diff --git a/Debug/cppcheck/10.html b/Debug/cppcheck/10.html index 30df35f2b23d..cbbc85ebe5a2 100644 --- a/Debug/cppcheck/10.html +++ b/Debug/cppcheck/10.html @@ -152,12 +152,12 @@
  1
@@ -261,432 +261,108 @@ 

Cppcheck report - [

// *****************************************************************************
+102
// *****************************************************************************
 /*!
-  \file      src/LinearSolver/CSR.cpp
+  \file      src/Base/HashMapReducer.hpp
   \copyright 2012-2015 J. Bakosi,
              2016-2018 Los Alamos National Security, LLC.,
              2019-2021 Triad National Security, LLC.
              All rights reserved. See the LICENSE file for details.
-  \brief     Compressed sparse row (CSR) storage for a sparse matrix
-  \details   Compressed sparse row (CSR) storage for a sparse matrix.
+  \brief     Custom Charm++ reducer for merging std::unordered_maps across PEs
+  \details   Custom Charm++ reducer for merging std::unordered_maps across PEs.
 */
 // *****************************************************************************
-
-#include "Exception.hpp"
-#include "CSR.hpp"
-
-using tk::CSR;
-
-CSR::CSR( std::size_t nc,
-          const std::pair< std::vector< std::size_t >,
-                           std::vector< std::size_t > >& psup )
-try :<--- syntax error: keyword 'try' is not allowed in global scope
-  ncomp( nc ),
-  rnz( psup.second.size()-1 ),
-  ia( rnz.size()*ncomp+1 )
-// *****************************************************************************
-//  Constructor: Create a CSR symmetric matrix with ncomp scalar components per
-//  non-zero matrix entry, storing only the upper triangular part
-//! \param[in] nc Number of scalar components (degrees of freedom)
-//! \param[in] psup Points surrounding points of mesh graph, see tk::genPsup
-// *****************************************************************************
-{
-  Assert( ncomp > 0, "Sparse matrix ncomp must be positive" );
-  Assert( rnz.size() > 0, "Sparse matrix size must be positive" );
-
-  const auto& psup1 = psup.first;
-  const auto& psup2 = psup.second;
-
-  // Calculate number of nonzeros in each block row (rnz), total number of
-  // nonzeros (nnz), and fill in row indices (ia)
-  std::size_t nnz, i;
-  for (ia[0]=1, nnz=i=0; i<psup2.size()-1; ++i) {
-    // add up and store nonzeros of row i (only upper triangular part)
-    std::size_t j;
-    for (rnz[i]=1, j=psup2[i]+1; j<=psup2[i+1]; ++j)
-      ++rnz[i];
-
-    // add up total number of nonzeros
-    nnz += rnz[i] * ncomp;
+#ifndef HashMapReducer_h
+#define HashMapReducer_h
+
+#include <vector>
+#include <unordered_map>
+#include <unordered_set>
+#include <memory>
+
+#include "NoWarning/charm++.hpp"
+
+#include "ContainerUtil.hpp"
+
+namespace tk {
+
+//! Serialize std::unordered_map to raw memory stream
+//! \tparam Key Map key
+//! \tparam T Map value
+//! \tparam Hash Map hasher
+//! \tparam Eq Map equality operator
+//! \param[in] m Hash map to serialize
+//! \return Pair of the length and the raw stream containing the serialized map
+template< class Key,
+          class T,
+          class Hash = std::hash< Key >,
+          class Eq = std::equal_to< Key > >
+std::pair< int, std::unique_ptr<char[]> >
+serialize( const std::unordered_map< Key, T, Hash, Eq >& m ) {
+   // Prepare for serializing map to a raw binary stream, compute size
+  PUP::sizer sizer;
+  sizer | const_cast< std::unordered_map< Key, T, Hash, Eq >& >( m );
+
+  // Create raw character stream to store the serialized map
+  std::unique_ptr<char[]> flatData = std::make_unique<char[]>( sizer.size() );
+
+  // Serialize map, each message will contain a map
+  PUP::toMem packer( flatData.get() );
+  packer | const_cast< std::unordered_map< Key, T, Hash, Eq >& >( m );
 
-    // fill up row index
-    for (std::size_t k=0; k<ncomp; ++k)
-      ia[i*ncomp+k+1] = ia[i*ncomp+k] + rnz[i];
-  }
-
-  // Allocate storage for matrix values and column indices
-  a.resize( nnz, 0.0 );
-  ja.resize( nnz );
-
-  // fill column indices
-  for (i=0; i<rnz.size(); ++i)
-    for (std::size_t k=0; k<ncomp; ++k) {
-      auto itmp = i*ncomp+k;
-      ja[ia[itmp]-1] = itmp+1;  // put in column index of diagonal
-      for (std::size_t n=1, j=psup2[i]+1; j<=psup2[i+1]; ++j) {
-        // put in column index of an off-diagonal
-	ja[ia[itmp]-1+(n++)] = psup1[j]*ncomp+k+1;
-      }
-    }
-
-  // (bubble-)sort column indices
-  for (i=0; i<rnz.size(); ++i)
-    for (std::size_t k=0; k<ncomp; ++k)
-      for (std::size_t j=psup2[i]+1; j<=psup2[i+1]; ++j)
-         for (std::size_t l=1; l<rnz[i]; ++l)   // sort column indices of row i
-            for (std::size_t e=0; e<rnz[i]-l; ++e)
-              if (ja[ia[i*ncomp+k]-1+e] > ja[ia[i*ncomp+k]+e])
-	        std::swap( ja[ia[i*ncomp+k]-1+e], ja[ia[i*ncomp+k]+e] );
-
-} // Catch std::exception
-  catch (std::exception& se) {
-    // (re-)throw tk::Excpetion
-    Throw( std::string("RUNTIME ERROR in CSR constructor: ") + se.what() );
-  }
-
-const tk::real&
-CSR::operator()( std::size_t row, std::size_t col, std::size_t pos ) const
-// *****************************************************************************
-//  Return const reference to sparse matrix entry at a position specified
-//  using relative addressing
-//! \param[in] row Block row
-//! \param[in] col Block column
-//! \param[in] pos Position in block
-//! \return Const reference to matrix entry at position specified
-// *****************************************************************************
-{
-  auto rncomp = row * ncomp;
-
-  for (std::size_t n=0, j=ia[rncomp+pos]-1; j<ia[rncomp+pos+1]-1; ++j, ++n)
-    if (col*ncomp+pos+1 == ja[j])
-      return a[ia[rncomp+pos]-1+n];
+  // Return size of and raw stream
+  return { sizer.size(), std::move(flatData) };
+}
+
+//! \brief Charm++ custom reducer for merging std::unordered_maps during
+//!   reduction across PEs
+//! \tparam Key Map key
+//! \tparam T Map value
+//! \tparam Hash Map hasher
+//! \tparam Eq Map equality operator
+//! \param[in] nmsg Number of messages in msgs
+//! \param[in] msgs Charm++ reduction message containing the serialized maps
+//! \return Aggregated std::unordered_maps built for further aggregation if
+//!    needed
+//! \details During aggregation the map keys are inserted, i.e., the keys remain
+//!   unique and the mapped values, assuming containers defining begin() and
+//!   end() iterators() are concatenated.
+//! \note The mapped type must be a container, i.e., must provide iterators
+//!   begin() and end().
+template< class Key,
+          class T,
+          class Hash = std::hash< Key >,
+          class Eq = std::equal_to< Key > >
+CkReductionMsg*
+mergeHashMap( int nmsg, CkReductionMsg **msgs ) {
+  // Will store deserialized map
+  std::unordered_map< Key, T, Hash, Eq > p;
+
+  // Create PUP deserializer based on message passed in
+  PUP::fromMem creator( msgs[0]->getData() );
+
+  // Deserialize map from raw stream
+  creator | p;
+
+  for (int m=1; m<nmsg; ++m) {
+    // Unpack map
+    std::unordered_map< Key, T, Hash, Eq > u;
+    PUP::fromMem curCreator( msgs[m]->getData() );
+    curCreator | u;
+    // Concatenate maps
+    for (auto&& c : u) concat( std::move(c.second), p[c.first] );<--- Iterating over container 'u' that is always empty.
+  }
+
+  // Serialize concatenated maps to raw stream
+  auto stream = tk::serialize( p );
+
+  // Forward serialized hash map
+  return CkReductionMsg::buildNew( stream.first, stream.second.get() );
+}
+
+} // tk::
 
-  Throw("Sparse matrix index not found");
-}
-
-void
-CSR::dirichlet( std::size_t i,
-                const std::vector< std::size_t >& gid,
-                const NodeCommMap& nodecommap,
-                std::size_t pos )
-// *****************************************************************************
-//  Set Dirichlet boundary condition at a node
-//! \param[in] i Local id at which to set Dirichlet BC
-//! \param[in] gid Local->global node id map
-//! \param[in] nodecommap Node communication map with global node ids
-//! \param[in] pos Position in block
-//! \details In parallel there can be multiple contributions to a single node
-//!   on the mesh, and correspondingly, a single matrix row can be partially
-//!   represented on multiple partitions. Setting a Dirichlet BC entails
-//!   zeroing out the row of the matrix and putting 1/N into the diagonal entry,
-//!   where N is the number of partitions that contribute to the mesh node
-//!   (matrix row). As a result, when the matrix participates in a matrix-vector
-//!   product, where the partial contributions across all partitions are
-//!   aggregated, the diagonal will contain 1 after the sum across partitions.
-//! \note Both gid and nodecommap are optional - unused in serial. If nodecommap
-//!   is empty, serial is assumed and gid is unused.
-// *****************************************************************************
-{
-  auto incomp = i * ncomp;
-  auto diag = nodecommap.empty() ? 1.0 : 1.0/tk::count(nodecommap,gid[i]);
-
-  // zero column
-  for (std::size_t r=0; r<rnz.size()*ncomp; ++r)
-    for (std::size_t j=ia[r]-1; j<ia[r+1]-1; ++j)
-      if (incomp+pos+1==ja[j]) a[j] = 0.0;
-
-  // zero row and put in diagonal
-  for (std::size_t j=ia[incomp+pos]-1; j<ia[incomp+pos+1]-1; ++j)
-    if (incomp+pos+1==ja[j]) a[j] = diag; else a[j] = 0.0;
-}
-
-void
-CSR::mult( const std::vector< real >& x,
-           std::vector< real >& r,
-           const std::vector< tk::real >& bcmask ) const
-// *****************************************************************************
-//  Multiply CSR matrix with vector from the right: r = A * x
-//! \param[in] x Vector to multiply matrix with from the right
-//! \param[in] r Result vector of product r = A * x
-//! \param[in] bcmask Dirichlet BC mask
-//! \note This is only complete in serial. In parallel, this computes the own
-//!   contributions to the product, so it must be followed by communication
-//!   combining the rows stored on multiple partitions.
-// *****************************************************************************
-{
-  std::fill( begin(r), end(r), 0.0 );
-
-  for (std::size_t i=0; i<rnz.size()*ncomp; ++i)
-    for (std::size_t j=ia[i]-1; j<ia[i+1]-1; ++j)
-      r[i] += bcmask[i] * a[j] * x[ja[j]-1];
-}
-
-std::ostream&
-CSR::write_stored( std::ostream& os ) const
-// *****************************************************************************
-//  Write out CSR as stored
-//! \param[in,out] os Output stream to write to
-//! \return Updated output stream
-// *****************************************************************************
-{
-  os << "size (npoin) = " << rnz.size() << '\n';
-  os << "ncomp = " << ncomp << '\n';
-  os << "rsize (size*ncomp) = " << rnz.size() * ncomp << '\n';
-  os << "nnz = " << a.size() << '\n';
-
-  std::size_t i;
-
-  os << "rnz[npoin=" << rnz.size() << "] = { ";
-  for (i=0; i<rnz.size()-1; ++i) os << rnz[i] << ", ";
-  os << rnz[i] << " }\n";
-
-  os << "ia[rsize+1=" << rnz.size()*ncomp+1 << "] = { ";
-  for (i=0; i<ia.size()-1; ++i) os << ia[i] << ", ";
-  os << ia[i] << " }\n";
-
-  os << "ja[nnz=" << ja.size() << "] = { ";
-  for (i=0; i<ja.size()-1; ++i) os << ja[i] << ", ";
-  os << ja[i] << " }\n";
-
-  os << "a[nnz=" << a.size() << "] = { ";
-  for (i=0; i<a.size()-1; ++i) os << a[i] << ", ";
-  os << a[i] << " }\n";
-
-  return os;
-}
-
-std::ostream&
-CSR::write_structure( std::ostream& os ) const
-// *****************************************************************************
-//  Write out CSR nonzero structure
-//! \param[in,out] os Output stream to write to
-//! \return Updated output stream
-// *****************************************************************************
-{
-  for (std::size_t i=0; i<rnz.size()*ncomp; ++i) {
-    // leading zeros
-    for (std::size_t j=1; j<ja[ia[i]-1]; ++j) os << ". ";
-    for (std::size_t n=ia[i]-1; n<ia[i+1]-1; ++n) {
-      // zeros between nonzeros
-      if (n>ia[i]-1) for (std::size_t j=ja[n-1]; j<ja[n]-1; ++j) os << ". ";
-      // nonzero
-      os << "o ";
-    }
-    // trailing zeros
-    for (std::size_t j=ja[ia[i+1]-2]; j<rnz.size()*ncomp; ++j) os << ". ";
-    os << '\n';
-  }
-
-  return os;
-}
-
-std::ostream&
-CSR::write_matrix( std::ostream& os ) const
-// *****************************************************************************
-//  Write out CSR as a real matrix
-//! \param[in,out] os Output stream to write to
-//! \return Updated output stream
-// *****************************************************************************
-{
-  for (std::size_t i=0; i<rnz.size()*ncomp; ++i) {
-    for (std::size_t j=1; j<ja[ia[i]-1]; ++j) os << "0\t";
-    for (std::size_t n=ia[i]-1; n<ia[i+1]-1; ++n) {
-      if (n>ia[i]-1) for (std::size_t j=ja[n-1]; j<ja[n]-1; ++j ) os << "0\t";
-      os << a[n] << '\t';
-    }
-    for (std::size_t j=ja[ia[i+1]-2]; j<rnz.size()*ncomp; ++j) os << "0\t";
-    os << '\n';
-  }
-
-  return os;
-}
-
-std::ostream&
-CSR::write_matlab( std::ostream& os ) const
-// *****************************************************************************
-//  Write out CSR in Matlab/Octave format
-//! \param[in,out] os Output stream to write to
-//! \return Updated output stream
-// *****************************************************************************
-{
-  os << "A = [ ";
-  for (std::size_t i=0; i<rnz.size()*ncomp; ++i) {
-    for (std::size_t j=1; j<ja[ia[i]-1]; ++j) os << "0 ";
-    for ( std::size_t n=ia[i]-1; n<ia[i+1]-1; ++n) {
-      if (n > ia[i]-1)
-        for (std::size_t j=ja[n-1]; j<ja[n]-1; ++j) os << "0 ";
-      os << a[n] << ' ';
-    }
-    for (std::size_t j=ja[ia[i+1]-2]; j<rnz.size()*ncomp; ++j) os << "0 ";
-    os << ";\n";
-  }
-  os << "]\n";
-
-  return os;
-}
+#endif // HashMapReducer_h
 
diff --git a/Debug/cppcheck/11.html b/Debug/cppcheck/11.html index 462f61ae9327..8517ae16e79b 100644 --- a/Debug/cppcheck/11.html +++ b/Debug/cppcheck/11.html @@ -152,12 +152,12 @@
  1
@@ -261,108 +261,1216 @@ 

Cppcheck report - [

// *****************************************************************************
+102
+103
+104
+105
+106
+107
+108
+109
+110
+111
+112
+113
+114
+115
+116
+117
+118
+119
+120
+121
+122
+123
+124
+125
+126
+127
+128
+129
+130
+131
+132
+133
+134
+135
+136
+137
+138
+139
+140
+141
+142
+143
+144
+145
+146
+147
+148
+149
+150
+151
+152
+153
+154
+155
+156
+157
+158
+159
+160
+161
+162
+163
+164
+165
+166
+167
+168
+169
+170
+171
+172
+173
+174
+175
+176
+177
+178
+179
+180
+181
+182
+183
+184
+185
+186
+187
+188
+189
+190
+191
+192
+193
+194
+195
+196
+197
+198
+199
+200
+201
+202
+203
+204
+205
+206
+207
+208
+209
+210
+211
+212
+213
+214
+215
+216
+217
+218
+219
+220
+221
+222
+223
+224
+225
+226
+227
+228
+229
+230
+231
+232
+233
+234
+235
+236
+237
+238
+239
+240
+241
+242
+243
+244
+245
+246
+247
+248
+249
+250
+251
+252
+253
+254
+255
+256
+257
+258
+259
+260
+261
+262
+263
+264
+265
+266
+267
+268
+269
+270
+271
+272
+273
+274
+275
+276
+277
+278
+279
+280
+281
+282
+283
+284
+285
+286
+287
+288
+289
+290
+291
+292
+293
+294
+295
+296
+297
+298
+299
+300
+301
+302
+303
+304
+305
+306
+307
+308
+309
+310
+311
+312
+313
+314
+315
+316
+317
+318
+319
+320
+321
+322
+323
+324
+325
+326
+327
+328
+329
+330
+331
+332
+333
+334
+335
+336
+337
+338
+339
+340
+341
+342
+343
+344
+345
+346
+347
+348
+349
+350
+351
+352
+353
+354
+355
+356
+357
+358
+359
+360
+361
+362
+363
+364
+365
+366
+367
+368
+369
+370
+371
+372
+373
+374
+375
+376
+377
+378
+379
+380
+381
+382
+383
+384
+385
+386
+387
+388
+389
+390
+391
+392
+393
+394
+395
+396
+397
+398
+399
+400
+401
+402
+403
+404
+405
+406
+407
+408
+409
+410
+411
+412
+413
+414
+415
+416
+417
+418
+419
+420
+421
+422
+423
+424
+425
+426
+427
+428
+429
+430
+431
+432
+433
+434
+435
+436
+437
+438
+439
+440
+441
+442
+443
+444
+445
+446
+447
+448
+449
+450
+451
+452
+453
+454
+455
+456
+457
+458
+459
+460
+461
+462
+463
+464
+465
+466
+467
+468
+469
+470
+471
+472
+473
+474
+475
+476
+477
+478
+479
+480
+481
+482
+483
+484
+485
+486
+487
+488
+489
+490
+491
+492
+493
+494
+495
+496
+497
+498
+499
+500
+501
+502
+503
+504
+505
+506
+507
+508
+509
+510
+511
+512
+513
+514
+515
+516
+517
+518
+519
+520
+521
+522
+523
+524
+525
+526
+527
+528
+529
+530
+531
+532
+533
+534
+535
+536
+537
+538
+539
+540
+541
+542
+543
+544
+545
+546
+547
+548
+549
+550
+551
+552
+553
+554
+555
+556
+557
+558
+559
+560
+561
+562
+563
+564
+565
+566
+567
+568
+569
+570
+571
+572
+573
+574
+575
+576
+577
+578
+579
+580
+581
+582
+583
+584
+585
+586
+587
+588
+589
+590
+591
+592
+593
+594
+595
+596
+597
+598
+599
+600
+601
+602
+603
+604
+605
+606
+607
+608
+609
+610
+611
+612
+613
+614
+615
+616
+617
+618
+619
+620
+621
+622
+623
+624
+625
+626
+627
+628
+629
+630
+631
+632
+633
+634
+635
+636
+637
+638
+639
+640
+641
+642
+643
+644
+645
+646
+647
+648
+649
+650
+651
+652
+653
+654
+655
+656
// *****************************************************************************
 /*!
-  \file      src/Base/HashMapReducer.hpp
+  \file      src/Base/Vector.hpp
   \copyright 2012-2015 J. Bakosi,
              2016-2018 Los Alamos National Security, LLC.,
              2019-2021 Triad National Security, LLC.
              All rights reserved. See the LICENSE file for details.
-  \brief     Custom Charm++ reducer for merging std::unordered_maps across PEs
-  \details   Custom Charm++ reducer for merging std::unordered_maps across PEs.
+  \brief     Vector algebra
+  \details   Vector algebra.
 */
 // *****************************************************************************
-#ifndef HashMapReducer_h
-#define HashMapReducer_h
+#ifndef Vector_h
+#define Vector_h
 
-#include <vector>
-#include <unordered_map>
-#include <unordered_set>
-#include <memory>
+#include <array>
+#include <cmath>
+#include <vector>
+#include <cblas.h>
 
-#include "NoWarning/charm++.hpp"
-
-#include "ContainerUtil.hpp"
-
-namespace tk {
-
-//! Serialize std::unordered_map to raw memory stream
-//! \tparam Key Map key
-//! \tparam T Map value
-//! \tparam Hash Map hasher
-//! \tparam Eq Map equality operator
-//! \param[in] m Hash map to serialize
-//! \return Pair of the length and the raw stream containing the serialized map
-template< class Key,
-          class T,
-          class Hash = std::hash< Key >,
-          class Eq = std::equal_to< Key > >
-std::pair< int, std::unique_ptr<char[]> >
-serialize( const std::unordered_map< Key, T, Hash, Eq >& m ) {
-   // Prepare for serializing map to a raw binary stream, compute size
-  PUP::sizer sizer;
-  sizer | const_cast< std::unordered_map< Key, T, Hash, Eq >& >( m );
+#include "Types.hpp"
+#include "Exception.hpp"
+
+// ignore old-style-casts required for lapack/blas calls
+#if defined(__clang__)
+  #pragma clang diagnostic ignored "-Wold-style-cast"
+#endif
+
+// Lapacke forward declarations
+extern "C" {
+
+using lapack_int = long;
+
+#define LAPACK_ROW_MAJOR 101
+#define LAPACK_COL_MAJOR 102
+
+extern lapack_int LAPACKE_dgetrf( int, lapack_int, lapack_int, double*,
+  lapack_int, lapack_int* );
+extern lapack_int LAPACKE_dgetri( int, lapack_int, double*, lapack_int,
+  const lapack_int* );
+
+}
 
-  // Create raw character stream to store the serialized map
-  std::unique_ptr<char[]> flatData = std::make_unique<char[]>( sizer.size() );
-
-  // Serialize map, each message will contain a map
-  PUP::toMem packer( flatData.get() );
-  packer | const_cast< std::unordered_map< Key, T, Hash, Eq >& >( m );
-
-  // Return size of and raw stream
-  return { sizer.size(), std::move(flatData) };
-}
-
-//! \brief Charm++ custom reducer for merging std::unordered_maps during
-//!   reduction across PEs
-//! \tparam Key Map key
-//! \tparam T Map value
-//! \tparam Hash Map hasher
-//! \tparam Eq Map equality operator
-//! \param[in] nmsg Number of messages in msgs
-//! \param[in] msgs Charm++ reduction message containing the serialized maps
-//! \return Aggregated std::unordered_maps built for further aggregation if
-//!    needed
-//! \details During aggregation the map keys are inserted, i.e., the keys remain
-//!   unique and the mapped values, assuming containers defining begin() and
-//!   end() iterators() are concatenated.
-//! \note The mapped type must be a container, i.e., must provide iterators
-//!   begin() and end().
-template< class Key,
-          class T,
-          class Hash = std::hash< Key >,
-          class Eq = std::equal_to< Key > >
-CkReductionMsg*
-mergeHashMap( int nmsg, CkReductionMsg **msgs ) {
-  // Will store deserialized map
-  std::unordered_map< Key, T, Hash, Eq > p;
-
-  // Create PUP deserializer based on message passed in
-  PUP::fromMem creator( msgs[0]->getData() );
-
-  // Deserialize map from raw stream
-  creator | p;
-
-  for (int m=1; m<nmsg; ++m) {
-    // Unpack map
-    std::unordered_map< Key, T, Hash, Eq > u;
-    PUP::fromMem curCreator( msgs[m]->getData() );
-    curCreator | u;
-    // Concatenate maps
-    for (auto&& c : u) concat( std::move(c.second), p[c.first] );<--- Iterating over container 'u' that is always empty.
-  }
-
-  // Serialize concatenated maps to raw stream
-  auto stream = tk::serialize( p );
-
-  // Forward serialized hash map
-  return CkReductionMsg::buildNew( stream.first, stream.second.get() );
-}
-
-} // tk::
-
-#endif // HashMapReducer_h
+namespace tk {
+
+//! Flip sign of vector components
+//! \param[in] v Vector whose components to multiply by -1.0
+inline void
+flip( std::array< real, 3 >& v )
+{
+  v[0] = -v[0];
+  v[1] = -v[1];
+  v[2] = -v[2];
+}
+
+//! Compute the cross-product of two vectors
+//! \param[in] v1x x coordinate of the 1st vector
+//! \param[in] v1y y coordinate of the 1st vector
+//! \param[in] v1z z coordinate of the 1st vector
+//! \param[in] v2x x coordinate of the 2nd vector
+//! \param[in] v2y y coordinate of the 2nd vector
+//! \param[in] v2z z coordinate of the 2nd vector
+//! \param[out] rx x coordinate of the product vector
+//! \param[out] ry y coordinate of the product vector
+//! \param[out] rz z coordinate of the product vector
+#pragma omp declare simd
+inline void
+cross( real v1x, real v1y, real v1z,
+       real v2x, real v2y, real v2z,
+       real& rx, real& ry, real& rz )
+{
+  rx = v1y*v2z - v2y*v1z;
+  ry = v1z*v2x - v2z*v1x;
+  rz = v1x*v2y - v2x*v1y;
+}
+
+//! Compute the cross-product of two vectors
+//! \param[in] v1 1st vector
+//! \param[in] v2 2nd vector
+//! \return Cross-product
+inline std::array< real, 3 >
+cross( const std::array< real, 3 >& v1, const std::array< real, 3 >& v2 )
+{
+  real rx, ry, rz;
+  cross( v1[0], v1[1], v1[2], v2[0], v2[1], v2[2], rx, ry, rz );
+  return { std::move(rx), std::move(ry), std::move(rz) };
+}
+
+//! Compute the cross-product of two vectors divided by a scalar
+//! \param[in] v1x x coordinate of the 1st vector
+//! \param[in] v1y y coordinate of the 1st vector
+//! \param[in] v1z z coordinate of the 1st vector
+//! \param[in] v2x x coordinate of the 2nd vector
+//! \param[in] v2y y coordinate of the 2nd vector
+//! \param[in] v2z z coordinate of the 2nd vector
+//! \param[in] j The scalar to divide the product with
+//! \param[out] rx x coordinate of the product vector
+//! \param[out] ry y coordinate of the product vector
+//! \param[out] rz z coordinate of the product vector
+#pragma omp declare simd uniform(j)
+inline void
+crossdiv( real v1x, real v1y, real v1z,
+          real v2x, real v2y, real v2z,
+          real j,
+          real& rx, real& ry, real& rz )
+{
+  cross( v1x, v1y, v1z, v2x, v2y, v2z, rx, ry, rz );
+  rx /= j;
+  ry /= j;
+  rz /= j;
+}
+
+//! Compute the cross-product of two vectors divided by a scalar
+//! \param[in] v1 1st vector
+//! \param[in] v2 2nd vector
+//! \param[in] j Scalar to divide each component by
+//! \return Cross-product divided by scalar
+inline std::array< real, 3 >
+crossdiv( const std::array< real, 3 >& v1,
+          const std::array< real, 3 >& v2,
+          real j )
+{
+  return {{ (v1[1]*v2[2] - v2[1]*v1[2]) / j,
+            (v1[2]*v2[0] - v2[2]*v1[0]) / j,
+            (v1[0]*v2[1] - v2[0]*v1[1]) / j }};
+}
+
+//! Compute the dot-product of two vectors
+//! \param[in] v1 1st vector
+//! \param[in] v2 2nd vector
+//! \return Dot-product
+inline real
+dot( const std::array< real, 3 >& v1, const std::array< real, 3 >& v2 )
+{
+  return v1[0]*v2[0] + v1[1]*v2[1] + v1[2]*v2[2];
+}
+
+//! Compute the dot-product of a matrix and a vector
+//! \param[in] m Matrix
+//! \param[in] v vector
+//! \return Dot-product
+inline std::array< real, 3 >
+matvec(
+  const std::array< std::array< real, 3 >, 3 >& m,
+  const std::array< real, 3 >& v )
+{
+  std::array< real, 3 > mv{0, 0, 0};
+  for (std::size_t i=0; i<3; ++i) {
+    for (std::size_t j=0; j<3; ++j)
+      mv[i] += m[i][j]*v[j];
+  }
+
+  return mv;
+}
+
+//! Compute length of a vector
+//! \param[in] x X coordinate of vector
+//! \param[in] y Y coordinate of vector
+//! \param[in] z Z coordinate of vector
+//! \return length
+#pragma omp declare simd
+inline real
+length( real x, real y, real z )
+{
+  return std::sqrt( x*x + y*y + z*z );
+}
+
+//! Compute length of a vector
+//! \param[in] v vector
+//! \return length
+inline real
+length( const std::array< real, 3 >& v )
+{
+  return std::sqrt( dot(v,v) );
+}
+
+//! Scale vector to unit length
+//! \param[in,out] v Vector to normalize
+inline void
+unit( std::array< real, 3 >& v ) noexcept(ndebug)
+{
+  auto len = length( v );
+  Assert( len > std::numeric_limits< tk::real >::epsilon(), "div by zero" );<--- Exception thrown in function declared not to throw exceptions.
+  v[0] /= len;
+  v[1] /= len;
+  v[2] /= len;
+}
+
+//! Compute the triple-product of three vectors
+//! \param[in] v1x x coordinate of the 1st vector
+//! \param[in] v1y y coordinate of the 1st vector
+//! \param[in] v1z z coordinate of the 1st vector
+//! \param[in] v2x x coordinate of the 2nd vector
+//! \param[in] v2y y coordinate of the 2nd vector
+//! \param[in] v2z z coordinate of the 2nd vector
+//! \param[in] v3x x coordinate of the 3rd vector
+//! \param[in] v3y y coordinate of the 3rd vector
+//! \param[in] v3z z coordinate of the 3rd vector
+//! \return Scalar value of the triple product
+#pragma omp declare simd
+inline tk::real
+triple( real v1x, real v1y, real v1z,
+        real v2x, real v2y, real v2z,
+        real v3x, real v3y, real v3z )
+{
+  real cx, cy, cz;
+  cross( v2x, v2y, v2z, v3x, v3y, v3z, cx, cy, cz );
+  return v1x*cx + v1y*cy + v1z*cz;
+}
+
+//! Compute the triple-product of three vectors
+//! \param[in] v1 1st vector
+//! \param[in] v2 2nd vector
+//! \param[in] v3 3rd vector
+//! \return Triple-product
+inline real
+triple( const std::array< real, 3 >& v1,
+        const std::array< real, 3 >& v2,
+        const std::array< real, 3 >& v3 )
+{
+  return dot( v1, cross(v2,v3) );
+}
+
+//! Rotate vector about X axis
+//! \param[in] v Vector to rotate
+//! \param[in] angle Angle to use to rotate with
+//! \return Rotated vector
+inline std::array< real, 3 >
+rotateX( const std::array< real, 3 >& v, real angle )
+{
+  using std::cos;  using std::sin;
+
+  std::array< std::array< real, 3 >, 3 >
+    R{{ {{ 1.0,         0.0,          0.0 }},
+        {{ 0.0,   cos(angle), -sin(angle) }},
+        {{ 0.0,   sin(angle),  cos(angle) }} }};
+
+  return {{ dot(R[0],v), dot(R[1],v), dot(R[2],v) }};
+}
+
+//! Rotate vector about Y axis
+//! \param[in] v Vector to rotate
+//! \param[in] angle Angle to use to rotate with
+//! \return Rotated vector
+inline std::array< real, 3 >
+rotateY( const std::array< real, 3 >& v, real angle )
+{
+  using std::cos;  using std::sin;
+
+  std::array< std::array< real, 3 >, 3 >
+    R{{ {{ cos(angle),  0.0, sin(angle) }},
+        {{ 0.0,         1.0,        0.0 }},
+        {{ -sin(angle), 0.0, cos(angle) }} }};
+
+  return {{ dot(R[0],v), dot(R[1],v), dot(R[2],v) }};
+}
+
+//! Rotate vector about Z axis
+//! \param[in] v Vector to rotate
+//! \param[in] angle Angle to use to rotate with
+//! \return Rotated vector
+inline std::array< real, 3 >
+rotateZ( const std::array< real, 3 >& v, real angle )
+{
+  using std::cos;  using std::sin;
+
+  std::array< std::array< real, 3 >, 3 >
+    R{{ {{ cos(angle), -sin(angle), 0.0 }},
+        {{ sin(angle),  cos(angle), 0.0 }},
+        {{ 0.0,         0.0,        1.0 }} }};
+
+  return {{ dot(R[0],v), dot(R[1],v), dot(R[2],v) }};
+}
+
+//! \brief Compute the determinant of the Jacobian of a coordinate
+//!  transformation over a tetrahedron
+//! \param[in] v1 (x,y,z) coordinates of 1st vertex of the tetrahedron
+//! \param[in] v2 (x,y,z) coordinates of 2nd vertex of the tetrahedron
+//! \param[in] v3 (x,y,z) coordinates of 3rd vertex of the tetrahedron
+//! \param[in] v4 (x,y,z) coordinates of 4th vertex of the tetrahedron
+//! \return Determinant of the Jacobian of transformation of physical
+//!   tetrahedron to reference (xi, eta, zeta) space
+inline real
+Jacobian( const std::array< real, 3 >& v1,
+          const std::array< real, 3 >& v2,
+          const std::array< real, 3 >& v3,
+          const std::array< real, 3 >& v4 )
+{
+  std::array< real, 3 > ba{{ v2[0]-v1[0], v2[1]-v1[1], v2[2]-v1[2] }},
+                        ca{{ v3[0]-v1[0], v3[1]-v1[1], v3[2]-v1[2] }},
+                        da{{ v4[0]-v1[0], v4[1]-v1[1], v4[2]-v1[2] }};
+  return triple( ba, ca, da );
+}
+
+//! \brief Compute the inverse of the Jacobian of a coordinate transformation
+//!   over a tetrahedron
+//! \param[in] v1 (x,y,z) coordinates of 1st vertex of the tetrahedron
+//! \param[in] v2 (x,y,z) coordinates of 2nd vertex of the tetrahedron
+//! \param[in] v3 (x,y,z) coordinates of 3rd vertex of the tetrahedron
+//! \param[in] v4 (x,y,z) coordinates of 4th vertex of the tetrahedron
+//! \return Inverse of the Jacobian of transformation of physical
+//!   tetrahedron to reference (xi, eta, zeta) space
+inline std::array< std::array< real, 3 >, 3 >
+inverseJacobian( const std::array< real, 3 >& v1,
+                 const std::array< real, 3 >& v2,
+                 const std::array< real, 3 >& v3,
+                 const std::array< real, 3 >& v4 )
+{
+  std::array< std::array< real, 3 >, 3 > jacInv;
+
+  auto detJ = Jacobian( v1, v2, v3, v4 );
+
+  jacInv[0][0] =  (  (v3[1]-v1[1])*(v4[2]-v1[2])
+                   - (v4[1]-v1[1])*(v3[2]-v1[2])) / detJ;
+  jacInv[1][0] = -(  (v2[1]-v1[1])*(v4[2]-v1[2])
+                   - (v4[1]-v1[1])*(v2[2]-v1[2])) / detJ;
+  jacInv[2][0] =  (  (v2[1]-v1[1])*(v3[2]-v1[2])
+                   - (v3[1]-v1[1])*(v2[2]-v1[2])) / detJ;
+
+  jacInv[0][1] = -(  (v3[0]-v1[0])*(v4[2]-v1[2])
+                   - (v4[0]-v1[0])*(v3[2]-v1[2])) / detJ;
+  jacInv[1][1] =  (  (v2[0]-v1[0])*(v4[2]-v1[2])
+                   - (v4[0]-v1[0])*(v2[2]-v1[2])) / detJ;
+  jacInv[2][1] = -(  (v2[0]-v1[0])*(v3[2]-v1[2])
+                   - (v3[0]-v1[0])*(v2[2]-v1[2])) / detJ;
+
+  jacInv[0][2] =  (  (v3[0]-v1[0])*(v4[1]-v1[1])
+                   - (v4[0]-v1[0])*(v3[1]-v1[1])) / detJ;
+  jacInv[1][2] = -(  (v2[0]-v1[0])*(v4[1]-v1[1])
+                   - (v4[0]-v1[0])*(v2[1]-v1[1])) / detJ;
+  jacInv[2][2] =  (  (v2[0]-v1[0])*(v3[1]-v1[1])
+                   - (v3[0]-v1[0])*(v2[1]-v1[1])) / detJ;
+
+  return jacInv;
+}
+
+//! Compute the determinant of 3x3 matrix
+//!  \param[in] a 3x3 matrix
+//!  \return Determinant of the 3x3 matrix
+inline tk::real
+determinant( const std::array< std::array< tk::real, 3 >, 3 >& a )
+{
+  return ( a[0][0] * (a[1][1]*a[2][2]-a[1][2]*a[2][1])
+         - a[0][1] * (a[1][0]*a[2][2]-a[1][2]*a[2][0])
+         + a[0][2] * (a[1][0]*a[2][1]-a[1][1]*a[2][0]) );
+}
+
+//! Compute the inverse of 3x3 matrix
+//!  \param[in] m 3x3 matrix
+//!  \return Inverse of the 3x3 matrix
+inline std::array< std::array< tk::real, 3 >, 3 >
+inverse( const std::array< std::array< tk::real, 3 >, 3 >& m )
+{
+  tk::real det = m[0][0] * (m[1][1] * m[2][2] - m[2][1] * m[1][2]) -
+                 m[0][1] * (m[1][0] * m[2][2] - m[1][2] * m[2][0]) +
+                 m[0][2] * (m[1][0] * m[2][1] - m[1][1] * m[2][0]);
+
+  tk::real invdet = 1.0 / det;
+
+  std::array< std::array< tk::real, 3 >, 3 > minv;
+  minv[0][0] = (m[1][1] * m[2][2] - m[2][1] * m[1][2]) * invdet;
+  minv[0][1] = (m[0][2] * m[2][1] - m[0][1] * m[2][2]) * invdet;
+  minv[0][2] = (m[0][1] * m[1][2] - m[0][2] * m[1][1]) * invdet;
+  minv[1][0] = (m[1][2] * m[2][0] - m[1][0] * m[2][2]) * invdet;
+  minv[1][1] = (m[0][0] * m[2][2] - m[0][2] * m[2][0]) * invdet;
+  minv[1][2] = (m[1][0] * m[0][2] - m[0][0] * m[1][2]) * invdet;
+  minv[2][0] = (m[1][0] * m[2][1] - m[2][0] * m[1][1]) * invdet;
+  minv[2][1] = (m[2][0] * m[0][1] - m[0][0] * m[2][1]) * invdet;
+  minv[2][2] = (m[0][0] * m[1][1] - m[1][0] * m[0][1]) * invdet;
+
+  return minv;
+}
+
+//! Solve a 3x3 system of equations using Cramer's rule
+//!  \param[in] a 3x3 lhs matrix
+//!  \param[in] b 3x1 rhs matrix
+//!  \return Array of solutions of the 3x3 system
+inline std::array < tk::real, 3 >
+cramer( const std::array< std::array< tk::real, 3 >, 3>& a,
+        const std::array< tk::real, 3 >& b )
+{
+  auto de = determinant( a );
+
+  auto nu(0.0);
+  std::array < real, 3 > x;
+
+  nu = determinant( {{{{b[0], a[0][1], a[0][2]}},
+                      {{b[1], a[1][1], a[1][2]}},
+                      {{b[2], a[2][1], a[2][2]}}}} );
+  x[0] = nu/de;
+
+  nu = determinant( {{{{a[0][0], b[0], a[0][2]}},
+                      {{a[1][0], b[1], a[1][2]}},
+                      {{a[2][0], b[2], a[2][2]}}}} );
+  x[1] = nu/de;
+
+  nu = determinant( {{{{a[0][0], a[0][1], b[0]}},
+                      {{a[1][0], a[1][1], b[1]}},
+                      {{a[2][0], a[2][1], b[2]}}}} );
+  x[2] = nu/de;
+
+  return x;
+}
+
+//! Move a point to a reference space given coordinates of origin of that space
+//!  \param[in] origin Origin of reference frame to which point is to be moved
+//!  \param[in,out] point Point that needs to be moved to reference frame
+inline void
+movePoint( const std::array< tk::real, 3 >& origin,
+  std::array< tk::real, 3 >& point )
+{
+  for (std::size_t i=0; i<3; ++i)
+    point[i] -= origin[i];
+}
+
+//! Rotate a point in 3D space by specifying rotation angles in degrees
+//!  \param[in] angles Angles in 3D space by which point is to be rotated
+//!  \param[in,out] point Point that needs to be rotated
+inline void
+rotatePoint( const std::array< tk::real, 3 >& angles,
+  std::array< tk::real, 3 >& point )
+{
+  // Convert angles to radian
+  tk::real pi = 4.0*std::atan(1.0);
+  auto a = angles[0] * pi/180.0;
+  auto b = angles[1] * pi/180.0;
+  auto c = angles[2] * pi/180.0;
+
+  // Rotation matrix
+  std::array< std::array< tk::real, 3 >, 3 > rotMat;
+  {
+    using namespace std;
+    rotMat[0][0] = cos(b)*cos(c);
+    rotMat[0][1] = - cos(b)*sin(c);
+    rotMat[0][2] = sin(b);
+
+    rotMat[1][0] = sin(a)*sin(b)*cos(c) + cos(a)*sin(c);
+    rotMat[1][1] = - sin(a)*sin(b)*sin(c) + cos(a)*cos(c);
+    rotMat[1][2] = - sin(a)*cos(b);
+
+    rotMat[2][0] = - cos(a)*sin(b)*cos(c) + sin(a)*sin(c);
+    rotMat[2][1] = cos(a)*sin(b)*sin(c) + sin(a)*cos(c);
+    rotMat[2][2] = cos(a)*cos(b);
+  }
+
+  // Apply rotation
+  std::array< tk::real, 3 > x{{0.0, 0.0, 0.0}};
+  for (std::size_t i=0; i<3; ++i) {
+    for (std::size_t j=0; j<3; ++j) {
+      x[i] += rotMat[i][j]*point[j];
+    }
+  }
+  point = x;
+}
+
+//! \brief Get the Right Cauchy-Green strain tensor from the inverse deformation
+//! gradient tensor.
+//! \param[in] g Inverse deformation gradient tensor
+//! \return Right Cauchy-Green tensor
+inline std::array< std::array< real, 3 >, 3 >
+getRightCauchyGreen(const std::array< std::array< real, 3 >, 3 >& g)
+{
+  // allocate matrices
+  double G[9], C[9];
+
+  // initialize c-matrices
+  for (std::size_t i=0; i<3; ++i) {
+    for (std::size_t j=0; j<3; ++j)
+      G[i*3+j] = g[i][j];
+  }
+
+  // get g.g^T
+  cblas_dgemm(CblasRowMajor, CblasNoTrans, CblasTrans,
+    3, 3, 3, 1.0, G, 3, G, 3, 0.0, C, 3);
+
+  // get inv(g.g^T)
+  lapack_int ipiv[3];
+
+  #ifndef NDEBUG
+  lapack_int ierr =
+  #endif
+    LAPACKE_dgetrf(LAPACK_ROW_MAJOR, 3, 3, C, 3, ipiv);
+  Assert(ierr==0, "Lapack error in LU factorization of g.g^T");
+
+  #ifndef NDEBUG
+  lapack_int jerr =
+  #endif
+    LAPACKE_dgetri(LAPACK_ROW_MAJOR, 3, C, 3, ipiv);
+  Assert(jerr==0, "Lapack error in inverting g.g^T");
+
+  // Output C as 2D array
+  return {{ {C[0], C[1], C[2]},
+            {C[3], C[4], C[5]},
+            {C[6], C[7], C[8]} }};
+}
+
+//! \brief Get the Left Cauchy-Green strain tensor from the inverse deformation
+//! gradient tensor.
+//! \param[in] g Inverse deformation gradient tensor
+//! \return Left Cauchy-Green tensor
+inline std::array< std::array< real, 3 >, 3 >
+getLeftCauchyGreen(const std::array< std::array< real, 3 >, 3 >& g)
+{
+  // allocate matrices
+  double G[9], b[9];
+
+  // initialize c-matrices
+  for (std::size_t i=0; i<3; ++i) {
+    for (std::size_t j=0; j<3; ++j)
+      G[i*3+j] = g[i][j];
+  }
+
+  // get g^T.g
+  cblas_dgemm(CblasRowMajor, CblasTrans, CblasNoTrans,
+    3, 3, 3, 1.0, G, 3, G, 3, 0.0, b, 3);
+
+  // get inv(g^T.g)
+  lapack_int ipiv[3];
+
+  #ifndef NDEBUG
+  lapack_int ierr =
+  #endif
+    LAPACKE_dgetrf(LAPACK_ROW_MAJOR, 3, 3, b, 3, ipiv);
+  Assert(ierr==0, "Lapack error in LU factorization of g^T.g");
+
+  #ifndef NDEBUG
+  lapack_int jerr =
+  #endif
+    LAPACKE_dgetri(LAPACK_ROW_MAJOR, 3, b, 3, ipiv);
+  Assert(jerr==0, "Lapack error in inverting g^T.g");
+
+  // Output b as 2D array
+  return {{ {b[0], b[1], b[2]},
+            {b[3], b[4], b[5]},
+            {b[6], b[7], b[8]} }};
+}
+
+//! \brief Rotate a second order tensor (e.g. a Strain/Stress matrix) from
+//! the (x,y,z) to a new (r,s,t) coordinate system.
+//! The first direction is given by a unit vector r = (rx,ry,rz).
+//! Then, the second is chosen to be:
+//! if |rx| > 0 or |ry| > 0:
+//! - s = (ry/sqrt(rx*rx+ry*ry),-rx/sqrt(rx*rx+ry*ry),0)
+//! else:
+//! - s = (1,0,0)
+//! Then, third basis vector is obtained from
+//! the cross-product between the first two.
+//! \param[in] mat matrix to be rotated.
+//! \param[in] r Coordinates of the first basis vector r = (rx,ry,rz).
+//! \return rotated tensor
+inline std::array< std::array< tk::real, 3 >, 3 >
+rotateTensor(const std::array< std::array< tk::real, 3 >, 3 >& mat,
+             const std::array< tk::real, 3 >& r )
+{
+  // define rotation matrix
+  tk::real eps = 1.0e-04;
+  double rotMat[9];
+  tk::real rx = r[0];
+  tk::real ry = r[1];
+  tk::real rz = r[2];
+  if (std::abs(rx) > eps || std::abs(ry) > eps)
+  {
+    tk::real rxryNorm = std::sqrt(rx*rx+ry*ry);
+    rotMat[0] = rx;
+    rotMat[1] = ry;
+    rotMat[2] = rz;
+    rotMat[3] = ry/rxryNorm;
+    rotMat[4] = -rx/rxryNorm;
+    rotMat[5] = 0.0;
+    rotMat[6] = rx*rz/rxryNorm;
+    rotMat[7] = ry*rz/rxryNorm;
+    rotMat[8] = -rxryNorm;
+  }
+  else
+  {
+    rotMat[0] = rx;
+    rotMat[1] = ry;
+    rotMat[2] = rz;
+    rotMat[3] = 1.0;
+    rotMat[4] = 0.0;
+    rotMat[5] = 0.0;
+    rotMat[6] = 0.0;
+    rotMat[7] = 1.0;
+    rotMat[8] = 0.0;
+  }
+
+  // define matrices
+  double matAuxIn[9], matAuxOut[9];
+  for (std::size_t i=0; i<3; ++i)
+    for (std::size_t j=0; j<3; ++j)
+      matAuxIn[i*3+j] = mat[i][j];
+
+  // compute matAuxIn*rotMat and store it into matAuxOut
+  cblas_dgemm(CblasRowMajor, CblasNoTrans, CblasNoTrans,
+    3, 3, 3, 1.0, matAuxIn, 3, rotMat, 3, 0.0, matAuxOut, 3);
+
+  // matAuxOut -> matAuxIn
+  for (std::size_t i=0; i<9; i++)
+  {
+    matAuxIn[i]  = matAuxOut[i];
+    matAuxOut[i] = 0.0;
+  }
+
+  // compute rotMat^T*matAuxIn and store it into matAuxOut
+  cblas_dgemm(CblasRowMajor, CblasTrans, CblasNoTrans,
+    3, 3, 3, 1.0, rotMat, 3, matAuxIn, 3, 0.0, matAuxOut, 3);
+
+  // return matAuxOut as a 2D array
+  return {{ {matAuxOut[0], matAuxOut[1], matAuxOut[2]},
+            {matAuxOut[3], matAuxOut[4], matAuxOut[5]},
+            {matAuxOut[6], matAuxOut[7], matAuxOut[8]} }};
+}
+
+//! \brief Reflect a second order tensor (e.g. a Strain/Stress matrix)
+//! \param[in] mat matrix to be rotated.
+//! \param[in] reflectMat Reflection matrix
+//! \return reflected tensor
+inline std::array< std::array< tk::real, 3 >, 3 >
+reflectTensor(const std::array< std::array< tk::real, 3 >, 3 >& mat,
+              const std::array< std::array< tk::real, 3 >, 3 >& reflectMat)
+{
+  // define reflection matrix
+  double refMat[9];
+  for (std::size_t i=0; i<3; ++i)
+    for (std::size_t j=0; j<3; ++j)
+      refMat[i*3+j] = reflectMat[i][j];
+
+  // define matAux (I need matrices as row major 1D arrays)
+  double matAuxIn[9], matAuxOut[9];
+  for (std::size_t i=0; i<3; ++i)
+    for (std::size_t j=0; j<3; ++j)
+      matAuxIn[i*3+j] = mat[i][j];
+
+  // compute matAuxIn*refMat and store it into matAuxOut
+  cblas_dgemm(CblasRowMajor, CblasNoTrans, CblasNoTrans,
+    3, 3, 3, 1.0, matAuxIn, 3, refMat, 3, 0.0, matAuxOut, 3);
+
+  // matAuxOut -> matAuxIn
+  for (std::size_t i=0; i<9; i++)
+  {
+    matAuxIn[i]  = matAuxOut[i];
+    matAuxOut[i] = 0.0;
+  }
+
+  // compute refMat^T*matAuxIn and store it into matAuxOut
+  cblas_dgemm(CblasRowMajor, CblasTrans, CblasNoTrans,
+    3, 3, 3, 1.0, refMat, 3, matAuxIn, 3, 0.0, matAuxOut, 3);
+
+  // return matAuxOut as a 2D array
+  return {{ {matAuxOut[0], matAuxOut[1], matAuxOut[2]},
+            {matAuxOut[3], matAuxOut[4], matAuxOut[5]},
+            {matAuxOut[6], matAuxOut[7], matAuxOut[8]} }};
+}
+
+} // tk::
+
+#endif // Vector_h
 
diff --git a/Debug/cppcheck/13.html b/Debug/cppcheck/13.html index f6a8f6deca44..6d1b247600e7 100644 --- a/Debug/cppcheck/13.html +++ b/Debug/cppcheck/13.html @@ -152,647 +152,2121 @@
- - + @@ -1610,8 +1610,8 @@ 1455 : 291386250 : m_u(e, rmark) = rkcoef[0][m_stage] * m_un(e, rmark) 1456 : 291386250 : + rkcoef[1][m_stage] * ( m_u(e, rmark) 1457 : 291386250 : + d->Dt() * m_rhs(e, mark)/m_lhs(e, mark) ); - 1458 [ + + ]: 291386250 : if(fabs(m_u(e, rmark)) < 1e-16) - 1459 : 135098681 : m_u(e, rmark) = 0; + 1458 [ + + ]: 291386250 : if(fabs(m_u(e, rmark)) < 1e-16) + 1459 : 135097052 : m_u(e, rmark) = 0; 1460 : : } 1461 : : } 1462 : : } @@ -1876,7 +1876,7 @@ 1710 : 823468 : auto chbnd = [ this ]( std::size_t p ) { 1711 : : return 1712 : 411734 : std::any_of( m_outmesh.nodeCommMap.cbegin(), m_outmesh.nodeCommMap.cend(), - 1713 [ + - ]: 1115005 : [&](const auto& s) { return s.second.find(p) != s.second.cend(); } ); + 1713 [ + - ]: 1114624 : [&](const auto& s) { return s.second.find(p) != s.second.cend(); } ); 1714 : 2162 : }; 1715 : : 1716 : : // Finish computing node field output averages in internal nodes diff --git a/Debug/test_coverage/Inciter/DG.hpp.func-sort-c.html b/Debug/test_coverage/Inciter/DG.hpp.func-sort-c.html index 1112e3bb7b5a..06262d5e0830 100644 --- a/Debug/test_coverage/Inciter/DG.hpp.func-sort-c.html +++ b/Debug/test_coverage/Inciter/DG.hpp.func-sort-c.html @@ -33,7 +33,7 @@ - + @@ -89,11 +89,11 @@ - + - + diff --git a/Debug/test_coverage/Inciter/DG.hpp.func.html b/Debug/test_coverage/Inciter/DG.hpp.func.html index 4d5eabafc820..8bcb026ad0c1 100644 --- a/Debug/test_coverage/Inciter/DG.hpp.func.html +++ b/Debug/test_coverage/Inciter/DG.hpp.func.html @@ -33,7 +33,7 @@ - + @@ -77,7 +77,7 @@ - + @@ -89,7 +89,7 @@ - + diff --git a/Debug/test_coverage/Inciter/DG.hpp.gcov.html b/Debug/test_coverage/Inciter/DG.hpp.gcov.html index d845bd759bf5..d3069c5ca3b1 100644 --- a/Debug/test_coverage/Inciter/DG.hpp.gcov.html +++ b/Debug/test_coverage/Inciter/DG.hpp.gcov.html @@ -33,7 +33,7 @@ - + @@ -152,7 +152,7 @@ 78 : : #endif 79 : : //! Migrate constructor 80 : : // cppcheck-suppress uninitMemberVar - 81 [ + - ]: 5122 : explicit DG( CkMigrateMessage* msg ) : CBase_DG( msg ) {} + 81 [ + - ]: 5047 : explicit DG( CkMigrateMessage* msg ) : CBase_DG( msg ) {} 82 : : #if defined(__clang__) 83 : : #pragma clang diagnostic pop 84 : : #endif @@ -299,56 +299,56 @@ 225 : : ///@{ 226 : : //! \brief Pack/Unpack serialize member function 227 : : //! \param[in,out] p Charm++'s PUP::er serializer object reference - 228 : 15922 : void pup( PUP::er &p ) override { - 229 : 15922 : p | m_disc; - 230 : 15922 : p | m_ghosts; - 231 : 15922 : p | m_ndof_NodalExtrm; - 232 : 15922 : p | m_nsol; - 233 : 15922 : p | m_ninitsol; - 234 : 15922 : p | m_nlim; - 235 : 15922 : p | m_nnod; - 236 : 15922 : p | m_nrefine; - 237 : 15922 : p | m_nsmooth; - 238 : 15922 : p | m_nreco; - 239 : 15922 : p | m_nnodalExtrema; - 240 : 15922 : p | m_u; - 241 : 15922 : p | m_un; - 242 : 15922 : p | m_p; - 243 : 15922 : p | m_geoElem; - 244 : 15922 : p | m_lhs; - 245 : 15922 : p | m_mtInv; - 246 : 15922 : p | m_uNodalExtrm; - 247 : 15922 : p | m_pNodalExtrm; - 248 : 15922 : p | m_uNodalExtrmc; - 249 : 15922 : p | m_pNodalExtrmc; - 250 : 15922 : p | m_rhs; - 251 : 15922 : p | m_rhsprev; - 252 : 15922 : p | m_stiffrhs; - 253 : 15922 : p | m_stiffrhsprev; - 254 : 15922 : p | m_stiffEqIdx; - 255 : 15922 : p | m_nonStiffEqIdx; - 256 : 15922 : p | m_nstiffeq; - 257 : 15922 : p | m_nnonstiffeq; - 258 : 15922 : p | m_npoin; - 259 : 15922 : p | m_diag; - 260 : 15922 : p | m_stage; - 261 : 15922 : p | m_ndof; - 262 : 15922 : p | m_numEqDof; - 263 : 15922 : p | m_uc; - 264 : 15922 : p | m_pc; - 265 : 15922 : p | m_ndofc; - 266 : 15922 : p | m_initial; - 267 : 15922 : p | m_uElemfields; - 268 : 15922 : p | m_pElemfields; - 269 : 15922 : p | m_uNodefields; - 270 : 15922 : p | m_pNodefields; - 271 : 15922 : p | m_uNodefieldsc; - 272 : 15922 : p | m_pNodefieldsc; - 273 : 15922 : p | m_outmesh; - 274 : 15922 : p | m_boxelems; - 275 : 15922 : p | m_shockmarker; - 276 : 15922 : p | m_rho0mat; - 277 : 15922 : } + 228 : 15697 : void pup( PUP::er &p ) override { + 229 : 15697 : p | m_disc; + 230 : 15697 : p | m_ghosts; + 231 : 15697 : p | m_ndof_NodalExtrm; + 232 : 15697 : p | m_nsol; + 233 : 15697 : p | m_ninitsol; + 234 : 15697 : p | m_nlim; + 235 : 15697 : p | m_nnod; + 236 : 15697 : p | m_nrefine; + 237 : 15697 : p | m_nsmooth; + 238 : 15697 : p | m_nreco; + 239 : 15697 : p | m_nnodalExtrema; + 240 : 15697 : p | m_u; + 241 : 15697 : p | m_un; + 242 : 15697 : p | m_p; + 243 : 15697 : p | m_geoElem; + 244 : 15697 : p | m_lhs; + 245 : 15697 : p | m_mtInv; + 246 : 15697 : p | m_uNodalExtrm; + 247 : 15697 : p | m_pNodalExtrm; + 248 : 15697 : p | m_uNodalExtrmc; + 249 : 15697 : p | m_pNodalExtrmc; + 250 : 15697 : p | m_rhs; + 251 : 15697 : p | m_rhsprev; + 252 : 15697 : p | m_stiffrhs; + 253 : 15697 : p | m_stiffrhsprev; + 254 : 15697 : p | m_stiffEqIdx; + 255 : 15697 : p | m_nonStiffEqIdx; + 256 : 15697 : p | m_nstiffeq; + 257 : 15697 : p | m_nnonstiffeq; + 258 : 15697 : p | m_npoin; + 259 : 15697 : p | m_diag; + 260 : 15697 : p | m_stage; + 261 : 15697 : p | m_ndof; + 262 : 15697 : p | m_numEqDof; + 263 : 15697 : p | m_uc; + 264 : 15697 : p | m_pc; + 265 : 15697 : p | m_ndofc; + 266 : 15697 : p | m_initial; + 267 : 15697 : p | m_uElemfields; + 268 : 15697 : p | m_pElemfields; + 269 : 15697 : p | m_uNodefields; + 270 : 15697 : p | m_pNodefields; + 271 : 15697 : p | m_uNodefieldsc; + 272 : 15697 : p | m_pNodefieldsc; + 273 : 15697 : p | m_outmesh; + 274 : 15697 : p | m_boxelems; + 275 : 15697 : p | m_shockmarker; + 276 : 15697 : p | m_rho0mat; + 277 : 15697 : } 278 : : //! \brief Pack/Unpack serialize operator| 279 : : //! \param[in,out] p Charm++'s PUP::er serializer object reference 280 : : //! \param[in,out] i DG object reference diff --git a/Debug/test_coverage/Inciter/DiagReducer.cpp.func-sort-c.html b/Debug/test_coverage/Inciter/DiagReducer.cpp.func-sort-c.html index dbdf12a6a6ed..01481c8d2de5 100644 --- a/Debug/test_coverage/Inciter/DiagReducer.cpp.func-sort-c.html +++ b/Debug/test_coverage/Inciter/DiagReducer.cpp.func-sort-c.html @@ -33,7 +33,7 @@ - + @@ -73,11 +73,11 @@ - + - +
  1
-  2
-  3
-  4
-  5
-  6
-  7
-  8
-  9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
- 37
- 38
- 39
- 40
- 41
- 42
- 43
- 44
- 45
- 46
- 47
- 48
- 49
- 50
- 51
- 52
- 53
- 54
- 55
- 56
- 57
- 58
- 59
- 60
- 61
- 62
- 63
- 64
- 65
- 66
- 67
- 68
- 69
- 70
- 71
- 72
- 73
- 74
- 75
- 76
- 77
- 78
- 79
- 80
- 81
- 82
- 83
- 84
- 85
- 86
- 87
- 88
- 89
- 90
- 91
- 92
- 93
- 94
- 95
- 96
- 97
- 98
- 99
-100
-101
-102
-103
-104
-105
-106
-107
-108
-109
-110
-111
-112
-113
-114
-115
-116
-117
-118
-119
-120
-121
-122
-123
-124
-125
-126
-127
-128
-129
-130
-131
-132
-133
-134
-135
-136
-137
-138
-139
-140
-141
-142
-143
-144
-145
-146
-147
-148
-149
-150
-151
-152
-153
-154
-155
-156
-157
-158
-159
-160
-161
-162
-163
-164
-165
-166
-167
-168
-169
-170
-171
-172
-173
-174
-175
-176
-177
-178
-179
-180
-181
-182
-183
-184
-185
-186
-187
-188
-189
-190
-191
-192
-193
-194
-195
-196
-197
-198
-199
-200
-201
-202
-203
-204
-205
-206
-207
-208
-209
-210
-211
-212
-213
-214
-215
-216
-217
-218
-219
-220
-221
-222
-223
-224
-225
-226
-227
-228
-229
-230
-231
-232
-233
-234
-235
-236
-237
-238
-239
-240
-241
-242
-243
-244
-245
-246
-247
-248
-249
-250
-251
-252
-253
-254
-255
-256
-257
-258
-259
-260
-261
-262
-263
-264
-265
-266
-267
-268
-269
-270
-271
-272
-273
-274
-275
-276
-277
-278
-279
-280
-281
-282
-283
-284
-285
-286
-287
-288
-289
-290
-291
-292
-293
-294
-295
-296
-297
-298
-299
-300
-301
-302
-303
-304
-305
-306
-307
-308
-309
-310
-311
-312
-313
-314
-315
-316
-317
#ifndef AMR_edge_store_h
-#define AMR_edge_store_h
-
-#include <cassert>
-
-#include "Loggers.hpp"
-#include "AMR/AMR_types.hpp"
-
-namespace AMR {
-
-    class edge_store_t {
-        public:
-            // TODO: convert this to an unordered map with a custom hash (can lift from Quinoa)
-            edges_t edges;
-
-            // Node connectivity does this any way, but in a slightly less efficient way
-            // Maps the edge to the child node which splits it
-                // This was added retrospectivley to support the operation "for
-                // edge formed of initial nodes {A,B}, what node(s) were added
-                // between them"
-                // NOTE: At some point, this could probably be deleted..
-                // NOTE: This is only mainted by split.
-            //std::map<edge_t, size_t> children;
+
   1
+   2
+   3
+   4
+   5
+   6
+   7
+   8
+   9
+  10
+  11
+  12
+  13
+  14
+  15
+  16
+  17
+  18
+  19
+  20
+  21
+  22
+  23
+  24
+  25
+  26
+  27
+  28
+  29
+  30
+  31
+  32
+  33
+  34
+  35
+  36
+  37
+  38
+  39
+  40
+  41
+  42
+  43
+  44
+  45
+  46
+  47
+  48
+  49
+  50
+  51
+  52
+  53
+  54
+  55
+  56
+  57
+  58
+  59
+  60
+  61
+  62
+  63
+  64
+  65
+  66
+  67
+  68
+  69
+  70
+  71
+  72
+  73
+  74
+  75
+  76
+  77
+  78
+  79
+  80
+  81
+  82
+  83
+  84
+  85
+  86
+  87
+  88
+  89
+  90
+  91
+  92
+  93
+  94
+  95
+  96
+  97
+  98
+  99
+ 100
+ 101
+ 102
+ 103
+ 104
+ 105
+ 106
+ 107
+ 108
+ 109
+ 110
+ 111
+ 112
+ 113
+ 114
+ 115
+ 116
+ 117
+ 118
+ 119
+ 120
+ 121
+ 122
+ 123
+ 124
+ 125
+ 126
+ 127
+ 128
+ 129
+ 130
+ 131
+ 132
+ 133
+ 134
+ 135
+ 136
+ 137
+ 138
+ 139
+ 140
+ 141
+ 142
+ 143
+ 144
+ 145
+ 146
+ 147
+ 148
+ 149
+ 150
+ 151
+ 152
+ 153
+ 154
+ 155
+ 156
+ 157
+ 158
+ 159
+ 160
+ 161
+ 162
+ 163
+ 164
+ 165
+ 166
+ 167
+ 168
+ 169
+ 170
+ 171
+ 172
+ 173
+ 174
+ 175
+ 176
+ 177
+ 178
+ 179
+ 180
+ 181
+ 182
+ 183
+ 184
+ 185
+ 186
+ 187
+ 188
+ 189
+ 190
+ 191
+ 192
+ 193
+ 194
+ 195
+ 196
+ 197
+ 198
+ 199
+ 200
+ 201
+ 202
+ 203
+ 204
+ 205
+ 206
+ 207
+ 208
+ 209
+ 210
+ 211
+ 212
+ 213
+ 214
+ 215
+ 216
+ 217
+ 218
+ 219
+ 220
+ 221
+ 222
+ 223
+ 224
+ 225
+ 226
+ 227
+ 228
+ 229
+ 230
+ 231
+ 232
+ 233
+ 234
+ 235
+ 236
+ 237
+ 238
+ 239
+ 240
+ 241
+ 242
+ 243
+ 244
+ 245
+ 246
+ 247
+ 248
+ 249
+ 250
+ 251
+ 252
+ 253
+ 254
+ 255
+ 256
+ 257
+ 258
+ 259
+ 260
+ 261
+ 262
+ 263
+ 264
+ 265
+ 266
+ 267
+ 268
+ 269
+ 270
+ 271
+ 272
+ 273
+ 274
+ 275
+ 276
+ 277
+ 278
+ 279
+ 280
+ 281
+ 282
+ 283
+ 284
+ 285
+ 286
+ 287
+ 288
+ 289
+ 290
+ 291
+ 292
+ 293
+ 294
+ 295
+ 296
+ 297
+ 298
+ 299
+ 300
+ 301
+ 302
+ 303
+ 304
+ 305
+ 306
+ 307
+ 308
+ 309
+ 310
+ 311
+ 312
+ 313
+ 314
+ 315
+ 316
+ 317
+ 318
+ 319
+ 320
+ 321
+ 322
+ 323
+ 324
+ 325
+ 326
+ 327
+ 328
+ 329
+ 330
+ 331
+ 332
+ 333
+ 334
+ 335
+ 336
+ 337
+ 338
+ 339
+ 340
+ 341
+ 342
+ 343
+ 344
+ 345
+ 346
+ 347
+ 348
+ 349
+ 350
+ 351
+ 352
+ 353
+ 354
+ 355
+ 356
+ 357
+ 358
+ 359
+ 360
+ 361
+ 362
+ 363
+ 364
+ 365
+ 366
+ 367
+ 368
+ 369
+ 370
+ 371
+ 372
+ 373
+ 374
+ 375
+ 376
+ 377
+ 378
+ 379
+ 380
+ 381
+ 382
+ 383
+ 384
+ 385
+ 386
+ 387
+ 388
+ 389
+ 390
+ 391
+ 392
+ 393
+ 394
+ 395
+ 396
+ 397
+ 398
+ 399
+ 400
+ 401
+ 402
+ 403
+ 404
+ 405
+ 406
+ 407
+ 408
+ 409
+ 410
+ 411
+ 412
+ 413
+ 414
+ 415
+ 416
+ 417
+ 418
+ 419
+ 420
+ 421
+ 422
+ 423
+ 424
+ 425
+ 426
+ 427
+ 428
+ 429
+ 430
+ 431
+ 432
+ 433
+ 434
+ 435
+ 436
+ 437
+ 438
+ 439
+ 440
+ 441
+ 442
+ 443
+ 444
+ 445
+ 446
+ 447
+ 448
+ 449
+ 450
+ 451
+ 452
+ 453
+ 454
+ 455
+ 456
+ 457
+ 458
+ 459
+ 460
+ 461
+ 462
+ 463
+ 464
+ 465
+ 466
+ 467
+ 468
+ 469
+ 470
+ 471
+ 472
+ 473
+ 474
+ 475
+ 476
+ 477
+ 478
+ 479
+ 480
+ 481
+ 482
+ 483
+ 484
+ 485
+ 486
+ 487
+ 488
+ 489
+ 490
+ 491
+ 492
+ 493
+ 494
+ 495
+ 496
+ 497
+ 498
+ 499
+ 500
+ 501
+ 502
+ 503
+ 504
+ 505
+ 506
+ 507
+ 508
+ 509
+ 510
+ 511
+ 512
+ 513
+ 514
+ 515
+ 516
+ 517
+ 518
+ 519
+ 520
+ 521
+ 522
+ 523
+ 524
+ 525
+ 526
+ 527
+ 528
+ 529
+ 530
+ 531
+ 532
+ 533
+ 534
+ 535
+ 536
+ 537
+ 538
+ 539
+ 540
+ 541
+ 542
+ 543
+ 544
+ 545
+ 546
+ 547
+ 548
+ 549
+ 550
+ 551
+ 552
+ 553
+ 554
+ 555
+ 556
+ 557
+ 558
+ 559
+ 560
+ 561
+ 562
+ 563
+ 564
+ 565
+ 566
+ 567
+ 568
+ 569
+ 570
+ 571
+ 572
+ 573
+ 574
+ 575
+ 576
+ 577
+ 578
+ 579
+ 580
+ 581
+ 582
+ 583
+ 584
+ 585
+ 586
+ 587
+ 588
+ 589
+ 590
+ 591
+ 592
+ 593
+ 594
+ 595
+ 596
+ 597
+ 598
+ 599
+ 600
+ 601
+ 602
+ 603
+ 604
+ 605
+ 606
+ 607
+ 608
+ 609
+ 610
+ 611
+ 612
+ 613
+ 614
+ 615
+ 616
+ 617
+ 618
+ 619
+ 620
+ 621
+ 622
+ 623
+ 624
+ 625
+ 626
+ 627
+ 628
+ 629
+ 630
+ 631
+ 632
+ 633
+ 634
+ 635
+ 636
+ 637
+ 638
+ 639
+ 640
+ 641
+ 642
+ 643
+ 644
+ 645
+ 646
+ 647
+ 648
+ 649
+ 650
+ 651
+ 652
+ 653
+ 654
+ 655
+ 656
+ 657
+ 658
+ 659
+ 660
+ 661
+ 662
+ 663
+ 664
+ 665
+ 666
+ 667
+ 668
+ 669
+ 670
+ 671
+ 672
+ 673
+ 674
+ 675
+ 676
+ 677
+ 678
+ 679
+ 680
+ 681
+ 682
+ 683
+ 684
+ 685
+ 686
+ 687
+ 688
+ 689
+ 690
+ 691
+ 692
+ 693
+ 694
+ 695
+ 696
+ 697
+ 698
+ 699
+ 700
+ 701
+ 702
+ 703
+ 704
+ 705
+ 706
+ 707
+ 708
+ 709
+ 710
+ 711
+ 712
+ 713
+ 714
+ 715
+ 716
+ 717
+ 718
+ 719
+ 720
+ 721
+ 722
+ 723
+ 724
+ 725
+ 726
+ 727
+ 728
+ 729
+ 730
+ 731
+ 732
+ 733
+ 734
+ 735
+ 736
+ 737
+ 738
+ 739
+ 740
+ 741
+ 742
+ 743
+ 744
+ 745
+ 746
+ 747
+ 748
+ 749
+ 750
+ 751
+ 752
+ 753
+ 754
+ 755
+ 756
+ 757
+ 758
+ 759
+ 760
+ 761
+ 762
+ 763
+ 764
+ 765
+ 766
+ 767
+ 768
+ 769
+ 770
+ 771
+ 772
+ 773
+ 774
+ 775
+ 776
+ 777
+ 778
+ 779
+ 780
+ 781
+ 782
+ 783
+ 784
+ 785
+ 786
+ 787
+ 788
+ 789
+ 790
+ 791
+ 792
+ 793
+ 794
+ 795
+ 796
+ 797
+ 798
+ 799
+ 800
+ 801
+ 802
+ 803
+ 804
+ 805
+ 806
+ 807
+ 808
+ 809
+ 810
+ 811
+ 812
+ 813
+ 814
+ 815
+ 816
+ 817
+ 818
+ 819
+ 820
+ 821
+ 822
+ 823
+ 824
+ 825
+ 826
+ 827
+ 828
+ 829
+ 830
+ 831
+ 832
+ 833
+ 834
+ 835
+ 836
+ 837
+ 838
+ 839
+ 840
+ 841
+ 842
+ 843
+ 844
+ 845
+ 846
+ 847
+ 848
+ 849
+ 850
+ 851
+ 852
+ 853
+ 854
+ 855
+ 856
+ 857
+ 858
+ 859
+ 860
+ 861
+ 862
+ 863
+ 864
+ 865
+ 866
+ 867
+ 868
+ 869
+ 870
+ 871
+ 872
+ 873
+ 874
+ 875
+ 876
+ 877
+ 878
+ 879
+ 880
+ 881
+ 882
+ 883
+ 884
+ 885
+ 886
+ 887
+ 888
+ 889
+ 890
+ 891
+ 892
+ 893
+ 894
+ 895
+ 896
+ 897
+ 898
+ 899
+ 900
+ 901
+ 902
+ 903
+ 904
+ 905
+ 906
+ 907
+ 908
+ 909
+ 910
+ 911
+ 912
+ 913
+ 914
+ 915
+ 916
+ 917
+ 918
+ 919
+ 920
+ 921
+ 922
+ 923
+ 924
+ 925
+ 926
+ 927
+ 928
+ 929
+ 930
+ 931
+ 932
+ 933
+ 934
+ 935
+ 936
+ 937
+ 938
+ 939
+ 940
+ 941
+ 942
+ 943
+ 944
+ 945
+ 946
+ 947
+ 948
+ 949
+ 950
+ 951
+ 952
+ 953
+ 954
+ 955
+ 956
+ 957
+ 958
+ 959
+ 960
+ 961
+ 962
+ 963
+ 964
+ 965
+ 966
+ 967
+ 968
+ 969
+ 970
+ 971
+ 972
+ 973
+ 974
+ 975
+ 976
+ 977
+ 978
+ 979
+ 980
+ 981
+ 982
+ 983
+ 984
+ 985
+ 986
+ 987
+ 988
+ 989
+ 990
+ 991
+ 992
+ 993
+ 994
+ 995
+ 996
+ 997
+ 998
+ 999
+1000
+1001
+1002
+1003
+1004
+1005
+1006
+1007
+1008
+1009
+1010
+1011
+1012
+1013
+1014
+1015
+1016
+1017
+1018
+1019
+1020
+1021
+1022
+1023
+1024
+1025
+1026
+1027
+1028
+1029
+1030
+1031
+1032
+1033
+1034
+1035
+1036
+1037
+1038
+1039
+1040
+1041
+1042
+1043
+1044
+1045
+1046
+1047
+1048
+1049
+1050
+1051
+1052
+1053
+1054
// *****************************************************************************
+/*!
+  \file      src/IO/ExodusIIMeshReader.cpp
+  \copyright 2012-2015 J. Bakosi,
+             2016-2018 Los Alamos National Security, LLC.,
+             2019-2021 Triad National Security, LLC.
+             All rights reserved. See the LICENSE file for details.
+  \brief     ExodusII mesh reader
+  \details   ExodusII mesh reader class definition.
+*/
+// *****************************************************************************
+
+#include <numeric>
+
+#include "NoWarning/exodusII.hpp"
+
+#include "ExodusIIMeshReader.hpp"
+#include "ContainerUtil.hpp"
+#include "Exception.hpp"
+#include "UnsMesh.hpp"
+#include "Reorder.hpp"
+
+using tk::ExodusIIMeshReader;
 
-            size_t size()
-            {
-                return edges.size();
-            }
-
-            /**
-             * @brief Function to create new edge between two nodes with an
-             * intermediate. Given nodes A, B, and AB makes edge A->AB and AB->B
-             *
-             * @param A First end node
-             * @param B Second end node
-             * @param AB Intermediate node
-             * @param lc Lock case for the new edges
-             */
-            void split(size_t A, size_t B, size_t AB, Edge_Lock_Case lc)
-            {
-                trace_out << "Splitting with lock case " << lc << std::endl;
-                generate(A, AB, lc);
-                generate(B, AB, lc);
-
-                //children.insert( std::pair<edge_t, size_t>(edge_t(A,B), AB));
-                // Generate pertinent keys
-                //edge_t keyAB = nodes_to_key(A, B);
-
-                // NOTE: This isn't explicitly needed in the paper, and may be
-                    // implicitly dealt with somewhere?
-                //mark_edge_for_refinement(keyAB);
-            }
+ExodusIIMeshReader::ExodusIIMeshReader( const std::string& filename,<--- Member variable 'ExodusIIMeshReader::m_nelem' is not initialized in the constructor.
+                                        int cpuwordsize,
+                                        int iowordsize ) :
+  m_filename( filename ),
+  m_cpuwordsize( cpuwordsize ),
+  m_iowordsize( iowordsize ),
+  m_inFile( 0 ),
+  m_nnode( 0 ),
+  m_neblk( 0 ),
+  m_neset( 0 ),
+  m_from( 0 ),
+  m_till( 0 ),
+  m_blockid(),
+  m_blockid_by_type( ExoNnpe.size() ),
+  m_nel( ExoNnpe.size() ),
+  m_elemblocks(),
+  m_tri()
+// *****************************************************************************
+//  Constructor: open Exodus II file
+//! \param[in] filename File to open as ExodusII file
+//! \param[in] cpuwordsize Set CPU word size, see ExodusII documentation
+//! \param[in] iowordsize Set I/O word size, see ExodusII documentation
+// *****************************************************************************
+{
+  // Increase verbosity from ExodusII library in debug mode
+  #ifndef NDEBUG
+  ex_opts( EX_DEBUG | EX_VERBOSE );
+  #endif
 
-            /**
-             * @brief Given nodes A and B, generate an edge between them
-             *
-             * @param A First node
-             * @param B Second node
-             * @param lc Lock case for new edge
-             */
-            void generate(size_t A, size_t B, Edge_Lock_Case lc)
-            {
-                if ((A != 0) && (B != 0)) {
-                    trace_out << "A " << A << " B " << B << std::endl;
-                    assert(A != B);
-                }
-
-                // Generate key
-                edge_t keyAB = nodes_to_key(A, B);
-                //Create refined edge
-                Edge_Refinement edgeAB = Edge_Refinement(A, B, false, false, lc);
-                // Add edge to store
-                add(keyAB, edgeAB);
-            }
-
-            bool exists(edge_t key)
-            {
-                if (edges.find(key) != edges.end())
-                {
-                    return true;
-                }
-                return false;
-            }
-
-            /**
-             * @brief Function to retrieve an edge from the edge store
-             *
-             * @param key Key of the edge to get
-             *
-             * @return A reference to the fetched edge
-             */
-            Edge_Refinement& get(edge_t key)
-            {
-                //trace_out << "get edge " << key << std::endl;
-                // cppcheck-suppress assertWithSideEffect
-                if (!exists(key)) trace_out << "key not found " << key.first()
-                  << " - " << key.second() << std::endl;
-                assert( exists(key) );
-                return edges[key];
-            }
-
-            Edge_Lock_Case lock_case(const edge_t& key)
-            {
-                return get(key).lock_case;
-            }
-
-            void erase(edge_t key)
-            {
-                trace_out << "Deref removing edge: " << key.first() << " - "
-                  << key.second() << std::endl;
-                edges.erase(key);
-            }
-
-            /**
-             * @brief Function to add edge to edge store
-             *
-             * @param key The key for the given edge
-             * @param e The edge data
-             *
-             * Note: This tolerate the addition of duplicate edges
-             */
-            void add(edge_t key, Edge_Refinement e)
-            {
-                // Add edge if it doesn't exist (default behavior of insert)
-                edges.insert( std::pair<edge_t, Edge_Refinement>(key, e));
-
-                // TODO: It may be worth adding a check here to ensure if we're
-                // trying to add a new edge that exists it should contain the
-                // same data
-            }
-
-            static edge_t nodes_to_key(size_t A, size_t B)
-            {
-                return edge_t(A,B);
-            }
-
-            /**
-             * @brief Function to build a  string key from two node ids
-             * NOTE: Regardless of order of arguments, the same key will be generated
-             */
-            //static std::string nodes_to_key(size_t A, size_t B)
-            //{
-                //return std::to_string(std::min(A,B)) + KEY_DELIM + std::to_string(std::max(A,B));
-            //}
-
-            /**
-             * @brief function to take the nodes representing a face
-             * and to build the possible edges based on that
-             *
-             * For a given face {ABC}, generate the edge pairs {AB, AC, BC}
-             *
-             * @param face_ids The ids of the face to generate this for
-             *
-             * @return A (partially filled) list of all edges present on the
-             * face
-             */
-            // FIXME: Is it OK that it leaves some of the array blank?
-            static edge_list_t generate_keys_from_face_ids(face_ids_t face_ids)
-            {
-                edge_list_t key_list;
-                size_t A = face_ids[0];
-                size_t B = face_ids[1];
-                size_t C = face_ids[2];
-
-                edge_t key = nodes_to_key(A,B);
-                key_list[0] = key; // TODO: Is it OK to use copy assignment here?
-
-                key = nodes_to_key(A,C);
-                key_list[1] = key;
-
-                key = nodes_to_key(B,C);
-                key_list[2] = key;
-
-                return key_list;
-            }
+  float version;
+
+  m_inFile = ex_open( filename.c_str(), EX_READ, &cpuwordsize, &iowordsize,
+                      &version );
+
+  // output exodusII/netcdf configuration
+  //ex_print_config();
+
+  ErrChk( m_inFile > 0, "Failed to open ExodusII file: " + filename );
+}
+
+ExodusIIMeshReader::~ExodusIIMeshReader() noexcept
+// *****************************************************************************
+//  Destructor
+// *****************************************************************************
+{
+  if ( ex_close(m_inFile) < 0 )
+    printf( ">>> WARNING: Failed to close ExodusII file: %s\n",
+            m_filename.c_str() );
+}
+
+void
+ExodusIIMeshReader::readMesh( UnsMesh& mesh )
+// *****************************************************************************
+//  Read ExodusII mesh file
+//! \param[in] mesh Unstructured mesh object
+// *****************************************************************************
+{
+  readHeader( mesh );
+  readAllElements( mesh );
+  readAllNodes( mesh );
+  readSidesetFaces( mesh.bface(), mesh.faceid() );
+  readTimeValues( mesh.vartimes() );
+  readNodeVarNames( mesh.nodevarnames() );
+  readElemVarNames( mesh.elemvarnames() );
+  readNodeScalars( mesh.vartimes().size(),
+                   mesh.nodevarnames().size(),
+                   mesh.nodevars() );
+  readElemScalars( mesh.vartimes().size(),
+                   mesh.elemvarnames().size(),
+                   mesh.elemvars() );
+}
+
+void
+ExodusIIMeshReader::readGraph( UnsMesh& mesh )
+// *****************************************************************************
+//  Read only connectivity graph from file
+//! \param[in] mesh Unstructured mesh object
+// *****************************************************************************
+{
+  readHeader( mesh );
+  readAllElements( mesh );
+}
+
+void
+ExodusIIMeshReader::readMeshPart(
+  std::vector< std::size_t >& ginpoel,
+  std::vector< std::size_t >& inpoel,
+  std::vector< std::size_t >& triinp,
+  std::unordered_map< std::size_t, std::size_t >& lid,
+  tk::UnsMesh::Coords& coord,
+  std::unordered_map< std::size_t, std::set< std::size_t > >& elemBlockId,
+  int numpes, int mype )
+// *****************************************************************************
+//  Read a part of the mesh (graph and coordinates) from ExodusII file
+//! \param[in,out] ginpoel Container to store element connectivity of this PE's
+//!   chunk of the mesh (global ids)
+//! \param[in,out] inpoel Container to store element connectivity with local
+//!   node IDs of this PE's mesh chunk
+//! \param[in,out] triinp Container to store triangle element connectivity
+//!   (if exists in file) with global node indices
+//! \param[in,out] lid Container to store global->local node IDs of elements of
+//!   this PE's mesh chunk
+//! \param[in,out] coord Container to store coordinates of mesh nodes of this
+//!   PE's mesh chunk
+//! \param[in,out] elemBlockId List of elements for each block-id.
+//! \param[in] numpes Total number of PEs (default n = 1, for a single-CPU read)
+//! \param[in] mype This PE (default m = 0, for a single-CPU read)
+// *****************************************************************************
+{
+  Assert( mype < numpes, "Invalid input: PE id must be lower than NumPEs" );
+  Assert( ginpoel.empty() && inpoel.empty() && lid.empty() &&
+          coord[0].empty() && coord[1].empty() && coord[2].empty(),
+          "Containers to store mesh must be empty" );
+
+  // Read info on element blocks from ExodusII file
+  readElemBlockIDs();
+  // Get number of number of tetrahedron elements in file
+  auto nel = nelem( tk::ExoElemType::TET );
+
+  // Compute extents of element IDs of this PE's mesh chunk to read
+  auto npes = static_cast< std::size_t >( numpes );
+  auto pe = static_cast< std::size_t >( mype );
+  auto chunk = nel / npes;
+  m_from = pe * chunk;
+  m_till = m_from + chunk;
+  if (pe == npes-1) m_till += nel % npes;
+
+  // Read tetrahedron connectivity between from and till
+  readElements( {{m_from, m_till-1}}, tk::ExoElemType::TET, ginpoel );
+  elemBlockId = m_elemInBlockId;
+
+  // Compute local data from global mesh connectivity
+  std::vector< std::size_t > gid;
+  std::tie( inpoel, gid, lid ) = tk::global2local( ginpoel );
+
+  // Read this PE's chunk of the mesh node coordinates from file
+  coord = readCoords( gid );
+
+  // Generate set of unique faces
+  tk::UnsMesh::FaceSet faces;
+  for (std::size_t e=0; e<ginpoel.size()/4; ++e)
+    for (std::size_t f=0; f<4; ++f) {
+      const auto& tri = tk::expofa[f];
+      faces.insert( {{{ ginpoel[ e*4+tri[0] ],
+                        ginpoel[ e*4+tri[1] ],
+                        ginpoel[ e*4+tri[2] ] }}} );
+    }
+
+  // Read triangle element connectivity (all triangle blocks in file)
+  auto ntri = nelem( tk::ExoElemType::TRI );
+  if ( ntri !=0 ) readElements( {{0,ntri-1}}, tk::ExoElemType::TRI, triinp );
 
-            /**
-             * @brief function to take a list of edge and mark them all
-             * as needing to be refined
-             *
-             * @param ids List of ids to mark for refinement
-             */
-            void mark_edges_for_refinement(std::vector<node_pair_t> ids) {
-                for (const auto& id : ids)
-            {
-                    edge_t key = nodes_to_key(id[0], id[1]);
-
-                    mark_for_refinement(key);
-                    trace_out << get(key).needs_refining << std::endl;
-                }
-            }
-
-
-            /**
-             * @brief function to mark a single edge as needing
-             * refinement (provides a nice abstraction from messing with the
-             * struct directly).
-             *
-             * @param key The edge key to mark as refinement
-             */
-            void mark_for_refinement(const edge_t& key)
-            {
-                // cppcheck-suppress assertWithSideEffect
-                assert( exists(key) );
-                get(key).needs_refining = 1;
-            }
-
-            /**
-             * @brief function to take a list of edge and mark them all
-             * as needing to be refined as a part of the 8:4 derefinement
-             *
-             * @param ids List of ids to mark for deref-refinement
-             */
-            void mark_edges_for_deref_ref(std::vector<node_pair_t> ids)
-            {
-              for (const auto& id : ids)
-                {
-                  edge_t key = nodes_to_key(id[0], id[1]);
-
-                  // cppcheck-suppress assertWithSideEffect
-                  assert( exists(key) );
-                  // value of 2 for needs_refining indicates part of derefine
-                  get(key).needs_refining = 2;
-
-                  trace_out << "edge: " << key.get_data()[0] << "-"
-                    << key.get_data()[1] << " deref-ref: "
-                    << get(key).needs_refining << std::endl;
-                }
-            }
-
-            /**
-             * @brief Function to unmark and edge as needing refinement
-             *
-             * @param key The key representing the edge to unmark
-             */
-            void unmark_for_refinement(const edge_t& key)
-            {
-                // cppcheck-suppress assertWithSideEffect
-                assert( exists(key) );
-                get(key).needs_refining = 0;
-            }
-
-            /**
-             * @brief For a given list of node pairs, mark the edge as needing
-             * to be de-refined
-             *
-             * @param ids a vector of pairs to mark for derefinement
-             */
-            void mark_edges_for_derefinement(std::vector<node_pair_t> ids) {
-                for (const auto& id : ids)
-                {
-                    edge_t key = nodes_to_key(id[0], id[1]);
-
-                    mark_edge_for_derefinement(key);
-                }
-            }
-            void mark_edge_for_derefinement(const edge_t& key) {
-                    get(key).needs_derefining = true;
-            }
-
-
-            /**
-             * @brief Function to generate a list of edge keys from a tet
-             *
-             * @param tet The tet to generate edge pairs for
-             *
-             * @return A list (array) of edge keys which can be separated out to
-             * name the two composing node ids
-             */
-            edge_list_t generate_keys(tet_t tet)
-            {
-                // FIXME : Generate these with a (2d) loop and not hard code them?
-                edge_list_t key_list;
-
-                size_t A = tet[0];
-                size_t B = tet[1];
-                size_t C = tet[2];
-                size_t D = tet[3];
-
-                edge_t key;
+  // Keep triangles shared in (partially-read) tetrahedron mesh
+  std::vector< std::size_t > triinp_own;
+  std::size_t ltrid = 0;        // local triangle id
+  for (std::size_t e=0; e<triinp.size()/3; ++e) {
+    auto i = faces.find( {{ triinp[e*3+0], triinp[e*3+1], triinp[e*3+2] }} );
+    if (i != end(faces)) {
+      m_tri[e] = ltrid++;       // generate global->local triangle ids
+      triinp_own.push_back( triinp[e*3+0] );
+      triinp_own.push_back( triinp[e*3+1] );
+      triinp_own.push_back( triinp[e*3+2] );
+    }
+  }
+  triinp = std::move(triinp_own);
+}
+
+std::array< std::vector< tk::real >, 3 >
+ExodusIIMeshReader::readCoords( const std::vector< std::size_t >& gid ) const
+// *****************************************************************************
+//  Read coordinates of a number of mesh nodes from ExodusII file
+//! \param[in] gid Global node IDs whose coordinates to read
+//! \return Vector of node coordinates read from file
+// *****************************************************************************
+{
+  // Read node coordinates from file with global node IDs given in gid
+  return readNodes( gid );
+}
+
+std::size_t
+ExodusIIMeshReader::readHeader()
+// *****************************************************************************
+//  Read ExodusII header without setting mesh size
+//! \return Number of nodes in mesh
+// *****************************************************************************
+{
+  char title[MAX_LINE_LENGTH+1];
+  int ndim, nelem, nnodeset, nelemset, nnode, neblk;
+
+  ErrChk(
+    ex_get_init( m_inFile, title, &ndim, &nnode, &nelem, &neblk, &nnodeset,
+                 &nelemset ) == 0,
+    "Failed to read header from ExodusII file: " + m_filename );
+
+  ErrChk( nnode > 0,
+          "Number of nodes read from ExodusII file must be larger than zero" );
+  ErrChk( neblk > 0,
+          "Number of element blocks read from ExodusII file must be larger "
+          "than zero" );
+  ErrChk( ndim == 3, "Need a 3D mesh from ExodusII file " + m_filename );
+
+  m_nelem = static_cast< std::size_t >( nelem );
+  m_neblk = static_cast< std::size_t >( neblk );
+  m_neset = static_cast< std::size_t >( nelemset );
+
+  return static_cast< std::size_t >( nnode );
+}
+
+void
+ExodusIIMeshReader::readHeader( UnsMesh& mesh )
+// *****************************************************************************
+//  Read ExodusII header with setting mesh size
+//! \param[in] mesh Unstructured mesh object
+// *****************************************************************************
+{
+  // Read ExodusII file header and set mesh graph size
+  mesh.size() = m_nnode = static_cast< std::size_t >( readHeader() );
+}
+
+void
+ExodusIIMeshReader::readAllNodes( UnsMesh& mesh ) const
+// *****************************************************************************
+//  Read all node coordinates from ExodusII file
+//! \param[in] mesh Unstructured mesh object
+// *****************************************************************************
+{
+  mesh.x().resize( m_nnode );
+  mesh.y().resize( m_nnode );
+  mesh.z().resize( m_nnode );
+
+  ErrChk( ex_get_coord( m_inFile, mesh.x().data(), mesh.y().data(),
+                        mesh.z().data() ) == 0,
+          "Failed to read coordinates from ExodusII file: " + m_filename );
+}
+
+void
+ExodusIIMeshReader::readNode( std::size_t fid,
+                              std::size_t mid,
+                              std::vector< tk::real >& x,
+                              std::vector< tk::real >& y,
+                              std::vector< tk::real >& z ) const
+// *****************************************************************************
+//  Read coordinates of a single mesh node from ExodusII file
+//! \param[in] fid Node id in file whose coordinates to read
+//! \param[in] mid Node id in memory to which to put new cordinates
+//! \param[in,out] x Vector of x coordinates to push to
+//! \param[in,out] y Vector of y coordinates to push to
+//! \param[in,out] z Vector of z coordinates to push to
+// *****************************************************************************
+{
+  Assert( x.size() == y.size() && x.size() == z.size(), "Size mismatch" );
+  Assert( mid < x.size() && mid < y.size() && mid < z.size(),
+          "Indexing out of bounds" );
+
+  readNode( fid, x[mid], y[mid], z[mid] );
+}
 
-                key = nodes_to_key(A,B);
-                key_list[0] = key;
-
-                key = nodes_to_key(A,C);
-                key_list[1] = key;
-
-                key = nodes_to_key(A,D);
-                key_list[2] = key;
-
-                key = nodes_to_key(B,C);
-                key_list[3] = key;
+void
+ExodusIIMeshReader::readNode( std::size_t id,
+                              std::array< tk::real, 3 >& coord ) const
+// *****************************************************************************
+//  Read coordinates of a single mesh node from ExodusII file
+//! \param[in] id Node id whose coordinates to read
+//! \param[in,out] coord Array of x, y, and z coordinates
+// *****************************************************************************
+{
+  readNode( id, coord[0], coord[1], coord[2] );
+}
 
-                key = nodes_to_key(B,D);
-                key_list[4] = key;
-
-                key = nodes_to_key(C,D);
-                key_list[5] = key;
-
-                return key_list;
-            }
-
-            /**
-             * @brief Helper debug function to print edge information
-             */
-            void print() {
-                for (const auto& kv : edges)
-                {
-                    trace_out << "edge " << kv.first << " between " <<
-                        kv.second.A << " and " << kv.second.B <<
-                    std::endl;
-                }
-            }
-    };
-}
-
-#endif // AMR_edge_store
+void
+ExodusIIMeshReader::readNode( std::size_t id,
+                              tk::real& x,
+                              tk::real& y,
+                              tk::real& z ) const
+// *****************************************************************************
+// Read coordinates of a single mesh node from file
+//! \param[in] id Node id whose coordinates to read
+//! \param[in,out] x X coordinate to write to
+//! \param[in,out] y Y coordinate to write to
+//! \param[in,out] z Z coordinate to write to
+// *****************************************************************************
+{
+  ErrChk(
+    ex_get_partial_coord( m_inFile, static_cast<int64_t>(id)+1, 1,
+                          &x, &y, &z ) == 0,
+    "Failed to read coordinates of node " + std::to_string(id) +
+    " from ExodusII file: " + m_filename );
+}
+
+std::array< std::vector< tk::real >, 3 >
+ExodusIIMeshReader::readNodes( const std::vector< std::size_t >& gid ) const
+// *****************************************************************************
+//  Read coordinates of a number of mesh nodes from ExodusII file
+//! \param[in] gid Node IDs whose coordinates to read
+//! \return Mesh node coordinates
+// *****************************************************************************
+{
+  std::vector< tk::real > px( gid.size() ), py( gid.size() ), pz( gid.size() );
+
+  std::size_t i=0;
+  for (auto g : gid) readNode( g, i++, px, py, pz );
+
+  return {{ std::move(px), std::move(py), std::move(pz) }};
+}
+
+std::size_t
+ExodusIIMeshReader::readElemBlockIDs()
+// *****************************************************************************
+//  Read element block IDs from ExodusII file
+//! \return Total number of nodes in mesh
+// *****************************************************************************
+{
+  // Read ExodusII file header
+  auto nnode = readHeader();<--- Variable 'nnode' is assigned a value that is never used.
+
+  std::vector< int > bid( m_neblk );
+
+  // Read element block ids
+  ErrChk( ex_get_ids( m_inFile, EX_ELEM_BLOCK, bid.data()) == 0,
+          "Failed to read element block ids from ExodusII file: " +
+          m_filename );
+
+  m_elemblocks.clear();
+  m_nel.clear();
+  m_nel.resize( ExoNnpe.size() );
+  m_blockid_by_type.clear();
+  m_blockid_by_type.resize( ExoNnpe.size() );
+
+  // Fill element block ID vector
+  for (auto id : bid) {
+    char eltype[MAX_STR_LENGTH+1];
+    int n, nnpe, nattr;
+
+    // Read element block information
+    ErrChk( ex_get_block( m_inFile, EX_ELEM_BLOCK, id, eltype, &n, &nnpe,
+                          &nattr, nullptr, nullptr ) == 0,
+      "Failed to read element block information from ExodusII file: " +
+      m_filename );
+
+    // Store ExodusII element block ID
+    m_blockid.push_back( id );
+
+    auto nel = static_cast< std::size_t >( n );
+
+    // Store info on ExodusII element blocks
+    if (nnpe == 4) {        // tetrahedra
+
+      m_elemblocks.push_back( { ExoElemType::TET, nel } );
+      auto e = static_cast< std::size_t >( ExoElemType::TET );
+      m_blockid_by_type[ e ].push_back( id );
+      m_nel[ e ].push_back( nel );
+      Assert( m_blockid_by_type[e].size() == m_nel[e].size(), "Size mismatch" );
+
+    } else if (nnpe == 3) { // triangles
+
+      m_elemblocks.push_back( { ExoElemType::TRI, nel } );
+      auto e = static_cast< std::size_t >( ExoElemType::TRI );
+      m_blockid_by_type[ e ].push_back( id );
+      m_nel[ e ].push_back( nel );
+      Assert( m_blockid_by_type[e].size() == m_nel[e].size(), "Size mismatch" );
+
+    }
+  }
+
+  return nnode;
+}
+
+void
+ExodusIIMeshReader::readAllElements( UnsMesh& mesh )
+// *****************************************************************************
+//  Read all element blocks and mesh connectivity from ExodusII file
+//! \param[inout] mesh Unstructured mesh object to store mesh in
+// *****************************************************************************
+{
+  // Read element block ids
+  readElemBlockIDs();
+
+  for (auto id : m_blockid) {
+    char eltype[MAX_STR_LENGTH+1];
+    int nel, nnpe, nattr;
+
+    // Read element block information
+    ErrChk( ex_get_block( m_inFile, EX_ELEM_BLOCK, id, eltype, &nel, &nnpe,
+                          &nattr, nullptr, nullptr ) == 0,
+      "Failed to read element block information from ExodusII file: " +
+      m_filename );
+
+    // Read element connectivity
+    auto connectsize = static_cast< std::size_t >( nel*nnpe );
+    if (nnpe == 4) {    // tetrahedra
+
+      std::vector< int > inpoel( connectsize );
+      ErrChk( ex_get_conn( m_inFile, EX_ELEM_BLOCK, id, inpoel.data(),
+                           nullptr, nullptr ) == 0,
+        "Failed to read " + std::string(eltype) + " element connectivity from "
+        "ExodusII file: " + m_filename );
+      for (auto n : inpoel)
+        mesh.tetinpoel().push_back( static_cast< std::size_t >( n ) );
+
+    } else if (nnpe == 3) {    // triangles
+
+      std::vector< int > inpoel( connectsize );
+      ErrChk( ex_get_conn( m_inFile, EX_ELEM_BLOCK, id, inpoel.data(),
+                           nullptr, nullptr ) == 0,
+        "Failed to read " + std::string(eltype) + " element connectivity from "
+        "ExodusII file: " + m_filename );
+      for (auto n : inpoel)
+        mesh.triinpoel().push_back( static_cast< std::size_t >( n ) );
+
+    }
+  }
+
+  // Shift node IDs to start from zero
+  shiftToZero( mesh.triinpoel() );
+  shiftToZero( mesh.tetinpoel() );
+}
+
+void
+ExodusIIMeshReader::readElements( const std::array< std::size_t, 2 >& ext,
+                                  tk::ExoElemType elemtype,
+                                  std::vector< std::size_t >& conn )
+// *****************************************************************************
+//  Read element connectivity of a number of mesh cells from ExodusII file
+//! \param[in] ext Extents of element IDs whose connectivity to read:
+//!   [from...till), using zero-based element IDs, where 'from' >=0, inclusive
+//!   and 'till < 'maxelements', where 'maxelements' is the total number of
+//!   elements of all element blocks in the file of the requested cell type.
+//!   Note that 'maxelements' can be queried by nelem().
+//! \param[in] elemtype Element type
+//! \param[inout] conn Connectivity vector to push to
+//! \note Must be preceded by a call to readElemBlockIDs()
+//! \details This function takes the extents of element IDs in a zero-based
+//!   fashion. These input extents can be thought of "absolute" extents that
+//!   denote lowest and the largest-1 element IDs to be read from file.
+//!   The mesh block-wise element set is also updated.
+// *****************************************************************************
+{
+  Assert( tk::sumsize(m_blockid_by_type) > 0,
+          "A call to this function must be preceded by a call to "
+          "ExodusIIMeshReader::readElemBlockIDs()" );
+  Assert( ext[0] <= ext[1] &&
+          ext[0] < nelem(elemtype) &&
+          ext[1] < nelem(elemtype),
+          "Invalid element ID extents. Of the requested extents [from...till), "
+          "'from' must be lower than or equal to 'till', and they must be in "
+          "the range [0...maxelements), where 'maxelements' is the total "
+          "number of elements of all element blocks in the file of the "
+          "requested cell type. Requested element ID extents: ["
+          + std::to_string(ext[0]) + "..." + std::to_string(ext[1])
+          + "), 'maxelements' of cell type with "
+          + std::to_string( ExoNnpe[ static_cast<std::size_t>(elemtype) ] )
+          + " nodes per cell in file '" + m_filename + "': "
+          + std::to_string( nelem( elemtype ) ) );
+
+  auto e = static_cast< std::size_t >( elemtype );
+  // List of number of elements of all blocks of element type requested
+  const auto& nel = m_nel[e];
+  // List of element block IDs for element type requested
+  const auto& bid = m_blockid_by_type[e];
+
+  // Compute lower and upper element block ids to read from based on extents
+  std::size_t lo_bid = 0, hi_bid = 0, offset = 0;
+  for (std::size_t b=0; b<nel.size(); ++b) {
+    std::size_t lo = offset;                    // lo (min) elem ID in block
+    std::size_t hi = offset + nel[b] - 1;       // hi (max) elem ID in block
+    if (ext[0] >= lo && ext[0] <= hi) lo_bid = b;
+    if (ext[1] >= lo && ext[1] <= hi) hi_bid = b;
+    offset += nel[b];
+  }
+
+  Assert( lo_bid < nel.size() && lo_bid < bid.size(),
+          "Invalid start block ID" );
+  Assert( hi_bid < nel.size() && hi_bid < bid.size(),
+          "Invalid end block ID" );
+
+  // Compute relative extents based on absolute ones for each block to read from
+  std::vector< std::array< std::size_t, 2 > > rext;
+  offset = 0;
+  for (std::size_t b=0; b<lo_bid; ++b) offset += nel[b];
+  for (std::size_t b=lo_bid; b<=hi_bid; ++b) {
+    std::size_t lo = offset;
+    std::size_t hi = offset + nel[b] - 1;
+    std::size_t le = 1, he = nel[b];
+    if (ext[0] >= lo && ext[0] <= hi) le = ext[0] - lo + 1;
+    if (ext[1] >= lo && ext[1] <= hi) he = ext[1] - lo + 1;
+    Assert( le >= 1 && le <= nel[b] && he >= 1 && he <= nel[b],
+            "Relative index out of block" );
+    rext.push_back( {{ le, he }} );
+    offset += nel[b];
+  }
+
+  Assert( std::accumulate(
+            std::next(rext.cbegin()), rext.cend(), rext[0][1]-rext[0][0]+1,
+            []( std::size_t n, const std::array< std::size_t, 2 >& r )
+            { return n + r[1] - r[0] + 1; }
+          ) == ext[1]-ext[0]+1,
+          "Total number of elements to read incorrect, requested extents: " +
+          std::to_string(ext[0]) + " ... " + std::to_string(ext[1]) );
+
+  std::vector< int > inpoel;
+
+  // Read element connectivity from file
+  std::size_t B = 0;
+  for (auto b=lo_bid; b<=hi_bid; ++b, ++B) {
+    const auto& r = rext[B];
+    std::vector< int > c( (r[1]-r[0]+1) * ExoNnpe[e] );
+    ErrChk( ex_get_partial_conn( m_inFile,
+                                 EX_ELEM_BLOCK,
+                                 bid[b],
+                                 static_cast< int64_t >( r[0] ),
+                                 static_cast< int64_t >( r[1]-r[0]+1 ),
+                                 c.data(),
+                                 nullptr,
+                                 nullptr ) == 0,
+            "Failed to read element connectivity of elements [" +
+            std::to_string(r[0]) + "..." + std::to_string(r[1]) +
+            "] from element block " + std::to_string(bid[b]) + " in ExodusII "
+            "file: " + m_filename );
+
+    // Store tet-elements under their respective mesh block ids
+    if (elemtype == ExoElemType::TET) {
+      for (std::size_t i=0; i<c.size()/ExoNnpe[e]; ++i) {
+        auto& tetblk = m_elemInBlockId[static_cast<std::size_t>(bid[b])];
+        tetblk.insert((inpoel.size()/ExoNnpe[e]) + i);
+      }
+    }
+
+    inpoel.reserve( inpoel.size() + c.size() );
+    std::move( begin(c), end(c), std::back_inserter(inpoel) );
+  }
+
+  Assert( inpoel.size() == (ext[1]-ext[0]+1)*ExoNnpe[e],
+          "Failed to read element connectivity of elements [" +
+          std::to_string(ext[0]) + "..." + std::to_string(ext[1]) + ") from "
+          "ExodusII file: " + m_filename );
+
+  // Put in element connectivity using zero-based node indexing
+  for (auto& i : inpoel) --i;
+  conn.reserve( conn.size() + inpoel.size() );
+  std::move( begin(inpoel), end(inpoel), std::back_inserter(conn) );
+}
+
+void
+ExodusIIMeshReader::readFaces( std::vector< std::size_t >& conn )
+// *****************************************************************************
+//  Read face connectivity of a number of boundary faces from ExodusII file
+//! \param[inout] conn Connectivity vector to push to
+//! \details This function reads in the total number of boundary faces,
+//!   also called triangle-elements in the EXO2 file, and their connectivity.
+// *****************************************************************************
+{
+  // Return quietly if no triangle elements in file
+  if (nelem(tk::ExoElemType::TRI) == 0) return;
+
+  // Read triangle boundary-face connectivity (all the triangle element block)
+  readElements( {{0,nelem(tk::ExoElemType::TRI)-1}}, tk::ExoElemType::TRI,
+                conn );
+}
+
+std::vector< std::size_t >
+ExodusIIMeshReader::readNodemap()
+// *****************************************************************************
+//  Read local to global node-ID map from ExodusII file
+//! \return node_map Vector mapping the local Exodus node-IDs to global node-IDs
+//! \details The node-map is required to get the "Exodus-global" node-IDs from
+//!   the "Exodus-internal" node-IDs, which are returned from the exodus APIs.
+//!   The node-IDs in the exodus file are referred to as the "Exodus-global"
+//!   node-IDs or "fileIDs" in Quinoa.
+// *****************************************************************************
+{
+  // Read triangle boundary-face connectivity
+  auto nnode = readElemBlockIDs();
+
+  // Create array to store node-number map
+  std::vector< int > node_map( nnode );
+
+  // Read in the node number map to map the above nodes to the global node-IDs
+  ErrChk( ex_get_id_map( m_inFile, EX_NODE_MAP, node_map.data() ) == 0,
+          "Failed to read node map length from ExodusII file: " );
+
+  std::vector< std::size_t > node_map1( nnode );
+
+  for (std::size_t i=0; i<nnode; ++i)
+  {
+          node_map1[i] = static_cast< std::size_t >(node_map[i]-1);
+  }
+
+  return node_map1;
+}
+
+std::map< int, std::vector< std::size_t > >
+ExodusIIMeshReader::readSidesetNodes()
+// *****************************************************************************
+//  Read node list of all side sets from ExodusII file
+//! \return Node lists mapped to side set ids
+// *****************************************************************************
+{
+  // Read ExodusII file header (fills m_neset)
+  readHeader();
+
+  // Node lists mapped to side set ids
+  std::map< int, std::vector< std::size_t > > side;
+
+  if (m_neset > 0) {
+    // Read all side set ids from file
+    std::vector< int > ids( m_neset );
+    ErrChk( ex_get_ids( m_inFile, EX_SIDE_SET, ids.data() ) == 0,
+            "Failed to read side set ids from ExodusII file: " + m_filename );
+    // Read in node list for all side sets
+    for (auto i : ids) {
+      int nface, nnode;
+      // Read number of faces and number of distribution factors in side set i
+      ErrChk( ex_get_set_param( m_inFile, EX_SIDE_SET, i, &nface, &nnode ) == 0,
+              "Failed to read side set " + std::to_string(i) + " parameters "
+              "from ExodusII file: " + m_filename );
+      // Read number of nodes in side set i (overwrite nnode)
+      ErrChk( ex_get_side_set_node_list_len( m_inFile, i, &nnode ) == 0,
+              "Failed to read side set " + std::to_string(i) + " node list "
+              "length from ExodusII file: " + m_filename );
+      Assert(nnode > 0, "Number of nodes = 0 in side set" + std::to_string(i));
+      std::vector< int > df( static_cast< std::size_t >( nface ) );
+      std::vector< int > nodes( static_cast< std::size_t >( nnode ) );
+      // Read in node list for side set i
+      ErrChk( ex_get_side_set_node_list( m_inFile, i, df.data(), nodes.data() )
+                == 0, "Failed to read node list of side set " +
+                      std::to_string(i) + " from ExodusII file: " +
+                      m_filename );
+      // Make node list unique
+      tk::unique( nodes );
+      // Store 0-based node ID list as std::size_t vector instead of ints
+      auto& list = side[ i ];
+      for (auto n : nodes) list.push_back( static_cast<std::size_t>(n-1) );<--- Consider using std::transform algorithm instead of a raw loop.
+    }
+  }
+
+  return side;
+}
+
+void
+ExodusIIMeshReader::readSidesetFaces(
+  std::map< int, std::vector< std::size_t > >& bface,
+  std::map< int, std::vector< std::size_t > >& faces )
+// *****************************************************************************
+//  Read side sets from ExodusII file
+//! \param[in,out] bface Elem ids of side sets to read into
+//! \param[in,out] faces Elem-relative face ids of tets of side sets
+// *****************************************************************************
+{
+  // Read element block ids
+  readElemBlockIDs();
+
+  if (m_neset > 0) {
+    // Read side set ids from file
+    std::vector< int > ids( m_neset );
+    ErrChk( ex_get_ids( m_inFile, EX_SIDE_SET, ids.data() ) == 0,
+            "Failed to read side set ids from ExodusII file: " + m_filename );
+
+    // Read all side sets from file
+    for (auto i : ids) {
+      int nface, nnode;
+
+      // Read number of faces in side set
+      ErrChk( ex_get_set_param( m_inFile, EX_SIDE_SET, i, &nface, &nnode ) == 0,
+              "Failed to read side set " + std::to_string(i) + " parameters "
+              "from ExodusII file: " + m_filename );
+
+      Assert(nface > 0, "Number of faces = 0 in side set" + std::to_string(i));
+
+      std::vector< int > exoelem( static_cast< std::size_t >( nface ) );
+      std::vector< int > exoface( static_cast< std::size_t >( nface ) );
+
+      // Read in file-internal element ids and relative face ids for side set
+      ErrChk( ex_get_set( m_inFile, EX_SIDE_SET, i, exoelem.data(),
+                          exoface.data() ) == 0,
+              "Failed to read side set " + std::to_string(i) );
+
+      // Store file-internal element ids of side set
+      auto& elem = bface[i];
+      elem.resize( exoelem.size() );
+      std::size_t j = 0;
+      for (auto e : exoelem) elem[j++] = static_cast< std::size_t >( e-1 );
+
+      // Store zero-based relative face ids of side set
+      auto& face = faces[i];
+      face.resize( exoface.size() );
+      j = 0;
+      for (auto n : exoface) face[j++] = static_cast< std::size_t >( n-1 );
+
+      Assert( std::all_of( begin(face), end(face),
+                           [](std::size_t f){ return f<4; } ),
+              "Relative face id of side set must be between 0 and 3" );
+      Assert( elem.size() == face.size(), "Size mismatch" );
+    }
+  }
+}
+
+std::pair< tk::ExoElemType, std::size_t >
+ExodusIIMeshReader::blkRelElemId( std::size_t id ) const
+// *****************************************************************************
+// Compute element-block-relative element id and element type
+//! \param[in] id (ExodusII) file-internal element id
+//! \return Element type the internal id points to and element id relative to
+//!   cell-type
+//! \details This function takes an internal element id, which in general can
+//!   point to any element block in the ExodusII file and thus we do not know
+//!   which element type a block contains. It then computes which cell type the
+//!   id points to and computes the relative index for the given cell type. This
+//!   is necessary because elements are read in from file by from potentially
+//!   multiple blocks by cell type.
+//! \note Must be preceded by a call to readElemBlockIDs()
+// *****************************************************************************
+{
+  auto TRI = tk::ExoElemType::TRI;
+  auto TET = tk::ExoElemType::TET;
+
+  std::size_t e = 0;            // counts elements (independent of cell type)
+  std::size_t ntri = 0;         // counts triangle elements
+  std::size_t ntet = 0;         // counts tetrahedron elements
+
+  for (const auto& b : m_elemblocks) {  // walk all element blocks in order
+    e += b.second;                      // increment file-internal element id
+    if (e > id) {                       // found element block for internal id
+      if (b.first == TRI) {             // if triangle block
+        return { TRI, id-ntet };        // return cell type and triangle id
+      } else if (b.first == TET) {      // if tetrahedron block
+        return { TET, id-ntri };        // return cell type and tetrahedron id
+      }
+    }
+    // increment triangle and tetrahedron elements independently
+    if (b.first == TRI)
+      ntri += b.second;
+    else if (b.first == TET)
+      ntet += b.second;
+  }
+
+  Throw( " Exodus internal element id not found" );
+}
+
+std::vector< std::size_t >
+ExodusIIMeshReader::triinpoel(
+  std::map< int, std::vector< std::size_t > >& belem,
+  const std::map< int, std::vector< std::size_t > >& faces,
+  const std::vector< std::size_t >& ginpoel,
+  const std::vector< std::size_t >& triinp ) const
+// *****************************************************************************
+//  Generate triangle face connectivity for side sets
+//! \param[in,out] belem File-internal elem ids of side sets
+//! \param[in] faces Elem-relative face ids of side sets
+//! \param[in] ginpoel Tetrahedron element connectivity with global nodes
+//! \param[in] triinp Triangle element connectivity with global nodes
+//!   (if exists in file)
+//! \return Triangle face connectivity with global node IDs of side sets
+//! \details This function takes lists of file-internal element ids (in belem)
+//!   for side sets and does two things: (1) generates face connectivity (with
+//!   global node IDs) for side sets, and (2) converts the (ExodusII)
+//!   file-internal element IDs to face ids so that they can be used to index
+//!   into the face connectivity. The IDs in belem are modified and the face
+//!   connectivity (for boundary faces only) is returned.
+//! \note Must be preceded by a call to readElemBlockIDs()
+// *****************************************************************************
+{
+  Assert( !(m_from == 0 && m_till == 0),
+          "Lower and upper tetrahedron id bounds must not both be zero" );
+
+  // This will contain one of our final results: face (triangle) connectivity
+  // for the side sets only. The difference between bnd_triinpoel and triinpoel
+  // is that triinpoel is a triangle element connectivity, independent of side
+  // sets, while bnd_triinpoel is a triangle connectivity only for side sets.
+  std::vector< std::size_t > bnd_triinpoel;
+
+  // Storage for boundary face lists for each side set on this PE
+  std::map< int, std::vector< std::size_t > > belem_own;
+
+  std::size_t f = 0;            // counts all faces
+  for (auto& ss : belem) {      // for all side sets
+
+    // insert side set id into new map
+    auto& b = belem_own[ ss.first ];
+    // get element-relative face ids for side set
+    const auto& face = tk::cref_find( faces, ss.first );
+    std::size_t s = 0;          // counts side set faces
+    for (auto& i : ss.second) { // for all faces on side set
+
+      // compute element-block-relative element id and element type
+      auto r = blkRelElemId( i );
+
+      // extract boundary face connectivity based on element type
+      bool localface = false;
+      if (r.first == tk::ExoElemType::TRI) {
+
+        auto t = m_tri.find(r.second);
+        if (t != end(m_tri)) {  // only if triangle id exists on this PE
+          Assert( t->second < triinp.size()/3,
+                  "Indexing out of triangle connectivity" );
+          // generate triangle (face) connectivity using global node ids
+          bnd_triinpoel.push_back( triinp[ t->second*3 + 0 ] );
+          bnd_triinpoel.push_back( triinp[ t->second*3 + 1 ] );
+          bnd_triinpoel.push_back( triinp[ t->second*3 + 2 ] );
+          localface = true;
+        }
+
+      } else if (r.first == tk::ExoElemType::TET) {
+
+        if (r.second >= m_from && r.second < m_till) {  // if tet is on this PE
+          auto t = r.second - m_from;
+          Assert( t < ginpoel.size()/4,
+                  "Indexing out of tetrahedron connectivity" );
+          // get ExodusII face-node numbering for side sets, see ExodusII
+          // manual figure on "Sideset side Numbering"
+          const auto& tri = tk::expofa[ face[s] ];
+          // generate triangle (face) connectivity using global node ids, note
+          // the switched node order, 0,2,1, as lpofa is different from expofa
+          bnd_triinpoel.push_back( ginpoel[ t*4 + tri[0] ] );
+          bnd_triinpoel.push_back( ginpoel[ t*4 + tri[1] ] );
+          bnd_triinpoel.push_back( ginpoel[ t*4 + tri[2] ] );
+          localface = true;
+        }
+
+      }
+
+      ++s;
+
+      // generate PE-local face id for side set (this is to be used to index
+      // into triinpoel)
+      if (localface) b.push_back( f++ );
+    }
+
+    // if no faces on this side set (on this PE), remove side set id
+    if (b.empty()) belem_own.erase( ss.first );
+  }
+
+  belem = std::move(belem_own);
+
+  return bnd_triinpoel;
+}
+
+void
+ExodusIIMeshReader::readNodeVarNames( std::vector< std::string >& nv ) const
+// *****************************************************************************
+//  Read the names of nodal output variables from ExodusII file
+//! \param[in,out] nv Nodal variable names
+// *****************************************************************************
+{
+  #if defined(__clang__)
+    #pragma clang diagnostic push
+    #pragma clang diagnostic ignored "-Wvla"
+    #pragma clang diagnostic ignored "-Wvla-extension"
+  #elif defined(STRICT_GNUC)
+    #pragma GCC diagnostic push
+    #pragma GCC diagnostic ignored "-Wvla"
+  #endif
+
+  int numvars = 0;
+
+  ErrChk(
+    ex_get_variable_param( m_inFile, EX_NODE_BLOCK, &numvars ) == 0,
+    "Failed to read nodal output variable parameters from ExodusII file: " +
+    m_filename );
+
+  if (numvars) {
+
+    char* names[ static_cast< std::size_t >( numvars ) ];
+    for (int i=0; i<numvars; ++i)
+      names[i] = static_cast<char*>( calloc((MAX_STR_LENGTH+1), sizeof(char)) );
+
+    ErrChk( ex_get_variable_names( m_inFile,
+                                   EX_NODAL,
+                                   numvars,
+                                   names ) == 0,
+            "Failed to read nodal variable names from ExodusII file: " +
+            m_filename );
+
+    nv.resize( static_cast< std::size_t >( numvars ) );
+    std::size_t i = 0;
+    for (auto& n : nv) n = names[ i++ ];<--- Consider using std::fill or std::generate algorithm instead of a raw loop.
+
+  }
+
+  #if defined(__clang__)
+    #pragma clang diagnostic pop
+  #elif defined(STRICT_GNUC)
+    #pragma GCC diagnostic pop
+  #endif
+}
+
+void
+ExodusIIMeshReader::readElemVarNames( std::vector< std::string >& ev ) const
+// *****************************************************************************
+//  Read the names of elemental output variables from ExodusII file
+//! \param[in,out] ev Elemental variable names
+// *****************************************************************************
+{
+  #if defined(__clang__)
+    #pragma clang diagnostic push
+    #pragma clang diagnostic ignored "-Wvla"
+    #pragma clang diagnostic ignored "-Wvla-extension"
+  #elif defined(STRICT_GNUC)
+    #pragma GCC diagnostic push
+    #pragma GCC diagnostic ignored "-Wvla"
+  #endif
+
+  int numvars = 0;
+
+  ErrChk(
+    ex_get_variable_param( m_inFile, EX_ELEM_BLOCK, &numvars ) == 0,
+    "Failed to read element output variable parameters from ExodusII file: " +
+    m_filename );
+
+  if (numvars) {
+
+    char* names[ static_cast< std::size_t >( numvars ) ];
+    for (int i=0; i<numvars; ++i)
+      names[i] = static_cast<char*>( calloc((MAX_STR_LENGTH+1), sizeof(char)) );
+
+    ErrChk( ex_get_variable_names( m_inFile,
+                                   EX_ELEM_BLOCK,
+                                   numvars,
+                                   names ) == 0,
+            "Failed to read element variable names from ExodusII file: " +
+            m_filename );
+
+    ev.resize( static_cast< std::size_t >( numvars ) );
+    std::size_t i = 0;
+    for (auto& n : ev) n = names[ i++ ];<--- Consider using std::fill or std::generate algorithm instead of a raw loop.
+
+  }
+
+  #if defined(__clang__)
+    #pragma clang diagnostic pop
+  #elif defined(STRICT_GNUC)
+    #pragma GCC diagnostic pop
+  #endif
+}
+
+void
+ExodusIIMeshReader::readTimeValues( std::vector< tk::real >& tv ) const
+// *****************************************************************************
+//  Read time values from ExodusII file
+//! \param[in] tv Vector of time values at which field data is saved
+// *****************************************************************************
+{
+  auto num_time_steps =
+    static_cast< std::size_t >( ex_inquire_int( m_inFile, EX_INQ_TIME ) );
+
+  if (num_time_steps) {
+    tv.resize( num_time_steps, 0.0 );
+    ErrChk( ex_get_all_times( m_inFile, tv.data() ) == 0,
+             "Failed to read time values from ExodusII file: " + m_filename );
+  }
+}
+
+void
+ExodusIIMeshReader::readNodeScalars(
+  std::size_t ntime,
+  std::size_t nvar,
+  std::vector< std::vector< std::vector< tk::real > > >& var ) const
+// *****************************************************************************
+//  Read node scalar fields from ExodusII file
+//! \param[in] ntime Number of time steps to read
+//! \param[in] nvar Number of variables to read
+//! \param[in] var Vector of nodal variables to read to: inner vector: nodes,
+//!   middle vector: (physics) variable, outer vector: time step
+// *****************************************************************************
+{
+  var.resize( ntime );
+  for (auto& v : var) {
+    v.resize( nvar );
+    for (auto& n : v) n.resize( m_nnode );
+  }
+
+  for (std::size_t t=0; t<var.size(); ++t) {
+    for (std::size_t id=0; id<var[t].size(); ++id) {
+      ErrChk( ex_get_var( m_inFile,
+                          static_cast< int >( t+1 ),
+                          EX_NODAL,
+                          static_cast< int >( id+1 ),
+                          1,
+                          static_cast< int64_t >( var[t][id].size() ),
+                          var[t][id].data() ) == 0,
+              "Failed to read node scalar from ExodusII file: " + m_filename );
+    }
+  }
+}
+
+void
+ExodusIIMeshReader::readElemScalars(
+  std::size_t ntime,
+  std::size_t nvar,
+  std::vector< std::vector< std::vector< tk::real > > >& var ) const
+// *****************************************************************************
+//  Read element scalar fields from ExodusII file
+//! \param[in] ntime Number of time steps to read
+//! \param[in] nvar Number of variables to read
+//! \param[in] var Vector of elemental variables to read to: inner vector:
+//!   elements, middle vector: (physics) variable, outer vector: time step
+// *****************************************************************************
+{
+  var.resize( ntime );
+  for (auto& v : var) {
+    v.resize( nvar );
+    for (auto& n : v) n.resize( m_nelem );
+  }
+
+  for (std::size_t t=0; t<var.size(); ++t) {
+    for (std::size_t id=0; id<var[t].size(); ++id) {
+      ErrChk( ex_get_var( m_inFile,
+                          static_cast< int >( t+1 ),
+                          EX_ELEM_BLOCK,
+                          static_cast< int >( id+1 ),
+                          1,
+                          static_cast< int64_t >( var[t][id].size() ),
+                          var[t][id].data() ) == 0,
+              "Failed to read element scalar from ExodusII file: " +
+              m_filename );
+    }
+  }
+}
+
+std::size_t
+ExodusIIMeshReader::nelem( tk::ExoElemType elemtype ) const
+// *****************************************************************************
+//  Return number of elements in all mesh blocks for a given elem type in file
+//! \param[in] elemtype Element type
+//! \return Number of elements in all blocks for the elem type
+//! \note Must be preceded by a call to readElemBlockIDs()
+// *****************************************************************************
+{
+  auto e = static_cast< std::size_t >( elemtype );
+  return std::accumulate( m_nel[e].cbegin(), m_nel[e].cend(), 0u );
+}
 
diff --git a/Debug/cppcheck/14.html b/Debug/cppcheck/14.html index 9f4c3ac9190c..60bf71e415f5 100644 --- a/Debug/cppcheck/14.html +++ b/Debug/cppcheck/14.html @@ -152,2121 +152,1167 @@
- - + @@ -237,7 +237,7 @@ - +
   1
-   2
-   3
-   4
-   5
-   6
-   7
-   8
-   9
-  10
-  11
-  12
-  13
-  14
-  15
-  16
-  17
-  18
-  19
-  20
-  21
-  22
-  23
-  24
-  25
-  26
-  27
-  28
-  29
-  30
-  31
-  32
-  33
-  34
-  35
-  36
-  37
-  38
-  39
-  40
-  41
-  42
-  43
-  44
-  45
-  46
-  47
-  48
-  49
-  50
-  51
-  52
-  53
-  54
-  55
-  56
-  57
-  58
-  59
-  60
-  61
-  62
-  63
-  64
-  65
-  66
-  67
-  68
-  69
-  70
-  71
-  72
-  73
-  74
-  75
-  76
-  77
-  78
-  79
-  80
-  81
-  82
-  83
-  84
-  85
-  86
-  87
-  88
-  89
-  90
-  91
-  92
-  93
-  94
-  95
-  96
-  97
-  98
-  99
- 100
- 101
- 102
- 103
- 104
- 105
- 106
- 107
- 108
- 109
- 110
- 111
- 112
- 113
- 114
- 115
- 116
- 117
- 118
- 119
- 120
- 121
- 122
- 123
- 124
- 125
- 126
- 127
- 128
- 129
- 130
- 131
- 132
- 133
- 134
- 135
- 136
- 137
- 138
- 139
- 140
- 141
- 142
- 143
- 144
- 145
- 146
- 147
- 148
- 149
- 150
- 151
- 152
- 153
- 154
- 155
- 156
- 157
- 158
- 159
- 160
- 161
- 162
- 163
- 164
- 165
- 166
- 167
- 168
- 169
- 170
- 171
- 172
- 173
- 174
- 175
- 176
- 177
- 178
- 179
- 180
- 181
- 182
- 183
- 184
- 185
- 186
- 187
- 188
- 189
- 190
- 191
- 192
- 193
- 194
- 195
- 196
- 197
- 198
- 199
- 200
- 201
- 202
- 203
- 204
- 205
- 206
- 207
- 208
- 209
- 210
- 211
- 212
- 213
- 214
- 215
- 216
- 217
- 218
- 219
- 220
- 221
- 222
- 223
- 224
- 225
- 226
- 227
- 228
- 229
- 230
- 231
- 232
- 233
- 234
- 235
- 236
- 237
- 238
- 239
- 240
- 241
- 242
- 243
- 244
- 245
- 246
- 247
- 248
- 249
- 250
- 251
- 252
- 253
- 254
- 255
- 256
- 257
- 258
- 259
- 260
- 261
- 262
- 263
- 264
- 265
- 266
- 267
- 268
- 269
- 270
- 271
- 272
- 273
- 274
- 275
- 276
- 277
- 278
- 279
- 280
- 281
- 282
- 283
- 284
- 285
- 286
- 287
- 288
- 289
- 290
- 291
- 292
- 293
- 294
- 295
- 296
- 297
- 298
- 299
- 300
- 301
- 302
- 303
- 304
- 305
- 306
- 307
- 308
- 309
- 310
- 311
- 312
- 313
- 314
- 315
- 316
- 317
- 318
- 319
- 320
- 321
- 322
- 323
- 324
- 325
- 326
- 327
- 328
- 329
- 330
- 331
- 332
- 333
- 334
- 335
- 336
- 337
- 338
- 339
- 340
- 341
- 342
- 343
- 344
- 345
- 346
- 347
- 348
- 349
- 350
- 351
- 352
- 353
- 354
- 355
- 356
- 357
- 358
- 359
- 360
- 361
- 362
- 363
- 364
- 365
- 366
- 367
- 368
- 369
- 370
- 371
- 372
- 373
- 374
- 375
- 376
- 377
- 378
- 379
- 380
- 381
- 382
- 383
- 384
- 385
- 386
- 387
- 388
- 389
- 390
- 391
- 392
- 393
- 394
- 395
- 396
- 397
- 398
- 399
- 400
- 401
- 402
- 403
- 404
- 405
- 406
- 407
- 408
- 409
- 410
- 411
- 412
- 413
- 414
- 415
- 416
- 417
- 418
- 419
- 420
- 421
- 422
- 423
- 424
- 425
- 426
- 427
- 428
- 429
- 430
- 431
- 432
- 433
- 434
- 435
- 436
- 437
- 438
- 439
- 440
- 441
- 442
- 443
- 444
- 445
- 446
- 447
- 448
- 449
- 450
- 451
- 452
- 453
- 454
- 455
- 456
- 457
- 458
- 459
- 460
- 461
- 462
- 463
- 464
- 465
- 466
- 467
- 468
- 469
- 470
- 471
- 472
- 473
- 474
- 475
- 476
- 477
- 478
- 479
- 480
- 481
- 482
- 483
- 484
- 485
- 486
- 487
- 488
- 489
- 490
- 491
- 492
- 493
- 494
- 495
- 496
- 497
- 498
- 499
- 500
- 501
- 502
- 503
- 504
- 505
- 506
- 507
- 508
- 509
- 510
- 511
- 512
- 513
- 514
- 515
- 516
- 517
- 518
- 519
- 520
- 521
- 522
- 523
- 524
- 525
- 526
- 527
- 528
- 529
- 530
- 531
- 532
- 533
- 534
- 535
- 536
- 537
- 538
- 539
- 540
- 541
- 542
- 543
- 544
- 545
- 546
- 547
- 548
- 549
- 550
- 551
- 552
- 553
- 554
- 555
- 556
- 557
- 558
- 559
- 560
- 561
- 562
- 563
- 564
- 565
- 566
- 567
- 568
- 569
- 570
- 571
- 572
- 573
- 574
- 575
- 576
- 577
- 578
- 579
- 580
- 581
- 582
- 583
- 584
- 585
- 586
- 587
- 588
- 589
- 590
- 591
- 592
- 593
- 594
- 595
- 596
- 597
- 598
- 599
- 600
- 601
- 602
- 603
- 604
- 605
- 606
- 607
- 608
- 609
- 610
- 611
- 612
- 613
- 614
- 615
- 616
- 617
- 618
- 619
- 620
- 621
- 622
- 623
- 624
- 625
- 626
- 627
- 628
- 629
- 630
- 631
- 632
- 633
- 634
- 635
- 636
- 637
- 638
- 639
- 640
- 641
- 642
- 643
- 644
- 645
- 646
- 647
- 648
- 649
- 650
- 651
- 652
- 653
- 654
- 655
- 656
- 657
- 658
- 659
- 660
- 661
- 662
- 663
- 664
- 665
- 666
- 667
- 668
- 669
- 670
- 671
- 672
- 673
- 674
- 675
- 676
- 677
- 678
- 679
- 680
- 681
- 682
- 683
- 684
- 685
- 686
- 687
- 688
- 689
- 690
- 691
- 692
- 693
- 694
- 695
- 696
- 697
- 698
- 699
- 700
- 701
- 702
- 703
- 704
- 705
- 706
- 707
- 708
- 709
- 710
- 711
- 712
- 713
- 714
- 715
- 716
- 717
- 718
- 719
- 720
- 721
- 722
- 723
- 724
- 725
- 726
- 727
- 728
- 729
- 730
- 731
- 732
- 733
- 734
- 735
- 736
- 737
- 738
- 739
- 740
- 741
- 742
- 743
- 744
- 745
- 746
- 747
- 748
- 749
- 750
- 751
- 752
- 753
- 754
- 755
- 756
- 757
- 758
- 759
- 760
- 761
- 762
- 763
- 764
- 765
- 766
- 767
- 768
- 769
- 770
- 771
- 772
- 773
- 774
- 775
- 776
- 777
- 778
- 779
- 780
- 781
- 782
- 783
- 784
- 785
- 786
- 787
- 788
- 789
- 790
- 791
- 792
- 793
- 794
- 795
- 796
- 797
- 798
- 799
- 800
- 801
- 802
- 803
- 804
- 805
- 806
- 807
- 808
- 809
- 810
- 811
- 812
- 813
- 814
- 815
- 816
- 817
- 818
- 819
- 820
- 821
- 822
- 823
- 824
- 825
- 826
- 827
- 828
- 829
- 830
- 831
- 832
- 833
- 834
- 835
- 836
- 837
- 838
- 839
- 840
- 841
- 842
- 843
- 844
- 845
- 846
- 847
- 848
- 849
- 850
- 851
- 852
- 853
- 854
- 855
- 856
- 857
- 858
- 859
- 860
- 861
- 862
- 863
- 864
- 865
- 866
- 867
- 868
- 869
- 870
- 871
- 872
- 873
- 874
- 875
- 876
- 877
- 878
- 879
- 880
- 881
- 882
- 883
- 884
- 885
- 886
- 887
- 888
- 889
- 890
- 891
- 892
- 893
- 894
- 895
- 896
- 897
- 898
- 899
- 900
- 901
- 902
- 903
- 904
- 905
- 906
- 907
- 908
- 909
- 910
- 911
- 912
- 913
- 914
- 915
- 916
- 917
- 918
- 919
- 920
- 921
- 922
- 923
- 924
- 925
- 926
- 927
- 928
- 929
- 930
- 931
- 932
- 933
- 934
- 935
- 936
- 937
- 938
- 939
- 940
- 941
- 942
- 943
- 944
- 945
- 946
- 947
- 948
- 949
- 950
- 951
- 952
- 953
- 954
- 955
- 956
- 957
- 958
- 959
- 960
- 961
- 962
- 963
- 964
- 965
- 966
- 967
- 968
- 969
- 970
- 971
- 972
- 973
- 974
- 975
- 976
- 977
- 978
- 979
- 980
- 981
- 982
- 983
- 984
- 985
- 986
- 987
- 988
- 989
- 990
- 991
- 992
- 993
- 994
- 995
- 996
- 997
- 998
- 999
-1000
-1001
-1002
-1003
-1004
-1005
-1006
-1007
-1008
-1009
-1010
-1011
-1012
-1013
-1014
-1015
-1016
-1017
-1018
-1019
-1020
-1021
-1022
-1023
-1024
-1025
-1026
-1027
-1028
-1029
-1030
-1031
-1032
-1033
-1034
-1035
-1036
-1037
-1038
-1039
-1040
-1041
-1042
-1043
-1044
-1045
-1046
-1047
-1048
-1049
-1050
-1051
-1052
-1053
-1054
// *****************************************************************************
+
  1
+  2
+  3
+  4
+  5
+  6
+  7
+  8
+  9
+ 10
+ 11
+ 12
+ 13
+ 14
+ 15
+ 16
+ 17
+ 18
+ 19
+ 20
+ 21
+ 22
+ 23
+ 24
+ 25
+ 26
+ 27
+ 28
+ 29
+ 30
+ 31
+ 32
+ 33
+ 34
+ 35
+ 36
+ 37
+ 38
+ 39
+ 40
+ 41
+ 42
+ 43
+ 44
+ 45
+ 46
+ 47
+ 48
+ 49
+ 50
+ 51
+ 52
+ 53
+ 54
+ 55
+ 56
+ 57
+ 58
+ 59
+ 60
+ 61
+ 62
+ 63
+ 64
+ 65
+ 66
+ 67
+ 68
+ 69
+ 70
+ 71
+ 72
+ 73
+ 74
+ 75
+ 76
+ 77
+ 78
+ 79
+ 80
+ 81
+ 82
+ 83
+ 84
+ 85
+ 86
+ 87
+ 88
+ 89
+ 90
+ 91
+ 92
+ 93
+ 94
+ 95
+ 96
+ 97
+ 98
+ 99
+100
+101
+102
+103
+104
+105
+106
+107
+108
+109
+110
+111
+112
+113
+114
+115
+116
+117
+118
+119
+120
+121
+122
+123
+124
+125
+126
+127
+128
+129
+130
+131
+132
+133
+134
+135
+136
+137
+138
+139
+140
+141
+142
+143
+144
+145
+146
+147
+148
+149
+150
+151
+152
+153
+154
+155
+156
+157
+158
+159
+160
+161
+162
+163
+164
+165
+166
+167
+168
+169
+170
+171
+172
+173
+174
+175
+176
+177
+178
+179
+180
+181
+182
+183
+184
+185
+186
+187
+188
+189
+190
+191
+192
+193
+194
+195
+196
+197
+198
+199
+200
+201
+202
+203
+204
+205
+206
+207
+208
+209
+210
+211
+212
+213
+214
+215
+216
+217
+218
+219
+220
+221
+222
+223
+224
+225
+226
+227
+228
+229
+230
+231
+232
+233
+234
+235
+236
+237
+238
+239
+240
+241
+242
+243
+244
+245
+246
+247
+248
+249
+250
+251
+252
+253
+254
+255
+256
+257
+258
+259
+260
+261
+262
+263
+264
+265
+266
+267
+268
+269
+270
+271
+272
+273
+274
+275
+276
+277
+278
+279
+280
+281
+282
+283
+284
+285
+286
+287
+288
+289
+290
+291
+292
+293
+294
+295
+296
+297
+298
+299
+300
+301
+302
+303
+304
+305
+306
+307
+308
+309
+310
+311
+312
+313
+314
+315
+316
+317
+318
+319
+320
+321
+322
+323
+324
+325
+326
+327
+328
+329
+330
+331
+332
+333
+334
+335
+336
+337
+338
+339
+340
+341
+342
+343
+344
+345
+346
+347
+348
+349
+350
+351
+352
+353
+354
+355
+356
+357
+358
+359
+360
+361
+362
+363
+364
+365
+366
+367
+368
+369
+370
+371
+372
+373
+374
+375
+376
+377
+378
+379
+380
+381
+382
+383
+384
+385
+386
+387
+388
+389
+390
+391
+392
+393
+394
+395
+396
+397
+398
+399
+400
+401
+402
+403
+404
+405
+406
+407
+408
+409
+410
+411
+412
+413
+414
+415
+416
+417
+418
+419
+420
+421
+422
+423
+424
+425
+426
+427
+428
+429
+430
+431
+432
+433
+434
+435
+436
+437
+438
+439
+440
+441
+442
+443
+444
+445
+446
+447
+448
+449
+450
+451
+452
+453
+454
+455
+456
+457
+458
+459
+460
+461
+462
+463
+464
+465
+466
+467
+468
+469
+470
+471
+472
+473
+474
+475
+476
+477
+478
+479
+480
+481
+482
+483
+484
+485
+486
+487
+488
+489
+490
+491
+492
+493
+494
+495
+496
+497
+498
+499
+500
+501
+502
+503
+504
+505
+506
+507
+508
+509
+510
+511
+512
+513
+514
+515
+516
+517
+518
+519
+520
+521
+522
+523
+524
+525
+526
+527
+528
+529
+530
+531
+532
+533
+534
+535
+536
+537
+538
+539
+540
+541
+542
+543
+544
+545
+546
+547
+548
+549
+550
+551
+552
+553
+554
+555
+556
+557
+558
+559
+560
+561
+562
+563
+564
+565
+566
+567
+568
+569
+570
+571
+572
+573
+574
+575
+576
+577
// *****************************************************************************
 /*!
-  \file      src/IO/ExodusIIMeshReader.cpp
+  \file      src/LinearSolver/ConjugateGradients.cpp
   \copyright 2012-2015 J. Bakosi,
              2016-2018 Los Alamos National Security, LLC.,
              2019-2021 Triad National Security, LLC.
              All rights reserved. See the LICENSE file for details.
-  \brief     ExodusII mesh reader
-  \details   ExodusII mesh reader class definition.
-*/
-// *****************************************************************************
-
-#include <numeric>
+  \brief     Charm++ chare array for distributed conjugate gradients.
+  \details   Charm++ chare array for asynchronous distributed
+    conjugate gradients linear solver.
+  \see Y. Saad, Iterative Methods for Sparse Linear Systems: Second Edition,
+    ISBN 9780898718003, 2003, Algorithm 6.18, conjugate gradients to solve the
+    linear system A * x = b, reproduced here:
 
-#include "NoWarning/exodusII.hpp"
-
-#include "ExodusIIMeshReader.hpp"
-#include "ContainerUtil.hpp"
-#include "Exception.hpp"
-#include "UnsMesh.hpp"
-#include "Reorder.hpp"
-
-using tk::ExodusIIMeshReader;
-
-ExodusIIMeshReader::ExodusIIMeshReader( const std::string& filename,<--- Member variable 'ExodusIIMeshReader::m_nelem' is not initialized in the constructor.
-                                        int cpuwordsize,
-                                        int iowordsize ) :
-  m_filename( filename ),
-  m_cpuwordsize( cpuwordsize ),
-  m_iowordsize( iowordsize ),
-  m_inFile( 0 ),
-  m_nnode( 0 ),
-  m_neblk( 0 ),
-  m_neset( 0 ),
-  m_from( 0 ),
-  m_till( 0 ),
-  m_blockid(),
-  m_blockid_by_type( ExoNnpe.size() ),
-  m_nel( ExoNnpe.size() ),
-  m_elemblocks(),
-  m_tri()
-// *****************************************************************************
-//  Constructor: open Exodus II file
-//! \param[in] filename File to open as ExodusII file
-//! \param[in] cpuwordsize Set CPU word size, see ExodusII documentation
-//! \param[in] iowordsize Set I/O word size, see ExodusII documentation
-// *****************************************************************************
-{
-  // Increase verbosity from ExodusII library in debug mode
-  #ifndef NDEBUG
-  ex_opts( EX_DEBUG | EX_VERBOSE );
-  #endif
-
-  float version;
-
-  m_inFile = ex_open( filename.c_str(), EX_READ, &cpuwordsize, &iowordsize,
-                      &version );
-
-  // output exodusII/netcdf configuration
-  //ex_print_config();
-
-  ErrChk( m_inFile > 0, "Failed to open ExodusII file: " + filename );
-}
-
-ExodusIIMeshReader::~ExodusIIMeshReader() noexcept
-// *****************************************************************************
-//  Destructor
-// *****************************************************************************
-{
-  if ( ex_close(m_inFile) < 0 )
-    printf( ">>> WARNING: Failed to close ExodusII file: %s\n",
-            m_filename.c_str() );
-}
-
-void
-ExodusIIMeshReader::readMesh( UnsMesh& mesh )
-// *****************************************************************************
-//  Read ExodusII mesh file
-//! \param[in] mesh Unstructured mesh object
-// *****************************************************************************
-{
-  readHeader( mesh );
-  readAllElements( mesh );
-  readAllNodes( mesh );
-  readSidesetFaces( mesh.bface(), mesh.faceid() );
-  readTimeValues( mesh.vartimes() );
-  readNodeVarNames( mesh.nodevarnames() );
-  readElemVarNames( mesh.elemvarnames() );
-  readNodeScalars( mesh.vartimes().size(),
-                   mesh.nodevarnames().size(),
-                   mesh.nodevars() );
-  readElemScalars( mesh.vartimes().size(),
-                   mesh.elemvarnames().size(),
-                   mesh.elemvars() );
-}
-
-void
-ExodusIIMeshReader::readGraph( UnsMesh& mesh )
-// *****************************************************************************
-//  Read only connectivity graph from file
-//! \param[in] mesh Unstructured mesh object
-// *****************************************************************************
-{
-  readHeader( mesh );
-  readAllElements( mesh );
-}
+    Compute r0:=b-A*x0, p0:=r0
+    For j=0,1,..., until convergence, do
+      alpha_j := (r_j,r_j) / (Ap_j,p_j)
+      x_{j+1} := x_j + alpha_j p_j
+      r_{j+1} := r_j - alpha_j A p_j
+      beta_j := (r_{j+1},r_{j+1}) / (r_j,r_j)
+      p_{j+1} := r_{j+1} + beta_j p_j
+    end
+*/
+// *****************************************************************************
+
+#include <numeric>
+#include <iostream>
+
+#include "Exception.hpp"
+#include "ConjugateGradients.hpp"
+#include "Vector.hpp"
+
+using tk::ConjugateGradients;
+
+ConjugateGradients::ConjugateGradients(<--- Member variable 'ConjugateGradients::m_tol' is not initialized in the constructor.
+  const CSR& A,
+  const std::vector< tk::real >& x,
+  const std::vector< tk::real >& b,
+  const std::vector< std::size_t >& gid,
+  const std::unordered_map< std::size_t, std::size_t >& lid,
+  const NodeCommMap& nodecommmap ) :
+  m_A( A ),
+  m_x( x ),
+  m_b( b ),
+  m_gid( gid ),
+  m_lid( lid ),
+  m_nodeCommMap( nodecommmap ),
+  m_r( m_A.rsize(), 0.0 ),
+  m_rc(),
+  m_nr( 0 ),
+  m_bc(),
+  m_bcc(),
+  m_bcmask( m_A.rsize(), 1.0 ),
+  m_nb( 0 ),
+  m_p( m_A.rsize(), 0.0 ),
+  m_q( m_A.rsize(), 0.0 ),
+  m_qc(),
+  m_nq( 0 ),
+  m_initres(),
+  m_solved(),
+  m_normb( 0.0 ),
+  m_it( 0 ),
+  m_maxit( 0 ),
+  m_rho( 0.0 ),
+  m_rho0( 0.0 ),
+  m_alpha( 0.0 ),
+  m_converged( false ),
+  m_xc(),
+  m_nx( 0 )
+// *****************************************************************************
+//  Constructor
+//! \param[in] A Left hand side matrix of the linear system to solve in Ax=b
+//! \param[in] x Solution (initial guess) of the linear system to solve in Ax=b
+//! \param[in] b Right hand side of the linear system to solve in Ax=b
+//! \param[in] gid Global node ids
+//! \param[in] lid Local node ids associated to global ones
+//! \param[in] nodecommmap Global mesh node IDs shared with other chares
+//!   associated to their chare IDs
+// *****************************************************************************
+{
+  // Fill in gid and lid for serial solve
+  if (gid.empty() || lid.empty() || nodecommmap.empty()) {
+    m_gid.resize( m_A.rsize()/m_A.Ncomp() );
+    std::iota( begin(m_gid), end(m_gid), 0 );
+    for (auto g : m_gid) m_lid[g] = g;
+  }
+
+  Assert( m_A.rsize() == m_gid.size()*A.Ncomp(), "Size mismatch" );
+  Assert( m_x.size() == m_gid.size()*A.Ncomp(), "Size mismatch" );
+  Assert( m_b.size() == m_gid.size()*A.Ncomp(), "Size mismatch" );
+}
+
+void
+ConjugateGradients::setup( CkCallback c )
+// *****************************************************************************
+//  Setup solver
+//! \param[in] c Call to continue with after initialization is complete
+//! \details This function initiates computing the residual (r=b-A*x), its dot
+//!   product, and the rhs norm.
+// *****************************************************************************
+{
+  m_initres = c;
+
+  // initiate computing A * x (for the initial residual)
+  thisProxy[ thisIndex ].wait4res();
+  residual();
 
-void
-ExodusIIMeshReader::readMeshPart(
-  std::vector< std::size_t >& ginpoel,
-  std::vector< std::size_t >& inpoel,
-  std::vector< std::size_t >& triinp,
-  std::unordered_map< std::size_t, std::size_t >& lid,
-  tk::UnsMesh::Coords& coord,
-  std::unordered_map< std::size_t, std::set< std::size_t > >& elemBlockId,
-  int numpes, int mype )
+  // initiate computing norm of right hand side
+  dot( m_b, m_b,
+       CkCallback( CkReductionTarget(ConjugateGradients,normb), thisProxy ) );
+}
+
+void
+ConjugateGradients::dot( const std::vector< tk::real >& a,
+                         const std::vector< tk::real >& b,
+                         CkCallback c )
 // *****************************************************************************
-//  Read a part of the mesh (graph and coordinates) from ExodusII file
-//! \param[in,out] ginpoel Container to store element connectivity of this PE's
-//!   chunk of the mesh (global ids)
-//! \param[in,out] inpoel Container to store element connectivity with local
-//!   node IDs of this PE's mesh chunk
-//! \param[in,out] triinp Container to store triangle element connectivity
-//!   (if exists in file) with global node indices
-//! \param[in,out] lid Container to store global->local node IDs of elements of
-//!   this PE's mesh chunk
-//! \param[in,out] coord Container to store coordinates of mesh nodes of this
-//!   PE's mesh chunk
-//! \param[in,out] elemBlockId List of elements for each block-id.
-//! \param[in] numpes Total number of PEs (default n = 1, for a single-CPU read)
-//! \param[in] mype This PE (default m = 0, for a single-CPU read)
-// *****************************************************************************
-{
-  Assert( mype < numpes, "Invalid input: PE id must be lower than NumPEs" );
-  Assert( ginpoel.empty() && inpoel.empty() && lid.empty() &&
-          coord[0].empty() && coord[1].empty() && coord[2].empty(),
-          "Containers to store mesh must be empty" );
-
-  // Read info on element blocks from ExodusII file
-  readElemBlockIDs();
-  // Get number of number of tetrahedron elements in file
-  auto nel = nelem( tk::ExoElemType::TET );
-
-  // Compute extents of element IDs of this PE's mesh chunk to read
-  auto npes = static_cast< std::size_t >( numpes );
-  auto pe = static_cast< std::size_t >( mype );
-  auto chunk = nel / npes;
-  m_from = pe * chunk;
-  m_till = m_from + chunk;
-  if (pe == npes-1) m_till += nel % npes;
-
-  // Read tetrahedron connectivity between from and till
-  readElements( {{m_from, m_till-1}}, tk::ExoElemType::TET, ginpoel );
-  elemBlockId = m_elemInBlockId;
-
-  // Compute local data from global mesh connectivity
-  std::vector< std::size_t > gid;
-  std::tie( inpoel, gid, lid ) = tk::global2local( ginpoel );
-
-  // Read this PE's chunk of the mesh node coordinates from file
-  coord = readCoords( gid );
-
-  // Generate set of unique faces
-  tk::UnsMesh::FaceSet faces;
-  for (std::size_t e=0; e<ginpoel.size()/4; ++e)
-    for (std::size_t f=0; f<4; ++f) {
-      const auto& tri = tk::expofa[f];
-      faces.insert( {{{ ginpoel[ e*4+tri[0] ],
-                        ginpoel[ e*4+tri[1] ],
-                        ginpoel[ e*4+tri[2] ] }}} );
-    }
-
-  // Read triangle element connectivity (all triangle blocks in file)
-  auto ntri = nelem( tk::ExoElemType::TRI );
-  if ( ntri !=0 ) readElements( {{0,ntri-1}}, tk::ExoElemType::TRI, triinp );
-
-  // Keep triangles shared in (partially-read) tetrahedron mesh
-  std::vector< std::size_t > triinp_own;
-  std::size_t ltrid = 0;        // local triangle id
-  for (std::size_t e=0; e<triinp.size()/3; ++e) {
-    auto i = faces.find( {{ triinp[e*3+0], triinp[e*3+1], triinp[e*3+2] }} );
-    if (i != end(faces)) {
-      m_tri[e] = ltrid++;       // generate global->local triangle ids
-      triinp_own.push_back( triinp[e*3+0] );
-      triinp_own.push_back( triinp[e*3+1] );
-      triinp_own.push_back( triinp[e*3+2] );
-    }
-  }
-  triinp = std::move(triinp_own);
-}
+//  Initiate computation of dot product of two vectors
+//! \param[in] a 1st vector of dot product
+//! \param[in] b 2nd vector of dot product
+//! \param[in] c Callback to target with the final result
+// *****************************************************************************
+{
+  Assert( a.size() == b.size(), "Size mismatch" );
+
+  tk::real D = 0.0;
+  auto ncomp = m_A.Ncomp();
+  for (std::size_t i=0; i<a.size()/ncomp; ++i) {
+    auto incomp = i*ncomp;
+    if (not slave(m_nodeCommMap,m_gid[i],thisIndex))
+      for (std::size_t d=0; d<ncomp; ++d)
+        D += a[incomp+d] * b[incomp+d];
+  }
+
+  contribute( sizeof(tk::real), &D, CkReduction::sum_double, c );
+}
+
+void
+ConjugateGradients::normb( tk::real n )
+// *****************************************************************************
+// Compute the norm of the right hand side
+//! \param[in] n Norm of right hand side (aggregated across all chares)
+// *****************************************************************************
+{
+  m_normb = std::sqrt(n);
+  normb_complete();
+}
+
+void
+ConjugateGradients::residual()
+// *****************************************************************************
+//  Initiate A * x for computing the initial residual, r = b - A * x
+// *****************************************************************************
+{
+  // Compute own contribution to r = A * x
+  m_A.mult( m_x, m_r, m_bcmask );
+
+  // Send partial product on chare-boundary nodes to fellow chares
+  if (m_nodeCommMap.empty()) {
+    comres_complete();
+  } else {
+    auto ncomp = m_A.Ncomp();
+    for (const auto& [c,n] : m_nodeCommMap) {
+      std::vector< std::vector< tk::real > > rc( n.size() );
+      std::size_t j = 0;
+      for (auto g : n) {
+        std::vector< tk::real > nr( ncomp );
+        auto i = tk::cref_find( m_lid, g );
+        for (std::size_t d=0; d<ncomp; ++d) nr[d] = m_r[ i*ncomp+d ];
+        rc[j++] = std::move(nr);
+      }
+      thisProxy[c].comres( std::vector<std::size_t>(begin(n),end(n)), rc );
+    }
+  }
+
+  ownres_complete();
+}
+
+void
+ConjugateGradients::comres( const std::vector< std::size_t >& gid,
+                            const std::vector< std::vector< tk::real > >& rc )
+// *****************************************************************************
+//  Receive contributions to A * x on chare-boundaries
+//! \param[in] gid Global mesh node IDs at which we receive contributions
+//! \param[in] rc Partial contributions at chare-boundary nodes
+// *****************************************************************************
+{
+  Assert( rc.size() == gid.size(), "Size mismatch" );
+
+  using tk::operator+=;
 
-std::array< std::vector< tk::real >, 3 >
-ExodusIIMeshReader::readCoords( const std::vector< std::size_t >& gid ) const
-// *****************************************************************************
-//  Read coordinates of a number of mesh nodes from ExodusII file
-//! \param[in] gid Global node IDs whose coordinates to read
-//! \return Vector of node coordinates read from file
-// *****************************************************************************
-{
-  // Read node coordinates from file with global node IDs given in gid
-  return readNodes( gid );
-}
-
-std::size_t
-ExodusIIMeshReader::readHeader()
-// *****************************************************************************
-//  Read ExodusII header without setting mesh size
-//! \return Number of nodes in mesh
-// *****************************************************************************
-{
-  char title[MAX_LINE_LENGTH+1];
-  int ndim, nelem, nnodeset, nelemset, nnode, neblk;
-
-  ErrChk(
-    ex_get_init( m_inFile, title, &ndim, &nnode, &nelem, &neblk, &nnodeset,
-                 &nelemset ) == 0,
-    "Failed to read header from ExodusII file: " + m_filename );
+  for (std::size_t i=0; i<gid.size(); ++i)
+    m_rc[ gid[i] ] += rc[i];
+
+  if (++m_nr == m_nodeCommMap.size()) {
+    m_nr = 0;
+    comres_complete();
+  }
+}
+
+void
+ConjugateGradients::initres()
+// *****************************************************************************
+// Finish computing the initial residual, r = b - A * x
+// *****************************************************************************
+{
+  // Combine own and communicated contributions to r = A * x
+  auto ncomp = m_A.Ncomp();
+  for (const auto& [gid,r] : m_rc) {
+    auto i = tk::cref_find( m_lid, gid );
+    for (std::size_t c=0; c<ncomp; ++c) m_r[i*ncomp+c] += r[c];
+  }
+  tk::destroy( m_rc );
+
+  // Finish computing the initial residual, r = b - A * x
+  for (auto& r : m_r) r *= -1.0;<--- Consider using std::transform algorithm instead of a raw loop.
+  m_r += m_b;
 
-  ErrChk( nnode > 0,
-          "Number of nodes read from ExodusII file must be larger than zero" );
-  ErrChk( neblk > 0,
-          "Number of element blocks read from ExodusII file must be larger "
-          "than zero" );
-  ErrChk( ndim == 3, "Need a 3D mesh from ExodusII file " + m_filename );
-
-  m_nelem = static_cast< std::size_t >( nelem );
-  m_neblk = static_cast< std::size_t >( neblk );
-  m_neset = static_cast< std::size_t >( nelemset );
-
-  return static_cast< std::size_t >( nnode );
-}
-
-void
-ExodusIIMeshReader::readHeader( UnsMesh& mesh )
-// *****************************************************************************
-//  Read ExodusII header with setting mesh size
-//! \param[in] mesh Unstructured mesh object
-// *****************************************************************************
-{
-  // Read ExodusII file header and set mesh graph size
-  mesh.size() = m_nnode = static_cast< std::size_t >( readHeader() );
-}
-
-void
-ExodusIIMeshReader::readAllNodes( UnsMesh& mesh ) const
-// *****************************************************************************
-//  Read all node coordinates from ExodusII file
-//! \param[in] mesh Unstructured mesh object
+  // Initialize p
+  m_p = m_r;
+
+  // initiate computing the dot product of the initial residual, rho = (r,r)
+  dot( m_r, m_r,
+       CkCallback( CkReductionTarget(ConjugateGradients,rho), thisProxy ) );
+}
+
+void
+ConjugateGradients::rho( tk::real r )
+// *****************************************************************************
+// Compute rho = (r,r)
+//! \param[in] r Dot product, rho = (r,r) (aggregated across all chares)
+// *****************************************************************************
+{
+  // store dot product of residual
+  m_rho = r;
+
+  // send back rhs norm to caller
+  m_initres.send( CkDataMsg::buildNew( sizeof(tk::real), &m_normb ) );
+}
+
+void
+ConjugateGradients::init(
+  const std::vector< tk::real >& x,
+  const std::vector< tk::real >& b,
+  const std::unordered_map< std::size_t,
+          std::vector< std::pair< bool, tk::real > > >& bc,
+  std::size_t ignorebc,
+  CkCallback cb )
 // *****************************************************************************
-{
-  mesh.x().resize( m_nnode );
-  mesh.y().resize( m_nnode );
-  mesh.z().resize( m_nnode );
-
-  ErrChk( ex_get_coord( m_inFile, mesh.x().data(), mesh.y().data(),
-                        mesh.z().data() ) == 0,
-          "Failed to read coordinates from ExodusII file: " + m_filename );
-}
-
-void
-ExodusIIMeshReader::readNode( std::size_t fid,
-                              std::size_t mid,
-                              std::vector< tk::real >& x,
-                              std::vector< tk::real >& y,
-                              std::vector< tk::real >& z ) const
-// *****************************************************************************
-//  Read coordinates of a single mesh node from ExodusII file
-//! \param[in] fid Node id in file whose coordinates to read
-//! \param[in] mid Node id in memory to which to put new cordinates
-//! \param[in,out] x Vector of x coordinates to push to
-//! \param[in,out] y Vector of y coordinates to push to
-//! \param[in,out] z Vector of z coordinates to push to
-// *****************************************************************************
-{
-  Assert( x.size() == y.size() && x.size() == z.size(), "Size mismatch" );
-  Assert( mid < x.size() && mid < y.size() && mid < z.size(),
-          "Indexing out of bounds" );
-
-  readNode( fid, x[mid], y[mid], z[mid] );
-}
-
-void
-ExodusIIMeshReader::readNode( std::size_t id,
-                              std::array< tk::real, 3 >& coord ) const
-// *****************************************************************************
-//  Read coordinates of a single mesh node from ExodusII file
-//! \param[in] id Node id whose coordinates to read
-//! \param[in,out] coord Array of x, y, and z coordinates
-// *****************************************************************************
-{
-  readNode( id, coord[0], coord[1], coord[2] );
-}
-
-void
-ExodusIIMeshReader::readNode( std::size_t id,
-                              tk::real& x,
-                              tk::real& y,
-                              tk::real& z ) const
-// *****************************************************************************
-// Read coordinates of a single mesh node from file
-//! \param[in] id Node id whose coordinates to read
-//! \param[in,out] x X coordinate to write to
-//! \param[in,out] y Y coordinate to write to
-//! \param[in,out] z Z coordinate to write to
-// *****************************************************************************
-{
-  ErrChk(
-    ex_get_partial_coord( m_inFile, static_cast<int64_t>(id)+1, 1,
-                          &x, &y, &z ) == 0,
-    "Failed to read coordinates of node " + std::to_string(id) +
-    " from ExodusII file: " + m_filename );
-}
-
-std::array< std::vector< tk::real >, 3 >
-ExodusIIMeshReader::readNodes( const std::vector< std::size_t >& gid ) const
-// *****************************************************************************
-//  Read coordinates of a number of mesh nodes from ExodusII file
-//! \param[in] gid Node IDs whose coordinates to read
-//! \return Mesh node coordinates
-// *****************************************************************************
-{
-  std::vector< tk::real > px( gid.size() ), py( gid.size() ), pz( gid.size() );
-
-  std::size_t i=0;
-  for (auto g : gid) readNode( g, i++, px, py, pz );
-
-  return {{ std::move(px), std::move(py), std::move(pz) }};
-}
-
-std::size_t
-ExodusIIMeshReader::readElemBlockIDs()
-// *****************************************************************************
-//  Read element block IDs from ExodusII file
-//! \return Total number of nodes in mesh
-// *****************************************************************************
-{
-  // Read ExodusII file header
-  auto nnode = readHeader();<--- Variable 'nnode' is assigned a value that is never used.
-
-  std::vector< int > bid( m_neblk );
-
-  // Read element block ids
-  ErrChk( ex_get_ids( m_inFile, EX_ELEM_BLOCK, bid.data()) == 0,
-          "Failed to read element block ids from ExodusII file: " +
-          m_filename );
-
-  m_elemblocks.clear();
-  m_nel.clear();
-  m_nel.resize( ExoNnpe.size() );
-  m_blockid_by_type.clear();
-  m_blockid_by_type.resize( ExoNnpe.size() );
+//  Initialize linear solve: set initial guess and boundary conditions
+//! \param[in] x Initial guess
+//! \param[in] b Right hand side vector
+//! \param[in] bc Local node ids and associated Dirichlet BCs
+//! \param[in] ignorebc True if applyin BCs should be skipped
+//! \param[in] cb Call to continue with when initialized and ready for a solve
+//! \details This function allows setting the initial guess and boundary
+//!   conditions, followed by computing the initial residual and the rhs norm.
+// *****************************************************************************
+{
+  // Optionally set initial guess
+  if (not x.empty()) m_x = x;
+
+  // Optionally update rhs
+  if (not b.empty()) m_b = b;
+
+  if (ignorebc) {
+
+    setup( cb );
+
+  } else {
+
+    // Store incoming BCs
+    m_bc = bc;
+
+    // Get ready to communicate boundary conditions. This is necessary because
+    // there can be nodes a chare contributes to but does not apply BCs on. This
+    // happens if a node is in the node communication map but not on the list of
+    // incoming BCs on this chare. To have all chares share the same view on all
+    // BC nodes, we send the global node ids together with the Dirichlet BCs at
+    // which BCs are set to those fellow chares that also contribute to those BC
+    // nodes. Only after this communication step we apply the BCs on the matrix,
+    // which then will correctly setup the BC rows that exist on multiple chares
+    // (which now will be the same as the results of making the BCs consistent
+    // across all chares that contribute.
+    thisProxy[ thisIndex ].wait4bc();
+
+    // Send boundary conditions to those who contribute to those rows
+    if (m_nodeCommMap.empty()) {
+      combc_complete();
+    } else {
+      for (const auto& [c,n] : m_nodeCommMap) {
+        std::unordered_map< std::size_t,
+          std::vector< std::pair< bool, tk::real > > > expbc;
+        for (auto g : n) {
+          auto i = tk::cref_find( m_lid, g );
+          auto j = bc.find(i);
+          if (j != end(bc)) expbc[g] = j->second;
+        }
+        thisProxy[c].combc( expbc );
+      }
+    }
+
+    ownbc_complete( cb );
+
+  }
+}
+
+void
+ConjugateGradients::combc(
+  const std::unordered_map< std::size_t,
+     std::vector< std::pair< bool, tk::real > > >& bc )
+// *****************************************************************************
+//  Receive contributions to boundary conditions on chare-boundaries
+//! \param[in] bc Contributions to boundary conditions
+// *****************************************************************************
+{
+  for (const auto& [g,dirbc] : bc) m_bcc[ tk::cref_find(m_lid,g) ] = dirbc;
+
+  if (++m_nb == m_nodeCommMap.size()) {
+    m_nb = 0;
+    combc_complete();
+  }
+}
+
+void
+ConjugateGradients::apply( CkCallback cb )
+// *****************************************************************************
+//  Apply boundary conditions
+//! \param[in] cb Call to continue with after applying the BCs is complete
+// *****************************************************************************
+{
+  // Merge own and received contributions to boundary conditions
+  for (const auto& [i,dirbc] : m_bcc) m_bc[i] = dirbc;
+  tk::destroy( m_bcc );
+
+  auto ncomp = m_A.Ncomp();
+
+  // Setup Dirichlet BC map as contiguous mask
+  for (const auto& [i,bc] : m_bc)
+    for (std::size_t j=0; j<ncomp; ++j)
+      m_bcmask[i*ncomp+j] = 0.0;
+
+  // Apply Dirichlet BCs on matrix and rhs
+  for (const auto& [i,dirbc] : m_bc) {
+    for (std::size_t j=0; j<ncomp; ++j) {
+      if (dirbc[j].first) {
+        m_A.dirichlet( i, m_gid, m_nodeCommMap, j );
+        m_b[i*ncomp+j] = dirbc[j].second;
+      }
+    }
+  }
 
-  // Fill element block ID vector
-  for (auto id : bid) {
-    char eltype[MAX_STR_LENGTH+1];
-    int n, nnpe, nattr;
-
-    // Read element block information
-    ErrChk( ex_get_block( m_inFile, EX_ELEM_BLOCK, id, eltype, &n, &nnpe,
-                          &nattr, nullptr, nullptr ) == 0,
-      "Failed to read element block information from ExodusII file: " +
-      m_filename );
-
-    // Store ExodusII element block ID
-    m_blockid.push_back( id );
-
-    auto nel = static_cast< std::size_t >( n );
-
-    // Store info on ExodusII element blocks
-    if (nnpe == 4) {        // tetrahedra
-
-      m_elemblocks.push_back( { ExoElemType::TET, nel } );
-      auto e = static_cast< std::size_t >( ExoElemType::TET );
-      m_blockid_by_type[ e ].push_back( id );
-      m_nel[ e ].push_back( nel );
-      Assert( m_blockid_by_type[e].size() == m_nel[e].size(), "Size mismatch" );
-
-    } else if (nnpe == 3) { // triangles
-
-      m_elemblocks.push_back( { ExoElemType::TRI, nel } );
-      auto e = static_cast< std::size_t >( ExoElemType::TRI );
-      m_blockid_by_type[ e ].push_back( id );
-      m_nel[ e ].push_back( nel );
-      Assert( m_blockid_by_type[e].size() == m_nel[e].size(), "Size mismatch" );
+  // Recompute initial residual (r=b-A*x), its dot product, and the rhs norm
+  setup( cb );
+}
+
+void
+ConjugateGradients::solve( std::size_t maxit, tk::real tol, CkCallback c )
+// *****************************************************************************
+//  Solve linear system
+//! \param[in] maxit Max iteration count
+//! \param[in] tol Stop tolerance
+//! \param[in] c Call to continue with after solve is complete
+// *****************************************************************************
+{
+  m_maxit = maxit;
+  m_tol = tol;
+  m_solved = c;
+  m_it = 0;
+
+  next();
+}
+
+void
+ConjugateGradients::next()
+// *****************************************************************************
+//  Start next linear solver iteration
+// *****************************************************************************
+{
+  if (m_it == 0) m_alpha = 0.0; else m_alpha = m_rho/m_rho0;
+  m_rho0 = m_rho;
+
+  // compute p = r + alpha * p
+  for (std::size_t i=0; i<m_p.size(); ++i) m_p[i] = m_r[i] + m_alpha * m_p[i];
 
-    }
-  }
-
-  return nnode;
-}
+  // initiate computing q = A * p
+  thisProxy[ thisIndex ].wait4q();
+  qAp();
+}
+
 
 void
-ExodusIIMeshReader::readAllElements( UnsMesh& mesh )
+ConjugateGradients::qAp()
 // *****************************************************************************
-//  Read all element blocks and mesh connectivity from ExodusII file
-//! \param[inout] mesh Unstructured mesh object to store mesh in
-// *****************************************************************************
-{
-  // Read element block ids
-  readElemBlockIDs();
-
-  for (auto id : m_blockid) {
-    char eltype[MAX_STR_LENGTH+1];
-    int nel, nnpe, nattr;
-
-    // Read element block information
-    ErrChk( ex_get_block( m_inFile, EX_ELEM_BLOCK, id, eltype, &nel, &nnpe,
-                          &nattr, nullptr, nullptr ) == 0,
-      "Failed to read element block information from ExodusII file: " +
-      m_filename );
-
-    // Read element connectivity
-    auto connectsize = static_cast< std::size_t >( nel*nnpe );
-    if (nnpe == 4) {    // tetrahedra
-
-      std::vector< int > inpoel( connectsize );
-      ErrChk( ex_get_conn( m_inFile, EX_ELEM_BLOCK, id, inpoel.data(),
-                           nullptr, nullptr ) == 0,
-        "Failed to read " + std::string(eltype) + " element connectivity from "
-        "ExodusII file: " + m_filename );
-      for (auto n : inpoel)
-        mesh.tetinpoel().push_back( static_cast< std::size_t >( n ) );
-
-    } else if (nnpe == 3) {    // triangles
-
-      std::vector< int > inpoel( connectsize );
-      ErrChk( ex_get_conn( m_inFile, EX_ELEM_BLOCK, id, inpoel.data(),
-                           nullptr, nullptr ) == 0,
-        "Failed to read " + std::string(eltype) + " element connectivity from "
-        "ExodusII file: " + m_filename );
-      for (auto n : inpoel)
-        mesh.triinpoel().push_back( static_cast< std::size_t >( n ) );
-
-    }
-  }
-
-  // Shift node IDs to start from zero
-  shiftToZero( mesh.triinpoel() );
-  shiftToZero( mesh.tetinpoel() );
-}
-
-void
-ExodusIIMeshReader::readElements( const std::array< std::size_t, 2 >& ext,
-                                  tk::ExoElemType elemtype,
-                                  std::vector< std::size_t >& conn )
+//  Initiate computing q = A * p
+// *****************************************************************************
+{
+  // Compute own contribution to q = A * p
+  m_A.mult( m_p, m_q, m_bcmask );
+
+  // Send partial product on chare-boundary nodes to fellow chares
+  if (m_nodeCommMap.empty()) {
+    comq_complete();
+  } else {
+    auto ncomp = m_A.Ncomp();
+    for (const auto& [c,n] : m_nodeCommMap) {
+      std::vector< std::vector< tk::real > > qc( n.size() );
+      std::size_t j = 0;
+      for (auto g : n) {
+        std::vector< tk::real > nq( ncomp );
+        auto i = tk::cref_find( m_lid, g );
+        for (std::size_t d=0; d<ncomp; ++d) nq[d] = m_q[ i*ncomp+d ];
+        qc[j++] = std::move(nq);
+      }
+      thisProxy[c].comq( std::vector<std::size_t>(begin(n),end(n)), qc );
+    }
+  }
+
+  ownq_complete();
+}
+
+void
+ConjugateGradients::comq( const std::vector< std::size_t >& gid,
+                          const std::vector< std::vector< tk::real > >& qc )
+// *****************************************************************************
+//  Receive contributions to q = A * p on chare-boundaries
+//! \param[in] gid Global mesh node IDs at which we receive contributions
+//! \param[in] qc Partial contributions at chare-boundary nodes
+// *****************************************************************************
+{
+  Assert( qc.size() == gid.size(), "Size mismatch" );
+
+  using tk::operator+=;
+
+  for (std::size_t i=0; i<gid.size(); ++i)
+    m_qc[ gid[i] ] += qc[i];
+
+  if (++m_nq == m_nodeCommMap.size()) {
+    m_nq = 0;
+    comq_complete();
+  }
+}
+
+void
+ConjugateGradients::q()
 // *****************************************************************************
-//  Read element connectivity of a number of mesh cells from ExodusII file
-//! \param[in] ext Extents of element IDs whose connectivity to read:
-//!   [from...till), using zero-based element IDs, where 'from' >=0, inclusive
-//!   and 'till < 'maxelements', where 'maxelements' is the total number of
-//!   elements of all element blocks in the file of the requested cell type.
-//!   Note that 'maxelements' can be queried by nelem().
-//! \param[in] elemtype Element type
-//! \param[inout] conn Connectivity vector to push to
-//! \note Must be preceded by a call to readElemBlockIDs()
-//! \details This function takes the extents of element IDs in a zero-based
-//!   fashion. These input extents can be thought of "absolute" extents that
-//!   denote lowest and the largest-1 element IDs to be read from file.
-//!   The mesh block-wise element set is also updated.
-// *****************************************************************************
-{
-  Assert( tk::sumsize(m_blockid_by_type) > 0,
-          "A call to this function must be preceded by a call to "
-          "ExodusIIMeshReader::readElemBlockIDs()" );
-  Assert( ext[0] <= ext[1] &&
-          ext[0] < nelem(elemtype) &&
-          ext[1] < nelem(elemtype),
-          "Invalid element ID extents. Of the requested extents [from...till), "
-          "'from' must be lower than or equal to 'till', and they must be in "
-          "the range [0...maxelements), where 'maxelements' is the total "
-          "number of elements of all element blocks in the file of the "
-          "requested cell type. Requested element ID extents: ["
-          + std::to_string(ext[0]) + "..." + std::to_string(ext[1])
-          + "), 'maxelements' of cell type with "
-          + std::to_string( ExoNnpe[ static_cast<std::size_t>(elemtype) ] )
-          + " nodes per cell in file '" + m_filename + "': "
-          + std::to_string( nelem( elemtype ) ) );
-
-  auto e = static_cast< std::size_t >( elemtype );
-  // List of number of elements of all blocks of element type requested
-  const auto& nel = m_nel[e];
-  // List of element block IDs for element type requested
-  const auto& bid = m_blockid_by_type[e];
+// Finish computing q = A * p
+// *****************************************************************************
+{
+  // Combine own and communicated contributions to q = A * p
+  auto ncomp = m_A.Ncomp();
+  for (const auto& [gid,q] : m_qc) {
+    auto i = tk::cref_find( m_lid, gid );
+    for (std::size_t c=0; c<ncomp; ++c)
+      m_q[i*ncomp+c] += q[c];
+  }
+  tk::destroy( m_qc );
+
+  // initiate computing (p,q)
+  dot( m_p, m_q,
+       CkCallback( CkReductionTarget(ConjugateGradients,pq), thisProxy ) );
+}
+
+void
+ConjugateGradients::pq( tk::real d )
+// *****************************************************************************
+// Compute the dot product (p,q)
+//! \param[in] d Dot product of (p,q) (aggregated across all chares)
+// *****************************************************************************
+{
+  // If (p,q)=0, then p and q are orthogonal and the system either has a trivial
+  // solution, x=x0, or the BCs are incomplete or wrong, in either case the
+  // solve cannot continue.
+  const auto eps = std::numeric_limits< tk::real >::epsilon();
+  if (std::abs(d) < eps) {
+    m_it = m_maxit;
+    m_alpha = 0.0;
+  } else {
+    m_alpha = m_rho / d;
+  }
+
+  // compute r = r - alpha * q
+  for (std::size_t i=0; i<m_r.size(); ++i) m_r[i] -= m_alpha * m_q[i];
 
-  // Compute lower and upper element block ids to read from based on extents
-  std::size_t lo_bid = 0, hi_bid = 0, offset = 0;
-  for (std::size_t b=0; b<nel.size(); ++b) {
-    std::size_t lo = offset;                    // lo (min) elem ID in block
-    std::size_t hi = offset + nel[b] - 1;       // hi (max) elem ID in block
-    if (ext[0] >= lo && ext[0] <= hi) lo_bid = b;
-    if (ext[1] >= lo && ext[1] <= hi) hi_bid = b;
-    offset += nel[b];
-  }
-
-  Assert( lo_bid < nel.size() && lo_bid < bid.size(),
-          "Invalid start block ID" );
-  Assert( hi_bid < nel.size() && hi_bid < bid.size(),
-          "Invalid end block ID" );
-
-  // Compute relative extents based on absolute ones for each block to read from
-  std::vector< std::array< std::size_t, 2 > > rext;
-  offset = 0;
-  for (std::size_t b=0; b<lo_bid; ++b) offset += nel[b];
-  for (std::size_t b=lo_bid; b<=hi_bid; ++b) {
-    std::size_t lo = offset;
-    std::size_t hi = offset + nel[b] - 1;
-    std::size_t le = 1, he = nel[b];
-    if (ext[0] >= lo && ext[0] <= hi) le = ext[0] - lo + 1;
-    if (ext[1] >= lo && ext[1] <= hi) he = ext[1] - lo + 1;
-    Assert( le >= 1 && le <= nel[b] && he >= 1 && he <= nel[b],
-            "Relative index out of block" );
-    rext.push_back( {{ le, he }} );
-    offset += nel[b];
-  }
-
-  Assert( std::accumulate(
-            std::next(rext.cbegin()), rext.cend(), rext[0][1]-rext[0][0]+1,
-            []( std::size_t n, const std::array< std::size_t, 2 >& r )
-            { return n + r[1] - r[0] + 1; }
-          ) == ext[1]-ext[0]+1,
-          "Total number of elements to read incorrect, requested extents: " +
-          std::to_string(ext[0]) + " ... " + std::to_string(ext[1]) );
-
-  std::vector< int > inpoel;
+  // initiate computing norm of residual: (r,r)
+  dot( m_r, m_r,
+       CkCallback( CkReductionTarget(ConjugateGradients,normres), thisProxy ) );
+}
+
+void
+ConjugateGradients::normres( tk::real r )
+// *****************************************************************************
+// Compute norm of residual: (r,r)
+//! \param[in] r Dot product, (r,r) (aggregated across all chares)
+// *****************************************************************************
+{
+  m_rho = r;
+
+  // Advance solution: x = x + alpha * p
+  for (std::size_t i=0; i<m_x.size(); ++i) m_x[i] += m_alpha * m_p[i];
+
+  // Communicate solution
+  thisProxy[ thisIndex ].wait4x();
+
+  // Send solution on chare-boundary nodes to fellow chares
+  if (m_nodeCommMap.empty()) {
+    comx_complete();
+  } else {
+    auto ncomp = m_A.Ncomp();
+    for (const auto& [c,n] : m_nodeCommMap) {
+      std::vector< std::vector< tk::real > > xc( n.size() );
+      std::size_t j = 0;
+      for (auto g : n) {
+        std::vector< tk::real > nx( ncomp );
+        auto i = tk::cref_find( m_lid, g );
+        for (std::size_t d=0; d<ncomp; ++d) nx[d] = m_x[ i*ncomp+d ];
+        xc[j++] = std::move(nx);
+      }
+      thisProxy[c].comx( std::vector<std::size_t>(begin(n),end(n)), xc );
+    }
+  }
+
+  ownx_complete();
+}
 
-  // Read element connectivity from file
-  std::size_t B = 0;
-  for (auto b=lo_bid; b<=hi_bid; ++b, ++B) {
-    const auto& r = rext[B];
-    std::vector< int > c( (r[1]-r[0]+1) * ExoNnpe[e] );
-    ErrChk( ex_get_partial_conn( m_inFile,
-                                 EX_ELEM_BLOCK,
-                                 bid[b],
-                                 static_cast< int64_t >( r[0] ),
-                                 static_cast< int64_t >( r[1]-r[0]+1 ),
-                                 c.data(),
-                                 nullptr,
-                                 nullptr ) == 0,
-            "Failed to read element connectivity of elements [" +
-            std::to_string(r[0]) + "..." + std::to_string(r[1]) +
-            "] from element block " + std::to_string(bid[b]) + " in ExodusII "
-            "file: " + m_filename );
-
-    // Store tet-elements under their respective mesh block ids
-    if (elemtype == ExoElemType::TET) {
-      for (std::size_t i=0; i<c.size()/ExoNnpe[e]; ++i) {
-        auto& tetblk = m_elemInBlockId[static_cast<std::size_t>(bid[b])];
-        tetblk.insert((inpoel.size()/ExoNnpe[e]) + i);
-      }
-    }
-
-    inpoel.reserve( inpoel.size() + c.size() );
-    std::move( begin(c), end(c), std::back_inserter(inpoel) );
-  }
-
-  Assert( inpoel.size() == (ext[1]-ext[0]+1)*ExoNnpe[e],
-          "Failed to read element connectivity of elements [" +
-          std::to_string(ext[0]) + "..." + std::to_string(ext[1]) + ") from "
-          "ExodusII file: " + m_filename );
+void
+ConjugateGradients::comx( const std::vector< std::size_t >& gid,
+                          const std::vector< std::vector< tk::real > >& xc )
+// *****************************************************************************
+//  Receive contributions to final solution on chare-boundaries
+//! \param[in] gid Global mesh node IDs at which we receive contributions
+//! \param[in] xc Partial contributions at chare-boundary nodes
+// *****************************************************************************
+{
+  Assert( xc.size() == gid.size(), "Size mismatch" );
+
+  for (std::size_t i=0; i<gid.size(); ++i) m_xc[ gid[i] ] += xc[i];
+
+  if (++m_nx == m_nodeCommMap.size()) {
+    m_nx = 0;
+    comx_complete();
+  }
+}
+
+void
+ConjugateGradients::x()
+// *****************************************************************************
+// Assemble solution on chare boundaries
+// *****************************************************************************
+{
+  // Assemble solution on chare boundaries by averaging
+  auto ncomp = m_A.Ncomp();
+  for (const auto& [g,x] : m_xc) {
+    auto i = tk::cref_find(m_lid,g);
+    for (std::size_t d=0; d<ncomp; ++d) m_x[i*ncomp+d] += x[d];
+    auto c = tk::count(m_nodeCommMap,g);
+    for (std::size_t d=0; d<ncomp; ++d) m_x[i*ncomp+d] /= c;
+  }
+  tk::destroy( m_xc );
 
-  // Put in element connectivity using zero-based node indexing
-  for (auto& i : inpoel) --i;
-  conn.reserve( conn.size() + inpoel.size() );
-  std::move( begin(inpoel), end(inpoel), std::back_inserter(conn) );
-}
+  ++m_it;
+  auto normb = m_normb > 1.0e-14 ? m_normb : 1.0;
+  auto normr = std::sqrt( m_rho );
+
+  if ( m_it < m_maxit && normr > m_tol*normb ) {
 
-void
-ExodusIIMeshReader::readFaces( std::vector< std::size_t >& conn )
-// *****************************************************************************
-//  Read face connectivity of a number of boundary faces from ExodusII file
-//! \param[inout] conn Connectivity vector to push to
-//! \details This function reads in the total number of boundary faces,
-//!   also called triangle-elements in the EXO2 file, and their connectivity.
-// *****************************************************************************
-{
-  // Return quietly if no triangle elements in file
-  if (nelem(tk::ExoElemType::TRI) == 0) return;
-
-  // Read triangle boundary-face connectivity (all the triangle element block)
-  readElements( {{0,nelem(tk::ExoElemType::TRI)-1}}, tk::ExoElemType::TRI,
-                conn );
-}
-
-std::vector< std::size_t >
-ExodusIIMeshReader::readNodemap()
-// *****************************************************************************
-//  Read local to global node-ID map from ExodusII file
-//! \return node_map Vector mapping the local Exodus node-IDs to global node-IDs
-//! \details The node-map is required to get the "Exodus-global" node-IDs from
-//!   the "Exodus-internal" node-IDs, which are returned from the exodus APIs.
-//!   The node-IDs in the exodus file are referred to as the "Exodus-global"
-//!   node-IDs or "fileIDs" in Quinoa.
-// *****************************************************************************
-{
-  // Read triangle boundary-face connectivity
-  auto nnode = readElemBlockIDs();
-
-  // Create array to store node-number map
-  std::vector< int > node_map( nnode );
-
-  // Read in the node number map to map the above nodes to the global node-IDs
-  ErrChk( ex_get_id_map( m_inFile, EX_NODE_MAP, node_map.data() ) == 0,
-          "Failed to read node map length from ExodusII file: " );
-
-  std::vector< std::size_t > node_map1( nnode );
-
-  for (std::size_t i=0; i<nnode; ++i)
-  {
-          node_map1[i] = static_cast< std::size_t >(node_map[i]-1);
-  }
-
-  return node_map1;
-}
-
-std::map< int, std::vector< std::size_t > >
-ExodusIIMeshReader::readSidesetNodes()
-// *****************************************************************************
-//  Read node list of all side sets from ExodusII file
-//! \return Node lists mapped to side set ids
-// *****************************************************************************
-{
-  // Read ExodusII file header (fills m_neset)
-  readHeader();
-
-  // Node lists mapped to side set ids
-  std::map< int, std::vector< std::size_t > > side;
-
-  if (m_neset > 0) {
-    // Read all side set ids from file
-    std::vector< int > ids( m_neset );
-    ErrChk( ex_get_ids( m_inFile, EX_SIDE_SET, ids.data() ) == 0,
-            "Failed to read side set ids from ExodusII file: " + m_filename );
-    // Read in node list for all side sets
-    for (auto i : ids) {
-      int nface, nnode;
-      // Read number of faces and number of distribution factors in side set i
-      ErrChk( ex_get_set_param( m_inFile, EX_SIDE_SET, i, &nface, &nnode ) == 0,
-              "Failed to read side set " + std::to_string(i) + " parameters "
-              "from ExodusII file: " + m_filename );
-      // Read number of nodes in side set i (overwrite nnode)
-      ErrChk( ex_get_side_set_node_list_len( m_inFile, i, &nnode ) == 0,
-              "Failed to read side set " + std::to_string(i) + " node list "
-              "length from ExodusII file: " + m_filename );
-      Assert(nnode > 0, "Number of nodes = 0 in side set" + std::to_string(i));
-      std::vector< int > df( static_cast< std::size_t >( nface ) );
-      std::vector< int > nodes( static_cast< std::size_t >( nnode ) );
-      // Read in node list for side set i
-      ErrChk( ex_get_side_set_node_list( m_inFile, i, df.data(), nodes.data() )
-                == 0, "Failed to read node list of side set " +
-                      std::to_string(i) + " from ExodusII file: " +
-                      m_filename );
-      // Make node list unique
-      tk::unique( nodes );
-      // Store 0-based node ID list as std::size_t vector instead of ints
-      auto& list = side[ i ];
-      for (auto n : nodes) list.push_back( static_cast<std::size_t>(n-1) );<--- Consider using std::transform algorithm instead of a raw loop.
-    }
-  }
-
-  return side;
-}
-
-void
-ExodusIIMeshReader::readSidesetFaces(
-  std::map< int, std::vector< std::size_t > >& bface,
-  std::map< int, std::vector< std::size_t > >& faces )
-// *****************************************************************************
-//  Read side sets from ExodusII file
-//! \param[in,out] bface Elem ids of side sets to read into
-//! \param[in,out] faces Elem-relative face ids of tets of side sets
-// *****************************************************************************
-{
-  // Read element block ids
-  readElemBlockIDs();
-
-  if (m_neset > 0) {
-    // Read side set ids from file
-    std::vector< int > ids( m_neset );
-    ErrChk( ex_get_ids( m_inFile, EX_SIDE_SET, ids.data() ) == 0,
-            "Failed to read side set ids from ExodusII file: " + m_filename );
-
-    // Read all side sets from file
-    for (auto i : ids) {
-      int nface, nnode;
-
-      // Read number of faces in side set
-      ErrChk( ex_get_set_param( m_inFile, EX_SIDE_SET, i, &nface, &nnode ) == 0,
-              "Failed to read side set " + std::to_string(i) + " parameters "
-              "from ExodusII file: " + m_filename );
-
-      Assert(nface > 0, "Number of faces = 0 in side set" + std::to_string(i));
-
-      std::vector< int > exoelem( static_cast< std::size_t >( nface ) );
-      std::vector< int > exoface( static_cast< std::size_t >( nface ) );
-
-      // Read in file-internal element ids and relative face ids for side set
-      ErrChk( ex_get_set( m_inFile, EX_SIDE_SET, i, exoelem.data(),
-                          exoface.data() ) == 0,
-              "Failed to read side set " + std::to_string(i) );
-
-      // Store file-internal element ids of side set
-      auto& elem = bface[i];
-      elem.resize( exoelem.size() );
-      std::size_t j = 0;
-      for (auto e : exoelem) elem[j++] = static_cast< std::size_t >( e-1 );
-
-      // Store zero-based relative face ids of side set
-      auto& face = faces[i];
-      face.resize( exoface.size() );
-      j = 0;
-      for (auto n : exoface) face[j++] = static_cast< std::size_t >( n-1 );
-
-      Assert( std::all_of( begin(face), end(face),
-                           [](std::size_t f){ return f<4; } ),
-              "Relative face id of side set must be between 0 and 3" );
-      Assert( elem.size() == face.size(), "Size mismatch" );
-    }
-  }
-}
-
-std::pair< tk::ExoElemType, std::size_t >
-ExodusIIMeshReader::blkRelElemId( std::size_t id ) const
-// *****************************************************************************
-// Compute element-block-relative element id and element type
-//! \param[in] id (ExodusII) file-internal element id
-//! \return Element type the internal id points to and element id relative to
-//!   cell-type
-//! \details This function takes an internal element id, which in general can
-//!   point to any element block in the ExodusII file and thus we do not know
-//!   which element type a block contains. It then computes which cell type the
-//!   id points to and computes the relative index for the given cell type. This
-//!   is necessary because elements are read in from file by from potentially
-//!   multiple blocks by cell type.
-//! \note Must be preceded by a call to readElemBlockIDs()
-// *****************************************************************************
-{
-  auto TRI = tk::ExoElemType::TRI;
-  auto TET = tk::ExoElemType::TET;
-
-  std::size_t e = 0;            // counts elements (independent of cell type)
-  std::size_t ntri = 0;         // counts triangle elements
-  std::size_t ntet = 0;         // counts tetrahedron elements
-
-  for (const auto& b : m_elemblocks) {  // walk all element blocks in order
-    e += b.second;                      // increment file-internal element id
-    if (e > id) {                       // found element block for internal id
-      if (b.first == TRI) {             // if triangle block
-        return { TRI, id-ntet };        // return cell type and triangle id
-      } else if (b.first == TET) {      // if tetrahedron block
-        return { TET, id-ntri };        // return cell type and tetrahedron id
-      }
-    }
-    // increment triangle and tetrahedron elements independently
-    if (b.first == TRI)
-      ntri += b.second;
-    else if (b.first == TET)
-      ntet += b.second;
-  }
-
-  Throw( " Exodus internal element id not found" );
-}
-
-std::vector< std::size_t >
-ExodusIIMeshReader::triinpoel(
-  std::map< int, std::vector< std::size_t > >& belem,
-  const std::map< int, std::vector< std::size_t > >& faces,
-  const std::vector< std::size_t >& ginpoel,
-  const std::vector< std::size_t >& triinp ) const
-// *****************************************************************************
-//  Generate triangle face connectivity for side sets
-//! \param[in,out] belem File-internal elem ids of side sets
-//! \param[in] faces Elem-relative face ids of side sets
-//! \param[in] ginpoel Tetrahedron element connectivity with global nodes
-//! \param[in] triinp Triangle element connectivity with global nodes
-//!   (if exists in file)
-//! \return Triangle face connectivity with global node IDs of side sets
-//! \details This function takes lists of file-internal element ids (in belem)
-//!   for side sets and does two things: (1) generates face connectivity (with
-//!   global node IDs) for side sets, and (2) converts the (ExodusII)
-//!   file-internal element IDs to face ids so that they can be used to index
-//!   into the face connectivity. The IDs in belem are modified and the face
-//!   connectivity (for boundary faces only) is returned.
-//! \note Must be preceded by a call to readElemBlockIDs()
-// *****************************************************************************
-{
-  Assert( !(m_from == 0 && m_till == 0),
-          "Lower and upper tetrahedron id bounds must not both be zero" );
-
-  // This will contain one of our final results: face (triangle) connectivity
-  // for the side sets only. The difference between bnd_triinpoel and triinpoel
-  // is that triinpoel is a triangle element connectivity, independent of side
-  // sets, while bnd_triinpoel is a triangle connectivity only for side sets.
-  std::vector< std::size_t > bnd_triinpoel;
-
-  // Storage for boundary face lists for each side set on this PE
-  std::map< int, std::vector< std::size_t > > belem_own;
-
-  std::size_t f = 0;            // counts all faces
-  for (auto& ss : belem) {      // for all side sets
-
-    // insert side set id into new map
-    auto& b = belem_own[ ss.first ];
-    // get element-relative face ids for side set
-    const auto& face = tk::cref_find( faces, ss.first );
-    std::size_t s = 0;          // counts side set faces
-    for (auto& i : ss.second) { // for all faces on side set
-
-      // compute element-block-relative element id and element type
-      auto r = blkRelElemId( i );
-
-      // extract boundary face connectivity based on element type
-      bool localface = false;
-      if (r.first == tk::ExoElemType::TRI) {
-
-        auto t = m_tri.find(r.second);
-        if (t != end(m_tri)) {  // only if triangle id exists on this PE
-          Assert( t->second < triinp.size()/3,
-                  "Indexing out of triangle connectivity" );
-          // generate triangle (face) connectivity using global node ids
-          bnd_triinpoel.push_back( triinp[ t->second*3 + 0 ] );
-          bnd_triinpoel.push_back( triinp[ t->second*3 + 1 ] );
-          bnd_triinpoel.push_back( triinp[ t->second*3 + 2 ] );
-          localface = true;
-        }
-
-      } else if (r.first == tk::ExoElemType::TET) {
-
-        if (r.second >= m_from && r.second < m_till) {  // if tet is on this PE
-          auto t = r.second - m_from;
-          Assert( t < ginpoel.size()/4,
-                  "Indexing out of tetrahedron connectivity" );
-          // get ExodusII face-node numbering for side sets, see ExodusII
-          // manual figure on "Sideset side Numbering"
-          const auto& tri = tk::expofa[ face[s] ];
-          // generate triangle (face) connectivity using global node ids, note
-          // the switched node order, 0,2,1, as lpofa is different from expofa
-          bnd_triinpoel.push_back( ginpoel[ t*4 + tri[0] ] );
-          bnd_triinpoel.push_back( ginpoel[ t*4 + tri[1] ] );
-          bnd_triinpoel.push_back( ginpoel[ t*4 + tri[2] ] );
-          localface = true;
-        }
-
-      }
-
-      ++s;
-
-      // generate PE-local face id for side set (this is to be used to index
-      // into triinpoel)
-      if (localface) b.push_back( f++ );
-    }
-
-    // if no faces on this side set (on this PE), remove side set id
-    if (b.empty()) belem_own.erase( ss.first );
-  }
-
-  belem = std::move(belem_own);
-
-  return bnd_triinpoel;
-}
-
-void
-ExodusIIMeshReader::readNodeVarNames( std::vector< std::string >& nv ) const
-// *****************************************************************************
-//  Read the names of nodal output variables from ExodusII file
-//! \param[in,out] nv Nodal variable names
-// *****************************************************************************
-{
-  #if defined(__clang__)
-    #pragma clang diagnostic push
-    #pragma clang diagnostic ignored "-Wvla"
-    #pragma clang diagnostic ignored "-Wvla-extension"
-  #elif defined(STRICT_GNUC)
-    #pragma GCC diagnostic push
-    #pragma GCC diagnostic ignored "-Wvla"
-  #endif
-
-  int numvars = 0;
-
-  ErrChk(
-    ex_get_variable_param( m_inFile, EX_NODE_BLOCK, &numvars ) == 0,
-    "Failed to read nodal output variable parameters from ExodusII file: " +
-    m_filename );
-
-  if (numvars) {
-
-    char* names[ static_cast< std::size_t >( numvars ) ];
-    for (int i=0; i<numvars; ++i)
-      names[i] = static_cast<char*>( calloc((MAX_STR_LENGTH+1), sizeof(char)) );
-
-    ErrChk( ex_get_variable_names( m_inFile,
-                                   EX_NODAL,
-                                   numvars,
-                                   names ) == 0,
-            "Failed to read nodal variable names from ExodusII file: " +
-            m_filename );
-
-    nv.resize( static_cast< std::size_t >( numvars ) );
-    std::size_t i = 0;
-    for (auto& n : nv) n = names[ i++ ];<--- Consider using std::fill or std::generate algorithm instead of a raw loop.
-
-  }
-
-  #if defined(__clang__)
-    #pragma clang diagnostic pop
-  #elif defined(STRICT_GNUC)
-    #pragma GCC diagnostic pop
-  #endif
-}
-
-void
-ExodusIIMeshReader::readElemVarNames( std::vector< std::string >& ev ) const
-// *****************************************************************************
-//  Read the names of elemental output variables from ExodusII file
-//! \param[in,out] ev Elemental variable names
-// *****************************************************************************
-{
-  #if defined(__clang__)
-    #pragma clang diagnostic push
-    #pragma clang diagnostic ignored "-Wvla"
-    #pragma clang diagnostic ignored "-Wvla-extension"
-  #elif defined(STRICT_GNUC)
-    #pragma GCC diagnostic push
-    #pragma GCC diagnostic ignored "-Wvla"
-  #endif
-
-  int numvars = 0;
-
-  ErrChk(
-    ex_get_variable_param( m_inFile, EX_ELEM_BLOCK, &numvars ) == 0,
-    "Failed to read element output variable parameters from ExodusII file: " +
-    m_filename );
-
-  if (numvars) {
-
-    char* names[ static_cast< std::size_t >( numvars ) ];
-    for (int i=0; i<numvars; ++i)
-      names[i] = static_cast<char*>( calloc((MAX_STR_LENGTH+1), sizeof(char)) );
-
-    ErrChk( ex_get_variable_names( m_inFile,
-                                   EX_ELEM_BLOCK,
-                                   numvars,
-                                   names ) == 0,
-            "Failed to read element variable names from ExodusII file: " +
-            m_filename );
-
-    ev.resize( static_cast< std::size_t >( numvars ) );
-    std::size_t i = 0;
-    for (auto& n : ev) n = names[ i++ ];<--- Consider using std::fill or std::generate algorithm instead of a raw loop.
-
-  }
-
-  #if defined(__clang__)
-    #pragma clang diagnostic pop
-  #elif defined(STRICT_GNUC)
-    #pragma GCC diagnostic pop
-  #endif
-}
-
-void
-ExodusIIMeshReader::readTimeValues( std::vector< tk::real >& tv ) const
-// *****************************************************************************
-//  Read time values from ExodusII file
-//! \param[in] tv Vector of time values at which field data is saved
-// *****************************************************************************
-{
-  auto num_time_steps =
-    static_cast< std::size_t >( ex_inquire_int( m_inFile, EX_INQ_TIME ) );
-
-  if (num_time_steps) {
-    tv.resize( num_time_steps, 0.0 );
-    ErrChk( ex_get_all_times( m_inFile, tv.data() ) == 0,
-             "Failed to read time values from ExodusII file: " + m_filename );
-  }
-}
-
-void
-ExodusIIMeshReader::readNodeScalars(
-  std::size_t ntime,
-  std::size_t nvar,
-  std::vector< std::vector< std::vector< tk::real > > >& var ) const
-// *****************************************************************************
-//  Read node scalar fields from ExodusII file
-//! \param[in] ntime Number of time steps to read
-//! \param[in] nvar Number of variables to read
-//! \param[in] var Vector of nodal variables to read to: inner vector: nodes,
-//!   middle vector: (physics) variable, outer vector: time step
-// *****************************************************************************
-{
-  var.resize( ntime );
-  for (auto& v : var) {
-    v.resize( nvar );
-    for (auto& n : v) n.resize( m_nnode );
-  }
-
-  for (std::size_t t=0; t<var.size(); ++t) {
-    for (std::size_t id=0; id<var[t].size(); ++id) {
-      ErrChk( ex_get_var( m_inFile,
-                          static_cast< int >( t+1 ),
-                          EX_NODAL,
-                          static_cast< int >( id+1 ),
-                          1,
-                          static_cast< int64_t >( var[t][id].size() ),
-                          var[t][id].data() ) == 0,
-              "Failed to read node scalar from ExodusII file: " + m_filename );
-    }
-  }
-}
-
-void
-ExodusIIMeshReader::readElemScalars(
-  std::size_t ntime,
-  std::size_t nvar,
-  std::vector< std::vector< std::vector< tk::real > > >& var ) const
-// *****************************************************************************
-//  Read element scalar fields from ExodusII file
-//! \param[in] ntime Number of time steps to read
-//! \param[in] nvar Number of variables to read
-//! \param[in] var Vector of elemental variables to read to: inner vector:
-//!   elements, middle vector: (physics) variable, outer vector: time step
-// *****************************************************************************
-{
-  var.resize( ntime );
-  for (auto& v : var) {
-    v.resize( nvar );
-    for (auto& n : v) n.resize( m_nelem );
-  }
-
-  for (std::size_t t=0; t<var.size(); ++t) {
-    for (std::size_t id=0; id<var[t].size(); ++id) {
-      ErrChk( ex_get_var( m_inFile,
-                          static_cast< int >( t+1 ),
-                          EX_ELEM_BLOCK,
-                          static_cast< int >( id+1 ),
-                          1,
-                          static_cast< int64_t >( var[t][id].size() ),
-                          var[t][id].data() ) == 0,
-              "Failed to read element scalar from ExodusII file: " +
-              m_filename );
-    }
-  }
-}
-
-std::size_t
-ExodusIIMeshReader::nelem( tk::ExoElemType elemtype ) const
-// *****************************************************************************
-//  Return number of elements in all mesh blocks for a given elem type in file
-//! \param[in] elemtype Element type
-//! \return Number of elements in all blocks for the elem type
-//! \note Must be preceded by a call to readElemBlockIDs()
-// *****************************************************************************
-{
-  auto e = static_cast< std::size_t >( elemtype );
-  return std::accumulate( m_nel[e].cbegin(), m_nel[e].cend(), 0u );
-}
+    next();
+
+  } else {
+
+    m_converged = m_it == m_maxit && normr > m_tol*normb ? false : true;
+    m_solved.send( CkDataMsg::buildNew( sizeof(tk::real), &normr ) );
+
+  }
+}
+
+#include "NoWarning/conjugategradients.def.h"
 
diff --git a/Debug/cppcheck/15.html b/Debug/cppcheck/15.html index 26fe26f9b63b..b128b5d1e77f 100644 --- a/Debug/cppcheck/15.html +++ b/Debug/cppcheck/15.html @@ -152,2667 +152,535 @@
- - + @@ -102,7 +102,7 @@ 28 : : public: 29 : : 30 : : //! Default constructor for migration - 31 : 7861 : refinement_t() {} + 31 : 7774 : refinement_t() {} 32 : : 33 : : //! Constructor taking a user-specified max refinement level 34 : 2007 : refinement_t( size_t u_mrl ) : diff --git a/Debug/test_coverage/Inciter/AMR/tet_store.hpp.func-sort-c.html b/Debug/test_coverage/Inciter/AMR/tet_store.hpp.func-sort-c.html index abaec928fa4f..826dc29a45b7 100644 --- a/Debug/test_coverage/Inciter/AMR/tet_store.hpp.func-sort-c.html +++ b/Debug/test_coverage/Inciter/AMR/tet_store.hpp.func-sort-c.html @@ -33,7 +33,7 @@ - + diff --git a/Debug/test_coverage/Inciter/AMR/tet_store.hpp.func.html b/Debug/test_coverage/Inciter/AMR/tet_store.hpp.func.html index 7570d143e63d..f8f500fd2e6d 100644 --- a/Debug/test_coverage/Inciter/AMR/tet_store.hpp.func.html +++ b/Debug/test_coverage/Inciter/AMR/tet_store.hpp.func.html @@ -33,7 +33,7 @@ - + diff --git a/Debug/test_coverage/Inciter/AMR/tet_store.hpp.gcov.html b/Debug/test_coverage/Inciter/AMR/tet_store.hpp.gcov.html index ec25dbd05ad0..d2ffdd904ba1 100644 --- a/Debug/test_coverage/Inciter/AMR/tet_store.hpp.gcov.html +++ b/Debug/test_coverage/Inciter/AMR/tet_store.hpp.gcov.html @@ -33,7 +33,7 @@ - + diff --git a/Debug/test_coverage/Inciter/AMR/util.cpp.func-sort-c.html b/Debug/test_coverage/Inciter/AMR/util.cpp.func-sort-c.html index 9ccdcdd0925b..447f37e014a9 100644 --- a/Debug/test_coverage/Inciter/AMR/util.cpp.func-sort-c.html +++ b/Debug/test_coverage/Inciter/AMR/util.cpp.func-sort-c.html @@ -33,7 +33,7 @@ - + diff --git a/Debug/test_coverage/Inciter/AMR/util.cpp.func.html b/Debug/test_coverage/Inciter/AMR/util.cpp.func.html index 53f096748a7e..6ba07a65b7b5 100644 --- a/Debug/test_coverage/Inciter/AMR/util.cpp.func.html +++ b/Debug/test_coverage/Inciter/AMR/util.cpp.func.html @@ -33,7 +33,7 @@ - + diff --git a/Debug/test_coverage/Inciter/AMR/util.cpp.gcov.html b/Debug/test_coverage/Inciter/AMR/util.cpp.gcov.html index 0803b2a83850..18dcd93bb14b 100644 --- a/Debug/test_coverage/Inciter/AMR/util.cpp.gcov.html +++ b/Debug/test_coverage/Inciter/AMR/util.cpp.gcov.html @@ -33,7 +33,7 @@ - + diff --git a/Debug/test_coverage/Inciter/DG.cpp.func-sort-c.html b/Debug/test_coverage/Inciter/DG.cpp.func-sort-c.html index 54c9aea71a84..bfe10d89a76c 100644 --- a/Debug/test_coverage/Inciter/DG.cpp.func-sort-c.html +++ b/Debug/test_coverage/Inciter/DG.cpp.func-sort-c.html @@ -33,7 +33,7 @@ - + @@ -237,7 +237,7 @@ - +
   1
-   2
-   3
-   4
-   5
-   6
-   7
-   8
-   9
-  10
-  11
-  12
-  13
-  14
-  15
-  16
-  17
-  18
-  19
-  20
-  21
-  22
-  23
-  24
-  25
-  26
-  27
-  28
-  29
-  30
-  31
-  32
-  33
-  34
-  35
-  36
-  37
-  38
-  39
-  40
-  41
-  42
-  43
-  44
-  45
-  46
-  47
-  48
-  49
-  50
-  51
-  52
-  53
-  54
-  55
-  56
-  57
-  58
-  59
-  60
-  61
-  62
-  63
-  64
-  65
-  66
-  67
-  68
-  69
-  70
-  71
-  72
-  73
-  74
-  75
-  76
-  77
-  78
-  79
-  80
-  81
-  82
-  83
-  84
-  85
-  86
-  87
-  88
-  89
-  90
-  91
-  92
-  93
-  94
-  95
-  96
-  97
-  98
-  99
- 100
- 101
- 102
- 103
- 104
- 105
- 106
- 107
- 108
- 109
- 110
- 111
- 112
- 113
- 114
- 115
- 116
- 117
- 118
- 119
- 120
- 121
- 122
- 123
- 124
- 125
- 126
- 127
- 128
- 129
- 130
- 131
- 132
- 133
- 134
- 135
- 136
- 137
- 138
- 139
- 140
- 141
- 142
- 143
- 144
- 145
- 146
- 147
- 148
- 149
- 150
- 151
- 152
- 153
- 154
- 155
- 156
- 157
- 158
- 159
- 160
- 161
- 162
- 163
- 164
- 165
- 166
- 167
- 168
- 169
- 170
- 171
- 172
- 173
- 174
- 175
- 176
- 177
- 178
- 179
- 180
- 181
- 182
- 183
- 184
- 185
- 186
- 187
- 188
- 189
- 190
- 191
- 192
- 193
- 194
- 195
- 196
- 197
- 198
- 199
- 200
- 201
- 202
- 203
- 204
- 205
- 206
- 207
- 208
- 209
- 210
- 211
- 212
- 213
- 214
- 215
- 216
- 217
- 218
- 219
- 220
- 221
- 222
- 223
- 224
- 225
- 226
- 227
- 228
- 229
- 230
- 231
- 232
- 233
- 234
- 235
- 236
- 237
- 238
- 239
- 240
- 241
- 242
- 243
- 244
- 245
- 246
- 247
- 248
- 249
- 250
- 251
- 252
- 253
- 254
- 255
- 256
- 257
- 258
- 259
- 260
- 261
- 262
- 263
- 264
- 265
- 266
- 267
- 268
- 269
- 270
- 271
- 272
- 273
- 274
- 275
- 276
- 277
- 278
- 279
- 280
- 281
- 282
- 283
- 284
- 285
- 286
- 287
- 288
- 289
- 290
- 291
- 292
- 293
- 294
- 295
- 296
- 297
- 298
- 299
- 300
- 301
- 302
- 303
- 304
- 305
- 306
- 307
- 308
- 309
- 310
- 311
- 312
- 313
- 314
- 315
- 316
- 317
- 318
- 319
- 320
- 321
- 322
- 323
- 324
- 325
- 326
- 327
- 328
- 329
- 330
- 331
- 332
- 333
- 334
- 335
- 336
- 337
- 338
- 339
- 340
- 341
- 342
- 343
- 344
- 345
- 346
- 347
- 348
- 349
- 350
- 351
- 352
- 353
- 354
- 355
- 356
- 357
- 358
- 359
- 360
- 361
- 362
- 363
- 364
- 365
- 366
- 367
- 368
- 369
- 370
- 371
- 372
- 373
- 374
- 375
- 376
- 377
- 378
- 379
- 380
- 381
- 382
- 383
- 384
- 385
- 386
- 387
- 388
- 389
- 390
- 391
- 392
- 393
- 394
- 395
- 396
- 397
- 398
- 399
- 400
- 401
- 402
- 403
- 404
- 405
- 406
- 407
- 408
- 409
- 410
- 411
- 412
- 413
- 414
- 415
- 416
- 417
- 418
- 419
- 420
- 421
- 422
- 423
- 424
- 425
- 426
- 427
- 428
- 429
- 430
- 431
- 432
- 433
- 434
- 435
- 436
- 437
- 438
- 439
- 440
- 441
- 442
- 443
- 444
- 445
- 446
- 447
- 448
- 449
- 450
- 451
- 452
- 453
- 454
- 455
- 456
- 457
- 458
- 459
- 460
- 461
- 462
- 463
- 464
- 465
- 466
- 467
- 468
- 469
- 470
- 471
- 472
- 473
- 474
- 475
- 476
- 477
- 478
- 479
- 480
- 481
- 482
- 483
- 484
- 485
- 486
- 487
- 488
- 489
- 490
- 491
- 492
- 493
- 494
- 495
- 496
- 497
- 498
- 499
- 500
- 501
- 502
- 503
- 504
- 505
- 506
- 507
- 508
- 509
- 510
- 511
- 512
- 513
- 514
- 515
- 516
- 517
- 518
- 519
- 520
- 521
- 522
- 523
- 524
- 525
- 526
- 527
- 528
- 529
- 530
- 531
- 532
- 533
- 534
- 535
- 536
- 537
- 538
- 539
- 540
- 541
- 542
- 543
- 544
- 545
- 546
- 547
- 548
- 549
- 550
- 551
- 552
- 553
- 554
- 555
- 556
- 557
- 558
- 559
- 560
- 561
- 562
- 563
- 564
- 565
- 566
- 567
- 568
- 569
- 570
- 571
- 572
- 573
- 574
- 575
- 576
- 577
- 578
- 579
- 580
- 581
- 582
- 583
- 584
- 585
- 586
- 587
- 588
- 589
- 590
- 591
- 592
- 593
- 594
- 595
- 596
- 597
- 598
- 599
- 600
- 601
- 602
- 603
- 604
- 605
- 606
- 607
- 608
- 609
- 610
- 611
- 612
- 613
- 614
- 615
- 616
- 617
- 618
- 619
- 620
- 621
- 622
- 623
- 624
- 625
- 626
- 627
- 628
- 629
- 630
- 631
- 632
- 633
- 634
- 635
- 636
- 637
- 638
- 639
- 640
- 641
- 642
- 643
- 644
- 645
- 646
- 647
- 648
- 649
- 650
- 651
- 652
- 653
- 654
- 655
- 656
- 657
- 658
- 659
- 660
- 661
- 662
- 663
- 664
- 665
- 666
- 667
- 668
- 669
- 670
- 671
- 672
- 673
- 674
- 675
- 676
- 677
- 678
- 679
- 680
- 681
- 682
- 683
- 684
- 685
- 686
- 687
- 688
- 689
- 690
- 691
- 692
- 693
- 694
- 695
- 696
- 697
- 698
- 699
- 700
- 701
- 702
- 703
- 704
- 705
- 706
- 707
- 708
- 709
- 710
- 711
- 712
- 713
- 714
- 715
- 716
- 717
- 718
- 719
- 720
- 721
- 722
- 723
- 724
- 725
- 726
- 727
- 728
- 729
- 730
- 731
- 732
- 733
- 734
- 735
- 736
- 737
- 738
- 739
- 740
- 741
- 742
- 743
- 744
- 745
- 746
- 747
- 748
- 749
- 750
- 751
- 752
- 753
- 754
- 755
- 756
- 757
- 758
- 759
- 760
- 761
- 762
- 763
- 764
- 765
- 766
- 767
- 768
- 769
- 770
- 771
- 772
- 773
- 774
- 775
- 776
- 777
- 778
- 779
- 780
- 781
- 782
- 783
- 784
- 785
- 786
- 787
- 788
- 789
- 790
- 791
- 792
- 793
- 794
- 795
- 796
- 797
- 798
- 799
- 800
- 801
- 802
- 803
- 804
- 805
- 806
- 807
- 808
- 809
- 810
- 811
- 812
- 813
- 814
- 815
- 816
- 817
- 818
- 819
- 820
- 821
- 822
- 823
- 824
- 825
- 826
- 827
- 828
- 829
- 830
- 831
- 832
- 833
- 834
- 835
- 836
- 837
- 838
- 839
- 840
- 841
- 842
- 843
- 844
- 845
- 846
- 847
- 848
- 849
- 850
- 851
- 852
- 853
- 854
- 855
- 856
- 857
- 858
- 859
- 860
- 861
- 862
- 863
- 864
- 865
- 866
- 867
- 868
- 869
- 870
- 871
- 872
- 873
- 874
- 875
- 876
- 877
- 878
- 879
- 880
- 881
- 882
- 883
- 884
- 885
- 886
- 887
- 888
- 889
- 890
- 891
- 892
- 893
- 894
- 895
- 896
- 897
- 898
- 899
- 900
- 901
- 902
- 903
- 904
- 905
- 906
- 907
- 908
- 909
- 910
- 911
- 912
- 913
- 914
- 915
- 916
- 917
- 918
- 919
- 920
- 921
- 922
- 923
- 924
- 925
- 926
- 927
- 928
- 929
- 930
- 931
- 932
- 933
- 934
- 935
- 936
- 937
- 938
- 939
- 940
- 941
- 942
- 943
- 944
- 945
- 946
- 947
- 948
- 949
- 950
- 951
- 952
- 953
- 954
- 955
- 956
- 957
- 958
- 959
- 960
- 961
- 962
- 963
- 964
- 965
- 966
- 967
- 968
- 969
- 970
- 971
- 972
- 973
- 974
- 975
- 976
- 977
- 978
- 979
- 980
- 981
- 982
- 983
- 984
- 985
- 986
- 987
- 988
- 989
- 990
- 991
- 992
- 993
- 994
- 995
- 996
- 997
- 998
- 999
-1000
-1001
-1002
-1003
-1004
-1005
-1006
-1007
-1008
-1009
-1010
-1011
-1012
-1013
-1014
-1015
-1016
-1017
-1018
-1019
-1020
-1021
-1022
-1023
-1024
-1025
-1026
-1027
-1028
-1029
-1030
-1031
-1032
-1033
-1034
-1035
-1036
-1037
-1038
-1039
-1040
-1041
-1042
-1043
-1044
-1045
-1046
-1047
-1048
-1049
-1050
-1051
-1052
-1053
-1054
-1055
-1056
-1057
-1058
-1059
-1060
-1061
-1062
-1063
-1064
-1065
-1066
-1067
-1068
-1069
-1070
-1071
-1072
-1073
-1074
-1075
-1076
-1077
-1078
-1079
-1080
-1081
-1082
-1083
-1084
-1085
-1086
-1087
-1088
-1089
-1090
-1091
-1092
-1093
-1094
-1095
-1096
-1097
-1098
-1099
-1100
-1101
-1102
-1103
-1104
-1105
-1106
-1107
-1108
-1109
-1110
-1111
-1112
-1113
-1114
-1115
-1116
-1117
-1118
-1119
-1120
-1121
-1122
-1123
-1124
-1125
-1126
-1127
-1128
-1129
-1130
-1131
-1132
-1133
-1134
-1135
-1136
-1137
-1138
-1139
-1140
-1141
-1142
-1143
-1144
-1145
-1146
-1147
-1148
-1149
-1150
-1151
-1152
-1153
-1154
-1155
-1156
-1157
-1158
-1159
-1160
-1161
-1162
-1163
-1164
-1165
-1166
-1167
-1168
-1169
-1170
-1171
-1172
-1173
-1174
-1175
-1176
-1177
-1178
-1179
-1180
-1181
-1182
-1183
-1184
-1185
-1186
-1187
-1188
-1189
-1190
-1191
-1192
-1193
-1194
-1195
-1196
-1197
-1198
-1199
-1200
-1201
-1202
-1203
-1204
-1205
-1206
-1207
-1208
-1209
-1210
-1211
-1212
-1213
-1214
-1215
-1216
-1217
-1218
-1219
-1220
-1221
-1222
-1223
-1224
-1225
-1226
-1227
-1228
-1229
-1230
-1231
-1232
-1233
-1234
-1235
-1236
-1237
-1238
-1239
-1240
-1241
-1242
-1243
-1244
-1245
-1246
-1247
-1248
-1249
-1250
-1251
-1252
-1253
-1254
-1255
-1256
-1257
-1258
-1259
-1260
-1261
-1262
-1263
-1264
-1265
-1266
-1267
-1268
-1269
-1270
-1271
-1272
-1273
-1274
-1275
-1276
-1277
-1278
-1279
-1280
-1281
-1282
-1283
-1284
-1285
-1286
-1287
-1288
-1289
-1290
-1291
-1292
-1293
-1294
-1295
-1296
-1297
-1298
-1299
-1300
-1301
-1302
-1303
-1304
-1305
-1306
-1307
-1308
-1309
-1310
-1311
-1312
-1313
-1314
-1315
-1316
-1317
-1318
-1319
-1320
-1321
-1322
-1323
-1324
-1325
-1326
-1327
#ifndef AMR_refinement_h
-#define AMR_refinement_h
-
-#include <algorithm>
-
-#include "Macro.hpp"
-#include "tet_store.hpp"
-#include "node_connectivity.hpp"
-
-// TODO: make this have a base class to support multiple generator schemes
-// using the policy design pattern
-
-#if defined(STRICT_GNUC)
-  #pragma GCC diagnostic push
-  #pragma GCC diagnostic ignored "-Wunused-but-set-variable"
-#endif
-
-namespace AMR {
-
-    class refinement_t {
-        private:
-
-            size_t DEFAULT_REFINEMENT_LEVEL = 0; //TODO: Is this in the right place?
-            size_t MIN_REFINEMENT_LEVEL = DEFAULT_REFINEMENT_LEVEL;
-            // list of "intermediate" edges to be deleted
-            std::set< edge_t > delete_list;
-
-        public:
-
-            //! Default constructor for migration
-            refinement_t() {}
-
-            //! Constructor taking a user-specified max refinement level
-            refinement_t( size_t u_mrl ) :
-              MAX_REFINEMENT_LEVEL( u_mrl ) {}
-
-            size_t MAX_REFINEMENT_LEVEL;
-
-            // TODO: Document this
-            child_id_list_t generate_child_ids( tet_store_t& tet_store, size_t parent_id, size_t count = MAX_CHILDREN)
-            {
-                //return morton_id_generator_t::get_children_ids(parent_id);
-                return tet_store.generate_child_ids(parent_id, count);
-            }
-
-            /**
-             * @brief function to detect when an invalid refinement is
-             * invoked
-             *
-             * @param tet_store Tet store to use
-             * @param tet_id Id the of the tet which will be refined
-             *
-             * @return A bool stating if the tet can be validly refined
-             */
-            bool check_allowed_refinement( tet_store_t& tet_store, size_t tet_id)
-            {
-                Refinement_State& master_element = tet_store.data(tet_id);<--- Variable 'master_element' can be declared with const
-
-                // These asserts mean we never actually try refine a 1:2 or 1:4
-                assert( master_element.refinement_case !=
-                        Refinement_Case::one_to_two);
-                assert( master_element.refinement_case !=
-                        Refinement_Case::one_to_four);
-
-                // cppcheck-suppress assertWithSideEffect
-                assert( tet_store.is_active(tet_id) );
-
-                // Check this won't take us past the max refinement level
-                if (master_element.refinement_level >= MAX_REFINEMENT_LEVEL)
-                {
-                    return false;
-                }
-
-                // If we got here, we didn't detect anything which tells us not
-                // to refine
-                return true;
-            }
-
-            /**
-             * @brief Method which takes a tet id, and deduces the other
-             * parameters needed to perform a 1:2
-             *
-             * @param tet_store Tet store to use
-             * @param node_connectivity Mesh node connectivity (graph)
-             * @param tet_id The id to refine 1:2
-             */
-            void refine_one_to_two( tet_store_t& tet_store, node_connectivity_t& node_connectivity, size_t tet_id)
-            {
-                edge_list_t edge_list = tet_store.generate_edge_keys(tet_id);
-                node_pair_t nodes = find_single_refinement_nodes(tet_store,edge_list);
-                refine_one_to_two( tet_store, node_connectivity, tet_id, nodes[0], nodes[1]);
-            }
-
-/*
-            //! @brief Method which takes a tet id, and transforms arguments
-            //!   into the form needed for the main 1:2 refinement method
-            //! @param tet_id The id to refine 1:2
-            void refine_one_to_two(
-                    size_t tet_id,
-                    std::string edge_key
-            )
-            {
-                std::vector<std::string> nodes = util::split(edge_key,KEY_DELIM);
-                size_t edge_node_A_id =  std::stoul (nodes[0],nullptr,0);
-                size_t edge_node_B_id =  std::stoul (nodes[1],nullptr,0);
-                refine_one_to_two( tet_id, edge_node_A_id, edge_node_B_id);
-            }
-*/
-            /**
-             * @brief Refine a given tet id into 2 children.
-             * NOTE: Does not do any validity checking (currently?)
-             *
-             * @param tet_store Tet store to use
-             * @param node_connectivity Mesh node connectivity (graph)
-             * @param tet_id Id of tet to refine
-             * @param edge_node_A_id The first node of id of the edge which
-             * will be split
-             * @param edge_node_B_id The second node of id of the
-             * edge which will be split
-             */
-            void refine_one_to_two(
-                    tet_store_t& tet_store,
-                    node_connectivity_t& node_connectivity,
-                    size_t tet_id,
-                    size_t edge_node_A_id,
-                    size_t edge_node_B_id
-            )
-            {
-
-                trace_out << "refine_one_to_two" << std::endl;
-                if (!check_allowed_refinement(tet_store,tet_id)) return;
-
-                tet_t original_tet = tet_store.get(tet_id);
-
-                //coordinate_t original_tet_c = node_connectivity->id_to_coordinate(id);
-
-                size_t new_node_id = node_connectivity.add( edge_node_A_id, edge_node_B_id );
-
-                /// Split existing tet into two new tets
-
-                // The two new tets will be the same, but for each an edge will
-                // be cut, losing an edge  replaced by E
-
-                tet_t new_tet1;
-                tet_t new_tet2;
-
-                // Create a new tet that is based on the original
-                copy_tet(&new_tet1, &original_tet);
-
-                // Replace all node ids in tet that were pointing to A with new_node_id
-                replace_node(&new_tet1, edge_node_A_id, new_node_id);
-
-                // Create a new tet that is based on the original
-                copy_tet(&new_tet2, &original_tet);
-
-                // Replace all node ids in tet that were pointing to B with new_node_id
-                replace_node(&new_tet2, edge_node_B_id, new_node_id);
-
-                // Now, update the edge list
-
-                // Generate edges for split
-                tet_store.edge_store.split(edge_node_A_id, edge_node_B_id, new_node_id,
-                        Edge_Lock_Case::intermediate);
-
-                child_id_list_t child_list = generate_child_ids(tet_store,tet_id, 2);
-
-                size_t first_child_id = child_list[0];
-                size_t second_child_id = child_list[1];
-
-                // Add the two new tets to the system
-                size_t new_tet_id = first_child_id;
-                tet_store.add(
-                        first_child_id,
-                        new_tet1,
-                        Refinement_Case::one_to_two,
-                        tet_id
-                );
-
-                //size_t new_tet_id2 = second_child_id;
-                tet_store.add(
-                        second_child_id,
-                        new_tet2,
-                        Refinement_Case::one_to_two,
-                        tet_id
-                );
-
-                //trace_out << "1:2 DOING REFINE OF " << tet_id << ". Adding " << child_list[0] << " and " << child_list[1] << std::endl;
-
-                // This call is only needed to add a single edge, from the new
-                // node to the node on the normal to that face, but avoids
-                // directly calculating which nodes that is
-                tet_store.generate_edges(new_tet_id);
-
-                // Currently we lock one per tet, around the split node. We
-                // also need to lock the two "arms" which come out from it
-                //lock_edges_from_node(new_tet_id, new_node_id, Edge_Lock_Case::intermediate);
-                //lock_edges_from_node(new_tet_id2, new_node_id, Edge_Lock_Case::intermediate);
-
-                // Deactivate parent tet?
-                tet_store.deactivate(tet_id);
-                //lock_edges_from_node(new_node_id, Edge_Lock_Case::intermediate);
-                trace_out << "Adding " << new_node_id << " to intermediate list " << std::endl;
-                tet_store.intermediate_list.insert(new_node_id);
-            }
-
-            /**
-             * @brief Method which takes a tet id, and deduces the other
-             * parameters needed to perform a 1:4
-             *
-             * @param tet_store Tet store to use
-             * @param node_connectivity Mesh node connectivity (graph)
-             * @param tet_id The id to refine 1:4
-            */
-            void refine_one_to_four( tet_store_t& tet_store,
-                    node_connectivity_t& node_connectivity, size_t tet_id)
-            {
-                trace_out << "do refine 1:4 " << std::endl;
-                //bool face_refine = false;
-                size_t face_refine_id = 0; // FIXME: Does this need a better default
-                face_list_t face_list = tet_store.generate_face_lists(tet_id);
-
-                // Iterate over each face
-                for (size_t face = 0; face < NUM_TET_FACES; face++)
-                {
-                    int num_face_refine_edges = 0;
-
-                    face_ids_t face_ids = face_list[face];
-                    trace_out << "face ids " <<
-                        face_ids[0] << ", " <<
-                        face_ids[1] << ", " <<
-                        face_ids[2] << ", " <<
-                        std::endl;
+
  1
+  2
+  3
+  4
+  5
+  6
+  7
+  8
+  9
+ 10
+ 11
+ 12
+ 13
+ 14
+ 15
+ 16
+ 17
+ 18
+ 19
+ 20
+ 21
+ 22
+ 23
+ 24
+ 25
+ 26
+ 27
+ 28
+ 29
+ 30
+ 31
+ 32
+ 33
+ 34
+ 35
+ 36
+ 37
+ 38
+ 39
+ 40
+ 41
+ 42
+ 43
+ 44
+ 45
+ 46
+ 47
+ 48
+ 49
+ 50
+ 51
+ 52
+ 53
+ 54
+ 55
+ 56
+ 57
+ 58
+ 59
+ 60
+ 61
+ 62
+ 63
+ 64
+ 65
+ 66
+ 67
+ 68
+ 69
+ 70
+ 71
+ 72
+ 73
+ 74
+ 75
+ 76
+ 77
+ 78
+ 79
+ 80
+ 81
+ 82
+ 83
+ 84
+ 85
+ 86
+ 87
+ 88
+ 89
+ 90
+ 91
+ 92
+ 93
+ 94
+ 95
+ 96
+ 97
+ 98
+ 99
+100
+101
+102
+103
+104
+105
+106
+107
+108
+109
+110
+111
+112
+113
+114
+115
+116
+117
+118
+119
+120
+121
+122
+123
+124
+125
+126
+127
+128
+129
+130
+131
+132
+133
+134
+135
+136
+137
+138
+139
+140
+141
+142
+143
+144
+145
+146
+147
+148
+149
+150
+151
+152
+153
+154
+155
+156
+157
+158
+159
+160
+161
+162
+163
+164
+165
+166
+167
+168
+169
+170
+171
+172
+173
+174
+175
+176
+177
+178
+179
+180
+181
+182
+183
+184
+185
+186
+187
+188
+189
+190
+191
+192
+193
+194
+195
+196
+197
+198
+199
+200
+201
+202
+203
+204
+205
+206
+207
+208
+209
+210
+211
+212
+213
+214
+215
+216
+217
+218
+219
+220
+221
+222
+223
+224
+225
+226
+227
+228
+229
+230
+231
+232
+233
+234
+235
+236
+237
+238
+239
+240
+241
+242
+243
+244
+245
+246
+247
+248
+249
+250
+251
+252
+253
+254
+255
+256
+257
+258
+259
+260
+261
// *****************************************************************************
+/*!
+  \file      src/LinearSolver/ConjugateGradients.hpp
+  \copyright 2012-2015 J. Bakosi,
+             2016-2018 Los Alamos National Security, LLC.,
+             2019-2021 Triad National Security, LLC.
+             All rights reserved. See the LICENSE file for details.
+  \brief     Charm++ chare array for distributed conjugate gradients
+  \details   Charm++ chare array for asynchronous distributed
+    conjugate gradients linear solver.
+
+    There are a potentially large number of ConjugateGradients Charm++ chares.
+    Each ConjugateGradient chare gets a chunk of the full load, due to partiting
+    the mesh, on which the solve is performed.
+
+    The implementation uses the Charm++ runtime system and is fully
+    asynchronous, overlapping computation and communication. The algorithm
+    utilizes the structured dagger (SDAG) Charm++ functionality.
+*/
+// *****************************************************************************
+#ifndef ConjugateGradients_h
+#define ConjugateGradients_h
+
+#include "Types.hpp"
+#include "CSR.hpp"
+
+#include "NoWarning/conjugategradients.decl.h"
+
+namespace tk {
+
+//! \brief ConjugateGradients Charm++ chare array used to perform a distributed
+//!   linear solve with the conjugate gradients algorithm
+class ConjugateGradients : public CBase_ConjugateGradients {
+
+  public:
+    #if defined(__clang__)
+      #pragma clang diagnostic push
+      #pragma clang diagnostic ignored "-Wunused-parameter"
+    #elif defined(STRICT_GNUC)
+      #pragma GCC diagnostic push
+      #pragma GCC diagnostic ignored "-Wunused-parameter"
+    #endif
+    // Include Charm++ SDAG code. See http://charm.cs.illinois.edu/manuals/html/
+    // charm++/manual.html, Sec. "Structured Control Flow: Structured Dagger".
+    ConjugateGradients_SDAG_CODE
+    #if defined(__clang__)
+      #pragma clang diagnostic pop
+    #elif defined(STRICT_GNUC)
+      #pragma GCC diagnostic pop
+    #endif
+
+    //! Constructor
+    explicit ConjugateGradients(
+      const CSR& A,
+      const std::vector< tk::real >& x,
+      const std::vector< tk::real >& b,
+      const std::vector< std::size_t >& gid,
+      const std::unordered_map< std::size_t, std::size_t >& lid,
+      const NodeCommMap& nodecommmap );
+
+    #if defined(__clang__)
+      #pragma clang diagnostic push
+      #pragma clang diagnostic ignored "-Wundefined-func-template"
+    #endif
+    //! Constructor taking a tuple of {A,x,b} by rvalue reference
+    explicit ConjugateGradients(<--- Member variable 'ConjugateGradients::m_tol' is not initialized in the constructor.
+      std::tuple< tk::CSR,
+                  std::vector< tk::real >,
+                  std::vector< tk::real > >&& system,
+      const std::vector< std::size_t >& gid,
+      const std::unordered_map< std::size_t, std::size_t >& lid,
+      const NodeCommMap& nodecommmap ) :
+      ConjugateGradients( std::move(std::get<0>(system)),
+                          std::move(std::get<1>(system)),
+                          std::move(std::get<2>(system)),
+                          gid, lid, nodecommmap ) {}
+
+    //! Migrate constructor
+    explicit ConjugateGradients( CkMigrateMessage* ) {}<--- Member variable 'ConjugateGradients::m_nr' is not initialized in the constructor.<--- Member variable 'ConjugateGradients::m_nb' is not initialized in the constructor.<--- Member variable 'ConjugateGradients::m_nq' is not initialized in the constructor.<--- Member variable 'ConjugateGradients::m_normb' is not initialized in the constructor.<--- Member variable 'ConjugateGradients::m_it' is not initialized in the constructor.<--- Member variable 'ConjugateGradients::m_maxit' is not initialized in the constructor.<--- Member variable 'ConjugateGradients::m_tol' is not initialized in the constructor.<--- Member variable 'ConjugateGradients::m_rho' is not initialized in the constructor.<--- Member variable 'ConjugateGradients::m_rho0' is not initialized in the constructor.<--- Member variable 'ConjugateGradients::m_alpha' is not initialized in the constructor.<--- Member variable 'ConjugateGradients::m_converged' is not initialized in the constructor.<--- Member variable 'ConjugateGradients::m_nx' is not initialized in the constructor.
+    #if defined(__clang__)
+      #pragma clang diagnostic pop
+    #endif
+
+    //! Solve linear system
+    void solve( std::size_t maxit, tk::real tol, CkCallback c );
+
+    //! Initialize linear solve: set initial guess and boundary conditions
+    void init( const std::vector< tk::real >& x,
+               const std::vector< tk::real >& b,
+               const std::unordered_map< std::size_t,
+                       std::vector< std::pair< bool, tk::real > > >& bc,
+               std::size_t ignorebc,
+               CkCallback cb );
+
+    //! Setup solver
+    void setup( CkCallback c );
+
+    //! Compute the norm of the right hand side
+    void normb( tk::real n );
+
+    //! Compute rho = (r,r)
+    void rho( tk::real r );
+
+    //! Receive contributions to r = b - A * x on chare-boundaries
+    void comres( const std::vector< std::size_t >& gid,
+                 const std::vector< std::vector< tk::real > >& rc );
+
+    //! Receive contributions to boundary conditions on chare-boundaries
+    void combc( const std::unordered_map< std::size_t,
+                       std::vector< std::pair< bool, tk::real > > >& bc );
+
+    //! Receive contributions to q = A * p on chare-boundaries
+    void comq( const std::vector< std::size_t >& gid,
+               const std::vector< std::vector< tk::real > >& qc );
+
+    void comx( const std::vector< std::size_t >& gid,
+               const std::vector< std::vector< tk::real > >& xc );
+
+    //! Compute the dot product (p,q)
+    void pq( tk::real d );
+
+    //! Compute the norm of the residual: (r,r)
+    void normres( tk::real r );
+
+    //! Access solution
+    std::vector< tk::real > solution() const { return m_x; }
+
+    //! Return convergence flag
+    bool converged() const { return m_converged; }
+
+    /** @name Pack/unpack (Charm++ serialization) routines */
+    ///@{
+    //! \brief Pack/Unpack serialize member function
+    //! \param[in,out] p Charm++'s PUP::er serializer object reference
+    void pup( PUP::er &p ) override {
+      p | m_A;
+      p | m_x;
+      p | m_b;
+      p | m_gid;
+      p | m_lid;
+      p | m_nodeCommMap;
+      p | m_r;
+      p | m_rc;
+      p | m_nr;
+      p | m_bc;
+      p | m_bcc;
+      p | m_bcmask;
+      p | m_nb;
+      p | m_p;
+      p | m_q;
+      p | m_qc;
+      p | m_nq;
+      p | m_initres;
+      p | m_solved;
+      p | m_normb;
+      p | m_it;
+      p | m_maxit;
+      p | m_tol;
+      p | m_rho;
+      p | m_rho0;
+      p | m_alpha;
+      p | m_converged;
+      p | m_xc;
+      p | m_nx;
+    }
+    //! \brief Pack/Unpack serialize operator|
+    //! \param[in,out] p Charm++'s PUP::er serializer object reference
+    //! \param[in,out] c ConjugateGradients object reference
+    friend void operator|( PUP::er& p, ConjugateGradients& c ) { c.pup(p); }
+    ///@}
+
+  private:
+    //! Sparse matrix
+    CSR m_A;
+    //! Solution/unknown
+    std::vector< tk::real > m_x;
+    //! Right hand side
+    std::vector< tk::real > m_b;
+    //! Global node IDs
+    std::vector< std::size_t > m_gid;
+    //! Local node IDs associated to global ones
+    std::unordered_map< std::size_t, std::size_t > m_lid;
+    //! Global mesh node IDs shared with other chares associated to chare IDs
+    NodeCommMap m_nodeCommMap;
+    //! Auxiliary vector for CG solve
+    std::vector< tk::real > m_r;
+    //! Receive buffer for communication of r = b - A * x
+    std::unordered_map< std::size_t, std::vector< tk::real > > m_rc;
+    //! Counter for assembling m_r
+    std::size_t m_nr;
+    //! Dirichlet boundary conditions
+    std::unordered_map< std::size_t,
+        std::vector< std::pair< bool, tk::real > > > m_bc;
+    //! Dirichlet boundary conditions communication buffer
+    std::unordered_map< std::size_t,
+        std::vector< std::pair< bool, tk::real > > > m_bcc;
+    //! Dirichlet boundary condition mask
+    std::vector< tk::real > m_bcmask;
+    //! Counter for assembling boundary conditions
+    std::size_t m_nb;
+    //! Auxiliary vector for CG solve
+    std::vector< tk::real > m_p;
+    //! Auxiliary vector for CG solve
+    std::vector< tk::real > m_q;
+    //! Receive buffer for communication of q = A * p
+    std::unordered_map< std::size_t, std::vector< tk::real > > m_qc;
+    //! Counter for assembling m_q
+    std::size_t m_nq;
+    //! Charm++ callback to continue with when the setup is complete
+    CkCallback m_initres;
+    //! Charm++ callback to continue with when the solve is complete
+    CkCallback m_solved;
+    //! L2 norm of the right hand side
+    tk::real m_normb;
+    //! Iteration count
+    std::size_t m_it;
+    //! Max iteration count
+    std::size_t m_maxit;
+    //! Stop tolerance
+    tk::real m_tol;
+    //! Helper scalar for CG algorithm
+    tk::real m_rho;
+    //! Helper scalar for CG algorithm
+    tk::real m_rho0;
+    //! Helper scalar for CG algorithm
+    tk::real m_alpha;
+    //! Convergence flag: true if linear smoother converged to tolerance
+    bool m_converged;
+    //! Receive buffer for solution
+    std::unordered_map< std::size_t, std::vector< tk::real > > m_xc;
+    //! Counter for assembling the solution on chare boundaries
+    std::size_t m_nx;
 
-                    edge_list_t face_edge_list = AMR::edge_store_t::generate_keys_from_face_ids(face_ids);
-                    // For this face list, see which ones need refining
-                    trace_out << "Looping to " << NUM_FACE_NODES << std::endl;
-                    for (size_t k = 0; k < NUM_FACE_NODES; k++)
-                    {
-                        trace_out << "nodes " << k << std::endl;
-
-                        edge_t edge = face_edge_list[k];
-                        if (tet_store.edge_store.get(edge).needs_refining == 1)
-                        {
-                            num_face_refine_edges++;
-                            trace_out << "Ref " << edge << " Num face => " << num_face_refine_edges << std::endl;
-                        }
-
-                        // Check for locked edges
-                            // This case only cares about faces with no locks
-                        if (tet_store.edge_store.lock_case(edge) != Edge_Lock_Case::unlocked)
-                        {
-                            // Abort this face
-                            trace_out << "Face has lock it's not this one " << face << std::endl;
-                            num_face_refine_edges = 0;
-                            break;
-                        }
-                        trace_out << "Num face => " << num_face_refine_edges << std::endl;
-                    }
-                    if (num_face_refine_edges >= 2)
-                    {
-                        assert(num_face_refine_edges < 4);
-                        //face_refine = true;
-                        trace_out << "Accepting face " << face << std::endl;
-                        face_refine_id = face;
-                        break;
-                    }
-                }
-
-                tet_t tet = tet_store.get(tet_id);
-                size_t opposite_offset = AMR::node_connectivity_t::face_list_opposite(face_list, face_refine_id);
-                size_t opposite_id = tet[opposite_offset];
-
-                trace_out << "1:4 tet mark id " << tet_id << std::endl;
-                trace_out << "opposite offset " << opposite_offset << std::endl;
-                trace_out << "opposite id " << opposite_id << std::endl;
-                trace_out << "face refine id " << face_refine_id << std::endl;
-                trace_out << "face list 0 " << face_list[face_refine_id][0] << std::endl;
-                trace_out << "face list 1 " << face_list[face_refine_id][1] << std::endl;
-                trace_out << "face list 2 " << face_list[face_refine_id][2] << std::endl;
-
-                refine_one_to_four(tet_store, node_connectivity, tet_id, face_list[face_refine_id], opposite_id);
-            }
-
-            /**
-             * @brief Method which takes a tet id, and deduces the other
-             * parameters needed to perform a 1:4, as a part of an 8:4 deref
-             *
-             * @param tet_store Tet store to use
-             * @param node_connectivity Mesh node connectivity (graph)
-             * @param tet_id The id to refine 1:4
-             * @param kept_edges Vector of edges to keep after deref-ref
-            */
-            void deref_refine_one_to_four( tet_store_t& tet_store,
-                    node_connectivity_t& node_connectivity, size_t tet_id,
-                    std::vector< edge_t >& kept_edges)
-            {
-                trace_out << "do refine 1:4 " << std::endl;
-                //bool face_refine = false;
-                size_t face_refine_id = 0; // FIXME: Does this need a better default
-                face_list_t face_list = tet_store.generate_face_lists(tet_id);
-
-                // Iterate over each face
-                for (size_t face = 0; face < NUM_TET_FACES; face++)
-                {
-                    int num_face_refine_edges = 0;
-
-                    face_ids_t face_ids = face_list[face];
-                    trace_out << "face ids " <<
-                        face_ids[0] << ", " <<
-                        face_ids[1] << ", " <<
-                        face_ids[2] << ", " <<
-                        std::endl;
-
-                    edge_list_t face_edge_list = AMR::edge_store_t::generate_keys_from_face_ids(face_ids);
-                    // For this face list, see which ones need refining
-                    trace_out << "Looping to " << NUM_FACE_NODES << std::endl;
-                    for (size_t k = 0; k < NUM_FACE_NODES; k++)
-                    {
-                        edge_t edge = face_edge_list[k];
-                        trace_out << "edge-nodes " << edge.get_data()[0] << "-"
-                          << edge.get_data()[1] << std::endl;
-
-                        if (tet_store.edge_store.get(edge).needs_refining == 2)
-                        {
-                            num_face_refine_edges++;
-                            trace_out << "Ref " << edge << " Num face => " << num_face_refine_edges << std::endl;
-                        }
-
-                        // Check for locked edges
-                            // This case only cares about faces with no locks
-                        if (tet_store.edge_store.lock_case(edge) != Edge_Lock_Case::unlocked)
-                        {
-                            // Abort this face
-                            trace_out << "Face has lock it's not this one " << face << std::endl;
-                            num_face_refine_edges = 0;
-                            break;
-                        }
-                        trace_out << "Num face => " << num_face_refine_edges << std::endl;
-                    }
-                    if (num_face_refine_edges >= 2)
-                    {
-                        assert(num_face_refine_edges < 4);
-                        //face_refine = true;
-                        trace_out << "Accepting face " << face << std::endl;
-                        face_refine_id = face;
-                        break;
-                    }
-                }
-
-                tet_t tet = tet_store.get(tet_id);
-                size_t opposite_offset = AMR::node_connectivity_t::face_list_opposite(face_list, face_refine_id);
-                size_t opposite_id = tet[opposite_offset];
-
-                trace_out << "1:4 tet mark id " << tet_id << std::endl;
-                trace_out << "opposite offset " << opposite_offset << std::endl;
-                trace_out << "opposite id " << opposite_id << std::endl;
-                trace_out << "face refine id " << face_refine_id << std::endl;
-                trace_out << "face list 0 " << face_list[face_refine_id][0] << std::endl;
-                trace_out << "face list 1 " << face_list[face_refine_id][1] << std::endl;
-                trace_out << "face list 2 " << face_list[face_refine_id][2] << std::endl;
-
-                // store edges that should not be removed due to the deref-ref
-                auto kept_edge_list = AMR::edge_store_t::
-                  generate_keys_from_face_ids(face_list[face_refine_id]);
-                for (size_t i=0; i<3; ++i) {
-                  kept_edges.push_back(kept_edge_list[i]);
-                }
-
-                refine_one_to_four(tet_store, node_connectivity, tet_id, face_list[face_refine_id], opposite_id);
-            }
-
-            /**
-             * @brief Refine a given tet id into 4 children.
-             * NOTE: Does not do any validity checking (currently?)
-             *
-             * @param tet_store Tet store to use
-             * @param node_connectivity Mesh node connectivity (graph)
-             * @param tet_id The id of the tet to refine
-             * @param face_ids The ids which make the face to be split
-             * @param opposite_id The remaining id which is "opposite" the
-             * split face
-             */
-            void refine_one_to_four(
-                    tet_store_t& tet_store,
-                    node_connectivity_t& node_connectivity,
-                    size_t tet_id,
-                    std::array<size_t, NUM_FACE_NODES> face_ids,
-                    size_t opposite_id
-            )
-            {
-
-                trace_out << "refine_one_to_four" << std::endl;
-                if (!check_allowed_refinement(tet_store,tet_id)) return;
-
-                trace_out << "Refining tet_id " << tet_id <<
-                    " 1:4 opposite edge " << opposite_id << std::endl;
-
-                tet_t t = tet_store.get(tet_id);
-                trace_out  << "Tet has nodes " <<
-                    t[0] << ", " <<
-                    t[1] << ", " <<
-                    t[2] << ", " <<
-                    t[3] << ", " <<
-                    std::endl;
-
-                trace_out << "face_ids " <<
-                    face_ids[0] << ", " <<
-                    face_ids[1] << ", " <<
-                    face_ids[2] << ", " <<
-                    std::endl;
-
-                size_t A = face_ids[0];
-                size_t B = face_ids[1];
-                size_t C = face_ids[2];
-                size_t D = opposite_id;
-
-                trace_out <<
-                    " A " << A <<
-                    " B " << B <<
-                    " C " << C <<
-                    " D " << D <<
-                    std::endl;
-
-                // Make new nodes
-                //coordinate_t AB_mid = node_connectivity->find_mid_point(A, B);
-                size_t AB = node_connectivity.add(A,B);
-
-                //coordinate_t AC_mid = node_connectivity->find_mid_point(A, C);
-                size_t AC = node_connectivity.add(A,C);
-
-                //coordinate_t BC_mid = node_connectivity->find_mid_point(B, C);
-                size_t BC = node_connectivity.add(B,C);
-
-                // Use nodes to update edges
-                // All added edges will be locked due to containing intermediate points
-                // Split Outer face  edges
-                tet_store.edge_store.split(A, C, AC, Edge_Lock_Case::intermediate);
-                tet_store.edge_store.split(A, B, AB, Edge_Lock_Case::intermediate);
-                tet_store.edge_store.split(B, C, BC, Edge_Lock_Case::intermediate);
-
-                // Connect D to intermediate points
-                tet_store.edge_store.generate(D, AC, Edge_Lock_Case::intermediate);
-                tet_store.edge_store.generate(D, BC, Edge_Lock_Case::intermediate);
-                tet_store.edge_store.generate(D, AB, Edge_Lock_Case::intermediate);
-                // Connect inner edges
-                tet_store.edge_store.generate(AC, BC, Edge_Lock_Case::intermediate);
-                tet_store.edge_store.generate(AC, AB, Edge_Lock_Case::intermediate);
-                tet_store.edge_store.generate(AB, BC, Edge_Lock_Case::intermediate);
-
-                // Make new Tets
-                //  This is just the node opposite the face plus each pair
-                //  of the news nodes, and the old corner
-                //  FIXME: How to find that near corner programatically?
-
-                // Hard coded solution
-                // A AC AB D
-                // AC AB BC D
-                // AC BC C D
-                // AB B BC D
-
-                size_t num_children = 4;
-                child_id_list_t child = generate_child_ids(tet_store,tet_id, num_children);
-
-                // Outsides
-                tet_store.add(child[0], {{A,  AB, AC, D}}, Refinement_Case::one_to_four, tet_id);
-                tet_store.add(child[2], {{AC, BC, C,  D}}, Refinement_Case::one_to_four, tet_id);
-                tet_store.add(child[3], {{AB, B,  BC, D}}, Refinement_Case::one_to_four, tet_id);
-
-                // Center
-                size_t center_id = child[1]; // 1 to preserve Jacobian order
-                tet_store.add(center_id, {{AC, AB, BC, D}}, Refinement_Case::one_to_four, tet_id);
-
-
-                // TODO: replace this with a more concise way to lock the correct edges
-
-                tet_store.add_center(center_id);
-                /*
-                lock_edges_from_node(child[0], AB, Edge_Lock_Case::intermediate);
-                lock_edges_from_node(child[0], AC, Edge_Lock_Case::intermediate);
-                lock_edges_from_node(child[2], AC, Edge_Lock_Case::intermediate);
-                lock_edges_from_node(child[2], BC, Edge_Lock_Case::intermediate);
-                lock_edges_from_node(child[3], AB, Edge_Lock_Case::intermediate);
-                lock_edges_from_node(child[3], BC, Edge_Lock_Case::intermediate);
-                lock_edges_from_node(center_id, AC, Edge_Lock_Case::intermediate);
-                lock_edges_from_node(center_id, AB, Edge_Lock_Case::intermediate);
-                lock_edges_from_node(center_id, BC, Edge_Lock_Case::intermediate);
-                */
-
-
-                tet_store.deactivate(tet_id);
-
-                //trace_out << "1:4 DOING REFINE OF " << tet_id << ". Adding "
-                    // << child[0] << ", "
-                    // << child[1] << ", "
-                    // << child[2] << ", "
-                    // << child[3]
-                    // << std::endl;
-
-                /*
-                lock_edges_from_node(AB, Edge_Lock_Case::intermediate);
-                lock_edges_from_node(AC, Edge_Lock_Case::intermediate);
-                lock_edges_from_node(BC, Edge_Lock_Case::intermediate);
-                */
-
-                trace_out << "Adding " << AB << " to intermediate list " << std::endl;
-                tet_store.intermediate_list.insert(AB);
-                trace_out << "Adding " << AC << " to intermediate list " << std::endl;
-                tet_store.intermediate_list.insert(AC);
-                trace_out << "Adding " << BC << " to intermediate list " << std::endl;
-                tet_store.intermediate_list.insert(BC);
-
-            }
-
-            /**
-             * @brief Refine a given tet id into 8 children.
-             * NOTE: Does not do any validity checking (currently?)
-             *
-             * @param tet_store Tet store to use
-             * @param node_connectivity Mesh node connectivity (graph)
-             * @param tet_id Id of tet to refine
-             */
-            void refine_one_to_eight( tet_store_t& tet_store,
-                    node_connectivity_t& node_connectivity, size_t tet_id)
-            {
-
-                trace_out << "refine_one_to_eight" << std::endl;
-                if (!check_allowed_refinement(tet_store,tet_id)) return;
-
-                // Split every edge into two
-                // Makes 4 tets out of the old corners and 3 near mid-points
-                // Make 4 out of the midpoints
-
-                // For Tet {ABCD} need to know all (non-repeating) node pairs
-                // {AB} {AC} {AD} {BC} {BD} {CD}
-                // This can either be hard coded, or generated with a 2d loop
-                // The loop would just be i=0..4, j=i..4
-                //
-
-
-                tet_t tet = tet_store.get(tet_id);
-
-                size_t A = tet[0];
-                size_t B = tet[1];
-                size_t C = tet[2];
-                size_t D = tet[3];
-
-                trace_out << "A " << A << " B " << B << " C " << C << " D " << D
-                    << std::endl;
-
-                // Generate pairs of nodes (i.e edges)
-                // Hard coding for now, can swap out for loop
-                //coordinate_t AB_mid = node_connectivity->find_mid_point(A,B);
-                size_t AB = node_connectivity.add(A,B);
-
-                //coordinate_t AC_mid = node_connectivity->find_mid_point(A,C);
-                size_t AC = node_connectivity.add(A,C);
-
-                //coordinate_t AD_mid = node_connectivity->find_mid_point(A,D);
-                size_t AD = node_connectivity.add(A,D);
-
-                //coordinate_t BC_mid = node_connectivity->find_mid_point(B,C);
-                size_t BC = node_connectivity.add(B,C);
-
-                //coordinate_t BD_mid = node_connectivity->find_mid_point(B,D);
-                size_t BD = node_connectivity.add(B,D);
-
-                //coordinate_t CD_mid = node_connectivity->find_mid_point(C,D);
-                size_t CD = node_connectivity.add(C,D);
-
-                // Update edges
-
-                tet_store.edge_store.split(A, C, AC, Edge_Lock_Case::unlocked);
-                tet_store.edge_store.split(A, B, AB, Edge_Lock_Case::unlocked);
-                tet_store.edge_store.split(A, D, AD, Edge_Lock_Case::unlocked);
-                tet_store.edge_store.split(B, C, BC, Edge_Lock_Case::unlocked);
-                tet_store.edge_store.split(B, D, BD, Edge_Lock_Case::unlocked);
-                tet_store.edge_store.split(C, D, CD, Edge_Lock_Case::unlocked);
-
-
-                // Outside edges for face ABC
-                tet_store.edge_store.generate(AC, BC, Edge_Lock_Case::unlocked);
-                tet_store.edge_store.generate(AC, AB, Edge_Lock_Case::unlocked);
-                tet_store.edge_store.generate(AB, BC, Edge_Lock_Case::unlocked);
-
-                // Outside edges for face ACD
-           	tet_store.edge_store.generate(AC, AD, Edge_Lock_Case::unlocked);
-                tet_store.edge_store.generate(AD, CD, Edge_Lock_Case::unlocked);
-                tet_store.edge_store.generate(AC, CD, Edge_Lock_Case::unlocked);
-
-                // Outside edges for face BCD
-                tet_store.edge_store.generate(BD, CD, Edge_Lock_Case::unlocked);
-                tet_store.edge_store.generate(BD, BC, Edge_Lock_Case::unlocked);
-                tet_store.edge_store.generate(CD, BC, Edge_Lock_Case::unlocked);
-
-                // Outside edges for face ABD
-                 tet_store.edge_store.generate(AD, BD, Edge_Lock_Case::unlocked);
-                tet_store.edge_store.generate(AB, AD, Edge_Lock_Case::unlocked);
-                tet_store.edge_store.generate(AB, BD, Edge_Lock_Case::unlocked);
-
-                // Interior Edges
-                   tet_store.edge_store.generate(AC, BD, Edge_Lock_Case::unlocked);
-                tet_store.edge_store.generate(CD, AD, Edge_Lock_Case::unlocked);
-
-                // Add the new tets
-                //
-                // External
-                // A AB AC AD - A
-                // B BA BC BD - B
-                // C CA CB CD - C
-                // D DA DB DC - D
-                // -
-                // Internal (for a face BDC, it's the intermediate and mid opposite)
-                // BC CD DB AC - BDC
-                // AB BD AD AC - ABD
-                // AB AC BC BD - ABC
-                // AC AD CD BD - ACD
-                //
-
-                // TODO: This is actually generating IDs not trying to get them
-                child_id_list_t child = generate_child_ids(tet_store,tet_id);
-
-                // This order should give a positive Jacobian
-                tet_store.add(child[0], {{A, AB, AC, AD}}, Refinement_Case::one_to_eight, tet_id);
-                tet_store.add(child[1], {{B, BC, AB, BD}}, Refinement_Case::one_to_eight, tet_id);
-                tet_store.add(child[2], {{C, AC, BC, CD}}, Refinement_Case::one_to_eight, tet_id);
-                tet_store.add(child[3], {{D, AD, CD, BD}}, Refinement_Case::one_to_eight, tet_id);
-
-                tet_store.add(child[4], {{BC, CD, AC, BD}}, Refinement_Case::one_to_eight, tet_id);
-                tet_store.add(child[5], {{AB, BD, AC, AD}}, Refinement_Case::one_to_eight, tet_id);
-                tet_store.add(child[6], {{AB, BC, AC, BD}}, Refinement_Case::one_to_eight, tet_id);
-                tet_store.add(child[7], {{AC, BD, CD, AD}}, Refinement_Case::one_to_eight, tet_id);
-
-                tet_store.deactivate(tet_id);
-
-                //trace_out << "1:8 DOING REFINE OF " << tet_id << ". "
-                    // << child[0] << ", "
-                    // << child[1] << ", "
-                    // << child[2] << ", "
-                    // << child[3] << ", "
-                    // << child[4] << ", "
-                    // << child[5] << ", "
-                    // << child[6] << ", "
-                    // << child[7]
-                    // << std::endl;
-
-            }
-
-            // This is just a simple assignment, but I wanted to abstract it
-            // for if we change the underlying type to something which a simple
-            // assignment is no longer safe
-            /**
-             * @brief Function to duplicate (deep copy) a tet. Useful for when
-             * you want to make a tet that's very similar to an existing one
-             *
-             * @param out The tet to store the copy
-             * @param original The tet to copy the data from
-             */
-            void copy_tet(tet_t* out, tet_t* original)
-            {
-                // NOTE: This will do a deep copy, so is safer than it may look
-                *out = *original;
-            }
-
-            // This is just a std::replace, but may need to be more complicated
-            // in the future?
-            /**
-             * @brief function to take an existing list of tet ids and
-             * replace one. This can be useful for when you want to build very
-             * similar tets which share nodes
-             *
-             * @param tet Tet to perform operation on
-             * @param remove Element to be replaced
-             * @param add Element to replace with
-             */
-            void replace_node(tet_t* tet, size_t remove, size_t add)
-            {
-                std::replace(tet->begin(), tet->end(), remove, add);
-            }
-
-            /**
-             * @brief Function to find out slot in the x,y,z data arrays a tet lives
-             *
-             * // NOTE: this is _currently_ trivial, but will be nice if we for
-             * example swap data stores to a map
-             *
-             * @param tet_store Tet store to use
-             * @param tet tet of the tet to look for
-             * @param element offset into that tet to look at
-             *
-             * @return tet into data arrays the tet lives
-             */
-            // TODO: Move this (or rename?)
-            size_t tet_id_to_node_id( tet_store_t& tet_store, size_t tet, size_t element) {
-                return tet_store.get(tet)[element];
-            }
-
-            /**
-             * @brief Function to find the nodes which make up the
-             * single (or first?º edge which needs to be refined in an given
-             * edge_list
-             *
-             * @param tet_store Tet store to use
-             * @param edge_list The edge list to search for a refinement edge
-             *
-             * @return The node pair which represent the edge which needs
-             * refining
-             */
-            node_pair_t find_single_refinement_nodes( tet_store_t& tet_store, edge_list_t edge_list)
-            {
-                node_pair_t returned_nodes;
-                bool found_break = false;
-                for (size_t k = 0; k < NUM_TET_EDGES; k++)
-                {
-                    edge_t edge = edge_list[k];
-
-                    if (tet_store.edge_store.get(edge).needs_refining == 1)
-                    {
-                        returned_nodes[0] = edge.first();
-                        returned_nodes[1] = edge.second();
-
-                        trace_out << "1:2 needs to be split on " <<
-                            returned_nodes[0] << " and " <<
-                            returned_nodes[1] << std::endl;
-
-                        found_break = true;
-                        break;
-                    }
-                }
-
-                assert(found_break);
-
-                return returned_nodes;
-            }
-
-            void lock_intermediates(
-                    tet_store_t& tet_store,
-                    const std::unordered_set<size_t>& intermediate_list,
-                    Edge_Lock_Case lock_case
-                )
-            {
-                // Loop over all edges
-                // If the edge is in the intermediate_list, deal with it
-                for (const auto& p : tet_store.edge_store.edges)
-                {
-                    auto e = p.first;
-                    size_t k1 = e.first();
-                    size_t k2 = e.second();
-                    // Can we make this double search cheaper?
-                    if (
-                            (intermediate_list.count(k1)) ||
-                            (intermediate_list.count(k2))
-                       )
-                    {
-                        trace_out << "Locking intermediate " << e << " from " << k1 << " and " << k2 << std::endl;
-                        tet_store.edge_store.get(e).lock_case = lock_case;
-                        tet_store.edge_store.get(e).needs_refining = 0;
-                    }
-                }
-
-            }
-
-            // TODO: remove this, it's horrible and not efficient.
-            // WARNING: THIS GOES OVER ALL TETS!!!!
-            void lock_edges_from_node(
-                    tet_store_t& tet_store,
-                    size_t node_id,
-                    Edge_Lock_Case lock_case
-            )
-            {
-                // Iterate over edges of ALL tet
-                for (const auto& kv : tet_store.tets)
-                {
-                    size_t tet_id = kv.first;
-                    edge_list_t edge_list = tet_store.generate_edge_keys(tet_id);
-                    for (size_t k = 0; k < NUM_TET_EDGES; k++)
-                    {
-                        // If it contains that node id, mark it using lock_case
-                        edge_t edge = edge_list[k];
-
-                        size_t edge_node_A_id = edge.first();
-                        size_t edge_node_B_id = edge.second();
-
-                        if ((edge_node_A_id == node_id) || (edge_node_B_id == node_id)) {
-                            trace_out << " found node in " << edge_node_A_id << " - " << edge_node_B_id << " set to " << lock_case << std::endl;
-                            tet_store.edge_store.get(edge).lock_case = lock_case;
-                            tet_store.edge_store.get(edge).needs_refining = 0;
-                        }
-                    }
-                }
-            }
-//            void lock_edges_from_node(
-//                    tet_store_t& tet_store,
-//                    size_t tet_id,
-//                    size_t node_id,
-//                    Edge_Lock_Case lock_case
-//            )
-//            {
-//                // Iterate over edges of of tet
-//                edge_list_t edge_list = tet_store.generate_edge_keys(tet_id);
-//                for (size_t k = 0; k < NUM_TET_EDGES; k++)
-//                {
-//                    // If it contains that node id, mark it using lock_case
-//                    edge_t edge = edge_list[k];
-//
-//                    size_t edge_node_A_id = edge.first();
-//                    size_t edge_node_B_id = edge.second();
-//
-//                    if ((edge_node_A_id == node_id) || (edge_node_B_id == node_id)) {
-//                        tet_store.edge_store.get(edge).lock_case = lock_case;
-//                    }
-//                }
-//            }
-
-
-            ///// DEREFINEMENT STARTS HERE /////
-            /**
-             * @brief Function to iterate over children and remove them
-             *
-             * @param tet_store Tet store to use
-             * @param parent_id Id of the parent for whom you will delete the
-             * children
-             */
-            void derefine_children(tet_store_t& tet_store, size_t parent_id)
-            {
-                // For a given tet_id, find and delete its children
-                Refinement_State& parent = tet_store.data(parent_id);
-                for (auto c : parent.children)
-                {
-                    tet_store.erase(c);
-                    //tet_store.deactivate(c);
-
-                    /*
-                    auto children = tet_store.data(c).children;
-                    // Debug printing
-                    std::cout << "tet " << c << "has ";
-                    for (auto child : children)
-                    {
-                        std::cout << " _child " << child;
-                    }
-                    std::cout << std::endl;
-                    */
-                }
-                parent.children.clear();
-            }
-
-            /**
-             * @brief Common code for derefinement. Deactives the children and
-             * actives the parent
-             *
-             * @param tet_store Tet store to use
-             * @param parent_id The id of the parent
-             */
-            void generic_derefine(tet_store_t& tet_store, size_t parent_id)
-            {
-                derefine_children(tet_store,parent_id);
-                tet_store.activate(parent_id);
-            }
-
-            /**
-             * @brief Perform 2->1 derefinement on tet
-             *
-             * @param tet_store Tet store to use
-             * @param parent_id The id of the parent
-             */
-            void derefine_two_to_one(tet_store_t& tet_store, node_connectivity_t&, size_t parent_id)
-            {
-                //if (!check_allowed_derefinement(tet_store,parent_id)) return;
-                // build a delete-list of edges/intermediates first, mesh_adapter
-                // deletes edges from this list later
-                determine_deletelist_of_intermediates(tet_store, parent_id);
-                generic_derefine(tet_store,parent_id);
-            }
-
-            /**
-             * @brief Perform 4->1 derefinement on tet
-             *
-             * @param tet_store Tet store to use
-             * @param parent_id The id of the parent
-             */
-            void derefine_four_to_one(tet_store_t& tet_store, node_connectivity_t&, size_t parent_id)
-            {
-                //if (!check_allowed_derefinement(tet_store,parent_id)) return;
-                // build a delete-list of edges/intermediates first, mesh_adapter
-                // deletes edges from this list later
-                determine_deletelist_of_intermediates(tet_store, parent_id);
-                generic_derefine(tet_store,parent_id);
-            }
-
-            /**
-             * @brief Perform 8->1 derefinement on tet
-             *
-             * @param tet_store Tet store to use
-             * @param parent_id The id of the parent
-             */
-            void derefine_eight_to_one(tet_store_t& tet_store, node_connectivity_t&, size_t parent_id)
-            {
-                //if (!check_allowed_derefinement(tet_store,parent_id)) return;
-
-                generic_derefine(tet_store,parent_id);
-
-                // TODO: Do we delete the nodes? Do we even have nodes?
-
-                // Delete the center edges
-                    // If edge isn't in the parent, delete it? Is there a better way?
-                edge_list_t parent_edges = tet_store.generate_edge_keys(parent_id);
-
-                Refinement_State& parent = tet_store.data(parent_id);<--- Variable 'parent' can be declared with const
-                for (auto c : parent.children)
-                {
-                    edge_list_t child_edges = tet_store.generate_edge_keys(c);
-                    // build a delete-list of non-matching edges first, then
-                    // mesh_adapter deletes edges from this list later
-                    determine_deletelist_of_non_matching_edges(child_edges, parent_edges);
-                }
-            }
-
-            // TODO: Document This.
-            void derefine_four_to_two(tet_store_t& tet_store, node_connectivity_t& node_connectivity, size_t parent_id)
-            {
-                //if (!check_allowed_derefinement(tet_store,parent_id)) return;
-
-                // A 4:2 (implemented as a 4:1 + 1:2) keeps three child edges,
-                // two of which are from the 1:2 splitting. The third edge
-                // connects the opposite parent node with the intermediate node
-                // (of the 1:2 splitting). Figure out which is this edge, and
-                // remove it from the delete list.
-                // 1. first store the possible edges that connect parent nodes
-                //    with the intermediate node of the 1:2. There are 2
-                //    possibilities, because we can already eliminate the
-                //    parents of the intermediate node.
-                auto edge = find_edge_not_derefined(tet_store,
-                  node_connectivity, parent_id);
-
-                std::array< edge_t, 2 > int_par_edges;
-                auto parent_tet = tet_store.get(parent_id);
-                auto npnode = node_connectivity.data().at(edge.get_data());
-                size_t icount(0);
-                for (size_t i=0; i<NUM_TET_NODES; ++i) {
-                  if (parent_tet[i] != edge.first() &&
-                    parent_tet[i] != edge.second()) {
-                    int_par_edges[icount] = edge_t(parent_tet[i], npnode);
-                    ++icount;
-                  }
-                }
-                assert(icount == 2);
-
-                // 2. find which one of these edges is present in the 4 children
-                child_id_list_t children = tet_store.data(parent_id).children;
-                bool ipedge_set = false;
-                edge_t int_par_edge;
-                for (size_t i=0; i<children.size(); i++) {
-                  edge_list_t chedge_list = tet_store.generate_edge_keys(children[i]);
-                  // Check each edge, and compare with possible edges
-                  for (size_t k=0; k<NUM_TET_EDGES; k++) {
-                    for (const auto& ipedge : int_par_edges) {
-                      if (chedge_list[k] == ipedge) {<--- Consider using std::find_if algorithm instead of a raw loop.
-                        int_par_edge = ipedge;
-                        ipedge_set = true;
-                        break;
-                      }
-                    }
-                  }
-                }
-                assert(ipedge_set);
-
-                derefine_four_to_one(tet_store, node_connectivity, parent_id);
-                refine_one_to_two( tet_store, node_connectivity, parent_id,
-                  edge.first(), edge.second() );
-
-                // remove edge not derefined from delete list
-                delete_list.erase(int_par_edge);
-                std::vector< edge_t > parent_edges;
-                parent_edges.push_back(edge);
-                remove_from_deletelist(node_connectivity, parent_edges);
-            }
-
-            // TODO: Document This.
-            void derefine_eight_to_two(tet_store_t& tet_store, node_connectivity_t& node_connectivity, size_t parent_id)
-            {
-                //if (!check_allowed_derefinement(tet_store,parent_id)) return;
-
-                auto edge = find_edge_not_derefined(tet_store,
-                  node_connectivity, parent_id);
-                derefine_eight_to_one(tet_store, node_connectivity, parent_id);
-                refine_one_to_two( tet_store, node_connectivity, parent_id,
-                  edge.first(), edge.second() );
-                // remove edge not derefined from delete list
-                std::vector< edge_t > parent_edges;
-                parent_edges.push_back(edge);
-                remove_from_deletelist(node_connectivity, parent_edges);
-            }
-
-            // TODO: Document This.
-            void derefine_eight_to_four(tet_store_t& tet_store, node_connectivity_t& node_connectivity, size_t parent_id)
-            {
-                //if (!check_allowed_derefinement(tet_store,parent_id)) return;
-                // TODO: think about if the logic for these derefs are right
-                derefine_eight_to_one(tet_store, node_connectivity, parent_id);
-                std::vector< edge_t > kept_edges;
-                deref_refine_one_to_four( tet_store, node_connectivity,
-                  parent_id, kept_edges);
-                // remove edge not derefined from delete list
-                remove_from_deletelist(node_connectivity, kept_edges);
-            }
-
-            /**
-             * @brief Loop over children and determine delete-list of all intermediate edges
-             *
-             * @param tet_store Tet store to use
-             * @param parent_id Id of parent
-             */
-            void determine_deletelist_of_intermediates(tet_store_t& tet_store, size_t parent_id)
-            {
-                Refinement_State& parent = tet_store.data(parent_id);<--- Variable 'parent' can be declared with const
-                auto parent_edges = tet_store.generate_edge_keys(parent_id);
-                std::set< edge_t > parent_edge_set;
-                for (auto pe:parent_edges) parent_edge_set.insert(pe);
-                for (auto c : parent.children)
-                {
-                    edge_list_t edge_list = tet_store.generate_edge_keys(c);
-                    for (size_t k = 0; k < NUM_TET_EDGES; k++)
-                    {
-                        edge_t edge = edge_list[k];
-                        // accept this code may try delete an edge which has already gone
-                        if (tet_store.edge_store.exists(edge)) {
-                            if (parent_edge_set.count(edge) == 0)
-                            {
-                                trace_out << "child " << c << " adding to delete list: "
-                                  << edge.first() << " - " << edge.second() << std::endl;
-                                delete_list.insert(edge);
-                            }
-                        }
-                    }
-                }
-            }
-
-            /**
-             * @brief Remove 'intermediate' edges (based on parent edges) from
-             *   delete list
-             *
-             * @param node_connectivity Node connectivity data structure
-             * @param parent_edges List of parent edges whose 'child' edges need
-             *   to be removed from the delete list
-             */
-            void remove_from_deletelist(
-              node_connectivity_t& node_connectivity,
-              const std::vector< edge_t >& parent_edges )
-            {
-              for (const auto& edge:parent_edges) {
-                auto npnode = node_connectivity.data().at(edge.get_data());
-                edge_t e1(edge.first(),npnode);
-                edge_t e2(edge.second(),npnode);
-                delete_list.erase(e1);
-                delete_list.erase(e2);
-              }
-            }
-
-            /**
-             * @brief Deletes the intermediate edge in the delete list for derefinement
-             *
-             * @param tet_store Tet store to use
-             */
-            void delete_intermediates_of_children(tet_store_t& tet_store)
-            {
-              for (const auto& edge : delete_list) {
-                tet_store.edge_store.erase(edge);
-                tet_store.intermediate_list.erase(edge.get_data()[0]);
-                tet_store.intermediate_list.erase(edge.get_data()[1]);
-              }
-
-              delete_list.clear();
-            }
-
-            /**
-             * @brief If edge in candidate is not present in basis, add edge
-             * (candidate) to delete list
-             *
-             * @param candidate The edge list which is to be searched and deleted
-             * @param basis The edge list to check against
-             */
-            void determine_deletelist_of_non_matching_edges(edge_list_t candidate,
-              edge_list_t basis)
-            {
-                trace_out << "Looking for edges to delete" << std::endl;
-
-                // TODO: Sanity check this now we changed to edge_t
-
-                // Loop over the edges in each child. Look over the basis and
-                // if we can't find it, delete it
-                for (size_t k = 0; k < NUM_TET_EDGES; k++)
-                {
-                    edge_t search_key = candidate[k];
-
-                    // Search the basis for it
-                    bool found_it = false;
-
-                    for (size_t l = 0; l < NUM_TET_EDGES; l++)
-                    {
-                        edge_t key = basis[l];
-                        if (search_key == key)
-                        {
-                            found_it = true;
-                        }
-                    }
-
-                    // If we didn't find it, delete it
-                    if (!found_it)
-                    {
-                        // Delete it
-                        //tet_store.edge_store.erase(search_key);
-                        trace_out << "adding to delete list: "
-                          << search_key.first() << " - " << search_key.second()
-                          << std::endl;
-                        delete_list.insert(search_key);
-                    }
-                }
-            }
-
-
-            /**
-             * @brief function to detect when an invalid derefinement is
-             * invoked
-             *
-             * @param tet_store Tet store to use
-             * @param tet_id Id the of the tet which will be de-refined
-             *
-             * @return A bool stating if the tet can be validly de-refined
-             */
-            bool check_allowed_derefinement( tet_store_t& tet_store, size_t tet_id)
-            {
-                Refinement_State& master_element = tet_store.data(tet_id);<--- Variable 'master_element' can be declared with const
-
-                // Check this won't take us past the max refinement level
-                if (master_element.refinement_level <= MIN_REFINEMENT_LEVEL)
-                {
-                    return false;
-                }
-
-                // If we got here, we didn't detect anything which tells us not
-                // to
-                return true;
-            }
-
-
-            // HERE BE DRAGONS! THIS IS DANGEROUS IF YOU USE IT WRONG
-            // For every child of parent_id, set his children to our won
-            // TODO: set a flag for the curious user to know we trashed the children
-            void overwrite_children(
-                    tet_store_t& tet_store,
-                    const child_id_list_t& to_be_replaced,
-                    const child_id_list_t& replace_with
-            )
-            {
-                for (auto c : to_be_replaced)
-                {
-                    tet_store.data(c).children = replace_with;
-                }
-            }
-
-            /**
-             * @brief function to detect which edge should not get derefined
-             *
-             * @param tet_store Tet store to use
-             * @param node_connectivity Node connectivity to use
-             * @param tet_id Id the of the tet which will be de-refined
-             *
-             * @return Array of size two containing nodes of required edge
-             */
-            edge_t find_edge_not_derefined(
-              tet_store_t& tet_store,
-              node_connectivity_t& node_connectivity,
-              size_t tet_id)
-            {
-              // 2 nonparent nodes set to derefine for a 4:2
-              // 5 nonparent nodes set to derefine for an 8:2
-              // will have 2 or 5 nonparent nodes set to deref; Figure out which
-              // edge is the one that is not set to deref
-
-              auto derefine_node_set = find_derefine_node_set(tet_store, tet_id);
-
-              //// Do number of points
-              //std::unordered_set<size_t> derefine_node_set;
-
-              // Find the set of nodes which are not in the parent
-              std::unordered_set<size_t> non_parent_nodes =
-                child_exclusive_nodes(tet_store, tet_id);
-
-              // from the above non_parent_nodes set and derefine_node_set,
-              // figureout which node should be removed
-              std::size_t ed_A(0), ed_B(0);
-              for (auto npn:non_parent_nodes) {
-                if (derefine_node_set.count(npn) == 0) {
-                  // we've found the node that should not be removed, now we
-                  // need to find the edge it belongs to
-                  auto nonderef_edge = node_connectivity.get(npn);
-                  ed_A = nonderef_edge[0];
-                  ed_B = nonderef_edge[1];
-                  //std::cout << "do-not-deref-APAN " << "A " << nd_edge[0]
-                  //        << " B " << nd_edge[1] << std::endl;
-                }
-              }
-
-              assert(ed_A!=ed_B);
-              edge_t nd_edge(ed_A, ed_B);
-              return nd_edge;
-            }
-
-            /**
-             * @brief function to detect what intermediate/non-parent nodes are
-             *   marked for derefinement
-             *
-             * @param tet_store Tet store to use
-             * @param tet_id Id of the tet which will be de-refined
-             *
-             * @return Set of nodes of marked for derefinement
-             */
-            std::unordered_set< size_t > find_derefine_node_set(
-              tet_store_t& tet_store,
-              size_t tet_id)
-            {
-              // Set of nodes which are not in the parent
-              std::unordered_set<size_t> non_parent_nodes =
-                child_exclusive_nodes(tet_store, tet_id);
-              std::unordered_set<size_t> derefine_node_set, unmarked_deref_node_set,
-                final_deref_node_set;
-
-              child_id_list_t children = tet_store.data(tet_id).children;
-
-              // Look at children
-              trace_out << tet_id << " Looping over " << children.size() << "children" << std::endl;
-              for (size_t i = 0; i < children.size(); i++)
-              {
-                  trace_out << "child: " << children[i] << std::endl;
-                  // TODO: Is this in element or tet ids?
-                  edge_list_t edge_list = tet_store.generate_edge_keys(children[i]);
-                  for (size_t k = 0; k < NUM_TET_EDGES; k++)
-                  {
-                      edge_t edge = edge_list[k];
-                      // TODO: where do we makr the edges that need to be derefed? parent of child?
-                      // Check each node, see if its an intermediate
-                      size_t A = edge.first();
-                      size_t B = edge.second();
-                      trace_out << "checking edge for deref " << A << " - " << B << std::endl;
-
-                      //if (tet_store.is_intermediate(A))
-                      if (non_parent_nodes.count(A) )
-                      {
-                        if (tet_store.edge_store.get(edge).needs_derefining) {
-                          trace_out << "Adding " << A << std::endl;
-                          derefine_node_set.insert(A);
-                        }
-                        else {
-                          unmarked_deref_node_set.insert(A);
-                          //trace_out << "NOT added " << A << std::endl;
-                        }
-                      }
-
-                      //if (tet_store.is_intermediate(B))
-                      if (non_parent_nodes.count(B))
-                      {
-                        if (tet_store.edge_store.get(edge).needs_derefining) {
-                          trace_out << "Adding " << B << std::endl;
-                          derefine_node_set.insert(B);
-                        }
-                        else {
-                          unmarked_deref_node_set.insert(B);
-                          //trace_out << "NOT added " << B << std::endl;
-                        }
-                      }
-                  }
-              }
-
-              //trace_out << "marked for deref: " << derefine_node_set.size() << std::endl;
-              //trace_out << "NOT marked for deref: " << unmarked_deref_node_set.size() << std::endl;
-
-              // remove nodes that are unmarked for derefinement
-              for (auto drnode : derefine_node_set) {
-                if (unmarked_deref_node_set.count(drnode) == 0) {
-                  final_deref_node_set.insert(drnode);
-                  trace_out << "Final deref node " << drnode << std::endl;
-                }
-              }
-
-              derefine_node_set = final_deref_node_set;
-              return derefine_node_set;
-            }
-
-
-            std::unordered_set<size_t> child_exclusive_nodes(tet_store_t& tet_store,
-              size_t tet_id)
-            {
-              std::unordered_set<size_t> non_parent_nodes;
-
-              // array
-              auto parent_tet = tet_store.get(tet_id);
-
-              // convert to set
-              std::unordered_set<size_t> parent_set(begin(parent_tet), end(parent_tet));
-
-              child_id_list_t children = tet_store.data(tet_id).children;
-              for (size_t i = 0; i < children.size(); i++)
-              {
-                      auto child_tet = tet_store.get( children[i] );
-
-                      // Look at nodes, if not present add to set
-                      for (std::size_t j = 0; j < NUM_TET_NODES; j++)
-                      {
-                              auto node = child_tet[j];
-                              if (parent_set.count(node) == 0)
-                              {
-                                      non_parent_nodes.insert(node);
-                              }
-                      }
-              }
-
-              trace_out <<" Found " << non_parent_nodes.size() << " non parent nodes " << std::endl;
-              return non_parent_nodes;
-
-            }
-    };
-}
-
-#if defined(STRICT_GNUC)
-  #pragma GCC diagnostic pop
-#endif
-
-#endif // guard
+    //! Initiate computationa of dot product of two vectors
+    void dot( const std::vector< tk::real >& a,
+              const std::vector< tk::real >& b,
+              CkCallback c );
+
+    //! Initiate A * x for computing the residual, r = b - A * x
+    void residual();
+    //! Finish computing the initial residual, r = b - A * x
+    void initres();
+
+    //! Apply boundary conditions
+    void apply( CkCallback cb );
+
+    //! Initiate computing q = A * p
+    void qAp();
+    //! Finish computing q = A * p
+    void q();
+
+    //! Start next linear solver iteration
+    void next();
+
+    //! Assemble solution on chare boundaries
+    void x();
+};
+
+} // tk::
+
+#endif // ConjugateGradients_h
 
diff --git a/Debug/cppcheck/16.html b/Debug/cppcheck/16.html index e4465b3f6e76..12d60d01966a 100644 --- a/Debug/cppcheck/16.html +++ b/Debug/cppcheck/16.html @@ -152,12 +152,12 @@
  1
@@ -476,843 +476,323 @@ 

Cppcheck report - [

// *****************************************************************************
-/*!
-  \file      src/LinearSolver/ConjugateGradients.cpp
-  \copyright 2012-2015 J. Bakosi,
-             2016-2018 Los Alamos National Security, LLC.,
-             2019-2021 Triad National Security, LLC.
-             All rights reserved. See the LICENSE file for details.
-  \brief     Charm++ chare array for distributed conjugate gradients.
-  \details   Charm++ chare array for asynchronous distributed
-    conjugate gradients linear solver.
-  \see Y. Saad, Iterative Methods for Sparse Linear Systems: Second Edition,
-    ISBN 9780898718003, 2003, Algorithm 6.18, conjugate gradients to solve the
-    linear system A * x = b, reproduced here:
-
-    Compute r0:=b-A*x0, p0:=r0
-    For j=0,1,..., until convergence, do
-      alpha_j := (r_j,r_j) / (Ap_j,p_j)
-      x_{j+1} := x_j + alpha_j p_j
-      r_{j+1} := r_j - alpha_j A p_j
-      beta_j := (r_{j+1},r_{j+1}) / (r_j,r_j)
-      p_{j+1} := r_{j+1} + beta_j p_j
-    end
-*/
-// *****************************************************************************
-
-#include <numeric>
-#include <iostream>
-
-#include "Exception.hpp"
-#include "ConjugateGradients.hpp"
-#include "Vector.hpp"
-
-using tk::ConjugateGradients;
-
-ConjugateGradients::ConjugateGradients(<--- Member variable 'ConjugateGradients::m_tol' is not initialized in the constructor.
-  const CSR& A,
-  const std::vector< tk::real >& x,
-  const std::vector< tk::real >& b,
-  const std::vector< std::size_t >& gid,
-  const std::unordered_map< std::size_t, std::size_t >& lid,
-  const NodeCommMap& nodecommmap ) :
-  m_A( A ),
-  m_x( x ),
-  m_b( b ),
-  m_gid( gid ),
-  m_lid( lid ),
-  m_nodeCommMap( nodecommmap ),
-  m_r( m_A.rsize(), 0.0 ),
-  m_rc(),
-  m_nr( 0 ),
-  m_bc(),
-  m_bcc(),
-  m_bcmask( m_A.rsize(), 1.0 ),
-  m_nb( 0 ),
-  m_p( m_A.rsize(), 0.0 ),
-  m_q( m_A.rsize(), 0.0 ),
-  m_qc(),
-  m_nq( 0 ),
-  m_initres(),
-  m_solved(),
-  m_normb( 0.0 ),
-  m_it( 0 ),
-  m_maxit( 0 ),
-  m_rho( 0.0 ),
-  m_rho0( 0.0 ),
-  m_alpha( 0.0 ),
-  m_converged( false ),
-  m_xc(),
-  m_nx( 0 )
-// *****************************************************************************
-//  Constructor
-//! \param[in] A Left hand side matrix of the linear system to solve in Ax=b
-//! \param[in] x Solution (initial guess) of the linear system to solve in Ax=b
-//! \param[in] b Right hand side of the linear system to solve in Ax=b
-//! \param[in] gid Global node ids
-//! \param[in] lid Local node ids associated to global ones
-//! \param[in] nodecommmap Global mesh node IDs shared with other chares
-//!   associated to their chare IDs
-// *****************************************************************************
-{
-  // Fill in gid and lid for serial solve
-  if (gid.empty() || lid.empty() || nodecommmap.empty()) {
-    m_gid.resize( m_A.rsize()/m_A.Ncomp() );
-    std::iota( begin(m_gid), end(m_gid), 0 );
-    for (auto g : m_gid) m_lid[g] = g;
-  }
-
-  Assert( m_A.rsize() == m_gid.size()*A.Ncomp(), "Size mismatch" );
-  Assert( m_x.size() == m_gid.size()*A.Ncomp(), "Size mismatch" );
-  Assert( m_b.size() == m_gid.size()*A.Ncomp(), "Size mismatch" );
-}
-
-void
-ConjugateGradients::setup( CkCallback c )
-// *****************************************************************************
-//  Setup solver
-//! \param[in] c Call to continue with after initialization is complete
-//! \details This function initiates computing the residual (r=b-A*x), its dot
-//!   product, and the rhs norm.
-// *****************************************************************************
-{
-  m_initres = c;
-
-  // initiate computing A * x (for the initial residual)
-  thisProxy[ thisIndex ].wait4res();
-  residual();
-
-  // initiate computing norm of right hand side
-  dot( m_b, m_b,
-       CkCallback( CkReductionTarget(ConjugateGradients,normb), thisProxy ) );
-}
-
-void
-ConjugateGradients::dot( const std::vector< tk::real >& a,
-                         const std::vector< tk::real >& b,
-                         CkCallback c )
-// *****************************************************************************
-//  Initiate computation of dot product of two vectors
-//! \param[in] a 1st vector of dot product
-//! \param[in] b 2nd vector of dot product
-//! \param[in] c Callback to target with the final result
-// *****************************************************************************
-{
-  Assert( a.size() == b.size(), "Size mismatch" );
-
-  tk::real D = 0.0;
-  auto ncomp = m_A.Ncomp();
-  for (std::size_t i=0; i<a.size()/ncomp; ++i) {
-    auto incomp = i*ncomp;
-    if (not slave(m_nodeCommMap,m_gid[i],thisIndex))
-      for (std::size_t d=0; d<ncomp; ++d)
-        D += a[incomp+d] * b[incomp+d];
-  }
-
-  contribute( sizeof(tk::real), &D, CkReduction::sum_double, c );
-}
-
-void
-ConjugateGradients::normb( tk::real n )
-// *****************************************************************************
-// Compute the norm of the right hand side
-//! \param[in] n Norm of right hand side (aggregated across all chares)
-// *****************************************************************************
-{
-  m_normb = std::sqrt(n);
-  normb_complete();
-}
-
-void
-ConjugateGradients::residual()
-// *****************************************************************************
-//  Initiate A * x for computing the initial residual, r = b - A * x
-// *****************************************************************************
-{
-  // Compute own contribution to r = A * x
-  m_A.mult( m_x, m_r, m_bcmask );
-
-  // Send partial product on chare-boundary nodes to fellow chares
-  if (m_nodeCommMap.empty()) {
-    comres_complete();
-  } else {
-    auto ncomp = m_A.Ncomp();
-    for (const auto& [c,n] : m_nodeCommMap) {
-      std::vector< std::vector< tk::real > > rc( n.size() );
-      std::size_t j = 0;
-      for (auto g : n) {
-        std::vector< tk::real > nr( ncomp );
-        auto i = tk::cref_find( m_lid, g );
-        for (std::size_t d=0; d<ncomp; ++d) nr[d] = m_r[ i*ncomp+d ];
-        rc[j++] = std::move(nr);
-      }
-      thisProxy[c].comres( std::vector<std::size_t>(begin(n),end(n)), rc );
-    }
-  }
-
-  ownres_complete();
-}
-
-void
-ConjugateGradients::comres( const std::vector< std::size_t >& gid,
-                            const std::vector< std::vector< tk::real > >& rc )
-// *****************************************************************************
-//  Receive contributions to A * x on chare-boundaries
-//! \param[in] gid Global mesh node IDs at which we receive contributions
-//! \param[in] rc Partial contributions at chare-boundary nodes
-// *****************************************************************************
-{
-  Assert( rc.size() == gid.size(), "Size mismatch" );
-
-  using tk::operator+=;
-
-  for (std::size_t i=0; i<gid.size(); ++i)
-    m_rc[ gid[i] ] += rc[i];
-
-  if (++m_nr == m_nodeCommMap.size()) {
-    m_nr = 0;
-    comres_complete();
-  }
-}
-
-void
-ConjugateGradients::initres()
-// *****************************************************************************
-// Finish computing the initial residual, r = b - A * x
-// *****************************************************************************
-{
-  // Combine own and communicated contributions to r = A * x
-  auto ncomp = m_A.Ncomp();
-  for (const auto& [gid,r] : m_rc) {
-    auto i = tk::cref_find( m_lid, gid );
-    for (std::size_t c=0; c<ncomp; ++c) m_r[i*ncomp+c] += r[c];
-  }
-  tk::destroy( m_rc );
-
-  // Finish computing the initial residual, r = b - A * x
-  for (auto& r : m_r) r *= -1.0;<--- Consider using std::transform algorithm instead of a raw loop.
-  m_r += m_b;
-
-  // Initialize p
-  m_p = m_r;
-
-  // initiate computing the dot product of the initial residual, rho = (r,r)
-  dot( m_r, m_r,
-       CkCallback( CkReductionTarget(ConjugateGradients,rho), thisProxy ) );
-}
-
-void
-ConjugateGradients::rho( tk::real r )
-// *****************************************************************************
-// Compute rho = (r,r)
-//! \param[in] r Dot product, rho = (r,r) (aggregated across all chares)
-// *****************************************************************************
-{
-  // store dot product of residual
-  m_rho = r;
-
-  // send back rhs norm to caller
-  m_initres.send( CkDataMsg::buildNew( sizeof(tk::real), &m_normb ) );
-}
-
-void
-ConjugateGradients::init(
-  const std::vector< tk::real >& x,
-  const std::vector< tk::real >& b,
-  const std::unordered_map< std::size_t,
-          std::vector< std::pair< bool, tk::real > > >& bc,
-  std::size_t ignorebc,
-  CkCallback cb )
-// *****************************************************************************
-//  Initialize linear solve: set initial guess and boundary conditions
-//! \param[in] x Initial guess
-//! \param[in] b Right hand side vector
-//! \param[in] bc Local node ids and associated Dirichlet BCs
-//! \param[in] ignorebc True if applyin BCs should be skipped
-//! \param[in] cb Call to continue with when initialized and ready for a solve
-//! \details This function allows setting the initial guess and boundary
-//!   conditions, followed by computing the initial residual and the rhs norm.
-// *****************************************************************************
-{
-  // Optionally set initial guess
-  if (not x.empty()) m_x = x;
-
-  // Optionally update rhs
-  if (not b.empty()) m_b = b;
-
-  if (ignorebc) {
-
-    setup( cb );
-
-  } else {
-
-    // Store incoming BCs
-    m_bc = bc;
+317
#ifndef AMR_edge_store_h
+#define AMR_edge_store_h
+
+#include <cassert>
+
+#include "Loggers.hpp"
+#include "AMR/AMR_types.hpp"
+
+namespace AMR {
+
+    class edge_store_t {
+        public:
+            // TODO: convert this to an unordered map with a custom hash (can lift from Quinoa)
+            edges_t edges;
+
+            // Node connectivity does this any way, but in a slightly less efficient way
+            // Maps the edge to the child node which splits it
+                // This was added retrospectivley to support the operation "for
+                // edge formed of initial nodes {A,B}, what node(s) were added
+                // between them"
+                // NOTE: At some point, this could probably be deleted..
+                // NOTE: This is only mainted by split.
+            //std::map<edge_t, size_t> children;
+
+            size_t size()
+            {
+                return edges.size();
+            }
+
+            /**
+             * @brief Function to create new edge between two nodes with an
+             * intermediate. Given nodes A, B, and AB makes edge A->AB and AB->B
+             *
+             * @param A First end node
+             * @param B Second end node
+             * @param AB Intermediate node
+             * @param lc Lock case for the new edges
+             */
+            void split(size_t A, size_t B, size_t AB, Edge_Lock_Case lc)
+            {
+                trace_out << "Splitting with lock case " << lc << std::endl;
+                generate(A, AB, lc);
+                generate(B, AB, lc);
+
+                //children.insert( std::pair<edge_t, size_t>(edge_t(A,B), AB));
+                // Generate pertinent keys
+                //edge_t keyAB = nodes_to_key(A, B);
+
+                // NOTE: This isn't explicitly needed in the paper, and may be
+                    // implicitly dealt with somewhere?
+                //mark_edge_for_refinement(keyAB);
+            }
+
+            /**
+             * @brief Given nodes A and B, generate an edge between them
+             *
+             * @param A First node
+             * @param B Second node
+             * @param lc Lock case for new edge
+             */
+            void generate(size_t A, size_t B, Edge_Lock_Case lc)
+            {
+                if ((A != 0) && (B != 0)) {
+                    trace_out << "A " << A << " B " << B << std::endl;
+                    assert(A != B);
+                }
+
+                // Generate key
+                edge_t keyAB = nodes_to_key(A, B);
+                //Create refined edge
+                Edge_Refinement edgeAB = Edge_Refinement(A, B, false, false, lc);
+                // Add edge to store
+                add(keyAB, edgeAB);
+            }
+
+            bool exists(edge_t key)
+            {
+                if (edges.find(key) != edges.end())
+                {
+                    return true;
+                }
+                return false;
+            }
+
+            /**
+             * @brief Function to retrieve an edge from the edge store
+             *
+             * @param key Key of the edge to get
+             *
+             * @return A reference to the fetched edge
+             */
+            Edge_Refinement& get(edge_t key)
+            {
+                //trace_out << "get edge " << key << std::endl;
+                // cppcheck-suppress assertWithSideEffect
+                if (!exists(key)) trace_out << "key not found " << key.first()
+                  << " - " << key.second() << std::endl;
+                assert( exists(key) );
+                return edges[key];
+            }
+
+            Edge_Lock_Case lock_case(const edge_t& key)
+            {
+                return get(key).lock_case;
+            }
+
+            void erase(edge_t key)
+            {
+                trace_out << "Deref removing edge: " << key.first() << " - "
+                  << key.second() << std::endl;
+                edges.erase(key);
+            }
+
+            /**
+             * @brief Function to add edge to edge store
+             *
+             * @param key The key for the given edge
+             * @param e The edge data
+             *
+             * Note: This tolerate the addition of duplicate edges
+             */
+            void add(edge_t key, Edge_Refinement e)
+            {
+                // Add edge if it doesn't exist (default behavior of insert)
+                edges.insert( std::pair<edge_t, Edge_Refinement>(key, e));
+
+                // TODO: It may be worth adding a check here to ensure if we're
+                // trying to add a new edge that exists it should contain the
+                // same data
+            }
+
+            static edge_t nodes_to_key(size_t A, size_t B)
+            {
+                return edge_t(A,B);
+            }
+
+            /**
+             * @brief Function to build a  string key from two node ids
+             * NOTE: Regardless of order of arguments, the same key will be generated
+             */
+            //static std::string nodes_to_key(size_t A, size_t B)
+            //{
+                //return std::to_string(std::min(A,B)) + KEY_DELIM + std::to_string(std::max(A,B));
+            //}
+
+            /**
+             * @brief function to take the nodes representing a face
+             * and to build the possible edges based on that
+             *
+             * For a given face {ABC}, generate the edge pairs {AB, AC, BC}
+             *
+             * @param face_ids The ids of the face to generate this for
+             *
+             * @return A (partially filled) list of all edges present on the
+             * face
+             */
+            // FIXME: Is it OK that it leaves some of the array blank?
+            static edge_list_t generate_keys_from_face_ids(face_ids_t face_ids)
+            {
+                edge_list_t key_list;
+                size_t A = face_ids[0];
+                size_t B = face_ids[1];
+                size_t C = face_ids[2];
+
+                edge_t key = nodes_to_key(A,B);
+                key_list[0] = key; // TODO: Is it OK to use copy assignment here?
+
+                key = nodes_to_key(A,C);
+                key_list[1] = key;
+
+                key = nodes_to_key(B,C);
+                key_list[2] = key;
+
+                return key_list;
+            }
+
+            /**
+             * @brief function to take a list of edge and mark them all
+             * as needing to be refined
+             *
+             * @param ids List of ids to mark for refinement
+             */
+            void mark_edges_for_refinement(std::vector<node_pair_t> ids) {
+                for (const auto& id : ids)
+            {
+                    edge_t key = nodes_to_key(id[0], id[1]);
+
+                    mark_for_refinement(key);
+                    trace_out << get(key).needs_refining << std::endl;
+                }
+            }
+
+
+            /**
+             * @brief function to mark a single edge as needing
+             * refinement (provides a nice abstraction from messing with the
+             * struct directly).
+             *
+             * @param key The edge key to mark as refinement
+             */
+            void mark_for_refinement(const edge_t& key)
+            {
+                // cppcheck-suppress assertWithSideEffect
+                assert( exists(key) );
+                get(key).needs_refining = 1;
+            }
+
+            /**
+             * @brief function to take a list of edge and mark them all
+             * as needing to be refined as a part of the 8:4 derefinement
+             *
+             * @param ids List of ids to mark for deref-refinement
+             */
+            void mark_edges_for_deref_ref(std::vector<node_pair_t> ids)
+            {
+              for (const auto& id : ids)
+                {
+                  edge_t key = nodes_to_key(id[0], id[1]);
+
+                  // cppcheck-suppress assertWithSideEffect
+                  assert( exists(key) );
+                  // value of 2 for needs_refining indicates part of derefine
+                  get(key).needs_refining = 2;
+
+                  trace_out << "edge: " << key.get_data()[0] << "-"
+                    << key.get_data()[1] << " deref-ref: "
+                    << get(key).needs_refining << std::endl;
+                }
+            }
+
+            /**
+             * @brief Function to unmark and edge as needing refinement
+             *
+             * @param key The key representing the edge to unmark
+             */
+            void unmark_for_refinement(const edge_t& key)
+            {
+                // cppcheck-suppress assertWithSideEffect
+                assert( exists(key) );
+                get(key).needs_refining = 0;
+            }
+
+            /**
+             * @brief For a given list of node pairs, mark the edge as needing
+             * to be de-refined
+             *
+             * @param ids a vector of pairs to mark for derefinement
+             */
+            void mark_edges_for_derefinement(std::vector<node_pair_t> ids) {
+                for (const auto& id : ids)
+                {
+                    edge_t key = nodes_to_key(id[0], id[1]);
+
+                    mark_edge_for_derefinement(key);
+                }
+            }
+            void mark_edge_for_derefinement(const edge_t& key) {
+                    get(key).needs_derefining = true;
+            }
+
+
+            /**
+             * @brief Function to generate a list of edge keys from a tet
+             *
+             * @param tet The tet to generate edge pairs for
+             *
+             * @return A list (array) of edge keys which can be separated out to
+             * name the two composing node ids
+             */
+            edge_list_t generate_keys(tet_t tet)
+            {
+                // FIXME : Generate these with a (2d) loop and not hard code them?
+                edge_list_t key_list;
 
-    // Get ready to communicate boundary conditions. This is necessary because
-    // there can be nodes a chare contributes to but does not apply BCs on. This
-    // happens if a node is in the node communication map but not on the list of
-    // incoming BCs on this chare. To have all chares share the same view on all
-    // BC nodes, we send the global node ids together with the Dirichlet BCs at
-    // which BCs are set to those fellow chares that also contribute to those BC
-    // nodes. Only after this communication step we apply the BCs on the matrix,
-    // which then will correctly setup the BC rows that exist on multiple chares
-    // (which now will be the same as the results of making the BCs consistent
-    // across all chares that contribute.
-    thisProxy[ thisIndex ].wait4bc();
-
-    // Send boundary conditions to those who contribute to those rows
-    if (m_nodeCommMap.empty()) {
-      combc_complete();
-    } else {
-      for (const auto& [c,n] : m_nodeCommMap) {
-        std::unordered_map< std::size_t,
-          std::vector< std::pair< bool, tk::real > > > expbc;
-        for (auto g : n) {
-          auto i = tk::cref_find( m_lid, g );
-          auto j = bc.find(i);
-          if (j != end(bc)) expbc[g] = j->second;
-        }
-        thisProxy[c].combc( expbc );
-      }
-    }
+                size_t A = tet[0];
+                size_t B = tet[1];
+                size_t C = tet[2];
+                size_t D = tet[3];
+
+                edge_t key;
+
+                key = nodes_to_key(A,B);
+                key_list[0] = key;
+
+                key = nodes_to_key(A,C);
+                key_list[1] = key;
+
+                key = nodes_to_key(A,D);
+                key_list[2] = key;
+
+                key = nodes_to_key(B,C);
+                key_list[3] = key;
+
+                key = nodes_to_key(B,D);
+                key_list[4] = key;
+
+                key = nodes_to_key(C,D);
+                key_list[5] = key;
+
+                return key_list;
+            }
 
-    ownbc_complete( cb );
-
-  }
-}
-
-void
-ConjugateGradients::combc(
-  const std::unordered_map< std::size_t,
-     std::vector< std::pair< bool, tk::real > > >& bc )
-// *****************************************************************************
-//  Receive contributions to boundary conditions on chare-boundaries
-//! \param[in] bc Contributions to boundary conditions
-// *****************************************************************************
-{
-  for (const auto& [g,dirbc] : bc) m_bcc[ tk::cref_find(m_lid,g) ] = dirbc;
-
-  if (++m_nb == m_nodeCommMap.size()) {
-    m_nb = 0;
-    combc_complete();
-  }
-}
-
-void
-ConjugateGradients::apply( CkCallback cb )
-// *****************************************************************************
-//  Apply boundary conditions
-//! \param[in] cb Call to continue with after applying the BCs is complete
-// *****************************************************************************
-{
-  // Merge own and received contributions to boundary conditions
-  for (const auto& [i,dirbc] : m_bcc) m_bc[i] = dirbc;
-  tk::destroy( m_bcc );
-
-  auto ncomp = m_A.Ncomp();
-
-  // Setup Dirichlet BC map as contiguous mask
-  for (const auto& [i,bc] : m_bc)
-    for (std::size_t j=0; j<ncomp; ++j)
-      m_bcmask[i*ncomp+j] = 0.0;
-
-  // Apply Dirichlet BCs on matrix and rhs
-  for (const auto& [i,dirbc] : m_bc) {
-    for (std::size_t j=0; j<ncomp; ++j) {
-      if (dirbc[j].first) {
-        m_A.dirichlet( i, m_gid, m_nodeCommMap, j );
-        m_b[i*ncomp+j] = dirbc[j].second;
-      }
-    }
-  }
-
-  // Recompute initial residual (r=b-A*x), its dot product, and the rhs norm
-  setup( cb );
-}
-
-void
-ConjugateGradients::solve( std::size_t maxit, tk::real tol, CkCallback c )
-// *****************************************************************************
-//  Solve linear system
-//! \param[in] maxit Max iteration count
-//! \param[in] tol Stop tolerance
-//! \param[in] c Call to continue with after solve is complete
-// *****************************************************************************
-{
-  m_maxit = maxit;
-  m_tol = tol;
-  m_solved = c;
-  m_it = 0;
-
-  next();
-}
-
-void
-ConjugateGradients::next()
-// *****************************************************************************
-//  Start next linear solver iteration
-// *****************************************************************************
-{
-  if (m_it == 0) m_alpha = 0.0; else m_alpha = m_rho/m_rho0;
-  m_rho0 = m_rho;
-
-  // compute p = r + alpha * p
-  for (std::size_t i=0; i<m_p.size(); ++i) m_p[i] = m_r[i] + m_alpha * m_p[i];
-
-  // initiate computing q = A * p
-  thisProxy[ thisIndex ].wait4q();
-  qAp();
-}
-
-
-void
-ConjugateGradients::qAp()
-// *****************************************************************************
-//  Initiate computing q = A * p
-// *****************************************************************************
-{
-  // Compute own contribution to q = A * p
-  m_A.mult( m_p, m_q, m_bcmask );
-
-  // Send partial product on chare-boundary nodes to fellow chares
-  if (m_nodeCommMap.empty()) {
-    comq_complete();
-  } else {
-    auto ncomp = m_A.Ncomp();
-    for (const auto& [c,n] : m_nodeCommMap) {
-      std::vector< std::vector< tk::real > > qc( n.size() );
-      std::size_t j = 0;
-      for (auto g : n) {
-        std::vector< tk::real > nq( ncomp );
-        auto i = tk::cref_find( m_lid, g );
-        for (std::size_t d=0; d<ncomp; ++d) nq[d] = m_q[ i*ncomp+d ];
-        qc[j++] = std::move(nq);
-      }
-      thisProxy[c].comq( std::vector<std::size_t>(begin(n),end(n)), qc );
-    }
-  }
-
-  ownq_complete();
-}
-
-void
-ConjugateGradients::comq( const std::vector< std::size_t >& gid,
-                          const std::vector< std::vector< tk::real > >& qc )
-// *****************************************************************************
-//  Receive contributions to q = A * p on chare-boundaries
-//! \param[in] gid Global mesh node IDs at which we receive contributions
-//! \param[in] qc Partial contributions at chare-boundary nodes
-// *****************************************************************************
-{
-  Assert( qc.size() == gid.size(), "Size mismatch" );
-
-  using tk::operator+=;
-
-  for (std::size_t i=0; i<gid.size(); ++i)
-    m_qc[ gid[i] ] += qc[i];
-
-  if (++m_nq == m_nodeCommMap.size()) {
-    m_nq = 0;
-    comq_complete();
-  }
-}
-
-void
-ConjugateGradients::q()
-// *****************************************************************************
-// Finish computing q = A * p
-// *****************************************************************************
-{
-  // Combine own and communicated contributions to q = A * p
-  auto ncomp = m_A.Ncomp();
-  for (const auto& [gid,q] : m_qc) {
-    auto i = tk::cref_find( m_lid, gid );
-    for (std::size_t c=0; c<ncomp; ++c)
-      m_q[i*ncomp+c] += q[c];
-  }
-  tk::destroy( m_qc );
-
-  // initiate computing (p,q)
-  dot( m_p, m_q,
-       CkCallback( CkReductionTarget(ConjugateGradients,pq), thisProxy ) );
-}
-
-void
-ConjugateGradients::pq( tk::real d )
-// *****************************************************************************
-// Compute the dot product (p,q)
-//! \param[in] d Dot product of (p,q) (aggregated across all chares)
-// *****************************************************************************
-{
-  // If (p,q)=0, then p and q are orthogonal and the system either has a trivial
-  // solution, x=x0, or the BCs are incomplete or wrong, in either case the
-  // solve cannot continue.
-  const auto eps = std::numeric_limits< tk::real >::epsilon();
-  if (std::abs(d) < eps) {
-    m_it = m_maxit;
-    m_alpha = 0.0;
-  } else {
-    m_alpha = m_rho / d;
-  }
-
-  // compute r = r - alpha * q
-  for (std::size_t i=0; i<m_r.size(); ++i) m_r[i] -= m_alpha * m_q[i];
-
-  // initiate computing norm of residual: (r,r)
-  dot( m_r, m_r,
-       CkCallback( CkReductionTarget(ConjugateGradients,normres), thisProxy ) );
-}
-
-void
-ConjugateGradients::normres( tk::real r )
-// *****************************************************************************
-// Compute norm of residual: (r,r)
-//! \param[in] r Dot product, (r,r) (aggregated across all chares)
-// *****************************************************************************
-{
-  m_rho = r;
-
-  // Advance solution: x = x + alpha * p
-  for (std::size_t i=0; i<m_x.size(); ++i) m_x[i] += m_alpha * m_p[i];
-
-  // Communicate solution
-  thisProxy[ thisIndex ].wait4x();
-
-  // Send solution on chare-boundary nodes to fellow chares
-  if (m_nodeCommMap.empty()) {
-    comx_complete();
-  } else {
-    auto ncomp = m_A.Ncomp();
-    for (const auto& [c,n] : m_nodeCommMap) {
-      std::vector< std::vector< tk::real > > xc( n.size() );
-      std::size_t j = 0;
-      for (auto g : n) {
-        std::vector< tk::real > nx( ncomp );
-        auto i = tk::cref_find( m_lid, g );
-        for (std::size_t d=0; d<ncomp; ++d) nx[d] = m_x[ i*ncomp+d ];
-        xc[j++] = std::move(nx);
-      }
-      thisProxy[c].comx( std::vector<std::size_t>(begin(n),end(n)), xc );
-    }
-  }
-
-  ownx_complete();
-}
-
-void
-ConjugateGradients::comx( const std::vector< std::size_t >& gid,
-                          const std::vector< std::vector< tk::real > >& xc )
-// *****************************************************************************
-//  Receive contributions to final solution on chare-boundaries
-//! \param[in] gid Global mesh node IDs at which we receive contributions
-//! \param[in] xc Partial contributions at chare-boundary nodes
-// *****************************************************************************
-{
-  Assert( xc.size() == gid.size(), "Size mismatch" );
-
-  for (std::size_t i=0; i<gid.size(); ++i) m_xc[ gid[i] ] += xc[i];
-
-  if (++m_nx == m_nodeCommMap.size()) {
-    m_nx = 0;
-    comx_complete();
-  }
-}
-
-void
-ConjugateGradients::x()
-// *****************************************************************************
-// Assemble solution on chare boundaries
-// *****************************************************************************
-{
-  // Assemble solution on chare boundaries by averaging
-  auto ncomp = m_A.Ncomp();
-  for (const auto& [g,x] : m_xc) {
-    auto i = tk::cref_find(m_lid,g);
-    for (std::size_t d=0; d<ncomp; ++d) m_x[i*ncomp+d] += x[d];
-    auto c = tk::count(m_nodeCommMap,g);
-    for (std::size_t d=0; d<ncomp; ++d) m_x[i*ncomp+d] /= c;
-  }
-  tk::destroy( m_xc );
-
-  ++m_it;
-  auto normb = m_normb > 1.0e-14 ? m_normb : 1.0;
-  auto normr = std::sqrt( m_rho );
-
-  if ( m_it < m_maxit && normr > m_tol*normb ) {
-
-    next();
-
-  } else {
-
-    m_converged = m_it == m_maxit && normr > m_tol*normb ? false : true;
-    m_solved.send( CkDataMsg::buildNew( sizeof(tk::real), &normr ) );
-
-  }
-}
-
-#include "NoWarning/conjugategradients.def.h"
+            /**
+             * @brief Helper debug function to print edge information
+             */
+            void print() {
+                for (const auto& kv : edges)
+                {
+                    trace_out << "edge " << kv.first << " between " <<
+                        kv.second.A << " and " << kv.second.B <<
+                    std::endl;
+                }
+            }
+    };
+}
+
+#endif // AMR_edge_store
 
diff --git a/Debug/cppcheck/17.html b/Debug/cppcheck/17.html index 42da008b62a4..83c5555c5c26 100644 --- a/Debug/cppcheck/17.html +++ b/Debug/cppcheck/17.html @@ -152,535 +152,2667 @@
- - + @@ -105,12 +105,12 @@ 31 : : size_t empty_node_count = 0; 32 : : 33 : : - 34 : 7861 : node_connectivity_t() { } // default cons + 34 : 7774 : node_connectivity_t() { } // default cons 35 : : 36 : : //! Non-const-ref accessor to state 37 : : //! \return All node pairs - 38 : 24399 : node_list_t& data() { return nodes; } - 39 : 24399 : inv_node_list_t& inv_data() { return inv_nodes; } + 38 : 24138 : node_list_t& data() { return nodes; } + 39 : 24138 : inv_node_list_t& inv_data() { return inv_nodes; } 40 : : 41 : : /** 42 : : * @brief Method to add initial nodes to the store diff --git a/Debug/test_coverage/Inciter/AMR/refinement.hpp.func-sort-c.html b/Debug/test_coverage/Inciter/AMR/refinement.hpp.func-sort-c.html index c9cd6c9f3c36..6819056457df 100644 --- a/Debug/test_coverage/Inciter/AMR/refinement.hpp.func-sort-c.html +++ b/Debug/test_coverage/Inciter/AMR/refinement.hpp.func-sort-c.html @@ -33,7 +33,7 @@ - + @@ -153,7 +153,7 @@ - + diff --git a/Debug/test_coverage/Inciter/AMR/refinement.hpp.func.html b/Debug/test_coverage/Inciter/AMR/refinement.hpp.func.html index 49adf98bc853..eee40f945525 100644 --- a/Debug/test_coverage/Inciter/AMR/refinement.hpp.func.html +++ b/Debug/test_coverage/Inciter/AMR/refinement.hpp.func.html @@ -33,7 +33,7 @@ - + @@ -185,7 +185,7 @@ - +
  1
-  2
-  3
-  4
-  5
-  6
-  7
-  8
-  9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
- 37
- 38
- 39
- 40
- 41
- 42
- 43
- 44
- 45
- 46
- 47
- 48
- 49
- 50
- 51
- 52
- 53
- 54
- 55
- 56
- 57
- 58
- 59
- 60
- 61
- 62
- 63
- 64
- 65
- 66
- 67
- 68
- 69
- 70
- 71
- 72
- 73
- 74
- 75
- 76
- 77
- 78
- 79
- 80
- 81
- 82
- 83
- 84
- 85
- 86
- 87
- 88
- 89
- 90
- 91
- 92
- 93
- 94
- 95
- 96
- 97
- 98
- 99
-100
-101
-102
-103
-104
-105
-106
-107
-108
-109
-110
-111
-112
-113
-114
-115
-116
-117
-118
-119
-120
-121
-122
-123
-124
-125
-126
-127
-128
-129
-130
-131
-132
-133
-134
-135
-136
-137
-138
-139
-140
-141
-142
-143
-144
-145
-146
-147
-148
-149
-150
-151
-152
-153
-154
-155
-156
-157
-158
-159
-160
-161
-162
-163
-164
-165
-166
-167
-168
-169
-170
-171
-172
-173
-174
-175
-176
-177
-178
-179
-180
-181
-182
-183
-184
-185
-186
-187
-188
-189
-190
-191
-192
-193
-194
-195
-196
-197
-198
-199
-200
-201
-202
-203
-204
-205
-206
-207
-208
-209
-210
-211
-212
-213
-214
-215
-216
-217
-218
-219
-220
-221
-222
-223
-224
-225
-226
-227
-228
-229
-230
-231
-232
-233
-234
-235
-236
-237
-238
-239
-240
-241
-242
-243
-244
-245
-246
-247
-248
-249
-250
-251
-252
-253
-254
-255
-256
-257
-258
-259
-260
-261
// *****************************************************************************
-/*!
-  \file      src/LinearSolver/ConjugateGradients.hpp
-  \copyright 2012-2015 J. Bakosi,
-             2016-2018 Los Alamos National Security, LLC.,
-             2019-2021 Triad National Security, LLC.
-             All rights reserved. See the LICENSE file for details.
-  \brief     Charm++ chare array for distributed conjugate gradients
-  \details   Charm++ chare array for asynchronous distributed
-    conjugate gradients linear solver.
-
-    There are a potentially large number of ConjugateGradients Charm++ chares.
-    Each ConjugateGradient chare gets a chunk of the full load, due to partiting
-    the mesh, on which the solve is performed.
-
-    The implementation uses the Charm++ runtime system and is fully
-    asynchronous, overlapping computation and communication. The algorithm
-    utilizes the structured dagger (SDAG) Charm++ functionality.
-*/
-// *****************************************************************************
-#ifndef ConjugateGradients_h
-#define ConjugateGradients_h
-
-#include "Types.hpp"
-#include "CSR.hpp"
-
-#include "NoWarning/conjugategradients.decl.h"
-
-namespace tk {
-
-//! \brief ConjugateGradients Charm++ chare array used to perform a distributed
-//!   linear solve with the conjugate gradients algorithm
-class ConjugateGradients : public CBase_ConjugateGradients {
-
-  public:
-    #if defined(__clang__)
-      #pragma clang diagnostic push
-      #pragma clang diagnostic ignored "-Wunused-parameter"
-    #elif defined(STRICT_GNUC)
-      #pragma GCC diagnostic push
-      #pragma GCC diagnostic ignored "-Wunused-parameter"
-    #endif
-    // Include Charm++ SDAG code. See http://charm.cs.illinois.edu/manuals/html/
-    // charm++/manual.html, Sec. "Structured Control Flow: Structured Dagger".
-    ConjugateGradients_SDAG_CODE
-    #if defined(__clang__)
-      #pragma clang diagnostic pop
-    #elif defined(STRICT_GNUC)
-      #pragma GCC diagnostic pop
-    #endif
-
-    //! Constructor
-    explicit ConjugateGradients(
-      const CSR& A,
-      const std::vector< tk::real >& x,
-      const std::vector< tk::real >& b,
-      const std::vector< std::size_t >& gid,
-      const std::unordered_map< std::size_t, std::size_t >& lid,
-      const NodeCommMap& nodecommmap );
-
-    #if defined(__clang__)
-      #pragma clang diagnostic push
-      #pragma clang diagnostic ignored "-Wundefined-func-template"
-    #endif
-    //! Constructor taking a tuple of {A,x,b} by rvalue reference
-    explicit ConjugateGradients(<--- Member variable 'ConjugateGradients::m_tol' is not initialized in the constructor.
-      std::tuple< tk::CSR,
-                  std::vector< tk::real >,
-                  std::vector< tk::real > >&& system,
-      const std::vector< std::size_t >& gid,
-      const std::unordered_map< std::size_t, std::size_t >& lid,
-      const NodeCommMap& nodecommmap ) :
-      ConjugateGradients( std::move(std::get<0>(system)),
-                          std::move(std::get<1>(system)),
-                          std::move(std::get<2>(system)),
-                          gid, lid, nodecommmap ) {}
-
-    //! Migrate constructor
-    explicit ConjugateGradients( CkMigrateMessage* ) {}<--- Member variable 'ConjugateGradients::m_nr' is not initialized in the constructor.<--- Member variable 'ConjugateGradients::m_nb' is not initialized in the constructor.<--- Member variable 'ConjugateGradients::m_nq' is not initialized in the constructor.<--- Member variable 'ConjugateGradients::m_normb' is not initialized in the constructor.<--- Member variable 'ConjugateGradients::m_it' is not initialized in the constructor.<--- Member variable 'ConjugateGradients::m_maxit' is not initialized in the constructor.<--- Member variable 'ConjugateGradients::m_tol' is not initialized in the constructor.<--- Member variable 'ConjugateGradients::m_rho' is not initialized in the constructor.<--- Member variable 'ConjugateGradients::m_rho0' is not initialized in the constructor.<--- Member variable 'ConjugateGradients::m_alpha' is not initialized in the constructor.<--- Member variable 'ConjugateGradients::m_converged' is not initialized in the constructor.<--- Member variable 'ConjugateGradients::m_nx' is not initialized in the constructor.
-    #if defined(__clang__)
-      #pragma clang diagnostic pop
-    #endif
-
-    //! Solve linear system
-    void solve( std::size_t maxit, tk::real tol, CkCallback c );
-
-    //! Initialize linear solve: set initial guess and boundary conditions
-    void init( const std::vector< tk::real >& x,
-               const std::vector< tk::real >& b,
-               const std::unordered_map< std::size_t,
-                       std::vector< std::pair< bool, tk::real > > >& bc,
-               std::size_t ignorebc,
-               CkCallback cb );
-
-    //! Setup solver
-    void setup( CkCallback c );
-
-    //! Compute the norm of the right hand side
-    void normb( tk::real n );
-
-    //! Compute rho = (r,r)
-    void rho( tk::real r );
-
-    //! Receive contributions to r = b - A * x on chare-boundaries
-    void comres( const std::vector< std::size_t >& gid,
-                 const std::vector< std::vector< tk::real > >& rc );
-
-    //! Receive contributions to boundary conditions on chare-boundaries
-    void combc( const std::unordered_map< std::size_t,
-                       std::vector< std::pair< bool, tk::real > > >& bc );
-
-    //! Receive contributions to q = A * p on chare-boundaries
-    void comq( const std::vector< std::size_t >& gid,
-               const std::vector< std::vector< tk::real > >& qc );
-
-    void comx( const std::vector< std::size_t >& gid,
-               const std::vector< std::vector< tk::real > >& xc );
-
-    //! Compute the dot product (p,q)
-    void pq( tk::real d );
-
-    //! Compute the norm of the residual: (r,r)
-    void normres( tk::real r );
-
-    //! Access solution
-    std::vector< tk::real > solution() const { return m_x; }
-
-    //! Return convergence flag
-    bool converged() const { return m_converged; }
-
-    /** @name Pack/unpack (Charm++ serialization) routines */
-    ///@{
-    //! \brief Pack/Unpack serialize member function
-    //! \param[in,out] p Charm++'s PUP::er serializer object reference
-    void pup( PUP::er &p ) override {
-      p | m_A;
-      p | m_x;
-      p | m_b;
-      p | m_gid;
-      p | m_lid;
-      p | m_nodeCommMap;
-      p | m_r;
-      p | m_rc;
-      p | m_nr;
-      p | m_bc;
-      p | m_bcc;
-      p | m_bcmask;
-      p | m_nb;
-      p | m_p;
-      p | m_q;
-      p | m_qc;
-      p | m_nq;
-      p | m_initres;
-      p | m_solved;
-      p | m_normb;
-      p | m_it;
-      p | m_maxit;
-      p | m_tol;
-      p | m_rho;
-      p | m_rho0;
-      p | m_alpha;
-      p | m_converged;
-      p | m_xc;
-      p | m_nx;
-    }
-    //! \brief Pack/Unpack serialize operator|
-    //! \param[in,out] p Charm++'s PUP::er serializer object reference
-    //! \param[in,out] c ConjugateGradients object reference
-    friend void operator|( PUP::er& p, ConjugateGradients& c ) { c.pup(p); }
-    ///@}
-
-  private:
-    //! Sparse matrix
-    CSR m_A;
-    //! Solution/unknown
-    std::vector< tk::real > m_x;
-    //! Right hand side
-    std::vector< tk::real > m_b;
-    //! Global node IDs
-    std::vector< std::size_t > m_gid;
-    //! Local node IDs associated to global ones
-    std::unordered_map< std::size_t, std::size_t > m_lid;
-    //! Global mesh node IDs shared with other chares associated to chare IDs
-    NodeCommMap m_nodeCommMap;
-    //! Auxiliary vector for CG solve
-    std::vector< tk::real > m_r;
-    //! Receive buffer for communication of r = b - A * x
-    std::unordered_map< std::size_t, std::vector< tk::real > > m_rc;
-    //! Counter for assembling m_r
-    std::size_t m_nr;
-    //! Dirichlet boundary conditions
-    std::unordered_map< std::size_t,
-        std::vector< std::pair< bool, tk::real > > > m_bc;
-    //! Dirichlet boundary conditions communication buffer
-    std::unordered_map< std::size_t,
-        std::vector< std::pair< bool, tk::real > > > m_bcc;
-    //! Dirichlet boundary condition mask
-    std::vector< tk::real > m_bcmask;
-    //! Counter for assembling boundary conditions
-    std::size_t m_nb;
-    //! Auxiliary vector for CG solve
-    std::vector< tk::real > m_p;
-    //! Auxiliary vector for CG solve
-    std::vector< tk::real > m_q;
-    //! Receive buffer for communication of q = A * p
-    std::unordered_map< std::size_t, std::vector< tk::real > > m_qc;
-    //! Counter for assembling m_q
-    std::size_t m_nq;
-    //! Charm++ callback to continue with when the setup is complete
-    CkCallback m_initres;
-    //! Charm++ callback to continue with when the solve is complete
-    CkCallback m_solved;
-    //! L2 norm of the right hand side
-    tk::real m_normb;
-    //! Iteration count
-    std::size_t m_it;
-    //! Max iteration count
-    std::size_t m_maxit;
-    //! Stop tolerance
-    tk::real m_tol;
-    //! Helper scalar for CG algorithm
-    tk::real m_rho;
-    //! Helper scalar for CG algorithm
-    tk::real m_rho0;
-    //! Helper scalar for CG algorithm
-    tk::real m_alpha;
-    //! Convergence flag: true if linear smoother converged to tolerance
-    bool m_converged;
-    //! Receive buffer for solution
-    std::unordered_map< std::size_t, std::vector< tk::real > > m_xc;
-    //! Counter for assembling the solution on chare boundaries
-    std::size_t m_nx;
+
   1
+   2
+   3
+   4
+   5
+   6
+   7
+   8
+   9
+  10
+  11
+  12
+  13
+  14
+  15
+  16
+  17
+  18
+  19
+  20
+  21
+  22
+  23
+  24
+  25
+  26
+  27
+  28
+  29
+  30
+  31
+  32
+  33
+  34
+  35
+  36
+  37
+  38
+  39
+  40
+  41
+  42
+  43
+  44
+  45
+  46
+  47
+  48
+  49
+  50
+  51
+  52
+  53
+  54
+  55
+  56
+  57
+  58
+  59
+  60
+  61
+  62
+  63
+  64
+  65
+  66
+  67
+  68
+  69
+  70
+  71
+  72
+  73
+  74
+  75
+  76
+  77
+  78
+  79
+  80
+  81
+  82
+  83
+  84
+  85
+  86
+  87
+  88
+  89
+  90
+  91
+  92
+  93
+  94
+  95
+  96
+  97
+  98
+  99
+ 100
+ 101
+ 102
+ 103
+ 104
+ 105
+ 106
+ 107
+ 108
+ 109
+ 110
+ 111
+ 112
+ 113
+ 114
+ 115
+ 116
+ 117
+ 118
+ 119
+ 120
+ 121
+ 122
+ 123
+ 124
+ 125
+ 126
+ 127
+ 128
+ 129
+ 130
+ 131
+ 132
+ 133
+ 134
+ 135
+ 136
+ 137
+ 138
+ 139
+ 140
+ 141
+ 142
+ 143
+ 144
+ 145
+ 146
+ 147
+ 148
+ 149
+ 150
+ 151
+ 152
+ 153
+ 154
+ 155
+ 156
+ 157
+ 158
+ 159
+ 160
+ 161
+ 162
+ 163
+ 164
+ 165
+ 166
+ 167
+ 168
+ 169
+ 170
+ 171
+ 172
+ 173
+ 174
+ 175
+ 176
+ 177
+ 178
+ 179
+ 180
+ 181
+ 182
+ 183
+ 184
+ 185
+ 186
+ 187
+ 188
+ 189
+ 190
+ 191
+ 192
+ 193
+ 194
+ 195
+ 196
+ 197
+ 198
+ 199
+ 200
+ 201
+ 202
+ 203
+ 204
+ 205
+ 206
+ 207
+ 208
+ 209
+ 210
+ 211
+ 212
+ 213
+ 214
+ 215
+ 216
+ 217
+ 218
+ 219
+ 220
+ 221
+ 222
+ 223
+ 224
+ 225
+ 226
+ 227
+ 228
+ 229
+ 230
+ 231
+ 232
+ 233
+ 234
+ 235
+ 236
+ 237
+ 238
+ 239
+ 240
+ 241
+ 242
+ 243
+ 244
+ 245
+ 246
+ 247
+ 248
+ 249
+ 250
+ 251
+ 252
+ 253
+ 254
+ 255
+ 256
+ 257
+ 258
+ 259
+ 260
+ 261
+ 262
+ 263
+ 264
+ 265
+ 266
+ 267
+ 268
+ 269
+ 270
+ 271
+ 272
+ 273
+ 274
+ 275
+ 276
+ 277
+ 278
+ 279
+ 280
+ 281
+ 282
+ 283
+ 284
+ 285
+ 286
+ 287
+ 288
+ 289
+ 290
+ 291
+ 292
+ 293
+ 294
+ 295
+ 296
+ 297
+ 298
+ 299
+ 300
+ 301
+ 302
+ 303
+ 304
+ 305
+ 306
+ 307
+ 308
+ 309
+ 310
+ 311
+ 312
+ 313
+ 314
+ 315
+ 316
+ 317
+ 318
+ 319
+ 320
+ 321
+ 322
+ 323
+ 324
+ 325
+ 326
+ 327
+ 328
+ 329
+ 330
+ 331
+ 332
+ 333
+ 334
+ 335
+ 336
+ 337
+ 338
+ 339
+ 340
+ 341
+ 342
+ 343
+ 344
+ 345
+ 346
+ 347
+ 348
+ 349
+ 350
+ 351
+ 352
+ 353
+ 354
+ 355
+ 356
+ 357
+ 358
+ 359
+ 360
+ 361
+ 362
+ 363
+ 364
+ 365
+ 366
+ 367
+ 368
+ 369
+ 370
+ 371
+ 372
+ 373
+ 374
+ 375
+ 376
+ 377
+ 378
+ 379
+ 380
+ 381
+ 382
+ 383
+ 384
+ 385
+ 386
+ 387
+ 388
+ 389
+ 390
+ 391
+ 392
+ 393
+ 394
+ 395
+ 396
+ 397
+ 398
+ 399
+ 400
+ 401
+ 402
+ 403
+ 404
+ 405
+ 406
+ 407
+ 408
+ 409
+ 410
+ 411
+ 412
+ 413
+ 414
+ 415
+ 416
+ 417
+ 418
+ 419
+ 420
+ 421
+ 422
+ 423
+ 424
+ 425
+ 426
+ 427
+ 428
+ 429
+ 430
+ 431
+ 432
+ 433
+ 434
+ 435
+ 436
+ 437
+ 438
+ 439
+ 440
+ 441
+ 442
+ 443
+ 444
+ 445
+ 446
+ 447
+ 448
+ 449
+ 450
+ 451
+ 452
+ 453
+ 454
+ 455
+ 456
+ 457
+ 458
+ 459
+ 460
+ 461
+ 462
+ 463
+ 464
+ 465
+ 466
+ 467
+ 468
+ 469
+ 470
+ 471
+ 472
+ 473
+ 474
+ 475
+ 476
+ 477
+ 478
+ 479
+ 480
+ 481
+ 482
+ 483
+ 484
+ 485
+ 486
+ 487
+ 488
+ 489
+ 490
+ 491
+ 492
+ 493
+ 494
+ 495
+ 496
+ 497
+ 498
+ 499
+ 500
+ 501
+ 502
+ 503
+ 504
+ 505
+ 506
+ 507
+ 508
+ 509
+ 510
+ 511
+ 512
+ 513
+ 514
+ 515
+ 516
+ 517
+ 518
+ 519
+ 520
+ 521
+ 522
+ 523
+ 524
+ 525
+ 526
+ 527
+ 528
+ 529
+ 530
+ 531
+ 532
+ 533
+ 534
+ 535
+ 536
+ 537
+ 538
+ 539
+ 540
+ 541
+ 542
+ 543
+ 544
+ 545
+ 546
+ 547
+ 548
+ 549
+ 550
+ 551
+ 552
+ 553
+ 554
+ 555
+ 556
+ 557
+ 558
+ 559
+ 560
+ 561
+ 562
+ 563
+ 564
+ 565
+ 566
+ 567
+ 568
+ 569
+ 570
+ 571
+ 572
+ 573
+ 574
+ 575
+ 576
+ 577
+ 578
+ 579
+ 580
+ 581
+ 582
+ 583
+ 584
+ 585
+ 586
+ 587
+ 588
+ 589
+ 590
+ 591
+ 592
+ 593
+ 594
+ 595
+ 596
+ 597
+ 598
+ 599
+ 600
+ 601
+ 602
+ 603
+ 604
+ 605
+ 606
+ 607
+ 608
+ 609
+ 610
+ 611
+ 612
+ 613
+ 614
+ 615
+ 616
+ 617
+ 618
+ 619
+ 620
+ 621
+ 622
+ 623
+ 624
+ 625
+ 626
+ 627
+ 628
+ 629
+ 630
+ 631
+ 632
+ 633
+ 634
+ 635
+ 636
+ 637
+ 638
+ 639
+ 640
+ 641
+ 642
+ 643
+ 644
+ 645
+ 646
+ 647
+ 648
+ 649
+ 650
+ 651
+ 652
+ 653
+ 654
+ 655
+ 656
+ 657
+ 658
+ 659
+ 660
+ 661
+ 662
+ 663
+ 664
+ 665
+ 666
+ 667
+ 668
+ 669
+ 670
+ 671
+ 672
+ 673
+ 674
+ 675
+ 676
+ 677
+ 678
+ 679
+ 680
+ 681
+ 682
+ 683
+ 684
+ 685
+ 686
+ 687
+ 688
+ 689
+ 690
+ 691
+ 692
+ 693
+ 694
+ 695
+ 696
+ 697
+ 698
+ 699
+ 700
+ 701
+ 702
+ 703
+ 704
+ 705
+ 706
+ 707
+ 708
+ 709
+ 710
+ 711
+ 712
+ 713
+ 714
+ 715
+ 716
+ 717
+ 718
+ 719
+ 720
+ 721
+ 722
+ 723
+ 724
+ 725
+ 726
+ 727
+ 728
+ 729
+ 730
+ 731
+ 732
+ 733
+ 734
+ 735
+ 736
+ 737
+ 738
+ 739
+ 740
+ 741
+ 742
+ 743
+ 744
+ 745
+ 746
+ 747
+ 748
+ 749
+ 750
+ 751
+ 752
+ 753
+ 754
+ 755
+ 756
+ 757
+ 758
+ 759
+ 760
+ 761
+ 762
+ 763
+ 764
+ 765
+ 766
+ 767
+ 768
+ 769
+ 770
+ 771
+ 772
+ 773
+ 774
+ 775
+ 776
+ 777
+ 778
+ 779
+ 780
+ 781
+ 782
+ 783
+ 784
+ 785
+ 786
+ 787
+ 788
+ 789
+ 790
+ 791
+ 792
+ 793
+ 794
+ 795
+ 796
+ 797
+ 798
+ 799
+ 800
+ 801
+ 802
+ 803
+ 804
+ 805
+ 806
+ 807
+ 808
+ 809
+ 810
+ 811
+ 812
+ 813
+ 814
+ 815
+ 816
+ 817
+ 818
+ 819
+ 820
+ 821
+ 822
+ 823
+ 824
+ 825
+ 826
+ 827
+ 828
+ 829
+ 830
+ 831
+ 832
+ 833
+ 834
+ 835
+ 836
+ 837
+ 838
+ 839
+ 840
+ 841
+ 842
+ 843
+ 844
+ 845
+ 846
+ 847
+ 848
+ 849
+ 850
+ 851
+ 852
+ 853
+ 854
+ 855
+ 856
+ 857
+ 858
+ 859
+ 860
+ 861
+ 862
+ 863
+ 864
+ 865
+ 866
+ 867
+ 868
+ 869
+ 870
+ 871
+ 872
+ 873
+ 874
+ 875
+ 876
+ 877
+ 878
+ 879
+ 880
+ 881
+ 882
+ 883
+ 884
+ 885
+ 886
+ 887
+ 888
+ 889
+ 890
+ 891
+ 892
+ 893
+ 894
+ 895
+ 896
+ 897
+ 898
+ 899
+ 900
+ 901
+ 902
+ 903
+ 904
+ 905
+ 906
+ 907
+ 908
+ 909
+ 910
+ 911
+ 912
+ 913
+ 914
+ 915
+ 916
+ 917
+ 918
+ 919
+ 920
+ 921
+ 922
+ 923
+ 924
+ 925
+ 926
+ 927
+ 928
+ 929
+ 930
+ 931
+ 932
+ 933
+ 934
+ 935
+ 936
+ 937
+ 938
+ 939
+ 940
+ 941
+ 942
+ 943
+ 944
+ 945
+ 946
+ 947
+ 948
+ 949
+ 950
+ 951
+ 952
+ 953
+ 954
+ 955
+ 956
+ 957
+ 958
+ 959
+ 960
+ 961
+ 962
+ 963
+ 964
+ 965
+ 966
+ 967
+ 968
+ 969
+ 970
+ 971
+ 972
+ 973
+ 974
+ 975
+ 976
+ 977
+ 978
+ 979
+ 980
+ 981
+ 982
+ 983
+ 984
+ 985
+ 986
+ 987
+ 988
+ 989
+ 990
+ 991
+ 992
+ 993
+ 994
+ 995
+ 996
+ 997
+ 998
+ 999
+1000
+1001
+1002
+1003
+1004
+1005
+1006
+1007
+1008
+1009
+1010
+1011
+1012
+1013
+1014
+1015
+1016
+1017
+1018
+1019
+1020
+1021
+1022
+1023
+1024
+1025
+1026
+1027
+1028
+1029
+1030
+1031
+1032
+1033
+1034
+1035
+1036
+1037
+1038
+1039
+1040
+1041
+1042
+1043
+1044
+1045
+1046
+1047
+1048
+1049
+1050
+1051
+1052
+1053
+1054
+1055
+1056
+1057
+1058
+1059
+1060
+1061
+1062
+1063
+1064
+1065
+1066
+1067
+1068
+1069
+1070
+1071
+1072
+1073
+1074
+1075
+1076
+1077
+1078
+1079
+1080
+1081
+1082
+1083
+1084
+1085
+1086
+1087
+1088
+1089
+1090
+1091
+1092
+1093
+1094
+1095
+1096
+1097
+1098
+1099
+1100
+1101
+1102
+1103
+1104
+1105
+1106
+1107
+1108
+1109
+1110
+1111
+1112
+1113
+1114
+1115
+1116
+1117
+1118
+1119
+1120
+1121
+1122
+1123
+1124
+1125
+1126
+1127
+1128
+1129
+1130
+1131
+1132
+1133
+1134
+1135
+1136
+1137
+1138
+1139
+1140
+1141
+1142
+1143
+1144
+1145
+1146
+1147
+1148
+1149
+1150
+1151
+1152
+1153
+1154
+1155
+1156
+1157
+1158
+1159
+1160
+1161
+1162
+1163
+1164
+1165
+1166
+1167
+1168
+1169
+1170
+1171
+1172
+1173
+1174
+1175
+1176
+1177
+1178
+1179
+1180
+1181
+1182
+1183
+1184
+1185
+1186
+1187
+1188
+1189
+1190
+1191
+1192
+1193
+1194
+1195
+1196
+1197
+1198
+1199
+1200
+1201
+1202
+1203
+1204
+1205
+1206
+1207
+1208
+1209
+1210
+1211
+1212
+1213
+1214
+1215
+1216
+1217
+1218
+1219
+1220
+1221
+1222
+1223
+1224
+1225
+1226
+1227
+1228
+1229
+1230
+1231
+1232
+1233
+1234
+1235
+1236
+1237
+1238
+1239
+1240
+1241
+1242
+1243
+1244
+1245
+1246
+1247
+1248
+1249
+1250
+1251
+1252
+1253
+1254
+1255
+1256
+1257
+1258
+1259
+1260
+1261
+1262
+1263
+1264
+1265
+1266
+1267
+1268
+1269
+1270
+1271
+1272
+1273
+1274
+1275
+1276
+1277
+1278
+1279
+1280
+1281
+1282
+1283
+1284
+1285
+1286
+1287
+1288
+1289
+1290
+1291
+1292
+1293
+1294
+1295
+1296
+1297
+1298
+1299
+1300
+1301
+1302
+1303
+1304
+1305
+1306
+1307
+1308
+1309
+1310
+1311
+1312
+1313
+1314
+1315
+1316
+1317
+1318
+1319
+1320
+1321
+1322
+1323
+1324
+1325
+1326
+1327
#ifndef AMR_refinement_h
+#define AMR_refinement_h
+
+#include <algorithm>
+
+#include "Macro.hpp"
+#include "tet_store.hpp"
+#include "node_connectivity.hpp"
+
+// TODO: make this have a base class to support multiple generator schemes
+// using the policy design pattern
+
+#if defined(STRICT_GNUC)
+  #pragma GCC diagnostic push
+  #pragma GCC diagnostic ignored "-Wunused-but-set-variable"
+#endif
+
+namespace AMR {
+
+    class refinement_t {
+        private:
+
+            size_t DEFAULT_REFINEMENT_LEVEL = 0; //TODO: Is this in the right place?
+            size_t MIN_REFINEMENT_LEVEL = DEFAULT_REFINEMENT_LEVEL;
+            // list of "intermediate" edges to be deleted
+            std::set< edge_t > delete_list;
+
+        public:
+
+            //! Default constructor for migration
+            refinement_t() {}
+
+            //! Constructor taking a user-specified max refinement level
+            refinement_t( size_t u_mrl ) :
+              MAX_REFINEMENT_LEVEL( u_mrl ) {}
+
+            size_t MAX_REFINEMENT_LEVEL;
+
+            // TODO: Document this
+            child_id_list_t generate_child_ids( tet_store_t& tet_store, size_t parent_id, size_t count = MAX_CHILDREN)
+            {
+                //return morton_id_generator_t::get_children_ids(parent_id);
+                return tet_store.generate_child_ids(parent_id, count);
+            }
+
+            /**
+             * @brief function to detect when an invalid refinement is
+             * invoked
+             *
+             * @param tet_store Tet store to use
+             * @param tet_id Id the of the tet which will be refined
+             *
+             * @return A bool stating if the tet can be validly refined
+             */
+            bool check_allowed_refinement( tet_store_t& tet_store, size_t tet_id)
+            {
+                Refinement_State& master_element = tet_store.data(tet_id);<--- Variable 'master_element' can be declared with const
+
+                // These asserts mean we never actually try refine a 1:2 or 1:4
+                assert( master_element.refinement_case !=
+                        Refinement_Case::one_to_two);
+                assert( master_element.refinement_case !=
+                        Refinement_Case::one_to_four);
+
+                // cppcheck-suppress assertWithSideEffect
+                assert( tet_store.is_active(tet_id) );
+
+                // Check this won't take us past the max refinement level
+                if (master_element.refinement_level >= MAX_REFINEMENT_LEVEL)
+                {
+                    return false;
+                }
+
+                // If we got here, we didn't detect anything which tells us not
+                // to refine
+                return true;
+            }
+
+            /**
+             * @brief Method which takes a tet id, and deduces the other
+             * parameters needed to perform a 1:2
+             *
+             * @param tet_store Tet store to use
+             * @param node_connectivity Mesh node connectivity (graph)
+             * @param tet_id The id to refine 1:2
+             */
+            void refine_one_to_two( tet_store_t& tet_store, node_connectivity_t& node_connectivity, size_t tet_id)
+            {
+                edge_list_t edge_list = tet_store.generate_edge_keys(tet_id);
+                node_pair_t nodes = find_single_refinement_nodes(tet_store,edge_list);
+                refine_one_to_two( tet_store, node_connectivity, tet_id, nodes[0], nodes[1]);
+            }
+
+/*
+            //! @brief Method which takes a tet id, and transforms arguments
+            //!   into the form needed for the main 1:2 refinement method
+            //! @param tet_id The id to refine 1:2
+            void refine_one_to_two(
+                    size_t tet_id,
+                    std::string edge_key
+            )
+            {
+                std::vector<std::string> nodes = util::split(edge_key,KEY_DELIM);
+                size_t edge_node_A_id =  std::stoul (nodes[0],nullptr,0);
+                size_t edge_node_B_id =  std::stoul (nodes[1],nullptr,0);
+                refine_one_to_two( tet_id, edge_node_A_id, edge_node_B_id);
+            }
+*/
+            /**
+             * @brief Refine a given tet id into 2 children.
+             * NOTE: Does not do any validity checking (currently?)
+             *
+             * @param tet_store Tet store to use
+             * @param node_connectivity Mesh node connectivity (graph)
+             * @param tet_id Id of tet to refine
+             * @param edge_node_A_id The first node of id of the edge which
+             * will be split
+             * @param edge_node_B_id The second node of id of the
+             * edge which will be split
+             */
+            void refine_one_to_two(
+                    tet_store_t& tet_store,
+                    node_connectivity_t& node_connectivity,
+                    size_t tet_id,
+                    size_t edge_node_A_id,
+                    size_t edge_node_B_id
+            )
+            {
+
+                trace_out << "refine_one_to_two" << std::endl;
+                if (!check_allowed_refinement(tet_store,tet_id)) return;
+
+                tet_t original_tet = tet_store.get(tet_id);
+
+                //coordinate_t original_tet_c = node_connectivity->id_to_coordinate(id);
+
+                size_t new_node_id = node_connectivity.add( edge_node_A_id, edge_node_B_id );
+
+                /// Split existing tet into two new tets
+
+                // The two new tets will be the same, but for each an edge will
+                // be cut, losing an edge  replaced by E
+
+                tet_t new_tet1;
+                tet_t new_tet2;
+
+                // Create a new tet that is based on the original
+                copy_tet(&new_tet1, &original_tet);
+
+                // Replace all node ids in tet that were pointing to A with new_node_id
+                replace_node(&new_tet1, edge_node_A_id, new_node_id);
+
+                // Create a new tet that is based on the original
+                copy_tet(&new_tet2, &original_tet);
+
+                // Replace all node ids in tet that were pointing to B with new_node_id
+                replace_node(&new_tet2, edge_node_B_id, new_node_id);
+
+                // Now, update the edge list
+
+                // Generate edges for split
+                tet_store.edge_store.split(edge_node_A_id, edge_node_B_id, new_node_id,
+                        Edge_Lock_Case::intermediate);
+
+                child_id_list_t child_list = generate_child_ids(tet_store,tet_id, 2);
+
+                size_t first_child_id = child_list[0];
+                size_t second_child_id = child_list[1];
+
+                // Add the two new tets to the system
+                size_t new_tet_id = first_child_id;
+                tet_store.add(
+                        first_child_id,
+                        new_tet1,
+                        Refinement_Case::one_to_two,
+                        tet_id
+                );
+
+                //size_t new_tet_id2 = second_child_id;
+                tet_store.add(
+                        second_child_id,
+                        new_tet2,
+                        Refinement_Case::one_to_two,
+                        tet_id
+                );
+
+                //trace_out << "1:2 DOING REFINE OF " << tet_id << ". Adding " << child_list[0] << " and " << child_list[1] << std::endl;
+
+                // This call is only needed to add a single edge, from the new
+                // node to the node on the normal to that face, but avoids
+                // directly calculating which nodes that is
+                tet_store.generate_edges(new_tet_id);
+
+                // Currently we lock one per tet, around the split node. We
+                // also need to lock the two "arms" which come out from it
+                //lock_edges_from_node(new_tet_id, new_node_id, Edge_Lock_Case::intermediate);
+                //lock_edges_from_node(new_tet_id2, new_node_id, Edge_Lock_Case::intermediate);
+
+                // Deactivate parent tet?
+                tet_store.deactivate(tet_id);
+                //lock_edges_from_node(new_node_id, Edge_Lock_Case::intermediate);
+                trace_out << "Adding " << new_node_id << " to intermediate list " << std::endl;
+                tet_store.intermediate_list.insert(new_node_id);
+            }
+
+            /**
+             * @brief Method which takes a tet id, and deduces the other
+             * parameters needed to perform a 1:4
+             *
+             * @param tet_store Tet store to use
+             * @param node_connectivity Mesh node connectivity (graph)
+             * @param tet_id The id to refine 1:4
+            */
+            void refine_one_to_four( tet_store_t& tet_store,
+                    node_connectivity_t& node_connectivity, size_t tet_id)
+            {
+                trace_out << "do refine 1:4 " << std::endl;
+                //bool face_refine = false;
+                size_t face_refine_id = 0; // FIXME: Does this need a better default
+                face_list_t face_list = tet_store.generate_face_lists(tet_id);
+
+                // Iterate over each face
+                for (size_t face = 0; face < NUM_TET_FACES; face++)
+                {
+                    int num_face_refine_edges = 0;
+
+                    face_ids_t face_ids = face_list[face];
+                    trace_out << "face ids " <<
+                        face_ids[0] << ", " <<
+                        face_ids[1] << ", " <<
+                        face_ids[2] << ", " <<
+                        std::endl;
 
-    //! Initiate computationa of dot product of two vectors
-    void dot( const std::vector< tk::real >& a,
-              const std::vector< tk::real >& b,
-              CkCallback c );
-
-    //! Initiate A * x for computing the residual, r = b - A * x
-    void residual();
-    //! Finish computing the initial residual, r = b - A * x
-    void initres();
-
-    //! Apply boundary conditions
-    void apply( CkCallback cb );
-
-    //! Initiate computing q = A * p
-    void qAp();
-    //! Finish computing q = A * p
-    void q();
-
-    //! Start next linear solver iteration
-    void next();
-
-    //! Assemble solution on chare boundaries
-    void x();
-};
-
-} // tk::
-
-#endif // ConjugateGradients_h
+                    edge_list_t face_edge_list = AMR::edge_store_t::generate_keys_from_face_ids(face_ids);
+                    // For this face list, see which ones need refining
+                    trace_out << "Looping to " << NUM_FACE_NODES << std::endl;
+                    for (size_t k = 0; k < NUM_FACE_NODES; k++)
+                    {
+                        trace_out << "nodes " << k << std::endl;
+
+                        edge_t edge = face_edge_list[k];
+                        if (tet_store.edge_store.get(edge).needs_refining == 1)
+                        {
+                            num_face_refine_edges++;
+                            trace_out << "Ref " << edge << " Num face => " << num_face_refine_edges << std::endl;
+                        }
+
+                        // Check for locked edges
+                            // This case only cares about faces with no locks
+                        if (tet_store.edge_store.lock_case(edge) != Edge_Lock_Case::unlocked)
+                        {
+                            // Abort this face
+                            trace_out << "Face has lock it's not this one " << face << std::endl;
+                            num_face_refine_edges = 0;
+                            break;
+                        }
+                        trace_out << "Num face => " << num_face_refine_edges << std::endl;
+                    }
+                    if (num_face_refine_edges >= 2)
+                    {
+                        assert(num_face_refine_edges < 4);
+                        //face_refine = true;
+                        trace_out << "Accepting face " << face << std::endl;
+                        face_refine_id = face;
+                        break;
+                    }
+                }
+
+                tet_t tet = tet_store.get(tet_id);
+                size_t opposite_offset = AMR::node_connectivity_t::face_list_opposite(face_list, face_refine_id);
+                size_t opposite_id = tet[opposite_offset];
+
+                trace_out << "1:4 tet mark id " << tet_id << std::endl;
+                trace_out << "opposite offset " << opposite_offset << std::endl;
+                trace_out << "opposite id " << opposite_id << std::endl;
+                trace_out << "face refine id " << face_refine_id << std::endl;
+                trace_out << "face list 0 " << face_list[face_refine_id][0] << std::endl;
+                trace_out << "face list 1 " << face_list[face_refine_id][1] << std::endl;
+                trace_out << "face list 2 " << face_list[face_refine_id][2] << std::endl;
+
+                refine_one_to_four(tet_store, node_connectivity, tet_id, face_list[face_refine_id], opposite_id);
+            }
+
+            /**
+             * @brief Method which takes a tet id, and deduces the other
+             * parameters needed to perform a 1:4, as a part of an 8:4 deref
+             *
+             * @param tet_store Tet store to use
+             * @param node_connectivity Mesh node connectivity (graph)
+             * @param tet_id The id to refine 1:4
+             * @param kept_edges Vector of edges to keep after deref-ref
+            */
+            void deref_refine_one_to_four( tet_store_t& tet_store,
+                    node_connectivity_t& node_connectivity, size_t tet_id,
+                    std::vector< edge_t >& kept_edges)
+            {
+                trace_out << "do refine 1:4 " << std::endl;
+                //bool face_refine = false;
+                size_t face_refine_id = 0; // FIXME: Does this need a better default
+                face_list_t face_list = tet_store.generate_face_lists(tet_id);
+
+                // Iterate over each face
+                for (size_t face = 0; face < NUM_TET_FACES; face++)
+                {
+                    int num_face_refine_edges = 0;
+
+                    face_ids_t face_ids = face_list[face];
+                    trace_out << "face ids " <<
+                        face_ids[0] << ", " <<
+                        face_ids[1] << ", " <<
+                        face_ids[2] << ", " <<
+                        std::endl;
+
+                    edge_list_t face_edge_list = AMR::edge_store_t::generate_keys_from_face_ids(face_ids);
+                    // For this face list, see which ones need refining
+                    trace_out << "Looping to " << NUM_FACE_NODES << std::endl;
+                    for (size_t k = 0; k < NUM_FACE_NODES; k++)
+                    {
+                        edge_t edge = face_edge_list[k];
+                        trace_out << "edge-nodes " << edge.get_data()[0] << "-"
+                          << edge.get_data()[1] << std::endl;
+
+                        if (tet_store.edge_store.get(edge).needs_refining == 2)
+                        {
+                            num_face_refine_edges++;
+                            trace_out << "Ref " << edge << " Num face => " << num_face_refine_edges << std::endl;
+                        }
+
+                        // Check for locked edges
+                            // This case only cares about faces with no locks
+                        if (tet_store.edge_store.lock_case(edge) != Edge_Lock_Case::unlocked)
+                        {
+                            // Abort this face
+                            trace_out << "Face has lock it's not this one " << face << std::endl;
+                            num_face_refine_edges = 0;
+                            break;
+                        }
+                        trace_out << "Num face => " << num_face_refine_edges << std::endl;
+                    }
+                    if (num_face_refine_edges >= 2)
+                    {
+                        assert(num_face_refine_edges < 4);
+                        //face_refine = true;
+                        trace_out << "Accepting face " << face << std::endl;
+                        face_refine_id = face;
+                        break;
+                    }
+                }
+
+                tet_t tet = tet_store.get(tet_id);
+                size_t opposite_offset = AMR::node_connectivity_t::face_list_opposite(face_list, face_refine_id);
+                size_t opposite_id = tet[opposite_offset];
+
+                trace_out << "1:4 tet mark id " << tet_id << std::endl;
+                trace_out << "opposite offset " << opposite_offset << std::endl;
+                trace_out << "opposite id " << opposite_id << std::endl;
+                trace_out << "face refine id " << face_refine_id << std::endl;
+                trace_out << "face list 0 " << face_list[face_refine_id][0] << std::endl;
+                trace_out << "face list 1 " << face_list[face_refine_id][1] << std::endl;
+                trace_out << "face list 2 " << face_list[face_refine_id][2] << std::endl;
+
+                // store edges that should not be removed due to the deref-ref
+                auto kept_edge_list = AMR::edge_store_t::
+                  generate_keys_from_face_ids(face_list[face_refine_id]);
+                for (size_t i=0; i<3; ++i) {
+                  kept_edges.push_back(kept_edge_list[i]);
+                }
+
+                refine_one_to_four(tet_store, node_connectivity, tet_id, face_list[face_refine_id], opposite_id);
+            }
+
+            /**
+             * @brief Refine a given tet id into 4 children.
+             * NOTE: Does not do any validity checking (currently?)
+             *
+             * @param tet_store Tet store to use
+             * @param node_connectivity Mesh node connectivity (graph)
+             * @param tet_id The id of the tet to refine
+             * @param face_ids The ids which make the face to be split
+             * @param opposite_id The remaining id which is "opposite" the
+             * split face
+             */
+            void refine_one_to_four(
+                    tet_store_t& tet_store,
+                    node_connectivity_t& node_connectivity,
+                    size_t tet_id,
+                    std::array<size_t, NUM_FACE_NODES> face_ids,
+                    size_t opposite_id
+            )
+            {
+
+                trace_out << "refine_one_to_four" << std::endl;
+                if (!check_allowed_refinement(tet_store,tet_id)) return;
+
+                trace_out << "Refining tet_id " << tet_id <<
+                    " 1:4 opposite edge " << opposite_id << std::endl;
+
+                tet_t t = tet_store.get(tet_id);
+                trace_out  << "Tet has nodes " <<
+                    t[0] << ", " <<
+                    t[1] << ", " <<
+                    t[2] << ", " <<
+                    t[3] << ", " <<
+                    std::endl;
+
+                trace_out << "face_ids " <<
+                    face_ids[0] << ", " <<
+                    face_ids[1] << ", " <<
+                    face_ids[2] << ", " <<
+                    std::endl;
+
+                size_t A = face_ids[0];
+                size_t B = face_ids[1];
+                size_t C = face_ids[2];
+                size_t D = opposite_id;
+
+                trace_out <<
+                    " A " << A <<
+                    " B " << B <<
+                    " C " << C <<
+                    " D " << D <<
+                    std::endl;
+
+                // Make new nodes
+                //coordinate_t AB_mid = node_connectivity->find_mid_point(A, B);
+                size_t AB = node_connectivity.add(A,B);
+
+                //coordinate_t AC_mid = node_connectivity->find_mid_point(A, C);
+                size_t AC = node_connectivity.add(A,C);
+
+                //coordinate_t BC_mid = node_connectivity->find_mid_point(B, C);
+                size_t BC = node_connectivity.add(B,C);
+
+                // Use nodes to update edges
+                // All added edges will be locked due to containing intermediate points
+                // Split Outer face  edges
+                tet_store.edge_store.split(A, C, AC, Edge_Lock_Case::intermediate);
+                tet_store.edge_store.split(A, B, AB, Edge_Lock_Case::intermediate);
+                tet_store.edge_store.split(B, C, BC, Edge_Lock_Case::intermediate);
+
+                // Connect D to intermediate points
+                tet_store.edge_store.generate(D, AC, Edge_Lock_Case::intermediate);
+                tet_store.edge_store.generate(D, BC, Edge_Lock_Case::intermediate);
+                tet_store.edge_store.generate(D, AB, Edge_Lock_Case::intermediate);
+                // Connect inner edges
+                tet_store.edge_store.generate(AC, BC, Edge_Lock_Case::intermediate);
+                tet_store.edge_store.generate(AC, AB, Edge_Lock_Case::intermediate);
+                tet_store.edge_store.generate(AB, BC, Edge_Lock_Case::intermediate);
+
+                // Make new Tets
+                //  This is just the node opposite the face plus each pair
+                //  of the news nodes, and the old corner
+                //  FIXME: How to find that near corner programatically?
+
+                // Hard coded solution
+                // A AC AB D
+                // AC AB BC D
+                // AC BC C D
+                // AB B BC D
+
+                size_t num_children = 4;
+                child_id_list_t child = generate_child_ids(tet_store,tet_id, num_children);
+
+                // Outsides
+                tet_store.add(child[0], {{A,  AB, AC, D}}, Refinement_Case::one_to_four, tet_id);
+                tet_store.add(child[2], {{AC, BC, C,  D}}, Refinement_Case::one_to_four, tet_id);
+                tet_store.add(child[3], {{AB, B,  BC, D}}, Refinement_Case::one_to_four, tet_id);
+
+                // Center
+                size_t center_id = child[1]; // 1 to preserve Jacobian order
+                tet_store.add(center_id, {{AC, AB, BC, D}}, Refinement_Case::one_to_four, tet_id);
+
+
+                // TODO: replace this with a more concise way to lock the correct edges
+
+                tet_store.add_center(center_id);
+                /*
+                lock_edges_from_node(child[0], AB, Edge_Lock_Case::intermediate);
+                lock_edges_from_node(child[0], AC, Edge_Lock_Case::intermediate);
+                lock_edges_from_node(child[2], AC, Edge_Lock_Case::intermediate);
+                lock_edges_from_node(child[2], BC, Edge_Lock_Case::intermediate);
+                lock_edges_from_node(child[3], AB, Edge_Lock_Case::intermediate);
+                lock_edges_from_node(child[3], BC, Edge_Lock_Case::intermediate);
+                lock_edges_from_node(center_id, AC, Edge_Lock_Case::intermediate);
+                lock_edges_from_node(center_id, AB, Edge_Lock_Case::intermediate);
+                lock_edges_from_node(center_id, BC, Edge_Lock_Case::intermediate);
+                */
+
+
+                tet_store.deactivate(tet_id);
+
+                //trace_out << "1:4 DOING REFINE OF " << tet_id << ". Adding "
+                    // << child[0] << ", "
+                    // << child[1] << ", "
+                    // << child[2] << ", "
+                    // << child[3]
+                    // << std::endl;
+
+                /*
+                lock_edges_from_node(AB, Edge_Lock_Case::intermediate);
+                lock_edges_from_node(AC, Edge_Lock_Case::intermediate);
+                lock_edges_from_node(BC, Edge_Lock_Case::intermediate);
+                */
+
+                trace_out << "Adding " << AB << " to intermediate list " << std::endl;
+                tet_store.intermediate_list.insert(AB);
+                trace_out << "Adding " << AC << " to intermediate list " << std::endl;
+                tet_store.intermediate_list.insert(AC);
+                trace_out << "Adding " << BC << " to intermediate list " << std::endl;
+                tet_store.intermediate_list.insert(BC);
+
+            }
+
+            /**
+             * @brief Refine a given tet id into 8 children.
+             * NOTE: Does not do any validity checking (currently?)
+             *
+             * @param tet_store Tet store to use
+             * @param node_connectivity Mesh node connectivity (graph)
+             * @param tet_id Id of tet to refine
+             */
+            void refine_one_to_eight( tet_store_t& tet_store,
+                    node_connectivity_t& node_connectivity, size_t tet_id)
+            {
+
+                trace_out << "refine_one_to_eight" << std::endl;
+                if (!check_allowed_refinement(tet_store,tet_id)) return;
+
+                // Split every edge into two
+                // Makes 4 tets out of the old corners and 3 near mid-points
+                // Make 4 out of the midpoints
+
+                // For Tet {ABCD} need to know all (non-repeating) node pairs
+                // {AB} {AC} {AD} {BC} {BD} {CD}
+                // This can either be hard coded, or generated with a 2d loop
+                // The loop would just be i=0..4, j=i..4
+                //
+
+
+                tet_t tet = tet_store.get(tet_id);
+
+                size_t A = tet[0];
+                size_t B = tet[1];
+                size_t C = tet[2];
+                size_t D = tet[3];
+
+                trace_out << "A " << A << " B " << B << " C " << C << " D " << D
+                    << std::endl;
+
+                // Generate pairs of nodes (i.e edges)
+                // Hard coding for now, can swap out for loop
+                //coordinate_t AB_mid = node_connectivity->find_mid_point(A,B);
+                size_t AB = node_connectivity.add(A,B);
+
+                //coordinate_t AC_mid = node_connectivity->find_mid_point(A,C);
+                size_t AC = node_connectivity.add(A,C);
+
+                //coordinate_t AD_mid = node_connectivity->find_mid_point(A,D);
+                size_t AD = node_connectivity.add(A,D);
+
+                //coordinate_t BC_mid = node_connectivity->find_mid_point(B,C);
+                size_t BC = node_connectivity.add(B,C);
+
+                //coordinate_t BD_mid = node_connectivity->find_mid_point(B,D);
+                size_t BD = node_connectivity.add(B,D);
+
+                //coordinate_t CD_mid = node_connectivity->find_mid_point(C,D);
+                size_t CD = node_connectivity.add(C,D);
+
+                // Update edges
+
+                tet_store.edge_store.split(A, C, AC, Edge_Lock_Case::unlocked);
+                tet_store.edge_store.split(A, B, AB, Edge_Lock_Case::unlocked);
+                tet_store.edge_store.split(A, D, AD, Edge_Lock_Case::unlocked);
+                tet_store.edge_store.split(B, C, BC, Edge_Lock_Case::unlocked);
+                tet_store.edge_store.split(B, D, BD, Edge_Lock_Case::unlocked);
+                tet_store.edge_store.split(C, D, CD, Edge_Lock_Case::unlocked);
+
+
+                // Outside edges for face ABC
+                tet_store.edge_store.generate(AC, BC, Edge_Lock_Case::unlocked);
+                tet_store.edge_store.generate(AC, AB, Edge_Lock_Case::unlocked);
+                tet_store.edge_store.generate(AB, BC, Edge_Lock_Case::unlocked);
+
+                // Outside edges for face ACD
+           	tet_store.edge_store.generate(AC, AD, Edge_Lock_Case::unlocked);
+                tet_store.edge_store.generate(AD, CD, Edge_Lock_Case::unlocked);
+                tet_store.edge_store.generate(AC, CD, Edge_Lock_Case::unlocked);
+
+                // Outside edges for face BCD
+                tet_store.edge_store.generate(BD, CD, Edge_Lock_Case::unlocked);
+                tet_store.edge_store.generate(BD, BC, Edge_Lock_Case::unlocked);
+                tet_store.edge_store.generate(CD, BC, Edge_Lock_Case::unlocked);
+
+                // Outside edges for face ABD
+                 tet_store.edge_store.generate(AD, BD, Edge_Lock_Case::unlocked);
+                tet_store.edge_store.generate(AB, AD, Edge_Lock_Case::unlocked);
+                tet_store.edge_store.generate(AB, BD, Edge_Lock_Case::unlocked);
+
+                // Interior Edges
+                   tet_store.edge_store.generate(AC, BD, Edge_Lock_Case::unlocked);
+                tet_store.edge_store.generate(CD, AD, Edge_Lock_Case::unlocked);
+
+                // Add the new tets
+                //
+                // External
+                // A AB AC AD - A
+                // B BA BC BD - B
+                // C CA CB CD - C
+                // D DA DB DC - D
+                // -
+                // Internal (for a face BDC, it's the intermediate and mid opposite)
+                // BC CD DB AC - BDC
+                // AB BD AD AC - ABD
+                // AB AC BC BD - ABC
+                // AC AD CD BD - ACD
+                //
+
+                // TODO: This is actually generating IDs not trying to get them
+                child_id_list_t child = generate_child_ids(tet_store,tet_id);
+
+                // This order should give a positive Jacobian
+                tet_store.add(child[0], {{A, AB, AC, AD}}, Refinement_Case::one_to_eight, tet_id);
+                tet_store.add(child[1], {{B, BC, AB, BD}}, Refinement_Case::one_to_eight, tet_id);
+                tet_store.add(child[2], {{C, AC, BC, CD}}, Refinement_Case::one_to_eight, tet_id);
+                tet_store.add(child[3], {{D, AD, CD, BD}}, Refinement_Case::one_to_eight, tet_id);
+
+                tet_store.add(child[4], {{BC, CD, AC, BD}}, Refinement_Case::one_to_eight, tet_id);
+                tet_store.add(child[5], {{AB, BD, AC, AD}}, Refinement_Case::one_to_eight, tet_id);
+                tet_store.add(child[6], {{AB, BC, AC, BD}}, Refinement_Case::one_to_eight, tet_id);
+                tet_store.add(child[7], {{AC, BD, CD, AD}}, Refinement_Case::one_to_eight, tet_id);
+
+                tet_store.deactivate(tet_id);
+
+                //trace_out << "1:8 DOING REFINE OF " << tet_id << ". "
+                    // << child[0] << ", "
+                    // << child[1] << ", "
+                    // << child[2] << ", "
+                    // << child[3] << ", "
+                    // << child[4] << ", "
+                    // << child[5] << ", "
+                    // << child[6] << ", "
+                    // << child[7]
+                    // << std::endl;
+
+            }
+
+            // This is just a simple assignment, but I wanted to abstract it
+            // for if we change the underlying type to something which a simple
+            // assignment is no longer safe
+            /**
+             * @brief Function to duplicate (deep copy) a tet. Useful for when
+             * you want to make a tet that's very similar to an existing one
+             *
+             * @param out The tet to store the copy
+             * @param original The tet to copy the data from
+             */
+            void copy_tet(tet_t* out, tet_t* original)
+            {
+                // NOTE: This will do a deep copy, so is safer than it may look
+                *out = *original;
+            }
+
+            // This is just a std::replace, but may need to be more complicated
+            // in the future?
+            /**
+             * @brief function to take an existing list of tet ids and
+             * replace one. This can be useful for when you want to build very
+             * similar tets which share nodes
+             *
+             * @param tet Tet to perform operation on
+             * @param remove Element to be replaced
+             * @param add Element to replace with
+             */
+            void replace_node(tet_t* tet, size_t remove, size_t add)
+            {
+                std::replace(tet->begin(), tet->end(), remove, add);
+            }
+
+            /**
+             * @brief Function to find out slot in the x,y,z data arrays a tet lives
+             *
+             * // NOTE: this is _currently_ trivial, but will be nice if we for
+             * example swap data stores to a map
+             *
+             * @param tet_store Tet store to use
+             * @param tet tet of the tet to look for
+             * @param element offset into that tet to look at
+             *
+             * @return tet into data arrays the tet lives
+             */
+            // TODO: Move this (or rename?)
+            size_t tet_id_to_node_id( tet_store_t& tet_store, size_t tet, size_t element) {
+                return tet_store.get(tet)[element];
+            }
+
+            /**
+             * @brief Function to find the nodes which make up the
+             * single (or first?º edge which needs to be refined in an given
+             * edge_list
+             *
+             * @param tet_store Tet store to use
+             * @param edge_list The edge list to search for a refinement edge
+             *
+             * @return The node pair which represent the edge which needs
+             * refining
+             */
+            node_pair_t find_single_refinement_nodes( tet_store_t& tet_store, edge_list_t edge_list)
+            {
+                node_pair_t returned_nodes;
+                bool found_break = false;
+                for (size_t k = 0; k < NUM_TET_EDGES; k++)
+                {
+                    edge_t edge = edge_list[k];
+
+                    if (tet_store.edge_store.get(edge).needs_refining == 1)
+                    {
+                        returned_nodes[0] = edge.first();
+                        returned_nodes[1] = edge.second();
+
+                        trace_out << "1:2 needs to be split on " <<
+                            returned_nodes[0] << " and " <<
+                            returned_nodes[1] << std::endl;
+
+                        found_break = true;
+                        break;
+                    }
+                }
+
+                assert(found_break);
+
+                return returned_nodes;
+            }
+
+            void lock_intermediates(
+                    tet_store_t& tet_store,
+                    const std::unordered_set<size_t>& intermediate_list,
+                    Edge_Lock_Case lock_case
+                )
+            {
+                // Loop over all edges
+                // If the edge is in the intermediate_list, deal with it
+                for (const auto& p : tet_store.edge_store.edges)
+                {
+                    auto e = p.first;
+                    size_t k1 = e.first();
+                    size_t k2 = e.second();
+                    // Can we make this double search cheaper?
+                    if (
+                            (intermediate_list.count(k1)) ||
+                            (intermediate_list.count(k2))
+                       )
+                    {
+                        trace_out << "Locking intermediate " << e << " from " << k1 << " and " << k2 << std::endl;
+                        tet_store.edge_store.get(e).lock_case = lock_case;
+                        tet_store.edge_store.get(e).needs_refining = 0;
+                    }
+                }
+
+            }
+
+            // TODO: remove this, it's horrible and not efficient.
+            // WARNING: THIS GOES OVER ALL TETS!!!!
+            void lock_edges_from_node(
+                    tet_store_t& tet_store,
+                    size_t node_id,
+                    Edge_Lock_Case lock_case
+            )
+            {
+                // Iterate over edges of ALL tet
+                for (const auto& kv : tet_store.tets)
+                {
+                    size_t tet_id = kv.first;
+                    edge_list_t edge_list = tet_store.generate_edge_keys(tet_id);
+                    for (size_t k = 0; k < NUM_TET_EDGES; k++)
+                    {
+                        // If it contains that node id, mark it using lock_case
+                        edge_t edge = edge_list[k];
+
+                        size_t edge_node_A_id = edge.first();
+                        size_t edge_node_B_id = edge.second();
+
+                        if ((edge_node_A_id == node_id) || (edge_node_B_id == node_id)) {
+                            trace_out << " found node in " << edge_node_A_id << " - " << edge_node_B_id << " set to " << lock_case << std::endl;
+                            tet_store.edge_store.get(edge).lock_case = lock_case;
+                            tet_store.edge_store.get(edge).needs_refining = 0;
+                        }
+                    }
+                }
+            }
+//            void lock_edges_from_node(
+//                    tet_store_t& tet_store,
+//                    size_t tet_id,
+//                    size_t node_id,
+//                    Edge_Lock_Case lock_case
+//            )
+//            {
+//                // Iterate over edges of of tet
+//                edge_list_t edge_list = tet_store.generate_edge_keys(tet_id);
+//                for (size_t k = 0; k < NUM_TET_EDGES; k++)
+//                {
+//                    // If it contains that node id, mark it using lock_case
+//                    edge_t edge = edge_list[k];
+//
+//                    size_t edge_node_A_id = edge.first();
+//                    size_t edge_node_B_id = edge.second();
+//
+//                    if ((edge_node_A_id == node_id) || (edge_node_B_id == node_id)) {
+//                        tet_store.edge_store.get(edge).lock_case = lock_case;
+//                    }
+//                }
+//            }
+
+
+            ///// DEREFINEMENT STARTS HERE /////
+            /**
+             * @brief Function to iterate over children and remove them
+             *
+             * @param tet_store Tet store to use
+             * @param parent_id Id of the parent for whom you will delete the
+             * children
+             */
+            void derefine_children(tet_store_t& tet_store, size_t parent_id)
+            {
+                // For a given tet_id, find and delete its children
+                Refinement_State& parent = tet_store.data(parent_id);
+                for (auto c : parent.children)
+                {
+                    tet_store.erase(c);
+                    //tet_store.deactivate(c);
+
+                    /*
+                    auto children = tet_store.data(c).children;
+                    // Debug printing
+                    std::cout << "tet " << c << "has ";
+                    for (auto child : children)
+                    {
+                        std::cout << " _child " << child;
+                    }
+                    std::cout << std::endl;
+                    */
+                }
+                parent.children.clear();
+            }
+
+            /**
+             * @brief Common code for derefinement. Deactives the children and
+             * actives the parent
+             *
+             * @param tet_store Tet store to use
+             * @param parent_id The id of the parent
+             */
+            void generic_derefine(tet_store_t& tet_store, size_t parent_id)
+            {
+                derefine_children(tet_store,parent_id);
+                tet_store.activate(parent_id);
+            }
+
+            /**
+             * @brief Perform 2->1 derefinement on tet
+             *
+             * @param tet_store Tet store to use
+             * @param parent_id The id of the parent
+             */
+            void derefine_two_to_one(tet_store_t& tet_store, node_connectivity_t&, size_t parent_id)
+            {
+                //if (!check_allowed_derefinement(tet_store,parent_id)) return;
+                // build a delete-list of edges/intermediates first, mesh_adapter
+                // deletes edges from this list later
+                determine_deletelist_of_intermediates(tet_store, parent_id);
+                generic_derefine(tet_store,parent_id);
+            }
+
+            /**
+             * @brief Perform 4->1 derefinement on tet
+             *
+             * @param tet_store Tet store to use
+             * @param parent_id The id of the parent
+             */
+            void derefine_four_to_one(tet_store_t& tet_store, node_connectivity_t&, size_t parent_id)
+            {
+                //if (!check_allowed_derefinement(tet_store,parent_id)) return;
+                // build a delete-list of edges/intermediates first, mesh_adapter
+                // deletes edges from this list later
+                determine_deletelist_of_intermediates(tet_store, parent_id);
+                generic_derefine(tet_store,parent_id);
+            }
+
+            /**
+             * @brief Perform 8->1 derefinement on tet
+             *
+             * @param tet_store Tet store to use
+             * @param parent_id The id of the parent
+             */
+            void derefine_eight_to_one(tet_store_t& tet_store, node_connectivity_t&, size_t parent_id)
+            {
+                //if (!check_allowed_derefinement(tet_store,parent_id)) return;
+
+                generic_derefine(tet_store,parent_id);
+
+                // TODO: Do we delete the nodes? Do we even have nodes?
+
+                // Delete the center edges
+                    // If edge isn't in the parent, delete it? Is there a better way?
+                edge_list_t parent_edges = tet_store.generate_edge_keys(parent_id);
+
+                Refinement_State& parent = tet_store.data(parent_id);<--- Variable 'parent' can be declared with const
+                for (auto c : parent.children)
+                {
+                    edge_list_t child_edges = tet_store.generate_edge_keys(c);
+                    // build a delete-list of non-matching edges first, then
+                    // mesh_adapter deletes edges from this list later
+                    determine_deletelist_of_non_matching_edges(child_edges, parent_edges);
+                }
+            }
+
+            // TODO: Document This.
+            void derefine_four_to_two(tet_store_t& tet_store, node_connectivity_t& node_connectivity, size_t parent_id)
+            {
+                //if (!check_allowed_derefinement(tet_store,parent_id)) return;
+
+                // A 4:2 (implemented as a 4:1 + 1:2) keeps three child edges,
+                // two of which are from the 1:2 splitting. The third edge
+                // connects the opposite parent node with the intermediate node
+                // (of the 1:2 splitting). Figure out which is this edge, and
+                // remove it from the delete list.
+                // 1. first store the possible edges that connect parent nodes
+                //    with the intermediate node of the 1:2. There are 2
+                //    possibilities, because we can already eliminate the
+                //    parents of the intermediate node.
+                auto edge = find_edge_not_derefined(tet_store,
+                  node_connectivity, parent_id);
+
+                std::array< edge_t, 2 > int_par_edges;
+                auto parent_tet = tet_store.get(parent_id);
+                auto npnode = node_connectivity.data().at(edge.get_data());
+                size_t icount(0);
+                for (size_t i=0; i<NUM_TET_NODES; ++i) {
+                  if (parent_tet[i] != edge.first() &&
+                    parent_tet[i] != edge.second()) {
+                    int_par_edges[icount] = edge_t(parent_tet[i], npnode);
+                    ++icount;
+                  }
+                }
+                assert(icount == 2);
+
+                // 2. find which one of these edges is present in the 4 children
+                child_id_list_t children = tet_store.data(parent_id).children;
+                bool ipedge_set = false;
+                edge_t int_par_edge;
+                for (size_t i=0; i<children.size(); i++) {
+                  edge_list_t chedge_list = tet_store.generate_edge_keys(children[i]);
+                  // Check each edge, and compare with possible edges
+                  for (size_t k=0; k<NUM_TET_EDGES; k++) {
+                    for (const auto& ipedge : int_par_edges) {
+                      if (chedge_list[k] == ipedge) {<--- Consider using std::find_if algorithm instead of a raw loop.
+                        int_par_edge = ipedge;
+                        ipedge_set = true;
+                        break;
+                      }
+                    }
+                  }
+                }
+                assert(ipedge_set);
+
+                derefine_four_to_one(tet_store, node_connectivity, parent_id);
+                refine_one_to_two( tet_store, node_connectivity, parent_id,
+                  edge.first(), edge.second() );
+
+                // remove edge not derefined from delete list
+                delete_list.erase(int_par_edge);
+                std::vector< edge_t > parent_edges;
+                parent_edges.push_back(edge);
+                remove_from_deletelist(node_connectivity, parent_edges);
+            }
+
+            // TODO: Document This.
+            void derefine_eight_to_two(tet_store_t& tet_store, node_connectivity_t& node_connectivity, size_t parent_id)
+            {
+                //if (!check_allowed_derefinement(tet_store,parent_id)) return;
+
+                auto edge = find_edge_not_derefined(tet_store,
+                  node_connectivity, parent_id);
+                derefine_eight_to_one(tet_store, node_connectivity, parent_id);
+                refine_one_to_two( tet_store, node_connectivity, parent_id,
+                  edge.first(), edge.second() );
+                // remove edge not derefined from delete list
+                std::vector< edge_t > parent_edges;
+                parent_edges.push_back(edge);
+                remove_from_deletelist(node_connectivity, parent_edges);
+            }
+
+            // TODO: Document This.
+            void derefine_eight_to_four(tet_store_t& tet_store, node_connectivity_t& node_connectivity, size_t parent_id)
+            {
+                //if (!check_allowed_derefinement(tet_store,parent_id)) return;
+                // TODO: think about if the logic for these derefs are right
+                derefine_eight_to_one(tet_store, node_connectivity, parent_id);
+                std::vector< edge_t > kept_edges;
+                deref_refine_one_to_four( tet_store, node_connectivity,
+                  parent_id, kept_edges);
+                // remove edge not derefined from delete list
+                remove_from_deletelist(node_connectivity, kept_edges);
+            }
+
+            /**
+             * @brief Loop over children and determine delete-list of all intermediate edges
+             *
+             * @param tet_store Tet store to use
+             * @param parent_id Id of parent
+             */
+            void determine_deletelist_of_intermediates(tet_store_t& tet_store, size_t parent_id)
+            {
+                Refinement_State& parent = tet_store.data(parent_id);<--- Variable 'parent' can be declared with const
+                auto parent_edges = tet_store.generate_edge_keys(parent_id);
+                std::set< edge_t > parent_edge_set;
+                for (auto pe:parent_edges) parent_edge_set.insert(pe);
+                for (auto c : parent.children)
+                {
+                    edge_list_t edge_list = tet_store.generate_edge_keys(c);
+                    for (size_t k = 0; k < NUM_TET_EDGES; k++)
+                    {
+                        edge_t edge = edge_list[k];
+                        // accept this code may try delete an edge which has already gone
+                        if (tet_store.edge_store.exists(edge)) {
+                            if (parent_edge_set.count(edge) == 0)
+                            {
+                                trace_out << "child " << c << " adding to delete list: "
+                                  << edge.first() << " - " << edge.second() << std::endl;
+                                delete_list.insert(edge);
+                            }
+                        }
+                    }
+                }
+            }
+
+            /**
+             * @brief Remove 'intermediate' edges (based on parent edges) from
+             *   delete list
+             *
+             * @param node_connectivity Node connectivity data structure
+             * @param parent_edges List of parent edges whose 'child' edges need
+             *   to be removed from the delete list
+             */
+            void remove_from_deletelist(
+              node_connectivity_t& node_connectivity,
+              const std::vector< edge_t >& parent_edges )
+            {
+              for (const auto& edge:parent_edges) {
+                auto npnode = node_connectivity.data().at(edge.get_data());
+                edge_t e1(edge.first(),npnode);
+                edge_t e2(edge.second(),npnode);
+                delete_list.erase(e1);
+                delete_list.erase(e2);
+              }
+            }
+
+            /**
+             * @brief Deletes the intermediate edge in the delete list for derefinement
+             *
+             * @param tet_store Tet store to use
+             */
+            void delete_intermediates_of_children(tet_store_t& tet_store)
+            {
+              for (const auto& edge : delete_list) {
+                tet_store.edge_store.erase(edge);
+                tet_store.intermediate_list.erase(edge.get_data()[0]);
+                tet_store.intermediate_list.erase(edge.get_data()[1]);
+              }
+
+              delete_list.clear();
+            }
+
+            /**
+             * @brief If edge in candidate is not present in basis, add edge
+             * (candidate) to delete list
+             *
+             * @param candidate The edge list which is to be searched and deleted
+             * @param basis The edge list to check against
+             */
+            void determine_deletelist_of_non_matching_edges(edge_list_t candidate,
+              edge_list_t basis)
+            {
+                trace_out << "Looking for edges to delete" << std::endl;
+
+                // TODO: Sanity check this now we changed to edge_t
+
+                // Loop over the edges in each child. Look over the basis and
+                // if we can't find it, delete it
+                for (size_t k = 0; k < NUM_TET_EDGES; k++)
+                {
+                    edge_t search_key = candidate[k];
+
+                    // Search the basis for it
+                    bool found_it = false;
+
+                    for (size_t l = 0; l < NUM_TET_EDGES; l++)
+                    {
+                        edge_t key = basis[l];
+                        if (search_key == key)
+                        {
+                            found_it = true;
+                        }
+                    }
+
+                    // If we didn't find it, delete it
+                    if (!found_it)
+                    {
+                        // Delete it
+                        //tet_store.edge_store.erase(search_key);
+                        trace_out << "adding to delete list: "
+                          << search_key.first() << " - " << search_key.second()
+                          << std::endl;
+                        delete_list.insert(search_key);
+                    }
+                }
+            }
+
+
+            /**
+             * @brief function to detect when an invalid derefinement is
+             * invoked
+             *
+             * @param tet_store Tet store to use
+             * @param tet_id Id the of the tet which will be de-refined
+             *
+             * @return A bool stating if the tet can be validly de-refined
+             */
+            bool check_allowed_derefinement( tet_store_t& tet_store, size_t tet_id)
+            {
+                Refinement_State& master_element = tet_store.data(tet_id);<--- Variable 'master_element' can be declared with const
+
+                // Check this won't take us past the max refinement level
+                if (master_element.refinement_level <= MIN_REFINEMENT_LEVEL)
+                {
+                    return false;
+                }
+
+                // If we got here, we didn't detect anything which tells us not
+                // to
+                return true;
+            }
+
+
+            // HERE BE DRAGONS! THIS IS DANGEROUS IF YOU USE IT WRONG
+            // For every child of parent_id, set his children to our won
+            // TODO: set a flag for the curious user to know we trashed the children
+            void overwrite_children(
+                    tet_store_t& tet_store,
+                    const child_id_list_t& to_be_replaced,
+                    const child_id_list_t& replace_with
+            )
+            {
+                for (auto c : to_be_replaced)
+                {
+                    tet_store.data(c).children = replace_with;
+                }
+            }
+
+            /**
+             * @brief function to detect which edge should not get derefined
+             *
+             * @param tet_store Tet store to use
+             * @param node_connectivity Node connectivity to use
+             * @param tet_id Id the of the tet which will be de-refined
+             *
+             * @return Array of size two containing nodes of required edge
+             */
+            edge_t find_edge_not_derefined(
+              tet_store_t& tet_store,
+              node_connectivity_t& node_connectivity,
+              size_t tet_id)
+            {
+              // 2 nonparent nodes set to derefine for a 4:2
+              // 5 nonparent nodes set to derefine for an 8:2
+              // will have 2 or 5 nonparent nodes set to deref; Figure out which
+              // edge is the one that is not set to deref
+
+              auto derefine_node_set = find_derefine_node_set(tet_store, tet_id);
+
+              //// Do number of points
+              //std::unordered_set<size_t> derefine_node_set;
+
+              // Find the set of nodes which are not in the parent
+              std::unordered_set<size_t> non_parent_nodes =
+                child_exclusive_nodes(tet_store, tet_id);
+
+              // from the above non_parent_nodes set and derefine_node_set,
+              // figureout which node should be removed
+              std::size_t ed_A(0), ed_B(0);
+              for (auto npn:non_parent_nodes) {
+                if (derefine_node_set.count(npn) == 0) {
+                  // we've found the node that should not be removed, now we
+                  // need to find the edge it belongs to
+                  auto nonderef_edge = node_connectivity.get(npn);
+                  ed_A = nonderef_edge[0];
+                  ed_B = nonderef_edge[1];
+                  //std::cout << "do-not-deref-APAN " << "A " << nd_edge[0]
+                  //        << " B " << nd_edge[1] << std::endl;
+                }
+              }
+
+              assert(ed_A!=ed_B);
+              edge_t nd_edge(ed_A, ed_B);
+              return nd_edge;
+            }
+
+            /**
+             * @brief function to detect what intermediate/non-parent nodes are
+             *   marked for derefinement
+             *
+             * @param tet_store Tet store to use
+             * @param tet_id Id of the tet which will be de-refined
+             *
+             * @return Set of nodes of marked for derefinement
+             */
+            std::unordered_set< size_t > find_derefine_node_set(
+              tet_store_t& tet_store,
+              size_t tet_id)
+            {
+              // Set of nodes which are not in the parent
+              std::unordered_set<size_t> non_parent_nodes =
+                child_exclusive_nodes(tet_store, tet_id);
+              std::unordered_set<size_t> derefine_node_set, unmarked_deref_node_set,
+                final_deref_node_set;
+
+              child_id_list_t children = tet_store.data(tet_id).children;
+
+              // Look at children
+              trace_out << tet_id << " Looping over " << children.size() << "children" << std::endl;
+              for (size_t i = 0; i < children.size(); i++)
+              {
+                  trace_out << "child: " << children[i] << std::endl;
+                  // TODO: Is this in element or tet ids?
+                  edge_list_t edge_list = tet_store.generate_edge_keys(children[i]);
+                  for (size_t k = 0; k < NUM_TET_EDGES; k++)
+                  {
+                      edge_t edge = edge_list[k];
+                      // TODO: where do we makr the edges that need to be derefed? parent of child?
+                      // Check each node, see if its an intermediate
+                      size_t A = edge.first();
+                      size_t B = edge.second();
+                      trace_out << "checking edge for deref " << A << " - " << B << std::endl;
+
+                      //if (tet_store.is_intermediate(A))
+                      if (non_parent_nodes.count(A) )
+                      {
+                        if (tet_store.edge_store.get(edge).needs_derefining) {
+                          trace_out << "Adding " << A << std::endl;
+                          derefine_node_set.insert(A);
+                        }
+                        else {
+                          unmarked_deref_node_set.insert(A);
+                          //trace_out << "NOT added " << A << std::endl;
+                        }
+                      }
+
+                      //if (tet_store.is_intermediate(B))
+                      if (non_parent_nodes.count(B))
+                      {
+                        if (tet_store.edge_store.get(edge).needs_derefining) {
+                          trace_out << "Adding " << B << std::endl;
+                          derefine_node_set.insert(B);
+                        }
+                        else {
+                          unmarked_deref_node_set.insert(B);
+                          //trace_out << "NOT added " << B << std::endl;
+                        }
+                      }
+                  }
+              }
+
+              //trace_out << "marked for deref: " << derefine_node_set.size() << std::endl;
+              //trace_out << "NOT marked for deref: " << unmarked_deref_node_set.size() << std::endl;
+
+              // remove nodes that are unmarked for derefinement
+              for (auto drnode : derefine_node_set) {
+                if (unmarked_deref_node_set.count(drnode) == 0) {
+                  final_deref_node_set.insert(drnode);
+                  trace_out << "Final deref node " << drnode << std::endl;
+                }
+              }
+
+              derefine_node_set = final_deref_node_set;
+              return derefine_node_set;
+            }
+
+
+            std::unordered_set<size_t> child_exclusive_nodes(tet_store_t& tet_store,
+              size_t tet_id)
+            {
+              std::unordered_set<size_t> non_parent_nodes;
+
+              // array
+              auto parent_tet = tet_store.get(tet_id);
+
+              // convert to set
+              std::unordered_set<size_t> parent_set(begin(parent_tet), end(parent_tet));
+
+              child_id_list_t children = tet_store.data(tet_id).children;
+              for (size_t i = 0; i < children.size(); i++)
+              {
+                      auto child_tet = tet_store.get( children[i] );
+
+                      // Look at nodes, if not present add to set
+                      for (std::size_t j = 0; j < NUM_TET_NODES; j++)
+                      {
+                              auto node = child_tet[j];
+                              if (parent_set.count(node) == 0)
+                              {
+                                      non_parent_nodes.insert(node);
+                              }
+                      }
+              }
+
+              trace_out <<" Found " << non_parent_nodes.size() << " non parent nodes " << std::endl;
+              return non_parent_nodes;
+
+            }
+    };
+}
+
+#if defined(STRICT_GNUC)
+  #pragma GCC diagnostic pop
+#endif
+
+#endif // guard
 
diff --git a/Debug/cppcheck/18.html b/Debug/cppcheck/18.html index 9d0988799c71..6304dcfac2cf 100644 --- a/Debug/cppcheck/18.html +++ b/Debug/cppcheck/18.html @@ -152,12 +152,12 @@
  1
@@ -265,1448 +265,112 @@ 

Cppcheck report - [

#ifndef AMR_tet_store_h
-#define AMR_tet_store_h
-
-#include <unordered_set>
-#include <vector>
-
-#include "AMR_types.hpp"
-#include "active_element_store.hpp"
-#include "master_element_store.hpp"
-#include "marked_refinements_store.hpp"
-#include "edge_store.hpp"
-#include "util.hpp"
-#include "id_generator.hpp"
+106
// *****************************************************************************
+/*!
+  \file      src/LinearSolver/CSR.hpp
+  \copyright 2012-2015 J. Bakosi,
+             2016-2018 Los Alamos National Security, LLC.,
+             2019-2021 Triad National Security, LLC.
+             All rights reserved. See the LICENSE file for details.
+  \brief     Compressed sparse row (CSR) storage for a sparse matrix
+  \details   Compressed sparse row (CSR) storage for a sparse matrix.
+*/
+// *****************************************************************************
+#ifndef CSR_h
+#define CSR_h
 
-namespace AMR {
-
-    class tet_store_t {
-        public:
-            // FIXME: Remove this (center_tets) data structure!
-                // This is a horrendous code abuse, and I'm sorry. I'm fairly
-                // certain we'll be re-writing how this detection is done and just
-                // wanted a quick-fix so I could move on :(
-            std::set<size_t> center_tets; // Store for 1:4 centers
+#include <vector>
+#include <ostream>
+
+#include "NoWarning/pup_stl.hpp"
+
+#include "Types.hpp"
+#include "CommMap.hpp"
+
+namespace tk {
 
-            std::set<size_t> delete_list; // For marking deletions in deref
-
-            AMR::active_element_store_t active_elements;
-            AMR::master_element_store_t master_elements;
-
-            std::vector< std::size_t > active_tetinpoel;
-            std::set< std::size_t > active_nodes;
-
-            AMR::id_generator_t id_generator;
+//! Compressed sparse row (CSR) storage for a sparse matrix
+class CSR {
+
+  public:
+    //! \brief Constructor: Create a CSR symmetric matrix with ncomp scalar
+    //!   components, storing only the upper triangular part
+    explicit CSR( std::size_t nc,
+                  const std::pair< std::vector< std::size_t >,
+                                   std::vector< std::size_t > >& psup );
 
-            std::unordered_set<size_t> intermediate_list;
-            // Public so it can be trivially grabbed for looping over.
-            std::vector< std::size_t > active_id_mapping;
-
-            tet_list_t tets;
-            AMR::edge_store_t edge_store;
+    //! Empty constructor for Charm++
+    explicit CSR() = default;
+
+    //! Return const reference to sparse matrix entry at a position
+    const real&
+    operator()( std::size_t row, std::size_t col, std::size_t pos=0 ) const;
 
-            // TODO: Make this (and others) private at some point
-            AMR::marked_refinements_store_t<AMR::Refinement_Case> marked_refinements;
-            AMR::marked_refinements_store_t<AMR::Derefinement_Case> marked_derefinements;
-
-            /**
-             * @brief function to return the number of tets stored
-             *
-             * @return Num of tets
-             */
-            size_t size() {
-                return tets.size();
-            }
-
-            /**
-             * @brief Helper to check if an given tet is active
-             *
-             * @param id id of the tool to check
-             *
-             * @return active status of tet
-             */
-            bool is_active(size_t id)
-            {
-                return active_elements.exists(id);
-            }
-
-            /**
-             * @brief Return refinement case for a given id
-             *
-             * @param id id to get case for
-             *
-             * @return Refinement case for id
-             */
-            Refinement_Case get_refinement_case(size_t id)
-            {
-                return data(id).refinement_case;
-            }
+    //! Return non-const reference to sparse matrix entry at a position
+    //! \see "Avoid Duplication in const and Non-const Member Function," and
+    //!   "Use const whenever possible," Scott Meyers, Effective C++, 3d ed.
+    real&
+    operator()( std::size_t row, std::size_t col, std::size_t pos=0 ) {
+      return const_cast< real& >(
+               static_cast< const CSR& >( *this ).operator()( row, col, pos ) );
+    }
+
+    //! Set Dirichlet boundary condition at a node
+    void dirichlet(
+      std::size_t i,
+      const std::vector< std::size_t >& gid = {},
+      const NodeCommMap& nodecommap = {},
+      std::size_t pos=0 );
+
+    //! Multiply CSR matrix with vector from the right: r = A * x
+    void mult( const std::vector< real >& x, std::vector< real >& r,
+               const std::vector< tk::real >& bcmask ) const;
+
+    //! Access real size of matrix
+    std::size_t rsize() const { return rnz.size()*ncomp; }
+
+    //! Access the number of scalar components per non-zero matrix entry
+    std::size_t Ncomp() const { return ncomp; }
+
+    //! Write out CSR as stored
+    std::ostream& write_stored( std::ostream &os ) const;
+    //! Write out CSR nonzero structure
+    std::ostream& write_structure( std::ostream &os ) const;
+    //! Write out CSR contribute structure
+    std::ostream& write_contribute( std::ostream &os ) const;
+    //! Write out CSR as a real matrix
+    std::ostream& write_matrix( std::ostream &os ) const;
+    //! Write out CSR in Matlab/Octave format
+    std::ostream& write_matlab( std::ostream &os ) const;
 
-            /**
-             * @brief Set value of normal
-             *
-             * @param id Id to set
-             * @param val true/false to set
-             */
-            void set_normal(size_t id, bool val)
-            {
-                data(id).normal = val;
-            }
-
-            /**
-             * @brief Get normal value for given id
-             *
-             * @param id Id of tet to check
-             *
-             * @return true/false of normal value
-             */
-            bool is_normal(size_t id)
-            {
-                // should the underlying type be bool?
-                return data(id).normal;
-            }
-
-            /**
-             * @brief set a tet as normal
-             *
-             * @param id id to set
-             */
-            void mark_normal(size_t id)
-            {
-                set_normal(id, true);
-            }
-
-            /**
-             * @brief get data for a tet from master element
-             *
-             * @param id id of tet to get
-             *
-             * @return state of the tet
-             */
-            Refinement_State& data(size_t id)
-            {
-                return master_elements.get(id);
-            }
-
-            const Refinement_State& data(size_t id) const
-            {
-                return master_elements.get(id);
-            }
-
-            /**
-             * @brief Method to insert tet into the tet store, so the
-             * underlying data structure doesn't have to be interfaced with
-             * directly
-             *
-             * @param id Id of the added tet
-             * @param t The tet element
-             */
-            void insert(size_t id, tet_t t)
-            {
-                // cppcheck-suppress assertWithSideEffect
-                assert( !exists(id) );
-                tets.insert( std::pair<size_t, tet_t>(id, t));
-            }
-
-            /**
-             * @brief Getter for tet element
-             *
-             * @param id Id of tet to get
-             *
-             * @return Copy of the tet
-             */
-            tet_t get( size_t id )
-            {
-                // cppcheck-suppress assertWithSideEffect
-                assert( exists(id) );
-                return tets.at(id);
-            }
-
-            /**
-             * @brief Function to check if a tet exists. Useful for debugging
-             * access to invalid tets, or trying to re-create a tet which
-             * already exists
-             *
-             * @param id Id of the tet to check
-             *
-             * @return Bool stating if the tet already exists
-             */
-            bool exists(size_t id)
-            {
-                auto f = tets.find(id);
-                if (f != tets.end())
-                {
-                    //trace_out << "tet " << id << " exists." << std::endl;
-                    return true;
-                }
-                return false;
-            }
-
-            /**
-             * @brief Function to store a tet from a list of nodes
-             *
-             * @param id The ID of the tetrahedron to insert
-             * @param nodes The node ids which make up the tet
-             */
-            void store_tet(size_t id, tet_t nodes) {
-
-                insert(id, nodes);
-
-                // Sanity check the storage ids
-                // (this is probably better in a function/2d loop)
-                assert( nodes[0] != nodes[1] );
-                assert( nodes[0] != nodes[2] );
-                assert( nodes[0] != nodes[3] );
-                assert( nodes[1] != nodes[2] );
-                assert( nodes[1] != nodes[3] );
-                assert( nodes[2] != nodes[3] );
-            }
-
-            /**
-             * @brief Convenience function to store a tet without first building
-             * a list
-             *
-             * @param id The ID of the tetrahedron to store
-             * @param first First Node
-             * @param second Second Node
-             * @param third Third Node
-             * @param forth Forth Node
-             */
-            void store_tet(
-                    size_t id,
-                    size_t first,
-                    size_t second,
-                    size_t third,
-                    size_t forth
-                    )
-            {
-                store_tet( id, { {first, second, third, forth} } );
-            }
-
-            void add(
-                    size_t id,
-                    const tet_t& nodes,
-                    Refinement_Case refinement_case,
-                    size_t parent_id
-            )
-            {
-
-                //std::cout << "id " << id << " parent " << parent_id << std::endl;
-
-                add_to_master(id, nodes, refinement_case, parent_id, true);
-
-                master_elements.get(id).refinement_level =
-                    master_elements.get(parent_id).refinement_level+1;
-
-                // Deal with updating parent
-                master_elements.add_child(parent_id, id);
-
-                trace_out << "Added child " << id << std::endl;
-            }
-
-            /**
-             * @brief Convenience function to add a tet to the master_elements
-             * and active_elements store
-             *
-             * @param id The ID of the tetrahedron to add
-             * @param nodes A list of the nodes which form th etet
-             * @param refinement_case The refinement case which caused this tet
-             * to be generated
-             * @param parent_id The ID of the parent tetrahedron
-             * @param has_parent True if element has a parent
-            */
-            void add_to_master(size_t id, const tet_t& nodes,
-              Refinement_Case refinement_case, size_t parent_id=0,
-              bool has_parent=false)
-            {
-                store_tet(id, nodes);
-
-                size_t refinement_level = 0;
-
-                // Add to master list
-                master_elements.add(id, refinement_case, refinement_level, parent_id, has_parent);
-
-                // The new master element should start as active
-                active_elements.add(id);
-            }
-
-            /**
-             * @brief Interface to add a tet from the original mesh (no parent)
-            */
-            void add(const tet_t& nodes, Refinement_Case refinement_case)
-            {
-                size_t id = id_generator.get_next_tet_id();
-                add_to_master(id, nodes, refinement_case);
-            }
-
-            // NOTE: this does *not* deal with edges
-            /**
-             * @brief Function to delete a tet from the tet store (useful in
-             * derefinement)
-             *
-             * @param id id of the tet to delete
-             */
-            void erase(size_t id)
-            {
-                deactivate(id);
-                master_elements.erase(id);
-                tets.erase(id);
-                // TODO: Should this update the number of children here rather than at the call site?
-            }
-
-            /**
-             * @brief Function to remove a tet from the active tet list
-             *
-             * @param id The id of the tet to deactivate
-             */
-            void deactivate(size_t id) {
-                active_elements.erase(id);
-                // TODO: For safety, should we also mark it's edges as not
-                // needing to be refined?
-            }
-
-            void activate(size_t id) {
-                if (!is_active(id) )
-                {
-                    active_elements.add(id);
-                }
-            }
-
-            /**
-             * @brief Function to add a tet to a list which maintains what is a
-             * center tet. (The need to maintain a list could be replaced by a
-             * geometric check on the tet itself)
-             *
-             * @param id Id of the tet to add
-             */
-            void add_center(size_t id)
-            {
-                // cppcheck-suppress assertWithSideEffect
-                assert( !is_center(id) );
-                center_tets.insert(id);
-            }
-
-            /**
-             * @brief function to check if a tet is a center tet in a 1:4
-             *
-             * @param id Id of the tet to check
-             *
-             * @return Bool stating if it's a center tet or not
-             */
-            bool is_center(size_t id)
-            {
-                if (center_tets.find(id) != center_tets.end())
-                {
-                    return true;
-                }
-                return false;
-            }
-
-            /**
-             * @brief Function to get a list of refinement levels, useful for
-             * vis
-             *
-             * @return Vector containing refinement levels of tets
-             */
-            std::vector< real_t > get_refinement_level_list() const
-            {
-                std::vector<real_t> refinement_level_list;
-
-                for (const auto& kv : tets)
-                {
-                    size_t element_id = kv.first;
-                    if (active_elements.exists( element_id  )) {
-                        real_t val = static_cast< tk::real >(
-                          master_elements.get(element_id).refinement_level );
-                        refinement_level_list.push_back(val);
-                    }
-                }
-
-                trace_out << "Made refinement level list of len " << refinement_level_list.size() << std::endl;
-                return refinement_level_list;
-            }
-
-            /**
-             * @brief Function to return a list of cell types, useful when
-             * invoking the vis to do coloring by cell type
-             *
-             * @return Vector listening the types of cells
-             */
-            std::vector< real_t > get_cell_type_list() const
-            {
-                std::vector<real_t> cell_type_list;
-
-                for (const auto& kv : tets)
-                {
-                    size_t element_id = kv.first;
-
-                    if (active_elements.exists( element_id  )) {
-
-                        real_t val = 0.0;
-
-                        // Be a good citizen, make this enum human readable
-                        switch (master_elements.get(element_id).refinement_case)
-                        {
-                            case Refinement_Case::one_to_two:
-                                val = 2.0;
-                                break;
-                            case Refinement_Case::one_to_four:
-                                val = 4.0;
-                                break;
-                            case Refinement_Case::one_to_eight:
-                                val = 8.0;
-                                break;
-                            case Refinement_Case::initial_grid:
-                                val = 1.0;
-                                break;
-                            // TODO: this will never actually happen, as a 2:8 currently views
-                            // itself as a 1:8 (as it did a 2:1, and a 1:8)
-                            case Refinement_Case::two_to_eight:
-                                val = 2.8;
-                                break;
-                            case Refinement_Case::four_to_eight:
-                                val = 4.8;
-                                break;
-                            case Refinement_Case::none:
-                                val = 0.0;
-                                break;
-                        }
-                        cell_type_list.push_back(val);
-                    }
-                }
-
-                trace_out << "Made cell type list of len " << cell_type_list.size() << std::endl;
-                return cell_type_list;
-            }
-
-            /**
-             * @brief The function gives a way to go back from active_inpoel to
-             * real AMR id
-             *
-             * @return A vector which hold the AMR ids of the active inpoel
-             */
-            std::vector< std::size_t >& get_active_id_mapping()
-            {
-                active_id_mapping.clear();
-
-                for (const auto& kv : tets)
-                {
-                    size_t element_id = kv.first;
-
-                    if (is_active( element_id )) {
-                        active_id_mapping.push_back( element_id );
-                    }
-                }
-
-                return active_id_mapping;
-            }
-
-            /**
-             * @brief Function to extract only the active elements from tetinpeol
-             *
-             * @return List of only active elements
-             */
-            // TODO: need equiv for m_x/m_y/m_z? Otherwise there will be
-            // useless nodes in m_x etc? (Although that's functionally fine)
-            std::vector< std::size_t >& get_active_inpoel()
-            {
-                active_tetinpoel.clear();
-                active_nodes.clear();
-
-                for (const auto& kv : tets)
-                {
-
-                    size_t element_id = kv.first;
-                    auto t = kv.second;
-
-                    if (is_active( element_id )) {
-                        active_tetinpoel.push_back( t[0] );
-                        active_tetinpoel.push_back( t[1] );
-                        active_tetinpoel.push_back( t[2] );
-                        active_tetinpoel.push_back( t[3] );
-
-                        active_nodes.insert( t[0] );
-                        active_nodes.insert( t[1] );
-                        active_nodes.insert( t[2] );
-                        active_nodes.insert( t[3] );
-                    }
-                }
-
-                return active_tetinpoel;
-            }
-
-            // TODO: These mark methods can probably be a single one to which a
-                // Refinement_Case is passed, depending on how extra edges are marked
-            /**
-             * @brief Function to mark a given tet as needing a 1:2 refinement
-             *
-             * @param tet_id The tet to mark
-             */
-            void mark_one_to_two(size_t tet_id)
-            {
-                // TODO: If none of these methods need extra markings, then
-                // change them into a single method
-                trace_out << "Mark " << tet_id << " as 1:2" << std::endl;
-                marked_refinements.add(tet_id, Refinement_Case::one_to_two);
-            }
-
-            /**
-             * @brief Mark a given tet as needing a 1:4 refinement
-             *
-             * @param tet_id The tet to mark
-             */
-            void mark_one_to_four(size_t tet_id)
-            {
-                trace_out << "Mark " << tet_id << " as 1:4" << std::endl;
-                marked_refinements.add(tet_id, Refinement_Case::one_to_four);
-            }
-
-            /**
-             * @brief Mark a given tet as needing a 2:8 refinement
-             *
-             * @param tet_id id of tet to mark
-             */
-            void mark_two_to_eight(size_t tet_id)
-            {
-                trace_out << "Mark " << tet_id << " as 2:8" << std::endl;
-                marked_refinements.add(tet_id, Refinement_Case::two_to_eight);
-            }
-
-            /**
-             * @brief Mark a given tet as needing a 4:8 refinement
-             *
-             * @param tet_id id of tet to mark
-             */
-            void mark_four_to_eight(size_t tet_id)
-            {
-                trace_out << "Mark " << tet_id << " as 4:8" << std::endl;
-                marked_refinements.add(tet_id, Refinement_Case::four_to_eight);
-            }
-
-            /**
-             * @brief Function to mark a given tet as needing a 1:8 refinement
-             *
-             * @param tet_id The tet to mark
-             */
-            void mark_one_to_eight(size_t tet_id)
-            {
-                trace_out << "Mark " << tet_id << " as 1:8" << std::endl;
-                marked_refinements.add(tet_id, Refinement_Case::one_to_eight);
-            }
-
-            bool has_refinement_decision(size_t id)
-            {
-                return marked_refinements.exists(id);
-            }
-
-            /**
-             * @brief Helper debug function to print tet information
-             */
-            void print_tets() {
-                for (const auto& kv : tets)
-                {
-                    tet_t tet = kv.second;
-
-                    trace_out << "Tet " << kv.first << " has edges :" <<
-                        tet[0] << ", " <<
-                        tet[1] << ", " <<
-                        tet[2] << ", " <<
-                        tet[3] << ", " <<
-                    std::endl;
-                }
-            }
-
-            void print_edges()
-            {
-                edge_store.print();
-            }
-
-            void print_node_types()
-            {
-
-                int initial_grid = 0;
-                int one_to_two = 0;
-                int one_to_four = 0;
-                int one_to_eight = 0;
-                int other = 0;
-
-                for (const auto& kv : tets)
-                {
-                    size_t tet_id = kv.first;
-                    if (is_active(tet_id))
-                    {
-                        switch(get_refinement_case(tet_id))
-                        {
-                            case Refinement_Case::one_to_two:
-                                one_to_two++;
-                                break;
-                            case Refinement_Case::one_to_four:
-                                one_to_four++;
-                                break;
-                            case Refinement_Case::one_to_eight:
-                                one_to_eight++;
-                                break;
-                            case Refinement_Case::initial_grid:
-                                initial_grid++;
-                                break;
-                            case Refinement_Case::two_to_eight:
-                                // Don't care (yet)
-                                other++;
-                                break;
-                            case Refinement_Case::four_to_eight:
-                                // Don't care (yet)
-                                other++;
-                                break;
-                            case Refinement_Case::none:
-                                // Don't care (yet)
-                                other++;
-                                break;
-                        }
-
-                    }
-                }
-
-                //std::cout << "Active Totals:" << std::endl;
-                //std::cout << "  --> Initial = " << initial_grid << std::endl;
-                //std::cout << "  --> 1:2 = " << one_to_two << std::endl;
-                //std::cout << "  --> 1:4 = " << one_to_four << std::endl;
-                //std::cout << "  --> 1:8 = " << one_to_eight << std::endl;
-            }
-
-            edge_list_t generate_edge_keys(size_t tet_id)
-            {
-                tet_t tet = get(tet_id);
-                return edge_store.generate_keys(tet);
-            }
-
-            void generate_edges(size_t i) {
-                //  For tet ABCD, edges are:
-                //  AB, AC, AD, BC, BD, CD
-                //
-                edge_list_t edge_list = generate_edge_keys(i);
-
-                for (size_t j = 0; j < NUM_TET_EDGES; j++)
-                {
-                    edge_t edge = edge_list[j];
-
-                    size_t A = edge.first();
-                    size_t B = edge.second();
-
-                    Edge_Refinement er = Edge_Refinement(A, B, false,
-                            false, Edge_Lock_Case::unlocked);
-
-                    edge_store.add(edge, er);
-                }
-            }
-
-            /**
-             * @brief function to take a tet_id, finds it's nodes, and
-             * expresses them as faces
-             *
-             * Take tet ABCD, generate faces {ABC, ABD, ACD, BCD}
-             *
-             * @param tet_id The tet to generate faces for
-             *
-             * @return A list of faces making this tet
-             */
-            face_list_t generate_face_lists(size_t tet_id)
-            {
-                // Hard code this for now...
-                tet_t tet = get(tet_id);
-
-                trace_out  << "Tet has nodes " <<
-                    tet[0] << ", " <<
-                    tet[1] << ", " <<
-                    tet[2] << ", " <<
-                    tet[3] << ", " <<
-                    std::endl;
-
-                face_list_t face_list;
-
-                // ABC
-                face_list[0][0] = tet[0];
-                face_list[0][1] = tet[1];
-                face_list[0][2] = tet[2];
-
-                // ABD
-                face_list[1][0] = tet[0];
-                face_list[1][1] = tet[3];
-                face_list[1][2] = tet[1];
-
-                // ACD
-                face_list[2][0] = tet[0];
-                face_list[2][1] = tet[2];
-                face_list[2][2] = tet[3];
-
-                // BCD
-                face_list[3][0] = tet[1];
-                face_list[3][1] = tet[3];
-                face_list[3][2] = tet[2];
-
-                return face_list;
-            }
-
-            /**
-             * @brief Function which marks all edges in a given tet as needing
-             * to be refined
-             *
-             * @param tet_id ID of the tet to mark
-             */
-            void mark_edges_for_refinement(size_t tet_id)
-            {
-                edge_list_t edge_list = generate_edge_keys(tet_id);
-                for (size_t k = 0; k < NUM_TET_EDGES; k++)
-                {
-                    edge_t edge = edge_list[k];
-                    edge_store.mark_for_refinement(edge);
-                    trace_out << "Marking edge " << edge << " for refine " << std::endl;
-                }
-            }
-
-            /**
-             * @brief Delete existing edges. Iterate over the tets, and add them to
-             * the edge store.
-             */
-            // FIXME: Better name for this?
-            void generate_edges() {
-
-                // Go over tets, and generate all known edges
-                edge_store.edges.clear();
-
-                // Jump over tets
-                for (const auto& kv : tets)
-                {
-                    size_t tet_id = kv.first;
-                    generate_edges(tet_id);
-                }
-            }
-
-            void unset_marked_children(size_t parent_id)
-            {
-                Refinement_State& parent = data(parent_id);<--- Variable 'parent' can be declared with const
-                for (auto c : parent.children)
-                {
-                    marked_refinements.erase(c);
-                }
-            }
-
-            child_id_list_t generate_child_ids(size_t parent_id, size_t count = MAX_CHILDREN)
-            {
-                return id_generator.generate_child_ids(parent_id, count);
-            }
-            size_t get_child_id(size_t parent_id, size_t offset) const
-            {
-                return master_elements.get_child_id(parent_id, offset);
-            }
-
-            size_t get_parent_id(size_t id) const
-            {
-                return master_elements.get_parent(id);
-            }
-
-            // Deref
-            void process_delete_list()
-            {
-                trace_out << "process_delete_list " << delete_list.size() << std::endl;
-                size_t original_size = size();
-                for(auto f : delete_list) {
-                    erase(f);
-                }
-
-                size_t end_size = size();
-                trace_out << "Deleted " << original_size-end_size << std::endl;
-
-                delete_list.clear();
-            }
-            /**
-             * @brief Function to mark a given tet as a specific Derefinement_Case
-             *
-             * @param tet_id The tet to mark
-             * @param decision The Derefinement_case to set
-             */
-            void mark_derefinement_decision(size_t tet_id, AMR::Derefinement_Case decision)
-            {
-                trace_out << "MARKING_DEREF_DECISION" << std::endl;
-                marked_derefinements.add(tet_id, decision);
-            }
-            bool has_derefinement_decision(size_t id)
-            {
-                return marked_derefinements.exists(id);
-            }
-
-    };
-}
-
-#endif // guard
+    /** @name Pack/unpack (Charm++ serialization) routines */
+    ///@{
+    //! \brief Pack/Unpack serialize member function
+    //! \param[in,out] p Charm++'s PUP::er serializer object reference
+    void pup( PUP::er &p ) {<--- Parameter 'p' can be declared with const
+      p | ncomp;
+      p | rnz;
+      p | ia;
+      p | ja;
+      p | a;
+    }
+    //! \brief Pack/Unpack serialize operator|
+    //! \param[in,out] p Charm++'s PUP::er serializer object reference
+    //! \param[in,out] c CSR object reference
+    friend void operator|( PUP::er& p, CSR& c ) { c.pup(p); }
+    ///@}
+
+  private:
+    std::size_t ncomp;                  //!< Number of scalars per non-zero
+    std::vector< std::size_t > rnz;     //!< Number of nonzeros in each row
+    std::vector< std::size_t > ia;      //!< Row pointers
+    std::vector< std::size_t > ja;      //!< Column indices
+    std::vector< real > a;              //!< Nonzero matrix values
+};
+
+} // tk::
+
+#endif // CSR_h
 
diff --git a/Debug/cppcheck/19.html b/Debug/cppcheck/19.html index c60499f7d343..61b7efdd9343 100644 --- a/Debug/cppcheck/19.html +++ b/Debug/cppcheck/19.html @@ -152,12 +152,12 @@
  1
@@ -265,112 +265,1448 @@ 

Cppcheck report - [

// *****************************************************************************
-/*!
-  \file      src/LinearSolver/CSR.hpp
-  \copyright 2012-2015 J. Bakosi,
-             2016-2018 Los Alamos National Security, LLC.,
-             2019-2021 Triad National Security, LLC.
-             All rights reserved. See the LICENSE file for details.
-  \brief     Compressed sparse row (CSR) storage for a sparse matrix
-  \details   Compressed sparse row (CSR) storage for a sparse matrix.
-*/
-// *****************************************************************************
-#ifndef CSR_h
-#define CSR_h
+106
+107
+108
+109
+110
+111
+112
+113
+114
+115
+116
+117
+118
+119
+120
+121
+122
+123
+124
+125
+126
+127
+128
+129
+130
+131
+132
+133
+134
+135
+136
+137
+138
+139
+140
+141
+142
+143
+144
+145
+146
+147
+148
+149
+150
+151
+152
+153
+154
+155
+156
+157
+158
+159
+160
+161
+162
+163
+164
+165
+166
+167
+168
+169
+170
+171
+172
+173
+174
+175
+176
+177
+178
+179
+180
+181
+182
+183
+184
+185
+186
+187
+188
+189
+190
+191
+192
+193
+194
+195
+196
+197
+198
+199
+200
+201
+202
+203
+204
+205
+206
+207
+208
+209
+210
+211
+212
+213
+214
+215
+216
+217
+218
+219
+220
+221
+222
+223
+224
+225
+226
+227
+228
+229
+230
+231
+232
+233
+234
+235
+236
+237
+238
+239
+240
+241
+242
+243
+244
+245
+246
+247
+248
+249
+250
+251
+252
+253
+254
+255
+256
+257
+258
+259
+260
+261
+262
+263
+264
+265
+266
+267
+268
+269
+270
+271
+272
+273
+274
+275
+276
+277
+278
+279
+280
+281
+282
+283
+284
+285
+286
+287
+288
+289
+290
+291
+292
+293
+294
+295
+296
+297
+298
+299
+300
+301
+302
+303
+304
+305
+306
+307
+308
+309
+310
+311
+312
+313
+314
+315
+316
+317
+318
+319
+320
+321
+322
+323
+324
+325
+326
+327
+328
+329
+330
+331
+332
+333
+334
+335
+336
+337
+338
+339
+340
+341
+342
+343
+344
+345
+346
+347
+348
+349
+350
+351
+352
+353
+354
+355
+356
+357
+358
+359
+360
+361
+362
+363
+364
+365
+366
+367
+368
+369
+370
+371
+372
+373
+374
+375
+376
+377
+378
+379
+380
+381
+382
+383
+384
+385
+386
+387
+388
+389
+390
+391
+392
+393
+394
+395
+396
+397
+398
+399
+400
+401
+402
+403
+404
+405
+406
+407
+408
+409
+410
+411
+412
+413
+414
+415
+416
+417
+418
+419
+420
+421
+422
+423
+424
+425
+426
+427
+428
+429
+430
+431
+432
+433
+434
+435
+436
+437
+438
+439
+440
+441
+442
+443
+444
+445
+446
+447
+448
+449
+450
+451
+452
+453
+454
+455
+456
+457
+458
+459
+460
+461
+462
+463
+464
+465
+466
+467
+468
+469
+470
+471
+472
+473
+474
+475
+476
+477
+478
+479
+480
+481
+482
+483
+484
+485
+486
+487
+488
+489
+490
+491
+492
+493
+494
+495
+496
+497
+498
+499
+500
+501
+502
+503
+504
+505
+506
+507
+508
+509
+510
+511
+512
+513
+514
+515
+516
+517
+518
+519
+520
+521
+522
+523
+524
+525
+526
+527
+528
+529
+530
+531
+532
+533
+534
+535
+536
+537
+538
+539
+540
+541
+542
+543
+544
+545
+546
+547
+548
+549
+550
+551
+552
+553
+554
+555
+556
+557
+558
+559
+560
+561
+562
+563
+564
+565
+566
+567
+568
+569
+570
+571
+572
+573
+574
+575
+576
+577
+578
+579
+580
+581
+582
+583
+584
+585
+586
+587
+588
+589
+590
+591
+592
+593
+594
+595
+596
+597
+598
+599
+600
+601
+602
+603
+604
+605
+606
+607
+608
+609
+610
+611
+612
+613
+614
+615
+616
+617
+618
+619
+620
+621
+622
+623
+624
+625
+626
+627
+628
+629
+630
+631
+632
+633
+634
+635
+636
+637
+638
+639
+640
+641
+642
+643
+644
+645
+646
+647
+648
+649
+650
+651
+652
+653
+654
+655
+656
+657
+658
+659
+660
+661
+662
+663
+664
+665
+666
+667
+668
+669
+670
+671
+672
+673
+674
+675
+676
+677
+678
+679
+680
+681
+682
+683
+684
+685
+686
+687
+688
+689
+690
+691
+692
+693
+694
+695
+696
+697
+698
+699
+700
+701
+702
+703
+704
+705
+706
+707
+708
+709
+710
+711
+712
+713
+714
+715
+716
+717
+718
+719
+720
+721
+722
+723
+724
+725
+726
+727
+728
+729
+730
+731
+732
+733
+734
+735
+736
+737
+738
+739
+740
+741
+742
+743
+744
+745
+746
+747
+748
+749
+750
+751
+752
+753
+754
+755
+756
+757
+758
+759
+760
+761
+762
+763
+764
+765
+766
+767
+768
+769
+770
+771
+772
+773
+774
#ifndef AMR_tet_store_h
+#define AMR_tet_store_h
+
+#include <unordered_set>
+#include <vector>
+
+#include "AMR_types.hpp"
+#include "active_element_store.hpp"
+#include "master_element_store.hpp"
+#include "marked_refinements_store.hpp"
+#include "edge_store.hpp"
+#include "util.hpp"
+#include "id_generator.hpp"
 
-#include <vector>
-#include <ostream>
-
-#include "NoWarning/pup_stl.hpp"
-
-#include "Types.hpp"
-#include "CommMap.hpp"
-
-namespace tk {
+namespace AMR {
+
+    class tet_store_t {
+        public:
+            // FIXME: Remove this (center_tets) data structure!
+                // This is a horrendous code abuse, and I'm sorry. I'm fairly
+                // certain we'll be re-writing how this detection is done and just
+                // wanted a quick-fix so I could move on :(
+            std::set<size_t> center_tets; // Store for 1:4 centers
 
-//! Compressed sparse row (CSR) storage for a sparse matrix
-class CSR {
-
-  public:
-    //! \brief Constructor: Create a CSR symmetric matrix with ncomp scalar
-    //!   components, storing only the upper triangular part
-    explicit CSR( std::size_t nc,
-                  const std::pair< std::vector< std::size_t >,
-                                   std::vector< std::size_t > >& psup );
+            std::set<size_t> delete_list; // For marking deletions in deref
+
+            AMR::active_element_store_t active_elements;
+            AMR::master_element_store_t master_elements;
+
+            std::vector< std::size_t > active_tetinpoel;
+            std::set< std::size_t > active_nodes;
+
+            AMR::id_generator_t id_generator;
 
-    //! Empty constructor for Charm++
-    explicit CSR() = default;
-
-    //! Return const reference to sparse matrix entry at a position
-    const real&
-    operator()( std::size_t row, std::size_t col, std::size_t pos=0 ) const;
+            std::unordered_set<size_t> intermediate_list;
+            // Public so it can be trivially grabbed for looping over.
+            std::vector< std::size_t > active_id_mapping;
+
+            tet_list_t tets;
+            AMR::edge_store_t edge_store;
 
-    //! Return non-const reference to sparse matrix entry at a position
-    //! \see "Avoid Duplication in const and Non-const Member Function," and
-    //!   "Use const whenever possible," Scott Meyers, Effective C++, 3d ed.
-    real&
-    operator()( std::size_t row, std::size_t col, std::size_t pos=0 ) {
-      return const_cast< real& >(
-               static_cast< const CSR& >( *this ).operator()( row, col, pos ) );
-    }
-
-    //! Set Dirichlet boundary condition at a node
-    void dirichlet(
-      std::size_t i,
-      const std::vector< std::size_t >& gid = {},
-      const NodeCommMap& nodecommap = {},
-      std::size_t pos=0 );
-
-    //! Multiply CSR matrix with vector from the right: r = A * x
-    void mult( const std::vector< real >& x, std::vector< real >& r,
-               const std::vector< tk::real >& bcmask ) const;
-
-    //! Access real size of matrix
-    std::size_t rsize() const { return rnz.size()*ncomp; }
-
-    //! Access the number of scalar components per non-zero matrix entry
-    std::size_t Ncomp() const { return ncomp; }
-
-    //! Write out CSR as stored
-    std::ostream& write_stored( std::ostream &os ) const;
-    //! Write out CSR nonzero structure
-    std::ostream& write_structure( std::ostream &os ) const;
-    //! Write out CSR contribute structure
-    std::ostream& write_contribute( std::ostream &os ) const;
-    //! Write out CSR as a real matrix
-    std::ostream& write_matrix( std::ostream &os ) const;
-    //! Write out CSR in Matlab/Octave format
-    std::ostream& write_matlab( std::ostream &os ) const;
+            // TODO: Make this (and others) private at some point
+            AMR::marked_refinements_store_t<AMR::Refinement_Case> marked_refinements;
+            AMR::marked_refinements_store_t<AMR::Derefinement_Case> marked_derefinements;
+
+            /**
+             * @brief function to return the number of tets stored
+             *
+             * @return Num of tets
+             */
+            size_t size() {
+                return tets.size();
+            }
+
+            /**
+             * @brief Helper to check if an given tet is active
+             *
+             * @param id id of the tool to check
+             *
+             * @return active status of tet
+             */
+            bool is_active(size_t id)
+            {
+                return active_elements.exists(id);
+            }
+
+            /**
+             * @brief Return refinement case for a given id
+             *
+             * @param id id to get case for
+             *
+             * @return Refinement case for id
+             */
+            Refinement_Case get_refinement_case(size_t id)
+            {
+                return data(id).refinement_case;
+            }
 
-    /** @name Pack/unpack (Charm++ serialization) routines */
-    ///@{
-    //! \brief Pack/Unpack serialize member function
-    //! \param[in,out] p Charm++'s PUP::er serializer object reference
-    void pup( PUP::er &p ) {<--- Parameter 'p' can be declared with const
-      p | ncomp;
-      p | rnz;
-      p | ia;
-      p | ja;
-      p | a;
-    }
-    //! \brief Pack/Unpack serialize operator|
-    //! \param[in,out] p Charm++'s PUP::er serializer object reference
-    //! \param[in,out] c CSR object reference
-    friend void operator|( PUP::er& p, CSR& c ) { c.pup(p); }
-    ///@}
-
-  private:
-    std::size_t ncomp;                  //!< Number of scalars per non-zero
-    std::vector< std::size_t > rnz;     //!< Number of nonzeros in each row
-    std::vector< std::size_t > ia;      //!< Row pointers
-    std::vector< std::size_t > ja;      //!< Column indices
-    std::vector< real > a;              //!< Nonzero matrix values
-};
-
-} // tk::
-
-#endif // CSR_h
+            /**
+             * @brief Set value of normal
+             *
+             * @param id Id to set
+             * @param val true/false to set
+             */
+            void set_normal(size_t id, bool val)
+            {
+                data(id).normal = val;
+            }
+
+            /**
+             * @brief Get normal value for given id
+             *
+             * @param id Id of tet to check
+             *
+             * @return true/false of normal value
+             */
+            bool is_normal(size_t id)
+            {
+                // should the underlying type be bool?
+                return data(id).normal;
+            }
+
+            /**
+             * @brief set a tet as normal
+             *
+             * @param id id to set
+             */
+            void mark_normal(size_t id)
+            {
+                set_normal(id, true);
+            }
+
+            /**
+             * @brief get data for a tet from master element
+             *
+             * @param id id of tet to get
+             *
+             * @return state of the tet
+             */
+            Refinement_State& data(size_t id)
+            {
+                return master_elements.get(id);
+            }
+
+            const Refinement_State& data(size_t id) const
+            {
+                return master_elements.get(id);
+            }
+
+            /**
+             * @brief Method to insert tet into the tet store, so the
+             * underlying data structure doesn't have to be interfaced with
+             * directly
+             *
+             * @param id Id of the added tet
+             * @param t The tet element
+             */
+            void insert(size_t id, tet_t t)
+            {
+                // cppcheck-suppress assertWithSideEffect
+                assert( !exists(id) );
+                tets.insert( std::pair<size_t, tet_t>(id, t));
+            }
+
+            /**
+             * @brief Getter for tet element
+             *
+             * @param id Id of tet to get
+             *
+             * @return Copy of the tet
+             */
+            tet_t get( size_t id )
+            {
+                // cppcheck-suppress assertWithSideEffect
+                assert( exists(id) );
+                return tets.at(id);
+            }
+
+            /**
+             * @brief Function to check if a tet exists. Useful for debugging
+             * access to invalid tets, or trying to re-create a tet which
+             * already exists
+             *
+             * @param id Id of the tet to check
+             *
+             * @return Bool stating if the tet already exists
+             */
+            bool exists(size_t id)
+            {
+                auto f = tets.find(id);
+                if (f != tets.end())
+                {
+                    //trace_out << "tet " << id << " exists." << std::endl;
+                    return true;
+                }
+                return false;
+            }
+
+            /**
+             * @brief Function to store a tet from a list of nodes
+             *
+             * @param id The ID of the tetrahedron to insert
+             * @param nodes The node ids which make up the tet
+             */
+            void store_tet(size_t id, tet_t nodes) {
+
+                insert(id, nodes);
+
+                // Sanity check the storage ids
+                // (this is probably better in a function/2d loop)
+                assert( nodes[0] != nodes[1] );
+                assert( nodes[0] != nodes[2] );
+                assert( nodes[0] != nodes[3] );
+                assert( nodes[1] != nodes[2] );
+                assert( nodes[1] != nodes[3] );
+                assert( nodes[2] != nodes[3] );
+            }
+
+            /**
+             * @brief Convenience function to store a tet without first building
+             * a list
+             *
+             * @param id The ID of the tetrahedron to store
+             * @param first First Node
+             * @param second Second Node
+             * @param third Third Node
+             * @param forth Forth Node
+             */
+            void store_tet(
+                    size_t id,
+                    size_t first,
+                    size_t second,
+                    size_t third,
+                    size_t forth
+                    )
+            {
+                store_tet( id, { {first, second, third, forth} } );
+            }
+
+            void add(
+                    size_t id,
+                    const tet_t& nodes,
+                    Refinement_Case refinement_case,
+                    size_t parent_id
+            )
+            {
+
+                //std::cout << "id " << id << " parent " << parent_id << std::endl;
+
+                add_to_master(id, nodes, refinement_case, parent_id, true);
+
+                master_elements.get(id).refinement_level =
+                    master_elements.get(parent_id).refinement_level+1;
+
+                // Deal with updating parent
+                master_elements.add_child(parent_id, id);
+
+                trace_out << "Added child " << id << std::endl;
+            }
+
+            /**
+             * @brief Convenience function to add a tet to the master_elements
+             * and active_elements store
+             *
+             * @param id The ID of the tetrahedron to add
+             * @param nodes A list of the nodes which form th etet
+             * @param refinement_case The refinement case which caused this tet
+             * to be generated
+             * @param parent_id The ID of the parent tetrahedron
+             * @param has_parent True if element has a parent
+            */
+            void add_to_master(size_t id, const tet_t& nodes,
+              Refinement_Case refinement_case, size_t parent_id=0,
+              bool has_parent=false)
+            {
+                store_tet(id, nodes);
+
+                size_t refinement_level = 0;
+
+                // Add to master list
+                master_elements.add(id, refinement_case, refinement_level, parent_id, has_parent);
+
+                // The new master element should start as active
+                active_elements.add(id);
+            }
+
+            /**
+             * @brief Interface to add a tet from the original mesh (no parent)
+            */
+            void add(const tet_t& nodes, Refinement_Case refinement_case)
+            {
+                size_t id = id_generator.get_next_tet_id();
+                add_to_master(id, nodes, refinement_case);
+            }
+
+            // NOTE: this does *not* deal with edges
+            /**
+             * @brief Function to delete a tet from the tet store (useful in
+             * derefinement)
+             *
+             * @param id id of the tet to delete
+             */
+            void erase(size_t id)
+            {
+                deactivate(id);
+                master_elements.erase(id);
+                tets.erase(id);
+                // TODO: Should this update the number of children here rather than at the call site?
+            }
+
+            /**
+             * @brief Function to remove a tet from the active tet list
+             *
+             * @param id The id of the tet to deactivate
+             */
+            void deactivate(size_t id) {
+                active_elements.erase(id);
+                // TODO: For safety, should we also mark it's edges as not
+                // needing to be refined?
+            }
+
+            void activate(size_t id) {
+                if (!is_active(id) )
+                {
+                    active_elements.add(id);
+                }
+            }
+
+            /**
+             * @brief Function to add a tet to a list which maintains what is a
+             * center tet. (The need to maintain a list could be replaced by a
+             * geometric check on the tet itself)
+             *
+             * @param id Id of the tet to add
+             */
+            void add_center(size_t id)
+            {
+                // cppcheck-suppress assertWithSideEffect
+                assert( !is_center(id) );
+                center_tets.insert(id);
+            }
+
+            /**
+             * @brief function to check if a tet is a center tet in a 1:4
+             *
+             * @param id Id of the tet to check
+             *
+             * @return Bool stating if it's a center tet or not
+             */
+            bool is_center(size_t id)
+            {
+                if (center_tets.find(id) != center_tets.end())
+                {
+                    return true;
+                }
+                return false;
+            }
+
+            /**
+             * @brief Function to get a list of refinement levels, useful for
+             * vis
+             *
+             * @return Vector containing refinement levels of tets
+             */
+            std::vector< real_t > get_refinement_level_list() const
+            {
+                std::vector<real_t> refinement_level_list;
+
+                for (const auto& kv : tets)
+                {
+                    size_t element_id = kv.first;
+                    if (active_elements.exists( element_id  )) {
+                        real_t val = static_cast< tk::real >(
+                          master_elements.get(element_id).refinement_level );
+                        refinement_level_list.push_back(val);
+                    }
+                }
+
+                trace_out << "Made refinement level list of len " << refinement_level_list.size() << std::endl;
+                return refinement_level_list;
+            }
+
+            /**
+             * @brief Function to return a list of cell types, useful when
+             * invoking the vis to do coloring by cell type
+             *
+             * @return Vector listening the types of cells
+             */
+            std::vector< real_t > get_cell_type_list() const
+            {
+                std::vector<real_t> cell_type_list;
+
+                for (const auto& kv : tets)
+                {
+                    size_t element_id = kv.first;
+
+                    if (active_elements.exists( element_id  )) {
+
+                        real_t val = 0.0;
+
+                        // Be a good citizen, make this enum human readable
+                        switch (master_elements.get(element_id).refinement_case)
+                        {
+                            case Refinement_Case::one_to_two:
+                                val = 2.0;
+                                break;
+                            case Refinement_Case::one_to_four:
+                                val = 4.0;
+                                break;
+                            case Refinement_Case::one_to_eight:
+                                val = 8.0;
+                                break;
+                            case Refinement_Case::initial_grid:
+                                val = 1.0;
+                                break;
+                            // TODO: this will never actually happen, as a 2:8 currently views
+                            // itself as a 1:8 (as it did a 2:1, and a 1:8)
+                            case Refinement_Case::two_to_eight:
+                                val = 2.8;
+                                break;
+                            case Refinement_Case::four_to_eight:
+                                val = 4.8;
+                                break;
+                            case Refinement_Case::none:
+                                val = 0.0;
+                                break;
+                        }
+                        cell_type_list.push_back(val);
+                    }
+                }
+
+                trace_out << "Made cell type list of len " << cell_type_list.size() << std::endl;
+                return cell_type_list;
+            }
+
+            /**
+             * @brief The function gives a way to go back from active_inpoel to
+             * real AMR id
+             *
+             * @return A vector which hold the AMR ids of the active inpoel
+             */
+            std::vector< std::size_t >& get_active_id_mapping()
+            {
+                active_id_mapping.clear();
+
+                for (const auto& kv : tets)
+                {
+                    size_t element_id = kv.first;
+
+                    if (is_active( element_id )) {
+                        active_id_mapping.push_back( element_id );
+                    }
+                }
+
+                return active_id_mapping;
+            }
+
+            /**
+             * @brief Function to extract only the active elements from tetinpeol
+             *
+             * @return List of only active elements
+             */
+            // TODO: need equiv for m_x/m_y/m_z? Otherwise there will be
+            // useless nodes in m_x etc? (Although that's functionally fine)
+            std::vector< std::size_t >& get_active_inpoel()
+            {
+                active_tetinpoel.clear();
+                active_nodes.clear();
+
+                for (const auto& kv : tets)
+                {
+
+                    size_t element_id = kv.first;
+                    auto t = kv.second;
+
+                    if (is_active( element_id )) {
+                        active_tetinpoel.push_back( t[0] );
+                        active_tetinpoel.push_back( t[1] );
+                        active_tetinpoel.push_back( t[2] );
+                        active_tetinpoel.push_back( t[3] );
+
+                        active_nodes.insert( t[0] );
+                        active_nodes.insert( t[1] );
+                        active_nodes.insert( t[2] );
+                        active_nodes.insert( t[3] );
+                    }
+                }
+
+                return active_tetinpoel;
+            }
+
+            // TODO: These mark methods can probably be a single one to which a
+                // Refinement_Case is passed, depending on how extra edges are marked
+            /**
+             * @brief Function to mark a given tet as needing a 1:2 refinement
+             *
+             * @param tet_id The tet to mark
+             */
+            void mark_one_to_two(size_t tet_id)
+            {
+                // TODO: If none of these methods need extra markings, then
+                // change them into a single method
+                trace_out << "Mark " << tet_id << " as 1:2" << std::endl;
+                marked_refinements.add(tet_id, Refinement_Case::one_to_two);
+            }
+
+            /**
+             * @brief Mark a given tet as needing a 1:4 refinement
+             *
+             * @param tet_id The tet to mark
+             */
+            void mark_one_to_four(size_t tet_id)
+            {
+                trace_out << "Mark " << tet_id << " as 1:4" << std::endl;
+                marked_refinements.add(tet_id, Refinement_Case::one_to_four);
+            }
+
+            /**
+             * @brief Mark a given tet as needing a 2:8 refinement
+             *
+             * @param tet_id id of tet to mark
+             */
+            void mark_two_to_eight(size_t tet_id)
+            {
+                trace_out << "Mark " << tet_id << " as 2:8" << std::endl;
+                marked_refinements.add(tet_id, Refinement_Case::two_to_eight);
+            }
+
+            /**
+             * @brief Mark a given tet as needing a 4:8 refinement
+             *
+             * @param tet_id id of tet to mark
+             */
+            void mark_four_to_eight(size_t tet_id)
+            {
+                trace_out << "Mark " << tet_id << " as 4:8" << std::endl;
+                marked_refinements.add(tet_id, Refinement_Case::four_to_eight);
+            }
+
+            /**
+             * @brief Function to mark a given tet as needing a 1:8 refinement
+             *
+             * @param tet_id The tet to mark
+             */
+            void mark_one_to_eight(size_t tet_id)
+            {
+                trace_out << "Mark " << tet_id << " as 1:8" << std::endl;
+                marked_refinements.add(tet_id, Refinement_Case::one_to_eight);
+            }
+
+            bool has_refinement_decision(size_t id)
+            {
+                return marked_refinements.exists(id);
+            }
+
+            /**
+             * @brief Helper debug function to print tet information
+             */
+            void print_tets() {
+                for (const auto& kv : tets)
+                {
+                    tet_t tet = kv.second;
+
+                    trace_out << "Tet " << kv.first << " has edges :" <<
+                        tet[0] << ", " <<
+                        tet[1] << ", " <<
+                        tet[2] << ", " <<
+                        tet[3] << ", " <<
+                    std::endl;
+                }
+            }
+
+            void print_edges()
+            {
+                edge_store.print();
+            }
+
+            void print_node_types()
+            {
+
+                int initial_grid = 0;
+                int one_to_two = 0;
+                int one_to_four = 0;
+                int one_to_eight = 0;
+                int other = 0;
+
+                for (const auto& kv : tets)
+                {
+                    size_t tet_id = kv.first;
+                    if (is_active(tet_id))
+                    {
+                        switch(get_refinement_case(tet_id))
+                        {
+                            case Refinement_Case::one_to_two:
+                                one_to_two++;
+                                break;
+                            case Refinement_Case::one_to_four:
+                                one_to_four++;
+                                break;
+                            case Refinement_Case::one_to_eight:
+                                one_to_eight++;
+                                break;
+                            case Refinement_Case::initial_grid:
+                                initial_grid++;
+                                break;
+                            case Refinement_Case::two_to_eight:
+                                // Don't care (yet)
+                                other++;
+                                break;
+                            case Refinement_Case::four_to_eight:
+                                // Don't care (yet)
+                                other++;
+                                break;
+                            case Refinement_Case::none:
+                                // Don't care (yet)
+                                other++;
+                                break;
+                        }
+
+                    }
+                }
+
+                //std::cout << "Active Totals:" << std::endl;
+                //std::cout << "  --> Initial = " << initial_grid << std::endl;
+                //std::cout << "  --> 1:2 = " << one_to_two << std::endl;
+                //std::cout << "  --> 1:4 = " << one_to_four << std::endl;
+                //std::cout << "  --> 1:8 = " << one_to_eight << std::endl;
+            }
+
+            edge_list_t generate_edge_keys(size_t tet_id)
+            {
+                tet_t tet = get(tet_id);
+                return edge_store.generate_keys(tet);
+            }
+
+            void generate_edges(size_t i) {
+                //  For tet ABCD, edges are:
+                //  AB, AC, AD, BC, BD, CD
+                //
+                edge_list_t edge_list = generate_edge_keys(i);
+
+                for (size_t j = 0; j < NUM_TET_EDGES; j++)
+                {
+                    edge_t edge = edge_list[j];
+
+                    size_t A = edge.first();
+                    size_t B = edge.second();
+
+                    Edge_Refinement er = Edge_Refinement(A, B, false,
+                            false, Edge_Lock_Case::unlocked);
+
+                    edge_store.add(edge, er);
+                }
+            }
+
+            /**
+             * @brief function to take a tet_id, finds it's nodes, and
+             * expresses them as faces
+             *
+             * Take tet ABCD, generate faces {ABC, ABD, ACD, BCD}
+             *
+             * @param tet_id The tet to generate faces for
+             *
+             * @return A list of faces making this tet
+             */
+            face_list_t generate_face_lists(size_t tet_id)
+            {
+                // Hard code this for now...
+                tet_t tet = get(tet_id);
+
+                trace_out  << "Tet has nodes " <<
+                    tet[0] << ", " <<
+                    tet[1] << ", " <<
+                    tet[2] << ", " <<
+                    tet[3] << ", " <<
+                    std::endl;
+
+                face_list_t face_list;
+
+                // ABC
+                face_list[0][0] = tet[0];
+                face_list[0][1] = tet[1];
+                face_list[0][2] = tet[2];
+
+                // ABD
+                face_list[1][0] = tet[0];
+                face_list[1][1] = tet[3];
+                face_list[1][2] = tet[1];
+
+                // ACD
+                face_list[2][0] = tet[0];
+                face_list[2][1] = tet[2];
+                face_list[2][2] = tet[3];
+
+                // BCD
+                face_list[3][0] = tet[1];
+                face_list[3][1] = tet[3];
+                face_list[3][2] = tet[2];
+
+                return face_list;
+            }
+
+            /**
+             * @brief Function which marks all edges in a given tet as needing
+             * to be refined
+             *
+             * @param tet_id ID of the tet to mark
+             */
+            void mark_edges_for_refinement(size_t tet_id)
+            {
+                edge_list_t edge_list = generate_edge_keys(tet_id);
+                for (size_t k = 0; k < NUM_TET_EDGES; k++)
+                {
+                    edge_t edge = edge_list[k];
+                    edge_store.mark_for_refinement(edge);
+                    trace_out << "Marking edge " << edge << " for refine " << std::endl;
+                }
+            }
+
+            /**
+             * @brief Delete existing edges. Iterate over the tets, and add them to
+             * the edge store.
+             */
+            // FIXME: Better name for this?
+            void generate_edges() {
+
+                // Go over tets, and generate all known edges
+                edge_store.edges.clear();
+
+                // Jump over tets
+                for (const auto& kv : tets)
+                {
+                    size_t tet_id = kv.first;
+                    generate_edges(tet_id);
+                }
+            }
+
+            void unset_marked_children(size_t parent_id)
+            {
+                Refinement_State& parent = data(parent_id);<--- Variable 'parent' can be declared with const
+                for (auto c : parent.children)
+                {
+                    marked_refinements.erase(c);
+                }
+            }
+
+            child_id_list_t generate_child_ids(size_t parent_id, size_t count = MAX_CHILDREN)
+            {
+                return id_generator.generate_child_ids(parent_id, count);
+            }
+            size_t get_child_id(size_t parent_id, size_t offset) const
+            {
+                return master_elements.get_child_id(parent_id, offset);
+            }
+
+            size_t get_parent_id(size_t id) const
+            {
+                return master_elements.get_parent(id);
+            }
+
+            // Deref
+            void process_delete_list()
+            {
+                trace_out << "process_delete_list " << delete_list.size() << std::endl;
+                size_t original_size = size();
+                for(auto f : delete_list) {
+                    erase(f);
+                }
+
+                size_t end_size = size();
+                trace_out << "Deleted " << original_size-end_size << std::endl;
+
+                delete_list.clear();
+            }
+            /**
+             * @brief Function to mark a given tet as a specific Derefinement_Case
+             *
+             * @param tet_id The tet to mark
+             * @param decision The Derefinement_case to set
+             */
+            void mark_derefinement_decision(size_t tet_id, AMR::Derefinement_Case decision)
+            {
+                trace_out << "MARKING_DEREF_DECISION" << std::endl;
+                marked_derefinements.add(tet_id, decision);
+            }
+            bool has_derefinement_decision(size_t id)
+            {
+                return marked_derefinements.exists(id);
+            }
+
+    };
+}
+
+#endif // guard
 
diff --git a/Debug/cppcheck/21.html b/Debug/cppcheck/21.html index 63d3be8aea0c..121556db42a3 100644 --- a/Debug/cppcheck/21.html +++ b/Debug/cppcheck/21.html @@ -152,12 +152,12 @@
  1
@@ -287,134 +287,692 @@ 

Cppcheck report - [

// *****************************************************************************
+128
+129
+130
+131
+132
+133
+134
+135
+136
+137
+138
+139
+140
+141
+142
+143
+144
+145
+146
+147
+148
+149
+150
+151
+152
+153
+154
+155
+156
+157
+158
+159
+160
+161
+162
+163
+164
+165
+166
+167
+168
+169
+170
+171
+172
+173
+174
+175
+176
+177
+178
+179
+180
+181
+182
+183
+184
+185
+186
+187
+188
+189
+190
+191
+192
+193
+194
+195
+196
+197
+198
+199
+200
+201
+202
+203
+204
+205
+206
+207
+208
+209
+210
+211
+212
+213
+214
+215
+216
+217
+218
+219
+220
+221
+222
+223
+224
+225
+226
+227
+228
+229
+230
+231
+232
+233
+234
+235
+236
+237
+238
+239
+240
+241
+242
+243
+244
+245
+246
+247
+248
+249
+250
+251
+252
+253
+254
+255
+256
+257
+258
+259
+260
+261
+262
+263
+264
+265
+266
+267
+268
+269
+270
+271
+272
+273
+274
+275
+276
+277
+278
+279
+280
+281
+282
+283
+284
+285
+286
+287
+288
+289
+290
+291
+292
+293
+294
+295
+296
+297
+298
+299
+300
+301
+302
+303
+304
+305
+306
+307
+308
+309
+310
+311
+312
+313
+314
+315
+316
+317
+318
+319
+320
+321
+322
+323
+324
+325
+326
+327
+328
+329
+330
+331
+332
+333
+334
+335
+336
+337
+338
+339
+340
+341
+342
+343
+344
+345
+346
+347
+348
+349
+350
+351
+352
+353
+354
+355
+356
+357
+358
+359
+360
+361
+362
+363
+364
+365
+366
+367
+368
+369
+370
+371
+372
+373
+374
+375
+376
+377
+378
+379
+380
+381
+382
+383
+384
+385
+386
+387
+388
+389
+390
+391
+392
+393
+394
+395
+396
+397
+398
+399
+400
+401
+402
+403
+404
+405
+406
+407
// *****************************************************************************
 /*!
-  \file      src/Control/HelpFactory.hpp
+  \file      src/Control/StatCtr.hpp
   \copyright 2012-2015 J. Bakosi,
              2016-2018 Los Alamos National Security, LLC.,
              2019-2021 Triad National Security, LLC.
              All rights reserved. See the LICENSE file for details.
-  \brief     Command-line and input deck help factory
-  \details   This file contains some types that facilitate the generation of
-     on-screen help.
+  \brief     Types and associated functions to deal with moments and PDFs
+  \details   Types and associated functions to deal with statistical moments and
+    probability density functions.
 */
 // *****************************************************************************
-#ifndef HelpFactory_h
-#define HelpFactory_h
+#ifndef StatControl_h
+#define StatControl_h
 
-#include <brigand/sequences/list.hpp>
-#include <brigand/algorithms/for_each.hpp>
-
+#include "Types.hpp"
+#include "Exception.hpp"
+#include "Keywords.hpp"
 #include "PUPUtil.hpp"
-#include "Factory.hpp"
-#include "Has.hpp"
-#include "Types.hpp"
+
+namespace tk {
+namespace ctr {
 
-namespace tk {
-namespace ctr {
-
-//! \brief Keyword information bundle
-//! \details This bundle contains the information that is used to display
-//!    on-screen help on all command-line arguments and control file keywords
-//!    for an exectuable. This struct is stored in a container that associates
-//!    keywords (used by a grammar and parser) to this struct. The container, an
-//!    runtime, std::map, is filled by the CmdLine and InputDeck objects'
-//!    constructors by one or more brigand::for_each which loops through the
-//!    set of all keywords used in a grammar. The maps are stored in the CmdLine
-//!    and InputDeck objects (which are tagged tuples) and thus can be migrated
-//!    through the network, thus the Charm++ parck/unpack routines are defined.
-//! \see Info functor used to fill the std::maps
-struct KeywordInfo {
-  std::string shortDescription;           //!< Short description
-  std::string longDescription;            //!< Long description
-  std::optional< std::string > alias;     //!< Keyword alias
-  std::optional< std::string > expt;      //!< Expected type description
-  std::optional< std::string > lower;     //!< Lower bound as string
-  std::optional< std::string > upper;     //!< Upper bound as string
-  std::optional< std::string > choices;   //!< Expected choices description
-
-  /** @name Pack/Unpack: Serialize KeywordInfo object for Charm++ */
-  ///@{
-  //! \brief Pack/Unpack serialize member function
-  //! \param[in,out] p Charm++'s PUP::er serializer object reference
-  void pup( PUP::er& p ) {<--- Parameter 'p' can be declared with const
-    p | shortDescription;
-    p | longDescription;
-    p | alias;
-    p | expt;
-    p | lower;
-    p | upper;
-    p | choices;
-  }
-  //! \brief Pack/Unpack serialize operator|
-  //! \param[in,out] p Charm++'s PUP::er serializer object reference
-  //! \param[in,out] info KeywordInfo object reference
-  friend void operator|( PUP::er& p, KeywordInfo& info ) { info.pup(p); }
-  ///@}
-};
-
-//! \brief A typedef for associating a keyword-string with its associated
-//!   information stored in a KeywordInfo struct
-using HelpFactory = std::map< std::string, KeywordInfo >;
-
-//! \brief Help bundle on a single keyword
-//! \details This is used for delivering help on a single keyword. This struct
-//!    also differentiates between command-line arguments and control file
-//!    keywords.
-struct HelpKw {
-  HelpFactory::key_type keyword;        //!< Keyword string
-  HelpFactory::mapped_type info;        //!< Keyword information
-  bool cmd;                             //!< True if command-line keyword
-
-  /** @name Pack/Unpack: Serialize HelpKw object for Charm++ */
-  ///@{
-  //! \brief Pack/Unpack serialize member function
-  //! \param[in,out] p Charm++'s PUP::er serializer object reference
-  void pup( PUP::er& p ) { p|keyword; p|info; p|cmd; }<--- Parameter 'p' can be declared with const
-  //! \brief Pack/Unpack serialize operator|
-  //! \param[in,out] p Charm++'s PUP::er serializer object reference
-  //! \param[in,out] h HelpKw object reference
-  friend void operator|( PUP::er& p, HelpKw& h ) { h.pup(p); }
-  ///@}
-};
-
-//! \brief Function object for filling a HelpFactory (std::map) with keywords
-//!   and their associated information bundle
-//! \details This struct is used as a functor to loop through a set of keywords
-//!   at compile-time and generate code for filling up the std::map.
-struct Info {
-  //! Store reference to map we are filling
-  tk::ctr::HelpFactory& m_factory;
-  //! Constructor: store reference to map to fill
-  explicit Info( tk::ctr::HelpFactory& factory ) : m_factory( factory ) {}
-  //! \brief Function call operator templated on the type that does the filling
-  template< typename U > void operator()( brigand::type_<U> ) {
-    m_factory[ U::string() ] = { U::shortDescription(),
-                                 U::longDescription(),
-                                 U::alias(),
-                                 U::expt(),
-                                 U::lower(),
-                                 U::upper(),
-                                 U::choices() };
-  }
-
-  //! Fill map in a simpler way passing a string rather than a brigand-type
-  void fill( const tk::entry_t& kw )
-  {
-    m_factory[kw.string()] = { kw.shortDescription(),
-                               kw.longDescription(),
-                               kw.alias(),
-                               kw.expt(),
-                               kw.lower(),
-                               kw.upper(),
-                               kw.choices() };
-  }
-};
-
-} // ctr::
-} // tk::
-
-#endif // HelpFactory_h
+//! \brief Moment specifies which type of moment is computed for a quantity in
+//!    a Term
+enum class Moment : uint8_t { ORDINARY=0,      //!< Full variable
+                              CENTRAL          //!< Fluctuation
+};
+
+//! \brief Term is a Moment of a quantity with a field ID to be ensemble
+//!    averaged
+//! \details Internally the numbering of field IDs starts from 0, but presented
+//!    to the user, e.g., in screen-output, as starting from 1.
+struct Term {
+  using ncomp_t = kw::ncomp::info::expect::type;
+
+  char var;             //!< Variable name
+  ncomp_t field;        //!< Field ID
+  Moment moment;        //!< Moment type: ordinary, central
+
+  /** @name Pack/Unpack: Serialize Term object for Charm++ */
+  ///@{
+  //! Pack/Unpack serialize member function
+  //! \param[in,out] p Charm++'s PUP::er serializer object reference
+  void pup( PUP::er& p ) {
+    p | var;
+    p | field;
+    PUP::pup( p, moment );
+  }
+  //! \brief Pack/Unpack serialize operator|
+  //! \param[in,out] p Charm++'s PUP::er serializer object reference
+  //! \param[in,out] t Term object reference
+  friend void operator|( PUP::er& p, Term& t ) { t.pup(p); } 
+  ///@}
+
+  //! \brief Constructor: initialize all state data
+  //! \param[in] v Variable name
+  //! \param[in] f Field ID
+  //! \param[in] m Moment type enum: Moment::ORDINARY or Moment::CENTRAL
+  explicit Term( char v = 0, ncomp_t f = 0, Moment m = Moment::ORDINARY ) :
+    var( v ), field( f ), moment( m ) {}
+
+  //! \brief Equal operator for, e.g., finding unique elements, used by, e.g.,
+  //!    std::unique().
+  //! \details Test on field, moment, and var
+  //! \param[in] term Term to compare
+  //! \return Boolean indicating if term equals 'this'
+  bool operator== ( const Term& term ) const {
+    if (var == term.var && field == term.field && moment == term.moment)
+      return true;
+    else
+      return false;
+  }
+
+  //! \brief Less-than operator for ordering, used by, e.g., std::sort().
+  //! \details Test on var, field, and moment.
+  //! \param[in] term Term to compare
+  //! \return Boolean indicating if term is less than 'this'
+  bool operator< ( const Term& term ) const {
+    if (var < term.var)
+      return true;
+    else if (var == term.var && field < term.field)
+      return true;
+    else if (var == term.var && field == term.field && moment < term.moment)
+      return true;
+    else
+      return false;
+  }
+};
+
+//! \brief Pack/Unpack: Namespace-scope serialize Term object for Charm++
+//! \param[in,out] p Charm++'s PUP::er serializer object reference
+//! \param[in,out] t Term object reference
+inline void pup( PUP::er& p, Term& t ) { t.pup(p); }
+
+//! \brief Products are arbitrary number of Terms to be multiplied and ensemble
+//!   averaged.
+//! \details An example is the scalar flux in x direction which needs two terms
+//! for ensemble averaging: (Y-\<Y\>) and (U-\<U\>), then the central moment is
+//! \<yu\> = <(Y-\<Y\>)(U-\<U\>)>, another example is the third mixed central
+//! moment of three scalars which needs three terms for ensemble averaging:
+//! (Y1-\<Y1\>), (Y2-\<Y2\>), and (Y3-\<Y3\>), then the central moment is
+//! \<y1y2y3\> = \<(Y1-\<Y1\>)(Y2-\<Y2\>)(Y3-\<Y3\>)\>.
+using Product = std::vector< Term >;
+
+
+// The following functions are useful for debugging, and unused.
+#if defined(__clang__)
+  #pragma clang diagnostic push
+  #pragma clang diagnostic ignored "-Wunused-function"
+#endif
+
+//! \brief Operator + for adding Term (var+field) to a std::string
+//! \param[in] lhs std::string to add to
+//! \param[in] term Term to add
+//! \return Updated std::string
+static std::string operator+ ( const std::string& lhs, const Term& term ) {
+  std::stringstream ss;
+  ss << lhs << term.var << term.field+1;
+  std::string rhs = ss.str();
+  return rhs;
+}
+
+//! \brief Operator += for adding Term (var+field) to a std::string
+//! \param[in,out] os std::string to add to
+//! \param[in] term Term to add
+//! \return Updated std::string
+static std::string& operator+= ( std::string& os, const Term& term ) {
+  std::stringstream ss;
+  ss << os << term.var << term.field+1;
+  os = ss.str();
+  return os;
+}
+
+//! \brief Operator << for writing Term to output streams
+//! \param[in,out] os Output stream to write to
+//! \param[in] term Term to write
+//! \return Updated output stream
+static std::ostream& operator<< ( std::ostream& os, const Term& term ) {
+  os << term.var << term.field+1;
+  return os;
+}
+
+//! \brief Operator + for adding products (var+field) to a std::string
+//! \param[in] lhs std::string to add to
+//! \param[in] p Product to add
+//! \return Updated std::string
+static std::string operator+ ( const std::string& lhs, const Product& p ) {
+  std::stringstream ss;
+  ss << lhs;
+  if (!p.empty()) {
+    ss << '<';
+    for (const auto& w : p) ss << w;
+    ss << '>';
+  }
+  std::string rhs = ss.str();
+  return rhs;
+}
+
+//! \brief Operator << for writing products to output streams
+//! \param[in,out] os Output stream to write to
+//! \param[in] p Product, std::vector< Term >, to write
+//! \return Updated output stream
+static
+std::ostream& operator<< ( std::ostream& os, const Product& p ) {
+  if (!p.empty()) {
+    os << '<';
+    for (const auto& w : p) os << w;
+    os << '>';
+  }
+  return os;
+}
+
+//! \brief Function for writing PDF sample space variables to output streams
+//! \param[in,out] os Output stream to write to
+//! \param[in] var Vector of Terms to write
+//! \param[in] bin Vector of PDF bin sizes
+//! \param[in] name Name of PDF
+//! \param[in] ext Vector of sample space extents
+//! \return Updated output stream
+static
+std::ostream& pdf( std::ostream& os,
+                   const std::vector< Term >& var,
+                   const std::vector< tk::real >& bin,
+                   const std::string& name,
+                   const std::vector< tk::real >& ext )
+{
+  Assert( !var.empty(), "var is empty in sample_space()" );
+  Assert( !bin.empty(), "bin is empty in sample_space()" );
+  Assert( var.size() == bin.size(),
+          "var.size and bin.size() must equal in ctr::pdf()" );
+
+  os << name << '(';
+  std::size_t i;
+  // sample space variables
+  for (i=0; i<var.size()-1; ++i) os << var[i] << ',';
+  os << var[i] << ':';
+  // sample space bin sizes
+  for (i=0; i<bin.size()-1; ++i) os << bin[i] << ',';
+  os << bin[i];
+  // sample space extents
+  if (!ext.empty()) {
+    os << ';';
+    for (i=0; i<ext.size()-1; ++i) os << ext[i] << ',';
+    os << ext[i];
+  }
+  os << ") ";
+  return os;
+}
+
+#if defined(__clang__)
+  #pragma clang diagnostic pop
+#endif
+
+//! \brief Find out if a vector of Terms only contains ordinary moment terms
+//! \details If and only if all terms are ordinary, the vector of Terms is
+//!    ordinary.
+//! \param[in] vec Vector of Terms to check
+//! \return Boolean indicating if all terms are ordinary
+static inline bool
+ordinary( const std::vector< ctr::Term >& vec ) {
+  if (std::any_of( vec.cbegin(), vec.cend(),
+        []( const ctr::Term& t ){ return t.moment == ctr::Moment::CENTRAL; } ))
+    return false;
+  else
+    return true;
+}
+
+//! \brief Find out if a vector of Terms contains any central moment terms
+//! \details If any term is central, the vector of Terms is central.
+//! \param[in] vec Vector of Terms to check
+//! \return Boolean indicating of any term is central
+static inline bool
+central( const std::vector< ctr::Term >& vec )
+{ return !ordinary( vec ); }
+
+//! \brief Probability density function (vector of sample space variables)
+using Probability = std::vector< Term >;
+
+//! \brief PDF information bundle
+//! \note If the user did not specify extents for a PDF, the corresponding
+//!   extents vector still exists but it is empty.
+struct PDFInfo {
+  const std::string& name;                  //!< PDF identifier, i.e., name
+  const std::vector< tk::real >& exts;      //!< Sample space extents
+  std::vector< std::string > vars;          //!< List of sample space variables
+  std::uint64_t it;                         //!< Iteration count
+  tk::real time;                            //!< Time stamp
+};
+
+//! \brief Find PDF information, see tk::ctr::PDFInfo
+//! \note Size of binsizes, names, pdfs, and exts must all be equal
+//! \note idx must be less than the length of binsizes, names, and pdfs
+//! \param[in] binsizes Vector of sample space bin sizes for multiple PDFs
+//! \param[in] names Vector of PDF names
+//! \param[in] exts Vector of sample space extents. Note: if the user did not
+//!   specify extents for a PDF, the corresponding extents vector still exists
+//!   but it is empty.
+//! \param[in] pdfs Vector of PDFs
+//! \param[in] m ORDINARY or CENTRAL PDF we are looking for
+//! \param[in] idx Index of the PDF within the list of matching (based on D and
+//!   m) PDFs requested
+//! \param[in] it Iteration count
+//! \param[in] time Physical time
+//! \return The PDF metadata requested
+//! \details Find PDF information given the sample space dimension (template
+//!   argument D), ordinary or central PDF (m), and the index within the list of
+//!   matching (based on D and m) PDFs requested (idx). This function must find
+//!   the PDF, if it does not, it throws an exception.
+//! \see walker::Distributor
+template< std::size_t D >
+PDFInfo pdfInfo( const std::vector< std::vector< tk::real > >& binsizes,
+                 const std::vector< std::string >& names,
+                 const std::vector< std::vector< tk::real > >& exts,
+                 const std::vector< Probability >& pdfs,
+                 tk::ctr::Moment m,
+                 std::size_t idx,
+                 std::uint64_t it,
+                 tk::real time )
+{
+  Assert( binsizes.size() == names.size(),
+          "Length of binsizes vector and that of PDF names must equal" );
+  Assert( binsizes.size() == pdfs.size(),
+          "Length of binsizes vector and that of PDFs must equal" );
+  Assert( binsizes.size() == exts.size(),
+          "Length of binsizes vector and that of PDF extents must equal" );
+  Assert( binsizes.size() > idx, "Indexing out of bounds" );
+
+  std::size_t i = 0;  // will count all PDFs queried
+  std::size_t n = 0;  // will count PDFs with sample space dimensions and type
+                      // (orindary or central) we are looking for
+  for (const auto& bs : binsizes) {
+    if ( bs.size() == D &&
+         ((m == Moment::ORDINARY && ordinary(pdfs[i])) ||
+          (m == Moment::CENTRAL && central(pdfs[i]))) ) ++n;
+    if (n == idx+1) {
+      std::vector< std::string > vars;
+      for (const auto& term : pdfs[i])
+        // cppcheck-suppress useStlAlgorithm
+        vars.push_back( term.var + std::to_string(term.field+1) );
+      return { names[i], exts[i], std::move(vars), it, time };
+    }
+    ++i;
+  }
+  Throw( "Cannot find PDF." );
+}
+
+//! Extract number of PDFs given sample space dimension
+//! \details Count number of PDFs given the sample space dimension (template
+//!   argument D) and whether the PDF is ordinary or central (m)
+//! \note Size of binsizes, names, pdfs, and exts must all be equal
+//! \param[in] binsizes Vector of vector of bin sizes (inner vector: a different
+//!   entry for each sample space dimension for potentially multi-variate PDFs,
+//!   outer vector: potentially multiple PDFs)
+//! \param[in] pdfs Vector of PDFs
+//! \param[in] m ORDINARY or CENTRAL PDF we are looking for
+//! \return The number of PDFs matchin the criteria discussed above
+template< std::size_t D >
+std::size_t numPDF( const std::vector< std::vector< tk::real > >& binsizes,
+                    const std::vector< Probability >& pdfs,
+                    ctr::Moment m )
+{
+  Assert( binsizes.size() == pdfs.size(),
+          "Length of binsizes vector and that of PDFs must equal" );
+  auto& kind = (m == Moment::ORDINARY ? ordinary : central);<--- Variable 'kind' can be declared with const
+  std::size_t i=0, n=0;
+  for (const auto& p : pdfs) {
+    const auto& bs = binsizes[i++];
+    if (kind(p) && bs.size() == D) ++n;
+  }
+  return n;
+}
+
+//! Lookup moment in moments map based on product key
+static inline tk::real
+lookup( const Product& p, const std::map< Product, tk::real >& moments ) {
+  const auto& it = moments.find( p );
+  if (it != end(moments))
+    return it->second;
+  else
+    Throw( "Cannot find moment " + p + " in moments map" );
+}
+
+//! Construct mean
+//! \param[in] var Variable
+//! \param[in] c Component number
+//! \return Constructed vector< Term > identifying the first ordinary moment
+//!   (mean) of field (component) c of variable var
+static inline Product
+mean( char var, kw::ncomp::info::expect::type c ) {
+  tk::ctr::Term m( static_cast<char>(std::toupper(var)), c, Moment::ORDINARY );
+  return tk::ctr::Product( { m } );
+}
+
+//! Construct covariance
+//! \param[in] var1 Variable 1
+//! \param[in] c1 Component number 1
+//! \param[in] var2 Variable 2
+//! \param[in] c2 Component number 2
+//! \return Constructed vector< Term > identifying the first ordinary moment
+//!   (mean) of field (component) c of variable var
+static inline Product
+covariance( char var1, kw::ncomp::info::expect::type c1,
+            char var2, kw::ncomp::info::expect::type c2 )
+{
+  tk::ctr::Term u( static_cast<char>(std::tolower(var1)), c1, Moment::CENTRAL );
+  tk::ctr::Term v( static_cast<char>(std::tolower(var2)), c2, Moment::CENTRAL );
+  return tk::ctr::Product( { u, v } );
+}
+
+//! Construct variance
+//! \param[in] var Variable
+//! \param[in] c Component number
+//! \return Constructed vector< Term > identifying the second central moment
+//!   (variance) of field (component) c of variable var
+static inline Product
+variance( char var, kw::ncomp::info::expect::type c ) {
+  tk::ctr::Term f( static_cast<char>(std::tolower(var)), c, Moment::CENTRAL );
+  return tk::ctr::Product( { f, f } );
+}
+
+//! Construct third central moment
+//! \param[in] var Variable
+//! \param[in] c Component number
+//! \return Constructed vector< Term > identifying the third central moment
+//!   of field (component) c of variable var
+static inline Product
+cen3( char var, kw::ncomp::info::expect::type c ) {
+  tk::ctr::Term f( static_cast<char>(std::tolower(var)), c, Moment::CENTRAL );
+  return tk::ctr::Product( { f, f, f } );
+}
+
+//! Construct second ordinary moment
+//! \param[in] var Variable
+//! \param[in] c Component number
+//! \return Constructed vector< Term > identifying the second ordinary moment
+//!   of field (component) c of variable var
+static inline Product
+ord2( char var, kw::ncomp::info::expect::type c ) {
+  tk::ctr::Term f( static_cast<char>(std::toupper(var)), c, Moment::ORDINARY );
+  return tk::ctr::Product( { f, f } );
+}
+
+} // ctr::
+} // tk::
+
+#endif // StatControl_h
 
diff --git a/Debug/cppcheck/22.html b/Debug/cppcheck/22.html index 4ae0480d8050..3b25a7a1c531 100644 --- a/Debug/cppcheck/22.html +++ b/Debug/cppcheck/22.html @@ -152,827 +152,3011 @@
- - + @@ -99,7 +99,7 @@ 25 : : public: 26 : : 27 : : //! Default constructor for migration - 28 : 7861 : mesh_adapter_t() {} + 28 : 7774 : mesh_adapter_t() {} 29 : : 30 : : //! Constructor taking a max refinement level and a mesh graph 31 : 2007 : explicit mesh_adapter_t( std::size_t u_mrl, diff --git a/Debug/test_coverage/Inciter/AMR/node_connectivity.hpp.func-sort-c.html b/Debug/test_coverage/Inciter/AMR/node_connectivity.hpp.func-sort-c.html index 3622e0592fdc..e8f867e33fb9 100644 --- a/Debug/test_coverage/Inciter/AMR/node_connectivity.hpp.func-sort-c.html +++ b/Debug/test_coverage/Inciter/AMR/node_connectivity.hpp.func-sort-c.html @@ -33,7 +33,7 @@ - + @@ -85,15 +85,15 @@ - + - + - + diff --git a/Debug/test_coverage/Inciter/AMR/node_connectivity.hpp.func.html b/Debug/test_coverage/Inciter/AMR/node_connectivity.hpp.func.html index 95b6691bb256..c3a71771d549 100644 --- a/Debug/test_coverage/Inciter/AMR/node_connectivity.hpp.func.html +++ b/Debug/test_coverage/Inciter/AMR/node_connectivity.hpp.func.html @@ -33,7 +33,7 @@ - + @@ -85,7 +85,7 @@ - + @@ -93,7 +93,7 @@ - + @@ -101,7 +101,7 @@ - +
  1
-  2
-  3
-  4
-  5
-  6
-  7
-  8
-  9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
- 37
- 38
- 39
- 40
- 41
- 42
- 43
- 44
- 45
- 46
- 47
- 48
- 49
- 50
- 51
- 52
- 53
- 54
- 55
- 56
- 57
- 58
- 59
- 60
- 61
- 62
- 63
- 64
- 65
- 66
- 67
- 68
- 69
- 70
- 71
- 72
- 73
- 74
- 75
- 76
- 77
- 78
- 79
- 80
- 81
- 82
- 83
- 84
- 85
- 86
- 87
- 88
- 89
- 90
- 91
- 92
- 93
- 94
- 95
- 96
- 97
- 98
- 99
-100
-101
-102
-103
-104
-105
-106
-107
-108
-109
-110
-111
-112
-113
-114
-115
-116
-117
-118
-119
-120
-121
-122
-123
-124
-125
-126
-127
-128
-129
-130
-131
-132
-133
-134
-135
-136
-137
-138
-139
-140
-141
-142
-143
-144
-145
-146
-147
-148
-149
-150
-151
-152
-153
-154
-155
-156
-157
-158
-159
-160
-161
-162
-163
-164
-165
-166
-167
-168
-169
-170
-171
-172
-173
-174
-175
-176
-177
-178
-179
-180
-181
-182
-183
-184
-185
-186
-187
-188
-189
-190
-191
-192
-193
-194
-195
-196
-197
-198
-199
-200
-201
-202
-203
-204
-205
-206
-207
-208
-209
-210
-211
-212
-213
-214
-215
-216
-217
-218
-219
-220
-221
-222
-223
-224
-225
-226
-227
-228
-229
-230
-231
-232
-233
-234
-235
-236
-237
-238
-239
-240
-241
-242
-243
-244
-245
-246
-247
-248
-249
-250
-251
-252
-253
-254
-255
-256
-257
-258
-259
-260
-261
-262
-263
-264
-265
-266
-267
-268
-269
-270
-271
-272
-273
-274
-275
-276
-277
-278
-279
-280
-281
-282
-283
-284
-285
-286
-287
-288
-289
-290
-291
-292
-293
-294
-295
-296
-297
-298
-299
-300
-301
-302
-303
-304
-305
-306
-307
-308
-309
-310
-311
-312
-313
-314
-315
-316
-317
-318
-319
-320
-321
-322
-323
-324
-325
-326
-327
-328
-329
-330
-331
-332
-333
-334
-335
-336
-337
-338
-339
-340
-341
-342
-343
-344
-345
-346
-347
-348
-349
-350
-351
-352
-353
-354
-355
-356
-357
-358
-359
-360
-361
-362
-363
-364
-365
-366
-367
-368
-369
-370
-371
-372
-373
-374
-375
-376
-377
-378
-379
-380
-381
-382
-383
-384
-385
-386
-387
-388
-389
-390
-391
-392
-393
-394
-395
-396
-397
-398
-399
-400
-401
-402
-403
-404
-405
-406
-407
// *****************************************************************************
+
   1
+   2
+   3
+   4
+   5
+   6
+   7
+   8
+   9
+  10
+  11
+  12
+  13
+  14
+  15
+  16
+  17
+  18
+  19
+  20
+  21
+  22
+  23
+  24
+  25
+  26
+  27
+  28
+  29
+  30
+  31
+  32
+  33
+  34
+  35
+  36
+  37
+  38
+  39
+  40
+  41
+  42
+  43
+  44
+  45
+  46
+  47
+  48
+  49
+  50
+  51
+  52
+  53
+  54
+  55
+  56
+  57
+  58
+  59
+  60
+  61
+  62
+  63
+  64
+  65
+  66
+  67
+  68
+  69
+  70
+  71
+  72
+  73
+  74
+  75
+  76
+  77
+  78
+  79
+  80
+  81
+  82
+  83
+  84
+  85
+  86
+  87
+  88
+  89
+  90
+  91
+  92
+  93
+  94
+  95
+  96
+  97
+  98
+  99
+ 100
+ 101
+ 102
+ 103
+ 104
+ 105
+ 106
+ 107
+ 108
+ 109
+ 110
+ 111
+ 112
+ 113
+ 114
+ 115
+ 116
+ 117
+ 118
+ 119
+ 120
+ 121
+ 122
+ 123
+ 124
+ 125
+ 126
+ 127
+ 128
+ 129
+ 130
+ 131
+ 132
+ 133
+ 134
+ 135
+ 136
+ 137
+ 138
+ 139
+ 140
+ 141
+ 142
+ 143
+ 144
+ 145
+ 146
+ 147
+ 148
+ 149
+ 150
+ 151
+ 152
+ 153
+ 154
+ 155
+ 156
+ 157
+ 158
+ 159
+ 160
+ 161
+ 162
+ 163
+ 164
+ 165
+ 166
+ 167
+ 168
+ 169
+ 170
+ 171
+ 172
+ 173
+ 174
+ 175
+ 176
+ 177
+ 178
+ 179
+ 180
+ 181
+ 182
+ 183
+ 184
+ 185
+ 186
+ 187
+ 188
+ 189
+ 190
+ 191
+ 192
+ 193
+ 194
+ 195
+ 196
+ 197
+ 198
+ 199
+ 200
+ 201
+ 202
+ 203
+ 204
+ 205
+ 206
+ 207
+ 208
+ 209
+ 210
+ 211
+ 212
+ 213
+ 214
+ 215
+ 216
+ 217
+ 218
+ 219
+ 220
+ 221
+ 222
+ 223
+ 224
+ 225
+ 226
+ 227
+ 228
+ 229
+ 230
+ 231
+ 232
+ 233
+ 234
+ 235
+ 236
+ 237
+ 238
+ 239
+ 240
+ 241
+ 242
+ 243
+ 244
+ 245
+ 246
+ 247
+ 248
+ 249
+ 250
+ 251
+ 252
+ 253
+ 254
+ 255
+ 256
+ 257
+ 258
+ 259
+ 260
+ 261
+ 262
+ 263
+ 264
+ 265
+ 266
+ 267
+ 268
+ 269
+ 270
+ 271
+ 272
+ 273
+ 274
+ 275
+ 276
+ 277
+ 278
+ 279
+ 280
+ 281
+ 282
+ 283
+ 284
+ 285
+ 286
+ 287
+ 288
+ 289
+ 290
+ 291
+ 292
+ 293
+ 294
+ 295
+ 296
+ 297
+ 298
+ 299
+ 300
+ 301
+ 302
+ 303
+ 304
+ 305
+ 306
+ 307
+ 308
+ 309
+ 310
+ 311
+ 312
+ 313
+ 314
+ 315
+ 316
+ 317
+ 318
+ 319
+ 320
+ 321
+ 322
+ 323
+ 324
+ 325
+ 326
+ 327
+ 328
+ 329
+ 330
+ 331
+ 332
+ 333
+ 334
+ 335
+ 336
+ 337
+ 338
+ 339
+ 340
+ 341
+ 342
+ 343
+ 344
+ 345
+ 346
+ 347
+ 348
+ 349
+ 350
+ 351
+ 352
+ 353
+ 354
+ 355
+ 356
+ 357
+ 358
+ 359
+ 360
+ 361
+ 362
+ 363
+ 364
+ 365
+ 366
+ 367
+ 368
+ 369
+ 370
+ 371
+ 372
+ 373
+ 374
+ 375
+ 376
+ 377
+ 378
+ 379
+ 380
+ 381
+ 382
+ 383
+ 384
+ 385
+ 386
+ 387
+ 388
+ 389
+ 390
+ 391
+ 392
+ 393
+ 394
+ 395
+ 396
+ 397
+ 398
+ 399
+ 400
+ 401
+ 402
+ 403
+ 404
+ 405
+ 406
+ 407
+ 408
+ 409
+ 410
+ 411
+ 412
+ 413
+ 414
+ 415
+ 416
+ 417
+ 418
+ 419
+ 420
+ 421
+ 422
+ 423
+ 424
+ 425
+ 426
+ 427
+ 428
+ 429
+ 430
+ 431
+ 432
+ 433
+ 434
+ 435
+ 436
+ 437
+ 438
+ 439
+ 440
+ 441
+ 442
+ 443
+ 444
+ 445
+ 446
+ 447
+ 448
+ 449
+ 450
+ 451
+ 452
+ 453
+ 454
+ 455
+ 456
+ 457
+ 458
+ 459
+ 460
+ 461
+ 462
+ 463
+ 464
+ 465
+ 466
+ 467
+ 468
+ 469
+ 470
+ 471
+ 472
+ 473
+ 474
+ 475
+ 476
+ 477
+ 478
+ 479
+ 480
+ 481
+ 482
+ 483
+ 484
+ 485
+ 486
+ 487
+ 488
+ 489
+ 490
+ 491
+ 492
+ 493
+ 494
+ 495
+ 496
+ 497
+ 498
+ 499
+ 500
+ 501
+ 502
+ 503
+ 504
+ 505
+ 506
+ 507
+ 508
+ 509
+ 510
+ 511
+ 512
+ 513
+ 514
+ 515
+ 516
+ 517
+ 518
+ 519
+ 520
+ 521
+ 522
+ 523
+ 524
+ 525
+ 526
+ 527
+ 528
+ 529
+ 530
+ 531
+ 532
+ 533
+ 534
+ 535
+ 536
+ 537
+ 538
+ 539
+ 540
+ 541
+ 542
+ 543
+ 544
+ 545
+ 546
+ 547
+ 548
+ 549
+ 550
+ 551
+ 552
+ 553
+ 554
+ 555
+ 556
+ 557
+ 558
+ 559
+ 560
+ 561
+ 562
+ 563
+ 564
+ 565
+ 566
+ 567
+ 568
+ 569
+ 570
+ 571
+ 572
+ 573
+ 574
+ 575
+ 576
+ 577
+ 578
+ 579
+ 580
+ 581
+ 582
+ 583
+ 584
+ 585
+ 586
+ 587
+ 588
+ 589
+ 590
+ 591
+ 592
+ 593
+ 594
+ 595
+ 596
+ 597
+ 598
+ 599
+ 600
+ 601
+ 602
+ 603
+ 604
+ 605
+ 606
+ 607
+ 608
+ 609
+ 610
+ 611
+ 612
+ 613
+ 614
+ 615
+ 616
+ 617
+ 618
+ 619
+ 620
+ 621
+ 622
+ 623
+ 624
+ 625
+ 626
+ 627
+ 628
+ 629
+ 630
+ 631
+ 632
+ 633
+ 634
+ 635
+ 636
+ 637
+ 638
+ 639
+ 640
+ 641
+ 642
+ 643
+ 644
+ 645
+ 646
+ 647
+ 648
+ 649
+ 650
+ 651
+ 652
+ 653
+ 654
+ 655
+ 656
+ 657
+ 658
+ 659
+ 660
+ 661
+ 662
+ 663
+ 664
+ 665
+ 666
+ 667
+ 668
+ 669
+ 670
+ 671
+ 672
+ 673
+ 674
+ 675
+ 676
+ 677
+ 678
+ 679
+ 680
+ 681
+ 682
+ 683
+ 684
+ 685
+ 686
+ 687
+ 688
+ 689
+ 690
+ 691
+ 692
+ 693
+ 694
+ 695
+ 696
+ 697
+ 698
+ 699
+ 700
+ 701
+ 702
+ 703
+ 704
+ 705
+ 706
+ 707
+ 708
+ 709
+ 710
+ 711
+ 712
+ 713
+ 714
+ 715
+ 716
+ 717
+ 718
+ 719
+ 720
+ 721
+ 722
+ 723
+ 724
+ 725
+ 726
+ 727
+ 728
+ 729
+ 730
+ 731
+ 732
+ 733
+ 734
+ 735
+ 736
+ 737
+ 738
+ 739
+ 740
+ 741
+ 742
+ 743
+ 744
+ 745
+ 746
+ 747
+ 748
+ 749
+ 750
+ 751
+ 752
+ 753
+ 754
+ 755
+ 756
+ 757
+ 758
+ 759
+ 760
+ 761
+ 762
+ 763
+ 764
+ 765
+ 766
+ 767
+ 768
+ 769
+ 770
+ 771
+ 772
+ 773
+ 774
+ 775
+ 776
+ 777
+ 778
+ 779
+ 780
+ 781
+ 782
+ 783
+ 784
+ 785
+ 786
+ 787
+ 788
+ 789
+ 790
+ 791
+ 792
+ 793
+ 794
+ 795
+ 796
+ 797
+ 798
+ 799
+ 800
+ 801
+ 802
+ 803
+ 804
+ 805
+ 806
+ 807
+ 808
+ 809
+ 810
+ 811
+ 812
+ 813
+ 814
+ 815
+ 816
+ 817
+ 818
+ 819
+ 820
+ 821
+ 822
+ 823
+ 824
+ 825
+ 826
+ 827
+ 828
+ 829
+ 830
+ 831
+ 832
+ 833
+ 834
+ 835
+ 836
+ 837
+ 838
+ 839
+ 840
+ 841
+ 842
+ 843
+ 844
+ 845
+ 846
+ 847
+ 848
+ 849
+ 850
+ 851
+ 852
+ 853
+ 854
+ 855
+ 856
+ 857
+ 858
+ 859
+ 860
+ 861
+ 862
+ 863
+ 864
+ 865
+ 866
+ 867
+ 868
+ 869
+ 870
+ 871
+ 872
+ 873
+ 874
+ 875
+ 876
+ 877
+ 878
+ 879
+ 880
+ 881
+ 882
+ 883
+ 884
+ 885
+ 886
+ 887
+ 888
+ 889
+ 890
+ 891
+ 892
+ 893
+ 894
+ 895
+ 896
+ 897
+ 898
+ 899
+ 900
+ 901
+ 902
+ 903
+ 904
+ 905
+ 906
+ 907
+ 908
+ 909
+ 910
+ 911
+ 912
+ 913
+ 914
+ 915
+ 916
+ 917
+ 918
+ 919
+ 920
+ 921
+ 922
+ 923
+ 924
+ 925
+ 926
+ 927
+ 928
+ 929
+ 930
+ 931
+ 932
+ 933
+ 934
+ 935
+ 936
+ 937
+ 938
+ 939
+ 940
+ 941
+ 942
+ 943
+ 944
+ 945
+ 946
+ 947
+ 948
+ 949
+ 950
+ 951
+ 952
+ 953
+ 954
+ 955
+ 956
+ 957
+ 958
+ 959
+ 960
+ 961
+ 962
+ 963
+ 964
+ 965
+ 966
+ 967
+ 968
+ 969
+ 970
+ 971
+ 972
+ 973
+ 974
+ 975
+ 976
+ 977
+ 978
+ 979
+ 980
+ 981
+ 982
+ 983
+ 984
+ 985
+ 986
+ 987
+ 988
+ 989
+ 990
+ 991
+ 992
+ 993
+ 994
+ 995
+ 996
+ 997
+ 998
+ 999
+1000
+1001
+1002
+1003
+1004
+1005
+1006
+1007
+1008
+1009
+1010
+1011
+1012
+1013
+1014
+1015
+1016
+1017
+1018
+1019
+1020
+1021
+1022
+1023
+1024
+1025
+1026
+1027
+1028
+1029
+1030
+1031
+1032
+1033
+1034
+1035
+1036
+1037
+1038
+1039
+1040
+1041
+1042
+1043
+1044
+1045
+1046
+1047
+1048
+1049
+1050
+1051
+1052
+1053
+1054
+1055
+1056
+1057
+1058
+1059
+1060
+1061
+1062
+1063
+1064
+1065
+1066
+1067
+1068
+1069
+1070
+1071
+1072
+1073
+1074
+1075
+1076
+1077
+1078
+1079
+1080
+1081
+1082
+1083
+1084
+1085
+1086
+1087
+1088
+1089
+1090
+1091
+1092
+1093
+1094
+1095
+1096
+1097
+1098
+1099
+1100
+1101
+1102
+1103
+1104
+1105
+1106
+1107
+1108
+1109
+1110
+1111
+1112
+1113
+1114
+1115
+1116
+1117
+1118
+1119
+1120
+1121
+1122
+1123
+1124
+1125
+1126
+1127
+1128
+1129
+1130
+1131
+1132
+1133
+1134
+1135
+1136
+1137
+1138
+1139
+1140
+1141
+1142
+1143
+1144
+1145
+1146
+1147
+1148
+1149
+1150
+1151
+1152
+1153
+1154
+1155
+1156
+1157
+1158
+1159
+1160
+1161
+1162
+1163
+1164
+1165
+1166
+1167
+1168
+1169
+1170
+1171
+1172
+1173
+1174
+1175
+1176
+1177
+1178
+1179
+1180
+1181
+1182
+1183
+1184
+1185
+1186
+1187
+1188
+1189
+1190
+1191
+1192
+1193
+1194
+1195
+1196
+1197
+1198
+1199
+1200
+1201
+1202
+1203
+1204
+1205
+1206
+1207
+1208
+1209
+1210
+1211
+1212
+1213
+1214
+1215
+1216
+1217
+1218
+1219
+1220
+1221
+1222
+1223
+1224
+1225
+1226
+1227
+1228
+1229
+1230
+1231
+1232
+1233
+1234
+1235
+1236
+1237
+1238
+1239
+1240
+1241
+1242
+1243
+1244
+1245
+1246
+1247
+1248
+1249
+1250
+1251
+1252
+1253
+1254
+1255
+1256
+1257
+1258
+1259
+1260
+1261
+1262
+1263
+1264
+1265
+1266
+1267
+1268
+1269
+1270
+1271
+1272
+1273
+1274
+1275
+1276
+1277
+1278
+1279
+1280
+1281
+1282
+1283
+1284
+1285
+1286
+1287
+1288
+1289
+1290
+1291
+1292
+1293
+1294
+1295
+1296
+1297
+1298
+1299
+1300
+1301
+1302
+1303
+1304
+1305
+1306
+1307
+1308
+1309
+1310
+1311
+1312
+1313
+1314
+1315
+1316
+1317
+1318
+1319
+1320
+1321
+1322
+1323
+1324
+1325
+1326
+1327
+1328
+1329
+1330
+1331
+1332
+1333
+1334
+1335
+1336
+1337
+1338
+1339
+1340
+1341
+1342
+1343
+1344
+1345
+1346
+1347
+1348
+1349
+1350
+1351
+1352
+1353
+1354
+1355
+1356
+1357
+1358
+1359
+1360
+1361
+1362
+1363
+1364
+1365
+1366
+1367
+1368
+1369
+1370
+1371
+1372
+1373
+1374
+1375
+1376
+1377
+1378
+1379
+1380
+1381
+1382
+1383
+1384
+1385
+1386
+1387
+1388
+1389
+1390
+1391
+1392
+1393
+1394
+1395
+1396
+1397
+1398
+1399
+1400
+1401
+1402
+1403
+1404
+1405
+1406
+1407
+1408
+1409
+1410
+1411
+1412
+1413
+1414
+1415
+1416
+1417
+1418
+1419
+1420
+1421
+1422
+1423
+1424
+1425
+1426
+1427
+1428
+1429
+1430
+1431
+1432
+1433
+1434
+1435
+1436
+1437
+1438
+1439
+1440
+1441
+1442
+1443
+1444
+1445
+1446
+1447
+1448
+1449
+1450
+1451
+1452
+1453
+1454
+1455
+1456
+1457
+1458
+1459
+1460
+1461
+1462
+1463
+1464
+1465
+1466
+1467
+1468
+1469
+1470
+1471
+1472
+1473
+1474
+1475
+1476
+1477
+1478
+1479
+1480
+1481
+1482
+1483
+1484
+1485
+1486
+1487
+1488
+1489
+1490
+1491
+1492
+1493
+1494
+1495
+1496
+1497
+1498
+1499
// *****************************************************************************
 /*!
-  \file      src/Control/StatCtr.hpp
+  \file      src/IO/PDFWriter.cpp
   \copyright 2012-2015 J. Bakosi,
              2016-2018 Los Alamos National Security, LLC.,
              2019-2021 Triad National Security, LLC.
              All rights reserved. See the LICENSE file for details.
-  \brief     Types and associated functions to deal with moments and PDFs
-  \details   Types and associated functions to deal with statistical moments and
-    probability density functions.
-*/
-// *****************************************************************************
-#ifndef StatControl_h
-#define StatControl_h
+  \brief     Univariate PDF writer
+  \brief     PDF writer class definition
+  \details   This file defines a PDF writer class that facilitates outputing
+    probability density functions (PDFs) into files in various formats using
+    various configurations.
+*/
+// *****************************************************************************
 
-#include "Types.hpp"
-#include "Exception.hpp"
-#include "Keywords.hpp"
-#include "PUPUtil.hpp"
-
-namespace tk {
-namespace ctr {
-
-//! \brief Moment specifies which type of moment is computed for a quantity in
-//!    a Term
-enum class Moment : uint8_t { ORDINARY=0,      //!< Full variable
-                              CENTRAL          //!< Fluctuation
-};
-
-//! \brief Term is a Moment of a quantity with a field ID to be ensemble
-//!    averaged
-//! \details Internally the numbering of field IDs starts from 0, but presented
-//!    to the user, e.g., in screen-output, as starting from 1.
-struct Term {
-  using ncomp_t = kw::ncomp::info::expect::type;
-
-  char var;             //!< Variable name
-  ncomp_t field;        //!< Field ID
-  Moment moment;        //!< Moment type: ordinary, central
-
-  /** @name Pack/Unpack: Serialize Term object for Charm++ */
-  ///@{
-  //! Pack/Unpack serialize member function
-  //! \param[in,out] p Charm++'s PUP::er serializer object reference
-  void pup( PUP::er& p ) {
-    p | var;
-    p | field;
-    PUP::pup( p, moment );
-  }
-  //! \brief Pack/Unpack serialize operator|
-  //! \param[in,out] p Charm++'s PUP::er serializer object reference
-  //! \param[in,out] t Term object reference
-  friend void operator|( PUP::er& p, Term& t ) { t.pup(p); } 
-  ///@}
-
-  //! \brief Constructor: initialize all state data
-  //! \param[in] v Variable name
-  //! \param[in] f Field ID
-  //! \param[in] m Moment type enum: Moment::ORDINARY or Moment::CENTRAL
-  explicit Term( char v = 0, ncomp_t f = 0, Moment m = Moment::ORDINARY ) :
-    var( v ), field( f ), moment( m ) {}
-
-  //! \brief Equal operator for, e.g., finding unique elements, used by, e.g.,
-  //!    std::unique().
-  //! \details Test on field, moment, and var
-  //! \param[in] term Term to compare
-  //! \return Boolean indicating if term equals 'this'
-  bool operator== ( const Term& term ) const {
-    if (var == term.var && field == term.field && moment == term.moment)
-      return true;
-    else
-      return false;
-  }
-
-  //! \brief Less-than operator for ordering, used by, e.g., std::sort().
-  //! \details Test on var, field, and moment.
-  //! \param[in] term Term to compare
-  //! \return Boolean indicating if term is less than 'this'
-  bool operator< ( const Term& term ) const {
-    if (var < term.var)
-      return true;
-    else if (var == term.var && field < term.field)
-      return true;
-    else if (var == term.var && field == term.field && moment < term.moment)
-      return true;
-    else
-      return false;
-  }
-};
-
-//! \brief Pack/Unpack: Namespace-scope serialize Term object for Charm++
-//! \param[in,out] p Charm++'s PUP::er serializer object reference
-//! \param[in,out] t Term object reference
-inline void pup( PUP::er& p, Term& t ) { t.pup(p); }
-
-//! \brief Products are arbitrary number of Terms to be multiplied and ensemble
-//!   averaged.
-//! \details An example is the scalar flux in x direction which needs two terms
-//! for ensemble averaging: (Y-\<Y\>) and (U-\<U\>), then the central moment is
-//! \<yu\> = <(Y-\<Y\>)(U-\<U\>)>, another example is the third mixed central
-//! moment of three scalars which needs three terms for ensemble averaging:
-//! (Y1-\<Y1\>), (Y2-\<Y2\>), and (Y3-\<Y3\>), then the central moment is
-//! \<y1y2y3\> = \<(Y1-\<Y1\>)(Y2-\<Y2\>)(Y3-\<Y3\>)\>.
-using Product = std::vector< Term >;
-
-
-// The following functions are useful for debugging, and unused.
-#if defined(__clang__)
-  #pragma clang diagnostic push
-  #pragma clang diagnostic ignored "-Wunused-function"
-#endif
-
-//! \brief Operator + for adding Term (var+field) to a std::string
-//! \param[in] lhs std::string to add to
-//! \param[in] term Term to add
-//! \return Updated std::string
-static std::string operator+ ( const std::string& lhs, const Term& term ) {
-  std::stringstream ss;
-  ss << lhs << term.var << term.field+1;
-  std::string rhs = ss.str();
-  return rhs;
+#include <iomanip>
+
+#include "NoWarning/exodusII.hpp"
+
+#include "PDFWriter.hpp"
+#include "Exception.hpp"
+
+using tk::PDFWriter;
+
+PDFWriter::PDFWriter( const std::string& filename,
+                      ctr::TxtFloatFormatType format,
+                      std::streamsize precision ) :
+  Writer( filename )
+// *****************************************************************************
+//  Constructor
+//! \param[in] filename Output filename to which output the PDF
+//! \param[in] format Configure floating-point output format for ASCII output
+//! \param[in] precision Configure precision for floating-point ASCII output
+// *****************************************************************************
+{
+  // Set floating-point format for output file stream
+  if (format == ctr::TxtFloatFormatType::DEFAULT)
+    {} //m_outFile << std::defaultfloat;   GCC does not yet support this
+  else if (format == ctr::TxtFloatFormatType::FIXED)
+    m_outFile << std::fixed;
+  else if (format == ctr::TxtFloatFormatType::SCIENTIFIC)
+    m_outFile << std::scientific;
+  else Throw( "Text floating-point format not recognized." );
+
+  // Set numeric precision for output file stream if the input makes sense
+  if (precision > 0 && precision < std::numeric_limits< tk::real >::digits10+2)
+    m_outFile << std::setprecision( static_cast<int>(precision) );
+}
+
+void
+PDFWriter::writeTxt( const UniPDF& pdf, const tk::ctr::PDFInfo& info ) const
+// *****************************************************************************
+//  Write out standardized univariate PDF to file
+//! \param[in] pdf Univariate PDF
+//! \param[in] info PDF metadata
+// *****************************************************************************
+{
+  const auto& name = info.name;
+  const auto& uext = info.exts;
+  const auto& vars = info.vars;
+  const auto& it = info.it;
+  const auto& time = info.time;
+
+  assertSampleSpaceDimensions< 1 >( vars );
+  assertSampleSpaceExtents< 1 >( uext );
+
+  // Query and optionally override number of bins and minimum of sample space if
+  // user-specified extents were given and copy probabilities from pdf to an
+  // array for output
+  std::size_t nbi;
+  tk::real min, max;
+  std::vector< tk::real > outpdf;
+  tk::real binsize;
+  std::array< long, 2*UniPDF::dim > ext;
+  extents( pdf, uext, nbi, min, max, binsize, ext, outpdf );
+
+  // Output header
+  m_outFile << "# vim: filetype=sh:\n#\n"
+            << "# Univariate PDF: " << name << '(' << vars[0] << ')' << '\n'
+            << "# -----------------------------------------------\n"
+            << "# Numeric precision: " << m_outFile.precision() << '\n'
+            << "# Bin size: " << binsize << '\n'
+            << "# Number of bins estimated: " << ext[1] - ext[0] + 1
+            << '\n'
+            << "# Number of bins output: " << nbi << '\n'
+            << "# Sample space extent: [" << min << " : " << max << "]\n"
+            << "# Integral: " << pdf.integral() << "\n"
+            << "# Iteration: " << it << "\n"
+            << "# Physical time: " << time << "\n#\n"
+            << "# Example step-by-step visualization with gnuplot\n"
+            << "# -----------------------------------------------\n"
+            << "# gnuplot> set grid\n"
+            << "# gnuplot> unset key\n"
+            << "# gnuplot> set xlabel \"" << vars[0] << "\"\n"
+            << "# gnuplot> set ylabel \"" << name << "(" << vars[0] << ")\"\n"
+            << "# gnuplot> plot ";
+  if (!uext.empty()) m_outFile << "[" << uext[0] << ':' << uext[1] << "] ";
+  m_outFile << "\"" << m_filename << "\" with points\n#\n"
+            << "# Gnuplot one-liner for quick copy-paste\n"
+            << "# -----------------------------------------------\n"
+            << "# set grid; unset key; set xlabel \"" << vars[0]
+            << "\"; set ylabel \"" << name << "(" << vars[0]
+            << ")\"; plot";
+  if (!uext.empty()) m_outFile << " [" << uext[0] << ':' << uext[1] << "]";
+  m_outFile << " \"" << m_filename << "\" w p\n#\n"
+            << "# Data columns: " << vars[0] << ", " << name << "(" << vars[0]
+            << ")\n# -----------------------------------------------\n";
+
+  // If no user-specified sample space extents, output pdf map directly
+  if (uext.empty()) {
+    for (const auto& p : pdf.map())
+      m_outFile << binsize * static_cast<tk::real>(p.first) << '\t'
+                << static_cast<tk::real>(p.second) / binsize /
+                   static_cast<tk::real>(pdf.nsample())
+                << std::endl;
+  } else { // If user-specified sample space extents, output outpdf array
+    std::size_t bin = 0;
+    for (const auto& p : outpdf)
+      m_outFile << binsize * static_cast<tk::real>(bin++) + uext[0] << '\t'
+                << p << std::endl;
+  }
 }
 
-//! \brief Operator += for adding Term (var+field) to a std::string
-//! \param[in,out] os std::string to add to
-//! \param[in] term Term to add
-//! \return Updated std::string
-static std::string& operator+= ( std::string& os, const Term& term ) {
-  std::stringstream ss;
-  ss << os << term.var << term.field+1;
-  os = ss.str();
-  return os;
-}
-
-//! \brief Operator << for writing Term to output streams
-//! \param[in,out] os Output stream to write to
-//! \param[in] term Term to write
-//! \return Updated output stream
-static std::ostream& operator<< ( std::ostream& os, const Term& term ) {
-  os << term.var << term.field+1;
-  return os;
-}
-
-//! \brief Operator + for adding products (var+field) to a std::string
-//! \param[in] lhs std::string to add to
-//! \param[in] p Product to add
-//! \return Updated std::string
-static std::string operator+ ( const std::string& lhs, const Product& p ) {
-  std::stringstream ss;
-  ss << lhs;
-  if (!p.empty()) {
-    ss << '<';
-    for (const auto& w : p) ss << w;
-    ss << '>';
-  }
-  std::string rhs = ss.str();
-  return rhs;
-}
-
-//! \brief Operator << for writing products to output streams
-//! \param[in,out] os Output stream to write to
-//! \param[in] p Product, std::vector< Term >, to write
-//! \return Updated output stream
-static
-std::ostream& operator<< ( std::ostream& os, const Product& p ) {
-  if (!p.empty()) {
-    os << '<';
-    for (const auto& w : p) os << w;
-    os << '>';
-  }
-  return os;
-}
-
-//! \brief Function for writing PDF sample space variables to output streams
-//! \param[in,out] os Output stream to write to
-//! \param[in] var Vector of Terms to write
-//! \param[in] bin Vector of PDF bin sizes
-//! \param[in] name Name of PDF
-//! \param[in] ext Vector of sample space extents
-//! \return Updated output stream
-static
-std::ostream& pdf( std::ostream& os,
-                   const std::vector< Term >& var,
-                   const std::vector< tk::real >& bin,
-                   const std::string& name,
-                   const std::vector< tk::real >& ext )
-{
-  Assert( !var.empty(), "var is empty in sample_space()" );
-  Assert( !bin.empty(), "bin is empty in sample_space()" );
-  Assert( var.size() == bin.size(),
-          "var.size and bin.size() must equal in ctr::pdf()" );
-
-  os << name << '(';
-  std::size_t i;
-  // sample space variables
-  for (i=0; i<var.size()-1; ++i) os << var[i] << ',';
-  os << var[i] << ':';
-  // sample space bin sizes
-  for (i=0; i<bin.size()-1; ++i) os << bin[i] << ',';
-  os << bin[i];
-  // sample space extents
-  if (!ext.empty()) {
-    os << ';';
-    for (i=0; i<ext.size()-1; ++i) os << ext[i] << ',';
-    os << ext[i];
-  }
-  os << ") ";
-  return os;
-}
-
-#if defined(__clang__)
-  #pragma clang diagnostic pop
-#endif
-
-//! \brief Find out if a vector of Terms only contains ordinary moment terms
-//! \details If and only if all terms are ordinary, the vector of Terms is
-//!    ordinary.
-//! \param[in] vec Vector of Terms to check
-//! \return Boolean indicating if all terms are ordinary
-static inline bool
-ordinary( const std::vector< ctr::Term >& vec ) {
-  if (std::any_of( vec.cbegin(), vec.cend(),
-        []( const ctr::Term& t ){ return t.moment == ctr::Moment::CENTRAL; } ))
-    return false;
-  else
-    return true;
-}
-
-//! \brief Find out if a vector of Terms contains any central moment terms
-//! \details If any term is central, the vector of Terms is central.
-//! \param[in] vec Vector of Terms to check
-//! \return Boolean indicating of any term is central
-static inline bool
-central( const std::vector< ctr::Term >& vec )
-{ return !ordinary( vec ); }
+void
+PDFWriter::writeTxt( const BiPDF& pdf, const tk::ctr::PDFInfo& info ) const
+// *****************************************************************************
+//  Write out standardized bivariate PDF to text file
+//! \param[in] pdf Bivariate PDF
+//! \param[in] info PDF metadata
+// *****************************************************************************
+{
+  const auto& name = info.name;
+  const auto& uext = info.exts;
+  const auto& vars = info.vars;
+  const auto& it = info.it;
+  const auto& time = info.time;
+
+  assertSampleSpaceDimensions< 2 >( vars );
+  assertSampleSpaceExtents< 2 >( uext );
+
+  // Query and optionally override number of bins and minima of sample space if
+  // user-specified extents were given and copy probabilities from pdf to a
+  // logically 2D array for output
+  std::size_t nbix, nbiy;
+  tk::real xmin, xmax, ymin, ymax;
+  std::vector< tk::real > outpdf;
+  std::array< tk::real, 2 > binsize;
+  std::array< long, 2*BiPDF::dim > ext;
+  extents( pdf, uext, nbix, nbiy, xmin, xmax, ymin, ymax, binsize, ext, outpdf,
+           ctr::PDFCenteringType::ELEM );
+
+  // Output metadata
+  m_outFile << "# vim: filetype=sh:\n#\n"
+            << "# Joint bivariate PDF: " << name << '(' << vars[0] << ','
+            << vars[1] << ")\n"
+            << "# -----------------------------------------------\n"
+            << "# Numeric precision: " << m_outFile.precision() << '\n'
+            << "# Bin sizes: " << binsize[0] << ", " << binsize[1] << '\n'
+            << "# Number of bins estimated: " << ext[1] - ext[0] + 1 << " x "
+            << ext[3] - ext[2] + 1 << '\n'
+            << "# Number of bins output: " << nbix << " x " << nbiy << '\n'
+            << "# Sample space extents: [" << xmin << " : " << xmax
+            << "], [" << ymin << " : " << ymax << "]\n"
+            << "# Iteration: " << it << "\n"
+            << "# Physical time: " << time << "\n#\n"
+            << "# Example step-by-step visualization with gnuplot\n"
+            << "# -----------------------------------------------\n"
+            << "# gnuplot> set grid\n"
+            << "# gnuplot> unset key\n"
+            << "# gnuplot> set xlabel \"" << vars[0] << "\"\n"
+            << "# gnuplot> set ylabel \"" << vars[1] << "\"\n"
+            << "# gnuplot> set zlabel \"" << name << "(" << vars[0] << ","
+            << vars[1] << ")\"\n"
+            << "# gnuplot> set dgrid3d 50,50,1\n"
+            << "# gnuplot> set cntrparam levels 20\n"
+            << "# gnuplot> set contour\n";
+  if (!uext.empty())
+    m_outFile << "# gnuplot> set xrange [" << uext[0] << ':' << uext[1] << "]\n"
+              << "# gnuplot> set yrange [" << uext[2] << ':' << uext[3] << "]\n";
+         
+  m_outFile << "# gnuplot> splot \"" << m_filename << "\" with lines\n#\n"
+            << "# Gnuplot one-liner for quick copy-paste\n"
+            << "# --------------------------------------\n"
+            << "# set grid; unset key; set xlabel \"" << vars[0]
+            << "\"; set ylabel \"" << vars[1] << "\"; set zlabel \"" << name
+            << "(" << vars[0] << ',' << vars[1] << ")\"; set dgrid3d 50,50,1; "
+               "set cntrparam levels 20; set contour; ";
+  if (!uext.empty())
+    m_outFile << "set xrange [" << uext[0] << ':' << uext[1] << "]; set yrange "
+                 "[" << uext[2] << ':' << uext[3] << "]; ";
+  m_outFile << "splot \"" << m_filename << "\" w l\n#\n"
+            << "# Data columns: " << vars[0] << ", " << vars[1] << ", "
+            << name << '(' << vars[0] << ',' << vars[1] << ")\n"
+            << "# -----------------------------------------------\n";
+
+  // If no user-specified sample space extents, output pdf map directly
+  if (uext.empty()) {
+    for (const auto& p : pdf.map())
+      m_outFile << binsize[0] * static_cast<tk::real>(p.first[0]) << '\t'
+                << binsize[1] * static_cast<tk::real>(p.first[1]) << '\t'
+                << p.second / binsize[0] / binsize[1] /
+                   static_cast<tk::real>(pdf.nsample())
+                << std::endl;
+  } else { // If user-specified sample space extents, output outpdf array
+    std::size_t bin = 0;
+    for (const auto& p : outpdf) {
+      m_outFile << binsize[0] * static_cast<tk::real>(bin % nbix) + uext[0]
+                << '\t'
+                << binsize[1] * static_cast<tk::real>(bin / nbix) + uext[2]
+                << '\t'
+                << p
+                << std::endl;
+      ++bin;
+    }
+  }
+
+  ErrChk( !m_outFile.bad(), "Failed to write to file: " + m_filename );
+}
+
+void
+PDFWriter::writeTxt( const TriPDF& pdf, const tk::ctr::PDFInfo& info ) const
+// *****************************************************************************
+//  Write out standardized trivariate PDF to text file
+//! \param[in] pdf Trivariate PDF
+//! \param[in] info PDF metadata
+// *****************************************************************************
+{
+  const auto& name = info.name;
+  const auto& uext = info.exts;
+  const auto& vars = info.vars;
+  const auto& it = info.it;
+  const auto& time = info.time;
+
+  assertSampleSpaceDimensions< 3 >( vars );
+  assertSampleSpaceExtents< 3 >( uext );
 
-//! \brief Probability density function (vector of sample space variables)
-using Probability = std::vector< Term >;
-
-//! \brief PDF information bundle
-//! \note If the user did not specify extents for a PDF, the corresponding
-//!   extents vector still exists but it is empty.
-struct PDFInfo {
-  const std::string& name;                  //!< PDF identifier, i.e., name
-  const std::vector< tk::real >& exts;      //!< Sample space extents
-  std::vector< std::string > vars;          //!< List of sample space variables
-  std::uint64_t it;                         //!< Iteration count
-  tk::real time;                            //!< Time stamp
-};
-
-//! \brief Find PDF information, see tk::ctr::PDFInfo
-//! \note Size of binsizes, names, pdfs, and exts must all be equal
-//! \note idx must be less than the length of binsizes, names, and pdfs
-//! \param[in] binsizes Vector of sample space bin sizes for multiple PDFs
-//! \param[in] names Vector of PDF names
-//! \param[in] exts Vector of sample space extents. Note: if the user did not
-//!   specify extents for a PDF, the corresponding extents vector still exists
-//!   but it is empty.
-//! \param[in] pdfs Vector of PDFs
-//! \param[in] m ORDINARY or CENTRAL PDF we are looking for
-//! \param[in] idx Index of the PDF within the list of matching (based on D and
-//!   m) PDFs requested
-//! \param[in] it Iteration count
-//! \param[in] time Physical time
-//! \return The PDF metadata requested
-//! \details Find PDF information given the sample space dimension (template
-//!   argument D), ordinary or central PDF (m), and the index within the list of
-//!   matching (based on D and m) PDFs requested (idx). This function must find
-//!   the PDF, if it does not, it throws an exception.
-//! \see walker::Distributor
-template< std::size_t D >
-PDFInfo pdfInfo( const std::vector< std::vector< tk::real > >& binsizes,
-                 const std::vector< std::string >& names,
-                 const std::vector< std::vector< tk::real > >& exts,
-                 const std::vector< Probability >& pdfs,
-                 tk::ctr::Moment m,
-                 std::size_t idx,
-                 std::uint64_t it,
-                 tk::real time )
-{
-  Assert( binsizes.size() == names.size(),
-          "Length of binsizes vector and that of PDF names must equal" );
-  Assert( binsizes.size() == pdfs.size(),
-          "Length of binsizes vector and that of PDFs must equal" );
-  Assert( binsizes.size() == exts.size(),
-          "Length of binsizes vector and that of PDF extents must equal" );
-  Assert( binsizes.size() > idx, "Indexing out of bounds" );
-
-  std::size_t i = 0;  // will count all PDFs queried
-  std::size_t n = 0;  // will count PDFs with sample space dimensions and type
-                      // (orindary or central) we are looking for
-  for (const auto& bs : binsizes) {
-    if ( bs.size() == D &&
-         ((m == Moment::ORDINARY && ordinary(pdfs[i])) ||
-          (m == Moment::CENTRAL && central(pdfs[i]))) ) ++n;
-    if (n == idx+1) {
-      std::vector< std::string > vars;
-      for (const auto& term : pdfs[i])
-        // cppcheck-suppress useStlAlgorithm
-        vars.push_back( term.var + std::to_string(term.field+1) );
-      return { names[i], exts[i], std::move(vars), it, time };
-    }
-    ++i;
-  }
-  Throw( "Cannot find PDF." );
-}
-
-//! Extract number of PDFs given sample space dimension
-//! \details Count number of PDFs given the sample space dimension (template
-//!   argument D) and whether the PDF is ordinary or central (m)
-//! \note Size of binsizes, names, pdfs, and exts must all be equal
-//! \param[in] binsizes Vector of vector of bin sizes (inner vector: a different
-//!   entry for each sample space dimension for potentially multi-variate PDFs,
-//!   outer vector: potentially multiple PDFs)
-//! \param[in] pdfs Vector of PDFs
-//! \param[in] m ORDINARY or CENTRAL PDF we are looking for
-//! \return The number of PDFs matchin the criteria discussed above
-template< std::size_t D >
-std::size_t numPDF( const std::vector< std::vector< tk::real > >& binsizes,
-                    const std::vector< Probability >& pdfs,
-                    ctr::Moment m )
-{
-  Assert( binsizes.size() == pdfs.size(),
-          "Length of binsizes vector and that of PDFs must equal" );
-  auto& kind = (m == Moment::ORDINARY ? ordinary : central);<--- Variable 'kind' can be declared with const
-  std::size_t i=0, n=0;
-  for (const auto& p : pdfs) {
-    const auto& bs = binsizes[i++];
-    if (kind(p) && bs.size() == D) ++n;
-  }
-  return n;
-}
-
-//! Lookup moment in moments map based on product key
-static inline tk::real
-lookup( const Product& p, const std::map< Product, tk::real >& moments ) {
-  const auto& it = moments.find( p );
-  if (it != end(moments))
-    return it->second;
-  else
-    Throw( "Cannot find moment " + p + " in moments map" );
-}
-
-//! Construct mean
-//! \param[in] var Variable
-//! \param[in] c Component number
-//! \return Constructed vector< Term > identifying the first ordinary moment
-//!   (mean) of field (component) c of variable var
-static inline Product
-mean( char var, kw::ncomp::info::expect::type c ) {
-  tk::ctr::Term m( static_cast<char>(std::toupper(var)), c, Moment::ORDINARY );
-  return tk::ctr::Product( { m } );
-}
-
-//! Construct covariance
-//! \param[in] var1 Variable 1
-//! \param[in] c1 Component number 1
-//! \param[in] var2 Variable 2
-//! \param[in] c2 Component number 2
-//! \return Constructed vector< Term > identifying the first ordinary moment
-//!   (mean) of field (component) c of variable var
-static inline Product
-covariance( char var1, kw::ncomp::info::expect::type c1,
-            char var2, kw::ncomp::info::expect::type c2 )
-{
-  tk::ctr::Term u( static_cast<char>(std::tolower(var1)), c1, Moment::CENTRAL );
-  tk::ctr::Term v( static_cast<char>(std::tolower(var2)), c2, Moment::CENTRAL );
-  return tk::ctr::Product( { u, v } );
-}
-
-//! Construct variance
-//! \param[in] var Variable
-//! \param[in] c Component number
-//! \return Constructed vector< Term > identifying the second central moment
-//!   (variance) of field (component) c of variable var
-static inline Product
-variance( char var, kw::ncomp::info::expect::type c ) {
-  tk::ctr::Term f( static_cast<char>(std::tolower(var)), c, Moment::CENTRAL );
-  return tk::ctr::Product( { f, f } );
-}
-
-//! Construct third central moment
-//! \param[in] var Variable
-//! \param[in] c Component number
-//! \return Constructed vector< Term > identifying the third central moment
-//!   of field (component) c of variable var
-static inline Product
-cen3( char var, kw::ncomp::info::expect::type c ) {
-  tk::ctr::Term f( static_cast<char>(std::tolower(var)), c, Moment::CENTRAL );
-  return tk::ctr::Product( { f, f, f } );
-}
-
-//! Construct second ordinary moment
-//! \param[in] var Variable
-//! \param[in] c Component number
-//! \return Constructed vector< Term > identifying the second ordinary moment
-//!   of field (component) c of variable var
-static inline Product
-ord2( char var, kw::ncomp::info::expect::type c ) {
-  tk::ctr::Term f( static_cast<char>(std::toupper(var)), c, Moment::ORDINARY );
-  return tk::ctr::Product( { f, f } );
-}
-
-} // ctr::
-} // tk::
-
-#endif // StatControl_h
+  // Query and optionally override number of bins and minima of sample space if
+  // user-specified extents were given and copy probabilities from pdf to a
+  // logically 3D array for output
+  std::size_t nbix, nbiy, nbiz;
+  tk::real xmin, xmax, ymin, ymax, zmin, zmax;
+  std::vector< tk::real > outpdf;
+  std::array< tk::real, 3 > binsize;
+  std::array< long, 2*TriPDF::dim > ext;
+  extents( pdf, uext, nbix, nbiy, nbiz, xmin, xmax, ymin, ymax, zmin, zmax,
+           binsize, ext, outpdf, ctr::PDFCenteringType::ELEM );
+
+  // Output header
+  m_outFile << "# vim: filetype=sh:\n#\n"
+            << "# Joint trivariate PDF: " << name << '(' << vars[0] << ','
+            << vars[1] << ',' << vars[2] << ")\n"
+            << "# -----------------------------------------------\n"
+            << "# Numeric precision: " << m_outFile.precision() << '\n'
+            << "# Bin sizes: " << binsize[0] << ", " << binsize[1] << ", "
+            << binsize[2] << '\n'
+            << "# Number of bins estimated: " << ext[1] - ext[0] + 1 << " x "
+            << ext[3] - ext[2] + 1 << " x " << ext[5] - ext[4] + 1 << '\n'
+            << "# Number of bins output: " << nbix << " x " << nbiy << " x "
+            << nbiz << '\n'
+            << "# Sample space extents: [" << xmin << " : " << xmax << "], ["
+            << ymin << " : " << ymax << "], [" << zmin << " : " << zmax
+            << "]\n"
+            << "# Iteration: " << it << "\n"
+            << "# Physical time: " << time << "\n#\n"
+            << "# Example step-by-step visualization with gnuplot\n"
+            << "# -----------------------------------------------\n"
+            << "# gnuplot> set grid\n"
+            << "# gnuplot> set xlabel \"" << vars[0] << "\"\n"
+            << "# gnuplot> set ylabel \"" << vars[1] << "\"\n"
+            << "# gnuplot> set zlabel \"" << vars[2] << "\"\n";
+  if (!uext.empty())
+    m_outFile << "# gnuplot> set xrange [" << uext[0] << ':' << uext[1] << "]\n"
+              << "# gnuplot> set yrange [" << uext[2] << ':' << uext[3] << "]\n"
+              << "# gnuplot> set zrange [" << uext[4] << ':' << uext[5] << "]\n";
+  m_outFile << "# gnuplot> splot \"" << m_filename << "\" pointtype 7 "
+               "linecolor palette title \"" << name << '(' << vars[0] << ','
+            << vars[1] << ',' << vars[2] << ")\"\n#\n"
+            << "# Gnuplot one-liner for quick copy-paste\n"
+            << "# --------------------------------------\n"
+            << "# set grid; set xlabel \"" << vars[0] << "\"; set ylabel \""
+            << vars[1] << "\"; set zlabel \"" << vars[2] << "\"; ";
+  if (!uext.empty())
+    m_outFile << "set xrange [" << uext[0] << ':' << uext[1] << "]; set yrange "
+                 "[" << uext[2] << ':' << uext[3] << "]; set zrange ["
+              << uext[4] << ':' << uext[5] << "]; ";
+  m_outFile << "splot \"" << m_filename << "\" pt 7 linecolor palette title \""
+            << name << '(' << vars[0] << ',' << vars[1] << ',' << vars[2] << ')'
+            << "\"\n#\n"
+            << "# Data columns: " << vars[0] << ", " << vars[1] << ", "
+            << vars[2] << ", " << name << '(' << vars[0] << ',' << vars[1]
+            << ',' << vars[2] << ")\n"
+            << "# -----------------------------------------------\n";
+
+  // If no user-specified sample space extents, output pdf map directly
+  if (uext.empty()) {
+    for (const auto& p : pdf.map())
+      m_outFile << binsize[0] * static_cast<tk::real>(p.first[0]) << '\t'
+                << binsize[1] * static_cast<tk::real>(p.first[1]) << '\t'
+                << binsize[2] * static_cast<tk::real>(p.first[2]) << '\t'
+                << p.second / binsize[0] / binsize[1] / binsize[2]
+                            / static_cast<tk::real>(pdf.nsample())
+                << std::endl;
+  } else { // If user-specified sample space extents, output outpdf array
+    std::size_t bin = 0;
+    const auto n = nbix*nbiy;
+    for (const auto& p : outpdf) {
+      m_outFile << binsize[0] * static_cast<tk::real>(bin % n % nbix) + uext[0]
+                << '\t'
+                << binsize[1] * static_cast<tk::real>(bin % n / nbix) + uext[2]
+                << '\t'
+                << binsize[2] * static_cast<tk::real>(bin / n) + uext[4] << '\t'
+                << p
+                << std::endl;
+      ++bin;
+    }
+  }
+
+  ErrChk( !m_outFile.bad(), "Failed to write to file: " + m_filename );
+}
+
+void
+PDFWriter::writeGmshTxt( const BiPDF& pdf,
+                         const tk::ctr::PDFInfo& info,
+                         ctr::PDFCenteringType centering ) const
+// *****************************************************************************
+//  Write out standardized bivariate PDF to Gmsh (text) format
+//! \param[in] pdf Bivariate PDF
+//! \param[in] info PDF metadata
+//! \param[in] centering Bin centering on sample space mesh
+// *****************************************************************************
+{
+  const auto& name = info.name;
+  const auto& uext = info.exts;
+  const auto& vars = info.vars;
+  const auto& it = info.it;
+  const auto& time = info.time;
+
+  assertSampleSpaceDimensions< 2 >( vars );
+  assertSampleSpaceExtents< 2 >( uext );
+
+  // Query and optionally override number of bins and minima of sample space if
+  // user-specified extents were given and copy probabilities from pdf to a
+  // logically 2D array for output
+  std::size_t nbix, nbiy;
+  tk::real xmin, xmax, ymin, ymax;
+  std::vector< tk::real > outpdf;
+  std::array< tk::real, 2 > binsize;
+  std::array< long, 2*BiPDF::dim > ext;
+  extents( pdf, uext, nbix, nbiy, xmin, xmax, ymin, ymax, binsize, ext, outpdf,
+           centering );
+
+  // Output metadata. The #s are unnecessary, but vi will color it differently.
+  m_outFile << "$Comments\n"
+            << "# vim: filetype=sh:\n"
+            << "# Joint bivariate PDF: " << name << '(' << vars[0] << ','
+            << vars[1] << ")\n"
+            << "# -----------------------------------------------\n"
+            << "# Numeric precision: " << m_outFile.precision() << '\n'
+            << "# Bin sizes: " << binsize[0] << ", " << binsize[1] << '\n'
+            << "# Number of bins estimated: " << ext[1] - ext[0] + 1 << " x "
+            << ext[3] - ext[2] + 1 << '\n'
+            << "# Number of bins output: " << nbix << " x " << nbiy << '\n'
+            << "# Sample space extents: [" << xmin << " : " << xmax
+            << "], [" << ymin << " : " << ymax << "]\n"
+            << "# Iteration: " << it << "\n"
+            << "# Physical time: " << time << "\n"
+            << "$EndComments\n";
+
+  // Output mesh header: mesh version, file type, data size
+  m_outFile << "$MeshFormat\n2.2 0 8\n$EndMeshFormat\n";
+  ErrChk( !m_outFile.bad(), "Failed to write to file: " + m_filename );
+
+  // Output grid points of discretized sample space (2D Cartesian grid)
+  m_outFile << "$Nodes\n" << (nbix+1)*(nbiy+1) << std::endl;
+  int k=0;
+  for (std::size_t i=0; i<=nbiy; i++) {
+    tk::real I = static_cast< tk::real >( i );
+    tk::real y = ymin + I*binsize[1];
+    for (std::size_t j=0; j<=nbix; j++) {
+      tk::real J = static_cast< tk::real >( j );
+      tk::real x = xmin + J*binsize[0];
+      m_outFile << ++k << ' ' << x << ' ' << y << " 0\n";
+    }
+  }
+  m_outFile << "$EndNodes\n";
+
+  // Output elements of discretized sample space (2D Cartesian grid)
+  m_outFile << "$Elements\n" << nbix*nbiy << "\n";
+  for (std::size_t i=0; i<nbix*nbiy; ++i) {
+    const auto y = i/nbix;
+    m_outFile << i+1 << " 3 2 1 1 " << i+y+1 << ' ' << i+y+2 << ' '
+              << i+y+nbix+3 << ' ' << i+y+nbix+2 << std::endl;
+  }
+  m_outFile << "$EndElements\n";
+
+  // Output PDF function values in element or node centers
+  std::string c( "Element" );
+  if (centering == ctr::PDFCenteringType::NODE) {
+    ++nbix; ++nbiy;
+    c = "Node";
+  }
+  m_outFile << '$' << c << "Data\n1\n\"" << name << "\"\n1\n0.0\n3\n0\n1\n"
+            << nbix*nbiy << "\n";
+
+  // If no user-specified sample space extents, output pdf map directly
+  if (uext.empty()) {
+
+    std::vector< int > out( nbix*nbiy, 0 ); // indicate bins filled (1)
+    for (const auto& p : pdf.map()) {
+      const auto bin = (p.first[1] - ext[2]) * static_cast<long>(nbix) +
+                       (p.first[0] - ext[0]) % static_cast<long>(nbix);
+      Assert( bin >= 0, "Bin underflow in PDFWriter::writeGmshTxt()." );
+      Assert( static_cast<std::size_t>(bin) < nbix*nbiy,
+              "Bin overflow in PDFWriter::writeGmshTxt()." );
+      out[ static_cast<std::size_t>(bin) ] = 1;
+      m_outFile << bin+1 << '\t'
+                << p.second / binsize[0] / binsize[1]
+                            / static_cast<tk::real>(pdf.nsample())
+                << std::endl;
+    }
+    // Output bins nonexistent in PDF (gmsh sometimes fails to plot the exiting
+    // bins if holes exist in the data, it also looks better as zero than holes)
+    for (std::size_t i=0; i<out.size(); ++i)
+      if (out[i] == 0) m_outFile << i+1 << "\t0" << std::endl;
+
+  } else { // If user-specified sample space extents, output outpdf array
+
+    std::size_t bin = 0;
+    for (const auto& p : outpdf) m_outFile << ++bin << ' ' << p << std::endl;
+
+  }
+
+  m_outFile << "$End" << c << "Data\n";
+
+  ErrChk( !m_outFile.bad(), "Failed to write to file: " + m_filename );
+}
+
+void
+PDFWriter::writeGmshTxt( const TriPDF& pdf,
+                         const tk::ctr::PDFInfo& info,
+                         ctr::PDFCenteringType centering ) const
+// *****************************************************************************
+//  Write out standardized trivariate PDF to Gmsh (text) format
+//! \param[in] pdf Trivariate PDF
+//! \param[in] info PDF metadata
+//! \param[in] centering Bin centering on sample space mesh
+// *****************************************************************************
+{
+  const auto& name = info.name;
+  const auto& uext = info.exts;
+  const auto& vars = info.vars;
+  const auto& it = info.it;
+  const auto& time = info.time;
+
+  assertSampleSpaceDimensions< 3 >( vars );
+  assertSampleSpaceExtents< 3 >( uext );
+
+  // Query and optionally override number of bins and minima of sample space if
+  // user-specified extents were given and copy probabilities from pdf to a
+  // logically 3D array for output
+  std::size_t nbix, nbiy, nbiz;
+  tk::real xmin, xmax, ymin, ymax, zmin, zmax;
+  std::vector< tk::real > outpdf;
+  std::array< tk::real, 3 > binsize;
+  std::array< long, 2*TriPDF::dim > ext;
+  extents( pdf, uext, nbix, nbiy, nbiz, xmin, xmax, ymin, ymax, zmin, zmax,
+           binsize, ext, outpdf, centering );
+
+  // Output metadata. The #s are unnecessary, but vi will color it differently.
+  m_outFile << "$Comments\n"
+            << "# vim: filetype=sh:\n#\n"
+            << "# Joint trivariate PDF: " << name << '(' << vars[0] << ','
+            << vars[1] << ',' << vars[2] << ")\n"
+            << "# -----------------------------------------------\n"
+            << "# Numeric precision: " << m_outFile.precision() << '\n'
+            << "# Bin sizes: " << binsize[0] << ", " << binsize[1] << ", "
+            << binsize[2] << '\n'
+            << "# Number of bins estimated: " << ext[1] - ext[0] + 1 << " x "
+            << ext[3] - ext[2] + 1 << " x " << ext[5] - ext[4] + 1 << '\n'
+            << "# Number of bins output: " << nbix << " x " << nbiy << " x "
+            << nbiz << '\n'
+            << "# Sample space extents: [" << xmin << " : " << xmax << "], ["
+            << ymin << " : " << ymax << "], [" << zmin << " : " << zmax << "]\n"
+            << "# Iteration: " << it << "\n"
+            << "# Physical time: " << time << "\n#\n"
+            << "$EndComments\n";
+
+  // Output mesh header: mesh version, file type, data size
+  m_outFile << "$MeshFormat\n2.2 0 8\n$EndMeshFormat\n";
+  ErrChk( !m_outFile.bad(), "Failed to write to file: " + m_filename );
+
+  // Output grid points of discretized sample space (3D Cartesian grid)
+  m_outFile << "$Nodes\n" << (nbix+1)*(nbiy+1)*(nbiz+1) << std::endl;
+  int l=0;
+  for (std::size_t k=0; k<=nbiz; k++) {
+    tk::real K = static_cast< tk::real >( k );
+    tk::real z = zmin + K*binsize[2];
+    for (std::size_t j=0; j<=nbiy; j++) {
+      tk::real J = static_cast< tk::real >( j );
+      tk::real y = ymin + J*binsize[1];
+      for (std::size_t i=0; i<=nbix; i++) {
+        tk::real I = static_cast< tk::real >( i );
+        tk::real x = xmin + I*binsize[0];
+        m_outFile << ++l << ' ' << x << ' ' << y << ' ' << z << '\n';
+      }
+    }
+  }
+  m_outFile << "$EndNodes\n";
+
+  // Output elements of discretized sample space (3D Cartesian grid)
+  m_outFile << "$Elements\n" << nbix*nbiy*nbiz << "\n";
+  const auto n = nbix*nbiy;
+  const auto p = (nbix+1)*(nbiy+1);
+  for (std::size_t i=0; i<nbix*nbiy*nbiz; ++i) {
+    const auto y = i/nbix + i/n*(nbix+1);
+    m_outFile << i+1 << " 5 2 1 1 " << i+y+1 << ' ' << i+y+2 << ' '
+              << i+y+nbix+3 << ' ' << i+y+nbix+2 << ' '
+              << i+y+p+1 << ' ' << i+y+p+2 << ' '
+              << i+y+p+nbix+3 << ' ' << i+y+p+nbix+2 << ' '
+              << std::endl;
+  }
+  m_outFile << "$EndElements\n";
+
+  // Output PDF function values in element or node centers
+  std::string c( "Element" );
+  if (centering == ctr::PDFCenteringType::NODE) {
+    ++nbix; ++nbiy; ++nbiz;
+    c = "Node";
+  }
+  m_outFile << '$' << c << "Data\n1\n\"" << name << "\"\n1\n0.0\n3\n0\n1\n"
+            << nbix*nbiy*nbiz << "\n";
+
+  // If no user-specified sample space extents, output pdf map directly
+  if (uext.empty()) {
+
+    std::vector< int > out( nbix*nbiy*nbiz, 0 ); // indicate bins filled
+    for (const auto& q : pdf.map()) {
+      const auto bin = (q.first[2] - ext[4]) * static_cast<long>(nbix*nbiy) +
+                       (q.first[1] - ext[2]) * static_cast<long>(nbix) +
+                       (q.first[0] - ext[0]) % static_cast<long>(nbix);
+      Assert( bin >= 0, "Bin underflow in PDFWriter::writeGmshTxt()." );
+      Assert( static_cast<std::size_t>(bin) < nbix*nbiy*nbiz,
+              "Bin overflow in PDFWriter::writeGmshTxt()." );
+      out[ static_cast<std::size_t>(bin) ] = 1 ;
+      m_outFile << bin+1 << '\t'
+                << q.second / binsize[0] / binsize[1] / binsize[2]
+                            / static_cast<tk::real>(pdf.nsample())
+                << std::endl;
+    }
+    // Output bins nonexistent in PDF (gmsh sometimes fails to plot the exiting
+    // bins if holes exist in the data, it also looks better as zero than holes)
+    for (std::size_t i=0; i<out.size(); ++i)
+      if (out[i] == 0) m_outFile << i+1 << "\t0" << std::endl;
+
+  } else { // If user-specified sample space extents, output outpdf array
+
+    std::size_t bin = 0;
+    for (const auto& q : outpdf) m_outFile << ++bin << ' ' << q << std::endl;
+
+  }
+
+  m_outFile << "$End" << c << "Data\n";
+
+  ErrChk( !m_outFile.bad(), "Failed to write to file: " + m_filename );
+}
+
+void
+PDFWriter::writeGmshBin( const BiPDF& pdf,
+                         const tk::ctr::PDFInfo& info,
+                         ctr::PDFCenteringType centering ) const
+// *****************************************************************************
+//  Write out standardized bivariate PDF to Gmsh (binary) format
+//! \param[in] pdf Bivariate PDF
+//! \param[in] info PDF metadata
+//! \param[in] centering Bin centering on sample space mesh
+// *****************************************************************************
+{
+  const auto& name = info.name;
+  const auto& uext = info.exts;
+  const auto& vars = info.vars;
+  const auto& it = info.it;
+  const auto& time = info.time;
+
+  assertSampleSpaceDimensions< 2 >( vars );
+  assertSampleSpaceExtents< 2 >( uext );
+
+  // Query and optionally override number of bins and minima of sample space if
+  // user-specified extents were given and copy probabilities from pdf to a
+  // logically 2D array for output
+  std::size_t nbix, nbiy;
+  tk::real xmin, xmax, ymin, ymax;
+  std::vector< tk::real > outpdf;
+  std::array< tk::real, 2 > binsize;
+  std::array< long, 2*BiPDF::dim > ext;
+  extents( pdf, uext, nbix, nbiy, xmin, xmax, ymin, ymax, binsize, ext, outpdf,
+           centering );
+
+  // Output metadata. The #s are unnecessary, but vi will color it differently.
+  m_outFile << "$Comments\n"
+            << "# vim: filetype=sh:\n"
+            << "# Joint bivariate PDF: " << name << '(' << vars[0] << ','
+            << vars[1] << ")\n"
+            << "# -----------------------------------------------\n"
+            << "# Numeric precision: 64-bit binary\n"
+            << "# Bin sizes: " << binsize[0] << ", " << binsize[1] << '\n'
+            << "# Number of bins estimated: " << ext[1] - ext[0] + 1 << " x "
+            << ext[3] - ext[2] + 1 << '\n'
+            << "# Number of bins output: " << nbix << " x " << nbiy << '\n'
+            << "# Sample space extents: [" << xmin << " : " << xmax
+            << "], [" << ymin << " : " << ymax << "]\n"
+            << "# Iteration: " << it << "\n"
+            << "# Physical time: " << time << "\n#\n"
+            << "$EndComments\n";
+
+  // Output mesh header: mesh version, file type, data size
+  m_outFile << "$MeshFormat\n2.2 1 8\n";
+  int one = 1;
+  m_outFile.write( reinterpret_cast<char*>(&one), sizeof(int) );
+  m_outFile << "\n$EndMeshFormat\n";
+  ErrChk( !m_outFile.bad(), "Failed to write to file: " + m_filename );
+
+  // Output grid points of discretized sample space (2D Cartesian grid)
+  m_outFile << "$Nodes\n" << (nbix+1)*(nbiy+1) << std::endl;
+  int k = 0;
+  tk::real z = 0.0;
+  for (std::size_t i=0; i<=nbiy; i++) {
+    tk::real I = static_cast< tk::real >( i );
+    tk::real y = ymin + I*binsize[1];
+    for (std::size_t j=0; j<=nbix; j++) {
+      tk::real J = static_cast< tk::real >( j );
+      tk::real x = xmin + J*binsize[0];
+      ++k;
+      m_outFile.write( reinterpret_cast< char* >( &k ), sizeof(int) );
+      m_outFile.write( reinterpret_cast< char* >( &x ), sizeof(tk::real) );
+      m_outFile.write( reinterpret_cast< char* >( &y ), sizeof(tk::real) );
+      m_outFile.write( reinterpret_cast< char* >( &z ), sizeof(tk::real) );
+    }
+  }
+  m_outFile << "\n$EndNodes\n";
+
+  // Output elements of discretized sample space (2D Cartesian grid)
+  m_outFile << "$Elements\n" << nbix*nbiy << "\n";
+  int type = 3;                 // gmsh elem type: 4-node quadrangle
+  std::size_t n = nbix*nbiy;    // number of elements in (this single) block
+  int ntags = 2;                // number of element tags
+  m_outFile.write( reinterpret_cast< char* >( &type ), sizeof(int) );
+  m_outFile.write( reinterpret_cast< char* >( &n ), sizeof(int) );
+  m_outFile.write( reinterpret_cast< char* >( &ntags ), sizeof(int) );
+  for (std::size_t i=0; i<n; ++i) {
+    const auto y = i/nbix;
+    auto id = i+1;
+    int tag[2] = { 1, 1 };
+    int con[4] = { static_cast< int >( i+y+1 ),
+                   static_cast< int >( i+y+2 ),
+                   static_cast< int >( i+y+nbix+3 ),
+                   static_cast< int >( i+y+nbix+2 ) };
+    m_outFile.write( reinterpret_cast< char* >( &id ), sizeof(int) );
+    m_outFile.write( reinterpret_cast< char* >( tag ), 2*sizeof(int) );
+    m_outFile.write( reinterpret_cast< char* >( con ), 4*sizeof(int) );
+  }
+  m_outFile << "\n$EndElements\n";
+
+  // Output PDF function values in element or node centers
+  std::string c( "Element" );
+  if (centering == ctr::PDFCenteringType::NODE) {
+    ++nbix; ++nbiy;
+    c = "Node";
+  }
+  m_outFile << '$' << c << "Data\n1\n\"" << name << "\"\n1\n0.0\n3\n0\n1\n"
+            << nbix*nbiy << "\n";
+
+  // If no user-specified sample space extents, output pdf map directly
+  if (uext.empty()) {
+
+    std::vector< int > out( nbix*nbiy, 0 ); // indicate bins filled
+    for (const auto& p : pdf.map()) {
+      const auto bin = (p.first[1] - ext[2]) * static_cast<long>(nbix) +
+                       (p.first[0] - ext[0]) % static_cast<long>(nbix);
+      Assert( bin >= 0, "Bin underflow in PDFWriter::writeGmshBin()." );
+      Assert( static_cast<std::size_t>(bin) < nbix*nbiy,
+              "Bin overflow in PDFWriter::writeGmshBin()." );
+      out[ static_cast<std::size_t>(bin) ] = 1;
+      auto id = static_cast<int>(bin+1);
+      tk::real prob = p.second / binsize[0] / binsize[1]
+                               / static_cast<tk::real>(pdf.nsample());
+      m_outFile.write( reinterpret_cast< char* >( &id ), sizeof(int) );
+      m_outFile.write( reinterpret_cast< char* >( &prob ), sizeof(tk::real) );
+    }
+    // Output bins nonexistent in PDF (gmsh sometimes fails to plot the exiting
+    // bins if holes exist in the data, it also looks better as zero than holes)
+    tk::real prob = 0.0;
+    for (std::size_t i=0; i<out.size(); ++i)
+      if (out[i] == 0) {
+        auto id = static_cast<int>(i+1);
+        m_outFile.write( reinterpret_cast< char* >( &id ), sizeof(int) );
+        m_outFile.write( reinterpret_cast< char* >( &prob ), sizeof(tk::real) );
+      }
+
+  } else { // If user-specified sample space extents, output outpdf array
+
+    int bin = 0;
+    for (auto& p : outpdf) {
+      ++bin;
+      m_outFile.write( reinterpret_cast< char* >( &bin ), sizeof(int) );
+      m_outFile.write( reinterpret_cast< char* >( &p ), sizeof(tk::real) );
+    }
+
+  }
+
+  m_outFile << "$End" << c << "Data\n";
+
+  ErrChk( !m_outFile.bad(), "Failed to write to file: " + m_filename );
+}
+
+void
+PDFWriter::writeGmshBin( const TriPDF& pdf,
+                         const tk::ctr::PDFInfo& info,
+                         ctr::PDFCenteringType centering ) const
+// *****************************************************************************
+//  Write out standardized trivariate PDF to Gmsh (binary) format
+//! \param[in] pdf Trivariate PDF
+//! \param[in] info PDF metadata
+//! \param[in] centering Bin centering on sample space mesh
+// *****************************************************************************
+{
+  const auto& name = info.name;
+  const auto& uext = info.exts;
+  const auto& vars = info.vars;
+  const auto& it = info.it;
+  const auto& time = info.time;
+
+  assertSampleSpaceDimensions< 3 >( vars );
+  assertSampleSpaceExtents< 3 >( uext );
+
+  // Query and optionally override number of bins and minima of sample space if
+  // user-specified extents were given and copy probabilities from pdf to a
+  // logically 3D array for output
+  std::size_t nbix, nbiy, nbiz;
+  tk::real xmin, xmax, ymin, ymax, zmin, zmax;
+  std::vector< tk::real > outpdf;
+  std::array< tk::real, 3 > binsize;
+  std::array< long, 2*TriPDF::dim > ext;
+  extents( pdf, uext, nbix, nbiy, nbiz, xmin, xmax, ymin, ymax, zmin, zmax,
+           binsize, ext, outpdf, centering );
+
+  // Output metadata. The #s are unnecessary, but vi will color it differently.
+  m_outFile << "$Comments\n"
+            << "# vim: filetype=sh:\n#\n"
+            << "# Joint trivariate PDF: " << name << '(' << vars[0] << ','
+            << vars[1] << ',' << vars[2] << ")\n"
+            << "# -----------------------------------------------\n"
+            << "# Numeric precision: 64-bit binary\n"
+            << "# Bin sizes: " << binsize[0] << ", " << binsize[1] << ", "
+            << binsize[2] << '\n'
+            << "# Number of bins estimated: " << ext[1] - ext[0] + 1 << " x "
+            << ext[3] - ext[2] + 1 << " x " << ext[5] - ext[4] + 1 << '\n'
+            << "# Number of bins output: " << nbix << " x " << nbiy << " x "
+            << nbiz << '\n'
+            << "# Sample space extents: [" << xmin << " : " << xmax << "], ["
+            << ymin << " : " << ymax << "], [" << zmin << " : " << zmax << "]\n"
+            << "# Iteration: " << it << "\n"
+            << "# Physical time: " << time << "\n#\n"
+            << "$EndComments\n";
+
+  // Output mesh header: mesh version, file type, data size
+  m_outFile << "$MeshFormat\n2.2 1 8\n";
+  int one = 1;
+  m_outFile.write( reinterpret_cast<char*>(&one), sizeof(int) );
+  m_outFile << "\n$EndMeshFormat\n";
+  ErrChk( !m_outFile.bad(), "Failed to write to file: " + m_filename );
+
+  // Output grid points of discretized sample space (3D Cartesian grid)
+  m_outFile << "$Nodes\n" << (nbix+1)*(nbiy+1)*(nbiz+1) << std::endl;
+  int l=0;
+  for (std::size_t k=0; k<=nbiz; k++) {
+    tk::real K = static_cast< tk::real >( k );
+    tk::real z = zmin + K*binsize[2];
+    for (std::size_t j=0; j<=nbiy; j++) {
+      tk::real J = static_cast< tk::real >( j );
+      tk::real y = ymin + J*binsize[1];
+      for (std::size_t i=0; i<=nbix; i++) {
+        tk::real I = static_cast< tk::real >( i );
+        tk::real x = xmin + I*binsize[0];
+        ++l;
+        m_outFile.write( reinterpret_cast< char* >( &l ), sizeof(int) );
+        m_outFile.write( reinterpret_cast< char* >( &x ), sizeof(tk::real) );
+        m_outFile.write( reinterpret_cast< char* >( &y ), sizeof(tk::real) );
+        m_outFile.write( reinterpret_cast< char* >( &z ), sizeof(tk::real) );
+      }
+    }
+  }
+  m_outFile << "\n$EndNodes\n";
+
+  // Output elements of discretized sample space (3D Cartesian grid)
+  m_outFile << "$Elements\n" << nbix*nbiy*nbiz << "\n";
+  int type = 5;                       // gmsh elem type: 8-node hexahedron
+  std::size_t nelem = nbix*nbiy*nbiz; // num of elements in (this single) block
+  int ntags = 2;                      // number of element tags
+  m_outFile.write( reinterpret_cast< char* >( &type ), sizeof(int) );
+  m_outFile.write( reinterpret_cast< char* >( &nelem ), sizeof(int) );
+  m_outFile.write( reinterpret_cast< char* >( &ntags ), sizeof(int) );
+  const auto n = nbix*nbiy;
+  const auto p = (nbix+1)*(nbiy+1);
+  for (std::size_t i=0; i<nelem; ++i) {
+    const auto y = i/nbix + i/n*(nbix+1);
+    auto id = i+1;
+    int tag[2] = { 1, 1 };
+    int con[8] = { static_cast< int >( i+y+1 ),
+                   static_cast< int >( i+y+2 ),
+                   static_cast< int >( i+y+nbix+3 ),
+                   static_cast< int >( i+y+nbix+2 ),
+                   static_cast< int >( i+y+p+1 ),
+                   static_cast< int >( i+y+p+2 ),
+                   static_cast< int >( i+y+p+nbix+3 ),
+                   static_cast< int >( i+y+p+nbix+2 ) };
+    m_outFile.write( reinterpret_cast< char* >( &id ), sizeof(int) );
+    m_outFile.write( reinterpret_cast< char* >( tag ), 2*sizeof(int) );
+    m_outFile.write( reinterpret_cast< char* >( con ), 8*sizeof(int) );
+  }
+  m_outFile << "\n$EndElements\n";
+
+  // Output PDF function values in element or node centers
+  std::string c( "Element" );
+  if (centering == ctr::PDFCenteringType::NODE) {
+    ++nbix; ++nbiy; ++nbiz;
+    c = "Node";
+  }
+  m_outFile << '$' << c << "Data\n1\n\"" << name << "\"\n1\n0.0\n3\n0\n1\n"
+            << nbix*nbiy*nbiz << "\n";
+
+  // If no user-specified sample space extents, output pdf map directly
+  if (uext.empty()) {
+
+    std::vector< int > out( nbix*nbiy*nbiz, 0 ); // indicate bins filled
+    for (const auto& q : pdf.map()) {
+      const auto bin = (q.first[2] - ext[4]) * static_cast<long>(nbix*nbiy) +
+                       (q.first[1] - ext[2]) * static_cast<long>(nbix) +
+                       (q.first[0] - ext[0]) % static_cast<long>(nbix);
+      Assert( bin >= 0, "Bin underflow in PDFWriter::writeGmshBin()." );
+      Assert( static_cast<std::size_t>(bin) < nbix*nbiy*nbiz,
+              "Bin overflow in PDFWriter::writeGmshBin()." );
+      out[ static_cast<std::size_t>(bin) ] = 1;
+      auto id = static_cast<int>(bin+1);
+      tk::real prob = q.second / binsize[0] / binsize[1] / binsize[2]
+                               / static_cast<tk::real>(pdf.nsample());
+      m_outFile.write( reinterpret_cast< char* >( &id ), sizeof(int) );
+      m_outFile.write( reinterpret_cast< char* >( &prob ), sizeof(tk::real) );
+    }
+    // Output bins nonexistent in PDF (gmsh sometimes fails to plot the exiting
+    // bins if holes exist in the data, it also looks better as zero than holes)
+    tk::real prob = 0.0;
+    for (std::size_t i=0; i<out.size(); ++i)
+      if (out[i] == 0) {
+        auto id = static_cast<int>(i+1);
+        m_outFile.write( reinterpret_cast< char* >( &id ), sizeof(int) );
+        m_outFile.write( reinterpret_cast< char* >( &prob ), sizeof(tk::real) );
+      }
+
+  } else { // If user-specified sample space extents, output outpdf array
+
+    int bin = 0;
+    for (auto& q : outpdf) {
+      ++bin;
+      m_outFile.write( reinterpret_cast< char* >( &bin ), sizeof(int) );
+      m_outFile.write( reinterpret_cast< char* >( &q ), sizeof(tk::real) );
+    }
+
+  }
+
+  m_outFile << "$End" << c << "Data\n";
+
+  ErrChk( !m_outFile.bad(), "Failed to write to file: " + m_filename );
+}
+
+void
+PDFWriter::writeExodusII( const BiPDF& pdf,
+                          const tk::ctr::PDFInfo& info,
+                          ctr::PDFCenteringType centering ) const
+// *****************************************************************************
+//  Write out standardized bivariate PDF to Exodus II format
+//! \param[in] pdf Bivariate PDF
+//! \param[in] info PDF metadata
+//! \param[in] centering Bin centering on sample space mesh
+// *****************************************************************************
+{
+  const auto& name = info.name;
+  const auto& uext = info.exts;
+  const auto& vars = info.vars;
+
+  assertSampleSpaceDimensions< 2 >( vars );
+  assertSampleSpaceExtents< 2 >( uext );
+
+  // Query and optionally override number of bins and minima of sample space if
+  // user-specified extents were given and copy probabilities from pdf to a
+  // logically 2D array for output
+  std::size_t nbix, nbiy;
+  tk::real xmin, xmax, ymin, ymax;
+  std::vector< tk::real > outpdf;
+  std::array< tk::real, 2 > binsize;
+  std::array< long, 2*BiPDF::dim > ext;
+  extents( pdf, uext, nbix, nbiy, xmin, xmax, ymin, ymax, binsize, ext, outpdf,
+           centering );
+
+  // Create ExodusII file
+  int outFile = createExFile();
+
+  // Compute number of nodes and number of elements in sample space mesh
+  std::size_t nelem = nbix*nbiy;
+  std::size_t nnode = (nbix+1)*(nbiy+1);
+
+  // Write ExodusII header
+  writeExHdr( outFile, static_cast<int>(nnode), static_cast<int>(nelem) );
+
+  // Write sample space variables as coordinate names
+  char* coordnames[] = { const_cast< char* >( vars[0].c_str() ),
+                         const_cast< char* >( vars[1].c_str() ),
+                         const_cast< char* >( "probability" ) };
+  ErrChk( ex_put_coord_names( outFile, coordnames ) == 0,
+          "Failed to write coordinate names to file: " + m_filename );
+
+  // Output grid points of discretized sample space (2D Cartesian grid)
+  std::vector< tk::real > x( nnode, 0.0 );
+  std::vector< tk::real > y( nnode, 0.0 );
+  std::vector< tk::real > z( nnode, 0.0 );
+  std::size_t k = 0;
+  for (std::size_t i=0; i<=nbiy; i++)
+    for (std::size_t j=0; j<=nbix; j++) {
+      x[k] = xmin + static_cast< tk::real >( j )*binsize[0];
+      y[k] = ymin + static_cast< tk::real >( i )*binsize[1];
+      ++k;
+    }
+  ErrChk( ex_put_coord( outFile, x.data(), y.data(), z.data() ) == 0,
+          "Failed to write coordinates to file: " + m_filename );
+
+  // Output elements of discretized sample space (2D Cartesian grid)
+  // Write element block information
+  ErrChk( ex_put_block( outFile,
+                        EX_ELEM_BLOCK,
+                        1,
+                        "QUADRANGLES",
+                        static_cast<int64_t>(nelem),
+                        4,
+                        0,
+                        0,
+                        0 ) == 0,
+          "Failed to write QUDARANGLE element block to file: " + m_filename );
+  // Write element connectivity
+  for (std::size_t i=0; i<nelem; ++i) {
+    auto ye = i/nbix;
+    int con[4] = { static_cast< int >( i+ye+1 ),
+                   static_cast< int >( i+ye+2 ),
+                   static_cast< int >( i+ye+nbix+3 ),
+                   static_cast< int >( i+ye+nbix+2 ) };
+    ErrChk( ex_put_partial_conn( outFile, EX_ELEM_BLOCK, 1,
+              static_cast<int64_t>(i+1), 1, con, nullptr, nullptr ) == 0,
+      "Failed to write element connectivity to file: " + m_filename );
+  }
+
+  // Output PDF function values in element or node centers
+  ex_entity_type c = EX_ELEM_BLOCK;
+  if (centering == ctr::PDFCenteringType::NODE) {
+    ++nbix; ++nbiy;<--- Variable 'nbix' is assigned a value that is never used.<--- Variable 'nbiy' is assigned a value that is never used.
+    c = EX_NODE_BLOCK;
+  }
+
+  // Write PDF function values metadata
+  ErrChk( ex_put_variable_param( outFile, c, 1 ) == 0,
+            "Failed to write results metadata to file: " + m_filename );
+  char* probname[1];
+  std::string pdfname( name + '(' + vars[0] + ',' + vars[1] + ')' );
+  probname[0] = const_cast< char* >( pdfname.c_str() );
+  ErrChk( ex_put_variable_names( outFile, c, 1, probname ) == 0,
+            "Failed to write results metadata to file: " + m_filename );
+
+  // If no user-specified sample space extents, output pdf map directly
+  if (uext.empty()) {
+
+    // Output PDF function values in element centers
+    std::vector< tk::real > prob( nbix*nbiy, 0.0 );
+    for (const auto& p : pdf.map()) {
+      const auto bin = (p.first[1] - ext[2]) * static_cast<long>(nbix) +
+                       (p.first[0] - ext[0]) % static_cast<long>(nbix);
+      Assert( bin >= 0, "Bin underflow in PDFWriter::writeExodusII()." );
+      Assert( static_cast<std::size_t>(bin) < nbix*nbiy,
+              "Bin overflow in PDFWriter::writeExodusII()." );
+      prob[ static_cast<std::size_t>(bin) ] =
+        p.second / binsize[0] / binsize[1]
+                 / static_cast<tk::real>(pdf.nsample());
+    }
+    writeExVar( outFile, centering, prob );
+
+  } else { // If user-specified sample space extents, output outpdf array
+
+    writeExVar( outFile, centering, outpdf );
+
+  }
+
+  ErrChk( ex_close(outFile) == 0, "Failed to close file: " + m_filename );
+}
+
+void
+PDFWriter::writeExodusII( const TriPDF& pdf,
+                          const tk::ctr::PDFInfo& info,
+                          ctr::PDFCenteringType centering ) const
+// *****************************************************************************
+//  Write out standardized trivariate PDF to Exodus II format
+//! \param[in] pdf Trivariate PDF
+//! \param[in] info PDF metadata
+//! \param[in] centering Bin centering on sample space mesh
+// *****************************************************************************
+{
+  const auto& name = info.name;
+  const auto& uext = info.exts;
+  const auto& vars = info.vars;
+
+  assertSampleSpaceDimensions< 3 >( vars );
+  assertSampleSpaceExtents< 3 >( uext );
+
+  // Query and optionally override number of bins and minima of sample space if
+  // user-specified extents were given and copy probabilities from pdf to a
+  // logically 3D array for output
+  std::size_t nbix, nbiy, nbiz;
+  tk::real xmin, xmax, ymin, ymax, zmin, zmax;
+  std::vector< tk::real > outpdf;
+  std::array< tk::real, 3 > binsize;
+  std::array< long, 2*TriPDF::dim > ext;
+  extents( pdf, uext, nbix, nbiy, nbiz, xmin, xmax, ymin, ymax, zmin, zmax,
+           binsize, ext, outpdf, centering );
+
+  // Create ExodusII file
+  int outFile = createExFile();
+
+  // Compute number of nodes and number of elements in sample space mesh
+  std::size_t nelem = nbix*nbiy*nbiz;
+  std::size_t nnode = (nbix+1)*(nbiy+1)*(nbiz+1);
+
+  // Write ExodusII header
+  writeExHdr( outFile, static_cast<int>(nnode), static_cast<int>(nelem) );
+
+  // Write sample space variables as coordinate names
+  char* coordnames[] = { const_cast< char* >( vars[0].c_str() ),
+                         const_cast< char* >( vars[1].c_str() ),
+                         const_cast< char* >( vars[2].c_str() ) };
+  ErrChk( ex_put_coord_names( outFile, coordnames ) == 0,
+          "Failed to write coordinate names to file: " + m_filename );
+
+  // Output grid points of discretized sample space (2D Cartesian grid)
+  std::vector< tk::real > x( nnode, 0.0 );
+  std::vector< tk::real > y( nnode, 0.0 );
+  std::vector< tk::real > z( nnode, 0.0 );
+  std::size_t l=0;
+  for (std::size_t k=0; k<=nbiz; k++)
+    for (std::size_t i=0; i<=nbiy; i++)
+      for (std::size_t j=0; j<=nbix; j++) {
+        x[l] = xmin + static_cast<tk::real>(j) * binsize[0];
+        y[l] = ymin + static_cast<tk::real>(i) * binsize[1];
+        z[l] = zmin + static_cast<tk::real>(k) * binsize[2];
+        ++l;
+      }
+  ErrChk( ex_put_coord( outFile, x.data(), y.data(), z.data() ) == 0,
+          "Failed to write coordinates to file: " + m_filename );
+
+  // Output elements of discretized sample space (2D Cartesian grid)
+  // Write element block information
+  ErrChk( ex_put_block( outFile,
+                        EX_ELEM_BLOCK,
+                        1,
+                        "HEXAHEDRA",
+                        static_cast<int64_t>(nelem),
+                        8,
+                        0,
+                        0,
+                        0 ) == 0,
+          "Failed to write HEXAHEDRA element block to file: " + m_filename );
+  // Write element connectivity
+  const auto n = nbix*nbiy;
+  const auto p = (nbix+1)*(nbiy+1);
+  for (std::size_t i=0; i<nelem; ++i) {
+    const auto ye = i/nbix + i/n*(nbix+1);
+    int con[8] = { static_cast< int >( i+ye+1 ),
+                   static_cast< int >( i+ye+2 ),
+                   static_cast< int >( i+ye+nbix+3 ),
+                   static_cast< int >( i+ye+nbix+2 ),
+                   static_cast< int >( i+ye+p+1 ),
+                   static_cast< int >( i+ye+p+2 ),
+                   static_cast< int >( i+ye+p+nbix+3 ),
+                   static_cast< int >( i+ye+p+nbix+2 ) };
+    ErrChk(
+      ex_put_partial_conn( outFile, EX_ELEM_BLOCK, 1,
+        static_cast<int64_t>(i+1), 1, con, nullptr, nullptr ) == 0,
+      "Failed to write element connectivity to file: " + m_filename );
+  }
+
+  // Output PDF function values in element or node centers
+  ex_entity_type c = EX_ELEM_BLOCK;
+  if (centering == ctr::PDFCenteringType::NODE) {
+    ++nbix; ++nbiy; ++nbiz;<--- Variable 'nbix' is assigned a value that is never used.<--- Variable 'nbiy' is assigned a value that is never used.<--- Variable 'nbiz' is assigned a value that is never used.
+    c = EX_NODE_BLOCK;
+  }
+
+  // Write PDF function values metadata
+  ErrChk( ex_put_variable_param( outFile, c, 1 ) == 0,
+            "Failed to write results metadata to file: " + m_filename );
+  char* probname[1];
+  std::string pdfname( name + '(' + vars[0] + ',' +
+                         vars[1] + ',' + vars[2] + ')' );
+  probname[0] = const_cast< char* >( pdfname.c_str() );
+  ErrChk( ex_put_variable_names( outFile, c, 1, probname ) == 0,
+            "Failed to write results metadata to file: " + m_filename );
+
+  // If no user-specified sample space extents, output pdf map directly
+  if (uext.empty()) {
+
+    // Output PDF function values in element centers
+    std::vector< tk::real > prob( nbix*nbiy*nbiz, 0.0 );
+    for (const auto& q : pdf.map()) {
+      const auto bin = (q.first[2] - ext[4]) * static_cast<long>(nbix*nbiy) +
+                       (q.first[1] - ext[2]) * static_cast<long>(nbix) +
+                       (q.first[0] - ext[0]) % static_cast<long>(nbix);
+      Assert( bin >= 0, "Bin underflow in PDFWriter::writeExodusII()." );
+      Assert( static_cast<std::size_t>(bin) < nbix*nbiy*nbiz,
+              "Bin overflow in PDFWriter::writeExodusII()." );
+      prob[ static_cast<std::size_t>(bin) ] =
+        q.second / binsize[0] / binsize[1] / binsize[2]
+                 / static_cast<tk::real>(pdf.nsample());
+    }
+    writeExVar( outFile, centering, prob );
+
+  } else { // If user-specified sample space extents, output outpdf array
+
+    writeExVar( outFile, centering, outpdf );
+
+  }
+
+  ErrChk( ex_close(outFile) == 0, "Failed to close file: " + m_filename );
+}
+
+int
+PDFWriter::createExFile() const
+// *****************************************************************************
+//  Create Exodus II file
+//! \return ExodusII file handle
+// *****************************************************************************
+{
+  int cpuwordsize = sizeof( double );
+  int iowordsize = sizeof( double );
+  int outFileId = ex_create( m_filename.c_str(),
+                             EX_CLOBBER | EX_NORMAL_MODEL,
+                             &cpuwordsize,
+                             &iowordsize );
+  ErrChk( outFileId > 0, "Failed to create file: " + m_filename );
+  return outFileId;
+}
+
+void
+PDFWriter::writeExHdr( int outFileId, int nnode, int nelem ) const
+// *****************************************************************************
+//  Write Exodus II file header
+//! \param[in] outFileId Output file ExodusII Id
+//! \param[in] nnode Number of nodes in mesh to write
+//! \param[in] nelem Number of elements in mesh to write
+// *****************************************************************************
+{
+  ErrChk( ex_put_init( outFileId,
+                       "Written by Quinoa",
+                       3,                     // number of dimensions
+                       nnode,                 // number of nodes
+                       nelem,                 // number of elements
+                       1,                     // number of element blocks
+                       0,                     // number of node sets
+                       0 ) == 0,              // number of side sets
+          "Failed to write header to file: " + m_filename );
+}
+
+void
+PDFWriter::writeExVar( int exoFile,
+                       ctr::PDFCenteringType centering,
+                       const std::vector< tk::real >& probability ) const
+// *****************************************************************************
+//  Output probability density function as Exodus II results field
+//! \param[in] exoFile ExodusII file handle to write to
+//! \param[in] centering Node-, or element-centering to use on sample space mesh
+//! \param[in] probability Probabilities at each sample space location
+// *****************************************************************************
+{
+  if (centering == ctr::PDFCenteringType::NODE)
+    ErrChk( ex_put_var( exoFile,
+                        1,
+                        EX_NODE_BLOCK,
+                        1,
+                        1,
+                        static_cast<int64_t>(probability.size()),
+                        probability.data() ) == 0,
+            "Failed to write node-centered bivariate PDF to file: " +
+            m_filename );
+  else
+    ErrChk( ex_put_var( exoFile,
+                        1,
+                        EX_ELEM_BLOCK,
+                        1,
+                        1,
+                        static_cast<int64_t>(probability.size()),
+                        probability.data() ) == 0,
+            "Failed to write elem-centered bivariate PDF to file: " +
+            m_filename );
+}
+
+void
+PDFWriter::extents( const UniPDF& pdf,
+                    const std::vector< tk::real >& uext,
+                    std::size_t& nbi,
+                    tk::real& min,
+                    tk::real& max,
+                    tk::real& binsize,
+                    std::array< long, 2*UniPDF::dim >& ext,
+                    std::vector< tk::real >& outpdf ) const
+// *****************************************************************************
+//  Query extents and other metadata of univariate PDF sample space
+//! \details Query and optionally override number of bins and minimum of sample
+//!    space if user-specified extents were given and copy probabilities from
+//!    pdf to an array for output for plotting univariate PDF.
+//! \param[in] pdf Univariate PDF object
+//! \param[in] uext User-specified extents of sample space
+//! \param[inout] nbi Number of bins
+//! \param[inout] min Minimum value of sample space
+//! \param[inout] max Maximum value of sample space
+//! \param[inout] binsize Bin size
+//! \param[inout] ext Extents of sample space
+//! \param[inout] outpdf PDF ready to be written out to file
+// *****************************************************************************
+{
+  assertSampleSpaceExtents< 1 >( uext );
+
+  // Query bin size and extents of sample space from PDF
+  binsize = pdf.binsize();
+  ext = pdf.extents();
+
+  // Compute number of bins of sample space (min bins: 1)
+  Assert( ext[1] >= ext[0], "Wrong extents in PDFWriter::extents" );
+  nbi = static_cast< std::size_t >( ext[1] - ext[0] + 1 );
+
+  // Compute minimum and maximum of sample space
+  min = binsize * static_cast< tk::real >( ext[0] );
+  max = binsize * static_cast< tk::real >( ext[1] );
+
+  // Override number of bins and minimum if user-specified extents were given,
+  // and copy probabilities from pdf to an array for output
+  if (!uext.empty()) {
+    // Override number of bins by that based on user-specified extents
+    Assert( uext[1] >= uext[0],
+            "Wrong user-defined extents in PDFWriter::extents" );
+    nbi = static_cast< std::size_t >(
+            std::lround( (uext[1] - uext[0]) / binsize ) );
+    // Override extents
+    min = uext[0];
+    max = uext[1];
+
+    // Size output pdf to user-requested dimensions to overridden nbi and
+    // initialize output probabilities to zero
+    outpdf = std::vector< tk::real >( nbi, 0.0 );
+
+    // Fill requested region of pdf to be output from computed pdf
+    for (const auto& p : pdf.map()) {
+      // Compute (i.e., shift) bin indices relative to user-requested extents
+      const auto bin = p.first - std::lround( uext[0] / binsize );
+      // Only copy probability value if shifted bin indices fall within
+      // user-requested extents (lower inclusive, upper exclusive)
+      if (bin >= 0 && bin < std::lround( (uext[1] - uext[0]) / binsize )) {
+        Assert( static_cast<std::size_t>(bin) < nbi,
+                "Bin overflow in user-specified-extent-based bin "
+                "calculation of univariate PDF extents." );
+        // Copy normalized probability to output pdf
+        outpdf[ static_cast<std::size_t>(bin) ] =
+          p.second / binsize / static_cast<tk::real>(pdf.nsample());
+      }
+    }
+  }
+}
+
+void
+PDFWriter::extents( const BiPDF& pdf,
+                    const std::vector< tk::real >& uext,
+                    std::size_t& nbix,
+                    std::size_t& nbiy,
+                    tk::real& xmin,
+                    tk::real& xmax,
+                    tk::real& ymin,
+                    tk::real& ymax,
+                    std::array< tk::real, BiPDF::dim >& binsize,
+                    std::array< long, 2*BiPDF::dim >& ext,
+                    std::vector< tk::real >& outpdf,
+                    ctr::PDFCenteringType centering ) const
+// *****************************************************************************
+//  Query extents and other metadata of bivariate PDF sample space
+//! \details Query and optionally override number of bins and minima of sample
+//!    space if user-specified extents were given and copy probabilities from
+//!    pdf to a logically 2D array for output for plotting bivariate joint PDF.
+//! \param[in] pdf Bivariate PDF object
+//! \param[in] uext User-specified extents of sample space
+//! \param[inout] nbix Number of bins in x dimension
+//! \param[inout] nbiy Number of bins in y dimension
+//! \param[inout] xmin Minimum x value of sample space
+//! \param[inout] xmax Maximum x value of sample space
+//! \param[inout] ymin Minimum y value of sample space
+//! \param[inout] ymax Maximum y value of sample space
+//! \param[inout] binsize Bin size
+//! \param[inout] ext Extents of sample space
+//! \param[inout] outpdf PDF ready to be written out to file
+//! \param[in] centering Bin centering on sample space mesh
+// *****************************************************************************
+{
+  assertSampleSpaceExtents< 2 >( uext );
+
+  // Query bin sizes and extents of sample space from PDF
+  binsize = pdf.binsize();
+  ext = pdf.extents();
+
+  // Compute number of bins in sample space directions (min bins: 1)
+  Assert( ext[1] >= ext[0], "Wrong extents in PDFWriter::extents" );
+  Assert( ext[3] >= ext[2], "Wrong extents in PDFWriter::extents" );
+  nbix = static_cast< std::size_t >( ext[1] - ext[0] + 1 );
+  nbiy = static_cast< std::size_t >( ext[3] - ext[2] + 1 );
+
+  // Compute minima and maxima of sample space
+  xmin = binsize[0] * static_cast< tk::real >( ext[0] );
+  xmax = binsize[0] * static_cast< tk::real >( ext[1] );
+  ymin = binsize[1] * static_cast< tk::real >( ext[2] );
+  ymax = binsize[1] * static_cast< tk::real >( ext[3] );
+
+  // Override number of bins and minima if user-specified extents were given,
+  // and copy probabilities from pdf to a logically 2D array for output
+  if (!uext.empty()) {
+    // Override number of bins by that based on user-specified extents
+    Assert( uext[1] >= uext[0],
+            "Wrong user-defined extents in PDFWriter::extents" );
+    Assert( uext[3] >= uext[2],
+            "Wrong user-defined extents in PDFWriter::extents" );
+    nbix = static_cast< std::size_t >(
+             std::lround( (uext[1] - uext[0]) / binsize[0] ) );
+    nbiy = static_cast< std::size_t >(
+             std::lround( (uext[3] - uext[2]) / binsize[1] ) );
+    // Override extents
+    xmin = uext[0];
+    xmax = uext[1];
+    ymin = uext[2];
+    ymax = uext[3];
+
+    // Temporarily increase number of bins if node-centered output required
+    if (centering == ctr::PDFCenteringType::NODE) { ++nbix; ++nbiy; }
+
+    // Size output pdf to user-requested dimensions to overridden nbiy * nbix
+    // and initialize output probabilities to zero
+    outpdf = std::vector< tk::real >( nbix*nbiy, 0.0 );
+
+    // Fill requested region of pdf to be output from computed pdf
+    for (const auto& p : pdf.map()) {
+      // Compute (i.e., shift) bin indices relative to user-requested extents
+      const auto x = p.first[0] - std::lround( uext[0] / binsize[0] );
+      const auto y = p.first[1] - std::lround( uext[2] / binsize[1] );
+      // Only copy probability value if shifted bin indices fall within
+      // user-requested extents (lower inclusive, upper exclusive)
+      if (x >= 0 && x < std::lround( (uext[1] - uext[0]) / binsize[0] ) &&
+          y >= 0 && y < std::lround( (uext[3] - uext[2]) / binsize[1] ))
+      {
+        const auto bin =
+          static_cast<std::size_t>(y)*nbix + static_cast<std::size_t>(x);
+        Assert( bin < nbix*nbiy, "Bin overflow in user-specified-extent-based "
+                "bin calculation of bivariate PDF." );
+        // Copy normalized probability to output pdf
+        outpdf[ bin ] = p.second / binsize[0] / binsize[1]
+                                 / static_cast<tk::real>(pdf.nsample());
+      }
+    }
+
+    // Revert number of bins if node-centered output required
+    if (centering == ctr::PDFCenteringType::NODE) { --nbix; --nbiy; }
+  }
+}
+
+void
+PDFWriter::extents( const TriPDF& pdf,
+                    const std::vector< tk::real >& uext,
+                    std::size_t& nbix,
+                    std::size_t& nbiy,
+                    std::size_t& nbiz,
+                    tk::real& xmin,
+                    tk::real& xmax,
+                    tk::real& ymin,
+                    tk::real& ymax,
+                    tk::real& zmin,
+                    tk::real& zmax,
+                    std::array< tk::real, TriPDF::dim >& binsize,
+                    std::array< long, 2*TriPDF::dim >& ext,
+                    std::vector< tk::real >& outpdf,
+                    ctr::PDFCenteringType centering ) const
+// *****************************************************************************
+//  Query extents and other metadata of trivariate PDF sample space
+//! \details Query and optionally override number of bins and minima of sample
+//!   space if user-specified extents were given and copy probabilities from
+//!   pdf to a logically 3D array for output for plotting trivariate joint PDF.
+//! \param[in] pdf Trivariate PDF object
+//! \param[in] uext User-specified extents of sample space
+//! \param[inout] nbix Number of bins in x dimension
+//! \param[inout] nbiy Number of bins in y dimension
+//! \param[inout] nbiz Number of bins in z dimension
+//! \param[inout] xmin Minimum x value of sample space
+//! \param[inout] xmax Maximum x value of sample space
+//! \param[inout] ymin Minimum y value of sample space
+//! \param[inout] ymax Maximum y value of sample space
+//! \param[inout] zmin Minimum z value of sample space
+//! \param[inout] zmax Maximum z value of sample space
+//! \param[inout] binsize Bin size
+//! \param[inout] ext Extents of sample space
+//! \param[inout] outpdf PDF ready to be written out to file
+//! \param[in] centering Bin centering on sample space mesh
+// *****************************************************************************
+{
+  assertSampleSpaceExtents< 3 >( uext );
+
+  // Query bin sizes and extents of sample space from PDF
+  binsize = pdf.binsize();
+  ext = pdf.extents();
+
+  // Compute number of bins in sample space directions (min bins: 1)
+  Assert( ext[1] >= ext[0], "Wrong extents in PDFWriter::extents" );
+  Assert( ext[3] >= ext[2], "Wrong extents in PDFWriter::extents" );
+  Assert( ext[5] >= ext[4], "Wrong extents in PDFWriter::extents" );
+  nbix = static_cast< std::size_t >( ext[1] - ext[0] + 1 );
+  nbiy = static_cast< std::size_t >( ext[3] - ext[2] + 1 );
+  nbiz = static_cast< std::size_t >( ext[5] - ext[4] + 1 );
+
+  // Compute minima and maxima of sample space
+  xmin = binsize[0] * static_cast< tk::real >( ext[0] );
+  xmax = binsize[0] * static_cast< tk::real >( ext[1] );
+  ymin = binsize[1] * static_cast< tk::real >( ext[2] );
+  ymax = binsize[1] * static_cast< tk::real >( ext[3] );
+  zmin = binsize[2] * static_cast< tk::real >( ext[4] );
+  zmax = binsize[2] * static_cast< tk::real >( ext[5] );
+
+  // Override number of bins and minima if user-specified extents were given,
+  // and copy probabilities from pdf to a logically 3D array for output
+  if (!uext.empty()) {
+    // Override number of bins by that based on user-specified extents
+    Assert( uext[1] >= uext[0],
+            "Wrong user-defined extents in PDFWriter::extents" );
+    Assert( uext[3] >= uext[2],
+            "Wrong user-defined extents in PDFWriter::extents" );
+    Assert( uext[5] >= uext[4],
+            "Wrong user-defined extents in PDFWriter::extents" );
+    nbix = static_cast< std::size_t >(
+             std::lround( (uext[1] - uext[0]) / binsize[0] ) );
+    nbiy = static_cast< std::size_t >(
+             std::lround( (uext[3] - uext[2]) / binsize[1] ) );
+    nbiz = static_cast< std::size_t >(
+             std::lround( (uext[5] - uext[4]) / binsize[2] ) );
+    // Override extents
+    xmin = uext[0];
+    xmax = uext[1];
+    ymin = uext[2];
+    ymax = uext[3];
+    zmin = uext[4];
+    zmax = uext[5];
+
+    // Temporarily increase number of bins if node-centered output required
+    if (centering == ctr::PDFCenteringType::NODE) { ++nbix; ++nbiy; ++nbiz; }
+
+    // Size output pdf to user-requested dimensions to overridden nbiz * nbiy *
+    // nbix and initialize output probabilities to zero
+    outpdf = std::vector< tk::real >( nbiz * nbiy * nbix, 0.0 );
+
+    // Fill requested region of pdf to be output from computed pdf
+    for (const auto& p : pdf.map()) {
+      // Compute (i.e., shift) bin indices relative to user-requested extents
+      const auto x = p.first[0] - std::lround( uext[0] / binsize[0] );
+      const auto y = p.first[1] - std::lround( uext[2] / binsize[1] );
+      const auto z = p.first[2] - std::lround( uext[4] / binsize[2] );
+      // Only copy probability value if shifted bin indices fall within
+      // user-requested extents (lower inclusive, upper exclusive)
+      if (x >= 0 && x < std::lround( (uext[1] - uext[0]) / binsize[0] ) &&
+          y >= 0 && y < std::lround( (uext[3] - uext[2]) / binsize[1] ) &&
+          z >= 0 && z < std::lround( (uext[5] - uext[4]) / binsize[2] ))
+      {
+        const auto X = static_cast< std::size_t >( x );
+        const auto Y = static_cast< std::size_t >( y );
+        const auto Z = static_cast< std::size_t >( z );
+        const auto bin = nbix*(Z*nbiy + Y) + X;
+        Assert( bin < nbix*nbiy*nbiz, "Bin overflow in "
+              "user-specified-extent-based bin calculation of bivariate PDF." );
+        // Copy normalized probability to output pdf
+        outpdf[ bin ] =
+          p.second / binsize[0] / binsize[1] / binsize[2]
+                   / static_cast<tk::real>(pdf.nsample());
+      }
+    }
+
+    // Revert number of bins if node-centered output required
+    if (centering == ctr::PDFCenteringType::NODE) { --nbix; --nbiy; --nbiz; }
+  }
+}
 
diff --git a/Debug/cppcheck/23.html b/Debug/cppcheck/23.html index 076b907f0173..0bf8f63d4312 100644 --- a/Debug/cppcheck/23.html +++ b/Debug/cppcheck/23.html @@ -152,12 +152,12 @@
  1
@@ -289,132 +289,132 @@ 

Cppcheck report - [

// *****************************************************************************
 /*!
-  \file      src/Control/MeshConv/CmdLine/Parser.cpp
+  \file      src/Control/HelpFactory.hpp
   \copyright 2012-2015 J. Bakosi,
              2016-2018 Los Alamos National Security, LLC.,
              2019-2021 Triad National Security, LLC.
              All rights reserved. See the LICENSE file for details.
-  \brief     MeshConv's command line parser
-  \details   This file defines the command-line argument parser for the mesh
-     file converter, MeshConv.
+  \brief     Command-line and input deck help factory
+  \details   This file contains some types that facilitate the generation of
+     on-screen help.
 */
 // *****************************************************************************
-
-#include "NoWarning/pegtl.hpp"
-#include "NoWarning/charm.hpp"
-
-#include "QuinoaConfig.hpp"
-#include "Exception.hpp"
-#include "Print.hpp"
-#include "Keywords.hpp"
-#include "MeshConv/Types.hpp"
-#include "MeshConv/CmdLine/Parser.hpp"
-#include "MeshConv/CmdLine/Grammar.hpp"
-
-namespace tk {
-namespace grm {
-
-tk::Print g_print;
-
-} // grm::
-} // tk::
-
-using meshconv::CmdLineParser;
-
-CmdLineParser::CmdLineParser( int argc,
-                              char** argv,
-                              const tk::Print& print,
-                              ctr::CmdLine& cmdline ) :
-  StringParser( argc, argv )
-// *****************************************************************************
-//  Contructor: parse the command line for MeshConv
-//! \param[in] argc Number of C-style character arrays in argv
-//! \param[in] argv C-style character array of character arrays
-//! \param[in] print Pretty printer
-//! \param[inout] cmdline Command-line stack where data is stored from parsing
-// *****************************************************************************
-{
-  // Create CmdLine (a tagged tuple) to store parsed input
-  ctr::CmdLine cmd;
-
-  // Reset parser's output stream to that of print's. This is so that mild
-  // warnings emitted during parsing can be output using the pretty printer.
-  // Usually, errors and warnings are simply accumulated during parsing and
-  // printed during diagnostics after the parser has finished. However, in some
-  // special cases we can provide a more user-friendly message right during
-  // parsing since there is more information available to construct a more
-  // sensible message. This is done in e.g., tk::grm::store_option. Resetting
-  // the global g_print, to that of passed in as the constructor argument allows
-  // not to have to create a new pretty printer, but use the existing one.
-  tk::grm::g_print.reset( print.save() );
-
-  // Parse command line string by populating the underlying tagged tuple
-  tao::pegtl::memory_input<> in( m_string, "command line" );
-  tao::pegtl::parse< cmd::read_string, tk::grm::action >( in, cmd );
-
-  // Echo errors and warnings accumulated during parsing
-  diagnostics( print, cmd.get< tag::error >() );
-
-  // Strip command line (and its underlying tagged tuple) from PEGTL instruments
-  // and transfer it out
-  cmdline = std::move( cmd );
-
-  // If we got here, the parser has succeeded
-  print.item("Parsed command line", "success");
-
-  // Print out help on all command-line arguments if the executable was invoked
-  // without arguments or the help was requested
-  const auto helpcmd = cmdline.get< tag::help >();
-  if (argc == 1 || helpcmd) {
-    print.help< tk::QUIET >( tk::meshconv_executable(),
-                             cmdline.get< tag::cmdinfo >(),
-                             "Command-line Parameters:", "-" );
-    print.mandatory< tk::QUIET >(
-     "The '--" + kw::input().string() + " <filename>' and the "
-     "'--" + kw::output().string() + " <filename>' arguments are mandatory." );
-    print.usage< tk::QUIET >(
-      tk::meshconv_executable(),
-      tk::meshconv_executable() + " -" + *kw::input().alias() + " in.msh -" +
-        *kw::output().alias() + " out.exo",
-      "will read data from 'in.msh' (in Gmsh format) and output it to "
-      "out.exo' (in ExodusII format)" );
-  }
-
-  // Print out verbose help for a single keyword if requested
-  const auto helpkw = cmdline.get< tag::helpkw >();
-  if (!helpkw.keyword.empty())
-    print.helpkw< tk::QUIET >( tk::meshconv_executable(), helpkw );
-
-  // Print out version information if it was requested
-  const auto version = cmdline.get< tag::version >();
-  if (version)
-    print.version< tk::QUIET >( tk::meshconv_executable(),
-                                tk::quinoa_version(),
-                                tk::git_commit(),
-                                tk::copyright() );
-
-  // Print out license information if it was requested
-  const auto license = cmdline.get< tag::license >();
-  if (license)
-    print.license< tk::QUIET >( tk::meshconv_executable(), tk::license() );
+#ifndef HelpFactory_h
+#define HelpFactory_h
+
+#include <brigand/sequences/list.hpp>
+#include <brigand/algorithms/for_each.hpp>
+
+#include "PUPUtil.hpp"
+#include "Factory.hpp"
+#include "Has.hpp"
+#include "Types.hpp"
+
+namespace tk {
+namespace ctr {
+
+//! \brief Keyword information bundle
+//! \details This bundle contains the information that is used to display
+//!    on-screen help on all command-line arguments and control file keywords
+//!    for an exectuable. This struct is stored in a container that associates
+//!    keywords (used by a grammar and parser) to this struct. The container, an
+//!    runtime, std::map, is filled by the CmdLine and InputDeck objects'
+//!    constructors by one or more brigand::for_each which loops through the
+//!    set of all keywords used in a grammar. The maps are stored in the CmdLine
+//!    and InputDeck objects (which are tagged tuples) and thus can be migrated
+//!    through the network, thus the Charm++ parck/unpack routines are defined.
+//! \see Info functor used to fill the std::maps
+struct KeywordInfo {
+  std::string shortDescription;           //!< Short description
+  std::string longDescription;            //!< Long description
+  std::optional< std::string > alias;     //!< Keyword alias
+  std::optional< std::string > expt;      //!< Expected type description
+  std::optional< std::string > lower;     //!< Lower bound as string
+  std::optional< std::string > upper;     //!< Upper bound as string
+  std::optional< std::string > choices;   //!< Expected choices description
+
+  /** @name Pack/Unpack: Serialize KeywordInfo object for Charm++ */
+  ///@{
+  //! \brief Pack/Unpack serialize member function
+  //! \param[in,out] p Charm++'s PUP::er serializer object reference
+  void pup( PUP::er& p ) {<--- Parameter 'p' can be declared with const
+    p | shortDescription;
+    p | longDescription;
+    p | alias;
+    p | expt;
+    p | lower;
+    p | upper;
+    p | choices;
+  }
+  //! \brief Pack/Unpack serialize operator|
+  //! \param[in,out] p Charm++'s PUP::er serializer object reference
+  //! \param[in,out] info KeywordInfo object reference
+  friend void operator|( PUP::er& p, KeywordInfo& info ) { info.pup(p); }
+  ///@}
+};
+
+//! \brief A typedef for associating a keyword-string with its associated
+//!   information stored in a KeywordInfo struct
+using HelpFactory = std::map< std::string, KeywordInfo >;
+
+//! \brief Help bundle on a single keyword
+//! \details This is used for delivering help on a single keyword. This struct
+//!    also differentiates between command-line arguments and control file
+//!    keywords.
+struct HelpKw {
+  HelpFactory::key_type keyword;        //!< Keyword string
+  HelpFactory::mapped_type info;        //!< Keyword information
+  bool cmd;                             //!< True if command-line keyword
+
+  /** @name Pack/Unpack: Serialize HelpKw object for Charm++ */
+  ///@{
+  //! \brief Pack/Unpack serialize member function
+  //! \param[in,out] p Charm++'s PUP::er serializer object reference
+  void pup( PUP::er& p ) { p|keyword; p|info; p|cmd; }<--- Parameter 'p' can be declared with const
+  //! \brief Pack/Unpack serialize operator|
+  //! \param[in,out] p Charm++'s PUP::er serializer object reference
+  //! \param[in,out] h HelpKw object reference
+  friend void operator|( PUP::er& p, HelpKw& h ) { h.pup(p); }
+  ///@}
+};
+
+//! \brief Function object for filling a HelpFactory (std::map) with keywords
+//!   and their associated information bundle
+//! \details This struct is used as a functor to loop through a set of keywords
+//!   at compile-time and generate code for filling up the std::map.
+struct Info {
+  //! Store reference to map we are filling
+  tk::ctr::HelpFactory& m_factory;
+  //! Constructor: store reference to map to fill
+  explicit Info( tk::ctr::HelpFactory& factory ) : m_factory( factory ) {}
+  //! \brief Function call operator templated on the type that does the filling
+  template< typename U > void operator()( brigand::type_<U> ) {
+    m_factory[ U::string() ] = { U::shortDescription(),
+                                 U::longDescription(),
+                                 U::alias(),
+                                 U::expt(),
+                                 U::lower(),
+                                 U::upper(),
+                                 U::choices() };
+  }
 
-  // Immediately exit if any help was output or was called without any argument
-  // or version or license info was requested with zero exit code
-  if (argc == 1 || helpcmd || !helpkw.keyword.empty() || version || license)
-    CkExit();
-
-  // Make sure mandatory arguments are set
-  auto ialias = kw::input().alias();
-  auto oalias = kw::output().alias();<--- Variable 'oalias' is assigned a value that is never used.
-  ErrChk( !(cmdline.get< tag::io, tag::input >().empty()),
-          "Mandatory input file not specified. "
-          "Use '--" + kw::input().string() + " <filename>'" +
-          ( ialias ? " or '-" + *ialias + " <filename>'" : "" ) + '.' );
-  ErrChk( !(cmdline.get< tag::io, tag::output >().empty()),
-          "Mandatory output file not specified. "
-          "Use '--" + kw::output().string() + " <filename>'" +
-          ( oalias ? " or '-" + *oalias + " <filename>'" : "" ) + '.' );
-}
+  //! Fill map in a simpler way passing a string rather than a brigand-type
+  void fill( const tk::entry_t& kw )
+  {
+    m_factory[kw.string()] = { kw.shortDescription(),
+                               kw.longDescription(),
+                               kw.alias(),
+                               kw.expt(),
+                               kw.lower(),
+                               kw.upper(),
+                               kw.choices() };
+  }
+};
+
+} // ctr::
+} // tk::
+
+#endif // HelpFactory_h
 
diff --git a/Debug/cppcheck/24.html b/Debug/cppcheck/24.html index be89a12b4797..3581126ed8a1 100644 --- a/Debug/cppcheck/24.html +++ b/Debug/cppcheck/24.html @@ -152,12 +152,12 @@
  1
@@ -287,216 +287,134 @@ 

Cppcheck report - [

// *****************************************************************************
+128
// *****************************************************************************
 /*!
-  \file      src/Main/MeshConv.cpp
+  \file      src/Control/MeshConv/CmdLine/Parser.cpp
   \copyright 2012-2015 J. Bakosi,
              2016-2018 Los Alamos National Security, LLC.,
              2019-2021 Triad National Security, LLC.
              All rights reserved. See the LICENSE file for details.
-  \brief     Mesh file converter Charm++ main chare
-  \details   Mesh file converter Charm++ main chare. This file contains the
-    definition of the Charm++ main chare, equivalent to main() in Charm++-land.
+  \brief     MeshConv's command line parser
+  \details   This file defines the command-line argument parser for the mesh
+     file converter, MeshConv.
 */
 // *****************************************************************************
 
-#include <vector>
-#include <utility>
-#include <iostream>
-
-#include "Print.hpp"
-#include "Timer.hpp"
-#include "Types.hpp"
-#include "QuinoaConfig.hpp"
-#include "Init.hpp"
-#include "Tags.hpp"
-#include "MeshConvDriver.hpp"
-#include "MeshConv/CmdLine/CmdLine.hpp"
-#include "MeshConv/CmdLine/Parser.hpp"
-#include "ProcessException.hpp"
-#include "ChareStateCollector.hpp"
+#include "NoWarning/pegtl.hpp"
+#include "NoWarning/charm.hpp"
+
+#include "QuinoaConfig.hpp"
+#include "Exception.hpp"
+#include "Print.hpp"
+#include "Keywords.hpp"
+#include "MeshConv/Types.hpp"
+#include "MeshConv/CmdLine/Parser.hpp"
+#include "MeshConv/CmdLine/Grammar.hpp"
+
+namespace tk {
+namespace grm {
+
+tk::Print g_print;
 
-#include "NoWarning/charm.hpp"
-#include "NoWarning/meshconv.decl.h"
+} // grm::
+} // tk::
 
-#if defined(__clang__)
-  #pragma clang diagnostic push
-  #pragma clang diagnostic ignored "-Wmissing-variable-declarations"
-#endif
-
-//! \brief Charm handle to the main proxy, facilitates call-back to finalize,
-//!    etc., must be in global scope, unique per executable
-CProxy_Main mainProxy;
-
-//! Chare state collector Charm++ chare group proxy
-tk::CProxy_ChareStateCollector stateProxy;
-
-//! If true, call and stack traces are to be output with exceptions
-//! \note This is true by default so that the trace is always output between
-//!   program start and the Main ctor in which the user-input from command line
-//!   setting for this overrides this true setting.
-bool g_trace = true;
+using meshconv::CmdLineParser;
+
+CmdLineParser::CmdLineParser( int argc,
+                              char** argv,
+                              const tk::Print& print,
+                              ctr::CmdLine& cmdline ) :
+  StringParser( argc, argv )
+// *****************************************************************************
+//  Contructor: parse the command line for MeshConv
+//! \param[in] argc Number of C-style character arrays in argv
+//! \param[in] argv C-style character array of character arrays
+//! \param[in] print Pretty printer
+//! \param[inout] cmdline Command-line stack where data is stored from parsing
+// *****************************************************************************
+{
+  // Create CmdLine (a tagged tuple) to store parsed input
+  ctr::CmdLine cmd;
 
-#if defined(__clang__)
-  #pragma clang diagnostic pop
-#endif
-
-//! \brief Charm++ main chare for the mesh converter executable, meshconv.
-//! \details Note that this object should not be in a namespace.
-// cppcheck-suppress noConstructor
-class Main : public CBase_Main {<--- Unmatched suppression: noConstructor
-
-  public:
-    //! \brief Constructor
-    //! \details MeshConv's main chare constructor is the entry point of the
-    //!   program, called by the Charm++ runtime system. The constructor does
-    //!   basic initialization steps, e.g., parser the command-line, prints out
-    //!   some useful information to screen (in verbose mode), and instantiates
-    //!   a driver. Since Charm++ is fully asynchronous, the constructor
-    //!   usually spawns asynchronous objects and immediately exits. Thus in the
-    //!   body of the main chare constructor we fire up an 'execute' chare,
-    //!   which then calls back to Main::execute(). Finishing the main chare
-    //!   constructor the Charm++ runtime system then starts the
-    //!   network-migration of all global-scope data (if any). The execute chare
-    //!   calling back to Main::execute() signals the end of the migration of
-    //!   the global-scope data. Then we are ready to execute the driver which
-    //!   calls back to Main::finalize() when it finished. Then finalize() exits
-    //!   by calling Charm++'s CkExit(), shutting down the runtime system.
-    //! \see http://charm.cs.illinois.edu/manuals/html/charm++/manual.html
-    Main( CkArgMsg* msg )
-    try :
-      m_signal( tk::setSignalHandlers() ),
-      m_cmdline(),
-      // Parse command line into m_cmdline using default simple pretty printer
-      m_cmdParser( msg->argc, msg->argv, tk::Print(), m_cmdline ),
-      // Create MeshConv driver
-      m_driver( tk::Main< meshconv::MeshConvDriver >
-                        ( msg->argc, msg->argv,
-                          m_cmdline,
-                          tk::HeaderType::MESHCONV,
-                          tk::meshconv_executable(),
-                          m_cmdline.get< tag::io, tag::screen >(),
-                          m_cmdline.get< tag::io, tag::nrestart >() ) ),
-      m_timer(1),       // Start new timer measuring the total runtime
-      m_timestamp()
-    {
-      delete msg;
-      g_trace = m_cmdline.get< tag::trace >();
-      tk::MainCtor( mainProxy, thisProxy, m_timer, m_cmdline,
-                    CkCallback( CkIndex_Main::quiescence(), thisProxy ) );
-      // If quiescence detection is on or user requested it, create chare state
-      // collector Charm++ chare group
-      if ( m_cmdline.get< tag::chare >() || m_cmdline.get< tag::quiescence >() )
-        stateProxy = tk::CProxy_ChareStateCollector::ckNew();
-      // Fire up an asynchronous execute object, which when created at some
-      // future point in time will call back to this->execute(). This is
-      // necessary so that this->execute() can access already migrated
-      // global-scope data.
-      CProxy_execute::ckNew();
-    } catch (...) { tk::processExceptionCharm(); }
-
-    void execute() {
-      try {
-        m_timestamp.emplace_back("Migrate global-scope data", m_timer[1].hms());
-        m_driver.execute();
-      } catch (...) { tk::processExceptionCharm(); }
-    }
-
-    //! Towards normal exit but collect chare state first (if any)
-    void finalize() {
-      tk::finalize( m_cmdline, m_timer, stateProxy, m_timestamp,
-        m_cmdline.get< tag::io, tag::screen >(),
-        m_cmdline.get< tag::io, tag::nrestart >(),
-        CkCallback( CkIndex_Main::dumpstate(nullptr), thisProxy ) );
-    }
-
-    //! Add a time stamp contributing to final timers output
-    void timestamp( std::string label, tk::real stamp ) {
-      try {
-        m_timestamp.emplace_back( label, tk::hms( stamp ) );
-      } catch (...) { tk::processExceptionCharm(); }
-    }
-    //! Add multiple time stamps contributing to final timers output
-    void timestamp( const std::vector< std::pair< std::string, tk::real > >& s )
-    { for (const auto& t : s) timestamp( t.first, t.second ); }
-
-    //! Entry method triggered when quiescence is detected
-    void quiescence() {
-      try {
-        stateProxy.collect( /* error= */ true,
-          CkCallback( CkIndex_Main::dumpstate(nullptr), thisProxy ) );
-      } catch (...) { tk::processExceptionCharm(); }
-    }
-
-    //! Dump chare state
-    void dumpstate( CkReductionMsg* msg ) {
-      tk::dumpstate( m_cmdline,
-        m_cmdline.get< tag::io, tag::screen >(),
-        m_cmdline.get< tag::io, tag::nrestart >(),
-        msg );
-    }
-
-  private:
-    int m_signal;                               //!< Used to set signal handlers
-    meshconv::ctr::CmdLine m_cmdline;           //!< Command line
-    meshconv::CmdLineParser m_cmdParser;        //!< Command line parser
-    meshconv::MeshConvDriver m_driver;          //!< Driver
-    std::vector< tk::Timer > m_timer;           //!< Timers
-
-    //! Time stamps in h:m:s with labels
-    std::vector< std::pair< std::string, tk::Timer::Watch > > m_timestamp;
-};
-
-//! \brief Charm++ chare execute
-//! \details By the time this object is constructed, the Charm++ runtime system
-//!    has finished migrating all global-scoped read-only objects which happens
-//!    after the main chare constructor has finished.
-class execute : public CBase_execute {
-  public: execute() { mainProxy.execute(); }
-};
-
-#include "NoWarning/meshconv.def.h"
+  // Reset parser's output stream to that of print's. This is so that mild
+  // warnings emitted during parsing can be output using the pretty printer.
+  // Usually, errors and warnings are simply accumulated during parsing and
+  // printed during diagnostics after the parser has finished. However, in some
+  // special cases we can provide a more user-friendly message right during
+  // parsing since there is more information available to construct a more
+  // sensible message. This is done in e.g., tk::grm::store_option. Resetting
+  // the global g_print, to that of passed in as the constructor argument allows
+  // not to have to create a new pretty printer, but use the existing one.
+  tk::grm::g_print.reset( print.save() );
+
+  // Parse command line string by populating the underlying tagged tuple
+  tao::pegtl::memory_input<> in( m_string, "command line" );
+  tao::pegtl::parse< cmd::read_string, tk::grm::action >( in, cmd );
+
+  // Echo errors and warnings accumulated during parsing
+  diagnostics( print, cmd.get< tag::error >() );
+
+  // Strip command line (and its underlying tagged tuple) from PEGTL instruments
+  // and transfer it out
+  cmdline = std::move( cmd );
+
+  // If we got here, the parser has succeeded
+  print.item("Parsed command line", "success");
+
+  // Print out help on all command-line arguments if the executable was invoked
+  // without arguments or the help was requested
+  const auto helpcmd = cmdline.get< tag::help >();
+  if (argc == 1 || helpcmd) {
+    print.help< tk::QUIET >( tk::meshconv_executable(),
+                             cmdline.get< tag::cmdinfo >(),
+                             "Command-line Parameters:", "-" );
+    print.mandatory< tk::QUIET >(
+     "The '--" + kw::input().string() + " <filename>' and the "
+     "'--" + kw::output().string() + " <filename>' arguments are mandatory." );
+    print.usage< tk::QUIET >(
+      tk::meshconv_executable(),
+      tk::meshconv_executable() + " -" + *kw::input().alias() + " in.msh -" +
+        *kw::output().alias() + " out.exo",
+      "will read data from 'in.msh' (in Gmsh format) and output it to "
+      "out.exo' (in ExodusII format)" );
+  }
+
+  // Print out verbose help for a single keyword if requested
+  const auto helpkw = cmdline.get< tag::helpkw >();
+  if (!helpkw.keyword.empty())
+    print.helpkw< tk::QUIET >( tk::meshconv_executable(), helpkw );
+
+  // Print out version information if it was requested
+  const auto version = cmdline.get< tag::version >();
+  if (version)
+    print.version< tk::QUIET >( tk::meshconv_executable(),
+                                tk::quinoa_version(),
+                                tk::git_commit(),
+                                tk::copyright() );
+
+  // Print out license information if it was requested
+  const auto license = cmdline.get< tag::license >();
+  if (license)
+    print.license< tk::QUIET >( tk::meshconv_executable(), tk::license() );
+
+  // Immediately exit if any help was output or was called without any argument
+  // or version or license info was requested with zero exit code
+  if (argc == 1 || helpcmd || !helpkw.keyword.empty() || version || license)
+    CkExit();
+
+  // Make sure mandatory arguments are set
+  auto ialias = kw::input().alias();
+  auto oalias = kw::output().alias();<--- Variable 'oalias' is assigned a value that is never used.
+  ErrChk( !(cmdline.get< tag::io, tag::input >().empty()),
+          "Mandatory input file not specified. "
+          "Use '--" + kw::input().string() + " <filename>'" +
+          ( ialias ? " or '-" + *ialias + " <filename>'" : "" ) + '.' );
+  ErrChk( !(cmdline.get< tag::io, tag::output >().empty()),
+          "Mandatory output file not specified. "
+          "Use '--" + kw::output().string() + " <filename>'" +
+          ( oalias ? " or '-" + *oalias + " <filename>'" : "" ) + '.' );
+}
 
diff --git a/Debug/cppcheck/25.html b/Debug/cppcheck/25.html index 48a0d2404abb..f7877f429229 100644 --- a/Debug/cppcheck/25.html +++ b/Debug/cppcheck/25.html @@ -152,3011 +152,351 @@
- - + @@ -77,7 +77,7 @@ - +
   1
-   2
-   3
-   4
-   5
-   6
-   7
-   8
-   9
-  10
-  11
-  12
-  13
-  14
-  15
-  16
-  17
-  18
-  19
-  20
-  21
-  22
-  23
-  24
-  25
-  26
-  27
-  28
-  29
-  30
-  31
-  32
-  33
-  34
-  35
-  36
-  37
-  38
-  39
-  40
-  41
-  42
-  43
-  44
-  45
-  46
-  47
-  48
-  49
-  50
-  51
-  52
-  53
-  54
-  55
-  56
-  57
-  58
-  59
-  60
-  61
-  62
-  63
-  64
-  65
-  66
-  67
-  68
-  69
-  70
-  71
-  72
-  73
-  74
-  75
-  76
-  77
-  78
-  79
-  80
-  81
-  82
-  83
-  84
-  85
-  86
-  87
-  88
-  89
-  90
-  91
-  92
-  93
-  94
-  95
-  96
-  97
-  98
-  99
- 100
- 101
- 102
- 103
- 104
- 105
- 106
- 107
- 108
- 109
- 110
- 111
- 112
- 113
- 114
- 115
- 116
- 117
- 118
- 119
- 120
- 121
- 122
- 123
- 124
- 125
- 126
- 127
- 128
- 129
- 130
- 131
- 132
- 133
- 134
- 135
- 136
- 137
- 138
- 139
- 140
- 141
- 142
- 143
- 144
- 145
- 146
- 147
- 148
- 149
- 150
- 151
- 152
- 153
- 154
- 155
- 156
- 157
- 158
- 159
- 160
- 161
- 162
- 163
- 164
- 165
- 166
- 167
- 168
- 169
- 170
- 171
- 172
- 173
- 174
- 175
- 176
- 177
- 178
- 179
- 180
- 181
- 182
- 183
- 184
- 185
- 186
- 187
- 188
- 189
- 190
- 191
- 192
- 193
- 194
- 195
- 196
- 197
- 198
- 199
- 200
- 201
- 202
- 203
- 204
- 205
- 206
- 207
- 208
- 209
- 210
- 211
- 212
- 213
- 214
- 215
- 216
- 217
- 218
- 219
- 220
- 221
- 222
- 223
- 224
- 225
- 226
- 227
- 228
- 229
- 230
- 231
- 232
- 233
- 234
- 235
- 236
- 237
- 238
- 239
- 240
- 241
- 242
- 243
- 244
- 245
- 246
- 247
- 248
- 249
- 250
- 251
- 252
- 253
- 254
- 255
- 256
- 257
- 258
- 259
- 260
- 261
- 262
- 263
- 264
- 265
- 266
- 267
- 268
- 269
- 270
- 271
- 272
- 273
- 274
- 275
- 276
- 277
- 278
- 279
- 280
- 281
- 282
- 283
- 284
- 285
- 286
- 287
- 288
- 289
- 290
- 291
- 292
- 293
- 294
- 295
- 296
- 297
- 298
- 299
- 300
- 301
- 302
- 303
- 304
- 305
- 306
- 307
- 308
- 309
- 310
- 311
- 312
- 313
- 314
- 315
- 316
- 317
- 318
- 319
- 320
- 321
- 322
- 323
- 324
- 325
- 326
- 327
- 328
- 329
- 330
- 331
- 332
- 333
- 334
- 335
- 336
- 337
- 338
- 339
- 340
- 341
- 342
- 343
- 344
- 345
- 346
- 347
- 348
- 349
- 350
- 351
- 352
- 353
- 354
- 355
- 356
- 357
- 358
- 359
- 360
- 361
- 362
- 363
- 364
- 365
- 366
- 367
- 368
- 369
- 370
- 371
- 372
- 373
- 374
- 375
- 376
- 377
- 378
- 379
- 380
- 381
- 382
- 383
- 384
- 385
- 386
- 387
- 388
- 389
- 390
- 391
- 392
- 393
- 394
- 395
- 396
- 397
- 398
- 399
- 400
- 401
- 402
- 403
- 404
- 405
- 406
- 407
- 408
- 409
- 410
- 411
- 412
- 413
- 414
- 415
- 416
- 417
- 418
- 419
- 420
- 421
- 422
- 423
- 424
- 425
- 426
- 427
- 428
- 429
- 430
- 431
- 432
- 433
- 434
- 435
- 436
- 437
- 438
- 439
- 440
- 441
- 442
- 443
- 444
- 445
- 446
- 447
- 448
- 449
- 450
- 451
- 452
- 453
- 454
- 455
- 456
- 457
- 458
- 459
- 460
- 461
- 462
- 463
- 464
- 465
- 466
- 467
- 468
- 469
- 470
- 471
- 472
- 473
- 474
- 475
- 476
- 477
- 478
- 479
- 480
- 481
- 482
- 483
- 484
- 485
- 486
- 487
- 488
- 489
- 490
- 491
- 492
- 493
- 494
- 495
- 496
- 497
- 498
- 499
- 500
- 501
- 502
- 503
- 504
- 505
- 506
- 507
- 508
- 509
- 510
- 511
- 512
- 513
- 514
- 515
- 516
- 517
- 518
- 519
- 520
- 521
- 522
- 523
- 524
- 525
- 526
- 527
- 528
- 529
- 530
- 531
- 532
- 533
- 534
- 535
- 536
- 537
- 538
- 539
- 540
- 541
- 542
- 543
- 544
- 545
- 546
- 547
- 548
- 549
- 550
- 551
- 552
- 553
- 554
- 555
- 556
- 557
- 558
- 559
- 560
- 561
- 562
- 563
- 564
- 565
- 566
- 567
- 568
- 569
- 570
- 571
- 572
- 573
- 574
- 575
- 576
- 577
- 578
- 579
- 580
- 581
- 582
- 583
- 584
- 585
- 586
- 587
- 588
- 589
- 590
- 591
- 592
- 593
- 594
- 595
- 596
- 597
- 598
- 599
- 600
- 601
- 602
- 603
- 604
- 605
- 606
- 607
- 608
- 609
- 610
- 611
- 612
- 613
- 614
- 615
- 616
- 617
- 618
- 619
- 620
- 621
- 622
- 623
- 624
- 625
- 626
- 627
- 628
- 629
- 630
- 631
- 632
- 633
- 634
- 635
- 636
- 637
- 638
- 639
- 640
- 641
- 642
- 643
- 644
- 645
- 646
- 647
- 648
- 649
- 650
- 651
- 652
- 653
- 654
- 655
- 656
- 657
- 658
- 659
- 660
- 661
- 662
- 663
- 664
- 665
- 666
- 667
- 668
- 669
- 670
- 671
- 672
- 673
- 674
- 675
- 676
- 677
- 678
- 679
- 680
- 681
- 682
- 683
- 684
- 685
- 686
- 687
- 688
- 689
- 690
- 691
- 692
- 693
- 694
- 695
- 696
- 697
- 698
- 699
- 700
- 701
- 702
- 703
- 704
- 705
- 706
- 707
- 708
- 709
- 710
- 711
- 712
- 713
- 714
- 715
- 716
- 717
- 718
- 719
- 720
- 721
- 722
- 723
- 724
- 725
- 726
- 727
- 728
- 729
- 730
- 731
- 732
- 733
- 734
- 735
- 736
- 737
- 738
- 739
- 740
- 741
- 742
- 743
- 744
- 745
- 746
- 747
- 748
- 749
- 750
- 751
- 752
- 753
- 754
- 755
- 756
- 757
- 758
- 759
- 760
- 761
- 762
- 763
- 764
- 765
- 766
- 767
- 768
- 769
- 770
- 771
- 772
- 773
- 774
- 775
- 776
- 777
- 778
- 779
- 780
- 781
- 782
- 783
- 784
- 785
- 786
- 787
- 788
- 789
- 790
- 791
- 792
- 793
- 794
- 795
- 796
- 797
- 798
- 799
- 800
- 801
- 802
- 803
- 804
- 805
- 806
- 807
- 808
- 809
- 810
- 811
- 812
- 813
- 814
- 815
- 816
- 817
- 818
- 819
- 820
- 821
- 822
- 823
- 824
- 825
- 826
- 827
- 828
- 829
- 830
- 831
- 832
- 833
- 834
- 835
- 836
- 837
- 838
- 839
- 840
- 841
- 842
- 843
- 844
- 845
- 846
- 847
- 848
- 849
- 850
- 851
- 852
- 853
- 854
- 855
- 856
- 857
- 858
- 859
- 860
- 861
- 862
- 863
- 864
- 865
- 866
- 867
- 868
- 869
- 870
- 871
- 872
- 873
- 874
- 875
- 876
- 877
- 878
- 879
- 880
- 881
- 882
- 883
- 884
- 885
- 886
- 887
- 888
- 889
- 890
- 891
- 892
- 893
- 894
- 895
- 896
- 897
- 898
- 899
- 900
- 901
- 902
- 903
- 904
- 905
- 906
- 907
- 908
- 909
- 910
- 911
- 912
- 913
- 914
- 915
- 916
- 917
- 918
- 919
- 920
- 921
- 922
- 923
- 924
- 925
- 926
- 927
- 928
- 929
- 930
- 931
- 932
- 933
- 934
- 935
- 936
- 937
- 938
- 939
- 940
- 941
- 942
- 943
- 944
- 945
- 946
- 947
- 948
- 949
- 950
- 951
- 952
- 953
- 954
- 955
- 956
- 957
- 958
- 959
- 960
- 961
- 962
- 963
- 964
- 965
- 966
- 967
- 968
- 969
- 970
- 971
- 972
- 973
- 974
- 975
- 976
- 977
- 978
- 979
- 980
- 981
- 982
- 983
- 984
- 985
- 986
- 987
- 988
- 989
- 990
- 991
- 992
- 993
- 994
- 995
- 996
- 997
- 998
- 999
-1000
-1001
-1002
-1003
-1004
-1005
-1006
-1007
-1008
-1009
-1010
-1011
-1012
-1013
-1014
-1015
-1016
-1017
-1018
-1019
-1020
-1021
-1022
-1023
-1024
-1025
-1026
-1027
-1028
-1029
-1030
-1031
-1032
-1033
-1034
-1035
-1036
-1037
-1038
-1039
-1040
-1041
-1042
-1043
-1044
-1045
-1046
-1047
-1048
-1049
-1050
-1051
-1052
-1053
-1054
-1055
-1056
-1057
-1058
-1059
-1060
-1061
-1062
-1063
-1064
-1065
-1066
-1067
-1068
-1069
-1070
-1071
-1072
-1073
-1074
-1075
-1076
-1077
-1078
-1079
-1080
-1081
-1082
-1083
-1084
-1085
-1086
-1087
-1088
-1089
-1090
-1091
-1092
-1093
-1094
-1095
-1096
-1097
-1098
-1099
-1100
-1101
-1102
-1103
-1104
-1105
-1106
-1107
-1108
-1109
-1110
-1111
-1112
-1113
-1114
-1115
-1116
-1117
-1118
-1119
-1120
-1121
-1122
-1123
-1124
-1125
-1126
-1127
-1128
-1129
-1130
-1131
-1132
-1133
-1134
-1135
-1136
-1137
-1138
-1139
-1140
-1141
-1142
-1143
-1144
-1145
-1146
-1147
-1148
-1149
-1150
-1151
-1152
-1153
-1154
-1155
-1156
-1157
-1158
-1159
-1160
-1161
-1162
-1163
-1164
-1165
-1166
-1167
-1168
-1169
-1170
-1171
-1172
-1173
-1174
-1175
-1176
-1177
-1178
-1179
-1180
-1181
-1182
-1183
-1184
-1185
-1186
-1187
-1188
-1189
-1190
-1191
-1192
-1193
-1194
-1195
-1196
-1197
-1198
-1199
-1200
-1201
-1202
-1203
-1204
-1205
-1206
-1207
-1208
-1209
-1210
-1211
-1212
-1213
-1214
-1215
-1216
-1217
-1218
-1219
-1220
-1221
-1222
-1223
-1224
-1225
-1226
-1227
-1228
-1229
-1230
-1231
-1232
-1233
-1234
-1235
-1236
-1237
-1238
-1239
-1240
-1241
-1242
-1243
-1244
-1245
-1246
-1247
-1248
-1249
-1250
-1251
-1252
-1253
-1254
-1255
-1256
-1257
-1258
-1259
-1260
-1261
-1262
-1263
-1264
-1265
-1266
-1267
-1268
-1269
-1270
-1271
-1272
-1273
-1274
-1275
-1276
-1277
-1278
-1279
-1280
-1281
-1282
-1283
-1284
-1285
-1286
-1287
-1288
-1289
-1290
-1291
-1292
-1293
-1294
-1295
-1296
-1297
-1298
-1299
-1300
-1301
-1302
-1303
-1304
-1305
-1306
-1307
-1308
-1309
-1310
-1311
-1312
-1313
-1314
-1315
-1316
-1317
-1318
-1319
-1320
-1321
-1322
-1323
-1324
-1325
-1326
-1327
-1328
-1329
-1330
-1331
-1332
-1333
-1334
-1335
-1336
-1337
-1338
-1339
-1340
-1341
-1342
-1343
-1344
-1345
-1346
-1347
-1348
-1349
-1350
-1351
-1352
-1353
-1354
-1355
-1356
-1357
-1358
-1359
-1360
-1361
-1362
-1363
-1364
-1365
-1366
-1367
-1368
-1369
-1370
-1371
-1372
-1373
-1374
-1375
-1376
-1377
-1378
-1379
-1380
-1381
-1382
-1383
-1384
-1385
-1386
-1387
-1388
-1389
-1390
-1391
-1392
-1393
-1394
-1395
-1396
-1397
-1398
-1399
-1400
-1401
-1402
-1403
-1404
-1405
-1406
-1407
-1408
-1409
-1410
-1411
-1412
-1413
-1414
-1415
-1416
-1417
-1418
-1419
-1420
-1421
-1422
-1423
-1424
-1425
-1426
-1427
-1428
-1429
-1430
-1431
-1432
-1433
-1434
-1435
-1436
-1437
-1438
-1439
-1440
-1441
-1442
-1443
-1444
-1445
-1446
-1447
-1448
-1449
-1450
-1451
-1452
-1453
-1454
-1455
-1456
-1457
-1458
-1459
-1460
-1461
-1462
-1463
-1464
-1465
-1466
-1467
-1468
-1469
-1470
-1471
-1472
-1473
-1474
-1475
-1476
-1477
-1478
-1479
-1480
-1481
-1482
-1483
-1484
-1485
-1486
-1487
-1488
-1489
-1490
-1491
-1492
-1493
-1494
-1495
-1496
-1497
-1498
-1499
// *****************************************************************************
+
  1
+  2
+  3
+  4
+  5
+  6
+  7
+  8
+  9
+ 10
+ 11
+ 12
+ 13
+ 14
+ 15
+ 16
+ 17
+ 18
+ 19
+ 20
+ 21
+ 22
+ 23
+ 24
+ 25
+ 26
+ 27
+ 28
+ 29
+ 30
+ 31
+ 32
+ 33
+ 34
+ 35
+ 36
+ 37
+ 38
+ 39
+ 40
+ 41
+ 42
+ 43
+ 44
+ 45
+ 46
+ 47
+ 48
+ 49
+ 50
+ 51
+ 52
+ 53
+ 54
+ 55
+ 56
+ 57
+ 58
+ 59
+ 60
+ 61
+ 62
+ 63
+ 64
+ 65
+ 66
+ 67
+ 68
+ 69
+ 70
+ 71
+ 72
+ 73
+ 74
+ 75
+ 76
+ 77
+ 78
+ 79
+ 80
+ 81
+ 82
+ 83
+ 84
+ 85
+ 86
+ 87
+ 88
+ 89
+ 90
+ 91
+ 92
+ 93
+ 94
+ 95
+ 96
+ 97
+ 98
+ 99
+100
+101
+102
+103
+104
+105
+106
+107
+108
+109
+110
+111
+112
+113
+114
+115
+116
+117
+118
+119
+120
+121
+122
+123
+124
+125
+126
+127
+128
+129
+130
+131
+132
+133
+134
+135
+136
+137
+138
+139
+140
+141
+142
+143
+144
+145
+146
+147
+148
+149
+150
+151
+152
+153
+154
+155
+156
+157
+158
+159
+160
+161
+162
+163
+164
+165
+166
+167
+168
+169
// *****************************************************************************
 /*!
-  \file      src/IO/PDFWriter.cpp
+  \file      src/Main/MeshConv.cpp
   \copyright 2012-2015 J. Bakosi,
              2016-2018 Los Alamos National Security, LLC.,
              2019-2021 Triad National Security, LLC.
              All rights reserved. See the LICENSE file for details.
-  \brief     Univariate PDF writer
-  \brief     PDF writer class definition
-  \details   This file defines a PDF writer class that facilitates outputing
-    probability density functions (PDFs) into files in various formats using
-    various configurations.
-*/
-// *****************************************************************************
-
-#include <iomanip>
+  \brief     Mesh file converter Charm++ main chare
+  \details   Mesh file converter Charm++ main chare. This file contains the
+    definition of the Charm++ main chare, equivalent to main() in Charm++-land.
+*/
+// *****************************************************************************
+
+#include <vector>
+#include <utility>
+#include <iostream>
 
-#include "NoWarning/exodusII.hpp"
-
-#include "PDFWriter.hpp"
-#include "Exception.hpp"
-
-using tk::PDFWriter;
-
-PDFWriter::PDFWriter( const std::string& filename,
-                      ctr::TxtFloatFormatType format,
-                      std::streamsize precision ) :
-  Writer( filename )
-// *****************************************************************************
-//  Constructor
-//! \param[in] filename Output filename to which output the PDF
-//! \param[in] format Configure floating-point output format for ASCII output
-//! \param[in] precision Configure precision for floating-point ASCII output
-// *****************************************************************************
-{
-  // Set floating-point format for output file stream
-  if (format == ctr::TxtFloatFormatType::DEFAULT)
-    {} //m_outFile << std::defaultfloat;   GCC does not yet support this
-  else if (format == ctr::TxtFloatFormatType::FIXED)
-    m_outFile << std::fixed;
-  else if (format == ctr::TxtFloatFormatType::SCIENTIFIC)
-    m_outFile << std::scientific;
-  else Throw( "Text floating-point format not recognized." );
+#include "Print.hpp"
+#include "Timer.hpp"
+#include "Types.hpp"
+#include "QuinoaConfig.hpp"
+#include "Init.hpp"
+#include "Tags.hpp"
+#include "MeshConvDriver.hpp"
+#include "MeshConv/CmdLine/CmdLine.hpp"
+#include "MeshConv/CmdLine/Parser.hpp"
+#include "ProcessException.hpp"
+#include "ChareStateCollector.hpp"
+
+#include "NoWarning/charm.hpp"
+#include "NoWarning/meshconv.decl.h"
+
+#if defined(__clang__)
+  #pragma clang diagnostic push
+  #pragma clang diagnostic ignored "-Wmissing-variable-declarations"
+#endif
+
+//! \brief Charm handle to the main proxy, facilitates call-back to finalize,
+//!    etc., must be in global scope, unique per executable
+CProxy_Main mainProxy;
+
+//! Chare state collector Charm++ chare group proxy
+tk::CProxy_ChareStateCollector stateProxy;
 
-  // Set numeric precision for output file stream if the input makes sense
-  if (precision > 0 && precision < std::numeric_limits< tk::real >::digits10+2)
-    m_outFile << std::setprecision( static_cast<int>(precision) );
-}
-
-void
-PDFWriter::writeTxt( const UniPDF& pdf, const tk::ctr::PDFInfo& info ) const
-// *****************************************************************************
-//  Write out standardized univariate PDF to file
-//! \param[in] pdf Univariate PDF
-//! \param[in] info PDF metadata
-// *****************************************************************************
-{
-  const auto& name = info.name;
-  const auto& uext = info.exts;
-  const auto& vars = info.vars;
-  const auto& it = info.it;
-  const auto& time = info.time;
-
-  assertSampleSpaceDimensions< 1 >( vars );
-  assertSampleSpaceExtents< 1 >( uext );
-
-  // Query and optionally override number of bins and minimum of sample space if
-  // user-specified extents were given and copy probabilities from pdf to an
-  // array for output
-  std::size_t nbi;
-  tk::real min, max;
-  std::vector< tk::real > outpdf;
-  tk::real binsize;
-  std::array< long, 2*UniPDF::dim > ext;
-  extents( pdf, uext, nbi, min, max, binsize, ext, outpdf );
-
-  // Output header
-  m_outFile << "# vim: filetype=sh:\n#\n"
-            << "# Univariate PDF: " << name << '(' << vars[0] << ')' << '\n'
-            << "# -----------------------------------------------\n"
-            << "# Numeric precision: " << m_outFile.precision() << '\n'
-            << "# Bin size: " << binsize << '\n'
-            << "# Number of bins estimated: " << ext[1] - ext[0] + 1
-            << '\n'
-            << "# Number of bins output: " << nbi << '\n'
-            << "# Sample space extent: [" << min << " : " << max << "]\n"
-            << "# Integral: " << pdf.integral() << "\n"
-            << "# Iteration: " << it << "\n"
-            << "# Physical time: " << time << "\n#\n"
-            << "# Example step-by-step visualization with gnuplot\n"
-            << "# -----------------------------------------------\n"
-            << "# gnuplot> set grid\n"
-            << "# gnuplot> unset key\n"
-            << "# gnuplot> set xlabel \"" << vars[0] << "\"\n"
-            << "# gnuplot> set ylabel \"" << name << "(" << vars[0] << ")\"\n"
-            << "# gnuplot> plot ";
-  if (!uext.empty()) m_outFile << "[" << uext[0] << ':' << uext[1] << "] ";
-  m_outFile << "\"" << m_filename << "\" with points\n#\n"
-            << "# Gnuplot one-liner for quick copy-paste\n"
-            << "# -----------------------------------------------\n"
-            << "# set grid; unset key; set xlabel \"" << vars[0]
-            << "\"; set ylabel \"" << name << "(" << vars[0]
-            << ")\"; plot";
-  if (!uext.empty()) m_outFile << " [" << uext[0] << ':' << uext[1] << "]";
-  m_outFile << " \"" << m_filename << "\" w p\n#\n"
-            << "# Data columns: " << vars[0] << ", " << name << "(" << vars[0]
-            << ")\n# -----------------------------------------------\n";
+//! If true, call and stack traces are to be output with exceptions
+//! \note This is true by default so that the trace is always output between
+//!   program start and the Main ctor in which the user-input from command line
+//!   setting for this overrides this true setting.
+bool g_trace = true;
+
+#if defined(__clang__)
+  #pragma clang diagnostic pop
+#endif
+
+//! \brief Charm++ main chare for the mesh converter executable, meshconv.
+//! \details Note that this object should not be in a namespace.
+// cppcheck-suppress noConstructor
+class Main : public CBase_Main {<--- Unmatched suppression: noConstructor
+
+  public:
+    //! \brief Constructor
+    //! \details MeshConv's main chare constructor is the entry point of the
+    //!   program, called by the Charm++ runtime system. The constructor does
+    //!   basic initialization steps, e.g., parser the command-line, prints out
+    //!   some useful information to screen (in verbose mode), and instantiates
+    //!   a driver. Since Charm++ is fully asynchronous, the constructor
+    //!   usually spawns asynchronous objects and immediately exits. Thus in the
+    //!   body of the main chare constructor we fire up an 'execute' chare,
+    //!   which then calls back to Main::execute(). Finishing the main chare
+    //!   constructor the Charm++ runtime system then starts the
+    //!   network-migration of all global-scope data (if any). The execute chare
+    //!   calling back to Main::execute() signals the end of the migration of
+    //!   the global-scope data. Then we are ready to execute the driver which
+    //!   calls back to Main::finalize() when it finished. Then finalize() exits
+    //!   by calling Charm++'s CkExit(), shutting down the runtime system.
+    //! \see http://charm.cs.illinois.edu/manuals/html/charm++/manual.html
+    Main( CkArgMsg* msg )
+    try :
+      m_signal( tk::setSignalHandlers() ),
+      m_cmdline(),
+      // Parse command line into m_cmdline using default simple pretty printer
+      m_cmdParser( msg->argc, msg->argv, tk::Print(), m_cmdline ),
+      // Create MeshConv driver
+      m_driver( tk::Main< meshconv::MeshConvDriver >
+                        ( msg->argc, msg->argv,
+                          m_cmdline,
+                          tk::HeaderType::MESHCONV,
+                          tk::meshconv_executable(),
+                          m_cmdline.get< tag::io, tag::screen >(),
+                          m_cmdline.get< tag::io, tag::nrestart >() ) ),
+      m_timer(1),       // Start new timer measuring the total runtime
+      m_timestamp()
+    {
+      delete msg;
+      g_trace = m_cmdline.get< tag::trace >();
+      tk::MainCtor( mainProxy, thisProxy, m_timer, m_cmdline,
+                    CkCallback( CkIndex_Main::quiescence(), thisProxy ) );
+      // If quiescence detection is on or user requested it, create chare state
+      // collector Charm++ chare group
+      if ( m_cmdline.get< tag::chare >() || m_cmdline.get< tag::quiescence >() )
+        stateProxy = tk::CProxy_ChareStateCollector::ckNew();
+      // Fire up an asynchronous execute object, which when created at some
+      // future point in time will call back to this->execute(). This is
+      // necessary so that this->execute() can access already migrated
+      // global-scope data.
+      CProxy_execute::ckNew();
+    } catch (...) { tk::processExceptionCharm(); }
 
-  // If no user-specified sample space extents, output pdf map directly
-  if (uext.empty()) {
-    for (const auto& p : pdf.map())
-      m_outFile << binsize * static_cast<tk::real>(p.first) << '\t'
-                << static_cast<tk::real>(p.second) / binsize /
-                   static_cast<tk::real>(pdf.nsample())
-                << std::endl;
-  } else { // If user-specified sample space extents, output outpdf array
-    std::size_t bin = 0;
-    for (const auto& p : outpdf)
-      m_outFile << binsize * static_cast<tk::real>(bin++) + uext[0] << '\t'
-                << p << std::endl;
-  }
-}
+    void execute() {
+      try {
+        m_timestamp.emplace_back("Migrate global-scope data", m_timer[1].hms());
+        m_driver.execute();
+      } catch (...) { tk::processExceptionCharm(); }
+    }
+
+    //! Towards normal exit but collect chare state first (if any)
+    void finalize() {
+      tk::finalize( m_cmdline, m_timer, stateProxy, m_timestamp,
+        m_cmdline.get< tag::io, tag::screen >(),
+        m_cmdline.get< tag::io, tag::nrestart >(),
+        CkCallback( CkIndex_Main::dumpstate(nullptr), thisProxy ) );
+    }
 
-void
-PDFWriter::writeTxt( const BiPDF& pdf, const tk::ctr::PDFInfo& info ) const
-// *****************************************************************************
-//  Write out standardized bivariate PDF to text file
-//! \param[in] pdf Bivariate PDF
-//! \param[in] info PDF metadata
-// *****************************************************************************
-{
-  const auto& name = info.name;
-  const auto& uext = info.exts;
-  const auto& vars = info.vars;
-  const auto& it = info.it;
-  const auto& time = info.time;
-
-  assertSampleSpaceDimensions< 2 >( vars );
-  assertSampleSpaceExtents< 2 >( uext );
-
-  // Query and optionally override number of bins and minima of sample space if
-  // user-specified extents were given and copy probabilities from pdf to a
-  // logically 2D array for output
-  std::size_t nbix, nbiy;
-  tk::real xmin, xmax, ymin, ymax;
-  std::vector< tk::real > outpdf;
-  std::array< tk::real, 2 > binsize;
-  std::array< long, 2*BiPDF::dim > ext;
-  extents( pdf, uext, nbix, nbiy, xmin, xmax, ymin, ymax, binsize, ext, outpdf,
-           ctr::PDFCenteringType::ELEM );
-
-  // Output metadata
-  m_outFile << "# vim: filetype=sh:\n#\n"
-            << "# Joint bivariate PDF: " << name << '(' << vars[0] << ','
-            << vars[1] << ")\n"
-            << "# -----------------------------------------------\n"
-            << "# Numeric precision: " << m_outFile.precision() << '\n'
-            << "# Bin sizes: " << binsize[0] << ", " << binsize[1] << '\n'
-            << "# Number of bins estimated: " << ext[1] - ext[0] + 1 << " x "
-            << ext[3] - ext[2] + 1 << '\n'
-            << "# Number of bins output: " << nbix << " x " << nbiy << '\n'
-            << "# Sample space extents: [" << xmin << " : " << xmax
-            << "], [" << ymin << " : " << ymax << "]\n"
-            << "# Iteration: " << it << "\n"
-            << "# Physical time: " << time << "\n#\n"
-            << "# Example step-by-step visualization with gnuplot\n"
-            << "# -----------------------------------------------\n"
-            << "# gnuplot> set grid\n"
-            << "# gnuplot> unset key\n"
-            << "# gnuplot> set xlabel \"" << vars[0] << "\"\n"
-            << "# gnuplot> set ylabel \"" << vars[1] << "\"\n"
-            << "# gnuplot> set zlabel \"" << name << "(" << vars[0] << ","
-            << vars[1] << ")\"\n"
-            << "# gnuplot> set dgrid3d 50,50,1\n"
-            << "# gnuplot> set cntrparam levels 20\n"
-            << "# gnuplot> set contour\n";
-  if (!uext.empty())
-    m_outFile << "# gnuplot> set xrange [" << uext[0] << ':' << uext[1] << "]\n"
-              << "# gnuplot> set yrange [" << uext[2] << ':' << uext[3] << "]\n";
-         
-  m_outFile << "# gnuplot> splot \"" << m_filename << "\" with lines\n#\n"
-            << "# Gnuplot one-liner for quick copy-paste\n"
-            << "# --------------------------------------\n"
-            << "# set grid; unset key; set xlabel \"" << vars[0]
-            << "\"; set ylabel \"" << vars[1] << "\"; set zlabel \"" << name
-            << "(" << vars[0] << ',' << vars[1] << ")\"; set dgrid3d 50,50,1; "
-               "set cntrparam levels 20; set contour; ";
-  if (!uext.empty())
-    m_outFile << "set xrange [" << uext[0] << ':' << uext[1] << "]; set yrange "
-                 "[" << uext[2] << ':' << uext[3] << "]; ";
-  m_outFile << "splot \"" << m_filename << "\" w l\n#\n"
-            << "# Data columns: " << vars[0] << ", " << vars[1] << ", "
-            << name << '(' << vars[0] << ',' << vars[1] << ")\n"
-            << "# -----------------------------------------------\n";
-
-  // If no user-specified sample space extents, output pdf map directly
-  if (uext.empty()) {
-    for (const auto& p : pdf.map())
-      m_outFile << binsize[0] * static_cast<tk::real>(p.first[0]) << '\t'
-                << binsize[1] * static_cast<tk::real>(p.first[1]) << '\t'
-                << p.second / binsize[0] / binsize[1] /
-                   static_cast<tk::real>(pdf.nsample())
-                << std::endl;
-  } else { // If user-specified sample space extents, output outpdf array
-    std::size_t bin = 0;
-    for (const auto& p : outpdf) {
-      m_outFile << binsize[0] * static_cast<tk::real>(bin % nbix) + uext[0]
-                << '\t'
-                << binsize[1] * static_cast<tk::real>(bin / nbix) + uext[2]
-                << '\t'
-                << p
-                << std::endl;
-      ++bin;
-    }
-  }
-
-  ErrChk( !m_outFile.bad(), "Failed to write to file: " + m_filename );
-}
-
-void
-PDFWriter::writeTxt( const TriPDF& pdf, const tk::ctr::PDFInfo& info ) const
-// *****************************************************************************
-//  Write out standardized trivariate PDF to text file
-//! \param[in] pdf Trivariate PDF
-//! \param[in] info PDF metadata
-// *****************************************************************************
-{
-  const auto& name = info.name;
-  const auto& uext = info.exts;
-  const auto& vars = info.vars;
-  const auto& it = info.it;
-  const auto& time = info.time;
-
-  assertSampleSpaceDimensions< 3 >( vars );
-  assertSampleSpaceExtents< 3 >( uext );
-
-  // Query and optionally override number of bins and minima of sample space if
-  // user-specified extents were given and copy probabilities from pdf to a
-  // logically 3D array for output
-  std::size_t nbix, nbiy, nbiz;
-  tk::real xmin, xmax, ymin, ymax, zmin, zmax;
-  std::vector< tk::real > outpdf;
-  std::array< tk::real, 3 > binsize;
-  std::array< long, 2*TriPDF::dim > ext;
-  extents( pdf, uext, nbix, nbiy, nbiz, xmin, xmax, ymin, ymax, zmin, zmax,
-           binsize, ext, outpdf, ctr::PDFCenteringType::ELEM );
-
-  // Output header
-  m_outFile << "# vim: filetype=sh:\n#\n"
-            << "# Joint trivariate PDF: " << name << '(' << vars[0] << ','
-            << vars[1] << ',' << vars[2] << ")\n"
-            << "# -----------------------------------------------\n"
-            << "# Numeric precision: " << m_outFile.precision() << '\n'
-            << "# Bin sizes: " << binsize[0] << ", " << binsize[1] << ", "
-            << binsize[2] << '\n'
-            << "# Number of bins estimated: " << ext[1] - ext[0] + 1 << " x "
-            << ext[3] - ext[2] + 1 << " x " << ext[5] - ext[4] + 1 << '\n'
-            << "# Number of bins output: " << nbix << " x " << nbiy << " x "
-            << nbiz << '\n'
-            << "# Sample space extents: [" << xmin << " : " << xmax << "], ["
-            << ymin << " : " << ymax << "], [" << zmin << " : " << zmax
-            << "]\n"
-            << "# Iteration: " << it << "\n"
-            << "# Physical time: " << time << "\n#\n"
-            << "# Example step-by-step visualization with gnuplot\n"
-            << "# -----------------------------------------------\n"
-            << "# gnuplot> set grid\n"
-            << "# gnuplot> set xlabel \"" << vars[0] << "\"\n"
-            << "# gnuplot> set ylabel \"" << vars[1] << "\"\n"
-            << "# gnuplot> set zlabel \"" << vars[2] << "\"\n";
-  if (!uext.empty())
-    m_outFile << "# gnuplot> set xrange [" << uext[0] << ':' << uext[1] << "]\n"
-              << "# gnuplot> set yrange [" << uext[2] << ':' << uext[3] << "]\n"
-              << "# gnuplot> set zrange [" << uext[4] << ':' << uext[5] << "]\n";
-  m_outFile << "# gnuplot> splot \"" << m_filename << "\" pointtype 7 "
-               "linecolor palette title \"" << name << '(' << vars[0] << ','
-            << vars[1] << ',' << vars[2] << ")\"\n#\n"
-            << "# Gnuplot one-liner for quick copy-paste\n"
-            << "# --------------------------------------\n"
-            << "# set grid; set xlabel \"" << vars[0] << "\"; set ylabel \""
-            << vars[1] << "\"; set zlabel \"" << vars[2] << "\"; ";
-  if (!uext.empty())
-    m_outFile << "set xrange [" << uext[0] << ':' << uext[1] << "]; set yrange "
-                 "[" << uext[2] << ':' << uext[3] << "]; set zrange ["
-              << uext[4] << ':' << uext[5] << "]; ";
-  m_outFile << "splot \"" << m_filename << "\" pt 7 linecolor palette title \""
-            << name << '(' << vars[0] << ',' << vars[1] << ',' << vars[2] << ')'
-            << "\"\n#\n"
-            << "# Data columns: " << vars[0] << ", " << vars[1] << ", "
-            << vars[2] << ", " << name << '(' << vars[0] << ',' << vars[1]
-            << ',' << vars[2] << ")\n"
-            << "# -----------------------------------------------\n";
-
-  // If no user-specified sample space extents, output pdf map directly
-  if (uext.empty()) {
-    for (const auto& p : pdf.map())
-      m_outFile << binsize[0] * static_cast<tk::real>(p.first[0]) << '\t'
-                << binsize[1] * static_cast<tk::real>(p.first[1]) << '\t'
-                << binsize[2] * static_cast<tk::real>(p.first[2]) << '\t'
-                << p.second / binsize[0] / binsize[1] / binsize[2]
-                            / static_cast<tk::real>(pdf.nsample())
-                << std::endl;
-  } else { // If user-specified sample space extents, output outpdf array
-    std::size_t bin = 0;
-    const auto n = nbix*nbiy;
-    for (const auto& p : outpdf) {
-      m_outFile << binsize[0] * static_cast<tk::real>(bin % n % nbix) + uext[0]
-                << '\t'
-                << binsize[1] * static_cast<tk::real>(bin % n / nbix) + uext[2]
-                << '\t'
-                << binsize[2] * static_cast<tk::real>(bin / n) + uext[4] << '\t'
-                << p
-                << std::endl;
-      ++bin;
-    }
-  }
-
-  ErrChk( !m_outFile.bad(), "Failed to write to file: " + m_filename );
-}
-
-void
-PDFWriter::writeGmshTxt( const BiPDF& pdf,
-                         const tk::ctr::PDFInfo& info,
-                         ctr::PDFCenteringType centering ) const
-// *****************************************************************************
-//  Write out standardized bivariate PDF to Gmsh (text) format
-//! \param[in] pdf Bivariate PDF
-//! \param[in] info PDF metadata
-//! \param[in] centering Bin centering on sample space mesh
-// *****************************************************************************
-{
-  const auto& name = info.name;
-  const auto& uext = info.exts;
-  const auto& vars = info.vars;
-  const auto& it = info.it;
-  const auto& time = info.time;
-
-  assertSampleSpaceDimensions< 2 >( vars );
-  assertSampleSpaceExtents< 2 >( uext );
-
-  // Query and optionally override number of bins and minima of sample space if
-  // user-specified extents were given and copy probabilities from pdf to a
-  // logically 2D array for output
-  std::size_t nbix, nbiy;
-  tk::real xmin, xmax, ymin, ymax;
-  std::vector< tk::real > outpdf;
-  std::array< tk::real, 2 > binsize;
-  std::array< long, 2*BiPDF::dim > ext;
-  extents( pdf, uext, nbix, nbiy, xmin, xmax, ymin, ymax, binsize, ext, outpdf,
-           centering );
-
-  // Output metadata. The #s are unnecessary, but vi will color it differently.
-  m_outFile << "$Comments\n"
-            << "# vim: filetype=sh:\n"
-            << "# Joint bivariate PDF: " << name << '(' << vars[0] << ','
-            << vars[1] << ")\n"
-            << "# -----------------------------------------------\n"
-            << "# Numeric precision: " << m_outFile.precision() << '\n'
-            << "# Bin sizes: " << binsize[0] << ", " << binsize[1] << '\n'
-            << "# Number of bins estimated: " << ext[1] - ext[0] + 1 << " x "
-            << ext[3] - ext[2] + 1 << '\n'
-            << "# Number of bins output: " << nbix << " x " << nbiy << '\n'
-            << "# Sample space extents: [" << xmin << " : " << xmax
-            << "], [" << ymin << " : " << ymax << "]\n"
-            << "# Iteration: " << it << "\n"
-            << "# Physical time: " << time << "\n"
-            << "$EndComments\n";
-
-  // Output mesh header: mesh version, file type, data size
-  m_outFile << "$MeshFormat\n2.2 0 8\n$EndMeshFormat\n";
-  ErrChk( !m_outFile.bad(), "Failed to write to file: " + m_filename );
-
-  // Output grid points of discretized sample space (2D Cartesian grid)
-  m_outFile << "$Nodes\n" << (nbix+1)*(nbiy+1) << std::endl;
-  int k=0;
-  for (std::size_t i=0; i<=nbiy; i++) {
-    tk::real I = static_cast< tk::real >( i );
-    tk::real y = ymin + I*binsize[1];
-    for (std::size_t j=0; j<=nbix; j++) {
-      tk::real J = static_cast< tk::real >( j );
-      tk::real x = xmin + J*binsize[0];
-      m_outFile << ++k << ' ' << x << ' ' << y << " 0\n";
-    }
-  }
-  m_outFile << "$EndNodes\n";
-
-  // Output elements of discretized sample space (2D Cartesian grid)
-  m_outFile << "$Elements\n" << nbix*nbiy << "\n";
-  for (std::size_t i=0; i<nbix*nbiy; ++i) {
-    const auto y = i/nbix;
-    m_outFile << i+1 << " 3 2 1 1 " << i+y+1 << ' ' << i+y+2 << ' '
-              << i+y+nbix+3 << ' ' << i+y+nbix+2 << std::endl;
-  }
-  m_outFile << "$EndElements\n";
-
-  // Output PDF function values in element or node centers
-  std::string c( "Element" );
-  if (centering == ctr::PDFCenteringType::NODE) {
-    ++nbix; ++nbiy;
-    c = "Node";
-  }
-  m_outFile << '$' << c << "Data\n1\n\"" << name << "\"\n1\n0.0\n3\n0\n1\n"
-            << nbix*nbiy << "\n";
-
-  // If no user-specified sample space extents, output pdf map directly
-  if (uext.empty()) {
-
-    std::vector< int > out( nbix*nbiy, 0 ); // indicate bins filled (1)
-    for (const auto& p : pdf.map()) {
-      const auto bin = (p.first[1] - ext[2]) * static_cast<long>(nbix) +
-                       (p.first[0] - ext[0]) % static_cast<long>(nbix);
-      Assert( bin >= 0, "Bin underflow in PDFWriter::writeGmshTxt()." );
-      Assert( static_cast<std::size_t>(bin) < nbix*nbiy,
-              "Bin overflow in PDFWriter::writeGmshTxt()." );
-      out[ static_cast<std::size_t>(bin) ] = 1;
-      m_outFile << bin+1 << '\t'
-                << p.second / binsize[0] / binsize[1]
-                            / static_cast<tk::real>(pdf.nsample())
-                << std::endl;
-    }
-    // Output bins nonexistent in PDF (gmsh sometimes fails to plot the exiting
-    // bins if holes exist in the data, it also looks better as zero than holes)
-    for (std::size_t i=0; i<out.size(); ++i)
-      if (out[i] == 0) m_outFile << i+1 << "\t0" << std::endl;
-
-  } else { // If user-specified sample space extents, output outpdf array
-
-    std::size_t bin = 0;
-    for (const auto& p : outpdf) m_outFile << ++bin << ' ' << p << std::endl;
-
-  }
-
-  m_outFile << "$End" << c << "Data\n";
-
-  ErrChk( !m_outFile.bad(), "Failed to write to file: " + m_filename );
-}
-
-void
-PDFWriter::writeGmshTxt( const TriPDF& pdf,
-                         const tk::ctr::PDFInfo& info,
-                         ctr::PDFCenteringType centering ) const
-// *****************************************************************************
-//  Write out standardized trivariate PDF to Gmsh (text) format
-//! \param[in] pdf Trivariate PDF
-//! \param[in] info PDF metadata
-//! \param[in] centering Bin centering on sample space mesh
-// *****************************************************************************
-{
-  const auto& name = info.name;
-  const auto& uext = info.exts;
-  const auto& vars = info.vars;
-  const auto& it = info.it;
-  const auto& time = info.time;
-
-  assertSampleSpaceDimensions< 3 >( vars );
-  assertSampleSpaceExtents< 3 >( uext );
-
-  // Query and optionally override number of bins and minima of sample space if
-  // user-specified extents were given and copy probabilities from pdf to a
-  // logically 3D array for output
-  std::size_t nbix, nbiy, nbiz;
-  tk::real xmin, xmax, ymin, ymax, zmin, zmax;
-  std::vector< tk::real > outpdf;
-  std::array< tk::real, 3 > binsize;
-  std::array< long, 2*TriPDF::dim > ext;
-  extents( pdf, uext, nbix, nbiy, nbiz, xmin, xmax, ymin, ymax, zmin, zmax,
-           binsize, ext, outpdf, centering );
-
-  // Output metadata. The #s are unnecessary, but vi will color it differently.
-  m_outFile << "$Comments\n"
-            << "# vim: filetype=sh:\n#\n"
-            << "# Joint trivariate PDF: " << name << '(' << vars[0] << ','
-            << vars[1] << ',' << vars[2] << ")\n"
-            << "# -----------------------------------------------\n"
-            << "# Numeric precision: " << m_outFile.precision() << '\n'
-            << "# Bin sizes: " << binsize[0] << ", " << binsize[1] << ", "
-            << binsize[2] << '\n'
-            << "# Number of bins estimated: " << ext[1] - ext[0] + 1 << " x "
-            << ext[3] - ext[2] + 1 << " x " << ext[5] - ext[4] + 1 << '\n'
-            << "# Number of bins output: " << nbix << " x " << nbiy << " x "
-            << nbiz << '\n'
-            << "# Sample space extents: [" << xmin << " : " << xmax << "], ["
-            << ymin << " : " << ymax << "], [" << zmin << " : " << zmax << "]\n"
-            << "# Iteration: " << it << "\n"
-            << "# Physical time: " << time << "\n#\n"
-            << "$EndComments\n";
-
-  // Output mesh header: mesh version, file type, data size
-  m_outFile << "$MeshFormat\n2.2 0 8\n$EndMeshFormat\n";
-  ErrChk( !m_outFile.bad(), "Failed to write to file: " + m_filename );
-
-  // Output grid points of discretized sample space (3D Cartesian grid)
-  m_outFile << "$Nodes\n" << (nbix+1)*(nbiy+1)*(nbiz+1) << std::endl;
-  int l=0;
-  for (std::size_t k=0; k<=nbiz; k++) {
-    tk::real K = static_cast< tk::real >( k );
-    tk::real z = zmin + K*binsize[2];
-    for (std::size_t j=0; j<=nbiy; j++) {
-      tk::real J = static_cast< tk::real >( j );
-      tk::real y = ymin + J*binsize[1];
-      for (std::size_t i=0; i<=nbix; i++) {
-        tk::real I = static_cast< tk::real >( i );
-        tk::real x = xmin + I*binsize[0];
-        m_outFile << ++l << ' ' << x << ' ' << y << ' ' << z << '\n';
-      }
-    }
-  }
-  m_outFile << "$EndNodes\n";
-
-  // Output elements of discretized sample space (3D Cartesian grid)
-  m_outFile << "$Elements\n" << nbix*nbiy*nbiz << "\n";
-  const auto n = nbix*nbiy;
-  const auto p = (nbix+1)*(nbiy+1);
-  for (std::size_t i=0; i<nbix*nbiy*nbiz; ++i) {
-    const auto y = i/nbix + i/n*(nbix+1);
-    m_outFile << i+1 << " 5 2 1 1 " << i+y+1 << ' ' << i+y+2 << ' '
-              << i+y+nbix+3 << ' ' << i+y+nbix+2 << ' '
-              << i+y+p+1 << ' ' << i+y+p+2 << ' '
-              << i+y+p+nbix+3 << ' ' << i+y+p+nbix+2 << ' '
-              << std::endl;
-  }
-  m_outFile << "$EndElements\n";
-
-  // Output PDF function values in element or node centers
-  std::string c( "Element" );
-  if (centering == ctr::PDFCenteringType::NODE) {
-    ++nbix; ++nbiy; ++nbiz;
-    c = "Node";
-  }
-  m_outFile << '$' << c << "Data\n1\n\"" << name << "\"\n1\n0.0\n3\n0\n1\n"
-            << nbix*nbiy*nbiz << "\n";
-
-  // If no user-specified sample space extents, output pdf map directly
-  if (uext.empty()) {
-
-    std::vector< int > out( nbix*nbiy*nbiz, 0 ); // indicate bins filled
-    for (const auto& q : pdf.map()) {
-      const auto bin = (q.first[2] - ext[4]) * static_cast<long>(nbix*nbiy) +
-                       (q.first[1] - ext[2]) * static_cast<long>(nbix) +
-                       (q.first[0] - ext[0]) % static_cast<long>(nbix);
-      Assert( bin >= 0, "Bin underflow in PDFWriter::writeGmshTxt()." );
-      Assert( static_cast<std::size_t>(bin) < nbix*nbiy*nbiz,
-              "Bin overflow in PDFWriter::writeGmshTxt()." );
-      out[ static_cast<std::size_t>(bin) ] = 1 ;
-      m_outFile << bin+1 << '\t'
-                << q.second / binsize[0] / binsize[1] / binsize[2]
-                            / static_cast<tk::real>(pdf.nsample())
-                << std::endl;
-    }
-    // Output bins nonexistent in PDF (gmsh sometimes fails to plot the exiting
-    // bins if holes exist in the data, it also looks better as zero than holes)
-    for (std::size_t i=0; i<out.size(); ++i)
-      if (out[i] == 0) m_outFile << i+1 << "\t0" << std::endl;
-
-  } else { // If user-specified sample space extents, output outpdf array
-
-    std::size_t bin = 0;
-    for (const auto& q : outpdf) m_outFile << ++bin << ' ' << q << std::endl;
-
-  }
-
-  m_outFile << "$End" << c << "Data\n";
-
-  ErrChk( !m_outFile.bad(), "Failed to write to file: " + m_filename );
-}
-
-void
-PDFWriter::writeGmshBin( const BiPDF& pdf,
-                         const tk::ctr::PDFInfo& info,
-                         ctr::PDFCenteringType centering ) const
-// *****************************************************************************
-//  Write out standardized bivariate PDF to Gmsh (binary) format
-//! \param[in] pdf Bivariate PDF
-//! \param[in] info PDF metadata
-//! \param[in] centering Bin centering on sample space mesh
-// *****************************************************************************
-{
-  const auto& name = info.name;
-  const auto& uext = info.exts;
-  const auto& vars = info.vars;
-  const auto& it = info.it;
-  const auto& time = info.time;
-
-  assertSampleSpaceDimensions< 2 >( vars );
-  assertSampleSpaceExtents< 2 >( uext );
-
-  // Query and optionally override number of bins and minima of sample space if
-  // user-specified extents were given and copy probabilities from pdf to a
-  // logically 2D array for output
-  std::size_t nbix, nbiy;
-  tk::real xmin, xmax, ymin, ymax;
-  std::vector< tk::real > outpdf;
-  std::array< tk::real, 2 > binsize;
-  std::array< long, 2*BiPDF::dim > ext;
-  extents( pdf, uext, nbix, nbiy, xmin, xmax, ymin, ymax, binsize, ext, outpdf,
-           centering );
-
-  // Output metadata. The #s are unnecessary, but vi will color it differently.
-  m_outFile << "$Comments\n"
-            << "# vim: filetype=sh:\n"
-            << "# Joint bivariate PDF: " << name << '(' << vars[0] << ','
-            << vars[1] << ")\n"
-            << "# -----------------------------------------------\n"
-            << "# Numeric precision: 64-bit binary\n"
-            << "# Bin sizes: " << binsize[0] << ", " << binsize[1] << '\n'
-            << "# Number of bins estimated: " << ext[1] - ext[0] + 1 << " x "
-            << ext[3] - ext[2] + 1 << '\n'
-            << "# Number of bins output: " << nbix << " x " << nbiy << '\n'
-            << "# Sample space extents: [" << xmin << " : " << xmax
-            << "], [" << ymin << " : " << ymax << "]\n"
-            << "# Iteration: " << it << "\n"
-            << "# Physical time: " << time << "\n#\n"
-            << "$EndComments\n";
-
-  // Output mesh header: mesh version, file type, data size
-  m_outFile << "$MeshFormat\n2.2 1 8\n";
-  int one = 1;
-  m_outFile.write( reinterpret_cast<char*>(&one), sizeof(int) );
-  m_outFile << "\n$EndMeshFormat\n";
-  ErrChk( !m_outFile.bad(), "Failed to write to file: " + m_filename );
-
-  // Output grid points of discretized sample space (2D Cartesian grid)
-  m_outFile << "$Nodes\n" << (nbix+1)*(nbiy+1) << std::endl;
-  int k = 0;
-  tk::real z = 0.0;
-  for (std::size_t i=0; i<=nbiy; i++) {
-    tk::real I = static_cast< tk::real >( i );
-    tk::real y = ymin + I*binsize[1];
-    for (std::size_t j=0; j<=nbix; j++) {
-      tk::real J = static_cast< tk::real >( j );
-      tk::real x = xmin + J*binsize[0];
-      ++k;
-      m_outFile.write( reinterpret_cast< char* >( &k ), sizeof(int) );
-      m_outFile.write( reinterpret_cast< char* >( &x ), sizeof(tk::real) );
-      m_outFile.write( reinterpret_cast< char* >( &y ), sizeof(tk::real) );
-      m_outFile.write( reinterpret_cast< char* >( &z ), sizeof(tk::real) );
-    }
-  }
-  m_outFile << "\n$EndNodes\n";
-
-  // Output elements of discretized sample space (2D Cartesian grid)
-  m_outFile << "$Elements\n" << nbix*nbiy << "\n";
-  int type = 3;                 // gmsh elem type: 4-node quadrangle
-  std::size_t n = nbix*nbiy;    // number of elements in (this single) block
-  int ntags = 2;                // number of element tags
-  m_outFile.write( reinterpret_cast< char* >( &type ), sizeof(int) );
-  m_outFile.write( reinterpret_cast< char* >( &n ), sizeof(int) );
-  m_outFile.write( reinterpret_cast< char* >( &ntags ), sizeof(int) );
-  for (std::size_t i=0; i<n; ++i) {
-    const auto y = i/nbix;
-    auto id = i+1;
-    int tag[2] = { 1, 1 };
-    int con[4] = { static_cast< int >( i+y+1 ),
-                   static_cast< int >( i+y+2 ),
-                   static_cast< int >( i+y+nbix+3 ),
-                   static_cast< int >( i+y+nbix+2 ) };
-    m_outFile.write( reinterpret_cast< char* >( &id ), sizeof(int) );
-    m_outFile.write( reinterpret_cast< char* >( tag ), 2*sizeof(int) );
-    m_outFile.write( reinterpret_cast< char* >( con ), 4*sizeof(int) );
-  }
-  m_outFile << "\n$EndElements\n";
-
-  // Output PDF function values in element or node centers
-  std::string c( "Element" );
-  if (centering == ctr::PDFCenteringType::NODE) {
-    ++nbix; ++nbiy;
-    c = "Node";
-  }
-  m_outFile << '$' << c << "Data\n1\n\"" << name << "\"\n1\n0.0\n3\n0\n1\n"
-            << nbix*nbiy << "\n";
-
-  // If no user-specified sample space extents, output pdf map directly
-  if (uext.empty()) {
-
-    std::vector< int > out( nbix*nbiy, 0 ); // indicate bins filled
-    for (const auto& p : pdf.map()) {
-      const auto bin = (p.first[1] - ext[2]) * static_cast<long>(nbix) +
-                       (p.first[0] - ext[0]) % static_cast<long>(nbix);
-      Assert( bin >= 0, "Bin underflow in PDFWriter::writeGmshBin()." );
-      Assert( static_cast<std::size_t>(bin) < nbix*nbiy,
-              "Bin overflow in PDFWriter::writeGmshBin()." );
-      out[ static_cast<std::size_t>(bin) ] = 1;
-      auto id = static_cast<int>(bin+1);
-      tk::real prob = p.second / binsize[0] / binsize[1]
-                               / static_cast<tk::real>(pdf.nsample());
-      m_outFile.write( reinterpret_cast< char* >( &id ), sizeof(int) );
-      m_outFile.write( reinterpret_cast< char* >( &prob ), sizeof(tk::real) );
-    }
-    // Output bins nonexistent in PDF (gmsh sometimes fails to plot the exiting
-    // bins if holes exist in the data, it also looks better as zero than holes)
-    tk::real prob = 0.0;
-    for (std::size_t i=0; i<out.size(); ++i)
-      if (out[i] == 0) {
-        auto id = static_cast<int>(i+1);
-        m_outFile.write( reinterpret_cast< char* >( &id ), sizeof(int) );
-        m_outFile.write( reinterpret_cast< char* >( &prob ), sizeof(tk::real) );
-      }
-
-  } else { // If user-specified sample space extents, output outpdf array
-
-    int bin = 0;
-    for (auto& p : outpdf) {
-      ++bin;
-      m_outFile.write( reinterpret_cast< char* >( &bin ), sizeof(int) );
-      m_outFile.write( reinterpret_cast< char* >( &p ), sizeof(tk::real) );
-    }
-
-  }
-
-  m_outFile << "$End" << c << "Data\n";
-
-  ErrChk( !m_outFile.bad(), "Failed to write to file: " + m_filename );
-}
-
-void
-PDFWriter::writeGmshBin( const TriPDF& pdf,
-                         const tk::ctr::PDFInfo& info,
-                         ctr::PDFCenteringType centering ) const
-// *****************************************************************************
-//  Write out standardized trivariate PDF to Gmsh (binary) format
-//! \param[in] pdf Trivariate PDF
-//! \param[in] info PDF metadata
-//! \param[in] centering Bin centering on sample space mesh
-// *****************************************************************************
-{
-  const auto& name = info.name;
-  const auto& uext = info.exts;
-  const auto& vars = info.vars;
-  const auto& it = info.it;
-  const auto& time = info.time;
-
-  assertSampleSpaceDimensions< 3 >( vars );
-  assertSampleSpaceExtents< 3 >( uext );
-
-  // Query and optionally override number of bins and minima of sample space if
-  // user-specified extents were given and copy probabilities from pdf to a
-  // logically 3D array for output
-  std::size_t nbix, nbiy, nbiz;
-  tk::real xmin, xmax, ymin, ymax, zmin, zmax;
-  std::vector< tk::real > outpdf;
-  std::array< tk::real, 3 > binsize;
-  std::array< long, 2*TriPDF::dim > ext;
-  extents( pdf, uext, nbix, nbiy, nbiz, xmin, xmax, ymin, ymax, zmin, zmax,
-           binsize, ext, outpdf, centering );
-
-  // Output metadata. The #s are unnecessary, but vi will color it differently.
-  m_outFile << "$Comments\n"
-            << "# vim: filetype=sh:\n#\n"
-            << "# Joint trivariate PDF: " << name << '(' << vars[0] << ','
-            << vars[1] << ',' << vars[2] << ")\n"
-            << "# -----------------------------------------------\n"
-            << "# Numeric precision: 64-bit binary\n"
-            << "# Bin sizes: " << binsize[0] << ", " << binsize[1] << ", "
-            << binsize[2] << '\n'
-            << "# Number of bins estimated: " << ext[1] - ext[0] + 1 << " x "
-            << ext[3] - ext[2] + 1 << " x " << ext[5] - ext[4] + 1 << '\n'
-            << "# Number of bins output: " << nbix << " x " << nbiy << " x "
-            << nbiz << '\n'
-            << "# Sample space extents: [" << xmin << " : " << xmax << "], ["
-            << ymin << " : " << ymax << "], [" << zmin << " : " << zmax << "]\n"
-            << "# Iteration: " << it << "\n"
-            << "# Physical time: " << time << "\n#\n"
-            << "$EndComments\n";
-
-  // Output mesh header: mesh version, file type, data size
-  m_outFile << "$MeshFormat\n2.2 1 8\n";
-  int one = 1;
-  m_outFile.write( reinterpret_cast<char*>(&one), sizeof(int) );
-  m_outFile << "\n$EndMeshFormat\n";
-  ErrChk( !m_outFile.bad(), "Failed to write to file: " + m_filename );
-
-  // Output grid points of discretized sample space (3D Cartesian grid)
-  m_outFile << "$Nodes\n" << (nbix+1)*(nbiy+1)*(nbiz+1) << std::endl;
-  int l=0;
-  for (std::size_t k=0; k<=nbiz; k++) {
-    tk::real K = static_cast< tk::real >( k );
-    tk::real z = zmin + K*binsize[2];
-    for (std::size_t j=0; j<=nbiy; j++) {
-      tk::real J = static_cast< tk::real >( j );
-      tk::real y = ymin + J*binsize[1];
-      for (std::size_t i=0; i<=nbix; i++) {
-        tk::real I = static_cast< tk::real >( i );
-        tk::real x = xmin + I*binsize[0];
-        ++l;
-        m_outFile.write( reinterpret_cast< char* >( &l ), sizeof(int) );
-        m_outFile.write( reinterpret_cast< char* >( &x ), sizeof(tk::real) );
-        m_outFile.write( reinterpret_cast< char* >( &y ), sizeof(tk::real) );
-        m_outFile.write( reinterpret_cast< char* >( &z ), sizeof(tk::real) );
-      }
-    }
-  }
-  m_outFile << "\n$EndNodes\n";
-
-  // Output elements of discretized sample space (3D Cartesian grid)
-  m_outFile << "$Elements\n" << nbix*nbiy*nbiz << "\n";
-  int type = 5;                       // gmsh elem type: 8-node hexahedron
-  std::size_t nelem = nbix*nbiy*nbiz; // num of elements in (this single) block
-  int ntags = 2;                      // number of element tags
-  m_outFile.write( reinterpret_cast< char* >( &type ), sizeof(int) );
-  m_outFile.write( reinterpret_cast< char* >( &nelem ), sizeof(int) );
-  m_outFile.write( reinterpret_cast< char* >( &ntags ), sizeof(int) );
-  const auto n = nbix*nbiy;
-  const auto p = (nbix+1)*(nbiy+1);
-  for (std::size_t i=0; i<nelem; ++i) {
-    const auto y = i/nbix + i/n*(nbix+1);
-    auto id = i+1;
-    int tag[2] = { 1, 1 };
-    int con[8] = { static_cast< int >( i+y+1 ),
-                   static_cast< int >( i+y+2 ),
-                   static_cast< int >( i+y+nbix+3 ),
-                   static_cast< int >( i+y+nbix+2 ),
-                   static_cast< int >( i+y+p+1 ),
-                   static_cast< int >( i+y+p+2 ),
-                   static_cast< int >( i+y+p+nbix+3 ),
-                   static_cast< int >( i+y+p+nbix+2 ) };
-    m_outFile.write( reinterpret_cast< char* >( &id ), sizeof(int) );
-    m_outFile.write( reinterpret_cast< char* >( tag ), 2*sizeof(int) );
-    m_outFile.write( reinterpret_cast< char* >( con ), 8*sizeof(int) );
-  }
-  m_outFile << "\n$EndElements\n";
-
-  // Output PDF function values in element or node centers
-  std::string c( "Element" );
-  if (centering == ctr::PDFCenteringType::NODE) {
-    ++nbix; ++nbiy; ++nbiz;
-    c = "Node";
-  }
-  m_outFile << '$' << c << "Data\n1\n\"" << name << "\"\n1\n0.0\n3\n0\n1\n"
-            << nbix*nbiy*nbiz << "\n";
-
-  // If no user-specified sample space extents, output pdf map directly
-  if (uext.empty()) {
-
-    std::vector< int > out( nbix*nbiy*nbiz, 0 ); // indicate bins filled
-    for (const auto& q : pdf.map()) {
-      const auto bin = (q.first[2] - ext[4]) * static_cast<long>(nbix*nbiy) +
-                       (q.first[1] - ext[2]) * static_cast<long>(nbix) +
-                       (q.first[0] - ext[0]) % static_cast<long>(nbix);
-      Assert( bin >= 0, "Bin underflow in PDFWriter::writeGmshBin()." );
-      Assert( static_cast<std::size_t>(bin) < nbix*nbiy*nbiz,
-              "Bin overflow in PDFWriter::writeGmshBin()." );
-      out[ static_cast<std::size_t>(bin) ] = 1;
-      auto id = static_cast<int>(bin+1);
-      tk::real prob = q.second / binsize[0] / binsize[1] / binsize[2]
-                               / static_cast<tk::real>(pdf.nsample());
-      m_outFile.write( reinterpret_cast< char* >( &id ), sizeof(int) );
-      m_outFile.write( reinterpret_cast< char* >( &prob ), sizeof(tk::real) );
-    }
-    // Output bins nonexistent in PDF (gmsh sometimes fails to plot the exiting
-    // bins if holes exist in the data, it also looks better as zero than holes)
-    tk::real prob = 0.0;
-    for (std::size_t i=0; i<out.size(); ++i)
-      if (out[i] == 0) {
-        auto id = static_cast<int>(i+1);
-        m_outFile.write( reinterpret_cast< char* >( &id ), sizeof(int) );
-        m_outFile.write( reinterpret_cast< char* >( &prob ), sizeof(tk::real) );
-      }
-
-  } else { // If user-specified sample space extents, output outpdf array
-
-    int bin = 0;
-    for (auto& q : outpdf) {
-      ++bin;
-      m_outFile.write( reinterpret_cast< char* >( &bin ), sizeof(int) );
-      m_outFile.write( reinterpret_cast< char* >( &q ), sizeof(tk::real) );
-    }
-
-  }
-
-  m_outFile << "$End" << c << "Data\n";
-
-  ErrChk( !m_outFile.bad(), "Failed to write to file: " + m_filename );
-}
-
-void
-PDFWriter::writeExodusII( const BiPDF& pdf,
-                          const tk::ctr::PDFInfo& info,
-                          ctr::PDFCenteringType centering ) const
-// *****************************************************************************
-//  Write out standardized bivariate PDF to Exodus II format
-//! \param[in] pdf Bivariate PDF
-//! \param[in] info PDF metadata
-//! \param[in] centering Bin centering on sample space mesh
-// *****************************************************************************
-{
-  const auto& name = info.name;
-  const auto& uext = info.exts;
-  const auto& vars = info.vars;
-
-  assertSampleSpaceDimensions< 2 >( vars );
-  assertSampleSpaceExtents< 2 >( uext );
-
-  // Query and optionally override number of bins and minima of sample space if
-  // user-specified extents were given and copy probabilities from pdf to a
-  // logically 2D array for output
-  std::size_t nbix, nbiy;
-  tk::real xmin, xmax, ymin, ymax;
-  std::vector< tk::real > outpdf;
-  std::array< tk::real, 2 > binsize;
-  std::array< long, 2*BiPDF::dim > ext;
-  extents( pdf, uext, nbix, nbiy, xmin, xmax, ymin, ymax, binsize, ext, outpdf,
-           centering );
-
-  // Create ExodusII file
-  int outFile = createExFile();
-
-  // Compute number of nodes and number of elements in sample space mesh
-  std::size_t nelem = nbix*nbiy;
-  std::size_t nnode = (nbix+1)*(nbiy+1);
-
-  // Write ExodusII header
-  writeExHdr( outFile, static_cast<int>(nnode), static_cast<int>(nelem) );
-
-  // Write sample space variables as coordinate names
-  char* coordnames[] = { const_cast< char* >( vars[0].c_str() ),
-                         const_cast< char* >( vars[1].c_str() ),
-                         const_cast< char* >( "probability" ) };
-  ErrChk( ex_put_coord_names( outFile, coordnames ) == 0,
-          "Failed to write coordinate names to file: " + m_filename );
-
-  // Output grid points of discretized sample space (2D Cartesian grid)
-  std::vector< tk::real > x( nnode, 0.0 );
-  std::vector< tk::real > y( nnode, 0.0 );
-  std::vector< tk::real > z( nnode, 0.0 );
-  std::size_t k = 0;
-  for (std::size_t i=0; i<=nbiy; i++)
-    for (std::size_t j=0; j<=nbix; j++) {
-      x[k] = xmin + static_cast< tk::real >( j )*binsize[0];
-      y[k] = ymin + static_cast< tk::real >( i )*binsize[1];
-      ++k;
-    }
-  ErrChk( ex_put_coord( outFile, x.data(), y.data(), z.data() ) == 0,
-          "Failed to write coordinates to file: " + m_filename );
-
-  // Output elements of discretized sample space (2D Cartesian grid)
-  // Write element block information
-  ErrChk( ex_put_block( outFile,
-                        EX_ELEM_BLOCK,
-                        1,
-                        "QUADRANGLES",
-                        static_cast<int64_t>(nelem),
-                        4,
-                        0,
-                        0,
-                        0 ) == 0,
-          "Failed to write QUDARANGLE element block to file: " + m_filename );
-  // Write element connectivity
-  for (std::size_t i=0; i<nelem; ++i) {
-    auto ye = i/nbix;
-    int con[4] = { static_cast< int >( i+ye+1 ),
-                   static_cast< int >( i+ye+2 ),
-                   static_cast< int >( i+ye+nbix+3 ),
-                   static_cast< int >( i+ye+nbix+2 ) };
-    ErrChk( ex_put_partial_conn( outFile, EX_ELEM_BLOCK, 1,
-              static_cast<int64_t>(i+1), 1, con, nullptr, nullptr ) == 0,
-      "Failed to write element connectivity to file: " + m_filename );
-  }
-
-  // Output PDF function values in element or node centers
-  ex_entity_type c = EX_ELEM_BLOCK;
-  if (centering == ctr::PDFCenteringType::NODE) {
-    ++nbix; ++nbiy;<--- Variable 'nbix' is assigned a value that is never used.<--- Variable 'nbiy' is assigned a value that is never used.
-    c = EX_NODE_BLOCK;
-  }
-
-  // Write PDF function values metadata
-  ErrChk( ex_put_variable_param( outFile, c, 1 ) == 0,
-            "Failed to write results metadata to file: " + m_filename );
-  char* probname[1];
-  std::string pdfname( name + '(' + vars[0] + ',' + vars[1] + ')' );
-  probname[0] = const_cast< char* >( pdfname.c_str() );
-  ErrChk( ex_put_variable_names( outFile, c, 1, probname ) == 0,
-            "Failed to write results metadata to file: " + m_filename );
-
-  // If no user-specified sample space extents, output pdf map directly
-  if (uext.empty()) {
-
-    // Output PDF function values in element centers
-    std::vector< tk::real > prob( nbix*nbiy, 0.0 );
-    for (const auto& p : pdf.map()) {
-      const auto bin = (p.first[1] - ext[2]) * static_cast<long>(nbix) +
-                       (p.first[0] - ext[0]) % static_cast<long>(nbix);
-      Assert( bin >= 0, "Bin underflow in PDFWriter::writeExodusII()." );
-      Assert( static_cast<std::size_t>(bin) < nbix*nbiy,
-              "Bin overflow in PDFWriter::writeExodusII()." );
-      prob[ static_cast<std::size_t>(bin) ] =
-        p.second / binsize[0] / binsize[1]
-                 / static_cast<tk::real>(pdf.nsample());
-    }
-    writeExVar( outFile, centering, prob );
-
-  } else { // If user-specified sample space extents, output outpdf array
-
-    writeExVar( outFile, centering, outpdf );
-
-  }
-
-  ErrChk( ex_close(outFile) == 0, "Failed to close file: " + m_filename );
-}
-
-void
-PDFWriter::writeExodusII( const TriPDF& pdf,
-                          const tk::ctr::PDFInfo& info,
-                          ctr::PDFCenteringType centering ) const
-// *****************************************************************************
-//  Write out standardized trivariate PDF to Exodus II format
-//! \param[in] pdf Trivariate PDF
-//! \param[in] info PDF metadata
-//! \param[in] centering Bin centering on sample space mesh
-// *****************************************************************************
-{
-  const auto& name = info.name;
-  const auto& uext = info.exts;
-  const auto& vars = info.vars;
-
-  assertSampleSpaceDimensions< 3 >( vars );
-  assertSampleSpaceExtents< 3 >( uext );
-
-  // Query and optionally override number of bins and minima of sample space if
-  // user-specified extents were given and copy probabilities from pdf to a
-  // logically 3D array for output
-  std::size_t nbix, nbiy, nbiz;
-  tk::real xmin, xmax, ymin, ymax, zmin, zmax;
-  std::vector< tk::real > outpdf;
-  std::array< tk::real, 3 > binsize;
-  std::array< long, 2*TriPDF::dim > ext;
-  extents( pdf, uext, nbix, nbiy, nbiz, xmin, xmax, ymin, ymax, zmin, zmax,
-           binsize, ext, outpdf, centering );
-
-  // Create ExodusII file
-  int outFile = createExFile();
-
-  // Compute number of nodes and number of elements in sample space mesh
-  std::size_t nelem = nbix*nbiy*nbiz;
-  std::size_t nnode = (nbix+1)*(nbiy+1)*(nbiz+1);
-
-  // Write ExodusII header
-  writeExHdr( outFile, static_cast<int>(nnode), static_cast<int>(nelem) );
-
-  // Write sample space variables as coordinate names
-  char* coordnames[] = { const_cast< char* >( vars[0].c_str() ),
-                         const_cast< char* >( vars[1].c_str() ),
-                         const_cast< char* >( vars[2].c_str() ) };
-  ErrChk( ex_put_coord_names( outFile, coordnames ) == 0,
-          "Failed to write coordinate names to file: " + m_filename );
-
-  // Output grid points of discretized sample space (2D Cartesian grid)
-  std::vector< tk::real > x( nnode, 0.0 );
-  std::vector< tk::real > y( nnode, 0.0 );
-  std::vector< tk::real > z( nnode, 0.0 );
-  std::size_t l=0;
-  for (std::size_t k=0; k<=nbiz; k++)
-    for (std::size_t i=0; i<=nbiy; i++)
-      for (std::size_t j=0; j<=nbix; j++) {
-        x[l] = xmin + static_cast<tk::real>(j) * binsize[0];
-        y[l] = ymin + static_cast<tk::real>(i) * binsize[1];
-        z[l] = zmin + static_cast<tk::real>(k) * binsize[2];
-        ++l;
-      }
-  ErrChk( ex_put_coord( outFile, x.data(), y.data(), z.data() ) == 0,
-          "Failed to write coordinates to file: " + m_filename );
-
-  // Output elements of discretized sample space (2D Cartesian grid)
-  // Write element block information
-  ErrChk( ex_put_block( outFile,
-                        EX_ELEM_BLOCK,
-                        1,
-                        "HEXAHEDRA",
-                        static_cast<int64_t>(nelem),
-                        8,
-                        0,
-                        0,
-                        0 ) == 0,
-          "Failed to write HEXAHEDRA element block to file: " + m_filename );
-  // Write element connectivity
-  const auto n = nbix*nbiy;
-  const auto p = (nbix+1)*(nbiy+1);
-  for (std::size_t i=0; i<nelem; ++i) {
-    const auto ye = i/nbix + i/n*(nbix+1);
-    int con[8] = { static_cast< int >( i+ye+1 ),
-                   static_cast< int >( i+ye+2 ),
-                   static_cast< int >( i+ye+nbix+3 ),
-                   static_cast< int >( i+ye+nbix+2 ),
-                   static_cast< int >( i+ye+p+1 ),
-                   static_cast< int >( i+ye+p+2 ),
-                   static_cast< int >( i+ye+p+nbix+3 ),
-                   static_cast< int >( i+ye+p+nbix+2 ) };
-    ErrChk(
-      ex_put_partial_conn( outFile, EX_ELEM_BLOCK, 1,
-        static_cast<int64_t>(i+1), 1, con, nullptr, nullptr ) == 0,
-      "Failed to write element connectivity to file: " + m_filename );
-  }
-
-  // Output PDF function values in element or node centers
-  ex_entity_type c = EX_ELEM_BLOCK;
-  if (centering == ctr::PDFCenteringType::NODE) {
-    ++nbix; ++nbiy; ++nbiz;<--- Variable 'nbix' is assigned a value that is never used.<--- Variable 'nbiy' is assigned a value that is never used.<--- Variable 'nbiz' is assigned a value that is never used.
-    c = EX_NODE_BLOCK;
-  }
-
-  // Write PDF function values metadata
-  ErrChk( ex_put_variable_param( outFile, c, 1 ) == 0,
-            "Failed to write results metadata to file: " + m_filename );
-  char* probname[1];
-  std::string pdfname( name + '(' + vars[0] + ',' +
-                         vars[1] + ',' + vars[2] + ')' );
-  probname[0] = const_cast< char* >( pdfname.c_str() );
-  ErrChk( ex_put_variable_names( outFile, c, 1, probname ) == 0,
-            "Failed to write results metadata to file: " + m_filename );
-
-  // If no user-specified sample space extents, output pdf map directly
-  if (uext.empty()) {
-
-    // Output PDF function values in element centers
-    std::vector< tk::real > prob( nbix*nbiy*nbiz, 0.0 );
-    for (const auto& q : pdf.map()) {
-      const auto bin = (q.first[2] - ext[4]) * static_cast<long>(nbix*nbiy) +
-                       (q.first[1] - ext[2]) * static_cast<long>(nbix) +
-                       (q.first[0] - ext[0]) % static_cast<long>(nbix);
-      Assert( bin >= 0, "Bin underflow in PDFWriter::writeExodusII()." );
-      Assert( static_cast<std::size_t>(bin) < nbix*nbiy*nbiz,
-              "Bin overflow in PDFWriter::writeExodusII()." );
-      prob[ static_cast<std::size_t>(bin) ] =
-        q.second / binsize[0] / binsize[1] / binsize[2]
-                 / static_cast<tk::real>(pdf.nsample());
-    }
-    writeExVar( outFile, centering, prob );
-
-  } else { // If user-specified sample space extents, output outpdf array
-
-    writeExVar( outFile, centering, outpdf );
-
-  }
-
-  ErrChk( ex_close(outFile) == 0, "Failed to close file: " + m_filename );
-}
-
-int
-PDFWriter::createExFile() const
-// *****************************************************************************
-//  Create Exodus II file
-//! \return ExodusII file handle
-// *****************************************************************************
-{
-  int cpuwordsize = sizeof( double );
-  int iowordsize = sizeof( double );
-  int outFileId = ex_create( m_filename.c_str(),
-                             EX_CLOBBER | EX_NORMAL_MODEL,
-                             &cpuwordsize,
-                             &iowordsize );
-  ErrChk( outFileId > 0, "Failed to create file: " + m_filename );
-  return outFileId;
-}
-
-void
-PDFWriter::writeExHdr( int outFileId, int nnode, int nelem ) const
-// *****************************************************************************
-//  Write Exodus II file header
-//! \param[in] outFileId Output file ExodusII Id
-//! \param[in] nnode Number of nodes in mesh to write
-//! \param[in] nelem Number of elements in mesh to write
-// *****************************************************************************
-{
-  ErrChk( ex_put_init( outFileId,
-                       "Written by Quinoa",
-                       3,                     // number of dimensions
-                       nnode,                 // number of nodes
-                       nelem,                 // number of elements
-                       1,                     // number of element blocks
-                       0,                     // number of node sets
-                       0 ) == 0,              // number of side sets
-          "Failed to write header to file: " + m_filename );
-}
-
-void
-PDFWriter::writeExVar( int exoFile,
-                       ctr::PDFCenteringType centering,
-                       const std::vector< tk::real >& probability ) const
-// *****************************************************************************
-//  Output probability density function as Exodus II results field
-//! \param[in] exoFile ExodusII file handle to write to
-//! \param[in] centering Node-, or element-centering to use on sample space mesh
-//! \param[in] probability Probabilities at each sample space location
-// *****************************************************************************
-{
-  if (centering == ctr::PDFCenteringType::NODE)
-    ErrChk( ex_put_var( exoFile,
-                        1,
-                        EX_NODE_BLOCK,
-                        1,
-                        1,
-                        static_cast<int64_t>(probability.size()),
-                        probability.data() ) == 0,
-            "Failed to write node-centered bivariate PDF to file: " +
-            m_filename );
-  else
-    ErrChk( ex_put_var( exoFile,
-                        1,
-                        EX_ELEM_BLOCK,
-                        1,
-                        1,
-                        static_cast<int64_t>(probability.size()),
-                        probability.data() ) == 0,
-            "Failed to write elem-centered bivariate PDF to file: " +
-            m_filename );
-}
-
-void
-PDFWriter::extents( const UniPDF& pdf,
-                    const std::vector< tk::real >& uext,
-                    std::size_t& nbi,
-                    tk::real& min,
-                    tk::real& max,
-                    tk::real& binsize,
-                    std::array< long, 2*UniPDF::dim >& ext,
-                    std::vector< tk::real >& outpdf ) const
-// *****************************************************************************
-//  Query extents and other metadata of univariate PDF sample space
-//! \details Query and optionally override number of bins and minimum of sample
-//!    space if user-specified extents were given and copy probabilities from
-//!    pdf to an array for output for plotting univariate PDF.
-//! \param[in] pdf Univariate PDF object
-//! \param[in] uext User-specified extents of sample space
-//! \param[inout] nbi Number of bins
-//! \param[inout] min Minimum value of sample space
-//! \param[inout] max Maximum value of sample space
-//! \param[inout] binsize Bin size
-//! \param[inout] ext Extents of sample space
-//! \param[inout] outpdf PDF ready to be written out to file
-// *****************************************************************************
-{
-  assertSampleSpaceExtents< 1 >( uext );
-
-  // Query bin size and extents of sample space from PDF
-  binsize = pdf.binsize();
-  ext = pdf.extents();
-
-  // Compute number of bins of sample space (min bins: 1)
-  Assert( ext[1] >= ext[0], "Wrong extents in PDFWriter::extents" );
-  nbi = static_cast< std::size_t >( ext[1] - ext[0] + 1 );
-
-  // Compute minimum and maximum of sample space
-  min = binsize * static_cast< tk::real >( ext[0] );
-  max = binsize * static_cast< tk::real >( ext[1] );
-
-  // Override number of bins and minimum if user-specified extents were given,
-  // and copy probabilities from pdf to an array for output
-  if (!uext.empty()) {
-    // Override number of bins by that based on user-specified extents
-    Assert( uext[1] >= uext[0],
-            "Wrong user-defined extents in PDFWriter::extents" );
-    nbi = static_cast< std::size_t >(
-            std::lround( (uext[1] - uext[0]) / binsize ) );
-    // Override extents
-    min = uext[0];
-    max = uext[1];
-
-    // Size output pdf to user-requested dimensions to overridden nbi and
-    // initialize output probabilities to zero
-    outpdf = std::vector< tk::real >( nbi, 0.0 );
-
-    // Fill requested region of pdf to be output from computed pdf
-    for (const auto& p : pdf.map()) {
-      // Compute (i.e., shift) bin indices relative to user-requested extents
-      const auto bin = p.first - std::lround( uext[0] / binsize );
-      // Only copy probability value if shifted bin indices fall within
-      // user-requested extents (lower inclusive, upper exclusive)
-      if (bin >= 0 && bin < std::lround( (uext[1] - uext[0]) / binsize )) {
-        Assert( static_cast<std::size_t>(bin) < nbi,
-                "Bin overflow in user-specified-extent-based bin "
-                "calculation of univariate PDF extents." );
-        // Copy normalized probability to output pdf
-        outpdf[ static_cast<std::size_t>(bin) ] =
-          p.second / binsize / static_cast<tk::real>(pdf.nsample());
-      }
-    }
-  }
-}
-
-void
-PDFWriter::extents( const BiPDF& pdf,
-                    const std::vector< tk::real >& uext,
-                    std::size_t& nbix,
-                    std::size_t& nbiy,
-                    tk::real& xmin,
-                    tk::real& xmax,
-                    tk::real& ymin,
-                    tk::real& ymax,
-                    std::array< tk::real, BiPDF::dim >& binsize,
-                    std::array< long, 2*BiPDF::dim >& ext,
-                    std::vector< tk::real >& outpdf,
-                    ctr::PDFCenteringType centering ) const
-// *****************************************************************************
-//  Query extents and other metadata of bivariate PDF sample space
-//! \details Query and optionally override number of bins and minima of sample
-//!    space if user-specified extents were given and copy probabilities from
-//!    pdf to a logically 2D array for output for plotting bivariate joint PDF.
-//! \param[in] pdf Bivariate PDF object
-//! \param[in] uext User-specified extents of sample space
-//! \param[inout] nbix Number of bins in x dimension
-//! \param[inout] nbiy Number of bins in y dimension
-//! \param[inout] xmin Minimum x value of sample space
-//! \param[inout] xmax Maximum x value of sample space
-//! \param[inout] ymin Minimum y value of sample space
-//! \param[inout] ymax Maximum y value of sample space
-//! \param[inout] binsize Bin size
-//! \param[inout] ext Extents of sample space
-//! \param[inout] outpdf PDF ready to be written out to file
-//! \param[in] centering Bin centering on sample space mesh
-// *****************************************************************************
-{
-  assertSampleSpaceExtents< 2 >( uext );
-
-  // Query bin sizes and extents of sample space from PDF
-  binsize = pdf.binsize();
-  ext = pdf.extents();
-
-  // Compute number of bins in sample space directions (min bins: 1)
-  Assert( ext[1] >= ext[0], "Wrong extents in PDFWriter::extents" );
-  Assert( ext[3] >= ext[2], "Wrong extents in PDFWriter::extents" );
-  nbix = static_cast< std::size_t >( ext[1] - ext[0] + 1 );
-  nbiy = static_cast< std::size_t >( ext[3] - ext[2] + 1 );
-
-  // Compute minima and maxima of sample space
-  xmin = binsize[0] * static_cast< tk::real >( ext[0] );
-  xmax = binsize[0] * static_cast< tk::real >( ext[1] );
-  ymin = binsize[1] * static_cast< tk::real >( ext[2] );
-  ymax = binsize[1] * static_cast< tk::real >( ext[3] );
-
-  // Override number of bins and minima if user-specified extents were given,
-  // and copy probabilities from pdf to a logically 2D array for output
-  if (!uext.empty()) {
-    // Override number of bins by that based on user-specified extents
-    Assert( uext[1] >= uext[0],
-            "Wrong user-defined extents in PDFWriter::extents" );
-    Assert( uext[3] >= uext[2],
-            "Wrong user-defined extents in PDFWriter::extents" );
-    nbix = static_cast< std::size_t >(
-             std::lround( (uext[1] - uext[0]) / binsize[0] ) );
-    nbiy = static_cast< std::size_t >(
-             std::lround( (uext[3] - uext[2]) / binsize[1] ) );
-    // Override extents
-    xmin = uext[0];
-    xmax = uext[1];
-    ymin = uext[2];
-    ymax = uext[3];
-
-    // Temporarily increase number of bins if node-centered output required
-    if (centering == ctr::PDFCenteringType::NODE) { ++nbix; ++nbiy; }
-
-    // Size output pdf to user-requested dimensions to overridden nbiy * nbix
-    // and initialize output probabilities to zero
-    outpdf = std::vector< tk::real >( nbix*nbiy, 0.0 );
-
-    // Fill requested region of pdf to be output from computed pdf
-    for (const auto& p : pdf.map()) {
-      // Compute (i.e., shift) bin indices relative to user-requested extents
-      const auto x = p.first[0] - std::lround( uext[0] / binsize[0] );
-      const auto y = p.first[1] - std::lround( uext[2] / binsize[1] );
-      // Only copy probability value if shifted bin indices fall within
-      // user-requested extents (lower inclusive, upper exclusive)
-      if (x >= 0 && x < std::lround( (uext[1] - uext[0]) / binsize[0] ) &&
-          y >= 0 && y < std::lround( (uext[3] - uext[2]) / binsize[1] ))
-      {
-        const auto bin =
-          static_cast<std::size_t>(y)*nbix + static_cast<std::size_t>(x);
-        Assert( bin < nbix*nbiy, "Bin overflow in user-specified-extent-based "
-                "bin calculation of bivariate PDF." );
-        // Copy normalized probability to output pdf
-        outpdf[ bin ] = p.second / binsize[0] / binsize[1]
-                                 / static_cast<tk::real>(pdf.nsample());
-      }
-    }
-
-    // Revert number of bins if node-centered output required
-    if (centering == ctr::PDFCenteringType::NODE) { --nbix; --nbiy; }
-  }
-}
-
-void
-PDFWriter::extents( const TriPDF& pdf,
-                    const std::vector< tk::real >& uext,
-                    std::size_t& nbix,
-                    std::size_t& nbiy,
-                    std::size_t& nbiz,
-                    tk::real& xmin,
-                    tk::real& xmax,
-                    tk::real& ymin,
-                    tk::real& ymax,
-                    tk::real& zmin,
-                    tk::real& zmax,
-                    std::array< tk::real, TriPDF::dim >& binsize,
-                    std::array< long, 2*TriPDF::dim >& ext,
-                    std::vector< tk::real >& outpdf,
-                    ctr::PDFCenteringType centering ) const
-// *****************************************************************************
-//  Query extents and other metadata of trivariate PDF sample space
-//! \details Query and optionally override number of bins and minima of sample
-//!   space if user-specified extents were given and copy probabilities from
-//!   pdf to a logically 3D array for output for plotting trivariate joint PDF.
-//! \param[in] pdf Trivariate PDF object
-//! \param[in] uext User-specified extents of sample space
-//! \param[inout] nbix Number of bins in x dimension
-//! \param[inout] nbiy Number of bins in y dimension
-//! \param[inout] nbiz Number of bins in z dimension
-//! \param[inout] xmin Minimum x value of sample space
-//! \param[inout] xmax Maximum x value of sample space
-//! \param[inout] ymin Minimum y value of sample space
-//! \param[inout] ymax Maximum y value of sample space
-//! \param[inout] zmin Minimum z value of sample space
-//! \param[inout] zmax Maximum z value of sample space
-//! \param[inout] binsize Bin size
-//! \param[inout] ext Extents of sample space
-//! \param[inout] outpdf PDF ready to be written out to file
-//! \param[in] centering Bin centering on sample space mesh
-// *****************************************************************************
-{
-  assertSampleSpaceExtents< 3 >( uext );
-
-  // Query bin sizes and extents of sample space from PDF
-  binsize = pdf.binsize();
-  ext = pdf.extents();
-
-  // Compute number of bins in sample space directions (min bins: 1)
-  Assert( ext[1] >= ext[0], "Wrong extents in PDFWriter::extents" );
-  Assert( ext[3] >= ext[2], "Wrong extents in PDFWriter::extents" );
-  Assert( ext[5] >= ext[4], "Wrong extents in PDFWriter::extents" );
-  nbix = static_cast< std::size_t >( ext[1] - ext[0] + 1 );
-  nbiy = static_cast< std::size_t >( ext[3] - ext[2] + 1 );
-  nbiz = static_cast< std::size_t >( ext[5] - ext[4] + 1 );
-
-  // Compute minima and maxima of sample space
-  xmin = binsize[0] * static_cast< tk::real >( ext[0] );
-  xmax = binsize[0] * static_cast< tk::real >( ext[1] );
-  ymin = binsize[1] * static_cast< tk::real >( ext[2] );
-  ymax = binsize[1] * static_cast< tk::real >( ext[3] );
-  zmin = binsize[2] * static_cast< tk::real >( ext[4] );
-  zmax = binsize[2] * static_cast< tk::real >( ext[5] );
-
-  // Override number of bins and minima if user-specified extents were given,
-  // and copy probabilities from pdf to a logically 3D array for output
-  if (!uext.empty()) {
-    // Override number of bins by that based on user-specified extents
-    Assert( uext[1] >= uext[0],
-            "Wrong user-defined extents in PDFWriter::extents" );
-    Assert( uext[3] >= uext[2],
-            "Wrong user-defined extents in PDFWriter::extents" );
-    Assert( uext[5] >= uext[4],
-            "Wrong user-defined extents in PDFWriter::extents" );
-    nbix = static_cast< std::size_t >(
-             std::lround( (uext[1] - uext[0]) / binsize[0] ) );
-    nbiy = static_cast< std::size_t >(
-             std::lround( (uext[3] - uext[2]) / binsize[1] ) );
-    nbiz = static_cast< std::size_t >(
-             std::lround( (uext[5] - uext[4]) / binsize[2] ) );
-    // Override extents
-    xmin = uext[0];
-    xmax = uext[1];
-    ymin = uext[2];
-    ymax = uext[3];
-    zmin = uext[4];
-    zmax = uext[5];
-
-    // Temporarily increase number of bins if node-centered output required
-    if (centering == ctr::PDFCenteringType::NODE) { ++nbix; ++nbiy; ++nbiz; }
-
-    // Size output pdf to user-requested dimensions to overridden nbiz * nbiy *
-    // nbix and initialize output probabilities to zero
-    outpdf = std::vector< tk::real >( nbiz * nbiy * nbix, 0.0 );
-
-    // Fill requested region of pdf to be output from computed pdf
-    for (const auto& p : pdf.map()) {
-      // Compute (i.e., shift) bin indices relative to user-requested extents
-      const auto x = p.first[0] - std::lround( uext[0] / binsize[0] );
-      const auto y = p.first[1] - std::lround( uext[2] / binsize[1] );
-      const auto z = p.first[2] - std::lround( uext[4] / binsize[2] );
-      // Only copy probability value if shifted bin indices fall within
-      // user-requested extents (lower inclusive, upper exclusive)
-      if (x >= 0 && x < std::lround( (uext[1] - uext[0]) / binsize[0] ) &&
-          y >= 0 && y < std::lround( (uext[3] - uext[2]) / binsize[1] ) &&
-          z >= 0 && z < std::lround( (uext[5] - uext[4]) / binsize[2] ))
-      {
-        const auto X = static_cast< std::size_t >( x );
-        const auto Y = static_cast< std::size_t >( y );
-        const auto Z = static_cast< std::size_t >( z );
-        const auto bin = nbix*(Z*nbiy + Y) + X;
-        Assert( bin < nbix*nbiy*nbiz, "Bin overflow in "
-              "user-specified-extent-based bin calculation of bivariate PDF." );
-        // Copy normalized probability to output pdf
-        outpdf[ bin ] =
-          p.second / binsize[0] / binsize[1] / binsize[2]
-                   / static_cast<tk::real>(pdf.nsample());
-      }
-    }
-
-    // Revert number of bins if node-centered output required
-    if (centering == ctr::PDFCenteringType::NODE) { --nbix; --nbiy; --nbiz; }
-  }
-}
+    //! Add a time stamp contributing to final timers output
+    void timestamp( std::string label, tk::real stamp ) {
+      try {
+        m_timestamp.emplace_back( label, tk::hms( stamp ) );
+      } catch (...) { tk::processExceptionCharm(); }
+    }
+    //! Add multiple time stamps contributing to final timers output
+    void timestamp( const std::vector< std::pair< std::string, tk::real > >& s )
+    { for (const auto& t : s) timestamp( t.first, t.second ); }
+
+    //! Entry method triggered when quiescence is detected
+    void quiescence() {
+      try {
+        stateProxy.collect( /* error= */ true,
+          CkCallback( CkIndex_Main::dumpstate(nullptr), thisProxy ) );
+      } catch (...) { tk::processExceptionCharm(); }
+    }
+
+    //! Dump chare state
+    void dumpstate( CkReductionMsg* msg ) {
+      tk::dumpstate( m_cmdline,
+        m_cmdline.get< tag::io, tag::screen >(),
+        m_cmdline.get< tag::io, tag::nrestart >(),
+        msg );
+    }
+
+  private:
+    int m_signal;                               //!< Used to set signal handlers
+    meshconv::ctr::CmdLine m_cmdline;           //!< Command line
+    meshconv::CmdLineParser m_cmdParser;        //!< Command line parser
+    meshconv::MeshConvDriver m_driver;          //!< Driver
+    std::vector< tk::Timer > m_timer;           //!< Timers
+
+    //! Time stamps in h:m:s with labels
+    std::vector< std::pair< std::string, tk::Timer::Watch > > m_timestamp;
+};
+
+//! \brief Charm++ chare execute
+//! \details By the time this object is constructed, the Charm++ runtime system
+//!    has finished migrating all global-scoped read-only objects which happens
+//!    after the main chare constructor has finished.
+class execute : public CBase_execute {
+  public: execute() { mainProxy.execute(); }
+};
+
+#include "NoWarning/meshconv.def.h"
 
diff --git a/Debug/cppcheck/27.html b/Debug/cppcheck/27.html index 98511b10b2c7..61d20a942438 100644 --- a/Debug/cppcheck/27.html +++ b/Debug/cppcheck/27.html @@ -152,12 +152,12 @@
  1
@@ -393,524 +393,240 @@ 

Cppcheck report - [

// *****************************************************************************
+234
// *****************************************************************************
 /*!
-  \file      src/Mesh/Reorder.cpp
+  \file      src/Main/UnitTest.cpp
   \copyright 2012-2015 J. Bakosi,
              2016-2018 Los Alamos National Security, LLC.,
              2019-2021 Triad National Security, LLC.
              All rights reserved. See the LICENSE file for details.
-  \brief     Mesh reordering routines for unstructured meshes
-  \details   Mesh reordering routines for unstructured meshes.
-*/
-// *****************************************************************************
-
-#include <algorithm>
-#include <iterator>
-#include <unordered_map>
+  \brief     UnitTest's Charm++ main chare and main().
+  \details   UnitTest's Charm++ main chare and main(). This file contains
+    the definition of the Charm++ main chare, equivalent to main() in Charm++-
+    land, running the serial and Charm++ unit tests as well as the ordinary
+    main() function, running the MPI unit test suite.
+*/
+// *****************************************************************************
+
 #include <map>
-#include <tuple>
-#include <cstddef>
-
-#include "Reorder.hpp"
-#include "Exception.hpp"
-#include "ContainerUtil.hpp"
-#include "Vector.hpp"
+#include <vector>
+#include <string>
+#include <iostream>
+#include <utility>
+#include <cstddef>
+
+#include "NoWarning/tut_runner.hpp"
 
-namespace tk {
-
-std::size_t
-shiftToZero( std::vector< std::size_t >& inpoel )
-// *****************************************************************************
-//  Shift node IDs to start with zero in element connectivity
-//! \param[inout] inpoel Inteconnectivity of points and elements
-//! \return Amount shifted
-//! \details This function implements a simple reordering of the node ids of the
-//!   element connectivity in inpoel by shifting the node ids so that the
-//!   smallest is zero.
-//! \note It is okay to call this function with an empty container; it will
-//!    simply return without throwing an exception.
-// *****************************************************************************
-{
-  if (inpoel.empty()) return 0;
-
-  // find smallest node id
-  auto minId = *std::min_element( begin(inpoel), end(inpoel) );
+#include "NoWarning/tutsuite.decl.h"
+#include "NoWarning/unittest.decl.h"
+
+#include "Print.hpp"
+#include "Timer.hpp"
+#include "Tags.hpp"
+#include "Exception.hpp"
+#include "Init.hpp"
+#include "QuinoaConfig.hpp"
+#include "HelpFactory.hpp"
+#include "Assessment.hpp"
+#include "ProcessException.hpp"
+#include "UnitTest/CmdLine/CmdLine.hpp"
+#include "UnitTestPrint.hpp"
+#include "UnitTestDriver.hpp"
+#include "UnitTest/CmdLine/Parser.hpp"
+#include "TUTConfig.hpp"
+#include "ChareStateCollector.hpp"
+#include "QuietCerr.hpp"
 
-  // shift node ids to start from zero
-  // cppcheck-suppress useStlAlgorithm
-  for (auto& n : inpoel) n -= minId;
-
-  return minId;
-}
-
-void
-remap( std::vector< std::size_t >& ids, const std::vector< std::size_t >& map )
-// *****************************************************************************
-//  Apply new maping to vector of indices
-//! \param[inout] ids Vector of integer IDs to remap
-//! \param[in] map Array of indices creating a new order
-//! \details This function applies a mapping (reordering) to the integer IDs
-//!   passed in using the map passed in. The mapping is expressed between the
-//!   array index and its value. The function overwrites every value, i, of
-//!   vector ids with map[i].
-//! \note The sizes of ids and map need not equal. Only the maximum index in ids
-//!   must be lower than the size of map.
-//! \note It is okay to call this function with either of the containers empty;
-//!   it will simply return without throwing an exception.
-// *****************************************************************************
-{
-  if (ids.empty() || map.empty()) return;
+#if defined(__clang__)
+  #pragma clang diagnostic push
+  #pragma clang diagnostic ignored "-Wmissing-variable-declarations"
+#endif
+
+//! \brief Charm handle to the main proxy, facilitates call-back to finalize,
+//!    etc., must be in global scope, unique per executable
+CProxy_Main mainProxy;
+
+//! Chare state collector Charm++ chare group proxy
+tk::CProxy_ChareStateCollector stateProxy;
+
+//! If true, call and stack traces are to be output with exceptions
+//! \note This is true by default so that the trace is always output between
+//!   program start and the Main ctor in which the user-input from command line
+//!   setting for this overrides this true setting.
+bool g_trace = true;
+
+#if defined(__clang__)
+  #pragma clang diagnostic pop
+#endif
+
+//! UnitTest declarations and definitions
+namespace unittest {
 
-  Assert( *max_element( begin(ids), end(ids) ) < map.size(),
-          "Indexing out of bounds" );
-
-  // remap integer IDs in vector ids
-  // cppcheck-suppress useStlAlgorithm
-  for (auto& i : ids) i = map[i];
-}
-
-void
-remap( std::vector< tk::real >& r, const std::vector< std::size_t >& map )
-// *****************************************************************************
-//  Apply new maping to vector of real numbers
-//! \param[inout] r Vector of real numbers to remap
-//! \param[in] map Array of indices creating a new order
-//! \details This function applies a mapping (reordering) to the real values
-//!   passed in using the map passed in. The mapping is expressed between the
-//!   array index and its value. The function moves every value r[i] to
-//!   r[ map[i] ].
-//! \note The sizes of r and map must be equal and the maximum index in map must
-//!   be lower than the size of map.
-//! \note It is okay to call this function with either of the containers empty;
-//!   it will simply return without throwing an exception.
-// *****************************************************************************
-{
-  if (r.empty() || map.empty()) return;
+//! Global-scope data. Initialized by the main chare and distibuted to all PEs
+//! by the Charm++ runtime system. Though semantically not const, all these
+//! global data should be considered read-only. See also
+//! http://charm.cs.illinois.edu/manuals/html/charm++/manual.html. The data
+//! below is global-scope because they must be available to all PEs which could
+//! be on different machines.
+
+#if defined(__clang__)
+  #pragma clang diagnostic push
+  #pragma clang diagnostic ignored "-Wmissing-variable-declarations"
+#endif
+
+//! Template Unit Test test runner
+tut::test_runner_singleton g_runner;
+
+//! Test suite Charm++ proxy facilitating call-back to unit test suite by
+//! individual unit tests spawning Charm++ chares
+CProxy_TUTSuite g_suiteProxy;
+
+//! UnitTest executable name. So that FileParser's unit tests can access a file
+//! for opening.
+std::string g_executable;
+
+//! Max number of tests in every group
+int g_maxTestsInGroup = tut::MAX_TESTS_IN_GROUP;
 
-  Assert( r.size() == map.size(), "Size mismatch" );
-  Assert( *max_element( begin(map), end(map) ) < map.size(),
-          "Indexing out of bounds" );
+#if defined(__clang__)
+  #pragma clang diagnostic pop
+#endif
 
-  // remap real numbers in vector
-  auto m = r;
-  for (std::size_t i=0; i<map.size(); ++i) r[ map[i] ] = m[ i ];
-}
-
-std::vector< std::size_t >
-remap( const std::vector< std::size_t >& ids,
-       const std::vector< std::size_t >& map )
-// *****************************************************************************
-//  Create remapped vector of indices using a vector
-//! \param[in] ids Vector of integer IDs to remap
-//! \param[in] map Array of indices creating a new order
-//! \return Remapped vector of ids
-//! \details This function applies a mapping (reordering) to the integer IDs
-//!   passed in using the map passed in. The mapping is expressed between the
-//!   array index and its value. The function creates and returns a new container
-//!   with remapped ids of identical size of the origin ids container.
-//! \note The sizes of ids and map must be equal and the maximum index in map
-//!   must be lower than the size of map.
-//! \note It is okay to call this function with either of the containers empty;
-//!   if ids is empty, it returns an empty container; if map is empty, it will
-//!   return the original container.
-// *****************************************************************************
-{
-  if (ids.empty()) return {};
-  if (map.empty()) return ids;
-
-  Assert( *max_element( begin(ids), end(ids) ) < map.size(),
-          "Indexing out of bounds" );
-
-  // in terms of the in-place remap of a vector usinga vector
-  auto newids = ids;
-  remap( newids, map );
-
-  return newids;
-}
-
-void
-remap( std::vector< std::size_t >& ids,
-       const std::unordered_map< std::size_t, std::size_t >& map )
-// *****************************************************************************
-//  In-place remap vector of indices using a map
-//! \param[in] ids Vector of integer IDs to remap
-//! \param[in] map Hash-map of key->value creating a new order
-//! \details This function applies a mapping (reordering) to the integer IDs
-//!   passed in using the map passed in. The mapping is expressed as a hash-map
-//!   of key->value pairs, where the key is the original and the value is the
-//!   new ids of the mapping. The function overwrites the ids container with the
-//!   remapped ids of identical size.
-//! \note All ids in the input ids container must have a key in the map.
-//!   Otherwise an exception is thrown.
-//! \note It is okay to call this function with the ids container empty but not
-//!   okay to pass an empty map.
-// *****************************************************************************
-{
-  Assert( !map.empty(), "Map must not be empty" );
-
-  for (auto& i : ids) i = tk::cref_find( map, i );<--- Consider using std::transform algorithm instead of a raw loop.
-}
-
-std::vector< std::size_t >
-remap( const std::vector< std::size_t >& ids,
-       const std::unordered_map< std::size_t, std::size_t >& map )
-// *****************************************************************************
-//  Create remapped vector of indices using a map
-//! \param[in] ids Vector of integer IDs to create new container of ids from
-//! \param[in] map Hash-map of key->value creating a new order
-//! \return Remapped vector of ids
-//! \details This function applies a mapping (reordering) to the integer IDs
-//!   passed in using the map passed in. The mapping is expressed as a hash-map
-//!   of key->value pairs, where the key is the original and the value is the
-//!   new ids of the mapping. The function creates and returns a new container
-//!   with the remapped ids of identical size of the original ids container.
-//! \note All ids in the input ids container must have a key in the map.
-//!   Otherwise an exception is thrown.
-//! \note It is okay to call this function with the ids container empty but not
-//!   okay to pass an empty map.
-// *****************************************************************************
-{
-  Assert( !map.empty(), "Map must not be empty" );
-
-  // in terms of the in-place remap of a vector using a map
-  auto newids = ids;
-  remap( newids, map );
-
-  return newids;
-}
-
-std::map< int, std::vector< std::size_t > >
-remap( const std::map< int, std::vector< std::size_t > >& ids,
-       const std::unordered_map< std::size_t, std::size_t >& map )
-// *****************************************************************************
-//  Create remapped map of vector of indices using a map
-//! \param[in] ids Map of vector of integer IDs to create new container of ids
-//!   from
-//! \param[in] map Hash-map of key->value creating a new order
-//! \return Remapped vector of ids
-//! \details This function applies a mapping (reordering) to the map of integer
-//!   IDs passed in using the map passed in by applying remap(vector,map) on
-//!   each vector of ids. The keys in the returned map will be the same as in
-//!   ids.
-// *****************************************************************************
-{
-  Assert( !map.empty(), "Map must not be empty" );
-
-  // in terms of the in-place remap of a vector using a map
-  auto newids = ids;
-  for (auto& m : newids) remap( m.second, map );
-
-  return newids;
-}
-
-std::vector< std::size_t >
-renumber( const std::pair< std::vector< std::size_t >,
-                           std::vector< std::size_t > >& psup )
-// *****************************************************************************
-//  Reorder mesh points with the advancing front technique
-//! \param[in] psup Points surrounding points
-//! \return Mapping created by renumbering (reordering)
-// *****************************************************************************
-{
-  // Find out number of nodes in graph
-  auto npoin = psup.second.size()-1;
-
-  // Construct mapping using advancing front
-  std::vector< int > hpoin( npoin, -1 ), lpoin( npoin, 0 );
-  std::vector< std::size_t > map( npoin, 0 );
-  hpoin[0] = 0;
-  lpoin[0] = 1;
-  std::size_t num = 1;
-  while (num < npoin) {
-    std::size_t cnt = 0;
-    std::size_t i = 0;
-    std::vector< int > kpoin( npoin, -1 );
-    int p;
-    while ((p = hpoin[i]) != -1) {
-      ++i;
-      auto P = static_cast< std::size_t >( p );
-      for (auto j=psup.second[P]+1; j<=psup.second[P+1]; ++j) {
-        auto q = psup.first[j];
-        if (lpoin[q] != 1) {    // consider points not yet counted
-          map[q] = num++;
-          kpoin[cnt] = static_cast< int >( q ); // register point as counted
-          lpoin[q] = 1;                         // register the point as counted
-          ++cnt;
-        }
-      }
-    }
-    hpoin = kpoin;
-  }
-
-//   // Construct new->old id map
-//   std::size_t i = 0;
-//   std::vector< std::size_t > oldmap( npoin );
-//   for (auto n : map) oldmap[n] = i++;
-
-  // Return old->new and new->old maps
-  return map;
-}
-
-std::unordered_map< std::size_t, std::size_t >
-assignLid( const std::vector< std::size_t >& gid )
-// *****************************************************************************
-//  Assign local ids to global ids
-//! \param[in] gid Global ids
-//! \return Map associating global ids to local ids
-// *****************************************************************************
-{
-  std::unordered_map< std::size_t, std::size_t > lid;
-  std::size_t l = 0;
-  for (auto p : gid) lid[p] = l++;
-  return lid;
-}
-
-std::tuple< std::vector< std::size_t >,
-            std::vector< std::size_t >,
-            std::unordered_map< std::size_t, std::size_t > >
-global2local( const std::vector< std::size_t >& ginpoel )
-// *****************************************************************************
-//  Generate element connectivity of local node IDs from connectivity of global
-//  node IDs also returning the mapping between local to global IDs
-//! \param[in] ginpoel Element connectivity with global node IDs
-//! \return Tuple of (1) element connectivity with local node IDs, (2) the
-//!   vector of unique global node IDs (i.e., the mapping between local to
-//!   global node IDs), and (3) mapping between global to local node IDs.
-// *****************************************************************************
-{
-  // Make a copy of the element connectivity with global node ids
-  auto gid = ginpoel;
-
-  // Generate a vector that holds only the unique global mesh node ids
-  tk::unique( gid );
-
-  // Assign local node ids to global node ids
-  const auto lid = tk::assignLid( gid );
-
-  Assert( gid.size() == lid.size(), "Size mismatch" );
-
-  // Generate element connectivity using local node ids
-  std::vector< std::size_t > inpoel( ginpoel.size() );
-  std::size_t j = 0;
-  for (auto p : ginpoel) inpoel[ j++ ] = tk::cref_find( lid, p );
-
-  // Return element connectivty with local node IDs
-  return std::make_tuple( inpoel, gid, lid );
-}
-
-bool
-positiveJacobians( const std::vector< std::size_t >& inpoel,
-                   const std::array< std::vector< real >, 3 >& coord )
-// *****************************************************************************
-// Test for positivity of the Jacobian for all cells in mesh
-//! \param[in] inpoel Element connectivity (zero-based, i.e., local if parallel)
-//! \param[in] coord Node coordinates
-//! \return True if Jacobians of all mesh cells are positive
-// *****************************************************************************
-{
-  Assert( !inpoel.empty(), "Mesh connectivity empty" );
-  Assert( inpoel.size() % 4 == 0,
-          "Mesh connectivity size must be divisible by 4 " );
-  Assert( tk::uniquecopy(inpoel).size() == coord[0].size(), "Number of unique "
-          "nodes in mesh connectivity must equal the number of nodes to which "
-          "coordinates have been supplied" );
-  Assert( tk::uniquecopy(inpoel).size() == coord[1].size(), "Number of unique "
-          "nodes in mesh connectivity must equal the number of nodes to which "
-          "coordinates have been supplied" );
-  Assert( tk::uniquecopy(inpoel).size() == coord[2].size(), "Number of unique "
-          "nodes in mesh connectivity must equal the number of nodes to which "
-          "coordinates have been supplied" );
-  Assert( *std::minmax_element( begin(inpoel), end(inpoel) ).first == 0,
-          "node ids should start from zero" );
-
-  const auto& x = coord[0];
-  const auto& y = coord[1];
-  const auto& z = coord[2];
-
-  for (std::size_t e=0; e<inpoel.size()/4; ++e) {
-    const std::array< std::size_t, 4 > N{{ inpoel[e*4+0], inpoel[e*4+1],
-                                           inpoel[e*4+2], inpoel[e*4+3] }};
-    // compute element Jacobi determinant / (5/120) = element volume * 4
-    const std::array< tk::real, 3 >
-      ba{{ x[N[1]]-x[N[0]], y[N[1]]-y[N[0]], z[N[1]]-z[N[0]] }},
-      ca{{ x[N[2]]-x[N[0]], y[N[2]]-y[N[0]], z[N[2]]-z[N[0]] }},
-      da{{ x[N[3]]-x[N[0]], y[N[3]]-y[N[0]], z[N[3]]-z[N[0]] }};
-    if (tk::triple( ba, ca, da ) < 0) return false;
- }
-
- return true;
-}
-
-std::map< int, std::vector< std::size_t > >
-bfacenodes( const std::map< int, std::vector< std::size_t > >& bface,
-            const std::vector< std::size_t >& triinpoel )
-// *****************************************************************************
-// Generate nodes of side set faces
-//! \param[in] bface Boundary-faces mapped to side set ids
-//! \param[in] triinpoel Boundary-face connectivity
-//! \return Nodes of side set faces for each side set passed in
-// *****************************************************************************
-{
-  auto bfn = bface;
-
-  for (auto& [s,b] : bfn) {
-    std::vector< std::size_t > nodes;
-    for (auto f : b) {
-      nodes.push_back( triinpoel[f*3+0] );
-      nodes.push_back( triinpoel[f*3+1] );
-      nodes.push_back( triinpoel[f*3+2] );
-    }
-    tk::unique( nodes );
-    b = std::move( nodes );
-  }
-
-  return bfn;
-}
-
-} // tk::
+//! Pack/Unpack test runner. This Pack/Unpack method (re-)creates the
+//! test runner singleton on all processing elements. Therefore we circumvent
+//! Charm's usual pack/unpack for this type, and thus sizing does not make
+//! sense: sizing is a no-op. We could initialize the stack in UnitTestDriver's
+//! constructor and let this function re-create the runner only when unpacking,
+//! but that leads to repeating the same code twice: once in UnitTestDriver's
+//! constructor, once here. Another option is to use this pack/unpack routine to
+//! both initially create (when packing) and to re-create (when unpacking) the
+//! runner, which eliminates the need for pre-creating the object in
+//! UnitTestDriver's constructor and therefore eliminates the repeated code.
+//! This explains the guard for sizing: the code below is called for packing
+//! only (in serial) and packing and unpacking (in parallel).
+inline void operator|( PUP::er& p, tut::test_runner_singleton& runner )
+{ if (!p.isSizing()) runner = tut::test_runner_singleton(); }
+
+} // unittest::
+
+//! \brief Charm++ main chare for the unit test suite executable, unittest.
+//! \details Note that this object should not be in a namespace.
+// cppcheck-suppress noConstructor
+class Main : public CBase_Main {<--- Unmatched suppression: noConstructor
+
+  public:
+    //! \brief Constructor
+    //! \details UnitTest's main chare constructor is the entry point of the
+    //!   program, called by the Charm++ runtime system. The constructor does
+    //!   basic initialization steps, e.g., parser the command-line, prints out
+    //!   some useful information to screen (in verbose mode), and instantiates
+    //!   a driver. Since Charm++ is fully asynchronous, the constructor
+    //!   usually spawns asynchronous objects and immediately exits. Thus in the
+    //!   body of the main chare constructor we fire up an 'execute' chare,
+    //!   which then calls back to Main::execute(). Finishing the main chare
+    //!   constructor the Charm++ runtime system then starts the
+    //!   network-migration of all global-scope data (if any). The execute chare
+    //!   calling back to Main::execute() signals the end of the migration of
+    //!   the global-scope data. Then we are ready to execute the driver. Since
+    //!   the unit test suite is parallel and asynchronous, its driver fires up
+    //!   additional Charm++ chare objects which then call back to
+    //!   Main::finalize() at some point in the future when all work has been
+    //!   finished. finalize() then exits by calling Charm++'s CkExit(),
+    //!   shutting down the runtime system.
+    //! \see http://charm.cs.illinois.edu/manuals/html/charm++/manual.html
+    Main( CkArgMsg* msg )
+    try :
+      m_signal( tk::setSignalHandlers() ),
+      m_helped( false ),
+      m_cmdline(),
+      // Parse command line into m_cmdline using default simple pretty printer
+      m_cmdParser( msg->argc, msg->argv, tk::Print(), m_cmdline, m_helped ),
+      // Create UnitTest driver
+      m_driver( tk::Main< unittest::UnitTestDriver >
+                        ( msg->argc, msg->argv,
+                          m_cmdline,
+                          tk::HeaderType::UNITTEST,
+                          tk::unittest_executable(),
+                          m_cmdline.get< tag::io, tag::screen >(),
+                          m_cmdline.get< tag::io, tag::nrestart >() ) ),
+      m_timer(1), // Start new timer measuring the serial+Charm++ runtime
+      m_timestamp()
+    {
+      g_trace = m_cmdline.get< tag::trace >();
+      // Immediately exit if any help was requested; help is printed in main()
+      if (m_helped) CkExit();
+      // Save executable name to global-scope string so FileParser can access it
+      unittest::g_executable = msg->argv[0];
+      delete msg;
+      // Call generic mainchare contructor
+      tk::MainCtor( mainProxy, thisProxy, m_timer, m_cmdline,
+                    CkCallback( CkIndex_Main::quiescence(), thisProxy ) );
+      // If quiescence detection is on or user requested it, create chare state
+      // collector Charm++ chare group
+      if ( m_cmdline.get< tag::chare >() || m_cmdline.get< tag::quiescence >() )
+        stateProxy = tk::CProxy_ChareStateCollector::ckNew();
+      // Fire up an asynchronous execute object, which when created at some
+      // future point in time will call back to this->execute(). This is
+      // necessary so that this->execute() can access already migrated
+      // global-scope data.
+      CProxy_execute::ckNew();
+      // Quiet std::cerr
+      tk::CProxy_QuietCerr::ckNew();
+    } catch (...) { tk::processExceptionCharm(); }
+
+    void execute() {
+      try {
+        m_timestamp.emplace_back("Migrate global-scope data", m_timer[1].hms());
+        m_driver.execute();       // fires up async chares
+      } catch (...) { tk::processExceptionCharm(); }
+    }
+
+    //! Towards normal exit but collect chare state first (if any)
+    void finalize( bool pass ) {
+      tk::finalize( m_cmdline, m_timer, stateProxy, m_timestamp,
+        m_cmdline.get< tag::io, tag::screen >(),
+        m_cmdline.get< tag::io, tag::nrestart >(),
+        CkCallback( CkIndex_Main::dumpstate(nullptr), thisProxy ),
+        pass );
+    }
+
+    //! Entry method triggered when quiescence is detected
+    void quiescence() {
+      try {
+        stateProxy.collect( /* error= */ true,
+          CkCallback( CkIndex_Main::dumpstate(nullptr), thisProxy ) );
+      } catch (...) { tk::processExceptionCharm(); }
+    }
+
+    //! Dump chare state
+    void dumpstate( CkReductionMsg* msg ) {
+      tk::dumpstate( m_cmdline,
+        m_cmdline.get< tag::io, tag::screen >(),
+        m_cmdline.get< tag::io, tag::nrestart >(),
+        msg );
+    }
+
+  private:
+    int m_signal;                               //!< Used to set signal handlers
+    bool m_helped;      //!< Indicates if help was requested on the command line
+    unittest::ctr::CmdLine m_cmdline;                   //!< Command line
+    unittest::CmdLineParser m_cmdParser;                //!< Command line parser
+    unittest::UnitTestDriver m_driver;                  //!< Driver
+    std::vector< tk::Timer > m_timer;                   //!< Timers
+
+    //! Time stamps in h:m:s with labels
+    std::vector< std::pair< std::string, tk::Timer::Watch > > m_timestamp;
+};
+
+//! \brief Charm++ chare execute
+//! \details By the time this object is constructed, the Charm++ runtime system
+//!    has finished migrating all global-scoped read-only objects which happens
+//!    after the main chare constructor has finished.
+class execute : public CBase_execute {
+  public: execute() { mainProxy.execute(); }
+};
+
+#include "NoWarning/unittest.def.h"
 
diff --git a/Debug/cppcheck/28.html b/Debug/cppcheck/28.html index 140a05b71e6e..8cc71c6f1ffd 100644 --- a/Debug/cppcheck/28.html +++ b/Debug/cppcheck/28.html @@ -152,12 +152,12 @@
  1
@@ -393,240 +393,524 @@ 

Cppcheck report - [

// *****************************************************************************
+234
+235
+236
+237
+238
+239
+240
+241
+242
+243
+244
+245
+246
+247
+248
+249
+250
+251
+252
+253
+254
+255
+256
+257
+258
+259
+260
+261
+262
+263
+264
+265
+266
+267
+268
+269
+270
+271
+272
+273
+274
+275
+276
+277
+278
+279
+280
+281
+282
+283
+284
+285
+286
+287
+288
+289
+290
+291
+292
+293
+294
+295
+296
+297
+298
+299
+300
+301
+302
+303
+304
+305
+306
+307
+308
+309
+310
+311
+312
+313
+314
+315
+316
+317
+318
+319
+320
+321
+322
+323
+324
+325
+326
+327
+328
+329
+330
+331
+332
+333
+334
+335
+336
+337
+338
+339
+340
+341
+342
+343
+344
+345
+346
+347
+348
+349
+350
+351
+352
+353
+354
+355
+356
+357
+358
+359
+360
+361
+362
+363
+364
+365
+366
+367
+368
+369
+370
+371
+372
+373
+374
+375
+376
// *****************************************************************************
 /*!
-  \file      src/Main/UnitTest.cpp
+  \file      src/Mesh/Reorder.cpp
   \copyright 2012-2015 J. Bakosi,
              2016-2018 Los Alamos National Security, LLC.,
              2019-2021 Triad National Security, LLC.
              All rights reserved. See the LICENSE file for details.
-  \brief     UnitTest's Charm++ main chare and main().
-  \details   UnitTest's Charm++ main chare and main(). This file contains
-    the definition of the Charm++ main chare, equivalent to main() in Charm++-
-    land, running the serial and Charm++ unit tests as well as the ordinary
-    main() function, running the MPI unit test suite.
-*/
-// *****************************************************************************
-
+  \brief     Mesh reordering routines for unstructured meshes
+  \details   Mesh reordering routines for unstructured meshes.
+*/
+// *****************************************************************************
+
+#include <algorithm>
+#include <iterator>
+#include <unordered_map>
 #include <map>
-#include <vector>
-#include <string>
-#include <iostream>
-#include <utility>
-#include <cstddef>
-
-#include "NoWarning/tut_runner.hpp"
+#include <tuple>
+#include <cstddef>
+
+#include "Reorder.hpp"
+#include "Exception.hpp"
+#include "ContainerUtil.hpp"
+#include "Vector.hpp"
 
-#include "NoWarning/tutsuite.decl.h"
-#include "NoWarning/unittest.decl.h"
-
-#include "Print.hpp"
-#include "Timer.hpp"
-#include "Tags.hpp"
-#include "Exception.hpp"
-#include "Init.hpp"
-#include "QuinoaConfig.hpp"
-#include "HelpFactory.hpp"
-#include "Assessment.hpp"
-#include "ProcessException.hpp"
-#include "UnitTest/CmdLine/CmdLine.hpp"
-#include "UnitTestPrint.hpp"
-#include "UnitTestDriver.hpp"
-#include "UnitTest/CmdLine/Parser.hpp"
-#include "TUTConfig.hpp"
-#include "ChareStateCollector.hpp"
-#include "QuietCerr.hpp"
+namespace tk {
+
+std::size_t
+shiftToZero( std::vector< std::size_t >& inpoel )
+// *****************************************************************************
+//  Shift node IDs to start with zero in element connectivity
+//! \param[inout] inpoel Inteconnectivity of points and elements
+//! \return Amount shifted
+//! \details This function implements a simple reordering of the node ids of the
+//!   element connectivity in inpoel by shifting the node ids so that the
+//!   smallest is zero.
+//! \note It is okay to call this function with an empty container; it will
+//!    simply return without throwing an exception.
+// *****************************************************************************
+{
+  if (inpoel.empty()) return 0;
+
+  // find smallest node id
+  auto minId = *std::min_element( begin(inpoel), end(inpoel) );
 
-#if defined(__clang__)
-  #pragma clang diagnostic push
-  #pragma clang diagnostic ignored "-Wmissing-variable-declarations"
-#endif
-
-//! \brief Charm handle to the main proxy, facilitates call-back to finalize,
-//!    etc., must be in global scope, unique per executable
-CProxy_Main mainProxy;
-
-//! Chare state collector Charm++ chare group proxy
-tk::CProxy_ChareStateCollector stateProxy;
-
-//! If true, call and stack traces are to be output with exceptions
-//! \note This is true by default so that the trace is always output between
-//!   program start and the Main ctor in which the user-input from command line
-//!   setting for this overrides this true setting.
-bool g_trace = true;
-
-#if defined(__clang__)
-  #pragma clang diagnostic pop
-#endif
-
-//! UnitTest declarations and definitions
-namespace unittest {
+  // shift node ids to start from zero
+  // cppcheck-suppress useStlAlgorithm
+  for (auto& n : inpoel) n -= minId;
+
+  return minId;
+}
+
+void
+remap( std::vector< std::size_t >& ids, const std::vector< std::size_t >& map )
+// *****************************************************************************
+//  Apply new maping to vector of indices
+//! \param[inout] ids Vector of integer IDs to remap
+//! \param[in] map Array of indices creating a new order
+//! \details This function applies a mapping (reordering) to the integer IDs
+//!   passed in using the map passed in. The mapping is expressed between the
+//!   array index and its value. The function overwrites every value, i, of
+//!   vector ids with map[i].
+//! \note The sizes of ids and map need not equal. Only the maximum index in ids
+//!   must be lower than the size of map.
+//! \note It is okay to call this function with either of the containers empty;
+//!   it will simply return without throwing an exception.
+// *****************************************************************************
+{
+  if (ids.empty() || map.empty()) return;
 
-//! Global-scope data. Initialized by the main chare and distibuted to all PEs
-//! by the Charm++ runtime system. Though semantically not const, all these
-//! global data should be considered read-only. See also
-//! http://charm.cs.illinois.edu/manuals/html/charm++/manual.html. The data
-//! below is global-scope because they must be available to all PEs which could
-//! be on different machines.
-
-#if defined(__clang__)
-  #pragma clang diagnostic push
-  #pragma clang diagnostic ignored "-Wmissing-variable-declarations"
-#endif
-
-//! Template Unit Test test runner
-tut::test_runner_singleton g_runner;
-
-//! Test suite Charm++ proxy facilitating call-back to unit test suite by
-//! individual unit tests spawning Charm++ chares
-CProxy_TUTSuite g_suiteProxy;
-
-//! UnitTest executable name. So that FileParser's unit tests can access a file
-//! for opening.
-std::string g_executable;
-
-//! Max number of tests in every group
-int g_maxTestsInGroup = tut::MAX_TESTS_IN_GROUP;
+  Assert( *max_element( begin(ids), end(ids) ) < map.size(),
+          "Indexing out of bounds" );
+
+  // remap integer IDs in vector ids
+  // cppcheck-suppress useStlAlgorithm
+  for (auto& i : ids) i = map[i];
+}
+
+void
+remap( std::vector< tk::real >& r, const std::vector< std::size_t >& map )
+// *****************************************************************************
+//  Apply new maping to vector of real numbers
+//! \param[inout] r Vector of real numbers to remap
+//! \param[in] map Array of indices creating a new order
+//! \details This function applies a mapping (reordering) to the real values
+//!   passed in using the map passed in. The mapping is expressed between the
+//!   array index and its value. The function moves every value r[i] to
+//!   r[ map[i] ].
+//! \note The sizes of r and map must be equal and the maximum index in map must
+//!   be lower than the size of map.
+//! \note It is okay to call this function with either of the containers empty;
+//!   it will simply return without throwing an exception.
+// *****************************************************************************
+{
+  if (r.empty() || map.empty()) return;
 
-#if defined(__clang__)
-  #pragma clang diagnostic pop
-#endif
+  Assert( r.size() == map.size(), "Size mismatch" );
+  Assert( *max_element( begin(map), end(map) ) < map.size(),
+          "Indexing out of bounds" );
 
-//! Pack/Unpack test runner. This Pack/Unpack method (re-)creates the
-//! test runner singleton on all processing elements. Therefore we circumvent
-//! Charm's usual pack/unpack for this type, and thus sizing does not make
-//! sense: sizing is a no-op. We could initialize the stack in UnitTestDriver's
-//! constructor and let this function re-create the runner only when unpacking,
-//! but that leads to repeating the same code twice: once in UnitTestDriver's
-//! constructor, once here. Another option is to use this pack/unpack routine to
-//! both initially create (when packing) and to re-create (when unpacking) the
-//! runner, which eliminates the need for pre-creating the object in
-//! UnitTestDriver's constructor and therefore eliminates the repeated code.
-//! This explains the guard for sizing: the code below is called for packing
-//! only (in serial) and packing and unpacking (in parallel).
-inline void operator|( PUP::er& p, tut::test_runner_singleton& runner )
-{ if (!p.isSizing()) runner = tut::test_runner_singleton(); }
-
-} // unittest::
-
-//! \brief Charm++ main chare for the unit test suite executable, unittest.
-//! \details Note that this object should not be in a namespace.
-// cppcheck-suppress noConstructor
-class Main : public CBase_Main {<--- Unmatched suppression: noConstructor
-
-  public:
-    //! \brief Constructor
-    //! \details UnitTest's main chare constructor is the entry point of the
-    //!   program, called by the Charm++ runtime system. The constructor does
-    //!   basic initialization steps, e.g., parser the command-line, prints out
-    //!   some useful information to screen (in verbose mode), and instantiates
-    //!   a driver. Since Charm++ is fully asynchronous, the constructor
-    //!   usually spawns asynchronous objects and immediately exits. Thus in the
-    //!   body of the main chare constructor we fire up an 'execute' chare,
-    //!   which then calls back to Main::execute(). Finishing the main chare
-    //!   constructor the Charm++ runtime system then starts the
-    //!   network-migration of all global-scope data (if any). The execute chare
-    //!   calling back to Main::execute() signals the end of the migration of
-    //!   the global-scope data. Then we are ready to execute the driver. Since
-    //!   the unit test suite is parallel and asynchronous, its driver fires up
-    //!   additional Charm++ chare objects which then call back to
-    //!   Main::finalize() at some point in the future when all work has been
-    //!   finished. finalize() then exits by calling Charm++'s CkExit(),
-    //!   shutting down the runtime system.
-    //! \see http://charm.cs.illinois.edu/manuals/html/charm++/manual.html
-    Main( CkArgMsg* msg )
-    try :
-      m_signal( tk::setSignalHandlers() ),
-      m_helped( false ),
-      m_cmdline(),
-      // Parse command line into m_cmdline using default simple pretty printer
-      m_cmdParser( msg->argc, msg->argv, tk::Print(), m_cmdline, m_helped ),
-      // Create UnitTest driver
-      m_driver( tk::Main< unittest::UnitTestDriver >
-                        ( msg->argc, msg->argv,
-                          m_cmdline,
-                          tk::HeaderType::UNITTEST,
-                          tk::unittest_executable(),
-                          m_cmdline.get< tag::io, tag::screen >(),
-                          m_cmdline.get< tag::io, tag::nrestart >() ) ),
-      m_timer(1), // Start new timer measuring the serial+Charm++ runtime
-      m_timestamp()
-    {
-      g_trace = m_cmdline.get< tag::trace >();
-      // Immediately exit if any help was requested; help is printed in main()
-      if (m_helped) CkExit();
-      // Save executable name to global-scope string so FileParser can access it
-      unittest::g_executable = msg->argv[0];
-      delete msg;
-      // Call generic mainchare contructor
-      tk::MainCtor( mainProxy, thisProxy, m_timer, m_cmdline,
-                    CkCallback( CkIndex_Main::quiescence(), thisProxy ) );
-      // If quiescence detection is on or user requested it, create chare state
-      // collector Charm++ chare group
-      if ( m_cmdline.get< tag::chare >() || m_cmdline.get< tag::quiescence >() )
-        stateProxy = tk::CProxy_ChareStateCollector::ckNew();
-      // Fire up an asynchronous execute object, which when created at some
-      // future point in time will call back to this->execute(). This is
-      // necessary so that this->execute() can access already migrated
-      // global-scope data.
-      CProxy_execute::ckNew();
-      // Quiet std::cerr
-      tk::CProxy_QuietCerr::ckNew();
-    } catch (...) { tk::processExceptionCharm(); }
-
-    void execute() {
-      try {
-        m_timestamp.emplace_back("Migrate global-scope data", m_timer[1].hms());
-        m_driver.execute();       // fires up async chares
-      } catch (...) { tk::processExceptionCharm(); }
-    }
-
-    //! Towards normal exit but collect chare state first (if any)
-    void finalize( bool pass ) {
-      tk::finalize( m_cmdline, m_timer, stateProxy, m_timestamp,
-        m_cmdline.get< tag::io, tag::screen >(),
-        m_cmdline.get< tag::io, tag::nrestart >(),
-        CkCallback( CkIndex_Main::dumpstate(nullptr), thisProxy ),
-        pass );
-    }
-
-    //! Entry method triggered when quiescence is detected
-    void quiescence() {
-      try {
-        stateProxy.collect( /* error= */ true,
-          CkCallback( CkIndex_Main::dumpstate(nullptr), thisProxy ) );
-      } catch (...) { tk::processExceptionCharm(); }
-    }
-
-    //! Dump chare state
-    void dumpstate( CkReductionMsg* msg ) {
-      tk::dumpstate( m_cmdline,
-        m_cmdline.get< tag::io, tag::screen >(),
-        m_cmdline.get< tag::io, tag::nrestart >(),
-        msg );
-    }
-
-  private:
-    int m_signal;                               //!< Used to set signal handlers
-    bool m_helped;      //!< Indicates if help was requested on the command line
-    unittest::ctr::CmdLine m_cmdline;                   //!< Command line
-    unittest::CmdLineParser m_cmdParser;                //!< Command line parser
-    unittest::UnitTestDriver m_driver;                  //!< Driver
-    std::vector< tk::Timer > m_timer;                   //!< Timers
-
-    //! Time stamps in h:m:s with labels
-    std::vector< std::pair< std::string, tk::Timer::Watch > > m_timestamp;
-};
-
-//! \brief Charm++ chare execute
-//! \details By the time this object is constructed, the Charm++ runtime system
-//!    has finished migrating all global-scoped read-only objects which happens
-//!    after the main chare constructor has finished.
-class execute : public CBase_execute {
-  public: execute() { mainProxy.execute(); }
-};
-
-#include "NoWarning/unittest.def.h"
+  // remap real numbers in vector
+  auto m = r;
+  for (std::size_t i=0; i<map.size(); ++i) r[ map[i] ] = m[ i ];
+}
+
+std::vector< std::size_t >
+remap( const std::vector< std::size_t >& ids,
+       const std::vector< std::size_t >& map )
+// *****************************************************************************
+//  Create remapped vector of indices using a vector
+//! \param[in] ids Vector of integer IDs to remap
+//! \param[in] map Array of indices creating a new order
+//! \return Remapped vector of ids
+//! \details This function applies a mapping (reordering) to the integer IDs
+//!   passed in using the map passed in. The mapping is expressed between the
+//!   array index and its value. The function creates and returns a new container
+//!   with remapped ids of identical size of the origin ids container.
+//! \note The sizes of ids and map must be equal and the maximum index in map
+//!   must be lower than the size of map.
+//! \note It is okay to call this function with either of the containers empty;
+//!   if ids is empty, it returns an empty container; if map is empty, it will
+//!   return the original container.
+// *****************************************************************************
+{
+  if (ids.empty()) return {};
+  if (map.empty()) return ids;
+
+  Assert( *max_element( begin(ids), end(ids) ) < map.size(),
+          "Indexing out of bounds" );
+
+  // in terms of the in-place remap of a vector usinga vector
+  auto newids = ids;
+  remap( newids, map );
+
+  return newids;
+}
+
+void
+remap( std::vector< std::size_t >& ids,
+       const std::unordered_map< std::size_t, std::size_t >& map )
+// *****************************************************************************
+//  In-place remap vector of indices using a map
+//! \param[in] ids Vector of integer IDs to remap
+//! \param[in] map Hash-map of key->value creating a new order
+//! \details This function applies a mapping (reordering) to the integer IDs
+//!   passed in using the map passed in. The mapping is expressed as a hash-map
+//!   of key->value pairs, where the key is the original and the value is the
+//!   new ids of the mapping. The function overwrites the ids container with the
+//!   remapped ids of identical size.
+//! \note All ids in the input ids container must have a key in the map.
+//!   Otherwise an exception is thrown.
+//! \note It is okay to call this function with the ids container empty but not
+//!   okay to pass an empty map.
+// *****************************************************************************
+{
+  Assert( !map.empty(), "Map must not be empty" );
+
+  for (auto& i : ids) i = tk::cref_find( map, i );<--- Consider using std::transform algorithm instead of a raw loop.
+}
+
+std::vector< std::size_t >
+remap( const std::vector< std::size_t >& ids,
+       const std::unordered_map< std::size_t, std::size_t >& map )
+// *****************************************************************************
+//  Create remapped vector of indices using a map
+//! \param[in] ids Vector of integer IDs to create new container of ids from
+//! \param[in] map Hash-map of key->value creating a new order
+//! \return Remapped vector of ids
+//! \details This function applies a mapping (reordering) to the integer IDs
+//!   passed in using the map passed in. The mapping is expressed as a hash-map
+//!   of key->value pairs, where the key is the original and the value is the
+//!   new ids of the mapping. The function creates and returns a new container
+//!   with the remapped ids of identical size of the original ids container.
+//! \note All ids in the input ids container must have a key in the map.
+//!   Otherwise an exception is thrown.
+//! \note It is okay to call this function with the ids container empty but not
+//!   okay to pass an empty map.
+// *****************************************************************************
+{
+  Assert( !map.empty(), "Map must not be empty" );
+
+  // in terms of the in-place remap of a vector using a map
+  auto newids = ids;
+  remap( newids, map );
+
+  return newids;
+}
+
+std::map< int, std::vector< std::size_t > >
+remap( const std::map< int, std::vector< std::size_t > >& ids,
+       const std::unordered_map< std::size_t, std::size_t >& map )
+// *****************************************************************************
+//  Create remapped map of vector of indices using a map
+//! \param[in] ids Map of vector of integer IDs to create new container of ids
+//!   from
+//! \param[in] map Hash-map of key->value creating a new order
+//! \return Remapped vector of ids
+//! \details This function applies a mapping (reordering) to the map of integer
+//!   IDs passed in using the map passed in by applying remap(vector,map) on
+//!   each vector of ids. The keys in the returned map will be the same as in
+//!   ids.
+// *****************************************************************************
+{
+  Assert( !map.empty(), "Map must not be empty" );
+
+  // in terms of the in-place remap of a vector using a map
+  auto newids = ids;
+  for (auto& m : newids) remap( m.second, map );
+
+  return newids;
+}
+
+std::vector< std::size_t >
+renumber( const std::pair< std::vector< std::size_t >,
+                           std::vector< std::size_t > >& psup )
+// *****************************************************************************
+//  Reorder mesh points with the advancing front technique
+//! \param[in] psup Points surrounding points
+//! \return Mapping created by renumbering (reordering)
+// *****************************************************************************
+{
+  // Find out number of nodes in graph
+  auto npoin = psup.second.size()-1;
+
+  // Construct mapping using advancing front
+  std::vector< int > hpoin( npoin, -1 ), lpoin( npoin, 0 );
+  std::vector< std::size_t > map( npoin, 0 );
+  hpoin[0] = 0;
+  lpoin[0] = 1;
+  std::size_t num = 1;
+  while (num < npoin) {
+    std::size_t cnt = 0;
+    std::size_t i = 0;
+    std::vector< int > kpoin( npoin, -1 );
+    int p;
+    while ((p = hpoin[i]) != -1) {
+      ++i;
+      auto P = static_cast< std::size_t >( p );
+      for (auto j=psup.second[P]+1; j<=psup.second[P+1]; ++j) {
+        auto q = psup.first[j];
+        if (lpoin[q] != 1) {    // consider points not yet counted
+          map[q] = num++;
+          kpoin[cnt] = static_cast< int >( q ); // register point as counted
+          lpoin[q] = 1;                         // register the point as counted
+          ++cnt;
+        }
+      }
+    }
+    hpoin = kpoin;
+  }
+
+//   // Construct new->old id map
+//   std::size_t i = 0;
+//   std::vector< std::size_t > oldmap( npoin );
+//   for (auto n : map) oldmap[n] = i++;
+
+  // Return old->new and new->old maps
+  return map;
+}
+
+std::unordered_map< std::size_t, std::size_t >
+assignLid( const std::vector< std::size_t >& gid )
+// *****************************************************************************
+//  Assign local ids to global ids
+//! \param[in] gid Global ids
+//! \return Map associating global ids to local ids
+// *****************************************************************************
+{
+  std::unordered_map< std::size_t, std::size_t > lid;
+  std::size_t l = 0;
+  for (auto p : gid) lid[p] = l++;
+  return lid;
+}
+
+std::tuple< std::vector< std::size_t >,
+            std::vector< std::size_t >,
+            std::unordered_map< std::size_t, std::size_t > >
+global2local( const std::vector< std::size_t >& ginpoel )
+// *****************************************************************************
+//  Generate element connectivity of local node IDs from connectivity of global
+//  node IDs also returning the mapping between local to global IDs
+//! \param[in] ginpoel Element connectivity with global node IDs
+//! \return Tuple of (1) element connectivity with local node IDs, (2) the
+//!   vector of unique global node IDs (i.e., the mapping between local to
+//!   global node IDs), and (3) mapping between global to local node IDs.
+// *****************************************************************************
+{
+  // Make a copy of the element connectivity with global node ids
+  auto gid = ginpoel;
+
+  // Generate a vector that holds only the unique global mesh node ids
+  tk::unique( gid );
+
+  // Assign local node ids to global node ids
+  const auto lid = tk::assignLid( gid );
+
+  Assert( gid.size() == lid.size(), "Size mismatch" );
+
+  // Generate element connectivity using local node ids
+  std::vector< std::size_t > inpoel( ginpoel.size() );
+  std::size_t j = 0;
+  for (auto p : ginpoel) inpoel[ j++ ] = tk::cref_find( lid, p );
+
+  // Return element connectivty with local node IDs
+  return std::make_tuple( inpoel, gid, lid );
+}
+
+bool
+positiveJacobians( const std::vector< std::size_t >& inpoel,
+                   const std::array< std::vector< real >, 3 >& coord )
+// *****************************************************************************
+// Test for positivity of the Jacobian for all cells in mesh
+//! \param[in] inpoel Element connectivity (zero-based, i.e., local if parallel)
+//! \param[in] coord Node coordinates
+//! \return True if Jacobians of all mesh cells are positive
+// *****************************************************************************
+{
+  Assert( !inpoel.empty(), "Mesh connectivity empty" );
+  Assert( inpoel.size() % 4 == 0,
+          "Mesh connectivity size must be divisible by 4 " );
+  Assert( tk::uniquecopy(inpoel).size() == coord[0].size(), "Number of unique "
+          "nodes in mesh connectivity must equal the number of nodes to which "
+          "coordinates have been supplied" );
+  Assert( tk::uniquecopy(inpoel).size() == coord[1].size(), "Number of unique "
+          "nodes in mesh connectivity must equal the number of nodes to which "
+          "coordinates have been supplied" );
+  Assert( tk::uniquecopy(inpoel).size() == coord[2].size(), "Number of unique "
+          "nodes in mesh connectivity must equal the number of nodes to which "
+          "coordinates have been supplied" );
+  Assert( *std::minmax_element( begin(inpoel), end(inpoel) ).first == 0,
+          "node ids should start from zero" );
+
+  const auto& x = coord[0];
+  const auto& y = coord[1];
+  const auto& z = coord[2];
+
+  for (std::size_t e=0; e<inpoel.size()/4; ++e) {
+    const std::array< std::size_t, 4 > N{{ inpoel[e*4+0], inpoel[e*4+1],
+                                           inpoel[e*4+2], inpoel[e*4+3] }};
+    // compute element Jacobi determinant / (5/120) = element volume * 4
+    const std::array< tk::real, 3 >
+      ba{{ x[N[1]]-x[N[0]], y[N[1]]-y[N[0]], z[N[1]]-z[N[0]] }},
+      ca{{ x[N[2]]-x[N[0]], y[N[2]]-y[N[0]], z[N[2]]-z[N[0]] }},
+      da{{ x[N[3]]-x[N[0]], y[N[3]]-y[N[0]], z[N[3]]-z[N[0]] }};
+    if (tk::triple( ba, ca, da ) < 0) return false;
+ }
+
+ return true;
+}
+
+std::map< int, std::vector< std::size_t > >
+bfacenodes( const std::map< int, std::vector< std::size_t > >& bface,
+            const std::vector< std::size_t >& triinpoel )
+// *****************************************************************************
+// Generate nodes of side set faces
+//! \param[in] bface Boundary-faces mapped to side set ids
+//! \param[in] triinpoel Boundary-face connectivity
+//! \return Nodes of side set faces for each side set passed in
+// *****************************************************************************
+{
+  auto bfn = bface;
+
+  for (auto& [s,b] : bfn) {
+    std::vector< std::size_t > nodes;
+    for (auto f : b) {
+      nodes.push_back( triinpoel[f*3+0] );
+      nodes.push_back( triinpoel[f*3+1] );
+      nodes.push_back( triinpoel[f*3+2] );
+    }
+    tk::unique( nodes );
+    b = std::move( nodes );
+  }
+
+  return bfn;
+}
+
+} // tk::
 
diff --git a/Debug/cppcheck/3.html b/Debug/cppcheck/3.html index 4c62a1a73425..1b602d10f108 100644 --- a/Debug/cppcheck/3.html +++ b/Debug/cppcheck/3.html @@ -152,12 +152,12 @@
  1
@@ -278,125 +278,251 @@ 

Cppcheck report - [

// *****************************************************************************
+119
+120
+121
+122
+123
+124
+125
+126
+127
+128
+129
+130
+131
+132
+133
+134
+135
+136
+137
+138
+139
+140
+141
+142
+143
+144
+145
+146
+147
+148
+149
+150
+151
+152
+153
+154
+155
+156
+157
+158
+159
+160
+161
+162
+163
+164
+165
+166
+167
+168
+169
+170
+171
+172
+173
+174
+175
+176
+177
+178
+179
+180
+181
+182
// *****************************************************************************
 /*!
-  \file      src/Inciter/DiagReducer.cpp
+  \file      src/IO/Omega_h_MeshReader.cpp
   \copyright 2012-2015 J. Bakosi,
              2016-2018 Los Alamos National Security, LLC.,
              2019-2021 Triad National Security, LLC.
              All rights reserved. See the LICENSE file for details.
-  \brief     Custom Charm++ reducer for merging std::vectors across PEs
-  \details   Custom Charm++ reducer for merging std::vectors across PEs.
+  \brief     Omega_h mesh reader
+  \details   Omega_h mesh reader class definition.
 */
 // *****************************************************************************
 
-#include <stddef.h>
-#include <type_traits>
-#include <memory>
-
-#include "DiagReducer.hpp"
-#include "Diagnostics.hpp"
-#include "Exception.hpp"
-
-namespace inciter {
-
-std::pair< int, std::unique_ptr<char[]> >
-serialize( std::size_t meshid,
-           std::size_t ncomp,
-           const std::vector< std::vector< tk::real > >& d )
-// *****************************************************************************
-// Serialize std::vectors to raw memory stream
-//! \param[in] meshid Mesh ID
-//! \param[in] ncomp Number of scalar components being solved
-//! \param[in] d Diagnostics vector of vectors (of eq components)
-//! \return Pair of the length and the raw stream containing the serialized
-//!   vectors
-// *****************************************************************************
-{
-  // Prepare for serializing diagnostics to a raw binary stream, compute size
-  PUP::sizer sizer;
-  sizer | meshid;
-  sizer | ncomp;
-  sizer | const_cast< std::vector< std::vector< tk::real > >& >( d );
-
-  // Create raw character stream to store the serialized vectors
-  std::unique_ptr<char[]> flatData = std::make_unique<char[]>( sizer.size() );
-
-  // Serialize vector, each message will contain a vector
-  PUP::toMem packer( flatData.get() );
-  packer | meshid;
-  packer | ncomp;
-  packer | const_cast< std::vector< std::vector< tk::real > >& >( d );
-
-  // Return size of and raw stream
-  return { sizer.size(), std::move(flatData) };
-}
-
-CkReductionMsg*
-mergeDiag( int nmsg, CkReductionMsg **msgs )
-// *****************************************************************************
-// Charm++ custom reducer for merging diagnostics during reduction across PEs
-//! \param[in] nmsg Number of messages in msgs
-//! \param[in] msgs Charm++ reduction message containing the serialized
-//!   diagnostics
-//! \return Aggregated diagnostics built for further aggregation if needed
-// *****************************************************************************
-{
-  std::size_t meshid, ncomp;
-  std::vector< std::vector< tk::real > > v;
+#include "NoWarning/Omega_h_file.hpp"
+#include <Omega_h_library.hpp>
+
+#include "Macro.hpp"
+#include "Omega_h_MeshReader.hpp"
+#include "Reorder.hpp"
+
+using tk::Omega_h_MeshReader;
+
+void
+Omega_h_MeshReader::readMeshPart(
+  std::vector< std::size_t >& ginpoel,
+  std::vector< std::size_t >& inpoel,
+  [[maybe_unused]] std::vector< std::size_t >& triinp,
+  std::unordered_map< std::size_t, std::size_t >& lid,
+  tk::UnsMesh::Coords& coord,
+  std::unordered_map< std::size_t, std::set< std::size_t > >&,
+  int numpes,
+  [[maybe_unused]] int mype )
+// *****************************************************************************
+//  Read a part of the mesh (graph and coordinates) from Omega_h file
+//! \param[in,out] ginpoel Container to store element connectivity of this PE's
+//!   chunk of the mesh (global ids)
+//! \param[in,out] inpoel Container to store element connectivity with local
+//!   node IDs of this PE's mesh chunk
+//! \param[in,out] triinp Container to store triangle element connectivity
+//!   (if exists in file) with global node indices
+//! \param[in,out] lid Container to store global->local node IDs of elements of
+//!   this PE's mesh chunk
+//! \param[in,out] coord Container to store coordinates of mesh nodes of this
+//!   PE's mesh chunk
+//! \param[in] numpes Total number of PEs (default n = 1, for a single-CPU read)
+//! \param[in] mype This PE (default m = 0, for a single-CPU read)
+//! \note The last two integer arguments are unused. They are needed because
+//!   this function can be used via a polymorphic interface via a base class,
+//!   see tk::MeshReader, and other specialized mesh readers, e.g.,
+//!   tk::ExodusIIMeshReader, use these arguments. Here we require the Omega_h
+//!   input mesh to be pre-partitioned, with Omega_h's osh_part tool, into the
+//!   number of partitions that is equal to the number of PEs this fuinction is
+//!   called on in parallel.
+// *****************************************************************************
+{
+  Assert( mype < numpes, "Invalid input: PE id must be lower than NumPEs" );
+  Assert( ginpoel.empty() && inpoel.empty() && lid.empty() &&
+          coord[0].empty() && coord[1].empty() && coord[2].empty(),
+          "Containers to store mesh must be empty" );
+
+  #if defined(__clang__)
+    #pragma clang diagnostic push
+    #pragma clang diagnostic ignored "-Wold-style-cast"
+  #endif
+
+  // Create Omega_h library instance
+  auto lib = Omega_h::Library( nullptr, nullptr, MPI_COMM_WORLD );
 
-  // Create PUP deserializer based on message passed in
-  PUP::fromMem creator( msgs[0]->getData() );
-
-  // Deserialize vector from raw stream
-  creator | meshid;<--- Uninitialized variable: meshid
-  creator | ncomp;<--- Uninitialized variable: ncomp
-  creator | v;
-
-  for (int m=1; m<nmsg; ++m) {
-    // Unpack vector
-    std::size_t mid, nc;
-    std::vector< std::vector< tk::real > > w;
-    PUP::fromMem curCreator( msgs[m]->getData() );
-    curCreator | mid;<--- Uninitialized variable: mid
-    curCreator | nc;<--- Uninitialized variable: nc
-    curCreator | w;
-    // Aggregate diagnostics vector
-    meshid = mid;<--- Uninitialized variable: mid<--- Variable 'meshid' is assigned a value that is never used.
-    ncomp = nc;<--- Uninitialized variable: nc<--- Variable 'ncomp' is assigned a value that is never used.
-    Assert( v.size() == w.size(),
-            "Size mismatch during diagnostics aggregation" );
-    Assert( v.size() == inciter::NUMDIAG,
-            "Size mismatch during diagnostics aggregation" );
-    for (std::size_t i=0; i<v.size(); ++i)<--- Unsigned less than zero
-      Assert( v[i].size() == w[i].size(),
-              "Size mismatch during diagnostics aggregation" );
-    // Apply diagnostics aggregation policy
-    // Sum for L2 normal of the numerical solution for all scalar components
-    for (std::size_t i=0; i<v[L2SOL].size(); ++i) v[L2SOL][i] += w[L2SOL][i];
-    // Sum for the L2 norm of the numerical - analytical solution for all comps
-    for (std::size_t i=0; i<v[L2ERR].size(); ++i) v[L2ERR][i] += w[L2ERR][i];
-    // Sum for the L2 norm of the residual of all components
-    for (std::size_t i=0; i<v[L2RES].size(); ++i) v[L2RES][i] += w[L2RES][i];
-    // Max for the Linf norm of the numerical - analytical solution for all comp
-    for (std::size_t i=0; i<v[LINFERR].size(); ++i)
-      if (w[LINFERR][i] > v[LINFERR][i]) v[LINFERR][i] = w[LINFERR][i];
-    // Sum of the total energy over the entire domain
-    v[TOTALSOL][0] += w[TOTALSOL][0];
-    // Copy ITER, TIME, DT
-    for (std::size_t j=v.size()-3; j<v.size(); ++j)
-      for (std::size_t i=0; i<v[j].size(); ++i)
-        v[j][i] = w[j][i];
-  }
-
-  // Serialize concatenated diagnostics vector to raw stream
-  auto stream = serialize( meshid, ncomp, v );
-
-  // Forward serialized diagnostics
-  return CkReductionMsg::buildNew( stream.first, stream.second.get() );
-}
+  #if defined(__clang__)
+    #pragma clang diagnostic pop
+  #endif
+
+  // Find out how many partitions the Omega_h mesh was saved with
+  auto nparts = Omega_h::binary::read_nparts( m_filename, lib.world() );
+
+  if (numpes < nparts)
+    Throw( "The Omega_h mesh reader only supports NumPEs >= nparts, where "
+           "nparts is the number of partitions the mesh is partitioned into. "
+           "Also note that NumPEs must be a power of 2 if NumPEs > nparts." );
+
+  // Read mesh
+  auto mesh = Omega_h::binary::read( m_filename, &lib );
+
+  // Lambda to check if int is a power of two
+  auto isPowerOfTwo = []( int x ) { return (x != 0) && ((x & (x - 1)) == 0); };
+
+  if (nparts != numpes) {
+    if (!isPowerOfTwo(numpes))
+      Throw( "The Omega_h mesh reader only supports NumPEs of power of 2" );
+    else
+      mesh.balance();
+  }
+
+  // Extract connectivity from Omega_h's mesh object
+  auto ntets = mesh.nelems();
+  ginpoel.resize( static_cast< std::size_t >( ntets ) * 4 );
+  auto o_inpoel = mesh.ask_elem_verts();
+  auto o_gid = mesh.globals( Omega_h::VERT );
+  for (int i=0; i<ntets; ++i)
+    for (int j=0; j<4; ++j) {
+      auto I = static_cast< std::size_t >( i );
+      auto J = static_cast< std::size_t >( j );
+      ginpoel[ I*4+J ] = static_cast<std::size_t>( o_gid[ o_inpoel[i*4+j] ] );
+    }
+
+  // Extract node coordinates from Omega_h's mesh object
+  auto o_coord = mesh.coords();
+
+  // Extract number of vertices from Omega_h's mesh object
+  auto nnode = static_cast< std::size_t >( mesh.nverts() );
+
+  // Extract node coordinates from Omega_h's mesh object
+  auto& x = coord[0];
+  auto& y = coord[1];
+  auto& z = coord[2];
+  x.resize( nnode );
+  y.resize( nnode );
+  z.resize( nnode );
 
-} // inciter::
+  for (std::size_t I=0; I<nnode; ++I) {
+    auto i = static_cast< int >( I );
+    x[I] = o_coord[ i*3+0 ];
+    y[I] = o_coord[ i*3+1 ];
+    z[I] = o_coord[ i*3+2 ];
+  }
+
+  // Compute local data from global mesh connectivity
+  std::vector< std::size_t > gid;
+  std::tie( inpoel, gid, lid ) = tk::global2local( ginpoel );
+}
+
+
+std::vector< std::size_t >
+Omega_h_MeshReader::triinpoel(
+  [[maybe_unused]] std::map< int, std::vector< std::size_t > >& bface,<--- Parameter 'bface' can be declared with const
+  [[maybe_unused]] const std::map< int, std::vector< std::size_t > >& faces,
+  [[maybe_unused]] const std::vector< std::size_t >& ginpoel,
+  [[maybe_unused]] const std::vector< std::size_t >& triinp ) const
+// *****************************************************************************
+// ...
+//! \note Must be preceded by a call to readElemBlockIDs()
+// *****************************************************************************
+{
+  std::vector< std::size_t > bnd_triinpoel;
+  return bnd_triinpoel;
+}
+
+void
+Omega_h_MeshReader::readSidesetFaces(
+  [[maybe_unused]] std::map< int, std::vector< std::size_t > >& bface,<--- Parameter 'bface' can be declared with const
+  [[maybe_unused]] std::map< int, std::vector< std::size_t > >& faces )<--- Parameter 'faces' can be declared with const
+// *****************************************************************************
+//  Read side sets from Omega_h file
+//! \param[in,out] bface Elem ids of side sets to read into
+//! \param[in,out] faces Elem-relative face ids of tets of side sets
+// *****************************************************************************
+{
+}
+
+void
+Omega_h_MeshReader::readFaces(
+  [[maybe_unused]] std::vector< std::size_t >& conn )
+// *****************************************************************************
+//  Read face connectivity of a number of boundary faces from Omega_h file
+//! \param[in,out] conn Connectivity vector to push to
+//! \details This function reads in the total number of boundary faces,
+//!   also called triangle-elements, and their connectivity.
+// *****************************************************************************
+{
+}
+
+std::map< int, std::vector< std::size_t > >
+Omega_h_MeshReader::readSidesetNodes()
+// *****************************************************************************
+//  Read node list of all side sets from Omega_h file
+//! \return Node lists mapped to side set ids
+// *****************************************************************************
+{
+  // Node lists mapped to side set ids
+  std::map< int, std::vector< std::size_t > > side;
+
+  return side;
+}
 
diff --git a/Debug/cppcheck/31.html b/Debug/cppcheck/31.html index 68631083c5ec..eac6638b14d9 100644 --- a/Debug/cppcheck/31.html +++ b/Debug/cppcheck/31.html @@ -152,12 +152,12 @@
  1
@@ -479,368 +479,326 @@ 

Cppcheck report - [

// *****************************************************************************
+320
// *****************************************************************************
 /*!
-  \file      src/Main/Inciter.cpp
+  \file      src/Inciter/Scheme.hpp
   \copyright 2012-2015 J. Bakosi,
              2016-2018 Los Alamos National Security, LLC.,
              2019-2021 Triad National Security, LLC.
              All rights reserved. See the LICENSE file for details.
-  \brief     Inciter, computational shock hydrodynamics tool, Charm++ main
-    chare.
-  \details   Inciter, computational shock hydrodynamics tool, Charm++ main
-    chare. This file contains the definition of the Charm++ main chare,
-    equivalent to main() in Charm++-land.
-*/
-// *****************************************************************************
-
-#include <unordered_map>
-#include <vector>
-#include <iostream>
-
-#include "Types.hpp"
-#include "Init.hpp"
-#include "QuinoaConfig.hpp"
-#include "Timer.hpp"
-#include "Exception.hpp"
-#include "CGPDE.hpp"
-#include "DGPDE.hpp"
-#include "FVPDE.hpp"
-#include "PDEStack.hpp"
-#include "ProcessException.hpp"
-#include "InciterPrint.hpp"
-#include "InciterDriver.hpp"
-#include "Inciter/CmdLine/Parser.hpp"
-#include "Inciter/CmdLine/CmdLine.hpp"
-#include "Inciter/InputDeck/InputDeck.hpp"
-#include "ChareStateCollector.hpp"
-#include "LBSwitch.hpp"
-
-#include "NoWarning/inciter.decl.h"
-
-#if defined(__clang__)
-  #pragma clang diagnostic push
-  #pragma clang diagnostic ignored "-Wmissing-variable-declarations"
-#endif
-
-//! \brief Charm handle to the main proxy, facilitates call-back to finalize,
-//!    etc., must be in global scope, unique per executable
-CProxy_Main mainProxy;
-
-//! Chare state collector Charm++ chare group proxy
-tk::CProxy_ChareStateCollector stateProxy;
-
-//! Load balancer switch group proxy
-tk::CProxy_LBSwitch LBSwitchProxy;
-
-//! If true, call and stack traces are to be output with exceptions
-//! \note This is true by default so that the trace is always output between
-//!   program start and the Main ctor in which the user-input from command line
-//!   setting for this overrides this true setting.
-bool g_trace = true;
-
-#if defined(__clang__)
-  #pragma clang diagnostic pop
-#endif
-
-//! Inciter declarations and definitions
-namespace inciter {
-
-//! Global-scope data. Initialized by the main chare and distibuted to all PEs
-//! by the Charm++ runtime system. Though semantically not const, all these
-//! global data should be considered read-only. See also
-//! http://charm.cs.illinois.edu/manuals/html/charm++/manual.html. The data
-//! below is global-scope because they must be available to all PEs which could
-//! be on different machines.
-
-#if defined(__clang__)
-  #pragma clang diagnostic push
-  #pragma clang diagnostic ignored "-Wmissing-variable-declarations"
-#endif
-
-//! Defaults of input deck, facilitates detection what is set by user
-//! \details This object is in global scope, it contains the default of all
-//!   possible user input, and thus it is made available to all PEs for
-//!   convenience reasons. The runtime system distributes it to all PEs during
-//!   initialization. Once distributed, the object does not change.
-ctr::InputDeck g_inputdeck_defaults;
-//! Lua Input deck filled by LuaParser, containing all input data
-//! \details This object is in global scope, it contains all of user input, and
-//!   thus it is made available to all PEs for convenience reasons. The runtime
-//!   system distributes it to all PEs during initialization. Once distributed,
-//!   the object does not change.
-ctr::InputDeck g_inputdeck;
-//! Partial differential equations using continuous Galerkin selected by user
-//! \details This vector is in global scope, because it holds polymorphic
-//!   objects, and thus must be distributed to all PEs during initialization.
-//!   Once distributed by the runtime system, the objects do not change.
-std::vector< CGPDE > g_cgpde;
-//! Partial differential equations using discontinuous Galerkin selected by user
-//! \details This vector is in global scope, because it holds polymorphic
-//!   objects, and thus must be distributed to all PEs during initialization.
-//!   Once distributed by the runtime system, the objects do not change.
-std::vector< DGPDE > g_dgpde;
-//! Partial differential equations using finite volume selected by user
-//! \details This vector is in global scope, because it holds polymorphic
-//!   objects, and thus must be distributed to all PEs during initialization.
-//!   Once distributed by the runtime system, the objects do not change.
-std::vector< FVPDE > g_fvpde;
-
-#if defined(__clang__)
-  #pragma clang diagnostic pop
-#endif
-
-//! \brief Pack/Unpack selected partial differential equations using continuous
-//!   Galerkin discretization.
-//! \details This Pack/Unpack method (re-)creates the PDE factory since it needs
-//!   to (re-)bind function pointers on different processing elements. Therefore
-//!   we circumvent Charm's usual pack/unpack for this type, and thus sizing
-//!   does not make sense: sizing is a no-op. We could initialize the factory in
-//!   InciterDriver's constructor and let this function re-create the stack only
-//!   when unpacking, but that leads to repeating the same code twice: once in
-//!   InciterDriver's constructor, once here. Another option is to use this
-//!   pack/unpack routine to both initially create (when packing) and to
-//!   re-create (when unpacking) the factory, which eliminates the need for
-//!   pre-creating the object in InciterDriver's constructor and therefore
-//!   eliminates the repeated code. This explains the guard for sizing: the code
-//!   below is called for packing only (in serial) and packing and unpacking (in
-//!   parallel).
-inline
-void operator|( PUP::er& p, std::vector< CGPDE >& eqs ) {
-  try {
-    if (!p.isSizing()) eqs = PDEStack().selectedCG();
-  } catch (...) { tk::processExceptionCharm(); }
-}
-
-//! \brief Pack/Unpack selected partial differential equations using
-//!   discontinuous Galerkin discretization.
-//! \details This Pack/Unpack method (re-)creates the PDE factory since it needs
-//!   to (re-)bind function pointers on different processing elements. Therefore
-//!   we circumvent Charm's usual pack/unpack for this type, and thus sizing
-//!   does not make sense: sizing is a no-op. We could initialize the factory in
-//!   InciterDriver's constructor and let this function re-create the stack only
-//!   when unpacking, but that leads to repeating the same code twice: once in
-//!   InciterDriver's constructor, once here. Another option is to use this
-//!   pack/unpack routine to both initially create (when packing) and to
-//!   re-create (when unpacking) the factory, which eliminates the need for
-//!   pre-creating the object in InciterDriver's constructor and therefore
-//!   eliminates the repeated code. This explains the guard for sizing: the code
-//!   below is called for packing only (in serial) and packing and unpacking (in
-//!   parallel).
-inline
-void operator|( PUP::er& p, std::vector< DGPDE >& eqs ) {
-  try {
-    if (!p.isSizing()) eqs = PDEStack().selectedDG();
-  } catch (...) { tk::processExceptionCharm(); }
-}
-
-//! \brief Pack/Unpack selected partial differential equations using
-//!   finite volume discretization.
-//! \details This Pack/Unpack method (re-)creates the PDE factory since it needs
-//!   to (re-)bind function pointers on different processing elements. Therefore
-//!   we circumvent Charm's usual pack/unpack for this type, and thus sizing
-//!   does not make sense: sizing is a no-op. We could initialize the factory in
-//!   InciterDriver's constructor and let this function re-create the stack only
-//!   when unpacking, but that leads to repeating the same code twice: once in
-//!   InciterDriver's constructor, once here. Another option is to use this
-//!   pack/unpack routine to both initially create (when packing) and to
-//!   re-create (when unpacking) the factory, which eliminates the need for
-//!   pre-creating the object in InciterDriver's constructor and therefore
-//!   eliminates the repeated code. This explains the guard for sizing: the code
-//!   below is called for packing only (in serial) and packing and unpacking (in
-//!   parallel).
-inline
-void operator|( PUP::er& p, std::vector< FVPDE >& eqs ) {
-  try {
-    if (!p.isSizing()) eqs = PDEStack().selectedFV();
-  } catch (...) { tk::processExceptionCharm(); }
-}
-
-} // inciter::
-
-//! \brief Charm++ main chare for the shock hydrodynamics executable, inciter.
-//! \details In inciter the Charm++ runtime system is initialized only after the
-//!   mesh has been read in, partitioned, and the necessary data structures,
-//!   e.g., communication maps, have been generated. This delayed initialization
-//!   of the Charm++ runtime system is required since the mesh partitioning is
-//!   done by Zoltan, an MPI library. Note that this Charm++ main chare object
-//!   should not be in a namespace.
-// cppcheck-suppress noConstructor
-class Main : public CBase_Main {<--- Unmatched suppression: noConstructor
-
-  public:
-    //! \brief Constructor
-    //! \details Inciter's main chare constructor is the entry point of the
-    //!   Charm++ portion of inciter, called by the Charm++ runtime system. The
-    //!   constructor does basic initialization steps, prints out some useful
-    //!   information to screen (in verbose mode), and instantiates a driver.
-    //!   Since Charm++ is fully asynchronous, the constructor usually spawns
-    //!   asynchronous objects and immediately exits. Thus in the body of the
-    //!   main chare constructor we fire up an 'execute' chare, which then calls
-    //!   back to Main::execute(). Finishing the main chare constructor the
-    //!   Charm++ runtime system then starts the network-migration of all
-    //!   global-scope data (if any). The execute chare calling back to
-    //!   Main::execute() signals the end of the migration of the global-scope
-    //!   data. Then we are ready to execute the driver. Since inciter is
-    //!   parallel and asynchronous, its driver fires up additional Charm++
-    //!   chare objects which then call back to Main::finalize() at some point
-    //!   in the future when all work has been finished. finalize() then exits
-    //!   by calling Charm++'s CkExit(), shutting down the runtime system.
-    //! \see http://charm.cs.illinois.edu/manuals/html/charm++/manual.html
-    Main( CkArgMsg* msg )
-    try :
-      m_signal( tk::setSignalHandlers() ),
-      m_cmdline(),
-      // Parse command line into m_cmdline using default simple pretty printer
-      m_cmdParser( msg->argc, msg->argv, tk::Print(), m_cmdline ),
-      // Create Inciter driver
-      m_driver( tk::Main< inciter::InciterDriver >
-                        ( msg->argc, msg->argv,
-                          m_cmdline,
-                          tk::HeaderType::INCITER,
-                          tk::inciter_executable(),
-                          inciter::g_inputdeck_defaults.get< tag::cmd, tag::io,
-                            tag::screen >(),
-                          inciter::g_inputdeck_defaults.get< tag::cmd, tag::io,
-                            tag::nrestart >() ) ),
-      // Start new timer measuring the total runtime
-      m_timer(1),
-      m_timestamp()
-    {
-      delete msg;
-      g_trace = m_cmdline.get< tag::trace >();
-      tk::MainCtor( mainProxy, thisProxy, m_timer, m_cmdline,
-                    CkCallback( CkIndex_Main::quiescence(), thisProxy ) );
-      // If quiescence detection is on or user requested it, create chare state
-      // collector Charm++ chare group
-      if ( m_cmdline.get< tag::chare >() || m_cmdline.get< tag::quiescence >() )
-        stateProxy = tk::CProxy_ChareStateCollector::ckNew();
-      // Fire up an asynchronous execute object, which when created at some
-      // future point in time will call back to this->execute(). This is
-      // necessary so that this->execute() can access already migrated
-      // global-scope data.
-      CProxy_execute::ckNew();
-    } catch (...) { tk::processExceptionCharm(); }
+  \brief     Polymorphic glue for calling Charm++ entry methods to base class
+    Discretization, its children implementing specific discretization schemes,
+    and helper classes
+  \details
+    The purpose of this class is to hide, behind a single type, different
+    Charm++  proxy types that model a single concept, i.e., define some common
+    functions as Charm++ entry methods that can be used in either a broadcast
+    and/or in a way of addressing a single array element. As a result, member
+    functions can be invoked by client code without knowing the underlying type
+    or any specifics to the underlying differences of the classes that model the
+    same concept, i.e., expose the same member functions. The idea is very
+    similar to inheritance and runtime polymorphism with base classes and
+    virtual functions: some member functions and data are common to all types
+    modeled (and thus are not repeated and/or copied), while some are specific.
+    A difference is that the "base" and "child" classes are Charm++ proxies.
+    Note that while Charm++ does support inheritance and runtime polymorphism
+    with chare arrays, we still prefer the implementation below because it uses
+    entirely value semantics (inside and in client code) and thus it keeps the
+    complexity of the dispatch behind this class and does not expose it to
+    client code.
+
+    The advantages of this class over traditional runtime polymorphism are (1)
+    value semantics (both internally and to client code), (2) not templated,
+    and (3) PUPable, i.e., an instance of Scheme can be sent across the network
+    using Charm++'s pup framework. Also, since the class only holds a couple of
+    chare proxies, it is lightweight.
+
+    Example usage from client code:
+
+    \code{.cpp}
+      // Instantiate a Scheme object
+      Scheme s( ctr::SchemeType::DG );  // see Control/Inciter/Options/Scheme.h
+
+      // Issue broadcast to child scheme entry method
+      s.bcast< Scheme::setup >(...);
+
+      // Issue broadcast to base (Discretization) entry method
+      s.disc().totalvol();
+    \endcode
+
+    Organization, implementation details, end extension of the class:
+
+    Scheme contains (at least) two Charm++ proxies: discproxy and proxy. The
+    former contains data and functionality common to all discretizations, and
+    this can be considered as an equivalent to a base class in the OOP sense.
+    The latter, proxy, contains data and functionality specific to a particular
+    discretization. When instantiated, Scheme is configured for a single
+    specific discretization which must be selected from the list of types in
+    SchemeBase::Proxy.
+
+    The underlying type of proxy is a variant, which allows storing exactly one
+    object. A variant is a type-safe union. An instance of a variant at any
+    given time either holds a value of one of its alternative types. Read more
+    on std::variant on how they work.
+
+    Adding a new child scheme is done by
+    (1) Adding a new type of Charm++ chare array proxy to Scheme::Proxy,
+    (2) Adding a new type of Charm++ chare array element proxy to
+        Scheme::ProxyElem, and
+    (3) Adding a new branch to the if test in Scheme's constructor.
+
+  \see A talk on "Concept-based runtime polymorphism with Charm++ chare arrays
+    using value semantics given by J. Bakosi at the 16th Annual Workshop on
+    Charm++ and its Applications, April 2018, discussing an earlier, more
+    verbose implementation of the idea, using C++11.
+*/
+// *****************************************************************************
+#ifndef Scheme_h
+#define Scheme_h
+
+#include "Exception.hpp"
+#include "PUPUtil.hpp"
+#include "Inciter/Options/Scheme.hpp"
+
+#include "NoWarning/discretization.decl.h"
+#include "NoWarning/alecg.decl.h"
+#include "NoWarning/oversetfe.decl.h"
+#include "NoWarning/dg.decl.h"
+#include "NoWarning/fv.decl.h"
+#include "NoWarning/ale.decl.h"
+#include "NoWarning/conjugategradients.decl.h"
+#include "NoWarning/ghosts.decl.h"
+
+namespace inciter {
+
+//! Base class for generic forwarding interface to discretization proxies
+class Scheme {
+
+  private:
+    //! Variant type listing all chare proxy types modeling the same concept
+    using Proxy = std::variant< CProxy_DG
+                              , CProxy_ALECG
+                              , CProxy_OversetFE
+                              , CProxy_FV >;
+
+  public:
+    //! Variant type listing all chare element proxy types
+    using ProxyElem = std::variant< CProxy_DG::element_t
+                                  , CProxy_ALECG::element_t
+                                  , CProxy_OversetFE::element_t
+                                  , CProxy_FV::element_t >;
+
+    //! Empty constructor for Charm++
+    explicit Scheme() {}
+
+    //! Constructor
+    //! \param[in] scheme Discretization scheme
+    //! \param[in] ale True if enable ALE
+    //! \param[in] linearsolver True if enable a linear solver
+    //! \details Based on the input enum we create at least two empty chare
+    //!   arrays: (1) discproxy which contains common functionality and data for
+    //!   all discretizations, and (2) proxy, which have functionality and data
+    //!   specific to a given discretization. Note that proxy is bound (in
+    //!   migration behavior and properties) to discproxy.
+    //! \note There may be other bound proxy arrays created depending on the
+    //!   specific discretization configured by the enum.
+    explicit Scheme( ctr::SchemeType scheme,
+                     bool ale = false,
+                     bool linearsolver = false,
+                     tk::Centering centering = tk::Centering::NODE ) :
+      discproxy( CProxy_Discretization::ckNew() )
+    {
+      bound.bindTo( discproxy );
+      if (scheme == ctr::SchemeType::DG ||
+                 scheme == ctr::SchemeType::P0P1 ||
+                 scheme == ctr::SchemeType::DGP1 ||
+                 scheme == ctr::SchemeType::DGP2 ||
+                 scheme == ctr::SchemeType::PDG)
+      {
+        proxy = static_cast< CProxy_DG >( CProxy_DG::ckNew(bound) );
+      } else if (scheme == ctr::SchemeType::ALECG) {
+        proxy = static_cast< CProxy_ALECG >( CProxy_ALECG::ckNew(bound) );
+      } else if (scheme == ctr::SchemeType::OversetFE) {
+        proxy = static_cast< CProxy_OversetFE >( CProxy_OversetFE::ckNew(bound) );
+      } else if (scheme == ctr::SchemeType::FV) {
+        proxy = static_cast< CProxy_FV >( CProxy_FV::ckNew(bound) );
+      } else Throw( "Unknown discretization scheme" );
+      if (ale) aleproxy = CProxy_ALE::ckNew(bound);
+      if (linearsolver)
+        conjugategradientsproxy = tk::CProxy_ConjugateGradients::ckNew(bound);
+      if (centering == tk::Centering::ELEM)
+        ghostsproxy = CProxy_Ghosts::ckNew(bound);
+    }
+
+    //! Entry method tags for specific Scheme classes to use with bcast()
+    struct setup {};
+    struct box {};
+    struct transferSol {};
+    struct advance {};
+    struct resized {};
+    struct resizeComm {};
+    struct refine {};
+    struct lhs {};
+    struct nodeNeighSetup {};
+    struct diag {};
+    struct evalLB {};
+    struct doneInserting {};
+    //! Issue broadcast to Scheme entry method
+    //! \tparam Fn Function tag identifying the entry method to call
+    //! \tparam Args Types of arguments to pass to entry method
+    //! \param[in] args Arguments to member function entry method to be called
+    //! \details This function issues a broadcast to a member function entry
+    //!   method of the Scheme chare array (the child of Discretization) and is
+    //!   thus equivalent to proxy.Fn(...).
+    template< typename Fn, typename... Args >
+    void bcast( Args&&... args ) {
+      std::visit( [&]( auto& p ){<--- Parameter 'p' can be declared with const
+          if constexpr( std::is_same_v< Fn, setup > )
+            p.setup( std::forward< Args >( args )... );
+          if constexpr( std::is_same_v< Fn, box > )
+            p.box( std::forward< Args >( args )... );
+          else if constexpr( std::is_same_v< Fn, transferSol > )
+            p.transferSol( std::forward< Args >( args )... );
+          else if constexpr( std::is_same_v< Fn, advance > )
+            p.advance( std::forward< Args >( args )... );
+          else if constexpr( std::is_same_v< Fn, resized > )
+            p.resized( std::forward< Args >( args )... );
+          else if constexpr( std::is_same_v< Fn, resizeComm > )
+            p.resizeComm( std::forward< Args >( args )... );
+          else if constexpr( std::is_same_v< Fn, refine > )
+            p.refine( std::forward< Args >( args )... );
+          else if constexpr( std::is_same_v< Fn, lhs > )
+            p.lhs( std::forward< Args >( args )... );
+          else if constexpr( std::is_same_v< Fn, nodeNeighSetup > )
+            p.nodeNeighSetup( std::forward< Args >( args )... );
+          else if constexpr( std::is_same_v< Fn, diag > )
+            p.diag( std::forward< Args >( args )... );
+          else if constexpr( std::is_same_v< Fn, evalLB > )
+            p.evalLB( std::forward< Args >( args )... );
+          else if constexpr( std::is_same_v< Fn, doneInserting > )
+            p.doneInserting( std::forward< Args >( args )... );
+        }, proxy );
+    }
+
+    //! Function tags for specific Scheme classes to use with ckLocal()
+    struct resizePostAMR {};
+    struct extractFieldOutput {};
+    struct solution {};
+    //! Call Scheme function via Charm++ chare array element's ckLocal()
+    //! \tparam Fn Function tag identifying the function to call
+    //! \tparam Args Types of arguments to pass to function
+    //! \param[in] x Chare array element index
+    //! \param[in] args Arguments to member function function to be called
+    //! \details This function calls a member function via Charm++'s ckLocal()
+    //!    behind the element proxy configured, indexed by the array index x.
+    //!    Since the call is behind ckLocal(), the member function does not have
+    //!    to be a Charm++ entry method.
+    template< typename Fn, typename... Args >
+    auto ckLocal( const CkArrayIndex1D& x, Args&&... args ) const {
+      auto e = element( x );
+      return std::visit( [&]( auto& p ){
+          if constexpr( std::is_same_v< Fn, resizePostAMR > )
+            return p.ckLocal()->resizePostAMR( std::forward<Args>(args)... );
+          else if constexpr( std::is_same_v< Fn, extractFieldOutput > )
+            return p.ckLocal()->extractFieldOutput(std::forward<Args>(args)...);
+          else if constexpr( std::is_same_v< Fn, solution > )
+            return p.ckLocal()->solution( std::forward<Args>(args)... );
+        }, e );
+    }
+
+    //! Function to call the insert entry method of an element proxy
+    //! \param[in] x Chare array element index
+    //! \param[in] args Arguments to member function (entry method) to be called
+    //! \details This function calls the insert member function of a chare array
+    //!   element proxy and thus equivalent to proxy[x].insert(...), using the
+    //!   last argument as default.
+    template< typename... Args >
+    void insert( const CkArrayIndex1D& x, Args&&... args ) {
+      auto e = element( x );
+      std::visit( [&]( auto& p ){ p.insert(std::forward<Args>(args)...); }, e );<--- Parameter 'p' can be declared with const
+    }
+
+    //! Get reference to discretization proxy
+    //! \return Discretization Charm++ chare array proxy
+    CProxy_Discretization& disc() noexcept { return discproxy; }
 
-    //! Migrate constructor: returning from a checkpoint
-    explicit Main( CkMigrateMessage* msg ) : CBase_Main( msg ),
-      m_signal( tk::setSignalHandlers() ),
-      m_cmdline(),
-      m_cmdParser( reinterpret_cast<CkArgMsg*>(msg)->argc,
-                   reinterpret_cast<CkArgMsg*>(msg)->argv,
-                   tk::Print(),
-                   m_cmdline ),
-      m_driver( tk::Main< inciter::InciterDriver >
-                        ( reinterpret_cast<CkArgMsg*>(msg)->argc,
-                          reinterpret_cast<CkArgMsg*>(msg)->argv,
-                          m_cmdline,
-                          tk::HeaderType::INCITER,
-                          tk::inciter_executable(),
-                          inciter::g_inputdeck_defaults.get< tag::cmd,
-                            tag::io, tag::screen >(),
-                          inciter::g_inputdeck.get< tag::cmd,
-                            tag::io, tag::nrestart >()+1 ) ),
-      m_timer(1),
-      m_timestamp()
-    {
-      // increase number of restarts (available for Transporter on PE 0)
-      ++inciter::g_inputdeck.get< tag::cmd, tag::io, tag::nrestart >();
-      g_trace = m_cmdline.get< tag::trace >();
-      tk::MainCtor( mainProxy, thisProxy, m_timer, m_cmdline,
-                    CkCallback( CkIndex_Main::quiescence(), thisProxy ) );
-    }
-
-    //! Execute driver created and initialized by constructor
-    void execute() {
-      try {
-        m_timestamp.emplace_back("Migrate global-scope data", m_timer[1].hms());
-        m_driver.execute();
-      } catch (...) { tk::processExceptionCharm(); }
-    }
-
-    //! Towards normal exit but collect chare state first (if any)
-    void finalize() {
-      tk::finalize( m_cmdline, m_timer, stateProxy, m_timestamp,
-        inciter::g_inputdeck_defaults.get< tag::cmd, tag::io, tag::screen >(),
-        inciter::g_inputdeck.get< tag::cmd, tag::io, tag::nrestart >(),
-        CkCallback( CkIndex_Main::dumpstate(nullptr), thisProxy ) );
+    //! Get reference to ALE proxy
+    //! \return ALE Charm++ chare array proxy
+    CProxy_ALE& ale() noexcept { return aleproxy; }
+
+    //! Get reference to ConjugateGradients proxy
+    //! \return ConjugateGradients Charm++ chare array proxy
+    tk::CProxy_ConjugateGradients& conjugategradients() noexcept
+    { return conjugategradientsproxy; }
+
+    //! Get reference to Ghosts proxy
+    //! \return Ghosts Charm++ chare array proxy
+    CProxy_Ghosts& ghosts() noexcept { return ghostsproxy; }
+
+    //! Get reference to scheme proxy
+    //! Get reference to scheme proxy
+    //! \return Variant storing Charm++ chare array proxy configured
+    const Proxy& getProxy() noexcept { return proxy; }
+
+    //! Query underlying proxy type
+    //! \return Zero-based index into the set of types of Proxy
+    std::size_t index() const noexcept { return proxy.index(); }
+
+    //! Query underlying proxy element type
+    //! \return Zero-based index that can be used, e.g., indexing into the set
+    //!   of types of ProxyElem
+    std::size_t index_element() const noexcept { return element(0).index(); }
+
+    //! Charm++ array options accessor for binding external proxies
+    //! \return Charm++ array options object reference
+    const CkArrayOptions& arrayoptions() { return bound; }
+
+    /** @name Charm++ pack/unpack serializer member functions */
+    ///@{
+    //! \brief Pack/Unpack serialize member function
+    //! \param[in,out] p Charm++'s PUP::er serializer object reference
+    void pup( PUP::er &p ) {<--- Parameter 'p' can be declared with const
+      p | proxy;
+      p | discproxy;
+      p | aleproxy;
+      p | conjugategradientsproxy;
+      p | ghostsproxy;
+      p | bound;
     }
-
-    //! Entry method triggered when quiescence is detected
-    void quiescence() {
-      try {
-        stateProxy.collect( /* error= */ true,
-          CkCallback( CkIndex_Main::dumpstate(nullptr), thisProxy ) );
-      } catch (...) { tk::processExceptionCharm(); }
-    }
-
-    //! Dump chare state
-    void dumpstate( CkReductionMsg* msg ) {
-      tk::dumpstate( m_cmdline,
-        inciter::g_inputdeck_defaults.get< tag::cmd, tag::io, tag::screen >(),
-        inciter::g_inputdeck.get< tag::cmd, tag::io, tag::nrestart >(),
-        msg );
-    }
-
-    /** @name Charm++ pack/unpack serializer member functions */
-    ///@{
-    //! \brief Pack/Unpack serialize member function
-    //! \param[in,out] p Charm++'s PUP::er serializer object reference
-    //! \note This is a Charm++ mainchare, pup() is thus only for
-    //!    checkpoint/restart.
-    void pup( PUP::er &p ) override {
-      p | m_timer;
-    }
-    //! \brief Pack/Unpack serialize operator|
-    //! \param[in,out] p Charm++'s PUP::er serializer object reference
-    //! \param[in,out] m Mainchare object reference
-    friend void operator|( PUP::er& p, Main& m ) { m.pup(p); }
-    //@}
-
-  private:
-    int m_signal;                               //!< Used to set signal handlers
-    inciter::ctr::CmdLine m_cmdline;            //!< Command line
-    inciter::CmdLineParser m_cmdParser;         //!< Command line parser
-    inciter::InciterDriver m_driver;            //!< Driver
-    std::vector< tk::Timer > m_timer;           //!< Timers
-    //! Time stamps in h:m:s with labels
-    std::vector< std::pair< std::string, tk::Timer::Watch > > m_timestamp;
-};
-
-//! \brief Charm++ chare execute
-//! \details By the time this object is constructed, the Charm++ runtime system
-//!    has finished migrating all global-scoped read-only objects which happens
-//!    after the main chare constructor has finished.
-class execute : public CBase_execute {
-  public:
-    //! Constructor
-    execute() { mainProxy.execute(); }
-    //! Migrate constructor
-    explicit execute( CkMigrateMessage* m ) : CBase_execute( m ) {}
-};
-
-#include "NoWarning/inciter.def.h"
+    //! \brief Pack/Unpack serialize operator|
+    //! \param[in,out] p Charm++'s PUP::er serializer object reference
+    //! \param[in,out] s Scheme object reference
+    friend void operator|( PUP::er& p, Scheme& s ) { s.pup(p); }
+    //@}
+
+  private:
+    //! Variant storing one proxy to which this class is configured for
+    Proxy proxy;
+    //! Charm++ proxy to data and code common to all discretizations
+    CProxy_Discretization discproxy;
+    //! Charm++ proxy to ALE class
+    CProxy_ALE aleproxy;
+    //! Charm++ proxy to conjugate gradients linear solver class
+    tk::CProxy_ConjugateGradients conjugategradientsproxy;
+    //! Charm++ proxy to Ghosts class
+    CProxy_Ghosts ghostsproxy;
+    //! Charm++ array options for binding chares
+    CkArrayOptions bound;
+
+    //! Function dereferencing operator[] of chare proxy inside variant
+    //! \param[in] x Chare array element index
+    //! \return Chare array element proxy as a variant, defined by ProxyElem
+    //! \details The returning element proxy is a variant, depending on the
+    //!   input proxy.
+    ProxyElem element( const CkArrayIndex1D& x ) const {
+      return std::visit( [&]( const auto& p ){
+               return static_cast< ProxyElem >( p[x] ); }, proxy );
+    }
+};
+
+} // inciter::
+
+#endif // Scheme_h
 
diff --git a/Debug/cppcheck/33.html b/Debug/cppcheck/33.html index 2e33da2b6b09..d1e2514d905c 100644 --- a/Debug/cppcheck/33.html +++ b/Debug/cppcheck/33.html @@ -152,12 +152,12 @@
  1
@@ -350,197 +350,1061 @@ 

Cppcheck report - [

// *****************************************************************************
+191
+192
+193
+194
+195
+196
+197
+198
+199
+200
+201
+202
+203
+204
+205
+206
+207
+208
+209
+210
+211
+212
+213
+214
+215
+216
+217
+218
+219
+220
+221
+222
+223
+224
+225
+226
+227
+228
+229
+230
+231
+232
+233
+234
+235
+236
+237
+238
+239
+240
+241
+242
+243
+244
+245
+246
+247
+248
+249
+250
+251
+252
+253
+254
+255
+256
+257
+258
+259
+260
+261
+262
+263
+264
+265
+266
+267
+268
+269
+270
+271
+272
+273
+274
+275
+276
+277
+278
+279
+280
+281
+282
+283
+284
+285
+286
+287
+288
+289
+290
+291
+292
+293
+294
+295
+296
+297
+298
+299
+300
+301
+302
+303
+304
+305
+306
+307
+308
+309
+310
+311
+312
+313
+314
+315
+316
+317
+318
+319
+320
+321
+322
+323
+324
+325
+326
+327
+328
+329
+330
+331
+332
+333
+334
+335
+336
+337
+338
+339
+340
+341
+342
+343
+344
+345
+346
+347
+348
+349
+350
+351
+352
+353
+354
+355
+356
+357
+358
+359
+360
+361
+362
+363
+364
+365
+366
+367
+368
+369
+370
+371
+372
+373
+374
+375
+376
+377
+378
+379
+380
+381
+382
+383
+384
+385
+386
+387
+388
+389
+390
+391
+392
+393
+394
+395
+396
+397
+398
+399
+400
+401
+402
+403
+404
+405
+406
+407
+408
+409
+410
+411
+412
+413
+414
+415
+416
+417
+418
+419
+420
+421
+422
+423
+424
+425
+426
+427
+428
+429
+430
+431
+432
+433
+434
+435
+436
+437
+438
+439
+440
+441
+442
+443
+444
+445
+446
+447
+448
+449
+450
+451
+452
+453
+454
+455
+456
+457
+458
+459
+460
+461
+462
+463
+464
+465
+466
+467
+468
+469
+470
+471
+472
+473
+474
+475
+476
+477
+478
+479
+480
+481
+482
+483
+484
+485
+486
+487
+488
+489
+490
+491
+492
+493
+494
+495
+496
+497
+498
+499
+500
+501
+502
+503
+504
+505
+506
+507
+508
+509
+510
+511
+512
+513
+514
+515
+516
+517
+518
+519
+520
+521
+522
+523
+524
+525
+526
+527
+528
+529
+530
+531
+532
+533
+534
+535
+536
+537
+538
+539
+540
+541
+542
+543
+544
+545
+546
+547
+548
+549
+550
+551
+552
+553
+554
+555
+556
+557
+558
+559
+560
+561
+562
+563
+564
+565
+566
+567
+568
+569
+570
+571
+572
+573
+574
+575
+576
+577
+578
+579
+580
+581
+582
+583
+584
+585
+586
+587
+588
+589
+590
+591
+592
+593
+594
+595
+596
+597
+598
+599
+600
+601
+602
+603
+604
+605
+606
+607
+608
+609
+610
+611
+612
+613
+614
+615
+616
+617
+618
+619
+620
+621
+622
+623
// *****************************************************************************
 /*!
-  \file      src/Control/Inciter/InputDeck/LuaParser.hpp
-  \copyright 2019-2023 Triad National Security, LLC.
-             All rights reserved. See the LICENSE file for details.
-  \brief     Inciter's lua input deck file parser
-  \details   This file declares the input deck, i.e., control file, parser for
-    the computational shock hydrodynamics tool, Inciter.
-*/
-// *****************************************************************************
-#ifndef InciterLuaParser_h
-#define InciterLuaParser_h
-
-#include "NoWarning/sol.hpp"
+  \file      src/Inciter/Sorter.cpp
+  \copyright 2012-2015 J. Bakosi,
+             2016-2018 Los Alamos National Security, LLC.,
+             2019-2021 Triad National Security, LLC.
+             All rights reserved. See the LICENSE file for details.
+  \brief     Mesh sorter for global distributed mesh reordering
+  \see       Sorter.h for more info.
+*/
+// *****************************************************************************
+
+#include <vector>
+#include <algorithm>
 
-#include "Inciter/CmdLine/CmdLine.hpp"
-#include "InputDeck.hpp"
-
-namespace tk { class Print; }
+#include "Sorter.hpp"
+#include "Reorder.hpp"
+#include "DerivedData.hpp"
+#include "Inciter/InputDeck/InputDeck.hpp"
 
 namespace inciter {
 
-//! \brief Control file lua-parser for Inciter.
-//! \details This class is used to interface with sol2, for the purpose of
-//!   parsing the control file for the computational shock hydrodynamics tool,
-//!   Inciter.
-class LuaParser {
+extern ctr::InputDeck g_inputdeck;
+
+} // inciter::
+
+using inciter::Sorter;
 
-  public:
-    //! Constructor
-    explicit LuaParser( const tk::Print& print,
-                              const ctr::CmdLine& cmdline,
-                              ctr::InputDeck& inputdeck );
-
-    //! Store lua inputdeck in custom struct
-    void storeInputDeck(
-      const sol::table& lua_ideck,
-      ctr::InputDeck& gideck );
-
-    //! Check and store material property into inpudeck storage
-    void checkStoreMatProp(
-      const sol::table table,
-      const std::string key,
-      std::size_t vecsize,
-      std::vector< tk::real >& storage );
-
-    //! Check and store field output variables
-    void addOutVar(
-      const std::string& varname,
-      const std::string& alias,
-      std::vector< char >& depv,
-      std::size_t nmat,
-      inciter::ctr::PDEType pde,
-      tk::Centering c,
-      std::vector< inciter::ctr::OutVar >& foutvar );
-
-  private:
-    const std::string m_filename;             //!< Name of file to parse
-
-    //! Assign parameter to inputdeck entry if specified, else default
-    //! \tparam N Type of parameter being read/assigned
-    //! \param[in] table Sol-table which contains said parameter
-    //! \param[in] key Key for said parameter in Sol-table
-    //! \param[in,out] storage Storage space in inputdeck where said parameter
-    //!   is to be stored
-    //! \param[in] dflt Default value of said parameter, if unspecified
-    template< typename N > void
-    storeIfSpecd(
-      const sol::table table,
-      const std::string key,
-      N& storage,
-      const N dflt )
-    {
-      auto sol_var = table[key];
-      if (sol_var.valid())
-        storage = sol_var;
-      else
-        storage = dflt;
-    }
-
-    //! Assign Option to inputdeck entry if specified, else default
-    //! \tparam Op Option-Type of parameter being read/assigned
-    //! \tparam OpClass Option-class of parameter being read/assigned
-    //! \param[in] table Sol-table which contains said parameter
-    //! \param[in] key Key for said parameter in Sol-table
-    //! \param[in,out] storage Storage space in inputdeck where said parameter
-    //!   is to be stored
-    //! \param[in] dflt Default value of said parameter, if unspecified
-    template< typename Op, class OpClass > void
-    storeOptIfSpecd(
-      const sol::table table,
-      const std::string key,
-      Op& storage,
-      const Op dflt )
-    {
-      OpClass opt;
-      auto sol_var = table[key];
-      if (sol_var.valid())
-        storage = opt.value(sol_var);
-      else
-        storage = dflt;
-    }
-
-    //! Assign vector parameter to inputdeck entry if specified, else default
-    //! \tparam N Type of parameter vector being read/assigned
-    //! \param[in] table Sol-table which contains said parameter
-    //! \param[in] key Key for said parameter in Sol-table
-    //! \param[in,out] storage Storage space in inputdeck where said parameter
-    //!   is to be stored
-    //! \param[in] dflt Default value of said parameter, if unspecified
-    template< typename N > void
-    storeVecIfSpecd(
-      const sol::table table,
-      const std::string key,
-      std::vector< N >& storage,
-      const std::vector< N >& dflt )
-    {
-      auto sol_vec = table[key];
-      if (sol_vec.valid()) {
-        for (std::size_t i=0; i<sol::table(sol_vec).size(); ++i)
-          storage.push_back(sol_vec[i+1]);
-      }
-      else
-        storage = dflt;
-    }
+Sorter::Sorter( std::size_t meshid,
+                const CProxy_Transporter& transporter,
+                const tk::CProxy_MeshWriter& meshwriter,
+                const tk::SorterCallback& cbs,
+                const std::vector< Scheme >& scheme,
+                CkCallback reorderRefiner,
+                const std::vector< std::size_t >& ginpoel,
+                const tk::UnsMesh::CoordMap& coordmap,
+                const tk::UnsMesh::Chunk& el,
+                const std::map< int, std::vector< std::size_t > >& bface,
+                const std::vector< std::size_t >& triinpoel,
+                const std::map< int, std::vector< std::size_t > >& bnode,
+                const std::unordered_map< std::size_t, std::set< std::size_t > >&
+                  elemblockid,
+                int nchare ) :
+  m_meshid( meshid ),
+  m_host( transporter ),
+  m_meshwriter( meshwriter ),
+  m_cbs( cbs ),
+  m_scheme( scheme ),
+  m_reorderRefiner( reorderRefiner ),
+  m_ginpoel( ginpoel ),
+  m_coordmap( coordmap ),
+  m_el( el ),
+  m_nbnd( 0 ),
+  m_bface( bface ),
+  m_triinpoel( triinpoel ),
+  m_bnode( bnode ),
+  m_elemblockid( elemblockid ),
+  m_nchare( nchare ),
+  m_nodeset( begin(ginpoel), end(ginpoel) ),
+  m_noffset( 0 ),
+  m_nodech(),
+  m_chnode(),
+  m_edgech(),
+  m_chedge(),
+  m_msum(),
+  m_reordcomm(),
+  m_start( 0 ),
+  m_newnodes(),
+  m_newcoordmap(),
+  m_reqnodes(),
+  m_lower( 0 ),
+  m_upper( 0 )
+// *****************************************************************************
+//  Constructor: prepare owned mesh node IDs for reordering
+//! \param[in] meshid Mesh ID
+//! \param[in] transporter Transporter (host) Charm++ proxy
+//! \param[in] meshwriter Mesh writer Charm++ proxy
+//! \param[in] cbs Charm++ callbacks for Sorter
+//! \param[in] scheme Discretization schemes (one per mesh)
+//! \param[in] reorderRefiner Callback to use to send reordered mesh to Refiner
+//! \param[in] ginpoel Mesh connectivity (this chare) using global node IDs
+//! \param[in] coordmap Mesh node coordinates (this chare) for global node IDs
+//! \param[in] bface Face lists mapped to side set ids
+//! \param[in] triinpoel Interconnectivity of points and boundary-faces
+//! \param[in] bnode Node ids mapped to side set ids
+//! \param[in] elemblockid Local tet ids associated to mesh block ids
+//! \param[in] nchare Total number of Charm++ worker chares
+// *****************************************************************************
+{
+  // Ensure boundary face ids will not index out of face connectivity
+  Assert( std::all_of( begin(m_bface), end(m_bface),
+            [&](const auto& s)
+            { return std::all_of( begin(s.second), end(s.second),
+                       [&](auto f){ return f*3+2 < m_triinpoel.size(); } ); } ),
+          "Boundary face data structures inconsistent" );
+}
+
+void
+Sorter::setup( std::size_t npoin )
+// *****************************************************************************
+// Setup chare mesh boundary node communication map
+//! \param[in] npoin Total number of mesh points in mesh. Note that the number
+//!   of mesh points does not have to be exactly the total number of points in
+//!   the mesh. It can be a larger number, but not less. This is only used here
+//!   to assign nodes to workers that will assign ids to mesh nodes during node
+//!   reordering.
+// *****************************************************************************
+{
+  // Compute the number of nodes (chunksize) a chare will build a node
+  // communication map for. We compute two values of chunksize: one for when
+  // the global node ids are abounded between [0...npoin-1], inclusive, and
+  // another one for when the global node ids are assigned by a hash algorithm
+  // during initial mesh refinement. In the latter case, the maximum
+  // representable value of a std::size_t is assumed to be the large global node
+  // id and is used to compute the chunksize. To compute the bin id, we attempt
+  // to use the first chunksize first: if it gives a chare id that is
+  // (strictly) lower than the number of chares, that's good. If not, we compute
+  // the bin id based on the second chunksize, which almost always will give a
+  // bin id strictly lower than the number of chares, except if the global node
+  // id assigned by the hash algorithm in Refiner hits the maximum
+  // representable number in std::size_t. If that is the case, we just assign
+  // that node to the last chare.
+  auto N = static_cast< std::size_t >( m_nchare );
+  std::array< std::size_t, 2 > chunksize{{
+     npoin / N, std::numeric_limits< std::size_t >::max() / N }};
 
-    //! Assign vector of Options to inputdeck entry if specified, else default
-    //! \tparam Op Option-Type of parameter being read/assigned
-    //! \tparam OpClass Option-class of parameter being read/assigned
-    //! \param[in] table Sol-table which contains said parameter
-    //! \param[in] key Key for said parameter in Sol-table
-    //! \param[in,out] storage Storage space in inputdeck where said parameter
-    //!   is to be stored
-    //! \param[in] dflt Default value of said parameter, if unspecified
-    template< typename Op, class OpClass > void
-    storeOptVecIfSpecd(
-      const sol::table table,
-      const std::string key,
-      std::vector< Op >& storage,
-      const std::vector< Op >& dflt )
-    {
-      OpClass opt;
-      auto sol_vec = table[key];
-      if (sol_vec.valid()) {
-        for (std::size_t i=0; i<sol::table(sol_vec).size(); ++i)
-          storage.push_back(opt.value(sol_vec[i+1]));
-      }
-      else
-        storage = dflt;
-    }
-
-    //! \brief Check validity of keywords within a particular block
-    //! \tparam tags Tags addressing the said block in the input deck
-    //! \param[in] block Sol table of the input deck block read in from the
-    //!   lua file
-    //! \param[in] blk_name Name of the block, for error clarity
-    template< typename... tags >
-    void checkBlock(const sol::table& block, const std::string& blk_name) const
-    {
-      for (const auto& kvp : block) {
-        bool is_valid(false);
-        auto ukw = kvp.first.as<std::string>();
-        brigand::for_each< tags... >( checkKw(ukw, is_valid) );
-        if (!is_valid)
-          Throw("Invalid keyword '" + ukw + "' in '" + blk_name + "' block.");
-      }
-    }
-
-    // Check if a keyword matches the existing ones
-    struct checkKw {
-      std::string user_kw;
-      // reference to bool keeping track of kw-match
-      bool& is_valid;
-      // Constructor
-      checkKw( const std::string& ukw, bool& isv ) :
-        user_kw(ukw), is_valid(isv) {}
-      //! Function to call for each keyword type
-      template< typename U > void operator()( brigand::type_<U> ) {
-        auto spec_key = U::name();
-        // only check if not previously matched
-        if (!is_valid) {
-          if (user_kw == spec_key) is_valid = true;
-          else is_valid = false;
-        }
-      }
-    };
-};
-
-} // namespace inciter
-
-#endif // InciterLuaParser_h
+  const auto scheme = g_inputdeck.get< tag::scheme >();<--- Variable 'scheme' is assigned a value that is never used.
+
+  // Find chare-boundary nodes and edges of our mesh chunk. This algorithm
+  // collects the global mesh node ids and edges on the chare boundary. A node
+  // is on a chare boundary if it belongs to a face of a tetrahedron that has
+  // no neighbor tet at a face. The edge is on the chare boundary if its first
+  // edge-end point is on a chare boundary. The nodes are categorized to bins
+  // that will be sent to different chares to build point-to-point
+  // communication maps across all chares. The binning is determined by the
+  // global node id divided by the chunksizes. See discussion above on how we
+  // use two chunksizes for global node ids assigned by the hash algorithm in
+  // Refiner (if initial mesh refinement has been done).
+  tk::CommMaps chbnd;
+  auto el = tk::global2local( m_ginpoel );      // generate local mesh data
+  const auto& inpoel = std::get< 0 >( el );     // local connectivity
+  auto esup = tk::genEsup( inpoel, 4 );         // elements surrounding points
+  auto esuel = tk::genEsuelTet( inpoel, esup ); // elems surrounding elements
+  for (std::size_t e=0; e<esuel.size()/4; ++e) {
+    auto mark = e*4;
+    for (std::size_t f=0; f<4; ++f)
+      if (esuel[mark+f] == -1)
+        for (std::size_t n=0; n<3; ++n) {
+          auto g = m_ginpoel[ mark+tk::lpofa[f][n] ];
+          auto bin = g / chunksize[0];
+          if (bin >= N) bin = g / chunksize[1];
+          if (bin >= N) bin = N - 1;
+          Assert( bin < N, "Will index out of number of chares" );
+          auto& b = chbnd[ static_cast< int >( bin ) ];
+          b.get< tag::node >().insert( g );
+          if (scheme == ctr::SchemeType::ALECG ||
+            scheme == ctr::SchemeType::OversetFE) {
+            auto h = m_ginpoel[ mark + tk::lpofa[ f ][ tk::lpoet[n][1] ] ];
+            b.get< tag::edge >().insert( { std::min(g,h), std::max(g,h) } );
+          }
+        }
+  }
+
+  // Send boundary data in bins to chares that will compute communication maps
+  // for the data in the bin. These bins form a distributed table.  Note that
+  // we only send data to those chares that have data to work on. The receiving
+  // sides do not know in advance if they receive messages or not.  Completion
+  // is detected by having the receiver respond back and counting the responses
+  // on the sender side, i.e., this chare.
+  m_nbnd = chbnd.size();
+  if (m_nbnd == 0)
+    contribute( sizeof(std::size_t), &m_meshid, CkReduction::nop,
+                m_cbs.get< tag::queried >() );
+  else
+    for (const auto& [ targetchare, bnd ] : chbnd)
+      thisProxy[ targetchare ].query( thisIndex, bnd );
+}
+
+void
+Sorter::query( int fromch, const tk::AllCommMaps& bnd )
+// *****************************************************************************
+// Incoming query for a list of mesh nodes for which this chare compiles node
+// communication maps
+//! \param[in] fromch Sender chare ID
+//! \param[in] bnd Chare-boundary data from another chare
+// *****************************************************************************
+{
+  // Store incoming nodes in node->chare and its inverse, chare->node, maps
+  const auto& nodes = bnd.get< tag::node >();
+  for (auto n : nodes) m_nodech[ n ].push_back( fromch );
+  m_chnode[ fromch ].insert( begin(nodes), end(nodes) );
+
+  // Store incoming edges in edge->chare and its inverse, chare->edge, maps
+  const auto& edges = bnd.get< tag::edge >();
+  for (const auto& e : edges) m_edgech[ e ].push_back( fromch );
+  m_chedge[ fromch ].insert( begin(edges), end(edges) );
+
+  // Report back to chare message received from
+  thisProxy[ fromch ].recvquery();
+}
+
+void
+Sorter::recvquery()
+// *****************************************************************************
+// Receive receipt of boundary node lists to query
+// *****************************************************************************
+{
+  if (--m_nbnd == 0)
+    contribute( sizeof(std::size_t), &m_meshid, CkReduction::nop,
+                m_cbs.get< tag::queried >() );
+}
+
+void
+Sorter::response()
+// *****************************************************************************
+//  Respond to boundary node list queries
+// *****************************************************************************
+{
+  std::unordered_map< int, tk::CommMaps > exp;
+
+  // Compute node communication map to be sent back to chares
+  for (const auto& [ neighborchare, bndnodes ] : m_chnode) {
+    auto& nc = exp[ neighborchare ];
+    for (auto n : bndnodes)
+      for (auto d : tk::cref_find(m_nodech,n))
+        if (d != neighborchare)
+          nc[d].get< tag::node >().insert( n );
+  }
+
+  // Compute edge communication map to be sent back to chares
+  for (const auto& [ neighborchare, bndedges ] : m_chedge) {
+    auto& ec = exp[ neighborchare ];
+    for (const auto& e : bndedges)
+      for (auto d : tk::cref_find(m_edgech,e))
+        if (d != neighborchare)
+          ec[d].get< tag::edge >().insert( e );
+  }
+
+  // Send communication maps to chares that issued a query to us. Communication
+  // maps were computed above for those chares that queried this map from us.
+  // This data form a distributed table and we only work on a chunk of it. Note
+  // that we only send data back to those chares that have queried us. The
+  // receiving sides do not know in advance if the receive messages or not.
+  // Completion is detected by having the receiver respond back and counting
+  // the responses on the sender side, i.e., this chare.
+  m_nbnd = exp.size();
+  if (m_nbnd == 0)
+    contribute( sizeof(std::size_t), &m_meshid, CkReduction::nop,
+                m_cbs.get< tag::responded >() );
+  else
+    for (const auto& [ targetchare, maps ] : exp)
+      thisProxy[ targetchare ].bnd( thisIndex, maps );
+}
+
+void
+Sorter::bnd( int fromch, const tk::CommMaps& msum )
+// *****************************************************************************
+// Receive boundary node communication maps for our mesh chunk
+//! \param[in] fromch Sender chare ID
+//! \param[in] msum Communication map(s) assembled by chare fromch
+// *****************************************************************************
+{
+  for (const auto& [ neighborchare, maps ] : msum) {
+    auto& m = m_msum[ neighborchare ];
+    const auto& nodemap = maps.get< tag::node >();
+    m.get< tag::node >().insert( begin(nodemap), end(nodemap) );
+    const auto& edgemap = maps.get< tag::edge >();
+    m.get< tag::edge >().insert( begin(edgemap), end(edgemap) );
+  }
+
+  // Report back to chare message received from
+  thisProxy[ fromch ].recvbnd();
+}
+
+void
+Sorter::recvbnd()
+// *****************************************************************************
+// Receive receipt of boundary node communication map
+// *****************************************************************************
+{
+  if (--m_nbnd == 0)
+    contribute( sizeof(std::size_t), &m_meshid, CkReduction::nop,
+                m_cbs.get< tag::responded >() );
+}
+
+void
+Sorter::start()
+// *****************************************************************************
+//  Start reordering (if enabled)
+// *****************************************************************************
+{
+  // Keep only those edges in edge comm map whose both end-points are in the
+  // node comm map
+  for (auto& [ neighborchare, maps ] : m_msum) {
+    const auto& nodes = maps.get< tag::node >();
+    tk::EdgeSet edges;
+    for (const auto& e : maps.get< tag::edge >())
+      if (nodes.find(e[0]) != end(nodes) && nodes.find(e[1]) != end(nodes))
+        edges.insert( e );
+    maps.get< tag::edge >() = std::move(edges);
+  }
+
+  if (g_inputdeck.get< tag::cmd, tag::feedback >()) m_host.chcomm();
+
+  tk::destroy( m_nodech );
+  tk::destroy( m_chnode );
+
+  if (g_inputdeck.get< tag::pelocal_reorder >())
+    mask();   // continue with mesh node reordering if requested (or required)
+  else
+    createDiscWorkers();  // skip mesh node reordering
+}
+
+void
+Sorter::mask()
+// *****************************************************************************
+//  Start preparing for mesh node reordering in parallel
+// *****************************************************************************
+{
+  // Compute asymmetric communcation map that will be used for reordering. This
+  // communication map is asymmetric because it associates global mesh node IDs
+  // to chares only with lower IDs than thisIndex. That is because this chare
+  // will need to receive new (reorderd) node IDs only from chares with lower
+  // IDs than thisIndex during node reordering. Since it only stores data for
+  // lower chare IDs, it is asymmetric. Note that because of this algorithm the
+  // type of m_msum is an ordered map, because of the std::none_of() algorithm
+  // needs to look at ALL chares this chare potentially communicates nodes with
+  // that have lower chare IDs that thisIndex. Since the map is ordered, it can
+  // walk through from the beginning of m_msum until the outer loop variable c,
+  // which is the chare ID the outer loop works on in a given cycle.
+  for (auto c=m_msum.cbegin(); c!=m_msum.cend(); ++c)
+    if (thisIndex > c->first) {
+      auto& n = m_reordcomm[ c->first ];
+      for (auto j : c->second.get< tag::node >())
+        if (std::none_of( m_msum.cbegin(), c,
+             [j]( const auto& s ) {
+               const auto& nodemap = s.second.template get< tag::node >();
+               return nodemap.find(j) != end(nodemap); } ))
+        {
+          n.insert(j);
+        }
+      if (n.empty()) m_reordcomm.erase( c->first );
+    }
+
+  // Count up total number of nodes this chare will need to receive
+  auto nrecv = tk::sumvalsize( m_reordcomm );
+
+  if ( g_inputdeck.get< tag::cmd, tag::feedback >() ) m_host.chmask();
+
+  // Compute number of mesh node IDs we will assign IDs to
+  auto nuniq = m_nodeset.size() - nrecv;
+
+  // Start computing offsets for node reordering
+  thisProxy.offset( thisIndex, nuniq );
+}
+
+void
+Sorter::offset( int c, std::size_t u )
+// *****************************************************************************
+//  Receive number of uniquely assigned global mesh node IDs from chares with
+//  lower IDs than thisIndex
+//! \param[in] c Chare ID
+//! \param[in] u Number of mesh node IDs chare c will assign IDs to
+//! \details This function computes the offset each chare will need to start
+//!   assigning its new node IDs from. The offset for a chare is the
+//!   offset for the previous chare plus the number of node IDs the previous
+//!   chare (uniquely) assigns new IDs for minus the number of node IDs the
+//!   previous chare receives from others (lower chares). This is computed here
+//!   in a parallel/distributed fashion by each chare sending its number of node
+//!   IDs (that it uniquely assigns) to all chares. Note that each chare would
+//!   only need to send this information to chares with higher IDs, but instead
+//!   this function is called in a broadcast fashion, because that is more
+//!   efficient than individual calls to only chares with higher IDs. Therefore
+//!   when computing the offsets, we only count the lower chares. When this is
+//!   done, we have the precise asymmetric communication map as well as the
+//!   start offset on all chares and so we can start the distributed global mesh
+//!   node ID reordering.
+// *****************************************************************************
+{
+  if (c < thisIndex) m_start += u;
+  if (++m_noffset == m_nchare) reorder();
+}
+
+void
+Sorter::reorder()
+// *****************************************************************************
+//  Reorder global mesh node IDs
+// *****************************************************************************
+{
+  // Activate SDAG waits for arriving requests from other chares requesting new
+  // node IDs for node IDs we assign new IDs to during reordering; and for
+  // computing/receiving lower and upper bounds of global node IDs our chare's
+  // linear system will operate on after reordering.
+  thisProxy[ thisIndex ].wait4prep();
+
+  // Send out request for new global node IDs for nodes we do not reorder
+  for (const auto& [ targetchare, nodes ] : m_reordcomm)
+    thisProxy[ targetchare ].request( thisIndex, nodes );
+
+  // Lambda to decide if node is assigned a new ID by this chare. If node is not
+  // found in the asymmetric communication map, it is owned, i.e., this chare
+  // assigns its new id.
+  auto ownnode = [ this ]( std::size_t p ) {
+    return std::all_of( m_reordcomm.cbegin(), m_reordcomm.cend(),
+                        [&](const auto& s)
+                        { return s.second.find(p) == s.second.cend(); } );
+  };
+
+  // Reorder our chunk of the mesh node IDs. Looping through all of our node
+  // IDs, we test if we are to assign a new ID to a node ID, and if so, we
+  // assign a new ID, i.e., reorder, by constructing a map associating new to
+  // old IDs (m_newnodes). We also count up the reordered nodes, which serves as
+  // the new node id. We also store the node coordinates associated to the new
+  // node ID.
+  for (auto p : m_nodeset)
+    if (ownnode(p)) {
+      m_newnodes[ p ] = m_start;        // assign new node ID (reorder)
+      m_newcoordmap.emplace( m_start, tk::cref_find(m_coordmap,p) );
+      ++m_start;
+    }
+
+  // Trigger SDAG wait indicating that reordering our node IDs are complete
+  reorderowned_complete();
+
+  // If all our nodes have new IDs assigned, reordering complete on this chare
+  if (m_newnodes.size() == m_nodeset.size()) finish();
+}
+
+void
+Sorter::request( int c, const std::unordered_set< std::size_t >& nd )
+// *****************************************************************************
+//  Request new global node IDs for old node IDs
+//! \param[in] c Chare request coming from and to which we send new IDs to
+//! \param[in] nd Set of old node IDs whose new IDs are requested
+// *****************************************************************************
+{
+  // Queue up requesting chare and node IDs
+  m_reqnodes.push_back( { c, nd } );
+  // Trigger SDAG wait signaling that node IDs have been requested from us
+  nodes_requested_complete();
+}
+
+void
+Sorter::prepare()
+// *****************************************************************************
+//  Find new node IDs for old ones and return them to the requestor(s)
+// *****************************************************************************
+{
+  // Find and return new node IDs to sender
+  for (const auto& [ requestorchare, nodes ] : m_reqnodes) {
+    std::unordered_map< std::size_t,
+      std::tuple< std::size_t, tk::UnsMesh::Coord > > n;
+    for (auto p : nodes) {
+      auto newid = tk::cref_find( m_newnodes, p );
+      n.emplace( p,
+        std::make_tuple( newid, tk::cref_find(m_newcoordmap,newid) ) );
+    }
+    thisProxy[ requestorchare ].neworder( n );
+  }
+
+  tk::destroy( m_reqnodes ); // Clear queue of requests just fulfilled
+
+  // Re-enable SDAG wait for preparing new node requests
+  thisProxy[ thisIndex ].wait4prep();
+
+  // Re-enable trigger signaling that reordering of owned node IDs are
+  // complete right away
+  reorderowned_complete();
+}
+
+void
+Sorter::neworder( const std::unordered_map< std::size_t,
+                        std::tuple< std::size_t, tk::UnsMesh::Coord > >& nodes )
+// *****************************************************************************
+//  Receive new (reordered) global node IDs
+//! \param[in] nodes Map associating new to old node IDs
+// *****************************************************************************
+{
+  // Store new node IDs associated to old ones, and node coordinates associated
+  // to new node IDs.
+  for (const auto& [ oldid, newnodes ] : nodes) {
+    auto newid = std::get< 0 >( newnodes );
+    m_newnodes[ oldid ] = newid;
+    m_newcoordmap.emplace( newid, std::get< 1 >( newnodes ) );
+  }
+
+  // If all our nodes have new IDs assigned, reorder complete on this PE
+  if (m_newnodes.size() == m_nodeset.size()) finish();
+}
+
+void
+Sorter::finish()
+// *****************************************************************************
+//  Compute final result of reordering
+//! \details Reordering is now complete on this chare. We now remap all mesh
+//!   data to reflect the new ordering.
+// *****************************************************************************
+{
+  // Update elem connectivity with the reordered node IDs
+  tk::remap( m_ginpoel, m_newnodes );
+
+  // Update node coordinate map with the reordered IDs
+  m_coordmap = m_newcoordmap;
+
+  // Update mesh chunk data structure held in our state with new node order
+  m_el = tk::global2local( m_ginpoel );
+
+  // Update symmetric chare-node communication map with the reordered IDs
+  for (auto& [ neighborchare, maps ] : m_msum) {
+
+    tk::NodeSet n;
+    for (auto p : maps.get< tag::node >())
+      n.insert( tk::cref_find( m_newnodes, p ) );
+    maps.get< tag::node >() = std::move( n );
+
+    tk::EdgeSet e;
+    for (const auto& ed : maps.get< tag::edge >()) {
+      e.insert( { tk::cref_find(m_newnodes,ed[0]),
+                  tk::cref_find(m_newnodes,ed[1]) } );
+    }
+    maps.get< tag::edge >() = std::move( e );
+
+  }
+
+  // Update boundary face-node connectivity with the reordered node IDs
+  tk::remap( m_triinpoel, m_newnodes );
+
+  // Update boundary node lists with the reordered node IDs
+  for (auto& [ setid, nodes ] : m_bnode) tk::remap( nodes, m_newnodes );
+
+  // Update mesh in Refiner after reordering
+  m_reorderRefiner.send();
+
+  // Progress report to host
+  if ( g_inputdeck.get< tag::cmd, tag::feedback >() ) m_host.chreordered();
+
+  createDiscWorkers();
+}
+
+void
+Sorter::mesh( std::vector< std::size_t >& ginpoel,
+              tk::UnsMesh::CoordMap& coordmap,
+              std::vector< std::size_t >& triinpoel,
+              std::map< int, std::vector< std::size_t > >& bnode )
+// *****************************************************************************
+// Update mesh data we hold for whoever calls this function
+//! \param[in,out] ginpoel Mesh connectivity using global IDs
+//! \param[in,out] coordmap Map of mesh node coordinates
+//! \param[in,out] triinpoel Boundary face-node connectivity
+//! \param[in] bnode Node lists of side sets
+// *****************************************************************************
+{
+  ginpoel = m_ginpoel;
+  coordmap = m_coordmap;
+  triinpoel = m_triinpoel;
+  bnode = m_bnode;
+}
+
+void
+Sorter::createDiscWorkers()
+// *****************************************************************************
+//  Create Discretization chare array elements on this PE
+//! \details We create chare array elements by calling the insert() member
+//!   function, which allows specifying the PE on which the array element is
+//!   created. and we send each chare array element the chunk of mesh it will
+//!   operate on.
+// *****************************************************************************
+{
+  std::vector< CProxy_Discretization > disc;
+  for (auto& d : m_scheme) disc.push_back( d.disc() );<--- Consider using std::transform algorithm instead of a raw loop.
+
+  // Create worker array element using Charm++ dynamic chare array element
+  // insertion: last arg: PE chare is created on. See also Charm++ manual, Sec.
+  // "Dynamic Insertion".
+
+  m_scheme[m_meshid].disc()[ thisIndex ].insert( m_meshid, disc,
+    m_scheme[m_meshid].ale(),
+    m_scheme[m_meshid].conjugategradients(), m_host, m_meshwriter, m_coordmap,
+    m_el, m_msum, m_bface, m_triinpoel, m_elemblockid, m_nchare );
+
+  contribute( sizeof(std::size_t), &m_meshid, CkReduction::nop,
+              m_cbs.get< tag::discinserted >() );
+}
+
+void
+Sorter::createWorkers()
+// *****************************************************************************
+//  Create worker chare array element
+// *****************************************************************************
+{
+  // Make sure (bound) base is already created and accessible
+  Assert( m_scheme[m_meshid].disc()[thisIndex].ckLocal() != nullptr,
+          "About to pass nullptr" );
+
+  // Create worker array element using Charm++ dynamic chare array element
+  // insertion: 1st arg: chare id, other args: Discretization's child ctor args.
+  // See also Charm++ manual, Sec. "Dynamic Insertion".
+
+  m_scheme[m_meshid].insert( thisIndex, m_scheme[m_meshid].disc(),
+    m_scheme[m_meshid].ghosts(), m_bface, m_bnode, m_triinpoel );
+
+  if ( g_inputdeck.get< tag::cmd, tag::feedback >() ) m_host.chcreated();
+
+  contribute( sizeof(std::size_t), &m_meshid, CkReduction::nop,
+              m_cbs.get< tag::workinserted >() );
+
+  // Free up some memory
+  tk::destroy( m_ginpoel );
+  tk::destroy( m_coordmap );
+  tk::destroy( m_bface );
+  tk::destroy( m_triinpoel );
+  tk::destroy( m_elemblockid );
+  tk::destroy( m_bnode );
+  tk::destroy( m_nodeset );
+  tk::destroy( m_nodech );
+  tk::destroy( m_chnode );
+  tk::destroy( m_msum );
+  tk::destroy( m_reordcomm );
+  tk::destroy( m_newnodes );
+  tk::destroy( m_reqnodes );
+}
+
+#include "NoWarning/sorter.def.h"
 
diff --git a/Debug/cppcheck/34.html b/Debug/cppcheck/34.html index 29bedf2d9d3f..3bde8fb6fae0 100644 --- a/Debug/cppcheck/34.html +++ b/Debug/cppcheck/34.html @@ -152,2505 +152,695 @@
- - + @@ -92,11 +92,11 @@ 18 : : size_t next_tet_id; 19 : : 20 : : // Constructor - 21 : 9868 : explicit id_generator_t(size_t start_tet_id = 0) : + 21 : 9781 : explicit id_generator_t(size_t start_tet_id = 0) : 22 : : start_id(start_tet_id), - 23 : 9868 : next_tet_id(start_id) + 23 : 9781 : next_tet_id(start_id) 24 : : { - 25 : 9868 : } + 25 : 9781 : } 26 : : 27 : : /** 28 : : * @brief Helper function to generate tet ids diff --git a/Debug/test_coverage/Inciter/AMR/index-sort-b.html b/Debug/test_coverage/Inciter/AMR/index-sort-b.html index 540380d5b3ed..434519d1887b 100644 --- a/Debug/test_coverage/Inciter/AMR/index-sort-b.html +++ b/Debug/test_coverage/Inciter/AMR/index-sort-b.html @@ -33,7 +33,7 @@ - + diff --git a/Debug/test_coverage/Inciter/AMR/index-sort-f.html b/Debug/test_coverage/Inciter/AMR/index-sort-f.html index 5817c3a6a104..d5c2a994efb1 100644 --- a/Debug/test_coverage/Inciter/AMR/index-sort-f.html +++ b/Debug/test_coverage/Inciter/AMR/index-sort-f.html @@ -33,7 +33,7 @@ - + @@ -166,28 +166,28 @@ - + - + - + - + - + - + @@ -201,18 +201,6 @@ - - - - - - - - - - + + + + + + + + + + - + diff --git a/Debug/test_coverage/Inciter/AMR/index.html b/Debug/test_coverage/Inciter/AMR/index.html index d167124923dc..9ede0f8ca44d 100644 --- a/Debug/test_coverage/Inciter/AMR/index.html +++ b/Debug/test_coverage/Inciter/AMR/index.html @@ -33,7 +33,7 @@ - + diff --git a/Debug/test_coverage/Inciter/AMR/marked_refinements_store.hpp.func-sort-c.html b/Debug/test_coverage/Inciter/AMR/marked_refinements_store.hpp.func-sort-c.html index 7c2c8c09f5ad..6f4978aedb54 100644 --- a/Debug/test_coverage/Inciter/AMR/marked_refinements_store.hpp.func-sort-c.html +++ b/Debug/test_coverage/Inciter/AMR/marked_refinements_store.hpp.func-sort-c.html @@ -33,7 +33,7 @@ - + @@ -81,19 +81,19 @@ - + - + - + - + diff --git a/Debug/test_coverage/Inciter/AMR/marked_refinements_store.hpp.func.html b/Debug/test_coverage/Inciter/AMR/marked_refinements_store.hpp.func.html index 52cb07234c32..a18683409ed5 100644 --- a/Debug/test_coverage/Inciter/AMR/marked_refinements_store.hpp.func.html +++ b/Debug/test_coverage/Inciter/AMR/marked_refinements_store.hpp.func.html @@ -33,7 +33,7 @@ - + @@ -73,7 +73,7 @@ - + @@ -85,7 +85,7 @@ - + @@ -97,7 +97,7 @@ - + @@ -109,7 +109,7 @@ - + diff --git a/Debug/test_coverage/Inciter/AMR/marked_refinements_store.hpp.gcov.html b/Debug/test_coverage/Inciter/AMR/marked_refinements_store.hpp.gcov.html index 57e8c96b5443..ae2621663c2b 100644 --- a/Debug/test_coverage/Inciter/AMR/marked_refinements_store.hpp.gcov.html +++ b/Debug/test_coverage/Inciter/AMR/marked_refinements_store.hpp.gcov.html @@ -33,7 +33,7 @@ - + @@ -105,8 +105,8 @@ 31 : : 32 : : //! Non-const-ref access to state 33 : : //! \return Map of marked refinements - 34 : 48798 : std::unordered_map<size_t, case_t>& data() { - 35 : 48798 : return marked_refinements; + 34 : 48276 : std::unordered_map<size_t, case_t>& data() { + 35 : 48276 : return marked_refinements; 36 : : } 37 : : 38 : : /** @@ -189,9 +189,9 @@ 115 : : * 116 : : * @return Bool stating is the state has changed 117 : : */ - 118 : 49650 : bool& get_state_changed() + 118 : 49128 : bool& get_state_changed() 119 : : { - 120 : 49650 : return state_changed; + 120 : 49128 : return state_changed; 121 : : } 122 : : }; 123 : : } diff --git a/Debug/test_coverage/Inciter/AMR/master_element_store.hpp.func-sort-c.html b/Debug/test_coverage/Inciter/AMR/master_element_store.hpp.func-sort-c.html index 271899dcbbf0..fceadbc715f9 100644 --- a/Debug/test_coverage/Inciter/AMR/master_element_store.hpp.func-sort-c.html +++ b/Debug/test_coverage/Inciter/AMR/master_element_store.hpp.func-sort-c.html @@ -33,7 +33,7 @@ - + @@ -77,7 +77,7 @@ - + diff --git a/Debug/test_coverage/Inciter/AMR/master_element_store.hpp.func.html b/Debug/test_coverage/Inciter/AMR/master_element_store.hpp.func.html index 73a0174e2cb2..bcfba095c687 100644 --- a/Debug/test_coverage/Inciter/AMR/master_element_store.hpp.func.html +++ b/Debug/test_coverage/Inciter/AMR/master_element_store.hpp.func.html @@ -33,7 +33,7 @@ - + @@ -81,7 +81,7 @@ - + diff --git a/Debug/test_coverage/Inciter/AMR/master_element_store.hpp.gcov.html b/Debug/test_coverage/Inciter/AMR/master_element_store.hpp.gcov.html index 548638db9930..034c7516e955 100644 --- a/Debug/test_coverage/Inciter/AMR/master_element_store.hpp.gcov.html +++ b/Debug/test_coverage/Inciter/AMR/master_element_store.hpp.gcov.html @@ -33,7 +33,7 @@ - + @@ -89,8 +89,8 @@ 15 : : std::map<size_t, Refinement_State> master_elements; 16 : : public: 17 : : //! Non-const-ref access to state - 18 : 24399 : std::map<size_t, Refinement_State>& data() { - 19 : 24399 : return master_elements; + 18 : 24138 : std::map<size_t, Refinement_State>& data() { + 19 : 24138 : return master_elements; 20 : : } 21 : : 22 : : /** diff --git a/Debug/test_coverage/Inciter/AMR/mesh_adapter.cpp.func-sort-c.html b/Debug/test_coverage/Inciter/AMR/mesh_adapter.cpp.func-sort-c.html index 9e82471f444b..6fc4dfc10c35 100644 --- a/Debug/test_coverage/Inciter/AMR/mesh_adapter.cpp.func-sort-c.html +++ b/Debug/test_coverage/Inciter/AMR/mesh_adapter.cpp.func-sort-c.html @@ -33,7 +33,7 @@ - + diff --git a/Debug/test_coverage/Inciter/AMR/mesh_adapter.cpp.func.html b/Debug/test_coverage/Inciter/AMR/mesh_adapter.cpp.func.html index 02c1c149e826..6ff6112275ab 100644 --- a/Debug/test_coverage/Inciter/AMR/mesh_adapter.cpp.func.html +++ b/Debug/test_coverage/Inciter/AMR/mesh_adapter.cpp.func.html @@ -33,7 +33,7 @@ - + diff --git a/Debug/test_coverage/Inciter/AMR/mesh_adapter.cpp.gcov.html b/Debug/test_coverage/Inciter/AMR/mesh_adapter.cpp.gcov.html index 7ee9851849ee..0a62e17b0e15 100644 --- a/Debug/test_coverage/Inciter/AMR/mesh_adapter.cpp.gcov.html +++ b/Debug/test_coverage/Inciter/AMR/mesh_adapter.cpp.gcov.html @@ -33,7 +33,7 @@ - + diff --git a/Debug/test_coverage/Inciter/AMR/mesh_adapter.hpp.func-sort-c.html b/Debug/test_coverage/Inciter/AMR/mesh_adapter.hpp.func-sort-c.html index 19c8e161c910..b34fea9aaa97 100644 --- a/Debug/test_coverage/Inciter/AMR/mesh_adapter.hpp.func-sort-c.html +++ b/Debug/test_coverage/Inciter/AMR/mesh_adapter.hpp.func-sort-c.html @@ -33,7 +33,7 @@ - + @@ -77,7 +77,7 @@ - +
   1
-   2
-   3
-   4
-   5
-   6
-   7
-   8
-   9
-  10
-  11
-  12
-  13
-  14
-  15
-  16
-  17
-  18
-  19
-  20
-  21
-  22
-  23
-  24
-  25
-  26
-  27
-  28
-  29
-  30
-  31
-  32
-  33
-  34
-  35
-  36
-  37
-  38
-  39
-  40
-  41
-  42
-  43
-  44
-  45
-  46
-  47
-  48
-  49
-  50
-  51
-  52
-  53
-  54
-  55
-  56
-  57
-  58
-  59
-  60
-  61
-  62
-  63
-  64
-  65
-  66
-  67
-  68
-  69
-  70
-  71
-  72
-  73
-  74
-  75
-  76
-  77
-  78
-  79
-  80
-  81
-  82
-  83
-  84
-  85
-  86
-  87
-  88
-  89
-  90
-  91
-  92
-  93
-  94
-  95
-  96
-  97
-  98
-  99
- 100
- 101
- 102
- 103
- 104
- 105
- 106
- 107
- 108
- 109
- 110
- 111
- 112
- 113
- 114
- 115
- 116
- 117
- 118
- 119
- 120
- 121
- 122
- 123
- 124
- 125
- 126
- 127
- 128
- 129
- 130
- 131
- 132
- 133
- 134
- 135
- 136
- 137
- 138
- 139
- 140
- 141
- 142
- 143
- 144
- 145
- 146
- 147
- 148
- 149
- 150
- 151
- 152
- 153
- 154
- 155
- 156
- 157
- 158
- 159
- 160
- 161
- 162
- 163
- 164
- 165
- 166
- 167
- 168
- 169
- 170
- 171
- 172
- 173
- 174
- 175
- 176
- 177
- 178
- 179
- 180
- 181
- 182
- 183
- 184
- 185
- 186
- 187
- 188
- 189
- 190
- 191
- 192
- 193
- 194
- 195
- 196
- 197
- 198
- 199
- 200
- 201
- 202
- 203
- 204
- 205
- 206
- 207
- 208
- 209
- 210
- 211
- 212
- 213
- 214
- 215
- 216
- 217
- 218
- 219
- 220
- 221
- 222
- 223
- 224
- 225
- 226
- 227
- 228
- 229
- 230
- 231
- 232
- 233
- 234
- 235
- 236
- 237
- 238
- 239
- 240
- 241
- 242
- 243
- 244
- 245
- 246
- 247
- 248
- 249
- 250
- 251
- 252
- 253
- 254
- 255
- 256
- 257
- 258
- 259
- 260
- 261
- 262
- 263
- 264
- 265
- 266
- 267
- 268
- 269
- 270
- 271
- 272
- 273
- 274
- 275
- 276
- 277
- 278
- 279
- 280
- 281
- 282
- 283
- 284
- 285
- 286
- 287
- 288
- 289
- 290
- 291
- 292
- 293
- 294
- 295
- 296
- 297
- 298
- 299
- 300
- 301
- 302
- 303
- 304
- 305
- 306
- 307
- 308
- 309
- 310
- 311
- 312
- 313
- 314
- 315
- 316
- 317
- 318
- 319
- 320
- 321
- 322
- 323
- 324
- 325
- 326
- 327
- 328
- 329
- 330
- 331
- 332
- 333
- 334
- 335
- 336
- 337
- 338
- 339
- 340
- 341
- 342
- 343
- 344
- 345
- 346
- 347
- 348
- 349
- 350
- 351
- 352
- 353
- 354
- 355
- 356
- 357
- 358
- 359
- 360
- 361
- 362
- 363
- 364
- 365
- 366
- 367
- 368
- 369
- 370
- 371
- 372
- 373
- 374
- 375
- 376
- 377
- 378
- 379
- 380
- 381
- 382
- 383
- 384
- 385
- 386
- 387
- 388
- 389
- 390
- 391
- 392
- 393
- 394
- 395
- 396
- 397
- 398
- 399
- 400
- 401
- 402
- 403
- 404
- 405
- 406
- 407
- 408
- 409
- 410
- 411
- 412
- 413
- 414
- 415
- 416
- 417
- 418
- 419
- 420
- 421
- 422
- 423
- 424
- 425
- 426
- 427
- 428
- 429
- 430
- 431
- 432
- 433
- 434
- 435
- 436
- 437
- 438
- 439
- 440
- 441
- 442
- 443
- 444
- 445
- 446
- 447
- 448
- 449
- 450
- 451
- 452
- 453
- 454
- 455
- 456
- 457
- 458
- 459
- 460
- 461
- 462
- 463
- 464
- 465
- 466
- 467
- 468
- 469
- 470
- 471
- 472
- 473
- 474
- 475
- 476
- 477
- 478
- 479
- 480
- 481
- 482
- 483
- 484
- 485
- 486
- 487
- 488
- 489
- 490
- 491
- 492
- 493
- 494
- 495
- 496
- 497
- 498
- 499
- 500
- 501
- 502
- 503
- 504
- 505
- 506
- 507
- 508
- 509
- 510
- 511
- 512
- 513
- 514
- 515
- 516
- 517
- 518
- 519
- 520
- 521
- 522
- 523
- 524
- 525
- 526
- 527
- 528
- 529
- 530
- 531
- 532
- 533
- 534
- 535
- 536
- 537
- 538
- 539
- 540
- 541
- 542
- 543
- 544
- 545
- 546
- 547
- 548
- 549
- 550
- 551
- 552
- 553
- 554
- 555
- 556
- 557
- 558
- 559
- 560
- 561
- 562
- 563
- 564
- 565
- 566
- 567
- 568
- 569
- 570
- 571
- 572
- 573
- 574
- 575
- 576
- 577
- 578
- 579
- 580
- 581
- 582
- 583
- 584
- 585
- 586
- 587
- 588
- 589
- 590
- 591
- 592
- 593
- 594
- 595
- 596
- 597
- 598
- 599
- 600
- 601
- 602
- 603
- 604
- 605
- 606
- 607
- 608
- 609
- 610
- 611
- 612
- 613
- 614
- 615
- 616
- 617
- 618
- 619
- 620
- 621
- 622
- 623
- 624
- 625
- 626
- 627
- 628
- 629
- 630
- 631
- 632
- 633
- 634
- 635
- 636
- 637
- 638
- 639
- 640
- 641
- 642
- 643
- 644
- 645
- 646
- 647
- 648
- 649
- 650
- 651
- 652
- 653
- 654
- 655
- 656
- 657
- 658
- 659
- 660
- 661
- 662
- 663
- 664
- 665
- 666
- 667
- 668
- 669
- 670
- 671
- 672
- 673
- 674
- 675
- 676
- 677
- 678
- 679
- 680
- 681
- 682
- 683
- 684
- 685
- 686
- 687
- 688
- 689
- 690
- 691
- 692
- 693
- 694
- 695
- 696
- 697
- 698
- 699
- 700
- 701
- 702
- 703
- 704
- 705
- 706
- 707
- 708
- 709
- 710
- 711
- 712
- 713
- 714
- 715
- 716
- 717
- 718
- 719
- 720
- 721
- 722
- 723
- 724
- 725
- 726
- 727
- 728
- 729
- 730
- 731
- 732
- 733
- 734
- 735
- 736
- 737
- 738
- 739
- 740
- 741
- 742
- 743
- 744
- 745
- 746
- 747
- 748
- 749
- 750
- 751
- 752
- 753
- 754
- 755
- 756
- 757
- 758
- 759
- 760
- 761
- 762
- 763
- 764
- 765
- 766
- 767
- 768
- 769
- 770
- 771
- 772
- 773
- 774
- 775
- 776
- 777
- 778
- 779
- 780
- 781
- 782
- 783
- 784
- 785
- 786
- 787
- 788
- 789
- 790
- 791
- 792
- 793
- 794
- 795
- 796
- 797
- 798
- 799
- 800
- 801
- 802
- 803
- 804
- 805
- 806
- 807
- 808
- 809
- 810
- 811
- 812
- 813
- 814
- 815
- 816
- 817
- 818
- 819
- 820
- 821
- 822
- 823
- 824
- 825
- 826
- 827
- 828
- 829
- 830
- 831
- 832
- 833
- 834
- 835
- 836
- 837
- 838
- 839
- 840
- 841
- 842
- 843
- 844
- 845
- 846
- 847
- 848
- 849
- 850
- 851
- 852
- 853
- 854
- 855
- 856
- 857
- 858
- 859
- 860
- 861
- 862
- 863
- 864
- 865
- 866
- 867
- 868
- 869
- 870
- 871
- 872
- 873
- 874
- 875
- 876
- 877
- 878
- 879
- 880
- 881
- 882
- 883
- 884
- 885
- 886
- 887
- 888
- 889
- 890
- 891
- 892
- 893
- 894
- 895
- 896
- 897
- 898
- 899
- 900
- 901
- 902
- 903
- 904
- 905
- 906
- 907
- 908
- 909
- 910
- 911
- 912
- 913
- 914
- 915
- 916
- 917
- 918
- 919
- 920
- 921
- 922
- 923
- 924
- 925
- 926
- 927
- 928
- 929
- 930
- 931
- 932
- 933
- 934
- 935
- 936
- 937
- 938
- 939
- 940
- 941
- 942
- 943
- 944
- 945
- 946
- 947
- 948
- 949
- 950
- 951
- 952
- 953
- 954
- 955
- 956
- 957
- 958
- 959
- 960
- 961
- 962
- 963
- 964
- 965
- 966
- 967
- 968
- 969
- 970
- 971
- 972
- 973
- 974
- 975
- 976
- 977
- 978
- 979
- 980
- 981
- 982
- 983
- 984
- 985
- 986
- 987
- 988
- 989
- 990
- 991
- 992
- 993
- 994
- 995
- 996
- 997
- 998
- 999
-1000
-1001
-1002
-1003
-1004
-1005
-1006
-1007
-1008
-1009
-1010
-1011
-1012
-1013
-1014
-1015
-1016
-1017
-1018
-1019
-1020
-1021
-1022
-1023
-1024
-1025
-1026
-1027
-1028
-1029
-1030
-1031
-1032
-1033
-1034
-1035
-1036
-1037
-1038
-1039
-1040
-1041
-1042
-1043
-1044
-1045
-1046
-1047
-1048
-1049
-1050
-1051
-1052
-1053
-1054
-1055
-1056
-1057
-1058
-1059
-1060
-1061
-1062
-1063
-1064
-1065
-1066
-1067
-1068
-1069
-1070
-1071
-1072
-1073
-1074
-1075
-1076
-1077
-1078
-1079
-1080
-1081
-1082
-1083
-1084
-1085
-1086
-1087
-1088
-1089
-1090
-1091
-1092
-1093
-1094
-1095
-1096
-1097
-1098
-1099
-1100
-1101
-1102
-1103
-1104
-1105
-1106
-1107
-1108
-1109
-1110
-1111
-1112
-1113
-1114
-1115
-1116
-1117
-1118
-1119
-1120
-1121
-1122
-1123
-1124
-1125
-1126
-1127
-1128
-1129
-1130
-1131
-1132
-1133
-1134
-1135
-1136
-1137
-1138
-1139
-1140
-1141
-1142
-1143
-1144
-1145
-1146
-1147
-1148
-1149
-1150
-1151
-1152
-1153
-1154
-1155
-1156
-1157
-1158
-1159
-1160
-1161
-1162
-1163
-1164
-1165
-1166
-1167
-1168
-1169
-1170
-1171
-1172
-1173
-1174
-1175
-1176
-1177
-1178
-1179
-1180
-1181
-1182
-1183
-1184
-1185
-1186
-1187
-1188
-1189
-1190
-1191
-1192
-1193
-1194
-1195
-1196
-1197
-1198
-1199
-1200
-1201
-1202
-1203
-1204
-1205
-1206
-1207
-1208
-1209
-1210
-1211
-1212
-1213
-1214
-1215
-1216
-1217
-1218
-1219
-1220
-1221
-1222
-1223
-1224
-1225
-1226
-1227
-1228
-1229
-1230
-1231
-1232
-1233
-1234
-1235
-1236
-1237
-1238
-1239
-1240
-1241
-1242
-1243
-1244
-1245
-1246
// *****************************************************************************
+
  1
+  2
+  3
+  4
+  5
+  6
+  7
+  8
+  9
+ 10
+ 11
+ 12
+ 13
+ 14
+ 15
+ 16
+ 17
+ 18
+ 19
+ 20
+ 21
+ 22
+ 23
+ 24
+ 25
+ 26
+ 27
+ 28
+ 29
+ 30
+ 31
+ 32
+ 33
+ 34
+ 35
+ 36
+ 37
+ 38
+ 39
+ 40
+ 41
+ 42
+ 43
+ 44
+ 45
+ 46
+ 47
+ 48
+ 49
+ 50
+ 51
+ 52
+ 53
+ 54
+ 55
+ 56
+ 57
+ 58
+ 59
+ 60
+ 61
+ 62
+ 63
+ 64
+ 65
+ 66
+ 67
+ 68
+ 69
+ 70
+ 71
+ 72
+ 73
+ 74
+ 75
+ 76
+ 77
+ 78
+ 79
+ 80
+ 81
+ 82
+ 83
+ 84
+ 85
+ 86
+ 87
+ 88
+ 89
+ 90
+ 91
+ 92
+ 93
+ 94
+ 95
+ 96
+ 97
+ 98
+ 99
+100
+101
+102
+103
+104
+105
+106
+107
+108
+109
+110
+111
+112
+113
+114
+115
+116
+117
+118
+119
+120
+121
+122
+123
+124
+125
+126
+127
+128
+129
+130
+131
+132
+133
+134
+135
+136
+137
+138
+139
+140
+141
+142
+143
+144
+145
+146
+147
+148
+149
+150
+151
+152
+153
+154
+155
+156
+157
+158
+159
+160
+161
+162
+163
+164
+165
+166
+167
+168
+169
+170
+171
+172
+173
+174
+175
+176
+177
+178
+179
+180
+181
+182
+183
+184
+185
+186
+187
+188
+189
+190
+191
+192
+193
+194
+195
+196
+197
+198
+199
+200
+201
+202
+203
+204
+205
+206
+207
+208
+209
+210
+211
+212
+213
+214
+215
+216
+217
+218
+219
+220
+221
+222
+223
+224
+225
+226
+227
+228
+229
+230
+231
+232
+233
+234
+235
+236
+237
+238
+239
+240
+241
+242
+243
+244
+245
+246
+247
+248
+249
+250
+251
+252
+253
+254
+255
+256
+257
+258
+259
+260
+261
+262
+263
+264
+265
+266
+267
+268
+269
+270
+271
+272
+273
+274
+275
+276
+277
+278
+279
+280
+281
+282
+283
+284
+285
+286
+287
+288
+289
+290
+291
+292
+293
+294
+295
+296
+297
+298
+299
+300
+301
+302
+303
+304
+305
+306
+307
+308
+309
+310
+311
+312
+313
+314
+315
+316
+317
+318
+319
+320
+321
+322
+323
+324
+325
+326
+327
+328
+329
+330
+331
+332
+333
+334
+335
+336
+337
+338
+339
+340
+341
// *****************************************************************************
 /*!
-  \file      src/Inciter/Discretization.cpp
+  \file      src/Main/Inciter.cpp
   \copyright 2012-2015 J. Bakosi,
              2016-2018 Los Alamos National Security, LLC.,
              2019-2021 Triad National Security, LLC.
              All rights reserved. See the LICENSE file for details.
-  \details   Data and functionality common to all discretization schemes
-  \see       Discretization.h and Discretization.C for more info.
-*/
-// *****************************************************************************
-
-#include "Tags.hpp"
-#include "Reorder.hpp"
-#include "Vector.hpp"
-#include "DerivedData.hpp"
-#include "Discretization.hpp"
-#include "MeshWriter.hpp"
-#include "DiagWriter.hpp"
-#include "Inciter/InputDeck/InputDeck.hpp"
-#include "Inciter/Options/Scheme.hpp"
-#include "Print.hpp"
-#include "Around.hpp"
-#include "QuinoaBuildConfig.hpp"
-#include "ConjugateGradients.hpp"
-#include "ALE.hpp"
-
-#include "M2MTransfer.hpp"
-
-namespace inciter {
-
-static CkReduction::reducerType PDFMerger;
-extern ctr::InputDeck g_inputdeck;
-extern ctr::InputDeck g_inputdeck_defaults;
-
-} // inciter::
+  \brief     Inciter, computational shock hydrodynamics tool, Charm++ main
+    chare.
+  \details   Inciter, computational shock hydrodynamics tool, Charm++ main
+    chare. This file contains the definition of the Charm++ main chare,
+    equivalent to main() in Charm++-land.
+*/
+// *****************************************************************************
+
+#include <unordered_map>
+#include <vector>
+#include <iostream>
+
+#include "Types.hpp"
+#include "Init.hpp"
+#include "QuinoaConfig.hpp"
+#include "Timer.hpp"
+#include "Exception.hpp"
+#include "CGPDE.hpp"
+#include "DGPDE.hpp"
+#include "FVPDE.hpp"
+#include "PDEStack.hpp"
+#include "ProcessException.hpp"
+#include "InciterPrint.hpp"
+#include "InciterDriver.hpp"
+#include "Inciter/CmdLine/Parser.hpp"
+#include "Inciter/CmdLine/CmdLine.hpp"
+#include "Inciter/InputDeck/InputDeck.hpp"
+#include "ChareStateCollector.hpp"
+#include "LBSwitch.hpp"
 
-using inciter::Discretization;
+#include "NoWarning/inciter.decl.h"
 
-Discretization::Discretization(
-  std::size_t meshid,
-  const std::vector< CProxy_Discretization >& disc,
-  const CProxy_ALE& aleproxy,
-  const tk::CProxy_ConjugateGradients& conjugategradientsproxy,
-  const CProxy_Transporter& transporter,
-  const tk::CProxy_MeshWriter& meshwriter,
-  const tk::UnsMesh::CoordMap& coordmap,
-  const tk::UnsMesh::Chunk& el,
-  const tk::CommMaps& msum,
-  const std::map< int, std::vector< std::size_t > >& bface,
-  const std::vector< std::size_t >& triinpoel,
-  const std::unordered_map< std::size_t, std::set< std::size_t > >& elemblockid,
-  int nc ) :
-  m_meshid( meshid ),
-  m_transfer( g_inputdeck.get< tag::transfer >() ),
-  m_disc( disc ),
-  m_nchare( nc ),
-  m_it( 0 ),
-  m_itr( 0 ),
-  m_itf( 0 ),
-  m_initial( 1 ),
-  m_t( g_inputdeck.get< tag::t0 >() ),
-  m_lastDumpTime( -std::numeric_limits< tk::real >::max() ),
-  m_physFieldFloor( 0.0 ),
-  m_physHistFloor( 0.0 ),
-  m_rangeFieldFloor( 0.0 ),
-  m_rangeHistFloor( 0.0 ),
-  m_dt( g_inputdeck.get< tag::dt >() ),
-  m_dtn( m_dt ),
-  m_nvol( 0 ),
-  m_nxfer( 0 ),
-  m_ale( aleproxy ),
-  m_transporter( transporter ),
-  m_meshwriter( meshwriter ),
-  m_el( el ),     // fills m_inpoel, m_gid, m_lid
-  m_coord( setCoord( coordmap ) ),
-  m_coordn( m_coord ),
-  m_nodeCommMap(),
-  m_edgeCommMap(),
-  m_meshvol( 0.0 ),
-  m_v( m_gid.size(), 0.0 ),
-  m_vol( m_gid.size(), 0.0 ),
-  m_volc(),
-  m_voln( m_vol ),
-  m_vol0( m_inpoel.size()/4, 0.0 ),
-  m_bid(),
-  m_timer(),
-  m_refined( 0 ),
-  m_prevstatus( std::chrono::high_resolution_clock::now() ),
-  m_nrestart( 0 ),
-  m_histdata(),
-  m_nsrc( 0 ),
-  m_ndst( 0 ),
-  m_meshvel( 0, 3 ),
-  m_meshvel_converged( true ),
-  m_bface( bface ),
-  m_triinpoel( triinpoel ),
-  m_elemblockid( elemblockid )
-// *****************************************************************************
-//  Constructor
-//! \param[in] meshid Mesh ID
-//! \param[in] disc All Discretization proxies (one per mesh)
-//! \param[in] aleproxy Distributed ALE proxy
-//! \param[in] conjugategradientsproxy Distributed Conjugrate Gradients linear
-//!   solver proxy
-//! \param[in] transporter Host (Transporter) proxy
-//! \param[in] meshwriter Mesh writer proxy
-//! \param[in] coordmap Coordinates of mesh nodes and their global IDs
-//! \param[in] el Elements of the mesh chunk we operate on
-//! \param[in] msum Communication maps associated to chare IDs bordering the
-//!   mesh chunk we operate on
-//! \param[in] bface Face lists mapped to side set ids
-//! \param[in] triinpoel Interconnectivity of points and boundary-faces
-//! \param[in] elemblockid Local tet ids associated with mesh block ids
-//! \param[in] nc Total number of Discretization chares
-// *****************************************************************************
-{
-  Assert( !m_inpoel.empty(), "No elements assigned to Discretization chare" );
-  Assert( tk::positiveJacobians( m_inpoel, m_coord ),
-          "Jacobian in input mesh to Discretization non-positive" );
-  #if not defined(__INTEL_COMPILER) || defined(NDEBUG)
-  // The above ifdef skips running the conformity test with the intel compiler
-  // in debug mode only. This is necessary because in tk::conforming(), filling
-  // up the map can fail with some meshes (only in parallel), e.g., tube.exo,
-  // used by some regression tests, due to the intel compiler generating some
-  // garbage incorrect code - only in debug, only in parallel, only with that
-  // mesh.
-  Assert( tk::conforming( m_inpoel, m_coord ),
-          "Input mesh to Discretization not conforming" );
-  #endif
-
-  // Store communication maps
-  for (const auto& [ c, maps ] : msum) {
-    m_nodeCommMap[c] = maps.get< tag::node >();
-    m_edgeCommMap[c] = maps.get< tag::edge >();
-  }
-
-  // Get ready for computing/communicating nodal volumes
-  startvol();
-
-  // Get chare-boundary node-id map
-  m_bid = genBid();
-
-  // Find host elements of user-specified points where time histories are
-  // saved, and save the shape functions evaluated at the point locations
-  const auto& pt = g_inputdeck.get< tag::history_output, tag::point >();
-  for (std::size_t p=0; p<pt.size(); ++p) {
-    std::array< tk::real, 4 > N;
-    const auto& l = pt[p].get< tag::coord >();
-    const auto& id = pt[p].get< tag::id >();
-    for (std::size_t e=0; e<m_inpoel.size()/4; ++e) {
-      if (tk::intet( m_coord, m_inpoel, l, e, N )) {
-        m_histdata.push_back( HistData{{ id, e, {l[0],l[1],l[2]}, N }} );
-        break;
-      }
-    }
-  }
-
-  // Insert ConjugrateGradients solver chare array element if needed
-  if (g_inputdeck.get< tag::ale, tag::ale >()) {
-    m_ale[ thisIndex ].insert( conjugategradientsproxy,
-                               m_coord, m_inpoel,
-                               m_gid, m_lid, m_nodeCommMap );
-  } else {
-    m_meshvel.resize( m_gid.size() );
-  }
-
-  // Register mesh with mesh-transfer lib
-  if (m_disc.size() == 1 || m_transfer.empty()) {
-    // skip transfer if single mesh or if not involved in coupling
-    transferInit();
-  } else {
-    if (thisIndex == 0) {
-      exam2m::addMesh( thisProxy, m_nchare,
-        CkCallback( CkIndex_Discretization::transferInit(), thisProxy ) );
-      //std::cout << "Disc: " << m_meshid << " m2m::addMesh()\n";
-    }
-  }
-}
-
-std::unordered_map< std::size_t, std::size_t >
-Discretization::genBid()
-// *****************************************************************************
-// Generate the Bid data-structure based on the node communication-map
-// *****************************************************************************
-{
-  // Count the number of mesh nodes at which we receive data from other chares
-  // and compute map associating boundary-chare node ID to global node ID
-  std::vector< std::size_t > c( tk::sumvalsize( m_nodeCommMap ) );
-  std::size_t j = 0;
-  for (const auto& [ch,n] : m_nodeCommMap) for (auto i : n) c[j++] = i;
-  tk::unique( c );
-  return tk::assignLid( c );
-}
-
-void
-Discretization::transferInit()
-// *****************************************************************************
-// Our mesh has been registered with the mesh-to-mesh transfer library (if
-// coupled to other solver)
-// *****************************************************************************
-{
-  // Compute number of mesh points owned
-  std::size_t npoin = m_gid.size();
-  for (auto g : m_gid) if (tk::slave(m_nodeCommMap,g,thisIndex)) --npoin;
-
-  // Tell the RTS that the Discretization chares have been created and compute
-  // the total number of mesh points across the distributed mesh
-  std::vector< std::size_t > meshdata{ m_meshid, npoin };
-  contribute( meshdata, CkReduction::sum_ulong,
-    CkCallback( CkReductionTarget(Transporter,disccreated), m_transporter ) );
-}
-
-void
-Discretization::meshvelStart(
-  const tk::UnsMesh::Coords vel,
-  const std::vector< tk::real >& soundspeed,
-  const std::unordered_map< int,
-    std::unordered_map< std::size_t, std::array< tk::real, 4 > > >& bnorm,
-  tk::real adt,
-  CkCallback done ) const
-// *****************************************************************************
-// Start computing new mesh velocity for ALE mesh motion
-//! \param[in] vel Fluid velocity at mesh nodes
-//! \param[in] soundspeed Speed of sound at mesh nodes
-//! \param[in] bnorm Face normals in boundary points associated to side sets
-//! \param[in] adt alpha*dt of the RK time step
-//! \param[in] done Function to continue with when mesh velocity has been
-//!   computed
-// *****************************************************************************
-{
-  if (g_inputdeck.get< tag::ale, tag::ale >())
-    m_ale[ thisIndex ].ckLocal()->start( vel, soundspeed, done,
-      m_coord, m_coordn, m_vol0, m_vol, bnorm, m_initial, m_it, m_t, adt );
-  else
-    done.send();
-}
-
-const tk::Fields&
-Discretization::meshvel() const
-// *****************************************************************************
-//! Query the mesh velocity
-//! \return Mesh velocity
-// *****************************************************************************
-{
-  if (g_inputdeck.get< tag::ale, tag::ale >())
-    return m_ale[ thisIndex ].ckLocal()->meshvel();
-  else
-    return m_meshvel;
-}
-
-void
-Discretization::meshvelBnd(
-  const std::map< int, std::vector< std::size_t > >& bface,
-  const std::map< int, std::vector< std::size_t > >& bnode,
-  const std::vector< std::size_t >& triinpoel) const
-// *****************************************************************************
-// Query ALE mesh velocity boundary condition node lists and node lists at
-// which ALE moves boundaries
-// *****************************************************************************
-{
-  if (g_inputdeck.get< tag::ale, tag::ale >())
-    m_ale[ thisIndex ].ckLocal()->meshvelBnd( bface, bnode, triinpoel );
-}
-
-void
-Discretization::meshvelConv()
-// *****************************************************************************
-//! Assess and record mesh velocity linear solver convergence
-// *****************************************************************************
-{
-  auto smoother = g_inputdeck.get< tag::ale, tag::smoother >();
-
-  if (g_inputdeck.get< tag::ale, tag::ale >() &&
-      (smoother == ctr::MeshVelocitySmootherType::LAPLACE or
-       smoother == ctr::MeshVelocitySmootherType::HELMHOLTZ))
-  {
-    m_meshvel_converged &= m_ale[ thisIndex ].ckLocal()->converged();
-  }
-}
-
-void
-Discretization::comfinal()
-// *****************************************************************************
-// Finish setting up communication maps and solution transfer callbacks
-// *****************************************************************************
-{
-  // Generate own subset of solver/mesh transfer list
-  for (const auto& t : m_transfer) {
-    if (t.src == m_meshid || t.dst == m_meshid) {
-      m_mytransfer.push_back( t );<--- Consider using std::copy_if algorithm instead of a raw loop.
-    }
-  }
-
-  // Signal the runtime system that the workers have been created
-  std::vector< std::size_t > meshdata{ /* initial = */ 1, m_meshid };
-  contribute( meshdata, CkReduction::sum_ulong,
-    CkCallback(CkReductionTarget(Transporter,comfinal), m_transporter) );
-}
-
-void
-Discretization::transfer(
-  tk::Fields& u,
-  std::size_t dirn,
-  CkCallback cb )
-// *****************************************************************************
-//  Start solution transfer (if coupled)
-//! \param[in,out] u Solution to transfer from/to
-//! \param[in] dirn Direction of solution transfer. 0: from background to
-//!   overset, 1: from overset to background
-//! \param[in] cb Callback to call when back and forth transfers complete.
-//! \details This function initiates the solution transfer (direction dependent
-//!   on 'dirn') between meshes. It invokes a reduction to Transporter when the
-//!   transfer in one direction is complete (dirn == 0), or calls back the
-//!   'cb' function in Scheme when transfers both directions are complete.
-//!   The function relies on 'dirn' to make this decision.
-// *****************************************************************************
-{
-  if (m_mytransfer.empty()) {   // skip transfer if not involved in coupling
-
-    cb.send();
-
-  } else {
-
-    m_transfer_complete = cb;
-
-    // determine source and destination mesh depending on direction of transfer
-    std::size_t fromMesh(0), toMesh(0);
-    CkCallback cb_xfer;
-    if (dirn == 0) {
-      fromMesh = m_mytransfer[m_nsrc].src;<--- Variable 'fromMesh' is assigned a value that is never used.
-      toMesh = m_mytransfer[m_ndst].dst;<--- Variable 'toMesh' is assigned a value that is never used.
-      cb_xfer = CkCallback( CkIndex_Discretization::to_complete(), thisProxy[thisIndex] );<--- Variable 'cb_xfer' is assigned a value that is never used.
-    }
-    else {
-      fromMesh = m_mytransfer[m_nsrc].dst;<--- Variable 'fromMesh' is assigned a value that is never used.
-      toMesh = m_mytransfer[m_ndst].src;<--- Variable 'toMesh' is assigned a value that is never used.
-      cb_xfer = CkCallback( CkIndex_Discretization::from_complete(), thisProxy[thisIndex] );<--- Variable 'cb_xfer' is assigned a value that is never used.
-    }
+#if defined(__clang__)
+  #pragma clang diagnostic push
+  #pragma clang diagnostic ignored "-Wmissing-variable-declarations"
+#endif
+
+//! \brief Charm handle to the main proxy, facilitates call-back to finalize,
+//!    etc., must be in global scope, unique per executable
+CProxy_Main mainProxy;
+
+//! Chare state collector Charm++ chare group proxy
+tk::CProxy_ChareStateCollector stateProxy;
+
+//! Load balancer switch group proxy
+tk::CProxy_LBSwitch LBSwitchProxy;
+
+//! If true, call and stack traces are to be output with exceptions
+//! \note This is true by default so that the trace is always output between
+//!   program start and the Main ctor in which the user-input from command line
+//!   setting for this overrides this true setting.
+bool g_trace = true;
+
+#if defined(__clang__)
+  #pragma clang diagnostic pop
+#endif
+
+//! Inciter declarations and definitions
+namespace inciter {
+
+//! Global-scope data. Initialized by the main chare and distibuted to all PEs
+//! by the Charm++ runtime system. Though semantically not const, all these
+//! global data should be considered read-only. See also
+//! http://charm.cs.illinois.edu/manuals/html/charm++/manual.html. The data
+//! below is global-scope because they must be available to all PEs which could
+//! be on different machines.
+
+#if defined(__clang__)
+  #pragma clang diagnostic push
+  #pragma clang diagnostic ignored "-Wmissing-variable-declarations"
+#endif
+
+//! Defaults of input deck, facilitates detection what is set by user
+//! \details This object is in global scope, it contains the default of all
+//!   possible user input, and thus it is made available to all PEs for
+//!   convenience reasons. The runtime system distributes it to all PEs during
+//!   initialization. Once distributed, the object does not change.
+ctr::InputDeck g_inputdeck_defaults;
+//! Lua Input deck filled by LuaParser, containing all input data
+//! \details This object is in global scope, it contains all of user input, and
+//!   thus it is made available to all PEs for convenience reasons. The runtime
+//!   system distributes it to all PEs during initialization. Once distributed,
+//!   the object does not change.
+ctr::InputDeck g_inputdeck;
+//! Partial differential equations using continuous Galerkin selected by user
+//! \details This vector is in global scope, because it holds polymorphic
+//!   objects, and thus must be distributed to all PEs during initialization.
+//!   Once distributed by the runtime system, the objects do not change.
+std::vector< CGPDE > g_cgpde;
+//! Partial differential equations using discontinuous Galerkin selected by user
+//! \details This vector is in global scope, because it holds polymorphic
+//!   objects, and thus must be distributed to all PEs during initialization.
+//!   Once distributed by the runtime system, the objects do not change.
+std::vector< DGPDE > g_dgpde;
+//! Partial differential equations using finite volume selected by user
+//! \details This vector is in global scope, because it holds polymorphic
+//!   objects, and thus must be distributed to all PEs during initialization.
+//!   Once distributed by the runtime system, the objects do not change.
+std::vector< FVPDE > g_fvpde;
+
+#if defined(__clang__)
+  #pragma clang diagnostic pop
+#endif
+
+//! \brief Pack/Unpack selected partial differential equations using continuous
+//!   Galerkin discretization.
+//! \details This Pack/Unpack method (re-)creates the PDE factory since it needs
+//!   to (re-)bind function pointers on different processing elements. Therefore
+//!   we circumvent Charm's usual pack/unpack for this type, and thus sizing
+//!   does not make sense: sizing is a no-op. We could initialize the factory in
+//!   InciterDriver's constructor and let this function re-create the stack only
+//!   when unpacking, but that leads to repeating the same code twice: once in
+//!   InciterDriver's constructor, once here. Another option is to use this
+//!   pack/unpack routine to both initially create (when packing) and to
+//!   re-create (when unpacking) the factory, which eliminates the need for
+//!   pre-creating the object in InciterDriver's constructor and therefore
+//!   eliminates the repeated code. This explains the guard for sizing: the code
+//!   below is called for packing only (in serial) and packing and unpacking (in
+//!   parallel).
+inline
+void operator|( PUP::er& p, std::vector< CGPDE >& eqs ) {
+  try {
+    if (!p.isSizing()) eqs = PDEStack().selectedCG();
+  } catch (...) { tk::processExceptionCharm(); }
+}
+
+//! \brief Pack/Unpack selected partial differential equations using
+//!   discontinuous Galerkin discretization.
+//! \details This Pack/Unpack method (re-)creates the PDE factory since it needs
+//!   to (re-)bind function pointers on different processing elements. Therefore
+//!   we circumvent Charm's usual pack/unpack for this type, and thus sizing
+//!   does not make sense: sizing is a no-op. We could initialize the factory in
+//!   InciterDriver's constructor and let this function re-create the stack only
+//!   when unpacking, but that leads to repeating the same code twice: once in
+//!   InciterDriver's constructor, once here. Another option is to use this
+//!   pack/unpack routine to both initially create (when packing) and to
+//!   re-create (when unpacking) the factory, which eliminates the need for
+//!   pre-creating the object in InciterDriver's constructor and therefore
+//!   eliminates the repeated code. This explains the guard for sizing: the code
+//!   below is called for packing only (in serial) and packing and unpacking (in
+//!   parallel).
+inline
+void operator|( PUP::er& p, std::vector< DGPDE >& eqs ) {
+  try {
+    if (!p.isSizing()) eqs = PDEStack().selectedDG();
+  } catch (...) { tk::processExceptionCharm(); }
+}
+
+//! \brief Pack/Unpack selected partial differential equations using
+//!   finite volume discretization.
+//! \details This Pack/Unpack method (re-)creates the PDE factory since it needs
+//!   to (re-)bind function pointers on different processing elements. Therefore
+//!   we circumvent Charm's usual pack/unpack for this type, and thus sizing
+//!   does not make sense: sizing is a no-op. We could initialize the factory in
+//!   InciterDriver's constructor and let this function re-create the stack only
+//!   when unpacking, but that leads to repeating the same code twice: once in
+//!   InciterDriver's constructor, once here. Another option is to use this
+//!   pack/unpack routine to both initially create (when packing) and to
+//!   re-create (when unpacking) the factory, which eliminates the need for
+//!   pre-creating the object in InciterDriver's constructor and therefore
+//!   eliminates the repeated code. This explains the guard for sizing: the code
+//!   below is called for packing only (in serial) and packing and unpacking (in
+//!   parallel).
+inline
+void operator|( PUP::er& p, std::vector< FVPDE >& eqs ) {
+  try {
+    if (!p.isSizing()) eqs = PDEStack().selectedFV();
+  } catch (...) { tk::processExceptionCharm(); }
+}
+
+} // inciter::
+
+//! \brief Charm++ main chare for the shock hydrodynamics executable, inciter.
+//! \details In inciter the Charm++ runtime system is initialized only after the
+//!   mesh has been read in, partitioned, and the necessary data structures,
+//!   e.g., communication maps, have been generated. This delayed initialization
+//!   of the Charm++ runtime system is required since the mesh partitioning is
+//!   done by Zoltan, an MPI library. Note that this Charm++ main chare object
+//!   should not be in a namespace.
+// cppcheck-suppress noConstructor
+class Main : public CBase_Main {<--- Unmatched suppression: noConstructor
+
+  public:
+    //! \brief Constructor
+    //! \details Inciter's main chare constructor is the entry point of the
+    //!   Charm++ portion of inciter, called by the Charm++ runtime system. The
+    //!   constructor does basic initialization steps, prints out some useful
+    //!   information to screen (in verbose mode), and instantiates a driver.
+    //!   Since Charm++ is fully asynchronous, the constructor usually spawns
+    //!   asynchronous objects and immediately exits. Thus in the body of the
+    //!   main chare constructor we fire up an 'execute' chare, which then calls
+    //!   back to Main::execute(). Finishing the main chare constructor the
+    //!   Charm++ runtime system then starts the network-migration of all
+    //!   global-scope data (if any). The execute chare calling back to
+    //!   Main::execute() signals the end of the migration of the global-scope
+    //!   data. Then we are ready to execute the driver. Since inciter is
+    //!   parallel and asynchronous, its driver fires up additional Charm++
+    //!   chare objects which then call back to Main::finalize() at some point
+    //!   in the future when all work has been finished. finalize() then exits
+    //!   by calling Charm++'s CkExit(), shutting down the runtime system.
+    //! \see http://charm.cs.illinois.edu/manuals/html/charm++/manual.html
+    Main( CkArgMsg* msg )
+    try :
+      m_signal( tk::setSignalHandlers() ),
+      m_cmdline(),
+      // Parse command line into m_cmdline using default simple pretty printer
+      m_cmdParser( msg->argc, msg->argv, tk::Print(), m_cmdline ),
+      // Create Inciter driver
+      m_driver( tk::Main< inciter::InciterDriver >
+                        ( msg->argc, msg->argv,
+                          m_cmdline,
+                          tk::HeaderType::INCITER,
+                          tk::inciter_executable(),
+                          inciter::g_inputdeck_defaults.get< tag::cmd, tag::io,
+                            tag::screen >(),
+                          inciter::g_inputdeck_defaults.get< tag::cmd, tag::io,
+                            tag::nrestart >() ) ),
+      // Start new timer measuring the total runtime
+      m_timer(1),
+      m_timestamp()
+    {
+      delete msg;
+      g_trace = m_cmdline.get< tag::trace >();
+      tk::MainCtor( mainProxy, thisProxy, m_timer, m_cmdline,
+                    CkCallback( CkIndex_Main::quiescence(), thisProxy ) );
+      // If quiescence detection is on or user requested it, create chare state
+      // collector Charm++ chare group
+      if ( m_cmdline.get< tag::chare >() || m_cmdline.get< tag::quiescence >() )
+        stateProxy = tk::CProxy_ChareStateCollector::ckNew();
+      // Fire up an asynchronous execute object, which when created at some
+      // future point in time will call back to this->execute(). This is
+      // necessary so that this->execute() can access already migrated
+      // global-scope data.
+      CProxy_execute::ckNew();
+    } catch (...) { tk::processExceptionCharm(); }
+
+    //! Migrate constructor: returning from a checkpoint
+    explicit Main( CkMigrateMessage* msg ) : CBase_Main( msg ),
+      m_signal( tk::setSignalHandlers() ),
+      m_cmdline(),
+      m_cmdParser( reinterpret_cast<CkArgMsg*>(msg)->argc,
+                   reinterpret_cast<CkArgMsg*>(msg)->argv,
+                   tk::Print(),
+                   m_cmdline ),
+      m_driver( tk::Main< inciter::InciterDriver >
+                        ( reinterpret_cast<CkArgMsg*>(msg)->argc,
+                          reinterpret_cast<CkArgMsg*>(msg)->argv,
+                          m_cmdline,
+                          tk::HeaderType::INCITER,
+                          tk::inciter_executable(),
+                          inciter::g_inputdeck_defaults.get< tag::cmd,
+                            tag::io, tag::screen >(),
+                          inciter::g_inputdeck.get< tag::cmd,
+                            tag::io, tag::nrestart >()+1 ) ),
+      m_timer(1),
+      m_timestamp()
+    {
+      // increase number of restarts (available for Transporter on PE 0)
+      ++inciter::g_inputdeck.get< tag::cmd, tag::io, tag::nrestart >();
+      g_trace = m_cmdline.get< tag::trace >();
+      tk::MainCtor( mainProxy, thisProxy, m_timer, m_cmdline,
+                    CkCallback( CkIndex_Main::quiescence(), thisProxy ) );
+    }
+
+    //! Execute driver created and initialized by constructor
+    void execute() {
+      try {
+        m_timestamp.emplace_back("Migrate global-scope data", m_timer[1].hms());
+        m_driver.execute();
+      } catch (...) { tk::processExceptionCharm(); }
+    }
+
+    //! Towards normal exit but collect chare state first (if any)
+    void finalize() {
+      tk::finalize( m_cmdline, m_timer, stateProxy, m_timestamp,
+        inciter::g_inputdeck_defaults.get< tag::cmd, tag::io, tag::screen >(),
+        inciter::g_inputdeck.get< tag::cmd, tag::io, tag::nrestart >(),
+        CkCallback( CkIndex_Main::dumpstate(nullptr), thisProxy ) );
+    }
+
+    //! Entry method triggered when quiescence is detected
+    void quiescence() {
+      try {
+        stateProxy.collect( /* error= */ true,
+          CkCallback( CkIndex_Main::dumpstate(nullptr), thisProxy ) );
+      } catch (...) { tk::processExceptionCharm(); }
+    }
+
+    //! Dump chare state
+    void dumpstate( CkReductionMsg* msg ) {
+      tk::dumpstate( m_cmdline,
+        inciter::g_inputdeck_defaults.get< tag::cmd, tag::io, tag::screen >(),
+        inciter::g_inputdeck.get< tag::cmd, tag::io, tag::nrestart >(),
+        msg );
+    }
+
+    /** @name Charm++ pack/unpack serializer member functions */
+    ///@{
+    //! \brief Pack/Unpack serialize member function
+    //! \param[in,out] p Charm++'s PUP::er serializer object reference
+    //! \note This is a Charm++ mainchare, pup() is thus only for
+    //!    checkpoint/restart.
+    void pup( PUP::er &p ) override {
+      p | m_timer;
+    }
+    //! \brief Pack/Unpack serialize operator|
+    //! \param[in,out] p Charm++'s PUP::er serializer object reference
+    //! \param[in,out] m Mainchare object reference
+    friend void operator|( PUP::er& p, Main& m ) { m.pup(p); }
+    //@}
+
+  private:
+    int m_signal;                               //!< Used to set signal handlers
+    inciter::ctr::CmdLine m_cmdline;            //!< Command line
+    inciter::CmdLineParser m_cmdParser;         //!< Command line parser
+    inciter::InciterDriver m_driver;            //!< Driver
+    std::vector< tk::Timer > m_timer;           //!< Timers
+    //! Time stamps in h:m:s with labels
+    std::vector< std::pair< std::string, tk::Timer::Watch > > m_timestamp;
+};
+
+//! \brief Charm++ chare execute
+//! \details By the time this object is constructed, the Charm++ runtime system
+//!    has finished migrating all global-scoped read-only objects which happens
+//!    after the main chare constructor has finished.
+class execute : public CBase_execute {
+  public:
+    //! Constructor
+    execute() { mainProxy.execute(); }
+    //! Migrate constructor
+    explicit execute( CkMigrateMessage* m ) : CBase_execute( m ) {}
+};
 
-    // Pass source and destination meshes to mesh transfer lib (if coupled)
-    Assert( m_nsrc < m_mytransfer.size(), "Indexing out of mytransfer[src]" );
-    if (fromMesh == m_meshid) {
-      exam2m::setSourceTets( thisProxy, thisIndex, &m_inpoel, &m_coord, u );
-      ++m_nsrc;
-    } else {
-      m_nsrc = 0;
-    }
-    Assert( m_ndst < m_mytransfer.size(), "Indexing out of mytransfer[dst]" );
-    if (toMesh == m_meshid) {
-      exam2m::setDestPoints( thisProxy, thisIndex, &m_coord, u,
-        cb_xfer );
-      ++m_ndst;<--- m_ndst is assigned
-    } else {
-      m_ndst = 0;
-    }
-
-  }
-
-  m_nsrc = 0;
-  m_ndst = 0;<--- m_ndst is overwritten
-}
-
-void Discretization::to_complete()
-// *****************************************************************************
-//! Solution transfer from background to overset mesh completed (from ExaM2M)
-//! \brief This is called by ExaM2M on the destination mesh when the
-//!   transfer completes. Since this is called only on the destination, we find
-//!   and notify the corresponding source of the completion.
-// *****************************************************************************
-{
-  // Lookup the source disc and notify it of completion
-  for (auto& t : m_transfer) {
-    if (m_meshid == t.dst) {
-      m_disc[ t.src ][ thisIndex ].transfer_complete();
-    }
-  }
-
-  thisProxy[ thisIndex ].transfer_complete();
-}
-
-void Discretization::from_complete()
-// *****************************************************************************
-//! Solution transfer from overset to background mesh completed (from ExaM2M)
-//! \brief This is called by ExaM2M on the destination mesh when the
-//!   transfer completes. Since this is called only on the destination, we find
-//!   and notify the corresponding source of the completion.
-// *****************************************************************************
-{
-  // Lookup the source disc and notify it of completion
-  for (auto& t : m_transfer) {
-    if (m_meshid == t.src) {
-      m_disc[ t.dst ][ thisIndex ].transfer_complete_from_dest();
-    }
-  }
-
-  m_transfer_complete.send();
-}
-
-void Discretization::transfer_complete_from_dest()
-// *****************************************************************************
-//! Solution transfer completed (from dest Discretization)
-//! \details Called on the source only by the destination when a back and forth
-//!   transfer step completes.
-// *****************************************************************************
-{
-  m_transfer_complete.send();
-}
-
-void Discretization::transfer_complete()
-// *****************************************************************************
-//! Solution transfer completed (one-way)
-//! \note Single exit point after solution transfer between meshes
-// *****************************************************************************
-{
-  contribute( sizeof(nullptr), nullptr, CkReduction::nop,
-    CkCallback(CkReductionTarget(Transporter,solutionTransferred),
-    m_transporter) );
-}
-
-std::vector< std::size_t >
-Discretization::bndel() const
-// *****************************************************************************
-// Find elements along our mesh chunk boundary
-//! \return List of local element ids that have at least a single node
-//!   contributing to a chare boundary
-// *****************************************************************************
-{
-  // Lambda to find out if a mesh node is shared with another chare
-  auto shared = [this]( std::size_t i ){
-    for (const auto& [c,n] : m_nodeCommMap)
-      if (n.find(i) != end(n)) return true;
-    return false;
-  };
-
-  // Find elements along our mesh chunk boundary
-  std::vector< std::size_t > e;
-  for (std::size_t n=0; n<m_inpoel.size(); ++n)
-    if (shared( m_gid[ m_inpoel[n] ] )) e.push_back( n/4 );
-  tk::unique( e );
-
-  return e;
-}
-
-void
-Discretization::resizePostAMR(
-  const tk::UnsMesh::Chunk& chunk,
-  const tk::UnsMesh::Coords& coord,
-  const std::unordered_map< std::size_t, std::size_t >& /*amrNodeMap*/,
-  const tk::NodeCommMap& nodeCommMap,
-  const std::set< std::size_t >& /*removedNodes*/,
-  const std::unordered_map< std::size_t, std::set< std::size_t > >& elemblockid )
-// *****************************************************************************
-//  Resize mesh data structures after mesh refinement
-//! \param[in] chunk New mesh chunk (connectivity and global<->local id maps)
-//! \param[in] coord New mesh node coordinates
-//! \param[in] amrNodeMap Node id map after amr (local ids)
-//! \param[in] nodeCommMap New node communication map
-//! \param[in] removedNodes Newly removed mesh node local ids
-//! \param[in] elemblockid New local tet ids associated with mesh block ids
-// *****************************************************************************
-{
-  m_el = chunk;         // updates m_inpoel, m_gid, m_lid
-  m_nodeCommMap.clear();
-  m_nodeCommMap = nodeCommMap;        // update node communication map
-  m_elemblockid.clear();
-  m_elemblockid = elemblockid;
-
-  // Update mesh volume container size
-  m_vol.resize( m_gid.size(), 0.0 );
-  if (!m_voln.empty()) m_voln.resize( m_gid.size(), 0.0 );
-
-  // Regenerate bid data
-  tk::destroy(m_bid);
-  m_bid = genBid();
-
-  // update mesh node coordinates
-  m_coord = coord;
-
-  // we are no longer during setup
-  m_initial = 0;
-}
-
-void
-Discretization::startvol()
-// *****************************************************************************
-//  Get ready for (re-)computing/communicating nodal volumes
-// *****************************************************************************
-{
-  m_nvol = 0;
-  thisProxy[ thisIndex ].wait4vol();
-
-  // Zero out mesh volume container
-  std::fill( begin(m_vol), end(m_vol), 0.0 );
-
-  // Clear receive buffer that will be used for collecting nodal volumes
-  m_volc.clear();
-}
-
-void
-Discretization::registerReducers()
-// *****************************************************************************
-//  Configure Charm++ reduction types
-//!  \details Since this is a [initnode] routine, see the .ci file, the
-//!   Charm++ runtime system executes the routine exactly once on every
-//!   logical node early on in the Charm++ init sequence. Must be static as
-//!   it is called without an object. See also: Section "Initializations at
-//!   Program Startup" at in the Charm++ manual
-//!   http://charm.cs.illinois.edu/manuals/html/charm++/manual.html.
-// *****************************************************************************
-{
-  PDFMerger = CkReduction::addReducer( tk::mergeUniPDFs );
-}
-
-tk::UnsMesh::Coords
-Discretization::setCoord( const tk::UnsMesh::CoordMap& coordmap )
-// *****************************************************************************
-// Set mesh coordinates based on coordinates map
-// *****************************************************************************
-{
-  Assert( coordmap.size() == m_gid.size(), "Size mismatch" );
-  Assert( coordmap.size() == m_lid.size(), "Size mismatch" );
-
-  tk::UnsMesh::Coords coord;
-  coord[0].resize( coordmap.size() );
-  coord[1].resize( coordmap.size() );
-  coord[2].resize( coordmap.size() );
-
-  for (const auto& [ gid, coords ] : coordmap) {
-    auto i = tk::cref_find( m_lid, gid );
-    coord[0][i] = coords[0];
-    coord[1][i] = coords[1];
-    coord[2][i] = coords[2];
-  }
-
-  return coord;
-}
-
-void
-Discretization::remap(
-  const std::unordered_map< std::size_t, std::size_t >& map )
-// *****************************************************************************
-//  Remap mesh data based on new local ids
-//! \param[in] map Mapping of old->new local ids
-// *****************************************************************************
-{
-  // Remap connectivity containing local IDs
-  for (auto& l : m_inpoel) l = tk::cref_find(map,l);
-
-  // Remap global->local id map
-  for (auto& [g,l] : m_lid) l = tk::cref_find(map,l);
-
-  // Remap global->local id map
-  auto maxid = std::numeric_limits< std::size_t >::max();
-  std::vector< std::size_t > newgid( m_gid.size(), maxid );
-  for (const auto& [o,n] : map) newgid[n] = m_gid[o];
-  m_gid = std::move( newgid );
-
-  Assert( std::all_of( m_gid.cbegin(), m_gid.cend(),
-            [=](std::size_t i){ return i < maxid; } ),
-          "Not all gid have been remapped" );
-
-  // Remap nodal volumes (with contributions along chare-boundaries)
-  std::vector< tk::real > newvol( m_vol.size(), 0.0 );
-  for (const auto& [o,n] : map) newvol[n] = m_vol[o];
-  m_vol = std::move( newvol );
-
-  // Remap nodal volumes (without contributions along chare-boundaries)
-  std::vector< tk::real > newv( m_v.size(), 0.0 );
-  for (const auto& [o,n] : map) newv[n] = m_v[o];
-  m_v = std::move( newv );
-
-  // Remap locations of node coordinates
-  tk::UnsMesh::Coords newcoord;
-  auto npoin = m_coord[0].size();
-  newcoord[0].resize( npoin );
-  newcoord[1].resize( npoin );
-  newcoord[2].resize( npoin );
-  for (const auto& [o,n] : map) {
-    newcoord[0][n] = m_coord[0][o];
-    newcoord[1][n] = m_coord[1][o];
-    newcoord[2][n] = m_coord[2][o];
-  }
-  m_coord = std::move( newcoord );
-}
-
-void
-Discretization::setRefiner( const CProxy_Refiner& ref )
-// *****************************************************************************
-//  Set Refiner Charm++ proxy
-//! \param[in] ref Incoming refiner proxy to store
-// *****************************************************************************
-{
-  m_refiner = ref;
-}
-
-void
-Discretization::vol()
-// *****************************************************************************
-// Sum mesh volumes to nodes, start communicating them on chare-boundaries
-// *****************************************************************************
-{
-  const auto& x = m_coord[0];
-  const auto& y = m_coord[1];
-  const auto& z = m_coord[2];
-
-  // Compute nodal volumes on our chunk of the mesh
-  for (std::size_t e=0; e<m_inpoel.size()/4; ++e) {
-    const std::array< std::size_t, 4 > N{{ m_inpoel[e*4+0], m_inpoel[e*4+1],
-                                           m_inpoel[e*4+2], m_inpoel[e*4+3] }};
-    // compute element Jacobi determinant * 5/120 = element volume / 4
-    const std::array< tk::real, 3 >
-      ba{{ x[N[1]]-x[N[0]], y[N[1]]-y[N[0]], z[N[1]]-z[N[0]] }},
-      ca{{ x[N[2]]-x[N[0]], y[N[2]]-y[N[0]], z[N[2]]-z[N[0]] }},
-      da{{ x[N[3]]-x[N[0]], y[N[3]]-y[N[0]], z[N[3]]-z[N[0]] }};
-    const auto J = tk::triple( ba, ca, da ) * 5.0 / 120.0;
-    ErrChk( J > 0, "Element Jacobian non-positive: PE:" +
-                   std::to_string(CkMyPe()) + ", node IDs: " +
-                   std::to_string(m_gid[N[0]]) + ',' +
-                   std::to_string(m_gid[N[1]]) + ',' +
-                   std::to_string(m_gid[N[2]]) + ',' +
-                   std::to_string(m_gid[N[3]]) + ", coords: (" +
-                   std::to_string(x[N[0]]) + ", " +
-                   std::to_string(y[N[0]]) + ", " +
-                   std::to_string(z[N[0]]) + "), (" +
-                   std::to_string(x[N[1]]) + ", " +
-                   std::to_string(y[N[1]]) + ", " +
-                   std::to_string(z[N[1]]) + "), (" +
-                   std::to_string(x[N[2]]) + ", " +
-                   std::to_string(y[N[2]]) + ", " +
-                   std::to_string(z[N[2]]) + "), (" +
-                   std::to_string(x[N[3]]) + ", " +
-                   std::to_string(y[N[3]]) + ", " +
-                   std::to_string(z[N[3]]) + ')' );
-    // scatter add V/4 to nodes
-    for (std::size_t j=0; j<4; ++j) m_vol[N[j]] += J;
-
-    // save element volumes at t=t0
-    if (m_it == 0) m_vol0[e] = J * 4.0;
-  }
-
-  // Store nodal volumes without contributions from other chares on
-  // chare-boundaries
-  m_v = m_vol;
-
-  // Send our nodal volume contributions to neighbor chares
-  if (m_nodeCommMap.empty())
-   totalvol();
-  else
-    for (const auto& [c,n] : m_nodeCommMap) {
-      std::vector< tk::real > v( n.size() );
-      std::size_t j = 0;
-      for (auto i : n) v[ j++ ] = m_vol[ tk::cref_find(m_lid,i) ];
-      thisProxy[c].comvol( std::vector<std::size_t>(begin(n), end(n)), v );
-    }
-
-  ownvol_complete();
-}
-
-void
-Discretization::comvol( const std::vector< std::size_t >& gid,
-                        const std::vector< tk::real >& nodevol )
-// *****************************************************************************
-//  Receive nodal volumes on chare-boundaries
-//! \param[in] gid Global mesh node IDs at which we receive volume contributions
-//! \param[in] nodevol Partial sums of nodal volume contributions to
-//!    chare-boundary nodes
-//! \details This function receives contributions to m_vol, which stores the
-//!   nodal volumes. While m_vol stores own contributions, m_volc collects the
-//!   neighbor chare contributions during communication. This way work on m_vol
-//!   and m_volc is overlapped. The contributions are applied in totalvol().
-// *****************************************************************************
-{
-  Assert( nodevol.size() == gid.size(), "Size mismatch" );
-
-  for (std::size_t i=0; i<gid.size(); ++i)
-    m_volc[ gid[i] ] += nodevol[i];
-
-  if (++m_nvol == m_nodeCommMap.size()) {
-    m_nvol = 0;
-    comvol_complete();
-  }
-}
-
-void
-Discretization::totalvol()
-// *****************************************************************************
-// Sum mesh volumes and contribute own mesh volume to total volume
-// *****************************************************************************
-{
-  // Add received contributions to nodal volumes
-  for (const auto& [gid, vol] : m_volc)
-    m_vol[ tk::cref_find(m_lid,gid) ] += vol;
-
-  // Clear receive buffer
-  tk::destroy(m_volc);
-
-  // Sum mesh volume to host
-  std::vector< tk::real > tvol{ 0.0,
-                                static_cast<tk::real>(m_initial),
-                                static_cast<tk::real>(m_meshid) };
-  for (auto v : m_v) tvol[0] += v;
-  contribute( tvol, CkReduction::sum_double,
-    CkCallback(CkReductionTarget(Transporter,totalvol), m_transporter) );
-}
-
-void
-Discretization::stat( tk::real mesh_volume )
-// *****************************************************************************
-// Compute mesh cell statistics
-//! \param[in] mesh_volume Total mesh volume
-// *****************************************************************************
-{
-  // Store total mesh volume
-  m_meshvol = mesh_volume;
-
-  const auto& x = m_coord[0];
-  const auto& y = m_coord[1];
-  const auto& z = m_coord[2];
-
-  auto MIN = -std::numeric_limits< tk::real >::max();
-  auto MAX = std::numeric_limits< tk::real >::max();
-  std::vector< tk::real > min{ MAX, MAX, MAX };
-  std::vector< tk::real > max{ MIN, MIN, MIN };
-  std::vector< tk::real > sum{ 0.0, 0.0, 0.0, 0.0, 0.0, 0.0 };
-  tk::UniPDF edgePDF( 1e-4 );
-  tk::UniPDF volPDF( 1e-4 );
-  tk::UniPDF ntetPDF( 1e-4 );
-
-  // Compute points surrounding points
-  auto psup = tk::genPsup( m_inpoel, 4, tk::genEsup(m_inpoel,4) );
-  Assert( psup.second.size()-1 == m_gid.size(),
-          "Number of mesh points and number of global IDs unequal" );
-
-  // Compute edge length statistics
-  // Note that while the min and max edge lengths are independent of the number
-  // of CPUs (by the time they are aggregated across all chares), the sum of
-  // the edge lengths and the edge length PDF are not. This is because the
-  // edges on the chare-boundary are counted multiple times and we
-  // conscientiously do not make an effort to precisely compute this, because
-  // that would require communication and more complex logic. Since these
-  // statistics are intended as simple average diagnostics, we ignore these
-  // small differences. For reproducible average edge lengths and edge length
-  // PDFs, run the mesh in serial.
-  for (std::size_t p=0; p<m_gid.size(); ++p)
-    for (auto i : tk::Around(psup,p)) {
-       const auto dx = x[ i ] - x[ p ];
-       const auto dy = y[ i ] - y[ p ];
-       const auto dz = z[ i ] - z[ p ];
-       const auto length = std::sqrt( dx*dx + dy*dy + dz*dz );
-       if (length < min[0]) min[0] = length;
-       if (length > max[0]) max[0] = length;
-       sum[0] += 1.0;
-       sum[1] += length;
-       edgePDF.add( length );
-    }
-
-  // Compute mesh cell volume statistics
-  for (std::size_t e=0; e<m_inpoel.size()/4; ++e) {
-    const std::array< std::size_t, 4 > N{{ m_inpoel[e*4+0], m_inpoel[e*4+1],
-                                           m_inpoel[e*4+2], m_inpoel[e*4+3] }};
-    const std::array< tk::real, 3 >
-      ba{{ x[N[1]]-x[N[0]], y[N[1]]-y[N[0]], z[N[1]]-z[N[0]] }},
-      ca{{ x[N[2]]-x[N[0]], y[N[2]]-y[N[0]], z[N[2]]-z[N[0]] }},
-      da{{ x[N[3]]-x[N[0]], y[N[3]]-y[N[0]], z[N[3]]-z[N[0]] }};
-    const auto L = std::cbrt( tk::triple( ba, ca, da ) / 6.0 );
-    if (L < min[1]) min[1] = L;
-    if (L > max[1]) max[1] = L;
-    sum[2] += 1.0;
-    sum[3] += L;
-    volPDF.add( L );
-  }
-
-  // Contribute stats of number of tetrahedra (ntets)
-  sum[4] = 1.0;
-  min[2] = max[2] = sum[5] = static_cast< tk::real >( m_inpoel.size() / 4 );
-  ntetPDF.add( min[2] );
-
-  min.push_back( static_cast<tk::real>(m_meshid) );
-  max.push_back( static_cast<tk::real>(m_meshid) );
-  sum.push_back( static_cast<tk::real>(m_meshid) );
-
-  // Contribute to mesh statistics across all Discretization chares
-  contribute( min, CkReduction::min_double,
-    CkCallback(CkReductionTarget(Transporter,minstat), m_transporter) );
-  contribute( max, CkReduction::max_double,
-    CkCallback(CkReductionTarget(Transporter,maxstat), m_transporter) );
-  contribute( sum, CkReduction::sum_double,
-    CkCallback(CkReductionTarget(Transporter,sumstat), m_transporter) );
-
-  // Serialize PDFs to raw stream
-  auto stream = tk::serialize( m_meshid, { edgePDF, volPDF, ntetPDF } );
-  // Create Charm++ callback function for reduction of PDFs with
-  // Transporter::pdfstat() as the final target where the results will appear.
-  CkCallback cb( CkIndex_Transporter::pdfstat(nullptr), m_transporter );
-  // Contribute serialized PDF of partial sums to host via Charm++ reduction
-  contribute( stream.first, stream.second.get(), PDFMerger, cb );
-}
-
-void
-Discretization::boxvol(
-  const std::vector< std::unordered_set< std::size_t > >& nodes,
-  const std::unordered_map< std::size_t, std::set< std::size_t > >& nodeblk,
-  std::size_t nuserblk )
-// *****************************************************************************
-// Compute total box IC volume
-//! \param[in] nodes Node list contributing to box IC volume (for each IC box)
-//! \param[in] nodeblk Node list associated to mesh blocks contributing to block
-//!   volumes (for each IC box)
-//! \param[in] nuserblk Number of user IC mesh blocks
-// *****************************************************************************
-{
-  // Compute partial box IC volume (just add up all boxes)
-  tk::real boxvol = 0.0;
-  for (const auto& b : nodes) for (auto i : b) boxvol += m_v[i];<--- Consider using std::accumulate algorithm instead of a raw loop.
-
-  // Compute partial IC mesh block volume
-  std::vector< tk::real > blockvols;
-  if (nuserblk > 0) {
-    blockvols.resize(nuserblk,0.0);
-    for (const auto& [blid, ndset] : nodeblk) {
-      // The following if-test makes sure we access volumes only of mesh blocks
-      // with user-specified ICs
-      if (blid < nuserblk) {
-        for (const auto& n : ndset) blockvols[blid] += m_v[n];
-      }
-    }
-  }
-
-  // Sum up box IC volume across all chares
-  auto meshdata = blockvols;
-  meshdata.push_back(boxvol);
-  meshdata.push_back(static_cast<tk::real>(m_meshid));
-  contribute( meshdata, CkReduction::sum_double,
-    CkCallback(CkReductionTarget(Transporter,boxvol), m_transporter) );
-}
-
-void
-Discretization::write(
-  const std::vector< std::size_t >& inpoel,
-  const tk::UnsMesh::Coords& coord,
-  const std::map< int, std::vector< std::size_t > >& bface,
-  const std::map< int, std::vector< std::size_t > >& bnode,
-  const std::vector< std::size_t >& triinpoel,
-  const std::vector< std::string>& elemfieldnames,
-  const std::vector< std::string>& nodefieldnames,
-  const std::vector< std::string>& elemsurfnames,
-  const std::vector< std::string>& nodesurfnames,
-  const std::vector< std::vector< tk::real > >& elemfields,
-  const std::vector< std::vector< tk::real > >& nodefields,
-  const std::vector< std::vector< tk::real > >& elemsurfs,
-  const std::vector< std::vector< tk::real > >& nodesurfs,
-  CkCallback c )
-// *****************************************************************************
-//  Output mesh and fields data (solution dump) to file(s)
-//! \param[in] inpoel Mesh connectivity for the mesh chunk to be written
-//! \param[in] coord Node coordinates of the mesh chunk to be written
-//! \param[in] bface Map of boundary-face lists mapped to corresponding side set
-//!   ids for this mesh chunk
-//! \param[in] bnode Map of boundary-node lists mapped to corresponding side set
-//!   ids for this mesh chunk
-//! \param[in] triinpoel Interconnectivity of points and boundary-face in this
-//!   mesh chunk
-//! \param[in] elemfieldnames Names of element fields to be output to file
-//! \param[in] nodefieldnames Names of node fields to be output to file
-//! \param[in] elemsurfnames Names of elemental surface fields to be output to
-//!   file
-//! \param[in] nodesurfnames Names of node surface fields to be output to file
-//! \param[in] elemfields Field data in mesh elements to output to file
-//! \param[in] nodefields Field data in mesh nodes to output to file
-//! \param[in] elemsurfs Surface field data in mesh elements to output to file
-//! \param[in] nodesurfs Surface field data in mesh nodes to output to file
-//! \param[in] c Function to continue with after the write
-//! \details Since m_meshwriter is a Charm++ chare group, it never migrates and
-//!   an instance is guaranteed on every PE. We index the first PE on every
-//!   logical compute node. In Charm++'s non-SMP mode, a node is the same as a
-//!   PE, so the index is the same as CkMyPe(). In SMP mode the index is the
-//!   first PE on every logical node. In non-SMP mode this yields one or more
-//!   output files per PE with zero or non-zero virtualization, respectively. If
-//!   there are multiple chares on a PE, the writes are serialized per PE, since
-//!   only a single entry method call can be executed at any given time. In SMP
-//!   mode, still the same number of files are output (one per chare), but the
-//!   output is serialized through the first PE of each compute node. In SMP
-//!   mode, channeling multiple files via a single PE on each node is required
-//!   by NetCDF and HDF5, as well as ExodusII, since none of these libraries are
-//!   thread-safe.
-// *****************************************************************************
-{
-  // If the previous iteration refined (or moved) the mesh or this is called
-  // before the first time step, we also output the mesh.
-  bool meshoutput = m_itf == 0 ? true : false;
-
-  auto eps = std::numeric_limits< tk::real >::epsilon();
-  bool fieldoutput = false;
-
-  // Output field data only if there is no dump at this physical time yet
-  if (std::abs(m_lastDumpTime - m_t) > eps ) {
-    m_lastDumpTime = m_t;
-    ++m_itf;
-    fieldoutput = true;
-  }
-
-  // set of sidesets where fieldoutput is required
-  std::set< int > outsets;
-  const auto& osv = g_inputdeck.get< tag::field_output, tag::sideset >();
-  outsets.insert(osv.begin(), osv.end());
-
-  m_meshwriter[ CkNodeFirst( CkMyNode() ) ].
-    write( m_meshid, meshoutput, fieldoutput, m_itr, m_itf, m_t, thisIndex,
-           g_inputdeck.get< tag::cmd, tag::io, tag::output >(),
-           inpoel, coord, bface, bnode, triinpoel, elemfieldnames,
-           nodefieldnames, elemsurfnames, nodesurfnames, elemfields, nodefields,
-           elemsurfs, nodesurfs, outsets, c );
-}
-
-void
-Discretization::setdt( tk::real newdt )
-// *****************************************************************************
-// Set time step size
-//! \param[in] newdt Size of the new time step
-// *****************************************************************************
-{
-  m_dtn = m_dt;
-  m_dt = newdt;
-
-  // Truncate the size of last time step
-  const auto term = g_inputdeck.get< tag::term >();
-  if (m_t+m_dt > term) m_dt = term - m_t;
-}
-
-void
-Discretization::next()
-// *****************************************************************************
-// Prepare for next step
-// *****************************************************************************
-{
-  // Update floor of physics time divided by output interval times
-  const auto eps = std::numeric_limits< tk::real >::epsilon();
-  const auto ft = g_inputdeck.get< tag::field_output, tag::time_interval >();
-  if (ft > eps) m_physFieldFloor = std::floor( m_t / ft );
-  const auto ht = g_inputdeck.get< tag::history_output, tag::time_interval >();
-  if (ht > eps) m_physHistFloor = std::floor( m_t / ht );
-
-  // Update floors of physics time divided by output interval times for ranges
-  const auto& rf = g_inputdeck.get< tag::field_output, tag::time_range >();
-  if (!rf.empty()) {
-    if (m_t > rf[0] and m_t < rf[1])
-      m_rangeFieldFloor = std::floor( m_t / rf[2] );
-    const auto& rh = g_inputdeck.get< tag::history_output, tag::time_range >();
-    if (m_t > rh[0] and m_t < rh[1])
-      m_rangeHistFloor = std::floor( m_t / rh[2] );
-  }
-
-  ++m_it;
-  m_t += m_dt;
-}
-
-void
-Discretization::grindZero()
-// *****************************************************************************
-//  Zero grind-time
-// *****************************************************************************
-{
-  m_prevstatus = std::chrono::high_resolution_clock::now();
-
-  if (thisIndex == 0 && m_meshid == 0) {
-    const auto verbose = g_inputdeck.get< tag::cmd, tag::verbose >();
-    const auto& def =
-      g_inputdeck_defaults.get< tag::cmd, tag::io, tag::screen >();
-    tk::Print print( g_inputdeck.get< tag::cmd >().logname( def, m_nrestart ),
-                     verbose ? std::cout : std::clog,
-                     std::ios_base::app );
-    print.diag( "Starting time stepping ..." );
-  }
-}
-
-bool
-Discretization::restarted( int nrestart )
-// *****************************************************************************
-//  Detect if just returned from a checkpoint and if so, zero timers
-//! \param[in] nrestart Number of times restarted
-//! \return True if restart detected
-// *****************************************************************************
-{
-  // Detect if just restarted from checkpoint:
-  //   nrestart == -1 if there was no checkpoint this step
-  //   d->Nrestart() == nrestart if there was a checkpoint this step
-  //   if both false, just restarted from a checkpoint
-  bool restarted = nrestart != -1 and m_nrestart != nrestart;
-
-   // If just restarted from checkpoint
-  if (restarted) {
-    // Update number of restarts
-    m_nrestart = nrestart;
-    // Start timer measuring time stepping wall clock time
-    m_timer.zero();
-    // Zero grind-timer
-    grindZero();
-  }
-
-  return restarted;
-}
-
-std::string
-Discretization::histfilename( const std::string& id,
-                              std::streamsize precision )
-// *****************************************************************************
-//  Construct history output filename
-//! \param[in] id History point id
-//! \param[in] precision Floating point precision to use for output
-//! \return History file name
-// *****************************************************************************
-{
-  auto of = g_inputdeck.get< tag::cmd, tag::io, tag::output >();
-  std::stringstream ss;
-
-  auto mid =
-    m_disc.size() > 1 ? std::string( '.' + std::to_string(m_meshid) ) : "";
-  ss << std::setprecision(static_cast<int>(precision)) << of << mid << ".hist." << id;
-
-  return ss.str();
-}
-
-void
-Discretization::histheader( std::vector< std::string >&& names )
-// *****************************************************************************
-//  Output headers for time history files (one for each point)
-//! \param[in] names History output variable names
-// *****************************************************************************
-{
-  for (const auto& h : m_histdata) {
-    auto prec = g_inputdeck.get< tag::history_output, tag::precision >();
-    tk::DiagWriter hw( histfilename( h.get< tag::id >(), prec ),
-                       g_inputdeck.get< tag::history_output, tag::format >(),
-                       prec );
-    hw.header( names );
-  }
-}
-
-void
-Discretization::history( std::vector< std::vector< tk::real > >&& data )
-// *****************************************************************************
-//  Output time history for a time step
-//! \param[in] data Time history data for all variables and equations integrated
-// *****************************************************************************
-{
-  Assert( data.size() == m_histdata.size(), "Size mismatch" );
-
-  std::size_t i = 0;
-  for (const auto& h : m_histdata) {
-    auto prec = g_inputdeck.get< tag::history_output, tag::precision >();
-    tk::DiagWriter hw( histfilename( h.get< tag::id >(), prec ),
-                       g_inputdeck.get< tag::history_output, tag::format >(),
-                       prec,
-                       std::ios_base::app );
-    hw.diag( m_it, m_t, m_dt, data[i] );
-    ++i;
-  }
-}
-
-bool
-Discretization::fielditer() const
-// *****************************************************************************
-//  Decide if field output iteration count interval is hit
-//! \return True if field output iteration count interval is hit
-// *****************************************************************************
-{
-  if (g_inputdeck.get< tag::cmd, tag::benchmark >()) return false;
-
-  return m_it % g_inputdeck.get< tag::field_output, tag::interval >() == 0;
-}
-
-bool
-Discretization::fieldtime() const
-// *****************************************************************************
-//  Decide if field output physics time interval is hit
-//! \return True if field output physics time interval is hit
-// *****************************************************************************
-{
-  if (g_inputdeck.get< tag::cmd, tag::benchmark >()) return false;
-
-  const auto eps = std::numeric_limits< tk::real >::epsilon();
-  const auto ft = g_inputdeck.get< tag::field_output, tag::time_interval >();
-
-  if (ft < eps) return false;
-
-  return std::floor(m_t/ft) - m_physFieldFloor > eps;
-}
-
-bool
-Discretization::fieldrange() const
-// *****************************************************************************
-//  Decide if physics time falls into a field output time range
-//! \return True if physics time falls into a field output time range
-// *****************************************************************************
-{
-  if (g_inputdeck.get< tag::cmd, tag::benchmark >()) return false;
-
-  const auto eps = std::numeric_limits< tk::real >::epsilon();
-
-  bool output = false;
-
-  const auto& rf = g_inputdeck.get< tag::field_output, tag::time_range >();
-  if (!rf.empty()) {
-    if (m_t > rf[0] and m_t < rf[1])
-      output |= std::floor(m_t/rf[2]) - m_rangeFieldFloor > eps;
-  }
-
-  return output;
-}
-
-bool
-Discretization::histiter() const
-// *****************************************************************************
-//  Decide if history output iteration count interval is hit
-//! \return True if history output iteration count interval is hit
-// *****************************************************************************
-{
-  const auto hist = g_inputdeck.get< tag::history_output, tag::interval >();
-  const auto& hist_points = g_inputdeck.get< tag::history_output, tag::point >();
-
-  return m_it % hist == 0 and not hist_points.empty();
-}
-
-bool
-Discretization::histtime() const
-// *****************************************************************************
-//  Decide if history output physics time interval is hit
-//! \return True if history output physics time interval is hit
-// *****************************************************************************
-{
-  if (g_inputdeck.get< tag::cmd, tag::benchmark >()) return false;
-
-  const auto eps = std::numeric_limits< tk::real >::epsilon();
-  const auto ht = g_inputdeck.get< tag::history_output, tag::time_interval >();
-
-  if (ht < eps) return false;
-
-  return std::floor(m_t/ht) - m_physHistFloor > eps;
-}
-
-bool
-Discretization::histrange() const
-// *****************************************************************************
-//  Decide if physics time falls into a history output time range
-//! \return True if physics time falls into a history output time range
-// *****************************************************************************
-{
-  if (g_inputdeck.get< tag::cmd, tag::benchmark >()) return false;
-
-  const auto eps = std::numeric_limits< tk::real >::epsilon();
-
-  bool output = false;
-
-  const auto& rh = g_inputdeck.get< tag::history_output, tag::time_range >();
-  if (!rh.empty()) {
-    if (m_t > rh[0] and m_t < rh[1])
-      output |= std::floor(m_t/rh[2]) - m_rangeHistFloor > eps;
-  }
-
-  return output;
-}
-
-bool
-Discretization::finished() const
-// *****************************************************************************
-//  Decide if this is the last time step
-//! \return True if this is the last time step
-// *****************************************************************************
-{
-  const auto eps = std::numeric_limits< tk::real >::epsilon();
-  const auto nstep = g_inputdeck.get< tag::nstep >();
-  const auto term = g_inputdeck.get< tag::term >();
-
-  return std::abs(m_t-term) < eps or m_it >= nstep;
-}
-
-void
-Discretization::status()
-// *****************************************************************************
-// Output one-liner status report
-// *****************************************************************************
-{
-  // Query after how many time steps user wants TTY dump
-  const auto tty = g_inputdeck.get< tag::ttyi >();
-
-  // estimate grind time (taken between this and the previous time step)
-  using std::chrono::duration_cast;
-  using ms = std::chrono::milliseconds;
-  using clock = std::chrono::high_resolution_clock;
-  auto grind_time = duration_cast< ms >(clock::now() - m_prevstatus).count();
-  m_prevstatus = clock::now();
-
-  if (thisIndex==0 and m_meshid == 0 and not (m_it%tty)) {
-
-    const auto term = g_inputdeck.get< tag::term >();
-    const auto t0 = g_inputdeck.get< tag::t0 >();
-    const auto nstep = g_inputdeck.get< tag::nstep >();
-    const auto diag = g_inputdeck.get< tag::diagnostics, tag::interval >();
-    const auto lbfreq = g_inputdeck.get< tag::cmd, tag::lbfreq >();
-    const auto rsfreq = g_inputdeck.get< tag::cmd, tag::rsfreq >();
-    const auto verbose = g_inputdeck.get< tag::cmd, tag::verbose >();
-    const auto benchmark = g_inputdeck.get< tag::cmd, tag::benchmark >();
-    const auto steady = g_inputdeck.get< tag::steady_state >();
-
-    // estimate time elapsed and time for accomplishment
-    tk::Timer::Watch ete, eta;
-    if (not steady) m_timer.eta( term-t0, m_t-t0, nstep, m_it, ete, eta );
-
-    const auto& def =
-      g_inputdeck_defaults.get< tag::cmd, tag::io, tag::screen >();
-    tk::Print print( g_inputdeck.get< tag::cmd >().logname( def, m_nrestart ),
-                     verbose ? std::cout : std::clog,
-                     std::ios_base::app );
-
-    // Output one-liner
-    print << std::setfill(' ') << std::setw(8) << m_it << "  "
-          << std::scientific << std::setprecision(6)
-          << std::setw(12) << m_t << "  "
-          << m_dt << "  "
-          << std::setfill('0')
-          << std::setw(3) << ete.hrs.count() << ":"
-          << std::setw(2) << ete.min.count() << ":"
-          << std::setw(2) << ete.sec.count() << "  "
-          << std::setw(3) << eta.hrs.count() << ":"
-          << std::setw(2) << eta.min.count() << ":"
-          << std::setw(2) << eta.sec.count() << "  "
-          << std::scientific << std::setprecision(6) << std::setfill(' ')
-          << std::setw(9) << grind_time << "  ";
-
-    // Augment one-liner status with output indicators
-    if (fielditer() or fieldtime() or fieldrange()) print << 'f';
-    if (not (m_it % diag)) print << 'd';
-    if (histiter() or histtime() or histrange()) print << 't';
-    if (m_refined) print << 'h';
-    if (not (m_it % lbfreq) && not finished()) print << 'l';
-    if (not benchmark && (not (m_it % rsfreq) || finished())) print << 'r';
-
-    if (not m_meshvel_converged) print << 'a';
-    m_meshvel_converged = true; // get ready for next time step
-
-    print << std::endl;
-  }
-}
-
-#include "NoWarning/discretization.def.h"
+#include "NoWarning/inciter.def.h"
 
diff --git a/Debug/cppcheck/35.html b/Debug/cppcheck/35.html index d8e7874b9852..8bc5410c346e 100644 --- a/Debug/cppcheck/35.html +++ b/Debug/cppcheck/35.html @@ -152,12 +152,12 @@
  1
@@ -394,375 +394,241 @@ 

Cppcheck report - [

// *****************************************************************************
+235
// *****************************************************************************
 /*!
-  \file      src/Inciter/Ghosts.hpp
+  \file      src/Inciter/ElemDiagnostics.cpp
   \copyright 2012-2015 J. Bakosi,
              2016-2018 Los Alamos National Security, LLC.,
              2019-2021 Triad National Security, LLC.
              All rights reserved. See the LICENSE file for details.
-  \brief     Declarations file for generating ghost data structures
-  \details   Declarations file for asynchronous distributed
-             ghost data structures using Charm++.
-
-    There are a potentially large number of Ghosts Charm++ chares.
-    Each Ghosts chare gets a chunk of the full load, due to partiting the mesh.
+  \brief     ElemDiagnostics class for collecting element diagnostics
+  \details   ElemDiagnostics class for collecting element diagnostics, e.g.,
+    residuals, and various norms of errors while solving partial differential
+    equations.
+*/
+// *****************************************************************************
 
-    The implementation uses the Charm++ runtime system and is fully
-    asynchronous, overlapping computation and communication. The algorithm
-    utilizes the structured dagger (SDAG) Charm++ functionality.
-*/
-// *****************************************************************************
-#ifndef Ghosts_h
-#define Ghosts_h
-
-#include "Fields.hpp"
-#include "FaceData.hpp"
-#include "Discretization.hpp"
+#include <array>
+#include <vector>
+#include <cmath>
+
+#include "DGPDE.hpp"
+#include "ElemDiagnostics.hpp"
+#include "DiagReducer.hpp"
+#include "Discretization.hpp"
+#include "Integrate/Basis.hpp"
+#include "Integrate/Quadrature.hpp"
+#include "Inciter/InputDeck/InputDeck.hpp"
 
-#include "NoWarning/ghosts.decl.h"
+namespace inciter {
 
-namespace inciter {
-
-//! Ghosts Charm++ chare array used to determine ghost data structures
-class Ghosts : public CBase_Ghosts {
+extern ctr::InputDeck g_inputdeck;
+extern std::vector< DGPDE > g_dgpde;
+
+static CkReduction::reducerType DiagMerger;
 
-  public:
-    #if defined(__clang__)
-      #pragma clang diagnostic push
-      #pragma clang diagnostic ignored "-Wunused-parameter"
-      #pragma clang diagnostic ignored "-Wdeprecated-declarations"
-    #elif defined(STRICT_GNUC)
-      #pragma GCC diagnostic push
-      #pragma GCC diagnostic ignored "-Wunused-parameter"
-      #pragma GCC diagnostic ignored "-Wdeprecated-declarations"
-    #elif defined(__INTEL_COMPILER)
-      #pragma warning( push )
-      #pragma warning( disable: 1478 )
-    #endif
-    // Include Charm++ SDAG code. See http://charm.cs.illinois.edu/manuals/html/
-    // charm++/manual.html, Sec. "Structured Control Flow: Structured Dagger".
-    Ghosts_SDAG_CODE
-    #if defined(__clang__)
-      #pragma clang diagnostic pop
-    #elif defined(STRICT_GNUC)
-      #pragma GCC diagnostic pop
-    #elif defined(__INTEL_COMPILER)
-      #pragma warning( pop )
-    #endif
-
-    //! Constructor
-    explicit
-    Ghosts( const CProxy_Discretization& disc,
-      const std::map< int, std::vector< std::size_t > >& bface,
-      const std::vector< std::size_t >& triinpoel,
-      std::size_t nunk,
-      CkCallback cbDone );
-
-    #if defined(__clang__)
-      #pragma clang diagnostic push
-      #pragma clang diagnostic ignored "-Wundefined-func-template"
-    #endif
-    //! Migrate constructor
-    // cppcheck-suppress uninitMemberVar
-    explicit Ghosts( CkMigrateMessage* ) {}
-    #if defined(__clang__)
-      #pragma clang diagnostic pop
-    #endif
-
-    //! Local face & tet IDs associated to 3 global node IDs
-    //! \details This map stores tetrahedron cell faces (map key) and their
-    //!   associated local face ID and inner local tet id adjacent to the face
-    //!   (map value). A face is given by 3 global node IDs.
-    using FaceMap =
-      std::unordered_map< tk::UnsMesh::Face,  // 3 global node IDs
-                          std::array< std::size_t, 2 >, // local face & tet ID
-                          tk::UnsMesh::Hash<3>,
-                          tk::UnsMesh::Eq<3> >;
-
-    //! Storage type for refined mesh used for field output
-    struct OutMesh {
-      //! Element connectivity, local->global node ids, global->local nodes ids
-      tk::UnsMesh::Chunk chunk;
-      //! Node coordinates
-      tk::UnsMesh::Coords coord;
-      //! Triangle element connectivity
-      std::vector< std::size_t > triinpoel;
-      //! Boundary-face connectivity
-      std::map< int, std::vector< std::size_t > > bface;
-      //! Node communinaction map
-      tk::NodeCommMap nodeCommMap;
-      //! \brief Pack/Unpack serialize member function
-      //! \param[in,out] p Charm++'s PUP::er serializer object reference
-      void pup( PUP::er& p ) {<--- Parameter 'p' can be declared with const
-        p|chunk; p|coord; p|triinpoel; p|bface; p|nodeCommMap;
-      }
-      //! Destroyer
-      void destroy() {
-        tk::destroy( std::get<0>(chunk) );
-        tk::destroy( std::get<1>(chunk) );
-        tk::destroy( std::get<2>(chunk) );
-        tk::destroy( coord[0] );
-        tk::destroy( coord[1] );
-        tk::destroy( coord[2] );
-        tk::destroy( triinpoel );
-        tk::destroy( bface );
-        tk::destroy( nodeCommMap );
-      }
-    };
-
-    //! Discretization proxy
-    CProxy_Discretization m_disc;
-    //! Counter for number of unknowns on this chare (including ghosts)
-    std::size_t m_nunk;
-    //! Mesh connectivity extended
-    std::vector< std::size_t > m_inpoel;
-    //! Node coordinates extended
-    tk::UnsMesh::Coords m_coord;
-    //! Face data
-    FaceData m_fd;
-    //! Face geometry
-    tk::Fields m_geoFace;
-    //! Element geometry
-    tk::Fields m_geoElem;
-    //! Counter for number of faces on this chare (including chare boundaries)
-    std::size_t m_nfac;
-    //! Face & tet IDs associated to global node IDs of the face for each chare
-    //! \details This map stores not only the unique faces associated to
-    //!   fellow chares, but also a newly assigned local face ID and adjacent
-    //!   local tet ID.
-    std::unordered_map< int, FaceMap > m_bndFace;
-    //! Elements which are ghosts for other chares associated to those chare IDs
-    std::unordered_map< int, std::unordered_set< std::size_t > > m_sendGhost;
-    //! Local element id associated to ghost remote id charewise
-    //! \details This map associates the local element id (inner map value) to
-    //!    the (remote) element id of the ghost (inner map key) based on the
-    //!    chare id (outer map key) this remote element lies in.
-    std::unordered_map< int,
-      std::unordered_map< std::size_t, std::size_t > > m_ghost;
-    //! Expected ghost tet ids (used only in DEBUG)
-    std::set< std::size_t > m_exptGhost;
-    //! Map local ghost tet ids (value) and zero-based boundary ids (key)
-    std::unordered_map< std::size_t, std::size_t > m_bid;
-    //! Elements (value) surrounding point (key) data-structure
-    std::map< std::size_t, std::vector< std::size_t > > m_esup;
-    //! 1 if starting time stepping, 0 if during time stepping
-    std::size_t m_initial;
-
-    //1 Start setup of communication maps for cell-centered schemes
-    void startCommSetup();
+} // inciter::
+
+using inciter::ElemDiagnostics;
+
+void
+ElemDiagnostics::registerReducers()
+// *****************************************************************************
+//  Configure Charm++ reduction types
+//! \details This routine is supposed to be called from a Charm++ initnode
+//!   routine. Since the runtime system executes initnode routines exactly once
+//!   on every logical node early on in the Charm++ init sequence, they must be
+//!   static as they are called without an object. See also: Section
+//!   "Initializations at Program Startup" at in the Charm++ manual
+//!   http://charm.cs.illinois.edu/manuals/html/charm++/manual.html.
+// *****************************************************************************
+{
+  DiagMerger = CkReduction::addReducer( mergeDiag );
+}
+
+bool
+ElemDiagnostics::compute( Discretization& d,
+                          const std::size_t nchGhost,
+                          const tk::Fields& geoElem,
+                          const std::vector< std::size_t >& ndofel,
+                          const tk::Fields& u,
+                          const tk::Fields& un ) const
+// *****************************************************************************
+//  Compute diagnostics, e.g., residuals, norms of errors, etc.
+//! \param[in] d Discretization base class to read from
+//! \param[in] nchGhost Number of chare boundary ghost elements
+//! \param[in] geoElem Element geometry
+//! \param[in] ndofel Vector of local number of degrees of freedom
+//! \param[in] u Current solution vector
+//! \param[in] un Previous time-step solution vector
+//! \return True if diagnostics have been computed
+//! \details Diagnostics are defined as some norm, e.g., L2 norm, of a quantity,
+//!    computed in mesh elements, A, as ||A||_2 = sqrt[ sum_i(A_i)^2 V_i ],
+//!    where the sum is taken over all mesh elements and V_i is the cell volume.
+//!    We send multiple sets of quantities to the host for aggregation across
+//!    the whole mesh. The final aggregated solution will end up in
+//!    Transporter::diagnostics(). Aggregation of the partially computed
+//!    diagnostics is done via potentially different policies for each field.
+//! \see inciter::mergeDiag(), src/Inciter/Diagnostics.h
+// *****************************************************************************
+{
+  // Optionally collect diagnostics and send for aggregation across all workers
+
+  // Query after how many time steps user wants to dump diagnostics
+  auto diagfreq = g_inputdeck.get< tag::diagnostics, tag::interval >();
+
+  if ( !((d.It()+1) % diagfreq) || d.finished() ) {  // if remainder, don't compute diagnostics
+
+    // Query number of degrees of freedom from user's setting
+    const auto rdof = g_inputdeck.get< tag::rdof >();
+
+    // Diagnostics vector (of vectors) during aggregation. See
+    // Inciter/Diagnostics.h.
+    std::vector< std::vector< tk::real > >
+      diag( NUMDIAG, std::vector< tk::real >( u.nprop()/rdof, 0.0 ) );
+
+    // Compute diagnostics for DG
+    compute_diag(d, rdof, nchGhost, geoElem, ndofel, u, un, diag);
+
+    // Append diagnostics vector with metadata on the current time step
+    // ITER: Current iteration count (only the first entry is used)
+    // TIME: Current physical time (only the first entry is used)
+    // DT: Current physical time step size (only the first entry is used)
+    diag[ITER][0] = static_cast< tk::real >( d.It() );
+    diag[TIME][0] = d.T();
+    diag[DT][0] = d.Dt();
+
+    // Contribute to diagnostics
+    auto stream = serialize( d.MeshId(), u.nprop()/rdof, diag );
+    d.contribute( stream.first, stream.second.get(), DiagMerger,
+      CkCallback(CkIndex_Transporter::diagnostics(nullptr), d.Tr()) );
+
+    return true;        // diagnostics have been computed
+
+  }
+
+  return false;         // diagnostics have not been computed
+}
+
+void
+ElemDiagnostics::compute_diag( const Discretization& d,<--- Function 'compute_diag' argument order different: declaration 'd, ndofel, nchGhost, geoElem, pIndex, u, un, diag' definition 'd, rdof, nchGhost, geoElem, ndofel, u, un, diag'
+                               const std::size_t rdof,
+                               const std::size_t nchGhost,
+                               const tk::Fields& geoElem,
+                               const std::vector< std::size_t >& ndofel,
+                               const tk::Fields& u,
+                               const tk::Fields& un,
+                               std::vector< std::vector< tk::real > >& diag )
+const
+// *****************************************************************************
+//  Compute diagnostics, e.g., residuals, norms of errors, etc. for DG
+//! \param[in] d Discretization base class to read from
+//! \param[in] rdof Number of reconstructed degrees of freedom
+//! \param[in] nchGhost Number of chare boundary ghost elements
+//! \param[in] geoElem Element geometry
+//! \param[in] ndofel Vector of local number of degrees of freedom
+//! \param[in] u Current solution vector
+//! \param[in] un Previous time-step solution vector
+//! \param[in,out] diag Diagnostics vector
+// *****************************************************************************
+{
+  const auto& inpoel = d.Inpoel();
+  const auto& coord = d.Coord();
+
+  const auto& cx = coord[0];
+  const auto& cy = coord[1];
+  const auto& cz = coord[2];
+
+  for (std::size_t e=0; e<u.nunk()-nchGhost; ++e)
+  {
+    std::size_t dofe(1);
+    if (!ndofel.empty()) {
+      dofe = ndofel[e];
+    }
+    // Number of quadrature points for volume integration
+    auto ng = tk::NGdiag(dofe);
+
+    // arrays for quadrature points
+    std::array< std::vector< tk::real >, 3 > coordgp;
+    std::vector< tk::real > wgp;
 
-    //! Start sizing communication buffers and setting up ghost data
-    void resizeComm();
-
-    //! Receive unique set of faces we potentially share with/from another chare
-    void comfac( int fromch, const tk::UnsMesh::FaceSet& infaces );
-
-    //! Receive ghost data on chare boundaries from fellow chare
-    void comGhost( int fromch, const GhostData& ghost );
-
-    //! Receive requests for ghost data
-    void reqGhost();
-
-    //! Send all of our ghost data to fellow chares
-    void sendGhost();
-
-    //! Setup node-neighborhood (esup)
-    void nodeNeighSetup();
-
-    //! Receive element-surr-points data on chare boundaries from fellow chare
-    void comEsup( int fromch,
-      const std::unordered_map< std::size_t, std::vector< std::size_t > >&
-        bndEsup,
-      const std::unordered_map< std::size_t, std::vector< tk::real > >&
-        nodeBndCells );
+    coordgp[0].resize( ng );
+    coordgp[1].resize( ng );
+    coordgp[2].resize( ng );
+    wgp.resize( ng );
+
+    tk::GaussQuadratureTet( ng, coordgp, wgp );
+
+    // Extract the element coordinates
+    std::array< std::array< tk::real, 3>, 4 > coordel {{
+      {{ cx[ inpoel[4*e  ] ], cy[ inpoel[4*e  ] ], cz[ inpoel[4*e  ] ] }},
+      {{ cx[ inpoel[4*e+1] ], cy[ inpoel[4*e+1] ], cz[ inpoel[4*e+1] ] }},
+      {{ cx[ inpoel[4*e+2] ], cy[ inpoel[4*e+2] ], cz[ inpoel[4*e+2] ] }},
+      {{ cx[ inpoel[4*e+3] ], cy[ inpoel[4*e+3] ], cz[ inpoel[4*e+3] ] }} }};
+
+    for (std::size_t igp=0; igp<ng; ++igp)
+    {
+      // Compute the coordinates of quadrature point at physical domain
+      auto gp = tk::eval_gp( igp, coordel, coordgp );
+
+      // Compute the basis function
+      auto B = tk::eval_basis( dofe, coordgp[0][igp], coordgp[1][igp],
+                               coordgp[2][igp]);
+
+      auto wt = wgp[igp] * geoElem(e, 0);
 
-    /** @name Pack/unpack (Charm++ serialization) routines */
-    ///@{
-    //! \brief Pack/Unpack serialize member function
-    //! \param[in,out] p Charm++'s PUP::er serializer object reference
-    void pup( PUP::er &p ) override {
-      p | m_disc;
-      p | m_nunk;
-      p | m_inpoel;
-      p | m_coord;
-      p | m_fd;
-      p | m_geoFace;
-      p | m_geoElem;
-      p | m_nfac;
-      p | m_bndFace;
-      p | m_sendGhost;
-      p | m_ghost;
-      p | m_exptGhost;
-      p | m_bid;
-      p | m_esup;
-      p | m_initial;
-      p | m_ncomfac;
-      p | m_nadj;
-      p | m_ncomEsup;
-      p | m_ipface;
-      p | m_ghostData;
-      p | m_ghostReq;
-      p | m_expChBndFace;
-      p | m_infaces;
-      p | m_esupc;
-      p | m_cbAfterDone;
-    }
-    //! \brief Pack/Unpack serialize operator|
-    //! \param[in,out] p Charm++'s PUP::er serializer object reference
-    //! \param[in,out] a Ghosts object reference
-    friend void operator|( PUP::er& p, Ghosts& a ) { a.pup(p); }
-    ///@}
-
-  private:
-    using ncomp_t = tk::ncomp_t;
-
-    //! Counter for face adjacency communication map
-    std::size_t m_ncomfac;
-    //! Counter signaling that all ghost data have been received
-    std::size_t m_nadj;
-    //! Counter for element-surr-node adjacency communication map
-    std::size_t m_ncomEsup;
-    //! Internal + physical boundary faces (inverse of inpofa)
-    tk::UnsMesh::FaceSet m_ipface;
-    //! Ghost data associated to chare IDs we communicate with
-    std::unordered_map< int, GhostData > m_ghostData;
-    //! Number of chares requesting ghost data
-    std::size_t m_ghostReq;
-    //! Unique set of chare-boundary faces this chare is expected to receive
-    tk::UnsMesh::FaceSet m_expChBndFace;
-    //! Incoming communication buffer during chare-boundary face communication
-    std::unordered_map< int, tk::UnsMesh::FaceSet > m_infaces;
-    //! Communication buffer for esup data-structure
-    std::map< std::size_t, std::vector< std::size_t > > m_esupc;
-    //! Function call to continue with in Scheme when Ghosts is done
-    CkCallback m_cbAfterDone;
-
-    //! Access bound Discretization class pointer
-    Discretization* Disc() const {
-      Assert( m_disc[ thisIndex ].ckLocal() != nullptr, "ckLocal() null" );
-      return m_disc[ thisIndex ].ckLocal();
-    }
-
-    //! Compute chare-boundary faces
-    void bndFaces();
-
-    //! Setup own ghost data on this chare
-    void setupGhost();
-
-    //! Continue after face adjacency communication map completed on this chare
-    void faceAdj();
-
-    //! Compute partial boundary surface integral and sum across all chares
-    void bndIntegral();
-
-    //! Continue after node adjacency communication map completed on this chare
-    void adj();
-
-    //! Perform leak-test on chare boundary faces
-    bool leakyAdjacency();
-
-    //! Check if esuf of chare-boundary faces matches
-    bool faceMatch();
-
-    //! Verify that all chare-boundary faces have been received
-    bool receivedChBndFaces();
-
-    //! Find any chare for face (given by 3 global node IDs)
-    int findchare( const tk::UnsMesh::Face& t );
-
-    //! Check if entries in inpoel, inpofa and node-triplet are consistent
-    std::size_t nodetripletMatch(
-      const std::array< std::size_t, 2 >& id,
-      const tk::UnsMesh::Face& t );
-
-    //! Fill elements surrounding a face along chare boundary
-    void addEsuf(
-      const std::array< std::size_t, 2 >& id,
-      std::size_t ghostid );
-
-    //! Fill elements surrounding a element along chare boundary
-    void addEsuel(
-      const std::array< std::size_t, 2 >& id,
-      std::size_t ghostid,
-      const tk::UnsMesh::Face& t );
-
-    //! Fill face-geometry data along chare boundary
-    void addGeoFace(
-      const tk::UnsMesh::Face& t,
-      const std::array< std::size_t, 2 >& id );
-};
-
-} // inciter::
-
-#endif // Ghosts_h
+      std::vector< tk::real > s;
+
+      // cppcheck-suppress useStlAlgorithm
+      s = g_dgpde[d.MeshId()].solution( gp[0], gp[1], gp[2], d.T() );<--- Unmatched suppression: useStlAlgorithm
+
+      for (std::size_t c=0; c<u.nprop()/rdof; ++c)
+      {
+        auto mark = c*rdof;
+        auto ugp = u(e, mark);
+
+        if(dofe > 1)
+        {
+          ugp +=  u(e, mark+1) * B[1]
+                + u(e, mark+2) * B[2]
+                + u(e, mark+3) * B[3];
+
+          if(dofe > 4)
+          {
+            ugp +=  u(e, mark+4) * B[4]
+                  + u(e, mark+5) * B[5]
+                  + u(e, mark+6) * B[6]
+                  + u(e, mark+7) * B[7]
+                  + u(e, mark+8) * B[8]
+                  + u(e, mark+9) * B[9];
+          }
+        }
+
+        // Compute sum for L2 norm of the numerical solution
+        diag[L2SOL][c] += wt * ugp * ugp;
+
+        // Compute sum for L2 norm of the numerical-analytic solution
+        diag[L2ERR][c] += wt * (ugp-s[c]) * (ugp-s[c]);
+
+        // Compute max for Linf norm of the numerical-analytic solution
+        auto err = std::abs( ugp - s[c] );
+        if (err > diag[LINFERR][c]) diag[LINFERR][c] = err;
+      }
+    }
+    tk::real sp_te(0.0);
+    // cppcheck-suppress useStlAlgorithm
+    sp_te += g_dgpde[d.MeshId()].sp_totalenergy(e, u);<--- Unmatched suppression: useStlAlgorithm
+
+    // Compute sum of the total energy over the entire domain (only the
+    // first entry is used)
+    diag[TOTALSOL][0] += geoElem(e,0) * sp_te;
+
+    // Compute sum for L2 norm of the cell-avg residual
+    for (std::size_t c=0; c<u.nprop()/rdof; ++c)
+      diag[L2RES][c] += geoElem(e, 0) *
+        ( (u(e,c*rdof)-un(e,c*rdof)) * (u(e,c*rdof)-un(e,c*rdof)) );
+  }
+}
 
diff --git a/Debug/cppcheck/36.html b/Debug/cppcheck/36.html index 394418cea451..48038da0da77 100644 --- a/Debug/cppcheck/36.html +++ b/Debug/cppcheck/36.html @@ -152,12 +152,12 @@
  1
@@ -279,526 +279,126 @@ 

Cppcheck report - [

// *****************************************************************************
+120
// *****************************************************************************
 /*!
-  \file      src/Inciter/Scheme.hpp
+  \file      src/Main/InciterPrint.hpp
   \copyright 2012-2015 J. Bakosi,
              2016-2018 Los Alamos National Security, LLC.,
              2019-2021 Triad National Security, LLC.
              All rights reserved. See the LICENSE file for details.
-  \brief     Polymorphic glue for calling Charm++ entry methods to base class
-    Discretization, its children implementing specific discretization schemes,
-    and helper classes
-  \details
-    The purpose of this class is to hide, behind a single type, different
-    Charm++  proxy types that model a single concept, i.e., define some common
-    functions as Charm++ entry methods that can be used in either a broadcast
-    and/or in a way of addressing a single array element. As a result, member
-    functions can be invoked by client code without knowing the underlying type
-    or any specifics to the underlying differences of the classes that model the
-    same concept, i.e., expose the same member functions. The idea is very
-    similar to inheritance and runtime polymorphism with base classes and
-    virtual functions: some member functions and data are common to all types
-    modeled (and thus are not repeated and/or copied), while some are specific.
-    A difference is that the "base" and "child" classes are Charm++ proxies.
-    Note that while Charm++ does support inheritance and runtime polymorphism
-    with chare arrays, we still prefer the implementation below because it uses
-    entirely value semantics (inside and in client code) and thus it keeps the
-    complexity of the dispatch behind this class and does not expose it to
-    client code.
-
-    The advantages of this class over traditional runtime polymorphism are (1)
-    value semantics (both internally and to client code), (2) not templated,
-    and (3) PUPable, i.e., an instance of Scheme can be sent across the network
-    using Charm++'s pup framework. Also, since the class only holds a couple of
-    chare proxies, it is lightweight.
-
-    Example usage from client code:
-
-    \code{.cpp}
-      // Instantiate a Scheme object
-      Scheme s( ctr::SchemeType::DG );  // see Control/Inciter/Options/Scheme.h
-
-      // Issue broadcast to child scheme entry method
-      s.bcast< Scheme::setup >(...);
-
-      // Issue broadcast to base (Discretization) entry method
-      s.disc().totalvol();
-    \endcode
+  \brief     Inciter-specific pretty printer functionality
+  \details   Inciter-specific pretty printer functionality.
+*/
+// *****************************************************************************
+#ifndef InciterPrint_h
+#define InciterPrint_h
+
+#include <iostream>
+#include <string>
+
+#include "NoWarning/format.hpp"
+
+#include "Print.hpp"
+#include "ContainerUtil.hpp"
+#include "Inciter/InputDeck/InputDeck.hpp"
+#include "Inciter/Options/Physics.hpp"
+#include "Inciter/Options/Problem.hpp"
+
+namespace inciter {
+
+extern ctr::InputDeck g_inputdeck_defaults;
+extern ctr::InputDeck g_inputdeck;
+
+//! InciterPrint : tk::Print
+class InciterPrint : public tk::Print {
+
+  public:
+    //! Constructor
+    //! \param[in] screen Screen output filename
+    //! \param[in,out] str Verbose stream
+    //! \param[in] mode Open mode for screen output file, see
+    //!   http://en.cppreference.com/w/cpp/io/ios_base/openmode
+    //! \param[in,out] qstr Quiet stream
+    //! \see tk::RNGPrint::RNGPrint and tk::Print::Print
+    explicit InciterPrint( const std::string& screen,
+                           std::ostream& str = std::clog,
+                           std::ios_base::openmode mode = std::ios_base::out,
+                           std::ostream& qstr = std::cout ) :
+      Print( screen, str, mode, qstr ) {}
 
-    Organization, implementation details, end extension of the class:
-
-    Scheme contains (at least) two Charm++ proxies: discproxy and proxy. The
-    former contains data and functionality common to all discretizations, and
-    this can be considered as an equivalent to a base class in the OOP sense.
-    The latter, proxy, contains data and functionality specific to a particular
-    discretization. When instantiated, Scheme is configured for a single
-    specific discretization which must be selected from the list of types in
-    SchemeBase::Proxy.
-
-    The underlying type of proxy is a variant, which allows storing exactly one
-    object. A variant is a type-safe union. An instance of a variant at any
-    given time either holds a value of one of its alternative types. Read more
-    on std::variant on how they work.
-
-    Adding a new child scheme is done by
-    (1) Adding a new type of Charm++ chare array proxy to Scheme::Proxy,
-    (2) Adding a new type of Charm++ chare array element proxy to
-        Scheme::ProxyElem, and
-    (3) Adding a new branch to the if test in Scheme's constructor.
-
-  \see A talk on "Concept-based runtime polymorphism with Charm++ chare arrays
-    using value semantics given by J. Bakosi at the 16th Annual Workshop on
-    Charm++ and its Applications, April 2018, discussing an earlier, more
-    verbose implementation of the idea, using C++11.
-*/
-// *****************************************************************************
-#ifndef Scheme_h
-#define Scheme_h
-
-#include "Exception.hpp"
-#include "PUPUtil.hpp"
-#include "Inciter/Options/Scheme.hpp"
-
-#include "NoWarning/discretization.decl.h"
-#include "NoWarning/alecg.decl.h"
-#include "NoWarning/oversetfe.decl.h"
-#include "NoWarning/dg.decl.h"
-#include "NoWarning/fv.decl.h"
-#include "NoWarning/ale.decl.h"
-#include "NoWarning/conjugategradients.decl.h"
-#include "NoWarning/ghosts.decl.h"
-
-namespace inciter {
-
-//! Base class for generic forwarding interface to discretization proxies
-class Scheme {
+    //! Print control option: 'group : option'
+    template< typename Option, typename... tags >
+    void Item() const {
+      Option opt;
+      m_stream << m_item_name_value_fmt
+                  % m_item_indent % opt.group()
+                  % opt.name( g_inputdeck.get< tags... >() );
+    }
+
+    // Helper class for compact output of PDE policies
+    class Policies {
+      public:
+        // Default constructor
+        explicit Policies() : phys(), prob() {}
+        // Initializer constructor
+        explicit Policies( const std::string& p, const std::string& t ) :
+          phys(p), prob(t) {}
+        // Operator += for adding up two Policies structs
+        Policies& operator+= ( const Policies& p ) {
+          phys += p.phys;
+          prob += p.prob;
+          return *this;
+        }
+
+      private:
+        // Make all policies unique
+        void unique() { tk::unique( phys ); tk::unique( prob ); }
+
+        std::string phys;
+        std::string prob;
+    };
+
+    //! Print equation list with policies
+    //! \param[in] t Section title
+    //! \param[in] factory Factory to get equation data from
+    //! \param[in] ntypes Unique equation types
+    template< class Factory >
+    void eqlist( const std::string& t,
+                 const Factory& factory,
+                 std::size_t ntypes ) const
+    {
+      if (!factory.empty()) {
+        section( t );
+        item( "Unique equation types", ntypes );
+        item( "With all policy combinations", factory.size() );
+      }
+    }
 
-  private:
-    //! Variant type listing all chare proxy types modeling the same concept
-    using Proxy = std::variant< CProxy_DG
-                              , CProxy_ALECG
-                              , CProxy_OversetFE
-                              , CProxy_FV >;
-
-  public:
-    //! Variant type listing all chare element proxy types
-    using ProxyElem = std::variant< CProxy_DG::element_t
-                                  , CProxy_ALECG::element_t
-                                  , CProxy_OversetFE::element_t
-                                  , CProxy_FV::element_t >;
-
-    //! Empty constructor for Charm++
-    explicit Scheme() {}
-
-    //! Constructor
-    //! \param[in] scheme Discretization scheme
-    //! \param[in] ale True if enable ALE
-    //! \param[in] linearsolver True if enable a linear solver
-    //! \details Based on the input enum we create at least two empty chare
-    //!   arrays: (1) discproxy which contains common functionality and data for
-    //!   all discretizations, and (2) proxy, which have functionality and data
-    //!   specific to a given discretization. Note that proxy is bound (in
-    //!   migration behavior and properties) to discproxy.
-    //! \note There may be other bound proxy arrays created depending on the
-    //!   specific discretization configured by the enum.
-    explicit Scheme( ctr::SchemeType scheme,
-                     bool ale = false,
-                     bool linearsolver = false,
-                     tk::Centering centering = tk::Centering::NODE ) :
-      discproxy( CProxy_Discretization::ckNew() )
-    {
-      bound.bindTo( discproxy );
-      if (scheme == ctr::SchemeType::DG ||
-                 scheme == ctr::SchemeType::P0P1 ||
-                 scheme == ctr::SchemeType::DGP1 ||
-                 scheme == ctr::SchemeType::DGP2 ||
-                 scheme == ctr::SchemeType::PDG)
-      {
-        proxy = static_cast< CProxy_DG >( CProxy_DG::ckNew(bound) );
-      } else if (scheme == ctr::SchemeType::ALECG) {
-        proxy = static_cast< CProxy_ALECG >( CProxy_ALECG::ckNew(bound) );
-      } else if (scheme == ctr::SchemeType::OversetFE) {
-        proxy = static_cast< CProxy_OversetFE >( CProxy_OversetFE::ckNew(bound) );
-      } else if (scheme == ctr::SchemeType::FV) {
-        proxy = static_cast< CProxy_FV >( CProxy_FV::ckNew(bound) );
-      } else Throw( "Unknown discretization scheme" );
-      if (ale) aleproxy = CProxy_ALE::ckNew(bound);
-      if (linearsolver)
-        conjugategradientsproxy = tk::CProxy_ConjugateGradients::ckNew(bound);
-      if (centering == tk::Centering::ELEM)
-        ghostsproxy = CProxy_Ghosts::ckNew(bound);
-    }
-
-    //! Entry method tags for specific Scheme classes to use with bcast()
-    struct setup {};
-    struct box {};
-    struct transferSol {};
-    struct advance {};
-    struct resized {};
-    struct resizeComm {};
-    struct refine {};
-    struct lhs {};
-    struct nodeNeighSetup {};
-    struct diag {};
-    struct evalLB {};
-    struct doneInserting {};
-    //! Issue broadcast to Scheme entry method
-    //! \tparam Fn Function tag identifying the entry method to call
-    //! \tparam Args Types of arguments to pass to entry method
-    //! \param[in] args Arguments to member function entry method to be called
-    //! \details This function issues a broadcast to a member function entry
-    //!   method of the Scheme chare array (the child of Discretization) and is
-    //!   thus equivalent to proxy.Fn(...).
-    template< typename Fn, typename... Args >
-    void bcast( Args&&... args ) {
-      std::visit( [&]( auto& p ){<--- Parameter 'p' can be declared with const
-          if constexpr( std::is_same_v< Fn, setup > )
-            p.setup( std::forward< Args >( args )... );
-          if constexpr( std::is_same_v< Fn, box > )
-            p.box( std::forward< Args >( args )... );
-          else if constexpr( std::is_same_v< Fn, transferSol > )
-            p.transferSol( std::forward< Args >( args )... );
-          else if constexpr( std::is_same_v< Fn, advance > )
-            p.advance( std::forward< Args >( args )... );
-          else if constexpr( std::is_same_v< Fn, resized > )
-            p.resized( std::forward< Args >( args )... );
-          else if constexpr( std::is_same_v< Fn, resizeComm > )
-            p.resizeComm( std::forward< Args >( args )... );
-          else if constexpr( std::is_same_v< Fn, refine > )
-            p.refine( std::forward< Args >( args )... );
-          else if constexpr( std::is_same_v< Fn, lhs > )
-            p.lhs( std::forward< Args >( args )... );
-          else if constexpr( std::is_same_v< Fn, nodeNeighSetup > )
-            p.nodeNeighSetup( std::forward< Args >( args )... );
-          else if constexpr( std::is_same_v< Fn, diag > )
-            p.diag( std::forward< Args >( args )... );
-          else if constexpr( std::is_same_v< Fn, evalLB > )
-            p.evalLB( std::forward< Args >( args )... );
-          else if constexpr( std::is_same_v< Fn, doneInserting > )
-            p.doneInserting( std::forward< Args >( args )... );
-        }, proxy );
-    }
-
-    //! Function tags for specific Scheme classes to use with ckLocal()
-    struct resizePostAMR {};
-    struct extractFieldOutput {};
-    struct solution {};
-    //! Call Scheme function via Charm++ chare array element's ckLocal()
-    //! \tparam Fn Function tag identifying the function to call
-    //! \tparam Args Types of arguments to pass to function
-    //! \param[in] x Chare array element index
-    //! \param[in] args Arguments to member function function to be called
-    //! \details This function calls a member function via Charm++'s ckLocal()
-    //!    behind the element proxy configured, indexed by the array index x.
-    //!    Since the call is behind ckLocal(), the member function does not have
-    //!    to be a Charm++ entry method.
-    template< typename Fn, typename... Args >
-    auto ckLocal( const CkArrayIndex1D& x, Args&&... args ) const {
-      auto e = element( x );
-      return std::visit( [&]( auto& p ){
-          if constexpr( std::is_same_v< Fn, resizePostAMR > )
-            return p.ckLocal()->resizePostAMR( std::forward<Args>(args)... );
-          else if constexpr( std::is_same_v< Fn, extractFieldOutput > )
-            return p.ckLocal()->extractFieldOutput(std::forward<Args>(args)...);
-          else if constexpr( std::is_same_v< Fn, solution > )
-            return p.ckLocal()->solution( std::forward<Args>(args)... );
-        }, e );
-    }
-
-    //! Function to call the insert entry method of an element proxy
-    //! \param[in] x Chare array element index
-    //! \param[in] args Arguments to member function (entry method) to be called
-    //! \details This function calls the insert member function of a chare array
-    //!   element proxy and thus equivalent to proxy[x].insert(...), using the
-    //!   last argument as default.
-    template< typename... Args >
-    void insert( const CkArrayIndex1D& x, Args&&... args ) {
-      auto e = element( x );
-      std::visit( [&]( auto& p ){ p.insert(std::forward<Args>(args)...); }, e );<--- Parameter 'p' can be declared with const
-    }
-
-    //! Get reference to discretization proxy
-    //! \return Discretization Charm++ chare array proxy
-    CProxy_Discretization& disc() noexcept { return discproxy; }
-
-    //! Get reference to ALE proxy
-    //! \return ALE Charm++ chare array proxy
-    CProxy_ALE& ale() noexcept { return aleproxy; }
-
-    //! Get reference to ConjugateGradients proxy
-    //! \return ConjugateGradients Charm++ chare array proxy
-    tk::CProxy_ConjugateGradients& conjugategradients() noexcept
-    { return conjugategradientsproxy; }
-
-    //! Get reference to Ghosts proxy
-    //! \return Ghosts Charm++ chare array proxy
-    CProxy_Ghosts& ghosts() noexcept { return ghostsproxy; }
-
-    //! Get reference to scheme proxy
-    //! Get reference to scheme proxy
-    //! \return Variant storing Charm++ chare array proxy configured
-    const Proxy& getProxy() noexcept { return proxy; }
-
-    //! Query underlying proxy type
-    //! \return Zero-based index into the set of types of Proxy
-    std::size_t index() const noexcept { return proxy.index(); }
-
-    //! Query underlying proxy element type
-    //! \return Zero-based index that can be used, e.g., indexing into the set
-    //!   of types of ProxyElem
-    std::size_t index_element() const noexcept { return element(0).index(); }
-
-    //! Charm++ array options accessor for binding external proxies
-    //! \return Charm++ array options object reference
-    const CkArrayOptions& arrayoptions() { return bound; }
-
-    /** @name Charm++ pack/unpack serializer member functions */
-    ///@{
-    //! \brief Pack/Unpack serialize member function
-    //! \param[in,out] p Charm++'s PUP::er serializer object reference
-    void pup( PUP::er &p ) {<--- Parameter 'p' can be declared with const
-      p | proxy;
-      p | discproxy;
-      p | aleproxy;
-      p | conjugategradientsproxy;
-      p | ghostsproxy;
-      p | bound;
-    }
-    //! \brief Pack/Unpack serialize operator|
-    //! \param[in,out] p Charm++'s PUP::er serializer object reference
-    //! \param[in,out] s Scheme object reference
-    friend void operator|( PUP::er& p, Scheme& s ) { s.pup(p); }
-    //@}
-
-  private:
-    //! Variant storing one proxy to which this class is configured for
-    Proxy proxy;
-    //! Charm++ proxy to data and code common to all discretizations
-    CProxy_Discretization discproxy;
-    //! Charm++ proxy to ALE class
-    CProxy_ALE aleproxy;
-    //! Charm++ proxy to conjugate gradients linear solver class
-    tk::CProxy_ConjugateGradients conjugategradientsproxy;
-    //! Charm++ proxy to Ghosts class
-    CProxy_Ghosts ghostsproxy;
-    //! Charm++ array options for binding chares
-    CkArrayOptions bound;
-
-    //! Function dereferencing operator[] of chare proxy inside variant
-    //! \param[in] x Chare array element index
-    //! \return Chare array element proxy as a variant, defined by ProxyElem
-    //! \details The returning element proxy is a variant, depending on the
-    //!   input proxy.
-    ProxyElem element( const CkArrayIndex1D& x ) const {
-      return std::visit( [&]( const auto& p ){
-               return static_cast< ProxyElem >( p[x] ); }, proxy );
-    }
-};
-
-} // inciter::
-
-#endif // Scheme_h
+    //! Print configuration of a stack of partial differential equations
+    void pdes( const std::string& t,
+      const std::vector< std::vector< std::pair< std::string, std::string > > >&
+        info ) const;
+
+    //! Print out info on solver coupling
+    void couple( const std::vector< Transfer >& transfer,
+                 const std::vector< char >& depvar ) const;
+
+    //! Print time integration header
+    void inthead( const std::string& t, const std::string& name,
+                  const std::string& legend, const std::string& head ) const;
+
+  private:
+    //! Return partial differential equation name
+    //! \param[in] key Equation key
+    //! \return Partial differential equation name based on key
+    template< class Key >
+    std::string PDEName ( const Key& key ) const<--- Unused private function: 'InciterPrint::PDEName'
+    { return ctr::PDE().name( key.template get< tag::pde >() ); }
+};
+
+} // inciter::
+
+#endif // InciterPrint_h
 
diff --git a/Debug/cppcheck/37.html b/Debug/cppcheck/37.html index d88cdd172deb..0d2b44a3b8aa 100644 --- a/Debug/cppcheck/37.html +++ b/Debug/cppcheck/37.html @@ -152,1259 +152,2505 @@
- - + @@ -89,18 +89,18 @@ 15 : : friend std::ostream& operator<<(std::ostream&, const edge_t&); 16 : : 17 : : public: - 18 : 6181777 : edge_& get_data() { - 19 : 6181777 : return data; + 18 : 6058714 : edge_& get_data() { + 19 : 6058714 : return data; 20 : : } 21 : : - 22 : 5273904152 : const edge_& get_data() const { - 23 : 5273904152 : return data; + 22 : 5271764584 : const edge_& get_data() const { + 23 : 5271764584 : return data; 24 : : } 25 : : 26 : : // Constructors - 27 : 32347938 : edge_t() - 28 : 32347938 : { - 29 : 32347938 : } + 27 : 32306917 : edge_t() + 28 : 32306917 : { + 29 : 32306917 : } 30 : : 31 : 27961662 : edge_t(size_t A, size_t B) : data( {{std::min(A,B), std::max(A,B)}} ) 32 : : { @@ -130,23 +130,23 @@ 55 : : //{ 56 : : // return (data > rhs.get_data()); 57 : : //} - 58 : 1318476038 : bool operator<(const edge_t& rhs) const + 58 : 1317941146 : bool operator<(const edge_t& rhs) const 59 : : { 60 : : // ensure entries of rhs and this are in ascending order - 61 : 1318476038 : auto this_copy = this->data; - 62 : 1318476038 : this_copy[0] = std::min(this->data[0], this->data[1]); - 63 : 1318476038 : this_copy[1] = std::max(this->data[0], this->data[1]); + 61 : 1317941146 : auto this_copy = this->data; + 62 : 1317941146 : this_copy[0] = std::min(this->data[0], this->data[1]); + 63 : 1317941146 : this_copy[1] = std::max(this->data[0], this->data[1]); 64 : : std::array< std::size_t, 2 > rhs_copy; - 65 : 1318476038 : rhs_copy[0] = std::min(rhs.get_data()[0], rhs.get_data()[1]); - 66 : 1318476038 : rhs_copy[1] = std::max(rhs.get_data()[0], rhs.get_data()[1]); + 65 : 1317941146 : rhs_copy[0] = std::min(rhs.get_data()[0], rhs.get_data()[1]); + 66 : 1317941146 : rhs_copy[1] = std::max(rhs.get_data()[0], rhs.get_data()[1]); 67 : : - 68 [ + + ]: 1318476038 : if (this_copy[0] < rhs_copy[0]) - 69 : 462239919 : return true; - 70 [ + + ][ + + ]: 856236119 : else if (this_copy[0] == rhs_copy[0] && this_copy[1] < rhs_copy[1]) - [ + + ] - 71 : 166118659 : return true; + 68 [ + + ]: 1317941146 : if (this_copy[0] < rhs_copy[0]) + 69 : 462909364 : return true; + 70 [ + + ][ + + ]: 855031782 : else if (this_copy[0] == rhs_copy[0] && this_copy[1] < rhs_copy[1]) + [ + + ] + 71 : 166047165 : return true; 72 : : else - 73 : 690117460 : return false; + 73 : 688984617 : return false; 74 : : } 75 : : 76 : 8378276 : size_t first() const diff --git a/Debug/test_coverage/Inciter/AMR/edge_store.hpp.func-sort-c.html b/Debug/test_coverage/Inciter/AMR/edge_store.hpp.func-sort-c.html index 213386840d6a..a45b4a98f92a 100644 --- a/Debug/test_coverage/Inciter/AMR/edge_store.hpp.func-sort-c.html +++ b/Debug/test_coverage/Inciter/AMR/edge_store.hpp.func-sort-c.html @@ -33,7 +33,7 @@ - + diff --git a/Debug/test_coverage/Inciter/AMR/edge_store.hpp.func.html b/Debug/test_coverage/Inciter/AMR/edge_store.hpp.func.html index 47d234e2ab19..07a1dcc90de2 100644 --- a/Debug/test_coverage/Inciter/AMR/edge_store.hpp.func.html +++ b/Debug/test_coverage/Inciter/AMR/edge_store.hpp.func.html @@ -33,7 +33,7 @@ - + diff --git a/Debug/test_coverage/Inciter/AMR/edge_store.hpp.gcov.html b/Debug/test_coverage/Inciter/AMR/edge_store.hpp.gcov.html index 5b1591d50bfe..055ed7b1f789 100644 --- a/Debug/test_coverage/Inciter/AMR/edge_store.hpp.gcov.html +++ b/Debug/test_coverage/Inciter/AMR/edge_store.hpp.gcov.html @@ -33,7 +33,7 @@ - + diff --git a/Debug/test_coverage/Inciter/AMR/id_generator.hpp.func-sort-c.html b/Debug/test_coverage/Inciter/AMR/id_generator.hpp.func-sort-c.html index 2eb51263db7f..64a9681ef5d9 100644 --- a/Debug/test_coverage/Inciter/AMR/id_generator.hpp.func-sort-c.html +++ b/Debug/test_coverage/Inciter/AMR/id_generator.hpp.func-sort-c.html @@ -33,7 +33,7 @@ - + @@ -73,7 +73,7 @@ - + diff --git a/Debug/test_coverage/Inciter/AMR/id_generator.hpp.func.html b/Debug/test_coverage/Inciter/AMR/id_generator.hpp.func.html index 4742a9c07960..926226fc682f 100644 --- a/Debug/test_coverage/Inciter/AMR/id_generator.hpp.func.html +++ b/Debug/test_coverage/Inciter/AMR/id_generator.hpp.func.html @@ -33,7 +33,7 @@ - + @@ -81,7 +81,7 @@ - +
  1
-  2
-  3
-  4
-  5
-  6
-  7
-  8
-  9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
- 37
- 38
- 39
- 40
- 41
- 42
- 43
- 44
- 45
- 46
- 47
- 48
- 49
- 50
- 51
- 52
- 53
- 54
- 55
- 56
- 57
- 58
- 59
- 60
- 61
- 62
- 63
- 64
- 65
- 66
- 67
- 68
- 69
- 70
- 71
- 72
- 73
- 74
- 75
- 76
- 77
- 78
- 79
- 80
- 81
- 82
- 83
- 84
- 85
- 86
- 87
- 88
- 89
- 90
- 91
- 92
- 93
- 94
- 95
- 96
- 97
- 98
- 99
-100
-101
-102
-103
-104
-105
-106
-107
-108
-109
-110
-111
-112
-113
-114
-115
-116
-117
-118
-119
-120
-121
-122
-123
-124
-125
-126
-127
-128
-129
-130
-131
-132
-133
-134
-135
-136
-137
-138
-139
-140
-141
-142
-143
-144
-145
-146
-147
-148
-149
-150
-151
-152
-153
-154
-155
-156
-157
-158
-159
-160
-161
-162
-163
-164
-165
-166
-167
-168
-169
-170
-171
-172
-173
-174
-175
-176
-177
-178
-179
-180
-181
-182
-183
-184
-185
-186
-187
-188
-189
-190
-191
-192
-193
-194
-195
-196
-197
-198
-199
-200
-201
-202
-203
-204
-205
-206
-207
-208
-209
-210
-211
-212
-213
-214
-215
-216
-217
-218
-219
-220
-221
-222
-223
-224
-225
-226
-227
-228
-229
-230
-231
-232
-233
-234
-235
-236
-237
-238
-239
-240
-241
-242
-243
-244
-245
-246
-247
-248
-249
-250
-251
-252
-253
-254
-255
-256
-257
-258
-259
-260
-261
-262
-263
-264
-265
-266
-267
-268
-269
-270
-271
-272
-273
-274
-275
-276
-277
-278
-279
-280
-281
-282
-283
-284
-285
-286
-287
-288
-289
-290
-291
-292
-293
-294
-295
-296
-297
-298
-299
-300
-301
-302
-303
-304
-305
-306
-307
-308
-309
-310
-311
-312
-313
-314
-315
-316
-317
-318
-319
-320
-321
-322
-323
-324
-325
-326
-327
-328
-329
-330
-331
-332
-333
-334
-335
-336
-337
-338
-339
-340
-341
-342
-343
-344
-345
-346
-347
-348
-349
-350
-351
-352
-353
-354
-355
-356
-357
-358
-359
-360
-361
-362
-363
-364
-365
-366
-367
-368
-369
-370
-371
-372
-373
-374
-375
-376
-377
-378
-379
-380
-381
-382
-383
-384
-385
-386
-387
-388
-389
-390
-391
-392
-393
-394
-395
-396
-397
-398
-399
-400
-401
-402
-403
-404
-405
-406
-407
-408
-409
-410
-411
-412
-413
-414
-415
-416
-417
-418
-419
-420
-421
-422
-423
-424
-425
-426
-427
-428
-429
-430
-431
-432
-433
-434
-435
-436
-437
-438
-439
-440
-441
-442
-443
-444
-445
-446
-447
-448
-449
-450
-451
-452
-453
-454
-455
-456
-457
-458
-459
-460
-461
-462
-463
-464
-465
-466
-467
-468
-469
-470
-471
-472
-473
-474
-475
-476
-477
-478
-479
-480
-481
-482
-483
-484
-485
-486
-487
-488
-489
-490
-491
-492
-493
-494
-495
-496
-497
-498
-499
-500
-501
-502
-503
-504
-505
-506
-507
-508
-509
-510
-511
-512
-513
-514
-515
-516
-517
-518
-519
-520
-521
-522
-523
-524
-525
-526
-527
-528
-529
-530
-531
-532
-533
-534
-535
-536
-537
-538
-539
-540
-541
-542
-543
-544
-545
-546
-547
-548
-549
-550
-551
-552
-553
-554
-555
-556
-557
-558
-559
-560
-561
-562
-563
-564
-565
-566
-567
-568
-569
-570
-571
-572
-573
-574
-575
-576
-577
-578
-579
-580
-581
-582
-583
-584
-585
-586
-587
-588
-589
-590
-591
-592
-593
-594
-595
-596
-597
-598
-599
-600
-601
-602
-603
-604
-605
-606
-607
-608
-609
-610
-611
-612
-613
-614
-615
-616
-617
-618
-619
-620
-621
-622
-623
// *****************************************************************************
+
   1
+   2
+   3
+   4
+   5
+   6
+   7
+   8
+   9
+  10
+  11
+  12
+  13
+  14
+  15
+  16
+  17
+  18
+  19
+  20
+  21
+  22
+  23
+  24
+  25
+  26
+  27
+  28
+  29
+  30
+  31
+  32
+  33
+  34
+  35
+  36
+  37
+  38
+  39
+  40
+  41
+  42
+  43
+  44
+  45
+  46
+  47
+  48
+  49
+  50
+  51
+  52
+  53
+  54
+  55
+  56
+  57
+  58
+  59
+  60
+  61
+  62
+  63
+  64
+  65
+  66
+  67
+  68
+  69
+  70
+  71
+  72
+  73
+  74
+  75
+  76
+  77
+  78
+  79
+  80
+  81
+  82
+  83
+  84
+  85
+  86
+  87
+  88
+  89
+  90
+  91
+  92
+  93
+  94
+  95
+  96
+  97
+  98
+  99
+ 100
+ 101
+ 102
+ 103
+ 104
+ 105
+ 106
+ 107
+ 108
+ 109
+ 110
+ 111
+ 112
+ 113
+ 114
+ 115
+ 116
+ 117
+ 118
+ 119
+ 120
+ 121
+ 122
+ 123
+ 124
+ 125
+ 126
+ 127
+ 128
+ 129
+ 130
+ 131
+ 132
+ 133
+ 134
+ 135
+ 136
+ 137
+ 138
+ 139
+ 140
+ 141
+ 142
+ 143
+ 144
+ 145
+ 146
+ 147
+ 148
+ 149
+ 150
+ 151
+ 152
+ 153
+ 154
+ 155
+ 156
+ 157
+ 158
+ 159
+ 160
+ 161
+ 162
+ 163
+ 164
+ 165
+ 166
+ 167
+ 168
+ 169
+ 170
+ 171
+ 172
+ 173
+ 174
+ 175
+ 176
+ 177
+ 178
+ 179
+ 180
+ 181
+ 182
+ 183
+ 184
+ 185
+ 186
+ 187
+ 188
+ 189
+ 190
+ 191
+ 192
+ 193
+ 194
+ 195
+ 196
+ 197
+ 198
+ 199
+ 200
+ 201
+ 202
+ 203
+ 204
+ 205
+ 206
+ 207
+ 208
+ 209
+ 210
+ 211
+ 212
+ 213
+ 214
+ 215
+ 216
+ 217
+ 218
+ 219
+ 220
+ 221
+ 222
+ 223
+ 224
+ 225
+ 226
+ 227
+ 228
+ 229
+ 230
+ 231
+ 232
+ 233
+ 234
+ 235
+ 236
+ 237
+ 238
+ 239
+ 240
+ 241
+ 242
+ 243
+ 244
+ 245
+ 246
+ 247
+ 248
+ 249
+ 250
+ 251
+ 252
+ 253
+ 254
+ 255
+ 256
+ 257
+ 258
+ 259
+ 260
+ 261
+ 262
+ 263
+ 264
+ 265
+ 266
+ 267
+ 268
+ 269
+ 270
+ 271
+ 272
+ 273
+ 274
+ 275
+ 276
+ 277
+ 278
+ 279
+ 280
+ 281
+ 282
+ 283
+ 284
+ 285
+ 286
+ 287
+ 288
+ 289
+ 290
+ 291
+ 292
+ 293
+ 294
+ 295
+ 296
+ 297
+ 298
+ 299
+ 300
+ 301
+ 302
+ 303
+ 304
+ 305
+ 306
+ 307
+ 308
+ 309
+ 310
+ 311
+ 312
+ 313
+ 314
+ 315
+ 316
+ 317
+ 318
+ 319
+ 320
+ 321
+ 322
+ 323
+ 324
+ 325
+ 326
+ 327
+ 328
+ 329
+ 330
+ 331
+ 332
+ 333
+ 334
+ 335
+ 336
+ 337
+ 338
+ 339
+ 340
+ 341
+ 342
+ 343
+ 344
+ 345
+ 346
+ 347
+ 348
+ 349
+ 350
+ 351
+ 352
+ 353
+ 354
+ 355
+ 356
+ 357
+ 358
+ 359
+ 360
+ 361
+ 362
+ 363
+ 364
+ 365
+ 366
+ 367
+ 368
+ 369
+ 370
+ 371
+ 372
+ 373
+ 374
+ 375
+ 376
+ 377
+ 378
+ 379
+ 380
+ 381
+ 382
+ 383
+ 384
+ 385
+ 386
+ 387
+ 388
+ 389
+ 390
+ 391
+ 392
+ 393
+ 394
+ 395
+ 396
+ 397
+ 398
+ 399
+ 400
+ 401
+ 402
+ 403
+ 404
+ 405
+ 406
+ 407
+ 408
+ 409
+ 410
+ 411
+ 412
+ 413
+ 414
+ 415
+ 416
+ 417
+ 418
+ 419
+ 420
+ 421
+ 422
+ 423
+ 424
+ 425
+ 426
+ 427
+ 428
+ 429
+ 430
+ 431
+ 432
+ 433
+ 434
+ 435
+ 436
+ 437
+ 438
+ 439
+ 440
+ 441
+ 442
+ 443
+ 444
+ 445
+ 446
+ 447
+ 448
+ 449
+ 450
+ 451
+ 452
+ 453
+ 454
+ 455
+ 456
+ 457
+ 458
+ 459
+ 460
+ 461
+ 462
+ 463
+ 464
+ 465
+ 466
+ 467
+ 468
+ 469
+ 470
+ 471
+ 472
+ 473
+ 474
+ 475
+ 476
+ 477
+ 478
+ 479
+ 480
+ 481
+ 482
+ 483
+ 484
+ 485
+ 486
+ 487
+ 488
+ 489
+ 490
+ 491
+ 492
+ 493
+ 494
+ 495
+ 496
+ 497
+ 498
+ 499
+ 500
+ 501
+ 502
+ 503
+ 504
+ 505
+ 506
+ 507
+ 508
+ 509
+ 510
+ 511
+ 512
+ 513
+ 514
+ 515
+ 516
+ 517
+ 518
+ 519
+ 520
+ 521
+ 522
+ 523
+ 524
+ 525
+ 526
+ 527
+ 528
+ 529
+ 530
+ 531
+ 532
+ 533
+ 534
+ 535
+ 536
+ 537
+ 538
+ 539
+ 540
+ 541
+ 542
+ 543
+ 544
+ 545
+ 546
+ 547
+ 548
+ 549
+ 550
+ 551
+ 552
+ 553
+ 554
+ 555
+ 556
+ 557
+ 558
+ 559
+ 560
+ 561
+ 562
+ 563
+ 564
+ 565
+ 566
+ 567
+ 568
+ 569
+ 570
+ 571
+ 572
+ 573
+ 574
+ 575
+ 576
+ 577
+ 578
+ 579
+ 580
+ 581
+ 582
+ 583
+ 584
+ 585
+ 586
+ 587
+ 588
+ 589
+ 590
+ 591
+ 592
+ 593
+ 594
+ 595
+ 596
+ 597
+ 598
+ 599
+ 600
+ 601
+ 602
+ 603
+ 604
+ 605
+ 606
+ 607
+ 608
+ 609
+ 610
+ 611
+ 612
+ 613
+ 614
+ 615
+ 616
+ 617
+ 618
+ 619
+ 620
+ 621
+ 622
+ 623
+ 624
+ 625
+ 626
+ 627
+ 628
+ 629
+ 630
+ 631
+ 632
+ 633
+ 634
+ 635
+ 636
+ 637
+ 638
+ 639
+ 640
+ 641
+ 642
+ 643
+ 644
+ 645
+ 646
+ 647
+ 648
+ 649
+ 650
+ 651
+ 652
+ 653
+ 654
+ 655
+ 656
+ 657
+ 658
+ 659
+ 660
+ 661
+ 662
+ 663
+ 664
+ 665
+ 666
+ 667
+ 668
+ 669
+ 670
+ 671
+ 672
+ 673
+ 674
+ 675
+ 676
+ 677
+ 678
+ 679
+ 680
+ 681
+ 682
+ 683
+ 684
+ 685
+ 686
+ 687
+ 688
+ 689
+ 690
+ 691
+ 692
+ 693
+ 694
+ 695
+ 696
+ 697
+ 698
+ 699
+ 700
+ 701
+ 702
+ 703
+ 704
+ 705
+ 706
+ 707
+ 708
+ 709
+ 710
+ 711
+ 712
+ 713
+ 714
+ 715
+ 716
+ 717
+ 718
+ 719
+ 720
+ 721
+ 722
+ 723
+ 724
+ 725
+ 726
+ 727
+ 728
+ 729
+ 730
+ 731
+ 732
+ 733
+ 734
+ 735
+ 736
+ 737
+ 738
+ 739
+ 740
+ 741
+ 742
+ 743
+ 744
+ 745
+ 746
+ 747
+ 748
+ 749
+ 750
+ 751
+ 752
+ 753
+ 754
+ 755
+ 756
+ 757
+ 758
+ 759
+ 760
+ 761
+ 762
+ 763
+ 764
+ 765
+ 766
+ 767
+ 768
+ 769
+ 770
+ 771
+ 772
+ 773
+ 774
+ 775
+ 776
+ 777
+ 778
+ 779
+ 780
+ 781
+ 782
+ 783
+ 784
+ 785
+ 786
+ 787
+ 788
+ 789
+ 790
+ 791
+ 792
+ 793
+ 794
+ 795
+ 796
+ 797
+ 798
+ 799
+ 800
+ 801
+ 802
+ 803
+ 804
+ 805
+ 806
+ 807
+ 808
+ 809
+ 810
+ 811
+ 812
+ 813
+ 814
+ 815
+ 816
+ 817
+ 818
+ 819
+ 820
+ 821
+ 822
+ 823
+ 824
+ 825
+ 826
+ 827
+ 828
+ 829
+ 830
+ 831
+ 832
+ 833
+ 834
+ 835
+ 836
+ 837
+ 838
+ 839
+ 840
+ 841
+ 842
+ 843
+ 844
+ 845
+ 846
+ 847
+ 848
+ 849
+ 850
+ 851
+ 852
+ 853
+ 854
+ 855
+ 856
+ 857
+ 858
+ 859
+ 860
+ 861
+ 862
+ 863
+ 864
+ 865
+ 866
+ 867
+ 868
+ 869
+ 870
+ 871
+ 872
+ 873
+ 874
+ 875
+ 876
+ 877
+ 878
+ 879
+ 880
+ 881
+ 882
+ 883
+ 884
+ 885
+ 886
+ 887
+ 888
+ 889
+ 890
+ 891
+ 892
+ 893
+ 894
+ 895
+ 896
+ 897
+ 898
+ 899
+ 900
+ 901
+ 902
+ 903
+ 904
+ 905
+ 906
+ 907
+ 908
+ 909
+ 910
+ 911
+ 912
+ 913
+ 914
+ 915
+ 916
+ 917
+ 918
+ 919
+ 920
+ 921
+ 922
+ 923
+ 924
+ 925
+ 926
+ 927
+ 928
+ 929
+ 930
+ 931
+ 932
+ 933
+ 934
+ 935
+ 936
+ 937
+ 938
+ 939
+ 940
+ 941
+ 942
+ 943
+ 944
+ 945
+ 946
+ 947
+ 948
+ 949
+ 950
+ 951
+ 952
+ 953
+ 954
+ 955
+ 956
+ 957
+ 958
+ 959
+ 960
+ 961
+ 962
+ 963
+ 964
+ 965
+ 966
+ 967
+ 968
+ 969
+ 970
+ 971
+ 972
+ 973
+ 974
+ 975
+ 976
+ 977
+ 978
+ 979
+ 980
+ 981
+ 982
+ 983
+ 984
+ 985
+ 986
+ 987
+ 988
+ 989
+ 990
+ 991
+ 992
+ 993
+ 994
+ 995
+ 996
+ 997
+ 998
+ 999
+1000
+1001
+1002
+1003
+1004
+1005
+1006
+1007
+1008
+1009
+1010
+1011
+1012
+1013
+1014
+1015
+1016
+1017
+1018
+1019
+1020
+1021
+1022
+1023
+1024
+1025
+1026
+1027
+1028
+1029
+1030
+1031
+1032
+1033
+1034
+1035
+1036
+1037
+1038
+1039
+1040
+1041
+1042
+1043
+1044
+1045
+1046
+1047
+1048
+1049
+1050
+1051
+1052
+1053
+1054
+1055
+1056
+1057
+1058
+1059
+1060
+1061
+1062
+1063
+1064
+1065
+1066
+1067
+1068
+1069
+1070
+1071
+1072
+1073
+1074
+1075
+1076
+1077
+1078
+1079
+1080
+1081
+1082
+1083
+1084
+1085
+1086
+1087
+1088
+1089
+1090
+1091
+1092
+1093
+1094
+1095
+1096
+1097
+1098
+1099
+1100
+1101
+1102
+1103
+1104
+1105
+1106
+1107
+1108
+1109
+1110
+1111
+1112
+1113
+1114
+1115
+1116
+1117
+1118
+1119
+1120
+1121
+1122
+1123
+1124
+1125
+1126
+1127
+1128
+1129
+1130
+1131
+1132
+1133
+1134
+1135
+1136
+1137
+1138
+1139
+1140
+1141
+1142
+1143
+1144
+1145
+1146
+1147
+1148
+1149
+1150
+1151
+1152
+1153
+1154
+1155
+1156
+1157
+1158
+1159
+1160
+1161
+1162
+1163
+1164
+1165
+1166
+1167
+1168
+1169
+1170
+1171
+1172
+1173
+1174
+1175
+1176
+1177
+1178
+1179
+1180
+1181
+1182
+1183
+1184
+1185
+1186
+1187
+1188
+1189
+1190
+1191
+1192
+1193
+1194
+1195
+1196
+1197
+1198
+1199
+1200
+1201
+1202
+1203
+1204
+1205
+1206
+1207
+1208
+1209
+1210
+1211
+1212
+1213
+1214
+1215
+1216
+1217
+1218
+1219
+1220
+1221
+1222
+1223
+1224
+1225
+1226
+1227
+1228
+1229
+1230
+1231
+1232
+1233
+1234
+1235
+1236
+1237
+1238
+1239
+1240
+1241
+1242
+1243
+1244
+1245
+1246
// *****************************************************************************
 /*!
-  \file      src/Inciter/Sorter.cpp
+  \file      src/Inciter/Discretization.cpp
   \copyright 2012-2015 J. Bakosi,
              2016-2018 Los Alamos National Security, LLC.,
              2019-2021 Triad National Security, LLC.
              All rights reserved. See the LICENSE file for details.
-  \brief     Mesh sorter for global distributed mesh reordering
-  \see       Sorter.h for more info.
+  \details   Data and functionality common to all discretization schemes
+  \see       Discretization.h and Discretization.C for more info.
 */
 // *****************************************************************************
 
-#include <vector>
-#include <algorithm>
-
-#include "Sorter.hpp"
-#include "Reorder.hpp"
-#include "DerivedData.hpp"
-#include "Inciter/InputDeck/InputDeck.hpp"
-
-namespace inciter {
-
-extern ctr::InputDeck g_inputdeck;
-
-} // inciter::
-
-using inciter::Sorter;
-
-Sorter::Sorter( std::size_t meshid,
-                const CProxy_Transporter& transporter,
-                const tk::CProxy_MeshWriter& meshwriter,
-                const tk::SorterCallback& cbs,
-                const std::vector< Scheme >& scheme,
-                CkCallback reorderRefiner,
-                const std::vector< std::size_t >& ginpoel,
-                const tk::UnsMesh::CoordMap& coordmap,
-                const tk::UnsMesh::Chunk& el,
-                const std::map< int, std::vector< std::size_t > >& bface,
-                const std::vector< std::size_t >& triinpoel,
-                const std::map< int, std::vector< std::size_t > >& bnode,
-                const std::unordered_map< std::size_t, std::set< std::size_t > >&
-                  elemblockid,
-                int nchare ) :
-  m_meshid( meshid ),
-  m_host( transporter ),
-  m_meshwriter( meshwriter ),
-  m_cbs( cbs ),
-  m_scheme( scheme ),
-  m_reorderRefiner( reorderRefiner ),
-  m_ginpoel( ginpoel ),
-  m_coordmap( coordmap ),
-  m_el( el ),
-  m_nbnd( 0 ),
-  m_bface( bface ),
-  m_triinpoel( triinpoel ),
-  m_bnode( bnode ),
-  m_elemblockid( elemblockid ),
-  m_nchare( nchare ),
-  m_nodeset( begin(ginpoel), end(ginpoel) ),
-  m_noffset( 0 ),
-  m_nodech(),
-  m_chnode(),
-  m_edgech(),
-  m_chedge(),
-  m_msum(),
-  m_reordcomm(),
-  m_start( 0 ),
-  m_newnodes(),
-  m_newcoordmap(),
-  m_reqnodes(),
-  m_lower( 0 ),
-  m_upper( 0 )
-// *****************************************************************************
-//  Constructor: prepare owned mesh node IDs for reordering
-//! \param[in] meshid Mesh ID
-//! \param[in] transporter Transporter (host) Charm++ proxy
-//! \param[in] meshwriter Mesh writer Charm++ proxy
-//! \param[in] cbs Charm++ callbacks for Sorter
-//! \param[in] scheme Discretization schemes (one per mesh)
-//! \param[in] reorderRefiner Callback to use to send reordered mesh to Refiner
-//! \param[in] ginpoel Mesh connectivity (this chare) using global node IDs
-//! \param[in] coordmap Mesh node coordinates (this chare) for global node IDs
-//! \param[in] bface Face lists mapped to side set ids
-//! \param[in] triinpoel Interconnectivity of points and boundary-faces
-//! \param[in] bnode Node ids mapped to side set ids
-//! \param[in] elemblockid Local tet ids associated to mesh block ids
-//! \param[in] nchare Total number of Charm++ worker chares
-// *****************************************************************************
-{
-  // Ensure boundary face ids will not index out of face connectivity
-  Assert( std::all_of( begin(m_bface), end(m_bface),
-            [&](const auto& s)
-            { return std::all_of( begin(s.second), end(s.second),
-                       [&](auto f){ return f*3+2 < m_triinpoel.size(); } ); } ),
-          "Boundary face data structures inconsistent" );
-}
-
-void
-Sorter::setup( std::size_t npoin )
-// *****************************************************************************
-// Setup chare mesh boundary node communication map
-//! \param[in] npoin Total number of mesh points in mesh. Note that the number
-//!   of mesh points does not have to be exactly the total number of points in
-//!   the mesh. It can be a larger number, but not less. This is only used here
-//!   to assign nodes to workers that will assign ids to mesh nodes during node
-//!   reordering.
-// *****************************************************************************
-{
-  // Compute the number of nodes (chunksize) a chare will build a node
-  // communication map for. We compute two values of chunksize: one for when
-  // the global node ids are abounded between [0...npoin-1], inclusive, and
-  // another one for when the global node ids are assigned by a hash algorithm
-  // during initial mesh refinement. In the latter case, the maximum
-  // representable value of a std::size_t is assumed to be the large global node
-  // id and is used to compute the chunksize. To compute the bin id, we attempt
-  // to use the first chunksize first: if it gives a chare id that is
-  // (strictly) lower than the number of chares, that's good. If not, we compute
-  // the bin id based on the second chunksize, which almost always will give a
-  // bin id strictly lower than the number of chares, except if the global node
-  // id assigned by the hash algorithm in Refiner hits the maximum
-  // representable number in std::size_t. If that is the case, we just assign
-  // that node to the last chare.
-  auto N = static_cast< std::size_t >( m_nchare );
-  std::array< std::size_t, 2 > chunksize{{
-     npoin / N, std::numeric_limits< std::size_t >::max() / N }};
-
-  const auto scheme = g_inputdeck.get< tag::scheme >();<--- Variable 'scheme' is assigned a value that is never used.
-
-  // Find chare-boundary nodes and edges of our mesh chunk. This algorithm
-  // collects the global mesh node ids and edges on the chare boundary. A node
-  // is on a chare boundary if it belongs to a face of a tetrahedron that has
-  // no neighbor tet at a face. The edge is on the chare boundary if its first
-  // edge-end point is on a chare boundary. The nodes are categorized to bins
-  // that will be sent to different chares to build point-to-point
-  // communication maps across all chares. The binning is determined by the
-  // global node id divided by the chunksizes. See discussion above on how we
-  // use two chunksizes for global node ids assigned by the hash algorithm in
-  // Refiner (if initial mesh refinement has been done).
-  tk::CommMaps chbnd;
-  auto el = tk::global2local( m_ginpoel );      // generate local mesh data
-  const auto& inpoel = std::get< 0 >( el );     // local connectivity
-  auto esup = tk::genEsup( inpoel, 4 );         // elements surrounding points
-  auto esuel = tk::genEsuelTet( inpoel, esup ); // elems surrounding elements
-  for (std::size_t e=0; e<esuel.size()/4; ++e) {
-    auto mark = e*4;
-    for (std::size_t f=0; f<4; ++f)
-      if (esuel[mark+f] == -1)
-        for (std::size_t n=0; n<3; ++n) {
-          auto g = m_ginpoel[ mark+tk::lpofa[f][n] ];
-          auto bin = g / chunksize[0];
-          if (bin >= N) bin = g / chunksize[1];
-          if (bin >= N) bin = N - 1;
-          Assert( bin < N, "Will index out of number of chares" );
-          auto& b = chbnd[ static_cast< int >( bin ) ];
-          b.get< tag::node >().insert( g );
-          if (scheme == ctr::SchemeType::ALECG ||
-            scheme == ctr::SchemeType::OversetFE) {
-            auto h = m_ginpoel[ mark + tk::lpofa[ f ][ tk::lpoet[n][1] ] ];
-            b.get< tag::edge >().insert( { std::min(g,h), std::max(g,h) } );
-          }
-        }
-  }
-
-  // Send boundary data in bins to chares that will compute communication maps
-  // for the data in the bin. These bins form a distributed table.  Note that
-  // we only send data to those chares that have data to work on. The receiving
-  // sides do not know in advance if they receive messages or not.  Completion
-  // is detected by having the receiver respond back and counting the responses
-  // on the sender side, i.e., this chare.
-  m_nbnd = chbnd.size();
-  if (m_nbnd == 0)
-    contribute( sizeof(std::size_t), &m_meshid, CkReduction::nop,
-                m_cbs.get< tag::queried >() );
-  else
-    for (const auto& [ targetchare, bnd ] : chbnd)
-      thisProxy[ targetchare ].query( thisIndex, bnd );
-}
-
-void
-Sorter::query( int fromch, const tk::AllCommMaps& bnd )
-// *****************************************************************************
-// Incoming query for a list of mesh nodes for which this chare compiles node
-// communication maps
-//! \param[in] fromch Sender chare ID
-//! \param[in] bnd Chare-boundary data from another chare
-// *****************************************************************************
-{
-  // Store incoming nodes in node->chare and its inverse, chare->node, maps
-  const auto& nodes = bnd.get< tag::node >();
-  for (auto n : nodes) m_nodech[ n ].push_back( fromch );
-  m_chnode[ fromch ].insert( begin(nodes), end(nodes) );
-
-  // Store incoming edges in edge->chare and its inverse, chare->edge, maps
-  const auto& edges = bnd.get< tag::edge >();
-  for (const auto& e : edges) m_edgech[ e ].push_back( fromch );
-  m_chedge[ fromch ].insert( begin(edges), end(edges) );
-
-  // Report back to chare message received from
-  thisProxy[ fromch ].recvquery();
-}
-
-void
-Sorter::recvquery()
-// *****************************************************************************
-// Receive receipt of boundary node lists to query
-// *****************************************************************************
-{
-  if (--m_nbnd == 0)
-    contribute( sizeof(std::size_t), &m_meshid, CkReduction::nop,
-                m_cbs.get< tag::queried >() );
-}
-
-void
-Sorter::response()
-// *****************************************************************************
-//  Respond to boundary node list queries
-// *****************************************************************************
-{
-  std::unordered_map< int, tk::CommMaps > exp;
-
-  // Compute node communication map to be sent back to chares
-  for (const auto& [ neighborchare, bndnodes ] : m_chnode) {
-    auto& nc = exp[ neighborchare ];
-    for (auto n : bndnodes)
-      for (auto d : tk::cref_find(m_nodech,n))
-        if (d != neighborchare)
-          nc[d].get< tag::node >().insert( n );
-  }
-
-  // Compute edge communication map to be sent back to chares
-  for (const auto& [ neighborchare, bndedges ] : m_chedge) {
-    auto& ec = exp[ neighborchare ];
-    for (const auto& e : bndedges)
-      for (auto d : tk::cref_find(m_edgech,e))
-        if (d != neighborchare)
-          ec[d].get< tag::edge >().insert( e );
-  }
+#include "Tags.hpp"
+#include "Reorder.hpp"
+#include "Vector.hpp"
+#include "DerivedData.hpp"
+#include "Discretization.hpp"
+#include "MeshWriter.hpp"
+#include "DiagWriter.hpp"
+#include "Inciter/InputDeck/InputDeck.hpp"
+#include "Inciter/Options/Scheme.hpp"
+#include "Print.hpp"
+#include "Around.hpp"
+#include "QuinoaBuildConfig.hpp"
+#include "ConjugateGradients.hpp"
+#include "ALE.hpp"
+
+#include "M2MTransfer.hpp"
+
+namespace inciter {
+
+static CkReduction::reducerType PDFMerger;
+extern ctr::InputDeck g_inputdeck;
+extern ctr::InputDeck g_inputdeck_defaults;
+
+} // inciter::
+
+using inciter::Discretization;
+
+Discretization::Discretization(
+  std::size_t meshid,
+  const std::vector< CProxy_Discretization >& disc,
+  const CProxy_ALE& aleproxy,
+  const tk::CProxy_ConjugateGradients& conjugategradientsproxy,
+  const CProxy_Transporter& transporter,
+  const tk::CProxy_MeshWriter& meshwriter,
+  const tk::UnsMesh::CoordMap& coordmap,
+  const tk::UnsMesh::Chunk& el,
+  const tk::CommMaps& msum,
+  const std::map< int, std::vector< std::size_t > >& bface,
+  const std::vector< std::size_t >& triinpoel,
+  const std::unordered_map< std::size_t, std::set< std::size_t > >& elemblockid,
+  int nc ) :
+  m_meshid( meshid ),
+  m_transfer( g_inputdeck.get< tag::transfer >() ),
+  m_disc( disc ),
+  m_nchare( nc ),
+  m_it( 0 ),
+  m_itr( 0 ),
+  m_itf( 0 ),
+  m_initial( 1 ),
+  m_t( g_inputdeck.get< tag::t0 >() ),
+  m_lastDumpTime( -std::numeric_limits< tk::real >::max() ),
+  m_physFieldFloor( 0.0 ),
+  m_physHistFloor( 0.0 ),
+  m_rangeFieldFloor( 0.0 ),
+  m_rangeHistFloor( 0.0 ),
+  m_dt( g_inputdeck.get< tag::dt >() ),
+  m_dtn( m_dt ),
+  m_nvol( 0 ),
+  m_nxfer( 0 ),
+  m_ale( aleproxy ),
+  m_transporter( transporter ),
+  m_meshwriter( meshwriter ),
+  m_el( el ),     // fills m_inpoel, m_gid, m_lid
+  m_coord( setCoord( coordmap ) ),
+  m_coordn( m_coord ),
+  m_nodeCommMap(),
+  m_edgeCommMap(),
+  m_meshvol( 0.0 ),
+  m_v( m_gid.size(), 0.0 ),
+  m_vol( m_gid.size(), 0.0 ),
+  m_volc(),
+  m_voln( m_vol ),
+  m_vol0( m_inpoel.size()/4, 0.0 ),
+  m_bid(),
+  m_timer(),
+  m_refined( 0 ),
+  m_prevstatus( std::chrono::high_resolution_clock::now() ),
+  m_nrestart( 0 ),
+  m_histdata(),
+  m_nsrc( 0 ),
+  m_ndst( 0 ),
+  m_meshvel( 0, 3 ),
+  m_meshvel_converged( true ),
+  m_bface( bface ),
+  m_triinpoel( triinpoel ),
+  m_elemblockid( elemblockid )
+// *****************************************************************************
+//  Constructor
+//! \param[in] meshid Mesh ID
+//! \param[in] disc All Discretization proxies (one per mesh)
+//! \param[in] aleproxy Distributed ALE proxy
+//! \param[in] conjugategradientsproxy Distributed Conjugrate Gradients linear
+//!   solver proxy
+//! \param[in] transporter Host (Transporter) proxy
+//! \param[in] meshwriter Mesh writer proxy
+//! \param[in] coordmap Coordinates of mesh nodes and their global IDs
+//! \param[in] el Elements of the mesh chunk we operate on
+//! \param[in] msum Communication maps associated to chare IDs bordering the
+//!   mesh chunk we operate on
+//! \param[in] bface Face lists mapped to side set ids
+//! \param[in] triinpoel Interconnectivity of points and boundary-faces
+//! \param[in] elemblockid Local tet ids associated with mesh block ids
+//! \param[in] nc Total number of Discretization chares
+// *****************************************************************************
+{
+  Assert( !m_inpoel.empty(), "No elements assigned to Discretization chare" );
+  Assert( tk::positiveJacobians( m_inpoel, m_coord ),
+          "Jacobian in input mesh to Discretization non-positive" );
+  #if not defined(__INTEL_COMPILER) || defined(NDEBUG)
+  // The above ifdef skips running the conformity test with the intel compiler
+  // in debug mode only. This is necessary because in tk::conforming(), filling
+  // up the map can fail with some meshes (only in parallel), e.g., tube.exo,
+  // used by some regression tests, due to the intel compiler generating some
+  // garbage incorrect code - only in debug, only in parallel, only with that
+  // mesh.
+  Assert( tk::conforming( m_inpoel, m_coord ),
+          "Input mesh to Discretization not conforming" );
+  #endif
+
+  // Store communication maps
+  for (const auto& [ c, maps ] : msum) {
+    m_nodeCommMap[c] = maps.get< tag::node >();
+    m_edgeCommMap[c] = maps.get< tag::edge >();
+  }
+
+  // Get ready for computing/communicating nodal volumes
+  startvol();
+
+  // Get chare-boundary node-id map
+  m_bid = genBid();
+
+  // Find host elements of user-specified points where time histories are
+  // saved, and save the shape functions evaluated at the point locations
+  const auto& pt = g_inputdeck.get< tag::history_output, tag::point >();
+  for (std::size_t p=0; p<pt.size(); ++p) {
+    std::array< tk::real, 4 > N;
+    const auto& l = pt[p].get< tag::coord >();
+    const auto& id = pt[p].get< tag::id >();
+    for (std::size_t e=0; e<m_inpoel.size()/4; ++e) {
+      if (tk::intet( m_coord, m_inpoel, l, e, N )) {
+        m_histdata.push_back( HistData{{ id, e, {l[0],l[1],l[2]}, N }} );
+        break;
+      }
+    }
+  }
+
+  // Insert ConjugrateGradients solver chare array element if needed
+  if (g_inputdeck.get< tag::ale, tag::ale >()) {
+    m_ale[ thisIndex ].insert( conjugategradientsproxy,
+                               m_coord, m_inpoel,
+                               m_gid, m_lid, m_nodeCommMap );
+  } else {
+    m_meshvel.resize( m_gid.size() );
+  }
+
+  // Register mesh with mesh-transfer lib
+  if (m_disc.size() == 1 || m_transfer.empty()) {
+    // skip transfer if single mesh or if not involved in coupling
+    transferInit();
+  } else {
+    if (thisIndex == 0) {
+      exam2m::addMesh( thisProxy, m_nchare,
+        CkCallback( CkIndex_Discretization::transferInit(), thisProxy ) );
+      //std::cout << "Disc: " << m_meshid << " m2m::addMesh()\n";
+    }
+  }
+}
+
+std::unordered_map< std::size_t, std::size_t >
+Discretization::genBid()
+// *****************************************************************************
+// Generate the Bid data-structure based on the node communication-map
+// *****************************************************************************
+{
+  // Count the number of mesh nodes at which we receive data from other chares
+  // and compute map associating boundary-chare node ID to global node ID
+  std::vector< std::size_t > c( tk::sumvalsize( m_nodeCommMap ) );
+  std::size_t j = 0;
+  for (const auto& [ch,n] : m_nodeCommMap) for (auto i : n) c[j++] = i;
+  tk::unique( c );
+  return tk::assignLid( c );
+}
+
+void
+Discretization::transferInit()
+// *****************************************************************************
+// Our mesh has been registered with the mesh-to-mesh transfer library (if
+// coupled to other solver)
+// *****************************************************************************
+{
+  // Compute number of mesh points owned
+  std::size_t npoin = m_gid.size();
+  for (auto g : m_gid) if (tk::slave(m_nodeCommMap,g,thisIndex)) --npoin;
+
+  // Tell the RTS that the Discretization chares have been created and compute
+  // the total number of mesh points across the distributed mesh
+  std::vector< std::size_t > meshdata{ m_meshid, npoin };
+  contribute( meshdata, CkReduction::sum_ulong,
+    CkCallback( CkReductionTarget(Transporter,disccreated), m_transporter ) );
+}
+
+void
+Discretization::meshvelStart(
+  const tk::UnsMesh::Coords vel,
+  const std::vector< tk::real >& soundspeed,
+  const std::unordered_map< int,
+    std::unordered_map< std::size_t, std::array< tk::real, 4 > > >& bnorm,
+  tk::real adt,
+  CkCallback done ) const
+// *****************************************************************************
+// Start computing new mesh velocity for ALE mesh motion
+//! \param[in] vel Fluid velocity at mesh nodes
+//! \param[in] soundspeed Speed of sound at mesh nodes
+//! \param[in] bnorm Face normals in boundary points associated to side sets
+//! \param[in] adt alpha*dt of the RK time step
+//! \param[in] done Function to continue with when mesh velocity has been
+//!   computed
+// *****************************************************************************
+{
+  if (g_inputdeck.get< tag::ale, tag::ale >())
+    m_ale[ thisIndex ].ckLocal()->start( vel, soundspeed, done,
+      m_coord, m_coordn, m_vol0, m_vol, bnorm, m_initial, m_it, m_t, adt );
+  else
+    done.send();
+}
 
-  // Send communication maps to chares that issued a query to us. Communication
-  // maps were computed above for those chares that queried this map from us.
-  // This data form a distributed table and we only work on a chunk of it. Note
-  // that we only send data back to those chares that have queried us. The
-  // receiving sides do not know in advance if the receive messages or not.
-  // Completion is detected by having the receiver respond back and counting
-  // the responses on the sender side, i.e., this chare.
-  m_nbnd = exp.size();
-  if (m_nbnd == 0)
-    contribute( sizeof(std::size_t), &m_meshid, CkReduction::nop,
-                m_cbs.get< tag::responded >() );
-  else
-    for (const auto& [ targetchare, maps ] : exp)
-      thisProxy[ targetchare ].bnd( thisIndex, maps );
-}
-
-void
-Sorter::bnd( int fromch, const tk::CommMaps& msum )
+const tk::Fields&
+Discretization::meshvel() const
+// *****************************************************************************
+//! Query the mesh velocity
+//! \return Mesh velocity
+// *****************************************************************************
+{
+  if (g_inputdeck.get< tag::ale, tag::ale >())
+    return m_ale[ thisIndex ].ckLocal()->meshvel();
+  else
+    return m_meshvel;
+}
+
+void
+Discretization::meshvelBnd(
+  const std::map< int, std::vector< std::size_t > >& bface,
+  const std::map< int, std::vector< std::size_t > >& bnode,
+  const std::vector< std::size_t >& triinpoel) const
 // *****************************************************************************
-// Receive boundary node communication maps for our mesh chunk
-//! \param[in] fromch Sender chare ID
-//! \param[in] msum Communication map(s) assembled by chare fromch
-// *****************************************************************************
-{
-  for (const auto& [ neighborchare, maps ] : msum) {
-    auto& m = m_msum[ neighborchare ];
-    const auto& nodemap = maps.get< tag::node >();
-    m.get< tag::node >().insert( begin(nodemap), end(nodemap) );
-    const auto& edgemap = maps.get< tag::edge >();
-    m.get< tag::edge >().insert( begin(edgemap), end(edgemap) );
-  }
-
-  // Report back to chare message received from
-  thisProxy[ fromch ].recvbnd();
-}
-
-void
-Sorter::recvbnd()
-// *****************************************************************************
-// Receive receipt of boundary node communication map
-// *****************************************************************************
-{
-  if (--m_nbnd == 0)
-    contribute( sizeof(std::size_t), &m_meshid, CkReduction::nop,
-                m_cbs.get< tag::responded >() );
-}
-
-void
-Sorter::start()
-// *****************************************************************************
-//  Start reordering (if enabled)
-// *****************************************************************************
-{
-  // Keep only those edges in edge comm map whose both end-points are in the
-  // node comm map
-  for (auto& [ neighborchare, maps ] : m_msum) {
-    const auto& nodes = maps.get< tag::node >();
-    tk::EdgeSet edges;
-    for (const auto& e : maps.get< tag::edge >())
-      if (nodes.find(e[0]) != end(nodes) && nodes.find(e[1]) != end(nodes))
-        edges.insert( e );
-    maps.get< tag::edge >() = std::move(edges);
-  }
-
-  if (g_inputdeck.get< tag::cmd, tag::feedback >()) m_host.chcomm();
-
-  tk::destroy( m_nodech );
-  tk::destroy( m_chnode );
-
-  if (g_inputdeck.get< tag::pelocal_reorder >())
-    mask();   // continue with mesh node reordering if requested (or required)
-  else
-    createDiscWorkers();  // skip mesh node reordering
-}
-
-void
-Sorter::mask()
-// *****************************************************************************
-//  Start preparing for mesh node reordering in parallel
-// *****************************************************************************
-{
-  // Compute asymmetric communcation map that will be used for reordering. This
-  // communication map is asymmetric because it associates global mesh node IDs
-  // to chares only with lower IDs than thisIndex. That is because this chare
-  // will need to receive new (reorderd) node IDs only from chares with lower
-  // IDs than thisIndex during node reordering. Since it only stores data for
-  // lower chare IDs, it is asymmetric. Note that because of this algorithm the
-  // type of m_msum is an ordered map, because of the std::none_of() algorithm
-  // needs to look at ALL chares this chare potentially communicates nodes with
-  // that have lower chare IDs that thisIndex. Since the map is ordered, it can
-  // walk through from the beginning of m_msum until the outer loop variable c,
-  // which is the chare ID the outer loop works on in a given cycle.
-  for (auto c=m_msum.cbegin(); c!=m_msum.cend(); ++c)
-    if (thisIndex > c->first) {
-      auto& n = m_reordcomm[ c->first ];
-      for (auto j : c->second.get< tag::node >())
-        if (std::none_of( m_msum.cbegin(), c,
-             [j]( const auto& s ) {
-               const auto& nodemap = s.second.template get< tag::node >();
-               return nodemap.find(j) != end(nodemap); } ))
-        {
-          n.insert(j);
-        }
-      if (n.empty()) m_reordcomm.erase( c->first );
-    }
-
-  // Count up total number of nodes this chare will need to receive
-  auto nrecv = tk::sumvalsize( m_reordcomm );
-
-  if ( g_inputdeck.get< tag::cmd, tag::feedback >() ) m_host.chmask();
-
-  // Compute number of mesh node IDs we will assign IDs to
-  auto nuniq = m_nodeset.size() - nrecv;
-
-  // Start computing offsets for node reordering
-  thisProxy.offset( thisIndex, nuniq );
-}
-
-void
-Sorter::offset( int c, std::size_t u )
-// *****************************************************************************
-//  Receive number of uniquely assigned global mesh node IDs from chares with
-//  lower IDs than thisIndex
-//! \param[in] c Chare ID
-//! \param[in] u Number of mesh node IDs chare c will assign IDs to
-//! \details This function computes the offset each chare will need to start
-//!   assigning its new node IDs from. The offset for a chare is the
-//!   offset for the previous chare plus the number of node IDs the previous
-//!   chare (uniquely) assigns new IDs for minus the number of node IDs the
-//!   previous chare receives from others (lower chares). This is computed here
-//!   in a parallel/distributed fashion by each chare sending its number of node
-//!   IDs (that it uniquely assigns) to all chares. Note that each chare would
-//!   only need to send this information to chares with higher IDs, but instead
-//!   this function is called in a broadcast fashion, because that is more
-//!   efficient than individual calls to only chares with higher IDs. Therefore
-//!   when computing the offsets, we only count the lower chares. When this is
-//!   done, we have the precise asymmetric communication map as well as the
-//!   start offset on all chares and so we can start the distributed global mesh
-//!   node ID reordering.
-// *****************************************************************************
-{
-  if (c < thisIndex) m_start += u;
-  if (++m_noffset == m_nchare) reorder();
-}
-
-void
-Sorter::reorder()
-// *****************************************************************************
-//  Reorder global mesh node IDs
+// Query ALE mesh velocity boundary condition node lists and node lists at
+// which ALE moves boundaries
+// *****************************************************************************
+{
+  if (g_inputdeck.get< tag::ale, tag::ale >())
+    m_ale[ thisIndex ].ckLocal()->meshvelBnd( bface, bnode, triinpoel );
+}
+
+void
+Discretization::meshvelConv()
+// *****************************************************************************
+//! Assess and record mesh velocity linear solver convergence
+// *****************************************************************************
+{
+  auto smoother = g_inputdeck.get< tag::ale, tag::smoother >();
+
+  if (g_inputdeck.get< tag::ale, tag::ale >() &&
+      (smoother == ctr::MeshVelocitySmootherType::LAPLACE or
+       smoother == ctr::MeshVelocitySmootherType::HELMHOLTZ))
+  {
+    m_meshvel_converged &= m_ale[ thisIndex ].ckLocal()->converged();
+  }
+}
+
+void
+Discretization::comfinal()
+// *****************************************************************************
+// Finish setting up communication maps and solution transfer callbacks
+// *****************************************************************************
+{
+  // Generate own subset of solver/mesh transfer list
+  for (const auto& t : m_transfer) {
+    if (t.src == m_meshid || t.dst == m_meshid) {
+      m_mytransfer.push_back( t );<--- Consider using std::copy_if algorithm instead of a raw loop.
+    }
+  }
+
+  // Signal the runtime system that the workers have been created
+  std::vector< std::size_t > meshdata{ /* initial = */ 1, m_meshid };
+  contribute( meshdata, CkReduction::sum_ulong,
+    CkCallback(CkReductionTarget(Transporter,comfinal), m_transporter) );
+}
+
+void
+Discretization::transfer(
+  tk::Fields& u,
+  std::size_t dirn,
+  CkCallback cb )
+// *****************************************************************************
+//  Start solution transfer (if coupled)
+//! \param[in,out] u Solution to transfer from/to
+//! \param[in] dirn Direction of solution transfer. 0: from background to
+//!   overset, 1: from overset to background
+//! \param[in] cb Callback to call when back and forth transfers complete.
+//! \details This function initiates the solution transfer (direction dependent
+//!   on 'dirn') between meshes. It invokes a reduction to Transporter when the
+//!   transfer in one direction is complete (dirn == 0), or calls back the
+//!   'cb' function in Scheme when transfers both directions are complete.
+//!   The function relies on 'dirn' to make this decision.
+// *****************************************************************************
+{
+  if (m_mytransfer.empty()) {   // skip transfer if not involved in coupling
+
+    cb.send();
+
+  } else {
+
+    m_transfer_complete = cb;
+
+    // determine source and destination mesh depending on direction of transfer
+    std::size_t fromMesh(0), toMesh(0);
+    CkCallback cb_xfer;
+    if (dirn == 0) {
+      fromMesh = m_mytransfer[m_nsrc].src;<--- Variable 'fromMesh' is assigned a value that is never used.
+      toMesh = m_mytransfer[m_ndst].dst;<--- Variable 'toMesh' is assigned a value that is never used.
+      cb_xfer = CkCallback( CkIndex_Discretization::to_complete(), thisProxy[thisIndex] );<--- Variable 'cb_xfer' is assigned a value that is never used.
+    }
+    else {
+      fromMesh = m_mytransfer[m_nsrc].dst;<--- Variable 'fromMesh' is assigned a value that is never used.
+      toMesh = m_mytransfer[m_ndst].src;<--- Variable 'toMesh' is assigned a value that is never used.
+      cb_xfer = CkCallback( CkIndex_Discretization::from_complete(), thisProxy[thisIndex] );<--- Variable 'cb_xfer' is assigned a value that is never used.
+    }
+
+    // Pass source and destination meshes to mesh transfer lib (if coupled)
+    Assert( m_nsrc < m_mytransfer.size(), "Indexing out of mytransfer[src]" );
+    if (fromMesh == m_meshid) {
+      exam2m::setSourceTets( thisProxy, thisIndex, &m_inpoel, &m_coord, u );
+      ++m_nsrc;
+    } else {
+      m_nsrc = 0;
+    }
+    Assert( m_ndst < m_mytransfer.size(), "Indexing out of mytransfer[dst]" );
+    if (toMesh == m_meshid) {
+      exam2m::setDestPoints( thisProxy, thisIndex, &m_coord, u,
+        cb_xfer );
+      ++m_ndst;<--- m_ndst is assigned
+    } else {
+      m_ndst = 0;
+    }
+
+  }
+
+  m_nsrc = 0;
+  m_ndst = 0;<--- m_ndst is overwritten
+}
+
+void Discretization::to_complete()
+// *****************************************************************************
+//! Solution transfer from background to overset mesh completed (from ExaM2M)
+//! \brief This is called by ExaM2M on the destination mesh when the
+//!   transfer completes. Since this is called only on the destination, we find
+//!   and notify the corresponding source of the completion.
+// *****************************************************************************
+{
+  // Lookup the source disc and notify it of completion
+  for (auto& t : m_transfer) {
+    if (m_meshid == t.dst) {
+      m_disc[ t.src ][ thisIndex ].transfer_complete();
+    }
+  }
+
+  thisProxy[ thisIndex ].transfer_complete();
+}
+
+void Discretization::from_complete()
+// *****************************************************************************
+//! Solution transfer from overset to background mesh completed (from ExaM2M)
+//! \brief This is called by ExaM2M on the destination mesh when the
+//!   transfer completes. Since this is called only on the destination, we find
+//!   and notify the corresponding source of the completion.
 // *****************************************************************************
 {
-  // Activate SDAG waits for arriving requests from other chares requesting new
-  // node IDs for node IDs we assign new IDs to during reordering; and for
-  // computing/receiving lower and upper bounds of global node IDs our chare's
-  // linear system will operate on after reordering.
-  thisProxy[ thisIndex ].wait4prep();
-
-  // Send out request for new global node IDs for nodes we do not reorder
-  for (const auto& [ targetchare, nodes ] : m_reordcomm)
-    thisProxy[ targetchare ].request( thisIndex, nodes );
+  // Lookup the source disc and notify it of completion
+  for (auto& t : m_transfer) {
+    if (m_meshid == t.src) {
+      m_disc[ t.dst ][ thisIndex ].transfer_complete_from_dest();
+    }
+  }
+
+  m_transfer_complete.send();
+}
 
-  // Lambda to decide if node is assigned a new ID by this chare. If node is not
-  // found in the asymmetric communication map, it is owned, i.e., this chare
-  // assigns its new id.
-  auto ownnode = [ this ]( std::size_t p ) {
-    return std::all_of( m_reordcomm.cbegin(), m_reordcomm.cend(),
-                        [&](const auto& s)
-                        { return s.second.find(p) == s.second.cend(); } );
-  };
-
-  // Reorder our chunk of the mesh node IDs. Looping through all of our node
-  // IDs, we test if we are to assign a new ID to a node ID, and if so, we
-  // assign a new ID, i.e., reorder, by constructing a map associating new to
-  // old IDs (m_newnodes). We also count up the reordered nodes, which serves as
-  // the new node id. We also store the node coordinates associated to the new
-  // node ID.
-  for (auto p : m_nodeset)
-    if (ownnode(p)) {
-      m_newnodes[ p ] = m_start;        // assign new node ID (reorder)
-      m_newcoordmap.emplace( m_start, tk::cref_find(m_coordmap,p) );
-      ++m_start;
-    }
-
-  // Trigger SDAG wait indicating that reordering our node IDs are complete
-  reorderowned_complete();
-
-  // If all our nodes have new IDs assigned, reordering complete on this chare
-  if (m_newnodes.size() == m_nodeset.size()) finish();
-}
-
-void
-Sorter::request( int c, const std::unordered_set< std::size_t >& nd )
-// *****************************************************************************
-//  Request new global node IDs for old node IDs
-//! \param[in] c Chare request coming from and to which we send new IDs to
-//! \param[in] nd Set of old node IDs whose new IDs are requested
-// *****************************************************************************
-{
-  // Queue up requesting chare and node IDs
-  m_reqnodes.push_back( { c, nd } );
-  // Trigger SDAG wait signaling that node IDs have been requested from us
-  nodes_requested_complete();
-}
-
-void
-Sorter::prepare()
-// *****************************************************************************
-//  Find new node IDs for old ones and return them to the requestor(s)
-// *****************************************************************************
-{
-  // Find and return new node IDs to sender
-  for (const auto& [ requestorchare, nodes ] : m_reqnodes) {
-    std::unordered_map< std::size_t,
-      std::tuple< std::size_t, tk::UnsMesh::Coord > > n;
-    for (auto p : nodes) {
-      auto newid = tk::cref_find( m_newnodes, p );
-      n.emplace( p,
-        std::make_tuple( newid, tk::cref_find(m_newcoordmap,newid) ) );
-    }
-    thisProxy[ requestorchare ].neworder( n );
-  }
-
-  tk::destroy( m_reqnodes ); // Clear queue of requests just fulfilled
-
-  // Re-enable SDAG wait for preparing new node requests
-  thisProxy[ thisIndex ].wait4prep();
-
-  // Re-enable trigger signaling that reordering of owned node IDs are
-  // complete right away
-  reorderowned_complete();
-}
-
-void
-Sorter::neworder( const std::unordered_map< std::size_t,
-                        std::tuple< std::size_t, tk::UnsMesh::Coord > >& nodes )
-// *****************************************************************************
-//  Receive new (reordered) global node IDs
-//! \param[in] nodes Map associating new to old node IDs
-// *****************************************************************************
-{
-  // Store new node IDs associated to old ones, and node coordinates associated
-  // to new node IDs.
-  for (const auto& [ oldid, newnodes ] : nodes) {
-    auto newid = std::get< 0 >( newnodes );
-    m_newnodes[ oldid ] = newid;
-    m_newcoordmap.emplace( newid, std::get< 1 >( newnodes ) );
-  }
-
-  // If all our nodes have new IDs assigned, reorder complete on this PE
-  if (m_newnodes.size() == m_nodeset.size()) finish();
-}
-
-void
-Sorter::finish()
-// *****************************************************************************
-//  Compute final result of reordering
-//! \details Reordering is now complete on this chare. We now remap all mesh
-//!   data to reflect the new ordering.
-// *****************************************************************************
-{
-  // Update elem connectivity with the reordered node IDs
-  tk::remap( m_ginpoel, m_newnodes );
-
-  // Update node coordinate map with the reordered IDs
-  m_coordmap = m_newcoordmap;
-
-  // Update mesh chunk data structure held in our state with new node order
-  m_el = tk::global2local( m_ginpoel );
-
-  // Update symmetric chare-node communication map with the reordered IDs
-  for (auto& [ neighborchare, maps ] : m_msum) {
-
-    tk::NodeSet n;
-    for (auto p : maps.get< tag::node >())
-      n.insert( tk::cref_find( m_newnodes, p ) );
-    maps.get< tag::node >() = std::move( n );
-
-    tk::EdgeSet e;
-    for (const auto& ed : maps.get< tag::edge >()) {
-      e.insert( { tk::cref_find(m_newnodes,ed[0]),
-                  tk::cref_find(m_newnodes,ed[1]) } );
-    }
-    maps.get< tag::edge >() = std::move( e );
-
-  }
-
-  // Update boundary face-node connectivity with the reordered node IDs
-  tk::remap( m_triinpoel, m_newnodes );
-
-  // Update boundary node lists with the reordered node IDs
-  for (auto& [ setid, nodes ] : m_bnode) tk::remap( nodes, m_newnodes );
-
-  // Update mesh in Refiner after reordering
-  m_reorderRefiner.send();
-
-  // Progress report to host
-  if ( g_inputdeck.get< tag::cmd, tag::feedback >() ) m_host.chreordered();
-
-  createDiscWorkers();
-}
-
-void
-Sorter::mesh( std::vector< std::size_t >& ginpoel,
-              tk::UnsMesh::CoordMap& coordmap,
-              std::vector< std::size_t >& triinpoel,
-              std::map< int, std::vector< std::size_t > >& bnode )
+void Discretization::transfer_complete_from_dest()
+// *****************************************************************************
+//! Solution transfer completed (from dest Discretization)
+//! \details Called on the source only by the destination when a back and forth
+//!   transfer step completes.
+// *****************************************************************************
+{
+  m_transfer_complete.send();
+}
+
+void Discretization::transfer_complete()
+// *****************************************************************************
+//! Solution transfer completed (one-way)
+//! \note Single exit point after solution transfer between meshes
+// *****************************************************************************
+{
+  contribute( sizeof(nullptr), nullptr, CkReduction::nop,
+    CkCallback(CkReductionTarget(Transporter,solutionTransferred),
+    m_transporter) );
+}
+
+std::vector< std::size_t >
+Discretization::bndel() const
+// *****************************************************************************
+// Find elements along our mesh chunk boundary
+//! \return List of local element ids that have at least a single node
+//!   contributing to a chare boundary
+// *****************************************************************************
+{
+  // Lambda to find out if a mesh node is shared with another chare
+  auto shared = [this]( std::size_t i ){
+    for (const auto& [c,n] : m_nodeCommMap)
+      if (n.find(i) != end(n)) return true;
+    return false;
+  };
+
+  // Find elements along our mesh chunk boundary
+  std::vector< std::size_t > e;
+  for (std::size_t n=0; n<m_inpoel.size(); ++n)
+    if (shared( m_gid[ m_inpoel[n] ] )) e.push_back( n/4 );
+  tk::unique( e );
+
+  return e;
+}
+
+void
+Discretization::resizePostAMR(
+  const tk::UnsMesh::Chunk& chunk,
+  const tk::UnsMesh::Coords& coord,
+  const std::unordered_map< std::size_t, std::size_t >& /*amrNodeMap*/,
+  const tk::NodeCommMap& nodeCommMap,
+  const std::set< std::size_t >& /*removedNodes*/,
+  const std::unordered_map< std::size_t, std::set< std::size_t > >& elemblockid )
+// *****************************************************************************
+//  Resize mesh data structures after mesh refinement
+//! \param[in] chunk New mesh chunk (connectivity and global<->local id maps)
+//! \param[in] coord New mesh node coordinates
+//! \param[in] amrNodeMap Node id map after amr (local ids)
+//! \param[in] nodeCommMap New node communication map
+//! \param[in] removedNodes Newly removed mesh node local ids
+//! \param[in] elemblockid New local tet ids associated with mesh block ids
+// *****************************************************************************
+{
+  m_el = chunk;         // updates m_inpoel, m_gid, m_lid
+  m_nodeCommMap.clear();
+  m_nodeCommMap = nodeCommMap;        // update node communication map
+  m_elemblockid.clear();
+  m_elemblockid = elemblockid;
+
+  // Update mesh volume container size
+  m_vol.resize( m_gid.size(), 0.0 );
+  if (!m_voln.empty()) m_voln.resize( m_gid.size(), 0.0 );
+
+  // Regenerate bid data
+  tk::destroy(m_bid);
+  m_bid = genBid();
+
+  // update mesh node coordinates
+  m_coord = coord;
+
+  // we are no longer during setup
+  m_initial = 0;
+}
+
+void
+Discretization::startvol()
+// *****************************************************************************
+//  Get ready for (re-)computing/communicating nodal volumes
+// *****************************************************************************
+{
+  m_nvol = 0;
+  thisProxy[ thisIndex ].wait4vol();
+
+  // Zero out mesh volume container
+  std::fill( begin(m_vol), end(m_vol), 0.0 );
+
+  // Clear receive buffer that will be used for collecting nodal volumes
+  m_volc.clear();
+}
+
+void
+Discretization::registerReducers()
+// *****************************************************************************
+//  Configure Charm++ reduction types
+//!  \details Since this is a [initnode] routine, see the .ci file, the
+//!   Charm++ runtime system executes the routine exactly once on every
+//!   logical node early on in the Charm++ init sequence. Must be static as
+//!   it is called without an object. See also: Section "Initializations at
+//!   Program Startup" at in the Charm++ manual
+//!   http://charm.cs.illinois.edu/manuals/html/charm++/manual.html.
+// *****************************************************************************
+{
+  PDFMerger = CkReduction::addReducer( tk::mergeUniPDFs );
+}
+
+tk::UnsMesh::Coords
+Discretization::setCoord( const tk::UnsMesh::CoordMap& coordmap )
+// *****************************************************************************
+// Set mesh coordinates based on coordinates map
+// *****************************************************************************
+{
+  Assert( coordmap.size() == m_gid.size(), "Size mismatch" );
+  Assert( coordmap.size() == m_lid.size(), "Size mismatch" );
+
+  tk::UnsMesh::Coords coord;
+  coord[0].resize( coordmap.size() );
+  coord[1].resize( coordmap.size() );
+  coord[2].resize( coordmap.size() );
+
+  for (const auto& [ gid, coords ] : coordmap) {
+    auto i = tk::cref_find( m_lid, gid );
+    coord[0][i] = coords[0];
+    coord[1][i] = coords[1];
+    coord[2][i] = coords[2];
+  }
+
+  return coord;
+}
+
+void
+Discretization::remap(
+  const std::unordered_map< std::size_t, std::size_t >& map )
+// *****************************************************************************
+//  Remap mesh data based on new local ids
+//! \param[in] map Mapping of old->new local ids
 // *****************************************************************************
-// Update mesh data we hold for whoever calls this function
-//! \param[in,out] ginpoel Mesh connectivity using global IDs
-//! \param[in,out] coordmap Map of mesh node coordinates
-//! \param[in,out] triinpoel Boundary face-node connectivity
-//! \param[in] bnode Node lists of side sets
-// *****************************************************************************
-{
-  ginpoel = m_ginpoel;
-  coordmap = m_coordmap;
-  triinpoel = m_triinpoel;
-  bnode = m_bnode;
-}
+{
+  // Remap connectivity containing local IDs
+  for (auto& l : m_inpoel) l = tk::cref_find(map,l);
+
+  // Remap global->local id map
+  for (auto& [g,l] : m_lid) l = tk::cref_find(map,l);
+
+  // Remap global->local id map
+  auto maxid = std::numeric_limits< std::size_t >::max();
+  std::vector< std::size_t > newgid( m_gid.size(), maxid );
+  for (const auto& [o,n] : map) newgid[n] = m_gid[o];
+  m_gid = std::move( newgid );
 
-void
-Sorter::createDiscWorkers()
-// *****************************************************************************
-//  Create Discretization chare array elements on this PE
-//! \details We create chare array elements by calling the insert() member
-//!   function, which allows specifying the PE on which the array element is
-//!   created. and we send each chare array element the chunk of mesh it will
-//!   operate on.
-// *****************************************************************************
-{
-  std::vector< CProxy_Discretization > disc;
-  for (auto& d : m_scheme) disc.push_back( d.disc() );<--- Consider using std::transform algorithm instead of a raw loop.
-
-  // Create worker array element using Charm++ dynamic chare array element
-  // insertion: last arg: PE chare is created on. See also Charm++ manual, Sec.
-  // "Dynamic Insertion".
-
-  m_scheme[m_meshid].disc()[ thisIndex ].insert( m_meshid, disc,
-    m_scheme[m_meshid].ale(),
-    m_scheme[m_meshid].conjugategradients(), m_host, m_meshwriter, m_coordmap,
-    m_el, m_msum, m_bface, m_triinpoel, m_elemblockid, m_nchare );
-
-  contribute( sizeof(std::size_t), &m_meshid, CkReduction::nop,
-              m_cbs.get< tag::discinserted >() );
-}
-
-void
-Sorter::createWorkers()
-// *****************************************************************************
-//  Create worker chare array element
+  Assert( std::all_of( m_gid.cbegin(), m_gid.cend(),
+            [=](std::size_t i){ return i < maxid; } ),
+          "Not all gid have been remapped" );
+
+  // Remap nodal volumes (with contributions along chare-boundaries)
+  std::vector< tk::real > newvol( m_vol.size(), 0.0 );
+  for (const auto& [o,n] : map) newvol[n] = m_vol[o];
+  m_vol = std::move( newvol );
+
+  // Remap nodal volumes (without contributions along chare-boundaries)
+  std::vector< tk::real > newv( m_v.size(), 0.0 );
+  for (const auto& [o,n] : map) newv[n] = m_v[o];
+  m_v = std::move( newv );
+
+  // Remap locations of node coordinates
+  tk::UnsMesh::Coords newcoord;
+  auto npoin = m_coord[0].size();
+  newcoord[0].resize( npoin );
+  newcoord[1].resize( npoin );
+  newcoord[2].resize( npoin );
+  for (const auto& [o,n] : map) {
+    newcoord[0][n] = m_coord[0][o];
+    newcoord[1][n] = m_coord[1][o];
+    newcoord[2][n] = m_coord[2][o];
+  }
+  m_coord = std::move( newcoord );
+}
+
+void
+Discretization::setRefiner( const CProxy_Refiner& ref )
 // *****************************************************************************
-{
-  // Make sure (bound) base is already created and accessible
-  Assert( m_scheme[m_meshid].disc()[thisIndex].ckLocal() != nullptr,
-          "About to pass nullptr" );
-
-  // Create worker array element using Charm++ dynamic chare array element
-  // insertion: 1st arg: chare id, other args: Discretization's child ctor args.
-  // See also Charm++ manual, Sec. "Dynamic Insertion".
-
-  m_scheme[m_meshid].insert( thisIndex, m_scheme[m_meshid].disc(),
-    m_scheme[m_meshid].ghosts(), m_bface, m_bnode, m_triinpoel );
-
-  if ( g_inputdeck.get< tag::cmd, tag::feedback >() ) m_host.chcreated();
-
-  contribute( sizeof(std::size_t), &m_meshid, CkReduction::nop,
-              m_cbs.get< tag::workinserted >() );
+//  Set Refiner Charm++ proxy
+//! \param[in] ref Incoming refiner proxy to store
+// *****************************************************************************
+{
+  m_refiner = ref;
+}
+
+void
+Discretization::vol()
+// *****************************************************************************
+// Sum mesh volumes to nodes, start communicating them on chare-boundaries
+// *****************************************************************************
+{
+  const auto& x = m_coord[0];
+  const auto& y = m_coord[1];
+  const auto& z = m_coord[2];
 
-  // Free up some memory
-  tk::destroy( m_ginpoel );
-  tk::destroy( m_coordmap );
-  tk::destroy( m_bface );
-  tk::destroy( m_triinpoel );
-  tk::destroy( m_elemblockid );
-  tk::destroy( m_bnode );
-  tk::destroy( m_nodeset );
-  tk::destroy( m_nodech );
-  tk::destroy( m_chnode );
-  tk::destroy( m_msum );
-  tk::destroy( m_reordcomm );
-  tk::destroy( m_newnodes );
-  tk::destroy( m_reqnodes );
-}
-
-#include "NoWarning/sorter.def.h"
+  // Compute nodal volumes on our chunk of the mesh
+  for (std::size_t e=0; e<m_inpoel.size()/4; ++e) {
+    const std::array< std::size_t, 4 > N{{ m_inpoel[e*4+0], m_inpoel[e*4+1],
+                                           m_inpoel[e*4+2], m_inpoel[e*4+3] }};
+    // compute element Jacobi determinant * 5/120 = element volume / 4
+    const std::array< tk::real, 3 >
+      ba{{ x[N[1]]-x[N[0]], y[N[1]]-y[N[0]], z[N[1]]-z[N[0]] }},
+      ca{{ x[N[2]]-x[N[0]], y[N[2]]-y[N[0]], z[N[2]]-z[N[0]] }},
+      da{{ x[N[3]]-x[N[0]], y[N[3]]-y[N[0]], z[N[3]]-z[N[0]] }};
+    const auto J = tk::triple( ba, ca, da ) * 5.0 / 120.0;
+    ErrChk( J > 0, "Element Jacobian non-positive: PE:" +
+                   std::to_string(CkMyPe()) + ", node IDs: " +
+                   std::to_string(m_gid[N[0]]) + ',' +
+                   std::to_string(m_gid[N[1]]) + ',' +
+                   std::to_string(m_gid[N[2]]) + ',' +
+                   std::to_string(m_gid[N[3]]) + ", coords: (" +
+                   std::to_string(x[N[0]]) + ", " +
+                   std::to_string(y[N[0]]) + ", " +
+                   std::to_string(z[N[0]]) + "), (" +
+                   std::to_string(x[N[1]]) + ", " +
+                   std::to_string(y[N[1]]) + ", " +
+                   std::to_string(z[N[1]]) + "), (" +
+                   std::to_string(x[N[2]]) + ", " +
+                   std::to_string(y[N[2]]) + ", " +
+                   std::to_string(z[N[2]]) + "), (" +
+                   std::to_string(x[N[3]]) + ", " +
+                   std::to_string(y[N[3]]) + ", " +
+                   std::to_string(z[N[3]]) + ')' );
+    // scatter add V/4 to nodes
+    for (std::size_t j=0; j<4; ++j) m_vol[N[j]] += J;
+
+    // save element volumes at t=t0
+    if (m_it == 0) m_vol0[e] = J * 4.0;
+  }
+
+  // Store nodal volumes without contributions from other chares on
+  // chare-boundaries
+  m_v = m_vol;
+
+  // Send our nodal volume contributions to neighbor chares
+  if (m_nodeCommMap.empty())
+   totalvol();
+  else
+    for (const auto& [c,n] : m_nodeCommMap) {
+      std::vector< tk::real > v( n.size() );
+      std::size_t j = 0;
+      for (auto i : n) v[ j++ ] = m_vol[ tk::cref_find(m_lid,i) ];
+      thisProxy[c].comvol( std::vector<std::size_t>(begin(n), end(n)), v );
+    }
+
+  ownvol_complete();
+}
+
+void
+Discretization::comvol( const std::vector< std::size_t >& gid,
+                        const std::vector< tk::real >& nodevol )
+// *****************************************************************************
+//  Receive nodal volumes on chare-boundaries
+//! \param[in] gid Global mesh node IDs at which we receive volume contributions
+//! \param[in] nodevol Partial sums of nodal volume contributions to
+//!    chare-boundary nodes
+//! \details This function receives contributions to m_vol, which stores the
+//!   nodal volumes. While m_vol stores own contributions, m_volc collects the
+//!   neighbor chare contributions during communication. This way work on m_vol
+//!   and m_volc is overlapped. The contributions are applied in totalvol().
+// *****************************************************************************
+{
+  Assert( nodevol.size() == gid.size(), "Size mismatch" );
+
+  for (std::size_t i=0; i<gid.size(); ++i)
+    m_volc[ gid[i] ] += nodevol[i];
+
+  if (++m_nvol == m_nodeCommMap.size()) {
+    m_nvol = 0;
+    comvol_complete();
+  }
+}
+
+void
+Discretization::totalvol()
+// *****************************************************************************
+// Sum mesh volumes and contribute own mesh volume to total volume
+// *****************************************************************************
+{
+  // Add received contributions to nodal volumes
+  for (const auto& [gid, vol] : m_volc)
+    m_vol[ tk::cref_find(m_lid,gid) ] += vol;
+
+  // Clear receive buffer
+  tk::destroy(m_volc);
+
+  // Sum mesh volume to host
+  std::vector< tk::real > tvol{ 0.0,
+                                static_cast<tk::real>(m_initial),
+                                static_cast<tk::real>(m_meshid) };
+  for (auto v : m_v) tvol[0] += v;
+  contribute( tvol, CkReduction::sum_double,
+    CkCallback(CkReductionTarget(Transporter,totalvol), m_transporter) );
+}
+
+void
+Discretization::stat( tk::real mesh_volume )
+// *****************************************************************************
+// Compute mesh cell statistics
+//! \param[in] mesh_volume Total mesh volume
+// *****************************************************************************
+{
+  // Store total mesh volume
+  m_meshvol = mesh_volume;
+
+  const auto& x = m_coord[0];
+  const auto& y = m_coord[1];
+  const auto& z = m_coord[2];
+
+  auto MIN = -std::numeric_limits< tk::real >::max();
+  auto MAX = std::numeric_limits< tk::real >::max();
+  std::vector< tk::real > min{ MAX, MAX, MAX };
+  std::vector< tk::real > max{ MIN, MIN, MIN };
+  std::vector< tk::real > sum{ 0.0, 0.0, 0.0, 0.0, 0.0, 0.0 };
+  tk::UniPDF edgePDF( 1e-4 );
+  tk::UniPDF volPDF( 1e-4 );
+  tk::UniPDF ntetPDF( 1e-4 );
+
+  // Compute points surrounding points
+  auto psup = tk::genPsup( m_inpoel, 4, tk::genEsup(m_inpoel,4) );
+  Assert( psup.second.size()-1 == m_gid.size(),
+          "Number of mesh points and number of global IDs unequal" );
+
+  // Compute edge length statistics
+  // Note that while the min and max edge lengths are independent of the number
+  // of CPUs (by the time they are aggregated across all chares), the sum of
+  // the edge lengths and the edge length PDF are not. This is because the
+  // edges on the chare-boundary are counted multiple times and we
+  // conscientiously do not make an effort to precisely compute this, because
+  // that would require communication and more complex logic. Since these
+  // statistics are intended as simple average diagnostics, we ignore these
+  // small differences. For reproducible average edge lengths and edge length
+  // PDFs, run the mesh in serial.
+  for (std::size_t p=0; p<m_gid.size(); ++p)
+    for (auto i : tk::Around(psup,p)) {
+       const auto dx = x[ i ] - x[ p ];
+       const auto dy = y[ i ] - y[ p ];
+       const auto dz = z[ i ] - z[ p ];
+       const auto length = std::sqrt( dx*dx + dy*dy + dz*dz );
+       if (length < min[0]) min[0] = length;
+       if (length > max[0]) max[0] = length;
+       sum[0] += 1.0;
+       sum[1] += length;
+       edgePDF.add( length );
+    }
+
+  // Compute mesh cell volume statistics
+  for (std::size_t e=0; e<m_inpoel.size()/4; ++e) {
+    const std::array< std::size_t, 4 > N{{ m_inpoel[e*4+0], m_inpoel[e*4+1],
+                                           m_inpoel[e*4+2], m_inpoel[e*4+3] }};
+    const std::array< tk::real, 3 >
+      ba{{ x[N[1]]-x[N[0]], y[N[1]]-y[N[0]], z[N[1]]-z[N[0]] }},
+      ca{{ x[N[2]]-x[N[0]], y[N[2]]-y[N[0]], z[N[2]]-z[N[0]] }},
+      da{{ x[N[3]]-x[N[0]], y[N[3]]-y[N[0]], z[N[3]]-z[N[0]] }};
+    const auto L = std::cbrt( tk::triple( ba, ca, da ) / 6.0 );
+    if (L < min[1]) min[1] = L;
+    if (L > max[1]) max[1] = L;
+    sum[2] += 1.0;
+    sum[3] += L;
+    volPDF.add( L );
+  }
+
+  // Contribute stats of number of tetrahedra (ntets)
+  sum[4] = 1.0;
+  min[2] = max[2] = sum[5] = static_cast< tk::real >( m_inpoel.size() / 4 );
+  ntetPDF.add( min[2] );
+
+  min.push_back( static_cast<tk::real>(m_meshid) );
+  max.push_back( static_cast<tk::real>(m_meshid) );
+  sum.push_back( static_cast<tk::real>(m_meshid) );
+
+  // Contribute to mesh statistics across all Discretization chares
+  contribute( min, CkReduction::min_double,
+    CkCallback(CkReductionTarget(Transporter,minstat), m_transporter) );
+  contribute( max, CkReduction::max_double,
+    CkCallback(CkReductionTarget(Transporter,maxstat), m_transporter) );
+  contribute( sum, CkReduction::sum_double,
+    CkCallback(CkReductionTarget(Transporter,sumstat), m_transporter) );
+
+  // Serialize PDFs to raw stream
+  auto stream = tk::serialize( m_meshid, { edgePDF, volPDF, ntetPDF } );
+  // Create Charm++ callback function for reduction of PDFs with
+  // Transporter::pdfstat() as the final target where the results will appear.
+  CkCallback cb( CkIndex_Transporter::pdfstat(nullptr), m_transporter );
+  // Contribute serialized PDF of partial sums to host via Charm++ reduction
+  contribute( stream.first, stream.second.get(), PDFMerger, cb );
+}
+
+void
+Discretization::boxvol(
+  const std::vector< std::unordered_set< std::size_t > >& nodes,
+  const std::unordered_map< std::size_t, std::set< std::size_t > >& nodeblk,
+  std::size_t nuserblk )
+// *****************************************************************************
+// Compute total box IC volume
+//! \param[in] nodes Node list contributing to box IC volume (for each IC box)
+//! \param[in] nodeblk Node list associated to mesh blocks contributing to block
+//!   volumes (for each IC box)
+//! \param[in] nuserblk Number of user IC mesh blocks
+// *****************************************************************************
+{
+  // Compute partial box IC volume (just add up all boxes)
+  tk::real boxvol = 0.0;
+  for (const auto& b : nodes) for (auto i : b) boxvol += m_v[i];<--- Consider using std::accumulate algorithm instead of a raw loop.
+
+  // Compute partial IC mesh block volume
+  std::vector< tk::real > blockvols;
+  if (nuserblk > 0) {
+    blockvols.resize(nuserblk,0.0);
+    for (const auto& [blid, ndset] : nodeblk) {
+      // The following if-test makes sure we access volumes only of mesh blocks
+      // with user-specified ICs
+      if (blid < nuserblk) {
+        for (const auto& n : ndset) blockvols[blid] += m_v[n];
+      }
+    }
+  }
+
+  // Sum up box IC volume across all chares
+  auto meshdata = blockvols;
+  meshdata.push_back(boxvol);
+  meshdata.push_back(static_cast<tk::real>(m_meshid));
+  contribute( meshdata, CkReduction::sum_double,
+    CkCallback(CkReductionTarget(Transporter,boxvol), m_transporter) );
+}
+
+void
+Discretization::write(
+  const std::vector< std::size_t >& inpoel,
+  const tk::UnsMesh::Coords& coord,
+  const std::map< int, std::vector< std::size_t > >& bface,
+  const std::map< int, std::vector< std::size_t > >& bnode,
+  const std::vector< std::size_t >& triinpoel,
+  const std::vector< std::string>& elemfieldnames,
+  const std::vector< std::string>& nodefieldnames,
+  const std::vector< std::string>& elemsurfnames,
+  const std::vector< std::string>& nodesurfnames,
+  const std::vector< std::vector< tk::real > >& elemfields,
+  const std::vector< std::vector< tk::real > >& nodefields,
+  const std::vector< std::vector< tk::real > >& elemsurfs,
+  const std::vector< std::vector< tk::real > >& nodesurfs,
+  CkCallback c )
+// *****************************************************************************
+//  Output mesh and fields data (solution dump) to file(s)
+//! \param[in] inpoel Mesh connectivity for the mesh chunk to be written
+//! \param[in] coord Node coordinates of the mesh chunk to be written
+//! \param[in] bface Map of boundary-face lists mapped to corresponding side set
+//!   ids for this mesh chunk
+//! \param[in] bnode Map of boundary-node lists mapped to corresponding side set
+//!   ids for this mesh chunk
+//! \param[in] triinpoel Interconnectivity of points and boundary-face in this
+//!   mesh chunk
+//! \param[in] elemfieldnames Names of element fields to be output to file
+//! \param[in] nodefieldnames Names of node fields to be output to file
+//! \param[in] elemsurfnames Names of elemental surface fields to be output to
+//!   file
+//! \param[in] nodesurfnames Names of node surface fields to be output to file
+//! \param[in] elemfields Field data in mesh elements to output to file
+//! \param[in] nodefields Field data in mesh nodes to output to file
+//! \param[in] elemsurfs Surface field data in mesh elements to output to file
+//! \param[in] nodesurfs Surface field data in mesh nodes to output to file
+//! \param[in] c Function to continue with after the write
+//! \details Since m_meshwriter is a Charm++ chare group, it never migrates and
+//!   an instance is guaranteed on every PE. We index the first PE on every
+//!   logical compute node. In Charm++'s non-SMP mode, a node is the same as a
+//!   PE, so the index is the same as CkMyPe(). In SMP mode the index is the
+//!   first PE on every logical node. In non-SMP mode this yields one or more
+//!   output files per PE with zero or non-zero virtualization, respectively. If
+//!   there are multiple chares on a PE, the writes are serialized per PE, since
+//!   only a single entry method call can be executed at any given time. In SMP
+//!   mode, still the same number of files are output (one per chare), but the
+//!   output is serialized through the first PE of each compute node. In SMP
+//!   mode, channeling multiple files via a single PE on each node is required
+//!   by NetCDF and HDF5, as well as ExodusII, since none of these libraries are
+//!   thread-safe.
+// *****************************************************************************
+{
+  // If the previous iteration refined (or moved) the mesh or this is called
+  // before the first time step, we also output the mesh.
+  bool meshoutput = m_itf == 0 ? true : false;
+
+  auto eps = std::numeric_limits< tk::real >::epsilon();
+  bool fieldoutput = false;
+
+  // Output field data only if there is no dump at this physical time yet
+  if (std::abs(m_lastDumpTime - m_t) > eps ) {
+    m_lastDumpTime = m_t;
+    ++m_itf;
+    fieldoutput = true;
+  }
+
+  // set of sidesets where fieldoutput is required
+  std::set< int > outsets;
+  const auto& osv = g_inputdeck.get< tag::field_output, tag::sideset >();
+  outsets.insert(osv.begin(), osv.end());
+
+  m_meshwriter[ CkNodeFirst( CkMyNode() ) ].
+    write( m_meshid, meshoutput, fieldoutput, m_itr, m_itf, m_t, thisIndex,
+           g_inputdeck.get< tag::cmd, tag::io, tag::output >(),
+           inpoel, coord, bface, bnode, triinpoel, elemfieldnames,
+           nodefieldnames, elemsurfnames, nodesurfnames, elemfields, nodefields,
+           elemsurfs, nodesurfs, outsets, c );
+}
+
+void
+Discretization::setdt( tk::real newdt )
+// *****************************************************************************
+// Set time step size
+//! \param[in] newdt Size of the new time step
+// *****************************************************************************
+{
+  m_dtn = m_dt;
+  m_dt = newdt;
+
+  // Truncate the size of last time step
+  const auto term = g_inputdeck.get< tag::term >();
+  if (m_t+m_dt > term) m_dt = term - m_t;
+}
+
+void
+Discretization::next()
+// *****************************************************************************
+// Prepare for next step
+// *****************************************************************************
+{
+  // Update floor of physics time divided by output interval times
+  const auto eps = std::numeric_limits< tk::real >::epsilon();
+  const auto ft = g_inputdeck.get< tag::field_output, tag::time_interval >();
+  if (ft > eps) m_physFieldFloor = std::floor( m_t / ft );
+  const auto ht = g_inputdeck.get< tag::history_output, tag::time_interval >();
+  if (ht > eps) m_physHistFloor = std::floor( m_t / ht );
+
+  // Update floors of physics time divided by output interval times for ranges
+  const auto& rf = g_inputdeck.get< tag::field_output, tag::time_range >();
+  if (!rf.empty()) {
+    if (m_t > rf[0] and m_t < rf[1])
+      m_rangeFieldFloor = std::floor( m_t / rf[2] );
+    const auto& rh = g_inputdeck.get< tag::history_output, tag::time_range >();
+    if (m_t > rh[0] and m_t < rh[1])
+      m_rangeHistFloor = std::floor( m_t / rh[2] );
+  }
+
+  ++m_it;
+  m_t += m_dt;
+}
+
+void
+Discretization::grindZero()
+// *****************************************************************************
+//  Zero grind-time
+// *****************************************************************************
+{
+  m_prevstatus = std::chrono::high_resolution_clock::now();
+
+  if (thisIndex == 0 && m_meshid == 0) {
+    const auto verbose = g_inputdeck.get< tag::cmd, tag::verbose >();
+    const auto& def =
+      g_inputdeck_defaults.get< tag::cmd, tag::io, tag::screen >();
+    tk::Print print( g_inputdeck.get< tag::cmd >().logname( def, m_nrestart ),
+                     verbose ? std::cout : std::clog,
+                     std::ios_base::app );
+    print.diag( "Starting time stepping ..." );
+  }
+}
+
+bool
+Discretization::restarted( int nrestart )
+// *****************************************************************************
+//  Detect if just returned from a checkpoint and if so, zero timers
+//! \param[in] nrestart Number of times restarted
+//! \return True if restart detected
+// *****************************************************************************
+{
+  // Detect if just restarted from checkpoint:
+  //   nrestart == -1 if there was no checkpoint this step
+  //   d->Nrestart() == nrestart if there was a checkpoint this step
+  //   if both false, just restarted from a checkpoint
+  bool restarted = nrestart != -1 and m_nrestart != nrestart;
+
+   // If just restarted from checkpoint
+  if (restarted) {
+    // Update number of restarts
+    m_nrestart = nrestart;
+    // Start timer measuring time stepping wall clock time
+    m_timer.zero();
+    // Zero grind-timer
+    grindZero();
+  }
+
+  return restarted;
+}
+
+std::string
+Discretization::histfilename( const std::string& id,
+                              std::streamsize precision )
+// *****************************************************************************
+//  Construct history output filename
+//! \param[in] id History point id
+//! \param[in] precision Floating point precision to use for output
+//! \return History file name
+// *****************************************************************************
+{
+  auto of = g_inputdeck.get< tag::cmd, tag::io, tag::output >();
+  std::stringstream ss;
+
+  auto mid =
+    m_disc.size() > 1 ? std::string( '.' + std::to_string(m_meshid) ) : "";
+  ss << std::setprecision(static_cast<int>(precision)) << of << mid << ".hist." << id;
+
+  return ss.str();
+}
+
+void
+Discretization::histheader( std::vector< std::string >&& names )
+// *****************************************************************************
+//  Output headers for time history files (one for each point)
+//! \param[in] names History output variable names
+// *****************************************************************************
+{
+  for (const auto& h : m_histdata) {
+    auto prec = g_inputdeck.get< tag::history_output, tag::precision >();
+    tk::DiagWriter hw( histfilename( h.get< tag::id >(), prec ),
+                       g_inputdeck.get< tag::history_output, tag::format >(),
+                       prec );
+    hw.header( names );
+  }
+}
+
+void
+Discretization::history( std::vector< std::vector< tk::real > >&& data )
+// *****************************************************************************
+//  Output time history for a time step
+//! \param[in] data Time history data for all variables and equations integrated
+// *****************************************************************************
+{
+  Assert( data.size() == m_histdata.size(), "Size mismatch" );
+
+  std::size_t i = 0;
+  for (const auto& h : m_histdata) {
+    auto prec = g_inputdeck.get< tag::history_output, tag::precision >();
+    tk::DiagWriter hw( histfilename( h.get< tag::id >(), prec ),
+                       g_inputdeck.get< tag::history_output, tag::format >(),
+                       prec,
+                       std::ios_base::app );
+    hw.diag( m_it, m_t, m_dt, data[i] );
+    ++i;
+  }
+}
+
+bool
+Discretization::fielditer() const
+// *****************************************************************************
+//  Decide if field output iteration count interval is hit
+//! \return True if field output iteration count interval is hit
+// *****************************************************************************
+{
+  if (g_inputdeck.get< tag::cmd, tag::benchmark >()) return false;
+
+  return m_it % g_inputdeck.get< tag::field_output, tag::interval >() == 0;
+}
+
+bool
+Discretization::fieldtime() const
+// *****************************************************************************
+//  Decide if field output physics time interval is hit
+//! \return True if field output physics time interval is hit
+// *****************************************************************************
+{
+  if (g_inputdeck.get< tag::cmd, tag::benchmark >()) return false;
+
+  const auto eps = std::numeric_limits< tk::real >::epsilon();
+  const auto ft = g_inputdeck.get< tag::field_output, tag::time_interval >();
+
+  if (ft < eps) return false;
+
+  return std::floor(m_t/ft) - m_physFieldFloor > eps;
+}
+
+bool
+Discretization::fieldrange() const
+// *****************************************************************************
+//  Decide if physics time falls into a field output time range
+//! \return True if physics time falls into a field output time range
+// *****************************************************************************
+{
+  if (g_inputdeck.get< tag::cmd, tag::benchmark >()) return false;
+
+  const auto eps = std::numeric_limits< tk::real >::epsilon();
+
+  bool output = false;
+
+  const auto& rf = g_inputdeck.get< tag::field_output, tag::time_range >();
+  if (!rf.empty()) {
+    if (m_t > rf[0] and m_t < rf[1])
+      output |= std::floor(m_t/rf[2]) - m_rangeFieldFloor > eps;
+  }
+
+  return output;
+}
+
+bool
+Discretization::histiter() const
+// *****************************************************************************
+//  Decide if history output iteration count interval is hit
+//! \return True if history output iteration count interval is hit
+// *****************************************************************************
+{
+  const auto hist = g_inputdeck.get< tag::history_output, tag::interval >();
+  const auto& hist_points = g_inputdeck.get< tag::history_output, tag::point >();
+
+  return m_it % hist == 0 and not hist_points.empty();
+}
+
+bool
+Discretization::histtime() const
+// *****************************************************************************
+//  Decide if history output physics time interval is hit
+//! \return True if history output physics time interval is hit
+// *****************************************************************************
+{
+  if (g_inputdeck.get< tag::cmd, tag::benchmark >()) return false;
+
+  const auto eps = std::numeric_limits< tk::real >::epsilon();
+  const auto ht = g_inputdeck.get< tag::history_output, tag::time_interval >();
+
+  if (ht < eps) return false;
+
+  return std::floor(m_t/ht) - m_physHistFloor > eps;
+}
+
+bool
+Discretization::histrange() const
+// *****************************************************************************
+//  Decide if physics time falls into a history output time range
+//! \return True if physics time falls into a history output time range
+// *****************************************************************************
+{
+  if (g_inputdeck.get< tag::cmd, tag::benchmark >()) return false;
+
+  const auto eps = std::numeric_limits< tk::real >::epsilon();
+
+  bool output = false;
+
+  const auto& rh = g_inputdeck.get< tag::history_output, tag::time_range >();
+  if (!rh.empty()) {
+    if (m_t > rh[0] and m_t < rh[1])
+      output |= std::floor(m_t/rh[2]) - m_rangeHistFloor > eps;
+  }
+
+  return output;
+}
+
+bool
+Discretization::finished() const
+// *****************************************************************************
+//  Decide if this is the last time step
+//! \return True if this is the last time step
+// *****************************************************************************
+{
+  const auto eps = std::numeric_limits< tk::real >::epsilon();
+  const auto nstep = g_inputdeck.get< tag::nstep >();
+  const auto term = g_inputdeck.get< tag::term >();
+
+  return std::abs(m_t-term) < eps or m_it >= nstep;
+}
+
+void
+Discretization::status()
+// *****************************************************************************
+// Output one-liner status report
+// *****************************************************************************
+{
+  // Query after how many time steps user wants TTY dump
+  const auto tty = g_inputdeck.get< tag::ttyi >();
+
+  // estimate grind time (taken between this and the previous time step)
+  using std::chrono::duration_cast;
+  using ms = std::chrono::milliseconds;
+  using clock = std::chrono::high_resolution_clock;
+  auto grind_time = duration_cast< ms >(clock::now() - m_prevstatus).count();
+  m_prevstatus = clock::now();
+
+  if (thisIndex==0 and m_meshid == 0 and not (m_it%tty)) {
+
+    const auto term = g_inputdeck.get< tag::term >();
+    const auto t0 = g_inputdeck.get< tag::t0 >();
+    const auto nstep = g_inputdeck.get< tag::nstep >();
+    const auto diag = g_inputdeck.get< tag::diagnostics, tag::interval >();
+    const auto lbfreq = g_inputdeck.get< tag::cmd, tag::lbfreq >();
+    const auto rsfreq = g_inputdeck.get< tag::cmd, tag::rsfreq >();
+    const auto verbose = g_inputdeck.get< tag::cmd, tag::verbose >();
+    const auto benchmark = g_inputdeck.get< tag::cmd, tag::benchmark >();
+    const auto steady = g_inputdeck.get< tag::steady_state >();
+
+    // estimate time elapsed and time for accomplishment
+    tk::Timer::Watch ete, eta;
+    if (not steady) m_timer.eta( term-t0, m_t-t0, nstep, m_it, ete, eta );
+
+    const auto& def =
+      g_inputdeck_defaults.get< tag::cmd, tag::io, tag::screen >();
+    tk::Print print( g_inputdeck.get< tag::cmd >().logname( def, m_nrestart ),
+                     verbose ? std::cout : std::clog,
+                     std::ios_base::app );
+
+    // Output one-liner
+    print << std::setfill(' ') << std::setw(8) << m_it << "  "
+          << std::scientific << std::setprecision(6)
+          << std::setw(12) << m_t << "  "
+          << m_dt << "  "
+          << std::setfill('0')
+          << std::setw(3) << ete.hrs.count() << ":"
+          << std::setw(2) << ete.min.count() << ":"
+          << std::setw(2) << ete.sec.count() << "  "
+          << std::setw(3) << eta.hrs.count() << ":"
+          << std::setw(2) << eta.min.count() << ":"
+          << std::setw(2) << eta.sec.count() << "  "
+          << std::scientific << std::setprecision(6) << std::setfill(' ')
+          << std::setw(9) << grind_time << "  ";
+
+    // Augment one-liner status with output indicators
+    if (fielditer() or fieldtime() or fieldrange()) print << 'f';
+    if (not (m_it % diag)) print << 'd';
+    if (histiter() or histtime() or histrange()) print << 't';
+    if (m_refined) print << 'h';
+    if (not (m_it % lbfreq) && not finished()) print << 'l';
+    if (not benchmark && (not (m_it % rsfreq) || finished())) print << 'r';
+
+    if (not m_meshvel_converged) print << 'a';
+    m_meshvel_converged = true; // get ready for next time step
+
+    print << std::endl;
+  }
+}
+
+#include "NoWarning/discretization.def.h"
 
diff --git a/Debug/cppcheck/38.html b/Debug/cppcheck/38.html index dd1fd6d2c60f..74b54df059f0 100644 --- a/Debug/cppcheck/38.html +++ b/Debug/cppcheck/38.html @@ -152,2199 +152,853 @@
- - + @@ -73,7 +73,7 @@ - + @@ -85,7 +85,7 @@ - + @@ -97,7 +97,7 @@ - + @@ -105,7 +105,7 @@ - +
   1
-   2
-   3
-   4
-   5
-   6
-   7
-   8
-   9
-  10
-  11
-  12
-  13
-  14
-  15
-  16
-  17
-  18
-  19
-  20
-  21
-  22
-  23
-  24
-  25
-  26
-  27
-  28
-  29
-  30
-  31
-  32
-  33
-  34
-  35
-  36
-  37
-  38
-  39
-  40
-  41
-  42
-  43
-  44
-  45
-  46
-  47
-  48
-  49
-  50
-  51
-  52
-  53
-  54
-  55
-  56
-  57
-  58
-  59
-  60
-  61
-  62
-  63
-  64
-  65
-  66
-  67
-  68
-  69
-  70
-  71
-  72
-  73
-  74
-  75
-  76
-  77
-  78
-  79
-  80
-  81
-  82
-  83
-  84
-  85
-  86
-  87
-  88
-  89
-  90
-  91
-  92
-  93
-  94
-  95
-  96
-  97
-  98
-  99
- 100
- 101
- 102
- 103
- 104
- 105
- 106
- 107
- 108
- 109
- 110
- 111
- 112
- 113
- 114
- 115
- 116
- 117
- 118
- 119
- 120
- 121
- 122
- 123
- 124
- 125
- 126
- 127
- 128
- 129
- 130
- 131
- 132
- 133
- 134
- 135
- 136
- 137
- 138
- 139
- 140
- 141
- 142
- 143
- 144
- 145
- 146
- 147
- 148
- 149
- 150
- 151
- 152
- 153
- 154
- 155
- 156
- 157
- 158
- 159
- 160
- 161
- 162
- 163
- 164
- 165
- 166
- 167
- 168
- 169
- 170
- 171
- 172
- 173
- 174
- 175
- 176
- 177
- 178
- 179
- 180
- 181
- 182
- 183
- 184
- 185
- 186
- 187
- 188
- 189
- 190
- 191
- 192
- 193
- 194
- 195
- 196
- 197
- 198
- 199
- 200
- 201
- 202
- 203
- 204
- 205
- 206
- 207
- 208
- 209
- 210
- 211
- 212
- 213
- 214
- 215
- 216
- 217
- 218
- 219
- 220
- 221
- 222
- 223
- 224
- 225
- 226
- 227
- 228
- 229
- 230
- 231
- 232
- 233
- 234
- 235
- 236
- 237
- 238
- 239
- 240
- 241
- 242
- 243
- 244
- 245
- 246
- 247
- 248
- 249
- 250
- 251
- 252
- 253
- 254
- 255
- 256
- 257
- 258
- 259
- 260
- 261
- 262
- 263
- 264
- 265
- 266
- 267
- 268
- 269
- 270
- 271
- 272
- 273
- 274
- 275
- 276
- 277
- 278
- 279
- 280
- 281
- 282
- 283
- 284
- 285
- 286
- 287
- 288
- 289
- 290
- 291
- 292
- 293
- 294
- 295
- 296
- 297
- 298
- 299
- 300
- 301
- 302
- 303
- 304
- 305
- 306
- 307
- 308
- 309
- 310
- 311
- 312
- 313
- 314
- 315
- 316
- 317
- 318
- 319
- 320
- 321
- 322
- 323
- 324
- 325
- 326
- 327
- 328
- 329
- 330
- 331
- 332
- 333
- 334
- 335
- 336
- 337
- 338
- 339
- 340
- 341
- 342
- 343
- 344
- 345
- 346
- 347
- 348
- 349
- 350
- 351
- 352
- 353
- 354
- 355
- 356
- 357
- 358
- 359
- 360
- 361
- 362
- 363
- 364
- 365
- 366
- 367
- 368
- 369
- 370
- 371
- 372
- 373
- 374
- 375
- 376
- 377
- 378
- 379
- 380
- 381
- 382
- 383
- 384
- 385
- 386
- 387
- 388
- 389
- 390
- 391
- 392
- 393
- 394
- 395
- 396
- 397
- 398
- 399
- 400
- 401
- 402
- 403
- 404
- 405
- 406
- 407
- 408
- 409
- 410
- 411
- 412
- 413
- 414
- 415
- 416
- 417
- 418
- 419
- 420
- 421
- 422
- 423
- 424
- 425
- 426
- 427
- 428
- 429
- 430
- 431
- 432
- 433
- 434
- 435
- 436
- 437
- 438
- 439
- 440
- 441
- 442
- 443
- 444
- 445
- 446
- 447
- 448
- 449
- 450
- 451
- 452
- 453
- 454
- 455
- 456
- 457
- 458
- 459
- 460
- 461
- 462
- 463
- 464
- 465
- 466
- 467
- 468
- 469
- 470
- 471
- 472
- 473
- 474
- 475
- 476
- 477
- 478
- 479
- 480
- 481
- 482
- 483
- 484
- 485
- 486
- 487
- 488
- 489
- 490
- 491
- 492
- 493
- 494
- 495
- 496
- 497
- 498
- 499
- 500
- 501
- 502
- 503
- 504
- 505
- 506
- 507
- 508
- 509
- 510
- 511
- 512
- 513
- 514
- 515
- 516
- 517
- 518
- 519
- 520
- 521
- 522
- 523
- 524
- 525
- 526
- 527
- 528
- 529
- 530
- 531
- 532
- 533
- 534
- 535
- 536
- 537
- 538
- 539
- 540
- 541
- 542
- 543
- 544
- 545
- 546
- 547
- 548
- 549
- 550
- 551
- 552
- 553
- 554
- 555
- 556
- 557
- 558
- 559
- 560
- 561
- 562
- 563
- 564
- 565
- 566
- 567
- 568
- 569
- 570
- 571
- 572
- 573
- 574
- 575
- 576
- 577
- 578
- 579
- 580
- 581
- 582
- 583
- 584
- 585
- 586
- 587
- 588
- 589
- 590
- 591
- 592
- 593
- 594
- 595
- 596
- 597
- 598
- 599
- 600
- 601
- 602
- 603
- 604
- 605
- 606
- 607
- 608
- 609
- 610
- 611
- 612
- 613
- 614
- 615
- 616
- 617
- 618
- 619
- 620
- 621
- 622
- 623
- 624
- 625
- 626
- 627
- 628
- 629
- 630
- 631
- 632
- 633
- 634
- 635
- 636
- 637
- 638
- 639
- 640
- 641
- 642
- 643
- 644
- 645
- 646
- 647
- 648
- 649
- 650
- 651
- 652
- 653
- 654
- 655
- 656
- 657
- 658
- 659
- 660
- 661
- 662
- 663
- 664
- 665
- 666
- 667
- 668
- 669
- 670
- 671
- 672
- 673
- 674
- 675
- 676
- 677
- 678
- 679
- 680
- 681
- 682
- 683
- 684
- 685
- 686
- 687
- 688
- 689
- 690
- 691
- 692
- 693
- 694
- 695
- 696
- 697
- 698
- 699
- 700
- 701
- 702
- 703
- 704
- 705
- 706
- 707
- 708
- 709
- 710
- 711
- 712
- 713
- 714
- 715
- 716
- 717
- 718
- 719
- 720
- 721
- 722
- 723
- 724
- 725
- 726
- 727
- 728
- 729
- 730
- 731
- 732
- 733
- 734
- 735
- 736
- 737
- 738
- 739
- 740
- 741
- 742
- 743
- 744
- 745
- 746
- 747
- 748
- 749
- 750
- 751
- 752
- 753
- 754
- 755
- 756
- 757
- 758
- 759
- 760
- 761
- 762
- 763
- 764
- 765
- 766
- 767
- 768
- 769
- 770
- 771
- 772
- 773
- 774
- 775
- 776
- 777
- 778
- 779
- 780
- 781
- 782
- 783
- 784
- 785
- 786
- 787
- 788
- 789
- 790
- 791
- 792
- 793
- 794
- 795
- 796
- 797
- 798
- 799
- 800
- 801
- 802
- 803
- 804
- 805
- 806
- 807
- 808
- 809
- 810
- 811
- 812
- 813
- 814
- 815
- 816
- 817
- 818
- 819
- 820
- 821
- 822
- 823
- 824
- 825
- 826
- 827
- 828
- 829
- 830
- 831
- 832
- 833
- 834
- 835
- 836
- 837
- 838
- 839
- 840
- 841
- 842
- 843
- 844
- 845
- 846
- 847
- 848
- 849
- 850
- 851
- 852
- 853
- 854
- 855
- 856
- 857
- 858
- 859
- 860
- 861
- 862
- 863
- 864
- 865
- 866
- 867
- 868
- 869
- 870
- 871
- 872
- 873
- 874
- 875
- 876
- 877
- 878
- 879
- 880
- 881
- 882
- 883
- 884
- 885
- 886
- 887
- 888
- 889
- 890
- 891
- 892
- 893
- 894
- 895
- 896
- 897
- 898
- 899
- 900
- 901
- 902
- 903
- 904
- 905
- 906
- 907
- 908
- 909
- 910
- 911
- 912
- 913
- 914
- 915
- 916
- 917
- 918
- 919
- 920
- 921
- 922
- 923
- 924
- 925
- 926
- 927
- 928
- 929
- 930
- 931
- 932
- 933
- 934
- 935
- 936
- 937
- 938
- 939
- 940
- 941
- 942
- 943
- 944
- 945
- 946
- 947
- 948
- 949
- 950
- 951
- 952
- 953
- 954
- 955
- 956
- 957
- 958
- 959
- 960
- 961
- 962
- 963
- 964
- 965
- 966
- 967
- 968
- 969
- 970
- 971
- 972
- 973
- 974
- 975
- 976
- 977
- 978
- 979
- 980
- 981
- 982
- 983
- 984
- 985
- 986
- 987
- 988
- 989
- 990
- 991
- 992
- 993
- 994
- 995
- 996
- 997
- 998
- 999
-1000
-1001
-1002
-1003
-1004
-1005
-1006
-1007
-1008
-1009
-1010
-1011
-1012
-1013
-1014
-1015
-1016
-1017
-1018
-1019
-1020
-1021
-1022
-1023
-1024
-1025
-1026
-1027
-1028
-1029
-1030
-1031
-1032
-1033
-1034
-1035
-1036
-1037
-1038
-1039
-1040
-1041
-1042
-1043
-1044
-1045
-1046
-1047
-1048
-1049
-1050
-1051
-1052
-1053
-1054
-1055
-1056
-1057
-1058
-1059
-1060
-1061
-1062
-1063
-1064
-1065
-1066
-1067
-1068
-1069
-1070
-1071
-1072
-1073
-1074
-1075
-1076
-1077
-1078
-1079
-1080
-1081
-1082
-1083
-1084
-1085
-1086
-1087
-1088
-1089
-1090
-1091
-1092
-1093
// *****************************************************************************
+
  1
+  2
+  3
+  4
+  5
+  6
+  7
+  8
+  9
+ 10
+ 11
+ 12
+ 13
+ 14
+ 15
+ 16
+ 17
+ 18
+ 19
+ 20
+ 21
+ 22
+ 23
+ 24
+ 25
+ 26
+ 27
+ 28
+ 29
+ 30
+ 31
+ 32
+ 33
+ 34
+ 35
+ 36
+ 37
+ 38
+ 39
+ 40
+ 41
+ 42
+ 43
+ 44
+ 45
+ 46
+ 47
+ 48
+ 49
+ 50
+ 51
+ 52
+ 53
+ 54
+ 55
+ 56
+ 57
+ 58
+ 59
+ 60
+ 61
+ 62
+ 63
+ 64
+ 65
+ 66
+ 67
+ 68
+ 69
+ 70
+ 71
+ 72
+ 73
+ 74
+ 75
+ 76
+ 77
+ 78
+ 79
+ 80
+ 81
+ 82
+ 83
+ 84
+ 85
+ 86
+ 87
+ 88
+ 89
+ 90
+ 91
+ 92
+ 93
+ 94
+ 95
+ 96
+ 97
+ 98
+ 99
+100
+101
+102
+103
+104
+105
+106
+107
+108
+109
+110
+111
+112
+113
+114
+115
+116
+117
+118
+119
+120
+121
+122
+123
+124
+125
+126
+127
+128
+129
+130
+131
+132
+133
+134
+135
+136
+137
+138
+139
+140
+141
+142
+143
+144
+145
+146
+147
+148
+149
+150
+151
+152
+153
+154
+155
+156
+157
+158
+159
+160
+161
+162
+163
+164
+165
+166
+167
+168
+169
+170
+171
+172
+173
+174
+175
+176
+177
+178
+179
+180
+181
+182
+183
+184
+185
+186
+187
+188
+189
+190
+191
+192
+193
+194
+195
+196
+197
+198
+199
+200
+201
+202
+203
+204
+205
+206
+207
+208
+209
+210
+211
+212
+213
+214
+215
+216
+217
+218
+219
+220
+221
+222
+223
+224
+225
+226
+227
+228
+229
+230
+231
+232
+233
+234
+235
+236
+237
+238
+239
+240
+241
+242
+243
+244
+245
+246
+247
+248
+249
+250
+251
+252
+253
+254
+255
+256
+257
+258
+259
+260
+261
+262
+263
+264
+265
+266
+267
+268
+269
+270
+271
+272
+273
+274
+275
+276
+277
+278
+279
+280
+281
+282
+283
+284
+285
+286
+287
+288
+289
+290
+291
+292
+293
+294
+295
+296
+297
+298
+299
+300
+301
+302
+303
+304
+305
+306
+307
+308
+309
+310
+311
+312
+313
+314
+315
+316
+317
+318
+319
+320
+321
+322
+323
+324
+325
+326
+327
+328
+329
+330
+331
+332
+333
+334
+335
+336
+337
+338
+339
+340
+341
+342
+343
+344
+345
+346
+347
+348
+349
+350
+351
+352
+353
+354
+355
+356
+357
+358
+359
+360
+361
+362
+363
+364
+365
+366
+367
+368
+369
+370
+371
+372
+373
+374
+375
+376
+377
+378
+379
+380
+381
+382
+383
+384
+385
+386
+387
+388
+389
+390
+391
+392
+393
+394
+395
+396
+397
+398
+399
+400
+401
+402
+403
+404
+405
+406
+407
+408
+409
+410
+411
+412
+413
+414
+415
+416
+417
+418
+419
+420
// *****************************************************************************
 /*!
-  \file      src/Inciter/Ghosts.cpp
+  \file      src/PDE/EoS/JWL.cpp
   \copyright 2012-2015 J. Bakosi,
              2016-2018 Los Alamos National Security, LLC.,
              2019-2021 Triad National Security, LLC.
              All rights reserved. See the LICENSE file for details.
-  \brief     Definitions file for generating ghost data structures
-  \details   Definitions file for asynchronous distributed
-             ghost data structures using Charm++.
-*/
-// *****************************************************************************
-
-#include "Ghosts.hpp"
-#include "DerivedData.hpp"
-#include "Reorder.hpp"
-#include "Around.hpp"
-#include "ChareStateCollector.hpp"
-
-extern tk::CProxy_ChareStateCollector stateProxy;
-
-using inciter::Ghosts;
-
-Ghosts::Ghosts( const CProxy_Discretization& disc,
-  const std::map< int, std::vector< std::size_t > >& bface,
-  const std::vector< std::size_t >& triinpoel,
-  std::size_t nunk,
-  CkCallback cbDone ) :
-  m_disc( disc ),
-  m_nunk( nunk ),
-  m_inpoel( Disc()->Inpoel() ),
-  m_coord( Disc()->Coord() ),
-  m_fd( m_inpoel, bface, tk::remap(triinpoel,Disc()->Lid()) ),
-  m_geoFace( tk::genGeoFaceTri( m_fd.Nipfac(), m_fd.Inpofa(), m_coord) ),
-  m_geoElem( tk::genGeoElemTet( m_inpoel, m_coord ) ),
-  m_nfac( m_fd.Inpofa().size()/3 ),
-  m_bndFace(),
-  m_sendGhost(),
-  m_ghost(),
-  m_exptGhost(),
-  m_bid(),
-  m_esup(),
-  m_initial( 1 ),
-  m_ncomfac( 0 ),
-  m_nadj( 0 ),
-  m_ncomEsup( 0 ),
-  m_ipface(),
-  m_ghostData(),
-  m_ghostReq( 0 ),
-  m_expChBndFace(),
-  m_infaces(),
-  m_esupc(),
-  m_cbAfterDone( cbDone )
-// *****************************************************************************
-//  Constructor
-//! \param[in] disc Discretization proxy
-//! \param[in] bface Boundary-faces mapped to side set ids
-//! \param[in] triinpoel Boundary-face connectivity
-//! \param[in] nunk Number of unknowns
-//! \param[in] cbDone Function to continue with when Ghosts have been computed
-// *****************************************************************************
-{
-  if (g_inputdeck.get< tag::cmd, tag::chare >() ||
-      g_inputdeck.get< tag::cmd, tag::quiescence >())
-    stateProxy.ckLocalBranch()->insert( "Ghosts", thisIndex, CkMyPe(), Disc()->It(),
-                                        "Ghosts" );
-}
-
-void
-Ghosts::startCommSetup()
-// *****************************************************************************
-//  Start setup of communication maps for cell-centered schemes
-// *****************************************************************************
-{
-  // Ensure that mesh partition is not leaky
-  Assert( !tk::leakyPartition(m_fd.Esuel(), m_inpoel, m_coord),
-    "Input mesh to Ghosts leaky" );
-
-  // Ensure mesh physical boundary for the entire problem not leaky,
-  // effectively checking if the user has specified boundary conditions on all
-  // physical boundary faces
-  bndIntegral();
-}
-
-void
-Ghosts::bndIntegral()
-// *****************************************************************************
-//  Compute partial boundary surface integral and sum across all chares
-//! \details This function computes a partial surface integral over the boundary
-//!   of the faces of this mesh partition then sends its contribution to perform
-//!   the integral acorss the total problem boundary. After the global sum a
-//!   non-zero vector result indicates a leak, e.g., a hole in the boundary
-//!   which indicates an error in the boundary face data structures used to
-//!   compute the partial surface integrals.
-// *****************************************************************************
-{
-  // Storage for surface integral over our mesh chunk physical boundary
-  std::vector< tk::real > s{{ 0.0, 0.0, 0.0 }};
-
-  // Integrate over all physical boundary faces
-  for (std::size_t f=0; f<m_fd.Nbfac(); ++f) {
-    s[0] += m_geoFace(f,0) * m_geoFace(f,1);
-    s[1] += m_geoFace(f,0) * m_geoFace(f,2);
-    s[2] += m_geoFace(f,0) * m_geoFace(f,3);
-  }
-
-  s.push_back( 1.0 );  // positive: call-back to resizeComm() after reduction
-  s.push_back( static_cast< tk::real >( Disc()->MeshId() ) );
-
-  // Send contribution to host summing partial surface integrals
-  contribute( s, CkReduction::sum_double,
-    CkCallback(CkReductionTarget(Transporter,bndint), Disc()->Tr()) );
-}
-
-void
-Ghosts::resizeComm()
-// *****************************************************************************
-//  Start sizing communication buffers and setting up ghost data
-// *****************************************************************************
-{
-  // Enable SDAG wait for setting up chare boundary faces
-  thisProxy[ thisIndex ].wait4fac();
-
-  auto d = Disc();
-
-  const auto& gid = d->Gid();
-  const auto& inpofa = m_fd.Inpofa();
-  const auto& esuel = m_fd.Esuel();
-
-  // Perform leak test on mesh partition
-  Assert( !tk::leakyPartition( esuel, m_inpoel, m_coord ),
-          "Mesh partition leaky" );
-
-  // Activate SDAG waits for face adjacency map (ghost data) calculation
-  thisProxy[ thisIndex ].wait4ghost();
-  thisProxy[ thisIndex ].wait4esup();
-
-  // Invert inpofa to enable searching for faces based on (global) node triplets
-  Assert( inpofa.size() % 3 == 0, "Inpofa must contain triplets" );
-  for (std::size_t f=0; f<inpofa.size()/3; ++f)
-    m_ipface.insert( {{{ gid[ inpofa[f*3+0] ],
-                         gid[ inpofa[f*3+1] ],
-                         gid[ inpofa[f*3+2] ] }}} );
+  \brief     Jones, Wilkins, and Lee (JWL) equation of state
+  \details   This file defines functions for the JWL equation of
+             state for the compressible flow equations. These functions are
+             taken from 'JWL Equation of State', Menikoff, LA-UR-15-29536.
+*/
+// *****************************************************************************
+
+#include <cmath>
+#include <iostream>
+#include "EoS/JWL.hpp"
+
+using inciter::JWL;
+
+JWL::JWL( tk::real w, tk::real cv, tk::real rho0, tk::real de, tk::real rhor,
+  tk::real tr, tk::real pr, tk::real A, tk::real B, tk::real R1, tk::real R2 ) :
+  m_w(w),
+  m_cv(cv),
+  m_rho0(rho0),
+  m_de(de),
+  m_rhor(rhor),
+  m_tr(tr),
+  m_pr(pr),
+  m_a(A),
+  m_b(B),
+  m_r1(R1),
+  m_r2(R2)
+// *************************************************************************
+//  Constructor
+//! \param[in] w Grueneisen coefficient
+//! \param[in] cv Specific heat at constant volume
+//! \param[in] rho0 Density of initial state
+//! \param[in] de Heat of detonation for products. For reactants, it is
+//!   chosen such that the ambient internal energy (e0) is 0.
+//! \param[in] rhor Density of reference state
+//! \param[in] tr Temperature of reference state
+//! \param[in] pr Pressure of reference state
+//! \param[in] A Parameter A
+//! \param[in] B Parameter B
+//! \param[in] R1 Parameter R1
+//! \param[in] R2 Parameter R2
+// *************************************************************************
+{
+  // reference density provided
+  if (m_tr < 1e-8) {
+    // reference internal energy
+    auto er = intEnergy(rhor, pr);
+    // reference temperature from Eqn (15)
+    m_tr = 1.0/m_cv * (er + de -
+      (m_a/m_r1*exp(-m_r1*m_rho0/m_rhor) +
+       m_b/m_r2*exp(-m_r2*m_rho0/m_rhor)) / m_rho0);
+  }
+  // reference temperature provided
+  else
+  {
+    m_rhor = density(m_pr, m_tr);
+  }
+}
+
+tk::real
+JWL::density(
+  tk::real pr,
+  tk::real temp ) const
+// *************************************************************************
+//! \brief Calculate density from the material pressure and temperature
+//!   using the stiffened-gas equation of state
+//! \param[in] pr Material pressure
+//! \param[in] temp Material temperature
+//! \return Material density calculated using the stiffened-gas EoS
+// *************************************************************************
+{
+  tk::real r_guessL = 1e-4*m_rho0;  // left density bound
+  tk::real r_guessR = 1e2*m_rho0;   // right density bound
+  tk::real rho;
+
+  rho = bisection( r_guessL, r_guessR, pr, temp );
+
+  return rho;
+}
+
+
+tk::real
+JWL::pressure(
+  tk::real arho,
+  tk::real u,
+  tk::real v,
+  tk::real w,
+  tk::real arhoE,
+  tk::real alpha,
+  std::size_t imat,
+  const std::array< std::array< tk::real, 3 >, 3 >& ) const
+// *************************************************************************
+//! \brief Calculate pressure from the material density, momentum and total
+//!   energy using the stiffened-gas equation of state
+//! \param[in] arho Material partial density (alpha_k * rho_k)
+//! \param[in] u X-velocity
+//! \param[in] v Y-velocity
+//! \param[in] w Z-velocity
+//! \param[in] arhoE Material total energy (alpha_k * rho_k * E_k)
+//! \param[in] alpha Material volume fraction. Default is 1.0, so that for
+//!   the single-material system, this argument can be left unspecified by
+//!   the calling code
+//! \param[in] imat Material-id who's EoS is required. Default is 0, so that
+//!   for the single-material system, this argument can be left unspecified
+//!   by the calling code
+//! \return Material partial pressure (alpha_k * p_k) calculated using the
+//!   stiffened-gas EoS
+//! \details From Eqn. 1 in 'JWL Equation of State', Menikoff, LA-UR-15-29536
+// *************************************************************************
+{
+  // specific internal energy
+  tk::real e = (arhoE - 0.5*arho*(u*u + v*v + w*w))/arho;
+
+  //// reference energy (input quantity, might need for calculation)
+  //tk::real e0 = a/r1*exp(-r1*rho0/rho) + b/r2*exp(-r2*rho0/rho);
+
+  alpha = std::max(1e-14,alpha);
+  tk::real partpressure =
+    m_a*(alpha - m_w*arho/(m_rho0*m_r1))*exp(-m_r1*alpha*m_rho0/arho) +
+    m_b*(alpha - m_w*arho/(m_rho0*m_r2))*exp(-m_r2*alpha*m_rho0/arho) +
+    m_w*arho*(e + m_de);
+
+  // check partial pressure divergence
+  if (!std::isfinite(partpressure)) {
+    std::cout << "Material-id:      " << imat << std::endl;
+    std::cout << "Volume-fraction:  " << alpha << std::endl;
+    std::cout << "Partial density:  " << arho << std::endl;
+    std::cout << "Total energy:     " << arhoE << std::endl;
+    std::cout << "Velocity:         " << u << ", " << v << ", " << w
+      << std::endl;
+    Throw("Material-" + std::to_string(imat) +
+      " has nan/inf partial pressure: " + std::to_string(partpressure) +
+      ", material volume fraction: " + std::to_string(alpha));
+  }
+
+  return partpressure;
+}
 
-  // At this point ipface has node-id-triplets (faces) on the internal
-  // chare-domain and on the physical boundary but not on chare boundaries,
-  // hence the name internal + physical boundary faces.
-
-  // Build a set of faces (each face given by 3 global node IDs) associated to
-  // chares we potentially share boundary faces with.
-  tk::UnsMesh::FaceSet potbndface;
-  for (std::size_t e=0; e<esuel.size()/4; ++e) {   // for all our tets
-    auto mark = e*4;
-    for (std::size_t f=0; f<4; ++f)     // for all tet faces
-      if (esuel[mark+f] == -1) {        // if face has no outside-neighbor tet
-        // if does not exist among the internal and physical boundary faces,
-        // store as a potential chare-boundary face
-        tk::UnsMesh::Face t{{ gid[ m_inpoel[ mark + tk::lpofa[f][0] ] ],
-                              gid[ m_inpoel[ mark + tk::lpofa[f][1] ] ],
-                              gid[ m_inpoel[ mark + tk::lpofa[f][2] ] ] }};
-        if (m_ipface.find(t) == end(m_ipface)) {
-          Assert( m_expChBndFace.insert(t).second,
-                  "Store expected chare-boundary face" );
-          potbndface.insert( t );
-        }
-      }
-  }
-
-  if ( g_inputdeck.get< tag::cmd, tag::feedback >() ) d->Tr().chbndface();
-
-  // In the following we assume that the size of the (potential) boundary-face
-  // adjacency map above does not necessarily equal to that of the node
-  // adjacency map. This is because while a node can be shared at a single
-  // corner or along an edge, that does not necessarily share a face as well
-  // (in other words, shared nodes or edges can exist that are not part of a
-  // shared face). So the chares we communicate with across faces are not
-  // necessarily the same as the chares we would communicate nodes with.
-  //
-  // Since the sizes of the node and face adjacency maps are not the same, while
-  // sending the faces on chare boundaries would be okay, however, the receiver
-  // would not necessarily know how many chares it must receive from. To solve
-  // this problem we send to chares which we share at least a single node with,
-  // i.e., rely on the node-adjacency map. Note that to all chares we share at
-  // least a single node with we send all our potential chare-boundary faces.
-  // This is the same list of faces to all chares we send.
-  //
-  // Another underlying assumption here is, of course, that the size of the face
-  // adjacency map is always smaller than or equal to that of the node adjacency
-  // map, which is always true. Since the receive side already knows how many
-  // fellow chares it must receive shared node ids from, we use that to detect
-  // completion of the number of receives in comfac(). This simplifies the
-  // communication pattern and code.
-
-  // Send sets of faces adjacent to chare boundaries to fellow workers (if any)
-  if (d->NodeCommMap().empty())  // in serial, skip setting up ghosts altogether
-    faceAdj();
-  else
-    // for all chares we share nodes with
-    for (const auto& c : d->NodeCommMap()) {
-      thisProxy[ c.first ].comfac( thisIndex, potbndface );
-    }
-
-  ownfac_complete();
-}
-
-void
-Ghosts::comfac( int fromch, const tk::UnsMesh::FaceSet& infaces )
-// *****************************************************************************
-//  Receive unique set of faces we potentially share with/from another chare
-//! \param[in] fromch Sender chare id
-//! \param[in] infaces Unique set of faces we potentially share with fromch
-// *****************************************************************************
-{
-  if (g_inputdeck.get< tag::cmd, tag::chare >() ||
-      g_inputdeck.get< tag::cmd, tag::quiescence >())
-    stateProxy.ckLocalBranch()->insert( "Ghosts", thisIndex, CkMyPe(), Disc()->It(),
-                                        "comfac" );
-
-  // Buffer up incoming data
-  m_infaces[ fromch ] = infaces;
-
-  // if we have heard from all fellow chares that we share at least a single
-  // node, edge, or face with
-  if (++m_ncomfac == Disc()->NodeCommMap().size()) {
-    m_ncomfac = 0;
-    comfac_complete();
-  }
-}
-
-void
-Ghosts::bndFaces()
-// *****************************************************************************
-// Compute chare-boundary faces
-//! \details This is called when both send and receives are completed on a
-//!  chare and thus we are ready to compute chare-boundary faces and ghost data.
-// *****************************************************************************
-{
-  auto d = Disc();
-  if ( g_inputdeck.get< tag::cmd, tag::feedback >() ) d->Tr().chcomfac();
-  const auto& esuel = m_fd.Esuel();
-  const auto& gid = d->Gid();
+std::array< std::array< tk::real, 3 >, 3 >
+JWL::CauchyStress(
+  tk::real,
+  tk::real,
+  tk::real,
+  tk::real,
+  tk::real,
+  tk::real,
+  std::size_t,
+  const std::array< std::array< tk::real, 3 >, 3 >& ) const
+// *************************************************************************
+//! \brief Calculate the Cauchy stress tensor from the material density,
+//!   momentum, and total energy
+//! \return Material Cauchy stress tensor (alpha_k * sigma_k)
+// *************************************************************************
+{
+  std::array< std::array< tk::real, 3 >, 3 > asig{{{0,0,0}, {0,0,0}, {0,0,0}}};
+
+  // No elastic contribution
+
+  return asig;
+}
+
+tk::real
+JWL::soundspeed(
+  tk::real arho,
+  tk::real apr,
+  tk::real alpha,
+  std::size_t imat,
+  const std::array< std::array< tk::real, 3 >, 3 >&,
+  const std::array< tk::real, 3 >&,
+  const std::array< tk::real, 3 >& ) const
+// *************************************************************************
+//! Calculate speed of sound from the material density and material pressure
+//! \param[in] arho Material partial density (alpha_k * rho_k)
+//! \param[in] apr Material partial pressure (alpha_k * p_k)
+//! \param[in] alpha Material volume fraction. Default is 1.0, so that for
+//!   the single-material system, this argument can be left unspecified by
+//!   the calling code
+//! \param[in] imat Material-id who's EoS is required. Default is 0, so that
+//!   for the single-material system, this argument can be left unspecified
+//!   by the calling code
+//! \return Material speed of sound using the stiffened-gas EoS
+// *************************************************************************
+{
+  alpha = std::max(1e-14,alpha);
+  // limiting pressure to near-zero
+  auto apr_eff = std::max(alpha*
+    min_eff_pressure(1e-4*std::abs(apr/alpha), arho, alpha), apr);
+
+  auto co1 = m_rho0*alpha*alpha/(arho*arho);
+  auto co2 = alpha*(1.0+m_w)/arho;
+
+  tk::real ss = m_a*(m_r1*co1 - co2) * exp(-m_r1*alpha*m_rho0/arho)
+              + m_b*(m_r2*co1 - co2) * exp(-m_r2*alpha*m_rho0/arho)
+              + (1.0+m_w)*apr_eff/arho;
+
+  auto ss2 = ss;
+  ss = std::sqrt(ss);
+
+  // check sound speed divergence
+  if (!std::isfinite(ss)) {
+    std::cout << "Material-id:      " << imat << std::endl;
+    std::cout << "Volume-fraction:  " << alpha << std::endl;
+    std::cout << "Partial density:  " << arho << std::endl;
+    std::cout << "Partial pressure: " << apr << std::endl;
+    std::cout << "Min allowed pres: " << alpha*min_eff_pressure(0.0, arho,
+      alpha) << std::endl;
+    Throw("Material-" + std::to_string(imat) + " has nan/inf sound speed. "
+      "ss^2: " + std::to_string(ss2) + ", material volume fraction: " +
+      std::to_string(alpha));
+  }
+
+  return ss;
+}
+
+tk::real
+JWL::totalenergy(
+  tk::real rho,
+  tk::real u,
+  tk::real v,
+  tk::real w,
+  tk::real pr,
+  const std::array< std::array< tk::real, 3 >, 3 >& ) const
+// *************************************************************************
+//! \brief Calculate material specific total energy from the material
+//!   density, momentum and material pressure
+//! \param[in] rho Material density
+//! \param[in] u X-velocity
+//! \param[in] v Y-velocity
+//! \param[in] w Z-velocity
+//! \param[in] pr Material pressure
+//! \return Material specific total energy using the stiffened-gas EoS
+// *************************************************************************
+{
+  //// reference energy (input quantity, might need for calculation)
+  //tk::real e0 = a/r1*exp(-r1*rho0/rho) + b/r2*exp(-r2*rho0/rho);
 
-  for (const auto& in : m_infaces) {
-    // Find sender chare among chares we potentially share faces with. Note that
-    // it is feasible that a sender chare called us but we do not have a set of
-    // faces associated to that chare. This can happen if we only share a single
-    // node or an edge but not a face with that chare.
-    auto& bndface = m_bndFace[ in.first ];  // will associate to sender chare
-    // Try to find incoming faces on our chare boundary with other chares. If
-    // found, generate and assign new local face ID, associated to sender chare.
-    for (std::size_t e=0; e<esuel.size()/4; ++e) {  // for all our tets
-      auto mark = e*4;
-      for (std::size_t f=0; f<4; ++f) {  // for all cell faces
-        if (esuel[mark+f] == -1) {  // if face has no outside-neighbor tet
-          tk::UnsMesh::Face t{{ gid[ m_inpoel[ mark + tk::lpofa[f][0] ] ],
-                                gid[ m_inpoel[ mark + tk::lpofa[f][1] ] ],
-                                gid[ m_inpoel[ mark + tk::lpofa[f][2] ] ] }};
-          // if found among the incoming faces and if not one of our internal
-          // nor physical boundary faces
-          if ( in.second.find(t) != end(in.second) &&
-               m_ipface.find(t) == end(m_ipface) ) {
-            bndface[t][0] = m_nfac++;    // assign new local face ID
-          }
-        }
-      }
-    }
-    // If at this point if we have not found any face among our faces we
-    // potentially share with fromch, there is no need to keep an empty set of
-    // faces associated to fromch as we only share nodes or edges with it, but
-    // not faces.
-    if (bndface.empty()) m_bndFace.erase( in.first );
-  }
-
-  tk::destroy(m_ipface);
-  tk::destroy(m_infaces);
-
-  // Ensure all expected faces have been received
-  Assert( receivedChBndFaces(),
-    "Expected and received chare boundary faces mismatch" );
-
-  // Basic error checking on chare-boundary-face map
-  Assert( m_bndFace.find( thisIndex ) == m_bndFace.cend(),
-          "Face-communication map should not contain data for own chare ID" );
+  tk::real rhoE = rho*intEnergy( rho, pr )
+                + 0.5*rho*(u*u + v*v + w*w);
+
+  return rhoE;
+}
+
+tk::real
+JWL::temperature(
+  tk::real arho,
+  tk::real u,
+  tk::real v,
+  tk::real w,
+  tk::real arhoE,
+  tk::real alpha,
+  const std::array< std::array< tk::real, 3 >, 3 >& ) const
+// *************************************************************************
+//! \brief Calculate material temperature from the material density, and
+//!   material specific total energy
+//! \param[in] arho Material partial density (alpha_k * rho_k)
+//! \param[in] u X-velocity
+//! \param[in] v Y-velocity
+//! \param[in] w Z-velocity
+//! \param[in] arhoE Material total energy (alpha_k * rho_k * E_k)
+//! \param[in] alpha Material volume fraction. Default is 1.0, so that for
+//!   the single-material system, this argument can be left unspecified by
+//!   the calling code
+//! \return Material temperature using the stiffened-gas EoS
+// *************************************************************************
+{
+  alpha = std::max(1e-14,alpha);
+  tk::real rho = arho/alpha;
+
+  //// reference energy (input quantity, might need for calculation)
+  //tk::real e0 = a/r1*exp(-r1*rho0/rho) + b/r2*exp(-r2*rho0/rho);
+
+  tk::real t = ((arhoE - 0.5*arho*(u*u + v*v + w*w))/arho + m_de -
+    1.0/m_rho0*( m_a/m_r1*exp(-m_r1*m_rho0/rho)
+               + m_b/m_r2*exp(-m_r2*m_rho0/rho) ))/m_cv;
+
+  return t;
+}
 
-  // Store (local) tet ID adjacent to our chare boundary from the inside
-  for (std::size_t e=0; e<esuel.size()/4; ++e) {  // for all our tets
-    auto mark = e*4;
-    for (std::size_t f=0; f<4; ++f) {  // for all cell faces
-      if (esuel[mark+f] == -1) {  // if face has no outside-neighbor tet
-        tk::UnsMesh::Face t{{ gid[ m_inpoel[ mark + tk::lpofa[f][0] ] ],
-                              gid[ m_inpoel[ mark + tk::lpofa[f][1] ] ],
-                              gid[ m_inpoel[ mark + tk::lpofa[f][2] ] ] }};
-        auto c = findchare(t);
-        if (c > -1) {
-          auto& lbndface = tk::ref_find( m_bndFace, c );
-          auto& face = tk::ref_find( lbndface, t );
-          face[1] = e;  // store (local) inner tet ID adjacent to face
-        }
-      }
-    }
-  }
-
-  // At this point m_bndFace is complete on this PE. This means that starting
-  // from the sets of faces we potentially share with fellow chares we now
-  // only have those faces we actually share faces with (through which we need
-  // to communicate later). Also, m_bndFace not only has the unique faces
-  // associated to fellow chares, but also a newly assigned local face ID as
-  // well as the local id of the inner tet adjacent to the face. Continue by
-  // starting setting up ghost data
-  setupGhost();
-  // Besides setting up our own ghost data, we also issue requests (for ghost
-  // data) to those chares which we share faces with. Note that similar to
-  // comfac() we are calling reqGhost() by going through the node communication
-  // map instead, which may send requests to those chare we do not share faces
-  // with. This is so that we can test for completing by querying the size of
-  // the already complete node commincation map in reqGhost. Requests in
-  // sendGhost will only be fullfilled based on m_ghostData.
-  for (const auto& c : d->NodeCommMap())  // for all chares we share nodes with
-    thisProxy[ c.first ].reqGhost();
-}
-
-void
-Ghosts::setupGhost()
-// *****************************************************************************
-// Setup own ghost data on this chare
-// *****************************************************************************
-{
-  auto d = Disc();
-  const auto& gid = d->Gid();
-
-  // Enlarge elements surrounding faces data structure for ghosts
-  m_fd.Esuf().resize( 2*m_nfac, -2 );
-  m_fd.Inpofa().resize( 3*m_nfac, 0 );
-  // Enlarge face geometry data structure for ghosts
-  m_geoFace.resize( m_nfac, 0.0 );
-
-  const auto& esuel = m_fd.Esuel();
-
-  // Collect tet ids, their face connectivity (given by 3 global node IDs, each
-  // triplet for potentially multiple faces on the chare boundary), and their
-  // elem geometry data (see GhostData) associated to fellow chares adjacent to
-  // chare boundaries. Once received by fellow chares, these tets will become
-  // known as ghost elements and their data as ghost data.
-  for (std::size_t e=0; e<esuel.size()/4; ++e) {  // for all our tets
-    auto mark = e*4;
-    for (std::size_t f=0; f<4; ++f) {  // for all cell faces
-      if (esuel[mark+f] == -1) {  // if face has no outside-neighbor tet
-        tk::UnsMesh::Face t{{ gid[ m_inpoel[ mark + tk::lpofa[f][0] ] ],
-                              gid[ m_inpoel[ mark + tk::lpofa[f][1] ] ],
-                              gid[ m_inpoel[ mark + tk::lpofa[f][2] ] ] }};
-        auto c = findchare(t);
-        // It is possible that we do not find the chare for this face. We are
-        // looping through all of our tets and interrogating all faces that do
-        // not have neighboring tets but we only care about chare-boundary faces
-        // here as only those need ghost data. (esuel may also contain
-        // physical boundary faces)
-        if (c > -1) {
-          // Will store ghost data associated to neighbor chare
-          auto& ghost = m_ghostData[ c ];
-          // Store tet id adjacent to chare boundary as key for ghost data
-          auto& tuple = ghost[ e ];
-          // If tetid e has not yet been encountered, store geometry (only once)
-          auto& nodes = std::get< 0 >( tuple );
-          if (nodes.empty()) {
-            std::get< 1 >( tuple ) = m_geoElem[ e ];
-
-            auto& ncoord = std::get< 2 >( tuple );
-            ncoord[0] = m_coord[0][ m_inpoel[ mark+f ] ];
-            ncoord[1] = m_coord[1][ m_inpoel[ mark+f ] ];
-            ncoord[2] = m_coord[2][ m_inpoel[ mark+f ] ];
+tk::real
+JWL::min_eff_pressure(
+  tk::real min,
+  tk::real arho,
+  tk::real alpha ) const
+// *************************************************************************
+//! Compute the minimum allowed pressure
+//! \param[in] min Numerical threshold above which pressure needs to be limited
+//! \param[in] arho Material partial density (alpha_k * rho_k)
+//! \param[in] alpha Material volume fraction. Default is 1.0, so that for
+//!   the single-material system, this argument can be left unspecified by
+//!   the calling code
+//! \return Minimum pressure allowed by physical constraints
+// *************************************************************************
+{
+  alpha = std::max(1e-14,alpha);
+  auto co1 = m_rho0*alpha*alpha/(arho*arho);
+  auto co2 = alpha*(1.0+m_w)/arho;
+
+  // minimum pressure is constrained by zero soundspeed.
+  auto apr = -(m_a*(m_r1*co1 - co2) * exp(-m_r1*alpha*m_rho0/arho)
+             + m_b*(m_r2*co1 - co2) * exp(-m_r2*alpha*m_rho0/arho))
+    * arho/(1.0+m_w);
+
+  return apr/alpha + min;
+}
+
+tk::real
+JWL::intEnergy(
+  tk::real rho,
+  tk::real pr ) const
+// *************************************************************************
+//! \brief Calculate specific internal energy using the JWL equation of
+//!   state
+//! \param[in] rho Material density
+//! \param[in] pr Material pressure
+//! \return Material internal energy calculated using the JWL EoS
+//! \details By inverting Eqn. 1 in 'JWL Equation of State', Menikoff,
+//!   LA-UR-15-29536
+// *************************************************************************
+{
+  tk::real e = - m_de + 1.0/m_w/rho*( pr
+                - m_a*(1.0 - m_w*rho/m_r1/m_rho0)*exp(-m_r1*m_rho0/rho)
+                - m_b*(1.0 - m_w*rho/m_r2/m_rho0)*exp(-m_r2*m_rho0/rho) );
+
+  return e;
+}
+
+tk::real
+JWL::bisection(
+  tk::real a,
+  tk::real b,
+  tk::real p_known,
+  tk::real t_known ) const
+// *************************************************************************
+//! \brief Calculate density from known pressure and temperature using
+//!   bisection root finding method for JWL equation of state
+//! \param[in] a Left density bound for root finding
+//! \param[in] b Right density bound for root finding
+//! \param[in] p_known Known pressure
+//! \param[in] t_known Known temperature
+//! \return Material density calculated by inverting JWL pressure equation
+// *************************************************************************
+{
+  tk::real tol = 1e-12;
+  std::size_t maxiter = 1000;
+  std::size_t i(0);
+  tk::real c;
+  tk::real root(0);
+  std::size_t idebug = 0;<--- Assignment 'idebug=0', assigned value is 0
+  auto a_o = a;
+  auto b_o = b;
+
+  // function to minimize: fcn = p_known - PfromRT
+  // bounds b > a
+
+  while (i < maxiter)
+  {
+    c = (a + b)/2.0;
+    auto fcn = p_known - PfromRT( c, t_known);
+    if ( idebug == 1)<--- Condition 'idebug==1' is always false
+    {
+      std::cout << "Bisection iter:      " << i << std::endl;
+      std::cout << "fcn:  " << fcn << std::endl;
+      std::cout << "(b - a)/2.0: " << (b - a)/2.0 << std::endl;
+    }
 
-            std::get< 3 >( tuple ) = f;
-
-            std::get< 4 >( tuple ) = {{ gid[ m_inpoel[ mark ] ],
-                                        gid[ m_inpoel[ mark+1 ] ],
-                                        gid[ m_inpoel[ mark+2 ] ],
-                                        gid[ m_inpoel[ mark+3 ] ] }};
-          }
-          // (Always) store face node IDs on chare boundary, even if tetid e has
-          // already been stored. Thus we store potentially multiple faces along
-          // the same chare-boundary. This happens, e.g., when the boundary
-          // between chares is zig-zaggy enough to have 2 or even 3 faces of the
-          // same tet.
-          nodes.push_back( t[0] );
-          nodes.push_back( t[1] );
-          nodes.push_back( t[2] );
-          Assert( nodes.size() <= 4*3, "Overflow of faces/tet to send" );
-        }
-      }
-    }
-  }
-
-  // Basic error checking on local ghost data
-  Assert( m_ghostData.find( thisIndex ) == m_ghostData.cend(),
-          "Chare-node adjacency map should not contain data for own chare ID" );
-
-  // More in-depth error checking on local ghost data
-  for (const auto& c : m_ghostData)
-    for ([[maybe_unused]] const auto& t : c.second) {
-      Assert( !std::get< 0 >( t.second ).empty(),
-              "Emtpy face vector in ghost data" );
-      Assert( std::get< 0 >( t.second ).size() % 3 == 0,
-              "Face node IDs must be triplets" );
-      Assert( std::get< 0 >( t.second ).size() <= 4*3,    // <= 4*3 (4*numfaces)
-              "Max number of faces for a single ghost tet is 4" );
-      Assert( !std::get< 1 >( t.second ).empty(),
-              "No elem geometry data for ghost" );
-      Assert( std::get< 1 >( t.second ).size() == m_geoElem.nprop(),
-              "Elem geometry data for ghost must be for single tet" );
-      Assert( !std::get< 2 >( t.second ).empty(),
-              "No nodal coordinate data for ghost" );
-    }
-
-  ownghost_complete();
-}
-
-void
-Ghosts::reqGhost()
-// *****************************************************************************
-// Receive requests for ghost data
-// *****************************************************************************
-{
-  if (g_inputdeck.get< tag::cmd, tag::chare >() ||
-      g_inputdeck.get< tag::cmd, tag::quiescence >())
-    stateProxy.ckLocalBranch()->insert( "Ghosts", thisIndex, CkMyPe(), Disc()->It(),
-                                        "reqGhost" );
-
-  // If every chare we communicate with has requested ghost data from us, we may
-  // fulfill the requests, but only if we have already setup our ghost data.
-  if (++m_ghostReq == Disc()->NodeCommMap().size()) {
-    m_ghostReq = 0;
-    reqghost_complete();
-  }
-}
-
-void
-Ghosts::sendGhost()
-// *****************************************************************************
-// Send all of our ghost data to fellow chares
-// *****************************************************************************
-{
-  if (g_inputdeck.get< tag::cmd, tag::chare >() ||
-      g_inputdeck.get< tag::cmd, tag::quiescence >())
-    stateProxy.ckLocalBranch()->insert( "Ghosts", thisIndex, CkMyPe(), Disc()->It(),
-                                        "sendGhost" );
-
-  for (const auto& c : m_ghostData)
-    thisProxy[ c.first ].comGhost( thisIndex, c.second );
-
-  if ( g_inputdeck.get< tag::cmd, tag::feedback >() ) Disc()->Tr().chghost();
-}
-
-void
-Ghosts::comGhost( int fromch, const GhostData& ghost )
-// *****************************************************************************
-// Receive ghost data on chare boundaries from fellow chare
-//! \param[in] fromch Caller chare ID
-//! \param[in] ghost Ghost data, see Inciter/FaceData.h for the type
-// *****************************************************************************
-{
-  if (g_inputdeck.get< tag::cmd, tag::chare >() ||
-      g_inputdeck.get< tag::cmd, tag::quiescence >())
-    stateProxy.ckLocalBranch()->insert( "Ghosts", thisIndex, CkMyPe(), Disc()->It(),
-                                        "comGhost" );
-
-  auto d = Disc();
-  const auto& lid = d->Lid();
-  auto& inpofa = m_fd.Inpofa();
-  auto ncoord = m_coord[0].size();<--- Variable 'ncoord' is assigned a value that is never used.
-
-  // nodelist with fromch, currently only used for an assert
-  [[maybe_unused]] const auto& nl = tk::cref_find( d->NodeCommMap(), fromch );
-
-  auto& ghostelem = m_ghost[ fromch ];  // will associate to sender chare
-
-  // Store ghost data coming from chare
-  for (const auto& g : ghost) {  // loop over incoming ghost data
-    auto e = g.first;  // remote/ghost tet id outside of chare boundary<--- Variable 'e' is assigned a value that is never used.
-    const auto& nodes = std::get< 0 >( g.second );  // node IDs of face(s)
-    const auto& geo = std::get< 1 >( g.second );    // ghost elem geometry data
-    const auto& coordg = std::get< 2 >( g.second );  // coordinate of ghost node
-    const auto& inpoelg = std::get< 4 >( g.second ); // inpoel of ghost tet
-
-    Assert( nodes.size() % 3 == 0, "Face node IDs must be triplets" );
-    Assert( nodes.size() <= 4*3, "Overflow of faces/tet received" );
-    Assert( geo.size() % 5 == 0, "Ghost geometry size mismatch" );
-    Assert( geo.size() == m_geoElem.nprop(), "Ghost geometry number mismatch" );
-    Assert( coordg.size() == 3, "Incorrect ghost node coordinate size" );
-    Assert( inpoelg.size() == 4, "Incorrect ghost inpoel size" );
-
-    for (std::size_t n=0; n<nodes.size()/3; ++n) {  // face(s) of ghost e
-      // node IDs of face on chare boundary
-      tk::UnsMesh::Face t{{ nodes[n*3+0], nodes[n*3+1], nodes[n*3+2] }};
-      // must find t in nodelist of chare-boundary adjacent to fromch
-      Assert( nl.find(t[0]) != end(nl) &&
-              nl.find(t[1]) != end(nl) &&
-              nl.find(t[2]) != end(nl),
-           "Ghost face not found in chare-node adjacency map on receiving end" );
-      // must find face in boundary-face adjacency map for fromch
-      Assert( tk::cref_find(m_bndFace,fromch).find( t ) !=
-              tk::cref_find(m_bndFace,fromch).cend(), "Ghost face not "
-              "found in boundary-face adjacency map on receiving end" );
-      // find local face & tet ids for t
-      auto id = tk::cref_find( tk::cref_find(m_bndFace,fromch), t );
-      // compute face geometry for chare-boundary face
-      addGeoFace(t, id);
-      // add node-triplet to node-face connectivity
-      inpofa[3*id[0]+0] = tk::cref_find( lid, t[2] );
-      inpofa[3*id[0]+1] = tk::cref_find( lid, t[1] );
-      inpofa[3*id[0]+2] = tk::cref_find( lid, t[0] );
-
-      // if ghost tet id not yet encountered on boundary with fromch
-      auto i = ghostelem.find( e );
-      if (i != end(ghostelem)) {
-        // fill in elements surrounding face
-        addEsuf(id, i->second);
-        // fill in elements surrounding element
-        addEsuel(id, i->second, t);
-      } else {
-        // fill in elements surrounding face
-        addEsuf(id, m_nunk);
-        // fill in elements surrounding element
-        addEsuel(id, m_nunk, t);
-        ghostelem[e] = m_nunk;     // assign new local tet id to remote ghost id
-        m_geoElem.push_back( geo );// store ghost elem geometry
-        ++m_nunk;                  // increase number of unknowns on this chare
-        std::size_t counter = 0;
-        for (std::size_t gp=0; gp<4; ++gp) {
-          auto it = lid.find( inpoelg[gp] );
-          std::size_t lp;
-          if (it != end(lid))
-            lp = it->second;
-          else {
-            Assert( nodes.size() == 3, "Expected node not found in lid" );
-            Assert( gp == std::get< 3 >( g.second ),
-                    "Ghost node not matching correct entry in ghost inpoel" );
-            lp = ncoord;
-            ++counter;
-          }
-          m_inpoel.push_back( lp );       // store ghost element connectivity
-        }
-        // only a single or no ghost node should be found
-        Assert( counter <= 1, "Incorrect number of ghost nodes detected. "
-                "Detected "+ std::to_string(counter) +" ghost nodes" );
-        if (counter == 1) {
-          m_coord[0].push_back( coordg[0] ); // store ghost node coordinate
-          m_coord[1].push_back( coordg[1] );
-          m_coord[2].push_back( coordg[2] );
-          Assert( m_inpoel[ 4*(m_nunk-1)+std::get< 3 >( g.second ) ] == ncoord,
-                  "Mismatch in extended inpoel for ghost element" );
-          ++ncoord;                // increase number of nodes on this chare<--- Variable 'ncoord' is assigned a value that is never used.
-        }
-      }
-
-      // additional tests to ensure that entries in inpoel and t/inpofa match
-      Assert( nodetripletMatch(id, t) == 3,
-        "Mismatch/Overmatch in inpoel and inpofa at chare-boundary face" );
-    }
-  }
-
-  // Signal the runtime system that all workers have received their
-  // face-adjacency
-  if (++m_nadj == m_ghostData.size()) faceAdj();
-}
-
-void
-Ghosts::faceAdj()
-// *****************************************************************************
-// Continue after face adjacency communication map completed on this chare
-//! \details At this point the face communication map has been established
-//!    on this chare. Proceed to set up the nodal-comm map.
-// *****************************************************************************
-{
-  m_nadj = 0;
-
-  tk::destroy(m_bndFace);
-
-  // Ensure that all elements surrounding faces (are correct) including those at
-  // chare boundaries
-  for (std::size_t f=0; f<m_nfac; ++f) {
-    Assert( m_fd.Esuf()[2*f] > -1,
-            "Left element in esuf cannot be physical ghost" );
-    if (f >= m_fd.Nbfac())
-      Assert( m_fd.Esuf()[2*f+1] > -1,
-           "Right element in esuf for internal/chare faces cannot be a ghost" );
-  }
-
-  // Ensure that all elements surrounding elements are correct including those
-  // at chare boundaries
-  const auto& esuel = m_fd.Esuel();
-  std::size_t nbound = 0;
-  for (std::size_t e=0; e<esuel.size()/4; ++e) {
-    for (std::size_t f=0; f<4; ++f)
-      if (esuel[4*e+f] == -1) ++nbound;
-  }
-  Assert( nbound == m_fd.Nbfac(), "Incorrect number of ghost-element -1's in "
-         "updated esuel" );
-
-  // Error checking on ghost data
-  for(const auto& n : m_ghostData)
-    for([[maybe_unused]] const auto& i : n.second)
-      Assert( i.first < m_fd.Esuel().size()/4, "Sender contains ghost tet id " );
-
-  // Perform leak test on face geometry data structure enlarged by ghosts
-  Assert( !leakyAdjacency(), "Face adjacency leaky" );
-  Assert( faceMatch(), "Chare-boundary element-face "
-    "connectivity (esuf) does not match" );
-
-  // Create new map of elements along chare boundary which are ghosts for
-  // neighboring chare, associated with that chare ID
-  for (const auto& [cid, cgd] : m_ghostData)
-  {
-    auto& sg = m_sendGhost[cid];
-    for (const auto& e : cgd)
-    {
-      Assert(sg.find(e.first) == sg.end(), "Repeating element found in "
-        "ghost data");
-      sg.insert(e.first);
-    }
-    Assert(sg.size() == cgd.size(), "Incorrect size for sendGhost");
-  }
-  Assert(m_sendGhost.size() == m_ghostData.size(), "Incorrect number of "
-    "chares in sendGhost");
-
-  // Error checking on ghost data
-  for(const auto& n : m_sendGhost)
-    for([[maybe_unused]] const auto& i : n.second)
-      Assert( i < m_fd.Esuel().size()/4, "Sender contains ghost tet id. " );
-
-  // Generate and store Esup data-structure in a map
-  auto esup = tk::genEsup(m_inpoel, 4);
-  for (std::size_t p=0; p<Disc()->Gid().size(); ++p)
-  {
-    for (auto e : tk::Around(esup, p))
-    {
-      // since inpoel has been augmented with the face-ghost cell previously,
-      // esup also contains cells which are not on this mesh-chunk, hence the
-      // following test
-      if (e < m_fd.Esuel().size()/4) m_esup[p].push_back(e);
-    }
-  }
-
-  // Error checking on Esup map
-  for(const auto& p : m_esup)
-    for([[maybe_unused]] const auto& e : p.second)
-      Assert( e < m_fd.Esuel().size()/4, "Esup contains tet id greater than "
-      + std::to_string(m_fd.Esuel().size()/4-1) +" : "+ std::to_string(e) );
-
-  auto meshid = Disc()->MeshId();
-  contribute( sizeof(std::size_t), &meshid, CkReduction::nop,
-    CkCallback(CkReductionTarget(Transporter,startEsup), Disc()->Tr()) );
-}
-
-void
-Ghosts::nodeNeighSetup()
-// *****************************************************************************
-// Setup node-neighborhood (esup)
-//! \details At this point the face-ghost communication map has been established
-//!    on this chare. This function begins generating the node-ghost comm map.
-// *****************************************************************************
-{
-  if (Disc()->NodeCommMap().empty())
-  // in serial, skip setting up node-neighborhood
-  { comesup_complete(); }
-  else
-  {
-    const auto& nodeCommMap = Disc()->NodeCommMap();
-
-    // send out node-neighborhood map
-    for (const auto& [cid, nlist] : nodeCommMap)
-    {
-      std::unordered_map< std::size_t, std::vector< std::size_t > > bndEsup;
-      std::unordered_map< std::size_t, std::vector< tk::real > > nodeBndCells;
-      for (const auto& p : nlist)
-      {
-        auto pl = tk::cref_find(Disc()->Lid(), p);
-        // fill in the esup for the chare-boundary
-        const auto& pesup = tk::cref_find(m_esup, pl);
-        bndEsup[p] = pesup;
-
-        // fill a map with the element ids from esup as keys and geoElem as
-        // values, and another map containing these elements associated with
-        // the chare id with which they are node-neighbors.
-        for (const auto& e : pesup)
-        {
-          nodeBndCells[e] = m_geoElem[e];
-
-          // add these esup-elements into map of elements along chare boundary
-          Assert( e < m_fd.Esuel().size()/4, "Sender contains ghost tet id." );
-          m_sendGhost[cid].insert(e);
-        }
-      }
-
-      thisProxy[cid].comEsup(thisIndex, bndEsup, nodeBndCells);
-    }
-  }
-
-  ownesup_complete();
-}
-
-void
-Ghosts::comEsup( int fromch,
-  const std::unordered_map< std::size_t, std::vector< std::size_t > >& bndEsup,
-  const std::unordered_map< std::size_t, std::vector< tk::real > >&
-    nodeBndCells )
-// *****************************************************************************
-//! \brief Receive elements-surrounding-points data-structure for points on
-//    common boundary between receiving and sending neighbor chare, and the
-//    element geometries for these new elements
-//! \param[in] fromch Sender chare id
-//! \param[in] bndEsup Elements-surrounding-points data-structure from fromch
-//! \param[in] nodeBndCells Map containing element geometries associated with
-//!   remote element IDs in the esup
-// *****************************************************************************
-{
-  auto& chghost = m_ghost[fromch];
-
-  // Extend remote-local element id map and element geometry array
-  for (const auto& e : nodeBndCells)
-  {
-    // need to check following, because 'e' could have been added previously in
-    // remote-local element id map as a part of face-communication, i.e. as a
-    // face-ghost element
-    if (chghost.find(e.first) == chghost.end())
-    {
-      chghost[e.first] = m_nunk;
-      m_geoElem.push_back(e.second);
-      ++m_nunk;
-    }
-  }
-
-  // Store incoming data in comm-map buffer for Esup
-  for (const auto& [node, elist] : bndEsup)
-  {
-    auto pl = tk::cref_find(Disc()->Lid(), node);
-    auto& pesup = m_esupc[pl];
-    for (auto e : elist)
-    {
-      auto el = tk::cref_find(chghost, e);
-      pesup.push_back(el);
-    }
-  }
-
-  // if we have heard from all fellow chares that we share at least a single
-  // node, edge, or face with
-  if (++m_ncomEsup == Disc()->NodeCommMap().size()) {
-    m_ncomEsup = 0;
-    comesup_complete();
-  }
-}
-
-void
-Ghosts::adj()
-// *****************************************************************************
-// Finish up with adjacency maps, and do a global-sync to begin problem setup
-//! \details At this point, the nodal- and face-adjacency has been set up. This
-//    function does some error checking on the nodal-adjacency and prepares
-//    for problem setup.
-// *****************************************************************************
-{
-  // combine own and communicated contributions to elements surrounding points
-  for (auto& [p, elist] : m_esupc)
-  {
-    auto& pesup = tk::ref_find(m_esup, p);
-    for ([[maybe_unused]] auto e : elist)
-    {
-      Assert( e >= m_fd.Esuel().size()/4, "Non-ghost element received from "
-        "esup buffer." );
-    }
-    tk::concat< std::size_t >(std::move(elist), pesup);
-  }
-
-  tk::destroy(m_ghostData);
-  tk::destroy(m_esupc);
-
-  if ( g_inputdeck.get< tag::cmd, tag::feedback >() ) Disc()->Tr().chadj();
-
-  // Error checking on ghost data
-  for(const auto& n : m_sendGhost)
-    for([[maybe_unused]] const auto& i : n.second)
-      Assert( i < m_fd.Esuel().size()/4, "Sender contains ghost tet id. ");
-
-  // Create a mapping between local ghost tet ids and zero-based boundary ids
-  std::vector< std::size_t > c( tk::sumvalsize( m_ghost ) );
-  std::size_t j = 0;
-  for (const auto& n : m_ghost) {
-    for(const auto& i : n.second) {
-      c[j++] = i.second;
-    }
-  }
-  m_bid = tk::assignLid( c );
-
-  // Basic error checking on ghost tet ID map
-  Assert( m_ghost.find( thisIndex ) == m_ghost.cend(),
-          "Ghost id map should not contain data for own chare ID" );
-
-  // Store expected ghost tet IDs
-  for (const auto& n : m_ghost)
-    for ([[maybe_unused]] const auto& g : n.second)
-      Assert( m_exptGhost.insert( g.second ).second,
-              "Failed to store local tetid as exptected ghost id" );
-
-  // Callback function from DG/FV after ghost-setup is done
-  m_cbAfterDone.send();
-}
-
-bool
-Ghosts::leakyAdjacency()
-// *****************************************************************************
-// Perform leak-test on chare boundary faces
-//! \details This function computes a surface integral over the boundary of the
-//!   faces after the face adjacency communication map is completed. A non-zero
-//!   vector result indicates a leak, e.g., a hole in the partition (covered by
-//!   the faces of the face adjacency communication map), which indicates an
-//!   error upstream in the code that sets up the face communication data
-//!   structures.
-//! \note Compared to tk::leakyPartition() this function performs the leak-test
-//!   on the face geometry data structure enlarged by ghost faces on this
-//!   partition by computing a discrete surface integral considering the
-//!   physical and chare boundary faces, which should be equal to zero for a
-//!   closed domain.
-//! \return True if our chare face adjacency leaks.
-// *****************************************************************************
-{
-  // Storage for surface integral over our chunk of the adjacency
-  std::array< tk::real, 3 > s{{ 0.0, 0.0, 0.0 }};
-
-  // physical boundary faces
-  for (std::size_t f=0; f<m_fd.Nbfac(); ++f) {
-    s[0] += m_geoFace(f,0) * m_geoFace(f,1);
-    s[1] += m_geoFace(f,0) * m_geoFace(f,2);
-    s[2] += m_geoFace(f,0) * m_geoFace(f,3);
-  }
-
-  // chare-boundary faces
-  for (std::size_t f=m_fd.Nipfac(); f<m_fd.Esuf().size()/2; ++f) {
-    s[0] += m_geoFace(f,0) * m_geoFace(f,1);
-    s[1] += m_geoFace(f,0) * m_geoFace(f,2);
-    s[2] += m_geoFace(f,0) * m_geoFace(f,3);
-  }
-
-  auto eps = std::numeric_limits< tk::real >::epsilon() * 100;
-  return std::abs(s[0]) > eps || std::abs(s[1]) > eps || std::abs(s[2]) > eps;
-}
-
-bool
-Ghosts::faceMatch()
-// *****************************************************************************
-// Check if esuf of chare-boundary faces matches
-//! \details This function checks each chare-boundary esuf entry for the left
-//!   and right elements. Then, it tries to match all vertices of these
-//!   elements. Exactly three of these vertices must match if the esuf entry
-//!   has been updated correctly at chare-boundaries.
-//! \return True if chare-boundary faces match.
-// *****************************************************************************
-{
-  const auto& esuf = m_fd.Esuf();
-  bool match(true);
-
-  auto eps = std::numeric_limits< tk::real >::epsilon() * 100;
-
-  for (auto f=m_fd.Nipfac(); f<esuf.size()/2; ++f)
-  {
-    std::size_t el = static_cast< std::size_t >(esuf[2*f]);
-    std::size_t er = static_cast< std::size_t >(esuf[2*f+1]);
-
-    std::size_t count = 0;
-
-    for (std::size_t i=0; i<4; ++i)
-    {
-      auto ip = m_inpoel[4*el+i];
-      for (std::size_t j=0; j<4; ++j)
-      {
-        auto jp = m_inpoel[4*er+j];
-        auto xdiff = std::abs( m_coord[0][ip] - m_coord[0][jp] );
-        auto ydiff = std::abs( m_coord[1][ip] - m_coord[1][jp] );
-        auto zdiff = std::abs( m_coord[2][ip] - m_coord[2][jp] );
-
-        if ( xdiff<=eps && ydiff<=eps && zdiff<=eps ) ++count;
-      }
-    }
-
-    match = (match && count == 3);
-  }
-
-  return match;
-}
-
-bool
-Ghosts::receivedChBndFaces()
-// *****************************************************************************
-// Verify that all chare-boundary faces have been received
-//! \return True if all chare-boundary faces have been received
-// *****************************************************************************
-{
-  const auto& lid = Disc()->Lid();
-  tk::UnsMesh::FaceSet recvBndFace;
-
-  // Collect chare-boundary faces that have been received and expected
-  for (const auto& c : m_bndFace)
-    for (const auto& f : c.second)
-      if (m_expChBndFace.find(f.first) != end(m_expChBndFace))
-        recvBndFace.insert(f.first);
-
-   // Collect info on expected but not received faces
-   std::stringstream msg;
-   for (const auto& f : m_expChBndFace)
-     if (recvBndFace.find(f) == end(recvBndFace)) {
-       const auto& x = m_coord[0];
-       const auto& y = m_coord[1];
-       const auto& z = m_coord[2];
-       auto A = tk::cref_find( lid, f[0] );
-       auto B = tk::cref_find( lid, f[1] );
-       auto C = tk::cref_find( lid, f[2] );
-       msg << '{' << A << ',' << B << ',' << C << "}:("
-           << x[A] << ',' << y[A] << ',' << z[A] << ' '
-           << x[B] << ',' << y[B] << ',' << z[B] << ' '
-           << x[C] << ',' << y[C] << ',' << z[C] << ") ";
-     }
-
-  tk::destroy( m_expChBndFace );
-
-  // Error out with info on missing faces
-  auto s = msg.str();
-  if (!s.empty()) {
-    Throw( "Ghosts chare " + std::to_string(thisIndex) +
-           " missing face(s) {local node ids} (node coords): " + s );
-  } else {
-    return true;
-  }
-}
-
-int
-Ghosts::findchare( const tk::UnsMesh::Face& t )
-// *****************************************************************************
-// Find any chare for face (given by 3 global node IDs)
-//! \param[in] t Face given by three global node IDs
-//! \return Chare ID if found among any of the chares we communicate along
-//!   faces with, -1 if the face cannot be found.
-// *****************************************************************************
-{
-  for (const auto& cf : m_bndFace)
-    // cppcheck-suppress useStlAlgorithm
-    if (cf.second.find(t) != end(cf.second))<--- Unmatched suppression: useStlAlgorithm
-      return cf.first;
-  return -1;
-}
-
-std::size_t
-Ghosts::nodetripletMatch(
-  const std::array< std::size_t, 2 >& id,
-  const tk::UnsMesh::Face& t )
-// *****************************************************************************
-// Check if entries in inpoel, inpofa and node-triplet are consistent
-//! \param[in] id Local face and (inner) tet id adjacent to it
-//! \param[in] t node-triplet associated with the chare boundary face
-//! \return number of nodes in inpoel that matched with t and inpofa
-// *****************************************************************************
-{
-  const auto& esuf = m_fd.Esuf();
-  const auto& inpofa = m_fd.Inpofa();
-  const auto& lid = Disc()->Lid();
-
-  std::size_t counter = 0;
-  for (std::size_t k=0; k<4; ++k)
-  {
-    auto el = esuf[ 2*id[0] ];
-    auto ip = m_inpoel[ 4*static_cast< std::size_t >( el )+k ];<--- Variable 'ip' is assigned a value that is never used.
-    Assert( el == static_cast< int >( id[1] ), "Mismatch in id and esuf" );
-    for (std::size_t j=0; j<3; ++j)
-    {
-      auto jp = tk::cref_find( lid, t[j] );
-      auto fp = inpofa[ 3*id[0]+(2-j) ];
-      if (ip == jp && ip == fp) ++counter;
-    }
-  }
-
-  return counter;
-}
-
-void
-Ghosts::addEsuf(
-  const std::array< std::size_t, 2 >& id,
-  std::size_t ghostid )
-// *****************************************************************************
-// Fill elements surrounding a face along chare boundary
-//! \param[in] id Local face and (inner) tet id adjacent to it
-//! \param[in] ghostid Local ID for ghost tet
-//! \details This function extends and fills in the elements surrounding faces
-//!   data structure (esuf) so that the left and right element id is filled
-//!   in correctly on chare boundaries to contain the correct inner tet id and
-//!   the local tet id for the outer (ghost) tet, both adjacent to the given
-//!   chare-face boundary. Prior to this function, this data structure does not
-//!   have yet face-element connectivity adjacent to chare-boundary faces, only
-//!   for physical boundaries and internal faces that are not on the chare
-//!   boundary (this latter purely as a result of mesh partitioning). The remote
-//!   element id of the ghost is stored in a location that is local to our own
-//!   esuf. The face numbering is such that esuf stores the element-face
-//!   connectivity first for the physical-boundary faces, followed by that of
-//!   the internal faces, followed by the chare-boundary faces. As a result,
-//!   esuf can be used by physics algorithms in exactly the same way as would be
-//!   used in serial. In serial, of course, this data structure is not extended
-//!   at the end by the chare-boundaries.
-// *****************************************************************************
-{
-  auto& esuf = m_fd.Esuf();
-
-  Assert( 2*id[0]+1 < esuf.size(), "Indexing out of esuf" );
-
-  // put in inner tet id
-  Assert( esuf[ 2*id[0] ] == -2 && esuf[ 2*id[0]+1 ] == -2, "Updating esuf at "
-          "wrong location instead of chare-boundary" );
-  esuf[ 2*id[0]+0 ] = static_cast< int >( id[1] );
-  // put in local id for outer/ghost tet
-  esuf[ 2*id[0]+1 ] = static_cast< int >( ghostid );
-}
-
-void
-Ghosts::addEsuel(
-  const std::array< std::size_t, 2 >& id,
-  std::size_t ghostid,
-  const tk::UnsMesh::Face& t )
-// *****************************************************************************
-// Fill elements surrounding a element along chare boundary
-//! \param[in] id Local face and (inner) tet id adjacent to it
-//! \param[in] ghostid Local ID for ghost tet
-//! \param[in] t node-triplet associated with the chare boundary face
-//! \details This function updates the elements surrounding element (esuel) data
-//    structure for the (inner) tets adjacent to the chare-boundaries. It fills
-//    esuel of this inner tet with the local tet-id that has been assigned to
-//    the outer ghost tet in Ghosts::comGhost in place of the -1 before.
-// *****************************************************************************
-{
-  const auto& lid = Disc()->Lid();
-  [[maybe_unused]] const auto& esuf = m_fd.Esuf();
-  auto& esuel = m_fd.Esuel();
-
-  std::array< tk::UnsMesh::Face, 4 > face;
-  for (std::size_t f = 0; f<4; ++f)
-    for (std::size_t i = 0; i<3; ++i)
-      face[f][i] = m_inpoel[ id[1]*4 + tk::lpofa[f][i] ];
-
-  tk::UnsMesh::Face tl{{ tk::cref_find( lid, t[0] ),
-                         tk::cref_find( lid, t[1] ),
-                         tk::cref_find( lid, t[2] ) }};
-
-  std::size_t i(0), nmatch(0);
-  for (const auto& f : face) {
-    if (tk::UnsMesh::Eq< 3 >()( tl, f )) {
-      Assert( esuel[ id[1]*4 + i ] == -1, "Incorrect boundary element found in "
-             "esuel");
-      esuel[ id[1]*4 + i ] = static_cast<int>(ghostid);
-      ++nmatch;<--- Variable 'nmatch' is assigned a value that is never used.
-      Assert( esuel[ id[1]*4 + i ] == esuf[ 2*id[0]+1 ], "Incorrect boundary "
-             "element entered in esuel" );
-      Assert( static_cast<int>(id[1]) == esuf[ 2*id[0]+0 ], "Boundary "
-             "element entered in incorrect esuel location" );
-    }
-    ++i;
-  }
-
-  // ensure that exactly one face matched
-  Assert( nmatch == 1, "Incorrect number of node-triplets (faces) matched for "
-         "updating esuel; matching faces = "+ std::to_string(nmatch) );
-}
-
-void
-Ghosts::addGeoFace(
-  const tk::UnsMesh::Face& t,
-  const std::array< std::size_t, 2 >& id )
-// *****************************************************************************
-// Fill face-geometry data along chare boundary
-//! \param[in] t Face (given by 3 global node IDs) on the chare boundary
-//! \param[in] id Local face and (inner) tet id adjacent to face t
-//! \details This function fills in the face geometry data along a chare
-//!    boundary.
-// *****************************************************************************
-{
-  const auto& lid = Disc()->Lid();
-
-  // get global node IDs reversing order to get outward-pointing normal
-  auto A = tk::cref_find( lid, t[2] );
-  auto B = tk::cref_find( lid, t[1] );
-  auto C = tk::cref_find( lid, t[0] );
-  auto geochf = tk::geoFaceTri( {{m_coord[0][A], m_coord[0][B], m_coord[0][C]}},
-                                {{m_coord[1][A], m_coord[1][B], m_coord[1][C]}},
-                                {{m_coord[2][A], m_coord[2][B], m_coord[2][C]}} );
-
-  for (std::size_t i=0; i<7; ++i)
-    m_geoFace(id[0],i) = geochf(0,i);
-}
-
-#include "NoWarning/ghosts.def.h"
+    if ( std::abs(fcn) <= 1e-16 or (b - a)/2.0 < tol )
+    {
+      root = c;
+      break;
+    }
+
+    i++;
+    if ( static_cast< int > (std::copysign( 1.0, p_known - PfromRT( c, t_known) )) ==
+         static_cast< int > (std::copysign( 1.0, p_known - PfromRT( a, t_known) )) )
+    {
+      a = c;
+    }
+    else
+    {
+      b = c;
+    }
+
+    if ( i == maxiter )
+    {
+      Throw("JWL Bisection for density failed to converge after iterations "
+      + std::to_string(i));
+    }
+    if (std::abs(root-a_o) < 1e-16 || std::abs(root-b_o) < 1e-16)
+    {
+      Throw("JWL bisection for density resulted in left/right bound as "
+      "solution. Extend bounds for correctness");
+    }
+
+  }
+  return root;
+}
+
+
+tk::real
+JWL::PfromRT(
+  tk::real rho,
+  tk::real T ) const
+// *************************************************************************
+//! \brief Calculate pressure from density and temperature using JWL
+//!   equation of state
+//! \param[in] rho Material density
+//! \param[in] T Material temperature
+//! \return Material pressure calculated using the JWL EoS
+//! \details From Eqn. 14 in 'JWL Equation of State', Menikoff, LA-UR-15-29536
+// *************************************************************************
+{
+  return ( m_a*exp(-m_r1*m_rho0/rho) + m_b*exp(-m_r2*m_rho0/rho) +
+    m_w*(m_cv*T*rho) );
+}
 
diff --git a/Debug/cppcheck/39.html b/Debug/cppcheck/39.html index 5fb98ac88e08..bd6b3b45a0f4 100644 --- a/Debug/cppcheck/39.html +++ b/Debug/cppcheck/39.html @@ -152,12 +152,12 @@
  1
@@ -350,655 +350,197 @@ 

Cppcheck report - [

// *****************************************************************************
+191
// *****************************************************************************
 /*!
-  \file      src/PDE/EoS/JWL.cpp
-  \copyright 2012-2015 J. Bakosi,
-             2016-2018 Los Alamos National Security, LLC.,
-             2019-2021 Triad National Security, LLC.
-             All rights reserved. See the LICENSE file for details.
-  \brief     Jones, Wilkins, and Lee (JWL) equation of state
-  \details   This file defines functions for the JWL equation of
-             state for the compressible flow equations. These functions are
-             taken from 'JWL Equation of State', Menikoff, LA-UR-15-29536.
-*/
-// *****************************************************************************
-
-#include <cmath>
-#include <iostream>
-#include "EoS/JWL.hpp"
+  \file      src/Control/Inciter/InputDeck/LuaParser.hpp
+  \copyright 2019-2023 Triad National Security, LLC.
+             All rights reserved. See the LICENSE file for details.
+  \brief     Inciter's lua input deck file parser
+  \details   This file declares the input deck, i.e., control file, parser for
+    the computational shock hydrodynamics tool, Inciter.
+*/
+// *****************************************************************************
+#ifndef InciterLuaParser_h
+#define InciterLuaParser_h
+
+#include "NoWarning/sol.hpp"
+
+#include "Inciter/CmdLine/CmdLine.hpp"
+#include "InputDeck.hpp"
 
-using inciter::JWL;
+namespace tk { class Print; }
 
-JWL::JWL( tk::real w, tk::real cv, tk::real rho0, tk::real de, tk::real rhor,
-  tk::real tr, tk::real pr, tk::real A, tk::real B, tk::real R1, tk::real R2 ) :
-  m_w(w),
-  m_cv(cv),
-  m_rho0(rho0),
-  m_de(de),
-  m_rhor(rhor),
-  m_tr(tr),
-  m_pr(pr),
-  m_a(A),
-  m_b(B),
-  m_r1(R1),
-  m_r2(R2)
-// *************************************************************************
-//  Constructor
-//! \param[in] w Grueneisen coefficient
-//! \param[in] cv Specific heat at constant volume
-//! \param[in] rho0 Density of initial state
-//! \param[in] de Heat of detonation for products. For reactants, it is
-//!   chosen such that the ambient internal energy (e0) is 0.
-//! \param[in] rhor Density of reference state
-//! \param[in] tr Temperature of reference state
-//! \param[in] pr Pressure of reference state
-//! \param[in] A Parameter A
-//! \param[in] B Parameter B
-//! \param[in] R1 Parameter R1
-//! \param[in] R2 Parameter R2
-// *************************************************************************
-{
-  // reference density provided
-  if (m_tr < 1e-8) {
-    // reference internal energy
-    auto er = intEnergy(rhor, pr);
-    // reference temperature from Eqn (15)
-    m_tr = 1.0/m_cv * (er + de -
-      (m_a/m_r1*exp(-m_r1*m_rho0/m_rhor) +
-       m_b/m_r2*exp(-m_r2*m_rho0/m_rhor)) / m_rho0);
-  }
-  // reference temperature provided
-  else
-  {
-    m_rhor = density(m_pr, m_tr);
-  }
-}
-
-tk::real
-JWL::density(
-  tk::real pr,
-  tk::real temp ) const
-// *************************************************************************
-//! \brief Calculate density from the material pressure and temperature
-//!   using the stiffened-gas equation of state
-//! \param[in] pr Material pressure
-//! \param[in] temp Material temperature
-//! \return Material density calculated using the stiffened-gas EoS
-// *************************************************************************
-{
-  tk::real r_guessL = 1e-4*m_rho0;  // left density bound
-  tk::real r_guessR = 1e2*m_rho0;   // right density bound
-  tk::real rho;
-
-  rho = bisection( r_guessL, r_guessR, pr, temp );
-
-  return rho;
-}
-
-
-tk::real
-JWL::pressure(
-  tk::real arho,
-  tk::real u,
-  tk::real v,
-  tk::real w,
-  tk::real arhoE,
-  tk::real alpha,
-  std::size_t imat,
-  const std::array< std::array< tk::real, 3 >, 3 >& ) const
-// *************************************************************************
-//! \brief Calculate pressure from the material density, momentum and total
-//!   energy using the stiffened-gas equation of state
-//! \param[in] arho Material partial density (alpha_k * rho_k)
-//! \param[in] u X-velocity
-//! \param[in] v Y-velocity
-//! \param[in] w Z-velocity
-//! \param[in] arhoE Material total energy (alpha_k * rho_k * E_k)
-//! \param[in] alpha Material volume fraction. Default is 1.0, so that for
-//!   the single-material system, this argument can be left unspecified by
-//!   the calling code
-//! \param[in] imat Material-id who's EoS is required. Default is 0, so that
-//!   for the single-material system, this argument can be left unspecified
-//!   by the calling code
-//! \return Material partial pressure (alpha_k * p_k) calculated using the
-//!   stiffened-gas EoS
-//! \details From Eqn. 1 in 'JWL Equation of State', Menikoff, LA-UR-15-29536
-// *************************************************************************
-{
-  // specific internal energy
-  tk::real e = (arhoE - 0.5*arho*(u*u + v*v + w*w))/arho;
-
-  //// reference energy (input quantity, might need for calculation)
-  //tk::real e0 = a/r1*exp(-r1*rho0/rho) + b/r2*exp(-r2*rho0/rho);
-
-  alpha = std::max(1e-14,alpha);
-  tk::real partpressure =
-    m_a*(alpha - m_w*arho/(m_rho0*m_r1))*exp(-m_r1*alpha*m_rho0/arho) +
-    m_b*(alpha - m_w*arho/(m_rho0*m_r2))*exp(-m_r2*alpha*m_rho0/arho) +
-    m_w*arho*(e + m_de);
-
-  // check partial pressure divergence
-  if (!std::isfinite(partpressure)) {
-    std::cout << "Material-id:      " << imat << std::endl;
-    std::cout << "Volume-fraction:  " << alpha << std::endl;
-    std::cout << "Partial density:  " << arho << std::endl;
-    std::cout << "Total energy:     " << arhoE << std::endl;
-    std::cout << "Velocity:         " << u << ", " << v << ", " << w
-      << std::endl;
-    Throw("Material-" + std::to_string(imat) +
-      " has nan/inf partial pressure: " + std::to_string(partpressure) +
-      ", material volume fraction: " + std::to_string(alpha));
-  }
-
-  return partpressure;
-}
-
-std::array< std::array< tk::real, 3 >, 3 >
-JWL::CauchyStress(
-  tk::real,
-  tk::real,
-  tk::real,
-  tk::real,
-  tk::real,
-  tk::real,
-  std::size_t,
-  const std::array< std::array< tk::real, 3 >, 3 >& ) const
-// *************************************************************************
-//! \brief Calculate the Cauchy stress tensor from the material density,
-//!   momentum, and total energy
-//! \return Material Cauchy stress tensor (alpha_k * sigma_k)
-// *************************************************************************
-{
-  std::array< std::array< tk::real, 3 >, 3 > asig{{{0,0,0}, {0,0,0}, {0,0,0}}};
-
-  // No elastic contribution
-
-  return asig;
-}
-
-tk::real
-JWL::soundspeed(
-  tk::real arho,
-  tk::real apr,
-  tk::real alpha,
-  std::size_t imat,
-  const std::array< std::array< tk::real, 3 >, 3 >&,
-  const std::array< tk::real, 3 >&,
-  const std::array< tk::real, 3 >& ) const
-// *************************************************************************
-//! Calculate speed of sound from the material density and material pressure
-//! \param[in] arho Material partial density (alpha_k * rho_k)
-//! \param[in] apr Material partial pressure (alpha_k * p_k)
-//! \param[in] alpha Material volume fraction. Default is 1.0, so that for
-//!   the single-material system, this argument can be left unspecified by
-//!   the calling code
-//! \param[in] imat Material-id who's EoS is required. Default is 0, so that
-//!   for the single-material system, this argument can be left unspecified
-//!   by the calling code
-//! \return Material speed of sound using the stiffened-gas EoS
-// *************************************************************************
-{
-  alpha = std::max(1e-14,alpha);
-  // limiting pressure to near-zero
-  auto apr_eff = std::max(alpha*
-    min_eff_pressure(1e-4*std::abs(apr/alpha), arho, alpha), apr);
-
-  auto co1 = m_rho0*alpha*alpha/(arho*arho);
-  auto co2 = alpha*(1.0+m_w)/arho;
-
-  tk::real ss = m_a*(m_r1*co1 - co2) * exp(-m_r1*alpha*m_rho0/arho)
-              + m_b*(m_r2*co1 - co2) * exp(-m_r2*alpha*m_rho0/arho)
-              + (1.0+m_w)*apr_eff/arho;
-
-  auto ss2 = ss;
-  ss = std::sqrt(ss);
-
-  // check sound speed divergence
-  if (!std::isfinite(ss)) {
-    std::cout << "Material-id:      " << imat << std::endl;
-    std::cout << "Volume-fraction:  " << alpha << std::endl;
-    std::cout << "Partial density:  " << arho << std::endl;
-    std::cout << "Partial pressure: " << apr << std::endl;
-    std::cout << "Min allowed pres: " << alpha*min_eff_pressure(0.0, arho,
-      alpha) << std::endl;
-    Throw("Material-" + std::to_string(imat) + " has nan/inf sound speed. "
-      "ss^2: " + std::to_string(ss2) + ", material volume fraction: " +
-      std::to_string(alpha));
-  }
-
-  return ss;
-}
-
-tk::real
-JWL::totalenergy(
-  tk::real rho,
-  tk::real u,
-  tk::real v,
-  tk::real w,
-  tk::real pr,
-  const std::array< std::array< tk::real, 3 >, 3 >& ) const
-// *************************************************************************
-//! \brief Calculate material specific total energy from the material
-//!   density, momentum and material pressure
-//! \param[in] rho Material density
-//! \param[in] u X-velocity
-//! \param[in] v Y-velocity
-//! \param[in] w Z-velocity
-//! \param[in] pr Material pressure
-//! \return Material specific total energy using the stiffened-gas EoS
-// *************************************************************************
-{
-  //// reference energy (input quantity, might need for calculation)
-  //tk::real e0 = a/r1*exp(-r1*rho0/rho) + b/r2*exp(-r2*rho0/rho);
-
-  tk::real rhoE = rho*intEnergy( rho, pr )
-                + 0.5*rho*(u*u + v*v + w*w);
-
-  return rhoE;
-}
-
-tk::real
-JWL::temperature(
-  tk::real arho,
-  tk::real u,
-  tk::real v,
-  tk::real w,
-  tk::real arhoE,
-  tk::real alpha,
-  const std::array< std::array< tk::real, 3 >, 3 >& ) const
-// *************************************************************************
-//! \brief Calculate material temperature from the material density, and
-//!   material specific total energy
-//! \param[in] arho Material partial density (alpha_k * rho_k)
-//! \param[in] u X-velocity
-//! \param[in] v Y-velocity
-//! \param[in] w Z-velocity
-//! \param[in] arhoE Material total energy (alpha_k * rho_k * E_k)
-//! \param[in] alpha Material volume fraction. Default is 1.0, so that for
-//!   the single-material system, this argument can be left unspecified by
-//!   the calling code
-//! \return Material temperature using the stiffened-gas EoS
-// *************************************************************************
-{
-  alpha = std::max(1e-14,alpha);
-  tk::real rho = arho/alpha;
-
-  //// reference energy (input quantity, might need for calculation)
-  //tk::real e0 = a/r1*exp(-r1*rho0/rho) + b/r2*exp(-r2*rho0/rho);
-
-  tk::real t = ((arhoE - 0.5*arho*(u*u + v*v + w*w))/arho + m_de -
-    1.0/m_rho0*( m_a/m_r1*exp(-m_r1*m_rho0/rho)
-               + m_b/m_r2*exp(-m_r2*m_rho0/rho) ))/m_cv;
-
-  return t;
-}
-
-tk::real
-JWL::min_eff_pressure(
-  tk::real min,
-  tk::real arho,
-  tk::real alpha ) const
-// *************************************************************************
-//! Compute the minimum allowed pressure
-//! \param[in] min Numerical threshold above which pressure needs to be limited
-//! \param[in] arho Material partial density (alpha_k * rho_k)
-//! \param[in] alpha Material volume fraction. Default is 1.0, so that for
-//!   the single-material system, this argument can be left unspecified by
-//!   the calling code
-//! \return Minimum pressure allowed by physical constraints
-// *************************************************************************
-{
-  alpha = std::max(1e-14,alpha);
-  auto co1 = m_rho0*alpha*alpha/(arho*arho);
-  auto co2 = alpha*(1.0+m_w)/arho;
-
-  // minimum pressure is constrained by zero soundspeed.
-  auto apr = -(m_a*(m_r1*co1 - co2) * exp(-m_r1*alpha*m_rho0/arho)
-             + m_b*(m_r2*co1 - co2) * exp(-m_r2*alpha*m_rho0/arho))
-    * arho/(1.0+m_w);
-
-  return apr/alpha + min;
-}
-
-tk::real
-JWL::intEnergy(
-  tk::real rho,
-  tk::real pr ) const
-// *************************************************************************
-//! \brief Calculate specific internal energy using the JWL equation of
-//!   state
-//! \param[in] rho Material density
-//! \param[in] pr Material pressure
-//! \return Material internal energy calculated using the JWL EoS
-//! \details By inverting Eqn. 1 in 'JWL Equation of State', Menikoff,
-//!   LA-UR-15-29536
-// *************************************************************************
-{
-  tk::real e = - m_de + 1.0/m_w/rho*( pr
-                - m_a*(1.0 - m_w*rho/m_r1/m_rho0)*exp(-m_r1*m_rho0/rho)
-                - m_b*(1.0 - m_w*rho/m_r2/m_rho0)*exp(-m_r2*m_rho0/rho) );
-
-  return e;
-}
-
-tk::real
-JWL::bisection(
-  tk::real a,
-  tk::real b,
-  tk::real p_known,
-  tk::real t_known ) const
-// *************************************************************************
-//! \brief Calculate density from known pressure and temperature using
-//!   bisection root finding method for JWL equation of state
-//! \param[in] a Left density bound for root finding
-//! \param[in] b Right density bound for root finding
-//! \param[in] p_known Known pressure
-//! \param[in] t_known Known temperature
-//! \return Material density calculated by inverting JWL pressure equation
-// *************************************************************************
-{
-  tk::real tol = 1e-12;
-  std::size_t maxiter = 1000;
-  std::size_t i(0);
-  tk::real c;
-  tk::real root(0);
-  std::size_t idebug = 0;<--- Assignment 'idebug=0', assigned value is 0
-  auto a_o = a;
-  auto b_o = b;
-
-  // function to minimize: fcn = p_known - PfromRT
-  // bounds b > a
-
-  while (i < maxiter)
-  {
-    c = (a + b)/2.0;
-    auto fcn = p_known - PfromRT( c, t_known);
-    if ( idebug == 1)<--- Condition 'idebug==1' is always false
-    {
-      std::cout << "Bisection iter:      " << i << std::endl;
-      std::cout << "fcn:  " << fcn << std::endl;
-      std::cout << "(b - a)/2.0: " << (b - a)/2.0 << std::endl;
-    }
-
-    if ( std::abs(fcn) <= 1e-16 or (b - a)/2.0 < tol )
-    {
-      root = c;
-      break;
-    }
-
-    i++;
-    if ( static_cast< int > (std::copysign( 1.0, p_known - PfromRT( c, t_known) )) ==
-         static_cast< int > (std::copysign( 1.0, p_known - PfromRT( a, t_known) )) )
-    {
-      a = c;
-    }
-    else
-    {
-      b = c;
-    }
-
-    if ( i == maxiter )
-    {
-      Throw("JWL Bisection for density failed to converge after iterations "
-      + std::to_string(i));
-    }
-    if (std::abs(root-a_o) < 1e-16 || std::abs(root-b_o) < 1e-16)
-    {
-      Throw("JWL bisection for density resulted in left/right bound as "
-      "solution. Extend bounds for correctness");
-    }
-
-  }
-  return root;
-}
-
-
-tk::real
-JWL::PfromRT(
-  tk::real rho,
-  tk::real T ) const
-// *************************************************************************
-//! \brief Calculate pressure from density and temperature using JWL
-//!   equation of state
-//! \param[in] rho Material density
-//! \param[in] T Material temperature
-//! \return Material pressure calculated using the JWL EoS
-//! \details From Eqn. 14 in 'JWL Equation of State', Menikoff, LA-UR-15-29536
-// *************************************************************************
-{
-  return ( m_a*exp(-m_r1*m_rho0/rho) + m_b*exp(-m_r2*m_rho0/rho) +
-    m_w*(m_cv*T*rho) );
-}
+namespace inciter {
+
+//! \brief Control file lua-parser for Inciter.
+//! \details This class is used to interface with sol2, for the purpose of
+//!   parsing the control file for the computational shock hydrodynamics tool,
+//!   Inciter.
+class LuaParser {
+
+  public:
+    //! Constructor
+    explicit LuaParser( const tk::Print& print,
+                              const ctr::CmdLine& cmdline,
+                              ctr::InputDeck& inputdeck );
+
+    //! Store lua inputdeck in custom struct
+    void storeInputDeck(
+      const sol::table& lua_ideck,
+      ctr::InputDeck& gideck );
+
+    //! Check and store material property into inpudeck storage
+    void checkStoreMatProp(
+      const sol::table table,
+      const std::string key,
+      std::size_t vecsize,
+      std::vector< tk::real >& storage );
+
+    //! Check and store field output variables
+    void addOutVar(
+      const std::string& varname,
+      const std::string& alias,
+      std::vector< char >& depv,
+      std::size_t nmat,
+      inciter::ctr::PDEType pde,
+      tk::Centering c,
+      std::vector< inciter::ctr::OutVar >& foutvar );
+
+  private:
+    const std::string m_filename;             //!< Name of file to parse
+
+    //! Assign parameter to inputdeck entry if specified, else default
+    //! \tparam N Type of parameter being read/assigned
+    //! \param[in] table Sol-table which contains said parameter
+    //! \param[in] key Key for said parameter in Sol-table
+    //! \param[in,out] storage Storage space in inputdeck where said parameter
+    //!   is to be stored
+    //! \param[in] dflt Default value of said parameter, if unspecified
+    template< typename N > void
+    storeIfSpecd(
+      const sol::table table,
+      const std::string key,
+      N& storage,
+      const N dflt )
+    {
+      auto sol_var = table[key];
+      if (sol_var.valid())
+        storage = sol_var;
+      else
+        storage = dflt;
+    }
+
+    //! Assign Option to inputdeck entry if specified, else default
+    //! \tparam Op Option-Type of parameter being read/assigned
+    //! \tparam OpClass Option-class of parameter being read/assigned
+    //! \param[in] table Sol-table which contains said parameter
+    //! \param[in] key Key for said parameter in Sol-table
+    //! \param[in,out] storage Storage space in inputdeck where said parameter
+    //!   is to be stored
+    //! \param[in] dflt Default value of said parameter, if unspecified
+    template< typename Op, class OpClass > void
+    storeOptIfSpecd(
+      const sol::table table,
+      const std::string key,
+      Op& storage,
+      const Op dflt )
+    {
+      OpClass opt;
+      auto sol_var = table[key];
+      if (sol_var.valid())
+        storage = opt.value(sol_var);
+      else
+        storage = dflt;
+    }
+
+    //! Assign vector parameter to inputdeck entry if specified, else default
+    //! \tparam N Type of parameter vector being read/assigned
+    //! \param[in] table Sol-table which contains said parameter
+    //! \param[in] key Key for said parameter in Sol-table
+    //! \param[in,out] storage Storage space in inputdeck where said parameter
+    //!   is to be stored
+    //! \param[in] dflt Default value of said parameter, if unspecified
+    template< typename N > void
+    storeVecIfSpecd(
+      const sol::table table,
+      const std::string key,
+      std::vector< N >& storage,
+      const std::vector< N >& dflt )
+    {
+      auto sol_vec = table[key];
+      if (sol_vec.valid()) {
+        for (std::size_t i=0; i<sol::table(sol_vec).size(); ++i)
+          storage.push_back(sol_vec[i+1]);
+      }
+      else
+        storage = dflt;
+    }
+
+    //! Assign vector of Options to inputdeck entry if specified, else default
+    //! \tparam Op Option-Type of parameter being read/assigned
+    //! \tparam OpClass Option-class of parameter being read/assigned
+    //! \param[in] table Sol-table which contains said parameter
+    //! \param[in] key Key for said parameter in Sol-table
+    //! \param[in,out] storage Storage space in inputdeck where said parameter
+    //!   is to be stored
+    //! \param[in] dflt Default value of said parameter, if unspecified
+    template< typename Op, class OpClass > void
+    storeOptVecIfSpecd(
+      const sol::table table,
+      const std::string key,
+      std::vector< Op >& storage,
+      const std::vector< Op >& dflt )
+    {
+      OpClass opt;
+      auto sol_vec = table[key];
+      if (sol_vec.valid()) {
+        for (std::size_t i=0; i<sol::table(sol_vec).size(); ++i)
+          storage.push_back(opt.value(sol_vec[i+1]));
+      }
+      else
+        storage = dflt;
+    }
+
+    //! \brief Check validity of keywords within a particular block
+    //! \tparam tags Tags addressing the said block in the input deck
+    //! \param[in] block Sol table of the input deck block read in from the
+    //!   lua file
+    //! \param[in] blk_name Name of the block, for error clarity
+    template< typename... tags >
+    void checkBlock(const sol::table& block, const std::string& blk_name) const
+    {
+      for (const auto& kvp : block) {
+        bool is_valid(false);
+        auto ukw = kvp.first.as<std::string>();
+        brigand::for_each< tags... >( checkKw(ukw, is_valid) );
+        if (!is_valid)
+          Throw("Invalid keyword '" + ukw + "' in '" + blk_name + "' block.");
+      }
+    }
+
+    // Check if a keyword matches the existing ones
+    struct checkKw {
+      std::string user_kw;
+      // reference to bool keeping track of kw-match
+      bool& is_valid;
+      // Constructor
+      checkKw( const std::string& ukw, bool& isv ) :
+        user_kw(ukw), is_valid(isv) {}
+      //! Function to call for each keyword type
+      template< typename U > void operator()( brigand::type_<U> ) {
+        auto spec_key = U::name();
+        // only check if not previously matched
+        if (!is_valid) {
+          if (user_kw == spec_key) is_valid = true;
+          else is_valid = false;
+        }
+      }
+    };
+};
+
+} // namespace inciter
+
+#endif // InciterLuaParser_h
 
diff --git a/Debug/cppcheck/4.html b/Debug/cppcheck/4.html index e7ac4aaaa9fc..d1c39d1210e7 100644 --- a/Debug/cppcheck/4.html +++ b/Debug/cppcheck/4.html @@ -152,12 +152,12 @@
  1
@@ -278,251 +278,125 @@ 

Cppcheck report - [

// *****************************************************************************
+119
// *****************************************************************************
 /*!
-  \file      src/IO/Omega_h_MeshReader.cpp
+  \file      src/Inciter/DiagReducer.cpp
   \copyright 2012-2015 J. Bakosi,
              2016-2018 Los Alamos National Security, LLC.,
              2019-2021 Triad National Security, LLC.
              All rights reserved. See the LICENSE file for details.
-  \brief     Omega_h mesh reader
-  \details   Omega_h mesh reader class definition.
+  \brief     Custom Charm++ reducer for merging std::vectors across PEs
+  \details   Custom Charm++ reducer for merging std::vectors across PEs.
 */
 // *****************************************************************************
 
-#include "NoWarning/Omega_h_file.hpp"
-#include <Omega_h_library.hpp>
-
-#include "Macro.hpp"
-#include "Omega_h_MeshReader.hpp"
-#include "Reorder.hpp"
-
-using tk::Omega_h_MeshReader;
-
-void
-Omega_h_MeshReader::readMeshPart(
-  std::vector< std::size_t >& ginpoel,
-  std::vector< std::size_t >& inpoel,
-  [[maybe_unused]] std::vector< std::size_t >& triinp,
-  std::unordered_map< std::size_t, std::size_t >& lid,
-  tk::UnsMesh::Coords& coord,
-  std::unordered_map< std::size_t, std::set< std::size_t > >&,
-  int numpes,
-  [[maybe_unused]] int mype )
-// *****************************************************************************
-//  Read a part of the mesh (graph and coordinates) from Omega_h file
-//! \param[in,out] ginpoel Container to store element connectivity of this PE's
-//!   chunk of the mesh (global ids)
-//! \param[in,out] inpoel Container to store element connectivity with local
-//!   node IDs of this PE's mesh chunk
-//! \param[in,out] triinp Container to store triangle element connectivity
-//!   (if exists in file) with global node indices
-//! \param[in,out] lid Container to store global->local node IDs of elements of
-//!   this PE's mesh chunk
-//! \param[in,out] coord Container to store coordinates of mesh nodes of this
-//!   PE's mesh chunk
-//! \param[in] numpes Total number of PEs (default n = 1, for a single-CPU read)
-//! \param[in] mype This PE (default m = 0, for a single-CPU read)
-//! \note The last two integer arguments are unused. They are needed because
-//!   this function can be used via a polymorphic interface via a base class,
-//!   see tk::MeshReader, and other specialized mesh readers, e.g.,
-//!   tk::ExodusIIMeshReader, use these arguments. Here we require the Omega_h
-//!   input mesh to be pre-partitioned, with Omega_h's osh_part tool, into the
-//!   number of partitions that is equal to the number of PEs this fuinction is
-//!   called on in parallel.
-// *****************************************************************************
-{
-  Assert( mype < numpes, "Invalid input: PE id must be lower than NumPEs" );
-  Assert( ginpoel.empty() && inpoel.empty() && lid.empty() &&
-          coord[0].empty() && coord[1].empty() && coord[2].empty(),
-          "Containers to store mesh must be empty" );
-
-  #if defined(__clang__)
-    #pragma clang diagnostic push
-    #pragma clang diagnostic ignored "-Wold-style-cast"
-  #endif
-
-  // Create Omega_h library instance
-  auto lib = Omega_h::Library( nullptr, nullptr, MPI_COMM_WORLD );
+#include <stddef.h>
+#include <type_traits>
+#include <memory>
+
+#include "DiagReducer.hpp"
+#include "Diagnostics.hpp"
+#include "Exception.hpp"
+
+namespace inciter {
+
+std::pair< int, std::unique_ptr<char[]> >
+serialize( std::size_t meshid,
+           std::size_t ncomp,
+           const std::vector< std::vector< tk::real > >& d )
+// *****************************************************************************
+// Serialize std::vectors to raw memory stream
+//! \param[in] meshid Mesh ID
+//! \param[in] ncomp Number of scalar components being solved
+//! \param[in] d Diagnostics vector of vectors (of eq components)
+//! \return Pair of the length and the raw stream containing the serialized
+//!   vectors
+// *****************************************************************************
+{
+  // Prepare for serializing diagnostics to a raw binary stream, compute size
+  PUP::sizer sizer;
+  sizer | meshid;
+  sizer | ncomp;
+  sizer | const_cast< std::vector< std::vector< tk::real > >& >( d );
+
+  // Create raw character stream to store the serialized vectors
+  std::unique_ptr<char[]> flatData = std::make_unique<char[]>( sizer.size() );
+
+  // Serialize vector, each message will contain a vector
+  PUP::toMem packer( flatData.get() );
+  packer | meshid;
+  packer | ncomp;
+  packer | const_cast< std::vector< std::vector< tk::real > >& >( d );
+
+  // Return size of and raw stream
+  return { sizer.size(), std::move(flatData) };
+}
+
+CkReductionMsg*
+mergeDiag( int nmsg, CkReductionMsg **msgs )
+// *****************************************************************************
+// Charm++ custom reducer for merging diagnostics during reduction across PEs
+//! \param[in] nmsg Number of messages in msgs
+//! \param[in] msgs Charm++ reduction message containing the serialized
+//!   diagnostics
+//! \return Aggregated diagnostics built for further aggregation if needed
+// *****************************************************************************
+{
+  std::size_t meshid, ncomp;
+  std::vector< std::vector< tk::real > > v;
 
-  #if defined(__clang__)
-    #pragma clang diagnostic pop
-  #endif
-
-  // Find out how many partitions the Omega_h mesh was saved with
-  auto nparts = Omega_h::binary::read_nparts( m_filename, lib.world() );
-
-  if (numpes < nparts)
-    Throw( "The Omega_h mesh reader only supports NumPEs >= nparts, where "
-           "nparts is the number of partitions the mesh is partitioned into. "
-           "Also note that NumPEs must be a power of 2 if NumPEs > nparts." );
-
-  // Read mesh
-  auto mesh = Omega_h::binary::read( m_filename, &lib );
-
-  // Lambda to check if int is a power of two
-  auto isPowerOfTwo = []( int x ) { return (x != 0) && ((x & (x - 1)) == 0); };
-
-  if (nparts != numpes) {
-    if (!isPowerOfTwo(numpes))
-      Throw( "The Omega_h mesh reader only supports NumPEs of power of 2" );
-    else
-      mesh.balance();
-  }
-
-  // Extract connectivity from Omega_h's mesh object
-  auto ntets = mesh.nelems();
-  ginpoel.resize( static_cast< std::size_t >( ntets ) * 4 );
-  auto o_inpoel = mesh.ask_elem_verts();
-  auto o_gid = mesh.globals( Omega_h::VERT );
-  for (int i=0; i<ntets; ++i)
-    for (int j=0; j<4; ++j) {
-      auto I = static_cast< std::size_t >( i );
-      auto J = static_cast< std::size_t >( j );
-      ginpoel[ I*4+J ] = static_cast<std::size_t>( o_gid[ o_inpoel[i*4+j] ] );
-    }
-
-  // Extract node coordinates from Omega_h's mesh object
-  auto o_coord = mesh.coords();
-
-  // Extract number of vertices from Omega_h's mesh object
-  auto nnode = static_cast< std::size_t >( mesh.nverts() );
-
-  // Extract node coordinates from Omega_h's mesh object
-  auto& x = coord[0];
-  auto& y = coord[1];
-  auto& z = coord[2];
-  x.resize( nnode );
-  y.resize( nnode );
-  z.resize( nnode );
+  // Create PUP deserializer based on message passed in
+  PUP::fromMem creator( msgs[0]->getData() );
+
+  // Deserialize vector from raw stream
+  creator | meshid;<--- Uninitialized variable: meshid
+  creator | ncomp;<--- Uninitialized variable: ncomp
+  creator | v;
+
+  for (int m=1; m<nmsg; ++m) {
+    // Unpack vector
+    std::size_t mid, nc;
+    std::vector< std::vector< tk::real > > w;
+    PUP::fromMem curCreator( msgs[m]->getData() );
+    curCreator | mid;<--- Uninitialized variable: mid
+    curCreator | nc;<--- Uninitialized variable: nc
+    curCreator | w;
+    // Aggregate diagnostics vector
+    meshid = mid;<--- Uninitialized variable: mid<--- Variable 'meshid' is assigned a value that is never used.
+    ncomp = nc;<--- Uninitialized variable: nc<--- Variable 'ncomp' is assigned a value that is never used.
+    Assert( v.size() == w.size(),
+            "Size mismatch during diagnostics aggregation" );
+    Assert( v.size() == inciter::NUMDIAG,
+            "Size mismatch during diagnostics aggregation" );
+    for (std::size_t i=0; i<v.size(); ++i)<--- Unsigned less than zero
+      Assert( v[i].size() == w[i].size(),
+              "Size mismatch during diagnostics aggregation" );
+    // Apply diagnostics aggregation policy
+    // Sum for L2 normal of the numerical solution for all scalar components
+    for (std::size_t i=0; i<v[L2SOL].size(); ++i) v[L2SOL][i] += w[L2SOL][i];
+    // Sum for the L2 norm of the numerical - analytical solution for all comps
+    for (std::size_t i=0; i<v[L2ERR].size(); ++i) v[L2ERR][i] += w[L2ERR][i];
+    // Sum for the L2 norm of the residual of all components
+    for (std::size_t i=0; i<v[L2RES].size(); ++i) v[L2RES][i] += w[L2RES][i];
+    // Max for the Linf norm of the numerical - analytical solution for all comp
+    for (std::size_t i=0; i<v[LINFERR].size(); ++i)
+      if (w[LINFERR][i] > v[LINFERR][i]) v[LINFERR][i] = w[LINFERR][i];
+    // Sum of the total energy over the entire domain
+    v[TOTALSOL][0] += w[TOTALSOL][0];
+    // Copy ITER, TIME, DT
+    for (std::size_t j=v.size()-3; j<v.size(); ++j)
+      for (std::size_t i=0; i<v[j].size(); ++i)
+        v[j][i] = w[j][i];
+  }
+
+  // Serialize concatenated diagnostics vector to raw stream
+  auto stream = serialize( meshid, ncomp, v );
+
+  // Forward serialized diagnostics
+  return CkReductionMsg::buildNew( stream.first, stream.second.get() );
+}
 
-  for (std::size_t I=0; I<nnode; ++I) {
-    auto i = static_cast< int >( I );
-    x[I] = o_coord[ i*3+0 ];
-    y[I] = o_coord[ i*3+1 ];
-    z[I] = o_coord[ i*3+2 ];
-  }
-
-  // Compute local data from global mesh connectivity
-  std::vector< std::size_t > gid;
-  std::tie( inpoel, gid, lid ) = tk::global2local( ginpoel );
-}
-
-
-std::vector< std::size_t >
-Omega_h_MeshReader::triinpoel(
-  [[maybe_unused]] std::map< int, std::vector< std::size_t > >& bface,<--- Parameter 'bface' can be declared with const
-  [[maybe_unused]] const std::map< int, std::vector< std::size_t > >& faces,
-  [[maybe_unused]] const std::vector< std::size_t >& ginpoel,
-  [[maybe_unused]] const std::vector< std::size_t >& triinp ) const
-// *****************************************************************************
-// ...
-//! \note Must be preceded by a call to readElemBlockIDs()
-// *****************************************************************************
-{
-  std::vector< std::size_t > bnd_triinpoel;
-  return bnd_triinpoel;
-}
-
-void
-Omega_h_MeshReader::readSidesetFaces(
-  [[maybe_unused]] std::map< int, std::vector< std::size_t > >& bface,<--- Parameter 'bface' can be declared with const
-  [[maybe_unused]] std::map< int, std::vector< std::size_t > >& faces )<--- Parameter 'faces' can be declared with const
-// *****************************************************************************
-//  Read side sets from Omega_h file
-//! \param[in,out] bface Elem ids of side sets to read into
-//! \param[in,out] faces Elem-relative face ids of tets of side sets
-// *****************************************************************************
-{
-}
-
-void
-Omega_h_MeshReader::readFaces(
-  [[maybe_unused]] std::vector< std::size_t >& conn )
-// *****************************************************************************
-//  Read face connectivity of a number of boundary faces from Omega_h file
-//! \param[in,out] conn Connectivity vector to push to
-//! \details This function reads in the total number of boundary faces,
-//!   also called triangle-elements, and their connectivity.
-// *****************************************************************************
-{
-}
-
-std::map< int, std::vector< std::size_t > >
-Omega_h_MeshReader::readSidesetNodes()
-// *****************************************************************************
-//  Read node list of all side sets from Omega_h file
-//! \return Node lists mapped to side set ids
-// *****************************************************************************
-{
-  // Node lists mapped to side set ids
-  std::map< int, std::vector< std::size_t > > side;
-
-  return side;
-}
+} // inciter::
 
diff --git a/Debug/cppcheck/40.html b/Debug/cppcheck/40.html index 76e0ccd19e41..46a37a5f70b1 100644 --- a/Debug/cppcheck/40.html +++ b/Debug/cppcheck/40.html @@ -152,12 +152,12 @@
  1
@@ -394,241 +394,375 @@ 

Cppcheck report - [

// *****************************************************************************
+235
+236
+237
+238
+239
+240
+241
+242
+243
+244
+245
+246
+247
+248
+249
+250
+251
+252
+253
+254
+255
+256
+257
+258
+259
+260
+261
+262
+263
+264
+265
+266
+267
+268
+269
+270
+271
+272
+273
+274
+275
+276
+277
+278
+279
+280
+281
+282
+283
+284
+285
+286
+287
+288
+289
+290
+291
+292
+293
+294
+295
+296
+297
+298
+299
+300
+301
+302
// *****************************************************************************
 /*!
-  \file      src/Inciter/ElemDiagnostics.cpp
+  \file      src/Inciter/Ghosts.hpp
   \copyright 2012-2015 J. Bakosi,
              2016-2018 Los Alamos National Security, LLC.,
              2019-2021 Triad National Security, LLC.
              All rights reserved. See the LICENSE file for details.
-  \brief     ElemDiagnostics class for collecting element diagnostics
-  \details   ElemDiagnostics class for collecting element diagnostics, e.g.,
-    residuals, and various norms of errors while solving partial differential
-    equations.
-*/
-// *****************************************************************************
+  \brief     Declarations file for generating ghost data structures
+  \details   Declarations file for asynchronous distributed
+             ghost data structures using Charm++.
+
+    There are a potentially large number of Ghosts Charm++ chares.
+    Each Ghosts chare gets a chunk of the full load, due to partiting the mesh.
 
-#include <array>
-#include <vector>
-#include <cmath>
-
-#include "DGPDE.hpp"
-#include "ElemDiagnostics.hpp"
-#include "DiagReducer.hpp"
-#include "Discretization.hpp"
-#include "Integrate/Basis.hpp"
-#include "Integrate/Quadrature.hpp"
-#include "Inciter/InputDeck/InputDeck.hpp"
+    The implementation uses the Charm++ runtime system and is fully
+    asynchronous, overlapping computation and communication. The algorithm
+    utilizes the structured dagger (SDAG) Charm++ functionality.
+*/
+// *****************************************************************************
+#ifndef Ghosts_h
+#define Ghosts_h
+
+#include "Fields.hpp"
+#include "FaceData.hpp"
+#include "Discretization.hpp"
 
-namespace inciter {
+#include "NoWarning/ghosts.decl.h"
 
-extern ctr::InputDeck g_inputdeck;
-extern std::vector< DGPDE > g_dgpde;
-
-static CkReduction::reducerType DiagMerger;
+namespace inciter {
+
+//! Ghosts Charm++ chare array used to determine ghost data structures
+class Ghosts : public CBase_Ghosts {
 
-} // inciter::
-
-using inciter::ElemDiagnostics;
-
-void
-ElemDiagnostics::registerReducers()
-// *****************************************************************************
-//  Configure Charm++ reduction types
-//! \details This routine is supposed to be called from a Charm++ initnode
-//!   routine. Since the runtime system executes initnode routines exactly once
-//!   on every logical node early on in the Charm++ init sequence, they must be
-//!   static as they are called without an object. See also: Section
-//!   "Initializations at Program Startup" at in the Charm++ manual
-//!   http://charm.cs.illinois.edu/manuals/html/charm++/manual.html.
-// *****************************************************************************
-{
-  DiagMerger = CkReduction::addReducer( mergeDiag );
-}
-
-bool
-ElemDiagnostics::compute( Discretization& d,
-                          const std::size_t nchGhost,
-                          const tk::Fields& geoElem,
-                          const std::vector< std::size_t >& ndofel,
-                          const tk::Fields& u,
-                          const tk::Fields& un ) const
-// *****************************************************************************
-//  Compute diagnostics, e.g., residuals, norms of errors, etc.
-//! \param[in] d Discretization base class to read from
-//! \param[in] nchGhost Number of chare boundary ghost elements
-//! \param[in] geoElem Element geometry
-//! \param[in] ndofel Vector of local number of degrees of freedom
-//! \param[in] u Current solution vector
-//! \param[in] un Previous time-step solution vector
-//! \return True if diagnostics have been computed
-//! \details Diagnostics are defined as some norm, e.g., L2 norm, of a quantity,
-//!    computed in mesh elements, A, as ||A||_2 = sqrt[ sum_i(A_i)^2 V_i ],
-//!    where the sum is taken over all mesh elements and V_i is the cell volume.
-//!    We send multiple sets of quantities to the host for aggregation across
-//!    the whole mesh. The final aggregated solution will end up in
-//!    Transporter::diagnostics(). Aggregation of the partially computed
-//!    diagnostics is done via potentially different policies for each field.
-//! \see inciter::mergeDiag(), src/Inciter/Diagnostics.h
-// *****************************************************************************
-{
-  // Optionally collect diagnostics and send for aggregation across all workers
-
-  // Query after how many time steps user wants to dump diagnostics
-  auto diagfreq = g_inputdeck.get< tag::diagnostics, tag::interval >();
-
-  if ( !((d.It()+1) % diagfreq) || d.finished() ) {  // if remainder, don't compute diagnostics
-
-    // Query number of degrees of freedom from user's setting
-    const auto rdof = g_inputdeck.get< tag::rdof >();
-
-    // Diagnostics vector (of vectors) during aggregation. See
-    // Inciter/Diagnostics.h.
-    std::vector< std::vector< tk::real > >
-      diag( NUMDIAG, std::vector< tk::real >( u.nprop()/rdof, 0.0 ) );
-
-    // Compute diagnostics for DG
-    compute_diag(d, rdof, nchGhost, geoElem, ndofel, u, un, diag);
-
-    // Append diagnostics vector with metadata on the current time step
-    // ITER: Current iteration count (only the first entry is used)
-    // TIME: Current physical time (only the first entry is used)
-    // DT: Current physical time step size (only the first entry is used)
-    diag[ITER][0] = static_cast< tk::real >( d.It() );
-    diag[TIME][0] = d.T();
-    diag[DT][0] = d.Dt();
-
-    // Contribute to diagnostics
-    auto stream = serialize( d.MeshId(), u.nprop()/rdof, diag );
-    d.contribute( stream.first, stream.second.get(), DiagMerger,
-      CkCallback(CkIndex_Transporter::diagnostics(nullptr), d.Tr()) );
-
-    return true;        // diagnostics have been computed
-
-  }
-
-  return false;         // diagnostics have not been computed
-}
-
-void
-ElemDiagnostics::compute_diag( const Discretization& d,<--- Function 'compute_diag' argument order different: declaration 'd, ndofel, nchGhost, geoElem, pIndex, u, un, diag' definition 'd, rdof, nchGhost, geoElem, ndofel, u, un, diag'
-                               const std::size_t rdof,
-                               const std::size_t nchGhost,
-                               const tk::Fields& geoElem,
-                               const std::vector< std::size_t >& ndofel,
-                               const tk::Fields& u,
-                               const tk::Fields& un,
-                               std::vector< std::vector< tk::real > >& diag )
-const
-// *****************************************************************************
-//  Compute diagnostics, e.g., residuals, norms of errors, etc. for DG
-//! \param[in] d Discretization base class to read from
-//! \param[in] rdof Number of reconstructed degrees of freedom
-//! \param[in] nchGhost Number of chare boundary ghost elements
-//! \param[in] geoElem Element geometry
-//! \param[in] ndofel Vector of local number of degrees of freedom
-//! \param[in] u Current solution vector
-//! \param[in] un Previous time-step solution vector
-//! \param[in,out] diag Diagnostics vector
-// *****************************************************************************
-{
-  const auto& inpoel = d.Inpoel();
-  const auto& coord = d.Coord();
-
-  const auto& cx = coord[0];
-  const auto& cy = coord[1];
-  const auto& cz = coord[2];
-
-  for (std::size_t e=0; e<u.nunk()-nchGhost; ++e)
-  {
-    std::size_t dofe(1);
-    if (!ndofel.empty()) {
-      dofe = ndofel[e];
-    }
-    // Number of quadrature points for volume integration
-    auto ng = tk::NGdiag(dofe);
-
-    // arrays for quadrature points
-    std::array< std::vector< tk::real >, 3 > coordgp;
-    std::vector< tk::real > wgp;
+  public:
+    #if defined(__clang__)
+      #pragma clang diagnostic push
+      #pragma clang diagnostic ignored "-Wunused-parameter"
+      #pragma clang diagnostic ignored "-Wdeprecated-declarations"
+    #elif defined(STRICT_GNUC)
+      #pragma GCC diagnostic push
+      #pragma GCC diagnostic ignored "-Wunused-parameter"
+      #pragma GCC diagnostic ignored "-Wdeprecated-declarations"
+    #elif defined(__INTEL_COMPILER)
+      #pragma warning( push )
+      #pragma warning( disable: 1478 )
+    #endif
+    // Include Charm++ SDAG code. See http://charm.cs.illinois.edu/manuals/html/
+    // charm++/manual.html, Sec. "Structured Control Flow: Structured Dagger".
+    Ghosts_SDAG_CODE
+    #if defined(__clang__)
+      #pragma clang diagnostic pop
+    #elif defined(STRICT_GNUC)
+      #pragma GCC diagnostic pop
+    #elif defined(__INTEL_COMPILER)
+      #pragma warning( pop )
+    #endif
+
+    //! Constructor
+    explicit
+    Ghosts( const CProxy_Discretization& disc,
+      const std::map< int, std::vector< std::size_t > >& bface,
+      const std::vector< std::size_t >& triinpoel,
+      std::size_t nunk,
+      CkCallback cbDone );
+
+    #if defined(__clang__)
+      #pragma clang diagnostic push
+      #pragma clang diagnostic ignored "-Wundefined-func-template"
+    #endif
+    //! Migrate constructor
+    // cppcheck-suppress uninitMemberVar
+    explicit Ghosts( CkMigrateMessage* ) {}
+    #if defined(__clang__)
+      #pragma clang diagnostic pop
+    #endif
+
+    //! Local face & tet IDs associated to 3 global node IDs
+    //! \details This map stores tetrahedron cell faces (map key) and their
+    //!   associated local face ID and inner local tet id adjacent to the face
+    //!   (map value). A face is given by 3 global node IDs.
+    using FaceMap =
+      std::unordered_map< tk::UnsMesh::Face,  // 3 global node IDs
+                          std::array< std::size_t, 2 >, // local face & tet ID
+                          tk::UnsMesh::Hash<3>,
+                          tk::UnsMesh::Eq<3> >;
+
+    //! Storage type for refined mesh used for field output
+    struct OutMesh {
+      //! Element connectivity, local->global node ids, global->local nodes ids
+      tk::UnsMesh::Chunk chunk;
+      //! Node coordinates
+      tk::UnsMesh::Coords coord;
+      //! Triangle element connectivity
+      std::vector< std::size_t > triinpoel;
+      //! Boundary-face connectivity
+      std::map< int, std::vector< std::size_t > > bface;
+      //! Node communinaction map
+      tk::NodeCommMap nodeCommMap;
+      //! \brief Pack/Unpack serialize member function
+      //! \param[in,out] p Charm++'s PUP::er serializer object reference
+      void pup( PUP::er& p ) {<--- Parameter 'p' can be declared with const
+        p|chunk; p|coord; p|triinpoel; p|bface; p|nodeCommMap;
+      }
+      //! Destroyer
+      void destroy() {
+        tk::destroy( std::get<0>(chunk) );
+        tk::destroy( std::get<1>(chunk) );
+        tk::destroy( std::get<2>(chunk) );
+        tk::destroy( coord[0] );
+        tk::destroy( coord[1] );
+        tk::destroy( coord[2] );
+        tk::destroy( triinpoel );
+        tk::destroy( bface );
+        tk::destroy( nodeCommMap );
+      }
+    };
+
+    //! Discretization proxy
+    CProxy_Discretization m_disc;
+    //! Counter for number of unknowns on this chare (including ghosts)
+    std::size_t m_nunk;
+    //! Mesh connectivity extended
+    std::vector< std::size_t > m_inpoel;
+    //! Node coordinates extended
+    tk::UnsMesh::Coords m_coord;
+    //! Face data
+    FaceData m_fd;
+    //! Face geometry
+    tk::Fields m_geoFace;
+    //! Element geometry
+    tk::Fields m_geoElem;
+    //! Counter for number of faces on this chare (including chare boundaries)
+    std::size_t m_nfac;
+    //! Face & tet IDs associated to global node IDs of the face for each chare
+    //! \details This map stores not only the unique faces associated to
+    //!   fellow chares, but also a newly assigned local face ID and adjacent
+    //!   local tet ID.
+    std::unordered_map< int, FaceMap > m_bndFace;
+    //! Elements which are ghosts for other chares associated to those chare IDs
+    std::unordered_map< int, std::unordered_set< std::size_t > > m_sendGhost;
+    //! Local element id associated to ghost remote id charewise
+    //! \details This map associates the local element id (inner map value) to
+    //!    the (remote) element id of the ghost (inner map key) based on the
+    //!    chare id (outer map key) this remote element lies in.
+    std::unordered_map< int,
+      std::unordered_map< std::size_t, std::size_t > > m_ghost;
+    //! Expected ghost tet ids (used only in DEBUG)
+    std::set< std::size_t > m_exptGhost;
+    //! Map local ghost tet ids (value) and zero-based boundary ids (key)
+    std::unordered_map< std::size_t, std::size_t > m_bid;
+    //! Elements (value) surrounding point (key) data-structure
+    std::map< std::size_t, std::vector< std::size_t > > m_esup;
+    //! 1 if starting time stepping, 0 if during time stepping
+    std::size_t m_initial;
+
+    //1 Start setup of communication maps for cell-centered schemes
+    void startCommSetup();
 
-    coordgp[0].resize( ng );
-    coordgp[1].resize( ng );
-    coordgp[2].resize( ng );
-    wgp.resize( ng );
-
-    tk::GaussQuadratureTet( ng, coordgp, wgp );
-
-    // Extract the element coordinates
-    std::array< std::array< tk::real, 3>, 4 > coordel {{
-      {{ cx[ inpoel[4*e  ] ], cy[ inpoel[4*e  ] ], cz[ inpoel[4*e  ] ] }},
-      {{ cx[ inpoel[4*e+1] ], cy[ inpoel[4*e+1] ], cz[ inpoel[4*e+1] ] }},
-      {{ cx[ inpoel[4*e+2] ], cy[ inpoel[4*e+2] ], cz[ inpoel[4*e+2] ] }},
-      {{ cx[ inpoel[4*e+3] ], cy[ inpoel[4*e+3] ], cz[ inpoel[4*e+3] ] }} }};
-
-    for (std::size_t igp=0; igp<ng; ++igp)
-    {
-      // Compute the coordinates of quadrature point at physical domain
-      auto gp = tk::eval_gp( igp, coordel, coordgp );
-
-      // Compute the basis function
-      auto B = tk::eval_basis( dofe, coordgp[0][igp], coordgp[1][igp],
-                               coordgp[2][igp]);
-
-      auto wt = wgp[igp] * geoElem(e, 0);
+    //! Start sizing communication buffers and setting up ghost data
+    void resizeComm();
+
+    //! Receive unique set of faces we potentially share with/from another chare
+    void comfac( int fromch, const tk::UnsMesh::FaceSet& infaces );
+
+    //! Receive ghost data on chare boundaries from fellow chare
+    void comGhost( int fromch, const GhostData& ghost );
+
+    //! Receive requests for ghost data
+    void reqGhost();
+
+    //! Send all of our ghost data to fellow chares
+    void sendGhost();
+
+    //! Setup node-neighborhood (esup)
+    void nodeNeighSetup();
+
+    //! Receive element-surr-points data on chare boundaries from fellow chare
+    void comEsup( int fromch,
+      const std::unordered_map< std::size_t, std::vector< std::size_t > >&
+        bndEsup,
+      const std::unordered_map< std::size_t, std::vector< tk::real > >&
+        nodeBndCells );
 
-      std::vector< tk::real > s;
-
-      // cppcheck-suppress useStlAlgorithm
-      s = g_dgpde[d.MeshId()].solution( gp[0], gp[1], gp[2], d.T() );<--- Unmatched suppression: useStlAlgorithm
-
-      for (std::size_t c=0; c<u.nprop()/rdof; ++c)
-      {
-        auto mark = c*rdof;
-        auto ugp = u(e, mark);
-
-        if(dofe > 1)
-        {
-          ugp +=  u(e, mark+1) * B[1]
-                + u(e, mark+2) * B[2]
-                + u(e, mark+3) * B[3];
-
-          if(dofe > 4)
-          {
-            ugp +=  u(e, mark+4) * B[4]
-                  + u(e, mark+5) * B[5]
-                  + u(e, mark+6) * B[6]
-                  + u(e, mark+7) * B[7]
-                  + u(e, mark+8) * B[8]
-                  + u(e, mark+9) * B[9];
-          }
-        }
-
-        // Compute sum for L2 norm of the numerical solution
-        diag[L2SOL][c] += wt * ugp * ugp;
-
-        // Compute sum for L2 norm of the numerical-analytic solution
-        diag[L2ERR][c] += wt * (ugp-s[c]) * (ugp-s[c]);
-
-        // Compute max for Linf norm of the numerical-analytic solution
-        auto err = std::abs( ugp - s[c] );
-        if (err > diag[LINFERR][c]) diag[LINFERR][c] = err;
-      }
-    }
-    tk::real sp_te(0.0);
-    // cppcheck-suppress useStlAlgorithm
-    sp_te += g_dgpde[d.MeshId()].sp_totalenergy(e, u);<--- Unmatched suppression: useStlAlgorithm
-
-    // Compute sum of the total energy over the entire domain (only the
-    // first entry is used)
-    diag[TOTALSOL][0] += geoElem(e,0) * sp_te;
-
-    // Compute sum for L2 norm of the cell-avg residual
-    for (std::size_t c=0; c<u.nprop()/rdof; ++c)
-      diag[L2RES][c] += geoElem(e, 0) *
-        ( (u(e,c*rdof)-un(e,c*rdof)) * (u(e,c*rdof)-un(e,c*rdof)) );
-  }
-}
+    /** @name Pack/unpack (Charm++ serialization) routines */
+    ///@{
+    //! \brief Pack/Unpack serialize member function
+    //! \param[in,out] p Charm++'s PUP::er serializer object reference
+    void pup( PUP::er &p ) override {
+      p | m_disc;
+      p | m_nunk;
+      p | m_inpoel;
+      p | m_coord;
+      p | m_fd;
+      p | m_geoFace;
+      p | m_geoElem;
+      p | m_nfac;
+      p | m_bndFace;
+      p | m_sendGhost;
+      p | m_ghost;
+      p | m_exptGhost;
+      p | m_bid;
+      p | m_esup;
+      p | m_initial;
+      p | m_ncomfac;
+      p | m_nadj;
+      p | m_ncomEsup;
+      p | m_ipface;
+      p | m_ghostData;
+      p | m_ghostReq;
+      p | m_expChBndFace;
+      p | m_infaces;
+      p | m_esupc;
+      p | m_cbAfterDone;
+    }
+    //! \brief Pack/Unpack serialize operator|
+    //! \param[in,out] p Charm++'s PUP::er serializer object reference
+    //! \param[in,out] a Ghosts object reference
+    friend void operator|( PUP::er& p, Ghosts& a ) { a.pup(p); }
+    ///@}
+
+  private:
+    using ncomp_t = tk::ncomp_t;
+
+    //! Counter for face adjacency communication map
+    std::size_t m_ncomfac;
+    //! Counter signaling that all ghost data have been received
+    std::size_t m_nadj;
+    //! Counter for element-surr-node adjacency communication map
+    std::size_t m_ncomEsup;
+    //! Internal + physical boundary faces (inverse of inpofa)
+    tk::UnsMesh::FaceSet m_ipface;
+    //! Ghost data associated to chare IDs we communicate with
+    std::unordered_map< int, GhostData > m_ghostData;
+    //! Number of chares requesting ghost data
+    std::size_t m_ghostReq;
+    //! Unique set of chare-boundary faces this chare is expected to receive
+    tk::UnsMesh::FaceSet m_expChBndFace;
+    //! Incoming communication buffer during chare-boundary face communication
+    std::unordered_map< int, tk::UnsMesh::FaceSet > m_infaces;
+    //! Communication buffer for esup data-structure
+    std::map< std::size_t, std::vector< std::size_t > > m_esupc;
+    //! Function call to continue with in Scheme when Ghosts is done
+    CkCallback m_cbAfterDone;
+
+    //! Access bound Discretization class pointer
+    Discretization* Disc() const {
+      Assert( m_disc[ thisIndex ].ckLocal() != nullptr, "ckLocal() null" );
+      return m_disc[ thisIndex ].ckLocal();
+    }
+
+    //! Compute chare-boundary faces
+    void bndFaces();
+
+    //! Setup own ghost data on this chare
+    void setupGhost();
+
+    //! Continue after face adjacency communication map completed on this chare
+    void faceAdj();
+
+    //! Compute partial boundary surface integral and sum across all chares
+    void bndIntegral();
+
+    //! Continue after node adjacency communication map completed on this chare
+    void adj();
+
+    //! Perform leak-test on chare boundary faces
+    bool leakyAdjacency();
+
+    //! Check if esuf of chare-boundary faces matches
+    bool faceMatch();
+
+    //! Verify that all chare-boundary faces have been received
+    bool receivedChBndFaces();
+
+    //! Find any chare for face (given by 3 global node IDs)
+    int findchare( const tk::UnsMesh::Face& t );
+
+    //! Check if entries in inpoel, inpofa and node-triplet are consistent
+    std::size_t nodetripletMatch(
+      const std::array< std::size_t, 2 >& id,
+      const tk::UnsMesh::Face& t );
+
+    //! Fill elements surrounding a face along chare boundary
+    void addEsuf(
+      const std::array< std::size_t, 2 >& id,
+      std::size_t ghostid );
+
+    //! Fill elements surrounding a element along chare boundary
+    void addEsuel(
+      const std::array< std::size_t, 2 >& id,
+      std::size_t ghostid,
+      const tk::UnsMesh::Face& t );
+
+    //! Fill face-geometry data along chare boundary
+    void addGeoFace(
+      const tk::UnsMesh::Face& t,
+      const std::array< std::size_t, 2 >& id );
+};
+
+} // inciter::
+
+#endif // Ghosts_h
 
diff --git a/Debug/cppcheck/41.html b/Debug/cppcheck/41.html index 5d3b43be9d2b..77bfaea037e3 100644 --- a/Debug/cppcheck/41.html +++ b/Debug/cppcheck/41.html @@ -152,253 +152,2199 @@
- - + @@ -110,7 +110,7 @@ 36 : : bool normal; 37 : : bool has_parent; 38 : : - 39 : 1024146 : Refinement_State() {} + 39 : 998784 : Refinement_State() {} 40 : : 41 : : /** 42 : : * @brief Constructor which allows for all data fields to be explicitly diff --git a/Debug/test_coverage/Inciter/AMR/active_element_store.hpp.func-sort-c.html b/Debug/test_coverage/Inciter/AMR/active_element_store.hpp.func-sort-c.html index a7c005708d9e..145050b7fdd5 100644 --- a/Debug/test_coverage/Inciter/AMR/active_element_store.hpp.func-sort-c.html +++ b/Debug/test_coverage/Inciter/AMR/active_element_store.hpp.func-sort-c.html @@ -33,7 +33,7 @@ - + @@ -73,7 +73,7 @@ - + diff --git a/Debug/test_coverage/Inciter/AMR/active_element_store.hpp.func.html b/Debug/test_coverage/Inciter/AMR/active_element_store.hpp.func.html index a07935bdd7ab..efc1386c169f 100644 --- a/Debug/test_coverage/Inciter/AMR/active_element_store.hpp.func.html +++ b/Debug/test_coverage/Inciter/AMR/active_element_store.hpp.func.html @@ -33,7 +33,7 @@ - + @@ -77,7 +77,7 @@ - + diff --git a/Debug/test_coverage/Inciter/AMR/active_element_store.hpp.gcov.html b/Debug/test_coverage/Inciter/AMR/active_element_store.hpp.gcov.html index 91d2e1ec594c..5cac9ec9c9ac 100644 --- a/Debug/test_coverage/Inciter/AMR/active_element_store.hpp.gcov.html +++ b/Debug/test_coverage/Inciter/AMR/active_element_store.hpp.gcov.html @@ -33,7 +33,7 @@ - + @@ -86,7 +86,7 @@ 12 : : public: 13 : : 14 : : //! Non-const-ref access to state - 15 : 24399 : std::set<size_t>& data() { return active_elements; } + 15 : 24138 : std::set<size_t>& data() { return active_elements; } 16 : : 17 : : /** 18 : : * @brief Function to add active elements diff --git a/Debug/test_coverage/Inciter/AMR/edge.cpp.func-sort-c.html b/Debug/test_coverage/Inciter/AMR/edge.cpp.func-sort-c.html index 189a4188bf35..63b8fa715f35 100644 --- a/Debug/test_coverage/Inciter/AMR/edge.cpp.func-sort-c.html +++ b/Debug/test_coverage/Inciter/AMR/edge.cpp.func-sort-c.html @@ -33,7 +33,7 @@ - + diff --git a/Debug/test_coverage/Inciter/AMR/edge.cpp.func.html b/Debug/test_coverage/Inciter/AMR/edge.cpp.func.html index 8d1bd6301799..5a6b962aa5cc 100644 --- a/Debug/test_coverage/Inciter/AMR/edge.cpp.func.html +++ b/Debug/test_coverage/Inciter/AMR/edge.cpp.func.html @@ -33,7 +33,7 @@ - + diff --git a/Debug/test_coverage/Inciter/AMR/edge.cpp.gcov.html b/Debug/test_coverage/Inciter/AMR/edge.cpp.gcov.html index 6104d5f79cfa..66f6135ba573 100644 --- a/Debug/test_coverage/Inciter/AMR/edge.cpp.gcov.html +++ b/Debug/test_coverage/Inciter/AMR/edge.cpp.gcov.html @@ -33,7 +33,7 @@ - + diff --git a/Debug/test_coverage/Inciter/AMR/edge.hpp.func-sort-c.html b/Debug/test_coverage/Inciter/AMR/edge.hpp.func-sort-c.html index 3fa89680a998..7f3242fcf571 100644 --- a/Debug/test_coverage/Inciter/AMR/edge.hpp.func-sort-c.html +++ b/Debug/test_coverage/Inciter/AMR/edge.hpp.func-sort-c.html @@ -33,7 +33,7 @@ - + @@ -81,7 +81,7 @@ - + @@ -97,15 +97,15 @@ - + - + - +
  1
-  2
-  3
-  4
-  5
-  6
-  7
-  8
-  9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
- 37
- 38
- 39
- 40
- 41
- 42
- 43
- 44
- 45
- 46
- 47
- 48
- 49
- 50
- 51
- 52
- 53
- 54
- 55
- 56
- 57
- 58
- 59
- 60
- 61
- 62
- 63
- 64
- 65
- 66
- 67
- 68
- 69
- 70
- 71
- 72
- 73
- 74
- 75
- 76
- 77
- 78
- 79
- 80
- 81
- 82
- 83
- 84
- 85
- 86
- 87
- 88
- 89
- 90
- 91
- 92
- 93
- 94
- 95
- 96
- 97
- 98
- 99
-100
-101
-102
-103
-104
-105
-106
-107
-108
-109
-110
-111
-112
-113
-114
-115
-116
-117
-118
-119
-120
// *****************************************************************************
+
   1
+   2
+   3
+   4
+   5
+   6
+   7
+   8
+   9
+  10
+  11
+  12
+  13
+  14
+  15
+  16
+  17
+  18
+  19
+  20
+  21
+  22
+  23
+  24
+  25
+  26
+  27
+  28
+  29
+  30
+  31
+  32
+  33
+  34
+  35
+  36
+  37
+  38
+  39
+  40
+  41
+  42
+  43
+  44
+  45
+  46
+  47
+  48
+  49
+  50
+  51
+  52
+  53
+  54
+  55
+  56
+  57
+  58
+  59
+  60
+  61
+  62
+  63
+  64
+  65
+  66
+  67
+  68
+  69
+  70
+  71
+  72
+  73
+  74
+  75
+  76
+  77
+  78
+  79
+  80
+  81
+  82
+  83
+  84
+  85
+  86
+  87
+  88
+  89
+  90
+  91
+  92
+  93
+  94
+  95
+  96
+  97
+  98
+  99
+ 100
+ 101
+ 102
+ 103
+ 104
+ 105
+ 106
+ 107
+ 108
+ 109
+ 110
+ 111
+ 112
+ 113
+ 114
+ 115
+ 116
+ 117
+ 118
+ 119
+ 120
+ 121
+ 122
+ 123
+ 124
+ 125
+ 126
+ 127
+ 128
+ 129
+ 130
+ 131
+ 132
+ 133
+ 134
+ 135
+ 136
+ 137
+ 138
+ 139
+ 140
+ 141
+ 142
+ 143
+ 144
+ 145
+ 146
+ 147
+ 148
+ 149
+ 150
+ 151
+ 152
+ 153
+ 154
+ 155
+ 156
+ 157
+ 158
+ 159
+ 160
+ 161
+ 162
+ 163
+ 164
+ 165
+ 166
+ 167
+ 168
+ 169
+ 170
+ 171
+ 172
+ 173
+ 174
+ 175
+ 176
+ 177
+ 178
+ 179
+ 180
+ 181
+ 182
+ 183
+ 184
+ 185
+ 186
+ 187
+ 188
+ 189
+ 190
+ 191
+ 192
+ 193
+ 194
+ 195
+ 196
+ 197
+ 198
+ 199
+ 200
+ 201
+ 202
+ 203
+ 204
+ 205
+ 206
+ 207
+ 208
+ 209
+ 210
+ 211
+ 212
+ 213
+ 214
+ 215
+ 216
+ 217
+ 218
+ 219
+ 220
+ 221
+ 222
+ 223
+ 224
+ 225
+ 226
+ 227
+ 228
+ 229
+ 230
+ 231
+ 232
+ 233
+ 234
+ 235
+ 236
+ 237
+ 238
+ 239
+ 240
+ 241
+ 242
+ 243
+ 244
+ 245
+ 246
+ 247
+ 248
+ 249
+ 250
+ 251
+ 252
+ 253
+ 254
+ 255
+ 256
+ 257
+ 258
+ 259
+ 260
+ 261
+ 262
+ 263
+ 264
+ 265
+ 266
+ 267
+ 268
+ 269
+ 270
+ 271
+ 272
+ 273
+ 274
+ 275
+ 276
+ 277
+ 278
+ 279
+ 280
+ 281
+ 282
+ 283
+ 284
+ 285
+ 286
+ 287
+ 288
+ 289
+ 290
+ 291
+ 292
+ 293
+ 294
+ 295
+ 296
+ 297
+ 298
+ 299
+ 300
+ 301
+ 302
+ 303
+ 304
+ 305
+ 306
+ 307
+ 308
+ 309
+ 310
+ 311
+ 312
+ 313
+ 314
+ 315
+ 316
+ 317
+ 318
+ 319
+ 320
+ 321
+ 322
+ 323
+ 324
+ 325
+ 326
+ 327
+ 328
+ 329
+ 330
+ 331
+ 332
+ 333
+ 334
+ 335
+ 336
+ 337
+ 338
+ 339
+ 340
+ 341
+ 342
+ 343
+ 344
+ 345
+ 346
+ 347
+ 348
+ 349
+ 350
+ 351
+ 352
+ 353
+ 354
+ 355
+ 356
+ 357
+ 358
+ 359
+ 360
+ 361
+ 362
+ 363
+ 364
+ 365
+ 366
+ 367
+ 368
+ 369
+ 370
+ 371
+ 372
+ 373
+ 374
+ 375
+ 376
+ 377
+ 378
+ 379
+ 380
+ 381
+ 382
+ 383
+ 384
+ 385
+ 386
+ 387
+ 388
+ 389
+ 390
+ 391
+ 392
+ 393
+ 394
+ 395
+ 396
+ 397
+ 398
+ 399
+ 400
+ 401
+ 402
+ 403
+ 404
+ 405
+ 406
+ 407
+ 408
+ 409
+ 410
+ 411
+ 412
+ 413
+ 414
+ 415
+ 416
+ 417
+ 418
+ 419
+ 420
+ 421
+ 422
+ 423
+ 424
+ 425
+ 426
+ 427
+ 428
+ 429
+ 430
+ 431
+ 432
+ 433
+ 434
+ 435
+ 436
+ 437
+ 438
+ 439
+ 440
+ 441
+ 442
+ 443
+ 444
+ 445
+ 446
+ 447
+ 448
+ 449
+ 450
+ 451
+ 452
+ 453
+ 454
+ 455
+ 456
+ 457
+ 458
+ 459
+ 460
+ 461
+ 462
+ 463
+ 464
+ 465
+ 466
+ 467
+ 468
+ 469
+ 470
+ 471
+ 472
+ 473
+ 474
+ 475
+ 476
+ 477
+ 478
+ 479
+ 480
+ 481
+ 482
+ 483
+ 484
+ 485
+ 486
+ 487
+ 488
+ 489
+ 490
+ 491
+ 492
+ 493
+ 494
+ 495
+ 496
+ 497
+ 498
+ 499
+ 500
+ 501
+ 502
+ 503
+ 504
+ 505
+ 506
+ 507
+ 508
+ 509
+ 510
+ 511
+ 512
+ 513
+ 514
+ 515
+ 516
+ 517
+ 518
+ 519
+ 520
+ 521
+ 522
+ 523
+ 524
+ 525
+ 526
+ 527
+ 528
+ 529
+ 530
+ 531
+ 532
+ 533
+ 534
+ 535
+ 536
+ 537
+ 538
+ 539
+ 540
+ 541
+ 542
+ 543
+ 544
+ 545
+ 546
+ 547
+ 548
+ 549
+ 550
+ 551
+ 552
+ 553
+ 554
+ 555
+ 556
+ 557
+ 558
+ 559
+ 560
+ 561
+ 562
+ 563
+ 564
+ 565
+ 566
+ 567
+ 568
+ 569
+ 570
+ 571
+ 572
+ 573
+ 574
+ 575
+ 576
+ 577
+ 578
+ 579
+ 580
+ 581
+ 582
+ 583
+ 584
+ 585
+ 586
+ 587
+ 588
+ 589
+ 590
+ 591
+ 592
+ 593
+ 594
+ 595
+ 596
+ 597
+ 598
+ 599
+ 600
+ 601
+ 602
+ 603
+ 604
+ 605
+ 606
+ 607
+ 608
+ 609
+ 610
+ 611
+ 612
+ 613
+ 614
+ 615
+ 616
+ 617
+ 618
+ 619
+ 620
+ 621
+ 622
+ 623
+ 624
+ 625
+ 626
+ 627
+ 628
+ 629
+ 630
+ 631
+ 632
+ 633
+ 634
+ 635
+ 636
+ 637
+ 638
+ 639
+ 640
+ 641
+ 642
+ 643
+ 644
+ 645
+ 646
+ 647
+ 648
+ 649
+ 650
+ 651
+ 652
+ 653
+ 654
+ 655
+ 656
+ 657
+ 658
+ 659
+ 660
+ 661
+ 662
+ 663
+ 664
+ 665
+ 666
+ 667
+ 668
+ 669
+ 670
+ 671
+ 672
+ 673
+ 674
+ 675
+ 676
+ 677
+ 678
+ 679
+ 680
+ 681
+ 682
+ 683
+ 684
+ 685
+ 686
+ 687
+ 688
+ 689
+ 690
+ 691
+ 692
+ 693
+ 694
+ 695
+ 696
+ 697
+ 698
+ 699
+ 700
+ 701
+ 702
+ 703
+ 704
+ 705
+ 706
+ 707
+ 708
+ 709
+ 710
+ 711
+ 712
+ 713
+ 714
+ 715
+ 716
+ 717
+ 718
+ 719
+ 720
+ 721
+ 722
+ 723
+ 724
+ 725
+ 726
+ 727
+ 728
+ 729
+ 730
+ 731
+ 732
+ 733
+ 734
+ 735
+ 736
+ 737
+ 738
+ 739
+ 740
+ 741
+ 742
+ 743
+ 744
+ 745
+ 746
+ 747
+ 748
+ 749
+ 750
+ 751
+ 752
+ 753
+ 754
+ 755
+ 756
+ 757
+ 758
+ 759
+ 760
+ 761
+ 762
+ 763
+ 764
+ 765
+ 766
+ 767
+ 768
+ 769
+ 770
+ 771
+ 772
+ 773
+ 774
+ 775
+ 776
+ 777
+ 778
+ 779
+ 780
+ 781
+ 782
+ 783
+ 784
+ 785
+ 786
+ 787
+ 788
+ 789
+ 790
+ 791
+ 792
+ 793
+ 794
+ 795
+ 796
+ 797
+ 798
+ 799
+ 800
+ 801
+ 802
+ 803
+ 804
+ 805
+ 806
+ 807
+ 808
+ 809
+ 810
+ 811
+ 812
+ 813
+ 814
+ 815
+ 816
+ 817
+ 818
+ 819
+ 820
+ 821
+ 822
+ 823
+ 824
+ 825
+ 826
+ 827
+ 828
+ 829
+ 830
+ 831
+ 832
+ 833
+ 834
+ 835
+ 836
+ 837
+ 838
+ 839
+ 840
+ 841
+ 842
+ 843
+ 844
+ 845
+ 846
+ 847
+ 848
+ 849
+ 850
+ 851
+ 852
+ 853
+ 854
+ 855
+ 856
+ 857
+ 858
+ 859
+ 860
+ 861
+ 862
+ 863
+ 864
+ 865
+ 866
+ 867
+ 868
+ 869
+ 870
+ 871
+ 872
+ 873
+ 874
+ 875
+ 876
+ 877
+ 878
+ 879
+ 880
+ 881
+ 882
+ 883
+ 884
+ 885
+ 886
+ 887
+ 888
+ 889
+ 890
+ 891
+ 892
+ 893
+ 894
+ 895
+ 896
+ 897
+ 898
+ 899
+ 900
+ 901
+ 902
+ 903
+ 904
+ 905
+ 906
+ 907
+ 908
+ 909
+ 910
+ 911
+ 912
+ 913
+ 914
+ 915
+ 916
+ 917
+ 918
+ 919
+ 920
+ 921
+ 922
+ 923
+ 924
+ 925
+ 926
+ 927
+ 928
+ 929
+ 930
+ 931
+ 932
+ 933
+ 934
+ 935
+ 936
+ 937
+ 938
+ 939
+ 940
+ 941
+ 942
+ 943
+ 944
+ 945
+ 946
+ 947
+ 948
+ 949
+ 950
+ 951
+ 952
+ 953
+ 954
+ 955
+ 956
+ 957
+ 958
+ 959
+ 960
+ 961
+ 962
+ 963
+ 964
+ 965
+ 966
+ 967
+ 968
+ 969
+ 970
+ 971
+ 972
+ 973
+ 974
+ 975
+ 976
+ 977
+ 978
+ 979
+ 980
+ 981
+ 982
+ 983
+ 984
+ 985
+ 986
+ 987
+ 988
+ 989
+ 990
+ 991
+ 992
+ 993
+ 994
+ 995
+ 996
+ 997
+ 998
+ 999
+1000
+1001
+1002
+1003
+1004
+1005
+1006
+1007
+1008
+1009
+1010
+1011
+1012
+1013
+1014
+1015
+1016
+1017
+1018
+1019
+1020
+1021
+1022
+1023
+1024
+1025
+1026
+1027
+1028
+1029
+1030
+1031
+1032
+1033
+1034
+1035
+1036
+1037
+1038
+1039
+1040
+1041
+1042
+1043
+1044
+1045
+1046
+1047
+1048
+1049
+1050
+1051
+1052
+1053
+1054
+1055
+1056
+1057
+1058
+1059
+1060
+1061
+1062
+1063
+1064
+1065
+1066
+1067
+1068
+1069
+1070
+1071
+1072
+1073
+1074
+1075
+1076
+1077
+1078
+1079
+1080
+1081
+1082
+1083
+1084
+1085
+1086
+1087
+1088
+1089
+1090
+1091
+1092
+1093
// *****************************************************************************
 /*!
-  \file      src/Main/InciterPrint.hpp
+  \file      src/Inciter/Ghosts.cpp
   \copyright 2012-2015 J. Bakosi,
              2016-2018 Los Alamos National Security, LLC.,
              2019-2021 Triad National Security, LLC.
              All rights reserved. See the LICENSE file for details.
-  \brief     Inciter-specific pretty printer functionality
-  \details   Inciter-specific pretty printer functionality.
-*/
-// *****************************************************************************
-#ifndef InciterPrint_h
-#define InciterPrint_h
-
-#include <iostream>
-#include <string>
-
-#include "NoWarning/format.hpp"
+  \brief     Definitions file for generating ghost data structures
+  \details   Definitions file for asynchronous distributed
+             ghost data structures using Charm++.
+*/
+// *****************************************************************************
+
+#include "Ghosts.hpp"
+#include "DerivedData.hpp"
+#include "Reorder.hpp"
+#include "Around.hpp"
+#include "ChareStateCollector.hpp"
 
-#include "Print.hpp"
-#include "ContainerUtil.hpp"
-#include "Inciter/InputDeck/InputDeck.hpp"
-#include "Inciter/Options/Physics.hpp"
-#include "Inciter/Options/Problem.hpp"
-
-namespace inciter {
-
-extern ctr::InputDeck g_inputdeck_defaults;
-extern ctr::InputDeck g_inputdeck;
-
-//! InciterPrint : tk::Print
-class InciterPrint : public tk::Print {
-
-  public:
-    //! Constructor
-    //! \param[in] screen Screen output filename
-    //! \param[in,out] str Verbose stream
-    //! \param[in] mode Open mode for screen output file, see
-    //!   http://en.cppreference.com/w/cpp/io/ios_base/openmode
-    //! \param[in,out] qstr Quiet stream
-    //! \see tk::RNGPrint::RNGPrint and tk::Print::Print
-    explicit InciterPrint( const std::string& screen,
-                           std::ostream& str = std::clog,
-                           std::ios_base::openmode mode = std::ios_base::out,
-                           std::ostream& qstr = std::cout ) :
-      Print( screen, str, mode, qstr ) {}
-
-    //! Print control option: 'group : option'
-    template< typename Option, typename... tags >
-    void Item() const {
-      Option opt;
-      m_stream << m_item_name_value_fmt
-                  % m_item_indent % opt.group()
-                  % opt.name( g_inputdeck.get< tags... >() );
-    }
-
-    // Helper class for compact output of PDE policies
-    class Policies {
-      public:
-        // Default constructor
-        explicit Policies() : phys(), prob() {}
-        // Initializer constructor
-        explicit Policies( const std::string& p, const std::string& t ) :
-          phys(p), prob(t) {}
-        // Operator += for adding up two Policies structs
-        Policies& operator+= ( const Policies& p ) {
-          phys += p.phys;
-          prob += p.prob;
-          return *this;
-        }
-
-      private:
-        // Make all policies unique
-        void unique() { tk::unique( phys ); tk::unique( prob ); }
-
-        std::string phys;
-        std::string prob;
-    };
-
-    //! Print equation list with policies
-    //! \param[in] t Section title
-    //! \param[in] factory Factory to get equation data from
-    //! \param[in] ntypes Unique equation types
-    template< class Factory >
-    void eqlist( const std::string& t,
-                 const Factory& factory,
-                 std::size_t ntypes ) const
-    {
-      if (!factory.empty()) {
-        section( t );
-        item( "Unique equation types", ntypes );
-        item( "With all policy combinations", factory.size() );
-      }
-    }
-
-    //! Print configuration of a stack of partial differential equations
-    void pdes( const std::string& t,
-      const std::vector< std::vector< std::pair< std::string, std::string > > >&
-        info ) const;
-
-    //! Print out info on solver coupling
-    void couple( const std::vector< Transfer >& transfer,
-                 const std::vector< char >& depvar ) const;
-
-    //! Print time integration header
-    void inthead( const std::string& t, const std::string& name,
-                  const std::string& legend, const std::string& head ) const;
-
-  private:
-    //! Return partial differential equation name
-    //! \param[in] key Equation key
-    //! \return Partial differential equation name based on key
-    template< class Key >
-    std::string PDEName ( const Key& key ) const<--- Unused private function: 'InciterPrint::PDEName'
-    { return ctr::PDE().name( key.template get< tag::pde >() ); }
-};
-
-} // inciter::
-
-#endif // InciterPrint_h
+extern tk::CProxy_ChareStateCollector stateProxy;
+
+using inciter::Ghosts;
+
+Ghosts::Ghosts( const CProxy_Discretization& disc,
+  const std::map< int, std::vector< std::size_t > >& bface,
+  const std::vector< std::size_t >& triinpoel,
+  std::size_t nunk,
+  CkCallback cbDone ) :
+  m_disc( disc ),
+  m_nunk( nunk ),
+  m_inpoel( Disc()->Inpoel() ),
+  m_coord( Disc()->Coord() ),
+  m_fd( m_inpoel, bface, tk::remap(triinpoel,Disc()->Lid()) ),
+  m_geoFace( tk::genGeoFaceTri( m_fd.Nipfac(), m_fd.Inpofa(), m_coord) ),
+  m_geoElem( tk::genGeoElemTet( m_inpoel, m_coord ) ),
+  m_nfac( m_fd.Inpofa().size()/3 ),
+  m_bndFace(),
+  m_sendGhost(),
+  m_ghost(),
+  m_exptGhost(),
+  m_bid(),
+  m_esup(),
+  m_initial( 1 ),
+  m_ncomfac( 0 ),
+  m_nadj( 0 ),
+  m_ncomEsup( 0 ),
+  m_ipface(),
+  m_ghostData(),
+  m_ghostReq( 0 ),
+  m_expChBndFace(),
+  m_infaces(),
+  m_esupc(),
+  m_cbAfterDone( cbDone )
+// *****************************************************************************
+//  Constructor
+//! \param[in] disc Discretization proxy
+//! \param[in] bface Boundary-faces mapped to side set ids
+//! \param[in] triinpoel Boundary-face connectivity
+//! \param[in] nunk Number of unknowns
+//! \param[in] cbDone Function to continue with when Ghosts have been computed
+// *****************************************************************************
+{
+  if (g_inputdeck.get< tag::cmd, tag::chare >() ||
+      g_inputdeck.get< tag::cmd, tag::quiescence >())
+    stateProxy.ckLocalBranch()->insert( "Ghosts", thisIndex, CkMyPe(), Disc()->It(),
+                                        "Ghosts" );
+}
+
+void
+Ghosts::startCommSetup()
+// *****************************************************************************
+//  Start setup of communication maps for cell-centered schemes
+// *****************************************************************************
+{
+  // Ensure that mesh partition is not leaky
+  Assert( !tk::leakyPartition(m_fd.Esuel(), m_inpoel, m_coord),
+    "Input mesh to Ghosts leaky" );
+
+  // Ensure mesh physical boundary for the entire problem not leaky,
+  // effectively checking if the user has specified boundary conditions on all
+  // physical boundary faces
+  bndIntegral();
+}
+
+void
+Ghosts::bndIntegral()
+// *****************************************************************************
+//  Compute partial boundary surface integral and sum across all chares
+//! \details This function computes a partial surface integral over the boundary
+//!   of the faces of this mesh partition then sends its contribution to perform
+//!   the integral acorss the total problem boundary. After the global sum a
+//!   non-zero vector result indicates a leak, e.g., a hole in the boundary
+//!   which indicates an error in the boundary face data structures used to
+//!   compute the partial surface integrals.
+// *****************************************************************************
+{
+  // Storage for surface integral over our mesh chunk physical boundary
+  std::vector< tk::real > s{{ 0.0, 0.0, 0.0 }};
+
+  // Integrate over all physical boundary faces
+  for (std::size_t f=0; f<m_fd.Nbfac(); ++f) {
+    s[0] += m_geoFace(f,0) * m_geoFace(f,1);
+    s[1] += m_geoFace(f,0) * m_geoFace(f,2);
+    s[2] += m_geoFace(f,0) * m_geoFace(f,3);
+  }
+
+  s.push_back( 1.0 );  // positive: call-back to resizeComm() after reduction
+  s.push_back( static_cast< tk::real >( Disc()->MeshId() ) );
+
+  // Send contribution to host summing partial surface integrals
+  contribute( s, CkReduction::sum_double,
+    CkCallback(CkReductionTarget(Transporter,bndint), Disc()->Tr()) );
+}
+
+void
+Ghosts::resizeComm()
+// *****************************************************************************
+//  Start sizing communication buffers and setting up ghost data
+// *****************************************************************************
+{
+  // Enable SDAG wait for setting up chare boundary faces
+  thisProxy[ thisIndex ].wait4fac();
+
+  auto d = Disc();
+
+  const auto& gid = d->Gid();
+  const auto& inpofa = m_fd.Inpofa();
+  const auto& esuel = m_fd.Esuel();
+
+  // Perform leak test on mesh partition
+  Assert( !tk::leakyPartition( esuel, m_inpoel, m_coord ),
+          "Mesh partition leaky" );
+
+  // Activate SDAG waits for face adjacency map (ghost data) calculation
+  thisProxy[ thisIndex ].wait4ghost();
+  thisProxy[ thisIndex ].wait4esup();
+
+  // Invert inpofa to enable searching for faces based on (global) node triplets
+  Assert( inpofa.size() % 3 == 0, "Inpofa must contain triplets" );
+  for (std::size_t f=0; f<inpofa.size()/3; ++f)
+    m_ipface.insert( {{{ gid[ inpofa[f*3+0] ],
+                         gid[ inpofa[f*3+1] ],
+                         gid[ inpofa[f*3+2] ] }}} );
+
+  // At this point ipface has node-id-triplets (faces) on the internal
+  // chare-domain and on the physical boundary but not on chare boundaries,
+  // hence the name internal + physical boundary faces.
+
+  // Build a set of faces (each face given by 3 global node IDs) associated to
+  // chares we potentially share boundary faces with.
+  tk::UnsMesh::FaceSet potbndface;
+  for (std::size_t e=0; e<esuel.size()/4; ++e) {   // for all our tets
+    auto mark = e*4;
+    for (std::size_t f=0; f<4; ++f)     // for all tet faces
+      if (esuel[mark+f] == -1) {        // if face has no outside-neighbor tet
+        // if does not exist among the internal and physical boundary faces,
+        // store as a potential chare-boundary face
+        tk::UnsMesh::Face t{{ gid[ m_inpoel[ mark + tk::lpofa[f][0] ] ],
+                              gid[ m_inpoel[ mark + tk::lpofa[f][1] ] ],
+                              gid[ m_inpoel[ mark + tk::lpofa[f][2] ] ] }};
+        if (m_ipface.find(t) == end(m_ipface)) {
+          Assert( m_expChBndFace.insert(t).second,
+                  "Store expected chare-boundary face" );
+          potbndface.insert( t );
+        }
+      }
+  }
+
+  if ( g_inputdeck.get< tag::cmd, tag::feedback >() ) d->Tr().chbndface();
+
+  // In the following we assume that the size of the (potential) boundary-face
+  // adjacency map above does not necessarily equal to that of the node
+  // adjacency map. This is because while a node can be shared at a single
+  // corner or along an edge, that does not necessarily share a face as well
+  // (in other words, shared nodes or edges can exist that are not part of a
+  // shared face). So the chares we communicate with across faces are not
+  // necessarily the same as the chares we would communicate nodes with.
+  //
+  // Since the sizes of the node and face adjacency maps are not the same, while
+  // sending the faces on chare boundaries would be okay, however, the receiver
+  // would not necessarily know how many chares it must receive from. To solve
+  // this problem we send to chares which we share at least a single node with,
+  // i.e., rely on the node-adjacency map. Note that to all chares we share at
+  // least a single node with we send all our potential chare-boundary faces.
+  // This is the same list of faces to all chares we send.
+  //
+  // Another underlying assumption here is, of course, that the size of the face
+  // adjacency map is always smaller than or equal to that of the node adjacency
+  // map, which is always true. Since the receive side already knows how many
+  // fellow chares it must receive shared node ids from, we use that to detect
+  // completion of the number of receives in comfac(). This simplifies the
+  // communication pattern and code.
+
+  // Send sets of faces adjacent to chare boundaries to fellow workers (if any)
+  if (d->NodeCommMap().empty())  // in serial, skip setting up ghosts altogether
+    faceAdj();
+  else
+    // for all chares we share nodes with
+    for (const auto& c : d->NodeCommMap()) {
+      thisProxy[ c.first ].comfac( thisIndex, potbndface );
+    }
+
+  ownfac_complete();
+}
+
+void
+Ghosts::comfac( int fromch, const tk::UnsMesh::FaceSet& infaces )
+// *****************************************************************************
+//  Receive unique set of faces we potentially share with/from another chare
+//! \param[in] fromch Sender chare id
+//! \param[in] infaces Unique set of faces we potentially share with fromch
+// *****************************************************************************
+{
+  if (g_inputdeck.get< tag::cmd, tag::chare >() ||
+      g_inputdeck.get< tag::cmd, tag::quiescence >())
+    stateProxy.ckLocalBranch()->insert( "Ghosts", thisIndex, CkMyPe(), Disc()->It(),
+                                        "comfac" );
+
+  // Buffer up incoming data
+  m_infaces[ fromch ] = infaces;
+
+  // if we have heard from all fellow chares that we share at least a single
+  // node, edge, or face with
+  if (++m_ncomfac == Disc()->NodeCommMap().size()) {
+    m_ncomfac = 0;
+    comfac_complete();
+  }
+}
+
+void
+Ghosts::bndFaces()
+// *****************************************************************************
+// Compute chare-boundary faces
+//! \details This is called when both send and receives are completed on a
+//!  chare and thus we are ready to compute chare-boundary faces and ghost data.
+// *****************************************************************************
+{
+  auto d = Disc();
+  if ( g_inputdeck.get< tag::cmd, tag::feedback >() ) d->Tr().chcomfac();
+  const auto& esuel = m_fd.Esuel();
+  const auto& gid = d->Gid();
+
+  for (const auto& in : m_infaces) {
+    // Find sender chare among chares we potentially share faces with. Note that
+    // it is feasible that a sender chare called us but we do not have a set of
+    // faces associated to that chare. This can happen if we only share a single
+    // node or an edge but not a face with that chare.
+    auto& bndface = m_bndFace[ in.first ];  // will associate to sender chare
+    // Try to find incoming faces on our chare boundary with other chares. If
+    // found, generate and assign new local face ID, associated to sender chare.
+    for (std::size_t e=0; e<esuel.size()/4; ++e) {  // for all our tets
+      auto mark = e*4;
+      for (std::size_t f=0; f<4; ++f) {  // for all cell faces
+        if (esuel[mark+f] == -1) {  // if face has no outside-neighbor tet
+          tk::UnsMesh::Face t{{ gid[ m_inpoel[ mark + tk::lpofa[f][0] ] ],
+                                gid[ m_inpoel[ mark + tk::lpofa[f][1] ] ],
+                                gid[ m_inpoel[ mark + tk::lpofa[f][2] ] ] }};
+          // if found among the incoming faces and if not one of our internal
+          // nor physical boundary faces
+          if ( in.second.find(t) != end(in.second) &&
+               m_ipface.find(t) == end(m_ipface) ) {
+            bndface[t][0] = m_nfac++;    // assign new local face ID
+          }
+        }
+      }
+    }
+    // If at this point if we have not found any face among our faces we
+    // potentially share with fromch, there is no need to keep an empty set of
+    // faces associated to fromch as we only share nodes or edges with it, but
+    // not faces.
+    if (bndface.empty()) m_bndFace.erase( in.first );
+  }
+
+  tk::destroy(m_ipface);
+  tk::destroy(m_infaces);
+
+  // Ensure all expected faces have been received
+  Assert( receivedChBndFaces(),
+    "Expected and received chare boundary faces mismatch" );
+
+  // Basic error checking on chare-boundary-face map
+  Assert( m_bndFace.find( thisIndex ) == m_bndFace.cend(),
+          "Face-communication map should not contain data for own chare ID" );
+
+  // Store (local) tet ID adjacent to our chare boundary from the inside
+  for (std::size_t e=0; e<esuel.size()/4; ++e) {  // for all our tets
+    auto mark = e*4;
+    for (std::size_t f=0; f<4; ++f) {  // for all cell faces
+      if (esuel[mark+f] == -1) {  // if face has no outside-neighbor tet
+        tk::UnsMesh::Face t{{ gid[ m_inpoel[ mark + tk::lpofa[f][0] ] ],
+                              gid[ m_inpoel[ mark + tk::lpofa[f][1] ] ],
+                              gid[ m_inpoel[ mark + tk::lpofa[f][2] ] ] }};
+        auto c = findchare(t);
+        if (c > -1) {
+          auto& lbndface = tk::ref_find( m_bndFace, c );
+          auto& face = tk::ref_find( lbndface, t );
+          face[1] = e;  // store (local) inner tet ID adjacent to face
+        }
+      }
+    }
+  }
+
+  // At this point m_bndFace is complete on this PE. This means that starting
+  // from the sets of faces we potentially share with fellow chares we now
+  // only have those faces we actually share faces with (through which we need
+  // to communicate later). Also, m_bndFace not only has the unique faces
+  // associated to fellow chares, but also a newly assigned local face ID as
+  // well as the local id of the inner tet adjacent to the face. Continue by
+  // starting setting up ghost data
+  setupGhost();
+  // Besides setting up our own ghost data, we also issue requests (for ghost
+  // data) to those chares which we share faces with. Note that similar to
+  // comfac() we are calling reqGhost() by going through the node communication
+  // map instead, which may send requests to those chare we do not share faces
+  // with. This is so that we can test for completing by querying the size of
+  // the already complete node commincation map in reqGhost. Requests in
+  // sendGhost will only be fullfilled based on m_ghostData.
+  for (const auto& c : d->NodeCommMap())  // for all chares we share nodes with
+    thisProxy[ c.first ].reqGhost();
+}
+
+void
+Ghosts::setupGhost()
+// *****************************************************************************
+// Setup own ghost data on this chare
+// *****************************************************************************
+{
+  auto d = Disc();
+  const auto& gid = d->Gid();
+
+  // Enlarge elements surrounding faces data structure for ghosts
+  m_fd.Esuf().resize( 2*m_nfac, -2 );
+  m_fd.Inpofa().resize( 3*m_nfac, 0 );
+  // Enlarge face geometry data structure for ghosts
+  m_geoFace.resize( m_nfac, 0.0 );
+
+  const auto& esuel = m_fd.Esuel();
+
+  // Collect tet ids, their face connectivity (given by 3 global node IDs, each
+  // triplet for potentially multiple faces on the chare boundary), and their
+  // elem geometry data (see GhostData) associated to fellow chares adjacent to
+  // chare boundaries. Once received by fellow chares, these tets will become
+  // known as ghost elements and their data as ghost data.
+  for (std::size_t e=0; e<esuel.size()/4; ++e) {  // for all our tets
+    auto mark = e*4;
+    for (std::size_t f=0; f<4; ++f) {  // for all cell faces
+      if (esuel[mark+f] == -1) {  // if face has no outside-neighbor tet
+        tk::UnsMesh::Face t{{ gid[ m_inpoel[ mark + tk::lpofa[f][0] ] ],
+                              gid[ m_inpoel[ mark + tk::lpofa[f][1] ] ],
+                              gid[ m_inpoel[ mark + tk::lpofa[f][2] ] ] }};
+        auto c = findchare(t);
+        // It is possible that we do not find the chare for this face. We are
+        // looping through all of our tets and interrogating all faces that do
+        // not have neighboring tets but we only care about chare-boundary faces
+        // here as only those need ghost data. (esuel may also contain
+        // physical boundary faces)
+        if (c > -1) {
+          // Will store ghost data associated to neighbor chare
+          auto& ghost = m_ghostData[ c ];
+          // Store tet id adjacent to chare boundary as key for ghost data
+          auto& tuple = ghost[ e ];
+          // If tetid e has not yet been encountered, store geometry (only once)
+          auto& nodes = std::get< 0 >( tuple );
+          if (nodes.empty()) {
+            std::get< 1 >( tuple ) = m_geoElem[ e ];
+
+            auto& ncoord = std::get< 2 >( tuple );
+            ncoord[0] = m_coord[0][ m_inpoel[ mark+f ] ];
+            ncoord[1] = m_coord[1][ m_inpoel[ mark+f ] ];
+            ncoord[2] = m_coord[2][ m_inpoel[ mark+f ] ];
+
+            std::get< 3 >( tuple ) = f;
+
+            std::get< 4 >( tuple ) = {{ gid[ m_inpoel[ mark ] ],
+                                        gid[ m_inpoel[ mark+1 ] ],
+                                        gid[ m_inpoel[ mark+2 ] ],
+                                        gid[ m_inpoel[ mark+3 ] ] }};
+          }
+          // (Always) store face node IDs on chare boundary, even if tetid e has
+          // already been stored. Thus we store potentially multiple faces along
+          // the same chare-boundary. This happens, e.g., when the boundary
+          // between chares is zig-zaggy enough to have 2 or even 3 faces of the
+          // same tet.
+          nodes.push_back( t[0] );
+          nodes.push_back( t[1] );
+          nodes.push_back( t[2] );
+          Assert( nodes.size() <= 4*3, "Overflow of faces/tet to send" );
+        }
+      }
+    }
+  }
+
+  // Basic error checking on local ghost data
+  Assert( m_ghostData.find( thisIndex ) == m_ghostData.cend(),
+          "Chare-node adjacency map should not contain data for own chare ID" );
+
+  // More in-depth error checking on local ghost data
+  for (const auto& c : m_ghostData)
+    for ([[maybe_unused]] const auto& t : c.second) {
+      Assert( !std::get< 0 >( t.second ).empty(),
+              "Emtpy face vector in ghost data" );
+      Assert( std::get< 0 >( t.second ).size() % 3 == 0,
+              "Face node IDs must be triplets" );
+      Assert( std::get< 0 >( t.second ).size() <= 4*3,    // <= 4*3 (4*numfaces)
+              "Max number of faces for a single ghost tet is 4" );
+      Assert( !std::get< 1 >( t.second ).empty(),
+              "No elem geometry data for ghost" );
+      Assert( std::get< 1 >( t.second ).size() == m_geoElem.nprop(),
+              "Elem geometry data for ghost must be for single tet" );
+      Assert( !std::get< 2 >( t.second ).empty(),
+              "No nodal coordinate data for ghost" );
+    }
+
+  ownghost_complete();
+}
+
+void
+Ghosts::reqGhost()
+// *****************************************************************************
+// Receive requests for ghost data
+// *****************************************************************************
+{
+  if (g_inputdeck.get< tag::cmd, tag::chare >() ||
+      g_inputdeck.get< tag::cmd, tag::quiescence >())
+    stateProxy.ckLocalBranch()->insert( "Ghosts", thisIndex, CkMyPe(), Disc()->It(),
+                                        "reqGhost" );
+
+  // If every chare we communicate with has requested ghost data from us, we may
+  // fulfill the requests, but only if we have already setup our ghost data.
+  if (++m_ghostReq == Disc()->NodeCommMap().size()) {
+    m_ghostReq = 0;
+    reqghost_complete();
+  }
+}
+
+void
+Ghosts::sendGhost()
+// *****************************************************************************
+// Send all of our ghost data to fellow chares
+// *****************************************************************************
+{
+  if (g_inputdeck.get< tag::cmd, tag::chare >() ||
+      g_inputdeck.get< tag::cmd, tag::quiescence >())
+    stateProxy.ckLocalBranch()->insert( "Ghosts", thisIndex, CkMyPe(), Disc()->It(),
+                                        "sendGhost" );
+
+  for (const auto& c : m_ghostData)
+    thisProxy[ c.first ].comGhost( thisIndex, c.second );
+
+  if ( g_inputdeck.get< tag::cmd, tag::feedback >() ) Disc()->Tr().chghost();
+}
+
+void
+Ghosts::comGhost( int fromch, const GhostData& ghost )
+// *****************************************************************************
+// Receive ghost data on chare boundaries from fellow chare
+//! \param[in] fromch Caller chare ID
+//! \param[in] ghost Ghost data, see Inciter/FaceData.h for the type
+// *****************************************************************************
+{
+  if (g_inputdeck.get< tag::cmd, tag::chare >() ||
+      g_inputdeck.get< tag::cmd, tag::quiescence >())
+    stateProxy.ckLocalBranch()->insert( "Ghosts", thisIndex, CkMyPe(), Disc()->It(),
+                                        "comGhost" );
+
+  auto d = Disc();
+  const auto& lid = d->Lid();
+  auto& inpofa = m_fd.Inpofa();
+  auto ncoord = m_coord[0].size();<--- Variable 'ncoord' is assigned a value that is never used.
+
+  // nodelist with fromch, currently only used for an assert
+  [[maybe_unused]] const auto& nl = tk::cref_find( d->NodeCommMap(), fromch );
+
+  auto& ghostelem = m_ghost[ fromch ];  // will associate to sender chare
+
+  // Store ghost data coming from chare
+  for (const auto& g : ghost) {  // loop over incoming ghost data
+    auto e = g.first;  // remote/ghost tet id outside of chare boundary<--- Variable 'e' is assigned a value that is never used.
+    const auto& nodes = std::get< 0 >( g.second );  // node IDs of face(s)
+    const auto& geo = std::get< 1 >( g.second );    // ghost elem geometry data
+    const auto& coordg = std::get< 2 >( g.second );  // coordinate of ghost node
+    const auto& inpoelg = std::get< 4 >( g.second ); // inpoel of ghost tet
+
+    Assert( nodes.size() % 3 == 0, "Face node IDs must be triplets" );
+    Assert( nodes.size() <= 4*3, "Overflow of faces/tet received" );
+    Assert( geo.size() % 5 == 0, "Ghost geometry size mismatch" );
+    Assert( geo.size() == m_geoElem.nprop(), "Ghost geometry number mismatch" );
+    Assert( coordg.size() == 3, "Incorrect ghost node coordinate size" );
+    Assert( inpoelg.size() == 4, "Incorrect ghost inpoel size" );
+
+    for (std::size_t n=0; n<nodes.size()/3; ++n) {  // face(s) of ghost e
+      // node IDs of face on chare boundary
+      tk::UnsMesh::Face t{{ nodes[n*3+0], nodes[n*3+1], nodes[n*3+2] }};
+      // must find t in nodelist of chare-boundary adjacent to fromch
+      Assert( nl.find(t[0]) != end(nl) &&
+              nl.find(t[1]) != end(nl) &&
+              nl.find(t[2]) != end(nl),
+           "Ghost face not found in chare-node adjacency map on receiving end" );
+      // must find face in boundary-face adjacency map for fromch
+      Assert( tk::cref_find(m_bndFace,fromch).find( t ) !=
+              tk::cref_find(m_bndFace,fromch).cend(), "Ghost face not "
+              "found in boundary-face adjacency map on receiving end" );
+      // find local face & tet ids for t
+      auto id = tk::cref_find( tk::cref_find(m_bndFace,fromch), t );
+      // compute face geometry for chare-boundary face
+      addGeoFace(t, id);
+      // add node-triplet to node-face connectivity
+      inpofa[3*id[0]+0] = tk::cref_find( lid, t[2] );
+      inpofa[3*id[0]+1] = tk::cref_find( lid, t[1] );
+      inpofa[3*id[0]+2] = tk::cref_find( lid, t[0] );
+
+      // if ghost tet id not yet encountered on boundary with fromch
+      auto i = ghostelem.find( e );
+      if (i != end(ghostelem)) {
+        // fill in elements surrounding face
+        addEsuf(id, i->second);
+        // fill in elements surrounding element
+        addEsuel(id, i->second, t);
+      } else {
+        // fill in elements surrounding face
+        addEsuf(id, m_nunk);
+        // fill in elements surrounding element
+        addEsuel(id, m_nunk, t);
+        ghostelem[e] = m_nunk;     // assign new local tet id to remote ghost id
+        m_geoElem.push_back( geo );// store ghost elem geometry
+        ++m_nunk;                  // increase number of unknowns on this chare
+        std::size_t counter = 0;
+        for (std::size_t gp=0; gp<4; ++gp) {
+          auto it = lid.find( inpoelg[gp] );
+          std::size_t lp;
+          if (it != end(lid))
+            lp = it->second;
+          else {
+            Assert( nodes.size() == 3, "Expected node not found in lid" );
+            Assert( gp == std::get< 3 >( g.second ),
+                    "Ghost node not matching correct entry in ghost inpoel" );
+            lp = ncoord;
+            ++counter;
+          }
+          m_inpoel.push_back( lp );       // store ghost element connectivity
+        }
+        // only a single or no ghost node should be found
+        Assert( counter <= 1, "Incorrect number of ghost nodes detected. "
+                "Detected "+ std::to_string(counter) +" ghost nodes" );
+        if (counter == 1) {
+          m_coord[0].push_back( coordg[0] ); // store ghost node coordinate
+          m_coord[1].push_back( coordg[1] );
+          m_coord[2].push_back( coordg[2] );
+          Assert( m_inpoel[ 4*(m_nunk-1)+std::get< 3 >( g.second ) ] == ncoord,
+                  "Mismatch in extended inpoel for ghost element" );
+          ++ncoord;                // increase number of nodes on this chare<--- Variable 'ncoord' is assigned a value that is never used.
+        }
+      }
+
+      // additional tests to ensure that entries in inpoel and t/inpofa match
+      Assert( nodetripletMatch(id, t) == 3,
+        "Mismatch/Overmatch in inpoel and inpofa at chare-boundary face" );
+    }
+  }
+
+  // Signal the runtime system that all workers have received their
+  // face-adjacency
+  if (++m_nadj == m_ghostData.size()) faceAdj();
+}
+
+void
+Ghosts::faceAdj()
+// *****************************************************************************
+// Continue after face adjacency communication map completed on this chare
+//! \details At this point the face communication map has been established
+//!    on this chare. Proceed to set up the nodal-comm map.
+// *****************************************************************************
+{
+  m_nadj = 0;
+
+  tk::destroy(m_bndFace);
+
+  // Ensure that all elements surrounding faces (are correct) including those at
+  // chare boundaries
+  for (std::size_t f=0; f<m_nfac; ++f) {
+    Assert( m_fd.Esuf()[2*f] > -1,
+            "Left element in esuf cannot be physical ghost" );
+    if (f >= m_fd.Nbfac())
+      Assert( m_fd.Esuf()[2*f+1] > -1,
+           "Right element in esuf for internal/chare faces cannot be a ghost" );
+  }
+
+  // Ensure that all elements surrounding elements are correct including those
+  // at chare boundaries
+  const auto& esuel = m_fd.Esuel();
+  std::size_t nbound = 0;
+  for (std::size_t e=0; e<esuel.size()/4; ++e) {
+    for (std::size_t f=0; f<4; ++f)
+      if (esuel[4*e+f] == -1) ++nbound;
+  }
+  Assert( nbound == m_fd.Nbfac(), "Incorrect number of ghost-element -1's in "
+         "updated esuel" );
+
+  // Error checking on ghost data
+  for(const auto& n : m_ghostData)
+    for([[maybe_unused]] const auto& i : n.second)
+      Assert( i.first < m_fd.Esuel().size()/4, "Sender contains ghost tet id " );
+
+  // Perform leak test on face geometry data structure enlarged by ghosts
+  Assert( !leakyAdjacency(), "Face adjacency leaky" );
+  Assert( faceMatch(), "Chare-boundary element-face "
+    "connectivity (esuf) does not match" );
+
+  // Create new map of elements along chare boundary which are ghosts for
+  // neighboring chare, associated with that chare ID
+  for (const auto& [cid, cgd] : m_ghostData)
+  {
+    auto& sg = m_sendGhost[cid];
+    for (const auto& e : cgd)
+    {
+      Assert(sg.find(e.first) == sg.end(), "Repeating element found in "
+        "ghost data");
+      sg.insert(e.first);
+    }
+    Assert(sg.size() == cgd.size(), "Incorrect size for sendGhost");
+  }
+  Assert(m_sendGhost.size() == m_ghostData.size(), "Incorrect number of "
+    "chares in sendGhost");
+
+  // Error checking on ghost data
+  for(const auto& n : m_sendGhost)
+    for([[maybe_unused]] const auto& i : n.second)
+      Assert( i < m_fd.Esuel().size()/4, "Sender contains ghost tet id. " );
+
+  // Generate and store Esup data-structure in a map
+  auto esup = tk::genEsup(m_inpoel, 4);
+  for (std::size_t p=0; p<Disc()->Gid().size(); ++p)
+  {
+    for (auto e : tk::Around(esup, p))
+    {
+      // since inpoel has been augmented with the face-ghost cell previously,
+      // esup also contains cells which are not on this mesh-chunk, hence the
+      // following test
+      if (e < m_fd.Esuel().size()/4) m_esup[p].push_back(e);
+    }
+  }
+
+  // Error checking on Esup map
+  for(const auto& p : m_esup)
+    for([[maybe_unused]] const auto& e : p.second)
+      Assert( e < m_fd.Esuel().size()/4, "Esup contains tet id greater than "
+      + std::to_string(m_fd.Esuel().size()/4-1) +" : "+ std::to_string(e) );
+
+  auto meshid = Disc()->MeshId();
+  contribute( sizeof(std::size_t), &meshid, CkReduction::nop,
+    CkCallback(CkReductionTarget(Transporter,startEsup), Disc()->Tr()) );
+}
+
+void
+Ghosts::nodeNeighSetup()
+// *****************************************************************************
+// Setup node-neighborhood (esup)
+//! \details At this point the face-ghost communication map has been established
+//!    on this chare. This function begins generating the node-ghost comm map.
+// *****************************************************************************
+{
+  if (Disc()->NodeCommMap().empty())
+  // in serial, skip setting up node-neighborhood
+  { comesup_complete(); }
+  else
+  {
+    const auto& nodeCommMap = Disc()->NodeCommMap();
+
+    // send out node-neighborhood map
+    for (const auto& [cid, nlist] : nodeCommMap)
+    {
+      std::unordered_map< std::size_t, std::vector< std::size_t > > bndEsup;
+      std::unordered_map< std::size_t, std::vector< tk::real > > nodeBndCells;
+      for (const auto& p : nlist)
+      {
+        auto pl = tk::cref_find(Disc()->Lid(), p);
+        // fill in the esup for the chare-boundary
+        const auto& pesup = tk::cref_find(m_esup, pl);
+        bndEsup[p] = pesup;
+
+        // fill a map with the element ids from esup as keys and geoElem as
+        // values, and another map containing these elements associated with
+        // the chare id with which they are node-neighbors.
+        for (const auto& e : pesup)
+        {
+          nodeBndCells[e] = m_geoElem[e];
+
+          // add these esup-elements into map of elements along chare boundary
+          Assert( e < m_fd.Esuel().size()/4, "Sender contains ghost tet id." );
+          m_sendGhost[cid].insert(e);
+        }
+      }
+
+      thisProxy[cid].comEsup(thisIndex, bndEsup, nodeBndCells);
+    }
+  }
+
+  ownesup_complete();
+}
+
+void
+Ghosts::comEsup( int fromch,
+  const std::unordered_map< std::size_t, std::vector< std::size_t > >& bndEsup,
+  const std::unordered_map< std::size_t, std::vector< tk::real > >&
+    nodeBndCells )
+// *****************************************************************************
+//! \brief Receive elements-surrounding-points data-structure for points on
+//    common boundary between receiving and sending neighbor chare, and the
+//    element geometries for these new elements
+//! \param[in] fromch Sender chare id
+//! \param[in] bndEsup Elements-surrounding-points data-structure from fromch
+//! \param[in] nodeBndCells Map containing element geometries associated with
+//!   remote element IDs in the esup
+// *****************************************************************************
+{
+  auto& chghost = m_ghost[fromch];
+
+  // Extend remote-local element id map and element geometry array
+  for (const auto& e : nodeBndCells)
+  {
+    // need to check following, because 'e' could have been added previously in
+    // remote-local element id map as a part of face-communication, i.e. as a
+    // face-ghost element
+    if (chghost.find(e.first) == chghost.end())
+    {
+      chghost[e.first] = m_nunk;
+      m_geoElem.push_back(e.second);
+      ++m_nunk;
+    }
+  }
+
+  // Store incoming data in comm-map buffer for Esup
+  for (const auto& [node, elist] : bndEsup)
+  {
+    auto pl = tk::cref_find(Disc()->Lid(), node);
+    auto& pesup = m_esupc[pl];
+    for (auto e : elist)
+    {
+      auto el = tk::cref_find(chghost, e);
+      pesup.push_back(el);
+    }
+  }
+
+  // if we have heard from all fellow chares that we share at least a single
+  // node, edge, or face with
+  if (++m_ncomEsup == Disc()->NodeCommMap().size()) {
+    m_ncomEsup = 0;
+    comesup_complete();
+  }
+}
+
+void
+Ghosts::adj()
+// *****************************************************************************
+// Finish up with adjacency maps, and do a global-sync to begin problem setup
+//! \details At this point, the nodal- and face-adjacency has been set up. This
+//    function does some error checking on the nodal-adjacency and prepares
+//    for problem setup.
+// *****************************************************************************
+{
+  // combine own and communicated contributions to elements surrounding points
+  for (auto& [p, elist] : m_esupc)
+  {
+    auto& pesup = tk::ref_find(m_esup, p);
+    for ([[maybe_unused]] auto e : elist)
+    {
+      Assert( e >= m_fd.Esuel().size()/4, "Non-ghost element received from "
+        "esup buffer." );
+    }
+    tk::concat< std::size_t >(std::move(elist), pesup);
+  }
+
+  tk::destroy(m_ghostData);
+  tk::destroy(m_esupc);
+
+  if ( g_inputdeck.get< tag::cmd, tag::feedback >() ) Disc()->Tr().chadj();
+
+  // Error checking on ghost data
+  for(const auto& n : m_sendGhost)
+    for([[maybe_unused]] const auto& i : n.second)
+      Assert( i < m_fd.Esuel().size()/4, "Sender contains ghost tet id. ");
+
+  // Create a mapping between local ghost tet ids and zero-based boundary ids
+  std::vector< std::size_t > c( tk::sumvalsize( m_ghost ) );
+  std::size_t j = 0;
+  for (const auto& n : m_ghost) {
+    for(const auto& i : n.second) {
+      c[j++] = i.second;
+    }
+  }
+  m_bid = tk::assignLid( c );
+
+  // Basic error checking on ghost tet ID map
+  Assert( m_ghost.find( thisIndex ) == m_ghost.cend(),
+          "Ghost id map should not contain data for own chare ID" );
+
+  // Store expected ghost tet IDs
+  for (const auto& n : m_ghost)
+    for ([[maybe_unused]] const auto& g : n.second)
+      Assert( m_exptGhost.insert( g.second ).second,
+              "Failed to store local tetid as exptected ghost id" );
+
+  // Callback function from DG/FV after ghost-setup is done
+  m_cbAfterDone.send();
+}
+
+bool
+Ghosts::leakyAdjacency()
+// *****************************************************************************
+// Perform leak-test on chare boundary faces
+//! \details This function computes a surface integral over the boundary of the
+//!   faces after the face adjacency communication map is completed. A non-zero
+//!   vector result indicates a leak, e.g., a hole in the partition (covered by
+//!   the faces of the face adjacency communication map), which indicates an
+//!   error upstream in the code that sets up the face communication data
+//!   structures.
+//! \note Compared to tk::leakyPartition() this function performs the leak-test
+//!   on the face geometry data structure enlarged by ghost faces on this
+//!   partition by computing a discrete surface integral considering the
+//!   physical and chare boundary faces, which should be equal to zero for a
+//!   closed domain.
+//! \return True if our chare face adjacency leaks.
+// *****************************************************************************
+{
+  // Storage for surface integral over our chunk of the adjacency
+  std::array< tk::real, 3 > s{{ 0.0, 0.0, 0.0 }};
+
+  // physical boundary faces
+  for (std::size_t f=0; f<m_fd.Nbfac(); ++f) {
+    s[0] += m_geoFace(f,0) * m_geoFace(f,1);
+    s[1] += m_geoFace(f,0) * m_geoFace(f,2);
+    s[2] += m_geoFace(f,0) * m_geoFace(f,3);
+  }
+
+  // chare-boundary faces
+  for (std::size_t f=m_fd.Nipfac(); f<m_fd.Esuf().size()/2; ++f) {
+    s[0] += m_geoFace(f,0) * m_geoFace(f,1);
+    s[1] += m_geoFace(f,0) * m_geoFace(f,2);
+    s[2] += m_geoFace(f,0) * m_geoFace(f,3);
+  }
+
+  auto eps = std::numeric_limits< tk::real >::epsilon() * 100;
+  return std::abs(s[0]) > eps || std::abs(s[1]) > eps || std::abs(s[2]) > eps;
+}
+
+bool
+Ghosts::faceMatch()
+// *****************************************************************************
+// Check if esuf of chare-boundary faces matches
+//! \details This function checks each chare-boundary esuf entry for the left
+//!   and right elements. Then, it tries to match all vertices of these
+//!   elements. Exactly three of these vertices must match if the esuf entry
+//!   has been updated correctly at chare-boundaries.
+//! \return True if chare-boundary faces match.
+// *****************************************************************************
+{
+  const auto& esuf = m_fd.Esuf();
+  bool match(true);
+
+  auto eps = std::numeric_limits< tk::real >::epsilon() * 100;
+
+  for (auto f=m_fd.Nipfac(); f<esuf.size()/2; ++f)
+  {
+    std::size_t el = static_cast< std::size_t >(esuf[2*f]);
+    std::size_t er = static_cast< std::size_t >(esuf[2*f+1]);
+
+    std::size_t count = 0;
+
+    for (std::size_t i=0; i<4; ++i)
+    {
+      auto ip = m_inpoel[4*el+i];
+      for (std::size_t j=0; j<4; ++j)
+      {
+        auto jp = m_inpoel[4*er+j];
+        auto xdiff = std::abs( m_coord[0][ip] - m_coord[0][jp] );
+        auto ydiff = std::abs( m_coord[1][ip] - m_coord[1][jp] );
+        auto zdiff = std::abs( m_coord[2][ip] - m_coord[2][jp] );
+
+        if ( xdiff<=eps && ydiff<=eps && zdiff<=eps ) ++count;
+      }
+    }
+
+    match = (match && count == 3);
+  }
+
+  return match;
+}
+
+bool
+Ghosts::receivedChBndFaces()
+// *****************************************************************************
+// Verify that all chare-boundary faces have been received
+//! \return True if all chare-boundary faces have been received
+// *****************************************************************************
+{
+  const auto& lid = Disc()->Lid();
+  tk::UnsMesh::FaceSet recvBndFace;
+
+  // Collect chare-boundary faces that have been received and expected
+  for (const auto& c : m_bndFace)
+    for (const auto& f : c.second)
+      if (m_expChBndFace.find(f.first) != end(m_expChBndFace))
+        recvBndFace.insert(f.first);
+
+   // Collect info on expected but not received faces
+   std::stringstream msg;
+   for (const auto& f : m_expChBndFace)
+     if (recvBndFace.find(f) == end(recvBndFace)) {
+       const auto& x = m_coord[0];
+       const auto& y = m_coord[1];
+       const auto& z = m_coord[2];
+       auto A = tk::cref_find( lid, f[0] );
+       auto B = tk::cref_find( lid, f[1] );
+       auto C = tk::cref_find( lid, f[2] );
+       msg << '{' << A << ',' << B << ',' << C << "}:("
+           << x[A] << ',' << y[A] << ',' << z[A] << ' '
+           << x[B] << ',' << y[B] << ',' << z[B] << ' '
+           << x[C] << ',' << y[C] << ',' << z[C] << ") ";
+     }
+
+  tk::destroy( m_expChBndFace );
+
+  // Error out with info on missing faces
+  auto s = msg.str();
+  if (!s.empty()) {
+    Throw( "Ghosts chare " + std::to_string(thisIndex) +
+           " missing face(s) {local node ids} (node coords): " + s );
+  } else {
+    return true;
+  }
+}
+
+int
+Ghosts::findchare( const tk::UnsMesh::Face& t )
+// *****************************************************************************
+// Find any chare for face (given by 3 global node IDs)
+//! \param[in] t Face given by three global node IDs
+//! \return Chare ID if found among any of the chares we communicate along
+//!   faces with, -1 if the face cannot be found.
+// *****************************************************************************
+{
+  for (const auto& cf : m_bndFace)
+    // cppcheck-suppress useStlAlgorithm
+    if (cf.second.find(t) != end(cf.second))<--- Unmatched suppression: useStlAlgorithm
+      return cf.first;
+  return -1;
+}
+
+std::size_t
+Ghosts::nodetripletMatch(
+  const std::array< std::size_t, 2 >& id,
+  const tk::UnsMesh::Face& t )
+// *****************************************************************************
+// Check if entries in inpoel, inpofa and node-triplet are consistent
+//! \param[in] id Local face and (inner) tet id adjacent to it
+//! \param[in] t node-triplet associated with the chare boundary face
+//! \return number of nodes in inpoel that matched with t and inpofa
+// *****************************************************************************
+{
+  const auto& esuf = m_fd.Esuf();
+  const auto& inpofa = m_fd.Inpofa();
+  const auto& lid = Disc()->Lid();
+
+  std::size_t counter = 0;
+  for (std::size_t k=0; k<4; ++k)
+  {
+    auto el = esuf[ 2*id[0] ];
+    auto ip = m_inpoel[ 4*static_cast< std::size_t >( el )+k ];<--- Variable 'ip' is assigned a value that is never used.
+    Assert( el == static_cast< int >( id[1] ), "Mismatch in id and esuf" );
+    for (std::size_t j=0; j<3; ++j)
+    {
+      auto jp = tk::cref_find( lid, t[j] );
+      auto fp = inpofa[ 3*id[0]+(2-j) ];
+      if (ip == jp && ip == fp) ++counter;
+    }
+  }
+
+  return counter;
+}
+
+void
+Ghosts::addEsuf(
+  const std::array< std::size_t, 2 >& id,
+  std::size_t ghostid )
+// *****************************************************************************
+// Fill elements surrounding a face along chare boundary
+//! \param[in] id Local face and (inner) tet id adjacent to it
+//! \param[in] ghostid Local ID for ghost tet
+//! \details This function extends and fills in the elements surrounding faces
+//!   data structure (esuf) so that the left and right element id is filled
+//!   in correctly on chare boundaries to contain the correct inner tet id and
+//!   the local tet id for the outer (ghost) tet, both adjacent to the given
+//!   chare-face boundary. Prior to this function, this data structure does not
+//!   have yet face-element connectivity adjacent to chare-boundary faces, only
+//!   for physical boundaries and internal faces that are not on the chare
+//!   boundary (this latter purely as a result of mesh partitioning). The remote
+//!   element id of the ghost is stored in a location that is local to our own
+//!   esuf. The face numbering is such that esuf stores the element-face
+//!   connectivity first for the physical-boundary faces, followed by that of
+//!   the internal faces, followed by the chare-boundary faces. As a result,
+//!   esuf can be used by physics algorithms in exactly the same way as would be
+//!   used in serial. In serial, of course, this data structure is not extended
+//!   at the end by the chare-boundaries.
+// *****************************************************************************
+{
+  auto& esuf = m_fd.Esuf();
+
+  Assert( 2*id[0]+1 < esuf.size(), "Indexing out of esuf" );
+
+  // put in inner tet id
+  Assert( esuf[ 2*id[0] ] == -2 && esuf[ 2*id[0]+1 ] == -2, "Updating esuf at "
+          "wrong location instead of chare-boundary" );
+  esuf[ 2*id[0]+0 ] = static_cast< int >( id[1] );
+  // put in local id for outer/ghost tet
+  esuf[ 2*id[0]+1 ] = static_cast< int >( ghostid );
+}
+
+void
+Ghosts::addEsuel(
+  const std::array< std::size_t, 2 >& id,
+  std::size_t ghostid,
+  const tk::UnsMesh::Face& t )
+// *****************************************************************************
+// Fill elements surrounding a element along chare boundary
+//! \param[in] id Local face and (inner) tet id adjacent to it
+//! \param[in] ghostid Local ID for ghost tet
+//! \param[in] t node-triplet associated with the chare boundary face
+//! \details This function updates the elements surrounding element (esuel) data
+//    structure for the (inner) tets adjacent to the chare-boundaries. It fills
+//    esuel of this inner tet with the local tet-id that has been assigned to
+//    the outer ghost tet in Ghosts::comGhost in place of the -1 before.
+// *****************************************************************************
+{
+  const auto& lid = Disc()->Lid();
+  [[maybe_unused]] const auto& esuf = m_fd.Esuf();
+  auto& esuel = m_fd.Esuel();
+
+  std::array< tk::UnsMesh::Face, 4 > face;
+  for (std::size_t f = 0; f<4; ++f)
+    for (std::size_t i = 0; i<3; ++i)
+      face[f][i] = m_inpoel[ id[1]*4 + tk::lpofa[f][i] ];
+
+  tk::UnsMesh::Face tl{{ tk::cref_find( lid, t[0] ),
+                         tk::cref_find( lid, t[1] ),
+                         tk::cref_find( lid, t[2] ) }};
+
+  std::size_t i(0), nmatch(0);
+  for (const auto& f : face) {
+    if (tk::UnsMesh::Eq< 3 >()( tl, f )) {
+      Assert( esuel[ id[1]*4 + i ] == -1, "Incorrect boundary element found in "
+             "esuel");
+      esuel[ id[1]*4 + i ] = static_cast<int>(ghostid);
+      ++nmatch;<--- Variable 'nmatch' is assigned a value that is never used.
+      Assert( esuel[ id[1]*4 + i ] == esuf[ 2*id[0]+1 ], "Incorrect boundary "
+             "element entered in esuel" );
+      Assert( static_cast<int>(id[1]) == esuf[ 2*id[0]+0 ], "Boundary "
+             "element entered in incorrect esuel location" );
+    }
+    ++i;
+  }
+
+  // ensure that exactly one face matched
+  Assert( nmatch == 1, "Incorrect number of node-triplets (faces) matched for "
+         "updating esuel; matching faces = "+ std::to_string(nmatch) );
+}
+
+void
+Ghosts::addGeoFace(
+  const tk::UnsMesh::Face& t,
+  const std::array< std::size_t, 2 >& id )
+// *****************************************************************************
+// Fill face-geometry data along chare boundary
+//! \param[in] t Face (given by 3 global node IDs) on the chare boundary
+//! \param[in] id Local face and (inner) tet id adjacent to face t
+//! \details This function fills in the face geometry data along a chare
+//!    boundary.
+// *****************************************************************************
+{
+  const auto& lid = Disc()->Lid();
+
+  // get global node IDs reversing order to get outward-pointing normal
+  auto A = tk::cref_find( lid, t[2] );
+  auto B = tk::cref_find( lid, t[1] );
+  auto C = tk::cref_find( lid, t[0] );
+  auto geochf = tk::geoFaceTri( {{m_coord[0][A], m_coord[0][B], m_coord[0][C]}},
+                                {{m_coord[1][A], m_coord[1][B], m_coord[1][C]}},
+                                {{m_coord[2][A], m_coord[2][B], m_coord[2][C]}} );
+
+  for (std::size_t i=0; i<7; ++i)
+    m_geoFace(id[0],i) = geochf(0,i);
+}
+
+#include "NoWarning/ghosts.def.h"
 
diff --git a/Debug/cppcheck/42.html b/Debug/cppcheck/42.html index c373f0e466b9..483bf9d623cd 100644 --- a/Debug/cppcheck/42.html +++ b/Debug/cppcheck/42.html @@ -152,12 +152,12 @@
  1
@@ -356,309 +356,203 @@ 

Cppcheck report - [

// *****************************************************************************
+197
// *****************************************************************************
 /*!
-  \file      src/Inciter/Partitioner.hpp
+  \file      src/PDE/MultiMat/Problem/BoxInitialization.hpp
   \copyright 2012-2015 J. Bakosi,
              2016-2018 Los Alamos National Security, LLC.,
              2019-2021 Triad National Security, LLC.
              All rights reserved. See the LICENSE file for details.
-  \brief     Charm++ chare partitioner nodegroup used to perform mesh
-             partitioning
-  \details   Charm++ chare partitioner nodegroup used to perform mesh read and
-             partitioning, one worker per compute node.
-*/
-// *****************************************************************************
-#ifndef Partitioner_h
-#define Partitioner_h
-
-#include <array>
-#include <stddef.h>
-
-#include "ContainerUtil.hpp"
-#include "ZoltanInterOp.hpp"
-#include "Options/PartitioningAlgorithm.hpp"
-#include "DerivedData.hpp"
-#include "UnsMesh.hpp"
-#include "FaceData.hpp"
-#include "Sorter.hpp"
-#include "Refiner.hpp"
-#include "Callback.hpp"
-
-#include "NoWarning/partitioner.decl.h"
-
-namespace inciter {
-
-//! Partitioner Charm++ chare nodegroup class
-//! \details Instantiations of Partitioner comprise a processor aware Charm++
-//!   chare node group. When instantiated, a new object is created on each
-//!   compute node and not more (as opposed to individual chares or chare array
-//!   object elements). See also the Charm++ interface file partitioner.ci.
-class Partitioner : public CBase_Partitioner {
-
-  private:
-    //! \brief Mesh data used for categorizing mesh chunks assigned to chares
-    //!    after mesh partitioning and before mesh distribution across chares
-    using MeshData =
-      std::tuple<
-        // Tetrahedron (domain element) connectivity
-        std::vector< std::size_t >,
-        // Boundary face connectivity for each side set
-        std::unordered_map< int, std::vector< std::size_t > >,
-        // Boundary node lists for each side set
-        std::unordered_map< int, std::vector< std::size_t > >,
-        // Mesh block ids (value) associated to local tet ids (index)
-        std::vector< std::size_t > >;
-
-  public:
-    //! Constructor
-    Partitioner( std::size_t meshid,
-                 const std::string& filename,
-                 const tk::PartitionerCallback& cbp,
-                 const tk::RefinerCallback& cbr,
-                 const tk::SorterCallback& cbs,
-                 const CProxy_Transporter& host,
-                 const CProxy_Refiner& refiner,
-                 const CProxy_Sorter& sorter,
-                 const tk::CProxy_MeshWriter& meshwriter,
-                 const std::vector< Scheme >& scheme,
-                 const std::map< int, std::vector< std::size_t > >& bface,
-                 const std::map< int, std::vector< std::size_t > >& faces,
-                 const std::map< int, std::vector< std::size_t > >& bnode );
-
-    //! Destructor
-    ~Partitioner() override;
-
-    #if defined(__clang__)
-      #pragma clang diagnostic push
-      #pragma clang diagnostic ignored "-Wundefined-func-template"
-    #endif
-    //! Migrate constructor
-    explicit Partitioner( CkMigrateMessage* m ) : CBase_Partitioner( m ) {}<--- Member variable 'Partitioner::m_meshid' is not initialized in the constructor.<--- Member variable 'Partitioner::m_ndist' is not initialized in the constructor.<--- Member variable 'Partitioner::m_nchare' is not initialized in the constructor.
-    #if defined(__clang__)
-      #pragma clang diagnostic pop
-    #endif
-
-    //! Partition the computational mesh into a number of chares
-    void partition( int nchare );
-
-    //! Receive mesh associated to chares we own after refinement
-    void addMesh( int fromnode,
-                  const std::unordered_map< int,
-                    std::tuple<
-                      std::vector< std::size_t >,
-                      tk::UnsMesh::CoordMap,
-                      std::unordered_map< int, std::vector< std::size_t > >,
-                      std::unordered_map< int, std::vector< std::size_t > >,
-                      std::vector< std::size_t >
-                    > >& chmesh );
-
-    //! Acknowledge received mesh after initial mesh refinement
-    void recvMesh();
-
-    //! Optionally start refining the mesh
-    void refine();
-
-    /** @name Charm++ pack/unpack serializer member functions */
-    ///@{
-    //! \brief Pack/Unpack serialize member function
-    //! \param[in,out] p Charm++'s PUP::er serializer object reference
-    //! \note This is a Charm++ nodegroup, pup() is thus only for
-    //!    checkpoint/restart.
-    void pup( PUP::er &p ) override {
-      p | m_meshid;
-      p | m_cbp;
-      p | m_cbr;
-      p | m_cbs;
-      p | m_host;
-      p | m_refiner;
-      p | m_sorter;
-      p | m_meshwriter;
-      p | m_scheme;
-      p | m_ginpoel;
-      p | m_coord;
-      p | m_inpoel;
-      p | m_lid;
-      p | m_elemBlockId;
-      p | m_ndist;
-      p | m_nchare;
-      p | m_nface;
-      p | m_nodech;
-      p | m_linnodes;
-      p | m_chinpoel;
-      p | m_chcoordmap;
-      p | m_chbface;
-      p | m_chtriinpoel;
-      p | m_chbnode;
-      p | m_chelemblockid;
-      p | m_bnodechares;
-      p | m_bface;
-      p | m_triinpoel;
-      p | m_bnode;
-    }
-    //! \brief Pack/Unpack serialize operator|
-    //! \param[in,out] p Charm++'s PUP::er serializer object reference
-    //! \param[in,out] i Partitioner object reference
-    friend void operator|( PUP::er& p, Partitioner& i ) { i.pup(p); }
-    //@}
-
-  private:
-    //! Mesh ID
-    std::size_t m_meshid;
-    //! Charm++ callbacks associated to compile-time tags for partitioner
-    tk::PartitionerCallback m_cbp;
-    //! Charm++ callbacks associated to compile-time tags for refiner
-    tk::RefinerCallback m_cbr;
-    //! Charm++ callbacks associated to compile-time tags for sorter
-    tk::SorterCallback m_cbs;
-    //! Host proxy
-    CProxy_Transporter m_host;
-    //! Mesh refiner proxy
-    CProxy_Refiner m_refiner;
-    //! Mesh sorter proxy
-    CProxy_Sorter m_sorter;
-    //! Mesh writer proxy
-    tk::CProxy_MeshWriter m_meshwriter;
-    //! Discretization schemes (one per mesh)
-    std::vector< Scheme > m_scheme;
-    //! Element connectivity of this compute node's mesh chunk (global ids)
-    std::vector< std::size_t > m_ginpoel;
-    //! Coordinates of mesh nodes of this compute node's mesh chunk
-    tk::UnsMesh::Coords m_coord;
-    //! \brief Element connectivity with local node IDs of this compute node's
-    //!   mesh chunk
-    std::vector< std::size_t > m_inpoel;
-    //! Global->local node IDs of elements of this compute node's mesh chunk
-    //! \details Key: global node id, value: local node id
-    std::unordered_map< std::size_t, std::size_t > m_lid;
-    //! List of elements for each block-id.
-    //! \details key: block id, value: set of elements in corresponding block
-    std::unordered_map< std::size_t, std::set< std::size_t > > m_elemBlockId;
-    //! Counter during mesh distribution
-    std::size_t m_ndist;
-    //! Total number of chares across all compute nodes
-    int m_nchare;
-    //! Counters (for each chare owned) for assigning face ids in parallel
-    std::unordered_map< int, std::size_t > m_nface;
-    //! Chare IDs (value) associated to global mesh node IDs (key)
-    //! \details Multiple chares can contribute to a single node, hence vector
-    //!   for map value.
-    std::unordered_map< std::size_t, std::vector< int > > m_nodech;
-    //! \brief Map associating new node IDs (as in producing contiguous-row-id
-    //!   linear system contributions) as map-values to old node IDs (as in
-    //!   file) as map-keys
-    std::unordered_map< std::size_t, std::size_t > m_linnodes;
-    //! Mesh connectivity using global node IDs associated to chares owned
-    std::unordered_map< int, std::vector< std::size_t > > m_chinpoel;
-    //! Coordinates associated to global node IDs of our mesh chunk for chares
-    std::unordered_map< int, tk::UnsMesh::CoordMap > m_chcoordmap;
-    //! Side set id + boundary face id for each chare
-    std::unordered_map< int,
-      std::map< int, std::vector< std::size_t > > > m_chbface;
-    //! Boundary face connectivity for each chare
-    std::map< int, std::vector< std::size_t > > m_chtriinpoel;
-    //! Side set id + boundary nodes for each chare
-    std::unordered_map< int,
-      std::map< int, std::vector< std::size_t > > > m_chbnode;
-    //! Mesh block ids associated to local tet ids for each chare
-    //! \details outer key: chare id, vector index: tet id, value: block id of
-    //!   corresponding tet.
-    std::unordered_map< int, std::vector< std::size_t > > m_chelemblockid;
-    //! \brief Map associating a list of chare IDs to old (as in file) global
-    //!   mesh node IDs on the chare boundaries
-    //! \details Note that a single global mesh node ID can be associated to
-    //!   multiple chare IDs as multiple chares can contribute to a single node.
-    std::unordered_map< std::size_t, std::vector< int > > m_bnodechares;
-    //! Boundary face IDs associated associated to side set IDs
-    std::map< int, std::vector< std::size_t > > m_bface;
-    //! Boundary face-node connectivity
-    std::vector< std::size_t > m_triinpoel;
-    //! List of boundary nodes associated to side-set IDs
-    std::map< int, std::vector< std::size_t > > m_bnode;
-
-    //! Compute element centroid coordinates
-    std::array< std::vector< tk::real >, 3 >
-    centroids( const std::vector< std::size_t >& inpoel,
-               const tk::UnsMesh::Coords& coord );
-
-    //!  Categorize mesh elements (given by their gobal node IDs) by target
-    std::unordered_map< int, MeshData >
-    categorize( const std::vector< std::size_t >& che ) const;
-
-    //! Extract coordinates associated to global nodes of a mesh chunk
-    tk::UnsMesh::CoordMap coordmap( const std::vector< std::size_t >& inpoel );
-
-    //! Distribute mesh to target compute nodes after mesh partitioning
-    void distribute( std::unordered_map< int, MeshData >&& mesh );
-
-    //! Compute chare (partition) distribution across compute nodes
-    std::array< int, 2 > distribution( int npart ) const;
-
-    //! Return nodegroup id for chare id
-    int node( int id ) const;
-
-    //! Keep only those nodes for side sets that reside on this compute node
-    void ownBndNodes(
-      const std::unordered_map< std::size_t, std::size_t >& lid,
-      std::map< int, std::vector< std::size_t > >& bnode );
-};
-
-} // inciter::
-
-#endif // Partitioner_h
+  \brief     User-defined box initialization
+  \details   This file defines functions for initializing solutions for
+    compressible multi-material equations inside the user-defined box.
+*/
+// *****************************************************************************
+#ifndef MultiMatBoxInitialization_h
+#define MultiMatBoxInitialization_h
+
+#include "Fields.hpp"
+#include "EoS/EOS.hpp"
+#include "ContainerUtil.hpp"
+#include "MultiMat/MultiMatIndexing.hpp"
+
+namespace inciter {
+
+using ncomp_t = tk::ncomp_t;
+
+template< class B >
+void initializeBox( const std::vector< EOS >& mat_blk,
+                    tk::real V_ex,
+                    tk::real t,
+                    const B& b,
+                    tk::real bgpreic,
+                    tk::real bgtempic,
+                    std::vector< tk::real >& s )
+// *****************************************************************************
+// Set the solution in the user-defined IC box/mesh block
+//! \tparam B IC-block type to operate, ctr::box, or ctr::meshblock
+//! \param[in] V_ex Exact box volume
+//! \param[in] t Physical time
+//! \param[in] b IC box configuration to use
+//! \param[in] bgpreic Background pressure user input
+//! \param[in] bgtempic Background temperature user input
+//! \param[in,out] s Solution vector that is set to box ICs
+//! \details This function sets the fluid density and total specific energy
+//!   within a box initial condition, configured by the user. If the user
+//!   is specified a box where mass is specified, we also assume here that
+//!   internal energy content (energy per unit volume) is also
+//!   specified. Specific internal energy (energy per unit mass) is then
+//!   computed here (and added to the kinetic energy) from the internal
+//!   energy per unit volume by multiplying it with the total box volume
+//!   and dividing it by the total mass of the material in the box.
+//!   Example (SI) units of the quantities involved:
+//!    * internal energy content (energy per unit volume): J/m^3
+//!    * specific energy (internal energy per unit mass): J/kg
+// *****************************************************************************
+{
+  auto nmat = g_inputdeck.get< tag::multimat, tag::nmat >();
+
+  const auto& solidx = g_inputdeck.get< tag::matidxmap, tag::solidx >();
+
+  const auto& initiate = b.template get< tag::initiate >();
+
+  // get material id in box (offset by 1, since input deck uses 1-based ids)
+  std::size_t boxmatid = b.template get< tag::materialid >() - 1;
+  const auto& boxvel = b.template get< tag::velocity >();
+  auto boxpre = b.template get< tag::pressure >();
+  auto boxene = b.template get< tag::energy >();
+  auto boxtemp = b.template get< tag::temperature >();
+  auto boxmas = b.template get< tag::mass >();
+  auto boxenc = b.template get< tag::energy_content >();
+
+  auto alphamin = 1.0e-12;
+
+  // [I] Compute the states inside the IC box/block based on the type of user
+  // input.
+
+  // material volume fractions
+  for (std::size_t k=0; k<nmat; ++k) {
+    if (k == boxmatid) {
+      s[volfracIdx(nmat,k)] = 1.0 - (static_cast< tk::real >(nmat-1))*alphamin;
+    }
+    else {
+      s[volfracIdx(nmat,k)] = alphamin;
+    }
+  }
+  // material states (density, pressure, velocity)
+  tk::real u = 0.0, v = 0.0, w = 0.0, spi(0.0), pr(0.0), tmp(0.0), rbulk(0.0);
+  std::vector< tk::real > rhok(nmat, 0.0);
+  // 1. User-specified mass, specific energy (J/m^3) and volume of box
+  if (boxmas > 0.0) {
+    if (boxenc <= 1e-12) Throw( "Box energy content must be nonzero" );<--- If condition 'boxenc<=1e-12' is true, the function will return/exit
+    // determine density and energy of material in the box
+    rhok[boxmatid] = boxmas / V_ex;
+    spi = boxenc / rhok[boxmatid];
+
+    // Determine pressure and temperature
+    auto boxmat_vf = s[volfracIdx(nmat,boxmatid)];
+
+    // Since initiate type 'linear' assigns the background IC values to all
+    // nodes within a box at initialization (followed by adding a time-dependent
+    // energy source term representing a propagating wave-front), the pressure
+    // in the box needs to be set to background pressure.
+    if (initiate == ctr::InitiateType::LINEAR && t < 1e-12) {
+      if (boxmas <= 1e-12 || boxenc <= 1e-12 || bgpreic <= 1e-12 ||<--- Testing identical condition 'boxenc<=1e-12'
+        bgtempic <= 1e-12)
+        Throw("Box mass, energy content, background pressure and background "
+          "temperature must be specified for IC with linear propagating source");
+
+      pr = bgpreic;
+      auto te = mat_blk[boxmatid].compute< EOS::totalenergy >(
+        rhok[boxmatid], u, v, w, pr);
+      tmp = mat_blk[boxmatid].compute< EOS::temperature >(
+        boxmat_vf*rhok[boxmatid], u, v, w, boxmat_vf*te, boxmat_vf );
+
+      // if the above density and pressure lead to an invalid thermodynamic
+      // state (negative temperature/energy), change temperature to background
+      // temperature and use corresponding density.
+      if (tmp < 0.0 || te < 0.0) {
+        tmp = bgtempic;
+        rhok[boxmatid] = mat_blk[boxmatid].compute< EOS::density >(pr, tmp);
+        spi = boxenc / rhok[boxmatid];
+      }
+    }
+    // For initiate type 'impulse', pressure and temperature are determined from
+    // energy content that needs to be dumped into the box at IC.
+    else if (initiate == ctr::InitiateType::IMPULSE) {
+      pr = mat_blk[boxmatid].compute< EOS::pressure >(
+        boxmat_vf*rhok[boxmatid], u, v, w, boxmat_vf*rhok[boxmatid]*spi,
+        boxmat_vf, boxmatid );
+      tmp = mat_blk[boxmatid].compute< EOS::temperature >(
+        boxmat_vf*rhok[boxmatid], u, v, w, boxmat_vf*rhok[boxmatid]*spi,
+        boxmat_vf );
+    }
+    else Throw( "IC box initiate type not implemented for multimat" );
+
+    // find density of trace material quantities in the box based on pressure
+    for (std::size_t k=0; k<nmat; ++k) {
+      if (k != boxmatid) {
+        rhok[k] = mat_blk[k].compute< EOS::density >(pr, tmp);
+      }
+    }
+  }
+  // 2. User-specified temperature, pressure and velocity in box
+  else {
+    for (std::size_t k=0; k<nmat; ++k) {
+      rhok[k] = mat_blk[k].compute< EOS::density >(boxpre, boxtemp);
+    }
+    if (boxvel.size() == 3) {
+      u = boxvel[0];
+      v = boxvel[1];
+      w = boxvel[2];
+    }
+    if (boxpre > 0.0) {
+      pr = boxpre;
+    }
+    if (boxene > 0.0) {
+      Throw("IC-box with specified energy not set up for multimat");
+    }
+  }
+  // bulk density
+  for (std::size_t k=0; k<nmat; ++k) rbulk += s[volfracIdx(nmat,k)]*rhok[k];
+
+  // [II] Finally initialize the solution vector
+  for (std::size_t k=0; k<nmat; ++k) {
+    // partial density
+    s[densityIdx(nmat,k)] = s[volfracIdx(nmat,k)] * rhok[k];
+    // total specific energy
+    if (boxmas > 0.0 && k == boxmatid &&
+      initiate == ctr::InitiateType::IMPULSE) {
+      s[energyIdx(nmat,k)] = s[volfracIdx(nmat,k)] * rhok[k] * spi;
+    }
+    else {
+      // TEMP: Eventually we would need to initialize gk from control file
+      std::array< std::array< tk::real, 3 >, 3 > gk;
+      if (solidx[k] > 0) {
+        for (std::size_t i=0; i<3; ++i) {
+          for (std::size_t j=0; j<3; ++j) {
+            if (i==j) gk[i][j] = 1.0;
+            else gk[i][j] = 0.0;
+            s[deformIdx(nmat,solidx[k],i,j)] = gk[i][j];
+          }
+        }
+      }
+      else {
+        gk = {{}};
+      }
+      s[energyIdx(nmat,k)] = s[volfracIdx(nmat,k)] *
+        mat_blk[k].compute< EOS::totalenergy >( rhok[k], u, v, w, pr, gk );
+    }
+  }
+  // bulk momentum
+  s[momentumIdx(nmat,0)] = rbulk * u;
+  s[momentumIdx(nmat,1)] = rbulk * v;
+  s[momentumIdx(nmat,2)] = rbulk * w;
+}
+
+} //inciter::
+
+#endif // MultiMatBoxInitialization_h
 
diff --git a/Debug/cppcheck/43.html b/Debug/cppcheck/43.html index 04c06877650a..a1a3230050bf 100644 --- a/Debug/cppcheck/43.html +++ b/Debug/cppcheck/43.html @@ -152,12 +152,12 @@
   1
@@ -1645,210 +1645,84 @@ 

Cppcheck report - [

// *****************************************************************************
+1486
// *****************************************************************************
 /*!
-  \file      src/Inciter/ALECG.cpp
+  \file      src/Inciter/OversetFE.cpp
   \copyright 2012-2015 J. Bakosi,
              2016-2018 Los Alamos National Security, LLC.,
              2019-2021 Triad National Security, LLC.
              All rights reserved. See the LICENSE file for details.
-  \brief     ALECG for a PDE system with continuous Galerkin + ALE + RK
-  \details   ALECG advances a system of partial differential equations (PDEs)
+  \brief     OversetFE for a PDE system with continuous Galerkin FE + RK
+  \details   OversetFE advances a system of partial differential equations
     using a continuous Galerkin (CG) finite element (FE) spatial discretization
     (using linear shapefunctions on tetrahedron elements) combined with a
-    Runge-Kutta (RK) time stepping scheme in the arbitrary Eulerian-Lagrangian
-    reference frame.
-  \see The documentation in ALECG.hpp.
-*/
-// *****************************************************************************
-
-#include "QuinoaBuildConfig.hpp"
-#include "ALECG.hpp"
-#include "Vector.hpp"
-#include "Reader.hpp"
-#include "ContainerUtil.hpp"
-#include "UnsMesh.hpp"
-#include "ExodusIIMeshWriter.hpp"
-#include "Inciter/InputDeck/InputDeck.hpp"
-#include "DerivedData.hpp"
-#include "CGPDE.hpp"
-#include "Discretization.hpp"
-#include "DiagReducer.hpp"
-#include "NodeBC.hpp"
-#include "Refiner.hpp"
-#include "Reorder.hpp"
-#include "Around.hpp"
-#include "CGPDE.hpp"
-#include "Integrate/Mass.hpp"
-#include "FieldOutput.hpp"
+    Runge-Kutta (RK) time stepping scheme and overset grids.
+  \see The documentation in OversetFE.hpp.
+*/
+// *****************************************************************************
+
+#include "QuinoaBuildConfig.hpp"
+#include "OversetFE.hpp"
+#include "Vector.hpp"
+#include "Reader.hpp"
+#include "ContainerUtil.hpp"
+#include "UnsMesh.hpp"
+#include "ExodusIIMeshWriter.hpp"
+#include "Inciter/InputDeck/InputDeck.hpp"
+#include "DerivedData.hpp"
+#include "CGPDE.hpp"
+#include "Discretization.hpp"
+#include "DiagReducer.hpp"
+#include "NodeBC.hpp"
+#include "Refiner.hpp"
+#include "Reorder.hpp"
+#include "Around.hpp"
+#include "CGPDE.hpp"
+#include "FieldOutput.hpp"
+
+namespace inciter {
 
-namespace inciter {
-
-extern ctr::InputDeck g_inputdeck;
-extern std::vector< CGPDE > g_cgpde;
-
-//! Runge-Kutta coefficients
-static const std::array< tk::real, 3 > rkcoef{{ 1.0/3.0, 1.0/2.0, 1.0 }};
+extern ctr::InputDeck g_inputdeck;
+extern std::vector< CGPDE > g_cgpde;
+
+//! Runge-Kutta coefficients
+static const std::array< tk::real, 3 > rkcoef{{ 1.0/3.0, 1.0/2.0, 1.0 }};
+
+} // inciter::
 
-} // inciter::
+using inciter::OversetFE;
 
-using inciter::ALECG;
-
-ALECG::ALECG( const CProxy_Discretization& disc,
-              const CProxy_Ghosts&,
-              const std::map< int, std::vector< std::size_t > >& bface,
-              const std::map< int, std::vector< std::size_t > >& bnode,
-              const std::vector< std::size_t >& triinpoel ) :
-  m_disc( disc ),
-  m_nsol( 0 ),
-  m_ngrad( 0 ),
-  m_nrhs( 0 ),
-  m_nbnorm( 0 ),
-  m_ndfnorm( 0 ),
-  m_nmblk( 0 ),
-  m_bnode( bnode ),
-  m_bface( bface ),
-  m_triinpoel( tk::remap( triinpoel, Disc()->Lid() ) ),
-  m_bndel( Disc()->bndel() ),
-  m_dfnorm(),
-  m_dfnormc(),
-  m_dfn(),
-  m_esup( tk::genEsup( Disc()->Inpoel(), 4 ) ),
-  m_psup( tk::genPsup( Disc()->Inpoel(), 4, m_esup ) ),
-  m_u( Disc()->Gid().size(),
-       g_inputdeck.get< tag::ncomp >() ),
-  m_un( m_u.nunk(), m_u.nprop() ),
-  m_rhs( m_u.nunk(), m_u.nprop() ),
-  m_rhsc(),
-  m_chBndGrad( Disc()->Bid().size(), m_u.nprop()*3 ),
-  m_dirbc(),
-  m_chBndGradc(),
+OversetFE::OversetFE( const CProxy_Discretization& disc,
+              const CProxy_Ghosts&,
+              const std::map< int, std::vector< std::size_t > >& bface,
+              const std::map< int, std::vector< std::size_t > >& bnode,
+              const std::vector< std::size_t >& triinpoel ) :
+  m_disc( disc ),
+  m_nsol( 0 ),
+  m_ngrad( 0 ),
+  m_nrhs( 0 ),
+  m_nbnorm( 0 ),
+  m_ndfnorm( 0 ),
+  m_nmblk( 0 ),
+  m_bnode( bnode ),
+  m_bface( bface ),
+  m_triinpoel( tk::remap( triinpoel, Disc()->Lid() ) ),
+  m_bndel( Disc()->bndel() ),
+  m_dfnorm(),
+  m_dfnormc(),
+  m_dfn(),
+  m_esup( tk::genEsup( Disc()->Inpoel(), 4 ) ),
+  m_psup( tk::genPsup( Disc()->Inpoel(), 4, m_esup ) ),
+  m_u( Disc()->Gid().size(),
+       g_inputdeck.get< tag::ncomp >() ),
+  m_uc( m_u.nunk(), m_u.nprop()+1 ),
+  m_un( m_u.nunk(), m_u.nprop() ),
+  m_rhs( m_u.nunk(), m_u.nprop() ),
+  m_rhsc(),
+  m_chBndGrad( Disc()->Bid().size(), m_u.nprop()*3 ),
+  m_dirbc(),
+  m_chBndGradc(),
+  m_blank( m_u.nunk(), 1.0 ),
   m_diag(),
   m_bnorm(),
   m_bnormc(),
@@ -1864,11 +1738,11 @@ 

Cppcheck report - [ m_dtp( m_u.nunk(), 0.0 ), m_tp( m_u.nunk(), g_inputdeck.get< tag::t0 >() ), m_finished( 0 ), - m_newmesh( 0 ), - m_refinedmesh( 0 ), - m_nusermeshblk( 0 ), - m_nodeblockid(), - m_nodeblockidc() + m_movedmesh( 0 ), + m_nusermeshblk( 0 ), + m_nodeblockid(), + m_nodeblockidc(), + m_ixfer(0) // ***************************************************************************** // Constructor //! \param[in] disc Discretization proxy @@ -1909,1480 +1783,1354 @@

Cppcheck report - [ } // Query/update boundary-conditions-related data structures from user input - queryBnd(); + getBCNodes(); // Activate SDAG wait for initially computing normals, and mesh blocks thisProxy[ thisIndex ].wait4norm(); thisProxy[ thisIndex ].wait4meshblk(); - d->comfinal(); - -} -//! [Constructor] + // Determine user-specified mesh velocity + const auto& uservelvec = + g_inputdeck.get< tag::mesh >()[d->MeshId()].get< tag::velocity >(); + m_uservel = {uservelvec[0], uservelvec[1], uservelvec[2]}; -void -ALECG::queryBnd() -// ***************************************************************************** -// Query/update boundary-conditions-related data structures from user input -// ***************************************************************************** -{ - auto d = Disc(); - - // Query and match user-specified Dirichlet boundary conditions to side sets - const auto steady = g_inputdeck.get< tag::steady_state >(); - if (steady) for (auto& deltat : m_dtp) deltat *= rkcoef[m_stage];<--- Consider using std::transform algorithm instead of a raw loop. - m_dirbc = match( d->MeshId(), m_u.nprop(), d->T(), rkcoef[m_stage] * d->Dt(), - m_tp, m_dtp, d->Coord(), d->Lid(), m_bnode, - /* increment = */ false ); - if (steady) for (auto& deltat : m_dtp) deltat /= rkcoef[m_stage];<--- Consider using std::transform algorithm instead of a raw loop. - - // Prepare unique set of symmetry BC nodes - auto sym = d->bcnodes< tag::symmetry >( m_bface, m_triinpoel ); - for (const auto& [s,nodes] : sym) - m_symbcnodes.insert( begin(nodes), end(nodes) ); - - // Prepare unique set of farfield BC nodes - auto far = d->bcnodes< tag::farfield >( m_bface, m_triinpoel ); - for (const auto& [s,nodes] : far) - m_farfieldbcnodes.insert( begin(nodes), end(nodes) ); - - // If farfield BC is set on a node, will not also set symmetry BC - for (auto fn : m_farfieldbcnodes) m_symbcnodes.erase(fn); - - // Prepare boundary nodes contiguously accessible from a triangle-face loop - m_symbctri.resize( m_triinpoel.size()/3, 0 ); - for (std::size_t e=0; e<m_triinpoel.size()/3; ++e) - if (m_symbcnodes.find(m_triinpoel[e*3+0]) != end(m_symbcnodes)) - m_symbctri[e] = 1; - - // Prepare unique set of time dependent BC nodes - m_timedepbcnodes.clear(); - m_timedepbcFn.clear(); - const auto& timedep = - g_inputdeck.get< tag::bc >()[d->MeshId()].get< tag::timedep >(); - if (!timedep.empty()) { - m_timedepbcnodes.resize(timedep.size()); - m_timedepbcFn.resize(timedep.size()); - std::size_t ib=0; - for (const auto& bndry : timedep) { - std::unordered_set< std::size_t > nodes; - for (const auto& s : bndry.template get< tag::sideset >()) { - auto k = m_bnode.find(static_cast<int>(s)); - if (k != end(m_bnode)) { - for (auto g : k->second) { // global node ids on side set - nodes.insert( tk::cref_find(d->Lid(),g) ); - } - } - } - m_timedepbcnodes[ib].insert( begin(nodes), end(nodes) ); - - // Store user defined discrete function in time. This is done in the same - // loop as the BC nodes, so that the indices for the two vectors - // m_timedepbcnodes and m_timedepbcFn are consistent with each other - auto fn = bndry.template get< tag::fn >(); - for (std::size_t ir=0; ir<fn.size()/6; ++ir) { - m_timedepbcFn[ib].push_back({{ fn[ir*6+0], fn[ir*6+1], fn[ir*6+2], - fn[ir*6+3], fn[ir*6+4], fn[ir*6+5] }}); - } - ++ib; - } - } - - Assert(m_timedepbcFn.size() == m_timedepbcnodes.size(), "Incorrect number of " - "time dependent functions."); - - // Query ALE mesh velocity boundary condition node lists and node lists at - // which ALE moves boundaries - d->meshvelBnd( m_bface, m_bnode, m_triinpoel ); -} - -void -ALECG::norm() -// ***************************************************************************** -// Start (re-)computing boundary point-, and dual-face normals -// ***************************************************************************** -{ - auto d = Disc(); + if (g_inputdeck.get< tag::steady_state >() && + std::sqrt(tk::dot(m_uservel, m_uservel)) > 1e-8) + Throw("Mesh motion cannot be activated for steady state problem"); + + d->comfinal(); + +} +//! [Constructor] + +void +OversetFE::getBCNodes() +// ***************************************************************************** +// Query/update boundary-conditions-related data structures from user input +// ***************************************************************************** +{ + auto d = Disc(); + + // Prepare unique set of symmetry BC nodes + auto sym = d->bcnodes< tag::symmetry >( m_bface, m_triinpoel ); + for (const auto& [s,nodes] : sym) + m_symbcnodes.insert( begin(nodes), end(nodes) ); + + // Prepare unique set of farfield BC nodes + auto far = d->bcnodes< tag::farfield >( m_bface, m_triinpoel ); + for (const auto& [s,nodes] : far) + m_farfieldbcnodes.insert( begin(nodes), end(nodes) ); + + // If farfield BC is set on a node, will not also set symmetry BC + for (auto fn : m_farfieldbcnodes) m_symbcnodes.erase(fn); + + // Prepare boundary nodes contiguously accessible from a triangle-face loop + m_symbctri.resize( m_triinpoel.size()/3, 0 ); + for (std::size_t e=0; e<m_triinpoel.size()/3; ++e) + if (m_symbcnodes.find(m_triinpoel[e*3+0]) != end(m_symbcnodes)) + m_symbctri[e] = 1; + + // Prepare unique set of time dependent BC nodes + m_timedepbcnodes.clear(); + m_timedepbcFn.clear(); + const auto& timedep = + g_inputdeck.get< tag::bc >()[d->MeshId()].get< tag::timedep >(); + if (!timedep.empty()) { + m_timedepbcnodes.resize(timedep.size()); + m_timedepbcFn.resize(timedep.size()); + std::size_t ib=0; + for (const auto& bndry : timedep) { + std::unordered_set< std::size_t > nodes; + for (const auto& s : bndry.template get< tag::sideset >()) { + auto k = m_bnode.find(static_cast<int>(s)); + if (k != end(m_bnode)) { + for (auto g : k->second) { // global node ids on side set + nodes.insert( tk::cref_find(d->Lid(),g) ); + } + } + } + m_timedepbcnodes[ib].insert( begin(nodes), end(nodes) ); + + // Store user defined discrete function in time. This is done in the same + // loop as the BC nodes, so that the indices for the two vectors + // m_timedepbcnodes and m_timedepbcFn are consistent with each other + auto fn = bndry.template get< tag::fn >(); + for (std::size_t ir=0; ir<fn.size()/6; ++ir) { + m_timedepbcFn[ib].push_back({{ fn[ir*6+0], fn[ir*6+1], fn[ir*6+2], + fn[ir*6+3], fn[ir*6+4], fn[ir*6+5] }}); + } + ++ib; + } + } + + Assert(m_timedepbcFn.size() == m_timedepbcnodes.size(), "Incorrect number of " + "time dependent functions."); +} + +void +OversetFE::norm() +// ***************************************************************************** +// Start (re-)computing boundary point-, and dual-face normals +// ***************************************************************************** +{ + auto d = Disc(); + + // Query nodes at which symmetry BCs are specified + auto bn = d->bcnodes< tag::symmetry >( m_bface, m_triinpoel ); - // Query nodes at which symmetry BCs are specified - auto bn = d->bcnodes< tag::symmetry >( m_bface, m_triinpoel ); - - // Query nodes at which farfield BCs are specified - auto far = d->bcnodes< tag::farfield >( m_bface, m_triinpoel ); - // Merge BC data where boundary-point normals are required - for (const auto& [s,n] : far) bn[s].insert( begin(n), end(n) ); - - // Query nodes at which mesh velocity symmetry BCs are specified - std::unordered_map<int, std::unordered_set< std::size_t >> ms; - for (const auto& s : g_inputdeck.get< tag::ale, tag::symmetry >()) { - auto k = m_bface.find(static_cast<int>(s)); - if (k != end(m_bface)) { - auto& n = ms[ k->first ]; - for (auto f : k->second) { - n.insert( m_triinpoel[f*3+0] ); - n.insert( m_triinpoel[f*3+1] ); - n.insert( m_triinpoel[f*3+2] ); - } - } - } - // Merge BC data where boundary-point normals are required - for (const auto& [s,n] : ms) bn[s].insert( begin(n), end(n) ); + // Query nodes at which farfield BCs are specified + auto far = d->bcnodes< tag::farfield >( m_bface, m_triinpoel ); + // Merge BC data where boundary-point normals are required + for (const auto& [s,n] : far) bn[s].insert( begin(n), end(n) ); + + // Query nodes at which mesh velocity symmetry BCs are specified + std::unordered_map<int, std::unordered_set< std::size_t >> ms; + for (const auto& s : g_inputdeck.get< tag::ale, tag::symmetry >()) { + auto k = m_bface.find(static_cast<int>(s)); + if (k != end(m_bface)) { + auto& n = ms[ k->first ]; + for (auto f : k->second) { + n.insert( m_triinpoel[f*3+0] ); + n.insert( m_triinpoel[f*3+1] ); + n.insert( m_triinpoel[f*3+2] ); + } + } + } + // Merge BC data where boundary-point normals are required + for (const auto& [s,n] : ms) bn[s].insert( begin(n), end(n) ); + + // Compute boundary point normals + bnorm( bn ); - // Compute boundary point normals - bnorm( bn ); - - // Compute dual-face normals associated to edges - dfnorm(); -} - -std::array< tk::real, 3 > -ALECG::edfnorm( const tk::UnsMesh::Edge& edge, - const std::unordered_map< tk::UnsMesh::Edge, - std::vector< std::size_t >, - tk::UnsMesh::Hash<2>, tk::UnsMesh::Eq<2> >& esued ) -const -// ***************************************************************************** -// Compute normal of dual-mesh associated to edge -//! \param[in] edge Edge whose dual-face normal to compute given by local ids -//! \param[in] esued Elements surrounding edges -//! \return Dual-face normal for edge -// ***************************************************************************** -{ - auto d = Disc(); - const auto& inpoel = d->Inpoel(); - const auto& coord = d->Coord(); - const auto& x = coord[0]; - const auto& y = coord[1]; - const auto& z = coord[2]; - - std::array< tk::real, 3 > n{ 0.0, 0.0, 0.0 }; - - for (auto e : tk::cref_find(esued,edge)) { - // access node IDs - const std::array< std::size_t, 4 > - N{ inpoel[e*4+0], inpoel[e*4+1], inpoel[e*4+2], inpoel[e*4+3] }; - // compute element Jacobi determinant - const std::array< tk::real, 3 > - ba{{ x[N[1]]-x[N[0]], y[N[1]]-y[N[0]], z[N[1]]-z[N[0]] }}, - ca{{ x[N[2]]-x[N[0]], y[N[2]]-y[N[0]], z[N[2]]-z[N[0]] }}, - da{{ x[N[3]]-x[N[0]], y[N[3]]-y[N[0]], z[N[3]]-z[N[0]] }}; - const auto J = tk::triple( ba, ca, da ); // J = 6V - Assert( J > 0, "Element Jacobian non-positive" ); - // shape function derivatives, nnode*ndim [4][3] - std::array< std::array< tk::real, 3 >, 4 > grad; - grad[1] = tk::crossdiv( ca, da, J ); - grad[2] = tk::crossdiv( da, ba, J ); - grad[3] = tk::crossdiv( ba, ca, J ); - for (std::size_t i=0; i<3; ++i) - grad[0][i] = -grad[1][i]-grad[2][i]-grad[3][i]; - // sum normal contributions - // The constant 1/48: Eq (12) from Waltz et al. Computers & fluids (92) 2014 - // The result of the integral of shape function N on a tet is V/4. - // This can be written as J/(6*4). Eq (12) has a 1/2 multiplier. - // This leads to J/48. - auto J48 = J/48.0; - for (const auto& [a,b] : tk::lpoed) { - auto s = tk::orient( {N[a],N[b]}, edge ); - for (std::size_t j=0; j<3; ++j) - n[j] += J48 * s * (grad[a][j] - grad[b][j]); - } - } + // Compute dual-face normals associated to edges + dfnorm(); +} + +std::array< tk::real, 3 > +OversetFE::edfnorm( const tk::UnsMesh::Edge& edge, + const std::unordered_map< tk::UnsMesh::Edge, + std::vector< std::size_t >, + tk::UnsMesh::Hash<2>, tk::UnsMesh::Eq<2> >& esued ) +const +// ***************************************************************************** +// Compute normal of dual-mesh associated to edge +//! \param[in] edge Edge whose dual-face normal to compute given by local ids +//! \param[in] esued Elements surrounding edges +//! \return Dual-face normal for edge +// ***************************************************************************** +{ + auto d = Disc(); + const auto& inpoel = d->Inpoel(); + const auto& coord = d->Coord(); + const auto& x = coord[0]; + const auto& y = coord[1]; + const auto& z = coord[2]; + + std::array< tk::real, 3 > n{ 0.0, 0.0, 0.0 }; + + for (auto e : tk::cref_find(esued,edge)) { + // access node IDs + const std::array< std::size_t, 4 > + N{ inpoel[e*4+0], inpoel[e*4+1], inpoel[e*4+2], inpoel[e*4+3] }; + // compute element Jacobi determinant + const std::array< tk::real, 3 > + ba{{ x[N[1]]-x[N[0]], y[N[1]]-y[N[0]], z[N[1]]-z[N[0]] }}, + ca{{ x[N[2]]-x[N[0]], y[N[2]]-y[N[0]], z[N[2]]-z[N[0]] }}, + da{{ x[N[3]]-x[N[0]], y[N[3]]-y[N[0]], z[N[3]]-z[N[0]] }}; + const auto J = tk::triple( ba, ca, da ); // J = 6V + Assert( J > 0, "Element Jacobian non-positive" ); + // shape function derivatives, nnode*ndim [4][3] + std::array< std::array< tk::real, 3 >, 4 > grad; + grad[1] = tk::crossdiv( ca, da, J ); + grad[2] = tk::crossdiv( da, ba, J ); + grad[3] = tk::crossdiv( ba, ca, J ); + for (std::size_t i=0; i<3; ++i) + grad[0][i] = -grad[1][i]-grad[2][i]-grad[3][i]; + // sum normal contributions + // The constant 1/48: Eq (12) from Waltz et al. Computers & fluids (92) 2014 + // The result of the integral of shape function N on a tet is V/4. + // This can be written as J/(6*4). Eq (12) has a 1/2 multiplier. + // This leads to J/48. + auto J48 = J/48.0; + for (const auto& [a,b] : tk::lpoed) { + auto s = tk::orient( {N[a],N[b]}, edge ); + for (std::size_t j=0; j<3; ++j) + n[j] += J48 * s * (grad[a][j] - grad[b][j]); + } + } + + return n; +} - return n; -} - -void -ALECG::dfnorm() -// ***************************************************************************** -// Compute dual-face normals associated to edges -// ***************************************************************************** -{ - auto d = Disc(); - const auto& inpoel = d->Inpoel(); - const auto& gid = d->Gid(); +void +OversetFE::dfnorm() +// ***************************************************************************** +// Compute dual-face normals associated to edges +// ***************************************************************************** +{ + auto d = Disc(); + const auto& inpoel = d->Inpoel(); + const auto& gid = d->Gid(); + + // compute derived data structures + auto esued = tk::genEsued( inpoel, 4, tk::genEsup( inpoel, 4 ) ); - // compute derived data structures - auto esued = tk::genEsued( inpoel, 4, tk::genEsup( inpoel, 4 ) ); - - // Compute dual-face normals for domain edges - for (std::size_t p=0; p<gid.size(); ++p) // for each point p - for (auto q : tk::Around(m_psup,p)) // for each edge p-q - if (gid[p] < gid[q]) - m_dfnorm[{gid[p],gid[q]}] = edfnorm( {p,q}, esued ); - - // Send our dual-face normal contributions to neighbor chares - if (d->EdgeCommMap().empty()) - comdfnorm_complete(); - else { - for (const auto& [c,edges] : d->EdgeCommMap()) { - decltype(m_dfnorm) exp; - for (const auto& e : edges) exp[e] = tk::cref_find(m_dfnorm,e); - thisProxy[c].comdfnorm( exp ); - } - } + // Compute dual-face normals for domain edges + for (std::size_t p=0; p<gid.size(); ++p) // for each point p + for (auto q : tk::Around(m_psup,p)) // for each edge p-q + if (gid[p] < gid[q]) + m_dfnorm[{gid[p],gid[q]}] = edfnorm( {p,q}, esued ); + + // Send our dual-face normal contributions to neighbor chares + if (d->EdgeCommMap().empty()) + comdfnorm_complete(); + else { + for (const auto& [c,edges] : d->EdgeCommMap()) { + decltype(m_dfnorm) exp; + for (const auto& e : edges) exp[e] = tk::cref_find(m_dfnorm,e); + thisProxy[c].comdfnorm( exp ); + } + } + + owndfnorm_complete(); +} - owndfnorm_complete(); -} - -void -ALECG::comdfnorm( const std::unordered_map< tk::UnsMesh::Edge, - std::array< tk::real, 3 >, - tk::UnsMesh::Hash<2>, tk::UnsMesh::Eq<2> >& dfnorm ) -// ***************************************************************************** -// Receive contributions to dual-face normals on chare-boundaries -//! \param[in] dfnorm Incoming partial sums of dual-face normals associated to -//! chare-boundary edges -// ***************************************************************************** -{ - // Buffer up inccoming contributions to dual-face normals - for (const auto& [e,n] : dfnorm) { - auto& dfn = m_dfnormc[e]; - dfn[0] += n[0]; - dfn[1] += n[1]; - dfn[2] += n[2]; - } - - if (++m_ndfnorm == Disc()->EdgeCommMap().size()) { - m_ndfnorm = 0; - comdfnorm_complete(); - } -} - -void -ALECG::bnorm( const std::unordered_map< int, - std::unordered_set< std::size_t > >& bcnodes ) -// ***************************************************************************** -// Compute boundary point normals -//! \param[in] bcnodes Local node ids associated to side set ids at which BCs -//! are set that require normals -//***************************************************************************** -{ - auto d = Disc(); - - m_bnorm = cg::bnorm( m_bface, m_triinpoel, d->Coord(), d->Gid(), bcnodes ); - - // Send our nodal normal contributions to neighbor chares - if (d->NodeCommMap().empty()) - comnorm_complete(); - else - for (const auto& [ neighborchare, sharednodes ] : d->NodeCommMap()) { - std::unordered_map< int, - std::unordered_map< std::size_t, std::array< tk::real, 4 > > > exp; - for (auto i : sharednodes) { - for (const auto& [s,norms] : m_bnorm) { - auto j = norms.find(i); - if (j != end(norms)) exp[s][i] = j->second; - } - } - thisProxy[ neighborchare ].comnorm( exp ); - } +void +OversetFE::comdfnorm( const std::unordered_map< tk::UnsMesh::Edge, + std::array< tk::real, 3 >, + tk::UnsMesh::Hash<2>, tk::UnsMesh::Eq<2> >& dfnorm ) +// ***************************************************************************** +// Receive contributions to dual-face normals on chare-boundaries +//! \param[in] dfnorm Incoming partial sums of dual-face normals associated to +//! chare-boundary edges +// ***************************************************************************** +{ + // Buffer up inccoming contributions to dual-face normals + for (const auto& [e,n] : dfnorm) { + auto& dfn = m_dfnormc[e]; + dfn[0] += n[0]; + dfn[1] += n[1]; + dfn[2] += n[2]; + } + + if (++m_ndfnorm == Disc()->EdgeCommMap().size()) { + m_ndfnorm = 0; + comdfnorm_complete(); + } +} + +void +OversetFE::bnorm( const std::unordered_map< int, + std::unordered_set< std::size_t > >& bcnodes ) +// ***************************************************************************** +// Compute boundary point normals +//! \param[in] bcnodes Local node ids associated to side set ids at which BCs +//! are set that require normals +//***************************************************************************** +{ + auto d = Disc(); + + m_bnorm = cg::bnorm( m_bface, m_triinpoel, d->Coord(), d->Gid(), bcnodes ); + + // Send our nodal normal contributions to neighbor chares + if (d->NodeCommMap().empty()) + comnorm_complete(); + else + for (const auto& [ neighborchare, sharednodes ] : d->NodeCommMap()) { + std::unordered_map< int, + std::unordered_map< std::size_t, std::array< tk::real, 4 > > > exp; + for (auto i : sharednodes) { + for (const auto& [s,norms] : m_bnorm) { + auto j = norms.find(i); + if (j != end(norms)) exp[s][i] = j->second; + } + } + thisProxy[ neighborchare ].comnorm( exp ); + } + + ownnorm_complete(); +} - ownnorm_complete(); -} - -void -ALECG::comnorm( const std::unordered_map< int, - std::unordered_map< std::size_t, std::array< tk::real, 4 > > >& innorm ) -// ***************************************************************************** -// Receive boundary point normals on chare-boundaries -//! \param[in] innorm Incoming partial sums of boundary point normal -//! contributions to normals (first 3 components), inverse distance squared -//! (4th component), associated to side set ids -// ***************************************************************************** -{ - // Buffer up incoming boundary-point normal vector contributions - for (const auto& [s,norms] : innorm) { - auto& bnorms = m_bnormc[s]; - for (const auto& [p,n] : norms) { - auto& bnorm = bnorms[p]; - bnorm[0] += n[0]; - bnorm[1] += n[1]; - bnorm[2] += n[2]; - bnorm[3] += n[3]; - } - } - - if (++m_nbnorm == Disc()->NodeCommMap().size()) { - m_nbnorm = 0; - comnorm_complete(); - } -} - -void -ALECG::registerReducers() -// ***************************************************************************** -// Configure Charm++ reduction types initiated from this chare array -//! \details Since this is a [initnode] routine, the runtime system executes the -//! routine exactly once on every logical node early on in the Charm++ init -//! sequence. Must be static as it is called without an object. See also: -//! Section "Initializations at Program Startup" at in the Charm++ manual -//! http://charm.cs.illinois.edu/manuals/html/charm++/manual.html. -// ***************************************************************************** -{ - NodeDiagnostics::registerReducers(); -} - -void -ALECG::ResumeFromSync() -// ***************************************************************************** -// Return from migration -//! \details This is called when load balancing (LB) completes. The presence of -//! this function does not affect whether or not we block on LB. -// ***************************************************************************** -{ - if (Disc()->It() == 0) Throw( "it = 0 in ResumeFromSync()" ); +void +OversetFE::comnorm( const std::unordered_map< int, + std::unordered_map< std::size_t, std::array< tk::real, 4 > > >& innorm ) +// ***************************************************************************** +// Receive boundary point normals on chare-boundaries +//! \param[in] innorm Incoming partial sums of boundary point normal +//! contributions to normals (first 3 components), inverse distance squared +//! (4th component), associated to side set ids +// ***************************************************************************** +{ + // Buffer up incoming boundary-point normal vector contributions + for (const auto& [s,norms] : innorm) { + auto& bnorms = m_bnormc[s]; + for (const auto& [p,n] : norms) { + auto& bnorm = bnorms[p]; + bnorm[0] += n[0]; + bnorm[1] += n[1]; + bnorm[2] += n[2]; + bnorm[3] += n[3]; + } + } + + if (++m_nbnorm == Disc()->NodeCommMap().size()) { + m_nbnorm = 0; + comnorm_complete(); + } +} + +void +OversetFE::registerReducers() +// ***************************************************************************** +// Configure Charm++ reduction types initiated from this chare array +//! \details Since this is a [initnode] routine, the runtime system executes the +//! routine exactly once on every logical node early on in the Charm++ init +//! sequence. Must be static as it is called without an object. See also: +//! Section "Initializations at Program Startup" at in the Charm++ manual +//! http://charm.cs.illinois.edu/manuals/html/charm++/manual.html. +// ***************************************************************************** +{ + NodeDiagnostics::registerReducers(); +} + +void +OversetFE::ResumeFromSync() +// ***************************************************************************** +// Return from migration +//! \details This is called when load balancing (LB) completes. The presence of +//! this function does not affect whether or not we block on LB. +// ***************************************************************************** +{ + if (Disc()->It() == 0) Throw( "it = 0 in ResumeFromSync()" ); + + if (!g_inputdeck.get< tag::cmd, tag::nonblocking >()) next(); +} - if (!g_inputdeck.get< tag::cmd, tag::nonblocking >()) next(); -} - -//! [setup] -void -ALECG::setup() -// ***************************************************************************** -// Start setup for solution -// ***************************************************************************** -{ - auto d = Disc(); - - // Determine nodes inside user-defined IC box - g_cgpde[d->MeshId()].IcBoxNodes( d->Coord(), d->Inpoel(), - d->ElemBlockId(), m_boxnodes, m_nodeblockid, m_nusermeshblk ); - - // Communicate mesh block nodes to other chares on chare-boundary - if (d->NodeCommMap().empty()) // in serial we are done - comblk_complete(); - else // send mesh block information to chare-boundary nodes to fellow chares - for (const auto& [c,n] : d->NodeCommMap()) { - // data structure assigning block ids (set of values) to nodes (index). - // although nodeblockid is a map with key-blockid and value-nodeid, the - // sending data structure has to be inverted, because of how communication - // data is handled. - std::vector< std::set< std::size_t > > mb( n.size() ); - std::size_t j = 0; - for (auto i : n) { - for (const auto& [blid, ndset] : m_nodeblockid) { - // if node was found in a block, add to send-data - if (ndset.find(tk::cref_find(d->Lid(),i)) != ndset.end()) - mb[j].insert(blid); - } - if (m_nusermeshblk > 0) - Assert(mb[j].size() > 0, "Sending no block data for node"); - ++j; - } - thisProxy[c].comblk( std::vector<std::size_t>(begin(n),end(n)), mb ); - } +//! [setup] +void +OversetFE::setup() +// ***************************************************************************** +// Start setup for solution +// ***************************************************************************** +{ + auto d = Disc(); + + // Determine nodes inside user-defined IC box + g_cgpde[d->MeshId()].IcBoxNodes( d->Coord(), d->Inpoel(), + d->ElemBlockId(), m_boxnodes, m_nodeblockid, m_nusermeshblk ); + + // Communicate mesh block nodes to other chares on chare-boundary + if (d->NodeCommMap().empty()) // in serial we are done + comblk_complete(); + else // send mesh block information to chare-boundary nodes to fellow chares + for (const auto& [c,n] : d->NodeCommMap()) { + // data structure assigning block ids (set of values) to nodes (index). + // although nodeblockid is a map with key-blockid and value-nodeid, the + // sending data structure has to be inverted, because of how communication + // data is handled. + std::vector< std::set< std::size_t > > mb( n.size() ); + std::size_t j = 0; + for (auto i : n) { + for (const auto& [blid, ndset] : m_nodeblockid) { + // if node was found in a block, add to send-data + if (ndset.find(tk::cref_find(d->Lid(),i)) != ndset.end()) + mb[j].insert(blid); + } + if (m_nusermeshblk > 0) + Assert(mb[j].size() > 0, "Sending no block data for node"); + ++j; + } + thisProxy[c].comblk( std::vector<std::size_t>(begin(n),end(n)), mb ); + } + + ownblk_complete(); +} - ownblk_complete(); -} - -void -ALECG::comblk( const std::vector< std::size_t >& gid, - const std::vector< std::set< std::size_t > >& mb ) -// ***************************************************************************** -// Receive mesh block information for nodes on chare-boundaries -//! \param[in] gid Global mesh node IDs at which we receive RHS contributions -//! \param[in] mb Block ids for each node on chare-boundaries -//! \details This function receives mesh block information for nodes on chare -//! boundaries. While m_nodeblockid stores block information for own nodes, -//! m_nodeblockidc collects the neighbor chare information during -//! communication. This way work on m_nodeblockid and m_nodeblockidc is -//! overlapped. The two are combined in continueSetup(). -// ***************************************************************************** -{ - Assert( mb.size() == gid.size(), "Size mismatch" ); - - for (std::size_t i=0; i<gid.size(); ++i) { - for (const auto& blid : mb[i]) { - m_nodeblockidc[blid].insert(gid[i]); - } - } - - // When we have heard from all chares we communicate with, this chare is done - if (++m_nmblk == Disc()->NodeCommMap().size()) { - m_nmblk = 0; - comblk_complete(); - } -} - -void -ALECG::continueSetup() -// ***************************************************************************** -// Continue setup for solution, after communication for mesh blocks -// ***************************************************************************** -{ - auto d = Disc(); - - // Combine own and communicated mesh block information - for (const auto& [blid, ndset] : m_nodeblockidc) { - for (const auto& i : ndset) { - auto lid = tk::cref_find(d->Lid(), i); - m_nodeblockid[blid].insert(lid); - } - } +void +OversetFE::comblk( const std::vector< std::size_t >& gid, + const std::vector< std::set< std::size_t > >& mb ) +// ***************************************************************************** +// Receive mesh block information for nodes on chare-boundaries +//! \param[in] gid Global mesh node IDs at which we receive RHS contributions +//! \param[in] mb Block ids for each node on chare-boundaries +//! \details This function receives mesh block information for nodes on chare +//! boundaries. While m_nodeblockid stores block information for own nodes, +//! m_nodeblockidc collects the neighbor chare information during +//! communication. This way work on m_nodeblockid and m_nodeblockidc is +//! overlapped. The two are combined in continueSetup(). +// ***************************************************************************** +{ + Assert( mb.size() == gid.size(), "Size mismatch" ); + + for (std::size_t i=0; i<gid.size(); ++i) { + for (const auto& blid : mb[i]) { + m_nodeblockidc[blid].insert(gid[i]); + } + } + + // When we have heard from all chares we communicate with, this chare is done + if (++m_nmblk == Disc()->NodeCommMap().size()) { + m_nmblk = 0; + comblk_complete(); + } +} + +void +OversetFE::continueSetup() +// ***************************************************************************** +// Continue setup for solution, after communication for mesh blocks +// ***************************************************************************** +{ + auto d = Disc(); + + // Combine own and communicated mesh block information + for (const auto& [blid, ndset] : m_nodeblockidc) { + for (const auto& i : ndset) { + auto lid = tk::cref_find(d->Lid(), i); + m_nodeblockid[blid].insert(lid); + } + } + + // clear receive buffer + tk::destroy(m_nodeblockidc); - // clear receive buffer - tk::destroy(m_nodeblockidc); + // Compute volume of user-defined box IC + d->boxvol( m_boxnodes, m_nodeblockid, m_nusermeshblk ); - // Compute volume of user-defined box IC - d->boxvol( m_boxnodes, m_nodeblockid, m_nusermeshblk ); - - // Query time history field output labels from all PDEs integrated - const auto& hist_points = g_inputdeck.get< tag::history_output, tag::point >(); - if (!hist_points.empty()) { - std::vector< std::string > histnames; - auto n = g_cgpde[d->MeshId()].histNames(); - histnames.insert( end(histnames), begin(n), end(n) ); - d->histheader( std::move(histnames) ); - } -} -//! [setup] - -void -ALECG::volumetric( tk::Fields& u, const std::vector< tk::real >& v ) -// ***************************************************************************** -// Multiply solution with mesh volume -//! \param[in,out] u Solution vector -//! \param[in] v Volume to multiply with -// ***************************************************************************** -{ - Assert( v.size() == u.nunk(), "Size mismatch" ); - - for (std::size_t i=0; i<u.nunk(); ++i) - for (ncomp_t c=0; c<u.nprop(); ++c) - u(i,c) *= v[i]; -} - -void -ALECG::conserved( tk::Fields& u, const std::vector< tk::real >& v ) -// ***************************************************************************** -// Divide solution with mesh volume -//! \param[in,out] u Solution vector -//! \param[in] v Volume to divide with -// ***************************************************************************** -{ - Assert( v.size() == u.nunk(), "Size mismatch" ); - - for (std::size_t i=0; i<u.nunk(); ++i) - for (ncomp_t c=0; c<u.nprop(); ++c) { - u(i,c) /= v[i]; - } -} - -void -ALECG::box( tk::real v, const std::vector< tk::real >& blkvols ) -// ***************************************************************************** -// Receive total box IC volume and set conditions in box -//! \param[in] v Total volume within user-specified box -//! \param[in] blkvols Vector of mesh block discrete volumes with user ICs -// ***************************************************************************** -{ - Assert(blkvols.size() == m_nusermeshblk, - "Incorrect size of block volume vector"); - auto d = Disc(); - - // Store user-defined box/block IC volume - d->Boxvol() = v; - d->MeshBlkVol() = blkvols; - - // Set initial conditions for all PDEs - g_cgpde[d->MeshId()].initialize( d->Coord(), m_u, d->T(), d->Boxvol(), - m_boxnodes, d->MeshBlkVol(), m_nodeblockid ); - - // Multiply conserved variables with mesh volume - volumetric( m_u, Disc()->Vol() ); + // Query time history field output labels from all PDEs integrated + const auto& hist_points = g_inputdeck.get< tag::history_output, tag::point >(); + if (!hist_points.empty()) { + std::vector< std::string > histnames; + auto n = g_cgpde[d->MeshId()].histNames(); + histnames.insert( end(histnames), begin(n), end(n) ); + d->histheader( std::move(histnames) ); + } +} +//! [setup] + +void +OversetFE::box( tk::real v, const std::vector< tk::real >& blkvols ) +// ***************************************************************************** +// Receive total box IC volume and set conditions in box +//! \param[in] v Total volume within user-specified box +//! \param[in] blkvols Vector of mesh block discrete volumes with user ICs +// ***************************************************************************** +{ + Assert(blkvols.size() == m_nusermeshblk, + "Incorrect size of block volume vector"); + auto d = Disc(); + + // Store user-defined box/block IC volume + d->Boxvol() = v; + d->MeshBlkVol() = blkvols; + + // Set initial conditions for all PDEs + g_cgpde[d->MeshId()].initialize( d->Coord(), m_u, d->T(), d->Boxvol(), + m_boxnodes, d->MeshBlkVol(), m_nodeblockid ); + + // Initialize nodal mesh volumes at previous time step stage + d->Voln() = d->Vol(); + + // Initiate solution transfer (if coupled) + transferSol(); +} + +void +OversetFE::transferSol() +// ***************************************************************************** +// Transfer solution to other solver and mesh if coupled +// ***************************************************************************** +{ + // Set up transfer-flags for receiving mesh + if (m_ixfer == 1) { + applySolTransfer(0); + } + setTransferFlags(m_ixfer); + ++m_ixfer; + + // Initiate IC transfer (if coupled) + Disc()->transfer( m_uc, m_ixfer-1, + CkCallback(CkIndex_OversetFE::lhs(), thisProxy[thisIndex]) ); +} + +//! [Compute lhs] +void +OversetFE::lhs() +// ***************************************************************************** +// Compute the left-hand side of transport equations +//! \details Also (re-)compute all data structures if the mesh changed. +// ***************************************************************************** +{ + // Do corrections in solution based on incoming transfer + applySolTransfer(1); + m_ixfer = 0; - // Initialize nodal mesh volumes at previous time step stage - d->Voln() = d->Vol(); - - // Start computing the mesh mesh velocity for ALE - meshvelstart(); -} - -void -ALECG::meshvelstart() -// ***************************************************************************** -// Start computing the mesh mesh velocity for ALE -// ***************************************************************************** -{ - auto d = Disc(); - - // Apply boundary conditions on numerical solution - BC(); - - conserved( m_u, d->Vol() ); + // No need for LHS in OversetFE + + // If mesh moved: (Re-)compute boundary point- and dual-face normals, and + // then proceed to stage() + // If mesh did not move: shortcut to stage() + if (m_movedmesh || Disc()->Initial()) norm(); + else stage(); +} +//! [Compute lhs] + +//! [Merge normals and continue] +void +OversetFE::mergelhs() +// ***************************************************************************** +// The own and communication portion of the left-hand side is complete +// ***************************************************************************** +{ + // Combine own and communicated contributions of normals + normfinal(); - // query fluid velocity across all systems integrated - tk::UnsMesh::Coords vel; - g_cgpde[d->MeshId()].velocity( m_u, vel ); - // query speed of sound in mesh nodes across all systems integrated - std::vector< tk::real > soundspeed; - g_cgpde[d->MeshId()].soundspeed( m_u, soundspeed ); - - volumetric( m_u, d->Vol() ); + // Start with time stepping logic + if (Disc()->Initial()) { + // Output initial conditions to file and then start time stepping + writeFields( CkCallback(CkIndex_OversetFE::start(), thisProxy[thisIndex]) ); + } + else stage(); +} +//! [Merge normals and continue] - // Start computing the mesh mesh velocity for ALE - d->meshvelStart( vel, soundspeed, m_bnorm, rkcoef[m_stage] * d->Dt(), - CkCallback(CkIndex_ALECG::meshveldone(), thisProxy[thisIndex]) ); -} - -void -ALECG::meshveldone() -// ***************************************************************************** -// Done with computing the mesh velocity for ALE -// ***************************************************************************** -{ - // Assess and record mesh velocity linear solver conergence - Disc()->meshvelConv(); - - // Continue - if (Disc()->Initial()) { - - conserved( m_u, Disc()->Vol() ); - - // Initiate IC transfer (if coupled) - Disc()->transfer( m_u, 0, - CkCallback(CkIndex_ALECG::transfer_complete(), thisProxy[thisIndex]) ); - - lhs(); - - } else { - - ale(); - - } -} - -//! [start] -void -ALECG::start() -// ***************************************************************************** -// Start time stepping -// ***************************************************************************** -{ - // Set flag that indicates that we are now during time stepping - Disc()->Initial( 0 ); - // Start timer measuring time stepping wall clock time - Disc()->Timer().zero(); - // Zero grind-timer - Disc()->grindZero(); - // Continue to first time step - next(); -} -//! [start] - -//! [Compute lhs] -void -ALECG::lhs() -// ***************************************************************************** -// Compute the left-hand side of transport equations -//! \details Also (re-)compute all data structures if the mesh changed. -// ***************************************************************************** -{ - // No need for LHS in ALECG - - // (Re-)compute boundary point-, and dual-face normals - norm(); -} -//! [Compute lhs] - -//! [Merge normals and continue] -void -ALECG::mergelhs() -// ***************************************************************************** -// The own and communication portion of the left-hand side is complete -// ***************************************************************************** -{ - // Combine own and communicated contributions of normals - normfinal(); - - if (Disc()->Initial()) { - volumetric( m_u, Disc()->Vol() ); - // Output initial conditions to file - writeFields( CkCallback(CkIndex_ALECG::start(), thisProxy[thisIndex]) ); - } else { - norm_complete(); - } -} -//! [Merge normals and continue] - -void -ALECG::normfinal() -// ***************************************************************************** -// Finish computing dual-face and boundary point normals -// ***************************************************************************** -{ - auto d = Disc(); - const auto& lid = d->Lid(); - - // Combine own and communicated contributions to boundary point normals - for (const auto& [s,norms] : m_bnormc) { - auto& bnorms = m_bnorm[s]; - for (const auto& [p,n] : norms) { - auto& norm = bnorms[p]; - norm[0] += n[0]; - norm[1] += n[1]; - norm[2] += n[2]; - norm[3] += n[3]; +//! [start] +void +OversetFE::start() +// ***************************************************************************** +// Start time stepping +// ***************************************************************************** +{ + // Set flag that indicates that we are now during time stepping + Disc()->Initial( 0 ); + // Start timer measuring time stepping wall clock time + Disc()->Timer().zero(); + // Zero grind-timer + Disc()->grindZero(); + // Continue to first time step + next(); +} +//! [start] + +void +OversetFE::applySolTransfer( + std::size_t dirn ) +// ***************************************************************************** +// \brief Apply the transferred solution to the solution vector based on +// transfer flags previously set up +//! \param[in] dirn 0 if called from B to O, 1 if called from O to B +// ***************************************************************************** +{ + // Change solution only if: + // 1. undergoing transfer from B to O, and currently on O + if (dirn == 0 && Disc()->MeshId() != 0) { + + for (auto i : m_farfieldbcnodes) { + // overset-BC nodes: use transferred solution and blank nodes. + // the transfer-flag from m_uc is not used since it has been overwritten + // by Disc()->transfer() with the flag from B + for (ncomp_t c=0; c<m_u.nprop(); ++c) { // Loop over number of equations + m_u(i,c) = m_uc(i,c); + } + m_blank[i] = 0.0; + } + + } + // 2. undergoing transfer from O to B, and currently on B + else if (dirn == 1 && Disc()->MeshId() == 0) { + + //TODO: index the flag in a better way + std::size_t iflag = m_uc.nprop()-1; + + // Zero out solution space for nodes with a specific transfer flag set + for (std::size_t i=0; i<m_uc.nunk(); ++i) { // Check flag value + + if (std::abs(m_uc(i,iflag) - 1.0) < 1e-4) { + // overset-BC nodes: use transferred solution and blank nodes + for (ncomp_t c=0; c<m_u.nprop(); ++c) { // Loop over number of equations + m_u(i,c) = m_uc(i,c); + } + m_blank[i] = 0.0; + } + else if (std::abs(m_uc(i,iflag) - 2.0) < 1e-4) { + // hole: blank nodes + m_blank[i] = 0.0; + } + else { + // do nothing + m_blank[i] = 1.0; + } + + } + + } +} + +void +OversetFE::setTransferFlags( + std::size_t dirn ) +// ***************************************************************************** +// Set flags informing solution transfer decisions +//! \param[in] dirn 0 if called from B to O, 1 if called from O to B +// ***************************************************************************** +{ + // Copy solution and reset flags + //TODO: index the flag in a better way + std::size_t iflag = m_uc.nprop()-1; + + for (std::size_t i=0; i<m_u.nunk(); ++i) { + for (std::size_t c=0; c<m_u.nprop(); ++c) { + m_uc(i,c) = m_u(i,c); + } + // Reset flags + m_uc(i,iflag) = 0.0; + + // reset blanking coefficient + m_blank[i] = 1.0; + } + + // Transfer flags for O to B are based on block-ids that are hardcoded + // TODO: remove hardcoding + + // Called from transfer-B-to-O + if (dirn == 0) { + if (Disc()->MeshId() != 0) { + // Overset meshes: assign appropriate values to flag + for (auto i : m_farfieldbcnodes) m_uc(i,iflag) = 1.0; } } - tk::destroy( m_bnormc ); - - // Divide summed point normals by the sum of inverse distance squared - for (auto& [s,norms] : m_bnorm) - for (auto& [p,n] : norms) { - n[0] /= n[3]; - n[1] /= n[3]; - n[2] /= n[3]; - Assert( (n[0]*n[0] + n[1]*n[1] + n[2]*n[2] - 1.0) < - 1.0e+3*std::numeric_limits< tk::real >::epsilon(), - "Non-unit normal" ); - } - - // Replace global->local ids associated to boundary point normals - decltype(m_bnorm) bnorm; - for (auto& [s,norms] : m_bnorm) { - auto& bnorms = bnorm[s]; - for (auto&& [g,n] : norms) - bnorms[ tk::cref_find(lid,g) ] = std::move(n); - } - m_bnorm = std::move(bnorm); - - // Count contributions to chare-boundary edges - std::unordered_map< tk::UnsMesh::Edge, std::size_t, - tk::UnsMesh::Hash<2>, tk::UnsMesh::Eq<2> > edge_node_count; - for (const auto& [c,edges] : d->EdgeCommMap()) - for (const auto& e : edges) - ++edge_node_count[e]; - - // Combine and weigh communicated contributions to dual-face normals - for (auto& [e,n] : m_dfnormc) { - const auto& dfn = tk::cref_find( m_dfnorm, e ); - n[0] += dfn[0]; - n[1] += dfn[1]; - n[2] += dfn[2]; - auto count = static_cast< tk::real >( tk::cref_find( edge_node_count, e ) ); - auto factor = 1.0/(count + 1.0); - for (auto & x : n) x *= factor;<--- Consider using std::transform algorithm instead of a raw loop. - } - - // Generate list of unique edges - tk::UnsMesh::EdgeSet uedge; - for (std::size_t p=0; p<m_u.nunk(); ++p) - for (auto q : tk::Around(m_psup,p)) - uedge.insert( {p,q} ); - - // Flatten edge list - m_edgenode.resize( uedge.size() * 2 ); - std::size_t f = 0; - const auto& gid = d->Gid(); - for (auto&& [p,q] : uedge) { - if (gid[p] > gid[q]) { - m_edgenode[f+0] = std::move(q); - m_edgenode[f+1] = std::move(p); - } else { - m_edgenode[f+0] = std::move(p); - m_edgenode[f+1] = std::move(q); - } - f += 2; - } - tk::destroy(uedge); - - // Convert dual-face normals to streamable (and vectorizable) data structure - m_dfn.resize( m_edgenode.size() * 3 ); // 2 vectors per access - std::unordered_map< tk::UnsMesh::Edge, std::size_t, - tk::UnsMesh::Hash<2>, tk::UnsMesh::Eq<2> > eid; - for (std::size_t e=0; e<m_edgenode.size()/2; ++e) { - auto p = m_edgenode[e*2+0]; - auto q = m_edgenode[e*2+1]; - eid[{p,q}] = e; - std::array< std::size_t, 2 > g{ gid[p], gid[q] }; - auto n = tk::cref_find( m_dfnorm, g ); - // figure out if this is an edge on the parallel boundary - auto nit = m_dfnormc.find( g ); - auto m = ( nit != m_dfnormc.end() ) ? nit->second : n; - m_dfn[e*6+0] = n[0]; - m_dfn[e*6+1] = n[1]; - m_dfn[e*6+2] = n[2]; - m_dfn[e*6+3] = m[0]; - m_dfn[e*6+4] = m[1]; - m_dfn[e*6+5] = m[2]; - } - - tk::destroy( m_dfnorm ); - tk::destroy( m_dfnormc ); - - // Flatten edge id data structure - m_edgeid.resize( m_psup.first.size() ); - for (std::size_t p=0,k=0; p<m_u.nunk(); ++p) - for (auto q : tk::Around(m_psup,p)) - m_edgeid[k++] = tk::cref_find( eid, {p,q} ); -} - -void -ALECG::BC() -// ***************************************************************************** -// Apply boundary conditions -// \details The following BC enforcement changes the initial condition or -//! updated solution (dependending on when it is called) to ensure strong -//! imposition of the BCs. This is a matter of choice. Another alternative is -//! to only apply BCs when computing fluxes at boundary faces, thereby only -//! weakly enforcing the BCs. The former is conventionally used in continunous -//! Galerkin finite element methods (such as ALECG implements), whereas the -//! latter, in finite volume methods. -// ***************************************************************************** -{ - auto d = Disc(); - const auto& coord = d->Coord(); - - conserved( m_u, d->Vol() ); - - // Apply Dirichlet BCs - for (const auto& [b,bc] : m_dirbc) - for (ncomp_t c=0; c<m_u.nprop(); ++c) - if (bc[c].first) m_u(b,c) = bc[c].second; - - // Apply symmetry BCs - g_cgpde[d->MeshId()].symbc( m_u, coord, m_bnorm, m_symbcnodes ); + // Called from transfer-O-to-B + else { + if (Disc()->MeshId() != 0) { + // Overset meshes: assign appropriate values to flag + for (const auto& [blid, ndset] : m_nodeblockid) { + if (blid == 103) { + for (auto i : ndset) m_uc(i,iflag) = 1.0; + } + else if (blid == 104) { + for (auto i : ndset) m_uc(i,iflag) = 2.0; + } + } + } + } +} + +void +OversetFE::normfinal() +// ***************************************************************************** +// Finish computing dual-face and boundary point normals +// ***************************************************************************** +{ + auto d = Disc(); + const auto& lid = d->Lid(); + + // Combine own and communicated contributions to boundary point normals + for (const auto& [s,norms] : m_bnormc) { + auto& bnorms = m_bnorm[s]; + for (const auto& [p,n] : norms) { + auto& norm = bnorms[p]; + norm[0] += n[0]; + norm[1] += n[1]; + norm[2] += n[2]; + norm[3] += n[3]; + } + } + tk::destroy( m_bnormc ); + + // Divide summed point normals by the sum of inverse distance squared + for (auto& [s,norms] : m_bnorm) + for (auto& [p,n] : norms) { + n[0] /= n[3]; + n[1] /= n[3]; + n[2] /= n[3]; + Assert( (n[0]*n[0] + n[1]*n[1] + n[2]*n[2] - 1.0) < + 1.0e+3*std::numeric_limits< tk::real >::epsilon(), + "Non-unit normal" ); + } + + // Replace global->local ids associated to boundary point normals + decltype(m_bnorm) bnorm; + for (auto& [s,norms] : m_bnorm) { + auto& bnorms = bnorm[s]; + for (auto&& [g,n] : norms) + bnorms[ tk::cref_find(lid,g) ] = std::move(n); + } + m_bnorm = std::move(bnorm); + + // Count contributions to chare-boundary edges + std::unordered_map< tk::UnsMesh::Edge, std::size_t, + tk::UnsMesh::Hash<2>, tk::UnsMesh::Eq<2> > edge_node_count; + for (const auto& [c,edges] : d->EdgeCommMap()) + for (const auto& e : edges) + ++edge_node_count[e]; + + // Combine and weigh communicated contributions to dual-face normals + for (auto& [e,n] : m_dfnormc) { + const auto& dfn = tk::cref_find( m_dfnorm, e ); + n[0] += dfn[0]; + n[1] += dfn[1]; + n[2] += dfn[2]; + auto count = static_cast< tk::real >( tk::cref_find( edge_node_count, e ) ); + auto factor = 1.0/(count + 1.0); + for (auto & x : n) x *= factor;<--- Consider using std::transform algorithm instead of a raw loop. + } + + // Generate list of unique edges + tk::UnsMesh::EdgeSet uedge; + for (std::size_t p=0; p<m_u.nunk(); ++p) + for (auto q : tk::Around(m_psup,p)) + uedge.insert( {p,q} ); + + // Flatten edge list + m_edgenode.resize( uedge.size() * 2 ); + std::size_t f = 0; + const auto& gid = d->Gid(); + for (auto&& [p,q] : uedge) { + if (gid[p] > gid[q]) { + m_edgenode[f+0] = std::move(q); + m_edgenode[f+1] = std::move(p); + } else { + m_edgenode[f+0] = std::move(p); + m_edgenode[f+1] = std::move(q); + } + f += 2; + } + tk::destroy(uedge); + + // Convert dual-face normals to streamable (and vectorizable) data structure + m_dfn.resize( m_edgenode.size() * 3 ); // 2 vectors per access + std::unordered_map< tk::UnsMesh::Edge, std::size_t, + tk::UnsMesh::Hash<2>, tk::UnsMesh::Eq<2> > eid; + for (std::size_t e=0; e<m_edgenode.size()/2; ++e) { + auto p = m_edgenode[e*2+0]; + auto q = m_edgenode[e*2+1]; + eid[{p,q}] = e; + std::array< std::size_t, 2 > g{ gid[p], gid[q] }; + auto n = tk::cref_find( m_dfnorm, g ); + // figure out if this is an edge on the parallel boundary + auto nit = m_dfnormc.find( g ); + auto m = ( nit != m_dfnormc.end() ) ? nit->second : n; + m_dfn[e*6+0] = n[0]; + m_dfn[e*6+1] = n[1]; + m_dfn[e*6+2] = n[2]; + m_dfn[e*6+3] = m[0]; + m_dfn[e*6+4] = m[1]; + m_dfn[e*6+5] = m[2]; + } - // Apply farfield BCs - g_cgpde[d->MeshId()].farfieldbc( m_u, coord, m_bnorm, m_farfieldbcnodes ); + tk::destroy( m_dfnorm ); + tk::destroy( m_dfnormc ); - // Apply user defined time dependent BCs - g_cgpde[d->MeshId()].timedepbc( d->T(), m_u, m_timedepbcnodes, - m_timedepbcFn ); - - volumetric( m_u, d->Vol() ); + // Flatten edge id data structure + m_edgeid.resize( m_psup.first.size() ); + for (std::size_t p=0,k=0; p<m_u.nunk(); ++p) + for (auto q : tk::Around(m_psup,p)) + m_edgeid[k++] = tk::cref_find( eid, {p,q} ); } void -ALECG::next() +OversetFE::BC() // ***************************************************************************** -// Continue to next time step -// ***************************************************************************** -{ - dt(); -} - -void -ALECG::dt() +// Apply boundary conditions +// \details The following BC enforcement changes the initial condition or +//! updated solution (dependending on when it is called) to ensure strong +//! imposition of the BCs. This is a matter of choice. Another alternative is +//! to only apply BCs when computing fluxes at boundary faces, thereby only +//! weakly enforcing the BCs. The former is conventionally used in continunous +//! Galerkin finite element methods (such as OversetFE implements), whereas the +//! latter, in finite volume methods. // ***************************************************************************** -// Compute time step size -// ***************************************************************************** -{ - tk::real mindt = std::numeric_limits< tk::real >::max(); - - auto const_dt = g_inputdeck.get< tag::dt >(); - auto eps = std::numeric_limits< tk::real >::epsilon(); - - auto d = Disc(); - - // use constant dt if configured - if (std::abs(const_dt) > eps) { - - mindt = const_dt; - - } else { // compute dt based on CFL - - //! [Find the minimum dt across all PDEs integrated] - conserved( m_u, Disc()->Vol() ); - if (g_inputdeck.get< tag::steady_state >()) { - - // compute new dt for each mesh point - g_cgpde[d->MeshId()].dt( d->It(), d->Vol(), m_u, m_dtp ); - - // find the smallest dt of all nodes on this chare - mindt = *std::min_element( begin(m_dtp), end(m_dtp) ); - - } else { // compute new dt for this chare - - // find the smallest dt of all equations on this chare - auto eqdt = g_cgpde[d->MeshId()].dt( d->Coord(), d->Inpoel(), d->T(), - d->Dtn(), m_u, d->Vol(), d->Voln() ); - if (eqdt < mindt) mindt = eqdt; - - } - volumetric( m_u, Disc()->Vol() ); - //! [Find the minimum dt across all PDEs integrated] - +{ + auto d = Disc(); + const auto& coord = d->Coord(); + + const auto& bcmesh = g_inputdeck.get< tag::bc >(); + + for (const auto& bci : bcmesh) { + const auto& bcm = bci.get< tag::mesh >(); + for (const auto& im : bcm) { + // only if this bc is meant for current mesh + if (im-1 == d->MeshId()) { + + // Query and match user-specified Dirichlet boundary conditions to side sets + const auto steady = g_inputdeck.get< tag::steady_state >(); + if (steady) for (auto& deltat : m_dtp) deltat *= rkcoef[m_stage];<--- Consider using std::transform algorithm instead of a raw loop. + m_dirbc = match( d->MeshId(), m_u.nprop(), d->T(), rkcoef[m_stage] * d->Dt(), + m_tp, m_dtp, d->Coord(), d->Lid(), m_bnode, + /* increment = */ false ); + if (steady) for (auto& deltat : m_dtp) deltat /= rkcoef[m_stage];<--- Consider using std::transform algorithm instead of a raw loop. + + // Apply Dirichlet BCs + for (const auto& [b,bc] : m_dirbc) + for (ncomp_t c=0; c<m_u.nprop(); ++c) + if (bc[c].first) m_u(b,c) = bc[c].second; + + // Apply symmetry BCs + g_cgpde[d->MeshId()].symbc( m_u, coord, m_bnorm, m_symbcnodes ); + + // Apply farfield BCs + if (bci.get< tag::farfield >().empty() || (d->MeshId() == 0)) { + g_cgpde[d->MeshId()].farfieldbc( m_u, coord, m_bnorm, m_farfieldbcnodes ); + } + + // Apply user defined time dependent BCs + g_cgpde[d->MeshId()].timedepbc( d->T(), m_u, m_timedepbcnodes, + m_timedepbcFn ); + } + } } - - //! [Advance] - // Actiavate SDAG waits for next time step stage - thisProxy[ thisIndex ].wait4grad(); - thisProxy[ thisIndex ].wait4rhs(); - - // Contribute to minimum dt across all chares and advance to next step - contribute( sizeof(tk::real), &mindt, CkReduction::min_double, - CkCallback(CkReductionTarget(ALECG,advance), thisProxy) ); - //! [Advance] -} - -void -ALECG::advance( tk::real newdt, tk::real ) -// ***************************************************************************** -// Advance equations to next time step -//! \param[in] newdt The smallest dt across the whole problem -// ***************************************************************************** -{ - auto d = Disc(); - - // Set new time step size - if (m_stage == 0) d->setdt( newdt ); +} + +void +OversetFE::next() +// ***************************************************************************** +// Continue to next time step +// ***************************************************************************** +{ + dt(); +} + +void +OversetFE::dt() +// ***************************************************************************** +// Compute time step size +// ***************************************************************************** +{ + tk::real mindt = std::numeric_limits< tk::real >::max(); + + auto const_dt = g_inputdeck.get< tag::dt >(); + auto eps = std::numeric_limits< tk::real >::epsilon(); + + auto d = Disc(); - // Compute gradients for next time step - chBndGrad(); -} - -void -ALECG::chBndGrad() -// ***************************************************************************** -// Compute nodal gradients at chare-boundary nodes. Gradients at internal nodes -// are calculated locally as needed and are not stored. -// ***************************************************************************** -{ - auto d = Disc(); + // use constant dt if configured + if (std::abs(const_dt) > eps) { + + mindt = const_dt; + + } else { // compute dt based on CFL + + //! [Find the minimum dt across all PDEs integrated] + if (g_inputdeck.get< tag::steady_state >()) { + + // compute new dt for each mesh point + g_cgpde[d->MeshId()].dt( d->It(), d->Vol(), m_u, m_dtp ); - // Divide solution with mesh volume - conserved( m_u, Disc()->Vol() ); - // Compute own portion of gradients for all equations - g_cgpde[d->MeshId()].chBndGrad( d->Coord(), d->Inpoel(), m_bndel, d->Gid(), - d->Bid(), m_u, m_chBndGrad ); - // Multiply solution with mesh volume - volumetric( m_u, Disc()->Vol() ); - - // Communicate gradients to other chares on chare-boundary - if (d->NodeCommMap().empty()) // in serial we are done - comgrad_complete(); - else // send gradients contributions to chare-boundary nodes to fellow chares - for (const auto& [c,n] : d->NodeCommMap()) { - std::vector< std::vector< tk::real > > g( n.size() ); - std::size_t j = 0; - for (auto i : n) g[ j++ ] = m_chBndGrad[ tk::cref_find(d->Bid(),i) ]; - thisProxy[c].comChBndGrad( std::vector<std::size_t>(begin(n),end(n)), g ); - } + // find the smallest dt of all nodes on this chare + mindt = *std::min_element( begin(m_dtp), end(m_dtp) ); + + } else { // compute new dt for this chare + + // find the smallest dt of all equations on this chare + auto eqdt = g_cgpde[d->MeshId()].dt( d->Coord(), d->Inpoel(), d->T(), + d->Dtn(), m_u, d->Vol(), d->Voln() ); + if (eqdt < mindt) mindt = eqdt; + + } + //! [Find the minimum dt across all PDEs integrated] + + } + + // Determine if this chunk of mesh needs to be moved + g_cgpde[d->MeshId()].getMeshVel(d->T(), d->Coord(), m_psup, m_symbcnodes, + m_uservel, m_u, d->MeshVel(), m_movedmesh); - owngrad_complete(); -} - -void -ALECG::comChBndGrad( const std::vector< std::size_t >& gid, - const std::vector< std::vector< tk::real > >& G ) -// ***************************************************************************** -// Receive contributions to nodal gradients on chare-boundaries -//! \param[in] gid Global mesh node IDs at which we receive grad contributions -//! \param[in] G Partial contributions of gradients to chare-boundary nodes -//! \details This function receives contributions to m_chBndGrad, which stores -//! nodal gradients at mesh chare-boundary nodes. While m_chBndGrad stores -//! own contributions, m_chBndGradc collects the neighbor chare -//! contributions during communication. This way work on m_chBndGrad and -//! m_chBndGradc is overlapped. The two are combined in rhs(). -// ***************************************************************************** -{ - Assert( G.size() == gid.size(), "Size mismatch" ); - - using tk::operator+=; - - for (std::size_t i=0; i<gid.size(); ++i) m_chBndGradc[ gid[i] ] += G[i]; - - if (++m_ngrad == Disc()->NodeCommMap().size()) { - m_ngrad = 0; - comgrad_complete(); - } -} - -void -ALECG::rhs() + //! [Advance] + // Actiavate SDAG waits for next time step stage + thisProxy[ thisIndex ].wait4grad(); + thisProxy[ thisIndex ].wait4rhs(); + + // TODO: this is a hacky way to know if any chunk moved. redesign it + std::vector < tk::real > reducndata(d->Transfers().size()+2, 0.0); + + reducndata[0] = mindt; + reducndata[d->MeshId()+1] = static_cast< tk::real >(-m_movedmesh); + + // Contribute to minimum dt across all chares and advance to next step + if (g_inputdeck.get< tag::steady_state >()) { + contribute( reducndata, CkReduction::min_double, + CkCallback(CkReductionTarget(OversetFE,advance), thisProxy) ); + } + else { + // if solving a time-accurate problem, find minimum dt across all meshes + // and eventually broadcast to OversetFE::advance() + contribute( reducndata, CkReduction::min_double, + CkCallback(CkReductionTarget(Transporter,minDtAcrossMeshes), d->Tr()) ); + } + //! [Advance] +} + +void +OversetFE::advance( tk::real newdt, tk::real nmovedmesh ) +// ***************************************************************************** +// Advance equations to next time step +//! \param[in] newdt The smallest dt across the whole problem +//! \param[in] nmovedmesh (negative of) if any chunk of this mesh moved // ***************************************************************************** -// Compute right-hand side of transport equations -// ***************************************************************************** -{ - auto d = Disc(); - - // Combine own and communicated contributions to nodal gradients - for (const auto& [gid,g] : m_chBndGradc) { - auto bid = tk::cref_find( d->Bid(), gid ); - for (ncomp_t c=0; c<m_chBndGrad.nprop(); ++c) - m_chBndGrad(bid,c) += g[c]; - } - - // clear gradients receive buffer - tk::destroy(m_chBndGradc); - - const auto steady = g_inputdeck.get< tag::steady_state >(); - - // Compute own portion of right-hand side for all equations - auto prev_rkcoef = m_stage == 0 ? 0.0 : rkcoef[m_stage-1]; - if (steady) - for (std::size_t p=0; p<m_tp.size(); ++p) m_tp[p] += prev_rkcoef * m_dtp[p]; - conserved( m_u, Disc()->Vol() ); - g_cgpde[d->MeshId()].rhs( d->T() + prev_rkcoef * d->Dt(), d->Coord(), d->Inpoel(), - m_triinpoel, d->Gid(), d->Bid(), d->Lid(), m_dfn, m_psup, m_esup, - m_symbctri, d->Vol(), m_edgenode, m_edgeid, - m_boxnodes, m_chBndGrad, m_u, d->meshvel(), m_tp, d->Boxvol(), - m_rhs ); - volumetric( m_u, Disc()->Vol() ); - if (steady) - for (std::size_t p=0; p<m_tp.size(); ++p) m_tp[p] -= prev_rkcoef * m_dtp[p]; - - // Query/update boundary-conditions-related data structures from user input - queryBnd(); - - // Communicate rhs to other chares on chare-boundary - if (d->NodeCommMap().empty()) // in serial we are done - comrhs_complete(); - else // send contributions of rhs to chare-boundary nodes to fellow chares - for (const auto& [c,n] : d->NodeCommMap()) { - std::vector< std::vector< tk::real > > r( n.size() ); - std::size_t j = 0; - for (auto i : n) r[ j++ ] = m_rhs[ tk::cref_find(d->Lid(),i) ]; - thisProxy[c].comrhs( std::vector<std::size_t>(begin(n),end(n)), r ); - } - - ownrhs_complete(); -} - -void -ALECG::comrhs( const std::vector< std::size_t >& gid, - const std::vector< std::vector< tk::real > >& R ) -// ***************************************************************************** -// Receive contributions to right-hand side vector on chare-boundaries -//! \param[in] gid Global mesh node IDs at which we receive RHS contributions -//! \param[in] R Partial contributions of RHS to chare-boundary nodes -//! \details This function receives contributions to m_rhs, which stores the -//! right hand side vector at mesh nodes. While m_rhs stores own -//! contributions, m_rhsc collects the neighbor chare contributions during -//! communication. This way work on m_rhs and m_rhsc is overlapped. The two -//! are combined in solve(). -// ***************************************************************************** -{ - Assert( R.size() == gid.size(), "Size mismatch" ); - - using tk::operator+=; +{ + auto d = Disc(); + + // Set new time step size + if (m_stage == 0) d->setdt( newdt ); + + // TODO: this is a hacky way to know if any chunk moved. redesign it + if (nmovedmesh < -0.1) m_movedmesh = 1; + + // Compute gradients for next time step + chBndGrad(); +} + +void +OversetFE::chBndGrad() +// ***************************************************************************** +// Compute nodal gradients at chare-boundary nodes. Gradients at internal nodes +// are calculated locally as needed and are not stored. +// ***************************************************************************** +{ + auto d = Disc(); + + // Compute own portion of gradients for all equations + g_cgpde[d->MeshId()].chBndGrad( d->Coord(), d->Inpoel(), m_bndel, d->Gid(), + d->Bid(), m_u, m_chBndGrad ); + + // Communicate gradients to other chares on chare-boundary + if (d->NodeCommMap().empty()) // in serial we are done + comgrad_complete(); + else // send gradients contributions to chare-boundary nodes to fellow chares + for (const auto& [c,n] : d->NodeCommMap()) { + std::vector< std::vector< tk::real > > g( n.size() ); + std::size_t j = 0; + for (auto i : n) g[ j++ ] = m_chBndGrad[ tk::cref_find(d->Bid(),i) ]; + thisProxy[c].comChBndGrad( std::vector<std::size_t>(begin(n),end(n)), g ); + } + + owngrad_complete(); +} + +void +OversetFE::comChBndGrad( const std::vector< std::size_t >& gid, + const std::vector< std::vector< tk::real > >& G ) +// ***************************************************************************** +// Receive contributions to nodal gradients on chare-boundaries +//! \param[in] gid Global mesh node IDs at which we receive grad contributions +//! \param[in] G Partial contributions of gradients to chare-boundary nodes +//! \details This function receives contributions to m_chBndGrad, which stores +//! nodal gradients at mesh chare-boundary nodes. While m_chBndGrad stores +//! own contributions, m_chBndGradc collects the neighbor chare +//! contributions during communication. This way work on m_chBndGrad and +//! m_chBndGradc is overlapped. The two are combined in rhs(). +// ***************************************************************************** +{ + Assert( G.size() == gid.size(), "Size mismatch" ); + + using tk::operator+=; + + for (std::size_t i=0; i<gid.size(); ++i) m_chBndGradc[ gid[i] ] += G[i]; + + if (++m_ngrad == Disc()->NodeCommMap().size()) { + m_ngrad = 0; + comgrad_complete(); + } +} - for (std::size_t i=0; i<gid.size(); ++i) m_rhsc[ gid[i] ] += R[i]; - - // When we have heard from all chares we communicate with, this chare is done - if (++m_nrhs == Disc()->NodeCommMap().size()) { - m_nrhs = 0; - comrhs_complete(); - } -} - -void -ALECG::solve() -// ***************************************************************************** -// Advance systems of equations -// ***************************************************************************** -{ - auto d = Disc(); - - // Combine own and communicated contributions to rhs - for (const auto& b : m_rhsc) { - auto lid = tk::cref_find( d->Lid(), b.first ); - for (ncomp_t c=0; c<m_rhs.nprop(); ++c) m_rhs(lid,c) += b.second[c]; - } - - // clear receive buffer - tk::destroy(m_rhsc); - - // Update state at time n - if (m_stage == 0) { - m_un = m_u; - if (g_inputdeck.get< tag::ale, tag::ale >()) d->UpdateCoordn(); - } - - // Solve the sytem - if (g_inputdeck.get< tag::steady_state >()) { - - // Advance solution, converging to steady state - for (std::size_t i=0; i<m_u.nunk(); ++i) - for (ncomp_t c=0; c<m_u.nprop(); ++c) - m_u(i,c) = m_un(i,c) + rkcoef[m_stage] * m_dtp[i] * m_rhs(i,c); - - } else { +void +OversetFE::rhs() +// ***************************************************************************** +// Compute right-hand side of transport equations +// ***************************************************************************** +{ + auto d = Disc(); + + // Combine own and communicated contributions to nodal gradients + for (const auto& [gid,g] : m_chBndGradc) { + auto bid = tk::cref_find( d->Bid(), gid ); + for (ncomp_t c=0; c<m_chBndGrad.nprop(); ++c) + m_chBndGrad(bid,c) += g[c]; + } + + // clear gradients receive buffer + tk::destroy(m_chBndGradc); + + const auto steady = g_inputdeck.get< tag::steady_state >(); + + // Assign mesh velocity + if (m_movedmesh) { + const auto& coord = d->Coord(); + auto& mvel = d->MeshVel(); + for (std::size_t p=0; p<coord[0].size(); ++p) { + for (std::size_t i=0; i<3; ++i) + mvel(p, i) = m_uservel[i]; + } + } + + // Compute own portion of right-hand side for all equations + auto prev_rkcoef = m_stage == 0 ? 0.0 : rkcoef[m_stage-1]; + if (steady) + for (std::size_t p=0; p<m_tp.size(); ++p) m_tp[p] += prev_rkcoef * m_dtp[p]; + g_cgpde[d->MeshId()].rhs( d->T() + prev_rkcoef * d->Dt(), d->Coord(), d->Inpoel(), + m_triinpoel, d->Gid(), d->Bid(), d->Lid(), m_dfn, m_psup, m_esup, + m_symbctri, d->Vol(), m_edgenode, m_edgeid, + m_boxnodes, m_chBndGrad, m_u, d->MeshVel(), m_tp, d->Boxvol(), + m_rhs ); + if (steady) + for (std::size_t p=0; p<m_tp.size(); ++p) m_tp[p] -= prev_rkcoef * m_dtp[p]; - auto adt = rkcoef[m_stage] * d->Dt(); - - // Advance unsteady solution - m_u = m_un + adt * m_rhs; - - // Advance mesh if ALE is enabled - if (g_inputdeck.get< tag::ale, tag::ale >()) { - auto& coord = d->Coord(); - const auto& w = d->meshvel(); - for (auto j : g_inputdeck.get< tag::ale, tag::mesh_motion >()) - for (std::size_t i=0; i<coord[j].size(); ++i) - coord[j][i] = d->Coordn()[j][i] + adt * w(i,j); - } + // Communicate rhs to other chares on chare-boundary + if (d->NodeCommMap().empty()) // in serial we are done + comrhs_complete(); + else // send contributions of rhs to chare-boundary nodes to fellow chares + for (const auto& [c,n] : d->NodeCommMap()) { + std::vector< std::vector< tk::real > > r( n.size() ); + std::size_t j = 0; + for (auto i : n) r[ j++ ] = m_rhs[ tk::cref_find(d->Lid(),i) ]; + thisProxy[c].comrhs( std::vector<std::size_t>(begin(n),end(n)), r ); + } + + ownrhs_complete(); +} - } - - m_newmesh = 0; // recompute normals after ALE (if enabled) - m_refinedmesh = 0; // mesh has not been refined by ALE - // Activate SDAG waits - thisProxy[ thisIndex ].wait4norm(); - thisProxy[ thisIndex ].wait4mesh(); - - //! [Continue after solve] - // Recompute mesh volumes if ALE is enabled - if (g_inputdeck.get< tag::ale, tag::ale >()) { - - transfer_complete(); - // Save nodal volumes at previous time step stage - d->Voln() = d->Vol(); - // Prepare for recomputing the nodal volumes - d->startvol(); - auto meshid = d->MeshId(); - contribute( sizeof(std::size_t), &meshid, CkReduction::nop, - CkCallback(CkReductionTarget(Transporter,resized), d->Tr()) ); - - } else { - - norm_complete(); - resized(); - - } - //! [Continue after solve] -} - -void -ALECG::ale() -// ***************************************************************************** -// Continue after computing the new mesh velocity for ALE -// ***************************************************************************** -{ - auto d = Disc(); - - if (m_stage < 2) { - - // Activate SDAG wait for next time step stage - thisProxy[ thisIndex ].wait4grad(); - thisProxy[ thisIndex ].wait4rhs(); +void +OversetFE::comrhs( const std::vector< std::size_t >& gid, + const std::vector< std::vector< tk::real > >& R ) +// ***************************************************************************** +// Receive contributions to right-hand side vector on chare-boundaries +//! \param[in] gid Global mesh node IDs at which we receive RHS contributions +//! \param[in] R Partial contributions of RHS to chare-boundary nodes +//! \details This function receives contributions to m_rhs, which stores the +//! right hand side vector at mesh nodes. While m_rhs stores own +//! contributions, m_rhsc collects the neighbor chare contributions during +//! communication. This way work on m_rhs and m_rhsc is overlapped. The two +//! are combined in solve(). +// ***************************************************************************** +{ + Assert( R.size() == gid.size(), "Size mismatch" ); + + using tk::operator+=; + + for (std::size_t i=0; i<gid.size(); ++i) m_rhsc[ gid[i] ] += R[i]; + + // When we have heard from all chares we communicate with, this chare is done + if (++m_nrhs == Disc()->NodeCommMap().size()) { + m_nrhs = 0; + comrhs_complete(); + } +} + +void +OversetFE::solve() +// ***************************************************************************** +// Advance systems of equations +// ***************************************************************************** +{ + auto d = Disc(); + + // Combine own and communicated contributions to rhs + for (const auto& b : m_rhsc) { + auto lid = tk::cref_find( d->Lid(), b.first ); + for (ncomp_t c=0; c<m_rhs.nprop(); ++c) m_rhs(lid,c) += b.second[c]; + } + + // clear receive buffer + tk::destroy(m_rhsc); - // continue to mesh-to-mesh transfer (if coupled) - transfer(); - - } else { + // Update state at time n + if (m_stage == 0) { + m_un = m_u; + } - // Ensure new field output file if mesh moved if ALE is enabled - if (g_inputdeck.get< tag::ale, tag::ale >()) { - d->Itf() = 0; // Zero field output iteration count if mesh moved - ++d->Itr(); // Increase number of iterations with a change in the mesh - } - - // Compute diagnostics, e.g., residuals - conserved( m_u, Disc()->Vol() ); - conserved( m_un, Disc()->Voln() ); - auto diag_computed = m_diag.compute( *d, m_u, m_un, m_bnorm, - m_symbcnodes, m_farfieldbcnodes ); - volumetric( m_u, Disc()->Vol() ); - volumetric( m_un, Disc()->Voln() ); - // Increase number of iterations and physical time - d->next(); - // Advance physical time for local time stepping - if (g_inputdeck.get< tag::steady_state >()) - for (std::size_t i=0; i<m_u.nunk(); ++i) m_tp[i] += m_dtp[i]; - // Continue to mesh refinement (if configured) - if (!diag_computed) refine( std::vector< tk::real >( m_u.nprop(), 1.0 ) ); - - } -} - -//! [Refine] -void -ALECG::refine( const std::vector< tk::real >& l2res ) -// ***************************************************************************** -// Optionally refine/derefine mesh -//! \param[in] l2res L2-norms of the residual for each scalar component -//! computed across the whole problem -// ***************************************************************************** -{ - auto d = Disc(); + // Explicit time-stepping using RK3 + const auto steady = g_inputdeck.get< tag::steady_state >(); + for (std::size_t i=0; i<m_u.nunk(); ++i) { + // time-step + auto dtp = d->Dt(); + if (steady) dtp = m_dtp[i]; + + for (ncomp_t c=0; c<m_u.nprop(); ++c) + m_u(i,c) = m_un(i,c) + m_blank[i] * rkcoef[m_stage] * dtp * m_rhs(i,c) + / d->Vol()[i]; + } + + // Move overset mesh + if (m_movedmesh) { + auto& x = d->Coord()[0]; + auto& y = d->Coord()[1]; + auto& z = d->Coord()[2]; + const auto& w = d->MeshVel(); + for (std::size_t i=0; i<w.nunk(); ++i) { + // time-step + auto dtp = d->Dt(); + if (steady) dtp = m_dtp[i]; + + x[i] += rkcoef[m_stage] * dtp * w(i,0); + y[i] += rkcoef[m_stage] * dtp * w(i,1); + z[i] += rkcoef[m_stage] * dtp * w(i,2); + } + } + // the following line will be needed for situations where the mesh stops + // moving after its initial motion + // else m_movedmesh = 0; + + // Apply boundary-conditions + BC(); - const auto steady = g_inputdeck.get< tag::steady_state >(); - const auto residual = g_inputdeck.get< tag::residual >(); - const auto rc = g_inputdeck.get< tag::rescomp >() - 1; - - if (steady) { - - // this is the last time step if max time of max number of time steps - // reached or the residual has reached its convergence criterion - if (d->finished() or l2res[rc] < residual) m_finished = 1; - - } else { - - // this is the last time step if max time or max iterations reached - if (d->finished()) m_finished = 1; - - } - - auto dtref = g_inputdeck.get< tag::amr, tag::dtref >(); - auto dtfreq = g_inputdeck.get< tag::amr, tag::dtfreq >(); - - // Activate SDAG waits for re-computing the normals - m_newmesh = 1; // recompute normals after AMR (if enabled) - thisProxy[ thisIndex ].wait4norm(); - thisProxy[ thisIndex ].wait4mesh(); - - // if t>0 refinement enabled and we hit the frequency - if (dtref && !(d->It() % dtfreq)) { // refine - - // Convert to conserved unknowns, since the next step changes volumes - conserved(m_u, d->Vol()); - - m_refinedmesh = 1; - d->startvol(); - d->Ref()->dtref( m_bface, m_bnode, m_triinpoel ); - d->refined() = 1; - - } else { // do not refine - - m_refinedmesh = 0; - d->refined() = 0; - norm_complete(); - resized(); - - } -} -//! [Refine] + // Increment Runge-Kutta stage counter + ++m_stage; + + // Activate SDAG wait for next time step stage + thisProxy[ thisIndex ].wait4grad(); + thisProxy[ thisIndex ].wait4rhs(); + + // Compute diagnostics, and finish-up time step (if m_stage == 3) + bool diag_computed(false); + if (m_stage == 3) { + // Compute diagnostics, e.g., residuals + diag_computed = m_diag.compute( *d, m_u, m_un, m_bnorm, + m_symbcnodes, m_farfieldbcnodes ); + // Increase number of iterations and physical time + d->next(); + // Advance physical time for local time stepping + if (g_inputdeck.get< tag::steady_state >()) + for (std::size_t i=0; i<m_u.nunk(); ++i) m_tp[i] += m_dtp[i]; + } + // Continue to finish-up time-step-stage + // Note: refine is called via a bcast if diag_computed == true + if (!diag_computed) refine( std::vector< tk::real >( m_u.nprop(), 1.0 ) ); +} + +//! [Refine] +void +OversetFE::refine( const std::vector< tk::real >& l2res ) +// ***************************************************************************** +// Finish up end of time-step procedures and continue to moving mesh +//! \param[in] l2res L2-norms of the residual for each scalar component +//! computed across the whole problem +// ***************************************************************************** +{ + auto d = Disc(); + + if (m_stage == 3) { + const auto steady = g_inputdeck.get< tag::steady_state >(); + const auto residual = g_inputdeck.get< tag::residual >(); + const auto rc = g_inputdeck.get< tag::rescomp >() - 1; + + if (m_movedmesh) { + d->Itf() = 0; // Zero field output iteration count if mesh moved + ++d->Itr(); // Increase number of iterations with a change in the mesh + } + + if (steady) { -//! [Resize] -void -ALECG::resizePostAMR( - const std::vector< std::size_t >& /*ginpoel*/, - const tk::UnsMesh::Chunk& chunk, - const tk::UnsMesh::Coords& coord, - const std::unordered_map< std::size_t, tk::UnsMesh::Edge >& addedNodes, - const std::unordered_map< std::size_t, std::size_t >& /*addedTets*/, - const std::set< std::size_t >& removedNodes, - const std::unordered_map< std::size_t, std::size_t >& amrNodeMap, - const tk::NodeCommMap& nodeCommMap, - const std::map< int, std::vector< std::size_t > >& bface, - const std::map< int, std::vector< std::size_t > >& bnode, - const std::vector< std::size_t >& triinpoel, - const std::unordered_map< std::size_t, std::set< std::size_t > >& elemblockid ) -// ***************************************************************************** -// Receive new mesh from Refiner -//! \param[in] ginpoel Mesh connectivity with global node ids -//! \param[in] chunk New mesh chunk (connectivity and global<->local id maps) -//! \param[in] coord New mesh node coordinates -//! \param[in] addedNodes Newly added mesh nodes and their parents (local ids) -//! \param[in] addedTets Newly added mesh cells and their parents (local ids) -//! \param[in] removedNodes Newly removed mesh node local ids -//! \param[in] amrNodeMap Node id map after amr (local ids) -//! \param[in] nodeCommMap New node communication map -//! \param[in] bface Boundary-faces mapped to side set ids -//! \param[in] bnode Boundary-node lists mapped to side set ids -//! \param[in] triinpoel Boundary-face connectivity -//! \param[in] elemblockid Local tet ids associated with mesh block ids -// ***************************************************************************** -{ - auto d = Disc(); - - d->Itf() = 0; // Zero field output iteration count if AMR - ++d->Itr(); // Increase number of iterations with a change in the mesh - - // Resize mesh data structures after mesh refinement - d->resizePostAMR( chunk, coord, amrNodeMap, nodeCommMap, removedNodes, - elemblockid ); - - // Remove newly removed nodes from solution vectors - m_u.rm(removedNodes); - m_un.rm(removedNodes); - m_rhs.rm(removedNodes); - - // Resize auxiliary solution vectors - auto npoin = coord[0].size(); - auto nprop = m_u.nprop(); - m_u.resize( npoin ); - m_un.resize( npoin ); - m_rhs.resize( npoin ); - m_chBndGrad.resize( d->Bid().size() ); - tk::destroy(m_esup); - tk::destroy(m_psup); - m_esup = tk::genEsup( d->Inpoel(), 4 ); - m_psup = tk::genPsup( d->Inpoel(), 4, m_esup ); - - // Update solution on new mesh - for (const auto& n : addedNodes) - for (std::size_t c=0; c<nprop; ++c) { - Assert(n.first < m_u.nunk(), "Added node index out of bounds post-AMR"); - Assert(n.second[0] < m_u.nunk() && n.second[1] < m_u.nunk(), - "Indices of parent-edge nodes out of bounds post-AMR"); - m_u(n.first,c) = (m_u(n.second[0],c) + m_u(n.second[1],c))/2.0; - } - - // Update physical-boundary node-, face-, and element lists - m_bnode = bnode; - m_bface = bface; - m_triinpoel = tk::remap( triinpoel, d->Lid() ); + // this is the last time step if max time of max number of time steps + // reached or the residual has reached its convergence criterion + if (d->finished() or l2res[rc] < residual) m_finished = 1; + + } else { + + // this is the last time step if max time or max iterations reached + if (d->finished()) m_finished = 1; + + } + } + + if (m_movedmesh) { + // Normals need to be recomputed if overset mesh has been moved + thisProxy[ thisIndex ].wait4norm(); + } + + // Start solution transfer + transferSol(); +} +//! [Refine] + +//! [stage] +void +OversetFE::stage() +// ***************************************************************************** +// Evaluate whether to continue with next time step stage +// ***************************************************************************** +{ + // if not all Runge-Kutta stages complete, continue to next time stage, + // otherwise start next time step + if (m_stage == 3) { + // output field data and start with next time step + out(); + } + else { + // start with next time-step stage + chBndGrad(); + } +} +//! [stage] + +void +OversetFE::writeFields( CkCallback c ) +// ***************************************************************************** +// Output mesh-based fields to file +//! \param[in] c Function to continue with after the write +// ***************************************************************************** +{ + if (g_inputdeck.get< tag::cmd, tag::benchmark >()) { + + c.send(); + + } else { + + auto d = Disc(); + const auto& coord = d->Coord(); + + //// if coupled: depvars: src:'a', dst:'b','c',... + //char depvar = 0; + //if (not d->Transfers().empty()) { + // depvar = 'a' + static_cast< char >( d->MeshId() ); + //} + + // Query fields names requested by user + auto nodefieldnames = numericFieldNames( tk::Centering::NODE ); + + // Collect field output from numerical solution requested by user + auto nodefields = numericFieldOutput( m_u, tk::Centering::NODE, + g_cgpde[Disc()->MeshId()].OutVarFn(), m_u ); - auto meshid = d->MeshId(); - contribute( sizeof(std::size_t), &meshid, CkReduction::nop, - CkCallback(CkReductionTarget(Transporter,resized), d->Tr()) ); -} -//! [Resize] - -void -ALECG::resized() -// ***************************************************************************** -// Resizing data sutrctures after mesh refinement has been completed -// ***************************************************************************** -{ - auto d = Disc(); - - // Revert to volumetric unknowns, if soln was converted in ALECG::refine() - auto dtref = g_inputdeck.get< tag::amr, tag::dtref >(); - auto dtfreq = g_inputdeck.get< tag::amr, tag::dtfreq >(); - if (dtref && !(d->It() % dtfreq) && m_refinedmesh==1) { - volumetric(m_u, d->Vol()); - // Update previous volumes after refinement - d->Voln() = d->Vol(); - } - - resize_complete(); -} - -void -ALECG::transfer() -// ***************************************************************************** -// Transfer solution to other solver and mesh if coupled -// ***************************************************************************** -{ - // Initiate solution transfer (if coupled) + // Collect field output names for analytical solutions + analyticFieldNames( g_cgpde[d->MeshId()], tk::Centering::NODE, + nodefieldnames ); + + // Collect field output from analytical solutions (if exist) + analyticFieldOutput( g_cgpde[d->MeshId()], tk::Centering::NODE, coord[0], + coord[1], coord[2], d->T(), nodefields ); + + // Query and collect nodal block and surface field names from PDEs integrated + std::vector< std::string > nodesurfnames; + auto sn = g_cgpde[d->MeshId()].surfNames(); + nodesurfnames.insert( end(nodesurfnames), begin(sn), end(sn) ); + + // Collect nodal block and surface field solution + std::vector< std::vector< tk::real > > nodesurfs; + auto so = g_cgpde[d->MeshId()].surfOutput( tk::bfacenodes(m_bface, + m_triinpoel), m_u ); + nodesurfs.insert( end(nodesurfs), begin(so), end(so) ); + + // Collect elemental block and surface field names from PDEs integrated + auto elemsurfnames = nodesurfnames;<--- Variable 'elemsurfnames' is assigned a value that is never used. + + // Collect elemental block and surface field solution + std::vector< std::vector< tk::real > > elemsurfs; + auto eso = g_cgpde[d->MeshId()].elemSurfOutput( m_bface, m_triinpoel, m_u ); + elemsurfs.insert( end(elemsurfs), begin(eso), end(eso) ); + + Assert( nodefieldnames.size() == nodefields.size(), "Size mismatch" ); + + // Send mesh and fields data (solution dump) for output to file + d->write( d->Inpoel(), coord, m_bface, tk::remap(m_bnode,d->Lid()), + m_triinpoel, {}, nodefieldnames, elemsurfnames, + nodesurfnames, {}, nodefields, elemsurfs, nodesurfs, c ); -//TODO: enable this for during-timestepping solution transfer -// Disc()->transfer(m_u, CkCallback(CkIndex_ALECG::stage(), thisProxy[thisIndex])); - thisProxy[thisIndex].stage(); -} - -//! [stage] -void -ALECG::stage() -// ***************************************************************************** -// Evaluate whether to continue with next time step stage -// ***************************************************************************** -{ - transfer_complete(); - - // Increment Runge-Kutta stage counter - ++m_stage; - - // if not all Runge-Kutta stages complete, continue to next time stage, - // otherwise output field data to file(s) - if (m_stage < 3) chBndGrad(); else out(); -} -//! [stage] - -void -ALECG::writeFields( CkCallback c ) -// ***************************************************************************** -// Output mesh-based fields to file -//! \param[in] c Function to continue with after the write + } +} + +void +OversetFE::out() +// ***************************************************************************** +// Output mesh field data and continue to next time step +// ***************************************************************************** +{ + auto d = Disc(); + + // Output time history + if (d->histiter() or d->histtime() or d->histrange()) { + std::vector< std::vector< tk::real > > hist; + auto h = g_cgpde[d->MeshId()].histOutput( d->Hist(), d->Inpoel(), m_u ); + hist.insert( end(hist), begin(h), end(h) ); + d->history( std::move(hist) ); + } + + // Output field data + if (d->fielditer() or d->fieldtime() or d->fieldrange() or m_finished) + writeFields(CkCallback( CkIndex_OversetFE::step(), thisProxy[thisIndex]) ); + else + step(); +} + +void +OversetFE::evalLB( int nrestart ) // ***************************************************************************** -{ - if (g_inputdeck.get< tag::cmd, tag::benchmark >()) { - - c.send(); - - } else { - - auto d = Disc(); - const auto& coord = d->Coord(); +// Evaluate whether to do load balancing +//! \param[in] nrestart Number of times restarted +// ***************************************************************************** +{ + auto d = Disc(); + + // Detect if just returned from a checkpoint and if so, zero timers and + // finished flag + if (d->restarted( nrestart )) m_finished = 0; - // Query fields names requested by user - auto nodefieldnames = numericFieldNames( tk::Centering::NODE ); + const auto lbfreq = g_inputdeck.get< tag::cmd, tag::lbfreq >(); + const auto nonblocking = g_inputdeck.get< tag::cmd, tag::nonblocking >(); - // Collect field output from numerical solution requested by user - conserved( m_u, Disc()->Vol() ); - auto nodefields = numericFieldOutput( m_u, tk::Centering::NODE, - g_cgpde[Disc()->MeshId()].OutVarFn(), m_u ); - volumetric( m_u, Disc()->Vol() ); + // Load balancing if user frequency is reached or after the second time-step + if ( (d->It()) % lbfreq == 0 || d->It() == 2 ) { + + AtSync(); + if (nonblocking) next(); - //! Lambda to put in a field for output if not empty - auto add_node_field = [&]( const auto& name, const auto& field ){ - if (not field.empty()) { - nodefieldnames.push_back( name ); - nodefields.push_back( field ); - } - }; - - // Output mesh velocity if ALE is enabled - if (g_inputdeck.get< tag::ale, tag::ale >()) { - const auto& w = d->meshvel(); - add_node_field( "x-mesh-velocity", w.extract_comp(0) ); - add_node_field( "y-mesh-velocity", w.extract_comp(1) ); - add_node_field( "z-mesh-velocity", w.extract_comp(2) ); - add_node_field( "volume", d->Vol() ); - } - - // Collect field output names for analytical solutions - analyticFieldNames( g_cgpde[d->MeshId()], tk::Centering::NODE, - nodefieldnames ); - - // Collect field output from analytical solutions (if exist) - analyticFieldOutput( g_cgpde[d->MeshId()], tk::Centering::NODE, coord[0], - coord[1], coord[2], d->T(), nodefields ); - - // Query and collect nodal block and surface field names from PDEs integrated - std::vector< std::string > nodesurfnames; - auto sn = g_cgpde[d->MeshId()].surfNames(); - nodesurfnames.insert( end(nodesurfnames), begin(sn), end(sn) ); - - // Collect nodal block and surface field solution - std::vector< std::vector< tk::real > > nodesurfs; - conserved( m_u, Disc()->Vol() ); - auto so = g_cgpde[d->MeshId()].surfOutput( tk::bfacenodes(m_bface, - m_triinpoel), m_u ); - nodesurfs.insert( end(nodesurfs), begin(so), end(so) ); - - // Collect elemental block and surface field names from PDEs integrated - auto elemsurfnames = nodesurfnames; - - // Collect elemental block and surface field solution - std::vector< std::vector< tk::real > > elemsurfs; - auto eso = g_cgpde[d->MeshId()].elemSurfOutput( m_bface, m_triinpoel, m_u ); - elemsurfs.insert( end(elemsurfs), begin(eso), end(eso) ); - - // Query refinement data - auto dtref = g_inputdeck.get< tag::amr, tag::dtref >(); + } else { + + next(); + + } +} + +void +OversetFE::evalRestart() +// ***************************************************************************** +// Evaluate whether to save checkpoint/restart +// ***************************************************************************** +{ + auto d = Disc(); + + const auto rsfreq = g_inputdeck.get< tag::cmd, tag::rsfreq >(); + const auto benchmark = g_inputdeck.get< tag::cmd, tag::benchmark >(); + + if (not benchmark and not (d->It() % rsfreq)) { + + std::vector< std::size_t > meshdata{ /* finished = */ 0, d->MeshId() }; + contribute( meshdata, CkReduction::nop, + CkCallback(CkReductionTarget(Transporter,checkpoint), d->Tr()) ); + + } else { + + evalLB( /* nrestart = */ -1 ); + + } +} + +void +OversetFE::step() +// ***************************************************************************** +// Evaluate whether to continue with next time step +// ***************************************************************************** +{ + auto d = Disc(); + + // Output one-liner status report to screen + d->status(); + // Reset Runge-Kutta stage counter + m_stage = 0; + + if (not m_finished) { + + evalRestart(); - std::tuple< std::vector< std::string >, - std::vector< std::vector< tk::real > >, - std::vector< std::string >, - std::vector< std::vector< tk::real > > > r; - if (dtref) r = d->Ref()->refinementFields(); - volumetric( m_u, Disc()->Vol() ); - - auto& refinement_elemfieldnames = std::get< 0 >( r ); - auto& refinement_elemfields = std::get< 1 >( r ); - auto& refinement_nodefieldnames = std::get< 2 >( r ); - auto& refinement_nodefields = std::get< 3 >( r ); - - nodefieldnames.insert( end(nodefieldnames), - begin(refinement_nodefieldnames), end(refinement_nodefieldnames) ); - nodefields.insert( end(nodefields), - begin(refinement_nodefields), end(refinement_nodefields) ); - - auto elemfieldnames = std::move(refinement_elemfieldnames); - auto elemfields = std::move(refinement_elemfields); - - Assert( elemfieldnames.size() == elemfields.size(), "Size mismatch" ); - Assert( nodefieldnames.size() == nodefields.size(), "Size mismatch" ); - - // Send mesh and fields data (solution dump) for output to file - d->write( d->Inpoel(), coord, m_bface, tk::remap(m_bnode,d->Lid()), - m_triinpoel, elemfieldnames, nodefieldnames, elemsurfnames, - nodesurfnames, elemfields, nodefields, elemsurfs, nodesurfs, c ); - - } -} - -void -ALECG::out() -// ***************************************************************************** -// Output mesh field data -// ***************************************************************************** -{ - auto d = Disc(); - - // Output time history - if (d->histiter() or d->histtime() or d->histrange()) { - std::vector< std::vector< tk::real > > hist; - conserved( m_u, Disc()->Vol() ); - auto h = g_cgpde[d->MeshId()].histOutput( d->Hist(), d->Inpoel(), m_u ); - hist.insert( end(hist), begin(h), end(h) ); - volumetric( m_u, Disc()->Vol() ); - d->history( std::move(hist) ); - } - - // Output field data - if (d->fielditer() or d->fieldtime() or d->fieldrange() or m_finished) - writeFields( CkCallback(CkIndex_ALECG::step(), thisProxy[thisIndex]) ); - else - step(); -} - -void -ALECG::evalLB( int nrestart ) -// ***************************************************************************** -// Evaluate whether to do load balancing -//! \param[in] nrestart Number of times restarted -// ***************************************************************************** -{ - auto d = Disc(); - - // Detect if just returned from a checkpoint and if so, zero timers and - // finished flag - if (d->restarted( nrestart )) m_finished = 0; - - const auto lbfreq = g_inputdeck.get< tag::cmd, tag::lbfreq >(); - const auto nonblocking = g_inputdeck.get< tag::cmd, tag::nonblocking >(); - - // Load balancing if user frequency is reached or after the second time-step - if ( (d->It()) % lbfreq == 0 || d->It() == 2 ) { - - AtSync(); - if (nonblocking) next(); - - } else { - - next(); - - } -} - -void -ALECG::evalRestart() -// ***************************************************************************** -// Evaluate whether to save checkpoint/restart -// ***************************************************************************** -{ - auto d = Disc(); - - const auto rsfreq = g_inputdeck.get< tag::cmd, tag::rsfreq >(); - const auto benchmark = g_inputdeck.get< tag::cmd, tag::benchmark >(); - - if (not benchmark and not (d->It() % rsfreq)) { - - std::vector< std::size_t > meshdata{ /* finished = */ 0, d->MeshId() }; - contribute( meshdata, CkReduction::nop, - CkCallback(CkReductionTarget(Transporter,checkpoint), d->Tr()) ); - - } else { - - evalLB( /* nrestart = */ -1 ); - - } -} - -void -ALECG::step() -// ***************************************************************************** -// Evaluate whether to continue with next time step -// ***************************************************************************** -{ - auto d = Disc(); - - // Output one-liner status report to screen - d->status(); - // Reset Runge-Kutta stage counter - m_stage = 0; - - if (not m_finished) { - - evalRestart(); - - } else { - - auto meshid = d->MeshId(); - d->contribute( sizeof(std::size_t), &meshid, CkReduction::nop, - CkCallback(CkReductionTarget(Transporter,finish), d->Tr()) ); - - } -} - -#include "NoWarning/alecg.def.h" + } else { + + auto meshid = d->MeshId(); + d->contribute( sizeof(std::size_t), &meshid, CkReduction::nop, + CkCallback(CkReductionTarget(Transporter,finish), d->Tr()) ); + + } +} + +#include "NoWarning/oversetfe.def.h"

diff --git a/Debug/cppcheck/44.html b/Debug/cppcheck/44.html index b8412e065605..8c7060ee9966 100644 --- a/Debug/cppcheck/44.html +++ b/Debug/cppcheck/44.html @@ -152,407 +152,2973 @@
- - + @@ -77,7 +77,7 @@ - +
  1
-  2
-  3
-  4
-  5
-  6
-  7
-  8
-  9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
- 37
- 38
- 39
- 40
- 41
- 42
- 43
- 44
- 45
- 46
- 47
- 48
- 49
- 50
- 51
- 52
- 53
- 54
- 55
- 56
- 57
- 58
- 59
- 60
- 61
- 62
- 63
- 64
- 65
- 66
- 67
- 68
- 69
- 70
- 71
- 72
- 73
- 74
- 75
- 76
- 77
- 78
- 79
- 80
- 81
- 82
- 83
- 84
- 85
- 86
- 87
- 88
- 89
- 90
- 91
- 92
- 93
- 94
- 95
- 96
- 97
- 98
- 99
-100
-101
-102
-103
-104
-105
-106
-107
-108
-109
-110
-111
-112
-113
-114
-115
-116
-117
-118
-119
-120
-121
-122
-123
-124
-125
-126
-127
-128
-129
-130
-131
-132
-133
-134
-135
-136
-137
-138
-139
-140
-141
-142
-143
-144
-145
-146
-147
-148
-149
-150
-151
-152
-153
-154
-155
-156
-157
-158
-159
-160
-161
-162
-163
-164
-165
-166
-167
-168
-169
-170
-171
-172
-173
-174
-175
-176
-177
-178
-179
-180
-181
-182
-183
-184
-185
-186
-187
-188
-189
-190
-191
-192
-193
-194
-195
-196
-197
// *****************************************************************************
+
   1
+   2
+   3
+   4
+   5
+   6
+   7
+   8
+   9
+  10
+  11
+  12
+  13
+  14
+  15
+  16
+  17
+  18
+  19
+  20
+  21
+  22
+  23
+  24
+  25
+  26
+  27
+  28
+  29
+  30
+  31
+  32
+  33
+  34
+  35
+  36
+  37
+  38
+  39
+  40
+  41
+  42
+  43
+  44
+  45
+  46
+  47
+  48
+  49
+  50
+  51
+  52
+  53
+  54
+  55
+  56
+  57
+  58
+  59
+  60
+  61
+  62
+  63
+  64
+  65
+  66
+  67
+  68
+  69
+  70
+  71
+  72
+  73
+  74
+  75
+  76
+  77
+  78
+  79
+  80
+  81
+  82
+  83
+  84
+  85
+  86
+  87
+  88
+  89
+  90
+  91
+  92
+  93
+  94
+  95
+  96
+  97
+  98
+  99
+ 100
+ 101
+ 102
+ 103
+ 104
+ 105
+ 106
+ 107
+ 108
+ 109
+ 110
+ 111
+ 112
+ 113
+ 114
+ 115
+ 116
+ 117
+ 118
+ 119
+ 120
+ 121
+ 122
+ 123
+ 124
+ 125
+ 126
+ 127
+ 128
+ 129
+ 130
+ 131
+ 132
+ 133
+ 134
+ 135
+ 136
+ 137
+ 138
+ 139
+ 140
+ 141
+ 142
+ 143
+ 144
+ 145
+ 146
+ 147
+ 148
+ 149
+ 150
+ 151
+ 152
+ 153
+ 154
+ 155
+ 156
+ 157
+ 158
+ 159
+ 160
+ 161
+ 162
+ 163
+ 164
+ 165
+ 166
+ 167
+ 168
+ 169
+ 170
+ 171
+ 172
+ 173
+ 174
+ 175
+ 176
+ 177
+ 178
+ 179
+ 180
+ 181
+ 182
+ 183
+ 184
+ 185
+ 186
+ 187
+ 188
+ 189
+ 190
+ 191
+ 192
+ 193
+ 194
+ 195
+ 196
+ 197
+ 198
+ 199
+ 200
+ 201
+ 202
+ 203
+ 204
+ 205
+ 206
+ 207
+ 208
+ 209
+ 210
+ 211
+ 212
+ 213
+ 214
+ 215
+ 216
+ 217
+ 218
+ 219
+ 220
+ 221
+ 222
+ 223
+ 224
+ 225
+ 226
+ 227
+ 228
+ 229
+ 230
+ 231
+ 232
+ 233
+ 234
+ 235
+ 236
+ 237
+ 238
+ 239
+ 240
+ 241
+ 242
+ 243
+ 244
+ 245
+ 246
+ 247
+ 248
+ 249
+ 250
+ 251
+ 252
+ 253
+ 254
+ 255
+ 256
+ 257
+ 258
+ 259
+ 260
+ 261
+ 262
+ 263
+ 264
+ 265
+ 266
+ 267
+ 268
+ 269
+ 270
+ 271
+ 272
+ 273
+ 274
+ 275
+ 276
+ 277
+ 278
+ 279
+ 280
+ 281
+ 282
+ 283
+ 284
+ 285
+ 286
+ 287
+ 288
+ 289
+ 290
+ 291
+ 292
+ 293
+ 294
+ 295
+ 296
+ 297
+ 298
+ 299
+ 300
+ 301
+ 302
+ 303
+ 304
+ 305
+ 306
+ 307
+ 308
+ 309
+ 310
+ 311
+ 312
+ 313
+ 314
+ 315
+ 316
+ 317
+ 318
+ 319
+ 320
+ 321
+ 322
+ 323
+ 324
+ 325
+ 326
+ 327
+ 328
+ 329
+ 330
+ 331
+ 332
+ 333
+ 334
+ 335
+ 336
+ 337
+ 338
+ 339
+ 340
+ 341
+ 342
+ 343
+ 344
+ 345
+ 346
+ 347
+ 348
+ 349
+ 350
+ 351
+ 352
+ 353
+ 354
+ 355
+ 356
+ 357
+ 358
+ 359
+ 360
+ 361
+ 362
+ 363
+ 364
+ 365
+ 366
+ 367
+ 368
+ 369
+ 370
+ 371
+ 372
+ 373
+ 374
+ 375
+ 376
+ 377
+ 378
+ 379
+ 380
+ 381
+ 382
+ 383
+ 384
+ 385
+ 386
+ 387
+ 388
+ 389
+ 390
+ 391
+ 392
+ 393
+ 394
+ 395
+ 396
+ 397
+ 398
+ 399
+ 400
+ 401
+ 402
+ 403
+ 404
+ 405
+ 406
+ 407
+ 408
+ 409
+ 410
+ 411
+ 412
+ 413
+ 414
+ 415
+ 416
+ 417
+ 418
+ 419
+ 420
+ 421
+ 422
+ 423
+ 424
+ 425
+ 426
+ 427
+ 428
+ 429
+ 430
+ 431
+ 432
+ 433
+ 434
+ 435
+ 436
+ 437
+ 438
+ 439
+ 440
+ 441
+ 442
+ 443
+ 444
+ 445
+ 446
+ 447
+ 448
+ 449
+ 450
+ 451
+ 452
+ 453
+ 454
+ 455
+ 456
+ 457
+ 458
+ 459
+ 460
+ 461
+ 462
+ 463
+ 464
+ 465
+ 466
+ 467
+ 468
+ 469
+ 470
+ 471
+ 472
+ 473
+ 474
+ 475
+ 476
+ 477
+ 478
+ 479
+ 480
+ 481
+ 482
+ 483
+ 484
+ 485
+ 486
+ 487
+ 488
+ 489
+ 490
+ 491
+ 492
+ 493
+ 494
+ 495
+ 496
+ 497
+ 498
+ 499
+ 500
+ 501
+ 502
+ 503
+ 504
+ 505
+ 506
+ 507
+ 508
+ 509
+ 510
+ 511
+ 512
+ 513
+ 514
+ 515
+ 516
+ 517
+ 518
+ 519
+ 520
+ 521
+ 522
+ 523
+ 524
+ 525
+ 526
+ 527
+ 528
+ 529
+ 530
+ 531
+ 532
+ 533
+ 534
+ 535
+ 536
+ 537
+ 538
+ 539
+ 540
+ 541
+ 542
+ 543
+ 544
+ 545
+ 546
+ 547
+ 548
+ 549
+ 550
+ 551
+ 552
+ 553
+ 554
+ 555
+ 556
+ 557
+ 558
+ 559
+ 560
+ 561
+ 562
+ 563
+ 564
+ 565
+ 566
+ 567
+ 568
+ 569
+ 570
+ 571
+ 572
+ 573
+ 574
+ 575
+ 576
+ 577
+ 578
+ 579
+ 580
+ 581
+ 582
+ 583
+ 584
+ 585
+ 586
+ 587
+ 588
+ 589
+ 590
+ 591
+ 592
+ 593
+ 594
+ 595
+ 596
+ 597
+ 598
+ 599
+ 600
+ 601
+ 602
+ 603
+ 604
+ 605
+ 606
+ 607
+ 608
+ 609
+ 610
+ 611
+ 612
+ 613
+ 614
+ 615
+ 616
+ 617
+ 618
+ 619
+ 620
+ 621
+ 622
+ 623
+ 624
+ 625
+ 626
+ 627
+ 628
+ 629
+ 630
+ 631
+ 632
+ 633
+ 634
+ 635
+ 636
+ 637
+ 638
+ 639
+ 640
+ 641
+ 642
+ 643
+ 644
+ 645
+ 646
+ 647
+ 648
+ 649
+ 650
+ 651
+ 652
+ 653
+ 654
+ 655
+ 656
+ 657
+ 658
+ 659
+ 660
+ 661
+ 662
+ 663
+ 664
+ 665
+ 666
+ 667
+ 668
+ 669
+ 670
+ 671
+ 672
+ 673
+ 674
+ 675
+ 676
+ 677
+ 678
+ 679
+ 680
+ 681
+ 682
+ 683
+ 684
+ 685
+ 686
+ 687
+ 688
+ 689
+ 690
+ 691
+ 692
+ 693
+ 694
+ 695
+ 696
+ 697
+ 698
+ 699
+ 700
+ 701
+ 702
+ 703
+ 704
+ 705
+ 706
+ 707
+ 708
+ 709
+ 710
+ 711
+ 712
+ 713
+ 714
+ 715
+ 716
+ 717
+ 718
+ 719
+ 720
+ 721
+ 722
+ 723
+ 724
+ 725
+ 726
+ 727
+ 728
+ 729
+ 730
+ 731
+ 732
+ 733
+ 734
+ 735
+ 736
+ 737
+ 738
+ 739
+ 740
+ 741
+ 742
+ 743
+ 744
+ 745
+ 746
+ 747
+ 748
+ 749
+ 750
+ 751
+ 752
+ 753
+ 754
+ 755
+ 756
+ 757
+ 758
+ 759
+ 760
+ 761
+ 762
+ 763
+ 764
+ 765
+ 766
+ 767
+ 768
+ 769
+ 770
+ 771
+ 772
+ 773
+ 774
+ 775
+ 776
+ 777
+ 778
+ 779
+ 780
+ 781
+ 782
+ 783
+ 784
+ 785
+ 786
+ 787
+ 788
+ 789
+ 790
+ 791
+ 792
+ 793
+ 794
+ 795
+ 796
+ 797
+ 798
+ 799
+ 800
+ 801
+ 802
+ 803
+ 804
+ 805
+ 806
+ 807
+ 808
+ 809
+ 810
+ 811
+ 812
+ 813
+ 814
+ 815
+ 816
+ 817
+ 818
+ 819
+ 820
+ 821
+ 822
+ 823
+ 824
+ 825
+ 826
+ 827
+ 828
+ 829
+ 830
+ 831
+ 832
+ 833
+ 834
+ 835
+ 836
+ 837
+ 838
+ 839
+ 840
+ 841
+ 842
+ 843
+ 844
+ 845
+ 846
+ 847
+ 848
+ 849
+ 850
+ 851
+ 852
+ 853
+ 854
+ 855
+ 856
+ 857
+ 858
+ 859
+ 860
+ 861
+ 862
+ 863
+ 864
+ 865
+ 866
+ 867
+ 868
+ 869
+ 870
+ 871
+ 872
+ 873
+ 874
+ 875
+ 876
+ 877
+ 878
+ 879
+ 880
+ 881
+ 882
+ 883
+ 884
+ 885
+ 886
+ 887
+ 888
+ 889
+ 890
+ 891
+ 892
+ 893
+ 894
+ 895
+ 896
+ 897
+ 898
+ 899
+ 900
+ 901
+ 902
+ 903
+ 904
+ 905
+ 906
+ 907
+ 908
+ 909
+ 910
+ 911
+ 912
+ 913
+ 914
+ 915
+ 916
+ 917
+ 918
+ 919
+ 920
+ 921
+ 922
+ 923
+ 924
+ 925
+ 926
+ 927
+ 928
+ 929
+ 930
+ 931
+ 932
+ 933
+ 934
+ 935
+ 936
+ 937
+ 938
+ 939
+ 940
+ 941
+ 942
+ 943
+ 944
+ 945
+ 946
+ 947
+ 948
+ 949
+ 950
+ 951
+ 952
+ 953
+ 954
+ 955
+ 956
+ 957
+ 958
+ 959
+ 960
+ 961
+ 962
+ 963
+ 964
+ 965
+ 966
+ 967
+ 968
+ 969
+ 970
+ 971
+ 972
+ 973
+ 974
+ 975
+ 976
+ 977
+ 978
+ 979
+ 980
+ 981
+ 982
+ 983
+ 984
+ 985
+ 986
+ 987
+ 988
+ 989
+ 990
+ 991
+ 992
+ 993
+ 994
+ 995
+ 996
+ 997
+ 998
+ 999
+1000
+1001
+1002
+1003
+1004
+1005
+1006
+1007
+1008
+1009
+1010
+1011
+1012
+1013
+1014
+1015
+1016
+1017
+1018
+1019
+1020
+1021
+1022
+1023
+1024
+1025
+1026
+1027
+1028
+1029
+1030
+1031
+1032
+1033
+1034
+1035
+1036
+1037
+1038
+1039
+1040
+1041
+1042
+1043
+1044
+1045
+1046
+1047
+1048
+1049
+1050
+1051
+1052
+1053
+1054
+1055
+1056
+1057
+1058
+1059
+1060
+1061
+1062
+1063
+1064
+1065
+1066
+1067
+1068
+1069
+1070
+1071
+1072
+1073
+1074
+1075
+1076
+1077
+1078
+1079
+1080
+1081
+1082
+1083
+1084
+1085
+1086
+1087
+1088
+1089
+1090
+1091
+1092
+1093
+1094
+1095
+1096
+1097
+1098
+1099
+1100
+1101
+1102
+1103
+1104
+1105
+1106
+1107
+1108
+1109
+1110
+1111
+1112
+1113
+1114
+1115
+1116
+1117
+1118
+1119
+1120
+1121
+1122
+1123
+1124
+1125
+1126
+1127
+1128
+1129
+1130
+1131
+1132
+1133
+1134
+1135
+1136
+1137
+1138
+1139
+1140
+1141
+1142
+1143
+1144
+1145
+1146
+1147
+1148
+1149
+1150
+1151
+1152
+1153
+1154
+1155
+1156
+1157
+1158
+1159
+1160
+1161
+1162
+1163
+1164
+1165
+1166
+1167
+1168
+1169
+1170
+1171
+1172
+1173
+1174
+1175
+1176
+1177
+1178
+1179
+1180
+1181
+1182
+1183
+1184
+1185
+1186
+1187
+1188
+1189
+1190
+1191
+1192
+1193
+1194
+1195
+1196
+1197
+1198
+1199
+1200
+1201
+1202
+1203
+1204
+1205
+1206
+1207
+1208
+1209
+1210
+1211
+1212
+1213
+1214
+1215
+1216
+1217
+1218
+1219
+1220
+1221
+1222
+1223
+1224
+1225
+1226
+1227
+1228
+1229
+1230
+1231
+1232
+1233
+1234
+1235
+1236
+1237
+1238
+1239
+1240
+1241
+1242
+1243
+1244
+1245
+1246
+1247
+1248
+1249
+1250
+1251
+1252
+1253
+1254
+1255
+1256
+1257
+1258
+1259
+1260
+1261
+1262
+1263
+1264
+1265
+1266
+1267
+1268
+1269
+1270
+1271
+1272
+1273
+1274
+1275
+1276
+1277
+1278
+1279
+1280
+1281
+1282
+1283
+1284
+1285
+1286
+1287
+1288
+1289
+1290
+1291
+1292
+1293
+1294
+1295
+1296
+1297
+1298
+1299
+1300
+1301
+1302
+1303
+1304
+1305
+1306
+1307
+1308
+1309
+1310
+1311
+1312
+1313
+1314
+1315
+1316
+1317
+1318
+1319
+1320
+1321
+1322
+1323
+1324
+1325
+1326
+1327
+1328
+1329
+1330
+1331
+1332
+1333
+1334
+1335
+1336
+1337
+1338
+1339
+1340
+1341
+1342
+1343
+1344
+1345
+1346
+1347
+1348
+1349
+1350
+1351
+1352
+1353
+1354
+1355
+1356
+1357
+1358
+1359
+1360
+1361
+1362
+1363
+1364
+1365
+1366
+1367
+1368
+1369
+1370
+1371
+1372
+1373
+1374
+1375
+1376
+1377
+1378
+1379
+1380
+1381
+1382
+1383
+1384
+1385
+1386
+1387
+1388
+1389
+1390
+1391
+1392
+1393
+1394
+1395
+1396
+1397
+1398
+1399
+1400
+1401
+1402
+1403
+1404
+1405
+1406
+1407
+1408
+1409
+1410
+1411
+1412
+1413
+1414
+1415
+1416
+1417
+1418
+1419
+1420
+1421
+1422
+1423
+1424
+1425
+1426
+1427
+1428
+1429
+1430
+1431
+1432
+1433
+1434
+1435
+1436
+1437
+1438
+1439
+1440
+1441
+1442
+1443
+1444
+1445
+1446
+1447
+1448
+1449
+1450
+1451
+1452
+1453
+1454
+1455
+1456
+1457
+1458
+1459
+1460
+1461
+1462
+1463
+1464
+1465
+1466
+1467
+1468
+1469
+1470
+1471
+1472
+1473
+1474
+1475
+1476
+1477
+1478
+1479
+1480
// *****************************************************************************
 /*!
-  \file      src/PDE/MultiMat/Problem/BoxInitialization.hpp
+  \file      src/PDE/MultiMat/DGMultiMat.hpp
   \copyright 2012-2015 J. Bakosi,
              2016-2018 Los Alamos National Security, LLC.,
              2019-2021 Triad National Security, LLC.
              All rights reserved. See the LICENSE file for details.
-  \brief     User-defined box initialization
-  \details   This file defines functions for initializing solutions for
-    compressible multi-material equations inside the user-defined box.
-*/
-// *****************************************************************************
-#ifndef MultiMatBoxInitialization_h
-#define MultiMatBoxInitialization_h
-
-#include "Fields.hpp"
-#include "EoS/EOS.hpp"
-#include "ContainerUtil.hpp"
-#include "MultiMat/MultiMatIndexing.hpp"
-
-namespace inciter {
-
-using ncomp_t = tk::ncomp_t;
-
-template< class B >
-void initializeBox( const std::vector< EOS >& mat_blk,
-                    tk::real V_ex,
-                    tk::real t,
-                    const B& b,
-                    tk::real bgpreic,
-                    tk::real bgtempic,
-                    std::vector< tk::real >& s )
-// *****************************************************************************
-// Set the solution in the user-defined IC box/mesh block
-//! \tparam B IC-block type to operate, ctr::box, or ctr::meshblock
-//! \param[in] V_ex Exact box volume
-//! \param[in] t Physical time
-//! \param[in] b IC box configuration to use
-//! \param[in] bgpreic Background pressure user input
-//! \param[in] bgtempic Background temperature user input
-//! \param[in,out] s Solution vector that is set to box ICs
-//! \details This function sets the fluid density and total specific energy
-//!   within a box initial condition, configured by the user. If the user
-//!   is specified a box where mass is specified, we also assume here that
-//!   internal energy content (energy per unit volume) is also
-//!   specified. Specific internal energy (energy per unit mass) is then
-//!   computed here (and added to the kinetic energy) from the internal
-//!   energy per unit volume by multiplying it with the total box volume
-//!   and dividing it by the total mass of the material in the box.
-//!   Example (SI) units of the quantities involved:
-//!    * internal energy content (energy per unit volume): J/m^3
-//!    * specific energy (internal energy per unit mass): J/kg
-// *****************************************************************************
-{
-  auto nmat = g_inputdeck.get< tag::multimat, tag::nmat >();
+  \brief     Compressible multi-material flow using discontinuous Galerkin
+    finite elements
+  \details   This file implements calls to the physics operators governing
+    compressible multi-material flow (with velocity equilibrium) using
+    discontinuous Galerkin discretizations.
+*/
+// *****************************************************************************
+#ifndef DGMultiMat_h
+#define DGMultiMat_h
+
+#include <cmath>
+#include <algorithm>
+#include <unordered_set>
+#include <map>
+#include <array>
+
+#include "Macro.hpp"
+#include "Exception.hpp"
+#include "Vector.hpp"
+#include "ContainerUtil.hpp"
+#include "UnsMesh.hpp"
+#include "Inciter/InputDeck/InputDeck.hpp"
+#include "Integrate/Basis.hpp"
+#include "Integrate/Quadrature.hpp"
+#include "Integrate/Initialize.hpp"
+#include "Integrate/Mass.hpp"
+#include "Integrate/Surface.hpp"
+#include "Integrate/Boundary.hpp"
+#include "Integrate/Volume.hpp"
+#include "Integrate/MultiMatTerms.hpp"
+#include "Integrate/Source.hpp"
+#include "Integrate/SolidTerms.hpp"
+#include "RiemannChoice.hpp"
+#include "MultiMat/MultiMatIndexing.hpp"
+#include "Reconstruction.hpp"
+#include "Limiter.hpp"
+#include "Problem/FieldOutput.hpp"
+#include "Problem/BoxInitialization.hpp"
+#include "PrefIndicator.hpp"
+#include "MultiMat/BCFunctions.hpp"
+#include "MultiMat/MiscMultiMatFns.hpp"
+#include "EoS/GetMatProp.hpp"
+
+namespace inciter {
+
+extern ctr::InputDeck g_inputdeck;
+
+namespace dg {
 
-  const auto& solidx = g_inputdeck.get< tag::matidxmap, tag::solidx >();
-
-  const auto& initiate = b.template get< tag::initiate >();
-
-  // get material id in box (offset by 1, since input deck uses 1-based ids)
-  std::size_t boxmatid = b.template get< tag::materialid >() - 1;
-  const auto& boxvel = b.template get< tag::velocity >();
-  auto boxpre = b.template get< tag::pressure >();
-  auto boxene = b.template get< tag::energy >();
-  auto boxtemp = b.template get< tag::temperature >();
-  auto boxmas = b.template get< tag::mass >();
-  auto boxenc = b.template get< tag::energy_content >();
-
-  auto alphamin = 1.0e-12;
-
-  // [I] Compute the states inside the IC box/block based on the type of user
-  // input.
-
-  // material volume fractions
-  for (std::size_t k=0; k<nmat; ++k) {
-    if (k == boxmatid) {
-      s[volfracIdx(nmat,k)] = 1.0 - (static_cast< tk::real >(nmat-1))*alphamin;
-    }
-    else {
-      s[volfracIdx(nmat,k)] = alphamin;
-    }
-  }
-  // material states (density, pressure, velocity)
-  tk::real u = 0.0, v = 0.0, w = 0.0, spi(0.0), pr(0.0), tmp(0.0), rbulk(0.0);
-  std::vector< tk::real > rhok(nmat, 0.0);
-  // 1. User-specified mass, specific energy (J/m^3) and volume of box
-  if (boxmas > 0.0) {
-    if (boxenc <= 1e-12) Throw( "Box energy content must be nonzero" );<--- If condition 'boxenc<=1e-12' is true, the function will return/exit
-    // determine density and energy of material in the box
-    rhok[boxmatid] = boxmas / V_ex;
-    spi = boxenc / rhok[boxmatid];
-
-    // Determine pressure and temperature
-    auto boxmat_vf = s[volfracIdx(nmat,boxmatid)];
-
-    // Since initiate type 'linear' assigns the background IC values to all
-    // nodes within a box at initialization (followed by adding a time-dependent
-    // energy source term representing a propagating wave-front), the pressure
-    // in the box needs to be set to background pressure.
-    if (initiate == ctr::InitiateType::LINEAR && t < 1e-12) {
-      if (boxmas <= 1e-12 || boxenc <= 1e-12 || bgpreic <= 1e-12 ||<--- Testing identical condition 'boxenc<=1e-12'
-        bgtempic <= 1e-12)
-        Throw("Box mass, energy content, background pressure and background "
-          "temperature must be specified for IC with linear propagating source");
-
-      pr = bgpreic;
-      auto te = mat_blk[boxmatid].compute< EOS::totalenergy >(
-        rhok[boxmatid], u, v, w, pr);
-      tmp = mat_blk[boxmatid].compute< EOS::temperature >(
-        boxmat_vf*rhok[boxmatid], u, v, w, boxmat_vf*te, boxmat_vf );
-
-      // if the above density and pressure lead to an invalid thermodynamic
-      // state (negative temperature/energy), change temperature to background
-      // temperature and use corresponding density.
-      if (tmp < 0.0 || te < 0.0) {
-        tmp = bgtempic;
-        rhok[boxmatid] = mat_blk[boxmatid].compute< EOS::density >(pr, tmp);
-        spi = boxenc / rhok[boxmatid];
-      }
-    }
-    // For initiate type 'impulse', pressure and temperature are determined from
-    // energy content that needs to be dumped into the box at IC.
-    else if (initiate == ctr::InitiateType::IMPULSE) {
-      pr = mat_blk[boxmatid].compute< EOS::pressure >(
-        boxmat_vf*rhok[boxmatid], u, v, w, boxmat_vf*rhok[boxmatid]*spi,
-        boxmat_vf, boxmatid );
-      tmp = mat_blk[boxmatid].compute< EOS::temperature >(
-        boxmat_vf*rhok[boxmatid], u, v, w, boxmat_vf*rhok[boxmatid]*spi,
-        boxmat_vf );
-    }
-    else Throw( "IC box initiate type not implemented for multimat" );
-
-    // find density of trace material quantities in the box based on pressure
-    for (std::size_t k=0; k<nmat; ++k) {
-      if (k != boxmatid) {
-        rhok[k] = mat_blk[k].compute< EOS::density >(pr, tmp);
-      }
-    }
-  }
-  // 2. User-specified temperature, pressure and velocity in box
-  else {
-    for (std::size_t k=0; k<nmat; ++k) {
-      rhok[k] = mat_blk[k].compute< EOS::density >(boxpre, boxtemp);
-    }
-    if (boxvel.size() == 3) {
-      u = boxvel[0];
-      v = boxvel[1];
-      w = boxvel[2];
-    }
-    if (boxpre > 0.0) {
-      pr = boxpre;
-    }
-    if (boxene > 0.0) {
-      Throw("IC-box with specified energy not set up for multimat");
-    }
-  }
-  // bulk density
-  for (std::size_t k=0; k<nmat; ++k) rbulk += s[volfracIdx(nmat,k)]*rhok[k];
-
-  // [II] Finally initialize the solution vector
-  for (std::size_t k=0; k<nmat; ++k) {
-    // partial density
-    s[densityIdx(nmat,k)] = s[volfracIdx(nmat,k)] * rhok[k];
-    // total specific energy
-    if (boxmas > 0.0 && k == boxmatid &&
-      initiate == ctr::InitiateType::IMPULSE) {
-      s[energyIdx(nmat,k)] = s[volfracIdx(nmat,k)] * rhok[k] * spi;
-    }
-    else {
-      // TEMP: Eventually we would need to initialize gk from control file
-      std::array< std::array< tk::real, 3 >, 3 > gk;
-      if (solidx[k] > 0) {
-        for (std::size_t i=0; i<3; ++i) {
-          for (std::size_t j=0; j<3; ++j) {
-            if (i==j) gk[i][j] = 1.0;
-            else gk[i][j] = 0.0;
-            s[deformIdx(nmat,solidx[k],i,j)] = gk[i][j];
-          }
-        }
-      }
-      else {
-        gk = {{}};
-      }
-      s[energyIdx(nmat,k)] = s[volfracIdx(nmat,k)] *
-        mat_blk[k].compute< EOS::totalenergy >( rhok[k], u, v, w, pr, gk );
-    }
-  }
-  // bulk momentum
-  s[momentumIdx(nmat,0)] = rbulk * u;
-  s[momentumIdx(nmat,1)] = rbulk * v;
-  s[momentumIdx(nmat,2)] = rbulk * w;
-}
+//! \brief MultiMat used polymorphically with tk::DGPDE
+//! \details The template arguments specify policies and are used to configure
+//!   the behavior of the class. The policies are:
+//!   - Physics - physics configuration, see PDE/MultiMat/Physics.h
+//!   - Problem - problem configuration, see PDE/MultiMat/Problem.h
+//! \note The default physics is Euler, set in inciter::deck::check_multimat()
+template< class Physics, class Problem >
+class MultiMat {
+
+  private:
+    using eq = tag::multimat;
+
+  public:
+    //! Constructor
+    explicit MultiMat() :
+      m_ncomp( g_inputdeck.get< tag::ncomp >() ),
+      m_nprim(nprim()),
+      m_riemann( multimatRiemannSolver(
+        g_inputdeck.get< tag::flux >() ) )
+    {
+      // associate boundary condition configurations with state functions
+      brigand::for_each< ctr::bclist::Keys >( ConfigBC( m_bc,
+        { dirichlet
+        , symmetry
+        , invalidBC         // Inlet BC not implemented
+        , invalidBC         // Outlet BC not implemented
+        , farfieldOutlet
+        , extrapolate } ) );
+
+      // EoS initialization
+      initializeMaterialEoS( m_mat_blk );
+    }
+
+    //! Find the number of primitive quantities required for this PDE system
+    //! \return The number of primitive quantities required to be stored for
+    //!   this PDE system
+    std::size_t nprim() const<--- Shadowed declaration
+    {
+      auto nmat = g_inputdeck.get< tag::multimat, tag::nmat >();<--- Shadow variable
+      const auto& solidx = inciter::g_inputdeck.get<
+        tag::matidxmap, tag::solidx >();
+
+      // individual material pressures and three velocity components
+      std::size_t np(nmat+3);
+
+      for (std::size_t k=0; k<nmat; ++k) {
+        if (solidx[k] > 0) {
+          // individual material Cauchy stress tensor components
+          np += 6;
+        }
+      }
+
+      return np;
+    }
+
+    //! Find the number of materials set up for this PDE system
+    //! \return The number of materials set up for this PDE system
+    std::size_t nmat() const<--- Shadowed declaration<--- Shadowed declaration<--- Shadowed declaration<--- Shadowed declaration<--- Shadowed declaration<--- Shadowed declaration<--- Shadowed declaration<--- Shadowed declaration<--- Shadowed declaration<--- Shadowed declaration<--- Shadowed declaration<--- Shadowed declaration<--- Shadowed declaration<--- Shadowed declaration<--- Shadowed declaration<--- Shadowed declaration<--- Shadowed declaration<--- Shadowed declaration<--- Shadowed declaration<--- Shadowed declaration<--- Shadowed declaration<--- Shadowed declaration<--- Shadowed declaration<--- Shadowed declaration
+    {
+      auto nmat = g_inputdeck.get< tag::multimat, tag::nmat >();
+      return nmat;
+    }
+
+    //! Assign number of DOFs per equation in the PDE system
+    //! \param[in,out] numEqDof Array storing number of Dofs for each PDE
+    //!   equation
+    void numEquationDofs(std::vector< std::size_t >& numEqDof) const
+    {
+      // all equation-dofs initialized to ndofs first
+      for (std::size_t i=0; i<m_ncomp; ++i) {
+        numEqDof.push_back(g_inputdeck.get< tag::ndof >());
+      }
+
+      // volume fractions are P0Pm (ndof = 1) for multi-material simulations
+      auto nmat = g_inputdeck.get< tag::multimat, tag::nmat >();<--- Shadow variable
+      if(nmat > 1)
+        for (std::size_t k=0; k<nmat; ++k)
+          numEqDof[volfracIdx(nmat, k)] = 1;
+    }
+
+    //! Determine elements that lie inside the user-defined IC box
+    //! \param[in] geoElem Element geometry array
+    //! \param[in] nielem Number of internal elements
+    //! \param[in,out] inbox List of nodes at which box user ICs are set for
+    //!    each IC box
+    void IcBoxElems( const tk::Fields& geoElem,
+      std::size_t nielem,
+      std::vector< std::unordered_set< std::size_t > >& inbox ) const
+    {
+      tk::BoxElems< eq >(geoElem, nielem, inbox);
+    }
+
+    //! Find how many 'stiff equations', which are the inverse
+    //! deformation equations because of plasticity
+    //! \return number of stiff equations
+    std::size_t nstiffeq() const
+    {
+      const auto& solidx = g_inputdeck.get< tag::matidxmap, tag::solidx >();
+      std::size_t nmat = g_inputdeck.get< tag::multimat, tag::nmat >();<--- Shadow variable
+      return 9*numSolids(nmat, solidx);
+    }
+
+    //! Find how many 'non-stiff equations', which are the inverse
+    //! deformation equations because of plasticity
+    //! \return number of stiff equations
+    std::size_t nnonstiffeq() const
+    {
+      return m_ncomp-nstiffeq();
+    }
+
+    //! Locate the stiff equations.
+    //! \param[out] stiffEqIdx list with pointers to stiff equations
+    void setStiffEqIdx( std::vector< std::size_t >& stiffEqIdx ) const
+    {
+      stiffEqIdx.resize(nstiffeq(), 0);
+      const auto& solidx = g_inputdeck.get< tag::matidxmap, tag::solidx >();
+      std::size_t nmat = g_inputdeck.get< tag::multimat, tag::nmat >();<--- Shadow variable
+      std::size_t icnt = 0;
+      for (std::size_t k=0; k<nmat; ++k)
+        if (solidx[k] > 0)
+          for (std::size_t i=0; i<3; ++i)
+            for (std::size_t j=0; j<3; ++j)
+            {
+              stiffEqIdx[icnt] =
+                inciter::deformIdx(nmat, solidx[k], i, j);
+              icnt++;
+            }
+    }
+
+    //! Locate the nonstiff equations.
+    //! \param[out] nonStiffEqIdx list with pointers to nonstiff equations
+    void setNonStiffEqIdx( std::vector< std::size_t >& nonStiffEqIdx ) const
+    {
+      nonStiffEqIdx.resize(nnonstiffeq(), 0);
+      for (std::size_t icomp=0; icomp<nnonstiffeq(); icomp++)
+        nonStiffEqIdx[icomp] = icomp;
+    }
 
-} //inciter::
-
-#endif // MultiMatBoxInitialization_h
+    //! Initialize the compressible flow equations, prepare for time integration
+    //! \param[in] L Block diagonal mass matrix
+    //! \param[in] inpoel Element-node connectivity
+    //! \param[in] coord Array of nodal coordinates
+    //! \param[in] inbox List of elements at which box user ICs are set for
+    //!   each IC box
+    //! \param[in] elemblkid Element ids associated with mesh block ids where
+    //!   user ICs are set
+    //! \param[in,out] unk Array of unknowns
+    //! \param[in] t Physical time
+    //! \param[in] nielem Number of internal elements
+    void initialize( const tk::Fields& L,
+      const std::vector< std::size_t >& inpoel,
+      const tk::UnsMesh::Coords& coord,
+      const std::vector< std::unordered_set< std::size_t > >& inbox,
+      const std::unordered_map< std::size_t, std::set< std::size_t > >&
+        elemblkid,
+      tk::Fields& unk,
+      tk::real t,
+      const std::size_t nielem ) const
+    {
+      tk::initialize( m_ncomp, m_mat_blk, L, inpoel, coord,
+                      Problem::initialize, unk, t, nielem );
+
+      const auto rdof = g_inputdeck.get< tag::rdof >();
+      const auto& ic = g_inputdeck.get< tag::ic >();
+      const auto& icbox = ic.get< tag::box >();
+      const auto& icmbk = ic.get< tag::meshblock >();
+
+      const auto& bgpre = ic.get< tag::pressure >();
+      const auto& bgtemp = ic.get< tag::temperature >();
+
+      // Set initial conditions inside user-defined IC boxes and mesh blocks
+      std::vector< tk::real > s(m_ncomp, 0.0);
+      for (std::size_t e=0; e<nielem; ++e) {
+        // inside user-defined box
+        if (!icbox.empty()) {
+          std::size_t bcnt = 0;
+          for (const auto& b : icbox) {   // for all boxes
+            if (inbox.size() > bcnt && inbox[bcnt].find(e) != inbox[bcnt].end())
+            {
+              std::vector< tk::real > box
+                { b.template get< tag::xmin >(), b.template get< tag::xmax >(),
+                  b.template get< tag::ymin >(), b.template get< tag::ymax >(),
+                  b.template get< tag::zmin >(), b.template get< tag::zmax >() };
+              auto V_ex = (box[1]-box[0]) * (box[3]-box[2]) * (box[5]-box[4]);
+              for (std::size_t c=0; c<m_ncomp; ++c) {
+                auto mark = c*rdof;
+                s[c] = unk(e,mark);
+                // set high-order DOFs to zero
+                for (std::size_t i=1; i<rdof; ++i)
+                  unk(e,mark+i) = 0.0;
+              }
+              initializeBox<ctr::boxList>( m_mat_blk, V_ex, t, b, bgpre,
+                bgtemp, s );
+              // store box-initialization in solution vector
+              for (std::size_t c=0; c<m_ncomp; ++c) {
+                auto mark = c*rdof;
+                unk(e,mark) = s[c];
+              }
+            }
+            ++bcnt;
+          }
+        }
+
+        // inside user-specified mesh blocks
+        if (!icmbk.empty()) {
+          for (const auto& b : icmbk) { // for all blocks
+            auto blid = b.get< tag::blockid >();
+            auto V_ex = b.get< tag::volume >();
+            if (elemblkid.find(blid) != elemblkid.end()) {
+              const auto& elset = tk::cref_find(elemblkid, blid);
+              if (elset.find(e) != elset.end()) {
+                initializeBox<ctr::meshblockList>( m_mat_blk, V_ex, t, b,
+                  bgpre, bgtemp, s );
+                // store initialization in solution vector
+                for (std::size_t c=0; c<m_ncomp; ++c) {
+                  auto mark = c*rdof;
+                  unk(e,mark) = s[c];
+                }
+              }
+            }
+          }
+        }
+      }
+    }
+
+    //! Save initial densities for all materials
+    //! \param[out] rho0mat List of initial densities
+    void setRho0mat( std::vector< tk::real >& rho0mat ) const
+    {
+      std::size_t nmat = g_inputdeck.get< tag::multimat, tag::nmat >();<--- Shadow variable
+      rho0mat.resize( nmat, 0.0 );
+      const auto& ic = g_inputdeck.get< tag::ic >();
+      const auto& icbox = ic.get< tag::box >();
+      const auto& icmbk = ic.get< tag::meshblock >();
+      // Get background properties
+      std::size_t k = ic.get< tag::materialid >() - 1;
+      tk::real pr = ic.get< tag::pressure >();
+      tk::real tmp = ic.get< tag::temperature >();
+      rho0mat[k] = m_mat_blk[k].compute< EOS::density >(pr, tmp);
+
+      // Check inside used defined box
+      if (!icbox.empty())
+      {
+        for (const auto& b : icbox) {   // for all boxes
+          k = b.template get< tag::materialid >() - 1;
+          pr = b.template get< tag::pressure >();
+          tmp = b.template get< tag::temperature >();
+          rho0mat[k] = m_mat_blk[k].compute< EOS::density >(pr, tmp);
+        }
+      }
+
+      // Check inside user-specified mesh blocks
+      if (!icmbk.empty())
+      {
+        for (const auto& b : icmbk) { // for all blocks
+          k = b.template get< tag::materialid >() - 1;
+          pr = b.template get< tag::pressure >();
+          tmp = b.template get< tag::temperature >();
+          rho0mat[k] = m_mat_blk[k].compute< EOS::density >(pr, tmp);
+        }
+      }
+    }
+
+    //! Compute density constraint for a given material
+    //! \param[in] nelem Number of elements
+    //! \param[in] unk Array of unknowns
+    //! \param[in] rho0mat List of initial densities
+    //! \param[out] densityConstr Density Constraint: rho/(rho0*det(g))
+    void computeDensityConstr( std::size_t nelem,
+                               tk::Fields& unk,<--- Parameter 'unk' can be declared with const
+                               std::vector< tk::real >& rho0mat,<--- Parameter 'rho0mat' can be declared with const
+                               std::vector< tk::real >& densityConstr) const
+    {
+      const auto& solidx = g_inputdeck.get< tag::matidxmap, tag::solidx >();
+      std::size_t rdof = g_inputdeck.get< tag::rdof >();
+      std::size_t nmat = g_inputdeck.get< tag::multimat, tag::nmat >();<--- Shadow variable
+      for (std::size_t e=0; e<nelem; ++e)
+        densityConstr[e] = 0.0;
+      for (std::size_t imat=0; imat<nmat; ++imat)
+        if (solidx[imat] > 0)
+        {
+          for (std::size_t e=0; e<nelem; ++e)
+          {
+            // Retrieve unknowns
+            tk::real arho = unk(e, densityDofIdx(nmat, imat, rdof, 0));
+            std::array< std::array< tk::real, 3 >, 3 > g;
+            for (std::size_t i=0; i<3; ++i)
+              for (std::size_t j=0; j<3; ++j)
+                g[i][j] = unk(e, deformDofIdx(nmat, solidx[imat], i, j, rdof, 0));
+            // Compute determinant of g
+            tk::real detg = tk::determinant(g);
+            // Compute constraint measure
+            densityConstr[e] += arho/(rho0mat[imat]*detg);
+          }
+        }
+        else
+        {
+          for (std::size_t e=0; e<nelem; ++e)
+          {
+            // Retrieve alpha and add it to the constraint measure
+            tk::real alpha = unk(e, volfracDofIdx(nmat, imat, rdof, 0));
+            densityConstr[e] += alpha;
+          }
+        }
+    }
+
+    //! Compute the left hand side block-diagonal mass matrix
+    //! \param[in] geoElem Element geometry array
+    //! \param[in,out] l Block diagonal mass matrix
+    void lhs( const tk::Fields& geoElem, tk::Fields& l ) const {
+      const auto ndof = g_inputdeck.get< tag::ndof >();
+      // Unlike Compflow and Transport, there is a weak reconstruction about
+      // conservative variable after limiting function which will require the
+      // size of left hand side vector to be rdof
+      tk::mass( m_ncomp, ndof, geoElem, l );
+    }
+
+    //! Update the interface cells to first order dofs
+    //! \param[in] unk Array of unknowns
+    //! \param[in] nielem Number of internal elements
+//    //! \param[in,out] ndofel Array of dofs
+    //! \details This function resets the high-order terms in interface cells.
+    void updateInterfaceCells( tk::Fields& unk,<--- Parameter 'unk' can be declared with const
+      std::size_t nielem,
+      std::vector< std::size_t >& /*ndofel*/ ) const
+    {
+      auto intsharp =
+        g_inputdeck.get< tag::multimat, tag::intsharp >();
+      // If this cell is not material interface, return this function
+      if(not intsharp)  return;
+
+      auto rdof = g_inputdeck.get< tag::rdof >();
+      auto nmat = g_inputdeck.get< tag::multimat, tag::nmat >();<--- Shadow variable
+      const auto& solidx = g_inputdeck.get<
+        tag::matidxmap, tag::solidx >();
+
+      for (std::size_t e=0; e<nielem; ++e) {
+        std::vector< std::size_t > matInt(nmat, 0);
+        std::vector< tk::real > alAvg(nmat, 0.0);
+        for (std::size_t k=0; k<nmat; ++k)
+          alAvg[k] = unk(e, volfracDofIdx(nmat,k,rdof,0));
+        auto intInd = interfaceIndicator(nmat, alAvg, matInt);
+
+        // interface cells cannot be high-order
+        if (intInd) {
+          //ndofel[e] = 1;
+          for (std::size_t k=0; k<nmat; ++k) {
+            if (matInt[k]) {
+              for (std::size_t i=1; i<rdof; ++i) {
+                unk(e, densityDofIdx(nmat,k,rdof,i)) = 0.0;
+                unk(e, energyDofIdx(nmat,k,rdof,i)) = 0.0;
+              }
+              if (solidx[k] > 0) {
+                for (std::size_t i=0; i<3; ++i)
+                  for (std::size_t j=0; j<3; ++j)
+                    for (std::size_t idof=1; idof<rdof; ++idof) {
+                      unk(e, deformDofIdx(nmat,solidx[k],i,j,rdof,idof)) = 0.0;
+                    }
+              }
+            }
+          }
+          for (std::size_t idir=0; idir<3; ++idir) {
+            for (std::size_t i=1; i<rdof; ++i) {
+              unk(e, momentumDofIdx(nmat,idir,rdof,i)) = 0.0;
+            }
+          }
+        }
+      }
+    }
+
+    //! Update the primitives for this PDE system
+    //! \param[in] unk Array of unknowns
+    //! \param[in] L The left hand side block-diagonal mass matrix
+    //! \param[in] geoElem Element geometry array
+    //! \param[in,out] prim Array of primitives
+    //! \param[in] nielem Number of internal elements
+    //! \details This function computes and stores the dofs for primitive
+    //!   quantities, which are required for obtaining reconstructed states used
+    //!   in the Riemann solver. See /PDE/Riemann/AUSM.hpp, where the
+    //!   normal velocity for advection is calculated from independently
+    //!   reconstructed velocities.
+    void updatePrimitives( const tk::Fields& unk,
+                           const tk::Fields& L,
+                           const tk::Fields& geoElem,
+                           tk::Fields& prim,<--- Parameter 'prim' can be declared with const
+                           std::size_t nielem ) const
+    {
+      const auto rdof = g_inputdeck.get< tag::rdof >();<--- Variable 'rdof' is assigned a value that is never used.
+      const auto ndof = g_inputdeck.get< tag::ndof >();<--- Variable 'ndof' is assigned a value that is never used.
+      auto nmat = g_inputdeck.get< tag::multimat, tag::nmat >();<--- Shadow variable<--- Variable 'nmat' is assigned a value that is never used.
+      const auto& solidx = g_inputdeck.get< tag::matidxmap, tag::solidx >();
+
+      Assert( unk.nunk() == prim.nunk(), "Number of unknowns in solution "
+              "vector and primitive vector at recent time step incorrect" );
+      Assert( unk.nprop() == rdof*m_ncomp, "Number of components in solution "
+              "vector must equal "+ std::to_string(rdof*m_ncomp) );
+      Assert( prim.nprop() == rdof*m_nprim, "Number of components in vector of "
+              "primitive quantities must equal "+ std::to_string(rdof*m_nprim) );
+
+      for (std::size_t e=0; e<nielem; ++e)
+      {
+        std::vector< tk::real > R(m_nprim*ndof, 0.0);
+
+        auto ng = tk::NGvol(ndof);
+
+        // arrays for quadrature points
+        std::array< std::vector< tk::real >, 3 > coordgp;
+        std::vector< tk::real > wgp;
+
+        coordgp[0].resize( ng );
+        coordgp[1].resize( ng );
+        coordgp[2].resize( ng );
+        wgp.resize( ng );
+
+        tk::GaussQuadratureTet( ng, coordgp, wgp );
+
+        // Loop over quadrature points in element e
+        for (std::size_t igp=0; igp<ng; ++igp)
+        {
+          // Compute the basis function
+          auto B =
+            tk::eval_basis( ndof, coordgp[0][igp], coordgp[1][igp], coordgp[2][igp] );
+
+          auto w = wgp[igp] * geoElem(e, 0);
+
+          auto state = tk::eval_state( m_ncomp, rdof, ndof, e, unk, B );
+
+          // bulk density at quadrature point
+          tk::real rhob(0.0);
+          for (std::size_t k=0; k<nmat; ++k)
+            rhob += state[densityIdx(nmat, k)];
+
+          // velocity vector at quadrature point
+          std::array< tk::real, 3 >
+            vel{ state[momentumIdx(nmat, 0)]/rhob,
+                 state[momentumIdx(nmat, 1)]/rhob,
+                 state[momentumIdx(nmat, 2)]/rhob };
+
+          std::vector< tk::real > pri(m_nprim, 0.0);
+
+          // Evaluate material pressure at quadrature point
+          for(std::size_t imat = 0; imat < nmat; imat++)
+          {
+            auto alphamat = state[volfracIdx(nmat, imat)];
+            auto arhomat = state[densityIdx(nmat, imat)];
+            auto arhoemat = state[energyIdx(nmat, imat)];
+            auto gmat = getDeformGrad(nmat, imat, state);
+            pri[pressureIdx(nmat,imat)] = m_mat_blk[imat].compute<
+              EOS::pressure >( arhomat, vel[0], vel[1], vel[2], arhoemat,
+              alphamat, imat, gmat );
+
+            pri[pressureIdx(nmat,imat)] = constrain_pressure( m_mat_blk,
+              pri[pressureIdx(nmat,imat)], arhomat, alphamat, imat);
+
+            if (solidx[imat] > 0) {
+              auto asigmat = m_mat_blk[imat].computeTensor< EOS::CauchyStress >(
+              arhomat, vel[0], vel[1], vel[2], arhoemat,
+              alphamat, imat, gmat );
+
+              pri[stressIdx(nmat,solidx[imat],0)] = asigmat[0][0];
+              pri[stressIdx(nmat,solidx[imat],1)] = asigmat[1][1];
+              pri[stressIdx(nmat,solidx[imat],2)] = asigmat[2][2];
+              pri[stressIdx(nmat,solidx[imat],3)] = asigmat[0][1];
+              pri[stressIdx(nmat,solidx[imat],4)] = asigmat[0][2];
+              pri[stressIdx(nmat,solidx[imat],5)] = asigmat[1][2];
+            }
+          }
+
+          // Evaluate bulk velocity at quadrature point
+          for (std::size_t idir=0; idir<3; ++idir) {
+            pri[velocityIdx(nmat,idir)] = vel[idir];
+          }
+
+          for(std::size_t k = 0; k < m_nprim; k++)
+          {
+            auto mark = k * ndof;
+            for(std::size_t idof = 0; idof < ndof; idof++)
+              R[mark+idof] += w * pri[k] * B[idof];
+          }
+        }
+
+        // Update the DG solution of primitive variables
+        for(std::size_t k = 0; k < m_nprim; k++)
+        {
+          auto mark = k * ndof;
+          auto rmark = k * rdof;
+          for(std::size_t idof = 0; idof < ndof; idof++)
+          {
+            prim(e, rmark+idof) = R[mark+idof] / L(e, mark+idof);
+            if(fabs(prim(e, rmark+idof)) < 1e-16)
+              prim(e, rmark+idof) = 0;
+          }
+        }
+      }
+    }
+
+    //! Clean up the state of trace materials for this PDE system
+    //! \param[in] t Physical time
+    //! \param[in] geoElem Element geometry array
+    //! \param[in,out] unk Array of unknowns
+    //! \param[in,out] prim Array of primitives
+    //! \param[in] nielem Number of internal elements
+    //! \details This function cleans up the state of materials present in trace
+    //!   quantities in each cell. Specifically, the state of materials with
+    //!   very low volume-fractions in a cell is replaced by the state of the
+    //!   material which is present in the largest quantity in that cell. This
+    //!   becomes necessary when shocks pass through cells which contain a very
+    //!   small amount of material. The state of that tiny material might
+    //!   become unphysical and cause solution to diverge; thus requiring such
+    //!   a "reset".
+    void cleanTraceMaterial( tk::real t,
+                             const tk::Fields& geoElem,
+                             tk::Fields& unk,
+                             tk::Fields& prim,
+                             std::size_t nielem ) const
+    {
+      [[maybe_unused]] const auto rdof = g_inputdeck.get< tag::rdof >();
+      auto nmat = g_inputdeck.get< tag::multimat, tag::nmat >();<--- Shadow variable<--- Variable 'nmat' is assigned a value that is never used.
+
+      Assert( unk.nunk() == prim.nunk(), "Number of unknowns in solution "
+              "vector and primitive vector at recent time step incorrect" );
+      Assert( unk.nprop() == rdof*m_ncomp, "Number of components in solution "
+              "vector must equal "+ std::to_string(rdof*m_ncomp) );
+      Assert( prim.nprop() == rdof*m_nprim, "Number of components in vector of "
+              "primitive quantities must equal "+ std::to_string(rdof*m_nprim) );
+
+      auto neg_density = cleanTraceMultiMat(t, nielem, m_mat_blk, geoElem, nmat,
+        unk, prim);
+
+      if (neg_density) Throw("Negative partial density.");
+    }
+
+    //! Reconstruct second-order solution from first-order
+    //! \param[in] geoElem Element geometry array
+    //! \param[in] fd Face connectivity and boundary conditions object
+    //! \param[in] esup Elements-surrounding-nodes connectivity
+    //! \param[in] inpoel Element-node connectivity
+    //! \param[in] coord Array of nodal coordinates
+    //! \param[in,out] U Solution vector at recent time step
+    //! \param[in,out] P Vector of primitives at recent time step
+    void reconstruct( tk::real,
+                      const tk::Fields&,
+                      const tk::Fields& geoElem,
+                      const inciter::FaceData& fd,
+                      const std::map< std::size_t, std::vector< std::size_t > >&
+                        esup,
+                      const std::vector< std::size_t >& inpoel,
+                      const tk::UnsMesh::Coords& coord,
+                      tk::Fields& U,
+                      tk::Fields& P ) const
+    {
+      const auto rdof = g_inputdeck.get< tag::rdof >();
+      const auto ndof = g_inputdeck.get< tag::ndof >();
+
+      bool is_p0p1(false);<--- Variable 'is_p0p1' is assigned a value that is never used.
+      if (rdof == 4 && ndof == 1)
+        is_p0p1 = true;<--- Variable 'is_p0p1' is assigned a value that is never used.
+
+      const auto nelem = fd.Esuel().size()/4;<--- Variable 'nelem' is assigned a value that is never used.
+      auto nmat = g_inputdeck.get< tag::multimat, tag::nmat >();<--- Shadow variable<--- Variable 'nmat' is assigned a value that is never used.
+
+      Assert( U.nprop() == rdof*m_ncomp, "Number of components in solution "
+              "vector must equal "+ std::to_string(rdof*m_ncomp) );
+
+      //----- reconstruction of conserved quantities -----
+      //--------------------------------------------------
+      // specify how many variables need to be reconstructed
+      std::vector< std::size_t > vars;
+      for (std::size_t c=0; c<m_ncomp; ++c) vars.push_back(c);
+      // If DG is applied, reconstruct only volume fractions
+      if (!is_p0p1 && ndof > 1)
+      {
+        vars.clear();
+        for (std::size_t k=0; k<nmat; ++k) vars.push_back(volfracIdx(nmat, k));
+      }
+
+      // 1. solve 3x3 least-squares system
+      for (std::size_t e=0; e<nelem; ++e)
+      {
+        // Reconstruct second-order dofs of volume-fractions in Taylor space
+        // using nodal-stencils, for a good interface-normal estimate
+        tk::recoLeastSqExtStencil( rdof, e, esup, inpoel, geoElem, U, vars );
+      }
+
+      // 2. transform reconstructed derivatives to Dubiner dofs
+      tk::transform_P0P1(rdof, nelem, inpoel, coord, U, vars);
+
+      //----- reconstruction of primitive quantities -----
+      //--------------------------------------------------
+      // For multimat, conserved and primitive quantities are reconstructed
+      // separately.
+      if (is_p0p1) {
+        vars.clear();
+        for (std::size_t c=0; c<m_nprim; ++c) vars.push_back(c);
+
+        // 1.
+        for (std::size_t e=0; e<nelem; ++e)
+        {
+          // Reconstruct second-order dofs of volume-fractions in Taylor space
+          // using nodal-stencils, for a good interface-normal estimate
+          tk::recoLeastSqExtStencil( rdof, e, esup, inpoel, geoElem, P, vars );
+        }
+
+        // 2.
+        tk::transform_P0P1(rdof, nelem, inpoel, coord, P, vars);
+      }
+    }
+
+    //! Limit second-order solution, and primitive quantities separately
+    //! \param[in] t Physical time
+    //! \param[in] geoFace Face geometry array
+    //! \param[in] geoElem Element geometry array
+    //! \param[in] fd Face connectivity and boundary conditions object
+    //! \param[in] esup Elements-surrounding-nodes connectivity
+    //! \param[in] inpoel Element-node connectivity
+    //! \param[in] coord Array of nodal coordinates
+    //! \param[in] ndofel Vector of local number of degrees of freedome
+    //! \param[in] gid Local->global node id map
+    //! \param[in] bid Local chare-boundary node ids (value) associated to
+    //!   global node ids (key)
+    //! \param[in] uNodalExtrm Chare-boundary nodal extrema for conservative
+    //!   variables
+    //! \param[in] pNodalExtrm Chare-boundary nodal extrema for primitive
+    //!   variables
+    //! \param[in] mtInv Inverse of Taylor mass matrix
+    //! \param[in,out] U Solution vector at recent time step
+    //! \param[in,out] P Vector of primitives at recent time step
+    //! \param[in,out] shockmarker Vector of shock-marker values
+    void limit( [[maybe_unused]] tk::real t,
+                const tk::Fields& geoFace,
+                const tk::Fields& geoElem,
+                const inciter::FaceData& fd,
+                const std::map< std::size_t, std::vector< std::size_t > >& esup,
+                const std::vector< std::size_t >& inpoel,
+                const tk::UnsMesh::Coords& coord,
+                const std::vector< std::size_t >& ndofel,
+                const std::vector< std::size_t >& gid,
+                const std::unordered_map< std::size_t, std::size_t >& bid,
+                const std::vector< std::vector<tk::real> >& uNodalExtrm,
+                const std::vector< std::vector<tk::real> >& pNodalExtrm,
+                const std::vector< std::vector<tk::real> >& mtInv,
+                tk::Fields& U,
+                tk::Fields& P,
+                std::vector< std::size_t >& shockmarker ) const
+    {
+      Assert( U.nunk() == P.nunk(), "Number of unknowns in solution "
+              "vector and primitive vector at recent time step incorrect" );
+
+      const auto limiter = g_inputdeck.get< tag::limiter >();
+      auto nmat = g_inputdeck.get< tag::multimat, tag::nmat >();<--- Shadow variable
+      const auto rdof = g_inputdeck.get< tag::rdof >();
+      const auto& solidx = g_inputdeck.get<
+        tag::matidxmap, tag::solidx >();
+
+      // limit vectors of conserved and primitive quantities
+      if (limiter == ctr::LimiterType::SUPERBEEP1)
+      {
+        SuperbeeMultiMat_P1( fd.Esuel(), inpoel, ndofel,
+          coord, solidx, U, P, nmat );
+      }
+      else if (limiter == ctr::LimiterType::VERTEXBASEDP1 && rdof == 4)
+      {
+        VertexBasedMultiMat_P1( esup, inpoel, ndofel, fd.Esuel().size()/4,
+          m_mat_blk, fd, geoFace, geoElem, coord, flux, solidx, U, P,
+          nmat, shockmarker );
+      }
+      else if (limiter == ctr::LimiterType::VERTEXBASEDP1 && rdof == 10)
+      {
+        VertexBasedMultiMat_P2( esup, inpoel, ndofel, fd.Esuel().size()/4,
+          m_mat_blk, fd, geoFace, geoElem, coord, gid, bid,
+          uNodalExtrm, pNodalExtrm, mtInv, flux, solidx, U, P, nmat,
+          shockmarker );
+      }
+      else if (limiter != ctr::LimiterType::NOLIMITER)
+      {
+        Throw("Limiter type not configured for multimat.");
+      }
+    }
+
+    //! Apply CPL to the conservative variable solution for this PDE system
+    //! \param[in] prim Array of primitive variables
+    //! \param[in] geoElem Element geometry array
+    //! \param[in] inpoel Element-node connectivity
+    //! \param[in] coord Array of nodal coordinates
+    //! \param[in,out] unk Array of conservative variables
+    //! \param[in] nielem Number of internal elements
+    //! \details This function applies CPL to obtain consistent dofs for
+    //!   conservative quantities based on the limited primitive quantities.
+    //!   See Pandare et al. (2023). On the Design of Stable,
+    //!   Consistent, and Conservative High-Order Methods for Multi-Material
+    //!   Hydrodynamics. J Comp Phys, 112313.
+    void CPL( const tk::Fields& prim,
+      const tk::Fields& geoElem,
+      const std::vector< std::size_t >& inpoel,
+      const tk::UnsMesh::Coords& coord,
+      tk::Fields& unk,
+      std::size_t nielem ) const
+    {
+      [[maybe_unused]] const auto rdof = g_inputdeck.get< tag::rdof >();
+      auto nmat = g_inputdeck.get< tag::multimat, tag::nmat >();<--- Shadow variable<--- Variable 'nmat' is assigned a value that is never used.
+
+      Assert( unk.nunk() == prim.nunk(), "Number of unknowns in solution "
+              "vector and primitive vector at recent time step incorrect" );
+      Assert( unk.nprop() == rdof*m_ncomp, "Number of components in solution "
+              "vector must equal "+ std::to_string(rdof*m_ncomp) );
+      Assert( prim.nprop() == rdof*m_nprim, "Number of components in vector of "
+              "primitive quantities must equal "+ std::to_string(rdof*m_nprim) );
+
+      correctLimConservMultiMat(nielem, m_mat_blk, nmat, inpoel,
+        coord, geoElem, prim, unk);
+    }
+
+    //! Return cell-average deformation gradient tensor
+    //! \param[in] unk Solution vector at recent time step
+    //! \param[in] nielem Number of internal elements
+    //! \details This function returns the bulk cell-average inverse
+    //!   deformation gradient tensor
+    std::array< std::vector< tk::real >, 9 > cellAvgDeformGrad(
+      const tk::Fields& unk,
+      std::size_t nielem ) const
+    {
+      const auto rdof = g_inputdeck.get< tag::rdof >();
+      auto nmat = g_inputdeck.get< tag::multimat, tag::nmat >();<--- Shadow variable
+      const auto& solidx = g_inputdeck.get< tag::matidxmap, tag::solidx >();
+
+      std::array< std::vector< tk::real >, 9 > gb;
+      if (inciter::haveSolid(nmat, solidx)) {
+        for (auto& gij : gb)
+          gij.resize(nielem, 0.0);
+        for (std::size_t e=0; e<nielem; ++e) {
+          for (std::size_t k=0; k<nmat; ++k) {
+            if (solidx[k] > 0) {
+              for (std::size_t i=0; i<3; ++i)
+                for (std::size_t j=0; j<3; ++j)
+                  gb[3*i+j][e] += unk(e, volfracDofIdx(nmat,k,rdof,0)) *
+                    unk(e,deformDofIdx(nmat,solidx[k],i,j,rdof,0));
+            }
+          }
+        }
+      }
+
+      return gb;
+    }
+
+
+    //! Compute right hand side
+    //! \param[in] t Physical time
+    //! \param[in] geoFace Face geometry array
+    //! \param[in] geoElem Element geometry array
+    //! \param[in] fd Face connectivity and boundary conditions object
+    //! \param[in] inpoel Element-node connectivity
+    //! \param[in] coord Array of nodal coordinates
+    //! \param[in] U Solution vector at recent time step
+    //! \param[in] P Primitive vector at recent time step
+    //! \param[in] ndofel Vector of local number of degrees of freedom
+    //! \param[in] rho0mat Initial densities of all materials
+    //! \param[in] dt Delta time
+    //! \param[in,out] R Right-hand side vector computed
+    void rhs( tk::real t,
+              const tk::Fields& geoFace,
+              const tk::Fields& geoElem,
+              const inciter::FaceData& fd,
+              const std::vector< std::size_t >& inpoel,
+              const std::vector< std::unordered_set< std::size_t > >&,
+              const tk::UnsMesh::Coords& coord,
+              const tk::Fields& U,
+              const tk::Fields& P,
+              const std::vector< std::size_t >& ndofel,
+              const std::vector< tk::real >& rho0mat,
+              const tk::real dt,
+              tk::Fields& R ) const
+    {
+      const auto ndof = g_inputdeck.get< tag::ndof >();
+      const auto rdof = g_inputdeck.get< tag::rdof >();
+      auto nmat = g_inputdeck.get< tag::multimat, tag::nmat >();<--- Shadow variable
+      const auto intsharp =
+        g_inputdeck.get< tag::multimat, tag::intsharp >();
+      const auto& solidx = inciter::g_inputdeck.get<
+        tag::matidxmap, tag::solidx >();
+      auto nsld = numSolids(nmat, solidx);
+
+      const auto nelem = fd.Esuel().size()/4;
+
+      Assert( U.nunk() == P.nunk(), "Number of unknowns in solution "
+              "vector and primitive vector at recent time step incorrect" );
+      Assert( U.nunk() == R.nunk(), "Number of unknowns in solution "
+              "vector and right-hand side at recent time step incorrect" );
+      Assert( U.nprop() == rdof*m_ncomp, "Number of components in solution "
+              "vector must equal "+ std::to_string(rdof*m_ncomp) );
+      Assert( P.nprop() == rdof*m_nprim, "Number of components in primitive "
+              "vector must equal "+ std::to_string(rdof*m_nprim) );
+      Assert( R.nprop() == ndof*m_ncomp, "Number of components in right-hand "
+              "side vector must equal "+ std::to_string(ndof*m_ncomp) );
+      Assert( fd.Inpofa().size()/3 == fd.Esuf().size()/2,
+              "Mismatch in inpofa size" );
+
+      // set rhs to zero
+      R.fill(0.0);
+
+      // Allocate space for Riemann derivatives used in non-conservative terms.
+      // The following Riemann derivatives are stored, in order:
+      // 1) 3*nmat terms: derivatives of partial pressure of each material,
+      //    for the energy equations.
+      // 2) ndof terms: derivatives of Riemann velocity times the basis
+      //    function, for the volume fraction equations.
+      // 3) nmat*3*3*9 terms: 3 derivatives of u_l*g_ij for each material, for
+      //    the deformation gradient equations.
+      // 4) 3*nsld terms: 3 derivatives of \alpha \sigma_ij for each solid
+      //    material, for the energy equations.
+      std::vector< std::vector< tk::real > >
+        riemannDeriv(3*nmat+ndof+3*nsld, std::vector<tk::real>(U.nunk(),0.0));
+
+      // vectors to store the data of riemann velocity used for reconstruction
+      // in volume fraction equation
+      std::vector< std::vector< tk::real > > vriem( U.nunk() );
+      std::vector< std::vector< tk::real > > riemannLoc( U.nunk() );
+
+      // configure a no-op lambda for prescribed velocity
+      auto velfn = []( ncomp_t, tk::real, tk::real, tk::real, tk::real ){
+        return tk::VelFn::result_type(); };
+
+      // compute internal surface flux integrals
+      tk::surfInt( nmat, m_mat_blk, t, ndof, rdof, inpoel, solidx,
+                   coord, fd, geoFace, geoElem, m_riemann, velfn, U, P, ndofel,
+                   dt, R, vriem, riemannLoc, riemannDeriv, intsharp );
+
+      // compute optional source term
+      tk::srcInt( m_mat_blk, t, ndof, fd.Esuel().size()/4, inpoel,
+                  coord, geoElem, Problem::src, ndofel, R, nmat );
+
+      if(ndof > 1)
+        // compute volume integrals
+        tk::volInt( nmat, t, m_mat_blk, ndof, rdof, nelem,
+                    inpoel, coord, geoElem, flux, velfn, U, P, ndofel, R,
+                    intsharp );
+
+      // compute boundary surface flux integrals
+      for (const auto& b : m_bc)
+        tk::bndSurfInt( nmat, m_mat_blk, ndof, rdof,
+                        b.first, fd, geoFace, geoElem, inpoel, coord, t,
+                        m_riemann, velfn, b.second, U, P, ndofel, R, vriem,
+                        riemannLoc, riemannDeriv, intsharp );
+
+      Assert( riemannDeriv.size() == 3*nmat+ndof+3*nsld, "Size of "
+              "Riemann derivative vector incorrect" );
+
+      // get derivatives from riemannDeriv
+      for (std::size_t k=0; k<riemannDeriv.size(); ++k)
+      {
+        Assert( riemannDeriv[k].size() == U.nunk(), "Riemann derivative vector "
+                "for non-conservative terms has incorrect size" );
+        for (std::size_t e=0; e<U.nunk(); ++e)
+          riemannDeriv[k][e] /= geoElem(e, 0);
+      }
+
+      // compute volume integrals of non-conservative terms
+      tk::nonConservativeInt( nmat, m_mat_blk, ndof, rdof, nelem,
+                              inpoel, coord, geoElem, U, P, riemannDeriv,
+                              ndofel, R, intsharp );
+
+      // Compute integrals for inverse deformation correction in solid materials
+      if (inciter::haveSolid(nmat, solidx) &&
+        g_inputdeck.get< tag::multimat, tag::rho0constraint >())
+        tk::solidTermsVolInt( nmat, m_mat_blk, ndof, rdof, nelem,
+                              inpoel, coord, geoElem, U, P, ndofel,
+                              rho0mat, dt, R);
+
+      // compute finite pressure relaxation terms
+      if (g_inputdeck.get< tag::multimat, tag::prelax >())
+      {
+        const auto ct = g_inputdeck.get< tag::multimat,
+                                         tag::prelax_timescale >();
+        tk::pressureRelaxationInt( nmat, m_mat_blk, ndof,
+                                   rdof, nelem, inpoel, coord, geoElem, U, P,
+                                   ndofel, ct, R, intsharp );
+      }
+    }
+
+    //! Evaluate the adaptive indicator and mark the ndof for each element
+    //! \param[in] nunk Number of unknowns
+    //! \param[in] coord Array of nodal coordinates
+    //! \param[in] inpoel Element-node connectivity
+    //! \param[in] fd Face connectivity and boundary conditions object
+    //! \param[in] unk Array of unknowns
+    //! \param[in] prim Array of primitive quantities
+    //! \param[in] indicator p-refinement indicator type
+    //! \param[in] ndof Number of degrees of freedom in the solution
+    //! \param[in] ndofmax Max number of degrees of freedom for p-refinement
+    //! \param[in] tolref Tolerance for p-refinement
+    //! \param[in,out] ndofel Vector of local number of degrees of freedome
+    void eval_ndof( std::size_t nunk,
+                    [[maybe_unused]] const tk::UnsMesh::Coords& coord,
+                    [[maybe_unused]] const std::vector< std::size_t >& inpoel,
+                    const inciter::FaceData& fd,
+                    const tk::Fields& unk,
+                    const tk::Fields& prim,
+                    inciter::ctr::PrefIndicatorType indicator,
+                    std::size_t ndof,
+                    std::size_t ndofmax,
+                    tk::real tolref,
+                    std::vector< std::size_t >& ndofel ) const
+    {
+      const auto& esuel = fd.Esuel();
+      auto nmat = g_inputdeck.get< tag::multimat, tag::nmat >();<--- Shadow variable
+
+      if(indicator == inciter::ctr::PrefIndicatorType::SPECTRAL_DECAY)
+        spectral_decay(nmat, nunk, esuel, unk, prim, ndof, ndofmax, tolref,
+          ndofel);
+      else
+        Throw( "No such adaptive indicator type" );
+    }
+
+    //! Compute the minimum time step size
+    //! \param[in] fd Face connectivity and boundary conditions object
+    //! \param[in] geoFace Face geometry array
+    //! \param[in] geoElem Element geometry array
+//    //! \param[in] ndofel Vector of local number of degrees of freedom
+    //! \param[in] U Solution vector at recent time step
+    //! \param[in] P Vector of primitive quantities at recent time step
+    //! \param[in] nielem Number of internal elements
+    //! \return Minimum time step size
+    //! \details The allowable dt is calculated by looking at the maximum
+    //!   wave-speed in elements surrounding each face, times the area of that
+    //!   face. Once the maximum of this quantity over the mesh is determined,
+    //!   the volume of each cell is divided by this quantity. A minimum of this
+    //!   ratio is found over the entire mesh, which gives the allowable dt.
+    tk::real dt( const std::array< std::vector< tk::real >, 3 >&,
+                 const std::vector< std::size_t >&,
+                 const inciter::FaceData& fd,
+                 const tk::Fields& geoFace,
+                 const tk::Fields& geoElem,
+                 const std::vector< std::size_t >& /*ndofel*/,
+                 const tk::Fields& U,
+                 const tk::Fields& P,
+                 const std::size_t nielem ) const
+    {
+      const auto ndof = g_inputdeck.get< tag::ndof >();
+      auto nmat = g_inputdeck.get< tag::multimat, tag::nmat >();<--- Shadow variable
+
+      auto mindt = timeStepSizeMultiMat( m_mat_blk, fd.Esuf(), geoFace, geoElem,
+        nielem, nmat, U, P);
+
+      tk::real dgp = 0.0;
+      if (ndof == 4)
+      {
+        dgp = 1.0;
+      }
+      else if (ndof == 10)
+      {
+        dgp = 2.0;
+      }
+
+      // Scale smallest dt with CFL coefficient and the CFL is scaled by (2*p+1)
+      // where p is the order of the DG polynomial by linear stability theory.
+      mindt /= (2.0*dgp + 1.0);
+      return mindt;
+    }
+
+    //! Compute stiff terms for a single element
+    //! \param[in] e Element number
+    //! \param[in] geoElem Element geometry array
+    //! \param[in] inpoel Element-node connectivity
+    //! \param[in] coord Array of nodal coordinates
+    //! \param[in] U Solution vector at recent time step
+    //! \param[in] P Primitive vector at recent time step
+    //! \param[in] ndofel Vector of local number of degrees of freedom
+    //! \param[in,out] R Right-hand side vector computed
+    void stiff_rhs( std::size_t e,
+                    const tk::Fields& geoElem,
+                    const std::vector< std::size_t >& inpoel,
+                    const tk::UnsMesh::Coords& coord,
+                    const tk::Fields& U,
+                    const tk::Fields& P,
+                    const std::vector< std::size_t >& ndofel,
+                    tk::Fields& R ) const<--- Parameter 'R' can be declared with const
+    {
+      const auto ndof = g_inputdeck.get< tag::ndof >();<--- Variable 'ndof' is assigned a value that is never used.
+      const auto rdof = g_inputdeck.get< tag::rdof >();<--- Variable 'rdof' is assigned a value that is never used.
+      auto nmat = g_inputdeck.get< tag::multimat, tag::nmat >();<--- Shadow variable<--- Variable 'nmat' is assigned a value that is never used.
+      const auto intsharp =<--- Variable 'intsharp' is assigned a value that is never used.
+        g_inputdeck.get< tag::multimat, tag::intsharp >();
+      const auto& solidx = inciter::g_inputdeck.get<
+        tag::matidxmap, tag::solidx >();
+
+      Assert( U.nunk() == P.nunk(), "Number of unknowns in solution "
+              "vector and primitive vector at recent time step incorrect" );
+      Assert( U.nprop() == rdof*m_ncomp, "Number of components in solution "
+              "vector must equal "+ std::to_string(rdof*m_ncomp) );
+      Assert( P.nprop() == rdof*m_nprim, "Number of components in primitive "
+              "vector must equal "+ std::to_string(rdof*m_nprim) );
+      Assert( R.nprop() == ndof*nstiffeq(), "Number of components in "
+              "right-hand side must equal "+ std::to_string(ndof*nstiffeq()) );
+
+      // set rhs to zero for element e
+      for (std::size_t i=0; i<ndof*nstiffeq(); ++i)
+        R(e, i) = 0.0;
+
+      const auto& cx = coord[0];
+      const auto& cy = coord[1];
+      const auto& cz = coord[2];
+
+      auto ncomp = U.nprop()/rdof;
+      auto nprim = P.nprop()/rdof;<--- Shadow variable
+
+      auto ng = tk::NGvol(ndofel[e]);
+
+      // arrays for quadrature points
+      std::array< std::vector< tk::real >, 3 > coordgp;
+      std::vector< tk::real > wgp;
+
+      coordgp[0].resize( ng );
+      coordgp[1].resize( ng );
+      coordgp[2].resize( ng );
+      wgp.resize( ng );
+
+      tk::GaussQuadratureTet( ng, coordgp, wgp );
+
+      // Extract the element coordinates
+      std::array< std::array< tk::real, 3>, 4 > coordel {{
+        {{ cx[ inpoel[4*e  ] ], cy[ inpoel[4*e  ] ], cz[ inpoel[4*e  ] ] }},
+        {{ cx[ inpoel[4*e+1] ], cy[ inpoel[4*e+1] ], cz[ inpoel[4*e+1] ] }},
+        {{ cx[ inpoel[4*e+2] ], cy[ inpoel[4*e+2] ], cz[ inpoel[4*e+2] ] }},
+        {{ cx[ inpoel[4*e+3] ], cy[ inpoel[4*e+3] ], cz[ inpoel[4*e+3] ] }}
+      }};
+
+      // Gaussian quadrature
+      for (std::size_t igp=0; igp<ng; ++igp)
+      {
+        // Compute the coordinates of quadrature point at physical domain
+        auto gp = tk::eval_gp( igp, coordel, coordgp );
+
+        // Compute the basis function
+        auto B = tk::eval_basis( ndofel[e], coordgp[0][igp], coordgp[1][igp],
+                             coordgp[2][igp] );
+
+        auto state = tk::evalPolynomialSol(m_mat_blk, intsharp, ncomp, nprim,
+          rdof, nmat, e, ndofel[e], inpoel, coord, geoElem, gp, B, U, P);
+
+        // compute source
+        // Loop through materials
+        std::size_t ksld = 0;
+        for (std::size_t k=0; k<nmat; ++k)
+        {
+          if (solidx[k] > 0)
+          {
+            tk::real alpha = state[inciter::volfracIdx(nmat, k)];
+            std::array< std::array< tk::real, 3 >, 3 > g;
+            // Compute the source terms
+            for (std::size_t i=0; i<3; ++i)
+              for (std::size_t j=0; j<3; ++j)
+                g[i][j] = state[inciter::deformIdx(nmat,solidx[k],i,j)];
+
+            // Compute Lp
+            // Reference: Ortega, A. L., Lombardini, M., Pullin, D. I., &
+            // Meiron, D. I. (2014). Numerical simulation of elastic–plastic
+            // solid mechanics using an Eulerian stretch tensor approach and
+            // HLLD Riemann solver. Journal of Computational Physics, 257,
+            // 414-441
+            std::array< std::array< tk::real, 3 >, 3 > Lp;
+
+            // 1. Compute dev(sigma)
+            auto sigma_dev = m_mat_blk[k].computeTensor< EOS::CauchyStress >(
+              0.0, 0.0, 0.0, 0.0, 0.0, alpha, k, g );
+            for (std::size_t i=0; i<3; ++i)
+              for (std::size_t j=0; j<3; ++j)
+                sigma_dev[i][j] /= alpha;
+            tk::real sigma_trace =
+              sigma_dev[0][0]+sigma_dev[1][1]+sigma_dev[2][2];
+            for (std::size_t i=0; i<3; ++i)
+              sigma_dev[i][i] -= sigma_trace/3.0;
+
+            // 2. Compute inv(g)
+            double ginv[9];
+            for (std::size_t i=0; i<3; ++i)
+              for (std::size_t j=0; j<3; ++j)
+                ginv[3*i+j] = g[i][j];
+            lapack_int ipiv[3];
+            #ifndef NDEBUG
+            lapack_int ierr =
+            #endif
+              LAPACKE_dgetrf(LAPACK_ROW_MAJOR, 3, 3, ginv, 3, ipiv);
+            Assert(ierr==0, "Lapack error in LU factorization of g");
+            #ifndef NDEBUG
+            lapack_int jerr =
+            #endif
+              LAPACKE_dgetri(LAPACK_ROW_MAJOR, 3, ginv, 3, ipiv);
+            Assert(jerr==0, "Lapack error in inverting g");
+
+            // 3. Compute dev(sigma)*inv(g)
+            std::array< std::array< tk::real, 3 >, 3 > aux_mat;
+            for (std::size_t i=0; i<3; ++i)
+              for (std::size_t j=0; j<3; ++j)
+              {
+                tk::real sum = 0.0;
+                for (std::size_t l=0; l<3; ++l)
+                  sum += sigma_dev[i][l]*ginv[3*l+j];
+                aux_mat[i][j] = sum;
+              }
+
+            // 4. Compute g*(dev(sigma)*inv(g))
+            for (std::size_t i=0; i<3; ++i)
+              for (std::size_t j=0; j<3; ++j)
+              {
+                tk::real sum = 0.0;
+                for (std::size_t l=0; l<3; ++l)
+                  sum += g[i][l]*aux_mat[l][j];
+                Lp[i][j] = sum;
+              }
+
+            // 5. Divide by 2*mu*tau
+            // 'Perfect' plasticity
+            tk::real yield_stress = getmatprop< tag::yield_stress >(k);
+            tk::real equiv_stress = 0.0;
+            for (std::size_t i=0; i<3; ++i)
+              for (std::size_t j=0; j<3; ++j)
+                equiv_stress += sigma_dev[i][j]*sigma_dev[i][j];
+            equiv_stress = std::sqrt(3.0*equiv_stress/2.0);
+            // rel_factor = 1/tau <- Perfect plasticity for now.
+            tk::real rel_factor = 0.0;
+            if (equiv_stress >= yield_stress)
+              rel_factor = yield_stress;
+            tk::real mu = getmatprop< tag::mu >(k);
+            for (std::size_t i=0; i<3; ++i)
+              for (std::size_t j=0; j<3; ++j)
+                Lp[i][j] *= rel_factor/(2.0*mu);
+
+            // Compute the source terms
+            std::vector< tk::real > s(9*ndof, 0.0);
+            for (std::size_t i=0; i<3; ++i)
+              for (std::size_t j=0; j<3; ++j)
+                for (std::size_t idof=0; idof<ndof; ++idof)
+                {
+                  s[(i*3+j)*ndof+idof] = B[idof] * (Lp[i][0]*g[0][j]
+                                                   +Lp[i][1]*g[1][j]
+                                                   +Lp[i][2]*g[2][j]);
+                }
+
+            auto wt = wgp[igp] * geoElem(e, 0);
+
+            // Contribute to the right-hand-side
+            for (std::size_t i=0; i<3; ++i)
+              for (std::size_t j=0; j<3; ++j)
+                for (std::size_t idof=0; idof<ndof; ++idof)
+                {
+                  std::size_t srcId = (i*3+j)*ndof+idof;
+                  std::size_t dofId = solidTensorIdx(ksld,i,j)*ndof+idof;
+                  R(e, dofId) += wt * s[srcId];
+                }
+
+            ksld++;
+          }
+        }
+
+        }
+    }
+
+    //! Extract the velocity field at cell nodes. Currently unused.
+    //! \param[in] U Solution vector at recent time step
+    //! \param[in] N Element node indices
+    //! \return Array of the four values of the velocity field
+    std::array< std::array< tk::real, 4 >, 3 >
+    velocity( const tk::Fields& U,
+              const std::array< std::vector< tk::real >, 3 >&,
+              const std::array< std::size_t, 4 >& N ) const
+    {
+      const auto rdof = g_inputdeck.get< tag::rdof >();
+      auto nmat = g_inputdeck.get< tag::multimat, tag::nmat >();<--- Shadow variable
+
+      std::array< std::array< tk::real, 4 >, 3 > v;
+      v[0] = U.extract( momentumDofIdx(nmat, 0, rdof, 0), N );
+      v[1] = U.extract( momentumDofIdx(nmat, 1, rdof, 0), N );
+      v[2] = U.extract( momentumDofIdx(nmat, 2, rdof, 0), N );
+
+      std::vector< std::array< tk::real, 4 > > ar;
+      ar.resize(nmat);
+      for (std::size_t k=0; k<nmat; ++k)
+        ar[k] = U.extract( densityDofIdx(nmat, k, rdof, 0), N );
+
+      std::array< tk::real, 4 > r{{ 0.0, 0.0, 0.0, 0.0 }};
+      for (std::size_t i=0; i<r.size(); ++i) {
+        for (std::size_t k=0; k<nmat; ++k)
+          r[i] += ar[k][i];
+      }
+
+      std::transform( r.begin(), r.end(), v[0].begin(), v[0].begin(),
+                      []( tk::real s, tk::real& d ){ return d /= s; } );
+      std::transform( r.begin(), r.end(), v[1].begin(), v[1].begin(),
+                      []( tk::real s, tk::real& d ){ return d /= s; } );
+      std::transform( r.begin(), r.end(), v[2].begin(), v[2].begin(),
+                      []( tk::real s, tk::real& d ){ return d /= s; } );
+      return v;
+    }
+
+    //! Return a map that associates user-specified strings to functions
+    //! \return Map that associates user-specified strings to functions that
+    //!   compute relevant quantities to be output to file
+    std::map< std::string, tk::GetVarFn > OutVarFn() const
+    { return MultiMatOutVarFn(); }
+
+    //! Return analytic field names to be output to file
+    //! \return Vector of strings labelling analytic fields output in file
+    std::vector< std::string > analyticFieldNames() const {
+      auto nmat = g_inputdeck.get< eq, tag::nmat >();<--- Shadow variable
+
+      return MultiMatFieldNames(nmat);
+    }
+
+    //! Return time history field names to be output to file
+    //! \return Vector of strings labelling time history fields output in file
+    std::vector< std::string > histNames() const {
+      return MultiMatHistNames();
+    }
+
+    //! Return surface field output going to file
+    std::vector< std::vector< tk::real > >
+    surfOutput( const std::map< int, std::vector< std::size_t > >&,
+                tk::Fields& ) const
+    {
+      std::vector< std::vector< tk::real > > s; // punt for now
+      return s;
+    }
+
+    //! Return time history field output evaluated at time history points
+    //! \param[in] h History point data
+    //! \param[in] inpoel Element-node connectivity
+    //! \param[in] coord Array of nodal coordinates
+    //! \param[in] U Array of unknowns
+    //! \param[in] P Array of primitive quantities
+    //! \return Vector of time history output of bulk flow quantities (density,
+    //!   velocity, total energy, and pressure) evaluated at time history points
+    std::vector< std::vector< tk::real > >
+    histOutput( const std::vector< HistData >& h,
+                const std::vector< std::size_t >& inpoel,
+                const tk::UnsMesh::Coords& coord,
+                const tk::Fields& U,
+                const tk::Fields& P ) const
+    {
+      const auto rdof = g_inputdeck.get< tag::rdof >();
+      auto nmat = g_inputdeck.get< tag::multimat, tag::nmat >();<--- Shadow variable
+
+      const auto& x = coord[0];
+      const auto& y = coord[1];
+      const auto& z = coord[2];
+
+      std::vector< std::vector< tk::real > > Up(h.size());
+
+      std::size_t j = 0;
+      for (const auto& p : h) {
+        auto e = p.get< tag::elem >();
+        auto chp = p.get< tag::coord >();
+
+        // Evaluate inverse Jacobian
+        std::array< std::array< tk::real, 3>, 4 > cp{{
+          {{ x[inpoel[4*e  ]], y[inpoel[4*e  ]], z[inpoel[4*e  ]] }},
+          {{ x[inpoel[4*e+1]], y[inpoel[4*e+1]], z[inpoel[4*e+1]] }},
+          {{ x[inpoel[4*e+2]], y[inpoel[4*e+2]], z[inpoel[4*e+2]] }},
+          {{ x[inpoel[4*e+3]], y[inpoel[4*e+3]], z[inpoel[4*e+3]] }} }};
+        auto J = tk::inverseJacobian( cp[0], cp[1], cp[2], cp[3] );
+
+        // evaluate solution at history-point
+        std::array< tk::real, 3 > dc{{chp[0]-cp[0][0], chp[1]-cp[0][1],
+          chp[2]-cp[0][2]}};
+        auto B = tk::eval_basis(rdof, tk::dot(J[0],dc), tk::dot(J[1],dc),
+          tk::dot(J[2],dc));
+        auto uhp = eval_state(m_ncomp, rdof, rdof, e, U, B);
+        auto php = eval_state(m_nprim, rdof, rdof, e, P, B);
+
+        // store solution in history output vector
+        Up[j].resize(6, 0.0);
+        for (std::size_t k=0; k<nmat; ++k) {
+          Up[j][0] += uhp[densityIdx(nmat,k)];
+          Up[j][4] += uhp[energyIdx(nmat,k)];
+          Up[j][5] += php[pressureIdx(nmat,k)];
+        }
+        Up[j][1] = php[velocityIdx(nmat,0)];
+        Up[j][2] = php[velocityIdx(nmat,1)];
+        Up[j][3] = php[velocityIdx(nmat,2)];
+        ++j;
+      }
+
+      return Up;
+    }
+
+    //! Return names of integral variables to be output to diagnostics file
+    //! \return Vector of strings labelling integral variables output
+    std::vector< std::string > names() const
+    {
+      auto nmat = g_inputdeck.get< tag::multimat, tag::nmat >();<--- Shadow variable
+      return MultiMatDiagNames(nmat);
+    }
+
+    //! Return analytic solution (if defined by Problem) at xi, yi, zi, t
+    //! \param[in] xi X-coordinate at which to evaluate the analytic solution
+    //! \param[in] yi Y-coordinate at which to evaluate the analytic solution
+    //! \param[in] zi Z-coordinate at which to evaluate the analytic solution
+    //! \param[in] t Physical time at which to evaluate the analytic solution
+    //! \return Vector of analytic solution at given location and time
+    std::vector< tk::real >
+    analyticSolution( tk::real xi, tk::real yi, tk::real zi, tk::real t ) const
+    { return Problem::analyticSolution( m_ncomp, m_mat_blk, xi, yi, zi, t ); }
+
+    //! Return analytic solution for conserved variables
+    //! \param[in] xi X-coordinate at which to evaluate the analytic solution
+    //! \param[in] yi Y-coordinate at which to evaluate the analytic solution
+    //! \param[in] zi Z-coordinate at which to evaluate the analytic solution
+    //! \param[in] t Physical time at which to evaluate the analytic solution
+    //! \return Vector of analytic solution at given location and time
+    std::vector< tk::real >
+    solution( tk::real xi, tk::real yi, tk::real zi, tk::real t ) const
+    { return Problem::initialize( m_ncomp, m_mat_blk, xi, yi, zi, t ); }
+
+    //! Return cell-averaged specific total energy for an element
+    //! \param[in] e Element id for which total energy is required
+    //! \param[in] unk Vector of conserved quantities
+    //! \return Cell-averaged specific total energy for given element
+    tk::real sp_totalenergy(std::size_t e, const tk::Fields& unk) const
+    {
+      const auto rdof = g_inputdeck.get< tag::rdof >();
+      auto nmat = g_inputdeck.get< tag::multimat, tag::nmat >();<--- Shadow variable
+
+      tk::real sp_te(0.0);
+      // sum each material total energy
+      for (std::size_t k=0; k<nmat; ++k) {
+        sp_te += unk(e, energyDofIdx(nmat,k,rdof,0));
+      }
+      return sp_te;
+    }
+
+  private:
+    //! Number of components in this PDE system
+    const ncomp_t m_ncomp;
+    //! Number of primitive quantities stored in this PDE system
+    const ncomp_t m_nprim;
+    //! Riemann solver
+    tk::RiemannFluxFn m_riemann;
+    //! BC configuration
+    BCStateFn m_bc;
+    //! EOS material block
+    std::vector< EOS > m_mat_blk;
+
+    //! Evaluate conservative part of physical flux function for this PDE system
+    //! \param[in] ncomp Number of scalar components in this PDE system
+    //! \param[in] ugp Numerical solution at the Gauss point at which to
+    //!   evaluate the flux
+    //! \return Flux vectors for all components in this PDE system
+    //! \note The function signature must follow tk::FluxFn
+    static tk::FluxFn::result_type
+    flux( ncomp_t ncomp,
+          const std::vector< EOS >& mat_blk,
+          const std::vector< tk::real >& ugp,
+          const std::vector< std::array< tk::real, 3 > >& )
+    {
+      auto nmat = g_inputdeck.get< tag::multimat, tag::nmat >();<--- Shadow variable
+
+      return tk::fluxTerms(ncomp, nmat, mat_blk, ugp);
+    }
+
+    //! \brief Boundary state function providing the left and right state of a
+    //!   face at Dirichlet boundaries
+    //! \param[in] ncomp Number of scalar components in this PDE system
+    //! \param[in] mat_blk EOS material block
+    //! \param[in] ul Left (domain-internal) state
+    //! \param[in] x X-coordinate at which to compute the states
+    //! \param[in] y Y-coordinate at which to compute the states
+    //! \param[in] z Z-coordinate at which to compute the states
+    //! \param[in] t Physical time
+    //! \return Left and right states for all scalar components in this PDE
+    //!   system
+    //! \note The function signature must follow tk::StateFn. For multimat, the
+    //!   left or right state is the vector of conserved quantities, followed by
+    //!   the vector of primitive quantities appended to it.
+    static tk::StateFn::result_type
+    dirichlet( ncomp_t ncomp,
+               const std::vector< EOS >& mat_blk,
+               const std::vector< tk::real >& ul, tk::real x, tk::real y,
+               tk::real z, tk::real t, const std::array< tk::real, 3 >& )
+    {
+      auto nmat = g_inputdeck.get< tag::multimat, tag::nmat >();<--- Shadow variable
+      const auto& solidx = g_inputdeck.get<
+        tag::matidxmap, tag::solidx >();
+
+      [[maybe_unused]] auto nsld = numSolids(nmat, solidx);
+
+      auto ur = Problem::initialize( ncomp, mat_blk, x, y, z, t );
+      Assert( ur.size() == ncomp, "Incorrect size for boundary state vector" );
+
+      ur.resize(ul.size());
+
+      tk::real rho(0.0);
+      for (std::size_t k=0; k<nmat; ++k)
+        rho += ur[densityIdx(nmat, k)];
+
+      // get primitives in boundary state
+
+      // velocity
+      ur[ncomp+velocityIdx(nmat, 0)] = ur[momentumIdx(nmat, 0)] / rho;
+      ur[ncomp+velocityIdx(nmat, 1)] = ur[momentumIdx(nmat, 1)] / rho;
+      ur[ncomp+velocityIdx(nmat, 2)] = ur[momentumIdx(nmat, 2)] / rho;
+
+      // material pressures
+      for (std::size_t k=0; k<nmat; ++k)
+      {
+        auto gk = getDeformGrad(nmat, k, ur);
+        ur[ncomp+pressureIdx(nmat, k)] = mat_blk[k].compute< EOS::pressure >(
+          ur[densityIdx(nmat, k)], ur[ncomp+velocityIdx(nmat, 0)],
+          ur[ncomp+velocityIdx(nmat, 1)], ur[ncomp+velocityIdx(nmat, 2)],
+          ur[energyIdx(nmat, k)], ur[volfracIdx(nmat, k)], k, gk );
+      }
+
+      Assert( ur.size() == ncomp+nmat+3+nsld*6, "Incorrect size for appended "
+              "boundary state vector" );
+
+      return {{ std::move(ul), std::move(ur) }};
+    }
+
+    // Other boundary condition types that do not depend on "Problem" should be
+    // added in BCFunctions.hpp
+};
+
+} // dg::
+
+} // inciter::
+
+#endif // DGMultiMat_h
 
diff --git a/Debug/cppcheck/45.html b/Debug/cppcheck/45.html index df43e2a86c18..96d245c331f6 100644 --- a/Debug/cppcheck/45.html +++ b/Debug/cppcheck/45.html @@ -152,4403 +152,513 @@
- - + @@ -124,15 +124,15 @@ 50 : : Edge_Lock_Case lock_case; // TODO: Refactor this to match _ style? 51 : : 52 : : // Explicit Empty Constructor - 53 : 1776474 : Edge_Refinement() : + 53 : 1735453 : Edge_Refinement() : 54 : : A(0), 55 : : B(0), 56 : : needs_refining(0), 57 : : needs_derefining(false), - 58 : 1776474 : lock_case(Edge_Lock_Case::unlocked) + 58 : 1735453 : lock_case(Edge_Lock_Case::unlocked) 59 : : { 60 : : // Empty - 61 : 1776474 : } + 61 : 1735453 : } 62 : : 63 : : // bool operator==( const Edge_Refinement& r ) const { 64 : : // return A == r.A && diff --git a/Debug/test_coverage/Inciter/AMR/Error.cpp.func-sort-c.html b/Debug/test_coverage/Inciter/AMR/Error.cpp.func-sort-c.html index 47f8b0b36015..442c376380dc 100644 --- a/Debug/test_coverage/Inciter/AMR/Error.cpp.func-sort-c.html +++ b/Debug/test_coverage/Inciter/AMR/Error.cpp.func-sort-c.html @@ -33,7 +33,7 @@ - + diff --git a/Debug/test_coverage/Inciter/AMR/Error.cpp.func.html b/Debug/test_coverage/Inciter/AMR/Error.cpp.func.html index ffccbb4cfd64..ede42ee6dd5e 100644 --- a/Debug/test_coverage/Inciter/AMR/Error.cpp.func.html +++ b/Debug/test_coverage/Inciter/AMR/Error.cpp.func.html @@ -33,7 +33,7 @@ - + diff --git a/Debug/test_coverage/Inciter/AMR/Error.cpp.gcov.html b/Debug/test_coverage/Inciter/AMR/Error.cpp.gcov.html index 58266ebe4422..c4935c01334a 100644 --- a/Debug/test_coverage/Inciter/AMR/Error.cpp.gcov.html +++ b/Debug/test_coverage/Inciter/AMR/Error.cpp.gcov.html @@ -33,7 +33,7 @@ - + diff --git a/Debug/test_coverage/Inciter/AMR/Refinement_State.hpp.func-sort-c.html b/Debug/test_coverage/Inciter/AMR/Refinement_State.hpp.func-sort-c.html index 1f0b6ca67676..9e0d928fca9e 100644 --- a/Debug/test_coverage/Inciter/AMR/Refinement_State.hpp.func-sort-c.html +++ b/Debug/test_coverage/Inciter/AMR/Refinement_State.hpp.func-sort-c.html @@ -33,7 +33,7 @@ - + @@ -77,7 +77,7 @@ - +
   1
-   2
-   3
-   4
-   5
-   6
-   7
-   8
-   9
-  10
-  11
-  12
-  13
-  14
-  15
-  16
-  17
-  18
-  19
-  20
-  21
-  22
-  23
-  24
-  25
-  26
-  27
-  28
-  29
-  30
-  31
-  32
-  33
-  34
-  35
-  36
-  37
-  38
-  39
-  40
-  41
-  42
-  43
-  44
-  45
-  46
-  47
-  48
-  49
-  50
-  51
-  52
-  53
-  54
-  55
-  56
-  57
-  58
-  59
-  60
-  61
-  62
-  63
-  64
-  65
-  66
-  67
-  68
-  69
-  70
-  71
-  72
-  73
-  74
-  75
-  76
-  77
-  78
-  79
-  80
-  81
-  82
-  83
-  84
-  85
-  86
-  87
-  88
-  89
-  90
-  91
-  92
-  93
-  94
-  95
-  96
-  97
-  98
-  99
- 100
- 101
- 102
- 103
- 104
- 105
- 106
- 107
- 108
- 109
- 110
- 111
- 112
- 113
- 114
- 115
- 116
- 117
- 118
- 119
- 120
- 121
- 122
- 123
- 124
- 125
- 126
- 127
- 128
- 129
- 130
- 131
- 132
- 133
- 134
- 135
- 136
- 137
- 138
- 139
- 140
- 141
- 142
- 143
- 144
- 145
- 146
- 147
- 148
- 149
- 150
- 151
- 152
- 153
- 154
- 155
- 156
- 157
- 158
- 159
- 160
- 161
- 162
- 163
- 164
- 165
- 166
- 167
- 168
- 169
- 170
- 171
- 172
- 173
- 174
- 175
- 176
- 177
- 178
- 179
- 180
- 181
- 182
- 183
- 184
- 185
- 186
- 187
- 188
- 189
- 190
- 191
- 192
- 193
- 194
- 195
- 196
- 197
- 198
- 199
- 200
- 201
- 202
- 203
- 204
- 205
- 206
- 207
- 208
- 209
- 210
- 211
- 212
- 213
- 214
- 215
- 216
- 217
- 218
- 219
- 220
- 221
- 222
- 223
- 224
- 225
- 226
- 227
- 228
- 229
- 230
- 231
- 232
- 233
- 234
- 235
- 236
- 237
- 238
- 239
- 240
- 241
- 242
- 243
- 244
- 245
- 246
- 247
- 248
- 249
- 250
- 251
- 252
- 253
- 254
- 255
- 256
- 257
- 258
- 259
- 260
- 261
- 262
- 263
- 264
- 265
- 266
- 267
- 268
- 269
- 270
- 271
- 272
- 273
- 274
- 275
- 276
- 277
- 278
- 279
- 280
- 281
- 282
- 283
- 284
- 285
- 286
- 287
- 288
- 289
- 290
- 291
- 292
- 293
- 294
- 295
- 296
- 297
- 298
- 299
- 300
- 301
- 302
- 303
- 304
- 305
- 306
- 307
- 308
- 309
- 310
- 311
- 312
- 313
- 314
- 315
- 316
- 317
- 318
- 319
- 320
- 321
- 322
- 323
- 324
- 325
- 326
- 327
- 328
- 329
- 330
- 331
- 332
- 333
- 334
- 335
- 336
- 337
- 338
- 339
- 340
- 341
- 342
- 343
- 344
- 345
- 346
- 347
- 348
- 349
- 350
- 351
- 352
- 353
- 354
- 355
- 356
- 357
- 358
- 359
- 360
- 361
- 362
- 363
- 364
- 365
- 366
- 367
- 368
- 369
- 370
- 371
- 372
- 373
- 374
- 375
- 376
- 377
- 378
- 379
- 380
- 381
- 382
- 383
- 384
- 385
- 386
- 387
- 388
- 389
- 390
- 391
- 392
- 393
- 394
- 395
- 396
- 397
- 398
- 399
- 400
- 401
- 402
- 403
- 404
- 405
- 406
- 407
- 408
- 409
- 410
- 411
- 412
- 413
- 414
- 415
- 416
- 417
- 418
- 419
- 420
- 421
- 422
- 423
- 424
- 425
- 426
- 427
- 428
- 429
- 430
- 431
- 432
- 433
- 434
- 435
- 436
- 437
- 438
- 439
- 440
- 441
- 442
- 443
- 444
- 445
- 446
- 447
- 448
- 449
- 450
- 451
- 452
- 453
- 454
- 455
- 456
- 457
- 458
- 459
- 460
- 461
- 462
- 463
- 464
- 465
- 466
- 467
- 468
- 469
- 470
- 471
- 472
- 473
- 474
- 475
- 476
- 477
- 478
- 479
- 480
- 481
- 482
- 483
- 484
- 485
- 486
- 487
- 488
- 489
- 490
- 491
- 492
- 493
- 494
- 495
- 496
- 497
- 498
- 499
- 500
- 501
- 502
- 503
- 504
- 505
- 506
- 507
- 508
- 509
- 510
- 511
- 512
- 513
- 514
- 515
- 516
- 517
- 518
- 519
- 520
- 521
- 522
- 523
- 524
- 525
- 526
- 527
- 528
- 529
- 530
- 531
- 532
- 533
- 534
- 535
- 536
- 537
- 538
- 539
- 540
- 541
- 542
- 543
- 544
- 545
- 546
- 547
- 548
- 549
- 550
- 551
- 552
- 553
- 554
- 555
- 556
- 557
- 558
- 559
- 560
- 561
- 562
- 563
- 564
- 565
- 566
- 567
- 568
- 569
- 570
- 571
- 572
- 573
- 574
- 575
- 576
- 577
- 578
- 579
- 580
- 581
- 582
- 583
- 584
- 585
- 586
- 587
- 588
- 589
- 590
- 591
- 592
- 593
- 594
- 595
- 596
- 597
- 598
- 599
- 600
- 601
- 602
- 603
- 604
- 605
- 606
- 607
- 608
- 609
- 610
- 611
- 612
- 613
- 614
- 615
- 616
- 617
- 618
- 619
- 620
- 621
- 622
- 623
- 624
- 625
- 626
- 627
- 628
- 629
- 630
- 631
- 632
- 633
- 634
- 635
- 636
- 637
- 638
- 639
- 640
- 641
- 642
- 643
- 644
- 645
- 646
- 647
- 648
- 649
- 650
- 651
- 652
- 653
- 654
- 655
- 656
- 657
- 658
- 659
- 660
- 661
- 662
- 663
- 664
- 665
- 666
- 667
- 668
- 669
- 670
- 671
- 672
- 673
- 674
- 675
- 676
- 677
- 678
- 679
- 680
- 681
- 682
- 683
- 684
- 685
- 686
- 687
- 688
- 689
- 690
- 691
- 692
- 693
- 694
- 695
- 696
- 697
- 698
- 699
- 700
- 701
- 702
- 703
- 704
- 705
- 706
- 707
- 708
- 709
- 710
- 711
- 712
- 713
- 714
- 715
- 716
- 717
- 718
- 719
- 720
- 721
- 722
- 723
- 724
- 725
- 726
- 727
- 728
- 729
- 730
- 731
- 732
- 733
- 734
- 735
- 736
- 737
- 738
- 739
- 740
- 741
- 742
- 743
- 744
- 745
- 746
- 747
- 748
- 749
- 750
- 751
- 752
- 753
- 754
- 755
- 756
- 757
- 758
- 759
- 760
- 761
- 762
- 763
- 764
- 765
- 766
- 767
- 768
- 769
- 770
- 771
- 772
- 773
- 774
- 775
- 776
- 777
- 778
- 779
- 780
- 781
- 782
- 783
- 784
- 785
- 786
- 787
- 788
- 789
- 790
- 791
- 792
- 793
- 794
- 795
- 796
- 797
- 798
- 799
- 800
- 801
- 802
- 803
- 804
- 805
- 806
- 807
- 808
- 809
- 810
- 811
- 812
- 813
- 814
- 815
- 816
- 817
- 818
- 819
- 820
- 821
- 822
- 823
- 824
- 825
- 826
- 827
- 828
- 829
- 830
- 831
- 832
- 833
- 834
- 835
- 836
- 837
- 838
- 839
- 840
- 841
- 842
- 843
- 844
- 845
- 846
- 847
- 848
- 849
- 850
- 851
- 852
- 853
- 854
- 855
- 856
- 857
- 858
- 859
- 860
- 861
- 862
- 863
- 864
- 865
- 866
- 867
- 868
- 869
- 870
- 871
- 872
- 873
- 874
- 875
- 876
- 877
- 878
- 879
- 880
- 881
- 882
- 883
- 884
- 885
- 886
- 887
- 888
- 889
- 890
- 891
- 892
- 893
- 894
- 895
- 896
- 897
- 898
- 899
- 900
- 901
- 902
- 903
- 904
- 905
- 906
- 907
- 908
- 909
- 910
- 911
- 912
- 913
- 914
- 915
- 916
- 917
- 918
- 919
- 920
- 921
- 922
- 923
- 924
- 925
- 926
- 927
- 928
- 929
- 930
- 931
- 932
- 933
- 934
- 935
- 936
- 937
- 938
- 939
- 940
- 941
- 942
- 943
- 944
- 945
- 946
- 947
- 948
- 949
- 950
- 951
- 952
- 953
- 954
- 955
- 956
- 957
- 958
- 959
- 960
- 961
- 962
- 963
- 964
- 965
- 966
- 967
- 968
- 969
- 970
- 971
- 972
- 973
- 974
- 975
- 976
- 977
- 978
- 979
- 980
- 981
- 982
- 983
- 984
- 985
- 986
- 987
- 988
- 989
- 990
- 991
- 992
- 993
- 994
- 995
- 996
- 997
- 998
- 999
-1000
-1001
-1002
-1003
-1004
-1005
-1006
-1007
-1008
-1009
-1010
-1011
-1012
-1013
-1014
-1015
-1016
-1017
-1018
-1019
-1020
-1021
-1022
-1023
-1024
-1025
-1026
-1027
-1028
-1029
-1030
-1031
-1032
-1033
-1034
-1035
-1036
-1037
-1038
-1039
-1040
-1041
-1042
-1043
-1044
-1045
-1046
-1047
-1048
-1049
-1050
-1051
-1052
-1053
-1054
-1055
-1056
-1057
-1058
-1059
-1060
-1061
-1062
-1063
-1064
-1065
-1066
-1067
-1068
-1069
-1070
-1071
-1072
-1073
-1074
-1075
-1076
-1077
-1078
-1079
-1080
-1081
-1082
-1083
-1084
-1085
-1086
-1087
-1088
-1089
-1090
-1091
-1092
-1093
-1094
-1095
-1096
-1097
-1098
-1099
-1100
-1101
-1102
-1103
-1104
-1105
-1106
-1107
-1108
-1109
-1110
-1111
-1112
-1113
-1114
-1115
-1116
-1117
-1118
-1119
-1120
-1121
-1122
-1123
-1124
-1125
-1126
-1127
-1128
-1129
-1130
-1131
-1132
-1133
-1134
-1135
-1136
-1137
-1138
-1139
-1140
-1141
-1142
-1143
-1144
-1145
-1146
-1147
-1148
-1149
-1150
-1151
-1152
-1153
-1154
-1155
-1156
-1157
-1158
-1159
-1160
-1161
-1162
-1163
-1164
-1165
-1166
-1167
-1168
-1169
-1170
-1171
-1172
-1173
-1174
-1175
-1176
-1177
-1178
-1179
-1180
-1181
-1182
-1183
-1184
-1185
-1186
-1187
-1188
-1189
-1190
-1191
-1192
-1193
-1194
-1195
-1196
-1197
-1198
-1199
-1200
-1201
-1202
-1203
-1204
-1205
-1206
-1207
-1208
-1209
-1210
-1211
-1212
-1213
-1214
-1215
-1216
-1217
-1218
-1219
-1220
-1221
-1222
-1223
-1224
-1225
-1226
-1227
-1228
-1229
-1230
-1231
-1232
-1233
-1234
-1235
-1236
-1237
-1238
-1239
-1240
-1241
-1242
-1243
-1244
-1245
-1246
-1247
-1248
-1249
-1250
-1251
-1252
-1253
-1254
-1255
-1256
-1257
-1258
-1259
-1260
-1261
-1262
-1263
-1264
-1265
-1266
-1267
-1268
-1269
-1270
-1271
-1272
-1273
-1274
-1275
-1276
-1277
-1278
-1279
-1280
-1281
-1282
-1283
-1284
-1285
-1286
-1287
-1288
-1289
-1290
-1291
-1292
-1293
-1294
-1295
-1296
-1297
-1298
-1299
-1300
-1301
-1302
-1303
-1304
-1305
-1306
-1307
-1308
-1309
-1310
-1311
-1312
-1313
-1314
-1315
-1316
-1317
-1318
-1319
-1320
-1321
-1322
-1323
-1324
-1325
-1326
-1327
-1328
-1329
-1330
-1331
-1332
-1333
-1334
-1335
-1336
-1337
-1338
-1339
-1340
-1341
-1342
-1343
-1344
-1345
-1346
-1347
-1348
-1349
-1350
-1351
-1352
-1353
-1354
-1355
-1356
-1357
-1358
-1359
-1360
-1361
-1362
-1363
-1364
-1365
-1366
-1367
-1368
-1369
-1370
-1371
-1372
-1373
-1374
-1375
-1376
-1377
-1378
-1379
-1380
-1381
-1382
-1383
-1384
-1385
-1386
-1387
-1388
-1389
-1390
-1391
-1392
-1393
-1394
-1395
-1396
-1397
-1398
-1399
-1400
-1401
-1402
-1403
-1404
-1405
-1406
-1407
-1408
-1409
-1410
-1411
-1412
-1413
-1414
-1415
-1416
-1417
-1418
-1419
-1420
-1421
-1422
-1423
-1424
-1425
-1426
-1427
-1428
-1429
-1430
-1431
-1432
-1433
-1434
-1435
-1436
-1437
-1438
-1439
-1440
-1441
-1442
-1443
-1444
-1445
-1446
-1447
-1448
-1449
-1450
-1451
-1452
-1453
-1454
-1455
-1456
-1457
-1458
-1459
-1460
-1461
-1462
-1463
-1464
-1465
-1466
-1467
-1468
-1469
-1470
-1471
-1472
-1473
-1474
-1475
-1476
-1477
-1478
-1479
-1480
-1481
-1482
-1483
-1484
-1485
-1486
-1487
-1488
-1489
-1490
-1491
-1492
-1493
-1494
-1495
-1496
-1497
-1498
-1499
-1500
-1501
-1502
-1503
-1504
-1505
-1506
-1507
-1508
-1509
-1510
-1511
-1512
-1513
-1514
-1515
-1516
-1517
-1518
-1519
-1520
-1521
-1522
-1523
-1524
-1525
-1526
-1527
-1528
-1529
-1530
-1531
-1532
-1533
-1534
-1535
-1536
-1537
-1538
-1539
-1540
-1541
-1542
-1543
-1544
-1545
-1546
-1547
-1548
-1549
-1550
-1551
-1552
-1553
-1554
-1555
-1556
-1557
-1558
-1559
-1560
-1561
-1562
-1563
-1564
-1565
-1566
-1567
-1568
-1569
-1570
-1571
-1572
-1573
-1574
-1575
-1576
-1577
-1578
-1579
-1580
-1581
-1582
-1583
-1584
-1585
-1586
-1587
-1588
-1589
-1590
-1591
-1592
-1593
-1594
-1595
-1596
-1597
-1598
-1599
-1600
-1601
-1602
-1603
-1604
-1605
-1606
-1607
-1608
-1609
-1610
-1611
-1612
-1613
-1614
-1615
-1616
-1617
-1618
-1619
-1620
-1621
-1622
-1623
-1624
-1625
-1626
-1627
-1628
-1629
-1630
-1631
-1632
-1633
-1634
-1635
-1636
-1637
-1638
-1639
-1640
-1641
-1642
-1643
-1644
-1645
-1646
-1647
-1648
-1649
-1650
-1651
-1652
-1653
-1654
-1655
-1656
-1657
-1658
-1659
-1660
-1661
-1662
-1663
-1664
-1665
-1666
-1667
-1668
-1669
-1670
-1671
-1672
-1673
-1674
-1675
-1676
-1677
-1678
-1679
-1680
-1681
-1682
-1683
-1684
-1685
-1686
-1687
-1688
-1689
-1690
-1691
-1692
-1693
-1694
-1695
-1696
-1697
-1698
-1699
-1700
-1701
-1702
-1703
-1704
-1705
-1706
-1707
-1708
-1709
-1710
-1711
-1712
-1713
-1714
-1715
-1716
-1717
-1718
-1719
-1720
-1721
-1722
-1723
-1724
-1725
-1726
-1727
-1728
-1729
-1730
-1731
-1732
-1733
-1734
-1735
-1736
-1737
-1738
-1739
-1740
-1741
-1742
-1743
-1744
-1745
-1746
-1747
-1748
-1749
-1750
-1751
-1752
-1753
-1754
-1755
-1756
-1757
-1758
-1759
-1760
-1761
-1762
-1763
-1764
-1765
-1766
-1767
-1768
-1769
-1770
-1771
-1772
-1773
-1774
-1775
-1776
-1777
-1778
-1779
-1780
-1781
-1782
-1783
-1784
-1785
-1786
-1787
-1788
-1789
-1790
-1791
-1792
-1793
-1794
-1795
-1796
-1797
-1798
-1799
-1800
-1801
-1802
-1803
-1804
-1805
-1806
-1807
-1808
-1809
-1810
-1811
-1812
-1813
-1814
-1815
-1816
-1817
-1818
-1819
-1820
-1821
-1822
-1823
-1824
-1825
-1826
-1827
-1828
-1829
-1830
-1831
-1832
-1833
-1834
-1835
-1836
-1837
-1838
-1839
-1840
-1841
-1842
-1843
-1844
-1845
-1846
-1847
-1848
-1849
-1850
-1851
-1852
-1853
-1854
-1855
-1856
-1857
-1858
-1859
-1860
-1861
-1862
-1863
-1864
-1865
-1866
-1867
-1868
-1869
-1870
-1871
-1872
-1873
-1874
-1875
-1876
-1877
-1878
-1879
-1880
-1881
-1882
-1883
-1884
-1885
-1886
-1887
-1888
-1889
-1890
-1891
-1892
-1893
-1894
-1895
-1896
-1897
-1898
-1899
-1900
-1901
-1902
-1903
-1904
-1905
-1906
-1907
-1908
-1909
-1910
-1911
-1912
-1913
-1914
-1915
-1916
-1917
-1918
-1919
-1920
-1921
-1922
-1923
-1924
-1925
-1926
-1927
-1928
-1929
-1930
-1931
-1932
-1933
-1934
-1935
-1936
-1937
-1938
-1939
-1940
-1941
-1942
-1943
-1944
-1945
-1946
-1947
-1948
-1949
-1950
-1951
-1952
-1953
-1954
-1955
-1956
-1957
-1958
-1959
-1960
-1961
-1962
-1963
-1964
-1965
-1966
-1967
-1968
-1969
-1970
-1971
-1972
-1973
-1974
-1975
-1976
-1977
-1978
-1979
-1980
-1981
-1982
-1983
-1984
-1985
-1986
-1987
-1988
-1989
-1990
-1991
-1992
-1993
-1994
-1995
-1996
-1997
-1998
-1999
-2000
-2001
-2002
-2003
-2004
-2005
-2006
-2007
-2008
-2009
-2010
-2011
-2012
-2013
-2014
-2015
-2016
-2017
-2018
-2019
-2020
-2021
-2022
-2023
-2024
-2025
-2026
-2027
-2028
-2029
-2030
-2031
-2032
-2033
-2034
-2035
-2036
-2037
-2038
-2039
-2040
-2041
-2042
-2043
-2044
-2045
-2046
-2047
-2048
-2049
-2050
-2051
-2052
-2053
-2054
-2055
-2056
-2057
-2058
-2059
-2060
-2061
-2062
-2063
-2064
-2065
-2066
-2067
-2068
-2069
-2070
-2071
-2072
-2073
-2074
-2075
-2076
-2077
-2078
-2079
-2080
-2081
-2082
-2083
-2084
-2085
-2086
-2087
-2088
-2089
-2090
-2091
-2092
-2093
-2094
-2095
-2096
-2097
-2098
-2099
-2100
-2101
-2102
-2103
-2104
-2105
-2106
-2107
-2108
-2109
-2110
-2111
-2112
-2113
-2114
-2115
-2116
-2117
-2118
-2119
-2120
-2121
-2122
-2123
-2124
-2125
-2126
-2127
-2128
-2129
-2130
-2131
-2132
-2133
-2134
-2135
-2136
-2137
-2138
-2139
-2140
-2141
-2142
-2143
-2144
-2145
-2146
-2147
-2148
-2149
-2150
-2151
-2152
-2153
-2154
-2155
-2156
-2157
-2158
-2159
-2160
-2161
-2162
-2163
-2164
-2165
-2166
-2167
-2168
-2169
-2170
-2171
-2172
-2173
-2174
-2175
-2176
-2177
// *****************************************************************************
+
  1
+  2
+  3
+  4
+  5
+  6
+  7
+  8
+  9
+ 10
+ 11
+ 12
+ 13
+ 14
+ 15
+ 16
+ 17
+ 18
+ 19
+ 20
+ 21
+ 22
+ 23
+ 24
+ 25
+ 26
+ 27
+ 28
+ 29
+ 30
+ 31
+ 32
+ 33
+ 34
+ 35
+ 36
+ 37
+ 38
+ 39
+ 40
+ 41
+ 42
+ 43
+ 44
+ 45
+ 46
+ 47
+ 48
+ 49
+ 50
+ 51
+ 52
+ 53
+ 54
+ 55
+ 56
+ 57
+ 58
+ 59
+ 60
+ 61
+ 62
+ 63
+ 64
+ 65
+ 66
+ 67
+ 68
+ 69
+ 70
+ 71
+ 72
+ 73
+ 74
+ 75
+ 76
+ 77
+ 78
+ 79
+ 80
+ 81
+ 82
+ 83
+ 84
+ 85
+ 86
+ 87
+ 88
+ 89
+ 90
+ 91
+ 92
+ 93
+ 94
+ 95
+ 96
+ 97
+ 98
+ 99
+100
+101
+102
+103
+104
+105
+106
+107
+108
+109
+110
+111
+112
+113
+114
+115
+116
+117
+118
+119
+120
+121
+122
+123
+124
+125
+126
+127
+128
+129
+130
+131
+132
+133
+134
+135
+136
+137
+138
+139
+140
+141
+142
+143
+144
+145
+146
+147
+148
+149
+150
+151
+152
+153
+154
+155
+156
+157
+158
+159
+160
+161
+162
+163
+164
+165
+166
+167
+168
+169
+170
+171
+172
+173
+174
+175
+176
+177
+178
+179
+180
+181
+182
+183
+184
+185
+186
+187
+188
+189
+190
+191
+192
+193
+194
+195
+196
+197
+198
+199
+200
+201
+202
+203
+204
+205
+206
+207
+208
+209
+210
+211
+212
+213
+214
+215
+216
+217
+218
+219
+220
+221
+222
+223
+224
+225
+226
+227
+228
+229
+230
+231
+232
+233
+234
+235
+236
+237
+238
+239
+240
+241
+242
+243
+244
+245
+246
+247
+248
+249
+250
// *****************************************************************************
 /*!
-  \file      src/Inciter/Refiner.cpp
+  \file      src/Inciter/Partitioner.hpp
   \copyright 2012-2015 J. Bakosi,
              2016-2018 Los Alamos National Security, LLC.,
              2019-2021 Triad National Security, LLC.
              All rights reserved. See the LICENSE file for details.
-  \brief     Mesh refiner for interfacing the mesh refinement library
-  \see       Refiner.h for more info.
-*/
-// *****************************************************************************
-
-#include <vector>
-#include <algorithm>
-
-#include "Refiner.hpp"
-#include "Reorder.hpp"
-#include "AMR/mesh_adapter.hpp"
-#include "AMR/Error.hpp"
-#include "Inciter/InputDeck/InputDeck.hpp"
-#include "CGPDE.hpp"
-#include "DGPDE.hpp"
-#include "FVPDE.hpp"
-#include "DerivedData.hpp"
-#include "UnsMesh.hpp"
-#include "Centering.hpp"
-#include "Around.hpp"
-#include "Sorter.hpp"
-#include "Discretization.hpp"
-
-namespace inciter {
-
-extern ctr::InputDeck g_inputdeck;
-extern ctr::InputDeck g_inputdeck_defaults;
-extern std::vector< CGPDE > g_cgpde;
-extern std::vector< DGPDE > g_dgpde;
-extern std::vector< FVPDE > g_fvpde;
-
-} // inciter::
+  \brief     Charm++ chare partitioner nodegroup used to perform mesh
+             partitioning
+  \details   Charm++ chare partitioner nodegroup used to perform mesh read and
+             partitioning, one worker per compute node.
+*/
+// *****************************************************************************
+#ifndef Partitioner_h
+#define Partitioner_h
+
+#include <array>
+#include <stddef.h>
+
+#include "ContainerUtil.hpp"
+#include "ZoltanInterOp.hpp"
+#include "Options/PartitioningAlgorithm.hpp"
+#include "DerivedData.hpp"
+#include "UnsMesh.hpp"
+#include "FaceData.hpp"
+#include "Sorter.hpp"
+#include "Refiner.hpp"
+#include "Callback.hpp"
+
+#include "NoWarning/partitioner.decl.h"
+
+namespace inciter {
+
+//! Partitioner Charm++ chare nodegroup class
+//! \details Instantiations of Partitioner comprise a processor aware Charm++
+//!   chare node group. When instantiated, a new object is created on each
+//!   compute node and not more (as opposed to individual chares or chare array
+//!   object elements). See also the Charm++ interface file partitioner.ci.
+class Partitioner : public CBase_Partitioner {
 
-using inciter::Refiner;
-
-Refiner::Refiner( std::size_t meshid,
-                  const CProxy_Transporter& transporter,
-                  const CProxy_Sorter& sorter,
-                  const tk::CProxy_MeshWriter& meshwriter,
-                  const std::vector< Scheme >& scheme,
-                  const tk::RefinerCallback& cbr,
-                  const tk::SorterCallback& cbs,
-                  const std::vector< std::size_t >& ginpoel,
-                  const tk::UnsMesh::CoordMap& coordmap,
-                  const std::map< int, std::vector< std::size_t > >& bface,
-                  const std::vector< std::size_t >& triinpoel,
-                  const std::map< int, std::vector< std::size_t > >& bnode,
-                  const std::vector< std::size_t >& elemblid,
-                  int nchare ) :
-  m_meshid( meshid ),
-  m_ncit(0),
-  m_host( transporter ),
-  m_sorter( sorter ),
-  m_meshwriter( meshwriter ),
-  m_scheme( scheme ),
-  m_cbr( cbr ),
-  m_cbs( cbs ),
-  m_ginpoel( ginpoel ),
-  m_el( tk::global2local( ginpoel ) ),     // fills m_inpoel, m_gid, m_lid
-  m_coordmap( coordmap ),
-  m_coord( flatcoord(coordmap) ),
-  m_bface( bface ),
-  m_bnode( bnode ),
-  m_triinpoel( triinpoel ),
-  m_elemblockid(),
-  m_nchare( nchare ),
-  m_mode( RefMode::T0REF ),
-  m_initref( g_inputdeck.get< tag::amr, tag::initial >() ),
-  m_ninitref( g_inputdeck.get< tag::amr, tag::initial >().size() ),
-  m_refiner( g_inputdeck.get< tag::amr, tag::maxlevels >(), m_inpoel ),
-  m_nref( 0 ),
-  m_nbnd( 0 ),
-  m_extra( 0 ),
-  m_ch(),
-  m_edgech(),
-  m_chedge(),
-  m_localEdgeData(),
-  m_remoteEdgeData(),
-  m_nodeCommMap(),
-  m_oldTets(),
-  m_addedNodes(),
-  m_addedTets(),
-  m_removedNodes(),
-  m_amrNodeMap(),
-  m_oldntets( 0 ),
-  m_coarseBndFaces(),
-  m_coarseBndNodes(),
-  m_coarseBlkElems(),
-  m_rid( m_coord[0].size() ),
-//  m_oldrid(),
-  m_lref( m_rid.size() ),
-//  m_oldparent(),
-  m_writeCallback(),
-  m_outref_ginpoel(),
-  m_outref_el(),
-  m_outref_coord(),
-  m_outref_addedNodes(),
-  m_outref_addedTets(),
-  m_outref_nodeCommMap(),
-  m_outref_bface(),
-  m_outref_bnode(),
-  m_outref_triinpoel()
-// *****************************************************************************
-//  Constructor
-//! \param[in] meshid Mesh ID
-//! \param[in] transporter Transporter (host) proxy
-//! \param[in] sorter Mesh reordering (sorter) proxy
-//! \param[in] meshwriter Mesh writer proxy
-//! \param[in] scheme Discretization schemes (one per mesh)
-//! \param[in] cbr Charm++ callbacks for Refiner
-//! \param[in] cbs Charm++ callbacks for Sorter
-//! \param[in] ginpoel Mesh connectivity (this chare) using global node IDs
-//! \param[in] coordmap Mesh node coordinates (this chare) for global node IDs
-//! \param[in] bface File-internal elem ids of side sets
-//! \param[in] triinpoel Triangle face connectivity with global IDs
-//! \param[in] bnode Node lists of side sets
-//! \param[in] elemblid Mesh block ids associated to local tet ids
-//! \param[in] nchare Total number of refiner chares (chare array elements)
-// *****************************************************************************
-{
-  Assert( !m_ginpoel.empty(), "No elements assigned to refiner chare" );
-  Assert( tk::positiveJacobians( m_inpoel, m_coord ),
-          "Input mesh to Refiner Jacobian non-positive" );
-  Assert( !tk::leakyPartition(
-            tk::genEsuelTet( m_inpoel, tk::genEsup(m_inpoel,4) ),
-            m_inpoel, m_coord ),
-          "Input mesh to Refiner leaky" );
-
-  // Construct data structure assigning sets of element ids to mesh blocks
-  for (std::size_t ie=0; ie<elemblid.size(); ++ie) {
-    m_elemblockid[elemblid[ie]].insert(ie);
-  }
-
-  #if not defined(__INTEL_COMPILER) || defined(NDEBUG)
-  // The above ifdef skips running the conformity test with the intel compiler
-  // in debug mode only. This is necessary because in tk::conforming(), filling
-  // up the map can fail with some meshes (only in parallel), e.g., tube.exo,
-  // used by some regression tests, due to the intel compiler generating some
-  // garbage incorrect code - only in debug, only in parallel, only with that
-  // mesh.
-  Assert( tk::conforming( m_inpoel, m_coord, true, m_rid ),
-          "Input mesh to Refiner not conforming" );
-  #endif
-
-  // Generate local -> refiner lib node id map and its inverse
-  libmap();
-
-  // Reverse initial mesh refinement type list (will pop from back)
-  std::reverse( begin(m_initref), end(m_initref) );
-
-  // Generate boundary data structures for coarse mesh
-  coarseMesh();
-
-  // If initial mesh refinement is configured, start initial mesh refinement.
-  // See also tk::grm::check_amr_errors in Control/Inciter/InputDeck/Ggrammar.h.
-  if (g_inputdeck.get< tag::amr, tag::t0ref >() && m_ninitref > 0)
-    t0ref();
-  else
-    endt0ref();
-}
-
-void
-Refiner::libmap()
-// *****************************************************************************
-// (Re-)generate local -> refiner lib node id map and its inverse
-// *****************************************************************************
-{
-  // Fill initial (matching) mapping between local and refiner node ids
-  std::iota( begin(m_rid), end(m_rid), 0 );
-
-  // Fill in inverse, mapping refiner to local node ids
-  std::size_t i = 0;
-  for (auto r : m_rid) m_lref[r] = i++;
-}
-
-void
-Refiner::coarseMesh()
-// *****************************************************************************
-// (Re-)generate side set and block data structures for coarse mesh
-// *****************************************************************************
-{
-  // Generate unique set of faces for each side set of the input (coarsest) mesh
-  m_coarseBndFaces.clear();
-  for (const auto& [ setid, faceids ] : m_bface) {
-    auto& faces = m_coarseBndFaces[ setid ];
-    for (auto f : faceids) {
-      faces.insert(
-        {{{ m_triinpoel[f*3+0], m_triinpoel[f*3+1], m_triinpoel[f*3+2] }}} );
-    }
-  }
-
-  // Generate unique set of nodes for each side set of the input (coarsest) mesh
-  m_coarseBndNodes.clear();
-  for (const auto& [ setid, nodes ] : m_bnode) {
-    m_coarseBndNodes[ setid ].insert( begin(nodes), end(nodes) );
-  }
-
-  // Generate set of elements for each mesh block of the input (coarsest) mesh
-  m_coarseBlkElems.clear();
-  for (const auto& [blid, elids] : m_elemblockid) {
-    for (auto ie : elids) {
-      m_coarseBlkElems[blid].insert( {{{m_inpoel[ie*4+0], m_inpoel[ie*4+1],
-        m_inpoel[ie*4+2], m_inpoel[ie*4+3]}}} );
-    }
-  }
-}
-
-void
-Refiner::sendProxy()
-// *****************************************************************************
-// Send Refiner proxy to Discretization objects
-//! \details This should be called when bound Discretization chare array
-//!   elements have already been created.
-// *****************************************************************************
-{
-  // Make sure (bound) Discretization chare is already created and accessible
-  Assert( m_scheme[m_meshid].disc()[thisIndex].ckLocal() != nullptr,
-          "About to dereference nullptr" );
-
-  // Pass Refiner Charm++ chare proxy to fellow (bound) Discretization object
-  m_scheme[m_meshid].disc()[thisIndex].ckLocal()->setRefiner( thisProxy );
-}
-
-void
-Refiner::reorder()
-// *****************************************************************************
-// Query Sorter and update local mesh with the reordered one
-// *****************************************************************************
-{
-  m_sorter[thisIndex].ckLocal()->
-    mesh( m_ginpoel, m_coordmap, m_triinpoel, m_bnode );
-
-  // Update local mesh data based on data just received from Sorter
-  m_el = tk::global2local( m_ginpoel );     // fills m_inpoel, m_gid, m_lid
-  m_coord = flatcoord( m_coordmap );
-
-  // Re-generate boundary data structures for coarse mesh
-  coarseMesh();
-
-  // WARNING: This re-creates the AMR lib which is probably not what we
-  // ultimately want, beacuse this deletes its history recorded during initial
-  // (t<0) refinement. However, this appears to correctly update the local mesh
-  // based on the reordered one (from Sorter) at least when t0ref is off.
-  m_refiner = AMR::mesh_adapter_t(
-    g_inputdeck.get< tag::amr, tag::maxlevels >(), m_inpoel );
-}
-
-tk::UnsMesh::Coords
-Refiner::flatcoord( const tk::UnsMesh::CoordMap& coordmap )
-// *****************************************************************************
-// Generate flat coordinate data from coordinate map
-//! \param[in] coordmap Coordinates associated to global node IDs of mesh chunk
-//! \return Flat coordinate data
-// *****************************************************************************
-{
-  tk::UnsMesh::Coords coord;
-
-  // Convert node coordinates associated to global node IDs to a flat vector
-  auto npoin = coordmap.size();
-  Assert( m_gid.size() == npoin, "Size mismatch" );
-  coord[0].resize( npoin );
-  coord[1].resize( npoin );
-  coord[2].resize( npoin );
-  for (const auto& [ gid, coords ] : coordmap) {
-    auto i = tk::cref_find( m_lid, gid );
-    Assert( i < npoin, "Indexing out of coordinate map" );
-    coord[0][i] = coords[0];
-    coord[1][i] = coords[1];
-    coord[2][i] = coords[2];
-  }
-
-  return coord;
-}
-
-void
-Refiner::dtref( const std::map< int, std::vector< std::size_t > >& bface,
-                const std::map< int, std::vector< std::size_t > >& bnode,
-                const std::vector< std::size_t >& triinpoel )
-// *****************************************************************************
-// Start mesh refinement (during time stepping, t>0)
-//! \param[in] bface Boundary-faces mapped to side set ids
-//! \param[in] bnode Boundary-node lists mapped to side set ids
-//! \param[in] triinpoel Boundary-face connectivity
-// *****************************************************************************
-{
-  m_mode = RefMode::DTREF;
-
-  // Update boundary node lists
-  m_bface = bface;
-  m_bnode = bnode;
-  m_triinpoel = tk::remap(triinpoel, m_gid);
-
-  start();
-}
-
-void
-Refiner::outref( const std::map< int, std::vector< std::size_t > >& bface,
-                 const std::map< int, std::vector< std::size_t > >& bnode,
-                 const std::vector< std::size_t >& triinpoel,
-                 CkCallback c,
-                 RefMode mode )
-// *****************************************************************************
-// Start mesh refinement (for field output)
-//! \param[in] bface Boundary-faces mapped to side set ids
-//! \param[in] bnode Boundary-node lists mapped to side set ids
-//! \param[in] triinpoel Boundary-face connectivity
-//! \param[in] c Function to continue with after the writing field output
-//! \param[in] mode Refinement mode
-// *****************************************************************************
-{
-  m_mode = mode;
-
-  m_writeCallback = c;
-
-  // Update boundary node lists
-  m_bface = bface;
-  m_bnode = bnode;
-  m_triinpoel = triinpoel;
-
-  start();
-}
-
-void
-Refiner::t0ref()
-// *****************************************************************************
-// Output mesh to file before a new step mesh refinement
-// *****************************************************************************
-{
-  Assert( m_ninitref > 0, "No initial mesh refinement steps configured" );
-  // Output initial mesh to file
-  auto l = m_ninitref - m_initref.size();  // num initref steps completed
-  auto t0 = g_inputdeck.get< tag::t0 >();
-  if (l == 0) {
-    writeMesh( "t0ref", l, t0-1.0,
-      CkCallback( CkIndex_Refiner::start(), thisProxy[thisIndex] ) );
-  } else {
-    start();
-  }
-}
-
-void
-Refiner::start()
-// *****************************************************************************
-//  Start new step of mesh refinement
-// *****************************************************************************
-{
-  m_extra = 0;
-  m_ch.clear();
-  m_remoteEdgeData.clear();
-  m_remoteEdges.clear();
-
-  updateEdgeData();
-
-  // Generate and communicate boundary edges
-  bndEdges();
-}
-
-void
-Refiner::bndEdges()
-// *****************************************************************************
-// Generate boundary edges and send them to all chares
-//! \details Extract edges on the boundary only. The boundary edges (shared by
-//!   multiple chares) will be agreed on a refinement that yields a conforming
-//!   mesh across chares boundaries.
-// *****************************************************************************
-{
-  // Compute the number of edges (chunksize) a chare will respond to when
-  // computing shared edges
-  auto N = static_cast< std::size_t >( m_nchare );
-  std::size_t chunksize = std::numeric_limits< std::size_t >::max() / N;<--- Variable 'chunksize' is assigned a value that is never used.
-
-  // Generate boundary edges of our mesh chunk
-  std::unordered_map< int, EdgeSet > chbedges;
-  auto esup = tk::genEsup( m_inpoel, 4 );         // elements surrounding points
-  auto esuel = tk::genEsuelTet( m_inpoel, esup ); // elems surrounding elements
-  for (std::size_t e=0; e<esuel.size()/4; ++e) {
-    auto mark = e*4;
-    for (std::size_t f=0; f<4; ++f) {
-      if (esuel[mark+f] == -1) {
-        auto A = m_ginpoel[ mark+tk::lpofa[f][0] ];
-        auto B = m_ginpoel[ mark+tk::lpofa[f][1] ];<--- Variable 'B' is assigned a value that is never used.
-        auto C = m_ginpoel[ mark+tk::lpofa[f][2] ];<--- Variable 'C' is assigned a value that is never used.
-        Assert( m_lid.find( A ) != end(m_lid), "Local node ID not found" );
-        Assert( m_lid.find( B ) != end(m_lid), "Local node ID not found" );
-        Assert( m_lid.find( C ) != end(m_lid), "Local node ID not found" );
-        // assign edges to bins a single chare will respond to when computing
-        // shared edges
-        auto bin = A / chunksize;
-        Assert( bin < N, "Will index out of number of chares" );
-        chbedges[ static_cast<int>(bin) ].insert( {A,B} );
-        bin = B / chunksize;
-        Assert( bin < N, "Will index out of number of chares" );
-        chbedges[ static_cast<int>(bin) ].insert( {B,C} );
-        bin = C / chunksize;
-        Assert( bin < N, "Will index out of number of chares" );
-        chbedges[ static_cast<int>(bin) ].insert( {C,A} );
-      }
-    }
-  }
-
-  // Send edges in bins to chares that will compute shared edges
-  m_nbnd = chbedges.size();
-  if (m_nbnd == 0)
-    contribute( sizeof(std::size_t), &m_meshid, CkReduction::nop,
-                m_cbr.get< tag::queried >() );
-  else
-    for (const auto& [ targetchare, bndedges ] : chbedges)
-      thisProxy[ targetchare ].query( thisIndex, bndedges );
-}
-
-void
-Refiner::query( int fromch, const EdgeSet& edges )
-// *****************************************************************************
-// Incoming query for a list boundary edges for which this chare compiles
-// shared edges
-//! \param[in] fromch Sender chare ID
-//! \param[in] edges Chare-boundary edge list from another chare
-// *****************************************************************************
-{
-  // Store incoming edges in edge->chare and its inverse, chare->edge, maps
-  for (const auto& e : edges) m_edgech[ e ].push_back( fromch );
-  m_chedge[ fromch ].insert( begin(edges), end(edges) );
-  // Report back to chare message received from
-  thisProxy[ fromch ].recvquery();
-}
-
-void
-Refiner::recvquery()
-// *****************************************************************************
-// Receive receipt of boundary edge lists to query
-// *****************************************************************************
-{
-  if (--m_nbnd == 0)
-    contribute( sizeof(std::size_t), &m_meshid, CkReduction::nop,
-                m_cbr.get< tag::queried >() );
-}
-
-void
-Refiner::response()
-// *****************************************************************************
-//  Respond to boundary edge list queries
-// *****************************************************************************
-{
-  std::unordered_map< int, std::vector< int > > exp;
-
-  // Compute shared edges whose chare ids will be sent back to querying chares
-  for (const auto& [ neighborchare, bndedges ] : m_chedge) {
-    auto& e = exp[ neighborchare ];
-    for (const auto& ed : bndedges)
-      for (auto d : tk::cref_find(m_edgech,ed))
-        if (d != neighborchare)
-          e.push_back( d );<--- Consider using std::copy_if algorithm instead of a raw loop.
-  }
-
-  // Send chare ids of shared edges to chares that issued a query to us. Shared
-  // boundary edges assigned to chare ids sharing the boundary edge were
-  // computed above for those chares that queried this map from us. These
-  // boundary edges form a distributed table and we only work on a chunk of it.
-  // Note that we only send data back to those chares that have queried us. The
-  // receiving sides do not know in advance if they receive messages or not.
-  // Completion is detected by having the receiver respond back and counting
-  // the responses on the sender side, i.e., this chare.
-  m_nbnd = exp.size();
-  if (m_nbnd == 0)
-    contribute( sizeof(std::size_t), &m_meshid, CkReduction::nop,
-                m_cbr.get< tag::responded >() );
-  else
-    for (const auto& [ targetchare, bndedges ] : exp)
-      thisProxy[ targetchare ].bnd( thisIndex, bndedges );
-}
-
-void
-Refiner::bnd( int fromch, const std::vector< int >& chares )
-// *****************************************************************************
-// Receive shared boundary edges for our mesh chunk
-//! \param[in] fromch Sender chare ID
-//! \param[in] chares Chare ids we share edges with
-// *****************************************************************************
-{
-  // Store chare ids we share edges with
-  m_ch.insert( begin(chares), end(chares) );
-
-  // Report back to chare message received from
-  thisProxy[ fromch ].recvbnd();
-}
-
-void
-Refiner::recvbnd()
-// *****************************************************************************
-// Receive receipt of shared boundary edges
-// *****************************************************************************
-{
-  if (--m_nbnd == 0)
-    contribute( sizeof(std::size_t), &m_meshid, CkReduction::nop,
-                m_cbr.get< tag::responded >() );
-}
-
-void
-Refiner::refine()
-// *****************************************************************************
-//  Do a single step of mesh refinement (really, only tag edges)
-//! \details During initial (t<0, t0ref) mesh refinement, this is a single step
-//!   in a potentially multiple-entry list of initial adaptive mesh refinement
-//!   steps. Distribution of the chare-boundary edges must have preceded this
-//!   step, so that boundary edges (shared by multiple chares) can agree on a
-//!   refinement that yields a conforming mesh across chare boundaries.
-//!
-//!   During-timestepping (t>0, dtref) mesh refinement this is called once, as
-//!   we only do a single step during time stepping.
-//!
-//!   During field-output (outref) mesh refinement, this may be called multiple
-//!   times, depending the number of refinement levels needed for the field
-//!   output.
-// *****************************************************************************
-{
-  // Free memory used for computing shared boundary edges
-  tk::destroy( m_edgech );
-  tk::destroy( m_chedge );
-
-  // Perform leak test on old mesh
-  Assert( !tk::leakyPartition(
-            tk::genEsuelTet( m_inpoel, tk::genEsup(m_inpoel,4) ),
-            m_inpoel, m_coord ),
-          "Mesh partition before refinement leaky" );
-
-  if (m_mode == RefMode::T0REF) {
-
-    // Refine mesh based on next initial refinement type
-    if (!m_initref.empty()) {
-      auto r = m_initref.back();    // consume (reversed) list from its back
-      if (r == ctr::AMRInitialType::UNIFORM)
-        uniformRefine();
-      else if (r == ctr::AMRInitialType::UNIFORM_DEREFINE)
-        uniformDeRefine();
-      else if (r == ctr::AMRInitialType::INITIAL_CONDITIONS)
-        errorRefine();
-      else if (r == ctr::AMRInitialType::COORDINATES)
-        coordRefine();
-      else if (r == ctr::AMRInitialType::EDGELIST)
-        edgelistRefine();
-      else Throw( "Initial AMR type not implemented" );
-    }
-
-  } else if (m_mode == RefMode::DTREF) {
-
-    if (g_inputdeck.get< tag::amr, tag::dtref_uniform >())
-      uniformRefine();
-    else
-      errorRefine();
-
-  } else if (m_mode == RefMode::OUTREF) {
-
-    uniformRefine();
-
-  } else if (m_mode == RefMode::OUTDEREF) {
-
-    uniformDeRefine();
-
-  } else Throw( "RefMode not implemented" );
-
-  // Communicate extra edges
-  comExtra();
-}
-
-void
-Refiner::comExtra()
-// *****************************************************************************
-// Communicate extra edges along chare boundaries
-// *****************************************************************************
-{
-  // Export extra added nodes on our mesh chunk boundary to other chares
-  if (m_ch.empty()) {
-    correctref();
-  } else {
-    for (auto c : m_ch) {  // for all chares we share at least an edge with
-      thisProxy[c].addRefBndEdges(thisIndex, m_localEdgeData, m_intermediates);
-    }
-  }
-}
-
-void
-Refiner::addRefBndEdges(
-  int fromch,
-  const AMR::EdgeData& ed,
-  const std::unordered_set< std::size_t >& intermediates )
-// *****************************************************************************
-//! Receive edges on our chare boundary from other chares
-//! \param[in] fromch Chare call coming from
-//! \param[in] ed Edges on chare boundary
-//! \param[in] intermediates Intermediate nodes
-//! \details Other than update remoteEdge data, this function also updates
-//!   locking information for such edges whos nodes are marked as intermediate
-//!   by neighboring chares.
-// *****************************************************************************
-{
-  // Save/augment buffers of edge data for each sender chare
-  auto& red = m_remoteEdgeData[ fromch ];
-  auto& re = m_remoteEdges[ fromch ];
-  using edge_data_t = std::tuple< Edge, int, int, AMR::Edge_Lock_Case >;
-  for (const auto& [ edge, data ] : ed) {
-    red.push_back( edge_data_t{ edge, std::get<0>(data), std::get<1>(data),
-      std::get<2>(data) } );
-    re.push_back( edge );
-  }
-
-  // Add intermediates to mesh refiner lib
-  // needs to be done only when mesh has been actually updated, i.e. first iter
-  if (m_ncit == 0) {
-    auto esup = tk::genEsup( m_inpoel, 4 );
-    auto psup = tk::genPsup( m_inpoel, 4, esup );
-    for (const auto g : intermediates) {
-      auto l = m_lid.find( g ); // convert to local node ids
-      if (l != end(m_lid)) {
-        // lock all edges connected to intermediate node
-        auto p = l->second;
-        for (auto q : tk::Around(psup,p)) {
-          AMR::edge_t e(m_rid[p], m_rid[q]);
-          auto& refedge = m_refiner.tet_store.edge_store.get(e);
-          if (refedge.lock_case == AMR::Edge_Lock_Case::unlocked) {
-            refedge.lock_case = AMR::Edge_Lock_Case::temporary; //intermediate;
-            refedge.needs_refining = 0;
-          }
-        }
-      }
-    }
-  }
-
-  // Heard from every worker we share at least a single edge with
-  if (++m_nref == m_ch.size()) {
-    m_nref = 0;
-
-    updateBndEdgeData();
-
-    std::vector< std::size_t > meshdata{ m_meshid };
-    contribute( meshdata, CkReduction::max_ulong,
-                m_cbr.get< tag::compatibility >() );
-  }
-}
-
-void
-Refiner::correctref()
-// *****************************************************************************
-//  Correct extra edges to arrive at conforming mesh across chare boundaries
-//! \details This function is called repeatedly until there is not a a single
-//!    edge that needs correction for the whole distributed problem to arrive at
-//!    a conforming mesh across chare boundaries during a mesh refinement step.
-// *****************************************************************************
-{
-  auto unlocked = AMR::Edge_Lock_Case::unlocked;
-
-  // Storage for edge data that need correction to yield a conforming mesh
-  AMR::EdgeData extra;
-  std::size_t neigh_extra(0);
-
-  // Vars for debugging purposes
-  std::size_t nlocked(0);<--- Variable 'nlocked' is assigned a value that is never used.
-  std::array< std::size_t, 4 > ncorrcase{{0,0,0,0}};
-
-  // loop through all edges shared with other chares
-  for (const auto& [ neighborchare, edgedata ] : m_remoteEdgeData) {
-    for (const auto& [edge,remote_needs_refining,remote_needs_derefining,
-      remote_lock_case] : edgedata) {
-      // find local data of remote edge
-      auto it = m_localEdgeData.find( edge );
-      if (it != end(m_localEdgeData)) {
-        auto& local = it->second;
-        auto& local_needs_refining = std::get<0>(local);
-        auto& local_needs_derefining = std::get<1>(local);
-        auto& local_lock_case = std::get<2>(local);
-
-        auto local_needs_refining_orig = local_needs_refining;<--- Variable 'local_needs_refining_orig' is assigned a value that is never used.
-        auto local_needs_derefining_orig = local_needs_derefining;<--- Variable 'local_needs_derefining_orig' is assigned a value that is never used.
-        auto local_lock_case_orig = local_lock_case;<--- Variable 'local_lock_case_orig' is assigned a value that is never used.
-
-        Assert( !(local_lock_case > unlocked && local_needs_refining),
-                "Invalid local edge: locked & needs refining" );
-        Assert( !(remote_lock_case > unlocked && remote_needs_refining),
-                "Invalid remote edge: locked & needs refining" );
-        Assert( !(local_needs_derefining == 1 && local_needs_refining > 0),
-                "Invalid local edge: needs refining and derefining" );
-
-        // The parallel compatibility (par-compat) algorithm
-
-        // compute lock from local and remote locks as most restrictive
-        local_lock_case = std::max( local_lock_case, remote_lock_case );
-
-        if (local_lock_case > unlocked) {
-          local_needs_refining = 0;
-          if (local_needs_refining != local_needs_refining_orig ||
-            local_lock_case != local_lock_case_orig)
-            ++ncorrcase[0];
-        }
-
-        // Possible combinations of remote-local ref-deref decisions
-        // rows 1, 5, 9: no action needed.
-        // rows 4, 7, 8: no action on local-side; comm needed.
-        //
-        //    LOCAL          |        REMOTE    |  Result
-        // 1  d              |        d         |  d
-        // 2  d              |        -         |  -
-        // 3  d              |        r         |  r
-        // 4  -              |        d         |  -
-        // 5  -              |        -         |  -
-        // 6  -              |        r         |  r
-        // 7  r              |        d         |  r
-        // 8  r              |        -         |  r
-        // 9  r              |        r         |  r
-
-        // Rows 3, 6
-        // If remote wants to refine
-        if (remote_needs_refining == 1) {
-          if (local_lock_case == unlocked) {
-            local_needs_refining = 1;
-            local_needs_derefining = false;
-            if (local_needs_refining != local_needs_refining_orig ||
-              local_needs_derefining != local_needs_derefining_orig)
-              ++ncorrcase[1];
-          }
-          else {
-           ++nlocked;
-          }
-        }
-
-        // Row 2
-        // If remote neither wants to refine nor derefine
-        if (remote_needs_refining == 0 && remote_needs_derefining == false) {
-          local_needs_derefining = false;
-          if (local_needs_derefining != local_needs_derefining_orig)
-            ++ncorrcase[2];
-        }
-
-        // Row 1: special case
-        // If remote wants to deref-ref (either of 8:4, 8:2, 4:2)
-        // and local does not want to refine (neither pure ref nor deref-ref)
-        if (remote_needs_refining == 2 && local_needs_refining == 0) {
-          if (local_lock_case == unlocked) {
-            local_needs_refining = 1;
-            local_needs_derefining = false;
-            if (local_needs_refining != local_needs_refining_orig ||
-              local_needs_derefining != local_needs_derefining_orig)
-              ++ncorrcase[3];
-          }
-          else {
-            ++nlocked;<--- Variable 'nlocked' is assigned a value that is never used.
-          }
-        }
-
-        // Rows 4, 7, 8
-
-        // if the remote sent us data that makes us change our local state,
-        // e.g., local{-,0} + remote{r,0} -> local{r,0}, i.e., I changed my
-        // state I need to tell the world about it
-        if (local_lock_case != local_lock_case_orig ||
-            local_needs_refining != local_needs_refining_orig ||
-            local_needs_derefining != local_needs_derefining_orig)
-        {
-          auto l1 = tk::cref_find( m_lid, edge[0] );
-          auto l2 = tk::cref_find( m_lid, edge[1] );
-          Assert( l1 != l2, "Edge end-points local ids are the same" );
-          auto r1 = m_rid[ l1 ];
-          auto r2 = m_rid[ l2 ];
-          Assert( r1 != r2, "Edge end-points refiner ids are the same" );
-          //std::cout << thisIndex << ": " << r1 << ", " << r2 << std::endl;
-          //if (m_refiner.tet_store.edge_store.get(AMR::edge_t(r1,r2)).lock_case > local_lock_case) {
-          //  std::cout << thisIndex << ": edge " << r1 << "-" << r2 <<
-          //    "; prev=" << local_lock_case_orig <<
-          //    "; new=" << local_lock_case <<
-          //    "; amr-lib=" << m_refiner.tet_store.edge_store.get(AMR::edge_t(r1,r2)).lock_case <<
-          //    " | parcompatiter " << m_ncit << std::endl;
-          //}
-           extra[ {{ std::min(r1,r2), std::max(r1,r2) }} ] =
-             { local_needs_refining, local_needs_derefining, local_lock_case };
-        }
-        // or if the remote data is inconsistent with what I think, e.g.,
-        // local{r,0} + remote{-,0} -> local{r,0}, i.e., the remote does not
-        // yet agree, so another par-compat iteration will be pursued. but
-        // I do not have to locally run ref-compat.
-        else if (local_lock_case != remote_lock_case ||
-          local_needs_refining != remote_needs_refining ||
-          local_needs_derefining != remote_needs_derefining)
-        {
-          ++neigh_extra;
-        }
-      }
-    }
-  }
-
-  m_remoteEdgeData.clear();
-  m_extra = extra.size();
-  //std::cout << thisIndex << ": amr correction reqd for nedge: " << m_extra << std::endl;
-  //std::cout << thisIndex << ": amr correction reqd for neighbor edges: " << neigh_extra << std::endl;
-  //std::cout << thisIndex << ": edge counts by correction case: " << ncorrcase[0]
-  //  << ", " << ncorrcase[1] << ", " << ncorrcase[2] << ", " << ncorrcase[3] << std::endl;
-  //std::cout << thisIndex << ": locked edges that req corr: " << nlocked << std::endl;
-
-  if (!extra.empty()) {
-    //std::cout << thisIndex << ": redoing markings" << std::endl;
-    // Do refinement compatibility (ref-compat) for edges that need correction
-    m_refiner.mark_error_refinement_corr( extra );
-    ++m_ncit;
-    // Update our extra-edge store based on refiner
-    updateEdgeData();
-    m_remoteEdges.clear();
-  }
-  else if (neigh_extra == 0) {
-    m_ncit = 0;
-  }
-
-  // Aggregate number of extra edges that still need correction and some
-  // refinement/derefinement statistics
-  const auto& tet_store = m_refiner.tet_store;
-  std::vector< std::size_t >
-    m{ m_meshid,
-       m_extra,
-       tet_store.marked_refinements.size(),
-       tet_store.marked_derefinements.size(),
-       static_cast< std::underlying_type_t< RefMode > >( m_mode ) };
-  contribute( m, CkReduction::sum_ulong, m_cbr.get< tag::matched >() );
-}
-
-void
-Refiner::updateEdgeData()
-// *****************************************************************************
-// Query AMR lib and update our local store of edge data
-// *****************************************************************************
-{
-  m_localEdgeData.clear();
-  m_intermediates.clear();
-
-  // This currently takes ALL edges from the AMR lib, i.e., on the whole
-  // domain. We should eventually only collect edges here that are shared with
-  // other chares.
-  const auto& ref_edges = m_refiner.tet_store.edge_store.edges;
-  const auto& refinpoel = m_refiner.tet_store.get_active_inpoel();
-
-  for (std::size_t e=0; e<refinpoel.size()/4; ++e) {
-    auto A = refinpoel[e*4+0];
-    auto B = refinpoel[e*4+1];
-    auto C = refinpoel[e*4+2];
-    auto D = refinpoel[e*4+3];
-    std::array<Edge,6> edges{{ {{A,B}}, {{B,C}}, {{A,C}},
-                               {{A,D}}, {{B,D}}, {{C,D}} }};
-    for (const auto& ed : edges) {
-      auto ae = AMR::edge_t{{{ std::min(ed[0],ed[1]), std::max(ed[0],ed[1]) }}};
-      auto r = tk::cref_find( ref_edges, ae );
-      const auto ged = Edge{{ m_gid[ tk::cref_find( m_lref, ed[0] ) ],
-                              m_gid[ tk::cref_find( m_lref, ed[1] ) ] }};
-      m_localEdgeData[ ged ] = { r.needs_refining, r.needs_derefining,
-        r.lock_case };
-    }
-  }
-
-  // Build intermediates to send. This currently takes ALL intermediates from
-  // the AMR lib, i.e., on the whole domain. We should eventually only collect
-  // edges here that are shared with other chares.
-  for (const auto& r : m_refiner.tet_store.intermediate_list) {
-    m_intermediates.insert( m_gid[ tk::cref_find( m_lref, r ) ] );
-  }
-}
-
-void
-Refiner::updateBndEdgeData()
-// *****************************************************************************
-// Query AMR lib and update our local store of boundary edge data
-// *****************************************************************************
-{
-  // This currently takes ALL edges from the AMR lib, i.e., on the whole
-  // domain. We should eventually only collect edges here that are shared with
-  // other chares.
-  const auto& ref_edges = m_refiner.tet_store.edge_store.edges;
-  const auto& refinpoel = m_refiner.tet_store.get_active_inpoel();
-
-  for (std::size_t e=0; e<refinpoel.size()/4; ++e) {
-    auto A = refinpoel[e*4+0];
-    auto B = refinpoel[e*4+1];
-    auto C = refinpoel[e*4+2];
-    auto D = refinpoel[e*4+3];
-    std::array<Edge,6> edges{{ {{A,B}}, {{B,C}}, {{A,C}},
-                               {{A,D}}, {{B,D}}, {{C,D}} }};
-    for (const auto& ed : edges) {
-      auto ae = AMR::edge_t{{{ std::min(ed[0],ed[1]), std::max(ed[0],ed[1]) }}};
-      auto r = tk::cref_find( ref_edges, ae );
-      const auto ged = Edge{{ m_gid[ tk::cref_find( m_lref, ed[0] ) ],
-                              m_gid[ tk::cref_find( m_lref, ed[1] ) ] }};
-      // only update edges that are on chare boundary OR unlocked
-      if (m_localEdgeData.find(ged) == m_localEdgeData.end() ||
-        std::get<2>(m_localEdgeData[ged]) == AMR::Edge_Lock_Case::unlocked) {
-        m_localEdgeData[ ged ] = { r.needs_refining, r.needs_derefining,
-          r.lock_case };
-      }
-    }
-  }
-}
-
-std::tuple< std::vector< std::string >,
-            std::vector< std::vector< tk::real > >,
-            std::vector< std::string >,
-            std::vector< std::vector< tk::real > > >
-Refiner::refinementFields() const
-// *****************************************************************************
-//  Collect mesh output fields from refiner lib
-//! \return Names and fields of mesh refinement data in mesh cells and nodes
-// *****************************************************************************
-{
-  // Find number of nodes in current mesh
-  auto npoin = tk::npoin_in_graph( m_inpoel );
-  // Generate edges surrounding points in current mesh
-  auto esup = tk::genEsup( m_inpoel, 4 );
-
-  // Update solution on current mesh
-  const auto& u = solution( npoin, esup );
-  Assert( u.nunk() == npoin, "Solution uninitialized or wrong size" );
-
-  // Compute error in edges on current mesh
-  auto edgeError = errorsInEdges( npoin, esup, u );
-
-  // Transfer error from edges to cells for field output
-  std::vector< tk::real > error( m_inpoel.size()/4, 0.0 );
-  for (std::size_t e=0; e<m_inpoel.size()/4; ++e) {
-    auto A = m_inpoel[e*4+0];
-    auto B = m_inpoel[e*4+1];
-    auto C = m_inpoel[e*4+2];
-    auto D = m_inpoel[e*4+3];
-    std::array<Edge,6> edges{{ {{A,B}}, {{B,C}}, {{A,C}},
-                               {{A,D}}, {{B,D}}, {{C,D}} }};
-    // sum error from edges to elements
-    for (const auto& ed : edges) error[e] += tk::cref_find( edgeError, ed );
-    error[e] /= 6.0;    // assign edge-average error to element
-  }
-
-  // Prepare element fields with mesh refinement data
-  std::vector< std::string >
-    elemfieldnames{ "refinement level", "cell type", "error" };
-  auto& tet_store = m_refiner.tet_store;
-  std::vector< std::vector< tk::real > > elemfields{
-    tet_store.get_refinement_level_list(),
-    tet_store.get_cell_type_list(),
-    error };
-
-  using tuple_t = std::tuple< std::vector< std::string >,
-                              std::vector< std::vector< tk::real > >,
-                              std::vector< std::string >,
-                              std::vector< std::vector< tk::real > > >;
-  return tuple_t{ elemfieldnames, elemfields, {}, {} };
-}
-
-void
-Refiner::writeMesh( const std::string& basefilename,
-                    uint64_t itr,
-                    tk::real t,
-                    CkCallback c ) const
-// *****************************************************************************
-//  Output mesh to file(s)
-//! \param[in] basefilename File name to append to
-//! \param[in] itr Iteration count since a new mesh
-//! \param[in] t "Physical time" to write to file. "Time" here is used to
-//!   designate a new time step at which the mesh is saved.
-//! \param[in] c Function to continue with after the write
-// *****************************************************************************
-{
-  auto r = refinementFields();
-  auto& elemfieldnames = std::get< 0 >( r );
-  auto& elemfields = std::get< 1 >( r );
-  auto& nodefieldnames = std::get< 2 >( r );
-  auto& nodefields = std::get< 3 >( r );
-
-  // Prepare solution field names: depvar + component id for all eqs
-  auto nprop = g_inputdeck.get< tag::ncomp >();
-  std::vector< std::string > solfieldnames;
-  for (std::size_t i=0; i<nprop; ++i) {
-    solfieldnames.push_back(
-      g_inputdeck.get< tag::depvar >()[0] + std::to_string(i+1) );
-  }
-  Assert( solfieldnames.size() == nprop, "Size mismatch" );
-
-  const auto scheme = g_inputdeck.get< tag::scheme >();
-  const auto centering = ctr::Scheme().centering( scheme );
-  auto t0 = g_inputdeck.get< tag::t0 >();
-
-  // list of nodes/elements at which box ICs are defined
-  std::vector< std::unordered_set< std::size_t > > inbox;
-  tk::real V = 1.0;
-  std::vector< tk::real > blkvols;
-  std::unordered_map< std::size_t, std::set< std::size_t > > nodeblockid,
-    elemblockid;
-
-  // Prepare node or element fields for output to file
-  if (centering == tk::Centering::NODE) {
-
-    // Augment element field names with solution variable names + field ids
-    nodefieldnames.insert( end(nodefieldnames),
-                           begin(solfieldnames), end(solfieldnames) );
-
-    // Evaluate initial conditions on current mesh at t0
-    tk::Fields u( m_coord[0].size(), nprop );
-    g_cgpde[m_meshid].initialize( m_coord, u, t0, V, inbox, blkvols,
-      nodeblockid );
-
-    // Extract all scalar components from solution for output to file
-    for (std::size_t i=0; i<nprop; ++i)
-      nodefields.push_back( u.extract_comp( i ) );
-
-  } else if (centering == tk::Centering::ELEM) {
-
-    // Augment element field names with solution variable names + field ids
-    elemfieldnames.insert( end(elemfieldnames),
-                           begin(solfieldnames), end(solfieldnames) );
-
-    auto ndof = g_inputdeck.get< tag::ndof >();
-    tk::Fields lhs( m_inpoel.size()/4, ndof*nprop );
-
-    // Generate left hand side for DG and evaluate initial conditions on
-    // current mesh at t0
-    auto geoElem = tk::genGeoElemTet( m_inpoel, m_coord );
-    auto u = lhs;
-    if (scheme == ctr::SchemeType::FV) {
-      g_fvpde[m_meshid].lhs( geoElem, lhs );
-      g_fvpde[m_meshid].initialize( lhs, m_inpoel, m_coord, inbox, elemblockid,
-        u, t0, m_inpoel.size()/4 );
-    }
-    else {
-      g_dgpde[m_meshid].lhs( geoElem, lhs );
-      g_dgpde[m_meshid].initialize( lhs, m_inpoel, m_coord, inbox, elemblockid,
-        u, t0, m_inpoel.size()/4 );
-    }
-
-    // Extract all scalar components from solution for output to file
-    for (std::size_t i=0; i<nprop; ++i)
-      elemfields.push_back( u.extract_comp( i ) );
-  }
-
-  // Output mesh
-  m_meshwriter[ CkNodeFirst( CkMyNode() ) ].
-    write( m_meshid, /*meshoutput = */ true, /*fieldoutput = */ true, itr, 1, t,
-           thisIndex, basefilename, m_inpoel, m_coord, m_bface,
-           tk::remap(m_bnode,m_lid), tk::remap(m_triinpoel,m_lid),
-           elemfieldnames, nodefieldnames, {}, {}, elemfields, nodefields, {},
-           {}, {}, c );
-}
-
-void
-Refiner::perform()
-// *****************************************************************************
-// Perform mesh refinement and decide how to continue
-//! \details First the mesh refiner object is called to perform a single step
-//!   of mesh refinement. Then, if this function is called during a step
-//!   (potentially multiple levels of) initial AMR, it evaluates whether to do
-//!   another one. If it is called during time stepping, this concludes the
-//!   single mesh refinement step and the new mesh is sent to the PDE worker
-//!   (Discretization).
-// *****************************************************************************
-{
-  // Save old tets and their ids before performing refinement. Outref is always
-  // followed by outderef, so to the outside world, the mesh is uchanged, thus
-  // no update.
-  if (m_mode != RefMode::OUTREF && m_mode != RefMode::OUTDEREF) {
-    m_oldTets.clear();
-    for (const auto& [ id, tet ] : m_refiner.tet_store.tets) {
-      m_oldTets.insert( tet );
-    }
-    m_oldntets = m_oldTets.size();
-  }
-
-  if (m_mode == RefMode::T0REF) {
-
-    // Refine mesh based on next initial refinement type
-    if (!m_initref.empty()) {
-      auto r = m_initref.back();    // consume (reversed) list from its back
-      if (r == ctr::AMRInitialType::UNIFORM_DEREFINE)
-        m_refiner.perform_derefinement();
-      else
-        m_refiner.perform_refinement();
-    }
-
-  } else {
-
-    // TODO: does not work yet, fix as above
-    m_refiner.perform_refinement();
-    m_refiner.perform_derefinement();
-  }
-
-  // Remove temporary edge-locks resulting from the parallel compatibility
-  m_refiner.remove_edge_locks(1);
-  m_refiner.remove_edge_temp_locks();
-
-  //auto& tet_store = m_refiner.tet_store;
-  //std::cout << "before ref: " << tet_store.marked_refinements.size() << ", " << tet_store.marked_derefinements.size() << ", " << tet_store.size() << ", " << tet_store.get_active_inpoel().size() << '\n';
-  //std::cout << "after ref: " << tet_store.marked_refinements.size() << ", " << tet_store.marked_derefinements.size() << ", " << tet_store.size() << ", " << tet_store.get_active_inpoel().size() << '\n';
-  //std::cout << "after deref: " << tet_store.marked_refinements.size() << ", " << tet_store.marked_derefinements.size() << ", " << tet_store.size() << ", " << tet_store.get_active_inpoel().size() << '\n';
-
-  // Update volume and boundary mesh
-  updateMesh();
-
-  // Save mesh at every initial refinement step (mainly for debugging). Will
-  // replace with just a 'next()' in production.
-  if (m_mode == RefMode::T0REF) {
-
-    auto l = m_ninitref - m_initref.size() + 1;  // num initref steps completed
-    auto t0 = g_inputdeck.get< tag::t0 >();
-    // Generate times equally subdividing t0-1...t0 to ninitref steps
-    auto t =
-      t0 - 1.0 + static_cast<tk::real>(l)/static_cast<tk::real>(m_ninitref);
-    auto itr = l;
-    // Output mesh after refinement step
-    writeMesh( "t0ref", itr, t,
-               CkCallback( CkIndex_Refiner::next(), thisProxy[thisIndex] ) );
-
-  } else {
-
-    next();
-
-  }
-}
-
-void
-Refiner::next()
-// *****************************************************************************
-// Continue after finishing a refinement step
-// *****************************************************************************
-{
-  if (m_mode == RefMode::T0REF) {
-
-    // Remove initial mesh refinement step from list
-    if (!m_initref.empty()) m_initref.pop_back();
-    // Continue to next initial AMR step or finish
-    if (!m_initref.empty()) t0ref(); else endt0ref();
-
-  } else if (m_mode == RefMode::DTREF) {
-
-    // Send new mesh, solution, and communication data back to PDE worker
-    m_scheme[m_meshid].ckLocal< Scheme::resizePostAMR >( thisIndex,  m_ginpoel,
-      m_el, m_coord, m_addedNodes, m_addedTets, m_removedNodes, m_amrNodeMap,
-      m_nodeCommMap, m_bface, m_bnode, m_triinpoel, m_elemblockid );
-
-  } else if (m_mode == RefMode::OUTREF) {
-
-    // Store field output mesh
-    m_outref_ginpoel = m_ginpoel;
-    m_outref_el = m_el;
-    m_outref_coord = m_coord;
-    m_outref_addedNodes = m_addedNodes;
-    m_outref_addedTets = m_addedTets;
-    m_outref_nodeCommMap = m_nodeCommMap;
-    m_outref_bface = m_bface;
-    m_outref_bnode = m_bnode;
-    m_outref_triinpoel = m_triinpoel;
-
-    // Derefine mesh to the state previous to field output
-    outref( m_outref_bface, m_outref_bnode, m_outref_triinpoel, m_writeCallback,
-            RefMode::OUTDEREF );
-
-  } else if (m_mode == RefMode::OUTDEREF) {
-
-    // Send field output mesh to PDE worker
-    m_scheme[m_meshid].ckLocal< Scheme::extractFieldOutput >( thisIndex,
-      m_outref_ginpoel, m_outref_el, m_outref_coord, m_outref_addedNodes,
-      m_outref_addedTets, m_outref_nodeCommMap, m_outref_bface, m_outref_bnode,
-      m_outref_triinpoel, m_writeCallback );
-
-  } else Throw( "RefMode not implemented" );
-}
-
-void
-Refiner::endt0ref()
-// *****************************************************************************
-// Finish initial mesh refinement
-//! \details This function is called as after initial mesh refinement has
-//!   finished. If initial mesh reifnement was not configured by the user, this
-//!   is the point where we continue after the constructor, by computing the
-//!   total number of elements across the whole problem.
-// *****************************************************************************
-{
-  // create sorter Charm++ chare array elements using dynamic insertion
-  m_sorter[ thisIndex ].insert( m_meshid, m_host, m_meshwriter, m_cbs, m_scheme,
-    CkCallback(CkIndex_Refiner::reorder(), thisProxy[thisIndex]), m_ginpoel,
-    m_coordmap, m_el, m_bface, m_triinpoel, m_bnode, m_elemblockid, m_nchare );
-
-  // Compute final number of cells across whole problem
-  std::vector< std::size_t >
-    meshdata{ m_meshid, m_ginpoel.size()/4, m_coord[0].size() };
-  contribute( meshdata, CkReduction::sum_ulong, m_cbr.get< tag::refined >() );
-
-  // // Free up memory if no dtref
-  // if (!g_inputdeck.get< tag::amr, tag::dtref >()) {
-  //   tk::destroy( m_ginpoel );
-  //   tk::destroy( m_el );
-  //   tk::destroy( m_coordmap );
-  //   tk::destroy( m_coord );
-  //   tk::destroy( m_bface );
-  //   tk::destroy( m_bnode );
-  //   tk::destroy( m_triinpoel );
-  //   tk::destroy( m_initref );
-  //   tk::destroy( m_ch );
-  //   tk::destroy( m_edgech );
-  //   tk::destroy( m_chedge );
-  //   tk::destroy( m_localEdgeData );
-  //   tk::destroy( m_remoteEdgeData );
-  //   tk::destroy( m_remoteEdges );
-  //   tk::destroy( m_intermediates );
-  //   tk::destroy( m_nodeCommMap );
-  //   tk::destroy( m_oldTets );
-  //   tk::destroy( m_addedNodes );
-  //   tk::destroy( m_addedTets );
-  //   tk::destroy( m_coarseBndFaces );
-  //   tk::destroy( m_coarseBndNodes );
-  //   tk::destroy( m_rid );
-//  //   tk::destroy( m_oldrid );
-  //   tk::destroy( m_lref );
-//  //   tk::destroy( m_oldparent );
-  // }
-}
-
-void
-Refiner::uniformRefine()
-// *****************************************************************************
-// Do uniform mesh refinement
-// *****************************************************************************
-{
-  // Do uniform refinement
-  m_refiner.mark_uniform_refinement();
-
-  // Update our extra-edge store based on refiner
-  updateEdgeData();
-
-  // Set number of extra edges to be zero, skipping correction (if this is the
-  // only step in this refinement step)
-  m_extra = 0;
-}
-
-void
-Refiner::uniformDeRefine()
-// *****************************************************************************
-// Do uniform mesh derefinement
-// *****************************************************************************
-{
-  // Do uniform derefinement
-  m_refiner.mark_uniform_derefinement();
-
-  // Update our extra-edge store based on refiner
-  updateEdgeData();
-
-  // Set number of extra edges to be zero, skipping correction (if this is the
-  // only step in this refinement step)
-  m_extra = 0;
-}
-
-Refiner::EdgeError
-Refiner::errorsInEdges(
-  std::size_t npoin,
-  const std::pair< std::vector<std::size_t>, std::vector<std::size_t> >& esup,
-  const tk::Fields& u ) const
-// *****************************************************************************
-//  Compute errors in edges
-//! \param[in] npoin Number nodes in current mesh (partition)
-//! \param[in] esup Elements surrounding points linked vectors
-//! \param[in] u Solution evaluated at mesh nodes for all scalar components
-//! \return A map associating errors (real values between 0.0 and 1.0 incusive)
-//!   to edges (2 local node IDs)
-// *****************************************************************************
-{
-  // Get the indices (in the system of systems) of refinement variables and the
-  // error indicator configured
-  auto ncomp = g_inputdeck.get< tag::ncomp >();
-  auto errtype = g_inputdeck.get< tag::amr, tag::error >();
-
-  // Compute points surrounding points
-  auto psup = tk::genPsup( m_inpoel, 4, esup );
-
-  // Compute errors in ICs and define refinement criteria for edges
-  AMR::Error error;
-  EdgeError edgeError;
-
-  for (std::size_t p=0; p<npoin; ++p) { // for all mesh nodes on this chare
-    for (auto q : tk::Around(psup,p)) { // for all nodes surrounding p
-      tk::real cmax = 0.0;
-      AMR::edge_t e(p,q);
-      for (std::size_t i=0; i<ncomp; ++i) { // for all refinement variables
-        auto c = error.scalar( u, e, i, m_coord, m_inpoel, esup, errtype );
-        if (c > cmax) cmax = c;        // find max error at edge
-      }
-      edgeError[ {{p,q}} ] = cmax;       // associate error to edge
-    }
-  }
-
-  return edgeError;
-}
-
-tk::Fields
-Refiner::solution( std::size_t npoin,
-                   const std::pair< std::vector< std::size_t >,
-                                    std::vector< std::size_t > >& esup ) const
-// *****************************************************************************
-//  Update (or evaluate) solution on current mesh
-//! \param[in] npoin Number nodes in current mesh (partition)
-//! \param[in] esup Elements surrounding points linked vectors
-//! \return Solution updated/evaluated for all scalar components
-// *****************************************************************************
-{
-  // Get solution whose error to evaluate
-  tk::Fields u;
-
-  if (m_mode == RefMode::T0REF) {
-
-    // Evaluate initial conditions at mesh nodes
-    u = nodeinit( npoin, esup );
-
-  } else if (m_mode == RefMode::DTREF) {
-
-    // Query current solution
-    u = m_scheme[m_meshid].ckLocal< Scheme::solution >( thisIndex );
- 
-    const auto scheme = g_inputdeck.get< tag::scheme >();
-    const auto centering = ctr::Scheme().centering( scheme );
-    if (centering == tk::Centering::ELEM) {
-
-      // ...
-      Throw("Element-based solution handling not implemented in Refiner");
-
-    }
-
-  } else if (m_mode == RefMode::OUTREF) {
-
-
-
-  } else if (m_mode == RefMode::OUTDEREF) {
-
-
-
-  } else Throw( "RefMode not implemented" );
-
-  return u;
-}
-
-void
-Refiner::errorRefine()
-// *****************************************************************************
-// Do error-based mesh refinement and derefinement
-// *****************************************************************************
-{
-  // Find number of nodes in old mesh
-  auto npoin = tk::npoin_in_graph( m_inpoel );
-  // Generate edges surrounding points in old mesh
-  auto esup = tk::genEsup( m_inpoel, 4 );
-
-  // Update solution on current mesh
-  const auto& u = solution( npoin, esup );
-  Assert( u.nunk() == npoin, "Solution uninitialized or wrong size" );
-
-  using AMR::edge_t;
-  using AMR::edge_tag;
-
-  // Compute error in edges. Tag edge for refinement if error exceeds
-  // refinement tolerance, tag edge for derefinement if error is below
-  // derefinement tolerance.
-  auto tolref = g_inputdeck.get< tag::amr, tag::tol_refine >();
-  auto tolderef = g_inputdeck.get< tag::amr, tag::tol_derefine >();
-  std::vector< std::pair< edge_t, edge_tag > > tagged_edges;
-  for (const auto& e : errorsInEdges(npoin,esup,u)) {
-    if (e.second > tolref) {
-      tagged_edges.push_back( { edge_t( m_rid[e.first[0]], m_rid[e.first[1]] ),
-                                edge_tag::REFINE } );
-    } else if (e.second < tolderef) {
-      tagged_edges.push_back( { edge_t( m_rid[e.first[0]], m_rid[e.first[1]] ),
-                                edge_tag::DEREFINE } );
-    }
-  }
-
-  // Do error-based refinement
-  m_refiner.mark_error_refinement( tagged_edges );
-
-  // Update our extra-edge store based on refiner
-  updateEdgeData();
-
-  // Set number of extra edges to a nonzero number, triggering correction
-  m_extra = 1;
-}
-
-void
-Refiner::edgelistRefine()
-// *****************************************************************************
-// Do mesh refinement based on user explicitly tagging edges
-// *****************************************************************************
-{
-  // Get user-defined node-pairs (edges) to tag for refinement
-  const auto& edgenodelist = g_inputdeck.get< tag::amr, tag::edgelist >();
-
-  if (!edgenodelist.empty()) {  // if user explicitly tagged edges
-    // Find number of nodes in old mesh
-    auto npoin = tk::npoin_in_graph( m_inpoel );
-    // Generate edges surrounding points in old mesh
-    auto esup = tk::genEsup( m_inpoel, 4 );
-    auto psup = tk::genPsup( m_inpoel, 4, esup );
-
-    EdgeSet useredges;
-    for (std::size_t i=0; i<edgenodelist.size()/2; ++i)
-      useredges.insert( {{ {edgenodelist[i*2+0], edgenodelist[i*2+1]} }} );
-
-    using AMR::edge_t;
-    using AMR::edge_tag;
-
-    // Tag edges the user configured
-    std::vector< std::pair< edge_t, edge_tag > > tagged_edges;
-    for (std::size_t p=0; p<npoin; ++p)        // for all mesh nodes on this chare
-      for (auto q : tk::Around(psup,p)) {      // for all nodes surrounding p
-        Edge e{{ m_gid[p], m_gid[q] }};
-        auto f = useredges.find(e);
-        if (f != end(useredges)) { // tag edge if on user's list
-          tagged_edges.push_back( { edge_t( m_rid[p], m_rid[q] ),
-                                    edge_tag::REFINE } );
-          useredges.erase( f );
-        }
-      }
-
-    // Do error-based refinement
-    m_refiner.mark_error_refinement( tagged_edges );
-
-    // Update our extra-edge store based on refiner
-    updateEdgeData();
-
-    // Set number of extra edges to a nonzero number, triggering correction
-    m_extra = 1;
-  }
-}
-
-void
-Refiner::coordRefine()
-// *****************************************************************************
-// Do mesh refinement based on tagging edges based on end-point coordinates
-// *****************************************************************************
-{
-  // Get user-defined half-world coordinates
-  const auto& amr_coord = g_inputdeck.get< tag::amr, tag::coords >();
-  auto xminus = amr_coord.get< tag::xminus >();
-  auto xplus  = amr_coord.get< tag::xplus >();
-  auto yminus = amr_coord.get< tag::yminus >();
-  auto yplus  = amr_coord.get< tag::yplus >();
-  auto zminus = amr_coord.get< tag::zminus >();
-  auto zplus  = amr_coord.get< tag::zplus >();
-
-  // The default is the largest representable double
-  auto eps =
-    std::numeric_limits< tk::real >::epsilon();
-  const auto& amr_defcoord = g_inputdeck_defaults.get< tag::amr, tag::coords >();
-  auto xminus_default = amr_defcoord.get< tag::xminus >();
-  auto xplus_default = amr_defcoord.get< tag::xplus >();
-  auto yminus_default = amr_defcoord.get< tag::yminus >();
-  auto yplus_default = amr_defcoord.get< tag::yplus >();
-  auto zminus_default = amr_defcoord.get< tag::zminus >();
-  auto zplus_default = amr_defcoord.get< tag::zplus >();
-
-  // Decide if user has configured the half-world
-  bool xm = std::abs(xminus - xminus_default) > eps ? true : false;
-  bool xp = std::abs(xplus - xplus_default) > eps ? true : false;
-  bool ym = std::abs(yminus - yminus_default) > eps ? true : false;
-  bool yp = std::abs(yplus - yplus_default) > eps ? true : false;
-  bool zm = std::abs(zminus - zminus_default) > eps ? true : false;
-  bool zp = std::abs(zplus - zplus_default) > eps ? true : false;
-
-  using AMR::edge_t;
-  using AMR::edge_tag;
-
-  if (xm || xp || ym || yp || zm || zp) {       // if any half-world configured
-    // Find number of nodes in old mesh
-    auto npoin = tk::npoin_in_graph( m_inpoel );
-    // Generate edges surrounding points in old mesh
-    auto esup = tk::genEsup( m_inpoel, 4 );
-    auto psup = tk::genPsup( m_inpoel, 4, esup );
-    // Get access to node coordinates
-    const auto& x = m_coord[0];
-    const auto& y = m_coord[1];
-    const auto& z = m_coord[2];
-    // Compute edges to be tagged for refinement
-    std::vector< std::pair< edge_t, edge_tag > > tagged_edges;
-    for (std::size_t p=0; p<npoin; ++p)    // for all mesh nodes on this chare
-      for (auto q : tk::Around(psup,p)) {  // for all nodes surrounding p
-        Edge e{{p,q}};
-
-        bool t = true;
-        if (xm) { if (x[p]>xminus && x[q]>xminus) t = false; }
-        if (xp) { if (x[p]<xplus && x[q]<xplus) t = false; }
-        if (ym) { if (y[p]>yminus && y[q]>yminus) t = false; }
-        if (yp) { if (y[p]<yplus && y[q]<yplus) t = false; }
-        if (zm) { if (z[p]>zminus && z[q]>zminus) t = false; }
-        if (zp) { if (z[p]<zplus && z[q]<zplus) t = false; }
-
-        if (t) {
-          tagged_edges.push_back( { edge_t( m_rid[e[0]], m_rid[e[1]] ),
-                                    edge_tag::REFINE } );
-        }
-      }
-
-    // Do error-based refinement
-    m_refiner.mark_error_refinement( tagged_edges );
-
-    // Update our extra-edge store based on refiner
-    updateEdgeData();
-
-    // Set number of extra edges to a nonzero number, triggering correction
-    m_extra = 1;
-  }
-}
-
-tk::Fields
-Refiner::nodeinit( std::size_t npoin,
-                   const std::pair< std::vector< std::size_t >,
-                                    std::vector< std::size_t > >& esup ) const
-// *****************************************************************************
-// Evaluate initial conditions (IC) at mesh nodes
-//! \param[in] npoin Number points in mesh (on this chare)
-//! \param[in] esup Elements surrounding points as linked lists, see tk::genEsup
-//! \return Initial conditions (evaluated at t0) at nodes
-// *****************************************************************************
-{
-  auto t0 = g_inputdeck.get< tag::t0 >();
-  auto nprop = g_inputdeck.get< tag::ncomp >();
-
-  // Will store nodal ICs
-  tk::Fields u( m_coord[0].size(), nprop );
-
-  // Evaluate ICs differently depending on nodal or cell-centered discretization
-  const auto scheme = g_inputdeck.get< tag::scheme >();
-  const auto centering = ctr::Scheme().centering( scheme );
-  // list of nodes/elements at which box ICs are defined
-  std::vector< std::unordered_set< std::size_t > > inbox;
-  tk::real V = 1.0;
-  std::vector< tk::real > blkvols;
-  std::unordered_map< std::size_t, std::set< std::size_t > > nodeblockid,
-    elemblockid;
-
-  if (centering == tk::Centering::NODE) {
-
-    // Evaluate ICs for all scalar components integrated
-    g_cgpde[m_meshid].initialize( m_coord, u, t0, V, inbox, blkvols,
-      nodeblockid );
-
-  } else if (centering == tk::Centering::ELEM) {
-
-    auto esuel = tk::genEsuelTet( m_inpoel, esup ); // elems surrounding elements
-    // Initialize cell-based unknowns
-    tk::Fields ue( m_inpoel.size()/4, nprop );
-    auto lhs = ue;
-    auto geoElem = tk::genGeoElemTet( m_inpoel, m_coord );
-    if (scheme == ctr::SchemeType::FV) {
-    g_fvpde[m_meshid].lhs( geoElem, lhs );
-    g_fvpde[m_meshid].initialize( lhs, m_inpoel, m_coord, inbox, elemblockid,
-      ue, t0, esuel.size()/4 );
-    }
-    else {
-    g_dgpde[m_meshid].lhs( geoElem, lhs );
-    g_dgpde[m_meshid].initialize( lhs, m_inpoel, m_coord, inbox, elemblockid,
-      ue, t0, esuel.size()/4 );
-    }
-
-    // Transfer initial conditions from cells to nodes
-    for (std::size_t p=0; p<npoin; ++p) {    // for all mesh nodes on this chare
-      std::vector< tk::real > up( nprop, 0.0 );
-      tk::real vol = 0.0;
-      for (auto e : tk::Around(esup,p)) {       // for all cells around node p
-        // compute nodal volume: every element contributes their volume / 4
-        vol += geoElem(e,0) / 4.0;
-        // sum cell value to node weighed by cell volume / 4
-        for (std::size_t c=0; c<nprop; ++c)
-          up[c] += ue[e][c] * geoElem(e,0) / 4.0;
-      }
-      // store nodal value
-      for (std::size_t c=0; c<nprop; ++c) u(p,c) = up[c] / vol;
-    }
-
-  } else Throw( "Scheme centring not handled for nodal initialization" );
-
-  Assert( u.nunk() == m_coord[0].size(), "Size mismatch" );
-  Assert( u.nprop() == nprop, "Size mismatch" );
-
-  return u;
-}
-
-void
-Refiner::updateMesh()
-// *****************************************************************************
-// Update old mesh after refinement
-// *****************************************************************************
-{
-  // Get refined mesh connectivity
-  const auto& refinpoel = m_refiner.tet_store.get_active_inpoel();
-  Assert( refinpoel.size()%4 == 0, "Inconsistent refined mesh connectivity" );
-
-  // Generate unique node lists of old and refined mesh using local ids
-  auto rinpoel = m_inpoel;
-  tk::remap( rinpoel, m_rid );
-  std::unordered_set< std::size_t > old( begin(rinpoel), end(rinpoel) );
-  std::unordered_set< std::size_t > ref( begin(refinpoel), end(refinpoel) );
-
-  // Augment refiner id -> local node id map with newly added nodes
-  std::size_t l = m_lref.size();
-  for (auto r : ref) if (old.find(r) == end(old)) m_lref[r] = l++;
-
-  // Get nodal communication map from Discretization worker
-  if ( m_mode == RefMode::DTREF ||
-       m_mode == RefMode::OUTREF ||
-       m_mode == RefMode::OUTDEREF ) {
-    m_nodeCommMap =
-      m_scheme[m_meshid].disc()[thisIndex].ckLocal()->NodeCommMap();
-  }
-
-  // Update mesh and solution after refinement
-  newVolMesh( old, ref );
-
-  // Update mesh connectivity from refiner lib, remapping refiner to local ids
-  m_inpoel = m_refiner.tet_store.get_active_inpoel();
-  tk::remap( m_inpoel, m_lref );
-
-  // Update mesh connectivity with new global node ids
-  m_ginpoel = m_inpoel;
-  Assert( tk::uniquecopy(m_ginpoel).size() == m_coord[0].size(),
-          "Size mismatch" );
-  tk::remap( m_ginpoel, m_gid );
-
-  // Update boundary face and node information
-  newBndMesh( ref );
-
-  // Augment node communication map with newly added nodes on chare-boundary
-  if (m_mode == RefMode::DTREF || m_mode == RefMode::OUTREF) {
-    for (const auto& [ neighborchare, edges ] : m_remoteEdges) {
-      auto& nodes = tk::ref_find( m_nodeCommMap, neighborchare );
-      for (const auto& e : edges) {
-        // If parent nodes were part of the node communication map for chare
-        if (nodes.find(e[0]) != end(nodes) && nodes.find(e[1]) != end(nodes)) {
-          // Add new node if local id was generated for it
-          auto n = Hash<2>()( e );
-          if (m_lid.find(n) != end(m_lid)) nodes.insert( n );
-        }
-      }
-    }
-  }
-
-  // Ensure valid mesh after refinement
-  Assert( tk::positiveJacobians( m_inpoel, m_coord ),
-          "Refined mesh cell Jacobian non-positive" );
-
-  Assert( tk::conforming( m_inpoel, m_coord, true, m_rid ),
-          "Chare-"+std::to_string(thisIndex)+
-          " mesh not conforming after updating mesh after mesh refinement" );
-
-  // Perform leak test on new mesh
-  Assert( !tk::leakyPartition(
-            tk::genEsuelTet( m_inpoel, tk::genEsup(m_inpoel,4) ),
-            m_inpoel, m_coord ),
-          "Refined mesh partition leaky" );
-}
-
-void
-Refiner::newVolMesh( const std::unordered_set< std::size_t >& old,
-                     const std::unordered_set< std::size_t >& ref )
-// *****************************************************************************
-//  Compute new volume mesh after mesh refinement
-//! \param[in] old Unique nodes of the old (unrefined) mesh using
-//!   refiner-lib ids
-//! \param[in] ref Unique nodes of the refined mesh using refiner-lib ids
-// *****************************************************************************
-{
-  const auto& x = m_coord[0];
-  const auto& y = m_coord[1];
-  const auto& z = m_coord[2];
-
-  // Generate coordinates and ids to newly added nodes after refinement
-  std::unordered_map< std::size_t, std::size_t > gid_add;
-  tk::destroy( m_addedNodes );
-  tk::destroy( m_removedNodes );
-  tk::destroy( m_amrNodeMap );
-  for (auto r : ref) {               // for all unique nodes of the refined mesh
-    if (old.find(r) == end(old)) {   // if node is newly added
-      // get (local) parent ids of newly added node
-      auto p = m_refiner.node_connectivity.get( r );
-      Assert(p[0] != p[1], "Node without parent edge in newVolMesh");
-      Assert( old.find(p[0]) != end(old) && old.find(p[1]) != end(old),
-              "Parent(s) not in old mesh" );
-      // local parent ids
-      decltype(p) lp{{tk::cref_find(m_lref,p[0]), tk::cref_find(m_lref,p[1])}};
-      // global parent ids
-      decltype(p) gp{{m_gid[lp[0]], m_gid[lp[1]]}};
-      // generate new global ID for newly added node
-      auto g = Hash<2>()( gp );
-
-      // if node added by AMR lib has not yet been added to Refiner's new mesh
-      if (m_coordmap.find(g) == end(m_coordmap)) {
-        Assert( g >= old.size(), "Hashed id overwriting old id" );
-        Assert( m_lid.find(g) == end(m_lid),
-                "Overwriting entry global->local node ID map" );
-        auto l = tk::cref_find( m_lref, r );
-        // store newly added node id and their parent ids (local ids)
-        m_addedNodes[r] = lp;   // key = r for later update to local
-        // assign new node to refiner->global map
-        gid_add[r] = g; // key = r for later search
-        // assign new node to global->local map
-        m_lid[g] = l;
-        // generate and store coordinates for newly added node
-        m_coordmap.insert( {g, {{ (x[lp[0]] + x[lp[1]])/2.0,
-                                  (y[lp[0]] + y[lp[1]])/2.0,
-                                  (z[lp[0]] + z[lp[1]])/2.0 }} } );
-      }
-    }
-  }
-  tk::destroy( m_coord );
-
-  // generate a node map based on oldnodes+addednodes
-  std::vector< size_t > nodeVec(m_coordmap.size());
-  for (size_t j=0; j<nodeVec.size(); ++j) {
-    nodeVec[j] = j;
-  }
-
-  // Remove coordinates and ids of removed nodes due to derefinement
-  std::unordered_map< std::size_t, std::size_t > gid_rem;
-  for (auto o : old) {               // for all unique nodes of the old mesh
-    if (ref.find(o) == end(ref)) {   // if node is no longer in new mesh
-      auto l = tk::cref_find( m_lref, o );
-      auto g = m_gid[l];
-      // store local-ids of removed nodes
-      m_removedNodes.insert(l);
-      // remove derefined nodes from node comm map
-      for (auto& [neighborchare, sharednodes] : m_nodeCommMap) {
-        if (sharednodes.find(g) != sharednodes.end()) {
-          sharednodes.erase(g);
-        }
-      }
-      gid_rem[l] = g;
-      m_lid.erase( g );
-      m_coordmap.erase( g );
-    }
-  }
-
-  // update the node map by removing the derefined nodes
-  if (m_mode == RefMode::DTREF && m_removedNodes.size() > 0) {
-    // remove derefined nodes
-    size_t remCount = 0;
-    size_t origSize = nodeVec.size();
-    for (size_t j=0; j<origSize; ++j) {
-      auto nd = nodeVec[j-remCount];
-
-      bool no_change = false;
-      size_t nodeidx = 0;
-      for (const auto& rn : m_removedNodes) {
-        if (nd < *m_removedNodes.cbegin()) {
-          no_change = true;
-          break;
-        }
-        else if (nd <= rn) {
-          nodeidx = rn;
-          break;
-        }
-      }
-
-      // if node is out-or-range of removed nodes list, continue with next entry
-      if (no_change)
-        continue;
-      // if not is within range of removed nodes list, erase node appropriately
-      else if (nodeidx == nd) {
-        //! Difference type for iterator/pointer arithmetics
-        using diff_type = std::vector< std::size_t >::difference_type;
-        nodeVec.erase(nodeVec.begin()+static_cast< diff_type >(j-remCount));
-        ++remCount;
-      }
-    }
-
-    Assert(remCount == m_removedNodes.size(), "Incorrect number of nodes removed "
-      "from node map.");
-  }
-
-  // invert node vector to get node map
-  for (size_t i=0; i<nodeVec.size(); ++i) {
-    m_amrNodeMap[nodeVec[i]] = i;
-  }
-
-  //// Save previous states of refiner-local node id maps before update
-  //m_oldrid = m_rid;
-  //m_oldlref = m_lref;
-
-  // Generate new node id maps for nodes kept
-  tk::destroy( m_lref );
-  std::vector< std::size_t > rid( ref.size() );
-  std::vector< std::size_t > gid( ref.size() );
-  std::size_t l = 0;    // will generate new local node id
-  for (std::size_t i=0; i<m_gid.size(); ++i) {
-    if (gid_rem.find(i) == end(gid_rem)) {
-      gid[l] = m_gid[i];
-      rid[l] = m_rid[i];
-      m_lref[ m_rid[i] ] = l;
-      ++l;
-    }
-  }
-  // Add newly added nodes due to refinement to node id maps
-  decltype(m_addedNodes) addedNodes( m_addedNodes.size() );<--- Variable 'addedNodes' is assigned a value that is never used.
-  for (const auto& n : gid_add) {
-    auto r = n.first;
-    auto g = n.second;
-    gid[l] = g;
-    rid[l] = r;<--- Variable 'rid[l]' is assigned a value that is never used.
-    Assert(m_lref.find(r) == m_lref.end(), "Overwriting lref");
-    m_lref[r] = l;
-    auto it = m_addedNodes.find( r );
-    Assert( it != end(m_addedNodes), "Cannot find added node" );
-    addedNodes[l] = std::move(it->second);
-    addedNodes.at(l)[0] = m_amrNodeMap[addedNodes.at(l)[0]];
-    addedNodes.at(l)[1] = m_amrNodeMap[addedNodes.at(l)[1]];
-    ++l;
-  }
-  Assert( m_lref.size() == ref.size(), "Size mismatch" );
-  //for (auto r : ref) {
-  //  Assert(m_lref.find(r) != m_lref.end(), "Node missing in lref");
-  //}
-  //const auto& int_list = m_refiner.tet_store.intermediate_list;
-  //for (auto in : int_list) {
-  //  Assert(m_lref.find(in) != m_lref.end(), "Interm node missing in lref: "
-  //    + std::to_string(in));
-  //}
-  m_rid = std::move( rid );
-  Assert( m_rid.size() == ref.size(), "Size mismatch" );
-  m_addedNodes = std::move( addedNodes );
-
-  // Update node coordinates, ids, and id maps
-  auto& rx = m_coord[0];
-  auto& ry = m_coord[1];
-  auto& rz = m_coord[2];
-  rx.resize( ref.size() );
-  ry.resize( ref.size() );
-  rz.resize( ref.size() );
-  for (std::size_t i=0; i<gid.size(); ++i) {
-    tk::ref_find( m_lid, gid[i] ) = i;
-    const auto& c = tk::cref_find( m_coordmap, gid[i] );
-    rx[i] = c[0];
-    ry[i] = c[1];
-    rz[i] = c[2];
-  }
-  m_gid = std::move( gid );
-  Assert( m_gid.size() == m_lid.size() && m_gid.size() == ref.size(),
-    "Size mismatch" );
-}
-
-std::unordered_set< std::size_t >
-Refiner::ancestors( std::size_t n )
-// *****************************************************************************
-// Find the oldest parents of a mesh node in the AMR hierarchy
-//! \param[in] n Local node id whose ancestors to search
-//! \return Parents of local node id from the coarsest (original) mesh
-// *****************************************************************************
-{
-  auto d = m_refiner.node_connectivity.get( m_rid[n] );
-  decltype(d) p{{ tk::cref_find( m_lref, d[0] ),
-                  tk::cref_find( m_lref, d[1] ) }};
-
-  std::unordered_set< std::size_t > s;
-
-  if (p != AMR::node_pair_t{{n,n}}) {
-    auto q = ancestors( p[0] );
-    s.insert( begin(q), end(q) );
-    auto r = ancestors( p[1] );
-    s.insert( begin(r), end(r) );
-  } else {
-    s.insert( begin(p), end(p) );
-  }
-
-  return s;
-}
-
-Refiner::BndFaceData
-Refiner::boundary()
-// *****************************************************************************
-//  Generate boundary data structures used to update refined/derefined boundary
-//  faces and nodes of side sets
-//! \return A tuple of boundary face data
-//! \details The output of this function is used to regenerate physical boundary
-//!   face and node data structures after refinement, see updateBndData().
-// *****************************************************************************
-{
-  // Generate the inverse of AMR's tet store.
-  std::unordered_map< Tet, std::size_t, Hash<4>, Eq<4> > invtets;
-  for (const auto& [key, tet] : m_refiner.tet_store.tets)
-    invtets[ tet ] = key;
-
-  //std::cout << thisIndex << " invt: " << invtets.size() << '\n';
-  //std::cout << thisIndex << " active inpoel size: " << m_refiner.tet_store.get_active_inpoel().size() << '\n';
-  //std::cout << thisIndex << " marked derefinement size: " << m_refiner.tet_store.marked_derefinements.size() << '\n';
-
-  // Generate data structure pcFaceTets for the new (post-AMR) mesh:
-  // pcFaceTets is a map that associates all triangle boundary faces (physical
-  // and chare) to the id of the tet adjacent to the said face.
-  // Key: Face-nodes' global id; Value: tet-id.
-  std::unordered_map< Face, std::size_t, Hash<3>, Eq<3> > pcFaceTets;
-  auto esuel = tk::genEsuelTet( m_inpoel, tk::genEsup(m_inpoel,4) );
-  for (std::size_t e=0; e<esuel.size()/4; ++e) {
-    auto m = e*4;
-    for (std::size_t f=0; f<4; ++f) {
-      if (esuel[m+f] == -1) {  // if a face does not have an adjacent tet
-        Face b{{ m_ginpoel[ m+tk::lpofa[f][0] ],
-                 m_ginpoel[ m+tk::lpofa[f][1] ],
-                 m_ginpoel[ m+tk::lpofa[f][2] ] }};
-        Assert( m_inpoel[m+0] < m_rid.size() &&
-                m_inpoel[m+1] < m_rid.size() &&
-                m_inpoel[m+2] < m_rid.size() &&
-                m_inpoel[m+3] < m_rid.size(), "Indexing out of rid" );
-        Tet t{{ m_rid[ m_inpoel[m+0] ], m_rid[ m_inpoel[m+1] ],
-                m_rid[ m_inpoel[m+2] ], m_rid[ m_inpoel[m+3] ] }};
-        //Tet t{{ m_inpoel[m+0], m_inpoel[m+1],
-        //        m_inpoel[m+2], m_inpoel[m+3] }};
-        // associate tet id to adjacent (physical or chare) boundary face
-        auto i = invtets.find( t );
-        Assert(m_refiner.tet_store.is_active(i->second),
-          "Inactive element while regenerating boundary data");
-        if (i != end(invtets)) {
-          //std::cout << "refacetets: " <<
-          //  b[0] << "-" << b[1] << "-" << b[2] << std::endl;
-          pcFaceTets[ b ] = i->second;
-        } else {
-          Throw("Active element not found in tet_store");
-        }
-      }
-    }
-  }
-
-  // Generate child->parent tet and id maps after refinement/derefinement step
-//  tk::destroy( m_oldparent );
-  m_addedTets.clear();
-  std::size_t p = 0;
-  std::size_t c = 0;<--- Variable 'c' is assigned a value that is never used.
-  const auto& tet_store = m_refiner.tet_store;
-  for (const auto& t : tet_store.tets) {
-    // query number of children of tet
-    auto nc = tet_store.data( t.first ).children.size();
-    for (decltype(nc) i=0; i<nc; ++i ) {      // for all child tets
-      // get child tet id
-      auto childtet = tet_store.get_child_id( t.first, i );
-      auto ct = tet_store.tets.find( childtet );
-      Assert(ct != tet_store.tets.end(), "Child not found in tet store");
-//      //auto cA = tk::cref_find( m_lref, ct->second[0] );
-//      //auto cB = tk::cref_find( m_lref, ct->second[1] );
-//      //auto cC = tk::cref_find( m_lref, ct->second[2] );
-//      //auto cD = tk::cref_find( m_lref, ct->second[3] );
-//      // get nodes of parent tet
-//      //auto pA = tk::cref_find( m_lref, t.second[0] );
-//      //auto pB = tk::cref_find( m_lref, t.second[1] );
-//      //auto pC = tk::cref_find( m_lref, t.second[2] );
-//      //auto pD = tk::cref_find( m_lref, t.second[3] );
-//      // assign parent tet to child tet
-//      //m_oldparent[ {{cA,cB,cC,cD}} ] = {{pA,pB,pC,pD}};
-//      m_oldparent[ ct->second ] = t.second; //{{pA,pB,pC,pD}};
-      if (m_oldTets.find(ct->second) == end(m_oldTets)) {
-        // TODO: the following code can assign negative ids to newly added tets.
-        // This needs to be corrected before applying to cell-based schemes.
-        //Assert((p-m_oldntets) > 0, "Negative id assigned to added tet");
-        m_addedTets[ c++ ] = p - m_oldntets;
-      }
-    }
-    ++p;
-  }
-
-  //std::cout << thisIndex << " added: " << m_addedTets.size() << '\n';
-  //std::cout << thisIndex << " parent: " << m_oldparent.size() << '\n';
-  //std::cout << thisIndex << " pcret: " << pcFaceTets.size() << '\n';
-
-  //for (std::size_t f=0; f<m_triinpoel.size()/3; ++f) {
-  //  std::cout << "triinpoel: " <<
-  //    m_triinpoel[f*3+0] << "-" << m_triinpoel[f*3+1] << "-" <<
-  //    m_triinpoel[f*3+2] << std::endl;
-  //}
-
-  return pcFaceTets;
-}
-
-void
-Refiner::newBndMesh( const std::unordered_set< std::size_t >& ref )
-// *****************************************************************************
-// Update boundary data structures after mesh refinement
-//! \param[in] ref Unique nodes of the refined mesh using refiner-lib ids
-// *****************************************************************************
-{
-  // Generate boundary face data structures used to regenerate boundary face
-  // and node data after mesh refinement
-  auto pcFaceTets = boundary();
-
-  // Regerate boundary faces and nodes after AMR step
-  updateBndData( ref, pcFaceTets );
-}
-
-void
-Refiner::updateBndData(
-  [[maybe_unused]] const std::unordered_set< std::size_t >& ref,
-  const BndFaceData& pcFaceTets )
-// *****************************************************************************
-// Regenerate boundary faces and nodes after AMR step
-//! \param[in] ref Unique nodes of the refined mesh using refiner-lib ids
-//! \param[in] pcFaceTets Boundary face data
-// *****************************************************************************
-{
-  // storage for boundary faces associated to side-set IDs of the refined mesh
-  tk::destroy( m_bface );
-  // storage for boundary faces-node connectivity of the refined mesh
-  tk::destroy( m_triinpoel );
-  // storage for boundary nodes associated to side-set IDs of the refined mesh
-  tk::destroy( m_bnode );
-
-  // face id counter
-  std::size_t facecnt = 0;
-  // will collect unique faces added for each side set
-  std::unordered_map< int, FaceSet > bf;
-
-  // Lambda to associate a boundary face and connectivity to a side set.
-  // Argument 's' is the list of faces (ids) to add the new face to. Argument
-  // 'ss' is the side set id to which the face is added. Argument 'f' is the
-  // triangle face connectivity to add.
-  auto addBndFace = [&]( std::vector< std::size_t >& s, int ss, const Face& f )
-  {
-    // only add face if it has not yet been aded to this side set
-    if (bf[ ss ].insert( f ).second) {
-      s.push_back( facecnt++ );
-      m_triinpoel.insert( end(m_triinpoel), begin(f), end(f) );
-      Assert(m_triinpoel.size()/3 == facecnt, "Incorrect size of triinpoel");
-    }
-  };
-
-  // Lambda to search the parents in the coarsest mesh of a mesh node and if
-  // found, add its global id to boundary node lists associated to the side
-  // set(s) of its parents. Argument 'n' is the local id of the mesh node id
-  // whose parents to search.
-  auto addBndNodes = [&]( std::size_t n ){
-    auto a = ancestors( n );  // find parents of n in coarse mesh
-    if (a.size() == 1) {
-      // node was part of the coarse mesh
-      Assert(*a.cbegin() == n, "Single ancestor not self");
-      auto ss = keys( m_coarseBndNodes, m_gid[*a.cbegin()] );
-      for (auto s : ss)
-        m_bnode[ s ].push_back( m_gid[n] );
-    } else if (a.size() == 2) {
-      // node was added to an edge of a coarse face
-      std::vector< std::size_t > p( begin(a), end(a) );
-      auto ss1 = keys( m_coarseBndNodes, m_gid[p[0]] );
-      auto ss2 = keys( m_coarseBndNodes, m_gid[p[1]] );
-      for (auto s : ss1) {
-        // only add 'n' to bnode if all parent nodes are in same side set, else
-        // 'n' is not a boundary node
-        if (ss2.find(s) != end(ss2)) {
-          m_bnode[ s ].push_back( m_gid[n] );
-        }
-      }
-    } else if (a.size() == 3) {
-      // node was added inside of a coarse face
-      std::vector< std::size_t > p( begin(a), end(a) );
-      auto ss1 = keys( m_coarseBndNodes, m_gid[p[0]] );
-      auto ss2 = keys( m_coarseBndNodes, m_gid[p[1]] );
-      auto ss3 = keys( m_coarseBndNodes, m_gid[p[2]] );
-      for (auto s : ss1) {
-        // only add 'n' to bnode if all parent nodes are in same side set, else
-        // 'n' is not a boundary node
-        if (ss2.find(s) != end(ss2) && ss3.find(s) != end(ss3)) {
-          m_bnode[ s ].push_back( m_gid[n] );
-        }
-      }
-    }
-  };
-
-  // Regenerate boundary faces for new mesh along side sets. For all faces
-  // associated to side sets, we find the ancestors (parents of nodes in the
-  // original/coarsest mesh) of the nodes comprising the physical and chare
-  // boundary faces of the new mesh.
-  //bool faceNoSs = false;
-  // for all P/C faces in current (post-AMR) mesh
-  for (const auto& [ face, tetid ] : pcFaceTets) {
-    // find ancestors of face
-    std::unordered_set< std::size_t > ans;
-    for (std::size_t i=0; i<3; ++i) {
-      auto ai = ancestors(tk::cref_find(m_lid, face[i]));
-      ans.insert(ai.begin(), ai.end());
-    }
-    Assert(ans.size() == 3, "Incorrect number of ancestors in refined face");
-    Face af;
-    std::size_t i = 0;
-    for (auto ai:ans) {
-      af[i] = m_gid[ai];
-      ++i;
-    }
-    // for all boundary faces in original mesh
-    //std::size_t fss = 0;
-    for (const auto& [ss, cfaceset] : m_coarseBndFaces) {
-      if (cfaceset.find(af) != cfaceset.end()) {
-        addBndFace(m_bface[ss], ss, face);
-        //++fss;
-      }
-      for (auto j : face) {
-        addBndNodes(tk::cref_find(m_lid, j));
-      }
-    }
-    //if (fss==0) {
-    //  std::cout << "Face added to no/multiple side sets; " << fss << std::endl;
-    //  faceNoSs = true;
-    //}
-  }
-
-  // Commented code below, since diagcg can work without sideset/bcs
-  //Assert(!faceNoSs, "Face/s added to incorrect number of side sets");
-
-  // Make boundary node IDs unique for each physical boundary (side set)
-  for (auto& s : m_bnode) tk::unique( s.second );
-
-  //for (const auto& [ setid, faceids ] : m_bface) {
-  //  std::cout << "sset: " << setid << std::endl;
-  //  for (auto f : faceids) {
-  //    Assert(f<m_triinpoel.size()/3, "Out of bounds access into triinpoel");
-  //    std::cout << "new bndfaces: " <<
-  //      m_triinpoel[f*3+0] << "-" << m_triinpoel[f*3+1] << "-" <<
-  //      m_triinpoel[f*3+2] << std::endl;
-  //  }
-  //}
-
-  //for (std::size_t f=0; f<m_triinpoel.size()/3; ++f) {
-  //  std::cout << "new triinpoel: " <<
-  //    m_triinpoel[f*3+0] << "-" << m_triinpoel[f*3+1] << "-" <<
-  //    m_triinpoel[f*3+2] << std::endl;
-  //}
-
-  //std::cout << thisIndex << " bf: " << tk::sumvalsize( m_bface ) << '\n';
-
-  //std::cout << thisIndex << " bn: " << tk::sumvalsize( m_bnode ) << '\n';
-
-  // Perform leak-test on boundary face data just updated (only in DEBUG)
-  Assert( bndIntegral(), "Partial boundary integral" );
-}
-
-bool
-Refiner::bndIntegral()
-// *****************************************************************************
-//  Compute partial boundary surface integral and sum across all chares
-//! \return true so we don't trigger assert in client code
-//! \details This function computes a partial surface integral over the boundary
-//!   of the faces of this mesh partition then sends its contribution to perform
-//!   the integral acorss the total problem boundary. After the global sum a
-//!   non-zero vector result indicates a leak, e.g., a hole in the boundary
-//!   which indicates an error in the boundary face data structures used to
-//!   compute the partial surface integrals.
-// *****************************************************************************
-{
-  const auto& x = m_coord[0];
-  const auto& y = m_coord[1];
-  const auto& z = m_coord[2];
-
-  std::vector< tk::real > s{{ 0.0, 0.0, 0.0 }};
-
-  for (const auto& [ setid, faceids ] : m_bface) {
-    for (auto f : faceids) {
-      auto A = tk::cref_find( m_lid, m_triinpoel[f*3+0] );
-      auto B = tk::cref_find( m_lid, m_triinpoel[f*3+1] );
-      auto C = tk::cref_find( m_lid, m_triinpoel[f*3+2] );
-      // Compute geometry data for face
-      auto geoface = tk::geoFaceTri( {{x[A], x[B], x[C]}},
-                                     {{y[A], y[B], y[C]}},
-                                     {{z[A], z[B], z[C]}} );
-      // Sum up face area * face unit-normal
-      s[0] += geoface(0,0) * geoface(0,1);
-      s[1] += geoface(0,0) * geoface(0,2);
-      s[2] += geoface(0,0) * geoface(0,3);
-    }
-  }
-
-  s.push_back( -1.0 );  // negative: no call-back after reduction
-  s.push_back( static_cast< tk::real >( m_meshid ) );
-
-  // Send contribution to host summing partial surface integrals
-  contribute( s, CkReduction::sum_double, m_cbr.get< tag::bndint >() );
-
-  return true;  // don't trigger the assert in client code
-}
-
-#include "NoWarning/refiner.def.h"
+  private:
+    //! \brief Mesh data used for categorizing mesh chunks assigned to chares
+    //!    after mesh partitioning and before mesh distribution across chares
+    using MeshData =
+      std::tuple<
+        // Tetrahedron (domain element) connectivity
+        std::vector< std::size_t >,
+        // Boundary face connectivity for each side set
+        std::unordered_map< int, std::vector< std::size_t > >,
+        // Boundary node lists for each side set
+        std::unordered_map< int, std::vector< std::size_t > >,
+        // Mesh block ids (value) associated to local tet ids (index)
+        std::vector< std::size_t > >;
+
+  public:
+    //! Constructor
+    Partitioner( std::size_t meshid,
+                 const std::string& filename,
+                 const tk::PartitionerCallback& cbp,
+                 const tk::RefinerCallback& cbr,
+                 const tk::SorterCallback& cbs,
+                 const CProxy_Transporter& host,
+                 const CProxy_Refiner& refiner,
+                 const CProxy_Sorter& sorter,
+                 const tk::CProxy_MeshWriter& meshwriter,
+                 const std::vector< Scheme >& scheme,
+                 const std::map< int, std::vector< std::size_t > >& bface,
+                 const std::map< int, std::vector< std::size_t > >& faces,
+                 const std::map< int, std::vector< std::size_t > >& bnode );
+
+    //! Destructor
+    ~Partitioner() override;
+
+    #if defined(__clang__)
+      #pragma clang diagnostic push
+      #pragma clang diagnostic ignored "-Wundefined-func-template"
+    #endif
+    //! Migrate constructor
+    explicit Partitioner( CkMigrateMessage* m ) : CBase_Partitioner( m ) {}<--- Member variable 'Partitioner::m_meshid' is not initialized in the constructor.<--- Member variable 'Partitioner::m_ndist' is not initialized in the constructor.<--- Member variable 'Partitioner::m_nchare' is not initialized in the constructor.
+    #if defined(__clang__)
+      #pragma clang diagnostic pop
+    #endif
+
+    //! Partition the computational mesh into a number of chares
+    void partition( int nchare );
+
+    //! Receive mesh associated to chares we own after refinement
+    void addMesh( int fromnode,
+                  const std::unordered_map< int,
+                    std::tuple<
+                      std::vector< std::size_t >,
+                      tk::UnsMesh::CoordMap,
+                      std::unordered_map< int, std::vector< std::size_t > >,
+                      std::unordered_map< int, std::vector< std::size_t > >,
+                      std::vector< std::size_t >
+                    > >& chmesh );
+
+    //! Acknowledge received mesh after initial mesh refinement
+    void recvMesh();
+
+    //! Optionally start refining the mesh
+    void refine();
+
+    /** @name Charm++ pack/unpack serializer member functions */
+    ///@{
+    //! \brief Pack/Unpack serialize member function
+    //! \param[in,out] p Charm++'s PUP::er serializer object reference
+    //! \note This is a Charm++ nodegroup, pup() is thus only for
+    //!    checkpoint/restart.
+    void pup( PUP::er &p ) override {
+      p | m_meshid;
+      p | m_cbp;
+      p | m_cbr;
+      p | m_cbs;
+      p | m_host;
+      p | m_refiner;
+      p | m_sorter;
+      p | m_meshwriter;
+      p | m_scheme;
+      p | m_ginpoel;
+      p | m_coord;
+      p | m_inpoel;
+      p | m_lid;
+      p | m_elemBlockId;
+      p | m_ndist;
+      p | m_nchare;
+      p | m_nface;
+      p | m_nodech;
+      p | m_linnodes;
+      p | m_chinpoel;
+      p | m_chcoordmap;
+      p | m_chbface;
+      p | m_chtriinpoel;
+      p | m_chbnode;
+      p | m_chelemblockid;
+      p | m_bnodechares;
+      p | m_bface;
+      p | m_triinpoel;
+      p | m_bnode;
+    }
+    //! \brief Pack/Unpack serialize operator|
+    //! \param[in,out] p Charm++'s PUP::er serializer object reference
+    //! \param[in,out] i Partitioner object reference
+    friend void operator|( PUP::er& p, Partitioner& i ) { i.pup(p); }
+    //@}
+
+  private:
+    //! Mesh ID
+    std::size_t m_meshid;
+    //! Charm++ callbacks associated to compile-time tags for partitioner
+    tk::PartitionerCallback m_cbp;
+    //! Charm++ callbacks associated to compile-time tags for refiner
+    tk::RefinerCallback m_cbr;
+    //! Charm++ callbacks associated to compile-time tags for sorter
+    tk::SorterCallback m_cbs;
+    //! Host proxy
+    CProxy_Transporter m_host;
+    //! Mesh refiner proxy
+    CProxy_Refiner m_refiner;
+    //! Mesh sorter proxy
+    CProxy_Sorter m_sorter;
+    //! Mesh writer proxy
+    tk::CProxy_MeshWriter m_meshwriter;
+    //! Discretization schemes (one per mesh)
+    std::vector< Scheme > m_scheme;
+    //! Element connectivity of this compute node's mesh chunk (global ids)
+    std::vector< std::size_t > m_ginpoel;
+    //! Coordinates of mesh nodes of this compute node's mesh chunk
+    tk::UnsMesh::Coords m_coord;
+    //! \brief Element connectivity with local node IDs of this compute node's
+    //!   mesh chunk
+    std::vector< std::size_t > m_inpoel;
+    //! Global->local node IDs of elements of this compute node's mesh chunk
+    //! \details Key: global node id, value: local node id
+    std::unordered_map< std::size_t, std::size_t > m_lid;
+    //! List of elements for each block-id.
+    //! \details key: block id, value: set of elements in corresponding block
+    std::unordered_map< std::size_t, std::set< std::size_t > > m_elemBlockId;
+    //! Counter during mesh distribution
+    std::size_t m_ndist;
+    //! Total number of chares across all compute nodes
+    int m_nchare;
+    //! Counters (for each chare owned) for assigning face ids in parallel
+    std::unordered_map< int, std::size_t > m_nface;
+    //! Chare IDs (value) associated to global mesh node IDs (key)
+    //! \details Multiple chares can contribute to a single node, hence vector
+    //!   for map value.
+    std::unordered_map< std::size_t, std::vector< int > > m_nodech;
+    //! \brief Map associating new node IDs (as in producing contiguous-row-id
+    //!   linear system contributions) as map-values to old node IDs (as in
+    //!   file) as map-keys
+    std::unordered_map< std::size_t, std::size_t > m_linnodes;
+    //! Mesh connectivity using global node IDs associated to chares owned
+    std::unordered_map< int, std::vector< std::size_t > > m_chinpoel;
+    //! Coordinates associated to global node IDs of our mesh chunk for chares
+    std::unordered_map< int, tk::UnsMesh::CoordMap > m_chcoordmap;
+    //! Side set id + boundary face id for each chare
+    std::unordered_map< int,
+      std::map< int, std::vector< std::size_t > > > m_chbface;
+    //! Boundary face connectivity for each chare
+    std::map< int, std::vector< std::size_t > > m_chtriinpoel;
+    //! Side set id + boundary nodes for each chare
+    std::unordered_map< int,
+      std::map< int, std::vector< std::size_t > > > m_chbnode;
+    //! Mesh block ids associated to local tet ids for each chare
+    //! \details outer key: chare id, vector index: tet id, value: block id of
+    //!   corresponding tet.
+    std::unordered_map< int, std::vector< std::size_t > > m_chelemblockid;
+    //! \brief Map associating a list of chare IDs to old (as in file) global
+    //!   mesh node IDs on the chare boundaries
+    //! \details Note that a single global mesh node ID can be associated to
+    //!   multiple chare IDs as multiple chares can contribute to a single node.
+    std::unordered_map< std::size_t, std::vector< int > > m_bnodechares;
+    //! Boundary face IDs associated associated to side set IDs
+    std::map< int, std::vector< std::size_t > > m_bface;
+    //! Boundary face-node connectivity
+    std::vector< std::size_t > m_triinpoel;
+    //! List of boundary nodes associated to side-set IDs
+    std::map< int, std::vector< std::size_t > > m_bnode;
+
+    //! Compute element centroid coordinates
+    std::array< std::vector< tk::real >, 3 >
+    centroids( const std::vector< std::size_t >& inpoel,
+               const tk::UnsMesh::Coords& coord );
+
+    //!  Categorize mesh elements (given by their gobal node IDs) by target
+    std::unordered_map< int, MeshData >
+    categorize( const std::vector< std::size_t >& che ) const;
+
+    //! Extract coordinates associated to global nodes of a mesh chunk
+    tk::UnsMesh::CoordMap coordmap( const std::vector< std::size_t >& inpoel );
+
+    //! Distribute mesh to target compute nodes after mesh partitioning
+    void distribute( std::unordered_map< int, MeshData >&& mesh );
+
+    //! Compute chare (partition) distribution across compute nodes
+    std::array< int, 2 > distribution( int npart ) const;
+
+    //! Return nodegroup id for chare id
+    int node( int id ) const;
+
+    //! Keep only those nodes for side sets that reside on this compute node
+    void ownBndNodes(
+      const std::unordered_map< std::size_t, std::size_t >& lid,
+      std::map< int, std::vector< std::size_t > >& bnode );
+};
+
+} // inciter::
+
+#endif // Partitioner_h
 
diff --git a/Debug/cppcheck/46.html b/Debug/cppcheck/46.html index 7dc7712cbffe..87f808c8e7c2 100644 --- a/Debug/cppcheck/46.html +++ b/Debug/cppcheck/46.html @@ -152,2271 +152,1807 @@
- - + @@ -238,7 +238,7 @@ - + @@ -250,7 +250,7 @@ - + @@ -274,7 +274,7 @@ - + @@ -286,7 +286,7 @@ - + diff --git a/Debug/test_coverage/IO/index.html b/Debug/test_coverage/IO/index.html index af1d97ccd250..1cdfdc647a58 100644 --- a/Debug/test_coverage/IO/index.html +++ b/Debug/test_coverage/IO/index.html @@ -33,7 +33,7 @@ - + diff --git a/Debug/test_coverage/Inciter/ALE.cpp.func-sort-c.html b/Debug/test_coverage/Inciter/ALE.cpp.func-sort-c.html index eb116262c63a..14aae62d8edf 100644 --- a/Debug/test_coverage/Inciter/ALE.cpp.func-sort-c.html +++ b/Debug/test_coverage/Inciter/ALE.cpp.func-sort-c.html @@ -33,7 +33,7 @@ - + diff --git a/Debug/test_coverage/Inciter/ALE.cpp.func.html b/Debug/test_coverage/Inciter/ALE.cpp.func.html index 59a54cdfe797..a6b562674852 100644 --- a/Debug/test_coverage/Inciter/ALE.cpp.func.html +++ b/Debug/test_coverage/Inciter/ALE.cpp.func.html @@ -33,7 +33,7 @@ - + diff --git a/Debug/test_coverage/Inciter/ALE.cpp.gcov.html b/Debug/test_coverage/Inciter/ALE.cpp.gcov.html index 731d9f4e468c..d4585a60dca5 100644 --- a/Debug/test_coverage/Inciter/ALE.cpp.gcov.html +++ b/Debug/test_coverage/Inciter/ALE.cpp.gcov.html @@ -33,7 +33,7 @@ - + diff --git a/Debug/test_coverage/Inciter/ALE.hpp.func-sort-c.html b/Debug/test_coverage/Inciter/ALE.hpp.func-sort-c.html index 0fd9c6a3eb64..a7eae75ea9c8 100644 --- a/Debug/test_coverage/Inciter/ALE.hpp.func-sort-c.html +++ b/Debug/test_coverage/Inciter/ALE.hpp.func-sort-c.html @@ -33,7 +33,7 @@ - + @@ -73,11 +73,11 @@ - + - + diff --git a/Debug/test_coverage/Inciter/ALE.hpp.func.html b/Debug/test_coverage/Inciter/ALE.hpp.func.html index af8243aa6b15..d2734efe2782 100644 --- a/Debug/test_coverage/Inciter/ALE.hpp.func.html +++ b/Debug/test_coverage/Inciter/ALE.hpp.func.html @@ -33,7 +33,7 @@ - + @@ -73,11 +73,11 @@ - + - + diff --git a/Debug/test_coverage/Inciter/ALE.hpp.gcov.html b/Debug/test_coverage/Inciter/ALE.hpp.gcov.html index 7884a7121200..ccb3dc6df255 100644 --- a/Debug/test_coverage/Inciter/ALE.hpp.gcov.html +++ b/Debug/test_coverage/Inciter/ALE.hpp.gcov.html @@ -33,7 +33,7 @@ - + @@ -146,7 +146,7 @@ 72 : : #endif 73 : : //! Migrate constructor 74 : : // cppcheck-suppress uninitMemberVar - 75 : 108 : explicit ALE( CkMigrateMessage* ) {} + 75 : 101 : explicit ALE( CkMigrateMessage* ) {} 76 : : #if defined(__clang__) 77 : : #pragma clang diagnostic pop 78 : : #endif @@ -214,38 +214,38 @@ 140 : : ///@{ 141 : : //! \brief Pack/Unpack serialize member function 142 : : //! \param[in,out] p Charm++'s PUP::er serializer object reference - 143 : 355 : void pup( PUP::er &p ) override { - 144 : 355 : p | m_conjugategradients; - 145 : 355 : p | m_done; - 146 : 355 : p | m_soundspeed; - 147 : 355 : p | m_nvort; - 148 : 355 : p | m_ndiv; - 149 : 355 : p | m_npot; - 150 : 355 : p | m_nwf; - 151 : 355 : p | m_nodeCommMap; - 152 : 355 : p | m_lid; - 153 : 355 : p | m_coord0; - 154 : 355 : p | m_coord; - 155 : 355 : p | m_inpoel; - 156 : 355 : p | m_vol0; - 157 : 355 : p | m_vol; - 158 : 355 : p | m_it; - 159 : 355 : p | m_t; - 160 : 355 : p | m_adt; - 161 : 355 : p | m_w; - 162 : 355 : p | m_wf; - 163 : 355 : p | m_wfc; - 164 : 355 : p | m_veldiv; - 165 : 355 : p | m_veldivc; - 166 : 355 : p | m_gradpot; - 167 : 355 : p | m_gradpotc; - 168 : 355 : p | m_vorticity; - 169 : 355 : p | m_vorticityc; - 170 : 355 : p | m_bnorm; - 171 : 355 : p | m_meshveldirbcnodes; - 172 : 355 : p | m_meshvelsymbcnodes; - 173 : 355 : p | m_move; - 174 : 355 : } + 143 : 334 : void pup( PUP::er &p ) override { + 144 : 334 : p | m_conjugategradients; + 145 : 334 : p | m_done; + 146 : 334 : p | m_soundspeed; + 147 : 334 : p | m_nvort; + 148 : 334 : p | m_ndiv; + 149 : 334 : p | m_npot; + 150 : 334 : p | m_nwf; + 151 : 334 : p | m_nodeCommMap; + 152 : 334 : p | m_lid; + 153 : 334 : p | m_coord0; + 154 : 334 : p | m_coord; + 155 : 334 : p | m_inpoel; + 156 : 334 : p | m_vol0; + 157 : 334 : p | m_vol; + 158 : 334 : p | m_it; + 159 : 334 : p | m_t; + 160 : 334 : p | m_adt; + 161 : 334 : p | m_w; + 162 : 334 : p | m_wf; + 163 : 334 : p | m_wfc; + 164 : 334 : p | m_veldiv; + 165 : 334 : p | m_veldivc; + 166 : 334 : p | m_gradpot; + 167 : 334 : p | m_gradpotc; + 168 : 334 : p | m_vorticity; + 169 : 334 : p | m_vorticityc; + 170 : 334 : p | m_bnorm; + 171 : 334 : p | m_meshveldirbcnodes; + 172 : 334 : p | m_meshvelsymbcnodes; + 173 : 334 : p | m_move; + 174 : 334 : } 175 : : //! \brief Pack/Unpack serialize operator| 176 : : //! \param[in,out] p Charm++'s PUP::er serializer object reference 177 : : //! \param[in,out] a ALE object reference diff --git a/Debug/test_coverage/Inciter/ALECG.cpp.func-sort-c.html b/Debug/test_coverage/Inciter/ALECG.cpp.func-sort-c.html index a9e4fb55794b..ef93b7801c15 100644 --- a/Debug/test_coverage/Inciter/ALECG.cpp.func-sort-c.html +++ b/Debug/test_coverage/Inciter/ALECG.cpp.func-sort-c.html @@ -33,7 +33,7 @@ - + diff --git a/Debug/test_coverage/Inciter/ALECG.cpp.func.html b/Debug/test_coverage/Inciter/ALECG.cpp.func.html index f487ca745f78..1f02ce9c3c47 100644 --- a/Debug/test_coverage/Inciter/ALECG.cpp.func.html +++ b/Debug/test_coverage/Inciter/ALECG.cpp.func.html @@ -33,7 +33,7 @@ - + diff --git a/Debug/test_coverage/Inciter/ALECG.cpp.gcov.html b/Debug/test_coverage/Inciter/ALECG.cpp.gcov.html index 9d28cfc29036..cfb42e99f229 100644 --- a/Debug/test_coverage/Inciter/ALECG.cpp.gcov.html +++ b/Debug/test_coverage/Inciter/ALECG.cpp.gcov.html @@ -33,7 +33,7 @@ - + @@ -906,12 +906,12 @@ 803 : 1617 : std::size_t f = 0; 804 : 1617 : const auto& gid = d->Gid(); 805 [ + + ]: 7476488 : for (auto&& [p,q] : uedge) { - 806 [ + + ]: 7474871 : if (gid[p] > gid[q]) { - 807 : 98380 : m_edgenode[f+0] = std::move(q); - 808 : 98380 : m_edgenode[f+1] = std::move(p); + 806 [ + + ]: 7474871 : if (gid[p] > gid[q]) { + 807 : 97729 : m_edgenode[f+0] = std::move(q); + 808 : 97729 : m_edgenode[f+1] = std::move(p); 809 : : } else { - 810 : 7376491 : m_edgenode[f+0] = std::move(p); - 811 : 7376491 : m_edgenode[f+1] = std::move(q); + 810 : 7377142 : m_edgenode[f+0] = std::move(p); + 811 : 7377142 : m_edgenode[f+1] = std::move(q); 812 : : } 813 : 7474871 : f += 2; 814 : : } diff --git a/Debug/test_coverage/Inciter/ALECG.hpp.func-sort-c.html b/Debug/test_coverage/Inciter/ALECG.hpp.func-sort-c.html index 2090fd9849cc..24b0889a7f01 100644 --- a/Debug/test_coverage/Inciter/ALECG.hpp.func-sort-c.html +++ b/Debug/test_coverage/Inciter/ALECG.hpp.func-sort-c.html @@ -33,7 +33,7 @@ - + @@ -93,11 +93,11 @@ - + - + diff --git a/Debug/test_coverage/Inciter/ALECG.hpp.func.html b/Debug/test_coverage/Inciter/ALECG.hpp.func.html index e140ce0921c9..cbd1e547b130 100644 --- a/Debug/test_coverage/Inciter/ALECG.hpp.func.html +++ b/Debug/test_coverage/Inciter/ALECG.hpp.func.html @@ -33,7 +33,7 @@ - + @@ -89,11 +89,11 @@ - + - + diff --git a/Debug/test_coverage/Inciter/ALECG.hpp.gcov.html b/Debug/test_coverage/Inciter/ALECG.hpp.gcov.html index 36d7c55d0391..5311d7d9a9f9 100644 --- a/Debug/test_coverage/Inciter/ALECG.hpp.gcov.html +++ b/Debug/test_coverage/Inciter/ALECG.hpp.gcov.html @@ -33,7 +33,7 @@ - + @@ -158,7 +158,7 @@ 84 : : #endif 85 : : //! Migrate constructor 86 : : // cppcheck-suppress uninitMemberVar - 87 : 1648 : explicit ALECG( CkMigrateMessage* msg ) : CBase_ALECG( msg ) {} + 87 : 1637 : explicit ALECG( CkMigrateMessage* msg ) : CBase_ALECG( msg ) {} 88 : : #if defined(__clang__) 89 : : #pragma clang diagnostic pop 90 : : #endif @@ -279,51 +279,51 @@ 205 : : ///@{ 206 : : //! \brief Pack/Unpack serialize member function 207 : : //! \param[in,out] p Charm++'s PUP::er serializer object reference - 208 : 5184 : void pup( PUP::er &p ) override { - 209 : 5184 : p | m_disc; - 210 : 5184 : p | m_nsol; - 211 : 5184 : p | m_ngrad; - 212 : 5184 : p | m_nrhs; - 213 : 5184 : p | m_nbnorm; - 214 : 5184 : p | m_ndfnorm; - 215 : 5184 : p | m_nmblk; - 216 : 5184 : p | m_bnode; - 217 : 5184 : p | m_bface; - 218 : 5184 : p | m_triinpoel; - 219 : 5184 : p | m_bndel; - 220 : 5184 : p | m_dfnorm; - 221 : 5184 : p | m_dfnormc; - 222 : 5184 : p | m_dfn; - 223 : 5184 : p | m_esup; - 224 : 5184 : p | m_psup; - 225 : 5184 : p | m_u; - 226 : 5184 : p | m_un; - 227 : 5184 : p | m_rhs; - 228 : 5184 : p | m_rhsc; - 229 : 5184 : p | m_chBndGrad; - 230 : 5184 : p | m_dirbc; - 231 : 5184 : p | m_chBndGradc; - 232 : 5184 : p | m_diag; - 233 : 5184 : p | m_bnorm; - 234 : 5184 : p | m_bnormc; - 235 : 5184 : p | m_symbcnodes; - 236 : 5184 : p | m_farfieldbcnodes; - 237 : 5184 : p | m_symbctri; - 238 : 5184 : p | m_timedepbcnodes; - 239 : 5184 : p | m_timedepbcFn; - 240 : 5184 : p | m_stage; - 241 : 5184 : p | m_boxnodes; - 242 : 5184 : p | m_edgenode; - 243 : 5184 : p | m_edgeid; - 244 : 5184 : p | m_dtp; - 245 : 5184 : p | m_tp; - 246 : 5184 : p | m_finished; - 247 : 5184 : p | m_newmesh; - 248 : 5184 : p | m_refinedmesh; - 249 : 5184 : p | m_nusermeshblk; - 250 : 5184 : p | m_nodeblockid; - 251 : 5184 : p | m_nodeblockidc; - 252 : 5184 : } + 208 : 5151 : void pup( PUP::er &p ) override { + 209 : 5151 : p | m_disc; + 210 : 5151 : p | m_nsol; + 211 : 5151 : p | m_ngrad; + 212 : 5151 : p | m_nrhs; + 213 : 5151 : p | m_nbnorm; + 214 : 5151 : p | m_ndfnorm; + 215 : 5151 : p | m_nmblk; + 216 : 5151 : p | m_bnode; + 217 : 5151 : p | m_bface; + 218 : 5151 : p | m_triinpoel; + 219 : 5151 : p | m_bndel; + 220 : 5151 : p | m_dfnorm; + 221 : 5151 : p | m_dfnormc; + 222 : 5151 : p | m_dfn; + 223 : 5151 : p | m_esup; + 224 : 5151 : p | m_psup; + 225 : 5151 : p | m_u; + 226 : 5151 : p | m_un; + 227 : 5151 : p | m_rhs; + 228 : 5151 : p | m_rhsc; + 229 : 5151 : p | m_chBndGrad; + 230 : 5151 : p | m_dirbc; + 231 : 5151 : p | m_chBndGradc; + 232 : 5151 : p | m_diag; + 233 : 5151 : p | m_bnorm; + 234 : 5151 : p | m_bnormc; + 235 : 5151 : p | m_symbcnodes; + 236 : 5151 : p | m_farfieldbcnodes; + 237 : 5151 : p | m_symbctri; + 238 : 5151 : p | m_timedepbcnodes; + 239 : 5151 : p | m_timedepbcFn; + 240 : 5151 : p | m_stage; + 241 : 5151 : p | m_boxnodes; + 242 : 5151 : p | m_edgenode; + 243 : 5151 : p | m_edgeid; + 244 : 5151 : p | m_dtp; + 245 : 5151 : p | m_tp; + 246 : 5151 : p | m_finished; + 247 : 5151 : p | m_newmesh; + 248 : 5151 : p | m_refinedmesh; + 249 : 5151 : p | m_nusermeshblk; + 250 : 5151 : p | m_nodeblockid; + 251 : 5151 : p | m_nodeblockidc; + 252 : 5151 : } 253 : : //! \brief Pack/Unpack serialize operator| 254 : : //! \param[in,out] p Charm++'s PUP::er serializer object reference 255 : : //! \param[in,out] i ALECG object reference diff --git a/Debug/test_coverage/Inciter/AMR/AMR_types.hpp.func-sort-c.html b/Debug/test_coverage/Inciter/AMR/AMR_types.hpp.func-sort-c.html index b036dd660eb0..5350f0369da2 100644 --- a/Debug/test_coverage/Inciter/AMR/AMR_types.hpp.func-sort-c.html +++ b/Debug/test_coverage/Inciter/AMR/AMR_types.hpp.func-sort-c.html @@ -33,7 +33,7 @@ - + @@ -73,7 +73,7 @@ - + diff --git a/Debug/test_coverage/Inciter/AMR/AMR_types.hpp.func.html b/Debug/test_coverage/Inciter/AMR/AMR_types.hpp.func.html index 90c83fbd2d2f..af76e3f71272 100644 --- a/Debug/test_coverage/Inciter/AMR/AMR_types.hpp.func.html +++ b/Debug/test_coverage/Inciter/AMR/AMR_types.hpp.func.html @@ -33,7 +33,7 @@ - + @@ -77,7 +77,7 @@ - +
   1
-   2
-   3
-   4
-   5
-   6
-   7
-   8
-   9
-  10
-  11
-  12
-  13
-  14
-  15
-  16
-  17
-  18
-  19
-  20
-  21
-  22
-  23
-  24
-  25
-  26
-  27
-  28
-  29
-  30
-  31
-  32
-  33
-  34
-  35
-  36
-  37
-  38
-  39
-  40
-  41
-  42
-  43
-  44
-  45
-  46
-  47
-  48
-  49
-  50
-  51
-  52
-  53
-  54
-  55
-  56
-  57
-  58
-  59
-  60
-  61
-  62
-  63
-  64
-  65
-  66
-  67
-  68
-  69
-  70
-  71
-  72
-  73
-  74
-  75
-  76
-  77
-  78
-  79
-  80
-  81
-  82
-  83
-  84
-  85
-  86
-  87
-  88
-  89
-  90
-  91
-  92
-  93
-  94
-  95
-  96
-  97
-  98
-  99
- 100
- 101
- 102
- 103
- 104
- 105
- 106
- 107
- 108
- 109
- 110
- 111
- 112
- 113
- 114
- 115
- 116
- 117
- 118
- 119
- 120
- 121
- 122
- 123
- 124
- 125
- 126
- 127
- 128
- 129
- 130
- 131
- 132
- 133
- 134
- 135
- 136
- 137
- 138
- 139
- 140
- 141
- 142
- 143
- 144
- 145
- 146
- 147
- 148
- 149
- 150
- 151
- 152
- 153
- 154
- 155
- 156
- 157
- 158
- 159
- 160
- 161
- 162
- 163
- 164
- 165
- 166
- 167
- 168
- 169
- 170
- 171
- 172
- 173
- 174
- 175
- 176
- 177
- 178
- 179
- 180
- 181
- 182
- 183
- 184
- 185
- 186
- 187
- 188
- 189
- 190
- 191
- 192
- 193
- 194
- 195
- 196
- 197
- 198
- 199
- 200
- 201
- 202
- 203
- 204
- 205
- 206
- 207
- 208
- 209
- 210
- 211
- 212
- 213
- 214
- 215
- 216
- 217
- 218
- 219
- 220
- 221
- 222
- 223
- 224
- 225
- 226
- 227
- 228
- 229
- 230
- 231
- 232
- 233
- 234
- 235
- 236
- 237
- 238
- 239
- 240
- 241
- 242
- 243
- 244
- 245
- 246
- 247
- 248
- 249
- 250
- 251
- 252
- 253
- 254
- 255
- 256
- 257
- 258
- 259
- 260
- 261
- 262
- 263
- 264
- 265
- 266
- 267
- 268
- 269
- 270
- 271
- 272
- 273
- 274
- 275
- 276
- 277
- 278
- 279
- 280
- 281
- 282
- 283
- 284
- 285
- 286
- 287
- 288
- 289
- 290
- 291
- 292
- 293
- 294
- 295
- 296
- 297
- 298
- 299
- 300
- 301
- 302
- 303
- 304
- 305
- 306
- 307
- 308
- 309
- 310
- 311
- 312
- 313
- 314
- 315
- 316
- 317
- 318
- 319
- 320
- 321
- 322
- 323
- 324
- 325
- 326
- 327
- 328
- 329
- 330
- 331
- 332
- 333
- 334
- 335
- 336
- 337
- 338
- 339
- 340
- 341
- 342
- 343
- 344
- 345
- 346
- 347
- 348
- 349
- 350
- 351
- 352
- 353
- 354
- 355
- 356
- 357
- 358
- 359
- 360
- 361
- 362
- 363
- 364
- 365
- 366
- 367
- 368
- 369
- 370
- 371
- 372
- 373
- 374
- 375
- 376
- 377
- 378
- 379
- 380
- 381
- 382
- 383
- 384
- 385
- 386
- 387
- 388
- 389
- 390
- 391
- 392
- 393
- 394
- 395
- 396
- 397
- 398
- 399
- 400
- 401
- 402
- 403
- 404
- 405
- 406
- 407
- 408
- 409
- 410
- 411
- 412
- 413
- 414
- 415
- 416
- 417
- 418
- 419
- 420
- 421
- 422
- 423
- 424
- 425
- 426
- 427
- 428
- 429
- 430
- 431
- 432
- 433
- 434
- 435
- 436
- 437
- 438
- 439
- 440
- 441
- 442
- 443
- 444
- 445
- 446
- 447
- 448
- 449
- 450
- 451
- 452
- 453
- 454
- 455
- 456
- 457
- 458
- 459
- 460
- 461
- 462
- 463
- 464
- 465
- 466
- 467
- 468
- 469
- 470
- 471
- 472
- 473
- 474
- 475
- 476
- 477
- 478
- 479
- 480
- 481
- 482
- 483
- 484
- 485
- 486
- 487
- 488
- 489
- 490
- 491
- 492
- 493
- 494
- 495
- 496
- 497
- 498
- 499
- 500
- 501
- 502
- 503
- 504
- 505
- 506
- 507
- 508
- 509
- 510
- 511
- 512
- 513
- 514
- 515
- 516
- 517
- 518
- 519
- 520
- 521
- 522
- 523
- 524
- 525
- 526
- 527
- 528
- 529
- 530
- 531
- 532
- 533
- 534
- 535
- 536
- 537
- 538
- 539
- 540
- 541
- 542
- 543
- 544
- 545
- 546
- 547
- 548
- 549
- 550
- 551
- 552
- 553
- 554
- 555
- 556
- 557
- 558
- 559
- 560
- 561
- 562
- 563
- 564
- 565
- 566
- 567
- 568
- 569
- 570
- 571
- 572
- 573
- 574
- 575
- 576
- 577
- 578
- 579
- 580
- 581
- 582
- 583
- 584
- 585
- 586
- 587
- 588
- 589
- 590
- 591
- 592
- 593
- 594
- 595
- 596
- 597
- 598
- 599
- 600
- 601
- 602
- 603
- 604
- 605
- 606
- 607
- 608
- 609
- 610
- 611
- 612
- 613
- 614
- 615
- 616
- 617
- 618
- 619
- 620
- 621
- 622
- 623
- 624
- 625
- 626
- 627
- 628
- 629
- 630
- 631
- 632
- 633
- 634
- 635
- 636
- 637
- 638
- 639
- 640
- 641
- 642
- 643
- 644
- 645
- 646
- 647
- 648
- 649
- 650
- 651
- 652
- 653
- 654
- 655
- 656
- 657
- 658
- 659
- 660
- 661
- 662
- 663
- 664
- 665
- 666
- 667
- 668
- 669
- 670
- 671
- 672
- 673
- 674
- 675
- 676
- 677
- 678
- 679
- 680
- 681
- 682
- 683
- 684
- 685
- 686
- 687
- 688
- 689
- 690
- 691
- 692
- 693
- 694
- 695
- 696
- 697
- 698
- 699
- 700
- 701
- 702
- 703
- 704
- 705
- 706
- 707
- 708
- 709
- 710
- 711
- 712
- 713
- 714
- 715
- 716
- 717
- 718
- 719
- 720
- 721
- 722
- 723
- 724
- 725
- 726
- 727
- 728
- 729
- 730
- 731
- 732
- 733
- 734
- 735
- 736
- 737
- 738
- 739
- 740
- 741
- 742
- 743
- 744
- 745
- 746
- 747
- 748
- 749
- 750
- 751
- 752
- 753
- 754
- 755
- 756
- 757
- 758
- 759
- 760
- 761
- 762
- 763
- 764
- 765
- 766
- 767
- 768
- 769
- 770
- 771
- 772
- 773
- 774
- 775
- 776
- 777
- 778
- 779
- 780
- 781
- 782
- 783
- 784
- 785
- 786
- 787
- 788
- 789
- 790
- 791
- 792
- 793
- 794
- 795
- 796
- 797
- 798
- 799
- 800
- 801
- 802
- 803
- 804
- 805
- 806
- 807
- 808
- 809
- 810
- 811
- 812
- 813
- 814
- 815
- 816
- 817
- 818
- 819
- 820
- 821
- 822
- 823
- 824
- 825
- 826
- 827
- 828
- 829
- 830
- 831
- 832
- 833
- 834
- 835
- 836
- 837
- 838
- 839
- 840
- 841
- 842
- 843
- 844
- 845
- 846
- 847
- 848
- 849
- 850
- 851
- 852
- 853
- 854
- 855
- 856
- 857
- 858
- 859
- 860
- 861
- 862
- 863
- 864
- 865
- 866
- 867
- 868
- 869
- 870
- 871
- 872
- 873
- 874
- 875
- 876
- 877
- 878
- 879
- 880
- 881
- 882
- 883
- 884
- 885
- 886
- 887
- 888
- 889
- 890
- 891
- 892
- 893
- 894
- 895
- 896
- 897
- 898
- 899
- 900
- 901
- 902
- 903
- 904
- 905
- 906
- 907
- 908
- 909
- 910
- 911
- 912
- 913
- 914
- 915
- 916
- 917
- 918
- 919
- 920
- 921
- 922
- 923
- 924
- 925
- 926
- 927
- 928
- 929
- 930
- 931
- 932
- 933
- 934
- 935
- 936
- 937
- 938
- 939
- 940
- 941
- 942
- 943
- 944
- 945
- 946
- 947
- 948
- 949
- 950
- 951
- 952
- 953
- 954
- 955
- 956
- 957
- 958
- 959
- 960
- 961
- 962
- 963
- 964
- 965
- 966
- 967
- 968
- 969
- 970
- 971
- 972
- 973
- 974
- 975
- 976
- 977
- 978
- 979
- 980
- 981
- 982
- 983
- 984
- 985
- 986
- 987
- 988
- 989
- 990
- 991
- 992
- 993
- 994
- 995
- 996
- 997
- 998
- 999
-1000
-1001
-1002
-1003
-1004
-1005
-1006
-1007
-1008
-1009
-1010
-1011
-1012
-1013
-1014
-1015
-1016
-1017
-1018
-1019
-1020
-1021
-1022
-1023
-1024
-1025
-1026
-1027
-1028
-1029
-1030
-1031
-1032
-1033
-1034
-1035
-1036
-1037
-1038
-1039
-1040
-1041
-1042
-1043
-1044
-1045
-1046
-1047
-1048
-1049
-1050
-1051
-1052
-1053
-1054
-1055
-1056
-1057
-1058
-1059
-1060
-1061
-1062
-1063
-1064
-1065
-1066
-1067
-1068
-1069
-1070
-1071
-1072
-1073
-1074
-1075
-1076
-1077
-1078
-1079
-1080
-1081
-1082
-1083
-1084
-1085
-1086
-1087
-1088
-1089
-1090
-1091
-1092
-1093
-1094
-1095
-1096
-1097
-1098
-1099
-1100
-1101
-1102
-1103
-1104
-1105
-1106
-1107
-1108
-1109
-1110
-1111
-1112
-1113
-1114
-1115
-1116
-1117
-1118
-1119
-1120
-1121
-1122
-1123
-1124
-1125
-1126
-1127
-1128
-1129
// *****************************************************************************
+
  1
+  2
+  3
+  4
+  5
+  6
+  7
+  8
+  9
+ 10
+ 11
+ 12
+ 13
+ 14
+ 15
+ 16
+ 17
+ 18
+ 19
+ 20
+ 21
+ 22
+ 23
+ 24
+ 25
+ 26
+ 27
+ 28
+ 29
+ 30
+ 31
+ 32
+ 33
+ 34
+ 35
+ 36
+ 37
+ 38
+ 39
+ 40
+ 41
+ 42
+ 43
+ 44
+ 45
+ 46
+ 47
+ 48
+ 49
+ 50
+ 51
+ 52
+ 53
+ 54
+ 55
+ 56
+ 57
+ 58
+ 59
+ 60
+ 61
+ 62
+ 63
+ 64
+ 65
+ 66
+ 67
+ 68
+ 69
+ 70
+ 71
+ 72
+ 73
+ 74
+ 75
+ 76
+ 77
+ 78
+ 79
+ 80
+ 81
+ 82
+ 83
+ 84
+ 85
+ 86
+ 87
+ 88
+ 89
+ 90
+ 91
+ 92
+ 93
+ 94
+ 95
+ 96
+ 97
+ 98
+ 99
+100
+101
+102
+103
+104
+105
+106
+107
+108
+109
+110
+111
+112
+113
+114
+115
+116
+117
+118
+119
+120
+121
+122
+123
+124
+125
+126
+127
+128
+129
+130
+131
+132
+133
+134
+135
+136
+137
+138
+139
+140
+141
+142
+143
+144
+145
+146
+147
+148
+149
+150
+151
+152
+153
+154
+155
+156
+157
+158
+159
+160
+161
+162
+163
+164
+165
+166
+167
+168
+169
+170
+171
+172
+173
+174
+175
+176
+177
+178
+179
+180
+181
+182
+183
+184
+185
+186
+187
+188
+189
+190
+191
+192
+193
+194
+195
+196
+197
+198
+199
+200
+201
+202
+203
+204
+205
+206
+207
+208
+209
+210
+211
+212
+213
+214
+215
+216
+217
+218
+219
+220
+221
+222
+223
+224
+225
+226
+227
+228
+229
+230
+231
+232
+233
+234
+235
+236
+237
+238
+239
+240
+241
+242
+243
+244
+245
+246
+247
+248
+249
+250
+251
+252
+253
+254
+255
+256
+257
+258
+259
+260
+261
+262
+263
+264
+265
+266
+267
+268
+269
+270
+271
+272
+273
+274
+275
+276
+277
+278
+279
+280
+281
+282
+283
+284
+285
+286
+287
+288
+289
+290
+291
+292
+293
+294
+295
+296
+297
+298
+299
+300
+301
+302
+303
+304
+305
+306
+307
+308
+309
+310
+311
+312
+313
+314
+315
+316
+317
+318
+319
+320
+321
+322
+323
+324
+325
+326
+327
+328
+329
+330
+331
+332
+333
+334
+335
+336
+337
+338
+339
+340
+341
+342
+343
+344
+345
+346
+347
+348
+349
+350
+351
+352
+353
+354
+355
+356
+357
+358
+359
+360
+361
+362
+363
+364
+365
+366
+367
+368
+369
+370
+371
+372
+373
+374
+375
+376
+377
+378
+379
+380
+381
+382
+383
+384
+385
+386
+387
+388
+389
+390
+391
+392
+393
+394
+395
+396
+397
+398
+399
+400
+401
+402
+403
+404
+405
+406
+407
+408
+409
+410
+411
+412
+413
+414
+415
+416
+417
+418
+419
+420
+421
+422
+423
+424
+425
+426
+427
+428
+429
+430
+431
+432
+433
+434
+435
+436
+437
+438
+439
+440
+441
+442
+443
+444
+445
+446
+447
+448
+449
+450
+451
+452
+453
+454
+455
+456
+457
+458
+459
+460
+461
+462
+463
+464
+465
+466
+467
+468
+469
+470
+471
+472
+473
+474
+475
+476
+477
+478
+479
+480
+481
+482
+483
+484
+485
+486
+487
+488
+489
+490
+491
+492
+493
+494
+495
+496
+497
+498
+499
+500
+501
+502
+503
+504
+505
+506
+507
+508
+509
+510
+511
+512
+513
+514
+515
+516
+517
+518
+519
+520
+521
+522
+523
+524
+525
+526
+527
+528
+529
+530
+531
+532
+533
+534
+535
+536
+537
+538
+539
+540
+541
+542
+543
+544
+545
+546
+547
+548
+549
+550
+551
+552
+553
+554
+555
+556
+557
+558
+559
+560
+561
+562
+563
+564
+565
+566
+567
+568
+569
+570
+571
+572
+573
+574
+575
+576
+577
+578
+579
+580
+581
+582
+583
+584
+585
+586
+587
+588
+589
+590
+591
+592
+593
+594
+595
+596
+597
+598
+599
+600
+601
+602
+603
+604
+605
+606
+607
+608
+609
+610
+611
+612
+613
+614
+615
+616
+617
+618
+619
+620
+621
+622
+623
+624
+625
+626
+627
+628
+629
+630
+631
+632
+633
+634
+635
+636
+637
+638
+639
+640
+641
+642
+643
+644
+645
+646
+647
+648
+649
+650
+651
+652
+653
+654
+655
+656
+657
+658
+659
+660
+661
+662
+663
+664
+665
+666
+667
+668
+669
+670
+671
+672
+673
+674
+675
+676
+677
+678
+679
+680
+681
+682
+683
+684
+685
+686
+687
+688
+689
+690
+691
+692
+693
+694
+695
+696
+697
+698
+699
+700
+701
+702
+703
+704
+705
+706
+707
+708
+709
+710
+711
+712
+713
+714
+715
+716
+717
+718
+719
+720
+721
+722
+723
+724
+725
+726
+727
+728
+729
+730
+731
+732
+733
+734
+735
+736
+737
+738
+739
+740
+741
+742
+743
+744
+745
+746
+747
+748
+749
+750
+751
+752
+753
+754
+755
+756
+757
+758
+759
+760
+761
+762
+763
+764
+765
+766
+767
+768
+769
+770
+771
+772
+773
+774
+775
+776
+777
+778
+779
+780
+781
+782
+783
+784
+785
+786
+787
+788
+789
+790
+791
+792
+793
+794
+795
+796
+797
+798
+799
+800
+801
+802
+803
+804
+805
+806
+807
+808
+809
+810
+811
+812
+813
+814
+815
+816
+817
+818
+819
+820
+821
+822
+823
+824
+825
+826
+827
+828
+829
+830
+831
+832
+833
+834
+835
+836
+837
+838
+839
+840
+841
+842
+843
+844
+845
+846
+847
+848
+849
+850
+851
+852
+853
+854
+855
+856
+857
+858
+859
+860
+861
+862
+863
+864
+865
+866
+867
+868
+869
+870
+871
+872
+873
+874
+875
+876
+877
+878
+879
+880
+881
+882
+883
+884
+885
+886
+887
+888
+889
+890
+891
+892
+893
+894
+895
+896
+897
// *****************************************************************************
 /*!
-  \file      src/Inciter/FV.cpp
+  \file      src/PDE/MultiMat/FVMultiMat.hpp
   \copyright 2012-2015 J. Bakosi,
              2016-2018 Los Alamos National Security, LLC.,
              2019-2021 Triad National Security, LLC.
              All rights reserved. See the LICENSE file for details.
-  \brief     FV advances a system of PDEs with the finite volume scheme
-  \details   FV advances a system of partial differential equations (PDEs) using
-    the finite volume (FV) (on tetrahedron elements).
-  \see The documentation in FV.h.
+  \brief     Compressible multi-material flow using finite volumes
+  \details   This file implements calls to the physics operators governing
+    compressible multi-material flow (with velocity equilibrium) using finite
+    volume discretizations.
 */
 // *****************************************************************************
-
-#include <algorithm>
-#include <numeric>
-#include <sstream>
-
-#include "FV.hpp"
-#include "Discretization.hpp"
-#include "FVPDE.hpp"
-#include "DiagReducer.hpp"
-#include "DerivedData.hpp"
-#include "ElemDiagnostics.hpp"
-#include "Inciter/InputDeck/InputDeck.hpp"
-#include "Refiner.hpp"
-#include "Limiter.hpp"
-#include "PrefIndicator.hpp"
-#include "Reorder.hpp"
-#include "Vector.hpp"
-#include "Around.hpp"
-#include "Integrate/Basis.hpp"
-#include "FieldOutput.hpp"
-#include "ChareStateCollector.hpp"
-
-namespace inciter {
-
-extern ctr::InputDeck g_inputdeck;
-extern std::vector< FVPDE > g_fvpde;
-
-} // inciter::
-
-extern tk::CProxy_ChareStateCollector stateProxy;
-
-using inciter::FV;
+#ifndef FVMultiMat_h
+#define FVMultiMat_h
+
+#include <cmath>
+#include <algorithm>
+#include <unordered_set>
+#include <map>
+#include <array>
+
+#include "Macro.hpp"
+#include "Exception.hpp"
+#include "Vector.hpp"
+#include "ContainerUtil.hpp"
+#include "UnsMesh.hpp"
+#include "Inciter/InputDeck/InputDeck.hpp"
+#include "Integrate/Basis.hpp"
+#include "Integrate/Quadrature.hpp"
+#include "Integrate/Initialize.hpp"
+#include "Integrate/Mass.hpp"
+#include "Integrate/Surface.hpp"
+#include "Integrate/Boundary.hpp"
+#include "Integrate/Volume.hpp"
+#include "Integrate/MultiMatTerms.hpp"
+#include "Integrate/Source.hpp"
+#include "RiemannChoice.hpp"
+#include "MultiMat/MultiMatIndexing.hpp"
+#include "Reconstruction.hpp"
+#include "Limiter.hpp"
+#include "Problem/FieldOutput.hpp"
+#include "Problem/BoxInitialization.hpp"
+#include "MultiMat/BCFunctions.hpp"
+#include "MultiMat/MiscMultiMatFns.hpp"
 
-FV::FV( const CProxy_Discretization& disc,
-        const CProxy_Ghosts& ghostsproxy,
-        const std::map< int, std::vector< std::size_t > >& bface,
-        const std::map< int, std::vector< std::size_t > >& /* bnode */,
-        const std::vector< std::size_t >& triinpoel ) :
-  m_disc( disc ),
-  m_ghosts( ghostsproxy ),
-  m_nsol( 0 ),
-  m_ninitsol( 0 ),
-  m_nlim( 0 ),
-  m_nnod( 0 ),
-  m_u( Disc()->Inpoel().size()/4,
-       g_inputdeck.get< tag::rdof >()*
-       g_inputdeck.get< tag::ncomp >() ),
-  m_un( m_u.nunk(), m_u.nprop() ),
-  m_p( m_u.nunk(), g_inputdeck.get< tag::rdof >()*
-    g_fvpde[Disc()->MeshId()].nprim() ),
-  m_lhs( m_u.nunk(),
-         g_inputdeck.get< tag::ncomp >() ),
-  m_rhs( m_u.nunk(), m_lhs.nprop() ),
-  m_npoin( Disc()->Coord()[0].size() ),
-  m_diag(),
-  m_stage( 0 ),
-  m_uc(),
-  m_pc(),
-  m_initial( 1 ),
-  m_uElemfields( m_u.nunk(), m_lhs.nprop() ),
-  m_pElemfields(m_u.nunk(),
-    m_p.nprop()/g_inputdeck.get< tag::rdof >()),
-  m_uNodefields( m_npoin, m_lhs.nprop() ),
-  m_pNodefields(m_npoin,
-    m_p.nprop()/g_inputdeck.get< tag::rdof >()),
-  m_uNodefieldsc(),
-  m_pNodefieldsc(),
-  m_boxelems(),
-  m_srcFlag(m_u.nunk(), 0),
-  m_nrk(0),
-  m_dte(m_u.nunk(), 0.0),
-  m_finished(0)
-// *****************************************************************************
-//  Constructor
-//! \param[in] disc Discretization proxy
-//! \param[in] bface Boundary-faces mapped to side set ids
-//! \param[in] triinpoel Boundary-face connectivity
-// *****************************************************************************
-{
-  //! Runge-Kutta coefficients
-  m_nrk = 2;
-  m_rkcoef[0].resize(m_nrk);
-  m_rkcoef[1].resize(m_nrk);
-  if (m_nrk == 2) {
-    m_rkcoef = {{ {{ 0.0, 1.0/2.0 }}, {{ 1.0, 1.0/2.0 }} }};
-  }
-  else {
-    m_rkcoef = {{ {{ 0.0, 3.0/4.0, 1.0/3.0 }}, {{ 1.0, 1.0/4.0, 2.0/3.0 }} }};
-  }
+namespace inciter {
+
+extern ctr::InputDeck g_inputdeck;
+
+namespace fv {
+
+//! \brief MultiMat used polymorphically with tk::FVPDE
+//! \details The template arguments specify policies and are used to configure
+//!   the behavior of the class. The policies are:
+//!   - Physics - physics configuration, see PDE/MultiMat/Physics.h
+//!   - Problem - problem configuration, see PDE/MultiMat/Problem.h
+//! \note The default physics is Euler, set in inciter::deck::check_multimat()
+template< class Physics, class Problem >
+class MultiMat {
+
+  private:
+    using eq = tag::multimat;
+
+  public:
+    //! Constructor
+    explicit MultiMat() :
+      m_physics(),
+      m_ncomp( g_inputdeck.get< tag::ncomp >() ),
+      m_riemann( multimatRiemannSolver(
+        g_inputdeck.get< tag::flux >() ) )
+    {
+      // associate boundary condition configurations with state functions
+      brigand::for_each< ctr::bclist::Keys >( ConfigBC( m_bc,
+        { dirichlet
+        , symmetry
+        , invalidBC         // Inlet BC not implemented
+        , invalidBC         // Outlet BC not implemented
+        , farfieldOutlet
+        , extrapolate } ) );
+
+      // EoS initialization
+      initializeMaterialEoS( m_mat_blk );
+    }
+
+    //! Find the number of primitive quantities required for this PDE system
+    //! \return The number of primitive quantities required to be stored for
+    //!   this PDE system
+    std::size_t nprim() const<--- Shadowed declaration
+    {
+      auto nmat = g_inputdeck.get< tag::multimat, tag::nmat >();<--- Shadow variable
+      // multimat needs individual material pressures and velocities currently
+      return (nmat+3);
+    }
+
+    //! Find the number of materials set up for this PDE system
+    //! \return The number of materials set up for this PDE system
+    std::size_t nmat() const<--- Shadowed declaration<--- Shadowed declaration<--- Shadowed declaration<--- Shadowed declaration<--- Shadowed declaration<--- Shadowed declaration<--- Shadowed declaration<--- Shadowed declaration<--- Shadowed declaration<--- Shadowed declaration<--- Shadowed declaration<--- Shadowed declaration<--- Shadowed declaration<--- Shadowed declaration<--- Shadowed declaration<--- Shadowed declaration<--- Shadowed declaration
+    {
+      auto nmat = g_inputdeck.get< tag::multimat, tag::nmat >();
+      return nmat;
+    }
 
-  if (g_inputdeck.get< tag::cmd, tag::chare >() ||
-      g_inputdeck.get< tag::cmd, tag::quiescence >())
-    stateProxy.ckLocalBranch()->insert( "FV", thisIndex, CkMyPe(), Disc()->It(),
-                                        "FV" );
-
-  usesAtSync = true;    // enable migration at AtSync
-
-  // Enable SDAG wait for initially building the solution vector and limiting
-  if (m_initial) {
-    thisProxy[ thisIndex ].wait4sol();
-    thisProxy[ thisIndex ].wait4lim();
-    thisProxy[ thisIndex ].wait4nod();
-  }
-
-  m_ghosts[thisIndex].insert(m_disc, bface, triinpoel, m_u.nunk(),
-    CkCallback(CkIndex_FV::resizeSolVectors(), thisProxy[thisIndex]));
-
-  // global-sync to call doneInserting on m_ghosts
-  auto meshid = Disc()->MeshId();
-  contribute( sizeof(std::size_t), &meshid, CkReduction::nop,
-    CkCallback(CkReductionTarget(Transporter,doneInsertingGhosts),
-    Disc()->Tr()) );
-}
-
-void
-FV::registerReducers()
-// *****************************************************************************
-//  Configure Charm++ reduction types
-//! \details Since this is a [initnode] routine, the runtime system executes the
-//!   routine exactly once on every logical node early on in the Charm++ init
-//!   sequence. Must be static as it is called without an object. See also:
-//!   Section "Initializations at Program Startup" at in the Charm++ manual
-//!   http://charm.cs.illinois.edu/manuals/html/charm++/manual.html.
-// *****************************************************************************
-{
-  ElemDiagnostics::registerReducers();
-}
-
-void
-FV::ResumeFromSync()
-// *****************************************************************************
-//  Return from migration
-//! \details This is called when load balancing (LB) completes. The presence of
-//!   this function does not affect whether or not we block on LB.
-// *****************************************************************************
-{
-  if (Disc()->It() == 0) Throw( "it = 0 in ResumeFromSync()" );
-
-  if (!g_inputdeck.get< tag::cmd, tag::nonblocking >()) next();
-}
-
-void
-FV::resizeSolVectors()
-// *****************************************************************************
-// Resize solution vectors after extension due to Ghosts
-// *****************************************************************************
-{
-  // Resize solution vectors, lhs and rhs by the number of ghost tets
-  m_u.resize( myGhosts()->m_nunk );
-  m_un.resize( myGhosts()->m_nunk );
-  m_srcFlag.resize( myGhosts()->m_nunk );
-  m_p.resize( myGhosts()->m_nunk );
-  m_lhs.resize( myGhosts()->m_nunk );
-  m_rhs.resize( myGhosts()->m_nunk );
-  m_dte.resize( myGhosts()->m_nunk );
-
-  // Size communication buffer for solution
-  for (auto& u : m_uc) u.resize( myGhosts()->m_bid.size() );
-  for (auto& p : m_pc) p.resize( myGhosts()->m_bid.size() );
-
-  // Ensure that we also have all the geometry and connectivity data
-  // (including those of ghosts)
-  Assert( myGhosts()->m_geoElem.nunk() == m_u.nunk(),
-    "GeoElem unknowns size mismatch" );
-
-  // Signal the runtime system that all workers have received their adjacency
-  std::vector< std::size_t > meshdata{ myGhosts()->m_initial, Disc()->MeshId() };
-  contribute( meshdata, CkReduction::sum_ulong,
-    CkCallback(CkReductionTarget(Transporter,comfinal), Disc()->Tr()) );
-}
-
-void
-FV::setup()
-// *****************************************************************************
-// Set initial conditions, generate lhs, output mesh
-// *****************************************************************************
-{
-  if (g_inputdeck.get< tag::cmd, tag::chare >() ||
-      g_inputdeck.get< tag::cmd, tag::quiescence >())
-    stateProxy.ckLocalBranch()->insert( "FV", thisIndex, CkMyPe(), Disc()->It(),
-                                        "setup" );
-
-  auto d = Disc();<--- Variable 'd' is assigned a value that is never used.
-
-  // Basic error checking on sizes of element geometry data and connectivity
-  Assert( myGhosts()->m_geoElem.nunk() == m_lhs.nunk(),
-    "Size mismatch in FV::setup()" );
-
-  // Compute left-hand side of discrete PDEs
-  lhs();
-
-  // Determine elements inside user-defined IC box
-  g_fvpde[d->MeshId()].IcBoxElems( myGhosts()->m_geoElem,
-    myGhosts()->m_fd.Esuel().size()/4, m_boxelems );
-
-  // Compute volume of user-defined box IC
-  d->boxvol( {}, {}, 0 );      // punt for now
-
-  // Query time history field output labels from all PDEs integrated
-  const auto& hist_points = g_inputdeck.get< tag::history_output, tag::point >();
-  if (!hist_points.empty()) {
-    std::vector< std::string > histnames;
-    auto n = g_fvpde[d->MeshId()].histNames();
-    histnames.insert( end(histnames), begin(n), end(n) );
-    d->histheader( std::move(histnames) );
-  }
-}
-
-void
-FV::box( tk::real v, const std::vector< tk::real >& )
-// *****************************************************************************
-// Receive total box IC volume and set conditions in box
-//! \param[in] v Total volume within user-specified box
-// *****************************************************************************
-{
-  auto d = Disc();
-
-  // Store user-defined box IC volume
-  d->Boxvol() = v;
+    //! Determine elements that lie inside the user-defined IC box
+    //! \param[in] geoElem Element geometry array
+    //! \param[in] nielem Number of internal elements
+    //! \param[in,out] inbox List of nodes at which box user ICs are set for
+    //!    each IC box
+    void IcBoxElems( const tk::Fields& geoElem,
+      std::size_t nielem,
+      std::vector< std::unordered_set< std::size_t > >& inbox ) const
+    {
+      tk::BoxElems< eq >(geoElem, nielem, inbox);
+    }
+
+    //! Initalize the compressible flow equations, prepare for time integration
+    //! \param[in] L Block diagonal mass matrix
+    //! \param[in] inpoel Element-node connectivity
+    //! \param[in] coord Array of nodal coordinates
+    //! \param[in] inbox List of elements at which box user ICs are set for
+    //!   each IC box
+    //! \param[in] elemblkid Element ids associated with mesh block ids where
+    //!   user ICs are set
+    //! \param[in,out] unk Array of unknowns
+    //! \param[in] t Physical time
+    //! \param[in] nielem Number of internal elements
+    void initialize( const tk::Fields& L,
+      const std::vector< std::size_t >& inpoel,
+      const tk::UnsMesh::Coords& coord,
+      const std::vector< std::unordered_set< std::size_t > >& inbox,
+      const std::unordered_map< std::size_t, std::set< std::size_t > >&
+        elemblkid,
+      tk::Fields& unk,
+      tk::real t,
+      const std::size_t nielem ) const
+    {
+      tk::initialize( m_ncomp, m_mat_blk, L, inpoel, coord,
+                      Problem::initialize, unk, t, nielem );
+
+      const auto rdof = g_inputdeck.get< tag::rdof >();
+      const auto& ic = g_inputdeck.get< tag::ic >();
+      const auto& icbox = ic.get< tag::box >();
+      const auto& icmbk = ic.get< tag::meshblock >();
+
+      const auto& bgpre = ic.get< tag::pressure >();
+      const auto& bgtemp = ic.get< tag::temperature >();
+
+      // Set initial conditions inside user-defined IC boxes and mesh blocks
+      std::vector< tk::real > s(m_ncomp, 0.0);
+      for (std::size_t e=0; e<nielem; ++e) {
+        // inside user-defined box
+        if (!icbox.empty()) {
+          std::size_t bcnt = 0;
+          for (const auto& b : icbox) {   // for all boxes
+            if (inbox.size() > bcnt && inbox[bcnt].find(e) != inbox[bcnt].end())
+            {
+              std::vector< tk::real > box
+                { b.template get< tag::xmin >(), b.template get< tag::xmax >(),
+                  b.template get< tag::ymin >(), b.template get< tag::ymax >(),
+                  b.template get< tag::zmin >(), b.template get< tag::zmax >() };
+              auto V_ex = (box[1]-box[0]) * (box[3]-box[2]) * (box[5]-box[4]);
+              for (std::size_t c=0; c<m_ncomp; ++c) {
+                auto mark = c*rdof;
+                s[c] = unk(e,mark);
+                // set high-order DOFs to zero
+                for (std::size_t i=1; i<rdof; ++i)
+                  unk(e,mark+i) = 0.0;
+              }
+              initializeBox<ctr::boxList>( m_mat_blk, V_ex, t, b, bgpre,
+                bgtemp, s );
+              // store box-initialization in solution vector
+              for (std::size_t c=0; c<m_ncomp; ++c) {
+                auto mark = c*rdof;
+                unk(e,mark) = s[c];
+              }
+            }
+            ++bcnt;
+          }
+        }
+
+        // inside user-specified mesh blocks
+        for (const auto& b : icmbk) { // for all blocks
+          auto blid = b.get< tag::blockid >();
+          auto V_ex = b.get< tag::volume >();
+          if (elemblkid.find(blid) != elemblkid.end()) {
+            const auto& elset = tk::cref_find(elemblkid, blid);
+            if (elset.find(e) != elset.end()) {
+              initializeBox<ctr::meshblockList>( m_mat_blk, V_ex, t, b,
+                bgpre, bgtemp, s );
+              // store initialization in solution vector
+              for (std::size_t c=0; c<m_ncomp; ++c) {
+                auto mark = c*rdof;
+                unk(e,mark) = s[c];
+              }
+            }
+          }
+        }
+      }
+    }
+
+    //! Compute the left hand side block-diagonal mass matrix
+    //! \param[in] geoElem Element geometry array
+    //! \param[in,out] l Block diagonal mass matrix
+    void lhs( const tk::Fields& geoElem, tk::Fields& l ) const {<--- Parameter 'l' can be declared with const
+      const auto nelem = geoElem.nunk();
+      for (std::size_t e=0; e<nelem; ++e)
+        for (ncomp_t c=0; c<m_ncomp; ++c)
+          l(e, c) = geoElem(e,0);
+    }
+
+    //! Update the primitives for this PDE system
+    //! \param[in] unk Array of unknowns
+    //! \param[in,out] prim Array of primitives
+    //! \param[in] nielem Number of internal elements
+    //! \details This function computes and stores the dofs for primitive
+    //!   quantities, which are required for obtaining reconstructed states used
+    //!   in the Riemann solver. See /PDE/Riemann/AUSM.hpp, where the
+    //!   normal velocity for advection is calculated from independently
+    //!   reconstructed velocities.
+    void updatePrimitives( const tk::Fields& unk,
+                           tk::Fields& prim,<--- Parameter 'prim' can be declared with const
+                           std::size_t nielem ) const
+    {
+      const auto rdof = g_inputdeck.get< tag::rdof >();<--- Variable 'rdof' is assigned a value that is never used.
+      auto nmat = g_inputdeck.get< tag::multimat, tag::nmat >();<--- Shadow variable<--- Variable 'nmat' is assigned a value that is never used.
+
+      Assert( unk.nunk() == prim.nunk(), "Number of unknowns in solution "
+              "vector and primitive vector at recent time step incorrect" );
+      Assert( unk.nprop() == rdof*m_ncomp, "Number of components in solution "
+              "vector must equal "+ std::to_string(rdof*m_ncomp) );
+      Assert( prim.nprop() == rdof*nprim(), "Number of components in vector of "
+              "primitive quantities must equal "+ std::to_string(rdof*nprim()) );
 
-  // Set initial conditions for all PDEs
-  g_fvpde[d->MeshId()].initialize( m_lhs, myGhosts()->m_inpoel,
-    myGhosts()->m_coord, m_boxelems, d->ElemBlockId(), m_u, d->T(),
-    myGhosts()->m_fd.Esuel().size()/4 );
-  g_fvpde[d->MeshId()].updatePrimitives( m_u, m_p,
-    myGhosts()->m_fd.Esuel().size()/4 );
-
-  m_un = m_u;
+      for (std::size_t e=0; e<nielem; ++e)
+      {
+        // cell-average bulk density
+        tk::real rhob(0.0);
+        for (std::size_t k=0; k<nmat; ++k)
+        {
+          rhob += unk(e, densityDofIdx(nmat, k, rdof, 0));
+        }
 
-  // Output initial conditions to file (regardless of whether it was requested)
-  startFieldOutput( CkCallback(CkIndex_FV::start(), thisProxy[thisIndex]) );
-}
-
-void
-FV::start()
-// *****************************************************************************
-//  Start time stepping
-// *****************************************************************************
-{
-  // Start timer measuring time stepping wall clock time
-  Disc()->Timer().zero();
-  // Zero grind-timer
-  Disc()->grindZero();
-  // Start time stepping by computing the size of the next time step)
-  next();
-}
-
-void
-FV::startFieldOutput( CkCallback c )
-// *****************************************************************************
-// Start preparing fields for output to file
-//! \param[in] c Function to continue with after the write
-// *****************************************************************************
-{
-  // No field output in benchmark mode or if field output frequency not hit
-  if (g_inputdeck.get< tag::cmd, tag::benchmark >() || !fieldOutput()) {
-
-    c.send();
-
-  } else {
+        // cell-average velocity
+        std::array< tk::real, 3 >
+          vel{{ unk(e, momentumDofIdx(nmat, 0, rdof, 0))/rhob,
+                unk(e, momentumDofIdx(nmat, 1, rdof, 0))/rhob,
+                unk(e, momentumDofIdx(nmat, 2, rdof, 0))/rhob }};
+
+        for (std::size_t idir=0; idir<3; ++idir)
+        {
+          prim(e, velocityDofIdx(nmat, idir, rdof, 0)) = vel[idir];
+          for (std::size_t idof=1; idof<rdof; ++idof)
+            prim(e, velocityDofIdx(nmat, idir, rdof, idof)) = 0.0;
+        }
+
+        // cell-average material pressure
+        for (std::size_t k=0; k<nmat; ++k)
+        {
+          tk::real arhomat = unk(e, densityDofIdx(nmat, k, rdof, 0));
+          tk::real arhoemat = unk(e, energyDofIdx(nmat, k, rdof, 0));
+          tk::real alphamat = unk(e, volfracDofIdx(nmat, k, rdof, 0));
+          auto gmat = getDeformGrad(nmat, k, unk.extract(e));
+          prim(e, pressureDofIdx(nmat, k, rdof, 0)) =
+            m_mat_blk[k].compute< EOS::pressure >( arhomat, vel[0], vel[1],
+            vel[2], arhoemat, alphamat, k, gmat );
+          prim(e, pressureDofIdx(nmat, k, rdof, 0)) =
+            constrain_pressure( m_mat_blk,
+            prim(e, pressureDofIdx(nmat, k, rdof, 0)), arhomat, alphamat, k);
+          for (std::size_t idof=1; idof<rdof; ++idof)
+            prim(e, pressureDofIdx(nmat, k, rdof, idof)) = 0.0;
+        }
+      }
+    }
 
-    // Optionally refine mesh for field output
-    auto d = Disc();
-
-    if (refinedOutput()) {
-
-      const auto& tr = tk::remap( myGhosts()->m_fd.Triinpoel(), d->Gid() );
-      d->Ref()->outref( myGhosts()->m_fd.Bface(), {}, tr, c );
-
-    } else {
-
-      // cut off ghosts from mesh connectivity and coordinates
-      extractFieldOutput( {}, d->Chunk(), d->Coord(), {}, {}, d->NodeCommMap(),
-        {}, {}, {}, c );
-
-    }
-
-  }
-}
-
-void
-FV::next()
-// *****************************************************************************
-// Advance equations to next time step
-// *****************************************************************************
-{
-  // communicate solution ghost data (if any)
-  if (myGhosts()->m_sendGhost.empty())
-    comsol_complete();
-  else
-    for(const auto& [cid, ghostdata] : myGhosts()->m_sendGhost) {
-      std::vector< std::size_t > tetid( ghostdata.size() );
-      std::vector< std::vector< tk::real > > u( ghostdata.size() ),
-                                             prim( ghostdata.size() );
-      std::size_t j = 0;
-      for(const auto& i : ghostdata) {
-        Assert( i < myGhosts()->m_fd.Esuel().size()/4,
-          "Sending solution ghost data" );
-        tetid[j] = i;
-        u[j] = m_u[i];
-        prim[j] = m_p[i];
-        ++j;
-      }
-      thisProxy[ cid ].comsol( thisIndex, tetid, u, prim );
-    }
-
-  ownsol_complete();
-}
-
-void
-FV::comsol( int fromch,
-            const std::vector< std::size_t >& tetid,
-            const std::vector< std::vector< tk::real > >& u,
-            const std::vector< std::vector< tk::real > >& prim )
-// *****************************************************************************
-//  Receive chare-boundary solution ghost data from neighboring chares
-//! \param[in] fromch Sender chare id
-//! \param[in] tetid Ghost tet ids we receive solution data for
-//! \param[in] u Solution ghost data
-//! \param[in] prim Primitive variables in ghost cells
-//! \details This function receives contributions to the unlimited solution
-//!   from fellow chares.
-// *****************************************************************************
-{
-  Assert( u.size() == tetid.size(), "Size mismatch in FV::comsol()" );
-  Assert( prim.size() == tetid.size(), "Size mismatch in FV::comsol()" );
-
-  // Find local-to-ghost tet id map for sender chare
-  const auto& n = tk::cref_find( myGhosts()->m_ghost, fromch );
-
-  for (std::size_t i=0; i<tetid.size(); ++i) {
-    auto j = tk::cref_find( n, tetid[i] );
-    Assert( j >= myGhosts()->m_fd.Esuel().size()/4,
-      "Receiving solution non-ghost data" );
-    auto b = tk::cref_find( myGhosts()->m_bid, j );
-    Assert( b < m_uc[0].size(), "Indexing out of bounds" );
-    m_uc[0][b] = u[i];
-    m_pc[0][b] = prim[i];
-  }
+    //! Clean up the state of trace materials for this PDE system
+    //! \param[in] t Physical time
+    //! \param[in] geoElem Element geometry array
+    //! \param[in,out] unk Array of unknowns
+    //! \param[in,out] prim Array of primitives
+    //! \param[in] nielem Number of internal elements
+    //! \details This function cleans up the state of materials present in trace
+    //!   quantities in each cell. Specifically, the state of materials with
+    //!   very low volume-fractions in a cell is replaced by the state of the
+    //!   material which is present in the largest quantity in that cell. This
+    //!   becomes necessary when shocks pass through cells which contain a very
+    //!   small amount of material. The state of that tiny material might
+    //!   become unphysical and cause solution to diverge; thus requiring such
+    //!   a "reset".
+    void cleanTraceMaterial( tk::real t,
+                             const tk::Fields& geoElem,
+                             tk::Fields& unk,
+                             tk::Fields& prim,
+                             std::size_t nielem ) const
+    {
+      [[maybe_unused]] const auto rdof = g_inputdeck.get< tag::rdof >();
+      auto nmat = g_inputdeck.get< tag::multimat, tag::nmat >();<--- Shadow variable<--- Variable 'nmat' is assigned a value that is never used.
+
+      Assert( unk.nunk() == prim.nunk(), "Number of unknowns in solution "
+              "vector and primitive vector at recent time step incorrect" );
+      Assert( unk.nprop() == rdof*m_ncomp, "Number of components in solution "
+              "vector must equal "+ std::to_string(rdof*m_ncomp) );
+      Assert( prim.nprop() == rdof*nprim(), "Number of components in vector of "
+              "primitive quantities must equal "+ std::to_string(rdof*nprim()) );
+      Assert( (g_inputdeck.get< tag::ndof >()) <= 4, "High-order "
+              "discretizations not set up for multimat cleanTraceMaterial()" );
+
+      auto neg_density = cleanTraceMultiMat(t, nielem, m_mat_blk, geoElem, nmat,
+        unk, prim);
+
+      if (neg_density) Throw("Negative partial density.");
+    }
+
+    //! Reconstruct second-order solution from first-order
+    //! \param[in] geoElem Element geometry array
+    //! \param[in] fd Face connectivity and boundary conditions object
+    //! \param[in] esup Elements-surrounding-nodes connectivity
+    //! \param[in] inpoel Element-node connectivity
+    //! \param[in] coord Array of nodal coordinates
+    //! \param[in,out] U Solution vector at recent time step
+    //! \param[in,out] P Vector of primitives at recent time step
+    void reconstruct( const tk::Fields& geoElem,
+                      const inciter::FaceData& fd,
+                      const std::map< std::size_t, std::vector< std::size_t > >&
+                        esup,
+                      const std::vector< std::size_t >& inpoel,
+                      const tk::UnsMesh::Coords& coord,
+                      tk::Fields& U,
+                      tk::Fields& P ) const
+    {
+      const auto rdof = g_inputdeck.get< tag::rdof >();
+      const auto nelem = fd.Esuel().size()/4;<--- Variable 'nelem' is assigned a value that is never used.
+      auto nmat = g_inputdeck.get< tag::multimat, tag::nmat >();<--- Shadow variable<--- Variable 'nmat' is assigned a value that is never used.
+
+      Assert( U.nprop() == rdof*m_ncomp, "Number of components in solution "
+              "vector must equal "+ std::to_string(rdof*m_ncomp) );
+
+      //----- reconstruction of conserved quantities -----
+      //--------------------------------------------------
+      // specify how many variables need to be reconstructed
+      std::vector< std::size_t > vars;
+      for (std::size_t k=0; k<nmat; ++k) {
+        vars.push_back(volfracIdx(nmat,k));
+        vars.push_back(densityIdx(nmat,k));
+      }
+
+      // 1. solve 3x3 least-squares system
+      for (std::size_t e=0; e<nelem; ++e)
+      {
+        // Reconstruct second-order dofs of volume-fractions in Taylor space
+        // using nodal-stencils, for a good interface-normal estimate
+        tk::recoLeastSqExtStencil( rdof, e, esup, inpoel, geoElem, U, vars );
+      }
 
-  // if we have received all solution ghost contributions from neighboring
-  // chares (chares we communicate along chare-boundary faces with), and
-  // contributed our solution to these neighbors, proceed to reconstructions
-  if (++m_nsol == myGhosts()->m_sendGhost.size()) {
-    m_nsol = 0;
-    comsol_complete();
-  }
-}
-
-void
-FV::extractFieldOutput(
-  const std::vector< std::size_t >& /*ginpoel*/,
-  const tk::UnsMesh::Chunk& chunk,
-  const tk::UnsMesh::Coords& coord,
-  const std::unordered_map< std::size_t, tk::UnsMesh::Edge >& /*addedNodes*/,
-  const std::unordered_map< std::size_t, std::size_t >& addedTets,
-  const tk::NodeCommMap& nodeCommMap,
-  const std::map< int, std::vector< std::size_t > >& /* bface */,
-  const std::map< int, std::vector< std::size_t > >& /* bnode */,
-  const std::vector< std::size_t >& /* triinpoel */,
-  CkCallback c )
-// *****************************************************************************
-// Extract field output going to file
-//! \param[in] chunk Field-output mesh chunk (connectivity and global<->local
-//!    id maps)
-//! \param[in] coord Field-output mesh node coordinates
-//! \param[in] addedTets Field-output mesh cells and their parents (local ids)
-//! \param[in] nodeCommMap Field-output mesh node communication map
-//! \param[in] c Function to continue with after the write
-// *****************************************************************************
-{
-  const auto& inpoel = std::get< 0 >( chunk );
-
-  // Evaluate element solution on incoming mesh
-  evalSolution( *Disc(), inpoel, coord, addedTets, std::vector< std::size_t>{},
-    m_u, m_p, m_uElemfields, m_pElemfields, m_uNodefields, m_pNodefields );
-
-  // Send node fields contributions to neighbor chares
-  if (nodeCommMap.empty())
-    comnodeout_complete();
-  else {
-    const auto& lid = std::get< 2 >( chunk );
-    auto esup = tk::genEsup( inpoel, 4 );
-    for(const auto& [ch,nodes] : nodeCommMap) {
-      // Pack node field data in chare boundary nodes
-      std::vector< std::vector< tk::real > >
-        lu( m_uNodefields.nprop(), std::vector< tk::real >( nodes.size() ) );
-      std::vector< std::vector< tk::real > >
-        lp( m_pNodefields.nprop(), std::vector< tk::real >( nodes.size() ) );
-      for (std::size_t f=0; f<m_uNodefields.nprop(); ++f) {
-        std::size_t j = 0;
-        for (auto g : nodes)
-          lu[f][j++] = m_uNodefields(tk::cref_find(lid,g),f);
-      }
-      for (std::size_t f=0; f<m_pNodefields.nprop(); ++f) {
-        std::size_t j = 0;
-        for (auto g : nodes)
-          lp[f][j++] = m_pNodefields(tk::cref_find(lid,g),f);
+      // 2. transform reconstructed derivatives to Dubiner dofs
+      tk::transform_P0P1(rdof, nelem, inpoel, coord, U, vars);
+
+      //----- reconstruction of primitive quantities -----
+      //--------------------------------------------------
+      // For multimat, conserved and primitive quantities are reconstructed
+      // separately.
+      vars.clear();
+      for (std::size_t c=0; c<nprim(); ++c) vars.push_back(c);
+      // 1.
+      for (std::size_t e=0; e<nelem; ++e)
+      {
+        // Reconstruct second-order dofs of volume-fractions in Taylor space
+        // using nodal-stencils, for a good interface-normal estimate
+        tk::recoLeastSqExtStencil( rdof, e, esup, inpoel, geoElem, P, vars );
+      }
+
+      // 2.
+      tk::transform_P0P1(rdof, nelem, inpoel, coord, P, vars);
+    }
+
+    //! Limit second-order solution, and primitive quantities separately
+    //! \param[in] geoFace Face geometry array
+    //! \param[in] fd Face connectivity and boundary conditions object
+    //! \param[in] esup Elements-surrounding-nodes connectivity
+    //! \param[in] inpoel Element-node connectivity
+    //! \param[in] coord Array of nodal coordinates
+    //! \param[in] srcFlag Whether the energy source was added
+    //! \param[in,out] U Solution vector at recent time step
+    //! \param[in,out] P Vector of primitives at recent time step
+    void limit( const tk::Fields& geoFace,
+                const inciter::FaceData& fd,
+                const std::map< std::size_t, std::vector< std::size_t > >& esup,
+                const std::vector< std::size_t >& inpoel,
+                const tk::UnsMesh::Coords& coord,
+                const std::vector< int >& srcFlag,
+                tk::Fields& U,
+                tk::Fields& P ) const
+    {
+      Assert( U.nunk() == P.nunk(), "Number of unknowns in solution "
+              "vector and primitive vector at recent time step incorrect" );
+
+      const auto limiter = g_inputdeck.get< tag::limiter >();
+      auto nmat = g_inputdeck.get< tag::multimat, tag::nmat >();<--- Shadow variable
+      const auto& solidx = g_inputdeck.get<
+        tag::matidxmap, tag::solidx >();
+
+      // limit vectors of conserved and primitive quantities
+      if (limiter == ctr::LimiterType::VERTEXBASEDP1)
+      {
+        VertexBasedMultiMat_FV( esup, inpoel, fd.Esuel().size()/4,
+          coord, srcFlag, solidx, U, P, nmat );
+        PositivityPreservingMultiMat_FV( inpoel, fd.Esuel().size()/4, nmat,
+          m_mat_blk, coord, geoFace, U, P );
+      }
+      else if (limiter != ctr::LimiterType::NOLIMITER)
+      {
+        Throw("Limiter type not configured for multimat.");
       }
-      // Pack (partial) number of elements surrounding chare boundary nodes
-      std::vector< std::size_t > nesup( nodes.size() );
-      std::size_t j = 0;
-      for (auto g : nodes) {
-        auto i = tk::cref_find( lid, g );
-        nesup[j++] = esup.second[i+1] - esup.second[i];
-      }
-      thisProxy[ch].comnodeout(
-        std::vector<std::size_t>(begin(nodes),end(nodes)), nesup, lu, lp );
-    }
-  }
-
-  ownnod_complete( c );
-}
-
-void
-FV::lhs()
-// *****************************************************************************
-// Compute left-hand side of discrete transport equations
-// *****************************************************************************
-{
-  g_fvpde[Disc()->MeshId()].lhs( myGhosts()->m_geoElem, m_lhs );
-
-  if (!m_initial) stage();
-}
-
-void
-FV::reco()
-// *****************************************************************************
-// Compute reconstructions
-// *****************************************************************************
-{
-  const auto rdof = g_inputdeck.get< tag::rdof >();
-
-  // Combine own and communicated contributions of unreconstructed solution and
-  // degrees of freedom in cells (if p-adaptive)
-  for (const auto& b : myGhosts()->m_bid) {
-    Assert( m_uc[0][b.second].size() == m_u.nprop(), "ncomp size mismatch" );
-    Assert( m_pc[0][b.second].size() == m_p.nprop(), "ncomp size mismatch" );
-    for (std::size_t c=0; c<m_u.nprop(); ++c) {
-      m_u(b.first,c) = m_uc[0][b.second][c];
-    }
-    for (std::size_t c=0; c<m_p.nprop(); ++c) {
-      m_p(b.first,c) = m_pc[0][b.second][c];
-    }
-  }
-
-  if (rdof > 1) {
-    // Reconstruct second-order solution and primitive quantities
-    g_fvpde[Disc()->MeshId()].reconstruct( myGhosts()->m_geoElem, myGhosts()->m_fd,
-      myGhosts()->m_esup, myGhosts()->m_inpoel, myGhosts()->m_coord, m_u, m_p );
-  }
-
-  // start limiting
-  lim();
-}
-
-void
-FV::lim()
-// *****************************************************************************
-// Compute limiter function
-// *****************************************************************************
-{
-  const auto rdof = g_inputdeck.get< tag::rdof >();
-
-  if (rdof > 1) {
-    g_fvpde[Disc()->MeshId()].limit( myGhosts()->m_geoFace, myGhosts()->m_fd,
-      myGhosts()->m_esup,
-      myGhosts()->m_inpoel, myGhosts()->m_coord, m_srcFlag, m_u, m_p );
-  }
-
-  // Send limited solution to neighboring chares
-  if (myGhosts()->m_sendGhost.empty())
-    comlim_complete();
-  else
-    for(const auto& [cid, ghostdata] : myGhosts()->m_sendGhost) {
-      std::vector< std::size_t > tetid( ghostdata.size() );
-      std::vector< std::vector< tk::real > > u( ghostdata.size() ),
-                                             prim( ghostdata.size() );
-      std::size_t j = 0;
-      for(const auto& i : ghostdata) {
-        Assert( i < myGhosts()->m_fd.Esuel().size()/4,
-          "Sending limiter ghost data" );
-        tetid[j] = i;
-        u[j] = m_u[i];
-        prim[j] = m_p[i];
-        ++j;
-      }
-      thisProxy[ cid ].comlim( thisIndex, tetid, u, prim );
-    }
+    }
+
+    //! Apply CPL to the conservative variable solution for this PDE system
+    //! \param[in] prim Array of primitive variables
+    //! \param[in] geoElem Element geometry array
+    //! \param[in] inpoel Element-node connectivity
+    //! \param[in] coord Array of nodal coordinates
+    //! \param[in,out] unk Array of conservative variables
+    //! \param[in] nielem Number of internal elements
+    //! \details This function applies CPL to obtain consistent dofs for
+    //!   conservative quantities based on the limited primitive quantities.
+    //!   See Pandare et al. (2023). On the Design of Stable,
+    //!   Consistent, and Conservative High-Order Methods for Multi-Material
+    //!   Hydrodynamics. J Comp Phys, 112313.
+    void CPL( const tk::Fields& prim,
+      const tk::Fields& geoElem,
+      const std::vector< std::size_t >& inpoel,
+      const tk::UnsMesh::Coords& coord,
+      tk::Fields& unk,
+      std::size_t nielem ) const
+    {
+      [[maybe_unused]] const auto rdof = g_inputdeck.get< tag::rdof >();
+      auto nmat = g_inputdeck.get< tag::multimat, tag::nmat >();<--- Shadow variable<--- Variable 'nmat' is assigned a value that is never used.
+
+      Assert( unk.nunk() == prim.nunk(), "Number of unknowns in solution "
+              "vector and primitive vector at recent time step incorrect" );
+      Assert( unk.nprop() == rdof*m_ncomp, "Number of components in solution "
+              "vector must equal "+ std::to_string(rdof*m_ncomp) );
+      Assert( prim.nprop() == rdof*nprim(), "Number of components in vector of "
+              "primitive quantities must equal "+ std::to_string(rdof*nprim()) );
+
+      correctLimConservMultiMat(nielem, m_mat_blk, nmat, inpoel,
+        coord, geoElem, prim, unk);
+    }
+
+    //! Compute right hand side
+    //! \param[in] t Physical time
+    //! \param[in] geoFace Face geometry array
+    //! \param[in] geoElem Element geometry array
+    //! \param[in] fd Face connectivity and boundary conditions object
+    //! \param[in] inpoel Element-node connectivity
+    //! \param[in] coord Array of nodal coordinates
+    //! \param[in] elemblkid Element ids associated with mesh block ids where
+    //!   user ICs are set
+    //! \param[in] U Solution vector at recent time step
+    //! \param[in] P Primitive vector at recent time step
+    //! \param[in,out] R Right-hand side vector computed
+    //! \param[in,out] srcFlag Whether the energy source was added
+    void rhs( tk::real t,
+              const tk::Fields& geoFace,
+              const tk::Fields& geoElem,
+              const inciter::FaceData& fd,
+              const std::vector< std::size_t >& inpoel,
+              const tk::UnsMesh::Coords& coord,
+              const std::unordered_map< std::size_t, std::set< std::size_t > >&
+                elemblkid,
+              const tk::Fields& U,
+              const tk::Fields& P,
+              tk::Fields& R,
+              std::vector< int >& srcFlag ) const
+    {
+      const auto rdof = g_inputdeck.get< tag::rdof >();
+      auto nmat = g_inputdeck.get< tag::multimat, tag::nmat >();<--- Shadow variable
+      const auto intsharp =
+        g_inputdeck.get< tag::multimat, tag::intsharp >();
+
+      const auto nelem = fd.Esuel().size()/4;
+
+      Assert( U.nunk() == P.nunk(), "Number of unknowns in solution "
+              "vector and primitive vector at recent time step incorrect" );
+      Assert( U.nunk() == R.nunk(), "Number of unknowns in solution "
+              "vector and right-hand side at recent time step incorrect" );
+      Assert( U.nprop() == rdof*m_ncomp, "Number of components in solution "
+              "vector must equal "+ std::to_string(rdof*m_ncomp) );
+      Assert( P.nprop() == rdof*nprim(), "Number of components in primitive "
+              "vector must equal "+ std::to_string(rdof*nprim()) );
+      Assert( fd.Inpofa().size()/3 == fd.Esuf().size()/2,
+              "Mismatch in inpofa size" );
+
+      // set rhs to zero
+      R.fill(0.0);
+
+      // configure a no-op lambda for prescribed velocity
+      auto velfn = []( ncomp_t, tk::real, tk::real, tk::real, tk::real ){
+        return tk::VelFn::result_type(); };
+
+      // compute internal surface flux (including non-conservative) integrals
+      tk::surfIntFV( nmat, m_mat_blk, t, rdof, inpoel,
+                     coord, fd, geoFace, geoElem, m_riemann, velfn, U, P,
+                     srcFlag, R, intsharp );
 
-  ownlim_complete();
-}
-
-void
-FV::comlim( int fromch,
-            const std::vector< std::size_t >& tetid,
-            const std::vector< std::vector< tk::real > >& u,
-            const std::vector< std::vector< tk::real > >& prim )
-// *****************************************************************************
-//  Receive chare-boundary limiter ghost data from neighboring chares
-//! \param[in] fromch Sender chare id
-//! \param[in] tetid Ghost tet ids we receive solution data for
-//! \param[in] u Limited high-order solution
-//! \param[in] prim Limited high-order primitive quantities
-//! \details This function receives contributions to the limited solution from
-//!   fellow chares.
-// *****************************************************************************
-{
-  Assert( u.size() == tetid.size(), "Size mismatch in FV::comlim()" );
-  Assert( prim.size() == tetid.size(), "Size mismatch in FV::comlim()" );
-
-  // Find local-to-ghost tet id map for sender chare
-  const auto& n = tk::cref_find( myGhosts()->m_ghost, fromch );
+      // compute boundary surface flux (including non-conservative) integrals
+      for (const auto& b : m_bc)
+        tk::bndSurfIntFV( nmat, m_mat_blk, rdof, b.first,
+                          fd, geoFace, geoElem, inpoel, coord, t, m_riemann,
+                          velfn, b.second, U, P, srcFlag, R, intsharp );
+
+      // compute optional source term
+      tk::srcIntFV( m_mat_blk, t, fd.Esuel().size()/4,
+                    geoElem, Problem::src, R, nmat );
+
+      // compute finite pressure relaxation terms
+      if (g_inputdeck.get< tag::multimat, tag::prelax >())
+      {
+        const auto ct = g_inputdeck.get< tag::multimat,
+                                         tag::prelax_timescale >();
+        tk::pressureRelaxationIntFV( nmat, m_mat_blk, rdof,
+                                     nelem, inpoel, coord, geoElem, U, P, ct,
+                                     R );
+      }
+
+      // compute external (energy) sources
+      m_physics.physSrc(nmat, t, geoElem, elemblkid, R, srcFlag);
+    }
 
-  for (std::size_t i=0; i<tetid.size(); ++i) {
-    auto j = tk::cref_find( n, tetid[i] );
-    Assert( j >= myGhosts()->m_fd.Esuel().size()/4,
-      "Receiving solution non-ghost data" );
-    auto b = tk::cref_find( myGhosts()->m_bid, j );
-    Assert( b < m_uc[1].size(), "Indexing out of bounds" );
-    Assert( b < m_pc[1].size(), "Indexing out of bounds" );
-    m_uc[1][b] = u[i];
-    m_pc[1][b] = prim[i];
-  }
-
-  // if we have received all solution ghost contributions from neighboring
-  // chares (chares we communicate along chare-boundary faces with), and
-  // contributed our solution to these neighbors, proceed to limiting
-  if (++m_nlim == myGhosts()->m_sendGhost.size()) {
-    m_nlim = 0;
-    comlim_complete();
-  }
-}
-
-void
-FV::dt()
-// *****************************************************************************
-// Compute time step size
-// *****************************************************************************
-{
-  auto d = Disc();
-
-  // Combine own and communicated contributions of limited solution and degrees
-  // of freedom in cells (if p-adaptive)
-  for (const auto& b : myGhosts()->m_bid) {
-    Assert( m_uc[1][b.second].size() == m_u.nprop(), "ncomp size mismatch" );
-    Assert( m_pc[1][b.second].size() == m_p.nprop(), "ncomp size mismatch" );
-    for (std::size_t c=0; c<m_u.nprop(); ++c) {
-      m_u(b.first,c) = m_uc[1][b.second][c];
-    }
-    for (std::size_t c=0; c<m_p.nprop(); ++c) {
-      m_p(b.first,c) = m_pc[1][b.second][c];
-    }
-  }
-
-  auto mindt = std::numeric_limits< tk::real >::max();
-
-  if (m_stage == 0)
-  {
-    auto const_dt = g_inputdeck.get< tag::dt >();
-    auto eps = std::numeric_limits< tk::real >::epsilon();
-
-    // use constant dt if configured
-    if (std::abs(const_dt) > eps) {
-
-      mindt = const_dt;
-
-    } else {      // compute dt based on CFL
-
-      // find the minimum dt across all PDEs integrated
-      auto eqdt =
-        g_fvpde[d->MeshId()].dt( myGhosts()->m_fd, myGhosts()->m_geoFace,
-          myGhosts()->m_geoElem, m_u, m_p, myGhosts()->m_fd.Esuel().size()/4,
-          m_srcFlag, m_dte );
-      if (eqdt < mindt) mindt = eqdt;
-
-      // time-step suppression for unsteady problems
-      tk::real coeff(1.0);
-      if (!g_inputdeck.get< tag::steady_state >()) {
-        if (d->It() < 100) coeff = 0.01 * static_cast< tk::real >(d->It());
-      }
-
-      mindt *= coeff * g_inputdeck.get< tag::cfl >();
-    }
-  }
-  else
-  {
-    mindt = d->Dt();
-  }
-
-  // Contribute to minimum dt across all chares then advance to next step
-  contribute( sizeof(tk::real), &mindt, CkReduction::min_double,
-              CkCallback(CkReductionTarget(FV,solve), thisProxy) );
-}
-
-void
-FV::solve( tk::real newdt )
-// *****************************************************************************
-// Compute right-hand side of discrete transport equations
-//! \param[in] newdt Size of this new time step
-// *****************************************************************************
-{
-  // Enable SDAG wait for building the solution vector during the next stage
-  thisProxy[ thisIndex ].wait4sol();
-  thisProxy[ thisIndex ].wait4lim();
-  thisProxy[ thisIndex ].wait4nod();
-
-  auto d = Disc();
-  const auto rdof = g_inputdeck.get< tag::rdof >();
-  const auto neq = m_u.nprop()/rdof;
+    //! Compute the minimum time step size
+//    //! \param[in] fd Face connectivity and boundary conditions object
+//    //! \param[in] geoFace Face geometry array
+    //! \param[in] geoElem Element geometry array
+    //! \param[in] U Solution vector at recent time step
+    //! \param[in] P Vector of primitive quantities at recent time step
+    //! \param[in] nielem Number of internal elements
+    //! \param[in] srcFlag Whether the energy source was added
+    //! \param[in,out] local_dte Time step size for each element (for local
+    //!   time stepping)
+    //! \return Minimum time step size
+    //! \details The allowable dt is calculated by looking at the maximum
+    //!   wave-speed in elements surrounding each face, times the area of that
+    //!   face. Once the maximum of this quantity over the mesh is determined,
+    //!   the volume of each cell is divided by this quantity. A minimum of this
+    //!   ratio is found over the entire mesh, which gives the allowable dt.
+    tk::real dt( const inciter::FaceData& /*fd*/,
+                 const tk::Fields& /*geoFace*/,
+                 const tk::Fields& geoElem,
+                 const tk::Fields& U,
+                 const tk::Fields& P,
+                 const std::size_t nielem,
+                 const std::vector< int >& srcFlag,
+                 std::vector< tk::real >& local_dte ) const
+    {
+      auto nmat = g_inputdeck.get< tag::multimat, tag::nmat >();<--- Shadow variable
+
+      // obtain dt restrictions from all physics
+      auto dt_e = timeStepSizeMultiMatFV(m_mat_blk, geoElem, nielem, nmat, U,
+        P, local_dte);
+      auto dt_p = m_physics.dtRestriction(geoElem, nielem, srcFlag);
+
+      return std::min(dt_e, dt_p);
+    }
+
+    //! Extract the velocity field at cell nodes. Currently unused.
+    //! \param[in] U Solution vector at recent time step
+    //! \param[in] N Element node indices
+    //! \return Array of the four values of the velocity field
+    std::array< std::array< tk::real, 4 >, 3 >
+    velocity( const tk::Fields& U,
+              const std::array< std::vector< tk::real >, 3 >&,
+              const std::array< std::size_t, 4 >& N ) const
+    {
+      const auto rdof = g_inputdeck.get< tag::rdof >();
+      auto nmat = g_inputdeck.get< tag::multimat, tag::nmat >();<--- Shadow variable
+
+      std::array< std::array< tk::real, 4 >, 3 > v;
+      v[0] = U.extract( momentumDofIdx(nmat, 0, rdof, 0), N );
+      v[1] = U.extract( momentumDofIdx(nmat, 1, rdof, 0), N );
+      v[2] = U.extract( momentumDofIdx(nmat, 2, rdof, 0), N );
+
+      std::vector< std::array< tk::real, 4 > > ar;
+      ar.resize(nmat);
+      for (std::size_t k=0; k<nmat; ++k)
+        ar[k] = U.extract( densityDofIdx(nmat, k, rdof, 0), N );
+
+      std::array< tk::real, 4 > r{{ 0.0, 0.0, 0.0, 0.0 }};
+      for (std::size_t i=0; i<r.size(); ++i) {
+        for (std::size_t k=0; k<nmat; ++k)
+          r[i] += ar[k][i];
+      }
+
+      std::transform( r.begin(), r.end(), v[0].begin(), v[0].begin(),
+                      []( tk::real s, tk::real& d ){ return d /= s; } );
+      std::transform( r.begin(), r.end(), v[1].begin(), v[1].begin(),
+                      []( tk::real s, tk::real& d ){ return d /= s; } );
+      std::transform( r.begin(), r.end(), v[2].begin(), v[2].begin(),
+                      []( tk::real s, tk::real& d ){ return d /= s; } );
+      return v;
+    }
+
+    //! Return a map that associates user-specified strings to functions
+    //! \return Map that associates user-specified strings to functions that
+    //!   compute relevant quantities to be output to file
+    std::map< std::string, tk::GetVarFn > OutVarFn() const
+    { return MultiMatOutVarFn(); }
+
+    //! Return analytic field names to be output to file
+    //! \return Vector of strings labelling analytic fields output in file
+    std::vector< std::string > analyticFieldNames() const {
+      auto nmat = g_inputdeck.get< eq, tag::nmat >();<--- Shadow variable
+
+      return MultiMatFieldNames(nmat);
+    }
+
+    //! Return surface field names to be output to file
+    //! \return Vector of strings labelling surface fields output in file
+    std::vector< std::string > surfNames() const
+    { return MultiMatSurfNames(); }
+
+    //! Return time history field names to be output to file
+    //! \return Vector of strings labelling time history fields output in file
+    std::vector< std::string > histNames() const {
+      return MultiMatHistNames();
+    }
 
-  // Set new time step size
-  if (m_stage == 0) d->setdt( newdt );
-
-  // Update Un
-  if (m_stage == 0) m_un = m_u;
-
-  // physical time at time-stage for computing exact source terms for
-  // unsteady problems
-  tk::real physT(d->T());
-  // 2-stage RK
-  if (m_nrk == 2) {
-    if (m_stage == 1) {
-      physT += d->Dt();
-    }
-  }
-  // 3-stage RK
-  else {
-    if (m_stage == 1) {
-      physT += d->Dt();
-    }
-    else if (m_stage == 2) {
-      physT += 0.5*d->Dt();
-    }
-  }
-
-  // Compute rhs
-  g_fvpde[d->MeshId()].rhs( physT, myGhosts()->m_geoFace, myGhosts()->m_geoElem,
-    myGhosts()->m_fd, myGhosts()->m_inpoel, myGhosts()->m_coord,
-    d->ElemBlockId(), m_u, m_p, m_rhs, m_srcFlag );
-
-  // Explicit time-stepping using RK3 to discretize time-derivative
-  const auto steady = g_inputdeck.get< tag::steady_state >();
-  for (std::size_t e=0; e<myGhosts()->m_nunk; ++e)
-    for (std::size_t c=0; c<neq; ++c)
-    {
-      auto dte = d->Dt();
-      if (steady) dte = m_dte[e];
-      auto rmark = c*rdof;
-      m_u(e, rmark) =  m_rkcoef[0][m_stage] * m_un(e, rmark)
-        + m_rkcoef[1][m_stage] * ( m_u(e, rmark)
-          + dte * m_rhs(e, c)/m_lhs(e, c) );
-      // zero out reconstructed dofs of equations using reduced dofs
-      if (rdof > 1) {
-        for (std::size_t k=1; k<rdof; ++k)
-        {
-          rmark = c*rdof+k;
-          m_u(e, rmark) = 0.0;
-        }
-      }
-    }
-
-  // Update primitives based on the evolved solution
-  g_fvpde[d->MeshId()].updatePrimitives( m_u, m_p,
-    myGhosts()->m_fd.Esuel().size()/4 );
-  if (!g_inputdeck.get< tag::accuracy_test >()) {
-    g_fvpde[d->MeshId()].cleanTraceMaterial( physT, myGhosts()->m_geoElem, m_u,
-      m_p, myGhosts()->m_fd.Esuel().size()/4 );
-  }
-
-  if (m_stage < m_nrk-1) {
-
-    // continue with next time step stage
-    stage();
-
-  } else {
-
-    // Increase number of iterations and physical time
-    d->next();
-
-    // Compute diagnostics, e.g., residuals
-    auto diag_computed = m_diag.compute( *d,
-      m_u.nunk()-myGhosts()->m_fd.Esuel().size()/4, myGhosts()->m_geoElem,
-      std::vector< std::size_t>{}, m_u, m_un );
-
-    // Continue to mesh refinement (if configured)
-    if (!diag_computed) refine( std::vector< tk::real >( m_u.nprop(), 1.0 ) );
-
-  }
-}
-
-void
-FV::refine( const std::vector< tk::real >& l2res )
-// *****************************************************************************
-// Optionally refine/derefine mesh
-//! \param[in] l2res L2-norms of the residual for each scalar component
-//!   computed across the whole problem
-// *****************************************************************************
-{
-  auto d = Disc();
-
-  // Assess convergence for steady state
-  const auto steady = g_inputdeck.get< tag::steady_state >();
-  const auto residual = g_inputdeck.get< tag::residual >();
-  const auto rc = g_inputdeck.get< tag::rescomp >() - 1;
-
-  bool converged(false);
-  if (steady) converged = l2res[rc] < residual;
-
-  // this is the last time step if max time of max number of time steps
-  // reached or the residual has reached its convergence criterion
-  if (d->finished() or converged) m_finished = 1;
-
-  auto dtref = g_inputdeck.get< tag::amr, tag::dtref >();
-  auto dtfreq = g_inputdeck.get< tag::amr, tag::dtfreq >();
-
-  // if t>0 refinement enabled and we hit the dtref frequency
-  if (dtref && !(d->It() % dtfreq)) {   // refine
-
-    d->startvol();
-    d->Ref()->dtref( myGhosts()->m_fd.Bface(), {},
-      tk::remap(myGhosts()->m_fd.Triinpoel(),d->Gid()) );
-    d->refined() = 1;
-
-  } else {      // do not refine
-
-    d->refined() = 0;
-    stage();
-
-  }
-}
-
-void
-FV::resizePostAMR(
-  const std::vector< std::size_t >& /*ginpoel*/,
-  const tk::UnsMesh::Chunk& chunk,
-  const tk::UnsMesh::Coords& coord,
-  const std::unordered_map< std::size_t, tk::UnsMesh::Edge >& /*addedNodes*/,
-  const std::unordered_map< std::size_t, std::size_t >& addedTets,
-  const std::set< std::size_t >& removedNodes,
-  const std::unordered_map< std::size_t, std::size_t >& amrNodeMap,
-  const tk::NodeCommMap& nodeCommMap,
-  const std::map< int, std::vector< std::size_t > >& bface,
-  const std::map< int, std::vector< std::size_t > >& /* bnode */,
-  const std::vector< std::size_t >& triinpoel,
-  const std::unordered_map< std::size_t, std::set< std::size_t > >& elemblockid )
-// *****************************************************************************
-//  Receive new mesh from Refiner
-//! \param[in] chunk New mesh chunk (connectivity and global<->local id maps)
-//! \param[in] coord New mesh node coordinates
-//! \param[in] addedTets Newly added mesh cells and their parents (local ids)
-//! \param[in] removedNodes Newly removed mesh node local ids
-//! \param[in] amrNodeMap Node id map after amr (local ids)
-//! \param[in] nodeCommMap New node communication map
-//! \param[in] bface Boundary-faces mapped to side set ids
-//! \param[in] triinpoel Boundary-face connectivity
-//! \param[in] elemblockid Local tet ids associated with mesh block ids
-// *****************************************************************************
-{
-  auto d = Disc();
-
-  // Set flag that indicates that we are during time stepping
-  m_initial = 0;
-  myGhosts()->m_initial = 0;
-
-  // Zero field output iteration count between two mesh refinement steps
-  d->Itf() = 0;
-
-  // Increase number of iterations with mesh refinement
-  ++d->Itr();
-
-  // Save old number of elements
-  [[maybe_unused]] auto old_nelem = myGhosts()->m_inpoel.size()/4;
-
-  // Resize mesh data structures
-  d->resizePostAMR( chunk, coord, amrNodeMap, nodeCommMap, removedNodes,
-    elemblockid );
-
-  // Update state
-  myGhosts()->m_inpoel = d->Inpoel();
-  myGhosts()->m_coord = d->Coord();
-  auto nelem = myGhosts()->m_inpoel.size()/4;
-  m_p.resize( nelem );
-  m_u.resize( nelem );
-  m_srcFlag.resize( nelem );
-  m_un.resize( nelem );
-  m_lhs.resize( nelem );
-  m_rhs.resize( nelem );
-
-  myGhosts()->m_fd = FaceData( myGhosts()->m_inpoel, bface,
-    tk::remap(triinpoel,d->Lid()) );
-
-  myGhosts()->m_geoFace =
-    tk::Fields( tk::genGeoFaceTri( myGhosts()->m_fd.Nipfac(),
-    myGhosts()->m_fd.Inpofa(), coord ) );
-  myGhosts()->m_geoElem = tk::Fields( tk::genGeoElemTet( myGhosts()->m_inpoel,
-    coord ) );
-
-  myGhosts()->m_nfac = myGhosts()->m_fd.Inpofa().size()/3;
-  myGhosts()->m_nunk = nelem;
-  m_npoin = coord[0].size();
-  myGhosts()->m_bndFace.clear();
-  myGhosts()->m_exptGhost.clear();
-  myGhosts()->m_sendGhost.clear();
-  myGhosts()->m_ghost.clear();
-  myGhosts()->m_esup.clear();
-
-  // Update solution on new mesh, P0 (cell center value) only for now
-  m_un = m_u;
-  auto pn = m_p;<--- Variable 'pn' is assigned a value that is never used.
-  auto unprop = m_u.nprop();<--- Variable 'unprop' is assigned a value that is never used.
-  auto pnprop = m_p.nprop();<--- Variable 'pnprop' is assigned a value that is never used.
-  for (const auto& [child,parent] : addedTets) {
-    Assert( child < nelem, "Indexing out of new solution vector" );
-    Assert( parent < old_nelem, "Indexing out of old solution vector" );
-    for (std::size_t i=0; i<unprop; ++i) m_u(child,i) = m_un(parent,i);
-    for (std::size_t i=0; i<pnprop; ++i) m_p(child,i) = pn(parent,i);
-  }
-  m_un = m_u;
-
-  // Resize communication buffers
-  m_ghosts[thisIndex].resizeComm();
-}
-
-bool
-FV::fieldOutput() const
-// *****************************************************************************
-// Decide wether to output field data
-//! \return True if field data is output in this step
-// *****************************************************************************
-{
-  auto d = Disc();
-
-  // Output field data
-  return d->fielditer() or d->fieldtime() or d->fieldrange() or m_finished;
-}
-
-bool
-FV::refinedOutput() const
-// *****************************************************************************
-// Decide if we write field output using a refined mesh
-//! \return True if field output will use a refined mesh
-// *****************************************************************************
-{
-  return g_inputdeck.get< tag::field_output, tag::refined >() &&
-         g_inputdeck.get< tag::scheme >() != ctr::SchemeType::FV;
-}
+    //! Return surface field output going to file
+    std::vector< std::vector< tk::real > >
+    surfOutput( const inciter::FaceData& fd,
+      const tk::Fields& U,
+      const tk::Fields& P ) const
+    {
+      const auto rdof = g_inputdeck.get< tag::rdof >();
+      auto nmat = g_inputdeck.get< tag::multimat, tag::nmat >();<--- Shadow variable
+
+      return MultiMatSurfOutput( nmat, rdof, fd, U, P );
+    }
+
+    //! Return time history field output evaluated at time history points
+    //! \param[in] h History point data
+    //! \param[in] inpoel Element-node connectivity
+    //! \param[in] coord Array of nodal coordinates
+    //! \param[in] U Array of unknowns
+    //! \param[in] P Array of primitive quantities
+    //! \return Vector of time history output of bulk flow quantities (density,
+    //!   velocity, total energy, pressure, and volume fraction) evaluated at 
+    //!   time history points
+    std::vector< std::vector< tk::real > >
+    histOutput( const std::vector< HistData >& h,
+                const std::vector< std::size_t >& inpoel,
+                const tk::UnsMesh::Coords& coord,
+                const tk::Fields& U,
+                const tk::Fields& P ) const
+    {
+      const auto rdof = g_inputdeck.get< tag::rdof >();
+      auto nmat = g_inputdeck.get< tag::multimat, tag::nmat >();<--- Shadow variable
+
+      const auto& x = coord[0];
+      const auto& y = coord[1];
+      const auto& z = coord[2];
+
+      std::vector< std::vector< tk::real > > Up(h.size());
+
+      std::size_t j = 0;
+      for (const auto& p : h) {
+        auto e = p.get< tag::elem >();
+        auto chp = p.get< tag::coord >();
+
+        // Evaluate inverse Jacobian
+        std::array< std::array< tk::real, 3>, 4 > cp{{
+          {{ x[inpoel[4*e  ]], y[inpoel[4*e  ]], z[inpoel[4*e  ]] }},
+          {{ x[inpoel[4*e+1]], y[inpoel[4*e+1]], z[inpoel[4*e+1]] }},
+          {{ x[inpoel[4*e+2]], y[inpoel[4*e+2]], z[inpoel[4*e+2]] }},
+          {{ x[inpoel[4*e+3]], y[inpoel[4*e+3]], z[inpoel[4*e+3]] }} }};
+        auto J = tk::inverseJacobian( cp[0], cp[1], cp[2], cp[3] );
+
+        // evaluate solution at history-point
+        std::array< tk::real, 3 > dc{{chp[0]-cp[0][0], chp[1]-cp[0][1],
+          chp[2]-cp[0][2]}};
+        auto B = tk::eval_basis(rdof, tk::dot(J[0],dc), tk::dot(J[1],dc),
+          tk::dot(J[2],dc));
+        auto uhp = eval_state(m_ncomp, rdof, rdof, e, U, B);
+        auto php = eval_state(nprim(), rdof, rdof, e, P, B);
+
+        // store solution in history output vector
+        Up[j].resize(6+nmat, 0.0);
+        for (std::size_t k=0; k<nmat; ++k) {
+          Up[j][0] += uhp[densityIdx(nmat,k)];
+          Up[j][4] += uhp[energyIdx(nmat,k)];
+          Up[j][5] += php[pressureIdx(nmat,k)];
+          Up[j][6+k] = uhp[volfracIdx(nmat,k)];
+        }
+        Up[j][1] = php[velocityIdx(nmat,0)];
+        Up[j][2] = php[velocityIdx(nmat,1)];
+        Up[j][3] = php[velocityIdx(nmat,2)];
+        ++j;
+      }
+
+      return Up;
+    }
+
+    //! Return names of integral variables to be output to diagnostics file
+    //! \return Vector of strings labelling integral variables output
+    std::vector< std::string > names() const
+    {
+      auto nmat = g_inputdeck.get< tag::multimat, tag::nmat >();<--- Shadow variable
+      return MultiMatDiagNames(nmat);
+    }
+
+    //! Return analytic solution (if defined by Problem) at xi, yi, zi, t
+    //! \param[in] xi X-coordinate at which to evaluate the analytic solution
+    //! \param[in] yi Y-coordinate at which to evaluate the analytic solution
+    //! \param[in] zi Z-coordinate at which to evaluate the analytic solution
+    //! \param[in] t Physical time at which to evaluate the analytic solution
+    //! \return Vector of analytic solution at given location and time
+    std::vector< tk::real >
+    analyticSolution( tk::real xi, tk::real yi, tk::real zi, tk::real t ) const
+    { return Problem::analyticSolution( m_ncomp, m_mat_blk, xi, yi, zi, t ); }
+
+    //! Return analytic solution for conserved variables
+    //! \param[in] xi X-coordinate at which to evaluate the analytic solution
+    //! \param[in] yi Y-coordinate at which to evaluate the analytic solution
+    //! \param[in] zi Z-coordinate at which to evaluate the analytic solution
+    //! \param[in] t Physical time at which to evaluate the analytic solution
+    //! \return Vector of analytic solution at given location and time
+    std::vector< tk::real >
+    solution( tk::real xi, tk::real yi, tk::real zi, tk::real t ) const
+    { return Problem::initialize( m_ncomp, m_mat_blk, xi, yi, zi, t ); }
+
+    //! Return cell-averaged specific total energy for an element
+    //! \param[in] e Element id for which total energy is required
+    //! \param[in] unk Vector of conserved quantities
+    //! \return Cell-averaged specific total energy for given element
+    tk::real sp_totalenergy(std::size_t e, const tk::Fields& unk) const
+    {
+      const auto rdof = g_inputdeck.get< tag::rdof >();
+      auto nmat = g_inputdeck.get< tag::multimat, tag::nmat >();<--- Shadow variable
+
+      tk::real sp_te(0.0);
+      // sum each material total energy
+      for (std::size_t k=0; k<nmat; ++k) {
+        sp_te += unk(e, energyDofIdx(nmat,k,rdof,0));
+      }
+      return sp_te;
+    }
+
+    //! Compute relevant sound speed for output
+    //! \param[in] nielem Number of internal elements
+    //! \param[in] U Solution vector at recent time step
+    //! \param[in] P Primitive vector at recent time step
+    //! \param[in,out] ss Sound speed vector
+    void soundspeed(
+      std::size_t nielem,
+      const tk::Fields& U,
+      const tk::Fields& P,
+      std::vector< tk::real >& ss) const
+    {
+      Assert( ss.size() == nielem, "Size of sound speed vector incorrect " );
+
+      const auto ndof = g_inputdeck.get< tag::ndof >();
+      const auto rdof = g_inputdeck.get< tag::rdof >();
+      const auto use_mass_avg =
+        g_inputdeck.get< tag::multimat, tag::dt_sos_massavg >();
+      auto nmat = g_inputdeck.get< tag::multimat, tag::nmat >();<--- Shadow variable
+      std::size_t ncomp = U.nprop()/rdof;
+      std::size_t nprim = P.nprop()/rdof;<--- Shadow variable
+
+      std::vector< tk::real > ugp(ncomp, 0.0), pgp(nprim, 0.0);<--- Variable 'ugp' is assigned a value that is never used.<--- Variable 'pgp' is assigned a value that is never used.
+
+      for (std::size_t e=0; e<nielem; ++e) {
+        // basis function at centroid
+        std::vector< tk::real > B(rdof, 0.0);
+        B[0] = 1.0;
+
+        // get conserved quantities
+        ugp = eval_state(ncomp, rdof, ndof, e, U, B);
+        // get primitive quantities
+        pgp = eval_state(nprim, rdof, ndof, e, P, B);
+
+        // acoustic speed (this should be consistent with time-step calculation)
+        ss[e] = 0.0;
+        tk::real mixtureDensity = 0.0;
+        for (std::size_t k=0; k<nmat; ++k)
+        {
+          if (use_mass_avg > 0)
+          {
+            // mass averaging SoS
+            ss[e] += ugp[densityIdx(nmat,k)]*
+              m_mat_blk[k].compute< EOS::soundspeed >(
+              ugp[densityIdx(nmat, k)], pgp[pressureIdx(nmat, k)],
+              ugp[volfracIdx(nmat, k)], k );
+
+            mixtureDensity += ugp[densityIdx(nmat,k)];
+          }
+          else
+          {
+            if (ugp[volfracIdx(nmat, k)] > 1.0e-04)
+            {
+              ss[e] = std::max( ss[e], m_mat_blk[k].compute< EOS::soundspeed >(
+                ugp[densityIdx(nmat, k)], pgp[pressureIdx(nmat, k)],
+                ugp[volfracIdx(nmat, k)], k ) );
+            }
+          }
+        }
+        if (use_mass_avg > 0) ss[e] /= mixtureDensity;
+      }
+    }
+
+  private:
+    //! Physics policy
+    const Physics m_physics;
+    //! Number of components in this PDE system
+    const ncomp_t m_ncomp;
+    //! Riemann solver
+    tk::RiemannFluxFn m_riemann;
+    //! BC configuration
+    BCStateFn m_bc;
+    //! EOS material block
+    std::vector< EOS > m_mat_blk;
+
+    //! Evaluate conservative part of physical flux function for this PDE system
+    //! \param[in] ncomp Number of scalar components in this PDE system
+    //! \param[in] ugp Numerical solution at the Gauss point at which to
+    //!   evaluate the flux
+    //! \return Flux vectors for all components in this PDE system
+    //! \note The function signature must follow tk::FluxFn
+    static tk::FluxFn::result_type
+    flux( ncomp_t ncomp,
+          const std::vector< EOS >& mat_blk,
+          const std::vector< tk::real >& ugp,
+          const std::vector< std::array< tk::real, 3 > >& )
+    {
+      auto nmat = g_inputdeck.get< tag::multimat, tag::nmat >();<--- Shadow variable
+
+      return tk::fluxTerms(ncomp, nmat, mat_blk, ugp);
+    }
+
+    //! \brief Boundary state function providing the left and right state of a
+    //!   face at Dirichlet boundaries
+    //! \param[in] ncomp Number of scalar components in this PDE system
+    //! \param[in] ul Left (domain-internal) state
+    //! \param[in] x X-coordinate at which to compute the states
+    //! \param[in] y Y-coordinate at which to compute the states
+    //! \param[in] z Z-coordinate at which to compute the states
+    //! \param[in] t Physical time
+    //! \return Left and right states for all scalar components in this PDE
+    //!   system
+    //! \note The function signature must follow tk::StateFn. For multimat, the
+    //!   left or right state is the vector of conserved quantities, followed by
+    //!   the vector of primitive quantities appended to it.
+    static tk::StateFn::result_type
+    dirichlet( ncomp_t ncomp,
+               const std::vector< EOS >& mat_blk,
+               const std::vector< tk::real >& ul, tk::real x, tk::real y,
+               tk::real z, tk::real t, const std::array< tk::real, 3 >& )
+    {
+      auto nmat = g_inputdeck.get< tag::multimat, tag::nmat >();<--- Shadow variable<--- Variable 'nmat' is assigned a value that is never used.
+
+      auto ur = Problem::initialize( ncomp, mat_blk, x, y, z, t );
+      Assert( ur.size() == ncomp, "Incorrect size for boundary state vector" );
+
+      ur.resize(ul.size());
 
-void
-FV::writeFields( CkCallback c )
-// *****************************************************************************
-// Output mesh field data
-//! \param[in] c Function to continue with after the write
-// *****************************************************************************
-{
-  auto d = Disc();
-
-  const auto& inpoel = std::get< 0 >( d->Chunk() );
-  auto esup = tk::genEsup( inpoel, 4 );
-  auto nelem = inpoel.size() / 4;
-
-  // Combine own and communicated contributions and finish averaging of node
-  // field output in chare boundary nodes
-  const auto& lid = std::get< 2 >( d->Chunk() );
-  for (const auto& [g,f] : m_uNodefieldsc) {
-    Assert( m_uNodefields.nprop() == f.first.size(), "Size mismatch" );
-    auto p = tk::cref_find( lid, g );
-    for (std::size_t i=0; i<f.first.size(); ++i) {
-      m_uNodefields(p,i) += f.first[i];
-      m_uNodefields(p,i) /= static_cast< tk::real >(
-                              esup.second[p+1] - esup.second[p] + f.second );
-    }
-  }
-  tk::destroy( m_uNodefieldsc );
-  for (const auto& [g,f] : m_pNodefieldsc) {
-    Assert( m_pNodefields.nprop() == f.first.size(), "Size mismatch" );
-    auto p = tk::cref_find( lid, g );
-    for (std::size_t i=0; i<f.first.size(); ++i) {
-      m_pNodefields(p,i) += f.first[i];
-      m_pNodefields(p,i) /= static_cast< tk::real >(
-                              esup.second[p+1] - esup.second[p] + f.second );
-    }
-  }
-  tk::destroy( m_pNodefieldsc );
-
-  // Lambda to decide if a node (global id) is on a chare boundary of the field
-  // output mesh. p - global node id, return true if node is on the chare
-  // boundary.
-  auto chbnd = [ this ]( std::size_t p ) {
-    return
-      std::any_of( Disc()->NodeCommMap().cbegin(), Disc()->NodeCommMap().cend(),
-        [&](const auto& s) { return s.second.find(p) != s.second.cend(); } );
-  };
-
-  // Finish computing node field output averages in internal nodes
-  auto npoin = d->Coord()[0].size();
-  auto& gid = std::get< 1 >( d->Chunk() );
-  for (std::size_t p=0; p<npoin; ++p) {
-    if (!chbnd(gid[p])) {
-      auto n = static_cast< tk::real >( esup.second[p+1] - esup.second[p] );
-      for (std::size_t i=0; i<m_uNodefields.nprop(); ++i)
-        m_uNodefields(p,i) /= n;
-      for (std::size_t i=0; i<m_pNodefields.nprop(); ++i)
-        m_pNodefields(p,i) /= n;
-    }
-  }
-
-  // Collect field output from numerical solution requested by user
-  auto elemfields = numericFieldOutput( m_uElemfields, tk::Centering::ELEM,
-    g_fvpde[Disc()->MeshId()].OutVarFn(), m_pElemfields );
-  auto nodefields = numericFieldOutput( m_uNodefields, tk::Centering::NODE,
-    g_fvpde[Disc()->MeshId()].OutVarFn(), m_pNodefields );
-
-  // Collect field output from analytical solutions (if exist)
-  const auto& coord = d->Coord();
-  auto geoElem = tk::genGeoElemTet( inpoel, coord );
-  auto t = Disc()->T();
-  analyticFieldOutput( g_fvpde[d->MeshId()], tk::Centering::ELEM,
-    geoElem.extract_comp(1), geoElem.extract_comp(2), geoElem.extract_comp(3),
-    t, elemfields );
-  analyticFieldOutput( g_fvpde[d->MeshId()], tk::Centering::NODE, coord[0],
-    coord[1], coord[2], t, nodefields );
-
-  // Add sound speed vector
-  std::vector< tk::real > soundspd(nelem, 0.0);
-  g_fvpde[d->MeshId()].soundspeed(nelem, m_u, m_p, soundspd);
-  elemfields.push_back(soundspd);
-
-  // Add source flag array to element-centered field output
-  std::vector< tk::real > srcFlag( begin(m_srcFlag), end(m_srcFlag) );
-  // Here m_srcFlag has a size of m_u.nunk() which is the number of the
-  // elements within this partition (nelem) plus the ghost partition cells.
-  // For the purpose of output, we only need the solution data within this
-  // partition. Therefore, resizing it to nelem removes the extra partition
-  // boundary allocations in the srcFlag vector. Since the code assumes that
-  // the boundary elements are on the top, the resize operation keeps the lower
-  // portion.
-  srcFlag.resize( nelem );
-  elemfields.push_back( srcFlag );
-
-  // Query fields names requested by user
-  auto elemfieldnames = numericFieldNames( tk::Centering::ELEM );
-  auto nodefieldnames = numericFieldNames( tk::Centering::NODE );
-
-  // Collect field output names for analytical solutions
-  analyticFieldNames( g_fvpde[d->MeshId()], tk::Centering::ELEM, elemfieldnames );
-  analyticFieldNames( g_fvpde[d->MeshId()], tk::Centering::NODE, nodefieldnames );
-
-  elemfieldnames.push_back( "sound speed" );
-  elemfieldnames.push_back( "src_flag" );
-
-  Assert( elemfieldnames.size() == elemfields.size(), "Size mismatch" );
-  Assert( nodefieldnames.size() == nodefields.size(), "Size mismatch" );
-
-  // Collect surface output names
-  auto surfnames = g_fvpde[d->MeshId()].surfNames();
-
-  // Collect surface field solution
-  const auto& fd = myGhosts()->m_fd;
-  auto elemsurfs = g_fvpde[d->MeshId()].surfOutput(fd, m_u, m_p);
-
-  // Output chare mesh and fields metadata to file
-  const auto& triinpoel = tk::remap( fd.Triinpoel(), d->Gid() );
-  d->write( inpoel, d->Coord(), fd.Bface(), {},
-            tk::remap( triinpoel, lid ), elemfieldnames, nodefieldnames,
-            surfnames, {}, elemfields, nodefields, elemsurfs, {}, c );
-}
-
-void
-FV::comnodeout( const std::vector< std::size_t >& gid,
-                const std::vector< std::size_t >& nesup,
-                const std::vector< std::vector< tk::real > >& Lu,
-                const std::vector< std::vector< tk::real > >& Lp )
-// *****************************************************************************
-//  Receive chare-boundary nodal solution (for field output) contributions from
-//  neighboring chares
-//! \param[in] gid Global mesh node IDs at which we receive contributions
-//! \param[in] nesup Number of elements surrounding points
-//! \param[in] Lu Partial contributions of solution nodal fields to
-//!   chare-boundary nodes
-//! \param[in] Lp Partial contributions of primitive quantity nodal fields to
-//!   chare-boundary nodes
-// *****************************************************************************
-{
-  Assert( gid.size() == nesup.size(), "Size mismatch" );
-  Assert(Lu.size() == m_uNodefields.nprop(), "Fields size mismatch");
-  Assert(Lp.size() == m_pNodefields.nprop(), "Fields size mismatch");
-  for (std::size_t f=0; f<Lu.size(); ++f)
-    Assert( gid.size() == Lu[f].size(), "Size mismatch" );
-  for (std::size_t f=0; f<Lp.size(); ++f)
-    Assert( gid.size() == Lp[f].size(), "Size mismatch" );
-
-  for (std::size_t i=0; i<gid.size(); ++i) {
-    auto& nfu = m_uNodefieldsc[ gid[i] ];
-    nfu.first.resize( Lu.size() );
-    for (std::size_t f=0; f<Lu.size(); ++f) nfu.first[f] += Lu[f][i];
-    nfu.second += nesup[i];
-    auto& nfp = m_pNodefieldsc[ gid[i] ];
-    nfp.first.resize( Lp.size() );
-    for (std::size_t f=0; f<Lp.size(); ++f) nfp.first[f] += Lp[f][i];
-    nfp.second += nesup[i];
-  }
-
-  // When we have heard from all chares we communicate with, this chare is done
-  if (++m_nnod == Disc()->NodeCommMap().size()) {
-    m_nnod = 0;
-    comnodeout_complete();
-  }
-}
-
-void
-FV::stage()
-// *****************************************************************************
-// Evaluate whether to continue with next time step stage
-// *****************************************************************************
-{
-  // Increment Runge-Kutta stage counter
-  ++m_stage;
-
-  // if not all Runge-Kutta stages complete, continue to next time stage,
-  // otherwise prepare for nodal field output
-  if (m_stage < m_nrk)
-    next();
-  else
-    startFieldOutput( CkCallback(CkIndex_FV::step(), thisProxy[thisIndex]) );
-}
-
-void
-FV::evalLB( int nrestart )
-// *****************************************************************************
-// Evaluate whether to do load balancing
-//! \param[in] nrestart Number of times restarted
-// *****************************************************************************
-{
-  auto d = Disc();
-
-  // Detect if just returned from a checkpoint and if so, zero timers and flag
-  if (d->restarted( nrestart )) m_finished = 0;
-
-  const auto lbfreq = g_inputdeck.get< tag::cmd, tag::lbfreq >();
-  const auto nonblocking = g_inputdeck.get< tag::cmd, tag::nonblocking >();
-
-  // Load balancing if user frequency is reached or after the second time-step
-  if ( (d->It()) % lbfreq == 0 || d->It() == 2 ) {
-
-    AtSync();
-    if (nonblocking) next();
-
-  } else {
-
-    next();
-
-  }
-}
-
-void
-FV::evalRestart()
-// *****************************************************************************
-// Evaluate whether to save checkpoint/restart
-// *****************************************************************************
-{
-  auto d = Disc();
-
-  const auto rsfreq = g_inputdeck.get< tag::cmd, tag::rsfreq >();
-  const auto benchmark = g_inputdeck.get< tag::cmd, tag::benchmark >();
-
-  if ( !benchmark && (d->It()) % rsfreq == 0 ) {
-
-    std::vector< std::size_t > meshdata{ /* finished = */ 0, d->MeshId() };
-    contribute( meshdata, CkReduction::nop,
-      CkCallback(CkReductionTarget(Transporter,checkpoint), d->Tr()) );
-
-  } else {
-
-    evalLB( /* nrestart = */ -1 );
-
-  }
-}
-
-void
-FV::step()
-// *****************************************************************************
-// Evaluate wether to continue with next time step
-// *****************************************************************************
-{
-  auto d = Disc();
-
-  // Output time history
-  if (d->histiter() or d->histtime() or d->histrange()) {
-    std::vector< std::vector< tk::real > > hist;
-    auto h = g_fvpde[d->MeshId()].histOutput( d->Hist(), myGhosts()->m_inpoel,
-      myGhosts()->m_coord, m_u, m_p );
-    hist.insert( end(hist), begin(h), end(h) );
-    d->history( std::move(hist) );
-  }
-
-  // Output one-liner status report to screen
-  d->status();
-  // Reset Runge-Kutta stage counter
-  m_stage = 0;
-
-  // If neither max iterations nor max time reached, continue, otherwise finish
-  if (not m_finished) {
-
-    evalRestart();
- 
-  } else {
-
-    auto meshid = d->MeshId();
-    d->contribute( sizeof(std::size_t), &meshid, CkReduction::nop,
-                   CkCallback(CkReductionTarget(Transporter,finish), d->Tr()) );
-
-  }
-}
-
-#include "NoWarning/fv.def.h"
+      tk::real rho(0.0);
+      for (std::size_t k=0; k<nmat; ++k)
+        rho += ur[densityIdx(nmat, k)];
+
+      // get primitives in boundary state
+
+      // velocity
+      ur[ncomp+velocityIdx(nmat, 0)] = ur[momentumIdx(nmat, 0)] / rho;
+      ur[ncomp+velocityIdx(nmat, 1)] = ur[momentumIdx(nmat, 1)] / rho;
+      ur[ncomp+velocityIdx(nmat, 2)] = ur[momentumIdx(nmat, 2)] / rho;
+
+      // material pressures
+      for (std::size_t k=0; k<nmat; ++k)
+      {
+        auto gk = getDeformGrad(nmat, k, ur);
+        ur[ncomp+pressureIdx(nmat, k)] = mat_blk[k].compute< EOS::pressure >(
+          ur[densityIdx(nmat, k)], ur[ncomp+velocityIdx(nmat, 0)],
+          ur[ncomp+velocityIdx(nmat, 1)], ur[ncomp+velocityIdx(nmat, 2)],
+          ur[energyIdx(nmat, k)], ur[volfracIdx(nmat, k)], k, gk );
+      }
+
+      Assert( ur.size() == ncomp+nmat+3, "Incorrect size for appended "
+              "boundary state vector" );
+
+      return {{ std::move(ul), std::move(ur) }};
+    }
+
+    // Other boundary condition types that do not depend on "Problem" should be
+    // added in BCFunctions.hpp
+};
+
+} // fv::
+
+} // inciter::
+
+#endif // FVMultiMat_h
 
diff --git a/Debug/cppcheck/47.html b/Debug/cppcheck/47.html index 0dc1af769812..8e861086b17e 100644 --- a/Debug/cppcheck/47.html +++ b/Debug/cppcheck/47.html @@ -152,12 +152,12 @@
   1
@@ -1639,1486 +1639,2916 @@ 

Cppcheck report - [

// *****************************************************************************
+1480
+1481
+1482
+1483
+1484
+1485
+1486
+1487
+1488
+1489
+1490
+1491
+1492
+1493
+1494
+1495
+1496
+1497
+1498
+1499
+1500
+1501
+1502
+1503
+1504
+1505
+1506
+1507
+1508
+1509
+1510
+1511
+1512
+1513
+1514
+1515
+1516
+1517
+1518
+1519
+1520
+1521
+1522
+1523
+1524
+1525
+1526
+1527
+1528
+1529
+1530
+1531
+1532
+1533
+1534
+1535
+1536
+1537
+1538
+1539
+1540
+1541
+1542
+1543
+1544
+1545
+1546
+1547
+1548
+1549
+1550
+1551
+1552
+1553
+1554
+1555
+1556
+1557
+1558
+1559
+1560
+1561
+1562
+1563
+1564
+1565
+1566
+1567
+1568
+1569
+1570
+1571
+1572
+1573
+1574
+1575
+1576
+1577
+1578
+1579
+1580
+1581
+1582
+1583
+1584
+1585
+1586
+1587
+1588
+1589
+1590
+1591
+1592
+1593
+1594
+1595
+1596
+1597
+1598
+1599
+1600
+1601
+1602
+1603
+1604
+1605
+1606
+1607
+1608
+1609
+1610
+1611
+1612
+1613
+1614
+1615
+1616
+1617
+1618
+1619
+1620
+1621
+1622
+1623
+1624
+1625
+1626
+1627
+1628
+1629
+1630
+1631
+1632
+1633
+1634
+1635
+1636
+1637
+1638
+1639
+1640
+1641
+1642
+1643
+1644
+1645
+1646
+1647
+1648
+1649
+1650
+1651
+1652
+1653
+1654
+1655
+1656
+1657
+1658
+1659
+1660
+1661
+1662
+1663
+1664
+1665
+1666
+1667
+1668
+1669
+1670
+1671
+1672
+1673
+1674
+1675
+1676
+1677
+1678
+1679
+1680
+1681
+1682
+1683
+1684
+1685
+1686
+1687
+1688
+1689
+1690
+1691
+1692
+1693
+1694
+1695
+1696
+1697
+1698
+1699
+1700
+1701
+1702
+1703
+1704
+1705
+1706
+1707
+1708
+1709
+1710
+1711
+1712
+1713
+1714
+1715
+1716
+1717
+1718
+1719
+1720
+1721
+1722
+1723
+1724
+1725
+1726
+1727
+1728
+1729
+1730
+1731
+1732
+1733
+1734
+1735
+1736
+1737
+1738
+1739
+1740
+1741
+1742
+1743
+1744
+1745
+1746
+1747
+1748
+1749
+1750
+1751
+1752
+1753
+1754
+1755
+1756
+1757
+1758
+1759
+1760
+1761
+1762
+1763
+1764
+1765
+1766
+1767
+1768
+1769
+1770
+1771
+1772
+1773
+1774
+1775
+1776
+1777
+1778
+1779
+1780
+1781
+1782
+1783
+1784
+1785
+1786
+1787
+1788
+1789
+1790
+1791
+1792
+1793
+1794
+1795
+1796
+1797
+1798
+1799
+1800
+1801
+1802
+1803
+1804
+1805
+1806
+1807
+1808
+1809
+1810
+1811
+1812
+1813
+1814
+1815
+1816
+1817
+1818
+1819
+1820
+1821
+1822
+1823
+1824
+1825
+1826
+1827
+1828
+1829
+1830
+1831
+1832
+1833
+1834
+1835
+1836
+1837
+1838
+1839
+1840
+1841
+1842
+1843
+1844
+1845
+1846
+1847
+1848
+1849
+1850
+1851
+1852
+1853
+1854
+1855
+1856
+1857
+1858
+1859
+1860
+1861
+1862
+1863
+1864
+1865
+1866
+1867
+1868
+1869
+1870
+1871
+1872
+1873
+1874
+1875
+1876
+1877
+1878
+1879
+1880
+1881
+1882
+1883
+1884
+1885
+1886
+1887
+1888
+1889
+1890
+1891
+1892
+1893
+1894
+1895
+1896
+1897
+1898
+1899
+1900
+1901
+1902
+1903
+1904
+1905
+1906
+1907
+1908
+1909
+1910
+1911
+1912
+1913
+1914
+1915
+1916
+1917
+1918
+1919
+1920
+1921
+1922
+1923
+1924
+1925
+1926
+1927
+1928
+1929
+1930
+1931
+1932
+1933
+1934
+1935
+1936
+1937
+1938
+1939
+1940
+1941
+1942
+1943
+1944
+1945
+1946
+1947
+1948
+1949
+1950
+1951
+1952
+1953
+1954
+1955
+1956
+1957
+1958
+1959
+1960
+1961
+1962
+1963
+1964
+1965
+1966
+1967
+1968
+1969
+1970
+1971
+1972
+1973
+1974
+1975
+1976
+1977
+1978
+1979
+1980
+1981
+1982
+1983
+1984
+1985
+1986
+1987
+1988
+1989
+1990
+1991
+1992
+1993
+1994
+1995
+1996
+1997
+1998
+1999
+2000
+2001
+2002
+2003
+2004
+2005
+2006
+2007
+2008
+2009
+2010
+2011
+2012
+2013
+2014
+2015
+2016
+2017
+2018
+2019
+2020
+2021
+2022
+2023
+2024
+2025
+2026
+2027
+2028
+2029
+2030
+2031
+2032
+2033
+2034
+2035
+2036
+2037
+2038
+2039
+2040
+2041
+2042
+2043
+2044
+2045
+2046
+2047
+2048
+2049
+2050
+2051
+2052
+2053
+2054
+2055
+2056
+2057
+2058
+2059
+2060
+2061
+2062
+2063
+2064
+2065
+2066
+2067
+2068
+2069
+2070
+2071
+2072
+2073
+2074
+2075
+2076
+2077
+2078
+2079
+2080
+2081
+2082
+2083
+2084
+2085
+2086
+2087
+2088
+2089
+2090
+2091
+2092
+2093
+2094
+2095
+2096
+2097
+2098
+2099
+2100
+2101
+2102
+2103
+2104
+2105
+2106
+2107
+2108
+2109
+2110
+2111
+2112
+2113
+2114
+2115
+2116
+2117
+2118
+2119
+2120
+2121
+2122
+2123
+2124
+2125
+2126
+2127
+2128
+2129
+2130
+2131
+2132
+2133
+2134
+2135
+2136
+2137
+2138
+2139
+2140
+2141
+2142
+2143
+2144
+2145
+2146
+2147
+2148
+2149
+2150
+2151
+2152
+2153
+2154
+2155
+2156
+2157
+2158
+2159
+2160
+2161
+2162
+2163
+2164
+2165
+2166
+2167
+2168
+2169
+2170
+2171
+2172
+2173
+2174
+2175
+2176
+2177
// *****************************************************************************
 /*!
-  \file      src/PDE/MultiMat/DGMultiMat.hpp
+  \file      src/Inciter/Refiner.cpp
   \copyright 2012-2015 J. Bakosi,
              2016-2018 Los Alamos National Security, LLC.,
              2019-2021 Triad National Security, LLC.
              All rights reserved. See the LICENSE file for details.
-  \brief     Compressible multi-material flow using discontinuous Galerkin
-    finite elements
-  \details   This file implements calls to the physics operators governing
-    compressible multi-material flow (with velocity equilibrium) using
-    discontinuous Galerkin discretizations.
-*/
-// *****************************************************************************
-#ifndef DGMultiMat_h
-#define DGMultiMat_h
-
-#include <cmath>
-#include <algorithm>
-#include <unordered_set>
-#include <map>
-#include <array>
-
-#include "Macro.hpp"
-#include "Exception.hpp"
-#include "Vector.hpp"
-#include "ContainerUtil.hpp"
-#include "UnsMesh.hpp"
-#include "Inciter/InputDeck/InputDeck.hpp"
-#include "Integrate/Basis.hpp"
-#include "Integrate/Quadrature.hpp"
-#include "Integrate/Initialize.hpp"
-#include "Integrate/Mass.hpp"
-#include "Integrate/Surface.hpp"
-#include "Integrate/Boundary.hpp"
-#include "Integrate/Volume.hpp"
-#include "Integrate/MultiMatTerms.hpp"
-#include "Integrate/Source.hpp"
-#include "Integrate/SolidTerms.hpp"
-#include "RiemannChoice.hpp"
-#include "MultiMat/MultiMatIndexing.hpp"
-#include "Reconstruction.hpp"
-#include "Limiter.hpp"
-#include "Problem/FieldOutput.hpp"
-#include "Problem/BoxInitialization.hpp"
-#include "PrefIndicator.hpp"
-#include "MultiMat/BCFunctions.hpp"
-#include "MultiMat/MiscMultiMatFns.hpp"
-#include "EoS/GetMatProp.hpp"
-
-namespace inciter {
-
-extern ctr::InputDeck g_inputdeck;
-
-namespace dg {
-
-//! \brief MultiMat used polymorphically with tk::DGPDE
-//! \details The template arguments specify policies and are used to configure
-//!   the behavior of the class. The policies are:
-//!   - Physics - physics configuration, see PDE/MultiMat/Physics.h
-//!   - Problem - problem configuration, see PDE/MultiMat/Problem.h
-//! \note The default physics is Euler, set in inciter::deck::check_multimat()
-template< class Physics, class Problem >
-class MultiMat {
-
-  private:
-    using eq = tag::multimat;
-
-  public:
-    //! Constructor
-    explicit MultiMat() :
-      m_ncomp( g_inputdeck.get< tag::ncomp >() ),
-      m_nprim(nprim()),
-      m_riemann( multimatRiemannSolver(
-        g_inputdeck.get< tag::flux >() ) )
-    {
-      // associate boundary condition configurations with state functions
-      brigand::for_each< ctr::bclist::Keys >( ConfigBC( m_bc,
-        { dirichlet
-        , symmetry
-        , invalidBC         // Inlet BC not implemented
-        , invalidBC         // Outlet BC not implemented
-        , farfieldOutlet
-        , extrapolate } ) );
-
-      // EoS initialization
-      initializeMaterialEoS( m_mat_blk );
-    }
-
-    //! Find the number of primitive quantities required for this PDE system
-    //! \return The number of primitive quantities required to be stored for
-    //!   this PDE system
-    std::size_t nprim() const<--- Shadowed declaration
-    {
-      auto nmat = g_inputdeck.get< tag::multimat, tag::nmat >();<--- Shadow variable
-      const auto& solidx = inciter::g_inputdeck.get<
-        tag::matidxmap, tag::solidx >();
-
-      // individual material pressures and three velocity components
-      std::size_t np(nmat+3);
-
-      for (std::size_t k=0; k<nmat; ++k) {
-        if (solidx[k] > 0) {
-          // individual material Cauchy stress tensor components
-          np += 6;
-        }
-      }
-
-      return np;
-    }
-
-    //! Find the number of materials set up for this PDE system
-    //! \return The number of materials set up for this PDE system
-    std::size_t nmat() const<--- Shadowed declaration<--- Shadowed declaration<--- Shadowed declaration<--- Shadowed declaration<--- Shadowed declaration<--- Shadowed declaration<--- Shadowed declaration<--- Shadowed declaration<--- Shadowed declaration<--- Shadowed declaration<--- Shadowed declaration<--- Shadowed declaration<--- Shadowed declaration<--- Shadowed declaration<--- Shadowed declaration<--- Shadowed declaration<--- Shadowed declaration<--- Shadowed declaration<--- Shadowed declaration<--- Shadowed declaration<--- Shadowed declaration<--- Shadowed declaration<--- Shadowed declaration<--- Shadowed declaration
-    {
-      auto nmat = g_inputdeck.get< tag::multimat, tag::nmat >();
-      return nmat;
-    }
-
-    //! Assign number of DOFs per equation in the PDE system
-    //! \param[in,out] numEqDof Array storing number of Dofs for each PDE
-    //!   equation
-    void numEquationDofs(std::vector< std::size_t >& numEqDof) const
-    {
-      // all equation-dofs initialized to ndofs first
-      for (std::size_t i=0; i<m_ncomp; ++i) {
-        numEqDof.push_back(g_inputdeck.get< tag::ndof >());
-      }
-
-      // volume fractions are P0Pm (ndof = 1) for multi-material simulations
-      auto nmat = g_inputdeck.get< tag::multimat, tag::nmat >();<--- Shadow variable
-      if(nmat > 1)
-        for (std::size_t k=0; k<nmat; ++k)
-          numEqDof[volfracIdx(nmat, k)] = 1;
-    }
-
-    //! Determine elements that lie inside the user-defined IC box
-    //! \param[in] geoElem Element geometry array
-    //! \param[in] nielem Number of internal elements
-    //! \param[in,out] inbox List of nodes at which box user ICs are set for
-    //!    each IC box
-    void IcBoxElems( const tk::Fields& geoElem,
-      std::size_t nielem,
-      std::vector< std::unordered_set< std::size_t > >& inbox ) const
-    {
-      tk::BoxElems< eq >(geoElem, nielem, inbox);
-    }
-
-    //! Find how many 'stiff equations', which are the inverse
-    //! deformation equations because of plasticity
-    //! \return number of stiff equations
-    std::size_t nstiffeq() const
-    {
-      const auto& solidx = g_inputdeck.get< tag::matidxmap, tag::solidx >();
-      std::size_t nmat = g_inputdeck.get< tag::multimat, tag::nmat >();<--- Shadow variable
-      return 9*numSolids(nmat, solidx);
-    }
-
-    //! Find how many 'non-stiff equations', which are the inverse
-    //! deformation equations because of plasticity
-    //! \return number of stiff equations
-    std::size_t nnonstiffeq() const
-    {
-      return m_ncomp-nstiffeq();
-    }
-
-    //! Locate the stiff equations.
-    //! \param[out] stiffEqIdx list with pointers to stiff equations
-    void setStiffEqIdx( std::vector< std::size_t >& stiffEqIdx ) const
-    {
-      stiffEqIdx.resize(nstiffeq(), 0);
-      const auto& solidx = g_inputdeck.get< tag::matidxmap, tag::solidx >();
-      std::size_t nmat = g_inputdeck.get< tag::multimat, tag::nmat >();<--- Shadow variable
-      std::size_t icnt = 0;
-      for (std::size_t k=0; k<nmat; ++k)
-        if (solidx[k] > 0)
-          for (std::size_t i=0; i<3; ++i)
-            for (std::size_t j=0; j<3; ++j)
-            {
-              stiffEqIdx[icnt] =
-                inciter::deformIdx(nmat, solidx[k], i, j);
-              icnt++;
-            }
-    }
-
-    //! Locate the nonstiff equations.
-    //! \param[out] nonStiffEqIdx list with pointers to nonstiff equations
-    void setNonStiffEqIdx( std::vector< std::size_t >& nonStiffEqIdx ) const
-    {
-      nonStiffEqIdx.resize(nnonstiffeq(), 0);
-      for (std::size_t icomp=0; icomp<nnonstiffeq(); icomp++)
-        nonStiffEqIdx[icomp] = icomp;
-    }
-
-    //! Initialize the compressible flow equations, prepare for time integration
-    //! \param[in] L Block diagonal mass matrix
-    //! \param[in] inpoel Element-node connectivity
-    //! \param[in] coord Array of nodal coordinates
-    //! \param[in] inbox List of elements at which box user ICs are set for
-    //!   each IC box
-    //! \param[in] elemblkid Element ids associated with mesh block ids where
-    //!   user ICs are set
-    //! \param[in,out] unk Array of unknowns
-    //! \param[in] t Physical time
-    //! \param[in] nielem Number of internal elements
-    void initialize( const tk::Fields& L,
-      const std::vector< std::size_t >& inpoel,
-      const tk::UnsMesh::Coords& coord,
-      const std::vector< std::unordered_set< std::size_t > >& inbox,
-      const std::unordered_map< std::size_t, std::set< std::size_t > >&
-        elemblkid,
-      tk::Fields& unk,
-      tk::real t,
-      const std::size_t nielem ) const
-    {
-      tk::initialize( m_ncomp, m_mat_blk, L, inpoel, coord,
-                      Problem::initialize, unk, t, nielem );
-
-      const auto rdof = g_inputdeck.get< tag::rdof >();
-      const auto& ic = g_inputdeck.get< tag::ic >();
-      const auto& icbox = ic.get< tag::box >();
-      const auto& icmbk = ic.get< tag::meshblock >();
-
-      const auto& bgpre = ic.get< tag::pressure >();
-      const auto& bgtemp = ic.get< tag::temperature >();
+  \brief     Mesh refiner for interfacing the mesh refinement library
+  \see       Refiner.h for more info.
+*/
+// *****************************************************************************
+
+#include <vector>
+#include <algorithm>
+
+#include "Refiner.hpp"
+#include "Reorder.hpp"
+#include "AMR/mesh_adapter.hpp"
+#include "AMR/Error.hpp"
+#include "Inciter/InputDeck/InputDeck.hpp"
+#include "CGPDE.hpp"
+#include "DGPDE.hpp"
+#include "FVPDE.hpp"
+#include "DerivedData.hpp"
+#include "UnsMesh.hpp"
+#include "Centering.hpp"
+#include "Around.hpp"
+#include "Sorter.hpp"
+#include "Discretization.hpp"
+
+namespace inciter {
+
+extern ctr::InputDeck g_inputdeck;
+extern ctr::InputDeck g_inputdeck_defaults;
+extern std::vector< CGPDE > g_cgpde;
+extern std::vector< DGPDE > g_dgpde;
+extern std::vector< FVPDE > g_fvpde;
+
+} // inciter::
+
+using inciter::Refiner;
+
+Refiner::Refiner( std::size_t meshid,
+                  const CProxy_Transporter& transporter,
+                  const CProxy_Sorter& sorter,
+                  const tk::CProxy_MeshWriter& meshwriter,
+                  const std::vector< Scheme >& scheme,
+                  const tk::RefinerCallback& cbr,
+                  const tk::SorterCallback& cbs,
+                  const std::vector< std::size_t >& ginpoel,
+                  const tk::UnsMesh::CoordMap& coordmap,
+                  const std::map< int, std::vector< std::size_t > >& bface,
+                  const std::vector< std::size_t >& triinpoel,
+                  const std::map< int, std::vector< std::size_t > >& bnode,
+                  const std::vector< std::size_t >& elemblid,
+                  int nchare ) :
+  m_meshid( meshid ),
+  m_ncit(0),
+  m_host( transporter ),
+  m_sorter( sorter ),
+  m_meshwriter( meshwriter ),
+  m_scheme( scheme ),
+  m_cbr( cbr ),
+  m_cbs( cbs ),
+  m_ginpoel( ginpoel ),
+  m_el( tk::global2local( ginpoel ) ),     // fills m_inpoel, m_gid, m_lid
+  m_coordmap( coordmap ),
+  m_coord( flatcoord(coordmap) ),
+  m_bface( bface ),
+  m_bnode( bnode ),
+  m_triinpoel( triinpoel ),
+  m_elemblockid(),
+  m_nchare( nchare ),
+  m_mode( RefMode::T0REF ),
+  m_initref( g_inputdeck.get< tag::amr, tag::initial >() ),
+  m_ninitref( g_inputdeck.get< tag::amr, tag::initial >().size() ),
+  m_refiner( g_inputdeck.get< tag::amr, tag::maxlevels >(), m_inpoel ),
+  m_nref( 0 ),
+  m_nbnd( 0 ),
+  m_extra( 0 ),
+  m_ch(),
+  m_edgech(),
+  m_chedge(),
+  m_localEdgeData(),
+  m_remoteEdgeData(),
+  m_nodeCommMap(),
+  m_oldTets(),
+  m_addedNodes(),
+  m_addedTets(),
+  m_removedNodes(),
+  m_amrNodeMap(),
+  m_oldntets( 0 ),
+  m_coarseBndFaces(),
+  m_coarseBndNodes(),
+  m_coarseBlkElems(),
+  m_rid( m_coord[0].size() ),
+//  m_oldrid(),
+  m_lref( m_rid.size() ),
+//  m_oldparent(),
+  m_writeCallback(),
+  m_outref_ginpoel(),
+  m_outref_el(),
+  m_outref_coord(),
+  m_outref_addedNodes(),
+  m_outref_addedTets(),
+  m_outref_nodeCommMap(),
+  m_outref_bface(),
+  m_outref_bnode(),
+  m_outref_triinpoel()
+// *****************************************************************************
+//  Constructor
+//! \param[in] meshid Mesh ID
+//! \param[in] transporter Transporter (host) proxy
+//! \param[in] sorter Mesh reordering (sorter) proxy
+//! \param[in] meshwriter Mesh writer proxy
+//! \param[in] scheme Discretization schemes (one per mesh)
+//! \param[in] cbr Charm++ callbacks for Refiner
+//! \param[in] cbs Charm++ callbacks for Sorter
+//! \param[in] ginpoel Mesh connectivity (this chare) using global node IDs
+//! \param[in] coordmap Mesh node coordinates (this chare) for global node IDs
+//! \param[in] bface File-internal elem ids of side sets
+//! \param[in] triinpoel Triangle face connectivity with global IDs
+//! \param[in] bnode Node lists of side sets
+//! \param[in] elemblid Mesh block ids associated to local tet ids
+//! \param[in] nchare Total number of refiner chares (chare array elements)
+// *****************************************************************************
+{
+  Assert( !m_ginpoel.empty(), "No elements assigned to refiner chare" );
+  Assert( tk::positiveJacobians( m_inpoel, m_coord ),
+          "Input mesh to Refiner Jacobian non-positive" );
+  Assert( !tk::leakyPartition(
+            tk::genEsuelTet( m_inpoel, tk::genEsup(m_inpoel,4) ),
+            m_inpoel, m_coord ),
+          "Input mesh to Refiner leaky" );
+
+  // Construct data structure assigning sets of element ids to mesh blocks
+  for (std::size_t ie=0; ie<elemblid.size(); ++ie) {
+    m_elemblockid[elemblid[ie]].insert(ie);
+  }
+
+  #if not defined(__INTEL_COMPILER) || defined(NDEBUG)
+  // The above ifdef skips running the conformity test with the intel compiler
+  // in debug mode only. This is necessary because in tk::conforming(), filling
+  // up the map can fail with some meshes (only in parallel), e.g., tube.exo,
+  // used by some regression tests, due to the intel compiler generating some
+  // garbage incorrect code - only in debug, only in parallel, only with that
+  // mesh.
+  Assert( tk::conforming( m_inpoel, m_coord, true, m_rid ),
+          "Input mesh to Refiner not conforming" );
+  #endif
+
+  // Generate local -> refiner lib node id map and its inverse
+  libmap();
+
+  // Reverse initial mesh refinement type list (will pop from back)
+  std::reverse( begin(m_initref), end(m_initref) );
+
+  // Generate boundary data structures for coarse mesh
+  coarseMesh();
+
+  // If initial mesh refinement is configured, start initial mesh refinement.
+  // See also tk::grm::check_amr_errors in Control/Inciter/InputDeck/Ggrammar.h.
+  if (g_inputdeck.get< tag::amr, tag::t0ref >() && m_ninitref > 0)
+    t0ref();
+  else
+    endt0ref();
+}
+
+void
+Refiner::libmap()
+// *****************************************************************************
+// (Re-)generate local -> refiner lib node id map and its inverse
+// *****************************************************************************
+{
+  // Fill initial (matching) mapping between local and refiner node ids
+  std::iota( begin(m_rid), end(m_rid), 0 );
+
+  // Fill in inverse, mapping refiner to local node ids
+  std::size_t i = 0;
+  for (auto r : m_rid) m_lref[r] = i++;
+}
+
+void
+Refiner::coarseMesh()
+// *****************************************************************************
+// (Re-)generate side set and block data structures for coarse mesh
+// *****************************************************************************
+{
+  // Generate unique set of faces for each side set of the input (coarsest) mesh
+  m_coarseBndFaces.clear();
+  for (const auto& [ setid, faceids ] : m_bface) {
+    auto& faces = m_coarseBndFaces[ setid ];
+    for (auto f : faceids) {
+      faces.insert(
+        {{{ m_triinpoel[f*3+0], m_triinpoel[f*3+1], m_triinpoel[f*3+2] }}} );
+    }
+  }
+
+  // Generate unique set of nodes for each side set of the input (coarsest) mesh
+  m_coarseBndNodes.clear();
+  for (const auto& [ setid, nodes ] : m_bnode) {
+    m_coarseBndNodes[ setid ].insert( begin(nodes), end(nodes) );
+  }
+
+  // Generate set of elements for each mesh block of the input (coarsest) mesh
+  m_coarseBlkElems.clear();
+  for (const auto& [blid, elids] : m_elemblockid) {
+    for (auto ie : elids) {
+      m_coarseBlkElems[blid].insert( {{{m_inpoel[ie*4+0], m_inpoel[ie*4+1],
+        m_inpoel[ie*4+2], m_inpoel[ie*4+3]}}} );
+    }
+  }
+}
+
+void
+Refiner::sendProxy()
+// *****************************************************************************
+// Send Refiner proxy to Discretization objects
+//! \details This should be called when bound Discretization chare array
+//!   elements have already been created.
+// *****************************************************************************
+{
+  // Make sure (bound) Discretization chare is already created and accessible
+  Assert( m_scheme[m_meshid].disc()[thisIndex].ckLocal() != nullptr,
+          "About to dereference nullptr" );
 
-      // Set initial conditions inside user-defined IC boxes and mesh blocks
-      std::vector< tk::real > s(m_ncomp, 0.0);
-      for (std::size_t e=0; e<nielem; ++e) {
-        // inside user-defined box
-        if (!icbox.empty()) {
-          std::size_t bcnt = 0;
-          for (const auto& b : icbox) {   // for all boxes
-            if (inbox.size() > bcnt && inbox[bcnt].find(e) != inbox[bcnt].end())
-            {
-              std::vector< tk::real > box
-                { b.template get< tag::xmin >(), b.template get< tag::xmax >(),
-                  b.template get< tag::ymin >(), b.template get< tag::ymax >(),
-                  b.template get< tag::zmin >(), b.template get< tag::zmax >() };
-              auto V_ex = (box[1]-box[0]) * (box[3]-box[2]) * (box[5]-box[4]);
-              for (std::size_t c=0; c<m_ncomp; ++c) {
-                auto mark = c*rdof;
-                s[c] = unk(e,mark);
-                // set high-order DOFs to zero
-                for (std::size_t i=1; i<rdof; ++i)
-                  unk(e,mark+i) = 0.0;
-              }
-              initializeBox<ctr::boxList>( m_mat_blk, V_ex, t, b, bgpre,
-                bgtemp, s );
-              // store box-initialization in solution vector
-              for (std::size_t c=0; c<m_ncomp; ++c) {
-                auto mark = c*rdof;
-                unk(e,mark) = s[c];
-              }
-            }
-            ++bcnt;
-          }
-        }
-
-        // inside user-specified mesh blocks
-        if (!icmbk.empty()) {
-          for (const auto& b : icmbk) { // for all blocks
-            auto blid = b.get< tag::blockid >();
-            auto V_ex = b.get< tag::volume >();
-            if (elemblkid.find(blid) != elemblkid.end()) {
-              const auto& elset = tk::cref_find(elemblkid, blid);
-              if (elset.find(e) != elset.end()) {
-                initializeBox<ctr::meshblockList>( m_mat_blk, V_ex, t, b,
-                  bgpre, bgtemp, s );
-                // store initialization in solution vector
-                for (std::size_t c=0; c<m_ncomp; ++c) {
-                  auto mark = c*rdof;
-                  unk(e,mark) = s[c];
-                }
-              }
-            }
-          }
-        }
-      }
-    }
+  // Pass Refiner Charm++ chare proxy to fellow (bound) Discretization object
+  m_scheme[m_meshid].disc()[thisIndex].ckLocal()->setRefiner( thisProxy );
+}
+
+void
+Refiner::reorder()
+// *****************************************************************************
+// Query Sorter and update local mesh with the reordered one
+// *****************************************************************************
+{
+  m_sorter[thisIndex].ckLocal()->
+    mesh( m_ginpoel, m_coordmap, m_triinpoel, m_bnode );
+
+  // Update local mesh data based on data just received from Sorter
+  m_el = tk::global2local( m_ginpoel );     // fills m_inpoel, m_gid, m_lid
+  m_coord = flatcoord( m_coordmap );
+
+  // Re-generate boundary data structures for coarse mesh
+  coarseMesh();
+
+  // WARNING: This re-creates the AMR lib which is probably not what we
+  // ultimately want, beacuse this deletes its history recorded during initial
+  // (t<0) refinement. However, this appears to correctly update the local mesh
+  // based on the reordered one (from Sorter) at least when t0ref is off.
+  m_refiner = AMR::mesh_adapter_t(
+    g_inputdeck.get< tag::amr, tag::maxlevels >(), m_inpoel );
+}
+
+tk::UnsMesh::Coords
+Refiner::flatcoord( const tk::UnsMesh::CoordMap& coordmap )
+// *****************************************************************************
+// Generate flat coordinate data from coordinate map
+//! \param[in] coordmap Coordinates associated to global node IDs of mesh chunk
+//! \return Flat coordinate data
+// *****************************************************************************
+{
+  tk::UnsMesh::Coords coord;
+
+  // Convert node coordinates associated to global node IDs to a flat vector
+  auto npoin = coordmap.size();
+  Assert( m_gid.size() == npoin, "Size mismatch" );
+  coord[0].resize( npoin );
+  coord[1].resize( npoin );
+  coord[2].resize( npoin );
+  for (const auto& [ gid, coords ] : coordmap) {
+    auto i = tk::cref_find( m_lid, gid );
+    Assert( i < npoin, "Indexing out of coordinate map" );
+    coord[0][i] = coords[0];
+    coord[1][i] = coords[1];
+    coord[2][i] = coords[2];
+  }
+
+  return coord;
+}
 
-    //! Save initial densities for all materials
-    //! \param[out] rho0mat List of initial densities
-    void setRho0mat( std::vector< tk::real >& rho0mat ) const
-    {
-      std::size_t nmat = g_inputdeck.get< tag::multimat, tag::nmat >();<--- Shadow variable
-      rho0mat.resize( nmat, 0.0 );
-      const auto& ic = g_inputdeck.get< tag::ic >();
-      const auto& icbox = ic.get< tag::box >();
-      const auto& icmbk = ic.get< tag::meshblock >();
-      // Get background properties
-      std::size_t k = ic.get< tag::materialid >() - 1;
-      tk::real pr = ic.get< tag::pressure >();
-      tk::real tmp = ic.get< tag::temperature >();
-      rho0mat[k] = m_mat_blk[k].compute< EOS::density >(pr, tmp);
-
-      // Check inside used defined box
-      if (!icbox.empty())
-      {
-        for (const auto& b : icbox) {   // for all boxes
-          k = b.template get< tag::materialid >() - 1;
-          pr = b.template get< tag::pressure >();
-          tmp = b.template get< tag::temperature >();
-          rho0mat[k] = m_mat_blk[k].compute< EOS::density >(pr, tmp);
-        }
-      }
-
-      // Check inside user-specified mesh blocks
-      if (!icmbk.empty())
-      {
-        for (const auto& b : icmbk) { // for all blocks
-          k = b.template get< tag::materialid >() - 1;
-          pr = b.template get< tag::pressure >();
-          tmp = b.template get< tag::temperature >();
-          rho0mat[k] = m_mat_blk[k].compute< EOS::density >(pr, tmp);
-        }
-      }
-    }
+void
+Refiner::dtref( const std::map< int, std::vector< std::size_t > >& bface,
+                const std::map< int, std::vector< std::size_t > >& bnode,
+                const std::vector< std::size_t >& triinpoel )
+// *****************************************************************************
+// Start mesh refinement (during time stepping, t>0)
+//! \param[in] bface Boundary-faces mapped to side set ids
+//! \param[in] bnode Boundary-node lists mapped to side set ids
+//! \param[in] triinpoel Boundary-face connectivity
+// *****************************************************************************
+{
+  m_mode = RefMode::DTREF;
+
+  // Update boundary node lists
+  m_bface = bface;
+  m_bnode = bnode;
+  m_triinpoel = tk::remap(triinpoel, m_gid);
+
+  start();
+}
+
+void
+Refiner::outref( const std::map< int, std::vector< std::size_t > >& bface,
+                 const std::map< int, std::vector< std::size_t > >& bnode,
+                 const std::vector< std::size_t >& triinpoel,
+                 CkCallback c,
+                 RefMode mode )
+// *****************************************************************************
+// Start mesh refinement (for field output)
+//! \param[in] bface Boundary-faces mapped to side set ids
+//! \param[in] bnode Boundary-node lists mapped to side set ids
+//! \param[in] triinpoel Boundary-face connectivity
+//! \param[in] c Function to continue with after the writing field output
+//! \param[in] mode Refinement mode
+// *****************************************************************************
+{
+  m_mode = mode;
 
-    //! Compute density constraint for a given material
-    //! \param[in] nelem Number of elements
-    //! \param[in] unk Array of unknowns
-    //! \param[in] rho0mat List of initial densities
-    //! \param[out] densityConstr Density Constraint: rho/(rho0*det(g))
-    void computeDensityConstr( std::size_t nelem,
-                               tk::Fields& unk,<--- Parameter 'unk' can be declared with const
-                               std::vector< tk::real >& rho0mat,<--- Parameter 'rho0mat' can be declared with const
-                               std::vector< tk::real >& densityConstr) const
-    {
-      const auto& solidx = g_inputdeck.get< tag::matidxmap, tag::solidx >();
-      std::size_t rdof = g_inputdeck.get< tag::rdof >();
-      std::size_t nmat = g_inputdeck.get< tag::multimat, tag::nmat >();<--- Shadow variable
-      for (std::size_t e=0; e<nelem; ++e)
-        densityConstr[e] = 0.0;
-      for (std::size_t imat=0; imat<nmat; ++imat)
-        if (solidx[imat] > 0)
-        {
-          for (std::size_t e=0; e<nelem; ++e)
-          {
-            // Retrieve unknowns
-            tk::real arho = unk(e, densityDofIdx(nmat, imat, rdof, 0));
-            std::array< std::array< tk::real, 3 >, 3 > g;
-            for (std::size_t i=0; i<3; ++i)
-              for (std::size_t j=0; j<3; ++j)
-                g[i][j] = unk(e, deformDofIdx(nmat, solidx[imat], i, j, rdof, 0));
-            // Compute determinant of g
-            tk::real detg = tk::determinant(g);
-            // Compute constraint measure
-            densityConstr[e] += arho/(rho0mat[imat]*detg);
-          }
-        }
-        else
-        {
-          for (std::size_t e=0; e<nelem; ++e)
-          {
-            // Retrieve alpha and add it to the constraint measure
-            tk::real alpha = unk(e, volfracDofIdx(nmat, imat, rdof, 0));
-            densityConstr[e] += alpha;
-          }
-        }
-    }
-
-    //! Compute the left hand side block-diagonal mass matrix
-    //! \param[in] geoElem Element geometry array
-    //! \param[in,out] l Block diagonal mass matrix
-    void lhs( const tk::Fields& geoElem, tk::Fields& l ) const {
-      const auto ndof = g_inputdeck.get< tag::ndof >();
-      // Unlike Compflow and Transport, there is a weak reconstruction about
-      // conservative variable after limiting function which will require the
-      // size of left hand side vector to be rdof
-      tk::mass( m_ncomp, ndof, geoElem, l );
-    }
-
-    //! Update the interface cells to first order dofs
-    //! \param[in] unk Array of unknowns
-    //! \param[in] nielem Number of internal elements
-//    //! \param[in,out] ndofel Array of dofs
-    //! \details This function resets the high-order terms in interface cells.
-    void updateInterfaceCells( tk::Fields& unk,<--- Parameter 'unk' can be declared with const
-      std::size_t nielem,
-      std::vector< std::size_t >& /*ndofel*/ ) const
-    {
-      auto intsharp =
-        g_inputdeck.get< tag::multimat, tag::intsharp >();
-      // If this cell is not material interface, return this function
-      if(not intsharp)  return;
-
-      auto rdof = g_inputdeck.get< tag::rdof >();
-      auto nmat = g_inputdeck.get< tag::multimat, tag::nmat >();<--- Shadow variable
-      const auto& solidx = g_inputdeck.get<
-        tag::matidxmap, tag::solidx >();
-
-      for (std::size_t e=0; e<nielem; ++e) {
-        std::vector< std::size_t > matInt(nmat, 0);
-        std::vector< tk::real > alAvg(nmat, 0.0);
-        for (std::size_t k=0; k<nmat; ++k)
-          alAvg[k] = unk(e, volfracDofIdx(nmat,k,rdof,0));
-        auto intInd = interfaceIndicator(nmat, alAvg, matInt);
-
-        // interface cells cannot be high-order
-        if (intInd) {
-          //ndofel[e] = 1;
-          for (std::size_t k=0; k<nmat; ++k) {
-            if (matInt[k]) {
-              for (std::size_t i=1; i<rdof; ++i) {
-                unk(e, densityDofIdx(nmat,k,rdof,i)) = 0.0;
-                unk(e, energyDofIdx(nmat,k,rdof,i)) = 0.0;
-              }
-              if (solidx[k] > 0) {
-                for (std::size_t i=0; i<3; ++i)
-                  for (std::size_t j=0; j<3; ++j)
-                    for (std::size_t idof=1; idof<rdof; ++idof) {
-                      unk(e, deformDofIdx(nmat,solidx[k],i,j,rdof,idof)) = 0.0;
-                    }
-              }
-            }
-          }
-          for (std::size_t idir=0; idir<3; ++idir) {
-            for (std::size_t i=1; i<rdof; ++i) {
-              unk(e, momentumDofIdx(nmat,idir,rdof,i)) = 0.0;
-            }
-          }
-        }
-      }
-    }
-
-    //! Update the primitives for this PDE system
-    //! \param[in] unk Array of unknowns
-    //! \param[in] L The left hand side block-diagonal mass matrix
-    //! \param[in] geoElem Element geometry array
-    //! \param[in,out] prim Array of primitives
-    //! \param[in] nielem Number of internal elements
-    //! \details This function computes and stores the dofs for primitive
-    //!   quantities, which are required for obtaining reconstructed states used
-    //!   in the Riemann solver. See /PDE/Riemann/AUSM.hpp, where the
-    //!   normal velocity for advection is calculated from independently
-    //!   reconstructed velocities.
-    void updatePrimitives( const tk::Fields& unk,
-                           const tk::Fields& L,
-                           const tk::Fields& geoElem,
-                           tk::Fields& prim,<--- Parameter 'prim' can be declared with const
-                           std::size_t nielem ) const
-    {
-      const auto rdof = g_inputdeck.get< tag::rdof >();<--- Variable 'rdof' is assigned a value that is never used.
-      const auto ndof = g_inputdeck.get< tag::ndof >();<--- Variable 'ndof' is assigned a value that is never used.
-      auto nmat = g_inputdeck.get< tag::multimat, tag::nmat >();<--- Shadow variable<--- Variable 'nmat' is assigned a value that is never used.
-      const auto& solidx = g_inputdeck.get< tag::matidxmap, tag::solidx >();
-
-      Assert( unk.nunk() == prim.nunk(), "Number of unknowns in solution "
-              "vector and primitive vector at recent time step incorrect" );
-      Assert( unk.nprop() == rdof*m_ncomp, "Number of components in solution "
-              "vector must equal "+ std::to_string(rdof*m_ncomp) );
-      Assert( prim.nprop() == rdof*m_nprim, "Number of components in vector of "
-              "primitive quantities must equal "+ std::to_string(rdof*m_nprim) );
-
-      for (std::size_t e=0; e<nielem; ++e)
-      {
-        std::vector< tk::real > R(m_nprim*ndof, 0.0);
-
-        auto ng = tk::NGvol(ndof);
+  m_writeCallback = c;
+
+  // Update boundary node lists
+  m_bface = bface;
+  m_bnode = bnode;
+  m_triinpoel = triinpoel;
+
+  start();
+}
+
+void
+Refiner::t0ref()
+// *****************************************************************************
+// Output mesh to file before a new step mesh refinement
+// *****************************************************************************
+{
+  Assert( m_ninitref > 0, "No initial mesh refinement steps configured" );
+  // Output initial mesh to file
+  auto l = m_ninitref - m_initref.size();  // num initref steps completed
+  auto t0 = g_inputdeck.get< tag::t0 >();
+  if (l == 0) {
+    writeMesh( "t0ref", l, t0-1.0,
+      CkCallback( CkIndex_Refiner::start(), thisProxy[thisIndex] ) );
+  } else {
+    start();
+  }
+}
+
+void
+Refiner::start()
+// *****************************************************************************
+//  Start new step of mesh refinement
+// *****************************************************************************
+{
+  m_extra = 0;
+  m_ch.clear();
+  m_remoteEdgeData.clear();
+  m_remoteEdges.clear();
+
+  updateEdgeData();
+
+  // Generate and communicate boundary edges
+  bndEdges();
+}
+
+void
+Refiner::bndEdges()
+// *****************************************************************************
+// Generate boundary edges and send them to all chares
+//! \details Extract edges on the boundary only. The boundary edges (shared by
+//!   multiple chares) will be agreed on a refinement that yields a conforming
+//!   mesh across chares boundaries.
+// *****************************************************************************
+{
+  // Compute the number of edges (chunksize) a chare will respond to when
+  // computing shared edges
+  auto N = static_cast< std::size_t >( m_nchare );
+  std::size_t chunksize = std::numeric_limits< std::size_t >::max() / N;<--- Variable 'chunksize' is assigned a value that is never used.
+
+  // Generate boundary edges of our mesh chunk
+  std::unordered_map< int, EdgeSet > chbedges;
+  auto esup = tk::genEsup( m_inpoel, 4 );         // elements surrounding points
+  auto esuel = tk::genEsuelTet( m_inpoel, esup ); // elems surrounding elements
+  for (std::size_t e=0; e<esuel.size()/4; ++e) {
+    auto mark = e*4;
+    for (std::size_t f=0; f<4; ++f) {
+      if (esuel[mark+f] == -1) {
+        auto A = m_ginpoel[ mark+tk::lpofa[f][0] ];
+        auto B = m_ginpoel[ mark+tk::lpofa[f][1] ];<--- Variable 'B' is assigned a value that is never used.
+        auto C = m_ginpoel[ mark+tk::lpofa[f][2] ];<--- Variable 'C' is assigned a value that is never used.
+        Assert( m_lid.find( A ) != end(m_lid), "Local node ID not found" );
+        Assert( m_lid.find( B ) != end(m_lid), "Local node ID not found" );
+        Assert( m_lid.find( C ) != end(m_lid), "Local node ID not found" );
+        // assign edges to bins a single chare will respond to when computing
+        // shared edges
+        auto bin = A / chunksize;
+        Assert( bin < N, "Will index out of number of chares" );
+        chbedges[ static_cast<int>(bin) ].insert( {A,B} );
+        bin = B / chunksize;
+        Assert( bin < N, "Will index out of number of chares" );
+        chbedges[ static_cast<int>(bin) ].insert( {B,C} );
+        bin = C / chunksize;
+        Assert( bin < N, "Will index out of number of chares" );
+        chbedges[ static_cast<int>(bin) ].insert( {C,A} );
+      }
+    }
+  }
+
+  // Send edges in bins to chares that will compute shared edges
+  m_nbnd = chbedges.size();
+  if (m_nbnd == 0)
+    contribute( sizeof(std::size_t), &m_meshid, CkReduction::nop,
+                m_cbr.get< tag::queried >() );
+  else
+    for (const auto& [ targetchare, bndedges ] : chbedges)
+      thisProxy[ targetchare ].query( thisIndex, bndedges );
+}
+
+void
+Refiner::query( int fromch, const EdgeSet& edges )
+// *****************************************************************************
+// Incoming query for a list boundary edges for which this chare compiles
+// shared edges
+//! \param[in] fromch Sender chare ID
+//! \param[in] edges Chare-boundary edge list from another chare
+// *****************************************************************************
+{
+  // Store incoming edges in edge->chare and its inverse, chare->edge, maps
+  for (const auto& e : edges) m_edgech[ e ].push_back( fromch );
+  m_chedge[ fromch ].insert( begin(edges), end(edges) );
+  // Report back to chare message received from
+  thisProxy[ fromch ].recvquery();
+}
+
+void
+Refiner::recvquery()
+// *****************************************************************************
+// Receive receipt of boundary edge lists to query
+// *****************************************************************************
+{
+  if (--m_nbnd == 0)
+    contribute( sizeof(std::size_t), &m_meshid, CkReduction::nop,
+                m_cbr.get< tag::queried >() );
+}
+
+void
+Refiner::response()
+// *****************************************************************************
+//  Respond to boundary edge list queries
+// *****************************************************************************
+{
+  std::unordered_map< int, std::vector< int > > exp;
+
+  // Compute shared edges whose chare ids will be sent back to querying chares
+  for (const auto& [ neighborchare, bndedges ] : m_chedge) {
+    auto& e = exp[ neighborchare ];
+    for (const auto& ed : bndedges)
+      for (auto d : tk::cref_find(m_edgech,ed))
+        if (d != neighborchare)
+          e.push_back( d );<--- Consider using std::copy_if algorithm instead of a raw loop.
+  }
 
-        // arrays for quadrature points
-        std::array< std::vector< tk::real >, 3 > coordgp;
-        std::vector< tk::real > wgp;
-
-        coordgp[0].resize( ng );
-        coordgp[1].resize( ng );
-        coordgp[2].resize( ng );
-        wgp.resize( ng );
-
-        tk::GaussQuadratureTet( ng, coordgp, wgp );
-
-        // Loop over quadrature points in element e
-        for (std::size_t igp=0; igp<ng; ++igp)
-        {
-          // Compute the basis function
-          auto B =
-            tk::eval_basis( ndof, coordgp[0][igp], coordgp[1][igp], coordgp[2][igp] );
-
-          auto w = wgp[igp] * geoElem(e, 0);
-
-          auto state = tk::eval_state( m_ncomp, rdof, ndof, e, unk, B );
-
-          // bulk density at quadrature point
-          tk::real rhob(0.0);
-          for (std::size_t k=0; k<nmat; ++k)
-            rhob += state[densityIdx(nmat, k)];
-
-          // velocity vector at quadrature point
-          std::array< tk::real, 3 >
-            vel{ state[momentumIdx(nmat, 0)]/rhob,
-                 state[momentumIdx(nmat, 1)]/rhob,
-                 state[momentumIdx(nmat, 2)]/rhob };
-
-          std::vector< tk::real > pri(m_nprim, 0.0);
-
-          // Evaluate material pressure at quadrature point
-          for(std::size_t imat = 0; imat < nmat; imat++)
-          {
-            auto alphamat = state[volfracIdx(nmat, imat)];
-            auto arhomat = state[densityIdx(nmat, imat)];
-            auto arhoemat = state[energyIdx(nmat, imat)];
-            auto gmat = getDeformGrad(nmat, imat, state);
-            pri[pressureIdx(nmat,imat)] = m_mat_blk[imat].compute<
-              EOS::pressure >( arhomat, vel[0], vel[1], vel[2], arhoemat,
-              alphamat, imat, gmat );
-
-            pri[pressureIdx(nmat,imat)] = constrain_pressure( m_mat_blk,
-              pri[pressureIdx(nmat,imat)], arhomat, alphamat, imat);
-
-            if (solidx[imat] > 0) {
-              auto asigmat = m_mat_blk[imat].computeTensor< EOS::CauchyStress >(
-              arhomat, vel[0], vel[1], vel[2], arhoemat,
-              alphamat, imat, gmat );
-
-              pri[stressIdx(nmat,solidx[imat],0)] = asigmat[0][0];
-              pri[stressIdx(nmat,solidx[imat],1)] = asigmat[1][1];
-              pri[stressIdx(nmat,solidx[imat],2)] = asigmat[2][2];
-              pri[stressIdx(nmat,solidx[imat],3)] = asigmat[0][1];
-              pri[stressIdx(nmat,solidx[imat],4)] = asigmat[0][2];
-              pri[stressIdx(nmat,solidx[imat],5)] = asigmat[1][2];
-            }
-          }
-
-          // Evaluate bulk velocity at quadrature point
-          for (std::size_t idir=0; idir<3; ++idir) {
-            pri[velocityIdx(nmat,idir)] = vel[idir];
-          }
-
-          for(std::size_t k = 0; k < m_nprim; k++)
-          {
-            auto mark = k * ndof;
-            for(std::size_t idof = 0; idof < ndof; idof++)
-              R[mark+idof] += w * pri[k] * B[idof];
-          }
-        }
-
-        // Update the DG solution of primitive variables
-        for(std::size_t k = 0; k < m_nprim; k++)
-        {
-          auto mark = k * ndof;
-          auto rmark = k * rdof;
-          for(std::size_t idof = 0; idof < ndof; idof++)
-          {
-            prim(e, rmark+idof) = R[mark+idof] / L(e, mark+idof);
-            if(fabs(prim(e, rmark+idof)) < 1e-16)
-              prim(e, rmark+idof) = 0;
-          }
-        }
-      }
-    }
+  // Send chare ids of shared edges to chares that issued a query to us. Shared
+  // boundary edges assigned to chare ids sharing the boundary edge were
+  // computed above for those chares that queried this map from us. These
+  // boundary edges form a distributed table and we only work on a chunk of it.
+  // Note that we only send data back to those chares that have queried us. The
+  // receiving sides do not know in advance if they receive messages or not.
+  // Completion is detected by having the receiver respond back and counting
+  // the responses on the sender side, i.e., this chare.
+  m_nbnd = exp.size();
+  if (m_nbnd == 0)
+    contribute( sizeof(std::size_t), &m_meshid, CkReduction::nop,
+                m_cbr.get< tag::responded >() );
+  else
+    for (const auto& [ targetchare, bndedges ] : exp)
+      thisProxy[ targetchare ].bnd( thisIndex, bndedges );
+}
+
+void
+Refiner::bnd( int fromch, const std::vector< int >& chares )
+// *****************************************************************************
+// Receive shared boundary edges for our mesh chunk
+//! \param[in] fromch Sender chare ID
+//! \param[in] chares Chare ids we share edges with
+// *****************************************************************************
+{
+  // Store chare ids we share edges with
+  m_ch.insert( begin(chares), end(chares) );
+
+  // Report back to chare message received from
+  thisProxy[ fromch ].recvbnd();
+}
+
+void
+Refiner::recvbnd()
+// *****************************************************************************
+// Receive receipt of shared boundary edges
+// *****************************************************************************
+{
+  if (--m_nbnd == 0)
+    contribute( sizeof(std::size_t), &m_meshid, CkReduction::nop,
+                m_cbr.get< tag::responded >() );
+}
+
+void
+Refiner::refine()
+// *****************************************************************************
+//  Do a single step of mesh refinement (really, only tag edges)
+//! \details During initial (t<0, t0ref) mesh refinement, this is a single step
+//!   in a potentially multiple-entry list of initial adaptive mesh refinement
+//!   steps. Distribution of the chare-boundary edges must have preceded this
+//!   step, so that boundary edges (shared by multiple chares) can agree on a
+//!   refinement that yields a conforming mesh across chare boundaries.
+//!
+//!   During-timestepping (t>0, dtref) mesh refinement this is called once, as
+//!   we only do a single step during time stepping.
+//!
+//!   During field-output (outref) mesh refinement, this may be called multiple
+//!   times, depending the number of refinement levels needed for the field
+//!   output.
+// *****************************************************************************
+{
+  // Free memory used for computing shared boundary edges
+  tk::destroy( m_edgech );
+  tk::destroy( m_chedge );
+
+  // Perform leak test on old mesh
+  Assert( !tk::leakyPartition(
+            tk::genEsuelTet( m_inpoel, tk::genEsup(m_inpoel,4) ),
+            m_inpoel, m_coord ),
+          "Mesh partition before refinement leaky" );
+
+  if (m_mode == RefMode::T0REF) {
+
+    // Refine mesh based on next initial refinement type
+    if (!m_initref.empty()) {
+      auto r = m_initref.back();    // consume (reversed) list from its back
+      if (r == ctr::AMRInitialType::UNIFORM)
+        uniformRefine();
+      else if (r == ctr::AMRInitialType::UNIFORM_DEREFINE)
+        uniformDeRefine();
+      else if (r == ctr::AMRInitialType::INITIAL_CONDITIONS)
+        errorRefine();
+      else if (r == ctr::AMRInitialType::COORDINATES)
+        coordRefine();
+      else if (r == ctr::AMRInitialType::EDGELIST)
+        edgelistRefine();
+      else Throw( "Initial AMR type not implemented" );
+    }
+
+  } else if (m_mode == RefMode::DTREF) {
 
-    //! Clean up the state of trace materials for this PDE system
-    //! \param[in] t Physical time
-    //! \param[in] geoElem Element geometry array
-    //! \param[in,out] unk Array of unknowns
-    //! \param[in,out] prim Array of primitives
-    //! \param[in] nielem Number of internal elements
-    //! \details This function cleans up the state of materials present in trace
-    //!   quantities in each cell. Specifically, the state of materials with
-    //!   very low volume-fractions in a cell is replaced by the state of the
-    //!   material which is present in the largest quantity in that cell. This
-    //!   becomes necessary when shocks pass through cells which contain a very
-    //!   small amount of material. The state of that tiny material might
-    //!   become unphysical and cause solution to diverge; thus requiring such
-    //!   a "reset".
-    void cleanTraceMaterial( tk::real t,
-                             const tk::Fields& geoElem,
-                             tk::Fields& unk,
-                             tk::Fields& prim,
-                             std::size_t nielem ) const
-    {
-      [[maybe_unused]] const auto rdof = g_inputdeck.get< tag::rdof >();
-      auto nmat = g_inputdeck.get< tag::multimat, tag::nmat >();<--- Shadow variable<--- Variable 'nmat' is assigned a value that is never used.
-
-      Assert( unk.nunk() == prim.nunk(), "Number of unknowns in solution "
-              "vector and primitive vector at recent time step incorrect" );
-      Assert( unk.nprop() == rdof*m_ncomp, "Number of components in solution "
-              "vector must equal "+ std::to_string(rdof*m_ncomp) );
-      Assert( prim.nprop() == rdof*m_nprim, "Number of components in vector of "
-              "primitive quantities must equal "+ std::to_string(rdof*m_nprim) );
-
-      auto neg_density = cleanTraceMultiMat(t, nielem, m_mat_blk, geoElem, nmat,
-        unk, prim);
-
-      if (neg_density) Throw("Negative partial density.");
-    }
-
-    //! Reconstruct second-order solution from first-order
-    //! \param[in] geoElem Element geometry array
-    //! \param[in] fd Face connectivity and boundary conditions object
-    //! \param[in] esup Elements-surrounding-nodes connectivity
-    //! \param[in] inpoel Element-node connectivity
-    //! \param[in] coord Array of nodal coordinates
-    //! \param[in,out] U Solution vector at recent time step
-    //! \param[in,out] P Vector of primitives at recent time step
-    void reconstruct( tk::real,
-                      const tk::Fields&,
-                      const tk::Fields& geoElem,
-                      const inciter::FaceData& fd,
-                      const std::map< std::size_t, std::vector< std::size_t > >&
-                        esup,
-                      const std::vector< std::size_t >& inpoel,
-                      const tk::UnsMesh::Coords& coord,
-                      tk::Fields& U,
-                      tk::Fields& P ) const
-    {
-      const auto rdof = g_inputdeck.get< tag::rdof >();
-      const auto ndof = g_inputdeck.get< tag::ndof >();
-
-      bool is_p0p1(false);<--- Variable 'is_p0p1' is assigned a value that is never used.
-      if (rdof == 4 && ndof == 1)
-        is_p0p1 = true;<--- Variable 'is_p0p1' is assigned a value that is never used.
-
-      const auto nelem = fd.Esuel().size()/4;<--- Variable 'nelem' is assigned a value that is never used.
-      auto nmat = g_inputdeck.get< tag::multimat, tag::nmat >();<--- Shadow variable<--- Variable 'nmat' is assigned a value that is never used.
-
-      Assert( U.nprop() == rdof*m_ncomp, "Number of components in solution "
-              "vector must equal "+ std::to_string(rdof*m_ncomp) );
-
-      //----- reconstruction of conserved quantities -----
-      //--------------------------------------------------
-      // specify how many variables need to be reconstructed
-      std::vector< std::size_t > vars;
-      for (std::size_t c=0; c<m_ncomp; ++c) vars.push_back(c);
-      // If DG is applied, reconstruct only volume fractions
-      if (!is_p0p1 && ndof > 1)
-      {
-        vars.clear();
-        for (std::size_t k=0; k<nmat; ++k) vars.push_back(volfracIdx(nmat, k));
+    if (g_inputdeck.get< tag::amr, tag::dtref_uniform >())
+      uniformRefine();
+    else
+      errorRefine();
+
+  } else if (m_mode == RefMode::OUTREF) {
+
+    uniformRefine();
+
+  } else if (m_mode == RefMode::OUTDEREF) {
+
+    uniformDeRefine();
+
+  } else Throw( "RefMode not implemented" );
+
+  // Communicate extra edges
+  comExtra();
+}
+
+void
+Refiner::comExtra()
+// *****************************************************************************
+// Communicate extra edges along chare boundaries
+// *****************************************************************************
+{
+  // Export extra added nodes on our mesh chunk boundary to other chares
+  if (m_ch.empty()) {
+    correctref();
+  } else {
+    for (auto c : m_ch) {  // for all chares we share at least an edge with
+      thisProxy[c].addRefBndEdges(thisIndex, m_localEdgeData, m_intermediates);
+    }
+  }
+}
+
+void
+Refiner::addRefBndEdges(
+  int fromch,
+  const AMR::EdgeData& ed,
+  const std::unordered_set< std::size_t >& intermediates )
+// *****************************************************************************
+//! Receive edges on our chare boundary from other chares
+//! \param[in] fromch Chare call coming from
+//! \param[in] ed Edges on chare boundary
+//! \param[in] intermediates Intermediate nodes
+//! \details Other than update remoteEdge data, this function also updates
+//!   locking information for such edges whos nodes are marked as intermediate
+//!   by neighboring chares.
+// *****************************************************************************
+{
+  // Save/augment buffers of edge data for each sender chare
+  auto& red = m_remoteEdgeData[ fromch ];
+  auto& re = m_remoteEdges[ fromch ];
+  using edge_data_t = std::tuple< Edge, int, int, AMR::Edge_Lock_Case >;
+  for (const auto& [ edge, data ] : ed) {
+    red.push_back( edge_data_t{ edge, std::get<0>(data), std::get<1>(data),
+      std::get<2>(data) } );
+    re.push_back( edge );
+  }
+
+  // Add intermediates to mesh refiner lib
+  // needs to be done only when mesh has been actually updated, i.e. first iter
+  if (m_ncit == 0) {
+    auto esup = tk::genEsup( m_inpoel, 4 );
+    auto psup = tk::genPsup( m_inpoel, 4, esup );
+    for (const auto g : intermediates) {
+      auto l = m_lid.find( g ); // convert to local node ids
+      if (l != end(m_lid)) {
+        // lock all edges connected to intermediate node
+        auto p = l->second;
+        for (auto q : tk::Around(psup,p)) {
+          AMR::edge_t e(m_rid[p], m_rid[q]);
+          auto& refedge = m_refiner.tet_store.edge_store.get(e);
+          if (refedge.lock_case == AMR::Edge_Lock_Case::unlocked) {
+            refedge.lock_case = AMR::Edge_Lock_Case::temporary; //intermediate;
+            refedge.needs_refining = 0;
+          }
+        }
       }
-
-      // 1. solve 3x3 least-squares system
-      for (std::size_t e=0; e<nelem; ++e)
-      {
-        // Reconstruct second-order dofs of volume-fractions in Taylor space
-        // using nodal-stencils, for a good interface-normal estimate
-        tk::recoLeastSqExtStencil( rdof, e, esup, inpoel, geoElem, U, vars );
-      }
+    }
+  }
+
+  // Heard from every worker we share at least a single edge with
+  if (++m_nref == m_ch.size()) {
+    m_nref = 0;
+
+    updateBndEdgeData();
 
-      // 2. transform reconstructed derivatives to Dubiner dofs
-      tk::transform_P0P1(rdof, nelem, inpoel, coord, U, vars);
-
-      //----- reconstruction of primitive quantities -----
-      //--------------------------------------------------
-      // For multimat, conserved and primitive quantities are reconstructed
-      // separately.
-      if (is_p0p1) {
-        vars.clear();
-        for (std::size_t c=0; c<m_nprim; ++c) vars.push_back(c);
-
-        // 1.
-        for (std::size_t e=0; e<nelem; ++e)
-        {
-          // Reconstruct second-order dofs of volume-fractions in Taylor space
-          // using nodal-stencils, for a good interface-normal estimate
-          tk::recoLeastSqExtStencil( rdof, e, esup, inpoel, geoElem, P, vars );
-        }
-
-        // 2.
-        tk::transform_P0P1(rdof, nelem, inpoel, coord, P, vars);
-      }
-    }
-
-    //! Limit second-order solution, and primitive quantities separately
-    //! \param[in] t Physical time
-    //! \param[in] geoFace Face geometry array
-    //! \param[in] geoElem Element geometry array
-    //! \param[in] fd Face connectivity and boundary conditions object
-    //! \param[in] esup Elements-surrounding-nodes connectivity
-    //! \param[in] inpoel Element-node connectivity
-    //! \param[in] coord Array of nodal coordinates
-    //! \param[in] ndofel Vector of local number of degrees of freedome
-    //! \param[in] gid Local->global node id map
-    //! \param[in] bid Local chare-boundary node ids (value) associated to
-    //!   global node ids (key)
-    //! \param[in] uNodalExtrm Chare-boundary nodal extrema for conservative
-    //!   variables
-    //! \param[in] pNodalExtrm Chare-boundary nodal extrema for primitive
-    //!   variables
-    //! \param[in] mtInv Inverse of Taylor mass matrix
-    //! \param[in,out] U Solution vector at recent time step
-    //! \param[in,out] P Vector of primitives at recent time step
-    //! \param[in,out] shockmarker Vector of shock-marker values
-    void limit( [[maybe_unused]] tk::real t,
-                const tk::Fields& geoFace,
-                const tk::Fields& geoElem,
-                const inciter::FaceData& fd,
-                const std::map< std::size_t, std::vector< std::size_t > >& esup,
-                const std::vector< std::size_t >& inpoel,
-                const tk::UnsMesh::Coords& coord,
-                const std::vector< std::size_t >& ndofel,
-                const std::vector< std::size_t >& gid,
-                const std::unordered_map< std::size_t, std::size_t >& bid,
-                const std::vector< std::vector<tk::real> >& uNodalExtrm,
-                const std::vector< std::vector<tk::real> >& pNodalExtrm,
-                const std::vector< std::vector<tk::real> >& mtInv,
-                tk::Fields& U,
-                tk::Fields& P,
-                std::vector< std::size_t >& shockmarker ) const
-    {
-      Assert( U.nunk() == P.nunk(), "Number of unknowns in solution "
-              "vector and primitive vector at recent time step incorrect" );
-
-      const auto limiter = g_inputdeck.get< tag::limiter >();
-      auto nmat = g_inputdeck.get< tag::multimat, tag::nmat >();<--- Shadow variable
-      const auto rdof = g_inputdeck.get< tag::rdof >();
-      const auto& solidx = g_inputdeck.get<
-        tag::matidxmap, tag::solidx >();
-
-      // limit vectors of conserved and primitive quantities
-      if (limiter == ctr::LimiterType::SUPERBEEP1)
-      {
-        SuperbeeMultiMat_P1( fd.Esuel(), inpoel, ndofel,
-          coord, solidx, U, P, nmat );
-      }
-      else if (limiter == ctr::LimiterType::VERTEXBASEDP1 && rdof == 4)
-      {
-        VertexBasedMultiMat_P1( esup, inpoel, ndofel, fd.Esuel().size()/4,
-          m_mat_blk, fd, geoFace, geoElem, coord, flux, solidx, U, P,
-          nmat, shockmarker );
-      }
-      else if (limiter == ctr::LimiterType::VERTEXBASEDP1 && rdof == 10)
-      {
-        VertexBasedMultiMat_P2( esup, inpoel, ndofel, fd.Esuel().size()/4,
-          m_mat_blk, fd, geoFace, geoElem, coord, gid, bid,
-          uNodalExtrm, pNodalExtrm, mtInv, flux, solidx, U, P, nmat,
-          shockmarker );
-      }
-      else if (limiter != ctr::LimiterType::NOLIMITER)
-      {
-        Throw("Limiter type not configured for multimat.");
-      }
-    }
-
-    //! Apply CPL to the conservative variable solution for this PDE system
-    //! \param[in] prim Array of primitive variables
-    //! \param[in] geoElem Element geometry array
-    //! \param[in] inpoel Element-node connectivity
-    //! \param[in] coord Array of nodal coordinates
-    //! \param[in,out] unk Array of conservative variables
-    //! \param[in] nielem Number of internal elements
-    //! \details This function applies CPL to obtain consistent dofs for
-    //!   conservative quantities based on the limited primitive quantities.
-    //!   See Pandare et al. (2023). On the Design of Stable,
-    //!   Consistent, and Conservative High-Order Methods for Multi-Material
-    //!   Hydrodynamics. J Comp Phys, 112313.
-    void CPL( const tk::Fields& prim,
-      const tk::Fields& geoElem,
-      const std::vector< std::size_t >& inpoel,
-      const tk::UnsMesh::Coords& coord,
-      tk::Fields& unk,
-      std::size_t nielem ) const
-    {
-      [[maybe_unused]] const auto rdof = g_inputdeck.get< tag::rdof >();
-      auto nmat = g_inputdeck.get< tag::multimat, tag::nmat >();<--- Shadow variable<--- Variable 'nmat' is assigned a value that is never used.
-
-      Assert( unk.nunk() == prim.nunk(), "Number of unknowns in solution "
-              "vector and primitive vector at recent time step incorrect" );
-      Assert( unk.nprop() == rdof*m_ncomp, "Number of components in solution "
-              "vector must equal "+ std::to_string(rdof*m_ncomp) );
-      Assert( prim.nprop() == rdof*m_nprim, "Number of components in vector of "
-              "primitive quantities must equal "+ std::to_string(rdof*m_nprim) );
-
-      correctLimConservMultiMat(nielem, m_mat_blk, nmat, inpoel,
-        coord, geoElem, prim, unk);
-    }
-
-    //! Return cell-average deformation gradient tensor
-    //! \param[in] unk Solution vector at recent time step
-    //! \param[in] nielem Number of internal elements
-    //! \details This function returns the bulk cell-average inverse
-    //!   deformation gradient tensor
-    std::array< std::vector< tk::real >, 9 > cellAvgDeformGrad(
-      const tk::Fields& unk,
-      std::size_t nielem ) const
-    {
-      const auto rdof = g_inputdeck.get< tag::rdof >();
-      auto nmat = g_inputdeck.get< tag::multimat, tag::nmat >();<--- Shadow variable
-      const auto& solidx = g_inputdeck.get< tag::matidxmap, tag::solidx >();
-
-      std::array< std::vector< tk::real >, 9 > gb;
-      if (inciter::haveSolid(nmat, solidx)) {
-        for (auto& gij : gb)
-          gij.resize(nielem, 0.0);
-        for (std::size_t e=0; e<nielem; ++e) {
-          for (std::size_t k=0; k<nmat; ++k) {
-            if (solidx[k] > 0) {
-              for (std::size_t i=0; i<3; ++i)
-                for (std::size_t j=0; j<3; ++j)
-                  gb[3*i+j][e] += unk(e, volfracDofIdx(nmat,k,rdof,0)) *
-                    unk(e,deformDofIdx(nmat,solidx[k],i,j,rdof,0));
-            }
-          }
-        }
-      }
-
-      return gb;
-    }
-
-
-    //! Compute right hand side
-    //! \param[in] t Physical time
-    //! \param[in] geoFace Face geometry array
-    //! \param[in] geoElem Element geometry array
-    //! \param[in] fd Face connectivity and boundary conditions object
-    //! \param[in] inpoel Element-node connectivity
-    //! \param[in] coord Array of nodal coordinates
-    //! \param[in] U Solution vector at recent time step
-    //! \param[in] P Primitive vector at recent time step
-    //! \param[in] ndofel Vector of local number of degrees of freedom
-    //! \param[in] rho0mat Initial densities of all materials
-    //! \param[in] dt Delta time
-    //! \param[in,out] R Right-hand side vector computed
-    void rhs( tk::real t,
-              const tk::Fields& geoFace,
-              const tk::Fields& geoElem,
-              const inciter::FaceData& fd,
-              const std::vector< std::size_t >& inpoel,
-              const std::vector< std::unordered_set< std::size_t > >&,
-              const tk::UnsMesh::Coords& coord,
-              const tk::Fields& U,
-              const tk::Fields& P,
-              const std::vector< std::size_t >& ndofel,
-              const std::vector< tk::real >& rho0mat,
-              const tk::real dt,
-              tk::Fields& R ) const
-    {
-      const auto ndof = g_inputdeck.get< tag::ndof >();
-      const auto rdof = g_inputdeck.get< tag::rdof >();
-      auto nmat = g_inputdeck.get< tag::multimat, tag::nmat >();<--- Shadow variable
-      const auto intsharp =
-        g_inputdeck.get< tag::multimat, tag::intsharp >();
-      const auto& solidx = inciter::g_inputdeck.get<
-        tag::matidxmap, tag::solidx >();
-      auto nsld = numSolids(nmat, solidx);
-
-      const auto nelem = fd.Esuel().size()/4;
-
-      Assert( U.nunk() == P.nunk(), "Number of unknowns in solution "
-              "vector and primitive vector at recent time step incorrect" );
-      Assert( U.nunk() == R.nunk(), "Number of unknowns in solution "
-              "vector and right-hand side at recent time step incorrect" );
-      Assert( U.nprop() == rdof*m_ncomp, "Number of components in solution "
-              "vector must equal "+ std::to_string(rdof*m_ncomp) );
-      Assert( P.nprop() == rdof*m_nprim, "Number of components in primitive "
-              "vector must equal "+ std::to_string(rdof*m_nprim) );
-      Assert( R.nprop() == ndof*m_ncomp, "Number of components in right-hand "
-              "side vector must equal "+ std::to_string(ndof*m_ncomp) );
-      Assert( fd.Inpofa().size()/3 == fd.Esuf().size()/2,
-              "Mismatch in inpofa size" );
-
-      // set rhs to zero
-      R.fill(0.0);
-
-      // Allocate space for Riemann derivatives used in non-conservative terms.
-      // The following Riemann derivatives are stored, in order:
-      // 1) 3*nmat terms: derivatives of partial pressure of each material,
-      //    for the energy equations.
-      // 2) ndof terms: derivatives of Riemann velocity times the basis
-      //    function, for the volume fraction equations.
-      // 3) nmat*3*3*9 terms: 3 derivatives of u_l*g_ij for each material, for
-      //    the deformation gradient equations.
-      // 4) 3*nsld terms: 3 derivatives of \alpha \sigma_ij for each solid
-      //    material, for the energy equations.
-      std::vector< std::vector< tk::real > >
-        riemannDeriv(3*nmat+ndof+3*nsld, std::vector<tk::real>(U.nunk(),0.0));
-
-      // vectors to store the data of riemann velocity used for reconstruction
-      // in volume fraction equation
-      std::vector< std::vector< tk::real > > vriem( U.nunk() );
-      std::vector< std::vector< tk::real > > riemannLoc( U.nunk() );
-
-      // configure a no-op lambda for prescribed velocity
-      auto velfn = []( ncomp_t, tk::real, tk::real, tk::real, tk::real ){
-        return tk::VelFn::result_type(); };
-
-      // compute internal surface flux integrals
-      tk::surfInt( nmat, m_mat_blk, t, ndof, rdof, inpoel, solidx,
-                   coord, fd, geoFace, geoElem, m_riemann, velfn, U, P, ndofel,
-                   dt, R, vriem, riemannLoc, riemannDeriv, intsharp );
-
-      // compute optional source term
-      tk::srcInt( m_mat_blk, t, ndof, fd.Esuel().size()/4, inpoel,
-                  coord, geoElem, Problem::src, ndofel, R, nmat );
-
-      if(ndof > 1)
-        // compute volume integrals
-        tk::volInt( nmat, t, m_mat_blk, ndof, rdof, nelem,
-                    inpoel, coord, geoElem, flux, velfn, U, P, ndofel, R,
-                    intsharp );
-
-      // compute boundary surface flux integrals
-      for (const auto& b : m_bc)
-        tk::bndSurfInt( nmat, m_mat_blk, ndof, rdof,
-                        b.first, fd, geoFace, geoElem, inpoel, coord, t,
-                        m_riemann, velfn, b.second, U, P, ndofel, R, vriem,
-                        riemannLoc, riemannDeriv, intsharp );
-
-      Assert( riemannDeriv.size() == 3*nmat+ndof+3*nsld, "Size of "
-              "Riemann derivative vector incorrect" );
-
-      // get derivatives from riemannDeriv
-      for (std::size_t k=0; k<riemannDeriv.size(); ++k)
-      {
-        Assert( riemannDeriv[k].size() == U.nunk(), "Riemann derivative vector "
-                "for non-conservative terms has incorrect size" );
-        for (std::size_t e=0; e<U.nunk(); ++e)
-          riemannDeriv[k][e] /= geoElem(e, 0);
-      }
-
-      // compute volume integrals of non-conservative terms
-      tk::nonConservativeInt( nmat, m_mat_blk, ndof, rdof, nelem,
-                              inpoel, coord, geoElem, U, P, riemannDeriv,
-                              ndofel, R, intsharp );
+    std::vector< std::size_t > meshdata{ m_meshid };
+    contribute( meshdata, CkReduction::max_ulong,
+                m_cbr.get< tag::compatibility >() );
+  }
+}
+
+void
+Refiner::correctref()
+// *****************************************************************************
+//  Correct extra edges to arrive at conforming mesh across chare boundaries
+//! \details This function is called repeatedly until there is not a a single
+//!    edge that needs correction for the whole distributed problem to arrive at
+//!    a conforming mesh across chare boundaries during a mesh refinement step.
+// *****************************************************************************
+{
+  auto unlocked = AMR::Edge_Lock_Case::unlocked;
+
+  // Storage for edge data that need correction to yield a conforming mesh
+  AMR::EdgeData extra;
+  std::size_t neigh_extra(0);
+
+  // Vars for debugging purposes
+  std::size_t nlocked(0);<--- Variable 'nlocked' is assigned a value that is never used.
+  std::array< std::size_t, 4 > ncorrcase{{0,0,0,0}};
+
+  // loop through all edges shared with other chares
+  for (const auto& [ neighborchare, edgedata ] : m_remoteEdgeData) {
+    for (const auto& [edge,remote_needs_refining,remote_needs_derefining,
+      remote_lock_case] : edgedata) {
+      // find local data of remote edge
+      auto it = m_localEdgeData.find( edge );
+      if (it != end(m_localEdgeData)) {
+        auto& local = it->second;
+        auto& local_needs_refining = std::get<0>(local);
+        auto& local_needs_derefining = std::get<1>(local);
+        auto& local_lock_case = std::get<2>(local);
+
+        auto local_needs_refining_orig = local_needs_refining;<--- Variable 'local_needs_refining_orig' is assigned a value that is never used.
+        auto local_needs_derefining_orig = local_needs_derefining;<--- Variable 'local_needs_derefining_orig' is assigned a value that is never used.
+        auto local_lock_case_orig = local_lock_case;<--- Variable 'local_lock_case_orig' is assigned a value that is never used.
+
+        Assert( !(local_lock_case > unlocked && local_needs_refining),
+                "Invalid local edge: locked & needs refining" );
+        Assert( !(remote_lock_case > unlocked && remote_needs_refining),
+                "Invalid remote edge: locked & needs refining" );
+        Assert( !(local_needs_derefining == 1 && local_needs_refining > 0),
+                "Invalid local edge: needs refining and derefining" );
+
+        // The parallel compatibility (par-compat) algorithm
+
+        // compute lock from local and remote locks as most restrictive
+        local_lock_case = std::max( local_lock_case, remote_lock_case );
+
+        if (local_lock_case > unlocked) {
+          local_needs_refining = 0;
+          if (local_needs_refining != local_needs_refining_orig ||
+            local_lock_case != local_lock_case_orig)
+            ++ncorrcase[0];
+        }
+
+        // Possible combinations of remote-local ref-deref decisions
+        // rows 1, 5, 9: no action needed.
+        // rows 4, 7, 8: no action on local-side; comm needed.
+        //
+        //    LOCAL          |        REMOTE    |  Result
+        // 1  d              |        d         |  d
+        // 2  d              |        -         |  -
+        // 3  d              |        r         |  r
+        // 4  -              |        d         |  -
+        // 5  -              |        -         |  -
+        // 6  -              |        r         |  r
+        // 7  r              |        d         |  r
+        // 8  r              |        -         |  r
+        // 9  r              |        r         |  r
+
+        // Rows 3, 6
+        // If remote wants to refine
+        if (remote_needs_refining == 1) {
+          if (local_lock_case == unlocked) {
+            local_needs_refining = 1;
+            local_needs_derefining = false;
+            if (local_needs_refining != local_needs_refining_orig ||
+              local_needs_derefining != local_needs_derefining_orig)
+              ++ncorrcase[1];
+          }
+          else {
+           ++nlocked;
+          }
+        }
+
+        // Row 2
+        // If remote neither wants to refine nor derefine
+        if (remote_needs_refining == 0 && remote_needs_derefining == false) {
+          local_needs_derefining = false;
+          if (local_needs_derefining != local_needs_derefining_orig)
+            ++ncorrcase[2];
+        }
+
+        // Row 1: special case
+        // If remote wants to deref-ref (either of 8:4, 8:2, 4:2)
+        // and local does not want to refine (neither pure ref nor deref-ref)
+        if (remote_needs_refining == 2 && local_needs_refining == 0) {
+          if (local_lock_case == unlocked) {
+            local_needs_refining = 1;
+            local_needs_derefining = false;
+            if (local_needs_refining != local_needs_refining_orig ||
+              local_needs_derefining != local_needs_derefining_orig)
+              ++ncorrcase[3];
+          }
+          else {
+            ++nlocked;<--- Variable 'nlocked' is assigned a value that is never used.
+          }
+        }
+
+        // Rows 4, 7, 8
+
+        // if the remote sent us data that makes us change our local state,
+        // e.g., local{-,0} + remote{r,0} -> local{r,0}, i.e., I changed my
+        // state I need to tell the world about it
+        if (local_lock_case != local_lock_case_orig ||
+            local_needs_refining != local_needs_refining_orig ||
+            local_needs_derefining != local_needs_derefining_orig)
+        {
+          auto l1 = tk::cref_find( m_lid, edge[0] );
+          auto l2 = tk::cref_find( m_lid, edge[1] );
+          Assert( l1 != l2, "Edge end-points local ids are the same" );
+          auto r1 = m_rid[ l1 ];
+          auto r2 = m_rid[ l2 ];
+          Assert( r1 != r2, "Edge end-points refiner ids are the same" );
+          //std::cout << thisIndex << ": " << r1 << ", " << r2 << std::endl;
+          //if (m_refiner.tet_store.edge_store.get(AMR::edge_t(r1,r2)).lock_case > local_lock_case) {
+          //  std::cout << thisIndex << ": edge " << r1 << "-" << r2 <<
+          //    "; prev=" << local_lock_case_orig <<
+          //    "; new=" << local_lock_case <<
+          //    "; amr-lib=" << m_refiner.tet_store.edge_store.get(AMR::edge_t(r1,r2)).lock_case <<
+          //    " | parcompatiter " << m_ncit << std::endl;
+          //}
+           extra[ {{ std::min(r1,r2), std::max(r1,r2) }} ] =
+             { local_needs_refining, local_needs_derefining, local_lock_case };
+        }
+        // or if the remote data is inconsistent with what I think, e.g.,
+        // local{r,0} + remote{-,0} -> local{r,0}, i.e., the remote does not
+        // yet agree, so another par-compat iteration will be pursued. but
+        // I do not have to locally run ref-compat.
+        else if (local_lock_case != remote_lock_case ||
+          local_needs_refining != remote_needs_refining ||
+          local_needs_derefining != remote_needs_derefining)
+        {
+          ++neigh_extra;
+        }
+      }
+    }
+  }
+
+  m_remoteEdgeData.clear();
+  m_extra = extra.size();
+  //std::cout << thisIndex << ": amr correction reqd for nedge: " << m_extra << std::endl;
+  //std::cout << thisIndex << ": amr correction reqd for neighbor edges: " << neigh_extra << std::endl;
+  //std::cout << thisIndex << ": edge counts by correction case: " << ncorrcase[0]
+  //  << ", " << ncorrcase[1] << ", " << ncorrcase[2] << ", " << ncorrcase[3] << std::endl;
+  //std::cout << thisIndex << ": locked edges that req corr: " << nlocked << std::endl;
+
+  if (!extra.empty()) {
+    //std::cout << thisIndex << ": redoing markings" << std::endl;
+    // Do refinement compatibility (ref-compat) for edges that need correction
+    m_refiner.mark_error_refinement_corr( extra );
+    ++m_ncit;
+    // Update our extra-edge store based on refiner
+    updateEdgeData();
+    m_remoteEdges.clear();
+  }
+  else if (neigh_extra == 0) {
+    m_ncit = 0;
+  }
+
+  // Aggregate number of extra edges that still need correction and some
+  // refinement/derefinement statistics
+  const auto& tet_store = m_refiner.tet_store;
+  std::vector< std::size_t >
+    m{ m_meshid,
+       m_extra,
+       tet_store.marked_refinements.size(),
+       tet_store.marked_derefinements.size(),
+       static_cast< std::underlying_type_t< RefMode > >( m_mode ) };
+  contribute( m, CkReduction::sum_ulong, m_cbr.get< tag::matched >() );
+}
+
+void
+Refiner::updateEdgeData()
+// *****************************************************************************
+// Query AMR lib and update our local store of edge data
+// *****************************************************************************
+{
+  m_localEdgeData.clear();
+  m_intermediates.clear();
+
+  // This currently takes ALL edges from the AMR lib, i.e., on the whole
+  // domain. We should eventually only collect edges here that are shared with
+  // other chares.
+  const auto& ref_edges = m_refiner.tet_store.edge_store.edges;
+  const auto& refinpoel = m_refiner.tet_store.get_active_inpoel();
+
+  for (std::size_t e=0; e<refinpoel.size()/4; ++e) {
+    auto A = refinpoel[e*4+0];
+    auto B = refinpoel[e*4+1];
+    auto C = refinpoel[e*4+2];
+    auto D = refinpoel[e*4+3];
+    std::array<Edge,6> edges{{ {{A,B}}, {{B,C}}, {{A,C}},
+                               {{A,D}}, {{B,D}}, {{C,D}} }};
+    for (const auto& ed : edges) {
+      auto ae = AMR::edge_t{{{ std::min(ed[0],ed[1]), std::max(ed[0],ed[1]) }}};
+      auto r = tk::cref_find( ref_edges, ae );
+      const auto ged = Edge{{ m_gid[ tk::cref_find( m_lref, ed[0] ) ],
+                              m_gid[ tk::cref_find( m_lref, ed[1] ) ] }};
+      m_localEdgeData[ ged ] = { r.needs_refining, r.needs_derefining,
+        r.lock_case };
+    }
+  }
+
+  // Build intermediates to send. This currently takes ALL intermediates from
+  // the AMR lib, i.e., on the whole domain. We should eventually only collect
+  // edges here that are shared with other chares.
+  for (const auto& r : m_refiner.tet_store.intermediate_list) {
+    m_intermediates.insert( m_gid[ tk::cref_find( m_lref, r ) ] );
+  }
+}
+
+void
+Refiner::updateBndEdgeData()
+// *****************************************************************************
+// Query AMR lib and update our local store of boundary edge data
+// *****************************************************************************
+{
+  // This currently takes ALL edges from the AMR lib, i.e., on the whole
+  // domain. We should eventually only collect edges here that are shared with
+  // other chares.
+  const auto& ref_edges = m_refiner.tet_store.edge_store.edges;
+  const auto& refinpoel = m_refiner.tet_store.get_active_inpoel();
+
+  for (std::size_t e=0; e<refinpoel.size()/4; ++e) {
+    auto A = refinpoel[e*4+0];
+    auto B = refinpoel[e*4+1];
+    auto C = refinpoel[e*4+2];
+    auto D = refinpoel[e*4+3];
+    std::array<Edge,6> edges{{ {{A,B}}, {{B,C}}, {{A,C}},
+                               {{A,D}}, {{B,D}}, {{C,D}} }};
+    for (const auto& ed : edges) {
+      auto ae = AMR::edge_t{{{ std::min(ed[0],ed[1]), std::max(ed[0],ed[1]) }}};
+      auto r = tk::cref_find( ref_edges, ae );
+      const auto ged = Edge{{ m_gid[ tk::cref_find( m_lref, ed[0] ) ],
+                              m_gid[ tk::cref_find( m_lref, ed[1] ) ] }};
+      // only update edges that are on chare boundary OR unlocked
+      if (m_localEdgeData.find(ged) == m_localEdgeData.end() ||
+        std::get<2>(m_localEdgeData[ged]) == AMR::Edge_Lock_Case::unlocked) {
+        m_localEdgeData[ ged ] = { r.needs_refining, r.needs_derefining,
+          r.lock_case };
+      }
+    }
+  }
+}
+
+std::tuple< std::vector< std::string >,
+            std::vector< std::vector< tk::real > >,
+            std::vector< std::string >,
+            std::vector< std::vector< tk::real > > >
+Refiner::refinementFields() const
+// *****************************************************************************
+//  Collect mesh output fields from refiner lib
+//! \return Names and fields of mesh refinement data in mesh cells and nodes
+// *****************************************************************************
+{
+  // Find number of nodes in current mesh
+  auto npoin = tk::npoin_in_graph( m_inpoel );
+  // Generate edges surrounding points in current mesh
+  auto esup = tk::genEsup( m_inpoel, 4 );
 
-      // Compute integrals for inverse deformation correction in solid materials
-      if (inciter::haveSolid(nmat, solidx) &&
-        g_inputdeck.get< tag::multimat, tag::rho0constraint >())
-        tk::solidTermsVolInt( nmat, m_mat_blk, ndof, rdof, nelem,
-                              inpoel, coord, geoElem, U, P, ndofel,
-                              rho0mat, dt, R);
+  // Update solution on current mesh
+  const auto& u = solution( npoin, esup );
+  Assert( u.nunk() == npoin, "Solution uninitialized or wrong size" );
+
+  // Compute error in edges on current mesh
+  auto edgeError = errorsInEdges( npoin, esup, u );
 
-      // compute finite pressure relaxation terms
-      if (g_inputdeck.get< tag::multimat, tag::prelax >())
-      {
-        const auto ct = g_inputdeck.get< tag::multimat,
-                                         tag::prelax_timescale >();
-        tk::pressureRelaxationInt( nmat, m_mat_blk, ndof,
-                                   rdof, nelem, inpoel, coord, geoElem, U, P,
-                                   ndofel, ct, R, intsharp );
-      }
-    }
-
-    //! Evaluate the adaptive indicator and mark the ndof for each element
-    //! \param[in] nunk Number of unknowns
-    //! \param[in] coord Array of nodal coordinates
-    //! \param[in] inpoel Element-node connectivity
-    //! \param[in] fd Face connectivity and boundary conditions object
-    //! \param[in] unk Array of unknowns
-    //! \param[in] prim Array of primitive quantities
-    //! \param[in] indicator p-refinement indicator type
-    //! \param[in] ndof Number of degrees of freedom in the solution
-    //! \param[in] ndofmax Max number of degrees of freedom for p-refinement
-    //! \param[in] tolref Tolerance for p-refinement
-    //! \param[in,out] ndofel Vector of local number of degrees of freedome
-    void eval_ndof( std::size_t nunk,
-                    [[maybe_unused]] const tk::UnsMesh::Coords& coord,
-                    [[maybe_unused]] const std::vector< std::size_t >& inpoel,
-                    const inciter::FaceData& fd,
-                    const tk::Fields& unk,
-                    const tk::Fields& prim,
-                    inciter::ctr::PrefIndicatorType indicator,
-                    std::size_t ndof,
-                    std::size_t ndofmax,
-                    tk::real tolref,
-                    std::vector< std::size_t >& ndofel ) const
-    {
-      const auto& esuel = fd.Esuel();
-      auto nmat = g_inputdeck.get< tag::multimat, tag::nmat >();<--- Shadow variable
-
-      if(indicator == inciter::ctr::PrefIndicatorType::SPECTRAL_DECAY)
-        spectral_decay(nmat, nunk, esuel, unk, prim, ndof, ndofmax, tolref,
-          ndofel);
-      else
-        Throw( "No such adaptive indicator type" );
-    }
-
-    //! Compute the minimum time step size
-    //! \param[in] fd Face connectivity and boundary conditions object
-    //! \param[in] geoFace Face geometry array
-    //! \param[in] geoElem Element geometry array
-//    //! \param[in] ndofel Vector of local number of degrees of freedom
-    //! \param[in] U Solution vector at recent time step
-    //! \param[in] P Vector of primitive quantities at recent time step
-    //! \param[in] nielem Number of internal elements
-    //! \return Minimum time step size
-    //! \details The allowable dt is calculated by looking at the maximum
-    //!   wave-speed in elements surrounding each face, times the area of that
-    //!   face. Once the maximum of this quantity over the mesh is determined,
-    //!   the volume of each cell is divided by this quantity. A minimum of this
-    //!   ratio is found over the entire mesh, which gives the allowable dt.
-    tk::real dt( const std::array< std::vector< tk::real >, 3 >&,
-                 const std::vector< std::size_t >&,
-                 const inciter::FaceData& fd,
-                 const tk::Fields& geoFace,
-                 const tk::Fields& geoElem,
-                 const std::vector< std::size_t >& /*ndofel*/,
-                 const tk::Fields& U,
-                 const tk::Fields& P,
-                 const std::size_t nielem ) const
-    {
-      const auto ndof = g_inputdeck.get< tag::ndof >();
-      auto nmat = g_inputdeck.get< tag::multimat, tag::nmat >();<--- Shadow variable
-
-      auto mindt = timeStepSizeMultiMat( m_mat_blk, fd.Esuf(), geoFace, geoElem,
-        nielem, nmat, U, P);
-
-      tk::real dgp = 0.0;
-      if (ndof == 4)
-      {
-        dgp = 1.0;
-      }
-      else if (ndof == 10)
-      {
-        dgp = 2.0;
-      }
-
-      // Scale smallest dt with CFL coefficient and the CFL is scaled by (2*p+1)
-      // where p is the order of the DG polynomial by linear stability theory.
-      mindt /= (2.0*dgp + 1.0);
-      return mindt;
-    }
-
-    //! Compute stiff terms for a single element
-    //! \param[in] e Element number
-    //! \param[in] geoElem Element geometry array
-    //! \param[in] inpoel Element-node connectivity
-    //! \param[in] coord Array of nodal coordinates
-    //! \param[in] U Solution vector at recent time step
-    //! \param[in] P Primitive vector at recent time step
-    //! \param[in] ndofel Vector of local number of degrees of freedom
-    //! \param[in,out] R Right-hand side vector computed
-    void stiff_rhs( std::size_t e,
-                    const tk::Fields& geoElem,
-                    const std::vector< std::size_t >& inpoel,
-                    const tk::UnsMesh::Coords& coord,
-                    const tk::Fields& U,
-                    const tk::Fields& P,
-                    const std::vector< std::size_t >& ndofel,
-                    tk::Fields& R ) const<--- Parameter 'R' can be declared with const
-    {
-      const auto ndof = g_inputdeck.get< tag::ndof >();<--- Variable 'ndof' is assigned a value that is never used.
-      const auto rdof = g_inputdeck.get< tag::rdof >();<--- Variable 'rdof' is assigned a value that is never used.
-      auto nmat = g_inputdeck.get< tag::multimat, tag::nmat >();<--- Shadow variable<--- Variable 'nmat' is assigned a value that is never used.
-      const auto intsharp =<--- Variable 'intsharp' is assigned a value that is never used.
-        g_inputdeck.get< tag::multimat, tag::intsharp >();
-      const auto& solidx = inciter::g_inputdeck.get<
-        tag::matidxmap, tag::solidx >();
-
-      Assert( U.nunk() == P.nunk(), "Number of unknowns in solution "
-              "vector and primitive vector at recent time step incorrect" );
-      Assert( U.nprop() == rdof*m_ncomp, "Number of components in solution "
-              "vector must equal "+ std::to_string(rdof*m_ncomp) );
-      Assert( P.nprop() == rdof*m_nprim, "Number of components in primitive "
-              "vector must equal "+ std::to_string(rdof*m_nprim) );
-      Assert( R.nprop() == ndof*nstiffeq(), "Number of components in "
-              "right-hand side must equal "+ std::to_string(ndof*nstiffeq()) );
-
-      // set rhs to zero for element e
-      for (std::size_t i=0; i<ndof*nstiffeq(); ++i)
-        R(e, i) = 0.0;
-
-      const auto& cx = coord[0];
-      const auto& cy = coord[1];
-      const auto& cz = coord[2];
-
-      auto ncomp = U.nprop()/rdof;
-      auto nprim = P.nprop()/rdof;<--- Shadow variable
-
-      auto ng = tk::NGvol(ndofel[e]);
-
-      // arrays for quadrature points
-      std::array< std::vector< tk::real >, 3 > coordgp;
-      std::vector< tk::real > wgp;
-
-      coordgp[0].resize( ng );
-      coordgp[1].resize( ng );
-      coordgp[2].resize( ng );
-      wgp.resize( ng );
-
-      tk::GaussQuadratureTet( ng, coordgp, wgp );
-
-      // Extract the element coordinates
-      std::array< std::array< tk::real, 3>, 4 > coordel {{
-        {{ cx[ inpoel[4*e  ] ], cy[ inpoel[4*e  ] ], cz[ inpoel[4*e  ] ] }},
-        {{ cx[ inpoel[4*e+1] ], cy[ inpoel[4*e+1] ], cz[ inpoel[4*e+1] ] }},
-        {{ cx[ inpoel[4*e+2] ], cy[ inpoel[4*e+2] ], cz[ inpoel[4*e+2] ] }},
-        {{ cx[ inpoel[4*e+3] ], cy[ inpoel[4*e+3] ], cz[ inpoel[4*e+3] ] }}
-      }};
+  // Transfer error from edges to cells for field output
+  std::vector< tk::real > error( m_inpoel.size()/4, 0.0 );
+  for (std::size_t e=0; e<m_inpoel.size()/4; ++e) {
+    auto A = m_inpoel[e*4+0];
+    auto B = m_inpoel[e*4+1];
+    auto C = m_inpoel[e*4+2];
+    auto D = m_inpoel[e*4+3];
+    std::array<Edge,6> edges{{ {{A,B}}, {{B,C}}, {{A,C}},
+                               {{A,D}}, {{B,D}}, {{C,D}} }};
+    // sum error from edges to elements
+    for (const auto& ed : edges) error[e] += tk::cref_find( edgeError, ed );
+    error[e] /= 6.0;    // assign edge-average error to element
+  }
+
+  // Prepare element fields with mesh refinement data
+  std::vector< std::string >
+    elemfieldnames{ "refinement level", "cell type", "error" };
+  auto& tet_store = m_refiner.tet_store;
+  std::vector< std::vector< tk::real > > elemfields{
+    tet_store.get_refinement_level_list(),
+    tet_store.get_cell_type_list(),
+    error };
+
+  using tuple_t = std::tuple< std::vector< std::string >,
+                              std::vector< std::vector< tk::real > >,
+                              std::vector< std::string >,
+                              std::vector< std::vector< tk::real > > >;
+  return tuple_t{ elemfieldnames, elemfields, {}, {} };
+}
+
+void
+Refiner::writeMesh( const std::string& basefilename,
+                    uint64_t itr,
+                    tk::real t,
+                    CkCallback c ) const
+// *****************************************************************************
+//  Output mesh to file(s)
+//! \param[in] basefilename File name to append to
+//! \param[in] itr Iteration count since a new mesh
+//! \param[in] t "Physical time" to write to file. "Time" here is used to
+//!   designate a new time step at which the mesh is saved.
+//! \param[in] c Function to continue with after the write
+// *****************************************************************************
+{
+  auto r = refinementFields();
+  auto& elemfieldnames = std::get< 0 >( r );
+  auto& elemfields = std::get< 1 >( r );
+  auto& nodefieldnames = std::get< 2 >( r );
+  auto& nodefields = std::get< 3 >( r );
+
+  // Prepare solution field names: depvar + component id for all eqs
+  auto nprop = g_inputdeck.get< tag::ncomp >();
+  std::vector< std::string > solfieldnames;
+  for (std::size_t i=0; i<nprop; ++i) {
+    solfieldnames.push_back(
+      g_inputdeck.get< tag::depvar >()[0] + std::to_string(i+1) );
+  }
+  Assert( solfieldnames.size() == nprop, "Size mismatch" );
+
+  const auto scheme = g_inputdeck.get< tag::scheme >();
+  const auto centering = ctr::Scheme().centering( scheme );
+  auto t0 = g_inputdeck.get< tag::t0 >();
+
+  // list of nodes/elements at which box ICs are defined
+  std::vector< std::unordered_set< std::size_t > > inbox;
+  tk::real V = 1.0;
+  std::vector< tk::real > blkvols;
+  std::unordered_map< std::size_t, std::set< std::size_t > > nodeblockid,
+    elemblockid;
+
+  // Prepare node or element fields for output to file
+  if (centering == tk::Centering::NODE) {
+
+    // Augment element field names with solution variable names + field ids
+    nodefieldnames.insert( end(nodefieldnames),
+                           begin(solfieldnames), end(solfieldnames) );
+
+    // Evaluate initial conditions on current mesh at t0
+    tk::Fields u( m_coord[0].size(), nprop );
+    g_cgpde[m_meshid].initialize( m_coord, u, t0, V, inbox, blkvols,
+      nodeblockid );
+
+    // Extract all scalar components from solution for output to file
+    for (std::size_t i=0; i<nprop; ++i)
+      nodefields.push_back( u.extract_comp( i ) );
+
+  } else if (centering == tk::Centering::ELEM) {
+
+    // Augment element field names with solution variable names + field ids
+    elemfieldnames.insert( end(elemfieldnames),
+                           begin(solfieldnames), end(solfieldnames) );
+
+    auto ndof = g_inputdeck.get< tag::ndof >();
+    tk::Fields lhs( m_inpoel.size()/4, ndof*nprop );
+
+    // Generate left hand side for DG and evaluate initial conditions on
+    // current mesh at t0
+    auto geoElem = tk::genGeoElemTet( m_inpoel, m_coord );
+    auto u = lhs;
+    if (scheme == ctr::SchemeType::FV) {
+      g_fvpde[m_meshid].lhs( geoElem, lhs );
+      g_fvpde[m_meshid].initialize( lhs, m_inpoel, m_coord, inbox, elemblockid,
+        u, t0, m_inpoel.size()/4 );
+    }
+    else {
+      g_dgpde[m_meshid].lhs( geoElem, lhs );
+      g_dgpde[m_meshid].initialize( lhs, m_inpoel, m_coord, inbox, elemblockid,
+        u, t0, m_inpoel.size()/4 );
+    }
+
+    // Extract all scalar components from solution for output to file
+    for (std::size_t i=0; i<nprop; ++i)
+      elemfields.push_back( u.extract_comp( i ) );
+  }
+
+  // Output mesh
+  m_meshwriter[ CkNodeFirst( CkMyNode() ) ].
+    write( m_meshid, /*meshoutput = */ true, /*fieldoutput = */ true, itr, 1, t,
+           thisIndex, basefilename, m_inpoel, m_coord, m_bface,
+           tk::remap(m_bnode,m_lid), tk::remap(m_triinpoel,m_lid),
+           elemfieldnames, nodefieldnames, {}, {}, elemfields, nodefields, {},
+           {}, {}, c );
+}
+
+void
+Refiner::perform()
+// *****************************************************************************
+// Perform mesh refinement and decide how to continue
+//! \details First the mesh refiner object is called to perform a single step
+//!   of mesh refinement. Then, if this function is called during a step
+//!   (potentially multiple levels of) initial AMR, it evaluates whether to do
+//!   another one. If it is called during time stepping, this concludes the
+//!   single mesh refinement step and the new mesh is sent to the PDE worker
+//!   (Discretization).
+// *****************************************************************************
+{
+  // Save old tets and their ids before performing refinement. Outref is always
+  // followed by outderef, so to the outside world, the mesh is uchanged, thus
+  // no update.
+  if (m_mode != RefMode::OUTREF && m_mode != RefMode::OUTDEREF) {
+    m_oldTets.clear();
+    for (const auto& [ id, tet ] : m_refiner.tet_store.tets) {
+      m_oldTets.insert( tet );
+    }
+    m_oldntets = m_oldTets.size();
+  }
+
+  if (m_mode == RefMode::T0REF) {
+
+    // Refine mesh based on next initial refinement type
+    if (!m_initref.empty()) {
+      auto r = m_initref.back();    // consume (reversed) list from its back
+      if (r == ctr::AMRInitialType::UNIFORM_DEREFINE)
+        m_refiner.perform_derefinement();
+      else
+        m_refiner.perform_refinement();
+    }
 
-      // Gaussian quadrature
-      for (std::size_t igp=0; igp<ng; ++igp)
-      {
-        // Compute the coordinates of quadrature point at physical domain
-        auto gp = tk::eval_gp( igp, coordel, coordgp );
-
-        // Compute the basis function
-        auto B = tk::eval_basis( ndofel[e], coordgp[0][igp], coordgp[1][igp],
-                             coordgp[2][igp] );
-
-        auto state = tk::evalPolynomialSol(m_mat_blk, intsharp, ncomp, nprim,
-          rdof, nmat, e, ndofel[e], inpoel, coord, geoElem, gp, B, U, P);
-
-        // compute source
-        // Loop through materials
-        std::size_t ksld = 0;
-        for (std::size_t k=0; k<nmat; ++k)
-        {
-          if (solidx[k] > 0)
-          {
-            tk::real alpha = state[inciter::volfracIdx(nmat, k)];
-            std::array< std::array< tk::real, 3 >, 3 > g;
-            // Compute the source terms
-            for (std::size_t i=0; i<3; ++i)
-              for (std::size_t j=0; j<3; ++j)
-                g[i][j] = state[inciter::deformIdx(nmat,solidx[k],i,j)];
-
-            // Compute Lp
-            // Reference: Ortega, A. L., Lombardini, M., Pullin, D. I., &
-            // Meiron, D. I. (2014). Numerical simulation of elastic–plastic
-            // solid mechanics using an Eulerian stretch tensor approach and
-            // HLLD Riemann solver. Journal of Computational Physics, 257,
-            // 414-441
-            std::array< std::array< tk::real, 3 >, 3 > Lp;
+  } else {
+
+    // TODO: does not work yet, fix as above
+    m_refiner.perform_refinement();
+    m_refiner.perform_derefinement();
+  }
+
+  // Remove temporary edge-locks resulting from the parallel compatibility
+  m_refiner.remove_edge_locks(1);
+  m_refiner.remove_edge_temp_locks();
+
+  //auto& tet_store = m_refiner.tet_store;
+  //std::cout << "before ref: " << tet_store.marked_refinements.size() << ", " << tet_store.marked_derefinements.size() << ", " << tet_store.size() << ", " << tet_store.get_active_inpoel().size() << '\n';
+  //std::cout << "after ref: " << tet_store.marked_refinements.size() << ", " << tet_store.marked_derefinements.size() << ", " << tet_store.size() << ", " << tet_store.get_active_inpoel().size() << '\n';
+  //std::cout << "after deref: " << tet_store.marked_refinements.size() << ", " << tet_store.marked_derefinements.size() << ", " << tet_store.size() << ", " << tet_store.get_active_inpoel().size() << '\n';
+
+  // Update volume and boundary mesh
+  updateMesh();
+
+  // Save mesh at every initial refinement step (mainly for debugging). Will
+  // replace with just a 'next()' in production.
+  if (m_mode == RefMode::T0REF) {
+
+    auto l = m_ninitref - m_initref.size() + 1;  // num initref steps completed
+    auto t0 = g_inputdeck.get< tag::t0 >();
+    // Generate times equally subdividing t0-1...t0 to ninitref steps
+    auto t =
+      t0 - 1.0 + static_cast<tk::real>(l)/static_cast<tk::real>(m_ninitref);
+    auto itr = l;
+    // Output mesh after refinement step
+    writeMesh( "t0ref", itr, t,
+               CkCallback( CkIndex_Refiner::next(), thisProxy[thisIndex] ) );
+
+  } else {
 
-            // 1. Compute dev(sigma)
-            auto sigma_dev = m_mat_blk[k].computeTensor< EOS::CauchyStress >(
-              0.0, 0.0, 0.0, 0.0, 0.0, alpha, k, g );
-            for (std::size_t i=0; i<3; ++i)
-              for (std::size_t j=0; j<3; ++j)
-                sigma_dev[i][j] /= alpha;
-            tk::real sigma_trace =
-              sigma_dev[0][0]+sigma_dev[1][1]+sigma_dev[2][2];
-            for (std::size_t i=0; i<3; ++i)
-              sigma_dev[i][i] -= sigma_trace/3.0;
-
-            // 2. Compute inv(g)
-            double ginv[9];
-            for (std::size_t i=0; i<3; ++i)
-              for (std::size_t j=0; j<3; ++j)
-                ginv[3*i+j] = g[i][j];
-            lapack_int ipiv[3];
-            #ifndef NDEBUG
-            lapack_int ierr =
-            #endif
-              LAPACKE_dgetrf(LAPACK_ROW_MAJOR, 3, 3, ginv, 3, ipiv);
-            Assert(ierr==0, "Lapack error in LU factorization of g");
-            #ifndef NDEBUG
-            lapack_int jerr =
-            #endif
-              LAPACKE_dgetri(LAPACK_ROW_MAJOR, 3, ginv, 3, ipiv);
-            Assert(jerr==0, "Lapack error in inverting g");
-
-            // 3. Compute dev(sigma)*inv(g)
-            std::array< std::array< tk::real, 3 >, 3 > aux_mat;
-            for (std::size_t i=0; i<3; ++i)
-              for (std::size_t j=0; j<3; ++j)
-              {
-                tk::real sum = 0.0;
-                for (std::size_t l=0; l<3; ++l)
-                  sum += sigma_dev[i][l]*ginv[3*l+j];
-                aux_mat[i][j] = sum;
-              }
-
-            // 4. Compute g*(dev(sigma)*inv(g))
-            for (std::size_t i=0; i<3; ++i)
-              for (std::size_t j=0; j<3; ++j)
-              {
-                tk::real sum = 0.0;
-                for (std::size_t l=0; l<3; ++l)
-                  sum += g[i][l]*aux_mat[l][j];
-                Lp[i][j] = sum;
-              }
-
-            // 5. Divide by 2*mu*tau
-            // 'Perfect' plasticity
-            tk::real yield_stress = getmatprop< tag::yield_stress >(k);
-            tk::real equiv_stress = 0.0;
-            for (std::size_t i=0; i<3; ++i)
-              for (std::size_t j=0; j<3; ++j)
-                equiv_stress += sigma_dev[i][j]*sigma_dev[i][j];
-            equiv_stress = std::sqrt(3.0*equiv_stress/2.0);
-            // rel_factor = 1/tau <- Perfect plasticity for now.
-            tk::real rel_factor = 0.0;
-            if (equiv_stress >= yield_stress)
-              rel_factor = yield_stress;
-            tk::real mu = getmatprop< tag::mu >(k);
-            for (std::size_t i=0; i<3; ++i)
-              for (std::size_t j=0; j<3; ++j)
-                Lp[i][j] *= rel_factor/(2.0*mu);
-
-            // Compute the source terms
-            std::vector< tk::real > s(9*ndof, 0.0);
-            for (std::size_t i=0; i<3; ++i)
-              for (std::size_t j=0; j<3; ++j)
-                for (std::size_t idof=0; idof<ndof; ++idof)
-                {
-                  s[(i*3+j)*ndof+idof] = B[idof] * (Lp[i][0]*g[0][j]
-                                                   +Lp[i][1]*g[1][j]
-                                                   +Lp[i][2]*g[2][j]);
-                }
-
-            auto wt = wgp[igp] * geoElem(e, 0);
-
-            // Contribute to the right-hand-side
-            for (std::size_t i=0; i<3; ++i)
-              for (std::size_t j=0; j<3; ++j)
-                for (std::size_t idof=0; idof<ndof; ++idof)
-                {
-                  std::size_t srcId = (i*3+j)*ndof+idof;
-                  std::size_t dofId = solidTensorIdx(ksld,i,j)*ndof+idof;
-                  R(e, dofId) += wt * s[srcId];
-                }
-
-            ksld++;
-          }
-        }
-
-        }
-    }
-
-    //! Extract the velocity field at cell nodes. Currently unused.
-    //! \param[in] U Solution vector at recent time step
-    //! \param[in] N Element node indices
-    //! \return Array of the four values of the velocity field
-    std::array< std::array< tk::real, 4 >, 3 >
-    velocity( const tk::Fields& U,
-              const std::array< std::vector< tk::real >, 3 >&,
-              const std::array< std::size_t, 4 >& N ) const
-    {
-      const auto rdof = g_inputdeck.get< tag::rdof >();
-      auto nmat = g_inputdeck.get< tag::multimat, tag::nmat >();<--- Shadow variable
-
-      std::array< std::array< tk::real, 4 >, 3 > v;
-      v[0] = U.extract( momentumDofIdx(nmat, 0, rdof, 0), N );
-      v[1] = U.extract( momentumDofIdx(nmat, 1, rdof, 0), N );
-      v[2] = U.extract( momentumDofIdx(nmat, 2, rdof, 0), N );
-
-      std::vector< std::array< tk::real, 4 > > ar;
-      ar.resize(nmat);
-      for (std::size_t k=0; k<nmat; ++k)
-        ar[k] = U.extract( densityDofIdx(nmat, k, rdof, 0), N );
-
-      std::array< tk::real, 4 > r{{ 0.0, 0.0, 0.0, 0.0 }};
-      for (std::size_t i=0; i<r.size(); ++i) {
-        for (std::size_t k=0; k<nmat; ++k)
-          r[i] += ar[k][i];
-      }
-
-      std::transform( r.begin(), r.end(), v[0].begin(), v[0].begin(),
-                      []( tk::real s, tk::real& d ){ return d /= s; } );
-      std::transform( r.begin(), r.end(), v[1].begin(), v[1].begin(),
-                      []( tk::real s, tk::real& d ){ return d /= s; } );
-      std::transform( r.begin(), r.end(), v[2].begin(), v[2].begin(),
-                      []( tk::real s, tk::real& d ){ return d /= s; } );
-      return v;
-    }
-
-    //! Return a map that associates user-specified strings to functions
-    //! \return Map that associates user-specified strings to functions that
-    //!   compute relevant quantities to be output to file
-    std::map< std::string, tk::GetVarFn > OutVarFn() const
-    { return MultiMatOutVarFn(); }
-
-    //! Return analytic field names to be output to file
-    //! \return Vector of strings labelling analytic fields output in file
-    std::vector< std::string > analyticFieldNames() const {
-      auto nmat = g_inputdeck.get< eq, tag::nmat >();<--- Shadow variable
-
-      return MultiMatFieldNames(nmat);
-    }
-
-    //! Return time history field names to be output to file
-    //! \return Vector of strings labelling time history fields output in file
-    std::vector< std::string > histNames() const {
-      return MultiMatHistNames();
-    }
-
-    //! Return surface field output going to file
-    std::vector< std::vector< tk::real > >
-    surfOutput( const std::map< int, std::vector< std::size_t > >&,
-                tk::Fields& ) const
-    {
-      std::vector< std::vector< tk::real > > s; // punt for now
-      return s;
-    }
-
-    //! Return time history field output evaluated at time history points
-    //! \param[in] h History point data
-    //! \param[in] inpoel Element-node connectivity
-    //! \param[in] coord Array of nodal coordinates
-    //! \param[in] U Array of unknowns
-    //! \param[in] P Array of primitive quantities
-    //! \return Vector of time history output of bulk flow quantities (density,
-    //!   velocity, total energy, and pressure) evaluated at time history points
-    std::vector< std::vector< tk::real > >
-    histOutput( const std::vector< HistData >& h,
-                const std::vector< std::size_t >& inpoel,
-                const tk::UnsMesh::Coords& coord,
-                const tk::Fields& U,
-                const tk::Fields& P ) const
-    {
-      const auto rdof = g_inputdeck.get< tag::rdof >();
-      auto nmat = g_inputdeck.get< tag::multimat, tag::nmat >();<--- Shadow variable
-
-      const auto& x = coord[0];
-      const auto& y = coord[1];
-      const auto& z = coord[2];
-
-      std::vector< std::vector< tk::real > > Up(h.size());
-
-      std::size_t j = 0;
-      for (const auto& p : h) {
-        auto e = p.get< tag::elem >();
-        auto chp = p.get< tag::coord >();
-
-        // Evaluate inverse Jacobian
-        std::array< std::array< tk::real, 3>, 4 > cp{{
-          {{ x[inpoel[4*e  ]], y[inpoel[4*e  ]], z[inpoel[4*e  ]] }},
-          {{ x[inpoel[4*e+1]], y[inpoel[4*e+1]], z[inpoel[4*e+1]] }},
-          {{ x[inpoel[4*e+2]], y[inpoel[4*e+2]], z[inpoel[4*e+2]] }},
-          {{ x[inpoel[4*e+3]], y[inpoel[4*e+3]], z[inpoel[4*e+3]] }} }};
-        auto J = tk::inverseJacobian( cp[0], cp[1], cp[2], cp[3] );
+    next();
+
+  }
+}
+
+void
+Refiner::next()
+// *****************************************************************************
+// Continue after finishing a refinement step
+// *****************************************************************************
+{
+  if (m_mode == RefMode::T0REF) {
+
+    // Remove initial mesh refinement step from list
+    if (!m_initref.empty()) m_initref.pop_back();
+    // Continue to next initial AMR step or finish
+    if (!m_initref.empty()) t0ref(); else endt0ref();
+
+  } else if (m_mode == RefMode::DTREF) {
+
+    // Send new mesh, solution, and communication data back to PDE worker
+    m_scheme[m_meshid].ckLocal< Scheme::resizePostAMR >( thisIndex,  m_ginpoel,
+      m_el, m_coord, m_addedNodes, m_addedTets, m_removedNodes, m_amrNodeMap,
+      m_nodeCommMap, m_bface, m_bnode, m_triinpoel, m_elemblockid );
+
+  } else if (m_mode == RefMode::OUTREF) {
+
+    // Store field output mesh
+    m_outref_ginpoel = m_ginpoel;
+    m_outref_el = m_el;
+    m_outref_coord = m_coord;
+    m_outref_addedNodes = m_addedNodes;
+    m_outref_addedTets = m_addedTets;
+    m_outref_nodeCommMap = m_nodeCommMap;
+    m_outref_bface = m_bface;
+    m_outref_bnode = m_bnode;
+    m_outref_triinpoel = m_triinpoel;
+
+    // Derefine mesh to the state previous to field output
+    outref( m_outref_bface, m_outref_bnode, m_outref_triinpoel, m_writeCallback,
+            RefMode::OUTDEREF );
+
+  } else if (m_mode == RefMode::OUTDEREF) {
+
+    // Send field output mesh to PDE worker
+    m_scheme[m_meshid].ckLocal< Scheme::extractFieldOutput >( thisIndex,
+      m_outref_ginpoel, m_outref_el, m_outref_coord, m_outref_addedNodes,
+      m_outref_addedTets, m_outref_nodeCommMap, m_outref_bface, m_outref_bnode,
+      m_outref_triinpoel, m_writeCallback );
+
+  } else Throw( "RefMode not implemented" );
+}
+
+void
+Refiner::endt0ref()
+// *****************************************************************************
+// Finish initial mesh refinement
+//! \details This function is called as after initial mesh refinement has
+//!   finished. If initial mesh reifnement was not configured by the user, this
+//!   is the point where we continue after the constructor, by computing the
+//!   total number of elements across the whole problem.
+// *****************************************************************************
+{
+  // create sorter Charm++ chare array elements using dynamic insertion
+  m_sorter[ thisIndex ].insert( m_meshid, m_host, m_meshwriter, m_cbs, m_scheme,
+    CkCallback(CkIndex_Refiner::reorder(), thisProxy[thisIndex]), m_ginpoel,
+    m_coordmap, m_el, m_bface, m_triinpoel, m_bnode, m_elemblockid, m_nchare );
+
+  // Compute final number of cells across whole problem
+  std::vector< std::size_t >
+    meshdata{ m_meshid, m_ginpoel.size()/4, m_coord[0].size() };
+  contribute( meshdata, CkReduction::sum_ulong, m_cbr.get< tag::refined >() );
+
+  // // Free up memory if no dtref
+  // if (!g_inputdeck.get< tag::amr, tag::dtref >()) {
+  //   tk::destroy( m_ginpoel );
+  //   tk::destroy( m_el );
+  //   tk::destroy( m_coordmap );
+  //   tk::destroy( m_coord );
+  //   tk::destroy( m_bface );
+  //   tk::destroy( m_bnode );
+  //   tk::destroy( m_triinpoel );
+  //   tk::destroy( m_initref );
+  //   tk::destroy( m_ch );
+  //   tk::destroy( m_edgech );
+  //   tk::destroy( m_chedge );
+  //   tk::destroy( m_localEdgeData );
+  //   tk::destroy( m_remoteEdgeData );
+  //   tk::destroy( m_remoteEdges );
+  //   tk::destroy( m_intermediates );
+  //   tk::destroy( m_nodeCommMap );
+  //   tk::destroy( m_oldTets );
+  //   tk::destroy( m_addedNodes );
+  //   tk::destroy( m_addedTets );
+  //   tk::destroy( m_coarseBndFaces );
+  //   tk::destroy( m_coarseBndNodes );
+  //   tk::destroy( m_rid );
+//  //   tk::destroy( m_oldrid );
+  //   tk::destroy( m_lref );
+//  //   tk::destroy( m_oldparent );
+  // }
+}
+
+void
+Refiner::uniformRefine()
+// *****************************************************************************
+// Do uniform mesh refinement
+// *****************************************************************************
+{
+  // Do uniform refinement
+  m_refiner.mark_uniform_refinement();
+
+  // Update our extra-edge store based on refiner
+  updateEdgeData();
+
+  // Set number of extra edges to be zero, skipping correction (if this is the
+  // only step in this refinement step)
+  m_extra = 0;
+}
+
+void
+Refiner::uniformDeRefine()
+// *****************************************************************************
+// Do uniform mesh derefinement
+// *****************************************************************************
+{
+  // Do uniform derefinement
+  m_refiner.mark_uniform_derefinement();
+
+  // Update our extra-edge store based on refiner
+  updateEdgeData();
+
+  // Set number of extra edges to be zero, skipping correction (if this is the
+  // only step in this refinement step)
+  m_extra = 0;
+}
+
+Refiner::EdgeError
+Refiner::errorsInEdges(
+  std::size_t npoin,
+  const std::pair< std::vector<std::size_t>, std::vector<std::size_t> >& esup,
+  const tk::Fields& u ) const
+// *****************************************************************************
+//  Compute errors in edges
+//! \param[in] npoin Number nodes in current mesh (partition)
+//! \param[in] esup Elements surrounding points linked vectors
+//! \param[in] u Solution evaluated at mesh nodes for all scalar components
+//! \return A map associating errors (real values between 0.0 and 1.0 incusive)
+//!   to edges (2 local node IDs)
+// *****************************************************************************
+{
+  // Get the indices (in the system of systems) of refinement variables and the
+  // error indicator configured
+  auto ncomp = g_inputdeck.get< tag::ncomp >();
+  auto errtype = g_inputdeck.get< tag::amr, tag::error >();
+
+  // Compute points surrounding points
+  auto psup = tk::genPsup( m_inpoel, 4, esup );
+
+  // Compute errors in ICs and define refinement criteria for edges
+  AMR::Error error;
+  EdgeError edgeError;
+
+  for (std::size_t p=0; p<npoin; ++p) { // for all mesh nodes on this chare
+    for (auto q : tk::Around(psup,p)) { // for all nodes surrounding p
+      tk::real cmax = 0.0;
+      AMR::edge_t e(p,q);
+      for (std::size_t i=0; i<ncomp; ++i) { // for all refinement variables
+        auto c = error.scalar( u, e, i, m_coord, m_inpoel, esup, errtype );
+        if (c > cmax) cmax = c;        // find max error at edge
+      }
+      edgeError[ {{p,q}} ] = cmax;       // associate error to edge
+    }
+  }
+
+  return edgeError;
+}
+
+tk::Fields
+Refiner::solution( std::size_t npoin,
+                   const std::pair< std::vector< std::size_t >,
+                                    std::vector< std::size_t > >& esup ) const
+// *****************************************************************************
+//  Update (or evaluate) solution on current mesh
+//! \param[in] npoin Number nodes in current mesh (partition)
+//! \param[in] esup Elements surrounding points linked vectors
+//! \return Solution updated/evaluated for all scalar components
+// *****************************************************************************
+{
+  // Get solution whose error to evaluate
+  tk::Fields u;
+
+  if (m_mode == RefMode::T0REF) {
+
+    // Evaluate initial conditions at mesh nodes
+    u = nodeinit( npoin, esup );
+
+  } else if (m_mode == RefMode::DTREF) {
 
-        // evaluate solution at history-point
-        std::array< tk::real, 3 > dc{{chp[0]-cp[0][0], chp[1]-cp[0][1],
-          chp[2]-cp[0][2]}};
-        auto B = tk::eval_basis(rdof, tk::dot(J[0],dc), tk::dot(J[1],dc),
-          tk::dot(J[2],dc));
-        auto uhp = eval_state(m_ncomp, rdof, rdof, e, U, B);
-        auto php = eval_state(m_nprim, rdof, rdof, e, P, B);
-
-        // store solution in history output vector
-        Up[j].resize(6, 0.0);
-        for (std::size_t k=0; k<nmat; ++k) {
-          Up[j][0] += uhp[densityIdx(nmat,k)];
-          Up[j][4] += uhp[energyIdx(nmat,k)];
-          Up[j][5] += php[pressureIdx(nmat,k)];
-        }
-        Up[j][1] = php[velocityIdx(nmat,0)];
-        Up[j][2] = php[velocityIdx(nmat,1)];
-        Up[j][3] = php[velocityIdx(nmat,2)];
-        ++j;
-      }
-
-      return Up;
-    }
-
-    //! Return names of integral variables to be output to diagnostics file
-    //! \return Vector of strings labelling integral variables output
-    std::vector< std::string > names() const
-    {
-      auto nmat = g_inputdeck.get< tag::multimat, tag::nmat >();<--- Shadow variable
-      return MultiMatDiagNames(nmat);
-    }
-
-    //! Return analytic solution (if defined by Problem) at xi, yi, zi, t
-    //! \param[in] xi X-coordinate at which to evaluate the analytic solution
-    //! \param[in] yi Y-coordinate at which to evaluate the analytic solution
-    //! \param[in] zi Z-coordinate at which to evaluate the analytic solution
-    //! \param[in] t Physical time at which to evaluate the analytic solution
-    //! \return Vector of analytic solution at given location and time
-    std::vector< tk::real >
-    analyticSolution( tk::real xi, tk::real yi, tk::real zi, tk::real t ) const
-    { return Problem::analyticSolution( m_ncomp, m_mat_blk, xi, yi, zi, t ); }
-
-    //! Return analytic solution for conserved variables
-    //! \param[in] xi X-coordinate at which to evaluate the analytic solution
-    //! \param[in] yi Y-coordinate at which to evaluate the analytic solution
-    //! \param[in] zi Z-coordinate at which to evaluate the analytic solution
-    //! \param[in] t Physical time at which to evaluate the analytic solution
-    //! \return Vector of analytic solution at given location and time
-    std::vector< tk::real >
-    solution( tk::real xi, tk::real yi, tk::real zi, tk::real t ) const
-    { return Problem::initialize( m_ncomp, m_mat_blk, xi, yi, zi, t ); }
-
-    //! Return cell-averaged specific total energy for an element
-    //! \param[in] e Element id for which total energy is required
-    //! \param[in] unk Vector of conserved quantities
-    //! \return Cell-averaged specific total energy for given element
-    tk::real sp_totalenergy(std::size_t e, const tk::Fields& unk) const
-    {
-      const auto rdof = g_inputdeck.get< tag::rdof >();
-      auto nmat = g_inputdeck.get< tag::multimat, tag::nmat >();<--- Shadow variable
-
-      tk::real sp_te(0.0);
-      // sum each material total energy
-      for (std::size_t k=0; k<nmat; ++k) {
-        sp_te += unk(e, energyDofIdx(nmat,k,rdof,0));
-      }
-      return sp_te;
-    }
+    // Query current solution
+    u = m_scheme[m_meshid].ckLocal< Scheme::solution >( thisIndex );
+ 
+    const auto scheme = g_inputdeck.get< tag::scheme >();
+    const auto centering = ctr::Scheme().centering( scheme );
+    if (centering == tk::Centering::ELEM) {
+
+      // ...
+      Throw("Element-based solution handling not implemented in Refiner");
+
+    }
+
+  } else if (m_mode == RefMode::OUTREF) {
+
+
+
+  } else if (m_mode == RefMode::OUTDEREF) {
+
+
+
+  } else Throw( "RefMode not implemented" );
+
+  return u;
+}
+
+void
+Refiner::errorRefine()
+// *****************************************************************************
+// Do error-based mesh refinement and derefinement
+// *****************************************************************************
+{
+  // Find number of nodes in old mesh
+  auto npoin = tk::npoin_in_graph( m_inpoel );
+  // Generate edges surrounding points in old mesh
+  auto esup = tk::genEsup( m_inpoel, 4 );
+
+  // Update solution on current mesh
+  const auto& u = solution( npoin, esup );
+  Assert( u.nunk() == npoin, "Solution uninitialized or wrong size" );
+
+  using AMR::edge_t;
+  using AMR::edge_tag;
+
+  // Compute error in edges. Tag edge for refinement if error exceeds
+  // refinement tolerance, tag edge for derefinement if error is below
+  // derefinement tolerance.
+  auto tolref = g_inputdeck.get< tag::amr, tag::tol_refine >();
+  auto tolderef = g_inputdeck.get< tag::amr, tag::tol_derefine >();
+  std::vector< std::pair< edge_t, edge_tag > > tagged_edges;
+  for (const auto& e : errorsInEdges(npoin,esup,u)) {
+    if (e.second > tolref) {
+      tagged_edges.push_back( { edge_t( m_rid[e.first[0]], m_rid[e.first[1]] ),
+                                edge_tag::REFINE } );
+    } else if (e.second < tolderef) {
+      tagged_edges.push_back( { edge_t( m_rid[e.first[0]], m_rid[e.first[1]] ),
+                                edge_tag::DEREFINE } );
+    }
+  }
+
+  // Do error-based refinement
+  m_refiner.mark_error_refinement( tagged_edges );
+
+  // Update our extra-edge store based on refiner
+  updateEdgeData();
+
+  // Set number of extra edges to a nonzero number, triggering correction
+  m_extra = 1;
+}
 
-  private:
-    //! Number of components in this PDE system
-    const ncomp_t m_ncomp;
-    //! Number of primitive quantities stored in this PDE system
-    const ncomp_t m_nprim;
-    //! Riemann solver
-    tk::RiemannFluxFn m_riemann;
-    //! BC configuration
-    BCStateFn m_bc;
-    //! EOS material block
-    std::vector< EOS > m_mat_blk;
-
-    //! Evaluate conservative part of physical flux function for this PDE system
-    //! \param[in] ncomp Number of scalar components in this PDE system
-    //! \param[in] ugp Numerical solution at the Gauss point at which to
-    //!   evaluate the flux
-    //! \return Flux vectors for all components in this PDE system
-    //! \note The function signature must follow tk::FluxFn
-    static tk::FluxFn::result_type
-    flux( ncomp_t ncomp,
-          const std::vector< EOS >& mat_blk,
-          const std::vector< tk::real >& ugp,
-          const std::vector< std::array< tk::real, 3 > >& )
-    {
-      auto nmat = g_inputdeck.get< tag::multimat, tag::nmat >();<--- Shadow variable
-
-      return tk::fluxTerms(ncomp, nmat, mat_blk, ugp);
-    }
-
-    //! \brief Boundary state function providing the left and right state of a
-    //!   face at Dirichlet boundaries
-    //! \param[in] ncomp Number of scalar components in this PDE system
-    //! \param[in] mat_blk EOS material block
-    //! \param[in] ul Left (domain-internal) state
-    //! \param[in] x X-coordinate at which to compute the states
-    //! \param[in] y Y-coordinate at which to compute the states
-    //! \param[in] z Z-coordinate at which to compute the states
-    //! \param[in] t Physical time
-    //! \return Left and right states for all scalar components in this PDE
-    //!   system
-    //! \note The function signature must follow tk::StateFn. For multimat, the
-    //!   left or right state is the vector of conserved quantities, followed by
-    //!   the vector of primitive quantities appended to it.
-    static tk::StateFn::result_type
-    dirichlet( ncomp_t ncomp,
-               const std::vector< EOS >& mat_blk,
-               const std::vector< tk::real >& ul, tk::real x, tk::real y,
-               tk::real z, tk::real t, const std::array< tk::real, 3 >& )
-    {
-      auto nmat = g_inputdeck.get< tag::multimat, tag::nmat >();<--- Shadow variable
-      const auto& solidx = g_inputdeck.get<
-        tag::matidxmap, tag::solidx >();
-
-      [[maybe_unused]] auto nsld = numSolids(nmat, solidx);
-
-      auto ur = Problem::initialize( ncomp, mat_blk, x, y, z, t );
-      Assert( ur.size() == ncomp, "Incorrect size for boundary state vector" );
-
-      ur.resize(ul.size());
-
-      tk::real rho(0.0);
-      for (std::size_t k=0; k<nmat; ++k)
-        rho += ur[densityIdx(nmat, k)];
-
-      // get primitives in boundary state
-
-      // velocity
-      ur[ncomp+velocityIdx(nmat, 0)] = ur[momentumIdx(nmat, 0)] / rho;
-      ur[ncomp+velocityIdx(nmat, 1)] = ur[momentumIdx(nmat, 1)] / rho;
-      ur[ncomp+velocityIdx(nmat, 2)] = ur[momentumIdx(nmat, 2)] / rho;
-
-      // material pressures
-      for (std::size_t k=0; k<nmat; ++k)
-      {
-        auto gk = getDeformGrad(nmat, k, ur);
-        ur[ncomp+pressureIdx(nmat, k)] = mat_blk[k].compute< EOS::pressure >(
-          ur[densityIdx(nmat, k)], ur[ncomp+velocityIdx(nmat, 0)],
-          ur[ncomp+velocityIdx(nmat, 1)], ur[ncomp+velocityIdx(nmat, 2)],
-          ur[energyIdx(nmat, k)], ur[volfracIdx(nmat, k)], k, gk );
-      }
+void
+Refiner::edgelistRefine()
+// *****************************************************************************
+// Do mesh refinement based on user explicitly tagging edges
+// *****************************************************************************
+{
+  // Get user-defined node-pairs (edges) to tag for refinement
+  const auto& edgenodelist = g_inputdeck.get< tag::amr, tag::edgelist >();
+
+  if (!edgenodelist.empty()) {  // if user explicitly tagged edges
+    // Find number of nodes in old mesh
+    auto npoin = tk::npoin_in_graph( m_inpoel );
+    // Generate edges surrounding points in old mesh
+    auto esup = tk::genEsup( m_inpoel, 4 );
+    auto psup = tk::genPsup( m_inpoel, 4, esup );
+
+    EdgeSet useredges;
+    for (std::size_t i=0; i<edgenodelist.size()/2; ++i)
+      useredges.insert( {{ {edgenodelist[i*2+0], edgenodelist[i*2+1]} }} );
+
+    using AMR::edge_t;
+    using AMR::edge_tag;
+
+    // Tag edges the user configured
+    std::vector< std::pair< edge_t, edge_tag > > tagged_edges;
+    for (std::size_t p=0; p<npoin; ++p)        // for all mesh nodes on this chare
+      for (auto q : tk::Around(psup,p)) {      // for all nodes surrounding p
+        Edge e{{ m_gid[p], m_gid[q] }};
+        auto f = useredges.find(e);
+        if (f != end(useredges)) { // tag edge if on user's list
+          tagged_edges.push_back( { edge_t( m_rid[p], m_rid[q] ),
+                                    edge_tag::REFINE } );
+          useredges.erase( f );
+        }
+      }
+
+    // Do error-based refinement
+    m_refiner.mark_error_refinement( tagged_edges );
+
+    // Update our extra-edge store based on refiner
+    updateEdgeData();
+
+    // Set number of extra edges to a nonzero number, triggering correction
+    m_extra = 1;
+  }
+}
+
+void
+Refiner::coordRefine()
+// *****************************************************************************
+// Do mesh refinement based on tagging edges based on end-point coordinates
+// *****************************************************************************
+{
+  // Get user-defined half-world coordinates
+  const auto& amr_coord = g_inputdeck.get< tag::amr, tag::coords >();
+  auto xminus = amr_coord.get< tag::xminus >();
+  auto xplus  = amr_coord.get< tag::xplus >();
+  auto yminus = amr_coord.get< tag::yminus >();
+  auto yplus  = amr_coord.get< tag::yplus >();
+  auto zminus = amr_coord.get< tag::zminus >();
+  auto zplus  = amr_coord.get< tag::zplus >();
+
+  // The default is the largest representable double
+  auto eps =
+    std::numeric_limits< tk::real >::epsilon();
+  const auto& amr_defcoord = g_inputdeck_defaults.get< tag::amr, tag::coords >();
+  auto xminus_default = amr_defcoord.get< tag::xminus >();
+  auto xplus_default = amr_defcoord.get< tag::xplus >();
+  auto yminus_default = amr_defcoord.get< tag::yminus >();
+  auto yplus_default = amr_defcoord.get< tag::yplus >();
+  auto zminus_default = amr_defcoord.get< tag::zminus >();
+  auto zplus_default = amr_defcoord.get< tag::zplus >();
+
+  // Decide if user has configured the half-world
+  bool xm = std::abs(xminus - xminus_default) > eps ? true : false;
+  bool xp = std::abs(xplus - xplus_default) > eps ? true : false;
+  bool ym = std::abs(yminus - yminus_default) > eps ? true : false;
+  bool yp = std::abs(yplus - yplus_default) > eps ? true : false;
+  bool zm = std::abs(zminus - zminus_default) > eps ? true : false;
+  bool zp = std::abs(zplus - zplus_default) > eps ? true : false;
 
-      Assert( ur.size() == ncomp+nmat+3+nsld*6, "Incorrect size for appended "
-              "boundary state vector" );
+  using AMR::edge_t;
+  using AMR::edge_tag;
 
-      return {{ std::move(ul), std::move(ur) }};
-    }
-
-    // Other boundary condition types that do not depend on "Problem" should be
-    // added in BCFunctions.hpp
-};
-
-} // dg::
-
-} // inciter::
-
-#endif // DGMultiMat_h
+  if (xm || xp || ym || yp || zm || zp) {       // if any half-world configured
+    // Find number of nodes in old mesh
+    auto npoin = tk::npoin_in_graph( m_inpoel );
+    // Generate edges surrounding points in old mesh
+    auto esup = tk::genEsup( m_inpoel, 4 );
+    auto psup = tk::genPsup( m_inpoel, 4, esup );
+    // Get access to node coordinates
+    const auto& x = m_coord[0];
+    const auto& y = m_coord[1];
+    const auto& z = m_coord[2];
+    // Compute edges to be tagged for refinement
+    std::vector< std::pair< edge_t, edge_tag > > tagged_edges;
+    for (std::size_t p=0; p<npoin; ++p)    // for all mesh nodes on this chare
+      for (auto q : tk::Around(psup,p)) {  // for all nodes surrounding p
+        Edge e{{p,q}};
+
+        bool t = true;
+        if (xm) { if (x[p]>xminus && x[q]>xminus) t = false; }
+        if (xp) { if (x[p]<xplus && x[q]<xplus) t = false; }
+        if (ym) { if (y[p]>yminus && y[q]>yminus) t = false; }
+        if (yp) { if (y[p]<yplus && y[q]<yplus) t = false; }
+        if (zm) { if (z[p]>zminus && z[q]>zminus) t = false; }
+        if (zp) { if (z[p]<zplus && z[q]<zplus) t = false; }
+
+        if (t) {
+          tagged_edges.push_back( { edge_t( m_rid[e[0]], m_rid[e[1]] ),
+                                    edge_tag::REFINE } );
+        }
+      }
+
+    // Do error-based refinement
+    m_refiner.mark_error_refinement( tagged_edges );
+
+    // Update our extra-edge store based on refiner
+    updateEdgeData();
+
+    // Set number of extra edges to a nonzero number, triggering correction
+    m_extra = 1;
+  }
+}
+
+tk::Fields
+Refiner::nodeinit( std::size_t npoin,
+                   const std::pair< std::vector< std::size_t >,
+                                    std::vector< std::size_t > >& esup ) const
+// *****************************************************************************
+// Evaluate initial conditions (IC) at mesh nodes
+//! \param[in] npoin Number points in mesh (on this chare)
+//! \param[in] esup Elements surrounding points as linked lists, see tk::genEsup
+//! \return Initial conditions (evaluated at t0) at nodes
+// *****************************************************************************
+{
+  auto t0 = g_inputdeck.get< tag::t0 >();
+  auto nprop = g_inputdeck.get< tag::ncomp >();
+
+  // Will store nodal ICs
+  tk::Fields u( m_coord[0].size(), nprop );
+
+  // Evaluate ICs differently depending on nodal or cell-centered discretization
+  const auto scheme = g_inputdeck.get< tag::scheme >();
+  const auto centering = ctr::Scheme().centering( scheme );
+  // list of nodes/elements at which box ICs are defined
+  std::vector< std::unordered_set< std::size_t > > inbox;
+  tk::real V = 1.0;
+  std::vector< tk::real > blkvols;
+  std::unordered_map< std::size_t, std::set< std::size_t > > nodeblockid,
+    elemblockid;
+
+  if (centering == tk::Centering::NODE) {
+
+    // Evaluate ICs for all scalar components integrated
+    g_cgpde[m_meshid].initialize( m_coord, u, t0, V, inbox, blkvols,
+      nodeblockid );
+
+  } else if (centering == tk::Centering::ELEM) {
+
+    auto esuel = tk::genEsuelTet( m_inpoel, esup ); // elems surrounding elements
+    // Initialize cell-based unknowns
+    tk::Fields ue( m_inpoel.size()/4, nprop );
+    auto lhs = ue;
+    auto geoElem = tk::genGeoElemTet( m_inpoel, m_coord );
+    if (scheme == ctr::SchemeType::FV) {
+    g_fvpde[m_meshid].lhs( geoElem, lhs );
+    g_fvpde[m_meshid].initialize( lhs, m_inpoel, m_coord, inbox, elemblockid,
+      ue, t0, esuel.size()/4 );
+    }
+    else {
+    g_dgpde[m_meshid].lhs( geoElem, lhs );
+    g_dgpde[m_meshid].initialize( lhs, m_inpoel, m_coord, inbox, elemblockid,
+      ue, t0, esuel.size()/4 );
+    }
+
+    // Transfer initial conditions from cells to nodes
+    for (std::size_t p=0; p<npoin; ++p) {    // for all mesh nodes on this chare
+      std::vector< tk::real > up( nprop, 0.0 );
+      tk::real vol = 0.0;
+      for (auto e : tk::Around(esup,p)) {       // for all cells around node p
+        // compute nodal volume: every element contributes their volume / 4
+        vol += geoElem(e,0) / 4.0;
+        // sum cell value to node weighed by cell volume / 4
+        for (std::size_t c=0; c<nprop; ++c)
+          up[c] += ue[e][c] * geoElem(e,0) / 4.0;
+      }
+      // store nodal value
+      for (std::size_t c=0; c<nprop; ++c) u(p,c) = up[c] / vol;
+    }
+
+  } else Throw( "Scheme centring not handled for nodal initialization" );
+
+  Assert( u.nunk() == m_coord[0].size(), "Size mismatch" );
+  Assert( u.nprop() == nprop, "Size mismatch" );
+
+  return u;
+}
+
+void
+Refiner::updateMesh()
+// *****************************************************************************
+// Update old mesh after refinement
+// *****************************************************************************
+{
+  // Get refined mesh connectivity
+  const auto& refinpoel = m_refiner.tet_store.get_active_inpoel();
+  Assert( refinpoel.size()%4 == 0, "Inconsistent refined mesh connectivity" );
+
+  // Generate unique node lists of old and refined mesh using local ids
+  auto rinpoel = m_inpoel;
+  tk::remap( rinpoel, m_rid );
+  std::unordered_set< std::size_t > old( begin(rinpoel), end(rinpoel) );
+  std::unordered_set< std::size_t > ref( begin(refinpoel), end(refinpoel) );
+
+  // Augment refiner id -> local node id map with newly added nodes
+  std::size_t l = m_lref.size();
+  for (auto r : ref) if (old.find(r) == end(old)) m_lref[r] = l++;
+
+  // Get nodal communication map from Discretization worker
+  if ( m_mode == RefMode::DTREF ||
+       m_mode == RefMode::OUTREF ||
+       m_mode == RefMode::OUTDEREF ) {
+    m_nodeCommMap =
+      m_scheme[m_meshid].disc()[thisIndex].ckLocal()->NodeCommMap();
+  }
+
+  // Update mesh and solution after refinement
+  newVolMesh( old, ref );
+
+  // Update mesh connectivity from refiner lib, remapping refiner to local ids
+  m_inpoel = m_refiner.tet_store.get_active_inpoel();
+  tk::remap( m_inpoel, m_lref );
+
+  // Update mesh connectivity with new global node ids
+  m_ginpoel = m_inpoel;
+  Assert( tk::uniquecopy(m_ginpoel).size() == m_coord[0].size(),
+          "Size mismatch" );
+  tk::remap( m_ginpoel, m_gid );
+
+  // Update boundary face and node information
+  newBndMesh( ref );
+
+  // Augment node communication map with newly added nodes on chare-boundary
+  if (m_mode == RefMode::DTREF || m_mode == RefMode::OUTREF) {
+    for (const auto& [ neighborchare, edges ] : m_remoteEdges) {
+      auto& nodes = tk::ref_find( m_nodeCommMap, neighborchare );
+      for (const auto& e : edges) {
+        // If parent nodes were part of the node communication map for chare
+        if (nodes.find(e[0]) != end(nodes) && nodes.find(e[1]) != end(nodes)) {
+          // Add new node if local id was generated for it
+          auto n = Hash<2>()( e );
+          if (m_lid.find(n) != end(m_lid)) nodes.insert( n );
+        }
+      }
+    }
+  }
+
+  // Ensure valid mesh after refinement
+  Assert( tk::positiveJacobians( m_inpoel, m_coord ),
+          "Refined mesh cell Jacobian non-positive" );
+
+  Assert( tk::conforming( m_inpoel, m_coord, true, m_rid ),
+          "Chare-"+std::to_string(thisIndex)+
+          " mesh not conforming after updating mesh after mesh refinement" );
+
+  // Perform leak test on new mesh
+  Assert( !tk::leakyPartition(
+            tk::genEsuelTet( m_inpoel, tk::genEsup(m_inpoel,4) ),
+            m_inpoel, m_coord ),
+          "Refined mesh partition leaky" );
+}
+
+void
+Refiner::newVolMesh( const std::unordered_set< std::size_t >& old,
+                     const std::unordered_set< std::size_t >& ref )
+// *****************************************************************************
+//  Compute new volume mesh after mesh refinement
+//! \param[in] old Unique nodes of the old (unrefined) mesh using
+//!   refiner-lib ids
+//! \param[in] ref Unique nodes of the refined mesh using refiner-lib ids
+// *****************************************************************************
+{
+  const auto& x = m_coord[0];
+  const auto& y = m_coord[1];
+  const auto& z = m_coord[2];
+
+  // Generate coordinates and ids to newly added nodes after refinement
+  std::unordered_map< std::size_t, std::size_t > gid_add;
+  tk::destroy( m_addedNodes );
+  tk::destroy( m_removedNodes );
+  tk::destroy( m_amrNodeMap );
+  for (auto r : ref) {               // for all unique nodes of the refined mesh
+    if (old.find(r) == end(old)) {   // if node is newly added
+      // get (local) parent ids of newly added node
+      auto p = m_refiner.node_connectivity.get( r );
+      Assert(p[0] != p[1], "Node without parent edge in newVolMesh");
+      Assert( old.find(p[0]) != end(old) && old.find(p[1]) != end(old),
+              "Parent(s) not in old mesh" );
+      // local parent ids
+      decltype(p) lp{{tk::cref_find(m_lref,p[0]), tk::cref_find(m_lref,p[1])}};
+      // global parent ids
+      decltype(p) gp{{m_gid[lp[0]], m_gid[lp[1]]}};
+      // generate new global ID for newly added node
+      auto g = Hash<2>()( gp );
+
+      // if node added by AMR lib has not yet been added to Refiner's new mesh
+      if (m_coordmap.find(g) == end(m_coordmap)) {
+        Assert( g >= old.size(), "Hashed id overwriting old id" );
+        Assert( m_lid.find(g) == end(m_lid),
+                "Overwriting entry global->local node ID map" );
+        auto l = tk::cref_find( m_lref, r );
+        // store newly added node id and their parent ids (local ids)
+        m_addedNodes[r] = lp;   // key = r for later update to local
+        // assign new node to refiner->global map
+        gid_add[r] = g; // key = r for later search
+        // assign new node to global->local map
+        m_lid[g] = l;
+        // generate and store coordinates for newly added node
+        m_coordmap.insert( {g, {{ (x[lp[0]] + x[lp[1]])/2.0,
+                                  (y[lp[0]] + y[lp[1]])/2.0,
+                                  (z[lp[0]] + z[lp[1]])/2.0 }} } );
+      }
+    }
+  }
+  tk::destroy( m_coord );
+
+  // generate a node map based on oldnodes+addednodes
+  std::vector< size_t > nodeVec(m_coordmap.size());
+  for (size_t j=0; j<nodeVec.size(); ++j) {
+    nodeVec[j] = j;
+  }
+
+  // Remove coordinates and ids of removed nodes due to derefinement
+  std::unordered_map< std::size_t, std::size_t > gid_rem;
+  for (auto o : old) {               // for all unique nodes of the old mesh
+    if (ref.find(o) == end(ref)) {   // if node is no longer in new mesh
+      auto l = tk::cref_find( m_lref, o );
+      auto g = m_gid[l];
+      // store local-ids of removed nodes
+      m_removedNodes.insert(l);
+      // remove derefined nodes from node comm map
+      for (auto& [neighborchare, sharednodes] : m_nodeCommMap) {
+        if (sharednodes.find(g) != sharednodes.end()) {
+          sharednodes.erase(g);
+        }
+      }
+      gid_rem[l] = g;
+      m_lid.erase( g );
+      m_coordmap.erase( g );
+    }
+  }
+
+  // update the node map by removing the derefined nodes
+  if (m_mode == RefMode::DTREF && m_removedNodes.size() > 0) {
+    // remove derefined nodes
+    size_t remCount = 0;
+    size_t origSize = nodeVec.size();
+    for (size_t j=0; j<origSize; ++j) {
+      auto nd = nodeVec[j-remCount];
+
+      bool no_change = false;
+      size_t nodeidx = 0;
+      for (const auto& rn : m_removedNodes) {
+        if (nd < *m_removedNodes.cbegin()) {
+          no_change = true;
+          break;
+        }
+        else if (nd <= rn) {
+          nodeidx = rn;
+          break;
+        }
+      }
+
+      // if node is out-or-range of removed nodes list, continue with next entry
+      if (no_change)
+        continue;
+      // if not is within range of removed nodes list, erase node appropriately
+      else if (nodeidx == nd) {
+        //! Difference type for iterator/pointer arithmetics
+        using diff_type = std::vector< std::size_t >::difference_type;
+        nodeVec.erase(nodeVec.begin()+static_cast< diff_type >(j-remCount));
+        ++remCount;
+      }
+    }
+
+    Assert(remCount == m_removedNodes.size(), "Incorrect number of nodes removed "
+      "from node map.");
+  }
+
+  // invert node vector to get node map
+  for (size_t i=0; i<nodeVec.size(); ++i) {
+    m_amrNodeMap[nodeVec[i]] = i;
+  }
+
+  //// Save previous states of refiner-local node id maps before update
+  //m_oldrid = m_rid;
+  //m_oldlref = m_lref;
+
+  // Generate new node id maps for nodes kept
+  tk::destroy( m_lref );
+  std::vector< std::size_t > rid( ref.size() );
+  std::vector< std::size_t > gid( ref.size() );
+  std::size_t l = 0;    // will generate new local node id
+  for (std::size_t i=0; i<m_gid.size(); ++i) {
+    if (gid_rem.find(i) == end(gid_rem)) {
+      gid[l] = m_gid[i];
+      rid[l] = m_rid[i];
+      m_lref[ m_rid[i] ] = l;
+      ++l;
+    }
+  }
+  // Add newly added nodes due to refinement to node id maps
+  decltype(m_addedNodes) addedNodes( m_addedNodes.size() );<--- Variable 'addedNodes' is assigned a value that is never used.
+  for (const auto& n : gid_add) {
+    auto r = n.first;
+    auto g = n.second;
+    gid[l] = g;
+    rid[l] = r;<--- Variable 'rid[l]' is assigned a value that is never used.
+    Assert(m_lref.find(r) == m_lref.end(), "Overwriting lref");
+    m_lref[r] = l;
+    auto it = m_addedNodes.find( r );
+    Assert( it != end(m_addedNodes), "Cannot find added node" );
+    addedNodes[l] = std::move(it->second);
+    addedNodes.at(l)[0] = m_amrNodeMap[addedNodes.at(l)[0]];
+    addedNodes.at(l)[1] = m_amrNodeMap[addedNodes.at(l)[1]];
+    ++l;
+  }
+  Assert( m_lref.size() == ref.size(), "Size mismatch" );
+  //for (auto r : ref) {
+  //  Assert(m_lref.find(r) != m_lref.end(), "Node missing in lref");
+  //}
+  //const auto& int_list = m_refiner.tet_store.intermediate_list;
+  //for (auto in : int_list) {
+  //  Assert(m_lref.find(in) != m_lref.end(), "Interm node missing in lref: "
+  //    + std::to_string(in));
+  //}
+  m_rid = std::move( rid );
+  Assert( m_rid.size() == ref.size(), "Size mismatch" );
+  m_addedNodes = std::move( addedNodes );
+
+  // Update node coordinates, ids, and id maps
+  auto& rx = m_coord[0];
+  auto& ry = m_coord[1];
+  auto& rz = m_coord[2];
+  rx.resize( ref.size() );
+  ry.resize( ref.size() );
+  rz.resize( ref.size() );
+  for (std::size_t i=0; i<gid.size(); ++i) {
+    tk::ref_find( m_lid, gid[i] ) = i;
+    const auto& c = tk::cref_find( m_coordmap, gid[i] );
+    rx[i] = c[0];
+    ry[i] = c[1];
+    rz[i] = c[2];
+  }
+  m_gid = std::move( gid );
+  Assert( m_gid.size() == m_lid.size() && m_gid.size() == ref.size(),
+    "Size mismatch" );
+}
+
+std::unordered_set< std::size_t >
+Refiner::ancestors( std::size_t n )
+// *****************************************************************************
+// Find the oldest parents of a mesh node in the AMR hierarchy
+//! \param[in] n Local node id whose ancestors to search
+//! \return Parents of local node id from the coarsest (original) mesh
+// *****************************************************************************
+{
+  auto d = m_refiner.node_connectivity.get( m_rid[n] );
+  decltype(d) p{{ tk::cref_find( m_lref, d[0] ),
+                  tk::cref_find( m_lref, d[1] ) }};
+
+  std::unordered_set< std::size_t > s;
+
+  if (p != AMR::node_pair_t{{n,n}}) {
+    auto q = ancestors( p[0] );
+    s.insert( begin(q), end(q) );
+    auto r = ancestors( p[1] );
+    s.insert( begin(r), end(r) );
+  } else {
+    s.insert( begin(p), end(p) );
+  }
+
+  return s;
+}
+
+Refiner::BndFaceData
+Refiner::boundary()
+// *****************************************************************************
+//  Generate boundary data structures used to update refined/derefined boundary
+//  faces and nodes of side sets
+//! \return A tuple of boundary face data
+//! \details The output of this function is used to regenerate physical boundary
+//!   face and node data structures after refinement, see updateBndData().
+// *****************************************************************************
+{
+  // Generate the inverse of AMR's tet store.
+  std::unordered_map< Tet, std::size_t, Hash<4>, Eq<4> > invtets;
+  for (const auto& [key, tet] : m_refiner.tet_store.tets)
+    invtets[ tet ] = key;
+
+  //std::cout << thisIndex << " invt: " << invtets.size() << '\n';
+  //std::cout << thisIndex << " active inpoel size: " << m_refiner.tet_store.get_active_inpoel().size() << '\n';
+  //std::cout << thisIndex << " marked derefinement size: " << m_refiner.tet_store.marked_derefinements.size() << '\n';
+
+  // Generate data structure pcFaceTets for the new (post-AMR) mesh:
+  // pcFaceTets is a map that associates all triangle boundary faces (physical
+  // and chare) to the id of the tet adjacent to the said face.
+  // Key: Face-nodes' global id; Value: tet-id.
+  std::unordered_map< Face, std::size_t, Hash<3>, Eq<3> > pcFaceTets;
+  auto esuel = tk::genEsuelTet( m_inpoel, tk::genEsup(m_inpoel,4) );
+  for (std::size_t e=0; e<esuel.size()/4; ++e) {
+    auto m = e*4;
+    for (std::size_t f=0; f<4; ++f) {
+      if (esuel[m+f] == -1) {  // if a face does not have an adjacent tet
+        Face b{{ m_ginpoel[ m+tk::lpofa[f][0] ],
+                 m_ginpoel[ m+tk::lpofa[f][1] ],
+                 m_ginpoel[ m+tk::lpofa[f][2] ] }};
+        Assert( m_inpoel[m+0] < m_rid.size() &&
+                m_inpoel[m+1] < m_rid.size() &&
+                m_inpoel[m+2] < m_rid.size() &&
+                m_inpoel[m+3] < m_rid.size(), "Indexing out of rid" );
+        Tet t{{ m_rid[ m_inpoel[m+0] ], m_rid[ m_inpoel[m+1] ],
+                m_rid[ m_inpoel[m+2] ], m_rid[ m_inpoel[m+3] ] }};
+        //Tet t{{ m_inpoel[m+0], m_inpoel[m+1],
+        //        m_inpoel[m+2], m_inpoel[m+3] }};
+        // associate tet id to adjacent (physical or chare) boundary face
+        auto i = invtets.find( t );
+        Assert(m_refiner.tet_store.is_active(i->second),
+          "Inactive element while regenerating boundary data");
+        if (i != end(invtets)) {
+          //std::cout << "refacetets: " <<
+          //  b[0] << "-" << b[1] << "-" << b[2] << std::endl;
+          pcFaceTets[ b ] = i->second;
+        } else {
+          Throw("Active element not found in tet_store");
+        }
+      }
+    }
+  }
+
+  // Generate child->parent tet and id maps after refinement/derefinement step
+//  tk::destroy( m_oldparent );
+  m_addedTets.clear();
+  std::size_t p = 0;
+  std::size_t c = 0;<--- Variable 'c' is assigned a value that is never used.
+  const auto& tet_store = m_refiner.tet_store;
+  for (const auto& t : tet_store.tets) {
+    // query number of children of tet
+    auto nc = tet_store.data( t.first ).children.size();
+    for (decltype(nc) i=0; i<nc; ++i ) {      // for all child tets
+      // get child tet id
+      auto childtet = tet_store.get_child_id( t.first, i );
+      auto ct = tet_store.tets.find( childtet );
+      Assert(ct != tet_store.tets.end(), "Child not found in tet store");
+//      //auto cA = tk::cref_find( m_lref, ct->second[0] );
+//      //auto cB = tk::cref_find( m_lref, ct->second[1] );
+//      //auto cC = tk::cref_find( m_lref, ct->second[2] );
+//      //auto cD = tk::cref_find( m_lref, ct->second[3] );
+//      // get nodes of parent tet
+//      //auto pA = tk::cref_find( m_lref, t.second[0] );
+//      //auto pB = tk::cref_find( m_lref, t.second[1] );
+//      //auto pC = tk::cref_find( m_lref, t.second[2] );
+//      //auto pD = tk::cref_find( m_lref, t.second[3] );
+//      // assign parent tet to child tet
+//      //m_oldparent[ {{cA,cB,cC,cD}} ] = {{pA,pB,pC,pD}};
+//      m_oldparent[ ct->second ] = t.second; //{{pA,pB,pC,pD}};
+      if (m_oldTets.find(ct->second) == end(m_oldTets)) {
+        // TODO: the following code can assign negative ids to newly added tets.
+        // This needs to be corrected before applying to cell-based schemes.
+        //Assert((p-m_oldntets) > 0, "Negative id assigned to added tet");
+        m_addedTets[ c++ ] = p - m_oldntets;
+      }
+    }
+    ++p;
+  }
+
+  //std::cout << thisIndex << " added: " << m_addedTets.size() << '\n';
+  //std::cout << thisIndex << " parent: " << m_oldparent.size() << '\n';
+  //std::cout << thisIndex << " pcret: " << pcFaceTets.size() << '\n';
+
+  //for (std::size_t f=0; f<m_triinpoel.size()/3; ++f) {
+  //  std::cout << "triinpoel: " <<
+  //    m_triinpoel[f*3+0] << "-" << m_triinpoel[f*3+1] << "-" <<
+  //    m_triinpoel[f*3+2] << std::endl;
+  //}
+
+  return pcFaceTets;
+}
+
+void
+Refiner::newBndMesh( const std::unordered_set< std::size_t >& ref )
+// *****************************************************************************
+// Update boundary data structures after mesh refinement
+//! \param[in] ref Unique nodes of the refined mesh using refiner-lib ids
+// *****************************************************************************
+{
+  // Generate boundary face data structures used to regenerate boundary face
+  // and node data after mesh refinement
+  auto pcFaceTets = boundary();
+
+  // Regerate boundary faces and nodes after AMR step
+  updateBndData( ref, pcFaceTets );
+}
+
+void
+Refiner::updateBndData(
+  [[maybe_unused]] const std::unordered_set< std::size_t >& ref,
+  const BndFaceData& pcFaceTets )
+// *****************************************************************************
+// Regenerate boundary faces and nodes after AMR step
+//! \param[in] ref Unique nodes of the refined mesh using refiner-lib ids
+//! \param[in] pcFaceTets Boundary face data
+// *****************************************************************************
+{
+  // storage for boundary faces associated to side-set IDs of the refined mesh
+  tk::destroy( m_bface );
+  // storage for boundary faces-node connectivity of the refined mesh
+  tk::destroy( m_triinpoel );
+  // storage for boundary nodes associated to side-set IDs of the refined mesh
+  tk::destroy( m_bnode );
+
+  // face id counter
+  std::size_t facecnt = 0;
+  // will collect unique faces added for each side set
+  std::unordered_map< int, FaceSet > bf;
+
+  // Lambda to associate a boundary face and connectivity to a side set.
+  // Argument 's' is the list of faces (ids) to add the new face to. Argument
+  // 'ss' is the side set id to which the face is added. Argument 'f' is the
+  // triangle face connectivity to add.
+  auto addBndFace = [&]( std::vector< std::size_t >& s, int ss, const Face& f )
+  {
+    // only add face if it has not yet been aded to this side set
+    if (bf[ ss ].insert( f ).second) {
+      s.push_back( facecnt++ );
+      m_triinpoel.insert( end(m_triinpoel), begin(f), end(f) );
+      Assert(m_triinpoel.size()/3 == facecnt, "Incorrect size of triinpoel");
+    }
+  };
+
+  // Lambda to search the parents in the coarsest mesh of a mesh node and if
+  // found, add its global id to boundary node lists associated to the side
+  // set(s) of its parents. Argument 'n' is the local id of the mesh node id
+  // whose parents to search.
+  auto addBndNodes = [&]( std::size_t n ){
+    auto a = ancestors( n );  // find parents of n in coarse mesh
+    if (a.size() == 1) {
+      // node was part of the coarse mesh
+      Assert(*a.cbegin() == n, "Single ancestor not self");
+      auto ss = keys( m_coarseBndNodes, m_gid[*a.cbegin()] );
+      for (auto s : ss)
+        m_bnode[ s ].push_back( m_gid[n] );
+    } else if (a.size() == 2) {
+      // node was added to an edge of a coarse face
+      std::vector< std::size_t > p( begin(a), end(a) );
+      auto ss1 = keys( m_coarseBndNodes, m_gid[p[0]] );
+      auto ss2 = keys( m_coarseBndNodes, m_gid[p[1]] );
+      for (auto s : ss1) {
+        // only add 'n' to bnode if all parent nodes are in same side set, else
+        // 'n' is not a boundary node
+        if (ss2.find(s) != end(ss2)) {
+          m_bnode[ s ].push_back( m_gid[n] );
+        }
+      }
+    } else if (a.size() == 3) {
+      // node was added inside of a coarse face
+      std::vector< std::size_t > p( begin(a), end(a) );
+      auto ss1 = keys( m_coarseBndNodes, m_gid[p[0]] );
+      auto ss2 = keys( m_coarseBndNodes, m_gid[p[1]] );
+      auto ss3 = keys( m_coarseBndNodes, m_gid[p[2]] );
+      for (auto s : ss1) {
+        // only add 'n' to bnode if all parent nodes are in same side set, else
+        // 'n' is not a boundary node
+        if (ss2.find(s) != end(ss2) && ss3.find(s) != end(ss3)) {
+          m_bnode[ s ].push_back( m_gid[n] );
+        }
+      }
+    }
+  };
+
+  // Regenerate boundary faces for new mesh along side sets. For all faces
+  // associated to side sets, we find the ancestors (parents of nodes in the
+  // original/coarsest mesh) of the nodes comprising the physical and chare
+  // boundary faces of the new mesh.
+  //bool faceNoSs = false;
+  // for all P/C faces in current (post-AMR) mesh
+  for (const auto& [ face, tetid ] : pcFaceTets) {
+    // find ancestors of face
+    std::unordered_set< std::size_t > ans;
+    for (std::size_t i=0; i<3; ++i) {
+      auto ai = ancestors(tk::cref_find(m_lid, face[i]));
+      ans.insert(ai.begin(), ai.end());
+    }
+    Assert(ans.size() == 3, "Incorrect number of ancestors in refined face");
+    Face af;
+    std::size_t i = 0;
+    for (auto ai:ans) {
+      af[i] = m_gid[ai];
+      ++i;
+    }
+    // for all boundary faces in original mesh
+    //std::size_t fss = 0;
+    for (const auto& [ss, cfaceset] : m_coarseBndFaces) {
+      if (cfaceset.find(af) != cfaceset.end()) {
+        addBndFace(m_bface[ss], ss, face);
+        //++fss;
+      }
+      for (auto j : face) {
+        addBndNodes(tk::cref_find(m_lid, j));
+      }
+    }
+    //if (fss==0) {
+    //  std::cout << "Face added to no/multiple side sets; " << fss << std::endl;
+    //  faceNoSs = true;
+    //}
+  }
+
+  // Commented code below, since diagcg can work without sideset/bcs
+  //Assert(!faceNoSs, "Face/s added to incorrect number of side sets");
+
+  // Make boundary node IDs unique for each physical boundary (side set)
+  for (auto& s : m_bnode) tk::unique( s.second );
+
+  //for (const auto& [ setid, faceids ] : m_bface) {
+  //  std::cout << "sset: " << setid << std::endl;
+  //  for (auto f : faceids) {
+  //    Assert(f<m_triinpoel.size()/3, "Out of bounds access into triinpoel");
+  //    std::cout << "new bndfaces: " <<
+  //      m_triinpoel[f*3+0] << "-" << m_triinpoel[f*3+1] << "-" <<
+  //      m_triinpoel[f*3+2] << std::endl;
+  //  }
+  //}
+
+  //for (std::size_t f=0; f<m_triinpoel.size()/3; ++f) {
+  //  std::cout << "new triinpoel: " <<
+  //    m_triinpoel[f*3+0] << "-" << m_triinpoel[f*3+1] << "-" <<
+  //    m_triinpoel[f*3+2] << std::endl;
+  //}
+
+  //std::cout << thisIndex << " bf: " << tk::sumvalsize( m_bface ) << '\n';
+
+  //std::cout << thisIndex << " bn: " << tk::sumvalsize( m_bnode ) << '\n';
+
+  // Perform leak-test on boundary face data just updated (only in DEBUG)
+  Assert( bndIntegral(), "Partial boundary integral" );
+}
+
+bool
+Refiner::bndIntegral()
+// *****************************************************************************
+//  Compute partial boundary surface integral and sum across all chares
+//! \return true so we don't trigger assert in client code
+//! \details This function computes a partial surface integral over the boundary
+//!   of the faces of this mesh partition then sends its contribution to perform
+//!   the integral acorss the total problem boundary. After the global sum a
+//!   non-zero vector result indicates a leak, e.g., a hole in the boundary
+//!   which indicates an error in the boundary face data structures used to
+//!   compute the partial surface integrals.
+// *****************************************************************************
+{
+  const auto& x = m_coord[0];
+  const auto& y = m_coord[1];
+  const auto& z = m_coord[2];
+
+  std::vector< tk::real > s{{ 0.0, 0.0, 0.0 }};
+
+  for (const auto& [ setid, faceids ] : m_bface) {
+    for (auto f : faceids) {
+      auto A = tk::cref_find( m_lid, m_triinpoel[f*3+0] );
+      auto B = tk::cref_find( m_lid, m_triinpoel[f*3+1] );
+      auto C = tk::cref_find( m_lid, m_triinpoel[f*3+2] );
+      // Compute geometry data for face
+      auto geoface = tk::geoFaceTri( {{x[A], x[B], x[C]}},
+                                     {{y[A], y[B], y[C]}},
+                                     {{z[A], z[B], z[C]}} );
+      // Sum up face area * face unit-normal
+      s[0] += geoface(0,0) * geoface(0,1);
+      s[1] += geoface(0,0) * geoface(0,2);
+      s[2] += geoface(0,0) * geoface(0,3);
+    }
+  }
+
+  s.push_back( -1.0 );  // negative: no call-back after reduction
+  s.push_back( static_cast< tk::real >( m_meshid ) );
+
+  // Send contribution to host summing partial surface integrals
+  contribute( s, CkReduction::sum_double, m_cbr.get< tag::bndint >() );
+
+  return true;  // don't trigger the assert in client code
+}
+
+#include "NoWarning/refiner.def.h"
 
diff --git a/Debug/cppcheck/48.html b/Debug/cppcheck/48.html index 1f349e25d396..b2c7ec9d329a 100644 --- a/Debug/cppcheck/48.html +++ b/Debug/cppcheck/48.html @@ -152,12 +152,12 @@
  1
@@ -881,1078 +881,728 @@ 

Cppcheck report - [

// *****************************************************************************
+722
// *****************************************************************************
 /*!
-  \file      src/PDE/MultiMat/FVMultiMat.hpp
+  \file      src/PDE/DGPDE.hpp
   \copyright 2012-2015 J. Bakosi,
              2016-2018 Los Alamos National Security, LLC.,
              2019-2021 Triad National Security, LLC.
              All rights reserved. See the LICENSE file for details.
-  \brief     Compressible multi-material flow using finite volumes
-  \details   This file implements calls to the physics operators governing
-    compressible multi-material flow (with velocity equilibrium) using finite
-    volume discretizations.
-*/
-// *****************************************************************************
-#ifndef FVMultiMat_h
-#define FVMultiMat_h
-
-#include <cmath>
-#include <algorithm>
-#include <unordered_set>
-#include <map>
-#include <array>
-
-#include "Macro.hpp"
-#include "Exception.hpp"
-#include "Vector.hpp"
-#include "ContainerUtil.hpp"
-#include "UnsMesh.hpp"
-#include "Inciter/InputDeck/InputDeck.hpp"
-#include "Integrate/Basis.hpp"
-#include "Integrate/Quadrature.hpp"
-#include "Integrate/Initialize.hpp"
-#include "Integrate/Mass.hpp"
-#include "Integrate/Surface.hpp"
-#include "Integrate/Boundary.hpp"
-#include "Integrate/Volume.hpp"
-#include "Integrate/MultiMatTerms.hpp"
-#include "Integrate/Source.hpp"
-#include "RiemannChoice.hpp"
-#include "MultiMat/MultiMatIndexing.hpp"
-#include "Reconstruction.hpp"
-#include "Limiter.hpp"
-#include "Problem/FieldOutput.hpp"
-#include "Problem/BoxInitialization.hpp"
-#include "MultiMat/BCFunctions.hpp"
-#include "MultiMat/MiscMultiMatFns.hpp"
-
-namespace inciter {
-
-extern ctr::InputDeck g_inputdeck;
-
-namespace fv {
-
-//! \brief MultiMat used polymorphically with tk::FVPDE
-//! \details The template arguments specify policies and are used to configure
-//!   the behavior of the class. The policies are:
-//!   - Physics - physics configuration, see PDE/MultiMat/Physics.h
-//!   - Problem - problem configuration, see PDE/MultiMat/Problem.h
-//! \note The default physics is Euler, set in inciter::deck::check_multimat()
-template< class Physics, class Problem >
-class MultiMat {
-
-  private:
-    using eq = tag::multimat;
-
-  public:
-    //! Constructor
-    explicit MultiMat() :
-      m_physics(),
-      m_ncomp( g_inputdeck.get< tag::ncomp >() ),
-      m_riemann( multimatRiemannSolver(
-        g_inputdeck.get< tag::flux >() ) )
-    {
-      // associate boundary condition configurations with state functions
-      brigand::for_each< ctr::bclist::Keys >( ConfigBC( m_bc,
-        { dirichlet
-        , symmetry
-        , invalidBC         // Inlet BC not implemented
-        , invalidBC         // Outlet BC not implemented
-        , farfieldOutlet
-        , extrapolate } ) );
-
-      // EoS initialization
-      initializeMaterialEoS( m_mat_blk );
-    }
-
-    //! Find the number of primitive quantities required for this PDE system
-    //! \return The number of primitive quantities required to be stored for
-    //!   this PDE system
-    std::size_t nprim() const<--- Shadowed declaration
-    {
-      auto nmat = g_inputdeck.get< tag::multimat, tag::nmat >();<--- Shadow variable
-      // multimat needs individual material pressures and velocities currently
-      return (nmat+3);
-    }
-
-    //! Find the number of materials set up for this PDE system
-    //! \return The number of materials set up for this PDE system
-    std::size_t nmat() const<--- Shadowed declaration<--- Shadowed declaration<--- Shadowed declaration<--- Shadowed declaration<--- Shadowed declaration<--- Shadowed declaration<--- Shadowed declaration<--- Shadowed declaration<--- Shadowed declaration<--- Shadowed declaration<--- Shadowed declaration<--- Shadowed declaration<--- Shadowed declaration<--- Shadowed declaration<--- Shadowed declaration<--- Shadowed declaration<--- Shadowed declaration
-    {
-      auto nmat = g_inputdeck.get< tag::multimat, tag::nmat >();
-      return nmat;
-    }
-
-    //! Determine elements that lie inside the user-defined IC box
-    //! \param[in] geoElem Element geometry array
-    //! \param[in] nielem Number of internal elements
-    //! \param[in,out] inbox List of nodes at which box user ICs are set for
-    //!    each IC box
-    void IcBoxElems( const tk::Fields& geoElem,
-      std::size_t nielem,
-      std::vector< std::unordered_set< std::size_t > >& inbox ) const
-    {
-      tk::BoxElems< eq >(geoElem, nielem, inbox);
-    }
-
-    //! Initalize the compressible flow equations, prepare for time integration
-    //! \param[in] L Block diagonal mass matrix
-    //! \param[in] inpoel Element-node connectivity
-    //! \param[in] coord Array of nodal coordinates
-    //! \param[in] inbox List of elements at which box user ICs are set for
-    //!   each IC box
-    //! \param[in] elemblkid Element ids associated with mesh block ids where
-    //!   user ICs are set
-    //! \param[in,out] unk Array of unknowns
-    //! \param[in] t Physical time
-    //! \param[in] nielem Number of internal elements
-    void initialize( const tk::Fields& L,
-      const std::vector< std::size_t >& inpoel,
-      const tk::UnsMesh::Coords& coord,
-      const std::vector< std::unordered_set< std::size_t > >& inbox,
-      const std::unordered_map< std::size_t, std::set< std::size_t > >&
-        elemblkid,
-      tk::Fields& unk,
-      tk::real t,
-      const std::size_t nielem ) const
-    {
-      tk::initialize( m_ncomp, m_mat_blk, L, inpoel, coord,
-                      Problem::initialize, unk, t, nielem );
-
-      const auto rdof = g_inputdeck.get< tag::rdof >();
-      const auto& ic = g_inputdeck.get< tag::ic >();
-      const auto& icbox = ic.get< tag::box >();
-      const auto& icmbk = ic.get< tag::meshblock >();
-
-      const auto& bgpre = ic.get< tag::pressure >();
-      const auto& bgtemp = ic.get< tag::temperature >();
-
-      // Set initial conditions inside user-defined IC boxes and mesh blocks
-      std::vector< tk::real > s(m_ncomp, 0.0);
-      for (std::size_t e=0; e<nielem; ++e) {
-        // inside user-defined box
-        if (!icbox.empty()) {
-          std::size_t bcnt = 0;
-          for (const auto& b : icbox) {   // for all boxes
-            if (inbox.size() > bcnt && inbox[bcnt].find(e) != inbox[bcnt].end())
-            {
-              std::vector< tk::real > box
-                { b.template get< tag::xmin >(), b.template get< tag::xmax >(),
-                  b.template get< tag::ymin >(), b.template get< tag::ymax >(),
-                  b.template get< tag::zmin >(), b.template get< tag::zmax >() };
-              auto V_ex = (box[1]-box[0]) * (box[3]-box[2]) * (box[5]-box[4]);
-              for (std::size_t c=0; c<m_ncomp; ++c) {
-                auto mark = c*rdof;
-                s[c] = unk(e,mark);
-                // set high-order DOFs to zero
-                for (std::size_t i=1; i<rdof; ++i)
-                  unk(e,mark+i) = 0.0;
-              }
-              initializeBox<ctr::boxList>( m_mat_blk, V_ex, t, b, bgpre,
-                bgtemp, s );
-              // store box-initialization in solution vector
-              for (std::size_t c=0; c<m_ncomp; ++c) {
-                auto mark = c*rdof;
-                unk(e,mark) = s[c];
-              }
-            }
-            ++bcnt;
-          }
-        }
-
-        // inside user-specified mesh blocks
-        for (const auto& b : icmbk) { // for all blocks
-          auto blid = b.get< tag::blockid >();
-          auto V_ex = b.get< tag::volume >();
-          if (elemblkid.find(blid) != elemblkid.end()) {
-            const auto& elset = tk::cref_find(elemblkid, blid);
-            if (elset.find(e) != elset.end()) {
-              initializeBox<ctr::meshblockList>( m_mat_blk, V_ex, t, b,
-                bgpre, bgtemp, s );
-              // store initialization in solution vector
-              for (std::size_t c=0; c<m_ncomp; ++c) {
-                auto mark = c*rdof;
-                unk(e,mark) = s[c];
-              }
-            }
-          }
-        }
-      }
-    }
-
-    //! Compute the left hand side block-diagonal mass matrix
-    //! \param[in] geoElem Element geometry array
-    //! \param[in,out] l Block diagonal mass matrix
-    void lhs( const tk::Fields& geoElem, tk::Fields& l ) const {<--- Parameter 'l' can be declared with const
-      const auto nelem = geoElem.nunk();
-      for (std::size_t e=0; e<nelem; ++e)
-        for (ncomp_t c=0; c<m_ncomp; ++c)
-          l(e, c) = geoElem(e,0);
-    }
-
-    //! Update the primitives for this PDE system
-    //! \param[in] unk Array of unknowns
-    //! \param[in,out] prim Array of primitives
-    //! \param[in] nielem Number of internal elements
-    //! \details This function computes and stores the dofs for primitive
-    //!   quantities, which are required for obtaining reconstructed states used
-    //!   in the Riemann solver. See /PDE/Riemann/AUSM.hpp, where the
-    //!   normal velocity for advection is calculated from independently
-    //!   reconstructed velocities.
-    void updatePrimitives( const tk::Fields& unk,
-                           tk::Fields& prim,<--- Parameter 'prim' can be declared with const
-                           std::size_t nielem ) const
-    {
-      const auto rdof = g_inputdeck.get< tag::rdof >();<--- Variable 'rdof' is assigned a value that is never used.
-      auto nmat = g_inputdeck.get< tag::multimat, tag::nmat >();<--- Shadow variable<--- Variable 'nmat' is assigned a value that is never used.
-
-      Assert( unk.nunk() == prim.nunk(), "Number of unknowns in solution "
-              "vector and primitive vector at recent time step incorrect" );
-      Assert( unk.nprop() == rdof*m_ncomp, "Number of components in solution "
-              "vector must equal "+ std::to_string(rdof*m_ncomp) );
-      Assert( prim.nprop() == rdof*nprim(), "Number of components in vector of "
-              "primitive quantities must equal "+ std::to_string(rdof*nprim()) );
-
-      for (std::size_t e=0; e<nielem; ++e)
-      {
-        // cell-average bulk density
-        tk::real rhob(0.0);
-        for (std::size_t k=0; k<nmat; ++k)
-        {
-          rhob += unk(e, densityDofIdx(nmat, k, rdof, 0));
-        }
-
-        // cell-average velocity
-        std::array< tk::real, 3 >
-          vel{{ unk(e, momentumDofIdx(nmat, 0, rdof, 0))/rhob,
-                unk(e, momentumDofIdx(nmat, 1, rdof, 0))/rhob,
-                unk(e, momentumDofIdx(nmat, 2, rdof, 0))/rhob }};
-
-        for (std::size_t idir=0; idir<3; ++idir)
-        {
-          prim(e, velocityDofIdx(nmat, idir, rdof, 0)) = vel[idir];
-          for (std::size_t idof=1; idof<rdof; ++idof)
-            prim(e, velocityDofIdx(nmat, idir, rdof, idof)) = 0.0;
-        }
-
-        // cell-average material pressure
-        for (std::size_t k=0; k<nmat; ++k)
-        {
-          tk::real arhomat = unk(e, densityDofIdx(nmat, k, rdof, 0));
-          tk::real arhoemat = unk(e, energyDofIdx(nmat, k, rdof, 0));
-          tk::real alphamat = unk(e, volfracDofIdx(nmat, k, rdof, 0));
-          auto gmat = getDeformGrad(nmat, k, unk.extract(e));
-          prim(e, pressureDofIdx(nmat, k, rdof, 0)) =
-            m_mat_blk[k].compute< EOS::pressure >( arhomat, vel[0], vel[1],
-            vel[2], arhoemat, alphamat, k, gmat );
-          prim(e, pressureDofIdx(nmat, k, rdof, 0)) =
-            constrain_pressure( m_mat_blk,
-            prim(e, pressureDofIdx(nmat, k, rdof, 0)), arhomat, alphamat, k);
-          for (std::size_t idof=1; idof<rdof; ++idof)
-            prim(e, pressureDofIdx(nmat, k, rdof, idof)) = 0.0;
-        }
-      }
-    }
-
-    //! Clean up the state of trace materials for this PDE system
-    //! \param[in] t Physical time
-    //! \param[in] geoElem Element geometry array
-    //! \param[in,out] unk Array of unknowns
-    //! \param[in,out] prim Array of primitives
-    //! \param[in] nielem Number of internal elements
-    //! \details This function cleans up the state of materials present in trace
-    //!   quantities in each cell. Specifically, the state of materials with
-    //!   very low volume-fractions in a cell is replaced by the state of the
-    //!   material which is present in the largest quantity in that cell. This
-    //!   becomes necessary when shocks pass through cells which contain a very
-    //!   small amount of material. The state of that tiny material might
-    //!   become unphysical and cause solution to diverge; thus requiring such
-    //!   a "reset".
-    void cleanTraceMaterial( tk::real t,
-                             const tk::Fields& geoElem,
-                             tk::Fields& unk,
-                             tk::Fields& prim,
-                             std::size_t nielem ) const
-    {
-      [[maybe_unused]] const auto rdof = g_inputdeck.get< tag::rdof >();
-      auto nmat = g_inputdeck.get< tag::multimat, tag::nmat >();<--- Shadow variable<--- Variable 'nmat' is assigned a value that is never used.
-
-      Assert( unk.nunk() == prim.nunk(), "Number of unknowns in solution "
-              "vector and primitive vector at recent time step incorrect" );
-      Assert( unk.nprop() == rdof*m_ncomp, "Number of components in solution "
-              "vector must equal "+ std::to_string(rdof*m_ncomp) );
-      Assert( prim.nprop() == rdof*nprim(), "Number of components in vector of "
-              "primitive quantities must equal "+ std::to_string(rdof*nprim()) );
-      Assert( (g_inputdeck.get< tag::ndof >()) <= 4, "High-order "
-              "discretizations not set up for multimat cleanTraceMaterial()" );
-
-      auto neg_density = cleanTraceMultiMat(t, nielem, m_mat_blk, geoElem, nmat,
-        unk, prim);
-
-      if (neg_density) Throw("Negative partial density.");
-    }
-
-    //! Reconstruct second-order solution from first-order
-    //! \param[in] geoElem Element geometry array
-    //! \param[in] fd Face connectivity and boundary conditions object
-    //! \param[in] esup Elements-surrounding-nodes connectivity
-    //! \param[in] inpoel Element-node connectivity
-    //! \param[in] coord Array of nodal coordinates
-    //! \param[in,out] U Solution vector at recent time step
-    //! \param[in,out] P Vector of primitives at recent time step
-    void reconstruct( const tk::Fields& geoElem,
-                      const inciter::FaceData& fd,
-                      const std::map< std::size_t, std::vector< std::size_t > >&
-                        esup,
-                      const std::vector< std::size_t >& inpoel,
-                      const tk::UnsMesh::Coords& coord,
-                      tk::Fields& U,
-                      tk::Fields& P ) const
-    {
-      const auto rdof = g_inputdeck.get< tag::rdof >();
-      const auto nelem = fd.Esuel().size()/4;<--- Variable 'nelem' is assigned a value that is never used.
-      auto nmat = g_inputdeck.get< tag::multimat, tag::nmat >();<--- Shadow variable<--- Variable 'nmat' is assigned a value that is never used.
-
-      Assert( U.nprop() == rdof*m_ncomp, "Number of components in solution "
-              "vector must equal "+ std::to_string(rdof*m_ncomp) );
+  \brief     Partial differential equation base for discontinuous Galerkin PDEs
+  \details   This file defines a generic partial differential equation (PDE)
+    class for PDEs that use discontinuous Galerkin spatial discretization.
+    The class uses runtime polymorphism without client-side inheritance:
+    inheritance is confined to the internals of the class, invisible to
+    client-code. The class exclusively deals with ownership enabling client-side
+    value semantics. Credit goes to Sean Parent at Adobe:
+    https://github.com/sean-parent/sean-parent.github.com/wiki/
+    Papers-and-Presentations.
+*/
+// *****************************************************************************
+#ifndef DGPDE_h
+#define DGPDE_h
+
+#include <array>
+#include <string>
+#include <vector>
+#include <memory>
+#include <unordered_set>
+#include <functional>
+
+#include "Types.hpp"
+#include "Fields.hpp"
+#include "FaceData.hpp"
+#include "UnsMesh.hpp"
+#include "Inciter/InputDeck/InputDeck.hpp"
+#include "FunctionPrototypes.hpp"
+#include "History.hpp"
+
+namespace inciter {
+
+extern ctr::InputDeck g_inputdeck;
+
+using ncomp_t = tk::ncomp_t;
+using BCStateFn =
+  std::vector< std::pair< std::vector< std::size_t >, tk::StateFn > >;
+
+//! Extract BC configuration ignoring if BC not specified
+//! \note A more preferable way of catching errors such as this function
+//!   hides is during parsing, so that we don't even get here if BCs are
+//!   not correctly specified. For now we simply ignore if BCs are not
+//!   specified by allowing empty BC vectors from the user input.
+struct ConfigBC {
+  BCStateFn& state;    //!< BC state config: sidesets + statefn
+  const std::vector< tk::StateFn >& fn;    //!< BC state functions
+  std::size_t c;       //!< Counts BC types configured
+  //! Constructor
+  ConfigBC( BCStateFn& s,
+            const std::vector< tk::StateFn >& f ) :
+    state(s), fn(f), c(0) {}
+  //! Function to call for each BC type
+  template< typename U > void operator()( brigand::type_<U> ) {
+    std::vector< std::size_t > cfg, v;
+    // collect sidesets across all meshes
+    for (const auto& ibc : g_inputdeck.get< tag::bc >()) {
+      v.insert(v.end(), ibc.get< U >().begin(), ibc.get< U >().end());
+    }
+    if (v.size() > 0) cfg = v;<--- Variable 'cfg' is assigned a value that is never used.
+    Assert( fn.size() > c, "StateFn missing for BC type" );
+    state.push_back( { cfg, fn[c++] } );
+  }
+};
+
+//! State function for invalid/un-configured boundary conditions
+[[noreturn]] tk::StateFn::result_type
+invalidBC( ncomp_t, const std::vector< EOS >&,
+           const std::vector< tk::real >&, tk::real, tk::real, tk::real,
+           tk::real, const std::array< tk::real, 3> & );
+
+//! \brief Partial differential equation base for discontinuous Galerkin PDEs
+//! \details This class uses runtime polymorphism without client-side
+//!   inheritance: inheritance is confined to the internals of the this class,
+//!   invisible to client-code. The class exclusively deals with ownership
+//!   enabling client-side value semantics. Credit goes to Sean Parent at Adobe:
+//!   https://github.com/sean-parent/sean-parent.github.com/wiki/
+//!   Papers-and-Presentations. For example client code that models a DGPDE,
+//!   see inciter::CompFlow.
+class DGPDE {
+
+  private:
+    using ncomp_t = tk::ncomp_t;
+
+  public:
+    //! Default constructor taking no arguments for Charm++
+    explicit DGPDE() = default;
+
+    //! \brief Constructor taking an object modeling Concept.
+    //! \details The object of class T comes pre-constructed.
+    //! \param[in] x Instantiated object of type T given by the template
+    //!   argument.
+    template< typename T > explicit DGPDE( T x ) :
+      self( std::make_unique< Model<T> >( std::move(x) ) ) {}
+
+    //! \brief Constructor taking a function pointer to a constructor of an
+    //!   object modeling Concept.
+    //! \details Passing std::function allows late execution of the constructor,
+    //!   i.e., as late as inside this class' constructor, and thus usage from
+    //!   a factory. Note that there are at least two different ways of using
+    //!   this constructor:
+    //!   - Bind T's constructor arguments and place it in std::function<T()>
+    //!   and passing no arguments as args.... This case then instantiates the
+    //!   model via its constructor and stores it in here.
+    //!   - Bind a single placeholder argument to T's constructor and pass it in
+    //!   as host's args..., which then forwards it to model's constructor. This
+    //!   allows late binding, i.e., binding the argument only here.
+    //! \see See also the wrapper tk::recordModel() which does the former and
+    //!   tk::recordModelLate() which does the latter, both defined in
+    //!   src/Base/Factory.h.
+    //! \param[in] x Function pointer to a constructor of an object modeling
+    //!    Concept.
+    //! \param[in] args Zero or more constructor arguments
+    template< typename T, typename...Args >
+    explicit DGPDE( std::function<T(Args...)> x, Args&&... args ) :
+      self( std::make_unique< Model<T> >(
+              std::move( x( std::forward<Args>(args)... ) ) ) ) {}
+
+    //! Public interface to find number of primitive quantities for the diff eq
+    std::size_t nprim() const
+    { return self->nprim(); }
+
+    //! Public interface to find number of materials for the diff eq
+    std::size_t nmat() const
+    { return self->nmat(); }
+
+    //! Public interface to find Dofs for each equation in pde system
+    void numEquationDofs(std::vector< std::size_t >& numEqDof) const
+    { return self->numEquationDofs(numEqDof); }
+
+    //! Public interface to find how 'stiff equations', which are the inverse
+    //! deformation equations because of plasticity
+    std::size_t nstiffeq() const
+    { return self->nstiffeq(); }
+
+    //! Public interface to find how 'nonstiff equations', which are the inverse
+    //! deformation equations because of plasticity
+    std::size_t nnonstiffeq() const
+    { return self->nnonstiffeq(); }
+
+    //! Public function to locate the stiff equations
+    void setStiffEqIdx( std::vector< std::size_t >& stiffEqIdx ) const
+    { return self->setStiffEqIdx( stiffEqIdx ); }
+
+    //! Public function to locate the nonstiff equations
+    void setNonStiffEqIdx( std::vector< std::size_t >& nonStiffEqIdx ) const
+    { return self->setNonStiffEqIdx( nonStiffEqIdx ); }
+
+    //! Public interface to determine elements that lie inside the IC box
+    void IcBoxElems( const tk::Fields& geoElem,
+      std::size_t nielem,
+      std::vector< std::unordered_set< std::size_t > >& inbox ) const
+    { self->IcBoxElems( geoElem, nielem, inbox ); }
+
+    //! Public interface to setting the initial conditions for the diff eq
+    void initialize(
+      const tk::Fields& L,
+      const std::vector< std::size_t >& inpoel,
+      const tk::UnsMesh::Coords& coord,
+      const std::vector< std::unordered_set< std::size_t > >& inbox,
+      const std::unordered_map< std::size_t, std::set< std::size_t > >&
+        elemblkid,
+      tk::Fields& unk,
+      tk::real t,
+      const std::size_t nielem ) const
+    { self->initialize( L, inpoel, coord, inbox, elemblkid, unk, t, nielem ); }
+
+    //! Public interface for saving initial densities of materials
+    void setRho0mat( std::vector< tk::real >& rho0mat) const
+    { return self->setRho0mat( rho0mat ); }
+
+    //! Public interface for computing density constraint
+    void computeDensityConstr( std::size_t nelem,
+                               tk::Fields& unk,
+                               std::vector< tk::real >& rho0mat,
+                               std::vector< tk::real >& densityConstr) const
+    { self->computeDensityConstr( nelem, unk, rho0mat, densityConstr); }
+
+    //! Public interface to computing the left-hand side matrix for the diff eq
+    void lhs( const tk::Fields& geoElem, tk::Fields& l ) const
+    { self->lhs( geoElem, l ); }
+
+    //! Public interface to updating the interface cells for the diff eq
+    void updateInterfaceCells( tk::Fields& unk,
+                               std::size_t nielem,
+                               std::vector< std::size_t >& ndofel ) const
+    { self->updateInterfaceCells( unk, nielem, ndofel ); }
+
+    //! Public interface to updating the primitives for the diff eq
+    void updatePrimitives( const tk::Fields& unk,
+                           const tk::Fields& L,
+                           const tk::Fields& geoElem,
+                           tk::Fields& prim,
+                           std::size_t nielem ) const
+    { self->updatePrimitives( unk, L, geoElem, prim, nielem ); }
+
+    //! Public interface to cleaning up trace materials for the diff eq
+    void cleanTraceMaterial( tk::real t,
+                             const tk::Fields& geoElem,
+                             tk::Fields& unk,
+                             tk::Fields& prim,
+                             std::size_t nielem ) const
+    { self->cleanTraceMaterial( t, geoElem, unk, prim, nielem ); }
+
+    //! Public interface to reconstructing the second-order solution
+    void reconstruct( tk::real t,
+                      const tk::Fields& geoFace,
+                      const tk::Fields& geoElem,
+                      const inciter::FaceData& fd,
+                      const std::map< std::size_t, std::vector< std::size_t > >&
+                        esup,
+                      const std::vector< std::size_t >& inpoel,
+                      const tk::UnsMesh::Coords& coord,
+                      tk::Fields& U,
+                      tk::Fields& P ) const
+    {
+      self->reconstruct( t, geoFace, geoElem, fd, esup, inpoel, coord, U, P );
+    }
+
+    //! Public interface to limiting the second-order solution
+    void limit( tk::real t,
+                const tk::Fields& geoFace,
+                const tk::Fields& geoElem,
+                const inciter::FaceData& fd,
+                const std::map< std::size_t, std::vector< std::size_t > >& esup,
+                const std::vector< std::size_t >& inpoel,
+                const tk::UnsMesh::Coords& coord,
+                const std::vector< std::size_t >& ndofel,
+                const std::vector< std::size_t >& gid,
+                const std::unordered_map< std::size_t, std::size_t >& bid,
+                const std::vector< std::vector<tk::real> >& uNodalExtrm,
+                const std::vector< std::vector<tk::real> >& pNodalExtrm,
+                const std::vector< std::vector<tk::real> >& mtInv,
+                tk::Fields& U,
+                tk::Fields& P,
+                std::vector< std::size_t >& shockmarker ) const
+    {
+      self->limit( t, geoFace, geoElem, fd, esup, inpoel, coord, ndofel, gid,
+                   bid, uNodalExtrm, pNodalExtrm, mtInv, U, P, shockmarker );
+    }
+
+    //! Public interface to update the conservative variable solution
+    void CPL( const tk::Fields& prim,
+              const tk::Fields& geoElem,
+              const std::vector< std::size_t >& inpoel,
+              const tk::UnsMesh::Coords& coord,
+              tk::Fields& unk,
+              std::size_t nielem ) const
+    {
+      self->CPL( prim, geoElem, inpoel, coord, unk, nielem );
+    }
+
+    //! Public interface to getting the cell-averaged deformation gradients
+    std::array< std::vector< tk::real >, 9 > cellAvgDeformGrad(
+      const tk::Fields& U,
+      std::size_t nielem ) const
+    {
+      return self->cellAvgDeformGrad( U, nielem );
+    }
+
+    //! Public interface to computing the P1 right-hand side vector
+    void rhs( tk::real t,
+              const tk::Fields& geoFace,
+              const tk::Fields& geoElem,
+              const inciter::FaceData& fd,
+              const std::vector< std::size_t >& inpoel,
+              const std::vector< std::unordered_set< std::size_t > >& boxelems,
+              const tk::UnsMesh::Coords& coord,
+              const tk::Fields& U,
+              const tk::Fields& P,
+              const std::vector< std::size_t >& ndofel,
+              const std::vector< tk::real >& rho0mat,
+              const tk::real dt,
+              tk::Fields& R ) const
+    {
+      self->rhs( t, geoFace, geoElem, fd, inpoel, boxelems, coord, U, P,
+                 ndofel, rho0mat, dt, R );
+    }
+
+    //! Evaluate the adaptive indicator and mark the ndof for each element
+    void eval_ndof( std::size_t nunk,
+                    const tk::UnsMesh::Coords& coord,
+                    const std::vector< std::size_t >& inpoel,
+                    const inciter::FaceData& fd,
+                    const tk::Fields& unk,
+                    const tk::Fields& prim,
+                    inciter::ctr::PrefIndicatorType indicator,
+                    std::size_t ndof,
+                    std::size_t ndofmax,
+                    tk::real tolref,
+                    std::vector< std::size_t >& ndofel ) const
+    {
+      self->eval_ndof( nunk, coord, inpoel, fd, unk, prim, indicator, ndof,
+        ndofmax, tolref, ndofel );
+    }
+
+    //! Public interface for computing the minimum time step size
+    tk::real dt( const std::array< std::vector< tk::real >, 3 >& coord,
+                 const std::vector< std::size_t >& inpoel,
+                 const inciter::FaceData& fd,
+                 const tk::Fields& geoFace,
+                 const tk::Fields& geoElem,
+                 const std::vector< std::size_t >& ndofel,
+                 const tk::Fields& U,
+                 const tk::Fields& P,
+                 const std::size_t nielem ) const
+    { return self->dt( coord, inpoel, fd, geoFace, geoElem, ndofel, U,
+                       P, nielem ); }
+
+    //! Public interface for computing stiff terms for an element
+    void stiff_rhs( std::size_t e,
+                    const tk::Fields& geoElem,
+                    const std::vector< std::size_t >& inpoel,
+                    const tk::UnsMesh::Coords& coord,
+                    const tk::Fields& U,
+                    const tk::Fields& P,
+                    const std::vector< std::size_t >& ndofel,
+                    tk::Fields& R ) const
+    { return self->stiff_rhs( e, geoElem, inpoel, coord, U, P, ndofel, R); }
+
+    //! Public interface to returning maps of output var functions
+    std::map< std::string, tk::GetVarFn > OutVarFn() const
+    { return self->OutVarFn(); }
+
+    //! Public interface to returning analytic field output labels
+    std::vector< std::string > analyticFieldNames() const
+    { return self->analyticFieldNames(); }
+
+    //! Public interface to returning time history field output labels
+    std::vector< std::string > histNames() const { return self->histNames(); }
 
-      //----- reconstruction of conserved quantities -----
-      //--------------------------------------------------
-      // specify how many variables need to be reconstructed
-      std::vector< std::size_t > vars;
-      for (std::size_t k=0; k<nmat; ++k) {
-        vars.push_back(volfracIdx(nmat,k));
-        vars.push_back(densityIdx(nmat,k));
-      }
+    //! Public interface to returning variable names
+    std::vector< std::string > names() const { return self->names(); }
+
+    //! Public interface to returning surface field output
+    std::vector< std::vector< tk::real > >
+    surfOutput( const std::map< int, std::vector< std::size_t > >& bnd,
+                tk::Fields& U ) const
+    { return self->surfOutput( bnd, U ); }
 
-      // 1. solve 3x3 least-squares system
-      for (std::size_t e=0; e<nelem; ++e)
-      {
-        // Reconstruct second-order dofs of volume-fractions in Taylor space
-        // using nodal-stencils, for a good interface-normal estimate
-        tk::recoLeastSqExtStencil( rdof, e, esup, inpoel, geoElem, U, vars );
-      }
-
-      // 2. transform reconstructed derivatives to Dubiner dofs
-      tk::transform_P0P1(rdof, nelem, inpoel, coord, U, vars);
-
-      //----- reconstruction of primitive quantities -----
-      //--------------------------------------------------
-      // For multimat, conserved and primitive quantities are reconstructed
-      // separately.
-      vars.clear();
-      for (std::size_t c=0; c<nprim(); ++c) vars.push_back(c);
-      // 1.
-      for (std::size_t e=0; e<nelem; ++e)
-      {
-        // Reconstruct second-order dofs of volume-fractions in Taylor space
-        // using nodal-stencils, for a good interface-normal estimate
-        tk::recoLeastSqExtStencil( rdof, e, esup, inpoel, geoElem, P, vars );
-      }
-
-      // 2.
-      tk::transform_P0P1(rdof, nelem, inpoel, coord, P, vars);
-    }
-
-    //! Limit second-order solution, and primitive quantities separately
-    //! \param[in] geoFace Face geometry array
-    //! \param[in] fd Face connectivity and boundary conditions object
-    //! \param[in] esup Elements-surrounding-nodes connectivity
-    //! \param[in] inpoel Element-node connectivity
-    //! \param[in] coord Array of nodal coordinates
-    //! \param[in] srcFlag Whether the energy source was added
-    //! \param[in,out] U Solution vector at recent time step
-    //! \param[in,out] P Vector of primitives at recent time step
-    void limit( const tk::Fields& geoFace,
-                const inciter::FaceData& fd,
-                const std::map< std::size_t, std::vector< std::size_t > >& esup,
-                const std::vector< std::size_t >& inpoel,
-                const tk::UnsMesh::Coords& coord,
-                const std::vector< int >& srcFlag,
-                tk::Fields& U,
-                tk::Fields& P ) const
-    {
-      Assert( U.nunk() == P.nunk(), "Number of unknowns in solution "
-              "vector and primitive vector at recent time step incorrect" );
-
-      const auto limiter = g_inputdeck.get< tag::limiter >();
-      auto nmat = g_inputdeck.get< tag::multimat, tag::nmat >();<--- Shadow variable
-      const auto& solidx = g_inputdeck.get<
-        tag::matidxmap, tag::solidx >();
-
-      // limit vectors of conserved and primitive quantities
-      if (limiter == ctr::LimiterType::VERTEXBASEDP1)
-      {
-        VertexBasedMultiMat_FV( esup, inpoel, fd.Esuel().size()/4,
-          coord, srcFlag, solidx, U, P, nmat );
-        PositivityPreservingMultiMat_FV( inpoel, fd.Esuel().size()/4, nmat,
-          m_mat_blk, coord, geoFace, U, P );
-      }
-      else if (limiter != ctr::LimiterType::NOLIMITER)
-      {
-        Throw("Limiter type not configured for multimat.");
-      }
-    }
-
-    //! Apply CPL to the conservative variable solution for this PDE system
-    //! \param[in] prim Array of primitive variables
-    //! \param[in] geoElem Element geometry array
-    //! \param[in] inpoel Element-node connectivity
-    //! \param[in] coord Array of nodal coordinates
-    //! \param[in,out] unk Array of conservative variables
-    //! \param[in] nielem Number of internal elements
-    //! \details This function applies CPL to obtain consistent dofs for
-    //!   conservative quantities based on the limited primitive quantities.
-    //!   See Pandare et al. (2023). On the Design of Stable,
-    //!   Consistent, and Conservative High-Order Methods for Multi-Material
-    //!   Hydrodynamics. J Comp Phys, 112313.
-    void CPL( const tk::Fields& prim,
-      const tk::Fields& geoElem,
-      const std::vector< std::size_t >& inpoel,
-      const tk::UnsMesh::Coords& coord,
-      tk::Fields& unk,
-      std::size_t nielem ) const
-    {
-      [[maybe_unused]] const auto rdof = g_inputdeck.get< tag::rdof >();
-      auto nmat = g_inputdeck.get< tag::multimat, tag::nmat >();<--- Shadow variable<--- Variable 'nmat' is assigned a value that is never used.
-
-      Assert( unk.nunk() == prim.nunk(), "Number of unknowns in solution "
-              "vector and primitive vector at recent time step incorrect" );
-      Assert( unk.nprop() == rdof*m_ncomp, "Number of components in solution "
-              "vector must equal "+ std::to_string(rdof*m_ncomp) );
-      Assert( prim.nprop() == rdof*nprim(), "Number of components in vector of "
-              "primitive quantities must equal "+ std::to_string(rdof*nprim()) );
-
-      correctLimConservMultiMat(nielem, m_mat_blk, nmat, inpoel,
-        coord, geoElem, prim, unk);
-    }
-
-    //! Compute right hand side
-    //! \param[in] t Physical time
-    //! \param[in] geoFace Face geometry array
-    //! \param[in] geoElem Element geometry array
-    //! \param[in] fd Face connectivity and boundary conditions object
-    //! \param[in] inpoel Element-node connectivity
-    //! \param[in] coord Array of nodal coordinates
-    //! \param[in] elemblkid Element ids associated with mesh block ids where
-    //!   user ICs are set
-    //! \param[in] U Solution vector at recent time step
-    //! \param[in] P Primitive vector at recent time step
-    //! \param[in,out] R Right-hand side vector computed
-    //! \param[in,out] srcFlag Whether the energy source was added
-    void rhs( tk::real t,
-              const tk::Fields& geoFace,
-              const tk::Fields& geoElem,
-              const inciter::FaceData& fd,
-              const std::vector< std::size_t >& inpoel,
-              const tk::UnsMesh::Coords& coord,
-              const std::unordered_map< std::size_t, std::set< std::size_t > >&
-                elemblkid,
-              const tk::Fields& U,
-              const tk::Fields& P,
-              tk::Fields& R,
-              std::vector< int >& srcFlag ) const
-    {
-      const auto rdof = g_inputdeck.get< tag::rdof >();
-      auto nmat = g_inputdeck.get< tag::multimat, tag::nmat >();<--- Shadow variable
-      const auto intsharp =
-        g_inputdeck.get< tag::multimat, tag::intsharp >();
-
-      const auto nelem = fd.Esuel().size()/4;
-
-      Assert( U.nunk() == P.nunk(), "Number of unknowns in solution "
-              "vector and primitive vector at recent time step incorrect" );
-      Assert( U.nunk() == R.nunk(), "Number of unknowns in solution "
-              "vector and right-hand side at recent time step incorrect" );
-      Assert( U.nprop() == rdof*m_ncomp, "Number of components in solution "
-              "vector must equal "+ std::to_string(rdof*m_ncomp) );
-      Assert( P.nprop() == rdof*nprim(), "Number of components in primitive "
-              "vector must equal "+ std::to_string(rdof*nprim()) );
-      Assert( fd.Inpofa().size()/3 == fd.Esuf().size()/2,
-              "Mismatch in inpofa size" );
-
-      // set rhs to zero
-      R.fill(0.0);
-
-      // configure a no-op lambda for prescribed velocity
-      auto velfn = []( ncomp_t, tk::real, tk::real, tk::real, tk::real ){
-        return tk::VelFn::result_type(); };
-
-      // compute internal surface flux (including non-conservative) integrals
-      tk::surfIntFV( nmat, m_mat_blk, t, rdof, inpoel,
-                     coord, fd, geoFace, geoElem, m_riemann, velfn, U, P,
-                     srcFlag, R, intsharp );
-
-      // compute boundary surface flux (including non-conservative) integrals
-      for (const auto& b : m_bc)
-        tk::bndSurfIntFV( nmat, m_mat_blk, rdof, b.first,
-                          fd, geoFace, geoElem, inpoel, coord, t, m_riemann,
-                          velfn, b.second, U, P, srcFlag, R, intsharp );
-
-      // compute optional source term
-      tk::srcIntFV( m_mat_blk, t, fd.Esuel().size()/4,
-                    geoElem, Problem::src, R, nmat );
-
-      // compute finite pressure relaxation terms
-      if (g_inputdeck.get< tag::multimat, tag::prelax >())
-      {
-        const auto ct = g_inputdeck.get< tag::multimat,
-                                         tag::prelax_timescale >();
-        tk::pressureRelaxationIntFV( nmat, m_mat_blk, rdof,
-                                     nelem, inpoel, coord, geoElem, U, P, ct,
-                                     R );
-      }
-
-      // compute external (energy) sources
-      m_physics.physSrc(nmat, t, geoElem, elemblkid, R, srcFlag);
-    }
-
-    //! Compute the minimum time step size
-//    //! \param[in] fd Face connectivity and boundary conditions object
-//    //! \param[in] geoFace Face geometry array
-    //! \param[in] geoElem Element geometry array
-    //! \param[in] U Solution vector at recent time step
-    //! \param[in] P Vector of primitive quantities at recent time step
-    //! \param[in] nielem Number of internal elements
-    //! \param[in] srcFlag Whether the energy source was added
-    //! \param[in,out] local_dte Time step size for each element (for local
-    //!   time stepping)
-    //! \return Minimum time step size
-    //! \details The allowable dt is calculated by looking at the maximum
-    //!   wave-speed in elements surrounding each face, times the area of that
-    //!   face. Once the maximum of this quantity over the mesh is determined,
-    //!   the volume of each cell is divided by this quantity. A minimum of this
-    //!   ratio is found over the entire mesh, which gives the allowable dt.
-    tk::real dt( const inciter::FaceData& /*fd*/,
-                 const tk::Fields& /*geoFace*/,
-                 const tk::Fields& geoElem,
-                 const tk::Fields& U,
-                 const tk::Fields& P,
-                 const std::size_t nielem,
-                 const std::vector< int >& srcFlag,
-                 std::vector< tk::real >& local_dte ) const
-    {
-      auto nmat = g_inputdeck.get< tag::multimat, tag::nmat >();<--- Shadow variable
-
-      // obtain dt restrictions from all physics
-      auto dt_e = timeStepSizeMultiMatFV(m_mat_blk, geoElem, nielem, nmat, U,
-        P, local_dte);
-      auto dt_p = m_physics.dtRestriction(geoElem, nielem, srcFlag);
-
-      return std::min(dt_e, dt_p);
-    }
-
-    //! Extract the velocity field at cell nodes. Currently unused.
-    //! \param[in] U Solution vector at recent time step
-    //! \param[in] N Element node indices
-    //! \return Array of the four values of the velocity field
-    std::array< std::array< tk::real, 4 >, 3 >
-    velocity( const tk::Fields& U,
-              const std::array< std::vector< tk::real >, 3 >&,
-              const std::array< std::size_t, 4 >& N ) const
-    {
-      const auto rdof = g_inputdeck.get< tag::rdof >();
-      auto nmat = g_inputdeck.get< tag::multimat, tag::nmat >();<--- Shadow variable
-
-      std::array< std::array< tk::real, 4 >, 3 > v;
-      v[0] = U.extract( momentumDofIdx(nmat, 0, rdof, 0), N );
-      v[1] = U.extract( momentumDofIdx(nmat, 1, rdof, 0), N );
-      v[2] = U.extract( momentumDofIdx(nmat, 2, rdof, 0), N );
-
-      std::vector< std::array< tk::real, 4 > > ar;
-      ar.resize(nmat);
-      for (std::size_t k=0; k<nmat; ++k)
-        ar[k] = U.extract( densityDofIdx(nmat, k, rdof, 0), N );
-
-      std::array< tk::real, 4 > r{{ 0.0, 0.0, 0.0, 0.0 }};
-      for (std::size_t i=0; i<r.size(); ++i) {
-        for (std::size_t k=0; k<nmat; ++k)
-          r[i] += ar[k][i];
-      }
-
-      std::transform( r.begin(), r.end(), v[0].begin(), v[0].begin(),
-                      []( tk::real s, tk::real& d ){ return d /= s; } );
-      std::transform( r.begin(), r.end(), v[1].begin(), v[1].begin(),
-                      []( tk::real s, tk::real& d ){ return d /= s; } );
-      std::transform( r.begin(), r.end(), v[2].begin(), v[2].begin(),
-                      []( tk::real s, tk::real& d ){ return d /= s; } );
-      return v;
-    }
-
-    //! Return a map that associates user-specified strings to functions
-    //! \return Map that associates user-specified strings to functions that
-    //!   compute relevant quantities to be output to file
-    std::map< std::string, tk::GetVarFn > OutVarFn() const
-    { return MultiMatOutVarFn(); }
-
-    //! Return analytic field names to be output to file
-    //! \return Vector of strings labelling analytic fields output in file
-    std::vector< std::string > analyticFieldNames() const {
-      auto nmat = g_inputdeck.get< eq, tag::nmat >();<--- Shadow variable
-
-      return MultiMatFieldNames(nmat);
-    }
-
-    //! Return surface field names to be output to file
-    //! \return Vector of strings labelling surface fields output in file
-    std::vector< std::string > surfNames() const
-    { return MultiMatSurfNames(); }
-
-    //! Return time history field names to be output to file
-    //! \return Vector of strings labelling time history fields output in file
-    std::vector< std::string > histNames() const {
-      return MultiMatHistNames();
-    }
-
-    //! Return surface field output going to file
-    std::vector< std::vector< tk::real > >
-    surfOutput( const inciter::FaceData& fd,
-      const tk::Fields& U,
-      const tk::Fields& P ) const
-    {
-      const auto rdof = g_inputdeck.get< tag::rdof >();
-      auto nmat = g_inputdeck.get< tag::multimat, tag::nmat >();<--- Shadow variable
-
-      return MultiMatSurfOutput( nmat, rdof, fd, U, P );
-    }
-
-    //! Return time history field output evaluated at time history points
-    //! \param[in] h History point data
-    //! \param[in] inpoel Element-node connectivity
-    //! \param[in] coord Array of nodal coordinates
-    //! \param[in] U Array of unknowns
-    //! \param[in] P Array of primitive quantities
-    //! \return Vector of time history output of bulk flow quantities (density,
-    //!   velocity, total energy, pressure, and volume fraction) evaluated at 
-    //!   time history points
-    std::vector< std::vector< tk::real > >
-    histOutput( const std::vector< HistData >& h,
-                const std::vector< std::size_t >& inpoel,
-                const tk::UnsMesh::Coords& coord,
-                const tk::Fields& U,
-                const tk::Fields& P ) const
-    {
-      const auto rdof = g_inputdeck.get< tag::rdof >();
-      auto nmat = g_inputdeck.get< tag::multimat, tag::nmat >();<--- Shadow variable
-
-      const auto& x = coord[0];
-      const auto& y = coord[1];
-      const auto& z = coord[2];
-
-      std::vector< std::vector< tk::real > > Up(h.size());
-
-      std::size_t j = 0;
-      for (const auto& p : h) {
-        auto e = p.get< tag::elem >();
-        auto chp = p.get< tag::coord >();
-
-        // Evaluate inverse Jacobian
-        std::array< std::array< tk::real, 3>, 4 > cp{{
-          {{ x[inpoel[4*e  ]], y[inpoel[4*e  ]], z[inpoel[4*e  ]] }},
-          {{ x[inpoel[4*e+1]], y[inpoel[4*e+1]], z[inpoel[4*e+1]] }},
-          {{ x[inpoel[4*e+2]], y[inpoel[4*e+2]], z[inpoel[4*e+2]] }},
-          {{ x[inpoel[4*e+3]], y[inpoel[4*e+3]], z[inpoel[4*e+3]] }} }};
-        auto J = tk::inverseJacobian( cp[0], cp[1], cp[2], cp[3] );
-
-        // evaluate solution at history-point
-        std::array< tk::real, 3 > dc{{chp[0]-cp[0][0], chp[1]-cp[0][1],
-          chp[2]-cp[0][2]}};
-        auto B = tk::eval_basis(rdof, tk::dot(J[0],dc), tk::dot(J[1],dc),
-          tk::dot(J[2],dc));
-        auto uhp = eval_state(m_ncomp, rdof, rdof, e, U, B);
-        auto php = eval_state(nprim(), rdof, rdof, e, P, B);
-
-        // store solution in history output vector
-        Up[j].resize(6+nmat, 0.0);
-        for (std::size_t k=0; k<nmat; ++k) {
-          Up[j][0] += uhp[densityIdx(nmat,k)];
-          Up[j][4] += uhp[energyIdx(nmat,k)];
-          Up[j][5] += php[pressureIdx(nmat,k)];
-          Up[j][6+k] = uhp[volfracIdx(nmat,k)];
-        }
-        Up[j][1] = php[velocityIdx(nmat,0)];
-        Up[j][2] = php[velocityIdx(nmat,1)];
-        Up[j][3] = php[velocityIdx(nmat,2)];
-        ++j;
-      }
-
-      return Up;
-    }
-
-    //! Return names of integral variables to be output to diagnostics file
-    //! \return Vector of strings labelling integral variables output
-    std::vector< std::string > names() const
-    {
-      auto nmat = g_inputdeck.get< tag::multimat, tag::nmat >();<--- Shadow variable
-      return MultiMatDiagNames(nmat);
-    }
-
-    //! Return analytic solution (if defined by Problem) at xi, yi, zi, t
-    //! \param[in] xi X-coordinate at which to evaluate the analytic solution
-    //! \param[in] yi Y-coordinate at which to evaluate the analytic solution
-    //! \param[in] zi Z-coordinate at which to evaluate the analytic solution
-    //! \param[in] t Physical time at which to evaluate the analytic solution
-    //! \return Vector of analytic solution at given location and time
-    std::vector< tk::real >
-    analyticSolution( tk::real xi, tk::real yi, tk::real zi, tk::real t ) const
-    { return Problem::analyticSolution( m_ncomp, m_mat_blk, xi, yi, zi, t ); }
-
-    //! Return analytic solution for conserved variables
-    //! \param[in] xi X-coordinate at which to evaluate the analytic solution
-    //! \param[in] yi Y-coordinate at which to evaluate the analytic solution
-    //! \param[in] zi Z-coordinate at which to evaluate the analytic solution
-    //! \param[in] t Physical time at which to evaluate the analytic solution
-    //! \return Vector of analytic solution at given location and time
-    std::vector< tk::real >
-    solution( tk::real xi, tk::real yi, tk::real zi, tk::real t ) const
-    { return Problem::initialize( m_ncomp, m_mat_blk, xi, yi, zi, t ); }
-
-    //! Return cell-averaged specific total energy for an element
-    //! \param[in] e Element id for which total energy is required
-    //! \param[in] unk Vector of conserved quantities
-    //! \return Cell-averaged specific total energy for given element
-    tk::real sp_totalenergy(std::size_t e, const tk::Fields& unk) const
-    {
-      const auto rdof = g_inputdeck.get< tag::rdof >();
-      auto nmat = g_inputdeck.get< tag::multimat, tag::nmat >();<--- Shadow variable
-
-      tk::real sp_te(0.0);
-      // sum each material total energy
-      for (std::size_t k=0; k<nmat; ++k) {
-        sp_te += unk(e, energyDofIdx(nmat,k,rdof,0));
-      }
-      return sp_te;
-    }
-
-    //! Compute relevant sound speed for output
-    //! \param[in] nielem Number of internal elements
-    //! \param[in] U Solution vector at recent time step
-    //! \param[in] P Primitive vector at recent time step
-    //! \param[in,out] ss Sound speed vector
-    void soundspeed(
-      std::size_t nielem,
-      const tk::Fields& U,
-      const tk::Fields& P,
-      std::vector< tk::real >& ss) const
-    {
-      Assert( ss.size() == nielem, "Size of sound speed vector incorrect " );
-
-      const auto ndof = g_inputdeck.get< tag::ndof >();
-      const auto rdof = g_inputdeck.get< tag::rdof >();
-      const auto use_mass_avg =
-        g_inputdeck.get< tag::multimat, tag::dt_sos_massavg >();
-      auto nmat = g_inputdeck.get< tag::multimat, tag::nmat >();<--- Shadow variable
-      std::size_t ncomp = U.nprop()/rdof;
-      std::size_t nprim = P.nprop()/rdof;<--- Shadow variable
-
-      std::vector< tk::real > ugp(ncomp, 0.0), pgp(nprim, 0.0);<--- Variable 'ugp' is assigned a value that is never used.<--- Variable 'pgp' is assigned a value that is never used.
-
-      for (std::size_t e=0; e<nielem; ++e) {
-        // basis function at centroid
-        std::vector< tk::real > B(rdof, 0.0);
-        B[0] = 1.0;
-
-        // get conserved quantities
-        ugp = eval_state(ncomp, rdof, ndof, e, U, B);
-        // get primitive quantities
-        pgp = eval_state(nprim, rdof, ndof, e, P, B);
-
-        // acoustic speed (this should be consistent with time-step calculation)
-        ss[e] = 0.0;
-        tk::real mixtureDensity = 0.0;
-        for (std::size_t k=0; k<nmat; ++k)
-        {
-          if (use_mass_avg > 0)
-          {
-            // mass averaging SoS
-            ss[e] += ugp[densityIdx(nmat,k)]*
-              m_mat_blk[k].compute< EOS::soundspeed >(
-              ugp[densityIdx(nmat, k)], pgp[pressureIdx(nmat, k)],
-              ugp[volfracIdx(nmat, k)], k );
-
-            mixtureDensity += ugp[densityIdx(nmat,k)];
-          }
-          else
-          {
-            if (ugp[volfracIdx(nmat, k)] > 1.0e-04)
-            {
-              ss[e] = std::max( ss[e], m_mat_blk[k].compute< EOS::soundspeed >(
-                ugp[densityIdx(nmat, k)], pgp[pressureIdx(nmat, k)],
-                ugp[volfracIdx(nmat, k)], k ) );
-            }
-          }
-        }
-        if (use_mass_avg > 0) ss[e] /= mixtureDensity;
-      }
-    }
-
-  private:
-    //! Physics policy
-    const Physics m_physics;
-    //! Number of components in this PDE system
-    const ncomp_t m_ncomp;
-    //! Riemann solver
-    tk::RiemannFluxFn m_riemann;
-    //! BC configuration
-    BCStateFn m_bc;
-    //! EOS material block
-    std::vector< EOS > m_mat_blk;
-
-    //! Evaluate conservative part of physical flux function for this PDE system
-    //! \param[in] ncomp Number of scalar components in this PDE system
-    //! \param[in] ugp Numerical solution at the Gauss point at which to
-    //!   evaluate the flux
-    //! \return Flux vectors for all components in this PDE system
-    //! \note The function signature must follow tk::FluxFn
-    static tk::FluxFn::result_type
-    flux( ncomp_t ncomp,
-          const std::vector< EOS >& mat_blk,
-          const std::vector< tk::real >& ugp,
-          const std::vector< std::array< tk::real, 3 > >& )
-    {
-      auto nmat = g_inputdeck.get< tag::multimat, tag::nmat >();<--- Shadow variable
-
-      return tk::fluxTerms(ncomp, nmat, mat_blk, ugp);
-    }
-
-    //! \brief Boundary state function providing the left and right state of a
-    //!   face at Dirichlet boundaries
-    //! \param[in] ncomp Number of scalar components in this PDE system
-    //! \param[in] ul Left (domain-internal) state
-    //! \param[in] x X-coordinate at which to compute the states
-    //! \param[in] y Y-coordinate at which to compute the states
-    //! \param[in] z Z-coordinate at which to compute the states
-    //! \param[in] t Physical time
-    //! \return Left and right states for all scalar components in this PDE
-    //!   system
-    //! \note The function signature must follow tk::StateFn. For multimat, the
-    //!   left or right state is the vector of conserved quantities, followed by
-    //!   the vector of primitive quantities appended to it.
-    static tk::StateFn::result_type
-    dirichlet( ncomp_t ncomp,
-               const std::vector< EOS >& mat_blk,
-               const std::vector< tk::real >& ul, tk::real x, tk::real y,
-               tk::real z, tk::real t, const std::array< tk::real, 3 >& )
-    {
-      auto nmat = g_inputdeck.get< tag::multimat, tag::nmat >();<--- Shadow variable<--- Variable 'nmat' is assigned a value that is never used.
-
-      auto ur = Problem::initialize( ncomp, mat_blk, x, y, z, t );
-      Assert( ur.size() == ncomp, "Incorrect size for boundary state vector" );
-
-      ur.resize(ul.size());
-
-      tk::real rho(0.0);
-      for (std::size_t k=0; k<nmat; ++k)
-        rho += ur[densityIdx(nmat, k)];
-
-      // get primitives in boundary state
-
-      // velocity
-      ur[ncomp+velocityIdx(nmat, 0)] = ur[momentumIdx(nmat, 0)] / rho;
-      ur[ncomp+velocityIdx(nmat, 1)] = ur[momentumIdx(nmat, 1)] / rho;
-      ur[ncomp+velocityIdx(nmat, 2)] = ur[momentumIdx(nmat, 2)] / rho;
-
-      // material pressures
-      for (std::size_t k=0; k<nmat; ++k)
-      {
-        auto gk = getDeformGrad(nmat, k, ur);
-        ur[ncomp+pressureIdx(nmat, k)] = mat_blk[k].compute< EOS::pressure >(
-          ur[densityIdx(nmat, k)], ur[ncomp+velocityIdx(nmat, 0)],
-          ur[ncomp+velocityIdx(nmat, 1)], ur[ncomp+velocityIdx(nmat, 2)],
-          ur[energyIdx(nmat, k)], ur[volfracIdx(nmat, k)], k, gk );
-      }
-
-      Assert( ur.size() == ncomp+nmat+3, "Incorrect size for appended "
-              "boundary state vector" );
-
-      return {{ std::move(ul), std::move(ur) }};
-    }
-
-    // Other boundary condition types that do not depend on "Problem" should be
-    // added in BCFunctions.hpp
-};
-
-} // fv::
-
-} // inciter::
-
-#endif // FVMultiMat_h
+    //! Public interface to return point history output
+    std::vector< std::vector< tk::real > >
+    histOutput( const std::vector< HistData >& h,
+      const std::vector< std::size_t >& inpoel,
+      const tk::UnsMesh::Coords& coord,
+      const tk::Fields& U,
+      const tk::Fields& P ) const
+    { return self->histOutput( h, inpoel, coord, U, P ); }
+
+    //! Public interface to returning analytic solution
+    tk::InitializeFn::result_type
+    analyticSolution( tk::real xi, tk::real yi, tk::real zi, tk::real t ) const
+    { return self->analyticSolution( xi, yi, zi, t ); }
+
+    //! Public interface to returning the analytic solution for conserved vars
+    tk::InitializeFn::result_type
+    solution( tk::real xi, tk::real yi, tk::real zi, tk::real t ) const
+    { return self->solution( xi, yi, zi, t ); }
+
+    //! Public interface to returning the specific total energy
+    tk::real
+    sp_totalenergy( std::size_t e, const tk::Fields& unk ) const
+    { return self->sp_totalenergy( e, unk ); }
+
+    //! Copy assignment
+    DGPDE& operator=( const DGPDE& x )
+    { DGPDE tmp(x); *this = std::move(tmp); return *this; }
+    //! Copy constructor
+    DGPDE( const DGPDE& x ) : self( x.self->copy() ) {}
+    //! Move assignment
+    DGPDE& operator=( DGPDE&& ) noexcept = default;
+    //! Move constructor
+    DGPDE( DGPDE&& ) noexcept = default;
+
+  private:
+    //! \brief Concept is a pure virtual base class specifying the requirements
+    //!   of polymorphic objects deriving from it
+    struct Concept {
+      Concept() = default;
+      Concept( const Concept& ) = default;
+      virtual ~Concept() = default;
+      virtual Concept* copy() const = 0;
+      virtual std::size_t nprim() const = 0;
+      virtual std::size_t nmat() const = 0;
+      virtual void numEquationDofs(std::vector< std::size_t >&) const = 0;
+      virtual std::size_t nstiffeq() const = 0;
+      virtual std::size_t nnonstiffeq() const = 0;
+      virtual void setStiffEqIdx( std::vector< std::size_t >& ) const = 0;
+      virtual void setNonStiffEqIdx( std::vector< std::size_t >& ) const = 0;
+      virtual void IcBoxElems( const tk::Fields&,
+        std::size_t,
+        std::vector< std::unordered_set< std::size_t > >& ) const = 0;
+      virtual void initialize(
+        const tk::Fields&,
+        const std::vector< std::size_t >&,
+        const tk::UnsMesh::Coords&,
+        const std::vector< std::unordered_set< std::size_t > >&,
+        const std::unordered_map< std::size_t, std::set< std::size_t > >&,
+        tk::Fields&,
+        tk::real,
+        const std::size_t nielem ) const = 0;
+      virtual void setRho0mat( std::vector< tk::real >& ) const = 0;
+      virtual void computeDensityConstr( std::size_t nelem,
+                                         tk::Fields& unk,
+                                         std::vector< tk::real >& rho0mat,
+                                         std::vector< tk::real >& densityConstr)
+                                         const = 0;
+      virtual void lhs( const tk::Fields&, tk::Fields& ) const = 0;
+      virtual void updateInterfaceCells( tk::Fields&,
+                                         std::size_t,
+                                         std::vector< std::size_t >& ) const = 0;
+      virtual void updatePrimitives( const tk::Fields&,
+                                     const tk::Fields&,
+                                     const tk::Fields&,
+                                     tk::Fields&,
+                                     std::size_t ) const = 0;
+      virtual void cleanTraceMaterial( tk::real,
+                                       const tk::Fields&,
+                                       tk::Fields&,
+                                       tk::Fields&,
+                                       std::size_t ) const = 0;
+      virtual void reconstruct( tk::real,
+                                const tk::Fields&,
+                                const tk::Fields&,
+                                const inciter::FaceData&,
+                                const std::map< std::size_t,
+                                  std::vector< std::size_t > >&,
+                                const std::vector< std::size_t >&,
+                                const tk::UnsMesh::Coords&,
+                                tk::Fields&,
+                                tk::Fields& ) const = 0;
+      virtual void limit( tk::real,
+                          const tk::Fields&,
+                          const tk::Fields&,
+                          const inciter::FaceData&,
+                          const std::map< std::size_t,
+                            std::vector< std::size_t > >&,
+                          const std::vector< std::size_t >&,
+                          const tk::UnsMesh::Coords&,
+                          const std::vector< std::size_t >&,
+                          const std::vector< std::size_t >&,
+                          const std::unordered_map< std::size_t, std::size_t >&,
+                          const std::vector< std::vector<tk::real> >&,
+                          const std::vector< std::vector<tk::real> >&,
+                          const std::vector< std::vector<tk::real> >&,
+                          tk::Fields&,
+                          tk::Fields&,
+                          std::vector< std::size_t >& ) const = 0;
+      virtual void CPL( const tk::Fields&,
+                        const tk::Fields&,
+                        const std::vector< std::size_t >&,
+                        const tk::UnsMesh::Coords&,
+                        tk::Fields&,
+                        std::size_t ) const = 0;
+      virtual std::array< std::vector< tk::real >, 9 > cellAvgDeformGrad(
+        const tk::Fields&,
+        std::size_t ) const = 0;
+      virtual void rhs( tk::real,
+                        const tk::Fields&,
+                        const tk::Fields&,
+                        const inciter::FaceData&,
+                        const std::vector< std::size_t >&,
+                        const std::vector< std::unordered_set< std::size_t > >&,
+                        const tk::UnsMesh::Coords&,
+                        const tk::Fields&,
+                        const tk::Fields&,
+                        const std::vector< std::size_t >&,
+                        const std::vector< tk::real >&,
+                        const tk::real,
+                        tk::Fields& ) const = 0;
+      virtual void eval_ndof( std::size_t,
+                              const tk::UnsMesh::Coords&,
+                              const std::vector< std::size_t >&,
+                              const inciter::FaceData&,
+                              const tk::Fields&,
+                              const tk::Fields&,
+                              inciter::ctr::PrefIndicatorType,
+                              std::size_t,
+                              std::size_t,
+                              tk::real,
+                              std::vector< std::size_t >& ) const = 0;
+      virtual tk::real dt( const std::array< std::vector< tk::real >, 3 >&,
+                           const std::vector< std::size_t >&,
+                           const inciter::FaceData&,
+                           const tk::Fields&,
+                           const tk::Fields&,
+                           const std::vector< std::size_t >&,
+                           const tk::Fields&,
+                           const tk::Fields&,
+                           const std::size_t ) const = 0;
+      virtual void stiff_rhs( std::size_t,
+                              const tk::Fields&,
+                              const std::vector< std::size_t >&,
+                              const tk::UnsMesh::Coords&,
+                              const tk::Fields&,
+                              const tk::Fields&,
+                              const std::vector< std::size_t >&,
+                              tk::Fields& ) const = 0;
+      virtual std::map< std::string, tk::GetVarFn > OutVarFn() const = 0;
+      virtual std::vector< std::string > analyticFieldNames() const = 0;
+      virtual std::vector< std::string > histNames() const = 0;
+      virtual std::vector< std::string > names() const = 0;
+      virtual std::vector< std::vector< tk::real > > surfOutput(
+        const std::map< int, std::vector< std::size_t > >&,
+        tk::Fields& ) const = 0;
+      virtual std::vector< std::vector< tk::real > > histOutput(
+        const std::vector< HistData >&,
+        const std::vector< std::size_t >&,
+        const tk::UnsMesh::Coords&,
+        const tk::Fields&,
+        const tk::Fields& ) const = 0;
+      virtual tk::InitializeFn::result_type analyticSolution(
+        tk::real xi, tk::real yi, tk::real zi, tk::real t ) const = 0;
+      virtual tk::InitializeFn::result_type solution(
+        tk::real xi, tk::real yi, tk::real zi, tk::real t ) const = 0;
+      virtual tk::real sp_totalenergy(
+        std::size_t, const tk::Fields& ) const = 0;
+    };
+
+    //! \brief Model models the Concept above by deriving from it and overriding
+    //!   the virtual functions required by Concept
+    template< typename T >
+    struct Model : Concept {
+      explicit Model( T x ) : data( std::move(x) ) {}
+      Concept* copy() const override { return new Model( *this ); }
+      std::size_t nprim() const override
+      { return data.nprim(); }
+      std::size_t nmat() const override
+      { return data.nmat(); }
+      void numEquationDofs(std::vector< std::size_t >& numEqDof) const override
+      { data.numEquationDofs(numEqDof); }
+      std::size_t nstiffeq() const override
+      { return data.nstiffeq(); }
+      std::size_t nnonstiffeq() const override
+      { return data.nnonstiffeq(); }
+      void setStiffEqIdx( std::vector< std::size_t >& stiffEqIdx ) const override
+      { data.setStiffEqIdx(stiffEqIdx); }
+      void setNonStiffEqIdx( std::vector< std::size_t >& nonStiffEqIdx ) const override
+      { data.setNonStiffEqIdx(nonStiffEqIdx); }
+      void IcBoxElems( const tk::Fields& geoElem,
+        std::size_t nielem,
+        std::vector< std::unordered_set< std::size_t > >& inbox )
+      const override { data.IcBoxElems( geoElem, nielem, inbox ); }
+      void initialize(
+        const tk::Fields& L,
+        const std::vector< std::size_t >& inpoel,
+        const tk::UnsMesh::Coords& coord,
+        const std::vector< std::unordered_set< std::size_t > >& inbox,
+        const std::unordered_map< std::size_t, std::set< std::size_t > >&
+          elemblkid,
+        tk::Fields& unk,
+        tk::real t,
+        const std::size_t nielem )
+      const override { data.initialize( L, inpoel, coord, inbox, elemblkid, unk,
+        t, nielem ); }
+      void setRho0mat( std::vector< tk::real >& rho0mat ) const override
+      { data.setRho0mat( rho0mat ); }
+      void computeDensityConstr( std::size_t nelem,
+                                 tk::Fields& unk,
+                                 std::vector< tk::real >& rho0mat,
+                                 std::vector< tk::real >& densityConstr)
+                                 const override
+      { data.computeDensityConstr( nelem, unk, rho0mat, densityConstr ); }
+      void lhs( const tk::Fields& geoElem, tk::Fields& l ) const override
+      { data.lhs( geoElem, l ); }
+      void updateInterfaceCells( tk::Fields& unk,
+                                 std::size_t nielem,
+                                 std::vector< std::size_t >& ndofel )
+      const override { data.updateInterfaceCells( unk, nielem, ndofel ); }
+      void updatePrimitives( const tk::Fields& unk,
+                             const tk::Fields& L,
+                             const tk::Fields& geoElem,
+                             tk::Fields& prim,
+                             std::size_t nielem )
+      const override { data.updatePrimitives( unk, L, geoElem, prim, nielem ); }
+      void cleanTraceMaterial( tk::real t,
+                               const tk::Fields& geoElem,
+                               tk::Fields& unk,
+                               tk::Fields& prim,
+                               std::size_t nielem )
+      const override { data.cleanTraceMaterial( t, geoElem, unk, prim, nielem ); }
+      void reconstruct( tk::real t,
+                        const tk::Fields& geoFace,
+                        const tk::Fields& geoElem,
+                        const inciter::FaceData& fd,
+                        const std::map< std::size_t,
+                          std::vector< std::size_t > >& esup,
+                        const std::vector< std::size_t >& inpoel,
+                        const tk::UnsMesh::Coords& coord,
+                        tk::Fields& U,
+                        tk::Fields& P ) const override
+      {
+        data.reconstruct( t, geoFace, geoElem, fd, esup, inpoel, coord, U, P );
+      }
+      void limit( tk::real t,
+                  const tk::Fields& geoFace,
+                  const tk::Fields& geoElem,
+                  const inciter::FaceData& fd,
+                  const std::map< std::size_t, std::vector< std::size_t > >&
+                    esup,
+                  const std::vector< std::size_t >& inpoel,
+                  const tk::UnsMesh::Coords& coord,
+                  const std::vector< std::size_t >& ndofel,
+                  const std::vector< std::size_t >& gid,
+                  const std::unordered_map< std::size_t, std::size_t >& bid,
+                  const std::vector< std::vector<tk::real> >& uNodalExtrm,
+                  const std::vector< std::vector<tk::real> >& pNodalExtrm,
+                  const std::vector< std::vector<tk::real> >& mtInv,
+                  tk::Fields& U,
+                  tk::Fields& P,
+                  std::vector< std::size_t >& shockmarker ) const override
+      {
+        data.limit( t, geoFace, geoElem, fd, esup, inpoel, coord, ndofel, gid,
+                    bid, uNodalExtrm, pNodalExtrm, mtInv, U, P, shockmarker );
+      }
+      void CPL( const tk::Fields& prim,
+                const tk::Fields& geoElem,
+                const std::vector< std::size_t >& inpoel,
+                const tk::UnsMesh::Coords& coord,
+                tk::Fields& unk,
+                std::size_t nielem ) const override
+      {
+        data.CPL( prim, geoElem, inpoel, coord, unk, nielem );
+      }
+      std::array< std::vector< tk::real >, 9 > cellAvgDeformGrad(
+        const tk::Fields& U,
+        std::size_t nielem ) const override
+      {
+        return data.cellAvgDeformGrad( U, nielem );
+      }
+      void rhs(
+        tk::real t,
+        const tk::Fields& geoFace,
+        const tk::Fields& geoElem,
+        const inciter::FaceData& fd,
+        const std::vector< std::size_t >& inpoel,
+        const std::vector< std::unordered_set< std::size_t > >& boxelems,
+        const tk::UnsMesh::Coords& coord,
+        const tk::Fields& U,
+        const tk::Fields& P,
+        const std::vector< std::size_t >& ndofel,
+        const std::vector< tk::real >& rho0mat,
+        const tk::real dt,
+        tk::Fields& R ) const override
+      {
+        data.rhs( t, geoFace, geoElem, fd, inpoel, boxelems, coord, U, P,
+                  ndofel, rho0mat, dt, R );
+      }
+      void eval_ndof( std::size_t nunk,
+                      const tk::UnsMesh::Coords& coord,
+                      const std::vector< std::size_t >& inpoel,
+                      const inciter::FaceData& fd,
+                      const tk::Fields& unk,
+                      const tk::Fields& prim,
+                      inciter::ctr::PrefIndicatorType indicator,
+                      std::size_t ndof,
+                      std::size_t ndofmax,
+                      tk::real tolref,
+                      std::vector< std::size_t >& ndofel ) const override
+      { data.eval_ndof( nunk, coord, inpoel, fd, unk, prim, indicator, ndof,
+                        ndofmax, tolref, ndofel ); }
+      tk::real dt( const std::array< std::vector< tk::real >, 3 >& coord,
+                   const std::vector< std::size_t >& inpoel,
+                   const inciter::FaceData& fd,
+                   const tk::Fields& geoFace,
+                   const tk::Fields& geoElem,
+                   const std::vector< std::size_t >& ndofel,
+                   const tk::Fields& U,
+                   const tk::Fields& P,
+                   const std::size_t nielem ) const override
+      { return data.dt( coord, inpoel, fd, geoFace, geoElem, ndofel,
+                        U, P, nielem ); }
+      void stiff_rhs( std::size_t e,
+                      const tk::Fields& geoElem,
+                      const std::vector< std::size_t >& inpoel,
+                      const tk::UnsMesh::Coords& coord,
+                      const tk::Fields& U,
+                      const tk::Fields& P,
+                      const std::vector< std::size_t >& ndofel,
+                      tk::Fields& R ) const override
+      { return data.stiff_rhs( e, geoElem, inpoel, coord, U, P, ndofel, R ); }
+      std::map< std::string, tk::GetVarFn > OutVarFn() const override
+      { return data.OutVarFn(); }
+      std::vector< std::string > analyticFieldNames() const override
+      { return data.analyticFieldNames(); }
+      std::vector< std::string > histNames() const override
+      { return data.histNames(); }
+      std::vector< std::string > names() const override
+      { return data.names(); }
+      std::vector< std::vector< tk::real > > surfOutput(
+        const std::map< int, std::vector< std::size_t > >& bnd,
+        tk::Fields& U ) const override
+      { return data.surfOutput( bnd, U ); }
+      std::vector< std::vector< tk::real > > histOutput(
+        const std::vector< HistData >& h,
+        const std::vector< std::size_t >& inpoel,
+        const tk::UnsMesh::Coords& coord,
+        const tk::Fields& U,
+        const tk::Fields& P ) const override
+      { return data.histOutput( h, inpoel, coord, U, P ); }
+      tk::InitializeFn::result_type
+      analyticSolution( tk::real xi, tk::real yi, tk::real zi, tk::real t )
+       const override { return data.analyticSolution( xi, yi, zi, t ); }
+      tk::InitializeFn::result_type
+      solution( tk::real xi, tk::real yi, tk::real zi, tk::real t )
+       const override { return data.solution( xi, yi, zi, t ); }
+      tk::real sp_totalenergy( std::size_t e, const tk::Fields& unk )
+       const override { return data.sp_totalenergy( e, unk ); }
+      T data;
+    };
+
+    std::unique_ptr< Concept > self;    //!< Base pointer used polymorphically
+};
+
+} // inciter::
+
+#endif // DGPDE_h
 
diff --git a/Debug/cppcheck/49.html b/Debug/cppcheck/49.html index 3d4333aca98b..167d48dd9ca0 100644 --- a/Debug/cppcheck/49.html +++ b/Debug/cppcheck/49.html @@ -152,12 +152,12 @@
  1
@@ -323,1286 +323,170 @@ 

Cppcheck report - [

// *****************************************************************************
+164
// *****************************************************************************
 /*!
-  \file      src/PDE/DGPDE.hpp
+  \file      src/PDE/ConfigureMultiMat.cpp
   \copyright 2012-2015 J. Bakosi,
              2016-2018 Los Alamos National Security, LLC.,
              2019-2021 Triad National Security, LLC.
              All rights reserved. See the LICENSE file for details.
-  \brief     Partial differential equation base for discontinuous Galerkin PDEs
-  \details   This file defines a generic partial differential equation (PDE)
-    class for PDEs that use discontinuous Galerkin spatial discretization.
-    The class uses runtime polymorphism without client-side inheritance:
-    inheritance is confined to the internals of the class, invisible to
-    client-code. The class exclusively deals with ownership enabling client-side
-    value semantics. Credit goes to Sean Parent at Adobe:
-    https://github.com/sean-parent/sean-parent.github.com/wiki/
-    Papers-and-Presentations.
-*/
-// *****************************************************************************
-#ifndef DGPDE_h
-#define DGPDE_h
+  \brief     Register and compile configuration for multi-material compressible
+     flow PDE
+  \details   Register and compile configuration for compressible multi-material
+     flow PDE.
+*/
+// *****************************************************************************
+
+#include <set>
+#include <map>
+#include <vector>
+#include <string>
+
+#include <brigand/algorithms/for_each.hpp>
 
-#include <array>
-#include <string>
-#include <vector>
-#include <memory>
-#include <unordered_set>
-#include <functional>
-
-#include "Types.hpp"
-#include "Fields.hpp"
-#include "FaceData.hpp"
-#include "UnsMesh.hpp"
-#include "Inciter/InputDeck/InputDeck.hpp"
-#include "FunctionPrototypes.hpp"
-#include "History.hpp"
+#include "Tags.hpp"
+#include "CartesianProduct.hpp"
+#include "PDEFactory.hpp"
+#include "Inciter/Options/PDE.hpp"
+#include "ContainerUtil.hpp"
+#include "ConfigureMultiMat.hpp"
+#include "MultiMat/Physics/DG.hpp"
+#include "MultiMat/Physics/FV.hpp"
+#include "MultiMat/DGMultiMat.hpp"
+#include "MultiMat/FVMultiMat.hpp"
+#include "MultiMat/Problem.hpp"
+#include "Inciter/Options/Material.hpp"
+
+namespace inciter {
 
-namespace inciter {
-
-extern ctr::InputDeck g_inputdeck;
-
-using ncomp_t = tk::ncomp_t;
-using BCStateFn =
-  std::vector< std::pair< std::vector< std::size_t >, tk::StateFn > >;
-
-//! Extract BC configuration ignoring if BC not specified
-//! \note A more preferable way of catching errors such as this function
-//!   hides is during parsing, so that we don't even get here if BCs are
-//!   not correctly specified. For now we simply ignore if BCs are not
-//!   specified by allowing empty BC vectors from the user input.
-struct ConfigBC {
-  BCStateFn& state;    //!< BC state config: sidesets + statefn
-  const std::vector< tk::StateFn >& fn;    //!< BC state functions
-  std::size_t c;       //!< Counts BC types configured
-  //! Constructor
-  ConfigBC( BCStateFn& s,
-            const std::vector< tk::StateFn >& f ) :
-    state(s), fn(f), c(0) {}
-  //! Function to call for each BC type
-  template< typename U > void operator()( brigand::type_<U> ) {
-    std::vector< std::size_t > cfg, v;
-    // collect sidesets across all meshes
-    for (const auto& ibc : g_inputdeck.get< tag::bc >()) {
-      v.insert(v.end(), ibc.get< U >().begin(), ibc.get< U >().end());
-    }
-    if (v.size() > 0) cfg = v;<--- Variable 'cfg' is assigned a value that is never used.
-    Assert( fn.size() > c, "StateFn missing for BC type" );
-    state.push_back( { cfg, fn[c++] } );
-  }
-};
-
-//! State function for invalid/un-configured boundary conditions
-[[noreturn]] tk::StateFn::result_type
-invalidBC( ncomp_t, const std::vector< EOS >&,
-           const std::vector< tk::real >&, tk::real, tk::real, tk::real,
-           tk::real, const std::array< tk::real, 3> & );
-
-//! \brief Partial differential equation base for discontinuous Galerkin PDEs
-//! \details This class uses runtime polymorphism without client-side
-//!   inheritance: inheritance is confined to the internals of the this class,
-//!   invisible to client-code. The class exclusively deals with ownership
-//!   enabling client-side value semantics. Credit goes to Sean Parent at Adobe:
-//!   https://github.com/sean-parent/sean-parent.github.com/wiki/
-//!   Papers-and-Presentations. For example client code that models a DGPDE,
-//!   see inciter::CompFlow.
-class DGPDE {
-
-  private:
-    using ncomp_t = tk::ncomp_t;
-
-  public:
-    //! Default constructor taking no arguments for Charm++
-    explicit DGPDE() = default;
+void
+registerMultiMat( DGFactory& df, FVFactory& ff,
+  std::set< ctr::PDEType >& fvt, std::set< ctr::PDEType >& dgt )
+// *****************************************************************************
+// Register multi-material compressible flow PDE into PDE factory
+//! \param[in,out] df Discontinuous Galerkin PDE factory to register to
+//! \param[in,out] ff Finite volume PDE factory to register to
+//! \param[in,out] dgt Counters for equation types registered into DG factory
+//! \param[in,out] fvt Counters for equation types registered into FV factory
+// *****************************************************************************
+{
+  // Construct vector of vectors for all possible policies
+  using DGMultiMatPolicies =
+    tk::cartesian_product< dg::MultiMatPhysics, MultiMatProblems >;
+  // Register PDEs for all combinations of policies
+  brigand::for_each< DGMultiMatPolicies >(
+    registerDG< dg::MultiMat >( df, dgt, ctr::PDEType::MULTIMAT ) );
+
+  // Construct vector of vectors for all possible policies
+  using FVMultiMatPolicies =
+    tk::cartesian_product< fv::MultiMatPhysics, MultiMatProblems >;
+  // Register PDEs for all combinations of policies
+  brigand::for_each< FVMultiMatPolicies >(
+    registerFV< fv::MultiMat >( ff, fvt, ctr::PDEType::MULTIMAT ) );
+}
+
+std::vector< std::pair< std::string, std::string > >
+infoMultiMat( std::map< ctr::PDEType, tk::ncomp_t >& cnt )
+// *****************************************************************************
+//  Return information on the compressible flow system of PDEs
+//! \param[inout] cnt std::map of counters for all PDE types
+//! \return vector of string pairs describing the PDE configuration
+// *****************************************************************************
+{
+  using eq = tag::multimat;
+  using tk::parameter;
+  using tk::parameters;
+
+  auto c = ++cnt[ ctr::PDEType::MULTIMAT ];       // count eqs
+  --c;  // used to index vectors starting with 0<--- Variable 'c' is assigned a value that is never used.
+
+  std::vector< std::pair< std::string, std::string > > nfo;
+
+  nfo.emplace_back( ctr::PDE().name( ctr::PDEType::MULTIMAT ), "" );
+
+  nfo.emplace_back( "physics", ctr::Physics().name(
+    g_inputdeck.get< eq, tag::physics >() ) );
+
+  nfo.emplace_back( "problem", ctr::Problem().name(
+    g_inputdeck.get< eq, tag::problem >() ) );
+
+  nfo.emplace_back( "flux", ctr::Flux().name(
+    g_inputdeck.get< tag::flux >() ) );
+
+  auto nmat = g_inputdeck.get< eq, tag::nmat >();
+  nfo.emplace_back( "number of materials", std::to_string( nmat ) );
 
-    //! \brief Constructor taking an object modeling Concept.
-    //! \details The object of class T comes pre-constructed.
-    //! \param[in] x Instantiated object of type T given by the template
-    //!   argument.
-    template< typename T > explicit DGPDE( T x ) :
-      self( std::make_unique< Model<T> >( std::move(x) ) ) {}
-
-    //! \brief Constructor taking a function pointer to a constructor of an
-    //!   object modeling Concept.
-    //! \details Passing std::function allows late execution of the constructor,
-    //!   i.e., as late as inside this class' constructor, and thus usage from
-    //!   a factory. Note that there are at least two different ways of using
-    //!   this constructor:
-    //!   - Bind T's constructor arguments and place it in std::function<T()>
-    //!   and passing no arguments as args.... This case then instantiates the
-    //!   model via its constructor and stores it in here.
-    //!   - Bind a single placeholder argument to T's constructor and pass it in
-    //!   as host's args..., which then forwards it to model's constructor. This
-    //!   allows late binding, i.e., binding the argument only here.
-    //! \see See also the wrapper tk::recordModel() which does the former and
-    //!   tk::recordModelLate() which does the latter, both defined in
-    //!   src/Base/Factory.h.
-    //! \param[in] x Function pointer to a constructor of an object modeling
-    //!    Concept.
-    //! \param[in] args Zero or more constructor arguments
-    template< typename T, typename...Args >
-    explicit DGPDE( std::function<T(Args...)> x, Args&&... args ) :
-      self( std::make_unique< Model<T> >(
-              std::move( x( std::forward<Args>(args)... ) ) ) ) {}
-
-    //! Public interface to find number of primitive quantities for the diff eq
-    std::size_t nprim() const
-    { return self->nprim(); }
-
-    //! Public interface to find number of materials for the diff eq
-    std::size_t nmat() const
-    { return self->nmat(); }
+  auto prelax = g_inputdeck.get< eq, tag::prelax >();
+  nfo.emplace_back( "finite pressure relaxation", std::to_string( prelax ) );
+
+  auto intsharp = g_inputdeck.get< eq, tag::intsharp >();
+  nfo.emplace_back( "interface sharpening", std::to_string( intsharp ) );
+
+  auto rho0cn = g_inputdeck.get< eq, tag::rho0constraint >();
+  nfo.emplace_back( "density constraint correction", std::to_string( rho0cn ) );
+
+  auto ncomp = g_inputdeck.get< tag::ncomp >();
+  nfo.emplace_back( "number of components", std::to_string( ncomp ) );
+
+  // Material eos output
+  const auto& matprop = g_inputdeck.get< tag::material >();
+  for (const auto& mtype : matprop) {
+    const auto& m_id = mtype.get< tag::id >();
+    ctr::Material opt;
+    nfo.emplace_back( opt.name( mtype.get< tag::eos >() ),
+      std::to_string(m_id.size())+" materials" );
+    nfo.emplace_back( "material id", parameters( m_id ) );
+  }
+
+  // ICs and IC-boxes
+
+  const auto& ic = g_inputdeck.get< tag::ic >();
+
+  const auto& bgmatidic = ic.get< tag::materialid >();
+  nfo.emplace_back( "IC background material id", parameter( bgmatidic ) );
+
+  const auto& icbox = ic.get< tag::box >();
+  if (!icbox.empty()) {
+    std::size_t bcnt = 0;
+    for (const auto& b : icbox) {   // for all boxes configured for this eq
+      std::vector< tk::real > box
+        { b.get< tag::xmin >(), b.get< tag::xmax >(),
+          b.get< tag::ymin >(), b.get< tag::ymax >(),
+          b.get< tag::zmin >(), b.get< tag::zmax >() };
 
-    //! Public interface to find Dofs for each equation in pde system
-    void numEquationDofs(std::vector< std::size_t >& numEqDof) const
-    { return self->numEquationDofs(numEqDof); }
-
-    //! Public interface to find how 'stiff equations', which are the inverse
-    //! deformation equations because of plasticity
-    std::size_t nstiffeq() const
-    { return self->nstiffeq(); }
+      std::string boxname = "IC box " + parameter(bcnt);
+      nfo.emplace_back( boxname, parameters( box ) );
+
+      nfo.emplace_back( boxname + " orientation",
+        parameters(b.get< tag::orientation >()) );
+
+      nfo.emplace_back( boxname + " material id",
+                        parameter( b.get< tag::materialid >() ) );
 
-    //! Public interface to find how 'nonstiff equations', which are the inverse
-    //! deformation equations because of plasticity
-    std::size_t nnonstiffeq() const
-    { return self->nnonstiffeq(); }
-
-    //! Public function to locate the stiff equations
-    void setStiffEqIdx( std::vector< std::size_t >& stiffEqIdx ) const
-    { return self->setStiffEqIdx( stiffEqIdx ); }
-
-    //! Public function to locate the nonstiff equations
-    void setNonStiffEqIdx( std::vector< std::size_t >& nonStiffEqIdx ) const
-    { return self->setNonStiffEqIdx( nonStiffEqIdx ); }
+      const auto& initiate = b.get< tag::initiate >();
+      auto opt = ctr::Initiate();
+      nfo.emplace_back( boxname + ' ' + opt.group(), opt.name(initiate) );
+
+      ++bcnt;
+    }
+  }
+
+  const auto& icblock = ic.get< tag::meshblock >();
+  for (const auto& b : icblock) {   // for all blocks configured for eq
+    std::string blockname = "IC mesh block " +
+      parameter(b.get< tag::blockid >());
 
-    //! Public interface to determine elements that lie inside the IC box
-    void IcBoxElems( const tk::Fields& geoElem,
-      std::size_t nielem,
-      std::vector< std::unordered_set< std::size_t > >& inbox ) const
-    { self->IcBoxElems( geoElem, nielem, inbox ); }
-
-    //! Public interface to setting the initial conditions for the diff eq
-    void initialize(
-      const tk::Fields& L,
-      const std::vector< std::size_t >& inpoel,
-      const tk::UnsMesh::Coords& coord,
-      const std::vector< std::unordered_set< std::size_t > >& inbox,
-      const std::unordered_map< std::size_t, std::set< std::size_t > >&
-        elemblkid,
-      tk::Fields& unk,
-      tk::real t,
-      const std::size_t nielem ) const
-    { self->initialize( L, inpoel, coord, inbox, elemblkid, unk, t, nielem ); }
-
-    //! Public interface for saving initial densities of materials
-    void setRho0mat( std::vector< tk::real >& rho0mat) const
-    { return self->setRho0mat( rho0mat ); }
-
-    //! Public interface for computing density constraint
-    void computeDensityConstr( std::size_t nelem,
-                               tk::Fields& unk,
-                               std::vector< tk::real >& rho0mat,
-                               std::vector< tk::real >& densityConstr) const
-    { self->computeDensityConstr( nelem, unk, rho0mat, densityConstr); }
-
-    //! Public interface to computing the left-hand side matrix for the diff eq
-    void lhs( const tk::Fields& geoElem, tk::Fields& l ) const
-    { self->lhs( geoElem, l ); }
-
-    //! Public interface to updating the interface cells for the diff eq
-    void updateInterfaceCells( tk::Fields& unk,
-                               std::size_t nielem,
-                               std::vector< std::size_t >& ndofel ) const
-    { self->updateInterfaceCells( unk, nielem, ndofel ); }
-
-    //! Public interface to updating the primitives for the diff eq
-    void updatePrimitives( const tk::Fields& unk,
-                           const tk::Fields& L,
-                           const tk::Fields& geoElem,
-                           tk::Fields& prim,
-                           std::size_t nielem ) const
-    { self->updatePrimitives( unk, L, geoElem, prim, nielem ); }
-
-    //! Public interface to cleaning up trace materials for the diff eq
-    void cleanTraceMaterial( tk::real t,
-                             const tk::Fields& geoElem,
-                             tk::Fields& unk,
-                             tk::Fields& prim,
-                             std::size_t nielem ) const
-    { self->cleanTraceMaterial( t, geoElem, unk, prim, nielem ); }
-
-    //! Public interface to reconstructing the second-order solution
-    void reconstruct( tk::real t,
-                      const tk::Fields& geoFace,
-                      const tk::Fields& geoElem,
-                      const inciter::FaceData& fd,
-                      const std::map< std::size_t, std::vector< std::size_t > >&
-                        esup,
-                      const std::vector< std::size_t >& inpoel,
-                      const tk::UnsMesh::Coords& coord,
-                      tk::Fields& U,
-                      tk::Fields& P ) const
-    {
-      self->reconstruct( t, geoFace, geoElem, fd, esup, inpoel, coord, U, P );
-    }
-
-    //! Public interface to limiting the second-order solution
-    void limit( tk::real t,
-                const tk::Fields& geoFace,
-                const tk::Fields& geoElem,
-                const inciter::FaceData& fd,
-                const std::map< std::size_t, std::vector< std::size_t > >& esup,
-                const std::vector< std::size_t >& inpoel,
-                const tk::UnsMesh::Coords& coord,
-                const std::vector< std::size_t >& ndofel,
-                const std::vector< std::size_t >& gid,
-                const std::unordered_map< std::size_t, std::size_t >& bid,
-                const std::vector< std::vector<tk::real> >& uNodalExtrm,
-                const std::vector< std::vector<tk::real> >& pNodalExtrm,
-                const std::vector< std::vector<tk::real> >& mtInv,
-                tk::Fields& U,
-                tk::Fields& P,
-                std::vector< std::size_t >& shockmarker ) const
-    {
-      self->limit( t, geoFace, geoElem, fd, esup, inpoel, coord, ndofel, gid,
-                   bid, uNodalExtrm, pNodalExtrm, mtInv, U, P, shockmarker );
-    }
-
-    //! Public interface to update the conservative variable solution
-    void CPL( const tk::Fields& prim,
-              const tk::Fields& geoElem,
-              const std::vector< std::size_t >& inpoel,
-              const tk::UnsMesh::Coords& coord,
-              tk::Fields& unk,
-              std::size_t nielem ) const
-    {
-      self->CPL( prim, geoElem, inpoel, coord, unk, nielem );
-    }
-
-    //! Public interface to getting the cell-averaged deformation gradients
-    std::array< std::vector< tk::real >, 9 > cellAvgDeformGrad(
-      const tk::Fields& U,
-      std::size_t nielem ) const
-    {
-      return self->cellAvgDeformGrad( U, nielem );
-    }
-
-    //! Public interface to computing the P1 right-hand side vector
-    void rhs( tk::real t,
-              const tk::Fields& geoFace,
-              const tk::Fields& geoElem,
-              const inciter::FaceData& fd,
-              const std::vector< std::size_t >& inpoel,
-              const std::vector< std::unordered_set< std::size_t > >& boxelems,
-              const tk::UnsMesh::Coords& coord,
-              const tk::Fields& U,
-              const tk::Fields& P,
-              const std::vector< std::size_t >& ndofel,
-              const std::vector< tk::real >& rho0mat,
-              const tk::real dt,
-              tk::Fields& R ) const
-    {
-      self->rhs( t, geoFace, geoElem, fd, inpoel, boxelems, coord, U, P,
-                 ndofel, rho0mat, dt, R );
-    }
-
-    //! Evaluate the adaptive indicator and mark the ndof for each element
-    void eval_ndof( std::size_t nunk,
-                    const tk::UnsMesh::Coords& coord,
-                    const std::vector< std::size_t >& inpoel,
-                    const inciter::FaceData& fd,
-                    const tk::Fields& unk,
-                    const tk::Fields& prim,
-                    inciter::ctr::PrefIndicatorType indicator,
-                    std::size_t ndof,
-                    std::size_t ndofmax,
-                    tk::real tolref,
-                    std::vector< std::size_t >& ndofel ) const
-    {
-      self->eval_ndof( nunk, coord, inpoel, fd, unk, prim, indicator, ndof,
-        ndofmax, tolref, ndofel );
-    }
-
-    //! Public interface for computing the minimum time step size
-    tk::real dt( const std::array< std::vector< tk::real >, 3 >& coord,
-                 const std::vector< std::size_t >& inpoel,
-                 const inciter::FaceData& fd,
-                 const tk::Fields& geoFace,
-                 const tk::Fields& geoElem,
-                 const std::vector< std::size_t >& ndofel,
-                 const tk::Fields& U,
-                 const tk::Fields& P,
-                 const std::size_t nielem ) const
-    { return self->dt( coord, inpoel, fd, geoFace, geoElem, ndofel, U,
-                       P, nielem ); }
-
-    //! Public interface for computing stiff terms for an element
-    void stiff_rhs( std::size_t e,
-                    const tk::Fields& geoElem,
-                    const std::vector< std::size_t >& inpoel,
-                    const tk::UnsMesh::Coords& coord,
-                    const tk::Fields& U,
-                    const tk::Fields& P,
-                    const std::vector< std::size_t >& ndofel,
-                    tk::Fields& R ) const
-    { return self->stiff_rhs( e, geoElem, inpoel, coord, U, P, ndofel, R); }
-
-    //! Public interface to returning maps of output var functions
-    std::map< std::string, tk::GetVarFn > OutVarFn() const
-    { return self->OutVarFn(); }
-
-    //! Public interface to returning analytic field output labels
-    std::vector< std::string > analyticFieldNames() const
-    { return self->analyticFieldNames(); }
-
-    //! Public interface to returning time history field output labels
-    std::vector< std::string > histNames() const { return self->histNames(); }
-
-    //! Public interface to returning variable names
-    std::vector< std::string > names() const { return self->names(); }
-
-    //! Public interface to returning surface field output
-    std::vector< std::vector< tk::real > >
-    surfOutput( const std::map< int, std::vector< std::size_t > >& bnd,
-                tk::Fields& U ) const
-    { return self->surfOutput( bnd, U ); }
-
-    //! Public interface to return point history output
-    std::vector< std::vector< tk::real > >
-    histOutput( const std::vector< HistData >& h,
-      const std::vector< std::size_t >& inpoel,
-      const tk::UnsMesh::Coords& coord,
-      const tk::Fields& U,
-      const tk::Fields& P ) const
-    { return self->histOutput( h, inpoel, coord, U, P ); }
-
-    //! Public interface to returning analytic solution
-    tk::InitializeFn::result_type
-    analyticSolution( tk::real xi, tk::real yi, tk::real zi, tk::real t ) const
-    { return self->analyticSolution( xi, yi, zi, t ); }
-
-    //! Public interface to returning the analytic solution for conserved vars
-    tk::InitializeFn::result_type
-    solution( tk::real xi, tk::real yi, tk::real zi, tk::real t ) const
-    { return self->solution( xi, yi, zi, t ); }
-
-    //! Public interface to returning the specific total energy
-    tk::real
-    sp_totalenergy( std::size_t e, const tk::Fields& unk ) const
-    { return self->sp_totalenergy( e, unk ); }
-
-    //! Copy assignment
-    DGPDE& operator=( const DGPDE& x )
-    { DGPDE tmp(x); *this = std::move(tmp); return *this; }
-    //! Copy constructor
-    DGPDE( const DGPDE& x ) : self( x.self->copy() ) {}
-    //! Move assignment
-    DGPDE& operator=( DGPDE&& ) noexcept = default;
-    //! Move constructor
-    DGPDE( DGPDE&& ) noexcept = default;
-
-  private:
-    //! \brief Concept is a pure virtual base class specifying the requirements
-    //!   of polymorphic objects deriving from it
-    struct Concept {
-      Concept() = default;
-      Concept( const Concept& ) = default;
-      virtual ~Concept() = default;
-      virtual Concept* copy() const = 0;
-      virtual std::size_t nprim() const = 0;
-      virtual std::size_t nmat() const = 0;
-      virtual void numEquationDofs(std::vector< std::size_t >&) const = 0;
-      virtual std::size_t nstiffeq() const = 0;
-      virtual std::size_t nnonstiffeq() const = 0;
-      virtual void setStiffEqIdx( std::vector< std::size_t >& ) const = 0;
-      virtual void setNonStiffEqIdx( std::vector< std::size_t >& ) const = 0;
-      virtual void IcBoxElems( const tk::Fields&,
-        std::size_t,
-        std::vector< std::unordered_set< std::size_t > >& ) const = 0;
-      virtual void initialize(
-        const tk::Fields&,
-        const std::vector< std::size_t >&,
-        const tk::UnsMesh::Coords&,
-        const std::vector< std::unordered_set< std::size_t > >&,
-        const std::unordered_map< std::size_t, std::set< std::size_t > >&,
-        tk::Fields&,
-        tk::real,
-        const std::size_t nielem ) const = 0;
-      virtual void setRho0mat( std::vector< tk::real >& ) const = 0;
-      virtual void computeDensityConstr( std::size_t nelem,
-                                         tk::Fields& unk,
-                                         std::vector< tk::real >& rho0mat,
-                                         std::vector< tk::real >& densityConstr)
-                                         const = 0;
-      virtual void lhs( const tk::Fields&, tk::Fields& ) const = 0;
-      virtual void updateInterfaceCells( tk::Fields&,
-                                         std::size_t,
-                                         std::vector< std::size_t >& ) const = 0;
-      virtual void updatePrimitives( const tk::Fields&,
-                                     const tk::Fields&,
-                                     const tk::Fields&,
-                                     tk::Fields&,
-                                     std::size_t ) const = 0;
-      virtual void cleanTraceMaterial( tk::real,
-                                       const tk::Fields&,
-                                       tk::Fields&,
-                                       tk::Fields&,
-                                       std::size_t ) const = 0;
-      virtual void reconstruct( tk::real,
-                                const tk::Fields&,
-                                const tk::Fields&,
-                                const inciter::FaceData&,
-                                const std::map< std::size_t,
-                                  std::vector< std::size_t > >&,
-                                const std::vector< std::size_t >&,
-                                const tk::UnsMesh::Coords&,
-                                tk::Fields&,
-                                tk::Fields& ) const = 0;
-      virtual void limit( tk::real,
-                          const tk::Fields&,
-                          const tk::Fields&,
-                          const inciter::FaceData&,
-                          const std::map< std::size_t,
-                            std::vector< std::size_t > >&,
-                          const std::vector< std::size_t >&,
-                          const tk::UnsMesh::Coords&,
-                          const std::vector< std::size_t >&,
-                          const std::vector< std::size_t >&,
-                          const std::unordered_map< std::size_t, std::size_t >&,
-                          const std::vector< std::vector<tk::real> >&,
-                          const std::vector< std::vector<tk::real> >&,
-                          const std::vector< std::vector<tk::real> >&,
-                          tk::Fields&,
-                          tk::Fields&,
-                          std::vector< std::size_t >& ) const = 0;
-      virtual void CPL( const tk::Fields&,
-                        const tk::Fields&,
-                        const std::vector< std::size_t >&,
-                        const tk::UnsMesh::Coords&,
-                        tk::Fields&,
-                        std::size_t ) const = 0;
-      virtual std::array< std::vector< tk::real >, 9 > cellAvgDeformGrad(
-        const tk::Fields&,
-        std::size_t ) const = 0;
-      virtual void rhs( tk::real,
-                        const tk::Fields&,
-                        const tk::Fields&,
-                        const inciter::FaceData&,
-                        const std::vector< std::size_t >&,
-                        const std::vector< std::unordered_set< std::size_t > >&,
-                        const tk::UnsMesh::Coords&,
-                        const tk::Fields&,
-                        const tk::Fields&,
-                        const std::vector< std::size_t >&,
-                        const std::vector< tk::real >&,
-                        const tk::real,
-                        tk::Fields& ) const = 0;
-      virtual void eval_ndof( std::size_t,
-                              const tk::UnsMesh::Coords&,
-                              const std::vector< std::size_t >&,
-                              const inciter::FaceData&,
-                              const tk::Fields&,
-                              const tk::Fields&,
-                              inciter::ctr::PrefIndicatorType,
-                              std::size_t,
-                              std::size_t,
-                              tk::real,
-                              std::vector< std::size_t >& ) const = 0;
-      virtual tk::real dt( const std::array< std::vector< tk::real >, 3 >&,
-                           const std::vector< std::size_t >&,
-                           const inciter::FaceData&,
-                           const tk::Fields&,
-                           const tk::Fields&,
-                           const std::vector< std::size_t >&,
-                           const tk::Fields&,
-                           const tk::Fields&,
-                           const std::size_t ) const = 0;
-      virtual void stiff_rhs( std::size_t,
-                              const tk::Fields&,
-                              const std::vector< std::size_t >&,
-                              const tk::UnsMesh::Coords&,
-                              const tk::Fields&,
-                              const tk::Fields&,
-                              const std::vector< std::size_t >&,
-                              tk::Fields& ) const = 0;
-      virtual std::map< std::string, tk::GetVarFn > OutVarFn() const = 0;
-      virtual std::vector< std::string > analyticFieldNames() const = 0;
-      virtual std::vector< std::string > histNames() const = 0;
-      virtual std::vector< std::string > names() const = 0;
-      virtual std::vector< std::vector< tk::real > > surfOutput(
-        const std::map< int, std::vector< std::size_t > >&,
-        tk::Fields& ) const = 0;
-      virtual std::vector< std::vector< tk::real > > histOutput(
-        const std::vector< HistData >&,
-        const std::vector< std::size_t >&,
-        const tk::UnsMesh::Coords&,
-        const tk::Fields&,
-        const tk::Fields& ) const = 0;
-      virtual tk::InitializeFn::result_type analyticSolution(
-        tk::real xi, tk::real yi, tk::real zi, tk::real t ) const = 0;
-      virtual tk::InitializeFn::result_type solution(
-        tk::real xi, tk::real yi, tk::real zi, tk::real t ) const = 0;
-      virtual tk::real sp_totalenergy(
-        std::size_t, const tk::Fields& ) const = 0;
-    };
-
-    //! \brief Model models the Concept above by deriving from it and overriding
-    //!   the virtual functions required by Concept
-    template< typename T >
-    struct Model : Concept {
-      explicit Model( T x ) : data( std::move(x) ) {}
-      Concept* copy() const override { return new Model( *this ); }
-      std::size_t nprim() const override
-      { return data.nprim(); }
-      std::size_t nmat() const override
-      { return data.nmat(); }
-      void numEquationDofs(std::vector< std::size_t >& numEqDof) const override
-      { data.numEquationDofs(numEqDof); }
-      std::size_t nstiffeq() const override
-      { return data.nstiffeq(); }
-      std::size_t nnonstiffeq() const override
-      { return data.nnonstiffeq(); }
-      void setStiffEqIdx( std::vector< std::size_t >& stiffEqIdx ) const override
-      { data.setStiffEqIdx(stiffEqIdx); }
-      void setNonStiffEqIdx( std::vector< std::size_t >& nonStiffEqIdx ) const override
-      { data.setNonStiffEqIdx(nonStiffEqIdx); }
-      void IcBoxElems( const tk::Fields& geoElem,
-        std::size_t nielem,
-        std::vector< std::unordered_set< std::size_t > >& inbox )
-      const override { data.IcBoxElems( geoElem, nielem, inbox ); }
-      void initialize(
-        const tk::Fields& L,
-        const std::vector< std::size_t >& inpoel,
-        const tk::UnsMesh::Coords& coord,
-        const std::vector< std::unordered_set< std::size_t > >& inbox,
-        const std::unordered_map< std::size_t, std::set< std::size_t > >&
-          elemblkid,
-        tk::Fields& unk,
-        tk::real t,
-        const std::size_t nielem )
-      const override { data.initialize( L, inpoel, coord, inbox, elemblkid, unk,
-        t, nielem ); }
-      void setRho0mat( std::vector< tk::real >& rho0mat ) const override
-      { data.setRho0mat( rho0mat ); }
-      void computeDensityConstr( std::size_t nelem,
-                                 tk::Fields& unk,
-                                 std::vector< tk::real >& rho0mat,
-                                 std::vector< tk::real >& densityConstr)
-                                 const override
-      { data.computeDensityConstr( nelem, unk, rho0mat, densityConstr ); }
-      void lhs( const tk::Fields& geoElem, tk::Fields& l ) const override
-      { data.lhs( geoElem, l ); }
-      void updateInterfaceCells( tk::Fields& unk,
-                                 std::size_t nielem,
-                                 std::vector< std::size_t >& ndofel )
-      const override { data.updateInterfaceCells( unk, nielem, ndofel ); }
-      void updatePrimitives( const tk::Fields& unk,
-                             const tk::Fields& L,
-                             const tk::Fields& geoElem,
-                             tk::Fields& prim,
-                             std::size_t nielem )
-      const override { data.updatePrimitives( unk, L, geoElem, prim, nielem ); }
-      void cleanTraceMaterial( tk::real t,
-                               const tk::Fields& geoElem,
-                               tk::Fields& unk,
-                               tk::Fields& prim,
-                               std::size_t nielem )
-      const override { data.cleanTraceMaterial( t, geoElem, unk, prim, nielem ); }
-      void reconstruct( tk::real t,
-                        const tk::Fields& geoFace,
-                        const tk::Fields& geoElem,
-                        const inciter::FaceData& fd,
-                        const std::map< std::size_t,
-                          std::vector< std::size_t > >& esup,
-                        const std::vector< std::size_t >& inpoel,
-                        const tk::UnsMesh::Coords& coord,
-                        tk::Fields& U,
-                        tk::Fields& P ) const override
-      {
-        data.reconstruct( t, geoFace, geoElem, fd, esup, inpoel, coord, U, P );
-      }
-      void limit( tk::real t,
-                  const tk::Fields& geoFace,
-                  const tk::Fields& geoElem,
-                  const inciter::FaceData& fd,
-                  const std::map< std::size_t, std::vector< std::size_t > >&
-                    esup,
-                  const std::vector< std::size_t >& inpoel,
-                  const tk::UnsMesh::Coords& coord,
-                  const std::vector< std::size_t >& ndofel,
-                  const std::vector< std::size_t >& gid,
-                  const std::unordered_map< std::size_t, std::size_t >& bid,
-                  const std::vector< std::vector<tk::real> >& uNodalExtrm,
-                  const std::vector< std::vector<tk::real> >& pNodalExtrm,
-                  const std::vector< std::vector<tk::real> >& mtInv,
-                  tk::Fields& U,
-                  tk::Fields& P,
-                  std::vector< std::size_t >& shockmarker ) const override
-      {
-        data.limit( t, geoFace, geoElem, fd, esup, inpoel, coord, ndofel, gid,
-                    bid, uNodalExtrm, pNodalExtrm, mtInv, U, P, shockmarker );
-      }
-      void CPL( const tk::Fields& prim,
-                const tk::Fields& geoElem,
-                const std::vector< std::size_t >& inpoel,
-                const tk::UnsMesh::Coords& coord,
-                tk::Fields& unk,
-                std::size_t nielem ) const override
-      {
-        data.CPL( prim, geoElem, inpoel, coord, unk, nielem );
-      }
-      std::array< std::vector< tk::real >, 9 > cellAvgDeformGrad(
-        const tk::Fields& U,
-        std::size_t nielem ) const override
-      {
-        return data.cellAvgDeformGrad( U, nielem );
-      }
-      void rhs(
-        tk::real t,
-        const tk::Fields& geoFace,
-        const tk::Fields& geoElem,
-        const inciter::FaceData& fd,
-        const std::vector< std::size_t >& inpoel,
-        const std::vector< std::unordered_set< std::size_t > >& boxelems,
-        const tk::UnsMesh::Coords& coord,
-        const tk::Fields& U,
-        const tk::Fields& P,
-        const std::vector< std::size_t >& ndofel,
-        const std::vector< tk::real >& rho0mat,
-        const tk::real dt,
-        tk::Fields& R ) const override
-      {
-        data.rhs( t, geoFace, geoElem, fd, inpoel, boxelems, coord, U, P,
-                  ndofel, rho0mat, dt, R );
-      }
-      void eval_ndof( std::size_t nunk,
-                      const tk::UnsMesh::Coords& coord,
-                      const std::vector< std::size_t >& inpoel,
-                      const inciter::FaceData& fd,
-                      const tk::Fields& unk,
-                      const tk::Fields& prim,
-                      inciter::ctr::PrefIndicatorType indicator,
-                      std::size_t ndof,
-                      std::size_t ndofmax,
-                      tk::real tolref,
-                      std::vector< std::size_t >& ndofel ) const override
-      { data.eval_ndof( nunk, coord, inpoel, fd, unk, prim, indicator, ndof,
-                        ndofmax, tolref, ndofel ); }
-      tk::real dt( const std::array< std::vector< tk::real >, 3 >& coord,
-                   const std::vector< std::size_t >& inpoel,
-                   const inciter::FaceData& fd,
-                   const tk::Fields& geoFace,
-                   const tk::Fields& geoElem,
-                   const std::vector< std::size_t >& ndofel,
-                   const tk::Fields& U,
-                   const tk::Fields& P,
-                   const std::size_t nielem ) const override
-      { return data.dt( coord, inpoel, fd, geoFace, geoElem, ndofel,
-                        U, P, nielem ); }
-      void stiff_rhs( std::size_t e,
-                      const tk::Fields& geoElem,
-                      const std::vector< std::size_t >& inpoel,
-                      const tk::UnsMesh::Coords& coord,
-                      const tk::Fields& U,
-                      const tk::Fields& P,
-                      const std::vector< std::size_t >& ndofel,
-                      tk::Fields& R ) const override
-      { return data.stiff_rhs( e, geoElem, inpoel, coord, U, P, ndofel, R ); }
-      std::map< std::string, tk::GetVarFn > OutVarFn() const override
-      { return data.OutVarFn(); }
-      std::vector< std::string > analyticFieldNames() const override
-      { return data.analyticFieldNames(); }
-      std::vector< std::string > histNames() const override
-      { return data.histNames(); }
-      std::vector< std::string > names() const override
-      { return data.names(); }
-      std::vector< std::vector< tk::real > > surfOutput(
-        const std::map< int, std::vector< std::size_t > >& bnd,
-        tk::Fields& U ) const override
-      { return data.surfOutput( bnd, U ); }
-      std::vector< std::vector< tk::real > > histOutput(
-        const std::vector< HistData >& h,
-        const std::vector< std::size_t >& inpoel,
-        const tk::UnsMesh::Coords& coord,
-        const tk::Fields& U,
-        const tk::Fields& P ) const override
-      { return data.histOutput( h, inpoel, coord, U, P ); }
-      tk::InitializeFn::result_type
-      analyticSolution( tk::real xi, tk::real yi, tk::real zi, tk::real t )
-       const override { return data.analyticSolution( xi, yi, zi, t ); }
-      tk::InitializeFn::result_type
-      solution( tk::real xi, tk::real yi, tk::real zi, tk::real t )
-       const override { return data.solution( xi, yi, zi, t ); }
-      tk::real sp_totalenergy( std::size_t e, const tk::Fields& unk )
-       const override { return data.sp_totalenergy( e, unk ); }
-      T data;
-    };
-
-    std::unique_ptr< Concept > self;    //!< Base pointer used polymorphically
-};
-
-} // inciter::
-
-#endif // DGPDE_h
+    nfo.emplace_back( blockname + " material id",
+                      parameter( b.get< tag::materialid >() ) );
+    const auto& initiate = b.get< tag::initiate >();
+    auto opt = ctr::Initiate();
+    nfo.emplace_back( blockname + ' ' + opt.group(), opt.name(initiate) );
+  }
+
+  return nfo;
+}
+
+}  // inciter::
 
diff --git a/Debug/cppcheck/50.html b/Debug/cppcheck/50.html index c73beb8606cb..a0790fb4241d 100644 --- a/Debug/cppcheck/50.html +++ b/Debug/cppcheck/50.html @@ -152,1609 +152,2597 @@
- - - - - - - + + + + + + diff --git a/Debug/test_coverage/Control/CommonGrammar.hpp.func-sort-c.html b/Debug/test_coverage/Control/CommonGrammar.hpp.func-sort-c.html index 8fadbd0051a3..ff27b6226453 100644 --- a/Debug/test_coverage/Control/CommonGrammar.hpp.func-sort-c.html +++ b/Debug/test_coverage/Control/CommonGrammar.hpp.func-sort-c.html @@ -33,7 +33,7 @@ - + diff --git a/Debug/test_coverage/Control/CommonGrammar.hpp.func.html b/Debug/test_coverage/Control/CommonGrammar.hpp.func.html index 8fe2a82fd0af..926b23aac5b7 100644 --- a/Debug/test_coverage/Control/CommonGrammar.hpp.func.html +++ b/Debug/test_coverage/Control/CommonGrammar.hpp.func.html @@ -33,7 +33,7 @@ - + diff --git a/Debug/test_coverage/Control/CommonGrammar.hpp.gcov.html b/Debug/test_coverage/Control/CommonGrammar.hpp.gcov.html index 7af8b0d19a04..9e59e3cb5879 100644 --- a/Debug/test_coverage/Control/CommonGrammar.hpp.gcov.html +++ b/Debug/test_coverage/Control/CommonGrammar.hpp.gcov.html @@ -33,7 +33,7 @@ - + diff --git a/Debug/test_coverage/Control/HelpFactory.hpp.func-sort-c.html b/Debug/test_coverage/Control/HelpFactory.hpp.func-sort-c.html index 0d0a26ae3d95..aa147be821e2 100644 --- a/Debug/test_coverage/Control/HelpFactory.hpp.func-sort-c.html +++ b/Debug/test_coverage/Control/HelpFactory.hpp.func-sort-c.html @@ -33,7 +33,7 @@ - + diff --git a/Debug/test_coverage/Control/HelpFactory.hpp.func.html b/Debug/test_coverage/Control/HelpFactory.hpp.func.html index d8e4e34b0531..9f912a4cb1a3 100644 --- a/Debug/test_coverage/Control/HelpFactory.hpp.func.html +++ b/Debug/test_coverage/Control/HelpFactory.hpp.func.html @@ -33,7 +33,7 @@ - + diff --git a/Debug/test_coverage/Control/HelpFactory.hpp.gcov.html b/Debug/test_coverage/Control/HelpFactory.hpp.gcov.html index 3c80d555d813..8551b431ce27 100644 --- a/Debug/test_coverage/Control/HelpFactory.hpp.gcov.html +++ b/Debug/test_coverage/Control/HelpFactory.hpp.gcov.html @@ -33,7 +33,7 @@ - + diff --git a/Debug/test_coverage/Control/Inciter/CmdLine/CmdLine.hpp.func-sort-c.html b/Debug/test_coverage/Control/Inciter/CmdLine/CmdLine.hpp.func-sort-c.html index fc53aae8627a..da88f6b4f5d4 100644 --- a/Debug/test_coverage/Control/Inciter/CmdLine/CmdLine.hpp.func-sort-c.html +++ b/Debug/test_coverage/Control/Inciter/CmdLine/CmdLine.hpp.func-sort-c.html @@ -33,7 +33,7 @@ - + diff --git a/Debug/test_coverage/Control/Inciter/CmdLine/CmdLine.hpp.func.html b/Debug/test_coverage/Control/Inciter/CmdLine/CmdLine.hpp.func.html index 1db1320c7fa6..39c85518e63b 100644 --- a/Debug/test_coverage/Control/Inciter/CmdLine/CmdLine.hpp.func.html +++ b/Debug/test_coverage/Control/Inciter/CmdLine/CmdLine.hpp.func.html @@ -33,7 +33,7 @@ - + diff --git a/Debug/test_coverage/Control/Inciter/CmdLine/CmdLine.hpp.gcov.html b/Debug/test_coverage/Control/Inciter/CmdLine/CmdLine.hpp.gcov.html index dd1ba121a380..3554df9a5c3c 100644 --- a/Debug/test_coverage/Control/Inciter/CmdLine/CmdLine.hpp.gcov.html +++ b/Debug/test_coverage/Control/Inciter/CmdLine/CmdLine.hpp.gcov.html @@ -33,7 +33,7 @@ - + diff --git a/Debug/test_coverage/Control/Inciter/CmdLine/Parser.cpp.func-sort-c.html b/Debug/test_coverage/Control/Inciter/CmdLine/Parser.cpp.func-sort-c.html index c7ed5945c43e..d4cccc5aaf2d 100644 --- a/Debug/test_coverage/Control/Inciter/CmdLine/Parser.cpp.func-sort-c.html +++ b/Debug/test_coverage/Control/Inciter/CmdLine/Parser.cpp.func-sort-c.html @@ -33,7 +33,7 @@ - + diff --git a/Debug/test_coverage/Control/Inciter/CmdLine/Parser.cpp.func.html b/Debug/test_coverage/Control/Inciter/CmdLine/Parser.cpp.func.html index 759fdc455f84..01031f7e8624 100644 --- a/Debug/test_coverage/Control/Inciter/CmdLine/Parser.cpp.func.html +++ b/Debug/test_coverage/Control/Inciter/CmdLine/Parser.cpp.func.html @@ -33,7 +33,7 @@ - + diff --git a/Debug/test_coverage/Control/Inciter/CmdLine/Parser.cpp.gcov.html b/Debug/test_coverage/Control/Inciter/CmdLine/Parser.cpp.gcov.html index 7a652dccee81..4090e2fa92a6 100644 --- a/Debug/test_coverage/Control/Inciter/CmdLine/Parser.cpp.gcov.html +++ b/Debug/test_coverage/Control/Inciter/CmdLine/Parser.cpp.gcov.html @@ -33,7 +33,7 @@ - + diff --git a/Debug/test_coverage/Control/Inciter/CmdLine/index-sort-b.html b/Debug/test_coverage/Control/Inciter/CmdLine/index-sort-b.html index bfa3b38c02f1..cb4f5abf925a 100644 --- a/Debug/test_coverage/Control/Inciter/CmdLine/index-sort-b.html +++ b/Debug/test_coverage/Control/Inciter/CmdLine/index-sort-b.html @@ -33,7 +33,7 @@ - + diff --git a/Debug/test_coverage/Control/Inciter/CmdLine/index-sort-f.html b/Debug/test_coverage/Control/Inciter/CmdLine/index-sort-f.html index 1596ef90c7ae..6f8ff1acc71a 100644 --- a/Debug/test_coverage/Control/Inciter/CmdLine/index-sort-f.html +++ b/Debug/test_coverage/Control/Inciter/CmdLine/index-sort-f.html @@ -33,7 +33,7 @@ - + diff --git a/Debug/test_coverage/Control/Inciter/CmdLine/index-sort-l.html b/Debug/test_coverage/Control/Inciter/CmdLine/index-sort-l.html index 3456417db182..9445928ff390 100644 --- a/Debug/test_coverage/Control/Inciter/CmdLine/index-sort-l.html +++ b/Debug/test_coverage/Control/Inciter/CmdLine/index-sort-l.html @@ -33,7 +33,7 @@ - + diff --git a/Debug/test_coverage/Control/Inciter/CmdLine/index.html b/Debug/test_coverage/Control/Inciter/CmdLine/index.html index bdcb2cf8dfb6..7a8b18dd36d1 100644 --- a/Debug/test_coverage/Control/Inciter/CmdLine/index.html +++ b/Debug/test_coverage/Control/Inciter/CmdLine/index.html @@ -33,7 +33,7 @@ - + diff --git a/Debug/test_coverage/Control/Inciter/InputDeck/InputDeck.hpp.func-sort-c.html b/Debug/test_coverage/Control/Inciter/InputDeck/InputDeck.hpp.func-sort-c.html index 4df8be268bfe..bbf724eef1d8 100644 --- a/Debug/test_coverage/Control/Inciter/InputDeck/InputDeck.hpp.func-sort-c.html +++ b/Debug/test_coverage/Control/Inciter/InputDeck/InputDeck.hpp.func-sort-c.html @@ -33,7 +33,7 @@ - + diff --git a/Debug/test_coverage/Control/Inciter/InputDeck/InputDeck.hpp.func.html b/Debug/test_coverage/Control/Inciter/InputDeck/InputDeck.hpp.func.html index 3cfb05620339..afd141893833 100644 --- a/Debug/test_coverage/Control/Inciter/InputDeck/InputDeck.hpp.func.html +++ b/Debug/test_coverage/Control/Inciter/InputDeck/InputDeck.hpp.func.html @@ -33,7 +33,7 @@ - + diff --git a/Debug/test_coverage/Control/Inciter/InputDeck/InputDeck.hpp.gcov.html b/Debug/test_coverage/Control/Inciter/InputDeck/InputDeck.hpp.gcov.html index 21074a93418c..bb1be8fc02e9 100644 --- a/Debug/test_coverage/Control/Inciter/InputDeck/InputDeck.hpp.gcov.html +++ b/Debug/test_coverage/Control/Inciter/InputDeck/InputDeck.hpp.gcov.html @@ -33,7 +33,7 @@ - + diff --git a/Debug/test_coverage/Control/Inciter/InputDeck/LuaParser.cpp.func-sort-c.html b/Debug/test_coverage/Control/Inciter/InputDeck/LuaParser.cpp.func-sort-c.html index d4e197f19bad..2f56487236eb 100644 --- a/Debug/test_coverage/Control/Inciter/InputDeck/LuaParser.cpp.func-sort-c.html +++ b/Debug/test_coverage/Control/Inciter/InputDeck/LuaParser.cpp.func-sort-c.html @@ -33,7 +33,7 @@ - + diff --git a/Debug/test_coverage/Control/Inciter/InputDeck/LuaParser.cpp.func.html b/Debug/test_coverage/Control/Inciter/InputDeck/LuaParser.cpp.func.html index 6211b03e8f4c..11f05d3225eb 100644 --- a/Debug/test_coverage/Control/Inciter/InputDeck/LuaParser.cpp.func.html +++ b/Debug/test_coverage/Control/Inciter/InputDeck/LuaParser.cpp.func.html @@ -33,7 +33,7 @@ - + diff --git a/Debug/test_coverage/Control/Inciter/InputDeck/LuaParser.cpp.gcov.html b/Debug/test_coverage/Control/Inciter/InputDeck/LuaParser.cpp.gcov.html index 394edca25196..d70f33af2561 100644 --- a/Debug/test_coverage/Control/Inciter/InputDeck/LuaParser.cpp.gcov.html +++ b/Debug/test_coverage/Control/Inciter/InputDeck/LuaParser.cpp.gcov.html @@ -33,7 +33,7 @@ - + diff --git a/Debug/test_coverage/Control/Inciter/InputDeck/LuaParser.hpp.func-sort-c.html b/Debug/test_coverage/Control/Inciter/InputDeck/LuaParser.hpp.func-sort-c.html index ca1c1a507c6e..6687ade335ac 100644 --- a/Debug/test_coverage/Control/Inciter/InputDeck/LuaParser.hpp.func-sort-c.html +++ b/Debug/test_coverage/Control/Inciter/InputDeck/LuaParser.hpp.func-sort-c.html @@ -33,7 +33,7 @@ - + diff --git a/Debug/test_coverage/Control/Inciter/InputDeck/LuaParser.hpp.func.html b/Debug/test_coverage/Control/Inciter/InputDeck/LuaParser.hpp.func.html index ab9aaa684390..24f538172448 100644 --- a/Debug/test_coverage/Control/Inciter/InputDeck/LuaParser.hpp.func.html +++ b/Debug/test_coverage/Control/Inciter/InputDeck/LuaParser.hpp.func.html @@ -33,7 +33,7 @@ - + diff --git a/Debug/test_coverage/Control/Inciter/InputDeck/LuaParser.hpp.gcov.html b/Debug/test_coverage/Control/Inciter/InputDeck/LuaParser.hpp.gcov.html index 492815599334..63886fa3225e 100644 --- a/Debug/test_coverage/Control/Inciter/InputDeck/LuaParser.hpp.gcov.html +++ b/Debug/test_coverage/Control/Inciter/InputDeck/LuaParser.hpp.gcov.html @@ -33,7 +33,7 @@ - + diff --git a/Debug/test_coverage/Control/Inciter/InputDeck/index-sort-b.html b/Debug/test_coverage/Control/Inciter/InputDeck/index-sort-b.html index a2b860bac4c9..4b3291376e6b 100644 --- a/Debug/test_coverage/Control/Inciter/InputDeck/index-sort-b.html +++ b/Debug/test_coverage/Control/Inciter/InputDeck/index-sort-b.html @@ -33,7 +33,7 @@ - + diff --git a/Debug/test_coverage/Control/Inciter/InputDeck/index-sort-f.html b/Debug/test_coverage/Control/Inciter/InputDeck/index-sort-f.html index d50330d8176c..87f089745462 100644 --- a/Debug/test_coverage/Control/Inciter/InputDeck/index-sort-f.html +++ b/Debug/test_coverage/Control/Inciter/InputDeck/index-sort-f.html @@ -33,7 +33,7 @@ - + diff --git a/Debug/test_coverage/Control/Inciter/InputDeck/index-sort-l.html b/Debug/test_coverage/Control/Inciter/InputDeck/index-sort-l.html index 1bac33c0acda..50c149e48ae6 100644 --- a/Debug/test_coverage/Control/Inciter/InputDeck/index-sort-l.html +++ b/Debug/test_coverage/Control/Inciter/InputDeck/index-sort-l.html @@ -33,7 +33,7 @@ - + diff --git a/Debug/test_coverage/Control/Inciter/InputDeck/index.html b/Debug/test_coverage/Control/Inciter/InputDeck/index.html index 03a80fcb017f..79d2c3486123 100644 --- a/Debug/test_coverage/Control/Inciter/InputDeck/index.html +++ b/Debug/test_coverage/Control/Inciter/InputDeck/index.html @@ -33,7 +33,7 @@ - + diff --git a/Debug/test_coverage/Control/Inciter/Options/AMRError.hpp.func-sort-c.html b/Debug/test_coverage/Control/Inciter/Options/AMRError.hpp.func-sort-c.html index ba17094b419d..3fdb5b4ccb22 100644 --- a/Debug/test_coverage/Control/Inciter/Options/AMRError.hpp.func-sort-c.html +++ b/Debug/test_coverage/Control/Inciter/Options/AMRError.hpp.func-sort-c.html @@ -33,7 +33,7 @@ - + diff --git a/Debug/test_coverage/Control/Inciter/Options/AMRError.hpp.func.html b/Debug/test_coverage/Control/Inciter/Options/AMRError.hpp.func.html index 0d2567cf711f..d4dac60fa420 100644 --- a/Debug/test_coverage/Control/Inciter/Options/AMRError.hpp.func.html +++ b/Debug/test_coverage/Control/Inciter/Options/AMRError.hpp.func.html @@ -33,7 +33,7 @@ - + diff --git a/Debug/test_coverage/Control/Inciter/Options/AMRError.hpp.gcov.html b/Debug/test_coverage/Control/Inciter/Options/AMRError.hpp.gcov.html index 6a3df7e16896..d15c702f0171 100644 --- a/Debug/test_coverage/Control/Inciter/Options/AMRError.hpp.gcov.html +++ b/Debug/test_coverage/Control/Inciter/Options/AMRError.hpp.gcov.html @@ -33,7 +33,7 @@ - + diff --git a/Debug/test_coverage/Control/Inciter/Options/AMRInitial.hpp.func-sort-c.html b/Debug/test_coverage/Control/Inciter/Options/AMRInitial.hpp.func-sort-c.html index badb1ced0523..775ed21d13b6 100644 --- a/Debug/test_coverage/Control/Inciter/Options/AMRInitial.hpp.func-sort-c.html +++ b/Debug/test_coverage/Control/Inciter/Options/AMRInitial.hpp.func-sort-c.html @@ -33,7 +33,7 @@ - + diff --git a/Debug/test_coverage/Control/Inciter/Options/AMRInitial.hpp.func.html b/Debug/test_coverage/Control/Inciter/Options/AMRInitial.hpp.func.html index 9072ab5f5c40..cf349e0c3f91 100644 --- a/Debug/test_coverage/Control/Inciter/Options/AMRInitial.hpp.func.html +++ b/Debug/test_coverage/Control/Inciter/Options/AMRInitial.hpp.func.html @@ -33,7 +33,7 @@ - + diff --git a/Debug/test_coverage/Control/Inciter/Options/AMRInitial.hpp.gcov.html b/Debug/test_coverage/Control/Inciter/Options/AMRInitial.hpp.gcov.html index 08d338a7def7..7071273e89af 100644 --- a/Debug/test_coverage/Control/Inciter/Options/AMRInitial.hpp.gcov.html +++ b/Debug/test_coverage/Control/Inciter/Options/AMRInitial.hpp.gcov.html @@ -33,7 +33,7 @@ - + diff --git a/Debug/test_coverage/Control/Inciter/Options/Flux.hpp.func-sort-c.html b/Debug/test_coverage/Control/Inciter/Options/Flux.hpp.func-sort-c.html index 549ad48c8c3f..680eb406b725 100644 --- a/Debug/test_coverage/Control/Inciter/Options/Flux.hpp.func-sort-c.html +++ b/Debug/test_coverage/Control/Inciter/Options/Flux.hpp.func-sort-c.html @@ -33,7 +33,7 @@ - + diff --git a/Debug/test_coverage/Control/Inciter/Options/Flux.hpp.func.html b/Debug/test_coverage/Control/Inciter/Options/Flux.hpp.func.html index b6102c97b8f6..b4813bae7adb 100644 --- a/Debug/test_coverage/Control/Inciter/Options/Flux.hpp.func.html +++ b/Debug/test_coverage/Control/Inciter/Options/Flux.hpp.func.html @@ -33,7 +33,7 @@ - + diff --git a/Debug/test_coverage/Control/Inciter/Options/Flux.hpp.gcov.html b/Debug/test_coverage/Control/Inciter/Options/Flux.hpp.gcov.html index bf1ad663f582..e72535f8729e 100644 --- a/Debug/test_coverage/Control/Inciter/Options/Flux.hpp.gcov.html +++ b/Debug/test_coverage/Control/Inciter/Options/Flux.hpp.gcov.html @@ -33,7 +33,7 @@ - + diff --git a/Debug/test_coverage/Control/Inciter/Options/Initiate.hpp.func-sort-c.html b/Debug/test_coverage/Control/Inciter/Options/Initiate.hpp.func-sort-c.html index 2c062fcf9412..21d7cf21ebfa 100644 --- a/Debug/test_coverage/Control/Inciter/Options/Initiate.hpp.func-sort-c.html +++ b/Debug/test_coverage/Control/Inciter/Options/Initiate.hpp.func-sort-c.html @@ -33,7 +33,7 @@ - + diff --git a/Debug/test_coverage/Control/Inciter/Options/Initiate.hpp.func.html b/Debug/test_coverage/Control/Inciter/Options/Initiate.hpp.func.html index 3bdf9c8c516d..a8f50090aa5c 100644 --- a/Debug/test_coverage/Control/Inciter/Options/Initiate.hpp.func.html +++ b/Debug/test_coverage/Control/Inciter/Options/Initiate.hpp.func.html @@ -33,7 +33,7 @@ - + diff --git a/Debug/test_coverage/Control/Inciter/Options/Initiate.hpp.gcov.html b/Debug/test_coverage/Control/Inciter/Options/Initiate.hpp.gcov.html index f251958116ac..940bed63bab0 100644 --- a/Debug/test_coverage/Control/Inciter/Options/Initiate.hpp.gcov.html +++ b/Debug/test_coverage/Control/Inciter/Options/Initiate.hpp.gcov.html @@ -33,7 +33,7 @@ - + diff --git a/Debug/test_coverage/Control/Inciter/Options/Limiter.hpp.func-sort-c.html b/Debug/test_coverage/Control/Inciter/Options/Limiter.hpp.func-sort-c.html index 76c7389125ba..0dc5cbb54933 100644 --- a/Debug/test_coverage/Control/Inciter/Options/Limiter.hpp.func-sort-c.html +++ b/Debug/test_coverage/Control/Inciter/Options/Limiter.hpp.func-sort-c.html @@ -33,7 +33,7 @@ - + diff --git a/Debug/test_coverage/Control/Inciter/Options/Limiter.hpp.func.html b/Debug/test_coverage/Control/Inciter/Options/Limiter.hpp.func.html index ca9fa70265c5..643dd6db1e84 100644 --- a/Debug/test_coverage/Control/Inciter/Options/Limiter.hpp.func.html +++ b/Debug/test_coverage/Control/Inciter/Options/Limiter.hpp.func.html @@ -33,7 +33,7 @@ - + diff --git a/Debug/test_coverage/Control/Inciter/Options/Limiter.hpp.gcov.html b/Debug/test_coverage/Control/Inciter/Options/Limiter.hpp.gcov.html index 13eac85154a5..b8b623fce581 100644 --- a/Debug/test_coverage/Control/Inciter/Options/Limiter.hpp.gcov.html +++ b/Debug/test_coverage/Control/Inciter/Options/Limiter.hpp.gcov.html @@ -33,7 +33,7 @@ - + diff --git a/Debug/test_coverage/Control/Inciter/Options/Material.hpp.func-sort-c.html b/Debug/test_coverage/Control/Inciter/Options/Material.hpp.func-sort-c.html index db7c753a76a4..49cf5919e112 100644 --- a/Debug/test_coverage/Control/Inciter/Options/Material.hpp.func-sort-c.html +++ b/Debug/test_coverage/Control/Inciter/Options/Material.hpp.func-sort-c.html @@ -33,7 +33,7 @@ - + diff --git a/Debug/test_coverage/Control/Inciter/Options/Material.hpp.func.html b/Debug/test_coverage/Control/Inciter/Options/Material.hpp.func.html index 2001a9b93a0e..77817f7c77e8 100644 --- a/Debug/test_coverage/Control/Inciter/Options/Material.hpp.func.html +++ b/Debug/test_coverage/Control/Inciter/Options/Material.hpp.func.html @@ -33,7 +33,7 @@ - + diff --git a/Debug/test_coverage/Control/Inciter/Options/Material.hpp.gcov.html b/Debug/test_coverage/Control/Inciter/Options/Material.hpp.gcov.html index 530cd21004dc..684b13c0ee75 100644 --- a/Debug/test_coverage/Control/Inciter/Options/Material.hpp.gcov.html +++ b/Debug/test_coverage/Control/Inciter/Options/Material.hpp.gcov.html @@ -33,7 +33,7 @@ - + diff --git a/Debug/test_coverage/Control/Inciter/Options/MeshVelocity.hpp.func-sort-c.html b/Debug/test_coverage/Control/Inciter/Options/MeshVelocity.hpp.func-sort-c.html index d54de71a65de..309088d1a47f 100644 --- a/Debug/test_coverage/Control/Inciter/Options/MeshVelocity.hpp.func-sort-c.html +++ b/Debug/test_coverage/Control/Inciter/Options/MeshVelocity.hpp.func-sort-c.html @@ -33,7 +33,7 @@ - + diff --git a/Debug/test_coverage/Control/Inciter/Options/MeshVelocity.hpp.func.html b/Debug/test_coverage/Control/Inciter/Options/MeshVelocity.hpp.func.html index 3a20e005eeb9..fbcb7db7f648 100644 --- a/Debug/test_coverage/Control/Inciter/Options/MeshVelocity.hpp.func.html +++ b/Debug/test_coverage/Control/Inciter/Options/MeshVelocity.hpp.func.html @@ -33,7 +33,7 @@ - + diff --git a/Debug/test_coverage/Control/Inciter/Options/MeshVelocity.hpp.gcov.html b/Debug/test_coverage/Control/Inciter/Options/MeshVelocity.hpp.gcov.html index d71a283c3165..b5d5f120ece4 100644 --- a/Debug/test_coverage/Control/Inciter/Options/MeshVelocity.hpp.gcov.html +++ b/Debug/test_coverage/Control/Inciter/Options/MeshVelocity.hpp.gcov.html @@ -33,7 +33,7 @@ - + diff --git a/Debug/test_coverage/Control/Inciter/Options/MeshVelocitySmoother.hpp.func-sort-c.html b/Debug/test_coverage/Control/Inciter/Options/MeshVelocitySmoother.hpp.func-sort-c.html index 8ffd4f663387..b6127e72dd8d 100644 --- a/Debug/test_coverage/Control/Inciter/Options/MeshVelocitySmoother.hpp.func-sort-c.html +++ b/Debug/test_coverage/Control/Inciter/Options/MeshVelocitySmoother.hpp.func-sort-c.html @@ -33,7 +33,7 @@ - + diff --git a/Debug/test_coverage/Control/Inciter/Options/MeshVelocitySmoother.hpp.func.html b/Debug/test_coverage/Control/Inciter/Options/MeshVelocitySmoother.hpp.func.html index 15afbab1daca..cc117b929688 100644 --- a/Debug/test_coverage/Control/Inciter/Options/MeshVelocitySmoother.hpp.func.html +++ b/Debug/test_coverage/Control/Inciter/Options/MeshVelocitySmoother.hpp.func.html @@ -33,7 +33,7 @@ - + diff --git a/Debug/test_coverage/Control/Inciter/Options/MeshVelocitySmoother.hpp.gcov.html b/Debug/test_coverage/Control/Inciter/Options/MeshVelocitySmoother.hpp.gcov.html index 9d6291b5e7cc..a0244da3bd4c 100644 --- a/Debug/test_coverage/Control/Inciter/Options/MeshVelocitySmoother.hpp.gcov.html +++ b/Debug/test_coverage/Control/Inciter/Options/MeshVelocitySmoother.hpp.gcov.html @@ -33,7 +33,7 @@ - + diff --git a/Debug/test_coverage/Control/Inciter/Options/PDE.hpp.func-sort-c.html b/Debug/test_coverage/Control/Inciter/Options/PDE.hpp.func-sort-c.html index 445cd4624ae7..1b72ba1105c8 100644 --- a/Debug/test_coverage/Control/Inciter/Options/PDE.hpp.func-sort-c.html +++ b/Debug/test_coverage/Control/Inciter/Options/PDE.hpp.func-sort-c.html @@ -33,7 +33,7 @@ - + diff --git a/Debug/test_coverage/Control/Inciter/Options/PDE.hpp.func.html b/Debug/test_coverage/Control/Inciter/Options/PDE.hpp.func.html index 496981c8a966..090b7292236a 100644 --- a/Debug/test_coverage/Control/Inciter/Options/PDE.hpp.func.html +++ b/Debug/test_coverage/Control/Inciter/Options/PDE.hpp.func.html @@ -33,7 +33,7 @@ - + diff --git a/Debug/test_coverage/Control/Inciter/Options/PDE.hpp.gcov.html b/Debug/test_coverage/Control/Inciter/Options/PDE.hpp.gcov.html index c2ffa83d5177..7708e538d56c 100644 --- a/Debug/test_coverage/Control/Inciter/Options/PDE.hpp.gcov.html +++ b/Debug/test_coverage/Control/Inciter/Options/PDE.hpp.gcov.html @@ -33,7 +33,7 @@ - + diff --git a/Debug/test_coverage/Control/Inciter/Options/Physics.hpp.func-sort-c.html b/Debug/test_coverage/Control/Inciter/Options/Physics.hpp.func-sort-c.html index 95dffcb4139f..c8a6a010968d 100644 --- a/Debug/test_coverage/Control/Inciter/Options/Physics.hpp.func-sort-c.html +++ b/Debug/test_coverage/Control/Inciter/Options/Physics.hpp.func-sort-c.html @@ -33,7 +33,7 @@ - + diff --git a/Debug/test_coverage/Control/Inciter/Options/Physics.hpp.func.html b/Debug/test_coverage/Control/Inciter/Options/Physics.hpp.func.html index 0f47d9ba397e..ff7eb8828bc5 100644 --- a/Debug/test_coverage/Control/Inciter/Options/Physics.hpp.func.html +++ b/Debug/test_coverage/Control/Inciter/Options/Physics.hpp.func.html @@ -33,7 +33,7 @@ - + diff --git a/Debug/test_coverage/Control/Inciter/Options/Physics.hpp.gcov.html b/Debug/test_coverage/Control/Inciter/Options/Physics.hpp.gcov.html index fc028ec1d261..7c8ef91be644 100644 --- a/Debug/test_coverage/Control/Inciter/Options/Physics.hpp.gcov.html +++ b/Debug/test_coverage/Control/Inciter/Options/Physics.hpp.gcov.html @@ -33,7 +33,7 @@ - + diff --git a/Debug/test_coverage/Control/Inciter/Options/PrefIndicator.hpp.func-sort-c.html b/Debug/test_coverage/Control/Inciter/Options/PrefIndicator.hpp.func-sort-c.html index eab73a27d4eb..3e67cf887cdc 100644 --- a/Debug/test_coverage/Control/Inciter/Options/PrefIndicator.hpp.func-sort-c.html +++ b/Debug/test_coverage/Control/Inciter/Options/PrefIndicator.hpp.func-sort-c.html @@ -33,7 +33,7 @@ - + diff --git a/Debug/test_coverage/Control/Inciter/Options/PrefIndicator.hpp.func.html b/Debug/test_coverage/Control/Inciter/Options/PrefIndicator.hpp.func.html index df35dc1421b9..f396e79daabc 100644 --- a/Debug/test_coverage/Control/Inciter/Options/PrefIndicator.hpp.func.html +++ b/Debug/test_coverage/Control/Inciter/Options/PrefIndicator.hpp.func.html @@ -33,7 +33,7 @@ - + diff --git a/Debug/test_coverage/Control/Inciter/Options/PrefIndicator.hpp.gcov.html b/Debug/test_coverage/Control/Inciter/Options/PrefIndicator.hpp.gcov.html index b7cf60acc0de..a131730d6b3e 100644 --- a/Debug/test_coverage/Control/Inciter/Options/PrefIndicator.hpp.gcov.html +++ b/Debug/test_coverage/Control/Inciter/Options/PrefIndicator.hpp.gcov.html @@ -33,7 +33,7 @@ - + diff --git a/Debug/test_coverage/Control/Inciter/Options/Problem.hpp.func-sort-c.html b/Debug/test_coverage/Control/Inciter/Options/Problem.hpp.func-sort-c.html index ffba64bd3443..4feae153c155 100644 --- a/Debug/test_coverage/Control/Inciter/Options/Problem.hpp.func-sort-c.html +++ b/Debug/test_coverage/Control/Inciter/Options/Problem.hpp.func-sort-c.html @@ -33,7 +33,7 @@ - + diff --git a/Debug/test_coverage/Control/Inciter/Options/Problem.hpp.func.html b/Debug/test_coverage/Control/Inciter/Options/Problem.hpp.func.html index 5bad0bbcb65e..c94ae7326c90 100644 --- a/Debug/test_coverage/Control/Inciter/Options/Problem.hpp.func.html +++ b/Debug/test_coverage/Control/Inciter/Options/Problem.hpp.func.html @@ -33,7 +33,7 @@ - + diff --git a/Debug/test_coverage/Control/Inciter/Options/Problem.hpp.gcov.html b/Debug/test_coverage/Control/Inciter/Options/Problem.hpp.gcov.html index 66768bd58546..16d777f5ad7a 100644 --- a/Debug/test_coverage/Control/Inciter/Options/Problem.hpp.gcov.html +++ b/Debug/test_coverage/Control/Inciter/Options/Problem.hpp.gcov.html @@ -33,7 +33,7 @@ - + diff --git a/Debug/test_coverage/Control/Inciter/Options/Scheme.hpp.func-sort-c.html b/Debug/test_coverage/Control/Inciter/Options/Scheme.hpp.func-sort-c.html index b836f1a308c4..0ac65aecead6 100644 --- a/Debug/test_coverage/Control/Inciter/Options/Scheme.hpp.func-sort-c.html +++ b/Debug/test_coverage/Control/Inciter/Options/Scheme.hpp.func-sort-c.html @@ -33,7 +33,7 @@ - + diff --git a/Debug/test_coverage/Control/Inciter/Options/Scheme.hpp.func.html b/Debug/test_coverage/Control/Inciter/Options/Scheme.hpp.func.html index 287ce4de48e1..8670b3de151d 100644 --- a/Debug/test_coverage/Control/Inciter/Options/Scheme.hpp.func.html +++ b/Debug/test_coverage/Control/Inciter/Options/Scheme.hpp.func.html @@ -33,7 +33,7 @@ - + diff --git a/Debug/test_coverage/Control/Inciter/Options/Scheme.hpp.gcov.html b/Debug/test_coverage/Control/Inciter/Options/Scheme.hpp.gcov.html index c03cff9dca93..85e8526adfb2 100644 --- a/Debug/test_coverage/Control/Inciter/Options/Scheme.hpp.gcov.html +++ b/Debug/test_coverage/Control/Inciter/Options/Scheme.hpp.gcov.html @@ -33,7 +33,7 @@ - + diff --git a/Debug/test_coverage/Control/Inciter/Options/index-sort-b.html b/Debug/test_coverage/Control/Inciter/Options/index-sort-b.html index 5dd902f11c30..9165bccfb10b 100644 --- a/Debug/test_coverage/Control/Inciter/Options/index-sort-b.html +++ b/Debug/test_coverage/Control/Inciter/Options/index-sort-b.html @@ -33,7 +33,7 @@ - + @@ -82,24 +82,24 @@ - + - - + + - + - - + + @@ -118,48 +118,48 @@ - + - + - + - + - + - - + + - + - - + + diff --git a/Debug/test_coverage/Control/Inciter/Options/index-sort-f.html b/Debug/test_coverage/Control/Inciter/Options/index-sort-f.html index ab72c6b9f136..487eea8d58f0 100644 --- a/Debug/test_coverage/Control/Inciter/Options/index-sort-f.html +++ b/Debug/test_coverage/Control/Inciter/Options/index-sort-f.html @@ -33,7 +33,7 @@ - + @@ -82,64 +82,64 @@ - + - + - + - - + + - + - - + + - + - + - - + + - + - + - - + + - + @@ -154,52 +154,40 @@ - + - - + + - + - + - - - - - - - - - - - + - + - + - - + + - + @@ -225,6 +213,18 @@ + + + + + + + + + + - + @@ -166,7 +166,7 @@ - + @@ -178,7 +178,7 @@ - + diff --git a/Debug/test_coverage/Control/Inciter/Options/index.html b/Debug/test_coverage/Control/Inciter/Options/index.html index 07d6c8eac68a..9dae7b0ad9f6 100644 --- a/Debug/test_coverage/Control/Inciter/Options/index.html +++ b/Debug/test_coverage/Control/Inciter/Options/index.html @@ -33,7 +33,7 @@ - + diff --git a/Debug/test_coverage/Control/Inciter/OutVar.hpp.func-sort-c.html b/Debug/test_coverage/Control/Inciter/OutVar.hpp.func-sort-c.html index 086130ea6cda..1d5b95253c24 100644 --- a/Debug/test_coverage/Control/Inciter/OutVar.hpp.func-sort-c.html +++ b/Debug/test_coverage/Control/Inciter/OutVar.hpp.func-sort-c.html @@ -33,7 +33,7 @@ - + diff --git a/Debug/test_coverage/Control/Inciter/OutVar.hpp.func.html b/Debug/test_coverage/Control/Inciter/OutVar.hpp.func.html index 8500577ddc17..09ac9d03d98d 100644 --- a/Debug/test_coverage/Control/Inciter/OutVar.hpp.func.html +++ b/Debug/test_coverage/Control/Inciter/OutVar.hpp.func.html @@ -33,7 +33,7 @@ - + diff --git a/Debug/test_coverage/Control/Inciter/OutVar.hpp.gcov.html b/Debug/test_coverage/Control/Inciter/OutVar.hpp.gcov.html index c550bfefdff5..493647d1f404 100644 --- a/Debug/test_coverage/Control/Inciter/OutVar.hpp.gcov.html +++ b/Debug/test_coverage/Control/Inciter/OutVar.hpp.gcov.html @@ -33,7 +33,7 @@ - + diff --git a/Debug/test_coverage/Control/Inciter/index-sort-b.html b/Debug/test_coverage/Control/Inciter/index-sort-b.html index ab63c6790990..276298eef9a0 100644 --- a/Debug/test_coverage/Control/Inciter/index-sort-b.html +++ b/Debug/test_coverage/Control/Inciter/index-sort-b.html @@ -33,7 +33,7 @@ - + diff --git a/Debug/test_coverage/Control/Inciter/index-sort-f.html b/Debug/test_coverage/Control/Inciter/index-sort-f.html index c583299550a7..130a146411a0 100644 --- a/Debug/test_coverage/Control/Inciter/index-sort-f.html +++ b/Debug/test_coverage/Control/Inciter/index-sort-f.html @@ -33,7 +33,7 @@ - + diff --git a/Debug/test_coverage/Control/Inciter/index-sort-l.html b/Debug/test_coverage/Control/Inciter/index-sort-l.html index a204d2fa6c58..34765e4bdd0d 100644 --- a/Debug/test_coverage/Control/Inciter/index-sort-l.html +++ b/Debug/test_coverage/Control/Inciter/index-sort-l.html @@ -33,7 +33,7 @@ - + diff --git a/Debug/test_coverage/Control/Inciter/index.html b/Debug/test_coverage/Control/Inciter/index.html index ec9802c658c4..a31b799ca336 100644 --- a/Debug/test_coverage/Control/Inciter/index.html +++ b/Debug/test_coverage/Control/Inciter/index.html @@ -33,7 +33,7 @@ - + diff --git a/Debug/test_coverage/Control/Keyword.hpp.func-sort-c.html b/Debug/test_coverage/Control/Keyword.hpp.func-sort-c.html index 170bf75fbc81..7a8263ca2497 100644 --- a/Debug/test_coverage/Control/Keyword.hpp.func-sort-c.html +++ b/Debug/test_coverage/Control/Keyword.hpp.func-sort-c.html @@ -33,7 +33,7 @@ - + diff --git a/Debug/test_coverage/Control/Keyword.hpp.func.html b/Debug/test_coverage/Control/Keyword.hpp.func.html index d326e38533ee..6d4b531fd0d6 100644 --- a/Debug/test_coverage/Control/Keyword.hpp.func.html +++ b/Debug/test_coverage/Control/Keyword.hpp.func.html @@ -33,7 +33,7 @@ - + diff --git a/Debug/test_coverage/Control/Keyword.hpp.gcov.html b/Debug/test_coverage/Control/Keyword.hpp.gcov.html index 7bbe6ed71f6a..b4d057053776 100644 --- a/Debug/test_coverage/Control/Keyword.hpp.gcov.html +++ b/Debug/test_coverage/Control/Keyword.hpp.gcov.html @@ -33,7 +33,7 @@ - + diff --git a/Debug/test_coverage/Control/Keywords.hpp.func-sort-c.html b/Debug/test_coverage/Control/Keywords.hpp.func-sort-c.html index 399bd94664b8..4e195cb153c1 100644 --- a/Debug/test_coverage/Control/Keywords.hpp.func-sort-c.html +++ b/Debug/test_coverage/Control/Keywords.hpp.func-sort-c.html @@ -33,7 +33,7 @@ - + diff --git a/Debug/test_coverage/Control/Keywords.hpp.func.html b/Debug/test_coverage/Control/Keywords.hpp.func.html index 40e0f29ef700..626ae997aaf4 100644 --- a/Debug/test_coverage/Control/Keywords.hpp.func.html +++ b/Debug/test_coverage/Control/Keywords.hpp.func.html @@ -33,7 +33,7 @@ - + diff --git a/Debug/test_coverage/Control/Keywords.hpp.gcov.html b/Debug/test_coverage/Control/Keywords.hpp.gcov.html index b6711247352e..330129d807ef 100644 --- a/Debug/test_coverage/Control/Keywords.hpp.gcov.html +++ b/Debug/test_coverage/Control/Keywords.hpp.gcov.html @@ -33,7 +33,7 @@ - + diff --git a/Debug/test_coverage/Control/MeshConv/CmdLine/CmdLine.hpp.func-sort-c.html b/Debug/test_coverage/Control/MeshConv/CmdLine/CmdLine.hpp.func-sort-c.html index 578116dd3767..ec66ab7b9ffb 100644 --- a/Debug/test_coverage/Control/MeshConv/CmdLine/CmdLine.hpp.func-sort-c.html +++ b/Debug/test_coverage/Control/MeshConv/CmdLine/CmdLine.hpp.func-sort-c.html @@ -33,7 +33,7 @@ - + diff --git a/Debug/test_coverage/Control/MeshConv/CmdLine/CmdLine.hpp.func.html b/Debug/test_coverage/Control/MeshConv/CmdLine/CmdLine.hpp.func.html index 93e7045bb4b3..c5ea9f276ac8 100644 --- a/Debug/test_coverage/Control/MeshConv/CmdLine/CmdLine.hpp.func.html +++ b/Debug/test_coverage/Control/MeshConv/CmdLine/CmdLine.hpp.func.html @@ -33,7 +33,7 @@ - + diff --git a/Debug/test_coverage/Control/MeshConv/CmdLine/CmdLine.hpp.gcov.html b/Debug/test_coverage/Control/MeshConv/CmdLine/CmdLine.hpp.gcov.html index 9b4fded860d2..b307c951863e 100644 --- a/Debug/test_coverage/Control/MeshConv/CmdLine/CmdLine.hpp.gcov.html +++ b/Debug/test_coverage/Control/MeshConv/CmdLine/CmdLine.hpp.gcov.html @@ -33,7 +33,7 @@ - + diff --git a/Debug/test_coverage/Control/MeshConv/CmdLine/Parser.cpp.func-sort-c.html b/Debug/test_coverage/Control/MeshConv/CmdLine/Parser.cpp.func-sort-c.html index c4cebb0d1820..90fe403f64b8 100644 --- a/Debug/test_coverage/Control/MeshConv/CmdLine/Parser.cpp.func-sort-c.html +++ b/Debug/test_coverage/Control/MeshConv/CmdLine/Parser.cpp.func-sort-c.html @@ -33,7 +33,7 @@ - + diff --git a/Debug/test_coverage/Control/MeshConv/CmdLine/Parser.cpp.func.html b/Debug/test_coverage/Control/MeshConv/CmdLine/Parser.cpp.func.html index 874647bba1d5..b5cdbb826485 100644 --- a/Debug/test_coverage/Control/MeshConv/CmdLine/Parser.cpp.func.html +++ b/Debug/test_coverage/Control/MeshConv/CmdLine/Parser.cpp.func.html @@ -33,7 +33,7 @@ - + diff --git a/Debug/test_coverage/Control/MeshConv/CmdLine/Parser.cpp.gcov.html b/Debug/test_coverage/Control/MeshConv/CmdLine/Parser.cpp.gcov.html index 35530bbee442..4645d48b1781 100644 --- a/Debug/test_coverage/Control/MeshConv/CmdLine/Parser.cpp.gcov.html +++ b/Debug/test_coverage/Control/MeshConv/CmdLine/Parser.cpp.gcov.html @@ -33,7 +33,7 @@ - + diff --git a/Debug/test_coverage/Control/MeshConv/CmdLine/index-sort-b.html b/Debug/test_coverage/Control/MeshConv/CmdLine/index-sort-b.html index 6f05f0c658f2..ec72984627cd 100644 --- a/Debug/test_coverage/Control/MeshConv/CmdLine/index-sort-b.html +++ b/Debug/test_coverage/Control/MeshConv/CmdLine/index-sort-b.html @@ -33,7 +33,7 @@ - + diff --git a/Debug/test_coverage/Control/MeshConv/CmdLine/index-sort-f.html b/Debug/test_coverage/Control/MeshConv/CmdLine/index-sort-f.html index d73653457273..4ee39ffb4421 100644 --- a/Debug/test_coverage/Control/MeshConv/CmdLine/index-sort-f.html +++ b/Debug/test_coverage/Control/MeshConv/CmdLine/index-sort-f.html @@ -33,7 +33,7 @@ - + diff --git a/Debug/test_coverage/Control/MeshConv/CmdLine/index-sort-l.html b/Debug/test_coverage/Control/MeshConv/CmdLine/index-sort-l.html index c6fdb8cc2216..5de1f57b4737 100644 --- a/Debug/test_coverage/Control/MeshConv/CmdLine/index-sort-l.html +++ b/Debug/test_coverage/Control/MeshConv/CmdLine/index-sort-l.html @@ -33,7 +33,7 @@ - + diff --git a/Debug/test_coverage/Control/MeshConv/CmdLine/index.html b/Debug/test_coverage/Control/MeshConv/CmdLine/index.html index de75b8b0f7ae..cad0c0722bbd 100644 --- a/Debug/test_coverage/Control/MeshConv/CmdLine/index.html +++ b/Debug/test_coverage/Control/MeshConv/CmdLine/index.html @@ -33,7 +33,7 @@ - + diff --git a/Debug/test_coverage/Control/Options/Error.hpp.func-sort-c.html b/Debug/test_coverage/Control/Options/Error.hpp.func-sort-c.html index f2fad78b9be0..e96ab409a008 100644 --- a/Debug/test_coverage/Control/Options/Error.hpp.func-sort-c.html +++ b/Debug/test_coverage/Control/Options/Error.hpp.func-sort-c.html @@ -33,7 +33,7 @@ - + diff --git a/Debug/test_coverage/Control/Options/Error.hpp.func.html b/Debug/test_coverage/Control/Options/Error.hpp.func.html index 12732b8c8336..4a4ba3453472 100644 --- a/Debug/test_coverage/Control/Options/Error.hpp.func.html +++ b/Debug/test_coverage/Control/Options/Error.hpp.func.html @@ -33,7 +33,7 @@ - + diff --git a/Debug/test_coverage/Control/Options/Error.hpp.gcov.html b/Debug/test_coverage/Control/Options/Error.hpp.gcov.html index d8668d519742..9b79a2af7a03 100644 --- a/Debug/test_coverage/Control/Options/Error.hpp.gcov.html +++ b/Debug/test_coverage/Control/Options/Error.hpp.gcov.html @@ -33,7 +33,7 @@ - + diff --git a/Debug/test_coverage/Control/Options/FieldFile.hpp.func-sort-c.html b/Debug/test_coverage/Control/Options/FieldFile.hpp.func-sort-c.html index b350fea8fda6..e5cff0041788 100644 --- a/Debug/test_coverage/Control/Options/FieldFile.hpp.func-sort-c.html +++ b/Debug/test_coverage/Control/Options/FieldFile.hpp.func-sort-c.html @@ -33,7 +33,7 @@ - + diff --git a/Debug/test_coverage/Control/Options/FieldFile.hpp.func.html b/Debug/test_coverage/Control/Options/FieldFile.hpp.func.html index 24a3ef7ca2f5..8adeb725699e 100644 --- a/Debug/test_coverage/Control/Options/FieldFile.hpp.func.html +++ b/Debug/test_coverage/Control/Options/FieldFile.hpp.func.html @@ -33,7 +33,7 @@ - + diff --git a/Debug/test_coverage/Control/Options/FieldFile.hpp.gcov.html b/Debug/test_coverage/Control/Options/FieldFile.hpp.gcov.html index 8ded2752cc06..76c46ce55e99 100644 --- a/Debug/test_coverage/Control/Options/FieldFile.hpp.gcov.html +++ b/Debug/test_coverage/Control/Options/FieldFile.hpp.gcov.html @@ -33,7 +33,7 @@ - + diff --git a/Debug/test_coverage/Control/Options/PartitioningAlgorithm.hpp.func-sort-c.html b/Debug/test_coverage/Control/Options/PartitioningAlgorithm.hpp.func-sort-c.html index 242e9473de20..24280815a75b 100644 --- a/Debug/test_coverage/Control/Options/PartitioningAlgorithm.hpp.func-sort-c.html +++ b/Debug/test_coverage/Control/Options/PartitioningAlgorithm.hpp.func-sort-c.html @@ -33,7 +33,7 @@ - + diff --git a/Debug/test_coverage/Control/Options/PartitioningAlgorithm.hpp.func.html b/Debug/test_coverage/Control/Options/PartitioningAlgorithm.hpp.func.html index f03ea76efdc8..427acafe9c31 100644 --- a/Debug/test_coverage/Control/Options/PartitioningAlgorithm.hpp.func.html +++ b/Debug/test_coverage/Control/Options/PartitioningAlgorithm.hpp.func.html @@ -33,7 +33,7 @@ - + diff --git a/Debug/test_coverage/Control/Options/PartitioningAlgorithm.hpp.gcov.html b/Debug/test_coverage/Control/Options/PartitioningAlgorithm.hpp.gcov.html index 679009f2e5e0..6267c79842f3 100644 --- a/Debug/test_coverage/Control/Options/PartitioningAlgorithm.hpp.gcov.html +++ b/Debug/test_coverage/Control/Options/PartitioningAlgorithm.hpp.gcov.html @@ -33,7 +33,7 @@ - + diff --git a/Debug/test_coverage/Control/Options/TxtFloatFormat.hpp.func-sort-c.html b/Debug/test_coverage/Control/Options/TxtFloatFormat.hpp.func-sort-c.html index 0c9eaecc9afb..76ed18dee79a 100644 --- a/Debug/test_coverage/Control/Options/TxtFloatFormat.hpp.func-sort-c.html +++ b/Debug/test_coverage/Control/Options/TxtFloatFormat.hpp.func-sort-c.html @@ -33,7 +33,7 @@ - + diff --git a/Debug/test_coverage/Control/Options/TxtFloatFormat.hpp.func.html b/Debug/test_coverage/Control/Options/TxtFloatFormat.hpp.func.html index 35c4c8b31824..d7ee05968095 100644 --- a/Debug/test_coverage/Control/Options/TxtFloatFormat.hpp.func.html +++ b/Debug/test_coverage/Control/Options/TxtFloatFormat.hpp.func.html @@ -33,7 +33,7 @@ - + diff --git a/Debug/test_coverage/Control/Options/TxtFloatFormat.hpp.gcov.html b/Debug/test_coverage/Control/Options/TxtFloatFormat.hpp.gcov.html index a250369c533c..fb84b5784b6e 100644 --- a/Debug/test_coverage/Control/Options/TxtFloatFormat.hpp.gcov.html +++ b/Debug/test_coverage/Control/Options/TxtFloatFormat.hpp.gcov.html @@ -33,7 +33,7 @@ - + diff --git a/Debug/test_coverage/Control/Options/UserTable.hpp.func-sort-c.html b/Debug/test_coverage/Control/Options/UserTable.hpp.func-sort-c.html index dd3330a58c39..3ecd34bfea46 100644 --- a/Debug/test_coverage/Control/Options/UserTable.hpp.func-sort-c.html +++ b/Debug/test_coverage/Control/Options/UserTable.hpp.func-sort-c.html @@ -33,7 +33,7 @@ - + diff --git a/Debug/test_coverage/Control/Options/UserTable.hpp.func.html b/Debug/test_coverage/Control/Options/UserTable.hpp.func.html index 3b1ca175b6aa..f3fefdc4e5c3 100644 --- a/Debug/test_coverage/Control/Options/UserTable.hpp.func.html +++ b/Debug/test_coverage/Control/Options/UserTable.hpp.func.html @@ -33,7 +33,7 @@ - + diff --git a/Debug/test_coverage/Control/Options/UserTable.hpp.gcov.html b/Debug/test_coverage/Control/Options/UserTable.hpp.gcov.html index b3d8a18f7202..e6c9c2edb04b 100644 --- a/Debug/test_coverage/Control/Options/UserTable.hpp.gcov.html +++ b/Debug/test_coverage/Control/Options/UserTable.hpp.gcov.html @@ -33,7 +33,7 @@ - + diff --git a/Debug/test_coverage/Control/Options/index-sort-b.html b/Debug/test_coverage/Control/Options/index-sort-b.html index 2d620850f27c..7524e7a7dbe6 100644 --- a/Debug/test_coverage/Control/Options/index-sort-b.html +++ b/Debug/test_coverage/Control/Options/index-sort-b.html @@ -33,7 +33,7 @@ - + diff --git a/Debug/test_coverage/Control/Options/index-sort-f.html b/Debug/test_coverage/Control/Options/index-sort-f.html index 10e749ac377c..5e9f0211cc46 100644 --- a/Debug/test_coverage/Control/Options/index-sort-f.html +++ b/Debug/test_coverage/Control/Options/index-sort-f.html @@ -33,7 +33,7 @@ - + @@ -82,52 +82,52 @@ - + - - + + - + - + - - + + - + - + - - + + - + - - + + - + diff --git a/Debug/test_coverage/Control/Options/index-sort-l.html b/Debug/test_coverage/Control/Options/index-sort-l.html index a5b1272680fc..b9f537e3928d 100644 --- a/Debug/test_coverage/Control/Options/index-sort-l.html +++ b/Debug/test_coverage/Control/Options/index-sort-l.html @@ -33,7 +33,7 @@ - + diff --git a/Debug/test_coverage/Control/Options/index.html b/Debug/test_coverage/Control/Options/index.html index 050017b3a0e0..300504cbbfd7 100644 --- a/Debug/test_coverage/Control/Options/index.html +++ b/Debug/test_coverage/Control/Options/index.html @@ -33,7 +33,7 @@ - + diff --git a/Debug/test_coverage/Control/StatCtr.hpp.func-sort-c.html b/Debug/test_coverage/Control/StatCtr.hpp.func-sort-c.html index b51b9e362d3c..68558bb48d18 100644 --- a/Debug/test_coverage/Control/StatCtr.hpp.func-sort-c.html +++ b/Debug/test_coverage/Control/StatCtr.hpp.func-sort-c.html @@ -33,7 +33,7 @@ - + diff --git a/Debug/test_coverage/Control/StatCtr.hpp.func.html b/Debug/test_coverage/Control/StatCtr.hpp.func.html index f7e163da5caf..cef1fda8be5c 100644 --- a/Debug/test_coverage/Control/StatCtr.hpp.func.html +++ b/Debug/test_coverage/Control/StatCtr.hpp.func.html @@ -33,7 +33,7 @@ - + diff --git a/Debug/test_coverage/Control/StatCtr.hpp.gcov.html b/Debug/test_coverage/Control/StatCtr.hpp.gcov.html index 37e107448e4a..d9d32a55227a 100644 --- a/Debug/test_coverage/Control/StatCtr.hpp.gcov.html +++ b/Debug/test_coverage/Control/StatCtr.hpp.gcov.html @@ -33,7 +33,7 @@ - + diff --git a/Debug/test_coverage/Control/StringParser.cpp.func-sort-c.html b/Debug/test_coverage/Control/StringParser.cpp.func-sort-c.html index 64ee78b29c01..6bf17f0566bc 100644 --- a/Debug/test_coverage/Control/StringParser.cpp.func-sort-c.html +++ b/Debug/test_coverage/Control/StringParser.cpp.func-sort-c.html @@ -33,7 +33,7 @@ - + diff --git a/Debug/test_coverage/Control/StringParser.cpp.func.html b/Debug/test_coverage/Control/StringParser.cpp.func.html index 4d1b61d7c566..25b6a139f1fc 100644 --- a/Debug/test_coverage/Control/StringParser.cpp.func.html +++ b/Debug/test_coverage/Control/StringParser.cpp.func.html @@ -33,7 +33,7 @@ - + diff --git a/Debug/test_coverage/Control/StringParser.cpp.gcov.html b/Debug/test_coverage/Control/StringParser.cpp.gcov.html index 89603c92436d..898eb9077e0d 100644 --- a/Debug/test_coverage/Control/StringParser.cpp.gcov.html +++ b/Debug/test_coverage/Control/StringParser.cpp.gcov.html @@ -33,7 +33,7 @@ - + diff --git a/Debug/test_coverage/Control/StringParser.hpp.func-sort-c.html b/Debug/test_coverage/Control/StringParser.hpp.func-sort-c.html index d069db712c88..eb8b2ac89c65 100644 --- a/Debug/test_coverage/Control/StringParser.hpp.func-sort-c.html +++ b/Debug/test_coverage/Control/StringParser.hpp.func-sort-c.html @@ -33,7 +33,7 @@ - + diff --git a/Debug/test_coverage/Control/StringParser.hpp.func.html b/Debug/test_coverage/Control/StringParser.hpp.func.html index 5d37b55f2f48..67406c217109 100644 --- a/Debug/test_coverage/Control/StringParser.hpp.func.html +++ b/Debug/test_coverage/Control/StringParser.hpp.func.html @@ -33,7 +33,7 @@ - + diff --git a/Debug/test_coverage/Control/StringParser.hpp.gcov.html b/Debug/test_coverage/Control/StringParser.hpp.gcov.html index 3b498e009a30..1798f0ad5c43 100644 --- a/Debug/test_coverage/Control/StringParser.hpp.gcov.html +++ b/Debug/test_coverage/Control/StringParser.hpp.gcov.html @@ -33,7 +33,7 @@ - + diff --git a/Debug/test_coverage/Control/Tags.hpp.func-sort-c.html b/Debug/test_coverage/Control/Tags.hpp.func-sort-c.html index af8e6e1aa065..d03293748246 100644 --- a/Debug/test_coverage/Control/Tags.hpp.func-sort-c.html +++ b/Debug/test_coverage/Control/Tags.hpp.func-sort-c.html @@ -33,7 +33,7 @@ - + diff --git a/Debug/test_coverage/Control/Tags.hpp.func.html b/Debug/test_coverage/Control/Tags.hpp.func.html index 6165c4baa768..0bfa6514a067 100644 --- a/Debug/test_coverage/Control/Tags.hpp.func.html +++ b/Debug/test_coverage/Control/Tags.hpp.func.html @@ -33,7 +33,7 @@ - + diff --git a/Debug/test_coverage/Control/Tags.hpp.gcov.html b/Debug/test_coverage/Control/Tags.hpp.gcov.html index 11bc365fce30..523dcef1b89c 100644 --- a/Debug/test_coverage/Control/Tags.hpp.gcov.html +++ b/Debug/test_coverage/Control/Tags.hpp.gcov.html @@ -33,7 +33,7 @@ - + diff --git a/Debug/test_coverage/Control/Toggle.hpp.func-sort-c.html b/Debug/test_coverage/Control/Toggle.hpp.func-sort-c.html index ed32ffa0eaed..e0771981f975 100644 --- a/Debug/test_coverage/Control/Toggle.hpp.func-sort-c.html +++ b/Debug/test_coverage/Control/Toggle.hpp.func-sort-c.html @@ -33,7 +33,7 @@ - + diff --git a/Debug/test_coverage/Control/Toggle.hpp.func.html b/Debug/test_coverage/Control/Toggle.hpp.func.html index 17de0c54ab28..da17c85c82ac 100644 --- a/Debug/test_coverage/Control/Toggle.hpp.func.html +++ b/Debug/test_coverage/Control/Toggle.hpp.func.html @@ -33,7 +33,7 @@ - + diff --git a/Debug/test_coverage/Control/Toggle.hpp.gcov.html b/Debug/test_coverage/Control/Toggle.hpp.gcov.html index 9a7fc114665e..56e3a4754c75 100644 --- a/Debug/test_coverage/Control/Toggle.hpp.gcov.html +++ b/Debug/test_coverage/Control/Toggle.hpp.gcov.html @@ -33,7 +33,7 @@ - + diff --git a/Debug/test_coverage/Control/UnitTest/CmdLine/CmdLine.hpp.func-sort-c.html b/Debug/test_coverage/Control/UnitTest/CmdLine/CmdLine.hpp.func-sort-c.html index 4a22046b554c..d5a2f2067763 100644 --- a/Debug/test_coverage/Control/UnitTest/CmdLine/CmdLine.hpp.func-sort-c.html +++ b/Debug/test_coverage/Control/UnitTest/CmdLine/CmdLine.hpp.func-sort-c.html @@ -33,7 +33,7 @@ - + diff --git a/Debug/test_coverage/Control/UnitTest/CmdLine/CmdLine.hpp.func.html b/Debug/test_coverage/Control/UnitTest/CmdLine/CmdLine.hpp.func.html index 2ab921ebd56b..a02fe45b09c9 100644 --- a/Debug/test_coverage/Control/UnitTest/CmdLine/CmdLine.hpp.func.html +++ b/Debug/test_coverage/Control/UnitTest/CmdLine/CmdLine.hpp.func.html @@ -33,7 +33,7 @@ - + diff --git a/Debug/test_coverage/Control/UnitTest/CmdLine/CmdLine.hpp.gcov.html b/Debug/test_coverage/Control/UnitTest/CmdLine/CmdLine.hpp.gcov.html index 518f09b0e11b..e2406f1ba908 100644 --- a/Debug/test_coverage/Control/UnitTest/CmdLine/CmdLine.hpp.gcov.html +++ b/Debug/test_coverage/Control/UnitTest/CmdLine/CmdLine.hpp.gcov.html @@ -33,7 +33,7 @@ - + diff --git a/Debug/test_coverage/Control/UnitTest/CmdLine/Parser.cpp.func-sort-c.html b/Debug/test_coverage/Control/UnitTest/CmdLine/Parser.cpp.func-sort-c.html index 32d0b6a00d38..ebefd98fe04f 100644 --- a/Debug/test_coverage/Control/UnitTest/CmdLine/Parser.cpp.func-sort-c.html +++ b/Debug/test_coverage/Control/UnitTest/CmdLine/Parser.cpp.func-sort-c.html @@ -33,7 +33,7 @@ - + diff --git a/Debug/test_coverage/Control/UnitTest/CmdLine/Parser.cpp.func.html b/Debug/test_coverage/Control/UnitTest/CmdLine/Parser.cpp.func.html index 7a9c2ccf6c48..2ac432a88c4e 100644 --- a/Debug/test_coverage/Control/UnitTest/CmdLine/Parser.cpp.func.html +++ b/Debug/test_coverage/Control/UnitTest/CmdLine/Parser.cpp.func.html @@ -33,7 +33,7 @@ - + diff --git a/Debug/test_coverage/Control/UnitTest/CmdLine/Parser.cpp.gcov.html b/Debug/test_coverage/Control/UnitTest/CmdLine/Parser.cpp.gcov.html index d6f7c564e2c4..b9ada14bab7c 100644 --- a/Debug/test_coverage/Control/UnitTest/CmdLine/Parser.cpp.gcov.html +++ b/Debug/test_coverage/Control/UnitTest/CmdLine/Parser.cpp.gcov.html @@ -33,7 +33,7 @@ - + diff --git a/Debug/test_coverage/Control/UnitTest/CmdLine/index-sort-b.html b/Debug/test_coverage/Control/UnitTest/CmdLine/index-sort-b.html index bd52d77e2dcc..a3997337233d 100644 --- a/Debug/test_coverage/Control/UnitTest/CmdLine/index-sort-b.html +++ b/Debug/test_coverage/Control/UnitTest/CmdLine/index-sort-b.html @@ -33,7 +33,7 @@ - + diff --git a/Debug/test_coverage/Control/UnitTest/CmdLine/index-sort-f.html b/Debug/test_coverage/Control/UnitTest/CmdLine/index-sort-f.html index 501f1fdc2b25..e4ddfc2656dd 100644 --- a/Debug/test_coverage/Control/UnitTest/CmdLine/index-sort-f.html +++ b/Debug/test_coverage/Control/UnitTest/CmdLine/index-sort-f.html @@ -33,7 +33,7 @@ - + diff --git a/Debug/test_coverage/Control/UnitTest/CmdLine/index-sort-l.html b/Debug/test_coverage/Control/UnitTest/CmdLine/index-sort-l.html index cc9c8d3428dd..af99362e3476 100644 --- a/Debug/test_coverage/Control/UnitTest/CmdLine/index-sort-l.html +++ b/Debug/test_coverage/Control/UnitTest/CmdLine/index-sort-l.html @@ -33,7 +33,7 @@ - + diff --git a/Debug/test_coverage/Control/UnitTest/CmdLine/index.html b/Debug/test_coverage/Control/UnitTest/CmdLine/index.html index bfbbe8ec6fb3..6803c16e78f9 100644 --- a/Debug/test_coverage/Control/UnitTest/CmdLine/index.html +++ b/Debug/test_coverage/Control/UnitTest/CmdLine/index.html @@ -33,7 +33,7 @@ - + diff --git a/Debug/test_coverage/Control/index-sort-b.html b/Debug/test_coverage/Control/index-sort-b.html index 0f3f198dbf70..fd02f2c67442 100644 --- a/Debug/test_coverage/Control/index-sort-b.html +++ b/Debug/test_coverage/Control/index-sort-b.html @@ -33,7 +33,7 @@ - + diff --git a/Debug/test_coverage/Control/index-sort-f.html b/Debug/test_coverage/Control/index-sort-f.html index 2c070b59e215..fe2c64bb2a28 100644 --- a/Debug/test_coverage/Control/index-sort-f.html +++ b/Debug/test_coverage/Control/index-sort-f.html @@ -33,7 +33,7 @@ - + diff --git a/Debug/test_coverage/Control/index-sort-l.html b/Debug/test_coverage/Control/index-sort-l.html index 5131115bac5e..bab4b34f787c 100644 --- a/Debug/test_coverage/Control/index-sort-l.html +++ b/Debug/test_coverage/Control/index-sort-l.html @@ -33,7 +33,7 @@ - + diff --git a/Debug/test_coverage/Control/index.html b/Debug/test_coverage/Control/index.html index 935b9947c954..8d92a6b0c832 100644 --- a/Debug/test_coverage/Control/index.html +++ b/Debug/test_coverage/Control/index.html @@ -33,7 +33,7 @@ - + diff --git a/Debug/test_coverage/IO/ASCMeshReader.cpp.func-sort-c.html b/Debug/test_coverage/IO/ASCMeshReader.cpp.func-sort-c.html index c390cbf8ed0a..321582b6af42 100644 --- a/Debug/test_coverage/IO/ASCMeshReader.cpp.func-sort-c.html +++ b/Debug/test_coverage/IO/ASCMeshReader.cpp.func-sort-c.html @@ -33,7 +33,7 @@ - + diff --git a/Debug/test_coverage/IO/ASCMeshReader.cpp.func.html b/Debug/test_coverage/IO/ASCMeshReader.cpp.func.html index 50b9e0852440..a5c5d8342299 100644 --- a/Debug/test_coverage/IO/ASCMeshReader.cpp.func.html +++ b/Debug/test_coverage/IO/ASCMeshReader.cpp.func.html @@ -33,7 +33,7 @@ - + diff --git a/Debug/test_coverage/IO/ASCMeshReader.cpp.gcov.html b/Debug/test_coverage/IO/ASCMeshReader.cpp.gcov.html index bc48832b4374..bec9d86287bd 100644 --- a/Debug/test_coverage/IO/ASCMeshReader.cpp.gcov.html +++ b/Debug/test_coverage/IO/ASCMeshReader.cpp.gcov.html @@ -33,7 +33,7 @@ - + diff --git a/Debug/test_coverage/IO/ASCMeshReader.hpp.func-sort-c.html b/Debug/test_coverage/IO/ASCMeshReader.hpp.func-sort-c.html index c6e8b6c66b23..10fe711f7140 100644 --- a/Debug/test_coverage/IO/ASCMeshReader.hpp.func-sort-c.html +++ b/Debug/test_coverage/IO/ASCMeshReader.hpp.func-sort-c.html @@ -33,7 +33,7 @@ - + diff --git a/Debug/test_coverage/IO/ASCMeshReader.hpp.func.html b/Debug/test_coverage/IO/ASCMeshReader.hpp.func.html index b17ba2af52d7..9d9975d4ad3d 100644 --- a/Debug/test_coverage/IO/ASCMeshReader.hpp.func.html +++ b/Debug/test_coverage/IO/ASCMeshReader.hpp.func.html @@ -33,7 +33,7 @@ - + diff --git a/Debug/test_coverage/IO/ASCMeshReader.hpp.gcov.html b/Debug/test_coverage/IO/ASCMeshReader.hpp.gcov.html index b0bdf65ae204..c7cbaf277427 100644 --- a/Debug/test_coverage/IO/ASCMeshReader.hpp.gcov.html +++ b/Debug/test_coverage/IO/ASCMeshReader.hpp.gcov.html @@ -33,7 +33,7 @@ - + diff --git a/Debug/test_coverage/IO/DiagWriter.cpp.func-sort-c.html b/Debug/test_coverage/IO/DiagWriter.cpp.func-sort-c.html index 9fdac3d0e310..a626967e3876 100644 --- a/Debug/test_coverage/IO/DiagWriter.cpp.func-sort-c.html +++ b/Debug/test_coverage/IO/DiagWriter.cpp.func-sort-c.html @@ -33,7 +33,7 @@ - + diff --git a/Debug/test_coverage/IO/DiagWriter.cpp.func.html b/Debug/test_coverage/IO/DiagWriter.cpp.func.html index 10a466c79e6f..e88a5f5bf680 100644 --- a/Debug/test_coverage/IO/DiagWriter.cpp.func.html +++ b/Debug/test_coverage/IO/DiagWriter.cpp.func.html @@ -33,7 +33,7 @@ - + diff --git a/Debug/test_coverage/IO/DiagWriter.cpp.gcov.html b/Debug/test_coverage/IO/DiagWriter.cpp.gcov.html index e91de00b5eb4..b337f3c8a85f 100644 --- a/Debug/test_coverage/IO/DiagWriter.cpp.gcov.html +++ b/Debug/test_coverage/IO/DiagWriter.cpp.gcov.html @@ -33,7 +33,7 @@ - + diff --git a/Debug/test_coverage/IO/ExodusIIMeshReader.cpp.func-sort-c.html b/Debug/test_coverage/IO/ExodusIIMeshReader.cpp.func-sort-c.html index 232d65d61a58..6fa217a2c915 100644 --- a/Debug/test_coverage/IO/ExodusIIMeshReader.cpp.func-sort-c.html +++ b/Debug/test_coverage/IO/ExodusIIMeshReader.cpp.func-sort-c.html @@ -33,7 +33,7 @@ - + diff --git a/Debug/test_coverage/IO/ExodusIIMeshReader.cpp.func.html b/Debug/test_coverage/IO/ExodusIIMeshReader.cpp.func.html index c27a12cc8383..f1c0b9527453 100644 --- a/Debug/test_coverage/IO/ExodusIIMeshReader.cpp.func.html +++ b/Debug/test_coverage/IO/ExodusIIMeshReader.cpp.func.html @@ -33,7 +33,7 @@ - + diff --git a/Debug/test_coverage/IO/ExodusIIMeshReader.cpp.gcov.html b/Debug/test_coverage/IO/ExodusIIMeshReader.cpp.gcov.html index 49648aa115ec..ffb41a0d8d15 100644 --- a/Debug/test_coverage/IO/ExodusIIMeshReader.cpp.gcov.html +++ b/Debug/test_coverage/IO/ExodusIIMeshReader.cpp.gcov.html @@ -33,7 +33,7 @@ - + diff --git a/Debug/test_coverage/IO/ExodusIIMeshReader.hpp.func-sort-c.html b/Debug/test_coverage/IO/ExodusIIMeshReader.hpp.func-sort-c.html index dcae09b641e2..d6d86b318d82 100644 --- a/Debug/test_coverage/IO/ExodusIIMeshReader.hpp.func-sort-c.html +++ b/Debug/test_coverage/IO/ExodusIIMeshReader.hpp.func-sort-c.html @@ -33,7 +33,7 @@ - + diff --git a/Debug/test_coverage/IO/ExodusIIMeshReader.hpp.func.html b/Debug/test_coverage/IO/ExodusIIMeshReader.hpp.func.html index cdf8af633811..2723aadbb0d3 100644 --- a/Debug/test_coverage/IO/ExodusIIMeshReader.hpp.func.html +++ b/Debug/test_coverage/IO/ExodusIIMeshReader.hpp.func.html @@ -33,7 +33,7 @@ - + diff --git a/Debug/test_coverage/IO/ExodusIIMeshReader.hpp.gcov.html b/Debug/test_coverage/IO/ExodusIIMeshReader.hpp.gcov.html index 4676a0c46cd2..3d7e77e98fdd 100644 --- a/Debug/test_coverage/IO/ExodusIIMeshReader.hpp.gcov.html +++ b/Debug/test_coverage/IO/ExodusIIMeshReader.hpp.gcov.html @@ -33,7 +33,7 @@ - + diff --git a/Debug/test_coverage/IO/ExodusIIMeshWriter.cpp.func-sort-c.html b/Debug/test_coverage/IO/ExodusIIMeshWriter.cpp.func-sort-c.html index 29e1820db790..58c11e332f1f 100644 --- a/Debug/test_coverage/IO/ExodusIIMeshWriter.cpp.func-sort-c.html +++ b/Debug/test_coverage/IO/ExodusIIMeshWriter.cpp.func-sort-c.html @@ -33,7 +33,7 @@ - + diff --git a/Debug/test_coverage/IO/ExodusIIMeshWriter.cpp.func.html b/Debug/test_coverage/IO/ExodusIIMeshWriter.cpp.func.html index 0042eaf808b6..bcf77afa2777 100644 --- a/Debug/test_coverage/IO/ExodusIIMeshWriter.cpp.func.html +++ b/Debug/test_coverage/IO/ExodusIIMeshWriter.cpp.func.html @@ -33,7 +33,7 @@ - + diff --git a/Debug/test_coverage/IO/ExodusIIMeshWriter.cpp.gcov.html b/Debug/test_coverage/IO/ExodusIIMeshWriter.cpp.gcov.html index 9177845ab814..fe92f397e877 100644 --- a/Debug/test_coverage/IO/ExodusIIMeshWriter.cpp.gcov.html +++ b/Debug/test_coverage/IO/ExodusIIMeshWriter.cpp.gcov.html @@ -33,7 +33,7 @@ - + diff --git a/Debug/test_coverage/IO/ExodusIIMeshWriter.hpp.func-sort-c.html b/Debug/test_coverage/IO/ExodusIIMeshWriter.hpp.func-sort-c.html index 843c0e57ae33..fb0a4919c12a 100644 --- a/Debug/test_coverage/IO/ExodusIIMeshWriter.hpp.func-sort-c.html +++ b/Debug/test_coverage/IO/ExodusIIMeshWriter.hpp.func-sort-c.html @@ -33,7 +33,7 @@ - + diff --git a/Debug/test_coverage/IO/ExodusIIMeshWriter.hpp.func.html b/Debug/test_coverage/IO/ExodusIIMeshWriter.hpp.func.html index 1ceb16abfda0..ddbed8c4283e 100644 --- a/Debug/test_coverage/IO/ExodusIIMeshWriter.hpp.func.html +++ b/Debug/test_coverage/IO/ExodusIIMeshWriter.hpp.func.html @@ -33,7 +33,7 @@ - + diff --git a/Debug/test_coverage/IO/ExodusIIMeshWriter.hpp.gcov.html b/Debug/test_coverage/IO/ExodusIIMeshWriter.hpp.gcov.html index 9507535c82aa..661c813736cf 100644 --- a/Debug/test_coverage/IO/ExodusIIMeshWriter.hpp.gcov.html +++ b/Debug/test_coverage/IO/ExodusIIMeshWriter.hpp.gcov.html @@ -33,7 +33,7 @@ - + diff --git a/Debug/test_coverage/IO/GmshMeshReader.cpp.func-sort-c.html b/Debug/test_coverage/IO/GmshMeshReader.cpp.func-sort-c.html index 6392fa805f14..802a0d85d439 100644 --- a/Debug/test_coverage/IO/GmshMeshReader.cpp.func-sort-c.html +++ b/Debug/test_coverage/IO/GmshMeshReader.cpp.func-sort-c.html @@ -33,7 +33,7 @@ - + diff --git a/Debug/test_coverage/IO/GmshMeshReader.cpp.func.html b/Debug/test_coverage/IO/GmshMeshReader.cpp.func.html index 8c0da34fe4f2..22d7657e72c7 100644 --- a/Debug/test_coverage/IO/GmshMeshReader.cpp.func.html +++ b/Debug/test_coverage/IO/GmshMeshReader.cpp.func.html @@ -33,7 +33,7 @@ - + diff --git a/Debug/test_coverage/IO/GmshMeshReader.cpp.gcov.html b/Debug/test_coverage/IO/GmshMeshReader.cpp.gcov.html index 3da5bb759313..970921061453 100644 --- a/Debug/test_coverage/IO/GmshMeshReader.cpp.gcov.html +++ b/Debug/test_coverage/IO/GmshMeshReader.cpp.gcov.html @@ -33,7 +33,7 @@ - + diff --git a/Debug/test_coverage/IO/GmshMeshReader.hpp.func-sort-c.html b/Debug/test_coverage/IO/GmshMeshReader.hpp.func-sort-c.html index 937edb8ea12e..236e2415d724 100644 --- a/Debug/test_coverage/IO/GmshMeshReader.hpp.func-sort-c.html +++ b/Debug/test_coverage/IO/GmshMeshReader.hpp.func-sort-c.html @@ -33,7 +33,7 @@ - + diff --git a/Debug/test_coverage/IO/GmshMeshReader.hpp.func.html b/Debug/test_coverage/IO/GmshMeshReader.hpp.func.html index a5362c1782dd..751b015ee326 100644 --- a/Debug/test_coverage/IO/GmshMeshReader.hpp.func.html +++ b/Debug/test_coverage/IO/GmshMeshReader.hpp.func.html @@ -33,7 +33,7 @@ - + diff --git a/Debug/test_coverage/IO/GmshMeshReader.hpp.gcov.html b/Debug/test_coverage/IO/GmshMeshReader.hpp.gcov.html index 4b211a8df536..8c105b53ecfd 100644 --- a/Debug/test_coverage/IO/GmshMeshReader.hpp.gcov.html +++ b/Debug/test_coverage/IO/GmshMeshReader.hpp.gcov.html @@ -33,7 +33,7 @@ - + diff --git a/Debug/test_coverage/IO/GmshMeshWriter.cpp.func-sort-c.html b/Debug/test_coverage/IO/GmshMeshWriter.cpp.func-sort-c.html index 3c7f8fbf355c..0ee72b34310b 100644 --- a/Debug/test_coverage/IO/GmshMeshWriter.cpp.func-sort-c.html +++ b/Debug/test_coverage/IO/GmshMeshWriter.cpp.func-sort-c.html @@ -33,7 +33,7 @@ - + diff --git a/Debug/test_coverage/IO/GmshMeshWriter.cpp.func.html b/Debug/test_coverage/IO/GmshMeshWriter.cpp.func.html index 8d3a91847df1..15e01b6bbc15 100644 --- a/Debug/test_coverage/IO/GmshMeshWriter.cpp.func.html +++ b/Debug/test_coverage/IO/GmshMeshWriter.cpp.func.html @@ -33,7 +33,7 @@ - + diff --git a/Debug/test_coverage/IO/GmshMeshWriter.cpp.gcov.html b/Debug/test_coverage/IO/GmshMeshWriter.cpp.gcov.html index 6ce1e7bd4280..f1a7c184954d 100644 --- a/Debug/test_coverage/IO/GmshMeshWriter.cpp.gcov.html +++ b/Debug/test_coverage/IO/GmshMeshWriter.cpp.gcov.html @@ -33,7 +33,7 @@ - + diff --git a/Debug/test_coverage/IO/GmshMeshWriter.hpp.func-sort-c.html b/Debug/test_coverage/IO/GmshMeshWriter.hpp.func-sort-c.html index a2619f1f00cb..2f3ef3fd99f1 100644 --- a/Debug/test_coverage/IO/GmshMeshWriter.hpp.func-sort-c.html +++ b/Debug/test_coverage/IO/GmshMeshWriter.hpp.func-sort-c.html @@ -33,7 +33,7 @@ - + diff --git a/Debug/test_coverage/IO/GmshMeshWriter.hpp.func.html b/Debug/test_coverage/IO/GmshMeshWriter.hpp.func.html index ef608bf732d0..9359f9ee859a 100644 --- a/Debug/test_coverage/IO/GmshMeshWriter.hpp.func.html +++ b/Debug/test_coverage/IO/GmshMeshWriter.hpp.func.html @@ -33,7 +33,7 @@ - + diff --git a/Debug/test_coverage/IO/GmshMeshWriter.hpp.gcov.html b/Debug/test_coverage/IO/GmshMeshWriter.hpp.gcov.html index 4278f93b1eac..e1dc512b6e99 100644 --- a/Debug/test_coverage/IO/GmshMeshWriter.hpp.gcov.html +++ b/Debug/test_coverage/IO/GmshMeshWriter.hpp.gcov.html @@ -33,7 +33,7 @@ - + diff --git a/Debug/test_coverage/IO/HyperMeshReader.cpp.func-sort-c.html b/Debug/test_coverage/IO/HyperMeshReader.cpp.func-sort-c.html index b450770bd95f..35837aa93d4c 100644 --- a/Debug/test_coverage/IO/HyperMeshReader.cpp.func-sort-c.html +++ b/Debug/test_coverage/IO/HyperMeshReader.cpp.func-sort-c.html @@ -33,7 +33,7 @@ - + diff --git a/Debug/test_coverage/IO/HyperMeshReader.cpp.func.html b/Debug/test_coverage/IO/HyperMeshReader.cpp.func.html index 6d17e5250955..2ec39e579545 100644 --- a/Debug/test_coverage/IO/HyperMeshReader.cpp.func.html +++ b/Debug/test_coverage/IO/HyperMeshReader.cpp.func.html @@ -33,7 +33,7 @@ - + diff --git a/Debug/test_coverage/IO/HyperMeshReader.cpp.gcov.html b/Debug/test_coverage/IO/HyperMeshReader.cpp.gcov.html index e69bf0368462..2be6723f9b06 100644 --- a/Debug/test_coverage/IO/HyperMeshReader.cpp.gcov.html +++ b/Debug/test_coverage/IO/HyperMeshReader.cpp.gcov.html @@ -33,7 +33,7 @@ - + diff --git a/Debug/test_coverage/IO/HyperMeshReader.hpp.func-sort-c.html b/Debug/test_coverage/IO/HyperMeshReader.hpp.func-sort-c.html index f88a3aa6b19a..dcafa75d6e60 100644 --- a/Debug/test_coverage/IO/HyperMeshReader.hpp.func-sort-c.html +++ b/Debug/test_coverage/IO/HyperMeshReader.hpp.func-sort-c.html @@ -33,7 +33,7 @@ - + diff --git a/Debug/test_coverage/IO/HyperMeshReader.hpp.func.html b/Debug/test_coverage/IO/HyperMeshReader.hpp.func.html index f79e049198dc..8f4e4c88929d 100644 --- a/Debug/test_coverage/IO/HyperMeshReader.hpp.func.html +++ b/Debug/test_coverage/IO/HyperMeshReader.hpp.func.html @@ -33,7 +33,7 @@ - + diff --git a/Debug/test_coverage/IO/HyperMeshReader.hpp.gcov.html b/Debug/test_coverage/IO/HyperMeshReader.hpp.gcov.html index 6ab34b19b1bc..1295e09d96a9 100644 --- a/Debug/test_coverage/IO/HyperMeshReader.hpp.gcov.html +++ b/Debug/test_coverage/IO/HyperMeshReader.hpp.gcov.html @@ -33,7 +33,7 @@ - + diff --git a/Debug/test_coverage/IO/MeshDetect.cpp.func-sort-c.html b/Debug/test_coverage/IO/MeshDetect.cpp.func-sort-c.html index f43f211659c0..b798f8a6e002 100644 --- a/Debug/test_coverage/IO/MeshDetect.cpp.func-sort-c.html +++ b/Debug/test_coverage/IO/MeshDetect.cpp.func-sort-c.html @@ -33,7 +33,7 @@ - + diff --git a/Debug/test_coverage/IO/MeshDetect.cpp.func.html b/Debug/test_coverage/IO/MeshDetect.cpp.func.html index 810c330591d7..dbcb50627364 100644 --- a/Debug/test_coverage/IO/MeshDetect.cpp.func.html +++ b/Debug/test_coverage/IO/MeshDetect.cpp.func.html @@ -33,7 +33,7 @@ - + diff --git a/Debug/test_coverage/IO/MeshDetect.cpp.gcov.html b/Debug/test_coverage/IO/MeshDetect.cpp.gcov.html index 35463851dfd4..287b68a2ce02 100644 --- a/Debug/test_coverage/IO/MeshDetect.cpp.gcov.html +++ b/Debug/test_coverage/IO/MeshDetect.cpp.gcov.html @@ -33,7 +33,7 @@ - + diff --git a/Debug/test_coverage/IO/MeshFactory.cpp.func-sort-c.html b/Debug/test_coverage/IO/MeshFactory.cpp.func-sort-c.html index 39f55718089f..242a3998dedf 100644 --- a/Debug/test_coverage/IO/MeshFactory.cpp.func-sort-c.html +++ b/Debug/test_coverage/IO/MeshFactory.cpp.func-sort-c.html @@ -33,7 +33,7 @@ - + diff --git a/Debug/test_coverage/IO/MeshFactory.cpp.func.html b/Debug/test_coverage/IO/MeshFactory.cpp.func.html index 718bd9f6ceb8..88909581b547 100644 --- a/Debug/test_coverage/IO/MeshFactory.cpp.func.html +++ b/Debug/test_coverage/IO/MeshFactory.cpp.func.html @@ -33,7 +33,7 @@ - + diff --git a/Debug/test_coverage/IO/MeshFactory.cpp.gcov.html b/Debug/test_coverage/IO/MeshFactory.cpp.gcov.html index e52519ec363f..7d54d0358b0a 100644 --- a/Debug/test_coverage/IO/MeshFactory.cpp.gcov.html +++ b/Debug/test_coverage/IO/MeshFactory.cpp.gcov.html @@ -33,7 +33,7 @@ - + diff --git a/Debug/test_coverage/IO/MeshReader.hpp.func-sort-c.html b/Debug/test_coverage/IO/MeshReader.hpp.func-sort-c.html index ab518d927c86..3f8a75e83fb7 100644 --- a/Debug/test_coverage/IO/MeshReader.hpp.func-sort-c.html +++ b/Debug/test_coverage/IO/MeshReader.hpp.func-sort-c.html @@ -33,7 +33,7 @@ - + diff --git a/Debug/test_coverage/IO/MeshReader.hpp.func.html b/Debug/test_coverage/IO/MeshReader.hpp.func.html index 6b9a49407b67..9c78d1cfdf97 100644 --- a/Debug/test_coverage/IO/MeshReader.hpp.func.html +++ b/Debug/test_coverage/IO/MeshReader.hpp.func.html @@ -33,7 +33,7 @@ - + diff --git a/Debug/test_coverage/IO/MeshReader.hpp.gcov.html b/Debug/test_coverage/IO/MeshReader.hpp.gcov.html index bcb9247b778d..10e4a9a91284 100644 --- a/Debug/test_coverage/IO/MeshReader.hpp.gcov.html +++ b/Debug/test_coverage/IO/MeshReader.hpp.gcov.html @@ -33,7 +33,7 @@ - + diff --git a/Debug/test_coverage/IO/MeshWriter.cpp.func-sort-c.html b/Debug/test_coverage/IO/MeshWriter.cpp.func-sort-c.html index 1fe5e33ca2cc..8ac0c45d94ae 100644 --- a/Debug/test_coverage/IO/MeshWriter.cpp.func-sort-c.html +++ b/Debug/test_coverage/IO/MeshWriter.cpp.func-sort-c.html @@ -33,7 +33,7 @@ - + diff --git a/Debug/test_coverage/IO/MeshWriter.cpp.func.html b/Debug/test_coverage/IO/MeshWriter.cpp.func.html index 892ee2e46d3f..498ce3379c7e 100644 --- a/Debug/test_coverage/IO/MeshWriter.cpp.func.html +++ b/Debug/test_coverage/IO/MeshWriter.cpp.func.html @@ -33,7 +33,7 @@ - + diff --git a/Debug/test_coverage/IO/MeshWriter.cpp.gcov.html b/Debug/test_coverage/IO/MeshWriter.cpp.gcov.html index 01dd014efc93..f84445dc1e3c 100644 --- a/Debug/test_coverage/IO/MeshWriter.cpp.gcov.html +++ b/Debug/test_coverage/IO/MeshWriter.cpp.gcov.html @@ -33,7 +33,7 @@ - + diff --git a/Debug/test_coverage/IO/MeshWriter.hpp.func-sort-c.html b/Debug/test_coverage/IO/MeshWriter.hpp.func-sort-c.html index 11d20f7f0e2f..217963a165e3 100644 --- a/Debug/test_coverage/IO/MeshWriter.hpp.func-sort-c.html +++ b/Debug/test_coverage/IO/MeshWriter.hpp.func-sort-c.html @@ -33,7 +33,7 @@ - + diff --git a/Debug/test_coverage/IO/MeshWriter.hpp.func.html b/Debug/test_coverage/IO/MeshWriter.hpp.func.html index 69da819d8245..5373e5b4f545 100644 --- a/Debug/test_coverage/IO/MeshWriter.hpp.func.html +++ b/Debug/test_coverage/IO/MeshWriter.hpp.func.html @@ -33,7 +33,7 @@ - + diff --git a/Debug/test_coverage/IO/MeshWriter.hpp.gcov.html b/Debug/test_coverage/IO/MeshWriter.hpp.gcov.html index 19c9677af8bf..7629e88fbdc9 100644 --- a/Debug/test_coverage/IO/MeshWriter.hpp.gcov.html +++ b/Debug/test_coverage/IO/MeshWriter.hpp.gcov.html @@ -33,7 +33,7 @@ - + diff --git a/Debug/test_coverage/IO/NetgenMeshReader.cpp.func-sort-c.html b/Debug/test_coverage/IO/NetgenMeshReader.cpp.func-sort-c.html index 651b6be3057c..fb5f05dbaa80 100644 --- a/Debug/test_coverage/IO/NetgenMeshReader.cpp.func-sort-c.html +++ b/Debug/test_coverage/IO/NetgenMeshReader.cpp.func-sort-c.html @@ -33,7 +33,7 @@ - + diff --git a/Debug/test_coverage/IO/NetgenMeshReader.cpp.func.html b/Debug/test_coverage/IO/NetgenMeshReader.cpp.func.html index bb58cdaabd8b..40a087b0b2b5 100644 --- a/Debug/test_coverage/IO/NetgenMeshReader.cpp.func.html +++ b/Debug/test_coverage/IO/NetgenMeshReader.cpp.func.html @@ -33,7 +33,7 @@ - + diff --git a/Debug/test_coverage/IO/NetgenMeshReader.cpp.gcov.html b/Debug/test_coverage/IO/NetgenMeshReader.cpp.gcov.html index 64186e6a7803..beb4354eac3e 100644 --- a/Debug/test_coverage/IO/NetgenMeshReader.cpp.gcov.html +++ b/Debug/test_coverage/IO/NetgenMeshReader.cpp.gcov.html @@ -33,7 +33,7 @@ - + diff --git a/Debug/test_coverage/IO/NetgenMeshReader.hpp.func-sort-c.html b/Debug/test_coverage/IO/NetgenMeshReader.hpp.func-sort-c.html index 807c9d08632d..ce3f4d75b2db 100644 --- a/Debug/test_coverage/IO/NetgenMeshReader.hpp.func-sort-c.html +++ b/Debug/test_coverage/IO/NetgenMeshReader.hpp.func-sort-c.html @@ -33,7 +33,7 @@ - + diff --git a/Debug/test_coverage/IO/NetgenMeshReader.hpp.func.html b/Debug/test_coverage/IO/NetgenMeshReader.hpp.func.html index 89c9f1bac5c8..ebc217af9552 100644 --- a/Debug/test_coverage/IO/NetgenMeshReader.hpp.func.html +++ b/Debug/test_coverage/IO/NetgenMeshReader.hpp.func.html @@ -33,7 +33,7 @@ - + diff --git a/Debug/test_coverage/IO/NetgenMeshReader.hpp.gcov.html b/Debug/test_coverage/IO/NetgenMeshReader.hpp.gcov.html index 34a9d98598ba..3b2bf5fe30a2 100644 --- a/Debug/test_coverage/IO/NetgenMeshReader.hpp.gcov.html +++ b/Debug/test_coverage/IO/NetgenMeshReader.hpp.gcov.html @@ -33,7 +33,7 @@ - + diff --git a/Debug/test_coverage/IO/NetgenMeshWriter.cpp.func-sort-c.html b/Debug/test_coverage/IO/NetgenMeshWriter.cpp.func-sort-c.html index b28b1d6162c0..ce015a71eef8 100644 --- a/Debug/test_coverage/IO/NetgenMeshWriter.cpp.func-sort-c.html +++ b/Debug/test_coverage/IO/NetgenMeshWriter.cpp.func-sort-c.html @@ -33,7 +33,7 @@ - + diff --git a/Debug/test_coverage/IO/NetgenMeshWriter.cpp.func.html b/Debug/test_coverage/IO/NetgenMeshWriter.cpp.func.html index 053b3832461e..db6685da0fda 100644 --- a/Debug/test_coverage/IO/NetgenMeshWriter.cpp.func.html +++ b/Debug/test_coverage/IO/NetgenMeshWriter.cpp.func.html @@ -33,7 +33,7 @@ - + diff --git a/Debug/test_coverage/IO/NetgenMeshWriter.cpp.gcov.html b/Debug/test_coverage/IO/NetgenMeshWriter.cpp.gcov.html index 080a9cc9f15b..2d4b7aad9d79 100644 --- a/Debug/test_coverage/IO/NetgenMeshWriter.cpp.gcov.html +++ b/Debug/test_coverage/IO/NetgenMeshWriter.cpp.gcov.html @@ -33,7 +33,7 @@ - + diff --git a/Debug/test_coverage/IO/NetgenMeshWriter.hpp.func-sort-c.html b/Debug/test_coverage/IO/NetgenMeshWriter.hpp.func-sort-c.html index 48aa7d15d9ee..9c747b0a71b1 100644 --- a/Debug/test_coverage/IO/NetgenMeshWriter.hpp.func-sort-c.html +++ b/Debug/test_coverage/IO/NetgenMeshWriter.hpp.func-sort-c.html @@ -33,7 +33,7 @@ - + diff --git a/Debug/test_coverage/IO/NetgenMeshWriter.hpp.func.html b/Debug/test_coverage/IO/NetgenMeshWriter.hpp.func.html index 80686dc83cba..05c3d39c9391 100644 --- a/Debug/test_coverage/IO/NetgenMeshWriter.hpp.func.html +++ b/Debug/test_coverage/IO/NetgenMeshWriter.hpp.func.html @@ -33,7 +33,7 @@ - + diff --git a/Debug/test_coverage/IO/NetgenMeshWriter.hpp.gcov.html b/Debug/test_coverage/IO/NetgenMeshWriter.hpp.gcov.html index a2ce3d2af8ad..6728d08bd3ce 100644 --- a/Debug/test_coverage/IO/NetgenMeshWriter.hpp.gcov.html +++ b/Debug/test_coverage/IO/NetgenMeshWriter.hpp.gcov.html @@ -33,7 +33,7 @@ - + diff --git a/Debug/test_coverage/IO/PDFWriter.cpp.func-sort-c.html b/Debug/test_coverage/IO/PDFWriter.cpp.func-sort-c.html index e1e953c2100a..dd48fbe9a73e 100644 --- a/Debug/test_coverage/IO/PDFWriter.cpp.func-sort-c.html +++ b/Debug/test_coverage/IO/PDFWriter.cpp.func-sort-c.html @@ -33,7 +33,7 @@ - + diff --git a/Debug/test_coverage/IO/PDFWriter.cpp.func.html b/Debug/test_coverage/IO/PDFWriter.cpp.func.html index ec6beb032d3e..bb8f5837f927 100644 --- a/Debug/test_coverage/IO/PDFWriter.cpp.func.html +++ b/Debug/test_coverage/IO/PDFWriter.cpp.func.html @@ -33,7 +33,7 @@ - + diff --git a/Debug/test_coverage/IO/PDFWriter.cpp.gcov.html b/Debug/test_coverage/IO/PDFWriter.cpp.gcov.html index 93db70c7d9e0..dea4890cfb79 100644 --- a/Debug/test_coverage/IO/PDFWriter.cpp.gcov.html +++ b/Debug/test_coverage/IO/PDFWriter.cpp.gcov.html @@ -33,7 +33,7 @@ - + diff --git a/Debug/test_coverage/IO/PDFWriter.hpp.func-sort-c.html b/Debug/test_coverage/IO/PDFWriter.hpp.func-sort-c.html index 8a6d9f4b2e7f..729d8f5151cb 100644 --- a/Debug/test_coverage/IO/PDFWriter.hpp.func-sort-c.html +++ b/Debug/test_coverage/IO/PDFWriter.hpp.func-sort-c.html @@ -33,7 +33,7 @@ - + diff --git a/Debug/test_coverage/IO/PDFWriter.hpp.func.html b/Debug/test_coverage/IO/PDFWriter.hpp.func.html index 9065b80ac899..eac87f7179b5 100644 --- a/Debug/test_coverage/IO/PDFWriter.hpp.func.html +++ b/Debug/test_coverage/IO/PDFWriter.hpp.func.html @@ -33,7 +33,7 @@ - + diff --git a/Debug/test_coverage/IO/PDFWriter.hpp.gcov.html b/Debug/test_coverage/IO/PDFWriter.hpp.gcov.html index 8c37be24c1c6..e426adcbdf69 100644 --- a/Debug/test_coverage/IO/PDFWriter.hpp.gcov.html +++ b/Debug/test_coverage/IO/PDFWriter.hpp.gcov.html @@ -33,7 +33,7 @@ - + diff --git a/Debug/test_coverage/IO/RDGFLOMeshReader.cpp.func-sort-c.html b/Debug/test_coverage/IO/RDGFLOMeshReader.cpp.func-sort-c.html index a2f1f9561ef2..576c5b49287e 100644 --- a/Debug/test_coverage/IO/RDGFLOMeshReader.cpp.func-sort-c.html +++ b/Debug/test_coverage/IO/RDGFLOMeshReader.cpp.func-sort-c.html @@ -33,7 +33,7 @@ - + diff --git a/Debug/test_coverage/IO/RDGFLOMeshReader.cpp.func.html b/Debug/test_coverage/IO/RDGFLOMeshReader.cpp.func.html index 6d51bbd922e8..92bc2058aab5 100644 --- a/Debug/test_coverage/IO/RDGFLOMeshReader.cpp.func.html +++ b/Debug/test_coverage/IO/RDGFLOMeshReader.cpp.func.html @@ -33,7 +33,7 @@ - + diff --git a/Debug/test_coverage/IO/RDGFLOMeshReader.cpp.gcov.html b/Debug/test_coverage/IO/RDGFLOMeshReader.cpp.gcov.html index 1957b818a4c1..7c6501777162 100644 --- a/Debug/test_coverage/IO/RDGFLOMeshReader.cpp.gcov.html +++ b/Debug/test_coverage/IO/RDGFLOMeshReader.cpp.gcov.html @@ -33,7 +33,7 @@ - + diff --git a/Debug/test_coverage/IO/RDGFLOMeshReader.hpp.func-sort-c.html b/Debug/test_coverage/IO/RDGFLOMeshReader.hpp.func-sort-c.html index 6b50de75debd..0f58c7ba8d2f 100644 --- a/Debug/test_coverage/IO/RDGFLOMeshReader.hpp.func-sort-c.html +++ b/Debug/test_coverage/IO/RDGFLOMeshReader.hpp.func-sort-c.html @@ -33,7 +33,7 @@ - + diff --git a/Debug/test_coverage/IO/RDGFLOMeshReader.hpp.func.html b/Debug/test_coverage/IO/RDGFLOMeshReader.hpp.func.html index daaca5534032..c513ffbc4915 100644 --- a/Debug/test_coverage/IO/RDGFLOMeshReader.hpp.func.html +++ b/Debug/test_coverage/IO/RDGFLOMeshReader.hpp.func.html @@ -33,7 +33,7 @@ - + diff --git a/Debug/test_coverage/IO/RDGFLOMeshReader.hpp.gcov.html b/Debug/test_coverage/IO/RDGFLOMeshReader.hpp.gcov.html index 195d1a7b7149..bca09ac589a0 100644 --- a/Debug/test_coverage/IO/RDGFLOMeshReader.hpp.gcov.html +++ b/Debug/test_coverage/IO/RDGFLOMeshReader.hpp.gcov.html @@ -33,7 +33,7 @@ - + diff --git a/Debug/test_coverage/IO/STLTxtMeshReader.cpp.func-sort-c.html b/Debug/test_coverage/IO/STLTxtMeshReader.cpp.func-sort-c.html index 1a1b0ca184a7..3b4b8cea91fd 100644 --- a/Debug/test_coverage/IO/STLTxtMeshReader.cpp.func-sort-c.html +++ b/Debug/test_coverage/IO/STLTxtMeshReader.cpp.func-sort-c.html @@ -33,7 +33,7 @@ - + diff --git a/Debug/test_coverage/IO/STLTxtMeshReader.cpp.func.html b/Debug/test_coverage/IO/STLTxtMeshReader.cpp.func.html index 3f2afb2623eb..777642b0f061 100644 --- a/Debug/test_coverage/IO/STLTxtMeshReader.cpp.func.html +++ b/Debug/test_coverage/IO/STLTxtMeshReader.cpp.func.html @@ -33,7 +33,7 @@ - + diff --git a/Debug/test_coverage/IO/STLTxtMeshReader.cpp.gcov.html b/Debug/test_coverage/IO/STLTxtMeshReader.cpp.gcov.html index 3eac9233a2ae..bbc2d17720fd 100644 --- a/Debug/test_coverage/IO/STLTxtMeshReader.cpp.gcov.html +++ b/Debug/test_coverage/IO/STLTxtMeshReader.cpp.gcov.html @@ -33,7 +33,7 @@ - + diff --git a/Debug/test_coverage/IO/STLTxtMeshReader.hpp.func-sort-c.html b/Debug/test_coverage/IO/STLTxtMeshReader.hpp.func-sort-c.html index fc9b6d5a7d2a..919154b3e541 100644 --- a/Debug/test_coverage/IO/STLTxtMeshReader.hpp.func-sort-c.html +++ b/Debug/test_coverage/IO/STLTxtMeshReader.hpp.func-sort-c.html @@ -33,7 +33,7 @@ - + diff --git a/Debug/test_coverage/IO/STLTxtMeshReader.hpp.func.html b/Debug/test_coverage/IO/STLTxtMeshReader.hpp.func.html index bc1b4321e643..b1bcdcdfedba 100644 --- a/Debug/test_coverage/IO/STLTxtMeshReader.hpp.func.html +++ b/Debug/test_coverage/IO/STLTxtMeshReader.hpp.func.html @@ -33,7 +33,7 @@ - + diff --git a/Debug/test_coverage/IO/STLTxtMeshReader.hpp.gcov.html b/Debug/test_coverage/IO/STLTxtMeshReader.hpp.gcov.html index 57d09ea06624..a66a5f5b6c49 100644 --- a/Debug/test_coverage/IO/STLTxtMeshReader.hpp.gcov.html +++ b/Debug/test_coverage/IO/STLTxtMeshReader.hpp.gcov.html @@ -33,7 +33,7 @@ - + diff --git a/Debug/test_coverage/IO/TxtStatWriter.cpp.func-sort-c.html b/Debug/test_coverage/IO/TxtStatWriter.cpp.func-sort-c.html index d4f1dbb27a02..780966a51b31 100644 --- a/Debug/test_coverage/IO/TxtStatWriter.cpp.func-sort-c.html +++ b/Debug/test_coverage/IO/TxtStatWriter.cpp.func-sort-c.html @@ -33,7 +33,7 @@ - + diff --git a/Debug/test_coverage/IO/TxtStatWriter.cpp.func.html b/Debug/test_coverage/IO/TxtStatWriter.cpp.func.html index e99aab77fda6..ad929ad9050c 100644 --- a/Debug/test_coverage/IO/TxtStatWriter.cpp.func.html +++ b/Debug/test_coverage/IO/TxtStatWriter.cpp.func.html @@ -33,7 +33,7 @@ - + diff --git a/Debug/test_coverage/IO/TxtStatWriter.cpp.gcov.html b/Debug/test_coverage/IO/TxtStatWriter.cpp.gcov.html index ca2af854944a..3a241717b4c3 100644 --- a/Debug/test_coverage/IO/TxtStatWriter.cpp.gcov.html +++ b/Debug/test_coverage/IO/TxtStatWriter.cpp.gcov.html @@ -33,7 +33,7 @@ - + diff --git a/Debug/test_coverage/IO/UGRIDMeshReader.cpp.func-sort-c.html b/Debug/test_coverage/IO/UGRIDMeshReader.cpp.func-sort-c.html index d23e57fbbabb..326f75271056 100644 --- a/Debug/test_coverage/IO/UGRIDMeshReader.cpp.func-sort-c.html +++ b/Debug/test_coverage/IO/UGRIDMeshReader.cpp.func-sort-c.html @@ -33,7 +33,7 @@ - + diff --git a/Debug/test_coverage/IO/UGRIDMeshReader.cpp.func.html b/Debug/test_coverage/IO/UGRIDMeshReader.cpp.func.html index fa94ec511ec0..80b2e0e30350 100644 --- a/Debug/test_coverage/IO/UGRIDMeshReader.cpp.func.html +++ b/Debug/test_coverage/IO/UGRIDMeshReader.cpp.func.html @@ -33,7 +33,7 @@ - + diff --git a/Debug/test_coverage/IO/UGRIDMeshReader.cpp.gcov.html b/Debug/test_coverage/IO/UGRIDMeshReader.cpp.gcov.html index 1874dcb8dbe1..a23ac9414fce 100644 --- a/Debug/test_coverage/IO/UGRIDMeshReader.cpp.gcov.html +++ b/Debug/test_coverage/IO/UGRIDMeshReader.cpp.gcov.html @@ -33,7 +33,7 @@ - + diff --git a/Debug/test_coverage/IO/UGRIDMeshReader.hpp.func-sort-c.html b/Debug/test_coverage/IO/UGRIDMeshReader.hpp.func-sort-c.html index 93cbf7149461..0e9ad8121767 100644 --- a/Debug/test_coverage/IO/UGRIDMeshReader.hpp.func-sort-c.html +++ b/Debug/test_coverage/IO/UGRIDMeshReader.hpp.func-sort-c.html @@ -33,7 +33,7 @@ - + diff --git a/Debug/test_coverage/IO/UGRIDMeshReader.hpp.func.html b/Debug/test_coverage/IO/UGRIDMeshReader.hpp.func.html index 4f1e66a13311..99a4c00b6ad0 100644 --- a/Debug/test_coverage/IO/UGRIDMeshReader.hpp.func.html +++ b/Debug/test_coverage/IO/UGRIDMeshReader.hpp.func.html @@ -33,7 +33,7 @@ - + diff --git a/Debug/test_coverage/IO/UGRIDMeshReader.hpp.gcov.html b/Debug/test_coverage/IO/UGRIDMeshReader.hpp.gcov.html index 94a7bf11fa5f..712a34ee60bf 100644 --- a/Debug/test_coverage/IO/UGRIDMeshReader.hpp.gcov.html +++ b/Debug/test_coverage/IO/UGRIDMeshReader.hpp.gcov.html @@ -33,7 +33,7 @@ - + diff --git a/Debug/test_coverage/IO/index-sort-b.html b/Debug/test_coverage/IO/index-sort-b.html index 133bb40c790c..f7d94b7dc809 100644 --- a/Debug/test_coverage/IO/index-sort-b.html +++ b/Debug/test_coverage/IO/index-sort-b.html @@ -33,7 +33,7 @@ - + @@ -94,24 +94,24 @@ - + - + - + - + @@ -358,14 +358,14 @@ - + - + - + @@ -382,7 +382,7 @@ - + @@ -394,7 +394,7 @@ - + @@ -406,19 +406,19 @@ - + - - + + - + @@ -430,26 +430,26 @@ - + - - + + - + - + - + diff --git a/Debug/test_coverage/IO/index-sort-f.html b/Debug/test_coverage/IO/index-sort-f.html index 75b8b8688cd6..24e6e2cbcdff 100644 --- a/Debug/test_coverage/IO/index-sort-f.html +++ b/Debug/test_coverage/IO/index-sort-f.html @@ -33,7 +33,7 @@ - + @@ -94,24 +94,24 @@ - + - + - + - + @@ -202,7 +202,7 @@ - + @@ -214,7 +214,7 @@ - + @@ -238,7 +238,7 @@ - + @@ -250,7 +250,7 @@ - + @@ -274,16 +274,16 @@ - + - - + + - - + + @@ -310,28 +310,40 @@ - + - + - + + + + + + + + + + + - + - - - + + + @@ -346,40 +358,40 @@ - + - + - - + + - + - + - - + + - + - + - - - + + + @@ -418,16 +430,16 @@ - + - + - - - + + + @@ -441,18 +453,6 @@ - - - - - - - - - -
  1
-  2
-  3
-  4
-  5
-  6
-  7
-  8
-  9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
- 37
- 38
- 39
- 40
- 41
- 42
- 43
- 44
- 45
- 46
- 47
- 48
- 49
- 50
- 51
- 52
- 53
- 54
- 55
- 56
- 57
- 58
- 59
- 60
- 61
- 62
- 63
- 64
- 65
- 66
- 67
- 68
- 69
- 70
- 71
- 72
- 73
- 74
- 75
- 76
- 77
- 78
- 79
- 80
- 81
- 82
- 83
- 84
- 85
- 86
- 87
- 88
- 89
- 90
- 91
- 92
- 93
- 94
- 95
- 96
- 97
- 98
- 99
-100
-101
-102
-103
-104
-105
-106
-107
-108
-109
-110
-111
-112
-113
-114
-115
-116
-117
-118
-119
-120
-121
-122
-123
-124
-125
-126
-127
-128
-129
-130
-131
-132
-133
-134
-135
-136
-137
-138
-139
-140
-141
-142
-143
-144
-145
-146
-147
-148
-149
-150
-151
-152
-153
-154
-155
-156
-157
-158
-159
-160
-161
-162
-163
-164
-165
-166
-167
-168
-169
-170
-171
-172
-173
-174
-175
-176
-177
-178
-179
-180
-181
-182
-183
-184
-185
-186
-187
-188
-189
-190
-191
-192
-193
-194
-195
-196
-197
-198
-199
-200
-201
-202
-203
-204
-205
-206
-207
-208
-209
-210
-211
-212
-213
-214
-215
-216
-217
-218
-219
-220
-221
-222
-223
-224
-225
-226
-227
-228
-229
-230
-231
-232
-233
-234
-235
-236
-237
-238
-239
-240
-241
-242
-243
-244
-245
-246
-247
-248
-249
-250
-251
-252
-253
-254
-255
-256
-257
-258
-259
-260
-261
-262
-263
-264
-265
-266
-267
-268
-269
-270
-271
-272
-273
-274
-275
-276
-277
-278
-279
-280
-281
-282
-283
-284
-285
-286
-287
-288
-289
-290
-291
-292
-293
-294
-295
-296
-297
-298
-299
-300
-301
-302
-303
-304
-305
-306
-307
-308
-309
-310
-311
-312
-313
-314
-315
-316
-317
-318
-319
-320
-321
-322
-323
-324
-325
-326
-327
-328
-329
-330
-331
-332
-333
-334
-335
-336
-337
-338
-339
-340
-341
-342
-343
-344
-345
-346
-347
-348
-349
-350
-351
-352
-353
-354
-355
-356
-357
-358
-359
-360
-361
-362
-363
-364
-365
-366
-367
-368
-369
-370
-371
-372
-373
-374
-375
-376
-377
-378
-379
-380
-381
-382
-383
-384
-385
-386
-387
-388
-389
-390
-391
-392
-393
-394
-395
-396
-397
-398
-399
-400
-401
-402
-403
-404
-405
-406
-407
-408
-409
-410
-411
-412
-413
-414
-415
-416
-417
-418
-419
-420
-421
-422
-423
-424
-425
-426
-427
-428
-429
-430
-431
-432
-433
-434
-435
-436
-437
-438
-439
-440
-441
-442
-443
-444
-445
-446
-447
-448
-449
-450
-451
-452
-453
-454
-455
-456
-457
-458
-459
-460
-461
-462
-463
-464
-465
-466
-467
-468
-469
-470
-471
-472
-473
-474
-475
-476
-477
-478
-479
-480
-481
-482
-483
-484
-485
-486
-487
-488
-489
-490
-491
-492
-493
-494
-495
-496
-497
-498
-499
-500
-501
-502
-503
-504
-505
-506
-507
-508
-509
-510
-511
-512
-513
-514
-515
-516
-517
-518
-519
-520
-521
-522
-523
-524
-525
-526
-527
-528
-529
-530
-531
-532
-533
-534
-535
-536
-537
-538
-539
-540
-541
-542
-543
-544
-545
-546
-547
-548
-549
-550
-551
-552
-553
-554
-555
-556
-557
-558
-559
-560
-561
-562
-563
-564
-565
-566
-567
-568
-569
-570
-571
-572
-573
-574
-575
-576
-577
-578
-579
-580
-581
-582
-583
-584
-585
-586
-587
-588
-589
-590
-591
-592
-593
-594
-595
-596
-597
-598
-599
-600
-601
-602
-603
-604
-605
-606
-607
-608
-609
-610
-611
-612
-613
-614
-615
-616
-617
-618
-619
-620
-621
-622
-623
-624
-625
-626
-627
-628
-629
-630
-631
-632
-633
-634
-635
-636
-637
-638
-639
-640
-641
-642
-643
-644
-645
-646
-647
-648
-649
-650
-651
-652
-653
-654
-655
-656
-657
-658
-659
-660
-661
-662
-663
-664
-665
-666
-667
-668
-669
-670
-671
-672
-673
-674
-675
-676
-677
-678
-679
-680
-681
-682
-683
-684
-685
-686
-687
-688
-689
-690
-691
-692
-693
-694
-695
-696
-697
-698
-699
-700
-701
-702
-703
-704
-705
-706
-707
-708
-709
-710
-711
-712
-713
-714
-715
-716
-717
-718
-719
-720
-721
-722
-723
-724
-725
-726
-727
-728
-729
-730
-731
-732
-733
-734
-735
-736
-737
-738
-739
-740
-741
-742
-743
-744
-745
-746
-747
-748
-749
-750
-751
-752
-753
-754
-755
-756
-757
-758
-759
-760
-761
-762
-763
-764
-765
-766
-767
-768
-769
-770
-771
-772
-773
-774
-775
-776
-777
-778
-779
-780
-781
-782
-783
-784
-785
-786
-787
-788
-789
-790
-791
-792
-793
-794
-795
-796
-797
-798
// *****************************************************************************
+
   1
+   2
+   3
+   4
+   5
+   6
+   7
+   8
+   9
+  10
+  11
+  12
+  13
+  14
+  15
+  16
+  17
+  18
+  19
+  20
+  21
+  22
+  23
+  24
+  25
+  26
+  27
+  28
+  29
+  30
+  31
+  32
+  33
+  34
+  35
+  36
+  37
+  38
+  39
+  40
+  41
+  42
+  43
+  44
+  45
+  46
+  47
+  48
+  49
+  50
+  51
+  52
+  53
+  54
+  55
+  56
+  57
+  58
+  59
+  60
+  61
+  62
+  63
+  64
+  65
+  66
+  67
+  68
+  69
+  70
+  71
+  72
+  73
+  74
+  75
+  76
+  77
+  78
+  79
+  80
+  81
+  82
+  83
+  84
+  85
+  86
+  87
+  88
+  89
+  90
+  91
+  92
+  93
+  94
+  95
+  96
+  97
+  98
+  99
+ 100
+ 101
+ 102
+ 103
+ 104
+ 105
+ 106
+ 107
+ 108
+ 109
+ 110
+ 111
+ 112
+ 113
+ 114
+ 115
+ 116
+ 117
+ 118
+ 119
+ 120
+ 121
+ 122
+ 123
+ 124
+ 125
+ 126
+ 127
+ 128
+ 129
+ 130
+ 131
+ 132
+ 133
+ 134
+ 135
+ 136
+ 137
+ 138
+ 139
+ 140
+ 141
+ 142
+ 143
+ 144
+ 145
+ 146
+ 147
+ 148
+ 149
+ 150
+ 151
+ 152
+ 153
+ 154
+ 155
+ 156
+ 157
+ 158
+ 159
+ 160
+ 161
+ 162
+ 163
+ 164
+ 165
+ 166
+ 167
+ 168
+ 169
+ 170
+ 171
+ 172
+ 173
+ 174
+ 175
+ 176
+ 177
+ 178
+ 179
+ 180
+ 181
+ 182
+ 183
+ 184
+ 185
+ 186
+ 187
+ 188
+ 189
+ 190
+ 191
+ 192
+ 193
+ 194
+ 195
+ 196
+ 197
+ 198
+ 199
+ 200
+ 201
+ 202
+ 203
+ 204
+ 205
+ 206
+ 207
+ 208
+ 209
+ 210
+ 211
+ 212
+ 213
+ 214
+ 215
+ 216
+ 217
+ 218
+ 219
+ 220
+ 221
+ 222
+ 223
+ 224
+ 225
+ 226
+ 227
+ 228
+ 229
+ 230
+ 231
+ 232
+ 233
+ 234
+ 235
+ 236
+ 237
+ 238
+ 239
+ 240
+ 241
+ 242
+ 243
+ 244
+ 245
+ 246
+ 247
+ 248
+ 249
+ 250
+ 251
+ 252
+ 253
+ 254
+ 255
+ 256
+ 257
+ 258
+ 259
+ 260
+ 261
+ 262
+ 263
+ 264
+ 265
+ 266
+ 267
+ 268
+ 269
+ 270
+ 271
+ 272
+ 273
+ 274
+ 275
+ 276
+ 277
+ 278
+ 279
+ 280
+ 281
+ 282
+ 283
+ 284
+ 285
+ 286
+ 287
+ 288
+ 289
+ 290
+ 291
+ 292
+ 293
+ 294
+ 295
+ 296
+ 297
+ 298
+ 299
+ 300
+ 301
+ 302
+ 303
+ 304
+ 305
+ 306
+ 307
+ 308
+ 309
+ 310
+ 311
+ 312
+ 313
+ 314
+ 315
+ 316
+ 317
+ 318
+ 319
+ 320
+ 321
+ 322
+ 323
+ 324
+ 325
+ 326
+ 327
+ 328
+ 329
+ 330
+ 331
+ 332
+ 333
+ 334
+ 335
+ 336
+ 337
+ 338
+ 339
+ 340
+ 341
+ 342
+ 343
+ 344
+ 345
+ 346
+ 347
+ 348
+ 349
+ 350
+ 351
+ 352
+ 353
+ 354
+ 355
+ 356
+ 357
+ 358
+ 359
+ 360
+ 361
+ 362
+ 363
+ 364
+ 365
+ 366
+ 367
+ 368
+ 369
+ 370
+ 371
+ 372
+ 373
+ 374
+ 375
+ 376
+ 377
+ 378
+ 379
+ 380
+ 381
+ 382
+ 383
+ 384
+ 385
+ 386
+ 387
+ 388
+ 389
+ 390
+ 391
+ 392
+ 393
+ 394
+ 395
+ 396
+ 397
+ 398
+ 399
+ 400
+ 401
+ 402
+ 403
+ 404
+ 405
+ 406
+ 407
+ 408
+ 409
+ 410
+ 411
+ 412
+ 413
+ 414
+ 415
+ 416
+ 417
+ 418
+ 419
+ 420
+ 421
+ 422
+ 423
+ 424
+ 425
+ 426
+ 427
+ 428
+ 429
+ 430
+ 431
+ 432
+ 433
+ 434
+ 435
+ 436
+ 437
+ 438
+ 439
+ 440
+ 441
+ 442
+ 443
+ 444
+ 445
+ 446
+ 447
+ 448
+ 449
+ 450
+ 451
+ 452
+ 453
+ 454
+ 455
+ 456
+ 457
+ 458
+ 459
+ 460
+ 461
+ 462
+ 463
+ 464
+ 465
+ 466
+ 467
+ 468
+ 469
+ 470
+ 471
+ 472
+ 473
+ 474
+ 475
+ 476
+ 477
+ 478
+ 479
+ 480
+ 481
+ 482
+ 483
+ 484
+ 485
+ 486
+ 487
+ 488
+ 489
+ 490
+ 491
+ 492
+ 493
+ 494
+ 495
+ 496
+ 497
+ 498
+ 499
+ 500
+ 501
+ 502
+ 503
+ 504
+ 505
+ 506
+ 507
+ 508
+ 509
+ 510
+ 511
+ 512
+ 513
+ 514
+ 515
+ 516
+ 517
+ 518
+ 519
+ 520
+ 521
+ 522
+ 523
+ 524
+ 525
+ 526
+ 527
+ 528
+ 529
+ 530
+ 531
+ 532
+ 533
+ 534
+ 535
+ 536
+ 537
+ 538
+ 539
+ 540
+ 541
+ 542
+ 543
+ 544
+ 545
+ 546
+ 547
+ 548
+ 549
+ 550
+ 551
+ 552
+ 553
+ 554
+ 555
+ 556
+ 557
+ 558
+ 559
+ 560
+ 561
+ 562
+ 563
+ 564
+ 565
+ 566
+ 567
+ 568
+ 569
+ 570
+ 571
+ 572
+ 573
+ 574
+ 575
+ 576
+ 577
+ 578
+ 579
+ 580
+ 581
+ 582
+ 583
+ 584
+ 585
+ 586
+ 587
+ 588
+ 589
+ 590
+ 591
+ 592
+ 593
+ 594
+ 595
+ 596
+ 597
+ 598
+ 599
+ 600
+ 601
+ 602
+ 603
+ 604
+ 605
+ 606
+ 607
+ 608
+ 609
+ 610
+ 611
+ 612
+ 613
+ 614
+ 615
+ 616
+ 617
+ 618
+ 619
+ 620
+ 621
+ 622
+ 623
+ 624
+ 625
+ 626
+ 627
+ 628
+ 629
+ 630
+ 631
+ 632
+ 633
+ 634
+ 635
+ 636
+ 637
+ 638
+ 639
+ 640
+ 641
+ 642
+ 643
+ 644
+ 645
+ 646
+ 647
+ 648
+ 649
+ 650
+ 651
+ 652
+ 653
+ 654
+ 655
+ 656
+ 657
+ 658
+ 659
+ 660
+ 661
+ 662
+ 663
+ 664
+ 665
+ 666
+ 667
+ 668
+ 669
+ 670
+ 671
+ 672
+ 673
+ 674
+ 675
+ 676
+ 677
+ 678
+ 679
+ 680
+ 681
+ 682
+ 683
+ 684
+ 685
+ 686
+ 687
+ 688
+ 689
+ 690
+ 691
+ 692
+ 693
+ 694
+ 695
+ 696
+ 697
+ 698
+ 699
+ 700
+ 701
+ 702
+ 703
+ 704
+ 705
+ 706
+ 707
+ 708
+ 709
+ 710
+ 711
+ 712
+ 713
+ 714
+ 715
+ 716
+ 717
+ 718
+ 719
+ 720
+ 721
+ 722
+ 723
+ 724
+ 725
+ 726
+ 727
+ 728
+ 729
+ 730
+ 731
+ 732
+ 733
+ 734
+ 735
+ 736
+ 737
+ 738
+ 739
+ 740
+ 741
+ 742
+ 743
+ 744
+ 745
+ 746
+ 747
+ 748
+ 749
+ 750
+ 751
+ 752
+ 753
+ 754
+ 755
+ 756
+ 757
+ 758
+ 759
+ 760
+ 761
+ 762
+ 763
+ 764
+ 765
+ 766
+ 767
+ 768
+ 769
+ 770
+ 771
+ 772
+ 773
+ 774
+ 775
+ 776
+ 777
+ 778
+ 779
+ 780
+ 781
+ 782
+ 783
+ 784
+ 785
+ 786
+ 787
+ 788
+ 789
+ 790
+ 791
+ 792
+ 793
+ 794
+ 795
+ 796
+ 797
+ 798
+ 799
+ 800
+ 801
+ 802
+ 803
+ 804
+ 805
+ 806
+ 807
+ 808
+ 809
+ 810
+ 811
+ 812
+ 813
+ 814
+ 815
+ 816
+ 817
+ 818
+ 819
+ 820
+ 821
+ 822
+ 823
+ 824
+ 825
+ 826
+ 827
+ 828
+ 829
+ 830
+ 831
+ 832
+ 833
+ 834
+ 835
+ 836
+ 837
+ 838
+ 839
+ 840
+ 841
+ 842
+ 843
+ 844
+ 845
+ 846
+ 847
+ 848
+ 849
+ 850
+ 851
+ 852
+ 853
+ 854
+ 855
+ 856
+ 857
+ 858
+ 859
+ 860
+ 861
+ 862
+ 863
+ 864
+ 865
+ 866
+ 867
+ 868
+ 869
+ 870
+ 871
+ 872
+ 873
+ 874
+ 875
+ 876
+ 877
+ 878
+ 879
+ 880
+ 881
+ 882
+ 883
+ 884
+ 885
+ 886
+ 887
+ 888
+ 889
+ 890
+ 891
+ 892
+ 893
+ 894
+ 895
+ 896
+ 897
+ 898
+ 899
+ 900
+ 901
+ 902
+ 903
+ 904
+ 905
+ 906
+ 907
+ 908
+ 909
+ 910
+ 911
+ 912
+ 913
+ 914
+ 915
+ 916
+ 917
+ 918
+ 919
+ 920
+ 921
+ 922
+ 923
+ 924
+ 925
+ 926
+ 927
+ 928
+ 929
+ 930
+ 931
+ 932
+ 933
+ 934
+ 935
+ 936
+ 937
+ 938
+ 939
+ 940
+ 941
+ 942
+ 943
+ 944
+ 945
+ 946
+ 947
+ 948
+ 949
+ 950
+ 951
+ 952
+ 953
+ 954
+ 955
+ 956
+ 957
+ 958
+ 959
+ 960
+ 961
+ 962
+ 963
+ 964
+ 965
+ 966
+ 967
+ 968
+ 969
+ 970
+ 971
+ 972
+ 973
+ 974
+ 975
+ 976
+ 977
+ 978
+ 979
+ 980
+ 981
+ 982
+ 983
+ 984
+ 985
+ 986
+ 987
+ 988
+ 989
+ 990
+ 991
+ 992
+ 993
+ 994
+ 995
+ 996
+ 997
+ 998
+ 999
+1000
+1001
+1002
+1003
+1004
+1005
+1006
+1007
+1008
+1009
+1010
+1011
+1012
+1013
+1014
+1015
+1016
+1017
+1018
+1019
+1020
+1021
+1022
+1023
+1024
+1025
+1026
+1027
+1028
+1029
+1030
+1031
+1032
+1033
+1034
+1035
+1036
+1037
+1038
+1039
+1040
+1041
+1042
+1043
+1044
+1045
+1046
+1047
+1048
+1049
+1050
+1051
+1052
+1053
+1054
+1055
+1056
+1057
+1058
+1059
+1060
+1061
+1062
+1063
+1064
+1065
+1066
+1067
+1068
+1069
+1070
+1071
+1072
+1073
+1074
+1075
+1076
+1077
+1078
+1079
+1080
+1081
+1082
+1083
+1084
+1085
+1086
+1087
+1088
+1089
+1090
+1091
+1092
+1093
+1094
+1095
+1096
+1097
+1098
+1099
+1100
+1101
+1102
+1103
+1104
+1105
+1106
+1107
+1108
+1109
+1110
+1111
+1112
+1113
+1114
+1115
+1116
+1117
+1118
+1119
+1120
+1121
+1122
+1123
+1124
+1125
+1126
+1127
+1128
+1129
+1130
+1131
+1132
+1133
+1134
+1135
+1136
+1137
+1138
+1139
+1140
+1141
+1142
+1143
+1144
+1145
+1146
+1147
+1148
+1149
+1150
+1151
+1152
+1153
+1154
+1155
+1156
+1157
+1158
+1159
+1160
+1161
+1162
+1163
+1164
+1165
+1166
+1167
+1168
+1169
+1170
+1171
+1172
+1173
+1174
+1175
+1176
+1177
+1178
+1179
+1180
+1181
+1182
+1183
+1184
+1185
+1186
+1187
+1188
+1189
+1190
+1191
+1192
+1193
+1194
+1195
+1196
+1197
+1198
+1199
+1200
+1201
+1202
+1203
+1204
+1205
+1206
+1207
+1208
+1209
+1210
+1211
+1212
+1213
+1214
+1215
+1216
+1217
+1218
+1219
+1220
+1221
+1222
+1223
+1224
+1225
+1226
+1227
+1228
+1229
+1230
+1231
+1232
+1233
+1234
+1235
+1236
+1237
+1238
+1239
+1240
+1241
+1242
+1243
+1244
+1245
+1246
+1247
+1248
+1249
+1250
+1251
+1252
+1253
+1254
+1255
+1256
+1257
+1258
+1259
+1260
+1261
+1262
+1263
+1264
+1265
+1266
+1267
+1268
+1269
+1270
+1271
+1272
+1273
+1274
+1275
+1276
+1277
+1278
+1279
+1280
+1281
+1282
+1283
+1284
+1285
+1286
+1287
+1288
+1289
+1290
+1291
+1292
// *****************************************************************************
 /*!
-  \file      src/PDE/Transport/CGTransport.hpp
+  \file      src/PDE/CompFlow/DGCompFlow.hpp
   \copyright 2012-2015 J. Bakosi,
              2016-2018 Los Alamos National Security, LLC.,
              2019-2021 Triad National Security, LLC.
              All rights reserved. See the LICENSE file for details.
-  \brief     Scalar transport using continous Galerkin discretization
-  \details   This file implements the physics operators governing transported
-     scalars using continuous Galerkin discretization.
-*/
-// *****************************************************************************
-#ifndef CGTransport_h
-#define CGTransport_h
-
-#include <vector>
-#include <array>
-#include <limits>
-#include <cmath>
+  \brief     Compressible single-material flow using discontinuous Galerkin
+     finite elements
+  \details   This file implements calls to the physics operators governing
+    compressible single-material flow using discontinuous Galerkin
+    discretizations.
+*/
+// *****************************************************************************
+#ifndef DGCompFlow_h
+#define DGCompFlow_h
+
+#include <cmath>
+#include <algorithm>
 #include <unordered_set>
-#include <unordered_map>
+#include <map>
 
-#include "Exception.hpp"
-#include "Vector.hpp"
-#include "DerivedData.hpp"
-#include "Around.hpp"
-#include "Reconstruction.hpp"
-#include "Inciter/InputDeck/InputDeck.hpp"
-#include "CGPDE.hpp"
-#include "History.hpp"
-
-namespace inciter {
-
-extern ctr::InputDeck g_inputdeck;
-
-namespace cg {
-
-//! \brief Transport equation used polymorphically with tk::CGPDE
-//! \details The template argument(s) specify policies and are used to configure
-//!   the behavior of the class. The policies are:
-//!   - Physics - physics configuration, see PDE/Transport/Physics/CG.h
-//!   - Problem - problem configuration, see PDE/Transport/Problem.h
-//! \note The default physics is CGAdvection, set in
-//!    inciter::deck::check_transport()
-template< class Physics, class Problem >
-class Transport {
-
-  private:
-    using ncomp_t = tk::ncomp_t;
-    using real = tk::real;
-    using eq = tag::transport;
-
-    static constexpr real muscl_eps = 1.0e-9;
-    static constexpr real muscl_const = 1.0/3.0;
-    static constexpr real muscl_m1 = 1.0 - muscl_const;
-    static constexpr real muscl_p1 = 1.0 + muscl_const;
-
-  public:
-    //! Constructor
-    explicit Transport() :
-      m_physics( Physics() ),
-      m_problem( Problem() ),
-      m_ncomp(g_inputdeck.get< tag::ncomp >())
-    {
-      m_problem.errchk( m_ncomp );
-    }
-
-    //! Determine nodes that lie inside the user-defined IC box
-    void
-    IcBoxNodes( const tk::UnsMesh::Coords&,
-                const std::vector< std::size_t >&,
-                const std::unordered_map< std::size_t, std::set< std::size_t > >&,
-                std::vector< std::unordered_set< std::size_t > >&,
-                std::unordered_map< std::size_t, std::set< std::size_t > >&,
-                std::size_t& ) const {}
-
-    //! Initalize the transport equations using problem policy
-    //! \param[in] coord Mesh node coordinates
-    //! \param[in,out] unk Array of unknowns
-    //! \param[in] t Physical time
-    void
-    initialize( const std::array< std::vector< real >, 3 >& coord,
-                tk::Fields& unk,
-                real t,
-                real,
-                const std::vector< std::unordered_set< std::size_t > >&,
-                const std::vector< tk::real >&,
-                const std::unordered_map< std::size_t, std::set< std::size_t > >&
-              ) const
-    {
-      Assert( coord[0].size() == unk.nunk(), "Size mismatch" );
-      const auto& x = coord[0];
-      const auto& y = coord[1];
-      const auto& z = coord[2];
-      for (ncomp_t i=0; i<x.size(); ++i) {
-        auto s = Problem::initialize( m_ncomp, m_mat_blk, x[i], y[i],
-                                      z[i], t );
-        for (ncomp_t c=0; c<m_ncomp; ++c)
-          unk( i, c ) = s[c];
-      }
-    }
-
-    //! Query a velocity
-    //! \note Since this function does not touch its output argument, that
-    //!   means this system does not define a "velocity".
-    void velocity( const tk::Fields&, tk::UnsMesh::Coords& ) const {}
-
-    //! Query the sound speed
-    //! \note Since this function does not touch its output argument, that
-    //!   means this system does not define a "sound speed".
-    void soundspeed( const tk::Fields&, std::vector< tk::real >& ) const {}
-
-    //! Return analytic solution (if defined by Problem) at xi, yi, zi, t
-    //! \param[in] xi X-coordinate
-    //! \param[in] yi Y-coordinate
-    //! \param[in] zi Z-coordinate
-    //! \param[in] t Physical time
-    //! \return Vector of analytic solution at given location and time
-    std::vector< real >
-    analyticSolution( real xi, real yi, real zi, real t ) const
-    { return Problem::analyticSolution( m_ncomp, m_mat_blk, xi, yi, zi, t ); }
-
-    //! Return analytic solution for conserved variables
-    //! \param[in] xi X-coordinate at which to evaluate the analytic solution
-    //! \param[in] yi Y-coordinate at which to evaluate the analytic solution
-    //! \param[in] zi Z-coordinate at which to evaluate the analytic solution
-    //! \param[in] t Physical time at which to evaluate the analytic solution
-    //! \return Vector of analytic solution at given location and time
-    std::vector< tk::real >
-    solution( tk::real xi, tk::real yi, tk::real zi, tk::real t ) const
-    { return Problem::initialize( m_ncomp, m_mat_blk, xi, yi, zi, t ); }
-
-    //! Compute nodal gradients of primitive variables for ALECG
-    //! \param[in] coord Mesh node coordinates
-    //! \param[in] inpoel Mesh element connectivity
-    //! \param[in] bndel List of elements contributing to chare-boundary nodes
-    //! \param[in] gid Local->global node id map
-    //! \param[in] bid Local chare-boundary node ids (value) associated to
-    //!    global node ids (key)
-    //! \param[in] U Solution vector at recent time step
-    //! \param[in,out] G Nodal gradients of primitive variables
-    void chBndGrad( const std::array< std::vector< real >, 3 >& coord,
-      const std::vector< std::size_t >& inpoel,
-      const std::vector< std::size_t >& bndel,
-      const std::vector< std::size_t >& gid,
-      const std::unordered_map< std::size_t, std::size_t >& bid,
-      const tk::Fields& U,
-      tk::Fields& G ) const
-    {
-      Assert( U.nunk() == coord[0].size(), "Number of unknowns in solution "
-              "vector at recent time step incorrect" );
-
-      // compute gradients of primitive variables in points
-      G.fill( 0.0 );
-
-      // access node cooordinates
-      const auto& x = coord[0];
-      const auto& y = coord[1];
-      const auto& z = coord[2];
-
-      for (auto e : bndel) {  // elements contributing to chare boundary nodes
-        // access node IDs
-        std::size_t N[4] =
-          { inpoel[e*4+0], inpoel[e*4+1], inpoel[e*4+2], inpoel[e*4+3] };
-        // compute element Jacobi determinant, J = 6V
-        real bax = x[N[1]]-x[N[0]];
-        real bay = y[N[1]]-y[N[0]];
-        real baz = z[N[1]]-z[N[0]];
-        real cax = x[N[2]]-x[N[0]];
-        real cay = y[N[2]]-y[N[0]];
-        real caz = z[N[2]]-z[N[0]];
-        real dax = x[N[3]]-x[N[0]];
-        real day = y[N[3]]-y[N[0]];
-        real daz = z[N[3]]-z[N[0]];
-        auto J = tk::triple( bax, bay, baz, cax, cay, caz, dax, day, daz );
-        auto J24 = J/24.0;
-        // shape function derivatives, nnode*ndim [4][3]
-        real g[4][3];
-        tk::crossdiv( cax, cay, caz, dax, day, daz, J,
-                      g[1][0], g[1][1], g[1][2] );
-        tk::crossdiv( dax, day, daz, bax, bay, baz, J,
-                      g[2][0], g[2][1], g[2][2] );
-        tk::crossdiv( bax, bay, baz, cax, cay, caz, J,
-                      g[3][0], g[3][1], g[3][2] );
-        for (std::size_t i=0; i<3; ++i)
-          g[0][i] = -g[1][i] - g[2][i] - g[3][i];
-        // scatter-add gradient contributions to boundary nodes
-        for (std::size_t a=0; a<4; ++a) {
-          auto i = bid.find( gid[N[a]] );
-          if (i != end(bid))
-            for (std::size_t c=0; c<m_ncomp; ++c)
-              for (std::size_t b=0; b<4; ++b)
-                for (std::size_t j=0; j<3; ++j)
-                  G(i->second,c*3+j) += J24 * g[b][j] * U(N[b],c);
-        }
-      }
-    }
-
-    //! Compute right hand side for ALECG
-    //! \param[in] coord Mesh node coordinates
-    //! \param[in] inpoel Mesh element connectivity
-    //! \param[in] triinpoel Boundary triangle face connecitivity
-    //! \param[in] bid Local chare-boundary node ids (value) associated to
-    //!    global node ids (key)
-    //! \param[in] lid Global->local node ids
-    //! \param[in] dfn Dual-face normals
-    //! \param[in] psup Points surrounding points
-    //! \param[in] esup Elements surrounding points
-    //! \param[in] symbctri Vector with 1 at symmetry BC nodes
-    //! \param[in] vol Nodal volumes
-    //! \param[in] edgeid Local node id pair -> edge id map
-    //! \param[in] G Nodal gradients in chare-boundary nodes
-    //! \param[in] U Solution vector at recent time step
-    //! \param[in] W Mesh velocity
-    //! \param[in,out] R Right-hand side vector computed
-    void rhs(
-      real,
-      const std::array< std::vector< real >, 3 >&  coord,
-      const std::vector< std::size_t >& inpoel,
-      const std::vector< std::size_t >& triinpoel,
-      const std::vector< std::size_t >&,
-      const std::unordered_map< std::size_t, std::size_t >& bid,
-      const std::unordered_map< std::size_t, std::size_t >& lid,
-      const std::vector< real >& dfn,
-      const std::pair< std::vector< std::size_t >,
-                       std::vector< std::size_t > >& psup,
-      const std::pair< std::vector< std::size_t >,
-                       std::vector< std::size_t > >& esup,
-      const std::vector< int >& symbctri,
-      const std::vector< real >& vol,
-      const std::vector< std::size_t >&,
-      const std::vector< std::size_t >& edgeid,
-      const std::vector< std::unordered_set< std::size_t > >&,
-      const tk::Fields& G,
-      const tk::Fields& U,
-      [[maybe_unused]] const tk::Fields& W,
-      const std::vector< tk::real >&,
-      real,
-      tk::Fields& R ) const
-    {
-      Assert( G.nprop() == m_ncomp*3,
-              "Number of components in gradient vector incorrect" );
-      Assert( U.nunk() == coord[0].size(), "Number of unknowns in solution "
-              "vector at recent time step incorrect" );
-      Assert( R.nunk() == coord[0].size(),
-              "Number of unknowns and/or number of components in right-hand "
-              "side vector incorrect" );
+#include <brigand/algorithms/for_each.hpp>
+
+#include "Macro.hpp"
+#include "Exception.hpp"
+#include "Vector.hpp"
+#include "ContainerUtil.hpp"
+#include "UnsMesh.hpp"
+#include "Inciter/InputDeck/InputDeck.hpp"
+#include "Integrate/Basis.hpp"
+#include "Integrate/Quadrature.hpp"
+#include "Integrate/Initialize.hpp"
+#include "Integrate/Mass.hpp"
+#include "Integrate/Surface.hpp"
+#include "Integrate/Boundary.hpp"
+#include "Integrate/Volume.hpp"
+#include "Integrate/Source.hpp"
+#include "RiemannChoice.hpp"
+#include "EoS/EOS.hpp"
+#include "Reconstruction.hpp"
+#include "Limiter.hpp"
+#include "PrefIndicator.hpp"
+
+namespace inciter {
+
+extern ctr::InputDeck g_inputdeck;
+
+namespace dg {
+
+//! \brief CompFlow used polymorphically with tk::DGPDE
+//! \details The template arguments specify policies and are used to configure
+//!   the behavior of the class. The policies are:
+//!   - Physics - physics configuration, see PDE/CompFlow/Physics.h
+//!   - Problem - problem configuration, see PDE/CompFlow/Problem.h
+//! \note The default physics is Euler, set in inciter::deck::check_compflow()
+template< class Physics, class Problem >
+class CompFlow {
+
+  private:
+    using eq = tag::compflow;
+
+  public:
+    //! Constructor
+    explicit CompFlow() :
+      m_physics(),
+      m_problem(),
+      m_ncomp( g_inputdeck.get< tag::ncomp >() ),
+      m_riemann( compflowRiemannSolver(
+        g_inputdeck.get< tag::flux >() ) )
+    {
+      // associate boundary condition configurations with state functions, the
+      // order in which the state functions listed matters, see ctr::bc::Keys
+      brigand::for_each< ctr::bclist::Keys >( ConfigBC( m_bc,
+        { dirichlet
+        , symmetry
+        , invalidBC         // Inlet BC not implemented
+        , invalidBC         // Outlet BC not implemented
+        , farfield
+        , extrapolate } ) );
+
+      // EoS initialization
+      const auto& matprop =
+        g_inputdeck.get< tag::material >();
+      const auto& matidxmap =
+        g_inputdeck.get< tag::matidxmap >();
+      auto mateos = matprop[matidxmap.get< tag::eosidx >()[0]].get<tag::eos>();
+      m_mat_blk.emplace_back(mateos, EqType::compflow, 0);
+
+    }
+
+    //! Find the number of primitive quantities required for this PDE system
+    //! \return The number of primitive quantities required to be stored for
+    //!   this PDE system
+    std::size_t nprim() const
+    {
+      // compflow does not need/store any primitive quantities currently
+      return 0;
+    }
+
+    //! Find the number of materials set up for this PDE system
+    //! \return The number of materials set up for this PDE system
+    std::size_t nmat() const
+    {
+      // compflow does not need nmat
+      return 0;
+    }
+
+    //! Assign number of DOFs per equation in the PDE system
+    //! \param[in,out] numEqDof Array storing number of Dofs for each PDE
+    //!   equation
+    void numEquationDofs(std::vector< std::size_t >& numEqDof) const
+    {
+      // all equation-dofs initialized to ndof
+      for (std::size_t i=0; i<m_ncomp; ++i) {
+        numEqDof.push_back(g_inputdeck.get< tag::ndof >());
+      }
+    }
+
+    //! Determine elements that lie inside the user-defined IC box
+    //! \param[in] geoElem Element geometry array
+    //! \param[in] nielem Number of internal elements
+    //! \param[in,out] inbox List of nodes at which box user ICs are set for
+    //!    each IC box
+    void IcBoxElems( const tk::Fields& geoElem,
+      std::size_t nielem,
+      std::vector< std::unordered_set< std::size_t > >& inbox ) const
+    {
+      tk::BoxElems< eq >(geoElem, nielem, inbox);
+    }
+
+    //! Find how 'stiff equations', which we currently
+    //! have none for Compflow
+    //! \return number of stiff equations
+    std::size_t nstiffeq() const
+    { return 0; }
+
+    //! Find how 'nonstiff equations', which we currently
+    //! don't use for Compflow
+    //! \return number of non-stiff equations
+    std::size_t nnonstiffeq() const
+    { return 0; }
+
+    //! Locate the stiff equations. Unused for compflow.
+    //! \param[out] stiffEqIdx list
+    void setStiffEqIdx( std::vector< std::size_t >& stiffEqIdx ) const
+    {
+      stiffEqIdx.resize(0);
+    }
+
+    //! Locate the nonstiff equations. Unused for compflow.
+    //! \param[out] nonStiffEqIdx list
+    void setNonStiffEqIdx( std::vector< std::size_t >& nonStiffEqIdx ) const
+    {
+      nonStiffEqIdx.resize(0);
+    }
+
+    //! Initalize the compressible flow equations, prepare for time integration
+    //! \param[in] L Block diagonal mass matrix
+    //! \param[in] inpoel Element-node connectivity
+    //! \param[in] coord Array of nodal coordinates
+    //! \param[in] inbox List of elements at which box user ICs are set for
+    //!    each IC box
+    //! \param[in,out] unk Array of unknowns
+    //! \param[in] t Physical time
+    //! \param[in] nielem Number of internal elements
+    void
+    initialize( const tk::Fields& L,
+                const std::vector< std::size_t >& inpoel,
+                const tk::UnsMesh::Coords& coord,
+                const std::vector< std::unordered_set< std::size_t > >& inbox,
+                const std::unordered_map< std::size_t,
+                  std::set< std::size_t > >&,
+                tk::Fields& unk,
+                tk::real t,
+                const std::size_t nielem ) const
+    {
+      tk::initialize( m_ncomp, m_mat_blk, L, inpoel, coord,
+                      Problem::initialize, unk, t, nielem );
+
+      const auto rdof = g_inputdeck.get< tag::rdof >();
+      const auto& ic = g_inputdeck.get< tag::ic >();
+      const auto& icbox = ic.get< tag::box >();
+      const auto& bgpreic = ic.get< tag::pressure >();
+      auto c_v = getmatprop< tag::cv >();
+
+      // Set initial conditions inside user-defined IC box
+      std::vector< tk::real > s(m_ncomp, 0.0);
+      for (std::size_t e=0; e<nielem; ++e) {
+        if (icbox.size() > 0) {
+          std::size_t bcnt = 0;
+          for (const auto& b : icbox) {   // for all boxes
+            if (inbox.size() > bcnt && inbox[bcnt].find(e) != inbox[bcnt].end())
+            {
+              std::vector< tk::real > box
+              { b.template get< tag::xmin >(), b.template get< tag::xmax >(),
+                b.template get< tag::ymin >(), b.template get< tag::ymax >(),
+                b.template get< tag::zmin >(), b.template get< tag::zmax >() };
+              auto V_ex = (box[1]-box[0]) * (box[3]-box[2]) * (box[5]-box[4]);
+              for (std::size_t c=0; c<m_ncomp; ++c) {
+                auto mark = c*rdof;
+                s[c] = unk(e,mark);
+                // set high-order DOFs to zero
+                for (std::size_t i=1; i<rdof; ++i)
+                  unk(e,mark+i) = 0.0;
+              }
+              initializeBox<ctr::boxList>( m_mat_blk, 1.0, V_ex,
+                t, b, bgpreic, c_v, s );
+              // store box-initialization in solution vector
+              for (std::size_t c=0; c<m_ncomp; ++c) {
+                auto mark = c*rdof;
+                unk(e,mark) = s[c];
+              }
+            }
+            ++bcnt;
+          }
+        }
+      }
+    }
+
+    //! Save initial densities for all materials
+    //! \param[out] rho0mat List of initial densities
+    void setRho0mat( std::vector< tk::real >& rho0mat ) const
+    {
+      rho0mat.resize(0);
+    }
+
+    //! Compute density constraint for a given material
+    // //! \param[in] nelem Number of elements
+    // //! \param[in] unk Array of unknowns
+    // //! \param[in] rho0mat List of initial densities
+    //! \param[out] densityConstr Density Constraint: rho/(rho0*det(g))
+    void computeDensityConstr( std::size_t /*nelem*/,
+                               tk::Fields& /*unk*/,
+                               std::vector< tk::real >& /*rho0mat*/,
+                               std::vector< tk::real >& densityConstr) const
+    {
+      densityConstr.resize(0);
+    }
+
+    //! Compute the left hand side block-diagonal mass matrix
+    //! \param[in] geoElem Element geometry array
+    //! \param[in,out] l Block diagonal mass matrix
+    void lhs( const tk::Fields& geoElem, tk::Fields& l ) const {
+      const auto ndof = g_inputdeck.get< tag::ndof >();
+      tk::mass( m_ncomp, ndof, geoElem, l );
+    }
 
-      // compute/assemble gradients in points
-      auto Grad = nodegrad( coord, inpoel, lid, bid, vol, esup, U, G );
-
-      // zero right hand side for all components
-      for (ncomp_t c=0; c<m_ncomp; ++c) R.fill( c, 0.0 );
-
-      // compute domain-edge integral
-      domainint( coord, inpoel, edgeid, psup, dfn, U, Grad, R );
-
-      // compute boundary integrals
-      bndint( coord, triinpoel, symbctri, U, R );
-    }
-
-    //! Compute overset mesh motion for OversetFE (no-op for transport)
-    void getMeshVel(
-      real,
-      const std::array< std::vector< real >, 3 >&,
-      const std::pair< std::vector< std::size_t >,
-                       std::vector< std::size_t > >&,
-      const std::unordered_set< std::size_t >&,
-      const std::array< tk::real, 3 >&,
-      const tk::Fields&,
-      tk::Fields&,
-      int& ) const
-    { }
-
-    //! Compute the minimum time step size (for unsteady time stepping)
-    //! \param[in] U Solution vector at recent time step
-    //! \param[in] coord Mesh node coordinates
-    //! \param[in] inpoel Mesh element connectivity
-    //! \param[in] t Physical time
-    //! \return Minimum time step size
-    real dt( const std::array< std::vector< real >, 3 >& coord,
-             const std::vector< std::size_t >& inpoel,
-             tk::real t,
-             tk::real,
-             const tk::Fields& U,
-             const std::vector< tk::real >&,
-             const std::vector< tk::real >& ) const
-    {
-      using tag::transport;
-      Assert( U.nunk() == coord[0].size(), "Number of unknowns in solution "
-              "vector at recent time step incorrect" );
-      const auto& x = coord[0];
-      const auto& y = coord[1];
-      const auto& z = coord[2];
-      // compute the minimum dt across all elements we own
-      auto mindt = std::numeric_limits< tk::real >::max();
-      auto eps = std::numeric_limits< tk::real >::epsilon();
-      auto large = std::numeric_limits< tk::real >::max();
-      for (std::size_t e=0; e<inpoel.size()/4; ++e) {
-        const std::array< std::size_t, 4 >
-          N{{ inpoel[e*4+0], inpoel[e*4+1], inpoel[e*4+2], inpoel[e*4+3] }};
-        // compute cubic root of element volume as the characteristic length
-        const std::array< real, 3 >
-          ba{{ x[N[1]]-x[N[0]], y[N[1]]-y[N[0]], z[N[1]]-z[N[0]] }},
-          ca{{ x[N[2]]-x[N[0]], y[N[2]]-y[N[0]], z[N[2]]-z[N[0]] }},
-          da{{ x[N[3]]-x[N[0]], y[N[3]]-y[N[0]], z[N[3]]-z[N[0]] }};
-        const auto L = std::cbrt( tk::triple( ba, ca, da ) / 6.0 );
-        // access solution at element nodes at recent time step
-        std::vector< std::array< real, 4 > > u( m_ncomp );
-        for (ncomp_t c=0; c<m_ncomp; ++c) u[c] = U.extract( c, N );
-        // get velocity for problem
-        const std::array< std::vector<std::array<real,3>>, 4 > vel{{
-          Problem::prescribedVelocity( m_ncomp,
-                                       x[N[0]], y[N[0]], z[N[0]], t ),
-          Problem::prescribedVelocity( m_ncomp,
-                                       x[N[1]], y[N[1]], z[N[1]], t ),
-          Problem::prescribedVelocity( m_ncomp,
-                                       x[N[2]], y[N[2]], z[N[2]], t ),
-          Problem::prescribedVelocity( m_ncomp,
-                                       x[N[3]], y[N[3]], z[N[3]], t ) }};
-        // compute the maximum length of the characteristic velocity (advection
-        // velocity) across the four element nodes
-        real maxvel = 0.0;
-        for (ncomp_t c=0; c<m_ncomp; ++c)
-          for (std::size_t i=0; i<4; ++i) {
-            auto v = tk::length( vel[i][c] );
-            if (v > maxvel) maxvel = v;
-          }
-        // compute element dt for the advection
-        auto advection_dt = std::abs(maxvel) > eps ? L / maxvel : large;
-        // compute element dt based on diffusion
-        auto diffusion_dt = m_physics.diffusion_dt( m_ncomp, L, u );
-        // compute minimum element dt
-        auto elemdt = std::min( advection_dt, diffusion_dt );
-        // find minimum dt across all elements
-        if (elemdt < mindt) mindt = elemdt;
-      }
-      return mindt * g_inputdeck.get< tag::cfl >();
-    }
-
-    //! Compute a time step size for each mesh node (for steady time stepping)
-    void dt( uint64_t,
-             const std::vector< tk::real >&,
-             const tk::Fields&,
-             std::vector< tk::real >& ) const {}
-
-    //! \brief Query Dirichlet boundary condition value on a given side set for
-    //!    all components in this PDE system
-    //! \param[in] t Physical time
-    //! \param[in] deltat Time step size
-    //! \param[in] tp Physical time for each mesh node
-    //! \param[in] dtp Time step size for each mesh node
-    //! \param[in] ss Pair of side set ID and list of node IDs on the side set
-    //! \param[in] coord Mesh node coordinates
-    //! \param[in] increment If true, evaluate the solution increment between
-    //!   t and t+dt for Dirichlet BCs. If false, evlauate the solution instead.
-    //! \return Vector of pairs of bool and boundary condition value associated
-    //!   to mesh node IDs at which Dirichlet boundary conditions are set. Note
-    //!   that if increment is true, instead of the actual boundary condition
-    //!   value, we return the increment between t+deltat and t, since,
-    //!   depending on client code and solver, that may be what the solution
-    //!   requires.
-    std::map< std::size_t, std::vector< std::pair<bool,real> > >
-    dirbc( real t,
-           real deltat,
-           const std::vector< tk::real >& tp,
-           const std::vector< tk::real >& dtp,
-           const std::pair< const int, std::vector< std::size_t > >& ss,
-           const std::array< std::vector< real >, 3 >& coord,
-           bool increment ) const
-    {
-      using NodeBC = std::vector< std::pair< bool, real > >;
-      std::map< std::size_t, NodeBC > bc;
-      const auto& ubc = g_inputdeck.get< tag::bc >()[0].get< tag::dirichlet >();
-      const auto steady = g_inputdeck.get< tag::steady_state >();<--- Variable 'steady' is assigned a value that is never used.
-      if (!ubc.empty()) {
-        Assert( ubc.size() > 0, "Indexing out of Dirichlet BC eq-vector" );
-        const auto& x = coord[0];
-        const auto& y = coord[1];
-        const auto& z = coord[2];
-        for (const auto& b : ubc)
-          if (static_cast<int>(b) == ss.first)
-            for (auto n : ss.second) {
-              Assert( x.size() > n, "Indexing out of coordinate array" );
-              if (steady) { t = tp[n]; deltat = dtp[n]; }
-              const auto s = increment ?
-                solinc( m_ncomp, m_mat_blk, x[n], y[n], z[n],
-                        t, deltat, Problem::initialize ) :
-                Problem::initialize( m_ncomp, m_mat_blk, x[n], y[n],
-                                     z[n], t+deltat );
-              auto& nbc = bc[n] = NodeBC( m_ncomp );
-              for (ncomp_t c=0; c<m_ncomp; ++c)
-                nbc[c] = { true, s[c] };
-            }
-      }
-      return bc;
-    }
-
-    //! Set symmetry boundary conditions at nodes
-    void
-    symbc(
-      tk::Fields&,
-      const std::array< std::vector< real >, 3 >&,
-      const std::unordered_map< int,
-              std::unordered_map< std::size_t,
-                std::array< real, 4 > > >&,
-      const std::unordered_set< std::size_t >& ) const {}
-
-    //! Set farfield boundary conditions at nodes
-    void farfieldbc(
-      tk::Fields&,
-      const std::array< std::vector< real >, 3 >&,
-      const std::unordered_map< int,
-              std::unordered_map< std::size_t,
-                std::array< real, 4 > > >&,
-      const std::unordered_set< std::size_t >& ) const {}
-
-    //! Apply user defined time dependent BCs (no-op for transport)
-    void
-    timedepbc( tk::real,
-      tk::Fields&,
-      const std::vector< std::unordered_set< std::size_t > >&,
-      const std::vector< tk::Table<5> >& ) const {}
-
-    //! Return a map that associates user-specified strings to functions
-    //! \return Map that associates user-specified strings to functions that
-    //!  compute relevant quantities to be output to file
-    std::map< std::string, tk::GetVarFn > OutVarFn() const {
-      std::map< std::string, tk::GetVarFn > OutFnMap;
-      OutFnMap["material_indicator"] = transport::matIndicatorOutVar;
-
-      return OutFnMap;
-    }
-
-    //! Return analytic field names to be output to file
-    //! \return Vector of strings labelling analytic fields output in file
-    std::vector< std::string > analyticFieldNames() const {
-      std::vector< std::string > n;
-      auto depvar = g_inputdeck.get< tag::depvar >()[0];
-      for (ncomp_t c=0; c<m_ncomp; ++c)
-        n.push_back( depvar + std::to_string(c) + "_analytic" );
-      return n;
-    }
-
-    //! Return surface field names to be output to file
-    //! \return Vector of strings labelling surface fields output in file
-    //! \details This functions should be written in conjunction with
-    //!   surfOutput(), which provides the vector of surface fields to be output
-    std::vector< std::string > surfNames() const { return {}; }
-
-    //! Return nodal surface field output going to file
-    std::vector< std::vector< real > >
-    surfOutput( const std::map< int, std::vector< std::size_t > >&,
-                const tk::Fields& ) const { return {}; }
-
-    //! Return elemental surface field output (on triangle faces) going to file
-    std::vector< std::vector< real > >
-    elemSurfOutput( const std::map< int, std::vector< std::size_t > >&,
-      const std::vector< std::size_t >&,
-      const tk::Fields& ) const { return {}; }
-
-    //! Return time history field names to be output to file
-    //! \return Vector of strings labelling time history fields output in file
-    std::vector< std::string > histNames() const { return {}; }
-
-    //! Return time history field output evaluated at time history points
-    std::vector< std::vector< real > >
-    histOutput( const std::vector< HistData >&,
-                const std::vector< std::size_t >&,
-                const tk::Fields& ) const { return {}; }
+    //! Update the interface cells to first order dofs
+    //! \details This function resets the high-order terms in interface cells,
+    //!   and is currently not used in compflow.
+    void updateInterfaceCells( tk::Fields&,
+      std::size_t,
+      std::vector< std::size_t >& ) const {}
+
+    //! Update the primitives for this PDE system
+    //! \details This function computes and stores the dofs for primitive
+    //!   quantities, which is currently unused for compflow. But if a limiter
+    //!   requires primitive variables for example, this would be the place to
+    //!   add the computation of the primitive variables.
+    void updatePrimitives( const tk::Fields&,
+                           const tk::Fields&,
+                           const tk::Fields&,
+                           tk::Fields&,
+                           std::size_t ) const {}
+
+    //! Clean up the state of trace materials for this PDE system
+    //! \details This function cleans up the state of materials present in trace
+    //!   quantities in each cell. This is unused for compflow.
+    void cleanTraceMaterial( tk::real,
+                             const tk::Fields&,
+                             tk::Fields&,
+                             tk::Fields&,
+                             std::size_t ) const {}
+
+    //! Reconstruct second-order solution from first-order using least-squares
+    //! \param[in] t Physical time
+    //! \param[in] geoFace Face geometry array
+    //! \param[in] geoElem Element geometry array
+    //! \param[in] fd Face connectivity and boundary conditions object
+    //! \param[in] inpoel Element-node connectivity
+    //! \param[in] coord Array of nodal coordinates
+    //! \param[in,out] U Solution vector at recent time step
+    //! \param[in,out] P Primitive vector at recent time step
+    void reconstruct( tk::real t,
+                      const tk::Fields& geoFace,
+                      const tk::Fields& geoElem,
+                      const inciter::FaceData& fd,
+                      const std::map< std::size_t, std::vector< std::size_t > >&,
+                      const std::vector< std::size_t >& inpoel,
+                      const tk::UnsMesh::Coords& coord,
+                      tk::Fields& U,
+                      tk::Fields& P ) const
+    {
+      const auto rdof = g_inputdeck.get< tag::rdof >();
+
+      // do reconstruction only if P0P1
+      if (rdof == 4 && g_inputdeck.get< tag::ndof >() == 1) {
+        const auto nelem = fd.Esuel().size()/4;<--- Variable 'nelem' is assigned a value that is never used.
+
+        Assert( U.nprop() == rdof*5, "Number of components in solution "
+                "vector must equal "+ std::to_string(rdof*5) );
+        Assert( fd.Inpofa().size()/3 == fd.Esuf().size()/2,
+                "Mismatch in inpofa size" );
+
+        // allocate and initialize matrix and vector for reconstruction
+        std::vector< std::array< std::array< tk::real, 3 >, 3 > >
+          lhs_ls( nelem, {{ {{0.0, 0.0, 0.0}},
+                            {{0.0, 0.0, 0.0}},
+                            {{0.0, 0.0, 0.0}} }} );
+        std::vector< std::vector< std::array< tk::real, 3 > > >
+          rhs_ls( nelem, std::vector< std::array< tk::real, 3 > >
+            ( m_ncomp,
+              {{ 0.0, 0.0, 0.0 }} ) );
+
+        // reconstruct x,y,z-derivatives of unknowns
+        // 0. get lhs matrix, which is only geometry dependent
+        tk::lhsLeastSq_P0P1(fd, geoElem, geoFace, lhs_ls);
+
+        // 1. internal face contributions
+        std::vector< std::size_t > vars;
+        for (std::size_t c=0; c<m_ncomp; ++c) vars.push_back(c);
+        tk::intLeastSq_P0P1( rdof, fd, geoElem, U, rhs_ls, vars );
+
+        // 2. boundary face contributions
+        for (const auto& b : m_bc)
+          tk::bndLeastSqConservedVar_P0P1( m_ncomp,
+            m_mat_blk, rdof, b.first, fd, geoFace, geoElem, t, b.second,
+            P, U, rhs_ls, vars );
+
+        // 3. solve 3x3 least-squares system
+        tk::solveLeastSq_P0P1( rdof, lhs_ls, rhs_ls, U, vars );
+
+        // 4. transform reconstructed derivatives to Dubiner dofs
+        tk::transform_P0P1( rdof, nelem, inpoel, coord, U, vars );
+      }
+    }
+
+    //! Limit second-order solution
+    //! \param[in] t Physical time
+    //! \param[in] geoFace Face geometry array
+    //! \param[in] geoElem Element geometry array
+    //! \param[in] fd Face connectivity and boundary conditions object
+    //! \param[in] esup Elements surrounding points
+    //! \param[in] inpoel Element-node connectivity
+    //! \param[in] coord Array of nodal coordinates
+    //! \param[in] ndofel Vector of local number of degrees of freedome
+    //! \param[in] gid Local->global node id map
+    //! \param[in] bid Local chare-boundary node ids (value) associated to
+    //!   global node ids (key)
+    //! \param[in] uNodalExtrm Chare-boundary nodal extrema for conservative
+    //!   variables
+    //! \param[in] mtInv Inverse of Taylor mass matrix
+    //! \param[in,out] U Solution vector at recent time step
+    //! \param[in,out] shockmarker Vector of shock-marker values
+    void limit( [[maybe_unused]] tk::real t,
+                [[maybe_unused]] const tk::Fields& geoFace,
+                const tk::Fields& geoElem,
+                const inciter::FaceData& fd,
+                const std::map< std::size_t, std::vector< std::size_t > >& esup,
+                const std::vector< std::size_t >& inpoel,
+                const tk::UnsMesh::Coords& coord,
+                const std::vector< std::size_t >& ndofel,
+                const std::vector< std::size_t >& gid,
+                const std::unordered_map< std::size_t, std::size_t >& bid,
+                const std::vector< std::vector<tk::real> >& uNodalExtrm,
+                const std::vector< std::vector<tk::real> >&,
+                const std::vector< std::vector<tk::real> >& mtInv,
+                tk::Fields& U,
+                tk::Fields&,
+                std::vector< std::size_t >& shockmarker) const
+    {
+      const auto limiter = g_inputdeck.get< tag::limiter >();
+      const auto rdof = g_inputdeck.get< tag::rdof >();
+      const auto& solidx = g_inputdeck.get< tag::matidxmap, tag::solidx >();
+
+      if (limiter == ctr::LimiterType::WENOP1)
+        WENO_P1( fd.Esuel(), U );
+      else if (limiter == ctr::LimiterType::SUPERBEEP1)
+        Superbee_P1( fd.Esuel(), inpoel, ndofel, coord, U );
+      else if (limiter == ctr::LimiterType::VERTEXBASEDP1 && rdof == 4)
+        VertexBasedCompflow_P1( esup, inpoel, ndofel, fd.Esuel().size()/4,
+          m_mat_blk, fd, geoFace, geoElem, coord, flux, solidx, U,
+          shockmarker);
+      else if (limiter == ctr::LimiterType::VERTEXBASEDP1 && rdof == 10)
+        VertexBasedCompflow_P2( esup, inpoel, ndofel, fd.Esuel().size()/4,
+          m_mat_blk, fd, geoFace, geoElem, coord, gid, bid,
+          uNodalExtrm, mtInv, flux, solidx, U, shockmarker);
+    }
+
+    //! Update the conservative variable solution for this PDE system
+    //! \details This function computes the updated dofs for conservative
+    //!   quantities based on the limited solution and is currently not used in
+    //!   compflow.
+    void CPL( const tk::Fields&,
+              const tk::Fields&,
+              const std::vector< std::size_t >&,
+              const tk::UnsMesh::Coords&,
+              tk::Fields&,
+              std::size_t ) const {}
+
+    //! Return cell-average deformation gradient tensor (no-op for compflow)
+    //! \details This function is a no-op in compflow.
+    std::array< std::vector< tk::real >, 9 > cellAvgDeformGrad(
+      const tk::Fields&,
+      std::size_t ) const
+    {
+      return {};
+    }
+
+    //! Compute right hand side
+    //! \param[in] t Physical time
+    //! \param[in] geoFace Face geometry array
+    //! \param[in] geoElem Element geometry array
+    //! \param[in] fd Face connectivity and boundary conditions object
+    //! \param[in] inpoel Element-node connectivity
+    //! \param[in] boxelems Mesh node ids within user-defined IC boxes
+    //! \param[in] coord Array of nodal coordinates
+    //! \param[in] U Solution vector at recent time step
+    //! \param[in] P Primitive vector at recent time step
+    //! \param[in] ndofel Vector of local number of degrees of freedom
+    // //! \param[in] rho0mat Initial densities of all materials
+    //! \param[in] dt Delta time
+    //! \param[in,out] R Right-hand side vector computed
+    void rhs( tk::real t,
+              const tk::Fields& geoFace,
+              const tk::Fields& geoElem,
+              const inciter::FaceData& fd,
+              const std::vector< std::size_t >& inpoel,
+              const std::vector< std::unordered_set< std::size_t > >& boxelems,
+              const tk::UnsMesh::Coords& coord,
+              const tk::Fields& U,
+              const tk::Fields& P,
+              const std::vector< std::size_t >& ndofel,
+              const std::vector< tk::real >& /*rho0mat*/,
+              const tk::real dt,
+              tk::Fields& R ) const
+    {
+      const auto ndof = g_inputdeck.get< tag::ndof >();
+      const auto rdof = g_inputdeck.get< tag::rdof >();
+
+      const auto& solidx = g_inputdeck.get< tag::matidxmap, tag::solidx >();
+
+      Assert( U.nunk() == P.nunk(), "Number of unknowns in solution "
+              "vector and primitive vector at recent time step incorrect" );
+      Assert( U.nunk() == R.nunk(), "Number of unknowns in solution "
+              "vector and right-hand side at recent time step incorrect" );
+      Assert( U.nprop() == rdof*5, "Number of components in solution "
+              "vector must equal "+ std::to_string(rdof*5) );
+      Assert( P.nprop() == 0, "Number of components in primitive "
+              "vector must equal "+ std::to_string(0) );
+      Assert( R.nprop() == ndof*5, "Number of components in right-hand "
+              "side vector must equal "+ std::to_string(ndof*5) );
+      Assert( fd.Inpofa().size()/3 == fd.Esuf().size()/2,
+              "Mismatch in inpofa size" );
+
+      // set rhs to zero
+      R.fill(0.0);
+
+      // empty vector for non-conservative terms. This vector is unused for
+      // single-material hydrodynamics since, there are no non-conservative
+      // terms in the system of PDEs.
+      std::vector< std::vector < tk::real > > riemannDeriv;
+
+      std::vector< std::vector< tk::real > > vriem;
+      std::vector< std::vector< tk::real > > riemannLoc;
+
+      // configure a no-op lambda for prescribed velocity
+      auto velfn = []( ncomp_t, tk::real, tk::real, tk::real, tk::real ){
+        return tk::VelFn::result_type(); };
 
-    //! Return names of integral variables to be output to diagnostics file
-    //! \return Vector of strings labelling integral variables output
-    std::vector< std::string > names() const {
-      std::vector< std::string > n;
-      const auto& depvar =
-        g_inputdeck.get< tag::depvar >().at(0);
-      // construct the name of the numerical solution for all components
-      for (ncomp_t c=0; c<m_ncomp; ++c)
-        n.push_back( depvar + std::to_string(c) );
-      return n;
-    }
-
-  private:
-    const Physics m_physics;            //!< Physics policy
-    const Problem m_problem;            //!< Problem policy
-    const ncomp_t m_ncomp;              //!< Number of components in this PDE
-    //! EOS material block
-    const std::vector< EOS > m_mat_blk;
-
-    //! \brief Compute/assemble nodal gradients of primitive variables for
-    //!   ALECG in all points
-    //! \param[in] coord Mesh node coordinates
-    //! \param[in] inpoel Mesh element connectivity
-    //! \param[in] lid Global->local node ids
-    //! \param[in] bid Local chare-boundary node ids (value) associated to
-    //!    global node ids (key)
-    //! \param[in] vol Nodal volumes
-    //! \param[in] esup Elements surrounding points
-    //! \param[in] U Solution vector at recent time step
-    //! \param[in] G Nodal gradients of primitive variables in chare-boundary nodes
-    //! \return Gradients of primitive variables in all mesh points
-    tk::Fields
-    nodegrad( const std::array< std::vector< real >, 3 >& coord,
-              const std::vector< std::size_t >& inpoel,
-              const std::unordered_map< std::size_t, std::size_t >& lid,
-              const std::unordered_map< std::size_t, std::size_t >& bid,
-              const std::vector< real >& vol,
-              const std::pair< std::vector< std::size_t >,
-                               std::vector< std::size_t > >& esup,
-              const tk::Fields& U,
-              const tk::Fields& G ) const
-    {
-      // allocate storage for nodal gradients of primitive variables
-      tk::Fields Grad( U.nunk(), m_ncomp*3 );
-      Grad.fill( 0.0 );
-
-      // access node cooordinates
-      const auto& x = coord[0];
-      const auto& y = coord[1];
-      const auto& z = coord[2];
-
-      // compute gradients of primitive variables in points
-      auto npoin = U.nunk();
-      #pragma omp simd
-      for (std::size_t p=0; p<npoin; ++p)
-        for (auto e : tk::Around(esup,p)) {
-          // access node IDs
-          std::size_t N[4] =
-            { inpoel[e*4+0], inpoel[e*4+1], inpoel[e*4+2], inpoel[e*4+3] };
-          // compute element Jacobi determinant, J = 6V
-          real bax = x[N[1]]-x[N[0]];
-          real bay = y[N[1]]-y[N[0]];
-          real baz = z[N[1]]-z[N[0]];
-          real cax = x[N[2]]-x[N[0]];
-          real cay = y[N[2]]-y[N[0]];
-          real caz = z[N[2]]-z[N[0]];
-          real dax = x[N[3]]-x[N[0]];
-          real day = y[N[3]]-y[N[0]];
-          real daz = z[N[3]]-z[N[0]];
-          auto J = tk::triple( bax, bay, baz, cax, cay, caz, dax, day, daz );
-          auto J24 = J/24.0;
-          // shape function derivatives, nnode*ndim [4][3]
-          real g[4][3];
-          tk::crossdiv( cax, cay, caz, dax, day, daz, J,
-                        g[1][0], g[1][1], g[1][2] );
-          tk::crossdiv( dax, day, daz, bax, bay, baz, J,
-                        g[2][0], g[2][1], g[2][2] );
-          tk::crossdiv( bax, bay, baz, cax, cay, caz, J,
-                        g[3][0], g[3][1], g[3][2] );
-          for (std::size_t i=0; i<3; ++i)
-            g[0][i] = -g[1][i] - g[2][i] - g[3][i];
-          // scatter-add gradient contributions to boundary nodes
-          for (std::size_t c=0; c<m_ncomp; ++c)
-            for (std::size_t b=0; b<4; ++b)
-              for (std::size_t i=0; i<3; ++i)
-                Grad(p,c*3+i) += J24 * g[b][i] * U(N[b],c);
-        }
-
-      // put in nodal gradients of chare-boundary points
-      for (const auto& [g,b] : bid) {
-        auto i = tk::cref_find( lid, g );
-        for (ncomp_t c=0; c<Grad.nprop(); ++c)
-          Grad(i,c) = G(b,c);
-      }
-
-      // divide weak result in gradients by nodal volume
-      for (std::size_t p=0; p<npoin; ++p)
-        for (std::size_t c=0; c<m_ncomp*3; ++c)
-          Grad(p,c) /= vol[p];
+      // compute internal surface flux integrals
+      tk::surfInt( 1, m_mat_blk, t, ndof, rdof, inpoel, solidx,
+                   coord, fd, geoFace, geoElem, m_riemann, velfn, U, P, ndofel,
+                   dt, R, vriem, riemannLoc, riemannDeriv );
+
+      // compute optional source term
+      tk::srcInt( m_mat_blk, t, ndof, fd.Esuel().size()/4,
+                  inpoel, coord, geoElem, Problem::src, ndofel, R );
+
+      if(ndof > 1)
+        // compute volume integrals
+        tk::volInt( 1, t, m_mat_blk, ndof, rdof,
+                    fd.Esuel().size()/4, inpoel, coord, geoElem, flux, velfn,
+                    U, P, ndofel, R );
+
+      // compute boundary surface flux integrals
+      for (const auto& b : m_bc)
+        tk::bndSurfInt( 1, m_mat_blk, ndof, rdof, b.first,
+                        fd, geoFace, geoElem, inpoel, coord, t, m_riemann,
+                        velfn, b.second, U, P, ndofel, R, vriem, riemannLoc,
+                        riemannDeriv );
+
+     // compute external (energy) sources
+      const auto& ic = g_inputdeck.get< tag::ic >();
+      const auto& icbox = ic.get< tag::box >();
+
+      if (!icbox.empty() && !boxelems.empty()) {
+        std::size_t bcnt = 0;
+        for (const auto& b : icbox) {   // for all boxes for this eq
+          std::vector< tk::real > box
+           { b.template get< tag::xmin >(), b.template get< tag::xmax >(),
+             b.template get< tag::ymin >(), b.template get< tag::ymax >(),
+             b.template get< tag::zmin >(), b.template get< tag::zmax >() };
+
+          const auto& initiate = b.template get< tag::initiate >();
+          if (initiate == ctr::InitiateType::LINEAR) {
+            boxSrc( t, inpoel, boxelems[bcnt], coord, geoElem, ndofel, R );
+          }
+          ++bcnt;
+        }
+      }
+    }
+
+    //! Evaluate the adaptive indicator and mark the ndof for each element
+    //! \param[in] nunk Number of unknowns
+    //! \param[in] coord Array of nodal coordinates
+    //! \param[in] inpoel Element-node connectivity
+    //! \param[in] fd Face connectivity and boundary conditions object
+    //! \param[in] unk Array of unknowns
+    //! \param[in] prim Array of primitive quantities
+    //! \param[in] indicator p-refinement indicator type
+    //! \param[in] ndof Number of degrees of freedom in the solution
+    //! \param[in] ndofmax Max number of degrees of freedom for p-refinement
+    //! \param[in] tolref Tolerance for p-refinement
+    //! \param[in,out] ndofel Vector of local number of degrees of freedome
+    void eval_ndof( std::size_t nunk,
+                    const tk::UnsMesh::Coords& coord,
+                    const std::vector< std::size_t >& inpoel,
+                    const inciter::FaceData& fd,
+                    const tk::Fields& unk,
+                    const tk::Fields& prim,
+                    inciter::ctr::PrefIndicatorType indicator,
+                    std::size_t ndof,
+                    std::size_t ndofmax,
+                    tk::real tolref,
+                    std::vector< std::size_t >& ndofel ) const
+    {
+      const auto& esuel = fd.Esuel();
+
+      if(indicator == inciter::ctr::PrefIndicatorType::SPECTRAL_DECAY)
+        spectral_decay( 1, nunk, esuel, unk, prim, ndof, ndofmax, tolref,
+          ndofel );
+      else if(indicator == inciter::ctr::PrefIndicatorType::NON_CONFORMITY)
+        non_conformity( nunk, fd.Nbfac(), inpoel, coord, esuel, fd.Esuf(),
+          fd.Inpofa(), unk, ndof, ndofmax, ndofel );
+      else
+        Throw( "No such adaptive indicator type" );
+    }
+
+    //! Compute the minimum time step size
+    //! \param[in] coord Mesh node coordinates
+    //! \param[in] inpoel Mesh element connectivity
+    //! \param[in] fd Face connectivity and boundary conditions object
+    //! \param[in] geoFace Face geometry array
+    //! \param[in] geoElem Element geometry array
+    //! \param[in] ndofel Vector of local number of degrees of freedom
+    //! \param[in] U Solution vector at recent time step
+    //! \return Minimum time step size
+    tk::real dt( const std::array< std::vector< tk::real >, 3 >& coord,
+                 const std::vector< std::size_t >& inpoel,
+                 const inciter::FaceData& fd,
+                 const tk::Fields& geoFace,
+                 const tk::Fields& geoElem,
+                 const std::vector< std::size_t >& ndofel,
+                 const tk::Fields& U,
+                 const tk::Fields&,
+                 const std::size_t /*nielem*/ ) const
+    {
+      const auto rdof = g_inputdeck.get< tag::rdof >();
 
-      return Grad;
-    }
+      const auto& esuf = fd.Esuf();
+      const auto& inpofa = fd.Inpofa();
 
-    //! \brief Compute MUSCL reconstruction in edge-end points using a MUSCL
-    //!    procedure with van Leer limiting
-    //! \param[in] p Left node id of edge-end
-    //! \param[in] q Right node id of edge-end
-    //! \param[in] coord Array of nodal coordinates
-    //! \param[in] G Gradient of all unknowns in mesh points
-    //! \param[in,out] uL Primitive variables at left edge-end point
-    //! \param[in,out] uR Primitive variables at right edge-end point
-    void
-    muscl( std::size_t p,
-           std::size_t q,
-           const tk::UnsMesh::Coords& coord,
-           const tk::Fields& G,
-           std::vector< real >& uL,
-           std::vector< real >& uR ) const
-    {
-      Assert( uL.size() == m_ncomp && uR.size() == m_ncomp, "Size mismatch" );
-      Assert( G.nprop()/3 == m_ncomp, "Size mismatch" );
-
-      const auto& x = coord[0];
-      const auto& y = coord[1];
-      const auto& z = coord[2];
-
-      // edge vector
-      std::array< real, 3 > vw{ x[q]-x[p], y[q]-y[p], z[q]-z[p] };
-
-      std::vector< real >
-        delta1( m_ncomp, 0.0 ), delta2( m_ncomp, 0.0 ), delta3( m_ncomp, 0.0 );
-
-      // MUSCL reconstruction of edge-end-point primitive variables
-      for (std::size_t c=0; c<m_ncomp; ++c) {
-        // gradients
-        std::array< real, 3 >
-          g1{ G(p,c*3+0), G(p,c*3+1), G(p,c*3+2) },
-          g2{ G(q,c*3+0), G(q,c*3+1), G(q,c*3+2) };
-
-        delta2[c] = uR[c] - uL[c];
-        delta1[c] = 2.0 * tk::dot(g1,vw) - delta2[c];
-        delta3[c] = 2.0 * tk::dot(g2,vw) - delta2[c];
-
-        // form limiters
-        auto rL = (delta2[c] + muscl_eps) / (delta1[c] + muscl_eps);
-        auto rR = (delta2[c] + muscl_eps) / (delta3[c] + muscl_eps);
-        auto rLinv = (delta1[c] + muscl_eps) / (delta2[c] + muscl_eps);
-        auto rRinv = (delta3[c] + muscl_eps) / (delta2[c] + muscl_eps);
-
-        auto phiL = (std::abs(rL) + rL) / (std::abs(rL) + 1.0);
-        auto phiR = (std::abs(rR) + rR) / (std::abs(rR) + 1.0);
-        auto phi_L_inv = (std::abs(rLinv) + rLinv) / (std::abs(rLinv) + 1.0);
-        auto phi_R_inv = (std::abs(rRinv) + rRinv) / (std::abs(rRinv) + 1.0);
+      tk::real rho, u, v, w, rhoE, p, a, vn, dSV_l, dSV_r;
+      std::vector< tk::real > delt( U.nunk(), 0.0 );
+
+      const auto& cx = coord[0];
+      const auto& cy = coord[1];
+      const auto& cz = coord[2];
+
+      // compute internal surface maximum characteristic speed
+      for (std::size_t f=0; f<esuf.size()/2; ++f)
+      {
+
+        std::size_t el = static_cast< std::size_t >(esuf[2*f]);
+        auto er = esuf[2*f+1];
+
+        // Number of quadrature points for  face integration
+        std::size_t ng;
+
+        if(er > -1)
+        {
+          auto eR = static_cast< std::size_t >( er );
+
+          auto ng_l = tk::NGfa(ndofel[el]);
+          auto ng_r = tk::NGfa(ndofel[eR]);
+
+          // When the number of gauss points for the left and right element are
+          // different, choose the larger ng
+          ng = std::max( ng_l, ng_r );
+        }
+        else
+        {
+          ng = tk::NGfa(ndofel[el]);
+        }
+
+        // arrays for quadrature points
+        std::array< std::vector< tk::real >, 2 > coordgp;
+        std::vector< tk::real > wgp;
+
+        coordgp[0].resize( ng );
+        coordgp[1].resize( ng );
+        wgp.resize( ng );
+
+        // get quadrature point weights and coordinates for triangle
+        tk::GaussQuadratureTri( ng, coordgp, wgp );
+
+        // Extract the left element coordinates
+        std::array< std::array< tk::real, 3>, 4 > coordel_l {{
+          {{ cx[inpoel[4*el  ]], cy[inpoel[4*el  ]], cz[inpoel[4*el  ]] }},
+          {{ cx[inpoel[4*el+1]], cy[inpoel[4*el+1]], cz[inpoel[4*el+1]] }},
+          {{ cx[inpoel[4*el+2]], cy[inpoel[4*el+2]], cz[inpoel[4*el+2]] }},
+          {{ cx[inpoel[4*el+3]], cy[inpoel[4*el+3]], cz[inpoel[4*el+3]] }} }};
 
-        // update unknowns with reconstructed unknowns
-        uL[c] += 0.25*(delta1[c]*muscl_m1*phiL + delta2[c]*muscl_p1*phi_L_inv);
-        uR[c] -= 0.25*(delta3[c]*muscl_m1*phiR + delta2[c]*muscl_p1*phi_R_inv);
-      }
-    }
-
-    //! Compute domain-edge integral for ALECG
-    //! \param[in] coord Mesh node coordinates
-    //! \param[in] inpoel Mesh element connectivity
-    //! \param[in] edgeid Local node id pair -> edge id map
-    //! \param[in] psup Points surrounding points
-    //! \param[in] dfn Dual-face normals
-    //! \param[in] U Solution vector at recent time step
-    //! \param[in] G Nodal gradients
-    //! \param[in,out] R Right-hand side vector computed
-    void domainint( const std::array< std::vector< real >, 3 >& coord,
-                    const std::vector< std::size_t >& inpoel,
-                    const std::vector< std::size_t >& edgeid,
-                    const std::pair< std::vector< std::size_t >,
-                                     std::vector< std::size_t > >& psup,
-                    const std::vector< real >& dfn,
-                    const tk::Fields& U,
-                    const tk::Fields& G,
-                    tk::Fields& R ) const
-    {
-      // access node cooordinates
-      const auto& x = coord[0];
-      const auto& y = coord[1];
-      const auto& z = coord[2];
+        // Compute the determinant of Jacobian matrix
+        auto detT_l = 
+           tk::Jacobian(coordel_l[0], coordel_l[1], coordel_l[2], coordel_l[3]);
+
+        // Extract the face coordinates
+        std::array< std::array< tk::real, 3>, 3 > coordfa {{
+          {{ cx[ inpofa[3*f  ] ], cy[ inpofa[3*f  ] ], cz[ inpofa[3*f  ] ] }},
+          {{ cx[ inpofa[3*f+1] ], cy[ inpofa[3*f+1] ], cz[ inpofa[3*f+1] ] }},
+          {{ cx[ inpofa[3*f+2] ], cy[ inpofa[3*f+2] ], cz[ inpofa[3*f+2] ] }}
+        }};
+
+        dSV_l = 0.0;<--- Variable 'dSV_l' is assigned a value that is never used.
+        dSV_r = 0.0;
+
+        // Gaussian quadrature
+        for (std::size_t igp=0; igp<ng; ++igp)
+        {
+          // Compute the coordinates of quadrature point at physical domain
+          auto gp = tk::eval_gp( igp, coordfa, coordgp );
+
+          // Compute the basis function for the left element
+          auto B_l = tk::eval_basis( ndofel[el],
+            tk::Jacobian(coordel_l[0], gp, coordel_l[2], coordel_l[3])/detT_l,
+            tk::Jacobian(coordel_l[0], coordel_l[1], gp, coordel_l[3])/detT_l,
+            tk::Jacobian(coordel_l[0], coordel_l[1], coordel_l[2], gp)/detT_l );
+
+          auto wt = wgp[igp] * geoFace(f,0);
+
+          std::array< std::vector< tk::real >, 2 > ugp;
 
-      // compute derived data structures
-      auto esued = tk::genEsued( inpoel, 4, tk::genEsup( inpoel, 4 ) );
-
-      // access pointer to right hand side at component
-      std::vector< const real* > r( m_ncomp );
-      for (ncomp_t c=0; c<m_ncomp; ++c) r[c] = R.cptr( c );
-
-      // domain-edge integral
-      for (std::size_t p=0,k=0; p<U.nunk(); ++p) {
-        for (auto q : tk::Around(psup,p)) {
-          // access dual-face normals for edge p-q
-          auto ed = edgeid[k++];
-          std::array< tk::real, 3 > n{ dfn[ed*6+0], dfn[ed*6+1], dfn[ed*6+2] };
-
-          std::vector< tk::real > uL( m_ncomp, 0.0 );
-          std::vector< tk::real > uR( m_ncomp, 0.0 );
-          for (std::size_t c=0; c<m_ncomp; ++c) {
-            uL[c] = U(p,c);
-            uR[c] = U(q,c);
-          }
-          // compute MUSCL reconstruction in edge-end points
-          muscl( p, q, coord, G, uL, uR );
-
-          // evaluate prescribed velocity
-          auto v =
-            Problem::prescribedVelocity( m_ncomp, x[p], y[p], z[p], 0.0 );
-          // sum donain-edge contributions
-          for (auto e : tk::cref_find(esued,{p,q})) {
-            const std::array< std::size_t, 4 >
-              N{{ inpoel[e*4+0], inpoel[e*4+1], inpoel[e*4+2], inpoel[e*4+3] }};
-            // compute element Jacobi determinant
-            const std::array< tk::real, 3 >
-              ba{{ x[N[1]]-x[N[0]], y[N[1]]-y[N[0]], z[N[1]]-z[N[0]] }},
-              ca{{ x[N[2]]-x[N[0]], y[N[2]]-y[N[0]], z[N[2]]-z[N[0]] }},
-              da{{ x[N[3]]-x[N[0]], y[N[3]]-y[N[0]], z[N[3]]-z[N[0]] }};
-            const auto J = tk::triple( ba, ca, da );        // J = 6V
-            // shape function derivatives, nnode*ndim [4][3]
-            std::array< std::array< tk::real, 3 >, 4 > grad;
-            grad[1] = tk::crossdiv( ca, da, J );
-            grad[2] = tk::crossdiv( da, ba, J );
-            grad[3] = tk::crossdiv( ba, ca, J );
-            for (std::size_t i=0; i<3; ++i)
-              grad[0][i] = -grad[1][i]-grad[2][i]-grad[3][i];
-            auto J48 = J/48.0;
-            for (const auto& [a,b] : tk::lpoed) {
-              auto s = tk::orient( {N[a],N[b]}, {p,q} );
-              for (std::size_t j=0; j<3; ++j) {
-                for (std::size_t c=0; c<m_ncomp; ++c) {
-                  R.var(r[c],p) -= J48 * s * (grad[a][j] - grad[b][j])
-                                   * v[c][j]*(uL[c] + uR[c])
-                    - J48 * std::abs(s * (grad[a][j] - grad[b][j]))
-                          * std::abs(tk::dot(v[c],n)) * (uR[c] - uL[c]);
-                }
-              }
-            }
-          }
-        }
-      }
-    }
-
-    //! Compute boundary integrals for ALECG
-    //! \param[in] coord Mesh node coordinates
-    //! \param[in] triinpoel Boundary triangle face connecitivity with local ids
-    //! \param[in] symbctri Vector with 1 at symmetry BC boundary triangles
-    //! \param[in] U Solution vector at recent time step
-    //! \param[in,out] R Right-hand side vector computed
-    void bndint( const std::array< std::vector< real >, 3 >& coord,
-                 const std::vector< std::size_t >& triinpoel,
-                 const std::vector< int >& symbctri,
-                 const tk::Fields& U,
-                 tk::Fields& R ) const
-    {
-      // access node coordinates
-      const auto& x = coord[0];
-      const auto& y = coord[1];
-      const auto& z = coord[2];
-
-      // boundary integrals: compute fluxes in edges
-      std::vector< real > bflux( triinpoel.size() * m_ncomp * 2 );
-
-      for (std::size_t e=0; e<triinpoel.size()/3; ++e) {
-        // access node IDs
-        std::array< std::size_t, 3 >
-          N{ triinpoel[e*3+0], triinpoel[e*3+1], triinpoel[e*3+2] };
-        // apply symmetry BCs
-        if (symbctri[e]) continue;
-        // node coordinates
-        std::array< tk::real, 3 > xp{ x[N[0]], x[N[1]], x[N[2]] },
-                                  yp{ y[N[0]], y[N[1]], y[N[2]] },
-                                  zp{ z[N[0]], z[N[1]], z[N[2]] };
-        // access solution at element nodes
-        std::vector< std::array< real, 3 > > u( m_ncomp );
-        for (ncomp_t c=0; c<m_ncomp; ++c) u[c] = U.extract( c, N );
-        // evaluate prescribed velocity
-        auto v =
-          Problem::prescribedVelocity( m_ncomp, xp[0], yp[0], zp[0], 0.0 );
-        // compute face area
-        auto A6 = tk::area( x[N[0]], x[N[1]], x[N[2]],
-                            y[N[0]], y[N[1]], y[N[2]],
-                            z[N[0]], z[N[1]], z[N[2]] ) / 6.0;
-        auto A24 = A6/4.0;
-        // compute face normal
-        auto n = tk::normal( xp, yp, zp );
-        // store flux in boundary elements
-        for (std::size_t c=0; c<m_ncomp; ++c) {
-          auto eb = (e*m_ncomp+c)*6;
-          auto vdotn = tk::dot( v[c], n );
-          auto Bab = A24 * vdotn * (u[c][0] + u[c][1]);
-          bflux[eb+0] = Bab + A6 * vdotn * u[c][0];
-          bflux[eb+1] = Bab;
-          Bab = A24 * vdotn * (u[c][1] + u[c][2]);
-          bflux[eb+2] = Bab + A6 * vdotn * u[c][1];
-          bflux[eb+3] = Bab;
-          Bab = A24 * vdotn * (u[c][2] + u[c][0]);
-          bflux[eb+4] = Bab + A6 * vdotn * u[c][2];
-          bflux[eb+5] = Bab;
-        }
-      }
-
-      // access pointer to right hand side at component
-      std::vector< const real* > r( m_ncomp );
-      for (ncomp_t c=0; c<m_ncomp; ++c) r[c] = R.cptr( c );
-
-      // boundary integrals: sum flux contributions to points
-      for (std::size_t e=0; e<triinpoel.size()/3; ++e) {
-        std::size_t N[3] =
-          { triinpoel[e*3+0], triinpoel[e*3+1], triinpoel[e*3+2] };
-        for (std::size_t c=0; c<m_ncomp; ++c) {
-          auto eb = (e*m_ncomp+c)*6;
-          R.var(r[c],N[0]) -= bflux[eb+0] + bflux[eb+5];
-          R.var(r[c],N[1]) -= bflux[eb+1] + bflux[eb+2];
-          R.var(r[c],N[2]) -= bflux[eb+3] + bflux[eb+4];
-        }
-      }
-
-      tk::destroy(bflux);
-    }
-};
-
-} // cg::
-} // inciter::
-
-#endif // Transport_h
+          // left element
+          for (ncomp_t c=0; c<5; ++c)
+          {
+            auto mark = c*rdof;
+            ugp[0].push_back( U(el, mark) );
+
+            if(ndofel[el] > 1)          //DG(P1)
+              ugp[0][c] +=  U(el, mark+1) * B_l[1]
+                          + U(el, mark+2) * B_l[2]
+                          + U(el, mark+3) * B_l[3];
+
+            if(ndofel[el] > 4)          //DG(P2)
+              ugp[0][c] +=  U(el, mark+4) * B_l[4]
+                          + U(el, mark+5) * B_l[5]
+                          + U(el, mark+6) * B_l[6]
+                          + U(el, mark+7) * B_l[7]
+                          + U(el, mark+8) * B_l[8]
+                          + U(el, mark+9) * B_l[9];
+          }
+
+          rho = ugp[0][0];
+          u = ugp[0][1]/rho;
+          v = ugp[0][2]/rho;
+          w = ugp[0][3]/rho;
+          rhoE = ugp[0][4];
+          p = m_mat_blk[0].compute< EOS::pressure >( rho, u, v, w, rhoE );
+
+          a = m_mat_blk[0].compute< EOS::soundspeed >( rho, p );
+
+          vn = u*geoFace(f,1) + v*geoFace(f,2) + w*geoFace(f,3);
+
+          dSV_l = wt * (std::fabs(vn) + a);
+
+          // right element
+          if (er > -1) {
+
+            // nodal coordinates of the right element
+            std::size_t eR = static_cast< std::size_t >( er );
+
+            // Extract the left element coordinates
+            std::array< std::array< tk::real, 3>, 4 > coordel_r {{
+              {{ cx[inpoel[4*eR  ]], cy[inpoel[4*eR  ]], cz[inpoel[4*eR  ]] }},
+              {{ cx[inpoel[4*eR+1]], cy[inpoel[4*eR+1]], cz[inpoel[4*eR+1]] }},
+              {{ cx[inpoel[4*eR+2]], cy[inpoel[4*eR+2]], cz[inpoel[4*eR+2]] }},
+              {{ cx[inpoel[4*eR+3]], cy[inpoel[4*eR+3]], cz[inpoel[4*eR+3]] }}
+            }};
+
+            // Compute the determinant of Jacobian matrix
+            auto detT_r =
+              tk::Jacobian(coordel_r[0],coordel_r[1],coordel_r[2],coordel_r[3]);
+
+            // Compute the coordinates of quadrature point at physical domain
+            gp = tk::eval_gp( igp, coordfa, coordgp );
+
+            // Compute the basis function for the right element
+            auto B_r = tk::eval_basis( ndofel[eR],
+              tk::Jacobian(coordel_r[0],gp,coordel_r[2],coordel_r[3])/detT_r,
+              tk::Jacobian(coordel_r[0],coordel_r[1],gp,coordel_r[3])/detT_r,
+              tk::Jacobian(coordel_r[0],coordel_r[1],coordel_r[2],gp)/detT_r );
+ 
+            for (ncomp_t c=0; c<5; ++c)
+            {
+              auto mark = c*rdof;
+              ugp[1].push_back( U(eR, mark) );
+
+              if(ndofel[eR] > 1)          //DG(P1)
+                ugp[1][c] +=  U(eR, mark+1) * B_r[1]
+                            + U(eR, mark+2) * B_r[2]
+                            + U(eR, mark+3) * B_r[3];
+
+              if(ndofel[eR] > 4)         //DG(P2)
+                ugp[1][c] +=  U(eR, mark+4) * B_r[4]
+                            + U(eR, mark+5) * B_r[5]
+                            + U(eR, mark+6) * B_r[6]
+                            + U(eR, mark+7) * B_r[7]
+                            + U(eR, mark+8) * B_r[8]
+                            + U(eR, mark+9) * B_r[9];
+            }
+
+            rho = ugp[1][0];
+            u = ugp[1][1]/rho;
+            v = ugp[1][2]/rho;
+            w = ugp[1][3]/rho;
+            rhoE = ugp[1][4];
+            p = m_mat_blk[0].compute< EOS::pressure >( rho, u, v, w, rhoE );
+            a = m_mat_blk[0].compute< EOS::soundspeed >( rho, p );
+
+            vn = u*geoFace(f,1) + v*geoFace(f,2) + w*geoFace(f,3);
+
+            dSV_r = wt * (std::fabs(vn) + a);
+            delt[eR] += std::max( dSV_l, dSV_r );
+          }
+
+          delt[el] += std::max( dSV_l, dSV_r );
+        }
+      }
+
+      tk::real mindt = std::numeric_limits< tk::real >::max();
+      tk::real dgp = 0.0;<--- Variable 'dgp' is assigned a value that is never used.
+
+      // compute allowable dt
+      for (std::size_t e=0; e<fd.Esuel().size()/4; ++e)
+      {
+        dgp = 0.0;
+        if (ndofel[e] == 4)
+        {
+          dgp = 1.0;
+        }
+        else if (ndofel[e] == 10)
+        {
+          dgp = 2.0;
+        }
+
+        // Scale smallest dt with CFL coefficient and the CFL is scaled by (2*p+1)
+        // where p is the order of the DG polynomial by linear stability theory.
+        mindt = std::min( mindt, geoElem(e,0)/ (delt[e] * (2.0*dgp + 1.0)) );
+      }
+
+      return mindt;
+    }
+
+    //! Compute stiff terms for a single element, not implemented here
+    // //! \param[in] e Element number
+    // //! \param[in] geoElem Element geometry array
+    // //! \param[in] inpoel Element-node connectivity
+    // //! \param[in] coord Array of nodal coordinates
+    // //! \param[in] U Solution vector at recent time step
+    // //! \param[in] P Primitive vector at recent time step
+    // //! \param[in] ndofel Vector of local number of degrees of freedom
+    // //! \param[in,out] R Right-hand side vector computed
+    void stiff_rhs( std::size_t /*e*/,
+                    const tk::Fields& /*geoElem*/,
+                    const std::vector< std::size_t >& /*inpoel*/,
+                    const tk::UnsMesh::Coords& /*coord*/,
+                    const tk::Fields& /*U*/,
+                    const tk::Fields& /*P*/,
+                    const std::vector< std::size_t >& /*ndofel*/,
+                    tk::Fields& /*R*/ ) const
+    {}
+
+    //! Extract the velocity field at cell nodes. Currently unused.
+    //! \param[in] U Solution vector at recent time step
+    //! \param[in] N Element node indices
+    //! \return Array of the four values of the velocity field
+    std::array< std::array< tk::real, 4 >, 3 >
+    velocity( const tk::Fields& U,
+              const std::array< std::vector< tk::real >, 3 >&,
+              const std::array< std::size_t, 4 >& N ) const
+    {
+      std::array< std::array< tk::real, 4 >, 3 > v;
+      v[0] = U.extract( 1, N );
+      v[1] = U.extract( 2, N );
+      v[2] = U.extract( 3, N );
+      auto r = U.extract( 0, N );
+      std::transform( r.begin(), r.end(), v[0].begin(), v[0].begin(),
+                      []( tk::real s, tk::real& d ){ return d /= s; } );
+      std::transform( r.begin(), r.end(), v[1].begin(), v[1].begin(),
+                      []( tk::real s, tk::real& d ){ return d /= s; } );
+      std::transform( r.begin(), r.end(), v[2].begin(), v[2].begin(),
+                      []( tk::real s, tk::real& d ){ return d /= s; } );
+      return v;
+    }
+
+    //! Return a map that associates user-specified strings to functions
+    //! \return Map that associates user-specified strings to functions that
+    //!   compute relevant quantities to be output to file
+    std::map< std::string, tk::GetVarFn > OutVarFn() const
+    { return CompFlowOutVarFn(); }
+
+    //! Return analytic field names to be output to file
+    //! \return Vector of strings labelling analytic fields output in file
+    std::vector< std::string > analyticFieldNames() const
+    { return m_problem.analyticFieldNames( m_ncomp ); }
+
+    //! Return time history field names to be output to file
+    //! \return Vector of strings labeling time history fields output in file
+    std::vector< std::string > histNames() const
+    { return CompFlowHistNames(); }
+
+    //! Return surface field output going to file
+    std::vector< std::vector< tk::real > >
+    surfOutput( const std::map< int, std::vector< std::size_t > >&,
+                tk::Fields& ) const
+    {
+      std::vector< std::vector< tk::real > > s; // punt for now
+      return s;
+    }
+
+    //! Return time history field output evaluated at time history points
+    //! \param[in] h History point data
+    //! \param[in] inpoel Element-node connectivity
+    //! \param[in] coord Array of nodal coordinates
+    //! \param[in] U Array of unknowns
+    std::vector< std::vector< tk::real > >
+    histOutput( const std::vector< HistData >& h,
+                const std::vector< std::size_t >& inpoel,
+                const tk::UnsMesh::Coords& coord,
+                const tk::Fields& U,
+                const tk::Fields& ) const
+    {
+      const auto rdof = g_inputdeck.get< tag::rdof >();
+
+      const auto& x = coord[0];
+      const auto& y = coord[1];
+      const auto& z = coord[2];
+
+      std::vector< std::vector< tk::real > > Up(h.size());
+
+      std::size_t j = 0;
+      for (const auto& p : h) {
+        auto e = p.get< tag::elem >();
+        auto chp = p.get< tag::coord >();
+
+        // Evaluate inverse Jacobian
+        std::array< std::array< tk::real, 3>, 4 > cp{{
+          {{ x[inpoel[4*e  ]], y[inpoel[4*e  ]], z[inpoel[4*e  ]] }},
+          {{ x[inpoel[4*e+1]], y[inpoel[4*e+1]], z[inpoel[4*e+1]] }},
+          {{ x[inpoel[4*e+2]], y[inpoel[4*e+2]], z[inpoel[4*e+2]] }},
+          {{ x[inpoel[4*e+3]], y[inpoel[4*e+3]], z[inpoel[4*e+3]] }} }};
+        auto J = tk::inverseJacobian( cp[0], cp[1], cp[2], cp[3] );
+
+        // evaluate solution at history-point
+        std::array< tk::real, 3 > dc{{chp[0]-cp[0][0], chp[1]-cp[0][1],
+          chp[2]-cp[0][2]}};
+        auto B = tk::eval_basis(rdof, tk::dot(J[0],dc), tk::dot(J[1],dc),
+          tk::dot(J[2],dc));
+        auto uhp = eval_state(m_ncomp, rdof, rdof, e, U, B);
+
+        // store solution in history output vector
+        Up[j].resize(6, 0.0);
+        Up[j][0] = uhp[0];
+        Up[j][1] = uhp[1]/uhp[0];
+        Up[j][2] = uhp[2]/uhp[0];
+        Up[j][3] = uhp[3]/uhp[0];
+        Up[j][4] = uhp[4]/uhp[0];
+        Up[j][5] = m_mat_blk[0].compute< EOS::pressure >( uhp[0], uhp[1]/uhp[0],
+          uhp[2]/uhp[0], uhp[3]/uhp[0], uhp[4] );
+        ++j;
+      }
+
+      return Up;
+    }
+
+    //! Return names of integral variables to be output to diagnostics file
+    //! \return Vector of strings labelling integral variables output
+    std::vector< std::string > names() const
+    { return m_problem.names( m_ncomp ); }
+
+    //! Return analytic solution (if defined by Problem) at xi, yi, zi, t
+    //! \param[in] xi X-coordinate at which to evaluate the analytic solution
+    //! \param[in] yi Y-coordinate at which to evaluate the analytic solution
+    //! \param[in] zi Z-coordinate at which to evaluate the analytic solution
+    //! \param[in] t Physical time at which to evaluate the analytic solution
+    //! \return Vector of analytic solution at given location and time
+    std::vector< tk::real >
+    analyticSolution( tk::real xi, tk::real yi, tk::real zi, tk::real t ) const
+    { return Problem::analyticSolution( m_ncomp, m_mat_blk, xi, yi,
+                                        zi, t ); }
+
+    //! Return analytic solution for conserved variables
+    //! \param[in] xi X-coordinate at which to evaluate the analytic solution
+    //! \param[in] yi Y-coordinate at which to evaluate the analytic solution
+    //! \param[in] zi Z-coordinate at which to evaluate the analytic solution
+    //! \param[in] t Physical time at which to evaluate the analytic solution
+    //! \return Vector of analytic solution at given location and time
+    std::vector< tk::real >
+    solution( tk::real xi, tk::real yi, tk::real zi, tk::real t ) const
+    { return Problem::initialize( m_ncomp, m_mat_blk, xi, yi, zi, t ); }
+
+    //! Return cell-averaged specific total energy for an element
+    //! \param[in] e Element id for which total energy is required
+    //! \param[in] unk Vector of conserved quantities
+    //! \return Cell-averaged specific total energy for given element
+    tk::real sp_totalenergy(std::size_t e, const tk::Fields& unk) const
+    {
+      const auto rdof = g_inputdeck.get< tag::rdof >();
+
+      return unk(e,4*rdof);
+    }
+
+  private:
+    //! Physics policy
+    const Physics m_physics;
+    //! Problem policy
+    const Problem m_problem;
+    //! Number of components in this PDE system
+    const ncomp_t m_ncomp;
+    //! Riemann solver
+    tk::RiemannFluxFn m_riemann;
+    //! BC configuration
+    BCStateFn m_bc;
+    //! EOS material block
+    std::vector< EOS > m_mat_blk;
+
+    //! Evaluate physical flux function for this PDE system
+    //! \param[in] ncomp Number of scalar components in this PDE system
+    //! \param[in] mat_blk EOS material block
+    //! \param[in] ugp Numerical solution at the Gauss point at which to
+    //!   evaluate the flux
+    //! \return Flux vectors for all components in this PDE system
+    //! \note The function signature must follow tk::FluxFn
+    static tk::FluxFn::result_type
+    flux( [[maybe_unused]] ncomp_t ncomp,
+          const std::vector< EOS >& mat_blk,
+          const std::vector< tk::real >& ugp,
+          const std::vector< std::array< tk::real, 3 > >& )
+    {
+      Assert( ugp.size() == ncomp, "Size mismatch" );
+
+      auto u = ugp[1] / ugp[0];
+      auto v = ugp[2] / ugp[0];
+      auto w = ugp[3] / ugp[0];
+      auto p = mat_blk[0].compute< EOS::pressure >( ugp[0], u, v, w, ugp[4] );
+
+      std::vector< std::array< tk::real, 3 > > fl( ugp.size() );
+
+      fl[0][0] = ugp[1];
+      fl[1][0] = ugp[1] * u + p;
+      fl[2][0] = ugp[1] * v;
+      fl[3][0] = ugp[1] * w;
+      fl[4][0] = u * (ugp[4] + p);
+
+      fl[0][1] = ugp[2];
+      fl[1][1] = ugp[2] * u;
+      fl[2][1] = ugp[2] * v + p;
+      fl[3][1] = ugp[2] * w;
+      fl[4][1] = v * (ugp[4] + p);
+
+      fl[0][2] = ugp[3];
+      fl[1][2] = ugp[3] * u;
+      fl[2][2] = ugp[3] * v;
+      fl[3][2] = ugp[3] * w + p;
+      fl[4][2] = w * (ugp[4] + p);
+
+      return fl;
+    }
+
+    //! \brief Boundary state function providing the left and right state of a
+    //!   face at Dirichlet boundaries
+    //! \param[in] ncomp Number of scalar components in this PDE system
+    //! \param[in] mat_blk EOS material block
+    //! \param[in] ul Left (domain-internal) state
+    //! \param[in] x X-coordinate at which to compute the states
+    //! \param[in] y Y-coordinate at which to compute the states
+    //! \param[in] z Z-coordinate at which to compute the states
+    //! \param[in] t Physical time
+    //! \return Left and right states for all scalar components in this PDE
+    //!   system
+    //! \note The function signature must follow tk::StateFn
+    static tk::StateFn::result_type
+    dirichlet( ncomp_t ncomp,
+               const std::vector< EOS >& mat_blk,
+               const std::vector< tk::real >& ul, tk::real x, tk::real y,
+               tk::real z, tk::real t, const std::array< tk::real, 3 >& )
+    {
+      return {{ ul, Problem::initialize( ncomp, mat_blk, x, y, z, t ) }};
+    }
+
+    //! \brief Boundary state function providing the left and right state of a
+    //!   face at symmetry boundaries
+    //! \param[in] ul Left (domain-internal) state
+    //! \param[in] fn Unit face normal
+    //! \return Left and right states for all scalar components in this PDE
+    //!   system
+    //! \note The function signature must follow tk::StateFn
+    static tk::StateFn::result_type
+    symmetry( ncomp_t, const std::vector< EOS >&,
+              const std::vector< tk::real >& ul, tk::real, tk::real, tk::real,
+              tk::real, const std::array< tk::real, 3 >& fn )
+    {
+      std::vector< tk::real > ur(5);
+      // Internal cell velocity components
+      auto v1l = ul[1]/ul[0];
+      auto v2l = ul[2]/ul[0];
+      auto v3l = ul[3]/ul[0];
+      // Normal component of velocity
+      auto vnl = v1l*fn[0] + v2l*fn[1] + v3l*fn[2];
+      // Ghost state velocity components
+      auto v1r = v1l - 2.0*vnl*fn[0];
+      auto v2r = v2l - 2.0*vnl*fn[1];
+      auto v3r = v3l - 2.0*vnl*fn[2];
+      // Boundary condition
+      ur[0] = ul[0];
+      ur[1] = ur[0] * v1r;
+      ur[2] = ur[0] * v2r;
+      ur[3] = ur[0] * v3r;
+      ur[4] = ul[4];
+      return {{ std::move(ul), std::move(ur) }};
+    }
+
+    //! \brief Boundary state function providing the left and right state of a
+    //!   face at farfield boundaries
+    //! \param[in] mat_blk EOS material block
+    //! \param[in] ul Left (domain-internal) state
+    //! \param[in] fn Unit face normal
+    //! \return Left and right states for all scalar components in this PDE
+    //!   system
+    //! \note The function signature must follow tk::StateFn
+    static tk::StateFn::result_type
+    farfield( ncomp_t, const std::vector< EOS >& mat_blk,
+              const std::vector< tk::real >& ul, tk::real, tk::real, tk::real,
+              tk::real, const std::array< tk::real, 3 >& fn )
+    {
+      // Primitive variables from farfield
+      const auto& bc = g_inputdeck.get< tag::bc >()[0];
+      auto frho = bc.get< tag::density >();
+      auto fp   = bc.get< tag::pressure >();
+      const auto& fu = bc.get< tag::velocity >();
+
+      // Speed of sound from farfield
+      auto fa = mat_blk[0].compute< EOS::soundspeed >( frho, fp );
+
+      // Normal component from farfield
+      auto fvn = fu[0]*fn[0] + fu[1]*fn[1] + fu[2]*fn[2];
+
+      // Mach number from farfield
+      auto fM = fvn / fa;
+
+      // Specific total energy from farfield
+      auto frhoE = mat_blk[0].compute< EOS::totalenergy >( frho, fu[0], fu[1],
+        fu[2], fp );
+
+      // Pressure from internal cell
+      auto p = mat_blk[0].compute< EOS::pressure >( ul[0], ul[1]/ul[0],
+        ul[2]/ul[0], ul[3]/ul[0], ul[4] );
+
+      auto ur = ul;
+
+      if(fM <= -1)                         // Supersonic inflow<--- Assuming that condition 'fM<=-1' is not redundant<--- Assuming that condition 'fM<=-1' is not redundant<--- Assuming that condition 'fM<=-1' is not redundant
+      {
+        // For supersonic inflow, all the characteristics are from outside.
+        // Therefore, we calculate the ghost cell state using the primitive
+        // variables from outside.
+        ur[0] = frho;
+        ur[1] = frho * fu[0];
+        ur[2] = frho * fu[1];
+        ur[3] = frho * fu[2];
+        ur[4] = frhoE;
+      } else if(fM > -1 && fM < 0)       // Subsonic inflow<--- Condition 'fM>-1' is always true<--- Condition 'fM<0' is always false
+      {
+        // For subsonic inflow, there are 1 outgoing characteristcs and 4
+        // incoming characteristic. Therefore, we calculate the ghost cell state
+        // by taking pressure from the internal cell and other quantities from
+        // the outside.
+        ur[0] = frho;
+        ur[1] = frho * fu[0];
+        ur[2] = frho * fu[1];
+        ur[3] = frho * fu[2];
+        ur[4] = mat_blk[0].compute< EOS::totalenergy >( frho, fu[0], fu[1],
+          fu[2], p );
+      } else if(fM >= 0 && fM < 1)       // Subsonic outflow<--- Condition 'fM>=0' is always true
+      {
+        // For subsonic outflow, there are 1 incoming characteristcs and 4
+        // outgoing characteristic. Therefore, we calculate the ghost cell state
+        // by taking pressure from the outside and other quantities from the
+        // internal cell.
+        ur[4] = mat_blk[0].compute< EOS::totalenergy >( ul[0], ul[1]/ul[0],
+          ul[2]/ul[0], ul[3]/ul[0], fp );
+      }
+      // Otherwise, for supersonic outflow, all the characteristics are from
+      // internal cell. Therefore, we calculate the ghost cell state using the
+      // conservative variables from outside.
+
+      return {{ ul, ur }};
+    }
+
+    //! \brief Boundary state function providing the left and right state of a
+    //!   face at extrapolation boundaries
+    //! \param[in] ul Left (domain-internal) state
+    //! \return Left and right states for all scalar components in this PDE
+    //!   system
+    //! \note The function signature must follow tk::StateFn
+    static tk::StateFn::result_type
+    extrapolate( ncomp_t, const std::vector< EOS >&,
+                 const std::vector< tk::real >& ul, tk::real, tk::real,
+                 tk::real, tk::real, const std::array< tk::real, 3 >& )
+    {
+      return {{ ul, ul }};
+    }
+
+    //! Compute sources corresponding to a propagating front in user-defined box
+    //! \param[in] t Physical time
+    //! \param[in] inpoel Element point connectivity
+    //! \param[in] boxelems Mesh node ids within user-defined box
+    //! \param[in] coord Mesh node coordinates
+    //! \param[in] geoElem Element geometry array
+    //! \param[in] ndofel Vector of local number of degrees of freedome
+    //! \param[in] R Right-hand side vector
+    //! \details This function add the energy source corresponding to a planar
+    //!   wave-front propagating along the z-direction with a user-specified
+    //!   velocity, within a box initial condition, configured by the user.
+    //!   Example (SI) units of the quantities involved:
+    //!    * internal energy content (energy per unit volume): J/m^3
+    //!    * specific energy (internal energy per unit mass): J/kg
+    void boxSrc( tk::real t,
+                 const std::vector< std::size_t >& inpoel,
+                 const std::unordered_set< std::size_t >& boxelems,
+                 const tk::UnsMesh::Coords& coord,
+                 const tk::Fields& geoElem,
+                 const std::vector< std::size_t >& ndofel,
+                 tk::Fields& R ) const
+    {
+      const auto ndof = g_inputdeck.get< tag::ndof >();<--- Variable 'ndof' is assigned a value that is never used.
+      const auto& ic = g_inputdeck.get< tag::ic >();
+      const auto& icbox = ic.get< tag::box >();
+
+      for (const auto& b : icbox) {   // for all boxes for this eq
+        std::vector< tk::real > box
+         { b.template get< tag::xmin >(), b.template get< tag::xmax >(),
+           b.template get< tag::ymin >(), b.template get< tag::ymax >(),
+           b.template get< tag::zmin >(), b.template get< tag::zmax >() };
+
+        auto boxenc = b.template get< tag::energy_content >();
+        Assert( boxenc > 0.0, "Box energy content must be nonzero" );
+
+        auto V_ex = (box[1]-box[0]) * (box[3]-box[2]) * (box[5]-box[4]);
+
+        // determine times at which sourcing is initialized and terminated
+        auto iv = b.template get< tag::front_speed >();
+        auto wFront = 0.1;
+        auto tInit = 0.0;
+        auto tFinal = tInit + (box[5] - box[4] - 2.0*wFront) / std::fabs(iv);
+        auto aBox = (box[1]-box[0]) * (box[3]-box[2]);
+
+        const auto& cx = coord[0];
+        const auto& cy = coord[1];
+        const auto& cz = coord[2];
+
+        if (t >= tInit && t <= tFinal) {
+          // The energy front is assumed to have a half-sine-wave shape. The
+          // half wave-length is the width of the front. At t=0, the center of
+          // this front (i.e. the peak of the partial-sine-wave) is at X_0 +
+          // W_0.  W_0 is calculated based on the width of the front and the
+          // direction of propagation (which is assumed to be along the
+          // z-direction).  If the front propagation velocity is positive, it
+          // is assumed that the initial position of the energy source is the
+          // minimum z-coordinate of the box; whereas if this velocity is
+          // negative, the initial position is the maximum z-coordinate of the
+          // box.
+
+          // Orientation of box
+          std::array< tk::real, 3 > b_orientn{{
+            b.template get< tag::orientation >()[0],
+            b.template get< tag::orientation >()[1],
+            b.template get< tag::orientation >()[2] }};
+          std::array< tk::real, 3 > b_centroid{{ 0.5*(box[0]+box[1]),
+            0.5*(box[2]+box[3]), 0.5*(box[4]+box[5]) }};
+          // Transform box to reference space
+          std::array< tk::real, 3 > b_min{{box[0], box[2], box[4]}};
+          std::array< tk::real, 3 > b_max{{box[1], box[3], box[5]}};
+          tk::movePoint(b_centroid, b_min);
+          tk::movePoint(b_centroid, b_max);
+
+          // initial center of front
+          tk::real zInit(b_min[2]);
+          if (iv < 0.0) zInit = b_max[2];
+          // current location of front
+          auto z0 = zInit + iv*t;
+          auto z1 = z0 + std::copysign(wFront, iv);
+          tk::real s0(z0), s1(z1);
+          // if velocity of propagation is negative, initial position is z1
+          if (iv < 0.0) {
+            s0 = z1;
+            s1 = z0;
+          }
+          // Sine-wave (positive part of the wave) source term amplitude
+          auto pi = 4.0 * std::atan(1.0);
+          auto amplE = boxenc * V_ex * pi
+            / (aBox * wFront * 2.0 * (tFinal-tInit));
+          //// Square wave (constant) source term amplitude
+          //auto amplE = boxenc * V_ex
+          //  / (aBox * wFront * (tFinal-tInit));
+
+          // add source
+          for (auto e : boxelems) {
+            std::array< tk::real, 3 > node{{ geoElem(e,1), geoElem(e,2),
+              geoElem(e,3) }};
+            // Transform node to reference space of box
+            tk::movePoint(b_centroid, node);
+            tk::rotatePoint({{-b_orientn[0], -b_orientn[1], -b_orientn[2]}},
+              node);
+
+            if (node[2] >= s0 && node[2] <= s1) {
+              auto ng = tk::NGvol(ndofel[e]);
+
+              // arrays for quadrature points
+              std::array< std::vector< tk::real >, 3 > coordgp;
+              std::vector< tk::real > wgp;
+
+              coordgp[0].resize( ng );
+              coordgp[1].resize( ng );
+              coordgp[2].resize( ng );
+              wgp.resize( ng );
+
+              tk::GaussQuadratureTet( ng, coordgp, wgp );
+
+              // Extract the element coordinates
+              std::array< std::array< tk::real, 3>, 4 > coordel{{
+              {{ cx[inpoel[4*e  ]], cy[inpoel[4*e  ]], cz[inpoel[4*e  ]] }},
+              {{ cx[inpoel[4*e+1]], cy[inpoel[4*e+1]], cz[inpoel[4*e+1]] }},
+              {{ cx[inpoel[4*e+2]], cy[inpoel[4*e+2]], cz[inpoel[4*e+2]] }},
+              {{ cx[inpoel[4*e+3]], cy[inpoel[4*e+3]], cz[inpoel[4*e+3]] }}}};
+
+              for (std::size_t igp=0; igp<ng; ++igp) {
+                // Compute the coordinates of quadrature point at physical
+                // domain
+                auto gp = tk::eval_gp( igp, coordel, coordgp );
+
+                // Transform quadrature point to reference space of box
+                tk::movePoint(b_centroid, gp);
+                tk::rotatePoint({{-b_orientn[0], -b_orientn[1], -b_orientn[2]}},
+                  gp);
+
+                // Compute the basis function
+                auto B = tk::eval_basis( ndofel[e], coordgp[0][igp],
+                                         coordgp[1][igp], coordgp[2][igp] );
+
+                // Compute the source term variable
+                std::vector< tk::real > s(5, 0.0);
+                s[4] = amplE * std::sin(pi*(gp[2]-s0)/wFront);
+
+                auto wt = wgp[igp] * geoElem(e, 0);
+
+                tk::update_rhs( ndof, ndofel[e], wt, e, B, s, R );
+              }
+            }
+          }
+        }
+      }
+    }
+};
+
+} // dg::
+
+} // inciter::
+
+#endif // DGCompFlow_h
 
diff --git a/Debug/cppcheck/51.html b/Debug/cppcheck/51.html index 577fe70e3226..a6f5b93fe3af 100644 --- a/Debug/cppcheck/51.html +++ b/Debug/cppcheck/51.html @@ -152,1437 +152,2271 @@
- - - - - - - - - - - + + + + + + + + + + - + - + - + - + - + - + @@ -321,18 +321,6 @@ - - - - - - - - - - + + + + + + + + + + - + - + - + - + @@ -49,9 +49,9 @@ - + - +
  1
-  2
-  3
-  4
-  5
-  6
-  7
-  8
-  9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
- 37
- 38
- 39
- 40
- 41
- 42
- 43
- 44
- 45
- 46
- 47
- 48
- 49
- 50
- 51
- 52
- 53
- 54
- 55
- 56
- 57
- 58
- 59
- 60
- 61
- 62
- 63
- 64
- 65
- 66
- 67
- 68
- 69
- 70
- 71
- 72
- 73
- 74
- 75
- 76
- 77
- 78
- 79
- 80
- 81
- 82
- 83
- 84
- 85
- 86
- 87
- 88
- 89
- 90
- 91
- 92
- 93
- 94
- 95
- 96
- 97
- 98
- 99
-100
-101
-102
-103
-104
-105
-106
-107
-108
-109
-110
-111
-112
-113
-114
-115
-116
-117
-118
-119
-120
-121
-122
-123
-124
-125
-126
-127
-128
-129
-130
-131
-132
-133
-134
-135
-136
-137
-138
-139
-140
-141
-142
-143
-144
-145
-146
-147
-148
-149
-150
-151
-152
-153
-154
-155
-156
-157
-158
-159
-160
-161
-162
-163
-164
-165
-166
-167
-168
-169
-170
-171
-172
-173
-174
-175
-176
-177
-178
-179
-180
-181
-182
-183
-184
-185
-186
-187
-188
-189
-190
-191
-192
-193
-194
-195
-196
-197
-198
-199
-200
-201
-202
-203
-204
-205
-206
-207
-208
-209
-210
-211
-212
-213
-214
-215
-216
-217
-218
-219
-220
-221
-222
-223
-224
-225
-226
-227
-228
-229
-230
-231
-232
-233
-234
-235
-236
-237
-238
-239
-240
-241
-242
-243
-244
-245
-246
-247
-248
-249
-250
-251
-252
-253
-254
-255
-256
-257
-258
-259
-260
-261
-262
-263
-264
-265
-266
-267
-268
-269
-270
-271
-272
-273
-274
-275
-276
-277
-278
-279
-280
-281
-282
-283
-284
-285
-286
-287
-288
-289
-290
-291
-292
-293
-294
-295
-296
-297
-298
-299
-300
-301
-302
-303
-304
-305
-306
-307
-308
-309
-310
-311
-312
-313
-314
-315
-316
-317
-318
-319
-320
-321
-322
-323
-324
-325
-326
-327
-328
-329
-330
-331
-332
-333
-334
-335
-336
-337
-338
-339
-340
-341
-342
-343
-344
-345
-346
-347
-348
-349
-350
-351
-352
-353
-354
-355
-356
-357
-358
-359
-360
-361
-362
-363
-364
-365
-366
-367
-368
-369
-370
-371
-372
-373
-374
-375
-376
-377
-378
-379
-380
-381
-382
-383
-384
-385
-386
-387
-388
-389
-390
-391
-392
-393
-394
-395
-396
-397
-398
-399
-400
-401
-402
-403
-404
-405
-406
-407
-408
-409
-410
-411
-412
-413
-414
-415
-416
-417
-418
-419
-420
-421
-422
-423
-424
-425
-426
-427
-428
-429
-430
-431
-432
-433
-434
-435
-436
-437
-438
-439
-440
-441
-442
-443
-444
-445
-446
-447
-448
-449
-450
-451
-452
-453
-454
-455
-456
-457
-458
-459
-460
-461
-462
-463
-464
-465
-466
-467
-468
-469
-470
-471
-472
-473
-474
-475
-476
-477
-478
-479
-480
-481
-482
-483
-484
-485
-486
-487
-488
-489
-490
-491
-492
-493
-494
-495
-496
-497
-498
-499
-500
-501
-502
-503
-504
-505
-506
-507
-508
-509
-510
-511
-512
-513
-514
-515
-516
-517
-518
-519
-520
-521
-522
-523
-524
-525
-526
-527
-528
-529
-530
-531
-532
-533
-534
-535
-536
-537
-538
-539
-540
-541
-542
-543
-544
-545
-546
-547
-548
-549
-550
-551
-552
-553
-554
-555
-556
-557
-558
-559
-560
-561
-562
-563
-564
-565
-566
-567
-568
-569
-570
-571
-572
-573
-574
-575
-576
-577
-578
-579
-580
-581
-582
-583
-584
-585
-586
-587
-588
-589
-590
-591
-592
-593
-594
-595
-596
-597
-598
-599
-600
-601
-602
-603
-604
-605
-606
-607
-608
-609
-610
-611
-612
-613
-614
-615
-616
-617
-618
-619
-620
-621
-622
-623
-624
-625
-626
-627
-628
-629
-630
-631
-632
-633
-634
-635
-636
-637
-638
-639
-640
-641
-642
-643
-644
-645
-646
-647
-648
-649
-650
-651
-652
-653
-654
-655
-656
-657
-658
-659
-660
-661
-662
-663
-664
-665
-666
-667
-668
-669
-670
-671
-672
-673
-674
-675
-676
-677
-678
-679
-680
-681
-682
-683
-684
-685
-686
-687
-688
-689
-690
-691
-692
-693
-694
-695
-696
-697
-698
-699
-700
-701
-702
-703
-704
-705
-706
-707
-708
-709
-710
-711
-712
// *****************************************************************************
+
   1
+   2
+   3
+   4
+   5
+   6
+   7
+   8
+   9
+  10
+  11
+  12
+  13
+  14
+  15
+  16
+  17
+  18
+  19
+  20
+  21
+  22
+  23
+  24
+  25
+  26
+  27
+  28
+  29
+  30
+  31
+  32
+  33
+  34
+  35
+  36
+  37
+  38
+  39
+  40
+  41
+  42
+  43
+  44
+  45
+  46
+  47
+  48
+  49
+  50
+  51
+  52
+  53
+  54
+  55
+  56
+  57
+  58
+  59
+  60
+  61
+  62
+  63
+  64
+  65
+  66
+  67
+  68
+  69
+  70
+  71
+  72
+  73
+  74
+  75
+  76
+  77
+  78
+  79
+  80
+  81
+  82
+  83
+  84
+  85
+  86
+  87
+  88
+  89
+  90
+  91
+  92
+  93
+  94
+  95
+  96
+  97
+  98
+  99
+ 100
+ 101
+ 102
+ 103
+ 104
+ 105
+ 106
+ 107
+ 108
+ 109
+ 110
+ 111
+ 112
+ 113
+ 114
+ 115
+ 116
+ 117
+ 118
+ 119
+ 120
+ 121
+ 122
+ 123
+ 124
+ 125
+ 126
+ 127
+ 128
+ 129
+ 130
+ 131
+ 132
+ 133
+ 134
+ 135
+ 136
+ 137
+ 138
+ 139
+ 140
+ 141
+ 142
+ 143
+ 144
+ 145
+ 146
+ 147
+ 148
+ 149
+ 150
+ 151
+ 152
+ 153
+ 154
+ 155
+ 156
+ 157
+ 158
+ 159
+ 160
+ 161
+ 162
+ 163
+ 164
+ 165
+ 166
+ 167
+ 168
+ 169
+ 170
+ 171
+ 172
+ 173
+ 174
+ 175
+ 176
+ 177
+ 178
+ 179
+ 180
+ 181
+ 182
+ 183
+ 184
+ 185
+ 186
+ 187
+ 188
+ 189
+ 190
+ 191
+ 192
+ 193
+ 194
+ 195
+ 196
+ 197
+ 198
+ 199
+ 200
+ 201
+ 202
+ 203
+ 204
+ 205
+ 206
+ 207
+ 208
+ 209
+ 210
+ 211
+ 212
+ 213
+ 214
+ 215
+ 216
+ 217
+ 218
+ 219
+ 220
+ 221
+ 222
+ 223
+ 224
+ 225
+ 226
+ 227
+ 228
+ 229
+ 230
+ 231
+ 232
+ 233
+ 234
+ 235
+ 236
+ 237
+ 238
+ 239
+ 240
+ 241
+ 242
+ 243
+ 244
+ 245
+ 246
+ 247
+ 248
+ 249
+ 250
+ 251
+ 252
+ 253
+ 254
+ 255
+ 256
+ 257
+ 258
+ 259
+ 260
+ 261
+ 262
+ 263
+ 264
+ 265
+ 266
+ 267
+ 268
+ 269
+ 270
+ 271
+ 272
+ 273
+ 274
+ 275
+ 276
+ 277
+ 278
+ 279
+ 280
+ 281
+ 282
+ 283
+ 284
+ 285
+ 286
+ 287
+ 288
+ 289
+ 290
+ 291
+ 292
+ 293
+ 294
+ 295
+ 296
+ 297
+ 298
+ 299
+ 300
+ 301
+ 302
+ 303
+ 304
+ 305
+ 306
+ 307
+ 308
+ 309
+ 310
+ 311
+ 312
+ 313
+ 314
+ 315
+ 316
+ 317
+ 318
+ 319
+ 320
+ 321
+ 322
+ 323
+ 324
+ 325
+ 326
+ 327
+ 328
+ 329
+ 330
+ 331
+ 332
+ 333
+ 334
+ 335
+ 336
+ 337
+ 338
+ 339
+ 340
+ 341
+ 342
+ 343
+ 344
+ 345
+ 346
+ 347
+ 348
+ 349
+ 350
+ 351
+ 352
+ 353
+ 354
+ 355
+ 356
+ 357
+ 358
+ 359
+ 360
+ 361
+ 362
+ 363
+ 364
+ 365
+ 366
+ 367
+ 368
+ 369
+ 370
+ 371
+ 372
+ 373
+ 374
+ 375
+ 376
+ 377
+ 378
+ 379
+ 380
+ 381
+ 382
+ 383
+ 384
+ 385
+ 386
+ 387
+ 388
+ 389
+ 390
+ 391
+ 392
+ 393
+ 394
+ 395
+ 396
+ 397
+ 398
+ 399
+ 400
+ 401
+ 402
+ 403
+ 404
+ 405
+ 406
+ 407
+ 408
+ 409
+ 410
+ 411
+ 412
+ 413
+ 414
+ 415
+ 416
+ 417
+ 418
+ 419
+ 420
+ 421
+ 422
+ 423
+ 424
+ 425
+ 426
+ 427
+ 428
+ 429
+ 430
+ 431
+ 432
+ 433
+ 434
+ 435
+ 436
+ 437
+ 438
+ 439
+ 440
+ 441
+ 442
+ 443
+ 444
+ 445
+ 446
+ 447
+ 448
+ 449
+ 450
+ 451
+ 452
+ 453
+ 454
+ 455
+ 456
+ 457
+ 458
+ 459
+ 460
+ 461
+ 462
+ 463
+ 464
+ 465
+ 466
+ 467
+ 468
+ 469
+ 470
+ 471
+ 472
+ 473
+ 474
+ 475
+ 476
+ 477
+ 478
+ 479
+ 480
+ 481
+ 482
+ 483
+ 484
+ 485
+ 486
+ 487
+ 488
+ 489
+ 490
+ 491
+ 492
+ 493
+ 494
+ 495
+ 496
+ 497
+ 498
+ 499
+ 500
+ 501
+ 502
+ 503
+ 504
+ 505
+ 506
+ 507
+ 508
+ 509
+ 510
+ 511
+ 512
+ 513
+ 514
+ 515
+ 516
+ 517
+ 518
+ 519
+ 520
+ 521
+ 522
+ 523
+ 524
+ 525
+ 526
+ 527
+ 528
+ 529
+ 530
+ 531
+ 532
+ 533
+ 534
+ 535
+ 536
+ 537
+ 538
+ 539
+ 540
+ 541
+ 542
+ 543
+ 544
+ 545
+ 546
+ 547
+ 548
+ 549
+ 550
+ 551
+ 552
+ 553
+ 554
+ 555
+ 556
+ 557
+ 558
+ 559
+ 560
+ 561
+ 562
+ 563
+ 564
+ 565
+ 566
+ 567
+ 568
+ 569
+ 570
+ 571
+ 572
+ 573
+ 574
+ 575
+ 576
+ 577
+ 578
+ 579
+ 580
+ 581
+ 582
+ 583
+ 584
+ 585
+ 586
+ 587
+ 588
+ 589
+ 590
+ 591
+ 592
+ 593
+ 594
+ 595
+ 596
+ 597
+ 598
+ 599
+ 600
+ 601
+ 602
+ 603
+ 604
+ 605
+ 606
+ 607
+ 608
+ 609
+ 610
+ 611
+ 612
+ 613
+ 614
+ 615
+ 616
+ 617
+ 618
+ 619
+ 620
+ 621
+ 622
+ 623
+ 624
+ 625
+ 626
+ 627
+ 628
+ 629
+ 630
+ 631
+ 632
+ 633
+ 634
+ 635
+ 636
+ 637
+ 638
+ 639
+ 640
+ 641
+ 642
+ 643
+ 644
+ 645
+ 646
+ 647
+ 648
+ 649
+ 650
+ 651
+ 652
+ 653
+ 654
+ 655
+ 656
+ 657
+ 658
+ 659
+ 660
+ 661
+ 662
+ 663
+ 664
+ 665
+ 666
+ 667
+ 668
+ 669
+ 670
+ 671
+ 672
+ 673
+ 674
+ 675
+ 676
+ 677
+ 678
+ 679
+ 680
+ 681
+ 682
+ 683
+ 684
+ 685
+ 686
+ 687
+ 688
+ 689
+ 690
+ 691
+ 692
+ 693
+ 694
+ 695
+ 696
+ 697
+ 698
+ 699
+ 700
+ 701
+ 702
+ 703
+ 704
+ 705
+ 706
+ 707
+ 708
+ 709
+ 710
+ 711
+ 712
+ 713
+ 714
+ 715
+ 716
+ 717
+ 718
+ 719
+ 720
+ 721
+ 722
+ 723
+ 724
+ 725
+ 726
+ 727
+ 728
+ 729
+ 730
+ 731
+ 732
+ 733
+ 734
+ 735
+ 736
+ 737
+ 738
+ 739
+ 740
+ 741
+ 742
+ 743
+ 744
+ 745
+ 746
+ 747
+ 748
+ 749
+ 750
+ 751
+ 752
+ 753
+ 754
+ 755
+ 756
+ 757
+ 758
+ 759
+ 760
+ 761
+ 762
+ 763
+ 764
+ 765
+ 766
+ 767
+ 768
+ 769
+ 770
+ 771
+ 772
+ 773
+ 774
+ 775
+ 776
+ 777
+ 778
+ 779
+ 780
+ 781
+ 782
+ 783
+ 784
+ 785
+ 786
+ 787
+ 788
+ 789
+ 790
+ 791
+ 792
+ 793
+ 794
+ 795
+ 796
+ 797
+ 798
+ 799
+ 800
+ 801
+ 802
+ 803
+ 804
+ 805
+ 806
+ 807
+ 808
+ 809
+ 810
+ 811
+ 812
+ 813
+ 814
+ 815
+ 816
+ 817
+ 818
+ 819
+ 820
+ 821
+ 822
+ 823
+ 824
+ 825
+ 826
+ 827
+ 828
+ 829
+ 830
+ 831
+ 832
+ 833
+ 834
+ 835
+ 836
+ 837
+ 838
+ 839
+ 840
+ 841
+ 842
+ 843
+ 844
+ 845
+ 846
+ 847
+ 848
+ 849
+ 850
+ 851
+ 852
+ 853
+ 854
+ 855
+ 856
+ 857
+ 858
+ 859
+ 860
+ 861
+ 862
+ 863
+ 864
+ 865
+ 866
+ 867
+ 868
+ 869
+ 870
+ 871
+ 872
+ 873
+ 874
+ 875
+ 876
+ 877
+ 878
+ 879
+ 880
+ 881
+ 882
+ 883
+ 884
+ 885
+ 886
+ 887
+ 888
+ 889
+ 890
+ 891
+ 892
+ 893
+ 894
+ 895
+ 896
+ 897
+ 898
+ 899
+ 900
+ 901
+ 902
+ 903
+ 904
+ 905
+ 906
+ 907
+ 908
+ 909
+ 910
+ 911
+ 912
+ 913
+ 914
+ 915
+ 916
+ 917
+ 918
+ 919
+ 920
+ 921
+ 922
+ 923
+ 924
+ 925
+ 926
+ 927
+ 928
+ 929
+ 930
+ 931
+ 932
+ 933
+ 934
+ 935
+ 936
+ 937
+ 938
+ 939
+ 940
+ 941
+ 942
+ 943
+ 944
+ 945
+ 946
+ 947
+ 948
+ 949
+ 950
+ 951
+ 952
+ 953
+ 954
+ 955
+ 956
+ 957
+ 958
+ 959
+ 960
+ 961
+ 962
+ 963
+ 964
+ 965
+ 966
+ 967
+ 968
+ 969
+ 970
+ 971
+ 972
+ 973
+ 974
+ 975
+ 976
+ 977
+ 978
+ 979
+ 980
+ 981
+ 982
+ 983
+ 984
+ 985
+ 986
+ 987
+ 988
+ 989
+ 990
+ 991
+ 992
+ 993
+ 994
+ 995
+ 996
+ 997
+ 998
+ 999
+1000
+1001
+1002
+1003
+1004
+1005
+1006
+1007
+1008
+1009
+1010
+1011
+1012
+1013
+1014
+1015
+1016
+1017
+1018
+1019
+1020
+1021
+1022
+1023
+1024
+1025
+1026
+1027
+1028
+1029
+1030
+1031
+1032
+1033
+1034
+1035
+1036
+1037
+1038
+1039
+1040
+1041
+1042
+1043
+1044
+1045
+1046
+1047
+1048
+1049
+1050
+1051
+1052
+1053
+1054
+1055
+1056
+1057
+1058
+1059
+1060
+1061
+1062
+1063
+1064
+1065
+1066
+1067
+1068
+1069
+1070
+1071
+1072
+1073
+1074
+1075
+1076
+1077
+1078
+1079
+1080
+1081
+1082
+1083
+1084
+1085
+1086
+1087
+1088
+1089
+1090
+1091
+1092
+1093
+1094
+1095
+1096
+1097
+1098
+1099
+1100
+1101
+1102
+1103
+1104
+1105
+1106
+1107
+1108
+1109
+1110
+1111
+1112
+1113
+1114
+1115
+1116
+1117
+1118
+1119
+1120
+1121
+1122
+1123
+1124
+1125
+1126
+1127
+1128
+1129
// *****************************************************************************
 /*!
-  \file      src/PDE/Transport/DGTransport.hpp
+  \file      src/Inciter/FV.cpp
   \copyright 2012-2015 J. Bakosi,
              2016-2018 Los Alamos National Security, LLC.,
              2019-2021 Triad National Security, LLC.
              All rights reserved. See the LICENSE file for details.
-  \brief     Scalar transport using disccontinous Galerkin discretization
-  \details   This file implements the physics operators governing transported
-     scalars using disccontinuous Galerkin discretization.
-*/
-// *****************************************************************************
-#ifndef DGTransport_h
-#define DGTransport_h
-
-#include <vector>
-#include <array>
-#include <limits>
-#include <cmath>
-#include <unordered_set>
-#include <map>
-
-#include "Macro.hpp"
-#include "Exception.hpp"
-#include "Vector.hpp"
-#include "UnsMesh.hpp"
-#include "Integrate/Basis.hpp"
-#include "Integrate/Quadrature.hpp"
-#include "Integrate/Initialize.hpp"
-#include "Integrate/Mass.hpp"
-#include "Integrate/Surface.hpp"
-#include "Integrate/Boundary.hpp"
-#include "Integrate/Volume.hpp"
-#include "Riemann/Upwind.hpp"
-#include "Reconstruction.hpp"
-#include "Limiter.hpp"
-#include "PrefIndicator.hpp"
-#include "EoS/EOS.hpp"
-#include "FunctionPrototypes.hpp"
-#include "ConfigureTransport.hpp"
-
-namespace inciter {
-
-extern ctr::InputDeck g_inputdeck;
-
-namespace dg {
-
-//! \brief Transport equation used polymorphically with tk::DGPDE
-//! \details The template argument(s) specify policies and are used to configure
-//!   the behavior of the class. The policies are:
-//!   - Physics - physics configuration, see PDE/Transport/Physics.h
-//!   - Problem - problem configuration, see PDE/Transport/Problem.h
-//! \note The default physics is DGAdvection, set in
-//!    inciter::deck::check_transport()
-template< class Physics, class Problem >
-class Transport {
-
-  private:
-    using eq = tag::transport;
-
-  public:
-    //! Constructor
-    explicit Transport() :
-      m_physics( Physics() ),
-      m_problem( Problem() ),
-      m_ncomp( g_inputdeck.get< tag::ncomp >() )
-    {
-      // associate boundary condition configurations with state functions, the
-      // order in which the state functions listed matters, see ctr::bc::Keys
-      brigand::for_each< ctr::bclist::Keys >( ConfigBC( m_bc,
-        { dirichlet
-        , invalidBC  // Symmetry BC not implemented
-        , inlet
-        , outlet
-        , invalidBC  // Characteristic BC not implemented
-        , extrapolate } ) );
-      m_problem.errchk( m_ncomp );
-    }
-
-    //! Find the number of primitive quantities required for this PDE system
-    //! \return The number of primitive quantities required to be stored for
-    //!   this PDE system
-    std::size_t nprim() const
-    {
-      // transport does not need/store any primitive quantities currently
-      return 0;
-    }
-
-    //! Find the number of materials set up for this PDE system
-    //! \return The number of materials set up for this PDE system
-    std::size_t nmat() const
-    {
-      return m_ncomp;
-    }
-
-    //! Assign number of DOFs per equation in the PDE system
-    //! \param[in,out] numEqDof Array storing number of Dofs for each PDE
-    //!   equation
-    void numEquationDofs(std::vector< std::size_t >& numEqDof) const
-    {
-      // all equation-dofs initialized to ndofs
-      for (std::size_t i=0; i<m_ncomp; ++i) {
-        numEqDof.push_back(g_inputdeck.get< tag::ndof >());
-      }
-    }
-
-    //! Find how 'stiff equations', which we currently
-    //! have none for Transport
-    //! \return number of stiff equations
-    std::size_t nstiffeq() const
-    { return 0; }
-
-    //! Find how 'nonstiff equations', which we currently
-    //! don't use for Transport
-    //! \return number of non-stiff equations
-    std::size_t nnonstiffeq() const
-    { return 0; }
-
-    //! Locate the stiff equations. Unused for transport.
-    //! \param[out] stiffEqIdx list
-    void setStiffEqIdx( std::vector< std::size_t >& stiffEqIdx ) const
-    {
-      stiffEqIdx.resize(0);
-    }
-
-    //! Locate the nonstiff equations. Unused for transport.
-    //! \param[out] nonStiffEqIdx list
-    void setNonStiffEqIdx( std::vector< std::size_t >& nonStiffEqIdx ) const
-    {
-      nonStiffEqIdx.resize(0);
-    }
-
-    //! Determine elements that lie inside the user-defined IC box
-    void IcBoxElems( const tk::Fields&,
-      std::size_t,
-      std::vector< std::unordered_set< std::size_t > >& ) const
-    {}
-
-    //! Initalize the transport equations for DG
-    //! \param[in] L Element mass matrix
-    //! \param[in] inpoel Element-node connectivity
-    //! \param[in] coord Array of nodal coordinates
-    //! \param[in,out] unk Array of unknowns
-    //! \param[in] t Physical time
-    //! \param[in] nielem Number of internal elements
-    void
-    initialize(
-      const tk::Fields& L,
-      const std::vector< std::size_t >& inpoel,
-      const tk::UnsMesh::Coords& coord,
-      const std::vector< std::unordered_set< std::size_t > >& /*inbox*/,
-      const std::unordered_map< std::size_t, std::set< std::size_t > >&,
-      tk::Fields& unk,
-      tk::real t,
-      const std::size_t nielem ) const
-    {
-      tk::initialize( m_ncomp, m_mat_blk, L, inpoel, coord,
-                      Problem::initialize, unk, t, nielem );
-    }
-
-    //! Save initial densities for all materials
-    //! \param[out] rho0mat List of initial densities
-    void setRho0mat( std::vector< tk::real >& rho0mat ) const
-    {
-      rho0mat.resize(0);
-    }
-
-    //! Compute density constraint for a given material
-    // //! \param[in] nelem Number of elements
-    // //! \param[in] unk Array of unknowns
-    // //! \param[in] rho0mat List of initial densities
-    //! \param[out] densityConstr Density Constraint: rho/(rho0*det(g))
-    void computeDensityConstr( std::size_t /*nelem*/,
-                               tk::Fields& /*unk*/,
-                               std::vector< tk::real >& /*rho0mat*/,
-                               std::vector< tk::real >& densityConstr) const
-    {
-      densityConstr.resize(0);
-    }
-
-    //! Compute the left hand side mass matrix
-    //! \param[in] geoElem Element geometry array
-    //! \param[in,out] l Block diagonal mass matrix
-    void lhs( const tk::Fields& geoElem, tk::Fields& l ) const {
-      const auto ndof = g_inputdeck.get< tag::ndof >();
-      tk::mass( m_ncomp, ndof, geoElem, l );
-    }
-
-    //! Update the interface cells to first order dofs
-    //! \details This function resets the high-order terms in interface cells,
-    //!   and is currently not used in transport.
-    void updateInterfaceCells( tk::Fields&,
-      std::size_t,
-      std::vector< std::size_t >& ) const {}
+  \brief     FV advances a system of PDEs with the finite volume scheme
+  \details   FV advances a system of partial differential equations (PDEs) using
+    the finite volume (FV) (on tetrahedron elements).
+  \see The documentation in FV.h.
+*/
+// *****************************************************************************
+
+#include <algorithm>
+#include <numeric>
+#include <sstream>
+
+#include "FV.hpp"
+#include "Discretization.hpp"
+#include "FVPDE.hpp"
+#include "DiagReducer.hpp"
+#include "DerivedData.hpp"
+#include "ElemDiagnostics.hpp"
+#include "Inciter/InputDeck/InputDeck.hpp"
+#include "Refiner.hpp"
+#include "Limiter.hpp"
+#include "PrefIndicator.hpp"
+#include "Reorder.hpp"
+#include "Vector.hpp"
+#include "Around.hpp"
+#include "Integrate/Basis.hpp"
+#include "FieldOutput.hpp"
+#include "ChareStateCollector.hpp"
+
+namespace inciter {
+
+extern ctr::InputDeck g_inputdeck;
+extern std::vector< FVPDE > g_fvpde;
+
+} // inciter::
+
+extern tk::CProxy_ChareStateCollector stateProxy;
+
+using inciter::FV;
+
+FV::FV( const CProxy_Discretization& disc,
+        const CProxy_Ghosts& ghostsproxy,
+        const std::map< int, std::vector< std::size_t > >& bface,
+        const std::map< int, std::vector< std::size_t > >& /* bnode */,
+        const std::vector< std::size_t >& triinpoel ) :
+  m_disc( disc ),
+  m_ghosts( ghostsproxy ),
+  m_nsol( 0 ),
+  m_ninitsol( 0 ),
+  m_nlim( 0 ),
+  m_nnod( 0 ),
+  m_u( Disc()->Inpoel().size()/4,
+       g_inputdeck.get< tag::rdof >()*
+       g_inputdeck.get< tag::ncomp >() ),
+  m_un( m_u.nunk(), m_u.nprop() ),
+  m_p( m_u.nunk(), g_inputdeck.get< tag::rdof >()*
+    g_fvpde[Disc()->MeshId()].nprim() ),
+  m_lhs( m_u.nunk(),
+         g_inputdeck.get< tag::ncomp >() ),
+  m_rhs( m_u.nunk(), m_lhs.nprop() ),
+  m_npoin( Disc()->Coord()[0].size() ),
+  m_diag(),
+  m_stage( 0 ),
+  m_uc(),
+  m_pc(),
+  m_initial( 1 ),
+  m_uElemfields( m_u.nunk(), m_lhs.nprop() ),
+  m_pElemfields(m_u.nunk(),
+    m_p.nprop()/g_inputdeck.get< tag::rdof >()),
+  m_uNodefields( m_npoin, m_lhs.nprop() ),
+  m_pNodefields(m_npoin,
+    m_p.nprop()/g_inputdeck.get< tag::rdof >()),
+  m_uNodefieldsc(),
+  m_pNodefieldsc(),
+  m_boxelems(),
+  m_srcFlag(m_u.nunk(), 0),
+  m_nrk(0),
+  m_dte(m_u.nunk(), 0.0),
+  m_finished(0)
+// *****************************************************************************
+//  Constructor
+//! \param[in] disc Discretization proxy
+//! \param[in] bface Boundary-faces mapped to side set ids
+//! \param[in] triinpoel Boundary-face connectivity
+// *****************************************************************************
+{
+  //! Runge-Kutta coefficients
+  m_nrk = 2;
+  m_rkcoef[0].resize(m_nrk);
+  m_rkcoef[1].resize(m_nrk);
+  if (m_nrk == 2) {
+    m_rkcoef = {{ {{ 0.0, 1.0/2.0 }}, {{ 1.0, 1.0/2.0 }} }};
+  }
+  else {
+    m_rkcoef = {{ {{ 0.0, 3.0/4.0, 1.0/3.0 }}, {{ 1.0, 1.0/4.0, 2.0/3.0 }} }};
+  }
+
+  if (g_inputdeck.get< tag::cmd, tag::chare >() ||
+      g_inputdeck.get< tag::cmd, tag::quiescence >())
+    stateProxy.ckLocalBranch()->insert( "FV", thisIndex, CkMyPe(), Disc()->It(),
+                                        "FV" );
+
+  usesAtSync = true;    // enable migration at AtSync
+
+  // Enable SDAG wait for initially building the solution vector and limiting
+  if (m_initial) {
+    thisProxy[ thisIndex ].wait4sol();
+    thisProxy[ thisIndex ].wait4lim();
+    thisProxy[ thisIndex ].wait4nod();
+  }
+
+  m_ghosts[thisIndex].insert(m_disc, bface, triinpoel, m_u.nunk(),
+    CkCallback(CkIndex_FV::resizeSolVectors(), thisProxy[thisIndex]));
+
+  // global-sync to call doneInserting on m_ghosts
+  auto meshid = Disc()->MeshId();
+  contribute( sizeof(std::size_t), &meshid, CkReduction::nop,
+    CkCallback(CkReductionTarget(Transporter,doneInsertingGhosts),
+    Disc()->Tr()) );
+}
+
+void
+FV::registerReducers()
+// *****************************************************************************
+//  Configure Charm++ reduction types
+//! \details Since this is a [initnode] routine, the runtime system executes the
+//!   routine exactly once on every logical node early on in the Charm++ init
+//!   sequence. Must be static as it is called without an object. See also:
+//!   Section "Initializations at Program Startup" at in the Charm++ manual
+//!   http://charm.cs.illinois.edu/manuals/html/charm++/manual.html.
+// *****************************************************************************
+{
+  ElemDiagnostics::registerReducers();
+}
+
+void
+FV::ResumeFromSync()
+// *****************************************************************************
+//  Return from migration
+//! \details This is called when load balancing (LB) completes. The presence of
+//!   this function does not affect whether or not we block on LB.
+// *****************************************************************************
+{
+  if (Disc()->It() == 0) Throw( "it = 0 in ResumeFromSync()" );
+
+  if (!g_inputdeck.get< tag::cmd, tag::nonblocking >()) next();
+}
+
+void
+FV::resizeSolVectors()
+// *****************************************************************************
+// Resize solution vectors after extension due to Ghosts
+// *****************************************************************************
+{
+  // Resize solution vectors, lhs and rhs by the number of ghost tets
+  m_u.resize( myGhosts()->m_nunk );
+  m_un.resize( myGhosts()->m_nunk );
+  m_srcFlag.resize( myGhosts()->m_nunk );
+  m_p.resize( myGhosts()->m_nunk );
+  m_lhs.resize( myGhosts()->m_nunk );
+  m_rhs.resize( myGhosts()->m_nunk );
+  m_dte.resize( myGhosts()->m_nunk );
+
+  // Size communication buffer for solution
+  for (auto& u : m_uc) u.resize( myGhosts()->m_bid.size() );
+  for (auto& p : m_pc) p.resize( myGhosts()->m_bid.size() );
+
+  // Ensure that we also have all the geometry and connectivity data
+  // (including those of ghosts)
+  Assert( myGhosts()->m_geoElem.nunk() == m_u.nunk(),
+    "GeoElem unknowns size mismatch" );
+
+  // Signal the runtime system that all workers have received their adjacency
+  std::vector< std::size_t > meshdata{ myGhosts()->m_initial, Disc()->MeshId() };
+  contribute( meshdata, CkReduction::sum_ulong,
+    CkCallback(CkReductionTarget(Transporter,comfinal), Disc()->Tr()) );
+}
+
+void
+FV::setup()
+// *****************************************************************************
+// Set initial conditions, generate lhs, output mesh
+// *****************************************************************************
+{
+  if (g_inputdeck.get< tag::cmd, tag::chare >() ||
+      g_inputdeck.get< tag::cmd, tag::quiescence >())
+    stateProxy.ckLocalBranch()->insert( "FV", thisIndex, CkMyPe(), Disc()->It(),
+                                        "setup" );
 
-    //! Update the primitives for this PDE system
-    //! \details This function computes and stores the dofs for primitive
-    //!   quantities, which are currently unused for transport.
-    void updatePrimitives( const tk::Fields&,
-                           const tk::Fields&,
-                           const tk::Fields&,
-                           tk::Fields&,
-                           std::size_t ) const {}
+  auto d = Disc();<--- Variable 'd' is assigned a value that is never used.
+
+  // Basic error checking on sizes of element geometry data and connectivity
+  Assert( myGhosts()->m_geoElem.nunk() == m_lhs.nunk(),
+    "Size mismatch in FV::setup()" );
+
+  // Compute left-hand side of discrete PDEs
+  lhs();
 
-    //! Clean up the state of trace materials for this PDE system
-    //! \details This function cleans up the state of materials present in trace
-    //!   quantities in each cell. This is currently unused for transport.
-    void cleanTraceMaterial( tk::real,
-                             const tk::Fields&,
-                             tk::Fields&,
-                             tk::Fields&,
-                             std::size_t ) const {}
-
-    //! Reconstruct second-order solution from first-order
-    //! \param[in] t Physical time
-    //! \param[in] geoFace Face geometry array
-    //! \param[in] geoElem Element geometry array
-    //! \param[in] fd Face connectivity and boundary conditions object
-    //! \param[in] esup Elements-surrounding-nodes connectivity
-    //! \param[in] inpoel Element-node connectivity
-    //! \param[in] coord Array of nodal coordinates
-    //! \param[in,out] U Solution vector at recent time step
-    //! \param[in,out] P Primitive vector at recent time step
-    void reconstruct( tk::real t,
-                      const tk::Fields& geoFace,
-                      const tk::Fields& geoElem,
-                      const inciter::FaceData& fd,
-                      const std::map< std::size_t, std::vector< std::size_t > >&
-                        esup,
-                      const std::vector< std::size_t >& inpoel,
-                      const tk::UnsMesh::Coords& coord,
-                      tk::Fields& U,
-                      tk::Fields& P ) const
-    {
-      const auto rdof = g_inputdeck.get< tag::rdof >();
-
-      // do reconstruction only if P0P1
-      if (rdof == 4 && g_inputdeck.get< tag::ndof >() == 1) {
-        const auto nelem = fd.Esuel().size()/4;<--- Variable 'nelem' is assigned a value that is never used.
-        const auto intsharp = g_inputdeck.get< tag::transport,<--- Variable 'intsharp' is assigned a value that is never used.
-          tag::intsharp >();
+  // Determine elements inside user-defined IC box
+  g_fvpde[d->MeshId()].IcBoxElems( myGhosts()->m_geoElem,
+    myGhosts()->m_fd.Esuel().size()/4, m_boxelems );
+
+  // Compute volume of user-defined box IC
+  d->boxvol( {}, {}, 0 );      // punt for now
+
+  // Query time history field output labels from all PDEs integrated
+  const auto& hist_points = g_inputdeck.get< tag::history_output, tag::point >();
+  if (!hist_points.empty()) {
+    std::vector< std::string > histnames;
+    auto n = g_fvpde[d->MeshId()].histNames();
+    histnames.insert( end(histnames), begin(n), end(n) );
+    d->histheader( std::move(histnames) );
+  }
+}
+
+void
+FV::box( tk::real v, const std::vector< tk::real >& )
+// *****************************************************************************
+// Receive total box IC volume and set conditions in box
+//! \param[in] v Total volume within user-specified box
+// *****************************************************************************
+{
+  auto d = Disc();
+
+  // Store user-defined box IC volume
+  d->Boxvol() = v;
+
+  // Set initial conditions for all PDEs
+  g_fvpde[d->MeshId()].initialize( m_lhs, myGhosts()->m_inpoel,
+    myGhosts()->m_coord, m_boxelems, d->ElemBlockId(), m_u, d->T(),
+    myGhosts()->m_fd.Esuel().size()/4 );
+  g_fvpde[d->MeshId()].updatePrimitives( m_u, m_p,
+    myGhosts()->m_fd.Esuel().size()/4 );
+
+  m_un = m_u;
 
-        Assert( U.nprop() == rdof*m_ncomp, "Number of components in solution "
-                "vector must equal "+ std::to_string(rdof*m_ncomp) );
-        Assert( fd.Inpofa().size()/3 == fd.Esuf().size()/2,
-                "Mismatch in inpofa size" );
-
-        // allocate and initialize matrix and vector for reconstruction
-        std::vector< std::array< std::array< tk::real, 3 >, 3 > >
-          lhs_ls( nelem, {{ {{0.0, 0.0, 0.0}},
-                            {{0.0, 0.0, 0.0}},
-                            {{0.0, 0.0, 0.0}} }} );
-        // specify how many variables need to be reconstructed
-        std::vector< std::size_t > vars;
-        for (std::size_t c=0; c<m_ncomp; ++c) vars.push_back(c);
-
-        std::vector< std::vector< std::array< tk::real, 3 > > >
-          rhs_ls( nelem, std::vector< std::array< tk::real, 3 > >
-            ( m_ncomp,
-              {{ 0.0, 0.0, 0.0 }} ) );
-
-        // reconstruct x,y,z-derivatives of unknowns
-        // 0. get lhs matrix, which is only geometry dependent
-        tk::lhsLeastSq_P0P1(fd, geoElem, geoFace, lhs_ls);
-
-        // 1. internal face contributions
-        tk::intLeastSq_P0P1( rdof, fd, geoElem, U, rhs_ls, vars );
-
-        // 2. boundary face contributions
-        for (const auto& b : m_bc)
-          tk::bndLeastSqConservedVar_P0P1( m_ncomp, 
-            m_mat_blk, rdof, b.first, fd, geoFace, geoElem, t, b.second, 
-            P, U, rhs_ls, vars );
+  // Output initial conditions to file (regardless of whether it was requested)
+  startFieldOutput( CkCallback(CkIndex_FV::start(), thisProxy[thisIndex]) );
+}
+
+void
+FV::start()
+// *****************************************************************************
+//  Start time stepping
+// *****************************************************************************
+{
+  // Start timer measuring time stepping wall clock time
+  Disc()->Timer().zero();
+  // Zero grind-timer
+  Disc()->grindZero();
+  // Start time stepping by computing the size of the next time step)
+  next();
+}
+
+void
+FV::startFieldOutput( CkCallback c )
+// *****************************************************************************
+// Start preparing fields for output to file
+//! \param[in] c Function to continue with after the write
+// *****************************************************************************
+{
+  // No field output in benchmark mode or if field output frequency not hit
+  if (g_inputdeck.get< tag::cmd, tag::benchmark >() || !fieldOutput()) {
+
+    c.send();
+
+  } else {
 
-        // 3. solve 3x3 least-squares system
-        tk::solveLeastSq_P0P1( rdof, lhs_ls, rhs_ls, U, vars );
+    // Optionally refine mesh for field output
+    auto d = Disc();
 
-        for (std::size_t e=0; e<nelem; ++e)
-        {
-          std::vector< std::size_t > matInt(m_ncomp, 0);
-          std::vector< tk::real > alAvg(m_ncomp, 0.0);
-          for (std::size_t k=0; k<m_ncomp; ++k)
-            alAvg[k] = U(e, k*rdof);
-          auto intInd = interfaceIndicator(m_ncomp, alAvg, matInt);
-          if ((intsharp > 0) && intInd)
-          {
-            // Reconstruct second-order dofs of volume-fractions in Taylor space
-            // using nodal-stencils, for a good interface-normal estimate
-            tk::recoLeastSqExtStencil( rdof, e, esup, inpoel, geoElem,
-              U, vars );
-          }
-        }
+    if (refinedOutput()) {
+
+      const auto& tr = tk::remap( myGhosts()->m_fd.Triinpoel(), d->Gid() );
+      d->Ref()->outref( myGhosts()->m_fd.Bface(), {}, tr, c );
+
+    } else {
+
+      // cut off ghosts from mesh connectivity and coordinates
+      extractFieldOutput( {}, d->Chunk(), d->Coord(), {}, {}, d->NodeCommMap(),
+        {}, {}, {}, c );
+
+    }
+
+  }
+}
 
-        // 4. transform reconstructed derivatives to Dubiner dofs
-        tk::transform_P0P1( rdof, nelem, inpoel, coord, U, vars );
-      }
-    }
-
-    //! Limit second-order solution
-    //! \param[in] t Physical time
-    //! \param[in] geoFace Face geometry array
-    //! \param[in] fd Face connectivity and boundary conditions object
-    //! \param[in] esup Elements surrounding points
-    //! \param[in] inpoel Element-node connectivity
-    //! \param[in] coord Array of nodal coordinates
-    //! \param[in] ndofel Vector of local number of degrees of freedome
-//    //! \param[in] gid Local->global node id map
-//    //! \param[in] bid Local chare-boundary node ids (value) associated to
-//    //!   global node ids (key)
-//    //! \param[in] uNodalExtrm Chare-boundary nodal extrema for conservative
-//    //!   variables
-    //! \param[in,out] U Solution vector at recent time step
-    void limit( [[maybe_unused]] tk::real t,
-                [[maybe_unused]] const tk::Fields& geoFace,
-                const tk::Fields&,
-                const inciter::FaceData& fd,
-                const std::map< std::size_t, std::vector< std::size_t > >& esup,
-                const std::vector< std::size_t >& inpoel,
-                const tk::UnsMesh::Coords& coord,
-                const std::vector< std::size_t >& ndofel,
-                const std::vector< std::size_t >&,
-                const std::unordered_map< std::size_t, std::size_t >&,
-                const std::vector< std::vector<tk::real> >&,
-                const std::vector< std::vector<tk::real> >&,
-                const std::vector< std::vector<tk::real> >&,
-                tk::Fields& U,
-                tk::Fields&,
-                std::vector< std::size_t >& ) const
-    {
-      const auto limiter = g_inputdeck.get< tag::limiter >();
-
-      if (limiter == ctr::LimiterType::WENOP1)
-        WENO_P1( fd.Esuel(), U );
-      else if (limiter == ctr::LimiterType::SUPERBEEP1)
-        Superbee_P1( fd.Esuel(), inpoel, ndofel, coord, U );
-      else if (limiter == ctr::LimiterType::VERTEXBASEDP1)
-        VertexBasedTransport_P1( esup, inpoel, ndofel, fd.Esuel().size()/4,
-          coord, U );
-    }
+void
+FV::next()
+// *****************************************************************************
+// Advance equations to next time step
+// *****************************************************************************
+{
+  // communicate solution ghost data (if any)
+  if (myGhosts()->m_sendGhost.empty())
+    comsol_complete();
+  else
+    for(const auto& [cid, ghostdata] : myGhosts()->m_sendGhost) {
+      std::vector< std::size_t > tetid( ghostdata.size() );
+      std::vector< std::vector< tk::real > > u( ghostdata.size() ),
+                                             prim( ghostdata.size() );
+      std::size_t j = 0;
+      for(const auto& i : ghostdata) {
+        Assert( i < myGhosts()->m_fd.Esuel().size()/4,
+          "Sending solution ghost data" );
+        tetid[j] = i;
+        u[j] = m_u[i];
+        prim[j] = m_p[i];
+        ++j;
+      }
+      thisProxy[ cid ].comsol( thisIndex, tetid, u, prim );
+    }
+
+  ownsol_complete();
+}
+
+void
+FV::comsol( int fromch,
+            const std::vector< std::size_t >& tetid,
+            const std::vector< std::vector< tk::real > >& u,
+            const std::vector< std::vector< tk::real > >& prim )
+// *****************************************************************************
+//  Receive chare-boundary solution ghost data from neighboring chares
+//! \param[in] fromch Sender chare id
+//! \param[in] tetid Ghost tet ids we receive solution data for
+//! \param[in] u Solution ghost data
+//! \param[in] prim Primitive variables in ghost cells
+//! \details This function receives contributions to the unlimited solution
+//!   from fellow chares.
+// *****************************************************************************
+{
+  Assert( u.size() == tetid.size(), "Size mismatch in FV::comsol()" );
+  Assert( prim.size() == tetid.size(), "Size mismatch in FV::comsol()" );
 
-    //! Update the conservative variable solution for this PDE system
-    //! \details This function computes the updated dofs for conservative
-    //!   quantities based on the limited solution and is currently not used in
-    //!   transport.
-    void CPL( const tk::Fields&,
-              const tk::Fields&,
-              const std::vector< std::size_t >&,
-              const tk::UnsMesh::Coords&,
-              tk::Fields&,
-              std::size_t ) const {}
-
-    //! Return cell-average deformation gradient tensor (no-op for transport)
-    //! \details This function is a no-op in transport.
-    std::array< std::vector< tk::real >, 9 > cellAvgDeformGrad(
-      const tk::Fields&,
-      std::size_t ) const
-    {
-      return {};
-    }
-
-    //! Compute right hand side
-    //! \param[in] t Physical time
-    //! \param[in] geoFace Face geometry array
-    //! \param[in] geoElem Element geometry array
-    //! \param[in] fd Face connectivity and boundary conditions object
-    //! \param[in] inpoel Element-node connectivity
-    //! \param[in] coord Array of nodal coordinates
-    //! \param[in] U Solution vector at recent time step
-    //! \param[in] P Primitive vector at recent time step
-    //! \param[in] ndofel Vector of local number of degrees of freedom
-    // //! \param[in] rho0mat Initial densities of all materials
-    //! \param[in] dt Delta time
-    //! \param[in,out] R Right-hand side vector computed
-    void rhs( tk::real t,
-              const tk::Fields& geoFace,
-              const tk::Fields& geoElem,
-              const inciter::FaceData& fd,
-              const std::vector< std::size_t >& inpoel,
-              const std::vector< std::unordered_set< std::size_t > >&,
-              const tk::UnsMesh::Coords& coord,
-              const tk::Fields& U,
-              const tk::Fields& P,
-              const std::vector< std::size_t >& ndofel,
-              const std::vector< tk::real >& /*rho0mat*/,
-              const tk::real dt,
-              tk::Fields& R ) const
-    {
-      const auto ndof = g_inputdeck.get< tag::ndof >();<--- Variable 'ndof' is assigned a value that is never used.
-      const auto rdof = g_inputdeck.get< tag::rdof >();<--- Variable 'rdof' is assigned a value that is never used.
-      const auto intsharp = g_inputdeck.get< tag::transport,<--- Variable 'intsharp' is assigned a value that is never used.
-        tag::intsharp >();
-
-      Assert( U.nunk() == P.nunk(), "Number of unknowns in solution "
-              "vector and primitive vector at recent time step incorrect" );
-      Assert( U.nunk() == R.nunk(), "Number of unknowns in solution "
-              "vector and right-hand side at recent time step incorrect" );
-      Assert( U.nprop() == rdof*m_ncomp, "Number of components in solution "
-              "vector must equal "+ std::to_string(rdof*m_ncomp) );
-      Assert( P.nprop() == 0, "Number of components in primitive "
-              "vector must equal "+ std::to_string(0) );
-      Assert( R.nprop() == ndof*m_ncomp, "Number of components in right-hand "
-              "side vector must equal "+ std::to_string(ndof*m_ncomp) );
-      Assert( fd.Inpofa().size()/3 == fd.Esuf().size()/2,
-              "Mismatch in inpofa size" );
-
-      // set rhs to zero
-      R.fill(0.0);
-
-      // empty vector for non-conservative terms. This vector is unused for
-      // linear transport since, there are no non-conservative terms in the
-      // system of PDEs.
-      std::vector< std::vector < tk::real > > riemannDeriv;
-
-      std::vector< std::vector< tk::real > > vriem;
-      std::vector< std::vector< tk::real > > riemannLoc;
-
-      // compute internal surface flux integrals
-      std::vector< std::size_t > solidx(1, 0);
-      tk::surfInt( m_ncomp, m_mat_blk, t, ndof, rdof,
-                   inpoel, solidx, coord, fd, geoFace, geoElem, Upwind::flux,
-                   Problem::prescribedVelocity, U, P, ndofel, dt, R, vriem,
-                   riemannLoc, riemannDeriv, intsharp );
-
-      if(ndof > 1)
-        // compute volume integrals
-        tk::volInt( m_ncomp, t, m_mat_blk, ndof, rdof,
-                    fd.Esuel().size()/4, inpoel, coord, geoElem, flux,
-                    Problem::prescribedVelocity, U, P, ndofel, R, intsharp );
-
-      // compute boundary surface flux integrals
-      for (const auto& b : m_bc)
-        tk::bndSurfInt( m_ncomp, m_mat_blk, ndof, rdof,
-          b.first, fd, geoFace, geoElem, inpoel, coord, t, Upwind::flux,
-          Problem::prescribedVelocity, b.second, U, P, ndofel, R, vriem,
-          riemannLoc, riemannDeriv, intsharp );
-    }
-
-    //! Evaluate the adaptive indicator and mark the ndof for each element
-    //! \param[in] nunk Number of unknowns
-    //! \param[in] coord Array of nodal coordinates
-    //! \param[in] inpoel Element-node connectivity
-    //! \param[in] fd Face connectivity and boundary conditions object
-    //! \param[in] unk Array of unknowns
-    //! \param[in] prim Array of primitive quantities
-    //! \param[in] indicator p-refinement indicator type
-    //! \param[in] ndof Number of degrees of freedom in the solution
-    //! \param[in] ndofmax Max number of degrees of freedom for p-refinement
-    //! \param[in] tolref Tolerance for p-refinement
-    //! \param[in,out] ndofel Vector of local number of degrees of freedome
-    void eval_ndof( std::size_t nunk,
-                    [[maybe_unused]] const tk::UnsMesh::Coords& coord,
-                    [[maybe_unused]] const std::vector< std::size_t >& inpoel,
-                    const inciter::FaceData& fd,
-                    const tk::Fields& unk,
-                    const tk::Fields& prim,
-                    inciter::ctr::PrefIndicatorType indicator,
-                    std::size_t ndof,
-                    std::size_t ndofmax,
-                    tk::real tolref,
-                    std::vector< std::size_t >& ndofel ) const
-    {
-      const auto& esuel = fd.Esuel();
-
-      if(indicator == inciter::ctr::PrefIndicatorType::SPECTRAL_DECAY)
-        spectral_decay( 1, nunk, esuel, unk, prim, ndof, ndofmax, tolref,
-          ndofel );
-      else
-        Throw( "No such adaptive indicator type" );
-    }
-
-    //! Compute the minimum time step size
-//     //! \param[in] U Solution vector at recent time step
-//     //! \param[in] coord Mesh node coordinates
-//     //! \param[in] inpoel Mesh element connectivity
-    //! \return Minimum time step size
-    tk::real dt( const std::array< std::vector< tk::real >, 3 >& /*coord*/,
-                 const std::vector< std::size_t >& /*inpoel*/,
-                 const inciter::FaceData& /*fd*/,
-                 const tk::Fields& /*geoFace*/,
-                 const tk::Fields& /*geoElem*/,
-                 const std::vector< std::size_t >& /*ndofel*/,
-                 const tk::Fields& /*U*/,
-                 const tk::Fields&,
-                 const std::size_t /*nielem*/ ) const
-    {
-      tk::real mindt = std::numeric_limits< tk::real >::max();
-      return mindt;
-    }
-
-    //! Compute stiff terms for a single element, not implemented here
-    // //! \param[in] e Element number
-    // //! \param[in] geoElem Element geometry array
-    // //! \param[in] inpoel Element-node connectivity
-    // //! \param[in] coord Array of nodal coordinates
-    // //! \param[in] U Solution vector at recent time step
-    // //! \param[in] P Primitive vector at recent time step
-    // //! \param[in] ndofel Vector of local number of degrees of freedom
-    // //! \param[in,out] R Right-hand side vector computed
-    void stiff_rhs( std::size_t /*e*/,
-                    const tk::Fields& /*geoElem*/,
-                    const std::vector< std::size_t >& /*inpoel*/,
-                    const tk::UnsMesh::Coords& /*coord*/,
-                    const tk::Fields& /*U*/,
-                    const tk::Fields& /*P*/,
-                    const std::vector< std::size_t >& /*ndofel*/,
-                    tk::Fields& /*R*/ ) const
-    {}
-
-    //! Return a map that associates user-specified strings to functions
-    //! \return Map that associates user-specified strings to functions that
-    //!  compute relevant quantities to be output to file
-    std::map< std::string, tk::GetVarFn > OutVarFn() const {
-      std::map< std::string, tk::GetVarFn > OutFnMap;
-      OutFnMap["material_indicator"] = transport::matIndicatorOutVar;
-
-      return OutFnMap;
-    }
-
-    //! Return analytic field names to be output to file
-    //! \return Vector of strings labelling analytic fields output in file
-    std::vector< std::string > analyticFieldNames() const {
-      std::vector< std::string > n;
-      auto depvar = g_inputdeck.get< tag::depvar >()[0];
-      for (ncomp_t c=0; c<m_ncomp; ++c)
-        n.push_back( depvar + std::to_string(c) + "_analytic" );
-      return n;
-    }
-
-    //! Return surface field output going to file
-    std::vector< std::vector< tk::real > >
-    surfOutput( const std::map< int, std::vector< std::size_t > >&,
-                tk::Fields& ) const
-    {
-      std::vector< std::vector< tk::real > > s; // punt for now
-      return s;
-    }
-
-    //! Return time history field names to be output to file
-    //! \return Vector of strings labelling time history fields output in file
-    std::vector< std::string > histNames() const {
-      std::vector< std::string > s; // punt for now
-      return s;
-    }
-
-    //! Return names of integral variables to be output to diagnostics file
-    //! \return Vector of strings labelling integral variables output
-    std::vector< std::string > names() const {
-      std::vector< std::string > n;
-      const auto& depvar =
-      g_inputdeck.get< tag::depvar >().at(0);
-      // construct the name of the numerical solution for all components
-      for (ncomp_t c=0; c<m_ncomp; ++c)
-        n.push_back( depvar + std::to_string(c) );
-      return n;
-    }
-
-    //! Return analytic solution (if defined by Problem) at xi, yi, zi, t
-    //! \param[in] xi X-coordinate at which to evaluate the analytic solution
-    //! \param[in] yi Y-coordinate at which to evaluate the analytic solution
-    //! \param[in] zi Z-coordinate at which to evaluate the analytic solution
-    //! \param[in] t Physical time at which to evaluate the analytic solution
-    //! \return Vector of analytic solution at given spatial location and time
-    std::vector< tk::real >
-    analyticSolution( tk::real xi, tk::real yi, tk::real zi, tk::real t ) const
-    { return Problem::analyticSolution( m_ncomp, m_mat_blk, xi, yi,
-                                        zi, t ); }
-
-    //! Return analytic solution for conserved variables
-    //! \param[in] xi X-coordinate at which to evaluate the analytic solution
-    //! \param[in] yi Y-coordinate at which to evaluate the analytic solution
-    //! \param[in] zi Z-coordinate at which to evaluate the analytic solution
-    //! \param[in] t Physical time at which to evaluate the analytic solution
-    //! \return Vector of analytic solution at given location and time
-    std::vector< tk::real >
-    solution( tk::real xi, tk::real yi, tk::real zi, tk::real t ) const
-    { return Problem::initialize( m_ncomp, m_mat_blk, xi, yi, zi, t ); }
-
-    //! Return time history field output evaluated at time history points
-    //! \param[in] h History point data
-    std::vector< std::vector< tk::real > >
-    histOutput( const std::vector< HistData >& h,
-                const std::vector< std::size_t >&,
-                const tk::UnsMesh::Coords&,
-                const tk::Fields&,
-                const tk::Fields& ) const
-    {
-      std::vector< std::vector< tk::real > > Up(h.size()); //punt for now
-      return Up;
-    }
-
-    //! Return cell-averaged total component mass per unit volume for an element
-    //! \param[in] e Element id for which total energy is required
-    //! \param[in] unk Vector of conserved quantities
-    //! \return Cell-averaged total component mass per unit volume for given
-    //!   element. Since transport does not have an associated total energy,
-    //!   return total mass.
-    tk::real sp_totalenergy(std::size_t e, const tk::Fields& unk) const
-    {
-      const auto rdof = g_inputdeck.get< tag::rdof >();
-
-      tk::real sp_m(0.0);
-      for (std::size_t c=0; c<m_ncomp; ++c) {
-        sp_m += unk(e,c*rdof);
-      }
-      return sp_m;
-    }
-
-  private:
-    const Physics m_physics;            //!< Physics policy
-    const Problem m_problem;            //!< Problem policy
-    const ncomp_t m_ncomp;              //!< Number of components in this PDE
-    //! BC configuration
-    BCStateFn m_bc;
-    //! \brief EOS material block - This PDE does not require an EOS block,
-    //! thus this variable has not been intialized.
-    std::vector< EOS > m_mat_blk;
-
-    //! Evaluate physical flux function for this PDE system
-    //! \param[in] ncomp Number of scalar components in this PDE system
-    //! \param[in] ugp Numerical solution at the Gauss point at which to
-    //!   evaluate the flux
-    //! \param[in] v Prescribed velocity evaluated at the Gauss point at which
-    //!   to evaluate the flux
-    //! \return Flux vectors for all components in this PDE system
-    //! \note The function signature must follow tk::FluxFn
-    static tk::FluxFn::result_type
-    flux( ncomp_t ncomp,
-          const std::vector< EOS >&,
-          const std::vector< tk::real >& ugp,
-          const std::vector< std::array< tk::real, 3 > >& v )
-
-    {
-      Assert( ugp.size() == ncomp, "Size mismatch" );
-      Assert( v.size() == ncomp, "Size mismatch" );
-
-      std::vector< std::array< tk::real, 3 > > fl( ugp.size() );
-
-      for (ncomp_t c=0; c<ncomp; ++c)
-        fl[c] = {{ v[c][0] * ugp[c], v[c][1] * ugp[c], v[c][2] * ugp[c] }};
-
-      return fl;
-    }
-
-    //! \brief Boundary state function providing the left and right state of a
-    //!   face at extrapolation boundaries
-    //! \param[in] ul Left (domain-internal) state
-    //! \return Left and right states for all scalar components in this PDE
-    //!   system
-    //! \note The function signature must follow tk::StateFn
-    static tk::StateFn::result_type
-    extrapolate( ncomp_t, const std::vector< EOS >&,
-                 const std::vector< tk::real >& ul, tk::real, tk::real,
-                 tk::real, tk::real, const std::array< tk::real, 3 >& )
-    {
-      return {{ ul, ul }};
-    }
-
-    //! \brief Boundary state function providing the left and right state of a
-    //!   face at extrapolation boundaries
-    //! \param[in] ul Left (domain-internal) state
-    //! \return Left and right states for all scalar components in this PDE
-    //!   system
-    //! \note The function signature must follow tk::StateFn
-    static tk::StateFn::result_type
-    inlet( ncomp_t, const std::vector< EOS >&,
-           const std::vector< tk::real >& ul, tk::real, tk::real, tk::real,
-           tk::real, const std::array< tk::real, 3 >& )
-    {
-      auto ur = ul;
-      std::fill( begin(ur), end(ur), 0.0 );
-      return {{ ul, std::move(ur) }};
-    }
-
-    //! \brief Boundary state function providing the left and right state of a
-    //!   face at outlet boundaries
-    //! \param[in] ul Left (domain-internal) state
-    //! \return Left and right states for all scalar components in this PDE
-    //!   system
-    //! \note The function signature must follow tk::StateFn
-    static tk::StateFn::result_type
-    outlet( ncomp_t, const std::vector< EOS >&,
-            const std::vector< tk::real >& ul, tk::real, tk::real, tk::real,
-            tk::real, const std::array< tk::real, 3 >& )
-    {
-      return {{ ul, ul }};
-    }
-
-    //! \brief Boundary state function providing the left and right state of a
-    //!   face at Dirichlet boundaries
-    //! \param[in] ncomp Number of scalar components in this PDE system
-    //! \param[in] ul Left (domain-internal) state
-    //! \param[in] x X-coordinate at which to compute the states
-    //! \param[in] y Y-coordinate at which to compute the states
-    //! \param[in] z Z-coordinate at which to compute the states
-    //! \param[in] t Physical time
-    //! \return Left and right states for all scalar components in this PDE
-    //!   system
-    //! \note The function signature must follow tk::StateFn
-    static tk::StateFn::result_type
-    dirichlet( ncomp_t ncomp, 
-               const std::vector< EOS >& mat_blk,
-               const std::vector< tk::real >& ul, tk::real x, tk::real y,
-               tk::real z, tk::real t, const std::array< tk::real, 3 >& )
-    {
-      return {{ ul, Problem::initialize( ncomp, mat_blk, x, y, z, t ) }};
-    }
-};
-
-} // dg::
-} // inciter::
-
-#endif // DGTransport_h
+  // Find local-to-ghost tet id map for sender chare
+  const auto& n = tk::cref_find( myGhosts()->m_ghost, fromch );
+
+  for (std::size_t i=0; i<tetid.size(); ++i) {
+    auto j = tk::cref_find( n, tetid[i] );
+    Assert( j >= myGhosts()->m_fd.Esuel().size()/4,
+      "Receiving solution non-ghost data" );
+    auto b = tk::cref_find( myGhosts()->m_bid, j );
+    Assert( b < m_uc[0].size(), "Indexing out of bounds" );
+    m_uc[0][b] = u[i];
+    m_pc[0][b] = prim[i];
+  }
+
+  // if we have received all solution ghost contributions from neighboring
+  // chares (chares we communicate along chare-boundary faces with), and
+  // contributed our solution to these neighbors, proceed to reconstructions
+  if (++m_nsol == myGhosts()->m_sendGhost.size()) {
+    m_nsol = 0;
+    comsol_complete();
+  }
+}
+
+void
+FV::extractFieldOutput(
+  const std::vector< std::size_t >& /*ginpoel*/,
+  const tk::UnsMesh::Chunk& chunk,
+  const tk::UnsMesh::Coords& coord,
+  const std::unordered_map< std::size_t, tk::UnsMesh::Edge >& /*addedNodes*/,
+  const std::unordered_map< std::size_t, std::size_t >& addedTets,
+  const tk::NodeCommMap& nodeCommMap,
+  const std::map< int, std::vector< std::size_t > >& /* bface */,
+  const std::map< int, std::vector< std::size_t > >& /* bnode */,
+  const std::vector< std::size_t >& /* triinpoel */,
+  CkCallback c )
+// *****************************************************************************
+// Extract field output going to file
+//! \param[in] chunk Field-output mesh chunk (connectivity and global<->local
+//!    id maps)
+//! \param[in] coord Field-output mesh node coordinates
+//! \param[in] addedTets Field-output mesh cells and their parents (local ids)
+//! \param[in] nodeCommMap Field-output mesh node communication map
+//! \param[in] c Function to continue with after the write
+// *****************************************************************************
+{
+  const auto& inpoel = std::get< 0 >( chunk );
+
+  // Evaluate element solution on incoming mesh
+  evalSolution( *Disc(), inpoel, coord, addedTets, std::vector< std::size_t>{},
+    m_u, m_p, m_uElemfields, m_pElemfields, m_uNodefields, m_pNodefields );
+
+  // Send node fields contributions to neighbor chares
+  if (nodeCommMap.empty())
+    comnodeout_complete();
+  else {
+    const auto& lid = std::get< 2 >( chunk );
+    auto esup = tk::genEsup( inpoel, 4 );
+    for(const auto& [ch,nodes] : nodeCommMap) {
+      // Pack node field data in chare boundary nodes
+      std::vector< std::vector< tk::real > >
+        lu( m_uNodefields.nprop(), std::vector< tk::real >( nodes.size() ) );
+      std::vector< std::vector< tk::real > >
+        lp( m_pNodefields.nprop(), std::vector< tk::real >( nodes.size() ) );
+      for (std::size_t f=0; f<m_uNodefields.nprop(); ++f) {
+        std::size_t j = 0;
+        for (auto g : nodes)
+          lu[f][j++] = m_uNodefields(tk::cref_find(lid,g),f);
+      }
+      for (std::size_t f=0; f<m_pNodefields.nprop(); ++f) {
+        std::size_t j = 0;
+        for (auto g : nodes)
+          lp[f][j++] = m_pNodefields(tk::cref_find(lid,g),f);
+      }
+      // Pack (partial) number of elements surrounding chare boundary nodes
+      std::vector< std::size_t > nesup( nodes.size() );
+      std::size_t j = 0;
+      for (auto g : nodes) {
+        auto i = tk::cref_find( lid, g );
+        nesup[j++] = esup.second[i+1] - esup.second[i];
+      }
+      thisProxy[ch].comnodeout(
+        std::vector<std::size_t>(begin(nodes),end(nodes)), nesup, lu, lp );
+    }
+  }
+
+  ownnod_complete( c );
+}
+
+void
+FV::lhs()
+// *****************************************************************************
+// Compute left-hand side of discrete transport equations
+// *****************************************************************************
+{
+  g_fvpde[Disc()->MeshId()].lhs( myGhosts()->m_geoElem, m_lhs );
+
+  if (!m_initial) stage();
+}
+
+void
+FV::reco()
+// *****************************************************************************
+// Compute reconstructions
+// *****************************************************************************
+{
+  const auto rdof = g_inputdeck.get< tag::rdof >();
+
+  // Combine own and communicated contributions of unreconstructed solution and
+  // degrees of freedom in cells (if p-adaptive)
+  for (const auto& b : myGhosts()->m_bid) {
+    Assert( m_uc[0][b.second].size() == m_u.nprop(), "ncomp size mismatch" );
+    Assert( m_pc[0][b.second].size() == m_p.nprop(), "ncomp size mismatch" );
+    for (std::size_t c=0; c<m_u.nprop(); ++c) {
+      m_u(b.first,c) = m_uc[0][b.second][c];
+    }
+    for (std::size_t c=0; c<m_p.nprop(); ++c) {
+      m_p(b.first,c) = m_pc[0][b.second][c];
+    }
+  }
+
+  if (rdof > 1) {
+    // Reconstruct second-order solution and primitive quantities
+    g_fvpde[Disc()->MeshId()].reconstruct( myGhosts()->m_geoElem, myGhosts()->m_fd,
+      myGhosts()->m_esup, myGhosts()->m_inpoel, myGhosts()->m_coord, m_u, m_p );
+  }
+
+  // start limiting
+  lim();
+}
+
+void
+FV::lim()
+// *****************************************************************************
+// Compute limiter function
+// *****************************************************************************
+{
+  const auto rdof = g_inputdeck.get< tag::rdof >();
+
+  if (rdof > 1) {
+    g_fvpde[Disc()->MeshId()].limit( myGhosts()->m_geoFace, myGhosts()->m_fd,
+      myGhosts()->m_esup,
+      myGhosts()->m_inpoel, myGhosts()->m_coord, m_srcFlag, m_u, m_p );
+  }
+
+  // Send limited solution to neighboring chares
+  if (myGhosts()->m_sendGhost.empty())
+    comlim_complete();
+  else
+    for(const auto& [cid, ghostdata] : myGhosts()->m_sendGhost) {
+      std::vector< std::size_t > tetid( ghostdata.size() );
+      std::vector< std::vector< tk::real > > u( ghostdata.size() ),
+                                             prim( ghostdata.size() );
+      std::size_t j = 0;
+      for(const auto& i : ghostdata) {
+        Assert( i < myGhosts()->m_fd.Esuel().size()/4,
+          "Sending limiter ghost data" );
+        tetid[j] = i;
+        u[j] = m_u[i];
+        prim[j] = m_p[i];
+        ++j;
+      }
+      thisProxy[ cid ].comlim( thisIndex, tetid, u, prim );
+    }
+
+  ownlim_complete();
+}
+
+void
+FV::comlim( int fromch,
+            const std::vector< std::size_t >& tetid,
+            const std::vector< std::vector< tk::real > >& u,
+            const std::vector< std::vector< tk::real > >& prim )
+// *****************************************************************************
+//  Receive chare-boundary limiter ghost data from neighboring chares
+//! \param[in] fromch Sender chare id
+//! \param[in] tetid Ghost tet ids we receive solution data for
+//! \param[in] u Limited high-order solution
+//! \param[in] prim Limited high-order primitive quantities
+//! \details This function receives contributions to the limited solution from
+//!   fellow chares.
+// *****************************************************************************
+{
+  Assert( u.size() == tetid.size(), "Size mismatch in FV::comlim()" );
+  Assert( prim.size() == tetid.size(), "Size mismatch in FV::comlim()" );
+
+  // Find local-to-ghost tet id map for sender chare
+  const auto& n = tk::cref_find( myGhosts()->m_ghost, fromch );
+
+  for (std::size_t i=0; i<tetid.size(); ++i) {
+    auto j = tk::cref_find( n, tetid[i] );
+    Assert( j >= myGhosts()->m_fd.Esuel().size()/4,
+      "Receiving solution non-ghost data" );
+    auto b = tk::cref_find( myGhosts()->m_bid, j );
+    Assert( b < m_uc[1].size(), "Indexing out of bounds" );
+    Assert( b < m_pc[1].size(), "Indexing out of bounds" );
+    m_uc[1][b] = u[i];
+    m_pc[1][b] = prim[i];
+  }
+
+  // if we have received all solution ghost contributions from neighboring
+  // chares (chares we communicate along chare-boundary faces with), and
+  // contributed our solution to these neighbors, proceed to limiting
+  if (++m_nlim == myGhosts()->m_sendGhost.size()) {
+    m_nlim = 0;
+    comlim_complete();
+  }
+}
+
+void
+FV::dt()
+// *****************************************************************************
+// Compute time step size
+// *****************************************************************************
+{
+  auto d = Disc();
+
+  // Combine own and communicated contributions of limited solution and degrees
+  // of freedom in cells (if p-adaptive)
+  for (const auto& b : myGhosts()->m_bid) {
+    Assert( m_uc[1][b.second].size() == m_u.nprop(), "ncomp size mismatch" );
+    Assert( m_pc[1][b.second].size() == m_p.nprop(), "ncomp size mismatch" );
+    for (std::size_t c=0; c<m_u.nprop(); ++c) {
+      m_u(b.first,c) = m_uc[1][b.second][c];
+    }
+    for (std::size_t c=0; c<m_p.nprop(); ++c) {
+      m_p(b.first,c) = m_pc[1][b.second][c];
+    }
+  }
+
+  auto mindt = std::numeric_limits< tk::real >::max();
+
+  if (m_stage == 0)
+  {
+    auto const_dt = g_inputdeck.get< tag::dt >();
+    auto eps = std::numeric_limits< tk::real >::epsilon();
+
+    // use constant dt if configured
+    if (std::abs(const_dt) > eps) {
+
+      mindt = const_dt;
+
+    } else {      // compute dt based on CFL
+
+      // find the minimum dt across all PDEs integrated
+      auto eqdt =
+        g_fvpde[d->MeshId()].dt( myGhosts()->m_fd, myGhosts()->m_geoFace,
+          myGhosts()->m_geoElem, m_u, m_p, myGhosts()->m_fd.Esuel().size()/4,
+          m_srcFlag, m_dte );
+      if (eqdt < mindt) mindt = eqdt;
+
+      // time-step suppression for unsteady problems
+      tk::real coeff(1.0);
+      if (!g_inputdeck.get< tag::steady_state >()) {
+        if (d->It() < 100) coeff = 0.01 * static_cast< tk::real >(d->It());
+      }
+
+      mindt *= coeff * g_inputdeck.get< tag::cfl >();
+    }
+  }
+  else
+  {
+    mindt = d->Dt();
+  }
+
+  // Contribute to minimum dt across all chares then advance to next step
+  contribute( sizeof(tk::real), &mindt, CkReduction::min_double,
+              CkCallback(CkReductionTarget(FV,solve), thisProxy) );
+}
+
+void
+FV::solve( tk::real newdt )
+// *****************************************************************************
+// Compute right-hand side of discrete transport equations
+//! \param[in] newdt Size of this new time step
+// *****************************************************************************
+{
+  // Enable SDAG wait for building the solution vector during the next stage
+  thisProxy[ thisIndex ].wait4sol();
+  thisProxy[ thisIndex ].wait4lim();
+  thisProxy[ thisIndex ].wait4nod();
+
+  auto d = Disc();
+  const auto rdof = g_inputdeck.get< tag::rdof >();
+  const auto neq = m_u.nprop()/rdof;
+
+  // Set new time step size
+  if (m_stage == 0) d->setdt( newdt );
+
+  // Update Un
+  if (m_stage == 0) m_un = m_u;
+
+  // physical time at time-stage for computing exact source terms for
+  // unsteady problems
+  tk::real physT(d->T());
+  // 2-stage RK
+  if (m_nrk == 2) {
+    if (m_stage == 1) {
+      physT += d->Dt();
+    }
+  }
+  // 3-stage RK
+  else {
+    if (m_stage == 1) {
+      physT += d->Dt();
+    }
+    else if (m_stage == 2) {
+      physT += 0.5*d->Dt();
+    }
+  }
+
+  // Compute rhs
+  g_fvpde[d->MeshId()].rhs( physT, myGhosts()->m_geoFace, myGhosts()->m_geoElem,
+    myGhosts()->m_fd, myGhosts()->m_inpoel, myGhosts()->m_coord,
+    d->ElemBlockId(), m_u, m_p, m_rhs, m_srcFlag );
+
+  // Explicit time-stepping using RK3 to discretize time-derivative
+  const auto steady = g_inputdeck.get< tag::steady_state >();
+  for (std::size_t e=0; e<myGhosts()->m_nunk; ++e)
+    for (std::size_t c=0; c<neq; ++c)
+    {
+      auto dte = d->Dt();
+      if (steady) dte = m_dte[e];
+      auto rmark = c*rdof;
+      m_u(e, rmark) =  m_rkcoef[0][m_stage] * m_un(e, rmark)
+        + m_rkcoef[1][m_stage] * ( m_u(e, rmark)
+          + dte * m_rhs(e, c)/m_lhs(e, c) );
+      // zero out reconstructed dofs of equations using reduced dofs
+      if (rdof > 1) {
+        for (std::size_t k=1; k<rdof; ++k)
+        {
+          rmark = c*rdof+k;
+          m_u(e, rmark) = 0.0;
+        }
+      }
+    }
+
+  // Update primitives based on the evolved solution
+  g_fvpde[d->MeshId()].updatePrimitives( m_u, m_p,
+    myGhosts()->m_fd.Esuel().size()/4 );
+  if (!g_inputdeck.get< tag::accuracy_test >()) {
+    g_fvpde[d->MeshId()].cleanTraceMaterial( physT, myGhosts()->m_geoElem, m_u,
+      m_p, myGhosts()->m_fd.Esuel().size()/4 );
+  }
+
+  if (m_stage < m_nrk-1) {
+
+    // continue with next time step stage
+    stage();
+
+  } else {
+
+    // Increase number of iterations and physical time
+    d->next();
+
+    // Compute diagnostics, e.g., residuals
+    auto diag_computed = m_diag.compute( *d,
+      m_u.nunk()-myGhosts()->m_fd.Esuel().size()/4, myGhosts()->m_geoElem,
+      std::vector< std::size_t>{}, m_u, m_un );
+
+    // Continue to mesh refinement (if configured)
+    if (!diag_computed) refine( std::vector< tk::real >( m_u.nprop(), 1.0 ) );
+
+  }
+}
+
+void
+FV::refine( const std::vector< tk::real >& l2res )
+// *****************************************************************************
+// Optionally refine/derefine mesh
+//! \param[in] l2res L2-norms of the residual for each scalar component
+//!   computed across the whole problem
+// *****************************************************************************
+{
+  auto d = Disc();
+
+  // Assess convergence for steady state
+  const auto steady = g_inputdeck.get< tag::steady_state >();
+  const auto residual = g_inputdeck.get< tag::residual >();
+  const auto rc = g_inputdeck.get< tag::rescomp >() - 1;
+
+  bool converged(false);
+  if (steady) converged = l2res[rc] < residual;
+
+  // this is the last time step if max time of max number of time steps
+  // reached or the residual has reached its convergence criterion
+  if (d->finished() or converged) m_finished = 1;
+
+  auto dtref = g_inputdeck.get< tag::amr, tag::dtref >();
+  auto dtfreq = g_inputdeck.get< tag::amr, tag::dtfreq >();
+
+  // if t>0 refinement enabled and we hit the dtref frequency
+  if (dtref && !(d->It() % dtfreq)) {   // refine
+
+    d->startvol();
+    d->Ref()->dtref( myGhosts()->m_fd.Bface(), {},
+      tk::remap(myGhosts()->m_fd.Triinpoel(),d->Gid()) );
+    d->refined() = 1;
+
+  } else {      // do not refine
+
+    d->refined() = 0;
+    stage();
+
+  }
+}
+
+void
+FV::resizePostAMR(
+  const std::vector< std::size_t >& /*ginpoel*/,
+  const tk::UnsMesh::Chunk& chunk,
+  const tk::UnsMesh::Coords& coord,
+  const std::unordered_map< std::size_t, tk::UnsMesh::Edge >& /*addedNodes*/,
+  const std::unordered_map< std::size_t, std::size_t >& addedTets,
+  const std::set< std::size_t >& removedNodes,
+  const std::unordered_map< std::size_t, std::size_t >& amrNodeMap,
+  const tk::NodeCommMap& nodeCommMap,
+  const std::map< int, std::vector< std::size_t > >& bface,
+  const std::map< int, std::vector< std::size_t > >& /* bnode */,
+  const std::vector< std::size_t >& triinpoel,
+  const std::unordered_map< std::size_t, std::set< std::size_t > >& elemblockid )
+// *****************************************************************************
+//  Receive new mesh from Refiner
+//! \param[in] chunk New mesh chunk (connectivity and global<->local id maps)
+//! \param[in] coord New mesh node coordinates
+//! \param[in] addedTets Newly added mesh cells and their parents (local ids)
+//! \param[in] removedNodes Newly removed mesh node local ids
+//! \param[in] amrNodeMap Node id map after amr (local ids)
+//! \param[in] nodeCommMap New node communication map
+//! \param[in] bface Boundary-faces mapped to side set ids
+//! \param[in] triinpoel Boundary-face connectivity
+//! \param[in] elemblockid Local tet ids associated with mesh block ids
+// *****************************************************************************
+{
+  auto d = Disc();
+
+  // Set flag that indicates that we are during time stepping
+  m_initial = 0;
+  myGhosts()->m_initial = 0;
+
+  // Zero field output iteration count between two mesh refinement steps
+  d->Itf() = 0;
+
+  // Increase number of iterations with mesh refinement
+  ++d->Itr();
+
+  // Save old number of elements
+  [[maybe_unused]] auto old_nelem = myGhosts()->m_inpoel.size()/4;
+
+  // Resize mesh data structures
+  d->resizePostAMR( chunk, coord, amrNodeMap, nodeCommMap, removedNodes,
+    elemblockid );
+
+  // Update state
+  myGhosts()->m_inpoel = d->Inpoel();
+  myGhosts()->m_coord = d->Coord();
+  auto nelem = myGhosts()->m_inpoel.size()/4;
+  m_p.resize( nelem );
+  m_u.resize( nelem );
+  m_srcFlag.resize( nelem );
+  m_un.resize( nelem );
+  m_lhs.resize( nelem );
+  m_rhs.resize( nelem );
+
+  myGhosts()->m_fd = FaceData( myGhosts()->m_inpoel, bface,
+    tk::remap(triinpoel,d->Lid()) );
+
+  myGhosts()->m_geoFace =
+    tk::Fields( tk::genGeoFaceTri( myGhosts()->m_fd.Nipfac(),
+    myGhosts()->m_fd.Inpofa(), coord ) );
+  myGhosts()->m_geoElem = tk::Fields( tk::genGeoElemTet( myGhosts()->m_inpoel,
+    coord ) );
+
+  myGhosts()->m_nfac = myGhosts()->m_fd.Inpofa().size()/3;
+  myGhosts()->m_nunk = nelem;
+  m_npoin = coord[0].size();
+  myGhosts()->m_bndFace.clear();
+  myGhosts()->m_exptGhost.clear();
+  myGhosts()->m_sendGhost.clear();
+  myGhosts()->m_ghost.clear();
+  myGhosts()->m_esup.clear();
+
+  // Update solution on new mesh, P0 (cell center value) only for now
+  m_un = m_u;
+  auto pn = m_p;<--- Variable 'pn' is assigned a value that is never used.
+  auto unprop = m_u.nprop();<--- Variable 'unprop' is assigned a value that is never used.
+  auto pnprop = m_p.nprop();<--- Variable 'pnprop' is assigned a value that is never used.
+  for (const auto& [child,parent] : addedTets) {
+    Assert( child < nelem, "Indexing out of new solution vector" );
+    Assert( parent < old_nelem, "Indexing out of old solution vector" );
+    for (std::size_t i=0; i<unprop; ++i) m_u(child,i) = m_un(parent,i);
+    for (std::size_t i=0; i<pnprop; ++i) m_p(child,i) = pn(parent,i);
+  }
+  m_un = m_u;
+
+  // Resize communication buffers
+  m_ghosts[thisIndex].resizeComm();
+}
+
+bool
+FV::fieldOutput() const
+// *****************************************************************************
+// Decide wether to output field data
+//! \return True if field data is output in this step
+// *****************************************************************************
+{
+  auto d = Disc();
+
+  // Output field data
+  return d->fielditer() or d->fieldtime() or d->fieldrange() or m_finished;
+}
+
+bool
+FV::refinedOutput() const
+// *****************************************************************************
+// Decide if we write field output using a refined mesh
+//! \return True if field output will use a refined mesh
+// *****************************************************************************
+{
+  return g_inputdeck.get< tag::field_output, tag::refined >() &&
+         g_inputdeck.get< tag::scheme >() != ctr::SchemeType::FV;
+}
+
+void
+FV::writeFields( CkCallback c )
+// *****************************************************************************
+// Output mesh field data
+//! \param[in] c Function to continue with after the write
+// *****************************************************************************
+{
+  auto d = Disc();
+
+  const auto& inpoel = std::get< 0 >( d->Chunk() );
+  auto esup = tk::genEsup( inpoel, 4 );
+  auto nelem = inpoel.size() / 4;
+
+  // Combine own and communicated contributions and finish averaging of node
+  // field output in chare boundary nodes
+  const auto& lid = std::get< 2 >( d->Chunk() );
+  for (const auto& [g,f] : m_uNodefieldsc) {
+    Assert( m_uNodefields.nprop() == f.first.size(), "Size mismatch" );
+    auto p = tk::cref_find( lid, g );
+    for (std::size_t i=0; i<f.first.size(); ++i) {
+      m_uNodefields(p,i) += f.first[i];
+      m_uNodefields(p,i) /= static_cast< tk::real >(
+                              esup.second[p+1] - esup.second[p] + f.second );
+    }
+  }
+  tk::destroy( m_uNodefieldsc );
+  for (const auto& [g,f] : m_pNodefieldsc) {
+    Assert( m_pNodefields.nprop() == f.first.size(), "Size mismatch" );
+    auto p = tk::cref_find( lid, g );
+    for (std::size_t i=0; i<f.first.size(); ++i) {
+      m_pNodefields(p,i) += f.first[i];
+      m_pNodefields(p,i) /= static_cast< tk::real >(
+                              esup.second[p+1] - esup.second[p] + f.second );
+    }
+  }
+  tk::destroy( m_pNodefieldsc );
+
+  // Lambda to decide if a node (global id) is on a chare boundary of the field
+  // output mesh. p - global node id, return true if node is on the chare
+  // boundary.
+  auto chbnd = [ this ]( std::size_t p ) {
+    return
+      std::any_of( Disc()->NodeCommMap().cbegin(), Disc()->NodeCommMap().cend(),
+        [&](const auto& s) { return s.second.find(p) != s.second.cend(); } );
+  };
+
+  // Finish computing node field output averages in internal nodes
+  auto npoin = d->Coord()[0].size();
+  auto& gid = std::get< 1 >( d->Chunk() );
+  for (std::size_t p=0; p<npoin; ++p) {
+    if (!chbnd(gid[p])) {
+      auto n = static_cast< tk::real >( esup.second[p+1] - esup.second[p] );
+      for (std::size_t i=0; i<m_uNodefields.nprop(); ++i)
+        m_uNodefields(p,i) /= n;
+      for (std::size_t i=0; i<m_pNodefields.nprop(); ++i)
+        m_pNodefields(p,i) /= n;
+    }
+  }
+
+  // Collect field output from numerical solution requested by user
+  auto elemfields = numericFieldOutput( m_uElemfields, tk::Centering::ELEM,
+    g_fvpde[Disc()->MeshId()].OutVarFn(), m_pElemfields );
+  auto nodefields = numericFieldOutput( m_uNodefields, tk::Centering::NODE,
+    g_fvpde[Disc()->MeshId()].OutVarFn(), m_pNodefields );
+
+  // Collect field output from analytical solutions (if exist)
+  const auto& coord = d->Coord();
+  auto geoElem = tk::genGeoElemTet( inpoel, coord );
+  auto t = Disc()->T();
+  analyticFieldOutput( g_fvpde[d->MeshId()], tk::Centering::ELEM,
+    geoElem.extract_comp(1), geoElem.extract_comp(2), geoElem.extract_comp(3),
+    t, elemfields );
+  analyticFieldOutput( g_fvpde[d->MeshId()], tk::Centering::NODE, coord[0],
+    coord[1], coord[2], t, nodefields );
+
+  // Add sound speed vector
+  std::vector< tk::real > soundspd(nelem, 0.0);
+  g_fvpde[d->MeshId()].soundspeed(nelem, m_u, m_p, soundspd);
+  elemfields.push_back(soundspd);
+
+  // Add source flag array to element-centered field output
+  std::vector< tk::real > srcFlag( begin(m_srcFlag), end(m_srcFlag) );
+  // Here m_srcFlag has a size of m_u.nunk() which is the number of the
+  // elements within this partition (nelem) plus the ghost partition cells.
+  // For the purpose of output, we only need the solution data within this
+  // partition. Therefore, resizing it to nelem removes the extra partition
+  // boundary allocations in the srcFlag vector. Since the code assumes that
+  // the boundary elements are on the top, the resize operation keeps the lower
+  // portion.
+  srcFlag.resize( nelem );
+  elemfields.push_back( srcFlag );
+
+  // Query fields names requested by user
+  auto elemfieldnames = numericFieldNames( tk::Centering::ELEM );
+  auto nodefieldnames = numericFieldNames( tk::Centering::NODE );
+
+  // Collect field output names for analytical solutions
+  analyticFieldNames( g_fvpde[d->MeshId()], tk::Centering::ELEM, elemfieldnames );
+  analyticFieldNames( g_fvpde[d->MeshId()], tk::Centering::NODE, nodefieldnames );
+
+  elemfieldnames.push_back( "sound speed" );
+  elemfieldnames.push_back( "src_flag" );
+
+  Assert( elemfieldnames.size() == elemfields.size(), "Size mismatch" );
+  Assert( nodefieldnames.size() == nodefields.size(), "Size mismatch" );
+
+  // Collect surface output names
+  auto surfnames = g_fvpde[d->MeshId()].surfNames();
+
+  // Collect surface field solution
+  const auto& fd = myGhosts()->m_fd;
+  auto elemsurfs = g_fvpde[d->MeshId()].surfOutput(fd, m_u, m_p);
+
+  // Output chare mesh and fields metadata to file
+  const auto& triinpoel = tk::remap( fd.Triinpoel(), d->Gid() );
+  d->write( inpoel, d->Coord(), fd.Bface(), {},
+            tk::remap( triinpoel, lid ), elemfieldnames, nodefieldnames,
+            surfnames, {}, elemfields, nodefields, elemsurfs, {}, c );
+}
+
+void
+FV::comnodeout( const std::vector< std::size_t >& gid,
+                const std::vector< std::size_t >& nesup,
+                const std::vector< std::vector< tk::real > >& Lu,
+                const std::vector< std::vector< tk::real > >& Lp )
+// *****************************************************************************
+//  Receive chare-boundary nodal solution (for field output) contributions from
+//  neighboring chares
+//! \param[in] gid Global mesh node IDs at which we receive contributions
+//! \param[in] nesup Number of elements surrounding points
+//! \param[in] Lu Partial contributions of solution nodal fields to
+//!   chare-boundary nodes
+//! \param[in] Lp Partial contributions of primitive quantity nodal fields to
+//!   chare-boundary nodes
+// *****************************************************************************
+{
+  Assert( gid.size() == nesup.size(), "Size mismatch" );
+  Assert(Lu.size() == m_uNodefields.nprop(), "Fields size mismatch");
+  Assert(Lp.size() == m_pNodefields.nprop(), "Fields size mismatch");
+  for (std::size_t f=0; f<Lu.size(); ++f)
+    Assert( gid.size() == Lu[f].size(), "Size mismatch" );
+  for (std::size_t f=0; f<Lp.size(); ++f)
+    Assert( gid.size() == Lp[f].size(), "Size mismatch" );
+
+  for (std::size_t i=0; i<gid.size(); ++i) {
+    auto& nfu = m_uNodefieldsc[ gid[i] ];
+    nfu.first.resize( Lu.size() );
+    for (std::size_t f=0; f<Lu.size(); ++f) nfu.first[f] += Lu[f][i];
+    nfu.second += nesup[i];
+    auto& nfp = m_pNodefieldsc[ gid[i] ];
+    nfp.first.resize( Lp.size() );
+    for (std::size_t f=0; f<Lp.size(); ++f) nfp.first[f] += Lp[f][i];
+    nfp.second += nesup[i];
+  }
+
+  // When we have heard from all chares we communicate with, this chare is done
+  if (++m_nnod == Disc()->NodeCommMap().size()) {
+    m_nnod = 0;
+    comnodeout_complete();
+  }
+}
+
+void
+FV::stage()
+// *****************************************************************************
+// Evaluate whether to continue with next time step stage
+// *****************************************************************************
+{
+  // Increment Runge-Kutta stage counter
+  ++m_stage;
+
+  // if not all Runge-Kutta stages complete, continue to next time stage,
+  // otherwise prepare for nodal field output
+  if (m_stage < m_nrk)
+    next();
+  else
+    startFieldOutput( CkCallback(CkIndex_FV::step(), thisProxy[thisIndex]) );
+}
+
+void
+FV::evalLB( int nrestart )
+// *****************************************************************************
+// Evaluate whether to do load balancing
+//! \param[in] nrestart Number of times restarted
+// *****************************************************************************
+{
+  auto d = Disc();
+
+  // Detect if just returned from a checkpoint and if so, zero timers and flag
+  if (d->restarted( nrestart )) m_finished = 0;
+
+  const auto lbfreq = g_inputdeck.get< tag::cmd, tag::lbfreq >();
+  const auto nonblocking = g_inputdeck.get< tag::cmd, tag::nonblocking >();
+
+  // Load balancing if user frequency is reached or after the second time-step
+  if ( (d->It()) % lbfreq == 0 || d->It() == 2 ) {
+
+    AtSync();
+    if (nonblocking) next();
+
+  } else {
+
+    next();
+
+  }
+}
+
+void
+FV::evalRestart()
+// *****************************************************************************
+// Evaluate whether to save checkpoint/restart
+// *****************************************************************************
+{
+  auto d = Disc();
+
+  const auto rsfreq = g_inputdeck.get< tag::cmd, tag::rsfreq >();
+  const auto benchmark = g_inputdeck.get< tag::cmd, tag::benchmark >();
+
+  if ( !benchmark && (d->It()) % rsfreq == 0 ) {
+
+    std::vector< std::size_t > meshdata{ /* finished = */ 0, d->MeshId() };
+    contribute( meshdata, CkReduction::nop,
+      CkCallback(CkReductionTarget(Transporter,checkpoint), d->Tr()) );
+
+  } else {
+
+    evalLB( /* nrestart = */ -1 );
+
+  }
+}
+
+void
+FV::step()
+// *****************************************************************************
+// Evaluate wether to continue with next time step
+// *****************************************************************************
+{
+  auto d = Disc();
+
+  // Output time history
+  if (d->histiter() or d->histtime() or d->histrange()) {
+    std::vector< std::vector< tk::real > > hist;
+    auto h = g_fvpde[d->MeshId()].histOutput( d->Hist(), myGhosts()->m_inpoel,
+      myGhosts()->m_coord, m_u, m_p );
+    hist.insert( end(hist), begin(h), end(h) );
+    d->history( std::move(hist) );
+  }
+
+  // Output one-liner status report to screen
+  d->status();
+  // Reset Runge-Kutta stage counter
+  m_stage = 0;
+
+  // If neither max iterations nor max time reached, continue, otherwise finish
+  if (not m_finished) {
+
+    evalRestart();
+ 
+  } else {
+
+    auto meshid = d->MeshId();
+    d->contribute( sizeof(std::size_t), &meshid, CkReduction::nop,
+                   CkCallback(CkReductionTarget(Transporter,finish), d->Tr()) );
+
+  }
+}
+
+#include "NoWarning/fv.def.h"
 
diff --git a/Debug/cppcheck/52.html b/Debug/cppcheck/52.html index 6488ca528521..1f452312f8e9 100644 --- a/Debug/cppcheck/52.html +++ b/Debug/cppcheck/52.html @@ -152,259 +152,3237 @@
- - - - - - - - - - - + + + + + + + + + + - + - + - - + + - + - + - + - + - - + + @@ -274,52 +274,52 @@ - + - - + + - - + + - + - + - - + + - + - - + + - - + + - + - + - - + + diff --git a/Debug/test_coverage/Base/index-sort-l.html b/Debug/test_coverage/Base/index-sort-l.html index cc45379a7b0c..3bb0edc3df23 100644 --- a/Debug/test_coverage/Base/index-sort-l.html +++ b/Debug/test_coverage/Base/index-sort-l.html @@ -27,16 +27,16 @@ - + - + - + - + @@ -49,9 +49,9 @@ - + - +
  1
-  2
-  3
-  4
-  5
-  6
-  7
-  8
-  9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
- 37
- 38
- 39
- 40
- 41
- 42
- 43
- 44
- 45
- 46
- 47
- 48
- 49
- 50
- 51
- 52
- 53
- 54
- 55
- 56
- 57
- 58
- 59
- 60
- 61
- 62
- 63
- 64
- 65
- 66
- 67
- 68
- 69
- 70
- 71
- 72
- 73
- 74
- 75
- 76
- 77
- 78
- 79
- 80
- 81
- 82
- 83
- 84
- 85
- 86
- 87
- 88
- 89
- 90
- 91
- 92
- 93
- 94
- 95
- 96
- 97
- 98
- 99
-100
-101
-102
-103
-104
-105
-106
-107
-108
-109
-110
-111
-112
-113
-114
-115
-116
-117
-118
-119
-120
-121
-122
-123
// *****************************************************************************
+
   1
+   2
+   3
+   4
+   5
+   6
+   7
+   8
+   9
+  10
+  11
+  12
+  13
+  14
+  15
+  16
+  17
+  18
+  19
+  20
+  21
+  22
+  23
+  24
+  25
+  26
+  27
+  28
+  29
+  30
+  31
+  32
+  33
+  34
+  35
+  36
+  37
+  38
+  39
+  40
+  41
+  42
+  43
+  44
+  45
+  46
+  47
+  48
+  49
+  50
+  51
+  52
+  53
+  54
+  55
+  56
+  57
+  58
+  59
+  60
+  61
+  62
+  63
+  64
+  65
+  66
+  67
+  68
+  69
+  70
+  71
+  72
+  73
+  74
+  75
+  76
+  77
+  78
+  79
+  80
+  81
+  82
+  83
+  84
+  85
+  86
+  87
+  88
+  89
+  90
+  91
+  92
+  93
+  94
+  95
+  96
+  97
+  98
+  99
+ 100
+ 101
+ 102
+ 103
+ 104
+ 105
+ 106
+ 107
+ 108
+ 109
+ 110
+ 111
+ 112
+ 113
+ 114
+ 115
+ 116
+ 117
+ 118
+ 119
+ 120
+ 121
+ 122
+ 123
+ 124
+ 125
+ 126
+ 127
+ 128
+ 129
+ 130
+ 131
+ 132
+ 133
+ 134
+ 135
+ 136
+ 137
+ 138
+ 139
+ 140
+ 141
+ 142
+ 143
+ 144
+ 145
+ 146
+ 147
+ 148
+ 149
+ 150
+ 151
+ 152
+ 153
+ 154
+ 155
+ 156
+ 157
+ 158
+ 159
+ 160
+ 161
+ 162
+ 163
+ 164
+ 165
+ 166
+ 167
+ 168
+ 169
+ 170
+ 171
+ 172
+ 173
+ 174
+ 175
+ 176
+ 177
+ 178
+ 179
+ 180
+ 181
+ 182
+ 183
+ 184
+ 185
+ 186
+ 187
+ 188
+ 189
+ 190
+ 191
+ 192
+ 193
+ 194
+ 195
+ 196
+ 197
+ 198
+ 199
+ 200
+ 201
+ 202
+ 203
+ 204
+ 205
+ 206
+ 207
+ 208
+ 209
+ 210
+ 211
+ 212
+ 213
+ 214
+ 215
+ 216
+ 217
+ 218
+ 219
+ 220
+ 221
+ 222
+ 223
+ 224
+ 225
+ 226
+ 227
+ 228
+ 229
+ 230
+ 231
+ 232
+ 233
+ 234
+ 235
+ 236
+ 237
+ 238
+ 239
+ 240
+ 241
+ 242
+ 243
+ 244
+ 245
+ 246
+ 247
+ 248
+ 249
+ 250
+ 251
+ 252
+ 253
+ 254
+ 255
+ 256
+ 257
+ 258
+ 259
+ 260
+ 261
+ 262
+ 263
+ 264
+ 265
+ 266
+ 267
+ 268
+ 269
+ 270
+ 271
+ 272
+ 273
+ 274
+ 275
+ 276
+ 277
+ 278
+ 279
+ 280
+ 281
+ 282
+ 283
+ 284
+ 285
+ 286
+ 287
+ 288
+ 289
+ 290
+ 291
+ 292
+ 293
+ 294
+ 295
+ 296
+ 297
+ 298
+ 299
+ 300
+ 301
+ 302
+ 303
+ 304
+ 305
+ 306
+ 307
+ 308
+ 309
+ 310
+ 311
+ 312
+ 313
+ 314
+ 315
+ 316
+ 317
+ 318
+ 319
+ 320
+ 321
+ 322
+ 323
+ 324
+ 325
+ 326
+ 327
+ 328
+ 329
+ 330
+ 331
+ 332
+ 333
+ 334
+ 335
+ 336
+ 337
+ 338
+ 339
+ 340
+ 341
+ 342
+ 343
+ 344
+ 345
+ 346
+ 347
+ 348
+ 349
+ 350
+ 351
+ 352
+ 353
+ 354
+ 355
+ 356
+ 357
+ 358
+ 359
+ 360
+ 361
+ 362
+ 363
+ 364
+ 365
+ 366
+ 367
+ 368
+ 369
+ 370
+ 371
+ 372
+ 373
+ 374
+ 375
+ 376
+ 377
+ 378
+ 379
+ 380
+ 381
+ 382
+ 383
+ 384
+ 385
+ 386
+ 387
+ 388
+ 389
+ 390
+ 391
+ 392
+ 393
+ 394
+ 395
+ 396
+ 397
+ 398
+ 399
+ 400
+ 401
+ 402
+ 403
+ 404
+ 405
+ 406
+ 407
+ 408
+ 409
+ 410
+ 411
+ 412
+ 413
+ 414
+ 415
+ 416
+ 417
+ 418
+ 419
+ 420
+ 421
+ 422
+ 423
+ 424
+ 425
+ 426
+ 427
+ 428
+ 429
+ 430
+ 431
+ 432
+ 433
+ 434
+ 435
+ 436
+ 437
+ 438
+ 439
+ 440
+ 441
+ 442
+ 443
+ 444
+ 445
+ 446
+ 447
+ 448
+ 449
+ 450
+ 451
+ 452
+ 453
+ 454
+ 455
+ 456
+ 457
+ 458
+ 459
+ 460
+ 461
+ 462
+ 463
+ 464
+ 465
+ 466
+ 467
+ 468
+ 469
+ 470
+ 471
+ 472
+ 473
+ 474
+ 475
+ 476
+ 477
+ 478
+ 479
+ 480
+ 481
+ 482
+ 483
+ 484
+ 485
+ 486
+ 487
+ 488
+ 489
+ 490
+ 491
+ 492
+ 493
+ 494
+ 495
+ 496
+ 497
+ 498
+ 499
+ 500
+ 501
+ 502
+ 503
+ 504
+ 505
+ 506
+ 507
+ 508
+ 509
+ 510
+ 511
+ 512
+ 513
+ 514
+ 515
+ 516
+ 517
+ 518
+ 519
+ 520
+ 521
+ 522
+ 523
+ 524
+ 525
+ 526
+ 527
+ 528
+ 529
+ 530
+ 531
+ 532
+ 533
+ 534
+ 535
+ 536
+ 537
+ 538
+ 539
+ 540
+ 541
+ 542
+ 543
+ 544
+ 545
+ 546
+ 547
+ 548
+ 549
+ 550
+ 551
+ 552
+ 553
+ 554
+ 555
+ 556
+ 557
+ 558
+ 559
+ 560
+ 561
+ 562
+ 563
+ 564
+ 565
+ 566
+ 567
+ 568
+ 569
+ 570
+ 571
+ 572
+ 573
+ 574
+ 575
+ 576
+ 577
+ 578
+ 579
+ 580
+ 581
+ 582
+ 583
+ 584
+ 585
+ 586
+ 587
+ 588
+ 589
+ 590
+ 591
+ 592
+ 593
+ 594
+ 595
+ 596
+ 597
+ 598
+ 599
+ 600
+ 601
+ 602
+ 603
+ 604
+ 605
+ 606
+ 607
+ 608
+ 609
+ 610
+ 611
+ 612
+ 613
+ 614
+ 615
+ 616
+ 617
+ 618
+ 619
+ 620
+ 621
+ 622
+ 623
+ 624
+ 625
+ 626
+ 627
+ 628
+ 629
+ 630
+ 631
+ 632
+ 633
+ 634
+ 635
+ 636
+ 637
+ 638
+ 639
+ 640
+ 641
+ 642
+ 643
+ 644
+ 645
+ 646
+ 647
+ 648
+ 649
+ 650
+ 651
+ 652
+ 653
+ 654
+ 655
+ 656
+ 657
+ 658
+ 659
+ 660
+ 661
+ 662
+ 663
+ 664
+ 665
+ 666
+ 667
+ 668
+ 669
+ 670
+ 671
+ 672
+ 673
+ 674
+ 675
+ 676
+ 677
+ 678
+ 679
+ 680
+ 681
+ 682
+ 683
+ 684
+ 685
+ 686
+ 687
+ 688
+ 689
+ 690
+ 691
+ 692
+ 693
+ 694
+ 695
+ 696
+ 697
+ 698
+ 699
+ 700
+ 701
+ 702
+ 703
+ 704
+ 705
+ 706
+ 707
+ 708
+ 709
+ 710
+ 711
+ 712
+ 713
+ 714
+ 715
+ 716
+ 717
+ 718
+ 719
+ 720
+ 721
+ 722
+ 723
+ 724
+ 725
+ 726
+ 727
+ 728
+ 729
+ 730
+ 731
+ 732
+ 733
+ 734
+ 735
+ 736
+ 737
+ 738
+ 739
+ 740
+ 741
+ 742
+ 743
+ 744
+ 745
+ 746
+ 747
+ 748
+ 749
+ 750
+ 751
+ 752
+ 753
+ 754
+ 755
+ 756
+ 757
+ 758
+ 759
+ 760
+ 761
+ 762
+ 763
+ 764
+ 765
+ 766
+ 767
+ 768
+ 769
+ 770
+ 771
+ 772
+ 773
+ 774
+ 775
+ 776
+ 777
+ 778
+ 779
+ 780
+ 781
+ 782
+ 783
+ 784
+ 785
+ 786
+ 787
+ 788
+ 789
+ 790
+ 791
+ 792
+ 793
+ 794
+ 795
+ 796
+ 797
+ 798
+ 799
+ 800
+ 801
+ 802
+ 803
+ 804
+ 805
+ 806
+ 807
+ 808
+ 809
+ 810
+ 811
+ 812
+ 813
+ 814
+ 815
+ 816
+ 817
+ 818
+ 819
+ 820
+ 821
+ 822
+ 823
+ 824
+ 825
+ 826
+ 827
+ 828
+ 829
+ 830
+ 831
+ 832
+ 833
+ 834
+ 835
+ 836
+ 837
+ 838
+ 839
+ 840
+ 841
+ 842
+ 843
+ 844
+ 845
+ 846
+ 847
+ 848
+ 849
+ 850
+ 851
+ 852
+ 853
+ 854
+ 855
+ 856
+ 857
+ 858
+ 859
+ 860
+ 861
+ 862
+ 863
+ 864
+ 865
+ 866
+ 867
+ 868
+ 869
+ 870
+ 871
+ 872
+ 873
+ 874
+ 875
+ 876
+ 877
+ 878
+ 879
+ 880
+ 881
+ 882
+ 883
+ 884
+ 885
+ 886
+ 887
+ 888
+ 889
+ 890
+ 891
+ 892
+ 893
+ 894
+ 895
+ 896
+ 897
+ 898
+ 899
+ 900
+ 901
+ 902
+ 903
+ 904
+ 905
+ 906
+ 907
+ 908
+ 909
+ 910
+ 911
+ 912
+ 913
+ 914
+ 915
+ 916
+ 917
+ 918
+ 919
+ 920
+ 921
+ 922
+ 923
+ 924
+ 925
+ 926
+ 927
+ 928
+ 929
+ 930
+ 931
+ 932
+ 933
+ 934
+ 935
+ 936
+ 937
+ 938
+ 939
+ 940
+ 941
+ 942
+ 943
+ 944
+ 945
+ 946
+ 947
+ 948
+ 949
+ 950
+ 951
+ 952
+ 953
+ 954
+ 955
+ 956
+ 957
+ 958
+ 959
+ 960
+ 961
+ 962
+ 963
+ 964
+ 965
+ 966
+ 967
+ 968
+ 969
+ 970
+ 971
+ 972
+ 973
+ 974
+ 975
+ 976
+ 977
+ 978
+ 979
+ 980
+ 981
+ 982
+ 983
+ 984
+ 985
+ 986
+ 987
+ 988
+ 989
+ 990
+ 991
+ 992
+ 993
+ 994
+ 995
+ 996
+ 997
+ 998
+ 999
+1000
+1001
+1002
+1003
+1004
+1005
+1006
+1007
+1008
+1009
+1010
+1011
+1012
+1013
+1014
+1015
+1016
+1017
+1018
+1019
+1020
+1021
+1022
+1023
+1024
+1025
+1026
+1027
+1028
+1029
+1030
+1031
+1032
+1033
+1034
+1035
+1036
+1037
+1038
+1039
+1040
+1041
+1042
+1043
+1044
+1045
+1046
+1047
+1048
+1049
+1050
+1051
+1052
+1053
+1054
+1055
+1056
+1057
+1058
+1059
+1060
+1061
+1062
+1063
+1064
+1065
+1066
+1067
+1068
+1069
+1070
+1071
+1072
+1073
+1074
+1075
+1076
+1077
+1078
+1079
+1080
+1081
+1082
+1083
+1084
+1085
+1086
+1087
+1088
+1089
+1090
+1091
+1092
+1093
+1094
+1095
+1096
+1097
+1098
+1099
+1100
+1101
+1102
+1103
+1104
+1105
+1106
+1107
+1108
+1109
+1110
+1111
+1112
+1113
+1114
+1115
+1116
+1117
+1118
+1119
+1120
+1121
+1122
+1123
+1124
+1125
+1126
+1127
+1128
+1129
+1130
+1131
+1132
+1133
+1134
+1135
+1136
+1137
+1138
+1139
+1140
+1141
+1142
+1143
+1144
+1145
+1146
+1147
+1148
+1149
+1150
+1151
+1152
+1153
+1154
+1155
+1156
+1157
+1158
+1159
+1160
+1161
+1162
+1163
+1164
+1165
+1166
+1167
+1168
+1169
+1170
+1171
+1172
+1173
+1174
+1175
+1176
+1177
+1178
+1179
+1180
+1181
+1182
+1183
+1184
+1185
+1186
+1187
+1188
+1189
+1190
+1191
+1192
+1193
+1194
+1195
+1196
+1197
+1198
+1199
+1200
+1201
+1202
+1203
+1204
+1205
+1206
+1207
+1208
+1209
+1210
+1211
+1212
+1213
+1214
+1215
+1216
+1217
+1218
+1219
+1220
+1221
+1222
+1223
+1224
+1225
+1226
+1227
+1228
+1229
+1230
+1231
+1232
+1233
+1234
+1235
+1236
+1237
+1238
+1239
+1240
+1241
+1242
+1243
+1244
+1245
+1246
+1247
+1248
+1249
+1250
+1251
+1252
+1253
+1254
+1255
+1256
+1257
+1258
+1259
+1260
+1261
+1262
+1263
+1264
+1265
+1266
+1267
+1268
+1269
+1270
+1271
+1272
+1273
+1274
+1275
+1276
+1277
+1278
+1279
+1280
+1281
+1282
+1283
+1284
+1285
+1286
+1287
+1288
+1289
+1290
+1291
+1292
+1293
+1294
+1295
+1296
+1297
+1298
+1299
+1300
+1301
+1302
+1303
+1304
+1305
+1306
+1307
+1308
+1309
+1310
+1311
+1312
+1313
+1314
+1315
+1316
+1317
+1318
+1319
+1320
+1321
+1322
+1323
+1324
+1325
+1326
+1327
+1328
+1329
+1330
+1331
+1332
+1333
+1334
+1335
+1336
+1337
+1338
+1339
+1340
+1341
+1342
+1343
+1344
+1345
+1346
+1347
+1348
+1349
+1350
+1351
+1352
+1353
+1354
+1355
+1356
+1357
+1358
+1359
+1360
+1361
+1362
+1363
+1364
+1365
+1366
+1367
+1368
+1369
+1370
+1371
+1372
+1373
+1374
+1375
+1376
+1377
+1378
+1379
+1380
+1381
+1382
+1383
+1384
+1385
+1386
+1387
+1388
+1389
+1390
+1391
+1392
+1393
+1394
+1395
+1396
+1397
+1398
+1399
+1400
+1401
+1402
+1403
+1404
+1405
+1406
+1407
+1408
+1409
+1410
+1411
+1412
+1413
+1414
+1415
+1416
+1417
+1418
+1419
+1420
+1421
+1422
+1423
+1424
+1425
+1426
+1427
+1428
+1429
+1430
+1431
+1432
+1433
+1434
+1435
+1436
+1437
+1438
+1439
+1440
+1441
+1442
+1443
+1444
+1445
+1446
+1447
+1448
+1449
+1450
+1451
+1452
+1453
+1454
+1455
+1456
+1457
+1458
+1459
+1460
+1461
+1462
+1463
+1464
+1465
+1466
+1467
+1468
+1469
+1470
+1471
+1472
+1473
+1474
+1475
+1476
+1477
+1478
+1479
+1480
+1481
+1482
+1483
+1484
+1485
+1486
+1487
+1488
+1489
+1490
+1491
+1492
+1493
+1494
+1495
+1496
+1497
+1498
+1499
+1500
+1501
+1502
+1503
+1504
+1505
+1506
+1507
+1508
+1509
+1510
+1511
+1512
+1513
+1514
+1515
+1516
+1517
+1518
+1519
+1520
+1521
+1522
+1523
+1524
+1525
+1526
+1527
+1528
+1529
+1530
+1531
+1532
+1533
+1534
+1535
+1536
+1537
+1538
+1539
+1540
+1541
+1542
+1543
+1544
+1545
+1546
+1547
+1548
+1549
+1550
+1551
+1552
+1553
+1554
+1555
+1556
+1557
+1558
+1559
+1560
+1561
+1562
+1563
+1564
+1565
+1566
+1567
+1568
+1569
+1570
+1571
+1572
+1573
+1574
+1575
+1576
+1577
+1578
+1579
+1580
+1581
+1582
+1583
+1584
+1585
+1586
+1587
+1588
+1589
+1590
+1591
+1592
+1593
+1594
+1595
+1596
+1597
+1598
+1599
+1600
+1601
+1602
+1603
+1604
+1605
+1606
+1607
+1608
+1609
+1610
+1611
+1612
// *****************************************************************************
 /*!
-  \file      src/PDE/ConfigureTransport.cpp
+  \file      src/Inciter/ALECG.cpp
   \copyright 2012-2015 J. Bakosi,
              2016-2018 Los Alamos National Security, LLC.,
              2019-2021 Triad National Security, LLC.
              All rights reserved. See the LICENSE file for details.
-  \brief     Register and compile configuration on the transport PDE
-  \details   Register and compile configuration on the transport PDE.
-*/
-// *****************************************************************************
-
-#include <set>
-#include <map>
-#include <vector>
-#include <string>
+  \brief     ALECG for a PDE system with continuous Galerkin + ALE + RK
+  \details   ALECG advances a system of partial differential equations (PDEs)
+    using a continuous Galerkin (CG) finite element (FE) spatial discretization
+    (using linear shapefunctions on tetrahedron elements) combined with a
+    Runge-Kutta (RK) time stepping scheme in the arbitrary Eulerian-Lagrangian
+    reference frame.
+  \see The documentation in ALECG.hpp.
+*/
+// *****************************************************************************
 
-#include <brigand/algorithms/for_each.hpp>
-
-#include "Tags.hpp"
-#include "CartesianProduct.hpp"
-#include "PDEFactory.hpp"
-#include "Inciter/Options/PDE.hpp"
-#include "ContainerUtil.hpp"
-#include "ConfigureTransport.hpp"
-#include "Transport/Physics/CG.hpp"
-#include "Transport/Physics/DG.hpp"
-#include "Transport/CGTransport.hpp"
-#include "Transport/DGTransport.hpp"
-#include "Transport/Problem.hpp"
-
-namespace inciter {
-
-void
-registerTransport( CGFactory& cf,
-                   DGFactory& df,
-                   std::set< ctr::PDEType >& cgt,
-                   std::set< ctr::PDEType >& dgt )
-// *****************************************************************************
-// Register transport PDE into PDE factory
-//! \param[in,out] cf Continuous Galerkin PDE factory to register to
-//! \param[in,out] df Discontinuous Galerkin PDE factory to register to
-//! \param[in,out] cgt Counters for equation types registered into CG factory
-//! \param[in,out] dgt Counters for equation types registered into DG factory
-// *****************************************************************************
-{
-  // Construct vector of vectors for all possible policies
-  using CGTransportPolicies =
-    tk::cartesian_product< cg::TransportPhysics, TransportProblems >;
-  // Register PDEs for all combinations of policies
-  brigand::for_each< CGTransportPolicies >(
-    registerCG< cg::Transport >( cf, cgt, ctr::PDEType::TRANSPORT ) );
-
-  // Construct vector of vectors for all possible policies
-  using DGTransportPolicies =
-    tk::cartesian_product< dg::TransportPhysics, TransportProblems >;
-  // Register PDEs for all combinations of policies
-  brigand::for_each< DGTransportPolicies >(
-    registerDG< dg::Transport >( df, dgt, ctr::PDEType::TRANSPORT ) );
-}
-
-std::vector< std::pair< std::string, std::string > >
-infoTransport( std::map< ctr::PDEType, tk::ncomp_t >& cnt )
-// *****************************************************************************
-//  Return information on the transport PDE
-//! \param[inout] cnt std::map of counters for all PDE types
-//! \return vector of string pairs describing the PDE configuration
-// *****************************************************************************
-{
-  using tk::parameters;
-  using eq = tag::transport;
-
-  auto c = ++cnt[ ctr::PDEType::TRANSPORT ];       // count eqs
-  --c;  // used to index vectors starting with 0<--- Variable 'c' is assigned a value that is never used.
-
-  std::vector< std::pair< std::string, std::string > > nfo;
-
-  nfo.emplace_back( ctr::PDE().name( ctr::PDEType::TRANSPORT ), "" );
-
-  nfo.emplace_back( "problem", ctr::Problem().name(
-    g_inputdeck.get< eq, tag::problem >() ) );
-
-  auto intsharp = g_inputdeck.get< eq, tag::intsharp >();
-  nfo.emplace_back( "interface sharpening", std::to_string( intsharp ) );
-
-  auto ncomp = g_inputdeck.get< tag::ncomp >();
-  nfo.emplace_back( "number of components", std::to_string( ncomp ) );
-
-  const auto& bc = g_inputdeck.get< tag::bc >();
-  for (const auto& ib : bc) {
-    const auto& bcdir = ib.get< tag::dirichlet >();
-    if (!bcdir.empty())
-      nfo.emplace_back( "Dirichlet boundary [" + std::to_string( ncomp ) + "]",
-        parameters( bcdir ) );
-
-    const auto& bcsym = ib.get< tag::symmetry >();
-    if (!bcsym.empty())
-      nfo.emplace_back( "Symmetry boundary [" + std::to_string( ncomp ) + "]",
-        parameters( bcsym ) );
-
-    const auto& bcinlet =
-      ib.get< tag::inlet >();
-    if (!bcinlet.empty())
-      nfo.emplace_back( "Inlet boundary [" + std::to_string( ncomp ) + "]",
-        parameters( bcinlet ) );
-
-    const auto& bcoutlet =
-      ib.get< tag::outlet >();
-    if (!bcoutlet.empty())
-      nfo.emplace_back( "Outlet boundary [" + std::to_string( ncomp ) + "]",
-        parameters( bcoutlet ) );
-
-    const auto& bcextrapolate =
-      ib.get< tag::extrapolate >();
-    if (!bcextrapolate.empty())
-      nfo.emplace_back( "Symmetry boundary [" + std::to_string( ncomp ) + "]",
-        parameters( bcextrapolate ) );
-  }
-
-  return nfo;
-}
-
-}  // inciter::
+#include "QuinoaBuildConfig.hpp"
+#include "ALECG.hpp"
+#include "Vector.hpp"
+#include "Reader.hpp"
+#include "ContainerUtil.hpp"
+#include "UnsMesh.hpp"
+#include "ExodusIIMeshWriter.hpp"
+#include "Inciter/InputDeck/InputDeck.hpp"
+#include "DerivedData.hpp"
+#include "CGPDE.hpp"
+#include "Discretization.hpp"
+#include "DiagReducer.hpp"
+#include "NodeBC.hpp"
+#include "Refiner.hpp"
+#include "Reorder.hpp"
+#include "Around.hpp"
+#include "CGPDE.hpp"
+#include "Integrate/Mass.hpp"
+#include "FieldOutput.hpp"
+
+namespace inciter {
+
+extern ctr::InputDeck g_inputdeck;
+extern std::vector< CGPDE > g_cgpde;
+
+//! Runge-Kutta coefficients
+static const std::array< tk::real, 3 > rkcoef{{ 1.0/3.0, 1.0/2.0, 1.0 }};
+
+} // inciter::
+
+using inciter::ALECG;
+
+ALECG::ALECG( const CProxy_Discretization& disc,
+              const CProxy_Ghosts&,
+              const std::map< int, std::vector< std::size_t > >& bface,
+              const std::map< int, std::vector< std::size_t > >& bnode,
+              const std::vector< std::size_t >& triinpoel ) :
+  m_disc( disc ),
+  m_nsol( 0 ),
+  m_ngrad( 0 ),
+  m_nrhs( 0 ),
+  m_nbnorm( 0 ),
+  m_ndfnorm( 0 ),
+  m_nmblk( 0 ),
+  m_bnode( bnode ),
+  m_bface( bface ),
+  m_triinpoel( tk::remap( triinpoel, Disc()->Lid() ) ),
+  m_bndel( Disc()->bndel() ),
+  m_dfnorm(),
+  m_dfnormc(),
+  m_dfn(),
+  m_esup( tk::genEsup( Disc()->Inpoel(), 4 ) ),
+  m_psup( tk::genPsup( Disc()->Inpoel(), 4, m_esup ) ),
+  m_u( Disc()->Gid().size(),
+       g_inputdeck.get< tag::ncomp >() ),
+  m_un( m_u.nunk(), m_u.nprop() ),
+  m_rhs( m_u.nunk(), m_u.nprop() ),
+  m_rhsc(),
+  m_chBndGrad( Disc()->Bid().size(), m_u.nprop()*3 ),
+  m_dirbc(),
+  m_chBndGradc(),
+  m_diag(),
+  m_bnorm(),
+  m_bnormc(),
+  m_symbcnodes(),
+  m_farfieldbcnodes(),
+  m_symbctri(),
+  m_timedepbcnodes(),
+  m_timedepbcFn(),
+  m_stage( 0 ),
+  m_boxnodes(),
+  m_edgenode(),
+  m_edgeid(),
+  m_dtp( m_u.nunk(), 0.0 ),
+  m_tp( m_u.nunk(), g_inputdeck.get< tag::t0 >() ),
+  m_finished( 0 ),
+  m_newmesh( 0 ),
+  m_refinedmesh( 0 ),
+  m_nusermeshblk( 0 ),
+  m_nodeblockid(),
+  m_nodeblockidc()
+// *****************************************************************************
+//  Constructor
+//! \param[in] disc Discretization proxy
+//! \param[in] bface Boundary-faces mapped to side sets used in the input file
+//! \param[in] bnode Boundary-node lists mapped to side sets used in input file
+//! \param[in] triinpoel Boundary-face connectivity where BCs set (global ids)
+// *****************************************************************************
+//! [Constructor]
+{
+  usesAtSync = true;    // enable migration at AtSync
+
+  auto d = Disc();
+
+  // Perform optional operator-access-pattern mesh node reordering
+  if (g_inputdeck.get< tag::operator_reorder >()) {
+
+    // Create new local ids based on access pattern of PDE operators
+    std::unordered_map< std::size_t, std::size_t > map;
+    std::size_t n = 0;
+
+    for (std::size_t p=0; p<m_u.nunk(); ++p) {  // for each point p
+      if (map.find(p) == end(map)) map[p] = n++;<--- Searching before insertion is not necessary.
+      for (auto q : tk::Around(m_psup,p)) {     // for each edge p-q
+        if (map.find(q) == end(map)) map[q] = n++;<--- Searching before insertion is not necessary.
+      }
+    }
+
+    Assert( map.size() == d->Gid().size(), "Map size mismatch" );
+
+    // Remap data in bound Discretization object
+    d->remap( map );
+    // Recompute elements surrounding points
+    m_esup = tk::genEsup( d->Inpoel(), 4 );
+    // Recompute points surrounding points
+    m_psup = tk::genPsup( d->Inpoel(), 4, m_esup );
+    // Remap boundary triangle face connectivity
+    tk::remap( m_triinpoel, map );
+  }
+
+  // Query/update boundary-conditions-related data structures from user input
+  queryBnd();
+
+  // Activate SDAG wait for initially computing normals, and mesh blocks
+  thisProxy[ thisIndex ].wait4norm();
+  thisProxy[ thisIndex ].wait4meshblk();
+
+  d->comfinal();
+
+}
+//! [Constructor]
+
+void
+ALECG::queryBnd()
+// *****************************************************************************
+// Query/update boundary-conditions-related data structures from user input
+// *****************************************************************************
+{
+  auto d = Disc();
+
+  // Query and match user-specified Dirichlet boundary conditions to side sets
+  const auto steady = g_inputdeck.get< tag::steady_state >();
+  if (steady) for (auto& deltat : m_dtp) deltat *= rkcoef[m_stage];<--- Consider using std::transform algorithm instead of a raw loop.
+  m_dirbc = match( d->MeshId(), m_u.nprop(), d->T(), rkcoef[m_stage] * d->Dt(),
+                   m_tp, m_dtp, d->Coord(), d->Lid(), m_bnode,
+                   /* increment = */ false );
+  if (steady) for (auto& deltat : m_dtp) deltat /= rkcoef[m_stage];<--- Consider using std::transform algorithm instead of a raw loop.
+
+  // Prepare unique set of symmetry BC nodes
+  auto sym = d->bcnodes< tag::symmetry >( m_bface, m_triinpoel );
+  for (const auto& [s,nodes] : sym)
+    m_symbcnodes.insert( begin(nodes), end(nodes) );
+
+  // Prepare unique set of farfield BC nodes
+  auto far = d->bcnodes< tag::farfield >( m_bface, m_triinpoel );
+  for (const auto& [s,nodes] : far)
+    m_farfieldbcnodes.insert( begin(nodes), end(nodes) );
+
+  // If farfield BC is set on a node, will not also set symmetry BC
+  for (auto fn : m_farfieldbcnodes) m_symbcnodes.erase(fn);
+
+  // Prepare boundary nodes contiguously accessible from a triangle-face loop
+  m_symbctri.resize( m_triinpoel.size()/3, 0 );
+  for (std::size_t e=0; e<m_triinpoel.size()/3; ++e)
+    if (m_symbcnodes.find(m_triinpoel[e*3+0]) != end(m_symbcnodes))
+      m_symbctri[e] = 1;
+
+  // Prepare unique set of time dependent BC nodes
+  m_timedepbcnodes.clear();
+  m_timedepbcFn.clear();
+  const auto& timedep =
+    g_inputdeck.get< tag::bc >()[d->MeshId()].get< tag::timedep >();
+  if (!timedep.empty()) {
+    m_timedepbcnodes.resize(timedep.size());
+    m_timedepbcFn.resize(timedep.size());
+    std::size_t ib=0;
+    for (const auto& bndry : timedep) {
+      std::unordered_set< std::size_t > nodes;
+      for (const auto& s : bndry.template get< tag::sideset >()) {
+        auto k = m_bnode.find(static_cast<int>(s));
+        if (k != end(m_bnode)) {
+          for (auto g : k->second) {      // global node ids on side set
+            nodes.insert( tk::cref_find(d->Lid(),g) );
+          }
+        }
+      }
+      m_timedepbcnodes[ib].insert( begin(nodes), end(nodes) );
+
+      // Store user defined discrete function in time. This is done in the same
+      // loop as the BC nodes, so that the indices for the two vectors
+      // m_timedepbcnodes and m_timedepbcFn are consistent with each other
+      auto fn = bndry.template get< tag::fn >();
+      for (std::size_t ir=0; ir<fn.size()/6; ++ir) {
+        m_timedepbcFn[ib].push_back({{ fn[ir*6+0], fn[ir*6+1], fn[ir*6+2],
+          fn[ir*6+3], fn[ir*6+4], fn[ir*6+5] }});
+      }
+      ++ib;
+    }
+  }
+
+  Assert(m_timedepbcFn.size() == m_timedepbcnodes.size(), "Incorrect number of "
+    "time dependent functions.");
+
+  // Query ALE mesh velocity boundary condition node lists and node lists at
+  // which ALE moves boundaries
+  d->meshvelBnd( m_bface, m_bnode, m_triinpoel );
+}
+
+void
+ALECG::norm()
+// *****************************************************************************
+// Start (re-)computing boundary point-, and dual-face normals
+// *****************************************************************************
+{
+  auto d = Disc();
+
+  // Query nodes at which symmetry BCs are specified
+  auto bn = d->bcnodes< tag::symmetry >( m_bface, m_triinpoel );
+
+  // Query nodes at which farfield BCs are specified
+  auto far = d->bcnodes< tag::farfield >( m_bface, m_triinpoel );
+  // Merge BC data where boundary-point normals are required
+  for (const auto& [s,n] : far) bn[s].insert( begin(n), end(n) );
+
+  // Query nodes at which mesh velocity symmetry BCs are specified
+  std::unordered_map<int, std::unordered_set< std::size_t >> ms;
+  for (const auto& s : g_inputdeck.get< tag::ale, tag::symmetry >()) {
+    auto k = m_bface.find(static_cast<int>(s));
+    if (k != end(m_bface)) {
+      auto& n = ms[ k->first ];
+      for (auto f : k->second) {
+        n.insert( m_triinpoel[f*3+0] );
+        n.insert( m_triinpoel[f*3+1] );
+        n.insert( m_triinpoel[f*3+2] );
+      }
+    }
+  }
+  // Merge BC data where boundary-point normals are required
+  for (const auto& [s,n] : ms) bn[s].insert( begin(n), end(n) );
+
+  // Compute boundary point normals
+  bnorm( bn );
+
+  // Compute dual-face normals associated to edges
+  dfnorm();
+}
+
+std::array< tk::real, 3 >
+ALECG::edfnorm( const tk::UnsMesh::Edge& edge,
+                const std::unordered_map< tk::UnsMesh::Edge,
+                        std::vector< std::size_t >,
+                        tk::UnsMesh::Hash<2>, tk::UnsMesh::Eq<2> >& esued )
+const
+// *****************************************************************************
+//  Compute normal of dual-mesh associated to edge
+//! \param[in] edge Edge whose dual-face normal to compute given by local ids
+//! \param[in] esued Elements surrounding edges
+//! \return Dual-face normal for edge
+// *****************************************************************************
+{
+  auto d = Disc();
+  const auto& inpoel = d->Inpoel();
+  const auto& coord = d->Coord();
+  const auto& x = coord[0];
+  const auto& y = coord[1];
+  const auto& z = coord[2];
+
+  std::array< tk::real, 3 > n{ 0.0, 0.0, 0.0 };
+
+  for (auto e : tk::cref_find(esued,edge)) {
+    // access node IDs
+    const std::array< std::size_t, 4 >
+      N{ inpoel[e*4+0], inpoel[e*4+1], inpoel[e*4+2], inpoel[e*4+3] };
+    // compute element Jacobi determinant
+    const std::array< tk::real, 3 >
+      ba{{ x[N[1]]-x[N[0]], y[N[1]]-y[N[0]], z[N[1]]-z[N[0]] }},
+      ca{{ x[N[2]]-x[N[0]], y[N[2]]-y[N[0]], z[N[2]]-z[N[0]] }},
+      da{{ x[N[3]]-x[N[0]], y[N[3]]-y[N[0]], z[N[3]]-z[N[0]] }};
+    const auto J = tk::triple( ba, ca, da );        // J = 6V
+    Assert( J > 0, "Element Jacobian non-positive" );
+    // shape function derivatives, nnode*ndim [4][3]
+    std::array< std::array< tk::real, 3 >, 4 > grad;
+    grad[1] = tk::crossdiv( ca, da, J );
+    grad[2] = tk::crossdiv( da, ba, J );
+    grad[3] = tk::crossdiv( ba, ca, J );
+    for (std::size_t i=0; i<3; ++i)
+      grad[0][i] = -grad[1][i]-grad[2][i]-grad[3][i];
+    // sum normal contributions
+    // The constant 1/48: Eq (12) from Waltz et al. Computers & fluids (92) 2014
+    // The result of the integral of shape function N on a tet is V/4.
+    // This can be written as J/(6*4). Eq (12) has a 1/2 multiplier.
+    // This leads to J/48.
+    auto J48 = J/48.0;
+    for (const auto& [a,b] : tk::lpoed) {
+      auto s = tk::orient( {N[a],N[b]}, edge );
+      for (std::size_t j=0; j<3; ++j)
+        n[j] += J48 * s * (grad[a][j] - grad[b][j]);
+    }
+  }
+
+  return n;
+}
+
+void
+ALECG::dfnorm()
+// *****************************************************************************
+// Compute dual-face normals associated to edges
+// *****************************************************************************
+{
+  auto d = Disc();
+  const auto& inpoel = d->Inpoel();
+  const auto& gid = d->Gid();
+
+  // compute derived data structures
+  auto esued = tk::genEsued( inpoel, 4, tk::genEsup( inpoel, 4 ) );
+
+  // Compute dual-face normals for domain edges
+  for (std::size_t p=0; p<gid.size(); ++p)    // for each point p
+    for (auto q : tk::Around(m_psup,p))       // for each edge p-q
+      if (gid[p] < gid[q])
+        m_dfnorm[{gid[p],gid[q]}] = edfnorm( {p,q}, esued );
+
+  // Send our dual-face normal contributions to neighbor chares
+  if (d->EdgeCommMap().empty())
+    comdfnorm_complete();
+  else {
+    for (const auto& [c,edges] : d->EdgeCommMap()) {
+      decltype(m_dfnorm) exp;
+      for (const auto& e : edges) exp[e] = tk::cref_find(m_dfnorm,e);
+      thisProxy[c].comdfnorm( exp );
+    }
+  }
+
+  owndfnorm_complete();
+}
+
+void
+ALECG::comdfnorm( const std::unordered_map< tk::UnsMesh::Edge,
+                    std::array< tk::real, 3 >,
+                    tk::UnsMesh::Hash<2>, tk::UnsMesh::Eq<2> >& dfnorm )
+// *****************************************************************************
+// Receive contributions to dual-face normals on chare-boundaries
+//! \param[in] dfnorm Incoming partial sums of dual-face normals associated to
+//!   chare-boundary edges
+// *****************************************************************************
+{
+  // Buffer up inccoming contributions to dual-face normals
+  for (const auto& [e,n] : dfnorm) {
+    auto& dfn = m_dfnormc[e];
+    dfn[0] += n[0];
+    dfn[1] += n[1];
+    dfn[2] += n[2];
+  }
+
+  if (++m_ndfnorm == Disc()->EdgeCommMap().size()) {
+    m_ndfnorm = 0;
+    comdfnorm_complete();
+  }
+}
+
+void
+ALECG::bnorm( const std::unordered_map< int,
+                std::unordered_set< std::size_t > >& bcnodes )
+// *****************************************************************************
+//  Compute boundary point normals
+//! \param[in] bcnodes Local node ids associated to side set ids at which BCs
+//!    are set that require normals
+//*****************************************************************************
+{
+  auto d = Disc();
+
+  m_bnorm = cg::bnorm( m_bface, m_triinpoel, d->Coord(), d->Gid(), bcnodes );
+
+  // Send our nodal normal contributions to neighbor chares
+  if (d->NodeCommMap().empty())
+    comnorm_complete();
+  else
+    for (const auto& [ neighborchare, sharednodes ] : d->NodeCommMap()) {
+      std::unordered_map< int,
+        std::unordered_map< std::size_t, std::array< tk::real, 4 > > > exp;
+      for (auto i : sharednodes) {
+        for (const auto& [s,norms] : m_bnorm) {
+          auto j = norms.find(i);
+          if (j != end(norms)) exp[s][i] = j->second;
+        }
+      }
+      thisProxy[ neighborchare ].comnorm( exp );
+    }
+
+  ownnorm_complete();
+}
+
+void
+ALECG::comnorm( const std::unordered_map< int,
+  std::unordered_map< std::size_t, std::array< tk::real, 4 > > >& innorm )
+// *****************************************************************************
+// Receive boundary point normals on chare-boundaries
+//! \param[in] innorm Incoming partial sums of boundary point normal
+//!   contributions to normals (first 3 components), inverse distance squared
+//!   (4th component), associated to side set ids
+// *****************************************************************************
+{
+  // Buffer up incoming boundary-point normal vector contributions
+  for (const auto& [s,norms] : innorm) {
+    auto& bnorms = m_bnormc[s];
+    for (const auto& [p,n] : norms) {
+      auto& bnorm = bnorms[p];
+      bnorm[0] += n[0];
+      bnorm[1] += n[1];
+      bnorm[2] += n[2];
+      bnorm[3] += n[3];
+    }
+  }
+
+  if (++m_nbnorm == Disc()->NodeCommMap().size()) {
+    m_nbnorm = 0;
+    comnorm_complete();
+  }
+}
+
+void
+ALECG::registerReducers()
+// *****************************************************************************
+//  Configure Charm++ reduction types initiated from this chare array
+//! \details Since this is a [initnode] routine, the runtime system executes the
+//!   routine exactly once on every logical node early on in the Charm++ init
+//!   sequence. Must be static as it is called without an object. See also:
+//!   Section "Initializations at Program Startup" at in the Charm++ manual
+//!   http://charm.cs.illinois.edu/manuals/html/charm++/manual.html.
+// *****************************************************************************
+{
+  NodeDiagnostics::registerReducers();
+}
+
+void
+ALECG::ResumeFromSync()
+// *****************************************************************************
+//  Return from migration
+//! \details This is called when load balancing (LB) completes. The presence of
+//!   this function does not affect whether or not we block on LB.
+// *****************************************************************************
+{
+  if (Disc()->It() == 0) Throw( "it = 0 in ResumeFromSync()" );
+
+  if (!g_inputdeck.get< tag::cmd, tag::nonblocking >()) next();
+}
+
+//! [setup]
+void
+ALECG::setup()
+// *****************************************************************************
+// Start setup for solution
+// *****************************************************************************
+{
+  auto d = Disc();
+
+  // Determine nodes inside user-defined IC box
+  g_cgpde[d->MeshId()].IcBoxNodes( d->Coord(), d->Inpoel(),
+    d->ElemBlockId(), m_boxnodes, m_nodeblockid, m_nusermeshblk );
+
+  // Communicate mesh block nodes to other chares on chare-boundary
+  if (d->NodeCommMap().empty())        // in serial we are done
+    comblk_complete();
+  else // send mesh block information to chare-boundary nodes to fellow chares
+    for (const auto& [c,n] : d->NodeCommMap()) {
+      // data structure assigning block ids (set of values) to nodes (index).
+      // although nodeblockid is a map with key-blockid and value-nodeid, the
+      // sending data structure has to be inverted, because of how communication
+      // data is handled.
+      std::vector< std::set< std::size_t > > mb( n.size() );
+      std::size_t j = 0;
+      for (auto i : n) {
+        for (const auto& [blid, ndset] : m_nodeblockid) {
+          // if node was found in a block, add to send-data
+          if (ndset.find(tk::cref_find(d->Lid(),i)) != ndset.end())
+            mb[j].insert(blid);
+        }
+        if (m_nusermeshblk > 0)
+          Assert(mb[j].size() > 0, "Sending no block data for node");
+        ++j;
+      }
+      thisProxy[c].comblk( std::vector<std::size_t>(begin(n),end(n)), mb );
+    }
+
+  ownblk_complete();
+}
+
+void
+ALECG::comblk( const std::vector< std::size_t >& gid,
+               const std::vector< std::set< std::size_t > >& mb )
+// *****************************************************************************
+//  Receive mesh block information for nodes on chare-boundaries
+//! \param[in] gid Global mesh node IDs at which we receive RHS contributions
+//! \param[in] mb Block ids for each node on chare-boundaries
+//! \details This function receives mesh block information for nodes on chare
+//!   boundaries. While m_nodeblockid stores block information for own nodes,
+//!   m_nodeblockidc collects the neighbor chare information during
+//!   communication. This way work on m_nodeblockid and m_nodeblockidc is
+//!   overlapped. The two are combined in continueSetup().
+// *****************************************************************************
+{
+  Assert( mb.size() == gid.size(), "Size mismatch" );
+
+  for (std::size_t i=0; i<gid.size(); ++i) {
+    for (const auto& blid : mb[i]) {
+      m_nodeblockidc[blid].insert(gid[i]);
+    }
+  }
+
+  // When we have heard from all chares we communicate with, this chare is done
+  if (++m_nmblk == Disc()->NodeCommMap().size()) {
+    m_nmblk = 0;
+    comblk_complete();
+  }
+}
+
+void
+ALECG::continueSetup()
+// *****************************************************************************
+// Continue setup for solution, after communication for mesh blocks
+// *****************************************************************************
+{
+  auto d = Disc();
+
+  // Combine own and communicated mesh block information
+  for (const auto& [blid, ndset] : m_nodeblockidc) {
+    for (const auto& i : ndset) {
+      auto lid = tk::cref_find(d->Lid(), i);
+      m_nodeblockid[blid].insert(lid);
+    }
+  }
+
+  // clear receive buffer
+  tk::destroy(m_nodeblockidc);
+
+  // Compute volume of user-defined box IC
+  d->boxvol( m_boxnodes, m_nodeblockid, m_nusermeshblk );
+
+  // Query time history field output labels from all PDEs integrated
+  const auto& hist_points = g_inputdeck.get< tag::history_output, tag::point >();
+  if (!hist_points.empty()) {
+    std::vector< std::string > histnames;
+    auto n = g_cgpde[d->MeshId()].histNames();
+    histnames.insert( end(histnames), begin(n), end(n) );
+    d->histheader( std::move(histnames) );
+  }
+}
+//! [setup]
+
+void
+ALECG::volumetric( tk::Fields& u, const std::vector< tk::real >& v )
+// *****************************************************************************
+//  Multiply solution with mesh volume
+//! \param[in,out] u Solution vector
+//! \param[in] v Volume to multiply with
+// *****************************************************************************
+{
+  Assert( v.size() == u.nunk(), "Size mismatch" );
+
+  for (std::size_t i=0; i<u.nunk(); ++i)
+    for (ncomp_t c=0; c<u.nprop(); ++c)
+      u(i,c) *= v[i];
+}
+
+void
+ALECG::conserved( tk::Fields& u, const std::vector< tk::real >& v )
+// *****************************************************************************
+//  Divide solution with mesh volume
+//! \param[in,out] u Solution vector
+//! \param[in] v Volume to divide with
+// *****************************************************************************
+{
+  Assert( v.size() == u.nunk(), "Size mismatch" );
+
+  for (std::size_t i=0; i<u.nunk(); ++i)
+    for (ncomp_t c=0; c<u.nprop(); ++c) {
+      u(i,c) /= v[i];
+    }
+}
+
+void
+ALECG::box( tk::real v, const std::vector< tk::real >& blkvols )
+// *****************************************************************************
+// Receive total box IC volume and set conditions in box
+//! \param[in] v Total volume within user-specified box
+//! \param[in] blkvols Vector of mesh block discrete volumes with user ICs
+// *****************************************************************************
+{
+  Assert(blkvols.size() == m_nusermeshblk,
+    "Incorrect size of block volume vector");
+  auto d = Disc();
+
+  // Store user-defined box/block IC volume
+  d->Boxvol() = v;
+  d->MeshBlkVol() = blkvols;
+
+  // Set initial conditions for all PDEs
+  g_cgpde[d->MeshId()].initialize( d->Coord(), m_u, d->T(), d->Boxvol(),
+    m_boxnodes, d->MeshBlkVol(), m_nodeblockid );
+
+  // Multiply conserved variables with mesh volume
+  volumetric( m_u, Disc()->Vol() );
+
+  // Initialize nodal mesh volumes at previous time step stage
+  d->Voln() = d->Vol();
+
+  // Start computing the mesh mesh velocity for ALE
+  meshvelstart();
+}
+
+void
+ALECG::meshvelstart()
+// *****************************************************************************
+// Start computing the mesh mesh velocity for ALE
+// *****************************************************************************
+{
+  auto d = Disc();
+
+  // Apply boundary conditions on numerical solution
+  BC();
+
+  conserved( m_u, d->Vol() );
+
+  // query fluid velocity across all systems integrated
+  tk::UnsMesh::Coords vel;
+  g_cgpde[d->MeshId()].velocity( m_u, vel );
+  // query speed of sound in mesh nodes across all systems integrated
+  std::vector< tk::real > soundspeed;
+  g_cgpde[d->MeshId()].soundspeed( m_u, soundspeed );
+
+  volumetric( m_u, d->Vol() );
+
+  // Start computing the mesh mesh velocity for ALE
+  d->meshvelStart( vel, soundspeed, m_bnorm, rkcoef[m_stage] * d->Dt(),
+    CkCallback(CkIndex_ALECG::meshveldone(), thisProxy[thisIndex]) );
+}
+
+void
+ALECG::meshveldone()
+// *****************************************************************************
+// Done with computing the mesh velocity for ALE
+// *****************************************************************************
+{
+  // Assess and record mesh velocity linear solver conergence
+  Disc()->meshvelConv();
+
+  // Continue
+  if (Disc()->Initial()) {
+
+    conserved( m_u, Disc()->Vol() );
+
+    // Initiate IC transfer (if coupled)
+    Disc()->transfer( m_u, 0,
+      CkCallback(CkIndex_ALECG::transfer_complete(), thisProxy[thisIndex]) );
+
+    lhs();
+
+  } else {
+
+    ale();
+
+  }
+}
+
+//! [start]
+void
+ALECG::start()
+// *****************************************************************************
+// Start time stepping
+// *****************************************************************************
+{
+  // Set flag that indicates that we are now during time stepping
+  Disc()->Initial( 0 );
+  // Start timer measuring time stepping wall clock time
+  Disc()->Timer().zero();
+  // Zero grind-timer
+  Disc()->grindZero();
+  // Continue to first time step
+  next();
+}
+//! [start]
+
+//! [Compute lhs]
+void
+ALECG::lhs()
+// *****************************************************************************
+// Compute the left-hand side of transport equations
+//! \details Also (re-)compute all data structures if the mesh changed.
+// *****************************************************************************
+{
+  // No need for LHS in ALECG
+
+  // (Re-)compute boundary point-, and dual-face normals
+  norm();
+}
+//! [Compute lhs]
+
+//! [Merge normals and continue]
+void
+ALECG::mergelhs()
+// *****************************************************************************
+// The own and communication portion of the left-hand side is complete
+// *****************************************************************************
+{
+  // Combine own and communicated contributions of normals
+  normfinal();
+
+  if (Disc()->Initial()) {
+    volumetric( m_u, Disc()->Vol() );
+    // Output initial conditions to file
+    writeFields( CkCallback(CkIndex_ALECG::start(), thisProxy[thisIndex]) );
+  } else {
+    norm_complete();
+  }
+}
+//! [Merge normals and continue]
+
+void
+ALECG::normfinal()
+// *****************************************************************************
+//  Finish computing dual-face and boundary point normals
+// *****************************************************************************
+{
+  auto d = Disc();
+  const auto& lid = d->Lid();
+
+  // Combine own and communicated contributions to boundary point normals
+  for (const auto& [s,norms] : m_bnormc) {
+    auto& bnorms = m_bnorm[s];
+    for (const auto& [p,n] : norms) {
+      auto& norm = bnorms[p];
+      norm[0] += n[0];
+      norm[1] += n[1];
+      norm[2] += n[2];
+      norm[3] += n[3];
+    }
+  }
+  tk::destroy( m_bnormc );
+
+  // Divide summed point normals by the sum of inverse distance squared
+  for (auto& [s,norms] : m_bnorm)
+    for (auto& [p,n] : norms) {
+      n[0] /= n[3];
+      n[1] /= n[3];
+      n[2] /= n[3];
+      Assert( (n[0]*n[0] + n[1]*n[1] + n[2]*n[2] - 1.0) <
+              1.0e+3*std::numeric_limits< tk::real >::epsilon(),
+              "Non-unit normal" );
+    }
+
+  // Replace global->local ids associated to boundary point normals
+  decltype(m_bnorm) bnorm;
+  for (auto& [s,norms] : m_bnorm) {
+    auto& bnorms = bnorm[s];
+    for (auto&& [g,n] : norms)
+      bnorms[ tk::cref_find(lid,g) ] = std::move(n);
+  }
+  m_bnorm = std::move(bnorm);
+
+  // Count contributions to chare-boundary edges
+  std::unordered_map< tk::UnsMesh::Edge, std::size_t,
+    tk::UnsMesh::Hash<2>, tk::UnsMesh::Eq<2> > edge_node_count;
+  for (const auto& [c,edges] : d->EdgeCommMap())
+    for (const auto& e : edges)
+      ++edge_node_count[e];
+
+  // Combine and weigh communicated contributions to dual-face normals
+  for (auto& [e,n] : m_dfnormc) {
+    const auto& dfn = tk::cref_find( m_dfnorm, e );
+    n[0] += dfn[0];
+    n[1] += dfn[1];
+    n[2] += dfn[2];
+    auto count = static_cast< tk::real >( tk::cref_find( edge_node_count, e ) );
+    auto factor = 1.0/(count + 1.0);
+    for (auto & x : n) x *= factor;<--- Consider using std::transform algorithm instead of a raw loop.
+  }
+
+  // Generate list of unique edges
+  tk::UnsMesh::EdgeSet uedge;
+  for (std::size_t p=0; p<m_u.nunk(); ++p)
+    for (auto q : tk::Around(m_psup,p))
+      uedge.insert( {p,q} );
+
+  // Flatten edge list
+  m_edgenode.resize( uedge.size() * 2 );
+  std::size_t f = 0;
+  const auto& gid = d->Gid();
+  for (auto&& [p,q] : uedge) {
+    if (gid[p] > gid[q]) {
+      m_edgenode[f+0] = std::move(q);
+      m_edgenode[f+1] = std::move(p);
+    } else {
+      m_edgenode[f+0] = std::move(p);
+      m_edgenode[f+1] = std::move(q);
+    }
+    f += 2;
+  }
+  tk::destroy(uedge);
+
+  // Convert dual-face normals to streamable (and vectorizable) data structure
+  m_dfn.resize( m_edgenode.size() * 3 );      // 2 vectors per access
+  std::unordered_map< tk::UnsMesh::Edge, std::size_t,
+                      tk::UnsMesh::Hash<2>, tk::UnsMesh::Eq<2> > eid;
+  for (std::size_t e=0; e<m_edgenode.size()/2; ++e) {
+    auto p = m_edgenode[e*2+0];
+    auto q = m_edgenode[e*2+1];
+    eid[{p,q}] = e;
+    std::array< std::size_t, 2 > g{ gid[p], gid[q] };
+    auto n = tk::cref_find( m_dfnorm, g );
+    // figure out if this is an edge on the parallel boundary
+    auto nit = m_dfnormc.find( g );
+    auto m = ( nit != m_dfnormc.end() ) ? nit->second : n;
+    m_dfn[e*6+0] = n[0];
+    m_dfn[e*6+1] = n[1];
+    m_dfn[e*6+2] = n[2];
+    m_dfn[e*6+3] = m[0];
+    m_dfn[e*6+4] = m[1];
+    m_dfn[e*6+5] = m[2];
+  }
+
+  tk::destroy( m_dfnorm );
+  tk::destroy( m_dfnormc );
+
+  // Flatten edge id data structure
+  m_edgeid.resize( m_psup.first.size() );
+  for (std::size_t p=0,k=0; p<m_u.nunk(); ++p)
+    for (auto q : tk::Around(m_psup,p))
+      m_edgeid[k++] = tk::cref_find( eid, {p,q} );
+}
+
+void
+ALECG::BC()
+// *****************************************************************************
+// Apply boundary conditions
+// \details The following BC enforcement changes the initial condition or
+//!   updated solution (dependending on when it is called) to ensure strong
+//!   imposition of the BCs. This is a matter of choice. Another alternative is
+//!   to only apply BCs when computing fluxes at boundary faces, thereby only
+//!   weakly enforcing the BCs. The former is conventionally used in continunous
+//!   Galerkin finite element methods (such as ALECG implements), whereas the
+//!   latter, in finite volume methods.
+// *****************************************************************************
+{
+  auto d = Disc();
+  const auto& coord = d->Coord();
+
+  conserved( m_u, d->Vol() );
+
+  // Apply Dirichlet BCs
+  for (const auto& [b,bc] : m_dirbc)
+    for (ncomp_t c=0; c<m_u.nprop(); ++c)
+      if (bc[c].first) m_u(b,c) = bc[c].second;
+
+  // Apply symmetry BCs
+  g_cgpde[d->MeshId()].symbc( m_u, coord, m_bnorm, m_symbcnodes );
+
+  // Apply farfield BCs
+  g_cgpde[d->MeshId()].farfieldbc( m_u, coord, m_bnorm, m_farfieldbcnodes );
+
+  // Apply user defined time dependent BCs
+  g_cgpde[d->MeshId()].timedepbc( d->T(), m_u, m_timedepbcnodes,
+    m_timedepbcFn );
+
+  volumetric( m_u, d->Vol() );
+}
+
+void
+ALECG::next()
+// *****************************************************************************
+// Continue to next time step
+// *****************************************************************************
+{
+  dt();
+}
+
+void
+ALECG::dt()
+// *****************************************************************************
+// Compute time step size
+// *****************************************************************************
+{
+  tk::real mindt = std::numeric_limits< tk::real >::max();
+
+  auto const_dt = g_inputdeck.get< tag::dt >();
+  auto eps = std::numeric_limits< tk::real >::epsilon();
+
+  auto d = Disc();
+
+  // use constant dt if configured
+  if (std::abs(const_dt) > eps) {
+
+    mindt = const_dt;
+
+  } else {      // compute dt based on CFL
+
+    //! [Find the minimum dt across all PDEs integrated]
+    conserved( m_u, Disc()->Vol() );
+    if (g_inputdeck.get< tag::steady_state >()) {
+
+      // compute new dt for each mesh point
+      g_cgpde[d->MeshId()].dt( d->It(), d->Vol(), m_u, m_dtp );
+
+      // find the smallest dt of all nodes on this chare
+      mindt = *std::min_element( begin(m_dtp), end(m_dtp) );
+
+    } else {    // compute new dt for this chare
+
+      // find the smallest dt of all equations on this chare
+      auto eqdt = g_cgpde[d->MeshId()].dt( d->Coord(), d->Inpoel(), d->T(),
+        d->Dtn(), m_u, d->Vol(), d->Voln() );
+      if (eqdt < mindt) mindt = eqdt;
+
+    }
+    volumetric( m_u, Disc()->Vol() );
+    //! [Find the minimum dt across all PDEs integrated]
+
+  }
+
+  //! [Advance]
+  // Actiavate SDAG waits for next time step stage
+  thisProxy[ thisIndex ].wait4grad();
+  thisProxy[ thisIndex ].wait4rhs();
+
+  // Contribute to minimum dt across all chares and advance to next step
+  contribute( sizeof(tk::real), &mindt, CkReduction::min_double,
+              CkCallback(CkReductionTarget(ALECG,advance), thisProxy) );
+  //! [Advance]
+}
+
+void
+ALECG::advance( tk::real newdt, tk::real )
+// *****************************************************************************
+// Advance equations to next time step
+//! \param[in] newdt The smallest dt across the whole problem
+// *****************************************************************************
+{
+  auto d = Disc();
+
+  // Set new time step size
+  if (m_stage == 0) d->setdt( newdt );
+
+  // Compute gradients for next time step
+  chBndGrad();
+}
+
+void
+ALECG::chBndGrad()
+// *****************************************************************************
+// Compute nodal gradients at chare-boundary nodes. Gradients at internal nodes
+// are calculated locally as needed and are not stored.
+// *****************************************************************************
+{
+  auto d = Disc();
+
+  // Divide solution with mesh volume
+  conserved( m_u, Disc()->Vol() );
+  // Compute own portion of gradients for all equations
+  g_cgpde[d->MeshId()].chBndGrad( d->Coord(), d->Inpoel(), m_bndel, d->Gid(),
+    d->Bid(), m_u, m_chBndGrad );
+  // Multiply solution with mesh volume
+  volumetric( m_u, Disc()->Vol() );
+
+  // Communicate gradients to other chares on chare-boundary
+  if (d->NodeCommMap().empty())        // in serial we are done
+    comgrad_complete();
+  else // send gradients contributions to chare-boundary nodes to fellow chares
+    for (const auto& [c,n] : d->NodeCommMap()) {
+      std::vector< std::vector< tk::real > > g( n.size() );
+      std::size_t j = 0;
+      for (auto i : n) g[ j++ ] = m_chBndGrad[ tk::cref_find(d->Bid(),i) ];
+      thisProxy[c].comChBndGrad( std::vector<std::size_t>(begin(n),end(n)), g );
+    }
+
+  owngrad_complete();
+}
+
+void
+ALECG::comChBndGrad( const std::vector< std::size_t >& gid,
+                     const std::vector< std::vector< tk::real > >& G )
+// *****************************************************************************
+//  Receive contributions to nodal gradients on chare-boundaries
+//! \param[in] gid Global mesh node IDs at which we receive grad contributions
+//! \param[in] G Partial contributions of gradients to chare-boundary nodes
+//! \details This function receives contributions to m_chBndGrad, which stores
+//!   nodal gradients at mesh chare-boundary nodes. While m_chBndGrad stores
+//!   own contributions, m_chBndGradc collects the neighbor chare
+//!   contributions during communication. This way work on m_chBndGrad and
+//!   m_chBndGradc is overlapped. The two are combined in rhs().
+// *****************************************************************************
+{
+  Assert( G.size() == gid.size(), "Size mismatch" );
+
+  using tk::operator+=;
+
+  for (std::size_t i=0; i<gid.size(); ++i) m_chBndGradc[ gid[i] ] += G[i];
+
+  if (++m_ngrad == Disc()->NodeCommMap().size()) {
+    m_ngrad = 0;
+    comgrad_complete();
+  }
+}
+
+void
+ALECG::rhs()
+// *****************************************************************************
+// Compute right-hand side of transport equations
+// *****************************************************************************
+{
+  auto d = Disc();
+
+  // Combine own and communicated contributions to nodal gradients
+  for (const auto& [gid,g] : m_chBndGradc) {
+    auto bid = tk::cref_find( d->Bid(), gid );
+    for (ncomp_t c=0; c<m_chBndGrad.nprop(); ++c)
+      m_chBndGrad(bid,c) += g[c];
+  }
+
+  // clear gradients receive buffer
+  tk::destroy(m_chBndGradc);
+
+  const auto steady = g_inputdeck.get< tag::steady_state >();
+
+  // Compute own portion of right-hand side for all equations
+  auto prev_rkcoef = m_stage == 0 ? 0.0 : rkcoef[m_stage-1];
+  if (steady)
+    for (std::size_t p=0; p<m_tp.size(); ++p) m_tp[p] += prev_rkcoef * m_dtp[p];
+  conserved( m_u, Disc()->Vol() );
+  g_cgpde[d->MeshId()].rhs( d->T() + prev_rkcoef * d->Dt(), d->Coord(), d->Inpoel(),
+          m_triinpoel, d->Gid(), d->Bid(), d->Lid(), m_dfn, m_psup, m_esup,
+          m_symbctri, d->Vol(), m_edgenode, m_edgeid,
+          m_boxnodes, m_chBndGrad, m_u, d->meshvel(), m_tp, d->Boxvol(),
+          m_rhs );
+  volumetric( m_u, Disc()->Vol() );
+  if (steady)
+    for (std::size_t p=0; p<m_tp.size(); ++p) m_tp[p] -= prev_rkcoef * m_dtp[p];
+
+  // Query/update boundary-conditions-related data structures from user input
+  queryBnd();
+
+  // Communicate rhs to other chares on chare-boundary
+  if (d->NodeCommMap().empty())        // in serial we are done
+    comrhs_complete();
+  else // send contributions of rhs to chare-boundary nodes to fellow chares
+    for (const auto& [c,n] : d->NodeCommMap()) {
+      std::vector< std::vector< tk::real > > r( n.size() );
+      std::size_t j = 0;
+      for (auto i : n) r[ j++ ] = m_rhs[ tk::cref_find(d->Lid(),i) ];
+      thisProxy[c].comrhs( std::vector<std::size_t>(begin(n),end(n)), r );
+    }
+
+  ownrhs_complete();
+}
+
+void
+ALECG::comrhs( const std::vector< std::size_t >& gid,
+               const std::vector< std::vector< tk::real > >& R )
+// *****************************************************************************
+//  Receive contributions to right-hand side vector on chare-boundaries
+//! \param[in] gid Global mesh node IDs at which we receive RHS contributions
+//! \param[in] R Partial contributions of RHS to chare-boundary nodes
+//! \details This function receives contributions to m_rhs, which stores the
+//!   right hand side vector at mesh nodes. While m_rhs stores own
+//!   contributions, m_rhsc collects the neighbor chare contributions during
+//!   communication. This way work on m_rhs and m_rhsc is overlapped. The two
+//!   are combined in solve().
+// *****************************************************************************
+{
+  Assert( R.size() == gid.size(), "Size mismatch" );
+
+  using tk::operator+=;
+
+  for (std::size_t i=0; i<gid.size(); ++i) m_rhsc[ gid[i] ] += R[i];
+
+  // When we have heard from all chares we communicate with, this chare is done
+  if (++m_nrhs == Disc()->NodeCommMap().size()) {
+    m_nrhs = 0;
+    comrhs_complete();
+  }
+}
+
+void
+ALECG::solve()
+// *****************************************************************************
+//  Advance systems of equations
+// *****************************************************************************
+{
+  auto d = Disc();
+
+  // Combine own and communicated contributions to rhs
+  for (const auto& b : m_rhsc) {
+    auto lid = tk::cref_find( d->Lid(), b.first );
+    for (ncomp_t c=0; c<m_rhs.nprop(); ++c) m_rhs(lid,c) += b.second[c];
+  }
+
+  // clear receive buffer
+  tk::destroy(m_rhsc);
+
+  // Update state at time n
+  if (m_stage == 0) {
+    m_un = m_u;
+    if (g_inputdeck.get< tag::ale, tag::ale >()) d->UpdateCoordn();
+  }
+
+  // Solve the sytem
+  if (g_inputdeck.get< tag::steady_state >()) {
+
+    // Advance solution, converging to steady state
+    for (std::size_t i=0; i<m_u.nunk(); ++i)
+      for (ncomp_t c=0; c<m_u.nprop(); ++c)
+        m_u(i,c) = m_un(i,c) + rkcoef[m_stage] * m_dtp[i] * m_rhs(i,c);
+
+  } else {
+
+    auto adt = rkcoef[m_stage] * d->Dt();
+
+    // Advance unsteady solution
+    m_u = m_un + adt * m_rhs;
+
+    // Advance mesh if ALE is enabled
+    if (g_inputdeck.get< tag::ale, tag::ale >()) {
+      auto& coord = d->Coord();
+      const auto& w = d->meshvel();
+      for (auto j : g_inputdeck.get< tag::ale, tag::mesh_motion >())
+        for (std::size_t i=0; i<coord[j].size(); ++i)
+          coord[j][i] = d->Coordn()[j][i] + adt * w(i,j);
+    }
+
+  }
+
+  m_newmesh = 0;  // recompute normals after ALE (if enabled)
+  m_refinedmesh = 0;  // mesh has not been refined by ALE
+  // Activate SDAG waits
+  thisProxy[ thisIndex ].wait4norm();
+  thisProxy[ thisIndex ].wait4mesh();
+
+  //! [Continue after solve]
+  // Recompute mesh volumes if ALE is enabled
+  if (g_inputdeck.get< tag::ale, tag::ale >()) {
+
+    transfer_complete();
+    // Save nodal volumes at previous time step stage
+    d->Voln() = d->Vol();
+    // Prepare for recomputing the nodal volumes
+    d->startvol();
+    auto meshid = d->MeshId();
+    contribute( sizeof(std::size_t), &meshid, CkReduction::nop,
+                CkCallback(CkReductionTarget(Transporter,resized), d->Tr()) );
+
+  } else {
+
+    norm_complete();
+    resized();
+
+  }
+  //! [Continue after solve]
+}
+
+void
+ALECG::ale()
+// *****************************************************************************
+//  Continue after computing the new mesh velocity for ALE
+// *****************************************************************************
+{
+  auto d = Disc();
+
+  if (m_stage < 2) {
+
+    // Activate SDAG wait for next time step stage
+    thisProxy[ thisIndex ].wait4grad();
+    thisProxy[ thisIndex ].wait4rhs();
+
+    // continue to mesh-to-mesh transfer (if coupled)
+    transfer();
+
+  } else {
+
+    // Ensure new field output file if mesh moved if ALE is enabled
+    if (g_inputdeck.get< tag::ale, tag::ale >()) {
+      d->Itf() = 0;  // Zero field output iteration count if mesh moved
+      ++d->Itr();    // Increase number of iterations with a change in the mesh
+    }
+
+    // Compute diagnostics, e.g., residuals
+    conserved( m_u, Disc()->Vol() );
+    conserved( m_un, Disc()->Voln() );
+    auto diag_computed = m_diag.compute( *d, m_u, m_un, m_bnorm,
+                                         m_symbcnodes, m_farfieldbcnodes );
+    volumetric( m_u, Disc()->Vol() );
+    volumetric( m_un, Disc()->Voln() );
+    // Increase number of iterations and physical time
+    d->next();
+    // Advance physical time for local time stepping
+    if (g_inputdeck.get< tag::steady_state >())
+      for (std::size_t i=0; i<m_u.nunk(); ++i) m_tp[i] += m_dtp[i];
+    // Continue to mesh refinement (if configured)
+    if (!diag_computed) refine( std::vector< tk::real >( m_u.nprop(), 1.0 ) );
+
+  }
+}
+
+//! [Refine]
+void
+ALECG::refine( const std::vector< tk::real >& l2res )
+// *****************************************************************************
+// Optionally refine/derefine mesh
+//! \param[in] l2res L2-norms of the residual for each scalar component
+//!   computed across the whole problem
+// *****************************************************************************
+{
+  auto d = Disc();
+
+  const auto steady = g_inputdeck.get< tag::steady_state >();
+  const auto residual = g_inputdeck.get< tag::residual >();
+  const auto rc = g_inputdeck.get< tag::rescomp >() - 1;
+
+  if (steady) {
+
+    // this is the last time step if max time of max number of time steps
+    // reached or the residual has reached its convergence criterion
+    if (d->finished() or l2res[rc] < residual) m_finished = 1;
+
+  } else {
+
+    // this is the last time step if max time or max iterations reached
+    if (d->finished()) m_finished = 1;
+
+  }
+
+  auto dtref = g_inputdeck.get< tag::amr, tag::dtref >();
+  auto dtfreq = g_inputdeck.get< tag::amr, tag::dtfreq >();
+
+  // Activate SDAG waits for re-computing the normals
+  m_newmesh = 1;  // recompute normals after AMR (if enabled)
+  thisProxy[ thisIndex ].wait4norm();
+  thisProxy[ thisIndex ].wait4mesh();
+
+  // if t>0 refinement enabled and we hit the frequency
+  if (dtref && !(d->It() % dtfreq)) {   // refine
+
+    // Convert to conserved unknowns, since the next step changes volumes
+    conserved(m_u, d->Vol());
+
+    m_refinedmesh = 1;
+    d->startvol();
+    d->Ref()->dtref( m_bface, m_bnode, m_triinpoel );
+    d->refined() = 1;
+
+  } else {      // do not refine
+
+    m_refinedmesh = 0;
+    d->refined() = 0;
+    norm_complete();
+    resized();
+
+  }
+}
+//! [Refine]
+
+//! [Resize]
+void
+ALECG::resizePostAMR(
+  const std::vector< std::size_t >& /*ginpoel*/,
+  const tk::UnsMesh::Chunk& chunk,
+  const tk::UnsMesh::Coords& coord,
+  const std::unordered_map< std::size_t, tk::UnsMesh::Edge >& addedNodes,
+  const std::unordered_map< std::size_t, std::size_t >& /*addedTets*/,
+  const std::set< std::size_t >& removedNodes,
+  const std::unordered_map< std::size_t, std::size_t >& amrNodeMap,
+  const tk::NodeCommMap& nodeCommMap,
+  const std::map< int, std::vector< std::size_t > >& bface,
+  const std::map< int, std::vector< std::size_t > >& bnode,
+  const std::vector< std::size_t >& triinpoel,
+  const std::unordered_map< std::size_t, std::set< std::size_t > >& elemblockid )
+// *****************************************************************************
+//  Receive new mesh from Refiner
+//! \param[in] ginpoel Mesh connectivity with global node ids
+//! \param[in] chunk New mesh chunk (connectivity and global<->local id maps)
+//! \param[in] coord New mesh node coordinates
+//! \param[in] addedNodes Newly added mesh nodes and their parents (local ids)
+//! \param[in] addedTets Newly added mesh cells and their parents (local ids)
+//! \param[in] removedNodes Newly removed mesh node local ids
+//! \param[in] amrNodeMap Node id map after amr (local ids)
+//! \param[in] nodeCommMap New node communication map
+//! \param[in] bface Boundary-faces mapped to side set ids
+//! \param[in] bnode Boundary-node lists mapped to side set ids
+//! \param[in] triinpoel Boundary-face connectivity
+//! \param[in] elemblockid Local tet ids associated with mesh block ids
+// *****************************************************************************
+{
+  auto d = Disc();
+
+  d->Itf() = 0;  // Zero field output iteration count if AMR
+  ++d->Itr();    // Increase number of iterations with a change in the mesh
+
+  // Resize mesh data structures after mesh refinement
+  d->resizePostAMR( chunk, coord, amrNodeMap, nodeCommMap, removedNodes,
+    elemblockid );
+
+  // Remove newly removed nodes from solution vectors
+  m_u.rm(removedNodes);
+  m_un.rm(removedNodes);
+  m_rhs.rm(removedNodes);
+
+  // Resize auxiliary solution vectors
+  auto npoin = coord[0].size();
+  auto nprop = m_u.nprop();
+  m_u.resize( npoin );
+  m_un.resize( npoin );
+  m_rhs.resize( npoin );
+  m_chBndGrad.resize( d->Bid().size() );
+  tk::destroy(m_esup);
+  tk::destroy(m_psup);
+  m_esup = tk::genEsup( d->Inpoel(), 4 );
+  m_psup = tk::genPsup( d->Inpoel(), 4, m_esup );
+
+  // Update solution on new mesh
+  for (const auto& n : addedNodes)
+    for (std::size_t c=0; c<nprop; ++c) {
+      Assert(n.first < m_u.nunk(), "Added node index out of bounds post-AMR");
+      Assert(n.second[0] < m_u.nunk() && n.second[1] < m_u.nunk(),
+        "Indices of parent-edge nodes out of bounds post-AMR");
+      m_u(n.first,c) = (m_u(n.second[0],c) + m_u(n.second[1],c))/2.0;
+    }
+
+  // Update physical-boundary node-, face-, and element lists
+  m_bnode = bnode;
+  m_bface = bface;
+  m_triinpoel = tk::remap( triinpoel, d->Lid() );
+
+  auto meshid = d->MeshId();
+  contribute( sizeof(std::size_t), &meshid, CkReduction::nop,
+              CkCallback(CkReductionTarget(Transporter,resized), d->Tr()) );
+}
+//! [Resize]
+
+void
+ALECG::resized()
+// *****************************************************************************
+// Resizing data sutrctures after mesh refinement has been completed
+// *****************************************************************************
+{
+  auto d = Disc();
+
+  // Revert to volumetric unknowns, if soln was converted in ALECG::refine()
+  auto dtref = g_inputdeck.get< tag::amr, tag::dtref >();
+  auto dtfreq = g_inputdeck.get< tag::amr, tag::dtfreq >();
+  if (dtref && !(d->It() % dtfreq) && m_refinedmesh==1) {
+    volumetric(m_u, d->Vol());
+    // Update previous volumes after refinement
+    d->Voln() = d->Vol();
+  }
+
+  resize_complete();
+}
+
+void
+ALECG::transfer()
+// *****************************************************************************
+// Transfer solution to other solver and mesh if coupled
+// *****************************************************************************
+{
+  // Initiate solution transfer (if coupled)
+
+//TODO: enable this for during-timestepping solution transfer
+//  Disc()->transfer(m_u, CkCallback(CkIndex_ALECG::stage(), thisProxy[thisIndex]));
+  thisProxy[thisIndex].stage();
+}
+
+//! [stage]
+void
+ALECG::stage()
+// *****************************************************************************
+// Evaluate whether to continue with next time step stage
+// *****************************************************************************
+{
+  transfer_complete();
+
+  // Increment Runge-Kutta stage counter
+  ++m_stage;
+
+  // if not all Runge-Kutta stages complete, continue to next time stage,
+  // otherwise output field data to file(s)
+  if (m_stage < 3) chBndGrad(); else out();
+}
+//! [stage]
+
+void
+ALECG::writeFields( CkCallback c )
+// *****************************************************************************
+// Output mesh-based fields to file
+//! \param[in] c Function to continue with after the write
+// *****************************************************************************
+{
+  if (g_inputdeck.get< tag::cmd, tag::benchmark >()) {
+
+    c.send();
+
+  } else {
+
+    auto d = Disc();
+    const auto& coord = d->Coord();
+
+    // Query fields names requested by user
+    auto nodefieldnames = numericFieldNames( tk::Centering::NODE );
+
+    // Collect field output from numerical solution requested by user
+    conserved( m_u, Disc()->Vol() );
+    auto nodefields = numericFieldOutput( m_u, tk::Centering::NODE,
+      g_cgpde[Disc()->MeshId()].OutVarFn(), m_u );
+    volumetric( m_u, Disc()->Vol() );
+
+    //! Lambda to put in a field for output if not empty
+    auto add_node_field = [&]( const auto& name, const auto& field ){
+      if (not field.empty()) {
+        nodefieldnames.push_back( name );
+        nodefields.push_back( field );
+      }
+    };
+
+    // Output mesh velocity if ALE is enabled
+    if (g_inputdeck.get< tag::ale, tag::ale >()) {
+      const auto& w = d->meshvel();
+      add_node_field( "x-mesh-velocity", w.extract_comp(0) );
+      add_node_field( "y-mesh-velocity", w.extract_comp(1) );
+      add_node_field( "z-mesh-velocity", w.extract_comp(2) );
+      add_node_field( "volume", d->Vol() );
+    }
+
+    // Collect field output names for analytical solutions
+    analyticFieldNames( g_cgpde[d->MeshId()], tk::Centering::NODE,
+      nodefieldnames );
+
+    // Collect field output from analytical solutions (if exist)
+    analyticFieldOutput( g_cgpde[d->MeshId()], tk::Centering::NODE, coord[0],
+      coord[1], coord[2], d->T(), nodefields );
+
+    // Query and collect nodal block and surface field names from PDEs integrated
+    std::vector< std::string > nodesurfnames;
+    auto sn = g_cgpde[d->MeshId()].surfNames();
+    nodesurfnames.insert( end(nodesurfnames), begin(sn), end(sn) );
+
+    // Collect nodal block and surface field solution
+    std::vector< std::vector< tk::real > > nodesurfs;
+    conserved( m_u, Disc()->Vol() );
+    auto so = g_cgpde[d->MeshId()].surfOutput( tk::bfacenodes(m_bface,
+      m_triinpoel), m_u );
+    nodesurfs.insert( end(nodesurfs), begin(so), end(so) );
+
+    // Collect elemental block and surface field names from PDEs integrated
+    auto elemsurfnames = nodesurfnames;
+
+    // Collect elemental block and surface field solution
+    std::vector< std::vector< tk::real > > elemsurfs;
+    auto eso = g_cgpde[d->MeshId()].elemSurfOutput( m_bface, m_triinpoel, m_u );
+    elemsurfs.insert( end(elemsurfs), begin(eso), end(eso) );
+
+    // Query refinement data
+    auto dtref = g_inputdeck.get< tag::amr, tag::dtref >();
+
+    std::tuple< std::vector< std::string >,
+                std::vector< std::vector< tk::real > >,
+                std::vector< std::string >,
+                std::vector< std::vector< tk::real > > > r;
+    if (dtref) r = d->Ref()->refinementFields();
+    volumetric( m_u, Disc()->Vol() );
+
+    auto& refinement_elemfieldnames = std::get< 0 >( r );
+    auto& refinement_elemfields = std::get< 1 >( r );
+    auto& refinement_nodefieldnames = std::get< 2 >( r );
+    auto& refinement_nodefields = std::get< 3 >( r );
+
+    nodefieldnames.insert( end(nodefieldnames),
+      begin(refinement_nodefieldnames), end(refinement_nodefieldnames) );
+    nodefields.insert( end(nodefields),
+      begin(refinement_nodefields), end(refinement_nodefields) );
+
+    auto elemfieldnames = std::move(refinement_elemfieldnames);
+    auto elemfields = std::move(refinement_elemfields);
+
+    Assert( elemfieldnames.size() == elemfields.size(), "Size mismatch" );
+    Assert( nodefieldnames.size() == nodefields.size(), "Size mismatch" );
+
+    // Send mesh and fields data (solution dump) for output to file
+    d->write( d->Inpoel(), coord, m_bface, tk::remap(m_bnode,d->Lid()),
+              m_triinpoel, elemfieldnames, nodefieldnames, elemsurfnames,
+              nodesurfnames, elemfields, nodefields, elemsurfs, nodesurfs, c );
+
+  }
+}
+
+void
+ALECG::out()
+// *****************************************************************************
+// Output mesh field data
+// *****************************************************************************
+{
+  auto d = Disc();
+
+  // Output time history
+  if (d->histiter() or d->histtime() or d->histrange()) {
+    std::vector< std::vector< tk::real > > hist;
+    conserved( m_u, Disc()->Vol() );
+    auto h = g_cgpde[d->MeshId()].histOutput( d->Hist(), d->Inpoel(), m_u );
+    hist.insert( end(hist), begin(h), end(h) );
+    volumetric( m_u, Disc()->Vol() );
+    d->history( std::move(hist) );
+  }
+
+  // Output field data
+  if (d->fielditer() or d->fieldtime() or d->fieldrange() or m_finished)
+    writeFields( CkCallback(CkIndex_ALECG::step(), thisProxy[thisIndex]) );
+  else
+    step();
+}
+
+void
+ALECG::evalLB( int nrestart )
+// *****************************************************************************
+// Evaluate whether to do load balancing
+//! \param[in] nrestart Number of times restarted
+// *****************************************************************************
+{
+  auto d = Disc();
+
+  // Detect if just returned from a checkpoint and if so, zero timers and
+  // finished flag
+  if (d->restarted( nrestart )) m_finished = 0;
+
+  const auto lbfreq = g_inputdeck.get< tag::cmd, tag::lbfreq >();
+  const auto nonblocking = g_inputdeck.get< tag::cmd, tag::nonblocking >();
+
+  // Load balancing if user frequency is reached or after the second time-step
+  if ( (d->It()) % lbfreq == 0 || d->It() == 2 ) {
+
+    AtSync();
+    if (nonblocking) next();
+
+  } else {
+
+    next();
+
+  }
+}
+
+void
+ALECG::evalRestart()
+// *****************************************************************************
+// Evaluate whether to save checkpoint/restart
+// *****************************************************************************
+{
+  auto d = Disc();
+
+  const auto rsfreq = g_inputdeck.get< tag::cmd, tag::rsfreq >();
+  const auto benchmark = g_inputdeck.get< tag::cmd, tag::benchmark >();
+
+  if (not benchmark and not (d->It() % rsfreq)) {
+
+    std::vector< std::size_t > meshdata{ /* finished = */ 0, d->MeshId() };
+    contribute( meshdata, CkReduction::nop,
+      CkCallback(CkReductionTarget(Transporter,checkpoint), d->Tr()) );
+
+  } else {
+
+    evalLB( /* nrestart = */ -1 );
+
+  }
+}
+
+void
+ALECG::step()
+// *****************************************************************************
+// Evaluate whether to continue with next time step
+// *****************************************************************************
+{
+  auto d = Disc();
+
+  // Output one-liner status report to screen
+  d->status();
+  // Reset Runge-Kutta stage counter
+  m_stage = 0;
+
+  if (not m_finished) {
+
+    evalRestart();
+
+  } else {
+
+    auto meshid = d->MeshId();
+    d->contribute( sizeof(std::size_t), &meshid, CkReduction::nop,
+                   CkCallback(CkReductionTarget(Transporter,finish), d->Tr()) );
+
+  }
+}
+
+#include "NoWarning/alecg.def.h"
 
diff --git a/Debug/cppcheck/53.html b/Debug/cppcheck/53.html index d09e91890da7..efae730f5ad4 100644 --- a/Debug/cppcheck/53.html +++ b/Debug/cppcheck/53.html @@ -152,12 +152,12 @@
   1
@@ -1645,1492 +1645,1746 @@ 

Cppcheck report - [

// *****************************************************************************
+1486
+1487
+1488
+1489
+1490
+1491
+1492
+1493
+1494
+1495
+1496
+1497
+1498
+1499
+1500
+1501
+1502
+1503
+1504
+1505
+1506
+1507
+1508
+1509
+1510
+1511
+1512
+1513
+1514
+1515
+1516
+1517
+1518
+1519
+1520
+1521
+1522
+1523
+1524
+1525
+1526
+1527
+1528
+1529
+1530
+1531
+1532
+1533
+1534
+1535
+1536
+1537
+1538
+1539
+1540
+1541
+1542
+1543
+1544
+1545
+1546
+1547
+1548
+1549
+1550
+1551
+1552
+1553
+1554
+1555
+1556
+1557
+1558
+1559
+1560
+1561
+1562
+1563
+1564
+1565
+1566
+1567
+1568
+1569
+1570
+1571
+1572
+1573
+1574
+1575
+1576
+1577
+1578
+1579
+1580
+1581
+1582
+1583
+1584
+1585
+1586
+1587
+1588
+1589
+1590
+1591
+1592
+1593
+1594
+1595
+1596
+1597
+1598
+1599
+1600
+1601
+1602
+1603
+1604
+1605
+1606
+1607
+1608
+1609
+1610
+1611
+1612
+1613
// *****************************************************************************
 /*!
-  \file      src/Inciter/OversetFE.cpp
+  \file      src/PDE/CompFlow/CGCompFlow.hpp
   \copyright 2012-2015 J. Bakosi,
              2016-2018 Los Alamos National Security, LLC.,
              2019-2021 Triad National Security, LLC.
              All rights reserved. See the LICENSE file for details.
-  \brief     OversetFE for a PDE system with continuous Galerkin FE + RK
-  \details   OversetFE advances a system of partial differential equations
-    using a continuous Galerkin (CG) finite element (FE) spatial discretization
-    (using linear shapefunctions on tetrahedron elements) combined with a
-    Runge-Kutta (RK) time stepping scheme and overset grids.
-  \see The documentation in OversetFE.hpp.
-*/
-// *****************************************************************************
-
-#include "QuinoaBuildConfig.hpp"
-#include "OversetFE.hpp"
-#include "Vector.hpp"
-#include "Reader.hpp"
-#include "ContainerUtil.hpp"
-#include "UnsMesh.hpp"
-#include "ExodusIIMeshWriter.hpp"
-#include "Inciter/InputDeck/InputDeck.hpp"
-#include "DerivedData.hpp"
-#include "CGPDE.hpp"
-#include "Discretization.hpp"
-#include "DiagReducer.hpp"
+  \brief     Compressible single-material flow using continuous Galerkin
+  \details   This file implements the physics operators governing compressible
+    single-material flow using continuous Galerkin discretization.
+*/
+// *****************************************************************************
+#ifndef CGCompFlow_h
+#define CGCompFlow_h
+
+#include <cmath>
+#include <algorithm>
+#include <unordered_set>
+#include <unordered_map>
+
+#include "DerivedData.hpp"
+#include "Exception.hpp"
+#include "Vector.hpp"
+#include "Mesh/Around.hpp"
+#include "Reconstruction.hpp"
+#include "Problem/FieldOutput.hpp"
+#include "Problem/BoxInitialization.hpp"
+#include "Riemann/Rusanov.hpp"
 #include "NodeBC.hpp"
-#include "Refiner.hpp"
-#include "Reorder.hpp"
-#include "Around.hpp"
-#include "CGPDE.hpp"
-#include "FieldOutput.hpp"
+#include "EoS/EOS.hpp"
+#include "History.hpp"
+#include "Table.hpp"
+
+namespace inciter {
 
-namespace inciter {
+extern ctr::InputDeck g_inputdeck;
 
-extern ctr::InputDeck g_inputdeck;
-extern std::vector< CGPDE > g_cgpde;
-
-//! Runge-Kutta coefficients
-static const std::array< tk::real, 3 > rkcoef{{ 1.0/3.0, 1.0/2.0, 1.0 }};
-
-} // inciter::
-
-using inciter::OversetFE;
-
-OversetFE::OversetFE( const CProxy_Discretization& disc,
-              const CProxy_Ghosts&,
-              const std::map< int, std::vector< std::size_t > >& bface,
-              const std::map< int, std::vector< std::size_t > >& bnode,
-              const std::vector< std::size_t >& triinpoel ) :
-  m_disc( disc ),
-  m_nsol( 0 ),
-  m_ngrad( 0 ),
-  m_nrhs( 0 ),
-  m_nbnorm( 0 ),
-  m_ndfnorm( 0 ),
-  m_nmblk( 0 ),
-  m_bnode( bnode ),
-  m_bface( bface ),
-  m_triinpoel( tk::remap( triinpoel, Disc()->Lid() ) ),
-  m_bndel( Disc()->bndel() ),
-  m_dfnorm(),
-  m_dfnormc(),
-  m_dfn(),
-  m_esup( tk::genEsup( Disc()->Inpoel(), 4 ) ),
-  m_psup( tk::genPsup( Disc()->Inpoel(), 4, m_esup ) ),
-  m_u( Disc()->Gid().size(),
-       g_inputdeck.get< tag::ncomp >() ),
-  m_uc( m_u.nunk(), m_u.nprop()+1 ),
-  m_un( m_u.nunk(), m_u.nprop() ),
-  m_rhs( m_u.nunk(), m_u.nprop() ),
-  m_rhsc(),
-  m_chBndGrad( Disc()->Bid().size(), m_u.nprop()*3 ),
-  m_dirbc(),
-  m_chBndGradc(),
-  m_blank( m_u.nunk(), 1.0 ),
-  m_diag(),
-  m_bnorm(),
-  m_bnormc(),
-  m_symbcnodes(),
-  m_farfieldbcnodes(),
-  m_symbctri(),
-  m_timedepbcnodes(),
-  m_timedepbcFn(),
-  m_stage( 0 ),
-  m_boxnodes(),
-  m_edgenode(),
-  m_edgeid(),
-  m_dtp( m_u.nunk(), 0.0 ),
-  m_tp( m_u.nunk(), g_inputdeck.get< tag::t0 >() ),
-  m_finished( 0 ),
-  m_movedmesh( 0 ),
-  m_nusermeshblk( 0 ),
-  m_nodeblockid(),
-  m_nodeblockidc(),
-  m_ixfer(0)
-// *****************************************************************************
-//  Constructor
-//! \param[in] disc Discretization proxy
-//! \param[in] bface Boundary-faces mapped to side sets used in the input file
-//! \param[in] bnode Boundary-node lists mapped to side sets used in input file
-//! \param[in] triinpoel Boundary-face connectivity where BCs set (global ids)
-// *****************************************************************************
-//! [Constructor]
-{
-  usesAtSync = true;    // enable migration at AtSync
-
-  auto d = Disc();
-
-  // Perform optional operator-access-pattern mesh node reordering
-  if (g_inputdeck.get< tag::operator_reorder >()) {
-
-    // Create new local ids based on access pattern of PDE operators
-    std::unordered_map< std::size_t, std::size_t > map;
-    std::size_t n = 0;
-
-    for (std::size_t p=0; p<m_u.nunk(); ++p) {  // for each point p
-      if (map.find(p) == end(map)) map[p] = n++;<--- Searching before insertion is not necessary.
-      for (auto q : tk::Around(m_psup,p)) {     // for each edge p-q
-        if (map.find(q) == end(map)) map[q] = n++;<--- Searching before insertion is not necessary.
-      }
-    }
-
-    Assert( map.size() == d->Gid().size(), "Map size mismatch" );
+namespace cg {
+
+//! \brief CompFlow used polymorphically with tk::CGPDE
+//! \details The template arguments specify policies and are used to configure
+//!   the behavior of the class. The policies are:
+//!   - Physics - physics configuration, see PDE/CompFlow/Physics.h
+//!   - Problem - problem configuration, see PDE/CompFlow/Problems.h
+//! \note The default physics is Euler, set in inciter::deck::check_compflow()
+template< class Physics, class Problem >
+class CompFlow {
+
+  private:
+    using ncomp_t = tk::ncomp_t;
+    using eq = tag::compflow;
+    using real = tk::real;
+
+    static constexpr std::size_t m_ncomp = 5;
+    static constexpr real muscl_eps = 1.0e-9;
+    static constexpr real muscl_const = 1.0/3.0;
+    static constexpr real muscl_m1 = 1.0 - muscl_const;
+    static constexpr real muscl_p1 = 1.0 + muscl_const;
+
+  public:
+    //! \brief Constructor
+    explicit CompFlow() :
+      m_physics(),
+      m_problem(),
+      m_stagCnf(),
+      m_fr(),
+      m_fp(),
+      m_fu()
+    {
+      Assert( g_inputdeck.get< tag::ncomp >() == m_ncomp,
+       "Number of CompFlow PDE components must be " + std::to_string(m_ncomp) );
+
+      // EoS initialization
+      const auto& matprop =
+        g_inputdeck.get< tag::material >();
+      const auto& matidxmap =
+        g_inputdeck.get< tag::matidxmap >();
+      auto mateos = matprop[matidxmap.get< tag::eosidx >()[0]].get<tag::eos>();
+      m_mat_blk.emplace_back( mateos, EqType::compflow, 0 );
+
+      // Boundary condition configurations
+      for (const auto& bci : g_inputdeck.get< tag::bc >()) {
+        // store stag-point coordinates
+        auto& spt = std::get< 0 >(m_stagCnf);
+        spt.insert( spt.end(), bci.get< tag::stag_point >().begin(),
+          bci.get< tag::stag_point >().end() );
+        // store stag-radius
+        std::get< 1 >(m_stagCnf).push_back( bci.get< tag::radius >() );
+        // freestream quantities
+        m_fr = bci.get< tag::density >();
+        m_fp = bci.get< tag::pressure >();
+        m_fu = bci.get< tag::velocity >();
+      }
+    }
+
+    //! Determine nodes that lie inside the user-defined IC box and mesh blocks
+    //! \param[in] coord Mesh node coordinates
+    //! \param[in] inpoel Element node connectivity
+    //! \param[in,out] inbox List of nodes at which box user ICs are set for
+    //!    each IC box
+    //! \param[in] elemblkid Element ids associated with mesh block ids where
+    //!   user ICs are set
+    //! \param[in,out] nodeblkid Node ids associated to mesh block ids, where
+    //!   user ICs are set
+    //! \param[in,out] nuserblk number of mesh blocks where user ICs are set
+    void IcBoxNodes( const tk::UnsMesh::Coords& coord,
+      const std::vector< std::size_t >& inpoel,
+      const std::unordered_map< std::size_t, std::set< std::size_t > >& elemblkid,
+      std::vector< std::unordered_set< std::size_t > >& inbox,
+      std::unordered_map< std::size_t, std::set< std::size_t > >& nodeblkid,
+      std::size_t& nuserblk ) const
+    {
+      const auto& x = coord[0];
+      const auto& y = coord[1];
+      const auto& z = coord[2];
+
+      // Detect if user has configured IC boxes
+      const auto& icbox = g_inputdeck.get<tag::ic, tag::box>();
+      if (!icbox.empty()) {
+        std::size_t bcnt = 0;
+        for (const auto& b : icbox) {   // for all boxes for this eq
+          inbox.emplace_back();
+          std::vector< tk::real > box
+            { b.template get< tag::xmin >(), b.template get< tag::xmax >(),
+              b.template get< tag::ymin >(), b.template get< tag::ymax >(),
+              b.template get< tag::zmin >(), b.template get< tag::zmax >() };
 
-    // Remap data in bound Discretization object
-    d->remap( map );
-    // Recompute elements surrounding points
-    m_esup = tk::genEsup( d->Inpoel(), 4 );
-    // Recompute points surrounding points
-    m_psup = tk::genPsup( d->Inpoel(), 4, m_esup );
-    // Remap boundary triangle face connectivity
-    tk::remap( m_triinpoel, map );
-  }
-
-  // Query/update boundary-conditions-related data structures from user input
-  getBCNodes();
-
-  // Activate SDAG wait for initially computing normals, and mesh blocks
-  thisProxy[ thisIndex ].wait4norm();
-  thisProxy[ thisIndex ].wait4meshblk();
-
-  // Determine user-specified mesh velocity
-  const auto& uservelvec =
-    g_inputdeck.get< tag::mesh >()[d->MeshId()].get< tag::velocity >();
-  m_uservel = {uservelvec[0], uservelvec[1], uservelvec[2]};
-
-  if (g_inputdeck.get< tag::steady_state >() &&
-    std::sqrt(tk::dot(m_uservel, m_uservel)) > 1e-8)
-    Throw("Mesh motion cannot be activated for steady state problem");
-
-  d->comfinal();
-
-}
-//! [Constructor]
-
-void
-OversetFE::getBCNodes()
-// *****************************************************************************
-// Query/update boundary-conditions-related data structures from user input
-// *****************************************************************************
-{
-  auto d = Disc();
-
-  // Prepare unique set of symmetry BC nodes
-  auto sym = d->bcnodes< tag::symmetry >( m_bface, m_triinpoel );
-  for (const auto& [s,nodes] : sym)
-    m_symbcnodes.insert( begin(nodes), end(nodes) );
-
-  // Prepare unique set of farfield BC nodes
-  auto far = d->bcnodes< tag::farfield >( m_bface, m_triinpoel );
-  for (const auto& [s,nodes] : far)
-    m_farfieldbcnodes.insert( begin(nodes), end(nodes) );
+          // Determine orientation of box
+          std::array< tk::real, 3 > b_orientn{{
+            b.template get< tag::orientation >()[0],
+            b.template get< tag::orientation >()[1],
+            b.template get< tag::orientation >()[2] }};
+          std::array< tk::real, 3 > b_centroid{{ 0.5*(box[0]+box[1]),
+            0.5*(box[2]+box[3]), 0.5*(box[4]+box[5]) }};
+
+          const auto eps = std::numeric_limits< tk::real >::epsilon();
+          // Determine which nodes lie in the IC box
+          if ( std::any_of( begin(box), end(box), [=](auto p)
+                            { return abs(p) > eps; } ) )
+          {
+            // Transform box to reference space
+            std::array< tk::real, 3 > b_min{{box[0], box[2], box[4]}};
+            std::array< tk::real, 3 > b_max{{box[1], box[3], box[5]}};
+            tk::movePoint(b_centroid, b_min);
+            tk::movePoint(b_centroid, b_max);
+
+            for (ncomp_t i=0; i<x.size(); ++i) {
+              std::array< tk::real, 3 > node{{ x[i], y[i], z[i] }};
+              // Transform node to reference space of box
+              tk::movePoint(b_centroid, node);
+              tk::rotatePoint({{-b_orientn[0], -b_orientn[1], -b_orientn[2]}},
+                node);
+              if ( node[0]>b_min[0] && node[0]<b_max[0] &&
+                node[1]>b_min[1] && node[1]<b_max[1] &&
+                node[2]>b_min[2] && node[2]<b_max[2] )
+              {
+                inbox[bcnt].insert( i );
+              }
+            }
+          }
+          ++bcnt;
+        }
+      }
+
+      // size IC mesh blocks volume vector
+      const auto& mblks = g_inputdeck.get< tag::ic, tag::meshblock >();
+      // if mesh blocks have been specified for this system
+      if (!mblks.empty()) {
+        std::size_t idMax(0);
+        for (const auto& imb : mblks) {
+          idMax = std::max(idMax, imb.get< tag::blockid >());
+        }
+        // size is idMax+1 since block ids are usually 1-based
+        nuserblk = nuserblk+idMax+1;
+      }
 
-  // If farfield BC is set on a node, will not also set symmetry BC
-  for (auto fn : m_farfieldbcnodes) m_symbcnodes.erase(fn);
-
-  // Prepare boundary nodes contiguously accessible from a triangle-face loop
-  m_symbctri.resize( m_triinpoel.size()/3, 0 );
-  for (std::size_t e=0; e<m_triinpoel.size()/3; ++e)
-    if (m_symbcnodes.find(m_triinpoel[e*3+0]) != end(m_symbcnodes))
-      m_symbctri[e] = 1;
-
-  // Prepare unique set of time dependent BC nodes
-  m_timedepbcnodes.clear();
-  m_timedepbcFn.clear();
-  const auto& timedep =
-    g_inputdeck.get< tag::bc >()[d->MeshId()].get< tag::timedep >();
-  if (!timedep.empty()) {
-    m_timedepbcnodes.resize(timedep.size());
-    m_timedepbcFn.resize(timedep.size());
-    std::size_t ib=0;
-    for (const auto& bndry : timedep) {
-      std::unordered_set< std::size_t > nodes;
-      for (const auto& s : bndry.template get< tag::sideset >()) {
-        auto k = m_bnode.find(static_cast<int>(s));
-        if (k != end(m_bnode)) {
-          for (auto g : k->second) {      // global node ids on side set
-            nodes.insert( tk::cref_find(d->Lid(),g) );
-          }
-        }
-      }
-      m_timedepbcnodes[ib].insert( begin(nodes), end(nodes) );
-
-      // Store user defined discrete function in time. This is done in the same
-      // loop as the BC nodes, so that the indices for the two vectors
-      // m_timedepbcnodes and m_timedepbcFn are consistent with each other
-      auto fn = bndry.template get< tag::fn >();
-      for (std::size_t ir=0; ir<fn.size()/6; ++ir) {
-        m_timedepbcFn[ib].push_back({{ fn[ir*6+0], fn[ir*6+1], fn[ir*6+2],
-          fn[ir*6+3], fn[ir*6+4], fn[ir*6+5] }});
-      }
-      ++ib;
-    }
-  }
+      // determine node set for IC mesh blocks
+      for (const auto& [blid, elset] : elemblkid) {
+        if (!elset.empty()) {
+          auto& ndset = nodeblkid[blid];
+          for (auto ie : elset) {
+            for (std::size_t i=0; i<4; ++i) ndset.insert(inpoel[4*ie+i]);
+          }
+        }
+      }
+    }
+
+    //! Initalize the compressible flow equations, prepare for time integration
+    //! \param[in] coord Mesh node coordinates
+    //! \param[in,out] unk Array of unknowns
+    //! \param[in] t Physical time
+    //! \param[in] V Discrete volume of user-defined IC box
+    //! \param[in] inbox List of nodes at which box user ICs are set (for each
+    //!    box IC)
+    //! \param[in] nodeblkid Node ids associated to mesh block ids, where
+    //!   user ICs are set
+    //! \param[in] blkvols Vector of discrete volumes of each block where user
+    //!   ICs are set
+    void initialize(
+      const std::array< std::vector< real >, 3 >& coord,
+      tk::Fields& unk,
+      real t,
+      real V,
+      const std::vector< std::unordered_set< std::size_t > >& inbox,
+      const std::vector< tk::real >& blkvols,
+      const std::unordered_map< std::size_t, std::set< std::size_t > >&
+        nodeblkid ) const
+    {
+      Assert( coord[0].size() == unk.nunk(), "Size mismatch" );
+
+      const auto& x = coord[0];
+      const auto& y = coord[1];
+      const auto& z = coord[2];
+
+      const auto& ic = g_inputdeck.get< tag::ic >();
+      const auto& icbox = ic.get< tag::box >();
+      const auto& mblks = ic.get< tag::meshblock >();
 
-  Assert(m_timedepbcFn.size() == m_timedepbcnodes.size(), "Incorrect number of "
-    "time dependent functions.");
-}
+      const auto eps = 1000.0 * std::numeric_limits< tk::real >::epsilon();
+
+      tk::real bgpre = ic.get< tag::pressure >();
 
-void
-OversetFE::norm()
-// *****************************************************************************
-// Start (re-)computing boundary point-, and dual-face normals
-// *****************************************************************************
-{
-  auto d = Disc();
-
-  // Query nodes at which symmetry BCs are specified
-  auto bn = d->bcnodes< tag::symmetry >( m_bface, m_triinpoel );
-
-  // Query nodes at which farfield BCs are specified
-  auto far = d->bcnodes< tag::farfield >( m_bface, m_triinpoel );
-  // Merge BC data where boundary-point normals are required
-  for (const auto& [s,n] : far) bn[s].insert( begin(n), end(n) );
-
-  // Query nodes at which mesh velocity symmetry BCs are specified
-  std::unordered_map<int, std::unordered_set< std::size_t >> ms;
-  for (const auto& s : g_inputdeck.get< tag::ale, tag::symmetry >()) {
-    auto k = m_bface.find(static_cast<int>(s));
-    if (k != end(m_bface)) {
-      auto& n = ms[ k->first ];
-      for (auto f : k->second) {
-        n.insert( m_triinpoel[f*3+0] );
-        n.insert( m_triinpoel[f*3+1] );
-        n.insert( m_triinpoel[f*3+2] );
-      }
-    }
-  }
-  // Merge BC data where boundary-point normals are required
-  for (const auto& [s,n] : ms) bn[s].insert( begin(n), end(n) );
-
-  // Compute boundary point normals
-  bnorm( bn );
-
-  // Compute dual-face normals associated to edges
-  dfnorm();
-}
+      auto c_v = getmatprop< tag::cv >();
+
+      // Set initial and boundary conditions using problem policy
+      for (ncomp_t i=0; i<x.size(); ++i) {
+        auto s = Problem::initialize( m_ncomp, m_mat_blk, x[i], y[i], z[i], t );
+
+        // initialize the user-defined box IC
+        if (!icbox.empty()) {
+          std::size_t bcnt = 0;
+          for (const auto& b : icbox) { // for all boxes
+            if (inbox.size() > bcnt && inbox[bcnt].find(i) != inbox[bcnt].end())
+            {
+              std::vector< tk::real > box
+              { b.template get< tag::xmin >(), b.template get< tag::xmax >(),
+                b.template get< tag::ymin >(), b.template get< tag::ymax >(),
+                b.template get< tag::zmin >(), b.template get< tag::zmax >() };
+              auto V_ex = (box[1]-box[0]) * (box[3]-box[2]) * (box[5]-box[4]);
+              if (V_ex < eps) V = 1.0;
+              initializeBox<ctr::boxList>( m_mat_blk, V_ex/V,
+                V_ex, t, b, bgpre, c_v, s );
+            }
+            ++bcnt;
+          }
+        }
+
+        // initialize user-defined mesh block ICs
+        for (const auto& b : mblks) { // for all blocks
+          auto blid = b.get< tag::blockid >();
+          auto V_ex = b.get< tag::volume >();
+          if (blid >= blkvols.size()) Throw("Block volume not found");
+          if (nodeblkid.find(blid) != nodeblkid.end()) {
+            const auto& ndset = tk::cref_find(nodeblkid, blid);
+            if (ndset.find(i) != ndset.end()) {
+              initializeBox<ctr::meshblockList>( m_mat_blk,
+                V_ex/blkvols[blid], V_ex, t, b, bgpre, c_v, s );
+            }
+          }
+        }
 
-std::array< tk::real, 3 >
-OversetFE::edfnorm( const tk::UnsMesh::Edge& edge,
-                const std::unordered_map< tk::UnsMesh::Edge,
-                        std::vector< std::size_t >,
-                        tk::UnsMesh::Hash<2>, tk::UnsMesh::Eq<2> >& esued )
-const
-// *****************************************************************************
-//  Compute normal of dual-mesh associated to edge
-//! \param[in] edge Edge whose dual-face normal to compute given by local ids
-//! \param[in] esued Elements surrounding edges
-//! \return Dual-face normal for edge
-// *****************************************************************************
-{
-  auto d = Disc();
-  const auto& inpoel = d->Inpoel();
-  const auto& coord = d->Coord();
-  const auto& x = coord[0];
-  const auto& y = coord[1];
-  const auto& z = coord[2];
-
-  std::array< tk::real, 3 > n{ 0.0, 0.0, 0.0 };
-
-  for (auto e : tk::cref_find(esued,edge)) {
-    // access node IDs
-    const std::array< std::size_t, 4 >
-      N{ inpoel[e*4+0], inpoel[e*4+1], inpoel[e*4+2], inpoel[e*4+3] };
-    // compute element Jacobi determinant
-    const std::array< tk::real, 3 >
-      ba{{ x[N[1]]-x[N[0]], y[N[1]]-y[N[0]], z[N[1]]-z[N[0]] }},
-      ca{{ x[N[2]]-x[N[0]], y[N[2]]-y[N[0]], z[N[2]]-z[N[0]] }},
-      da{{ x[N[3]]-x[N[0]], y[N[3]]-y[N[0]], z[N[3]]-z[N[0]] }};
-    const auto J = tk::triple( ba, ca, da );        // J = 6V
-    Assert( J > 0, "Element Jacobian non-positive" );
-    // shape function derivatives, nnode*ndim [4][3]
-    std::array< std::array< tk::real, 3 >, 4 > grad;
-    grad[1] = tk::crossdiv( ca, da, J );
-    grad[2] = tk::crossdiv( da, ba, J );
-    grad[3] = tk::crossdiv( ba, ca, J );
-    for (std::size_t i=0; i<3; ++i)
-      grad[0][i] = -grad[1][i]-grad[2][i]-grad[3][i];
-    // sum normal contributions
-    // The constant 1/48: Eq (12) from Waltz et al. Computers & fluids (92) 2014
-    // The result of the integral of shape function N on a tet is V/4.
-    // This can be written as J/(6*4). Eq (12) has a 1/2 multiplier.
-    // This leads to J/48.
-    auto J48 = J/48.0;
-    for (const auto& [a,b] : tk::lpoed) {
-      auto s = tk::orient( {N[a],N[b]}, edge );
-      for (std::size_t j=0; j<3; ++j)
-        n[j] += J48 * s * (grad[a][j] - grad[b][j]);
-    }
-  }
-
-  return n;
-}
-
-void
-OversetFE::dfnorm()
-// *****************************************************************************
-// Compute dual-face normals associated to edges
-// *****************************************************************************
-{
-  auto d = Disc();
-  const auto& inpoel = d->Inpoel();
-  const auto& gid = d->Gid();
-
-  // compute derived data structures
-  auto esued = tk::genEsued( inpoel, 4, tk::genEsup( inpoel, 4 ) );
-
-  // Compute dual-face normals for domain edges
-  for (std::size_t p=0; p<gid.size(); ++p)    // for each point p
-    for (auto q : tk::Around(m_psup,p))       // for each edge p-q
-      if (gid[p] < gid[q])
-        m_dfnorm[{gid[p],gid[q]}] = edfnorm( {p,q}, esued );
-
-  // Send our dual-face normal contributions to neighbor chares
-  if (d->EdgeCommMap().empty())
-    comdfnorm_complete();
-  else {
-    for (const auto& [c,edges] : d->EdgeCommMap()) {
-      decltype(m_dfnorm) exp;
-      for (const auto& e : edges) exp[e] = tk::cref_find(m_dfnorm,e);
-      thisProxy[c].comdfnorm( exp );
-    }
-  }
-
-  owndfnorm_complete();
-}
-
-void
-OversetFE::comdfnorm( const std::unordered_map< tk::UnsMesh::Edge,
-                    std::array< tk::real, 3 >,
-                    tk::UnsMesh::Hash<2>, tk::UnsMesh::Eq<2> >& dfnorm )
-// *****************************************************************************
-// Receive contributions to dual-face normals on chare-boundaries
-//! \param[in] dfnorm Incoming partial sums of dual-face normals associated to
-//!   chare-boundary edges
-// *****************************************************************************
-{
-  // Buffer up inccoming contributions to dual-face normals
-  for (const auto& [e,n] : dfnorm) {
-    auto& dfn = m_dfnormc[e];
-    dfn[0] += n[0];
-    dfn[1] += n[1];
-    dfn[2] += n[2];
-  }
-
-  if (++m_ndfnorm == Disc()->EdgeCommMap().size()) {
-    m_ndfnorm = 0;
-    comdfnorm_complete();
-  }
-}
-
-void
-OversetFE::bnorm( const std::unordered_map< int,
-                std::unordered_set< std::size_t > >& bcnodes )
-// *****************************************************************************
-//  Compute boundary point normals
-//! \param[in] bcnodes Local node ids associated to side set ids at which BCs
-//!    are set that require normals
-//*****************************************************************************
-{
-  auto d = Disc();
-
-  m_bnorm = cg::bnorm( m_bface, m_triinpoel, d->Coord(), d->Gid(), bcnodes );
-
-  // Send our nodal normal contributions to neighbor chares
-  if (d->NodeCommMap().empty())
-    comnorm_complete();
-  else
-    for (const auto& [ neighborchare, sharednodes ] : d->NodeCommMap()) {
-      std::unordered_map< int,
-        std::unordered_map< std::size_t, std::array< tk::real, 4 > > > exp;
-      for (auto i : sharednodes) {
-        for (const auto& [s,norms] : m_bnorm) {
-          auto j = norms.find(i);
-          if (j != end(norms)) exp[s][i] = j->second;
-        }
-      }
-      thisProxy[ neighborchare ].comnorm( exp );
-    }
-
-  ownnorm_complete();
-}
+        unk(i,0) = s[0]; // rho
+        if (stagPoint(x[i],y[i],z[i])) {
+          unk(i,1) = unk(i,2) = unk(i,3) = 0.0;
+        } else {
+          unk(i,1) = s[1]; // rho * u
+          unk(i,2) = s[2]; // rho * v
+          unk(i,3) = s[3]; // rho * w
+        }
+        unk(i,4) = s[4]; // rho * e, e: total = kinetic + internal
+      }
+    }
+
+    //! Query the fluid velocity
+    //! \param[in] u Solution vector of conserved variables
+    //! \param[in,out] v Velocity components
+    void velocity( const tk::Fields& u, tk::UnsMesh::Coords& v ) const {
+      for (std::size_t j=0; j<3; ++j) {
+        // extract momentum
+        v[j] = u.extract_comp( 1+j );
+        Assert( v[j].size() == u.nunk(), "Size mismatch" );
+        // divide by density
+        for (std::size_t i=0; i<u.nunk(); ++i) v[j][i] /= u(i,0);
+      }
+    }
+
+    //! Query the sound speed
+    //! \param[in] U Solution vector of conserved variables
+    //! \param[in,out] s Speed of sound in mesh nodes
+    void soundspeed( const tk::Fields& U, std::vector< tk::real >& s ) const {
+      s.resize( U.nunk() );
+      for (std::size_t i=0; i<U.nunk(); ++i) {
+        auto r  = U(i,0);
+        auto ru = U(i,1);
+        auto rv = U(i,2);
+        auto rw = U(i,3);
+        auto re = U(i,4);
+        auto p = m_mat_blk[0].compute< EOS::pressure >(r, ru/r, rv/r, rw/r, re);
+        s[i] = m_mat_blk[0].compute< EOS::soundspeed >( r, p );
+      }
+    }
+
+    //! Return analytic solution (if defined by Problem) at xi, yi, zi, t
+    //! \param[in] xi X-coordinate
+    //! \param[in] yi Y-coordinate
+    //! \param[in] zi Z-coordinate
+    //! \param[in] t Physical time
+    //! \return Vector of analytic solution at given location and time
+    std::vector< real >
+    analyticSolution( real xi, real yi, real zi, real t ) const
+    { return Problem::analyticSolution( m_ncomp, m_mat_blk, xi, yi, zi, t ); }
+
+    //! Return analytic solution for conserved variables
+    //! \param[in] xi X-coordinate at which to evaluate the analytic solution
+    //! \param[in] yi Y-coordinate at which to evaluate the analytic solution
+    //! \param[in] zi Z-coordinate at which to evaluate the analytic solution
+    //! \param[in] t Physical time at which to evaluate the analytic solution
+    //! \return Vector of analytic solution at given location and time
+    std::vector< tk::real >
+    solution( tk::real xi, tk::real yi, tk::real zi, tk::real t ) const
+    { return Problem::initialize( m_ncomp, m_mat_blk, xi, yi, zi, t ); }
+
+    //! \brief Compute nodal gradients of primitive variables for ALECG along
+    //!   chare-boundary
+    //! \param[in] coord Mesh node coordinates
+    //! \param[in] inpoel Mesh element connectivity
+    //! \param[in] bndel List of elements contributing to chare-boundary nodes
+    //! \param[in] gid Local->global node id map
+    //! \param[in] bid Local chare-boundary node ids (value) associated to
+    //!    global node ids (key)
+    //! \param[in] U Solution vector at recent time step
+    //! \param[in,out] G Nodal gradients of primitive variables
+    //! \details This function only computes local contributions to gradients
+    //!   at chare-boundary nodes. Internal node gradients are calculated as
+    //!   required, and do not need to be stored.
+    void chBndGrad( const std::array< std::vector< real >, 3 >& coord,
+                    const std::vector< std::size_t >& inpoel,
+                    const std::vector< std::size_t >& bndel,
+                    const std::vector< std::size_t >& gid,
+                    const std::unordered_map< std::size_t, std::size_t >& bid,
+                    const tk::Fields& U,
+                    tk::Fields& G ) const
+    {
+      Assert( U.nunk() == coord[0].size(), "Number of unknowns in solution "
+              "vector at recent time step incorrect" );
+
+      // compute gradients of primitive variables in points
+      G.fill( 0.0 );
+
+      // access node cooordinates
+      const auto& x = coord[0];
+      const auto& y = coord[1];
+      const auto& z = coord[2];
+
+      for (auto e : bndel) {  // elements contributing to chare boundary nodes
+        // access node IDs
+        std::size_t N[4] =
+          { inpoel[e*4+0], inpoel[e*4+1], inpoel[e*4+2], inpoel[e*4+3] };
+        // compute element Jacobi determinant, J = 6V
+        real bax = x[N[1]]-x[N[0]];
+        real bay = y[N[1]]-y[N[0]];
+        real baz = z[N[1]]-z[N[0]];
+        real cax = x[N[2]]-x[N[0]];
+        real cay = y[N[2]]-y[N[0]];
+        real caz = z[N[2]]-z[N[0]];
+        real dax = x[N[3]]-x[N[0]];
+        real day = y[N[3]]-y[N[0]];
+        real daz = z[N[3]]-z[N[0]];
+        auto J = tk::triple( bax, bay, baz, cax, cay, caz, dax, day, daz );
+        ErrChk( J > 0, "Element Jacobian non-positive" );
+        auto J24 = J/24.0;
+        // shape function derivatives, nnode*ndim [4][3]
+        real g[4][3];
+        tk::crossdiv( cax, cay, caz, dax, day, daz, J,
+                      g[1][0], g[1][1], g[1][2] );
+        tk::crossdiv( dax, day, daz, bax, bay, baz, J,
+                      g[2][0], g[2][1], g[2][2] );
+        tk::crossdiv( bax, bay, baz, cax, cay, caz, J,
+                      g[3][0], g[3][1], g[3][2] );
+        for (std::size_t i=0; i<3; ++i)
+          g[0][i] = -g[1][i] - g[2][i] - g[3][i];
+        // scatter-add gradient contributions to boundary nodes
+        for (std::size_t a=0; a<4; ++a) {
+          auto i = bid.find( gid[N[a]] );
+          if (i != end(bid)) {
+            real u[5];
+            for (std::size_t b=0; b<4; ++b) {
+              u[0] = U(N[b],0);
+              u[1] = U(N[b],1)/u[0];
+              u[2] = U(N[b],2)/u[0];
+              u[3] = U(N[b],3)/u[0];
+              u[4] = U(N[b],4)/u[0]
+                     - 0.5*(u[1]*u[1] + u[2]*u[2] + u[3]*u[3]);
+              if ( stagPoint(x[N[b]],y[N[b]],z[N[b]]) )
+              {
+                u[1] = u[2] = u[3] = 0.0;
+              }
+              for (std::size_t c=0; c<5; ++c)
+                for (std::size_t j=0; j<3; ++j)
+                  G(i->second,c*3+j) += J24 * g[b][j] * u[c];
+            }
+          }
+        }
+      }
+    }
 
-void
-OversetFE::comnorm( const std::unordered_map< int,
-  std::unordered_map< std::size_t, std::array< tk::real, 4 > > >& innorm )
-// *****************************************************************************
-// Receive boundary point normals on chare-boundaries
-//! \param[in] innorm Incoming partial sums of boundary point normal
-//!   contributions to normals (first 3 components), inverse distance squared
-//!   (4th component), associated to side set ids
-// *****************************************************************************
-{
-  // Buffer up incoming boundary-point normal vector contributions
-  for (const auto& [s,norms] : innorm) {
-    auto& bnorms = m_bnormc[s];
-    for (const auto& [p,n] : norms) {
-      auto& bnorm = bnorms[p];
-      bnorm[0] += n[0];
-      bnorm[1] += n[1];
-      bnorm[2] += n[2];
-      bnorm[3] += n[3];
-    }
-  }
-
-  if (++m_nbnorm == Disc()->NodeCommMap().size()) {
-    m_nbnorm = 0;
-    comnorm_complete();
-  }
-}
-
-void
-OversetFE::registerReducers()
-// *****************************************************************************
-//  Configure Charm++ reduction types initiated from this chare array
-//! \details Since this is a [initnode] routine, the runtime system executes the
-//!   routine exactly once on every logical node early on in the Charm++ init
-//!   sequence. Must be static as it is called without an object. See also:
-//!   Section "Initializations at Program Startup" at in the Charm++ manual
-//!   http://charm.cs.illinois.edu/manuals/html/charm++/manual.html.
-// *****************************************************************************
-{
-  NodeDiagnostics::registerReducers();
-}
-
-void
-OversetFE::ResumeFromSync()
-// *****************************************************************************
-//  Return from migration
-//! \details This is called when load balancing (LB) completes. The presence of
-//!   this function does not affect whether or not we block on LB.
-// *****************************************************************************
-{
-  if (Disc()->It() == 0) Throw( "it = 0 in ResumeFromSync()" );
-
-  if (!g_inputdeck.get< tag::cmd, tag::nonblocking >()) next();
-}
-
-//! [setup]
-void
-OversetFE::setup()
-// *****************************************************************************
-// Start setup for solution
-// *****************************************************************************
-{
-  auto d = Disc();
-
-  // Determine nodes inside user-defined IC box
-  g_cgpde[d->MeshId()].IcBoxNodes( d->Coord(), d->Inpoel(),
-    d->ElemBlockId(), m_boxnodes, m_nodeblockid, m_nusermeshblk );
+    //! Compute right hand side for ALECG
+    //! \param[in] t Physical time
+    //! \param[in] coord Mesh node coordinates
+    //! \param[in] inpoel Mesh element connectivity
+    //! \param[in] triinpoel Boundary triangle face connecitivity with local ids
+    //! \param[in] bid Local chare-boundary node ids (value) associated to
+    //!    global node ids (key)
+    //! \param[in] gid Local->glocal node ids
+    //! \param[in] lid Global->local node ids
+    //! \param[in] dfn Dual-face normals
+    //! \param[in] psup Points surrounding points
+    //! \param[in] esup Elements surrounding points
+    //! \param[in] symbctri Vector with 1 at symmetry BC boundary triangles
+    //! \param[in] vol Nodal volumes
+    //! \param[in] edgenode Local node IDs of edges
+    //! \param[in] edgeid Edge ids in the order of access
+    //! \param[in] boxnodes Mesh node ids within user-defined IC boxes
+    //! \param[in] G Nodal gradients for chare-boundary nodes
+    //! \param[in] U Solution vector at recent time step
+    //! \param[in] W Mesh velocity
+    //! \param[in] tp Physical time for each mesh node
+    //! \param[in] V Total box volume
+    //! \param[in,out] R Right-hand side vector computed
+    void rhs( real t,
+              const std::array< std::vector< real >, 3 >& coord,
+              const std::vector< std::size_t >& inpoel,
+              const std::vector< std::size_t >& triinpoel,
+              const std::vector< std::size_t >& gid,
+              const std::unordered_map< std::size_t, std::size_t >& bid,
+              const std::unordered_map< std::size_t, std::size_t >& lid,
+              const std::vector< real >& dfn,
+              const std::pair< std::vector< std::size_t >,
+                               std::vector< std::size_t > >& psup,
+              const std::pair< std::vector< std::size_t >,
+                               std::vector< std::size_t > >& esup,
+              const std::vector< int >& symbctri,
+              const std::vector< real >& vol,
+              const std::vector< std::size_t >& edgenode,
+              const std::vector< std::size_t >& edgeid,
+              const std::vector< std::unordered_set< std::size_t > >& boxnodes,
+              const tk::Fields& G,
+              const tk::Fields& U,
+              const tk::Fields& W,
+              const std::vector< tk::real >& tp,
+              real V,
+              tk::Fields& R ) const
+    {
+      Assert( G.nprop() == m_ncomp*3,
+              "Number of components in gradient vector incorrect" );
+      Assert( U.nunk() == coord[0].size(), "Number of unknowns in solution "
+              "vector at recent time step incorrect" );
+      Assert( R.nunk() == coord[0].size(),
+              "Number of unknowns and/or number of components in right-hand "
+              "side vector incorrect" );
+      Assert( W.nunk() == coord[0].size(), "Size mismatch " );
+
+      // compute/assemble gradients in points
+      auto Grad = nodegrad( coord, inpoel, lid, bid, vol, esup, U, G );
+
+      // zero right hand side for all components
+      for (ncomp_t c=0; c<m_ncomp; ++c) R.fill( c, 0.0 );
+
+      // compute domain-edge integral
+      domainint( coord, gid, edgenode, edgeid, psup, dfn, U, W, Grad, R );
+
+      // compute boundary integrals
+      bndint( coord, triinpoel, symbctri, U, W, R );
 
-  // Communicate mesh block nodes to other chares on chare-boundary
-  if (d->NodeCommMap().empty())        // in serial we are done
-    comblk_complete();
-  else // send mesh block information to chare-boundary nodes to fellow chares
-    for (const auto& [c,n] : d->NodeCommMap()) {
-      // data structure assigning block ids (set of values) to nodes (index).
-      // although nodeblockid is a map with key-blockid and value-nodeid, the
-      // sending data structure has to be inverted, because of how communication
-      // data is handled.
-      std::vector< std::set< std::size_t > > mb( n.size() );
-      std::size_t j = 0;
-      for (auto i : n) {
-        for (const auto& [blid, ndset] : m_nodeblockid) {
-          // if node was found in a block, add to send-data
-          if (ndset.find(tk::cref_find(d->Lid(),i)) != ndset.end())
-            mb[j].insert(blid);
+      // compute external (energy) sources
+      const auto& icbox = g_inputdeck.get< tag::ic, tag::box >();
+
+      if (!icbox.empty() && !boxnodes.empty()) {
+        std::size_t bcnt = 0;
+        for (const auto& b : icbox) {   // for all boxes for this eq
+          std::vector< tk::real > box
+           { b.template get< tag::xmin >(), b.template get< tag::xmax >(),
+             b.template get< tag::ymin >(), b.template get< tag::ymax >(),
+             b.template get< tag::zmin >(), b.template get< tag::zmax >() };
+
+          const auto& initiate = b.template get< tag::initiate >();
+          if (initiate == ctr::InitiateType::LINEAR) {
+            boxSrc( V, t, inpoel, esup, boxnodes[bcnt], coord, R );
+          }
+          ++bcnt;
         }
-        if (m_nusermeshblk > 0)
-          Assert(mb[j].size() > 0, "Sending no block data for node");
-        ++j;
-      }
-      thisProxy[c].comblk( std::vector<std::size_t>(begin(n),end(n)), mb );
-    }
-
-  ownblk_complete();
-}
-
-void
-OversetFE::comblk( const std::vector< std::size_t >& gid,
-               const std::vector< std::set< std::size_t > >& mb )
-// *****************************************************************************
-//  Receive mesh block information for nodes on chare-boundaries
-//! \param[in] gid Global mesh node IDs at which we receive RHS contributions
-//! \param[in] mb Block ids for each node on chare-boundaries
-//! \details This function receives mesh block information for nodes on chare
-//!   boundaries. While m_nodeblockid stores block information for own nodes,
-//!   m_nodeblockidc collects the neighbor chare information during
-//!   communication. This way work on m_nodeblockid and m_nodeblockidc is
-//!   overlapped. The two are combined in continueSetup().
-// *****************************************************************************
-{
-  Assert( mb.size() == gid.size(), "Size mismatch" );
-
-  for (std::size_t i=0; i<gid.size(); ++i) {
-    for (const auto& blid : mb[i]) {
-      m_nodeblockidc[blid].insert(gid[i]);
-    }
-  }
-
-  // When we have heard from all chares we communicate with, this chare is done
-  if (++m_nmblk == Disc()->NodeCommMap().size()) {
-    m_nmblk = 0;
-    comblk_complete();
-  }
-}
-
-void
-OversetFE::continueSetup()
-// *****************************************************************************
-// Continue setup for solution, after communication for mesh blocks
-// *****************************************************************************
-{
-  auto d = Disc();
-
-  // Combine own and communicated mesh block information
-  for (const auto& [blid, ndset] : m_nodeblockidc) {
-    for (const auto& i : ndset) {
-      auto lid = tk::cref_find(d->Lid(), i);
-      m_nodeblockid[blid].insert(lid);
-    }
-  }
-
-  // clear receive buffer
-  tk::destroy(m_nodeblockidc);
-
-  // Compute volume of user-defined box IC
-  d->boxvol( m_boxnodes, m_nodeblockid, m_nusermeshblk );
+      }
+
+      // compute optional source integral
+      src( coord, inpoel, t, tp, R );
+    }
+
+    //! Compute overset mesh motion for OversetFE
+//    //! \param[in] t Physical time
+//    //! \param[in] coord Mesh node coordinates
+    //! \param[in] psup Points surrounding points
+    //! \param[in] symbcnodes Symmetry BC node list
+    //! \param[in] uservel User specified constant mesh velocity
+    //! \param[in] U Solution vector at recent time step
+//    //! \param[in,out] meshvel Velocity of each mesh node based on user input
+    //! \param[in,out] movedmesh True/false if mesh moved
+    void getMeshVel(
+      real /*t*/,
+      const std::array< std::vector< real >, 3 >& /*coord*/,
+      const std::pair< std::vector< std::size_t >,
+                       std::vector< std::size_t > >& psup,
+      const std::unordered_set< std::size_t >& symbcnodes,
+      const std::array< tk::real, 3 >& uservel,
+      const tk::Fields& U,
+      tk::Fields& /*meshvel*/,
+      int& movedmesh ) const
+    {
+      //Assert( meshvel.nunk() == U.nunk(),
+      //  "Mesh-velocity vector has incorrect size" );
+
+      auto uvelmag = std::sqrt(tk::dot(uservel, uservel));
+
+      // Check for pressure differential only if mesh has not moved before
+      if (movedmesh == 0 && uvelmag > 1e-8) {
+        for (auto p : symbcnodes) {
+          for (auto q : tk::Around(psup,p)) {
+            // compute pressure difference
+            real rL  = U(p,0);
+            real ruL = U(p,1) / rL;
+            real rvL = U(p,2) / rL;
+            real rwL = U(p,3) / rL;
+            real reL = U(p,4) / rL - 0.5*(ruL*ruL + rvL*rvL + rwL*rwL);
+            real rR  = U(q,0);
+            real ruR = U(q,1) / rR;
+            real rvR = U(q,2) / rR;
+            real rwR = U(q,3) / rR;
+            real reR = U(q,4) / rR - 0.5*(ruR*ruR + rvR*rvR + rwR*rwR);
+            real pL = m_mat_blk[0].compute< EOS::pressure >( rL, ruL/rL, rvL/rL,
+              rwL/rL, reL );
+            real pR = m_mat_blk[0].compute< EOS::pressure >( rR, ruR/rR, rvR/rR,
+              rwR/rR, reR );
+
+            if (std::abs(pR/pL) > 2.0) {
+              movedmesh = 1;
+              break;
+            }
+          }
+          if (movedmesh) break;
+        }
+      }
+    }
 
-  // Query time history field output labels from all PDEs integrated
-  const auto& hist_points = g_inputdeck.get< tag::history_output, tag::point >();
-  if (!hist_points.empty()) {
-    std::vector< std::string > histnames;
-    auto n = g_cgpde[d->MeshId()].histNames();
-    histnames.insert( end(histnames), begin(n), end(n) );
-    d->histheader( std::move(histnames) );
-  }
-}
-//! [setup]
-
-void
-OversetFE::box( tk::real v, const std::vector< tk::real >& blkvols )
-// *****************************************************************************
-// Receive total box IC volume and set conditions in box
-//! \param[in] v Total volume within user-specified box
-//! \param[in] blkvols Vector of mesh block discrete volumes with user ICs
-// *****************************************************************************
-{
-  Assert(blkvols.size() == m_nusermeshblk,
-    "Incorrect size of block volume vector");
-  auto d = Disc();
-
-  // Store user-defined box/block IC volume
-  d->Boxvol() = v;
-  d->MeshBlkVol() = blkvols;
-
-  // Set initial conditions for all PDEs
-  g_cgpde[d->MeshId()].initialize( d->Coord(), m_u, d->T(), d->Boxvol(),
-    m_boxnodes, d->MeshBlkVol(), m_nodeblockid );
-
-  // Initialize nodal mesh volumes at previous time step stage
-  d->Voln() = d->Vol();
-
-  // Initiate solution transfer (if coupled)
-  transferSol();
-}
-
-void
-OversetFE::transferSol()
-// *****************************************************************************
-// Transfer solution to other solver and mesh if coupled
-// *****************************************************************************
-{
-  // Set up transfer-flags for receiving mesh
-  if (m_ixfer == 1) {
-    applySolTransfer(0);
-  }
-  setTransferFlags(m_ixfer);
-  ++m_ixfer;
-
-  // Initiate IC transfer (if coupled)
-  Disc()->transfer( m_uc, m_ixfer-1,
-    CkCallback(CkIndex_OversetFE::lhs(), thisProxy[thisIndex]) );
-}
-
-//! [Compute lhs]
-void
-OversetFE::lhs()
-// *****************************************************************************
-// Compute the left-hand side of transport equations
-//! \details Also (re-)compute all data structures if the mesh changed.
-// *****************************************************************************
-{
-  // Do corrections in solution based on incoming transfer
-  applySolTransfer(1);
-  m_ixfer = 0;
-
-  // No need for LHS in OversetFE
-
-  // If mesh moved: (Re-)compute boundary point- and dual-face normals, and
-  //   then proceed to stage()
-  // If mesh did not move: shortcut to stage()
-  if (m_movedmesh || Disc()->Initial()) norm();
-  else stage();
-}
-//! [Compute lhs]
-
-//! [Merge normals and continue]
-void
-OversetFE::mergelhs()
-// *****************************************************************************
-// The own and communication portion of the left-hand side is complete
-// *****************************************************************************
-{
-  // Combine own and communicated contributions of normals
-  normfinal();
-
-  // Start with time stepping logic
-  if (Disc()->Initial()) {
-    // Output initial conditions to file and then start time stepping
-    writeFields( CkCallback(CkIndex_OversetFE::start(), thisProxy[thisIndex]) );
-  }
-  else stage();
-}
-//! [Merge normals and continue]
-
-//! [start]
-void
-OversetFE::start()
-// *****************************************************************************
-// Start time stepping
-// *****************************************************************************
-{
-  // Set flag that indicates that we are now during time stepping
-  Disc()->Initial( 0 );
-  // Start timer measuring time stepping wall clock time
-  Disc()->Timer().zero();
-  // Zero grind-timer
-  Disc()->grindZero();
-  // Continue to first time step
-  next();
-}
-//! [start]
-
-void
-OversetFE::applySolTransfer(
-  std::size_t dirn )
-// *****************************************************************************
-// \brief Apply the transferred solution to the solution vector based on
-//   transfer flags previously set up
-//! \param[in] dirn 0 if called from B to O, 1 if called from O to B
-// *****************************************************************************
-{
-  // Change solution only if:
-  //   1. undergoing transfer from B to O, and currently on O
-  if (dirn == 0 && Disc()->MeshId() != 0) {
-
-    for (auto i : m_farfieldbcnodes) {
-      // overset-BC nodes: use transferred solution and blank nodes.
-      // the transfer-flag from m_uc is not used since it has been overwritten
-      // by Disc()->transfer() with the flag from B
-      for (ncomp_t c=0; c<m_u.nprop(); ++c) { // Loop over number of equations
-        m_u(i,c) = m_uc(i,c);
-      }
-      m_blank[i] = 0.0;
-    }
-
-  }
-  //   2. undergoing transfer from O to B, and currently on B
-  else if (dirn == 1 && Disc()->MeshId() == 0) {
-
-    //TODO: index the flag in a better way
-    std::size_t iflag = m_uc.nprop()-1;
-
-    // Zero out solution space for nodes with a specific transfer flag set
-    for (std::size_t i=0; i<m_uc.nunk(); ++i) { // Check flag value
-
-      if (std::abs(m_uc(i,iflag) - 1.0) < 1e-4) {
-        // overset-BC nodes: use transferred solution and blank nodes
-        for (ncomp_t c=0; c<m_u.nprop(); ++c) { // Loop over number of equations
-          m_u(i,c) = m_uc(i,c);
-        }
-        m_blank[i] = 0.0;
-      }
-      else if (std::abs(m_uc(i,iflag) - 2.0) < 1e-4) {
-        // hole: blank nodes
-        m_blank[i] = 0.0;
-      }
-      else {
-        // do nothing
-        m_blank[i] = 1.0;
-      }
-
-    }
-
-  }
-}
+    //! Compute the minimum time step size (for unsteady time stepping)
+    //! \param[in] coord Mesh node coordinates
+    //! \param[in] inpoel Mesh element connectivity
+    //! \param[in] t Physical time
+    //! \param[in] dtn Time step size at the previous time step
+    //! \param[in] U Solution vector at recent time step
+    //! \param[in] vol Nodal volume (with contributions from other chares)
+    //! \param[in] voln Nodal volume (with contributions from other chares) at
+    //!   the previous time step
+    //! \return Minimum time step size
+    real dt( const std::array< std::vector< real >, 3 >& coord,
+             const std::vector< std::size_t >& inpoel,
+             tk::real t,
+             tk::real dtn,
+             const tk::Fields& U,
+             const std::vector< tk::real >& vol,
+             const std::vector< tk::real >& voln ) const
+    {
+      Assert( U.nunk() == coord[0].size(), "Number of unknowns in solution "
+              "vector at recent time step incorrect" );
+
+      // energy source propagation time and velocity
+      const auto& icbox = g_inputdeck.get< tag::ic, tag::box >();
+
+      const auto& x = coord[0];
+      const auto& y = coord[1];
+      const auto& z = coord[2];
+
+      // ratio of specific heats
+      auto g = getmatprop< tag::gamma >();
+      // compute the minimum dt across all elements we own
+      real mindt = std::numeric_limits< real >::max();
+      for (std::size_t e=0; e<inpoel.size()/4; ++e) {
+        const std::array< std::size_t, 4 > N{{ inpoel[e*4+0], inpoel[e*4+1],
+                                               inpoel[e*4+2], inpoel[e*4+3] }};
+        // compute cubic root of element volume as the characteristic length
+        const std::array< real, 3 >
+          ba{{ x[N[1]]-x[N[0]], y[N[1]]-y[N[0]], z[N[1]]-z[N[0]] }},
+          ca{{ x[N[2]]-x[N[0]], y[N[2]]-y[N[0]], z[N[2]]-z[N[0]] }},
+          da{{ x[N[3]]-x[N[0]], y[N[3]]-y[N[0]], z[N[3]]-z[N[0]] }};
+        const auto L = std::cbrt( tk::triple( ba, ca, da ) / 6.0 );
+        // access solution at element nodes at recent time step
+        std::array< std::array< real, 4 >, m_ncomp > u;
+        for (ncomp_t c=0; c<m_ncomp; ++c) u[c] = U.extract( c, N );
+        // compute the maximum length of the characteristic velocity (fluid
+        // velocity + sound velocity) across the four element nodes
+        real maxvel = 0.0;
+        for (std::size_t j=0; j<4; ++j) {
+          auto& r  = u[0][j];    // rho
+          auto& ru = u[1][j];    // rho * u
+          auto& rv = u[2][j];    // rho * v
+          auto& rw = u[3][j];    // rho * w
+          auto& re = u[4][j];    // rho * e
+          auto p = m_mat_blk[0].compute< EOS::pressure >( r, ru/r, rv/r, rw/r,
+            re );
+          if (p < 0) p = 0.0;
+          auto c = m_mat_blk[0].compute< EOS::soundspeed >( r, p );
+          auto v = std::sqrt((ru*ru + rv*rv + rw*rw)/r/r) + c; // char. velocity
+
+          // energy source propagation velocity (in all IC boxes configured)
+          if (!icbox.empty()) {
+            for (const auto& b : icbox) {   // for all boxes for this eq
+              const auto& initiate = b.template get< tag::initiate >();
+              auto iv = b.template get< tag::front_speed >();
+              if (initiate == ctr::InitiateType::LINEAR) {
+                auto zmin = b.template get< tag::zmin >();
+                auto zmax = b.template get< tag::zmax >();
+                auto wFront = 0.08;
+                auto tInit = 0.0;
+                auto tFinal = tInit + (zmax - zmin - 2.0*wFront) /
+                  std::fabs(iv);
+                if (t >= tInit && t <= tFinal)
+                  v = std::max(v, std::fabs(iv));
+              }
+            }
+          }
+
+          if (v > maxvel) maxvel = v;
+        }
+        // compute element dt for the Euler equations
+        auto euler_dt = L / maxvel;
+        // compute element dt based on the viscous force
+        auto viscous_dt = m_physics.viscous_dt( L, u );
+        // compute element dt based on thermal diffusion
+        auto conduct_dt = m_physics.conduct_dt( L, g, u );
+        // compute minimum element dt
+        auto elemdt = std::min( euler_dt, std::min( viscous_dt, conduct_dt ) );
+        // find minimum dt across all elements
+        mindt = std::min( elemdt, mindt );
+      }
+      mindt *= g_inputdeck.get< tag::cfl >();
+
+      // compute the minimum dt across all nodes we contribute to due to volume
+      // change in time
+      auto dvcfl = g_inputdeck.get< tag::ale, tag::dvcfl >();
+      if (dtn > 0.0 && dvcfl > 0.0) {
+        Assert( vol.size() == voln.size(), "Size mismatch" );
+        for (std::size_t p=0; p<vol.size(); ++p) {
+          auto vol_dt = dtn *
+            std::min(voln[p],vol[p]) / std::abs(voln[p]-vol[p]+1.0e-14);
+          mindt = std::min( vol_dt, mindt );
+        }
+        mindt *= dvcfl;
+      }
+
+      return mindt;
+    }
+
+    //! Compute a time step size for each mesh node (for steady time stepping)
+    //! \param[in] U Solution vector at recent time step
+    //! \param[in] vol Nodal volume (with contributions from other chares)
+    //! \param[in,out] dtp Time step size for each mesh node
+    void dt( uint64_t,
+             const std::vector< tk::real >& vol,
+             const tk::Fields& U,
+             std::vector< tk::real >& dtp ) const
+    {
+      for (std::size_t i=0; i<U.nunk(); ++i) {
+        // compute cubic root of element volume as the characteristic length
+        const auto L = std::cbrt( vol[i] );
+        // access solution at node p at recent time step
+        const auto u = U[i];
+        // compute pressure
+        auto p = m_mat_blk[0].compute< EOS::pressure >( u[0], u[1]/u[0],
+          u[2]/u[0], u[3]/u[0], u[4] );
+        if (p < 0) p = 0.0;
+        auto c = m_mat_blk[0].compute< EOS::soundspeed >( u[0], p );
+        // characteristic velocity
+        auto v = std::sqrt((u[1]*u[1] + u[2]*u[2] + u[3]*u[3])/u[0]/u[0]) + c;
+        // compute dt for node
+        dtp[i] = L / v * g_inputdeck.get< tag::cfl >();
+      }
+    }
+
+    //! \brief Query Dirichlet boundary condition value on a given side set for
+    //!    all components in this PDE system
+    //! \param[in] t Physical time
+    //! \param[in] deltat Time step size
+    //! \param[in] tp Physical time for each mesh node
+    //! \param[in] dtp Time step size for each mesh node
+    //! \param[in] ss Pair of side set ID and (local) node IDs on the side set
+    //! \param[in] coord Mesh node coordinates
+    //! \param[in] increment If true, evaluate the solution increment between
+    //!   t and t+dt for Dirichlet BCs. If false, evlauate the solution instead.
+    //! \return Vector of pairs of bool and boundary condition value associated
+    //!   to mesh node IDs at which Dirichlet boundary conditions are set. Note
+    //!   that if increment is true, instead of the actual boundary condition
+    //!   value, we return the increment between t+deltat and t, since,
+    //!   depending on client code and solver, that may be what the solution
+    //!   requires.
+    std::map< std::size_t, std::vector< std::pair<bool,real> > >
+    dirbc( real t,
+           real deltat,
+           const std::vector< tk::real >& tp,
+           const std::vector< tk::real >& dtp,
+           const std::pair< const int, std::vector< std::size_t > >& ss,
+           const std::array< std::vector< real >, 3 >& coord,
+           bool increment ) const
+    {
+      using NodeBC = std::vector< std::pair< bool, real > >;
+      std::map< std::size_t, NodeBC > bc;
+
+      // collect sidesets across all meshes
+      std::vector< std::size_t > ubc;
+      for (const auto& ibc : g_inputdeck.get< tag::bc >()) {
+        ubc.insert(ubc.end(), ibc.get< tag::dirichlet >().begin(),
+          ibc.get< tag::dirichlet >().end());
+      }
 
-void
-OversetFE::setTransferFlags(
-  std::size_t dirn )
-// *****************************************************************************
-//  Set flags informing solution transfer decisions
-//! \param[in] dirn 0 if called from B to O, 1 if called from O to B
-// *****************************************************************************
-{
-  // Copy solution and reset flags
-  //TODO: index the flag in a better way
-  std::size_t iflag = m_uc.nprop()-1;
-
-  for (std::size_t i=0; i<m_u.nunk(); ++i) {
-    for (std::size_t c=0; c<m_u.nprop(); ++c) {
-      m_uc(i,c) = m_u(i,c);
-    }
-    // Reset flags
-    m_uc(i,iflag) = 0.0;
-
-    // reset blanking coefficient
-    m_blank[i] = 1.0;
-  }
-
-  // Transfer flags for O to B are based on block-ids that are hardcoded
-  // TODO: remove hardcoding
+      const auto steady = g_inputdeck.get< tag::steady_state >();<--- Variable 'steady' is assigned a value that is never used.
+      if (!ubc.empty()) {
+        Assert( ubc.size() > 0, "Indexing out of Dirichlet BC eq-vector" );
+        const auto& x = coord[0];
+        const auto& y = coord[1];
+        const auto& z = coord[2];
+        for (const auto& b : ubc)
+          if (static_cast<int>(b) == ss.first)
+            for (auto n : ss.second) {
+              Assert( x.size() > n, "Indexing out of coordinate array" );
+              if (steady) { t = tp[n]; deltat = dtp[n]; }
+              auto s = increment ?
+                solinc( m_ncomp, m_mat_blk, x[n], y[n], z[n],
+                        t, deltat, Problem::initialize ) :
+                Problem::initialize( m_ncomp, m_mat_blk, x[n], y[n],
+                                     z[n], t+deltat );
+              if ( stagPoint(x[n],y[n],z[n]) ) {
+                s[1] = s[2] = s[3] = 0.0;
+              }
+              bc[n] = {{ {true,s[0]}, {true,s[1]}, {true,s[2]}, {true,s[3]},
+                         {true,s[4]} }};
+            }
+      }
+      return bc;
+    }
 
-  // Called from transfer-B-to-O
-  if (dirn == 0) {
-    if (Disc()->MeshId() != 0) {
-      // Overset meshes: assign appropriate values to flag
-      for (auto i : m_farfieldbcnodes) m_uc(i,iflag) = 1.0;
-    }
-  }
-  // Called from transfer-O-to-B
-  else {
-    if (Disc()->MeshId() != 0) {
-      // Overset meshes: assign appropriate values to flag
-      for (const auto& [blid, ndset] : m_nodeblockid) {
-        if (blid == 103) {
-          for (auto i : ndset) m_uc(i,iflag) = 1.0;
-        }
-        else if (blid == 104) {
-          for (auto i : ndset) m_uc(i,iflag) = 2.0;
-        }
-      }
-    }
-  }
-}
-
-void
-OversetFE::normfinal()
-// *****************************************************************************
-//  Finish computing dual-face and boundary point normals
-// *****************************************************************************
-{
-  auto d = Disc();
-  const auto& lid = d->Lid();
-
-  // Combine own and communicated contributions to boundary point normals
-  for (const auto& [s,norms] : m_bnormc) {
-    auto& bnorms = m_bnorm[s];
-    for (const auto& [p,n] : norms) {
-      auto& norm = bnorms[p];
-      norm[0] += n[0];
-      norm[1] += n[1];
-      norm[2] += n[2];
-      norm[3] += n[3];
+    //! Set symmetry boundary conditions at nodes
+    //! \param[in] U Solution vector at recent time step
+    //! \param[in] bnorm Face normals in boundary points, key local node id,
+    //!   first 3 reals of value: unit normal, outer key: side set id
+    //! \param[in] nodes Unique set of node ids at which to set symmetry BCs
+    void
+    symbc( tk::Fields& U,
+           const std::array< std::vector< real >, 3 >&,
+           const std::unordered_map< int,
+             std::unordered_map< std::size_t, std::array< real, 4 > > >& bnorm,
+           const std::unordered_set< std::size_t >& nodes ) const
+    {
+      // collect sidesets across all meshes
+      std::vector< std::size_t > sbc;
+      for (const auto& ibc : g_inputdeck.get< tag::bc >()) {
+        sbc.insert(sbc.end(), ibc.get< tag::symmetry >().begin(),
+          ibc.get< tag::symmetry >().end());
+      }
+
+      if (sbc.size() > 0) {             // use symbcs for this system
+        for (auto p : nodes) {                 // for all symbc nodes
+          // for all user-def symbc sets
+          for (std::size_t s=0; s<sbc.size(); ++s) {
+            // find nodes & normals for side
+            auto j = bnorm.find(static_cast<int>(sbc[s]));
+            if (j != end(bnorm)) {
+              auto i = j->second.find(p);      // find normal for node
+              if (i != end(j->second)) {
+                std::array< real, 3 >
+                  n{ i->second[0], i->second[1], i->second[2] },
+                  v{ U(p,1), U(p,2), U(p,3) };
+                auto v_dot_n = tk::dot( v, n );
+                // symbc: remove normal component of velocity
+                U(p,1) -= v_dot_n * n[0];
+                U(p,2) -= v_dot_n * n[1];
+                U(p,3) -= v_dot_n * n[2];
+              }
+            }
+          }
+        }
+      }
     }
-  }
-  tk::destroy( m_bnormc );
-
-  // Divide summed point normals by the sum of inverse distance squared
-  for (auto& [s,norms] : m_bnorm)
-    for (auto& [p,n] : norms) {
-      n[0] /= n[3];
-      n[1] /= n[3];
-      n[2] /= n[3];
-      Assert( (n[0]*n[0] + n[1]*n[1] + n[2]*n[2] - 1.0) <
-              1.0e+3*std::numeric_limits< tk::real >::epsilon(),
-              "Non-unit normal" );
-    }
-
-  // Replace global->local ids associated to boundary point normals
-  decltype(m_bnorm) bnorm;
-  for (auto& [s,norms] : m_bnorm) {
-    auto& bnorms = bnorm[s];
-    for (auto&& [g,n] : norms)
-      bnorms[ tk::cref_find(lid,g) ] = std::move(n);
-  }
-  m_bnorm = std::move(bnorm);
-
-  // Count contributions to chare-boundary edges
-  std::unordered_map< tk::UnsMesh::Edge, std::size_t,
-    tk::UnsMesh::Hash<2>, tk::UnsMesh::Eq<2> > edge_node_count;
-  for (const auto& [c,edges] : d->EdgeCommMap())
-    for (const auto& e : edges)
-      ++edge_node_count[e];
-
-  // Combine and weigh communicated contributions to dual-face normals
-  for (auto& [e,n] : m_dfnormc) {
-    const auto& dfn = tk::cref_find( m_dfnorm, e );
-    n[0] += dfn[0];
-    n[1] += dfn[1];
-    n[2] += dfn[2];
-    auto count = static_cast< tk::real >( tk::cref_find( edge_node_count, e ) );
-    auto factor = 1.0/(count + 1.0);
-    for (auto & x : n) x *= factor;<--- Consider using std::transform algorithm instead of a raw loop.
-  }
-
-  // Generate list of unique edges
-  tk::UnsMesh::EdgeSet uedge;
-  for (std::size_t p=0; p<m_u.nunk(); ++p)
-    for (auto q : tk::Around(m_psup,p))
-      uedge.insert( {p,q} );
-
-  // Flatten edge list
-  m_edgenode.resize( uedge.size() * 2 );
-  std::size_t f = 0;
-  const auto& gid = d->Gid();
-  for (auto&& [p,q] : uedge) {
-    if (gid[p] > gid[q]) {
-      m_edgenode[f+0] = std::move(q);
-      m_edgenode[f+1] = std::move(p);
-    } else {
-      m_edgenode[f+0] = std::move(p);
-      m_edgenode[f+1] = std::move(q);
-    }
-    f += 2;
-  }
-  tk::destroy(uedge);
-
-  // Convert dual-face normals to streamable (and vectorizable) data structure
-  m_dfn.resize( m_edgenode.size() * 3 );      // 2 vectors per access
-  std::unordered_map< tk::UnsMesh::Edge, std::size_t,
-                      tk::UnsMesh::Hash<2>, tk::UnsMesh::Eq<2> > eid;
-  for (std::size_t e=0; e<m_edgenode.size()/2; ++e) {
-    auto p = m_edgenode[e*2+0];
-    auto q = m_edgenode[e*2+1];
-    eid[{p,q}] = e;
-    std::array< std::size_t, 2 > g{ gid[p], gid[q] };
-    auto n = tk::cref_find( m_dfnorm, g );
-    // figure out if this is an edge on the parallel boundary
-    auto nit = m_dfnormc.find( g );
-    auto m = ( nit != m_dfnormc.end() ) ? nit->second : n;
-    m_dfn[e*6+0] = n[0];
-    m_dfn[e*6+1] = n[1];
-    m_dfn[e*6+2] = n[2];
-    m_dfn[e*6+3] = m[0];
-    m_dfn[e*6+4] = m[1];
-    m_dfn[e*6+5] = m[2];
-  }
-
-  tk::destroy( m_dfnorm );
-  tk::destroy( m_dfnormc );
-
-  // Flatten edge id data structure
-  m_edgeid.resize( m_psup.first.size() );
-  for (std::size_t p=0,k=0; p<m_u.nunk(); ++p)
-    for (auto q : tk::Around(m_psup,p))
-      m_edgeid[k++] = tk::cref_find( eid, {p,q} );
-}
-
-void
-OversetFE::BC()
-// *****************************************************************************
-// Apply boundary conditions
-// \details The following BC enforcement changes the initial condition or
-//!   updated solution (dependending on when it is called) to ensure strong
-//!   imposition of the BCs. This is a matter of choice. Another alternative is
-//!   to only apply BCs when computing fluxes at boundary faces, thereby only
-//!   weakly enforcing the BCs. The former is conventionally used in continunous
-//!   Galerkin finite element methods (such as OversetFE implements), whereas the
-//!   latter, in finite volume methods.
-// *****************************************************************************
-{
-  auto d = Disc();
-  const auto& coord = d->Coord();
-
-  const auto& bcmesh = g_inputdeck.get< tag::bc >();
+
+    //! Set farfield boundary conditions at nodes
+    //! \param[in] U Solution vector at recent time step
+    //! \param[in] bnorm Face normals in boundary points, key local node id,
+    //!   first 3 reals of value: unit normal, outer key: side set id
+    //! \param[in] nodes Unique set of node ids at which to set farfield BCs
+    void
+    farfieldbc(
+      tk::Fields& U,
+      const std::array< std::vector< real >, 3 >&,
+      const std::unordered_map< int,
+        std::unordered_map< std::size_t, std::array< real, 4 > > >& bnorm,
+      const std::unordered_set< std::size_t >& nodes ) const
+    {
+      // collect sidesets across all meshes
+      std::vector< std::size_t > fbc;
+      for (const auto& ibc : g_inputdeck.get< tag::bc >()) {
+        fbc.insert(fbc.end(), ibc.get< tag::farfield >().begin(),
+          ibc.get< tag::farfield >().end());
+      }
+
+      if (fbc.size() > 0)               // use farbcs for this system
+        for (auto p : nodes)                   // for all farfieldbc nodes
+          for (const auto& s : fbc) {// for all user-def farbc sets
+            auto j = bnorm.find(static_cast<int>(s));// find nodes & normals for side
+            if (j != end(bnorm)) {
+              auto i = j->second.find(p);      // find normal for node
+              if (i != end(j->second)) {
+                auto& r  = U(p,0);
+                auto& ru = U(p,1);
+                auto& rv = U(p,2);
+                auto& rw = U(p,3);
+                auto& re = U(p,4);
+                auto vn =
+                  (ru*i->second[0] + rv*i->second[1] + rw*i->second[2]) / r;
+                auto a = m_mat_blk[0].compute< EOS::soundspeed >( r,
+                  m_mat_blk[0].compute< EOS::pressure >( r, ru/r, rv/r, rw/r,
+                  re ) );
+                auto M = vn / a;
+                if (M <= -1.0) {                      // supersonic inflow
+                  r  = m_fr;
+                  ru = m_fr * m_fu[0];
+                  rv = m_fr * m_fu[1];
+                  rw = m_fr * m_fu[2];
+                  re = m_mat_blk[0].compute< EOS::totalenergy >( m_fr,
+                    m_fu[0], m_fu[1], m_fu[2], m_fp );
+                } else if (M > -1.0 && M < 0.0) {     // subsonic inflow
+                  auto pr = m_mat_blk[0].compute< EOS::pressure >
+                                                ( r, ru/r, rv/r, rw/r, re );
+                  r  = m_fr;
+                  ru = m_fr * m_fu[0];
+                  rv = m_fr * m_fu[1];
+                  rw = m_fr * m_fu[2];
+                  re = m_mat_blk[0].compute< EOS::totalenergy >( m_fr,
+                    m_fu[0], m_fu[1], m_fu[2], pr );
+                } else if (M >= 0.0 && M < 1.0) {     // subsonic outflow
+                  re = m_mat_blk[0].compute< EOS::totalenergy >( r, ru/r,
+                    rv/r, rw/r, m_fp );
+                }
+              }
+            }
+          }
+    }
+
+    //! Apply user defined time dependent BCs
+    //! \param[in] t Physical time
+    //! \param[in,out] U Solution vector at recent time step
+    //! \param[in] nodes Vector of unique sets of node ids at which to apply BCs
+    //! \details This function applies user defined time dependent boundary
+    //!   conditions on groups of side sets specified in the input file.
+    //!   The user specifies pressure, density, and velocity as discrete
+    //!   functions of time, in the control file, associated with a group of
+    //!   side sets. Several such groups can be specified, each with their
+    //!   own discrete function: p(t), rho(t), vx(t), vy(t), vz(t).
+    void
+    timedepbc( tk::real t,
+      tk::Fields& U,<--- Parameter 'U' can be declared with const
+      const std::vector< std::unordered_set< std::size_t > >& nodes,
+      const std::vector< tk::Table<5> >& timedepfn ) const
+    {
+      for (std::size_t ib=0; ib<nodes.size(); ++ib) {
+        for (auto p:nodes[ib]) {
+          // sample primitive vars from discrete data at time t
+          auto unk = tk::sample<5>(t, timedepfn[ib]);
+
+          // apply BCs after converting to conserved vars
+          U(p,0) = unk[1];
+          U(p,1) = unk[1]*unk[2];
+          U(p,2) = unk[1]*unk[3];
+          U(p,3) = unk[1]*unk[4];
+          U(p,4) = m_mat_blk[0].compute< EOS::totalenergy >( unk[1], unk[2],
+            unk[3], unk[4], unk[0]);
+        }
+      }
+    }
+
+    //! Return a map that associates user-specified strings to functions
+    //! \return Map that associates user-specified strings to functions that
+    //!   compute relevant quantities to be output to file
+    std::map< std::string, tk::GetVarFn > OutVarFn() const
+    { return CompFlowOutVarFn(); }
+
+    //! Return analytic field names to be output to file
+    //! \return Vector of strings labelling analytic fields output in file
+    std::vector< std::string > analyticFieldNames() const
+    { return m_problem.analyticFieldNames( m_ncomp ); }
+
+    //! Return surface field names to be output to file
+    //! \return Vector of strings labelling surface fields output in file
+    std::vector< std::string > surfNames() const
+    { return CompFlowSurfNames(); }
 
-  for (const auto& bci : bcmesh) {
-    const auto& bcm = bci.get< tag::mesh >();
-    for (const auto& im : bcm) {
-      // only if this bc is meant for current mesh
-      if (im-1 == d->MeshId()) {
-
-        // Query and match user-specified Dirichlet boundary conditions to side sets
-        const auto steady = g_inputdeck.get< tag::steady_state >();
-        if (steady) for (auto& deltat : m_dtp) deltat *= rkcoef[m_stage];<--- Consider using std::transform algorithm instead of a raw loop.
-        m_dirbc = match( d->MeshId(), m_u.nprop(), d->T(), rkcoef[m_stage] * d->Dt(),
-                         m_tp, m_dtp, d->Coord(), d->Lid(), m_bnode,
-                       /* increment = */ false );
-        if (steady) for (auto& deltat : m_dtp) deltat /= rkcoef[m_stage];<--- Consider using std::transform algorithm instead of a raw loop.
-
-        // Apply Dirichlet BCs
-        for (const auto& [b,bc] : m_dirbc)
-          for (ncomp_t c=0; c<m_u.nprop(); ++c)
-            if (bc[c].first) m_u(b,c) = bc[c].second;
-
-        // Apply symmetry BCs
-        g_cgpde[d->MeshId()].symbc( m_u, coord, m_bnorm, m_symbcnodes );
-
-        // Apply farfield BCs
-        if (bci.get< tag::farfield >().empty() || (d->MeshId() == 0)) {
-          g_cgpde[d->MeshId()].farfieldbc( m_u, coord, m_bnorm, m_farfieldbcnodes );
-        }
+    //! Return time history field names to be output to file
+    //! \return Vector of strings labelling time history fields output in file
+    std::vector< std::string > histNames() const
+    { return CompFlowHistNames(); }
+
+    //! Return nodal surface field output going to file
+    std::vector< std::vector< real > >
+    surfOutput( const std::map< int, std::vector< std::size_t > >& bnd,
+                const tk::Fields& U ) const
+    { return CompFlowSurfOutput( m_mat_blk, bnd, U ); }
+
+    //! Return elemental surface field output (on triangle faces) going to file
+    std::vector< std::vector< real > >
+    elemSurfOutput( const std::map< int, std::vector< std::size_t > >& bface,
+      const std::vector< std::size_t >& triinpoel,
+      const tk::Fields& U ) const
+    {
+      return CompFlowElemSurfOutput( m_mat_blk, bface, triinpoel, U );
+    }
+
+    //! Return time history field output evaluated at time history points
+    std::vector< std::vector< real > >
+    histOutput( const std::vector< HistData >& h,
+                const std::vector< std::size_t >& inpoel,
+                const tk::Fields& U ) const
+    { return CompFlowHistOutput( m_mat_blk, h, inpoel, U ); }
 
-        // Apply user defined time dependent BCs
-        g_cgpde[d->MeshId()].timedepbc( d->T(), m_u, m_timedepbcnodes,
-          m_timedepbcFn );
-      }
-    }
-  }
-}
-
-void
-OversetFE::next()
-// *****************************************************************************
-// Continue to next time step
-// *****************************************************************************
-{
-  dt();
-}
-
-void
-OversetFE::dt()
-// *****************************************************************************
-// Compute time step size
-// *****************************************************************************
-{
-  tk::real mindt = std::numeric_limits< tk::real >::max();
-
-  auto const_dt = g_inputdeck.get< tag::dt >();
-  auto eps = std::numeric_limits< tk::real >::epsilon();
-
-  auto d = Disc();
-
-  // use constant dt if configured
-  if (std::abs(const_dt) > eps) {
+    //! Return names of integral variables to be output to diagnostics file
+    //! \return Vector of strings labelling integral variables output
+    std::vector< std::string > names() const
+    { return m_problem.names( m_ncomp ); }
+
+  private:
+    const Physics m_physics;            //!< Physics policy
+    const Problem m_problem;            //!< Problem policy
+    //! Stagnation BC user configuration: point coordinates and radii
+    std::tuple< std::vector< real >, std::vector< real > > m_stagCnf;
+    real m_fr;                    //!< Farfield density
+    real m_fp;                    //!< Farfield pressure
+    std::vector< real > m_fu;     //!< Farfield velocity
+    //! EOS material block
+    std::vector< EOS > m_mat_blk;
+
+    //! Decide if point is a stagnation point
+    //! \param[in] x X mesh point coordinates to query
+    //! \param[in] y Y mesh point coordinates to query
+    //! \param[in] z Z mesh point coordinates to query
+    //! \return True if point is configured as a stagnation point by the user
+    #pragma omp declare simd
+    bool
+    stagPoint( real x, real y, real z ) const {
+      const auto& pnt = std::get< 0 >( m_stagCnf );
+      const auto& rad = std::get< 1 >( m_stagCnf );
+      for (std::size_t i=0; i<pnt.size()/3; ++i) {
+        if (tk::length( x-pnt[i*3+0], y-pnt[i*3+1], z-pnt[i*3+2] ) < rad[i])
+          return true;
+      }
+      return false;
+    }
 
-    mindt = const_dt;
-
-  } else {      // compute dt based on CFL
-
-    //! [Find the minimum dt across all PDEs integrated]
-    if (g_inputdeck.get< tag::steady_state >()) {
-
-      // compute new dt for each mesh point
-      g_cgpde[d->MeshId()].dt( d->It(), d->Vol(), m_u, m_dtp );
-
-      // find the smallest dt of all nodes on this chare
-      mindt = *std::min_element( begin(m_dtp), end(m_dtp) );
-
-    } else {    // compute new dt for this chare
-
-      // find the smallest dt of all equations on this chare
-      auto eqdt = g_cgpde[d->MeshId()].dt( d->Coord(), d->Inpoel(), d->T(),
-        d->Dtn(), m_u, d->Vol(), d->Voln() );
-      if (eqdt < mindt) mindt = eqdt;
-
-    }
-    //! [Find the minimum dt across all PDEs integrated]
-
-  }
-
-  // Determine if this chunk of mesh needs to be moved
-  g_cgpde[d->MeshId()].getMeshVel(d->T(), d->Coord(), m_psup, m_symbcnodes,
-    m_uservel, m_u, d->MeshVel(), m_movedmesh);
-
-  //! [Advance]
-  // Actiavate SDAG waits for next time step stage
-  thisProxy[ thisIndex ].wait4grad();
-  thisProxy[ thisIndex ].wait4rhs();
-
-  // TODO: this is a hacky way to know if any chunk moved. redesign it
-  std::vector < tk::real > reducndata(d->Transfers().size()+2, 0.0);
-
-  reducndata[0] = mindt;
-  reducndata[d->MeshId()+1] = static_cast< tk::real >(-m_movedmesh);
-
-  // Contribute to minimum dt across all chares and advance to next step
-  if (g_inputdeck.get< tag::steady_state >()) {
-    contribute( reducndata, CkReduction::min_double,
-                CkCallback(CkReductionTarget(OversetFE,advance), thisProxy) );
-  }
-  else {
-    // if solving a time-accurate problem, find minimum dt across all meshes
-    // and eventually broadcast to OversetFE::advance()
-    contribute( reducndata, CkReduction::min_double,
-      CkCallback(CkReductionTarget(Transporter,minDtAcrossMeshes), d->Tr()) );
-  }
-  //! [Advance]
-}
-
-void
-OversetFE::advance( tk::real newdt, tk::real nmovedmesh )
-// *****************************************************************************
-// Advance equations to next time step
-//! \param[in] newdt The smallest dt across the whole problem
-//! \param[in] nmovedmesh (negative of) if any chunk of this mesh moved
-// *****************************************************************************
-{
-  auto d = Disc();
-
-  // Set new time step size
-  if (m_stage == 0) d->setdt( newdt );
-
-  // TODO: this is a hacky way to know if any chunk moved. redesign it
-  if (nmovedmesh < -0.1) m_movedmesh = 1;
-
-  // Compute gradients for next time step
-  chBndGrad();
-}
-
-void
-OversetFE::chBndGrad()
-// *****************************************************************************
-// Compute nodal gradients at chare-boundary nodes. Gradients at internal nodes
-// are calculated locally as needed and are not stored.
-// *****************************************************************************
-{
-  auto d = Disc();
-
-  // Compute own portion of gradients for all equations
-  g_cgpde[d->MeshId()].chBndGrad( d->Coord(), d->Inpoel(), m_bndel, d->Gid(),
-    d->Bid(), m_u, m_chBndGrad );
-
-  // Communicate gradients to other chares on chare-boundary
-  if (d->NodeCommMap().empty())        // in serial we are done
-    comgrad_complete();
-  else // send gradients contributions to chare-boundary nodes to fellow chares
-    for (const auto& [c,n] : d->NodeCommMap()) {
-      std::vector< std::vector< tk::real > > g( n.size() );
-      std::size_t j = 0;
-      for (auto i : n) g[ j++ ] = m_chBndGrad[ tk::cref_find(d->Bid(),i) ];
-      thisProxy[c].comChBndGrad( std::vector<std::size_t>(begin(n),end(n)), g );
-    }
-
-  owngrad_complete();
-}
-
-void
-OversetFE::comChBndGrad( const std::vector< std::size_t >& gid,
-                     const std::vector< std::vector< tk::real > >& G )
-// *****************************************************************************
-//  Receive contributions to nodal gradients on chare-boundaries
-//! \param[in] gid Global mesh node IDs at which we receive grad contributions
-//! \param[in] G Partial contributions of gradients to chare-boundary nodes
-//! \details This function receives contributions to m_chBndGrad, which stores
-//!   nodal gradients at mesh chare-boundary nodes. While m_chBndGrad stores
-//!   own contributions, m_chBndGradc collects the neighbor chare
-//!   contributions during communication. This way work on m_chBndGrad and
-//!   m_chBndGradc is overlapped. The two are combined in rhs().
-// *****************************************************************************
-{
-  Assert( G.size() == gid.size(), "Size mismatch" );
-
-  using tk::operator+=;
-
-  for (std::size_t i=0; i<gid.size(); ++i) m_chBndGradc[ gid[i] ] += G[i];
-
-  if (++m_ngrad == Disc()->NodeCommMap().size()) {
-    m_ngrad = 0;
-    comgrad_complete();
-  }
-}
-
-void
-OversetFE::rhs()
-// *****************************************************************************
-// Compute right-hand side of transport equations
-// *****************************************************************************
-{
-  auto d = Disc();
-
-  // Combine own and communicated contributions to nodal gradients
-  for (const auto& [gid,g] : m_chBndGradc) {
-    auto bid = tk::cref_find( d->Bid(), gid );
-    for (ncomp_t c=0; c<m_chBndGrad.nprop(); ++c)
-      m_chBndGrad(bid,c) += g[c];
-  }
-
-  // clear gradients receive buffer
-  tk::destroy(m_chBndGradc);
-
-  const auto steady = g_inputdeck.get< tag::steady_state >();
-
-  // Assign mesh velocity
-  if (m_movedmesh) {
-    const auto& coord = d->Coord();
-    auto& mvel = d->MeshVel();
-    for (std::size_t p=0; p<coord[0].size(); ++p) {
-      for (std::size_t i=0; i<3; ++i)
-        mvel(p, i) = m_uservel[i];
-    }
-  }
+    //! \brief Compute/assemble nodal gradients of primitive variables for
+    //!   ALECG in all points
+    //! \param[in] coord Mesh node coordinates
+    //! \param[in] inpoel Mesh element connectivity
+    //! \param[in] lid Global->local node ids
+    //! \param[in] bid Local chare-boundary node ids (value) associated to
+    //!    global node ids (key)
+    //! \param[in] vol Nodal volumes
+    //! \param[in] esup Elements surrounding points
+    //! \param[in] U Solution vector at recent time step
+    //! \param[in] G Nodal gradients of primitive variables in chare-boundary
+    //!    nodes
+    //! \return Gradients of primitive variables in all mesh points
+    tk::Fields
+    nodegrad( const std::array< std::vector< real >, 3 >& coord,
+              const std::vector< std::size_t >& inpoel,
+              const std::unordered_map< std::size_t, std::size_t >& lid,
+              const std::unordered_map< std::size_t, std::size_t >& bid,
+              const std::vector< real >& vol,
+              const std::pair< std::vector< std::size_t >,
+                               std::vector< std::size_t > >& esup,
+              const tk::Fields& U,
+              const tk::Fields& G ) const
+    {
+      // allocate storage for nodal gradients of primitive variables
+      tk::Fields Grad( U.nunk(), m_ncomp*3 );
+      Grad.fill( 0.0 );
+
+      // access node cooordinates
+      const auto& x = coord[0];
+      const auto& y = coord[1];
+      const auto& z = coord[2];
+
+      // compute gradients of primitive variables in points
+      auto npoin = U.nunk();
+      #pragma omp simd
+      for (std::size_t p=0; p<npoin; ++p)
+        for (auto e : tk::Around(esup,p)) {
+          // access node IDs
+          std::size_t N[4] =
+            { inpoel[e*4+0], inpoel[e*4+1], inpoel[e*4+2], inpoel[e*4+3] };
+          // compute element Jacobi determinant, J = 6V
+          real bax = x[N[1]]-x[N[0]];
+          real bay = y[N[1]]-y[N[0]];
+          real baz = z[N[1]]-z[N[0]];
+          real cax = x[N[2]]-x[N[0]];
+          real cay = y[N[2]]-y[N[0]];
+          real caz = z[N[2]]-z[N[0]];
+          real dax = x[N[3]]-x[N[0]];
+          real day = y[N[3]]-y[N[0]];
+          real daz = z[N[3]]-z[N[0]];
+          auto J = tk::triple( bax, bay, baz, cax, cay, caz, dax, day, daz );
+          auto J24 = J/24.0;
+          // shape function derivatives, nnode*ndim [4][3]
+          real g[4][3];
+          tk::crossdiv( cax, cay, caz, dax, day, daz, J,
+                        g[1][0], g[1][1], g[1][2] );
+          tk::crossdiv( dax, day, daz, bax, bay, baz, J,
+                        g[2][0], g[2][1], g[2][2] );
+          tk::crossdiv( bax, bay, baz, cax, cay, caz, J,
+                        g[3][0], g[3][1], g[3][2] );
+          for (std::size_t i=0; i<3; ++i)
+            g[0][i] = -g[1][i] - g[2][i] - g[3][i];
+          // scatter-add gradient contributions to boundary nodes
+          real u[m_ncomp];
+          for (std::size_t b=0; b<4; ++b) {
+            u[0] = U(N[b],0);
+            u[1] = U(N[b],1)/u[0];
+            u[2] = U(N[b],2)/u[0];
+            u[3] = U(N[b],3)/u[0];
+            u[4] = U(N[b],4)/u[0]
+                   - 0.5*(u[1]*u[1] + u[2]*u[2] + u[3]*u[3]);
+            if ( stagPoint(x[N[b]],y[N[b]],z[N[b]]) )
+            {
+              u[1] = u[2] = u[3] = 0.0;
+            }
+            for (std::size_t c=0; c<m_ncomp; ++c)
+              for (std::size_t i=0; i<3; ++i)
+                Grad(p,c*3+i) += J24 * g[b][i] * u[c];
+          }
+        }
+
+      // put in nodal gradients of chare-boundary points
+      for (const auto& [g,b] : bid) {
+        auto i = tk::cref_find( lid, g );
+        for (ncomp_t c=0; c<Grad.nprop(); ++c)
+          Grad(i,c) = G(b,c);
+      }
+
+      // divide weak result in gradients by nodal volume
+      for (std::size_t p=0; p<npoin; ++p)
+        for (std::size_t c=0; c<m_ncomp*3; ++c)
+          Grad(p,c) /= vol[p];
+
+      return Grad;
+    }
+
+    //! Compute domain-edge integral for ALECG
+    //! \param[in] coord Mesh node coordinates
+    //! \param[in] gid Local->glocal node ids
+    //! \param[in] edgenode Local node ids of edges
+    //! \param[in] edgeid Local node id pair -> edge id map
+    //! \param[in] psup Points surrounding points
+    //! \param[in] dfn Dual-face normals
+    //! \param[in] U Solution vector at recent time step
+    //! \param[in] W Mesh velocity
+    //! \param[in] G Nodal gradients
+    //! \param[in,out] R Right-hand side vector computed
+    void domainint( const std::array< std::vector< real >, 3 >& coord,
+                    const std::vector< std::size_t >& gid,
+                    const std::vector< std::size_t >& edgenode,
+                    const std::vector< std::size_t >& edgeid,
+                    const std::pair< std::vector< std::size_t >,
+                                     std::vector< std::size_t > >& psup,
+                    const std::vector< real >& dfn,
+                    const tk::Fields& U,
+                    const tk::Fields& W,
+                    const tk::Fields& G,
+                    tk::Fields& R ) const
+    {
+      // domain-edge integral: compute fluxes in edges
+      std::vector< real > dflux( edgenode.size()/2 * m_ncomp );
+
+      // access node coordinates
+      const auto& x = coord[0];
+      const auto& y = coord[1];
+      const auto& z = coord[2];
+
+      #pragma omp simd
+      for (std::size_t e=0; e<edgenode.size()/2; ++e) {
+        auto p = edgenode[e*2+0];
+        auto q = edgenode[e*2+1];
+
+        // compute primitive variables at edge-end points
+        real rL  = U(p,0);
+        real ruL = U(p,1) / rL;
+        real rvL = U(p,2) / rL;
+        real rwL = U(p,3) / rL;
+        real reL = U(p,4) / rL - 0.5*(ruL*ruL + rvL*rvL + rwL*rwL);
+        real w1L = W(p,0);
+        real w2L = W(p,1);
+        real w3L = W(p,2);
+        real rR  = U(q,0);
+        real ruR = U(q,1) / rR;
+        real rvR = U(q,2) / rR;
+        real rwR = U(q,3) / rR;
+        real reR = U(q,4) / rR - 0.5*(ruR*ruR + rvR*rvR + rwR*rwR);
+        real w1R = W(q,0);
+        real w2R = W(q,1);
+        real w3R = W(q,2);
+
+        // apply stagnation BCs to primitive variables
+        if ( stagPoint(x[p],y[p],z[p]) )
+          ruL = rvL = rwL = 0.0;
+        if ( stagPoint(x[q],y[q],z[q]) )
+          ruR = rvR = rwR = 0.0;
 
-  // Compute own portion of right-hand side for all equations
-  auto prev_rkcoef = m_stage == 0 ? 0.0 : rkcoef[m_stage-1];
-  if (steady)
-    for (std::size_t p=0; p<m_tp.size(); ++p) m_tp[p] += prev_rkcoef * m_dtp[p];
-  g_cgpde[d->MeshId()].rhs( d->T() + prev_rkcoef * d->Dt(), d->Coord(), d->Inpoel(),
-          m_triinpoel, d->Gid(), d->Bid(), d->Lid(), m_dfn, m_psup, m_esup,
-          m_symbctri, d->Vol(), m_edgenode, m_edgeid,
-          m_boxnodes, m_chBndGrad, m_u, d->MeshVel(), m_tp, d->Boxvol(),
-          m_rhs );
-  if (steady)
-    for (std::size_t p=0; p<m_tp.size(); ++p) m_tp[p] -= prev_rkcoef * m_dtp[p];
-
-  // Communicate rhs to other chares on chare-boundary
-  if (d->NodeCommMap().empty())        // in serial we are done
-    comrhs_complete();
-  else // send contributions of rhs to chare-boundary nodes to fellow chares
-    for (const auto& [c,n] : d->NodeCommMap()) {
-      std::vector< std::vector< tk::real > > r( n.size() );
-      std::size_t j = 0;
-      for (auto i : n) r[ j++ ] = m_rhs[ tk::cref_find(d->Lid(),i) ];
-      thisProxy[c].comrhs( std::vector<std::size_t>(begin(n),end(n)), r );
-    }
-
-  ownrhs_complete();
-}
-
-void
-OversetFE::comrhs( const std::vector< std::size_t >& gid,
-               const std::vector< std::vector< tk::real > >& R )
-// *****************************************************************************
-//  Receive contributions to right-hand side vector on chare-boundaries
-//! \param[in] gid Global mesh node IDs at which we receive RHS contributions
-//! \param[in] R Partial contributions of RHS to chare-boundary nodes
-//! \details This function receives contributions to m_rhs, which stores the
-//!   right hand side vector at mesh nodes. While m_rhs stores own
-//!   contributions, m_rhsc collects the neighbor chare contributions during
-//!   communication. This way work on m_rhs and m_rhsc is overlapped. The two
-//!   are combined in solve().
-// *****************************************************************************
-{
-  Assert( R.size() == gid.size(), "Size mismatch" );
-
-  using tk::operator+=;
-
-  for (std::size_t i=0; i<gid.size(); ++i) m_rhsc[ gid[i] ] += R[i];
-
-  // When we have heard from all chares we communicate with, this chare is done
-  if (++m_nrhs == Disc()->NodeCommMap().size()) {
-    m_nrhs = 0;
-    comrhs_complete();
-  }
-}
+        // compute MUSCL reconstruction in edge-end points
+        muscl( p, q, coord, G,
+               rL, ruL, rvL, rwL, reL, rR, ruR, rvR, rwR, reR );
+
+        // convert back to conserved variables
+        reL = (reL + 0.5*(ruL*ruL + rvL*rvL + rwL*rwL)) * rL;
+        ruL *= rL;
+        rvL *= rL;
+        rwL *= rL;
+        reR = (reR + 0.5*(ruR*ruR + rvR*rvR + rwR*rwR)) * rR;
+        ruR *= rR;
+        rvR *= rR;
+        rwR *= rR;
+
+        // evaluate pressure at edge-end points
+        real pL = m_mat_blk[0].compute< EOS::pressure >( rL, ruL/rL, rvL/rL,
+          rwL/rL, reL );
+        real pR = m_mat_blk[0].compute< EOS::pressure >( rR, ruR/rR, rvR/rR,
+          rwR/rR, reR );
+
+        // compute Riemann flux using edge-end point states
+        real f[m_ncomp];
+        Rusanov::flux( m_mat_blk,
+                       dfn[e*6+0], dfn[e*6+1], dfn[e*6+2],
+                       dfn[e*6+3], dfn[e*6+4], dfn[e*6+5],
+                       rL, ruL, rvL, rwL, reL,
+                       rR, ruR, rvR, rwR, reR,
+                       w1L, w2L, w3L, w1R, w2R, w3R,
+                       pL, pR,
+                       f[0], f[1], f[2], f[3], f[4] );
+        // store flux in edges
+        for (std::size_t c=0; c<m_ncomp; ++c) dflux[e*m_ncomp+c] = f[c];
+      }
+
+      // access pointer to right hand side at component
+      std::array< const real*, m_ncomp > r;
+      for (ncomp_t c=0; c<m_ncomp; ++c) r[c] = R.cptr( c );
+
+      // domain-edge integral: sum flux contributions to points
+      for (std::size_t p=0,k=0; p<U.nunk(); ++p)
+        for (auto q : tk::Around(psup,p)) {
+          auto s = gid[p] > gid[q] ? -1.0 : 1.0;
+          auto e = edgeid[k++];
+          // the 2.0 in the following expression is so that the RHS contribution
+          // conforms with Eq 12 (Waltz et al. Computers & fluids (92) 2014);
+          // The 1/2 in Eq 12 is extracted from the flux function (Rusanov).
+          // However, Rusanov::flux computes the flux with the 1/2. This 2
+          // cancels with the 1/2 in Rusanov::flux, so that the 1/2 can be
+          // extracted out and multiplied as in Eq 12
+          for (std::size_t c=0; c<m_ncomp; ++c)
+            R.var(r[c],p) -= 2.0*s*dflux[e*m_ncomp+c];
+        }
 
-void
-OversetFE::solve()
-// *****************************************************************************
-//  Advance systems of equations
-// *****************************************************************************
-{
-  auto d = Disc();
-
-  // Combine own and communicated contributions to rhs
-  for (const auto& b : m_rhsc) {
-    auto lid = tk::cref_find( d->Lid(), b.first );
-    for (ncomp_t c=0; c<m_rhs.nprop(); ++c) m_rhs(lid,c) += b.second[c];
-  }
-
-  // clear receive buffer
-  tk::destroy(m_rhsc);
-
-  // Update state at time n
-  if (m_stage == 0) {
-    m_un = m_u;
-  }
-
-  // Explicit time-stepping using RK3
-  const auto steady = g_inputdeck.get< tag::steady_state >();
-  for (std::size_t i=0; i<m_u.nunk(); ++i) {
-    // time-step
-    auto dtp = d->Dt();
-    if (steady) dtp = m_dtp[i];
-
-    for (ncomp_t c=0; c<m_u.nprop(); ++c)
-      m_u(i,c) = m_un(i,c) + m_blank[i] * rkcoef[m_stage] * dtp * m_rhs(i,c)
-        / d->Vol()[i];
-  }
+      tk::destroy(dflux);
+    }
+
+    //! \brief Compute MUSCL reconstruction in edge-end points using a MUSCL
+    //!    procedure with van Leer limiting
+    //! \param[in] p Left node id of edge-end
+    //! \param[in] q Right node id of edge-end
+    //! \param[in] coord Array of nodal coordinates
+    //! \param[in] G Gradient of all unknowns in mesh points
+    //! \param[in,out] rL Left density
+    //! \param[in,out] uL Left X velocity
+    //! \param[in,out] vL Left Y velocity
+    //! \param[in,out] wL Left Z velocity
+    //! \param[in,out] eL Left internal energy
+    //! \param[in,out] rR Right density
+    //! \param[in,out] uR Right X velocity
+    //! \param[in,out] vR Right Y velocity
+    //! \param[in,out] wR Right Z velocity
+    //! \param[in,out] eR Right internal energy
+    void muscl( std::size_t p,
+                std::size_t q,
+                const tk::UnsMesh::Coords& coord,
+                const tk::Fields& G,
+                real& rL, real& uL, real& vL, real& wL, real& eL,
+                real& rR, real& uR, real& vR, real& wR, real& eR ) const
+    {
+      // access node coordinates
+      const auto& x = coord[0];
+      const auto& y = coord[1];
+      const auto& z = coord[2];
+
+      // edge vector
+      std::array< real, 3 > vw{ x[q]-x[p], y[q]-y[p], z[q]-z[p] };
 
-  // Move overset mesh
-  if (m_movedmesh) {
-    auto& x = d->Coord()[0];
-    auto& y = d->Coord()[1];
-    auto& z = d->Coord()[2];
-    const auto& w = d->MeshVel();
-    for (std::size_t i=0; i<w.nunk(); ++i) {
-      // time-step
-      auto dtp = d->Dt();
-      if (steady) dtp = m_dtp[i];
-
-      x[i] += rkcoef[m_stage] * dtp * w(i,0);
-      y[i] += rkcoef[m_stage] * dtp * w(i,1);
-      z[i] += rkcoef[m_stage] * dtp * w(i,2);
-    }
-  }
-  // the following line will be needed for situations where the mesh stops
-  // moving after its initial motion
-  // else m_movedmesh = 0;
-
-  // Apply boundary-conditions
-  BC();
-
-  // Increment Runge-Kutta stage counter
-  ++m_stage;
+      real delta1[5], delta2[5], delta3[5];
+      std::array< real, 5 > ls{ rL, uL, vL, wL, eL };
+      std::array< real, 5 > rs{ rR, uR, vR, wR, eR };
+      auto url = ls;
+      auto urr = rs;
+
+      // MUSCL reconstruction of edge-end-point primitive variables
+      for (std::size_t c=0; c<5; ++c) {
+        // gradients
+        std::array< real, 3 > g1{ G(p,c*3+0), G(p,c*3+1), G(p,c*3+2) },
+                              g2{ G(q,c*3+0), G(q,c*3+1), G(q,c*3+2) };
+
+        delta2[c] = rs[c] - ls[c];
+        delta1[c] = 2.0 * tk::dot(g1,vw) - delta2[c];
+        delta3[c] = 2.0 * tk::dot(g2,vw) - delta2[c];
+
+        // MUSCL extrapolation option 1:
+        // ---------------------------------------------------------------------
+        // Uncomment the following 3 blocks of code if this version is required.
+        // this reconstruction is from the following paper:
+        // Waltz, J., Morgan, N. R., Canfield, T. R., Charest, M. R.,
+        // Risinger, L. D., & Wohlbier, J. G. (2014). A three-dimensional
+        // finite element arbitrary Lagrangian–Eulerian method for shock
+        // hydrodynamics on unstructured grids. Computers & Fluids, 92,
+        // 172-187.
 
-  // Activate SDAG wait for next time step stage
-  thisProxy[ thisIndex ].wait4grad();
-  thisProxy[ thisIndex ].wait4rhs();
-
-  // Compute diagnostics, and finish-up time step (if m_stage == 3)
-  bool diag_computed(false);
-  if (m_stage == 3) {
-    // Compute diagnostics, e.g., residuals
-    diag_computed = m_diag.compute( *d, m_u, m_un, m_bnorm,
-                                    m_symbcnodes, m_farfieldbcnodes );
-    // Increase number of iterations and physical time
-    d->next();
-    // Advance physical time for local time stepping
-    if (g_inputdeck.get< tag::steady_state >())
-      for (std::size_t i=0; i<m_u.nunk(); ++i) m_tp[i] += m_dtp[i];
-  }
-  // Continue to finish-up time-step-stage
-  // Note: refine is called via a bcast if diag_computed == true
-  if (!diag_computed) refine( std::vector< tk::real >( m_u.nprop(), 1.0 ) );
-}
-
-//! [Refine]
-void
-OversetFE::refine( const std::vector< tk::real >& l2res )
-// *****************************************************************************
-// Finish up end of time-step procedures and continue to moving mesh
-//! \param[in] l2res L2-norms of the residual for each scalar component
-//!   computed across the whole problem
-// *****************************************************************************
-{
-  auto d = Disc();
-
-  if (m_stage == 3) {
-    const auto steady = g_inputdeck.get< tag::steady_state >();
-    const auto residual = g_inputdeck.get< tag::residual >();
-    const auto rc = g_inputdeck.get< tag::rescomp >() - 1;
+        //// form limiters
+        //auto rcL = (delta2[c] + muscl_eps) / (delta1[c] + muscl_eps);
+        //auto rcR = (delta2[c] + muscl_eps) / (delta3[c] + muscl_eps);
+        //auto rLinv = (delta1[c] + muscl_eps) / (delta2[c] + muscl_eps);
+        //auto rRinv = (delta3[c] + muscl_eps) / (delta2[c] + muscl_eps);
+
+        //// van Leer limiter
+        //// any other symmetric limiter could be used instead too
+        //auto phiL = (std::abs(rcL) + rcL) / (std::abs(rcL) + 1.0);
+        //auto phiR = (std::abs(rcR) + rcR) / (std::abs(rcR) + 1.0);
+        //auto phi_L_inv = (std::abs(rLinv) + rLinv) / (std::abs(rLinv) + 1.0);
+        //auto phi_R_inv = (std::abs(rRinv) + rRinv) / (std::abs(rRinv) + 1.0);
+
+        //// update unknowns with reconstructed unknowns
+        //url[c] += 0.25*(delta1[c]*muscl_m1*phiL + delta2[c]*muscl_p1*phi_L_inv);
+        //urr[c] -= 0.25*(delta3[c]*muscl_m1*phiR + delta2[c]*muscl_p1*phi_R_inv);
+
+        // ---------------------------------------------------------------------
+
+        // MUSCL extrapolation option 2:
+        // ---------------------------------------------------------------------
+        // The following 2 blocks of code.
+        // this reconstruction is from the following paper:
+        // Luo, H., Baum, J. D., & Lohner, R. (1994). Edge-based finite element
+        // scheme for the Euler equations. AIAA journal, 32(6), 1183-1190.
+        // Van Leer, B. (1974). Towards the ultimate conservative difference
+        // scheme. II. Monotonicity and conservation combined in a second-order
+        // scheme. Journal of computational physics, 14(4), 361-370.
+
+        // get Van Albada limiter
+        // the following form is derived from the flux limiter phi as:
+        // s = phi_inv - (1 - phi)
+        auto sL = std::max(0.0, (2.0*delta1[c]*delta2[c] + muscl_eps)
+          /(delta1[c]*delta1[c] + delta2[c]*delta2[c] + muscl_eps));
+        auto sR = std::max(0.0, (2.0*delta3[c]*delta2[c] + muscl_eps)
+          /(delta3[c]*delta3[c] + delta2[c]*delta2[c] + muscl_eps));
 
-    if (m_movedmesh) {
-      d->Itf() = 0;  // Zero field output iteration count if mesh moved
-      ++d->Itr();    // Increase number of iterations with a change in the mesh
-    }
-
-    if (steady) {
-
-      // this is the last time step if max time of max number of time steps
-      // reached or the residual has reached its convergence criterion
-      if (d->finished() or l2res[rc] < residual) m_finished = 1;
-
-    } else {
-
-      // this is the last time step if max time or max iterations reached
-      if (d->finished()) m_finished = 1;
-
-    }
-  }
-
-  if (m_movedmesh) {
-    // Normals need to be recomputed if overset mesh has been moved
-    thisProxy[ thisIndex ].wait4norm();
-  }
-
-  // Start solution transfer
-  transferSol();
-}
-//! [Refine]
-
-//! [stage]
-void
-OversetFE::stage()
-// *****************************************************************************
-// Evaluate whether to continue with next time step stage
-// *****************************************************************************
-{
-  // if not all Runge-Kutta stages complete, continue to next time stage,
-  // otherwise start next time step
-  if (m_stage == 3) {
-    // output field data and start with next time step
-    out();
-  }
-  else {
-    // start with next time-step stage
-    chBndGrad();
-  }
-}
-//! [stage]
-
-void
-OversetFE::writeFields( CkCallback c )
-// *****************************************************************************
-// Output mesh-based fields to file
-//! \param[in] c Function to continue with after the write
-// *****************************************************************************
-{
-  if (g_inputdeck.get< tag::cmd, tag::benchmark >()) {
-
-    c.send();
-
-  } else {
-
-    auto d = Disc();
-    const auto& coord = d->Coord();
-
-    //// if coupled: depvars: src:'a', dst:'b','c',...
-    //char depvar = 0;
-    //if (not d->Transfers().empty()) {
-    //  depvar = 'a' + static_cast< char >( d->MeshId() );
-    //}
-
-    // Query fields names requested by user
-    auto nodefieldnames = numericFieldNames( tk::Centering::NODE );
-
-    // Collect field output from numerical solution requested by user
-    auto nodefields = numericFieldOutput( m_u, tk::Centering::NODE,
-      g_cgpde[Disc()->MeshId()].OutVarFn(), m_u );
-
-    // Collect field output names for analytical solutions
-    analyticFieldNames( g_cgpde[d->MeshId()], tk::Centering::NODE,
-      nodefieldnames );
-
-    // Collect field output from analytical solutions (if exist)
-    analyticFieldOutput( g_cgpde[d->MeshId()], tk::Centering::NODE, coord[0],
-      coord[1], coord[2], d->T(), nodefields );
-
-    // Query and collect nodal block and surface field names from PDEs integrated
-    std::vector< std::string > nodesurfnames;
-    auto sn = g_cgpde[d->MeshId()].surfNames();
-    nodesurfnames.insert( end(nodesurfnames), begin(sn), end(sn) );
-
-    // Collect nodal block and surface field solution
-    std::vector< std::vector< tk::real > > nodesurfs;
-    auto so = g_cgpde[d->MeshId()].surfOutput( tk::bfacenodes(m_bface,
-      m_triinpoel), m_u );
-    nodesurfs.insert( end(nodesurfs), begin(so), end(so) );
-
-    // Collect elemental block and surface field names from PDEs integrated
-    auto elemsurfnames = nodesurfnames;<--- Variable 'elemsurfnames' is assigned a value that is never used.
-
-    // Collect elemental block and surface field solution
-    std::vector< std::vector< tk::real > > elemsurfs;
-    auto eso = g_cgpde[d->MeshId()].elemSurfOutput( m_bface, m_triinpoel, m_u );
-    elemsurfs.insert( end(elemsurfs), begin(eso), end(eso) );
-
-    Assert( nodefieldnames.size() == nodefields.size(), "Size mismatch" );
-
-    // Send mesh and fields data (solution dump) for output to file
-    d->write( d->Inpoel(), coord, m_bface, tk::remap(m_bnode,d->Lid()),
-              m_triinpoel, {}, nodefieldnames, elemsurfnames,
-              nodesurfnames, {}, nodefields, elemsurfs, nodesurfs, c );
-
-  }
-}
-
-void
-OversetFE::out()
-// *****************************************************************************
-// Output mesh field data and continue to next time step
-// *****************************************************************************
-{
-  auto d = Disc();
-
-  // Output time history
-  if (d->histiter() or d->histtime() or d->histrange()) {
-    std::vector< std::vector< tk::real > > hist;
-    auto h = g_cgpde[d->MeshId()].histOutput( d->Hist(), d->Inpoel(), m_u );
-    hist.insert( end(hist), begin(h), end(h) );
-    d->history( std::move(hist) );
-  }
-
-  // Output field data
-  if (d->fielditer() or d->fieldtime() or d->fieldrange() or m_finished)
-    writeFields(CkCallback( CkIndex_OversetFE::step(), thisProxy[thisIndex]) );
-  else
-    step();
-}
-
-void
-OversetFE::evalLB( int nrestart )
-// *****************************************************************************
-// Evaluate whether to do load balancing
-//! \param[in] nrestart Number of times restarted
-// *****************************************************************************
-{
-  auto d = Disc();
+        // update unknowns with reconstructed unknowns
+        url[c] += 0.25*sL*(delta1[c]*(1.0-muscl_const*sL)
+          + delta2[c]*(1.0+muscl_const*sL));
+        urr[c] -= 0.25*sR*(delta3[c]*(1.0-muscl_const*sR)
+          + delta2[c]*(1.0+muscl_const*sR));
+
+        // ---------------------------------------------------------------------
+      }
+
+      // force first order if the reconstructions for density or internal energy
+      // would have allowed negative values
+      if (ls[0] < delta1[0] || ls[4] < delta1[4]) url = ls;
+      if (rs[0] < -delta3[0] || rs[4] < -delta3[4]) urr = rs;
+
+      rL = url[0];
+      uL = url[1];
+      vL = url[2];
+      wL = url[3];
+      eL = url[4];
+
+      rR = urr[0];
+      uR = urr[1];
+      vR = urr[2];
+      wR = urr[3];
+      eR = urr[4];
+    }
+
+    //! Compute boundary integrals for ALECG
+    //! \param[in] coord Mesh node coordinates
+    //! \param[in] triinpoel Boundary triangle face connecitivity with local ids
+    //! \param[in] symbctri Vector with 1 at symmetry BC boundary triangles
+    //! \param[in] U Solution vector at recent time step
+    //! \param[in] W Mesh velocity
+    //! \param[in,out] R Right-hand side vector computed
+    void bndint( const std::array< std::vector< real >, 3 >& coord,
+                 const std::vector< std::size_t >& triinpoel,
+                 const std::vector< int >& symbctri,
+                 const tk::Fields& U,
+                 const tk::Fields& W,
+                 tk::Fields& R ) const
+    {
+
+      // access node coordinates
+      const auto& x = coord[0];
+      const auto& y = coord[1];
+      const auto& z = coord[2];
+
+      // boundary integrals: compute fluxes in edges
+      std::vector< real > bflux( triinpoel.size() * m_ncomp * 2 );
+
+      #pragma omp simd
+      for (std::size_t e=0; e<triinpoel.size()/3; ++e) {
+        // access node IDs
+        std::size_t N[3] =
+          { triinpoel[e*3+0], triinpoel[e*3+1], triinpoel[e*3+2] };
+        // access solution at element nodes
+        real rA  = U(N[0],0);
+        real rB  = U(N[1],0);
+        real rC  = U(N[2],0);
+        real ruA = U(N[0],1);
+        real ruB = U(N[1],1);
+        real ruC = U(N[2],1);
+        real rvA = U(N[0],2);
+        real rvB = U(N[1],2);
+        real rvC = U(N[2],2);
+        real rwA = U(N[0],3);
+        real rwB = U(N[1],3);
+        real rwC = U(N[2],3);
+        real reA = U(N[0],4);
+        real reB = U(N[1],4);
+        real reC = U(N[2],4);
+        real w1A = W(N[0],0);
+        real w2A = W(N[0],1);
+        real w3A = W(N[0],2);
+        real w1B = W(N[1],0);
+        real w2B = W(N[1],1);
+        real w3B = W(N[1],2);
+        real w1C = W(N[2],0);
+        real w2C = W(N[2],1);
+        real w3C = W(N[2],2);
+        // apply stagnation BCs
+        if ( stagPoint(x[N[0]],y[N[0]],z[N[0]]) )
+        {
+          ruA = rvA = rwA = 0.0;
+        }
+        if ( stagPoint(x[N[1]],y[N[1]],z[N[1]]) )
+        {
+          ruB = rvB = rwB = 0.0;
+        }
+        if ( stagPoint(x[N[2]],y[N[2]],z[N[2]]) )
+        {
+          ruC = rvC = rwC = 0.0;
+        }
+        // compute face normal
+        real nx, ny, nz;
+        tk::normal( x[N[0]], x[N[1]], x[N[2]],
+                    y[N[0]], y[N[1]], y[N[2]],
+                    z[N[0]], z[N[1]], z[N[2]],
+                    nx, ny, nz );
+        // compute boundary flux
+        real f[m_ncomp][3];
+        real p, vn;
+        int sym = symbctri[e];
+        p = m_mat_blk[0].compute< EOS::pressure >( rA, ruA/rA, rvA/rA, rwA/rA,
+          reA );
+        vn = sym ? 0.0 : (nx*(ruA/rA-w1A) + ny*(rvA/rA-w2A) + nz*(rwA/rA-w3A));
+        f[0][0] = rA*vn;
+        f[1][0] = ruA*vn + p*nx;
+        f[2][0] = rvA*vn + p*ny;
+        f[3][0] = rwA*vn + p*nz;
+        f[4][0] = reA*vn + p*(sym ? 0.0 : (nx*ruA + ny*rvA + nz*rwA)/rA);
+        p = m_mat_blk[0].compute< EOS::pressure >( rB, ruB/rB, rvB/rB, rwB/rB,
+          reB );
+        vn = sym ? 0.0 : (nx*(ruB/rB-w1B) + ny*(rvB/rB-w2B) + nz*(rwB/rB-w3B));
+        f[0][1] = rB*vn;
+        f[1][1] = ruB*vn + p*nx;
+        f[2][1] = rvB*vn + p*ny;
+        f[3][1] = rwB*vn + p*nz;
+        f[4][1] = reB*vn + p*(sym ? 0.0 : (nx*ruB + ny*rvB + nz*rwB)/rB);
+        p = m_mat_blk[0].compute< EOS::pressure >( rC, ruC/rC, rvC/rC, rwC/rC,
+          reC );
+        vn = sym ? 0.0 : (nx*(ruC/rC-w1C) + ny*(rvC/rC-w2C) + nz*(rwC/rC-w3C));
+        f[0][2] = rC*vn;
+        f[1][2] = ruC*vn + p*nx;
+        f[2][2] = rvC*vn + p*ny;
+        f[3][2] = rwC*vn + p*nz;
+        f[4][2] = reC*vn + p*(sym ? 0.0 : (nx*ruC + ny*rvC + nz*rwC)/rC);
+        // compute face area
+        auto A6 = tk::area( x[N[0]], x[N[1]], x[N[2]],
+                            y[N[0]], y[N[1]], y[N[2]],
+                            z[N[0]], z[N[1]], z[N[2]] ) / 6.0;
+        auto A24 = A6/4.0;
+        // store flux in boundary elements
+        for (std::size_t c=0; c<m_ncomp; ++c) {
+          auto eb = (e*m_ncomp+c)*6;
+          auto Bab = A24 * (f[c][0] + f[c][1]);
+          bflux[eb+0] = Bab + A6 * f[c][0];
+          bflux[eb+1] = Bab;
+          Bab = A24 * (f[c][1] + f[c][2]);
+          bflux[eb+2] = Bab + A6 * f[c][1];
+          bflux[eb+3] = Bab;
+          Bab = A24 * (f[c][2] + f[c][0]);
+          bflux[eb+4] = Bab + A6 * f[c][2];
+          bflux[eb+5] = Bab;
+        }
+      }
 
-  // Detect if just returned from a checkpoint and if so, zero timers and
-  // finished flag
-  if (d->restarted( nrestart )) m_finished = 0;
+      // access pointer to right hand side at component
+      std::array< const real*, m_ncomp > r;
+      for (ncomp_t c=0; c<m_ncomp; ++c) r[c] = R.cptr( c );
 
-  const auto lbfreq = g_inputdeck.get< tag::cmd, tag::lbfreq >();
-  const auto nonblocking = g_inputdeck.get< tag::cmd, tag::nonblocking >();
-
-  // Load balancing if user frequency is reached or after the second time-step
-  if ( (d->It()) % lbfreq == 0 || d->It() == 2 ) {
-
-    AtSync();
-    if (nonblocking) next();
+      // boundary integrals: sum flux contributions to points
+      for (std::size_t e=0; e<triinpoel.size()/3; ++e)
+        for (std::size_t c=0; c<m_ncomp; ++c) {
+          auto eb = (e*m_ncomp+c)*6;
+          R.var(r[c],triinpoel[e*3+0]) -= bflux[eb+0] + bflux[eb+5];
+          R.var(r[c],triinpoel[e*3+1]) -= bflux[eb+1] + bflux[eb+2];
+          R.var(r[c],triinpoel[e*3+2]) -= bflux[eb+3] + bflux[eb+4];
+        }
 
-  } else {
-
-    next();
-
-  }
-}
-
-void
-OversetFE::evalRestart()
-// *****************************************************************************
-// Evaluate whether to save checkpoint/restart
-// *****************************************************************************
-{
-  auto d = Disc();
-
-  const auto rsfreq = g_inputdeck.get< tag::cmd, tag::rsfreq >();
-  const auto benchmark = g_inputdeck.get< tag::cmd, tag::benchmark >();
-
-  if (not benchmark and not (d->It() % rsfreq)) {
+      tk::destroy(bflux);
+    }
+
+    //! Compute optional source integral
+    //! \param[in] coord Mesh node coordinates
+    //! \param[in] inpoel Mesh element connectivity
+    //! \param[in] t Physical time
+    //! \param[in] tp Physical time for each mesh node
+    //! \param[in,out] R Right-hand side vector computed
+    void src( const std::array< std::vector< real >, 3 >& coord,
+              const std::vector< std::size_t >& inpoel,
+              real t,
+              const std::vector< tk::real >& tp,
+              tk::Fields& R ) const
+    {
+      // access node coordinates
+      const auto& x = coord[0];
+      const auto& y = coord[1];
+      const auto& z = coord[2];
 
-    std::vector< std::size_t > meshdata{ /* finished = */ 0, d->MeshId() };
-    contribute( meshdata, CkReduction::nop,
-      CkCallback(CkReductionTarget(Transporter,checkpoint), d->Tr()) );
+      // access pointer to right hand side at component
+      std::array< const real*, m_ncomp > r;
+      for (ncomp_t c=0; c<m_ncomp; ++c) r[c] = R.cptr( c );
 
-  } else {
-
-    evalLB( /* nrestart = */ -1 );
-
-  }
-}
-
-void
-OversetFE::step()
-// *****************************************************************************
-// Evaluate whether to continue with next time step
-// *****************************************************************************
-{
-  auto d = Disc();
-
-  // Output one-liner status report to screen
-  d->status();
-  // Reset Runge-Kutta stage counter
-  m_stage = 0;
+      // source integral
+      for (std::size_t e=0; e<inpoel.size()/4; ++e) {
+        std::size_t N[4] =
+          { inpoel[e*4+0], inpoel[e*4+1], inpoel[e*4+2], inpoel[e*4+3] };
+        // compute element Jacobi determinant, J = 6V
+        auto J24 = tk::triple(
+          x[N[1]]-x[N[0]], y[N[1]]-y[N[0]], z[N[1]]-z[N[0]],
+          x[N[2]]-x[N[0]], y[N[2]]-y[N[0]], z[N[2]]-z[N[0]],
+          x[N[3]]-x[N[0]], y[N[3]]-y[N[0]], z[N[3]]-z[N[0]] ) / 24.0;
+        // sum source contributions to nodes
+        for (std::size_t a=0; a<4; ++a) {
+          std::vector< real > s(m_ncomp);
+          if (g_inputdeck.get< tag::steady_state >()) t = tp[N[a]];
+          Problem::src( 1, m_mat_blk, x[N[a]], y[N[a]], z[N[a]], t, s );
+          for (std::size_t c=0; c<m_ncomp; ++c)
+            R.var(r[c],N[a]) += J24 * s[c];
+        }
+      }
+    }
 
-  if (not m_finished) {
-
-    evalRestart();
-
-  } else {
-
-    auto meshid = d->MeshId();
-    d->contribute( sizeof(std::size_t), &meshid, CkReduction::nop,
-                   CkCallback(CkReductionTarget(Transporter,finish), d->Tr()) );
-
-  }
-}
-
-#include "NoWarning/oversetfe.def.h"
+    //! Compute sources corresponding to a propagating front in user-defined box
+    //! \param[in] V Total box volume
+    //! \param[in] t Physical time
+    //! \param[in] inpoel Element point connectivity
+    //! \param[in] esup Elements surrounding points
+    //! \param[in] boxnodes Mesh node ids within user-defined box
+    //! \param[in] coord Mesh node coordinates
+    //! \param[in] R Right-hand side vector
+    //! \details This function add the energy source corresponding to a planar
+    //!   wave-front propagating along the z-direction with a user-specified
+    //!   velocity, within a box initial condition, configured by the user.
+    //!   Example (SI) units of the quantities involved:
+    //!    * internal energy content (energy per unit volume): J/m^3
+    //!    * specific energy (internal energy per unit mass): J/kg
+    void boxSrc( real V,
+                 real t,
+                 const std::vector< std::size_t >& inpoel,
+                 const std::pair< std::vector< std::size_t >,
+                                  std::vector< std::size_t > >& esup,
+                 const std::unordered_set< std::size_t >& boxnodes,
+                 const std::array< std::vector< real >, 3 >& coord,
+                 tk::Fields& R ) const<--- Parameter 'R' can be declared with const
+    {
+      const auto& icbox = g_inputdeck.get< tag::ic, tag::box >();
+
+      if (!icbox.empty()) {
+        for (const auto& b : icbox) {   // for all boxes for this eq
+          std::vector< tk::real > box
+           { b.template get< tag::xmin >(), b.template get< tag::xmax >(),
+             b.template get< tag::ymin >(), b.template get< tag::ymax >(),
+             b.template get< tag::zmin >(), b.template get< tag::zmax >() };
+
+          auto boxenc = b.template get< tag::energy_content >();
+          Assert( boxenc > 0.0, "Box energy content must be nonzero" );
+
+          auto V_ex = (box[1]-box[0]) * (box[3]-box[2]) * (box[5]-box[4]);
+
+          // determine times at which sourcing is initialized and terminated
+          auto iv = b.template get< tag::front_speed >();
+          auto wFront = b.template get< tag::front_width >();
+          auto tInit = b.template get< tag::init_time >();
+          auto tFinal = tInit + (box[5] - box[4] - wFront) / std::fabs(iv);
+          auto aBox = (box[1]-box[0]) * (box[3]-box[2]);
+
+          const auto& x = coord[0];
+          const auto& y = coord[1];
+          const auto& z = coord[2];
+
+          if (t >= tInit && t <= tFinal) {
+            // The energy front is assumed to have a half-sine-wave shape. The
+            // half wave-length is the width of the front. At t=0, the center of
+            // this front (i.e. the peak of the partial-sine-wave) is at X_0 +
+            // W_0.  W_0 is calculated based on the width of the front and the
+            // direction of propagation (which is assumed to be along the
+            // z-direction).  If the front propagation velocity is positive, it
+            // is assumed that the initial position of the energy source is the
+            // minimum z-coordinate of the box; whereas if this velocity is
+            // negative, the initial position is the maximum z-coordinate of the
+            // box.
+
+            // Orientation of box
+            std::array< tk::real, 3 > b_orientn{{
+              b.template get< tag::orientation >()[0],
+              b.template get< tag::orientation >()[1],
+              b.template get< tag::orientation >()[2] }};
+            std::array< tk::real, 3 > b_centroid{{ 0.5*(box[0]+box[1]),
+              0.5*(box[2]+box[3]), 0.5*(box[4]+box[5]) }};
+            // Transform box to reference space
+            std::array< tk::real, 3 > b_min{{box[0], box[2], box[4]}};
+            std::array< tk::real, 3 > b_max{{box[1], box[3], box[5]}};
+            tk::movePoint(b_centroid, b_min);
+            tk::movePoint(b_centroid, b_max);
+
+            // initial center of front
+            tk::real zInit(b_min[2]);
+            if (iv < 0.0) zInit = b_max[2];
+            // current location of front
+            auto z0 = zInit + iv * (t-tInit);
+            auto z1 = z0 + std::copysign(wFront, iv);
+            tk::real s0(z0), s1(z1);
+            // if velocity of propagation is negative, initial position is z1
+            if (iv < 0.0) {
+              s0 = z1;
+              s1 = z0;
+            }
+            // Sine-wave (positive part of the wave) source term amplitude
+            auto pi = 4.0 * std::atan(1.0);
+            auto amplE = boxenc * V_ex * pi
+              / (aBox * wFront * 2.0 * (tFinal-tInit));
+            //// Square wave (constant) source term amplitude
+            //auto amplE = boxenc * V_ex
+            //  / (aBox * wFront * (tFinal-tInit));
+            //// arbitrary shape form
+            //auto amplE = boxenc * std::abs(iv) / wFront;
+            amplE *= V_ex / V;
+
+            // add source
+            for (auto p : boxnodes) {
+              std::array< tk::real, 3 > node{{ x[p], y[p], z[p] }};
+              // Transform node to reference space of box
+              tk::movePoint(b_centroid, node);
+              tk::rotatePoint({{-b_orientn[0], -b_orientn[1], -b_orientn[2]}},
+                node);
+
+              if (node[2] >= s0 && node[2] <= s1) {
+                auto S = amplE * std::sin(pi*(node[2]-s0)/wFront);
+                //// arbitrary shape form
+                //auto S = amplE;
+                for (auto e : tk::Around(esup,p)) {
+                  // access node IDs
+                  std::size_t N[4] =
+                    {inpoel[e*4+0], inpoel[e*4+1], inpoel[e*4+2], inpoel[e*4+3]};
+                  // compute element Jacobi determinant, J = 6V
+                  real bax = x[N[1]]-x[N[0]];
+                  real bay = y[N[1]]-y[N[0]];
+                  real baz = z[N[1]]-z[N[0]];
+                  real cax = x[N[2]]-x[N[0]];
+                  real cay = y[N[2]]-y[N[0]];
+                  real caz = z[N[2]]-z[N[0]];
+                  real dax = x[N[3]]-x[N[0]];
+                  real day = y[N[3]]-y[N[0]];
+                  real daz = z[N[3]]-z[N[0]];
+                  auto J =
+                    tk::triple( bax, bay, baz, cax, cay, caz, dax, day, daz );
+                  auto J24 = J/24.0;
+                  R(p,4) += J24 * S;
+                }
+              }
+            }
+          }
+        }
+      }
+    }
+
+};
+
+} // cg::
+
+} // inciter::
+
+#endif // CGCompFlow_h
 
diff --git a/Debug/cppcheck/54.html b/Debug/cppcheck/54.html index f1aa105c68ca..03782060c980 100644 --- a/Debug/cppcheck/54.html +++ b/Debug/cppcheck/54.html @@ -152,12 +152,12 @@
  1
@@ -323,86 +323,90 @@ 

Cppcheck report - [

// *****************************************************************************
+164
+165
+166
+167
+168
// *****************************************************************************
 /*!
-  \file      src/PDE/ConfigureMultiMat.cpp
+  \file      src/PDE/ConfigureCompFlow.cpp
   \copyright 2012-2015 J. Bakosi,
              2016-2018 Los Alamos National Security, LLC.,
              2019-2021 Triad National Security, LLC.
              All rights reserved. See the LICENSE file for details.
-  \brief     Register and compile configuration for multi-material compressible
-     flow PDE
-  \details   Register and compile configuration for compressible multi-material
-     flow PDE.
-*/
-// *****************************************************************************
-
-#include <set>
-#include <map>
-#include <vector>
-#include <string>
-
-#include <brigand/algorithms/for_each.hpp>
-
-#include "Tags.hpp"
-#include "CartesianProduct.hpp"
-#include "PDEFactory.hpp"
-#include "Inciter/Options/PDE.hpp"
-#include "ContainerUtil.hpp"
-#include "ConfigureMultiMat.hpp"
-#include "MultiMat/Physics/DG.hpp"
-#include "MultiMat/Physics/FV.hpp"
-#include "MultiMat/DGMultiMat.hpp"
-#include "MultiMat/FVMultiMat.hpp"
-#include "MultiMat/Problem.hpp"
-#include "Inciter/Options/Material.hpp"
+  \brief     Register and compile configuration for compressible flow PDE
+  \details   Register and compile configuration for compressible flow PDE.
+*/
+// *****************************************************************************
+
+#include <set>
+#include <map>
+#include <vector>
+#include <string>
+#include <limits>
+
+#include <brigand/algorithms/for_each.hpp>
+
+#include "Tags.hpp"
+#include "CartesianProduct.hpp"
+#include "PDEFactory.hpp"
+#include "Inciter/Options/PDE.hpp"
+#include "ContainerUtil.hpp"
+#include "ConfigureCompFlow.hpp"
+#include "CompFlow/Physics/CG.hpp"
+#include "CompFlow/Physics/DG.hpp"
+#include "CompFlow/CGCompFlow.hpp"
+#include "CompFlow/DGCompFlow.hpp"
+#include "CompFlow/Problem.hpp"
+
+namespace inciter {
 
-namespace inciter {
-
-void
-registerMultiMat( DGFactory& df, FVFactory& ff,
-  std::set< ctr::PDEType >& fvt, std::set< ctr::PDEType >& dgt )
+void
+registerCompFlow( CGFactory& cf,
+                  DGFactory& df,
+                  std::set< ctr::PDEType >& cgt,
+                  std::set< ctr::PDEType >& dgt )
 // *****************************************************************************
-// Register multi-material compressible flow PDE into PDE factory
-//! \param[in,out] df Discontinuous Galerkin PDE factory to register to
-//! \param[in,out] ff Finite volume PDE factory to register to
-//! \param[in,out] dgt Counters for equation types registered into DG factory
-//! \param[in,out] fvt Counters for equation types registered into FV factory
+// Register compressible flow PDE into PDE factory
+//! \param[in,out] cf Continuous Galerkin PDE factory to register to
+//! \param[in,out] df Discontinuous Galerkin PDE factory to register to
+//! \param[in,out] cgt Counters for equation types registered into CG factory
+//! \param[in,out] dgt Counters for equation types registered into DG factory
 // *****************************************************************************
 {
   // Construct vector of vectors for all possible policies
-  using DGMultiMatPolicies =
-    tk::cartesian_product< dg::MultiMatPhysics, MultiMatProblems >;
+  using CGCompFlowPolicies =
+    tk::cartesian_product< cg::CompFlowPhysics, CompFlowProblems >;
   // Register PDEs for all combinations of policies
-  brigand::for_each< DGMultiMatPolicies >(
-    registerDG< dg::MultiMat >( df, dgt, ctr::PDEType::MULTIMAT ) );
+  brigand::for_each< CGCompFlowPolicies >(
+    registerCG< cg::CompFlow >( cf, cgt, ctr::PDEType::COMPFLOW ) );
 
   // Construct vector of vectors for all possible policies
-  using FVMultiMatPolicies =
-    tk::cartesian_product< fv::MultiMatPhysics, MultiMatProblems >;
+  using DGCompFlowPolicies =
+    tk::cartesian_product< dg::CompFlowPhysics, CompFlowProblems >;
   // Register PDEs for all combinations of policies
-  brigand::for_each< FVMultiMatPolicies >(
-    registerFV< fv::MultiMat >( ff, fvt, ctr::PDEType::MULTIMAT ) );
+  brigand::for_each< DGCompFlowPolicies >(
+    registerDG< dg::CompFlow >( df, dgt, ctr::PDEType::COMPFLOW ) );
 }
 
 std::vector< std::pair< std::string, std::string > >
-infoMultiMat( std::map< ctr::PDEType, tk::ncomp_t >& cnt )
+infoCompFlow( std::map< ctr::PDEType, tk::ncomp_t >& cnt )
 // *****************************************************************************
 //  Return information on the compressible flow system of PDEs
 //! \param[inout] cnt std::map of counters for all PDE types
 //! \return vector of string pairs describing the PDE configuration
 // *****************************************************************************
 {
-  using eq = tag::multimat;
+  using eq = tag::compflow;
   using tk::parameter;
   using tk::parameters;
 
-  auto c = ++cnt[ ctr::PDEType::MULTIMAT ];       // count eqs
+  auto c = ++cnt[ ctr::PDEType::COMPFLOW ];       // count eqs
   --c;  // used to index vectors starting with 0<--- Variable 'c' is assigned a value that is never used.
 
   std::vector< std::pair< std::string, std::string > > nfo;
 
-  nfo.emplace_back( ctr::PDE().name( ctr::PDEType::MULTIMAT ), "" );
+  nfo.emplace_back( ctr::PDE().name( ctr::PDEType::COMPFLOW ), "" );
 
   nfo.emplace_back( "physics", ctr::Physics().name(
     g_inputdeck.get< eq, tag::physics >() ) );
@@ -410,83 +414,87 @@ 

Cppcheck report - [ nfo.emplace_back( "problem", ctr::Problem().name( g_inputdeck.get< eq, tag::problem >() ) ); - nfo.emplace_back( "flux", ctr::Flux().name( - g_inputdeck.get< tag::flux >() ) ); + auto ncomp = g_inputdeck.get< tag::ncomp >(); + nfo.emplace_back( "number of components", parameter( ncomp ) ); - auto nmat = g_inputdeck.get< eq, tag::nmat >(); - nfo.emplace_back( "number of materials", std::to_string( nmat ) ); - - auto prelax = g_inputdeck.get< eq, tag::prelax >(); - nfo.emplace_back( "finite pressure relaxation", std::to_string( prelax ) ); - - auto intsharp = g_inputdeck.get< eq, tag::intsharp >(); - nfo.emplace_back( "interface sharpening", std::to_string( intsharp ) ); + const auto scheme = g_inputdeck.get< tag::scheme >(); + if (scheme != ctr::SchemeType::ALECG && scheme != ctr::SchemeType::OversetFE) + nfo.emplace_back( "flux", ctr::Flux().name( + g_inputdeck.get< tag::flux >() ) ); + + // ICs + + const auto& ic = g_inputdeck.get< tag::ic >(); - auto rho0cn = g_inputdeck.get< eq, tag::rho0constraint >(); - nfo.emplace_back( "density constraint correction", std::to_string( rho0cn ) ); - - auto ncomp = g_inputdeck.get< tag::ncomp >(); - nfo.emplace_back( "number of components", std::to_string( ncomp ) ); - - // Material eos output - const auto& matprop = g_inputdeck.get< tag::material >(); - for (const auto& mtype : matprop) { - const auto& m_id = mtype.get< tag::id >(); - ctr::Material opt; - nfo.emplace_back( opt.name( mtype.get< tag::eos >() ), - std::to_string(m_id.size())+" materials" ); - nfo.emplace_back( "material id", parameters( m_id ) ); - } - - // ICs and IC-boxes - - const auto& ic = g_inputdeck.get< tag::ic >(); - - const auto& bgmatidic = ic.get< tag::materialid >(); - nfo.emplace_back( "IC background material id", parameter( bgmatidic ) ); + const auto& icbox = ic.get< tag::box >(); + if (!icbox.empty()) { + std::size_t bcnt = 0; + for (const auto& b : icbox) { // for all boxes configured for this eq + std::vector< tk::real > box + { b.get< tag::xmin >(), b.get< tag::xmax >(), + b.get< tag::ymin >(), b.get< tag::ymax >(), + b.get< tag::zmin >(), b.get< tag::zmax >() }; + + std::string boxname = "IC box " + parameter(bcnt); + nfo.emplace_back( boxname, parameters( box ) ); + + nfo.emplace_back( boxname + " orientation", + parameters(b.get< tag::orientation >()) ); + + const auto& initiate = b.get< tag::initiate >(); + auto opt = ctr::Initiate(); + nfo.emplace_back( boxname + ' ' + opt.group(), opt.name(initiate) ); + + ++bcnt; + } + } - const auto& icbox = ic.get< tag::box >(); - if (!icbox.empty()) { - std::size_t bcnt = 0; - for (const auto& b : icbox) { // for all boxes configured for this eq - std::vector< tk::real > box - { b.get< tag::xmin >(), b.get< tag::xmax >(), - b.get< tag::ymin >(), b.get< tag::ymax >(), - b.get< tag::zmin >(), b.get< tag::zmax >() }; - - std::string boxname = "IC box " + parameter(bcnt); - nfo.emplace_back( boxname, parameters( box ) ); + const auto& icblock = ic.get< tag::meshblock >(); + for (const auto& b : icblock) { // for all blocks configured for eq + std::string blockname = "IC mesh block " + + parameter(b.get< tag::blockid >()); + + const auto& initiate = b.get< tag::initiate >(); + auto opt = ctr::Initiate(); + nfo.emplace_back( blockname + ' ' + opt.group(), opt.name(initiate) ); + } + + // BCs - nfo.emplace_back( boxname + " orientation", - parameters(b.get< tag::orientation >()) ); - - nfo.emplace_back( boxname + " material id", - parameter( b.get< tag::materialid >() ) ); - - const auto& initiate = b.get< tag::initiate >(); - auto opt = ctr::Initiate(); - nfo.emplace_back( boxname + ' ' + opt.group(), opt.name(initiate) ); - - ++bcnt; - } - } - - const auto& icblock = ic.get< tag::meshblock >(); - for (const auto& b : icblock) { // for all blocks configured for eq - std::string blockname = "IC mesh block " + - parameter(b.get< tag::blockid >()); - - nfo.emplace_back( blockname + " material id", - parameter( b.get< tag::materialid >() ) ); - const auto& initiate = b.get< tag::initiate >(); - auto opt = ctr::Initiate(); - nfo.emplace_back( blockname + ' ' + opt.group(), opt.name(initiate) ); - } - - return nfo; -} - -} // inciter:: + const auto& bc = g_inputdeck.get< tag::bc >(); + for (const auto& ib : bc) { + const auto& stag = ib.get< tag::stag_point >(); + const auto& radius = ib.get< tag::radius >(); + if (!stag.empty()) { + nfo.emplace_back( "Stagnation point(s)", parameters( stag ) ); + nfo.emplace_back( "Stagnation point(s) radii", parameter( radius ) ); + } + + const auto& fs = ib.get< tag::farfield >(); + if (!fs.empty()) + nfo.emplace_back( "Farfield BC sideset(s)", parameters( fs ) ); + + const auto& sym = ib.get< tag::symmetry >(); + if (!sym.empty()) + nfo.emplace_back( "Symmetry BC sideset(s)", parameters( sym ) ); + + const auto& dir = ib.get< tag::dirichlet >(); + if (!dir.empty()) + nfo.emplace_back( "Dirichlet BC sideset(s)", parameters( dir ) ); + + const auto& timedep = ib.get< tag::timedep >(); + if (!timedep.empty()) { + for (const auto& bndry : timedep) { + nfo.emplace_back( "Time dependent BC sideset(s)",<--- Consider using std::transform algorithm instead of a raw loop. + parameters(bndry.get< tag::sideset >()) ); + } + } + } + + return nfo; +} + +} // inciter::

diff --git a/Debug/cppcheck/55.html b/Debug/cppcheck/55.html index b9b19edcf8c8..966450da633b 100644 --- a/Debug/cppcheck/55.html +++ b/Debug/cppcheck/55.html @@ -152,12 +152,12 @@
   1
@@ -1451,1298 +1451,1894 @@ 

Cppcheck report - [

// *****************************************************************************
+1292
+1293
+1294
+1295
+1296
+1297
+1298
+1299
+1300
+1301
+1302
+1303
+1304
+1305
+1306
+1307
+1308
+1309
+1310
+1311
+1312
+1313
+1314
+1315
+1316
+1317
+1318
+1319
+1320
+1321
+1322
+1323
+1324
+1325
+1326
+1327
+1328
+1329
+1330
+1331
+1332
+1333
+1334
+1335
+1336
+1337
+1338
+1339
+1340
+1341
+1342
+1343
+1344
+1345
+1346
+1347
+1348
+1349
+1350
+1351
+1352
+1353
+1354
+1355
+1356
+1357
+1358
+1359
+1360
+1361
+1362
+1363
+1364
+1365
+1366
+1367
+1368
+1369
+1370
+1371
+1372
+1373
+1374
+1375
+1376
+1377
+1378
+1379
+1380
+1381
+1382
+1383
+1384
+1385
+1386
+1387
+1388
+1389
+1390
+1391
+1392
+1393
+1394
+1395
+1396
+1397
+1398
+1399
+1400
+1401
+1402
+1403
+1404
+1405
+1406
+1407
+1408
+1409
+1410
+1411
+1412
+1413
+1414
+1415
+1416
+1417
+1418
+1419
+1420
+1421
+1422
+1423
+1424
+1425
+1426
+1427
+1428
+1429
+1430
+1431
+1432
+1433
+1434
+1435
+1436
+1437
+1438
+1439
+1440
+1441
+1442
+1443
+1444
+1445
+1446
+1447
+1448
+1449
+1450
+1451
+1452
+1453
+1454
+1455
+1456
+1457
+1458
+1459
+1460
+1461
+1462
+1463
+1464
+1465
+1466
+1467
+1468
+1469
+1470
+1471
+1472
+1473
+1474
+1475
+1476
+1477
+1478
+1479
+1480
+1481
+1482
+1483
+1484
+1485
+1486
+1487
+1488
+1489
+1490
+1491
+1492
+1493
+1494
+1495
+1496
+1497
+1498
+1499
+1500
+1501
+1502
+1503
+1504
+1505
+1506
+1507
+1508
+1509
+1510
+1511
+1512
+1513
+1514
+1515
+1516
+1517
+1518
+1519
+1520
+1521
+1522
+1523
+1524
+1525
+1526
+1527
+1528
+1529
+1530
+1531
+1532
+1533
+1534
+1535
+1536
+1537
+1538
+1539
+1540
+1541
+1542
+1543
+1544
+1545
+1546
+1547
+1548
+1549
+1550
+1551
+1552
+1553
+1554
+1555
+1556
+1557
+1558
+1559
+1560
+1561
+1562
+1563
+1564
+1565
+1566
+1567
+1568
+1569
+1570
+1571
+1572
+1573
+1574
+1575
+1576
+1577
+1578
+1579
+1580
+1581
+1582
+1583
+1584
+1585
+1586
+1587
+1588
+1589
+1590
// *****************************************************************************
 /*!
-  \file      src/PDE/CompFlow/DGCompFlow.hpp
+  \file      src/Inciter/Transporter.cpp
   \copyright 2012-2015 J. Bakosi,
              2016-2018 Los Alamos National Security, LLC.,
              2019-2021 Triad National Security, LLC.
              All rights reserved. See the LICENSE file for details.
-  \brief     Compressible single-material flow using discontinuous Galerkin
-     finite elements
-  \details   This file implements calls to the physics operators governing
-    compressible single-material flow using discontinuous Galerkin
-    discretizations.
-*/
-// *****************************************************************************
-#ifndef DGCompFlow_h
-#define DGCompFlow_h
+  \brief     Transporter drives the time integration of transport equations
+  \details   Transporter drives the time integration of transport equations.
+    The implementation uses the Charm++ runtime system and is fully asynchronous,
+    overlapping computation, communication as well as I/O. The algorithm
+    utilizes the structured dagger (SDAG) Charm++ functionality. The high-level
+    overview of the algorithm structure and how it interfaces with Charm++ is
+    discussed in the Charm++ interface file src/Inciter/transporter.ci.
+*/
+// *****************************************************************************
 
-#include <cmath>
-#include <algorithm>
-#include <unordered_set>
-#include <map>
-
-#include <brigand/algorithms/for_each.hpp>
+#include <string>
+#include <iostream>
+#include <cstddef>
+#include <unordered_set>
+#include <limits>
+#include <cmath>
 
-#include "Macro.hpp"
-#include "Exception.hpp"
-#include "Vector.hpp"
-#include "ContainerUtil.hpp"
-#include "UnsMesh.hpp"
-#include "Inciter/InputDeck/InputDeck.hpp"
-#include "Integrate/Basis.hpp"
-#include "Integrate/Quadrature.hpp"
-#include "Integrate/Initialize.hpp"
-#include "Integrate/Mass.hpp"
-#include "Integrate/Surface.hpp"
-#include "Integrate/Boundary.hpp"
-#include "Integrate/Volume.hpp"
-#include "Integrate/Source.hpp"
-#include "RiemannChoice.hpp"
-#include "EoS/EOS.hpp"
-#include "Reconstruction.hpp"
-#include "Limiter.hpp"
-#include "PrefIndicator.hpp"
-
-namespace inciter {
-
-extern ctr::InputDeck g_inputdeck;
-
-namespace dg {
-
-//! \brief CompFlow used polymorphically with tk::DGPDE
-//! \details The template arguments specify policies and are used to configure
-//!   the behavior of the class. The policies are:
-//!   - Physics - physics configuration, see PDE/CompFlow/Physics.h
-//!   - Problem - problem configuration, see PDE/CompFlow/Problem.h
-//! \note The default physics is Euler, set in inciter::deck::check_compflow()
-template< class Physics, class Problem >
-class CompFlow {
+#include <brigand/algorithms/for_each.hpp>
+
+#include "Macro.hpp"
+#include "Transporter.hpp"
+#include "Fields.hpp"
+#include "PDEStack.hpp"
+#include "UniPDF.hpp"
+#include "PDFWriter.hpp"
+#include "ContainerUtil.hpp"
+#include "LoadDistributor.hpp"
+#include "MeshReader.hpp"
+#include "Inciter/InputDeck/InputDeck.hpp"
+#include "NodeDiagnostics.hpp"
+#include "ElemDiagnostics.hpp"
+#include "DiagWriter.hpp"
+#include "Callback.hpp"
+#include "CartesianProduct.hpp"
+
+#include "NoWarning/inciter.decl.h"
+#include "NoWarning/partitioner.decl.h"
+
+extern CProxy_Main mainProxy;
+
+namespace inciter {
+
+extern ctr::InputDeck g_inputdeck_defaults;
+extern ctr::InputDeck g_inputdeck;
+extern std::vector< CGPDE > g_cgpde;
+extern std::vector< DGPDE > g_dgpde;
+extern std::vector< FVPDE > g_fvpde;
+
+}
+
+using inciter::Transporter;
 
-  private:
-    using eq = tag::compflow;
-
-  public:
-    //! Constructor
-    explicit CompFlow() :
-      m_physics(),
-      m_problem(),
-      m_ncomp( g_inputdeck.get< tag::ncomp >() ),
-      m_riemann( compflowRiemannSolver(
-        g_inputdeck.get< tag::flux >() ) )
-    {
-      // associate boundary condition configurations with state functions, the
-      // order in which the state functions listed matters, see ctr::bc::Keys
-      brigand::for_each< ctr::bclist::Keys >( ConfigBC( m_bc,
-        { dirichlet
-        , symmetry
-        , invalidBC         // Inlet BC not implemented
-        , invalidBC         // Outlet BC not implemented
-        , farfield
-        , extrapolate } ) );
-
-      // EoS initialization
-      const auto& matprop =
-        g_inputdeck.get< tag::material >();
-      const auto& matidxmap =
-        g_inputdeck.get< tag::matidxmap >();
-      auto mateos = matprop[matidxmap.get< tag::eosidx >()[0]].get<tag::eos>();
-      m_mat_blk.emplace_back(mateos, EqType::compflow, 0);
-
-    }
-
-    //! Find the number of primitive quantities required for this PDE system
-    //! \return The number of primitive quantities required to be stored for
-    //!   this PDE system
-    std::size_t nprim() const
-    {
-      // compflow does not need/store any primitive quantities currently
-      return 0;
-    }
-
-    //! Find the number of materials set up for this PDE system
-    //! \return The number of materials set up for this PDE system
-    std::size_t nmat() const
-    {
-      // compflow does not need nmat
-      return 0;
-    }
-
-    //! Assign number of DOFs per equation in the PDE system
-    //! \param[in,out] numEqDof Array storing number of Dofs for each PDE
-    //!   equation
-    void numEquationDofs(std::vector< std::size_t >& numEqDof) const
-    {
-      // all equation-dofs initialized to ndof
-      for (std::size_t i=0; i<m_ncomp; ++i) {
-        numEqDof.push_back(g_inputdeck.get< tag::ndof >());
-      }
-    }
-
-    //! Determine elements that lie inside the user-defined IC box
-    //! \param[in] geoElem Element geometry array
-    //! \param[in] nielem Number of internal elements
-    //! \param[in,out] inbox List of nodes at which box user ICs are set for
-    //!    each IC box
-    void IcBoxElems( const tk::Fields& geoElem,
-      std::size_t nielem,
-      std::vector< std::unordered_set< std::size_t > >& inbox ) const
-    {
-      tk::BoxElems< eq >(geoElem, nielem, inbox);
-    }
-
-    //! Find how 'stiff equations', which we currently
-    //! have none for Compflow
-    //! \return number of stiff equations
-    std::size_t nstiffeq() const
-    { return 0; }
-
-    //! Find how 'nonstiff equations', which we currently
-    //! don't use for Compflow
-    //! \return number of non-stiff equations
-    std::size_t nnonstiffeq() const
-    { return 0; }
+Transporter::Transporter() :
+  m_input( input() ),
+  m_nchare( m_input.size() ),
+  m_meshid(),
+  m_ncit( m_nchare.size(), 0 ),
+  m_nload( 0 ),
+  m_ntrans( 0 ),
+  m_ndtmsh( 0 ),
+  m_dtmsh(),
+  m_npart( 0 ),
+  m_nstat( 0 ),
+  m_ndisc( 0 ),
+  m_nchk( 0 ),
+  m_ncom( 0 ),
+  m_nt0refit( m_nchare.size(), 0 ),
+  m_ndtrefit( m_nchare.size(), 0 ),
+  m_noutrefit( m_nchare.size(), 0 ),
+  m_noutderefit( m_nchare.size(), 0 ),
+  m_scheme(),
+  m_partitioner(),
+  m_refiner(),
+  m_meshwriter(),
+  m_sorter(),
+  m_nelem( m_nchare.size() ),
+  m_npoin(),
+  m_finished( m_nchare.size(), 0 ),
+  m_meshvol( m_nchare.size() ),
+  m_minstat( m_nchare.size() ),
+  m_maxstat( m_nchare.size() ),
+  m_avgstat( m_nchare.size() ),
+  m_timer(),
+  m_progMesh( g_inputdeck.get< tag::cmd, tag::feedback >(),
+              ProgMeshPrefix, ProgMeshLegend ),
+  m_progWork( g_inputdeck.get< tag::cmd, tag::feedback >(),
+              ProgWorkPrefix, ProgWorkLegend )
+// *****************************************************************************
+//  Constructor
+// *****************************************************************************
+{
+  // Echo configuration to screen
+  info( printer() );
+
+  const auto nstep = g_inputdeck.get< tag::nstep >();
+  const auto t0 = g_inputdeck.get< tag::t0 >();
+  const auto term = g_inputdeck.get< tag::term >();
+  const auto constdt = g_inputdeck.get< tag::dt >();
+
+  // If the desired max number of time steps is larger than zero, and the
+  // termination time is larger than the initial time, and the constant time
+  // step size (if that is used) is smaller than the duration of the time to be
+  // simulated, we have work to do, otherwise, finish right away. If a constant
+  // dt is not used, that part of the logic is always true as the default
+  // constdt is zero, see inciter::ctr::InputDeck::InputDeck().
+  if ( nstep != 0 && term > t0 && constdt < term-t0 ) {
+
+    // Enable SDAG waits for collecting mesh statistics
+    thisProxy.wait4stat();
+
+    // Configure and write diagnostics file header
+    diagHeader();
+
+    // Create mesh partitioner AND boundary condition object group
+    createPartitioner();
+
+  } else finish();      // stop if no time stepping requested
+}
+
+Transporter::Transporter( CkMigrateMessage* m ) :
+  CBase_Transporter( m ),
+  m_progMesh( g_inputdeck.get< tag::cmd, tag::feedback >(),
+              ProgMeshPrefix, ProgMeshLegend ),
+  m_progWork( g_inputdeck.get< tag::cmd, tag::feedback >(),
+              ProgWorkPrefix, ProgWorkLegend )
+// *****************************************************************************
+//  Migrate constructor: returning from a checkpoint
+//! \param[in] m Charm++ migrate message
+// *****************************************************************************
+{
+   auto print = printer();
+   print.diag( "Restarted from checkpoint" );
+   info( print );
+   inthead( print );
+}
 
-    //! Locate the stiff equations. Unused for compflow.
-    //! \param[out] stiffEqIdx list
-    void setStiffEqIdx( std::vector< std::size_t >& stiffEqIdx ) const
-    {
-      stiffEqIdx.resize(0);
-    }
-
-    //! Locate the nonstiff equations. Unused for compflow.
-    //! \param[out] nonStiffEqIdx list
-    void setNonStiffEqIdx( std::vector< std::size_t >& nonStiffEqIdx ) const
-    {
-      nonStiffEqIdx.resize(0);
-    }
-
-    //! Initalize the compressible flow equations, prepare for time integration
-    //! \param[in] L Block diagonal mass matrix
-    //! \param[in] inpoel Element-node connectivity
-    //! \param[in] coord Array of nodal coordinates
-    //! \param[in] inbox List of elements at which box user ICs are set for
-    //!    each IC box
-    //! \param[in,out] unk Array of unknowns
-    //! \param[in] t Physical time
-    //! \param[in] nielem Number of internal elements
-    void
-    initialize( const tk::Fields& L,
-                const std::vector< std::size_t >& inpoel,
-                const tk::UnsMesh::Coords& coord,
-                const std::vector< std::unordered_set< std::size_t > >& inbox,
-                const std::unordered_map< std::size_t,
-                  std::set< std::size_t > >&,
-                tk::Fields& unk,
-                tk::real t,
-                const std::size_t nielem ) const
-    {
-      tk::initialize( m_ncomp, m_mat_blk, L, inpoel, coord,
-                      Problem::initialize, unk, t, nielem );
-
-      const auto rdof = g_inputdeck.get< tag::rdof >();
-      const auto& ic = g_inputdeck.get< tag::ic >();
-      const auto& icbox = ic.get< tag::box >();
-      const auto& bgpreic = ic.get< tag::pressure >();
-      auto c_v = getmatprop< tag::cv >();
-
-      // Set initial conditions inside user-defined IC box
-      std::vector< tk::real > s(m_ncomp, 0.0);
-      for (std::size_t e=0; e<nielem; ++e) {
-        if (icbox.size() > 0) {
-          std::size_t bcnt = 0;
-          for (const auto& b : icbox) {   // for all boxes
-            if (inbox.size() > bcnt && inbox[bcnt].find(e) != inbox[bcnt].end())
-            {
-              std::vector< tk::real > box
-              { b.template get< tag::xmin >(), b.template get< tag::xmax >(),
-                b.template get< tag::ymin >(), b.template get< tag::ymax >(),
-                b.template get< tag::zmin >(), b.template get< tag::zmax >() };
-              auto V_ex = (box[1]-box[0]) * (box[3]-box[2]) * (box[5]-box[4]);
-              for (std::size_t c=0; c<m_ncomp; ++c) {
-                auto mark = c*rdof;
-                s[c] = unk(e,mark);
-                // set high-order DOFs to zero
-                for (std::size_t i=1; i<rdof; ++i)
-                  unk(e,mark+i) = 0.0;
-              }
-              initializeBox<ctr::boxList>( m_mat_blk, 1.0, V_ex,
-                t, b, bgpreic, c_v, s );
-              // store box-initialization in solution vector
-              for (std::size_t c=0; c<m_ncomp; ++c) {
-                auto mark = c*rdof;
-                unk(e,mark) = s[c];
-              }
-            }
-            ++bcnt;
-          }
-        }
-      }
-    }
+std::vector< std::string >
+Transporter::input()
+// *****************************************************************************
+// Generate list of input mesh filenames configured by the user
+//! \return List of input mesh filenames configured by the user
+//! \details If the input file is given on the command line, a single solver
+//!   will be instantiated on the single mesh, solving potentially multiple
+//!   systems of (potentially coupled) equations. If the input file is not given
+//!   on the command line, the mesh files are expected to be configured in the
+//!   control/input file, associating a potentially different mesh to each
+//!   solver. Both configurations allow the solution of coupled systems, but the
+//!   first one solves all equations on the same mesh, while the latter can
+//!   couple solutions computed on multiple different meshes.
+// *****************************************************************************
+{
+  // Query input mesh filename specified on the command line
+  const auto& cmdinput = g_inputdeck.get< tag::cmd, tag::io, tag::input >();
+
+  // Extract mesh filenames specified in the control file (assigned to solvers)
+  std::vector< std::string > ctrinput;
+  for (const auto& im : g_inputdeck.get< tag::mesh >()) {
+    ctrinput.push_back(im.get< tag::filename >());<--- Consider using std::transform algorithm instead of a raw loop.
+  }
+
+  ErrChk( not cmdinput.empty() or not ctrinput.empty(),
+    "Either a single input mesh must be given on the command line or multiple "
+    "meshes must be configured in the control file." );
+
+   // Prepend control file path to mesh filenames in given in control file
+  if (not ctrinput.empty()) {
+     const auto& ctr = g_inputdeck.get< tag::cmd, tag::io, tag::control >();
+     auto path = ctr.substr( 0, ctr.find_last_of("/")+1 );
+     for (auto& f : ctrinput) f = path + f;<--- Consider using std::transform algorithm instead of a raw loop.
+  }
+
+  if (cmdinput.empty()) return ctrinput; else return { cmdinput };
+}
+
+void
+Transporter::info( const InciterPrint& print )
+// *****************************************************************************
+// Echo configuration to screen
+//! \param[in] print Pretty printer object to use for printing
+// *****************************************************************************
+{
+  print.part( "Factory" );
+
+  // Print out info data layout
+  print.list( "Unknowns data layout (CMake: FIELD_DATA_LAYOUT)",
+              std::list< std::string >{ tk::Fields::layout() } );
+
+  // Re-create partial differential equations stack for output
+  PDEStack stack;
+
+  // Print out information on PDE factories
+  print.eqlist( "Registered PDEs using continuous Galerkin (CG) methods",
+                stack.cgfactory(), stack.cgntypes() );
+  print.eqlist( "Registered PDEs using discontinuous Galerkin (DG) methods",
+                stack.dgfactory(), stack.dgntypes() );
+  print.eqlist( "Registered PDEs using finite volume (DG) methods",
+                stack.fvfactory(), stack.fvntypes() );
+  print.endpart();
+
+  // Print out information on problem
+  print.part( "Problem" );
+
+  // Print out info on problem title
+  if ( !g_inputdeck.get< tag::title >().empty() )
+    print.title( g_inputdeck.get< tag::title >() );
+
+  const auto nstep = g_inputdeck.get< tag::nstep >();
+  const auto t0 = g_inputdeck.get< tag::t0 >();
+  const auto term = g_inputdeck.get< tag::term >();
+  const auto constdt = g_inputdeck.get< tag::dt >();
+  const auto cfl = g_inputdeck.get< tag::cfl >();
+  const auto scheme = g_inputdeck.get< tag::scheme >();
 
-    //! Save initial densities for all materials
-    //! \param[out] rho0mat List of initial densities
-    void setRho0mat( std::vector< tk::real >& rho0mat ) const
-    {
-      rho0mat.resize(0);
-    }
-
-    //! Compute density constraint for a given material
-    // //! \param[in] nelem Number of elements
-    // //! \param[in] unk Array of unknowns
-    // //! \param[in] rho0mat List of initial densities
-    //! \param[out] densityConstr Density Constraint: rho/(rho0*det(g))
-    void computeDensityConstr( std::size_t /*nelem*/,
-                               tk::Fields& /*unk*/,
-                               std::vector< tk::real >& /*rho0mat*/,
-                               std::vector< tk::real >& densityConstr) const
-    {
-      densityConstr.resize(0);
-    }
-
-    //! Compute the left hand side block-diagonal mass matrix
-    //! \param[in] geoElem Element geometry array
-    //! \param[in,out] l Block diagonal mass matrix
-    void lhs( const tk::Fields& geoElem, tk::Fields& l ) const {
-      const auto ndof = g_inputdeck.get< tag::ndof >();
-      tk::mass( m_ncomp, ndof, geoElem, l );
-    }
-
-    //! Update the interface cells to first order dofs
-    //! \details This function resets the high-order terms in interface cells,
-    //!   and is currently not used in compflow.
-    void updateInterfaceCells( tk::Fields&,
-      std::size_t,
-      std::vector< std::size_t >& ) const {}
-
-    //! Update the primitives for this PDE system
-    //! \details This function computes and stores the dofs for primitive
-    //!   quantities, which is currently unused for compflow. But if a limiter
-    //!   requires primitive variables for example, this would be the place to
-    //!   add the computation of the primitive variables.
-    void updatePrimitives( const tk::Fields&,
-                           const tk::Fields&,
-                           const tk::Fields&,
-                           tk::Fields&,
-                           std::size_t ) const {}
-
-    //! Clean up the state of trace materials for this PDE system
-    //! \details This function cleans up the state of materials present in trace
-    //!   quantities in each cell. This is unused for compflow.
-    void cleanTraceMaterial( tk::real,
-                             const tk::Fields&,
-                             tk::Fields&,
-                             tk::Fields&,
-                             std::size_t ) const {}
+  // Print discretization parameters
+  print.section( "Discretization parameters" );
+  print.Item< ctr::Scheme, tag::scheme >();
+  print.item( "Implicit-Explicit Runge-Kutta",
+              g_inputdeck.get< tag::imex_runge_kutta >() );
+
+  if (g_inputdeck.centering() == tk::Centering::ELEM)
+  {
+    print.Item< ctr::Limiter, tag::limiter >();
+
+    print.item("Shock detection based limiting",
+      g_inputdeck.get< tag::shock_detector_coeff >());
+
+    if (g_inputdeck.get< tag::accuracy_test >())
+    {
+      print.item("WARNING: order-of-accuracy testing enabled",
+        "robustness corrections inactive");
+    }
+
+    print.item("Limited solution projection",
+      g_inputdeck.get< tag::limsol_projection >());
+  }
+  print.item( "PE-locality mesh reordering",
+              g_inputdeck.get< tag::pelocal_reorder >() );
+  print.item( "Operator-access mesh reordering",
+              g_inputdeck.get< tag::operator_reorder >() );
+  auto steady = g_inputdeck.get< tag::steady_state >();
+  print.item( "Local time stepping", steady );
+  if (steady) {
+    print.item( "L2-norm residual convergence criterion",
+                g_inputdeck.get< tag::residual >() );
+    print.item( "Convergence criterion component index",
+                g_inputdeck.get< tag::rescomp >() );
+  }
+  print.item( "Number of time steps", nstep );
+  print.item( "Start time", t0 );
+  print.item( "Terminate time", term );
+
+  if (constdt > std::numeric_limits< tk::real >::epsilon())
+    print.item( "Constant time step size", constdt );
+  else if (cfl > std::numeric_limits< tk::real >::epsilon())
+  {
+    print.item( "CFL coefficient", cfl );
+  }
+
+  const auto& meshes = g_inputdeck.get< tag::mesh >();
+  const auto& depvars = g_inputdeck.get< tag::depvar >();
+  for (std::size_t i=0; i<meshes.size(); ++i) {
+    print.item( "Dependent var name and assoc. mesh", std::string{depvars[i]}
+      + " - " + meshes[i].get< tag::filename >() );
+  }
+
+  // Print out info on settings of selected partial differential equations
+  print.pdes( "Partial differential equations integrated", stack.info() );
 
-    //! Reconstruct second-order solution from first-order using least-squares
-    //! \param[in] t Physical time
-    //! \param[in] geoFace Face geometry array
-    //! \param[in] geoElem Element geometry array
-    //! \param[in] fd Face connectivity and boundary conditions object
-    //! \param[in] inpoel Element-node connectivity
-    //! \param[in] coord Array of nodal coordinates
-    //! \param[in,out] U Solution vector at recent time step
-    //! \param[in,out] P Primitive vector at recent time step
-    void reconstruct( tk::real t,
-                      const tk::Fields& geoFace,
-                      const tk::Fields& geoElem,
-                      const inciter::FaceData& fd,
-                      const std::map< std::size_t, std::vector< std::size_t > >&,
-                      const std::vector< std::size_t >& inpoel,
-                      const tk::UnsMesh::Coords& coord,
-                      tk::Fields& U,
-                      tk::Fields& P ) const
-    {
-      const auto rdof = g_inputdeck.get< tag::rdof >();
-
-      // do reconstruction only if P0P1
-      if (rdof == 4 && g_inputdeck.get< tag::ndof >() == 1) {
-        const auto nelem = fd.Esuel().size()/4;<--- Variable 'nelem' is assigned a value that is never used.
-
-        Assert( U.nprop() == rdof*5, "Number of components in solution "
-                "vector must equal "+ std::to_string(rdof*5) );
-        Assert( fd.Inpofa().size()/3 == fd.Esuf().size()/2,
-                "Mismatch in inpofa size" );
+  // Print out adaptive polynomial refinement configuration
+  if (scheme == ctr::SchemeType::PDG) {
+    print.section( "Polynomial refinement (p-ref)" );
+    print.item( "p-refinement",
+                g_inputdeck.get< tag::pref, tag::pref >() );
+    print.Item< ctr::PrefIndicator, tag::pref, tag::indicator >();
+    print.item( "Max degrees of freedom",
+                g_inputdeck.get< tag::pref, tag::ndofmax >() );
+    print.item( "Tolerance",
+                g_inputdeck.get< tag::pref, tag::tolref >() );
+  }
+
+  // Print out adaptive mesh refinement configuration
+  const auto amr = g_inputdeck.get< tag::amr, tag::amr >();
+  if (amr) {
+    print.section( "Mesh refinement (h-ref)" );
+    auto maxlevels = g_inputdeck.get< tag::amr, tag::maxlevels >();
+    print.item( "Maximum mesh refinement levels", maxlevels );
+    print.Item< ctr::AMRError, tag::amr, tag::error >();
+    auto t0ref = g_inputdeck.get< tag::amr, tag::t0ref >();
+    print.item( "Refinement at t<0 (t0ref)", t0ref );
+    if (t0ref) {
+      const auto& initref = g_inputdeck.get< tag::amr, tag::initial >();
+      print.item( "Initial refinement steps", initref.size() );
+
+      auto eps = std::numeric_limits< tk::real >::epsilon();
+
+      const auto& amr_coord = g_inputdeck.get< tag::amr, tag::coords >();
+      const auto& amr_defcoord = g_inputdeck_defaults.get< tag::amr, tag::coords >();
 
-        // allocate and initialize matrix and vector for reconstruction
-        std::vector< std::array< std::array< tk::real, 3 >, 3 > >
-          lhs_ls( nelem, {{ {{0.0, 0.0, 0.0}},
-                            {{0.0, 0.0, 0.0}},
-                            {{0.0, 0.0, 0.0}} }} );
-        std::vector< std::vector< std::array< tk::real, 3 > > >
-          rhs_ls( nelem, std::vector< std::array< tk::real, 3 > >
-            ( m_ncomp,
-              {{ 0.0, 0.0, 0.0 }} ) );
-
-        // reconstruct x,y,z-derivatives of unknowns
-        // 0. get lhs matrix, which is only geometry dependent
-        tk::lhsLeastSq_P0P1(fd, geoElem, geoFace, lhs_ls);
-
-        // 1. internal face contributions
-        std::vector< std::size_t > vars;
-        for (std::size_t c=0; c<m_ncomp; ++c) vars.push_back(c);
-        tk::intLeastSq_P0P1( rdof, fd, geoElem, U, rhs_ls, vars );
-
-        // 2. boundary face contributions
-        for (const auto& b : m_bc)
-          tk::bndLeastSqConservedVar_P0P1( m_ncomp,
-            m_mat_blk, rdof, b.first, fd, geoFace, geoElem, t, b.second,
-            P, U, rhs_ls, vars );
-
-        // 3. solve 3x3 least-squares system
-        tk::solveLeastSq_P0P1( rdof, lhs_ls, rhs_ls, U, vars );
-
-        // 4. transform reconstructed derivatives to Dubiner dofs
-        tk::transform_P0P1( rdof, nelem, inpoel, coord, U, vars );
-      }
-    }
-
-    //! Limit second-order solution
-    //! \param[in] t Physical time
-    //! \param[in] geoFace Face geometry array
-    //! \param[in] geoElem Element geometry array
-    //! \param[in] fd Face connectivity and boundary conditions object
-    //! \param[in] esup Elements surrounding points
-    //! \param[in] inpoel Element-node connectivity
-    //! \param[in] coord Array of nodal coordinates
-    //! \param[in] ndofel Vector of local number of degrees of freedome
-    //! \param[in] gid Local->global node id map
-    //! \param[in] bid Local chare-boundary node ids (value) associated to
-    //!   global node ids (key)
-    //! \param[in] uNodalExtrm Chare-boundary nodal extrema for conservative
-    //!   variables
-    //! \param[in] mtInv Inverse of Taylor mass matrix
-    //! \param[in,out] U Solution vector at recent time step
-    //! \param[in,out] shockmarker Vector of shock-marker values
-    void limit( [[maybe_unused]] tk::real t,
-                [[maybe_unused]] const tk::Fields& geoFace,
-                const tk::Fields& geoElem,
-                const inciter::FaceData& fd,
-                const std::map< std::size_t, std::vector< std::size_t > >& esup,
-                const std::vector< std::size_t >& inpoel,
-                const tk::UnsMesh::Coords& coord,
-                const std::vector< std::size_t >& ndofel,
-                const std::vector< std::size_t >& gid,
-                const std::unordered_map< std::size_t, std::size_t >& bid,
-                const std::vector< std::vector<tk::real> >& uNodalExtrm,
-                const std::vector< std::vector<tk::real> >&,
-                const std::vector< std::vector<tk::real> >& mtInv,
-                tk::Fields& U,
-                tk::Fields&,
-                std::vector< std::size_t >& shockmarker) const
-    {
-      const auto limiter = g_inputdeck.get< tag::limiter >();
-      const auto rdof = g_inputdeck.get< tag::rdof >();
-      const auto& solidx = g_inputdeck.get< tag::matidxmap, tag::solidx >();
-
-      if (limiter == ctr::LimiterType::WENOP1)
-        WENO_P1( fd.Esuel(), U );
-      else if (limiter == ctr::LimiterType::SUPERBEEP1)
-        Superbee_P1( fd.Esuel(), inpoel, ndofel, coord, U );
-      else if (limiter == ctr::LimiterType::VERTEXBASEDP1 && rdof == 4)
-        VertexBasedCompflow_P1( esup, inpoel, ndofel, fd.Esuel().size()/4,
-          m_mat_blk, fd, geoFace, geoElem, coord, flux, solidx, U,
-          shockmarker);
-      else if (limiter == ctr::LimiterType::VERTEXBASEDP1 && rdof == 10)
-        VertexBasedCompflow_P2( esup, inpoel, ndofel, fd.Esuel().size()/4,
-          m_mat_blk, fd, geoFace, geoElem, coord, gid, bid,
-          uNodalExtrm, mtInv, flux, solidx, U, shockmarker);
-    }
-
-    //! Update the conservative variable solution for this PDE system
-    //! \details This function computes the updated dofs for conservative
-    //!   quantities based on the limited solution and is currently not used in
-    //!   compflow.
-    void CPL( const tk::Fields&,
-              const tk::Fields&,
-              const std::vector< std::size_t >&,
-              const tk::UnsMesh::Coords&,
-              tk::Fields&,
-              std::size_t ) const {}
-
-    //! Return cell-average deformation gradient tensor (no-op for compflow)
-    //! \details This function is a no-op in compflow.
-    std::array< std::vector< tk::real >, 9 > cellAvgDeformGrad(
-      const tk::Fields&,
-      std::size_t ) const
-    {
-      return {};
-    }
-
-    //! Compute right hand side
-    //! \param[in] t Physical time
-    //! \param[in] geoFace Face geometry array
-    //! \param[in] geoElem Element geometry array
-    //! \param[in] fd Face connectivity and boundary conditions object
-    //! \param[in] inpoel Element-node connectivity
-    //! \param[in] boxelems Mesh node ids within user-defined IC boxes
-    //! \param[in] coord Array of nodal coordinates
-    //! \param[in] U Solution vector at recent time step
-    //! \param[in] P Primitive vector at recent time step
-    //! \param[in] ndofel Vector of local number of degrees of freedom
-    // //! \param[in] rho0mat Initial densities of all materials
-    //! \param[in] dt Delta time
-    //! \param[in,out] R Right-hand side vector computed
-    void rhs( tk::real t,
-              const tk::Fields& geoFace,
-              const tk::Fields& geoElem,
-              const inciter::FaceData& fd,
-              const std::vector< std::size_t >& inpoel,
-              const std::vector< std::unordered_set< std::size_t > >& boxelems,
-              const tk::UnsMesh::Coords& coord,
-              const tk::Fields& U,
-              const tk::Fields& P,
-              const std::vector< std::size_t >& ndofel,
-              const std::vector< tk::real >& /*rho0mat*/,
-              const tk::real dt,
-              tk::Fields& R ) const
-    {
-      const auto ndof = g_inputdeck.get< tag::ndof >();
-      const auto rdof = g_inputdeck.get< tag::rdof >();
-
-      const auto& solidx = g_inputdeck.get< tag::matidxmap, tag::solidx >();
-
-      Assert( U.nunk() == P.nunk(), "Number of unknowns in solution "
-              "vector and primitive vector at recent time step incorrect" );
-      Assert( U.nunk() == R.nunk(), "Number of unknowns in solution "
-              "vector and right-hand side at recent time step incorrect" );
-      Assert( U.nprop() == rdof*5, "Number of components in solution "
-              "vector must equal "+ std::to_string(rdof*5) );
-      Assert( P.nprop() == 0, "Number of components in primitive "
-              "vector must equal "+ std::to_string(0) );
-      Assert( R.nprop() == ndof*5, "Number of components in right-hand "
-              "side vector must equal "+ std::to_string(ndof*5) );
-      Assert( fd.Inpofa().size()/3 == fd.Esuf().size()/2,
-              "Mismatch in inpofa size" );
-
-      // set rhs to zero
-      R.fill(0.0);
-
-      // empty vector for non-conservative terms. This vector is unused for
-      // single-material hydrodynamics since, there are no non-conservative
-      // terms in the system of PDEs.
-      std::vector< std::vector < tk::real > > riemannDeriv;
-
-      std::vector< std::vector< tk::real > > vriem;
-      std::vector< std::vector< tk::real > > riemannLoc;
-
-      // configure a no-op lambda for prescribed velocity
-      auto velfn = []( ncomp_t, tk::real, tk::real, tk::real, tk::real ){
-        return tk::VelFn::result_type(); };
-
-      // compute internal surface flux integrals
-      tk::surfInt( 1, m_mat_blk, t, ndof, rdof, inpoel, solidx,
-                   coord, fd, geoFace, geoElem, m_riemann, velfn, U, P, ndofel,
-                   dt, R, vriem, riemannLoc, riemannDeriv );
-
-      // compute optional source term
-      tk::srcInt( m_mat_blk, t, ndof, fd.Esuel().size()/4,
-                  inpoel, coord, geoElem, Problem::src, ndofel, R );
-
-      if(ndof > 1)
-        // compute volume integrals
-        tk::volInt( 1, t, m_mat_blk, ndof, rdof,
-                    fd.Esuel().size()/4, inpoel, coord, geoElem, flux, velfn,
-                    U, P, ndofel, R );
-
-      // compute boundary surface flux integrals
-      for (const auto& b : m_bc)
-        tk::bndSurfInt( 1, m_mat_blk, ndof, rdof, b.first,
-                        fd, geoFace, geoElem, inpoel, coord, t, m_riemann,
-                        velfn, b.second, U, P, ndofel, R, vriem, riemannLoc,
-                        riemannDeriv );
-
-     // compute external (energy) sources
-      const auto& ic = g_inputdeck.get< tag::ic >();
-      const auto& icbox = ic.get< tag::box >();
-
-      if (!icbox.empty() && !boxelems.empty()) {
-        std::size_t bcnt = 0;
-        for (const auto& b : icbox) {   // for all boxes for this eq
-          std::vector< tk::real > box
-           { b.template get< tag::xmin >(), b.template get< tag::xmax >(),
-             b.template get< tag::ymin >(), b.template get< tag::ymax >(),
-             b.template get< tag::zmin >(), b.template get< tag::zmax >() };
+      auto xminus = amr_coord.get< tag::xminus >();
+      auto xminus_default = amr_defcoord.get< tag::xminus >();
+      if (std::abs( xminus - xminus_default ) > eps)
+        print.item( "Initial refinement x-", xminus );
+      auto xplus = amr_coord.get< tag::xplus >();
+      auto xplus_default = amr_defcoord.get< tag::xplus >();
+      if (std::abs( xplus - xplus_default ) > eps)
+        print.item( "Initial refinement x+", xplus );
+
+      auto yminus = amr_coord.get< tag::yminus >();
+      auto yminus_default = amr_defcoord.get< tag::yminus >();
+      if (std::abs( yminus - yminus_default ) > eps)
+        print.item( "Initial refinement y-", yminus );
+      auto yplus = amr_coord.get< tag::yplus >();
+      auto yplus_default = amr_defcoord.get< tag::yplus >();
+      if (std::abs( yplus - yplus_default ) > eps)
+        print.item( "Initial refinement y+", yplus );
+
+      auto zminus = amr_coord.get< tag::zminus >();
+      auto zminus_default = amr_defcoord.get< tag::zminus >();
+      if (std::abs( zminus - zminus_default ) > eps)
+        print.item( "Initial refinement z-", zminus );
+      auto zplus = amr_coord.get< tag::zplus >();
+      auto zplus_default = amr_defcoord.get< tag::zplus >();
+      if (std::abs( zplus - zplus_default ) > eps)
+        print.item( "Initial refinement z+", zplus );
+    }
+    auto dtref = g_inputdeck.get< tag::amr, tag::dtref >();
+    print.item( "Refinement at t>0 (dtref)", dtref );
+    if (dtref) {
+      auto dtfreq = g_inputdeck.get< tag::amr, tag::dtfreq >();
+      print.item( "Mesh refinement frequency, t>0", dtfreq );
+      print.item( "Uniform-only mesh refinement, t>0",
+                  g_inputdeck.get< tag::amr, tag::dtref_uniform >() );
+    }
+    print.item( "Refinement tolerance",
+                g_inputdeck.get< tag::amr, tag::tol_refine >() );
+    print.item( "De-refinement tolerance",
+                g_inputdeck.get< tag::amr, tag::tol_derefine >() );
+  }
+
+  // Print out ALE configuration
+  const auto ale = g_inputdeck.get< tag::ale, tag::ale >();
+  if (ale) {
+    print.section( "Arbitrary Lagrangian-Eulerian (ALE) mesh motion" );
+    auto dvcfl = g_inputdeck.get< tag::ale, tag::dvcfl >();
+    print.item( "Volume-change CFL coefficient", dvcfl );
+    print.Item< ctr::MeshVelocity, tag::ale, tag::mesh_velocity >();
+    print.Item< ctr::MeshVelocitySmoother, tag::ale, tag::smoother >();
+    print.item( "Mesh motion dimensions", tk::parameters(
+                g_inputdeck.get< tag::ale, tag::mesh_motion >() ) );
+    const auto& meshforce = g_inputdeck.get< tag::ale, tag::meshforce >();
+    print.item( "Mesh velocity force coefficients", tk::parameters(meshforce) );
+    print.item( "Vorticity multiplier",
+                g_inputdeck.get< tag::ale, tag::vortmult >() );
+    print.item( "Mesh velocity linear solver tolerance",
+                g_inputdeck.get< tag::ale, tag::tolerance >() );
+    print.item( "Mesh velocity linear solver maxit",
+                g_inputdeck.get< tag::ale, tag::maxit >() );
+    const auto& dir = g_inputdeck.get< tag::ale, tag::dirichlet >();
+    if (not dir.empty())
+      print.item( "Mesh velocity Dirichlet BC sideset(s)",
+                  tk::parameters( dir ) );
+    const auto& sym = g_inputdeck.get< tag::ale, tag::symmetry >();
+    if (not sym.empty())
+      print.item( "Mesh velocity symmetry BC sideset(s)",
+                  tk::parameters( sym ) );
+    std::size_t i = 1;
+    for (const auto& m : g_inputdeck.get< tag::ale, tag::move >()) {
+       tk::ctr::UserTable opt;
+       print.item( opt.group() + ' ' + std::to_string(i) + " interpreted as",
+                   opt.name( m.get< tag::fntype >() ) );
+       const auto& s = m.get< tag::sideset >();
+       if (not s.empty())
+         print.item( "Moving sideset(s) with table " + std::to_string(i),
+                     tk::parameters(s));
+       ++i;
+    }
+  }
+
+  // Print I/O filenames
+  print.section( "Input/Output filenames and directories" );
+  print.item( "Input mesh(es)", tk::parameters( m_input ) );
+  const auto& of = g_inputdeck.get< tag::cmd, tag::io, tag::output >();
+  print.item( "Volume field output file(s)",
+              of + ".e-s.<meshid>.<numchares>.<chareid>" );
+  print.item( "Surface field output file(s)",
+              of + "-surf.<surfid>.e-s.<meshid>.<numchares>.<chareid>" );
+  print.item( "History output file(s)", of + ".hist.{pointid}" );
+  print.item( "Diagnostics file",
+              g_inputdeck.get< tag::cmd, tag::io, tag::diag >() );
+  print.item( "Checkpoint/restart directory",
+              g_inputdeck.get< tag::cmd, tag::io, tag::restart >() + '/' );
+
+  // Print output intervals
+  print.section( "Output intervals (in units of iteration count)" );
+  print.item( "TTY", g_inputdeck.get< tag::ttyi>() );
+  print.item( "Field and surface",
+              g_inputdeck.get< tag::field_output, tag::interval >() );
+  print.item( "History",
+              g_inputdeck.get< tag::history_output, tag::interval >() );
+  print.item( "Diagnostics",
+              g_inputdeck.get< tag::diagnostics, tag::interval >() );
+  print.item( "Checkpoint/restart",
+              g_inputdeck.get< tag::cmd, tag::rsfreq >() );
+  auto tf = g_inputdeck.get< tag::field_output, tag::time_interval >();
+  auto th = g_inputdeck.get< tag::history_output, tag::time_interval >();
+  if (tf>0.0 || th>0.0) {
+    print.section( "Output intervals (in units of physics time)" );
+    if (tf > 0.0) print.item( "Field and surface", tf );
+    if (th > 0.0) print.item( "History", th );
+  }
+  const auto& rf = g_inputdeck.get< tag::field_output, tag::time_range >();
+  const auto& rh = g_inputdeck.get< tag::history_output, tag::time_range >();
+  if (not rf.empty() or not rh.empty()) {
+    print.section( "Output time ranges (in units of physics time)" );
+    print.item("Field output { mintime, maxtime, dt }", tk::parameters(rf));
+    print.item("History output { mintime, maxtime, dt }", tk::parameters(rh));
+  }
+
+  //// Print output variables: fields and surfaces
+  //const auto nodeoutvars = g_inputdeck.outvars( tk::Centering::NODE );
+  //const auto elemoutvars = g_inputdeck.outvars( tk::Centering::ELEM );
+  //const auto outsets = g_inputdeck.outsets();
+  //if (!nodeoutvars.empty() || !elemoutvars.empty() || !outsets.empty())
+  //   print.section( "Output fields" );
+  //if (!nodeoutvars.empty())
+  //  print.item( "Node field(s)", tk::parameters(nodeoutvars) );
+  //if (!elemoutvars.empty())
+  //  print.item( "Elem field(s)", tk::parameters(elemoutvars) );
+  //if (!aliases.empty())
+  //  print.item( "Alias(es)", tk::parameters(aliases) );
+  //if (!outsets.empty())
+  //  print.item( "Surface side set(s)", tk::parameters(outsets) );
+
+  // Print output variables: history
+  const auto& pt = g_inputdeck.get< tag::history_output, tag::point >();
+  if (!pt.empty()) {
+    print.section( "Output time history" );
+    for (std::size_t p=0; p<pt.size(); ++p) {
+      const auto& id = pt[p].get< tag::id >();
+      std::stringstream ss;
+      auto prec = g_inputdeck.get< tag::history_output, tag::precision >();
+      ss << std::setprecision( static_cast<int>(prec) );
+      ss << of << ".hist." << id;
+      print.longitem( "At point " + id + ' ' +
+        tk::parameters(pt[p].get<tag::coord>()), ss.str() );
+    }
+  }
+
+  print.endsubsection();
+}
+
+bool
+Transporter::matchBCs( std::map< int, std::vector< std::size_t > >& bnd )
+// *****************************************************************************
+ // Verify that side sets specified in the control file exist in mesh file
+ //! \details This function does two things: (1) it verifies that the side
+ //!   sets used in the input file (either to which boundary conditions (BC)
+ //!   are assigned or listed as field output by the user in the
+ //!   input file) all exist among the side sets read from the input mesh
+ //!   file and errors out if at least one does not, and (2) it matches the
+ //!   side set ids at which the user has configured BCs (or listed as an output
+ //!   surface) to side set ids read from the mesh file and removes those face
+ //!   and node lists associated to side sets that the user did not set BCs or
+ //!   listed as field output on (as they will not need processing further since
+ //!   they will not be used).
+ //! \param[in,out] bnd Node or face lists mapped to side set ids
+ //! \return True if sidesets have been used and found in mesh
+// *****************************************************************************
+{
+  // Query side set ids at which BCs assigned for all BC types for all PDEs
+  using bclist = ctr::bclist::Keys;
+  std::unordered_set< int > usedsets;
+  brigand::for_each< bclist >( UserBC( g_inputdeck, usedsets ) );
+
+  // Query side sets of time dependent BCs (since tag::bctimedep is not a part
+  // of tag::bc)
+  const auto& bcs = g_inputdeck.get< tag::bc >();
+  for (const auto& bci : bcs) {
+    for (const auto& b : bci.get< tag::timedep >()) {
+      for (auto i : b.get< tag::sideset >())
+        usedsets.insert(static_cast<int>(i));
+    }
+  }
+
+  // Query side sets of boundaries prescribed as moving with ALE
+  for (const auto& move : g_inputdeck.get< tag::ale, tag::move >())
+    for (auto i : move.get< tag::sideset >())
+      usedsets.insert(static_cast<int>(i));
+
+  // Add sidesets requested for field output
+  const auto& ss = g_inputdeck.get< tag::cmd, tag::io, tag::surface >();
+  for (const auto& s : ss) {
+    std::stringstream conv( s );
+    int num;
+    conv >> num;
+    usedsets.insert( num );
+  }
 
-          const auto& initiate = b.template get< tag::initiate >();
-          if (initiate == ctr::InitiateType::LINEAR) {
-            boxSrc( t, inpoel, boxelems[bcnt], coord, geoElem, ndofel, R );
-          }
-          ++bcnt;
-        }
-      }
-    }
-
-    //! Evaluate the adaptive indicator and mark the ndof for each element
-    //! \param[in] nunk Number of unknowns
-    //! \param[in] coord Array of nodal coordinates
-    //! \param[in] inpoel Element-node connectivity
-    //! \param[in] fd Face connectivity and boundary conditions object
-    //! \param[in] unk Array of unknowns
-    //! \param[in] prim Array of primitive quantities
-    //! \param[in] indicator p-refinement indicator type
-    //! \param[in] ndof Number of degrees of freedom in the solution
-    //! \param[in] ndofmax Max number of degrees of freedom for p-refinement
-    //! \param[in] tolref Tolerance for p-refinement
-    //! \param[in,out] ndofel Vector of local number of degrees of freedome
-    void eval_ndof( std::size_t nunk,
-                    const tk::UnsMesh::Coords& coord,
-                    const std::vector< std::size_t >& inpoel,
-                    const inciter::FaceData& fd,
-                    const tk::Fields& unk,
-                    const tk::Fields& prim,
-                    inciter::ctr::PrefIndicatorType indicator,
-                    std::size_t ndof,
-                    std::size_t ndofmax,
-                    tk::real tolref,
-                    std::vector< std::size_t >& ndofel ) const
-    {
-      const auto& esuel = fd.Esuel();
-
-      if(indicator == inciter::ctr::PrefIndicatorType::SPECTRAL_DECAY)
-        spectral_decay( 1, nunk, esuel, unk, prim, ndof, ndofmax, tolref,
-          ndofel );
-      else if(indicator == inciter::ctr::PrefIndicatorType::NON_CONFORMITY)
-        non_conformity( nunk, fd.Nbfac(), inpoel, coord, esuel, fd.Esuf(),
-          fd.Inpofa(), unk, ndof, ndofmax, ndofel );
-      else
-        Throw( "No such adaptive indicator type" );
-    }
-
-    //! Compute the minimum time step size
-    //! \param[in] coord Mesh node coordinates
-    //! \param[in] inpoel Mesh element connectivity
-    //! \param[in] fd Face connectivity and boundary conditions object
-    //! \param[in] geoFace Face geometry array
-    //! \param[in] geoElem Element geometry array
-    //! \param[in] ndofel Vector of local number of degrees of freedom
-    //! \param[in] U Solution vector at recent time step
-    //! \return Minimum time step size
-    tk::real dt( const std::array< std::vector< tk::real >, 3 >& coord,
-                 const std::vector< std::size_t >& inpoel,
-                 const inciter::FaceData& fd,
-                 const tk::Fields& geoFace,
-                 const tk::Fields& geoElem,
-                 const std::vector< std::size_t >& ndofel,
-                 const tk::Fields& U,
-                 const tk::Fields&,
-                 const std::size_t /*nielem*/ ) const
-    {
-      const auto rdof = g_inputdeck.get< tag::rdof >();
-
-      const auto& esuf = fd.Esuf();
-      const auto& inpofa = fd.Inpofa();
+  // Find user-configured side set ids among side sets read from mesh file
+  std::unordered_set< int > sidesets_used;
+  for (auto i : usedsets) {       // for all side sets used in control file
+    if (bnd.find(i) != end(bnd))  // used set found among side sets in file
+      sidesets_used.insert( i );  // store side set id configured as BC
+    //else {
+    //  Throw( "Boundary conditions specified on side set " +
+    //    std::to_string(i) + " which does not exist in mesh file" );
+    //}
+  }
+
+  // Remove sidesets not used (will not process those further)
+  tk::erase_if( bnd, [&]( auto& item ) {
+    return sidesets_used.find( item.first ) == end(sidesets_used);
+  });
+
+  return !bnd.empty();
+}
+
+void
+Transporter::createPartitioner()
+// *****************************************************************************
+// Create mesh partitioner AND boundary conditions group
+// *****************************************************************************
+{
+  auto scheme = g_inputdeck.get< tag::scheme >();
+  auto centering = ctr::Scheme().centering( scheme );
+  auto print = printer();
+
+  // Create partitioner callbacks (order important)
+  tk::PartitionerCallback cbp {{
+      CkCallback( CkReductionTarget(Transporter,load), thisProxy )
+    , CkCallback( CkReductionTarget(Transporter,partitioned), thisProxy )
+    , CkCallback( CkReductionTarget(Transporter,distributed), thisProxy )
+    , CkCallback( CkReductionTarget(Transporter,refinserted), thisProxy )
+    , CkCallback( CkReductionTarget(Transporter,refined), thisProxy )
+  }};
+
+  // Create refiner callbacks (order important)
+  tk::RefinerCallback cbr {{
+      CkCallback( CkReductionTarget(Transporter,queriedRef), thisProxy )
+    , CkCallback( CkReductionTarget(Transporter,respondedRef), thisProxy )
+    , CkCallback( CkReductionTarget(Transporter,compatibility), thisProxy )
+    , CkCallback( CkReductionTarget(Transporter,bndint), thisProxy )
+    , CkCallback( CkReductionTarget(Transporter,matched), thisProxy )
+    , CkCallback( CkReductionTarget(Transporter,refined), thisProxy )
+  }};
+
+  // Create sorter callbacks (order important)
+  tk::SorterCallback cbs {{
+      CkCallback( CkReductionTarget(Transporter,queried), thisProxy )
+    , CkCallback( CkReductionTarget(Transporter,responded), thisProxy )
+    , CkCallback( CkReductionTarget(Transporter,discinserted), thisProxy )
+    , CkCallback( CkReductionTarget(Transporter,workinserted), thisProxy )
+  }};
+
+  // Start timer measuring preparation of mesh(es) for partitioning
+  m_timer[ TimerTag::MESH_READ ];
+
+  // Start preparing mesh(es)
+  print.diag( "Reading mesh(es)" );
+
+  // Create (discretization) Scheme chare worker arrays for all meshes
+  for ([[maybe_unused]] const auto& filename : m_input)
+    m_scheme.emplace_back( g_inputdeck.get< tag::scheme >(),
+                           g_inputdeck.get< tag::ale, tag::ale >(),
+                           need_linearsolver(),
+                           centering );
 
-      tk::real rho, u, v, w, rhoE, p, a, vn, dSV_l, dSV_r;
-      std::vector< tk::real > delt( U.nunk(), 0.0 );
-
-      const auto& cx = coord[0];
-      const auto& cy = coord[1];
-      const auto& cz = coord[2];
-
-      // compute internal surface maximum characteristic speed
-      for (std::size_t f=0; f<esuf.size()/2; ++f)
-      {
+  ErrChk( !m_input.empty(), "No input mesh" );
+
+  // Read boundary (side set) data from a list of input mesh files
+  std::size_t meshid = 0;
+  for (const auto& filename : m_input) {
+    // Create mesh reader for reading side sets from file
+    tk::MeshReader mr( filename );
+
+    // Read out total number of mesh points from mesh file
+    m_npoin.push_back( mr.npoin() );
 
-        std::size_t el = static_cast< std::size_t >(esuf[2*f]);
-        auto er = esuf[2*f+1];
-
-        // Number of quadrature points for  face integration
-        std::size_t ng;
-
-        if(er > -1)
-        {
-          auto eR = static_cast< std::size_t >( er );
+    std::map< int, std::vector< std::size_t > > bface;
+    std::map< int, std::vector< std::size_t > > faces;
+    std::map< int, std::vector< std::size_t > > bnode;
+
+    // Read boundary-face connectivity on side sets
+    mr.readSidesetFaces( bface, faces );
+
+    bool bcs_set = false;
+    if (centering == tk::Centering::ELEM) {
 
-          auto ng_l = tk::NGfa(ndofel[el]);
-          auto ng_r = tk::NGfa(ndofel[eR]);
+      // Verify boundarty condition (BC) side sets used exist in mesh file
+      bcs_set = matchBCs( bface );
 
-          // When the number of gauss points for the left and right element are
-          // different, choose the larger ng
-          ng = std::max( ng_l, ng_r );
-        }
-        else
-        {
-          ng = tk::NGfa(ndofel[el]);
-        }
-
-        // arrays for quadrature points
-        std::array< std::vector< tk::real >, 2 > coordgp;
-        std::vector< tk::real > wgp;
+    } else if (centering == tk::Centering::NODE) {
+
+      // Read node lists on side sets
+      bnode = mr.readSidesetNodes();
+      // Verify boundarty condition (BC) side sets used exist in mesh file
+      bool bcnode_set = matchBCs( bnode );
+      bool bcface_set = matchBCs( bface );
+      bcs_set = bcface_set or bcnode_set;
+    }
+
+    // Warn on no BCs
+    if (!bcs_set) print << "\n>>> WARNING: No boundary conditions set\n\n";
 
-        coordgp[0].resize( ng );
-        coordgp[1].resize( ng );
-        wgp.resize( ng );
-
-        // get quadrature point weights and coordinates for triangle
-        tk::GaussQuadratureTri( ng, coordgp, wgp );
-
-        // Extract the left element coordinates
-        std::array< std::array< tk::real, 3>, 4 > coordel_l {{
-          {{ cx[inpoel[4*el  ]], cy[inpoel[4*el  ]], cz[inpoel[4*el  ]] }},
-          {{ cx[inpoel[4*el+1]], cy[inpoel[4*el+1]], cz[inpoel[4*el+1]] }},
-          {{ cx[inpoel[4*el+2]], cy[inpoel[4*el+2]], cz[inpoel[4*el+2]] }},
-          {{ cx[inpoel[4*el+3]], cy[inpoel[4*el+3]], cz[inpoel[4*el+3]] }} }};
+    auto opt = m_scheme[meshid].arrayoptions();
+    // Create empty mesh refiner chare array (bound to workers)
+    m_refiner.push_back( CProxy_Refiner::ckNew(opt) );
+    // Create empty mesh sorter Charm++ chare array (bound to workers)
+    m_sorter.push_back( CProxy_Sorter::ckNew(opt) );
+
+    // Create MeshWriter chare group for mesh
+    m_meshwriter.push_back(
+      tk::CProxy_MeshWriter::ckNew(
+        g_inputdeck.get< tag::field_output, tag::filetype >(),
+        centering,
+        g_inputdeck.get< tag::cmd, tag::benchmark >(),
+        m_input.size() ) );
 
-        // Compute the determinant of Jacobian matrix
-        auto detT_l = 
-           tk::Jacobian(coordel_l[0], coordel_l[1], coordel_l[2], coordel_l[3]);
-
-        // Extract the face coordinates
-        std::array< std::array< tk::real, 3>, 3 > coordfa {{
-          {{ cx[ inpofa[3*f  ] ], cy[ inpofa[3*f  ] ], cz[ inpofa[3*f  ] ] }},
-          {{ cx[ inpofa[3*f+1] ], cy[ inpofa[3*f+1] ], cz[ inpofa[3*f+1] ] }},
-          {{ cx[ inpofa[3*f+2] ], cy[ inpofa[3*f+2] ], cz[ inpofa[3*f+2] ] }}
-        }};
-
-        dSV_l = 0.0;<--- Variable 'dSV_l' is assigned a value that is never used.
-        dSV_r = 0.0;
-
-        // Gaussian quadrature
-        for (std::size_t igp=0; igp<ng; ++igp)
-        {
-          // Compute the coordinates of quadrature point at physical domain
-          auto gp = tk::eval_gp( igp, coordfa, coordgp );
-
-          // Compute the basis function for the left element
-          auto B_l = tk::eval_basis( ndofel[el],
-            tk::Jacobian(coordel_l[0], gp, coordel_l[2], coordel_l[3])/detT_l,
-            tk::Jacobian(coordel_l[0], coordel_l[1], gp, coordel_l[3])/detT_l,
-            tk::Jacobian(coordel_l[0], coordel_l[1], coordel_l[2], gp)/detT_l );
-
-          auto wt = wgp[igp] * geoFace(f,0);
-
-          std::array< std::vector< tk::real >, 2 > ugp;
-
-          // left element
-          for (ncomp_t c=0; c<5; ++c)
-          {
-            auto mark = c*rdof;
-            ugp[0].push_back( U(el, mark) );
+    // Create mesh partitioner Charm++ chare nodegroup for all meshes
+    m_partitioner.push_back(
+      CProxy_Partitioner::ckNew( meshid, filename, cbp, cbr, cbs,
+        thisProxy, m_refiner.back(), m_sorter.back(), m_meshwriter.back(),
+        m_scheme, bface, faces, bnode ) );
+
+    ++meshid;
+  }
+}
+
+void
+Transporter::load( std::size_t meshid, std::size_t nelem )
+// *****************************************************************************
+// Reduction target: the mesh has been read from file on all PEs
+//! \param[in] meshid Mesh id (summed accross all compute nodes)
+//! \param[in] nelem Number of mesh elements per mesh (summed across all
+//!    compute nodes)
+// *****************************************************************************
+{
+  meshid /= static_cast< std::size_t >( CkNumNodes() );
+  Assert( meshid < m_nelem.size(), "MeshId indexing out" );
+  m_nelem[meshid] = nelem;
+
+  // Compute load distribution given total work (nelem) and user-specified
+  // virtualization
+  uint64_t chunksize, remainder;
+  m_nchare[meshid] = static_cast<int>(
+    tk::linearLoadDistributor(
+       g_inputdeck.get< tag::cmd, tag::virtualization >(),
+       m_nelem[meshid], CkNumPes(), chunksize, remainder ) );
+
+  // Store sum of meshids (across all chares, key) for each meshid (value).
+  // This is used to look up the mesh id after collectives that sum their data.
+  m_meshid[ static_cast<std::size_t>(m_nchare[meshid])*meshid ] = meshid;
+  Assert( meshid < m_nelem.size(), "MeshId indexing out" );
 
-            if(ndofel[el] > 1)          //DG(P1)
-              ugp[0][c] +=  U(el, mark+1) * B_l[1]
-                          + U(el, mark+2) * B_l[2]
-                          + U(el, mark+3) * B_l[3];
-
-            if(ndofel[el] > 4)          //DG(P2)
-              ugp[0][c] +=  U(el, mark+4) * B_l[4]
-                          + U(el, mark+5) * B_l[5]
-                          + U(el, mark+6) * B_l[6]
-                          + U(el, mark+7) * B_l[7]
-                          + U(el, mark+8) * B_l[8]
-                          + U(el, mark+9) * B_l[9];
-          }
-
-          rho = ugp[0][0];
-          u = ugp[0][1]/rho;
-          v = ugp[0][2]/rho;
-          w = ugp[0][3]/rho;
-          rhoE = ugp[0][4];
-          p = m_mat_blk[0].compute< EOS::pressure >( rho, u, v, w, rhoE );
-
-          a = m_mat_blk[0].compute< EOS::soundspeed >( rho, p );
-
-          vn = u*geoFace(f,1) + v*geoFace(f,2) + w*geoFace(f,3);
+  // Tell the meshwriter for this mesh the total number of its chares
+  m_meshwriter[meshid].nchare( meshid, m_nchare[meshid] );
+
+  if (++m_nload == m_nelem.size()) {     // all meshes have been loaded
+    m_nload = 0;
+    auto print = printer();
+
+    // Start timer measuring preparation of the mesh for partitioning
+    const auto& timer = tk::cref_find( m_timer, TimerTag::MESH_READ );
+    print.diag( "Mesh read time: " + std::to_string( timer.dsec() ) + " sec" );
+
+    // Print out mesh partitioning configuration
+    print.section( "Mesh partitioning" );
+    print.Item< tk::ctr::PartitioningAlgorithm, tag::partitioning >();
+    print.item( "Virtualization [0.0...1.0]",
+                g_inputdeck.get< tag::cmd, tag::virtualization >() );
+    // Print out initial mesh statistics
+    meshstat( "Initial load distribution" );
+
+    // Query number of initial mesh refinement steps
+    int nref = 0;
+    if (g_inputdeck.get< tag::amr, tag::t0ref >())
+      nref = static_cast<int>(g_inputdeck.get< tag::amr,
+        tag::initial >().size());
 
-          dSV_l = wt * (std::fabs(vn) + a);
-
-          // right element
-          if (er > -1) {
-
-            // nodal coordinates of the right element
-            std::size_t eR = static_cast< std::size_t >( er );
+    m_progMesh.start( print, "Preparing mesh", {{ CkNumPes(), CkNumPes(), nref,
+      m_nchare[0], m_nchare[0], m_nchare[0], m_nchare[0] }} );
+
+    // Partition first mesh
+    m_partitioner[0].partition( m_nchare[0] );
+  }
+}
 
-            // Extract the left element coordinates
-            std::array< std::array< tk::real, 3>, 4 > coordel_r {{
-              {{ cx[inpoel[4*eR  ]], cy[inpoel[4*eR  ]], cz[inpoel[4*eR  ]] }},
-              {{ cx[inpoel[4*eR+1]], cy[inpoel[4*eR+1]], cz[inpoel[4*eR+1]] }},
-              {{ cx[inpoel[4*eR+2]], cy[inpoel[4*eR+2]], cz[inpoel[4*eR+2]] }},
-              {{ cx[inpoel[4*eR+3]], cy[inpoel[4*eR+3]], cz[inpoel[4*eR+3]] }}
-            }};
-
-            // Compute the determinant of Jacobian matrix
-            auto detT_r =
-              tk::Jacobian(coordel_r[0],coordel_r[1],coordel_r[2],coordel_r[3]);
-
-            // Compute the coordinates of quadrature point at physical domain
-            gp = tk::eval_gp( igp, coordfa, coordgp );
-
-            // Compute the basis function for the right element
-            auto B_r = tk::eval_basis( ndofel[eR],
-              tk::Jacobian(coordel_r[0],gp,coordel_r[2],coordel_r[3])/detT_r,
-              tk::Jacobian(coordel_r[0],coordel_r[1],gp,coordel_r[3])/detT_r,
-              tk::Jacobian(coordel_r[0],coordel_r[1],coordel_r[2],gp)/detT_r );
- 
-            for (ncomp_t c=0; c<5; ++c)
-            {
-              auto mark = c*rdof;
-              ugp[1].push_back( U(eR, mark) );
-
-              if(ndofel[eR] > 1)          //DG(P1)
-                ugp[1][c] +=  U(eR, mark+1) * B_r[1]
-                            + U(eR, mark+2) * B_r[2]
-                            + U(eR, mark+3) * B_r[3];
-
-              if(ndofel[eR] > 4)         //DG(P2)
-                ugp[1][c] +=  U(eR, mark+4) * B_r[4]
-                            + U(eR, mark+5) * B_r[5]
-                            + U(eR, mark+6) * B_r[6]
-                            + U(eR, mark+7) * B_r[7]
-                            + U(eR, mark+8) * B_r[8]
-                            + U(eR, mark+9) * B_r[9];
-            }
-
-            rho = ugp[1][0];
-            u = ugp[1][1]/rho;
-            v = ugp[1][2]/rho;
-            w = ugp[1][3]/rho;
-            rhoE = ugp[1][4];
-            p = m_mat_blk[0].compute< EOS::pressure >( rho, u, v, w, rhoE );
-            a = m_mat_blk[0].compute< EOS::soundspeed >( rho, p );
-
-            vn = u*geoFace(f,1) + v*geoFace(f,2) + w*geoFace(f,3);
-
-            dSV_r = wt * (std::fabs(vn) + a);
-            delt[eR] += std::max( dSV_l, dSV_r );
-          }
-
-          delt[el] += std::max( dSV_l, dSV_r );
-        }
-      }
+void
+Transporter::partitioned( std::size_t meshid )
+// *****************************************************************************
+// Reduction target: a mesh has been partitioned
+//! \param[in] meshid Mesh id
+// *****************************************************************************
+{
+  if (++m_npart == m_nelem.size()) {     // all meshes have been partitioned
+    m_npart = 0;
+  } else { // partition next mesh
+    m_partitioner[meshid+1].partition( m_nchare[meshid+1] );
+  }
+}
+
+void
+Transporter::distributed( std::size_t meshid )
+// *****************************************************************************
+// Reduction target: all compute nodes have distributed their mesh after
+// partitioning
+//! \param[in] meshid Mesh id
+// *****************************************************************************
+{
+  m_partitioner[meshid].refine();
+}
+
+void
+Transporter::refinserted( std::size_t meshid, std::size_t error )
+// *****************************************************************************
+// Reduction target: all compute nodes have created the mesh refiners
+//! \param[in] meshid Mesh id (aggregated across all compute nodes with operator
+//!   max)
+//! \param[in] error Error code (aggregated across all compute nodes with
+//!   operator max)
+// *****************************************************************************
+{
+  if (error) {
+
+    printer() << "\n>>> ERROR: A worker chare was not assigned any mesh "
+              "elements after distributing mesh " + std::to_string(meshid) +
+              ". This can happen in SMP-mode with a large +ppn "
+              "parameter (number of worker threads per logical node) and is "
+              "most likely the fault of the mesh partitioning algorithm not "
+              "tolerating the case when it is asked to divide the "
+              "computational domain into a number of partitions different "
+              "than the number of ranks it is called on, i.e., in case of "
+              "overdecomposition and/or calling the partitioner in SMP mode "
+              "with +ppn larger than 1. Solution 1: Try a different "
+              "partitioning algorithm (e.g., rcb instead of mj). Solution 2: "
+              "Decrease +ppn.";
+    finish( meshid );
+
+  } else {
+
+     m_refiner[meshid].doneInserting();
+
+  }
+}
 
-      tk::real mindt = std::numeric_limits< tk::real >::max();
-      tk::real dgp = 0.0;<--- Variable 'dgp' is assigned a value that is never used.
-
-      // compute allowable dt
-      for (std::size_t e=0; e<fd.Esuel().size()/4; ++e)
-      {
-        dgp = 0.0;
-        if (ndofel[e] == 4)
-        {
-          dgp = 1.0;
-        }
-        else if (ndofel[e] == 10)
-        {
-          dgp = 2.0;
-        }
-
-        // Scale smallest dt with CFL coefficient and the CFL is scaled by (2*p+1)
-        // where p is the order of the DG polynomial by linear stability theory.
-        mindt = std::min( mindt, geoElem(e,0)/ (delt[e] * (2.0*dgp + 1.0)) );
-      }
-
-      return mindt;
-    }
-
-    //! Compute stiff terms for a single element, not implemented here
-    // //! \param[in] e Element number
-    // //! \param[in] geoElem Element geometry array
-    // //! \param[in] inpoel Element-node connectivity
-    // //! \param[in] coord Array of nodal coordinates
-    // //! \param[in] U Solution vector at recent time step
-    // //! \param[in] P Primitive vector at recent time step
-    // //! \param[in] ndofel Vector of local number of degrees of freedom
-    // //! \param[in,out] R Right-hand side vector computed
-    void stiff_rhs( std::size_t /*e*/,
-                    const tk::Fields& /*geoElem*/,
-                    const std::vector< std::size_t >& /*inpoel*/,
-                    const tk::UnsMesh::Coords& /*coord*/,
-                    const tk::Fields& /*U*/,
-                    const tk::Fields& /*P*/,
-                    const std::vector< std::size_t >& /*ndofel*/,
-                    tk::Fields& /*R*/ ) const
-    {}
-
-    //! Extract the velocity field at cell nodes. Currently unused.
-    //! \param[in] U Solution vector at recent time step
-    //! \param[in] N Element node indices
-    //! \return Array of the four values of the velocity field
-    std::array< std::array< tk::real, 4 >, 3 >
-    velocity( const tk::Fields& U,
-              const std::array< std::vector< tk::real >, 3 >&,
-              const std::array< std::size_t, 4 >& N ) const
-    {
-      std::array< std::array< tk::real, 4 >, 3 > v;
-      v[0] = U.extract( 1, N );
-      v[1] = U.extract( 2, N );
-      v[2] = U.extract( 3, N );
-      auto r = U.extract( 0, N );
-      std::transform( r.begin(), r.end(), v[0].begin(), v[0].begin(),
-                      []( tk::real s, tk::real& d ){ return d /= s; } );
-      std::transform( r.begin(), r.end(), v[1].begin(), v[1].begin(),
-                      []( tk::real s, tk::real& d ){ return d /= s; } );
-      std::transform( r.begin(), r.end(), v[2].begin(), v[2].begin(),
-                      []( tk::real s, tk::real& d ){ return d /= s; } );
-      return v;
-    }
+void
+Transporter::queriedRef( std::size_t meshid )
+// *****************************************************************************
+// Reduction target: all Refiner chares have queried their boundary edges
+//! \param[in] meshid Mesh id
+// *****************************************************************************
+{
+  m_refiner[meshid].response();
+}
+
+void
+Transporter::respondedRef( std::size_t meshid )
+// *****************************************************************************
+// Reduction target: all Refiner chares have setup their boundary edges
+//! \param[in] meshid Mesh id
+// *****************************************************************************
+{
+  m_refiner[meshid].refine();
+}
+
+void
+Transporter::compatibility( std::size_t meshid )
+// *****************************************************************************
+// Reduction target: all Refiner chares have received a round of edges,
+// and have run their compatibility algorithm
+//! \param[in] meshid Mesh id (aggregated across all chares using operator max)
+//! \details This is called iteratively, until convergence by Refiner. At this
+//!   point all Refiner chares have received a round of edge data (tags whether
+//!   an edge needs to be refined, etc.), and applied the compatibility
+//!   algorithm independent of other Refiner chares. We keep going until the
+//!   mesh is no longer modified by the compatibility algorithm, based on a new
+//!   round of edge data communication started in Refiner::comExtra().
+// *****************************************************************************
+{
+  m_refiner[meshid].correctref();
+}
+
+void
+Transporter::matched( std::size_t summeshid,
+                      std::size_t nextra,
+                      std::size_t nref,
+                      std::size_t nderef,
+                      std::size_t sumrefmode )
+// *****************************************************************************
+// Reduction target: all Refiner chares have matched/corrected the tagging
+// of chare-boundary edges, all chares are ready to perform refinement.
+//! \param[in] summeshid Mesh id (summed across all chares)
+//! \param[in] nextra Sum (across all chares) of the number of edges on each
+//!   chare that need correction along chare boundaries
+//! \param[in] nref Sum of number of refined tetrahedra across all chares.
+//! \param[in] nderef Sum of number of derefined tetrahedra across all chares.
+//! \param[in] sumrefmode Sum of contributions from all chares, encoding
+//!   refinement mode of operation.
+// *****************************************************************************
+{
+  auto meshid = tk::cref_find( m_meshid, summeshid );
+
+  // If at least a single edge on a chare still needs correction, do correction,
+  // otherwise, this mesh refinement step is complete
+  if (nextra > 0) {
+
+    ++m_ncit[meshid];
+    m_refiner[meshid].comExtra();
+
+  } else {
 
-    //! Return a map that associates user-specified strings to functions
-    //! \return Map that associates user-specified strings to functions that
-    //!   compute relevant quantities to be output to file
-    std::map< std::string, tk::GetVarFn > OutVarFn() const
-    { return CompFlowOutVarFn(); }
+    auto print = printer();
+
+    // decode refmode
+    auto refmode = static_cast< Refiner::RefMode >(
+                     sumrefmode / static_cast<std::size_t>(m_nchare[meshid]) );
 
-    //! Return analytic field names to be output to file
-    //! \return Vector of strings labelling analytic fields output in file
-    std::vector< std::string > analyticFieldNames() const
-    { return m_problem.analyticFieldNames( m_ncomp ); }
-
-    //! Return time history field names to be output to file
-    //! \return Vector of strings labeling time history fields output in file
-    std::vector< std::string > histNames() const
-    { return CompFlowHistNames(); }
-
-    //! Return surface field output going to file
-    std::vector< std::vector< tk::real > >
-    surfOutput( const std::map< int, std::vector< std::size_t > >&,
-                tk::Fields& ) const
-    {
-      std::vector< std::vector< tk::real > > s; // punt for now
-      return s;
-    }
-
-    //! Return time history field output evaluated at time history points
-    //! \param[in] h History point data
-    //! \param[in] inpoel Element-node connectivity
-    //! \param[in] coord Array of nodal coordinates
-    //! \param[in] U Array of unknowns
-    std::vector< std::vector< tk::real > >
-    histOutput( const std::vector< HistData >& h,
-                const std::vector< std::size_t >& inpoel,
-                const tk::UnsMesh::Coords& coord,
-                const tk::Fields& U,
-                const tk::Fields& ) const
-    {
-      const auto rdof = g_inputdeck.get< tag::rdof >();
-
-      const auto& x = coord[0];
-      const auto& y = coord[1];
-      const auto& z = coord[2];
-
-      std::vector< std::vector< tk::real > > Up(h.size());
-
-      std::size_t j = 0;
-      for (const auto& p : h) {
-        auto e = p.get< tag::elem >();
-        auto chp = p.get< tag::coord >();
-
-        // Evaluate inverse Jacobian
-        std::array< std::array< tk::real, 3>, 4 > cp{{
-          {{ x[inpoel[4*e  ]], y[inpoel[4*e  ]], z[inpoel[4*e  ]] }},
-          {{ x[inpoel[4*e+1]], y[inpoel[4*e+1]], z[inpoel[4*e+1]] }},
-          {{ x[inpoel[4*e+2]], y[inpoel[4*e+2]], z[inpoel[4*e+2]] }},
-          {{ x[inpoel[4*e+3]], y[inpoel[4*e+3]], z[inpoel[4*e+3]] }} }};
-        auto J = tk::inverseJacobian( cp[0], cp[1], cp[2], cp[3] );
-
-        // evaluate solution at history-point
-        std::array< tk::real, 3 > dc{{chp[0]-cp[0][0], chp[1]-cp[0][1],
-          chp[2]-cp[0][2]}};
-        auto B = tk::eval_basis(rdof, tk::dot(J[0],dc), tk::dot(J[1],dc),
-          tk::dot(J[2],dc));
-        auto uhp = eval_state(m_ncomp, rdof, rdof, e, U, B);
-
-        // store solution in history output vector
-        Up[j].resize(6, 0.0);
-        Up[j][0] = uhp[0];
-        Up[j][1] = uhp[1]/uhp[0];
-        Up[j][2] = uhp[2]/uhp[0];
-        Up[j][3] = uhp[3]/uhp[0];
-        Up[j][4] = uhp[4]/uhp[0];
-        Up[j][5] = m_mat_blk[0].compute< EOS::pressure >( uhp[0], uhp[1]/uhp[0],
-          uhp[2]/uhp[0], uhp[3]/uhp[0], uhp[4] );
-        ++j;
-      }
-
-      return Up;
-    }
-
-    //! Return names of integral variables to be output to diagnostics file
-    //! \return Vector of strings labelling integral variables output
-    std::vector< std::string > names() const
-    { return m_problem.names( m_ncomp ); }
-
-    //! Return analytic solution (if defined by Problem) at xi, yi, zi, t
-    //! \param[in] xi X-coordinate at which to evaluate the analytic solution
-    //! \param[in] yi Y-coordinate at which to evaluate the analytic solution
-    //! \param[in] zi Z-coordinate at which to evaluate the analytic solution
-    //! \param[in] t Physical time at which to evaluate the analytic solution
-    //! \return Vector of analytic solution at given location and time
-    std::vector< tk::real >
-    analyticSolution( tk::real xi, tk::real yi, tk::real zi, tk::real t ) const
-    { return Problem::analyticSolution( m_ncomp, m_mat_blk, xi, yi,
-                                        zi, t ); }
-
-    //! Return analytic solution for conserved variables
-    //! \param[in] xi X-coordinate at which to evaluate the analytic solution
-    //! \param[in] yi Y-coordinate at which to evaluate the analytic solution
-    //! \param[in] zi Z-coordinate at which to evaluate the analytic solution
-    //! \param[in] t Physical time at which to evaluate the analytic solution
-    //! \return Vector of analytic solution at given location and time
-    std::vector< tk::real >
-    solution( tk::real xi, tk::real yi, tk::real zi, tk::real t ) const
-    { return Problem::initialize( m_ncomp, m_mat_blk, xi, yi, zi, t ); }
-
-    //! Return cell-averaged specific total energy for an element
-    //! \param[in] e Element id for which total energy is required
-    //! \param[in] unk Vector of conserved quantities
-    //! \return Cell-averaged specific total energy for given element
-    tk::real sp_totalenergy(std::size_t e, const tk::Fields& unk) const
-    {
-      const auto rdof = g_inputdeck.get< tag::rdof >();
-
-      return unk(e,4*rdof);
-    }
-
-  private:
-    //! Physics policy
-    const Physics m_physics;
-    //! Problem policy
-    const Problem m_problem;
-    //! Number of components in this PDE system
-    const ncomp_t m_ncomp;
-    //! Riemann solver
-    tk::RiemannFluxFn m_riemann;
-    //! BC configuration
-    BCStateFn m_bc;
-    //! EOS material block
-    std::vector< EOS > m_mat_blk;
-
-    //! Evaluate physical flux function for this PDE system
-    //! \param[in] ncomp Number of scalar components in this PDE system
-    //! \param[in] mat_blk EOS material block
-    //! \param[in] ugp Numerical solution at the Gauss point at which to
-    //!   evaluate the flux
-    //! \return Flux vectors for all components in this PDE system
-    //! \note The function signature must follow tk::FluxFn
-    static tk::FluxFn::result_type
-    flux( [[maybe_unused]] ncomp_t ncomp,
-          const std::vector< EOS >& mat_blk,
-          const std::vector< tk::real >& ugp,
-          const std::vector< std::array< tk::real, 3 > >& )
-    {
-      Assert( ugp.size() == ncomp, "Size mismatch" );
-
-      auto u = ugp[1] / ugp[0];
-      auto v = ugp[2] / ugp[0];
-      auto w = ugp[3] / ugp[0];
-      auto p = mat_blk[0].compute< EOS::pressure >( ugp[0], u, v, w, ugp[4] );
-
-      std::vector< std::array< tk::real, 3 > > fl( ugp.size() );
-
-      fl[0][0] = ugp[1];
-      fl[1][0] = ugp[1] * u + p;
-      fl[2][0] = ugp[1] * v;
-      fl[3][0] = ugp[1] * w;
-      fl[4][0] = u * (ugp[4] + p);
-
-      fl[0][1] = ugp[2];
-      fl[1][1] = ugp[2] * u;
-      fl[2][1] = ugp[2] * v + p;
-      fl[3][1] = ugp[2] * w;
-      fl[4][1] = v * (ugp[4] + p);
-
-      fl[0][2] = ugp[3];
-      fl[1][2] = ugp[3] * u;
-      fl[2][2] = ugp[3] * v;
-      fl[3][2] = ugp[3] * w + p;
-      fl[4][2] = w * (ugp[4] + p);
-
-      return fl;
-    }
-
-    //! \brief Boundary state function providing the left and right state of a
-    //!   face at Dirichlet boundaries
-    //! \param[in] ncomp Number of scalar components in this PDE system
-    //! \param[in] mat_blk EOS material block
-    //! \param[in] ul Left (domain-internal) state
-    //! \param[in] x X-coordinate at which to compute the states
-    //! \param[in] y Y-coordinate at which to compute the states
-    //! \param[in] z Z-coordinate at which to compute the states
-    //! \param[in] t Physical time
-    //! \return Left and right states for all scalar components in this PDE
-    //!   system
-    //! \note The function signature must follow tk::StateFn
-    static tk::StateFn::result_type
-    dirichlet( ncomp_t ncomp,
-               const std::vector< EOS >& mat_blk,
-               const std::vector< tk::real >& ul, tk::real x, tk::real y,
-               tk::real z, tk::real t, const std::array< tk::real, 3 >& )
-    {
-      return {{ ul, Problem::initialize( ncomp, mat_blk, x, y, z, t ) }};
-    }
-
-    //! \brief Boundary state function providing the left and right state of a
-    //!   face at symmetry boundaries
-    //! \param[in] ul Left (domain-internal) state
-    //! \param[in] fn Unit face normal
-    //! \return Left and right states for all scalar components in this PDE
-    //!   system
-    //! \note The function signature must follow tk::StateFn
-    static tk::StateFn::result_type
-    symmetry( ncomp_t, const std::vector< EOS >&,
-              const std::vector< tk::real >& ul, tk::real, tk::real, tk::real,
-              tk::real, const std::array< tk::real, 3 >& fn )
-    {
-      std::vector< tk::real > ur(5);
-      // Internal cell velocity components
-      auto v1l = ul[1]/ul[0];
-      auto v2l = ul[2]/ul[0];
-      auto v3l = ul[3]/ul[0];
-      // Normal component of velocity
-      auto vnl = v1l*fn[0] + v2l*fn[1] + v3l*fn[2];
-      // Ghost state velocity components
-      auto v1r = v1l - 2.0*vnl*fn[0];
-      auto v2r = v2l - 2.0*vnl*fn[1];
-      auto v3r = v3l - 2.0*vnl*fn[2];
-      // Boundary condition
-      ur[0] = ul[0];
-      ur[1] = ur[0] * v1r;
-      ur[2] = ur[0] * v2r;
-      ur[3] = ur[0] * v3r;
-      ur[4] = ul[4];
-      return {{ std::move(ul), std::move(ur) }};
-    }
-
-    //! \brief Boundary state function providing the left and right state of a
-    //!   face at farfield boundaries
-    //! \param[in] mat_blk EOS material block
-    //! \param[in] ul Left (domain-internal) state
-    //! \param[in] fn Unit face normal
-    //! \return Left and right states for all scalar components in this PDE
-    //!   system
-    //! \note The function signature must follow tk::StateFn
-    static tk::StateFn::result_type
-    farfield( ncomp_t, const std::vector< EOS >& mat_blk,
-              const std::vector< tk::real >& ul, tk::real, tk::real, tk::real,
-              tk::real, const std::array< tk::real, 3 >& fn )
-    {
-      // Primitive variables from farfield
-      const auto& bc = g_inputdeck.get< tag::bc >()[0];
-      auto frho = bc.get< tag::density >();
-      auto fp   = bc.get< tag::pressure >();
-      const auto& fu = bc.get< tag::velocity >();
-
-      // Speed of sound from farfield
-      auto fa = mat_blk[0].compute< EOS::soundspeed >( frho, fp );
+    if (refmode == Refiner::RefMode::T0REF) {
+
+      if (!g_inputdeck.get< tag::cmd, tag::feedback >()) {
+        ctr::AMRInitial opt;
+        print.diag( { "meshid", "t0ref", "type", "nref", "nderef", "ncorr" },
+                    { std::to_string(meshid),
+                      std::to_string(m_nt0refit[meshid]),
+                      "initial",
+                      std::to_string(nref),
+                      std::to_string(nderef),
+                      std::to_string(m_ncit[meshid]) } );
+        ++m_nt0refit[meshid];
+      }
+      m_progMesh.inc< REFINE >( print );
+
+    } else if (refmode == Refiner::RefMode::DTREF) {
+
+      auto dtref_uni = g_inputdeck.get< tag::amr, tag::dtref_uniform >();
+      print.diag( { "meshid", "dtref", "type", "nref", "nderef", "ncorr" },
+                  { std::to_string(meshid),
+                    std::to_string(++m_ndtrefit[meshid]),
+                    (dtref_uni?"uniform":"error"),
+                    std::to_string(nref),
+                    std::to_string(nderef),
+                    std::to_string(m_ncit[meshid]) },
+                  false );
+
+    } else if (refmode == Refiner::RefMode::OUTREF) {
+
+      print.diag( { "meshid", "outref", "nref", "nderef", "ncorr" },
+                  { std::to_string(meshid),
+                    std::to_string(++m_noutrefit[meshid]),
+                    std::to_string(nref),
+                    std::to_string(nderef),
+                    std::to_string(m_ncit[meshid]) }, false );
+
+    } else if (refmode == Refiner::RefMode::OUTDEREF) {
+
+      print.diag( { "meshid", "outderef", "nref", "nderef", "ncorr" },
+                  { std::to_string(meshid),
+                    std::to_string(++m_noutderefit[meshid]),
+                    std::to_string(nref),
+                    std::to_string(nderef),
+                    std::to_string(m_ncit[meshid]) },
+                  false );
+
+    } else Throw( "RefMode not implemented" );
+
+    m_ncit[meshid] = 0;
+    m_refiner[meshid].perform();
+
+  }
+}
+
+void
+Transporter::bndint( tk::real sx, tk::real sy, tk::real sz, tk::real cb,
+                     tk::real summeshid )
+// *****************************************************************************
+// Compute surface integral across the whole problem and perform leak-test
+//! \param[in] sx X component of vector summed
+//! \param[in] sy Y component of vector summed
+//! \param[in] sz Z component of vector summed
+//! \param[in] cb Invoke callback if positive
+//! \param[in] summeshid Mesh id (summed accross all chares)
+//! \details This function aggregates partial surface integrals across the
+//!   boundary faces of the whole problem. After this global sum a
+//!   non-zero vector result indicates a leak, e.g., a hole in the boundary,
+//!   which indicates an error in the boundary face data structures used to
+//!   compute the partial surface integrals.
+// *****************************************************************************
+{
+  auto meshid = tk::cref_find( m_meshid, static_cast<std::size_t>(summeshid) );
+
+  std::stringstream err;
+  if (cb < 0.0) {
+    err << "Mesh boundary leaky after mesh refinement step; this is due to a "
+     "problem with updating the side sets used to specify boundary conditions "
+     "on faces: ";
+  } else if (cb > 0.0) {
+    err << "Mesh boundary leaky during initialization; this is due to "
+    "incorrect or incompletely specified boundary conditions for a given input "
+    "mesh: ";
+  }
+
+  auto eps = 1.0e-10;
+  if (std::abs(sx) > eps || std::abs(sy) > eps || std::abs(sz) > eps) {
+    err << "Integral result must be a zero vector: " << std::setprecision(12) <<
+           std::abs(sx) << ", " << std::abs(sy) << ", " << std::abs(sz) <<
+           ", eps = " << eps;
+    Throw( err.str() );
+  }
+
+  if (cb > 0.0) m_scheme[meshid].ghosts().resizeComm();
+}
+
+void
+Transporter::refined( std::size_t summeshid,
+                      std::size_t nelem,
+                      std::size_t npoin )
+// *****************************************************************************
+// Reduction target: all chares have refined their mesh
+//! \param[in] summeshid Mesh id (summed accross all Refiner chares)
+//! \param[in] nelem Total number of elements in mesh summed across the
+//!   distributed mesh
+//! \param[in] npoin Total number of mesh points summed across the distributed
+//!   mesh. Note that in parallel this is larger than the number of points in
+//!   the mesh, because the boundary nodes are multi-counted. But we only need
+//!   an equal or larger than npoin for Sorter::setup, so this is okay.
+// *****************************************************************************
+{
+  auto meshid = tk::cref_find( m_meshid, summeshid );
+
+  // Store new number of elements for initially refined mesh
+  m_nelem[meshid] = nelem;
+
+  m_sorter[meshid].doneInserting();
+  m_sorter[meshid].setup( npoin );
+}
+
+void
+Transporter::queried( std::size_t meshid )
+// *****************************************************************************
+// Reduction target: all Sorter chares have queried their boundary edges
+//! \param[in] meshid Mesh id
+// *****************************************************************************
+{
+  m_sorter[meshid].response();
+}
+
+void
+Transporter::responded( std::size_t meshid )
+// *****************************************************************************
+// Reduction target: all Sorter chares have responded with their boundary edges
+//! \param[in] meshid Mesh id
+// *****************************************************************************
+{
+  m_sorter[meshid].start();
+}
+
+void
+Transporter::resized( std::size_t meshid )
+// *****************************************************************************
+// Reduction target: all worker chares have resized their own mesh data after
+// AMR or ALE
+//! \param[in] meshid Mesh id
+//! \note Only used for nodal schemes
+// *****************************************************************************
+{
+  m_scheme[meshid].disc().vol();
+  m_scheme[meshid].bcast< Scheme::lhs >();
+}
+
+void
+Transporter::startEsup( std::size_t meshid )
+// *****************************************************************************
+// Reduction target: all worker chares have generated their own esup
+//! \param[in] meshid Mesh id
+//! \note Only used for cell-centered schemes
+// *****************************************************************************
+{
+  m_scheme[meshid].ghosts().nodeNeighSetup();
+}
+
+void
+Transporter::discinserted( std::size_t meshid )
+// *****************************************************************************
+// Reduction target: all Discretization chares have been inserted
+//! \param[in] meshid Mesh id
+// *****************************************************************************
+{
+  m_scheme[meshid].disc().doneInserting();
+}
+
+void
+Transporter::meshstat( const std::string& header ) const
+// *****************************************************************************
+// Print out mesh statistics
+//! \param[in] header Section header
+// *****************************************************************************
+{
+  auto print = printer();
+
+  print.section( header );
+
+  if (m_nelem.size() > 1) {
+    print.item( "Number of tetrahedra (per mesh)",tk::parameters(m_nelem) );
+    print.item( "Number of points (per mesh)", tk::parameters(m_npoin) );
+    print.item( "Number of work units (per mesh)", tk::parameters(m_nchare) );
+  }
+
+  print.item( "Total number of tetrahedra",
+              std::accumulate( begin(m_nelem), end(m_nelem), 0UL ) );
+  print.item( "Total number of points",
+              std::accumulate( begin(m_npoin), end(m_npoin), 0UL ) );
+  print.item( "Total number of work units",
+              std::accumulate( begin(m_nchare), end(m_nchare), 0 ) );
+
+  print.endsubsection();
+}
+
+bool
+Transporter::need_linearsolver() const
+// *****************************************************************************
+//  Decide if we need a linear solver for ALE
+//! \return True if ALE will neeed a linear solver
+// *****************************************************************************
+{
+  auto smoother = g_inputdeck.get< tag::ale, tag::smoother >();
+
+  if ( g_inputdeck.get< tag::ale, tag::ale >() and
+       (smoother == ctr::MeshVelocitySmootherType::LAPLACE ||
+        smoother == ctr::MeshVelocitySmootherType::HELMHOLTZ) )
+  {
+     return true;
+  } else {
+     return false;
+  }
+}
+
+void
+Transporter::disccreated( std::size_t summeshid, std::size_t npoin )
+// *****************************************************************************
+// Reduction target: all Discretization constructors have been called
+//! \param[in] summeshid Mesh id (summed accross all chares)
+//! \param[in] npoin Total number of mesh points (summed across all chares)
+//!  Note that as opposed to npoin in refined(), this npoin is not
+//!  multi-counted, and thus should be correct in parallel.
+// *****************************************************************************
+{
+  auto meshid = tk::cref_find( m_meshid, summeshid );
+  //std::cout << "Trans: " << meshid << " Transporter::disccreated()\n";
+
+  // Update number of mesh points for mesh, since it may have been refined
+  if (g_inputdeck.get< tag::amr, tag::t0ref >()) m_npoin[meshid] = npoin;
+
+  if (++m_ndisc == m_nelem.size()) { // all Disc arrays have been created
+    m_ndisc = 0;
+    auto print = printer();
+    m_progMesh.end( print );
+    if (g_inputdeck.get< tag::amr, tag::t0ref >())
+      meshstat( "Initially (t<0) refined mesh graph statistics" );
+  }
 
-      // Normal component from farfield
-      auto fvn = fu[0]*fn[0] + fu[1]*fn[1] + fu[2]*fn[2];
-
-      // Mach number from farfield
-      auto fM = fvn / fa;
-
-      // Specific total energy from farfield
-      auto frhoE = mat_blk[0].compute< EOS::totalenergy >( frho, fu[0], fu[1],
-        fu[2], fp );
-
-      // Pressure from internal cell
-      auto p = mat_blk[0].compute< EOS::pressure >( ul[0], ul[1]/ul[0],
-        ul[2]/ul[0], ul[3]/ul[0], ul[4] );
-
-      auto ur = ul;
-
-      if(fM <= -1)                         // Supersonic inflow<--- Assuming that condition 'fM<=-1' is not redundant<--- Assuming that condition 'fM<=-1' is not redundant<--- Assuming that condition 'fM<=-1' is not redundant
-      {
-        // For supersonic inflow, all the characteristics are from outside.
-        // Therefore, we calculate the ghost cell state using the primitive
-        // variables from outside.
-        ur[0] = frho;
-        ur[1] = frho * fu[0];
-        ur[2] = frho * fu[1];
-        ur[3] = frho * fu[2];
-        ur[4] = frhoE;
-      } else if(fM > -1 && fM < 0)       // Subsonic inflow<--- Condition 'fM>-1' is always true<--- Condition 'fM<0' is always false
-      {
-        // For subsonic inflow, there are 1 outgoing characteristcs and 4
-        // incoming characteristic. Therefore, we calculate the ghost cell state
-        // by taking pressure from the internal cell and other quantities from
-        // the outside.
-        ur[0] = frho;
-        ur[1] = frho * fu[0];
-        ur[2] = frho * fu[1];
-        ur[3] = frho * fu[2];
-        ur[4] = mat_blk[0].compute< EOS::totalenergy >( frho, fu[0], fu[1],
-          fu[2], p );
-      } else if(fM >= 0 && fM < 1)       // Subsonic outflow<--- Condition 'fM>=0' is always true
-      {
-        // For subsonic outflow, there are 1 incoming characteristcs and 4
-        // outgoing characteristic. Therefore, we calculate the ghost cell state
-        // by taking pressure from the outside and other quantities from the
-        // internal cell.
-        ur[4] = mat_blk[0].compute< EOS::totalenergy >( ul[0], ul[1]/ul[0],
-          ul[2]/ul[0], ul[3]/ul[0], fp );
-      }
-      // Otherwise, for supersonic outflow, all the characteristics are from
-      // internal cell. Therefore, we calculate the ghost cell state using the
-      // conservative variables from outside.
-
-      return {{ ul, ur }};
-    }
-
-    //! \brief Boundary state function providing the left and right state of a
-    //!   face at extrapolation boundaries
-    //! \param[in] ul Left (domain-internal) state
-    //! \return Left and right states for all scalar components in this PDE
-    //!   system
-    //! \note The function signature must follow tk::StateFn
-    static tk::StateFn::result_type
-    extrapolate( ncomp_t, const std::vector< EOS >&,
-                 const std::vector< tk::real >& ul, tk::real, tk::real,
-                 tk::real, tk::real, const std::array< tk::real, 3 >& )
-    {
-      return {{ ul, ul }};
-    }
+  m_refiner[meshid].sendProxy();
+
+  if (g_inputdeck.get< tag::ale, tag::ale >())
+    m_scheme[meshid].ale().doneInserting();
+
+  if (need_linearsolver())
+    m_scheme[meshid].conjugategradients().doneInserting();
+
+  m_scheme[meshid].disc().vol();
+}
+
+void
+Transporter::workinserted( std::size_t meshid )
+// *****************************************************************************
+// Reduction target: all worker (derived discretization) chares have been
+// inserted
+//! \param[in] meshid Mesh id
+// *****************************************************************************
+{
+  m_scheme[meshid].bcast< Scheme::doneInserting >();
+}
+
+void
+Transporter::diagHeader()
+// *****************************************************************************
+// Configure and write diagnostics file header
+// *****************************************************************************
+{
+  for (std::size_t m=0; m<m_input.size(); ++m) {
+
+   // Output header for diagnostics output file
+    auto mid = m_input.size() > 1 ? std::string( '.' + std::to_string(m) ) : "";
+    tk::DiagWriter dw( g_inputdeck.get< tag::cmd, tag::io, tag::diag >() + mid,
+      g_inputdeck.get< tag::diagnostics, tag::format >(),
+      g_inputdeck.get< tag::diagnostics, tag::precision >() );
+
+    // Collect variables names for integral/diagnostics output
+    std::vector< std::string > var;
+    const auto scheme = g_inputdeck.get< tag::scheme >();
+    if ( scheme == ctr::SchemeType::ALECG ||
+         scheme == ctr::SchemeType::OversetFE )
+      for (const auto& eq : g_cgpde) varnames( eq, var );
+    else if ( scheme == ctr::SchemeType::DG ||
+              scheme == ctr::SchemeType::P0P1 ||
+              scheme == ctr::SchemeType::DGP1 ||
+              scheme == ctr::SchemeType::DGP2 ||
+              scheme == ctr::SchemeType::PDG )
+      for (const auto& eq : g_dgpde) varnames( eq, var );
+    else if (scheme == ctr::SchemeType::FV)
+      for (const auto& eq : g_fvpde) varnames( eq, var );
+    else Throw( "Diagnostics header not handled for discretization scheme" );
+
+    const tk::ctr::Error opt;
+    auto nv = var.size() / m_input.size();
+    std::vector< std::string > d;
+
+    // Add 'L2(var)' for all variables as those are always computed
+    const auto& l2name = opt.name( tk::ctr::ErrorType::L2 );
+    for (std::size_t i=0; i<nv; ++i) d.push_back( l2name + '(' + var[i] + ')' );
+
+    // Query user-requested diagnostics and augment diagnostics file header by
+    // 'err(var)', where 'err' is the error type  configured, and var is the
+    // variable computed, for all variables and all error types configured.
+    const auto& err = g_inputdeck.get< tag::diagnostics, tag::error >();
+    const auto& errname = opt.name( err );
+    for (std::size_t i=0; i<nv; ++i)
+      d.push_back( errname + '(' + var[i] + "-IC)" );
 
-    //! Compute sources corresponding to a propagating front in user-defined box
-    //! \param[in] t Physical time
-    //! \param[in] inpoel Element point connectivity
-    //! \param[in] boxelems Mesh node ids within user-defined box
-    //! \param[in] coord Mesh node coordinates
-    //! \param[in] geoElem Element geometry array
-    //! \param[in] ndofel Vector of local number of degrees of freedome
-    //! \param[in] R Right-hand side vector
-    //! \details This function add the energy source corresponding to a planar
-    //!   wave-front propagating along the z-direction with a user-specified
-    //!   velocity, within a box initial condition, configured by the user.
-    //!   Example (SI) units of the quantities involved:
-    //!    * internal energy content (energy per unit volume): J/m^3
-    //!    * specific energy (internal energy per unit mass): J/kg
-    void boxSrc( tk::real t,
-                 const std::vector< std::size_t >& inpoel,
-                 const std::unordered_set< std::size_t >& boxelems,
-                 const tk::UnsMesh::Coords& coord,
-                 const tk::Fields& geoElem,
-                 const std::vector< std::size_t >& ndofel,
-                 tk::Fields& R ) const
-    {
-      const auto ndof = g_inputdeck.get< tag::ndof >();<--- Variable 'ndof' is assigned a value that is never used.
-      const auto& ic = g_inputdeck.get< tag::ic >();
-      const auto& icbox = ic.get< tag::box >();
+    // Augment diagnostics variables by L2-norm of the residual and total energy
+    if ( scheme == ctr::SchemeType::ALECG ||
+         scheme == ctr::SchemeType::OversetFE ||
+         scheme == ctr::SchemeType::FV )
+    {
+      for (std::size_t i=0; i<nv; ++i) d.push_back( "L2(d" + var[i] + ')' );
+    }
+    d.push_back( "mE" );
+
+    // Write diagnostics header
+    dw.header( d );
+
+  }
+}
+
+void
+Transporter::doneInsertingGhosts(std::size_t meshid)
+// *****************************************************************************
+// Reduction target indicating all "ghosts" insertions are done
+//! \param[in] meshid Mesh id
+// *****************************************************************************
+{
+  m_scheme[meshid].ghosts().doneInserting();
+  m_scheme[meshid].ghosts().startCommSetup();
+}
 
-      for (const auto& b : icbox) {   // for all boxes for this eq
-        std::vector< tk::real > box
-         { b.template get< tag::xmin >(), b.template get< tag::xmax >(),
-           b.template get< tag::ymin >(), b.template get< tag::ymax >(),
-           b.template get< tag::zmin >(), b.template get< tag::zmax >() };
-
-        auto boxenc = b.template get< tag::energy_content >();
-        Assert( boxenc > 0.0, "Box energy content must be nonzero" );
-
-        auto V_ex = (box[1]-box[0]) * (box[3]-box[2]) * (box[5]-box[4]);
-
-        // determine times at which sourcing is initialized and terminated
-        auto iv = b.template get< tag::front_speed >();
-        auto wFront = 0.1;
-        auto tInit = 0.0;
-        auto tFinal = tInit + (box[5] - box[4] - 2.0*wFront) / std::fabs(iv);
-        auto aBox = (box[1]-box[0]) * (box[3]-box[2]);
-
-        const auto& cx = coord[0];
-        const auto& cy = coord[1];
-        const auto& cz = coord[2];
-
-        if (t >= tInit && t <= tFinal) {
-          // The energy front is assumed to have a half-sine-wave shape. The
-          // half wave-length is the width of the front. At t=0, the center of
-          // this front (i.e. the peak of the partial-sine-wave) is at X_0 +
-          // W_0.  W_0 is calculated based on the width of the front and the
-          // direction of propagation (which is assumed to be along the
-          // z-direction).  If the front propagation velocity is positive, it
-          // is assumed that the initial position of the energy source is the
-          // minimum z-coordinate of the box; whereas if this velocity is
-          // negative, the initial position is the maximum z-coordinate of the
-          // box.
-
-          // Orientation of box
-          std::array< tk::real, 3 > b_orientn{{
-            b.template get< tag::orientation >()[0],
-            b.template get< tag::orientation >()[1],
-            b.template get< tag::orientation >()[2] }};
-          std::array< tk::real, 3 > b_centroid{{ 0.5*(box[0]+box[1]),
-            0.5*(box[2]+box[3]), 0.5*(box[4]+box[5]) }};
-          // Transform box to reference space
-          std::array< tk::real, 3 > b_min{{box[0], box[2], box[4]}};
-          std::array< tk::real, 3 > b_max{{box[1], box[3], box[5]}};
-          tk::movePoint(b_centroid, b_min);
-          tk::movePoint(b_centroid, b_max);
-
-          // initial center of front
-          tk::real zInit(b_min[2]);
-          if (iv < 0.0) zInit = b_max[2];
-          // current location of front
-          auto z0 = zInit + iv*t;
-          auto z1 = z0 + std::copysign(wFront, iv);
-          tk::real s0(z0), s1(z1);
-          // if velocity of propagation is negative, initial position is z1
-          if (iv < 0.0) {
-            s0 = z1;
-            s1 = z0;
-          }
-          // Sine-wave (positive part of the wave) source term amplitude
-          auto pi = 4.0 * std::atan(1.0);
-          auto amplE = boxenc * V_ex * pi
-            / (aBox * wFront * 2.0 * (tFinal-tInit));
-          //// Square wave (constant) source term amplitude
-          //auto amplE = boxenc * V_ex
-          //  / (aBox * wFront * (tFinal-tInit));
+void
+Transporter::comfinal( std::size_t initial, std::size_t summeshid )
+// *****************************************************************************
+// Reduction target indicating that communication maps have been setup
+//! \param[in] initial Sum of contributions from all chares. If larger than
+//!    zero, we are during time stepping and if zero we are during setup.
+//! \param[in] summeshid Mesh id (summed accross the distributed mesh)
+// *****************************************************************************
+// [Discretization-specific communication maps]
+{
+  auto meshid = tk::cref_find( m_meshid, static_cast<std::size_t>(summeshid) );
+
+  if (initial > 0) {
+    m_scheme[meshid].bcast< Scheme::setup >();
+    // Turn on automatic load balancing
+    if (++m_ncom == m_nelem.size()) { // all worker arrays have finished
+      m_ncom = 0;
+      auto print = printer();
+      m_progWork.end( print );
+      tk::CProxy_LBSwitch::ckNew();
+      print.diag( "Load balancing on (if enabled in Charm++)" );
+    }
+  } else {
+    m_scheme[meshid].bcast< Scheme::lhs >();
+  }
+}
+// [Discretization-specific communication maps]
+
+void
+Transporter::totalvol( tk::real v, tk::real initial, tk::real summeshid )
+// *****************************************************************************
+// Reduction target summing total mesh volume across all workers
+//! \param[in] v Mesh volume summed across the distributed mesh
+//! \param[in] initial Sum of contributions from all chares. If larger than
+//!    zero, we are during setup, if zero, during time stepping.
+//! \param[in] summeshid Mesh id (summed accross the distributed mesh)
+// *****************************************************************************
+{
+  auto meshid = tk::cref_find( m_meshid, static_cast<std::size_t>(summeshid) );
+
+  m_meshvol[meshid] = v;
+
+  if (initial > 0.0)   // during initialization
+    m_scheme[meshid].disc().stat( v );
+  else                  // during ALE or AMR
+    m_scheme[meshid].bcast< Scheme::resized >();
+}
+
+void
+Transporter::minstat( tk::real d0, tk::real d1, tk::real d2, tk::real rmeshid )
+// *****************************************************************************
+// Reduction target yielding minimum mesh statistcs across all workers
+//! \param[in] d0 Minimum mesh statistics collected over all chares
+//! \param[in] d1 Minimum mesh statistics collected over all chares
+//! \param[in] d2 Minimum mesh statistics collected over all chares
+//! \param[in] rmeshid Mesh id as a real
+// *****************************************************************************
+{
+  auto meshid = static_cast<std::size_t>(rmeshid);
+
+  m_minstat[meshid][0] = d0;  // minimum edge length
+  m_minstat[meshid][1] = d1;  // minimum cell volume cubic root
+  m_minstat[meshid][2] = d2;  // minimum number of cells on chare
+
+  minstat_complete(meshid);
+}
 
-          // add source
-          for (auto e : boxelems) {
-            std::array< tk::real, 3 > node{{ geoElem(e,1), geoElem(e,2),
-              geoElem(e,3) }};
-            // Transform node to reference space of box
-            tk::movePoint(b_centroid, node);
-            tk::rotatePoint({{-b_orientn[0], -b_orientn[1], -b_orientn[2]}},
-              node);
-
-            if (node[2] >= s0 && node[2] <= s1) {
-              auto ng = tk::NGvol(ndofel[e]);
+void
+Transporter::maxstat( tk::real d0, tk::real d1, tk::real d2, tk::real rmeshid )
+// *****************************************************************************
+// Reduction target yielding the maximum mesh statistics across all workers
+//! \param[in] d0 Maximum mesh statistics collected over all chares
+//! \param[in] d1 Maximum mesh statistics collected over all chares
+//! \param[in] d2 Maximum mesh statistics collected over all chares
+//! \param[in] rmeshid Mesh id as a real
+// *****************************************************************************
+{
+  auto meshid = static_cast<std::size_t>(rmeshid);
 
-              // arrays for quadrature points
-              std::array< std::vector< tk::real >, 3 > coordgp;
-              std::vector< tk::real > wgp;
+  m_maxstat[meshid][0] = d0;  // maximum edge length
+  m_maxstat[meshid][1] = d1;  // maximum cell volume cubic root
+  m_maxstat[meshid][2] = d2;  // maximum number of cells on chare
 
-              coordgp[0].resize( ng );
-              coordgp[1].resize( ng );
-              coordgp[2].resize( ng );
-              wgp.resize( ng );
-
-              tk::GaussQuadratureTet( ng, coordgp, wgp );
-
-              // Extract the element coordinates
-              std::array< std::array< tk::real, 3>, 4 > coordel{{
-              {{ cx[inpoel[4*e  ]], cy[inpoel[4*e  ]], cz[inpoel[4*e  ]] }},
-              {{ cx[inpoel[4*e+1]], cy[inpoel[4*e+1]], cz[inpoel[4*e+1]] }},
-              {{ cx[inpoel[4*e+2]], cy[inpoel[4*e+2]], cz[inpoel[4*e+2]] }},
-              {{ cx[inpoel[4*e+3]], cy[inpoel[4*e+3]], cz[inpoel[4*e+3]] }}}};
-
-              for (std::size_t igp=0; igp<ng; ++igp) {
-                // Compute the coordinates of quadrature point at physical
-                // domain
-                auto gp = tk::eval_gp( igp, coordel, coordgp );
+  maxstat_complete(meshid);
+}
+
+void
+Transporter::sumstat( tk::real d0, tk::real d1, tk::real d2, tk::real d3,
+                      tk::real d4, tk::real d5, tk::real summeshid )
+// *****************************************************************************
+// Reduction target yielding the sum mesh statistics across all workers
+//! \param[in] d0 Sum mesh statistics collected over all chares
+//! \param[in] d1 Sum mesh statistics collected over all chares
+//! \param[in] d2 Sum mesh statistics collected over all chares
+//! \param[in] d3 Sum mesh statistics collected over all chares
+//! \param[in] d4 Sum mesh statistics collected over all chares
+//! \param[in] d5 Sum mesh statistics collected over all chares
+//! \param[in] summeshid Mesh id (summed accross the distributed mesh)
+// *****************************************************************************
+{
+  auto meshid = tk::cref_find( m_meshid, static_cast<std::size_t>(summeshid) );
 
-                // Transform quadrature point to reference space of box
-                tk::movePoint(b_centroid, gp);
-                tk::rotatePoint({{-b_orientn[0], -b_orientn[1], -b_orientn[2]}},
-                  gp);
-
-                // Compute the basis function
-                auto B = tk::eval_basis( ndofel[e], coordgp[0][igp],
-                                         coordgp[1][igp], coordgp[2][igp] );
-
-                // Compute the source term variable
-                std::vector< tk::real > s(5, 0.0);
-                s[4] = amplE * std::sin(pi*(gp[2]-s0)/wFront);
-
-                auto wt = wgp[igp] * geoElem(e, 0);
-
-                tk::update_rhs( ndof, ndofel[e], wt, e, B, s, R );
-              }
-            }
-          }
-        }
-      }
-    }
-};
-
-} // dg::
-
-} // inciter::
-
-#endif // DGCompFlow_h
+  m_avgstat[meshid][0] = d1 / d0;      // average edge length
+  m_avgstat[meshid][1] = d3 / d2;      // average cell volume cubic root
+  m_avgstat[meshid][2] = d5 / d4;      // average number of cells per chare
+
+  sumstat_complete(meshid);
+}
+
+void
+Transporter::pdfstat( CkReductionMsg* msg )
+// *****************************************************************************
+// Reduction target yielding PDF of mesh statistics across all workers
+//! \param[in] msg Serialized PDF
+// *****************************************************************************
+{
+  std::size_t meshid;
+  std::vector< tk::UniPDF > pdf;
+
+  // Deserialize final PDF
+  PUP::fromMem creator( msg->getData() );
+  creator | meshid;<--- Uninitialized variable: meshid
+  creator | pdf;
+  delete msg;
+
+  auto id = std::to_string(meshid);<--- Uninitialized variable: meshid
+
+  // Create new PDF file (overwrite if exists)
+  tk::PDFWriter pdfe( "mesh_edge_pdf." + id + ".txt" );
+  // Output edgelength PDF
+  // cppcheck-suppress containerOutOfBounds
+  pdfe.writeTxt( pdf[0],
+                 tk::ctr::PDFInfo{ {"PDF"}, {}, {"edgelength"}, 0, 0.0 } );
+
+  // Create new PDF file (overwrite if exists)
+  tk::PDFWriter pdfv( "mesh_vol_pdf." + id + ".txt" );
+  // Output cell volume cubic root PDF
+  pdfv.writeTxt( pdf[1],<--- Access out of bounds
+                 tk::ctr::PDFInfo{ {"PDF"}, {}, {"V^{1/3}"}, 0, 0.0 } );
+
+  // Create new PDF file (overwrite if exists)
+  tk::PDFWriter pdfn( "mesh_ntet_pdf." + id + ".txt" );
+  // Output number of cells PDF
+  pdfn.writeTxt( pdf[2],<--- Access out of bounds
+                 tk::ctr::PDFInfo{ {"PDF"}, {}, {"ntets"}, 0, 0.0 } );
+
+  pdfstat_complete(meshid);
+}
+
+void
+Transporter::stat()
+// *****************************************************************************
+// Echo diagnostics on mesh statistics
+// *****************************************************************************
+{
+  auto print = printer();
+
+  if (++m_nstat == m_nelem.size()) {     // stats from all meshes have arrived
+    m_nstat = 0;
+    for (std::size_t i=0; i<m_nelem.size(); ++i) {
+      print.diag(
+        "Mesh " + std::to_string(i) +
+        " distribution statistics: min/max/avg(edgelength) = " +
+        std::to_string( m_minstat[i][0] ) + " / " +
+        std::to_string( m_maxstat[i][0] ) + " / " +
+        std::to_string( m_avgstat[i][0] ) + ", " +
+        "min/max/avg(V^{1/3}) = " +
+        std::to_string( m_minstat[i][1] ) + " / " +
+        std::to_string( m_maxstat[i][1] ) + " / " +
+        std::to_string( m_avgstat[i][1] ) + ", " +
+        "min/max/avg(ntets) = " +
+        std::to_string( static_cast<std::size_t>(m_minstat[i][2]) ) + " / " +
+        std::to_string( static_cast<std::size_t>(m_maxstat[i][2]) ) + " / " +
+        std::to_string( static_cast<std::size_t>(m_avgstat[i][2]) ) );
+    }
+
+    // Print out time integration header to screen
+    inthead( print );
+
+    m_progWork.start( print, "Preparing workers",
+      {{ m_nchare[0], m_nchare[0], m_nchare[0], m_nchare[0], m_nchare[0] }} );
+
+    // Create "derived-class" workers
+    for (std::size_t i=0; i<m_nelem.size(); ++i) m_sorter[i].createWorkers();
+  }
+}
+
+void
+Transporter::boxvol( tk::real* meshdata, int n )
+// *****************************************************************************
+// Reduction target computing total volume of IC mesh blocks and box
+//! \param[in] meshdata Vector containing volumes of all IC mesh blocks,
+//!   volume of IC box, and mesh id as a real summed across the distributed mesh
+//! \param[in] n Size of vector, automatically computed by Charm
+// *****************************************************************************
+{
+  Assert(n>=2, "mesh data size incorrect");
+
+  // extract summed mesh id from vector
+  tk::real summeshid = meshdata[n-1];
+  auto meshid = tk::cref_find( m_meshid, static_cast<std::size_t>(summeshid) );
+
+  // extract summed box volume from vector
+  tk::real v = meshdata[n-2];
+  if (v > 0.0) printer().diag( "Box IC volume: " + std::to_string(v) );
+
+  // extract summed mesh block volumes from the vector
+  std::vector< tk::real > blockvols;
+  for (std::size_t blid=0; blid<(static_cast<std::size_t>(n)-2); ++blid) {
+    blockvols.push_back(meshdata[blid]);
+    if (blockvols[blid] > 0.0)
+      printer().diag( "Mesh block " + std::to_string(blid) +
+        " discrete volume: " + std::to_string(blockvols[blid]) );
+  }
+
+  m_scheme[meshid].bcast< Scheme::box >( v, blockvols );
+}
+
+void
+Transporter::solutionTransferred()
+// *****************************************************************************
+// Reduction target broadcasting to Schemes after mesh transfer
+// *****************************************************************************
+{
+  if (++m_ntrans == m_nelem.size()) {    // all meshes have been loaded
+    m_ntrans = 0;
+    for (auto& m : m_scheme) m.bcast< Scheme::transferSol >();
+  }
+}
+
+void
+Transporter::minDtAcrossMeshes( tk::real* reducndata, [[maybe_unused]] int n )
+// *****************************************************************************
+// Reduction target that computes minimum timestep across all meshes
+//! \param[in] reducndata Vector containing minimum values of dt and mesh-moved
+//!   flags, collected across all meshes
+//! \param[in] n Size of vector, automatically computed by Charm
+// *****************************************************************************
+{
+  Assert(static_cast<std::size_t>(n-1) == m_nelem.size(),
+    "Incorrectly sized reduction vector");
+  m_dtmsh.push_back(reducndata[0]);
+
+  if (++m_ndtmsh == m_nelem.size()) {    // all meshes have been loaded
+    Assert(m_dtmsh.size() == m_nelem.size(), "Incorrect size of dtmsh");
+
+    // compute minimum dt across meshes
+    tk::real dt = std::numeric_limits< tk::real >::max();
+    for (auto idt : m_dtmsh) dt = std::min(dt, idt);
+
+    // clear dt-vector and counter
+    m_dtmsh.clear();
+    m_ndtmsh = 0;
+
+    // broadcast to advance time step
+    std::size_t ic(0);
+    for (auto& m : m_scheme) {
+      m.bcast< Scheme::advance >( dt, reducndata[ic+1] );
+      ++ic;
+    }
+  }
+}
+
+void
+Transporter::inthead( const InciterPrint& print )
+// *****************************************************************************
+// Print out time integration header to screen
+//! \param[in] print Pretty printer object to use for printing
+// *****************************************************************************
+{
+  auto refined = g_inputdeck.get< tag::field_output, tag::refined >();
+  const auto scheme = g_inputdeck.get< tag::scheme >();
+  if (refined && scheme == ctr::SchemeType::DG) {
+    printer() << "\n>>> WARNING: Ignoring refined field output for DG(P0)\n\n";
+    refined = false;
+  }
+
+  print.inthead( "Time integration", "Navier-Stokes solver",
+  "Legend: it - iteration count\n"
+  "         t - physics time\n"
+  "        dt - physics time step size\n"
+  "       ETE - estimated wall-clock time elapsed (h:m:s)\n"
+  "       ETA - estimated wall-clock time for accomplishment (h:m:s)\n"
+  "       EGT - estimated grind wall-clock time (ms/timestep)\n"
+  "       flg - status flags, legend:\n"
+  "             f - " + std::string(refined ? "refined " : "")
+                      + "field (volume and surface)\n"
+  "             d - diagnostics\n"
+  "             t - physics time history\n"
+  "             h - h-refinement\n"
+  "             l - load balancing\n"
+  "             r - checkpoint\n"
+  "             a - ALE mesh velocity linear solver did not converge\n",
+  "\n      it             t            dt        ETE        ETA        EGT  flg\n"
+    " -------------------------------------------------------------------------\n" );
+}
+
+void
+Transporter::diagnostics( CkReductionMsg* msg )
+// *****************************************************************************
+// Reduction target optionally collecting diagnostics, e.g., residuals
+//! \param[in] msg Serialized diagnostics vector aggregated across all PEs
+//! \note Only used for nodal schemes
+// *****************************************************************************
+{
+  std::size_t meshid, ncomp;
+  std::vector< std::vector< tk::real > > d;
+
+  // Deserialize diagnostics vector
+  PUP::fromMem creator( msg->getData() );
+  creator | meshid;<--- Uninitialized variable: meshid
+  creator | ncomp;<--- Uninitialized variable: ncomp
+  creator | d;
+  delete msg;
+
+  auto id = std::to_string(meshid);<--- Uninitialized variable: meshid<--- Variable 'id' is assigned a value that is never used.
+
+  Assert( ncomp > 0, "Number of scalar components must be positive");<--- Uninitialized variable: ncomp
+  Assert( d.size() == NUMDIAG, "Diagnostics vector size mismatch" );
+
+  for (std::size_t i=0; i<d.size(); ++i)<--- Unsigned less than zero
+     Assert( d[i].size() == ncomp, "Size mismatch at final stage of "
+             "diagnostics aggregation for mesh " + id );
+
+  // Allocate storage for those diagnostics that are always computed
+  std::vector< tk::real > diag( ncomp, 0.0 );
+
+  // Finish computing diagnostics
+  for (std::size_t i=0; i<d[L2SOL].size(); ++i)
+    diag[i] = sqrt( d[L2SOL][i] / m_meshvol[meshid] );<--- Uninitialized variable: meshid
+  
+  // Query user-requested error types to output
+  const auto& error = g_inputdeck.get< tag::diagnostics, tag::error >();
+
+  decltype(ncomp) n = 0;<--- Variable 'n' is assigned a value that is never used.
+  n += ncomp;<--- Variable 'n' is assigned a value that is never used.
+  if (error == tk::ctr::ErrorType::L2) {
+   // Finish computing the L2 norm of the numerical - analytical solution
+   for (std::size_t i=0; i<d[L2ERR].size(); ++i)
+     diag.push_back( sqrt( d[L2ERR][i] / m_meshvol[meshid] ) );<--- Uninitialized variable: meshid
+  } else if (error == tk::ctr::ErrorType::LINF) {
+    // Finish computing the Linf norm of the numerical - analytical solution
+    for (std::size_t i=0; i<d[LINFERR].size(); ++i)
+      diag.push_back( d[LINFERR][i] );
+  }
+
+  // Finish computing the L2 norm of the residual and append
+  const auto scheme = g_inputdeck.get< tag::scheme >();
+  std::vector< tk::real > l2res( d[L2RES].size(), 0.0 );
+  if (scheme == ctr::SchemeType::ALECG || scheme == ctr::SchemeType::OversetFE) {
+    for (std::size_t i=0; i<d[L2RES].size(); ++i) {
+      l2res[i] = std::sqrt( d[L2RES][i] / m_meshvol[meshid] );<--- Uninitialized variable: meshid
+      diag.push_back( l2res[i] );
+    }
+  }
+  else if (scheme == ctr::SchemeType::FV) {
+    for (std::size_t i=0; i<d[L2RES].size(); ++i) {
+      l2res[i] = std::sqrt( d[L2RES][i] );
+      diag.push_back( l2res[i] );
+    }
+  }
+
+  // Append total energy
+  diag.push_back( d[TOTALSOL][0] );
+
+  // Append diagnostics file at selected times
+  auto filename = g_inputdeck.get< tag::cmd, tag::io, tag::diag >();
+  if (m_nelem.size() > 1) filename += '.' + id;
+  tk::DiagWriter dw( filename,
+    g_inputdeck.get< tag::diagnostics, tag::format >(),
+    g_inputdeck.get< tag::diagnostics, tag::precision >(),
+    std::ios_base::app );
+  dw.diag( static_cast<uint64_t>(d[ITER][0]), d[TIME][0], d[DT][0], diag );
+
+  // Continue time step
+  m_scheme[meshid].bcast< Scheme::refine >( l2res );<--- Uninitialized variable: meshid
+}
+
+void
+Transporter::resume()
+// *****************************************************************************
+// Resume execution from checkpoint/restart files
+//! \details This is invoked by Charm++ after the checkpoint is done, as well as
+//!   when the restart (returning from a checkpoint) is complete
+// *****************************************************************************
+{
+  if (std::any_of(begin(m_finished), end(m_finished), [](auto f){return !f;})) {
+    // If just restarted from a checkpoint, Main( CkMigrateMessage* msg ) has
+    // increased nrestart in g_inputdeck, but only on PE 0, so broadcast.
+    auto nrestart = g_inputdeck.get< tag::cmd, tag::io, tag::nrestart >();
+    for (std::size_t i=0; i<m_nelem.size(); ++i)
+      m_scheme[i].bcast< Scheme::evalLB >( nrestart );
+  } else
+    mainProxy.finalize();
+}
+
+void
+Transporter::checkpoint( std::size_t finished, std::size_t meshid )
+// *****************************************************************************
+// Save checkpoint/restart files
+//! \param[in] finished Nonzero if finished with time stepping
+//! \param[in] meshid Mesh id
+// *****************************************************************************
+{
+  m_finished[meshid] = finished;
+
+  if (++m_nchk == m_nelem.size()) { // all worker arrays have checkpointed
+    m_nchk = 0;
+    if (not g_inputdeck.get< tag::cmd, tag::benchmark >()) {
+      const auto& restart = g_inputdeck.get< tag::cmd, tag::io, tag::restart >();
+      CkCallback res( CkIndex_Transporter::resume(), thisProxy );
+      CkStartCheckpoint( restart.c_str(), res );
+    } else {
+      resume();
+    }
+  }
+}
+
+void
+Transporter::finish( std::size_t meshid )
+// *****************************************************************************
+// Normal finish of time stepping
+//! \param[in] meshid Mesh id
+// *****************************************************************************
+{
+  checkpoint( /* finished = */ 1, meshid );
+}
+
+#include "NoWarning/transporter.def.h"
 
diff --git a/Debug/cppcheck/56.html b/Debug/cppcheck/56.html index e7c6b45bbac7..aaf6354518c8 100644 --- a/Debug/cppcheck/56.html +++ b/Debug/cppcheck/56.html @@ -152,12 +152,12 @@
   1
@@ -1772,1619 +1772,3065 @@ 

Cppcheck report - [

// *****************************************************************************
+1613
+1614
+1615
+1616
+1617
+1618
+1619
+1620
+1621
+1622
+1623
+1624
+1625
+1626
+1627
+1628
+1629
+1630
+1631
+1632
+1633
+1634
+1635
+1636
+1637
+1638
+1639
+1640
+1641
+1642
+1643
+1644
+1645
+1646
+1647
+1648
+1649
+1650
+1651
+1652
+1653
+1654
+1655
+1656
+1657
+1658
+1659
+1660
+1661
+1662
+1663
+1664
+1665
+1666
+1667
+1668
+1669
+1670
+1671
+1672
+1673
+1674
+1675
+1676
+1677
+1678
+1679
+1680
+1681
+1682
+1683
+1684
+1685
+1686
+1687
+1688
+1689
+1690
+1691
+1692
+1693
+1694
+1695
+1696
+1697
+1698
+1699
+1700
+1701
+1702
+1703
+1704
+1705
+1706
+1707
+1708
+1709
+1710
+1711
+1712
+1713
+1714
+1715
+1716
+1717
+1718
+1719
+1720
+1721
+1722
+1723
+1724
+1725
+1726
+1727
+1728
+1729
+1730
+1731
+1732
+1733
+1734
+1735
+1736
+1737
+1738
+1739
+1740
+1741
+1742
+1743
+1744
+1745
+1746
+1747
+1748
+1749
+1750
+1751
+1752
+1753
+1754
+1755
+1756
+1757
+1758
+1759
+1760
+1761
+1762
+1763
+1764
+1765
+1766
+1767
+1768
+1769
+1770
+1771
+1772
+1773
+1774
+1775
+1776
+1777
+1778
+1779
+1780
+1781
+1782
+1783
+1784
+1785
+1786
+1787
+1788
+1789
+1790
+1791
+1792
+1793
+1794
+1795
+1796
+1797
+1798
+1799
+1800
+1801
+1802
+1803
+1804
+1805
+1806
+1807
+1808
+1809
+1810
+1811
+1812
+1813
+1814
+1815
+1816
+1817
+1818
+1819
+1820
+1821
+1822
+1823
+1824
+1825
+1826
+1827
+1828
+1829
+1830
+1831
+1832
+1833
+1834
+1835
+1836
+1837
+1838
+1839
+1840
+1841
+1842
+1843
+1844
+1845
+1846
+1847
+1848
+1849
+1850
+1851
+1852
+1853
+1854
+1855
+1856
+1857
+1858
+1859
+1860
+1861
+1862
+1863
+1864
+1865
+1866
+1867
+1868
+1869
+1870
+1871
+1872
+1873
+1874
+1875
+1876
+1877
+1878
+1879
+1880
+1881
+1882
+1883
+1884
+1885
+1886
+1887
+1888
+1889
+1890
+1891
+1892
+1893
+1894
+1895
+1896
+1897
+1898
+1899
+1900
+1901
+1902
+1903
+1904
+1905
+1906
+1907
+1908
+1909
+1910
+1911
+1912
+1913
+1914
+1915
+1916
+1917
+1918
+1919
+1920
+1921
+1922
+1923
+1924
+1925
+1926
+1927
+1928
+1929
+1930
+1931
+1932
+1933
+1934
+1935
+1936
+1937
+1938
+1939
+1940
+1941
+1942
+1943
+1944
+1945
+1946
+1947
+1948
+1949
+1950
+1951
+1952
+1953
+1954
+1955
+1956
+1957
+1958
+1959
+1960
+1961
+1962
+1963
+1964
+1965
+1966
+1967
+1968
+1969
+1970
+1971
+1972
+1973
+1974
+1975
+1976
+1977
+1978
+1979
+1980
+1981
+1982
+1983
+1984
+1985
+1986
+1987
+1988
+1989
+1990
+1991
+1992
+1993
+1994
+1995
+1996
+1997
+1998
+1999
+2000
+2001
+2002
+2003
+2004
+2005
+2006
+2007
+2008
+2009
+2010
+2011
+2012
+2013
+2014
+2015
+2016
+2017
+2018
+2019
+2020
+2021
+2022
+2023
+2024
+2025
+2026
+2027
+2028
+2029
+2030
+2031
+2032
+2033
+2034
+2035
+2036
+2037
+2038
+2039
+2040
+2041
+2042
+2043
+2044
+2045
+2046
+2047
+2048
+2049
+2050
+2051
+2052
+2053
+2054
+2055
+2056
+2057
+2058
+2059
+2060
+2061
+2062
+2063
+2064
+2065
+2066
+2067
+2068
+2069
+2070
+2071
+2072
+2073
+2074
+2075
+2076
+2077
+2078
+2079
+2080
+2081
+2082
+2083
+2084
+2085
+2086
+2087
+2088
+2089
+2090
+2091
+2092
+2093
+2094
+2095
+2096
+2097
+2098
+2099
+2100
+2101
+2102
+2103
+2104
+2105
+2106
+2107
+2108
+2109
+2110
+2111
+2112
+2113
+2114
+2115
+2116
+2117
+2118
+2119
+2120
+2121
+2122
+2123
+2124
+2125
+2126
+2127
+2128
+2129
+2130
+2131
+2132
+2133
+2134
+2135
+2136
+2137
+2138
+2139
+2140
+2141
+2142
+2143
+2144
+2145
+2146
+2147
+2148
+2149
+2150
+2151
+2152
+2153
+2154
+2155
+2156
+2157
+2158
+2159
+2160
+2161
+2162
+2163
+2164
+2165
+2166
+2167
+2168
+2169
+2170
+2171
+2172
+2173
+2174
+2175
+2176
+2177
+2178
+2179
+2180
+2181
+2182
+2183
+2184
+2185
+2186
+2187
+2188
+2189
+2190
+2191
+2192
+2193
+2194
+2195
+2196
+2197
+2198
+2199
+2200
+2201
+2202
+2203
+2204
+2205
+2206
+2207
+2208
+2209
+2210
+2211
+2212
+2213
+2214
+2215
+2216
+2217
+2218
+2219
+2220
+2221
+2222
+2223
+2224
+2225
+2226
+2227
+2228
+2229
+2230
+2231
+2232
+2233
+2234
+2235
+2236
+2237
+2238
+2239
+2240
+2241
+2242
+2243
+2244
+2245
+2246
+2247
+2248
+2249
+2250
+2251
+2252
+2253
+2254
+2255
+2256
+2257
+2258
+2259
+2260
+2261
+2262
+2263
+2264
+2265
+2266
+2267
+2268
+2269
+2270
+2271
+2272
+2273
+2274
+2275
+2276
+2277
+2278
+2279
+2280
+2281
+2282
+2283
+2284
+2285
+2286
+2287
+2288
+2289
+2290
+2291
+2292
+2293
+2294
+2295
+2296
+2297
+2298
+2299
+2300
+2301
+2302
+2303
+2304
+2305
+2306
+2307
+2308
+2309
+2310
+2311
+2312
+2313
+2314
+2315
+2316
+2317
+2318
+2319
+2320
+2321
+2322
+2323
+2324
+2325
+2326
+2327
+2328
+2329
+2330
+2331
+2332
+2333
+2334
+2335
+2336
// *****************************************************************************
 /*!
-  \file      src/PDE/CompFlow/CGCompFlow.hpp
+  \file      src/Inciter/DG.cpp
   \copyright 2012-2015 J. Bakosi,
              2016-2018 Los Alamos National Security, LLC.,
              2019-2021 Triad National Security, LLC.
              All rights reserved. See the LICENSE file for details.
-  \brief     Compressible single-material flow using continuous Galerkin
-  \details   This file implements the physics operators governing compressible
-    single-material flow using continuous Galerkin discretization.
-*/
-// *****************************************************************************
-#ifndef CGCompFlow_h
-#define CGCompFlow_h
+  \brief     DG advances a system of PDEs with the discontinuous Galerkin scheme
+  \details   DG advances a system of partial differential equations (PDEs) using
+    discontinuous Galerkin (DG) finite element (FE) spatial discretization (on
+    tetrahedron elements) combined with Runge-Kutta (RK) time stepping.
+  \see The documentation in DG.h.
+*/
+// *****************************************************************************
 
-#include <cmath>
-#include <algorithm>
-#include <unordered_set>
-#include <unordered_map>
-
-#include "DerivedData.hpp"
-#include "Exception.hpp"
-#include "Vector.hpp"
-#include "Mesh/Around.hpp"
-#include "Reconstruction.hpp"
-#include "Problem/FieldOutput.hpp"
-#include "Problem/BoxInitialization.hpp"
-#include "Riemann/Rusanov.hpp"
-#include "NodeBC.hpp"
-#include "EoS/EOS.hpp"
-#include "History.hpp"
-#include "Table.hpp"
-
-namespace inciter {
-
-extern ctr::InputDeck g_inputdeck;
-
-namespace cg {
-
-//! \brief CompFlow used polymorphically with tk::CGPDE
-//! \details The template arguments specify policies and are used to configure
-//!   the behavior of the class. The policies are:
-//!   - Physics - physics configuration, see PDE/CompFlow/Physics.h
-//!   - Problem - problem configuration, see PDE/CompFlow/Problems.h
-//! \note The default physics is Euler, set in inciter::deck::check_compflow()
-template< class Physics, class Problem >
-class CompFlow {
-
-  private:
-    using ncomp_t = tk::ncomp_t;
-    using eq = tag::compflow;
-    using real = tk::real;
-
-    static constexpr std::size_t m_ncomp = 5;
-    static constexpr real muscl_eps = 1.0e-9;
-    static constexpr real muscl_const = 1.0/3.0;
-    static constexpr real muscl_m1 = 1.0 - muscl_const;
-    static constexpr real muscl_p1 = 1.0 + muscl_const;
-
-  public:
-    //! \brief Constructor
-    explicit CompFlow() :
-      m_physics(),
-      m_problem(),
-      m_stagCnf(),
-      m_fr(),
-      m_fp(),
-      m_fu()
-    {
-      Assert( g_inputdeck.get< tag::ncomp >() == m_ncomp,
-       "Number of CompFlow PDE components must be " + std::to_string(m_ncomp) );
+#include <algorithm>
+#include <numeric>
+#include <sstream>
+
+#include "DG.hpp"
+#include "Discretization.hpp"
+#include "DGPDE.hpp"
+#include "DiagReducer.hpp"
+#include "DerivedData.hpp"
+#include "ElemDiagnostics.hpp"
+#include "Inciter/InputDeck/InputDeck.hpp"
+#include "Refiner.hpp"
+#include "Limiter.hpp"
+#include "Reorder.hpp"
+#include "Vector.hpp"
+#include "Around.hpp"
+#include "Integrate/Basis.hpp"
+#include "FieldOutput.hpp"
+#include "ChareStateCollector.hpp"
+#include "PDE/MultiMat/MultiMatIndexing.hpp"
+
+namespace inciter {
+
+extern ctr::InputDeck g_inputdeck;
+extern std::vector< DGPDE > g_dgpde;
+
+//! Runge-Kutta coefficients
+static const std::array< std::array< tk::real, 3 >, 2 >
+  rkcoef{{ {{ 0.0, 3.0/4.0, 1.0/3.0 }}, {{ 1.0, 1.0/4.0, 2.0/3.0 }} }};
+
+//! Implicit-Explicit Runge-Kutta Coefficients
+static const tk::real rk_gamma = (2.0-std::sqrt(2.0))/2.0;
+static const tk::real rk_delta = -2.0*std::sqrt(2.0)/3.0;
+static const tk::real c2 =
+  (27.0 + std::pow(2187.0-1458.0*std::sqrt(2.0),1.0/3.0)
+   + 9.0*std::pow(3.0+2.0*std::sqrt(2.0),1.0/3.0))/54.0;
+static const tk::real c3 = c2/(6.0*std::pow(c2,2.0)-3.0*c2+1.0);
+static const tk::real b2 = (3.0*c2-1.0)/(6.0*std::pow(c2,2.0));
+static const tk::real b3 =
+  (6.0*std::pow(c2,2.0)-3.0*c2+1.0)/(6.0*std::pow(c2,2.0));
+static const tk::real a22_impl = c2;
+static const tk::real a21_expl = c2;
+static const tk::real a32_expl = c3;
+static const tk::real a33_impl =
+  (1.0/6.0-b2*std::pow(c2,2.0)-b3*c2*c3)/(b3*(c3-c2));
+static const tk::real a32_impl = a33_impl-c3;
+static const std::array< std::array< tk::real, 3 >, 2 >
+  expl_rkcoef{{ {{ 0.0, 0.0, b2 }},
+                {{ a21_expl, a32_expl, b3 }} }};
+static const std::array< std::array< tk::real, 3 >, 2>
+  impl_rkcoef{{ {{ 0.0, a32_impl, b2 }},
+                {{ a22_impl, a33_impl, b3}} }};
+
+} // inciter::
+
+extern tk::CProxy_ChareStateCollector stateProxy;
 
-      // EoS initialization
-      const auto& matprop =
-        g_inputdeck.get< tag::material >();
-      const auto& matidxmap =
-        g_inputdeck.get< tag::matidxmap >();
-      auto mateos = matprop[matidxmap.get< tag::eosidx >()[0]].get<tag::eos>();
-      m_mat_blk.emplace_back( mateos, EqType::compflow, 0 );
-
-      // Boundary condition configurations
-      for (const auto& bci : g_inputdeck.get< tag::bc >()) {
-        // store stag-point coordinates
-        auto& spt = std::get< 0 >(m_stagCnf);
-        spt.insert( spt.end(), bci.get< tag::stag_point >().begin(),
-          bci.get< tag::stag_point >().end() );
-        // store stag-radius
-        std::get< 1 >(m_stagCnf).push_back( bci.get< tag::radius >() );
-        // freestream quantities
-        m_fr = bci.get< tag::density >();
-        m_fp = bci.get< tag::pressure >();
-        m_fu = bci.get< tag::velocity >();
-      }
-    }
-
-    //! Determine nodes that lie inside the user-defined IC box and mesh blocks
-    //! \param[in] coord Mesh node coordinates
-    //! \param[in] inpoel Element node connectivity
-    //! \param[in,out] inbox List of nodes at which box user ICs are set for
-    //!    each IC box
-    //! \param[in] elemblkid Element ids associated with mesh block ids where
-    //!   user ICs are set
-    //! \param[in,out] nodeblkid Node ids associated to mesh block ids, where
-    //!   user ICs are set
-    //! \param[in,out] nuserblk number of mesh blocks where user ICs are set
-    void IcBoxNodes( const tk::UnsMesh::Coords& coord,
-      const std::vector< std::size_t >& inpoel,
-      const std::unordered_map< std::size_t, std::set< std::size_t > >& elemblkid,
-      std::vector< std::unordered_set< std::size_t > >& inbox,
-      std::unordered_map< std::size_t, std::set< std::size_t > >& nodeblkid,
-      std::size_t& nuserblk ) const
-    {
-      const auto& x = coord[0];
-      const auto& y = coord[1];
-      const auto& z = coord[2];
-
-      // Detect if user has configured IC boxes
-      const auto& icbox = g_inputdeck.get<tag::ic, tag::box>();
-      if (!icbox.empty()) {
-        std::size_t bcnt = 0;
-        for (const auto& b : icbox) {   // for all boxes for this eq
-          inbox.emplace_back();
-          std::vector< tk::real > box
-            { b.template get< tag::xmin >(), b.template get< tag::xmax >(),
-              b.template get< tag::ymin >(), b.template get< tag::ymax >(),
-              b.template get< tag::zmin >(), b.template get< tag::zmax >() };
-
-          // Determine orientation of box
-          std::array< tk::real, 3 > b_orientn{{
-            b.template get< tag::orientation >()[0],
-            b.template get< tag::orientation >()[1],
-            b.template get< tag::orientation >()[2] }};
-          std::array< tk::real, 3 > b_centroid{{ 0.5*(box[0]+box[1]),
-            0.5*(box[2]+box[3]), 0.5*(box[4]+box[5]) }};
-
-          const auto eps = std::numeric_limits< tk::real >::epsilon();
-          // Determine which nodes lie in the IC box
-          if ( std::any_of( begin(box), end(box), [=](auto p)
-                            { return abs(p) > eps; } ) )
-          {
-            // Transform box to reference space
-            std::array< tk::real, 3 > b_min{{box[0], box[2], box[4]}};
-            std::array< tk::real, 3 > b_max{{box[1], box[3], box[5]}};
-            tk::movePoint(b_centroid, b_min);
-            tk::movePoint(b_centroid, b_max);
-
-            for (ncomp_t i=0; i<x.size(); ++i) {
-              std::array< tk::real, 3 > node{{ x[i], y[i], z[i] }};
-              // Transform node to reference space of box
-              tk::movePoint(b_centroid, node);
-              tk::rotatePoint({{-b_orientn[0], -b_orientn[1], -b_orientn[2]}},
-                node);
-              if ( node[0]>b_min[0] && node[0]<b_max[0] &&
-                node[1]>b_min[1] && node[1]<b_max[1] &&
-                node[2]>b_min[2] && node[2]<b_max[2] )
-              {
-                inbox[bcnt].insert( i );
-              }
-            }
-          }
-          ++bcnt;
-        }
-      }
+using inciter::DG;
+
+DG::DG( const CProxy_Discretization& disc,
+        const CProxy_Ghosts& ghostsproxy,
+        const std::map< int, std::vector< std::size_t > >& bface,
+        const std::map< int, std::vector< std::size_t > >& /* bnode */,
+        const std::vector< std::size_t >& triinpoel ) :
+  m_disc( disc ),
+  m_ghosts( ghostsproxy ),
+  m_ndof_NodalExtrm( 3 ), // for the first order derivatives in 3 directions
+  m_nsol( 0 ),
+  m_ninitsol( 0 ),
+  m_nlim( 0 ),
+  m_nnod( 0 ),
+  m_nrefine( 0 ),
+  m_nsmooth( 0 ),
+  m_nreco( 0 ),
+  m_nnodalExtrema( 0 ),
+  m_nstiffeq( g_dgpde[Disc()->MeshId()].nstiffeq() ),
+  m_nnonstiffeq( g_dgpde[Disc()->MeshId()].nnonstiffeq() ),
+  m_u( Disc()->Inpoel().size()/4,
+       g_inputdeck.get< tag::rdof >()*
+       g_inputdeck.get< tag::ncomp >() ),
+  m_un( m_u.nunk(), m_u.nprop() ),
+  m_p( m_u.nunk(), g_inputdeck.get< tag::rdof >()*
+    g_dgpde[Disc()->MeshId()].nprim() ),
+  m_lhs( m_u.nunk(),
+         g_inputdeck.get< tag::ndof >()*
+         g_inputdeck.get< tag::ncomp >() ),
+  m_rhs( m_u.nunk(), m_lhs.nprop() ),
+  m_rhsprev( m_u.nunk(), m_lhs.nprop() ),
+  m_stiffrhs( m_u.nunk(), g_inputdeck.get< tag::ndof >()*
+              g_dgpde[Disc()->MeshId()].nstiffeq() ),
+  m_stiffrhsprev( m_u.nunk(), g_inputdeck.get< tag::ndof >()*
+                  g_dgpde[Disc()->MeshId()].nstiffeq() ),
+  m_stiffEqIdx( g_dgpde[Disc()->MeshId()].nstiffeq() ),
+  m_nonStiffEqIdx( g_dgpde[Disc()->MeshId()].nnonstiffeq() ),
+  m_mtInv(
+    tk::invMassMatTaylorRefEl(g_inputdeck.get< tag::rdof >()) ),
+  m_uNodalExtrm(),
+  m_pNodalExtrm(),
+  m_uNodalExtrmc(),
+  m_pNodalExtrmc(),
+  m_npoin( Disc()->Coord()[0].size() ),
+  m_diag(),
+  m_stage( 0 ),
+  m_ndof(),
+  m_numEqDof(),
+  m_uc(),
+  m_pc(),
+  m_ndofc(),
+  m_initial( 1 ),
+  m_uElemfields( m_u.nunk(),
+                 g_inputdeck.get< tag::ncomp >() ),
+  m_pElemfields( m_u.nunk(),
+                 m_p.nprop() / g_inputdeck.get< tag::rdof >() ),
+  m_uNodefields( m_npoin,
+                 g_inputdeck.get< tag::ncomp >() ),
+  m_pNodefields( m_npoin,
+                 m_p.nprop() / g_inputdeck.get< tag::rdof >() ),
+  m_uNodefieldsc(),
+  m_pNodefieldsc(),
+  m_outmesh(),
+  m_boxelems(),
+  m_shockmarker(m_u.nunk(), 1),
+  m_rho0mat()
+// *****************************************************************************
+//  Constructor
+//! \param[in] disc Discretization proxy
+//! \param[in] bface Boundary-faces mapped to side set ids
+//! \param[in] triinpoel Boundary-face connectivity
+// *****************************************************************************
+{
+  if (g_inputdeck.get< tag::cmd, tag::chare >() ||
+      g_inputdeck.get< tag::cmd, tag::quiescence >())
+    stateProxy.ckLocalBranch()->insert( "DG", thisIndex, CkMyPe(), Disc()->It(),
+                                        "DG" );
+
+  // assign number of dofs for each equation in all pde systems
+  g_dgpde[Disc()->MeshId()].numEquationDofs(m_numEqDof);
+
+  // Allocate storage for the vector of nodal extrema
+  m_uNodalExtrm.resize( Disc()->Bid().size(),
+    std::vector<tk::real>( 2 * m_ndof_NodalExtrm *
+    g_inputdeck.get< tag::ncomp >() ) );
+  m_pNodalExtrm.resize( Disc()->Bid().size(),
+    std::vector<tk::real>( 2 * m_ndof_NodalExtrm *
+    m_p.nprop() / g_inputdeck.get< tag::rdof >() ) );
+
+  // Initialization for the buffer vector of nodal extrema
+  resizeNodalExtremac();
 
-      // size IC mesh blocks volume vector
-      const auto& mblks = g_inputdeck.get< tag::ic, tag::meshblock >();
-      // if mesh blocks have been specified for this system
-      if (!mblks.empty()) {
-        std::size_t idMax(0);
-        for (const auto& imb : mblks) {
-          idMax = std::max(idMax, imb.get< tag::blockid >());
-        }
-        // size is idMax+1 since block ids are usually 1-based
-        nuserblk = nuserblk+idMax+1;
-      }
-
-      // determine node set for IC mesh blocks
-      for (const auto& [blid, elset] : elemblkid) {
-        if (!elset.empty()) {
-          auto& ndset = nodeblkid[blid];
-          for (auto ie : elset) {
-            for (std::size_t i=0; i<4; ++i) ndset.insert(inpoel[4*ie+i]);
-          }
-        }
-      }
-    }
+  usesAtSync = true;    // enable migration at AtSync
+
+  // Enable SDAG wait for initially building the solution vector and limiting
+  if (m_initial) {
+    thisProxy[ thisIndex ].wait4sol();
+    thisProxy[ thisIndex ].wait4refine();
+    thisProxy[ thisIndex ].wait4smooth();
+    thisProxy[ thisIndex ].wait4lim();
+    thisProxy[ thisIndex ].wait4nod();
+    thisProxy[ thisIndex ].wait4reco();
+    thisProxy[ thisIndex ].wait4nodalExtrema();
+  }
+
+  m_ghosts[thisIndex].insert(m_disc, bface, triinpoel, m_u.nunk(),
+    CkCallback(CkIndex_DG::resizeSolVectors(), thisProxy[thisIndex]));
+
+  // global-sync to call doneInserting on m_ghosts
+  auto meshid = Disc()->MeshId();
+  contribute( sizeof(std::size_t), &meshid, CkReduction::nop,
+    CkCallback(CkReductionTarget(Transporter,doneInsertingGhosts),
+    Disc()->Tr()) );
+}
 
-    //! Initalize the compressible flow equations, prepare for time integration
-    //! \param[in] coord Mesh node coordinates
-    //! \param[in,out] unk Array of unknowns
-    //! \param[in] t Physical time
-    //! \param[in] V Discrete volume of user-defined IC box
-    //! \param[in] inbox List of nodes at which box user ICs are set (for each
-    //!    box IC)
-    //! \param[in] nodeblkid Node ids associated to mesh block ids, where
-    //!   user ICs are set
-    //! \param[in] blkvols Vector of discrete volumes of each block where user
-    //!   ICs are set
-    void initialize(
-      const std::array< std::vector< real >, 3 >& coord,
-      tk::Fields& unk,
-      real t,
-      real V,
-      const std::vector< std::unordered_set< std::size_t > >& inbox,
-      const std::vector< tk::real >& blkvols,
-      const std::unordered_map< std::size_t, std::set< std::size_t > >&
-        nodeblkid ) const
-    {
-      Assert( coord[0].size() == unk.nunk(), "Size mismatch" );
-
-      const auto& x = coord[0];
-      const auto& y = coord[1];
-      const auto& z = coord[2];
+void
+DG::registerReducers()
+// *****************************************************************************
+//  Configure Charm++ reduction types
+//! \details Since this is a [initnode] routine, the runtime system executes the
+//!   routine exactly once on every logical node early on in the Charm++ init
+//!   sequence. Must be static as it is called without an object. See also:
+//!   Section "Initializations at Program Startup" at in the Charm++ manual
+//!   http://charm.cs.illinois.edu/manuals/html/charm++/manual.html.
+// *****************************************************************************
+{
+  ElemDiagnostics::registerReducers();
+}
+
+void
+DG::ResumeFromSync()
+// *****************************************************************************
+//  Return from migration
+//! \details This is called when load balancing (LB) completes. The presence of
+//!   this function does not affect whether or not we block on LB.
+// *****************************************************************************
+{
+  if (Disc()->It() == 0) Throw( "it = 0 in ResumeFromSync()" );
+
+  if (!g_inputdeck.get< tag::cmd, tag::nonblocking >()) next();
+}
 
-      const auto& ic = g_inputdeck.get< tag::ic >();
-      const auto& icbox = ic.get< tag::box >();
-      const auto& mblks = ic.get< tag::meshblock >();
-
-      const auto eps = 1000.0 * std::numeric_limits< tk::real >::epsilon();
-
-      tk::real bgpre = ic.get< tag::pressure >();
-
-      auto c_v = getmatprop< tag::cv >();
-
-      // Set initial and boundary conditions using problem policy
-      for (ncomp_t i=0; i<x.size(); ++i) {
-        auto s = Problem::initialize( m_ncomp, m_mat_blk, x[i], y[i], z[i], t );
-
-        // initialize the user-defined box IC
-        if (!icbox.empty()) {
-          std::size_t bcnt = 0;
-          for (const auto& b : icbox) { // for all boxes
-            if (inbox.size() > bcnt && inbox[bcnt].find(i) != inbox[bcnt].end())
-            {
-              std::vector< tk::real > box
-              { b.template get< tag::xmin >(), b.template get< tag::xmax >(),
-                b.template get< tag::ymin >(), b.template get< tag::ymax >(),
-                b.template get< tag::zmin >(), b.template get< tag::zmax >() };
-              auto V_ex = (box[1]-box[0]) * (box[3]-box[2]) * (box[5]-box[4]);
-              if (V_ex < eps) V = 1.0;
-              initializeBox<ctr::boxList>( m_mat_blk, V_ex/V,
-                V_ex, t, b, bgpre, c_v, s );
-            }
-            ++bcnt;
-          }
-        }
-
-        // initialize user-defined mesh block ICs
-        for (const auto& b : mblks) { // for all blocks
-          auto blid = b.get< tag::blockid >();
-          auto V_ex = b.get< tag::volume >();
-          if (blid >= blkvols.size()) Throw("Block volume not found");
-          if (nodeblkid.find(blid) != nodeblkid.end()) {
-            const auto& ndset = tk::cref_find(nodeblkid, blid);
-            if (ndset.find(i) != ndset.end()) {
-              initializeBox<ctr::meshblockList>( m_mat_blk,
-                V_ex/blkvols[blid], V_ex, t, b, bgpre, c_v, s );
-            }
-          }
-        }
-
-        unk(i,0) = s[0]; // rho
-        if (stagPoint(x[i],y[i],z[i])) {
-          unk(i,1) = unk(i,2) = unk(i,3) = 0.0;
-        } else {
-          unk(i,1) = s[1]; // rho * u
-          unk(i,2) = s[2]; // rho * v
-          unk(i,3) = s[3]; // rho * w
-        }
-        unk(i,4) = s[4]; // rho * e, e: total = kinetic + internal
-      }
-    }
-
-    //! Query the fluid velocity
-    //! \param[in] u Solution vector of conserved variables
-    //! \param[in,out] v Velocity components
-    void velocity( const tk::Fields& u, tk::UnsMesh::Coords& v ) const {
-      for (std::size_t j=0; j<3; ++j) {
-        // extract momentum
-        v[j] = u.extract_comp( 1+j );
-        Assert( v[j].size() == u.nunk(), "Size mismatch" );
-        // divide by density
-        for (std::size_t i=0; i<u.nunk(); ++i) v[j][i] /= u(i,0);
-      }
-    }
+void
+DG::resizeSolVectors()
+// *****************************************************************************
+// Resize solution vectors after extension due to Ghosts and continue with setup
+// *****************************************************************************
+{
+  // Resize solution vectors, lhs and rhs by the number of ghost tets
+  m_u.resize( myGhosts()->m_nunk );
+  m_un.resize( myGhosts()->m_nunk );
+  m_p.resize( myGhosts()->m_nunk );
+  m_lhs.resize( myGhosts()->m_nunk );
+  m_rhs.resize( myGhosts()->m_nunk );
+  m_rhsprev.resize( myGhosts()->m_nunk );
+  m_stiffrhs.resize( myGhosts()->m_nunk );
+  m_stiffrhsprev.resize( myGhosts()->m_nunk );
+
+  // Size communication buffer for solution and number of degrees of freedom
+  for (auto& n : m_ndofc) n.resize( myGhosts()->m_bid.size() );
+  for (auto& u : m_uc) u.resize( myGhosts()->m_bid.size() );
+  for (auto& p : m_pc) p.resize( myGhosts()->m_bid.size() );
+
+  // Initialize number of degrees of freedom in mesh elements
+  const auto pref = g_inputdeck.get< tag::pref, tag::pref >();
+  if( pref )
+  {
+    const auto ndofmax = g_inputdeck.get< tag::pref, tag::ndofmax >();
+    m_ndof.resize( myGhosts()->m_nunk, ndofmax );
+  }
+  else
+  {
+    const auto ndof = g_inputdeck.get< tag::ndof >();
+    m_ndof.resize( myGhosts()->m_nunk, ndof );
+  }
+
+  // Ensure that we also have all the geometry and connectivity data
+  // (including those of ghosts)
+  Assert( myGhosts()->m_geoElem.nunk() == m_u.nunk(),
+    "GeoElem unknowns size mismatch" );
+
+  // Signal the runtime system that all workers have received their adjacency
+  std::vector< std::size_t > meshdata{ myGhosts()->m_initial, Disc()->MeshId() };
+  contribute( meshdata, CkReduction::sum_ulong,
+    CkCallback(CkReductionTarget(Transporter,comfinal), Disc()->Tr()) );
+}
+
+void
+DG::setup()
+// *****************************************************************************
+// Set initial conditions, generate lhs, output mesh
+// *****************************************************************************
+{
+  if (g_inputdeck.get< tag::cmd, tag::chare >() ||
+      g_inputdeck.get< tag::cmd, tag::quiescence >())
+    stateProxy.ckLocalBranch()->insert( "DG", thisIndex, CkMyPe(), Disc()->It(),
+                                        "setup" );
+
+  auto d = Disc();<--- Variable 'd' is assigned a value that is never used.
+
+  // Basic error checking on sizes of element geometry data and connectivity
+  Assert( myGhosts()->m_geoElem.nunk() == m_lhs.nunk(),
+    "Size mismatch in DG::setup()" );
+
+  // Compute left-hand side of discrete PDEs
+  lhs();
+
+  // Determine elements inside user-defined IC box
+  g_dgpde[d->MeshId()].IcBoxElems( myGhosts()->m_geoElem,
+    myGhosts()->m_fd.Esuel().size()/4, m_boxelems );
+
+  // Compute volume of user-defined box IC
+  d->boxvol( {}, {}, 0 );      // punt for now
 
-    //! Query the sound speed
-    //! \param[in] U Solution vector of conserved variables
-    //! \param[in,out] s Speed of sound in mesh nodes
-    void soundspeed( const tk::Fields& U, std::vector< tk::real >& s ) const {
-      s.resize( U.nunk() );
-      for (std::size_t i=0; i<U.nunk(); ++i) {
-        auto r  = U(i,0);
-        auto ru = U(i,1);
-        auto rv = U(i,2);
-        auto rw = U(i,3);
-        auto re = U(i,4);
-        auto p = m_mat_blk[0].compute< EOS::pressure >(r, ru/r, rv/r, rw/r, re);
-        s[i] = m_mat_blk[0].compute< EOS::soundspeed >( r, p );
-      }
-    }
-
-    //! Return analytic solution (if defined by Problem) at xi, yi, zi, t
-    //! \param[in] xi X-coordinate
-    //! \param[in] yi Y-coordinate
-    //! \param[in] zi Z-coordinate
-    //! \param[in] t Physical time
-    //! \return Vector of analytic solution at given location and time
-    std::vector< real >
-    analyticSolution( real xi, real yi, real zi, real t ) const
-    { return Problem::analyticSolution( m_ncomp, m_mat_blk, xi, yi, zi, t ); }
+  // Query time history field output labels from all PDEs integrated
+  const auto& hist_points = g_inputdeck.get< tag::history_output, tag::point >();
+  if (!hist_points.empty()) {
+    std::vector< std::string > histnames;
+    auto n = g_dgpde[d->MeshId()].histNames();
+    histnames.insert( end(histnames), begin(n), end(n) );
+    d->histheader( std::move(histnames) );
+  }
+
+  // If working with IMEX-RK, Store stiff equations into m_stiffEqIdx
+  if (g_inputdeck.get< tag::imex_runge_kutta >())
+  {
+    g_dgpde[Disc()->MeshId()].setStiffEqIdx(m_stiffEqIdx);
+    g_dgpde[Disc()->MeshId()].setNonStiffEqIdx(m_nonStiffEqIdx);
+  }
+}
+
+void
+DG::box( tk::real v, const std::vector< tk::real >& )
+// *****************************************************************************
+// Receive total box IC volume and set conditions in box
+//! \param[in] v Total volume within user-specified box
+// *****************************************************************************
+{
+  auto d = Disc();
 
-    //! Return analytic solution for conserved variables
-    //! \param[in] xi X-coordinate at which to evaluate the analytic solution
-    //! \param[in] yi Y-coordinate at which to evaluate the analytic solution
-    //! \param[in] zi Z-coordinate at which to evaluate the analytic solution
-    //! \param[in] t Physical time at which to evaluate the analytic solution
-    //! \return Vector of analytic solution at given location and time
-    std::vector< tk::real >
-    solution( tk::real xi, tk::real yi, tk::real zi, tk::real t ) const
-    { return Problem::initialize( m_ncomp, m_mat_blk, xi, yi, zi, t ); }
-
-    //! \brief Compute nodal gradients of primitive variables for ALECG along
-    //!   chare-boundary
-    //! \param[in] coord Mesh node coordinates
-    //! \param[in] inpoel Mesh element connectivity
-    //! \param[in] bndel List of elements contributing to chare-boundary nodes
-    //! \param[in] gid Local->global node id map
-    //! \param[in] bid Local chare-boundary node ids (value) associated to
-    //!    global node ids (key)
-    //! \param[in] U Solution vector at recent time step
-    //! \param[in,out] G Nodal gradients of primitive variables
-    //! \details This function only computes local contributions to gradients
-    //!   at chare-boundary nodes. Internal node gradients are calculated as
-    //!   required, and do not need to be stored.
-    void chBndGrad( const std::array< std::vector< real >, 3 >& coord,
-                    const std::vector< std::size_t >& inpoel,
-                    const std::vector< std::size_t >& bndel,
-                    const std::vector< std::size_t >& gid,
-                    const std::unordered_map< std::size_t, std::size_t >& bid,
-                    const tk::Fields& U,
-                    tk::Fields& G ) const
-    {
-      Assert( U.nunk() == coord[0].size(), "Number of unknowns in solution "
-              "vector at recent time step incorrect" );
-
-      // compute gradients of primitive variables in points
-      G.fill( 0.0 );
-
-      // access node cooordinates
-      const auto& x = coord[0];
-      const auto& y = coord[1];
-      const auto& z = coord[2];
-
-      for (auto e : bndel) {  // elements contributing to chare boundary nodes
-        // access node IDs
-        std::size_t N[4] =
-          { inpoel[e*4+0], inpoel[e*4+1], inpoel[e*4+2], inpoel[e*4+3] };
-        // compute element Jacobi determinant, J = 6V
-        real bax = x[N[1]]-x[N[0]];
-        real bay = y[N[1]]-y[N[0]];
-        real baz = z[N[1]]-z[N[0]];
-        real cax = x[N[2]]-x[N[0]];
-        real cay = y[N[2]]-y[N[0]];
-        real caz = z[N[2]]-z[N[0]];
-        real dax = x[N[3]]-x[N[0]];
-        real day = y[N[3]]-y[N[0]];
-        real daz = z[N[3]]-z[N[0]];
-        auto J = tk::triple( bax, bay, baz, cax, cay, caz, dax, day, daz );
-        ErrChk( J > 0, "Element Jacobian non-positive" );
-        auto J24 = J/24.0;
-        // shape function derivatives, nnode*ndim [4][3]
-        real g[4][3];
-        tk::crossdiv( cax, cay, caz, dax, day, daz, J,
-                      g[1][0], g[1][1], g[1][2] );
-        tk::crossdiv( dax, day, daz, bax, bay, baz, J,
-                      g[2][0], g[2][1], g[2][2] );
-        tk::crossdiv( bax, bay, baz, cax, cay, caz, J,
-                      g[3][0], g[3][1], g[3][2] );
-        for (std::size_t i=0; i<3; ++i)
-          g[0][i] = -g[1][i] - g[2][i] - g[3][i];
-        // scatter-add gradient contributions to boundary nodes
-        for (std::size_t a=0; a<4; ++a) {
-          auto i = bid.find( gid[N[a]] );
-          if (i != end(bid)) {
-            real u[5];
-            for (std::size_t b=0; b<4; ++b) {
-              u[0] = U(N[b],0);
-              u[1] = U(N[b],1)/u[0];
-              u[2] = U(N[b],2)/u[0];
-              u[3] = U(N[b],3)/u[0];
-              u[4] = U(N[b],4)/u[0]
-                     - 0.5*(u[1]*u[1] + u[2]*u[2] + u[3]*u[3]);
-              if ( stagPoint(x[N[b]],y[N[b]],z[N[b]]) )
-              {
-                u[1] = u[2] = u[3] = 0.0;
-              }
-              for (std::size_t c=0; c<5; ++c)
-                for (std::size_t j=0; j<3; ++j)
-                  G(i->second,c*3+j) += J24 * g[b][j] * u[c];
-            }
-          }
-        }
-      }
-    }
-
-    //! Compute right hand side for ALECG
-    //! \param[in] t Physical time
-    //! \param[in] coord Mesh node coordinates
-    //! \param[in] inpoel Mesh element connectivity
-    //! \param[in] triinpoel Boundary triangle face connecitivity with local ids
-    //! \param[in] bid Local chare-boundary node ids (value) associated to
-    //!    global node ids (key)
-    //! \param[in] gid Local->glocal node ids
-    //! \param[in] lid Global->local node ids
-    //! \param[in] dfn Dual-face normals
-    //! \param[in] psup Points surrounding points
-    //! \param[in] esup Elements surrounding points
-    //! \param[in] symbctri Vector with 1 at symmetry BC boundary triangles
-    //! \param[in] vol Nodal volumes
-    //! \param[in] edgenode Local node IDs of edges
-    //! \param[in] edgeid Edge ids in the order of access
-    //! \param[in] boxnodes Mesh node ids within user-defined IC boxes
-    //! \param[in] G Nodal gradients for chare-boundary nodes
-    //! \param[in] U Solution vector at recent time step
-    //! \param[in] W Mesh velocity
-    //! \param[in] tp Physical time for each mesh node
-    //! \param[in] V Total box volume
-    //! \param[in,out] R Right-hand side vector computed
-    void rhs( real t,
-              const std::array< std::vector< real >, 3 >& coord,
-              const std::vector< std::size_t >& inpoel,
-              const std::vector< std::size_t >& triinpoel,
-              const std::vector< std::size_t >& gid,
-              const std::unordered_map< std::size_t, std::size_t >& bid,
-              const std::unordered_map< std::size_t, std::size_t >& lid,
-              const std::vector< real >& dfn,
-              const std::pair< std::vector< std::size_t >,
-                               std::vector< std::size_t > >& psup,
-              const std::pair< std::vector< std::size_t >,
-                               std::vector< std::size_t > >& esup,
-              const std::vector< int >& symbctri,
-              const std::vector< real >& vol,
-              const std::vector< std::size_t >& edgenode,
-              const std::vector< std::size_t >& edgeid,
-              const std::vector< std::unordered_set< std::size_t > >& boxnodes,
-              const tk::Fields& G,
-              const tk::Fields& U,
-              const tk::Fields& W,
-              const std::vector< tk::real >& tp,
-              real V,
-              tk::Fields& R ) const
-    {
-      Assert( G.nprop() == m_ncomp*3,
-              "Number of components in gradient vector incorrect" );
-      Assert( U.nunk() == coord[0].size(), "Number of unknowns in solution "
-              "vector at recent time step incorrect" );
-      Assert( R.nunk() == coord[0].size(),
-              "Number of unknowns and/or number of components in right-hand "
-              "side vector incorrect" );
-      Assert( W.nunk() == coord[0].size(), "Size mismatch " );
-
-      // compute/assemble gradients in points
-      auto Grad = nodegrad( coord, inpoel, lid, bid, vol, esup, U, G );
-
-      // zero right hand side for all components
-      for (ncomp_t c=0; c<m_ncomp; ++c) R.fill( c, 0.0 );
-
-      // compute domain-edge integral
-      domainint( coord, gid, edgenode, edgeid, psup, dfn, U, W, Grad, R );
-
-      // compute boundary integrals
-      bndint( coord, triinpoel, symbctri, U, W, R );
-
-      // compute external (energy) sources
-      const auto& icbox = g_inputdeck.get< tag::ic, tag::box >();
-
-      if (!icbox.empty() && !boxnodes.empty()) {
-        std::size_t bcnt = 0;
-        for (const auto& b : icbox) {   // for all boxes for this eq
-          std::vector< tk::real > box
-           { b.template get< tag::xmin >(), b.template get< tag::xmax >(),
-             b.template get< tag::ymin >(), b.template get< tag::ymax >(),
-             b.template get< tag::zmin >(), b.template get< tag::zmax >() };
-
-          const auto& initiate = b.template get< tag::initiate >();
-          if (initiate == ctr::InitiateType::LINEAR) {
-            boxSrc( V, t, inpoel, esup, boxnodes[bcnt], coord, R );
-          }
-          ++bcnt;
-        }
-      }
-
-      // compute optional source integral
-      src( coord, inpoel, t, tp, R );
-    }
-
-    //! Compute overset mesh motion for OversetFE
-//    //! \param[in] t Physical time
-//    //! \param[in] coord Mesh node coordinates
-    //! \param[in] psup Points surrounding points
-    //! \param[in] symbcnodes Symmetry BC node list
-    //! \param[in] uservel User specified constant mesh velocity
-    //! \param[in] U Solution vector at recent time step
-//    //! \param[in,out] meshvel Velocity of each mesh node based on user input
-    //! \param[in,out] movedmesh True/false if mesh moved
-    void getMeshVel(
-      real /*t*/,
-      const std::array< std::vector< real >, 3 >& /*coord*/,
-      const std::pair< std::vector< std::size_t >,
-                       std::vector< std::size_t > >& psup,
-      const std::unordered_set< std::size_t >& symbcnodes,
-      const std::array< tk::real, 3 >& uservel,
-      const tk::Fields& U,
-      tk::Fields& /*meshvel*/,
-      int& movedmesh ) const
-    {
-      //Assert( meshvel.nunk() == U.nunk(),
-      //  "Mesh-velocity vector has incorrect size" );
-
-      auto uvelmag = std::sqrt(tk::dot(uservel, uservel));
-
-      // Check for pressure differential only if mesh has not moved before
-      if (movedmesh == 0 && uvelmag > 1e-8) {
-        for (auto p : symbcnodes) {
-          for (auto q : tk::Around(psup,p)) {
-            // compute pressure difference
-            real rL  = U(p,0);
-            real ruL = U(p,1) / rL;
-            real rvL = U(p,2) / rL;
-            real rwL = U(p,3) / rL;
-            real reL = U(p,4) / rL - 0.5*(ruL*ruL + rvL*rvL + rwL*rwL);
-            real rR  = U(q,0);
-            real ruR = U(q,1) / rR;
-            real rvR = U(q,2) / rR;
-            real rwR = U(q,3) / rR;
-            real reR = U(q,4) / rR - 0.5*(ruR*ruR + rvR*rvR + rwR*rwR);
-            real pL = m_mat_blk[0].compute< EOS::pressure >( rL, ruL/rL, rvL/rL,
-              rwL/rL, reL );
-            real pR = m_mat_blk[0].compute< EOS::pressure >( rR, ruR/rR, rvR/rR,
-              rwR/rR, reR );
-
-            if (std::abs(pR/pL) > 2.0) {
-              movedmesh = 1;
-              break;
-            }
-          }
-          if (movedmesh) break;
-        }
-      }
-    }
+  // Store user-defined box IC volume
+  d->Boxvol() = v;
+
+  // Set initial conditions for all PDEs
+  g_dgpde[d->MeshId()].initialize( m_lhs, myGhosts()->m_inpoel,
+    myGhosts()->m_coord, m_boxelems, d->ElemBlockId(), m_u, d->T(),
+    myGhosts()->m_fd.Esuel().size()/4 );
+  g_dgpde[d->MeshId()].updatePrimitives( m_u, m_lhs, myGhosts()->m_geoElem, m_p,
+    myGhosts()->m_fd.Esuel().size()/4 );
+  // Save initial densities of all materials
+  g_dgpde[d->MeshId()].setRho0mat( m_rho0mat );
+
+  m_un = m_u;
+
+  // Output initial conditions to file (regardless of whether it was requested)
+  startFieldOutput( CkCallback(CkIndex_DG::start(), thisProxy[thisIndex]) );
+}
+
+void
+DG::start()
+// *****************************************************************************
+//  Start time stepping
+// *****************************************************************************
+{
+  // Free memory storing output mesh
+  m_outmesh.destroy();
+
+  // Start timer measuring time stepping wall clock time
+  Disc()->Timer().zero();
+  // Zero grind-timer
+  Disc()->grindZero();
+  // Start time stepping by computing the size of the next time step)
+  next();
+}
+
+void
+DG::startFieldOutput( CkCallback c )
+// *****************************************************************************
+// Start preparing fields for output to file
+//! \param[in] c Function to continue with after the write
+// *****************************************************************************
+{
+  // No field output in benchmark mode or if field output frequency not hit
+  if (g_inputdeck.get< tag::cmd, tag::benchmark >() || !fieldOutput()) {
+
+    c.send();
+
+  } else {
+
+    // Optionally refine mesh for field output
+    auto d = Disc();
+
+    if (refinedOutput()) {
+
+      const auto& tr = tk::remap( myGhosts()->m_fd.Triinpoel(), d->Gid() );
+      d->Ref()->outref( myGhosts()->m_fd.Bface(), {}, tr, c );
+
+    } else {
+
+      // cut off ghosts from mesh connectivity and coordinates
+      const auto& tr = tk::remap( myGhosts()->m_fd.Triinpoel(), d->Gid() );
+      extractFieldOutput( {}, d->Chunk(), d->Coord(), {}, {},
+                          d->NodeCommMap(), myGhosts()->m_fd.Bface(), {}, tr, c );
+
+    }
+
+  }
+}
+
+void
+DG::next()
+// *****************************************************************************
+// Advance equations to next time step
+// *****************************************************************************
+{
+  const auto pref = g_inputdeck.get< tag::pref, tag::pref >();
+
+  auto d = Disc();
+
+  if (pref && m_stage == 0 && d->T() > 0)
+    g_dgpde[d->MeshId()].eval_ndof( myGhosts()->m_nunk, myGhosts()->m_coord,
+                  myGhosts()->m_inpoel,
+                  myGhosts()->m_fd, m_u, m_p,
+                  g_inputdeck.get< tag::pref, tag::indicator >(),
+                  g_inputdeck.get< tag::ndof >(),
+                  g_inputdeck.get< tag::pref, tag::ndofmax >(),
+                  g_inputdeck.get< tag::pref, tag::tolref >(),
+                  m_ndof );
+
+  // communicate solution ghost data (if any)
+  if (myGhosts()->m_sendGhost.empty())
+    comsol_complete();
+  else
+    for(const auto& [cid, ghostdata] : myGhosts()->m_sendGhost) {
+      std::vector< std::size_t > tetid( ghostdata.size() );
+      std::vector< std::vector< tk::real > > u( ghostdata.size() ),
+                                             prim( ghostdata.size() );
+      std::vector< std::size_t > ndof;
+      std::size_t j = 0;
+      for(const auto& i : ghostdata) {
+        Assert( i < myGhosts()->m_fd.Esuel().size()/4,
+          "Sending solution ghost data" );
+        tetid[j] = i;
+        u[j] = m_u[i];
+        prim[j] = m_p[i];
+        if (pref && m_stage == 0) ndof.push_back( m_ndof[i] );
+        ++j;
+      }
+      thisProxy[ cid ].comsol( thisIndex, m_stage, tetid, u, prim, ndof );
+    }
+
+  ownsol_complete();
+}
+
+void
+DG::comsol( int fromch,
+            std::size_t fromstage,
+            const std::vector< std::size_t >& tetid,
+            const std::vector< std::vector< tk::real > >& u,
+            const std::vector< std::vector< tk::real > >& prim,
+            const std::vector< std::size_t >& ndof )
+// *****************************************************************************
+//  Receive chare-boundary solution ghost data from neighboring chares
+//! \param[in] fromch Sender chare id
+//! \param[in] fromstage Sender chare time step stage
+//! \param[in] tetid Ghost tet ids we receive solution data for
+//! \param[in] u Solution ghost data
+//! \param[in] prim Primitive variables in ghost cells
+//! \param[in] ndof Number of degrees of freedom for chare-boundary elements
+//! \details This function receives contributions to the unlimited solution
+//!   from fellow chares.
+// *****************************************************************************
+{
+  Assert( u.size() == tetid.size(), "Size mismatch in DG::comsol()" );
+  Assert( prim.size() == tetid.size(), "Size mismatch in DG::comsol()" );
+
+  const auto pref = g_inputdeck.get< tag::pref, tag::pref >();
+
+  if (pref && fromstage == 0)
+    Assert( ndof.size() == tetid.size(), "Size mismatch in DG::comsol()" );
+
+  // Find local-to-ghost tet id map for sender chare
+  const auto& n = tk::cref_find( myGhosts()->m_ghost, fromch );
+
+  for (std::size_t i=0; i<tetid.size(); ++i) {
+    auto j = tk::cref_find( n, tetid[i] );
+    Assert( j >= myGhosts()->m_fd.Esuel().size()/4,
+      "Receiving solution non-ghost data" );
+    auto b = tk::cref_find( myGhosts()->m_bid, j );
+    Assert( b < m_uc[0].size(), "Indexing out of bounds" );
+    m_uc[0][b] = u[i];
+    m_pc[0][b] = prim[i];
+    if (pref && fromstage == 0) {
+      Assert( b < m_ndofc[0].size(), "Indexing out of bounds" );
+      m_ndofc[0][b] = ndof[i];
+    }
+  }
+
+  // if we have received all solution ghost contributions from neighboring
+  // chares (chares we communicate along chare-boundary faces with), and
+  // contributed our solution to these neighbors, proceed to reconstructions
+  if (++m_nsol == myGhosts()->m_sendGhost.size()) {
+    m_nsol = 0;
+    comsol_complete();
+  }
+}
+
+void
+DG::extractFieldOutput(
+  const std::vector< std::size_t >& /*ginpoel*/,
+  const tk::UnsMesh::Chunk& chunk,
+  const tk::UnsMesh::Coords& coord,
+  const std::unordered_map< std::size_t, tk::UnsMesh::Edge >& /*addedNodes*/,
+  const std::unordered_map< std::size_t, std::size_t >& addedTets,
+  const tk::NodeCommMap& nodeCommMap,
+  const std::map< int, std::vector< std::size_t > >& bface,
+  const std::map< int, std::vector< std::size_t > >& /* bnode */,
+  const std::vector< std::size_t >& triinpoel,
+  CkCallback c )
+// *****************************************************************************
+// Extract field output going to file
+//! \param[in] chunk Field-output mesh chunk (connectivity and global<->local
+//!    id maps)
+//! \param[in] coord Field-output mesh node coordinates
+//! \param[in] addedTets Field-output mesh cells and their parents (local ids)
+//! \param[in] nodeCommMap Field-output mesh node communication map
+//! \param[in] bface Field-output meshndary-faces mapped to side set ids
+//! \param[in] triinpoel Field-output mesh boundary-face connectivity
+//! \param[in] c Function to continue with after the write
+// *****************************************************************************
+{
+  m_outmesh.chunk = chunk;
+  m_outmesh.coord = coord;
+  m_outmesh.triinpoel = triinpoel;
+  m_outmesh.bface = bface;
+  m_outmesh.nodeCommMap = nodeCommMap;
+
+  const auto& inpoel = std::get< 0 >( chunk );
+
+  // Evaluate element solution on incoming mesh
+  evalSolution( *Disc(), inpoel, coord, addedTets, m_ndof, m_u, m_p,
+    m_uElemfields, m_pElemfields, m_uNodefields, m_pNodefields );
+
+  // Send node fields contributions to neighbor chares
+  if (nodeCommMap.empty())
+    comnodeout_complete();
+  else {
+    const auto& lid = std::get< 2 >( chunk );
+    auto esup = tk::genEsup( inpoel, 4 );
+    for(const auto& [ch,nodes] : nodeCommMap) {
+      // Pack node field data in chare boundary nodes
+      std::vector< std::vector< tk::real > >
+        lu( m_uNodefields.nprop(), std::vector< tk::real >( nodes.size() ) );
+      std::vector< std::vector< tk::real > >
+        lp( m_pNodefields.nprop(), std::vector< tk::real >( nodes.size() ) );
+      for (std::size_t f=0; f<m_uNodefields.nprop(); ++f) {
+        std::size_t j = 0;
+        for (auto g : nodes)
+          lu[f][j++] = m_uNodefields(tk::cref_find(lid,g),f);
+      }
+      for (std::size_t f=0; f<m_pNodefields.nprop(); ++f) {
+        std::size_t j = 0;
+        for (auto g : nodes)
+          lp[f][j++] = m_pNodefields(tk::cref_find(lid,g),f);
+      }
+      // Pack (partial) number of elements surrounding chare boundary nodes
+      std::vector< std::size_t > nesup( nodes.size() );
+      std::size_t j = 0;
+      for (auto g : nodes) {
+        auto i = tk::cref_find( lid, g );
+        nesup[j++] = esup.second[i+1] - esup.second[i];
+      }
+      thisProxy[ch].comnodeout(
+        std::vector<std::size_t>(begin(nodes),end(nodes)), nesup, lu, lp );
+    }
+  }
+
+  ownnod_complete( c, addedTets );
+}
 
-    //! Compute the minimum time step size (for unsteady time stepping)
-    //! \param[in] coord Mesh node coordinates
-    //! \param[in] inpoel Mesh element connectivity
-    //! \param[in] t Physical time
-    //! \param[in] dtn Time step size at the previous time step
-    //! \param[in] U Solution vector at recent time step
-    //! \param[in] vol Nodal volume (with contributions from other chares)
-    //! \param[in] voln Nodal volume (with contributions from other chares) at
-    //!   the previous time step
-    //! \return Minimum time step size
-    real dt( const std::array< std::vector< real >, 3 >& coord,
-             const std::vector< std::size_t >& inpoel,
-             tk::real t,
-             tk::real dtn,
-             const tk::Fields& U,
-             const std::vector< tk::real >& vol,
-             const std::vector< tk::real >& voln ) const
-    {
-      Assert( U.nunk() == coord[0].size(), "Number of unknowns in solution "
-              "vector at recent time step incorrect" );
-
-      // energy source propagation time and velocity
-      const auto& icbox = g_inputdeck.get< tag::ic, tag::box >();
-
-      const auto& x = coord[0];
-      const auto& y = coord[1];
-      const auto& z = coord[2];
-
-      // ratio of specific heats
-      auto g = getmatprop< tag::gamma >();
-      // compute the minimum dt across all elements we own
-      real mindt = std::numeric_limits< real >::max();
-      for (std::size_t e=0; e<inpoel.size()/4; ++e) {
-        const std::array< std::size_t, 4 > N{{ inpoel[e*4+0], inpoel[e*4+1],
-                                               inpoel[e*4+2], inpoel[e*4+3] }};
-        // compute cubic root of element volume as the characteristic length
-        const std::array< real, 3 >
-          ba{{ x[N[1]]-x[N[0]], y[N[1]]-y[N[0]], z[N[1]]-z[N[0]] }},
-          ca{{ x[N[2]]-x[N[0]], y[N[2]]-y[N[0]], z[N[2]]-z[N[0]] }},
-          da{{ x[N[3]]-x[N[0]], y[N[3]]-y[N[0]], z[N[3]]-z[N[0]] }};
-        const auto L = std::cbrt( tk::triple( ba, ca, da ) / 6.0 );
-        // access solution at element nodes at recent time step
-        std::array< std::array< real, 4 >, m_ncomp > u;
-        for (ncomp_t c=0; c<m_ncomp; ++c) u[c] = U.extract( c, N );
-        // compute the maximum length of the characteristic velocity (fluid
-        // velocity + sound velocity) across the four element nodes
-        real maxvel = 0.0;
-        for (std::size_t j=0; j<4; ++j) {
-          auto& r  = u[0][j];    // rho
-          auto& ru = u[1][j];    // rho * u
-          auto& rv = u[2][j];    // rho * v
-          auto& rw = u[3][j];    // rho * w
-          auto& re = u[4][j];    // rho * e
-          auto p = m_mat_blk[0].compute< EOS::pressure >( r, ru/r, rv/r, rw/r,
-            re );
-          if (p < 0) p = 0.0;
-          auto c = m_mat_blk[0].compute< EOS::soundspeed >( r, p );
-          auto v = std::sqrt((ru*ru + rv*rv + rw*rw)/r/r) + c; // char. velocity
-
-          // energy source propagation velocity (in all IC boxes configured)
-          if (!icbox.empty()) {
-            for (const auto& b : icbox) {   // for all boxes for this eq
-              const auto& initiate = b.template get< tag::initiate >();
-              auto iv = b.template get< tag::front_speed >();
-              if (initiate == ctr::InitiateType::LINEAR) {
-                auto zmin = b.template get< tag::zmin >();
-                auto zmax = b.template get< tag::zmax >();
-                auto wFront = 0.08;
-                auto tInit = 0.0;
-                auto tFinal = tInit + (zmax - zmin - 2.0*wFront) /
-                  std::fabs(iv);
-                if (t >= tInit && t <= tFinal)
-                  v = std::max(v, std::fabs(iv));
-              }
-            }
-          }
-
-          if (v > maxvel) maxvel = v;
-        }
-        // compute element dt for the Euler equations
-        auto euler_dt = L / maxvel;
-        // compute element dt based on the viscous force
-        auto viscous_dt = m_physics.viscous_dt( L, u );
-        // compute element dt based on thermal diffusion
-        auto conduct_dt = m_physics.conduct_dt( L, g, u );
-        // compute minimum element dt
-        auto elemdt = std::min( euler_dt, std::min( viscous_dt, conduct_dt ) );
-        // find minimum dt across all elements
-        mindt = std::min( elemdt, mindt );
-      }
-      mindt *= g_inputdeck.get< tag::cfl >();
-
-      // compute the minimum dt across all nodes we contribute to due to volume
-      // change in time
-      auto dvcfl = g_inputdeck.get< tag::ale, tag::dvcfl >();
-      if (dtn > 0.0 && dvcfl > 0.0) {
-        Assert( vol.size() == voln.size(), "Size mismatch" );
-        for (std::size_t p=0; p<vol.size(); ++p) {
-          auto vol_dt = dtn *
-            std::min(voln[p],vol[p]) / std::abs(voln[p]-vol[p]+1.0e-14);
-          mindt = std::min( vol_dt, mindt );
-        }
-        mindt *= dvcfl;
-      }
-
-      return mindt;
-    }
-
-    //! Compute a time step size for each mesh node (for steady time stepping)
-    //! \param[in] U Solution vector at recent time step
-    //! \param[in] vol Nodal volume (with contributions from other chares)
-    //! \param[in,out] dtp Time step size for each mesh node
-    void dt( uint64_t,
-             const std::vector< tk::real >& vol,
-             const tk::Fields& U,
-             std::vector< tk::real >& dtp ) const
-    {
-      for (std::size_t i=0; i<U.nunk(); ++i) {
-        // compute cubic root of element volume as the characteristic length
-        const auto L = std::cbrt( vol[i] );
-        // access solution at node p at recent time step
-        const auto u = U[i];
-        // compute pressure
-        auto p = m_mat_blk[0].compute< EOS::pressure >( u[0], u[1]/u[0],
-          u[2]/u[0], u[3]/u[0], u[4] );
-        if (p < 0) p = 0.0;
-        auto c = m_mat_blk[0].compute< EOS::soundspeed >( u[0], p );
-        // characteristic velocity
-        auto v = std::sqrt((u[1]*u[1] + u[2]*u[2] + u[3]*u[3])/u[0]/u[0]) + c;
-        // compute dt for node
-        dtp[i] = L / v * g_inputdeck.get< tag::cfl >();
-      }
-    }
-
-    //! \brief Query Dirichlet boundary condition value on a given side set for
-    //!    all components in this PDE system
-    //! \param[in] t Physical time
-    //! \param[in] deltat Time step size
-    //! \param[in] tp Physical time for each mesh node
-    //! \param[in] dtp Time step size for each mesh node
-    //! \param[in] ss Pair of side set ID and (local) node IDs on the side set
-    //! \param[in] coord Mesh node coordinates
-    //! \param[in] increment If true, evaluate the solution increment between
-    //!   t and t+dt for Dirichlet BCs. If false, evlauate the solution instead.
-    //! \return Vector of pairs of bool and boundary condition value associated
-    //!   to mesh node IDs at which Dirichlet boundary conditions are set. Note
-    //!   that if increment is true, instead of the actual boundary condition
-    //!   value, we return the increment between t+deltat and t, since,
-    //!   depending on client code and solver, that may be what the solution
-    //!   requires.
-    std::map< std::size_t, std::vector< std::pair<bool,real> > >
-    dirbc( real t,
-           real deltat,
-           const std::vector< tk::real >& tp,
-           const std::vector< tk::real >& dtp,
-           const std::pair< const int, std::vector< std::size_t > >& ss,
-           const std::array< std::vector< real >, 3 >& coord,
-           bool increment ) const
-    {
-      using NodeBC = std::vector< std::pair< bool, real > >;
-      std::map< std::size_t, NodeBC > bc;
-
-      // collect sidesets across all meshes
-      std::vector< std::size_t > ubc;
-      for (const auto& ibc : g_inputdeck.get< tag::bc >()) {
-        ubc.insert(ubc.end(), ibc.get< tag::dirichlet >().begin(),
-          ibc.get< tag::dirichlet >().end());
-      }
+void
+DG::lhs()
+// *****************************************************************************
+// Compute left-hand side of discrete transport equations
+// *****************************************************************************
+{
+  g_dgpde[Disc()->MeshId()].lhs( myGhosts()->m_geoElem, m_lhs );
+
+  if (!m_initial) stage();
+}
+
+void DG::refine()
+// *****************************************************************************
+// Add the protective layer for ndof refinement
+// *****************************************************************************
+{
+  const auto pref = g_inputdeck.get< tag::pref, tag::pref >();
+
+  // Combine own and communicated contributions of unreconstructed solution and
+  // degrees of freedom in cells (if p-adaptive)
+  for (const auto& b : myGhosts()->m_bid) {
+    Assert( m_uc[0][b.second].size() == m_u.nprop(), "ncomp size mismatch" );
+    Assert( m_pc[0][b.second].size() == m_p.nprop(), "ncomp size mismatch" );
+    for (std::size_t c=0; c<m_u.nprop(); ++c) {
+      m_u(b.first,c) = m_uc[0][b.second][c];
+    }
+    for (std::size_t c=0; c<m_p.nprop(); ++c) {
+      m_p(b.first,c) = m_pc[0][b.second][c];
+    }
+    if (pref && m_stage == 0) {
+      m_ndof[ b.first ] = m_ndofc[0][ b.second ];
+    }
+  }
+
+  if (pref && m_stage==0) refine_ndof();
+
+  if (myGhosts()->m_sendGhost.empty())
+    comrefine_complete();
+  else
+    for(const auto& [cid, ghostdata] : myGhosts()->m_sendGhost) {
+      std::vector< std::size_t > tetid( ghostdata.size() );
+      std::vector< std::vector< tk::real > > u( ghostdata.size() ),
+                                             prim( ghostdata.size() );
+      std::vector< std::size_t > ndof( ghostdata.size() );
+      std::size_t j = 0;
+      for(const auto& i : ghostdata) {
+        Assert( i < myGhosts()->m_fd.Esuel().size()/4, "Sending refined ndof  "
+          "data" );
+        tetid[j] = i;
+        if (pref && m_stage == 0) ndof[j] = m_ndof[i];
+        ++j;
+      }
+      thisProxy[ cid ].comrefine( thisIndex, tetid, ndof );
+    }
+
+  ownrefine_complete();
+}
+
+void
+DG::comrefine( int fromch,
+               const std::vector< std::size_t >& tetid,
+               const std::vector< std::size_t >& ndof )
+// *****************************************************************************
+//  Receive chare-boundary ghost data from neighboring chares
+//! \param[in] fromch Sender chare id
+//! \param[in] tetid Ghost tet ids we receive solution data for
+//! \param[in] ndof Number of degrees of freedom for chare-boundary elements
+//! \details This function receives contributions to the refined ndof data
+//!   from fellow chares.
+// *****************************************************************************
+{
+  const auto pref = g_inputdeck.get< tag::pref, tag::pref >();
+
+  if (pref && m_stage == 0)
+    Assert( ndof.size() == tetid.size(), "Size mismatch in DG::comrefine()" );
+
+  // Find local-to-ghost tet id map for sender chare
+  const auto& n = tk::cref_find( myGhosts()->m_ghost, fromch );
+
+  for (std::size_t i=0; i<tetid.size(); ++i) {
+    auto j = tk::cref_find( n, tetid[i] );
+    Assert( j >= myGhosts()->m_fd.Esuel().size()/4,
+      "Receiving solution non-ghost data" );
+    auto b = tk::cref_find( myGhosts()->m_bid, j );
+    if (pref && m_stage == 0) {
+      Assert( b < m_ndofc[1].size(), "Indexing out of bounds" );
+      m_ndofc[1][b] = ndof[i];
+    }
+  }
+
+  // if we have received all solution ghost contributions from neighboring
+  // chares (chares we communicate along chare-boundary faces with), and
+  // contributed our solution to these neighbors, proceed to limiting
+  if (++m_nrefine == myGhosts()->m_sendGhost.size()) {
+    m_nrefine = 0;
+    comrefine_complete();
+  }
+}
+
+void
+DG::smooth()
+// *****************************************************************************
+// Smooth the refined ndof distribution
+// *****************************************************************************
+{
+  const auto pref = g_inputdeck.get< tag::pref, tag::pref >();
+
+  for (const auto& b : myGhosts()->m_bid) {
+    if (pref && m_stage == 0)
+      m_ndof[ b.first ] = m_ndofc[1][ b.second ];
+  }
+
+  if (pref && m_stage==0) smooth_ndof();
+
+  if (myGhosts()->m_sendGhost.empty())
+    comsmooth_complete();
+  else
+    for(const auto& [cid, ghostdata] : myGhosts()->m_sendGhost) {
+      std::vector< std::size_t > tetid( ghostdata.size() );
+      std::vector< std::size_t > ndof;
+      std::size_t j = 0;
+      for(const auto& i : ghostdata) {
+        Assert( i < myGhosts()->m_fd.Esuel().size()/4, "Sending ndof data" );
+        tetid[j] = i;
+        if (pref && m_stage == 0) ndof.push_back( m_ndof[i] );
+        ++j;
+      }
+      thisProxy[ cid ].comsmooth( thisIndex, tetid, ndof );
+    }
+
+  ownsmooth_complete();
+}
+
+void
+DG::comsmooth( int fromch,
+               const std::vector< std::size_t >& tetid,
+               const std::vector< std::size_t >& ndof )
+// *****************************************************************************
+//  Receive chare-boundary ghost data from neighboring chares
+//! \param[in] fromch Sender chare id
+//! \param[in] tetid Ghost tet ids we receive solution data for
+//! \param[in] ndof Number of degrees of freedom for chare-boundary elements
+//! \details This function receives contributions to the smoothed ndof data
+//!   from fellow chares.
+// *****************************************************************************
+{
+  const auto pref = g_inputdeck.get< tag::pref, tag::pref >();
+
+  if (pref && m_stage == 0)
+    Assert( ndof.size() == tetid.size(), "Size mismatch in DG::comsmooth()" );
+
+  const auto& n = tk::cref_find( myGhosts()->m_ghost, fromch );
+
+  for (std::size_t i=0; i<tetid.size(); ++i) {
+    auto j = tk::cref_find( n, tetid[i] );
+    Assert( j >= myGhosts()->m_fd.Esuel().size()/4, "Receiving ndof data" );
+    auto b = tk::cref_find( myGhosts()->m_bid, j );
+    if (pref && m_stage == 0) {
+      Assert( b < m_ndofc[2].size(), "Indexing out of bounds" );
+      m_ndofc[2][b] = ndof[i];
+    }
+  }
+
+  if (++m_nsmooth == myGhosts()->m_sendGhost.size()) {
+    m_nsmooth = 0;
+    comsmooth_complete();
+  }
+}
 
-      const auto steady = g_inputdeck.get< tag::steady_state >();<--- Variable 'steady' is assigned a value that is never used.
-      if (!ubc.empty()) {
-        Assert( ubc.size() > 0, "Indexing out of Dirichlet BC eq-vector" );
-        const auto& x = coord[0];
-        const auto& y = coord[1];
-        const auto& z = coord[2];
-        for (const auto& b : ubc)
-          if (static_cast<int>(b) == ss.first)
-            for (auto n : ss.second) {
-              Assert( x.size() > n, "Indexing out of coordinate array" );
-              if (steady) { t = tp[n]; deltat = dtp[n]; }
-              auto s = increment ?
-                solinc( m_ncomp, m_mat_blk, x[n], y[n], z[n],
-                        t, deltat, Problem::initialize ) :
-                Problem::initialize( m_ncomp, m_mat_blk, x[n], y[n],
-                                     z[n], t+deltat );
-              if ( stagPoint(x[n],y[n],z[n]) ) {
-                s[1] = s[2] = s[3] = 0.0;
-              }
-              bc[n] = {{ {true,s[0]}, {true,s[1]}, {true,s[2]}, {true,s[3]},
-                         {true,s[4]} }};
-            }
-      }
-      return bc;
-    }
-
-    //! Set symmetry boundary conditions at nodes
-    //! \param[in] U Solution vector at recent time step
-    //! \param[in] bnorm Face normals in boundary points, key local node id,
-    //!   first 3 reals of value: unit normal, outer key: side set id
-    //! \param[in] nodes Unique set of node ids at which to set symmetry BCs
-    void
-    symbc( tk::Fields& U,
-           const std::array< std::vector< real >, 3 >&,
-           const std::unordered_map< int,
-             std::unordered_map< std::size_t, std::array< real, 4 > > >& bnorm,
-           const std::unordered_set< std::size_t >& nodes ) const
-    {
-      // collect sidesets across all meshes
-      std::vector< std::size_t > sbc;
-      for (const auto& ibc : g_inputdeck.get< tag::bc >()) {
-        sbc.insert(sbc.end(), ibc.get< tag::symmetry >().begin(),
-          ibc.get< tag::symmetry >().end());
-      }
+void
+DG::reco()
+// *****************************************************************************
+// Compute reconstructions
+// *****************************************************************************
+{
+  const auto pref = g_inputdeck.get< tag::pref, tag::pref >();
+  const auto rdof = g_inputdeck.get< tag::rdof >();
+
+  // Combine own and communicated contributions of unreconstructed solution and
+  // degrees of freedom in cells (if p-adaptive)
+  for (const auto& b : myGhosts()->m_bid) {
+    if (pref && m_stage == 0) {
+      m_ndof[ b.first ] = m_ndofc[2][ b.second ];
+    }
+  }
+
+  auto d = Disc();
+  if (rdof > 1)
+    // Reconstruct second-order solution and primitive quantities
+    g_dgpde[d->MeshId()].reconstruct( d->T(), myGhosts()->m_geoFace,
+      myGhosts()->m_geoElem,
+      myGhosts()->m_fd, myGhosts()->m_esup, myGhosts()->m_inpoel,
+      myGhosts()->m_coord, m_u, m_p );
+
+  // Send reconstructed solution to neighboring chares
+  if (myGhosts()->m_sendGhost.empty())
+    comreco_complete();
+  else
+    for(const auto& [cid, ghostdata] : myGhosts()->m_sendGhost) {
+      std::vector< std::size_t > tetid( ghostdata.size() );
+      std::vector< std::vector< tk::real > > u( ghostdata.size() ),
+                                             prim( ghostdata.size() );
+      std::size_t j = 0;
+      for(const auto& i : ghostdata) {
+        Assert( i < myGhosts()->m_fd.Esuel().size()/4, "Sending reconstructed ghost "
+          "data" );
+        tetid[j] = i;
+        u[j] = m_u[i];
+        prim[j] = m_p[i];
+        ++j;
+      }
+      thisProxy[ cid ].comreco( thisIndex, tetid, u, prim );
+    }
 
-      if (sbc.size() > 0) {             // use symbcs for this system
-        for (auto p : nodes) {                 // for all symbc nodes
-          // for all user-def symbc sets
-          for (std::size_t s=0; s<sbc.size(); ++s) {
-            // find nodes & normals for side
-            auto j = bnorm.find(static_cast<int>(sbc[s]));
-            if (j != end(bnorm)) {
-              auto i = j->second.find(p);      // find normal for node
-              if (i != end(j->second)) {
-                std::array< real, 3 >
-                  n{ i->second[0], i->second[1], i->second[2] },
-                  v{ U(p,1), U(p,2), U(p,3) };
-                auto v_dot_n = tk::dot( v, n );
-                // symbc: remove normal component of velocity
-                U(p,1) -= v_dot_n * n[0];
-                U(p,2) -= v_dot_n * n[1];
-                U(p,3) -= v_dot_n * n[2];
-              }
-            }
-          }
-        }
-      }
-    }
+  ownreco_complete();
+}
+
+void
+DG::comreco( int fromch,
+             const std::vector< std::size_t >& tetid,
+             const std::vector< std::vector< tk::real > >& u,
+             const std::vector< std::vector< tk::real > >& prim )
+// *****************************************************************************
+//  Receive chare-boundary reconstructed ghost data from neighboring chares
+//! \param[in] fromch Sender chare id
+//! \param[in] tetid Ghost tet ids we receive solution data for
+//! \param[in] u Reconstructed high-order solution
+//! \param[in] prim Limited high-order primitive quantities
+//! \details This function receives contributions to the reconstructed solution
+//!   from fellow chares.
+// *****************************************************************************
+{
+  Assert( u.size() == tetid.size(), "Size mismatch in DG::comreco()" );
+  Assert( prim.size() == tetid.size(), "Size mismatch in DG::comreco()" );
+
+  // Find local-to-ghost tet id map for sender chare
+  const auto& n = tk::cref_find( myGhosts()->m_ghost, fromch );
 
-    //! Set farfield boundary conditions at nodes
-    //! \param[in] U Solution vector at recent time step
-    //! \param[in] bnorm Face normals in boundary points, key local node id,
-    //!   first 3 reals of value: unit normal, outer key: side set id
-    //! \param[in] nodes Unique set of node ids at which to set farfield BCs
-    void
-    farfieldbc(
-      tk::Fields& U,
-      const std::array< std::vector< real >, 3 >&,
-      const std::unordered_map< int,
-        std::unordered_map< std::size_t, std::array< real, 4 > > >& bnorm,
-      const std::unordered_set< std::size_t >& nodes ) const
-    {
-      // collect sidesets across all meshes
-      std::vector< std::size_t > fbc;
-      for (const auto& ibc : g_inputdeck.get< tag::bc >()) {
-        fbc.insert(fbc.end(), ibc.get< tag::farfield >().begin(),
-          ibc.get< tag::farfield >().end());
-      }
+  for (std::size_t i=0; i<tetid.size(); ++i) {
+    auto j = tk::cref_find( n, tetid[i] );
+    Assert( j >= myGhosts()->m_fd.Esuel().size()/4,
+      "Receiving solution non-ghost data" );
+    auto b = tk::cref_find( myGhosts()->m_bid, j );
+    Assert( b < m_uc[1].size(), "Indexing out of bounds" );
+    Assert( b < m_pc[1].size(), "Indexing out of bounds" );
+    m_uc[1][b] = u[i];
+    m_pc[1][b] = prim[i];
+  }
+
+  // if we have received all solution ghost contributions from neighboring
+  // chares (chares we communicate along chare-boundary faces with), and
+  // contributed our solution to these neighbors, proceed to limiting
+  if (++m_nreco == myGhosts()->m_sendGhost.size()) {
+    m_nreco = 0;
+    comreco_complete();
+  }
+}
 
-      if (fbc.size() > 0)               // use farbcs for this system
-        for (auto p : nodes)                   // for all farfieldbc nodes
-          for (const auto& s : fbc) {// for all user-def farbc sets
-            auto j = bnorm.find(static_cast<int>(s));// find nodes & normals for side
-            if (j != end(bnorm)) {
-              auto i = j->second.find(p);      // find normal for node
-              if (i != end(j->second)) {
-                auto& r  = U(p,0);
-                auto& ru = U(p,1);
-                auto& rv = U(p,2);
-                auto& rw = U(p,3);
-                auto& re = U(p,4);
-                auto vn =
-                  (ru*i->second[0] + rv*i->second[1] + rw*i->second[2]) / r;
-                auto a = m_mat_blk[0].compute< EOS::soundspeed >( r,
-                  m_mat_blk[0].compute< EOS::pressure >( r, ru/r, rv/r, rw/r,
-                  re ) );
-                auto M = vn / a;
-                if (M <= -1.0) {                      // supersonic inflow
-                  r  = m_fr;
-                  ru = m_fr * m_fu[0];
-                  rv = m_fr * m_fu[1];
-                  rw = m_fr * m_fu[2];
-                  re = m_mat_blk[0].compute< EOS::totalenergy >( m_fr,
-                    m_fu[0], m_fu[1], m_fu[2], m_fp );
-                } else if (M > -1.0 && M < 0.0) {     // subsonic inflow
-                  auto pr = m_mat_blk[0].compute< EOS::pressure >
-                                                ( r, ru/r, rv/r, rw/r, re );
-                  r  = m_fr;
-                  ru = m_fr * m_fu[0];
-                  rv = m_fr * m_fu[1];
-                  rw = m_fr * m_fu[2];
-                  re = m_mat_blk[0].compute< EOS::totalenergy >( m_fr,
-                    m_fu[0], m_fu[1], m_fu[2], pr );
-                } else if (M >= 0.0 && M < 1.0) {     // subsonic outflow
-                  re = m_mat_blk[0].compute< EOS::totalenergy >( r, ru/r,
-                    rv/r, rw/r, m_fp );
-                }
-              }
-            }
-          }
-    }
-
-    //! Apply user defined time dependent BCs
-    //! \param[in] t Physical time
-    //! \param[in,out] U Solution vector at recent time step
-    //! \param[in] nodes Vector of unique sets of node ids at which to apply BCs
-    //! \details This function applies user defined time dependent boundary
-    //!   conditions on groups of side sets specified in the input file.
-    //!   The user specifies pressure, density, and velocity as discrete
-    //!   functions of time, in the control file, associated with a group of
-    //!   side sets. Several such groups can be specified, each with their
-    //!   own discrete function: p(t), rho(t), vx(t), vy(t), vz(t).
-    void
-    timedepbc( tk::real t,
-      tk::Fields& U,<--- Parameter 'U' can be declared with const
-      const std::vector< std::unordered_set< std::size_t > >& nodes,
-      const std::vector< tk::Table<5> >& timedepfn ) const
-    {
-      for (std::size_t ib=0; ib<nodes.size(); ++ib) {
-        for (auto p:nodes[ib]) {
-          // sample primitive vars from discrete data at time t
-          auto unk = tk::sample<5>(t, timedepfn[ib]);
-
-          // apply BCs after converting to conserved vars
-          U(p,0) = unk[1];
-          U(p,1) = unk[1]*unk[2];
-          U(p,2) = unk[1]*unk[3];
-          U(p,3) = unk[1]*unk[4];
-          U(p,4) = m_mat_blk[0].compute< EOS::totalenergy >( unk[1], unk[2],
-            unk[3], unk[4], unk[0]);
-        }
+void
+DG::nodalExtrema()
+// *****************************************************************************
+// Compute nodal extrema at chare-boundary nodes. Extrema at internal nodes
+// are calculated in limiter function.
+// *****************************************************************************
+{
+  auto d = Disc();
+  auto gid = d->Gid();
+  auto bid = d->Bid();
+  const auto rdof = g_inputdeck.get< tag::rdof >();
+  const auto ncomp = m_u.nprop() / rdof;
+  const auto nprim = m_p.nprop() / rdof;
+
+  // Combine own and communicated contributions of unlimited solution, and
+  // if a p-adaptive algorithm is used, degrees of freedom in cells
+  for (const auto& [boundary, localtet] : myGhosts()->m_bid) {
+    Assert( m_uc[1][localtet].size() == m_u.nprop(), "ncomp size mismatch" );
+    Assert( m_pc[1][localtet].size() == m_p.nprop(), "ncomp size mismatch" );
+    for (std::size_t c=0; c<m_u.nprop(); ++c) {
+      m_u(boundary,c) = m_uc[1][localtet][c];
+    }
+    for (std::size_t c=0; c<m_p.nprop(); ++c) {
+      m_p(boundary,c) = m_pc[1][localtet][c];
+    }
+  }
+
+  // Initialize nodal extrema vector
+  auto large = std::numeric_limits< tk::real >::max();
+  for(std::size_t i = 0; i<bid.size(); i++)
+  {
+    for (std::size_t c=0; c<ncomp; ++c)
+    {
+      for(std::size_t idof=0; idof<m_ndof_NodalExtrm; idof++)
+      {
+        auto max_mark = 2*c*m_ndof_NodalExtrm + 2*idof;
+        auto min_mark = max_mark + 1;
+        m_uNodalExtrm[i][max_mark] = -large;
+        m_uNodalExtrm[i][min_mark] =  large;
+      }
+    }
+    for (std::size_t c=0; c<nprim; ++c)
+    {
+      for(std::size_t idof=0; idof<m_ndof_NodalExtrm; idof++)
+      {
+        auto max_mark = 2*c*m_ndof_NodalExtrm + 2*idof;
+        auto min_mark = max_mark + 1;
+        m_pNodalExtrm[i][max_mark] = -large;
+        m_pNodalExtrm[i][min_mark] =  large;
+      }
+    }
+  }
+
+  // Evaluate the max/min value for the chare-boundary nodes
+  if(rdof > 4) {
+      evalNodalExtrmRefEl(ncomp, nprim, m_ndof_NodalExtrm, d->bndel(),
+        myGhosts()->m_inpoel, gid, bid, m_u, m_p, m_uNodalExtrm, m_pNodalExtrm);
+  }
+
+  // Communicate extrema at nodes to other chares on chare-boundary
+  if (d->NodeCommMap().empty())        // in serial we are done
+    comnodalExtrema_complete();
+  else  // send nodal extrema to chare-boundary nodes to fellow chares
+  {
+    for (const auto& [c,n] : d->NodeCommMap()) {
+      std::vector< std::vector< tk::real > > g1( n.size() ), g2( n.size() );
+      std::size_t j = 0;
+      for (auto i : n)
+      {
+        auto p = tk::cref_find(d->Bid(),i);
+        g1[ j   ] = m_uNodalExtrm[ p ];
+        g2[ j++ ] = m_pNodalExtrm[ p ];
       }
-    }
-
-    //! Return a map that associates user-specified strings to functions
-    //! \return Map that associates user-specified strings to functions that
-    //!   compute relevant quantities to be output to file
-    std::map< std::string, tk::GetVarFn > OutVarFn() const
-    { return CompFlowOutVarFn(); }
-
-    //! Return analytic field names to be output to file
-    //! \return Vector of strings labelling analytic fields output in file
-    std::vector< std::string > analyticFieldNames() const
-    { return m_problem.analyticFieldNames( m_ncomp ); }
-
-    //! Return surface field names to be output to file
-    //! \return Vector of strings labelling surface fields output in file
-    std::vector< std::string > surfNames() const
-    { return CompFlowSurfNames(); }
-
-    //! Return time history field names to be output to file
-    //! \return Vector of strings labelling time history fields output in file
-    std::vector< std::string > histNames() const
-    { return CompFlowHistNames(); }
-
-    //! Return nodal surface field output going to file
-    std::vector< std::vector< real > >
-    surfOutput( const std::map< int, std::vector< std::size_t > >& bnd,
-                const tk::Fields& U ) const
-    { return CompFlowSurfOutput( m_mat_blk, bnd, U ); }
-
-    //! Return elemental surface field output (on triangle faces) going to file
-    std::vector< std::vector< real > >
-    elemSurfOutput( const std::map< int, std::vector< std::size_t > >& bface,
-      const std::vector< std::size_t >& triinpoel,
-      const tk::Fields& U ) const
-    {
-      return CompFlowElemSurfOutput( m_mat_blk, bface, triinpoel, U );
-    }
-
-    //! Return time history field output evaluated at time history points
-    std::vector< std::vector< real > >
-    histOutput( const std::vector< HistData >& h,
-                const std::vector< std::size_t >& inpoel,
-                const tk::Fields& U ) const
-    { return CompFlowHistOutput( m_mat_blk, h, inpoel, U ); }
-
-    //! Return names of integral variables to be output to diagnostics file
-    //! \return Vector of strings labelling integral variables output
-    std::vector< std::string > names() const
-    { return m_problem.names( m_ncomp ); }
-
-  private:
-    const Physics m_physics;            //!< Physics policy
-    const Problem m_problem;            //!< Problem policy
-    //! Stagnation BC user configuration: point coordinates and radii
-    std::tuple< std::vector< real >, std::vector< real > > m_stagCnf;
-    real m_fr;                    //!< Farfield density
-    real m_fp;                    //!< Farfield pressure
-    std::vector< real > m_fu;     //!< Farfield velocity
-    //! EOS material block
-    std::vector< EOS > m_mat_blk;
-
-    //! Decide if point is a stagnation point
-    //! \param[in] x X mesh point coordinates to query
-    //! \param[in] y Y mesh point coordinates to query
-    //! \param[in] z Z mesh point coordinates to query
-    //! \return True if point is configured as a stagnation point by the user
-    #pragma omp declare simd
-    bool
-    stagPoint( real x, real y, real z ) const {
-      const auto& pnt = std::get< 0 >( m_stagCnf );
-      const auto& rad = std::get< 1 >( m_stagCnf );
-      for (std::size_t i=0; i<pnt.size()/3; ++i) {
-        if (tk::length( x-pnt[i*3+0], y-pnt[i*3+1], z-pnt[i*3+2] ) < rad[i])
-          return true;
-      }
-      return false;
-    }
-
-    //! \brief Compute/assemble nodal gradients of primitive variables for
-    //!   ALECG in all points
-    //! \param[in] coord Mesh node coordinates
-    //! \param[in] inpoel Mesh element connectivity
-    //! \param[in] lid Global->local node ids
-    //! \param[in] bid Local chare-boundary node ids (value) associated to
-    //!    global node ids (key)
-    //! \param[in] vol Nodal volumes
-    //! \param[in] esup Elements surrounding points
-    //! \param[in] U Solution vector at recent time step
-    //! \param[in] G Nodal gradients of primitive variables in chare-boundary
-    //!    nodes
-    //! \return Gradients of primitive variables in all mesh points
-    tk::Fields
-    nodegrad( const std::array< std::vector< real >, 3 >& coord,
-              const std::vector< std::size_t >& inpoel,
-              const std::unordered_map< std::size_t, std::size_t >& lid,
-              const std::unordered_map< std::size_t, std::size_t >& bid,
-              const std::vector< real >& vol,
-              const std::pair< std::vector< std::size_t >,
-                               std::vector< std::size_t > >& esup,
-              const tk::Fields& U,
-              const tk::Fields& G ) const
-    {
-      // allocate storage for nodal gradients of primitive variables
-      tk::Fields Grad( U.nunk(), m_ncomp*3 );
-      Grad.fill( 0.0 );
-
-      // access node cooordinates
-      const auto& x = coord[0];
-      const auto& y = coord[1];
-      const auto& z = coord[2];
-
-      // compute gradients of primitive variables in points
-      auto npoin = U.nunk();
-      #pragma omp simd
-      for (std::size_t p=0; p<npoin; ++p)
-        for (auto e : tk::Around(esup,p)) {
-          // access node IDs
-          std::size_t N[4] =
-            { inpoel[e*4+0], inpoel[e*4+1], inpoel[e*4+2], inpoel[e*4+3] };
-          // compute element Jacobi determinant, J = 6V
-          real bax = x[N[1]]-x[N[0]];
-          real bay = y[N[1]]-y[N[0]];
-          real baz = z[N[1]]-z[N[0]];
-          real cax = x[N[2]]-x[N[0]];
-          real cay = y[N[2]]-y[N[0]];
-          real caz = z[N[2]]-z[N[0]];
-          real dax = x[N[3]]-x[N[0]];
-          real day = y[N[3]]-y[N[0]];
-          real daz = z[N[3]]-z[N[0]];
-          auto J = tk::triple( bax, bay, baz, cax, cay, caz, dax, day, daz );
-          auto J24 = J/24.0;
-          // shape function derivatives, nnode*ndim [4][3]
-          real g[4][3];
-          tk::crossdiv( cax, cay, caz, dax, day, daz, J,
-                        g[1][0], g[1][1], g[1][2] );
-          tk::crossdiv( dax, day, daz, bax, bay, baz, J,
-                        g[2][0], g[2][1], g[2][2] );
-          tk::crossdiv( bax, bay, baz, cax, cay, caz, J,
-                        g[3][0], g[3][1], g[3][2] );
-          for (std::size_t i=0; i<3; ++i)
-            g[0][i] = -g[1][i] - g[2][i] - g[3][i];
-          // scatter-add gradient contributions to boundary nodes
-          real u[m_ncomp];
-          for (std::size_t b=0; b<4; ++b) {
-            u[0] = U(N[b],0);
-            u[1] = U(N[b],1)/u[0];
-            u[2] = U(N[b],2)/u[0];
-            u[3] = U(N[b],3)/u[0];
-            u[4] = U(N[b],4)/u[0]
-                   - 0.5*(u[1]*u[1] + u[2]*u[2] + u[3]*u[3]);
-            if ( stagPoint(x[N[b]],y[N[b]],z[N[b]]) )
-            {
-              u[1] = u[2] = u[3] = 0.0;
-            }
-            for (std::size_t c=0; c<m_ncomp; ++c)
-              for (std::size_t i=0; i<3; ++i)
-                Grad(p,c*3+i) += J24 * g[b][i] * u[c];
-          }
-        }
-
-      // put in nodal gradients of chare-boundary points
-      for (const auto& [g,b] : bid) {
-        auto i = tk::cref_find( lid, g );
-        for (ncomp_t c=0; c<Grad.nprop(); ++c)
-          Grad(i,c) = G(b,c);
-      }
-
-      // divide weak result in gradients by nodal volume
-      for (std::size_t p=0; p<npoin; ++p)
-        for (std::size_t c=0; c<m_ncomp*3; ++c)
-          Grad(p,c) /= vol[p];
-
-      return Grad;
-    }
-
-    //! Compute domain-edge integral for ALECG
-    //! \param[in] coord Mesh node coordinates
-    //! \param[in] gid Local->glocal node ids
-    //! \param[in] edgenode Local node ids of edges
-    //! \param[in] edgeid Local node id pair -> edge id map
-    //! \param[in] psup Points surrounding points
-    //! \param[in] dfn Dual-face normals
-    //! \param[in] U Solution vector at recent time step
-    //! \param[in] W Mesh velocity
-    //! \param[in] G Nodal gradients
-    //! \param[in,out] R Right-hand side vector computed
-    void domainint( const std::array< std::vector< real >, 3 >& coord,
-                    const std::vector< std::size_t >& gid,
-                    const std::vector< std::size_t >& edgenode,
-                    const std::vector< std::size_t >& edgeid,
-                    const std::pair< std::vector< std::size_t >,
-                                     std::vector< std::size_t > >& psup,
-                    const std::vector< real >& dfn,
-                    const tk::Fields& U,
-                    const tk::Fields& W,
-                    const tk::Fields& G,
-                    tk::Fields& R ) const
-    {
-      // domain-edge integral: compute fluxes in edges
-      std::vector< real > dflux( edgenode.size()/2 * m_ncomp );
+      thisProxy[c].comnodalExtrema( std::vector<std::size_t>(begin(n),end(n)),
+        g1, g2 );
+    }
+  }
+  ownnodalExtrema_complete();
+}
+
+void
+DG::comnodalExtrema( const std::vector< std::size_t >& gid,
+                     const std::vector< std::vector< tk::real > >& G1,
+                     const std::vector< std::vector< tk::real > >& G2 )
+// *****************************************************************************
+//  Receive contributions to nodal extrema on chare-boundaries
+//! \param[in] gid Global mesh node IDs at which we receive grad contributions
+//! \param[in] G1 Partial contributions of extrema for conservative variables to
+//!   chare-boundary nodes
+//! \param[in] G2 Partial contributions of extrema for primitive variables to
+//!   chare-boundary nodes
+//! \details This function receives contributions to m_uNodalExtrm/m_pNodalExtrm
+//!   , which stores nodal extrems at mesh chare-boundary nodes. While
+//!   m_uNodalExtrm/m_pNodalExtrm stores own contributions, m_uNodalExtrmc
+//!   /m_pNodalExtrmc collects the neighbor chare contributions during
+//!   communication.
+// *****************************************************************************
+{
+  Assert( G1.size() == gid.size(), "Size mismatch" );
+  Assert( G2.size() == gid.size(), "Size mismatch" );
+
+  const auto rdof = g_inputdeck.get< tag::rdof >();
+  const auto ncomp = m_u.nprop() / rdof;
+  const auto nprim = m_p.nprop() / rdof;
+
+  for (std::size_t i=0; i<gid.size(); ++i)
+  {
+    auto& u = m_uNodalExtrmc[gid[i]];
+    auto& p = m_pNodalExtrmc[gid[i]];
+    for (std::size_t c=0; c<ncomp; ++c)
+    {
+      for(std::size_t idof=0; idof<m_ndof_NodalExtrm; idof++)
+      {
+        auto max_mark = 2*c*m_ndof_NodalExtrm + 2*idof;
+        auto min_mark = max_mark + 1;
+        u[max_mark] = std::max( G1[i][max_mark], u[max_mark] );
+        u[min_mark] = std::min( G1[i][min_mark], u[min_mark] );
+      }
+    }
+    for (std::size_t c=0; c<nprim; ++c)
+    {
+      for(std::size_t idof=0; idof<m_ndof_NodalExtrm; idof++)
+      {
+        auto max_mark = 2*c*m_ndof_NodalExtrm + 2*idof;
+        auto min_mark = max_mark + 1;
+        p[max_mark] = std::max( G2[i][max_mark], p[max_mark] );
+        p[min_mark] = std::min( G2[i][min_mark], p[min_mark] );
+      }
+    }
+  }
+
+  if (++m_nnodalExtrema == Disc()->NodeCommMap().size())
+  {
+    m_nnodalExtrema = 0;
+    comnodalExtrema_complete();
+  }
+}
+
+void DG::resizeNodalExtremac()
+// *****************************************************************************
+//  Resize the buffer vector of nodal extrema
+// *****************************************************************************
+{
+  const auto rdof = g_inputdeck.get< tag::rdof >();
+  const auto ncomp = m_u.nprop() / rdof;
+  const auto nprim = m_p.nprop() / rdof;
+
+  auto large = std::numeric_limits< tk::real >::max();
+  for (const auto& [c,n] : Disc()->NodeCommMap())
+  {
+    for (auto i : n) {
+      auto& u = m_uNodalExtrmc[i];
+      auto& p = m_pNodalExtrmc[i];
+      u.resize( 2*m_ndof_NodalExtrm*ncomp, large );
+      p.resize( 2*m_ndof_NodalExtrm*nprim, large );
+
+      // Initialize the minimum nodal extrema
+      for(std::size_t idof=0; idof<m_ndof_NodalExtrm; idof++)
+      {
+        for(std::size_t k = 0; k < ncomp; k++)
+          u[2*k*m_ndof_NodalExtrm+2*idof] = -large;
+        for(std::size_t k = 0; k < nprim; k++)
+          p[2*k*m_ndof_NodalExtrm+2*idof] = -large;
+      }
+    }
+  }
+}
+
+void DG::evalNodalExtrmRefEl(
+  const std::size_t ncomp,
+  const std::size_t nprim,
+  const std::size_t ndof_NodalExtrm,
+  const std::vector< std::size_t >& bndel,
+  const std::vector< std::size_t >& inpoel,
+  const std::vector< std::size_t >& gid,
+  const std::unordered_map< std::size_t, std::size_t >& bid,
+  const tk::Fields& U,
+  const tk::Fields& P,
+  std::vector< std::vector<tk::real> >& uNodalExtrm,
+  std::vector< std::vector<tk::real> >& pNodalExtrm )
+// *****************************************************************************
+//  Compute the nodal extrema of ref el derivatives for chare-boundary nodes
+//! \param[in] ncomp Number of conservative variables
+//! \param[in] nprim Number of primitive variables
+//! \param[in] ndof_NodalExtrm Degree of freedom for nodal extrema
+//! \param[in] bndel List of elements contributing to chare-boundary nodes
+//! \param[in] inpoel Element-node connectivity for element e
+//! \param[in] gid Local->global node id map
+//! \param[in] bid Local chare-boundary node ids (value) associated to
+//!   global node ids (key)
+//! \param[in] U Vector of conservative variables
+//! \param[in] P Vector of primitive variables
+//! \param[in,out] uNodalExtrm Chare-boundary nodal extrema for conservative
+//!   variables
+//! \param[in,out] pNodalExtrm Chare-boundary nodal extrema for primitive
+//!   variables
+// *****************************************************************************
+{
+  const auto rdof = g_inputdeck.get< tag::rdof >();
+
+  for (auto e : bndel)
+  {
+    // access node IDs
+    const std::vector<std::size_t> N
+      { inpoel[e*4+0], inpoel[e*4+1], inpoel[e*4+2], inpoel[e*4+3] };
+
+    // Loop over nodes of element e
+    for(std::size_t ip=0; ip<4; ++ip)
+    {
+      auto i = bid.find( gid[N[ip]] );
+      if (i != end(bid))      // If ip is the chare boundary point
+      {
+        // If DG(P2) is applied, find the nodal extrema of the gradients of
+        // conservative/primitive variables in the reference element
+
+        // Vector used to store the first order derivatives for both
+        // conservative and primitive variables
+        std::vector< std::array< tk::real, 3 > > gradc(ncomp, {0.0, 0.0, 0.0});
+        std::vector< std::array< tk::real, 3 > > gradp(ncomp, {0.0, 0.0, 0.0});
+
+        // Derivatives of the Dubiner basis
+        std::array< tk::real, 3 > center {{0.25, 0.25, 0.25}};
+        auto dBdxi = tk::eval_dBdxi(rdof, center);
+
+        // Evaluate the first order derivative
+        for(std::size_t icomp = 0; icomp < ncomp; icomp++)
+        {
+          auto mark = icomp * rdof;
+          for(std::size_t idir = 0; idir < 3; idir++)
+          {
+            gradc[icomp][idir] = 0;
+            for(std::size_t idof = 1; idof < rdof; idof++)
+              gradc[icomp][idir] += U(e, mark+idof) * dBdxi[idir][idof];
+          }
+        }
+        for(std::size_t icomp = 0; icomp < nprim; icomp++)
+        {
+          auto mark = icomp * rdof;
+          for(std::size_t idir = 0; idir < 3; idir++)
+          {
+            gradp[icomp][idir] = 0;
+            for(std::size_t idof = 1; idof < rdof; idof++)
+              gradp[icomp][idir] += P(e, mark+idof) * dBdxi[idir][idof];
+          }
+        }
+
+        // Store the extrema for the gradients
+        for (std::size_t c=0; c<ncomp; ++c)
+        {
+          for (std::size_t idof = 0; idof < ndof_NodalExtrm; idof++)
+          {
+            auto max_mark = 2*c*m_ndof_NodalExtrm + 2*idof;
+            auto min_mark = max_mark + 1;
+            auto& ex = uNodalExtrm[i->second];
+            ex[max_mark] = std::max(ex[max_mark], gradc[c][idof]);
+            ex[min_mark] = std::min(ex[min_mark], gradc[c][idof]);
+          }
+        }
+        for (std::size_t c=0; c<nprim; ++c)
+        {
+          for (std::size_t idof = 0; idof < ndof_NodalExtrm; idof++)
+          {
+            auto max_mark = 2*c*m_ndof_NodalExtrm + 2*idof;
+            auto min_mark = max_mark + 1;
+            auto& ex = pNodalExtrm[i->second];
+            ex[max_mark] = std::max(ex[max_mark], gradp[c][idof]);
+            ex[min_mark] = std::min(ex[min_mark], gradp[c][idof]);
+          }
+        }
+      }
+    }
+  }
+}
 
-      // access node coordinates
-      const auto& x = coord[0];
-      const auto& y = coord[1];
-      const auto& z = coord[2];
-
-      #pragma omp simd
-      for (std::size_t e=0; e<edgenode.size()/2; ++e) {
-        auto p = edgenode[e*2+0];
-        auto q = edgenode[e*2+1];
-
-        // compute primitive variables at edge-end points
-        real rL  = U(p,0);
-        real ruL = U(p,1) / rL;
-        real rvL = U(p,2) / rL;
-        real rwL = U(p,3) / rL;
-        real reL = U(p,4) / rL - 0.5*(ruL*ruL + rvL*rvL + rwL*rwL);
-        real w1L = W(p,0);
-        real w2L = W(p,1);
-        real w3L = W(p,2);
-        real rR  = U(q,0);
-        real ruR = U(q,1) / rR;
-        real rvR = U(q,2) / rR;
-        real rwR = U(q,3) / rR;
-        real reR = U(q,4) / rR - 0.5*(ruR*ruR + rvR*rvR + rwR*rwR);
-        real w1R = W(q,0);
-        real w2R = W(q,1);
-        real w3R = W(q,2);
-
-        // apply stagnation BCs to primitive variables
-        if ( stagPoint(x[p],y[p],z[p]) )
-          ruL = rvL = rwL = 0.0;
-        if ( stagPoint(x[q],y[q],z[q]) )
-          ruR = rvR = rwR = 0.0;
-
-        // compute MUSCL reconstruction in edge-end points
-        muscl( p, q, coord, G,
-               rL, ruL, rvL, rwL, reL, rR, ruR, rvR, rwR, reR );
-
-        // convert back to conserved variables
-        reL = (reL + 0.5*(ruL*ruL + rvL*rvL + rwL*rwL)) * rL;
-        ruL *= rL;
-        rvL *= rL;
-        rwL *= rL;
-        reR = (reR + 0.5*(ruR*ruR + rvR*rvR + rwR*rwR)) * rR;
-        ruR *= rR;
-        rvR *= rR;
-        rwR *= rR;
-
-        // evaluate pressure at edge-end points
-        real pL = m_mat_blk[0].compute< EOS::pressure >( rL, ruL/rL, rvL/rL,
-          rwL/rL, reL );
-        real pR = m_mat_blk[0].compute< EOS::pressure >( rR, ruR/rR, rvR/rR,
-          rwR/rR, reR );
-
-        // compute Riemann flux using edge-end point states
-        real f[m_ncomp];
-        Rusanov::flux( m_mat_blk,
-                       dfn[e*6+0], dfn[e*6+1], dfn[e*6+2],
-                       dfn[e*6+3], dfn[e*6+4], dfn[e*6+5],
-                       rL, ruL, rvL, rwL, reL,
-                       rR, ruR, rvR, rwR, reR,
-                       w1L, w2L, w3L, w1R, w2R, w3R,
-                       pL, pR,
-                       f[0], f[1], f[2], f[3], f[4] );
-        // store flux in edges
-        for (std::size_t c=0; c<m_ncomp; ++c) dflux[e*m_ncomp+c] = f[c];
-      }
-
-      // access pointer to right hand side at component
-      std::array< const real*, m_ncomp > r;
-      for (ncomp_t c=0; c<m_ncomp; ++c) r[c] = R.cptr( c );
-
-      // domain-edge integral: sum flux contributions to points
-      for (std::size_t p=0,k=0; p<U.nunk(); ++p)
-        for (auto q : tk::Around(psup,p)) {
-          auto s = gid[p] > gid[q] ? -1.0 : 1.0;
-          auto e = edgeid[k++];
-          // the 2.0 in the following expression is so that the RHS contribution
-          // conforms with Eq 12 (Waltz et al. Computers & fluids (92) 2014);
-          // The 1/2 in Eq 12 is extracted from the flux function (Rusanov).
-          // However, Rusanov::flux computes the flux with the 1/2. This 2
-          // cancels with the 1/2 in Rusanov::flux, so that the 1/2 can be
-          // extracted out and multiplied as in Eq 12
-          for (std::size_t c=0; c<m_ncomp; ++c)
-            R.var(r[c],p) -= 2.0*s*dflux[e*m_ncomp+c];
-        }
-
-      tk::destroy(dflux);
-    }
-
-    //! \brief Compute MUSCL reconstruction in edge-end points using a MUSCL
-    //!    procedure with van Leer limiting
-    //! \param[in] p Left node id of edge-end
-    //! \param[in] q Right node id of edge-end
-    //! \param[in] coord Array of nodal coordinates
-    //! \param[in] G Gradient of all unknowns in mesh points
-    //! \param[in,out] rL Left density
-    //! \param[in,out] uL Left X velocity
-    //! \param[in,out] vL Left Y velocity
-    //! \param[in,out] wL Left Z velocity
-    //! \param[in,out] eL Left internal energy
-    //! \param[in,out] rR Right density
-    //! \param[in,out] uR Right X velocity
-    //! \param[in,out] vR Right Y velocity
-    //! \param[in,out] wR Right Z velocity
-    //! \param[in,out] eR Right internal energy
-    void muscl( std::size_t p,
-                std::size_t q,
-                const tk::UnsMesh::Coords& coord,
-                const tk::Fields& G,
-                real& rL, real& uL, real& vL, real& wL, real& eL,
-                real& rR, real& uR, real& vR, real& wR, real& eR ) const
-    {
-      // access node coordinates
-      const auto& x = coord[0];
-      const auto& y = coord[1];
-      const auto& z = coord[2];
-
-      // edge vector
-      std::array< real, 3 > vw{ x[q]-x[p], y[q]-y[p], z[q]-z[p] };
-
-      real delta1[5], delta2[5], delta3[5];
-      std::array< real, 5 > ls{ rL, uL, vL, wL, eL };
-      std::array< real, 5 > rs{ rR, uR, vR, wR, eR };
-      auto url = ls;
-      auto urr = rs;
-
-      // MUSCL reconstruction of edge-end-point primitive variables
-      for (std::size_t c=0; c<5; ++c) {
-        // gradients
-        std::array< real, 3 > g1{ G(p,c*3+0), G(p,c*3+1), G(p,c*3+2) },
-                              g2{ G(q,c*3+0), G(q,c*3+1), G(q,c*3+2) };
+void
+DG::lim()
+// *****************************************************************************
+// Compute limiter function
+// *****************************************************************************
+{
+  auto d = Disc();
+  const auto rdof = g_inputdeck.get< tag::rdof >();
+  const auto ncomp = m_u.nprop() / rdof;
+  const auto nprim = m_p.nprop() / rdof;
+
+  // Combine own and communicated contributions to nodal extrema
+  for (const auto& [gid,g] : m_uNodalExtrmc) {
+    auto bid = tk::cref_find( d->Bid(), gid );
+    for (ncomp_t c=0; c<ncomp; ++c)
+    {
+      for(std::size_t idof=0; idof<m_ndof_NodalExtrm; idof++)
+      {
+        auto max_mark = 2*c*m_ndof_NodalExtrm + 2*idof;
+        auto min_mark = max_mark + 1;
+        m_uNodalExtrm[bid][max_mark] =
+          std::max(g[max_mark], m_uNodalExtrm[bid][max_mark]);
+        m_uNodalExtrm[bid][min_mark] =
+          std::min(g[min_mark], m_uNodalExtrm[bid][min_mark]);
+      }
+    }
+  }
+  for (const auto& [gid,g] : m_pNodalExtrmc) {
+    auto bid = tk::cref_find( d->Bid(), gid );
+    for (ncomp_t c=0; c<nprim; ++c)
+    {
+      for(std::size_t idof=0; idof<m_ndof_NodalExtrm; idof++)
+      {
+        auto max_mark = 2*c*m_ndof_NodalExtrm + 2*idof;
+        auto min_mark = max_mark + 1;
+        m_pNodalExtrm[bid][max_mark] =
+          std::max(g[max_mark], m_pNodalExtrm[bid][max_mark]);
+        m_pNodalExtrm[bid][min_mark] =
+          std::min(g[min_mark], m_pNodalExtrm[bid][min_mark]);
+      }
+    }
+  }
+
+  // clear gradients receive buffer
+  tk::destroy(m_uNodalExtrmc);
+  tk::destroy(m_pNodalExtrmc);
+
+  if (rdof > 1) {
+    g_dgpde[d->MeshId()].limit( d->T(), myGhosts()->m_geoFace, myGhosts()->m_geoElem,
+              myGhosts()->m_fd, myGhosts()->m_esup, myGhosts()->m_inpoel,
+              myGhosts()->m_coord, m_ndof, d->Gid(), d->Bid(), m_uNodalExtrm,
+              m_pNodalExtrm, m_mtInv, m_u, m_p, m_shockmarker );
+
+    if (g_inputdeck.get< tag::limsol_projection >())
+      g_dgpde[d->MeshId()].CPL(m_p, myGhosts()->m_geoElem,
+        myGhosts()->m_inpoel, myGhosts()->m_coord, m_u,
+        myGhosts()->m_fd.Esuel().size()/4);
+  }
+
+  // Send limited solution to neighboring chares
+  if (myGhosts()->m_sendGhost.empty())
+    comlim_complete();
+  else
+    for(const auto& [cid, ghostdata] : myGhosts()->m_sendGhost) {
+      std::vector< std::size_t > tetid( ghostdata.size() );
+      std::vector< std::vector< tk::real > > u( ghostdata.size() ),
+                                             prim( ghostdata.size() );
+      std::vector< std::size_t > ndof;<--- Unused variable: ndof
+      std::size_t j = 0;
+      for(const auto& i : ghostdata) {
+        Assert( i < myGhosts()->m_fd.Esuel().size()/4,
+          "Sending limiter ghost data" );
+        tetid[j] = i;
+        u[j] = m_u[i];
+        prim[j] = m_p[i];
+        ++j;
+      }
+      thisProxy[ cid ].comlim( thisIndex, tetid, u, prim );
+    }
+
+  ownlim_complete();
+}
+
+void
+DG::refine_ndof()
+// *****************************************************************************
+//  p-refine all elements that are adjacent to p-refined elements
+//! \details This function p-refines all the neighbors of an element that has
+//!   been p-refined as a result of an error indicator.
+// *****************************************************************************
+{
+  auto d = Disc();
+  const auto& inpoel = d->Inpoel();
+  const auto npoin = d->Coord()[0].size();
+  const auto nelem = myGhosts()->m_fd.Esuel().size()/4;
+  std::vector<std::size_t> node_ndof(npoin, 1);
+
+  // Mark the max ndof for each node and store in node_ndof
+  for(std::size_t ip=0; ip<npoin; ip++)
+  {
+    const auto& pesup = tk::cref_find(myGhosts()->m_esup, ip);
+    for(auto er : pesup)
+      node_ndof[ip] = std::max(m_ndof[er], node_ndof[ip]);
+  }
+
+  for(std::size_t e = 0; e < nelem; e++)
+  {
+    // Find if any node of this element has p1/p2 ndofs
+    std::size_t counter_p2(0);
+    std::size_t counter_p1(0);
+    for(std::size_t inode = 0; inode < 4; inode++)
+    {
+      auto node = inpoel[4*e+inode];
+      if(node_ndof[node] == 10)
+        counter_p2++;
+      else if (node_ndof[node] == 4)
+        counter_p1++;
+    }
+
+    // If there is at least one node with p1/p2 ndofs, all of the elements
+    // around this node are refined to p1/p2.
+    if(counter_p2 > 0 && m_ndof[e] < 10)
+    {
+      if(m_ndof[e] == 4)
+        m_ndof[e] = 10;
+      if(m_ndof[e] == 1)
+        m_ndof[e] = 4;
+    }
+    else if(counter_p1 > 0 && m_ndof[e] < 4)
+      m_ndof[e] = 4;
+  }
+}
 
-        delta2[c] = rs[c] - ls[c];
-        delta1[c] = 2.0 * tk::dot(g1,vw) - delta2[c];
-        delta3[c] = 2.0 * tk::dot(g2,vw) - delta2[c];
-
-        // MUSCL extrapolation option 1:
-        // ---------------------------------------------------------------------
-        // Uncomment the following 3 blocks of code if this version is required.
-        // this reconstruction is from the following paper:
-        // Waltz, J., Morgan, N. R., Canfield, T. R., Charest, M. R.,
-        // Risinger, L. D., & Wohlbier, J. G. (2014). A three-dimensional
-        // finite element arbitrary Lagrangian–Eulerian method for shock
-        // hydrodynamics on unstructured grids. Computers & Fluids, 92,
-        // 172-187.
-
-        //// form limiters
-        //auto rcL = (delta2[c] + muscl_eps) / (delta1[c] + muscl_eps);
-        //auto rcR = (delta2[c] + muscl_eps) / (delta3[c] + muscl_eps);
-        //auto rLinv = (delta1[c] + muscl_eps) / (delta2[c] + muscl_eps);
-        //auto rRinv = (delta3[c] + muscl_eps) / (delta2[c] + muscl_eps);
-
-        //// van Leer limiter
-        //// any other symmetric limiter could be used instead too
-        //auto phiL = (std::abs(rcL) + rcL) / (std::abs(rcL) + 1.0);
-        //auto phiR = (std::abs(rcR) + rcR) / (std::abs(rcR) + 1.0);
-        //auto phi_L_inv = (std::abs(rLinv) + rLinv) / (std::abs(rLinv) + 1.0);
-        //auto phi_R_inv = (std::abs(rRinv) + rRinv) / (std::abs(rRinv) + 1.0);
-
-        //// update unknowns with reconstructed unknowns
-        //url[c] += 0.25*(delta1[c]*muscl_m1*phiL + delta2[c]*muscl_p1*phi_L_inv);
-        //urr[c] -= 0.25*(delta3[c]*muscl_m1*phiR + delta2[c]*muscl_p1*phi_R_inv);
-
-        // ---------------------------------------------------------------------
+void DG::smooth_ndof()
+// *****************************************************************************
+//  Smooth the refined ndof distribution to avoid zigzag refinement
+// *****************************************************************************
+{
+  auto d = Disc();
+  const auto& inpoel = d->Inpoel();
+  const auto npoin = d->Coord()[0].size();
+  const auto nelem = myGhosts()->m_fd.Esuel().size()/4;
+  std::vector<std::size_t> node_ndof(npoin, 1);
+
+  // Mark the max ndof for each node and store in node_ndof
+  for(std::size_t ip=0; ip<npoin; ip++)
+  {
+    const auto& pesup = tk::cref_find(myGhosts()->m_esup, ip);
+    for(auto er : pesup)
+      node_ndof[ip] = std::max(m_ndof[er], node_ndof[ip]);
+  }
+
+  for(std::size_t e = 0; e < nelem; e++)
+  {
+    // Find if any node of this element has p1/p2 ndofs
+    std::size_t counter_p2(0);
+    std::size_t counter_p1(0);
+    for(std::size_t inode = 0; inode < 4; inode++)
+    {
+      auto node = inpoel[4*e+inode];
+      if(node_ndof[node] == 10)
+        counter_p2++;
+      else if (node_ndof[node] == 4)
+        counter_p1++;
+    }
 
-        // MUSCL extrapolation option 2:
-        // ---------------------------------------------------------------------
-        // The following 2 blocks of code.
-        // this reconstruction is from the following paper:
-        // Luo, H., Baum, J. D., & Lohner, R. (1994). Edge-based finite element
-        // scheme for the Euler equations. AIAA journal, 32(6), 1183-1190.
-        // Van Leer, B. (1974). Towards the ultimate conservative difference
-        // scheme. II. Monotonicity and conservation combined in a second-order
-        // scheme. Journal of computational physics, 14(4), 361-370.
-
-        // get Van Albada limiter
-        // the following form is derived from the flux limiter phi as:
-        // s = phi_inv - (1 - phi)
-        auto sL = std::max(0.0, (2.0*delta1[c]*delta2[c] + muscl_eps)
-          /(delta1[c]*delta1[c] + delta2[c]*delta2[c] + muscl_eps));
-        auto sR = std::max(0.0, (2.0*delta3[c]*delta2[c] + muscl_eps)
-          /(delta3[c]*delta3[c] + delta2[c]*delta2[c] + muscl_eps));
-
-        // update unknowns with reconstructed unknowns
-        url[c] += 0.25*sL*(delta1[c]*(1.0-muscl_const*sL)
-          + delta2[c]*(1.0+muscl_const*sL));
-        urr[c] -= 0.25*sR*(delta3[c]*(1.0-muscl_const*sR)
-          + delta2[c]*(1.0+muscl_const*sR));
-
-        // ---------------------------------------------------------------------
-      }
+    // If all the nodes in the element are p1/p2, this element is refined to
+    // p1/p2.
+    if(counter_p2 == 4 && m_ndof[e] == 4)
+      m_ndof[e] = 10;
+    else if(counter_p1 == 4 && m_ndof[e] == 1)
+      m_ndof[e] = 4;
+  }
+}
+
+void
+DG::comlim( int fromch,
+            const std::vector< std::size_t >& tetid,
+            const std::vector< std::vector< tk::real > >& u,
+            const std::vector< std::vector< tk::real > >& prim )
+// *****************************************************************************
+//  Receive chare-boundary limiter ghost data from neighboring chares
+//! \param[in] fromch Sender chare id
+//! \param[in] tetid Ghost tet ids we receive solution data for
+//! \param[in] u Limited high-order solution
+//! \param[in] prim Limited high-order primitive quantities
+//! \details This function receives contributions to the limited solution from
+//!   fellow chares.
+// *****************************************************************************
+{
+  Assert( u.size() == tetid.size(), "Size mismatch in DG::comlim()" );
+  Assert( prim.size() == tetid.size(), "Size mismatch in DG::comlim()" );
 
-      // force first order if the reconstructions for density or internal energy
-      // would have allowed negative values
-      if (ls[0] < delta1[0] || ls[4] < delta1[4]) url = ls;
-      if (rs[0] < -delta3[0] || rs[4] < -delta3[4]) urr = rs;
-
-      rL = url[0];
-      uL = url[1];
-      vL = url[2];
-      wL = url[3];
-      eL = url[4];
-
-      rR = urr[0];
-      uR = urr[1];
-      vR = urr[2];
-      wR = urr[3];
-      eR = urr[4];
-    }
-
-    //! Compute boundary integrals for ALECG
-    //! \param[in] coord Mesh node coordinates
-    //! \param[in] triinpoel Boundary triangle face connecitivity with local ids
-    //! \param[in] symbctri Vector with 1 at symmetry BC boundary triangles
-    //! \param[in] U Solution vector at recent time step
-    //! \param[in] W Mesh velocity
-    //! \param[in,out] R Right-hand side vector computed
-    void bndint( const std::array< std::vector< real >, 3 >& coord,
-                 const std::vector< std::size_t >& triinpoel,
-                 const std::vector< int >& symbctri,
-                 const tk::Fields& U,
-                 const tk::Fields& W,
-                 tk::Fields& R ) const
-    {
-
-      // access node coordinates
-      const auto& x = coord[0];
-      const auto& y = coord[1];
-      const auto& z = coord[2];
-
-      // boundary integrals: compute fluxes in edges
-      std::vector< real > bflux( triinpoel.size() * m_ncomp * 2 );
-
-      #pragma omp simd
-      for (std::size_t e=0; e<triinpoel.size()/3; ++e) {
-        // access node IDs
-        std::size_t N[3] =
-          { triinpoel[e*3+0], triinpoel[e*3+1], triinpoel[e*3+2] };
-        // access solution at element nodes
-        real rA  = U(N[0],0);
-        real rB  = U(N[1],0);
-        real rC  = U(N[2],0);
-        real ruA = U(N[0],1);
-        real ruB = U(N[1],1);
-        real ruC = U(N[2],1);
-        real rvA = U(N[0],2);
-        real rvB = U(N[1],2);
-        real rvC = U(N[2],2);
-        real rwA = U(N[0],3);
-        real rwB = U(N[1],3);
-        real rwC = U(N[2],3);
-        real reA = U(N[0],4);
-        real reB = U(N[1],4);
-        real reC = U(N[2],4);
-        real w1A = W(N[0],0);
-        real w2A = W(N[0],1);
-        real w3A = W(N[0],2);
-        real w1B = W(N[1],0);
-        real w2B = W(N[1],1);
-        real w3B = W(N[1],2);
-        real w1C = W(N[2],0);
-        real w2C = W(N[2],1);
-        real w3C = W(N[2],2);
-        // apply stagnation BCs
-        if ( stagPoint(x[N[0]],y[N[0]],z[N[0]]) )
-        {
-          ruA = rvA = rwA = 0.0;
-        }
-        if ( stagPoint(x[N[1]],y[N[1]],z[N[1]]) )
-        {
-          ruB = rvB = rwB = 0.0;
-        }
-        if ( stagPoint(x[N[2]],y[N[2]],z[N[2]]) )
-        {
-          ruC = rvC = rwC = 0.0;
-        }
-        // compute face normal
-        real nx, ny, nz;
-        tk::normal( x[N[0]], x[N[1]], x[N[2]],
-                    y[N[0]], y[N[1]], y[N[2]],
-                    z[N[0]], z[N[1]], z[N[2]],
-                    nx, ny, nz );
-        // compute boundary flux
-        real f[m_ncomp][3];
-        real p, vn;
-        int sym = symbctri[e];
-        p = m_mat_blk[0].compute< EOS::pressure >( rA, ruA/rA, rvA/rA, rwA/rA,
-          reA );
-        vn = sym ? 0.0 : (nx*(ruA/rA-w1A) + ny*(rvA/rA-w2A) + nz*(rwA/rA-w3A));
-        f[0][0] = rA*vn;
-        f[1][0] = ruA*vn + p*nx;
-        f[2][0] = rvA*vn + p*ny;
-        f[3][0] = rwA*vn + p*nz;
-        f[4][0] = reA*vn + p*(sym ? 0.0 : (nx*ruA + ny*rvA + nz*rwA)/rA);
-        p = m_mat_blk[0].compute< EOS::pressure >( rB, ruB/rB, rvB/rB, rwB/rB,
-          reB );
-        vn = sym ? 0.0 : (nx*(ruB/rB-w1B) + ny*(rvB/rB-w2B) + nz*(rwB/rB-w3B));
-        f[0][1] = rB*vn;
-        f[1][1] = ruB*vn + p*nx;
-        f[2][1] = rvB*vn + p*ny;
-        f[3][1] = rwB*vn + p*nz;
-        f[4][1] = reB*vn + p*(sym ? 0.0 : (nx*ruB + ny*rvB + nz*rwB)/rB);
-        p = m_mat_blk[0].compute< EOS::pressure >( rC, ruC/rC, rvC/rC, rwC/rC,
-          reC );
-        vn = sym ? 0.0 : (nx*(ruC/rC-w1C) + ny*(rvC/rC-w2C) + nz*(rwC/rC-w3C));
-        f[0][2] = rC*vn;
-        f[1][2] = ruC*vn + p*nx;
-        f[2][2] = rvC*vn + p*ny;
-        f[3][2] = rwC*vn + p*nz;
-        f[4][2] = reC*vn + p*(sym ? 0.0 : (nx*ruC + ny*rvC + nz*rwC)/rC);
-        // compute face area
-        auto A6 = tk::area( x[N[0]], x[N[1]], x[N[2]],
-                            y[N[0]], y[N[1]], y[N[2]],
-                            z[N[0]], z[N[1]], z[N[2]] ) / 6.0;
-        auto A24 = A6/4.0;
-        // store flux in boundary elements
-        for (std::size_t c=0; c<m_ncomp; ++c) {
-          auto eb = (e*m_ncomp+c)*6;
-          auto Bab = A24 * (f[c][0] + f[c][1]);
-          bflux[eb+0] = Bab + A6 * f[c][0];
-          bflux[eb+1] = Bab;
-          Bab = A24 * (f[c][1] + f[c][2]);
-          bflux[eb+2] = Bab + A6 * f[c][1];
-          bflux[eb+3] = Bab;
-          Bab = A24 * (f[c][2] + f[c][0]);
-          bflux[eb+4] = Bab + A6 * f[c][2];
-          bflux[eb+5] = Bab;
-        }
-      }
+  // Find local-to-ghost tet id map for sender chare
+  const auto& n = tk::cref_find( myGhosts()->m_ghost, fromch );
+
+  for (std::size_t i=0; i<tetid.size(); ++i) {
+    auto j = tk::cref_find( n, tetid[i] );
+    Assert( j >= myGhosts()->m_fd.Esuel().size()/4,
+      "Receiving solution non-ghost data" );
+    auto b = tk::cref_find( myGhosts()->m_bid, j );
+    Assert( b < m_uc[2].size(), "Indexing out of bounds" );
+    Assert( b < m_pc[2].size(), "Indexing out of bounds" );
+    m_uc[2][b] = u[i];
+    m_pc[2][b] = prim[i];
+  }
+
+  // if we have received all solution ghost contributions from neighboring
+  // chares (chares we communicate along chare-boundary faces with), and
+  // contributed our solution to these neighbors, proceed to limiting
+  if (++m_nlim == myGhosts()->m_sendGhost.size()) {
+    m_nlim = 0;
+    comlim_complete();
+  }
+}
+
+void
+DG::dt()
+// *****************************************************************************
+// Compute time step size
+// *****************************************************************************
+{
+  auto d = Disc();
+
+  // Combine own and communicated contributions of limited solution and degrees
+  // of freedom in cells (if p-adaptive)
+  for (const auto& b : myGhosts()->m_bid) {
+    Assert( m_uc[2][b.second].size() == m_u.nprop(), "ncomp size mismatch" );
+    Assert( m_pc[2][b.second].size() == m_p.nprop(), "ncomp size mismatch" );
+    for (std::size_t c=0; c<m_u.nprop(); ++c) {
+      m_u(b.first,c) = m_uc[2][b.second][c];
+    }
+    for (std::size_t c=0; c<m_p.nprop(); ++c) {
+      m_p(b.first,c) = m_pc[2][b.second][c];
+    }
+  }
+
+  auto mindt = std::numeric_limits< tk::real >::max();
+
+  if (m_stage == 0)
+  {
+    auto const_dt = g_inputdeck.get< tag::dt >();
+    auto eps = std::numeric_limits< tk::real >::epsilon();
+
+    // use constant dt if configured
+    if (std::abs(const_dt) > eps) {
+
+      mindt = const_dt;
+
+    } else {      // compute dt based on CFL
+
+      // find the minimum dt across all PDEs integrated
+      auto eqdt =
+        g_dgpde[d->MeshId()].dt( myGhosts()->m_coord, myGhosts()->m_inpoel,
+          myGhosts()->m_fd,
+          myGhosts()->m_geoFace, myGhosts()->m_geoElem, m_ndof, m_u, m_p,
+          myGhosts()->m_fd.Esuel().size()/4 );
+      if (eqdt < mindt) mindt = eqdt;
+
+      mindt *= g_inputdeck.get< tag::cfl >();
+    }
+  }
+  else
+  {
+    mindt = d->Dt();
+  }
+
+  // Resize the buffer vector of nodal extrema
+  resizeNodalExtremac();
+
+  // Contribute to minimum dt across all chares then advance to next step
+  contribute( sizeof(tk::real), &mindt, CkReduction::min_double,
+              CkCallback(CkReductionTarget(DG,solve), thisProxy) );
+}
+
+void
+DG::solve( tk::real newdt )
+// *****************************************************************************
+// Compute right-hand side of discrete transport equations
+//! \param[in] newdt Size of this new time step
+// *****************************************************************************
+{
+  // Enable SDAG wait for building the solution vector during the next stage
+  thisProxy[ thisIndex ].wait4sol();
+  thisProxy[ thisIndex ].wait4refine();
+  thisProxy[ thisIndex ].wait4smooth();
+  thisProxy[ thisIndex ].wait4reco();
+  thisProxy[ thisIndex ].wait4nodalExtrema();
+  thisProxy[ thisIndex ].wait4lim();
+  thisProxy[ thisIndex ].wait4nod();
+
+  auto d = Disc();
+  const auto rdof = g_inputdeck.get< tag::rdof >();
+  const auto ndof = g_inputdeck.get< tag::ndof >();
+  const auto neq = m_u.nprop()/rdof;
+
+  // Set new time step size
+  if (m_stage == 0) d->setdt( newdt );
+
+  const auto pref = g_inputdeck.get< tag::pref, tag::pref >();
+  if (pref && m_stage == 0)
+  {
+    // When the element are coarsened, high order terms should be zero
+    for(std::size_t e = 0; e < myGhosts()->m_nunk; e++)
+    {
+      const auto ncomp= m_u.nprop()/rdof;
+      if(m_ndof[e] == 1)
+      {
+        for (std::size_t c=0; c<ncomp; ++c)
+        {
+          auto mark = c*rdof;
+          m_u(e, mark+1) = 0.0;
+          m_u(e, mark+2) = 0.0;
+          m_u(e, mark+3) = 0.0;
+        }
+      } else if(m_ndof[e] == 4)
+      {
+        for (std::size_t c=0; c<ncomp; ++c)
+        {
+          auto mark = c*ndof;
+          m_u(e, mark+4) = 0.0;
+          m_u(e, mark+5) = 0.0;
+          m_u(e, mark+6) = 0.0;
+          m_u(e, mark+7) = 0.0;
+          m_u(e, mark+8) = 0.0;
+          m_u(e, mark+9) = 0.0;
+        }
+      }
+    }
+  }
 
-      // access pointer to right hand side at component
-      std::array< const real*, m_ncomp > r;
-      for (ncomp_t c=0; c<m_ncomp; ++c) r[c] = R.cptr( c );
-
-      // boundary integrals: sum flux contributions to points
-      for (std::size_t e=0; e<triinpoel.size()/3; ++e)
-        for (std::size_t c=0; c<m_ncomp; ++c) {
-          auto eb = (e*m_ncomp+c)*6;
-          R.var(r[c],triinpoel[e*3+0]) -= bflux[eb+0] + bflux[eb+5];
-          R.var(r[c],triinpoel[e*3+1]) -= bflux[eb+1] + bflux[eb+2];
-          R.var(r[c],triinpoel[e*3+2]) -= bflux[eb+3] + bflux[eb+4];
-        }
-
-      tk::destroy(bflux);
-    }
-
-    //! Compute optional source integral
-    //! \param[in] coord Mesh node coordinates
-    //! \param[in] inpoel Mesh element connectivity
-    //! \param[in] t Physical time
-    //! \param[in] tp Physical time for each mesh node
-    //! \param[in,out] R Right-hand side vector computed
-    void src( const std::array< std::vector< real >, 3 >& coord,
-              const std::vector< std::size_t >& inpoel,
-              real t,
-              const std::vector< tk::real >& tp,
-              tk::Fields& R ) const
-    {
-      // access node coordinates
-      const auto& x = coord[0];
-      const auto& y = coord[1];
-      const auto& z = coord[2];
-
-      // access pointer to right hand side at component
-      std::array< const real*, m_ncomp > r;
-      for (ncomp_t c=0; c<m_ncomp; ++c) r[c] = R.cptr( c );
-
-      // source integral
-      for (std::size_t e=0; e<inpoel.size()/4; ++e) {
-        std::size_t N[4] =
-          { inpoel[e*4+0], inpoel[e*4+1], inpoel[e*4+2], inpoel[e*4+3] };
-        // compute element Jacobi determinant, J = 6V
-        auto J24 = tk::triple(
-          x[N[1]]-x[N[0]], y[N[1]]-y[N[0]], z[N[1]]-z[N[0]],
-          x[N[2]]-x[N[0]], y[N[2]]-y[N[0]], z[N[2]]-z[N[0]],
-          x[N[3]]-x[N[0]], y[N[3]]-y[N[0]], z[N[3]]-z[N[0]] ) / 24.0;
-        // sum source contributions to nodes
-        for (std::size_t a=0; a<4; ++a) {
-          std::vector< real > s(m_ncomp);
-          if (g_inputdeck.get< tag::steady_state >()) t = tp[N[a]];
-          Problem::src( 1, m_mat_blk, x[N[a]], y[N[a]], z[N[a]], t, s );
-          for (std::size_t c=0; c<m_ncomp; ++c)
-            R.var(r[c],N[a]) += J24 * s[c];
-        }
-      }
-    }
-
-    //! Compute sources corresponding to a propagating front in user-defined box
-    //! \param[in] V Total box volume
-    //! \param[in] t Physical time
-    //! \param[in] inpoel Element point connectivity
-    //! \param[in] esup Elements surrounding points
-    //! \param[in] boxnodes Mesh node ids within user-defined box
-    //! \param[in] coord Mesh node coordinates
-    //! \param[in] R Right-hand side vector
-    //! \details This function add the energy source corresponding to a planar
-    //!   wave-front propagating along the z-direction with a user-specified
-    //!   velocity, within a box initial condition, configured by the user.
-    //!   Example (SI) units of the quantities involved:
-    //!    * internal energy content (energy per unit volume): J/m^3
-    //!    * specific energy (internal energy per unit mass): J/kg
-    void boxSrc( real V,
-                 real t,
-                 const std::vector< std::size_t >& inpoel,
-                 const std::pair< std::vector< std::size_t >,
-                                  std::vector< std::size_t > >& esup,
-                 const std::unordered_set< std::size_t >& boxnodes,
-                 const std::array< std::vector< real >, 3 >& coord,
-                 tk::Fields& R ) const<--- Parameter 'R' can be declared with const
-    {
-      const auto& icbox = g_inputdeck.get< tag::ic, tag::box >();
-
-      if (!icbox.empty()) {
-        for (const auto& b : icbox) {   // for all boxes for this eq
-          std::vector< tk::real > box
-           { b.template get< tag::xmin >(), b.template get< tag::xmax >(),
-             b.template get< tag::ymin >(), b.template get< tag::ymax >(),
-             b.template get< tag::zmin >(), b.template get< tag::zmax >() };
-
-          auto boxenc = b.template get< tag::energy_content >();
-          Assert( boxenc > 0.0, "Box energy content must be nonzero" );
-
-          auto V_ex = (box[1]-box[0]) * (box[3]-box[2]) * (box[5]-box[4]);
+  // Update Un
+  if (m_stage == 0) m_un = m_u;
+
+  // Explicit or IMEX
+  const auto imex_runge_kutta = g_inputdeck.get< tag::imex_runge_kutta >();
+
+  // physical time at time-stage for computing exact source terms
+  tk::real physT(d->T());
+  if (m_stage == 1) {
+    physT += d->Dt();
+  }
+  else if (m_stage == 2) {
+    physT += 0.5*d->Dt();
+  }
+
+  if (imex_runge_kutta) {
+    if (m_stage == 0)
+    {
+      // Save previous rhs
+      m_rhsprev = m_rhs;
+      // Initialize m_stiffrhs to zero
+      m_stiffrhs.fill(0.0);
+      m_stiffrhsprev.fill(0.0);
+    }
+  }
+
+  g_dgpde[d->MeshId()].rhs( physT, myGhosts()->m_geoFace, myGhosts()->m_geoElem,
+    myGhosts()->m_fd, myGhosts()->m_inpoel, m_boxelems, myGhosts()->m_coord,
+    m_u, m_p, m_ndof, m_rho0mat, d->Dt(), m_rhs );
+
+  if (!imex_runge_kutta) {
+    // Explicit time-stepping using RK3 to discretize time-derivative
+    for(std::size_t e=0; e<myGhosts()->m_nunk; ++e)
+      for(std::size_t c=0; c<neq; ++c)
+      {
+        for (std::size_t k=0; k<m_numEqDof[c]; ++k)
+        {
+          auto rmark = c*rdof+k;
+          auto mark = c*ndof+k;
+          m_u(e, rmark) =  rkcoef[0][m_stage] * m_un(e, rmark)
+            + rkcoef[1][m_stage] * ( m_u(e, rmark)
+              + d->Dt() * m_rhs(e, mark)/m_lhs(e, mark) );
+          if(fabs(m_u(e, rmark)) < 1e-16)
+            m_u(e, rmark) = 0;
+        }
+      }
+  }
+  else {
+    // Implicit-Explicit time-stepping using RK3 to discretize time-derivative
+    DG::imex_integrate();
+  }
+
+  for(std::size_t e=0; e<myGhosts()->m_nunk; ++e)
+    for(std::size_t c=0; c<neq; ++c)
+    {
+      // zero out unused/reconstructed dofs of equations using reduced dofs
+      // (see DGMultiMat::numEquationDofs())
+      if (m_numEqDof[c] < rdof) {
+        for (std::size_t k=m_numEqDof[c]; k<rdof; ++k)
+        {
+          auto rmark = c*rdof+k;
+          m_u(e, rmark) = 0.0;
+        }
+      }
+    }
+
+  // Update primitives based on the evolved solution
+  g_dgpde[d->MeshId()].updateInterfaceCells( m_u,
+    myGhosts()->m_fd.Esuel().size()/4, m_ndof );
+  g_dgpde[d->MeshId()].updatePrimitives( m_u, m_lhs, myGhosts()->m_geoElem, m_p,
+    myGhosts()->m_fd.Esuel().size()/4 );
+  if (!g_inputdeck.get< tag::accuracy_test >()) {
+    g_dgpde[d->MeshId()].cleanTraceMaterial( physT, myGhosts()->m_geoElem, m_u,
+      m_p, myGhosts()->m_fd.Esuel().size()/4 );
+  }
+
+  if (m_stage < 2) {
+
+    // continue with next time step stage
+    stage();
+
+  } else {
+
+    // Increase number of iterations and physical time
+    d->next();
+
+    // Compute diagnostics, e.g., residuals
+    auto diag_computed = m_diag.compute( *d,
+      m_u.nunk()-myGhosts()->m_fd.Esuel().size()/4, myGhosts()->m_geoElem,
+      m_ndof, m_u, m_un );
+
+    // Continue to mesh refinement (if configured)
+    if (!diag_computed) refine( std::vector< tk::real >( m_u.nprop(), 0.0 ) );
 
-          // determine times at which sourcing is initialized and terminated
-          auto iv = b.template get< tag::front_speed >();
-          auto wFront = b.template get< tag::front_width >();
-          auto tInit = b.template get< tag::init_time >();
-          auto tFinal = tInit + (box[5] - box[4] - wFront) / std::fabs(iv);
-          auto aBox = (box[1]-box[0]) * (box[3]-box[2]);
-
-          const auto& x = coord[0];
-          const auto& y = coord[1];
-          const auto& z = coord[2];
-
-          if (t >= tInit && t <= tFinal) {
-            // The energy front is assumed to have a half-sine-wave shape. The
-            // half wave-length is the width of the front. At t=0, the center of
-            // this front (i.e. the peak of the partial-sine-wave) is at X_0 +
-            // W_0.  W_0 is calculated based on the width of the front and the
-            // direction of propagation (which is assumed to be along the
-            // z-direction).  If the front propagation velocity is positive, it
-            // is assumed that the initial position of the energy source is the
-            // minimum z-coordinate of the box; whereas if this velocity is
-            // negative, the initial position is the maximum z-coordinate of the
-            // box.
-
-            // Orientation of box
-            std::array< tk::real, 3 > b_orientn{{
-              b.template get< tag::orientation >()[0],
-              b.template get< tag::orientation >()[1],
-              b.template get< tag::orientation >()[2] }};
-            std::array< tk::real, 3 > b_centroid{{ 0.5*(box[0]+box[1]),
-              0.5*(box[2]+box[3]), 0.5*(box[4]+box[5]) }};
-            // Transform box to reference space
-            std::array< tk::real, 3 > b_min{{box[0], box[2], box[4]}};
-            std::array< tk::real, 3 > b_max{{box[1], box[3], box[5]}};
-            tk::movePoint(b_centroid, b_min);
-            tk::movePoint(b_centroid, b_max);
-
-            // initial center of front
-            tk::real zInit(b_min[2]);
-            if (iv < 0.0) zInit = b_max[2];
-            // current location of front
-            auto z0 = zInit + iv * (t-tInit);
-            auto z1 = z0 + std::copysign(wFront, iv);
-            tk::real s0(z0), s1(z1);
-            // if velocity of propagation is negative, initial position is z1
-            if (iv < 0.0) {
-              s0 = z1;
-              s1 = z0;
-            }
-            // Sine-wave (positive part of the wave) source term amplitude
-            auto pi = 4.0 * std::atan(1.0);
-            auto amplE = boxenc * V_ex * pi
-              / (aBox * wFront * 2.0 * (tFinal-tInit));
-            //// Square wave (constant) source term amplitude
-            //auto amplE = boxenc * V_ex
-            //  / (aBox * wFront * (tFinal-tInit));
-            //// arbitrary shape form
-            //auto amplE = boxenc * std::abs(iv) / wFront;
-            amplE *= V_ex / V;
-
-            // add source
-            for (auto p : boxnodes) {
-              std::array< tk::real, 3 > node{{ x[p], y[p], z[p] }};
-              // Transform node to reference space of box
-              tk::movePoint(b_centroid, node);
-              tk::rotatePoint({{-b_orientn[0], -b_orientn[1], -b_orientn[2]}},
-                node);
-
-              if (node[2] >= s0 && node[2] <= s1) {
-                auto S = amplE * std::sin(pi*(node[2]-s0)/wFront);
-                //// arbitrary shape form
-                //auto S = amplE;
-                for (auto e : tk::Around(esup,p)) {
-                  // access node IDs
-                  std::size_t N[4] =
-                    {inpoel[e*4+0], inpoel[e*4+1], inpoel[e*4+2], inpoel[e*4+3]};
-                  // compute element Jacobi determinant, J = 6V
-                  real bax = x[N[1]]-x[N[0]];
-                  real bay = y[N[1]]-y[N[0]];
-                  real baz = z[N[1]]-z[N[0]];
-                  real cax = x[N[2]]-x[N[0]];
-                  real cay = y[N[2]]-y[N[0]];
-                  real caz = z[N[2]]-z[N[0]];
-                  real dax = x[N[3]]-x[N[0]];
-                  real day = y[N[3]]-y[N[0]];
-                  real daz = z[N[3]]-z[N[0]];
-                  auto J =
-                    tk::triple( bax, bay, baz, cax, cay, caz, dax, day, daz );
-                  auto J24 = J/24.0;
-                  R(p,4) += J24 * S;
-                }
-              }
-            }
-          }
-        }
-      }
-    }
-
-};
-
-} // cg::
+  }
+}
+
+void
+DG::refine( [[maybe_unused]] const std::vector< tk::real >& l2res )
+// *****************************************************************************
+// Optionally refine/derefine mesh
+//! \param[in] l2res L2-norms of the residual for each scalar component
+//!   computed across the whole problem
+// *****************************************************************************
+{
+  auto d = Disc();
+
+  auto dtref = g_inputdeck.get< tag::amr, tag::dtref >();
+  auto dtfreq = g_inputdeck.get< tag::amr, tag::dtfreq >();
+
+  // if t>0 refinement enabled and we hit the dtref frequency
+  if (dtref && !(d->It() % dtfreq)) {   // refine
+
+    d->startvol();
+    d->Ref()->dtref( myGhosts()->m_fd.Bface(), {},
+      tk::remap(myGhosts()->m_fd.Triinpoel(),d->Gid()) );
+    d->refined() = 1;
+
+  } else {      // do not refine
+
+    d->refined() = 0;
+    stage();
+
+  }
+}
+
+void
+DG::resizePostAMR(
+  const std::vector< std::size_t >& /*ginpoel*/,
+  const tk::UnsMesh::Chunk& chunk,
+  const tk::UnsMesh::Coords& coord,
+  const std::unordered_map< std::size_t, tk::UnsMesh::Edge >& /*addedNodes*/,
+  const std::unordered_map< std::size_t, std::size_t >& addedTets,
+  const std::set< std::size_t >& removedNodes,
+  const std::unordered_map< std::size_t, std::size_t >& amrNodeMap,
+  const tk::NodeCommMap& nodeCommMap,
+  const std::map< int, std::vector< std::size_t > >& bface,
+  const std::map< int, std::vector< std::size_t > >& /* bnode */,
+  const std::vector< std::size_t >& triinpoel,
+  const std::unordered_map< std::size_t, std::set< std::size_t > >& elemblockid )
+// *****************************************************************************
+//  Receive new mesh from Refiner
+//! \param[in] chunk New mesh chunk (connectivity and global<->local id maps)
+//! \param[in] coord New mesh node coordinates
+//! \param[in] addedTets Newly added mesh cells and their parents (local ids)
+//! \param[in] removedNodes Newly removed mesh node local ids
+//! \param[in] amrNodeMap Node id map after amr (local ids)
+//! \param[in] nodeCommMap New node communication map
+//! \param[in] bface Boundary-faces mapped to side set ids
+//! \param[in] triinpoel Boundary-face connectivity
+//! \param[in] elemblockid Local tet ids associated with mesh block ids
+// *****************************************************************************
+{
+  auto d = Disc();
+
+  // Set flag that indicates that we are during time stepping
+  m_initial = 0;
+  myGhosts()->m_initial = 0;
+
+  // Zero field output iteration count between two mesh refinement steps
+  d->Itf() = 0;
+
+  // Increase number of iterations with mesh refinement
+  ++d->Itr();
+
+  // Save old number of elements
+  [[maybe_unused]] auto old_nelem = myGhosts()->m_inpoel.size()/4;
+
+  // Resize mesh data structures
+  d->resizePostAMR( chunk, coord, amrNodeMap, nodeCommMap, removedNodes,
+    elemblockid );
+
+  // Update state
+  myGhosts()->m_inpoel = d->Inpoel();
+  myGhosts()->m_coord = d->Coord();
+  auto nelem = myGhosts()->m_inpoel.size()/4;
+  m_p.resize( nelem );
+  m_u.resize( nelem );
+  m_un.resize( nelem );
+  m_lhs.resize( nelem );
+  m_rhs.resize( nelem );
+  m_rhsprev.resize( nelem );
+  m_stiffrhs.resize( nelem );
+  m_stiffrhsprev.resize( nelem );
+  m_uNodalExtrm.resize( Disc()->Bid().size(), std::vector<tk::real>( 2*
+    m_ndof_NodalExtrm*g_inputdeck.get< tag::ncomp >() ) );
+  m_pNodalExtrm.resize( Disc()->Bid().size(), std::vector<tk::real>( 2*
+    m_ndof_NodalExtrm*m_p.nprop()/g_inputdeck.get< tag::rdof >()));
+
+  // Resize the buffer vector of nodal extrema
+  resizeNodalExtremac();
+
+  myGhosts()->m_fd = FaceData( myGhosts()->m_inpoel, bface,
+    tk::remap(triinpoel,d->Lid()) );
 
-} // inciter::
-
-#endif // CGCompFlow_h
+  myGhosts()->m_geoFace =
+    tk::Fields( tk::genGeoFaceTri( myGhosts()->m_fd.Nipfac(),
+    myGhosts()->m_fd.Inpofa(), coord ) );
+  myGhosts()->m_geoElem = tk::Fields( tk::genGeoElemTet( myGhosts()->m_inpoel,
+    coord ) );
+
+  myGhosts()->m_nfac = myGhosts()->m_fd.Inpofa().size()/3;
+  myGhosts()->m_nunk = nelem;
+  m_npoin = coord[0].size();
+  myGhosts()->m_bndFace.clear();
+  myGhosts()->m_exptGhost.clear();
+  myGhosts()->m_sendGhost.clear();
+  myGhosts()->m_ghost.clear();
+  myGhosts()->m_esup.clear();
+
+  // Update solution on new mesh, P0 (cell center value) only for now
+  m_un = m_u;
+  auto pn = m_p;<--- Variable 'pn' is assigned a value that is never used.
+  auto unprop = m_u.nprop();<--- Variable 'unprop' is assigned a value that is never used.
+  auto pnprop = m_p.nprop();<--- Variable 'pnprop' is assigned a value that is never used.
+  for (const auto& [child,parent] : addedTets) {
+    Assert( child < nelem, "Indexing out of new solution vector" );
+    Assert( parent < old_nelem, "Indexing out of old solution vector" );
+    for (std::size_t i=0; i<unprop; ++i) m_u(child,i) = m_un(parent,i);
+    for (std::size_t i=0; i<pnprop; ++i) m_p(child,i) = pn(parent,i);
+  }
+  m_un = m_u;
+
+  // Resize communication buffers
+  m_ghosts[thisIndex].resizeComm();
+}
+
+bool
+DG::fieldOutput() const
+// *****************************************************************************
+// Decide wether to output field data
+//! \return True if field data is output in this step
+// *****************************************************************************
+{
+  auto d = Disc();
+
+  // Output field data
+  return d->fielditer() or d->fieldtime() or d->fieldrange() or d->finished();
+}
+
+bool
+DG::refinedOutput() const
+// *****************************************************************************
+// Decide if we write field output using a refined mesh
+//! \return True if field output will use a refined mesh
+// *****************************************************************************
+{
+  return g_inputdeck.get< tag::field_output, tag::refined >() &&
+         g_inputdeck.get< tag::scheme >() != ctr::SchemeType::DG;
+}
+
+void
+DG::writeFields(
+  CkCallback c,
+  const std::unordered_map< std::size_t, std::size_t >& addedTets )
+// *****************************************************************************
+// Output mesh field data
+//! \param[in] c Function to continue with after the write
+//! \param[in] addedTets Newly added mesh cells and their parents (local ids)
+// *****************************************************************************
+{
+  auto d = Disc();
+
+  const auto& inpoel = std::get< 0 >( m_outmesh.chunk );
+  auto esup = tk::genEsup( inpoel, 4 );
+  auto nelem = inpoel.size() / 4;
+
+  // Combine own and communicated contributions and finish averaging of node
+  // field output in chare boundary nodes
+  const auto& lid = std::get< 2 >( m_outmesh.chunk );
+  for (const auto& [g,f] : m_uNodefieldsc) {
+    Assert( m_uNodefields.nprop() == f.first.size(), "Size mismatch" );
+    auto p = tk::cref_find( lid, g );
+    for (std::size_t i=0; i<f.first.size(); ++i) {
+      m_uNodefields(p,i) += f.first[i];
+      m_uNodefields(p,i) /= static_cast< tk::real >(
+                              esup.second[p+1] - esup.second[p] + f.second );
+    }
+  }
+  tk::destroy( m_uNodefieldsc );
+  for (const auto& [g,f] : m_pNodefieldsc) {
+    Assert( m_pNodefields.nprop() == f.first.size(), "Size mismatch" );
+    auto p = tk::cref_find( lid, g );
+    for (std::size_t i=0; i<f.first.size(); ++i) {
+      m_pNodefields(p,i) += f.first[i];
+      m_pNodefields(p,i) /= static_cast< tk::real >(
+                              esup.second[p+1] - esup.second[p] + f.second );
+    }
+  }
+  tk::destroy( m_pNodefieldsc );
+
+  // Lambda to decide if a node (global id) is on a chare boundary of the field
+  // output mesh. p - global node id, return true if node is on the chare
+  // boundary.
+  auto chbnd = [ this ]( std::size_t p ) {
+    return
+      std::any_of( m_outmesh.nodeCommMap.cbegin(), m_outmesh.nodeCommMap.cend(),
+        [&](const auto& s) { return s.second.find(p) != s.second.cend(); } );
+  };
+
+  // Finish computing node field output averages in internal nodes
+  auto npoin = m_outmesh.coord[0].size();
+  auto& gid = std::get< 1 >( m_outmesh.chunk );
+  for (std::size_t p=0; p<npoin; ++p) {
+    if (!chbnd(gid[p])) {
+      auto n = static_cast< tk::real >( esup.second[p+1] - esup.second[p] );
+      for (std::size_t i=0; i<m_uNodefields.nprop(); ++i)
+        m_uNodefields(p,i) /= n;
+      for (std::size_t i=0; i<m_pNodefields.nprop(); ++i)
+        m_pNodefields(p,i) /= n;
+    }
+  }
+
+  // Collect field output from numerical solution requested by user
+  auto elemfields = numericFieldOutput( m_uElemfields, tk::Centering::ELEM,
+    g_dgpde[Disc()->MeshId()].OutVarFn(), m_pElemfields );
+  auto nodefields = numericFieldOutput( m_uNodefields, tk::Centering::NODE,
+    g_dgpde[Disc()->MeshId()].OutVarFn(), m_pNodefields );
+
+  // Collect field output from analytical solutions (if exist)
+  const auto& coord = m_outmesh.coord;
+  auto geoElem = tk::genGeoElemTet( inpoel, coord );
+  auto t = Disc()->T();
+  analyticFieldOutput( g_dgpde[d->MeshId()], tk::Centering::ELEM,
+    geoElem.extract_comp(1), geoElem.extract_comp(2), geoElem.extract_comp(3),
+    t, elemfields );
+  analyticFieldOutput( g_dgpde[d->MeshId()], tk::Centering::NODE, coord[0],
+    coord[1], coord[2], t, nodefields );
+
+  // Add adaptive indicator array to element-centered field output
+  if (g_inputdeck.get< tag::pref, tag::pref >()) {
+    std::vector< tk::real > ndof( begin(m_ndof), end(m_ndof) );
+    ndof.resize( nelem );
+    for (const auto& [child,parent] : addedTets)
+      ndof[child] = static_cast< tk::real >( m_ndof[parent] );
+    elemfields.push_back( ndof );
+  }
+
+  // Add shock detection marker array to element-centered field output
+  std::vector< tk::real > shockmarker( begin(m_shockmarker), end(m_shockmarker) );
+  // Here m_shockmarker has a size of m_u.nunk() which is the number of the
+  // elements within this partition (nelem) plus the ghost partition cells. In
+  // terms of output purpose, we only need the solution data within this
+  // partition. Therefore, resizing it to nelem removes the extra partition
+  // boundary allocations in the shockmarker vector. Since the code assumes that
+  // the boundary elements are on the top, the resize operation keeps the lower
+  // portion.
+  shockmarker.resize( nelem );
+  for (const auto& [child,parent] : addedTets)
+    shockmarker[child] = static_cast< tk::real >(m_shockmarker[parent]);
+  elemfields.push_back( shockmarker );
+
+  // Add rho0*det(g)/rho to make sure it is staying close to 1,
+  // averaged for all materials
+  std::vector< tk::real > densityConstr(nelem);
+  g_dgpde[d->MeshId()].computeDensityConstr(nelem, m_u, m_rho0mat,
+                                            densityConstr);
+  for (const auto& [child,parent] : addedTets)
+    densityConstr[child] = 0.0;
+  if (densityConstr.size() > 0) elemfields.push_back( densityConstr );
+
+  // Query fields names requested by user
+  auto elemfieldnames = numericFieldNames( tk::Centering::ELEM );
+  auto nodefieldnames = numericFieldNames( tk::Centering::NODE );
+
+  // Collect field output names for analytical solutions
+  analyticFieldNames( g_dgpde[d->MeshId()], tk::Centering::ELEM, elemfieldnames );
+  analyticFieldNames( g_dgpde[d->MeshId()], tk::Centering::NODE, nodefieldnames );
+
+  if (g_inputdeck.get< tag::pref, tag::pref >())
+    elemfieldnames.push_back( "NDOF" );
+
+  elemfieldnames.push_back( "shock_marker" );
+
+  if (densityConstr.size() > 0)
+    elemfieldnames.push_back( "density_constraint" );
+
+  Assert( elemfieldnames.size() == elemfields.size(), "Size mismatch" );
+  Assert( nodefieldnames.size() == nodefields.size(), "Size mismatch" );
+
+  // Output chare mesh and fields metadata to file
+  const auto& triinpoel = m_outmesh.triinpoel;
+  d->write( inpoel, m_outmesh.coord, m_outmesh.bface, {},
+            tk::remap( triinpoel, lid ), elemfieldnames, nodefieldnames,
+            {}, {}, elemfields, nodefields, {}, {}, c );
+}
+
+void
+DG::comnodeout( const std::vector< std::size_t >& gid,
+                const std::vector< std::size_t >& nesup,
+                const std::vector< std::vector< tk::real > >& Lu,
+                const std::vector< std::vector< tk::real > >& Lp )
+// *****************************************************************************
+//  Receive chare-boundary nodal solution (for field output) contributions from
+//  neighboring chares
+//! \param[in] gid Global mesh node IDs at which we receive contributions
+//! \param[in] nesup Number of elements surrounding points
+//! \param[in] Lu Partial contributions of solution nodal fields to
+//!   chare-boundary nodes
+//! \param[in] Lp Partial contributions of primitive quantity nodal fields to
+//!   chare-boundary nodes
+// *****************************************************************************
+{
+  Assert( gid.size() == nesup.size(), "Size mismatch" );
+  Assert(Lu.size() == m_uNodefields.nprop(), "Fields size mismatch");
+  Assert(Lp.size() == m_pNodefields.nprop(), "Fields size mismatch");
+  for (std::size_t f=0; f<Lu.size(); ++f)
+    Assert( gid.size() == Lu[f].size(), "Size mismatch" );
+  for (std::size_t f=0; f<Lp.size(); ++f)
+    Assert( gid.size() == Lp[f].size(), "Size mismatch" );
+
+  for (std::size_t i=0; i<gid.size(); ++i) {
+    auto& nfu = m_uNodefieldsc[ gid[i] ];
+    nfu.first.resize( Lu.size() );
+    for (std::size_t f=0; f<Lu.size(); ++f) nfu.first[f] += Lu[f][i];
+    nfu.second += nesup[i];
+    auto& nfp = m_pNodefieldsc[ gid[i] ];
+    nfp.first.resize( Lp.size() );
+    for (std::size_t f=0; f<Lp.size(); ++f) nfp.first[f] += Lp[f][i];
+    nfp.second += nesup[i];
+  }
+
+  // When we have heard from all chares we communicate with, this chare is done
+  if (++m_nnod == Disc()->NodeCommMap().size()) {
+    m_nnod = 0;
+    comnodeout_complete();
+  }
+}
+
+void
+DG::stage()
+// *****************************************************************************
+// Evaluate whether to continue with next time step stage
+// *****************************************************************************
+{
+  // Increment Runge-Kutta stage counter
+  ++m_stage;
+
+  // if not all Runge-Kutta stages complete, continue to next time stage,
+  // otherwise prepare for nodal field output
+  if (m_stage < 3)
+    next();
+  else
+    startFieldOutput( CkCallback(CkIndex_DG::step(), thisProxy[thisIndex]) );
+}
+
+void
+DG::evalLB( int nrestart )
+// *****************************************************************************
+// Evaluate whether to do load balancing
+//! \param[in] nrestart Number of times restarted
+// *****************************************************************************
+{
+  auto d = Disc();
+
+  // Detect if just returned from a checkpoint and if so, zero timers
+  d->restarted( nrestart );
+
+  const auto lbfreq = g_inputdeck.get< tag::cmd, tag::lbfreq >();
+  const auto nonblocking = g_inputdeck.get< tag::cmd, tag::nonblocking >();
+
+  // Load balancing if user frequency is reached or after the second time-step
+  if ( (d->It()) % lbfreq == 0 || d->It() == 2 ) {
+
+    AtSync();
+    if (nonblocking) next();
+
+  } else {
+
+    next();
+
+  }
+}
+
+void
+DG::evalRestart()
+// *****************************************************************************
+// Evaluate whether to save checkpoint/restart
+// *****************************************************************************
+{
+  auto d = Disc();
+
+  const auto rsfreq = g_inputdeck.get< tag::cmd, tag::rsfreq >();
+  const auto benchmark = g_inputdeck.get< tag::cmd, tag::benchmark >();
+
+  if (not benchmark and not (d->It() % rsfreq)) {
+
+    std::vector< std::size_t > meshdata{ /* finished = */ 0, d->MeshId() };
+    contribute( meshdata, CkReduction::nop,
+      CkCallback(CkReductionTarget(Transporter,checkpoint), d->Tr()) );
+
+  } else {
+
+    evalLB( /* nrestart = */ -1 );
+
+  }
+}
+
+void
+DG::step()
+// *****************************************************************************
+// Evaluate wether to continue with next time step
+// *****************************************************************************
+{
+  auto d = Disc();
+
+  // Output time history
+  if (d->histiter() or d->histtime() or d->histrange()) {
+    std::vector< std::vector< tk::real > > hist;
+    auto h = g_dgpde[d->MeshId()].histOutput( d->Hist(), myGhosts()->m_inpoel,
+      myGhosts()->m_coord, m_u, m_p );
+    hist.insert( end(hist), begin(h), end(h) );
+    d->history( std::move(hist) );
+  }
+
+  // Free memory storing output mesh
+  m_outmesh.destroy();
+
+  // Output one-liner status report to screen
+  d->status();
+  // Reset Runge-Kutta stage counter
+  m_stage = 0;
+
+  const auto term = g_inputdeck.get< tag::term >();
+  const auto nstep = g_inputdeck.get< tag::nstep >();
+  const auto eps = std::numeric_limits< tk::real >::epsilon();
+
+  // If neither max iterations nor max time reached, continue, otherwise finish
+  if (std::fabs(d->T()-term) > eps && d->It() < nstep) {
+
+    evalRestart();
+ 
+  } else {
+
+    auto meshid = d->MeshId();
+    d->contribute( sizeof(std::size_t), &meshid, CkReduction::nop,
+                   CkCallback(CkReductionTarget(Transporter,finish), d->Tr()) );
+
+  }
+}
+
+void
+DG::imex_integrate()
+{
+  /*****************************************************************************
+  Performs the Implicit-Explicit Runge-Kutta step.
+
+  \details Performs the Implicit-Explicit Runge-Kutta step. Scheme taken from
+  Cavaglieri, D., & Bewley, T. (2015). Low-storage implicit/explicit Runge–Kutta
+  schemes for the simulation of stiff high-dimensional ODE systems. Journal of
+  Computational Physics, 286, 172-193.
+
+  Scheme given by equations (25a,b):
+
+  u[0] = u[n] + dt * (expl_rkcoef[1,0]*R_ex(u[n])+impl_rkcoef[1,1]*R_im(u[0]))
+
+  u[1] = u[n] + dt * (expl_rkcoef[2,1]*R_ex(u[0])+impl_rkcoef[2,1]*R_im(u[0])
+                                                 +impl_rkcoef[2,2]*R_im(u[1]))
+
+  u[n+1] = u[n] + dt * (expl_rkcoef[3,1]*R_ex(u[0])+impl_rkcoef[3,1]*R_im(u[0])
+                        expl_rkcoef[3,2]*R_ex(u[1])+impl_rkcoef[3,2]*R_im(u[1]))
+
+  In order to solve the first two equations we need to solve a series of systems
+  of non-linear equations:
+
+  F1(u[0]) = B1 + R1(u[0]) = 0, and
+  F2(u[1]) = B2 + R2(u[1]) = 0,
+
+  where
+
+  B1 = u[n] + dt * expl_rkcoef[1,0]*R_ex(u[n]),
+  R1 = dt * impl_rkcoef[1,1]*R_im(u[0]) - u([0]),
+  B2 = u[n] + dt * (expl_rkcoef[2,1]*R_ex(u[0])+impl_rkcoef[2,1]*R_im(u[0])),
+  R2 = dt * impl_rkcoef[2,2]*R_im(u[1]) - u([1]).
+
+  In order to solve the non-linear system F(U) = 0, we employ Broyden's method.
+  Taken from https://en.wikipedia.org/wiki/Broyden%27s_method.
+  The method consists in obtaining an approximation for the inverse of the
+  Jacobian H = J^(-1) and advancing in a quasi-newton step:
+
+  U[k+1] = U[k] - H[k]*F(U[k]),
+
+  until F(U) is close enough to zero.
+
+  The approximation H[k] is improved at every iteration following
+
+  H[k] = H[k-1] + (DU[k]-H[k-1]*DF[k])/(DU[k]^T*H[k-1]*DF[k]) * DU[k]^T*H[k-1],
+
+  where DU[k] = U[k] - U[k-1] and DF[k] = F(U[k]) - F(U[k-1)).
+
+  This function performs the following main algorithmic steps:
+  - If stage == 0 or stage == 1:
+    - Take Initial value:
+      U[0] = U[n] + dt * expl_rkcoef[1,0]*R_ex(U[n]) (for stage 0)
+      U[1] = U[n] + dt * (expl_rkcoef[2,1]*R_ex(U[0])
+                         +impl_rkcoef[2,1]*R_im(U[0])) (for stage 1)
+    - Loop over the Elements (e++)
+      - Initialize Jacobian inverse approximation as the identity
+      - Compute implicit right-hand-side (F_im) with current U
+      - Iterate for the solution (iter++)
+        - Compute new solution U[k+1] = U[k] - H[k]*F(U[k])
+        - Compute implicit right-hand-side (F_im) with current U
+        - Compute DU and DF
+        - Update inverse Jacobian approximation by:
+          - Compute V1 = H[k-1]*DF[k] and V2 = DU[k]^T*H[k-1]
+          - Compute d = DU[k]^T*V1 and V3 = DU[k]-V1
+          - Compute V4 = V3/d
+          - Update H[k] = H[k-1] + V4*V2
+        - Save old U and F
+        - Compute absolute and relative errors
+        - Break iterations if error < tol or iter == max_iter
+     - Update explicit equations using only the explicit terms.
+  - Else if stage == 2:
+     - Update explicit equations using only the explicit terms.
+     - Update implicit equations using:
+     u[n+1] = u[n]+dt*(expl_rkcoef[3,1]*R_ex(u[0])+impl_rkcoef[3,1]*R_im(u[0])
+                       expl_rkcoef[3,2]*R_ex(u[1])+impl_rkcoef[3,2]*R_im(u[1]))
+
+  ******************************************************************************/
+  auto d = Disc();
+  const auto rdof = g_inputdeck.get< tag::rdof >();
+  const auto ndof = g_inputdeck.get< tag::ndof >();
+  if (m_stage < 2) {
+    // Save previous stiff_rhs
+    m_stiffrhsprev = m_stiffrhs;
+
+    // Compute the imex update
+
+    // Integrate explicitly on the imex equations
+    // (To use as initial values)
+    for (std::size_t e=0; e<myGhosts()->m_nunk; ++e)
+      for (std::size_t c=0; c<m_nstiffeq; ++c)
+      {
+        for (std::size_t k=0; k<m_numEqDof[c]; ++k)
+        {
+          auto rmark = m_stiffEqIdx[c]*rdof+k;
+          auto mark = m_stiffEqIdx[c]*ndof+k;
+          m_u(e, rmark) =  m_un(e, rmark) + d->Dt() * (
+            expl_rkcoef[0][m_stage] * m_rhsprev(e, mark)/m_lhs(e, mark)
+            + expl_rkcoef[1][m_stage] * m_rhs(e, mark)/m_lhs(e, mark)
+            + impl_rkcoef[0][m_stage]
+            * m_stiffrhsprev(e,c*ndof+k)/m_lhs(e, mark) );
+          if(fabs(m_u(e, rmark)) < 1e-16)
+            m_u(e, rmark) = 0;
+        }
+      }
+
+    // Solve for implicit-explicit equations
+    const auto nelem = myGhosts()->m_fd.Esuel().size()/4;
+    for (std::size_t e=0; e<nelem; ++e)
+    {
+      // Non-linear system f(u) = 0 to be solved
+      // Broyden's method
+      // Control parameters
+      std::size_t max_iter = g_inputdeck.get< tag::imex_maxiter >();
+      tk::real rel_tol = g_inputdeck.get< tag::imex_reltol >();
+      tk::real abs_tol = g_inputdeck.get< tag::imex_abstol >();
+      tk::real rel_err = rel_tol+1;
+      tk::real abs_err = abs_tol+1;
+      std::size_t nstiff = m_nstiffeq*ndof;
+
+      // Initialize Jacobian to be the identity
+      std::vector< std::vector< tk::real > >
+        approx_jacob(nstiff, std::vector< tk::real >(nstiff, 0.0));
+      for (std::size_t i=0; i<nstiff; ++i)
+        approx_jacob[i][i] = 1.0e+00;
+
+      // Save explicit terms to be re-used
+      std::vector< tk::real > expl_terms(nstiff, 0.0);
+      for (size_t ieq=0; ieq<m_nstiffeq; ++ieq)
+        for (size_t idof=0; idof<m_numEqDof[ieq]; ++idof)
+        {
+          auto stiffmark = m_stiffEqIdx[ieq]*ndof+idof;
+          auto stiffrmark = m_stiffEqIdx[ieq]*rdof+idof;
+          expl_terms[ieq*ndof+idof] = m_un(e, stiffrmark)
+            + d->Dt() * ( expl_rkcoef[0][m_stage]
+            * m_rhsprev(e,stiffmark)/m_lhs(e,stiffmark)
+            + expl_rkcoef[1][m_stage]
+            * m_rhs(e,stiffmark)/m_lhs(e,stiffmark)
+            + impl_rkcoef[0][m_stage]
+            * m_stiffrhsprev(e,ieq*ndof+idof)/m_lhs(e,stiffmark) );
+        }
+
+      // Compute stiff_rhs with initial u
+      g_dgpde[d->MeshId()].stiff_rhs( e, myGhosts()->m_geoElem,
+        myGhosts()->m_inpoel, myGhosts()->m_coord,
+        m_u, m_p, m_ndof, m_stiffrhs );
+
+      // Make auxiliary u_old and f_old to store previous values
+      std::vector< tk::real > u_old(nstiff, 0.0), f_old(nstiff, 0.0);
+      // Make delta_u and delta_f
+      std::vector< tk::real > delta_u(nstiff, 0.0), delta_f(nstiff, 0.0);
+      // Store f
+      std::vector< tk::real > f(nstiff, 0.0);
+      for (std::size_t ieq=0; ieq<m_nstiffeq; ++ieq)
+        for (std::size_t idof=0; idof<m_numEqDof[ieq]; ++idof)
+        {
+          auto stiffrmark = m_stiffEqIdx[ieq]*rdof+idof;
+          auto stiffmark = m_stiffEqIdx[ieq]*ndof+idof;
+          f[ieq*ndof+idof] = expl_terms[ieq*ndof+idof]
+            + d->Dt() * impl_rkcoef[1][m_stage]
+            * m_stiffrhs(e,ieq*ndof+idof)/m_lhs(e,stiffmark)
+            - m_u(e, stiffrmark);
+        }
+
+      // Initialize u_old and f_old
+      for (std::size_t ieq=0; ieq<m_nstiffeq; ++ieq)
+        for (std::size_t idof=0; idof<m_numEqDof[ieq]; ++idof)
+        {
+          u_old[ieq*ndof+idof] = m_u(e, m_stiffEqIdx[ieq]*rdof+idof);
+          f_old[ieq*ndof+idof] = f[ieq*ndof+idof];
+        }
+
+      // Store the norm of f initially, for relative error measure
+      tk::real err0 = 0.0;
+      for (std::size_t ieq=0; ieq<m_nstiffeq; ++ieq)
+        for (std::size_t idof=0; idof<m_numEqDof[ieq]; ++idof)
+          err0 += f[ieq*ndof+idof]*f[ieq*ndof+idof];
+      err0 = std::sqrt(err0);
+
+      // Iterate for the solution if err0 > 0
+      if (err0 > abs_tol)
+        for (size_t iter=0; iter<max_iter; ++iter)
+        {
+
+          // Compute new solution
+          tk::real delta;
+          for (std::size_t ieq=0; ieq<m_nstiffeq; ++ieq)
+            for (std::size_t idof=0; idof<m_numEqDof[ieq]; ++idof)
+            {
+              delta = 0.0;
+              for (std::size_t jeq=0; jeq<m_nstiffeq; ++jeq)
+                for (std::size_t jdof=0; jdof<m_numEqDof[jeq]; ++jdof)
+                  delta +=
+                    approx_jacob[ieq*ndof+idof][jeq*ndof+jdof] * f[jeq*ndof+jdof];
+              // Update u
+              auto stiffrmark = m_stiffEqIdx[ieq]*rdof+idof;
+              m_u(e, stiffrmark) -= delta;
+            }
+
+          // Compute new stiff_rhs
+          g_dgpde[d->MeshId()].stiff_rhs( e, myGhosts()->m_geoElem,
+            myGhosts()->m_inpoel, myGhosts()->m_coord,
+            m_u, m_p, m_ndof, m_stiffrhs );
+
+          // Compute new f(u)
+          for (std::size_t ieq=0; ieq<m_nstiffeq; ++ieq)
+            for (std::size_t idof=0; idof<m_numEqDof[ieq]; ++idof)
+            {
+              auto stiffrmark = m_stiffEqIdx[ieq]*rdof+idof;
+              auto stiffmark = m_stiffEqIdx[ieq]*ndof+idof;
+              f[ieq*ndof+idof] = expl_terms[ieq*ndof+idof]
+                + d->Dt() * impl_rkcoef[1][m_stage]
+                * m_stiffrhs(e,ieq*ndof+idof)/m_lhs(e,stiffmark)
+                - m_u(e, stiffrmark);
+            }
+
+          // Compute delta_u and delta_f
+          for (std::size_t ieq=0; ieq<m_nstiffeq; ++ieq)
+            for (std::size_t idof=0; idof<m_numEqDof[ieq]; ++idof)
+            {
+              auto stiffrmark = m_stiffEqIdx[ieq]*rdof+idof;
+              delta_u[ieq*ndof+idof] = m_u(e, stiffrmark) - u_old[ieq*ndof+idof];
+              delta_f[ieq*ndof+idof] = f[ieq*ndof+idof] - f_old[ieq*ndof+idof];
+            }
+
+          // Update inverse Jacobian approximation
+
+          // 1. Compute approx_jacob*delta_f and delta_u*jacob_approx
+          tk::real sum1, sum2;
+          std::vector< tk::real > auxvec1(nstiff, 0.0), auxvec2(nstiff, 0.0);
+          for (std::size_t ieq=0; ieq<m_nstiffeq; ++ieq)
+            for (std::size_t idof=0; idof<m_numEqDof[ieq]; ++idof)
+            {
+              sum1 = 0.0;
+              sum2 = 0.0;
+              for (std::size_t jeq=0; jeq<m_nstiffeq; ++jeq)
+                for (std::size_t jdof=0; jdof<m_numEqDof[jeq]; ++jdof)
+                {
+                  sum1 += approx_jacob[ieq*ndof+idof][jeq*ndof+jdof] *
+                    delta_f[jeq*ndof+jdof];
+                  sum2 += delta_u[jeq*ndof+jdof] *
+                    approx_jacob[jeq*ndof+jdof][ieq*ndof+idof];
+                }
+              auxvec1[ieq*ndof+idof] = sum1;
+              auxvec2[ieq*ndof+idof] = sum2;
+            }
+
+          // 2. Compute delta_u*approx_jacob*delta_f
+          // and delta_u-approx_jacob*delta_f
+          tk::real denom = 0.0;
+          for (std::size_t jeq=0; jeq<m_nstiffeq; ++jeq)
+            for (std::size_t jdof=0; jdof<m_numEqDof[jeq]; ++jdof)
+            {
+              denom += delta_u[jeq*ndof+jdof]*auxvec1[jeq*ndof+jdof];
+              auxvec1[jeq*ndof+jdof] =
+                delta_u[jeq*ndof+jdof]-auxvec1[jeq*ndof+jdof];
+            }
+
+          // 3. Divide delta_u+approx_jacob*delta_f
+          // by delta_u*(approx_jacob*delta_f)
+          if (std::abs(denom) < 1.0e-18)
+          {
+            if (denom < 0.0)
+            {
+              for (std::size_t jeq=0; jeq<m_nstiffeq; ++jeq)
+                for (std::size_t jdof=0; jdof<m_numEqDof[jeq]; ++jdof)
+                  auxvec1[jeq*ndof+jdof] /= -1.0e-18;
+            }
+            else
+            {
+              for (std::size_t jeq=0; jeq<m_nstiffeq; ++jeq)
+                for (std::size_t jdof=0; jdof<m_numEqDof[jeq]; ++jdof)
+                  auxvec1[jeq*ndof+jdof] /= 1.0e-18;
+            }
+          }
+          else
+          {
+            for (std::size_t jeq=0; jeq<m_nstiffeq; ++jeq)
+              for (std::size_t jdof=0; jdof<m_numEqDof[jeq]; ++jdof)
+                auxvec1[jeq*ndof+jdof] /= denom;
+          }
+
+          // 4. Perform outter product between the two arrays and
+          // add that quantity to the new jacobian approximation
+          for (std::size_t ieq=0; ieq<m_nstiffeq; ++ieq)
+            for (std::size_t idof=0; idof<m_numEqDof[ieq]; ++idof)
+              for (std::size_t jeq=0; jeq<m_nstiffeq; ++jeq)
+                for (std::size_t jdof=0; jdof<m_numEqDof[jeq]; ++jdof)
+                  approx_jacob[ieq*ndof+idof][jeq*ndof+jdof] +=
+                    auxvec1[ieq*ndof+idof] * auxvec2[jeq*ndof+jdof];
+
+          // Save solution and f
+          for (std::size_t ieq=0; ieq<m_nstiffeq; ++ieq)
+            for (std::size_t idof=0; idof<m_numEqDof[ieq]; ++idof)
+            {
+              u_old[ieq*ndof+idof] = m_u(e, m_stiffEqIdx[ieq]*rdof+idof);
+              f_old[ieq*ndof+idof] = f[ieq*ndof+idof];
+            }
+
+          // Compute a measure of error, use norm of f
+          tk::real err = 0.0;
+          for (std::size_t ieq=0; ieq<m_nstiffeq; ++ieq)
+            for (std::size_t idof=0; idof<m_numEqDof[ieq]; ++idof)
+              err += f[ieq*ndof+idof]*f[ieq*ndof+idof];
+          abs_err = std::sqrt(err);
+          rel_err = abs_err/err0;
+
+          // Check if error condition is met and loop back
+          if (rel_err < rel_tol || abs_err < abs_tol)
+            break;
+
+          // If we did not converge, print a message
+          if (iter == max_iter-1)
+          {
+            printf("\nIMEX-RK: Non-linear solver did not converge in %lu iterations\n", max_iter);<--- %lu in format string (no. 1) requires 'unsigned long' but the argument type is 'std::size_t {aka unsigned long}'.
+            printf("Element #%lu\n", e);<--- %lu in format string (no. 1) requires 'unsigned long' but the argument type is 'std::size_t {aka unsigned long}'.
+            printf("Relative error: %e\n", rel_err);
+            printf("Absolute error: %e\n\n", abs_err);
+          }
+        }
+    }
+
+    // Then, integrate explicitly on the remaining equations
+    for (std::size_t e=0; e<nelem; ++e)
+      for (std::size_t c=0; c<m_nnonstiffeq; ++c)
+      {
+        for (std::size_t k=0; k<m_numEqDof[c]; ++k)
+        {
+          auto rmark = m_nonStiffEqIdx[c]*rdof+k;
+          auto mark = m_nonStiffEqIdx[c]*ndof+k;
+          m_u(e, rmark) =  m_un(e, rmark) + d->Dt() * (
+            expl_rkcoef[0][m_stage] * m_rhsprev(e, mark)/m_lhs(e, mark)
+            + expl_rkcoef[1][m_stage] * m_rhs(e, mark)/m_lhs(e, mark));
+          if(fabs(m_u(e, rmark)) < 1e-16)
+            m_u(e, rmark) = 0;
+        }
+      }
+  }
+  else {
+    // For last stage just use all previously computed stages
+    const auto nelem = myGhosts()->m_fd.Esuel().size()/4;
+    for (std::size_t e=0; e<nelem; ++e)
+    {
+      // First integrate explicitly on nonstiff equations
+      for (std::size_t c=0; c<m_nnonstiffeq; ++c)
+      {
+        for (std::size_t k=0; k<m_numEqDof[c]; ++k)
+        {
+          auto rmark = m_nonStiffEqIdx[c]*rdof+k;
+          auto mark = m_nonStiffEqIdx[c]*ndof+k;
+          m_u(e, rmark) =  m_un(e, rmark) + d->Dt() * (
+            expl_rkcoef[0][m_stage] * m_rhsprev(e, mark)/m_lhs(e, mark)
+            + expl_rkcoef[1][m_stage] * m_rhs(e, mark)/m_lhs(e, mark));
+          if(fabs(m_u(e, rmark)) < 1e-16)
+            m_u(e, rmark) = 0;
+        }
+      }
+      // Then, integrate the imex-equations
+      for (std::size_t ieq=0; ieq<m_nstiffeq; ++ieq)
+        for (std::size_t idof=0; idof<m_numEqDof[ieq]; ++idof)
+        {
+          auto rmark = m_stiffEqIdx[ieq]*rdof+idof;
+          auto mark = m_stiffEqIdx[ieq]*ndof+idof;
+          m_u(e, rmark) = m_un(e, rmark)
+            + d->Dt() * (expl_rkcoef[0][m_stage]
+                         * m_rhsprev(e,mark)/m_lhs(e,mark)
+                         + expl_rkcoef[1][m_stage]
+                         * m_rhs(e,mark)/m_lhs(e,mark)
+                         + impl_rkcoef[0][m_stage]
+                         * m_stiffrhsprev(e,ieq*ndof+idof)/m_lhs(e,mark)
+                         + impl_rkcoef[1][m_stage]
+                         * m_stiffrhs(e,ieq*ndof+idof)/m_lhs(e,mark) );
+          if(fabs(m_u(e, rmark)) < 1e-16)
+            m_u(e, rmark) = 0;
+        }
+    }
+  }
+}
+
+#include "NoWarning/dg.def.h"
 
diff --git a/Debug/cppcheck/58.html b/Debug/cppcheck/58.html index 655a840d3ab0..c8de68bfd969 100644 --- a/Debug/cppcheck/58.html +++ b/Debug/cppcheck/58.html @@ -152,12 +152,12 @@
  1
@@ -327,174 +327,1434 @@ 

Cppcheck report - [

// *****************************************************************************
+168
+169
+170
+171
+172
+173
+174
+175
+176
+177
+178
+179
+180
+181
+182
+183
+184
+185
+186
+187
+188
+189
+190
+191
+192
+193
+194
+195
+196
+197
+198
+199
+200
+201
+202
+203
+204
+205
+206
+207
+208
+209
+210
+211
+212
+213
+214
+215
+216
+217
+218
+219
+220
+221
+222
+223
+224
+225
+226
+227
+228
+229
+230
+231
+232
+233
+234
+235
+236
+237
+238
+239
+240
+241
+242
+243
+244
+245
+246
+247
+248
+249
+250
+251
+252
+253
+254
+255
+256
+257
+258
+259
+260
+261
+262
+263
+264
+265
+266
+267
+268
+269
+270
+271
+272
+273
+274
+275
+276
+277
+278
+279
+280
+281
+282
+283
+284
+285
+286
+287
+288
+289
+290
+291
+292
+293
+294
+295
+296
+297
+298
+299
+300
+301
+302
+303
+304
+305
+306
+307
+308
+309
+310
+311
+312
+313
+314
+315
+316
+317
+318
+319
+320
+321
+322
+323
+324
+325
+326
+327
+328
+329
+330
+331
+332
+333
+334
+335
+336
+337
+338
+339
+340
+341
+342
+343
+344
+345
+346
+347
+348
+349
+350
+351
+352
+353
+354
+355
+356
+357
+358
+359
+360
+361
+362
+363
+364
+365
+366
+367
+368
+369
+370
+371
+372
+373
+374
+375
+376
+377
+378
+379
+380
+381
+382
+383
+384
+385
+386
+387
+388
+389
+390
+391
+392
+393
+394
+395
+396
+397
+398
+399
+400
+401
+402
+403
+404
+405
+406
+407
+408
+409
+410
+411
+412
+413
+414
+415
+416
+417
+418
+419
+420
+421
+422
+423
+424
+425
+426
+427
+428
+429
+430
+431
+432
+433
+434
+435
+436
+437
+438
+439
+440
+441
+442
+443
+444
+445
+446
+447
+448
+449
+450
+451
+452
+453
+454
+455
+456
+457
+458
+459
+460
+461
+462
+463
+464
+465
+466
+467
+468
+469
+470
+471
+472
+473
+474
+475
+476
+477
+478
+479
+480
+481
+482
+483
+484
+485
+486
+487
+488
+489
+490
+491
+492
+493
+494
+495
+496
+497
+498
+499
+500
+501
+502
+503
+504
+505
+506
+507
+508
+509
+510
+511
+512
+513
+514
+515
+516
+517
+518
+519
+520
+521
+522
+523
+524
+525
+526
+527
+528
+529
+530
+531
+532
+533
+534
+535
+536
+537
+538
+539
+540
+541
+542
+543
+544
+545
+546
+547
+548
+549
+550
+551
+552
+553
+554
+555
+556
+557
+558
+559
+560
+561
+562
+563
+564
+565
+566
+567
+568
+569
+570
+571
+572
+573
+574
+575
+576
+577
+578
+579
+580
+581
+582
+583
+584
+585
+586
+587
+588
+589
+590
+591
+592
+593
+594
+595
+596
+597
+598
+599
+600
+601
+602
+603
+604
+605
+606
+607
+608
+609
+610
+611
+612
+613
+614
+615
+616
+617
+618
+619
+620
+621
+622
+623
+624
+625
+626
+627
+628
+629
+630
+631
+632
+633
+634
+635
+636
+637
+638
+639
+640
+641
+642
+643
+644
+645
+646
+647
+648
+649
+650
+651
+652
+653
+654
+655
+656
+657
+658
+659
+660
+661
+662
+663
+664
+665
+666
+667
+668
+669
+670
+671
+672
+673
+674
+675
+676
+677
+678
+679
+680
+681
+682
+683
+684
+685
+686
+687
+688
+689
+690
+691
+692
+693
+694
+695
+696
+697
+698
+699
+700
+701
+702
+703
+704
+705
+706
+707
+708
+709
+710
+711
+712
+713
+714
+715
+716
+717
+718
+719
+720
+721
+722
+723
+724
+725
+726
+727
+728
+729
+730
+731
+732
+733
+734
+735
+736
+737
+738
+739
+740
+741
+742
+743
+744
+745
+746
+747
+748
+749
+750
+751
+752
+753
+754
+755
+756
+757
+758
+759
+760
+761
+762
+763
+764
+765
+766
+767
+768
+769
+770
+771
+772
+773
+774
+775
+776
+777
+778
+779
+780
+781
+782
+783
+784
+785
+786
+787
+788
+789
+790
+791
+792
+793
+794
+795
+796
+797
+798
// *****************************************************************************
 /*!
-  \file      src/PDE/ConfigureCompFlow.cpp
+  \file      src/PDE/Transport/CGTransport.hpp
   \copyright 2012-2015 J. Bakosi,
              2016-2018 Los Alamos National Security, LLC.,
              2019-2021 Triad National Security, LLC.
              All rights reserved. See the LICENSE file for details.
-  \brief     Register and compile configuration for compressible flow PDE
-  \details   Register and compile configuration for compressible flow PDE.
-*/
-// *****************************************************************************
-
-#include <set>
-#include <map>
-#include <vector>
-#include <string>
-#include <limits>
-
-#include <brigand/algorithms/for_each.hpp>
-
-#include "Tags.hpp"
-#include "CartesianProduct.hpp"
-#include "PDEFactory.hpp"
-#include "Inciter/Options/PDE.hpp"
-#include "ContainerUtil.hpp"
-#include "ConfigureCompFlow.hpp"
-#include "CompFlow/Physics/CG.hpp"
-#include "CompFlow/Physics/DG.hpp"
-#include "CompFlow/CGCompFlow.hpp"
-#include "CompFlow/DGCompFlow.hpp"
-#include "CompFlow/Problem.hpp"
-
-namespace inciter {
-
-void
-registerCompFlow( CGFactory& cf,
-                  DGFactory& df,
-                  std::set< ctr::PDEType >& cgt,
-                  std::set< ctr::PDEType >& dgt )
-// *****************************************************************************
-// Register compressible flow PDE into PDE factory
-//! \param[in,out] cf Continuous Galerkin PDE factory to register to
-//! \param[in,out] df Discontinuous Galerkin PDE factory to register to
-//! \param[in,out] cgt Counters for equation types registered into CG factory
-//! \param[in,out] dgt Counters for equation types registered into DG factory
-// *****************************************************************************
-{
-  // Construct vector of vectors for all possible policies
-  using CGCompFlowPolicies =
-    tk::cartesian_product< cg::CompFlowPhysics, CompFlowProblems >;
-  // Register PDEs for all combinations of policies
-  brigand::for_each< CGCompFlowPolicies >(
-    registerCG< cg::CompFlow >( cf, cgt, ctr::PDEType::COMPFLOW ) );
-
-  // Construct vector of vectors for all possible policies
-  using DGCompFlowPolicies =
-    tk::cartesian_product< dg::CompFlowPhysics, CompFlowProblems >;
-  // Register PDEs for all combinations of policies
-  brigand::for_each< DGCompFlowPolicies >(
-    registerDG< dg::CompFlow >( df, dgt, ctr::PDEType::COMPFLOW ) );
-}
-
-std::vector< std::pair< std::string, std::string > >
-infoCompFlow( std::map< ctr::PDEType, tk::ncomp_t >& cnt )
-// *****************************************************************************
-//  Return information on the compressible flow system of PDEs
-//! \param[inout] cnt std::map of counters for all PDE types
-//! \return vector of string pairs describing the PDE configuration
-// *****************************************************************************
-{
-  using eq = tag::compflow;
-  using tk::parameter;
-  using tk::parameters;
-
-  auto c = ++cnt[ ctr::PDEType::COMPFLOW ];       // count eqs
-  --c;  // used to index vectors starting with 0<--- Variable 'c' is assigned a value that is never used.
-
-  std::vector< std::pair< std::string, std::string > > nfo;
-
-  nfo.emplace_back( ctr::PDE().name( ctr::PDEType::COMPFLOW ), "" );
-
-  nfo.emplace_back( "physics", ctr::Physics().name(
-    g_inputdeck.get< eq, tag::physics >() ) );
-
-  nfo.emplace_back( "problem", ctr::Problem().name(
-    g_inputdeck.get< eq, tag::problem >() ) );
-
-  auto ncomp = g_inputdeck.get< tag::ncomp >();
-  nfo.emplace_back( "number of components", parameter( ncomp ) );
-
-  const auto scheme = g_inputdeck.get< tag::scheme >();
-  if (scheme != ctr::SchemeType::ALECG && scheme != ctr::SchemeType::OversetFE)
-    nfo.emplace_back( "flux", ctr::Flux().name(
-      g_inputdeck.get< tag::flux >() ) );
-
-  // ICs
-
-  const auto& ic = g_inputdeck.get< tag::ic >();
-
-  const auto& icbox = ic.get< tag::box >();
-  if (!icbox.empty()) {
-    std::size_t bcnt = 0;
-    for (const auto& b : icbox) {   // for all boxes configured for this eq
-      std::vector< tk::real > box
-        { b.get< tag::xmin >(), b.get< tag::xmax >(),
-          b.get< tag::ymin >(), b.get< tag::ymax >(),
-          b.get< tag::zmin >(), b.get< tag::zmax >() };
-
-      std::string boxname = "IC box " + parameter(bcnt);
-      nfo.emplace_back( boxname, parameters( box ) );
-
-      nfo.emplace_back( boxname + " orientation",
-        parameters(b.get< tag::orientation >()) );
-
-      const auto& initiate = b.get< tag::initiate >();
-      auto opt = ctr::Initiate();
-      nfo.emplace_back( boxname + ' ' + opt.group(), opt.name(initiate) );
-
-      ++bcnt;
-    }
-  }
+  \brief     Scalar transport using continous Galerkin discretization
+  \details   This file implements the physics operators governing transported
+     scalars using continuous Galerkin discretization.
+*/
+// *****************************************************************************
+#ifndef CGTransport_h
+#define CGTransport_h
+
+#include <vector>
+#include <array>
+#include <limits>
+#include <cmath>
+#include <unordered_set>
+#include <unordered_map>
+
+#include "Exception.hpp"
+#include "Vector.hpp"
+#include "DerivedData.hpp"
+#include "Around.hpp"
+#include "Reconstruction.hpp"
+#include "Inciter/InputDeck/InputDeck.hpp"
+#include "CGPDE.hpp"
+#include "History.hpp"
+
+namespace inciter {
+
+extern ctr::InputDeck g_inputdeck;
+
+namespace cg {
+
+//! \brief Transport equation used polymorphically with tk::CGPDE
+//! \details The template argument(s) specify policies and are used to configure
+//!   the behavior of the class. The policies are:
+//!   - Physics - physics configuration, see PDE/Transport/Physics/CG.h
+//!   - Problem - problem configuration, see PDE/Transport/Problem.h
+//! \note The default physics is CGAdvection, set in
+//!    inciter::deck::check_transport()
+template< class Physics, class Problem >
+class Transport {
+
+  private:
+    using ncomp_t = tk::ncomp_t;
+    using real = tk::real;
+    using eq = tag::transport;
+
+    static constexpr real muscl_eps = 1.0e-9;
+    static constexpr real muscl_const = 1.0/3.0;
+    static constexpr real muscl_m1 = 1.0 - muscl_const;
+    static constexpr real muscl_p1 = 1.0 + muscl_const;
+
+  public:
+    //! Constructor
+    explicit Transport() :
+      m_physics( Physics() ),
+      m_problem( Problem() ),
+      m_ncomp(g_inputdeck.get< tag::ncomp >())
+    {
+      m_problem.errchk( m_ncomp );
+    }
+
+    //! Determine nodes that lie inside the user-defined IC box
+    void
+    IcBoxNodes( const tk::UnsMesh::Coords&,
+                const std::vector< std::size_t >&,
+                const std::unordered_map< std::size_t, std::set< std::size_t > >&,
+                std::vector< std::unordered_set< std::size_t > >&,
+                std::unordered_map< std::size_t, std::set< std::size_t > >&,
+                std::size_t& ) const {}
+
+    //! Initalize the transport equations using problem policy
+    //! \param[in] coord Mesh node coordinates
+    //! \param[in,out] unk Array of unknowns
+    //! \param[in] t Physical time
+    void
+    initialize( const std::array< std::vector< real >, 3 >& coord,
+                tk::Fields& unk,
+                real t,
+                real,
+                const std::vector< std::unordered_set< std::size_t > >&,
+                const std::vector< tk::real >&,
+                const std::unordered_map< std::size_t, std::set< std::size_t > >&
+              ) const
+    {
+      Assert( coord[0].size() == unk.nunk(), "Size mismatch" );
+      const auto& x = coord[0];
+      const auto& y = coord[1];
+      const auto& z = coord[2];
+      for (ncomp_t i=0; i<x.size(); ++i) {
+        auto s = Problem::initialize( m_ncomp, m_mat_blk, x[i], y[i],
+                                      z[i], t );
+        for (ncomp_t c=0; c<m_ncomp; ++c)
+          unk( i, c ) = s[c];
+      }
+    }
+
+    //! Query a velocity
+    //! \note Since this function does not touch its output argument, that
+    //!   means this system does not define a "velocity".
+    void velocity( const tk::Fields&, tk::UnsMesh::Coords& ) const {}
+
+    //! Query the sound speed
+    //! \note Since this function does not touch its output argument, that
+    //!   means this system does not define a "sound speed".
+    void soundspeed( const tk::Fields&, std::vector< tk::real >& ) const {}
+
+    //! Return analytic solution (if defined by Problem) at xi, yi, zi, t
+    //! \param[in] xi X-coordinate
+    //! \param[in] yi Y-coordinate
+    //! \param[in] zi Z-coordinate
+    //! \param[in] t Physical time
+    //! \return Vector of analytic solution at given location and time
+    std::vector< real >
+    analyticSolution( real xi, real yi, real zi, real t ) const
+    { return Problem::analyticSolution( m_ncomp, m_mat_blk, xi, yi, zi, t ); }
 
-  const auto& icblock = ic.get< tag::meshblock >();
-  for (const auto& b : icblock) {   // for all blocks configured for eq
-    std::string blockname = "IC mesh block " +
-      parameter(b.get< tag::blockid >());
-
-    const auto& initiate = b.get< tag::initiate >();
-    auto opt = ctr::Initiate();
-    nfo.emplace_back( blockname + ' ' + opt.group(), opt.name(initiate) );
-  }
+    //! Return analytic solution for conserved variables
+    //! \param[in] xi X-coordinate at which to evaluate the analytic solution
+    //! \param[in] yi Y-coordinate at which to evaluate the analytic solution
+    //! \param[in] zi Z-coordinate at which to evaluate the analytic solution
+    //! \param[in] t Physical time at which to evaluate the analytic solution
+    //! \return Vector of analytic solution at given location and time
+    std::vector< tk::real >
+    solution( tk::real xi, tk::real yi, tk::real zi, tk::real t ) const
+    { return Problem::initialize( m_ncomp, m_mat_blk, xi, yi, zi, t ); }
 
-  // BCs
-
-  const auto& bc = g_inputdeck.get< tag::bc >();
-  for (const auto& ib : bc) {
-    const auto& stag = ib.get< tag::stag_point >();
-    const auto& radius = ib.get< tag::radius >();
-    if (!stag.empty()) {
-      nfo.emplace_back( "Stagnation point(s)", parameters( stag ) );
-      nfo.emplace_back( "Stagnation point(s) radii", parameter( radius ) );
-    }
-
-    const auto& fs = ib.get< tag::farfield >();
-    if (!fs.empty())
-      nfo.emplace_back( "Farfield BC sideset(s)", parameters( fs ) );
-
-    const auto& sym = ib.get< tag::symmetry >();
-    if (!sym.empty())
-      nfo.emplace_back( "Symmetry BC sideset(s)", parameters( sym ) );
-
-    const auto& dir = ib.get< tag::dirichlet >();
-    if (!dir.empty())
-      nfo.emplace_back( "Dirichlet BC sideset(s)", parameters( dir ) );
+    //! Compute nodal gradients of primitive variables for ALECG
+    //! \param[in] coord Mesh node coordinates
+    //! \param[in] inpoel Mesh element connectivity
+    //! \param[in] bndel List of elements contributing to chare-boundary nodes
+    //! \param[in] gid Local->global node id map
+    //! \param[in] bid Local chare-boundary node ids (value) associated to
+    //!    global node ids (key)
+    //! \param[in] U Solution vector at recent time step
+    //! \param[in,out] G Nodal gradients of primitive variables
+    void chBndGrad( const std::array< std::vector< real >, 3 >& coord,
+      const std::vector< std::size_t >& inpoel,
+      const std::vector< std::size_t >& bndel,
+      const std::vector< std::size_t >& gid,
+      const std::unordered_map< std::size_t, std::size_t >& bid,
+      const tk::Fields& U,
+      tk::Fields& G ) const
+    {
+      Assert( U.nunk() == coord[0].size(), "Number of unknowns in solution "
+              "vector at recent time step incorrect" );
+
+      // compute gradients of primitive variables in points
+      G.fill( 0.0 );
 
-    const auto& timedep = ib.get< tag::timedep >();
-    if (!timedep.empty()) {
-      for (const auto& bndry : timedep) {
-        nfo.emplace_back( "Time dependent BC sideset(s)",<--- Consider using std::transform algorithm instead of a raw loop.
-          parameters(bndry.get< tag::sideset >()) );
-      }
-    }
-  }
-
-  return nfo;
-}
-
-}  // inciter::
+      // access node cooordinates
+      const auto& x = coord[0];
+      const auto& y = coord[1];
+      const auto& z = coord[2];
+
+      for (auto e : bndel) {  // elements contributing to chare boundary nodes
+        // access node IDs
+        std::size_t N[4] =
+          { inpoel[e*4+0], inpoel[e*4+1], inpoel[e*4+2], inpoel[e*4+3] };
+        // compute element Jacobi determinant, J = 6V
+        real bax = x[N[1]]-x[N[0]];
+        real bay = y[N[1]]-y[N[0]];
+        real baz = z[N[1]]-z[N[0]];
+        real cax = x[N[2]]-x[N[0]];
+        real cay = y[N[2]]-y[N[0]];
+        real caz = z[N[2]]-z[N[0]];
+        real dax = x[N[3]]-x[N[0]];
+        real day = y[N[3]]-y[N[0]];
+        real daz = z[N[3]]-z[N[0]];
+        auto J = tk::triple( bax, bay, baz, cax, cay, caz, dax, day, daz );
+        auto J24 = J/24.0;
+        // shape function derivatives, nnode*ndim [4][3]
+        real g[4][3];
+        tk::crossdiv( cax, cay, caz, dax, day, daz, J,
+                      g[1][0], g[1][1], g[1][2] );
+        tk::crossdiv( dax, day, daz, bax, bay, baz, J,
+                      g[2][0], g[2][1], g[2][2] );
+        tk::crossdiv( bax, bay, baz, cax, cay, caz, J,
+                      g[3][0], g[3][1], g[3][2] );
+        for (std::size_t i=0; i<3; ++i)
+          g[0][i] = -g[1][i] - g[2][i] - g[3][i];
+        // scatter-add gradient contributions to boundary nodes
+        for (std::size_t a=0; a<4; ++a) {
+          auto i = bid.find( gid[N[a]] );
+          if (i != end(bid))
+            for (std::size_t c=0; c<m_ncomp; ++c)
+              for (std::size_t b=0; b<4; ++b)
+                for (std::size_t j=0; j<3; ++j)
+                  G(i->second,c*3+j) += J24 * g[b][j] * U(N[b],c);
+        }
+      }
+    }
+
+    //! Compute right hand side for ALECG
+    //! \param[in] coord Mesh node coordinates
+    //! \param[in] inpoel Mesh element connectivity
+    //! \param[in] triinpoel Boundary triangle face connecitivity
+    //! \param[in] bid Local chare-boundary node ids (value) associated to
+    //!    global node ids (key)
+    //! \param[in] lid Global->local node ids
+    //! \param[in] dfn Dual-face normals
+    //! \param[in] psup Points surrounding points
+    //! \param[in] esup Elements surrounding points
+    //! \param[in] symbctri Vector with 1 at symmetry BC nodes
+    //! \param[in] vol Nodal volumes
+    //! \param[in] edgeid Local node id pair -> edge id map
+    //! \param[in] G Nodal gradients in chare-boundary nodes
+    //! \param[in] U Solution vector at recent time step
+    //! \param[in] W Mesh velocity
+    //! \param[in,out] R Right-hand side vector computed
+    void rhs(
+      real,
+      const std::array< std::vector< real >, 3 >&  coord,
+      const std::vector< std::size_t >& inpoel,
+      const std::vector< std::size_t >& triinpoel,
+      const std::vector< std::size_t >&,
+      const std::unordered_map< std::size_t, std::size_t >& bid,
+      const std::unordered_map< std::size_t, std::size_t >& lid,
+      const std::vector< real >& dfn,
+      const std::pair< std::vector< std::size_t >,
+                       std::vector< std::size_t > >& psup,
+      const std::pair< std::vector< std::size_t >,
+                       std::vector< std::size_t > >& esup,
+      const std::vector< int >& symbctri,
+      const std::vector< real >& vol,
+      const std::vector< std::size_t >&,
+      const std::vector< std::size_t >& edgeid,
+      const std::vector< std::unordered_set< std::size_t > >&,
+      const tk::Fields& G,
+      const tk::Fields& U,
+      [[maybe_unused]] const tk::Fields& W,
+      const std::vector< tk::real >&,
+      real,
+      tk::Fields& R ) const
+    {
+      Assert( G.nprop() == m_ncomp*3,
+              "Number of components in gradient vector incorrect" );
+      Assert( U.nunk() == coord[0].size(), "Number of unknowns in solution "
+              "vector at recent time step incorrect" );
+      Assert( R.nunk() == coord[0].size(),
+              "Number of unknowns and/or number of components in right-hand "
+              "side vector incorrect" );
+
+      // compute/assemble gradients in points
+      auto Grad = nodegrad( coord, inpoel, lid, bid, vol, esup, U, G );
+
+      // zero right hand side for all components
+      for (ncomp_t c=0; c<m_ncomp; ++c) R.fill( c, 0.0 );
+
+      // compute domain-edge integral
+      domainint( coord, inpoel, edgeid, psup, dfn, U, Grad, R );
+
+      // compute boundary integrals
+      bndint( coord, triinpoel, symbctri, U, R );
+    }
+
+    //! Compute overset mesh motion for OversetFE (no-op for transport)
+    void getMeshVel(
+      real,
+      const std::array< std::vector< real >, 3 >&,
+      const std::pair< std::vector< std::size_t >,
+                       std::vector< std::size_t > >&,
+      const std::unordered_set< std::size_t >&,
+      const std::array< tk::real, 3 >&,
+      const tk::Fields&,
+      tk::Fields&,
+      int& ) const
+    { }
+
+    //! Compute the minimum time step size (for unsteady time stepping)
+    //! \param[in] U Solution vector at recent time step
+    //! \param[in] coord Mesh node coordinates
+    //! \param[in] inpoel Mesh element connectivity
+    //! \param[in] t Physical time
+    //! \return Minimum time step size
+    real dt( const std::array< std::vector< real >, 3 >& coord,
+             const std::vector< std::size_t >& inpoel,
+             tk::real t,
+             tk::real,
+             const tk::Fields& U,
+             const std::vector< tk::real >&,
+             const std::vector< tk::real >& ) const
+    {
+      using tag::transport;
+      Assert( U.nunk() == coord[0].size(), "Number of unknowns in solution "
+              "vector at recent time step incorrect" );
+      const auto& x = coord[0];
+      const auto& y = coord[1];
+      const auto& z = coord[2];
+      // compute the minimum dt across all elements we own
+      auto mindt = std::numeric_limits< tk::real >::max();
+      auto eps = std::numeric_limits< tk::real >::epsilon();
+      auto large = std::numeric_limits< tk::real >::max();
+      for (std::size_t e=0; e<inpoel.size()/4; ++e) {
+        const std::array< std::size_t, 4 >
+          N{{ inpoel[e*4+0], inpoel[e*4+1], inpoel[e*4+2], inpoel[e*4+3] }};
+        // compute cubic root of element volume as the characteristic length
+        const std::array< real, 3 >
+          ba{{ x[N[1]]-x[N[0]], y[N[1]]-y[N[0]], z[N[1]]-z[N[0]] }},
+          ca{{ x[N[2]]-x[N[0]], y[N[2]]-y[N[0]], z[N[2]]-z[N[0]] }},
+          da{{ x[N[3]]-x[N[0]], y[N[3]]-y[N[0]], z[N[3]]-z[N[0]] }};
+        const auto L = std::cbrt( tk::triple( ba, ca, da ) / 6.0 );
+        // access solution at element nodes at recent time step
+        std::vector< std::array< real, 4 > > u( m_ncomp );
+        for (ncomp_t c=0; c<m_ncomp; ++c) u[c] = U.extract( c, N );
+        // get velocity for problem
+        const std::array< std::vector<std::array<real,3>>, 4 > vel{{
+          Problem::prescribedVelocity( m_ncomp,
+                                       x[N[0]], y[N[0]], z[N[0]], t ),
+          Problem::prescribedVelocity( m_ncomp,
+                                       x[N[1]], y[N[1]], z[N[1]], t ),
+          Problem::prescribedVelocity( m_ncomp,
+                                       x[N[2]], y[N[2]], z[N[2]], t ),
+          Problem::prescribedVelocity( m_ncomp,
+                                       x[N[3]], y[N[3]], z[N[3]], t ) }};
+        // compute the maximum length of the characteristic velocity (advection
+        // velocity) across the four element nodes
+        real maxvel = 0.0;
+        for (ncomp_t c=0; c<m_ncomp; ++c)
+          for (std::size_t i=0; i<4; ++i) {
+            auto v = tk::length( vel[i][c] );
+            if (v > maxvel) maxvel = v;
+          }
+        // compute element dt for the advection
+        auto advection_dt = std::abs(maxvel) > eps ? L / maxvel : large;
+        // compute element dt based on diffusion
+        auto diffusion_dt = m_physics.diffusion_dt( m_ncomp, L, u );
+        // compute minimum element dt
+        auto elemdt = std::min( advection_dt, diffusion_dt );
+        // find minimum dt across all elements
+        if (elemdt < mindt) mindt = elemdt;
+      }
+      return mindt * g_inputdeck.get< tag::cfl >();
+    }
+
+    //! Compute a time step size for each mesh node (for steady time stepping)
+    void dt( uint64_t,
+             const std::vector< tk::real >&,
+             const tk::Fields&,
+             std::vector< tk::real >& ) const {}
+
+    //! \brief Query Dirichlet boundary condition value on a given side set for
+    //!    all components in this PDE system
+    //! \param[in] t Physical time
+    //! \param[in] deltat Time step size
+    //! \param[in] tp Physical time for each mesh node
+    //! \param[in] dtp Time step size for each mesh node
+    //! \param[in] ss Pair of side set ID and list of node IDs on the side set
+    //! \param[in] coord Mesh node coordinates
+    //! \param[in] increment If true, evaluate the solution increment between
+    //!   t and t+dt for Dirichlet BCs. If false, evlauate the solution instead.
+    //! \return Vector of pairs of bool and boundary condition value associated
+    //!   to mesh node IDs at which Dirichlet boundary conditions are set. Note
+    //!   that if increment is true, instead of the actual boundary condition
+    //!   value, we return the increment between t+deltat and t, since,
+    //!   depending on client code and solver, that may be what the solution
+    //!   requires.
+    std::map< std::size_t, std::vector< std::pair<bool,real> > >
+    dirbc( real t,
+           real deltat,
+           const std::vector< tk::real >& tp,
+           const std::vector< tk::real >& dtp,
+           const std::pair< const int, std::vector< std::size_t > >& ss,
+           const std::array< std::vector< real >, 3 >& coord,
+           bool increment ) const
+    {
+      using NodeBC = std::vector< std::pair< bool, real > >;
+      std::map< std::size_t, NodeBC > bc;
+      const auto& ubc = g_inputdeck.get< tag::bc >()[0].get< tag::dirichlet >();
+      const auto steady = g_inputdeck.get< tag::steady_state >();<--- Variable 'steady' is assigned a value that is never used.
+      if (!ubc.empty()) {
+        Assert( ubc.size() > 0, "Indexing out of Dirichlet BC eq-vector" );
+        const auto& x = coord[0];
+        const auto& y = coord[1];
+        const auto& z = coord[2];
+        for (const auto& b : ubc)
+          if (static_cast<int>(b) == ss.first)
+            for (auto n : ss.second) {
+              Assert( x.size() > n, "Indexing out of coordinate array" );
+              if (steady) { t = tp[n]; deltat = dtp[n]; }
+              const auto s = increment ?
+                solinc( m_ncomp, m_mat_blk, x[n], y[n], z[n],
+                        t, deltat, Problem::initialize ) :
+                Problem::initialize( m_ncomp, m_mat_blk, x[n], y[n],
+                                     z[n], t+deltat );
+              auto& nbc = bc[n] = NodeBC( m_ncomp );
+              for (ncomp_t c=0; c<m_ncomp; ++c)
+                nbc[c] = { true, s[c] };
+            }
+      }
+      return bc;
+    }
+
+    //! Set symmetry boundary conditions at nodes
+    void
+    symbc(
+      tk::Fields&,
+      const std::array< std::vector< real >, 3 >&,
+      const std::unordered_map< int,
+              std::unordered_map< std::size_t,
+                std::array< real, 4 > > >&,
+      const std::unordered_set< std::size_t >& ) const {}
+
+    //! Set farfield boundary conditions at nodes
+    void farfieldbc(
+      tk::Fields&,
+      const std::array< std::vector< real >, 3 >&,
+      const std::unordered_map< int,
+              std::unordered_map< std::size_t,
+                std::array< real, 4 > > >&,
+      const std::unordered_set< std::size_t >& ) const {}
+
+    //! Apply user defined time dependent BCs (no-op for transport)
+    void
+    timedepbc( tk::real,
+      tk::Fields&,
+      const std::vector< std::unordered_set< std::size_t > >&,
+      const std::vector< tk::Table<5> >& ) const {}
+
+    //! Return a map that associates user-specified strings to functions
+    //! \return Map that associates user-specified strings to functions that
+    //!  compute relevant quantities to be output to file
+    std::map< std::string, tk::GetVarFn > OutVarFn() const {
+      std::map< std::string, tk::GetVarFn > OutFnMap;
+      OutFnMap["material_indicator"] = transport::matIndicatorOutVar;
+
+      return OutFnMap;
+    }
+
+    //! Return analytic field names to be output to file
+    //! \return Vector of strings labelling analytic fields output in file
+    std::vector< std::string > analyticFieldNames() const {
+      std::vector< std::string > n;
+      auto depvar = g_inputdeck.get< tag::depvar >()[0];
+      for (ncomp_t c=0; c<m_ncomp; ++c)
+        n.push_back( depvar + std::to_string(c) + "_analytic" );
+      return n;
+    }
+
+    //! Return surface field names to be output to file
+    //! \return Vector of strings labelling surface fields output in file
+    //! \details This functions should be written in conjunction with
+    //!   surfOutput(), which provides the vector of surface fields to be output
+    std::vector< std::string > surfNames() const { return {}; }
+
+    //! Return nodal surface field output going to file
+    std::vector< std::vector< real > >
+    surfOutput( const std::map< int, std::vector< std::size_t > >&,
+                const tk::Fields& ) const { return {}; }
+
+    //! Return elemental surface field output (on triangle faces) going to file
+    std::vector< std::vector< real > >
+    elemSurfOutput( const std::map< int, std::vector< std::size_t > >&,
+      const std::vector< std::size_t >&,
+      const tk::Fields& ) const { return {}; }
+
+    //! Return time history field names to be output to file
+    //! \return Vector of strings labelling time history fields output in file
+    std::vector< std::string > histNames() const { return {}; }
+
+    //! Return time history field output evaluated at time history points
+    std::vector< std::vector< real > >
+    histOutput( const std::vector< HistData >&,
+                const std::vector< std::size_t >&,
+                const tk::Fields& ) const { return {}; }
+
+    //! Return names of integral variables to be output to diagnostics file
+    //! \return Vector of strings labelling integral variables output
+    std::vector< std::string > names() const {
+      std::vector< std::string > n;
+      const auto& depvar =
+        g_inputdeck.get< tag::depvar >().at(0);
+      // construct the name of the numerical solution for all components
+      for (ncomp_t c=0; c<m_ncomp; ++c)
+        n.push_back( depvar + std::to_string(c) );
+      return n;
+    }
+
+  private:
+    const Physics m_physics;            //!< Physics policy
+    const Problem m_problem;            //!< Problem policy
+    const ncomp_t m_ncomp;              //!< Number of components in this PDE
+    //! EOS material block
+    const std::vector< EOS > m_mat_blk;
+
+    //! \brief Compute/assemble nodal gradients of primitive variables for
+    //!   ALECG in all points
+    //! \param[in] coord Mesh node coordinates
+    //! \param[in] inpoel Mesh element connectivity
+    //! \param[in] lid Global->local node ids
+    //! \param[in] bid Local chare-boundary node ids (value) associated to
+    //!    global node ids (key)
+    //! \param[in] vol Nodal volumes
+    //! \param[in] esup Elements surrounding points
+    //! \param[in] U Solution vector at recent time step
+    //! \param[in] G Nodal gradients of primitive variables in chare-boundary nodes
+    //! \return Gradients of primitive variables in all mesh points
+    tk::Fields
+    nodegrad( const std::array< std::vector< real >, 3 >& coord,
+              const std::vector< std::size_t >& inpoel,
+              const std::unordered_map< std::size_t, std::size_t >& lid,
+              const std::unordered_map< std::size_t, std::size_t >& bid,
+              const std::vector< real >& vol,
+              const std::pair< std::vector< std::size_t >,
+                               std::vector< std::size_t > >& esup,
+              const tk::Fields& U,
+              const tk::Fields& G ) const
+    {
+      // allocate storage for nodal gradients of primitive variables
+      tk::Fields Grad( U.nunk(), m_ncomp*3 );
+      Grad.fill( 0.0 );
+
+      // access node cooordinates
+      const auto& x = coord[0];
+      const auto& y = coord[1];
+      const auto& z = coord[2];
+
+      // compute gradients of primitive variables in points
+      auto npoin = U.nunk();
+      #pragma omp simd
+      for (std::size_t p=0; p<npoin; ++p)
+        for (auto e : tk::Around(esup,p)) {
+          // access node IDs
+          std::size_t N[4] =
+            { inpoel[e*4+0], inpoel[e*4+1], inpoel[e*4+2], inpoel[e*4+3] };
+          // compute element Jacobi determinant, J = 6V
+          real bax = x[N[1]]-x[N[0]];
+          real bay = y[N[1]]-y[N[0]];
+          real baz = z[N[1]]-z[N[0]];
+          real cax = x[N[2]]-x[N[0]];
+          real cay = y[N[2]]-y[N[0]];
+          real caz = z[N[2]]-z[N[0]];
+          real dax = x[N[3]]-x[N[0]];
+          real day = y[N[3]]-y[N[0]];
+          real daz = z[N[3]]-z[N[0]];
+          auto J = tk::triple( bax, bay, baz, cax, cay, caz, dax, day, daz );
+          auto J24 = J/24.0;
+          // shape function derivatives, nnode*ndim [4][3]
+          real g[4][3];
+          tk::crossdiv( cax, cay, caz, dax, day, daz, J,
+                        g[1][0], g[1][1], g[1][2] );
+          tk::crossdiv( dax, day, daz, bax, bay, baz, J,
+                        g[2][0], g[2][1], g[2][2] );
+          tk::crossdiv( bax, bay, baz, cax, cay, caz, J,
+                        g[3][0], g[3][1], g[3][2] );
+          for (std::size_t i=0; i<3; ++i)
+            g[0][i] = -g[1][i] - g[2][i] - g[3][i];
+          // scatter-add gradient contributions to boundary nodes
+          for (std::size_t c=0; c<m_ncomp; ++c)
+            for (std::size_t b=0; b<4; ++b)
+              for (std::size_t i=0; i<3; ++i)
+                Grad(p,c*3+i) += J24 * g[b][i] * U(N[b],c);
+        }
+
+      // put in nodal gradients of chare-boundary points
+      for (const auto& [g,b] : bid) {
+        auto i = tk::cref_find( lid, g );
+        for (ncomp_t c=0; c<Grad.nprop(); ++c)
+          Grad(i,c) = G(b,c);
+      }
+
+      // divide weak result in gradients by nodal volume
+      for (std::size_t p=0; p<npoin; ++p)
+        for (std::size_t c=0; c<m_ncomp*3; ++c)
+          Grad(p,c) /= vol[p];
+
+      return Grad;
+    }
+
+    //! \brief Compute MUSCL reconstruction in edge-end points using a MUSCL
+    //!    procedure with van Leer limiting
+    //! \param[in] p Left node id of edge-end
+    //! \param[in] q Right node id of edge-end
+    //! \param[in] coord Array of nodal coordinates
+    //! \param[in] G Gradient of all unknowns in mesh points
+    //! \param[in,out] uL Primitive variables at left edge-end point
+    //! \param[in,out] uR Primitive variables at right edge-end point
+    void
+    muscl( std::size_t p,
+           std::size_t q,
+           const tk::UnsMesh::Coords& coord,
+           const tk::Fields& G,
+           std::vector< real >& uL,
+           std::vector< real >& uR ) const
+    {
+      Assert( uL.size() == m_ncomp && uR.size() == m_ncomp, "Size mismatch" );
+      Assert( G.nprop()/3 == m_ncomp, "Size mismatch" );
+
+      const auto& x = coord[0];
+      const auto& y = coord[1];
+      const auto& z = coord[2];
+
+      // edge vector
+      std::array< real, 3 > vw{ x[q]-x[p], y[q]-y[p], z[q]-z[p] };
+
+      std::vector< real >
+        delta1( m_ncomp, 0.0 ), delta2( m_ncomp, 0.0 ), delta3( m_ncomp, 0.0 );
+
+      // MUSCL reconstruction of edge-end-point primitive variables
+      for (std::size_t c=0; c<m_ncomp; ++c) {
+        // gradients
+        std::array< real, 3 >
+          g1{ G(p,c*3+0), G(p,c*3+1), G(p,c*3+2) },
+          g2{ G(q,c*3+0), G(q,c*3+1), G(q,c*3+2) };
+
+        delta2[c] = uR[c] - uL[c];
+        delta1[c] = 2.0 * tk::dot(g1,vw) - delta2[c];
+        delta3[c] = 2.0 * tk::dot(g2,vw) - delta2[c];
+
+        // form limiters
+        auto rL = (delta2[c] + muscl_eps) / (delta1[c] + muscl_eps);
+        auto rR = (delta2[c] + muscl_eps) / (delta3[c] + muscl_eps);
+        auto rLinv = (delta1[c] + muscl_eps) / (delta2[c] + muscl_eps);
+        auto rRinv = (delta3[c] + muscl_eps) / (delta2[c] + muscl_eps);
+
+        auto phiL = (std::abs(rL) + rL) / (std::abs(rL) + 1.0);
+        auto phiR = (std::abs(rR) + rR) / (std::abs(rR) + 1.0);
+        auto phi_L_inv = (std::abs(rLinv) + rLinv) / (std::abs(rLinv) + 1.0);
+        auto phi_R_inv = (std::abs(rRinv) + rRinv) / (std::abs(rRinv) + 1.0);
+
+        // update unknowns with reconstructed unknowns
+        uL[c] += 0.25*(delta1[c]*muscl_m1*phiL + delta2[c]*muscl_p1*phi_L_inv);
+        uR[c] -= 0.25*(delta3[c]*muscl_m1*phiR + delta2[c]*muscl_p1*phi_R_inv);
+      }
+    }
+
+    //! Compute domain-edge integral for ALECG
+    //! \param[in] coord Mesh node coordinates
+    //! \param[in] inpoel Mesh element connectivity
+    //! \param[in] edgeid Local node id pair -> edge id map
+    //! \param[in] psup Points surrounding points
+    //! \param[in] dfn Dual-face normals
+    //! \param[in] U Solution vector at recent time step
+    //! \param[in] G Nodal gradients
+    //! \param[in,out] R Right-hand side vector computed
+    void domainint( const std::array< std::vector< real >, 3 >& coord,
+                    const std::vector< std::size_t >& inpoel,
+                    const std::vector< std::size_t >& edgeid,
+                    const std::pair< std::vector< std::size_t >,
+                                     std::vector< std::size_t > >& psup,
+                    const std::vector< real >& dfn,
+                    const tk::Fields& U,
+                    const tk::Fields& G,
+                    tk::Fields& R ) const
+    {
+      // access node cooordinates
+      const auto& x = coord[0];
+      const auto& y = coord[1];
+      const auto& z = coord[2];
+
+      // compute derived data structures
+      auto esued = tk::genEsued( inpoel, 4, tk::genEsup( inpoel, 4 ) );
+
+      // access pointer to right hand side at component
+      std::vector< const real* > r( m_ncomp );
+      for (ncomp_t c=0; c<m_ncomp; ++c) r[c] = R.cptr( c );
+
+      // domain-edge integral
+      for (std::size_t p=0,k=0; p<U.nunk(); ++p) {
+        for (auto q : tk::Around(psup,p)) {
+          // access dual-face normals for edge p-q
+          auto ed = edgeid[k++];
+          std::array< tk::real, 3 > n{ dfn[ed*6+0], dfn[ed*6+1], dfn[ed*6+2] };
+
+          std::vector< tk::real > uL( m_ncomp, 0.0 );
+          std::vector< tk::real > uR( m_ncomp, 0.0 );
+          for (std::size_t c=0; c<m_ncomp; ++c) {
+            uL[c] = U(p,c);
+            uR[c] = U(q,c);
+          }
+          // compute MUSCL reconstruction in edge-end points
+          muscl( p, q, coord, G, uL, uR );
+
+          // evaluate prescribed velocity
+          auto v =
+            Problem::prescribedVelocity( m_ncomp, x[p], y[p], z[p], 0.0 );
+          // sum donain-edge contributions
+          for (auto e : tk::cref_find(esued,{p,q})) {
+            const std::array< std::size_t, 4 >
+              N{{ inpoel[e*4+0], inpoel[e*4+1], inpoel[e*4+2], inpoel[e*4+3] }};
+            // compute element Jacobi determinant
+            const std::array< tk::real, 3 >
+              ba{{ x[N[1]]-x[N[0]], y[N[1]]-y[N[0]], z[N[1]]-z[N[0]] }},
+              ca{{ x[N[2]]-x[N[0]], y[N[2]]-y[N[0]], z[N[2]]-z[N[0]] }},
+              da{{ x[N[3]]-x[N[0]], y[N[3]]-y[N[0]], z[N[3]]-z[N[0]] }};
+            const auto J = tk::triple( ba, ca, da );        // J = 6V
+            // shape function derivatives, nnode*ndim [4][3]
+            std::array< std::array< tk::real, 3 >, 4 > grad;
+            grad[1] = tk::crossdiv( ca, da, J );
+            grad[2] = tk::crossdiv( da, ba, J );
+            grad[3] = tk::crossdiv( ba, ca, J );
+            for (std::size_t i=0; i<3; ++i)
+              grad[0][i] = -grad[1][i]-grad[2][i]-grad[3][i];
+            auto J48 = J/48.0;
+            for (const auto& [a,b] : tk::lpoed) {
+              auto s = tk::orient( {N[a],N[b]}, {p,q} );
+              for (std::size_t j=0; j<3; ++j) {
+                for (std::size_t c=0; c<m_ncomp; ++c) {
+                  R.var(r[c],p) -= J48 * s * (grad[a][j] - grad[b][j])
+                                   * v[c][j]*(uL[c] + uR[c])
+                    - J48 * std::abs(s * (grad[a][j] - grad[b][j]))
+                          * std::abs(tk::dot(v[c],n)) * (uR[c] - uL[c]);
+                }
+              }
+            }
+          }
+        }
+      }
+    }
+
+    //! Compute boundary integrals for ALECG
+    //! \param[in] coord Mesh node coordinates
+    //! \param[in] triinpoel Boundary triangle face connecitivity with local ids
+    //! \param[in] symbctri Vector with 1 at symmetry BC boundary triangles
+    //! \param[in] U Solution vector at recent time step
+    //! \param[in,out] R Right-hand side vector computed
+    void bndint( const std::array< std::vector< real >, 3 >& coord,
+                 const std::vector< std::size_t >& triinpoel,
+                 const std::vector< int >& symbctri,
+                 const tk::Fields& U,
+                 tk::Fields& R ) const
+    {
+      // access node coordinates
+      const auto& x = coord[0];
+      const auto& y = coord[1];
+      const auto& z = coord[2];
+
+      // boundary integrals: compute fluxes in edges
+      std::vector< real > bflux( triinpoel.size() * m_ncomp * 2 );
+
+      for (std::size_t e=0; e<triinpoel.size()/3; ++e) {
+        // access node IDs
+        std::array< std::size_t, 3 >
+          N{ triinpoel[e*3+0], triinpoel[e*3+1], triinpoel[e*3+2] };
+        // apply symmetry BCs
+        if (symbctri[e]) continue;
+        // node coordinates
+        std::array< tk::real, 3 > xp{ x[N[0]], x[N[1]], x[N[2]] },
+                                  yp{ y[N[0]], y[N[1]], y[N[2]] },
+                                  zp{ z[N[0]], z[N[1]], z[N[2]] };
+        // access solution at element nodes
+        std::vector< std::array< real, 3 > > u( m_ncomp );
+        for (ncomp_t c=0; c<m_ncomp; ++c) u[c] = U.extract( c, N );
+        // evaluate prescribed velocity
+        auto v =
+          Problem::prescribedVelocity( m_ncomp, xp[0], yp[0], zp[0], 0.0 );
+        // compute face area
+        auto A6 = tk::area( x[N[0]], x[N[1]], x[N[2]],
+                            y[N[0]], y[N[1]], y[N[2]],
+                            z[N[0]], z[N[1]], z[N[2]] ) / 6.0;
+        auto A24 = A6/4.0;
+        // compute face normal
+        auto n = tk::normal( xp, yp, zp );
+        // store flux in boundary elements
+        for (std::size_t c=0; c<m_ncomp; ++c) {
+          auto eb = (e*m_ncomp+c)*6;
+          auto vdotn = tk::dot( v[c], n );
+          auto Bab = A24 * vdotn * (u[c][0] + u[c][1]);
+          bflux[eb+0] = Bab + A6 * vdotn * u[c][0];
+          bflux[eb+1] = Bab;
+          Bab = A24 * vdotn * (u[c][1] + u[c][2]);
+          bflux[eb+2] = Bab + A6 * vdotn * u[c][1];
+          bflux[eb+3] = Bab;
+          Bab = A24 * vdotn * (u[c][2] + u[c][0]);
+          bflux[eb+4] = Bab + A6 * vdotn * u[c][2];
+          bflux[eb+5] = Bab;
+        }
+      }
+
+      // access pointer to right hand side at component
+      std::vector< const real* > r( m_ncomp );
+      for (ncomp_t c=0; c<m_ncomp; ++c) r[c] = R.cptr( c );
+
+      // boundary integrals: sum flux contributions to points
+      for (std::size_t e=0; e<triinpoel.size()/3; ++e) {
+        std::size_t N[3] =
+          { triinpoel[e*3+0], triinpoel[e*3+1], triinpoel[e*3+2] };
+        for (std::size_t c=0; c<m_ncomp; ++c) {
+          auto eb = (e*m_ncomp+c)*6;
+          R.var(r[c],N[0]) -= bflux[eb+0] + bflux[eb+5];
+          R.var(r[c],N[1]) -= bflux[eb+1] + bflux[eb+2];
+          R.var(r[c],N[2]) -= bflux[eb+3] + bflux[eb+4];
+        }
+      }
+
+      tk::destroy(bflux);
+    }
+};
+
+} // cg::
+} // inciter::
+
+#endif // Transport_h
 
diff --git a/Debug/cppcheck/59.html b/Debug/cppcheck/59.html index f8851d3b970f..17eec815366e 100644 --- a/Debug/cppcheck/59.html +++ b/Debug/cppcheck/59.html @@ -152,4685 +152,1437 @@
- - - - - - - - - - - + + + + + + + + + + - + - + - + - + - + - + @@ -394,38 +394,38 @@ - + - + - + - + - + - + - + - + diff --git a/Debug/test_coverage/Base/index-sort-f.html b/Debug/test_coverage/Base/index-sort-f.html index c227bcada511..84853a08ed61 100644 --- a/Debug/test_coverage/Base/index-sort-f.html +++ b/Debug/test_coverage/Base/index-sort-f.html @@ -27,16 +27,16 @@ - + - + - + - + @@ -49,9 +49,9 @@ - + - +
   1
-   2
-   3
-   4
-   5
-   6
-   7
-   8
-   9
-  10
-  11
-  12
-  13
-  14
-  15
-  16
-  17
-  18
-  19
-  20
-  21
-  22
-  23
-  24
-  25
-  26
-  27
-  28
-  29
-  30
-  31
-  32
-  33
-  34
-  35
-  36
-  37
-  38
-  39
-  40
-  41
-  42
-  43
-  44
-  45
-  46
-  47
-  48
-  49
-  50
-  51
-  52
-  53
-  54
-  55
-  56
-  57
-  58
-  59
-  60
-  61
-  62
-  63
-  64
-  65
-  66
-  67
-  68
-  69
-  70
-  71
-  72
-  73
-  74
-  75
-  76
-  77
-  78
-  79
-  80
-  81
-  82
-  83
-  84
-  85
-  86
-  87
-  88
-  89
-  90
-  91
-  92
-  93
-  94
-  95
-  96
-  97
-  98
-  99
- 100
- 101
- 102
- 103
- 104
- 105
- 106
- 107
- 108
- 109
- 110
- 111
- 112
- 113
- 114
- 115
- 116
- 117
- 118
- 119
- 120
- 121
- 122
- 123
- 124
- 125
- 126
- 127
- 128
- 129
- 130
- 131
- 132
- 133
- 134
- 135
- 136
- 137
- 138
- 139
- 140
- 141
- 142
- 143
- 144
- 145
- 146
- 147
- 148
- 149
- 150
- 151
- 152
- 153
- 154
- 155
- 156
- 157
- 158
- 159
- 160
- 161
- 162
- 163
- 164
- 165
- 166
- 167
- 168
- 169
- 170
- 171
- 172
- 173
- 174
- 175
- 176
- 177
- 178
- 179
- 180
- 181
- 182
- 183
- 184
- 185
- 186
- 187
- 188
- 189
- 190
- 191
- 192
- 193
- 194
- 195
- 196
- 197
- 198
- 199
- 200
- 201
- 202
- 203
- 204
- 205
- 206
- 207
- 208
- 209
- 210
- 211
- 212
- 213
- 214
- 215
- 216
- 217
- 218
- 219
- 220
- 221
- 222
- 223
- 224
- 225
- 226
- 227
- 228
- 229
- 230
- 231
- 232
- 233
- 234
- 235
- 236
- 237
- 238
- 239
- 240
- 241
- 242
- 243
- 244
- 245
- 246
- 247
- 248
- 249
- 250
- 251
- 252
- 253
- 254
- 255
- 256
- 257
- 258
- 259
- 260
- 261
- 262
- 263
- 264
- 265
- 266
- 267
- 268
- 269
- 270
- 271
- 272
- 273
- 274
- 275
- 276
- 277
- 278
- 279
- 280
- 281
- 282
- 283
- 284
- 285
- 286
- 287
- 288
- 289
- 290
- 291
- 292
- 293
- 294
- 295
- 296
- 297
- 298
- 299
- 300
- 301
- 302
- 303
- 304
- 305
- 306
- 307
- 308
- 309
- 310
- 311
- 312
- 313
- 314
- 315
- 316
- 317
- 318
- 319
- 320
- 321
- 322
- 323
- 324
- 325
- 326
- 327
- 328
- 329
- 330
- 331
- 332
- 333
- 334
- 335
- 336
- 337
- 338
- 339
- 340
- 341
- 342
- 343
- 344
- 345
- 346
- 347
- 348
- 349
- 350
- 351
- 352
- 353
- 354
- 355
- 356
- 357
- 358
- 359
- 360
- 361
- 362
- 363
- 364
- 365
- 366
- 367
- 368
- 369
- 370
- 371
- 372
- 373
- 374
- 375
- 376
- 377
- 378
- 379
- 380
- 381
- 382
- 383
- 384
- 385
- 386
- 387
- 388
- 389
- 390
- 391
- 392
- 393
- 394
- 395
- 396
- 397
- 398
- 399
- 400
- 401
- 402
- 403
- 404
- 405
- 406
- 407
- 408
- 409
- 410
- 411
- 412
- 413
- 414
- 415
- 416
- 417
- 418
- 419
- 420
- 421
- 422
- 423
- 424
- 425
- 426
- 427
- 428
- 429
- 430
- 431
- 432
- 433
- 434
- 435
- 436
- 437
- 438
- 439
- 440
- 441
- 442
- 443
- 444
- 445
- 446
- 447
- 448
- 449
- 450
- 451
- 452
- 453
- 454
- 455
- 456
- 457
- 458
- 459
- 460
- 461
- 462
- 463
- 464
- 465
- 466
- 467
- 468
- 469
- 470
- 471
- 472
- 473
- 474
- 475
- 476
- 477
- 478
- 479
- 480
- 481
- 482
- 483
- 484
- 485
- 486
- 487
- 488
- 489
- 490
- 491
- 492
- 493
- 494
- 495
- 496
- 497
- 498
- 499
- 500
- 501
- 502
- 503
- 504
- 505
- 506
- 507
- 508
- 509
- 510
- 511
- 512
- 513
- 514
- 515
- 516
- 517
- 518
- 519
- 520
- 521
- 522
- 523
- 524
- 525
- 526
- 527
- 528
- 529
- 530
- 531
- 532
- 533
- 534
- 535
- 536
- 537
- 538
- 539
- 540
- 541
- 542
- 543
- 544
- 545
- 546
- 547
- 548
- 549
- 550
- 551
- 552
- 553
- 554
- 555
- 556
- 557
- 558
- 559
- 560
- 561
- 562
- 563
- 564
- 565
- 566
- 567
- 568
- 569
- 570
- 571
- 572
- 573
- 574
- 575
- 576
- 577
- 578
- 579
- 580
- 581
- 582
- 583
- 584
- 585
- 586
- 587
- 588
- 589
- 590
- 591
- 592
- 593
- 594
- 595
- 596
- 597
- 598
- 599
- 600
- 601
- 602
- 603
- 604
- 605
- 606
- 607
- 608
- 609
- 610
- 611
- 612
- 613
- 614
- 615
- 616
- 617
- 618
- 619
- 620
- 621
- 622
- 623
- 624
- 625
- 626
- 627
- 628
- 629
- 630
- 631
- 632
- 633
- 634
- 635
- 636
- 637
- 638
- 639
- 640
- 641
- 642
- 643
- 644
- 645
- 646
- 647
- 648
- 649
- 650
- 651
- 652
- 653
- 654
- 655
- 656
- 657
- 658
- 659
- 660
- 661
- 662
- 663
- 664
- 665
- 666
- 667
- 668
- 669
- 670
- 671
- 672
- 673
- 674
- 675
- 676
- 677
- 678
- 679
- 680
- 681
- 682
- 683
- 684
- 685
- 686
- 687
- 688
- 689
- 690
- 691
- 692
- 693
- 694
- 695
- 696
- 697
- 698
- 699
- 700
- 701
- 702
- 703
- 704
- 705
- 706
- 707
- 708
- 709
- 710
- 711
- 712
- 713
- 714
- 715
- 716
- 717
- 718
- 719
- 720
- 721
- 722
- 723
- 724
- 725
- 726
- 727
- 728
- 729
- 730
- 731
- 732
- 733
- 734
- 735
- 736
- 737
- 738
- 739
- 740
- 741
- 742
- 743
- 744
- 745
- 746
- 747
- 748
- 749
- 750
- 751
- 752
- 753
- 754
- 755
- 756
- 757
- 758
- 759
- 760
- 761
- 762
- 763
- 764
- 765
- 766
- 767
- 768
- 769
- 770
- 771
- 772
- 773
- 774
- 775
- 776
- 777
- 778
- 779
- 780
- 781
- 782
- 783
- 784
- 785
- 786
- 787
- 788
- 789
- 790
- 791
- 792
- 793
- 794
- 795
- 796
- 797
- 798
- 799
- 800
- 801
- 802
- 803
- 804
- 805
- 806
- 807
- 808
- 809
- 810
- 811
- 812
- 813
- 814
- 815
- 816
- 817
- 818
- 819
- 820
- 821
- 822
- 823
- 824
- 825
- 826
- 827
- 828
- 829
- 830
- 831
- 832
- 833
- 834
- 835
- 836
- 837
- 838
- 839
- 840
- 841
- 842
- 843
- 844
- 845
- 846
- 847
- 848
- 849
- 850
- 851
- 852
- 853
- 854
- 855
- 856
- 857
- 858
- 859
- 860
- 861
- 862
- 863
- 864
- 865
- 866
- 867
- 868
- 869
- 870
- 871
- 872
- 873
- 874
- 875
- 876
- 877
- 878
- 879
- 880
- 881
- 882
- 883
- 884
- 885
- 886
- 887
- 888
- 889
- 890
- 891
- 892
- 893
- 894
- 895
- 896
- 897
- 898
- 899
- 900
- 901
- 902
- 903
- 904
- 905
- 906
- 907
- 908
- 909
- 910
- 911
- 912
- 913
- 914
- 915
- 916
- 917
- 918
- 919
- 920
- 921
- 922
- 923
- 924
- 925
- 926
- 927
- 928
- 929
- 930
- 931
- 932
- 933
- 934
- 935
- 936
- 937
- 938
- 939
- 940
- 941
- 942
- 943
- 944
- 945
- 946
- 947
- 948
- 949
- 950
- 951
- 952
- 953
- 954
- 955
- 956
- 957
- 958
- 959
- 960
- 961
- 962
- 963
- 964
- 965
- 966
- 967
- 968
- 969
- 970
- 971
- 972
- 973
- 974
- 975
- 976
- 977
- 978
- 979
- 980
- 981
- 982
- 983
- 984
- 985
- 986
- 987
- 988
- 989
- 990
- 991
- 992
- 993
- 994
- 995
- 996
- 997
- 998
- 999
-1000
-1001
-1002
-1003
-1004
-1005
-1006
-1007
-1008
-1009
-1010
-1011
-1012
-1013
-1014
-1015
-1016
-1017
-1018
-1019
-1020
-1021
-1022
-1023
-1024
-1025
-1026
-1027
-1028
-1029
-1030
-1031
-1032
-1033
-1034
-1035
-1036
-1037
-1038
-1039
-1040
-1041
-1042
-1043
-1044
-1045
-1046
-1047
-1048
-1049
-1050
-1051
-1052
-1053
-1054
-1055
-1056
-1057
-1058
-1059
-1060
-1061
-1062
-1063
-1064
-1065
-1066
-1067
-1068
-1069
-1070
-1071
-1072
-1073
-1074
-1075
-1076
-1077
-1078
-1079
-1080
-1081
-1082
-1083
-1084
-1085
-1086
-1087
-1088
-1089
-1090
-1091
-1092
-1093
-1094
-1095
-1096
-1097
-1098
-1099
-1100
-1101
-1102
-1103
-1104
-1105
-1106
-1107
-1108
-1109
-1110
-1111
-1112
-1113
-1114
-1115
-1116
-1117
-1118
-1119
-1120
-1121
-1122
-1123
-1124
-1125
-1126
-1127
-1128
-1129
-1130
-1131
-1132
-1133
-1134
-1135
-1136
-1137
-1138
-1139
-1140
-1141
-1142
-1143
-1144
-1145
-1146
-1147
-1148
-1149
-1150
-1151
-1152
-1153
-1154
-1155
-1156
-1157
-1158
-1159
-1160
-1161
-1162
-1163
-1164
-1165
-1166
-1167
-1168
-1169
-1170
-1171
-1172
-1173
-1174
-1175
-1176
-1177
-1178
-1179
-1180
-1181
-1182
-1183
-1184
-1185
-1186
-1187
-1188
-1189
-1190
-1191
-1192
-1193
-1194
-1195
-1196
-1197
-1198
-1199
-1200
-1201
-1202
-1203
-1204
-1205
-1206
-1207
-1208
-1209
-1210
-1211
-1212
-1213
-1214
-1215
-1216
-1217
-1218
-1219
-1220
-1221
-1222
-1223
-1224
-1225
-1226
-1227
-1228
-1229
-1230
-1231
-1232
-1233
-1234
-1235
-1236
-1237
-1238
-1239
-1240
-1241
-1242
-1243
-1244
-1245
-1246
-1247
-1248
-1249
-1250
-1251
-1252
-1253
-1254
-1255
-1256
-1257
-1258
-1259
-1260
-1261
-1262
-1263
-1264
-1265
-1266
-1267
-1268
-1269
-1270
-1271
-1272
-1273
-1274
-1275
-1276
-1277
-1278
-1279
-1280
-1281
-1282
-1283
-1284
-1285
-1286
-1287
-1288
-1289
-1290
-1291
-1292
-1293
-1294
-1295
-1296
-1297
-1298
-1299
-1300
-1301
-1302
-1303
-1304
-1305
-1306
-1307
-1308
-1309
-1310
-1311
-1312
-1313
-1314
-1315
-1316
-1317
-1318
-1319
-1320
-1321
-1322
-1323
-1324
-1325
-1326
-1327
-1328
-1329
-1330
-1331
-1332
-1333
-1334
-1335
-1336
-1337
-1338
-1339
-1340
-1341
-1342
-1343
-1344
-1345
-1346
-1347
-1348
-1349
-1350
-1351
-1352
-1353
-1354
-1355
-1356
-1357
-1358
-1359
-1360
-1361
-1362
-1363
-1364
-1365
-1366
-1367
-1368
-1369
-1370
-1371
-1372
-1373
-1374
-1375
-1376
-1377
-1378
-1379
-1380
-1381
-1382
-1383
-1384
-1385
-1386
-1387
-1388
-1389
-1390
-1391
-1392
-1393
-1394
-1395
-1396
-1397
-1398
-1399
-1400
-1401
-1402
-1403
-1404
-1405
-1406
-1407
-1408
-1409
-1410
-1411
-1412
-1413
-1414
-1415
-1416
-1417
-1418
-1419
-1420
-1421
-1422
-1423
-1424
-1425
-1426
-1427
-1428
-1429
-1430
-1431
-1432
-1433
-1434
-1435
-1436
-1437
-1438
-1439
-1440
-1441
-1442
-1443
-1444
-1445
-1446
-1447
-1448
-1449
-1450
-1451
-1452
-1453
-1454
-1455
-1456
-1457
-1458
-1459
-1460
-1461
-1462
-1463
-1464
-1465
-1466
-1467
-1468
-1469
-1470
-1471
-1472
-1473
-1474
-1475
-1476
-1477
-1478
-1479
-1480
-1481
-1482
-1483
-1484
-1485
-1486
-1487
-1488
-1489
-1490
-1491
-1492
-1493
-1494
-1495
-1496
-1497
-1498
-1499
-1500
-1501
-1502
-1503
-1504
-1505
-1506
-1507
-1508
-1509
-1510
-1511
-1512
-1513
-1514
-1515
-1516
-1517
-1518
-1519
-1520
-1521
-1522
-1523
-1524
-1525
-1526
-1527
-1528
-1529
-1530
-1531
-1532
-1533
-1534
-1535
-1536
-1537
-1538
-1539
-1540
-1541
-1542
-1543
-1544
-1545
-1546
-1547
-1548
-1549
-1550
-1551
-1552
-1553
-1554
-1555
-1556
-1557
-1558
-1559
-1560
-1561
-1562
-1563
-1564
-1565
-1566
-1567
-1568
-1569
-1570
-1571
-1572
-1573
-1574
-1575
-1576
-1577
-1578
-1579
-1580
-1581
-1582
-1583
-1584
-1585
-1586
-1587
-1588
-1589
-1590
-1591
-1592
-1593
-1594
-1595
-1596
-1597
-1598
-1599
-1600
-1601
-1602
-1603
-1604
-1605
-1606
-1607
-1608
-1609
-1610
-1611
-1612
-1613
-1614
-1615
-1616
-1617
-1618
-1619
-1620
-1621
-1622
-1623
-1624
-1625
-1626
-1627
-1628
-1629
-1630
-1631
-1632
-1633
-1634
-1635
-1636
-1637
-1638
-1639
-1640
-1641
-1642
-1643
-1644
-1645
-1646
-1647
-1648
-1649
-1650
-1651
-1652
-1653
-1654
-1655
-1656
-1657
-1658
-1659
-1660
-1661
-1662
-1663
-1664
-1665
-1666
-1667
-1668
-1669
-1670
-1671
-1672
-1673
-1674
-1675
-1676
-1677
-1678
-1679
-1680
-1681
-1682
-1683
-1684
-1685
-1686
-1687
-1688
-1689
-1690
-1691
-1692
-1693
-1694
-1695
-1696
-1697
-1698
-1699
-1700
-1701
-1702
-1703
-1704
-1705
-1706
-1707
-1708
-1709
-1710
-1711
-1712
-1713
-1714
-1715
-1716
-1717
-1718
-1719
-1720
-1721
-1722
-1723
-1724
-1725
-1726
-1727
-1728
-1729
-1730
-1731
-1732
-1733
-1734
-1735
-1736
-1737
-1738
-1739
-1740
-1741
-1742
-1743
-1744
-1745
-1746
-1747
-1748
-1749
-1750
-1751
-1752
-1753
-1754
-1755
-1756
-1757
-1758
-1759
-1760
-1761
-1762
-1763
-1764
-1765
-1766
-1767
-1768
-1769
-1770
-1771
-1772
-1773
-1774
-1775
-1776
-1777
-1778
-1779
-1780
-1781
-1782
-1783
-1784
-1785
-1786
-1787
-1788
-1789
-1790
-1791
-1792
-1793
-1794
-1795
-1796
-1797
-1798
-1799
-1800
-1801
-1802
-1803
-1804
-1805
-1806
-1807
-1808
-1809
-1810
-1811
-1812
-1813
-1814
-1815
-1816
-1817
-1818
-1819
-1820
-1821
-1822
-1823
-1824
-1825
-1826
-1827
-1828
-1829
-1830
-1831
-1832
-1833
-1834
-1835
-1836
-1837
-1838
-1839
-1840
-1841
-1842
-1843
-1844
-1845
-1846
-1847
-1848
-1849
-1850
-1851
-1852
-1853
-1854
-1855
-1856
-1857
-1858
-1859
-1860
-1861
-1862
-1863
-1864
-1865
-1866
-1867
-1868
-1869
-1870
-1871
-1872
-1873
-1874
-1875
-1876
-1877
-1878
-1879
-1880
-1881
-1882
-1883
-1884
-1885
-1886
-1887
-1888
-1889
-1890
-1891
-1892
-1893
-1894
-1895
-1896
-1897
-1898
-1899
-1900
-1901
-1902
-1903
-1904
-1905
-1906
-1907
-1908
-1909
-1910
-1911
-1912
-1913
-1914
-1915
-1916
-1917
-1918
-1919
-1920
-1921
-1922
-1923
-1924
-1925
-1926
-1927
-1928
-1929
-1930
-1931
-1932
-1933
-1934
-1935
-1936
-1937
-1938
-1939
-1940
-1941
-1942
-1943
-1944
-1945
-1946
-1947
-1948
-1949
-1950
-1951
-1952
-1953
-1954
-1955
-1956
-1957
-1958
-1959
-1960
-1961
-1962
-1963
-1964
-1965
-1966
-1967
-1968
-1969
-1970
-1971
-1972
-1973
-1974
-1975
-1976
-1977
-1978
-1979
-1980
-1981
-1982
-1983
-1984
-1985
-1986
-1987
-1988
-1989
-1990
-1991
-1992
-1993
-1994
-1995
-1996
-1997
-1998
-1999
-2000
-2001
-2002
-2003
-2004
-2005
-2006
-2007
-2008
-2009
-2010
-2011
-2012
-2013
-2014
-2015
-2016
-2017
-2018
-2019
-2020
-2021
-2022
-2023
-2024
-2025
-2026
-2027
-2028
-2029
-2030
-2031
-2032
-2033
-2034
-2035
-2036
-2037
-2038
-2039
-2040
-2041
-2042
-2043
-2044
-2045
-2046
-2047
-2048
-2049
-2050
-2051
-2052
-2053
-2054
-2055
-2056
-2057
-2058
-2059
-2060
-2061
-2062
-2063
-2064
-2065
-2066
-2067
-2068
-2069
-2070
-2071
-2072
-2073
-2074
-2075
-2076
-2077
-2078
-2079
-2080
-2081
-2082
-2083
-2084
-2085
-2086
-2087
-2088
-2089
-2090
-2091
-2092
-2093
-2094
-2095
-2096
-2097
-2098
-2099
-2100
-2101
-2102
-2103
-2104
-2105
-2106
-2107
-2108
-2109
-2110
-2111
-2112
-2113
-2114
-2115
-2116
-2117
-2118
-2119
-2120
-2121
-2122
-2123
-2124
-2125
-2126
-2127
-2128
-2129
-2130
-2131
-2132
-2133
-2134
-2135
-2136
-2137
-2138
-2139
-2140
-2141
-2142
-2143
-2144
-2145
-2146
-2147
-2148
-2149
-2150
-2151
-2152
-2153
-2154
-2155
-2156
-2157
-2158
-2159
-2160
-2161
-2162
-2163
-2164
-2165
-2166
-2167
-2168
-2169
-2170
-2171
-2172
-2173
-2174
-2175
-2176
-2177
-2178
-2179
-2180
-2181
-2182
-2183
-2184
-2185
-2186
-2187
-2188
-2189
-2190
-2191
-2192
-2193
-2194
-2195
-2196
-2197
-2198
-2199
-2200
-2201
-2202
-2203
-2204
-2205
-2206
-2207
-2208
-2209
-2210
-2211
-2212
-2213
-2214
-2215
-2216
-2217
-2218
-2219
-2220
-2221
-2222
-2223
-2224
-2225
-2226
-2227
-2228
-2229
-2230
-2231
-2232
-2233
-2234
-2235
-2236
-2237
-2238
-2239
-2240
-2241
-2242
-2243
-2244
-2245
-2246
-2247
-2248
-2249
-2250
-2251
-2252
-2253
-2254
-2255
-2256
-2257
-2258
-2259
-2260
-2261
-2262
-2263
-2264
-2265
-2266
-2267
-2268
-2269
-2270
-2271
-2272
-2273
-2274
-2275
-2276
-2277
-2278
-2279
-2280
-2281
-2282
-2283
-2284
-2285
-2286
-2287
-2288
-2289
-2290
-2291
-2292
-2293
-2294
-2295
-2296
-2297
-2298
-2299
-2300
-2301
-2302
-2303
-2304
-2305
-2306
-2307
-2308
-2309
-2310
-2311
-2312
-2313
-2314
-2315
-2316
-2317
-2318
-2319
-2320
-2321
-2322
-2323
-2324
-2325
-2326
-2327
-2328
-2329
-2330
-2331
-2332
-2333
-2334
-2335
-2336
// *****************************************************************************
+
  1
+  2
+  3
+  4
+  5
+  6
+  7
+  8
+  9
+ 10
+ 11
+ 12
+ 13
+ 14
+ 15
+ 16
+ 17
+ 18
+ 19
+ 20
+ 21
+ 22
+ 23
+ 24
+ 25
+ 26
+ 27
+ 28
+ 29
+ 30
+ 31
+ 32
+ 33
+ 34
+ 35
+ 36
+ 37
+ 38
+ 39
+ 40
+ 41
+ 42
+ 43
+ 44
+ 45
+ 46
+ 47
+ 48
+ 49
+ 50
+ 51
+ 52
+ 53
+ 54
+ 55
+ 56
+ 57
+ 58
+ 59
+ 60
+ 61
+ 62
+ 63
+ 64
+ 65
+ 66
+ 67
+ 68
+ 69
+ 70
+ 71
+ 72
+ 73
+ 74
+ 75
+ 76
+ 77
+ 78
+ 79
+ 80
+ 81
+ 82
+ 83
+ 84
+ 85
+ 86
+ 87
+ 88
+ 89
+ 90
+ 91
+ 92
+ 93
+ 94
+ 95
+ 96
+ 97
+ 98
+ 99
+100
+101
+102
+103
+104
+105
+106
+107
+108
+109
+110
+111
+112
+113
+114
+115
+116
+117
+118
+119
+120
+121
+122
+123
+124
+125
+126
+127
+128
+129
+130
+131
+132
+133
+134
+135
+136
+137
+138
+139
+140
+141
+142
+143
+144
+145
+146
+147
+148
+149
+150
+151
+152
+153
+154
+155
+156
+157
+158
+159
+160
+161
+162
+163
+164
+165
+166
+167
+168
+169
+170
+171
+172
+173
+174
+175
+176
+177
+178
+179
+180
+181
+182
+183
+184
+185
+186
+187
+188
+189
+190
+191
+192
+193
+194
+195
+196
+197
+198
+199
+200
+201
+202
+203
+204
+205
+206
+207
+208
+209
+210
+211
+212
+213
+214
+215
+216
+217
+218
+219
+220
+221
+222
+223
+224
+225
+226
+227
+228
+229
+230
+231
+232
+233
+234
+235
+236
+237
+238
+239
+240
+241
+242
+243
+244
+245
+246
+247
+248
+249
+250
+251
+252
+253
+254
+255
+256
+257
+258
+259
+260
+261
+262
+263
+264
+265
+266
+267
+268
+269
+270
+271
+272
+273
+274
+275
+276
+277
+278
+279
+280
+281
+282
+283
+284
+285
+286
+287
+288
+289
+290
+291
+292
+293
+294
+295
+296
+297
+298
+299
+300
+301
+302
+303
+304
+305
+306
+307
+308
+309
+310
+311
+312
+313
+314
+315
+316
+317
+318
+319
+320
+321
+322
+323
+324
+325
+326
+327
+328
+329
+330
+331
+332
+333
+334
+335
+336
+337
+338
+339
+340
+341
+342
+343
+344
+345
+346
+347
+348
+349
+350
+351
+352
+353
+354
+355
+356
+357
+358
+359
+360
+361
+362
+363
+364
+365
+366
+367
+368
+369
+370
+371
+372
+373
+374
+375
+376
+377
+378
+379
+380
+381
+382
+383
+384
+385
+386
+387
+388
+389
+390
+391
+392
+393
+394
+395
+396
+397
+398
+399
+400
+401
+402
+403
+404
+405
+406
+407
+408
+409
+410
+411
+412
+413
+414
+415
+416
+417
+418
+419
+420
+421
+422
+423
+424
+425
+426
+427
+428
+429
+430
+431
+432
+433
+434
+435
+436
+437
+438
+439
+440
+441
+442
+443
+444
+445
+446
+447
+448
+449
+450
+451
+452
+453
+454
+455
+456
+457
+458
+459
+460
+461
+462
+463
+464
+465
+466
+467
+468
+469
+470
+471
+472
+473
+474
+475
+476
+477
+478
+479
+480
+481
+482
+483
+484
+485
+486
+487
+488
+489
+490
+491
+492
+493
+494
+495
+496
+497
+498
+499
+500
+501
+502
+503
+504
+505
+506
+507
+508
+509
+510
+511
+512
+513
+514
+515
+516
+517
+518
+519
+520
+521
+522
+523
+524
+525
+526
+527
+528
+529
+530
+531
+532
+533
+534
+535
+536
+537
+538
+539
+540
+541
+542
+543
+544
+545
+546
+547
+548
+549
+550
+551
+552
+553
+554
+555
+556
+557
+558
+559
+560
+561
+562
+563
+564
+565
+566
+567
+568
+569
+570
+571
+572
+573
+574
+575
+576
+577
+578
+579
+580
+581
+582
+583
+584
+585
+586
+587
+588
+589
+590
+591
+592
+593
+594
+595
+596
+597
+598
+599
+600
+601
+602
+603
+604
+605
+606
+607
+608
+609
+610
+611
+612
+613
+614
+615
+616
+617
+618
+619
+620
+621
+622
+623
+624
+625
+626
+627
+628
+629
+630
+631
+632
+633
+634
+635
+636
+637
+638
+639
+640
+641
+642
+643
+644
+645
+646
+647
+648
+649
+650
+651
+652
+653
+654
+655
+656
+657
+658
+659
+660
+661
+662
+663
+664
+665
+666
+667
+668
+669
+670
+671
+672
+673
+674
+675
+676
+677
+678
+679
+680
+681
+682
+683
+684
+685
+686
+687
+688
+689
+690
+691
+692
+693
+694
+695
+696
+697
+698
+699
+700
+701
+702
+703
+704
+705
+706
+707
+708
+709
+710
+711
+712
// *****************************************************************************
 /*!
-  \file      src/Inciter/DG.cpp
+  \file      src/PDE/Transport/DGTransport.hpp
   \copyright 2012-2015 J. Bakosi,
              2016-2018 Los Alamos National Security, LLC.,
              2019-2021 Triad National Security, LLC.
              All rights reserved. See the LICENSE file for details.
-  \brief     DG advances a system of PDEs with the discontinuous Galerkin scheme
-  \details   DG advances a system of partial differential equations (PDEs) using
-    discontinuous Galerkin (DG) finite element (FE) spatial discretization (on
-    tetrahedron elements) combined with Runge-Kutta (RK) time stepping.
-  \see The documentation in DG.h.
-*/
-// *****************************************************************************
+  \brief     Scalar transport using disccontinous Galerkin discretization
+  \details   This file implements the physics operators governing transported
+     scalars using disccontinuous Galerkin discretization.
+*/
+// *****************************************************************************
+#ifndef DGTransport_h
+#define DGTransport_h
 
-#include <algorithm>
-#include <numeric>
-#include <sstream>
-
-#include "DG.hpp"
-#include "Discretization.hpp"
-#include "DGPDE.hpp"
-#include "DiagReducer.hpp"
-#include "DerivedData.hpp"
-#include "ElemDiagnostics.hpp"
-#include "Inciter/InputDeck/InputDeck.hpp"
-#include "Refiner.hpp"
-#include "Limiter.hpp"
-#include "Reorder.hpp"
-#include "Vector.hpp"
-#include "Around.hpp"
-#include "Integrate/Basis.hpp"
-#include "FieldOutput.hpp"
-#include "ChareStateCollector.hpp"
-#include "PDE/MultiMat/MultiMatIndexing.hpp"
-
-namespace inciter {
-
-extern ctr::InputDeck g_inputdeck;
-extern std::vector< DGPDE > g_dgpde;
+#include <vector>
+#include <array>
+#include <limits>
+#include <cmath>
+#include <unordered_set>
+#include <map>
+
+#include "Macro.hpp"
+#include "Exception.hpp"
+#include "Vector.hpp"
+#include "UnsMesh.hpp"
+#include "Integrate/Basis.hpp"
+#include "Integrate/Quadrature.hpp"
+#include "Integrate/Initialize.hpp"
+#include "Integrate/Mass.hpp"
+#include "Integrate/Surface.hpp"
+#include "Integrate/Boundary.hpp"
+#include "Integrate/Volume.hpp"
+#include "Riemann/Upwind.hpp"
+#include "Reconstruction.hpp"
+#include "Limiter.hpp"
+#include "PrefIndicator.hpp"
+#include "EoS/EOS.hpp"
+#include "FunctionPrototypes.hpp"
+#include "ConfigureTransport.hpp"
 
-//! Runge-Kutta coefficients
-static const std::array< std::array< tk::real, 3 >, 2 >
-  rkcoef{{ {{ 0.0, 3.0/4.0, 1.0/3.0 }}, {{ 1.0, 1.0/4.0, 2.0/3.0 }} }};
+namespace inciter {
+
+extern ctr::InputDeck g_inputdeck;
 
-//! Implicit-Explicit Runge-Kutta Coefficients
-static const tk::real rk_gamma = (2.0-std::sqrt(2.0))/2.0;
-static const tk::real rk_delta = -2.0*std::sqrt(2.0)/3.0;
-static const tk::real c2 =
-  (27.0 + std::pow(2187.0-1458.0*std::sqrt(2.0),1.0/3.0)
-   + 9.0*std::pow(3.0+2.0*std::sqrt(2.0),1.0/3.0))/54.0;
-static const tk::real c3 = c2/(6.0*std::pow(c2,2.0)-3.0*c2+1.0);
-static const tk::real b2 = (3.0*c2-1.0)/(6.0*std::pow(c2,2.0));
-static const tk::real b3 =
-  (6.0*std::pow(c2,2.0)-3.0*c2+1.0)/(6.0*std::pow(c2,2.0));
-static const tk::real a22_impl = c2;
-static const tk::real a21_expl = c2;
-static const tk::real a32_expl = c3;
-static const tk::real a33_impl =
-  (1.0/6.0-b2*std::pow(c2,2.0)-b3*c2*c3)/(b3*(c3-c2));
-static const tk::real a32_impl = a33_impl-c3;
-static const std::array< std::array< tk::real, 3 >, 2 >
-  expl_rkcoef{{ {{ 0.0, 0.0, b2 }},
-                {{ a21_expl, a32_expl, b3 }} }};
-static const std::array< std::array< tk::real, 3 >, 2>
-  impl_rkcoef{{ {{ 0.0, a32_impl, b2 }},
-                {{ a22_impl, a33_impl, b3}} }};
-
-} // inciter::
-
-extern tk::CProxy_ChareStateCollector stateProxy;
-
-using inciter::DG;
-
-DG::DG( const CProxy_Discretization& disc,
-        const CProxy_Ghosts& ghostsproxy,
-        const std::map< int, std::vector< std::size_t > >& bface,
-        const std::map< int, std::vector< std::size_t > >& /* bnode */,
-        const std::vector< std::size_t >& triinpoel ) :
-  m_disc( disc ),
-  m_ghosts( ghostsproxy ),
-  m_ndof_NodalExtrm( 3 ), // for the first order derivatives in 3 directions
-  m_nsol( 0 ),
-  m_ninitsol( 0 ),
-  m_nlim( 0 ),
-  m_nnod( 0 ),
-  m_nrefine( 0 ),
-  m_nsmooth( 0 ),
-  m_nreco( 0 ),
-  m_nnodalExtrema( 0 ),
-  m_nstiffeq( g_dgpde[Disc()->MeshId()].nstiffeq() ),
-  m_nnonstiffeq( g_dgpde[Disc()->MeshId()].nnonstiffeq() ),
-  m_u( Disc()->Inpoel().size()/4,
-       g_inputdeck.get< tag::rdof >()*
-       g_inputdeck.get< tag::ncomp >() ),
-  m_un( m_u.nunk(), m_u.nprop() ),
-  m_p( m_u.nunk(), g_inputdeck.get< tag::rdof >()*
-    g_dgpde[Disc()->MeshId()].nprim() ),
-  m_lhs( m_u.nunk(),
-         g_inputdeck.get< tag::ndof >()*
-         g_inputdeck.get< tag::ncomp >() ),
-  m_rhs( m_u.nunk(), m_lhs.nprop() ),
-  m_rhsprev( m_u.nunk(), m_lhs.nprop() ),
-  m_stiffrhs( m_u.nunk(), g_inputdeck.get< tag::ndof >()*
-              g_dgpde[Disc()->MeshId()].nstiffeq() ),
-  m_stiffrhsprev( m_u.nunk(), g_inputdeck.get< tag::ndof >()*
-                  g_dgpde[Disc()->MeshId()].nstiffeq() ),
-  m_stiffEqIdx( g_dgpde[Disc()->MeshId()].nstiffeq() ),
-  m_nonStiffEqIdx( g_dgpde[Disc()->MeshId()].nnonstiffeq() ),
-  m_mtInv(
-    tk::invMassMatTaylorRefEl(g_inputdeck.get< tag::rdof >()) ),
-  m_uNodalExtrm(),
-  m_pNodalExtrm(),
-  m_uNodalExtrmc(),
-  m_pNodalExtrmc(),
-  m_npoin( Disc()->Coord()[0].size() ),
-  m_diag(),
-  m_stage( 0 ),
-  m_ndof(),
-  m_numEqDof(),
-  m_uc(),
-  m_pc(),
-  m_ndofc(),
-  m_initial( 1 ),
-  m_uElemfields( m_u.nunk(),
-                 g_inputdeck.get< tag::ncomp >() ),
-  m_pElemfields( m_u.nunk(),
-                 m_p.nprop() / g_inputdeck.get< tag::rdof >() ),
-  m_uNodefields( m_npoin,
-                 g_inputdeck.get< tag::ncomp >() ),
-  m_pNodefields( m_npoin,
-                 m_p.nprop() / g_inputdeck.get< tag::rdof >() ),
-  m_uNodefieldsc(),
-  m_pNodefieldsc(),
-  m_outmesh(),
-  m_boxelems(),
-  m_shockmarker(m_u.nunk(), 1),
-  m_rho0mat()
-// *****************************************************************************
-//  Constructor
-//! \param[in] disc Discretization proxy
-//! \param[in] bface Boundary-faces mapped to side set ids
-//! \param[in] triinpoel Boundary-face connectivity
-// *****************************************************************************
-{
-  if (g_inputdeck.get< tag::cmd, tag::chare >() ||
-      g_inputdeck.get< tag::cmd, tag::quiescence >())
-    stateProxy.ckLocalBranch()->insert( "DG", thisIndex, CkMyPe(), Disc()->It(),
-                                        "DG" );
-
-  // assign number of dofs for each equation in all pde systems
-  g_dgpde[Disc()->MeshId()].numEquationDofs(m_numEqDof);
-
-  // Allocate storage for the vector of nodal extrema
-  m_uNodalExtrm.resize( Disc()->Bid().size(),
-    std::vector<tk::real>( 2 * m_ndof_NodalExtrm *
-    g_inputdeck.get< tag::ncomp >() ) );
-  m_pNodalExtrm.resize( Disc()->Bid().size(),
-    std::vector<tk::real>( 2 * m_ndof_NodalExtrm *
-    m_p.nprop() / g_inputdeck.get< tag::rdof >() ) );
-
-  // Initialization for the buffer vector of nodal extrema
-  resizeNodalExtremac();
-
-  usesAtSync = true;    // enable migration at AtSync
-
-  // Enable SDAG wait for initially building the solution vector and limiting
-  if (m_initial) {
-    thisProxy[ thisIndex ].wait4sol();
-    thisProxy[ thisIndex ].wait4refine();
-    thisProxy[ thisIndex ].wait4smooth();
-    thisProxy[ thisIndex ].wait4lim();
-    thisProxy[ thisIndex ].wait4nod();
-    thisProxy[ thisIndex ].wait4reco();
-    thisProxy[ thisIndex ].wait4nodalExtrema();
-  }
-
-  m_ghosts[thisIndex].insert(m_disc, bface, triinpoel, m_u.nunk(),
-    CkCallback(CkIndex_DG::resizeSolVectors(), thisProxy[thisIndex]));
+namespace dg {
+
+//! \brief Transport equation used polymorphically with tk::DGPDE
+//! \details The template argument(s) specify policies and are used to configure
+//!   the behavior of the class. The policies are:
+//!   - Physics - physics configuration, see PDE/Transport/Physics.h
+//!   - Problem - problem configuration, see PDE/Transport/Problem.h
+//! \note The default physics is DGAdvection, set in
+//!    inciter::deck::check_transport()
+template< class Physics, class Problem >
+class Transport {
+
+  private:
+    using eq = tag::transport;
+
+  public:
+    //! Constructor
+    explicit Transport() :
+      m_physics( Physics() ),
+      m_problem( Problem() ),
+      m_ncomp( g_inputdeck.get< tag::ncomp >() )
+    {
+      // associate boundary condition configurations with state functions, the
+      // order in which the state functions listed matters, see ctr::bc::Keys
+      brigand::for_each< ctr::bclist::Keys >( ConfigBC( m_bc,
+        { dirichlet
+        , invalidBC  // Symmetry BC not implemented
+        , inlet
+        , outlet
+        , invalidBC  // Characteristic BC not implemented
+        , extrapolate } ) );
+      m_problem.errchk( m_ncomp );
+    }
+
+    //! Find the number of primitive quantities required for this PDE system
+    //! \return The number of primitive quantities required to be stored for
+    //!   this PDE system
+    std::size_t nprim() const
+    {
+      // transport does not need/store any primitive quantities currently
+      return 0;
+    }
+
+    //! Find the number of materials set up for this PDE system
+    //! \return The number of materials set up for this PDE system
+    std::size_t nmat() const
+    {
+      return m_ncomp;
+    }
+
+    //! Assign number of DOFs per equation in the PDE system
+    //! \param[in,out] numEqDof Array storing number of Dofs for each PDE
+    //!   equation
+    void numEquationDofs(std::vector< std::size_t >& numEqDof) const
+    {
+      // all equation-dofs initialized to ndofs
+      for (std::size_t i=0; i<m_ncomp; ++i) {
+        numEqDof.push_back(g_inputdeck.get< tag::ndof >());
+      }
+    }
+
+    //! Find how 'stiff equations', which we currently
+    //! have none for Transport
+    //! \return number of stiff equations
+    std::size_t nstiffeq() const
+    { return 0; }
+
+    //! Find how 'nonstiff equations', which we currently
+    //! don't use for Transport
+    //! \return number of non-stiff equations
+    std::size_t nnonstiffeq() const
+    { return 0; }
+
+    //! Locate the stiff equations. Unused for transport.
+    //! \param[out] stiffEqIdx list
+    void setStiffEqIdx( std::vector< std::size_t >& stiffEqIdx ) const
+    {
+      stiffEqIdx.resize(0);
+    }
+
+    //! Locate the nonstiff equations. Unused for transport.
+    //! \param[out] nonStiffEqIdx list
+    void setNonStiffEqIdx( std::vector< std::size_t >& nonStiffEqIdx ) const
+    {
+      nonStiffEqIdx.resize(0);
+    }
+
+    //! Determine elements that lie inside the user-defined IC box
+    void IcBoxElems( const tk::Fields&,
+      std::size_t,
+      std::vector< std::unordered_set< std::size_t > >& ) const
+    {}
+
+    //! Initalize the transport equations for DG
+    //! \param[in] L Element mass matrix
+    //! \param[in] inpoel Element-node connectivity
+    //! \param[in] coord Array of nodal coordinates
+    //! \param[in,out] unk Array of unknowns
+    //! \param[in] t Physical time
+    //! \param[in] nielem Number of internal elements
+    void
+    initialize(
+      const tk::Fields& L,
+      const std::vector< std::size_t >& inpoel,
+      const tk::UnsMesh::Coords& coord,
+      const std::vector< std::unordered_set< std::size_t > >& /*inbox*/,
+      const std::unordered_map< std::size_t, std::set< std::size_t > >&,
+      tk::Fields& unk,
+      tk::real t,
+      const std::size_t nielem ) const
+    {
+      tk::initialize( m_ncomp, m_mat_blk, L, inpoel, coord,
+                      Problem::initialize, unk, t, nielem );
+    }
+
+    //! Save initial densities for all materials
+    //! \param[out] rho0mat List of initial densities
+    void setRho0mat( std::vector< tk::real >& rho0mat ) const
+    {
+      rho0mat.resize(0);
+    }
+
+    //! Compute density constraint for a given material
+    // //! \param[in] nelem Number of elements
+    // //! \param[in] unk Array of unknowns
+    // //! \param[in] rho0mat List of initial densities
+    //! \param[out] densityConstr Density Constraint: rho/(rho0*det(g))
+    void computeDensityConstr( std::size_t /*nelem*/,
+                               tk::Fields& /*unk*/,
+                               std::vector< tk::real >& /*rho0mat*/,
+                               std::vector< tk::real >& densityConstr) const
+    {
+      densityConstr.resize(0);
+    }
 
-  // global-sync to call doneInserting on m_ghosts
-  auto meshid = Disc()->MeshId();
-  contribute( sizeof(std::size_t), &meshid, CkReduction::nop,
-    CkCallback(CkReductionTarget(Transporter,doneInsertingGhosts),
-    Disc()->Tr()) );
-}
-
-void
-DG::registerReducers()
-// *****************************************************************************
-//  Configure Charm++ reduction types
-//! \details Since this is a [initnode] routine, the runtime system executes the
-//!   routine exactly once on every logical node early on in the Charm++ init
-//!   sequence. Must be static as it is called without an object. See also:
-//!   Section "Initializations at Program Startup" at in the Charm++ manual
-//!   http://charm.cs.illinois.edu/manuals/html/charm++/manual.html.
-// *****************************************************************************
-{
-  ElemDiagnostics::registerReducers();
-}
-
-void
-DG::ResumeFromSync()
-// *****************************************************************************
-//  Return from migration
-//! \details This is called when load balancing (LB) completes. The presence of
-//!   this function does not affect whether or not we block on LB.
-// *****************************************************************************
-{
-  if (Disc()->It() == 0) Throw( "it = 0 in ResumeFromSync()" );
-
-  if (!g_inputdeck.get< tag::cmd, tag::nonblocking >()) next();
-}
-
-void
-DG::resizeSolVectors()
-// *****************************************************************************
-// Resize solution vectors after extension due to Ghosts and continue with setup
-// *****************************************************************************
-{
-  // Resize solution vectors, lhs and rhs by the number of ghost tets
-  m_u.resize( myGhosts()->m_nunk );
-  m_un.resize( myGhosts()->m_nunk );
-  m_p.resize( myGhosts()->m_nunk );
-  m_lhs.resize( myGhosts()->m_nunk );
-  m_rhs.resize( myGhosts()->m_nunk );
-  m_rhsprev.resize( myGhosts()->m_nunk );
-  m_stiffrhs.resize( myGhosts()->m_nunk );
-  m_stiffrhsprev.resize( myGhosts()->m_nunk );
-
-  // Size communication buffer for solution and number of degrees of freedom
-  for (auto& n : m_ndofc) n.resize( myGhosts()->m_bid.size() );
-  for (auto& u : m_uc) u.resize( myGhosts()->m_bid.size() );
-  for (auto& p : m_pc) p.resize( myGhosts()->m_bid.size() );
-
-  // Initialize number of degrees of freedom in mesh elements
-  const auto pref = g_inputdeck.get< tag::pref, tag::pref >();
-  if( pref )
-  {
-    const auto ndofmax = g_inputdeck.get< tag::pref, tag::ndofmax >();
-    m_ndof.resize( myGhosts()->m_nunk, ndofmax );
-  }
-  else
-  {
-    const auto ndof = g_inputdeck.get< tag::ndof >();
-    m_ndof.resize( myGhosts()->m_nunk, ndof );
-  }
-
-  // Ensure that we also have all the geometry and connectivity data
-  // (including those of ghosts)
-  Assert( myGhosts()->m_geoElem.nunk() == m_u.nunk(),
-    "GeoElem unknowns size mismatch" );
-
-  // Signal the runtime system that all workers have received their adjacency
-  std::vector< std::size_t > meshdata{ myGhosts()->m_initial, Disc()->MeshId() };
-  contribute( meshdata, CkReduction::sum_ulong,
-    CkCallback(CkReductionTarget(Transporter,comfinal), Disc()->Tr()) );
-}
-
-void
-DG::setup()
-// *****************************************************************************
-// Set initial conditions, generate lhs, output mesh
-// *****************************************************************************
-{
-  if (g_inputdeck.get< tag::cmd, tag::chare >() ||
-      g_inputdeck.get< tag::cmd, tag::quiescence >())
-    stateProxy.ckLocalBranch()->insert( "DG", thisIndex, CkMyPe(), Disc()->It(),
-                                        "setup" );
-
-  auto d = Disc();<--- Variable 'd' is assigned a value that is never used.
-
-  // Basic error checking on sizes of element geometry data and connectivity
-  Assert( myGhosts()->m_geoElem.nunk() == m_lhs.nunk(),
-    "Size mismatch in DG::setup()" );
-
-  // Compute left-hand side of discrete PDEs
-  lhs();
-
-  // Determine elements inside user-defined IC box
-  g_dgpde[d->MeshId()].IcBoxElems( myGhosts()->m_geoElem,
-    myGhosts()->m_fd.Esuel().size()/4, m_boxelems );
-
-  // Compute volume of user-defined box IC
-  d->boxvol( {}, {}, 0 );      // punt for now
-
-  // Query time history field output labels from all PDEs integrated
-  const auto& hist_points = g_inputdeck.get< tag::history_output, tag::point >();
-  if (!hist_points.empty()) {
-    std::vector< std::string > histnames;
-    auto n = g_dgpde[d->MeshId()].histNames();
-    histnames.insert( end(histnames), begin(n), end(n) );
-    d->histheader( std::move(histnames) );
-  }
-
-  // If working with IMEX-RK, Store stiff equations into m_stiffEqIdx
-  if (g_inputdeck.get< tag::imex_runge_kutta >())
-  {
-    g_dgpde[Disc()->MeshId()].setStiffEqIdx(m_stiffEqIdx);
-    g_dgpde[Disc()->MeshId()].setNonStiffEqIdx(m_nonStiffEqIdx);
-  }
-}
-
-void
-DG::box( tk::real v, const std::vector< tk::real >& )
-// *****************************************************************************
-// Receive total box IC volume and set conditions in box
-//! \param[in] v Total volume within user-specified box
-// *****************************************************************************
-{
-  auto d = Disc();
-
-  // Store user-defined box IC volume
-  d->Boxvol() = v;
-
-  // Set initial conditions for all PDEs
-  g_dgpde[d->MeshId()].initialize( m_lhs, myGhosts()->m_inpoel,
-    myGhosts()->m_coord, m_boxelems, d->ElemBlockId(), m_u, d->T(),
-    myGhosts()->m_fd.Esuel().size()/4 );
-  g_dgpde[d->MeshId()].updatePrimitives( m_u, m_lhs, myGhosts()->m_geoElem, m_p,
-    myGhosts()->m_fd.Esuel().size()/4 );
-  // Save initial densities of all materials
-  g_dgpde[d->MeshId()].setRho0mat( m_rho0mat );
-
-  m_un = m_u;
-
-  // Output initial conditions to file (regardless of whether it was requested)
-  startFieldOutput( CkCallback(CkIndex_DG::start(), thisProxy[thisIndex]) );
-}
-
-void
-DG::start()
-// *****************************************************************************
-//  Start time stepping
-// *****************************************************************************
-{
-  // Free memory storing output mesh
-  m_outmesh.destroy();
-
-  // Start timer measuring time stepping wall clock time
-  Disc()->Timer().zero();
-  // Zero grind-timer
-  Disc()->grindZero();
-  // Start time stepping by computing the size of the next time step)
-  next();
-}
-
-void
-DG::startFieldOutput( CkCallback c )
-// *****************************************************************************
-// Start preparing fields for output to file
-//! \param[in] c Function to continue with after the write
-// *****************************************************************************
-{
-  // No field output in benchmark mode or if field output frequency not hit
-  if (g_inputdeck.get< tag::cmd, tag::benchmark >() || !fieldOutput()) {
-
-    c.send();
-
-  } else {
-
-    // Optionally refine mesh for field output
-    auto d = Disc();
-
-    if (refinedOutput()) {
-
-      const auto& tr = tk::remap( myGhosts()->m_fd.Triinpoel(), d->Gid() );
-      d->Ref()->outref( myGhosts()->m_fd.Bface(), {}, tr, c );
-
-    } else {
-
-      // cut off ghosts from mesh connectivity and coordinates
-      const auto& tr = tk::remap( myGhosts()->m_fd.Triinpoel(), d->Gid() );
-      extractFieldOutput( {}, d->Chunk(), d->Coord(), {}, {},
-                          d->NodeCommMap(), myGhosts()->m_fd.Bface(), {}, tr, c );
-
-    }
-
-  }
-}
-
-void
-DG::next()
-// *****************************************************************************
-// Advance equations to next time step
-// *****************************************************************************
-{
-  const auto pref = g_inputdeck.get< tag::pref, tag::pref >();
-
-  auto d = Disc();
-
-  if (pref && m_stage == 0 && d->T() > 0)
-    g_dgpde[d->MeshId()].eval_ndof( myGhosts()->m_nunk, myGhosts()->m_coord,
-                  myGhosts()->m_inpoel,
-                  myGhosts()->m_fd, m_u, m_p,
-                  g_inputdeck.get< tag::pref, tag::indicator >(),
-                  g_inputdeck.get< tag::ndof >(),
-                  g_inputdeck.get< tag::pref, tag::ndofmax >(),
-                  g_inputdeck.get< tag::pref, tag::tolref >(),
-                  m_ndof );
-
-  // communicate solution ghost data (if any)
-  if (myGhosts()->m_sendGhost.empty())
-    comsol_complete();
-  else
-    for(const auto& [cid, ghostdata] : myGhosts()->m_sendGhost) {
-      std::vector< std::size_t > tetid( ghostdata.size() );
-      std::vector< std::vector< tk::real > > u( ghostdata.size() ),
-                                             prim( ghostdata.size() );
-      std::vector< std::size_t > ndof;
-      std::size_t j = 0;
-      for(const auto& i : ghostdata) {
-        Assert( i < myGhosts()->m_fd.Esuel().size()/4,
-          "Sending solution ghost data" );
-        tetid[j] = i;
-        u[j] = m_u[i];
-        prim[j] = m_p[i];
-        if (pref && m_stage == 0) ndof.push_back( m_ndof[i] );
-        ++j;
-      }
-      thisProxy[ cid ].comsol( thisIndex, m_stage, tetid, u, prim, ndof );
-    }
+    //! Compute the left hand side mass matrix
+    //! \param[in] geoElem Element geometry array
+    //! \param[in,out] l Block diagonal mass matrix
+    void lhs( const tk::Fields& geoElem, tk::Fields& l ) const {
+      const auto ndof = g_inputdeck.get< tag::ndof >();
+      tk::mass( m_ncomp, ndof, geoElem, l );
+    }
+
+    //! Update the interface cells to first order dofs
+    //! \details This function resets the high-order terms in interface cells,
+    //!   and is currently not used in transport.
+    void updateInterfaceCells( tk::Fields&,
+      std::size_t,
+      std::vector< std::size_t >& ) const {}
+
+    //! Update the primitives for this PDE system
+    //! \details This function computes and stores the dofs for primitive
+    //!   quantities, which are currently unused for transport.
+    void updatePrimitives( const tk::Fields&,
+                           const tk::Fields&,
+                           const tk::Fields&,
+                           tk::Fields&,
+                           std::size_t ) const {}
+
+    //! Clean up the state of trace materials for this PDE system
+    //! \details This function cleans up the state of materials present in trace
+    //!   quantities in each cell. This is currently unused for transport.
+    void cleanTraceMaterial( tk::real,
+                             const tk::Fields&,
+                             tk::Fields&,
+                             tk::Fields&,
+                             std::size_t ) const {}
+
+    //! Reconstruct second-order solution from first-order
+    //! \param[in] t Physical time
+    //! \param[in] geoFace Face geometry array
+    //! \param[in] geoElem Element geometry array
+    //! \param[in] fd Face connectivity and boundary conditions object
+    //! \param[in] esup Elements-surrounding-nodes connectivity
+    //! \param[in] inpoel Element-node connectivity
+    //! \param[in] coord Array of nodal coordinates
+    //! \param[in,out] U Solution vector at recent time step
+    //! \param[in,out] P Primitive vector at recent time step
+    void reconstruct( tk::real t,
+                      const tk::Fields& geoFace,
+                      const tk::Fields& geoElem,
+                      const inciter::FaceData& fd,
+                      const std::map< std::size_t, std::vector< std::size_t > >&
+                        esup,
+                      const std::vector< std::size_t >& inpoel,
+                      const tk::UnsMesh::Coords& coord,
+                      tk::Fields& U,
+                      tk::Fields& P ) const
+    {
+      const auto rdof = g_inputdeck.get< tag::rdof >();
+
+      // do reconstruction only if P0P1
+      if (rdof == 4 && g_inputdeck.get< tag::ndof >() == 1) {
+        const auto nelem = fd.Esuel().size()/4;<--- Variable 'nelem' is assigned a value that is never used.
+        const auto intsharp = g_inputdeck.get< tag::transport,<--- Variable 'intsharp' is assigned a value that is never used.
+          tag::intsharp >();
+
+        Assert( U.nprop() == rdof*m_ncomp, "Number of components in solution "
+                "vector must equal "+ std::to_string(rdof*m_ncomp) );
+        Assert( fd.Inpofa().size()/3 == fd.Esuf().size()/2,
+                "Mismatch in inpofa size" );
+
+        // allocate and initialize matrix and vector for reconstruction
+        std::vector< std::array< std::array< tk::real, 3 >, 3 > >
+          lhs_ls( nelem, {{ {{0.0, 0.0, 0.0}},
+                            {{0.0, 0.0, 0.0}},
+                            {{0.0, 0.0, 0.0}} }} );
+        // specify how many variables need to be reconstructed
+        std::vector< std::size_t > vars;
+        for (std::size_t c=0; c<m_ncomp; ++c) vars.push_back(c);
+
+        std::vector< std::vector< std::array< tk::real, 3 > > >
+          rhs_ls( nelem, std::vector< std::array< tk::real, 3 > >
+            ( m_ncomp,
+              {{ 0.0, 0.0, 0.0 }} ) );
+
+        // reconstruct x,y,z-derivatives of unknowns
+        // 0. get lhs matrix, which is only geometry dependent
+        tk::lhsLeastSq_P0P1(fd, geoElem, geoFace, lhs_ls);
+
+        // 1. internal face contributions
+        tk::intLeastSq_P0P1( rdof, fd, geoElem, U, rhs_ls, vars );
+
+        // 2. boundary face contributions
+        for (const auto& b : m_bc)
+          tk::bndLeastSqConservedVar_P0P1( m_ncomp, 
+            m_mat_blk, rdof, b.first, fd, geoFace, geoElem, t, b.second, 
+            P, U, rhs_ls, vars );
+
+        // 3. solve 3x3 least-squares system
+        tk::solveLeastSq_P0P1( rdof, lhs_ls, rhs_ls, U, vars );
+
+        for (std::size_t e=0; e<nelem; ++e)
+        {
+          std::vector< std::size_t > matInt(m_ncomp, 0);
+          std::vector< tk::real > alAvg(m_ncomp, 0.0);
+          for (std::size_t k=0; k<m_ncomp; ++k)
+            alAvg[k] = U(e, k*rdof);
+          auto intInd = interfaceIndicator(m_ncomp, alAvg, matInt);
+          if ((intsharp > 0) && intInd)
+          {
+            // Reconstruct second-order dofs of volume-fractions in Taylor space
+            // using nodal-stencils, for a good interface-normal estimate
+            tk::recoLeastSqExtStencil( rdof, e, esup, inpoel, geoElem,
+              U, vars );
+          }
+        }
+
+        // 4. transform reconstructed derivatives to Dubiner dofs
+        tk::transform_P0P1( rdof, nelem, inpoel, coord, U, vars );
+      }
+    }
+
+    //! Limit second-order solution
+    //! \param[in] t Physical time
+    //! \param[in] geoFace Face geometry array
+    //! \param[in] fd Face connectivity and boundary conditions object
+    //! \param[in] esup Elements surrounding points
+    //! \param[in] inpoel Element-node connectivity
+    //! \param[in] coord Array of nodal coordinates
+    //! \param[in] ndofel Vector of local number of degrees of freedome
+//    //! \param[in] gid Local->global node id map
+//    //! \param[in] bid Local chare-boundary node ids (value) associated to
+//    //!   global node ids (key)
+//    //! \param[in] uNodalExtrm Chare-boundary nodal extrema for conservative
+//    //!   variables
+    //! \param[in,out] U Solution vector at recent time step
+    void limit( [[maybe_unused]] tk::real t,
+                [[maybe_unused]] const tk::Fields& geoFace,
+                const tk::Fields&,
+                const inciter::FaceData& fd,
+                const std::map< std::size_t, std::vector< std::size_t > >& esup,
+                const std::vector< std::size_t >& inpoel,
+                const tk::UnsMesh::Coords& coord,
+                const std::vector< std::size_t >& ndofel,
+                const std::vector< std::size_t >&,
+                const std::unordered_map< std::size_t, std::size_t >&,
+                const std::vector< std::vector<tk::real> >&,
+                const std::vector< std::vector<tk::real> >&,
+                const std::vector< std::vector<tk::real> >&,
+                tk::Fields& U,
+                tk::Fields&,
+                std::vector< std::size_t >& ) const
+    {
+      const auto limiter = g_inputdeck.get< tag::limiter >();
+
+      if (limiter == ctr::LimiterType::WENOP1)
+        WENO_P1( fd.Esuel(), U );
+      else if (limiter == ctr::LimiterType::SUPERBEEP1)
+        Superbee_P1( fd.Esuel(), inpoel, ndofel, coord, U );
+      else if (limiter == ctr::LimiterType::VERTEXBASEDP1)
+        VertexBasedTransport_P1( esup, inpoel, ndofel, fd.Esuel().size()/4,
+          coord, U );
+    }
+
+    //! Update the conservative variable solution for this PDE system
+    //! \details This function computes the updated dofs for conservative
+    //!   quantities based on the limited solution and is currently not used in
+    //!   transport.
+    void CPL( const tk::Fields&,
+              const tk::Fields&,
+              const std::vector< std::size_t >&,
+              const tk::UnsMesh::Coords&,
+              tk::Fields&,
+              std::size_t ) const {}
+
+    //! Return cell-average deformation gradient tensor (no-op for transport)
+    //! \details This function is a no-op in transport.
+    std::array< std::vector< tk::real >, 9 > cellAvgDeformGrad(
+      const tk::Fields&,
+      std::size_t ) const
+    {
+      return {};
+    }
+
+    //! Compute right hand side
+    //! \param[in] t Physical time
+    //! \param[in] geoFace Face geometry array
+    //! \param[in] geoElem Element geometry array
+    //! \param[in] fd Face connectivity and boundary conditions object
+    //! \param[in] inpoel Element-node connectivity
+    //! \param[in] coord Array of nodal coordinates
+    //! \param[in] U Solution vector at recent time step
+    //! \param[in] P Primitive vector at recent time step
+    //! \param[in] ndofel Vector of local number of degrees of freedom
+    // //! \param[in] rho0mat Initial densities of all materials
+    //! \param[in] dt Delta time
+    //! \param[in,out] R Right-hand side vector computed
+    void rhs( tk::real t,
+              const tk::Fields& geoFace,
+              const tk::Fields& geoElem,
+              const inciter::FaceData& fd,
+              const std::vector< std::size_t >& inpoel,
+              const std::vector< std::unordered_set< std::size_t > >&,
+              const tk::UnsMesh::Coords& coord,
+              const tk::Fields& U,
+              const tk::Fields& P,
+              const std::vector< std::size_t >& ndofel,
+              const std::vector< tk::real >& /*rho0mat*/,
+              const tk::real dt,
+              tk::Fields& R ) const
+    {
+      const auto ndof = g_inputdeck.get< tag::ndof >();<--- Variable 'ndof' is assigned a value that is never used.
+      const auto rdof = g_inputdeck.get< tag::rdof >();<--- Variable 'rdof' is assigned a value that is never used.
+      const auto intsharp = g_inputdeck.get< tag::transport,<--- Variable 'intsharp' is assigned a value that is never used.
+        tag::intsharp >();
+
+      Assert( U.nunk() == P.nunk(), "Number of unknowns in solution "
+              "vector and primitive vector at recent time step incorrect" );
+      Assert( U.nunk() == R.nunk(), "Number of unknowns in solution "
+              "vector and right-hand side at recent time step incorrect" );
+      Assert( U.nprop() == rdof*m_ncomp, "Number of components in solution "
+              "vector must equal "+ std::to_string(rdof*m_ncomp) );
+      Assert( P.nprop() == 0, "Number of components in primitive "
+              "vector must equal "+ std::to_string(0) );
+      Assert( R.nprop() == ndof*m_ncomp, "Number of components in right-hand "
+              "side vector must equal "+ std::to_string(ndof*m_ncomp) );
+      Assert( fd.Inpofa().size()/3 == fd.Esuf().size()/2,
+              "Mismatch in inpofa size" );
+
+      // set rhs to zero
+      R.fill(0.0);
+
+      // empty vector for non-conservative terms. This vector is unused for
+      // linear transport since, there are no non-conservative terms in the
+      // system of PDEs.
+      std::vector< std::vector < tk::real > > riemannDeriv;
+
+      std::vector< std::vector< tk::real > > vriem;
+      std::vector< std::vector< tk::real > > riemannLoc;
+
+      // compute internal surface flux integrals
+      std::vector< std::size_t > solidx(1, 0);
+      tk::surfInt( m_ncomp, m_mat_blk, t, ndof, rdof,
+                   inpoel, solidx, coord, fd, geoFace, geoElem, Upwind::flux,
+                   Problem::prescribedVelocity, U, P, ndofel, dt, R, vriem,
+                   riemannLoc, riemannDeriv, intsharp );
 
-  ownsol_complete();
-}
-
-void
-DG::comsol( int fromch,
-            std::size_t fromstage,
-            const std::vector< std::size_t >& tetid,
-            const std::vector< std::vector< tk::real > >& u,
-            const std::vector< std::vector< tk::real > >& prim,
-            const std::vector< std::size_t >& ndof )
-// *****************************************************************************
-//  Receive chare-boundary solution ghost data from neighboring chares
-//! \param[in] fromch Sender chare id
-//! \param[in] fromstage Sender chare time step stage
-//! \param[in] tetid Ghost tet ids we receive solution data for
-//! \param[in] u Solution ghost data
-//! \param[in] prim Primitive variables in ghost cells
-//! \param[in] ndof Number of degrees of freedom for chare-boundary elements
-//! \details This function receives contributions to the unlimited solution
-//!   from fellow chares.
-// *****************************************************************************
-{
-  Assert( u.size() == tetid.size(), "Size mismatch in DG::comsol()" );
-  Assert( prim.size() == tetid.size(), "Size mismatch in DG::comsol()" );
-
-  const auto pref = g_inputdeck.get< tag::pref, tag::pref >();
-
-  if (pref && fromstage == 0)
-    Assert( ndof.size() == tetid.size(), "Size mismatch in DG::comsol()" );
-
-  // Find local-to-ghost tet id map for sender chare
-  const auto& n = tk::cref_find( myGhosts()->m_ghost, fromch );
-
-  for (std::size_t i=0; i<tetid.size(); ++i) {
-    auto j = tk::cref_find( n, tetid[i] );
-    Assert( j >= myGhosts()->m_fd.Esuel().size()/4,
-      "Receiving solution non-ghost data" );
-    auto b = tk::cref_find( myGhosts()->m_bid, j );
-    Assert( b < m_uc[0].size(), "Indexing out of bounds" );
-    m_uc[0][b] = u[i];
-    m_pc[0][b] = prim[i];
-    if (pref && fromstage == 0) {
-      Assert( b < m_ndofc[0].size(), "Indexing out of bounds" );
-      m_ndofc[0][b] = ndof[i];
-    }
-  }
+      if(ndof > 1)
+        // compute volume integrals
+        tk::volInt( m_ncomp, t, m_mat_blk, ndof, rdof,
+                    fd.Esuel().size()/4, inpoel, coord, geoElem, flux,
+                    Problem::prescribedVelocity, U, P, ndofel, R, intsharp );
+
+      // compute boundary surface flux integrals
+      for (const auto& b : m_bc)
+        tk::bndSurfInt( m_ncomp, m_mat_blk, ndof, rdof,
+          b.first, fd, geoFace, geoElem, inpoel, coord, t, Upwind::flux,
+          Problem::prescribedVelocity, b.second, U, P, ndofel, R, vriem,
+          riemannLoc, riemannDeriv, intsharp );
+    }
+
+    //! Evaluate the adaptive indicator and mark the ndof for each element
+    //! \param[in] nunk Number of unknowns
+    //! \param[in] coord Array of nodal coordinates
+    //! \param[in] inpoel Element-node connectivity
+    //! \param[in] fd Face connectivity and boundary conditions object
+    //! \param[in] unk Array of unknowns
+    //! \param[in] prim Array of primitive quantities
+    //! \param[in] indicator p-refinement indicator type
+    //! \param[in] ndof Number of degrees of freedom in the solution
+    //! \param[in] ndofmax Max number of degrees of freedom for p-refinement
+    //! \param[in] tolref Tolerance for p-refinement
+    //! \param[in,out] ndofel Vector of local number of degrees of freedome
+    void eval_ndof( std::size_t nunk,
+                    [[maybe_unused]] const tk::UnsMesh::Coords& coord,
+                    [[maybe_unused]] const std::vector< std::size_t >& inpoel,
+                    const inciter::FaceData& fd,
+                    const tk::Fields& unk,
+                    const tk::Fields& prim,
+                    inciter::ctr::PrefIndicatorType indicator,
+                    std::size_t ndof,
+                    std::size_t ndofmax,
+                    tk::real tolref,
+                    std::vector< std::size_t >& ndofel ) const
+    {
+      const auto& esuel = fd.Esuel();
+
+      if(indicator == inciter::ctr::PrefIndicatorType::SPECTRAL_DECAY)
+        spectral_decay( 1, nunk, esuel, unk, prim, ndof, ndofmax, tolref,
+          ndofel );
+      else
+        Throw( "No such adaptive indicator type" );
+    }
 
-  // if we have received all solution ghost contributions from neighboring
-  // chares (chares we communicate along chare-boundary faces with), and
-  // contributed our solution to these neighbors, proceed to reconstructions
-  if (++m_nsol == myGhosts()->m_sendGhost.size()) {
-    m_nsol = 0;
-    comsol_complete();
-  }
-}
-
-void
-DG::extractFieldOutput(
-  const std::vector< std::size_t >& /*ginpoel*/,
-  const tk::UnsMesh::Chunk& chunk,
-  const tk::UnsMesh::Coords& coord,
-  const std::unordered_map< std::size_t, tk::UnsMesh::Edge >& /*addedNodes*/,
-  const std::unordered_map< std::size_t, std::size_t >& addedTets,
-  const tk::NodeCommMap& nodeCommMap,
-  const std::map< int, std::vector< std::size_t > >& bface,
-  const std::map< int, std::vector< std::size_t > >& /* bnode */,
-  const std::vector< std::size_t >& triinpoel,
-  CkCallback c )
-// *****************************************************************************
-// Extract field output going to file
-//! \param[in] chunk Field-output mesh chunk (connectivity and global<->local
-//!    id maps)
-//! \param[in] coord Field-output mesh node coordinates
-//! \param[in] addedTets Field-output mesh cells and their parents (local ids)
-//! \param[in] nodeCommMap Field-output mesh node communication map
-//! \param[in] bface Field-output meshndary-faces mapped to side set ids
-//! \param[in] triinpoel Field-output mesh boundary-face connectivity
-//! \param[in] c Function to continue with after the write
-// *****************************************************************************
-{
-  m_outmesh.chunk = chunk;
-  m_outmesh.coord = coord;
-  m_outmesh.triinpoel = triinpoel;
-  m_outmesh.bface = bface;
-  m_outmesh.nodeCommMap = nodeCommMap;
-
-  const auto& inpoel = std::get< 0 >( chunk );
-
-  // Evaluate element solution on incoming mesh
-  evalSolution( *Disc(), inpoel, coord, addedTets, m_ndof, m_u, m_p,
-    m_uElemfields, m_pElemfields, m_uNodefields, m_pNodefields );
+    //! Compute the minimum time step size
+//     //! \param[in] U Solution vector at recent time step
+//     //! \param[in] coord Mesh node coordinates
+//     //! \param[in] inpoel Mesh element connectivity
+    //! \return Minimum time step size
+    tk::real dt( const std::array< std::vector< tk::real >, 3 >& /*coord*/,
+                 const std::vector< std::size_t >& /*inpoel*/,
+                 const inciter::FaceData& /*fd*/,
+                 const tk::Fields& /*geoFace*/,
+                 const tk::Fields& /*geoElem*/,
+                 const std::vector< std::size_t >& /*ndofel*/,
+                 const tk::Fields& /*U*/,
+                 const tk::Fields&,
+                 const std::size_t /*nielem*/ ) const
+    {
+      tk::real mindt = std::numeric_limits< tk::real >::max();
+      return mindt;
+    }
+
+    //! Compute stiff terms for a single element, not implemented here
+    // //! \param[in] e Element number
+    // //! \param[in] geoElem Element geometry array
+    // //! \param[in] inpoel Element-node connectivity
+    // //! \param[in] coord Array of nodal coordinates
+    // //! \param[in] U Solution vector at recent time step
+    // //! \param[in] P Primitive vector at recent time step
+    // //! \param[in] ndofel Vector of local number of degrees of freedom
+    // //! \param[in,out] R Right-hand side vector computed
+    void stiff_rhs( std::size_t /*e*/,
+                    const tk::Fields& /*geoElem*/,
+                    const std::vector< std::size_t >& /*inpoel*/,
+                    const tk::UnsMesh::Coords& /*coord*/,
+                    const tk::Fields& /*U*/,
+                    const tk::Fields& /*P*/,
+                    const std::vector< std::size_t >& /*ndofel*/,
+                    tk::Fields& /*R*/ ) const
+    {}
+
+    //! Return a map that associates user-specified strings to functions
+    //! \return Map that associates user-specified strings to functions that
+    //!  compute relevant quantities to be output to file
+    std::map< std::string, tk::GetVarFn > OutVarFn() const {
+      std::map< std::string, tk::GetVarFn > OutFnMap;
+      OutFnMap["material_indicator"] = transport::matIndicatorOutVar;
 
-  // Send node fields contributions to neighbor chares
-  if (nodeCommMap.empty())
-    comnodeout_complete();
-  else {
-    const auto& lid = std::get< 2 >( chunk );
-    auto esup = tk::genEsup( inpoel, 4 );
-    for(const auto& [ch,nodes] : nodeCommMap) {
-      // Pack node field data in chare boundary nodes
-      std::vector< std::vector< tk::real > >
-        lu( m_uNodefields.nprop(), std::vector< tk::real >( nodes.size() ) );
-      std::vector< std::vector< tk::real > >
-        lp( m_pNodefields.nprop(), std::vector< tk::real >( nodes.size() ) );
-      for (std::size_t f=0; f<m_uNodefields.nprop(); ++f) {
-        std::size_t j = 0;
-        for (auto g : nodes)
-          lu[f][j++] = m_uNodefields(tk::cref_find(lid,g),f);
-      }
-      for (std::size_t f=0; f<m_pNodefields.nprop(); ++f) {
-        std::size_t j = 0;
-        for (auto g : nodes)
-          lp[f][j++] = m_pNodefields(tk::cref_find(lid,g),f);
-      }
-      // Pack (partial) number of elements surrounding chare boundary nodes
-      std::vector< std::size_t > nesup( nodes.size() );
-      std::size_t j = 0;
-      for (auto g : nodes) {
-        auto i = tk::cref_find( lid, g );
-        nesup[j++] = esup.second[i+1] - esup.second[i];
-      }
-      thisProxy[ch].comnodeout(
-        std::vector<std::size_t>(begin(nodes),end(nodes)), nesup, lu, lp );
-    }
-  }
-
-  ownnod_complete( c, addedTets );
-}
-
-void
-DG::lhs()
-// *****************************************************************************
-// Compute left-hand side of discrete transport equations
-// *****************************************************************************
-{
-  g_dgpde[Disc()->MeshId()].lhs( myGhosts()->m_geoElem, m_lhs );
-
-  if (!m_initial) stage();
-}
-
-void DG::refine()
-// *****************************************************************************
-// Add the protective layer for ndof refinement
-// *****************************************************************************
-{
-  const auto pref = g_inputdeck.get< tag::pref, tag::pref >();
-
-  // Combine own and communicated contributions of unreconstructed solution and
-  // degrees of freedom in cells (if p-adaptive)
-  for (const auto& b : myGhosts()->m_bid) {
-    Assert( m_uc[0][b.second].size() == m_u.nprop(), "ncomp size mismatch" );
-    Assert( m_pc[0][b.second].size() == m_p.nprop(), "ncomp size mismatch" );
-    for (std::size_t c=0; c<m_u.nprop(); ++c) {
-      m_u(b.first,c) = m_uc[0][b.second][c];
-    }
-    for (std::size_t c=0; c<m_p.nprop(); ++c) {
-      m_p(b.first,c) = m_pc[0][b.second][c];
-    }
-    if (pref && m_stage == 0) {
-      m_ndof[ b.first ] = m_ndofc[0][ b.second ];
-    }
-  }
-
-  if (pref && m_stage==0) refine_ndof();
-
-  if (myGhosts()->m_sendGhost.empty())
-    comrefine_complete();
-  else
-    for(const auto& [cid, ghostdata] : myGhosts()->m_sendGhost) {
-      std::vector< std::size_t > tetid( ghostdata.size() );
-      std::vector< std::vector< tk::real > > u( ghostdata.size() ),
-                                             prim( ghostdata.size() );
-      std::vector< std::size_t > ndof( ghostdata.size() );
-      std::size_t j = 0;
-      for(const auto& i : ghostdata) {
-        Assert( i < myGhosts()->m_fd.Esuel().size()/4, "Sending refined ndof  "
-          "data" );
-        tetid[j] = i;
-        if (pref && m_stage == 0) ndof[j] = m_ndof[i];
-        ++j;
+      return OutFnMap;
+    }
+
+    //! Return analytic field names to be output to file
+    //! \return Vector of strings labelling analytic fields output in file
+    std::vector< std::string > analyticFieldNames() const {
+      std::vector< std::string > n;
+      auto depvar = g_inputdeck.get< tag::depvar >()[0];
+      for (ncomp_t c=0; c<m_ncomp; ++c)
+        n.push_back( depvar + std::to_string(c) + "_analytic" );
+      return n;
+    }
+
+    //! Return surface field output going to file
+    std::vector< std::vector< tk::real > >
+    surfOutput( const std::map< int, std::vector< std::size_t > >&,
+                tk::Fields& ) const
+    {
+      std::vector< std::vector< tk::real > > s; // punt for now
+      return s;
+    }
+
+    //! Return time history field names to be output to file
+    //! \return Vector of strings labelling time history fields output in file
+    std::vector< std::string > histNames() const {
+      std::vector< std::string > s; // punt for now
+      return s;
+    }
+
+    //! Return names of integral variables to be output to diagnostics file
+    //! \return Vector of strings labelling integral variables output
+    std::vector< std::string > names() const {
+      std::vector< std::string > n;
+      const auto& depvar =
+      g_inputdeck.get< tag::depvar >().at(0);
+      // construct the name of the numerical solution for all components
+      for (ncomp_t c=0; c<m_ncomp; ++c)
+        n.push_back( depvar + std::to_string(c) );
+      return n;
+    }
+
+    //! Return analytic solution (if defined by Problem) at xi, yi, zi, t
+    //! \param[in] xi X-coordinate at which to evaluate the analytic solution
+    //! \param[in] yi Y-coordinate at which to evaluate the analytic solution
+    //! \param[in] zi Z-coordinate at which to evaluate the analytic solution
+    //! \param[in] t Physical time at which to evaluate the analytic solution
+    //! \return Vector of analytic solution at given spatial location and time
+    std::vector< tk::real >
+    analyticSolution( tk::real xi, tk::real yi, tk::real zi, tk::real t ) const
+    { return Problem::analyticSolution( m_ncomp, m_mat_blk, xi, yi,
+                                        zi, t ); }
+
+    //! Return analytic solution for conserved variables
+    //! \param[in] xi X-coordinate at which to evaluate the analytic solution
+    //! \param[in] yi Y-coordinate at which to evaluate the analytic solution
+    //! \param[in] zi Z-coordinate at which to evaluate the analytic solution
+    //! \param[in] t Physical time at which to evaluate the analytic solution
+    //! \return Vector of analytic solution at given location and time
+    std::vector< tk::real >
+    solution( tk::real xi, tk::real yi, tk::real zi, tk::real t ) const
+    { return Problem::initialize( m_ncomp, m_mat_blk, xi, yi, zi, t ); }
+
+    //! Return time history field output evaluated at time history points
+    //! \param[in] h History point data
+    std::vector< std::vector< tk::real > >
+    histOutput( const std::vector< HistData >& h,
+                const std::vector< std::size_t >&,
+                const tk::UnsMesh::Coords&,
+                const tk::Fields&,
+                const tk::Fields& ) const
+    {
+      std::vector< std::vector< tk::real > > Up(h.size()); //punt for now
+      return Up;
+    }
+
+    //! Return cell-averaged total component mass per unit volume for an element
+    //! \param[in] e Element id for which total energy is required
+    //! \param[in] unk Vector of conserved quantities
+    //! \return Cell-averaged total component mass per unit volume for given
+    //!   element. Since transport does not have an associated total energy,
+    //!   return total mass.
+    tk::real sp_totalenergy(std::size_t e, const tk::Fields& unk) const
+    {
+      const auto rdof = g_inputdeck.get< tag::rdof >();
+
+      tk::real sp_m(0.0);
+      for (std::size_t c=0; c<m_ncomp; ++c) {
+        sp_m += unk(e,c*rdof);
       }
-      thisProxy[ cid ].comrefine( thisIndex, tetid, ndof );
+      return sp_m;
     }
 
-  ownrefine_complete();
-}
-
-void
-DG::comrefine( int fromch,
-               const std::vector< std::size_t >& tetid,
-               const std::vector< std::size_t >& ndof )
-// *****************************************************************************
-//  Receive chare-boundary ghost data from neighboring chares
-//! \param[in] fromch Sender chare id
-//! \param[in] tetid Ghost tet ids we receive solution data for
-//! \param[in] ndof Number of degrees of freedom for chare-boundary elements
-//! \details This function receives contributions to the refined ndof data
-//!   from fellow chares.
-// *****************************************************************************
-{
-  const auto pref = g_inputdeck.get< tag::pref, tag::pref >();
-
-  if (pref && m_stage == 0)
-    Assert( ndof.size() == tetid.size(), "Size mismatch in DG::comrefine()" );
-
-  // Find local-to-ghost tet id map for sender chare
-  const auto& n = tk::cref_find( myGhosts()->m_ghost, fromch );
+  private:
+    const Physics m_physics;            //!< Physics policy
+    const Problem m_problem;            //!< Problem policy
+    const ncomp_t m_ncomp;              //!< Number of components in this PDE
+    //! BC configuration
+    BCStateFn m_bc;
+    //! \brief EOS material block - This PDE does not require an EOS block,
+    //! thus this variable has not been intialized.
+    std::vector< EOS > m_mat_blk;
+
+    //! Evaluate physical flux function for this PDE system
+    //! \param[in] ncomp Number of scalar components in this PDE system
+    //! \param[in] ugp Numerical solution at the Gauss point at which to
+    //!   evaluate the flux
+    //! \param[in] v Prescribed velocity evaluated at the Gauss point at which
+    //!   to evaluate the flux
+    //! \return Flux vectors for all components in this PDE system
+    //! \note The function signature must follow tk::FluxFn
+    static tk::FluxFn::result_type
+    flux( ncomp_t ncomp,
+          const std::vector< EOS >&,
+          const std::vector< tk::real >& ugp,
+          const std::vector< std::array< tk::real, 3 > >& v )
 
-  for (std::size_t i=0; i<tetid.size(); ++i) {
-    auto j = tk::cref_find( n, tetid[i] );
-    Assert( j >= myGhosts()->m_fd.Esuel().size()/4,
-      "Receiving solution non-ghost data" );
-    auto b = tk::cref_find( myGhosts()->m_bid, j );
-    if (pref && m_stage == 0) {
-      Assert( b < m_ndofc[1].size(), "Indexing out of bounds" );
-      m_ndofc[1][b] = ndof[i];
-    }
-  }
-
-  // if we have received all solution ghost contributions from neighboring
-  // chares (chares we communicate along chare-boundary faces with), and
-  // contributed our solution to these neighbors, proceed to limiting
-  if (++m_nrefine == myGhosts()->m_sendGhost.size()) {
-    m_nrefine = 0;
-    comrefine_complete();
-  }
-}
-
-void
-DG::smooth()
-// *****************************************************************************
-// Smooth the refined ndof distribution
-// *****************************************************************************
-{
-  const auto pref = g_inputdeck.get< tag::pref, tag::pref >();
-
-  for (const auto& b : myGhosts()->m_bid) {
-    if (pref && m_stage == 0)
-      m_ndof[ b.first ] = m_ndofc[1][ b.second ];
-  }
-
-  if (pref && m_stage==0) smooth_ndof();
-
-  if (myGhosts()->m_sendGhost.empty())
-    comsmooth_complete();
-  else
-    for(const auto& [cid, ghostdata] : myGhosts()->m_sendGhost) {
-      std::vector< std::size_t > tetid( ghostdata.size() );
-      std::vector< std::size_t > ndof;
-      std::size_t j = 0;
-      for(const auto& i : ghostdata) {
-        Assert( i < myGhosts()->m_fd.Esuel().size()/4, "Sending ndof data" );
-        tetid[j] = i;
-        if (pref && m_stage == 0) ndof.push_back( m_ndof[i] );
-        ++j;
-      }
-      thisProxy[ cid ].comsmooth( thisIndex, tetid, ndof );
-    }
-
-  ownsmooth_complete();
-}
-
-void
-DG::comsmooth( int fromch,
-               const std::vector< std::size_t >& tetid,
-               const std::vector< std::size_t >& ndof )
-// *****************************************************************************
-//  Receive chare-boundary ghost data from neighboring chares
-//! \param[in] fromch Sender chare id
-//! \param[in] tetid Ghost tet ids we receive solution data for
-//! \param[in] ndof Number of degrees of freedom for chare-boundary elements
-//! \details This function receives contributions to the smoothed ndof data
-//!   from fellow chares.
-// *****************************************************************************
-{
-  const auto pref = g_inputdeck.get< tag::pref, tag::pref >();
-
-  if (pref && m_stage == 0)
-    Assert( ndof.size() == tetid.size(), "Size mismatch in DG::comsmooth()" );
-
-  const auto& n = tk::cref_find( myGhosts()->m_ghost, fromch );
-
-  for (std::size_t i=0; i<tetid.size(); ++i) {
-    auto j = tk::cref_find( n, tetid[i] );
-    Assert( j >= myGhosts()->m_fd.Esuel().size()/4, "Receiving ndof data" );
-    auto b = tk::cref_find( myGhosts()->m_bid, j );
-    if (pref && m_stage == 0) {
-      Assert( b < m_ndofc[2].size(), "Indexing out of bounds" );
-      m_ndofc[2][b] = ndof[i];
-    }
-  }
-
-  if (++m_nsmooth == myGhosts()->m_sendGhost.size()) {
-    m_nsmooth = 0;
-    comsmooth_complete();
-  }
-}
-
-void
-DG::reco()
-// *****************************************************************************
-// Compute reconstructions
-// *****************************************************************************
-{
-  const auto pref = g_inputdeck.get< tag::pref, tag::pref >();
-  const auto rdof = g_inputdeck.get< tag::rdof >();
-
-  // Combine own and communicated contributions of unreconstructed solution and
-  // degrees of freedom in cells (if p-adaptive)
-  for (const auto& b : myGhosts()->m_bid) {
-    if (pref && m_stage == 0) {
-      m_ndof[ b.first ] = m_ndofc[2][ b.second ];
-    }
-  }
-
-  auto d = Disc();
-  if (rdof > 1)
-    // Reconstruct second-order solution and primitive quantities
-    g_dgpde[d->MeshId()].reconstruct( d->T(), myGhosts()->m_geoFace,
-      myGhosts()->m_geoElem,
-      myGhosts()->m_fd, myGhosts()->m_esup, myGhosts()->m_inpoel,
-      myGhosts()->m_coord, m_u, m_p );
-
-  // Send reconstructed solution to neighboring chares
-  if (myGhosts()->m_sendGhost.empty())
-    comreco_complete();
-  else
-    for(const auto& [cid, ghostdata] : myGhosts()->m_sendGhost) {
-      std::vector< std::size_t > tetid( ghostdata.size() );
-      std::vector< std::vector< tk::real > > u( ghostdata.size() ),
-                                             prim( ghostdata.size() );
-      std::size_t j = 0;
-      for(const auto& i : ghostdata) {
-        Assert( i < myGhosts()->m_fd.Esuel().size()/4, "Sending reconstructed ghost "
-          "data" );
-        tetid[j] = i;
-        u[j] = m_u[i];
-        prim[j] = m_p[i];
-        ++j;
-      }
-      thisProxy[ cid ].comreco( thisIndex, tetid, u, prim );
-    }
-
-  ownreco_complete();
-}
-
-void
-DG::comreco( int fromch,
-             const std::vector< std::size_t >& tetid,
-             const std::vector< std::vector< tk::real > >& u,
-             const std::vector< std::vector< tk::real > >& prim )
-// *****************************************************************************
-//  Receive chare-boundary reconstructed ghost data from neighboring chares
-//! \param[in] fromch Sender chare id
-//! \param[in] tetid Ghost tet ids we receive solution data for
-//! \param[in] u Reconstructed high-order solution
-//! \param[in] prim Limited high-order primitive quantities
-//! \details This function receives contributions to the reconstructed solution
-//!   from fellow chares.
-// *****************************************************************************
-{
-  Assert( u.size() == tetid.size(), "Size mismatch in DG::comreco()" );
-  Assert( prim.size() == tetid.size(), "Size mismatch in DG::comreco()" );
-
-  // Find local-to-ghost tet id map for sender chare
-  const auto& n = tk::cref_find( myGhosts()->m_ghost, fromch );
-
-  for (std::size_t i=0; i<tetid.size(); ++i) {
-    auto j = tk::cref_find( n, tetid[i] );
-    Assert( j >= myGhosts()->m_fd.Esuel().size()/4,
-      "Receiving solution non-ghost data" );
-    auto b = tk::cref_find( myGhosts()->m_bid, j );
-    Assert( b < m_uc[1].size(), "Indexing out of bounds" );
-    Assert( b < m_pc[1].size(), "Indexing out of bounds" );
-    m_uc[1][b] = u[i];
-    m_pc[1][b] = prim[i];
-  }
-
-  // if we have received all solution ghost contributions from neighboring
-  // chares (chares we communicate along chare-boundary faces with), and
-  // contributed our solution to these neighbors, proceed to limiting
-  if (++m_nreco == myGhosts()->m_sendGhost.size()) {
-    m_nreco = 0;
-    comreco_complete();
-  }
-}
-
-void
-DG::nodalExtrema()
-// *****************************************************************************
-// Compute nodal extrema at chare-boundary nodes. Extrema at internal nodes
-// are calculated in limiter function.
-// *****************************************************************************
-{
-  auto d = Disc();
-  auto gid = d->Gid();
-  auto bid = d->Bid();
-  const auto rdof = g_inputdeck.get< tag::rdof >();
-  const auto ncomp = m_u.nprop() / rdof;
-  const auto nprim = m_p.nprop() / rdof;
-
-  // Combine own and communicated contributions of unlimited solution, and
-  // if a p-adaptive algorithm is used, degrees of freedom in cells
-  for (const auto& [boundary, localtet] : myGhosts()->m_bid) {
-    Assert( m_uc[1][localtet].size() == m_u.nprop(), "ncomp size mismatch" );
-    Assert( m_pc[1][localtet].size() == m_p.nprop(), "ncomp size mismatch" );
-    for (std::size_t c=0; c<m_u.nprop(); ++c) {
-      m_u(boundary,c) = m_uc[1][localtet][c];
-    }
-    for (std::size_t c=0; c<m_p.nprop(); ++c) {
-      m_p(boundary,c) = m_pc[1][localtet][c];
-    }
-  }
-
-  // Initialize nodal extrema vector
-  auto large = std::numeric_limits< tk::real >::max();
-  for(std::size_t i = 0; i<bid.size(); i++)
-  {
-    for (std::size_t c=0; c<ncomp; ++c)
-    {
-      for(std::size_t idof=0; idof<m_ndof_NodalExtrm; idof++)
-      {
-        auto max_mark = 2*c*m_ndof_NodalExtrm + 2*idof;
-        auto min_mark = max_mark + 1;
-        m_uNodalExtrm[i][max_mark] = -large;
-        m_uNodalExtrm[i][min_mark] =  large;
-      }
-    }
-    for (std::size_t c=0; c<nprim; ++c)
-    {
-      for(std::size_t idof=0; idof<m_ndof_NodalExtrm; idof++)
-      {
-        auto max_mark = 2*c*m_ndof_NodalExtrm + 2*idof;
-        auto min_mark = max_mark + 1;
-        m_pNodalExtrm[i][max_mark] = -large;
-        m_pNodalExtrm[i][min_mark] =  large;
-      }
-    }
-  }
-
-  // Evaluate the max/min value for the chare-boundary nodes
-  if(rdof > 4) {
-      evalNodalExtrmRefEl(ncomp, nprim, m_ndof_NodalExtrm, d->bndel(),
-        myGhosts()->m_inpoel, gid, bid, m_u, m_p, m_uNodalExtrm, m_pNodalExtrm);
-  }
-
-  // Communicate extrema at nodes to other chares on chare-boundary
-  if (d->NodeCommMap().empty())        // in serial we are done
-    comnodalExtrema_complete();
-  else  // send nodal extrema to chare-boundary nodes to fellow chares
-  {
-    for (const auto& [c,n] : d->NodeCommMap()) {
-      std::vector< std::vector< tk::real > > g1( n.size() ), g2( n.size() );
-      std::size_t j = 0;
-      for (auto i : n)
-      {
-        auto p = tk::cref_find(d->Bid(),i);
-        g1[ j   ] = m_uNodalExtrm[ p ];
-        g2[ j++ ] = m_pNodalExtrm[ p ];
-      }
-      thisProxy[c].comnodalExtrema( std::vector<std::size_t>(begin(n),end(n)),
-        g1, g2 );
-    }
-  }
-  ownnodalExtrema_complete();
-}
-
-void
-DG::comnodalExtrema( const std::vector< std::size_t >& gid,
-                     const std::vector< std::vector< tk::real > >& G1,
-                     const std::vector< std::vector< tk::real > >& G2 )
-// *****************************************************************************
-//  Receive contributions to nodal extrema on chare-boundaries
-//! \param[in] gid Global mesh node IDs at which we receive grad contributions
-//! \param[in] G1 Partial contributions of extrema for conservative variables to
-//!   chare-boundary nodes
-//! \param[in] G2 Partial contributions of extrema for primitive variables to
-//!   chare-boundary nodes
-//! \details This function receives contributions to m_uNodalExtrm/m_pNodalExtrm
-//!   , which stores nodal extrems at mesh chare-boundary nodes. While
-//!   m_uNodalExtrm/m_pNodalExtrm stores own contributions, m_uNodalExtrmc
-//!   /m_pNodalExtrmc collects the neighbor chare contributions during
-//!   communication.
-// *****************************************************************************
-{
-  Assert( G1.size() == gid.size(), "Size mismatch" );
-  Assert( G2.size() == gid.size(), "Size mismatch" );
-
-  const auto rdof = g_inputdeck.get< tag::rdof >();
-  const auto ncomp = m_u.nprop() / rdof;
-  const auto nprim = m_p.nprop() / rdof;
-
-  for (std::size_t i=0; i<gid.size(); ++i)
-  {
-    auto& u = m_uNodalExtrmc[gid[i]];
-    auto& p = m_pNodalExtrmc[gid[i]];
-    for (std::size_t c=0; c<ncomp; ++c)
-    {
-      for(std::size_t idof=0; idof<m_ndof_NodalExtrm; idof++)
-      {
-        auto max_mark = 2*c*m_ndof_NodalExtrm + 2*idof;
-        auto min_mark = max_mark + 1;
-        u[max_mark] = std::max( G1[i][max_mark], u[max_mark] );
-        u[min_mark] = std::min( G1[i][min_mark], u[min_mark] );
-      }
-    }
-    for (std::size_t c=0; c<nprim; ++c)
-    {
-      for(std::size_t idof=0; idof<m_ndof_NodalExtrm; idof++)
-      {
-        auto max_mark = 2*c*m_ndof_NodalExtrm + 2*idof;
-        auto min_mark = max_mark + 1;
-        p[max_mark] = std::max( G2[i][max_mark], p[max_mark] );
-        p[min_mark] = std::min( G2[i][min_mark], p[min_mark] );
-      }
-    }
-  }
-
-  if (++m_nnodalExtrema == Disc()->NodeCommMap().size())
-  {
-    m_nnodalExtrema = 0;
-    comnodalExtrema_complete();
-  }
-}
-
-void DG::resizeNodalExtremac()
-// *****************************************************************************
-//  Resize the buffer vector of nodal extrema
-// *****************************************************************************
-{
-  const auto rdof = g_inputdeck.get< tag::rdof >();
-  const auto ncomp = m_u.nprop() / rdof;
-  const auto nprim = m_p.nprop() / rdof;
-
-  auto large = std::numeric_limits< tk::real >::max();
-  for (const auto& [c,n] : Disc()->NodeCommMap())
-  {
-    for (auto i : n) {
-      auto& u = m_uNodalExtrmc[i];
-      auto& p = m_pNodalExtrmc[i];
-      u.resize( 2*m_ndof_NodalExtrm*ncomp, large );
-      p.resize( 2*m_ndof_NodalExtrm*nprim, large );
-
-      // Initialize the minimum nodal extrema
-      for(std::size_t idof=0; idof<m_ndof_NodalExtrm; idof++)
-      {
-        for(std::size_t k = 0; k < ncomp; k++)
-          u[2*k*m_ndof_NodalExtrm+2*idof] = -large;
-        for(std::size_t k = 0; k < nprim; k++)
-          p[2*k*m_ndof_NodalExtrm+2*idof] = -large;
-      }
-    }
-  }
-}
-
-void DG::evalNodalExtrmRefEl(
-  const std::size_t ncomp,
-  const std::size_t nprim,
-  const std::size_t ndof_NodalExtrm,
-  const std::vector< std::size_t >& bndel,
-  const std::vector< std::size_t >& inpoel,
-  const std::vector< std::size_t >& gid,
-  const std::unordered_map< std::size_t, std::size_t >& bid,
-  const tk::Fields& U,
-  const tk::Fields& P,
-  std::vector< std::vector<tk::real> >& uNodalExtrm,
-  std::vector< std::vector<tk::real> >& pNodalExtrm )
-// *****************************************************************************
-//  Compute the nodal extrema of ref el derivatives for chare-boundary nodes
-//! \param[in] ncomp Number of conservative variables
-//! \param[in] nprim Number of primitive variables
-//! \param[in] ndof_NodalExtrm Degree of freedom for nodal extrema
-//! \param[in] bndel List of elements contributing to chare-boundary nodes
-//! \param[in] inpoel Element-node connectivity for element e
-//! \param[in] gid Local->global node id map
-//! \param[in] bid Local chare-boundary node ids (value) associated to
-//!   global node ids (key)
-//! \param[in] U Vector of conservative variables
-//! \param[in] P Vector of primitive variables
-//! \param[in,out] uNodalExtrm Chare-boundary nodal extrema for conservative
-//!   variables
-//! \param[in,out] pNodalExtrm Chare-boundary nodal extrema for primitive
-//!   variables
-// *****************************************************************************
-{
-  const auto rdof = g_inputdeck.get< tag::rdof >();
-
-  for (auto e : bndel)
-  {
-    // access node IDs
-    const std::vector<std::size_t> N
-      { inpoel[e*4+0], inpoel[e*4+1], inpoel[e*4+2], inpoel[e*4+3] };
-
-    // Loop over nodes of element e
-    for(std::size_t ip=0; ip<4; ++ip)
-    {
-      auto i = bid.find( gid[N[ip]] );
-      if (i != end(bid))      // If ip is the chare boundary point
-      {
-        // If DG(P2) is applied, find the nodal extrema of the gradients of
-        // conservative/primitive variables in the reference element
-
-        // Vector used to store the first order derivatives for both
-        // conservative and primitive variables
-        std::vector< std::array< tk::real, 3 > > gradc(ncomp, {0.0, 0.0, 0.0});
-        std::vector< std::array< tk::real, 3 > > gradp(ncomp, {0.0, 0.0, 0.0});
-
-        // Derivatives of the Dubiner basis
-        std::array< tk::real, 3 > center {{0.25, 0.25, 0.25}};
-        auto dBdxi = tk::eval_dBdxi(rdof, center);
-
-        // Evaluate the first order derivative
-        for(std::size_t icomp = 0; icomp < ncomp; icomp++)
-        {
-          auto mark = icomp * rdof;
-          for(std::size_t idir = 0; idir < 3; idir++)
-          {
-            gradc[icomp][idir] = 0;
-            for(std::size_t idof = 1; idof < rdof; idof++)
-              gradc[icomp][idir] += U(e, mark+idof) * dBdxi[idir][idof];
-          }
-        }
-        for(std::size_t icomp = 0; icomp < nprim; icomp++)
-        {
-          auto mark = icomp * rdof;
-          for(std::size_t idir = 0; idir < 3; idir++)
-          {
-            gradp[icomp][idir] = 0;
-            for(std::size_t idof = 1; idof < rdof; idof++)
-              gradp[icomp][idir] += P(e, mark+idof) * dBdxi[idir][idof];
-          }
-        }
-
-        // Store the extrema for the gradients
-        for (std::size_t c=0; c<ncomp; ++c)
-        {
-          for (std::size_t idof = 0; idof < ndof_NodalExtrm; idof++)
-          {
-            auto max_mark = 2*c*m_ndof_NodalExtrm + 2*idof;
-            auto min_mark = max_mark + 1;
-            auto& ex = uNodalExtrm[i->second];
-            ex[max_mark] = std::max(ex[max_mark], gradc[c][idof]);
-            ex[min_mark] = std::min(ex[min_mark], gradc[c][idof]);
-          }
-        }
-        for (std::size_t c=0; c<nprim; ++c)
-        {
-          for (std::size_t idof = 0; idof < ndof_NodalExtrm; idof++)
-          {
-            auto max_mark = 2*c*m_ndof_NodalExtrm + 2*idof;
-            auto min_mark = max_mark + 1;
-            auto& ex = pNodalExtrm[i->second];
-            ex[max_mark] = std::max(ex[max_mark], gradp[c][idof]);
-            ex[min_mark] = std::min(ex[min_mark], gradp[c][idof]);
-          }
-        }
-      }
-    }
-  }
-}
-
-void
-DG::lim()
-// *****************************************************************************
-// Compute limiter function
-// *****************************************************************************
-{
-  auto d = Disc();
-  const auto rdof = g_inputdeck.get< tag::rdof >();
-  const auto ncomp = m_u.nprop() / rdof;
-  const auto nprim = m_p.nprop() / rdof;
-
-  // Combine own and communicated contributions to nodal extrema
-  for (const auto& [gid,g] : m_uNodalExtrmc) {
-    auto bid = tk::cref_find( d->Bid(), gid );
-    for (ncomp_t c=0; c<ncomp; ++c)
-    {
-      for(std::size_t idof=0; idof<m_ndof_NodalExtrm; idof++)
-      {
-        auto max_mark = 2*c*m_ndof_NodalExtrm + 2*idof;
-        auto min_mark = max_mark + 1;
-        m_uNodalExtrm[bid][max_mark] =
-          std::max(g[max_mark], m_uNodalExtrm[bid][max_mark]);
-        m_uNodalExtrm[bid][min_mark] =
-          std::min(g[min_mark], m_uNodalExtrm[bid][min_mark]);
-      }
-    }
-  }
-  for (const auto& [gid,g] : m_pNodalExtrmc) {
-    auto bid = tk::cref_find( d->Bid(), gid );
-    for (ncomp_t c=0; c<nprim; ++c)
-    {
-      for(std::size_t idof=0; idof<m_ndof_NodalExtrm; idof++)
-      {
-        auto max_mark = 2*c*m_ndof_NodalExtrm + 2*idof;
-        auto min_mark = max_mark + 1;
-        m_pNodalExtrm[bid][max_mark] =
-          std::max(g[max_mark], m_pNodalExtrm[bid][max_mark]);
-        m_pNodalExtrm[bid][min_mark] =
-          std::min(g[min_mark], m_pNodalExtrm[bid][min_mark]);
-      }
-    }
-  }
-
-  // clear gradients receive buffer
-  tk::destroy(m_uNodalExtrmc);
-  tk::destroy(m_pNodalExtrmc);
-
-  if (rdof > 1) {
-    g_dgpde[d->MeshId()].limit( d->T(), myGhosts()->m_geoFace, myGhosts()->m_geoElem,
-              myGhosts()->m_fd, myGhosts()->m_esup, myGhosts()->m_inpoel,
-              myGhosts()->m_coord, m_ndof, d->Gid(), d->Bid(), m_uNodalExtrm,
-              m_pNodalExtrm, m_mtInv, m_u, m_p, m_shockmarker );
-
-    if (g_inputdeck.get< tag::limsol_projection >())
-      g_dgpde[d->MeshId()].CPL(m_p, myGhosts()->m_geoElem,
-        myGhosts()->m_inpoel, myGhosts()->m_coord, m_u,
-        myGhosts()->m_fd.Esuel().size()/4);
-  }
-
-  // Send limited solution to neighboring chares
-  if (myGhosts()->m_sendGhost.empty())
-    comlim_complete();
-  else
-    for(const auto& [cid, ghostdata] : myGhosts()->m_sendGhost) {
-      std::vector< std::size_t > tetid( ghostdata.size() );
-      std::vector< std::vector< tk::real > > u( ghostdata.size() ),
-                                             prim( ghostdata.size() );
-      std::vector< std::size_t > ndof;<--- Unused variable: ndof
-      std::size_t j = 0;
-      for(const auto& i : ghostdata) {
-        Assert( i < myGhosts()->m_fd.Esuel().size()/4,
-          "Sending limiter ghost data" );
-        tetid[j] = i;
-        u[j] = m_u[i];
-        prim[j] = m_p[i];
-        ++j;
-      }
-      thisProxy[ cid ].comlim( thisIndex, tetid, u, prim );
-    }
-
-  ownlim_complete();
-}
-
-void
-DG::refine_ndof()
-// *****************************************************************************
-//  p-refine all elements that are adjacent to p-refined elements
-//! \details This function p-refines all the neighbors of an element that has
-//!   been p-refined as a result of an error indicator.
-// *****************************************************************************
-{
-  auto d = Disc();
-  const auto& inpoel = d->Inpoel();
-  const auto npoin = d->Coord()[0].size();
-  const auto nelem = myGhosts()->m_fd.Esuel().size()/4;
-  std::vector<std::size_t> node_ndof(npoin, 1);
-
-  // Mark the max ndof for each node and store in node_ndof
-  for(std::size_t ip=0; ip<npoin; ip++)
-  {
-    const auto& pesup = tk::cref_find(myGhosts()->m_esup, ip);
-    for(auto er : pesup)
-      node_ndof[ip] = std::max(m_ndof[er], node_ndof[ip]);
-  }
-
-  for(std::size_t e = 0; e < nelem; e++)
-  {
-    // Find if any node of this element has p1/p2 ndofs
-    std::size_t counter_p2(0);
-    std::size_t counter_p1(0);
-    for(std::size_t inode = 0; inode < 4; inode++)
-    {
-      auto node = inpoel[4*e+inode];
-      if(node_ndof[node] == 10)
-        counter_p2++;
-      else if (node_ndof[node] == 4)
-        counter_p1++;
-    }
-
-    // If there is at least one node with p1/p2 ndofs, all of the elements
-    // around this node are refined to p1/p2.
-    if(counter_p2 > 0 && m_ndof[e] < 10)
-    {
-      if(m_ndof[e] == 4)
-        m_ndof[e] = 10;
-      if(m_ndof[e] == 1)
-        m_ndof[e] = 4;
-    }
-    else if(counter_p1 > 0 && m_ndof[e] < 4)
-      m_ndof[e] = 4;
-  }
-}
-
-void DG::smooth_ndof()
-// *****************************************************************************
-//  Smooth the refined ndof distribution to avoid zigzag refinement
-// *****************************************************************************
-{
-  auto d = Disc();
-  const auto& inpoel = d->Inpoel();
-  const auto npoin = d->Coord()[0].size();
-  const auto nelem = myGhosts()->m_fd.Esuel().size()/4;
-  std::vector<std::size_t> node_ndof(npoin, 1);
-
-  // Mark the max ndof for each node and store in node_ndof
-  for(std::size_t ip=0; ip<npoin; ip++)
-  {
-    const auto& pesup = tk::cref_find(myGhosts()->m_esup, ip);
-    for(auto er : pesup)
-      node_ndof[ip] = std::max(m_ndof[er], node_ndof[ip]);
-  }
-
-  for(std::size_t e = 0; e < nelem; e++)
-  {
-    // Find if any node of this element has p1/p2 ndofs
-    std::size_t counter_p2(0);
-    std::size_t counter_p1(0);
-    for(std::size_t inode = 0; inode < 4; inode++)
-    {
-      auto node = inpoel[4*e+inode];
-      if(node_ndof[node] == 10)
-        counter_p2++;
-      else if (node_ndof[node] == 4)
-        counter_p1++;
-    }
-
-    // If all the nodes in the element are p1/p2, this element is refined to
-    // p1/p2.
-    if(counter_p2 == 4 && m_ndof[e] == 4)
-      m_ndof[e] = 10;
-    else if(counter_p1 == 4 && m_ndof[e] == 1)
-      m_ndof[e] = 4;
-  }
-}
-
-void
-DG::comlim( int fromch,
-            const std::vector< std::size_t >& tetid,
-            const std::vector< std::vector< tk::real > >& u,
-            const std::vector< std::vector< tk::real > >& prim )
-// *****************************************************************************
-//  Receive chare-boundary limiter ghost data from neighboring chares
-//! \param[in] fromch Sender chare id
-//! \param[in] tetid Ghost tet ids we receive solution data for
-//! \param[in] u Limited high-order solution
-//! \param[in] prim Limited high-order primitive quantities
-//! \details This function receives contributions to the limited solution from
-//!   fellow chares.
-// *****************************************************************************
-{
-  Assert( u.size() == tetid.size(), "Size mismatch in DG::comlim()" );
-  Assert( prim.size() == tetid.size(), "Size mismatch in DG::comlim()" );
-
-  // Find local-to-ghost tet id map for sender chare
-  const auto& n = tk::cref_find( myGhosts()->m_ghost, fromch );
-
-  for (std::size_t i=0; i<tetid.size(); ++i) {
-    auto j = tk::cref_find( n, tetid[i] );
-    Assert( j >= myGhosts()->m_fd.Esuel().size()/4,
-      "Receiving solution non-ghost data" );
-    auto b = tk::cref_find( myGhosts()->m_bid, j );
-    Assert( b < m_uc[2].size(), "Indexing out of bounds" );
-    Assert( b < m_pc[2].size(), "Indexing out of bounds" );
-    m_uc[2][b] = u[i];
-    m_pc[2][b] = prim[i];
-  }
-
-  // if we have received all solution ghost contributions from neighboring
-  // chares (chares we communicate along chare-boundary faces with), and
-  // contributed our solution to these neighbors, proceed to limiting
-  if (++m_nlim == myGhosts()->m_sendGhost.size()) {
-    m_nlim = 0;
-    comlim_complete();
-  }
-}
-
-void
-DG::dt()
-// *****************************************************************************
-// Compute time step size
-// *****************************************************************************
-{
-  auto d = Disc();
-
-  // Combine own and communicated contributions of limited solution and degrees
-  // of freedom in cells (if p-adaptive)
-  for (const auto& b : myGhosts()->m_bid) {
-    Assert( m_uc[2][b.second].size() == m_u.nprop(), "ncomp size mismatch" );
-    Assert( m_pc[2][b.second].size() == m_p.nprop(), "ncomp size mismatch" );
-    for (std::size_t c=0; c<m_u.nprop(); ++c) {
-      m_u(b.first,c) = m_uc[2][b.second][c];
-    }
-    for (std::size_t c=0; c<m_p.nprop(); ++c) {
-      m_p(b.first,c) = m_pc[2][b.second][c];
-    }
-  }
-
-  auto mindt = std::numeric_limits< tk::real >::max();
-
-  if (m_stage == 0)
-  {
-    auto const_dt = g_inputdeck.get< tag::dt >();
-    auto eps = std::numeric_limits< tk::real >::epsilon();
-
-    // use constant dt if configured
-    if (std::abs(const_dt) > eps) {
-
-      mindt = const_dt;
-
-    } else {      // compute dt based on CFL
-
-      // find the minimum dt across all PDEs integrated
-      auto eqdt =
-        g_dgpde[d->MeshId()].dt( myGhosts()->m_coord, myGhosts()->m_inpoel,
-          myGhosts()->m_fd,
-          myGhosts()->m_geoFace, myGhosts()->m_geoElem, m_ndof, m_u, m_p,
-          myGhosts()->m_fd.Esuel().size()/4 );
-      if (eqdt < mindt) mindt = eqdt;
-
-      mindt *= g_inputdeck.get< tag::cfl >();
-    }
-  }
-  else
-  {
-    mindt = d->Dt();
-  }
-
-  // Resize the buffer vector of nodal extrema
-  resizeNodalExtremac();
-
-  // Contribute to minimum dt across all chares then advance to next step
-  contribute( sizeof(tk::real), &mindt, CkReduction::min_double,
-              CkCallback(CkReductionTarget(DG,solve), thisProxy) );
-}
-
-void
-DG::solve( tk::real newdt )
-// *****************************************************************************
-// Compute right-hand side of discrete transport equations
-//! \param[in] newdt Size of this new time step
-// *****************************************************************************
-{
-  // Enable SDAG wait for building the solution vector during the next stage
-  thisProxy[ thisIndex ].wait4sol();
-  thisProxy[ thisIndex ].wait4refine();
-  thisProxy[ thisIndex ].wait4smooth();
-  thisProxy[ thisIndex ].wait4reco();
-  thisProxy[ thisIndex ].wait4nodalExtrema();
-  thisProxy[ thisIndex ].wait4lim();
-  thisProxy[ thisIndex ].wait4nod();
-
-  auto d = Disc();
-  const auto rdof = g_inputdeck.get< tag::rdof >();
-  const auto ndof = g_inputdeck.get< tag::ndof >();
-  const auto neq = m_u.nprop()/rdof;
-
-  // Set new time step size
-  if (m_stage == 0) d->setdt( newdt );
-
-  const auto pref = g_inputdeck.get< tag::pref, tag::pref >();
-  if (pref && m_stage == 0)
-  {
-    // When the element are coarsened, high order terms should be zero
-    for(std::size_t e = 0; e < myGhosts()->m_nunk; e++)
-    {
-      const auto ncomp= m_u.nprop()/rdof;
-      if(m_ndof[e] == 1)
-      {
-        for (std::size_t c=0; c<ncomp; ++c)
-        {
-          auto mark = c*rdof;
-          m_u(e, mark+1) = 0.0;
-          m_u(e, mark+2) = 0.0;
-          m_u(e, mark+3) = 0.0;
-        }
-      } else if(m_ndof[e] == 4)
-      {
-        for (std::size_t c=0; c<ncomp; ++c)
-        {
-          auto mark = c*ndof;
-          m_u(e, mark+4) = 0.0;
-          m_u(e, mark+5) = 0.0;
-          m_u(e, mark+6) = 0.0;
-          m_u(e, mark+7) = 0.0;
-          m_u(e, mark+8) = 0.0;
-          m_u(e, mark+9) = 0.0;
-        }
-      }
-    }
-  }
-
-  // Update Un
-  if (m_stage == 0) m_un = m_u;
-
-  // Explicit or IMEX
-  const auto imex_runge_kutta = g_inputdeck.get< tag::imex_runge_kutta >();
-
-  // physical time at time-stage for computing exact source terms
-  tk::real physT(d->T());
-  if (m_stage == 1) {
-    physT += d->Dt();
-  }
-  else if (m_stage == 2) {
-    physT += 0.5*d->Dt();
-  }
-
-  if (imex_runge_kutta) {
-    if (m_stage == 0)
-    {
-      // Save previous rhs
-      m_rhsprev = m_rhs;
-      // Initialize m_stiffrhs to zero
-      m_stiffrhs.fill(0.0);
-      m_stiffrhsprev.fill(0.0);
-    }
-  }
-
-  g_dgpde[d->MeshId()].rhs( physT, myGhosts()->m_geoFace, myGhosts()->m_geoElem,
-    myGhosts()->m_fd, myGhosts()->m_inpoel, m_boxelems, myGhosts()->m_coord,
-    m_u, m_p, m_ndof, m_rho0mat, d->Dt(), m_rhs );
-
-  if (!imex_runge_kutta) {
-    // Explicit time-stepping using RK3 to discretize time-derivative
-    for(std::size_t e=0; e<myGhosts()->m_nunk; ++e)
-      for(std::size_t c=0; c<neq; ++c)
-      {
-        for (std::size_t k=0; k<m_numEqDof[c]; ++k)
-        {
-          auto rmark = c*rdof+k;
-          auto mark = c*ndof+k;
-          m_u(e, rmark) =  rkcoef[0][m_stage] * m_un(e, rmark)
-            + rkcoef[1][m_stage] * ( m_u(e, rmark)
-              + d->Dt() * m_rhs(e, mark)/m_lhs(e, mark) );
-          if(fabs(m_u(e, rmark)) < 1e-16)
-            m_u(e, rmark) = 0;
-        }
-      }
-  }
-  else {
-    // Implicit-Explicit time-stepping using RK3 to discretize time-derivative
-    DG::imex_integrate();
-  }
-
-  for(std::size_t e=0; e<myGhosts()->m_nunk; ++e)
-    for(std::size_t c=0; c<neq; ++c)
-    {
-      // zero out unused/reconstructed dofs of equations using reduced dofs
-      // (see DGMultiMat::numEquationDofs())
-      if (m_numEqDof[c] < rdof) {
-        for (std::size_t k=m_numEqDof[c]; k<rdof; ++k)
-        {
-          auto rmark = c*rdof+k;
-          m_u(e, rmark) = 0.0;
-        }
-      }
-    }
-
-  // Update primitives based on the evolved solution
-  g_dgpde[d->MeshId()].updateInterfaceCells( m_u,
-    myGhosts()->m_fd.Esuel().size()/4, m_ndof );
-  g_dgpde[d->MeshId()].updatePrimitives( m_u, m_lhs, myGhosts()->m_geoElem, m_p,
-    myGhosts()->m_fd.Esuel().size()/4 );
-  if (!g_inputdeck.get< tag::accuracy_test >()) {
-    g_dgpde[d->MeshId()].cleanTraceMaterial( physT, myGhosts()->m_geoElem, m_u,
-      m_p, myGhosts()->m_fd.Esuel().size()/4 );
-  }
-
-  if (m_stage < 2) {
-
-    // continue with next time step stage
-    stage();
-
-  } else {
-
-    // Increase number of iterations and physical time
-    d->next();
-
-    // Compute diagnostics, e.g., residuals
-    auto diag_computed = m_diag.compute( *d,
-      m_u.nunk()-myGhosts()->m_fd.Esuel().size()/4, myGhosts()->m_geoElem,
-      m_ndof, m_u, m_un );
-
-    // Continue to mesh refinement (if configured)
-    if (!diag_computed) refine( std::vector< tk::real >( m_u.nprop(), 0.0 ) );
-
-  }
-}
-
-void
-DG::refine( [[maybe_unused]] const std::vector< tk::real >& l2res )
-// *****************************************************************************
-// Optionally refine/derefine mesh
-//! \param[in] l2res L2-norms of the residual for each scalar component
-//!   computed across the whole problem
-// *****************************************************************************
-{
-  auto d = Disc();
-
-  auto dtref = g_inputdeck.get< tag::amr, tag::dtref >();
-  auto dtfreq = g_inputdeck.get< tag::amr, tag::dtfreq >();
-
-  // if t>0 refinement enabled and we hit the dtref frequency
-  if (dtref && !(d->It() % dtfreq)) {   // refine
-
-    d->startvol();
-    d->Ref()->dtref( myGhosts()->m_fd.Bface(), {},
-      tk::remap(myGhosts()->m_fd.Triinpoel(),d->Gid()) );
-    d->refined() = 1;
-
-  } else {      // do not refine
-
-    d->refined() = 0;
-    stage();
-
-  }
-}
-
-void
-DG::resizePostAMR(
-  const std::vector< std::size_t >& /*ginpoel*/,
-  const tk::UnsMesh::Chunk& chunk,
-  const tk::UnsMesh::Coords& coord,
-  const std::unordered_map< std::size_t, tk::UnsMesh::Edge >& /*addedNodes*/,
-  const std::unordered_map< std::size_t, std::size_t >& addedTets,
-  const std::set< std::size_t >& removedNodes,
-  const std::unordered_map< std::size_t, std::size_t >& amrNodeMap,
-  const tk::NodeCommMap& nodeCommMap,
-  const std::map< int, std::vector< std::size_t > >& bface,
-  const std::map< int, std::vector< std::size_t > >& /* bnode */,
-  const std::vector< std::size_t >& triinpoel,
-  const std::unordered_map< std::size_t, std::set< std::size_t > >& elemblockid )
-// *****************************************************************************
-//  Receive new mesh from Refiner
-//! \param[in] chunk New mesh chunk (connectivity and global<->local id maps)
-//! \param[in] coord New mesh node coordinates
-//! \param[in] addedTets Newly added mesh cells and their parents (local ids)
-//! \param[in] removedNodes Newly removed mesh node local ids
-//! \param[in] amrNodeMap Node id map after amr (local ids)
-//! \param[in] nodeCommMap New node communication map
-//! \param[in] bface Boundary-faces mapped to side set ids
-//! \param[in] triinpoel Boundary-face connectivity
-//! \param[in] elemblockid Local tet ids associated with mesh block ids
-// *****************************************************************************
-{
-  auto d = Disc();
-
-  // Set flag that indicates that we are during time stepping
-  m_initial = 0;
-  myGhosts()->m_initial = 0;
-
-  // Zero field output iteration count between two mesh refinement steps
-  d->Itf() = 0;
-
-  // Increase number of iterations with mesh refinement
-  ++d->Itr();
-
-  // Save old number of elements
-  [[maybe_unused]] auto old_nelem = myGhosts()->m_inpoel.size()/4;
-
-  // Resize mesh data structures
-  d->resizePostAMR( chunk, coord, amrNodeMap, nodeCommMap, removedNodes,
-    elemblockid );
-
-  // Update state
-  myGhosts()->m_inpoel = d->Inpoel();
-  myGhosts()->m_coord = d->Coord();
-  auto nelem = myGhosts()->m_inpoel.size()/4;
-  m_p.resize( nelem );
-  m_u.resize( nelem );
-  m_un.resize( nelem );
-  m_lhs.resize( nelem );
-  m_rhs.resize( nelem );
-  m_rhsprev.resize( nelem );
-  m_stiffrhs.resize( nelem );
-  m_stiffrhsprev.resize( nelem );
-  m_uNodalExtrm.resize( Disc()->Bid().size(), std::vector<tk::real>( 2*
-    m_ndof_NodalExtrm*g_inputdeck.get< tag::ncomp >() ) );
-  m_pNodalExtrm.resize( Disc()->Bid().size(), std::vector<tk::real>( 2*
-    m_ndof_NodalExtrm*m_p.nprop()/g_inputdeck.get< tag::rdof >()));
-
-  // Resize the buffer vector of nodal extrema
-  resizeNodalExtremac();
-
-  myGhosts()->m_fd = FaceData( myGhosts()->m_inpoel, bface,
-    tk::remap(triinpoel,d->Lid()) );
-
-  myGhosts()->m_geoFace =
-    tk::Fields( tk::genGeoFaceTri( myGhosts()->m_fd.Nipfac(),
-    myGhosts()->m_fd.Inpofa(), coord ) );
-  myGhosts()->m_geoElem = tk::Fields( tk::genGeoElemTet( myGhosts()->m_inpoel,
-    coord ) );
-
-  myGhosts()->m_nfac = myGhosts()->m_fd.Inpofa().size()/3;
-  myGhosts()->m_nunk = nelem;
-  m_npoin = coord[0].size();
-  myGhosts()->m_bndFace.clear();
-  myGhosts()->m_exptGhost.clear();
-  myGhosts()->m_sendGhost.clear();
-  myGhosts()->m_ghost.clear();
-  myGhosts()->m_esup.clear();
-
-  // Update solution on new mesh, P0 (cell center value) only for now
-  m_un = m_u;
-  auto pn = m_p;<--- Variable 'pn' is assigned a value that is never used.
-  auto unprop = m_u.nprop();<--- Variable 'unprop' is assigned a value that is never used.
-  auto pnprop = m_p.nprop();<--- Variable 'pnprop' is assigned a value that is never used.
-  for (const auto& [child,parent] : addedTets) {
-    Assert( child < nelem, "Indexing out of new solution vector" );
-    Assert( parent < old_nelem, "Indexing out of old solution vector" );
-    for (std::size_t i=0; i<unprop; ++i) m_u(child,i) = m_un(parent,i);
-    for (std::size_t i=0; i<pnprop; ++i) m_p(child,i) = pn(parent,i);
-  }
-  m_un = m_u;
-
-  // Resize communication buffers
-  m_ghosts[thisIndex].resizeComm();
-}
-
-bool
-DG::fieldOutput() const
-// *****************************************************************************
-// Decide wether to output field data
-//! \return True if field data is output in this step
-// *****************************************************************************
-{
-  auto d = Disc();
-
-  // Output field data
-  return d->fielditer() or d->fieldtime() or d->fieldrange() or d->finished();
-}
-
-bool
-DG::refinedOutput() const
-// *****************************************************************************
-// Decide if we write field output using a refined mesh
-//! \return True if field output will use a refined mesh
-// *****************************************************************************
-{
-  return g_inputdeck.get< tag::field_output, tag::refined >() &&
-         g_inputdeck.get< tag::scheme >() != ctr::SchemeType::DG;
-}
-
-void
-DG::writeFields(
-  CkCallback c,
-  const std::unordered_map< std::size_t, std::size_t >& addedTets )
-// *****************************************************************************
-// Output mesh field data
-//! \param[in] c Function to continue with after the write
-//! \param[in] addedTets Newly added mesh cells and their parents (local ids)
-// *****************************************************************************
-{
-  auto d = Disc();
-
-  const auto& inpoel = std::get< 0 >( m_outmesh.chunk );
-  auto esup = tk::genEsup( inpoel, 4 );
-  auto nelem = inpoel.size() / 4;
-
-  // Combine own and communicated contributions and finish averaging of node
-  // field output in chare boundary nodes
-  const auto& lid = std::get< 2 >( m_outmesh.chunk );
-  for (const auto& [g,f] : m_uNodefieldsc) {
-    Assert( m_uNodefields.nprop() == f.first.size(), "Size mismatch" );
-    auto p = tk::cref_find( lid, g );
-    for (std::size_t i=0; i<f.first.size(); ++i) {
-      m_uNodefields(p,i) += f.first[i];
-      m_uNodefields(p,i) /= static_cast< tk::real >(
-                              esup.second[p+1] - esup.second[p] + f.second );
-    }
-  }
-  tk::destroy( m_uNodefieldsc );
-  for (const auto& [g,f] : m_pNodefieldsc) {
-    Assert( m_pNodefields.nprop() == f.first.size(), "Size mismatch" );
-    auto p = tk::cref_find( lid, g );
-    for (std::size_t i=0; i<f.first.size(); ++i) {
-      m_pNodefields(p,i) += f.first[i];
-      m_pNodefields(p,i) /= static_cast< tk::real >(
-                              esup.second[p+1] - esup.second[p] + f.second );
-    }
-  }
-  tk::destroy( m_pNodefieldsc );
-
-  // Lambda to decide if a node (global id) is on a chare boundary of the field
-  // output mesh. p - global node id, return true if node is on the chare
-  // boundary.
-  auto chbnd = [ this ]( std::size_t p ) {
-    return
-      std::any_of( m_outmesh.nodeCommMap.cbegin(), m_outmesh.nodeCommMap.cend(),
-        [&](const auto& s) { return s.second.find(p) != s.second.cend(); } );
-  };
-
-  // Finish computing node field output averages in internal nodes
-  auto npoin = m_outmesh.coord[0].size();
-  auto& gid = std::get< 1 >( m_outmesh.chunk );
-  for (std::size_t p=0; p<npoin; ++p) {
-    if (!chbnd(gid[p])) {
-      auto n = static_cast< tk::real >( esup.second[p+1] - esup.second[p] );
-      for (std::size_t i=0; i<m_uNodefields.nprop(); ++i)
-        m_uNodefields(p,i) /= n;
-      for (std::size_t i=0; i<m_pNodefields.nprop(); ++i)
-        m_pNodefields(p,i) /= n;
-    }
-  }
-
-  // Collect field output from numerical solution requested by user
-  auto elemfields = numericFieldOutput( m_uElemfields, tk::Centering::ELEM,
-    g_dgpde[Disc()->MeshId()].OutVarFn(), m_pElemfields );
-  auto nodefields = numericFieldOutput( m_uNodefields, tk::Centering::NODE,
-    g_dgpde[Disc()->MeshId()].OutVarFn(), m_pNodefields );
-
-  // Collect field output from analytical solutions (if exist)
-  const auto& coord = m_outmesh.coord;
-  auto geoElem = tk::genGeoElemTet( inpoel, coord );
-  auto t = Disc()->T();
-  analyticFieldOutput( g_dgpde[d->MeshId()], tk::Centering::ELEM,
-    geoElem.extract_comp(1), geoElem.extract_comp(2), geoElem.extract_comp(3),
-    t, elemfields );
-  analyticFieldOutput( g_dgpde[d->MeshId()], tk::Centering::NODE, coord[0],
-    coord[1], coord[2], t, nodefields );
-
-  // Add adaptive indicator array to element-centered field output
-  if (g_inputdeck.get< tag::pref, tag::pref >()) {
-    std::vector< tk::real > ndof( begin(m_ndof), end(m_ndof) );
-    ndof.resize( nelem );
-    for (const auto& [child,parent] : addedTets)
-      ndof[child] = static_cast< tk::real >( m_ndof[parent] );
-    elemfields.push_back( ndof );
-  }
-
-  // Add shock detection marker array to element-centered field output
-  std::vector< tk::real > shockmarker( begin(m_shockmarker), end(m_shockmarker) );
-  // Here m_shockmarker has a size of m_u.nunk() which is the number of the
-  // elements within this partition (nelem) plus the ghost partition cells. In
-  // terms of output purpose, we only need the solution data within this
-  // partition. Therefore, resizing it to nelem removes the extra partition
-  // boundary allocations in the shockmarker vector. Since the code assumes that
-  // the boundary elements are on the top, the resize operation keeps the lower
-  // portion.
-  shockmarker.resize( nelem );
-  for (const auto& [child,parent] : addedTets)
-    shockmarker[child] = static_cast< tk::real >(m_shockmarker[parent]);
-  elemfields.push_back( shockmarker );
-
-  // Add rho0*det(g)/rho to make sure it is staying close to 1,
-  // averaged for all materials
-  std::vector< tk::real > densityConstr(nelem);
-  g_dgpde[d->MeshId()].computeDensityConstr(nelem, m_u, m_rho0mat,
-                                            densityConstr);
-  for (const auto& [child,parent] : addedTets)
-    densityConstr[child] = 0.0;
-  if (densityConstr.size() > 0) elemfields.push_back( densityConstr );
-
-  // Query fields names requested by user
-  auto elemfieldnames = numericFieldNames( tk::Centering::ELEM );
-  auto nodefieldnames = numericFieldNames( tk::Centering::NODE );
-
-  // Collect field output names for analytical solutions
-  analyticFieldNames( g_dgpde[d->MeshId()], tk::Centering::ELEM, elemfieldnames );
-  analyticFieldNames( g_dgpde[d->MeshId()], tk::Centering::NODE, nodefieldnames );
-
-  if (g_inputdeck.get< tag::pref, tag::pref >())
-    elemfieldnames.push_back( "NDOF" );
-
-  elemfieldnames.push_back( "shock_marker" );
-
-  if (densityConstr.size() > 0)
-    elemfieldnames.push_back( "density_constraint" );
-
-  Assert( elemfieldnames.size() == elemfields.size(), "Size mismatch" );
-  Assert( nodefieldnames.size() == nodefields.size(), "Size mismatch" );
-
-  // Output chare mesh and fields metadata to file
-  const auto& triinpoel = m_outmesh.triinpoel;
-  d->write( inpoel, m_outmesh.coord, m_outmesh.bface, {},
-            tk::remap( triinpoel, lid ), elemfieldnames, nodefieldnames,
-            {}, {}, elemfields, nodefields, {}, {}, c );
-}
-
-void
-DG::comnodeout( const std::vector< std::size_t >& gid,
-                const std::vector< std::size_t >& nesup,
-                const std::vector< std::vector< tk::real > >& Lu,
-                const std::vector< std::vector< tk::real > >& Lp )
-// *****************************************************************************
-//  Receive chare-boundary nodal solution (for field output) contributions from
-//  neighboring chares
-//! \param[in] gid Global mesh node IDs at which we receive contributions
-//! \param[in] nesup Number of elements surrounding points
-//! \param[in] Lu Partial contributions of solution nodal fields to
-//!   chare-boundary nodes
-//! \param[in] Lp Partial contributions of primitive quantity nodal fields to
-//!   chare-boundary nodes
-// *****************************************************************************
-{
-  Assert( gid.size() == nesup.size(), "Size mismatch" );
-  Assert(Lu.size() == m_uNodefields.nprop(), "Fields size mismatch");
-  Assert(Lp.size() == m_pNodefields.nprop(), "Fields size mismatch");
-  for (std::size_t f=0; f<Lu.size(); ++f)
-    Assert( gid.size() == Lu[f].size(), "Size mismatch" );
-  for (std::size_t f=0; f<Lp.size(); ++f)
-    Assert( gid.size() == Lp[f].size(), "Size mismatch" );
-
-  for (std::size_t i=0; i<gid.size(); ++i) {
-    auto& nfu = m_uNodefieldsc[ gid[i] ];
-    nfu.first.resize( Lu.size() );
-    for (std::size_t f=0; f<Lu.size(); ++f) nfu.first[f] += Lu[f][i];
-    nfu.second += nesup[i];
-    auto& nfp = m_pNodefieldsc[ gid[i] ];
-    nfp.first.resize( Lp.size() );
-    for (std::size_t f=0; f<Lp.size(); ++f) nfp.first[f] += Lp[f][i];
-    nfp.second += nesup[i];
-  }
-
-  // When we have heard from all chares we communicate with, this chare is done
-  if (++m_nnod == Disc()->NodeCommMap().size()) {
-    m_nnod = 0;
-    comnodeout_complete();
-  }
-}
-
-void
-DG::stage()
-// *****************************************************************************
-// Evaluate whether to continue with next time step stage
-// *****************************************************************************
-{
-  // Increment Runge-Kutta stage counter
-  ++m_stage;
-
-  // if not all Runge-Kutta stages complete, continue to next time stage,
-  // otherwise prepare for nodal field output
-  if (m_stage < 3)
-    next();
-  else
-    startFieldOutput( CkCallback(CkIndex_DG::step(), thisProxy[thisIndex]) );
-}
-
-void
-DG::evalLB( int nrestart )
-// *****************************************************************************
-// Evaluate whether to do load balancing
-//! \param[in] nrestart Number of times restarted
-// *****************************************************************************
-{
-  auto d = Disc();
-
-  // Detect if just returned from a checkpoint and if so, zero timers
-  d->restarted( nrestart );
-
-  const auto lbfreq = g_inputdeck.get< tag::cmd, tag::lbfreq >();
-  const auto nonblocking = g_inputdeck.get< tag::cmd, tag::nonblocking >();
-
-  // Load balancing if user frequency is reached or after the second time-step
-  if ( (d->It()) % lbfreq == 0 || d->It() == 2 ) {
-
-    AtSync();
-    if (nonblocking) next();
-
-  } else {
-
-    next();
-
-  }
-}
-
-void
-DG::evalRestart()
-// *****************************************************************************
-// Evaluate whether to save checkpoint/restart
-// *****************************************************************************
-{
-  auto d = Disc();
-
-  const auto rsfreq = g_inputdeck.get< tag::cmd, tag::rsfreq >();
-  const auto benchmark = g_inputdeck.get< tag::cmd, tag::benchmark >();
-
-  if (not benchmark and not (d->It() % rsfreq)) {
-
-    std::vector< std::size_t > meshdata{ /* finished = */ 0, d->MeshId() };
-    contribute( meshdata, CkReduction::nop,
-      CkCallback(CkReductionTarget(Transporter,checkpoint), d->Tr()) );
-
-  } else {
-
-    evalLB( /* nrestart = */ -1 );
-
-  }
-}
-
-void
-DG::step()
-// *****************************************************************************
-// Evaluate wether to continue with next time step
-// *****************************************************************************
-{
-  auto d = Disc();
-
-  // Output time history
-  if (d->histiter() or d->histtime() or d->histrange()) {
-    std::vector< std::vector< tk::real > > hist;
-    auto h = g_dgpde[d->MeshId()].histOutput( d->Hist(), myGhosts()->m_inpoel,
-      myGhosts()->m_coord, m_u, m_p );
-    hist.insert( end(hist), begin(h), end(h) );
-    d->history( std::move(hist) );
-  }
-
-  // Free memory storing output mesh
-  m_outmesh.destroy();
-
-  // Output one-liner status report to screen
-  d->status();
-  // Reset Runge-Kutta stage counter
-  m_stage = 0;
-
-  const auto term = g_inputdeck.get< tag::term >();
-  const auto nstep = g_inputdeck.get< tag::nstep >();
-  const auto eps = std::numeric_limits< tk::real >::epsilon();
-
-  // If neither max iterations nor max time reached, continue, otherwise finish
-  if (std::fabs(d->T()-term) > eps && d->It() < nstep) {
-
-    evalRestart();
- 
-  } else {
-
-    auto meshid = d->MeshId();
-    d->contribute( sizeof(std::size_t), &meshid, CkReduction::nop,
-                   CkCallback(CkReductionTarget(Transporter,finish), d->Tr()) );
-
-  }
-}
-
-void
-DG::imex_integrate()
-{
-  /*****************************************************************************
-  Performs the Implicit-Explicit Runge-Kutta step.
-
-  \details Performs the Implicit-Explicit Runge-Kutta step. Scheme taken from
-  Cavaglieri, D., & Bewley, T. (2015). Low-storage implicit/explicit Runge–Kutta
-  schemes for the simulation of stiff high-dimensional ODE systems. Journal of
-  Computational Physics, 286, 172-193.
-
-  Scheme given by equations (25a,b):
-
-  u[0] = u[n] + dt * (expl_rkcoef[1,0]*R_ex(u[n])+impl_rkcoef[1,1]*R_im(u[0]))
-
-  u[1] = u[n] + dt * (expl_rkcoef[2,1]*R_ex(u[0])+impl_rkcoef[2,1]*R_im(u[0])
-                                                 +impl_rkcoef[2,2]*R_im(u[1]))
-
-  u[n+1] = u[n] + dt * (expl_rkcoef[3,1]*R_ex(u[0])+impl_rkcoef[3,1]*R_im(u[0])
-                        expl_rkcoef[3,2]*R_ex(u[1])+impl_rkcoef[3,2]*R_im(u[1]))
-
-  In order to solve the first two equations we need to solve a series of systems
-  of non-linear equations:
-
-  F1(u[0]) = B1 + R1(u[0]) = 0, and
-  F2(u[1]) = B2 + R2(u[1]) = 0,
-
-  where
-
-  B1 = u[n] + dt * expl_rkcoef[1,0]*R_ex(u[n]),
-  R1 = dt * impl_rkcoef[1,1]*R_im(u[0]) - u([0]),
-  B2 = u[n] + dt * (expl_rkcoef[2,1]*R_ex(u[0])+impl_rkcoef[2,1]*R_im(u[0])),
-  R2 = dt * impl_rkcoef[2,2]*R_im(u[1]) - u([1]).
-
-  In order to solve the non-linear system F(U) = 0, we employ Broyden's method.
-  Taken from https://en.wikipedia.org/wiki/Broyden%27s_method.
-  The method consists in obtaining an approximation for the inverse of the
-  Jacobian H = J^(-1) and advancing in a quasi-newton step:
-
-  U[k+1] = U[k] - H[k]*F(U[k]),
-
-  until F(U) is close enough to zero.
-
-  The approximation H[k] is improved at every iteration following
-
-  H[k] = H[k-1] + (DU[k]-H[k-1]*DF[k])/(DU[k]^T*H[k-1]*DF[k]) * DU[k]^T*H[k-1],
-
-  where DU[k] = U[k] - U[k-1] and DF[k] = F(U[k]) - F(U[k-1)).
-
-  This function performs the following main algorithmic steps:
-  - If stage == 0 or stage == 1:
-    - Take Initial value:
-      U[0] = U[n] + dt * expl_rkcoef[1,0]*R_ex(U[n]) (for stage 0)
-      U[1] = U[n] + dt * (expl_rkcoef[2,1]*R_ex(U[0])
-                         +impl_rkcoef[2,1]*R_im(U[0])) (for stage 1)
-    - Loop over the Elements (e++)
-      - Initialize Jacobian inverse approximation as the identity
-      - Compute implicit right-hand-side (F_im) with current U
-      - Iterate for the solution (iter++)
-        - Compute new solution U[k+1] = U[k] - H[k]*F(U[k])
-        - Compute implicit right-hand-side (F_im) with current U
-        - Compute DU and DF
-        - Update inverse Jacobian approximation by:
-          - Compute V1 = H[k-1]*DF[k] and V2 = DU[k]^T*H[k-1]
-          - Compute d = DU[k]^T*V1 and V3 = DU[k]-V1
-          - Compute V4 = V3/d
-          - Update H[k] = H[k-1] + V4*V2
-        - Save old U and F
-        - Compute absolute and relative errors
-        - Break iterations if error < tol or iter == max_iter
-     - Update explicit equations using only the explicit terms.
-  - Else if stage == 2:
-     - Update explicit equations using only the explicit terms.
-     - Update implicit equations using:
-     u[n+1] = u[n]+dt*(expl_rkcoef[3,1]*R_ex(u[0])+impl_rkcoef[3,1]*R_im(u[0])
-                       expl_rkcoef[3,2]*R_ex(u[1])+impl_rkcoef[3,2]*R_im(u[1]))
-
-  ******************************************************************************/
-  auto d = Disc();
-  const auto rdof = g_inputdeck.get< tag::rdof >();
-  const auto ndof = g_inputdeck.get< tag::ndof >();
-  if (m_stage < 2) {
-    // Save previous stiff_rhs
-    m_stiffrhsprev = m_stiffrhs;
-
-    // Compute the imex update
-
-    // Integrate explicitly on the imex equations
-    // (To use as initial values)
-    for (std::size_t e=0; e<myGhosts()->m_nunk; ++e)
-      for (std::size_t c=0; c<m_nstiffeq; ++c)
-      {
-        for (std::size_t k=0; k<m_numEqDof[c]; ++k)
-        {
-          auto rmark = m_stiffEqIdx[c]*rdof+k;
-          auto mark = m_stiffEqIdx[c]*ndof+k;
-          m_u(e, rmark) =  m_un(e, rmark) + d->Dt() * (
-            expl_rkcoef[0][m_stage] * m_rhsprev(e, mark)/m_lhs(e, mark)
-            + expl_rkcoef[1][m_stage] * m_rhs(e, mark)/m_lhs(e, mark)
-            + impl_rkcoef[0][m_stage]
-            * m_stiffrhsprev(e,c*ndof+k)/m_lhs(e, mark) );
-          if(fabs(m_u(e, rmark)) < 1e-16)
-            m_u(e, rmark) = 0;
-        }
-      }
-
-    // Solve for implicit-explicit equations
-    const auto nelem = myGhosts()->m_fd.Esuel().size()/4;
-    for (std::size_t e=0; e<nelem; ++e)
-    {
-      // Non-linear system f(u) = 0 to be solved
-      // Broyden's method
-      // Control parameters
-      std::size_t max_iter = g_inputdeck.get< tag::imex_maxiter >();
-      tk::real rel_tol = g_inputdeck.get< tag::imex_reltol >();
-      tk::real abs_tol = g_inputdeck.get< tag::imex_abstol >();
-      tk::real rel_err = rel_tol+1;
-      tk::real abs_err = abs_tol+1;
-      std::size_t nstiff = m_nstiffeq*ndof;
-
-      // Initialize Jacobian to be the identity
-      std::vector< std::vector< tk::real > >
-        approx_jacob(nstiff, std::vector< tk::real >(nstiff, 0.0));
-      for (std::size_t i=0; i<nstiff; ++i)
-        approx_jacob[i][i] = 1.0e+00;
-
-      // Save explicit terms to be re-used
-      std::vector< tk::real > expl_terms(nstiff, 0.0);
-      for (size_t ieq=0; ieq<m_nstiffeq; ++ieq)
-        for (size_t idof=0; idof<m_numEqDof[ieq]; ++idof)
-        {
-          auto stiffmark = m_stiffEqIdx[ieq]*ndof+idof;
-          auto stiffrmark = m_stiffEqIdx[ieq]*rdof+idof;
-          expl_terms[ieq*ndof+idof] = m_un(e, stiffrmark)
-            + d->Dt() * ( expl_rkcoef[0][m_stage]
-            * m_rhsprev(e,stiffmark)/m_lhs(e,stiffmark)
-            + expl_rkcoef[1][m_stage]
-            * m_rhs(e,stiffmark)/m_lhs(e,stiffmark)
-            + impl_rkcoef[0][m_stage]
-            * m_stiffrhsprev(e,ieq*ndof+idof)/m_lhs(e,stiffmark) );
-        }
-
-      // Compute stiff_rhs with initial u
-      g_dgpde[d->MeshId()].stiff_rhs( e, myGhosts()->m_geoElem,
-        myGhosts()->m_inpoel, myGhosts()->m_coord,
-        m_u, m_p, m_ndof, m_stiffrhs );
-
-      // Make auxiliary u_old and f_old to store previous values
-      std::vector< tk::real > u_old(nstiff, 0.0), f_old(nstiff, 0.0);
-      // Make delta_u and delta_f
-      std::vector< tk::real > delta_u(nstiff, 0.0), delta_f(nstiff, 0.0);
-      // Store f
-      std::vector< tk::real > f(nstiff, 0.0);
-      for (std::size_t ieq=0; ieq<m_nstiffeq; ++ieq)
-        for (std::size_t idof=0; idof<m_numEqDof[ieq]; ++idof)
-        {
-          auto stiffrmark = m_stiffEqIdx[ieq]*rdof+idof;
-          auto stiffmark = m_stiffEqIdx[ieq]*ndof+idof;
-          f[ieq*ndof+idof] = expl_terms[ieq*ndof+idof]
-            + d->Dt() * impl_rkcoef[1][m_stage]
-            * m_stiffrhs(e,ieq*ndof+idof)/m_lhs(e,stiffmark)
-            - m_u(e, stiffrmark);
-        }
-
-      // Initialize u_old and f_old
-      for (std::size_t ieq=0; ieq<m_nstiffeq; ++ieq)
-        for (std::size_t idof=0; idof<m_numEqDof[ieq]; ++idof)
-        {
-          u_old[ieq*ndof+idof] = m_u(e, m_stiffEqIdx[ieq]*rdof+idof);
-          f_old[ieq*ndof+idof] = f[ieq*ndof+idof];
-        }
-
-      // Store the norm of f initially, for relative error measure
-      tk::real err0 = 0.0;
-      for (std::size_t ieq=0; ieq<m_nstiffeq; ++ieq)
-        for (std::size_t idof=0; idof<m_numEqDof[ieq]; ++idof)
-          err0 += f[ieq*ndof+idof]*f[ieq*ndof+idof];
-      err0 = std::sqrt(err0);
-
-      // Iterate for the solution if err0 > 0
-      if (err0 > abs_tol)
-        for (size_t iter=0; iter<max_iter; ++iter)
-        {
-
-          // Compute new solution
-          tk::real delta;
-          for (std::size_t ieq=0; ieq<m_nstiffeq; ++ieq)
-            for (std::size_t idof=0; idof<m_numEqDof[ieq]; ++idof)
-            {
-              delta = 0.0;
-              for (std::size_t jeq=0; jeq<m_nstiffeq; ++jeq)
-                for (std::size_t jdof=0; jdof<m_numEqDof[jeq]; ++jdof)
-                  delta +=
-                    approx_jacob[ieq*ndof+idof][jeq*ndof+jdof] * f[jeq*ndof+jdof];
-              // Update u
-              auto stiffrmark = m_stiffEqIdx[ieq]*rdof+idof;
-              m_u(e, stiffrmark) -= delta;
-            }
-
-          // Compute new stiff_rhs
-          g_dgpde[d->MeshId()].stiff_rhs( e, myGhosts()->m_geoElem,
-            myGhosts()->m_inpoel, myGhosts()->m_coord,
-            m_u, m_p, m_ndof, m_stiffrhs );
-
-          // Compute new f(u)
-          for (std::size_t ieq=0; ieq<m_nstiffeq; ++ieq)
-            for (std::size_t idof=0; idof<m_numEqDof[ieq]; ++idof)
-            {
-              auto stiffrmark = m_stiffEqIdx[ieq]*rdof+idof;
-              auto stiffmark = m_stiffEqIdx[ieq]*ndof+idof;
-              f[ieq*ndof+idof] = expl_terms[ieq*ndof+idof]
-                + d->Dt() * impl_rkcoef[1][m_stage]
-                * m_stiffrhs(e,ieq*ndof+idof)/m_lhs(e,stiffmark)
-                - m_u(e, stiffrmark);
-            }
-
-          // Compute delta_u and delta_f
-          for (std::size_t ieq=0; ieq<m_nstiffeq; ++ieq)
-            for (std::size_t idof=0; idof<m_numEqDof[ieq]; ++idof)
-            {
-              auto stiffrmark = m_stiffEqIdx[ieq]*rdof+idof;
-              delta_u[ieq*ndof+idof] = m_u(e, stiffrmark) - u_old[ieq*ndof+idof];
-              delta_f[ieq*ndof+idof] = f[ieq*ndof+idof] - f_old[ieq*ndof+idof];
-            }
-
-          // Update inverse Jacobian approximation
-
-          // 1. Compute approx_jacob*delta_f and delta_u*jacob_approx
-          tk::real sum1, sum2;
-          std::vector< tk::real > auxvec1(nstiff, 0.0), auxvec2(nstiff, 0.0);
-          for (std::size_t ieq=0; ieq<m_nstiffeq; ++ieq)
-            for (std::size_t idof=0; idof<m_numEqDof[ieq]; ++idof)
-            {
-              sum1 = 0.0;
-              sum2 = 0.0;
-              for (std::size_t jeq=0; jeq<m_nstiffeq; ++jeq)
-                for (std::size_t jdof=0; jdof<m_numEqDof[jeq]; ++jdof)
-                {
-                  sum1 += approx_jacob[ieq*ndof+idof][jeq*ndof+jdof] *
-                    delta_f[jeq*ndof+jdof];
-                  sum2 += delta_u[jeq*ndof+jdof] *
-                    approx_jacob[jeq*ndof+jdof][ieq*ndof+idof];
-                }
-              auxvec1[ieq*ndof+idof] = sum1;
-              auxvec2[ieq*ndof+idof] = sum2;
-            }
-
-          // 2. Compute delta_u*approx_jacob*delta_f
-          // and delta_u-approx_jacob*delta_f
-          tk::real denom = 0.0;
-          for (std::size_t jeq=0; jeq<m_nstiffeq; ++jeq)
-            for (std::size_t jdof=0; jdof<m_numEqDof[jeq]; ++jdof)
-            {
-              denom += delta_u[jeq*ndof+jdof]*auxvec1[jeq*ndof+jdof];
-              auxvec1[jeq*ndof+jdof] =
-                delta_u[jeq*ndof+jdof]-auxvec1[jeq*ndof+jdof];
-            }
-
-          // 3. Divide delta_u+approx_jacob*delta_f
-          // by delta_u*(approx_jacob*delta_f)
-          if (std::abs(denom) < 1.0e-18)
-          {
-            if (denom < 0.0)
-            {
-              for (std::size_t jeq=0; jeq<m_nstiffeq; ++jeq)
-                for (std::size_t jdof=0; jdof<m_numEqDof[jeq]; ++jdof)
-                  auxvec1[jeq*ndof+jdof] /= -1.0e-18;
-            }
-            else
-            {
-              for (std::size_t jeq=0; jeq<m_nstiffeq; ++jeq)
-                for (std::size_t jdof=0; jdof<m_numEqDof[jeq]; ++jdof)
-                  auxvec1[jeq*ndof+jdof] /= 1.0e-18;
-            }
-          }
-          else
-          {
-            for (std::size_t jeq=0; jeq<m_nstiffeq; ++jeq)
-              for (std::size_t jdof=0; jdof<m_numEqDof[jeq]; ++jdof)
-                auxvec1[jeq*ndof+jdof] /= denom;
-          }
-
-          // 4. Perform outter product between the two arrays and
-          // add that quantity to the new jacobian approximation
-          for (std::size_t ieq=0; ieq<m_nstiffeq; ++ieq)
-            for (std::size_t idof=0; idof<m_numEqDof[ieq]; ++idof)
-              for (std::size_t jeq=0; jeq<m_nstiffeq; ++jeq)
-                for (std::size_t jdof=0; jdof<m_numEqDof[jeq]; ++jdof)
-                  approx_jacob[ieq*ndof+idof][jeq*ndof+jdof] +=
-                    auxvec1[ieq*ndof+idof] * auxvec2[jeq*ndof+jdof];
-
-          // Save solution and f
-          for (std::size_t ieq=0; ieq<m_nstiffeq; ++ieq)
-            for (std::size_t idof=0; idof<m_numEqDof[ieq]; ++idof)
-            {
-              u_old[ieq*ndof+idof] = m_u(e, m_stiffEqIdx[ieq]*rdof+idof);
-              f_old[ieq*ndof+idof] = f[ieq*ndof+idof];
-            }
-
-          // Compute a measure of error, use norm of f
-          tk::real err = 0.0;
-          for (std::size_t ieq=0; ieq<m_nstiffeq; ++ieq)
-            for (std::size_t idof=0; idof<m_numEqDof[ieq]; ++idof)
-              err += f[ieq*ndof+idof]*f[ieq*ndof+idof];
-          abs_err = std::sqrt(err);
-          rel_err = abs_err/err0;
-
-          // Check if error condition is met and loop back
-          if (rel_err < rel_tol || abs_err < abs_tol)
-            break;
-
-          // If we did not converge, print a message
-          if (iter == max_iter-1)
-          {
-            printf("\nIMEX-RK: Non-linear solver did not converge in %lu iterations\n", max_iter);<--- %lu in format string (no. 1) requires 'unsigned long' but the argument type is 'std::size_t {aka unsigned long}'.
-            printf("Element #%lu\n", e);<--- %lu in format string (no. 1) requires 'unsigned long' but the argument type is 'std::size_t {aka unsigned long}'.
-            printf("Relative error: %e\n", rel_err);
-            printf("Absolute error: %e\n\n", abs_err);
-          }
-        }
-    }
-
-    // Then, integrate explicitly on the remaining equations
-    for (std::size_t e=0; e<nelem; ++e)
-      for (std::size_t c=0; c<m_nnonstiffeq; ++c)
-      {
-        for (std::size_t k=0; k<m_numEqDof[c]; ++k)
-        {
-          auto rmark = m_nonStiffEqIdx[c]*rdof+k;
-          auto mark = m_nonStiffEqIdx[c]*ndof+k;
-          m_u(e, rmark) =  m_un(e, rmark) + d->Dt() * (
-            expl_rkcoef[0][m_stage] * m_rhsprev(e, mark)/m_lhs(e, mark)
-            + expl_rkcoef[1][m_stage] * m_rhs(e, mark)/m_lhs(e, mark));
-          if(fabs(m_u(e, rmark)) < 1e-16)
-            m_u(e, rmark) = 0;
-        }
-      }
-  }
-  else {
-    // For last stage just use all previously computed stages
-    const auto nelem = myGhosts()->m_fd.Esuel().size()/4;
-    for (std::size_t e=0; e<nelem; ++e)
-    {
-      // First integrate explicitly on nonstiff equations
-      for (std::size_t c=0; c<m_nnonstiffeq; ++c)
-      {
-        for (std::size_t k=0; k<m_numEqDof[c]; ++k)
-        {
-          auto rmark = m_nonStiffEqIdx[c]*rdof+k;
-          auto mark = m_nonStiffEqIdx[c]*ndof+k;
-          m_u(e, rmark) =  m_un(e, rmark) + d->Dt() * (
-            expl_rkcoef[0][m_stage] * m_rhsprev(e, mark)/m_lhs(e, mark)
-            + expl_rkcoef[1][m_stage] * m_rhs(e, mark)/m_lhs(e, mark));
-          if(fabs(m_u(e, rmark)) < 1e-16)
-            m_u(e, rmark) = 0;
-        }
-      }
-      // Then, integrate the imex-equations
-      for (std::size_t ieq=0; ieq<m_nstiffeq; ++ieq)
-        for (std::size_t idof=0; idof<m_numEqDof[ieq]; ++idof)
-        {
-          auto rmark = m_stiffEqIdx[ieq]*rdof+idof;
-          auto mark = m_stiffEqIdx[ieq]*ndof+idof;
-          m_u(e, rmark) = m_un(e, rmark)
-            + d->Dt() * (expl_rkcoef[0][m_stage]
-                         * m_rhsprev(e,mark)/m_lhs(e,mark)
-                         + expl_rkcoef[1][m_stage]
-                         * m_rhs(e,mark)/m_lhs(e,mark)
-                         + impl_rkcoef[0][m_stage]
-                         * m_stiffrhsprev(e,ieq*ndof+idof)/m_lhs(e,mark)
-                         + impl_rkcoef[1][m_stage]
-                         * m_stiffrhs(e,ieq*ndof+idof)/m_lhs(e,mark) );
-          if(fabs(m_u(e, rmark)) < 1e-16)
-            m_u(e, rmark) = 0;
-        }
-    }
-  }
-}
-
-#include "NoWarning/dg.def.h"
+    {
+      Assert( ugp.size() == ncomp, "Size mismatch" );
+      Assert( v.size() == ncomp, "Size mismatch" );
+
+      std::vector< std::array< tk::real, 3 > > fl( ugp.size() );
+
+      for (ncomp_t c=0; c<ncomp; ++c)
+        fl[c] = {{ v[c][0] * ugp[c], v[c][1] * ugp[c], v[c][2] * ugp[c] }};
+
+      return fl;
+    }
+
+    //! \brief Boundary state function providing the left and right state of a
+    //!   face at extrapolation boundaries
+    //! \param[in] ul Left (domain-internal) state
+    //! \return Left and right states for all scalar components in this PDE
+    //!   system
+    //! \note The function signature must follow tk::StateFn
+    static tk::StateFn::result_type
+    extrapolate( ncomp_t, const std::vector< EOS >&,
+                 const std::vector< tk::real >& ul, tk::real, tk::real,
+                 tk::real, tk::real, const std::array< tk::real, 3 >& )
+    {
+      return {{ ul, ul }};
+    }
+
+    //! \brief Boundary state function providing the left and right state of a
+    //!   face at extrapolation boundaries
+    //! \param[in] ul Left (domain-internal) state
+    //! \return Left and right states for all scalar components in this PDE
+    //!   system
+    //! \note The function signature must follow tk::StateFn
+    static tk::StateFn::result_type
+    inlet( ncomp_t, const std::vector< EOS >&,
+           const std::vector< tk::real >& ul, tk::real, tk::real, tk::real,
+           tk::real, const std::array< tk::real, 3 >& )
+    {
+      auto ur = ul;
+      std::fill( begin(ur), end(ur), 0.0 );
+      return {{ ul, std::move(ur) }};
+    }
+
+    //! \brief Boundary state function providing the left and right state of a
+    //!   face at outlet boundaries
+    //! \param[in] ul Left (domain-internal) state
+    //! \return Left and right states for all scalar components in this PDE
+    //!   system
+    //! \note The function signature must follow tk::StateFn
+    static tk::StateFn::result_type
+    outlet( ncomp_t, const std::vector< EOS >&,
+            const std::vector< tk::real >& ul, tk::real, tk::real, tk::real,
+            tk::real, const std::array< tk::real, 3 >& )
+    {
+      return {{ ul, ul }};
+    }
+
+    //! \brief Boundary state function providing the left and right state of a
+    //!   face at Dirichlet boundaries
+    //! \param[in] ncomp Number of scalar components in this PDE system
+    //! \param[in] ul Left (domain-internal) state
+    //! \param[in] x X-coordinate at which to compute the states
+    //! \param[in] y Y-coordinate at which to compute the states
+    //! \param[in] z Z-coordinate at which to compute the states
+    //! \param[in] t Physical time
+    //! \return Left and right states for all scalar components in this PDE
+    //!   system
+    //! \note The function signature must follow tk::StateFn
+    static tk::StateFn::result_type
+    dirichlet( ncomp_t ncomp, 
+               const std::vector< EOS >& mat_blk,
+               const std::vector< tk::real >& ul, tk::real x, tk::real y,
+               tk::real z, tk::real t, const std::array< tk::real, 3 >& )
+    {
+      return {{ ul, Problem::initialize( ncomp, mat_blk, x, y, z, t ) }};
+    }
+};
+
+} // dg::
+} // inciter::
+
+#endif // DGTransport_h
 
diff --git a/Debug/cppcheck/60.html b/Debug/cppcheck/60.html index 1825fda9abbc..fa2f9d84af5d 100644 --- a/Debug/cppcheck/60.html +++ b/Debug/cppcheck/60.html @@ -152,3193 +152,259 @@
- - + diff --git a/Debug/test_coverage/Base/Writer.cpp.func.html b/Debug/test_coverage/Base/Writer.cpp.func.html index 4c7067e83bd2..92adb942ba9d 100644 --- a/Debug/test_coverage/Base/Writer.cpp.func.html +++ b/Debug/test_coverage/Base/Writer.cpp.func.html @@ -33,7 +33,7 @@ - + diff --git a/Debug/test_coverage/Base/Writer.cpp.gcov.html b/Debug/test_coverage/Base/Writer.cpp.gcov.html index 4eaefcaae19c..ced07a7e4648 100644 --- a/Debug/test_coverage/Base/Writer.cpp.gcov.html +++ b/Debug/test_coverage/Base/Writer.cpp.gcov.html @@ -33,7 +33,7 @@ - + diff --git a/Debug/test_coverage/Base/Writer.hpp.func-sort-c.html b/Debug/test_coverage/Base/Writer.hpp.func-sort-c.html index 8daefc89ff12..fed854b4f3d9 100644 --- a/Debug/test_coverage/Base/Writer.hpp.func-sort-c.html +++ b/Debug/test_coverage/Base/Writer.hpp.func-sort-c.html @@ -33,7 +33,7 @@ - + diff --git a/Debug/test_coverage/Base/Writer.hpp.func.html b/Debug/test_coverage/Base/Writer.hpp.func.html index f183790a77e9..9546c6567b6c 100644 --- a/Debug/test_coverage/Base/Writer.hpp.func.html +++ b/Debug/test_coverage/Base/Writer.hpp.func.html @@ -33,7 +33,7 @@ - + diff --git a/Debug/test_coverage/Base/Writer.hpp.gcov.html b/Debug/test_coverage/Base/Writer.hpp.gcov.html index 7bcdbfdadc0f..083c209b11ff 100644 --- a/Debug/test_coverage/Base/Writer.hpp.gcov.html +++ b/Debug/test_coverage/Base/Writer.hpp.gcov.html @@ -33,7 +33,7 @@ - + diff --git a/Debug/test_coverage/Base/index-sort-b.html b/Debug/test_coverage/Base/index-sort-b.html index 4606ddd6581f..4e4890e8e7d6 100644 --- a/Debug/test_coverage/Base/index-sort-b.html +++ b/Debug/test_coverage/Base/index-sort-b.html @@ -27,16 +27,16 @@ - + - + - + - + @@ -49,9 +49,9 @@ - + - +
   1
-   2
-   3
-   4
-   5
-   6
-   7
-   8
-   9
-  10
-  11
-  12
-  13
-  14
-  15
-  16
-  17
-  18
-  19
-  20
-  21
-  22
-  23
-  24
-  25
-  26
-  27
-  28
-  29
-  30
-  31
-  32
-  33
-  34
-  35
-  36
-  37
-  38
-  39
-  40
-  41
-  42
-  43
-  44
-  45
-  46
-  47
-  48
-  49
-  50
-  51
-  52
-  53
-  54
-  55
-  56
-  57
-  58
-  59
-  60
-  61
-  62
-  63
-  64
-  65
-  66
-  67
-  68
-  69
-  70
-  71
-  72
-  73
-  74
-  75
-  76
-  77
-  78
-  79
-  80
-  81
-  82
-  83
-  84
-  85
-  86
-  87
-  88
-  89
-  90
-  91
-  92
-  93
-  94
-  95
-  96
-  97
-  98
-  99
- 100
- 101
- 102
- 103
- 104
- 105
- 106
- 107
- 108
- 109
- 110
- 111
- 112
- 113
- 114
- 115
- 116
- 117
- 118
- 119
- 120
- 121
- 122
- 123
- 124
- 125
- 126
- 127
- 128
- 129
- 130
- 131
- 132
- 133
- 134
- 135
- 136
- 137
- 138
- 139
- 140
- 141
- 142
- 143
- 144
- 145
- 146
- 147
- 148
- 149
- 150
- 151
- 152
- 153
- 154
- 155
- 156
- 157
- 158
- 159
- 160
- 161
- 162
- 163
- 164
- 165
- 166
- 167
- 168
- 169
- 170
- 171
- 172
- 173
- 174
- 175
- 176
- 177
- 178
- 179
- 180
- 181
- 182
- 183
- 184
- 185
- 186
- 187
- 188
- 189
- 190
- 191
- 192
- 193
- 194
- 195
- 196
- 197
- 198
- 199
- 200
- 201
- 202
- 203
- 204
- 205
- 206
- 207
- 208
- 209
- 210
- 211
- 212
- 213
- 214
- 215
- 216
- 217
- 218
- 219
- 220
- 221
- 222
- 223
- 224
- 225
- 226
- 227
- 228
- 229
- 230
- 231
- 232
- 233
- 234
- 235
- 236
- 237
- 238
- 239
- 240
- 241
- 242
- 243
- 244
- 245
- 246
- 247
- 248
- 249
- 250
- 251
- 252
- 253
- 254
- 255
- 256
- 257
- 258
- 259
- 260
- 261
- 262
- 263
- 264
- 265
- 266
- 267
- 268
- 269
- 270
- 271
- 272
- 273
- 274
- 275
- 276
- 277
- 278
- 279
- 280
- 281
- 282
- 283
- 284
- 285
- 286
- 287
- 288
- 289
- 290
- 291
- 292
- 293
- 294
- 295
- 296
- 297
- 298
- 299
- 300
- 301
- 302
- 303
- 304
- 305
- 306
- 307
- 308
- 309
- 310
- 311
- 312
- 313
- 314
- 315
- 316
- 317
- 318
- 319
- 320
- 321
- 322
- 323
- 324
- 325
- 326
- 327
- 328
- 329
- 330
- 331
- 332
- 333
- 334
- 335
- 336
- 337
- 338
- 339
- 340
- 341
- 342
- 343
- 344
- 345
- 346
- 347
- 348
- 349
- 350
- 351
- 352
- 353
- 354
- 355
- 356
- 357
- 358
- 359
- 360
- 361
- 362
- 363
- 364
- 365
- 366
- 367
- 368
- 369
- 370
- 371
- 372
- 373
- 374
- 375
- 376
- 377
- 378
- 379
- 380
- 381
- 382
- 383
- 384
- 385
- 386
- 387
- 388
- 389
- 390
- 391
- 392
- 393
- 394
- 395
- 396
- 397
- 398
- 399
- 400
- 401
- 402
- 403
- 404
- 405
- 406
- 407
- 408
- 409
- 410
- 411
- 412
- 413
- 414
- 415
- 416
- 417
- 418
- 419
- 420
- 421
- 422
- 423
- 424
- 425
- 426
- 427
- 428
- 429
- 430
- 431
- 432
- 433
- 434
- 435
- 436
- 437
- 438
- 439
- 440
- 441
- 442
- 443
- 444
- 445
- 446
- 447
- 448
- 449
- 450
- 451
- 452
- 453
- 454
- 455
- 456
- 457
- 458
- 459
- 460
- 461
- 462
- 463
- 464
- 465
- 466
- 467
- 468
- 469
- 470
- 471
- 472
- 473
- 474
- 475
- 476
- 477
- 478
- 479
- 480
- 481
- 482
- 483
- 484
- 485
- 486
- 487
- 488
- 489
- 490
- 491
- 492
- 493
- 494
- 495
- 496
- 497
- 498
- 499
- 500
- 501
- 502
- 503
- 504
- 505
- 506
- 507
- 508
- 509
- 510
- 511
- 512
- 513
- 514
- 515
- 516
- 517
- 518
- 519
- 520
- 521
- 522
- 523
- 524
- 525
- 526
- 527
- 528
- 529
- 530
- 531
- 532
- 533
- 534
- 535
- 536
- 537
- 538
- 539
- 540
- 541
- 542
- 543
- 544
- 545
- 546
- 547
- 548
- 549
- 550
- 551
- 552
- 553
- 554
- 555
- 556
- 557
- 558
- 559
- 560
- 561
- 562
- 563
- 564
- 565
- 566
- 567
- 568
- 569
- 570
- 571
- 572
- 573
- 574
- 575
- 576
- 577
- 578
- 579
- 580
- 581
- 582
- 583
- 584
- 585
- 586
- 587
- 588
- 589
- 590
- 591
- 592
- 593
- 594
- 595
- 596
- 597
- 598
- 599
- 600
- 601
- 602
- 603
- 604
- 605
- 606
- 607
- 608
- 609
- 610
- 611
- 612
- 613
- 614
- 615
- 616
- 617
- 618
- 619
- 620
- 621
- 622
- 623
- 624
- 625
- 626
- 627
- 628
- 629
- 630
- 631
- 632
- 633
- 634
- 635
- 636
- 637
- 638
- 639
- 640
- 641
- 642
- 643
- 644
- 645
- 646
- 647
- 648
- 649
- 650
- 651
- 652
- 653
- 654
- 655
- 656
- 657
- 658
- 659
- 660
- 661
- 662
- 663
- 664
- 665
- 666
- 667
- 668
- 669
- 670
- 671
- 672
- 673
- 674
- 675
- 676
- 677
- 678
- 679
- 680
- 681
- 682
- 683
- 684
- 685
- 686
- 687
- 688
- 689
- 690
- 691
- 692
- 693
- 694
- 695
- 696
- 697
- 698
- 699
- 700
- 701
- 702
- 703
- 704
- 705
- 706
- 707
- 708
- 709
- 710
- 711
- 712
- 713
- 714
- 715
- 716
- 717
- 718
- 719
- 720
- 721
- 722
- 723
- 724
- 725
- 726
- 727
- 728
- 729
- 730
- 731
- 732
- 733
- 734
- 735
- 736
- 737
- 738
- 739
- 740
- 741
- 742
- 743
- 744
- 745
- 746
- 747
- 748
- 749
- 750
- 751
- 752
- 753
- 754
- 755
- 756
- 757
- 758
- 759
- 760
- 761
- 762
- 763
- 764
- 765
- 766
- 767
- 768
- 769
- 770
- 771
- 772
- 773
- 774
- 775
- 776
- 777
- 778
- 779
- 780
- 781
- 782
- 783
- 784
- 785
- 786
- 787
- 788
- 789
- 790
- 791
- 792
- 793
- 794
- 795
- 796
- 797
- 798
- 799
- 800
- 801
- 802
- 803
- 804
- 805
- 806
- 807
- 808
- 809
- 810
- 811
- 812
- 813
- 814
- 815
- 816
- 817
- 818
- 819
- 820
- 821
- 822
- 823
- 824
- 825
- 826
- 827
- 828
- 829
- 830
- 831
- 832
- 833
- 834
- 835
- 836
- 837
- 838
- 839
- 840
- 841
- 842
- 843
- 844
- 845
- 846
- 847
- 848
- 849
- 850
- 851
- 852
- 853
- 854
- 855
- 856
- 857
- 858
- 859
- 860
- 861
- 862
- 863
- 864
- 865
- 866
- 867
- 868
- 869
- 870
- 871
- 872
- 873
- 874
- 875
- 876
- 877
- 878
- 879
- 880
- 881
- 882
- 883
- 884
- 885
- 886
- 887
- 888
- 889
- 890
- 891
- 892
- 893
- 894
- 895
- 896
- 897
- 898
- 899
- 900
- 901
- 902
- 903
- 904
- 905
- 906
- 907
- 908
- 909
- 910
- 911
- 912
- 913
- 914
- 915
- 916
- 917
- 918
- 919
- 920
- 921
- 922
- 923
- 924
- 925
- 926
- 927
- 928
- 929
- 930
- 931
- 932
- 933
- 934
- 935
- 936
- 937
- 938
- 939
- 940
- 941
- 942
- 943
- 944
- 945
- 946
- 947
- 948
- 949
- 950
- 951
- 952
- 953
- 954
- 955
- 956
- 957
- 958
- 959
- 960
- 961
- 962
- 963
- 964
- 965
- 966
- 967
- 968
- 969
- 970
- 971
- 972
- 973
- 974
- 975
- 976
- 977
- 978
- 979
- 980
- 981
- 982
- 983
- 984
- 985
- 986
- 987
- 988
- 989
- 990
- 991
- 992
- 993
- 994
- 995
- 996
- 997
- 998
- 999
-1000
-1001
-1002
-1003
-1004
-1005
-1006
-1007
-1008
-1009
-1010
-1011
-1012
-1013
-1014
-1015
-1016
-1017
-1018
-1019
-1020
-1021
-1022
-1023
-1024
-1025
-1026
-1027
-1028
-1029
-1030
-1031
-1032
-1033
-1034
-1035
-1036
-1037
-1038
-1039
-1040
-1041
-1042
-1043
-1044
-1045
-1046
-1047
-1048
-1049
-1050
-1051
-1052
-1053
-1054
-1055
-1056
-1057
-1058
-1059
-1060
-1061
-1062
-1063
-1064
-1065
-1066
-1067
-1068
-1069
-1070
-1071
-1072
-1073
-1074
-1075
-1076
-1077
-1078
-1079
-1080
-1081
-1082
-1083
-1084
-1085
-1086
-1087
-1088
-1089
-1090
-1091
-1092
-1093
-1094
-1095
-1096
-1097
-1098
-1099
-1100
-1101
-1102
-1103
-1104
-1105
-1106
-1107
-1108
-1109
-1110
-1111
-1112
-1113
-1114
-1115
-1116
-1117
-1118
-1119
-1120
-1121
-1122
-1123
-1124
-1125
-1126
-1127
-1128
-1129
-1130
-1131
-1132
-1133
-1134
-1135
-1136
-1137
-1138
-1139
-1140
-1141
-1142
-1143
-1144
-1145
-1146
-1147
-1148
-1149
-1150
-1151
-1152
-1153
-1154
-1155
-1156
-1157
-1158
-1159
-1160
-1161
-1162
-1163
-1164
-1165
-1166
-1167
-1168
-1169
-1170
-1171
-1172
-1173
-1174
-1175
-1176
-1177
-1178
-1179
-1180
-1181
-1182
-1183
-1184
-1185
-1186
-1187
-1188
-1189
-1190
-1191
-1192
-1193
-1194
-1195
-1196
-1197
-1198
-1199
-1200
-1201
-1202
-1203
-1204
-1205
-1206
-1207
-1208
-1209
-1210
-1211
-1212
-1213
-1214
-1215
-1216
-1217
-1218
-1219
-1220
-1221
-1222
-1223
-1224
-1225
-1226
-1227
-1228
-1229
-1230
-1231
-1232
-1233
-1234
-1235
-1236
-1237
-1238
-1239
-1240
-1241
-1242
-1243
-1244
-1245
-1246
-1247
-1248
-1249
-1250
-1251
-1252
-1253
-1254
-1255
-1256
-1257
-1258
-1259
-1260
-1261
-1262
-1263
-1264
-1265
-1266
-1267
-1268
-1269
-1270
-1271
-1272
-1273
-1274
-1275
-1276
-1277
-1278
-1279
-1280
-1281
-1282
-1283
-1284
-1285
-1286
-1287
-1288
-1289
-1290
-1291
-1292
-1293
-1294
-1295
-1296
-1297
-1298
-1299
-1300
-1301
-1302
-1303
-1304
-1305
-1306
-1307
-1308
-1309
-1310
-1311
-1312
-1313
-1314
-1315
-1316
-1317
-1318
-1319
-1320
-1321
-1322
-1323
-1324
-1325
-1326
-1327
-1328
-1329
-1330
-1331
-1332
-1333
-1334
-1335
-1336
-1337
-1338
-1339
-1340
-1341
-1342
-1343
-1344
-1345
-1346
-1347
-1348
-1349
-1350
-1351
-1352
-1353
-1354
-1355
-1356
-1357
-1358
-1359
-1360
-1361
-1362
-1363
-1364
-1365
-1366
-1367
-1368
-1369
-1370
-1371
-1372
-1373
-1374
-1375
-1376
-1377
-1378
-1379
-1380
-1381
-1382
-1383
-1384
-1385
-1386
-1387
-1388
-1389
-1390
-1391
-1392
-1393
-1394
-1395
-1396
-1397
-1398
-1399
-1400
-1401
-1402
-1403
-1404
-1405
-1406
-1407
-1408
-1409
-1410
-1411
-1412
-1413
-1414
-1415
-1416
-1417
-1418
-1419
-1420
-1421
-1422
-1423
-1424
-1425
-1426
-1427
-1428
-1429
-1430
-1431
-1432
-1433
-1434
-1435
-1436
-1437
-1438
-1439
-1440
-1441
-1442
-1443
-1444
-1445
-1446
-1447
-1448
-1449
-1450
-1451
-1452
-1453
-1454
-1455
-1456
-1457
-1458
-1459
-1460
-1461
-1462
-1463
-1464
-1465
-1466
-1467
-1468
-1469
-1470
-1471
-1472
-1473
-1474
-1475
-1476
-1477
-1478
-1479
-1480
-1481
-1482
-1483
-1484
-1485
-1486
-1487
-1488
-1489
-1490
-1491
-1492
-1493
-1494
-1495
-1496
-1497
-1498
-1499
-1500
-1501
-1502
-1503
-1504
-1505
-1506
-1507
-1508
-1509
-1510
-1511
-1512
-1513
-1514
-1515
-1516
-1517
-1518
-1519
-1520
-1521
-1522
-1523
-1524
-1525
-1526
-1527
-1528
-1529
-1530
-1531
-1532
-1533
-1534
-1535
-1536
-1537
-1538
-1539
-1540
-1541
-1542
-1543
-1544
-1545
-1546
-1547
-1548
-1549
-1550
-1551
-1552
-1553
-1554
-1555
-1556
-1557
-1558
-1559
-1560
-1561
-1562
-1563
-1564
-1565
-1566
-1567
-1568
-1569
-1570
-1571
-1572
-1573
-1574
-1575
-1576
-1577
-1578
-1579
-1580
-1581
-1582
-1583
-1584
-1585
-1586
-1587
-1588
-1589
-1590
// *****************************************************************************
+
  1
+  2
+  3
+  4
+  5
+  6
+  7
+  8
+  9
+ 10
+ 11
+ 12
+ 13
+ 14
+ 15
+ 16
+ 17
+ 18
+ 19
+ 20
+ 21
+ 22
+ 23
+ 24
+ 25
+ 26
+ 27
+ 28
+ 29
+ 30
+ 31
+ 32
+ 33
+ 34
+ 35
+ 36
+ 37
+ 38
+ 39
+ 40
+ 41
+ 42
+ 43
+ 44
+ 45
+ 46
+ 47
+ 48
+ 49
+ 50
+ 51
+ 52
+ 53
+ 54
+ 55
+ 56
+ 57
+ 58
+ 59
+ 60
+ 61
+ 62
+ 63
+ 64
+ 65
+ 66
+ 67
+ 68
+ 69
+ 70
+ 71
+ 72
+ 73
+ 74
+ 75
+ 76
+ 77
+ 78
+ 79
+ 80
+ 81
+ 82
+ 83
+ 84
+ 85
+ 86
+ 87
+ 88
+ 89
+ 90
+ 91
+ 92
+ 93
+ 94
+ 95
+ 96
+ 97
+ 98
+ 99
+100
+101
+102
+103
+104
+105
+106
+107
+108
+109
+110
+111
+112
+113
+114
+115
+116
+117
+118
+119
+120
+121
+122
+123
// *****************************************************************************
 /*!
-  \file      src/Inciter/Transporter.cpp
+  \file      src/PDE/ConfigureTransport.cpp
   \copyright 2012-2015 J. Bakosi,
              2016-2018 Los Alamos National Security, LLC.,
              2019-2021 Triad National Security, LLC.
              All rights reserved. See the LICENSE file for details.
-  \brief     Transporter drives the time integration of transport equations
-  \details   Transporter drives the time integration of transport equations.
-    The implementation uses the Charm++ runtime system and is fully asynchronous,
-    overlapping computation, communication as well as I/O. The algorithm
-    utilizes the structured dagger (SDAG) Charm++ functionality. The high-level
-    overview of the algorithm structure and how it interfaces with Charm++ is
-    discussed in the Charm++ interface file src/Inciter/transporter.ci.
-*/
-// *****************************************************************************
+  \brief     Register and compile configuration on the transport PDE
+  \details   Register and compile configuration on the transport PDE.
+*/
+// *****************************************************************************
+
+#include <set>
+#include <map>
+#include <vector>
+#include <string>
 
-#include <string>
-#include <iostream>
-#include <cstddef>
-#include <unordered_set>
-#include <limits>
-#include <cmath>
-
-#include <brigand/algorithms/for_each.hpp>
-
-#include "Macro.hpp"
-#include "Transporter.hpp"
-#include "Fields.hpp"
-#include "PDEStack.hpp"
-#include "UniPDF.hpp"
-#include "PDFWriter.hpp"
-#include "ContainerUtil.hpp"
-#include "LoadDistributor.hpp"
-#include "MeshReader.hpp"
-#include "Inciter/InputDeck/InputDeck.hpp"
-#include "NodeDiagnostics.hpp"
-#include "ElemDiagnostics.hpp"
-#include "DiagWriter.hpp"
-#include "Callback.hpp"
-#include "CartesianProduct.hpp"
-
-#include "NoWarning/inciter.decl.h"
-#include "NoWarning/partitioner.decl.h"
-
-extern CProxy_Main mainProxy;
-
-namespace inciter {
-
-extern ctr::InputDeck g_inputdeck_defaults;
-extern ctr::InputDeck g_inputdeck;
-extern std::vector< CGPDE > g_cgpde;
-extern std::vector< DGPDE > g_dgpde;
-extern std::vector< FVPDE > g_fvpde;
-
-}
-
-using inciter::Transporter;
-
-Transporter::Transporter() :
-  m_input( input() ),
-  m_nchare( m_input.size() ),
-  m_meshid(),
-  m_ncit( m_nchare.size(), 0 ),
-  m_nload( 0 ),
-  m_ntrans( 0 ),
-  m_ndtmsh( 0 ),
-  m_dtmsh(),
-  m_npart( 0 ),
-  m_nstat( 0 ),
-  m_ndisc( 0 ),
-  m_nchk( 0 ),
-  m_ncom( 0 ),
-  m_nt0refit( m_nchare.size(), 0 ),
-  m_ndtrefit( m_nchare.size(), 0 ),
-  m_noutrefit( m_nchare.size(), 0 ),
-  m_noutderefit( m_nchare.size(), 0 ),
-  m_scheme(),
-  m_partitioner(),
-  m_refiner(),
-  m_meshwriter(),
-  m_sorter(),
-  m_nelem( m_nchare.size() ),
-  m_npoin(),
-  m_finished( m_nchare.size(), 0 ),
-  m_meshvol( m_nchare.size() ),
-  m_minstat( m_nchare.size() ),
-  m_maxstat( m_nchare.size() ),
-  m_avgstat( m_nchare.size() ),
-  m_timer(),
-  m_progMesh( g_inputdeck.get< tag::cmd, tag::feedback >(),
-              ProgMeshPrefix, ProgMeshLegend ),
-  m_progWork( g_inputdeck.get< tag::cmd, tag::feedback >(),
-              ProgWorkPrefix, ProgWorkLegend )
-// *****************************************************************************
-//  Constructor
-// *****************************************************************************
-{
-  // Echo configuration to screen
-  info( printer() );
-
-  const auto nstep = g_inputdeck.get< tag::nstep >();
-  const auto t0 = g_inputdeck.get< tag::t0 >();
-  const auto term = g_inputdeck.get< tag::term >();
-  const auto constdt = g_inputdeck.get< tag::dt >();
+#include <brigand/algorithms/for_each.hpp>
+
+#include "Tags.hpp"
+#include "CartesianProduct.hpp"
+#include "PDEFactory.hpp"
+#include "Inciter/Options/PDE.hpp"
+#include "ContainerUtil.hpp"
+#include "ConfigureTransport.hpp"
+#include "Transport/Physics/CG.hpp"
+#include "Transport/Physics/DG.hpp"
+#include "Transport/CGTransport.hpp"
+#include "Transport/DGTransport.hpp"
+#include "Transport/Problem.hpp"
+
+namespace inciter {
+
+void
+registerTransport( CGFactory& cf,
+                   DGFactory& df,
+                   std::set< ctr::PDEType >& cgt,
+                   std::set< ctr::PDEType >& dgt )
+// *****************************************************************************
+// Register transport PDE into PDE factory
+//! \param[in,out] cf Continuous Galerkin PDE factory to register to
+//! \param[in,out] df Discontinuous Galerkin PDE factory to register to
+//! \param[in,out] cgt Counters for equation types registered into CG factory
+//! \param[in,out] dgt Counters for equation types registered into DG factory
+// *****************************************************************************
+{
+  // Construct vector of vectors for all possible policies
+  using CGTransportPolicies =
+    tk::cartesian_product< cg::TransportPhysics, TransportProblems >;
+  // Register PDEs for all combinations of policies
+  brigand::for_each< CGTransportPolicies >(
+    registerCG< cg::Transport >( cf, cgt, ctr::PDEType::TRANSPORT ) );
+
+  // Construct vector of vectors for all possible policies
+  using DGTransportPolicies =
+    tk::cartesian_product< dg::TransportPhysics, TransportProblems >;
+  // Register PDEs for all combinations of policies
+  brigand::for_each< DGTransportPolicies >(
+    registerDG< dg::Transport >( df, dgt, ctr::PDEType::TRANSPORT ) );
+}
+
+std::vector< std::pair< std::string, std::string > >
+infoTransport( std::map< ctr::PDEType, tk::ncomp_t >& cnt )
+// *****************************************************************************
+//  Return information on the transport PDE
+//! \param[inout] cnt std::map of counters for all PDE types
+//! \return vector of string pairs describing the PDE configuration
+// *****************************************************************************
+{
+  using tk::parameters;
+  using eq = tag::transport;
+
+  auto c = ++cnt[ ctr::PDEType::TRANSPORT ];       // count eqs
+  --c;  // used to index vectors starting with 0<--- Variable 'c' is assigned a value that is never used.
+
+  std::vector< std::pair< std::string, std::string > > nfo;
+
+  nfo.emplace_back( ctr::PDE().name( ctr::PDEType::TRANSPORT ), "" );
+
+  nfo.emplace_back( "problem", ctr::Problem().name(
+    g_inputdeck.get< eq, tag::problem >() ) );
+
+  auto intsharp = g_inputdeck.get< eq, tag::intsharp >();
+  nfo.emplace_back( "interface sharpening", std::to_string( intsharp ) );
+
+  auto ncomp = g_inputdeck.get< tag::ncomp >();
+  nfo.emplace_back( "number of components", std::to_string( ncomp ) );
+
+  const auto& bc = g_inputdeck.get< tag::bc >();
+  for (const auto& ib : bc) {
+    const auto& bcdir = ib.get< tag::dirichlet >();
+    if (!bcdir.empty())
+      nfo.emplace_back( "Dirichlet boundary [" + std::to_string( ncomp ) + "]",
+        parameters( bcdir ) );
+
+    const auto& bcsym = ib.get< tag::symmetry >();
+    if (!bcsym.empty())
+      nfo.emplace_back( "Symmetry boundary [" + std::to_string( ncomp ) + "]",
+        parameters( bcsym ) );
+
+    const auto& bcinlet =
+      ib.get< tag::inlet >();
+    if (!bcinlet.empty())
+      nfo.emplace_back( "Inlet boundary [" + std::to_string( ncomp ) + "]",
+        parameters( bcinlet ) );
 
-  // If the desired max number of time steps is larger than zero, and the
-  // termination time is larger than the initial time, and the constant time
-  // step size (if that is used) is smaller than the duration of the time to be
-  // simulated, we have work to do, otherwise, finish right away. If a constant
-  // dt is not used, that part of the logic is always true as the default
-  // constdt is zero, see inciter::ctr::InputDeck::InputDeck().
-  if ( nstep != 0 && term > t0 && constdt < term-t0 ) {
-
-    // Enable SDAG waits for collecting mesh statistics
-    thisProxy.wait4stat();
-
-    // Configure and write diagnostics file header
-    diagHeader();
-
-    // Create mesh partitioner AND boundary condition object group
-    createPartitioner();
-
-  } else finish();      // stop if no time stepping requested
-}
-
-Transporter::Transporter( CkMigrateMessage* m ) :
-  CBase_Transporter( m ),
-  m_progMesh( g_inputdeck.get< tag::cmd, tag::feedback >(),
-              ProgMeshPrefix, ProgMeshLegend ),
-  m_progWork( g_inputdeck.get< tag::cmd, tag::feedback >(),
-              ProgWorkPrefix, ProgWorkLegend )
-// *****************************************************************************
-//  Migrate constructor: returning from a checkpoint
-//! \param[in] m Charm++ migrate message
-// *****************************************************************************
-{
-   auto print = printer();
-   print.diag( "Restarted from checkpoint" );
-   info( print );
-   inthead( print );
-}
-
-std::vector< std::string >
-Transporter::input()
-// *****************************************************************************
-// Generate list of input mesh filenames configured by the user
-//! \return List of input mesh filenames configured by the user
-//! \details If the input file is given on the command line, a single solver
-//!   will be instantiated on the single mesh, solving potentially multiple
-//!   systems of (potentially coupled) equations. If the input file is not given
-//!   on the command line, the mesh files are expected to be configured in the
-//!   control/input file, associating a potentially different mesh to each
-//!   solver. Both configurations allow the solution of coupled systems, but the
-//!   first one solves all equations on the same mesh, while the latter can
-//!   couple solutions computed on multiple different meshes.
-// *****************************************************************************
-{
-  // Query input mesh filename specified on the command line
-  const auto& cmdinput = g_inputdeck.get< tag::cmd, tag::io, tag::input >();
-
-  // Extract mesh filenames specified in the control file (assigned to solvers)
-  std::vector< std::string > ctrinput;
-  for (const auto& im : g_inputdeck.get< tag::mesh >()) {
-    ctrinput.push_back(im.get< tag::filename >());<--- Consider using std::transform algorithm instead of a raw loop.
-  }
-
-  ErrChk( not cmdinput.empty() or not ctrinput.empty(),
-    "Either a single input mesh must be given on the command line or multiple "
-    "meshes must be configured in the control file." );
-
-   // Prepend control file path to mesh filenames in given in control file
-  if (not ctrinput.empty()) {
-     const auto& ctr = g_inputdeck.get< tag::cmd, tag::io, tag::control >();
-     auto path = ctr.substr( 0, ctr.find_last_of("/")+1 );
-     for (auto& f : ctrinput) f = path + f;<--- Consider using std::transform algorithm instead of a raw loop.
-  }
-
-  if (cmdinput.empty()) return ctrinput; else return { cmdinput };
-}
-
-void
-Transporter::info( const InciterPrint& print )
-// *****************************************************************************
-// Echo configuration to screen
-//! \param[in] print Pretty printer object to use for printing
-// *****************************************************************************
-{
-  print.part( "Factory" );
-
-  // Print out info data layout
-  print.list( "Unknowns data layout (CMake: FIELD_DATA_LAYOUT)",
-              std::list< std::string >{ tk::Fields::layout() } );
-
-  // Re-create partial differential equations stack for output
-  PDEStack stack;
-
-  // Print out information on PDE factories
-  print.eqlist( "Registered PDEs using continuous Galerkin (CG) methods",
-                stack.cgfactory(), stack.cgntypes() );
-  print.eqlist( "Registered PDEs using discontinuous Galerkin (DG) methods",
-                stack.dgfactory(), stack.dgntypes() );
-  print.eqlist( "Registered PDEs using finite volume (DG) methods",
-                stack.fvfactory(), stack.fvntypes() );
-  print.endpart();
-
-  // Print out information on problem
-  print.part( "Problem" );
-
-  // Print out info on problem title
-  if ( !g_inputdeck.get< tag::title >().empty() )
-    print.title( g_inputdeck.get< tag::title >() );
-
-  const auto nstep = g_inputdeck.get< tag::nstep >();
-  const auto t0 = g_inputdeck.get< tag::t0 >();
-  const auto term = g_inputdeck.get< tag::term >();
-  const auto constdt = g_inputdeck.get< tag::dt >();
-  const auto cfl = g_inputdeck.get< tag::cfl >();
-  const auto scheme = g_inputdeck.get< tag::scheme >();
-
-  // Print discretization parameters
-  print.section( "Discretization parameters" );
-  print.Item< ctr::Scheme, tag::scheme >();
-  print.item( "Implicit-Explicit Runge-Kutta",
-              g_inputdeck.get< tag::imex_runge_kutta >() );
-
-  if (g_inputdeck.centering() == tk::Centering::ELEM)
-  {
-    print.Item< ctr::Limiter, tag::limiter >();
-
-    print.item("Shock detection based limiting",
-      g_inputdeck.get< tag::shock_detector_coeff >());
-
-    if (g_inputdeck.get< tag::accuracy_test >())
-    {
-      print.item("WARNING: order-of-accuracy testing enabled",
-        "robustness corrections inactive");
-    }
-
-    print.item("Limited solution projection",
-      g_inputdeck.get< tag::limsol_projection >());
-  }
-  print.item( "PE-locality mesh reordering",
-              g_inputdeck.get< tag::pelocal_reorder >() );
-  print.item( "Operator-access mesh reordering",
-              g_inputdeck.get< tag::operator_reorder >() );
-  auto steady = g_inputdeck.get< tag::steady_state >();
-  print.item( "Local time stepping", steady );
-  if (steady) {
-    print.item( "L2-norm residual convergence criterion",
-                g_inputdeck.get< tag::residual >() );
-    print.item( "Convergence criterion component index",
-                g_inputdeck.get< tag::rescomp >() );
-  }
-  print.item( "Number of time steps", nstep );
-  print.item( "Start time", t0 );
-  print.item( "Terminate time", term );
-
-  if (constdt > std::numeric_limits< tk::real >::epsilon())
-    print.item( "Constant time step size", constdt );
-  else if (cfl > std::numeric_limits< tk::real >::epsilon())
-  {
-    print.item( "CFL coefficient", cfl );
-  }
-
-  const auto& meshes = g_inputdeck.get< tag::mesh >();
-  const auto& depvars = g_inputdeck.get< tag::depvar >();
-  for (std::size_t i=0; i<meshes.size(); ++i) {
-    print.item( "Dependent var name and assoc. mesh", std::string{depvars[i]}
-      + " - " + meshes[i].get< tag::filename >() );
-  }
-
-  // Print out info on settings of selected partial differential equations
-  print.pdes( "Partial differential equations integrated", stack.info() );
-
-  // Print out adaptive polynomial refinement configuration
-  if (scheme == ctr::SchemeType::PDG) {
-    print.section( "Polynomial refinement (p-ref)" );
-    print.item( "p-refinement",
-                g_inputdeck.get< tag::pref, tag::pref >() );
-    print.Item< ctr::PrefIndicator, tag::pref, tag::indicator >();
-    print.item( "Max degrees of freedom",
-                g_inputdeck.get< tag::pref, tag::ndofmax >() );
-    print.item( "Tolerance",
-                g_inputdeck.get< tag::pref, tag::tolref >() );
-  }
-
-  // Print out adaptive mesh refinement configuration
-  const auto amr = g_inputdeck.get< tag::amr, tag::amr >();
-  if (amr) {
-    print.section( "Mesh refinement (h-ref)" );
-    auto maxlevels = g_inputdeck.get< tag::amr, tag::maxlevels >();
-    print.item( "Maximum mesh refinement levels", maxlevels );
-    print.Item< ctr::AMRError, tag::amr, tag::error >();
-    auto t0ref = g_inputdeck.get< tag::amr, tag::t0ref >();
-    print.item( "Refinement at t<0 (t0ref)", t0ref );
-    if (t0ref) {
-      const auto& initref = g_inputdeck.get< tag::amr, tag::initial >();
-      print.item( "Initial refinement steps", initref.size() );
-
-      auto eps = std::numeric_limits< tk::real >::epsilon();
-
-      const auto& amr_coord = g_inputdeck.get< tag::amr, tag::coords >();
-      const auto& amr_defcoord = g_inputdeck_defaults.get< tag::amr, tag::coords >();
-
-      auto xminus = amr_coord.get< tag::xminus >();
-      auto xminus_default = amr_defcoord.get< tag::xminus >();
-      if (std::abs( xminus - xminus_default ) > eps)
-        print.item( "Initial refinement x-", xminus );
-      auto xplus = amr_coord.get< tag::xplus >();
-      auto xplus_default = amr_defcoord.get< tag::xplus >();
-      if (std::abs( xplus - xplus_default ) > eps)
-        print.item( "Initial refinement x+", xplus );
-
-      auto yminus = amr_coord.get< tag::yminus >();
-      auto yminus_default = amr_defcoord.get< tag::yminus >();
-      if (std::abs( yminus - yminus_default ) > eps)
-        print.item( "Initial refinement y-", yminus );
-      auto yplus = amr_coord.get< tag::yplus >();
-      auto yplus_default = amr_defcoord.get< tag::yplus >();
-      if (std::abs( yplus - yplus_default ) > eps)
-        print.item( "Initial refinement y+", yplus );
-
-      auto zminus = amr_coord.get< tag::zminus >();
-      auto zminus_default = amr_defcoord.get< tag::zminus >();
-      if (std::abs( zminus - zminus_default ) > eps)
-        print.item( "Initial refinement z-", zminus );
-      auto zplus = amr_coord.get< tag::zplus >();
-      auto zplus_default = amr_defcoord.get< tag::zplus >();
-      if (std::abs( zplus - zplus_default ) > eps)
-        print.item( "Initial refinement z+", zplus );
-    }
-    auto dtref = g_inputdeck.get< tag::amr, tag::dtref >();
-    print.item( "Refinement at t>0 (dtref)", dtref );
-    if (dtref) {
-      auto dtfreq = g_inputdeck.get< tag::amr, tag::dtfreq >();
-      print.item( "Mesh refinement frequency, t>0", dtfreq );
-      print.item( "Uniform-only mesh refinement, t>0",
-                  g_inputdeck.get< tag::amr, tag::dtref_uniform >() );
-    }
-    print.item( "Refinement tolerance",
-                g_inputdeck.get< tag::amr, tag::tol_refine >() );
-    print.item( "De-refinement tolerance",
-                g_inputdeck.get< tag::amr, tag::tol_derefine >() );
-  }
-
-  // Print out ALE configuration
-  const auto ale = g_inputdeck.get< tag::ale, tag::ale >();
-  if (ale) {
-    print.section( "Arbitrary Lagrangian-Eulerian (ALE) mesh motion" );
-    auto dvcfl = g_inputdeck.get< tag::ale, tag::dvcfl >();
-    print.item( "Volume-change CFL coefficient", dvcfl );
-    print.Item< ctr::MeshVelocity, tag::ale, tag::mesh_velocity >();
-    print.Item< ctr::MeshVelocitySmoother, tag::ale, tag::smoother >();
-    print.item( "Mesh motion dimensions", tk::parameters(
-                g_inputdeck.get< tag::ale, tag::mesh_motion >() ) );
-    const auto& meshforce = g_inputdeck.get< tag::ale, tag::meshforce >();
-    print.item( "Mesh velocity force coefficients", tk::parameters(meshforce) );
-    print.item( "Vorticity multiplier",
-                g_inputdeck.get< tag::ale, tag::vortmult >() );
-    print.item( "Mesh velocity linear solver tolerance",
-                g_inputdeck.get< tag::ale, tag::tolerance >() );
-    print.item( "Mesh velocity linear solver maxit",
-                g_inputdeck.get< tag::ale, tag::maxit >() );
-    const auto& dir = g_inputdeck.get< tag::ale, tag::dirichlet >();
-    if (not dir.empty())
-      print.item( "Mesh velocity Dirichlet BC sideset(s)",
-                  tk::parameters( dir ) );
-    const auto& sym = g_inputdeck.get< tag::ale, tag::symmetry >();
-    if (not sym.empty())
-      print.item( "Mesh velocity symmetry BC sideset(s)",
-                  tk::parameters( sym ) );
-    std::size_t i = 1;
-    for (const auto& m : g_inputdeck.get< tag::ale, tag::move >()) {
-       tk::ctr::UserTable opt;
-       print.item( opt.group() + ' ' + std::to_string(i) + " interpreted as",
-                   opt.name( m.get< tag::fntype >() ) );
-       const auto& s = m.get< tag::sideset >();
-       if (not s.empty())
-         print.item( "Moving sideset(s) with table " + std::to_string(i),
-                     tk::parameters(s));
-       ++i;
-    }
-  }
-
-  // Print I/O filenames
-  print.section( "Input/Output filenames and directories" );
-  print.item( "Input mesh(es)", tk::parameters( m_input ) );
-  const auto& of = g_inputdeck.get< tag::cmd, tag::io, tag::output >();
-  print.item( "Volume field output file(s)",
-              of + ".e-s.<meshid>.<numchares>.<chareid>" );
-  print.item( "Surface field output file(s)",
-              of + "-surf.<surfid>.e-s.<meshid>.<numchares>.<chareid>" );
-  print.item( "History output file(s)", of + ".hist.{pointid}" );
-  print.item( "Diagnostics file",
-              g_inputdeck.get< tag::cmd, tag::io, tag::diag >() );
-  print.item( "Checkpoint/restart directory",
-              g_inputdeck.get< tag::cmd, tag::io, tag::restart >() + '/' );
-
-  // Print output intervals
-  print.section( "Output intervals (in units of iteration count)" );
-  print.item( "TTY", g_inputdeck.get< tag::ttyi>() );
-  print.item( "Field and surface",
-              g_inputdeck.get< tag::field_output, tag::interval >() );
-  print.item( "History",
-              g_inputdeck.get< tag::history_output, tag::interval >() );
-  print.item( "Diagnostics",
-              g_inputdeck.get< tag::diagnostics, tag::interval >() );
-  print.item( "Checkpoint/restart",
-              g_inputdeck.get< tag::cmd, tag::rsfreq >() );
-  auto tf = g_inputdeck.get< tag::field_output, tag::time_interval >();
-  auto th = g_inputdeck.get< tag::history_output, tag::time_interval >();
-  if (tf>0.0 || th>0.0) {
-    print.section( "Output intervals (in units of physics time)" );
-    if (tf > 0.0) print.item( "Field and surface", tf );
-    if (th > 0.0) print.item( "History", th );
-  }
-  const auto& rf = g_inputdeck.get< tag::field_output, tag::time_range >();
-  const auto& rh = g_inputdeck.get< tag::history_output, tag::time_range >();
-  if (not rf.empty() or not rh.empty()) {
-    print.section( "Output time ranges (in units of physics time)" );
-    print.item("Field output { mintime, maxtime, dt }", tk::parameters(rf));
-    print.item("History output { mintime, maxtime, dt }", tk::parameters(rh));
-  }
-
-  //// Print output variables: fields and surfaces
-  //const auto nodeoutvars = g_inputdeck.outvars( tk::Centering::NODE );
-  //const auto elemoutvars = g_inputdeck.outvars( tk::Centering::ELEM );
-  //const auto outsets = g_inputdeck.outsets();
-  //if (!nodeoutvars.empty() || !elemoutvars.empty() || !outsets.empty())
-  //   print.section( "Output fields" );
-  //if (!nodeoutvars.empty())
-  //  print.item( "Node field(s)", tk::parameters(nodeoutvars) );
-  //if (!elemoutvars.empty())
-  //  print.item( "Elem field(s)", tk::parameters(elemoutvars) );
-  //if (!aliases.empty())
-  //  print.item( "Alias(es)", tk::parameters(aliases) );
-  //if (!outsets.empty())
-  //  print.item( "Surface side set(s)", tk::parameters(outsets) );
-
-  // Print output variables: history
-  const auto& pt = g_inputdeck.get< tag::history_output, tag::point >();
-  if (!pt.empty()) {
-    print.section( "Output time history" );
-    for (std::size_t p=0; p<pt.size(); ++p) {
-      const auto& id = pt[p].get< tag::id >();
-      std::stringstream ss;
-      auto prec = g_inputdeck.get< tag::history_output, tag::precision >();
-      ss << std::setprecision( static_cast<int>(prec) );
-      ss << of << ".hist." << id;
-      print.longitem( "At point " + id + ' ' +
-        tk::parameters(pt[p].get<tag::coord>()), ss.str() );
-    }
-  }
-
-  print.endsubsection();
-}
-
-bool
-Transporter::matchBCs( std::map< int, std::vector< std::size_t > >& bnd )
-// *****************************************************************************
- // Verify that side sets specified in the control file exist in mesh file
- //! \details This function does two things: (1) it verifies that the side
- //!   sets used in the input file (either to which boundary conditions (BC)
- //!   are assigned or listed as field output by the user in the
- //!   input file) all exist among the side sets read from the input mesh
- //!   file and errors out if at least one does not, and (2) it matches the
- //!   side set ids at which the user has configured BCs (or listed as an output
- //!   surface) to side set ids read from the mesh file and removes those face
- //!   and node lists associated to side sets that the user did not set BCs or
- //!   listed as field output on (as they will not need processing further since
- //!   they will not be used).
- //! \param[in,out] bnd Node or face lists mapped to side set ids
- //! \return True if sidesets have been used and found in mesh
-// *****************************************************************************
-{
-  // Query side set ids at which BCs assigned for all BC types for all PDEs
-  using bclist = ctr::bclist::Keys;
-  std::unordered_set< int > usedsets;
-  brigand::for_each< bclist >( UserBC( g_inputdeck, usedsets ) );
-
-  // Query side sets of time dependent BCs (since tag::bctimedep is not a part
-  // of tag::bc)
-  const auto& bcs = g_inputdeck.get< tag::bc >();
-  for (const auto& bci : bcs) {
-    for (const auto& b : bci.get< tag::timedep >()) {
-      for (auto i : b.get< tag::sideset >())
-        usedsets.insert(static_cast<int>(i));
-    }
-  }
-
-  // Query side sets of boundaries prescribed as moving with ALE
-  for (const auto& move : g_inputdeck.get< tag::ale, tag::move >())
-    for (auto i : move.get< tag::sideset >())
-      usedsets.insert(static_cast<int>(i));
-
-  // Add sidesets requested for field output
-  const auto& ss = g_inputdeck.get< tag::cmd, tag::io, tag::surface >();
-  for (const auto& s : ss) {
-    std::stringstream conv( s );
-    int num;
-    conv >> num;
-    usedsets.insert( num );
-  }
-
-  // Find user-configured side set ids among side sets read from mesh file
-  std::unordered_set< int > sidesets_used;
-  for (auto i : usedsets) {       // for all side sets used in control file
-    if (bnd.find(i) != end(bnd))  // used set found among side sets in file
-      sidesets_used.insert( i );  // store side set id configured as BC
-    //else {
-    //  Throw( "Boundary conditions specified on side set " +
-    //    std::to_string(i) + " which does not exist in mesh file" );
-    //}
-  }
-
-  // Remove sidesets not used (will not process those further)
-  tk::erase_if( bnd, [&]( auto& item ) {
-    return sidesets_used.find( item.first ) == end(sidesets_used);
-  });
-
-  return !bnd.empty();
-}
-
-void
-Transporter::createPartitioner()
-// *****************************************************************************
-// Create mesh partitioner AND boundary conditions group
-// *****************************************************************************
-{
-  auto scheme = g_inputdeck.get< tag::scheme >();
-  auto centering = ctr::Scheme().centering( scheme );
-  auto print = printer();
-
-  // Create partitioner callbacks (order important)
-  tk::PartitionerCallback cbp {{
-      CkCallback( CkReductionTarget(Transporter,load), thisProxy )
-    , CkCallback( CkReductionTarget(Transporter,partitioned), thisProxy )
-    , CkCallback( CkReductionTarget(Transporter,distributed), thisProxy )
-    , CkCallback( CkReductionTarget(Transporter,refinserted), thisProxy )
-    , CkCallback( CkReductionTarget(Transporter,refined), thisProxy )
-  }};
-
-  // Create refiner callbacks (order important)
-  tk::RefinerCallback cbr {{
-      CkCallback( CkReductionTarget(Transporter,queriedRef), thisProxy )
-    , CkCallback( CkReductionTarget(Transporter,respondedRef), thisProxy )
-    , CkCallback( CkReductionTarget(Transporter,compatibility), thisProxy )
-    , CkCallback( CkReductionTarget(Transporter,bndint), thisProxy )
-    , CkCallback( CkReductionTarget(Transporter,matched), thisProxy )
-    , CkCallback( CkReductionTarget(Transporter,refined), thisProxy )
-  }};
-
-  // Create sorter callbacks (order important)
-  tk::SorterCallback cbs {{
-      CkCallback( CkReductionTarget(Transporter,queried), thisProxy )
-    , CkCallback( CkReductionTarget(Transporter,responded), thisProxy )
-    , CkCallback( CkReductionTarget(Transporter,discinserted), thisProxy )
-    , CkCallback( CkReductionTarget(Transporter,workinserted), thisProxy )
-  }};
-
-  // Start timer measuring preparation of mesh(es) for partitioning
-  m_timer[ TimerTag::MESH_READ ];
-
-  // Start preparing mesh(es)
-  print.diag( "Reading mesh(es)" );
-
-  // Create (discretization) Scheme chare worker arrays for all meshes
-  for ([[maybe_unused]] const auto& filename : m_input)
-    m_scheme.emplace_back( g_inputdeck.get< tag::scheme >(),
-                           g_inputdeck.get< tag::ale, tag::ale >(),
-                           need_linearsolver(),
-                           centering );
-
-  ErrChk( !m_input.empty(), "No input mesh" );
-
-  // Read boundary (side set) data from a list of input mesh files
-  std::size_t meshid = 0;
-  for (const auto& filename : m_input) {
-    // Create mesh reader for reading side sets from file
-    tk::MeshReader mr( filename );
-
-    // Read out total number of mesh points from mesh file
-    m_npoin.push_back( mr.npoin() );
-
-    std::map< int, std::vector< std::size_t > > bface;
-    std::map< int, std::vector< std::size_t > > faces;
-    std::map< int, std::vector< std::size_t > > bnode;
-
-    // Read boundary-face connectivity on side sets
-    mr.readSidesetFaces( bface, faces );
-
-    bool bcs_set = false;
-    if (centering == tk::Centering::ELEM) {
-
-      // Verify boundarty condition (BC) side sets used exist in mesh file
-      bcs_set = matchBCs( bface );
-
-    } else if (centering == tk::Centering::NODE) {
-
-      // Read node lists on side sets
-      bnode = mr.readSidesetNodes();
-      // Verify boundarty condition (BC) side sets used exist in mesh file
-      bool bcnode_set = matchBCs( bnode );
-      bool bcface_set = matchBCs( bface );
-      bcs_set = bcface_set or bcnode_set;
-    }
-
-    // Warn on no BCs
-    if (!bcs_set) print << "\n>>> WARNING: No boundary conditions set\n\n";
-
-    auto opt = m_scheme[meshid].arrayoptions();
-    // Create empty mesh refiner chare array (bound to workers)
-    m_refiner.push_back( CProxy_Refiner::ckNew(opt) );
-    // Create empty mesh sorter Charm++ chare array (bound to workers)
-    m_sorter.push_back( CProxy_Sorter::ckNew(opt) );
-
-    // Create MeshWriter chare group for mesh
-    m_meshwriter.push_back(
-      tk::CProxy_MeshWriter::ckNew(
-        g_inputdeck.get< tag::field_output, tag::filetype >(),
-        centering,
-        g_inputdeck.get< tag::cmd, tag::benchmark >(),
-        m_input.size() ) );
-
-    // Create mesh partitioner Charm++ chare nodegroup for all meshes
-    m_partitioner.push_back(
-      CProxy_Partitioner::ckNew( meshid, filename, cbp, cbr, cbs,
-        thisProxy, m_refiner.back(), m_sorter.back(), m_meshwriter.back(),
-        m_scheme, bface, faces, bnode ) );
-
-    ++meshid;
-  }
-}
-
-void
-Transporter::load( std::size_t meshid, std::size_t nelem )
-// *****************************************************************************
-// Reduction target: the mesh has been read from file on all PEs
-//! \param[in] meshid Mesh id (summed accross all compute nodes)
-//! \param[in] nelem Number of mesh elements per mesh (summed across all
-//!    compute nodes)
-// *****************************************************************************
-{
-  meshid /= static_cast< std::size_t >( CkNumNodes() );
-  Assert( meshid < m_nelem.size(), "MeshId indexing out" );
-  m_nelem[meshid] = nelem;
-
-  // Compute load distribution given total work (nelem) and user-specified
-  // virtualization
-  uint64_t chunksize, remainder;
-  m_nchare[meshid] = static_cast<int>(
-    tk::linearLoadDistributor(
-       g_inputdeck.get< tag::cmd, tag::virtualization >(),
-       m_nelem[meshid], CkNumPes(), chunksize, remainder ) );
-
-  // Store sum of meshids (across all chares, key) for each meshid (value).
-  // This is used to look up the mesh id after collectives that sum their data.
-  m_meshid[ static_cast<std::size_t>(m_nchare[meshid])*meshid ] = meshid;
-  Assert( meshid < m_nelem.size(), "MeshId indexing out" );
-
-  // Tell the meshwriter for this mesh the total number of its chares
-  m_meshwriter[meshid].nchare( meshid, m_nchare[meshid] );
-
-  if (++m_nload == m_nelem.size()) {     // all meshes have been loaded
-    m_nload = 0;
-    auto print = printer();
-
-    // Start timer measuring preparation of the mesh for partitioning
-    const auto& timer = tk::cref_find( m_timer, TimerTag::MESH_READ );
-    print.diag( "Mesh read time: " + std::to_string( timer.dsec() ) + " sec" );
-
-    // Print out mesh partitioning configuration
-    print.section( "Mesh partitioning" );
-    print.Item< tk::ctr::PartitioningAlgorithm, tag::partitioning >();
-    print.item( "Virtualization [0.0...1.0]",
-                g_inputdeck.get< tag::cmd, tag::virtualization >() );
-    // Print out initial mesh statistics
-    meshstat( "Initial load distribution" );
-
-    // Query number of initial mesh refinement steps
-    int nref = 0;
-    if (g_inputdeck.get< tag::amr, tag::t0ref >())
-      nref = static_cast<int>(g_inputdeck.get< tag::amr,
-        tag::initial >().size());
-
-    m_progMesh.start( print, "Preparing mesh", {{ CkNumPes(), CkNumPes(), nref,
-      m_nchare[0], m_nchare[0], m_nchare[0], m_nchare[0] }} );
-
-    // Partition first mesh
-    m_partitioner[0].partition( m_nchare[0] );
-  }
-}
-
-void
-Transporter::partitioned( std::size_t meshid )
-// *****************************************************************************
-// Reduction target: a mesh has been partitioned
-//! \param[in] meshid Mesh id
-// *****************************************************************************
-{
-  if (++m_npart == m_nelem.size()) {     // all meshes have been partitioned
-    m_npart = 0;
-  } else { // partition next mesh
-    m_partitioner[meshid+1].partition( m_nchare[meshid+1] );
-  }
-}
-
-void
-Transporter::distributed( std::size_t meshid )
-// *****************************************************************************
-// Reduction target: all compute nodes have distributed their mesh after
-// partitioning
-//! \param[in] meshid Mesh id
-// *****************************************************************************
-{
-  m_partitioner[meshid].refine();
-}
-
-void
-Transporter::refinserted( std::size_t meshid, std::size_t error )
-// *****************************************************************************
-// Reduction target: all compute nodes have created the mesh refiners
-//! \param[in] meshid Mesh id (aggregated across all compute nodes with operator
-//!   max)
-//! \param[in] error Error code (aggregated across all compute nodes with
-//!   operator max)
-// *****************************************************************************
-{
-  if (error) {
-
-    printer() << "\n>>> ERROR: A worker chare was not assigned any mesh "
-              "elements after distributing mesh " + std::to_string(meshid) +
-              ". This can happen in SMP-mode with a large +ppn "
-              "parameter (number of worker threads per logical node) and is "
-              "most likely the fault of the mesh partitioning algorithm not "
-              "tolerating the case when it is asked to divide the "
-              "computational domain into a number of partitions different "
-              "than the number of ranks it is called on, i.e., in case of "
-              "overdecomposition and/or calling the partitioner in SMP mode "
-              "with +ppn larger than 1. Solution 1: Try a different "
-              "partitioning algorithm (e.g., rcb instead of mj). Solution 2: "
-              "Decrease +ppn.";
-    finish( meshid );
-
-  } else {
-
-     m_refiner[meshid].doneInserting();
-
-  }
-}
-
-void
-Transporter::queriedRef( std::size_t meshid )
-// *****************************************************************************
-// Reduction target: all Refiner chares have queried their boundary edges
-//! \param[in] meshid Mesh id
-// *****************************************************************************
-{
-  m_refiner[meshid].response();
-}
-
-void
-Transporter::respondedRef( std::size_t meshid )
-// *****************************************************************************
-// Reduction target: all Refiner chares have setup their boundary edges
-//! \param[in] meshid Mesh id
-// *****************************************************************************
-{
-  m_refiner[meshid].refine();
-}
-
-void
-Transporter::compatibility( std::size_t meshid )
-// *****************************************************************************
-// Reduction target: all Refiner chares have received a round of edges,
-// and have run their compatibility algorithm
-//! \param[in] meshid Mesh id (aggregated across all chares using operator max)
-//! \details This is called iteratively, until convergence by Refiner. At this
-//!   point all Refiner chares have received a round of edge data (tags whether
-//!   an edge needs to be refined, etc.), and applied the compatibility
-//!   algorithm independent of other Refiner chares. We keep going until the
-//!   mesh is no longer modified by the compatibility algorithm, based on a new
-//!   round of edge data communication started in Refiner::comExtra().
-// *****************************************************************************
-{
-  m_refiner[meshid].correctref();
-}
-
-void
-Transporter::matched( std::size_t summeshid,
-                      std::size_t nextra,
-                      std::size_t nref,
-                      std::size_t nderef,
-                      std::size_t sumrefmode )
-// *****************************************************************************
-// Reduction target: all Refiner chares have matched/corrected the tagging
-// of chare-boundary edges, all chares are ready to perform refinement.
-//! \param[in] summeshid Mesh id (summed across all chares)
-//! \param[in] nextra Sum (across all chares) of the number of edges on each
-//!   chare that need correction along chare boundaries
-//! \param[in] nref Sum of number of refined tetrahedra across all chares.
-//! \param[in] nderef Sum of number of derefined tetrahedra across all chares.
-//! \param[in] sumrefmode Sum of contributions from all chares, encoding
-//!   refinement mode of operation.
-// *****************************************************************************
-{
-  auto meshid = tk::cref_find( m_meshid, summeshid );
-
-  // If at least a single edge on a chare still needs correction, do correction,
-  // otherwise, this mesh refinement step is complete
-  if (nextra > 0) {
-
-    ++m_ncit[meshid];
-    m_refiner[meshid].comExtra();
-
-  } else {
-
-    auto print = printer();
-
-    // decode refmode
-    auto refmode = static_cast< Refiner::RefMode >(
-                     sumrefmode / static_cast<std::size_t>(m_nchare[meshid]) );
-
-    if (refmode == Refiner::RefMode::T0REF) {
-
-      if (!g_inputdeck.get< tag::cmd, tag::feedback >()) {
-        ctr::AMRInitial opt;
-        print.diag( { "meshid", "t0ref", "type", "nref", "nderef", "ncorr" },
-                    { std::to_string(meshid),
-                      std::to_string(m_nt0refit[meshid]),
-                      "initial",
-                      std::to_string(nref),
-                      std::to_string(nderef),
-                      std::to_string(m_ncit[meshid]) } );
-        ++m_nt0refit[meshid];
-      }
-      m_progMesh.inc< REFINE >( print );
-
-    } else if (refmode == Refiner::RefMode::DTREF) {
-
-      auto dtref_uni = g_inputdeck.get< tag::amr, tag::dtref_uniform >();
-      print.diag( { "meshid", "dtref", "type", "nref", "nderef", "ncorr" },
-                  { std::to_string(meshid),
-                    std::to_string(++m_ndtrefit[meshid]),
-                    (dtref_uni?"uniform":"error"),
-                    std::to_string(nref),
-                    std::to_string(nderef),
-                    std::to_string(m_ncit[meshid]) },
-                  false );
-
-    } else if (refmode == Refiner::RefMode::OUTREF) {
-
-      print.diag( { "meshid", "outref", "nref", "nderef", "ncorr" },
-                  { std::to_string(meshid),
-                    std::to_string(++m_noutrefit[meshid]),
-                    std::to_string(nref),
-                    std::to_string(nderef),
-                    std::to_string(m_ncit[meshid]) }, false );
-
-    } else if (refmode == Refiner::RefMode::OUTDEREF) {
-
-      print.diag( { "meshid", "outderef", "nref", "nderef", "ncorr" },
-                  { std::to_string(meshid),
-                    std::to_string(++m_noutderefit[meshid]),
-                    std::to_string(nref),
-                    std::to_string(nderef),
-                    std::to_string(m_ncit[meshid]) },
-                  false );
-
-    } else Throw( "RefMode not implemented" );
-
-    m_ncit[meshid] = 0;
-    m_refiner[meshid].perform();
-
-  }
-}
-
-void
-Transporter::bndint( tk::real sx, tk::real sy, tk::real sz, tk::real cb,
-                     tk::real summeshid )
-// *****************************************************************************
-// Compute surface integral across the whole problem and perform leak-test
-//! \param[in] sx X component of vector summed
-//! \param[in] sy Y component of vector summed
-//! \param[in] sz Z component of vector summed
-//! \param[in] cb Invoke callback if positive
-//! \param[in] summeshid Mesh id (summed accross all chares)
-//! \details This function aggregates partial surface integrals across the
-//!   boundary faces of the whole problem. After this global sum a
-//!   non-zero vector result indicates a leak, e.g., a hole in the boundary,
-//!   which indicates an error in the boundary face data structures used to
-//!   compute the partial surface integrals.
-// *****************************************************************************
-{
-  auto meshid = tk::cref_find( m_meshid, static_cast<std::size_t>(summeshid) );
-
-  std::stringstream err;
-  if (cb < 0.0) {
-    err << "Mesh boundary leaky after mesh refinement step; this is due to a "
-     "problem with updating the side sets used to specify boundary conditions "
-     "on faces: ";
-  } else if (cb > 0.0) {
-    err << "Mesh boundary leaky during initialization; this is due to "
-    "incorrect or incompletely specified boundary conditions for a given input "
-    "mesh: ";
-  }
-
-  auto eps = 1.0e-10;
-  if (std::abs(sx) > eps || std::abs(sy) > eps || std::abs(sz) > eps) {
-    err << "Integral result must be a zero vector: " << std::setprecision(12) <<
-           std::abs(sx) << ", " << std::abs(sy) << ", " << std::abs(sz) <<
-           ", eps = " << eps;
-    Throw( err.str() );
-  }
-
-  if (cb > 0.0) m_scheme[meshid].ghosts().resizeComm();
-}
-
-void
-Transporter::refined( std::size_t summeshid,
-                      std::size_t nelem,
-                      std::size_t npoin )
-// *****************************************************************************
-// Reduction target: all chares have refined their mesh
-//! \param[in] summeshid Mesh id (summed accross all Refiner chares)
-//! \param[in] nelem Total number of elements in mesh summed across the
-//!   distributed mesh
-//! \param[in] npoin Total number of mesh points summed across the distributed
-//!   mesh. Note that in parallel this is larger than the number of points in
-//!   the mesh, because the boundary nodes are multi-counted. But we only need
-//!   an equal or larger than npoin for Sorter::setup, so this is okay.
-// *****************************************************************************
-{
-  auto meshid = tk::cref_find( m_meshid, summeshid );
-
-  // Store new number of elements for initially refined mesh
-  m_nelem[meshid] = nelem;
-
-  m_sorter[meshid].doneInserting();
-  m_sorter[meshid].setup( npoin );
-}
-
-void
-Transporter::queried( std::size_t meshid )
-// *****************************************************************************
-// Reduction target: all Sorter chares have queried their boundary edges
-//! \param[in] meshid Mesh id
-// *****************************************************************************
-{
-  m_sorter[meshid].response();
-}
-
-void
-Transporter::responded( std::size_t meshid )
-// *****************************************************************************
-// Reduction target: all Sorter chares have responded with their boundary edges
-//! \param[in] meshid Mesh id
-// *****************************************************************************
-{
-  m_sorter[meshid].start();
-}
-
-void
-Transporter::resized( std::size_t meshid )
-// *****************************************************************************
-// Reduction target: all worker chares have resized their own mesh data after
-// AMR or ALE
-//! \param[in] meshid Mesh id
-//! \note Only used for nodal schemes
-// *****************************************************************************
-{
-  m_scheme[meshid].disc().vol();
-  m_scheme[meshid].bcast< Scheme::lhs >();
-}
-
-void
-Transporter::startEsup( std::size_t meshid )
-// *****************************************************************************
-// Reduction target: all worker chares have generated their own esup
-//! \param[in] meshid Mesh id
-//! \note Only used for cell-centered schemes
-// *****************************************************************************
-{
-  m_scheme[meshid].ghosts().nodeNeighSetup();
-}
-
-void
-Transporter::discinserted( std::size_t meshid )
-// *****************************************************************************
-// Reduction target: all Discretization chares have been inserted
-//! \param[in] meshid Mesh id
-// *****************************************************************************
-{
-  m_scheme[meshid].disc().doneInserting();
-}
-
-void
-Transporter::meshstat( const std::string& header ) const
-// *****************************************************************************
-// Print out mesh statistics
-//! \param[in] header Section header
-// *****************************************************************************
-{
-  auto print = printer();
-
-  print.section( header );
-
-  if (m_nelem.size() > 1) {
-    print.item( "Number of tetrahedra (per mesh)",tk::parameters(m_nelem) );
-    print.item( "Number of points (per mesh)", tk::parameters(m_npoin) );
-    print.item( "Number of work units (per mesh)", tk::parameters(m_nchare) );
-  }
-
-  print.item( "Total number of tetrahedra",
-              std::accumulate( begin(m_nelem), end(m_nelem), 0UL ) );
-  print.item( "Total number of points",
-              std::accumulate( begin(m_npoin), end(m_npoin), 0UL ) );
-  print.item( "Total number of work units",
-              std::accumulate( begin(m_nchare), end(m_nchare), 0 ) );
-
-  print.endsubsection();
-}
-
-bool
-Transporter::need_linearsolver() const
-// *****************************************************************************
-//  Decide if we need a linear solver for ALE
-//! \return True if ALE will neeed a linear solver
-// *****************************************************************************
-{
-  auto smoother = g_inputdeck.get< tag::ale, tag::smoother >();
-
-  if ( g_inputdeck.get< tag::ale, tag::ale >() and
-       (smoother == ctr::MeshVelocitySmootherType::LAPLACE ||
-        smoother == ctr::MeshVelocitySmootherType::HELMHOLTZ) )
-  {
-     return true;
-  } else {
-     return false;
-  }
-}
-
-void
-Transporter::disccreated( std::size_t summeshid, std::size_t npoin )
-// *****************************************************************************
-// Reduction target: all Discretization constructors have been called
-//! \param[in] summeshid Mesh id (summed accross all chares)
-//! \param[in] npoin Total number of mesh points (summed across all chares)
-//!  Note that as opposed to npoin in refined(), this npoin is not
-//!  multi-counted, and thus should be correct in parallel.
-// *****************************************************************************
-{
-  auto meshid = tk::cref_find( m_meshid, summeshid );
-  //std::cout << "Trans: " << meshid << " Transporter::disccreated()\n";
-
-  // Update number of mesh points for mesh, since it may have been refined
-  if (g_inputdeck.get< tag::amr, tag::t0ref >()) m_npoin[meshid] = npoin;
-
-  if (++m_ndisc == m_nelem.size()) { // all Disc arrays have been created
-    m_ndisc = 0;
-    auto print = printer();
-    m_progMesh.end( print );
-    if (g_inputdeck.get< tag::amr, tag::t0ref >())
-      meshstat( "Initially (t<0) refined mesh graph statistics" );
-  }
-
-  m_refiner[meshid].sendProxy();
-
-  if (g_inputdeck.get< tag::ale, tag::ale >())
-    m_scheme[meshid].ale().doneInserting();
-
-  if (need_linearsolver())
-    m_scheme[meshid].conjugategradients().doneInserting();
-
-  m_scheme[meshid].disc().vol();
-}
-
-void
-Transporter::workinserted( std::size_t meshid )
-// *****************************************************************************
-// Reduction target: all worker (derived discretization) chares have been
-// inserted
-//! \param[in] meshid Mesh id
-// *****************************************************************************
-{
-  m_scheme[meshid].bcast< Scheme::doneInserting >();
-}
-
-void
-Transporter::diagHeader()
-// *****************************************************************************
-// Configure and write diagnostics file header
-// *****************************************************************************
-{
-  for (std::size_t m=0; m<m_input.size(); ++m) {
-
-   // Output header for diagnostics output file
-    auto mid = m_input.size() > 1 ? std::string( '.' + std::to_string(m) ) : "";
-    tk::DiagWriter dw( g_inputdeck.get< tag::cmd, tag::io, tag::diag >() + mid,
-      g_inputdeck.get< tag::diagnostics, tag::format >(),
-      g_inputdeck.get< tag::diagnostics, tag::precision >() );
-
-    // Collect variables names for integral/diagnostics output
-    std::vector< std::string > var;
-    const auto scheme = g_inputdeck.get< tag::scheme >();
-    if ( scheme == ctr::SchemeType::ALECG ||
-         scheme == ctr::SchemeType::OversetFE )
-      for (const auto& eq : g_cgpde) varnames( eq, var );
-    else if ( scheme == ctr::SchemeType::DG ||
-              scheme == ctr::SchemeType::P0P1 ||
-              scheme == ctr::SchemeType::DGP1 ||
-              scheme == ctr::SchemeType::DGP2 ||
-              scheme == ctr::SchemeType::PDG )
-      for (const auto& eq : g_dgpde) varnames( eq, var );
-    else if (scheme == ctr::SchemeType::FV)
-      for (const auto& eq : g_fvpde) varnames( eq, var );
-    else Throw( "Diagnostics header not handled for discretization scheme" );
-
-    const tk::ctr::Error opt;
-    auto nv = var.size() / m_input.size();
-    std::vector< std::string > d;
-
-    // Add 'L2(var)' for all variables as those are always computed
-    const auto& l2name = opt.name( tk::ctr::ErrorType::L2 );
-    for (std::size_t i=0; i<nv; ++i) d.push_back( l2name + '(' + var[i] + ')' );
-
-    // Query user-requested diagnostics and augment diagnostics file header by
-    // 'err(var)', where 'err' is the error type  configured, and var is the
-    // variable computed, for all variables and all error types configured.
-    const auto& err = g_inputdeck.get< tag::diagnostics, tag::error >();
-    const auto& errname = opt.name( err );
-    for (std::size_t i=0; i<nv; ++i)
-      d.push_back( errname + '(' + var[i] + "-IC)" );
-
-    // Augment diagnostics variables by L2-norm of the residual and total energy
-    if ( scheme == ctr::SchemeType::ALECG ||
-         scheme == ctr::SchemeType::OversetFE ||
-         scheme == ctr::SchemeType::FV )
-    {
-      for (std::size_t i=0; i<nv; ++i) d.push_back( "L2(d" + var[i] + ')' );
-    }
-    d.push_back( "mE" );
-
-    // Write diagnostics header
-    dw.header( d );
-
-  }
-}
-
-void
-Transporter::doneInsertingGhosts(std::size_t meshid)
-// *****************************************************************************
-// Reduction target indicating all "ghosts" insertions are done
-//! \param[in] meshid Mesh id
-// *****************************************************************************
-{
-  m_scheme[meshid].ghosts().doneInserting();
-  m_scheme[meshid].ghosts().startCommSetup();
-}
-
-void
-Transporter::comfinal( std::size_t initial, std::size_t summeshid )
-// *****************************************************************************
-// Reduction target indicating that communication maps have been setup
-//! \param[in] initial Sum of contributions from all chares. If larger than
-//!    zero, we are during time stepping and if zero we are during setup.
-//! \param[in] summeshid Mesh id (summed accross the distributed mesh)
-// *****************************************************************************
-// [Discretization-specific communication maps]
-{
-  auto meshid = tk::cref_find( m_meshid, static_cast<std::size_t>(summeshid) );
-
-  if (initial > 0) {
-    m_scheme[meshid].bcast< Scheme::setup >();
-    // Turn on automatic load balancing
-    if (++m_ncom == m_nelem.size()) { // all worker arrays have finished
-      m_ncom = 0;
-      auto print = printer();
-      m_progWork.end( print );
-      tk::CProxy_LBSwitch::ckNew();
-      print.diag( "Load balancing on (if enabled in Charm++)" );
-    }
-  } else {
-    m_scheme[meshid].bcast< Scheme::lhs >();
-  }
-}
-// [Discretization-specific communication maps]
-
-void
-Transporter::totalvol( tk::real v, tk::real initial, tk::real summeshid )
-// *****************************************************************************
-// Reduction target summing total mesh volume across all workers
-//! \param[in] v Mesh volume summed across the distributed mesh
-//! \param[in] initial Sum of contributions from all chares. If larger than
-//!    zero, we are during setup, if zero, during time stepping.
-//! \param[in] summeshid Mesh id (summed accross the distributed mesh)
-// *****************************************************************************
-{
-  auto meshid = tk::cref_find( m_meshid, static_cast<std::size_t>(summeshid) );
-
-  m_meshvol[meshid] = v;
-
-  if (initial > 0.0)   // during initialization
-    m_scheme[meshid].disc().stat( v );
-  else                  // during ALE or AMR
-    m_scheme[meshid].bcast< Scheme::resized >();
-}
-
-void
-Transporter::minstat( tk::real d0, tk::real d1, tk::real d2, tk::real rmeshid )
-// *****************************************************************************
-// Reduction target yielding minimum mesh statistcs across all workers
-//! \param[in] d0 Minimum mesh statistics collected over all chares
-//! \param[in] d1 Minimum mesh statistics collected over all chares
-//! \param[in] d2 Minimum mesh statistics collected over all chares
-//! \param[in] rmeshid Mesh id as a real
-// *****************************************************************************
-{
-  auto meshid = static_cast<std::size_t>(rmeshid);
-
-  m_minstat[meshid][0] = d0;  // minimum edge length
-  m_minstat[meshid][1] = d1;  // minimum cell volume cubic root
-  m_minstat[meshid][2] = d2;  // minimum number of cells on chare
-
-  minstat_complete(meshid);
-}
-
-void
-Transporter::maxstat( tk::real d0, tk::real d1, tk::real d2, tk::real rmeshid )
-// *****************************************************************************
-// Reduction target yielding the maximum mesh statistics across all workers
-//! \param[in] d0 Maximum mesh statistics collected over all chares
-//! \param[in] d1 Maximum mesh statistics collected over all chares
-//! \param[in] d2 Maximum mesh statistics collected over all chares
-//! \param[in] rmeshid Mesh id as a real
-// *****************************************************************************
-{
-  auto meshid = static_cast<std::size_t>(rmeshid);
-
-  m_maxstat[meshid][0] = d0;  // maximum edge length
-  m_maxstat[meshid][1] = d1;  // maximum cell volume cubic root
-  m_maxstat[meshid][2] = d2;  // maximum number of cells on chare
-
-  maxstat_complete(meshid);
-}
-
-void
-Transporter::sumstat( tk::real d0, tk::real d1, tk::real d2, tk::real d3,
-                      tk::real d4, tk::real d5, tk::real summeshid )
-// *****************************************************************************
-// Reduction target yielding the sum mesh statistics across all workers
-//! \param[in] d0 Sum mesh statistics collected over all chares
-//! \param[in] d1 Sum mesh statistics collected over all chares
-//! \param[in] d2 Sum mesh statistics collected over all chares
-//! \param[in] d3 Sum mesh statistics collected over all chares
-//! \param[in] d4 Sum mesh statistics collected over all chares
-//! \param[in] d5 Sum mesh statistics collected over all chares
-//! \param[in] summeshid Mesh id (summed accross the distributed mesh)
-// *****************************************************************************
-{
-  auto meshid = tk::cref_find( m_meshid, static_cast<std::size_t>(summeshid) );
-
-  m_avgstat[meshid][0] = d1 / d0;      // average edge length
-  m_avgstat[meshid][1] = d3 / d2;      // average cell volume cubic root
-  m_avgstat[meshid][2] = d5 / d4;      // average number of cells per chare
-
-  sumstat_complete(meshid);
-}
-
-void
-Transporter::pdfstat( CkReductionMsg* msg )
-// *****************************************************************************
-// Reduction target yielding PDF of mesh statistics across all workers
-//! \param[in] msg Serialized PDF
-// *****************************************************************************
-{
-  std::size_t meshid;
-  std::vector< tk::UniPDF > pdf;
-
-  // Deserialize final PDF
-  PUP::fromMem creator( msg->getData() );
-  creator | meshid;<--- Uninitialized variable: meshid
-  creator | pdf;
-  delete msg;
-
-  auto id = std::to_string(meshid);<--- Uninitialized variable: meshid
-
-  // Create new PDF file (overwrite if exists)
-  tk::PDFWriter pdfe( "mesh_edge_pdf." + id + ".txt" );
-  // Output edgelength PDF
-  // cppcheck-suppress containerOutOfBounds
-  pdfe.writeTxt( pdf[0],
-                 tk::ctr::PDFInfo{ {"PDF"}, {}, {"edgelength"}, 0, 0.0 } );
-
-  // Create new PDF file (overwrite if exists)
-  tk::PDFWriter pdfv( "mesh_vol_pdf." + id + ".txt" );
-  // Output cell volume cubic root PDF
-  pdfv.writeTxt( pdf[1],<--- Access out of bounds
-                 tk::ctr::PDFInfo{ {"PDF"}, {}, {"V^{1/3}"}, 0, 0.0 } );
-
-  // Create new PDF file (overwrite if exists)
-  tk::PDFWriter pdfn( "mesh_ntet_pdf." + id + ".txt" );
-  // Output number of cells PDF
-  pdfn.writeTxt( pdf[2],<--- Access out of bounds
-                 tk::ctr::PDFInfo{ {"PDF"}, {}, {"ntets"}, 0, 0.0 } );
-
-  pdfstat_complete(meshid);
-}
-
-void
-Transporter::stat()
-// *****************************************************************************
-// Echo diagnostics on mesh statistics
-// *****************************************************************************
-{
-  auto print = printer();
-
-  if (++m_nstat == m_nelem.size()) {     // stats from all meshes have arrived
-    m_nstat = 0;
-    for (std::size_t i=0; i<m_nelem.size(); ++i) {
-      print.diag(
-        "Mesh " + std::to_string(i) +
-        " distribution statistics: min/max/avg(edgelength) = " +
-        std::to_string( m_minstat[i][0] ) + " / " +
-        std::to_string( m_maxstat[i][0] ) + " / " +
-        std::to_string( m_avgstat[i][0] ) + ", " +
-        "min/max/avg(V^{1/3}) = " +
-        std::to_string( m_minstat[i][1] ) + " / " +
-        std::to_string( m_maxstat[i][1] ) + " / " +
-        std::to_string( m_avgstat[i][1] ) + ", " +
-        "min/max/avg(ntets) = " +
-        std::to_string( static_cast<std::size_t>(m_minstat[i][2]) ) + " / " +
-        std::to_string( static_cast<std::size_t>(m_maxstat[i][2]) ) + " / " +
-        std::to_string( static_cast<std::size_t>(m_avgstat[i][2]) ) );
-    }
-
-    // Print out time integration header to screen
-    inthead( print );
-
-    m_progWork.start( print, "Preparing workers",
-      {{ m_nchare[0], m_nchare[0], m_nchare[0], m_nchare[0], m_nchare[0] }} );
-
-    // Create "derived-class" workers
-    for (std::size_t i=0; i<m_nelem.size(); ++i) m_sorter[i].createWorkers();
-  }
-}
-
-void
-Transporter::boxvol( tk::real* meshdata, int n )
-// *****************************************************************************
-// Reduction target computing total volume of IC mesh blocks and box
-//! \param[in] meshdata Vector containing volumes of all IC mesh blocks,
-//!   volume of IC box, and mesh id as a real summed across the distributed mesh
-//! \param[in] n Size of vector, automatically computed by Charm
-// *****************************************************************************
-{
-  Assert(n>=2, "mesh data size incorrect");
-
-  // extract summed mesh id from vector
-  tk::real summeshid = meshdata[n-1];
-  auto meshid = tk::cref_find( m_meshid, static_cast<std::size_t>(summeshid) );
-
-  // extract summed box volume from vector
-  tk::real v = meshdata[n-2];
-  if (v > 0.0) printer().diag( "Box IC volume: " + std::to_string(v) );
-
-  // extract summed mesh block volumes from the vector
-  std::vector< tk::real > blockvols;
-  for (std::size_t blid=0; blid<(static_cast<std::size_t>(n)-2); ++blid) {
-    blockvols.push_back(meshdata[blid]);
-    if (blockvols[blid] > 0.0)
-      printer().diag( "Mesh block " + std::to_string(blid) +
-        " discrete volume: " + std::to_string(blockvols[blid]) );
-  }
-
-  m_scheme[meshid].bcast< Scheme::box >( v, blockvols );
-}
-
-void
-Transporter::solutionTransferred()
-// *****************************************************************************
-// Reduction target broadcasting to Schemes after mesh transfer
-// *****************************************************************************
-{
-  if (++m_ntrans == m_nelem.size()) {    // all meshes have been loaded
-    m_ntrans = 0;
-    for (auto& m : m_scheme) m.bcast< Scheme::transferSol >();
-  }
-}
-
-void
-Transporter::minDtAcrossMeshes( tk::real* reducndata, [[maybe_unused]] int n )
-// *****************************************************************************
-// Reduction target that computes minimum timestep across all meshes
-//! \param[in] reducndata Vector containing minimum values of dt and mesh-moved
-//!   flags, collected across all meshes
-//! \param[in] n Size of vector, automatically computed by Charm
-// *****************************************************************************
-{
-  Assert(static_cast<std::size_t>(n-1) == m_nelem.size(),
-    "Incorrectly sized reduction vector");
-  m_dtmsh.push_back(reducndata[0]);
-
-  if (++m_ndtmsh == m_nelem.size()) {    // all meshes have been loaded
-    Assert(m_dtmsh.size() == m_nelem.size(), "Incorrect size of dtmsh");
-
-    // compute minimum dt across meshes
-    tk::real dt = std::numeric_limits< tk::real >::max();
-    for (auto idt : m_dtmsh) dt = std::min(dt, idt);
-
-    // clear dt-vector and counter
-    m_dtmsh.clear();
-    m_ndtmsh = 0;
-
-    // broadcast to advance time step
-    std::size_t ic(0);
-    for (auto& m : m_scheme) {
-      m.bcast< Scheme::advance >( dt, reducndata[ic+1] );
-      ++ic;
-    }
-  }
-}
-
-void
-Transporter::inthead( const InciterPrint& print )
-// *****************************************************************************
-// Print out time integration header to screen
-//! \param[in] print Pretty printer object to use for printing
-// *****************************************************************************
-{
-  auto refined = g_inputdeck.get< tag::field_output, tag::refined >();
-  const auto scheme = g_inputdeck.get< tag::scheme >();
-  if (refined && scheme == ctr::SchemeType::DG) {
-    printer() << "\n>>> WARNING: Ignoring refined field output for DG(P0)\n\n";
-    refined = false;
-  }
-
-  print.inthead( "Time integration", "Navier-Stokes solver",
-  "Legend: it - iteration count\n"
-  "         t - physics time\n"
-  "        dt - physics time step size\n"
-  "       ETE - estimated wall-clock time elapsed (h:m:s)\n"
-  "       ETA - estimated wall-clock time for accomplishment (h:m:s)\n"
-  "       EGT - estimated grind wall-clock time (ms/timestep)\n"
-  "       flg - status flags, legend:\n"
-  "             f - " + std::string(refined ? "refined " : "")
-                      + "field (volume and surface)\n"
-  "             d - diagnostics\n"
-  "             t - physics time history\n"
-  "             h - h-refinement\n"
-  "             l - load balancing\n"
-  "             r - checkpoint\n"
-  "             a - ALE mesh velocity linear solver did not converge\n",
-  "\n      it             t            dt        ETE        ETA        EGT  flg\n"
-    " -------------------------------------------------------------------------\n" );
-}
-
-void
-Transporter::diagnostics( CkReductionMsg* msg )
-// *****************************************************************************
-// Reduction target optionally collecting diagnostics, e.g., residuals
-//! \param[in] msg Serialized diagnostics vector aggregated across all PEs
-//! \note Only used for nodal schemes
-// *****************************************************************************
-{
-  std::size_t meshid, ncomp;
-  std::vector< std::vector< tk::real > > d;
-
-  // Deserialize diagnostics vector
-  PUP::fromMem creator( msg->getData() );
-  creator | meshid;<--- Uninitialized variable: meshid
-  creator | ncomp;<--- Uninitialized variable: ncomp
-  creator | d;
-  delete msg;
-
-  auto id = std::to_string(meshid);<--- Uninitialized variable: meshid<--- Variable 'id' is assigned a value that is never used.
-
-  Assert( ncomp > 0, "Number of scalar components must be positive");<--- Uninitialized variable: ncomp
-  Assert( d.size() == NUMDIAG, "Diagnostics vector size mismatch" );
-
-  for (std::size_t i=0; i<d.size(); ++i)<--- Unsigned less than zero
-     Assert( d[i].size() == ncomp, "Size mismatch at final stage of "
-             "diagnostics aggregation for mesh " + id );
-
-  // Allocate storage for those diagnostics that are always computed
-  std::vector< tk::real > diag( ncomp, 0.0 );
-
-  // Finish computing diagnostics
-  for (std::size_t i=0; i<d[L2SOL].size(); ++i)
-    diag[i] = sqrt( d[L2SOL][i] / m_meshvol[meshid] );<--- Uninitialized variable: meshid
-  
-  // Query user-requested error types to output
-  const auto& error = g_inputdeck.get< tag::diagnostics, tag::error >();
-
-  decltype(ncomp) n = 0;<--- Variable 'n' is assigned a value that is never used.
-  n += ncomp;<--- Variable 'n' is assigned a value that is never used.
-  if (error == tk::ctr::ErrorType::L2) {
-   // Finish computing the L2 norm of the numerical - analytical solution
-   for (std::size_t i=0; i<d[L2ERR].size(); ++i)
-     diag.push_back( sqrt( d[L2ERR][i] / m_meshvol[meshid] ) );<--- Uninitialized variable: meshid
-  } else if (error == tk::ctr::ErrorType::LINF) {
-    // Finish computing the Linf norm of the numerical - analytical solution
-    for (std::size_t i=0; i<d[LINFERR].size(); ++i)
-      diag.push_back( d[LINFERR][i] );
-  }
-
-  // Finish computing the L2 norm of the residual and append
-  const auto scheme = g_inputdeck.get< tag::scheme >();
-  std::vector< tk::real > l2res( d[L2RES].size(), 0.0 );
-  if (scheme == ctr::SchemeType::ALECG || scheme == ctr::SchemeType::OversetFE) {
-    for (std::size_t i=0; i<d[L2RES].size(); ++i) {
-      l2res[i] = std::sqrt( d[L2RES][i] / m_meshvol[meshid] );<--- Uninitialized variable: meshid
-      diag.push_back( l2res[i] );
-    }
-  }
-  else if (scheme == ctr::SchemeType::FV) {
-    for (std::size_t i=0; i<d[L2RES].size(); ++i) {
-      l2res[i] = std::sqrt( d[L2RES][i] );
-      diag.push_back( l2res[i] );
-    }
-  }
-
-  // Append total energy
-  diag.push_back( d[TOTALSOL][0] );
-
-  // Append diagnostics file at selected times
-  auto filename = g_inputdeck.get< tag::cmd, tag::io, tag::diag >();
-  if (m_nelem.size() > 1) filename += '.' + id;
-  tk::DiagWriter dw( filename,
-    g_inputdeck.get< tag::diagnostics, tag::format >(),
-    g_inputdeck.get< tag::diagnostics, tag::precision >(),
-    std::ios_base::app );
-  dw.diag( static_cast<uint64_t>(d[ITER][0]), d[TIME][0], d[DT][0], diag );
-
-  // Continue time step
-  m_scheme[meshid].bcast< Scheme::refine >( l2res );<--- Uninitialized variable: meshid
-}
-
-void
-Transporter::resume()
-// *****************************************************************************
-// Resume execution from checkpoint/restart files
-//! \details This is invoked by Charm++ after the checkpoint is done, as well as
-//!   when the restart (returning from a checkpoint) is complete
-// *****************************************************************************
-{
-  if (std::any_of(begin(m_finished), end(m_finished), [](auto f){return !f;})) {
-    // If just restarted from a checkpoint, Main( CkMigrateMessage* msg ) has
-    // increased nrestart in g_inputdeck, but only on PE 0, so broadcast.
-    auto nrestart = g_inputdeck.get< tag::cmd, tag::io, tag::nrestart >();
-    for (std::size_t i=0; i<m_nelem.size(); ++i)
-      m_scheme[i].bcast< Scheme::evalLB >( nrestart );
-  } else
-    mainProxy.finalize();
-}
-
-void
-Transporter::checkpoint( std::size_t finished, std::size_t meshid )
-// *****************************************************************************
-// Save checkpoint/restart files
-//! \param[in] finished Nonzero if finished with time stepping
-//! \param[in] meshid Mesh id
-// *****************************************************************************
-{
-  m_finished[meshid] = finished;
-
-  if (++m_nchk == m_nelem.size()) { // all worker arrays have checkpointed
-    m_nchk = 0;
-    if (not g_inputdeck.get< tag::cmd, tag::benchmark >()) {
-      const auto& restart = g_inputdeck.get< tag::cmd, tag::io, tag::restart >();
-      CkCallback res( CkIndex_Transporter::resume(), thisProxy );
-      CkStartCheckpoint( restart.c_str(), res );
-    } else {
-      resume();
-    }
-  }
-}
-
-void
-Transporter::finish( std::size_t meshid )
-// *****************************************************************************
-// Normal finish of time stepping
-//! \param[in] meshid Mesh id
-// *****************************************************************************
-{
-  checkpoint( /* finished = */ 1, meshid );
-}
-
-#include "NoWarning/transporter.def.h"
+    const auto& bcoutlet =
+      ib.get< tag::outlet >();
+    if (!bcoutlet.empty())
+      nfo.emplace_back( "Outlet boundary [" + std::to_string( ncomp ) + "]",
+        parameters( bcoutlet ) );
+
+    const auto& bcextrapolate =
+      ib.get< tag::extrapolate >();
+    if (!bcextrapolate.empty())
+      nfo.emplace_back( "Symmetry boundary [" + std::to_string( ncomp ) + "]",
+        parameters( bcextrapolate ) );
+  }
+
+  return nfo;
+}
+
+}  // inciter::
 
diff --git a/Debug/cppcheck/65.html b/Debug/cppcheck/65.html index 105cf45ab643..d7fec30649d2 100644 --- a/Debug/cppcheck/65.html +++ b/Debug/cppcheck/65.html @@ -152,2031 +152,997 @@
- - + @@ -129,7 +129,7 @@ - + diff --git a/Debug/test_coverage/Base/Vector.hpp.gcov.html b/Debug/test_coverage/Base/Vector.hpp.gcov.html index ee5ca7a795de..259580395926 100644 --- a/Debug/test_coverage/Base/Vector.hpp.gcov.html +++ b/Debug/test_coverage/Base/Vector.hpp.gcov.html @@ -27,18 +27,18 @@ - + - + - + - + - + @@ -52,9 +52,9 @@ - + - +
   1
-   2
-   3
-   4
-   5
-   6
-   7
-   8
-   9
-  10
-  11
-  12
-  13
-  14
-  15
-  16
-  17
-  18
-  19
-  20
-  21
-  22
-  23
-  24
-  25
-  26
-  27
-  28
-  29
-  30
-  31
-  32
-  33
-  34
-  35
-  36
-  37
-  38
-  39
-  40
-  41
-  42
-  43
-  44
-  45
-  46
-  47
-  48
-  49
-  50
-  51
-  52
-  53
-  54
-  55
-  56
-  57
-  58
-  59
-  60
-  61
-  62
-  63
-  64
-  65
-  66
-  67
-  68
-  69
-  70
-  71
-  72
-  73
-  74
-  75
-  76
-  77
-  78
-  79
-  80
-  81
-  82
-  83
-  84
-  85
-  86
-  87
-  88
-  89
-  90
-  91
-  92
-  93
-  94
-  95
-  96
-  97
-  98
-  99
- 100
- 101
- 102
- 103
- 104
- 105
- 106
- 107
- 108
- 109
- 110
- 111
- 112
- 113
- 114
- 115
- 116
- 117
- 118
- 119
- 120
- 121
- 122
- 123
- 124
- 125
- 126
- 127
- 128
- 129
- 130
- 131
- 132
- 133
- 134
- 135
- 136
- 137
- 138
- 139
- 140
- 141
- 142
- 143
- 144
- 145
- 146
- 147
- 148
- 149
- 150
- 151
- 152
- 153
- 154
- 155
- 156
- 157
- 158
- 159
- 160
- 161
- 162
- 163
- 164
- 165
- 166
- 167
- 168
- 169
- 170
- 171
- 172
- 173
- 174
- 175
- 176
- 177
- 178
- 179
- 180
- 181
- 182
- 183
- 184
- 185
- 186
- 187
- 188
- 189
- 190
- 191
- 192
- 193
- 194
- 195
- 196
- 197
- 198
- 199
- 200
- 201
- 202
- 203
- 204
- 205
- 206
- 207
- 208
- 209
- 210
- 211
- 212
- 213
- 214
- 215
- 216
- 217
- 218
- 219
- 220
- 221
- 222
- 223
- 224
- 225
- 226
- 227
- 228
- 229
- 230
- 231
- 232
- 233
- 234
- 235
- 236
- 237
- 238
- 239
- 240
- 241
- 242
- 243
- 244
- 245
- 246
- 247
- 248
- 249
- 250
- 251
- 252
- 253
- 254
- 255
- 256
- 257
- 258
- 259
- 260
- 261
- 262
- 263
- 264
- 265
- 266
- 267
- 268
- 269
- 270
- 271
- 272
- 273
- 274
- 275
- 276
- 277
- 278
- 279
- 280
- 281
- 282
- 283
- 284
- 285
- 286
- 287
- 288
- 289
- 290
- 291
- 292
- 293
- 294
- 295
- 296
- 297
- 298
- 299
- 300
- 301
- 302
- 303
- 304
- 305
- 306
- 307
- 308
- 309
- 310
- 311
- 312
- 313
- 314
- 315
- 316
- 317
- 318
- 319
- 320
- 321
- 322
- 323
- 324
- 325
- 326
- 327
- 328
- 329
- 330
- 331
- 332
- 333
- 334
- 335
- 336
- 337
- 338
- 339
- 340
- 341
- 342
- 343
- 344
- 345
- 346
- 347
- 348
- 349
- 350
- 351
- 352
- 353
- 354
- 355
- 356
- 357
- 358
- 359
- 360
- 361
- 362
- 363
- 364
- 365
- 366
- 367
- 368
- 369
- 370
- 371
- 372
- 373
- 374
- 375
- 376
- 377
- 378
- 379
- 380
- 381
- 382
- 383
- 384
- 385
- 386
- 387
- 388
- 389
- 390
- 391
- 392
- 393
- 394
- 395
- 396
- 397
- 398
- 399
- 400
- 401
- 402
- 403
- 404
- 405
- 406
- 407
- 408
- 409
- 410
- 411
- 412
- 413
- 414
- 415
- 416
- 417
- 418
- 419
- 420
- 421
- 422
- 423
- 424
- 425
- 426
- 427
- 428
- 429
- 430
- 431
- 432
- 433
- 434
- 435
- 436
- 437
- 438
- 439
- 440
- 441
- 442
- 443
- 444
- 445
- 446
- 447
- 448
- 449
- 450
- 451
- 452
- 453
- 454
- 455
- 456
- 457
- 458
- 459
- 460
- 461
- 462
- 463
- 464
- 465
- 466
- 467
- 468
- 469
- 470
- 471
- 472
- 473
- 474
- 475
- 476
- 477
- 478
- 479
- 480
- 481
- 482
- 483
- 484
- 485
- 486
- 487
- 488
- 489
- 490
- 491
- 492
- 493
- 494
- 495
- 496
- 497
- 498
- 499
- 500
- 501
- 502
- 503
- 504
- 505
- 506
- 507
- 508
- 509
- 510
- 511
- 512
- 513
- 514
- 515
- 516
- 517
- 518
- 519
- 520
- 521
- 522
- 523
- 524
- 525
- 526
- 527
- 528
- 529
- 530
- 531
- 532
- 533
- 534
- 535
- 536
- 537
- 538
- 539
- 540
- 541
- 542
- 543
- 544
- 545
- 546
- 547
- 548
- 549
- 550
- 551
- 552
- 553
- 554
- 555
- 556
- 557
- 558
- 559
- 560
- 561
- 562
- 563
- 564
- 565
- 566
- 567
- 568
- 569
- 570
- 571
- 572
- 573
- 574
- 575
- 576
- 577
- 578
- 579
- 580
- 581
- 582
- 583
- 584
- 585
- 586
- 587
- 588
- 589
- 590
- 591
- 592
- 593
- 594
- 595
- 596
- 597
- 598
- 599
- 600
- 601
- 602
- 603
- 604
- 605
- 606
- 607
- 608
- 609
- 610
- 611
- 612
- 613
- 614
- 615
- 616
- 617
- 618
- 619
- 620
- 621
- 622
- 623
- 624
- 625
- 626
- 627
- 628
- 629
- 630
- 631
- 632
- 633
- 634
- 635
- 636
- 637
- 638
- 639
- 640
- 641
- 642
- 643
- 644
- 645
- 646
- 647
- 648
- 649
- 650
- 651
- 652
- 653
- 654
- 655
- 656
- 657
- 658
- 659
- 660
- 661
- 662
- 663
- 664
- 665
- 666
- 667
- 668
- 669
- 670
- 671
- 672
- 673
- 674
- 675
- 676
- 677
- 678
- 679
- 680
- 681
- 682
- 683
- 684
- 685
- 686
- 687
- 688
- 689
- 690
- 691
- 692
- 693
- 694
- 695
- 696
- 697
- 698
- 699
- 700
- 701
- 702
- 703
- 704
- 705
- 706
- 707
- 708
- 709
- 710
- 711
- 712
- 713
- 714
- 715
- 716
- 717
- 718
- 719
- 720
- 721
- 722
- 723
- 724
- 725
- 726
- 727
- 728
- 729
- 730
- 731
- 732
- 733
- 734
- 735
- 736
- 737
- 738
- 739
- 740
- 741
- 742
- 743
- 744
- 745
- 746
- 747
- 748
- 749
- 750
- 751
- 752
- 753
- 754
- 755
- 756
- 757
- 758
- 759
- 760
- 761
- 762
- 763
- 764
- 765
- 766
- 767
- 768
- 769
- 770
- 771
- 772
- 773
- 774
- 775
- 776
- 777
- 778
- 779
- 780
- 781
- 782
- 783
- 784
- 785
- 786
- 787
- 788
- 789
- 790
- 791
- 792
- 793
- 794
- 795
- 796
- 797
- 798
- 799
- 800
- 801
- 802
- 803
- 804
- 805
- 806
- 807
- 808
- 809
- 810
- 811
- 812
- 813
- 814
- 815
- 816
- 817
- 818
- 819
- 820
- 821
- 822
- 823
- 824
- 825
- 826
- 827
- 828
- 829
- 830
- 831
- 832
- 833
- 834
- 835
- 836
- 837
- 838
- 839
- 840
- 841
- 842
- 843
- 844
- 845
- 846
- 847
- 848
- 849
- 850
- 851
- 852
- 853
- 854
- 855
- 856
- 857
- 858
- 859
- 860
- 861
- 862
- 863
- 864
- 865
- 866
- 867
- 868
- 869
- 870
- 871
- 872
- 873
- 874
- 875
- 876
- 877
- 878
- 879
- 880
- 881
- 882
- 883
- 884
- 885
- 886
- 887
- 888
- 889
- 890
- 891
- 892
- 893
- 894
- 895
- 896
- 897
- 898
- 899
- 900
- 901
- 902
- 903
- 904
- 905
- 906
- 907
- 908
- 909
- 910
- 911
- 912
- 913
- 914
- 915
- 916
- 917
- 918
- 919
- 920
- 921
- 922
- 923
- 924
- 925
- 926
- 927
- 928
- 929
- 930
- 931
- 932
- 933
- 934
- 935
- 936
- 937
- 938
- 939
- 940
- 941
- 942
- 943
- 944
- 945
- 946
- 947
- 948
- 949
- 950
- 951
- 952
- 953
- 954
- 955
- 956
- 957
- 958
- 959
- 960
- 961
- 962
- 963
- 964
- 965
- 966
- 967
- 968
- 969
- 970
- 971
- 972
- 973
- 974
- 975
- 976
- 977
- 978
- 979
- 980
- 981
- 982
- 983
- 984
- 985
- 986
- 987
- 988
- 989
- 990
- 991
- 992
- 993
- 994
- 995
- 996
- 997
- 998
- 999
-1000
-1001
-1002
-1003
-1004
-1005
-1006
-1007
-1008
-1009
// *****************************************************************************
+
  1
+  2
+  3
+  4
+  5
+  6
+  7
+  8
+  9
+ 10
+ 11
+ 12
+ 13
+ 14
+ 15
+ 16
+ 17
+ 18
+ 19
+ 20
+ 21
+ 22
+ 23
+ 24
+ 25
+ 26
+ 27
+ 28
+ 29
+ 30
+ 31
+ 32
+ 33
+ 34
+ 35
+ 36
+ 37
+ 38
+ 39
+ 40
+ 41
+ 42
+ 43
+ 44
+ 45
+ 46
+ 47
+ 48
+ 49
+ 50
+ 51
+ 52
+ 53
+ 54
+ 55
+ 56
+ 57
+ 58
+ 59
+ 60
+ 61
+ 62
+ 63
+ 64
+ 65
+ 66
+ 67
+ 68
+ 69
+ 70
+ 71
+ 72
+ 73
+ 74
+ 75
+ 76
+ 77
+ 78
+ 79
+ 80
+ 81
+ 82
+ 83
+ 84
+ 85
+ 86
+ 87
+ 88
+ 89
+ 90
+ 91
+ 92
+ 93
+ 94
+ 95
+ 96
+ 97
+ 98
+ 99
+100
+101
+102
+103
+104
+105
+106
+107
+108
+109
+110
+111
+112
+113
+114
+115
+116
+117
+118
+119
+120
+121
+122
+123
+124
+125
+126
+127
+128
+129
+130
+131
+132
+133
+134
+135
+136
+137
+138
+139
+140
+141
+142
+143
+144
+145
+146
+147
+148
+149
+150
+151
+152
+153
+154
+155
+156
+157
+158
+159
+160
+161
+162
+163
+164
+165
+166
+167
+168
+169
+170
+171
+172
+173
+174
+175
+176
+177
+178
+179
+180
+181
+182
+183
+184
+185
+186
+187
+188
+189
+190
+191
+192
+193
+194
+195
+196
+197
+198
+199
+200
+201
+202
+203
+204
+205
+206
+207
+208
+209
+210
+211
+212
+213
+214
+215
+216
+217
+218
+219
+220
+221
+222
+223
+224
+225
+226
+227
+228
+229
+230
+231
+232
+233
+234
+235
+236
+237
+238
+239
+240
+241
+242
+243
+244
+245
+246
+247
+248
+249
+250
+251
+252
+253
+254
+255
+256
+257
+258
+259
+260
+261
+262
+263
+264
+265
+266
+267
+268
+269
+270
+271
+272
+273
+274
+275
+276
+277
+278
+279
+280
+281
+282
+283
+284
+285
+286
+287
+288
+289
+290
+291
+292
+293
+294
+295
+296
+297
+298
+299
+300
+301
+302
+303
+304
+305
+306
+307
+308
+309
+310
+311
+312
+313
+314
+315
+316
+317
+318
+319
+320
+321
+322
+323
+324
+325
+326
+327
+328
+329
+330
+331
+332
+333
+334
+335
+336
+337
+338
+339
+340
+341
+342
+343
+344
+345
+346
+347
+348
+349
+350
+351
+352
+353
+354
+355
+356
+357
+358
+359
+360
+361
+362
+363
+364
+365
+366
+367
+368
+369
+370
+371
+372
+373
+374
+375
+376
+377
+378
+379
+380
+381
+382
+383
+384
+385
+386
+387
+388
+389
+390
+391
+392
+393
+394
+395
+396
+397
+398
+399
+400
+401
+402
+403
+404
+405
+406
+407
+408
+409
+410
+411
+412
+413
+414
+415
+416
+417
+418
+419
+420
+421
+422
+423
+424
+425
+426
+427
+428
+429
+430
+431
+432
+433
+434
+435
+436
+437
+438
+439
+440
+441
+442
+443
+444
+445
+446
+447
+448
+449
+450
+451
+452
+453
+454
+455
+456
+457
+458
+459
+460
+461
+462
+463
+464
+465
+466
+467
+468
+469
+470
+471
+472
+473
+474
+475
+476
+477
+478
+479
+480
+481
+482
+483
+484
+485
+486
+487
+488
+489
+490
+491
+492
// *****************************************************************************
 /*!
-  \file      src/PDE/Integrate/MultiMatTerms.cpp
+  \file      src/PDE/Integrate/Surface.cpp
   \copyright 2012-2015 J. Bakosi,
              2016-2018 Los Alamos National Security, LLC.,
              2019-2021 Triad National Security, LLC.
              All rights reserved. See the LICENSE file for details.
-  \brief     Functions for computing volume integrals of multi-material terms
-     using DG methods
-  \details   This file contains functionality for computing volume integrals of
-     non-conservative and pressure relaxation terms that appear in the
-     multi-material hydrodynamic equations, using the discontinuous Galerkin
-     method for various orders of numerical representation.
-*/
-// *****************************************************************************
-
-#include "QuinoaConfig.hpp"
-
-#include "MultiMatTerms.hpp"
-#include "Vector.hpp"
-#include "Quadrature.hpp"
-#include "MultiMat/MultiMatIndexing.hpp"
-#include "Reconstruction.hpp"
-#include "Inciter/InputDeck/InputDeck.hpp"
-#include "EoS/GetMatProp.hpp"
-
-namespace inciter {
-extern ctr::InputDeck g_inputdeck;
-}
-
-// Lapacke forward declarations
-extern "C" {
-
-using lapack_int = long;
-
-#define LAPACK_ROW_MAJOR 101
-
-lapack_int LAPACKE_dsysv( int, char, lapack_int, lapack_int, double*,
-    lapack_int, lapack_int*, double*, lapack_int );
-
-}
-
-namespace tk {
-
-void
-nonConservativeInt( std::size_t nmat,
-                    const std::vector< inciter::EOS >& mat_blk,
-                    const std::size_t ndof,
-                    const std::size_t rdof,
-                    const std::size_t nelem,
-                    const std::vector< std::size_t >& inpoel,
-                    const UnsMesh::Coords& coord,
-                    const Fields& geoElem,
-                    const Fields& U,
-                    const Fields& P,
-                    const std::vector< std::vector< tk::real > >& riemannDeriv,
-                    const std::vector< std::size_t >& ndofel,
-                    Fields& R,
-                    int intsharp )
-// *****************************************************************************
-//  Compute volume integrals for multi-material DG
-//! \details This is called for multi-material DG, computing volume integrals of
-//!   terms in the volume fraction and energy equations, which do not exist in
-//!   the single-material flow formulation (for `CompFlow` DG). For further
-//!   details see Pelanti, M., & Shyue, K. M. (2019). A numerical model for
-//!   multiphase liquid–vapor–gas flows with interfaces and cavitation.
-//!   International Journal of Multiphase Flow, 113, 208-230.
-//! \param[in] nmat Number of materials in this PDE system
-//! \param[in] mat_blk EOS material block
-//! \param[in] ndof Maximum number of degrees of freedom
-//! \param[in] rdof Maximum number of reconstructed degrees of freedom
-//! \param[in] nelem Total number of elements
-//! \param[in] inpoel Element-node connectivity
-//! \param[in] coord Array of nodal coordinates
-//! \param[in] geoElem Element geometry array
-//! \param[in] U Solution vector at recent time step
-//! \param[in] P Vector of primitive quantities at recent time step
-//! \param[in] riemannDeriv Derivatives of partial-pressures and velocities
-//!   computed from the Riemann solver for use in the non-conservative terms
-//! \param[in] ndofel Vector of local number of degrees of freedome
-//! \param[in,out] R Right-hand side vector added to
-//! \param[in] intsharp Interface reconstruction indicator
-// *****************************************************************************
-{
-  using inciter::volfracIdx;
-  using inciter::densityIdx;
-  using inciter::momentumIdx;
-  using inciter::energyIdx;
-  using inciter::velocityIdx;
-  using inciter::deformIdx;
-  using inciter::newSolidsAccFn;
+  \brief     Functions for computing internal surface integrals of a system
+     of PDEs in DG methods
+  \details   This file contains functionality for computing internal surface
+     integrals of a system of PDEs used in discontinuous Galerkin methods for
+     various orders of numerical representation.
+*/
+// *****************************************************************************
+
+#include <array>
+
+#include "Surface.hpp"
+#include "Vector.hpp"
+#include "Quadrature.hpp"
+#include "Reconstruction.hpp"
+#include "Integrate/SolidTerms.hpp"
+#include "Inciter/InputDeck/InputDeck.hpp"
+#include "MultiMat/MiscMultiMatFns.hpp"
+
+namespace inciter {
+extern ctr::InputDeck g_inputdeck;
+}
+
+namespace tk {
+
+void
+surfInt( std::size_t nmat,
+         const std::vector< inciter::EOS >& mat_blk,
+         real t,
+         const std::size_t ndof,
+         const std::size_t rdof,
+         const std::vector< std::size_t >& inpoel,
+         const std::vector< std::size_t >& /*solidx*/,
+         const UnsMesh::Coords& coord,
+         const inciter::FaceData& fd,
+         const Fields& geoFace,
+         const Fields& geoElem,
+         const RiemannFluxFn& flux,
+         const VelFn& vel,
+         const Fields& U,
+         const Fields& P,
+         const std::vector< std::size_t >& ndofel,
+         const tk::real /*dt*/,
+         Fields& R,
+         std::vector< std::vector< tk::real > >&,
+         std::vector< std::vector< tk::real > >&,
+         std::vector< std::vector< tk::real > >& riemannDeriv,
+         int intsharp )
+// *****************************************************************************
+//  Compute internal surface flux integrals
+//! \param[in] nmat Number of materials in this PDE system
+//! \param[in] mat_blk EOS material block
+//! \param[in] t Physical time
+//! \param[in] ndof Maximum number of degrees of freedom
+//! \param[in] rdof Maximum number of reconstructed degrees of freedom
+//! \param[in] inpoel Element-node connectivity
+// //! \param[in] solidx Material index indicator
+//! \param[in] coord Array of nodal coordinates
+//! \param[in] fd Face connectivity and boundary conditions object
+//! \param[in] geoFace Face geometry array
+//! \param[in] geoElem Element geometry array
+//! \param[in] flux Riemann flux function to use
+//! \param[in] vel Function to use to query prescribed velocity (if any)
+//! \param[in] U Solution vector at recent time step
+//! \param[in] P Vector of primitives at recent time step
+//! \param[in] ndofel Vector of local number of degrees of freedom
+// //! \param[in] dt Delta time
+//! \param[in,out] R Right-hand side vector computed
+//! \param[in,out] vriem Vector of the riemann velocity
+//! \param[in,out] riemannLoc Vector of coordinates where Riemann velocity data
+//!   is available
+//! \param[in,out] riemannDeriv Derivatives of partial-pressures and velocities
+//!   computed from the Riemann solver for use in the non-conservative terms.
+//!   These derivatives are used only for multi-material hydro and unused for
+//!   single-material compflow and linear transport.
+//! \param[in] intsharp Interface compression tag, an optional argument, with
+//!   default 0, so that it is unused for single-material and transport.
+// *****************************************************************************
+{
+  const auto& esuf = fd.Esuf();
+  const auto& inpofa = fd.Inpofa();
+
+  const auto& cx = coord[0];
+  const auto& cy = coord[1];
+  const auto& cz = coord[2];
 
-  const auto& solidx =
-    inciter::g_inputdeck.get< tag::matidxmap, tag::solidx >();
-
-  const auto& cx = coord[0];
-  const auto& cy = coord[1];
-  const auto& cz = coord[2];
-
-  auto ncomp = U.nprop()/rdof;
-  auto nprim = P.nprop()/rdof;
-
-  // compute volume integrals
-  for (std::size_t e=0; e<nelem; ++e)
-  {
-    auto ng = tk::NGvol(ndofel[e]);
+  auto ncomp = U.nprop()/rdof;<--- Variable 'ncomp' is assigned a value that is never used.
+  auto nprim = P.nprop()/rdof;<--- Variable 'nprim' is assigned a value that is never used.
+
+  //// Determine if we have solids in our problem
+  //bool haveSolid = inciter::haveSolid(nmat, solidx);
+
+  //Assert( (nmat==1 ? riemannDeriv.empty() : true), "Non-empty Riemann "
+  //        "derivative vector for single material compflow" );
+
+  // compute internal surface flux integrals
+  for (auto f=fd.Nbfac(); f<esuf.size()/2; ++f)
+  {
+    Assert( esuf[2*f] > -1 && esuf[2*f+1] > -1, "Interior element detected "
+            "as -1" );
 
-    // arrays for quadrature points
-    std::array< std::vector< real >, 3 > coordgp;
-    std::vector< real > wgp;
-
-    coordgp[0].resize( ng );
-    coordgp[1].resize( ng );
-    coordgp[2].resize( ng );
-    wgp.resize( ng );
-
-    GaussQuadratureTet( ng, coordgp, wgp );
-
-    // Extract the element coordinates
-    std::array< std::array< real, 3>, 4 > coordel {{
-      {{ cx[ inpoel[4*e  ] ], cy[ inpoel[4*e  ] ], cz[ inpoel[4*e  ] ] }},
-      {{ cx[ inpoel[4*e+1] ], cy[ inpoel[4*e+1] ], cz[ inpoel[4*e+1] ] }},
-      {{ cx[ inpoel[4*e+2] ], cy[ inpoel[4*e+2] ], cz[ inpoel[4*e+2] ] }},
-      {{ cx[ inpoel[4*e+3] ], cy[ inpoel[4*e+3] ], cz[ inpoel[4*e+3] ] }}
-    }};
-
-    auto jacInv =
-            inverseJacobian( coordel[0], coordel[1], coordel[2], coordel[3] );
-
-    // Compute the derivatives of basis function for DG(P1)
-    std::array< std::vector<tk::real>, 3 > dBdx;
-    if (ndofel[e] > 1)
-      dBdx = eval_dBdx_p1( ndofel[e], jacInv );
-
-    // Gaussian quadrature
-    for (std::size_t igp=0; igp<ng; ++igp)
-    {
-      if (ndofel[e] > 4)
-        eval_dBdx_p2( igp, coordgp, jacInv, dBdx );
-
-      // If an rDG method is set up (P0P1), then, currently we compute the P1
-      // basis functions and solutions by default. This implies that P0P1 is
-      // unsupported in the p-adaptive DG (PDG).
-      std::size_t dof_el;
-      if (rdof > ndof)
-      {
-        dof_el = rdof;
-      }
-      else
-      {
-        dof_el = ndofel[e];
-      }
+    std::size_t el = static_cast< std::size_t >(esuf[2*f]);
+    std::size_t er = static_cast< std::size_t >(esuf[2*f+1]);
+
+    auto ng_l = tk::NGfa(ndofel[el]);
+    auto ng_r = tk::NGfa(ndofel[er]);
+
+    // When the number of gauss points for the left and right element are
+    // different, choose the larger ng
+    auto ng = std::max( ng_l, ng_r );
+
+    // arrays for quadrature points
+    std::array< std::vector< real >, 2 > coordgp;
+    std::vector< real > wgp;
+
+    coordgp[0].resize( ng );
+    coordgp[1].resize( ng );
+    wgp.resize( ng );
+
+    // get quadrature point weights and coordinates for triangle
+    GaussQuadratureTri( ng, coordgp, wgp );
+
+    // Extract the element coordinates
+    std::array< std::array< tk::real, 3>, 4 > coordel_l {{
+      {{ cx[ inpoel[4*el  ] ], cy[ inpoel[4*el  ] ], cz[ inpoel[4*el  ] ] }},
+      {{ cx[ inpoel[4*el+1] ], cy[ inpoel[4*el+1] ], cz[ inpoel[4*el+1] ] }},
+      {{ cx[ inpoel[4*el+2] ], cy[ inpoel[4*el+2] ], cz[ inpoel[4*el+2] ] }},
+      {{ cx[ inpoel[4*el+3] ], cy[ inpoel[4*el+3] ], cz[ inpoel[4*el+3] ] }} }};
+
+    std::array< std::array< tk::real, 3>, 4 > coordel_r {{
+      {{ cx[ inpoel[4*er  ] ], cy[ inpoel[4*er  ] ], cz[ inpoel[4*er  ] ] }},
+      {{ cx[ inpoel[4*er+1] ], cy[ inpoel[4*er+1] ], cz[ inpoel[4*er+1] ] }},
+      {{ cx[ inpoel[4*er+2] ], cy[ inpoel[4*er+2] ], cz[ inpoel[4*er+2] ] }},
+      {{ cx[ inpoel[4*er+3] ], cy[ inpoel[4*er+3] ], cz[ inpoel[4*er+3] ] }} }};
+
+    // Compute the determinant of Jacobian matrix
+    auto detT_l =
+      Jacobian( coordel_l[0], coordel_l[1], coordel_l[2], coordel_l[3] );
+    auto detT_r =
+      Jacobian( coordel_r[0], coordel_r[1], coordel_r[2], coordel_r[3] );
+
+    // Extract the face coordinates
+    std::array< std::array< tk::real, 3>, 3 > coordfa {{
+      {{ cx[ inpofa[3*f  ] ], cy[ inpofa[3*f  ] ], cz[ inpofa[3*f  ] ] }},
+      {{ cx[ inpofa[3*f+1] ], cy[ inpofa[3*f+1] ], cz[ inpofa[3*f+1] ] }},
+      {{ cx[ inpofa[3*f+2] ], cy[ inpofa[3*f+2] ], cz[ inpofa[3*f+2] ] }} }};
 
-      // Compute the basis function
-      auto B =
-        eval_basis( dof_el, coordgp[0][igp], coordgp[1][igp], coordgp[2][igp] );
-
-      auto wt = wgp[igp] * geoElem(e, 0);
-
-      auto state = evalPolynomialSol(mat_blk, intsharp, ncomp, nprim,
-        rdof, nmat, e, dof_el, inpoel, coord, geoElem,
-        {{coordgp[0][igp], coordgp[1][igp], coordgp[2][igp]}}, B, U, P);
-
-      // get bulk properties
-      tk::real rhob(0.0);
-      for (std::size_t k=0; k<nmat; ++k)
-          rhob += state[densityIdx(nmat, k)];
-
-      // get the velocity vector
-      std::array< tk::real, 3 > vel{{ state[ncomp+velocityIdx(nmat, 0)],
-                                      state[ncomp+velocityIdx(nmat, 1)],
-                                      state[ncomp+velocityIdx(nmat, 2)] }};
-
-      std::vector< tk::real > ymat(nmat, 0.0);
-      std::array< tk::real, 3 > dap{{0.0, 0.0, 0.0}};
-      for (std::size_t k=0; k<nmat; ++k)
-      {
-        ymat[k] = state[densityIdx(nmat, k)]/rhob;
-
-        std::size_t mark(3*k);
-        if (solidx[k] > 0) mark = 3*nmat+ndof+3*(solidx[k]-1);
-
-        for (std::size_t idir=0; idir<3; ++idir)
-          dap[idir] += riemannDeriv[mark+idir][e];
-      }
-
-      // compute non-conservative terms
-      std::vector< std::vector< tk::real > > ncf
-        (ncomp, std::vector<tk::real>(ndof,0.0));
-
-      for (std::size_t idir=0; idir<3; ++idir)
-        for(std::size_t idof=0; idof<ndof; ++idof)
-          ncf[momentumIdx(nmat, idir)][idof] = 0.0;
-
-      for (std::size_t k=0; k<nmat; ++k)
-      {
-        // evaluate non-conservative term for energy equation
-        std::size_t mark(3*k);
-        if (solidx[k] > 0) mark = 3*nmat+ndof+3*(solidx[k]-1);
-
-        for(std::size_t idof=0; idof<ndof; ++idof)
-        {
-          ncf[densityIdx(nmat, k)][idof] = 0.0;
-
-          for (std::size_t idir=0; idir<3; ++idir)
-            ncf[energyIdx(nmat, k)][idof] -= vel[idir] * ( ymat[k]*dap[idir]
-                                                  - riemannDeriv[mark+idir][e] );
-        }
-
-        // Evaluate non-conservative term for volume fraction equation:
-        // Here we make an assumption that the derivative of Riemann velocity
-        // times the basis function is constant. Therefore, when P0P1/DGP1/DGP2
-        // are used for constant velocity problems, the discretization is
-        // consistent. However, for a general problem with varying velocity,
-        // there will be errors since the said derivative is not constant.
-        // A discretization that solves this issue has not been implemented yet.
-        // Nevertheless, this does not affect high-order accuracy in
-        // single material regions for problems with sharp interfaces. Since
-        // volume fractions are nearly constant in such regions, using
-        // high-order for volume fractions does not show any benefits over
-        // THINC. Therefore, for such problems, we only use FV for the volume
-        // fractions, and these non-conservative high-order terms do not need
-        // to be computed.
-        // In summary, high-order discretization for non-conservative terms in
-        // volume fraction equations is avoided for sharp interface problems.
-        if (ndof <= 4 || intsharp == 1) {
-          for(std::size_t idof=0; idof<ndof; ++idof)
-            ncf[volfracIdx(nmat, k)][idof] = state[volfracIdx(nmat, k)]
-                                           * riemannDeriv[3*nmat+idof][e];
-        } else if (intsharp == 0) {     // If DGP2 without THINC
-          // DGP2 is discretized differently than DGP1/FV to guarantee 3rd order
-          // convergence for the testcases with uniform and constant velocity.
-
-          // P0 contributions for all equations
-          for(std::size_t idof=0; idof<ndof; ++idof)
-          ncf[volfracIdx(nmat, k)][idof] = state[volfracIdx(nmat, k)]
-                                         * riemannDeriv[3*nmat][e] * B[idof];
-          // High order contributions
-          for(std::size_t idof=1; idof<ndof; ++idof)
-            for(std::size_t idir=0; idir<3; ++idir)
-            ncf[volfracIdx(nmat, k)][idof] += state[volfracIdx(nmat, k)]
-                                            * vel[idir] * dBdx[idir][idof];
-        }
-      }
-
-      updateRhsNonCons( ncomp, nmat, ndof, ndofel[e], wt, e, B, dBdx, ncf, R );
-    }
-  }
-}
-
-void
-updateRhsNonCons(
-  ncomp_t ncomp,
-  const std::size_t nmat,
-  const std::size_t ndof,
-  [[maybe_unused]] const std::size_t ndof_el,
-  const tk::real wt,
-  const std::size_t e,
-  const std::vector<tk::real>& B,
-  [[maybe_unused]] const std::array< std::vector<tk::real>, 3 >& dBdx,
-  const std::vector< std::vector< tk::real > >& ncf,
-  Fields& R )
-// *****************************************************************************
-//  Update the rhs by adding the non-conservative term integrals
-//! \param[in] ncomp Number of scalar components in this PDE system
-//! \param[in] nmat Number of materials
-//! \param[in] ndof Maximum number of degrees of freedom
-//! \param[in] ndof_el Number of degrees of freedom for local element
-//! \param[in] wt Weight of gauss quadrature point
-//! \param[in] e Element index
-//! \param[in] B Basis function evaluated at local quadrature point
-//! \param[in] dBdx Vector of basis function derivatives
-//! \param[in] ncf Vector of non-conservative terms
-//! \param[in,out] R Right-hand side vector computed
-// *****************************************************************************
-{
-  using inciter::volfracIdx;
-  using inciter::energyIdx;
-  using inciter::volfracDofIdx;
-  using inciter::energyDofIdx;
-
-  //Assert( dBdx[0].size() == ndof_el,
-  //        "Size mismatch for basis function derivatives" );
-  //Assert( dBdx[1].size() == ndof_el,
-  //        "Size mismatch for basis function derivatives" );
-  //Assert( dBdx[2].size() == ndof_el,
-  //        "Size mismatch for basis function derivatives" );
-  //Assert( ncf.size() == ncomp,
-  //        "Size mismatch for non-conservative term" );
-  Assert( ncf.size() == ncomp, "Size mismatch for non-conservative term" );
-
-  for (ncomp_t c=0; c<ncomp; ++c)
-  {
-    auto mark = c*ndof;
-    R(e, mark) += wt * ncf[c][0];
-  }
-
-  if( ndof_el > 1)
-  {
-    // Update rhs with distributions from volume fraction and energy equations
-    for (std::size_t k=0; k<nmat; ++k)
-    {
-      for(std::size_t idof = 1; idof < ndof; idof++)
-      {
-        R(e, volfracDofIdx(nmat,k,ndof,idof)) +=
-          wt * ncf[volfracIdx(nmat,k)][idof];
-        R(e, energyDofIdx(nmat,k,ndof,idof)) +=
-          wt * ncf[energyIdx(nmat,k)][idof] * B[idof];
-      }
-    }
-  }
-}
-
-std::vector< tk::real >
-nonConservativeIntFV(
-  std::size_t nmat,
-  const std::size_t rdof,
-  const std::size_t e,
-  const std::array< tk::real, 3 >& fn,
-  const Fields& U,
-  const Fields& P,
-  const std::vector< tk::real >& var_riemann )
-// *****************************************************************************
-//  Compute integrals of non-conservative terms for multi-material FV
-//! \details This is called for multi-material FV, computing integrals of
-//!   terms in the volume fraction and energy equations, which do not exist in
-//!   the single-material flow formulation (for `CompFlow`). For further
-//!   details see Pelanti, M., & Shyue, K. M. (2019). A numerical model for
-//!   multiphase liquid–vapor–gas flows with interfaces and cavitation.
-//!   International Journal of Multiphase Flow, 113, 208-230.
-//! \param[in] nmat Number of materials in this PDE system
-//! \param[in] rdof Maximum number of reconstructed degrees of freedom
-//! \param[in] e Element for which contribution is to be calculated
-//! \param[in] fn Face normal
-//! \param[in] U Solution vector at recent time step
-//! \param[in] P Vector of primitive quantities at recent time step
-//! \param[in] var_riemann Riemann-values of partial-pressures and velocities
-//!   computed from the Riemann solver for use in the non-conservative terms
-// *****************************************************************************
-{
-  using inciter::volfracIdx;
-  using inciter::densityIdx;
-  using inciter::momentumIdx;
-  using inciter::energyIdx;
-  using inciter::velocityIdx;
-  using inciter::volfracDofIdx;
-  using inciter::densityDofIdx;
-  using inciter::velocityDofIdx;
-
-  auto ncomp = U.nprop()/rdof;
+    std::array< real, 3 >
+      fn{{ geoFace(f,1), geoFace(f,2), geoFace(f,3) }};
+
+    // Gaussian quadrature
+    for (std::size_t igp=0; igp<ng; ++igp)
+    {
+      // Compute the coordinates of quadrature point at physical domain
+      auto gp = eval_gp( igp, coordfa, coordgp );
+
+      // In order to determine the high-order solution from the left and right
+      // elements at the surface quadrature points, the basis functions from
+      // the left and right elements are needed. For this, a transformation to
+      // the reference coordinates is necessary, since the basis functions are
+      // defined on the reference tetrahedron only.
+      // The transformation relations are shown below:
+      //  xi   = Jacobian( coordel[0], gp, coordel[2], coordel[3] ) / detT
+      //  eta  = Jacobian( coordel[0], coordel[2], gp, coordel[3] ) / detT
+      //  zeta = Jacobian( coordel[0], coordel[2], coordel[3], gp ) / detT
+
+      // If an rDG method is set up (P0P1), then, currently we compute the P1
+      // basis functions and solutions by default. This implies that P0P1 is
+      // unsupported in the p-adaptive DG (PDG). This is a workaround until we
+      // have rdofel, which is needed to distinguish between ndofs and rdofs per
+      // element for pDG.
+      std::size_t dof_el, dof_er;
+      if (rdof > ndof)
+      {
+        dof_el = rdof;
+        dof_er = rdof;
+      }
+      else
+      {
+        dof_el = ndofel[el];
+        dof_er = ndofel[er];
+      }
+
+      std::array< tk::real, 3> ref_gp_l{
+        Jacobian( coordel_l[0], gp, coordel_l[2], coordel_l[3] ) / detT_l,
+        Jacobian( coordel_l[0], coordel_l[1], gp, coordel_l[3] ) / detT_l,
+        Jacobian( coordel_l[0], coordel_l[1], coordel_l[2], gp ) / detT_l };
+      std::array< tk::real, 3> ref_gp_r{
+        Jacobian( coordel_r[0], gp, coordel_r[2], coordel_r[3] ) / detT_r,
+        Jacobian( coordel_r[0], coordel_r[1], gp, coordel_r[3] ) / detT_r,
+        Jacobian( coordel_r[0], coordel_r[1], coordel_r[2], gp ) / detT_r };
+
+      //Compute the basis functions
+      auto B_l = eval_basis( dof_el, ref_gp_l[0], ref_gp_l[1], ref_gp_l[2] );
+      auto B_r = eval_basis( dof_er, ref_gp_r[0], ref_gp_r[1], ref_gp_r[2] );
+
+      auto wt = wgp[igp] * geoFace(f,0);<--- Variable 'wt' is assigned a value that is never used.
+
+      std::array< std::vector< real >, 2 > state;
+
+      state[0] = evalPolynomialSol(mat_blk, intsharp, ncomp, nprim, rdof,
+        nmat, el, dof_el, inpoel, coord, geoElem, ref_gp_l, B_l, U, P);
+      state[1] = evalPolynomialSol(mat_blk, intsharp, ncomp, nprim, rdof,
+        nmat, er, dof_er, inpoel, coord, geoElem, ref_gp_r, B_r, U, P);
+
+      Assert( state[0].size() == ncomp+nprim, "Incorrect size for "
+              "appended boundary state vector" );
+      Assert( state[1].size() == ncomp+nprim, "Incorrect size for "
+              "appended boundary state vector" );
+
+      // evaluate prescribed velocity (if any)
+      auto v = vel( ncomp, gp[0], gp[1], gp[2], t );
+
+      // compute flux
+      auto fl = flux( mat_blk, fn, state, v );
+
+      // Add the surface integration term to the rhs
+      update_rhs_fa( ncomp, nmat, ndof, ndofel[el], ndofel[er], wt, fn,
+                     el, er, fl, B_l, B_r, R, riemannDeriv );
+    }
+  }
+}
+
+void
+update_rhs_fa( ncomp_t ncomp,
+               std::size_t nmat,
+               const std::size_t ndof,
+               const std::size_t ndof_l,
+               const std::size_t ndof_r,
+               const tk::real wt,
+               const std::array< tk::real, 3 >& fn,
+               const std::size_t el,
+               const std::size_t er,
+               const std::vector< tk::real >& fl,
+               const std::vector< tk::real >& B_l,
+               const std::vector< tk::real >& B_r,
+               Fields& R,<--- Parameter 'R' can be declared with const
+               std::vector< std::vector< tk::real > >& riemannDeriv )
+// *****************************************************************************
+//  Update the rhs by adding the surface integration term
+//! \param[in] ncomp Number of scalar components in this PDE system
+//! \param[in] nmat Number of materials in this PDE system
+//! \param[in] ndof Maximum number of degrees of freedom
+//! \param[in] ndof_l Number of degrees of freedom for left element
+//! \param[in] ndof_r Number of degrees of freedom for right element
+//! \param[in] wt Weight of gauss quadrature point
+//! \param[in] fn Face/Surface normal
+//! \param[in] el Left element index
+//! \param[in] er Right element index
+//! \param[in] fl Surface flux
+//! \param[in] B_l Basis function for the left element
+//! \param[in] B_r Basis function for the right element
+//! \param[in,out] R Right-hand side vector computed
+//! \param[in,out] riemannDeriv Derivatives of partial-pressures and velocities
+//!   computed from the Riemann solver for use in the non-conservative terms.
+//!   These derivatives are used only for multi-material hydro and unused for
+//!   single-material compflow and linear transport.
+// *****************************************************************************
+{
+  // following lines commented until rdofel is made available.
+  //Assert( B_l.size() == ndof_l, "Size mismatch" );
+  //Assert( B_r.size() == ndof_r, "Size mismatch" );
+
+  using inciter::newSolidsAccFn;
+
+  const auto& solidx =
+    inciter::g_inputdeck.get< tag::matidxmap, tag::solidx >();
+
+  for (ncomp_t c=0; c<ncomp; ++c)
+  {
+    auto mark = c*ndof;
+    R(el, mark) -= wt * fl[c];
+    R(er, mark) += wt * fl[c];
+
+    if(ndof_l > 1)          //DG(P1)
+    {
+      R(el, mark+1) -= wt * fl[c] * B_l[1];
+      R(el, mark+2) -= wt * fl[c] * B_l[2];
+      R(el, mark+3) -= wt * fl[c] * B_l[3];
+    }
+
+    if(ndof_r > 1)          //DG(P1)
+    {
+      R(er, mark+1) += wt * fl[c] * B_r[1];
+      R(er, mark+2) += wt * fl[c] * B_r[2];
+      R(er, mark+3) += wt * fl[c] * B_r[3];
+    }
+
+    if(ndof_l > 4)          //DG(P2)
+    {
+      R(el, mark+4) -= wt * fl[c] * B_l[4];
+      R(el, mark+5) -= wt * fl[c] * B_l[5];
+      R(el, mark+6) -= wt * fl[c] * B_l[6];
+      R(el, mark+7) -= wt * fl[c] * B_l[7];
+      R(el, mark+8) -= wt * fl[c] * B_l[8];
+      R(el, mark+9) -= wt * fl[c] * B_l[9];
+    }
+
+    if(ndof_r > 4)          //DG(P2)
+    {
+      R(er, mark+4) += wt * fl[c] * B_r[4];
+      R(er, mark+5) += wt * fl[c] * B_r[5];
+      R(er, mark+6) += wt * fl[c] * B_r[6];
+      R(er, mark+7) += wt * fl[c] * B_r[7];
+      R(er, mark+8) += wt * fl[c] * B_r[8];
+      R(er, mark+9) += wt * fl[c] * B_r[9];
+    }
+  }
+
+  // Prep for non-conservative terms in multimat
+  if (fl.size() > ncomp)
+  {
+    // Gradients of partial pressures
+    for (std::size_t k=0; k<nmat; ++k)
+    {
+      for (std::size_t idir=0; idir<3; ++idir)
+      {
+        riemannDeriv[3*k+idir][el] += wt * fl[ncomp+k] * fn[idir];
+        riemannDeriv[3*k+idir][er] -= wt * fl[ncomp+k] * fn[idir];
+      }
+    }
+
+    // Divergence of velocity multiples basis fucntion( d(uB) / dx )
+    for(std::size_t idof = 0; idof < ndof; idof++) {
+      riemannDeriv[3*nmat+idof][el] += wt * fl[ncomp+nmat] * B_l[idof];
+      riemannDeriv[3*nmat+idof][er] -= wt * fl[ncomp+nmat] * B_r[idof];
+    }
+
+    // Divergence of asigma: d(asig_ij)/dx_j
+    for (std::size_t k=0; k<nmat; ++k)
+      if (solidx[k] > 0)
+      {
+        std::size_t mark = ncomp+nmat+1+3*(solidx[k]-1);
+
+        for (std::size_t i=0; i<3; ++i)
+        {
+          riemannDeriv[3*nmat+ndof+3*(solidx[k]-1)+i][el] -=
+            wt * fl[mark+i];
+          riemannDeriv[3*nmat+ndof+3*(solidx[k]-1)+i][er] +=
+            wt * fl[mark+i];
+        }
+      }
+  }
+}
 
-  // get bulk properties
-  tk::real rhob(0.0), p_face(0.0);
-  for (std::size_t k=0; k<nmat; ++k)
-  {
-    rhob += U(e, densityDofIdx(nmat,k,rdof,0));
-    p_face += var_riemann[k];
-  }
-
-  std::array< tk::real, 3 > vel{{ P(e, velocityDofIdx(nmat,0,rdof,0)),
-                                  P(e, velocityDofIdx(nmat,1,rdof,0)),
-                                  P(e, velocityDofIdx(nmat,2,rdof,0)) }};
-
-  // compute non-conservative terms
-  std::vector< tk::real > ncf(ncomp, 0.0);
-  std::vector< tk::real > ymat(nmat, 0.0);
-  for (std::size_t k=0; k<nmat; ++k)
-  {
-    ymat[k] = U(e, densityDofIdx(nmat,k,rdof,0))/rhob;
-
-    // evaluate non-conservative term for energy equation
-    for (std::size_t idir=0; idir<3; ++idir)
-      ncf[energyIdx(nmat, k)] -= vel[idir] * ( ymat[k]*p_face*fn[idir]
-                                            - var_riemann[k]*fn[idir] );
-
-    // evaluate non-conservative term for volume fraction equation
-    ncf[volfracIdx(nmat, k)] = U(e, volfracDofIdx(nmat,k,rdof,0))
-      * var_riemann[nmat];
-  }
-
-  return ncf;
-}
-
-void
-pressureRelaxationInt( std::size_t nmat,
-                       const std::vector< inciter::EOS >& mat_blk,
-                       const std::size_t ndof,
-                       const std::size_t rdof,
-                       const std::size_t nelem,
-                       const std::vector< std::size_t >& inpoel,
-                       const UnsMesh::Coords& coord,
-                       const Fields& geoElem,
-                       const Fields& U,
-                       const Fields& P,
-                       const std::vector< std::size_t >& ndofel,
-                       const tk::real ct,
-                       Fields& R,
-                       int intsharp )
-// *****************************************************************************
-//  Compute volume integrals of pressure relaxation terms in multi-material DG
-//! \details This is called for multi-material DG to compute volume integrals of
-//!   finite pressure relaxation terms in the volume fraction and energy
-//!   equations, which do not exist in the single-material flow formulation (for
-//!   `CompFlow` DG). For further details see Dobrev, V. A., Kolev, T. V.,
-//!   Rieben, R. N., & Tomov, V. Z. (2016). Multi‐material closure model for
-//!   high‐order finite element Lagrangian hydrodynamics. International Journal
-//!   for Numerical Methods in Fluids, 82(10), 689-706.
-//! \param[in] nmat Number of materials in this PDE system
-//! \param[in] mat_blk EOS material block
-//! \param[in] ndof Maximum number of degrees of freedom
-//! \param[in] rdof Maximum number of reconstructed degrees of freedom
-//! \param[in] nelem Total number of elements
-//! \param[in] inpoel Element-node connectivity
-//! \param[in] coord Array of nodal coordinates
-//! \param[in] geoElem Element geometry array
-//! \param[in] U Solution vector at recent time step
-//! \param[in] P Vector of primitive quantities at recent time step
-//! \param[in] ndofel Vector of local number of degrees of freedome
-//! \param[in] ct Pressure relaxation time-scale for this system
-//! \param[in,out] R Right-hand side vector added to
-//! \param[in] intsharp Interface reconstruction indicator
-// *****************************************************************************
-{
-  using inciter::volfracIdx;
-  using inciter::densityIdx;
-  using inciter::momentumIdx;
-  using inciter::energyIdx;
-  using inciter::pressureIdx;
-  using inciter::velocityIdx;
-  using inciter::deformIdx;
-
-  const auto& solidx =
-    inciter::g_inputdeck.get< tag::matidxmap, tag::solidx >();
-
-  auto ncomp = U.nprop()/rdof;
-  auto nprim = P.nprop()/rdof;
-
-  // compute volume integrals
-  for (std::size_t e=0; e<nelem; ++e)
-  {
-    auto dx = geoElem(e,4)/2.0;
-    auto ng = NGvol(ndofel[e]);
-
-    // arrays for quadrature points
-    std::array< std::vector< real >, 3 > coordgp;
-    std::vector< real > wgp;
-
-    coordgp[0].resize( ng );
-    coordgp[1].resize( ng );
-    coordgp[2].resize( ng );
-    wgp.resize( ng );
-
-    GaussQuadratureTet( ng, coordgp, wgp );
-
-    // Compute the derivatives of basis function for DG(P1)
-    std::array< std::vector<real>, 3 > dBdx;
+void
+surfIntFV(
+  std::size_t nmat,
+  const std::vector< inciter::EOS >& mat_blk,
+  real t,
+  const std::size_t rdof,
+  const std::vector< std::size_t >& inpoel,
+  const UnsMesh::Coords& coord,
+  const inciter::FaceData& fd,
+  const Fields& geoFace,
+  const Fields& geoElem,
+  const RiemannFluxFn& flux,
+  const VelFn& vel,
+  const Fields& U,
+  const Fields& P,
+  const std::vector< int >& srcFlag,
+  Fields& R,
+  int intsharp )
+// *****************************************************************************
+//  Compute internal surface flux integrals for second order FV
+//! \param[in] nmat Number of materials in this PDE system
+//! \param[in] t Physical time
+//! \param[in] rdof Maximum number of reconstructed degrees of freedom
+//! \param[in] inpoel Element-node connectivity
+//! \param[in] coord Array of nodal coordinates
+//! \param[in] fd Face connectivity and boundary conditions object
+//! \param[in] geoFace Face geometry array
+//! \param[in] geoElem Element geometry array
+//! \param[in] flux Riemann flux function to use
+//! \param[in] vel Function to use to query prescribed velocity (if any)
+//! \param[in] U Solution vector at recent time step
+//! \param[in] P Vector of primitives at recent time step
+//! \param[in] srcFlag Whether the energy source was added
+//! \param[in,out] R Right-hand side vector computed
+//! \param[in] intsharp Interface compression tag, an optional argument, with
+//!   default 0, so that it is unused for single-material and transport.
+// *****************************************************************************
+{
+  const auto& esuf = fd.Esuf();
+
+  const auto& cx = coord[0];
+  const auto& cy = coord[1];
+  const auto& cz = coord[2];
+
+  auto ncomp = U.nprop()/rdof;<--- Variable 'ncomp' is assigned a value that is never used.
+  auto nprim = P.nprop()/rdof;<--- Variable 'nprim' is assigned a value that is never used.
+
+  // compute internal surface flux integrals
+  for (auto f=fd.Nbfac(); f<esuf.size()/2; ++f)
+  {
+    Assert( esuf[2*f] > -1 && esuf[2*f+1] > -1, "Interior element detected "
+            "as -1" );
+
+    std::size_t el = static_cast< std::size_t >(esuf[2*f]);
+    std::size_t er = static_cast< std::size_t >(esuf[2*f+1]);
+
+    // Extract the element coordinates
+    std::array< std::array< tk::real, 3>, 4 > coordel_l {{
+      {{ cx[ inpoel[4*el  ] ], cy[ inpoel[4*el  ] ], cz[ inpoel[4*el  ] ] }},
+      {{ cx[ inpoel[4*el+1] ], cy[ inpoel[4*el+1] ], cz[ inpoel[4*el+1] ] }},
+      {{ cx[ inpoel[4*el+2] ], cy[ inpoel[4*el+2] ], cz[ inpoel[4*el+2] ] }},
+      {{ cx[ inpoel[4*el+3] ], cy[ inpoel[4*el+3] ], cz[ inpoel[4*el+3] ] }} }};
+
+    std::array< std::array< tk::real, 3>, 4 > coordel_r {{
+      {{ cx[ inpoel[4*er  ] ], cy[ inpoel[4*er  ] ], cz[ inpoel[4*er  ] ] }},
+      {{ cx[ inpoel[4*er+1] ], cy[ inpoel[4*er+1] ], cz[ inpoel[4*er+1] ] }},
+      {{ cx[ inpoel[4*er+2] ], cy[ inpoel[4*er+2] ], cz[ inpoel[4*er+2] ] }},
+      {{ cx[ inpoel[4*er+3] ], cy[ inpoel[4*er+3] ], cz[ inpoel[4*er+3] ] }} }};
+
+    // Compute the determinant of Jacobian matrix
+    auto detT_l =
+      Jacobian( coordel_l[0], coordel_l[1], coordel_l[2], coordel_l[3] );
+    auto detT_r =
+      Jacobian( coordel_r[0], coordel_r[1], coordel_r[2], coordel_r[3] );
+
+    // face normal
+    std::array< real, 3 > fn{{geoFace(f,1), geoFace(f,2), geoFace(f,3)}};
+
+    // face centroid
+    std::array< real, 3 > gp{{geoFace(f,4), geoFace(f,5), geoFace(f,6)}};
+
+    // In order to determine the high-order solution from the left and right
+    // elements at the surface quadrature points, the basis functions from
+    // the left and right elements are needed. For this, a transformation to
+    // the reference coordinates is necessary, since the basis functions are
+    // defined on the reference tetrahedron only.
+    // The transformation relations are shown below:
+    //  xi   = Jacobian( coordel[0], gp, coordel[2], coordel[3] ) / detT
+    //  eta  = Jacobian( coordel[0], coordel[2], gp, coordel[3] ) / detT
+    //  zeta = Jacobian( coordel[0], coordel[2], coordel[3], gp ) / detT
+
+    std::array< tk::real, 3> ref_gp_l{
+      Jacobian( coordel_l[0], gp, coordel_l[2], coordel_l[3] ) / detT_l,
+      Jacobian( coordel_l[0], coordel_l[1], gp, coordel_l[3] ) / detT_l,
+      Jacobian( coordel_l[0], coordel_l[1], coordel_l[2], gp ) / detT_l };
+    std::array< tk::real, 3> ref_gp_r{
+      Jacobian( coordel_r[0], gp, coordel_r[2], coordel_r[3] ) / detT_r,
+      Jacobian( coordel_r[0], coordel_r[1], gp, coordel_r[3] ) / detT_r,
+      Jacobian( coordel_r[0], coordel_r[1], coordel_r[2], gp ) / detT_r };
+
+    //Compute the basis functions
+    auto B_l = eval_basis( rdof, ref_gp_l[0], ref_gp_l[1], ref_gp_l[2] );
+    auto B_r = eval_basis( rdof, ref_gp_r[0], ref_gp_r[1], ref_gp_r[2] );
+
+    std::array< std::vector< real >, 2 > state;
 
-    // Gaussian quadrature
-    for (std::size_t igp=0; igp<ng; ++igp)
-    {
-      // If an rDG method is set up (P0P1), then, currently we compute the P1
-      // basis functions and solutions by default. This implies that P0P1 is
-      // unsupported in the p-adaptive DG (PDG).
-      std::size_t dof_el;
-      if (rdof > ndof)
-      {
-        dof_el = rdof;
-      }
-      else
-      {
-        dof_el = ndofel[e];
-      }
-
-      // Compute the basis function
-      auto B =
-        eval_basis( dof_el, coordgp[0][igp], coordgp[1][igp], coordgp[2][igp] );
-
-      auto wt = wgp[igp] * geoElem(e, 0);
+    state[0] = evalFVSol(mat_blk, intsharp, ncomp, nprim, rdof,
+      nmat, el, inpoel, coord, geoElem, ref_gp_l, B_l, U, P, srcFlag[el]);
+    state[1] = evalFVSol(mat_blk, intsharp, ncomp, nprim, rdof,
+      nmat, er, inpoel, coord, geoElem, ref_gp_r, B_r, U, P, srcFlag[er]);
+
+    //safeReco(rdof, nmat, el, er, U, state);
+
+    Assert( state[0].size() == ncomp+nprim, "Incorrect size for "
+            "appended boundary state vector" );
+    Assert( state[1].size() == ncomp+nprim, "Incorrect size for "
+            "appended boundary state vector" );
+
+    // evaluate prescribed velocity (if any)
+    auto v = vel( ncomp, gp[0], gp[1], gp[2], t );
+
+    // compute flux
+    auto fl = flux( mat_blk, fn, state, v );
+
+    // compute non-conservative terms
+    std::vector< tk::real > var_riemann(nmat+1, 0.0);
+    for (std::size_t k=0; k<nmat+1; ++k) var_riemann[k] = fl[ncomp+k];
 
-      auto state = evalPolynomialSol(mat_blk, intsharp, ncomp, nprim,
-        rdof, nmat, e, dof_el, inpoel, coord, geoElem,
-        {{coordgp[0][igp], coordgp[1][igp], coordgp[2][igp]}}, B, U, P);
-
-      // get bulk properties
-      real rhob(0.0);
-      for (std::size_t k=0; k<nmat; ++k)
-        rhob += state[densityIdx(nmat, k)];
-
-      // get pressures and bulk modulii
-      real pb(0.0), nume(0.0), deno(0.0), trelax(0.0);
-      std::vector< real > apmat(nmat, 0.0), kmat(nmat, 0.0);
-      for (std::size_t k=0; k<nmat; ++k)
-      {
-        real arhomat = state[densityIdx(nmat, k)];
-        real alphamat = state[volfracIdx(nmat, k)];
-        apmat[k] = state[ncomp+pressureIdx(nmat, k)];
-        real amat = 0.0;
-        if (solidx[k] > 0)
-        {
-          std::array< std::array< tk::real, 3 >, 3 > g;
-          for (std::size_t i=0; i<3; ++i)
-            for (std::size_t j=0; j<3; ++j)
-              g[i][j] = state[deformIdx(nmat,solidx[k],i,j)];
-          auto grot = tk::rotateTensor(g, {{1.0, 0.0, 0.0}});
-          amat = mat_blk[k].compute< inciter::EOS::soundspeed >( arhomat,
-            apmat[k], alphamat, k, grot);
-          grot = tk::rotateTensor(g, {{0.0, 1.0, 0.0}});
-          amat = std::max(amat, mat_blk[k].compute< inciter::EOS::soundspeed >(
-            arhomat, apmat[k], alphamat, k, grot));
-          grot = tk::rotateTensor(g, {{0.0, 0.0, 1.0}});
-          amat = std::max(amat, mat_blk[k].compute< inciter::EOS::soundspeed >(
-            arhomat, apmat[k], alphamat, k, grot));
-        }
-        else
-        {
-          amat = mat_blk[k].compute< inciter::EOS::soundspeed >( arhomat,
-            apmat[k], alphamat, k );
-        }
-        kmat[k] = arhomat * amat * amat;
-        pb += apmat[k];
-
-        // relaxation parameters
-        trelax = std::max(trelax, ct*dx/amat);
-        nume += alphamat * apmat[k] / kmat[k];
-        deno += alphamat * alphamat / kmat[k];
-      }
-      auto p_relax = nume/deno;
-
-      // compute pressure relaxation terms
-      std::vector< real > s_prelax(ncomp, 0.0);
-      for (std::size_t k=0; k<nmat; ++k)
-      {
-        auto s_alpha = (apmat[k]-p_relax*state[volfracIdx(nmat, k)])
-          * (state[volfracIdx(nmat, k)]/kmat[k]) / trelax;
-        s_prelax[volfracIdx(nmat, k)] = s_alpha;
-        s_prelax[energyIdx(nmat, k)] = - pb*s_alpha;
-      }
-
-      updateRhsPre( ncomp, ndof, dof_el, wt, e, B, s_prelax, R );
-    }
-  }
-}
-
-void
-updateRhsPre(
-  ncomp_t ncomp,
-  const std::size_t ndof,
-  [[maybe_unused]] const std::size_t ndof_el,
-  const tk::real wt,
-  const std::size_t e,
-  const std::vector< tk::real >& B,
-  std::vector< tk::real >& ncf,
-  Fields& R )
-// *****************************************************************************
-//  Update the rhs by adding the pressure relaxation integrals
-//! \param[in] ncomp Number of scalar components in this PDE system
-//! \param[in] ndof Maximum number of degrees of freedom
-//! \param[in] ndof_el Number of degrees of freedom for local element
-//! \param[in] wt Weight of gauss quadrature point
-//! \param[in] e Element index
-//! \param[in] B Basis function evaluated at local quadrature point
-//! \param[in] ncf Vector of non-conservative terms
-//! \param[in,out] R Right-hand side vector computed
-// *****************************************************************************
-{
-  //Assert( dBdx[0].size() == ndof_el,
-  //        "Size mismatch for basis function derivatives" );
-  //Assert( dBdx[1].size() == ndof_el,
-  //        "Size mismatch for basis function derivatives" );
-  //Assert( dBdx[2].size() == ndof_el,
-  //        "Size mismatch for basis function derivatives" );
-  //Assert( ncf.size() == ncomp,
-  //        "Size mismatch for non-conservative term" );
-  Assert( ncf.size() == ncomp, "Size mismatch for non-conservative term" );
-
-  for (ncomp_t c=0; c<ncomp; ++c)
-  {
-    auto mark = c*ndof;
-    for(std::size_t idof = 0; idof < ndof; idof++)
-      R(e, mark+idof) += wt * ncf[c] * B[idof];
-  }
-}
-
-void
-pressureRelaxationIntFV(
-  std::size_t nmat,
-  const std::vector< inciter::EOS >& mat_blk,
-  const std::size_t rdof,
-  const std::size_t nelem,
-  const std::vector< std::size_t >& inpoel,
-  const UnsMesh::Coords& coord,
-  const Fields& geoElem,
-  const Fields& U,
-  const Fields& P,
-  const tk::real ct,
-  Fields& R )<--- Parameter 'R' can be declared with const
-// *****************************************************************************
-//  Compute volume integrals of pressure relaxation terms in multi-material FV
-//! \details This is called for multi-material FV to compute volume integrals of
-//!   finite pressure relaxation terms in the volume fraction and energy
-//!   equations, which do not exist in the single-material flow formulation (for
-//!   `CompFlow`). For further details see Dobrev, V. A., Kolev, T. V.,
-//!   Rieben, R. N., & Tomov, V. Z. (2016). Multi‐material closure model for
-//!   high‐order finite element Lagrangian hydrodynamics. International Journal
-//!   for Numerical Methods in Fluids, 82(10), 689-706.
-//! \param[in] nmat Number of materials in this PDE system
-//! \param[in] mat_blk EOS material block
-//! \param[in] rdof Maximum number of reconstructed degrees of freedom
-//! \param[in] nelem Total number of elements
-//! \param[in] geoElem Element geometry array
-//! \param[in] U Solution vector at recent time step
-//! \param[in] P Vector of primitive quantities at recent time step
-//! \param[in] ct Pressure relaxation time-scale for this system
-//! \param[in,out] R Right-hand side vector added to
-// *****************************************************************************
-{
-  using inciter::volfracIdx;
-  using inciter::energyIdx;
-  using inciter::pressureIdx;
-  using inciter::velocityIdx;
-  using inciter::densityIdx;
-
-  auto ncomp = U.nprop()/rdof;
-  auto nprim = P.nprop()/rdof;
-
-  // compute volume integrals
-  for (std::size_t e=0; e<nelem; ++e)
-  {
-    auto dx = geoElem(e,4)/2.0;
-
-    // Compute the basis function
-    std::vector< tk::real > B(rdof, 0.0);
-    B[0] = 1.0;
-
-    auto state = evalPolynomialSol(mat_blk, 0, ncomp, nprim,
-      rdof, nmat, e, rdof, inpoel, coord, geoElem,
-      {{0.25, 0.25, 0.25}}, B, U, P);
-
-    // get bulk properties
-    real rhob(0.0);
-    for (std::size_t k=0; k<nmat; ++k)
-      rhob += state[densityIdx(nmat, k)];
-
-    // get pressures and bulk modulii
-    real pb(0.0), nume(0.0), deno(0.0), trelax(0.0);
-    std::vector< real > apmat(nmat, 0.0), kmat(nmat, 0.0);
-    for (std::size_t k=0; k<nmat; ++k)
-    {
-      real arhomat = state[densityIdx(nmat, k)];
-      real alphamat = state[volfracIdx(nmat, k)];
-      apmat[k] = state[ncomp+pressureIdx(nmat, k)];
-      real amat = mat_blk[k].compute< inciter::EOS::soundspeed >( arhomat,
-        apmat[k], alphamat, k );
-      kmat[k] = arhomat * amat * amat;
-      pb += apmat[k];
-
-      // relaxation parameters
-      trelax = std::max(trelax, ct*dx/amat);
-      nume += alphamat * apmat[k] / kmat[k];
-      deno += alphamat * alphamat / kmat[k];
-    }
-    auto p_relax = nume/deno;
-
-    // compute pressure relaxation terms
-    std::vector< real > s_prelax(ncomp, 0.0);
-
-    // terms to ensure only existing materials are relaxed
-    real e_leftover(0), vf_leftover(0);
-    auto almax(0.0);
-    std::size_t kmax = 0;
-    for (std::size_t k=0; k<nmat; ++k)
-    {
-      real alphamat = state[volfracIdx(nmat, k)];
-      auto s_alpha = (apmat[k]-p_relax*state[volfracIdx(nmat, k)])
-        * (state[volfracIdx(nmat, k)]/kmat[k]) / trelax;
-
-      // only perform prelax on existing quantities
-      if (inciter::matExists(state[volfracIdx(nmat,k)])) {
-        s_prelax[volfracIdx(nmat, k)] = s_alpha;
-        s_prelax[energyIdx(nmat, k)] = - pb*s_alpha;
-      } else {
-        vf_leftover += s_alpha;
-        e_leftover  += - pb*s_alpha;
-      }
-      // get material that takes up most volume
-      if (alphamat > almax)
-      {
-        almax = alphamat;
-        kmax = k;
-      }
-    }
-
-    // add leftovers of non-existent mat to mat with most volume
-    s_prelax[volfracIdx(nmat, kmax)] += vf_leftover;
-    s_prelax[energyIdx(nmat, kmax)] += e_leftover;
-
-    for (ncomp_t c=0; c<ncomp; ++c)
-    {
-      R(e, c) += geoElem(e,0) * s_prelax[c];
-    }
-  }
-}
-
-std::vector< std::vector< tk::real > >
-solvevriem( std::size_t nelem,
-            const std::vector< std::vector< tk::real > >& vriem,
-            const std::vector< std::vector< tk::real > >& riemannLoc )
-// *****************************************************************************
-//  Solve the reconstruct velocity used for volume fraction equation by
-//  Least square method
-//! \param[in] nelem Numer of elements
-//! \param[in,out] vriem Vector of the riemann velocity
-//! \param[in,out] riemannLoc Vector of coordinates where Riemann velocity data
-//!   is available
-//! \return Vector of Riemann velocity polynomial solution
-// *****************************************************************************
-{
-  std::vector< std::vector< tk::real > >
-    vriempoly( nelem, std::vector<tk::real>(12,0.0) );
-
-  for (std::size_t e=0; e<nelem; ++e)
-  {
-    // Use the normal method to construct the linear system A^T * A * x = u
-    auto numgp = riemannLoc[e].size()/3;
-    std::vector< std::vector< tk::real > > A(numgp,
-                                             std::vector<tk::real>(4, 1.0));
-
-    for(std::size_t k = 0; k < numgp; k++)
-    {
-      auto mark = k * 3;
-      A[k][1] = riemannLoc[e][mark];
-      A[k][2] = riemannLoc[e][mark+1];
-      A[k][3] = riemannLoc[e][mark+2];
-    }
-
-    for(std::size_t idir = 0; idir < 3; idir++)
-    {
-      double AA_T[4*4], u[4];
-
-      for(std::size_t i = 0; i < 4; i++)
-        for(std::size_t j = 0; j < 4; j++)
-        {
-          auto id = 4 * i + j;
-          AA_T[id] = 0;
-          for(std::size_t k = 0; k < numgp; k++)
-            AA_T[id] += A[k][i] * A[k][j];
-        }
-
-      std::vector<tk::real> vel(numgp, 1.0);
-      for(std::size_t k = 0; k < numgp; k++)
-      {
-        auto mark = k * 3 + idir;
-        vel[k] = vriem[e][mark];
-      }
-      for(std::size_t k = 0; k < 4; k++)
-      {
-        u[k] = 0;
-        for(std::size_t i = 0; i < numgp; i++)
-          u[k] += A[i][k] * vel[i];
-      }
- 
-      lapack_int IPIV[4];
-      #ifndef NDEBUG
-      lapack_int info =
-      #endif
-        LAPACKE_dsysv( LAPACK_ROW_MAJOR, 'U', 4, 1, AA_T, 4, IPIV, u, 1 );
-      Assert( info == 0, "Error in linear system solver" );
-
-      auto idirmark = idir * 4;
-      for(std::size_t k = 0; k < 4; k++)
-        vriempoly[e][idirmark+k] = u[k];
-    }
-  }
-  return vriempoly;
-}
-
-void evaluRiemann( ncomp_t ncomp,
-                   const int e_left,
-                   const int e_right,
-                   const std::size_t nmat,
-                   const std::vector< tk::real >& fl,
-                   const std::array< tk::real, 3 >& fn,
-                   const std::array< tk::real, 3 >& gp,
-                   const std::array< std::vector< tk::real >, 2 >& state,
-                   std::vector< std::vector< tk::real > >& vriem,
-                   std::vector< std::vector< tk::real > >& riemannLoc )
-// *****************************************************************************
-//  Compute the riemann velocity at the interface
-//! \param[in] ncomp Number of scalar components in this PDE system
-//! \param[in] e_left Index for the left element
-//! \param[in] e_right Index for the right element
-//! \param[in] nmat Number of materials in this PDE system
-//! \param[in] fn Face/Surface normal
-//! \param[in] gp Gauss points coordinates
-//! \param[in] fl Surface flux
-//! \param[in] state Vector of state variables for left and right side
-//! \param[in,out] vriem Vector of the riemann velocity
-//! \param[in,out] riemannLoc Vector of coordinates where Riemann velocity data
-//!   is available
-// *****************************************************************************
-{
-  using inciter::densityIdx;
-  using inciter::momentumIdx;
-
-  std::size_t el(0), er(0);
-  el = static_cast< std::size_t >(e_left);
-  if(e_right != -1)
-    er = static_cast< std::size_t >(e_right);
-
-  riemannLoc[el].push_back( gp[0] );
-  riemannLoc[el].push_back( gp[1] );
-  riemannLoc[el].push_back( gp[2] );
-
-  if(e_right != -1)
-  {
-    riemannLoc[er].push_back( gp[0] );
-    riemannLoc[er].push_back( gp[1] );
-    riemannLoc[er].push_back( gp[2] );
-  }
-
-  tk::real rhobl(0.0), rhobr(0.0);
-  for (std::size_t k=0; k<nmat; ++k)
-  {
-    rhobl += state[0][densityIdx(nmat, k)];
-    rhobr += state[1][densityIdx(nmat, k)];
-  }
-
-  auto ul = state[0][momentumIdx(nmat, 0)] / rhobl;
-  auto vl = state[0][momentumIdx(nmat, 1)] / rhobl;
-  auto wl = state[0][momentumIdx(nmat, 2)] / rhobl;
-
-  auto ur = state[1][momentumIdx(nmat, 0)] / rhobr;
-  auto vr = state[1][momentumIdx(nmat, 1)] / rhobr;
-  auto wr = state[1][momentumIdx(nmat, 2)] / rhobr;
-
-  // Compute the normal velocities from left and right cells
-  auto vnl = ul * fn[0] + vl * fn[1] + wl * fn[2];
-  auto vnr = ur * fn[0] + vr * fn[1] + wr * fn[2];
-
-  // The interface velocity is evaluated by adding the normal velocity which
-  // is taken from the Riemann solver and the tangential velocity which is
-  // evaluated as an average of the left and right cells
-  auto urie = 0.5 * ((ul + ur) - fn[0] * (vnl + vnr)) + fl[ncomp+nmat] * fn[0];
-  auto vrie = 0.5 * ((vl + vr) - fn[1] * (vnl + vnr)) + fl[ncomp+nmat] * fn[1];
-  auto wrie = 0.5 * ((wl + wr) - fn[2] * (vnl + vnr)) + fl[ncomp+nmat] * fn[2];
-
-  vriem[el].push_back(urie);
-  vriem[el].push_back(vrie);
-  vriem[el].push_back(wrie);
-
-  if(e_right != -1)
-  {
-    vriem[er].push_back(urie);
-    vriem[er].push_back(vrie);
-    vriem[er].push_back(wrie);
-  }
-}
-
-std::vector< std::array< tk::real, 3 > >
-fluxTerms(
-  std::size_t ncomp,
-  std::size_t nmat,
-  const std::vector< inciter::EOS >& /*mat_blk*/,
-  const std::vector< tk::real >& ugp )
-// *****************************************************************************
-//  Compute the flux-function for the multimaterial PDEs
-//! \param[in] ncomp Number of components in this PDE system
-//! \param[in] nmat Number of materials in this PDE system
-// //! \param[in] mat_blk EOS material block
-//! \param[in] ugp State vector at the Gauss point at which flux is required
-//! \return Flux vectors for all components in multi-material PDE system
-// *****************************************************************************
-{
-  using inciter::volfracIdx;
-  using inciter::densityIdx;
-  using inciter::momentumIdx;
-  using inciter::energyIdx;
-  using inciter::velocityIdx;
-  using inciter::pressureIdx;
-  using inciter::deformIdx;
-
-  const auto& solidx =
-    inciter::g_inputdeck.get< tag::matidxmap, tag::solidx >();
-
-  std::vector< std::array< tk::real, 3 > > fl( ncomp, {{0, 0, 0}} );
-
-  tk::real rho(0.0);<--- Variable 'rho' is assigned a value that is never used.
-  for (std::size_t k=0; k<nmat; ++k)
-    rho += ugp[densityIdx(nmat, k)];<--- Variable 'rho' is assigned a value that is never used.
-
-  auto u = ugp[ncomp+velocityIdx(nmat,0)];
-  auto v = ugp[ncomp+velocityIdx(nmat,1)];
-  auto w = ugp[ncomp+velocityIdx(nmat,2)];
-
-  if (inciter::haveSolid(nmat, solidx))
-  {
-    std::vector< tk::real > al(nmat, 0.0);
-    std::vector< std::array< std::array< tk::real, 3 >, 3 > > g, asig;
-    std::array< std::array< tk::real, 3 >, 3 >
-      sig {{ {{0, 0, 0}}, {{0, 0, 0}}, {{0, 0, 0}} }};
-    for (std::size_t k=0; k<nmat; ++k)
-    {
-      al[k] = ugp[volfracIdx(nmat, k)];
-      // inv deformation gradient and Cauchy stress tensors
-      g.push_back(inciter::getDeformGrad(nmat, k, ugp));
-      asig.push_back(inciter::getCauchyStress(nmat, k, ncomp, ugp));
-      for (std::size_t i=0; i<3; ++i) asig[k][i][i] -= ugp[ncomp+pressureIdx(nmat,k)];
-
-      for (size_t i=0; i<3; ++i)
-        for (size_t j=0; j<3; ++j)
-          sig[i][j] += asig[k][i][j];
-    }
-
-    // conservative part of momentum flux
-    fl[momentumIdx(nmat, 0)][0] = ugp[momentumIdx(nmat, 0)] * u - sig[0][0];
-    fl[momentumIdx(nmat, 1)][0] = ugp[momentumIdx(nmat, 1)] * u - sig[0][1];
-    fl[momentumIdx(nmat, 2)][0] = ugp[momentumIdx(nmat, 2)] * u - sig[0][2];
-
-    fl[momentumIdx(nmat, 0)][1] = ugp[momentumIdx(nmat, 0)] * v - sig[1][0];
-    fl[momentumIdx(nmat, 1)][1] = ugp[momentumIdx(nmat, 1)] * v - sig[1][1];
-    fl[momentumIdx(nmat, 2)][1] = ugp[momentumIdx(nmat, 2)] * v - sig[1][2];
-
-    fl[momentumIdx(nmat, 0)][2] = ugp[momentumIdx(nmat, 0)] * w - sig[2][0];
-    fl[momentumIdx(nmat, 1)][2] = ugp[momentumIdx(nmat, 1)] * w - sig[2][1];
-    fl[momentumIdx(nmat, 2)][2] = ugp[momentumIdx(nmat, 2)] * w - sig[2][2];
-
-    for (std::size_t k=0; k<nmat; ++k)
-    {
-      // conservative part of volume-fraction flux
-      fl[volfracIdx(nmat, k)][0] = 0.0;
-      fl[volfracIdx(nmat, k)][1] = 0.0;
-      fl[volfracIdx(nmat, k)][2] = 0.0;
-
-      // conservative part of material continuity flux
-      fl[densityIdx(nmat, k)][0] = u * ugp[densityIdx(nmat, k)];
-      fl[densityIdx(nmat, k)][1] = v * ugp[densityIdx(nmat, k)];
-      fl[densityIdx(nmat, k)][2] = w * ugp[densityIdx(nmat, k)];
-
-      // conservative part of material total-energy flux
-      fl[energyIdx(nmat, k)][0] = u * ugp[energyIdx(nmat, k)]
-        - u * asig[k][0][0] - v * asig[k][1][0] - w * asig[k][2][0];
-      fl[energyIdx(nmat, k)][1] = v * ugp[energyIdx(nmat, k)]
-        - u * asig[k][0][1] - v * asig[k][1][1] - w * asig[k][2][1];
-      fl[energyIdx(nmat, k)][2] = w * ugp[energyIdx(nmat, k)]
-        - u * asig[k][0][2] - v * asig[k][1][2] - w * asig[k][2][2];
-
-      // conservative part of material inverse deformation gradient
-      // g_ij: \partial (g_il u_l) / \partial (x_j)
-      if (solidx[k] > 0)
-      {
-        for (std::size_t i=0; i<3; ++i)
-        {
-          for (std::size_t j=0; j<3; ++j)
-          {
-            fl[deformIdx(nmat,solidx[k],i,j)][j] =
-              u*g[k][i][0] + v*g[k][i][1] + w*g[k][i][2];
-          }
-          // other components are zero
-        }
-      }
-    }
-  }
-  else
-  {
-    tk::real p(0.0);
-    std::vector< tk::real > apk( nmat, 0.0 );
-    for (std::size_t k=0; k<nmat; ++k)
-    {
-      apk[k] = ugp[ncomp+pressureIdx(nmat,k)];
-      p += apk[k];
-    }
-
-    // conservative part of momentum flux
-    fl[momentumIdx(nmat, 0)][0] = ugp[momentumIdx(nmat, 0)] * u + p;
-    fl[momentumIdx(nmat, 1)][0] = ugp[momentumIdx(nmat, 1)] * u;
-    fl[momentumIdx(nmat, 2)][0] = ugp[momentumIdx(nmat, 2)] * u;
-
-    fl[momentumIdx(nmat, 0)][1] = ugp[momentumIdx(nmat, 0)] * v;
-    fl[momentumIdx(nmat, 1)][1] = ugp[momentumIdx(nmat, 1)] * v + p;
-    fl[momentumIdx(nmat, 2)][1] = ugp[momentumIdx(nmat, 2)] * v;
-
-    fl[momentumIdx(nmat, 0)][2] = ugp[momentumIdx(nmat, 0)] * w;
-    fl[momentumIdx(nmat, 1)][2] = ugp[momentumIdx(nmat, 1)] * w;
-    fl[momentumIdx(nmat, 2)][2] = ugp[momentumIdx(nmat, 2)] * w + p;
-
-    for (std::size_t k=0; k<nmat; ++k)
-    {
-      // conservative part of volume-fraction flux
-      fl[volfracIdx(nmat, k)][0] = 0.0;
-      fl[volfracIdx(nmat, k)][1] = 0.0;
-      fl[volfracIdx(nmat, k)][2] = 0.0;
-
-      // conservative part of material continuity flux
-      fl[densityIdx(nmat, k)][0] = u * ugp[densityIdx(nmat, k)];
-      fl[densityIdx(nmat, k)][1] = v * ugp[densityIdx(nmat, k)];
-      fl[densityIdx(nmat, k)][2] = w * ugp[densityIdx(nmat, k)];
-
-      // conservative part of material total-energy flux
-      auto hmat = ugp[energyIdx(nmat, k)] + apk[k];
-      fl[energyIdx(nmat, k)][0] = u * hmat;
-      fl[energyIdx(nmat, k)][1] = v * hmat;
-      fl[energyIdx(nmat, k)][2] = w * hmat;
-    }
-  }
-
-  return fl;
-}
-
-}// tk::
+    auto ncf_l = nonConservativeIntFV(nmat, rdof, el, fn, U, P, var_riemann);
+    auto ncf_r = nonConservativeIntFV(nmat, rdof, er, fn, U, P, var_riemann);
+
+    // Add the surface integration term to the rhs
+    for (ncomp_t c=0; c<ncomp; ++c)
+    {
+      R(el, c) -= geoFace(f,0) * (fl[c] - ncf_l[c]);
+      R(er, c) += geoFace(f,0) * (fl[c] - ncf_r[c]);
+    }
+  }
+}
+
+} // tk::
 
diff --git a/Debug/cppcheck/67.html b/Debug/cppcheck/67.html index 49cb97bfcf9f..ea19f22d33c2 100644 --- a/Debug/cppcheck/67.html +++ b/Debug/cppcheck/67.html @@ -152,997 +152,5129 @@
- - - - - @@ -111,9 +107,13 @@ + + + + - + diff --git a/Debug/test_coverage/Base/Vector.hpp.func.html b/Debug/test_coverage/Base/Vector.hpp.func.html index 2431f924e421..7c41e2eca893 100644 --- a/Debug/test_coverage/Base/Vector.hpp.func.html +++ b/Debug/test_coverage/Base/Vector.hpp.func.html @@ -27,18 +27,18 @@ - + - + - + - + - + @@ -52,9 +52,9 @@ - + - +
  1
-  2
-  3
-  4
-  5
-  6
-  7
-  8
-  9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
- 37
- 38
- 39
- 40
- 41
- 42
- 43
- 44
- 45
- 46
- 47
- 48
- 49
- 50
- 51
- 52
- 53
- 54
- 55
- 56
- 57
- 58
- 59
- 60
- 61
- 62
- 63
- 64
- 65
- 66
- 67
- 68
- 69
- 70
- 71
- 72
- 73
- 74
- 75
- 76
- 77
- 78
- 79
- 80
- 81
- 82
- 83
- 84
- 85
- 86
- 87
- 88
- 89
- 90
- 91
- 92
- 93
- 94
- 95
- 96
- 97
- 98
- 99
-100
-101
-102
-103
-104
-105
-106
-107
-108
-109
-110
-111
-112
-113
-114
-115
-116
-117
-118
-119
-120
-121
-122
-123
-124
-125
-126
-127
-128
-129
-130
-131
-132
-133
-134
-135
-136
-137
-138
-139
-140
-141
-142
-143
-144
-145
-146
-147
-148
-149
-150
-151
-152
-153
-154
-155
-156
-157
-158
-159
-160
-161
-162
-163
-164
-165
-166
-167
-168
-169
-170
-171
-172
-173
-174
-175
-176
-177
-178
-179
-180
-181
-182
-183
-184
-185
-186
-187
-188
-189
-190
-191
-192
-193
-194
-195
-196
-197
-198
-199
-200
-201
-202
-203
-204
-205
-206
-207
-208
-209
-210
-211
-212
-213
-214
-215
-216
-217
-218
-219
-220
-221
-222
-223
-224
-225
-226
-227
-228
-229
-230
-231
-232
-233
-234
-235
-236
-237
-238
-239
-240
-241
-242
-243
-244
-245
-246
-247
-248
-249
-250
-251
-252
-253
-254
-255
-256
-257
-258
-259
-260
-261
-262
-263
-264
-265
-266
-267
-268
-269
-270
-271
-272
-273
-274
-275
-276
-277
-278
-279
-280
-281
-282
-283
-284
-285
-286
-287
-288
-289
-290
-291
-292
-293
-294
-295
-296
-297
-298
-299
-300
-301
-302
-303
-304
-305
-306
-307
-308
-309
-310
-311
-312
-313
-314
-315
-316
-317
-318
-319
-320
-321
-322
-323
-324
-325
-326
-327
-328
-329
-330
-331
-332
-333
-334
-335
-336
-337
-338
-339
-340
-341
-342
-343
-344
-345
-346
-347
-348
-349
-350
-351
-352
-353
-354
-355
-356
-357
-358
-359
-360
-361
-362
-363
-364
-365
-366
-367
-368
-369
-370
-371
-372
-373
-374
-375
-376
-377
-378
-379
-380
-381
-382
-383
-384
-385
-386
-387
-388
-389
-390
-391
-392
-393
-394
-395
-396
-397
-398
-399
-400
-401
-402
-403
-404
-405
-406
-407
-408
-409
-410
-411
-412
-413
-414
-415
-416
-417
-418
-419
-420
-421
-422
-423
-424
-425
-426
-427
-428
-429
-430
-431
-432
-433
-434
-435
-436
-437
-438
-439
-440
-441
-442
-443
-444
-445
-446
-447
-448
-449
-450
-451
-452
-453
-454
-455
-456
-457
-458
-459
-460
-461
-462
-463
-464
-465
-466
-467
-468
-469
-470
-471
-472
-473
-474
-475
-476
-477
-478
-479
-480
-481
-482
-483
-484
-485
-486
-487
-488
-489
-490
-491
-492
// *****************************************************************************
+
   1
+   2
+   3
+   4
+   5
+   6
+   7
+   8
+   9
+  10
+  11
+  12
+  13
+  14
+  15
+  16
+  17
+  18
+  19
+  20
+  21
+  22
+  23
+  24
+  25
+  26
+  27
+  28
+  29
+  30
+  31
+  32
+  33
+  34
+  35
+  36
+  37
+  38
+  39
+  40
+  41
+  42
+  43
+  44
+  45
+  46
+  47
+  48
+  49
+  50
+  51
+  52
+  53
+  54
+  55
+  56
+  57
+  58
+  59
+  60
+  61
+  62
+  63
+  64
+  65
+  66
+  67
+  68
+  69
+  70
+  71
+  72
+  73
+  74
+  75
+  76
+  77
+  78
+  79
+  80
+  81
+  82
+  83
+  84
+  85
+  86
+  87
+  88
+  89
+  90
+  91
+  92
+  93
+  94
+  95
+  96
+  97
+  98
+  99
+ 100
+ 101
+ 102
+ 103
+ 104
+ 105
+ 106
+ 107
+ 108
+ 109
+ 110
+ 111
+ 112
+ 113
+ 114
+ 115
+ 116
+ 117
+ 118
+ 119
+ 120
+ 121
+ 122
+ 123
+ 124
+ 125
+ 126
+ 127
+ 128
+ 129
+ 130
+ 131
+ 132
+ 133
+ 134
+ 135
+ 136
+ 137
+ 138
+ 139
+ 140
+ 141
+ 142
+ 143
+ 144
+ 145
+ 146
+ 147
+ 148
+ 149
+ 150
+ 151
+ 152
+ 153
+ 154
+ 155
+ 156
+ 157
+ 158
+ 159
+ 160
+ 161
+ 162
+ 163
+ 164
+ 165
+ 166
+ 167
+ 168
+ 169
+ 170
+ 171
+ 172
+ 173
+ 174
+ 175
+ 176
+ 177
+ 178
+ 179
+ 180
+ 181
+ 182
+ 183
+ 184
+ 185
+ 186
+ 187
+ 188
+ 189
+ 190
+ 191
+ 192
+ 193
+ 194
+ 195
+ 196
+ 197
+ 198
+ 199
+ 200
+ 201
+ 202
+ 203
+ 204
+ 205
+ 206
+ 207
+ 208
+ 209
+ 210
+ 211
+ 212
+ 213
+ 214
+ 215
+ 216
+ 217
+ 218
+ 219
+ 220
+ 221
+ 222
+ 223
+ 224
+ 225
+ 226
+ 227
+ 228
+ 229
+ 230
+ 231
+ 232
+ 233
+ 234
+ 235
+ 236
+ 237
+ 238
+ 239
+ 240
+ 241
+ 242
+ 243
+ 244
+ 245
+ 246
+ 247
+ 248
+ 249
+ 250
+ 251
+ 252
+ 253
+ 254
+ 255
+ 256
+ 257
+ 258
+ 259
+ 260
+ 261
+ 262
+ 263
+ 264
+ 265
+ 266
+ 267
+ 268
+ 269
+ 270
+ 271
+ 272
+ 273
+ 274
+ 275
+ 276
+ 277
+ 278
+ 279
+ 280
+ 281
+ 282
+ 283
+ 284
+ 285
+ 286
+ 287
+ 288
+ 289
+ 290
+ 291
+ 292
+ 293
+ 294
+ 295
+ 296
+ 297
+ 298
+ 299
+ 300
+ 301
+ 302
+ 303
+ 304
+ 305
+ 306
+ 307
+ 308
+ 309
+ 310
+ 311
+ 312
+ 313
+ 314
+ 315
+ 316
+ 317
+ 318
+ 319
+ 320
+ 321
+ 322
+ 323
+ 324
+ 325
+ 326
+ 327
+ 328
+ 329
+ 330
+ 331
+ 332
+ 333
+ 334
+ 335
+ 336
+ 337
+ 338
+ 339
+ 340
+ 341
+ 342
+ 343
+ 344
+ 345
+ 346
+ 347
+ 348
+ 349
+ 350
+ 351
+ 352
+ 353
+ 354
+ 355
+ 356
+ 357
+ 358
+ 359
+ 360
+ 361
+ 362
+ 363
+ 364
+ 365
+ 366
+ 367
+ 368
+ 369
+ 370
+ 371
+ 372
+ 373
+ 374
+ 375
+ 376
+ 377
+ 378
+ 379
+ 380
+ 381
+ 382
+ 383
+ 384
+ 385
+ 386
+ 387
+ 388
+ 389
+ 390
+ 391
+ 392
+ 393
+ 394
+ 395
+ 396
+ 397
+ 398
+ 399
+ 400
+ 401
+ 402
+ 403
+ 404
+ 405
+ 406
+ 407
+ 408
+ 409
+ 410
+ 411
+ 412
+ 413
+ 414
+ 415
+ 416
+ 417
+ 418
+ 419
+ 420
+ 421
+ 422
+ 423
+ 424
+ 425
+ 426
+ 427
+ 428
+ 429
+ 430
+ 431
+ 432
+ 433
+ 434
+ 435
+ 436
+ 437
+ 438
+ 439
+ 440
+ 441
+ 442
+ 443
+ 444
+ 445
+ 446
+ 447
+ 448
+ 449
+ 450
+ 451
+ 452
+ 453
+ 454
+ 455
+ 456
+ 457
+ 458
+ 459
+ 460
+ 461
+ 462
+ 463
+ 464
+ 465
+ 466
+ 467
+ 468
+ 469
+ 470
+ 471
+ 472
+ 473
+ 474
+ 475
+ 476
+ 477
+ 478
+ 479
+ 480
+ 481
+ 482
+ 483
+ 484
+ 485
+ 486
+ 487
+ 488
+ 489
+ 490
+ 491
+ 492
+ 493
+ 494
+ 495
+ 496
+ 497
+ 498
+ 499
+ 500
+ 501
+ 502
+ 503
+ 504
+ 505
+ 506
+ 507
+ 508
+ 509
+ 510
+ 511
+ 512
+ 513
+ 514
+ 515
+ 516
+ 517
+ 518
+ 519
+ 520
+ 521
+ 522
+ 523
+ 524
+ 525
+ 526
+ 527
+ 528
+ 529
+ 530
+ 531
+ 532
+ 533
+ 534
+ 535
+ 536
+ 537
+ 538
+ 539
+ 540
+ 541
+ 542
+ 543
+ 544
+ 545
+ 546
+ 547
+ 548
+ 549
+ 550
+ 551
+ 552
+ 553
+ 554
+ 555
+ 556
+ 557
+ 558
+ 559
+ 560
+ 561
+ 562
+ 563
+ 564
+ 565
+ 566
+ 567
+ 568
+ 569
+ 570
+ 571
+ 572
+ 573
+ 574
+ 575
+ 576
+ 577
+ 578
+ 579
+ 580
+ 581
+ 582
+ 583
+ 584
+ 585
+ 586
+ 587
+ 588
+ 589
+ 590
+ 591
+ 592
+ 593
+ 594
+ 595
+ 596
+ 597
+ 598
+ 599
+ 600
+ 601
+ 602
+ 603
+ 604
+ 605
+ 606
+ 607
+ 608
+ 609
+ 610
+ 611
+ 612
+ 613
+ 614
+ 615
+ 616
+ 617
+ 618
+ 619
+ 620
+ 621
+ 622
+ 623
+ 624
+ 625
+ 626
+ 627
+ 628
+ 629
+ 630
+ 631
+ 632
+ 633
+ 634
+ 635
+ 636
+ 637
+ 638
+ 639
+ 640
+ 641
+ 642
+ 643
+ 644
+ 645
+ 646
+ 647
+ 648
+ 649
+ 650
+ 651
+ 652
+ 653
+ 654
+ 655
+ 656
+ 657
+ 658
+ 659
+ 660
+ 661
+ 662
+ 663
+ 664
+ 665
+ 666
+ 667
+ 668
+ 669
+ 670
+ 671
+ 672
+ 673
+ 674
+ 675
+ 676
+ 677
+ 678
+ 679
+ 680
+ 681
+ 682
+ 683
+ 684
+ 685
+ 686
+ 687
+ 688
+ 689
+ 690
+ 691
+ 692
+ 693
+ 694
+ 695
+ 696
+ 697
+ 698
+ 699
+ 700
+ 701
+ 702
+ 703
+ 704
+ 705
+ 706
+ 707
+ 708
+ 709
+ 710
+ 711
+ 712
+ 713
+ 714
+ 715
+ 716
+ 717
+ 718
+ 719
+ 720
+ 721
+ 722
+ 723
+ 724
+ 725
+ 726
+ 727
+ 728
+ 729
+ 730
+ 731
+ 732
+ 733
+ 734
+ 735
+ 736
+ 737
+ 738
+ 739
+ 740
+ 741
+ 742
+ 743
+ 744
+ 745
+ 746
+ 747
+ 748
+ 749
+ 750
+ 751
+ 752
+ 753
+ 754
+ 755
+ 756
+ 757
+ 758
+ 759
+ 760
+ 761
+ 762
+ 763
+ 764
+ 765
+ 766
+ 767
+ 768
+ 769
+ 770
+ 771
+ 772
+ 773
+ 774
+ 775
+ 776
+ 777
+ 778
+ 779
+ 780
+ 781
+ 782
+ 783
+ 784
+ 785
+ 786
+ 787
+ 788
+ 789
+ 790
+ 791
+ 792
+ 793
+ 794
+ 795
+ 796
+ 797
+ 798
+ 799
+ 800
+ 801
+ 802
+ 803
+ 804
+ 805
+ 806
+ 807
+ 808
+ 809
+ 810
+ 811
+ 812
+ 813
+ 814
+ 815
+ 816
+ 817
+ 818
+ 819
+ 820
+ 821
+ 822
+ 823
+ 824
+ 825
+ 826
+ 827
+ 828
+ 829
+ 830
+ 831
+ 832
+ 833
+ 834
+ 835
+ 836
+ 837
+ 838
+ 839
+ 840
+ 841
+ 842
+ 843
+ 844
+ 845
+ 846
+ 847
+ 848
+ 849
+ 850
+ 851
+ 852
+ 853
+ 854
+ 855
+ 856
+ 857
+ 858
+ 859
+ 860
+ 861
+ 862
+ 863
+ 864
+ 865
+ 866
+ 867
+ 868
+ 869
+ 870
+ 871
+ 872
+ 873
+ 874
+ 875
+ 876
+ 877
+ 878
+ 879
+ 880
+ 881
+ 882
+ 883
+ 884
+ 885
+ 886
+ 887
+ 888
+ 889
+ 890
+ 891
+ 892
+ 893
+ 894
+ 895
+ 896
+ 897
+ 898
+ 899
+ 900
+ 901
+ 902
+ 903
+ 904
+ 905
+ 906
+ 907
+ 908
+ 909
+ 910
+ 911
+ 912
+ 913
+ 914
+ 915
+ 916
+ 917
+ 918
+ 919
+ 920
+ 921
+ 922
+ 923
+ 924
+ 925
+ 926
+ 927
+ 928
+ 929
+ 930
+ 931
+ 932
+ 933
+ 934
+ 935
+ 936
+ 937
+ 938
+ 939
+ 940
+ 941
+ 942
+ 943
+ 944
+ 945
+ 946
+ 947
+ 948
+ 949
+ 950
+ 951
+ 952
+ 953
+ 954
+ 955
+ 956
+ 957
+ 958
+ 959
+ 960
+ 961
+ 962
+ 963
+ 964
+ 965
+ 966
+ 967
+ 968
+ 969
+ 970
+ 971
+ 972
+ 973
+ 974
+ 975
+ 976
+ 977
+ 978
+ 979
+ 980
+ 981
+ 982
+ 983
+ 984
+ 985
+ 986
+ 987
+ 988
+ 989
+ 990
+ 991
+ 992
+ 993
+ 994
+ 995
+ 996
+ 997
+ 998
+ 999
+1000
+1001
+1002
+1003
+1004
+1005
+1006
+1007
+1008
+1009
+1010
+1011
+1012
+1013
+1014
+1015
+1016
+1017
+1018
+1019
+1020
+1021
+1022
+1023
+1024
+1025
+1026
+1027
+1028
+1029
+1030
+1031
+1032
+1033
+1034
+1035
+1036
+1037
+1038
+1039
+1040
+1041
+1042
+1043
+1044
+1045
+1046
+1047
+1048
+1049
+1050
+1051
+1052
+1053
+1054
+1055
+1056
+1057
+1058
+1059
+1060
+1061
+1062
+1063
+1064
+1065
+1066
+1067
+1068
+1069
+1070
+1071
+1072
+1073
+1074
+1075
+1076
+1077
+1078
+1079
+1080
+1081
+1082
+1083
+1084
+1085
+1086
+1087
+1088
+1089
+1090
+1091
+1092
+1093
+1094
+1095
+1096
+1097
+1098
+1099
+1100
+1101
+1102
+1103
+1104
+1105
+1106
+1107
+1108
+1109
+1110
+1111
+1112
+1113
+1114
+1115
+1116
+1117
+1118
+1119
+1120
+1121
+1122
+1123
+1124
+1125
+1126
+1127
+1128
+1129
+1130
+1131
+1132
+1133
+1134
+1135
+1136
+1137
+1138
+1139
+1140
+1141
+1142
+1143
+1144
+1145
+1146
+1147
+1148
+1149
+1150
+1151
+1152
+1153
+1154
+1155
+1156
+1157
+1158
+1159
+1160
+1161
+1162
+1163
+1164
+1165
+1166
+1167
+1168
+1169
+1170
+1171
+1172
+1173
+1174
+1175
+1176
+1177
+1178
+1179
+1180
+1181
+1182
+1183
+1184
+1185
+1186
+1187
+1188
+1189
+1190
+1191
+1192
+1193
+1194
+1195
+1196
+1197
+1198
+1199
+1200
+1201
+1202
+1203
+1204
+1205
+1206
+1207
+1208
+1209
+1210
+1211
+1212
+1213
+1214
+1215
+1216
+1217
+1218
+1219
+1220
+1221
+1222
+1223
+1224
+1225
+1226
+1227
+1228
+1229
+1230
+1231
+1232
+1233
+1234
+1235
+1236
+1237
+1238
+1239
+1240
+1241
+1242
+1243
+1244
+1245
+1246
+1247
+1248
+1249
+1250
+1251
+1252
+1253
+1254
+1255
+1256
+1257
+1258
+1259
+1260
+1261
+1262
+1263
+1264
+1265
+1266
+1267
+1268
+1269
+1270
+1271
+1272
+1273
+1274
+1275
+1276
+1277
+1278
+1279
+1280
+1281
+1282
+1283
+1284
+1285
+1286
+1287
+1288
+1289
+1290
+1291
+1292
+1293
+1294
+1295
+1296
+1297
+1298
+1299
+1300
+1301
+1302
+1303
+1304
+1305
+1306
+1307
+1308
+1309
+1310
+1311
+1312
+1313
+1314
+1315
+1316
+1317
+1318
+1319
+1320
+1321
+1322
+1323
+1324
+1325
+1326
+1327
+1328
+1329
+1330
+1331
+1332
+1333
+1334
+1335
+1336
+1337
+1338
+1339
+1340
+1341
+1342
+1343
+1344
+1345
+1346
+1347
+1348
+1349
+1350
+1351
+1352
+1353
+1354
+1355
+1356
+1357
+1358
+1359
+1360
+1361
+1362
+1363
+1364
+1365
+1366
+1367
+1368
+1369
+1370
+1371
+1372
+1373
+1374
+1375
+1376
+1377
+1378
+1379
+1380
+1381
+1382
+1383
+1384
+1385
+1386
+1387
+1388
+1389
+1390
+1391
+1392
+1393
+1394
+1395
+1396
+1397
+1398
+1399
+1400
+1401
+1402
+1403
+1404
+1405
+1406
+1407
+1408
+1409
+1410
+1411
+1412
+1413
+1414
+1415
+1416
+1417
+1418
+1419
+1420
+1421
+1422
+1423
+1424
+1425
+1426
+1427
+1428
+1429
+1430
+1431
+1432
+1433
+1434
+1435
+1436
+1437
+1438
+1439
+1440
+1441
+1442
+1443
+1444
+1445
+1446
+1447
+1448
+1449
+1450
+1451
+1452
+1453
+1454
+1455
+1456
+1457
+1458
+1459
+1460
+1461
+1462
+1463
+1464
+1465
+1466
+1467
+1468
+1469
+1470
+1471
+1472
+1473
+1474
+1475
+1476
+1477
+1478
+1479
+1480
+1481
+1482
+1483
+1484
+1485
+1486
+1487
+1488
+1489
+1490
+1491
+1492
+1493
+1494
+1495
+1496
+1497
+1498
+1499
+1500
+1501
+1502
+1503
+1504
+1505
+1506
+1507
+1508
+1509
+1510
+1511
+1512
+1513
+1514
+1515
+1516
+1517
+1518
+1519
+1520
+1521
+1522
+1523
+1524
+1525
+1526
+1527
+1528
+1529
+1530
+1531
+1532
+1533
+1534
+1535
+1536
+1537
+1538
+1539
+1540
+1541
+1542
+1543
+1544
+1545
+1546
+1547
+1548
+1549
+1550
+1551
+1552
+1553
+1554
+1555
+1556
+1557
+1558
+1559
+1560
+1561
+1562
+1563
+1564
+1565
+1566
+1567
+1568
+1569
+1570
+1571
+1572
+1573
+1574
+1575
+1576
+1577
+1578
+1579
+1580
+1581
+1582
+1583
+1584
+1585
+1586
+1587
+1588
+1589
+1590
+1591
+1592
+1593
+1594
+1595
+1596
+1597
+1598
+1599
+1600
+1601
+1602
+1603
+1604
+1605
+1606
+1607
+1608
+1609
+1610
+1611
+1612
+1613
+1614
+1615
+1616
+1617
+1618
+1619
+1620
+1621
+1622
+1623
+1624
+1625
+1626
+1627
+1628
+1629
+1630
+1631
+1632
+1633
+1634
+1635
+1636
+1637
+1638
+1639
+1640
+1641
+1642
+1643
+1644
+1645
+1646
+1647
+1648
+1649
+1650
+1651
+1652
+1653
+1654
+1655
+1656
+1657
+1658
+1659
+1660
+1661
+1662
+1663
+1664
+1665
+1666
+1667
+1668
+1669
+1670
+1671
+1672
+1673
+1674
+1675
+1676
+1677
+1678
+1679
+1680
+1681
+1682
+1683
+1684
+1685
+1686
+1687
+1688
+1689
+1690
+1691
+1692
+1693
+1694
+1695
+1696
+1697
+1698
+1699
+1700
+1701
+1702
+1703
+1704
+1705
+1706
+1707
+1708
+1709
+1710
+1711
+1712
+1713
+1714
+1715
+1716
+1717
+1718
+1719
+1720
+1721
+1722
+1723
+1724
+1725
+1726
+1727
+1728
+1729
+1730
+1731
+1732
+1733
+1734
+1735
+1736
+1737
+1738
+1739
+1740
+1741
+1742
+1743
+1744
+1745
+1746
+1747
+1748
+1749
+1750
+1751
+1752
+1753
+1754
+1755
+1756
+1757
+1758
+1759
+1760
+1761
+1762
+1763
+1764
+1765
+1766
+1767
+1768
+1769
+1770
+1771
+1772
+1773
+1774
+1775
+1776
+1777
+1778
+1779
+1780
+1781
+1782
+1783
+1784
+1785
+1786
+1787
+1788
+1789
+1790
+1791
+1792
+1793
+1794
+1795
+1796
+1797
+1798
+1799
+1800
+1801
+1802
+1803
+1804
+1805
+1806
+1807
+1808
+1809
+1810
+1811
+1812
+1813
+1814
+1815
+1816
+1817
+1818
+1819
+1820
+1821
+1822
+1823
+1824
+1825
+1826
+1827
+1828
+1829
+1830
+1831
+1832
+1833
+1834
+1835
+1836
+1837
+1838
+1839
+1840
+1841
+1842
+1843
+1844
+1845
+1846
+1847
+1848
+1849
+1850
+1851
+1852
+1853
+1854
+1855
+1856
+1857
+1858
+1859
+1860
+1861
+1862
+1863
+1864
+1865
+1866
+1867
+1868
+1869
+1870
+1871
+1872
+1873
+1874
+1875
+1876
+1877
+1878
+1879
+1880
+1881
+1882
+1883
+1884
+1885
+1886
+1887
+1888
+1889
+1890
+1891
+1892
+1893
+1894
+1895
+1896
+1897
+1898
+1899
+1900
+1901
+1902
+1903
+1904
+1905
+1906
+1907
+1908
+1909
+1910
+1911
+1912
+1913
+1914
+1915
+1916
+1917
+1918
+1919
+1920
+1921
+1922
+1923
+1924
+1925
+1926
+1927
+1928
+1929
+1930
+1931
+1932
+1933
+1934
+1935
+1936
+1937
+1938
+1939
+1940
+1941
+1942
+1943
+1944
+1945
+1946
+1947
+1948
+1949
+1950
+1951
+1952
+1953
+1954
+1955
+1956
+1957
+1958
+1959
+1960
+1961
+1962
+1963
+1964
+1965
+1966
+1967
+1968
+1969
+1970
+1971
+1972
+1973
+1974
+1975
+1976
+1977
+1978
+1979
+1980
+1981
+1982
+1983
+1984
+1985
+1986
+1987
+1988
+1989
+1990
+1991
+1992
+1993
+1994
+1995
+1996
+1997
+1998
+1999
+2000
+2001
+2002
+2003
+2004
+2005
+2006
+2007
+2008
+2009
+2010
+2011
+2012
+2013
+2014
+2015
+2016
+2017
+2018
+2019
+2020
+2021
+2022
+2023
+2024
+2025
+2026
+2027
+2028
+2029
+2030
+2031
+2032
+2033
+2034
+2035
+2036
+2037
+2038
+2039
+2040
+2041
+2042
+2043
+2044
+2045
+2046
+2047
+2048
+2049
+2050
+2051
+2052
+2053
+2054
+2055
+2056
+2057
+2058
+2059
+2060
+2061
+2062
+2063
+2064
+2065
+2066
+2067
+2068
+2069
+2070
+2071
+2072
+2073
+2074
+2075
+2076
+2077
+2078
+2079
+2080
+2081
+2082
+2083
+2084
+2085
+2086
+2087
+2088
+2089
+2090
+2091
+2092
+2093
+2094
+2095
+2096
+2097
+2098
+2099
+2100
+2101
+2102
+2103
+2104
+2105
+2106
+2107
+2108
+2109
+2110
+2111
+2112
+2113
+2114
+2115
+2116
+2117
+2118
+2119
+2120
+2121
+2122
+2123
+2124
+2125
+2126
+2127
+2128
+2129
+2130
+2131
+2132
+2133
+2134
+2135
+2136
+2137
+2138
+2139
+2140
+2141
+2142
+2143
+2144
+2145
+2146
+2147
+2148
+2149
+2150
+2151
+2152
+2153
+2154
+2155
+2156
+2157
+2158
+2159
+2160
+2161
+2162
+2163
+2164
+2165
+2166
+2167
+2168
+2169
+2170
+2171
+2172
+2173
+2174
+2175
+2176
+2177
+2178
+2179
+2180
+2181
+2182
+2183
+2184
+2185
+2186
+2187
+2188
+2189
+2190
+2191
+2192
+2193
+2194
+2195
+2196
+2197
+2198
+2199
+2200
+2201
+2202
+2203
+2204
+2205
+2206
+2207
+2208
+2209
+2210
+2211
+2212
+2213
+2214
+2215
+2216
+2217
+2218
+2219
+2220
+2221
+2222
+2223
+2224
+2225
+2226
+2227
+2228
+2229
+2230
+2231
+2232
+2233
+2234
+2235
+2236
+2237
+2238
+2239
+2240
+2241
+2242
+2243
+2244
+2245
+2246
+2247
+2248
+2249
+2250
+2251
+2252
+2253
+2254
+2255
+2256
+2257
+2258
+2259
+2260
+2261
+2262
+2263
+2264
+2265
+2266
+2267
+2268
+2269
+2270
+2271
+2272
+2273
+2274
+2275
+2276
+2277
+2278
+2279
+2280
+2281
+2282
+2283
+2284
+2285
+2286
+2287
+2288
+2289
+2290
+2291
+2292
+2293
+2294
+2295
+2296
+2297
+2298
+2299
+2300
+2301
+2302
+2303
+2304
+2305
+2306
+2307
+2308
+2309
+2310
+2311
+2312
+2313
+2314
+2315
+2316
+2317
+2318
+2319
+2320
+2321
+2322
+2323
+2324
+2325
+2326
+2327
+2328
+2329
+2330
+2331
+2332
+2333
+2334
+2335
+2336
+2337
+2338
+2339
+2340
+2341
+2342
+2343
+2344
+2345
+2346
+2347
+2348
+2349
+2350
+2351
+2352
+2353
+2354
+2355
+2356
+2357
+2358
+2359
+2360
+2361
+2362
+2363
+2364
+2365
+2366
+2367
+2368
+2369
+2370
+2371
+2372
+2373
+2374
+2375
+2376
+2377
+2378
+2379
+2380
+2381
+2382
+2383
+2384
+2385
+2386
+2387
+2388
+2389
+2390
+2391
+2392
+2393
+2394
+2395
+2396
+2397
+2398
+2399
+2400
+2401
+2402
+2403
+2404
+2405
+2406
+2407
+2408
+2409
+2410
+2411
+2412
+2413
+2414
+2415
+2416
+2417
+2418
+2419
+2420
+2421
+2422
+2423
+2424
+2425
+2426
+2427
+2428
+2429
+2430
+2431
+2432
+2433
+2434
+2435
+2436
+2437
+2438
+2439
+2440
+2441
+2442
+2443
+2444
+2445
+2446
+2447
+2448
+2449
+2450
+2451
+2452
+2453
+2454
+2455
+2456
+2457
+2458
+2459
+2460
+2461
+2462
+2463
+2464
+2465
+2466
+2467
+2468
+2469
+2470
+2471
+2472
+2473
+2474
+2475
+2476
+2477
+2478
+2479
+2480
+2481
+2482
+2483
+2484
+2485
+2486
+2487
+2488
+2489
+2490
+2491
+2492
+2493
+2494
+2495
+2496
+2497
+2498
+2499
+2500
+2501
+2502
+2503
+2504
+2505
+2506
+2507
+2508
+2509
+2510
+2511
+2512
+2513
+2514
+2515
+2516
+2517
+2518
+2519
+2520
+2521
+2522
+2523
+2524
+2525
+2526
+2527
+2528
+2529
+2530
+2531
+2532
+2533
+2534
+2535
+2536
+2537
+2538
+2539
+2540
+2541
+2542
+2543
+2544
+2545
+2546
+2547
+2548
+2549
+2550
+2551
+2552
// *****************************************************************************
 /*!
-  \file      src/PDE/Integrate/Surface.cpp
+  \file      src/PDE/Limiter.cpp
   \copyright 2012-2015 J. Bakosi,
              2016-2018 Los Alamos National Security, LLC.,
              2019-2021 Triad National Security, LLC.
              All rights reserved. See the LICENSE file for details.
-  \brief     Functions for computing internal surface integrals of a system
-     of PDEs in DG methods
-  \details   This file contains functionality for computing internal surface
-     integrals of a system of PDEs used in discontinuous Galerkin methods for
-     various orders of numerical representation.
-*/
-// *****************************************************************************
-
-#include <array>
+  \brief     Limiters for discontiunous Galerkin methods
+  \details   This file contains functions that provide limiter function
+    calculations for maintaining monotonicity near solution discontinuities
+    for the DG discretization.
+*/
+// *****************************************************************************
+
+#include <array>
+#include <vector>
 
-#include "Surface.hpp"
+#include "FaceData.hpp"
 #include "Vector.hpp"
-#include "Quadrature.hpp"
-#include "Reconstruction.hpp"
-#include "Integrate/SolidTerms.hpp"
-#include "Inciter/InputDeck/InputDeck.hpp"
-#include "MultiMat/MiscMultiMatFns.hpp"
-
-namespace inciter {
-extern ctr::InputDeck g_inputdeck;
-}
+#include "Limiter.hpp"
+#include "DerivedData.hpp"
+#include "Integrate/Quadrature.hpp"
+#include "Integrate/Basis.hpp"
+#include "Inciter/InputDeck/InputDeck.hpp"
+#include "PrefIndicator.hpp"
+#include "Reconstruction.hpp"
+#include "Integrate/Mass.hpp"
+#include "MultiMat/MiscMultiMatFns.hpp"
 
-namespace tk {
+namespace inciter {
 
-void
-surfInt( std::size_t nmat,
-         const std::vector< inciter::EOS >& mat_blk,
-         real t,
-         const std::size_t ndof,
-         const std::size_t rdof,
-         const std::vector< std::size_t >& inpoel,
-         const std::vector< std::size_t >& /*solidx*/,
-         const UnsMesh::Coords& coord,
-         const inciter::FaceData& fd,
-         const Fields& geoFace,
-         const Fields& geoElem,
-         const RiemannFluxFn& flux,
-         const VelFn& vel,
-         const Fields& U,
-         const Fields& P,
-         const std::vector< std::size_t >& ndofel,
-         const tk::real /*dt*/,
-         Fields& R,
-         std::vector< std::vector< tk::real > >&,
-         std::vector< std::vector< tk::real > >&,
-         std::vector< std::vector< tk::real > >& riemannDeriv,
-         int intsharp )
-// *****************************************************************************
-//  Compute internal surface flux integrals
-//! \param[in] nmat Number of materials in this PDE system
-//! \param[in] mat_blk EOS material block
-//! \param[in] t Physical time
-//! \param[in] ndof Maximum number of degrees of freedom
-//! \param[in] rdof Maximum number of reconstructed degrees of freedom
-//! \param[in] inpoel Element-node connectivity
-// //! \param[in] solidx Material index indicator
-//! \param[in] coord Array of nodal coordinates
-//! \param[in] fd Face connectivity and boundary conditions object
-//! \param[in] geoFace Face geometry array
-//! \param[in] geoElem Element geometry array
-//! \param[in] flux Riemann flux function to use
-//! \param[in] vel Function to use to query prescribed velocity (if any)
-//! \param[in] U Solution vector at recent time step
-//! \param[in] P Vector of primitives at recent time step
-//! \param[in] ndofel Vector of local number of degrees of freedom
-// //! \param[in] dt Delta time
-//! \param[in,out] R Right-hand side vector computed
-//! \param[in,out] vriem Vector of the riemann velocity
-//! \param[in,out] riemannLoc Vector of coordinates where Riemann velocity data
-//!   is available
-//! \param[in,out] riemannDeriv Derivatives of partial-pressures and velocities
-//!   computed from the Riemann solver for use in the non-conservative terms.
-//!   These derivatives are used only for multi-material hydro and unused for
-//!   single-material compflow and linear transport.
-//! \param[in] intsharp Interface compression tag, an optional argument, with
-//!   default 0, so that it is unused for single-material and transport.
-// *****************************************************************************
-{
-  const auto& esuf = fd.Esuf();
-  const auto& inpofa = fd.Inpofa();
-
-  const auto& cx = coord[0];
-  const auto& cy = coord[1];
-  const auto& cz = coord[2];
+extern ctr::InputDeck g_inputdeck;
+
+void
+WENO_P1( const std::vector< int >& esuel,
+         tk::Fields& U )
+// *****************************************************************************
+//  Weighted Essentially Non-Oscillatory (WENO) limiter for DGP1
+//! \param[in] esuel Elements surrounding elements
+//! \param[in,out] U High-order solution vector which gets limited
+//! \details This WENO function should be called for transport and compflow
+//! \note This limiter function is experimental and untested. Use with caution.
+// *****************************************************************************
+{
+  const auto rdof = inciter::g_inputdeck.get< tag::rdof >();
+  const auto cweight = inciter::g_inputdeck.get< tag::cweight >();
+  auto nelem = esuel.size()/4;
+  std::array< std::vector< tk::real >, 3 >
+    limU {{ std::vector< tk::real >(nelem),
+            std::vector< tk::real >(nelem),
+            std::vector< tk::real >(nelem) }};
+
+  std::size_t ncomp = U.nprop()/rdof;
+
+  for (inciter::ncomp_t c=0; c<ncomp; ++c)
+  {
+    for (std::size_t e=0; e<nelem; ++e)
+    {
+      WENOLimiting(U, esuel, e, c, rdof, cweight, limU);
+    }
+
+    auto mark = c*rdof;
+
+    for (std::size_t e=0; e<nelem; ++e)
+    {
+      U(e, mark+1) = limU[0][e];
+      U(e, mark+2) = limU[1][e];
+      U(e, mark+3) = limU[2][e];
+    }
+  }
+}
+
+void
+Superbee_P1( const std::vector< int >& esuel,
+             const std::vector< std::size_t >& inpoel,
+             const std::vector< std::size_t >& ndofel,
+             const tk::UnsMesh::Coords& coord,
+             tk::Fields& U )
+// *****************************************************************************
+//  Superbee limiter for DGP1
+//! \param[in] esuel Elements surrounding elements
+//! \param[in] inpoel Element connectivity
+//! \param[in] ndofel Vector of local number of degrees of freedom
+//! \param[in] coord Array of nodal coordinates
+//! \param[in,out] U High-order solution vector which gets limited
+//! \details This Superbee function should be called for transport and compflow
+// *****************************************************************************
+{
+  const auto rdof = inciter::g_inputdeck.get< tag::rdof >();
+  const auto ndof = inciter::g_inputdeck.get< tag::ndof >();
+  std::size_t ncomp = U.nprop()/rdof;
 
-  auto ncomp = U.nprop()/rdof;<--- Variable 'ncomp' is assigned a value that is never used.
-  auto nprim = P.nprop()/rdof;<--- Variable 'nprim' is assigned a value that is never used.
-
-  //// Determine if we have solids in our problem
-  //bool haveSolid = inciter::haveSolid(nmat, solidx);
-
-  //Assert( (nmat==1 ? riemannDeriv.empty() : true), "Non-empty Riemann "
-  //        "derivative vector for single material compflow" );
-
-  // compute internal surface flux integrals
-  for (auto f=fd.Nbfac(); f<esuf.size()/2; ++f)
-  {
-    Assert( esuf[2*f] > -1 && esuf[2*f+1] > -1, "Interior element detected "
-            "as -1" );
-
-    std::size_t el = static_cast< std::size_t >(esuf[2*f]);
-    std::size_t er = static_cast< std::size_t >(esuf[2*f+1]);
-
-    auto ng_l = tk::NGfa(ndofel[el]);
-    auto ng_r = tk::NGfa(ndofel[er]);
-
-    // When the number of gauss points for the left and right element are
-    // different, choose the larger ng
-    auto ng = std::max( ng_l, ng_r );
-
-    // arrays for quadrature points
-    std::array< std::vector< real >, 2 > coordgp;
-    std::vector< real > wgp;
-
-    coordgp[0].resize( ng );
-    coordgp[1].resize( ng );
-    wgp.resize( ng );
-
-    // get quadrature point weights and coordinates for triangle
-    GaussQuadratureTri( ng, coordgp, wgp );
+  auto beta_lim = 2.0;
+
+  for (std::size_t e=0; e<esuel.size()/4; ++e)
+  {
+    // If an rDG method is set up (P0P1), then, currently we compute the P1
+    // basis functions and solutions by default. This implies that P0P1 is
+    // unsupported in the p-adaptive DG (PDG). This is a workaround until we
+    // have rdofel, which is needed to distinguish between ndofs and rdofs per
+    // element for pDG.
+    std::size_t dof_el;
+    if (rdof > ndof)
+    {
+      dof_el = rdof;
+    }
+    else
+    {
+      dof_el = ndofel[e];
+    }
+
+    if (dof_el > 1)
+    {
+      auto phi = SuperbeeLimiting(U, esuel, inpoel, coord, e, ndof, rdof,
+                   dof_el, ncomp, beta_lim);
+
+      // apply limiter function
+      for (inciter::ncomp_t c=0; c<ncomp; ++c)
+      {
+        auto mark = c*rdof;
+        U(e, mark+1) = phi[c] * U(e, mark+1);
+        U(e, mark+2) = phi[c] * U(e, mark+2);
+        U(e, mark+3) = phi[c] * U(e, mark+3);
+      }
+    }
+  }
+}
 
-    // Extract the element coordinates
-    std::array< std::array< tk::real, 3>, 4 > coordel_l {{
-      {{ cx[ inpoel[4*el  ] ], cy[ inpoel[4*el  ] ], cz[ inpoel[4*el  ] ] }},
-      {{ cx[ inpoel[4*el+1] ], cy[ inpoel[4*el+1] ], cz[ inpoel[4*el+1] ] }},
-      {{ cx[ inpoel[4*el+2] ], cy[ inpoel[4*el+2] ], cz[ inpoel[4*el+2] ] }},
-      {{ cx[ inpoel[4*el+3] ], cy[ inpoel[4*el+3] ], cz[ inpoel[4*el+3] ] }} }};
-
-    std::array< std::array< tk::real, 3>, 4 > coordel_r {{
-      {{ cx[ inpoel[4*er  ] ], cy[ inpoel[4*er  ] ], cz[ inpoel[4*er  ] ] }},
-      {{ cx[ inpoel[4*er+1] ], cy[ inpoel[4*er+1] ], cz[ inpoel[4*er+1] ] }},
-      {{ cx[ inpoel[4*er+2] ], cy[ inpoel[4*er+2] ], cz[ inpoel[4*er+2] ] }},
-      {{ cx[ inpoel[4*er+3] ], cy[ inpoel[4*er+3] ], cz[ inpoel[4*er+3] ] }} }};
-
-    // Compute the determinant of Jacobian matrix
-    auto detT_l =
-      Jacobian( coordel_l[0], coordel_l[1], coordel_l[2], coordel_l[3] );
-    auto detT_r =
-      Jacobian( coordel_r[0], coordel_r[1], coordel_r[2], coordel_r[3] );
-
-    // Extract the face coordinates
-    std::array< std::array< tk::real, 3>, 3 > coordfa {{
-      {{ cx[ inpofa[3*f  ] ], cy[ inpofa[3*f  ] ], cz[ inpofa[3*f  ] ] }},
-      {{ cx[ inpofa[3*f+1] ], cy[ inpofa[3*f+1] ], cz[ inpofa[3*f+1] ] }},
-      {{ cx[ inpofa[3*f+2] ], cy[ inpofa[3*f+2] ], cz[ inpofa[3*f+2] ] }} }};
-
-    std::array< real, 3 >
-      fn{{ geoFace(f,1), geoFace(f,2), geoFace(f,3) }};
-
-    // Gaussian quadrature
-    for (std::size_t igp=0; igp<ng; ++igp)
-    {
-      // Compute the coordinates of quadrature point at physical domain
-      auto gp = eval_gp( igp, coordfa, coordgp );
-
-      // In order to determine the high-order solution from the left and right
-      // elements at the surface quadrature points, the basis functions from
-      // the left and right elements are needed. For this, a transformation to
-      // the reference coordinates is necessary, since the basis functions are
-      // defined on the reference tetrahedron only.
-      // The transformation relations are shown below:
-      //  xi   = Jacobian( coordel[0], gp, coordel[2], coordel[3] ) / detT
-      //  eta  = Jacobian( coordel[0], coordel[2], gp, coordel[3] ) / detT
-      //  zeta = Jacobian( coordel[0], coordel[2], coordel[3], gp ) / detT
-
-      // If an rDG method is set up (P0P1), then, currently we compute the P1
-      // basis functions and solutions by default. This implies that P0P1 is
-      // unsupported in the p-adaptive DG (PDG). This is a workaround until we
-      // have rdofel, which is needed to distinguish between ndofs and rdofs per
-      // element for pDG.
-      std::size_t dof_el, dof_er;
-      if (rdof > ndof)
-      {
-        dof_el = rdof;
-        dof_er = rdof;
-      }
-      else
-      {
-        dof_el = ndofel[el];
-        dof_er = ndofel[er];
-      }
-
-      std::array< tk::real, 3> ref_gp_l{
-        Jacobian( coordel_l[0], gp, coordel_l[2], coordel_l[3] ) / detT_l,
-        Jacobian( coordel_l[0], coordel_l[1], gp, coordel_l[3] ) / detT_l,
-        Jacobian( coordel_l[0], coordel_l[1], coordel_l[2], gp ) / detT_l };
-      std::array< tk::real, 3> ref_gp_r{
-        Jacobian( coordel_r[0], gp, coordel_r[2], coordel_r[3] ) / detT_r,
-        Jacobian( coordel_r[0], coordel_r[1], gp, coordel_r[3] ) / detT_r,
-        Jacobian( coordel_r[0], coordel_r[1], coordel_r[2], gp ) / detT_r };
-
-      //Compute the basis functions
-      auto B_l = eval_basis( dof_el, ref_gp_l[0], ref_gp_l[1], ref_gp_l[2] );
-      auto B_r = eval_basis( dof_er, ref_gp_r[0], ref_gp_r[1], ref_gp_r[2] );
-
-      auto wt = wgp[igp] * geoFace(f,0);<--- Variable 'wt' is assigned a value that is never used.
-
-      std::array< std::vector< real >, 2 > state;
-
-      state[0] = evalPolynomialSol(mat_blk, intsharp, ncomp, nprim, rdof,
-        nmat, el, dof_el, inpoel, coord, geoElem, ref_gp_l, B_l, U, P);
-      state[1] = evalPolynomialSol(mat_blk, intsharp, ncomp, nprim, rdof,
-        nmat, er, dof_er, inpoel, coord, geoElem, ref_gp_r, B_r, U, P);
-
-      Assert( state[0].size() == ncomp+nprim, "Incorrect size for "
-              "appended boundary state vector" );
-      Assert( state[1].size() == ncomp+nprim, "Incorrect size for "
-              "appended boundary state vector" );
-
-      // evaluate prescribed velocity (if any)
-      auto v = vel( ncomp, gp[0], gp[1], gp[2], t );
-
-      // compute flux
-      auto fl = flux( mat_blk, fn, state, v );
-
-      // Add the surface integration term to the rhs
-      update_rhs_fa( ncomp, nmat, ndof, ndofel[el], ndofel[er], wt, fn,
-                     el, er, fl, B_l, B_r, R, riemannDeriv );
-    }
-  }
-}
-
-void
-update_rhs_fa( ncomp_t ncomp,
-               std::size_t nmat,
-               const std::size_t ndof,
-               const std::size_t ndof_l,
-               const std::size_t ndof_r,
-               const tk::real wt,
-               const std::array< tk::real, 3 >& fn,
-               const std::size_t el,
-               const std::size_t er,
-               const std::vector< tk::real >& fl,
-               const std::vector< tk::real >& B_l,
-               const std::vector< tk::real >& B_r,
-               Fields& R,<--- Parameter 'R' can be declared with const
-               std::vector< std::vector< tk::real > >& riemannDeriv )
-// *****************************************************************************
-//  Update the rhs by adding the surface integration term
-//! \param[in] ncomp Number of scalar components in this PDE system
-//! \param[in] nmat Number of materials in this PDE system
-//! \param[in] ndof Maximum number of degrees of freedom
-//! \param[in] ndof_l Number of degrees of freedom for left element
-//! \param[in] ndof_r Number of degrees of freedom for right element
-//! \param[in] wt Weight of gauss quadrature point
-//! \param[in] fn Face/Surface normal
-//! \param[in] el Left element index
-//! \param[in] er Right element index
-//! \param[in] fl Surface flux
-//! \param[in] B_l Basis function for the left element
-//! \param[in] B_r Basis function for the right element
-//! \param[in,out] R Right-hand side vector computed
-//! \param[in,out] riemannDeriv Derivatives of partial-pressures and velocities
-//!   computed from the Riemann solver for use in the non-conservative terms.
-//!   These derivatives are used only for multi-material hydro and unused for
-//!   single-material compflow and linear transport.
-// *****************************************************************************
-{
-  // following lines commented until rdofel is made available.
-  //Assert( B_l.size() == ndof_l, "Size mismatch" );
-  //Assert( B_r.size() == ndof_r, "Size mismatch" );
-
-  using inciter::newSolidsAccFn;
-
-  const auto& solidx =
-    inciter::g_inputdeck.get< tag::matidxmap, tag::solidx >();
-
-  for (ncomp_t c=0; c<ncomp; ++c)
-  {
-    auto mark = c*ndof;
-    R(el, mark) -= wt * fl[c];
-    R(er, mark) += wt * fl[c];
-
-    if(ndof_l > 1)          //DG(P1)
-    {
-      R(el, mark+1) -= wt * fl[c] * B_l[1];
-      R(el, mark+2) -= wt * fl[c] * B_l[2];
-      R(el, mark+3) -= wt * fl[c] * B_l[3];
-    }
-
-    if(ndof_r > 1)          //DG(P1)
-    {
-      R(er, mark+1) += wt * fl[c] * B_r[1];
-      R(er, mark+2) += wt * fl[c] * B_r[2];
-      R(er, mark+3) += wt * fl[c] * B_r[3];
-    }
-
-    if(ndof_l > 4)          //DG(P2)
-    {
-      R(el, mark+4) -= wt * fl[c] * B_l[4];
-      R(el, mark+5) -= wt * fl[c] * B_l[5];
-      R(el, mark+6) -= wt * fl[c] * B_l[6];
-      R(el, mark+7) -= wt * fl[c] * B_l[7];
-      R(el, mark+8) -= wt * fl[c] * B_l[8];
-      R(el, mark+9) -= wt * fl[c] * B_l[9];
-    }
-
-    if(ndof_r > 4)          //DG(P2)
-    {
-      R(er, mark+4) += wt * fl[c] * B_r[4];
-      R(er, mark+5) += wt * fl[c] * B_r[5];
-      R(er, mark+6) += wt * fl[c] * B_r[6];
-      R(er, mark+7) += wt * fl[c] * B_r[7];
-      R(er, mark+8) += wt * fl[c] * B_r[8];
-      R(er, mark+9) += wt * fl[c] * B_r[9];
-    }
-  }
-
-  // Prep for non-conservative terms in multimat
-  if (fl.size() > ncomp)
-  {
-    // Gradients of partial pressures
-    for (std::size_t k=0; k<nmat; ++k)
-    {
-      for (std::size_t idir=0; idir<3; ++idir)
-      {
-        riemannDeriv[3*k+idir][el] += wt * fl[ncomp+k] * fn[idir];
-        riemannDeriv[3*k+idir][er] -= wt * fl[ncomp+k] * fn[idir];
-      }
-    }
-
-    // Divergence of velocity multiples basis fucntion( d(uB) / dx )
-    for(std::size_t idof = 0; idof < ndof; idof++) {
-      riemannDeriv[3*nmat+idof][el] += wt * fl[ncomp+nmat] * B_l[idof];
-      riemannDeriv[3*nmat+idof][er] -= wt * fl[ncomp+nmat] * B_r[idof];
-    }
-
-    // Divergence of asigma: d(asig_ij)/dx_j
-    for (std::size_t k=0; k<nmat; ++k)
-      if (solidx[k] > 0)
-      {
-        std::size_t mark = ncomp+nmat+1+3*(solidx[k]-1);
-
-        for (std::size_t i=0; i<3; ++i)
-        {
-          riemannDeriv[3*nmat+ndof+3*(solidx[k]-1)+i][el] -=
-            wt * fl[mark+i];
-          riemannDeriv[3*nmat+ndof+3*(solidx[k]-1)+i][er] +=
-            wt * fl[mark+i];
-        }
-      }
-  }
-}
-
-void
-surfIntFV(
-  std::size_t nmat,
-  const std::vector< inciter::EOS >& mat_blk,
-  real t,
-  const std::size_t rdof,
-  const std::vector< std::size_t >& inpoel,
-  const UnsMesh::Coords& coord,
-  const inciter::FaceData& fd,
-  const Fields& geoFace,
-  const Fields& geoElem,
-  const RiemannFluxFn& flux,
-  const VelFn& vel,
-  const Fields& U,
-  const Fields& P,
-  const std::vector< int >& srcFlag,
-  Fields& R,
-  int intsharp )
-// *****************************************************************************
-//  Compute internal surface flux integrals for second order FV
-//! \param[in] nmat Number of materials in this PDE system
-//! \param[in] t Physical time
-//! \param[in] rdof Maximum number of reconstructed degrees of freedom
-//! \param[in] inpoel Element-node connectivity
-//! \param[in] coord Array of nodal coordinates
-//! \param[in] fd Face connectivity and boundary conditions object
-//! \param[in] geoFace Face geometry array
-//! \param[in] geoElem Element geometry array
-//! \param[in] flux Riemann flux function to use
-//! \param[in] vel Function to use to query prescribed velocity (if any)
-//! \param[in] U Solution vector at recent time step
-//! \param[in] P Vector of primitives at recent time step
-//! \param[in] srcFlag Whether the energy source was added
-//! \param[in,out] R Right-hand side vector computed
-//! \param[in] intsharp Interface compression tag, an optional argument, with
-//!   default 0, so that it is unused for single-material and transport.
-// *****************************************************************************
-{
-  const auto& esuf = fd.Esuf();
-
-  const auto& cx = coord[0];
-  const auto& cy = coord[1];
-  const auto& cz = coord[2];
-
-  auto ncomp = U.nprop()/rdof;<--- Variable 'ncomp' is assigned a value that is never used.
-  auto nprim = P.nprop()/rdof;<--- Variable 'nprim' is assigned a value that is never used.
-
-  // compute internal surface flux integrals
-  for (auto f=fd.Nbfac(); f<esuf.size()/2; ++f)
-  {
-    Assert( esuf[2*f] > -1 && esuf[2*f+1] > -1, "Interior element detected "
-            "as -1" );
-
-    std::size_t el = static_cast< std::size_t >(esuf[2*f]);
-    std::size_t er = static_cast< std::size_t >(esuf[2*f+1]);
-
-    // Extract the element coordinates
-    std::array< std::array< tk::real, 3>, 4 > coordel_l {{
-      {{ cx[ inpoel[4*el  ] ], cy[ inpoel[4*el  ] ], cz[ inpoel[4*el  ] ] }},
-      {{ cx[ inpoel[4*el+1] ], cy[ inpoel[4*el+1] ], cz[ inpoel[4*el+1] ] }},
-      {{ cx[ inpoel[4*el+2] ], cy[ inpoel[4*el+2] ], cz[ inpoel[4*el+2] ] }},
-      {{ cx[ inpoel[4*el+3] ], cy[ inpoel[4*el+3] ], cz[ inpoel[4*el+3] ] }} }};
-
-    std::array< std::array< tk::real, 3>, 4 > coordel_r {{
-      {{ cx[ inpoel[4*er  ] ], cy[ inpoel[4*er  ] ], cz[ inpoel[4*er  ] ] }},
-      {{ cx[ inpoel[4*er+1] ], cy[ inpoel[4*er+1] ], cz[ inpoel[4*er+1] ] }},
-      {{ cx[ inpoel[4*er+2] ], cy[ inpoel[4*er+2] ], cz[ inpoel[4*er+2] ] }},
-      {{ cx[ inpoel[4*er+3] ], cy[ inpoel[4*er+3] ], cz[ inpoel[4*er+3] ] }} }};
-
-    // Compute the determinant of Jacobian matrix
-    auto detT_l =
-      Jacobian( coordel_l[0], coordel_l[1], coordel_l[2], coordel_l[3] );
-    auto detT_r =
-      Jacobian( coordel_r[0], coordel_r[1], coordel_r[2], coordel_r[3] );
-
-    // face normal
-    std::array< real, 3 > fn{{geoFace(f,1), geoFace(f,2), geoFace(f,3)}};
-
-    // face centroid
-    std::array< real, 3 > gp{{geoFace(f,4), geoFace(f,5), geoFace(f,6)}};
-
-    // In order to determine the high-order solution from the left and right
-    // elements at the surface quadrature points, the basis functions from
-    // the left and right elements are needed. For this, a transformation to
-    // the reference coordinates is necessary, since the basis functions are
-    // defined on the reference tetrahedron only.
-    // The transformation relations are shown below:
-    //  xi   = Jacobian( coordel[0], gp, coordel[2], coordel[3] ) / detT
-    //  eta  = Jacobian( coordel[0], coordel[2], gp, coordel[3] ) / detT
-    //  zeta = Jacobian( coordel[0], coordel[2], coordel[3], gp ) / detT
-
-    std::array< tk::real, 3> ref_gp_l{
-      Jacobian( coordel_l[0], gp, coordel_l[2], coordel_l[3] ) / detT_l,
-      Jacobian( coordel_l[0], coordel_l[1], gp, coordel_l[3] ) / detT_l,
-      Jacobian( coordel_l[0], coordel_l[1], coordel_l[2], gp ) / detT_l };
-    std::array< tk::real, 3> ref_gp_r{
-      Jacobian( coordel_r[0], gp, coordel_r[2], coordel_r[3] ) / detT_r,
-      Jacobian( coordel_r[0], coordel_r[1], gp, coordel_r[3] ) / detT_r,
-      Jacobian( coordel_r[0], coordel_r[1], coordel_r[2], gp ) / detT_r };
+void
+SuperbeeMultiMat_P1(
+  const std::vector< int >& esuel,
+  const std::vector< std::size_t >& inpoel,
+  const std::vector< std::size_t >& ndofel,
+  const tk::UnsMesh::Coords& coord,
+  const std::vector< std::size_t >& solidx,
+  tk::Fields& U,
+  tk::Fields& P,
+  std::size_t nmat )
+// *****************************************************************************
+//  Superbee limiter for multi-material DGP1
+//! \param[in] esuel Elements surrounding elements
+//! \param[in] inpoel Element connectivity
+//! \param[in] ndofel Vector of local number of degrees of freedom
+//! \param[in] coord Array of nodal coordinates
+//! \param[in] solidx Solid material index indicator
+//! \param[in,out] U High-order solution vector which gets limited
+//! \param[in,out] P High-order vector of primitives which gets limited
+//! \param[in] nmat Number of materials in this PDE system
+//! \details This Superbee function should be called for multimat
+// *****************************************************************************
+{
+  const auto rdof = inciter::g_inputdeck.get< tag::rdof >();
+  const auto ndof = inciter::g_inputdeck.get< tag::ndof >();
+  const auto intsharp = inciter::g_inputdeck.get< tag::multimat,
+    tag::intsharp >();
+  std::size_t ncomp = U.nprop()/rdof;
+  std::size_t nprim = P.nprop()/rdof;
+
+  auto beta_lim = 2.0;
+
+  for (std::size_t e=0; e<esuel.size()/4; ++e)
+  {
+    // If an rDG method is set up (P0P1), then, currently we compute the P1
+    // basis functions and solutions by default. This implies that P0P1 is
+    // unsupported in the p-adaptive DG (PDG). This is a workaround until we
+    // have rdofel, which is needed to distinguish between ndofs and rdofs per
+    // element for pDG.
+    std::size_t dof_el;
+    if (rdof > ndof)
+    {
+      dof_el = rdof;
+    }
+    else
+    {
+      dof_el = ndofel[e];
+    }
+
+    if (dof_el > 1)
+    {
+      // limit conserved quantities
+      auto phic = SuperbeeLimiting(U, esuel, inpoel, coord, e, ndof, rdof,
+                    dof_el, ncomp, beta_lim);
+      // limit primitive quantities
+      auto phip = SuperbeeLimiting(P, esuel, inpoel, coord, e, ndof, rdof,
+                    dof_el, nprim, beta_lim);
+
+      std::vector< tk::real > phic_p2;
+      std::vector< std::vector< tk::real > > unk, prim;<--- Unused variable: unk<--- Unused variable: prim
+      if(ndof > 1)
+        BoundPreservingLimiting(nmat, ndof, e, inpoel, coord, U, phic,
+          phic_p2);
+
+      // limits under which compression is to be performed
+      std::vector< std::size_t > matInt(nmat, 0);
+      std::vector< tk::real > alAvg(nmat, 0.0);
+      for (std::size_t k=0; k<nmat; ++k)
+        alAvg[k] = U(e, volfracDofIdx(nmat,k,rdof,0));
+      auto intInd = interfaceIndicator(nmat, alAvg, matInt);
+      if ((intsharp > 0) && intInd)
+      {
+        for (std::size_t k=0; k<nmat; ++k)
+        {
+          if (matInt[k])
+            phic[volfracIdx(nmat,k)] = 1.0;
+        }
+      }
+      else
+      {
+        if (!g_inputdeck.get< tag::accuracy_test >())
+          consistentMultiMatLimiting_P1(nmat, rdof, e, solidx, U, P, phic,
+            phic_p2);
+      }
+
+      // apply limiter function
+      for (inciter::ncomp_t c=0; c<ncomp; ++c)
+      {
+        auto mark = c*rdof;
+        U(e, mark+1) = phic[c] * U(e, mark+1);
+        U(e, mark+2) = phic[c] * U(e, mark+2);
+        U(e, mark+3) = phic[c] * U(e, mark+3);
+      }
+      for (inciter::ncomp_t c=0; c<nprim; ++c)
+      {
+        auto mark = c*rdof;
+        P(e, mark+1) = phip[c] * P(e, mark+1);
+        P(e, mark+2) = phip[c] * P(e, mark+2);
+        P(e, mark+3) = phip[c] * P(e, mark+3);
+      }
+    }
+  }
+}
+
+void
+VertexBasedTransport_P1(
+  const std::map< std::size_t, std::vector< std::size_t > >& esup,
+  const std::vector< std::size_t >& inpoel,
+  const std::vector< std::size_t >& ndofel,
+  std::size_t nelem,
+  const tk::UnsMesh::Coords& coord,
+  tk::Fields& U )
+// *****************************************************************************
+//  Kuzmin's vertex-based limiter for transport DGP1
+//! \param[in] esup Elements surrounding points
+//! \param[in] inpoel Element connectivity
+//! \param[in] ndofel Vector of local number of degrees of freedom
+//! \param[in] nelem Number of elements
+//! \param[in] coord Array of nodal coordinates
+//! \param[in,out] U High-order solution vector which gets limited
+//! \details This vertex-based limiter function should be called for transport.
+//!   For details see: Kuzmin, D. (2010). A vertex-based hierarchical slope
+//!   limiter for p-adaptive discontinuous Galerkin methods. Journal of
+//!   computational and applied mathematics, 233(12), 3077-3085.
+// *****************************************************************************
+{
+  const auto rdof = inciter::g_inputdeck.get< tag::rdof >();
+  const auto ndof = inciter::g_inputdeck.get< tag::ndof >();
+  const auto intsharp = inciter::g_inputdeck.get< tag::transport,
+    tag::intsharp >();
+  std::size_t ncomp = U.nprop()/rdof;
+
+  for (std::size_t e=0; e<nelem; ++e)
+  {
+    // If an rDG method is set up (P0P1), then, currently we compute the P1
+    // basis functions and solutions by default. This implies that P0P1 is
+    // unsupported in the p-adaptive DG (PDG). This is a workaround until we
+    // have rdofel, which is needed to distinguish between ndofs and rdofs per
+    // element for pDG.
+    std::size_t dof_el;
+    if (rdof > ndof)
+    {
+      dof_el = rdof;
+    }
+    else
+    {
+      dof_el = ndofel[e];
+    }
+
+    if (dof_el > 1)
+    {
+      std::vector< tk::real > phi(ncomp, 1.0);
+      std::vector< std::size_t > var;
+      for (std::size_t c=0; c<ncomp; ++c) var.push_back(c);
+      // limit conserved quantities
+      VertexBasedLimiting(U, esup, inpoel, coord, e, rdof, dof_el,
+        ncomp, phi, var);
+
+      // limits under which compression is to be performed
+      std::vector< std::size_t > matInt(ncomp, 0);
+      std::vector< tk::real > alAvg(ncomp, 0.0);
+      for (std::size_t k=0; k<ncomp; ++k)
+        alAvg[k] = U(e,k*rdof);
+      auto intInd = interfaceIndicator(ncomp, alAvg, matInt);
+      if ((intsharp > 0) && intInd)
+      {
+        for (std::size_t k=0; k<ncomp; ++k)
+        {
+          if (matInt[k]) phi[k] = 1.0;
+        }
+      }
+
+      // apply limiter function
+      for (std::size_t c=0; c<ncomp; ++c)
+      {
+        auto mark = c*rdof;
+        U(e, mark+1) = phi[c] * U(e, mark+1);
+        U(e, mark+2) = phi[c] * U(e, mark+2);
+        U(e, mark+3) = phi[c] * U(e, mark+3);
+      }
+    }
+  }
+}
+
+void
+VertexBasedCompflow_P1(
+  const std::map< std::size_t, std::vector< std::size_t > >& esup,
+  const std::vector< std::size_t >& inpoel,
+  const std::vector< std::size_t >& ndofel,
+  std::size_t nelem,
+  const std::vector< inciter::EOS >& mat_blk,
+  const inciter::FaceData& fd,
+  const tk::Fields& geoFace,
+  const tk::Fields& geoElem,
+  const tk::UnsMesh::Coords& coord,
+  const tk::FluxFn& flux,
+  const std::vector< std::size_t >& solidx,
+  tk::Fields& U,
+  std::vector< std::size_t >& shockmarker )
+// *****************************************************************************
+//  Kuzmin's vertex-based limiter for single-material DGP1
+//! \param[in] esup Elements surrounding points
+//! \param[in] inpoel Element connectivity
+//! \param[in] ndofel Vector of local number of degrees of freedom
+//! \param[in] nelem Number of elements
+//! \param[in] mat_blk EOS material block
+//! \param[in] fd Face connectivity and boundary conditions object
+//! \param[in] geoFace Face geometry array
+// //! \param[in] geoElem Element geometry array
+//! \param[in] coord Array of nodal coordinates
+//! \param[in] flux Riemann flux function to use
+//! \param[in] solidx Solid material index indicator
+//! \param[in,out] U High-order solution vector which gets limited
+//! \param[in,out] shockmarker Shock detection marker array
+//! \details This vertex-based limiter function should be called for compflow.
+//!   For details see: Kuzmin, D. (2010). A vertex-based hierarchical slope
+//!   limiter for p-adaptive discontinuous Galerkin methods. Journal of
+//!   computational and applied mathematics, 233(12), 3077-3085.
+// *****************************************************************************
+{
+  const auto rdof = inciter::g_inputdeck.get< tag::rdof >();
+  const auto ndof = inciter::g_inputdeck.get< tag::ndof >();
+  std::size_t ncomp = U.nprop()/rdof;
+
+  // Null field for MarkShockCells argument
+  tk::Fields P;
+
+  if (inciter::g_inputdeck.get< tag::shock_detector_coeff >()
+    > 1e-6)
+    MarkShockCells(nelem, 1, ndof, rdof, mat_blk, ndofel,
+      inpoel, coord, fd, geoFace, geoElem, flux, solidx, U, P, shockmarker);
+
+  for (std::size_t e=0; e<nelem; ++e)
+  {
+    // If an rDG method is set up (P0P1), then, currently we compute the P1
+    // basis functions and solutions by default. This implies that P0P1 is
+    // unsupported in the p-adaptive DG (PDG). This is a workaround until we
+    // have rdofel, which is needed to distinguish between ndofs and rdofs per
+    // element for pDG.
+    std::size_t dof_el;
+    if (rdof > ndof)
+    {
+      dof_el = rdof;
+    }
+    else
+    {
+      dof_el = ndofel[e];
+    }
+
+    if (dof_el > 1 && shockmarker[e])
+    {
+      std::vector< tk::real > phi(ncomp, 1.0);
+      std::vector< std::size_t > var;
+      for (std::size_t c=0; c<ncomp; ++c) var.push_back(c);
+      // limit conserved quantities
+      VertexBasedLimiting(U, esup, inpoel, coord, e, rdof, dof_el,
+        ncomp, phi, var);
+
+      // apply limiter function
+      for (std::size_t c=0; c<ncomp; ++c)
+      {
+        auto mark = c*rdof;
+        U(e, mark+1) = phi[c] * U(e, mark+1);
+        U(e, mark+2) = phi[c] * U(e, mark+2);
+        U(e, mark+3) = phi[c] * U(e, mark+3);
+      }
+    }
+  }
+}
+
+void
+VertexBasedCompflow_P2(
+  const std::map< std::size_t, std::vector< std::size_t > >& esup,
+  const std::vector< std::size_t >& inpoel,
+  const std::vector< std::size_t >& ndofel,
+  std::size_t nelem,
+  const std::vector< inciter::EOS >& mat_blk,
+  const inciter::FaceData& fd,
+  const tk::Fields& geoFace,
+  const tk::Fields& geoElem,
+  const tk::UnsMesh::Coords& coord,
+  [[maybe_unused]] const std::vector< std::size_t >& gid,
+  [[maybe_unused]] const std::unordered_map< std::size_t, std::size_t >& bid,
+  [[maybe_unused]] const std::vector< std::vector<tk::real> >& uNodalExtrm,
+  [[maybe_unused]] const std::vector< std::vector<tk::real> >& mtInv,
+  const tk::FluxFn& flux,
+  const std::vector< std::size_t >& solidx,
+  tk::Fields& U,
+  std::vector< std::size_t >& shockmarker )
+// *****************************************************************************
+//  Kuzmin's vertex-based limiter on reference element for single-material DGP2
+//! \param[in] esup Elements surrounding points
+//! \param[in] inpoel Element connectivity
+//! \param[in] ndofel Vector of local number of degrees of freedom
+//! \param[in] nelem Number of elements
+//! \param[in] mat_blk EOS material block
+//! \param[in] fd Face connectivity and boundary conditions object
+//! \param[in] geoFace Face geometry array
+// //! \param[in] geoElem Element geometry array
+//! \param[in] coord Array of nodal coordinates
+//! \param[in] gid Local->global node id map
+//! \param[in] bid Local chare-boundary node ids (value) associated to
+//!   global node ids (key)
+//! \param[in] uNodalExtrm Chare-boundary nodal extrema for conservative
+//!   variables
+//! \param[in] mtInv Inverse of Taylor mass matrix
+//! \param[in] flux Riemann flux function to use
+//! \param[in] solidx Solid material index indicator
+//! \param[in,out] U High-order solution vector which gets limited
+//! \param[in,out] shockmarker Shock detection marker array
+//! \details This vertex-based limiter function should be called for compflow.
+//!   For details see: Kuzmin, D. (2010). A vertex-based hierarchical slope
+//!   limiter for p-adaptive discontinuous Galerkin methods. Journal of
+//!   computational and applied mathematics, 233(12), 3077-3085.
+// *****************************************************************************
+{
+  const auto rdof = inciter::g_inputdeck.get< tag::rdof >();
+  const auto ndof = inciter::g_inputdeck.get< tag::ndof >();
+  std::size_t ncomp = U.nprop()/rdof;
+
+  // Null field for MarkShockCells argument
+  tk::Fields P;
 
-    //Compute the basis functions
-    auto B_l = eval_basis( rdof, ref_gp_l[0], ref_gp_l[1], ref_gp_l[2] );
-    auto B_r = eval_basis( rdof, ref_gp_r[0], ref_gp_r[1], ref_gp_r[2] );
-
-    std::array< std::vector< real >, 2 > state;
-
-    state[0] = evalFVSol(mat_blk, intsharp, ncomp, nprim, rdof,
-      nmat, el, inpoel, coord, geoElem, ref_gp_l, B_l, U, P, srcFlag[el]);
-    state[1] = evalFVSol(mat_blk, intsharp, ncomp, nprim, rdof,
-      nmat, er, inpoel, coord, geoElem, ref_gp_r, B_r, U, P, srcFlag[er]);
-
-    //safeReco(rdof, nmat, el, er, U, state);
-
-    Assert( state[0].size() == ncomp+nprim, "Incorrect size for "
-            "appended boundary state vector" );
-    Assert( state[1].size() == ncomp+nprim, "Incorrect size for "
-            "appended boundary state vector" );
-
-    // evaluate prescribed velocity (if any)
-    auto v = vel( ncomp, gp[0], gp[1], gp[2], t );
-
-    // compute flux
-    auto fl = flux( mat_blk, fn, state, v );
-
-    // compute non-conservative terms
-    std::vector< tk::real > var_riemann(nmat+1, 0.0);
-    for (std::size_t k=0; k<nmat+1; ++k) var_riemann[k] = fl[ncomp+k];
-
-    auto ncf_l = nonConservativeIntFV(nmat, rdof, el, fn, U, P, var_riemann);
-    auto ncf_r = nonConservativeIntFV(nmat, rdof, er, fn, U, P, var_riemann);
-
-    // Add the surface integration term to the rhs
-    for (ncomp_t c=0; c<ncomp; ++c)
-    {
-      R(el, c) -= geoFace(f,0) * (fl[c] - ncf_l[c]);
-      R(er, c) += geoFace(f,0) * (fl[c] - ncf_r[c]);
-    }
-  }
-}
-
-} // tk::
+  if (inciter::g_inputdeck.get< tag::shock_detector_coeff >()
+    > 1e-6)
+    MarkShockCells(nelem, 1, ndof, rdof, mat_blk, ndofel,
+      inpoel, coord, fd, geoFace, geoElem, flux, solidx, U, P, shockmarker);
+
+  for (std::size_t e=0; e<nelem; ++e)
+  {
+    // If an rDG method is set up (P0P1), then, currently we compute the P1
+    // basis functions and solutions by default. This implies that P0P1 is
+    // unsupported in the p-adaptive DG (PDG). This is a workaround until we
+    // have rdofel, which is needed to distinguish between ndofs and rdofs per
+    // element for pDG.
+    std::size_t dof_el;
+    if (rdof > ndof)
+    {
+      dof_el = rdof;
+    }
+    else
+    {
+      dof_el = ndofel[e];
+    }
+
+    if (dof_el > 1 && shockmarker[e])
+    {
+      // The vector of limiting coefficients for P1 and P2 coefficients
+      std::vector< tk::real > phic_p1(ncomp, 1.0);
+
+      // Removing 3rd order DOFs if discontinuity is detected, and applying
+      // limiting to the 2nd order/P1 solution
+      for (std::size_t c=0; c<ncomp; ++c) {
+        for(std::size_t idof = 4; idof < rdof; idof++) {
+          auto mark = c * rdof + idof;
+          U(e, mark) = 0.0;
+        }
+      }
+
+      // Obtain limiting coefficient for P1 coefficients
+      std::vector< std::size_t > var;
+      for (std::size_t c=0; c<ncomp; ++c) var.push_back(c);
+      VertexBasedLimiting(U, esup, inpoel, coord, e, rdof, dof_el,
+        ncomp, phic_p1, var);
+
+      // apply limiter function to the solution with Taylor basis
+      for (std::size_t c=0; c<ncomp; ++c) {
+        auto mark = c * rdof;
+        for(std::size_t idof=1; idof<4; idof++)
+          U(e, mark+idof) = phic_p1[c] * U(e, mark+idof);
+      }
+    }
+  }
+}
+
+void
+VertexBasedMultiMat_P1(
+  const std::map< std::size_t, std::vector< std::size_t > >& esup,
+  const std::vector< std::size_t >& inpoel,
+  const std::vector< std::size_t >& ndofel,
+  std::size_t nelem,
+  const std::vector< inciter::EOS >& mat_blk,
+  const inciter::FaceData& fd,
+  const tk::Fields& geoFace,
+  const tk::Fields& geoElem,
+  const tk::UnsMesh::Coords& coord,
+  const tk::FluxFn& flux,
+  const std::vector< std::size_t >& solidx,
+  tk::Fields& U,
+  tk::Fields& P,
+  std::size_t nmat,
+  std::vector< std::size_t >& shockmarker )
+// *****************************************************************************
+//  Kuzmin's vertex-based limiter for multi-material DGP1
+//! \param[in] esup Elements surrounding points
+//! \param[in] inpoel Element connectivity
+//! \param[in] ndofel Vector of local number of degrees of freedom
+//! \param[in] nelem Number of elements
+//! \param[in] mat_blk EOS material block
+//! \param[in] fd Face connectivity and boundary conditions object
+//! \param[in] geoFace Face geometry array
+// //! \param[in] geoElem Element geometry array
+//! \param[in] coord Array of nodal coordinates
+//! \param[in] flux Riemann flux function to use
+//! \param[in] solidx Solid material index indicator
+//! \param[in,out] U High-order solution vector which gets limited
+//! \param[in,out] P High-order vector of primitives which gets limited
+//! \param[in] nmat Number of materials in this PDE system
+//! \param[in,out] shockmarker Shock detection marker array
+//! \details This vertex-based limiter function should be called for multimat.
+//!   For details see: Kuzmin, D. (2010). A vertex-based hierarchical slope
+//!   limiter for p-adaptive discontinuous Galerkin methods. Journal of
+//!   computational and applied mathematics, 233(12), 3077-3085.
+// *****************************************************************************
+{
+  const auto rdof = inciter::g_inputdeck.get< tag::rdof >();
+  const auto ndof = inciter::g_inputdeck.get< tag::ndof >();
+  const auto intsharp = inciter::g_inputdeck.get< tag::multimat,
+    tag::intsharp >();
+  std::size_t ncomp = U.nprop()/rdof;
+  std::size_t nprim = P.nprop()/rdof;
+
+  // Evaluate the interface condition and mark the shock cells
+  if (inciter::g_inputdeck.get< tag::shock_detector_coeff >()
+    > 1e-6 && ndof > 1)
+    MarkShockCells(nelem, nmat, ndof, rdof, mat_blk, ndofel,
+      inpoel, coord, fd, geoFace, geoElem, flux, solidx, U, P, shockmarker);
+
+  for (std::size_t e=0; e<nelem; ++e)
+  {
+    // If an rDG method is set up (P0P1), then, currently we compute the P1
+    // basis functions and solutions by default. This implies that P0P1 is
+    // unsupported in the p-adaptive DG (PDG). This is a workaround until we
+    // have rdofel, which is needed to distinguish between ndofs and rdofs per
+    // element for pDG.
+    std::size_t dof_el;
+    if (rdof > ndof)
+    {
+      dof_el = rdof;
+    }
+    else
+    {
+      dof_el = ndofel[e];
+    }
+
+    if (dof_el > 1)
+    {
+      std::vector< tk::real > phic(ncomp, 1.0);
+      std::vector< tk::real > phip(nprim, 1.0);
+      if(shockmarker[e]) {
+        // When shockmarker is 1, there is discontinuity within the element.
+        // Hence, the vertex-based limiter will be applied.
+
+        // limit conserved quantities
+        std::vector< std::size_t > varc;
+        for (std::size_t c=0; c<ncomp; ++c) varc.push_back(c);
+        VertexBasedLimiting(U, esup, inpoel, coord, e, rdof, dof_el,
+          ncomp, phic, varc);
+        // limit primitive quantities
+        std::vector< std::size_t > varp;
+        for (std::size_t c=0; c<nprim; ++c) varp.push_back(c);
+        VertexBasedLimiting(P, esup, inpoel, coord, e, rdof, dof_el,
+          nprim, phip, varp);
+      } else {
+        // When shockmarker is 0, the volume fraction, density and energy
+        // of minor material will still be limited to ensure a stable solution.
+        std::vector< std::size_t > vars;
+        for (std::size_t k=0; k<nmat; ++k) vars.push_back(volfracIdx(nmat,k));
+        VertexBasedLimiting(U, esup, inpoel, coord, e, rdof, dof_el,
+          ncomp, phic, vars);
+
+        for(std::size_t k=0; k<nmat; ++k) {
+          if(U(e, volfracDofIdx(nmat,k,rdof,0)) < 1e-4) {
+            // limit the density and energy of minor materials
+            vars.clear();
+            vars.push_back(densityIdx(nmat, k));
+            vars.push_back(energyIdx(nmat, k));
+            if (solidx[k] > 0) {
+              for (std::size_t i=0; i<3; ++i)
+                for (std::size_t j=0; j<3; ++j)
+                  vars.push_back(deformIdx(nmat, solidx[k], i, j));
+            }
+            VertexBasedLimiting(U, esup, inpoel, coord, e, rdof, dof_el,
+              ncomp, phic, vars);
+
+            // limit the pressure of minor materials
+            VertexBasedLimiting(P, esup, inpoel, coord, e, rdof, dof_el,
+              nprim, phip, std::vector< std::size_t >{pressureIdx(nmat, k)});
+          }
+        }
+      }
+
+      std::vector< tk::real > phic_p2, phip_p2;
+
+      PositivityLimitingMultiMat(nmat, mat_blk, rdof, dof_el, e, inpoel,
+        coord, U, P, phic, phic_p2, phip, phip_p2);
+
+      // limits under which compression is to be performed
+      std::vector< std::size_t > matInt(nmat, 0);
+      std::vector< tk::real > alAvg(nmat, 0.0);
+      for (std::size_t k=0; k<nmat; ++k)
+        alAvg[k] = U(e, volfracDofIdx(nmat,k,rdof,0));
+      auto intInd = interfaceIndicator(nmat, alAvg, matInt);
+      if ((intsharp > 0) && intInd) {
+        for (std::size_t k=0; k<nmat; ++k) {
+          if (matInt[k]) {
+            phic[volfracIdx(nmat,k)] = 1.0;
+          }
+        }
+      }
+      else {
+        if(nmat > 1)
+          BoundPreservingLimiting(nmat, ndof, e, inpoel, coord, U, phic,
+            phic_p2);
+
+        if (!g_inputdeck.get< tag::accuracy_test >())
+          consistentMultiMatLimiting_P1(nmat, rdof, e, solidx, U, P, phic,
+            phic_p2);
+      }
+
+      // apply limiter function
+      for (std::size_t c=0; c<ncomp; ++c)
+      {
+        auto mark = c*rdof;
+        U(e, mark+1) = phic[c] * U(e, mark+1);
+        U(e, mark+2) = phic[c] * U(e, mark+2);
+        U(e, mark+3) = phic[c] * U(e, mark+3);
+      }
+      for (std::size_t c=0; c<nprim; ++c)
+      {
+        auto mark = c*rdof;
+        P(e, mark+1) = phip[c] * P(e, mark+1);
+        P(e, mark+2) = phip[c] * P(e, mark+2);
+        P(e, mark+3) = phip[c] * P(e, mark+3);
+      }
+    }
+  }
+}
+
+void
+VertexBasedMultiMat_P2(
+  const std::map< std::size_t, std::vector< std::size_t > >& esup,
+  const std::vector< std::size_t >& inpoel,
+  const std::vector< std::size_t >& ndofel,
+  std::size_t nelem,
+  const std::vector< inciter::EOS >& mat_blk,
+  const inciter::FaceData& fd,
+  const tk::Fields& geoFace,
+  const tk::Fields& geoElem,
+  const tk::UnsMesh::Coords& coord,
+  [[maybe_unused]] const std::vector< std::size_t >& gid,
+  [[maybe_unused]] const std::unordered_map< std::size_t, std::size_t >& bid,
+  [[maybe_unused]] const std::vector< std::vector<tk::real> >& uNodalExtrm,
+  [[maybe_unused]] const std::vector< std::vector<tk::real> >& pNodalExtrm,
+  [[maybe_unused]] const std::vector< std::vector<tk::real> >& mtInv,
+  const tk::FluxFn& flux,
+  const std::vector< std::size_t >& solidx,
+  tk::Fields& U,
+  tk::Fields& P,
+  std::size_t nmat,
+  std::vector< std::size_t >& shockmarker )
+// *****************************************************************************
+//  Kuzmin's vertex-based limiter for multi-material DGP2
+//! \param[in] esup Elements surrounding points
+//! \param[in] inpoel Element connectivity
+//! \param[in] ndofel Vector of local number of degrees of freedom
+//! \param[in] nelem Number of elements
+//! \param[in] mat_blk EOS material block
+//! \param[in] fd Face connectivity and boundary conditions object
+//! \param[in] geoFace Face geometry array
+// //! \param[in] geoElem Element geometry array
+//! \param[in] coord Array of nodal coordinates
+//! \param[in] gid Local->global node id map
+//! \param[in] bid Local chare-boundary node ids (value) associated to
+//!   global node ids (key)
+//! \param[in] uNodalExtrm Chare-boundary nodal extrema for conservative
+//!   variables
+//! \param[in] pNodalExtrm Chare-boundary nodal extrema for primitive
+//!   variables
+//! \param[in] mtInv Inverse of Taylor mass matrix
+//! \param[in] flux Riemann flux function to use
+//! \param[in] solidx Solid material index indicator
+//! \param[in,out] U High-order solution vector which gets limited
+//! \param[in,out] P High-order vector of primitives which gets limited
+//! \param[in] nmat Number of materials in this PDE system
+//! \param[in,out] shockmarker Shock detection marker array
+//! \details This vertex-based limiter function should be called for multimat.
+//!   For details see: Kuzmin, D. (2010). A vertex-based hierarchical slope
+//!   limiter for p-adaptive discontinuous Galerkin methods. Journal of
+//!   computational and applied mathematics, 233(12), 3077-3085.
+// *****************************************************************************
+{
+  const auto rdof = inciter::g_inputdeck.get< tag::rdof >();
+  const auto ndof = inciter::g_inputdeck.get< tag::ndof >();
+  const auto intsharp = inciter::g_inputdeck.get< tag::multimat,
+    tag::intsharp >();
+  std::size_t ncomp = U.nprop()/rdof;
+  std::size_t nprim = P.nprop()/rdof;
+
+  // Evaluate the interface condition and mark the shock cells
+  if (inciter::g_inputdeck.get< tag::shock_detector_coeff >()
+    > 1e-6)
+    MarkShockCells(nelem, nmat, ndof, rdof, mat_blk, ndofel,
+      inpoel, coord, fd, geoFace, geoElem, flux, solidx, U, P, shockmarker);
+
+  for (std::size_t e=0; e<nelem; ++e)
+  {
+    // If an rDG method is set up (P0P1), then, currently we compute the P1
+    // basis functions and solutions by default. This implies that P0P1 is
+    // unsupported in the p-adaptive DG (PDG). This is a workaround until we
+    // have rdofel, which is needed to distinguish between ndofs and rdofs per
+    // element for pDG.
+    std::size_t dof_el;
+    if (rdof > ndof)
+    {
+      dof_el = rdof;
+    }
+    else
+    {
+      dof_el = ndofel[e];
+    }
+
+    if (dof_el > 1)
+    {
+      // The vector of limiting coefficients for P1
+      std::vector< tk::real > phic_p1(ncomp, 1.0), phic_p2(ncomp, 1.0);
+      std::vector< tk::real > phip_p1(nprim, 1.0), phip_p2(nprim, 1.0);
+
+      if(shockmarker[e]) {
+        // Removing 3rd order DOFs if discontinuity is detected, and applying
+        // limiting to the 2nd order/P1 solution
+        for (std::size_t c=0; c<ncomp; ++c) {
+          auto mark = c * rdof;
+          for(std::size_t idof = 4; idof < rdof; idof++)
+            U(e, mark+idof) = 0.0;
+        }
+        for (std::size_t c=0; c<nprim; ++c) {
+          auto mark = c * rdof;
+          for(std::size_t idof = 4; idof < rdof; idof++)
+            P(e, mark+idof) = 0.0;
+        }
+
+        // Obtain limiter coefficient for P1 conserved quantities
+        std::vector< std::size_t > varc;
+        for (std::size_t c=0; c<ncomp; ++c) varc.push_back(c);
+        VertexBasedLimiting(U, esup, inpoel, coord, e, rdof, dof_el,
+          ncomp, phic_p1, varc);
+        // Obtain limiter coefficient for P1 primitive quantities
+        std::vector< std::size_t > varp;
+        for (std::size_t c=0; c<nprim; ++c) varp.push_back(c);
+        VertexBasedLimiting(P, esup, inpoel, coord, e, rdof, dof_el,
+          nprim, phip_p1, varp);
+      } else {
+        // When shockmarker is 0, the volume fraction will still be limited to
+        // ensure a stable solution. Since the limiting strategy for third order
+        // solution will downgrade the accuracy to second order, the density,
+        // energy and pressure of minor material will not be limited.
+        std::vector< std::size_t > vars;
+        for (std::size_t k=0; k<nmat; ++k) vars.push_back(volfracIdx(nmat,k));
+        VertexBasedLimiting(U, esup, inpoel, coord, e, rdof, dof_el,
+          ncomp, phic_p1, vars);
+
+        //for(std::size_t k=0; k<nmat; ++k) {
+        //  if(U(e, volfracDofIdx(nmat,k,rdof,0)) < 1e-4) {
+        //    // limit the density of minor materials
+        //    VertexBasedLimiting(unk, U, esup, inpoel, coord, e, rdof, dof_el,
+        //      ncomp, phic_p1, std::vector< std::size_t >{densityIdx(nmat,k)});
+
+        //    // limit the pressure of minor materials
+        //    VertexBasedLimiting(prim, P, esup, inpoel, coord, e, rdof, dof_el,
+        //      nprim, phip_p1, std::vector< std::size_t >{pressureIdx(nmat,k)});
+        //  }
+        //}
+      }
+
+      PositivityLimitingMultiMat(nmat, mat_blk, ndof, dof_el, e, inpoel,
+          coord, U, P, phic_p1, phic_p2, phip_p1, phic_p2);
+
+      // limits under which compression is to be performed
+      std::vector< std::size_t > matInt(nmat, 0);
+      std::vector< tk::real > alAvg(nmat, 0.0);
+      for (std::size_t k=0; k<nmat; ++k)
+        alAvg[k] = U(e, volfracDofIdx(nmat,k,rdof,0));
+      auto intInd = interfaceIndicator(nmat, alAvg, matInt);
+      if ((intsharp > 0) && intInd) {
+        for (std::size_t k=0; k<nmat; ++k) {
+          if (matInt[k]) {
+            phic_p1[volfracIdx(nmat,k)] = 1.0;
+          }
+        }
+      }
+      else {
+        if(nmat > 1)
+          BoundPreservingLimiting(nmat, ndof, e, inpoel, coord, U,
+            phic_p1, phic_p2);
+
+        if (!g_inputdeck.get< tag::accuracy_test >())
+          consistentMultiMatLimiting_P1(nmat, rdof, e, solidx, U, P, phic_p1,
+            phic_p2);
+      }
+
+      // apply limiing coefficient
+      for (std::size_t c=0; c<ncomp; ++c)
+      {
+        auto mark = c * rdof;
+        for(std::size_t idof=1; idof<4; idof++)
+          U(e, mark+idof) = phic_p1[c] * U(e, mark+idof);
+        for(std::size_t idof=4; idof<rdof; idof++)
+          U(e, mark+idof) = phic_p2[c] * U(e, mark+idof);
+      }
+      for (std::size_t c=0; c<nprim; ++c)
+      {
+        auto mark = c * rdof;
+        for(std::size_t idof=1; idof<4; idof++)
+          P(e, mark+idof) = phip_p1[c] * P(e, mark+idof);
+        for(std::size_t idof=4; idof<rdof; idof++)
+          P(e, mark+idof) = phip_p2[c] * P(e, mark+idof);
+      }
+    }
+  }
+}
+
+void
+VertexBasedMultiMat_FV(
+  const std::map< std::size_t, std::vector< std::size_t > >& esup,
+  const std::vector< std::size_t >& inpoel,
+  std::size_t nelem,
+  const tk::UnsMesh::Coords& coord,
+  const std::vector< int >& srcFlag,
+  const std::vector< std::size_t >& solidx,
+  tk::Fields& U,
+  tk::Fields& P,
+  std::size_t nmat )
+// *****************************************************************************
+//  Kuzmin's vertex-based limiter for multi-material FV
+//! \param[in] esup Elements surrounding points
+//! \param[in] inpoel Element connectivity
+//! \param[in] nelem Number of elements
+//! \param[in] coord Array of nodal coordinates
+//! \param[in] srcFlag Whether the energy source was added
+//! \param[in] solidx Solid material index indicator
+//! \param[in,out] U High-order solution vector which gets limited
+//! \param[in,out] P High-order vector of primitives which gets limited
+//! \param[in] nmat Number of materials in this PDE system
+//! \details This vertex-based limiter function should be called for multimat.
+//!   For details see: Kuzmin, D. (2010). A vertex-based hierarchical slope
+//!   limiter for p-adaptive discontinuous Galerkin methods. Journal of
+//!   computational and applied mathematics, 233(12), 3077-3085.
+// *****************************************************************************
+{
+  const auto rdof = inciter::g_inputdeck.get< tag::rdof >();
+  const auto intsharp = inciter::g_inputdeck.get< tag::multimat,
+    tag::intsharp >();
+  std::size_t ncomp = U.nprop()/rdof;
+  std::size_t nprim = P.nprop()/rdof;
+
+  for (std::size_t e=0; e<nelem; ++e)
+  {
+    std::vector< tk::real > phic(ncomp, 1.0);
+    std::vector< tk::real > phip(nprim, 1.0);
+    // limit conserved quantities
+    std::vector< std::size_t > var;
+    for (std::size_t k=0; k<nmat; ++k) {
+      var.push_back(volfracIdx(nmat,k));
+      var.push_back(densityIdx(nmat,k));
+    }
+    VertexBasedLimiting(U, esup, inpoel, coord, e, rdof, rdof, ncomp,
+      phic, var);
+    // limit primitive quantities
+    var.clear();
+    for (std::size_t c=0; c<nprim; ++c) var.push_back(c);
+    VertexBasedLimiting(P, esup, inpoel, coord, e, rdof, rdof, nprim,
+      phip, var);
+
+    // limits under which compression is to be performed
+    std::vector< std::size_t > matInt(nmat, 0);
+    std::vector< tk::real > alAvg(nmat, 0.0);
+    for (std::size_t k=0; k<nmat; ++k)
+      alAvg[k] = U(e, volfracDofIdx(nmat,k,rdof,0));
+    auto intInd = interfaceIndicator(nmat, alAvg, matInt);
+    if ((intsharp > 0) && intInd && srcFlag[e] == 0)
+    {
+      for (std::size_t k=0; k<nmat; ++k)
+      {
+        if (matInt[k])
+          phic[volfracIdx(nmat,k)] = 1.0;
+      }
+    }
+    else
+    {
+      if (!g_inputdeck.get< tag::accuracy_test >()) {
+        std::vector< tk::real > phic_p2(ncomp, 1.0);
+        consistentMultiMatLimiting_P1(nmat, rdof, e, solidx, U, P, phic,
+          phic_p2);
+      }
+    }
+
+    // apply limiter function
+    for (std::size_t c=0; c<ncomp; ++c)
+    {
+      auto mark = c*rdof;
+      U(e, mark+1) = phic[c] * U(e, mark+1);
+      U(e, mark+2) = phic[c] * U(e, mark+2);
+      U(e, mark+3) = phic[c] * U(e, mark+3);
+    }
+    for (std::size_t c=0; c<nprim; ++c)
+    {
+      auto mark = c*rdof;
+      P(e, mark+1) = phip[c] * P(e, mark+1);
+      P(e, mark+2) = phip[c] * P(e, mark+2);
+      P(e, mark+3) = phip[c] * P(e, mark+3);
+    }
+  }
+}
+
+void
+WENOLimiting( const tk::Fields& U,
+              const std::vector< int >& esuel,
+              std::size_t e,
+              inciter::ncomp_t c,
+              std::size_t rdof,
+              tk::real cweight,
+              std::array< std::vector< tk::real >, 3 >& limU )
+// *****************************************************************************
+//  WENO limiter function calculation for P1 dofs
+//! \param[in] U High-order solution vector which is to be limited
+//! \param[in] esuel Elements surrounding elements
+//! \param[in] e Id of element whose solution is to be limited
+//! \param[in] c Index of component which is to be limited
+//! \param[in] rdof Maximum number of reconstructed degrees of freedom
+//! \param[in] cweight Weight of the central stencil
+//! \param[in,out] limU Limited gradients of component c
+// *****************************************************************************
+{
+  std::array< std::array< tk::real, 3 >, 5 > gradu;
+  std::array< tk::real, 5 > wtStencil, osc, wtDof;
+
+  auto mark = c*rdof;
+
+  // reset all stencil values to zero
+  for (auto& g : gradu) g.fill(0.0);
+  osc.fill(0);
+  wtDof.fill(0);
+  wtStencil.fill(0);
+
+  // The WENO limiter uses solution data from the neighborhood in the form
+  // of stencils to enforce non-oscillatory conditions. The immediate
+  // (Von Neumann) neighborhood of a tetrahedral cell consists of the 4
+  // cells that share faces with it. These are the 4 neighborhood-stencils
+  // for the tetrahedron. The primary stencil is the tet itself. Weights are
+  // assigned to these stencils, with the primary stencil usually assigned
+  // the highest weight. The lower the primary/central weight, the more
+  // dissipative the limiting effect. This central weight is usually problem
+  // dependent. It is set higher for relatively weaker discontinuities, and
+  // lower for stronger discontinuities.
+
+  // primary stencil
+  gradu[0][0] = U(e, mark+1);
+  gradu[0][1] = U(e, mark+2);
+  gradu[0][2] = U(e, mark+3);
+  wtStencil[0] = cweight;
+
+  // stencils from the neighborhood
+  for (std::size_t is=1; is<5; ++is)
+  {
+    auto nel = esuel[ 4*e+(is-1) ];
+
+    // ignore physical domain ghosts
+    if (nel == -1)
+    {
+      gradu[is].fill(0.0);
+      wtStencil[is] = 0.0;
+      continue;
+    }
+
+    std::size_t n = static_cast< std::size_t >( nel );
+    gradu[is][0] = U(n, mark+1);
+    gradu[is][1] = U(n, mark+2);
+    gradu[is][2] = U(n, mark+3);
+    wtStencil[is] = 1.0;
+  }
+
+  // From these stencils, an oscillation indicator is calculated, which
+  // determines the effective weights for the high-order solution DOFs.
+  // These effective weights determine the contribution of each of the
+  // stencils to the high-order solution DOFs of the current cell which are
+  // being limited. If this indicator detects a large oscillation in the
+  // solution of the current cell, it reduces the effective weight for the
+  // central stencil contribution to its high-order DOFs. This results in
+  // a more dissipative and well-behaved solution in the troubled cell.
+
+  // oscillation indicators
+  for (std::size_t is=0; is<5; ++is)
+    osc[is] = std::sqrt( tk::dot(gradu[is], gradu[is]) );
+
+  tk::real wtotal = 0;
+
+  // effective weights for dofs
+  for (std::size_t is=0; is<5; ++is)
+  {
+    // A small number (1.0e-8) is needed here to avoid dividing by a zero in
+    // the case of a constant solution, where osc would be zero. The number
+    // is not set to machine zero because it is squared, and a number
+    // between 1.0e-8 to 1.0e-6 is needed.
+    wtDof[is] = wtStencil[is] * pow( (1.0e-8 + osc[is]), -2 );
+    wtotal += wtDof[is];
+  }
+
+  for (std::size_t is=0; is<5; ++is)
+  {
+    wtDof[is] = wtDof[is]/wtotal;
+  }
+
+  limU[0][e] = 0.0;
+  limU[1][e] = 0.0;
+  limU[2][e] = 0.0;
+
+  // limiter function
+  for (std::size_t is=0; is<5; ++is)
+  {
+    limU[0][e] += wtDof[is]*gradu[is][0];
+    limU[1][e] += wtDof[is]*gradu[is][1];
+    limU[2][e] += wtDof[is]*gradu[is][2];
+  }
+}
+
+std::vector< tk::real >
+SuperbeeLimiting( const tk::Fields& U,
+                  const std::vector< int >& esuel,
+                  const std::vector< std::size_t >& inpoel,
+                  const tk::UnsMesh::Coords& coord,
+                  std::size_t e,
+                  std::size_t ndof,
+                  std::size_t rdof,
+                  std::size_t dof_el,
+                  inciter:: ncomp_t ncomp,
+                  tk::real beta_lim )
+// *****************************************************************************
+//  Superbee limiter function calculation for P1 dofs
+//! \param[in] U High-order solution vector which is to be limited
+//! \param[in] esuel Elements surrounding elements
+//! \param[in] inpoel Element connectivity
+//! \param[in] coord Array of nodal coordinates
+//! \param[in] e Id of element whose solution is to be limited
+//! \param[in] ndof Maximum number of degrees of freedom
+//! \param[in] rdof Maximum number of reconstructed degrees of freedom
+//! \param[in] dof_el Local number of degrees of freedom
+//! \param[in] ncomp Number of scalar components in this PDE system
+//! \param[in] beta_lim Parameter which is equal to 2 for Superbee and 1 for
+//!   minmod limiter
+//! \return phi Limiter function for solution in element e
+// *****************************************************************************
+{
+  // Superbee is a TVD limiter, which uses min-max bounds that the
+  // high-order solution should satisfy, to ensure TVD properties. For a
+  // high-order method like DG, this involves the following steps:
+  // 1. Find min-max bounds in the immediate neighborhood of cell.
+  // 2. Calculate the Superbee function for all the points where solution
+  //    needs to be reconstructed to (all quadrature points). From these,
+  //    use the minimum value of the limiter function.
+
+  std::vector< tk::real > uMin(ncomp, 0.0), uMax(ncomp, 0.0);
+
+  for (inciter::ncomp_t c=0; c<ncomp; ++c)
+  {
+    auto mark = c*rdof;
+    uMin[c] = U(e, mark);
+    uMax[c] = U(e, mark);
+  }
+
+  // ----- Step-1: find min/max in the neighborhood
+  for (std::size_t is=0; is<4; ++is)
+  {
+    auto nel = esuel[ 4*e+is ];
+
+    // ignore physical domain ghosts
+    if (nel == -1) continue;
+
+    auto n = static_cast< std::size_t >( nel );
+    for (inciter::ncomp_t c=0; c<ncomp; ++c)
+    {
+      auto mark = c*rdof;
+      uMin[c] = std::min(uMin[c], U(n, mark));
+      uMax[c] = std::max(uMax[c], U(n, mark));
+    }
+  }
+
+  // ----- Step-2: loop over all quadrature points to get limiter function
+
+  // to loop over all the quadrature points of all faces of element e,
+  // coordinates of the quadrature points are needed.
+  // Number of quadrature points for face integration
+  auto ng = tk::NGfa(ndof);
+
+  // arrays for quadrature points
+  std::array< std::vector< tk::real >, 2 > coordgp;
+  std::vector< tk::real > wgp;
+
+  coordgp[0].resize( ng );
+  coordgp[1].resize( ng );
+  wgp.resize( ng );
+
+  // get quadrature point weights and coordinates for triangle
+  tk::GaussQuadratureTri( ng, coordgp, wgp );
+
+  const auto& cx = coord[0];
+  const auto& cy = coord[1];
+  const auto& cz = coord[2];
+
+  // Extract the element coordinates
+  std::array< std::array< tk::real, 3>, 4 > coordel {{
+    {{ cx[ inpoel[4*e  ] ], cy[ inpoel[4*e  ] ], cz[ inpoel[4*e  ] ] }},
+    {{ cx[ inpoel[4*e+1] ], cy[ inpoel[4*e+1] ], cz[ inpoel[4*e+1] ] }},
+    {{ cx[ inpoel[4*e+2] ], cy[ inpoel[4*e+2] ], cz[ inpoel[4*e+2] ] }},
+    {{ cx[ inpoel[4*e+3] ], cy[ inpoel[4*e+3] ], cz[ inpoel[4*e+3] ] }} }};
+
+  // Compute the determinant of Jacobian matrix
+  auto detT =
+    tk::Jacobian( coordel[0], coordel[1], coordel[2], coordel[3] );
+
+  // initialize limiter function
+  std::vector< tk::real > phi(ncomp, 1.0);
+  for (std::size_t lf=0; lf<4; ++lf)
+  {
+    // Extract the face coordinates
+    std::array< std::size_t, 3 > inpofa_l {{ inpoel[4*e+tk::lpofa[lf][0]],
+                                             inpoel[4*e+tk::lpofa[lf][1]],
+                                             inpoel[4*e+tk::lpofa[lf][2]] }};
+
+    std::array< std::array< tk::real, 3>, 3 > coordfa {{
+      {{ cx[ inpofa_l[0] ], cy[ inpofa_l[0] ], cz[ inpofa_l[0] ] }},
+      {{ cx[ inpofa_l[1] ], cy[ inpofa_l[1] ], cz[ inpofa_l[1] ] }},
+      {{ cx[ inpofa_l[2] ], cy[ inpofa_l[2] ], cz[ inpofa_l[2] ] }} }};
+
+    // Gaussian quadrature
+    for (std::size_t igp=0; igp<ng; ++igp)
+    {
+      // Compute the coordinates of quadrature point at physical domain
+      auto gp = tk::eval_gp( igp, coordfa, coordgp );
+
+      //Compute the basis functions
+      auto B_l = tk::eval_basis( rdof,
+            tk::Jacobian( coordel[0], gp, coordel[2], coordel[3] ) / detT,
+            tk::Jacobian( coordel[0], coordel[1], gp, coordel[3] ) / detT,
+            tk::Jacobian( coordel[0], coordel[1], coordel[2], gp ) / detT );
+
+      auto state =
+        tk::eval_state(ncomp, rdof, dof_el, e, U, B_l);
+
+      Assert( state.size() == ncomp, "Size mismatch" );
+
+      // compute the limiter function
+      for (inciter::ncomp_t c=0; c<ncomp; ++c)
+      {
+        auto phi_gp = 1.0;
+        auto mark = c*rdof;
+        auto uNeg = state[c] - U(e, mark);
+        if (uNeg > 1.0e-14)
+        {
+          uNeg = std::max(uNeg, 1.0e-08);
+          phi_gp = std::min( 1.0, (uMax[c]-U(e, mark))/(2.0*uNeg) );
+        }
+        else if (uNeg < -1.0e-14)
+        {
+          uNeg = std::min(uNeg, -1.0e-08);
+          phi_gp = std::min( 1.0, (uMin[c]-U(e, mark))/(2.0*uNeg) );
+        }
+        else
+        {
+          phi_gp = 1.0;
+        }
+        phi_gp = std::max( 0.0,
+                           std::max( std::min(beta_lim*phi_gp, 1.0),
+                                     std::min(phi_gp, beta_lim) ) );
+        phi[c] = std::min( phi[c], phi_gp );
+      }
+    }
+  }
+
+  return phi;
+}
+
+void
+VertexBasedLimiting(
+  const tk::Fields& U,
+  const std::map< std::size_t, std::vector< std::size_t > >& esup,
+  const std::vector< std::size_t >& inpoel,
+  const tk::UnsMesh::Coords& coord,
+  std::size_t e,
+  std::size_t rdof,
+  std::size_t dof_el,
+  std::size_t ncomp,
+  std::vector< tk::real >& phi,
+  const std::vector< std::size_t >& VarList )
+// *****************************************************************************
+//  Kuzmin's vertex-based limiter function calculation for P1 dofs
+//! \param[in] U High-order solution vector which is to be limited
+//! \param[in] esup Elements surrounding points
+//! \param[in] inpoel Element connectivity
+//! \param[in] coord Array of nodal coordinates
+//! \param[in] e Id of element whose solution is to be limited
+//! \param[in] rdof Maximum number of reconstructed degrees of freedom
+//! \param[in] dof_el Local number of degrees of freedom
+//! \param[in] ncomp Number of scalar components in this PDE system
+//! \param[in,out] phi Limiter function for solution in element e
+//! \param[in] VarList List of variable indices to be limited
+// *****************************************************************************
+{
+  // Kuzmin's vertex-based TVD limiter uses min-max bounds that the
+  // high-order solution should satisfy, to ensure TVD properties. For a
+  // high-order method like DG, this involves the following steps:
+  // 1. Find min-max bounds in the nodal-neighborhood of cell.
+  // 2. Calculate the limiter function (Superbee) for all the vertices of cell.
+  //    From these, use the minimum value of the limiter function.
+
+  // Prepare for calculating Basis functions
+  const auto& cx = coord[0];
+  const auto& cy = coord[1];
+  const auto& cz = coord[2];
+
+  // Extract the element coordinates
+  std::array< std::array< tk::real, 3>, 4 > coordel {{
+    {{ cx[ inpoel[4*e  ] ], cy[ inpoel[4*e  ] ], cz[ inpoel[4*e  ] ] }},
+    {{ cx[ inpoel[4*e+1] ], cy[ inpoel[4*e+1] ], cz[ inpoel[4*e+1] ] }},
+    {{ cx[ inpoel[4*e+2] ], cy[ inpoel[4*e+2] ], cz[ inpoel[4*e+2] ] }},
+    {{ cx[ inpoel[4*e+3] ], cy[ inpoel[4*e+3] ], cz[ inpoel[4*e+3] ] }} }};
+
+  // Compute the determinant of Jacobian matrix
+  auto detT =
+    tk::Jacobian( coordel[0], coordel[1], coordel[2], coordel[3] );
+
+  std::vector< tk::real > uMin(VarList.size(), 0.0),
+                          uMax(VarList.size(), 0.0);
+
+  // loop over all nodes of the element e
+  for (std::size_t lp=0; lp<4; ++lp)
+  {
+    // reset min/max
+    for (std::size_t i=0; i<VarList.size(); ++i)
+    {
+      auto mark = VarList[i]*rdof;
+      uMin[i] = U(e, mark);
+      uMax[i] = U(e, mark);
+    }
+    auto p = inpoel[4*e+lp];
+    const auto& pesup = tk::cref_find(esup, p);
+
+    // ----- Step-1: find min/max in the neighborhood of node p
+    // loop over all the internal elements surrounding this node p
+    for (auto er : pesup)
+    {
+      for (std::size_t i=0; i<VarList.size(); ++i)
+      {
+        auto mark = VarList[i]*rdof;
+        uMin[i] = std::min(uMin[i], U(er, mark));
+        uMax[i] = std::max(uMax[i], U(er, mark));
+      }
+    }
+
+    // ----- Step-2: compute the limiter function at this node
+    // find high-order solution
+    std::vector< tk::real > state;
+    std::array< tk::real, 3 > gp{cx[p], cy[p], cz[p]};
+    auto B_p = tk::eval_basis( rdof,
+          tk::Jacobian( coordel[0], gp, coordel[2], coordel[3] ) / detT,
+          tk::Jacobian( coordel[0], coordel[1], gp, coordel[3] ) / detT,
+          tk::Jacobian( coordel[0], coordel[1], coordel[2], gp ) / detT );
+    state = tk::eval_state(ncomp, rdof, dof_el, e, U, B_p);
+
+    Assert( state.size() == ncomp, "Size mismatch" );
+
+    // compute the limiter function
+    for (std::size_t i=0; i<VarList.size(); ++i)
+    {
+      auto c = VarList[i];
+      auto phi_gp = 1.0;
+      auto mark = c*rdof;
+      auto uNeg = state[c] - U(e, mark);
+      auto uref = std::max(std::fabs(U(e,mark)), 1e-14);
+      if (uNeg > 1.0e-06*uref)
+      {
+        phi_gp = std::min( 1.0, (uMax[i]-U(e, mark))/uNeg );
+      }
+      else if (uNeg < -1.0e-06*uref)
+      {
+        phi_gp = std::min( 1.0, (uMin[i]-U(e, mark))/uNeg );
+      }
+      else
+      {
+        phi_gp = 1.0;
+      }
+
+    // ----- Step-3: take the minimum of the nodal-limiter functions
+      phi[c] = std::min( phi[c], phi_gp );
+    }
+  }
+}
+
+void
+VertexBasedLimiting_P2( const std::vector< std::vector< tk::real > >& unk,
+  const tk::Fields& U,
+  const std::map< std::size_t, std::vector< std::size_t > >& esup,
+  const std::vector< std::size_t >& inpoel,
+  std::size_t e,
+  std::size_t rdof,
+  [[maybe_unused]] std::size_t dof_el,
+  std::size_t ncomp,
+  const std::vector< std::size_t >& gid,
+  const std::unordered_map< std::size_t, std::size_t >& bid,
+  const std::vector< std::vector<tk::real> >& NodalExtrm,
+  const std::vector< std::size_t >& VarList,
+  std::vector< tk::real >& phi )
+// *****************************************************************************
+//  Kuzmin's vertex-based limiter function calculation for P2 dofs
+//! \param[in] U High-order solution vector which is to be limited
+//! \param[in] esup Elements surrounding points
+//! \param[in] inpoel Element connectivity
+//! \param[in] e Id of element whose solution is to be limited
+//! \param[in] rdof Maximum number of reconstructed degrees of freedom
+//! \param[in] dof_el Local number of degrees of freedom
+//! \param[in] ncomp Number of scalar components in this PDE system
+//! \param[in] gid Local->global node id map
+//! \param[in] bid Local chare-boundary node ids (value) associated to
+//!   global node ids (key)
+//! \param[in] NodalExtrm Chare-boundary nodal extrema
+//! \param[in] VarList List of variable indices that need to be limited
+//! \param[out] phi Limiter function for solution in element e
+//! \details This function limits the P2 dofs of P2 solution in a hierachical
+//!   way to P1 dof limiting. Here we treat the first order derivatives the same
+//!   way as cell average while second order derivatives represent the gradients
+//!   to be limited in the P1 limiting procedure.
+// *****************************************************************************
+{
+  const auto nelem = inpoel.size() / 4;
+
+  std::vector< std::vector< tk::real > > uMin, uMax;
+  uMin.resize( VarList.size(), std::vector<tk::real>(3, 0.0) );
+  uMax.resize( VarList.size(), std::vector<tk::real>(3, 0.0) );
+
+  // The coordinates of centroid in the reference domain
+  std::array< std::vector< tk::real >, 3 > center;
+  center[0].resize(1, 0.25);
+  center[1].resize(1, 0.25);
+  center[2].resize(1, 0.25);
+
+  std::array< std::array< tk::real, 4 >, 3 > cnodes{{
+    {{0, 1, 0, 0}},
+    {{0, 0, 1, 0}},
+    {{0, 0, 0, 1}} }};
+
+  // loop over all nodes of the element e
+  for (std::size_t lp=0; lp<4; ++lp)
+  {
+    // Find the max/min first-order derivatives for internal element
+    for (std::size_t i=0; i<VarList.size(); ++i)
+    {
+      for (std::size_t idir=1; idir < 4; ++idir)
+      {
+        uMin[i][idir-1] = unk[VarList[i]][idir];
+        uMax[i][idir-1] = unk[VarList[i]][idir];
+      }
+    }
+
+    auto p = inpoel[4*e+lp];
+    const auto& pesup = tk::cref_find(esup, p);
+
+    // Step-1: find min/max first order derivative at the centroid in the
+    // neighborhood of node p
+    for (auto er : pesup)
+    {
+      if(er < nelem)      // If this is internal element
+      {
+        // Compute the derivatives of basis function in the reference domain
+        auto dBdxi_er = tk::eval_dBdxi(rdof,
+          {{center[0][0], center[1][0], center[2][0]}});
+
+        for (std::size_t i=0; i<VarList.size(); ++i)
+        {
+          auto mark = VarList[i]*rdof;
+          for (std::size_t idir = 0; idir < 3; ++idir)
+          {
+            // The first order derivative at the centroid of element er
+            tk::real slope_er(0.0);
+            for(std::size_t idof = 1; idof < rdof; idof++)
+              slope_er += U(er, mark+idof) * dBdxi_er[idir][idof];
+
+            uMin[i][idir] = std::min(uMin[i][idir], slope_er);
+            uMax[i][idir] = std::max(uMax[i][idir], slope_er);
+
+          }
+        }
+      }
+    }
+    // If node p is the chare-boundary node, find min/max by comparing with
+    // the chare-boundary nodal extrema from vector NodalExtrm
+    auto gip = bid.find( gid[p] );
+    if(gip != end(bid))
+    {
+      auto ndof_NodalExtrm = NodalExtrm[0].size() / (ncomp * 2);
+      for (std::size_t i=0; i<VarList.size(); ++i)
+      {
+        for (std::size_t idir = 0; idir < 3; idir++)
+        {
+          auto max_mark = 2*VarList[i]*ndof_NodalExtrm + 2*idir;
+          auto min_mark = max_mark + 1;
+          const auto& ex = NodalExtrm[gip->second];
+          uMax[i][idir] = std::max(ex[max_mark], uMax[i][idir]);
+          uMin[i][idir] = std::min(ex[min_mark], uMin[i][idir]);
+        }
+      }
+    }
+
+    //Step-2: compute the limiter function at this node
+    std::array< tk::real, 3 > node{cnodes[0][lp], cnodes[1][lp], cnodes[2][lp]};
+
+    // find high-order solution
+    std::vector< std::array< tk::real, 3 > > state;
+    state.resize(VarList.size());
+
+    for (std::size_t i=0; i<VarList.size(); ++i)
+    {
+      auto dx = node[0] - center[0][0];
+      auto dy = node[1] - center[1][0];
+      auto dz = node[2] - center[2][0];
+
+      auto c = VarList[i];
+
+      state[i][0] = unk[c][1] + unk[c][4]*dx + unk[c][7]*dy + unk[c][8]*dz;
+      state[i][1] = unk[c][2] + unk[c][5]*dy + unk[c][7]*dx + unk[c][9]*dz;
+      state[i][2] = unk[c][3] + unk[c][6]*dz + unk[c][8]*dx + unk[c][9]*dy;
+    }
+
+    // compute the limiter function
+    for (std::size_t i=0; i<VarList.size(); ++i)
+    {
+      auto c = VarList[i];
+      tk::real phi_dir(1.0);
+      for (std::size_t idir = 1; idir <= 3; ++idir)
+      {
+        phi_dir = 1.0;<--- phi_dir is assigned
+        auto uNeg = state[i][idir-1] - unk[c][idir];
+        auto uref = std::max(std::fabs(unk[c][idir]), 1e-14);
+        if (uNeg > 1.0e-6*uref)
+        {
+          phi_dir =<--- phi_dir is overwritten
+            std::min( 1.0, ( uMax[i][idir-1] - unk[c][idir])/uNeg );
+        }
+        else if (uNeg < -1.0e-6*uref)
+        {
+          phi_dir =
+            std::min( 1.0, ( uMin[i][idir-1] - unk[c][idir])/uNeg );
+        }
+        else
+        {
+          phi_dir = 1.0;
+        }
+
+        phi[c] = std::min( phi[c], phi_dir );
+      }
+    }
+  }
+}
+
+void consistentMultiMatLimiting_P1(
+  std::size_t nmat,
+  std::size_t rdof,
+  std::size_t e,
+  const std::vector< std::size_t >& solidx,
+  tk::Fields& U,<--- Parameter 'U' can be declared with const
+  [[maybe_unused]] tk::Fields& P,
+  std::vector< tk::real >& phic_p1,
+  std::vector< tk::real >& phic_p2 )
+// *****************************************************************************
+//  Consistent limiter modifications for conservative variables
+//! \param[in] nmat Number of materials in this PDE system
+//! \param[in] rdof Total number of reconstructed dofs
+//! \param[in] e Element being checked for consistency
+//! \param[in] solidx Solid material index indicator
+//! \param[in] U Vector of conservative variables
+//! \param[in] P Vector of primitive variables
+//! \param[in,out] phic_p1 Vector of limiter functions for P1 dofs of the
+//!   conserved quantities
+//! \param[in,out] phip_p2 Vector of limiter functions for P2 dofs of the
+//!   conserved quantities
+// *****************************************************************************
+{
+  // find the limiter-function for volume-fractions
+  auto phi_al_p1(1.0), phi_al_p2(1.0), almax(0.0), dalmax(0.0);
+  //std::size_t nmax(0);
+  for (std::size_t k=0; k<nmat; ++k)
+  {
+    phi_al_p1 = std::min( phi_al_p1, phic_p1[volfracIdx(nmat, k)] );
+    if(rdof > 4)
+      phi_al_p2 = std::min( phi_al_p2, phic_p2[volfracIdx(nmat, k)] );
+    if (almax < U(e,volfracDofIdx(nmat, k, rdof, 0)))
+    {
+      //nmax = k;
+      almax = U(e,volfracDofIdx(nmat, k, rdof, 0));
+    }
+    tk::real dmax(0.0);
+    dmax = std::max(
+             std::max(
+               std::abs(U(e,volfracDofIdx(nmat, k, rdof, 1))),
+               std::abs(U(e,volfracDofIdx(nmat, k, rdof, 2))) ),
+               std::abs(U(e,volfracDofIdx(nmat, k, rdof, 3))) );
+    dalmax = std::max( dalmax, dmax );
+  }
+
+  auto al_band = 1e-4;
+
+  //phi_al = phic[nmax];
+
+  // determine if cell is a material-interface cell based on ad-hoc tolerances.
+  // if interface-cell, then modify high-order dofs of conserved unknowns
+  // consistently and use same limiter for all equations.
+  // Slopes of solution variables \alpha_k \rho_k and \alpha_k \rho_k E_k need
+  // to be modified in interface cells, such that slopes in the \rho_k and
+  // \rho_k E_k part are ignored and only slopes in \alpha_k are considered.
+  // Ideally, we would like to not do this, but this is a necessity to avoid
+  // limiter-limiter interactions in multiphase CFD (see "K.-M. Shyue, F. Xiao,
+  // An Eulerian interface sharpening algorithm for compressible two-phase flow:
+  // the algebraic THINC approach, Journal of Computational Physics 268, 2014,
+  // 326–354. doi:10.1016/j.jcp.2014.03.010." and "A. Chiapolino, R. Saurel,
+  // B. Nkonga, Sharpening diffuse interfaces with compressible fluids on
+  // unstructured meshes, Journal of Computational Physics 340 (2017) 389–417.
+  // doi:10.1016/j.jcp.2017.03.042."). This approximation should be applied in
+  // as narrow a band of interface-cells as possible. The following if-test
+  // defines this band of interface-cells. This tests checks the value of the
+  // maximum volume-fraction in the cell (almax) and the maximum change in
+  // volume-fraction in the cell (dalmax, calculated from second-order DOFs),
+  // to determine the band of interface-cells where the aforementioned fix needs
+  // to be applied. This if-test says that, the fix is applied when the change
+  // in volume-fraction across a cell is greater than 0.1, *and* the
+  // volume-fraction is between 0.1 and 0.9.
+  if ( //dalmax > al_band &&
+       (almax > al_band && almax < (1.0-al_band)) )
+  {
+    // 1. consistent high-order dofs
+    for (std::size_t k=0; k<nmat; ++k)
+    {
+      auto alk =
+        std::max( 1.0e-14, U(e,volfracDofIdx(nmat, k, rdof, 0)) );
+      auto rhok = U(e,densityDofIdx(nmat, k, rdof, 0)) / alk;
+      auto rhoE = U(e,energyDofIdx(nmat, k, rdof, 0)) / alk;
+      for (std::size_t idof=1; idof<rdof; ++idof)
+      {
+          U(e,densityDofIdx(nmat, k, rdof, idof)) = rhok *
+            U(e,volfracDofIdx(nmat, k, rdof, idof));
+          U(e,energyDofIdx(nmat, k, rdof, idof)) = rhoE *
+            U(e,volfracDofIdx(nmat, k, rdof, idof));
+      }
+      if (solidx[k] > 0)
+        for (std::size_t i=0; i<3; ++i)
+          for (std::size_t j=0; j<3; ++j)
+          {
+            for (std::size_t idof=1; idof<rdof; ++idof)
+              U(e,deformDofIdx(nmat,solidx[k],i,j,rdof,idof)) = 0.0;
+          }
+    }
+
+    // 2. same limiter for all volume-fractions and densities
+    for (std::size_t k=0; k<nmat; ++k)
+    {
+      phic_p1[volfracIdx(nmat, k)] = phi_al_p1;
+      phic_p1[densityIdx(nmat, k)] = phi_al_p1;
+      phic_p1[energyIdx(nmat, k)] = phi_al_p1;
+      if (solidx[k] > 0)
+        for (std::size_t i=0; i<3; ++i)
+          for (std::size_t j=0; j<3; ++j)
+            phic_p1[deformIdx(nmat,solidx[k],i,j)] = phi_al_p1;
+    }
+    if(rdof > 4)
+    {
+      for (std::size_t k=0; k<nmat; ++k)
+      {
+        phic_p2[volfracIdx(nmat, k)] = phi_al_p2;
+        phic_p2[densityIdx(nmat, k)] = phi_al_p2;
+        phic_p2[energyIdx(nmat, k)] = phi_al_p2;
+        if (solidx[k] > 0)
+          for (std::size_t i=0; i<3; ++i)
+            for (std::size_t j=0; j<3; ++j)
+              phic_p2[deformIdx(nmat,solidx[k],i,j)] = phi_al_p2;
+      }
+    }
+  }
+  else
+  {
+    // same limiter for all volume-fractions
+    for (std::size_t k=0; k<nmat; ++k)
+      phic_p1[volfracIdx(nmat, k)] = phi_al_p1;
+    if(rdof > 4)
+      for (std::size_t k=0; k<nmat; ++k)
+        phic_p2[volfracIdx(nmat, k)] = phi_al_p2;
+  }
+}
+
+void BoundPreservingLimiting( std::size_t nmat,
+                              std::size_t ndof,
+                              std::size_t e,
+                              const std::vector< std::size_t >& inpoel,
+                              const tk::UnsMesh::Coords& coord,
+                              const tk::Fields& U,
+                              std::vector< tk::real >& phic_p1,
+                              std::vector< tk::real >& phic_p2 )
+// *****************************************************************************
+//  Bound preserving limiter for volume fractions when MulMat scheme is selected
+//! \param[in] nmat Number of materials in this PDE system
+//! \param[in] ndof Total number of reconstructed dofs
+//! \param[in] e Element being checked for consistency
+//! \param[in] inpoel Element connectivity
+//! \param[in] coord Array of nodal coordinates
+//! \param[in,out] U Second-order solution vector which gets modified near
+//!   material interfaces for consistency
+//! \param[in] unk Vector of conservative variables based on Taylor basis
+//! \param[in,out] phic_p1 Vector of limiter functions for P1 dofs of the
+//!   conserved quantities
+//! \param[in,out] phic_p2 Vector of limiter functions for P2 dofs of the
+//!   conserved quantities
+//! \details This bound-preserving limiter is specifically meant to enforce
+//!   bounds [0,1], but it does not suppress oscillations like the other 'TVD'
+//!   limiters. TVD limiters on the other hand, do not preserve such bounds. A
+//!   combination of oscillation-suppressing and bound-preserving limiters can
+//!   obtain a non-oscillatory and bounded solution.
+// *****************************************************************************
+{
+  const auto& cx = coord[0];
+  const auto& cy = coord[1];
+  const auto& cz = coord[2];
+
+  // Extract the element coordinates
+  std::array< std::array< tk::real, 3>, 4 > coordel {{
+    {{ cx[ inpoel[4*e  ] ], cy[ inpoel[4*e  ] ], cz[ inpoel[4*e  ] ] }},
+    {{ cx[ inpoel[4*e+1] ], cy[ inpoel[4*e+1] ], cz[ inpoel[4*e+1] ] }},
+    {{ cx[ inpoel[4*e+2] ], cy[ inpoel[4*e+2] ], cz[ inpoel[4*e+2] ] }},
+    {{ cx[ inpoel[4*e+3] ], cy[ inpoel[4*e+3] ], cz[ inpoel[4*e+3] ] }} }};
+
+  // Compute the determinant of Jacobian matrix
+  auto detT =
+    tk::Jacobian( coordel[0], coordel[1], coordel[2], coordel[3] );
+
+  std::vector< tk::real > phi_bound(nmat, 1.0);
+
+  // Compute the upper and lower bound for volume fraction
+  const tk::real min = 1e-14;
+  const tk::real max = 1.0 - min;
+
+  // loop over all faces of the element e
+  for (std::size_t lf=0; lf<4; ++lf)
+  {
+    // Extract the face coordinates
+    std::array< std::size_t, 3 > inpofa_l {{ inpoel[4*e+tk::lpofa[lf][0]],
+                                             inpoel[4*e+tk::lpofa[lf][1]],
+                                             inpoel[4*e+tk::lpofa[lf][2]] }};
+
+    std::array< std::array< tk::real, 3>, 3 > coordfa {{
+      {{ cx[ inpofa_l[0] ], cy[ inpofa_l[0] ], cz[ inpofa_l[0] ] }},
+      {{ cx[ inpofa_l[1] ], cy[ inpofa_l[1] ], cz[ inpofa_l[1] ] }},
+      {{ cx[ inpofa_l[2] ], cy[ inpofa_l[2] ], cz[ inpofa_l[2] ] }} }};
+
+    auto ng = tk::NGfa(ndof);
+
+    // arrays for quadrature points
+    std::array< std::vector< tk::real >, 2 > coordgp;
+    std::vector< tk::real > wgp;
+
+    coordgp[0].resize( ng );
+    coordgp[1].resize( ng );
+    wgp.resize( ng );
+
+    // get quadrature point weights and coordinates for triangle
+    tk::GaussQuadratureTri( ng, coordgp, wgp );
+
+    // Gaussian quadrature
+    for (std::size_t igp=0; igp<ng; ++igp)
+    {
+      // Compute the coordinates of quadrature point at physical domain
+      auto gp = tk::eval_gp( igp, coordfa, coordgp );
+
+      //Compute the basis functions
+      auto B = tk::eval_basis( ndof,
+            tk::Jacobian( coordel[0], gp, coordel[2], coordel[3] ) / detT,
+            tk::Jacobian( coordel[0], coordel[1], gp, coordel[3] ) / detT,
+            tk::Jacobian( coordel[0], coordel[1], coordel[2], gp ) / detT );
+
+      auto state = eval_state( U.nprop()/ndof, ndof, ndof, e, U, B );
+
+      for(std::size_t imat = 0; imat < nmat; imat++)
+      {
+        auto phi = BoundPreservingLimitingFunction( min, max,
+          state[volfracIdx(nmat, imat)],
+          U(e,volfracDofIdx(nmat, imat, ndof, 0)) );
+        phi_bound[imat] = std::min( phi_bound[imat], phi );
+      }
+    }
+  }
+
+  // If DG(P2), the bound-preserving limiter should also be applied to the gauss
+  // point within the element
+  if(ndof > 4)
+  {
+    auto ng = tk::NGvol(ndof);
+
+    // arrays for quadrature points
+    std::array< std::vector< tk::real >, 3 > coordgp;
+    std::vector< tk::real > wgp;
+
+    coordgp[0].resize( ng );
+    coordgp[1].resize( ng );
+    coordgp[2].resize( ng );
+    wgp.resize( ng );
+
+    tk::GaussQuadratureTet( ng, coordgp, wgp );
+
+    for (std::size_t igp=0; igp<ng; ++igp)
+    {
+      // Compute the basis function
+      auto B = tk::eval_basis( ndof, coordgp[0][igp], coordgp[1][igp],
+        coordgp[2][igp] );
+
+      auto state = tk::eval_state(U.nprop()/ndof, ndof, ndof, e, U, B);
+
+      for(std::size_t imat = 0; imat < nmat; imat++)
+      {
+        auto phi = BoundPreservingLimitingFunction(min, max,
+          state[volfracIdx(nmat, imat)],
+          U(e,volfracDofIdx(nmat, imat, ndof, 0)) );
+        phi_bound[imat] = std::min( phi_bound[imat], phi );
+      }
+    }
+  }
+
+  for(std::size_t k=0; k<nmat; k++)
+    phic_p1[volfracIdx(nmat, k)] = std::min(phi_bound[k],
+      phic_p1[volfracIdx(nmat, k)]);
+
+  if(ndof > 4)
+    for(std::size_t k=0; k<nmat; k++)
+      phic_p2[volfracIdx(nmat, k)] = std::min(phi_bound[k],
+        phic_p2[volfracIdx(nmat, k)]);
+}
+
+tk::real
+BoundPreservingLimitingFunction( const tk::real min,
+                                 const tk::real max,
+                                 const tk::real al_gp,
+                                 const tk::real al_avg )
+// *****************************************************************************
+//  Bound-preserving limiter function for the volume fractions
+//! \param[in] min Minimum bound for volume fraction
+//! \param[in] max Maximum bound for volume fraction
+//! \param[in] al_gp Volume fraction at the quadrature point
+//! \param[in] al_avg Cell-average volume fraction
+//! \return The limiting coefficient from the bound-preserving limiter function
+// *****************************************************************************
+{
+  tk::real phi(1.0), al_diff(0.0);
+  al_diff = al_gp - al_avg;
+  if(al_gp > max && fabs(al_diff) > 1e-15)
+    phi = std::fabs( (max - al_avg) / al_diff );
+  else if(al_gp < min && fabs(al_diff) > 1e-15)
+    phi = std::fabs( (min - al_avg) / al_diff );
+  return phi;
+}
+
+void PositivityLimitingMultiMat( std::size_t nmat,
+                                 const std::vector< inciter::EOS >& mat_blk,
+                                 std::size_t rdof,
+                                 std::size_t ndof_el,
+                                 std::size_t e,
+                                 const std::vector< std::size_t >& inpoel,
+                                 const tk::UnsMesh::Coords& coord,
+                                 const tk::Fields& U,
+                                 const tk::Fields& P,
+                                 std::vector< tk::real >& phic_p1,
+                                 std::vector< tk::real >& phic_p2,
+                                 std::vector< tk::real >& phip_p1,
+                                 std::vector< tk::real >& phip_p2 )
+// *****************************************************************************
+//  Positivity preserving limiter for multi-material solver
+//! \param[in] nmat Number of materials in this PDE system
+//! \param[in] mat_blk EOS material block
+//! \param[in] rdof Total number of reconstructed dofs
+//! \param[in] ndof_el Number of dofs for element e
+//! \param[in] e Element being checked for consistency
+//! \param[in] inpoel Element connectivity
+//! \param[in] coord Array of nodal coordinates
+//! \param[in] U Vector of conservative variables
+//! \param[in] P Vector of primitive variables
+//! \param[in,out] phic_p1 Vector of limiter functions for P1 dofs of the
+//!   conserved quantities
+//! \param[in,out] phic_p2 Vector of limiter functions for P2 dofs of the
+//!   conserved quantities
+//! \param[in,out] phip_p1 Vector of limiter functions for P1 dofs of the
+//!   primitive quantities
+//! \param[in,out] phip_p2 Vector of limiter functions for P2 dofs of the
+//!   primitive quantities
+// *****************************************************************************
+{
+  const auto ncomp = U.nprop() / rdof;
+  const auto nprim = P.nprop() / rdof;
+
+  const auto& cx = coord[0];
+  const auto& cy = coord[1];
+  const auto& cz = coord[2];
+
+  // Extract the element coordinates
+  std::array< std::array< tk::real, 3>, 4 > coordel {{
+    {{ cx[ inpoel[4*e  ] ], cy[ inpoel[4*e  ] ], cz[ inpoel[4*e  ] ] }},
+    {{ cx[ inpoel[4*e+1] ], cy[ inpoel[4*e+1] ], cz[ inpoel[4*e+1] ] }},
+    {{ cx[ inpoel[4*e+2] ], cy[ inpoel[4*e+2] ], cz[ inpoel[4*e+2] ] }},
+    {{ cx[ inpoel[4*e+3] ], cy[ inpoel[4*e+3] ], cz[ inpoel[4*e+3] ] }} }};
+
+  // Compute the determinant of Jacobian matrix
+  auto detT =
+    tk::Jacobian( coordel[0], coordel[1], coordel[2], coordel[3] );
+
+  std::vector< tk::real > phic_bound(ncomp, 1.0);
+  std::vector< tk::real > phip_bound(nprim, 1.0);
+
+  const tk::real min = 1e-15;
+
+  for (std::size_t lf=0; lf<4; ++lf)
+  {
+    std::array< std::size_t, 3 > inpofa_l {{ inpoel[4*e+tk::lpofa[lf][0]],
+                                             inpoel[4*e+tk::lpofa[lf][1]],
+                                             inpoel[4*e+tk::lpofa[lf][2]] }};
+
+    std::array< std::array< tk::real, 3>, 3 > coordfa {{
+      {{ cx[ inpofa_l[0] ], cy[ inpofa_l[0] ], cz[ inpofa_l[0] ] }},
+      {{ cx[ inpofa_l[1] ], cy[ inpofa_l[1] ], cz[ inpofa_l[1] ] }},
+      {{ cx[ inpofa_l[2] ], cy[ inpofa_l[2] ], cz[ inpofa_l[2] ] }} }};
+
+    auto ng = tk::NGfa(ndof_el);
+
+    std::array< std::vector< tk::real >, 2 > coordgp;
+    std::vector< tk::real > wgp;
+
+    coordgp[0].resize( ng );
+    coordgp[1].resize( ng );
+    wgp.resize( ng );
+
+    tk::GaussQuadratureTri( ng, coordgp, wgp );
+
+    for (std::size_t igp=0; igp<ng; ++igp)
+    {
+      auto gp = tk::eval_gp( igp, coordfa, coordgp );
+      auto B = tk::eval_basis( ndof_el,
+            tk::Jacobian( coordel[0], gp, coordel[2], coordel[3] ) / detT,
+            tk::Jacobian( coordel[0], coordel[1], gp, coordel[3] ) / detT,
+            tk::Jacobian( coordel[0], coordel[1], coordel[2], gp ) / detT );
+
+      auto state = eval_state(ncomp, rdof, ndof_el, e, U, B);
+      auto sprim = eval_state(nprim, rdof, ndof_el, e, P, B);
+
+      for(std::size_t imat = 0; imat < nmat; imat++)
+      {
+        tk::real phi_rho(1.0), phi_rhoe(1.0), phi_pre(1.0);<--- phi_rho is assigned<--- phi_rhoe is assigned<--- phi_pre is assigned
+        // Evaluate the limiting coefficient for material density
+        auto rho = state[densityIdx(nmat, imat)];
+        auto rho_avg = U(e, densityDofIdx(nmat, imat, rdof, 0));
+        phi_rho = PositivityLimiting(min, rho, rho_avg);<--- phi_rho is overwritten
+        phic_bound[densityIdx(nmat, imat)] =
+          std::min(phic_bound[densityIdx(nmat, imat)], phi_rho);
+        // Evaluate the limiting coefficient for material energy
+        auto rhoe = state[energyIdx(nmat, imat)];
+        auto rhoe_avg = U(e, energyDofIdx(nmat, imat, rdof, 0));
+        phi_rhoe = PositivityLimiting(min, rhoe, rhoe_avg);<--- phi_rhoe is overwritten
+        phic_bound[energyIdx(nmat, imat)] =
+          std::min(phic_bound[energyIdx(nmat, imat)], phi_rhoe);
+        // Evaluate the limiting coefficient for material pressure
+        auto min_pre = std::max(min, state[volfracIdx(nmat, imat)] *
+          mat_blk[imat].compute< EOS::min_eff_pressure >(min, rho,
+          state[volfracIdx(nmat, imat)]));
+        auto pre = sprim[pressureIdx(nmat, imat)];
+        auto pre_avg = P(e, pressureDofIdx(nmat, imat, rdof, 0));
+        phi_pre = PositivityLimiting(min_pre, pre, pre_avg);<--- phi_pre is overwritten
+        phip_bound[pressureIdx(nmat, imat)] =
+          std::min(phip_bound[pressureIdx(nmat, imat)], phi_pre);
+      }
+    }
+  }
+
+  if(ndof_el > 4)
+  {
+    auto ng = tk::NGvol(ndof_el);
+    std::array< std::vector< tk::real >, 3 > coordgp;
+    std::vector< tk::real > wgp;
+
+    coordgp[0].resize( ng );
+    coordgp[1].resize( ng );
+    coordgp[2].resize( ng );
+    wgp.resize( ng );
+
+    tk::GaussQuadratureTet( ng, coordgp, wgp );
+
+    for (std::size_t igp=0; igp<ng; ++igp)
+    {
+      auto B = tk::eval_basis( ndof_el, coordgp[0][igp], coordgp[1][igp],
+        coordgp[2][igp] );
+
+      auto state = eval_state(ncomp, rdof, ndof_el, e, U, B);
+      auto sprim = eval_state(nprim, rdof, ndof_el, e, P, B);
+
+      for(std::size_t imat = 0; imat < nmat; imat++)
+      {
+        tk::real phi_rho(1.0), phi_rhoe(1.0), phi_pre(1.0);<--- phi_rho is assigned<--- phi_rhoe is assigned<--- phi_pre is assigned
+        // Evaluate the limiting coefficient for material density
+        auto rho = state[densityIdx(nmat, imat)];
+        auto rho_avg = U(e, densityDofIdx(nmat, imat, rdof, 0));
+        phi_rho = PositivityLimiting(min, rho, rho_avg);<--- phi_rho is overwritten
+        phic_bound[densityIdx(nmat, imat)] =
+          std::min(phic_bound[densityIdx(nmat, imat)], phi_rho);
+        // Evaluate the limiting coefficient for material energy
+        auto rhoe = state[energyIdx(nmat, imat)];
+        auto rhoe_avg = U(e, energyDofIdx(nmat, imat, rdof, 0));
+        phi_rhoe = PositivityLimiting(min, rhoe, rhoe_avg);<--- phi_rhoe is overwritten
+        phic_bound[energyIdx(nmat, imat)] =
+          std::min(phic_bound[energyIdx(nmat, imat)], phi_rhoe);
+        // Evaluate the limiting coefficient for material pressure
+        auto min_pre = std::max(min, state[volfracIdx(nmat, imat)] *
+          mat_blk[imat].compute< EOS::min_eff_pressure >(min, rho,
+          state[volfracIdx(nmat, imat)]));
+        auto pre = sprim[pressureIdx(nmat, imat)];
+        auto pre_avg = P(e, pressureDofIdx(nmat, imat, rdof, 0));
+        phi_pre = PositivityLimiting(min_pre, pre, pre_avg);<--- phi_pre is overwritten
+        phip_bound[pressureIdx(nmat, imat)] =
+          std::min(phip_bound[pressureIdx(nmat, imat)], phi_pre);
+      }
+    }
+  }
+
+  // apply new bounds to material quantities
+  for (std::size_t k=0; k<nmat; ++k) {
+    // mat density
+    phic_p1[densityIdx(nmat, k)] = std::min( phic_bound[densityIdx(nmat, k)],
+      phic_p1[densityIdx(nmat, k)] );
+    // mat energy
+    phic_p1[energyIdx(nmat, k)] = std::min( phic_bound[energyIdx(nmat, k)],
+      phic_p1[energyIdx(nmat, k)] );
+    // mat pressure
+    phip_p1[pressureIdx(nmat, k)] = std::min( phip_bound[pressureIdx(nmat, k)],
+      phip_p1[pressureIdx(nmat, k)] );
+
+    // for dgp2
+    if (ndof_el > 4) {
+      // mat density
+      phic_p2[densityIdx(nmat, k)] = std::min( phic_bound[densityIdx(nmat, k)],
+        phic_p2[densityIdx(nmat, k)] );
+      // mat energy
+      phic_p2[energyIdx(nmat, k)] = std::min( phic_bound[energyIdx(nmat, k)],
+        phic_p2[energyIdx(nmat, k)] );
+      // mat pressure
+      phip_p2[pressureIdx(nmat, k)] = std::min( phip_bound[pressureIdx(nmat, k)],
+        phip_p2[pressureIdx(nmat, k)] );
+    }
+  }
+}
+
+void PositivityPreservingMultiMat_FV(
+  const std::vector< std::size_t >& inpoel,
+  std::size_t nelem,
+  std::size_t nmat,
+  const std::vector< inciter::EOS >& mat_blk,
+  const tk::UnsMesh::Coords& coord,
+  const tk::Fields& /*geoFace*/,
+  tk::Fields& U,
+  tk::Fields& P )
+// *****************************************************************************
+//  Positivity preserving limiter for the FV multi-material solver
+//! \param[in] inpoel Element connectivity
+//! \param[in] nelem Number of elements
+//! \param[in] nmat Number of materials in this PDE system
+//! \param[in] mat_blk Material EOS block
+//! \param[in] coord Array of nodal coordinates
+////! \param[in] geoFace Face geometry array
+//! \param[in,out] U High-order solution vector which gets limited
+//! \param[in,out] P High-order vector of primitives which gets limited
+//! \details This positivity preserving limiter function should be called for
+//!   FV multimat.
+// *****************************************************************************
+{
+  const auto rdof = inciter::g_inputdeck.get< tag::rdof >();
+  const auto ncomp = U.nprop() / rdof;
+  const auto nprim = P.nprop() / rdof;
+
+  const auto& cx = coord[0];
+  const auto& cy = coord[1];
+  const auto& cz = coord[2];
+
+  for (std::size_t e=0; e<nelem; ++e)
+  {
+    // Extract the element coordinates
+    std::array< std::array< tk::real, 3>, 4 > coordel {{
+      {{ cx[ inpoel[4*e  ] ], cy[ inpoel[4*e  ] ], cz[ inpoel[4*e  ] ] }},
+      {{ cx[ inpoel[4*e+1] ], cy[ inpoel[4*e+1] ], cz[ inpoel[4*e+1] ] }},
+      {{ cx[ inpoel[4*e+2] ], cy[ inpoel[4*e+2] ], cz[ inpoel[4*e+2] ] }},
+      {{ cx[ inpoel[4*e+3] ], cy[ inpoel[4*e+3] ], cz[ inpoel[4*e+3] ] }} }};
+
+    // Compute the determinant of Jacobian matrix
+    auto detT =
+      tk::Jacobian( coordel[0], coordel[1], coordel[2], coordel[3] );
+
+    std::vector< tk::real > phic(ncomp, 1.0);
+    std::vector< tk::real > phip(nprim, 1.0);
+
+    const tk::real min = 1e-15;
+
+    // 1. Enforce positive density (total energy will be positive if pressure
+    //    and density are positive)
+    for (std::size_t lf=0; lf<4; ++lf)
+    {
+      std::array< std::size_t, 3 > inpofa_l {{ inpoel[4*e+tk::lpofa[lf][0]],
+                                               inpoel[4*e+tk::lpofa[lf][1]],
+                                               inpoel[4*e+tk::lpofa[lf][2]] }};
+
+      // face coordinates
+      std::array< std::array< tk::real, 3>, 3 > coordfa {{
+        {{ cx[ inpofa_l[0] ], cy[ inpofa_l[0] ], cz[ inpofa_l[0] ] }},
+        {{ cx[ inpofa_l[1] ], cy[ inpofa_l[1] ], cz[ inpofa_l[1] ] }},
+        {{ cx[ inpofa_l[2] ], cy[ inpofa_l[2] ], cz[ inpofa_l[2] ] }} }};
+
+      // face centroid
+      std::array< tk::real, 3 > fc{{
+        (coordfa[0][0]+coordfa[1][0]+coordfa[2][0])/3.0 ,
+        (coordfa[0][1]+coordfa[1][1]+coordfa[2][1])/3.0 ,
+        (coordfa[0][2]+coordfa[1][2]+coordfa[2][2])/3.0 }};
+
+      auto B = tk::eval_basis( rdof,
+            tk::Jacobian( coordel[0], fc, coordel[2], coordel[3] ) / detT,
+            tk::Jacobian( coordel[0], coordel[1], fc, coordel[3] ) / detT,
+            tk::Jacobian( coordel[0], coordel[1], coordel[2], fc ) / detT );
+      auto state = eval_state(ncomp, rdof, rdof, e, U, B);
+
+      for(std::size_t i=0; i<nmat; i++)
+      {
+        // Evaluate the limiting coefficient for material density
+        auto rho = state[densityIdx(nmat, i)];
+        auto rho_avg = U(e, densityDofIdx(nmat, i, rdof, 0));
+        auto phi_rho = PositivityLimiting(min, rho, rho_avg);
+        phic[densityIdx(nmat, i)] =
+          std::min(phic[densityIdx(nmat, i)], phi_rho);
+      }
+    }
+    // apply limiter coefficient
+    for(std::size_t i=0; i<nmat; i++)
+    {
+      U(e, densityDofIdx(nmat,i,rdof,1)) *= phic[densityIdx(nmat,i)];
+      U(e, densityDofIdx(nmat,i,rdof,2)) *= phic[densityIdx(nmat,i)];
+      U(e, densityDofIdx(nmat,i,rdof,3)) *= phic[densityIdx(nmat,i)];
+    }
+
+    // 2. Enforce positive pressure (assuming density is positive)
+    for (std::size_t lf=0; lf<4; ++lf)
+    {
+      std::array< std::size_t, 3 > inpofa_l {{ inpoel[4*e+tk::lpofa[lf][0]],
+                                               inpoel[4*e+tk::lpofa[lf][1]],
+                                               inpoel[4*e+tk::lpofa[lf][2]] }};
+
+      // face coordinates
+      std::array< std::array< tk::real, 3>, 3 > coordfa {{
+        {{ cx[ inpofa_l[0] ], cy[ inpofa_l[0] ], cz[ inpofa_l[0] ] }},
+        {{ cx[ inpofa_l[1] ], cy[ inpofa_l[1] ], cz[ inpofa_l[1] ] }},
+        {{ cx[ inpofa_l[2] ], cy[ inpofa_l[2] ], cz[ inpofa_l[2] ] }} }};
+
+      // face centroid
+      std::array< tk::real, 3 > fc{{
+        (coordfa[0][0]+coordfa[1][0]+coordfa[2][0])/3.0 ,
+        (coordfa[0][1]+coordfa[1][1]+coordfa[2][1])/3.0 ,
+        (coordfa[0][2]+coordfa[1][2]+coordfa[2][2])/3.0 }};
+
+      auto B = tk::eval_basis( rdof,
+            tk::Jacobian( coordel[0], fc, coordel[2], coordel[3] ) / detT,
+            tk::Jacobian( coordel[0], coordel[1], fc, coordel[3] ) / detT,
+            tk::Jacobian( coordel[0], coordel[1], coordel[2], fc ) / detT );
+      auto state = eval_state(ncomp, rdof, rdof, e, U, B);
+      auto sprim = eval_state(nprim, rdof, rdof, e, P, B);
+
+      for(std::size_t i=0; i<nmat; i++)
+      {
+        tk::real phi_pre(1.0);<--- phi_pre is assigned
+        // Evaluate the limiting coefficient for material pressure
+        auto rho = state[densityIdx(nmat, i)];
+        auto min_pre = std::max(min, U(e,volfracDofIdx(nmat,i,rdof,0)) *
+          mat_blk[i].compute< EOS::min_eff_pressure >(min, rho,
+          U(e,volfracDofIdx(nmat,i,rdof,0))));
+        auto pre = sprim[pressureIdx(nmat, i)];
+        auto pre_avg = P(e, pressureDofIdx(nmat, i, rdof, 0));
+        phi_pre = PositivityLimiting(min_pre, pre, pre_avg);<--- phi_pre is overwritten
+        phip[pressureIdx(nmat, i)] =
+          std::min(phip[pressureIdx(nmat, i)], phi_pre);
+      }
+    }
+    // apply limiter coefficient
+    for(std::size_t i=0; i<nmat; i++)
+    {
+      P(e, pressureDofIdx(nmat,i,rdof,1)) *= phip[pressureIdx(nmat,i)];
+      P(e, pressureDofIdx(nmat,i,rdof,2)) *= phip[pressureIdx(nmat,i)];
+      P(e, pressureDofIdx(nmat,i,rdof,3)) *= phip[pressureIdx(nmat,i)];
+    }
+  }
+}
+
+tk::real
+PositivityLimiting( const tk::real min,
+                    const tk::real u_gp,
+                    const tk::real u_avg )
+// *****************************************************************************
+//  Positivity-preserving limiter function
+//! \param[in] min Minimum bound for volume fraction
+//! \param[in] u_gp Variable quantity at the quadrature point
+//! \param[in] u_avg Cell-average variable quantitiy
+//! \return The limiting coefficient from the positivity-preserving limiter
+//!   function
+// *****************************************************************************
+{
+  tk::real phi(1.0);
+  tk::real diff = u_gp - u_avg;
+  // Only when u_gp is less than minimum threshold and the high order
+  // contribution is not zero, the limiting function will be applied
+  if(u_gp < min)
+    phi = std::fabs( (min - u_avg) / (diff+std::copysign(1e-15,diff)) );
+  return phi;
+}
+
+bool
+interfaceIndicator( std::size_t nmat,
+  const std::vector< tk::real >& al,
+  std::vector< std::size_t >& matInt )
+// *****************************************************************************
+//  Interface indicator function, which checks element for material interface
+//! \param[in] nmat Number of materials in this PDE system
+//! \param[in] al Cell-averaged volume fractions
+//! \param[in] matInt Array indicating which material has an interface
+//! \return Boolean which indicates if the element contains a material interface
+// *****************************************************************************
+{
+  bool intInd = false;
+
+  // limits under which compression is to be performed
+  auto al_eps = 1e-08;
+  auto loLim = 2.0 * al_eps;
+  auto hiLim = 1.0 - loLim;
+
+  auto almax = 0.0;
+  for (std::size_t k=0; k<nmat; ++k)
+  {
+    almax = std::max(almax, al[k]);
+    matInt[k] = 0;
+    if ((al[k] > loLim) && (al[k] < hiLim)) matInt[k] = 1;
+  }
+
+  if ((almax > loLim) && (almax < hiLim)) intInd = true;
+
+  return intInd;
+}
+
+void MarkShockCells ( const std::size_t nelem,
+                      const std::size_t nmat,
+                      const std::size_t ndof,
+                      const std::size_t rdof,
+                      const std::vector< inciter::EOS >& mat_blk,
+                      const std::vector< std::size_t >& ndofel,
+                      const std::vector< std::size_t >& inpoel,
+                      const tk::UnsMesh::Coords& coord,
+                      const inciter::FaceData& fd,
+                      [[maybe_unused]] const tk::Fields& geoFace,
+                      const tk::Fields& geoElem,
+                      const tk::FluxFn& flux,
+                      const std::vector< std::size_t >& solidx,
+                      const tk::Fields& U,
+                      const tk::Fields& P,
+                      std::vector< std::size_t >& shockmarker )
+// *****************************************************************************
+//  Mark the cells that contain discontinuity according to the interface
+//    condition
+//! \param[in] nelem Number of elements
+//! \param[in] nmat Number of materials in this PDE system
+//! \param[in] ndof Maximum number of degrees of freedom
+//! \param[in] rdof Maximum number of reconstructed degrees of freedom
+//! \param[in] mat_blk EOS material block
+//! \param[in] ndofel Vector of local number of degrees of freedome
+//! \param[in] inpoel Element-node connectivity
+//! \param[in] coord Array of nodal coordinates
+//! \param[in] fd Face connectivity and boundary conditions object
+//! \param[in] geoFace Face geometry array
+//! \param[in] geoElem Element geometry array
+//! \param[in] flux Flux function to use
+//! \param[in] solidx Solid material index indicator
+//! \param[in] U Solution vector at recent time step
+//! \param[in] P Vector of primitives at recent time step
+//! \param[in, out] shockmarker Vector of the shock indicator
+//! \details This function computes the discontinuity indicator based on
+//!   interface conditon. It is based on the following paper:
+//!   Hong L., Gianni A., Robert N. (2021) A moving discontinuous Galerkin
+//!   finite element method with interface condition enforcement for
+//!   compressible flows. Journal of Computational Physics,
+//!   doi: https://doi.org/10.1016/j.jcp.2021.110618
+// *****************************************************************************
+{
+  const auto coeff = g_inputdeck.get< tag::shock_detector_coeff >();
+
+  std::vector< tk::real > IC(U.nunk(), 0.0);
+  const auto& esuf = fd.Esuf();
+  const auto& inpofa = fd.Inpofa();
+
+  const auto& cx = coord[0];
+  const auto& cy = coord[1];
+  const auto& cz = coord[2];
+
+  auto ncomp = U.nprop()/rdof;<--- Variable 'ncomp' is assigned a value that is never used.
+  auto nprim = P.nprop()/rdof;<--- Variable 'nprim' is assigned a value that is never used.
+
+  // The interface-conservation based indicator will only evaluate the flux jump
+  // for the momentum equations
+  std::set< std::size_t > vars;
+  if(nmat > 1) {          // multi-material flow
+    for (std::size_t i=0; i<3; ++i) vars.insert(momentumIdx(nmat, i));
+  } else {                // single-material flow
+    for (std::size_t i=1; i<=3; ++i) vars.insert(i);
+  }
+
+  // Loop over faces
+  for (auto f=fd.Nbfac(); f<esuf.size()/2; ++f) {
+    Assert( esuf[2*f] > -1 && esuf[2*f+1] > -1, "Interior element detected "
+            "as -1" );
+
+    std::size_t el = static_cast< std::size_t >(esuf[2*f]);
+    std::size_t er = static_cast< std::size_t >(esuf[2*f+1]);
+
+    // When the number of gauss points for the left and right element are
+    // different, choose the larger ng
+    auto ng_l = tk::NGfa(ndofel[el]);
+    auto ng_r = tk::NGfa(ndofel[er]);
+
+    auto ng = std::max( ng_l, ng_r );
+
+    std::array< std::vector< tk::real >, 2 > coordgp
+      { std::vector<tk::real>(ng), std::vector<tk::real>(ng) };
+    std::vector< tk::real > wgp( ng );
+
+    tk::GaussQuadratureTri( ng, coordgp, wgp );
+
+    // Extract the element coordinates
+    std::array< std::array< tk::real, 3>, 4 > coordel_l {{
+      {{ cx[ inpoel[4*el  ] ], cy[ inpoel[4*el  ] ], cz[ inpoel[4*el  ] ] }},
+      {{ cx[ inpoel[4*el+1] ], cy[ inpoel[4*el+1] ], cz[ inpoel[4*el+1] ] }},
+      {{ cx[ inpoel[4*el+2] ], cy[ inpoel[4*el+2] ], cz[ inpoel[4*el+2] ] }},
+      {{ cx[ inpoel[4*el+3] ], cy[ inpoel[4*el+3] ], cz[ inpoel[4*el+3] ] }} }};
+
+    std::array< std::array< tk::real, 3>, 4 > coordel_r {{
+      {{ cx[ inpoel[4*er  ] ], cy[ inpoel[4*er  ] ], cz[ inpoel[4*er  ] ] }},
+      {{ cx[ inpoel[4*er+1] ], cy[ inpoel[4*er+1] ], cz[ inpoel[4*er+1] ] }},
+      {{ cx[ inpoel[4*er+2] ], cy[ inpoel[4*er+2] ], cz[ inpoel[4*er+2] ] }},
+      {{ cx[ inpoel[4*er+3] ], cy[ inpoel[4*er+3] ], cz[ inpoel[4*er+3] ] }} }};
+
+    // Compute the determinant of Jacobian matrix
+    auto detT_l =
+      tk::Jacobian( coordel_l[0], coordel_l[1], coordel_l[2], coordel_l[3] );
+    auto detT_r =
+      tk::Jacobian( coordel_r[0], coordel_r[1], coordel_r[2], coordel_r[3] );
+
+    std::array< std::array< tk::real, 3>, 3 > coordfa {{
+      {{ cx[ inpofa[3*f  ] ], cy[ inpofa[3*f  ] ], cz[ inpofa[3*f  ] ] }},
+      {{ cx[ inpofa[3*f+1] ], cy[ inpofa[3*f+1] ], cz[ inpofa[3*f+1] ] }},
+      {{ cx[ inpofa[3*f+2] ], cy[ inpofa[3*f+2] ], cz[ inpofa[3*f+2] ] }} }};
+
+    std::array< tk::real, 3 >
+      fn{{ geoFace(f,1), geoFace(f,2), geoFace(f,3) }};
+
+    // Numerator and denominator of the shock indicator
+    tk::real numer(0.0), denom(0.0);
+    std::vector< tk::real > fl_jump, fl_avg;
+    fl_jump.resize(3, 0.0);
+    fl_avg.resize(3, 0.0);
+
+    for (std::size_t igp=0; igp<ng; ++igp) {
+      auto gp = tk::eval_gp( igp, coordfa, coordgp );
+      std::size_t dof_el, dof_er;
+      if (rdof > ndof)
+      {
+        dof_el = rdof;
+        dof_er = rdof;
+      }
+      else
+      {
+        dof_el = ndofel[el];
+        dof_er = ndofel[er];
+      }
+      std::array< tk::real, 3> ref_gp_l{
+        tk::Jacobian( coordel_l[0], gp, coordel_l[2], coordel_l[3] ) / detT_l,
+        tk::Jacobian( coordel_l[0], coordel_l[1], gp, coordel_l[3] ) / detT_l,
+        tk::Jacobian( coordel_l[0], coordel_l[1], coordel_l[2], gp ) / detT_l };
+      std::array< tk::real, 3> ref_gp_r{
+        tk::Jacobian( coordel_r[0], gp, coordel_r[2], coordel_r[3] ) / detT_r,
+        tk::Jacobian( coordel_r[0], coordel_r[1], gp, coordel_r[3] ) / detT_r,
+        tk::Jacobian( coordel_r[0], coordel_r[1], coordel_r[2], gp ) / detT_r };
+      auto B_l = tk::eval_basis( dof_el, ref_gp_l[0], ref_gp_l[1], ref_gp_l[2] );
+      auto B_r = tk::eval_basis( dof_er, ref_gp_r[0], ref_gp_r[1], ref_gp_r[2] );
+
+      std::array< std::vector< tk::real >, 2 > state;
+
+      // Evaluate the high order solution at the qudrature point
+      state[0] = tk::evalPolynomialSol(mat_blk, 0, ncomp, nprim, rdof,
+        nmat, el, dof_el, inpoel, coord, geoElem, ref_gp_l, B_l, U, P);
+      state[1] = tk::evalPolynomialSol(mat_blk, 0, ncomp, nprim, rdof,
+        nmat, er, dof_er, inpoel, coord, geoElem, ref_gp_r, B_r, U, P);
+
+      Assert( state[0].size() == ncomp+nprim, "Incorrect size for "
+              "appended boundary state vector" );
+      Assert( state[1].size() == ncomp+nprim, "Incorrect size for "
+              "appended boundary state vector" );
+
+      // Force deformation unknown to first order
+      for (std::size_t k=0; k<nmat; ++k)
+        if (solidx[k] > 0)
+          for (std::size_t i=0; i<3; ++i)
+            for (std::size_t j=0; j<3; ++j)
+            {
+              state[0][deformIdx(nmat, solidx[k], i, j)] = U(el,deformDofIdx(
+                nmat, solidx[k], i, j, rdof, 0));
+              state[1][deformIdx(nmat, solidx[k], i, j)] = U(er,deformDofIdx(
+                nmat, solidx[k], i, j, rdof, 0));
+            }
+
+      // Evaluate the flux
+      auto fl = flux( ncomp, mat_blk, state[0], {} );
+      auto fr = flux( ncomp, mat_blk, state[1], {} );
+
+      std::size_t i(0);
+      for (const auto& c : vars) {
+        tk::real fn_l(0.0), fn_r(0.0);
+        for(std::size_t idir = 0; idir < 3; idir++) {
+          fn_l += fl[c][idir] * fn[idir];
+          fn_r += fr[c][idir] * fn[idir];
+        }
+        fl_jump[i] += wgp[igp] * (fn_l - fn_r) * (fn_l - fn_r);
+        fl_avg[i]  += wgp[igp] * (fn_l + fn_r) * (fn_l + fn_r) * 0.25;
+        ++i;
+      }
+    }
+
+    // Evaluate the numerator and denominator
+    for(std::size_t idir = 0; idir < 3; idir++) {
+      numer += std::sqrt(fl_jump[idir]);
+      denom += std::sqrt(fl_avg[idir]);
+    }
+
+    tk::real Ind(0.0);
+    if(denom > 1e-8)
+      Ind = numer / denom;
+    IC[el] = std::max(IC[el], Ind);
+    IC[er] = std::max(IC[er], Ind);
+  }
+
+  tk::real power = 0.0;
+  if(rdof == 10)  power = 1.5;
+  else            power = 1.0;
+
+  // Loop over element to mark shock cell
+  for (std::size_t e=0; e<nelem; ++e) {
+    // Evaluate the threshold
+    auto thres = coeff * std::pow(geoElem(e, 4), power);
+    if(IC[e] > thres)
+      shockmarker[e] = 1;
+    else
+      shockmarker[e] = 0;
+  }
+}
+
+void
+correctLimConservMultiMat(
+  std::size_t nelem,
+  const std::vector< EOS >& mat_blk,
+  std::size_t nmat,
+  const std::vector< std::size_t >& inpoel,
+  const tk::UnsMesh::Coords& coord,
+  const tk::Fields& geoElem,
+  const tk::Fields& prim,
+  tk::Fields& unk )
+// *****************************************************************************
+//  Update the conservative quantities after limiting for multi-material systems
+//! \param[in] nelem Number of internal elements
+//! \param[in] mat_blk EOS material block
+//! \param[in] nmat Number of materials in this PDE system
+//! \param[in] inpoel Element-node connectivity
+//! \param[in] coord Array of nodal coordinates
+//! \param[in] geoElem Element geometry array
+//! \param[in] prim Array of primitive variables
+//! \param[in,out] unk Array of conservative variables
+//! \details This function computes the updated dofs for conservative
+//!   quantities based on the limited primitive quantities, to re-instate
+//!   consistency between the limited primitive and evolved quantities. For
+//!   further details, see Pandare et al. (2023). On the Design of Stable,
+//!   Consistent, and Conservative High-Order Methods for Multi-Material
+//!   Hydrodynamics. J Comp Phys, 112313.
+// *****************************************************************************
+{
+  const auto rdof = g_inputdeck.get< tag::rdof >();
+  std::size_t ncomp = unk.nprop()/rdof;
+  std::size_t nprim = prim.nprop()/rdof;
+  const auto intsharp = inciter::g_inputdeck.get< tag::multimat,
+    tag::intsharp >();
+
+  for (std::size_t e=0; e<nelem; ++e) {
+    // Here we pre-compute the right-hand-side vector. The reason that the
+    // lhs in DG.cpp is not used is that the size of this vector in this
+    // projection procedure should be rdof instead of ndof.
+    auto L = tk::massMatrixDubiner(rdof, geoElem(e,0));
+
+    // The right-hand side vector is sized as nprim, i.e. the primitive quantity
+    // vector. However, it stores the consistently obtained values of evolved
+    // quantities, since nprim is the number of evolved quantities that need to
+    // be evaluated consistently. For this reason, accessing R will require
+    // the primitive quantity accessors. But this access is intended to give
+    // the corresponding evolved quantites, as follows:
+    // pressureIdx() - mat. total energy
+    // velocityIdx() - bulk momentum components
+    // stressIdx() - mat. inverse deformation gradient tensor components
+    std::vector< tk::real > R(nprim*rdof, 0.0);
+
+    auto ng = tk::NGvol(rdof);
+
+    // Arrays for quadrature points
+    std::array< std::vector< tk::real >, 3 > coordgp;
+    std::vector< tk::real > wgp;
+
+    coordgp[0].resize( ng );
+    coordgp[1].resize( ng );
+    coordgp[2].resize( ng );
+    wgp.resize( ng );
+
+    tk::GaussQuadratureTet( ng, coordgp, wgp );
+
+    // Loop over quadrature points in element e
+    for (std::size_t igp=0; igp<ng; ++igp) {
+      // Compute the basis function
+      auto B = tk::eval_basis( rdof, coordgp[0][igp], coordgp[1][igp],
+                               coordgp[2][igp] );
+
+      auto w = wgp[igp] * geoElem(e, 0);
+
+      // Evaluate the solution at quadrature point
+      auto state = evalPolynomialSol(mat_blk, intsharp, ncomp, nprim,
+        rdof, nmat, e, rdof, inpoel, coord, geoElem,
+        {{coordgp[0][igp], coordgp[1][igp], coordgp[2][igp]}}, B, unk, prim);
+
+      // Solution vector that stores the material energy and bulk momentum
+      std::vector< tk::real > s(nprim, 0.0);
+
+      // Bulk density at quadrature point
+      tk::real rhob(0.0);
+      for (std::size_t k=0; k<nmat; ++k)
+        rhob += state[densityIdx(nmat, k)];
+
+      // Velocity vector at quadrature point
+      std::array< tk::real, 3 >
+        vel{ state[ncomp+velocityIdx(nmat, 0)],
+             state[ncomp+velocityIdx(nmat, 1)],
+             state[ncomp+velocityIdx(nmat, 2)] };
+
+      // Compute and store the bulk momentum
+      for(std::size_t idir = 0; idir < 3; idir++)
+        s[velocityIdx(nmat, idir)] = rhob * vel[idir];
+
+      // Compute and store material energy at quadrature point
+      for(std::size_t imat = 0; imat < nmat; imat++) {
+        auto alphamat = state[volfracIdx(nmat, imat)];
+        auto rhomat = state[densityIdx(nmat, imat)]/alphamat;
+        auto premat = state[ncomp+pressureIdx(nmat, imat)]/alphamat;
+        auto gmat = getDeformGrad(nmat, imat, state);
+        s[pressureIdx(nmat,imat)] = alphamat *
+          mat_blk[imat].compute< EOS::totalenergy >( rhomat, vel[0], vel[1],
+          vel[2], premat, gmat );
+      }
+
+      // Evaluate the righ-hand-side vector
+      for(std::size_t k = 0; k < nprim; k++) {
+        auto mark = k * rdof;
+        for(std::size_t idof = 0; idof < rdof; idof++)
+          R[mark+idof] += w * s[k] * B[idof];
+      }
+    }
+
+    // Update the high order dofs of the material energy
+    for(std::size_t imat = 0; imat < nmat; imat++) {
+      for(std::size_t idof = 1; idof < rdof; idof++)
+        unk(e, energyDofIdx(nmat, imat, rdof, idof)) =
+          R[pressureDofIdx(nmat,imat,rdof,idof)] / L[idof];
+    }
+
+    // Update the high order dofs of the bulk momentum
+    for(std::size_t idir = 0; idir < 3; idir++) {
+      for(std::size_t idof = 1; idof < rdof; idof++)
+        unk(e, momentumDofIdx(nmat, idir, rdof, idof)) =
+          R[velocityDofIdx(nmat,idir,rdof,idof)] / L[idof];
+    }
+  }
+}
+
+tk::real
+constrain_pressure( const std::vector< EOS >& mat_blk,
+  tk::real apr,
+  tk::real arho,
+  tk::real alpha=1.0,
+  std::size_t imat=0 )
+// *****************************************************************************
+//  Constrain material partial pressure (alpha_k * p_k)
+//! \param[in] apr Material partial pressure (alpha_k * p_k)
+//! \param[in] arho Material partial density (alpha_k * rho_k)
+//! \param[in] alpha Material volume fraction. Default is 1.0, so that for the
+//!   single-material system, this argument can be left unspecified by the
+//!   calling code
+//! \param[in] imat Material-id who's EoS is required. Default is 0, so that
+//!   for the single-material system, this argument can be left unspecified by
+//!   the calling code
+//! \return Constrained material partial pressure (alpha_k * p_k)
+// *****************************************************************************
+{
+  return std::max(apr, alpha*mat_blk[imat].compute<
+    EOS::min_eff_pressure >(1e-12, arho, alpha));
+}
+
+
+} // inciter::
 
diff --git a/Debug/cppcheck/69.html b/Debug/cppcheck/69.html index 11fbe7c8d376..a07419d3990e 100644 --- a/Debug/cppcheck/69.html +++ b/Debug/cppcheck/69.html @@ -152,12 +152,12 @@
   1
@@ -1168,4113 +1168,1015 @@ 

Cppcheck report - [

// *****************************************************************************
+1009
// *****************************************************************************
 /*!
-  \file      src/PDE/Limiter.cpp
+  \file      src/PDE/Integrate/MultiMatTerms.cpp
   \copyright 2012-2015 J. Bakosi,
              2016-2018 Los Alamos National Security, LLC.,
              2019-2021 Triad National Security, LLC.
              All rights reserved. See the LICENSE file for details.
-  \brief     Limiters for discontiunous Galerkin methods
-  \details   This file contains functions that provide limiter function
-    calculations for maintaining monotonicity near solution discontinuities
-    for the DG discretization.
-*/
-// *****************************************************************************
-
-#include <array>
-#include <vector>
-
-#include "FaceData.hpp"
-#include "Vector.hpp"
-#include "Limiter.hpp"
-#include "DerivedData.hpp"
-#include "Integrate/Quadrature.hpp"
-#include "Integrate/Basis.hpp"
+  \brief     Functions for computing volume integrals of multi-material terms
+     using DG methods
+  \details   This file contains functionality for computing volume integrals of
+     non-conservative and pressure relaxation terms that appear in the
+     multi-material hydrodynamic equations, using the discontinuous Galerkin
+     method for various orders of numerical representation.
+*/
+// *****************************************************************************
+
+#include "QuinoaConfig.hpp"
+
+#include "MultiMatTerms.hpp"
+#include "Vector.hpp"
+#include "Quadrature.hpp"
+#include "MultiMat/MultiMatIndexing.hpp"
+#include "Reconstruction.hpp"
 #include "Inciter/InputDeck/InputDeck.hpp"
-#include "PrefIndicator.hpp"
-#include "Reconstruction.hpp"
-#include "Integrate/Mass.hpp"
-#include "MultiMat/MiscMultiMatFns.hpp"
-
-namespace inciter {
-
-extern ctr::InputDeck g_inputdeck;
+#include "EoS/GetMatProp.hpp"
+
+namespace inciter {
+extern ctr::InputDeck g_inputdeck;
+}
+
+// Lapacke forward declarations
+extern "C" {
 
-void
-WENO_P1( const std::vector< int >& esuel,
-         tk::Fields& U )
-// *****************************************************************************
-//  Weighted Essentially Non-Oscillatory (WENO) limiter for DGP1
-//! \param[in] esuel Elements surrounding elements
-//! \param[in,out] U High-order solution vector which gets limited
-//! \details This WENO function should be called for transport and compflow
-//! \note This limiter function is experimental and untested. Use with caution.
-// *****************************************************************************
-{
-  const auto rdof = inciter::g_inputdeck.get< tag::rdof >();
-  const auto cweight = inciter::g_inputdeck.get< tag::cweight >();
-  auto nelem = esuel.size()/4;
-  std::array< std::vector< tk::real >, 3 >
-    limU {{ std::vector< tk::real >(nelem),
-            std::vector< tk::real >(nelem),
-            std::vector< tk::real >(nelem) }};
-
-  std::size_t ncomp = U.nprop()/rdof;
-
-  for (inciter::ncomp_t c=0; c<ncomp; ++c)
-  {
-    for (std::size_t e=0; e<nelem; ++e)
-    {
-      WENOLimiting(U, esuel, e, c, rdof, cweight, limU);
-    }
-
-    auto mark = c*rdof;
-
-    for (std::size_t e=0; e<nelem; ++e)
-    {
-      U(e, mark+1) = limU[0][e];
-      U(e, mark+2) = limU[1][e];
-      U(e, mark+3) = limU[2][e];
-    }
-  }
-}
-
-void
-Superbee_P1( const std::vector< int >& esuel,
-             const std::vector< std::size_t >& inpoel,
-             const std::vector< std::size_t >& ndofel,
-             const tk::UnsMesh::Coords& coord,
-             tk::Fields& U )
-// *****************************************************************************
-//  Superbee limiter for DGP1
-//! \param[in] esuel Elements surrounding elements
-//! \param[in] inpoel Element connectivity
-//! \param[in] ndofel Vector of local number of degrees of freedom
-//! \param[in] coord Array of nodal coordinates
-//! \param[in,out] U High-order solution vector which gets limited
-//! \details This Superbee function should be called for transport and compflow
-// *****************************************************************************
-{
-  const auto rdof = inciter::g_inputdeck.get< tag::rdof >();
-  const auto ndof = inciter::g_inputdeck.get< tag::ndof >();
-  std::size_t ncomp = U.nprop()/rdof;
+using lapack_int = long;
+
+#define LAPACK_ROW_MAJOR 101
+
+lapack_int LAPACKE_dsysv( int, char, lapack_int, lapack_int, double*,
+    lapack_int, lapack_int*, double*, lapack_int );
+
+}
+
+namespace tk {
+
+void
+nonConservativeInt( std::size_t nmat,
+                    const std::vector< inciter::EOS >& mat_blk,
+                    const std::size_t ndof,
+                    const std::size_t rdof,
+                    const std::size_t nelem,
+                    const std::vector< std::size_t >& inpoel,
+                    const UnsMesh::Coords& coord,
+                    const Fields& geoElem,
+                    const Fields& U,
+                    const Fields& P,
+                    const std::vector< std::vector< tk::real > >& riemannDeriv,
+                    const std::vector< std::size_t >& ndofel,
+                    Fields& R,
+                    int intsharp )
+// *****************************************************************************
+//  Compute volume integrals for multi-material DG
+//! \details This is called for multi-material DG, computing volume integrals of
+//!   terms in the volume fraction and energy equations, which do not exist in
+//!   the single-material flow formulation (for `CompFlow` DG). For further
+//!   details see Pelanti, M., & Shyue, K. M. (2019). A numerical model for
+//!   multiphase liquid–vapor–gas flows with interfaces and cavitation.
+//!   International Journal of Multiphase Flow, 113, 208-230.
+//! \param[in] nmat Number of materials in this PDE system
+//! \param[in] mat_blk EOS material block
+//! \param[in] ndof Maximum number of degrees of freedom
+//! \param[in] rdof Maximum number of reconstructed degrees of freedom
+//! \param[in] nelem Total number of elements
+//! \param[in] inpoel Element-node connectivity
+//! \param[in] coord Array of nodal coordinates
+//! \param[in] geoElem Element geometry array
+//! \param[in] U Solution vector at recent time step
+//! \param[in] P Vector of primitive quantities at recent time step
+//! \param[in] riemannDeriv Derivatives of partial-pressures and velocities
+//!   computed from the Riemann solver for use in the non-conservative terms
+//! \param[in] ndofel Vector of local number of degrees of freedome
+//! \param[in,out] R Right-hand side vector added to
+//! \param[in] intsharp Interface reconstruction indicator
+// *****************************************************************************
+{
+  using inciter::volfracIdx;
+  using inciter::densityIdx;
+  using inciter::momentumIdx;
+  using inciter::energyIdx;
+  using inciter::velocityIdx;
+  using inciter::deformIdx;
+  using inciter::newSolidsAccFn;
 
-  auto beta_lim = 2.0;
-
-  for (std::size_t e=0; e<esuel.size()/4; ++e)
-  {
-    // If an rDG method is set up (P0P1), then, currently we compute the P1
-    // basis functions and solutions by default. This implies that P0P1 is
-    // unsupported in the p-adaptive DG (PDG). This is a workaround until we
-    // have rdofel, which is needed to distinguish between ndofs and rdofs per
-    // element for pDG.
-    std::size_t dof_el;
-    if (rdof > ndof)
-    {
-      dof_el = rdof;
-    }
-    else
-    {
-      dof_el = ndofel[e];
-    }
+  const auto& solidx =
+    inciter::g_inputdeck.get< tag::matidxmap, tag::solidx >();
+
+  const auto& cx = coord[0];
+  const auto& cy = coord[1];
+  const auto& cz = coord[2];
+
+  auto ncomp = U.nprop()/rdof;
+  auto nprim = P.nprop()/rdof;
+
+  // compute volume integrals
+  for (std::size_t e=0; e<nelem; ++e)
+  {
+    auto ng = tk::NGvol(ndofel[e]);
+
+    // arrays for quadrature points
+    std::array< std::vector< real >, 3 > coordgp;
+    std::vector< real > wgp;
 
-    if (dof_el > 1)
-    {
-      auto phi = SuperbeeLimiting(U, esuel, inpoel, coord, e, ndof, rdof,
-                   dof_el, ncomp, beta_lim);
+    coordgp[0].resize( ng );
+    coordgp[1].resize( ng );
+    coordgp[2].resize( ng );
+    wgp.resize( ng );
 
-      // apply limiter function
-      for (inciter::ncomp_t c=0; c<ncomp; ++c)
-      {
-        auto mark = c*rdof;
-        U(e, mark+1) = phi[c] * U(e, mark+1);
-        U(e, mark+2) = phi[c] * U(e, mark+2);
-        U(e, mark+3) = phi[c] * U(e, mark+3);
-      }
-    }
-  }
-}
-
-void
-SuperbeeMultiMat_P1(
-  const std::vector< int >& esuel,
-  const std::vector< std::size_t >& inpoel,
-  const std::vector< std::size_t >& ndofel,
-  const tk::UnsMesh::Coords& coord,
-  const std::vector< std::size_t >& solidx,
-  tk::Fields& U,
-  tk::Fields& P,
-  std::size_t nmat )
-// *****************************************************************************
-//  Superbee limiter for multi-material DGP1
-//! \param[in] esuel Elements surrounding elements
-//! \param[in] inpoel Element connectivity
-//! \param[in] ndofel Vector of local number of degrees of freedom
-//! \param[in] coord Array of nodal coordinates
-//! \param[in] solidx Solid material index indicator
-//! \param[in,out] U High-order solution vector which gets limited
-//! \param[in,out] P High-order vector of primitives which gets limited
-//! \param[in] nmat Number of materials in this PDE system
-//! \details This Superbee function should be called for multimat
-// *****************************************************************************
-{
-  const auto rdof = inciter::g_inputdeck.get< tag::rdof >();
-  const auto ndof = inciter::g_inputdeck.get< tag::ndof >();
-  const auto intsharp = inciter::g_inputdeck.get< tag::multimat,
-    tag::intsharp >();
-  std::size_t ncomp = U.nprop()/rdof;
-  std::size_t nprim = P.nprop()/rdof;
-
-  auto beta_lim = 2.0;
-
-  for (std::size_t e=0; e<esuel.size()/4; ++e)
-  {
-    // If an rDG method is set up (P0P1), then, currently we compute the P1
-    // basis functions and solutions by default. This implies that P0P1 is
-    // unsupported in the p-adaptive DG (PDG). This is a workaround until we
-    // have rdofel, which is needed to distinguish between ndofs and rdofs per
-    // element for pDG.
-    std::size_t dof_el;
-    if (rdof > ndof)
-    {
-      dof_el = rdof;
-    }
-    else
-    {
-      dof_el = ndofel[e];
-    }
-
-    if (dof_el > 1)
-    {
-      // limit conserved quantities
-      auto phic = SuperbeeLimiting(U, esuel, inpoel, coord, e, ndof, rdof,
-                    dof_el, ncomp, beta_lim);
-      // limit primitive quantities
-      auto phip = SuperbeeLimiting(P, esuel, inpoel, coord, e, ndof, rdof,
-                    dof_el, nprim, beta_lim);
+    GaussQuadratureTet( ng, coordgp, wgp );
+
+    // Extract the element coordinates
+    std::array< std::array< real, 3>, 4 > coordel {{
+      {{ cx[ inpoel[4*e  ] ], cy[ inpoel[4*e  ] ], cz[ inpoel[4*e  ] ] }},
+      {{ cx[ inpoel[4*e+1] ], cy[ inpoel[4*e+1] ], cz[ inpoel[4*e+1] ] }},
+      {{ cx[ inpoel[4*e+2] ], cy[ inpoel[4*e+2] ], cz[ inpoel[4*e+2] ] }},
+      {{ cx[ inpoel[4*e+3] ], cy[ inpoel[4*e+3] ], cz[ inpoel[4*e+3] ] }}
+    }};
+
+    auto jacInv =
+            inverseJacobian( coordel[0], coordel[1], coordel[2], coordel[3] );
+
+    // Compute the derivatives of basis function for DG(P1)
+    std::array< std::vector<tk::real>, 3 > dBdx;
+    if (ndofel[e] > 1)
+      dBdx = eval_dBdx_p1( ndofel[e], jacInv );
+
+    // Gaussian quadrature
+    for (std::size_t igp=0; igp<ng; ++igp)
+    {
+      if (ndofel[e] > 4)
+        eval_dBdx_p2( igp, coordgp, jacInv, dBdx );
+
+      // If an rDG method is set up (P0P1), then, currently we compute the P1
+      // basis functions and solutions by default. This implies that P0P1 is
+      // unsupported in the p-adaptive DG (PDG).
+      std::size_t dof_el;
+      if (rdof > ndof)
+      {
+        dof_el = rdof;
+      }
+      else
+      {
+        dof_el = ndofel[e];
+      }
+
+      // Compute the basis function
+      auto B =
+        eval_basis( dof_el, coordgp[0][igp], coordgp[1][igp], coordgp[2][igp] );
+
+      auto wt = wgp[igp] * geoElem(e, 0);
+
+      auto state = evalPolynomialSol(mat_blk, intsharp, ncomp, nprim,
+        rdof, nmat, e, dof_el, inpoel, coord, geoElem,
+        {{coordgp[0][igp], coordgp[1][igp], coordgp[2][igp]}}, B, U, P);
+
+      // get bulk properties
+      tk::real rhob(0.0);
+      for (std::size_t k=0; k<nmat; ++k)
+          rhob += state[densityIdx(nmat, k)];
+
+      // get the velocity vector
+      std::array< tk::real, 3 > vel{{ state[ncomp+velocityIdx(nmat, 0)],
+                                      state[ncomp+velocityIdx(nmat, 1)],
+                                      state[ncomp+velocityIdx(nmat, 2)] }};
+
+      std::vector< tk::real > ymat(nmat, 0.0);
+      std::array< tk::real, 3 > dap{{0.0, 0.0, 0.0}};
+      for (std::size_t k=0; k<nmat; ++k)
+      {
+        ymat[k] = state[densityIdx(nmat, k)]/rhob;
+
+        std::size_t mark(3*k);
+        if (solidx[k] > 0) mark = 3*nmat+ndof+3*(solidx[k]-1);
+
+        for (std::size_t idir=0; idir<3; ++idir)
+          dap[idir] += riemannDeriv[mark+idir][e];
+      }
 
-      std::vector< tk::real > phic_p2;
-      std::vector< std::vector< tk::real > > unk, prim;<--- Unused variable: unk<--- Unused variable: prim
-      if(ndof > 1)
-        BoundPreservingLimiting(nmat, ndof, e, inpoel, coord, U, phic,
-          phic_p2);
-
-      // limits under which compression is to be performed
-      std::vector< std::size_t > matInt(nmat, 0);
-      std::vector< tk::real > alAvg(nmat, 0.0);
-      for (std::size_t k=0; k<nmat; ++k)
-        alAvg[k] = U(e, volfracDofIdx(nmat,k,rdof,0));
-      auto intInd = interfaceIndicator(nmat, alAvg, matInt);
-      if ((intsharp > 0) && intInd)
-      {
-        for (std::size_t k=0; k<nmat; ++k)
+      // compute non-conservative terms
+      std::vector< std::vector< tk::real > > ncf
+        (ncomp, std::vector<tk::real>(ndof,0.0));
+
+      for (std::size_t idir=0; idir<3; ++idir)
+        for(std::size_t idof=0; idof<ndof; ++idof)
+          ncf[momentumIdx(nmat, idir)][idof] = 0.0;
+
+      for (std::size_t k=0; k<nmat; ++k)
+      {
+        // evaluate non-conservative term for energy equation
+        std::size_t mark(3*k);
+        if (solidx[k] > 0) mark = 3*nmat+ndof+3*(solidx[k]-1);
+
+        for(std::size_t idof=0; idof<ndof; ++idof)
         {
-          if (matInt[k])
-            phic[volfracIdx(nmat,k)] = 1.0;
-        }
-      }
-      else
-      {
-        if (!g_inputdeck.get< tag::accuracy_test >())
-          consistentMultiMatLimiting_P1(nmat, rdof, e, solidx, U, P, phic,
-            phic_p2);
-      }
-
-      // apply limiter function
-      for (inciter::ncomp_t c=0; c<ncomp; ++c)
-      {
-        auto mark = c*rdof;
-        U(e, mark+1) = phic[c] * U(e, mark+1);
-        U(e, mark+2) = phic[c] * U(e, mark+2);
-        U(e, mark+3) = phic[c] * U(e, mark+3);
-      }
-      for (inciter::ncomp_t c=0; c<nprim; ++c)
-      {
-        auto mark = c*rdof;
-        P(e, mark+1) = phip[c] * P(e, mark+1);
-        P(e, mark+2) = phip[c] * P(e, mark+2);
-        P(e, mark+3) = phip[c] * P(e, mark+3);
-      }
-    }
-  }
-}
-
-void
-VertexBasedTransport_P1(
-  const std::map< std::size_t, std::vector< std::size_t > >& esup,
-  const std::vector< std::size_t >& inpoel,
-  const std::vector< std::size_t >& ndofel,
-  std::size_t nelem,
-  const tk::UnsMesh::Coords& coord,
-  tk::Fields& U )
-// *****************************************************************************
-//  Kuzmin's vertex-based limiter for transport DGP1
-//! \param[in] esup Elements surrounding points
-//! \param[in] inpoel Element connectivity
-//! \param[in] ndofel Vector of local number of degrees of freedom
-//! \param[in] nelem Number of elements
-//! \param[in] coord Array of nodal coordinates
-//! \param[in,out] U High-order solution vector which gets limited
-//! \details This vertex-based limiter function should be called for transport.
-//!   For details see: Kuzmin, D. (2010). A vertex-based hierarchical slope
-//!   limiter for p-adaptive discontinuous Galerkin methods. Journal of
-//!   computational and applied mathematics, 233(12), 3077-3085.
-// *****************************************************************************
-{
-  const auto rdof = inciter::g_inputdeck.get< tag::rdof >();
-  const auto ndof = inciter::g_inputdeck.get< tag::ndof >();
-  const auto intsharp = inciter::g_inputdeck.get< tag::transport,
-    tag::intsharp >();
-  std::size_t ncomp = U.nprop()/rdof;
-
-  for (std::size_t e=0; e<nelem; ++e)
-  {
-    // If an rDG method is set up (P0P1), then, currently we compute the P1
-    // basis functions and solutions by default. This implies that P0P1 is
-    // unsupported in the p-adaptive DG (PDG). This is a workaround until we
-    // have rdofel, which is needed to distinguish between ndofs and rdofs per
-    // element for pDG.
-    std::size_t dof_el;
-    if (rdof > ndof)
-    {
-      dof_el = rdof;
-    }
-    else
-    {
-      dof_el = ndofel[e];
-    }
-
-    if (dof_el > 1)
-    {
-      std::vector< tk::real > phi(ncomp, 1.0);
-      std::vector< std::size_t > var;
-      for (std::size_t c=0; c<ncomp; ++c) var.push_back(c);
-      // limit conserved quantities
-      VertexBasedLimiting(U, esup, inpoel, coord, e, rdof, dof_el,
-        ncomp, phi, var);
-
-      // limits under which compression is to be performed
-      std::vector< std::size_t > matInt(ncomp, 0);
-      std::vector< tk::real > alAvg(ncomp, 0.0);
-      for (std::size_t k=0; k<ncomp; ++k)
-        alAvg[k] = U(e,k*rdof);
-      auto intInd = interfaceIndicator(ncomp, alAvg, matInt);
-      if ((intsharp > 0) && intInd)
-      {
-        for (std::size_t k=0; k<ncomp; ++k)
-        {
-          if (matInt[k]) phi[k] = 1.0;
-        }
-      }
-
-      // apply limiter function
-      for (std::size_t c=0; c<ncomp; ++c)
-      {
-        auto mark = c*rdof;
-        U(e, mark+1) = phi[c] * U(e, mark+1);
-        U(e, mark+2) = phi[c] * U(e, mark+2);
-        U(e, mark+3) = phi[c] * U(e, mark+3);
-      }
-    }
-  }
-}
-
-void
-VertexBasedCompflow_P1(
-  const std::map< std::size_t, std::vector< std::size_t > >& esup,
-  const std::vector< std::size_t >& inpoel,
-  const std::vector< std::size_t >& ndofel,
-  std::size_t nelem,
-  const std::vector< inciter::EOS >& mat_blk,
-  const inciter::FaceData& fd,
-  const tk::Fields& geoFace,
-  const tk::Fields& geoElem,
-  const tk::UnsMesh::Coords& coord,
-  const tk::FluxFn& flux,
-  const std::vector< std::size_t >& solidx,
-  tk::Fields& U,
-  std::vector< std::size_t >& shockmarker )
-// *****************************************************************************
-//  Kuzmin's vertex-based limiter for single-material DGP1
-//! \param[in] esup Elements surrounding points
-//! \param[in] inpoel Element connectivity
-//! \param[in] ndofel Vector of local number of degrees of freedom
-//! \param[in] nelem Number of elements
-//! \param[in] mat_blk EOS material block
-//! \param[in] fd Face connectivity and boundary conditions object
-//! \param[in] geoFace Face geometry array
-// //! \param[in] geoElem Element geometry array
-//! \param[in] coord Array of nodal coordinates
-//! \param[in] flux Riemann flux function to use
-//! \param[in] solidx Solid material index indicator
-//! \param[in,out] U High-order solution vector which gets limited
-//! \param[in,out] shockmarker Shock detection marker array
-//! \details This vertex-based limiter function should be called for compflow.
-//!   For details see: Kuzmin, D. (2010). A vertex-based hierarchical slope
-//!   limiter for p-adaptive discontinuous Galerkin methods. Journal of
-//!   computational and applied mathematics, 233(12), 3077-3085.
-// *****************************************************************************
-{
-  const auto rdof = inciter::g_inputdeck.get< tag::rdof >();
-  const auto ndof = inciter::g_inputdeck.get< tag::ndof >();
-  std::size_t ncomp = U.nprop()/rdof;
-
-  // Null field for MarkShockCells argument
-  tk::Fields P;
-
-  if (inciter::g_inputdeck.get< tag::shock_detector_coeff >()
-    > 1e-6)
-    MarkShockCells(nelem, 1, ndof, rdof, mat_blk, ndofel,
-      inpoel, coord, fd, geoFace, geoElem, flux, solidx, U, P, shockmarker);
-
-  for (std::size_t e=0; e<nelem; ++e)
-  {
-    // If an rDG method is set up (P0P1), then, currently we compute the P1
-    // basis functions and solutions by default. This implies that P0P1 is
-    // unsupported in the p-adaptive DG (PDG). This is a workaround until we
-    // have rdofel, which is needed to distinguish between ndofs and rdofs per
-    // element for pDG.
-    std::size_t dof_el;
-    if (rdof > ndof)
-    {
-      dof_el = rdof;
-    }
-    else
-    {
-      dof_el = ndofel[e];
-    }
-
-    if (dof_el > 1 && shockmarker[e])
-    {
-      std::vector< tk::real > phi(ncomp, 1.0);
-      std::vector< std::size_t > var;
-      for (std::size_t c=0; c<ncomp; ++c) var.push_back(c);
-      // limit conserved quantities
-      VertexBasedLimiting(U, esup, inpoel, coord, e, rdof, dof_el,
-        ncomp, phi, var);
-
-      // apply limiter function
-      for (std::size_t c=0; c<ncomp; ++c)
-      {
-        auto mark = c*rdof;
-        U(e, mark+1) = phi[c] * U(e, mark+1);
-        U(e, mark+2) = phi[c] * U(e, mark+2);
-        U(e, mark+3) = phi[c] * U(e, mark+3);
-      }
-    }
-  }
-}
-
-void
-VertexBasedCompflow_P2(
-  const std::map< std::size_t, std::vector< std::size_t > >& esup,
-  const std::vector< std::size_t >& inpoel,
-  const std::vector< std::size_t >& ndofel,
-  std::size_t nelem,
-  const std::vector< inciter::EOS >& mat_blk,
-  const inciter::FaceData& fd,
-  const tk::Fields& geoFace,
-  const tk::Fields& geoElem,
-  const tk::UnsMesh::Coords& coord,
-  [[maybe_unused]] const std::vector< std::size_t >& gid,
-  [[maybe_unused]] const std::unordered_map< std::size_t, std::size_t >& bid,
-  [[maybe_unused]] const std::vector< std::vector<tk::real> >& uNodalExtrm,
-  [[maybe_unused]] const std::vector< std::vector<tk::real> >& mtInv,
-  const tk::FluxFn& flux,
-  const std::vector< std::size_t >& solidx,
-  tk::Fields& U,
-  std::vector< std::size_t >& shockmarker )
-// *****************************************************************************
-//  Kuzmin's vertex-based limiter on reference element for single-material DGP2
-//! \param[in] esup Elements surrounding points
-//! \param[in] inpoel Element connectivity
-//! \param[in] ndofel Vector of local number of degrees of freedom
-//! \param[in] nelem Number of elements
-//! \param[in] mat_blk EOS material block
-//! \param[in] fd Face connectivity and boundary conditions object
-//! \param[in] geoFace Face geometry array
-// //! \param[in] geoElem Element geometry array
-//! \param[in] coord Array of nodal coordinates
-//! \param[in] gid Local->global node id map
-//! \param[in] bid Local chare-boundary node ids (value) associated to
-//!   global node ids (key)
-//! \param[in] uNodalExtrm Chare-boundary nodal extrema for conservative
-//!   variables
-//! \param[in] mtInv Inverse of Taylor mass matrix
-//! \param[in] flux Riemann flux function to use
-//! \param[in] solidx Solid material index indicator
-//! \param[in,out] U High-order solution vector which gets limited
-//! \param[in,out] shockmarker Shock detection marker array
-//! \details This vertex-based limiter function should be called for compflow.
-//!   For details see: Kuzmin, D. (2010). A vertex-based hierarchical slope
-//!   limiter for p-adaptive discontinuous Galerkin methods. Journal of
-//!   computational and applied mathematics, 233(12), 3077-3085.
-// *****************************************************************************
-{
-  const auto rdof = inciter::g_inputdeck.get< tag::rdof >();
-  const auto ndof = inciter::g_inputdeck.get< tag::ndof >();
-  std::size_t ncomp = U.nprop()/rdof;
-
-  // Null field for MarkShockCells argument
-  tk::Fields P;
-
-  if (inciter::g_inputdeck.get< tag::shock_detector_coeff >()
-    > 1e-6)
-    MarkShockCells(nelem, 1, ndof, rdof, mat_blk, ndofel,
-      inpoel, coord, fd, geoFace, geoElem, flux, solidx, U, P, shockmarker);
-
-  for (std::size_t e=0; e<nelem; ++e)
-  {
-    // If an rDG method is set up (P0P1), then, currently we compute the P1
-    // basis functions and solutions by default. This implies that P0P1 is
-    // unsupported in the p-adaptive DG (PDG). This is a workaround until we
-    // have rdofel, which is needed to distinguish between ndofs and rdofs per
-    // element for pDG.
-    std::size_t dof_el;
-    if (rdof > ndof)
-    {
-      dof_el = rdof;
-    }
-    else
-    {
-      dof_el = ndofel[e];
-    }
+          ncf[densityIdx(nmat, k)][idof] = 0.0;
+
+          for (std::size_t idir=0; idir<3; ++idir)
+            ncf[energyIdx(nmat, k)][idof] -= vel[idir] * ( ymat[k]*dap[idir]
+                                                  - riemannDeriv[mark+idir][e] );
+        }
+
+        // Evaluate non-conservative term for volume fraction equation:
+        // Here we make an assumption that the derivative of Riemann velocity
+        // times the basis function is constant. Therefore, when P0P1/DGP1/DGP2
+        // are used for constant velocity problems, the discretization is
+        // consistent. However, for a general problem with varying velocity,
+        // there will be errors since the said derivative is not constant.
+        // A discretization that solves this issue has not been implemented yet.
+        // Nevertheless, this does not affect high-order accuracy in
+        // single material regions for problems with sharp interfaces. Since
+        // volume fractions are nearly constant in such regions, using
+        // high-order for volume fractions does not show any benefits over
+        // THINC. Therefore, for such problems, we only use FV for the volume
+        // fractions, and these non-conservative high-order terms do not need
+        // to be computed.
+        // In summary, high-order discretization for non-conservative terms in
+        // volume fraction equations is avoided for sharp interface problems.
+        if (ndof <= 4 || intsharp == 1) {
+          for(std::size_t idof=0; idof<ndof; ++idof)
+            ncf[volfracIdx(nmat, k)][idof] = state[volfracIdx(nmat, k)]
+                                           * riemannDeriv[3*nmat+idof][e];
+        } else if (intsharp == 0) {     // If DGP2 without THINC
+          // DGP2 is discretized differently than DGP1/FV to guarantee 3rd order
+          // convergence for the testcases with uniform and constant velocity.
+
+          // P0 contributions for all equations
+          for(std::size_t idof=0; idof<ndof; ++idof)
+          ncf[volfracIdx(nmat, k)][idof] = state[volfracIdx(nmat, k)]
+                                         * riemannDeriv[3*nmat][e] * B[idof];
+          // High order contributions
+          for(std::size_t idof=1; idof<ndof; ++idof)
+            for(std::size_t idir=0; idir<3; ++idir)
+            ncf[volfracIdx(nmat, k)][idof] += state[volfracIdx(nmat, k)]
+                                            * vel[idir] * dBdx[idir][idof];
+        }
+      }
+
+      updateRhsNonCons( ncomp, nmat, ndof, ndofel[e], wt, e, B, dBdx, ncf, R );
+    }
+  }
+}
+
+void
+updateRhsNonCons(
+  ncomp_t ncomp,
+  const std::size_t nmat,
+  const std::size_t ndof,
+  [[maybe_unused]] const std::size_t ndof_el,
+  const tk::real wt,
+  const std::size_t e,
+  const std::vector<tk::real>& B,
+  [[maybe_unused]] const std::array< std::vector<tk::real>, 3 >& dBdx,
+  const std::vector< std::vector< tk::real > >& ncf,
+  Fields& R )
+// *****************************************************************************
+//  Update the rhs by adding the non-conservative term integrals
+//! \param[in] ncomp Number of scalar components in this PDE system
+//! \param[in] nmat Number of materials
+//! \param[in] ndof Maximum number of degrees of freedom
+//! \param[in] ndof_el Number of degrees of freedom for local element
+//! \param[in] wt Weight of gauss quadrature point
+//! \param[in] e Element index
+//! \param[in] B Basis function evaluated at local quadrature point
+//! \param[in] dBdx Vector of basis function derivatives
+//! \param[in] ncf Vector of non-conservative terms
+//! \param[in,out] R Right-hand side vector computed
+// *****************************************************************************
+{
+  using inciter::volfracIdx;
+  using inciter::energyIdx;
+  using inciter::volfracDofIdx;
+  using inciter::energyDofIdx;
+
+  //Assert( dBdx[0].size() == ndof_el,
+  //        "Size mismatch for basis function derivatives" );
+  //Assert( dBdx[1].size() == ndof_el,
+  //        "Size mismatch for basis function derivatives" );
+  //Assert( dBdx[2].size() == ndof_el,
+  //        "Size mismatch for basis function derivatives" );
+  //Assert( ncf.size() == ncomp,
+  //        "Size mismatch for non-conservative term" );
+  Assert( ncf.size() == ncomp, "Size mismatch for non-conservative term" );
+
+  for (ncomp_t c=0; c<ncomp; ++c)
+  {
+    auto mark = c*ndof;
+    R(e, mark) += wt * ncf[c][0];
+  }
+
+  if( ndof_el > 1)
+  {
+    // Update rhs with distributions from volume fraction and energy equations
+    for (std::size_t k=0; k<nmat; ++k)
+    {
+      for(std::size_t idof = 1; idof < ndof; idof++)
+      {
+        R(e, volfracDofIdx(nmat,k,ndof,idof)) +=
+          wt * ncf[volfracIdx(nmat,k)][idof];
+        R(e, energyDofIdx(nmat,k,ndof,idof)) +=
+          wt * ncf[energyIdx(nmat,k)][idof] * B[idof];
+      }
+    }
+  }
+}
+
+std::vector< tk::real >
+nonConservativeIntFV(
+  std::size_t nmat,
+  const std::size_t rdof,
+  const std::size_t e,
+  const std::array< tk::real, 3 >& fn,
+  const Fields& U,
+  const Fields& P,
+  const std::vector< tk::real >& var_riemann )
+// *****************************************************************************
+//  Compute integrals of non-conservative terms for multi-material FV
+//! \details This is called for multi-material FV, computing integrals of
+//!   terms in the volume fraction and energy equations, which do not exist in
+//!   the single-material flow formulation (for `CompFlow`). For further
+//!   details see Pelanti, M., & Shyue, K. M. (2019). A numerical model for
+//!   multiphase liquid–vapor–gas flows with interfaces and cavitation.
+//!   International Journal of Multiphase Flow, 113, 208-230.
+//! \param[in] nmat Number of materials in this PDE system
+//! \param[in] rdof Maximum number of reconstructed degrees of freedom
+//! \param[in] e Element for which contribution is to be calculated
+//! \param[in] fn Face normal
+//! \param[in] U Solution vector at recent time step
+//! \param[in] P Vector of primitive quantities at recent time step
+//! \param[in] var_riemann Riemann-values of partial-pressures and velocities
+//!   computed from the Riemann solver for use in the non-conservative terms
+// *****************************************************************************
+{
+  using inciter::volfracIdx;
+  using inciter::densityIdx;
+  using inciter::momentumIdx;
+  using inciter::energyIdx;
+  using inciter::velocityIdx;
+  using inciter::volfracDofIdx;
+  using inciter::densityDofIdx;
+  using inciter::velocityDofIdx;
+
+  auto ncomp = U.nprop()/rdof;
+
+  // get bulk properties
+  tk::real rhob(0.0), p_face(0.0);
+  for (std::size_t k=0; k<nmat; ++k)
+  {
+    rhob += U(e, densityDofIdx(nmat,k,rdof,0));
+    p_face += var_riemann[k];
+  }
+
+  std::array< tk::real, 3 > vel{{ P(e, velocityDofIdx(nmat,0,rdof,0)),
+                                  P(e, velocityDofIdx(nmat,1,rdof,0)),
+                                  P(e, velocityDofIdx(nmat,2,rdof,0)) }};
+
+  // compute non-conservative terms
+  std::vector< tk::real > ncf(ncomp, 0.0);
+  std::vector< tk::real > ymat(nmat, 0.0);
+  for (std::size_t k=0; k<nmat; ++k)
+  {
+    ymat[k] = U(e, densityDofIdx(nmat,k,rdof,0))/rhob;
+
+    // evaluate non-conservative term for energy equation
+    for (std::size_t idir=0; idir<3; ++idir)
+      ncf[energyIdx(nmat, k)] -= vel[idir] * ( ymat[k]*p_face*fn[idir]
+                                            - var_riemann[k]*fn[idir] );
+
+    // evaluate non-conservative term for volume fraction equation
+    ncf[volfracIdx(nmat, k)] = U(e, volfracDofIdx(nmat,k,rdof,0))
+      * var_riemann[nmat];
+  }
+
+  return ncf;
+}
+
+void
+pressureRelaxationInt( std::size_t nmat,
+                       const std::vector< inciter::EOS >& mat_blk,
+                       const std::size_t ndof,
+                       const std::size_t rdof,
+                       const std::size_t nelem,
+                       const std::vector< std::size_t >& inpoel,
+                       const UnsMesh::Coords& coord,
+                       const Fields& geoElem,
+                       const Fields& U,
+                       const Fields& P,
+                       const std::vector< std::size_t >& ndofel,
+                       const tk::real ct,
+                       Fields& R,
+                       int intsharp )
+// *****************************************************************************
+//  Compute volume integrals of pressure relaxation terms in multi-material DG
+//! \details This is called for multi-material DG to compute volume integrals of
+//!   finite pressure relaxation terms in the volume fraction and energy
+//!   equations, which do not exist in the single-material flow formulation (for
+//!   `CompFlow` DG). For further details see Dobrev, V. A., Kolev, T. V.,
+//!   Rieben, R. N., & Tomov, V. Z. (2016). Multi‐material closure model for
+//!   high‐order finite element Lagrangian hydrodynamics. International Journal
+//!   for Numerical Methods in Fluids, 82(10), 689-706.
+//! \param[in] nmat Number of materials in this PDE system
+//! \param[in] mat_blk EOS material block
+//! \param[in] ndof Maximum number of degrees of freedom
+//! \param[in] rdof Maximum number of reconstructed degrees of freedom
+//! \param[in] nelem Total number of elements
+//! \param[in] inpoel Element-node connectivity
+//! \param[in] coord Array of nodal coordinates
+//! \param[in] geoElem Element geometry array
+//! \param[in] U Solution vector at recent time step
+//! \param[in] P Vector of primitive quantities at recent time step
+//! \param[in] ndofel Vector of local number of degrees of freedome
+//! \param[in] ct Pressure relaxation time-scale for this system
+//! \param[in,out] R Right-hand side vector added to
+//! \param[in] intsharp Interface reconstruction indicator
+// *****************************************************************************
+{
+  using inciter::volfracIdx;
+  using inciter::densityIdx;
+  using inciter::momentumIdx;
+  using inciter::energyIdx;
+  using inciter::pressureIdx;
+  using inciter::velocityIdx;
+  using inciter::deformIdx;
+
+  const auto& solidx =
+    inciter::g_inputdeck.get< tag::matidxmap, tag::solidx >();
+
+  auto ncomp = U.nprop()/rdof;
+  auto nprim = P.nprop()/rdof;
+
+  // compute volume integrals
+  for (std::size_t e=0; e<nelem; ++e)
+  {
+    auto dx = geoElem(e,4)/2.0;
+    auto ng = NGvol(ndofel[e]);
+
+    // arrays for quadrature points
+    std::array< std::vector< real >, 3 > coordgp;
+    std::vector< real > wgp;
+
+    coordgp[0].resize( ng );
+    coordgp[1].resize( ng );
+    coordgp[2].resize( ng );
+    wgp.resize( ng );
+
+    GaussQuadratureTet( ng, coordgp, wgp );
+
+    // Compute the derivatives of basis function for DG(P1)
+    std::array< std::vector<real>, 3 > dBdx;
+
+    // Gaussian quadrature
+    for (std::size_t igp=0; igp<ng; ++igp)
+    {
+      // If an rDG method is set up (P0P1), then, currently we compute the P1
+      // basis functions and solutions by default. This implies that P0P1 is
+      // unsupported in the p-adaptive DG (PDG).
+      std::size_t dof_el;
+      if (rdof > ndof)
+      {
+        dof_el = rdof;
+      }
+      else
+      {
+        dof_el = ndofel[e];
+      }
 
-    if (dof_el > 1 && shockmarker[e])
-    {
-      // The vector of limiting coefficients for P1 and P2 coefficients
-      std::vector< tk::real > phic_p1(ncomp, 1.0);
-
-      // Removing 3rd order DOFs if discontinuity is detected, and applying
-      // limiting to the 2nd order/P1 solution
-      for (std::size_t c=0; c<ncomp; ++c) {
-        for(std::size_t idof = 4; idof < rdof; idof++) {
-          auto mark = c * rdof + idof;
-          U(e, mark) = 0.0;
-        }
-      }
-
-      // Obtain limiting coefficient for P1 coefficients
-      std::vector< std::size_t > var;
-      for (std::size_t c=0; c<ncomp; ++c) var.push_back(c);
-      VertexBasedLimiting(U, esup, inpoel, coord, e, rdof, dof_el,
-        ncomp, phic_p1, var);
-
-      // apply limiter function to the solution with Taylor basis
-      for (std::size_t c=0; c<ncomp; ++c) {
-        auto mark = c * rdof;
-        for(std::size_t idof=1; idof<4; idof++)
-          U(e, mark+idof) = phic_p1[c] * U(e, mark+idof);
-      }
-    }
-  }
-}
-
-void
-VertexBasedMultiMat_P1(
-  const std::map< std::size_t, std::vector< std::size_t > >& esup,
-  const std::vector< std::size_t >& inpoel,
-  const std::vector< std::size_t >& ndofel,
-  std::size_t nelem,
-  const std::vector< inciter::EOS >& mat_blk,
-  const inciter::FaceData& fd,
-  const tk::Fields& geoFace,
-  const tk::Fields& geoElem,
-  const tk::UnsMesh::Coords& coord,
-  const tk::FluxFn& flux,
-  const std::vector< std::size_t >& solidx,
-  tk::Fields& U,
-  tk::Fields& P,
-  std::size_t nmat,
-  std::vector< std::size_t >& shockmarker )
-// *****************************************************************************
-//  Kuzmin's vertex-based limiter for multi-material DGP1
-//! \param[in] esup Elements surrounding points
-//! \param[in] inpoel Element connectivity
-//! \param[in] ndofel Vector of local number of degrees of freedom
-//! \param[in] nelem Number of elements
-//! \param[in] mat_blk EOS material block
-//! \param[in] fd Face connectivity and boundary conditions object
-//! \param[in] geoFace Face geometry array
-// //! \param[in] geoElem Element geometry array
-//! \param[in] coord Array of nodal coordinates
-//! \param[in] flux Riemann flux function to use
-//! \param[in] solidx Solid material index indicator
-//! \param[in,out] U High-order solution vector which gets limited
-//! \param[in,out] P High-order vector of primitives which gets limited
-//! \param[in] nmat Number of materials in this PDE system
-//! \param[in,out] shockmarker Shock detection marker array
-//! \details This vertex-based limiter function should be called for multimat.
-//!   For details see: Kuzmin, D. (2010). A vertex-based hierarchical slope
-//!   limiter for p-adaptive discontinuous Galerkin methods. Journal of
-//!   computational and applied mathematics, 233(12), 3077-3085.
-// *****************************************************************************
-{
-  const auto rdof = inciter::g_inputdeck.get< tag::rdof >();
-  const auto ndof = inciter::g_inputdeck.get< tag::ndof >();
-  const auto intsharp = inciter::g_inputdeck.get< tag::multimat,
-    tag::intsharp >();
-  std::size_t ncomp = U.nprop()/rdof;
-  std::size_t nprim = P.nprop()/rdof;
-
-  // Evaluate the interface condition and mark the shock cells
-  if (inciter::g_inputdeck.get< tag::shock_detector_coeff >()
-    > 1e-6 && ndof > 1)
-    MarkShockCells(nelem, nmat, ndof, rdof, mat_blk, ndofel,
-      inpoel, coord, fd, geoFace, geoElem, flux, solidx, U, P, shockmarker);
-
-  for (std::size_t e=0; e<nelem; ++e)
-  {
-    // If an rDG method is set up (P0P1), then, currently we compute the P1
-    // basis functions and solutions by default. This implies that P0P1 is
-    // unsupported in the p-adaptive DG (PDG). This is a workaround until we
-    // have rdofel, which is needed to distinguish between ndofs and rdofs per
-    // element for pDG.
-    std::size_t dof_el;
-    if (rdof > ndof)
-    {
-      dof_el = rdof;
-    }
-    else
-    {
-      dof_el = ndofel[e];
-    }
-
-    if (dof_el > 1)
-    {
-      std::vector< tk::real > phic(ncomp, 1.0);
-      std::vector< tk::real > phip(nprim, 1.0);
-      if(shockmarker[e]) {
-        // When shockmarker is 1, there is discontinuity within the element.
-        // Hence, the vertex-based limiter will be applied.
-
-        // limit conserved quantities
-        std::vector< std::size_t > varc;
-        for (std::size_t c=0; c<ncomp; ++c) varc.push_back(c);
-        VertexBasedLimiting(U, esup, inpoel, coord, e, rdof, dof_el,
-          ncomp, phic, varc);
-        // limit primitive quantities
-        std::vector< std::size_t > varp;
-        for (std::size_t c=0; c<nprim; ++c) varp.push_back(c);
-        VertexBasedLimiting(P, esup, inpoel, coord, e, rdof, dof_el,
-          nprim, phip, varp);
-      } else {
-        // When shockmarker is 0, the volume fraction, density and energy
-        // of minor material will still be limited to ensure a stable solution.
-        std::vector< std::size_t > vars;
-        for (std::size_t k=0; k<nmat; ++k) vars.push_back(volfracIdx(nmat,k));
-        VertexBasedLimiting(U, esup, inpoel, coord, e, rdof, dof_el,
-          ncomp, phic, vars);
-
-        for(std::size_t k=0; k<nmat; ++k) {
-          if(U(e, volfracDofIdx(nmat,k,rdof,0)) < 1e-4) {
-            // limit the density and energy of minor materials
-            vars.clear();
-            vars.push_back(densityIdx(nmat, k));
-            vars.push_back(energyIdx(nmat, k));
-            if (solidx[k] > 0) {
-              for (std::size_t i=0; i<3; ++i)
-                for (std::size_t j=0; j<3; ++j)
-                  vars.push_back(deformIdx(nmat, solidx[k], i, j));
-            }
-            VertexBasedLimiting(U, esup, inpoel, coord, e, rdof, dof_el,
-              ncomp, phic, vars);
-
-            // limit the pressure of minor materials
-            VertexBasedLimiting(P, esup, inpoel, coord, e, rdof, dof_el,
-              nprim, phip, std::vector< std::size_t >{pressureIdx(nmat, k)});
-          }
-        }
-      }
-
-      std::vector< tk::real > phic_p2, phip_p2;
+      // Compute the basis function
+      auto B =
+        eval_basis( dof_el, coordgp[0][igp], coordgp[1][igp], coordgp[2][igp] );
+
+      auto wt = wgp[igp] * geoElem(e, 0);
+
+      auto state = evalPolynomialSol(mat_blk, intsharp, ncomp, nprim,
+        rdof, nmat, e, dof_el, inpoel, coord, geoElem,
+        {{coordgp[0][igp], coordgp[1][igp], coordgp[2][igp]}}, B, U, P);
+
+      // get bulk properties
+      real rhob(0.0);
+      for (std::size_t k=0; k<nmat; ++k)
+        rhob += state[densityIdx(nmat, k)];
+
+      // get pressures and bulk modulii
+      real pb(0.0), nume(0.0), deno(0.0), trelax(0.0);
+      std::vector< real > apmat(nmat, 0.0), kmat(nmat, 0.0);
+      for (std::size_t k=0; k<nmat; ++k)
+      {
+        real arhomat = state[densityIdx(nmat, k)];
+        real alphamat = state[volfracIdx(nmat, k)];
+        apmat[k] = state[ncomp+pressureIdx(nmat, k)];
+        real amat = 0.0;
+        if (solidx[k] > 0)
+        {
+          std::array< std::array< tk::real, 3 >, 3 > g;
+          for (std::size_t i=0; i<3; ++i)
+            for (std::size_t j=0; j<3; ++j)
+              g[i][j] = state[deformIdx(nmat,solidx[k],i,j)];
+          auto grot = tk::rotateTensor(g, {{1.0, 0.0, 0.0}});
+          amat = mat_blk[k].compute< inciter::EOS::soundspeed >( arhomat,
+            apmat[k], alphamat, k, grot);
+          grot = tk::rotateTensor(g, {{0.0, 1.0, 0.0}});
+          amat = std::max(amat, mat_blk[k].compute< inciter::EOS::soundspeed >(
+            arhomat, apmat[k], alphamat, k, grot));
+          grot = tk::rotateTensor(g, {{0.0, 0.0, 1.0}});
+          amat = std::max(amat, mat_blk[k].compute< inciter::EOS::soundspeed >(
+            arhomat, apmat[k], alphamat, k, grot));
+        }
+        else
+        {
+          amat = mat_blk[k].compute< inciter::EOS::soundspeed >( arhomat,
+            apmat[k], alphamat, k );
+        }
+        kmat[k] = arhomat * amat * amat;
+        pb += apmat[k];
+
+        // relaxation parameters
+        trelax = std::max(trelax, ct*dx/amat);
+        nume += alphamat * apmat[k] / kmat[k];
+        deno += alphamat * alphamat / kmat[k];
+      }
+      auto p_relax = nume/deno;
+
+      // compute pressure relaxation terms
+      std::vector< real > s_prelax(ncomp, 0.0);
+      for (std::size_t k=0; k<nmat; ++k)
+      {
+        auto s_alpha = (apmat[k]-p_relax*state[volfracIdx(nmat, k)])
+          * (state[volfracIdx(nmat, k)]/kmat[k]) / trelax;
+        s_prelax[volfracIdx(nmat, k)] = s_alpha;
+        s_prelax[energyIdx(nmat, k)] = - pb*s_alpha;
+      }
+
+      updateRhsPre( ncomp, ndof, dof_el, wt, e, B, s_prelax, R );
+    }
+  }
+}
+
+void
+updateRhsPre(
+  ncomp_t ncomp,
+  const std::size_t ndof,
+  [[maybe_unused]] const std::size_t ndof_el,
+  const tk::real wt,
+  const std::size_t e,
+  const std::vector< tk::real >& B,
+  std::vector< tk::real >& ncf,
+  Fields& R )
+// *****************************************************************************
+//  Update the rhs by adding the pressure relaxation integrals
+//! \param[in] ncomp Number of scalar components in this PDE system
+//! \param[in] ndof Maximum number of degrees of freedom
+//! \param[in] ndof_el Number of degrees of freedom for local element
+//! \param[in] wt Weight of gauss quadrature point
+//! \param[in] e Element index
+//! \param[in] B Basis function evaluated at local quadrature point
+//! \param[in] ncf Vector of non-conservative terms
+//! \param[in,out] R Right-hand side vector computed
+// *****************************************************************************
+{
+  //Assert( dBdx[0].size() == ndof_el,
+  //        "Size mismatch for basis function derivatives" );
+  //Assert( dBdx[1].size() == ndof_el,
+  //        "Size mismatch for basis function derivatives" );
+  //Assert( dBdx[2].size() == ndof_el,
+  //        "Size mismatch for basis function derivatives" );
+  //Assert( ncf.size() == ncomp,
+  //        "Size mismatch for non-conservative term" );
+  Assert( ncf.size() == ncomp, "Size mismatch for non-conservative term" );
+
+  for (ncomp_t c=0; c<ncomp; ++c)
+  {
+    auto mark = c*ndof;
+    for(std::size_t idof = 0; idof < ndof; idof++)
+      R(e, mark+idof) += wt * ncf[c] * B[idof];
+  }
+}
+
+void
+pressureRelaxationIntFV(
+  std::size_t nmat,
+  const std::vector< inciter::EOS >& mat_blk,
+  const std::size_t rdof,
+  const std::size_t nelem,
+  const std::vector< std::size_t >& inpoel,
+  const UnsMesh::Coords& coord,
+  const Fields& geoElem,
+  const Fields& U,
+  const Fields& P,
+  const tk::real ct,
+  Fields& R )<--- Parameter 'R' can be declared with const
+// *****************************************************************************
+//  Compute volume integrals of pressure relaxation terms in multi-material FV
+//! \details This is called for multi-material FV to compute volume integrals of
+//!   finite pressure relaxation terms in the volume fraction and energy
+//!   equations, which do not exist in the single-material flow formulation (for
+//!   `CompFlow`). For further details see Dobrev, V. A., Kolev, T. V.,
+//!   Rieben, R. N., & Tomov, V. Z. (2016). Multi‐material closure model for
+//!   high‐order finite element Lagrangian hydrodynamics. International Journal
+//!   for Numerical Methods in Fluids, 82(10), 689-706.
+//! \param[in] nmat Number of materials in this PDE system
+//! \param[in] mat_blk EOS material block
+//! \param[in] rdof Maximum number of reconstructed degrees of freedom
+//! \param[in] nelem Total number of elements
+//! \param[in] geoElem Element geometry array
+//! \param[in] U Solution vector at recent time step
+//! \param[in] P Vector of primitive quantities at recent time step
+//! \param[in] ct Pressure relaxation time-scale for this system
+//! \param[in,out] R Right-hand side vector added to
+// *****************************************************************************
+{
+  using inciter::volfracIdx;
+  using inciter::energyIdx;
+  using inciter::pressureIdx;
+  using inciter::velocityIdx;
+  using inciter::densityIdx;
 
-      PositivityLimitingMultiMat(nmat, mat_blk, rdof, dof_el, e, inpoel,
-        coord, U, P, phic, phic_p2, phip, phip_p2);
+  auto ncomp = U.nprop()/rdof;
+  auto nprim = P.nprop()/rdof;
 
-      // limits under which compression is to be performed
-      std::vector< std::size_t > matInt(nmat, 0);
-      std::vector< tk::real > alAvg(nmat, 0.0);
-      for (std::size_t k=0; k<nmat; ++k)
-        alAvg[k] = U(e, volfracDofIdx(nmat,k,rdof,0));
-      auto intInd = interfaceIndicator(nmat, alAvg, matInt);
-      if ((intsharp > 0) && intInd) {
-        for (std::size_t k=0; k<nmat; ++k) {
-          if (matInt[k]) {
-            phic[volfracIdx(nmat,k)] = 1.0;
-          }
-        }
-      }
-      else {
-        if(nmat > 1)
-          BoundPreservingLimiting(nmat, ndof, e, inpoel, coord, U, phic,
-            phic_p2);
+  // compute volume integrals
+  for (std::size_t e=0; e<nelem; ++e)
+  {
+    auto dx = geoElem(e,4)/2.0;
+
+    // Compute the basis function
+    std::vector< tk::real > B(rdof, 0.0);
+    B[0] = 1.0;
+
+    auto state = evalPolynomialSol(mat_blk, 0, ncomp, nprim,
+      rdof, nmat, e, rdof, inpoel, coord, geoElem,
+      {{0.25, 0.25, 0.25}}, B, U, P);
+
+    // get bulk properties
+    real rhob(0.0);
+    for (std::size_t k=0; k<nmat; ++k)
+      rhob += state[densityIdx(nmat, k)];
 
-        if (!g_inputdeck.get< tag::accuracy_test >())
-          consistentMultiMatLimiting_P1(nmat, rdof, e, solidx, U, P, phic,
-            phic_p2);
-      }
-
-      // apply limiter function
-      for (std::size_t c=0; c<ncomp; ++c)
-      {
-        auto mark = c*rdof;
-        U(e, mark+1) = phic[c] * U(e, mark+1);
-        U(e, mark+2) = phic[c] * U(e, mark+2);
-        U(e, mark+3) = phic[c] * U(e, mark+3);
-      }
-      for (std::size_t c=0; c<nprim; ++c)
-      {
-        auto mark = c*rdof;
-        P(e, mark+1) = phip[c] * P(e, mark+1);
-        P(e, mark+2) = phip[c] * P(e, mark+2);
-        P(e, mark+3) = phip[c] * P(e, mark+3);
-      }
-    }
-  }
-}
-
-void
-VertexBasedMultiMat_P2(
-  const std::map< std::size_t, std::vector< std::size_t > >& esup,
-  const std::vector< std::size_t >& inpoel,
-  const std::vector< std::size_t >& ndofel,
-  std::size_t nelem,
-  const std::vector< inciter::EOS >& mat_blk,
-  const inciter::FaceData& fd,
-  const tk::Fields& geoFace,
-  const tk::Fields& geoElem,
-  const tk::UnsMesh::Coords& coord,
-  [[maybe_unused]] const std::vector< std::size_t >& gid,
-  [[maybe_unused]] const std::unordered_map< std::size_t, std::size_t >& bid,
-  [[maybe_unused]] const std::vector< std::vector<tk::real> >& uNodalExtrm,
-  [[maybe_unused]] const std::vector< std::vector<tk::real> >& pNodalExtrm,
-  [[maybe_unused]] const std::vector< std::vector<tk::real> >& mtInv,
-  const tk::FluxFn& flux,
-  const std::vector< std::size_t >& solidx,
-  tk::Fields& U,
-  tk::Fields& P,
-  std::size_t nmat,
-  std::vector< std::size_t >& shockmarker )
-// *****************************************************************************
-//  Kuzmin's vertex-based limiter for multi-material DGP2
-//! \param[in] esup Elements surrounding points
-//! \param[in] inpoel Element connectivity
-//! \param[in] ndofel Vector of local number of degrees of freedom
-//! \param[in] nelem Number of elements
-//! \param[in] mat_blk EOS material block
-//! \param[in] fd Face connectivity and boundary conditions object
-//! \param[in] geoFace Face geometry array
-// //! \param[in] geoElem Element geometry array
-//! \param[in] coord Array of nodal coordinates
-//! \param[in] gid Local->global node id map
-//! \param[in] bid Local chare-boundary node ids (value) associated to
-//!   global node ids (key)
-//! \param[in] uNodalExtrm Chare-boundary nodal extrema for conservative
-//!   variables
-//! \param[in] pNodalExtrm Chare-boundary nodal extrema for primitive
-//!   variables
-//! \param[in] mtInv Inverse of Taylor mass matrix
-//! \param[in] flux Riemann flux function to use
-//! \param[in] solidx Solid material index indicator
-//! \param[in,out] U High-order solution vector which gets limited
-//! \param[in,out] P High-order vector of primitives which gets limited
-//! \param[in] nmat Number of materials in this PDE system
-//! \param[in,out] shockmarker Shock detection marker array
-//! \details This vertex-based limiter function should be called for multimat.
-//!   For details see: Kuzmin, D. (2010). A vertex-based hierarchical slope
-//!   limiter for p-adaptive discontinuous Galerkin methods. Journal of
-//!   computational and applied mathematics, 233(12), 3077-3085.
-// *****************************************************************************
-{
-  const auto rdof = inciter::g_inputdeck.get< tag::rdof >();
-  const auto ndof = inciter::g_inputdeck.get< tag::ndof >();
-  const auto intsharp = inciter::g_inputdeck.get< tag::multimat,
-    tag::intsharp >();
-  std::size_t ncomp = U.nprop()/rdof;
-  std::size_t nprim = P.nprop()/rdof;
+    // get pressures and bulk modulii
+    real pb(0.0), nume(0.0), deno(0.0), trelax(0.0);
+    std::vector< real > apmat(nmat, 0.0), kmat(nmat, 0.0);
+    for (std::size_t k=0; k<nmat; ++k)
+    {
+      real arhomat = state[densityIdx(nmat, k)];
+      real alphamat = state[volfracIdx(nmat, k)];
+      apmat[k] = state[ncomp+pressureIdx(nmat, k)];
+      real amat = mat_blk[k].compute< inciter::EOS::soundspeed >( arhomat,
+        apmat[k], alphamat, k );
+      kmat[k] = arhomat * amat * amat;
+      pb += apmat[k];
+
+      // relaxation parameters
+      trelax = std::max(trelax, ct*dx/amat);
+      nume += alphamat * apmat[k] / kmat[k];
+      deno += alphamat * alphamat / kmat[k];
+    }
+    auto p_relax = nume/deno;
+
+    // compute pressure relaxation terms
+    std::vector< real > s_prelax(ncomp, 0.0);
+
+    // terms to ensure only existing materials are relaxed
+    real e_leftover(0), vf_leftover(0);
+    auto almax(0.0);
+    std::size_t kmax = 0;
+    for (std::size_t k=0; k<nmat; ++k)
+    {
+      real alphamat = state[volfracIdx(nmat, k)];
+      auto s_alpha = (apmat[k]-p_relax*state[volfracIdx(nmat, k)])
+        * (state[volfracIdx(nmat, k)]/kmat[k]) / trelax;
+
+      // only perform prelax on existing quantities
+      if (inciter::matExists(state[volfracIdx(nmat,k)])) {
+        s_prelax[volfracIdx(nmat, k)] = s_alpha;
+        s_prelax[energyIdx(nmat, k)] = - pb*s_alpha;
+      } else {
+        vf_leftover += s_alpha;
+        e_leftover  += - pb*s_alpha;
+      }
+      // get material that takes up most volume
+      if (alphamat > almax)
+      {
+        almax = alphamat;
+        kmax = k;
+      }
+    }
+
+    // add leftovers of non-existent mat to mat with most volume
+    s_prelax[volfracIdx(nmat, kmax)] += vf_leftover;
+    s_prelax[energyIdx(nmat, kmax)] += e_leftover;
+
+    for (ncomp_t c=0; c<ncomp; ++c)
+    {
+      R(e, c) += geoElem(e,0) * s_prelax[c];
+    }
+  }
+}
+
+std::vector< std::vector< tk::real > >
+solvevriem( std::size_t nelem,
+            const std::vector< std::vector< tk::real > >& vriem,
+            const std::vector< std::vector< tk::real > >& riemannLoc )
+// *****************************************************************************
+//  Solve the reconstruct velocity used for volume fraction equation by
+//  Least square method
+//! \param[in] nelem Numer of elements
+//! \param[in,out] vriem Vector of the riemann velocity
+//! \param[in,out] riemannLoc Vector of coordinates where Riemann velocity data
+//!   is available
+//! \return Vector of Riemann velocity polynomial solution
+// *****************************************************************************
+{
+  std::vector< std::vector< tk::real > >
+    vriempoly( nelem, std::vector<tk::real>(12,0.0) );
+
+  for (std::size_t e=0; e<nelem; ++e)
+  {
+    // Use the normal method to construct the linear system A^T * A * x = u
+    auto numgp = riemannLoc[e].size()/3;
+    std::vector< std::vector< tk::real > > A(numgp,
+                                             std::vector<tk::real>(4, 1.0));
 
-  // Evaluate the interface condition and mark the shock cells
-  if (inciter::g_inputdeck.get< tag::shock_detector_coeff >()
-    > 1e-6)
-    MarkShockCells(nelem, nmat, ndof, rdof, mat_blk, ndofel,
-      inpoel, coord, fd, geoFace, geoElem, flux, solidx, U, P, shockmarker);
-
-  for (std::size_t e=0; e<nelem; ++e)
-  {
-    // If an rDG method is set up (P0P1), then, currently we compute the P1
-    // basis functions and solutions by default. This implies that P0P1 is
-    // unsupported in the p-adaptive DG (PDG). This is a workaround until we
-    // have rdofel, which is needed to distinguish between ndofs and rdofs per
-    // element for pDG.
-    std::size_t dof_el;
-    if (rdof > ndof)
-    {
-      dof_el = rdof;
-    }
-    else
-    {
-      dof_el = ndofel[e];
-    }
-
-    if (dof_el > 1)
-    {
-      // The vector of limiting coefficients for P1
-      std::vector< tk::real > phic_p1(ncomp, 1.0), phic_p2(ncomp, 1.0);
-      std::vector< tk::real > phip_p1(nprim, 1.0), phip_p2(nprim, 1.0);
-
-      if(shockmarker[e]) {
-        // Removing 3rd order DOFs if discontinuity is detected, and applying
-        // limiting to the 2nd order/P1 solution
-        for (std::size_t c=0; c<ncomp; ++c) {
-          auto mark = c * rdof;
-          for(std::size_t idof = 4; idof < rdof; idof++)
-            U(e, mark+idof) = 0.0;
-        }
-        for (std::size_t c=0; c<nprim; ++c) {
-          auto mark = c * rdof;
-          for(std::size_t idof = 4; idof < rdof; idof++)
-            P(e, mark+idof) = 0.0;
-        }
-
-        // Obtain limiter coefficient for P1 conserved quantities
-        std::vector< std::size_t > varc;
-        for (std::size_t c=0; c<ncomp; ++c) varc.push_back(c);
-        VertexBasedLimiting(U, esup, inpoel, coord, e, rdof, dof_el,
-          ncomp, phic_p1, varc);
-        // Obtain limiter coefficient for P1 primitive quantities
-        std::vector< std::size_t > varp;
-        for (std::size_t c=0; c<nprim; ++c) varp.push_back(c);
-        VertexBasedLimiting(P, esup, inpoel, coord, e, rdof, dof_el,
-          nprim, phip_p1, varp);
-      } else {
-        // When shockmarker is 0, the volume fraction will still be limited to
-        // ensure a stable solution. Since the limiting strategy for third order
-        // solution will downgrade the accuracy to second order, the density,
-        // energy and pressure of minor material will not be limited.
-        std::vector< std::size_t > vars;
-        for (std::size_t k=0; k<nmat; ++k) vars.push_back(volfracIdx(nmat,k));
-        VertexBasedLimiting(U, esup, inpoel, coord, e, rdof, dof_el,
-          ncomp, phic_p1, vars);
-
-        //for(std::size_t k=0; k<nmat; ++k) {
-        //  if(U(e, volfracDofIdx(nmat,k,rdof,0)) < 1e-4) {
-        //    // limit the density of minor materials
-        //    VertexBasedLimiting(unk, U, esup, inpoel, coord, e, rdof, dof_el,
-        //      ncomp, phic_p1, std::vector< std::size_t >{densityIdx(nmat,k)});
-
-        //    // limit the pressure of minor materials
-        //    VertexBasedLimiting(prim, P, esup, inpoel, coord, e, rdof, dof_el,
-        //      nprim, phip_p1, std::vector< std::size_t >{pressureIdx(nmat,k)});
-        //  }
-        //}
-      }
-
-      PositivityLimitingMultiMat(nmat, mat_blk, ndof, dof_el, e, inpoel,
-          coord, U, P, phic_p1, phic_p2, phip_p1, phic_p2);
-
-      // limits under which compression is to be performed
-      std::vector< std::size_t > matInt(nmat, 0);
-      std::vector< tk::real > alAvg(nmat, 0.0);
-      for (std::size_t k=0; k<nmat; ++k)
-        alAvg[k] = U(e, volfracDofIdx(nmat,k,rdof,0));
-      auto intInd = interfaceIndicator(nmat, alAvg, matInt);
-      if ((intsharp > 0) && intInd) {
-        for (std::size_t k=0; k<nmat; ++k) {
-          if (matInt[k]) {
-            phic_p1[volfracIdx(nmat,k)] = 1.0;
-          }
-        }
-      }
-      else {
-        if(nmat > 1)
-          BoundPreservingLimiting(nmat, ndof, e, inpoel, coord, U,
-            phic_p1, phic_p2);
-
-        if (!g_inputdeck.get< tag::accuracy_test >())
-          consistentMultiMatLimiting_P1(nmat, rdof, e, solidx, U, P, phic_p1,
-            phic_p2);
-      }
-
-      // apply limiing coefficient
-      for (std::size_t c=0; c<ncomp; ++c)
-      {
-        auto mark = c * rdof;
-        for(std::size_t idof=1; idof<4; idof++)
-          U(e, mark+idof) = phic_p1[c] * U(e, mark+idof);
-        for(std::size_t idof=4; idof<rdof; idof++)
-          U(e, mark+idof) = phic_p2[c] * U(e, mark+idof);
-      }
-      for (std::size_t c=0; c<nprim; ++c)
-      {
-        auto mark = c * rdof;
-        for(std::size_t idof=1; idof<4; idof++)
-          P(e, mark+idof) = phip_p1[c] * P(e, mark+idof);
-        for(std::size_t idof=4; idof<rdof; idof++)
-          P(e, mark+idof) = phip_p2[c] * P(e, mark+idof);
-      }
-    }
-  }
-}
+    for(std::size_t k = 0; k < numgp; k++)
+    {
+      auto mark = k * 3;
+      A[k][1] = riemannLoc[e][mark];
+      A[k][2] = riemannLoc[e][mark+1];
+      A[k][3] = riemannLoc[e][mark+2];
+    }
+
+    for(std::size_t idir = 0; idir < 3; idir++)
+    {
+      double AA_T[4*4], u[4];
+
+      for(std::size_t i = 0; i < 4; i++)
+        for(std::size_t j = 0; j < 4; j++)
+        {
+          auto id = 4 * i + j;
+          AA_T[id] = 0;
+          for(std::size_t k = 0; k < numgp; k++)
+            AA_T[id] += A[k][i] * A[k][j];
+        }
+
+      std::vector<tk::real> vel(numgp, 1.0);
+      for(std::size_t k = 0; k < numgp; k++)
+      {
+        auto mark = k * 3 + idir;
+        vel[k] = vriem[e][mark];
+      }
+      for(std::size_t k = 0; k < 4; k++)
+      {
+        u[k] = 0;
+        for(std::size_t i = 0; i < numgp; i++)
+          u[k] += A[i][k] * vel[i];
+      }
+ 
+      lapack_int IPIV[4];
+      #ifndef NDEBUG
+      lapack_int info =
+      #endif
+        LAPACKE_dsysv( LAPACK_ROW_MAJOR, 'U', 4, 1, AA_T, 4, IPIV, u, 1 );
+      Assert( info == 0, "Error in linear system solver" );
+
+      auto idirmark = idir * 4;
+      for(std::size_t k = 0; k < 4; k++)
+        vriempoly[e][idirmark+k] = u[k];
+    }
+  }
+  return vriempoly;
+}
+
+void evaluRiemann( ncomp_t ncomp,
+                   const int e_left,
+                   const int e_right,
+                   const std::size_t nmat,
+                   const std::vector< tk::real >& fl,
+                   const std::array< tk::real, 3 >& fn,
+                   const std::array< tk::real, 3 >& gp,
+                   const std::array< std::vector< tk::real >, 2 >& state,
+                   std::vector< std::vector< tk::real > >& vriem,
+                   std::vector< std::vector< tk::real > >& riemannLoc )
+// *****************************************************************************
+//  Compute the riemann velocity at the interface
+//! \param[in] ncomp Number of scalar components in this PDE system
+//! \param[in] e_left Index for the left element
+//! \param[in] e_right Index for the right element
+//! \param[in] nmat Number of materials in this PDE system
+//! \param[in] fn Face/Surface normal
+//! \param[in] gp Gauss points coordinates
+//! \param[in] fl Surface flux
+//! \param[in] state Vector of state variables for left and right side
+//! \param[in,out] vriem Vector of the riemann velocity
+//! \param[in,out] riemannLoc Vector of coordinates where Riemann velocity data
+//!   is available
+// *****************************************************************************
+{
+  using inciter::densityIdx;
+  using inciter::momentumIdx;
+
+  std::size_t el(0), er(0);
+  el = static_cast< std::size_t >(e_left);
+  if(e_right != -1)
+    er = static_cast< std::size_t >(e_right);
+
+  riemannLoc[el].push_back( gp[0] );
+  riemannLoc[el].push_back( gp[1] );
+  riemannLoc[el].push_back( gp[2] );
+
+  if(e_right != -1)
+  {
+    riemannLoc[er].push_back( gp[0] );
+    riemannLoc[er].push_back( gp[1] );
+    riemannLoc[er].push_back( gp[2] );
+  }
+
+  tk::real rhobl(0.0), rhobr(0.0);
+  for (std::size_t k=0; k<nmat; ++k)
+  {
+    rhobl += state[0][densityIdx(nmat, k)];
+    rhobr += state[1][densityIdx(nmat, k)];
+  }
+
+  auto ul = state[0][momentumIdx(nmat, 0)] / rhobl;
+  auto vl = state[0][momentumIdx(nmat, 1)] / rhobl;
+  auto wl = state[0][momentumIdx(nmat, 2)] / rhobl;
+
+  auto ur = state[1][momentumIdx(nmat, 0)] / rhobr;
+  auto vr = state[1][momentumIdx(nmat, 1)] / rhobr;
+  auto wr = state[1][momentumIdx(nmat, 2)] / rhobr;
+
+  // Compute the normal velocities from left and right cells
+  auto vnl = ul * fn[0] + vl * fn[1] + wl * fn[2];
+  auto vnr = ur * fn[0] + vr * fn[1] + wr * fn[2];
+
+  // The interface velocity is evaluated by adding the normal velocity which
+  // is taken from the Riemann solver and the tangential velocity which is
+  // evaluated as an average of the left and right cells
+  auto urie = 0.5 * ((ul + ur) - fn[0] * (vnl + vnr)) + fl[ncomp+nmat] * fn[0];
+  auto vrie = 0.5 * ((vl + vr) - fn[1] * (vnl + vnr)) + fl[ncomp+nmat] * fn[1];
+  auto wrie = 0.5 * ((wl + wr) - fn[2] * (vnl + vnr)) + fl[ncomp+nmat] * fn[2];
+
+  vriem[el].push_back(urie);
+  vriem[el].push_back(vrie);
+  vriem[el].push_back(wrie);
 
-void
-VertexBasedMultiMat_FV(
-  const std::map< std::size_t, std::vector< std::size_t > >& esup,
-  const std::vector< std::size_t >& inpoel,
-  std::size_t nelem,
-  const tk::UnsMesh::Coords& coord,
-  const std::vector< int >& srcFlag,
-  const std::vector< std::size_t >& solidx,
-  tk::Fields& U,
-  tk::Fields& P,
-  std::size_t nmat )
-// *****************************************************************************
-//  Kuzmin's vertex-based limiter for multi-material FV
-//! \param[in] esup Elements surrounding points
-//! \param[in] inpoel Element connectivity
-//! \param[in] nelem Number of elements
-//! \param[in] coord Array of nodal coordinates
-//! \param[in] srcFlag Whether the energy source was added
-//! \param[in] solidx Solid material index indicator
-//! \param[in,out] U High-order solution vector which gets limited
-//! \param[in,out] P High-order vector of primitives which gets limited
-//! \param[in] nmat Number of materials in this PDE system
-//! \details This vertex-based limiter function should be called for multimat.
-//!   For details see: Kuzmin, D. (2010). A vertex-based hierarchical slope
-//!   limiter for p-adaptive discontinuous Galerkin methods. Journal of
-//!   computational and applied mathematics, 233(12), 3077-3085.
-// *****************************************************************************
-{
-  const auto rdof = inciter::g_inputdeck.get< tag::rdof >();
-  const auto intsharp = inciter::g_inputdeck.get< tag::multimat,
-    tag::intsharp >();
-  std::size_t ncomp = U.nprop()/rdof;
-  std::size_t nprim = P.nprop()/rdof;
+  if(e_right != -1)
+  {
+    vriem[er].push_back(urie);
+    vriem[er].push_back(vrie);
+    vriem[er].push_back(wrie);
+  }
+}
+
+std::vector< std::array< tk::real, 3 > >
+fluxTerms(
+  std::size_t ncomp,
+  std::size_t nmat,
+  const std::vector< inciter::EOS >& /*mat_blk*/,
+  const std::vector< tk::real >& ugp )
+// *****************************************************************************
+//  Compute the flux-function for the multimaterial PDEs
+//! \param[in] ncomp Number of components in this PDE system
+//! \param[in] nmat Number of materials in this PDE system
+// //! \param[in] mat_blk EOS material block
+//! \param[in] ugp State vector at the Gauss point at which flux is required
+//! \return Flux vectors for all components in multi-material PDE system
+// *****************************************************************************
+{
+  using inciter::volfracIdx;
+  using inciter::densityIdx;
+  using inciter::momentumIdx;
+  using inciter::energyIdx;
+  using inciter::velocityIdx;
+  using inciter::pressureIdx;
+  using inciter::deformIdx;
+
+  const auto& solidx =
+    inciter::g_inputdeck.get< tag::matidxmap, tag::solidx >();
 
-  for (std::size_t e=0; e<nelem; ++e)
-  {
-    std::vector< tk::real > phic(ncomp, 1.0);
-    std::vector< tk::real > phip(nprim, 1.0);
-    // limit conserved quantities
-    std::vector< std::size_t > var;
-    for (std::size_t k=0; k<nmat; ++k) {
-      var.push_back(volfracIdx(nmat,k));
-      var.push_back(densityIdx(nmat,k));
-    }
-    VertexBasedLimiting(U, esup, inpoel, coord, e, rdof, rdof, ncomp,
-      phic, var);
-    // limit primitive quantities
-    var.clear();
-    for (std::size_t c=0; c<nprim; ++c) var.push_back(c);
-    VertexBasedLimiting(P, esup, inpoel, coord, e, rdof, rdof, nprim,
-      phip, var);
-
-    // limits under which compression is to be performed
-    std::vector< std::size_t > matInt(nmat, 0);
-    std::vector< tk::real > alAvg(nmat, 0.0);
-    for (std::size_t k=0; k<nmat; ++k)
-      alAvg[k] = U(e, volfracDofIdx(nmat,k,rdof,0));
-    auto intInd = interfaceIndicator(nmat, alAvg, matInt);
-    if ((intsharp > 0) && intInd && srcFlag[e] == 0)
-    {
-      for (std::size_t k=0; k<nmat; ++k)
-      {
-        if (matInt[k])
-          phic[volfracIdx(nmat,k)] = 1.0;
-      }
-    }
-    else
-    {
-      if (!g_inputdeck.get< tag::accuracy_test >()) {
-        std::vector< tk::real > phic_p2(ncomp, 1.0);
-        consistentMultiMatLimiting_P1(nmat, rdof, e, solidx, U, P, phic,
-          phic_p2);
-      }
-    }
-
-    // apply limiter function
-    for (std::size_t c=0; c<ncomp; ++c)
+  std::vector< std::array< tk::real, 3 > > fl( ncomp, {{0, 0, 0}} );
+
+  tk::real rho(0.0);<--- Variable 'rho' is assigned a value that is never used.
+  for (std::size_t k=0; k<nmat; ++k)
+    rho += ugp[densityIdx(nmat, k)];<--- Variable 'rho' is assigned a value that is never used.
+
+  auto u = ugp[ncomp+velocityIdx(nmat,0)];
+  auto v = ugp[ncomp+velocityIdx(nmat,1)];
+  auto w = ugp[ncomp+velocityIdx(nmat,2)];
+
+  if (inciter::haveSolid(nmat, solidx))
+  {
+    std::vector< tk::real > al(nmat, 0.0);
+    std::vector< std::array< std::array< tk::real, 3 >, 3 > > g, asig;
+    std::array< std::array< tk::real, 3 >, 3 >
+      sig {{ {{0, 0, 0}}, {{0, 0, 0}}, {{0, 0, 0}} }};
+    for (std::size_t k=0; k<nmat; ++k)
+    {
+      al[k] = ugp[volfracIdx(nmat, k)];
+      // inv deformation gradient and Cauchy stress tensors
+      g.push_back(inciter::getDeformGrad(nmat, k, ugp));
+      asig.push_back(inciter::getCauchyStress(nmat, k, ncomp, ugp));
+      for (std::size_t i=0; i<3; ++i) asig[k][i][i] -= ugp[ncomp+pressureIdx(nmat,k)];
+
+      for (size_t i=0; i<3; ++i)
+        for (size_t j=0; j<3; ++j)
+          sig[i][j] += asig[k][i][j];
+    }
+
+    // conservative part of momentum flux
+    fl[momentumIdx(nmat, 0)][0] = ugp[momentumIdx(nmat, 0)] * u - sig[0][0];
+    fl[momentumIdx(nmat, 1)][0] = ugp[momentumIdx(nmat, 1)] * u - sig[0][1];
+    fl[momentumIdx(nmat, 2)][0] = ugp[momentumIdx(nmat, 2)] * u - sig[0][2];
+
+    fl[momentumIdx(nmat, 0)][1] = ugp[momentumIdx(nmat, 0)] * v - sig[1][0];
+    fl[momentumIdx(nmat, 1)][1] = ugp[momentumIdx(nmat, 1)] * v - sig[1][1];
+    fl[momentumIdx(nmat, 2)][1] = ugp[momentumIdx(nmat, 2)] * v - sig[1][2];
+
+    fl[momentumIdx(nmat, 0)][2] = ugp[momentumIdx(nmat, 0)] * w - sig[2][0];
+    fl[momentumIdx(nmat, 1)][2] = ugp[momentumIdx(nmat, 1)] * w - sig[2][1];
+    fl[momentumIdx(nmat, 2)][2] = ugp[momentumIdx(nmat, 2)] * w - sig[2][2];
+
+    for (std::size_t k=0; k<nmat; ++k)
     {
-      auto mark = c*rdof;
-      U(e, mark+1) = phic[c] * U(e, mark+1);
-      U(e, mark+2) = phic[c] * U(e, mark+2);
-      U(e, mark+3) = phic[c] * U(e, mark+3);
-    }
-    for (std::size_t c=0; c<nprim; ++c)
-    {
-      auto mark = c*rdof;
-      P(e, mark+1) = phip[c] * P(e, mark+1);
-      P(e, mark+2) = phip[c] * P(e, mark+2);
-      P(e, mark+3) = phip[c] * P(e, mark+3);
-    }
-  }
-}
-
-void
-WENOLimiting( const tk::Fields& U,
-              const std::vector< int >& esuel,
-              std::size_t e,
-              inciter::ncomp_t c,
-              std::size_t rdof,
-              tk::real cweight,
-              std::array< std::vector< tk::real >, 3 >& limU )
-// *****************************************************************************
-//  WENO limiter function calculation for P1 dofs
-//! \param[in] U High-order solution vector which is to be limited
-//! \param[in] esuel Elements surrounding elements
-//! \param[in] e Id of element whose solution is to be limited
-//! \param[in] c Index of component which is to be limited
-//! \param[in] rdof Maximum number of reconstructed degrees of freedom
-//! \param[in] cweight Weight of the central stencil
-//! \param[in,out] limU Limited gradients of component c
-// *****************************************************************************
-{
-  std::array< std::array< tk::real, 3 >, 5 > gradu;
-  std::array< tk::real, 5 > wtStencil, osc, wtDof;
-
-  auto mark = c*rdof;
-
-  // reset all stencil values to zero
-  for (auto& g : gradu) g.fill(0.0);
-  osc.fill(0);
-  wtDof.fill(0);
-  wtStencil.fill(0);
-
-  // The WENO limiter uses solution data from the neighborhood in the form
-  // of stencils to enforce non-oscillatory conditions. The immediate
-  // (Von Neumann) neighborhood of a tetrahedral cell consists of the 4
-  // cells that share faces with it. These are the 4 neighborhood-stencils
-  // for the tetrahedron. The primary stencil is the tet itself. Weights are
-  // assigned to these stencils, with the primary stencil usually assigned
-  // the highest weight. The lower the primary/central weight, the more
-  // dissipative the limiting effect. This central weight is usually problem
-  // dependent. It is set higher for relatively weaker discontinuities, and
-  // lower for stronger discontinuities.
-
-  // primary stencil
-  gradu[0][0] = U(e, mark+1);
-  gradu[0][1] = U(e, mark+2);
-  gradu[0][2] = U(e, mark+3);
-  wtStencil[0] = cweight;
-
-  // stencils from the neighborhood
-  for (std::size_t is=1; is<5; ++is)
-  {
-    auto nel = esuel[ 4*e+(is-1) ];
-
-    // ignore physical domain ghosts
-    if (nel == -1)
-    {
-      gradu[is].fill(0.0);
-      wtStencil[is] = 0.0;
-      continue;
-    }
-
-    std::size_t n = static_cast< std::size_t >( nel );
-    gradu[is][0] = U(n, mark+1);
-    gradu[is][1] = U(n, mark+2);
-    gradu[is][2] = U(n, mark+3);
-    wtStencil[is] = 1.0;
-  }
-
-  // From these stencils, an oscillation indicator is calculated, which
-  // determines the effective weights for the high-order solution DOFs.
-  // These effective weights determine the contribution of each of the
-  // stencils to the high-order solution DOFs of the current cell which are
-  // being limited. If this indicator detects a large oscillation in the
-  // solution of the current cell, it reduces the effective weight for the
-  // central stencil contribution to its high-order DOFs. This results in
-  // a more dissipative and well-behaved solution in the troubled cell.
-
-  // oscillation indicators
-  for (std::size_t is=0; is<5; ++is)
-    osc[is] = std::sqrt( tk::dot(gradu[is], gradu[is]) );
-
-  tk::real wtotal = 0;
-
-  // effective weights for dofs
-  for (std::size_t is=0; is<5; ++is)
-  {
-    // A small number (1.0e-8) is needed here to avoid dividing by a zero in
-    // the case of a constant solution, where osc would be zero. The number
-    // is not set to machine zero because it is squared, and a number
-    // between 1.0e-8 to 1.0e-6 is needed.
-    wtDof[is] = wtStencil[is] * pow( (1.0e-8 + osc[is]), -2 );
-    wtotal += wtDof[is];
-  }
-
-  for (std::size_t is=0; is<5; ++is)
-  {
-    wtDof[is] = wtDof[is]/wtotal;
-  }
-
-  limU[0][e] = 0.0;
-  limU[1][e] = 0.0;
-  limU[2][e] = 0.0;
-
-  // limiter function
-  for (std::size_t is=0; is<5; ++is)
-  {
-    limU[0][e] += wtDof[is]*gradu[is][0];
-    limU[1][e] += wtDof[is]*gradu[is][1];
-    limU[2][e] += wtDof[is]*gradu[is][2];
-  }
-}
-
-std::vector< tk::real >
-SuperbeeLimiting( const tk::Fields& U,
-                  const std::vector< int >& esuel,
-                  const std::vector< std::size_t >& inpoel,
-                  const tk::UnsMesh::Coords& coord,
-                  std::size_t e,
-                  std::size_t ndof,
-                  std::size_t rdof,
-                  std::size_t dof_el,
-                  inciter:: ncomp_t ncomp,
-                  tk::real beta_lim )
-// *****************************************************************************
-//  Superbee limiter function calculation for P1 dofs
-//! \param[in] U High-order solution vector which is to be limited
-//! \param[in] esuel Elements surrounding elements
-//! \param[in] inpoel Element connectivity
-//! \param[in] coord Array of nodal coordinates
-//! \param[in] e Id of element whose solution is to be limited
-//! \param[in] ndof Maximum number of degrees of freedom
-//! \param[in] rdof Maximum number of reconstructed degrees of freedom
-//! \param[in] dof_el Local number of degrees of freedom
-//! \param[in] ncomp Number of scalar components in this PDE system
-//! \param[in] beta_lim Parameter which is equal to 2 for Superbee and 1 for
-//!   minmod limiter
-//! \return phi Limiter function for solution in element e
-// *****************************************************************************
-{
-  // Superbee is a TVD limiter, which uses min-max bounds that the
-  // high-order solution should satisfy, to ensure TVD properties. For a
-  // high-order method like DG, this involves the following steps:
-  // 1. Find min-max bounds in the immediate neighborhood of cell.
-  // 2. Calculate the Superbee function for all the points where solution
-  //    needs to be reconstructed to (all quadrature points). From these,
-  //    use the minimum value of the limiter function.
-
-  std::vector< tk::real > uMin(ncomp, 0.0), uMax(ncomp, 0.0);
-
-  for (inciter::ncomp_t c=0; c<ncomp; ++c)
-  {
-    auto mark = c*rdof;
-    uMin[c] = U(e, mark);
-    uMax[c] = U(e, mark);
-  }
-
-  // ----- Step-1: find min/max in the neighborhood
-  for (std::size_t is=0; is<4; ++is)
-  {
-    auto nel = esuel[ 4*e+is ];
-
-    // ignore physical domain ghosts
-    if (nel == -1) continue;
-
-    auto n = static_cast< std::size_t >( nel );
-    for (inciter::ncomp_t c=0; c<ncomp; ++c)
-    {
-      auto mark = c*rdof;
-      uMin[c] = std::min(uMin[c], U(n, mark));
-      uMax[c] = std::max(uMax[c], U(n, mark));
-    }
-  }
-
-  // ----- Step-2: loop over all quadrature points to get limiter function
-
-  // to loop over all the quadrature points of all faces of element e,
-  // coordinates of the quadrature points are needed.
-  // Number of quadrature points for face integration
-  auto ng = tk::NGfa(ndof);
-
-  // arrays for quadrature points
-  std::array< std::vector< tk::real >, 2 > coordgp;
-  std::vector< tk::real > wgp;
-
-  coordgp[0].resize( ng );
-  coordgp[1].resize( ng );
-  wgp.resize( ng );
-
-  // get quadrature point weights and coordinates for triangle
-  tk::GaussQuadratureTri( ng, coordgp, wgp );
-
-  const auto& cx = coord[0];
-  const auto& cy = coord[1];
-  const auto& cz = coord[2];
-
-  // Extract the element coordinates
-  std::array< std::array< tk::real, 3>, 4 > coordel {{
-    {{ cx[ inpoel[4*e  ] ], cy[ inpoel[4*e  ] ], cz[ inpoel[4*e  ] ] }},
-    {{ cx[ inpoel[4*e+1] ], cy[ inpoel[4*e+1] ], cz[ inpoel[4*e+1] ] }},
-    {{ cx[ inpoel[4*e+2] ], cy[ inpoel[4*e+2] ], cz[ inpoel[4*e+2] ] }},
-    {{ cx[ inpoel[4*e+3] ], cy[ inpoel[4*e+3] ], cz[ inpoel[4*e+3] ] }} }};
-
-  // Compute the determinant of Jacobian matrix
-  auto detT =
-    tk::Jacobian( coordel[0], coordel[1], coordel[2], coordel[3] );
-
-  // initialize limiter function
-  std::vector< tk::real > phi(ncomp, 1.0);
-  for (std::size_t lf=0; lf<4; ++lf)
-  {
-    // Extract the face coordinates
-    std::array< std::size_t, 3 > inpofa_l {{ inpoel[4*e+tk::lpofa[lf][0]],
-                                             inpoel[4*e+tk::lpofa[lf][1]],
-                                             inpoel[4*e+tk::lpofa[lf][2]] }};
-
-    std::array< std::array< tk::real, 3>, 3 > coordfa {{
-      {{ cx[ inpofa_l[0] ], cy[ inpofa_l[0] ], cz[ inpofa_l[0] ] }},
-      {{ cx[ inpofa_l[1] ], cy[ inpofa_l[1] ], cz[ inpofa_l[1] ] }},
-      {{ cx[ inpofa_l[2] ], cy[ inpofa_l[2] ], cz[ inpofa_l[2] ] }} }};
-
-    // Gaussian quadrature
-    for (std::size_t igp=0; igp<ng; ++igp)
-    {
-      // Compute the coordinates of quadrature point at physical domain
-      auto gp = tk::eval_gp( igp, coordfa, coordgp );
-
-      //Compute the basis functions
-      auto B_l = tk::eval_basis( rdof,
-            tk::Jacobian( coordel[0], gp, coordel[2], coordel[3] ) / detT,
-            tk::Jacobian( coordel[0], coordel[1], gp, coordel[3] ) / detT,
-            tk::Jacobian( coordel[0], coordel[1], coordel[2], gp ) / detT );
-
-      auto state =
-        tk::eval_state(ncomp, rdof, dof_el, e, U, B_l);
-
-      Assert( state.size() == ncomp, "Size mismatch" );
-
-      // compute the limiter function
-      for (inciter::ncomp_t c=0; c<ncomp; ++c)
-      {
-        auto phi_gp = 1.0;
-        auto mark = c*rdof;
-        auto uNeg = state[c] - U(e, mark);
-        if (uNeg > 1.0e-14)
-        {
-          uNeg = std::max(uNeg, 1.0e-08);
-          phi_gp = std::min( 1.0, (uMax[c]-U(e, mark))/(2.0*uNeg) );
-        }
-        else if (uNeg < -1.0e-14)
-        {
-          uNeg = std::min(uNeg, -1.0e-08);
-          phi_gp = std::min( 1.0, (uMin[c]-U(e, mark))/(2.0*uNeg) );
-        }
-        else
-        {
-          phi_gp = 1.0;
-        }
-        phi_gp = std::max( 0.0,
-                           std::max( std::min(beta_lim*phi_gp, 1.0),
-                                     std::min(phi_gp, beta_lim) ) );
-        phi[c] = std::min( phi[c], phi_gp );
-      }
-    }
-  }
-
-  return phi;
-}
-
-void
-VertexBasedLimiting(
-  const tk::Fields& U,
-  const std::map< std::size_t, std::vector< std::size_t > >& esup,
-  const std::vector< std::size_t >& inpoel,
-  const tk::UnsMesh::Coords& coord,
-  std::size_t e,
-  std::size_t rdof,
-  std::size_t dof_el,
-  std::size_t ncomp,
-  std::vector< tk::real >& phi,
-  const std::vector< std::size_t >& VarList )
-// *****************************************************************************
-//  Kuzmin's vertex-based limiter function calculation for P1 dofs
-//! \param[in] U High-order solution vector which is to be limited
-//! \param[in] esup Elements surrounding points
-//! \param[in] inpoel Element connectivity
-//! \param[in] coord Array of nodal coordinates
-//! \param[in] e Id of element whose solution is to be limited
-//! \param[in] rdof Maximum number of reconstructed degrees of freedom
-//! \param[in] dof_el Local number of degrees of freedom
-//! \param[in] ncomp Number of scalar components in this PDE system
-//! \param[in,out] phi Limiter function for solution in element e
-//! \param[in] VarList List of variable indices to be limited
-// *****************************************************************************
-{
-  // Kuzmin's vertex-based TVD limiter uses min-max bounds that the
-  // high-order solution should satisfy, to ensure TVD properties. For a
-  // high-order method like DG, this involves the following steps:
-  // 1. Find min-max bounds in the nodal-neighborhood of cell.
-  // 2. Calculate the limiter function (Superbee) for all the vertices of cell.
-  //    From these, use the minimum value of the limiter function.
-
-  // Prepare for calculating Basis functions
-  const auto& cx = coord[0];
-  const auto& cy = coord[1];
-  const auto& cz = coord[2];
-
-  // Extract the element coordinates
-  std::array< std::array< tk::real, 3>, 4 > coordel {{
-    {{ cx[ inpoel[4*e  ] ], cy[ inpoel[4*e  ] ], cz[ inpoel[4*e  ] ] }},
-    {{ cx[ inpoel[4*e+1] ], cy[ inpoel[4*e+1] ], cz[ inpoel[4*e+1] ] }},
-    {{ cx[ inpoel[4*e+2] ], cy[ inpoel[4*e+2] ], cz[ inpoel[4*e+2] ] }},
-    {{ cx[ inpoel[4*e+3] ], cy[ inpoel[4*e+3] ], cz[ inpoel[4*e+3] ] }} }};
-
-  // Compute the determinant of Jacobian matrix
-  auto detT =
-    tk::Jacobian( coordel[0], coordel[1], coordel[2], coordel[3] );
-
-  std::vector< tk::real > uMin(VarList.size(), 0.0),
-                          uMax(VarList.size(), 0.0);
-
-  // loop over all nodes of the element e
-  for (std::size_t lp=0; lp<4; ++lp)
-  {
-    // reset min/max
-    for (std::size_t i=0; i<VarList.size(); ++i)
-    {
-      auto mark = VarList[i]*rdof;
-      uMin[i] = U(e, mark);
-      uMax[i] = U(e, mark);
-    }
-    auto p = inpoel[4*e+lp];
-    const auto& pesup = tk::cref_find(esup, p);
-
-    // ----- Step-1: find min/max in the neighborhood of node p
-    // loop over all the internal elements surrounding this node p
-    for (auto er : pesup)
-    {
-      for (std::size_t i=0; i<VarList.size(); ++i)
-      {
-        auto mark = VarList[i]*rdof;
-        uMin[i] = std::min(uMin[i], U(er, mark));
-        uMax[i] = std::max(uMax[i], U(er, mark));
-      }
-    }
-
-    // ----- Step-2: compute the limiter function at this node
-    // find high-order solution
-    std::vector< tk::real > state;
-    std::array< tk::real, 3 > gp{cx[p], cy[p], cz[p]};
-    auto B_p = tk::eval_basis( rdof,
-          tk::Jacobian( coordel[0], gp, coordel[2], coordel[3] ) / detT,
-          tk::Jacobian( coordel[0], coordel[1], gp, coordel[3] ) / detT,
-          tk::Jacobian( coordel[0], coordel[1], coordel[2], gp ) / detT );
-    state = tk::eval_state(ncomp, rdof, dof_el, e, U, B_p);
-
-    Assert( state.size() == ncomp, "Size mismatch" );
-
-    // compute the limiter function
-    for (std::size_t i=0; i<VarList.size(); ++i)
-    {
-      auto c = VarList[i];
-      auto phi_gp = 1.0;
-      auto mark = c*rdof;
-      auto uNeg = state[c] - U(e, mark);
-      auto uref = std::max(std::fabs(U(e,mark)), 1e-14);
-      if (uNeg > 1.0e-06*uref)
-      {
-        phi_gp = std::min( 1.0, (uMax[i]-U(e, mark))/uNeg );
-      }
-      else if (uNeg < -1.0e-06*uref)
-      {
-        phi_gp = std::min( 1.0, (uMin[i]-U(e, mark))/uNeg );
-      }
-      else
-      {
-        phi_gp = 1.0;
-      }
-
-    // ----- Step-3: take the minimum of the nodal-limiter functions
-      phi[c] = std::min( phi[c], phi_gp );
-    }
-  }
-}
-
-void
-VertexBasedLimiting_P2( const std::vector< std::vector< tk::real > >& unk,
-  const tk::Fields& U,
-  const std::map< std::size_t, std::vector< std::size_t > >& esup,
-  const std::vector< std::size_t >& inpoel,
-  std::size_t e,
-  std::size_t rdof,
-  [[maybe_unused]] std::size_t dof_el,
-  std::size_t ncomp,
-  const std::vector< std::size_t >& gid,
-  const std::unordered_map< std::size_t, std::size_t >& bid,
-  const std::vector< std::vector<tk::real> >& NodalExtrm,
-  const std::vector< std::size_t >& VarList,
-  std::vector< tk::real >& phi )
-// *****************************************************************************
-//  Kuzmin's vertex-based limiter function calculation for P2 dofs
-//! \param[in] U High-order solution vector which is to be limited
-//! \param[in] esup Elements surrounding points
-//! \param[in] inpoel Element connectivity
-//! \param[in] e Id of element whose solution is to be limited
-//! \param[in] rdof Maximum number of reconstructed degrees of freedom
-//! \param[in] dof_el Local number of degrees of freedom
-//! \param[in] ncomp Number of scalar components in this PDE system
-//! \param[in] gid Local->global node id map
-//! \param[in] bid Local chare-boundary node ids (value) associated to
-//!   global node ids (key)
-//! \param[in] NodalExtrm Chare-boundary nodal extrema
-//! \param[in] VarList List of variable indices that need to be limited
-//! \param[out] phi Limiter function for solution in element e
-//! \details This function limits the P2 dofs of P2 solution in a hierachical
-//!   way to P1 dof limiting. Here we treat the first order derivatives the same
-//!   way as cell average while second order derivatives represent the gradients
-//!   to be limited in the P1 limiting procedure.
-// *****************************************************************************
-{
-  const auto nelem = inpoel.size() / 4;
-
-  std::vector< std::vector< tk::real > > uMin, uMax;
-  uMin.resize( VarList.size(), std::vector<tk::real>(3, 0.0) );
-  uMax.resize( VarList.size(), std::vector<tk::real>(3, 0.0) );
-
-  // The coordinates of centroid in the reference domain
-  std::array< std::vector< tk::real >, 3 > center;
-  center[0].resize(1, 0.25);
-  center[1].resize(1, 0.25);
-  center[2].resize(1, 0.25);
-
-  std::array< std::array< tk::real, 4 >, 3 > cnodes{{
-    {{0, 1, 0, 0}},
-    {{0, 0, 1, 0}},
-    {{0, 0, 0, 1}} }};
-
-  // loop over all nodes of the element e
-  for (std::size_t lp=0; lp<4; ++lp)
-  {
-    // Find the max/min first-order derivatives for internal element
-    for (std::size_t i=0; i<VarList.size(); ++i)
-    {
-      for (std::size_t idir=1; idir < 4; ++idir)
-      {
-        uMin[i][idir-1] = unk[VarList[i]][idir];
-        uMax[i][idir-1] = unk[VarList[i]][idir];
-      }
-    }
-
-    auto p = inpoel[4*e+lp];
-    const auto& pesup = tk::cref_find(esup, p);
-
-    // Step-1: find min/max first order derivative at the centroid in the
-    // neighborhood of node p
-    for (auto er : pesup)
-    {
-      if(er < nelem)      // If this is internal element
-      {
-        // Compute the derivatives of basis function in the reference domain
-        auto dBdxi_er = tk::eval_dBdxi(rdof,
-          {{center[0][0], center[1][0], center[2][0]}});
-
-        for (std::size_t i=0; i<VarList.size(); ++i)
-        {
-          auto mark = VarList[i]*rdof;
-          for (std::size_t idir = 0; idir < 3; ++idir)
-          {
-            // The first order derivative at the centroid of element er
-            tk::real slope_er(0.0);
-            for(std::size_t idof = 1; idof < rdof; idof++)
-              slope_er += U(er, mark+idof) * dBdxi_er[idir][idof];
-
-            uMin[i][idir] = std::min(uMin[i][idir], slope_er);
-            uMax[i][idir] = std::max(uMax[i][idir], slope_er);
-
-          }
-        }
-      }
-    }
-    // If node p is the chare-boundary node, find min/max by comparing with
-    // the chare-boundary nodal extrema from vector NodalExtrm
-    auto gip = bid.find( gid[p] );
-    if(gip != end(bid))
-    {
-      auto ndof_NodalExtrm = NodalExtrm[0].size() / (ncomp * 2);
-      for (std::size_t i=0; i<VarList.size(); ++i)
-      {
-        for (std::size_t idir = 0; idir < 3; idir++)
-        {
-          auto max_mark = 2*VarList[i]*ndof_NodalExtrm + 2*idir;
-          auto min_mark = max_mark + 1;
-          const auto& ex = NodalExtrm[gip->second];
-          uMax[i][idir] = std::max(ex[max_mark], uMax[i][idir]);
-          uMin[i][idir] = std::min(ex[min_mark], uMin[i][idir]);
-        }
-      }
-    }
-
-    //Step-2: compute the limiter function at this node
-    std::array< tk::real, 3 > node{cnodes[0][lp], cnodes[1][lp], cnodes[2][lp]};
-
-    // find high-order solution
-    std::vector< std::array< tk::real, 3 > > state;
-    state.resize(VarList.size());
-
-    for (std::size_t i=0; i<VarList.size(); ++i)
-    {
-      auto dx = node[0] - center[0][0];
-      auto dy = node[1] - center[1][0];
-      auto dz = node[2] - center[2][0];
-
-      auto c = VarList[i];
-
-      state[i][0] = unk[c][1] + unk[c][4]*dx + unk[c][7]*dy + unk[c][8]*dz;
-      state[i][1] = unk[c][2] + unk[c][5]*dy + unk[c][7]*dx + unk[c][9]*dz;
-      state[i][2] = unk[c][3] + unk[c][6]*dz + unk[c][8]*dx + unk[c][9]*dy;
-    }
-
-    // compute the limiter function
-    for (std::size_t i=0; i<VarList.size(); ++i)
-    {
-      auto c = VarList[i];
-      tk::real phi_dir(1.0);
-      for (std::size_t idir = 1; idir <= 3; ++idir)
-      {
-        phi_dir = 1.0;<--- phi_dir is assigned
-        auto uNeg = state[i][idir-1] - unk[c][idir];
-        auto uref = std::max(std::fabs(unk[c][idir]), 1e-14);
-        if (uNeg > 1.0e-6*uref)
-        {
-          phi_dir =<--- phi_dir is overwritten
-            std::min( 1.0, ( uMax[i][idir-1] - unk[c][idir])/uNeg );
-        }
-        else if (uNeg < -1.0e-6*uref)
-        {
-          phi_dir =
-            std::min( 1.0, ( uMin[i][idir-1] - unk[c][idir])/uNeg );
-        }
-        else
-        {
-          phi_dir = 1.0;
-        }
-
-        phi[c] = std::min( phi[c], phi_dir );
-      }
-    }
-  }
-}
-
-void consistentMultiMatLimiting_P1(
-  std::size_t nmat,
-  std::size_t rdof,
-  std::size_t e,
-  const std::vector< std::size_t >& solidx,
-  tk::Fields& U,<--- Parameter 'U' can be declared with const
-  [[maybe_unused]] tk::Fields& P,
-  std::vector< tk::real >& phic_p1,
-  std::vector< tk::real >& phic_p2 )
-// *****************************************************************************
-//  Consistent limiter modifications for conservative variables
-//! \param[in] nmat Number of materials in this PDE system
-//! \param[in] rdof Total number of reconstructed dofs
-//! \param[in] e Element being checked for consistency
-//! \param[in] solidx Solid material index indicator
-//! \param[in] U Vector of conservative variables
-//! \param[in] P Vector of primitive variables
-//! \param[in,out] phic_p1 Vector of limiter functions for P1 dofs of the
-//!   conserved quantities
-//! \param[in,out] phip_p2 Vector of limiter functions for P2 dofs of the
-//!   conserved quantities
-// *****************************************************************************
-{
-  // find the limiter-function for volume-fractions
-  auto phi_al_p1(1.0), phi_al_p2(1.0), almax(0.0), dalmax(0.0);
-  //std::size_t nmax(0);
-  for (std::size_t k=0; k<nmat; ++k)
-  {
-    phi_al_p1 = std::min( phi_al_p1, phic_p1[volfracIdx(nmat, k)] );
-    if(rdof > 4)
-      phi_al_p2 = std::min( phi_al_p2, phic_p2[volfracIdx(nmat, k)] );
-    if (almax < U(e,volfracDofIdx(nmat, k, rdof, 0)))
-    {
-      //nmax = k;
-      almax = U(e,volfracDofIdx(nmat, k, rdof, 0));
-    }
-    tk::real dmax(0.0);
-    dmax = std::max(
-             std::max(
-               std::abs(U(e,volfracDofIdx(nmat, k, rdof, 1))),
-               std::abs(U(e,volfracDofIdx(nmat, k, rdof, 2))) ),
-               std::abs(U(e,volfracDofIdx(nmat, k, rdof, 3))) );
-    dalmax = std::max( dalmax, dmax );
-  }
-
-  auto al_band = 1e-4;
-
-  //phi_al = phic[nmax];
-
-  // determine if cell is a material-interface cell based on ad-hoc tolerances.
-  // if interface-cell, then modify high-order dofs of conserved unknowns
-  // consistently and use same limiter for all equations.
-  // Slopes of solution variables \alpha_k \rho_k and \alpha_k \rho_k E_k need
-  // to be modified in interface cells, such that slopes in the \rho_k and
-  // \rho_k E_k part are ignored and only slopes in \alpha_k are considered.
-  // Ideally, we would like to not do this, but this is a necessity to avoid
-  // limiter-limiter interactions in multiphase CFD (see "K.-M. Shyue, F. Xiao,
-  // An Eulerian interface sharpening algorithm for compressible two-phase flow:
-  // the algebraic THINC approach, Journal of Computational Physics 268, 2014,
-  // 326–354. doi:10.1016/j.jcp.2014.03.010." and "A. Chiapolino, R. Saurel,
-  // B. Nkonga, Sharpening diffuse interfaces with compressible fluids on
-  // unstructured meshes, Journal of Computational Physics 340 (2017) 389–417.
-  // doi:10.1016/j.jcp.2017.03.042."). This approximation should be applied in
-  // as narrow a band of interface-cells as possible. The following if-test
-  // defines this band of interface-cells. This tests checks the value of the
-  // maximum volume-fraction in the cell (almax) and the maximum change in
-  // volume-fraction in the cell (dalmax, calculated from second-order DOFs),
-  // to determine the band of interface-cells where the aforementioned fix needs
-  // to be applied. This if-test says that, the fix is applied when the change
-  // in volume-fraction across a cell is greater than 0.1, *and* the
-  // volume-fraction is between 0.1 and 0.9.
-  if ( //dalmax > al_band &&
-       (almax > al_band && almax < (1.0-al_band)) )
-  {
-    // 1. consistent high-order dofs
-    for (std::size_t k=0; k<nmat; ++k)
-    {
-      auto alk =
-        std::max( 1.0e-14, U(e,volfracDofIdx(nmat, k, rdof, 0)) );
-      auto rhok = U(e,densityDofIdx(nmat, k, rdof, 0)) / alk;
-      auto rhoE = U(e,energyDofIdx(nmat, k, rdof, 0)) / alk;
-      for (std::size_t idof=1; idof<rdof; ++idof)
-      {
-          U(e,densityDofIdx(nmat, k, rdof, idof)) = rhok *
-            U(e,volfracDofIdx(nmat, k, rdof, idof));
-          U(e,energyDofIdx(nmat, k, rdof, idof)) = rhoE *
-            U(e,volfracDofIdx(nmat, k, rdof, idof));
-      }
-      if (solidx[k] > 0)
-        for (std::size_t i=0; i<3; ++i)
-          for (std::size_t j=0; j<3; ++j)
-          {
-            for (std::size_t idof=1; idof<rdof; ++idof)
-              U(e,deformDofIdx(nmat,solidx[k],i,j,rdof,idof)) = 0.0;
-          }
-    }
-
-    // 2. same limiter for all volume-fractions and densities
-    for (std::size_t k=0; k<nmat; ++k)
-    {
-      phic_p1[volfracIdx(nmat, k)] = phi_al_p1;
-      phic_p1[densityIdx(nmat, k)] = phi_al_p1;
-      phic_p1[energyIdx(nmat, k)] = phi_al_p1;
-      if (solidx[k] > 0)
-        for (std::size_t i=0; i<3; ++i)
-          for (std::size_t j=0; j<3; ++j)
-            phic_p1[deformIdx(nmat,solidx[k],i,j)] = phi_al_p1;
-    }
-    if(rdof > 4)
-    {
-      for (std::size_t k=0; k<nmat; ++k)
-      {
-        phic_p2[volfracIdx(nmat, k)] = phi_al_p2;
-        phic_p2[densityIdx(nmat, k)] = phi_al_p2;
-        phic_p2[energyIdx(nmat, k)] = phi_al_p2;
-        if (solidx[k] > 0)
-          for (std::size_t i=0; i<3; ++i)
-            for (std::size_t j=0; j<3; ++j)
-              phic_p2[deformIdx(nmat,solidx[k],i,j)] = phi_al_p2;
-      }
-    }
-  }
-  else
-  {
-    // same limiter for all volume-fractions
-    for (std::size_t k=0; k<nmat; ++k)
-      phic_p1[volfracIdx(nmat, k)] = phi_al_p1;
-    if(rdof > 4)
-      for (std::size_t k=0; k<nmat; ++k)
-        phic_p2[volfracIdx(nmat, k)] = phi_al_p2;
-  }
-}
-
-void BoundPreservingLimiting( std::size_t nmat,
-                              std::size_t ndof,
-                              std::size_t e,
-                              const std::vector< std::size_t >& inpoel,
-                              const tk::UnsMesh::Coords& coord,
-                              const tk::Fields& U,
-                              std::vector< tk::real >& phic_p1,
-                              std::vector< tk::real >& phic_p2 )
-// *****************************************************************************
-//  Bound preserving limiter for volume fractions when MulMat scheme is selected
-//! \param[in] nmat Number of materials in this PDE system
-//! \param[in] ndof Total number of reconstructed dofs
-//! \param[in] e Element being checked for consistency
-//! \param[in] inpoel Element connectivity
-//! \param[in] coord Array of nodal coordinates
-//! \param[in,out] U Second-order solution vector which gets modified near
-//!   material interfaces for consistency
-//! \param[in] unk Vector of conservative variables based on Taylor basis
-//! \param[in,out] phic_p1 Vector of limiter functions for P1 dofs of the
-//!   conserved quantities
-//! \param[in,out] phic_p2 Vector of limiter functions for P2 dofs of the
-//!   conserved quantities
-//! \details This bound-preserving limiter is specifically meant to enforce
-//!   bounds [0,1], but it does not suppress oscillations like the other 'TVD'
-//!   limiters. TVD limiters on the other hand, do not preserve such bounds. A
-//!   combination of oscillation-suppressing and bound-preserving limiters can
-//!   obtain a non-oscillatory and bounded solution.
-// *****************************************************************************
-{
-  const auto& cx = coord[0];
-  const auto& cy = coord[1];
-  const auto& cz = coord[2];
-
-  // Extract the element coordinates
-  std::array< std::array< tk::real, 3>, 4 > coordel {{
-    {{ cx[ inpoel[4*e  ] ], cy[ inpoel[4*e  ] ], cz[ inpoel[4*e  ] ] }},
-    {{ cx[ inpoel[4*e+1] ], cy[ inpoel[4*e+1] ], cz[ inpoel[4*e+1] ] }},
-    {{ cx[ inpoel[4*e+2] ], cy[ inpoel[4*e+2] ], cz[ inpoel[4*e+2] ] }},
-    {{ cx[ inpoel[4*e+3] ], cy[ inpoel[4*e+3] ], cz[ inpoel[4*e+3] ] }} }};
-
-  // Compute the determinant of Jacobian matrix
-  auto detT =
-    tk::Jacobian( coordel[0], coordel[1], coordel[2], coordel[3] );
-
-  std::vector< tk::real > phi_bound(nmat, 1.0);
-
-  // Compute the upper and lower bound for volume fraction
-  const tk::real min = 1e-14;
-  const tk::real max = 1.0 - min;
-
-  // loop over all faces of the element e
-  for (std::size_t lf=0; lf<4; ++lf)
-  {
-    // Extract the face coordinates
-    std::array< std::size_t, 3 > inpofa_l {{ inpoel[4*e+tk::lpofa[lf][0]],
-                                             inpoel[4*e+tk::lpofa[lf][1]],
-                                             inpoel[4*e+tk::lpofa[lf][2]] }};
-
-    std::array< std::array< tk::real, 3>, 3 > coordfa {{
-      {{ cx[ inpofa_l[0] ], cy[ inpofa_l[0] ], cz[ inpofa_l[0] ] }},
-      {{ cx[ inpofa_l[1] ], cy[ inpofa_l[1] ], cz[ inpofa_l[1] ] }},
-      {{ cx[ inpofa_l[2] ], cy[ inpofa_l[2] ], cz[ inpofa_l[2] ] }} }};
-
-    auto ng = tk::NGfa(ndof);
-
-    // arrays for quadrature points
-    std::array< std::vector< tk::real >, 2 > coordgp;
-    std::vector< tk::real > wgp;
-
-    coordgp[0].resize( ng );
-    coordgp[1].resize( ng );
-    wgp.resize( ng );
-
-    // get quadrature point weights and coordinates for triangle
-    tk::GaussQuadratureTri( ng, coordgp, wgp );
-
-    // Gaussian quadrature
-    for (std::size_t igp=0; igp<ng; ++igp)
-    {
-      // Compute the coordinates of quadrature point at physical domain
-      auto gp = tk::eval_gp( igp, coordfa, coordgp );
-
-      //Compute the basis functions
-      auto B = tk::eval_basis( ndof,
-            tk::Jacobian( coordel[0], gp, coordel[2], coordel[3] ) / detT,
-            tk::Jacobian( coordel[0], coordel[1], gp, coordel[3] ) / detT,
-            tk::Jacobian( coordel[0], coordel[1], coordel[2], gp ) / detT );
-
-      auto state = eval_state( U.nprop()/ndof, ndof, ndof, e, U, B );
-
-      for(std::size_t imat = 0; imat < nmat; imat++)
-      {
-        auto phi = BoundPreservingLimitingFunction( min, max,
-          state[volfracIdx(nmat, imat)],
-          U(e,volfracDofIdx(nmat, imat, ndof, 0)) );
-        phi_bound[imat] = std::min( phi_bound[imat], phi );
-      }
-    }
-  }
-
-  // If DG(P2), the bound-preserving limiter should also be applied to the gauss
-  // point within the element
-  if(ndof > 4)
-  {
-    auto ng = tk::NGvol(ndof);
-
-    // arrays for quadrature points
-    std::array< std::vector< tk::real >, 3 > coordgp;
-    std::vector< tk::real > wgp;
-
-    coordgp[0].resize( ng );
-    coordgp[1].resize( ng );
-    coordgp[2].resize( ng );
-    wgp.resize( ng );
-
-    tk::GaussQuadratureTet( ng, coordgp, wgp );
-
-    for (std::size_t igp=0; igp<ng; ++igp)
-    {
-      // Compute the basis function
-      auto B = tk::eval_basis( ndof, coordgp[0][igp], coordgp[1][igp],
-        coordgp[2][igp] );
-
-      auto state = tk::eval_state(U.nprop()/ndof, ndof, ndof, e, U, B);
-
-      for(std::size_t imat = 0; imat < nmat; imat++)
-      {
-        auto phi = BoundPreservingLimitingFunction(min, max,
-          state[volfracIdx(nmat, imat)],
-          U(e,volfracDofIdx(nmat, imat, ndof, 0)) );
-        phi_bound[imat] = std::min( phi_bound[imat], phi );
-      }
-    }
-  }
-
-  for(std::size_t k=0; k<nmat; k++)
-    phic_p1[volfracIdx(nmat, k)] = std::min(phi_bound[k],
-      phic_p1[volfracIdx(nmat, k)]);
-
-  if(ndof > 4)
-    for(std::size_t k=0; k<nmat; k++)
-      phic_p2[volfracIdx(nmat, k)] = std::min(phi_bound[k],
-        phic_p2[volfracIdx(nmat, k)]);
-}
-
-tk::real
-BoundPreservingLimitingFunction( const tk::real min,
-                                 const tk::real max,
-                                 const tk::real al_gp,
-                                 const tk::real al_avg )
-// *****************************************************************************
-//  Bound-preserving limiter function for the volume fractions
-//! \param[in] min Minimum bound for volume fraction
-//! \param[in] max Maximum bound for volume fraction
-//! \param[in] al_gp Volume fraction at the quadrature point
-//! \param[in] al_avg Cell-average volume fraction
-//! \return The limiting coefficient from the bound-preserving limiter function
-// *****************************************************************************
-{
-  tk::real phi(1.0), al_diff(0.0);
-  al_diff = al_gp - al_avg;
-  if(al_gp > max && fabs(al_diff) > 1e-15)
-    phi = std::fabs( (max - al_avg) / al_diff );
-  else if(al_gp < min && fabs(al_diff) > 1e-15)
-    phi = std::fabs( (min - al_avg) / al_diff );
-  return phi;
-}
-
-void PositivityLimitingMultiMat( std::size_t nmat,
-                                 const std::vector< inciter::EOS >& mat_blk,
-                                 std::size_t rdof,
-                                 std::size_t ndof_el,
-                                 std::size_t e,
-                                 const std::vector< std::size_t >& inpoel,
-                                 const tk::UnsMesh::Coords& coord,
-                                 const tk::Fields& U,
-                                 const tk::Fields& P,
-                                 std::vector< tk::real >& phic_p1,
-                                 std::vector< tk::real >& phic_p2,
-                                 std::vector< tk::real >& phip_p1,
-                                 std::vector< tk::real >& phip_p2 )
-// *****************************************************************************
-//  Positivity preserving limiter for multi-material solver
-//! \param[in] nmat Number of materials in this PDE system
-//! \param[in] mat_blk EOS material block
-//! \param[in] rdof Total number of reconstructed dofs
-//! \param[in] ndof_el Number of dofs for element e
-//! \param[in] e Element being checked for consistency
-//! \param[in] inpoel Element connectivity
-//! \param[in] coord Array of nodal coordinates
-//! \param[in] U Vector of conservative variables
-//! \param[in] P Vector of primitive variables
-//! \param[in,out] phic_p1 Vector of limiter functions for P1 dofs of the
-//!   conserved quantities
-//! \param[in,out] phic_p2 Vector of limiter functions for P2 dofs of the
-//!   conserved quantities
-//! \param[in,out] phip_p1 Vector of limiter functions for P1 dofs of the
-//!   primitive quantities
-//! \param[in,out] phip_p2 Vector of limiter functions for P2 dofs of the
-//!   primitive quantities
-// *****************************************************************************
-{
-  const auto ncomp = U.nprop() / rdof;
-  const auto nprim = P.nprop() / rdof;
-
-  const auto& cx = coord[0];
-  const auto& cy = coord[1];
-  const auto& cz = coord[2];
-
-  // Extract the element coordinates
-  std::array< std::array< tk::real, 3>, 4 > coordel {{
-    {{ cx[ inpoel[4*e  ] ], cy[ inpoel[4*e  ] ], cz[ inpoel[4*e  ] ] }},
-    {{ cx[ inpoel[4*e+1] ], cy[ inpoel[4*e+1] ], cz[ inpoel[4*e+1] ] }},
-    {{ cx[ inpoel[4*e+2] ], cy[ inpoel[4*e+2] ], cz[ inpoel[4*e+2] ] }},
-    {{ cx[ inpoel[4*e+3] ], cy[ inpoel[4*e+3] ], cz[ inpoel[4*e+3] ] }} }};
-
-  // Compute the determinant of Jacobian matrix
-  auto detT =
-    tk::Jacobian( coordel[0], coordel[1], coordel[2], coordel[3] );
-
-  std::vector< tk::real > phic_bound(ncomp, 1.0);
-  std::vector< tk::real > phip_bound(nprim, 1.0);
-
-  const tk::real min = 1e-15;
-
-  for (std::size_t lf=0; lf<4; ++lf)
-  {
-    std::array< std::size_t, 3 > inpofa_l {{ inpoel[4*e+tk::lpofa[lf][0]],
-                                             inpoel[4*e+tk::lpofa[lf][1]],
-                                             inpoel[4*e+tk::lpofa[lf][2]] }};
-
-    std::array< std::array< tk::real, 3>, 3 > coordfa {{
-      {{ cx[ inpofa_l[0] ], cy[ inpofa_l[0] ], cz[ inpofa_l[0] ] }},
-      {{ cx[ inpofa_l[1] ], cy[ inpofa_l[1] ], cz[ inpofa_l[1] ] }},
-      {{ cx[ inpofa_l[2] ], cy[ inpofa_l[2] ], cz[ inpofa_l[2] ] }} }};
-
-    auto ng = tk::NGfa(ndof_el);
-
-    std::array< std::vector< tk::real >, 2 > coordgp;
-    std::vector< tk::real > wgp;
-
-    coordgp[0].resize( ng );
-    coordgp[1].resize( ng );
-    wgp.resize( ng );
-
-    tk::GaussQuadratureTri( ng, coordgp, wgp );
-
-    for (std::size_t igp=0; igp<ng; ++igp)
-    {
-      auto gp = tk::eval_gp( igp, coordfa, coordgp );
-      auto B = tk::eval_basis( ndof_el,
-            tk::Jacobian( coordel[0], gp, coordel[2], coordel[3] ) / detT,
-            tk::Jacobian( coordel[0], coordel[1], gp, coordel[3] ) / detT,
-            tk::Jacobian( coordel[0], coordel[1], coordel[2], gp ) / detT );
-
-      auto state = eval_state(ncomp, rdof, ndof_el, e, U, B);
-      auto sprim = eval_state(nprim, rdof, ndof_el, e, P, B);
-
-      for(std::size_t imat = 0; imat < nmat; imat++)
-      {
-        tk::real phi_rho(1.0), phi_rhoe(1.0), phi_pre(1.0);<--- phi_rho is assigned<--- phi_rhoe is assigned<--- phi_pre is assigned
-        // Evaluate the limiting coefficient for material density
-        auto rho = state[densityIdx(nmat, imat)];
-        auto rho_avg = U(e, densityDofIdx(nmat, imat, rdof, 0));
-        phi_rho = PositivityLimiting(min, rho, rho_avg);<--- phi_rho is overwritten
-        phic_bound[densityIdx(nmat, imat)] =
-          std::min(phic_bound[densityIdx(nmat, imat)], phi_rho);
-        // Evaluate the limiting coefficient for material energy
-        auto rhoe = state[energyIdx(nmat, imat)];
-        auto rhoe_avg = U(e, energyDofIdx(nmat, imat, rdof, 0));
-        phi_rhoe = PositivityLimiting(min, rhoe, rhoe_avg);<--- phi_rhoe is overwritten
-        phic_bound[energyIdx(nmat, imat)] =
-          std::min(phic_bound[energyIdx(nmat, imat)], phi_rhoe);
-        // Evaluate the limiting coefficient for material pressure
-        auto min_pre = std::max(min, state[volfracIdx(nmat, imat)] *
-          mat_blk[imat].compute< EOS::min_eff_pressure >(min, rho,
-          state[volfracIdx(nmat, imat)]));
-        auto pre = sprim[pressureIdx(nmat, imat)];
-        auto pre_avg = P(e, pressureDofIdx(nmat, imat, rdof, 0));
-        phi_pre = PositivityLimiting(min_pre, pre, pre_avg);<--- phi_pre is overwritten
-        phip_bound[pressureIdx(nmat, imat)] =
-          std::min(phip_bound[pressureIdx(nmat, imat)], phi_pre);
-      }
-    }
-  }
-
-  if(ndof_el > 4)
-  {
-    auto ng = tk::NGvol(ndof_el);
-    std::array< std::vector< tk::real >, 3 > coordgp;
-    std::vector< tk::real > wgp;
-
-    coordgp[0].resize( ng );
-    coordgp[1].resize( ng );
-    coordgp[2].resize( ng );
-    wgp.resize( ng );
-
-    tk::GaussQuadratureTet( ng, coordgp, wgp );
-
-    for (std::size_t igp=0; igp<ng; ++igp)
-    {
-      auto B = tk::eval_basis( ndof_el, coordgp[0][igp], coordgp[1][igp],
-        coordgp[2][igp] );
-
-      auto state = eval_state(ncomp, rdof, ndof_el, e, U, B);
-      auto sprim = eval_state(nprim, rdof, ndof_el, e, P, B);
-
-      for(std::size_t imat = 0; imat < nmat; imat++)
-      {
-        tk::real phi_rho(1.0), phi_rhoe(1.0), phi_pre(1.0);<--- phi_rho is assigned<--- phi_rhoe is assigned<--- phi_pre is assigned
-        // Evaluate the limiting coefficient for material density
-        auto rho = state[densityIdx(nmat, imat)];
-        auto rho_avg = U(e, densityDofIdx(nmat, imat, rdof, 0));
-        phi_rho = PositivityLimiting(min, rho, rho_avg);<--- phi_rho is overwritten
-        phic_bound[densityIdx(nmat, imat)] =
-          std::min(phic_bound[densityIdx(nmat, imat)], phi_rho);
-        // Evaluate the limiting coefficient for material energy
-        auto rhoe = state[energyIdx(nmat, imat)];
-        auto rhoe_avg = U(e, energyDofIdx(nmat, imat, rdof, 0));
-        phi_rhoe = PositivityLimiting(min, rhoe, rhoe_avg);<--- phi_rhoe is overwritten
-        phic_bound[energyIdx(nmat, imat)] =
-          std::min(phic_bound[energyIdx(nmat, imat)], phi_rhoe);
-        // Evaluate the limiting coefficient for material pressure
-        auto min_pre = std::max(min, state[volfracIdx(nmat, imat)] *
-          mat_blk[imat].compute< EOS::min_eff_pressure >(min, rho,
-          state[volfracIdx(nmat, imat)]));
-        auto pre = sprim[pressureIdx(nmat, imat)];
-        auto pre_avg = P(e, pressureDofIdx(nmat, imat, rdof, 0));
-        phi_pre = PositivityLimiting(min_pre, pre, pre_avg);<--- phi_pre is overwritten
-        phip_bound[pressureIdx(nmat, imat)] =
-          std::min(phip_bound[pressureIdx(nmat, imat)], phi_pre);
-      }
-    }
-  }
-
-  // apply new bounds to material quantities
-  for (std::size_t k=0; k<nmat; ++k) {
-    // mat density
-    phic_p1[densityIdx(nmat, k)] = std::min( phic_bound[densityIdx(nmat, k)],
-      phic_p1[densityIdx(nmat, k)] );
-    // mat energy
-    phic_p1[energyIdx(nmat, k)] = std::min( phic_bound[energyIdx(nmat, k)],
-      phic_p1[energyIdx(nmat, k)] );
-    // mat pressure
-    phip_p1[pressureIdx(nmat, k)] = std::min( phip_bound[pressureIdx(nmat, k)],
-      phip_p1[pressureIdx(nmat, k)] );
-
-    // for dgp2
-    if (ndof_el > 4) {
-      // mat density
-      phic_p2[densityIdx(nmat, k)] = std::min( phic_bound[densityIdx(nmat, k)],
-        phic_p2[densityIdx(nmat, k)] );
-      // mat energy
-      phic_p2[energyIdx(nmat, k)] = std::min( phic_bound[energyIdx(nmat, k)],
-        phic_p2[energyIdx(nmat, k)] );
-      // mat pressure
-      phip_p2[pressureIdx(nmat, k)] = std::min( phip_bound[pressureIdx(nmat, k)],
-        phip_p2[pressureIdx(nmat, k)] );
-    }
-  }
-}
-
-void PositivityPreservingMultiMat_FV(
-  const std::vector< std::size_t >& inpoel,
-  std::size_t nelem,
-  std::size_t nmat,
-  const std::vector< inciter::EOS >& mat_blk,
-  const tk::UnsMesh::Coords& coord,
-  const tk::Fields& /*geoFace*/,
-  tk::Fields& U,
-  tk::Fields& P )
-// *****************************************************************************
-//  Positivity preserving limiter for the FV multi-material solver
-//! \param[in] inpoel Element connectivity
-//! \param[in] nelem Number of elements
-//! \param[in] nmat Number of materials in this PDE system
-//! \param[in] mat_blk Material EOS block
-//! \param[in] coord Array of nodal coordinates
-////! \param[in] geoFace Face geometry array
-//! \param[in,out] U High-order solution vector which gets limited
-//! \param[in,out] P High-order vector of primitives which gets limited
-//! \details This positivity preserving limiter function should be called for
-//!   FV multimat.
-// *****************************************************************************
-{
-  const auto rdof = inciter::g_inputdeck.get< tag::rdof >();
-  const auto ncomp = U.nprop() / rdof;
-  const auto nprim = P.nprop() / rdof;
-
-  const auto& cx = coord[0];
-  const auto& cy = coord[1];
-  const auto& cz = coord[2];
-
-  for (std::size_t e=0; e<nelem; ++e)
-  {
-    // Extract the element coordinates
-    std::array< std::array< tk::real, 3>, 4 > coordel {{
-      {{ cx[ inpoel[4*e  ] ], cy[ inpoel[4*e  ] ], cz[ inpoel[4*e  ] ] }},
-      {{ cx[ inpoel[4*e+1] ], cy[ inpoel[4*e+1] ], cz[ inpoel[4*e+1] ] }},
-      {{ cx[ inpoel[4*e+2] ], cy[ inpoel[4*e+2] ], cz[ inpoel[4*e+2] ] }},
-      {{ cx[ inpoel[4*e+3] ], cy[ inpoel[4*e+3] ], cz[ inpoel[4*e+3] ] }} }};
-
-    // Compute the determinant of Jacobian matrix
-    auto detT =
-      tk::Jacobian( coordel[0], coordel[1], coordel[2], coordel[3] );
-
-    std::vector< tk::real > phic(ncomp, 1.0);
-    std::vector< tk::real > phip(nprim, 1.0);
-
-    const tk::real min = 1e-15;
-
-    // 1. Enforce positive density (total energy will be positive if pressure
-    //    and density are positive)
-    for (std::size_t lf=0; lf<4; ++lf)
-    {
-      std::array< std::size_t, 3 > inpofa_l {{ inpoel[4*e+tk::lpofa[lf][0]],
-                                               inpoel[4*e+tk::lpofa[lf][1]],
-                                               inpoel[4*e+tk::lpofa[lf][2]] }};
-
-      // face coordinates
-      std::array< std::array< tk::real, 3>, 3 > coordfa {{
-        {{ cx[ inpofa_l[0] ], cy[ inpofa_l[0] ], cz[ inpofa_l[0] ] }},
-        {{ cx[ inpofa_l[1] ], cy[ inpofa_l[1] ], cz[ inpofa_l[1] ] }},
-        {{ cx[ inpofa_l[2] ], cy[ inpofa_l[2] ], cz[ inpofa_l[2] ] }} }};
-
-      // face centroid
-      std::array< tk::real, 3 > fc{{
-        (coordfa[0][0]+coordfa[1][0]+coordfa[2][0])/3.0 ,
-        (coordfa[0][1]+coordfa[1][1]+coordfa[2][1])/3.0 ,
-        (coordfa[0][2]+coordfa[1][2]+coordfa[2][2])/3.0 }};
-
-      auto B = tk::eval_basis( rdof,
-            tk::Jacobian( coordel[0], fc, coordel[2], coordel[3] ) / detT,
-            tk::Jacobian( coordel[0], coordel[1], fc, coordel[3] ) / detT,
-            tk::Jacobian( coordel[0], coordel[1], coordel[2], fc ) / detT );
-      auto state = eval_state(ncomp, rdof, rdof, e, U, B);
-
-      for(std::size_t i=0; i<nmat; i++)
-      {
-        // Evaluate the limiting coefficient for material density
-        auto rho = state[densityIdx(nmat, i)];
-        auto rho_avg = U(e, densityDofIdx(nmat, i, rdof, 0));
-        auto phi_rho = PositivityLimiting(min, rho, rho_avg);
-        phic[densityIdx(nmat, i)] =
-          std::min(phic[densityIdx(nmat, i)], phi_rho);
-      }
-    }
-    // apply limiter coefficient
-    for(std::size_t i=0; i<nmat; i++)
-    {
-      U(e, densityDofIdx(nmat,i,rdof,1)) *= phic[densityIdx(nmat,i)];
-      U(e, densityDofIdx(nmat,i,rdof,2)) *= phic[densityIdx(nmat,i)];
-      U(e, densityDofIdx(nmat,i,rdof,3)) *= phic[densityIdx(nmat,i)];
-    }
-
-    // 2. Enforce positive pressure (assuming density is positive)
-    for (std::size_t lf=0; lf<4; ++lf)
-    {
-      std::array< std::size_t, 3 > inpofa_l {{ inpoel[4*e+tk::lpofa[lf][0]],
-                                               inpoel[4*e+tk::lpofa[lf][1]],
-                                               inpoel[4*e+tk::lpofa[lf][2]] }};
-
-      // face coordinates
-      std::array< std::array< tk::real, 3>, 3 > coordfa {{
-        {{ cx[ inpofa_l[0] ], cy[ inpofa_l[0] ], cz[ inpofa_l[0] ] }},
-        {{ cx[ inpofa_l[1] ], cy[ inpofa_l[1] ], cz[ inpofa_l[1] ] }},
-        {{ cx[ inpofa_l[2] ], cy[ inpofa_l[2] ], cz[ inpofa_l[2] ] }} }};
-
-      // face centroid
-      std::array< tk::real, 3 > fc{{
-        (coordfa[0][0]+coordfa[1][0]+coordfa[2][0])/3.0 ,
-        (coordfa[0][1]+coordfa[1][1]+coordfa[2][1])/3.0 ,
-        (coordfa[0][2]+coordfa[1][2]+coordfa[2][2])/3.0 }};
-
-      auto B = tk::eval_basis( rdof,
-            tk::Jacobian( coordel[0], fc, coordel[2], coordel[3] ) / detT,
-            tk::Jacobian( coordel[0], coordel[1], fc, coordel[3] ) / detT,
-            tk::Jacobian( coordel[0], coordel[1], coordel[2], fc ) / detT );
-      auto state = eval_state(ncomp, rdof, rdof, e, U, B);
-      auto sprim = eval_state(nprim, rdof, rdof, e, P, B);
-
-      for(std::size_t i=0; i<nmat; i++)
-      {
-        tk::real phi_pre(1.0);<--- phi_pre is assigned
-        // Evaluate the limiting coefficient for material pressure
-        auto rho = state[densityIdx(nmat, i)];
-        auto min_pre = std::max(min, U(e,volfracDofIdx(nmat,i,rdof,0)) *
-          mat_blk[i].compute< EOS::min_eff_pressure >(min, rho,
-          U(e,volfracDofIdx(nmat,i,rdof,0))));
-        auto pre = sprim[pressureIdx(nmat, i)];
-        auto pre_avg = P(e, pressureDofIdx(nmat, i, rdof, 0));
-        phi_pre = PositivityLimiting(min_pre, pre, pre_avg);<--- phi_pre is overwritten
-        phip[pressureIdx(nmat, i)] =
-          std::min(phip[pressureIdx(nmat, i)], phi_pre);
-      }
-    }
-    // apply limiter coefficient
-    for(std::size_t i=0; i<nmat; i++)
-    {
-      P(e, pressureDofIdx(nmat,i,rdof,1)) *= phip[pressureIdx(nmat,i)];
-      P(e, pressureDofIdx(nmat,i,rdof,2)) *= phip[pressureIdx(nmat,i)];
-      P(e, pressureDofIdx(nmat,i,rdof,3)) *= phip[pressureIdx(nmat,i)];
-    }
-  }
-}
-
-tk::real
-PositivityLimiting( const tk::real min,
-                    const tk::real u_gp,
-                    const tk::real u_avg )
-// *****************************************************************************
-//  Positivity-preserving limiter function
-//! \param[in] min Minimum bound for volume fraction
-//! \param[in] u_gp Variable quantity at the quadrature point
-//! \param[in] u_avg Cell-average variable quantitiy
-//! \return The limiting coefficient from the positivity-preserving limiter
-//!   function
-// *****************************************************************************
-{
-  tk::real phi(1.0);
-  tk::real diff = u_gp - u_avg;
-  // Only when u_gp is less than minimum threshold and the high order
-  // contribution is not zero, the limiting function will be applied
-  if(u_gp < min)
-    phi = std::fabs( (min - u_avg) / (diff+std::copysign(1e-15,diff)) );
-  return phi;
-}
-
-bool
-interfaceIndicator( std::size_t nmat,
-  const std::vector< tk::real >& al,
-  std::vector< std::size_t >& matInt )
-// *****************************************************************************
-//  Interface indicator function, which checks element for material interface
-//! \param[in] nmat Number of materials in this PDE system
-//! \param[in] al Cell-averaged volume fractions
-//! \param[in] matInt Array indicating which material has an interface
-//! \return Boolean which indicates if the element contains a material interface
-// *****************************************************************************
-{
-  bool intInd = false;
-
-  // limits under which compression is to be performed
-  auto al_eps = 1e-08;
-  auto loLim = 2.0 * al_eps;
-  auto hiLim = 1.0 - loLim;
-
-  auto almax = 0.0;
-  for (std::size_t k=0; k<nmat; ++k)
-  {
-    almax = std::max(almax, al[k]);
-    matInt[k] = 0;
-    if ((al[k] > loLim) && (al[k] < hiLim)) matInt[k] = 1;
-  }
-
-  if ((almax > loLim) && (almax < hiLim)) intInd = true;
-
-  return intInd;
-}
-
-void MarkShockCells ( const std::size_t nelem,
-                      const std::size_t nmat,
-                      const std::size_t ndof,
-                      const std::size_t rdof,
-                      const std::vector< inciter::EOS >& mat_blk,
-                      const std::vector< std::size_t >& ndofel,
-                      const std::vector< std::size_t >& inpoel,
-                      const tk::UnsMesh::Coords& coord,
-                      const inciter::FaceData& fd,
-                      [[maybe_unused]] const tk::Fields& geoFace,
-                      const tk::Fields& geoElem,
-                      const tk::FluxFn& flux,
-                      const std::vector< std::size_t >& solidx,
-                      const tk::Fields& U,
-                      const tk::Fields& P,
-                      std::vector< std::size_t >& shockmarker )
-// *****************************************************************************
-//  Mark the cells that contain discontinuity according to the interface
-//    condition
-//! \param[in] nelem Number of elements
-//! \param[in] nmat Number of materials in this PDE system
-//! \param[in] ndof Maximum number of degrees of freedom
-//! \param[in] rdof Maximum number of reconstructed degrees of freedom
-//! \param[in] mat_blk EOS material block
-//! \param[in] ndofel Vector of local number of degrees of freedome
-//! \param[in] inpoel Element-node connectivity
-//! \param[in] coord Array of nodal coordinates
-//! \param[in] fd Face connectivity and boundary conditions object
-//! \param[in] geoFace Face geometry array
-//! \param[in] geoElem Element geometry array
-//! \param[in] flux Flux function to use
-//! \param[in] solidx Solid material index indicator
-//! \param[in] U Solution vector at recent time step
-//! \param[in] P Vector of primitives at recent time step
-//! \param[in, out] shockmarker Vector of the shock indicator
-//! \details This function computes the discontinuity indicator based on
-//!   interface conditon. It is based on the following paper:
-//!   Hong L., Gianni A., Robert N. (2021) A moving discontinuous Galerkin
-//!   finite element method with interface condition enforcement for
-//!   compressible flows. Journal of Computational Physics,
-//!   doi: https://doi.org/10.1016/j.jcp.2021.110618
-// *****************************************************************************
-{
-  const auto coeff = g_inputdeck.get< tag::shock_detector_coeff >();
-
-  std::vector< tk::real > IC(U.nunk(), 0.0);
-  const auto& esuf = fd.Esuf();
-  const auto& inpofa = fd.Inpofa();
-
-  const auto& cx = coord[0];
-  const auto& cy = coord[1];
-  const auto& cz = coord[2];
-
-  auto ncomp = U.nprop()/rdof;<--- Variable 'ncomp' is assigned a value that is never used.
-  auto nprim = P.nprop()/rdof;<--- Variable 'nprim' is assigned a value that is never used.
-
-  // The interface-conservation based indicator will only evaluate the flux jump
-  // for the momentum equations
-  std::set< std::size_t > vars;
-  if(nmat > 1) {          // multi-material flow
-    for (std::size_t i=0; i<3; ++i) vars.insert(momentumIdx(nmat, i));
-  } else {                // single-material flow
-    for (std::size_t i=1; i<=3; ++i) vars.insert(i);
-  }
-
-  // Loop over faces
-  for (auto f=fd.Nbfac(); f<esuf.size()/2; ++f) {
-    Assert( esuf[2*f] > -1 && esuf[2*f+1] > -1, "Interior element detected "
-            "as -1" );
-
-    std::size_t el = static_cast< std::size_t >(esuf[2*f]);
-    std::size_t er = static_cast< std::size_t >(esuf[2*f+1]);
-
-    // When the number of gauss points for the left and right element are
-    // different, choose the larger ng
-    auto ng_l = tk::NGfa(ndofel[el]);
-    auto ng_r = tk::NGfa(ndofel[er]);
-
-    auto ng = std::max( ng_l, ng_r );
-
-    std::array< std::vector< tk::real >, 2 > coordgp
-      { std::vector<tk::real>(ng), std::vector<tk::real>(ng) };
-    std::vector< tk::real > wgp( ng );
-
-    tk::GaussQuadratureTri( ng, coordgp, wgp );
-
-    // Extract the element coordinates
-    std::array< std::array< tk::real, 3>, 4 > coordel_l {{
-      {{ cx[ inpoel[4*el  ] ], cy[ inpoel[4*el  ] ], cz[ inpoel[4*el  ] ] }},
-      {{ cx[ inpoel[4*el+1] ], cy[ inpoel[4*el+1] ], cz[ inpoel[4*el+1] ] }},
-      {{ cx[ inpoel[4*el+2] ], cy[ inpoel[4*el+2] ], cz[ inpoel[4*el+2] ] }},
-      {{ cx[ inpoel[4*el+3] ], cy[ inpoel[4*el+3] ], cz[ inpoel[4*el+3] ] }} }};
-
-    std::array< std::array< tk::real, 3>, 4 > coordel_r {{
-      {{ cx[ inpoel[4*er  ] ], cy[ inpoel[4*er  ] ], cz[ inpoel[4*er  ] ] }},
-      {{ cx[ inpoel[4*er+1] ], cy[ inpoel[4*er+1] ], cz[ inpoel[4*er+1] ] }},
-      {{ cx[ inpoel[4*er+2] ], cy[ inpoel[4*er+2] ], cz[ inpoel[4*er+2] ] }},
-      {{ cx[ inpoel[4*er+3] ], cy[ inpoel[4*er+3] ], cz[ inpoel[4*er+3] ] }} }};
-
-    // Compute the determinant of Jacobian matrix
-    auto detT_l =
-      tk::Jacobian( coordel_l[0], coordel_l[1], coordel_l[2], coordel_l[3] );
-    auto detT_r =
-      tk::Jacobian( coordel_r[0], coordel_r[1], coordel_r[2], coordel_r[3] );
-
-    std::array< std::array< tk::real, 3>, 3 > coordfa {{
-      {{ cx[ inpofa[3*f  ] ], cy[ inpofa[3*f  ] ], cz[ inpofa[3*f  ] ] }},
-      {{ cx[ inpofa[3*f+1] ], cy[ inpofa[3*f+1] ], cz[ inpofa[3*f+1] ] }},
-      {{ cx[ inpofa[3*f+2] ], cy[ inpofa[3*f+2] ], cz[ inpofa[3*f+2] ] }} }};
-
-    std::array< tk::real, 3 >
-      fn{{ geoFace(f,1), geoFace(f,2), geoFace(f,3) }};
-
-    // Numerator and denominator of the shock indicator
-    tk::real numer(0.0), denom(0.0);
-    std::vector< tk::real > fl_jump, fl_avg;
-    fl_jump.resize(3, 0.0);
-    fl_avg.resize(3, 0.0);
-
-    for (std::size_t igp=0; igp<ng; ++igp) {
-      auto gp = tk::eval_gp( igp, coordfa, coordgp );
-      std::size_t dof_el, dof_er;
-      if (rdof > ndof)
-      {
-        dof_el = rdof;
-        dof_er = rdof;
-      }
-      else
-      {
-        dof_el = ndofel[el];
-        dof_er = ndofel[er];
-      }
-      std::array< tk::real, 3> ref_gp_l{
-        tk::Jacobian( coordel_l[0], gp, coordel_l[2], coordel_l[3] ) / detT_l,
-        tk::Jacobian( coordel_l[0], coordel_l[1], gp, coordel_l[3] ) / detT_l,
-        tk::Jacobian( coordel_l[0], coordel_l[1], coordel_l[2], gp ) / detT_l };
-      std::array< tk::real, 3> ref_gp_r{
-        tk::Jacobian( coordel_r[0], gp, coordel_r[2], coordel_r[3] ) / detT_r,
-        tk::Jacobian( coordel_r[0], coordel_r[1], gp, coordel_r[3] ) / detT_r,
-        tk::Jacobian( coordel_r[0], coordel_r[1], coordel_r[2], gp ) / detT_r };
-      auto B_l = tk::eval_basis( dof_el, ref_gp_l[0], ref_gp_l[1], ref_gp_l[2] );
-      auto B_r = tk::eval_basis( dof_er, ref_gp_r[0], ref_gp_r[1], ref_gp_r[2] );
-
-      std::array< std::vector< tk::real >, 2 > state;
-
-      // Evaluate the high order solution at the qudrature point
-      state[0] = tk::evalPolynomialSol(mat_blk, 0, ncomp, nprim, rdof,
-        nmat, el, dof_el, inpoel, coord, geoElem, ref_gp_l, B_l, U, P);
-      state[1] = tk::evalPolynomialSol(mat_blk, 0, ncomp, nprim, rdof,
-        nmat, er, dof_er, inpoel, coord, geoElem, ref_gp_r, B_r, U, P);
-
-      Assert( state[0].size() == ncomp+nprim, "Incorrect size for "
-              "appended boundary state vector" );
-      Assert( state[1].size() == ncomp+nprim, "Incorrect size for "
-              "appended boundary state vector" );
-
-      // Force deformation unknown to first order
-      for (std::size_t k=0; k<nmat; ++k)
-        if (solidx[k] > 0)
-          for (std::size_t i=0; i<3; ++i)
-            for (std::size_t j=0; j<3; ++j)
-            {
-              state[0][deformIdx(nmat, solidx[k], i, j)] = U(el,deformDofIdx(
-                nmat, solidx[k], i, j, rdof, 0));
-              state[1][deformIdx(nmat, solidx[k], i, j)] = U(er,deformDofIdx(
-                nmat, solidx[k], i, j, rdof, 0));
-            }
-
-      // Evaluate the flux
-      auto fl = flux( ncomp, mat_blk, state[0], {} );
-      auto fr = flux( ncomp, mat_blk, state[1], {} );
-
-      std::size_t i(0);
-      for (const auto& c : vars) {
-        tk::real fn_l(0.0), fn_r(0.0);
-        for(std::size_t idir = 0; idir < 3; idir++) {
-          fn_l += fl[c][idir] * fn[idir];
-          fn_r += fr[c][idir] * fn[idir];
-        }
-        fl_jump[i] += wgp[igp] * (fn_l - fn_r) * (fn_l - fn_r);
-        fl_avg[i]  += wgp[igp] * (fn_l + fn_r) * (fn_l + fn_r) * 0.25;
-        ++i;
-      }
-    }
-
-    // Evaluate the numerator and denominator
-    for(std::size_t idir = 0; idir < 3; idir++) {
-      numer += std::sqrt(fl_jump[idir]);
-      denom += std::sqrt(fl_avg[idir]);
-    }
-
-    tk::real Ind(0.0);
-    if(denom > 1e-8)
-      Ind = numer / denom;
-    IC[el] = std::max(IC[el], Ind);
-    IC[er] = std::max(IC[er], Ind);
-  }
-
-  tk::real power = 0.0;
-  if(rdof == 10)  power = 1.5;
-  else            power = 1.0;
-
-  // Loop over element to mark shock cell
-  for (std::size_t e=0; e<nelem; ++e) {
-    // Evaluate the threshold
-    auto thres = coeff * std::pow(geoElem(e, 4), power);
-    if(IC[e] > thres)
-      shockmarker[e] = 1;
-    else
-      shockmarker[e] = 0;
-  }
-}
-
-void
-correctLimConservMultiMat(
-  std::size_t nelem,
-  const std::vector< EOS >& mat_blk,
-  std::size_t nmat,
-  const std::vector< std::size_t >& inpoel,
-  const tk::UnsMesh::Coords& coord,
-  const tk::Fields& geoElem,
-  const tk::Fields& prim,
-  tk::Fields& unk )
-// *****************************************************************************
-//  Update the conservative quantities after limiting for multi-material systems
-//! \param[in] nelem Number of internal elements
-//! \param[in] mat_blk EOS material block
-//! \param[in] nmat Number of materials in this PDE system
-//! \param[in] inpoel Element-node connectivity
-//! \param[in] coord Array of nodal coordinates
-//! \param[in] geoElem Element geometry array
-//! \param[in] prim Array of primitive variables
-//! \param[in,out] unk Array of conservative variables
-//! \details This function computes the updated dofs for conservative
-//!   quantities based on the limited primitive quantities, to re-instate
-//!   consistency between the limited primitive and evolved quantities. For
-//!   further details, see Pandare et al. (2023). On the Design of Stable,
-//!   Consistent, and Conservative High-Order Methods for Multi-Material
-//!   Hydrodynamics. J Comp Phys, 112313.
-// *****************************************************************************
-{
-  const auto rdof = g_inputdeck.get< tag::rdof >();
-  std::size_t ncomp = unk.nprop()/rdof;
-  std::size_t nprim = prim.nprop()/rdof;
-  const auto intsharp = inciter::g_inputdeck.get< tag::multimat,
-    tag::intsharp >();
-
-  for (std::size_t e=0; e<nelem; ++e) {
-    // Here we pre-compute the right-hand-side vector. The reason that the
-    // lhs in DG.cpp is not used is that the size of this vector in this
-    // projection procedure should be rdof instead of ndof.
-    auto L = tk::massMatrixDubiner(rdof, geoElem(e,0));
-
-    // The right-hand side vector is sized as nprim, i.e. the primitive quantity
-    // vector. However, it stores the consistently obtained values of evolved
-    // quantities, since nprim is the number of evolved quantities that need to
-    // be evaluated consistently. For this reason, accessing R will require
-    // the primitive quantity accessors. But this access is intended to give
-    // the corresponding evolved quantites, as follows:
-    // pressureIdx() - mat. total energy
-    // velocityIdx() - bulk momentum components
-    // stressIdx() - mat. inverse deformation gradient tensor components
-    std::vector< tk::real > R(nprim*rdof, 0.0);
-
-    auto ng = tk::NGvol(rdof);
-
-    // Arrays for quadrature points
-    std::array< std::vector< tk::real >, 3 > coordgp;
-    std::vector< tk::real > wgp;
-
-    coordgp[0].resize( ng );
-    coordgp[1].resize( ng );
-    coordgp[2].resize( ng );
-    wgp.resize( ng );
-
-    tk::GaussQuadratureTet( ng, coordgp, wgp );
-
-    // Loop over quadrature points in element e
-    for (std::size_t igp=0; igp<ng; ++igp) {
-      // Compute the basis function
-      auto B = tk::eval_basis( rdof, coordgp[0][igp], coordgp[1][igp],
-                               coordgp[2][igp] );
-
-      auto w = wgp[igp] * geoElem(e, 0);
-
-      // Evaluate the solution at quadrature point
-      auto state = evalPolynomialSol(mat_blk, intsharp, ncomp, nprim,
-        rdof, nmat, e, rdof, inpoel, coord, geoElem,
-        {{coordgp[0][igp], coordgp[1][igp], coordgp[2][igp]}}, B, unk, prim);
-
-      // Solution vector that stores the material energy and bulk momentum
-      std::vector< tk::real > s(nprim, 0.0);
-
-      // Bulk density at quadrature point
-      tk::real rhob(0.0);
-      for (std::size_t k=0; k<nmat; ++k)
-        rhob += state[densityIdx(nmat, k)];
-
-      // Velocity vector at quadrature point
-      std::array< tk::real, 3 >
-        vel{ state[ncomp+velocityIdx(nmat, 0)],
-             state[ncomp+velocityIdx(nmat, 1)],
-             state[ncomp+velocityIdx(nmat, 2)] };
-
-      // Compute and store the bulk momentum
-      for(std::size_t idir = 0; idir < 3; idir++)
-        s[velocityIdx(nmat, idir)] = rhob * vel[idir];
-
-      // Compute and store material energy at quadrature point
-      for(std::size_t imat = 0; imat < nmat; imat++) {
-        auto alphamat = state[volfracIdx(nmat, imat)];
-        auto rhomat = state[densityIdx(nmat, imat)]/alphamat;
-        auto premat = state[ncomp+pressureIdx(nmat, imat)]/alphamat;
-        auto gmat = getDeformGrad(nmat, imat, state);
-        s[pressureIdx(nmat,imat)] = alphamat *
-          mat_blk[imat].compute< EOS::totalenergy >( rhomat, vel[0], vel[1],
-          vel[2], premat, gmat );
-      }
-
-      // Evaluate the righ-hand-side vector
-      for(std::size_t k = 0; k < nprim; k++) {
-        auto mark = k * rdof;
-        for(std::size_t idof = 0; idof < rdof; idof++)
-          R[mark+idof] += w * s[k] * B[idof];
-      }
-    }
-
-    // Update the high order dofs of the material energy
-    for(std::size_t imat = 0; imat < nmat; imat++) {
-      for(std::size_t idof = 1; idof < rdof; idof++)
-        unk(e, energyDofIdx(nmat, imat, rdof, idof)) =
-          R[pressureDofIdx(nmat,imat,rdof,idof)] / L[idof];
-    }
-
-    // Update the high order dofs of the bulk momentum
-    for(std::size_t idir = 0; idir < 3; idir++) {
-      for(std::size_t idof = 1; idof < rdof; idof++)
-        unk(e, momentumDofIdx(nmat, idir, rdof, idof)) =
-          R[velocityDofIdx(nmat,idir,rdof,idof)] / L[idof];
-    }
-  }
-}
-
-tk::real
-constrain_pressure( const std::vector< EOS >& mat_blk,
-  tk::real apr,
-  tk::real arho,
-  tk::real alpha=1.0,
-  std::size_t imat=0 )
-// *****************************************************************************
-//  Constrain material partial pressure (alpha_k * p_k)
-//! \param[in] apr Material partial pressure (alpha_k * p_k)
-//! \param[in] arho Material partial density (alpha_k * rho_k)
-//! \param[in] alpha Material volume fraction. Default is 1.0, so that for the
-//!   single-material system, this argument can be left unspecified by the
-//!   calling code
-//! \param[in] imat Material-id who's EoS is required. Default is 0, so that
-//!   for the single-material system, this argument can be left unspecified by
-//!   the calling code
-//! \return Constrained material partial pressure (alpha_k * p_k)
-// *****************************************************************************
-{
-  return std::max(apr, alpha*mat_blk[imat].compute<
-    EOS::min_eff_pressure >(1e-12, arho, alpha));
-}
-
-
-} // inciter::
+      // conservative part of volume-fraction flux
+      fl[volfracIdx(nmat, k)][0] = 0.0;
+      fl[volfracIdx(nmat, k)][1] = 0.0;
+      fl[volfracIdx(nmat, k)][2] = 0.0;
+
+      // conservative part of material continuity flux
+      fl[densityIdx(nmat, k)][0] = u * ugp[densityIdx(nmat, k)];
+      fl[densityIdx(nmat, k)][1] = v * ugp[densityIdx(nmat, k)];
+      fl[densityIdx(nmat, k)][2] = w * ugp[densityIdx(nmat, k)];
+
+      // conservative part of material total-energy flux
+      fl[energyIdx(nmat, k)][0] = u * ugp[energyIdx(nmat, k)]
+        - u * asig[k][0][0] - v * asig[k][1][0] - w * asig[k][2][0];
+      fl[energyIdx(nmat, k)][1] = v * ugp[energyIdx(nmat, k)]
+        - u * asig[k][0][1] - v * asig[k][1][1] - w * asig[k][2][1];
+      fl[energyIdx(nmat, k)][2] = w * ugp[energyIdx(nmat, k)]
+        - u * asig[k][0][2] - v * asig[k][1][2] - w * asig[k][2][2];
+
+      // conservative part of material inverse deformation gradient
+      // g_ij: \partial (g_il u_l) / \partial (x_j)
+      if (solidx[k] > 0)
+      {
+        for (std::size_t i=0; i<3; ++i)
+        {
+          for (std::size_t j=0; j<3; ++j)
+          {
+            fl[deformIdx(nmat,solidx[k],i,j)][j] =
+              u*g[k][i][0] + v*g[k][i][1] + w*g[k][i][2];
+          }
+          // other components are zero
+        }
+      }
+    }
+  }
+  else
+  {
+    tk::real p(0.0);
+    std::vector< tk::real > apk( nmat, 0.0 );
+    for (std::size_t k=0; k<nmat; ++k)
+    {
+      apk[k] = ugp[ncomp+pressureIdx(nmat,k)];
+      p += apk[k];
+    }
+
+    // conservative part of momentum flux
+    fl[momentumIdx(nmat, 0)][0] = ugp[momentumIdx(nmat, 0)] * u + p;
+    fl[momentumIdx(nmat, 1)][0] = ugp[momentumIdx(nmat, 1)] * u;
+    fl[momentumIdx(nmat, 2)][0] = ugp[momentumIdx(nmat, 2)] * u;
+
+    fl[momentumIdx(nmat, 0)][1] = ugp[momentumIdx(nmat, 0)] * v;
+    fl[momentumIdx(nmat, 1)][1] = ugp[momentumIdx(nmat, 1)] * v + p;
+    fl[momentumIdx(nmat, 2)][1] = ugp[momentumIdx(nmat, 2)] * v;
+
+    fl[momentumIdx(nmat, 0)][2] = ugp[momentumIdx(nmat, 0)] * w;
+    fl[momentumIdx(nmat, 1)][2] = ugp[momentumIdx(nmat, 1)] * w;
+    fl[momentumIdx(nmat, 2)][2] = ugp[momentumIdx(nmat, 2)] * w + p;
+
+    for (std::size_t k=0; k<nmat; ++k)
+    {
+      // conservative part of volume-fraction flux
+      fl[volfracIdx(nmat, k)][0] = 0.0;
+      fl[volfracIdx(nmat, k)][1] = 0.0;
+      fl[volfracIdx(nmat, k)][2] = 0.0;
+
+      // conservative part of material continuity flux
+      fl[densityIdx(nmat, k)][0] = u * ugp[densityIdx(nmat, k)];
+      fl[densityIdx(nmat, k)][1] = v * ugp[densityIdx(nmat, k)];
+      fl[densityIdx(nmat, k)][2] = w * ugp[densityIdx(nmat, k)];
+
+      // conservative part of material total-energy flux
+      auto hmat = ugp[energyIdx(nmat, k)] + apk[k];
+      fl[energyIdx(nmat, k)][0] = u * hmat;
+      fl[energyIdx(nmat, k)][1] = v * hmat;
+      fl[energyIdx(nmat, k)][2] = w * hmat;
+    }
+  }
+
+  return fl;
+}
+
+}// tk::
 
diff --git a/Debug/cppcheck/72.html b/Debug/cppcheck/72.html index ae026c3dd128..24a254975c4c 100644 --- a/Debug/cppcheck/72.html +++ b/Debug/cppcheck/72.html @@ -152,12 +152,12 @@
  1
@@ -302,239 +302,149 @@ 

Cppcheck report - [

// *****************************************************************************
+143
// *****************************************************************************
 /*!
-  \file      src/PDE/PDEStack.hpp
+  \file      src/PDE/MultiMat/Physics/FVEnergyPill.cpp
   \copyright 2012-2015 J. Bakosi,
              2016-2018 Los Alamos National Security, LLC.,
              2019-2021 Triad National Security, LLC.
              All rights reserved. See the LICENSE file for details.
-  \brief     Stack of differential equations
-  \details   This file declares class PDEStack, which implements various
-    functionality related to registering and instantiating partial differential
-    equation types. Registration and instantiation use a partial differential
-    equation factory, which is a std::map (an associative container),
-    associating unique partial differential equation keys to their constructor
-    calls. For more details, see the in-code documentation of the constructor.
+  \brief     Physics policy for the Euler equation governing multi-material flow
+    using a finite volume method
+  \details   This file defines a Physics policy class for the compressible
+    flow equations class fv::MultiMat, defined in PDE/MultiMat/FVMultiMat.h.
+    This specific class allows energy pill initialization of a user defined
+    box/block for multi-material flow. See PDE/MultiMat/Physics/FV.h for general
+    requirements on Physics policy classes for fv::MultiMat.
 */
 // *****************************************************************************
-#ifndef PDEStack_h
-#define PDEStack_h
-
-#include <map>
-#include <set>
-#include <string>
-#include <vector>
-#include <iostream>
+
+#include "FVEnergyPill.hpp"
+#include "Inciter/InputDeck/InputDeck.hpp"
+#include "ContainerUtil.hpp"
+#include "MultiMat/MultiMatIndexing.hpp"
+#include "NoWarning/charm++.hpp"
+
+namespace inciter {
 
-#include "NoWarning/back.hpp"
-#include "NoWarning/front.hpp"
-
-#include "Tags.hpp"
-#include "Types.hpp"
-#include "Exception.hpp"
-#include "Factory.hpp"
-#include "CGPDE.hpp"
-#include "DGPDE.hpp"
-#include "FVPDE.hpp"
-#include "PDEFactory.hpp"
-#include "Inciter/InputDeck/InputDeck.hpp"
-
-namespace inciter {
-
-extern ctr::InputDeck g_inputdeck;
-
-//! \brief Partial differential equations stack
-class PDEStack {
-
-  private:
-    using ncomp_t = tk::ncomp_t;
-
-  public:
-    //! Constructor: register partial differential equations into factory
-    explicit PDEStack();
-
-    //! Instantiate selected PDEs using continuous Galerkin discretization
-    std::vector< CGPDE > selectedCG() const;
-
-    //! Instantiate selected PDEs using discontinuous Galerkin discretization
-    std::vector< DGPDE > selectedDG() const;
-
-    //! Instantiate selected PDEs using finite volume discretization
-    std::vector< FVPDE > selectedFV() const;
-
-    //! Constant accessor to CGPDE factory
-    //! \return Constant reference to the CGPDE factory
-    const CGFactory& cgfactory() const { return m_cgfactory; }
-
-    //! Constant accessor to DGPDE factory
-    //! \return Constant reference to the DGPDE factory
-    const DGFactory& dgfactory() const { return m_dgfactory; }
-
-    //! Constant accessor to FVPDE factory
-    //! \return Constant reference to the FVPDE factory
-    const FVFactory& fvfactory() const { return m_fvfactory; }
-
-    //! Return info on selected partial differential equations
-    std::vector< std::vector< std::pair< std::string, std::string > > > info()
-    const;
-
-    //! Return number of unique equation types registered into the CG factory
-    //! \return The number of unique equation types registered into the CG
-    //!   factory the factory
-    std::size_t cgntypes() const { return m_cgEqTypes.size(); }
-
-    //! Return number of unique equation types registered into the DG factory
-    //! \return The number of unique equation types registered into the DG
-    //!   factory the factory
-    std::size_t dgntypes() const { return m_dgEqTypes.size(); }
-
-    //! Return number of unique equation types registered into the FV factory
-    //! \return The number of unique equation types registered into the FV
-    //!   factory the factory
-    std::size_t fvntypes() const { return m_fvEqTypes.size(); }
-
-  private:
-    //! \brief Instantiate a partial differential equation
-    //! \details The template argument, EqTag, is used to find the given
-    //!   partial differential equation in the input deck, the hierarchical data
-    //!   filled during control file parsing, containing user input. The
-    //!   template argument Factory specifies which factory we search in. The
-    //!   template argument PDE specifies the "base" PDE type that the
-    //!   instantiated "child" PDE class object is used polymorphically with.
-    //! \param[in] f Factory in which to search PDE in
-    //! \param[in] eq The unique partial differential equation key whose object
-    //!   to instantiate.
-    //! \param[in,out] cnt Counter, a std::map, that counts all instantiated
-    //!   partial differential equations by type.
-    template< class EqTag, class Factory, class PDE >
-    PDE createPDE( const Factory& f,
-                   ctr::PDEType eq,
-                   std::map< ctr::PDEType, ncomp_t >& cnt ) const
-    {
-      auto c = ++cnt[ eq ];   // count eqs
-      --c;                    // used to index vectors starting with 0<--- Variable 'c' is assigned a value that is never used.
-      const auto& nc = g_inputdeck.get< tag::ncomp >();
-      if ( nc ) {
-        // re-create key and search for it
-        auto prob = g_inputdeck.get< EqTag, tag::problem >();
-        // if more than one mesh, set problem type for all additional meshes
-        // as user-defined
-        if (cnt[eq] > 1) prob = ctr::ProblemType::USER_DEFINED;
-        ctr::PDEKey key{{ eq,
-          g_inputdeck.get< EqTag, tag::physics >(), prob }};
-        const auto it = f.find( key );
-        Assert( it != end( f ),
-                "Can't find PDE with key('" +
-                  ctr::PDE().name( key.get< tag::pde >() ) + "', '" +
-                  ctr::Physics().name( key.get< tag::physics >() ) + "', '" +
-                  ctr::Problem().name( key.get< tag::problem >() ) +
-                  + "') in factory" );
-        // Associate equation system index (value) to all variable offsets
-        for (ncomp_t i=0; i<nc; ++i) g_inputdeck.get<tag::sys>()[i] = c;
-        // instantiate and return PDE object
-        return it->second();
-      } else Throw ( "Can't create PDE with zero components" );
-    }
-
-    //! Wrapper of createPDE specialized for registering CG PDEs
-    //! \param[in] t Enum selecting PDE type, Control/Inciter/Options/PDE.h
-    //! \param[in,out] cnt Counter, a std::map, that counts all instantiated
-    //!   partial differential equations by type.
-    //! \details The sole reason for this function is to simplify client-code
-    //!   calling createPDE specialized to CG PDEs
-    template< class EqTag >
-    CGPDE createCG( ctr::PDEType t, std::map< ctr::PDEType, ncomp_t >& cnt )
-    const {
-      return createPDE< EqTag, CGFactory, CGPDE >( m_cgfactory, t, cnt );
-    }
-
-    //! Wrapper of createPDE specialized for registering DG PDEs
-    //! \param[in] t Enum selecting PDE type, Control/Inciter/Options/PDE.h
-    //! \param[in,out] cnt Counter, a std::map, that counts all instantiated
-    //!   partial differential equations by type.
-    //! \details The sole reason for this function is to simplify client-code
-    //!   calling createPDE specialized to DG PDEs
-    template< class EqTag >
-    DGPDE createDG( ctr::PDEType t, std::map< ctr::PDEType, ncomp_t >& cnt )
-    const {
-      return createPDE< EqTag, DGFactory, DGPDE >( m_dgfactory, t, cnt );
-    }
-
-    //! Wrapper of createPDE specialized for registering FV PDEs
-    //! \param[in] t Enum selecting PDE type, Control/Inciter/Options/PDE.h
-    //! \param[in,out] cnt Counter, a std::map, that counts all instantiated
-    //!   partial differential equations by type.
-    //! \details The sole reason for this function is to simplify client-code
-    //!   calling createPDE specialized to FV PDEs
-    template< class EqTag >
-    FVPDE createFV( ctr::PDEType t, std::map< ctr::PDEType, ncomp_t >& cnt )
-    const {
-      return createPDE< EqTag, FVFactory, FVPDE >( m_fvfactory, t, cnt );
-    }
-
-    //! PDE factory for continuous Galerkin discretization
-    CGFactory m_cgfactory;
-    //! PDE factory for discontinuous Galerkin discretization
-    DGFactory m_dgfactory;
-    //! PDE factory for finite volume discretization
-    FVFactory m_fvfactory;
-    //! Counters for equation types registered into the CG factory
-    std::set< ctr::PDEType > m_cgEqTypes;
-    //! Counters for equation types registered into the DG factory
-    std::set< ctr::PDEType > m_dgEqTypes;
-    //! Counters for equation types registered into the FV factory
-    std::set< ctr::PDEType > m_fvEqTypes;
-};
-
-} // inciter::
-
-#endif // PDEStack_h
+extern ctr::InputDeck g_inputdeck;
+
+} // inciter::
+
+using inciter::fv::MultiMatPhysicsEnergyPill;
+
+tk::real
+MultiMatPhysicsEnergyPill::dtRestriction(
+  const tk::Fields& geoElem,
+  std::size_t nelem,
+  const std::vector< int >& engSrcAd ) const
+// *****************************************************************************
+//  Compute the time step size restriction based on this physics
+//! \param[in] geoElem Element geometry array
+//! \param[in] nelem Number of elements
+//! \param[in] engSrcAd Whether the energy source was added
+//! \return Maximum allowable time step based on front propagation speed
+// *****************************************************************************
+{
+  auto mindt = std::numeric_limits< tk::real >::max();
+  // determine front propagation speed
+  const auto& icmbk = g_inputdeck.get< tag::ic, tag::meshblock >();
+  tk::real v_front(0.0);
+  for (const auto& b : icmbk) { // for all blocks
+    auto inittype = b.template get< tag::initiate >();
+    if (inittype == ctr::InitiateType::LINEAR) {
+      v_front = std::max(v_front,
+        b.template get< tag::front_speed >());
+    }
+  }
+
+  for (std::size_t e=0; e<nelem; ++e)
+  {
+    // characteristic length (radius of insphere)
+    auto dx = std::min(std::cbrt(geoElem(e,0)), geoElem(e,4))
+      /std::sqrt(24.0);
+
+    // element dt restriction if relevant energy sources were added
+    if (engSrcAd[e] > 0 && std::abs(v_front) > 1e-8)
+      mindt = std::min(mindt, dx/v_front);
+  }
+
+  return mindt;
+}
+
+void MultiMatPhysicsEnergyPill::
+physSrc(
+  std::size_t nmat,
+  tk::real t,
+  const tk::Fields& geoElem,
+  const std::unordered_map< std::size_t, std::set< std::size_t > >& elemblkid,
+  tk::Fields& R,<--- Parameter 'R' can be declared with const
+  std::vector< int >& engSrcAdded ) const
+// *****************************************************************************
+//! Compute sources corresponding to a propagating front in user-defined box
+//! \param[in] nmat Number of materials
+//! \param[in] t Physical time
+//! \param[in] geoElem Element geometry array
+//! \param[in] elemblkid Element ids associated with mesh block ids where
+//!   user ICs are set
+//! \param[in,out] R Right-hand side vector
+//! \param[in,out] engSrcAdded Whether the energy source was added
+//! \details This function adds the energy source corresponding to a
+//!   spherically growing wave-front propagating with a user-specified
+//!   velocity, within a user-configured mesh block initial condition.
+//!   Example (SI) units of the quantities involved:
+//!    * internal energy content (energy per unit volume): J/m^3
+//!    * specific energy (internal energy per unit mass): J/kg
+// *****************************************************************************
+{
+  const auto& icmbk = g_inputdeck.get< tag::ic, tag::meshblock >();
+  for (const auto& mb : icmbk) { // for all blocks
+    auto blid = mb.get< tag::blockid >();
+    if (elemblkid.find(blid) != elemblkid.end()) { // if elements exist in blk
+      const auto& initiate = mb.template get< tag::initiate >();
+      if (initiate == ctr::InitiateType::LINEAR) { // if propagating src
+
+        const auto& blkelems = tk::cref_find(elemblkid,blid);
+
+        auto enc = mb.template get< tag::energy_content >();
+        Assert( enc > 0.0, "Box energy content must be nonzero" );
+        const auto& x0_front = mb.template get< tag::point >();
+        Assert(x0_front.size()==3, "Incorrectly sized front initial location");
+        auto blkmatid = mb.template get< tag::materialid >();
+
+        // determine times at which sourcing is initialized and terminated
+        auto v_front = mb.template get< tag::front_speed >();
+        auto w_front = mb.template get< tag::front_width >();
+        auto tInit = mb.template get< tag::init_time >();
+
+        if (t >= tInit) {
+          // current radius of front
+          tk::real r_front = v_front * (t-tInit);
+          // arbitrary shape form
+          auto amplE = enc * v_front / w_front;
+
+          for (auto e : blkelems) {
+            std::array< tk::real, 3 > node{{ geoElem(e,1), geoElem(e,2),
+              geoElem(e,3) }};
+
+            auto r_e = std::sqrt(
+              (node[0]-x0_front[0])*(node[0]-x0_front[0]) +
+              (node[1]-x0_front[1])*(node[1]-x0_front[1]) +
+              (node[2]-x0_front[2])*(node[2]-x0_front[2]) );
+
+            // if element centroid lies within spherical shell add sources
+            if (r_e >= r_front && r_e <= r_front+w_front) {
+              // Add the source term to the rhs
+              R(e, energyDofIdx(nmat,blkmatid-1,1,0)) += geoElem(e,0) * amplE;
+              engSrcAdded[e] = 1;
+            }
+          }
+        }
+
+      }
+    }
+  }
+}
 
diff --git a/Debug/cppcheck/73.html b/Debug/cppcheck/73.html index a4e5073be42d..c9a632298188 100644 --- a/Debug/cppcheck/73.html +++ b/Debug/cppcheck/73.html @@ -152,2531 +152,389 @@
- - + @@ -73,7 +73,7 @@ - + @@ -89,11 +89,11 @@ - + - + diff --git a/Debug/test_coverage/Base/Timer.hpp.gcov.html b/Debug/test_coverage/Base/Timer.hpp.gcov.html index 23b3cd2288fc..cb3e156f3cdc 100644 --- a/Debug/test_coverage/Base/Timer.hpp.gcov.html +++ b/Debug/test_coverage/Base/Timer.hpp.gcov.html @@ -33,7 +33,7 @@ - + @@ -128,7 +128,7 @@ 54 : : }; 55 : : 56 : : //! Constructor: initialize clock to current time stamp. - 57 : 10959 : explicit Timer() : m_start( clock::now() ) {} + 57 : 10872 : explicit Timer() : m_start( clock::now() ) {} 58 : : 59 : : //! Zero timer 60 : 2001 : void zero() { m_start = clock::now(); } @@ -150,12 +150,12 @@ 76 : : ///@{ 77 : : //! Pack/Unpack serialize member function 78 : : //! \param[in,out] p Charm++'s PUP::er serializer object reference - 79 : 25026 : void pup( PUP::er& p ) - 80 : 25026 : { p( reinterpret_cast<char*>(&m_start), sizeof(clock::time_point) ); } + 79 : 24765 : void pup( PUP::er& p ) + 80 : 24765 : { p( reinterpret_cast<char*>(&m_start), sizeof(clock::time_point) ); } 81 : : //! \brief Pack/Unpack serialize operator| 82 : : //! \param[in,out] p Charm++'s PUP::er serializer object reference 83 : : //! \param[in,out] t Timer object reference - 84 : 25026 : friend void operator|( PUP::er& p, Timer& t ) { t.pup(p); } + 84 : 24765 : friend void operator|( PUP::er& p, Timer& t ) { t.pup(p); } 85 : : ///@} 86 : : 87 : : private: diff --git a/Debug/test_coverage/Base/Types.hpp.func-sort-c.html b/Debug/test_coverage/Base/Types.hpp.func-sort-c.html index 26db84478ed2..b1a69c3afa5e 100644 --- a/Debug/test_coverage/Base/Types.hpp.func-sort-c.html +++ b/Debug/test_coverage/Base/Types.hpp.func-sort-c.html @@ -33,7 +33,7 @@ - + diff --git a/Debug/test_coverage/Base/Types.hpp.func.html b/Debug/test_coverage/Base/Types.hpp.func.html index 3d972a815924..a026840a7663 100644 --- a/Debug/test_coverage/Base/Types.hpp.func.html +++ b/Debug/test_coverage/Base/Types.hpp.func.html @@ -33,7 +33,7 @@ - + diff --git a/Debug/test_coverage/Base/Types.hpp.gcov.html b/Debug/test_coverage/Base/Types.hpp.gcov.html index 8ebbf115fba5..be1f8f9f71c5 100644 --- a/Debug/test_coverage/Base/Types.hpp.gcov.html +++ b/Debug/test_coverage/Base/Types.hpp.gcov.html @@ -33,7 +33,7 @@ - + diff --git a/Debug/test_coverage/Base/Vector.hpp.func-sort-c.html b/Debug/test_coverage/Base/Vector.hpp.func-sort-c.html index bce6936beccf..d3639eb5233f 100644 --- a/Debug/test_coverage/Base/Vector.hpp.func-sort-c.html +++ b/Debug/test_coverage/Base/Vector.hpp.func-sort-c.html @@ -27,18 +27,18 @@ - + - + - + - + - + @@ -52,9 +52,9 @@ - + - +
   1
-   2
-   3
-   4
-   5
-   6
-   7
-   8
-   9
-  10
-  11
-  12
-  13
-  14
-  15
-  16
-  17
-  18
-  19
-  20
-  21
-  22
-  23
-  24
-  25
-  26
-  27
-  28
-  29
-  30
-  31
-  32
-  33
-  34
-  35
-  36
-  37
-  38
-  39
-  40
-  41
-  42
-  43
-  44
-  45
-  46
-  47
-  48
-  49
-  50
-  51
-  52
-  53
-  54
-  55
-  56
-  57
-  58
-  59
-  60
-  61
-  62
-  63
-  64
-  65
-  66
-  67
-  68
-  69
-  70
-  71
-  72
-  73
-  74
-  75
-  76
-  77
-  78
-  79
-  80
-  81
-  82
-  83
-  84
-  85
-  86
-  87
-  88
-  89
-  90
-  91
-  92
-  93
-  94
-  95
-  96
-  97
-  98
-  99
- 100
- 101
- 102
- 103
- 104
- 105
- 106
- 107
- 108
- 109
- 110
- 111
- 112
- 113
- 114
- 115
- 116
- 117
- 118
- 119
- 120
- 121
- 122
- 123
- 124
- 125
- 126
- 127
- 128
- 129
- 130
- 131
- 132
- 133
- 134
- 135
- 136
- 137
- 138
- 139
- 140
- 141
- 142
- 143
- 144
- 145
- 146
- 147
- 148
- 149
- 150
- 151
- 152
- 153
- 154
- 155
- 156
- 157
- 158
- 159
- 160
- 161
- 162
- 163
- 164
- 165
- 166
- 167
- 168
- 169
- 170
- 171
- 172
- 173
- 174
- 175
- 176
- 177
- 178
- 179
- 180
- 181
- 182
- 183
- 184
- 185
- 186
- 187
- 188
- 189
- 190
- 191
- 192
- 193
- 194
- 195
- 196
- 197
- 198
- 199
- 200
- 201
- 202
- 203
- 204
- 205
- 206
- 207
- 208
- 209
- 210
- 211
- 212
- 213
- 214
- 215
- 216
- 217
- 218
- 219
- 220
- 221
- 222
- 223
- 224
- 225
- 226
- 227
- 228
- 229
- 230
- 231
- 232
- 233
- 234
- 235
- 236
- 237
- 238
- 239
- 240
- 241
- 242
- 243
- 244
- 245
- 246
- 247
- 248
- 249
- 250
- 251
- 252
- 253
- 254
- 255
- 256
- 257
- 258
- 259
- 260
- 261
- 262
- 263
- 264
- 265
- 266
- 267
- 268
- 269
- 270
- 271
- 272
- 273
- 274
- 275
- 276
- 277
- 278
- 279
- 280
- 281
- 282
- 283
- 284
- 285
- 286
- 287
- 288
- 289
- 290
- 291
- 292
- 293
- 294
- 295
- 296
- 297
- 298
- 299
- 300
- 301
- 302
- 303
- 304
- 305
- 306
- 307
- 308
- 309
- 310
- 311
- 312
- 313
- 314
- 315
- 316
- 317
- 318
- 319
- 320
- 321
- 322
- 323
- 324
- 325
- 326
- 327
- 328
- 329
- 330
- 331
- 332
- 333
- 334
- 335
- 336
- 337
- 338
- 339
- 340
- 341
- 342
- 343
- 344
- 345
- 346
- 347
- 348
- 349
- 350
- 351
- 352
- 353
- 354
- 355
- 356
- 357
- 358
- 359
- 360
- 361
- 362
- 363
- 364
- 365
- 366
- 367
- 368
- 369
- 370
- 371
- 372
- 373
- 374
- 375
- 376
- 377
- 378
- 379
- 380
- 381
- 382
- 383
- 384
- 385
- 386
- 387
- 388
- 389
- 390
- 391
- 392
- 393
- 394
- 395
- 396
- 397
- 398
- 399
- 400
- 401
- 402
- 403
- 404
- 405
- 406
- 407
- 408
- 409
- 410
- 411
- 412
- 413
- 414
- 415
- 416
- 417
- 418
- 419
- 420
- 421
- 422
- 423
- 424
- 425
- 426
- 427
- 428
- 429
- 430
- 431
- 432
- 433
- 434
- 435
- 436
- 437
- 438
- 439
- 440
- 441
- 442
- 443
- 444
- 445
- 446
- 447
- 448
- 449
- 450
- 451
- 452
- 453
- 454
- 455
- 456
- 457
- 458
- 459
- 460
- 461
- 462
- 463
- 464
- 465
- 466
- 467
- 468
- 469
- 470
- 471
- 472
- 473
- 474
- 475
- 476
- 477
- 478
- 479
- 480
- 481
- 482
- 483
- 484
- 485
- 486
- 487
- 488
- 489
- 490
- 491
- 492
- 493
- 494
- 495
- 496
- 497
- 498
- 499
- 500
- 501
- 502
- 503
- 504
- 505
- 506
- 507
- 508
- 509
- 510
- 511
- 512
- 513
- 514
- 515
- 516
- 517
- 518
- 519
- 520
- 521
- 522
- 523
- 524
- 525
- 526
- 527
- 528
- 529
- 530
- 531
- 532
- 533
- 534
- 535
- 536
- 537
- 538
- 539
- 540
- 541
- 542
- 543
- 544
- 545
- 546
- 547
- 548
- 549
- 550
- 551
- 552
- 553
- 554
- 555
- 556
- 557
- 558
- 559
- 560
- 561
- 562
- 563
- 564
- 565
- 566
- 567
- 568
- 569
- 570
- 571
- 572
- 573
- 574
- 575
- 576
- 577
- 578
- 579
- 580
- 581
- 582
- 583
- 584
- 585
- 586
- 587
- 588
- 589
- 590
- 591
- 592
- 593
- 594
- 595
- 596
- 597
- 598
- 599
- 600
- 601
- 602
- 603
- 604
- 605
- 606
- 607
- 608
- 609
- 610
- 611
- 612
- 613
- 614
- 615
- 616
- 617
- 618
- 619
- 620
- 621
- 622
- 623
- 624
- 625
- 626
- 627
- 628
- 629
- 630
- 631
- 632
- 633
- 634
- 635
- 636
- 637
- 638
- 639
- 640
- 641
- 642
- 643
- 644
- 645
- 646
- 647
- 648
- 649
- 650
- 651
- 652
- 653
- 654
- 655
- 656
- 657
- 658
- 659
- 660
- 661
- 662
- 663
- 664
- 665
- 666
- 667
- 668
- 669
- 670
- 671
- 672
- 673
- 674
- 675
- 676
- 677
- 678
- 679
- 680
- 681
- 682
- 683
- 684
- 685
- 686
- 687
- 688
- 689
- 690
- 691
- 692
- 693
- 694
- 695
- 696
- 697
- 698
- 699
- 700
- 701
- 702
- 703
- 704
- 705
- 706
- 707
- 708
- 709
- 710
- 711
- 712
- 713
- 714
- 715
- 716
- 717
- 718
- 719
- 720
- 721
- 722
- 723
- 724
- 725
- 726
- 727
- 728
- 729
- 730
- 731
- 732
- 733
- 734
- 735
- 736
- 737
- 738
- 739
- 740
- 741
- 742
- 743
- 744
- 745
- 746
- 747
- 748
- 749
- 750
- 751
- 752
- 753
- 754
- 755
- 756
- 757
- 758
- 759
- 760
- 761
- 762
- 763
- 764
- 765
- 766
- 767
- 768
- 769
- 770
- 771
- 772
- 773
- 774
- 775
- 776
- 777
- 778
- 779
- 780
- 781
- 782
- 783
- 784
- 785
- 786
- 787
- 788
- 789
- 790
- 791
- 792
- 793
- 794
- 795
- 796
- 797
- 798
- 799
- 800
- 801
- 802
- 803
- 804
- 805
- 806
- 807
- 808
- 809
- 810
- 811
- 812
- 813
- 814
- 815
- 816
- 817
- 818
- 819
- 820
- 821
- 822
- 823
- 824
- 825
- 826
- 827
- 828
- 829
- 830
- 831
- 832
- 833
- 834
- 835
- 836
- 837
- 838
- 839
- 840
- 841
- 842
- 843
- 844
- 845
- 846
- 847
- 848
- 849
- 850
- 851
- 852
- 853
- 854
- 855
- 856
- 857
- 858
- 859
- 860
- 861
- 862
- 863
- 864
- 865
- 866
- 867
- 868
- 869
- 870
- 871
- 872
- 873
- 874
- 875
- 876
- 877
- 878
- 879
- 880
- 881
- 882
- 883
- 884
- 885
- 886
- 887
- 888
- 889
- 890
- 891
- 892
- 893
- 894
- 895
- 896
- 897
- 898
- 899
- 900
- 901
- 902
- 903
- 904
- 905
- 906
- 907
- 908
- 909
- 910
- 911
- 912
- 913
- 914
- 915
- 916
- 917
- 918
- 919
- 920
- 921
- 922
- 923
- 924
- 925
- 926
- 927
- 928
- 929
- 930
- 931
- 932
- 933
- 934
- 935
- 936
- 937
- 938
- 939
- 940
- 941
- 942
- 943
- 944
- 945
- 946
- 947
- 948
- 949
- 950
- 951
- 952
- 953
- 954
- 955
- 956
- 957
- 958
- 959
- 960
- 961
- 962
- 963
- 964
- 965
- 966
- 967
- 968
- 969
- 970
- 971
- 972
- 973
- 974
- 975
- 976
- 977
- 978
- 979
- 980
- 981
- 982
- 983
- 984
- 985
- 986
- 987
- 988
- 989
- 990
- 991
- 992
- 993
- 994
- 995
- 996
- 997
- 998
- 999
-1000
-1001
-1002
-1003
-1004
-1005
-1006
-1007
-1008
-1009
-1010
-1011
-1012
-1013
-1014
-1015
-1016
-1017
-1018
-1019
-1020
-1021
-1022
-1023
-1024
-1025
-1026
-1027
-1028
-1029
-1030
-1031
-1032
-1033
-1034
-1035
-1036
-1037
-1038
-1039
-1040
-1041
-1042
-1043
-1044
-1045
-1046
-1047
-1048
-1049
-1050
-1051
-1052
-1053
-1054
-1055
-1056
-1057
-1058
-1059
-1060
-1061
-1062
-1063
-1064
-1065
-1066
-1067
-1068
-1069
-1070
-1071
-1072
-1073
-1074
-1075
-1076
-1077
-1078
-1079
-1080
-1081
-1082
-1083
-1084
-1085
-1086
-1087
-1088
-1089
-1090
-1091
-1092
-1093
-1094
-1095
-1096
-1097
-1098
-1099
-1100
-1101
-1102
-1103
-1104
-1105
-1106
-1107
-1108
-1109
-1110
-1111
-1112
-1113
-1114
-1115
-1116
-1117
-1118
-1119
-1120
-1121
-1122
-1123
-1124
-1125
-1126
-1127
-1128
-1129
-1130
-1131
-1132
-1133
-1134
-1135
-1136
-1137
-1138
-1139
-1140
-1141
-1142
-1143
-1144
-1145
-1146
-1147
-1148
-1149
-1150
-1151
-1152
-1153
-1154
-1155
-1156
-1157
-1158
-1159
-1160
-1161
-1162
-1163
-1164
-1165
-1166
-1167
-1168
-1169
-1170
-1171
-1172
-1173
-1174
-1175
-1176
-1177
-1178
-1179
-1180
-1181
-1182
-1183
-1184
-1185
-1186
-1187
-1188
-1189
-1190
-1191
-1192
-1193
-1194
-1195
-1196
-1197
-1198
-1199
-1200
-1201
-1202
-1203
-1204
-1205
-1206
-1207
-1208
-1209
-1210
-1211
-1212
-1213
-1214
-1215
-1216
-1217
-1218
-1219
-1220
-1221
-1222
-1223
-1224
-1225
-1226
-1227
-1228
-1229
-1230
-1231
-1232
-1233
-1234
-1235
-1236
-1237
-1238
-1239
-1240
-1241
-1242
-1243
-1244
-1245
-1246
-1247
-1248
-1249
-1250
-1251
-1252
-1253
-1254
-1255
-1256
-1257
-1258
-1259
// *****************************************************************************
+
  1
+  2
+  3
+  4
+  5
+  6
+  7
+  8
+  9
+ 10
+ 11
+ 12
+ 13
+ 14
+ 15
+ 16
+ 17
+ 18
+ 19
+ 20
+ 21
+ 22
+ 23
+ 24
+ 25
+ 26
+ 27
+ 28
+ 29
+ 30
+ 31
+ 32
+ 33
+ 34
+ 35
+ 36
+ 37
+ 38
+ 39
+ 40
+ 41
+ 42
+ 43
+ 44
+ 45
+ 46
+ 47
+ 48
+ 49
+ 50
+ 51
+ 52
+ 53
+ 54
+ 55
+ 56
+ 57
+ 58
+ 59
+ 60
+ 61
+ 62
+ 63
+ 64
+ 65
+ 66
+ 67
+ 68
+ 69
+ 70
+ 71
+ 72
+ 73
+ 74
+ 75
+ 76
+ 77
+ 78
+ 79
+ 80
+ 81
+ 82
+ 83
+ 84
+ 85
+ 86
+ 87
+ 88
+ 89
+ 90
+ 91
+ 92
+ 93
+ 94
+ 95
+ 96
+ 97
+ 98
+ 99
+100
+101
+102
+103
+104
+105
+106
+107
+108
+109
+110
+111
+112
+113
+114
+115
+116
+117
+118
+119
+120
+121
+122
+123
+124
+125
+126
+127
+128
+129
+130
+131
+132
+133
+134
+135
+136
+137
+138
+139
+140
+141
+142
+143
+144
+145
+146
+147
+148
+149
+150
+151
+152
+153
+154
+155
+156
+157
+158
+159
+160
+161
+162
+163
+164
+165
+166
+167
+168
+169
+170
+171
+172
+173
+174
+175
+176
+177
+178
+179
+180
+181
+182
+183
+184
+185
+186
+187
+188
// *****************************************************************************
 /*!
-  \file      src/PDE/Reconstruction.cpp
+  \file      src/PDE/PDEStack.hpp
   \copyright 2012-2015 J. Bakosi,
              2016-2018 Los Alamos National Security, LLC.,
              2019-2021 Triad National Security, LLC.
              All rights reserved. See the LICENSE file for details.
-  \brief     Reconstruction for reconstructed discontinuous Galerkin methods
-  \details   This file contains functions that reconstruct an "n"th order
-    polynomial to an "n+1"th order polynomial using a least-squares
-    reconstruction procedure.
-*/
-// *****************************************************************************
-
-#include <array>
-#include <vector>
-#include <iostream>
-#include <iomanip>
+  \brief     Stack of differential equations
+  \details   This file declares class PDEStack, which implements various
+    functionality related to registering and instantiating partial differential
+    equation types. Registration and instantiation use a partial differential
+    equation factory, which is a std::map (an associative container),
+    associating unique partial differential equation keys to their constructor
+    calls. For more details, see the in-code documentation of the constructor.
+*/
+// *****************************************************************************
+#ifndef PDEStack_h
+#define PDEStack_h
 
-#include "Vector.hpp"
-#include "Around.hpp"
-#include "Base/HashMapReducer.hpp"
-#include "Reconstruction.hpp"
-#include "MultiMat/MultiMatIndexing.hpp"
-#include "Inciter/InputDeck/InputDeck.hpp"
-#include "Limiter.hpp"
-
-namespace inciter {
-extern ctr::InputDeck g_inputdeck;
-}
-
-namespace tk {
-
-void
-lhsLeastSq_P0P1( const inciter::FaceData& fd,
-                 const Fields& geoElem,
-                 const Fields& geoFace,
-                 std::vector< std::array< std::array< real, 3 >, 3 > >& lhs_ls )
-// *****************************************************************************
-//  Compute lhs matrix for the least-squares reconstruction
-//! \param[in] fd Face connectivity and boundary conditions object
-//! \param[in] geoElem Element geometry array
-//! \param[in] geoFace Face geometry array
-//! \param[in,out] lhs_ls LHS reconstruction matrix
-//! \details This function computing the lhs matrix for reconstruction, is
-//!   common for primitive and conserved quantities.
-// *****************************************************************************
-{
-  const auto& esuf = fd.Esuf();
-  const auto nelem = fd.Esuel().size()/4;
-
-  // Compute internal and boundary face contributions
-  for (std::size_t f=0; f<esuf.size()/2; ++f)
-  {
-    Assert( esuf[2*f] > -1, "Left-side element detected as -1" );
-
-    auto el = static_cast< std::size_t >(esuf[2*f]);
-    auto er = esuf[2*f+1];
-
-    std::array< real, 3 > geoElemR;
-    std::size_t eR(0);
-
-    // A second-order (piecewise linear) solution polynomial can be obtained
-    // from the first-order (piecewise constant) FV solutions by using a
-    // least-squares (LS) reconstruction process. LS uses the first-order
-    // solutions from the cell being processed, and the cells surrounding it.
-    // The LS system is obtaining by requiring the following to hold:
-    // 'Taylor expansions of solution from cell-i to the centroids of each of
-    // its neighboring cells should be equal to the cell average solution on
-    // that neighbor cell.'
-    // This gives a system of equations for the three second-order DOFs that are
-    // to be determined. In 3D tetrahedral meshes, this would give four
-    // equations (one for each neighbor )for the three unknown DOFs. This
-    // overdetermined system is solved in the least-squares sense using the
-    // normal equations approach. The normal equations approach involves
-    // pre-multiplying the overdetermined system by the transpose of the system
-    // matrix to obtain a square matrix (3x3 in this case).
-
-    // get a 3x3 system by applying the normal equation approach to the
-    // least-squares overdetermined system
-
-    if (er > -1) {
-    // internal face contribution
-      eR = static_cast< std::size_t >(er);
-      // Put in cell-centroid coordinates
-      geoElemR = {{ geoElem(eR,1), geoElem(eR,2), geoElem(eR,3) }};
-    }
-    else {
-    // boundary face contribution
-      // Put in face-centroid coordinates
-      geoElemR = {{ geoFace(f,4), geoFace(f,5), geoFace(f,6) }};
-    }
-
-    std::array< real, 3 > wdeltax{{ geoElemR[0]-geoElem(el,1),
-                                    geoElemR[1]-geoElem(el,2),
-                                    geoElemR[2]-geoElem(el,3) }};
-
-    // define a lambda for contributing to lhs matrix
-    auto lhs = [&]( std::size_t e ){
-    for (std::size_t idir=0; idir<3; ++idir)
-      for (std::size_t jdir=0; jdir<3; ++jdir)
-        lhs_ls[e][idir][jdir] += wdeltax[idir] * wdeltax[jdir];
-    };
-
-    // always add left element contribution (at a boundary face, the internal
-    // element is always the left element)
-    lhs(el);
-    // add right element contribution for internal faces only
-    if (er > -1)
-      if (eR < nelem) lhs(eR);
-
-  }
-}
-
-void
-intLeastSq_P0P1( const std::size_t rdof,
-                 const inciter::FaceData& fd,
-                 const Fields& geoElem,
-                 const Fields& W,
-                 std::vector< std::vector< std::array< real, 3 > > >& rhs_ls,
-                 const std::vector< std::size_t >& varList )
-// *****************************************************************************
-//  \brief Compute internal surface contributions to rhs vector of the
-//    least-squares reconstruction
-//! \param[in] rdof Maximum number of reconstructed degrees of freedom
-//! \param[in] fd Face connectivity and boundary conditions object
-//! \param[in] geoElem Element geometry array
-//! \param[in] W Solution vector to be reconstructed at recent time step
-//! \param[in,out] rhs_ls RHS reconstruction vector
-//! \param[in] varList List of indices in W, that need to be reconstructed
-//! \details This function computing the internal face contributions to the rhs
-//!   vector for reconstruction, is common for primitive and conserved
-//!   quantities. If `W` == `U`, compute internal face contributions for the
-//!   conserved variables. If `W` == `P`, compute internal face contributions
-//!   for the primitive variables.
-// *****************************************************************************
-{
-  const auto& esuf = fd.Esuf();
-  const auto nelem = fd.Esuel().size()/4;<--- Variable 'nelem' is assigned a value that is never used.
-
-  // Compute internal face contributions
-  for (auto f=fd.Nbfac(); f<esuf.size()/2; ++f)
-  {
-    Assert( esuf[2*f] > -1 && esuf[2*f+1] > -1, "Interior element detected "
-            "as -1" );
-
-    auto el = static_cast< std::size_t >(esuf[2*f]);
-    auto er = static_cast< std::size_t >(esuf[2*f+1]);
-
-    // get a 3x3 system by applying the normal equation approach to the
-    // least-squares overdetermined system
-
-    // 'wdeltax' is the distance vector between the centroids of this element
-    // and its neighbor
-    std::array< real, 3 > wdeltax{{ geoElem(er,1)-geoElem(el,1),
-                                    geoElem(er,2)-geoElem(el,2),
-                                    geoElem(er,3)-geoElem(el,3) }};
-
-    for (std::size_t idir=0; idir<3; ++idir)
-    {
-      // rhs vector
-      for (std::size_t i=0; i<varList.size(); ++i)
-      {
-        auto c = varList[i];
-        auto mark = c*rdof;
-        rhs_ls[el][c][idir] +=
-          wdeltax[idir] * (W(er,mark)-W(el,mark));
-        if (er < nelem)
-          rhs_ls[er][c][idir] +=
-            wdeltax[idir] * (W(er,mark)-W(el,mark));
-      }
-    }
-  }
-}
-
-void
-bndLeastSqConservedVar_P0P1(
-  ncomp_t ncomp,
-  const std::vector< inciter::EOS >& mat_blk,
-  std::size_t rdof,
-  const std::vector< std::size_t >& bcconfig,
-  const inciter::FaceData& fd,
-  const Fields& geoFace,
-  const Fields& geoElem,
-  real t,
-  const StateFn& state,
-  const Fields& P,
-  const Fields& U,
-  std::vector< std::vector< std::array< real, 3 > > >& rhs_ls,
-  const std::vector< std::size_t >& varList,
-  std::size_t nprim )
-// *****************************************************************************
-//  \brief Compute boundary surface contributions to rhs vector of the
-//    least-squares reconstruction of conserved quantities of the PDE system
-//! \param[in] ncomp Number of scalar components in this PDE system
-//! \param[in] mat_blk EOS material block
-//! \param[in] rdof Maximum number of reconstructed degrees of freedom
-//! \param[in] bcconfig BC configuration vector for multiple side sets
-//! \param[in] fd Face connectivity and boundary conditions object
-//! \param[in] geoFace Face geometry array
-//! \param[in] geoElem Element geometry array
-//! \param[in] t Physical time
-//! \param[in] state Function to evaluate the left and right solution state at
-//!   boundaries
-//! \param[in] P Primitive vector to be reconstructed at recent time step
-//! \param[in] U Solution vector to be reconstructed at recent time step
-//! \param[in,out] rhs_ls RHS reconstruction vector
-//! \param[in] varList List of indices in W, that need to be reconstructed
-//! \param[in] nprim This is the number of primitive quantities stored for this
-//!   PDE system. This is necessary to extend the state vector to the right
-//!   size, so that correct boundary conditions are obtained.
-//!   A default is set to 0, so that calling code for systems that do not store
-//!   primitive quantities does not need to specify this argument.
-//! \details This function computing the boundary face contributions to the rhs
-//!   vector for reconstruction, is used for conserved quantities only.
-// *****************************************************************************
-{
-  const auto& bface = fd.Bface();
-  const auto& esuf = fd.Esuf();
-
-  for (const auto& s : bcconfig) {       // for all bc sidesets
-    auto bc = bface.find(static_cast<int>(s));// faces for side set
-    if (bc != end(bface))
-    {
-      // Compute boundary face contributions
-      for (const auto& f : bc->second)
-      {
-        Assert( esuf[2*f+1] == -1, "physical boundary element not -1" );
-
-        std::size_t el = static_cast< std::size_t >(esuf[2*f]);
-
-        // arrays for quadrature points
-        std::array< real, 3 >
-          fc{{ geoFace(f,4), geoFace(f,5), geoFace(f,6) }};
-        std::array< real, 3 >
-          fn{{ geoFace(f,1), geoFace(f,2), geoFace(f,3) }};
-
-        // Compute the state variables at the left element
-        std::vector< real >B(1,1.0);
-        auto ul = eval_state( ncomp, rdof, 1, el, U, B );
-        auto uprim = eval_state( nprim, rdof, 1, el, P, B );
-
-        // consolidate primitives into state vector
-        ul.insert(ul.end(), uprim.begin(), uprim.end());
-
-        Assert( ul.size() == ncomp+nprim, "Incorrect size for "
-                "appended state vector" );
-
-        // Compute the state at the face-center using BC
-        auto ustate = state( ncomp, mat_blk, ul, fc[0], fc[1], fc[2], t, fn );
-
-        std::array< real, 3 > wdeltax{{ fc[0]-geoElem(el,1),
-                                        fc[1]-geoElem(el,2),
-                                        fc[2]-geoElem(el,3) }};
-
-        for (std::size_t idir=0; idir<3; ++idir)
-        {
-          // rhs vector
-          for (std::size_t i=0; i<varList.size(); ++i)
-          {
-            auto c = varList[i];
-            rhs_ls[el][c][idir] +=
-              wdeltax[idir] * (ustate[1][c]-ustate[0][c]);
-          }
-        }
-      }
-    }
-  }
-}
-
-void
-solveLeastSq_P0P1(
-  const std::size_t rdof,
-  const std::vector< std::array< std::array< real, 3 >, 3 > >& lhs,
-  const std::vector< std::vector< std::array< real, 3 > > >& rhs,
-  Fields& W,<--- Parameter 'W' can be declared with const
-  const std::vector< std::size_t >& varList )
-// *****************************************************************************
-//  Solve the 3x3 linear system for least-squares reconstruction
-//! \param[in] rdof Maximum number of reconstructed degrees of freedom
-//! \param[in] lhs LHS reconstruction matrix
-//! \param[in] rhs RHS reconstruction vector
-//! \param[in,out] W Solution vector to be reconstructed at recent time step
-//! \param[in] varList List of indices in W, that need to be reconstructed
-//! \details Solves the 3x3 linear system for each element, individually. For
-//!   systems that require reconstructions of primitive quantities, this should
-//!   be called twice, once with the argument 'W' as U (conserved), and again
-//!   with 'W' as P (primitive).
-// *****************************************************************************
-{
-  auto nelem = lhs.size();
-
-  for (std::size_t e=0; e<nelem; ++e)
-  {
-    for (std::size_t i=0; i<varList.size(); ++i)
-    {
-      auto mark = varList[i]*rdof;
-
-      // solve system using Cramer's rule
-      auto ux = tk::cramer( lhs[e], rhs[e][varList[i]] );
-
-      W(e,mark+1) = ux[0];
-      W(e,mark+2) = ux[1];
-      W(e,mark+3) = ux[2];
-    }
-  }
-}
-
-void
-recoLeastSqExtStencil(
-  std::size_t rdof,
-  std::size_t e,
-  const std::map< std::size_t, std::vector< std::size_t > >& esup,
-  const std::vector< std::size_t >& inpoel,
-  const Fields& geoElem,
-  Fields& W,<--- Parameter 'W' can be declared with const
-  const std::vector< std::size_t >& varList )
-// *****************************************************************************
-//  \brief Reconstruct the second-order solution using least-squares approach
-//    from an extended stencil involving the node-neighbors
-//! \param[in] rdof Maximum number of reconstructed degrees of freedom
-//! \param[in] e Element whoes solution is being reconstructed
-//! \param[in] esup Elements surrounding points
-//! \param[in] inpoel Element-node connectivity
-//! \param[in] geoElem Element geometry array
-//! \param[in,out] W Solution vector to be reconstructed at recent time step
-//! \param[in] varList List of indices in W, that need to be reconstructed
-//! \details A second-order (piecewise linear) solution polynomial is obtained
-//!   from the first-order (piecewise constant) FV solutions by using a
-//!   least-squares (LS) reconstruction process. This LS reconstruction function
-//!   using the nodal-neighbors of a cell, to get an overdetermined system of
-//!   equations for the derivatives of the solution. This overdetermined system
-//!   is solved in the least-squares sense using the normal equations approach.
-// *****************************************************************************
-{
-  // lhs matrix
-  std::array< std::array< tk::real, 3 >, 3 >
-    lhs_ls( {{ {{0.0, 0.0, 0.0}},
-               {{0.0, 0.0, 0.0}},
-               {{0.0, 0.0, 0.0}} }} );
-  // rhs matrix
-  std::vector< std::array< tk::real, 3 > >
-  rhs_ls( varList.size(), {{ 0.0, 0.0, 0.0 }} );
-
-  // loop over all nodes of the element e
-  for (std::size_t lp=0; lp<4; ++lp)
-  {
-    auto p = inpoel[4*e+lp];
-    const auto& pesup = cref_find(esup, p);
-
-    // loop over all the elements surrounding this node p
-    for (auto er : pesup)
-    {
-      // centroid distance
-      std::array< real, 3 > wdeltax{{ geoElem(er,1)-geoElem(e,1),
-                                      geoElem(er,2)-geoElem(e,2),
-                                      geoElem(er,3)-geoElem(e,3) }};
-
-      // contribute to lhs matrix
-      for (std::size_t idir=0; idir<3; ++idir)
-        for (std::size_t jdir=0; jdir<3; ++jdir)
-          lhs_ls[idir][jdir] += wdeltax[idir] * wdeltax[jdir];
-
-      // compute rhs matrix
-      for (std::size_t i=0; i<varList.size(); i++)
-      {
-        auto mark = varList[i]*rdof;
-        for (std::size_t idir=0; idir<3; ++idir)
-          rhs_ls[i][idir] +=
-            wdeltax[idir] * (W(er,mark)-W(e,mark));
-
-      }
-    }
-  }
-
-  // solve least-square normal equation system using Cramer's rule
-  for (std::size_t i=0; i<varList.size(); i++)
-  {
-    auto mark = varList[i]*rdof;
-
-    auto ux = tk::cramer( lhs_ls, rhs_ls[i] );
-
-    // Update the P1 dofs with the reconstructioned gradients.
-    // Since this reconstruction does not affect the cell-averaged solution,
-    // W(e,mark+0) is unchanged.
-    W(e,mark+1) = ux[0];
-    W(e,mark+2) = ux[1];
-    W(e,mark+3) = ux[2];
-  }
-}
-
-void
-transform_P0P1( std::size_t rdof,
-                std::size_t nelem,
-                const std::vector< std::size_t >& inpoel,
-                const UnsMesh::Coords& coord,
-                Fields& W,<--- Parameter 'W' can be declared with const
-                const std::vector< std::size_t >& varList )
-// *****************************************************************************
-//  Transform the reconstructed P1-derivatives to the Dubiner dofs
-//! \param[in] rdof Total number of reconstructed dofs
-//! \param[in] nelem Total number of elements
-//! \param[in] inpoel Element-node connectivity
-//! \param[in] coord Array of nodal coordinates
-//! \param[in,out] W Second-order reconstructed vector which gets transformed to
-//!   the Dubiner reference space
-//! \param[in] varList List of indices in W, that need to be reconstructed
-//! \details Since the DG solution (and the primitive quantities) are assumed to
-//!   be stored in the Dubiner space, this transformation from Taylor
-//!   coefficients to Dubiner coefficients is necessary.
-// *****************************************************************************
-{
-  const auto& cx = coord[0];
-  const auto& cy = coord[1];
-  const auto& cz = coord[2];
-
-  for (std::size_t e=0; e<nelem; ++e)
-  {
-    // Extract the element coordinates
-    std::array< std::array< real, 3>, 4 > coordel {{
-      {{ cx[ inpoel[4*e  ] ], cy[ inpoel[4*e  ] ], cz[ inpoel[4*e  ] ] }},
-      {{ cx[ inpoel[4*e+1] ], cy[ inpoel[4*e+1] ], cz[ inpoel[4*e+1] ] }},
-      {{ cx[ inpoel[4*e+2] ], cy[ inpoel[4*e+2] ], cz[ inpoel[4*e+2] ] }},
-      {{ cx[ inpoel[4*e+3] ], cy[ inpoel[4*e+3] ], cz[ inpoel[4*e+3] ] }}
-    }};
-
-    auto jacInv =
-      tk::inverseJacobian( coordel[0], coordel[1], coordel[2], coordel[3] );
-
-    // Compute the derivatives of basis function for DG(P1)
-    auto dBdx = tk::eval_dBdx_p1( rdof, jacInv );
-
-    for (std::size_t i=0; i<varList.size(); ++i)
-    {
-      auto mark = varList[i]*rdof;
-
-      // solve system using Cramer's rule
-      auto ux = tk::cramer( {{ {{dBdx[0][1], dBdx[0][2], dBdx[0][3]}},
-                               {{dBdx[1][1], dBdx[1][2], dBdx[1][3]}},
-                               {{dBdx[2][1], dBdx[2][2], dBdx[2][3]}} }},
-                            {{ W(e,mark+1),
-                               W(e,mark+2),
-                               W(e,mark+3) }} );
-
-      // replace physical derivatives with transformed dofs
-      W(e,mark+1) = ux[0];
-      W(e,mark+2) = ux[1];
-      W(e,mark+3) = ux[2];
-    }
-  }
-}
-
-void
-THINCReco( std::size_t rdof,
-           std::size_t nmat,
-           std::size_t e,
-           const std::vector< std::size_t >& inpoel,
-           const UnsMesh::Coords& coord,
-           const Fields& geoElem,
-           const std::array< real, 3 >& ref_xp,
-           const Fields& U,
-           const Fields& P,
-           bool intInd,
-           const std::vector< std::size_t >& matInt,
-           [[maybe_unused]] const std::vector< real >& vfmin,
-           [[maybe_unused]] const std::vector< real >& vfmax,
-           std::vector< real >& state )
-// *****************************************************************************
-//  Compute THINC reconstructions at quadrature point for multi-material flows
-//! \param[in] rdof Total number of reconstructed dofs
-//! \param[in] nmat Total number of materials
-//! \param[in] e Element for which interface reconstruction is being calculated
-//! \param[in] inpoel Element-node connectivity
-//! \param[in] coord Array of nodal coordinates
-//! \param[in] geoElem Element geometry array
-//! \param[in] ref_xp Quadrature point in reference space
-//! \param[in] U Solution vector
-//! \param[in] P Vector of primitives
-//! \param[in] intInd Boolean which indicates if the element contains a
-//!   material interface
-//! \param[in] matInt Array indicating which material has an interface
-//! \param[in] vfmin Vector containing min volume fractions for each material
-//!   in this cell
-//! \param[in] vfmax Vector containing max volume fractions for each material
-//!   in this cell
-//! \param[in,out] state Unknown/state vector at quadrature point, modified
-//!   if near interfaces using THINC
-//! \details This function is an interface for the multimat PDEs that use the
-//!   algebraic multi-material THINC reconstruction. This particular function
-//!   should only be called for multimat.
-// *****************************************************************************
-{
-  using inciter::volfracDofIdx;
-  using inciter::densityDofIdx;
-  using inciter::momentumDofIdx;
-  using inciter::energyDofIdx;
-  using inciter::pressureDofIdx;
-  using inciter::velocityDofIdx;
-  using inciter::deformDofIdx;
-  using inciter::stressDofIdx;
-  using inciter::volfracIdx;
-  using inciter::densityIdx;
-  using inciter::momentumIdx;
-  using inciter::energyIdx;
-  using inciter::pressureIdx;
-  using inciter::velocityIdx;
-  using inciter::deformIdx;
-  using inciter::stressIdx;
-
-  auto bparam = inciter::g_inputdeck.get< tag::multimat,
-    tag::intsharp_param >();
-  const auto ncomp = U.nprop()/rdof;
-  const auto& solidx = inciter::g_inputdeck.get< tag::matidxmap,
-    tag::solidx >();
-
-  // Step-1: Perform THINC reconstruction
-  // create a vector of volume-fractions and pass it to the THINC function
-  std::vector< real > alSol(rdof*nmat, 0.0);
-  std::vector< real > alReco(nmat, 0.0);
-  for (std::size_t k=0; k<nmat; ++k) {
-    auto mark = k*rdof;
-    for (std::size_t i=0; i<rdof; ++i) {
-      alSol[mark+i] = U(e, volfracDofIdx(nmat,k,rdof,i));
-    }
-    // initialize with TVD reconstructions which will be modified if near
-    // material interface
-    alReco[k] = state[volfracIdx(nmat,k)];
-  }
-  THINCFunction(rdof, nmat, e, inpoel, coord, ref_xp, geoElem(e,0), bparam,
-    alSol, intInd, matInt, alReco);
-
-  // check reconstructed volfracs for positivity
-  bool neg_vf = false;
-  for (std::size_t k=0; k<nmat; ++k) {
-    if (alReco[k] < 1e-16 && matInt[k] > 0) neg_vf = true;
-  }
-  for (std::size_t k=0; k<nmat; ++k) {
-    if (neg_vf) {
-      std::cout << "Material-id:        " << k << std::endl;
-      std::cout << "Volume-fraction:    " << std::setprecision(18) << alReco[k]
-        << std::endl;
-      std::cout << "Cell-avg vol-frac:  " << std::setprecision(18) <<
-        U(e,volfracDofIdx(nmat,k,rdof,0)) << std::endl;
-      std::cout << "Material-interface? " << intInd << std::endl;
-      std::cout << "Mat-k-involved?     " << matInt[k] << std::endl;
-    }
-  }
-  if (neg_vf) Throw("Material has negative volume fraction after THINC "
-    "reconstruction.");
-
-  // Step-2: Perform consistent reconstruction on other conserved quantities
-  if (intInd)
-  {
-    auto rhobCC(0.0), rhobHO(0.0);
-    for (std::size_t k=0; k<nmat; ++k)
-    {
-      auto alCC = U(e, volfracDofIdx(nmat,k,rdof,0));
-      alCC = std::max(1e-14, alCC);
-
-      if (matInt[k])
-      {
-        state[volfracIdx(nmat,k)] = alReco[k];
-        state[densityIdx(nmat,k)] = alReco[k]
-          * U(e, densityDofIdx(nmat,k,rdof,0))/alCC;
-        state[energyIdx(nmat,k)] = alReco[k]
-          * U(e, energyDofIdx(nmat,k,rdof,0))/alCC;
-        state[ncomp+pressureIdx(nmat,k)] = alReco[k]
-          * P(e, pressureDofIdx(nmat,k,rdof,0))/alCC;
-        if (solidx[k] > 0) {
-          for (std::size_t i=0; i<3; ++i)
-            for (std::size_t j=0; j<3; ++j)
-              state[deformIdx(nmat,solidx[k],i,j)] =
-                U(e, deformDofIdx(nmat,solidx[k],i,j,rdof,0));
-
-          for (std::size_t i=0; i<6; ++i)
-            state[ncomp+stressIdx(nmat,solidx[k],i)] = alReco[k]
-              * P(e, stressDofIdx(nmat,solidx[k],i,rdof,0))/alCC;
-        }
-      }
-
-      rhobCC += U(e, densityDofIdx(nmat,k,rdof,0));
-      rhobHO += state[densityIdx(nmat,k)];
-    }
-
-    // consistent reconstruction for bulk momentum
-    for (std::size_t i=0; i<3; ++i)
-    {
-      state[momentumIdx(nmat,i)] = rhobHO
-        * U(e, momentumDofIdx(nmat,i,rdof,0))/rhobCC;
-      state[ncomp+velocityIdx(nmat,i)] =
-        P(e, velocityDofIdx(nmat,i,rdof,0));
-    }
-  }
-}
-
-void
-THINCRecoTransport( std::size_t rdof,
-                    std::size_t,
-                    std::size_t e,
-                    const std::vector< std::size_t >& inpoel,
-                    const UnsMesh::Coords& coord,
-                    const Fields& geoElem,
-                    const std::array< real, 3 >& ref_xp,
-                    const Fields& U,
-                    const Fields&,
-                    [[maybe_unused]] const std::vector< real >& vfmin,
-                    [[maybe_unused]] const std::vector< real >& vfmax,
-                    std::vector< real >& state )
-// *****************************************************************************
-//  Compute THINC reconstructions at quadrature point for transport
-//! \param[in] rdof Total number of reconstructed dofs
-//! \param[in] e Element for which interface reconstruction is being calculated
-//! \param[in] inpoel Element-node connectivity
-//! \param[in] coord Array of nodal coordinates
-//! \param[in] geoElem Element geometry array
-//! \param[in] ref_xp Quadrature point in reference space
-//! \param[in] U Solution vector
-//! \param[in] vfmin Vector containing min volume fractions for each material
-//!   in this cell
-//! \param[in] vfmax Vector containing max volume fractions for each material
-//!   in this cell
-//! \param[in,out] state Unknown/state vector at quadrature point, modified
-//!   if near interfaces using THINC
-//! \details This function is an interface for the transport PDEs that use the
-//!   algebraic multi-material THINC reconstruction. This particular function
-//!   should only be called for transport.
-// *****************************************************************************
-{
-  auto bparam = inciter::g_inputdeck.get< tag::transport,
-    tag::intsharp_param >();
-  auto ncomp = U.nprop()/rdof;
-
-  // interface detection
-  std::vector< std::size_t > matInt(ncomp, 0);
-  std::vector< tk::real > alAvg(ncomp, 0.0);
-  for (std::size_t k=0; k<ncomp; ++k)
-    alAvg[k] = U(e, k*rdof);
-  auto intInd = inciter::interfaceIndicator(ncomp, alAvg, matInt);
-
-  // create a vector of volume-fractions and pass it to the THINC function
-  std::vector< real > alSol(rdof*ncomp, 0.0);
-  // initialize with TVD reconstructions (modified if near interface)
-  auto alReco = state;
-  for (std::size_t k=0; k<ncomp; ++k) {
-    auto mark = k*rdof;
-    for (std::size_t i=0; i<rdof; ++i) {
-      alSol[mark+i] = U(e,mark+i);
-    }
-  }
-  THINCFunction(rdof, ncomp, e, inpoel, coord, ref_xp, geoElem(e,0), bparam,
-    alSol, intInd, matInt, alReco);
-
-  state = alReco;
-}
-
-void
-THINCFunction( std::size_t rdof,
-               std::size_t nmat,
-               std::size_t e,
-               const std::vector< std::size_t >& inpoel,
-               const UnsMesh::Coords& coord,
-               const std::array< real, 3 >& ref_xp,
-               real vol,
-               real bparam,
-               const std::vector< real >& alSol,
-               bool intInd,
-               const std::vector< std::size_t >& matInt,
-               std::vector< real >& alReco )
-// *****************************************************************************
-//  Old version of the Multi-Medium THINC reconstruction function
-//! \param[in] rdof Total number of reconstructed dofs
-//! \param[in] nmat Total number of materials
-//! \param[in] e Element for which interface reconstruction is being calculated
-//! \param[in] inpoel Element-node connectivity
-//! \param[in] coord Array of nodal coordinates
-//! \param[in] ref_xp Quadrature point in reference space
-//! \param[in] vol Element volume
-//! \param[in] bparam User specified Beta for THINC, from the input file
-//! \param[in] alSol Volume fraction solution vector for element e
-//! \param[in] intInd Interface indicator, true if e is interface element
-//! \param[in] matInt Vector indicating materials which constitute interface
-//! \param[in,out] alReco Unknown/state vector at quadrature point, which gets
-//!   modified if near interface using MM-THINC
-//! \details This function computes the interface reconstruction using the
-//!   algebraic multi-material THINC reconstruction for each material at the
-//!   given (ref_xp) quadrature point. This function is based on the following:
-//!   Pandare A. K., Waltz J., & Bakosi J. (2021) Multi-Material Hydrodynamics
-//!   with Algebraic Sharp Interface Capturing. Computers & Fluids,
-//!   doi: https://doi.org/10.1016/j.compfluid.2020.104804.
-//!   This function will be removed after the newer version (see
-//!   THINCFunction_new) is sufficiently tested.
-// *****************************************************************************
-{
-  // determine number of materials with interfaces in this cell
-  auto epsl(1e-4), epsh(1e-1), bred(1.25), bmod(bparam);
-  std::size_t nIntMat(0);
-  for (std::size_t k=0; k<nmat; ++k)
-  {
-    auto alk = alSol[k*rdof];
-    if (alk > epsl)
-    {
-      ++nIntMat;
-      if ((alk > epsl) && (alk < epsh))
-        bmod = std::min(bmod,
-          (alk-epsl)/(epsh-epsl) * (bred - bparam) + bparam);
-      else if (alk > epsh)
-        bmod = bred;
-    }
-  }
-
-  if (nIntMat > 2) bparam = bmod;
-
-  // compression parameter
-  auto beta = bparam/std::cbrt(6.0*vol);
-
-  if (intInd)
-  {
-    // 1. Get unit normals to material interface
-
-    // Compute Jacobian matrix for converting Dubiner dofs to derivatives
-    const auto& cx = coord[0];
-    const auto& cy = coord[1];
-    const auto& cz = coord[2];
-
-    std::array< std::array< real, 3>, 4 > coordel {{
-      {{ cx[ inpoel[4*e  ] ], cy[ inpoel[4*e  ] ], cz[ inpoel[4*e  ] ] }},
-      {{ cx[ inpoel[4*e+1] ], cy[ inpoel[4*e+1] ], cz[ inpoel[4*e+1] ] }},
-      {{ cx[ inpoel[4*e+2] ], cy[ inpoel[4*e+2] ], cz[ inpoel[4*e+2] ] }},
-      {{ cx[ inpoel[4*e+3] ], cy[ inpoel[4*e+3] ], cz[ inpoel[4*e+3] ] }}
-    }};
-
-    auto jacInv =
-      tk::inverseJacobian( coordel[0], coordel[1], coordel[2], coordel[3] );
-
-    auto dBdx = tk::eval_dBdx_p1( rdof, jacInv );
-
-    std::array< real, 3 > nInt;
-    std::vector< std::array< real, 3 > > ref_n(nmat, {{0.0, 0.0, 0.0}});
-
-    // Get normals
-    for (std::size_t k=0; k<nmat; ++k)
-    {
-      // Get derivatives from moments in Dubiner space
-      for (std::size_t i=0; i<3; ++i)
-        nInt[i] = dBdx[i][1] * alSol[k*rdof+1]
-          + dBdx[i][2] * alSol[k*rdof+2]
-          + dBdx[i][3] * alSol[k*rdof+3];
-
-      auto nMag = std::sqrt(tk::dot(nInt, nInt)) + 1e-14;
-
-      for (std::size_t i=0; i<3; ++i)
-        nInt[i] /= nMag;
-
-      // project interface normal onto local/reference coordinate system
-      for (std::size_t i=0; i<3; ++i)
-      {
-        std::array< real, 3 > axis{
-          coordel[i+1][0]-coordel[0][0],
-          coordel[i+1][1]-coordel[0][1],
-          coordel[i+1][2]-coordel[0][2] };
-        ref_n[k][i] = tk::dot(nInt, axis);
-      }
-    }
-
-    // 2. Reconstruct volume fractions using THINC
-    auto max_lim = 1.0 - (static_cast<tk::real>(nmat-1)*1.0e-12);
-    auto min_lim = 1e-12;
-    auto sum_inter(0.0), sum_non_inter(0.0);
-    for (std::size_t k=0; k<nmat; ++k)
-    {
-      if (matInt[k])
-      {
-        // get location of material interface (volume fraction 0.5) from the
-        // assumed tanh volume fraction distribution, and cell-averaged
-        // volume fraction
-        auto alCC(alSol[k*rdof]);
-        auto Ac(0.0), Bc(0.0), Qc(0.0);
-        if ((std::abs(ref_n[k][0]) > std::abs(ref_n[k][1]))
-          && (std::abs(ref_n[k][0]) > std::abs(ref_n[k][2])))
-        {
-          Ac = std::exp(0.5*beta*ref_n[k][0]);
-          Bc = std::exp(0.5*beta*(ref_n[k][1]+ref_n[k][2]));
-          Qc = std::exp(0.5*beta*ref_n[k][0]*(2.0*alCC-1.0));
-        }
-        else if ((std::abs(ref_n[k][1]) > std::abs(ref_n[k][0]))
-          && (std::abs(ref_n[k][1]) > std::abs(ref_n[k][2])))
-        {
-          Ac = std::exp(0.5*beta*ref_n[k][1]);
-          Bc = std::exp(0.5*beta*(ref_n[k][0]+ref_n[k][2]));
-          Qc = std::exp(0.5*beta*ref_n[k][1]*(2.0*alCC-1.0));
-        }
-        else
-        {
-          Ac = std::exp(0.5*beta*ref_n[k][2]);
-          Bc = std::exp(0.5*beta*(ref_n[k][0]+ref_n[k][1]));
-          Qc = std::exp(0.5*beta*ref_n[k][2]*(2.0*alCC-1.0));
-        }
-        auto d = std::log((1.0-Ac*Qc) / (Ac*Bc*(Qc-Ac))) / (2.0*beta);
-
-        // THINC reconstruction
-        auto al_c = 0.5 * (1.0 + std::tanh(beta*(tk::dot(ref_n[k], ref_xp) + d)));
-
-        alReco[k] = std::min(max_lim, std::max(min_lim, al_c));
-
-        sum_inter += alReco[k];
-      } else
-      {
-        sum_non_inter += alReco[k];
-      }
-      // else, if this material does not have an interface close-by, the TVD
-      // reconstructions must be used for state variables. This is ensured by
-      // initializing the alReco vector as the TVD state.
-    }
-
-    // Rescale volume fractions of interface-materials to ensure unit sum
-    auto sum_rest = 1.0 - sum_non_inter;
-    for (std::size_t k=0; k<nmat; ++k)
-      if(matInt[k])
-        alReco[k] = alReco[k] * sum_rest / sum_inter;
-  }
-}
-
-void
-THINCFunction_new( std::size_t rdof,
-                   std::size_t nmat,
-                   std::size_t e,
-                   const std::vector< std::size_t >& inpoel,
-                   const UnsMesh::Coords& coord,
-                   const std::array< real, 3 >& ref_xp,
-                   real vol,
-                   real bparam,
-                   const std::vector< real >& alSol,
-                   bool intInd,
-                   const std::vector< std::size_t >& matInt,
-                   std::vector< real >& alReco )
-// *****************************************************************************
-//  New Multi-Medium THINC reconstruction function for volume fractions
-//! \param[in] rdof Total number of reconstructed dofs
-//! \param[in] nmat Total number of materials
-//! \param[in] e Element for which interface reconstruction is being calculated
-//! \param[in] inpoel Element-node connectivity
-//! \param[in] coord Array of nodal coordinates
-//! \param[in] ref_xp Quadrature point in reference space
-//! \param[in] vol Element volume
-//! \param[in] bparam User specified Beta for THINC, from the input file
-//! \param[in] alSol Volume fraction solution vector for element e
-//! \param[in] intInd Interface indicator, true if e is interface element
-//! \param[in] matInt Vector indicating materials which constitute interface
-//! \param[in,out] alReco Unknown/state vector at quadrature point, which gets
-//!   modified if near interface using MM-THINC
-//! \details This function computes the interface reconstruction using the
-//!   algebraic multi-material THINC reconstruction for each material at the
-//!   given (ref_xp) quadrature point. This function succeeds the older version
-//!   of the mm-THINC (see THINCFunction), but is still under testing and is
-//!   currently experimental.
-// *****************************************************************************
-{
-  // compression parameter
-  auto beta = bparam/std::cbrt(6.0*vol);
-
-  // If the cell is not material interface, return this function
-  if (not intInd) return;
-
-  // If the cell is material interface, THINC reconstruction is applied
-  // Step 1. Get unit normals to material interface
-  // -------------------------------------------------------------------------
-
-  // Compute Jacobian matrix for converting Dubiner dofs to derivatives
-  const auto& cx = coord[0];
-  const auto& cy = coord[1];
-  const auto& cz = coord[2];
-
-  std::array< std::array< real, 3>, 4 > coordel {{
-    {{ cx[ inpoel[4*e  ] ], cy[ inpoel[4*e  ] ], cz[ inpoel[4*e  ] ] }},
-    {{ cx[ inpoel[4*e+1] ], cy[ inpoel[4*e+1] ], cz[ inpoel[4*e+1] ] }},
-    {{ cx[ inpoel[4*e+2] ], cy[ inpoel[4*e+2] ], cz[ inpoel[4*e+2] ] }},
-    {{ cx[ inpoel[4*e+3] ], cy[ inpoel[4*e+3] ], cz[ inpoel[4*e+3] ] }}
-  }};
-
-  auto jacInv =
-    tk::inverseJacobian( coordel[0], coordel[1], coordel[2], coordel[3] );
-
-  auto dBdx = tk::eval_dBdx_p1( rdof, jacInv );
-
-  std::array< real, 3 > nInt;
-  std::array< real, 3 > ref_n{0.0, 0.0, 0.0};
-  auto almax(0.0);
-  std::size_t kmax(0);
-
-  // Determine index of material present in majority
-  for (std::size_t k=0; k<nmat; ++k)
-  {
-    auto alk = alSol[k*rdof];
-    if (alk > almax)
-    {
-      almax = alk;
-      kmax = k;
-    }
-  }
-
-  // Get normals of material present in majority
-  // Get derivatives from moments in Dubiner space
-  for (std::size_t i=0; i<3; ++i)
-    nInt[i] = dBdx[i][1] * alSol[kmax*rdof+1]
-      + dBdx[i][2] * alSol[kmax*rdof+2]
-      + dBdx[i][3] * alSol[kmax*rdof+3];
-
-  auto nMag = std::sqrt(tk::dot(nInt, nInt)) + 1e-14;
-
-  for (std::size_t i=0; i<3; ++i)
-    nInt[i] /= nMag;
-
-  // project interface normal onto local/reference coordinate system
-  for (std::size_t i=0; i<3; ++i)
-  {
-    std::array< real, 3 > axis{
-      coordel[i+1][0]-coordel[0][0],
-      coordel[i+1][1]-coordel[0][1],
-      coordel[i+1][2]-coordel[0][2] };
-    ref_n[i] = tk::dot(nInt, axis);
-  }
-
-  // Step 2. Reconstruct volume fraction of majority material using THINC
-  // -------------------------------------------------------------------------
-
-  auto al_max = 1.0 - (static_cast<tk::real>(nmat-1)*1.0e-12);
-  auto al_min = 1e-12;
-  auto alsum(0.0);
-  // get location of material interface (volume fraction 0.5) from the
-  // assumed tanh volume fraction distribution, and cell-averaged
-  // volume fraction
-  auto alCC(alSol[kmax*rdof]);
-  auto Ac(0.0), Bc(0.0), Qc(0.0);
-  if ((std::abs(ref_n[0]) > std::abs(ref_n[1]))
-    && (std::abs(ref_n[0]) > std::abs(ref_n[2])))
-  {
-    Ac = std::exp(0.5*beta*ref_n[0]);
-    Bc = std::exp(0.5*beta*(ref_n[1]+ref_n[2]));
-    Qc = std::exp(0.5*beta*ref_n[0]*(2.0*alCC-1.0));
-  }
-  else if ((std::abs(ref_n[1]) > std::abs(ref_n[0]))
-    && (std::abs(ref_n[1]) > std::abs(ref_n[2])))
-  {
-    Ac = std::exp(0.5*beta*ref_n[1]);
-    Bc = std::exp(0.5*beta*(ref_n[0]+ref_n[2]));
-    Qc = std::exp(0.5*beta*ref_n[1]*(2.0*alCC-1.0));
-  }
-  else
-  {
-    Ac = std::exp(0.5*beta*ref_n[2]);
-    Bc = std::exp(0.5*beta*(ref_n[0]+ref_n[1]));
-    Qc = std::exp(0.5*beta*ref_n[2]*(2.0*alCC-1.0));
-  }
-  auto d = std::log((1.0-Ac*Qc) / (Ac*Bc*(Qc-Ac))) / (2.0*beta);
-
-  // THINC reconstruction
-  auto al_c = 0.5 * (1.0 + std::tanh(beta*(tk::dot(ref_n, ref_xp) + d)));
-
-  alReco[kmax] = std::min(al_max, std::max(al_min, al_c));
-  alsum += alReco[kmax];
-
-  // if this material does not have an interface close-by, the TVD
-  // reconstructions must be used for state variables. This is ensured by
-  // initializing the alReco vector as the TVD state.
-  for (std::size_t k=0; k<nmat; ++k) {
-    if (!matInt[k]) {
-      alsum += alReco[k];
-    }
-  }
-
-  // Step 3. Do multimaterial cell corrections
-  // -------------------------------------------------------------------------
-
-  // distribute remaining volume to rest of materials
-  auto sum_left = 1.0 - alsum;
-  real den = 0.0;
-  for (std::size_t k=0; k<nmat; ++k) {
-    if (matInt[k] && k != kmax) {
-      auto mark = k * rdof;
-      alReco[k] = sum_left * alSol[mark];
-      den += alSol[mark];
-    }
-  }
-  // the distributed volfracs might be below al_min, correct that
-  real err = 0.0;
-  for (std::size_t k=0; k<nmat; ++k) {
-    if (matInt[k] && k != kmax) {
-      alReco[k] /= den;
-      if (alReco[k] < al_min) {
-        err += al_min - alReco[k];
-        alReco[k] = al_min;
-      }
-    }
-  }
-
-  // balance out errors
-  alReco[kmax] -= err;
-}
-
-std::vector< tk::real >
-evalPolynomialSol( const std::vector< inciter::EOS >& mat_blk,
-                   int intsharp,
-                   std::size_t ncomp,
-                   std::size_t nprim,
-                   std::size_t rdof,
-                   std::size_t nmat,
-                   std::size_t e,
-                   std::size_t dof_e,
-                   const std::vector< std::size_t >& inpoel,
-                   const UnsMesh::Coords& coord,
-                   const Fields& geoElem,
-                   const std::array< real, 3 >& ref_gp,
-                   const std::vector< real >& B,
-                   const Fields& U,
-                   const Fields& P )
-// *****************************************************************************
-//  Evaluate polynomial solution at quadrature point
-//! \param[in] mat_blk EOS material block
-//! \param[in] intsharp Interface reconstruction indicator
-//! \param[in] ncomp Number of components in the PDE system
-//! \param[in] nprim Number of primitive quantities
-//! \param[in] rdof Total number of reconstructed dofs
-//! \param[in] nmat Total number of materials
-//! \param[in] e Element for which polynomial solution is being evaluated
-//! \param[in] dof_e Degrees of freedom for element
-//! \param[in] inpoel Element-node connectivity
-//! \param[in] coord Array of nodal coordinates
-//! \param[in] geoElem Element geometry array
-//! \param[in] ref_gp Quadrature point in reference space
-//! \param[in] B Basis function at given quadrature point
-//! \param[in] U Solution vector
-//! \param[in] P Vector of primitives
-//! \return High-order unknown/state vector at quadrature point, modified
-//!   if near interfaces using THINC
-// *****************************************************************************
-{
-  std::vector< real > state;
-  std::vector< real > sprim;
-
-  state = eval_state( ncomp, rdof, dof_e, e, U, B );
-  sprim = eval_state( nprim, rdof, dof_e, e, P, B );
-
-  // interface detection
-  std::vector< std::size_t > matInt(nmat, 0);
-  bool intInd(false);
-  if (nmat > 1) {
-    std::vector< tk::real > alAvg(nmat, 0.0);
-    for (std::size_t k=0; k<nmat; ++k)
-      alAvg[k] = U(e, inciter::volfracDofIdx(nmat,k,rdof,0));
-    intInd = inciter::interfaceIndicator(nmat, alAvg, matInt);
-  }
-
-  // consolidate primitives into state vector
-  state.insert(state.end(), sprim.begin(), sprim.end());
-
-  if (intsharp > 0)
-  {
-    std::vector< tk::real > vfmax(nmat, 0.0), vfmin(nmat, 0.0);
-
-    // Until the appropriate setup for activating THINC with Transport
-    // is ready, the following two chunks of code will need to be commented
-    // for using THINC with Transport
-    //for (std::size_t k=0; k<nmat; ++k) {
-    //  vfmin[k] = VolFracMax(el, 2*k, 0);
-    //  vfmax[k] = VolFracMax(el, 2*k+1, 0);
-    //}
-    tk::THINCReco(rdof, nmat, e, inpoel, coord, geoElem,
-      ref_gp, U, P, intInd, matInt, vfmin, vfmax, state);
-
-    // Until the appropriate setup for activating THINC with Transport
-    // is ready, the following lines will need to be uncommented for
-    // using THINC with Transport
-    //tk::THINCRecoTransport(rdof, nmat, el, inpoel, coord,
-    //  geoElem, ref_gp_l, U, P, vfmin, vfmax, state[0]);
-  }
-
-  // physical constraints
-  if (state.size() > ncomp) {
-    using inciter::pressureIdx;
-    using inciter::volfracIdx;
-    using inciter::densityIdx;
-
-    for (std::size_t k=0; k<nmat; ++k) {
-      state[ncomp+pressureIdx(nmat,k)] = constrain_pressure( mat_blk,
-        state[ncomp+pressureIdx(nmat,k)], state[densityIdx(nmat,k)],
-        state[volfracIdx(nmat,k)], k );
-    }
-  }
-
-  return state;
-}
-
-std::vector< tk::real >
-evalFVSol( const std::vector< inciter::EOS >& mat_blk,
-           int intsharp,
-           std::size_t ncomp,
-           std::size_t nprim,
-           std::size_t rdof,
-           std::size_t nmat,
-           std::size_t e,
-           const std::vector< std::size_t >& inpoel,
-           const UnsMesh::Coords& coord,
-           const Fields& geoElem,
-           const std::array< real, 3 >& ref_gp,
-           const std::vector< real >& B,
-           const Fields& U,
-           const Fields& P,
-           int srcFlag )
-// *****************************************************************************
-//  Evaluate second-order FV solution at quadrature point
-//! \param[in] mat_blk EOS material block
-//! \param[in] intsharp Interface reconstruction indicator
-//! \param[in] ncomp Number of components in the PDE system
-//! \param[in] nprim Number of primitive quantities
-//! \param[in] rdof Total number of reconstructed dofs
-//! \param[in] nmat Total number of materials
-//! \param[in] e Element for which polynomial solution is being evaluated
-//! \param[in] inpoel Element-node connectivity
-//! \param[in] coord Array of nodal coordinates
-//! \param[in] geoElem Element geometry array
-//! \param[in] ref_gp Quadrature point in reference space
-//! \param[in] B Basis function at given quadrature point
-//! \param[in] U Solution vector
-//! \param[in] P Vector of primitives
-//! \param[in] srcFlag Whether the energy source was added to element e
-//! \return High-order unknown/state vector at quadrature point, modified
-//!   if near interfaces using THINC
-// *****************************************************************************
-{
-  using inciter::pressureIdx;
-  using inciter::velocityIdx;
-  using inciter::volfracIdx;
-  using inciter::densityIdx;
-  using inciter::energyIdx;
-  using inciter::momentumIdx;
-
-  std::vector< real > state;
-  std::vector< real > sprim;
-
-  state = eval_state( ncomp, rdof, rdof, e, U, B );
-  sprim = eval_state( nprim, rdof, rdof, e, P, B );
-
-  // interface detection so that eos is called on the appropriate quantities
-  std::vector< std::size_t > matInt(nmat, 0);
-  std::vector< tk::real > alAvg(nmat, 0.0);
-  for (std::size_t k=0; k<nmat; ++k)
-    alAvg[k] = U(e, inciter::volfracDofIdx(nmat,k,rdof,0));
-  auto intInd = inciter::interfaceIndicator(nmat, alAvg, matInt);
-
-  // get mat-energy from reconstructed mat-pressure
-  auto rhob(0.0);
-  for (std::size_t k=0; k<nmat; ++k) {
-    auto alk = state[volfracIdx(nmat,k)];
-    if (matInt[k]) {
-      alk = std::max(std::min(alk, 1.0-static_cast<tk::real>(nmat-1)*1e-12),
-        1e-12);
-    }
-    state[energyIdx(nmat,k)] = alk *
-      mat_blk[k].compute< inciter::EOS::totalenergy >(
-      state[densityIdx(nmat,k)]/alk, sprim[velocityIdx(nmat,0)],
-      sprim[velocityIdx(nmat,1)], sprim[velocityIdx(nmat,2)],
-      sprim[pressureIdx(nmat,k)]/alk);
-    rhob += state[densityIdx(nmat,k)];
-  }
-  // get momentum from reconstructed velocity and bulk density
-  for (std::size_t i=0; i<3; ++i) {
-    state[momentumIdx(nmat,i)] = rhob * sprim[velocityIdx(nmat,i)];
-  }
-
-  // consolidate primitives into state vector
-  state.insert(state.end(), sprim.begin(), sprim.end());
-
-  if (intsharp > 0 && srcFlag == 0)
-  {
-    std::vector< tk::real > vfmax(nmat, 0.0), vfmin(nmat, 0.0);
-
-    tk::THINCReco(rdof, nmat, e, inpoel, coord, geoElem,
-      ref_gp, U, P, intInd, matInt, vfmin, vfmax, state);
-  }
-
-  // physical constraints
-  if (state.size() > ncomp) {
-    for (std::size_t k=0; k<nmat; ++k) {
-      state[ncomp+pressureIdx(nmat,k)] = constrain_pressure( mat_blk,
-        state[ncomp+pressureIdx(nmat,k)], state[densityIdx(nmat,k)],
-        state[volfracIdx(nmat,k)], k );
-    }
-  }
-
-  return state;
-}
-
-void
-safeReco( std::size_t rdof,
-          std::size_t nmat,
-          std::size_t el,
-          int er,
-          const Fields& U,
-          std::array< std::vector< real >, 2 >& state )
-// *****************************************************************************
-//  Compute safe reconstructions near material interfaces
-//! \param[in] rdof Total number of reconstructed dofs
-//! \param[in] nmat Total number of material is PDE system
-//! \param[in] el Element on the left-side of face
-//! \param[in] er Element on the right-side of face
-//! \param[in] U Solution vector at recent time-stage
-//! \param[in,out] state Second-order reconstructed state, at cell-face, that
-//!   is being modified for safety
-//! \details When the consistent limiting is applied, there is a possibility
-//!   that the material densities and energies violate TVD bounds. This function
-//!   enforces the TVD bounds locally
-// *****************************************************************************
-{
-  using inciter::densityIdx;
-  using inciter::energyIdx;
-  using inciter::densityDofIdx;
-  using inciter::energyDofIdx;
-
-  if (er < 0) Throw("safe limiting cannot be called for boundary cells");
-
-  auto eR = static_cast< std::size_t >(er);
-
-  // define a lambda for the safe limiting
-  auto safeLimit = [&]( std::size_t c, real ul, real ur )
-  {
-    // find min/max at the face
-    auto uMin = std::min(ul, ur);
-    auto uMax = std::max(ul, ur);
-
-    // left-state limiting
-    state[0][c] = std::min(uMax, std::max(uMin, state[0][c]));
-
-    // right-state limiting
-    state[1][c] = std::min(uMax, std::max(uMin, state[1][c]));
-  };
-
-  for (std::size_t k=0; k<nmat; ++k)
-  {
-    real ul(0.0), ur(0.0);
-
-    // Density
-    // establish left- and right-hand states
-    ul = U(el, densityDofIdx(nmat, k, rdof, 0));
-    ur = U(eR, densityDofIdx(nmat, k, rdof, 0));
-
-    // limit reconstructed density
-    safeLimit(densityIdx(nmat,k), ul, ur);
-
-    // Energy
-    // establish left- and right-hand states
-    ul = U(el, energyDofIdx(nmat, k, rdof, 0));
-    ur = U(eR, energyDofIdx(nmat, k, rdof, 0));
-
-    // limit reconstructed energy
-    safeLimit(energyIdx(nmat,k), ul, ur);
-  }
-}
-
-} // tk::
+#include <map>
+#include <set>
+#include <string>
+#include <vector>
+#include <iostream>
+
+#include "NoWarning/back.hpp"
+#include "NoWarning/front.hpp"
+
+#include "Tags.hpp"
+#include "Types.hpp"
+#include "Exception.hpp"
+#include "Factory.hpp"
+#include "CGPDE.hpp"
+#include "DGPDE.hpp"
+#include "FVPDE.hpp"
+#include "PDEFactory.hpp"
+#include "Inciter/InputDeck/InputDeck.hpp"
+
+namespace inciter {
+
+extern ctr::InputDeck g_inputdeck;
+
+//! \brief Partial differential equations stack
+class PDEStack {
+
+  private:
+    using ncomp_t = tk::ncomp_t;
+
+  public:
+    //! Constructor: register partial differential equations into factory
+    explicit PDEStack();
+
+    //! Instantiate selected PDEs using continuous Galerkin discretization
+    std::vector< CGPDE > selectedCG() const;
+
+    //! Instantiate selected PDEs using discontinuous Galerkin discretization
+    std::vector< DGPDE > selectedDG() const;
+
+    //! Instantiate selected PDEs using finite volume discretization
+    std::vector< FVPDE > selectedFV() const;
+
+    //! Constant accessor to CGPDE factory
+    //! \return Constant reference to the CGPDE factory
+    const CGFactory& cgfactory() const { return m_cgfactory; }
+
+    //! Constant accessor to DGPDE factory
+    //! \return Constant reference to the DGPDE factory
+    const DGFactory& dgfactory() const { return m_dgfactory; }
+
+    //! Constant accessor to FVPDE factory
+    //! \return Constant reference to the FVPDE factory
+    const FVFactory& fvfactory() const { return m_fvfactory; }
+
+    //! Return info on selected partial differential equations
+    std::vector< std::vector< std::pair< std::string, std::string > > > info()
+    const;
+
+    //! Return number of unique equation types registered into the CG factory
+    //! \return The number of unique equation types registered into the CG
+    //!   factory the factory
+    std::size_t cgntypes() const { return m_cgEqTypes.size(); }
+
+    //! Return number of unique equation types registered into the DG factory
+    //! \return The number of unique equation types registered into the DG
+    //!   factory the factory
+    std::size_t dgntypes() const { return m_dgEqTypes.size(); }
+
+    //! Return number of unique equation types registered into the FV factory
+    //! \return The number of unique equation types registered into the FV
+    //!   factory the factory
+    std::size_t fvntypes() const { return m_fvEqTypes.size(); }
+
+  private:
+    //! \brief Instantiate a partial differential equation
+    //! \details The template argument, EqTag, is used to find the given
+    //!   partial differential equation in the input deck, the hierarchical data
+    //!   filled during control file parsing, containing user input. The
+    //!   template argument Factory specifies which factory we search in. The
+    //!   template argument PDE specifies the "base" PDE type that the
+    //!   instantiated "child" PDE class object is used polymorphically with.
+    //! \param[in] f Factory in which to search PDE in
+    //! \param[in] eq The unique partial differential equation key whose object
+    //!   to instantiate.
+    //! \param[in,out] cnt Counter, a std::map, that counts all instantiated
+    //!   partial differential equations by type.
+    template< class EqTag, class Factory, class PDE >
+    PDE createPDE( const Factory& f,
+                   ctr::PDEType eq,
+                   std::map< ctr::PDEType, ncomp_t >& cnt ) const
+    {
+      auto c = ++cnt[ eq ];   // count eqs
+      --c;                    // used to index vectors starting with 0<--- Variable 'c' is assigned a value that is never used.
+      const auto& nc = g_inputdeck.get< tag::ncomp >();
+      if ( nc ) {
+        // re-create key and search for it
+        auto prob = g_inputdeck.get< EqTag, tag::problem >();
+        // if more than one mesh, set problem type for all additional meshes
+        // as user-defined
+        if (cnt[eq] > 1) prob = ctr::ProblemType::USER_DEFINED;
+        ctr::PDEKey key{{ eq,
+          g_inputdeck.get< EqTag, tag::physics >(), prob }};
+        const auto it = f.find( key );
+        Assert( it != end( f ),
+                "Can't find PDE with key('" +
+                  ctr::PDE().name( key.get< tag::pde >() ) + "', '" +
+                  ctr::Physics().name( key.get< tag::physics >() ) + "', '" +
+                  ctr::Problem().name( key.get< tag::problem >() ) +
+                  + "') in factory" );
+        // Associate equation system index (value) to all variable offsets
+        for (ncomp_t i=0; i<nc; ++i) g_inputdeck.get<tag::sys>()[i] = c;
+        // instantiate and return PDE object
+        return it->second();
+      } else Throw ( "Can't create PDE with zero components" );
+    }
+
+    //! Wrapper of createPDE specialized for registering CG PDEs
+    //! \param[in] t Enum selecting PDE type, Control/Inciter/Options/PDE.h
+    //! \param[in,out] cnt Counter, a std::map, that counts all instantiated
+    //!   partial differential equations by type.
+    //! \details The sole reason for this function is to simplify client-code
+    //!   calling createPDE specialized to CG PDEs
+    template< class EqTag >
+    CGPDE createCG( ctr::PDEType t, std::map< ctr::PDEType, ncomp_t >& cnt )
+    const {
+      return createPDE< EqTag, CGFactory, CGPDE >( m_cgfactory, t, cnt );
+    }
+
+    //! Wrapper of createPDE specialized for registering DG PDEs
+    //! \param[in] t Enum selecting PDE type, Control/Inciter/Options/PDE.h
+    //! \param[in,out] cnt Counter, a std::map, that counts all instantiated
+    //!   partial differential equations by type.
+    //! \details The sole reason for this function is to simplify client-code
+    //!   calling createPDE specialized to DG PDEs
+    template< class EqTag >
+    DGPDE createDG( ctr::PDEType t, std::map< ctr::PDEType, ncomp_t >& cnt )
+    const {
+      return createPDE< EqTag, DGFactory, DGPDE >( m_dgfactory, t, cnt );
+    }
+
+    //! Wrapper of createPDE specialized for registering FV PDEs
+    //! \param[in] t Enum selecting PDE type, Control/Inciter/Options/PDE.h
+    //! \param[in,out] cnt Counter, a std::map, that counts all instantiated
+    //!   partial differential equations by type.
+    //! \details The sole reason for this function is to simplify client-code
+    //!   calling createPDE specialized to FV PDEs
+    template< class EqTag >
+    FVPDE createFV( ctr::PDEType t, std::map< ctr::PDEType, ncomp_t >& cnt )
+    const {
+      return createPDE< EqTag, FVFactory, FVPDE >( m_fvfactory, t, cnt );
+    }
+
+    //! PDE factory for continuous Galerkin discretization
+    CGFactory m_cgfactory;
+    //! PDE factory for discontinuous Galerkin discretization
+    DGFactory m_dgfactory;
+    //! PDE factory for finite volume discretization
+    FVFactory m_fvfactory;
+    //! Counters for equation types registered into the CG factory
+    std::set< ctr::PDEType > m_cgEqTypes;
+    //! Counters for equation types registered into the DG factory
+    std::set< ctr::PDEType > m_dgEqTypes;
+    //! Counters for equation types registered into the FV factory
+    std::set< ctr::PDEType > m_fvEqTypes;
+};
+
+} // inciter::
+
+#endif // PDEStack_h
 
diff --git a/Debug/cppcheck/74.html b/Debug/cppcheck/74.html index a05eedfe6139..209fb26f128a 100644 --- a/Debug/cppcheck/74.html +++ b/Debug/cppcheck/74.html @@ -152,183 +152,2531 @@
- - + @@ -217,7 +217,7 @@ - + @@ -225,7 +225,7 @@ - + @@ -1105,7 +1105,7 @@ - + @@ -1533,7 +1533,7 @@ - + @@ -1797,7 +1797,7 @@ - + @@ -1805,7 +1805,7 @@ - + @@ -1833,7 +1833,7 @@ - + @@ -1841,7 +1841,7 @@ - + @@ -2249,7 +2249,7 @@ - + @@ -2309,11 +2309,11 @@ - + - + diff --git a/Debug/test_coverage/Base/TaggedTuple.hpp.gcov.html b/Debug/test_coverage/Base/TaggedTuple.hpp.gcov.html index 8068a5bf8aeb..84e15d7858a6 100644 --- a/Debug/test_coverage/Base/TaggedTuple.hpp.gcov.html +++ b/Debug/test_coverage/Base/TaggedTuple.hpp.gcov.html @@ -33,7 +33,7 @@ - + @@ -173,7 +173,7 @@ 99 : : is_tagged_tuple_t< std::decay_t< TupleElement<Tag> > >; 100 : : 101 : : //! Default constructor - 102 : 268307 : explicit TaggedTuple() = default; + 102 : 268047 : explicit TaggedTuple() = default; 103 : : //! Initializer constructor 104 : 223177 : explicit TaggedTuple( Tuple&& tuple ) : m_members( std::move(tuple) ) {} 105 : : @@ -192,12 +192,12 @@ 118 : : 119 : : //! Reference data member accessor of field of tagged tuple at depth 120 : : template< typename Tag, typename... Tags > - 121 : 582462945 : auto& get() noexcept { - 122 : 582462945 : constexpr std::size_t idx = brigand::index_of< Keys, Tag >::value; + 121 : 585549945 : auto& get() noexcept { + 122 : 585549945 : constexpr std::size_t idx = brigand::index_of< Keys, Tag >::value; 123 : : if constexpr( is_tagged_tuple<Tag>::value and sizeof...(Tags) != 0 ) - 124 : 225890209 : return std::get< idx >( m_members ).template get< Tags... >(); + 124 : 227433709 : return std::get< idx >( m_members ).template get< Tags... >(); 125 : : else - 126 : 356572736 : return std::get< idx >( m_members ); + 126 : 358116236 : return std::get< idx >( m_members ); 127 : : } 128 : : 129 : : //! Convert and store value converting from string at depth @@ -245,11 +245,11 @@ 171 : : ///@{ 172 : : //! \brief Pack/Unpack serialize member function 173 : : //! \param[in,out] p Charm++'s PUP::er serializer object reference - 174 : 507838 : void pup( PUP::er& p ) { p | m_members; } + 174 : 507058 : void pup( PUP::er& p ) { p | m_members; } 175 : : //! \brief Pack/Unpack serialize operator| 176 : : //! \param[in,out] p Charm++'s PUP::er serializer object reference 177 : : //! \param[in,out] t TaggedTuple object reference - 178 : 504231 : friend void operator|( PUP::er& p, TaggedTuple<List>& t ) { t.pup(p); } + 178 : 503451 : friend void operator|( PUP::er& p, TaggedTuple<List>& t ) { t.pup(p); } 179 : : //@} 180 : : 181 : : //! Convert/parse string to and return as type given by template argument diff --git a/Debug/test_coverage/Base/TaggedTupleDeepPrint.hpp.func-sort-c.html b/Debug/test_coverage/Base/TaggedTupleDeepPrint.hpp.func-sort-c.html index 61ed463317d6..b359094c9461 100644 --- a/Debug/test_coverage/Base/TaggedTupleDeepPrint.hpp.func-sort-c.html +++ b/Debug/test_coverage/Base/TaggedTupleDeepPrint.hpp.func-sort-c.html @@ -33,7 +33,7 @@ - + diff --git a/Debug/test_coverage/Base/TaggedTupleDeepPrint.hpp.func.html b/Debug/test_coverage/Base/TaggedTupleDeepPrint.hpp.func.html index 7bc0330bc859..516734643dc4 100644 --- a/Debug/test_coverage/Base/TaggedTupleDeepPrint.hpp.func.html +++ b/Debug/test_coverage/Base/TaggedTupleDeepPrint.hpp.func.html @@ -33,7 +33,7 @@ - + diff --git a/Debug/test_coverage/Base/TaggedTupleDeepPrint.hpp.gcov.html b/Debug/test_coverage/Base/TaggedTupleDeepPrint.hpp.gcov.html index 92ff22034134..d6b2483a3e6e 100644 --- a/Debug/test_coverage/Base/TaggedTupleDeepPrint.hpp.gcov.html +++ b/Debug/test_coverage/Base/TaggedTupleDeepPrint.hpp.gcov.html @@ -33,7 +33,7 @@ - + diff --git a/Debug/test_coverage/Base/TaggedTuplePrint.hpp.func-sort-c.html b/Debug/test_coverage/Base/TaggedTuplePrint.hpp.func-sort-c.html index 0b41c2eb1758..14c09924abfd 100644 --- a/Debug/test_coverage/Base/TaggedTuplePrint.hpp.func-sort-c.html +++ b/Debug/test_coverage/Base/TaggedTuplePrint.hpp.func-sort-c.html @@ -33,7 +33,7 @@ - + diff --git a/Debug/test_coverage/Base/TaggedTuplePrint.hpp.func.html b/Debug/test_coverage/Base/TaggedTuplePrint.hpp.func.html index 91f23b216790..dc841cfbeaf1 100644 --- a/Debug/test_coverage/Base/TaggedTuplePrint.hpp.func.html +++ b/Debug/test_coverage/Base/TaggedTuplePrint.hpp.func.html @@ -33,7 +33,7 @@ - + diff --git a/Debug/test_coverage/Base/TaggedTuplePrint.hpp.gcov.html b/Debug/test_coverage/Base/TaggedTuplePrint.hpp.gcov.html index 3665e774741f..e3f3a019af3a 100644 --- a/Debug/test_coverage/Base/TaggedTuplePrint.hpp.gcov.html +++ b/Debug/test_coverage/Base/TaggedTuplePrint.hpp.gcov.html @@ -33,7 +33,7 @@ - + diff --git a/Debug/test_coverage/Base/TeeBuf.hpp.func-sort-c.html b/Debug/test_coverage/Base/TeeBuf.hpp.func-sort-c.html index 9ae655719085..e50d6fb44e46 100644 --- a/Debug/test_coverage/Base/TeeBuf.hpp.func-sort-c.html +++ b/Debug/test_coverage/Base/TeeBuf.hpp.func-sort-c.html @@ -33,7 +33,7 @@ - + diff --git a/Debug/test_coverage/Base/TeeBuf.hpp.func.html b/Debug/test_coverage/Base/TeeBuf.hpp.func.html index bec09b4d252c..3b279b000e15 100644 --- a/Debug/test_coverage/Base/TeeBuf.hpp.func.html +++ b/Debug/test_coverage/Base/TeeBuf.hpp.func.html @@ -33,7 +33,7 @@ - + diff --git a/Debug/test_coverage/Base/TeeBuf.hpp.gcov.html b/Debug/test_coverage/Base/TeeBuf.hpp.gcov.html index 15e9e2d1155e..93751b380b3c 100644 --- a/Debug/test_coverage/Base/TeeBuf.hpp.gcov.html +++ b/Debug/test_coverage/Base/TeeBuf.hpp.gcov.html @@ -33,7 +33,7 @@ - + diff --git a/Debug/test_coverage/Base/Timer.cpp.func-sort-c.html b/Debug/test_coverage/Base/Timer.cpp.func-sort-c.html index 02ff18229ee2..c0ddd88ea84a 100644 --- a/Debug/test_coverage/Base/Timer.cpp.func-sort-c.html +++ b/Debug/test_coverage/Base/Timer.cpp.func-sort-c.html @@ -33,7 +33,7 @@ - + diff --git a/Debug/test_coverage/Base/Timer.cpp.func.html b/Debug/test_coverage/Base/Timer.cpp.func.html index 3373da320bf4..25fc1f3109f4 100644 --- a/Debug/test_coverage/Base/Timer.cpp.func.html +++ b/Debug/test_coverage/Base/Timer.cpp.func.html @@ -33,7 +33,7 @@ - + diff --git a/Debug/test_coverage/Base/Timer.cpp.gcov.html b/Debug/test_coverage/Base/Timer.cpp.gcov.html index 7283fc53aa5e..df5c3f5b7c42 100644 --- a/Debug/test_coverage/Base/Timer.cpp.gcov.html +++ b/Debug/test_coverage/Base/Timer.cpp.gcov.html @@ -33,7 +33,7 @@ - + diff --git a/Debug/test_coverage/Base/Timer.hpp.func-sort-c.html b/Debug/test_coverage/Base/Timer.hpp.func-sort-c.html index 3ab7cf18e2f8..97e2b5eb2a7f 100644 --- a/Debug/test_coverage/Base/Timer.hpp.func-sort-c.html +++ b/Debug/test_coverage/Base/Timer.hpp.func-sort-c.html @@ -33,7 +33,7 @@ - + @@ -85,7 +85,7 @@ - + @@ -93,11 +93,11 @@ - + - +
 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
-10
-11
-12
-13
-14
-15
-16
-17
-18
-19
-20
-21
-22
-23
-24
-25
-26
-27
-28
-29
-30
-31
-32
-33
-34
-35
-36
-37
-38
-39
-40
-41
-42
-43
-44
-45
-46
-47
-48
-49
-50
-51
-52
-53
-54
-55
-56
-57
-58
-59
-60
-61
-62
-63
-64
-65
-66
-67
-68
-69
-70
-71
-72
-73
-74
-75
-76
-77
-78
-79
-80
-81
-82
-83
-84
-85
// *****************************************************************************
+
   1
+   2
+   3
+   4
+   5
+   6
+   7
+   8
+   9
+  10
+  11
+  12
+  13
+  14
+  15
+  16
+  17
+  18
+  19
+  20
+  21
+  22
+  23
+  24
+  25
+  26
+  27
+  28
+  29
+  30
+  31
+  32
+  33
+  34
+  35
+  36
+  37
+  38
+  39
+  40
+  41
+  42
+  43
+  44
+  45
+  46
+  47
+  48
+  49
+  50
+  51
+  52
+  53
+  54
+  55
+  56
+  57
+  58
+  59
+  60
+  61
+  62
+  63
+  64
+  65
+  66
+  67
+  68
+  69
+  70
+  71
+  72
+  73
+  74
+  75
+  76
+  77
+  78
+  79
+  80
+  81
+  82
+  83
+  84
+  85
+  86
+  87
+  88
+  89
+  90
+  91
+  92
+  93
+  94
+  95
+  96
+  97
+  98
+  99
+ 100
+ 101
+ 102
+ 103
+ 104
+ 105
+ 106
+ 107
+ 108
+ 109
+ 110
+ 111
+ 112
+ 113
+ 114
+ 115
+ 116
+ 117
+ 118
+ 119
+ 120
+ 121
+ 122
+ 123
+ 124
+ 125
+ 126
+ 127
+ 128
+ 129
+ 130
+ 131
+ 132
+ 133
+ 134
+ 135
+ 136
+ 137
+ 138
+ 139
+ 140
+ 141
+ 142
+ 143
+ 144
+ 145
+ 146
+ 147
+ 148
+ 149
+ 150
+ 151
+ 152
+ 153
+ 154
+ 155
+ 156
+ 157
+ 158
+ 159
+ 160
+ 161
+ 162
+ 163
+ 164
+ 165
+ 166
+ 167
+ 168
+ 169
+ 170
+ 171
+ 172
+ 173
+ 174
+ 175
+ 176
+ 177
+ 178
+ 179
+ 180
+ 181
+ 182
+ 183
+ 184
+ 185
+ 186
+ 187
+ 188
+ 189
+ 190
+ 191
+ 192
+ 193
+ 194
+ 195
+ 196
+ 197
+ 198
+ 199
+ 200
+ 201
+ 202
+ 203
+ 204
+ 205
+ 206
+ 207
+ 208
+ 209
+ 210
+ 211
+ 212
+ 213
+ 214
+ 215
+ 216
+ 217
+ 218
+ 219
+ 220
+ 221
+ 222
+ 223
+ 224
+ 225
+ 226
+ 227
+ 228
+ 229
+ 230
+ 231
+ 232
+ 233
+ 234
+ 235
+ 236
+ 237
+ 238
+ 239
+ 240
+ 241
+ 242
+ 243
+ 244
+ 245
+ 246
+ 247
+ 248
+ 249
+ 250
+ 251
+ 252
+ 253
+ 254
+ 255
+ 256
+ 257
+ 258
+ 259
+ 260
+ 261
+ 262
+ 263
+ 264
+ 265
+ 266
+ 267
+ 268
+ 269
+ 270
+ 271
+ 272
+ 273
+ 274
+ 275
+ 276
+ 277
+ 278
+ 279
+ 280
+ 281
+ 282
+ 283
+ 284
+ 285
+ 286
+ 287
+ 288
+ 289
+ 290
+ 291
+ 292
+ 293
+ 294
+ 295
+ 296
+ 297
+ 298
+ 299
+ 300
+ 301
+ 302
+ 303
+ 304
+ 305
+ 306
+ 307
+ 308
+ 309
+ 310
+ 311
+ 312
+ 313
+ 314
+ 315
+ 316
+ 317
+ 318
+ 319
+ 320
+ 321
+ 322
+ 323
+ 324
+ 325
+ 326
+ 327
+ 328
+ 329
+ 330
+ 331
+ 332
+ 333
+ 334
+ 335
+ 336
+ 337
+ 338
+ 339
+ 340
+ 341
+ 342
+ 343
+ 344
+ 345
+ 346
+ 347
+ 348
+ 349
+ 350
+ 351
+ 352
+ 353
+ 354
+ 355
+ 356
+ 357
+ 358
+ 359
+ 360
+ 361
+ 362
+ 363
+ 364
+ 365
+ 366
+ 367
+ 368
+ 369
+ 370
+ 371
+ 372
+ 373
+ 374
+ 375
+ 376
+ 377
+ 378
+ 379
+ 380
+ 381
+ 382
+ 383
+ 384
+ 385
+ 386
+ 387
+ 388
+ 389
+ 390
+ 391
+ 392
+ 393
+ 394
+ 395
+ 396
+ 397
+ 398
+ 399
+ 400
+ 401
+ 402
+ 403
+ 404
+ 405
+ 406
+ 407
+ 408
+ 409
+ 410
+ 411
+ 412
+ 413
+ 414
+ 415
+ 416
+ 417
+ 418
+ 419
+ 420
+ 421
+ 422
+ 423
+ 424
+ 425
+ 426
+ 427
+ 428
+ 429
+ 430
+ 431
+ 432
+ 433
+ 434
+ 435
+ 436
+ 437
+ 438
+ 439
+ 440
+ 441
+ 442
+ 443
+ 444
+ 445
+ 446
+ 447
+ 448
+ 449
+ 450
+ 451
+ 452
+ 453
+ 454
+ 455
+ 456
+ 457
+ 458
+ 459
+ 460
+ 461
+ 462
+ 463
+ 464
+ 465
+ 466
+ 467
+ 468
+ 469
+ 470
+ 471
+ 472
+ 473
+ 474
+ 475
+ 476
+ 477
+ 478
+ 479
+ 480
+ 481
+ 482
+ 483
+ 484
+ 485
+ 486
+ 487
+ 488
+ 489
+ 490
+ 491
+ 492
+ 493
+ 494
+ 495
+ 496
+ 497
+ 498
+ 499
+ 500
+ 501
+ 502
+ 503
+ 504
+ 505
+ 506
+ 507
+ 508
+ 509
+ 510
+ 511
+ 512
+ 513
+ 514
+ 515
+ 516
+ 517
+ 518
+ 519
+ 520
+ 521
+ 522
+ 523
+ 524
+ 525
+ 526
+ 527
+ 528
+ 529
+ 530
+ 531
+ 532
+ 533
+ 534
+ 535
+ 536
+ 537
+ 538
+ 539
+ 540
+ 541
+ 542
+ 543
+ 544
+ 545
+ 546
+ 547
+ 548
+ 549
+ 550
+ 551
+ 552
+ 553
+ 554
+ 555
+ 556
+ 557
+ 558
+ 559
+ 560
+ 561
+ 562
+ 563
+ 564
+ 565
+ 566
+ 567
+ 568
+ 569
+ 570
+ 571
+ 572
+ 573
+ 574
+ 575
+ 576
+ 577
+ 578
+ 579
+ 580
+ 581
+ 582
+ 583
+ 584
+ 585
+ 586
+ 587
+ 588
+ 589
+ 590
+ 591
+ 592
+ 593
+ 594
+ 595
+ 596
+ 597
+ 598
+ 599
+ 600
+ 601
+ 602
+ 603
+ 604
+ 605
+ 606
+ 607
+ 608
+ 609
+ 610
+ 611
+ 612
+ 613
+ 614
+ 615
+ 616
+ 617
+ 618
+ 619
+ 620
+ 621
+ 622
+ 623
+ 624
+ 625
+ 626
+ 627
+ 628
+ 629
+ 630
+ 631
+ 632
+ 633
+ 634
+ 635
+ 636
+ 637
+ 638
+ 639
+ 640
+ 641
+ 642
+ 643
+ 644
+ 645
+ 646
+ 647
+ 648
+ 649
+ 650
+ 651
+ 652
+ 653
+ 654
+ 655
+ 656
+ 657
+ 658
+ 659
+ 660
+ 661
+ 662
+ 663
+ 664
+ 665
+ 666
+ 667
+ 668
+ 669
+ 670
+ 671
+ 672
+ 673
+ 674
+ 675
+ 676
+ 677
+ 678
+ 679
+ 680
+ 681
+ 682
+ 683
+ 684
+ 685
+ 686
+ 687
+ 688
+ 689
+ 690
+ 691
+ 692
+ 693
+ 694
+ 695
+ 696
+ 697
+ 698
+ 699
+ 700
+ 701
+ 702
+ 703
+ 704
+ 705
+ 706
+ 707
+ 708
+ 709
+ 710
+ 711
+ 712
+ 713
+ 714
+ 715
+ 716
+ 717
+ 718
+ 719
+ 720
+ 721
+ 722
+ 723
+ 724
+ 725
+ 726
+ 727
+ 728
+ 729
+ 730
+ 731
+ 732
+ 733
+ 734
+ 735
+ 736
+ 737
+ 738
+ 739
+ 740
+ 741
+ 742
+ 743
+ 744
+ 745
+ 746
+ 747
+ 748
+ 749
+ 750
+ 751
+ 752
+ 753
+ 754
+ 755
+ 756
+ 757
+ 758
+ 759
+ 760
+ 761
+ 762
+ 763
+ 764
+ 765
+ 766
+ 767
+ 768
+ 769
+ 770
+ 771
+ 772
+ 773
+ 774
+ 775
+ 776
+ 777
+ 778
+ 779
+ 780
+ 781
+ 782
+ 783
+ 784
+ 785
+ 786
+ 787
+ 788
+ 789
+ 790
+ 791
+ 792
+ 793
+ 794
+ 795
+ 796
+ 797
+ 798
+ 799
+ 800
+ 801
+ 802
+ 803
+ 804
+ 805
+ 806
+ 807
+ 808
+ 809
+ 810
+ 811
+ 812
+ 813
+ 814
+ 815
+ 816
+ 817
+ 818
+ 819
+ 820
+ 821
+ 822
+ 823
+ 824
+ 825
+ 826
+ 827
+ 828
+ 829
+ 830
+ 831
+ 832
+ 833
+ 834
+ 835
+ 836
+ 837
+ 838
+ 839
+ 840
+ 841
+ 842
+ 843
+ 844
+ 845
+ 846
+ 847
+ 848
+ 849
+ 850
+ 851
+ 852
+ 853
+ 854
+ 855
+ 856
+ 857
+ 858
+ 859
+ 860
+ 861
+ 862
+ 863
+ 864
+ 865
+ 866
+ 867
+ 868
+ 869
+ 870
+ 871
+ 872
+ 873
+ 874
+ 875
+ 876
+ 877
+ 878
+ 879
+ 880
+ 881
+ 882
+ 883
+ 884
+ 885
+ 886
+ 887
+ 888
+ 889
+ 890
+ 891
+ 892
+ 893
+ 894
+ 895
+ 896
+ 897
+ 898
+ 899
+ 900
+ 901
+ 902
+ 903
+ 904
+ 905
+ 906
+ 907
+ 908
+ 909
+ 910
+ 911
+ 912
+ 913
+ 914
+ 915
+ 916
+ 917
+ 918
+ 919
+ 920
+ 921
+ 922
+ 923
+ 924
+ 925
+ 926
+ 927
+ 928
+ 929
+ 930
+ 931
+ 932
+ 933
+ 934
+ 935
+ 936
+ 937
+ 938
+ 939
+ 940
+ 941
+ 942
+ 943
+ 944
+ 945
+ 946
+ 947
+ 948
+ 949
+ 950
+ 951
+ 952
+ 953
+ 954
+ 955
+ 956
+ 957
+ 958
+ 959
+ 960
+ 961
+ 962
+ 963
+ 964
+ 965
+ 966
+ 967
+ 968
+ 969
+ 970
+ 971
+ 972
+ 973
+ 974
+ 975
+ 976
+ 977
+ 978
+ 979
+ 980
+ 981
+ 982
+ 983
+ 984
+ 985
+ 986
+ 987
+ 988
+ 989
+ 990
+ 991
+ 992
+ 993
+ 994
+ 995
+ 996
+ 997
+ 998
+ 999
+1000
+1001
+1002
+1003
+1004
+1005
+1006
+1007
+1008
+1009
+1010
+1011
+1012
+1013
+1014
+1015
+1016
+1017
+1018
+1019
+1020
+1021
+1022
+1023
+1024
+1025
+1026
+1027
+1028
+1029
+1030
+1031
+1032
+1033
+1034
+1035
+1036
+1037
+1038
+1039
+1040
+1041
+1042
+1043
+1044
+1045
+1046
+1047
+1048
+1049
+1050
+1051
+1052
+1053
+1054
+1055
+1056
+1057
+1058
+1059
+1060
+1061
+1062
+1063
+1064
+1065
+1066
+1067
+1068
+1069
+1070
+1071
+1072
+1073
+1074
+1075
+1076
+1077
+1078
+1079
+1080
+1081
+1082
+1083
+1084
+1085
+1086
+1087
+1088
+1089
+1090
+1091
+1092
+1093
+1094
+1095
+1096
+1097
+1098
+1099
+1100
+1101
+1102
+1103
+1104
+1105
+1106
+1107
+1108
+1109
+1110
+1111
+1112
+1113
+1114
+1115
+1116
+1117
+1118
+1119
+1120
+1121
+1122
+1123
+1124
+1125
+1126
+1127
+1128
+1129
+1130
+1131
+1132
+1133
+1134
+1135
+1136
+1137
+1138
+1139
+1140
+1141
+1142
+1143
+1144
+1145
+1146
+1147
+1148
+1149
+1150
+1151
+1152
+1153
+1154
+1155
+1156
+1157
+1158
+1159
+1160
+1161
+1162
+1163
+1164
+1165
+1166
+1167
+1168
+1169
+1170
+1171
+1172
+1173
+1174
+1175
+1176
+1177
+1178
+1179
+1180
+1181
+1182
+1183
+1184
+1185
+1186
+1187
+1188
+1189
+1190
+1191
+1192
+1193
+1194
+1195
+1196
+1197
+1198
+1199
+1200
+1201
+1202
+1203
+1204
+1205
+1206
+1207
+1208
+1209
+1210
+1211
+1212
+1213
+1214
+1215
+1216
+1217
+1218
+1219
+1220
+1221
+1222
+1223
+1224
+1225
+1226
+1227
+1228
+1229
+1230
+1231
+1232
+1233
+1234
+1235
+1236
+1237
+1238
+1239
+1240
+1241
+1242
+1243
+1244
+1245
+1246
+1247
+1248
+1249
+1250
+1251
+1252
+1253
+1254
+1255
+1256
+1257
+1258
+1259
// *****************************************************************************
 /*!
-  \file      src/PDE/Transport/Problem/CylVortex.cpp
+  \file      src/PDE/Reconstruction.cpp
   \copyright 2012-2015 J. Bakosi,
              2016-2018 Los Alamos National Security, LLC.,
              2019-2021 Triad National Security, LLC.
              All rights reserved. See the LICENSE file for details.
-  \brief     Problem configuration for transport equations
-  \details   This file defines a Problem policy class for the transport
-    equations, defined in PDE/Transport/CGTransport.hpp implementing
-    node-centered continuous Galerkin (CG) and PDE/Transport/DGTransport.hpp
-    implementing cell-centered discontinuous Galerkin (DG) discretizations.
-    See PDE/Transport/Problem.hpp for general requirements on Problem policy
-    classes for cg::Transport and dg::Transport.
-*/
-// *****************************************************************************
-
-#include "CylVortex.hpp"
+  \brief     Reconstruction for reconstructed discontinuous Galerkin methods
+  \details   This file contains functions that reconstruct an "n"th order
+    polynomial to an "n+1"th order polynomial using a least-squares
+    reconstruction procedure.
+*/
+// *****************************************************************************
+
+#include <array>
+#include <vector>
+#include <iostream>
+#include <iomanip>
 
-using inciter::TransportProblemCylVortex;
-
-std::vector< tk::real >
-TransportProblemCylVortex::initialize( ncomp_t ncomp,
-                                       const std::vector< EOS >&,
-                                       tk::real x, tk::real y, tk::real,
-                                       tk::real t )
-// *****************************************************************************
-//  Evaluate initial solution at (x,y,t) for all components
-//! \param[in] ncomp Number of components in this transport equation system
-//! \param[in] x X coordinate where to evaluate the solution
-//! \param[in] y Y coordinate where to evaluate the solution
-//! \param[in] t Time where to evaluate the solution
-//! \return Values of all components evaluated at (x,y,t=0)
-//! \details This function only gives the initial condition for the cylinder,
-//!   and not the solution at any time t>0.
-// *****************************************************************************
-{
-  const auto vel = prescribedVelocity( ncomp, x, y, 0.0, t );<--- Variable 'vel' is assigned a value that is never used.
-
-  if (ncomp != 4) Throw("Cylinder deformation in vortex is only set up for 4 "
-    "components");
-
-  std::vector< tk::real > s( ncomp, 0.0 );
-
-  // center of the cylinder
-  auto x0 = 0.5;
-  auto y0 = 0.75;
-  auto r = sqrt((x-x0)*(x-x0) + (y-y0)*(y-y0));
-
-  if (r<=0.15) {
-    if (x<x0 && y>=y0) s[0] = 1.0;
-    else if (x>=x0 && y>=y0) s[1] = 1.0;
-    else if (x>=x0 && y<y0) s[2] = 1.0;
-    else if (x<x0 && y<y0) s[3] = 1.0;
-  }
+#include "Vector.hpp"
+#include "Around.hpp"
+#include "Base/HashMapReducer.hpp"
+#include "Reconstruction.hpp"
+#include "MultiMat/MultiMatIndexing.hpp"
+#include "Inciter/InputDeck/InputDeck.hpp"
+#include "Limiter.hpp"
+
+namespace inciter {
+extern ctr::InputDeck g_inputdeck;
+}
+
+namespace tk {
+
+void
+lhsLeastSq_P0P1( const inciter::FaceData& fd,
+                 const Fields& geoElem,
+                 const Fields& geoFace,
+                 std::vector< std::array< std::array< real, 3 >, 3 > >& lhs_ls )
+// *****************************************************************************
+//  Compute lhs matrix for the least-squares reconstruction
+//! \param[in] fd Face connectivity and boundary conditions object
+//! \param[in] geoElem Element geometry array
+//! \param[in] geoFace Face geometry array
+//! \param[in,out] lhs_ls LHS reconstruction matrix
+//! \details This function computing the lhs matrix for reconstruction, is
+//!   common for primitive and conserved quantities.
+// *****************************************************************************
+{
+  const auto& esuf = fd.Esuf();
+  const auto nelem = fd.Esuel().size()/4;
+
+  // Compute internal and boundary face contributions
+  for (std::size_t f=0; f<esuf.size()/2; ++f)
+  {
+    Assert( esuf[2*f] > -1, "Left-side element detected as -1" );
 
-  return s;
-}
+    auto el = static_cast< std::size_t >(esuf[2*f]);
+    auto er = esuf[2*f+1];
 
-std::vector< std::array< tk::real, 3 > >
-TransportProblemCylVortex::prescribedVelocity( ncomp_t ncomp,
-  tk::real x, tk::real y, tk::real, tk::real t )
-// *****************************************************************************
-//! Assign prescribed velocity at a point
-//! \param[in] ncomp Number of components in this transport equation
-//! \param[in] x x coordinate at which to assign velocity
-//! \param[in] y y coordinate at which to assign velocity
-//! \param[in] t time at which to assign velocity
-//! \return Velocity assigned to all vertices of a tetrehedron, size:
-//!   ncomp * ndim = [ncomp][3]
-// *****************************************************************************
-{
-  std::vector< std::array< tk::real, 3 > > vel( ncomp );
-
-  auto pi = 4.0 * std::atan(1.0);
-  for (ncomp_t c=0; c<ncomp; ++c) {
-    vel[c][0] = - 2.0*std::cos(t*pi/4.0) * std::pow(std::sin(pi*x), 2)
-      * std::sin(pi*y) * std::cos(pi*y);
-    vel[c][1] = 2.0*std::cos(t*pi/4.0) * std::pow(std::sin(pi*y), 2)
-      * std::sin(pi*x) * std::cos(pi*x);
-    vel[c][2] = 0.0;
-  }
-
-  return vel;
-}
+    std::array< real, 3 > geoElemR;
+    std::size_t eR(0);
+
+    // A second-order (piecewise linear) solution polynomial can be obtained
+    // from the first-order (piecewise constant) FV solutions by using a
+    // least-squares (LS) reconstruction process. LS uses the first-order
+    // solutions from the cell being processed, and the cells surrounding it.
+    // The LS system is obtaining by requiring the following to hold:
+    // 'Taylor expansions of solution from cell-i to the centroids of each of
+    // its neighboring cells should be equal to the cell average solution on
+    // that neighbor cell.'
+    // This gives a system of equations for the three second-order DOFs that are
+    // to be determined. In 3D tetrahedral meshes, this would give four
+    // equations (one for each neighbor )for the three unknown DOFs. This
+    // overdetermined system is solved in the least-squares sense using the
+    // normal equations approach. The normal equations approach involves
+    // pre-multiplying the overdetermined system by the transpose of the system
+    // matrix to obtain a square matrix (3x3 in this case).
+
+    // get a 3x3 system by applying the normal equation approach to the
+    // least-squares overdetermined system
+
+    if (er > -1) {
+    // internal face contribution
+      eR = static_cast< std::size_t >(er);
+      // Put in cell-centroid coordinates
+      geoElemR = {{ geoElem(eR,1), geoElem(eR,2), geoElem(eR,3) }};
+    }
+    else {
+    // boundary face contribution
+      // Put in face-centroid coordinates
+      geoElemR = {{ geoFace(f,4), geoFace(f,5), geoFace(f,6) }};
+    }
+
+    std::array< real, 3 > wdeltax{{ geoElemR[0]-geoElem(el,1),
+                                    geoElemR[1]-geoElem(el,2),
+                                    geoElemR[2]-geoElem(el,3) }};
+
+    // define a lambda for contributing to lhs matrix
+    auto lhs = [&]( std::size_t e ){
+    for (std::size_t idir=0; idir<3; ++idir)
+      for (std::size_t jdir=0; jdir<3; ++jdir)
+        lhs_ls[e][idir][jdir] += wdeltax[idir] * wdeltax[jdir];
+    };
+
+    // always add left element contribution (at a boundary face, the internal
+    // element is always the left element)
+    lhs(el);
+    // add right element contribution for internal faces only
+    if (er > -1)
+      if (eR < nelem) lhs(eR);
+
+  }
+}
+
+void
+intLeastSq_P0P1( const std::size_t rdof,
+                 const inciter::FaceData& fd,
+                 const Fields& geoElem,
+                 const Fields& W,
+                 std::vector< std::vector< std::array< real, 3 > > >& rhs_ls,
+                 const std::vector< std::size_t >& varList )
+// *****************************************************************************
+//  \brief Compute internal surface contributions to rhs vector of the
+//    least-squares reconstruction
+//! \param[in] rdof Maximum number of reconstructed degrees of freedom
+//! \param[in] fd Face connectivity and boundary conditions object
+//! \param[in] geoElem Element geometry array
+//! \param[in] W Solution vector to be reconstructed at recent time step
+//! \param[in,out] rhs_ls RHS reconstruction vector
+//! \param[in] varList List of indices in W, that need to be reconstructed
+//! \details This function computing the internal face contributions to the rhs
+//!   vector for reconstruction, is common for primitive and conserved
+//!   quantities. If `W` == `U`, compute internal face contributions for the
+//!   conserved variables. If `W` == `P`, compute internal face contributions
+//!   for the primitive variables.
+// *****************************************************************************
+{
+  const auto& esuf = fd.Esuf();
+  const auto nelem = fd.Esuel().size()/4;<--- Variable 'nelem' is assigned a value that is never used.
+
+  // Compute internal face contributions
+  for (auto f=fd.Nbfac(); f<esuf.size()/2; ++f)
+  {
+    Assert( esuf[2*f] > -1 && esuf[2*f+1] > -1, "Interior element detected "
+            "as -1" );
+
+    auto el = static_cast< std::size_t >(esuf[2*f]);
+    auto er = static_cast< std::size_t >(esuf[2*f+1]);
+
+    // get a 3x3 system by applying the normal equation approach to the
+    // least-squares overdetermined system
+
+    // 'wdeltax' is the distance vector between the centroids of this element
+    // and its neighbor
+    std::array< real, 3 > wdeltax{{ geoElem(er,1)-geoElem(el,1),
+                                    geoElem(er,2)-geoElem(el,2),
+                                    geoElem(er,3)-geoElem(el,3) }};
+
+    for (std::size_t idir=0; idir<3; ++idir)
+    {
+      // rhs vector
+      for (std::size_t i=0; i<varList.size(); ++i)
+      {
+        auto c = varList[i];
+        auto mark = c*rdof;
+        rhs_ls[el][c][idir] +=
+          wdeltax[idir] * (W(er,mark)-W(el,mark));
+        if (er < nelem)
+          rhs_ls[er][c][idir] +=
+            wdeltax[idir] * (W(er,mark)-W(el,mark));
+      }
+    }
+  }
+}
+
+void
+bndLeastSqConservedVar_P0P1(
+  ncomp_t ncomp,
+  const std::vector< inciter::EOS >& mat_blk,
+  std::size_t rdof,
+  const std::vector< std::size_t >& bcconfig,
+  const inciter::FaceData& fd,
+  const Fields& geoFace,
+  const Fields& geoElem,
+  real t,
+  const StateFn& state,
+  const Fields& P,
+  const Fields& U,
+  std::vector< std::vector< std::array< real, 3 > > >& rhs_ls,
+  const std::vector< std::size_t >& varList,
+  std::size_t nprim )
+// *****************************************************************************
+//  \brief Compute boundary surface contributions to rhs vector of the
+//    least-squares reconstruction of conserved quantities of the PDE system
+//! \param[in] ncomp Number of scalar components in this PDE system
+//! \param[in] mat_blk EOS material block
+//! \param[in] rdof Maximum number of reconstructed degrees of freedom
+//! \param[in] bcconfig BC configuration vector for multiple side sets
+//! \param[in] fd Face connectivity and boundary conditions object
+//! \param[in] geoFace Face geometry array
+//! \param[in] geoElem Element geometry array
+//! \param[in] t Physical time
+//! \param[in] state Function to evaluate the left and right solution state at
+//!   boundaries
+//! \param[in] P Primitive vector to be reconstructed at recent time step
+//! \param[in] U Solution vector to be reconstructed at recent time step
+//! \param[in,out] rhs_ls RHS reconstruction vector
+//! \param[in] varList List of indices in W, that need to be reconstructed
+//! \param[in] nprim This is the number of primitive quantities stored for this
+//!   PDE system. This is necessary to extend the state vector to the right
+//!   size, so that correct boundary conditions are obtained.
+//!   A default is set to 0, so that calling code for systems that do not store
+//!   primitive quantities does not need to specify this argument.
+//! \details This function computing the boundary face contributions to the rhs
+//!   vector for reconstruction, is used for conserved quantities only.
+// *****************************************************************************
+{
+  const auto& bface = fd.Bface();
+  const auto& esuf = fd.Esuf();
+
+  for (const auto& s : bcconfig) {       // for all bc sidesets
+    auto bc = bface.find(static_cast<int>(s));// faces for side set
+    if (bc != end(bface))
+    {
+      // Compute boundary face contributions
+      for (const auto& f : bc->second)
+      {
+        Assert( esuf[2*f+1] == -1, "physical boundary element not -1" );
+
+        std::size_t el = static_cast< std::size_t >(esuf[2*f]);
+
+        // arrays for quadrature points
+        std::array< real, 3 >
+          fc{{ geoFace(f,4), geoFace(f,5), geoFace(f,6) }};
+        std::array< real, 3 >
+          fn{{ geoFace(f,1), geoFace(f,2), geoFace(f,3) }};
+
+        // Compute the state variables at the left element
+        std::vector< real >B(1,1.0);
+        auto ul = eval_state( ncomp, rdof, 1, el, U, B );
+        auto uprim = eval_state( nprim, rdof, 1, el, P, B );
+
+        // consolidate primitives into state vector
+        ul.insert(ul.end(), uprim.begin(), uprim.end());
+
+        Assert( ul.size() == ncomp+nprim, "Incorrect size for "
+                "appended state vector" );
+
+        // Compute the state at the face-center using BC
+        auto ustate = state( ncomp, mat_blk, ul, fc[0], fc[1], fc[2], t, fn );
+
+        std::array< real, 3 > wdeltax{{ fc[0]-geoElem(el,1),
+                                        fc[1]-geoElem(el,2),
+                                        fc[2]-geoElem(el,3) }};
+
+        for (std::size_t idir=0; idir<3; ++idir)
+        {
+          // rhs vector
+          for (std::size_t i=0; i<varList.size(); ++i)
+          {
+            auto c = varList[i];
+            rhs_ls[el][c][idir] +=
+              wdeltax[idir] * (ustate[1][c]-ustate[0][c]);
+          }
+        }
+      }
+    }
+  }
+}
+
+void
+solveLeastSq_P0P1(
+  const std::size_t rdof,
+  const std::vector< std::array< std::array< real, 3 >, 3 > >& lhs,
+  const std::vector< std::vector< std::array< real, 3 > > >& rhs,
+  Fields& W,<--- Parameter 'W' can be declared with const
+  const std::vector< std::size_t >& varList )
+// *****************************************************************************
+//  Solve the 3x3 linear system for least-squares reconstruction
+//! \param[in] rdof Maximum number of reconstructed degrees of freedom
+//! \param[in] lhs LHS reconstruction matrix
+//! \param[in] rhs RHS reconstruction vector
+//! \param[in,out] W Solution vector to be reconstructed at recent time step
+//! \param[in] varList List of indices in W, that need to be reconstructed
+//! \details Solves the 3x3 linear system for each element, individually. For
+//!   systems that require reconstructions of primitive quantities, this should
+//!   be called twice, once with the argument 'W' as U (conserved), and again
+//!   with 'W' as P (primitive).
+// *****************************************************************************
+{
+  auto nelem = lhs.size();
+
+  for (std::size_t e=0; e<nelem; ++e)
+  {
+    for (std::size_t i=0; i<varList.size(); ++i)
+    {
+      auto mark = varList[i]*rdof;
+
+      // solve system using Cramer's rule
+      auto ux = tk::cramer( lhs[e], rhs[e][varList[i]] );
+
+      W(e,mark+1) = ux[0];
+      W(e,mark+2) = ux[1];
+      W(e,mark+3) = ux[2];
+    }
+  }
+}
+
+void
+recoLeastSqExtStencil(
+  std::size_t rdof,
+  std::size_t e,
+  const std::map< std::size_t, std::vector< std::size_t > >& esup,
+  const std::vector< std::size_t >& inpoel,
+  const Fields& geoElem,
+  Fields& W,<--- Parameter 'W' can be declared with const
+  const std::vector< std::size_t >& varList )
+// *****************************************************************************
+//  \brief Reconstruct the second-order solution using least-squares approach
+//    from an extended stencil involving the node-neighbors
+//! \param[in] rdof Maximum number of reconstructed degrees of freedom
+//! \param[in] e Element whoes solution is being reconstructed
+//! \param[in] esup Elements surrounding points
+//! \param[in] inpoel Element-node connectivity
+//! \param[in] geoElem Element geometry array
+//! \param[in,out] W Solution vector to be reconstructed at recent time step
+//! \param[in] varList List of indices in W, that need to be reconstructed
+//! \details A second-order (piecewise linear) solution polynomial is obtained
+//!   from the first-order (piecewise constant) FV solutions by using a
+//!   least-squares (LS) reconstruction process. This LS reconstruction function
+//!   using the nodal-neighbors of a cell, to get an overdetermined system of
+//!   equations for the derivatives of the solution. This overdetermined system
+//!   is solved in the least-squares sense using the normal equations approach.
+// *****************************************************************************
+{
+  // lhs matrix
+  std::array< std::array< tk::real, 3 >, 3 >
+    lhs_ls( {{ {{0.0, 0.0, 0.0}},
+               {{0.0, 0.0, 0.0}},
+               {{0.0, 0.0, 0.0}} }} );
+  // rhs matrix
+  std::vector< std::array< tk::real, 3 > >
+  rhs_ls( varList.size(), {{ 0.0, 0.0, 0.0 }} );
+
+  // loop over all nodes of the element e
+  for (std::size_t lp=0; lp<4; ++lp)
+  {
+    auto p = inpoel[4*e+lp];
+    const auto& pesup = cref_find(esup, p);
+
+    // loop over all the elements surrounding this node p
+    for (auto er : pesup)
+    {
+      // centroid distance
+      std::array< real, 3 > wdeltax{{ geoElem(er,1)-geoElem(e,1),
+                                      geoElem(er,2)-geoElem(e,2),
+                                      geoElem(er,3)-geoElem(e,3) }};
+
+      // contribute to lhs matrix
+      for (std::size_t idir=0; idir<3; ++idir)
+        for (std::size_t jdir=0; jdir<3; ++jdir)
+          lhs_ls[idir][jdir] += wdeltax[idir] * wdeltax[jdir];
+
+      // compute rhs matrix
+      for (std::size_t i=0; i<varList.size(); i++)
+      {
+        auto mark = varList[i]*rdof;
+        for (std::size_t idir=0; idir<3; ++idir)
+          rhs_ls[i][idir] +=
+            wdeltax[idir] * (W(er,mark)-W(e,mark));
+
+      }
+    }
+  }
+
+  // solve least-square normal equation system using Cramer's rule
+  for (std::size_t i=0; i<varList.size(); i++)
+  {
+    auto mark = varList[i]*rdof;
+
+    auto ux = tk::cramer( lhs_ls, rhs_ls[i] );
+
+    // Update the P1 dofs with the reconstructioned gradients.
+    // Since this reconstruction does not affect the cell-averaged solution,
+    // W(e,mark+0) is unchanged.
+    W(e,mark+1) = ux[0];
+    W(e,mark+2) = ux[1];
+    W(e,mark+3) = ux[2];
+  }
+}
+
+void
+transform_P0P1( std::size_t rdof,
+                std::size_t nelem,
+                const std::vector< std::size_t >& inpoel,
+                const UnsMesh::Coords& coord,
+                Fields& W,<--- Parameter 'W' can be declared with const
+                const std::vector< std::size_t >& varList )
+// *****************************************************************************
+//  Transform the reconstructed P1-derivatives to the Dubiner dofs
+//! \param[in] rdof Total number of reconstructed dofs
+//! \param[in] nelem Total number of elements
+//! \param[in] inpoel Element-node connectivity
+//! \param[in] coord Array of nodal coordinates
+//! \param[in,out] W Second-order reconstructed vector which gets transformed to
+//!   the Dubiner reference space
+//! \param[in] varList List of indices in W, that need to be reconstructed
+//! \details Since the DG solution (and the primitive quantities) are assumed to
+//!   be stored in the Dubiner space, this transformation from Taylor
+//!   coefficients to Dubiner coefficients is necessary.
+// *****************************************************************************
+{
+  const auto& cx = coord[0];
+  const auto& cy = coord[1];
+  const auto& cz = coord[2];
+
+  for (std::size_t e=0; e<nelem; ++e)
+  {
+    // Extract the element coordinates
+    std::array< std::array< real, 3>, 4 > coordel {{
+      {{ cx[ inpoel[4*e  ] ], cy[ inpoel[4*e  ] ], cz[ inpoel[4*e  ] ] }},
+      {{ cx[ inpoel[4*e+1] ], cy[ inpoel[4*e+1] ], cz[ inpoel[4*e+1] ] }},
+      {{ cx[ inpoel[4*e+2] ], cy[ inpoel[4*e+2] ], cz[ inpoel[4*e+2] ] }},
+      {{ cx[ inpoel[4*e+3] ], cy[ inpoel[4*e+3] ], cz[ inpoel[4*e+3] ] }}
+    }};
+
+    auto jacInv =
+      tk::inverseJacobian( coordel[0], coordel[1], coordel[2], coordel[3] );
+
+    // Compute the derivatives of basis function for DG(P1)
+    auto dBdx = tk::eval_dBdx_p1( rdof, jacInv );
+
+    for (std::size_t i=0; i<varList.size(); ++i)
+    {
+      auto mark = varList[i]*rdof;
+
+      // solve system using Cramer's rule
+      auto ux = tk::cramer( {{ {{dBdx[0][1], dBdx[0][2], dBdx[0][3]}},
+                               {{dBdx[1][1], dBdx[1][2], dBdx[1][3]}},
+                               {{dBdx[2][1], dBdx[2][2], dBdx[2][3]}} }},
+                            {{ W(e,mark+1),
+                               W(e,mark+2),
+                               W(e,mark+3) }} );
+
+      // replace physical derivatives with transformed dofs
+      W(e,mark+1) = ux[0];
+      W(e,mark+2) = ux[1];
+      W(e,mark+3) = ux[2];
+    }
+  }
+}
+
+void
+THINCReco( std::size_t rdof,
+           std::size_t nmat,
+           std::size_t e,
+           const std::vector< std::size_t >& inpoel,
+           const UnsMesh::Coords& coord,
+           const Fields& geoElem,
+           const std::array< real, 3 >& ref_xp,
+           const Fields& U,
+           const Fields& P,
+           bool intInd,
+           const std::vector< std::size_t >& matInt,
+           [[maybe_unused]] const std::vector< real >& vfmin,
+           [[maybe_unused]] const std::vector< real >& vfmax,
+           std::vector< real >& state )
+// *****************************************************************************
+//  Compute THINC reconstructions at quadrature point for multi-material flows
+//! \param[in] rdof Total number of reconstructed dofs
+//! \param[in] nmat Total number of materials
+//! \param[in] e Element for which interface reconstruction is being calculated
+//! \param[in] inpoel Element-node connectivity
+//! \param[in] coord Array of nodal coordinates
+//! \param[in] geoElem Element geometry array
+//! \param[in] ref_xp Quadrature point in reference space
+//! \param[in] U Solution vector
+//! \param[in] P Vector of primitives
+//! \param[in] intInd Boolean which indicates if the element contains a
+//!   material interface
+//! \param[in] matInt Array indicating which material has an interface
+//! \param[in] vfmin Vector containing min volume fractions for each material
+//!   in this cell
+//! \param[in] vfmax Vector containing max volume fractions for each material
+//!   in this cell
+//! \param[in,out] state Unknown/state vector at quadrature point, modified
+//!   if near interfaces using THINC
+//! \details This function is an interface for the multimat PDEs that use the
+//!   algebraic multi-material THINC reconstruction. This particular function
+//!   should only be called for multimat.
+// *****************************************************************************
+{
+  using inciter::volfracDofIdx;
+  using inciter::densityDofIdx;
+  using inciter::momentumDofIdx;
+  using inciter::energyDofIdx;
+  using inciter::pressureDofIdx;
+  using inciter::velocityDofIdx;
+  using inciter::deformDofIdx;
+  using inciter::stressDofIdx;
+  using inciter::volfracIdx;
+  using inciter::densityIdx;
+  using inciter::momentumIdx;
+  using inciter::energyIdx;
+  using inciter::pressureIdx;
+  using inciter::velocityIdx;
+  using inciter::deformIdx;
+  using inciter::stressIdx;
+
+  auto bparam = inciter::g_inputdeck.get< tag::multimat,
+    tag::intsharp_param >();
+  const auto ncomp = U.nprop()/rdof;
+  const auto& solidx = inciter::g_inputdeck.get< tag::matidxmap,
+    tag::solidx >();
+
+  // Step-1: Perform THINC reconstruction
+  // create a vector of volume-fractions and pass it to the THINC function
+  std::vector< real > alSol(rdof*nmat, 0.0);
+  std::vector< real > alReco(nmat, 0.0);
+  for (std::size_t k=0; k<nmat; ++k) {
+    auto mark = k*rdof;
+    for (std::size_t i=0; i<rdof; ++i) {
+      alSol[mark+i] = U(e, volfracDofIdx(nmat,k,rdof,i));
+    }
+    // initialize with TVD reconstructions which will be modified if near
+    // material interface
+    alReco[k] = state[volfracIdx(nmat,k)];
+  }
+  THINCFunction(rdof, nmat, e, inpoel, coord, ref_xp, geoElem(e,0), bparam,
+    alSol, intInd, matInt, alReco);
+
+  // check reconstructed volfracs for positivity
+  bool neg_vf = false;
+  for (std::size_t k=0; k<nmat; ++k) {
+    if (alReco[k] < 1e-16 && matInt[k] > 0) neg_vf = true;
+  }
+  for (std::size_t k=0; k<nmat; ++k) {
+    if (neg_vf) {
+      std::cout << "Material-id:        " << k << std::endl;
+      std::cout << "Volume-fraction:    " << std::setprecision(18) << alReco[k]
+        << std::endl;
+      std::cout << "Cell-avg vol-frac:  " << std::setprecision(18) <<
+        U(e,volfracDofIdx(nmat,k,rdof,0)) << std::endl;
+      std::cout << "Material-interface? " << intInd << std::endl;
+      std::cout << "Mat-k-involved?     " << matInt[k] << std::endl;
+    }
+  }
+  if (neg_vf) Throw("Material has negative volume fraction after THINC "
+    "reconstruction.");
+
+  // Step-2: Perform consistent reconstruction on other conserved quantities
+  if (intInd)
+  {
+    auto rhobCC(0.0), rhobHO(0.0);
+    for (std::size_t k=0; k<nmat; ++k)
+    {
+      auto alCC = U(e, volfracDofIdx(nmat,k,rdof,0));
+      alCC = std::max(1e-14, alCC);
+
+      if (matInt[k])
+      {
+        state[volfracIdx(nmat,k)] = alReco[k];
+        state[densityIdx(nmat,k)] = alReco[k]
+          * U(e, densityDofIdx(nmat,k,rdof,0))/alCC;
+        state[energyIdx(nmat,k)] = alReco[k]
+          * U(e, energyDofIdx(nmat,k,rdof,0))/alCC;
+        state[ncomp+pressureIdx(nmat,k)] = alReco[k]
+          * P(e, pressureDofIdx(nmat,k,rdof,0))/alCC;
+        if (solidx[k] > 0) {
+          for (std::size_t i=0; i<3; ++i)
+            for (std::size_t j=0; j<3; ++j)
+              state[deformIdx(nmat,solidx[k],i,j)] =
+                U(e, deformDofIdx(nmat,solidx[k],i,j,rdof,0));
+
+          for (std::size_t i=0; i<6; ++i)
+            state[ncomp+stressIdx(nmat,solidx[k],i)] = alReco[k]
+              * P(e, stressDofIdx(nmat,solidx[k],i,rdof,0))/alCC;
+        }
+      }
+
+      rhobCC += U(e, densityDofIdx(nmat,k,rdof,0));
+      rhobHO += state[densityIdx(nmat,k)];
+    }
+
+    // consistent reconstruction for bulk momentum
+    for (std::size_t i=0; i<3; ++i)
+    {
+      state[momentumIdx(nmat,i)] = rhobHO
+        * U(e, momentumDofIdx(nmat,i,rdof,0))/rhobCC;
+      state[ncomp+velocityIdx(nmat,i)] =
+        P(e, velocityDofIdx(nmat,i,rdof,0));
+    }
+  }
+}
+
+void
+THINCRecoTransport( std::size_t rdof,
+                    std::size_t,
+                    std::size_t e,
+                    const std::vector< std::size_t >& inpoel,
+                    const UnsMesh::Coords& coord,
+                    const Fields& geoElem,
+                    const std::array< real, 3 >& ref_xp,
+                    const Fields& U,
+                    const Fields&,
+                    [[maybe_unused]] const std::vector< real >& vfmin,
+                    [[maybe_unused]] const std::vector< real >& vfmax,
+                    std::vector< real >& state )
+// *****************************************************************************
+//  Compute THINC reconstructions at quadrature point for transport
+//! \param[in] rdof Total number of reconstructed dofs
+//! \param[in] e Element for which interface reconstruction is being calculated
+//! \param[in] inpoel Element-node connectivity
+//! \param[in] coord Array of nodal coordinates
+//! \param[in] geoElem Element geometry array
+//! \param[in] ref_xp Quadrature point in reference space
+//! \param[in] U Solution vector
+//! \param[in] vfmin Vector containing min volume fractions for each material
+//!   in this cell
+//! \param[in] vfmax Vector containing max volume fractions for each material
+//!   in this cell
+//! \param[in,out] state Unknown/state vector at quadrature point, modified
+//!   if near interfaces using THINC
+//! \details This function is an interface for the transport PDEs that use the
+//!   algebraic multi-material THINC reconstruction. This particular function
+//!   should only be called for transport.
+// *****************************************************************************
+{
+  auto bparam = inciter::g_inputdeck.get< tag::transport,
+    tag::intsharp_param >();
+  auto ncomp = U.nprop()/rdof;
+
+  // interface detection
+  std::vector< std::size_t > matInt(ncomp, 0);
+  std::vector< tk::real > alAvg(ncomp, 0.0);
+  for (std::size_t k=0; k<ncomp; ++k)
+    alAvg[k] = U(e, k*rdof);
+  auto intInd = inciter::interfaceIndicator(ncomp, alAvg, matInt);
+
+  // create a vector of volume-fractions and pass it to the THINC function
+  std::vector< real > alSol(rdof*ncomp, 0.0);
+  // initialize with TVD reconstructions (modified if near interface)
+  auto alReco = state;
+  for (std::size_t k=0; k<ncomp; ++k) {
+    auto mark = k*rdof;
+    for (std::size_t i=0; i<rdof; ++i) {
+      alSol[mark+i] = U(e,mark+i);
+    }
+  }
+  THINCFunction(rdof, ncomp, e, inpoel, coord, ref_xp, geoElem(e,0), bparam,
+    alSol, intInd, matInt, alReco);
+
+  state = alReco;
+}
+
+void
+THINCFunction( std::size_t rdof,
+               std::size_t nmat,
+               std::size_t e,
+               const std::vector< std::size_t >& inpoel,
+               const UnsMesh::Coords& coord,
+               const std::array< real, 3 >& ref_xp,
+               real vol,
+               real bparam,
+               const std::vector< real >& alSol,
+               bool intInd,
+               const std::vector< std::size_t >& matInt,
+               std::vector< real >& alReco )
+// *****************************************************************************
+//  Old version of the Multi-Medium THINC reconstruction function
+//! \param[in] rdof Total number of reconstructed dofs
+//! \param[in] nmat Total number of materials
+//! \param[in] e Element for which interface reconstruction is being calculated
+//! \param[in] inpoel Element-node connectivity
+//! \param[in] coord Array of nodal coordinates
+//! \param[in] ref_xp Quadrature point in reference space
+//! \param[in] vol Element volume
+//! \param[in] bparam User specified Beta for THINC, from the input file
+//! \param[in] alSol Volume fraction solution vector for element e
+//! \param[in] intInd Interface indicator, true if e is interface element
+//! \param[in] matInt Vector indicating materials which constitute interface
+//! \param[in,out] alReco Unknown/state vector at quadrature point, which gets
+//!   modified if near interface using MM-THINC
+//! \details This function computes the interface reconstruction using the
+//!   algebraic multi-material THINC reconstruction for each material at the
+//!   given (ref_xp) quadrature point. This function is based on the following:
+//!   Pandare A. K., Waltz J., & Bakosi J. (2021) Multi-Material Hydrodynamics
+//!   with Algebraic Sharp Interface Capturing. Computers & Fluids,
+//!   doi: https://doi.org/10.1016/j.compfluid.2020.104804.
+//!   This function will be removed after the newer version (see
+//!   THINCFunction_new) is sufficiently tested.
+// *****************************************************************************
+{
+  // determine number of materials with interfaces in this cell
+  auto epsl(1e-4), epsh(1e-1), bred(1.25), bmod(bparam);
+  std::size_t nIntMat(0);
+  for (std::size_t k=0; k<nmat; ++k)
+  {
+    auto alk = alSol[k*rdof];
+    if (alk > epsl)
+    {
+      ++nIntMat;
+      if ((alk > epsl) && (alk < epsh))
+        bmod = std::min(bmod,
+          (alk-epsl)/(epsh-epsl) * (bred - bparam) + bparam);
+      else if (alk > epsh)
+        bmod = bred;
+    }
+  }
+
+  if (nIntMat > 2) bparam = bmod;
+
+  // compression parameter
+  auto beta = bparam/std::cbrt(6.0*vol);
+
+  if (intInd)
+  {
+    // 1. Get unit normals to material interface
+
+    // Compute Jacobian matrix for converting Dubiner dofs to derivatives
+    const auto& cx = coord[0];
+    const auto& cy = coord[1];
+    const auto& cz = coord[2];
+
+    std::array< std::array< real, 3>, 4 > coordel {{
+      {{ cx[ inpoel[4*e  ] ], cy[ inpoel[4*e  ] ], cz[ inpoel[4*e  ] ] }},
+      {{ cx[ inpoel[4*e+1] ], cy[ inpoel[4*e+1] ], cz[ inpoel[4*e+1] ] }},
+      {{ cx[ inpoel[4*e+2] ], cy[ inpoel[4*e+2] ], cz[ inpoel[4*e+2] ] }},
+      {{ cx[ inpoel[4*e+3] ], cy[ inpoel[4*e+3] ], cz[ inpoel[4*e+3] ] }}
+    }};
+
+    auto jacInv =
+      tk::inverseJacobian( coordel[0], coordel[1], coordel[2], coordel[3] );
+
+    auto dBdx = tk::eval_dBdx_p1( rdof, jacInv );
+
+    std::array< real, 3 > nInt;
+    std::vector< std::array< real, 3 > > ref_n(nmat, {{0.0, 0.0, 0.0}});
+
+    // Get normals
+    for (std::size_t k=0; k<nmat; ++k)
+    {
+      // Get derivatives from moments in Dubiner space
+      for (std::size_t i=0; i<3; ++i)
+        nInt[i] = dBdx[i][1] * alSol[k*rdof+1]
+          + dBdx[i][2] * alSol[k*rdof+2]
+          + dBdx[i][3] * alSol[k*rdof+3];
+
+      auto nMag = std::sqrt(tk::dot(nInt, nInt)) + 1e-14;
+
+      for (std::size_t i=0; i<3; ++i)
+        nInt[i] /= nMag;
+
+      // project interface normal onto local/reference coordinate system
+      for (std::size_t i=0; i<3; ++i)
+      {
+        std::array< real, 3 > axis{
+          coordel[i+1][0]-coordel[0][0],
+          coordel[i+1][1]-coordel[0][1],
+          coordel[i+1][2]-coordel[0][2] };
+        ref_n[k][i] = tk::dot(nInt, axis);
+      }
+    }
+
+    // 2. Reconstruct volume fractions using THINC
+    auto max_lim = 1.0 - (static_cast<tk::real>(nmat-1)*1.0e-12);
+    auto min_lim = 1e-12;
+    auto sum_inter(0.0), sum_non_inter(0.0);
+    for (std::size_t k=0; k<nmat; ++k)
+    {
+      if (matInt[k])
+      {
+        // get location of material interface (volume fraction 0.5) from the
+        // assumed tanh volume fraction distribution, and cell-averaged
+        // volume fraction
+        auto alCC(alSol[k*rdof]);
+        auto Ac(0.0), Bc(0.0), Qc(0.0);
+        if ((std::abs(ref_n[k][0]) > std::abs(ref_n[k][1]))
+          && (std::abs(ref_n[k][0]) > std::abs(ref_n[k][2])))
+        {
+          Ac = std::exp(0.5*beta*ref_n[k][0]);
+          Bc = std::exp(0.5*beta*(ref_n[k][1]+ref_n[k][2]));
+          Qc = std::exp(0.5*beta*ref_n[k][0]*(2.0*alCC-1.0));
+        }
+        else if ((std::abs(ref_n[k][1]) > std::abs(ref_n[k][0]))
+          && (std::abs(ref_n[k][1]) > std::abs(ref_n[k][2])))
+        {
+          Ac = std::exp(0.5*beta*ref_n[k][1]);
+          Bc = std::exp(0.5*beta*(ref_n[k][0]+ref_n[k][2]));
+          Qc = std::exp(0.5*beta*ref_n[k][1]*(2.0*alCC-1.0));
+        }
+        else
+        {
+          Ac = std::exp(0.5*beta*ref_n[k][2]);
+          Bc = std::exp(0.5*beta*(ref_n[k][0]+ref_n[k][1]));
+          Qc = std::exp(0.5*beta*ref_n[k][2]*(2.0*alCC-1.0));
+        }
+        auto d = std::log((1.0-Ac*Qc) / (Ac*Bc*(Qc-Ac))) / (2.0*beta);
+
+        // THINC reconstruction
+        auto al_c = 0.5 * (1.0 + std::tanh(beta*(tk::dot(ref_n[k], ref_xp) + d)));
+
+        alReco[k] = std::min(max_lim, std::max(min_lim, al_c));
+
+        sum_inter += alReco[k];
+      } else
+      {
+        sum_non_inter += alReco[k];
+      }
+      // else, if this material does not have an interface close-by, the TVD
+      // reconstructions must be used for state variables. This is ensured by
+      // initializing the alReco vector as the TVD state.
+    }
+
+    // Rescale volume fractions of interface-materials to ensure unit sum
+    auto sum_rest = 1.0 - sum_non_inter;
+    for (std::size_t k=0; k<nmat; ++k)
+      if(matInt[k])
+        alReco[k] = alReco[k] * sum_rest / sum_inter;
+  }
+}
+
+void
+THINCFunction_new( std::size_t rdof,
+                   std::size_t nmat,
+                   std::size_t e,
+                   const std::vector< std::size_t >& inpoel,
+                   const UnsMesh::Coords& coord,
+                   const std::array< real, 3 >& ref_xp,
+                   real vol,
+                   real bparam,
+                   const std::vector< real >& alSol,
+                   bool intInd,
+                   const std::vector< std::size_t >& matInt,
+                   std::vector< real >& alReco )
+// *****************************************************************************
+//  New Multi-Medium THINC reconstruction function for volume fractions
+//! \param[in] rdof Total number of reconstructed dofs
+//! \param[in] nmat Total number of materials
+//! \param[in] e Element for which interface reconstruction is being calculated
+//! \param[in] inpoel Element-node connectivity
+//! \param[in] coord Array of nodal coordinates
+//! \param[in] ref_xp Quadrature point in reference space
+//! \param[in] vol Element volume
+//! \param[in] bparam User specified Beta for THINC, from the input file
+//! \param[in] alSol Volume fraction solution vector for element e
+//! \param[in] intInd Interface indicator, true if e is interface element
+//! \param[in] matInt Vector indicating materials which constitute interface
+//! \param[in,out] alReco Unknown/state vector at quadrature point, which gets
+//!   modified if near interface using MM-THINC
+//! \details This function computes the interface reconstruction using the
+//!   algebraic multi-material THINC reconstruction for each material at the
+//!   given (ref_xp) quadrature point. This function succeeds the older version
+//!   of the mm-THINC (see THINCFunction), but is still under testing and is
+//!   currently experimental.
+// *****************************************************************************
+{
+  // compression parameter
+  auto beta = bparam/std::cbrt(6.0*vol);
+
+  // If the cell is not material interface, return this function
+  if (not intInd) return;
+
+  // If the cell is material interface, THINC reconstruction is applied
+  // Step 1. Get unit normals to material interface
+  // -------------------------------------------------------------------------
+
+  // Compute Jacobian matrix for converting Dubiner dofs to derivatives
+  const auto& cx = coord[0];
+  const auto& cy = coord[1];
+  const auto& cz = coord[2];
+
+  std::array< std::array< real, 3>, 4 > coordel {{
+    {{ cx[ inpoel[4*e  ] ], cy[ inpoel[4*e  ] ], cz[ inpoel[4*e  ] ] }},
+    {{ cx[ inpoel[4*e+1] ], cy[ inpoel[4*e+1] ], cz[ inpoel[4*e+1] ] }},
+    {{ cx[ inpoel[4*e+2] ], cy[ inpoel[4*e+2] ], cz[ inpoel[4*e+2] ] }},
+    {{ cx[ inpoel[4*e+3] ], cy[ inpoel[4*e+3] ], cz[ inpoel[4*e+3] ] }}
+  }};
+
+  auto jacInv =
+    tk::inverseJacobian( coordel[0], coordel[1], coordel[2], coordel[3] );
+
+  auto dBdx = tk::eval_dBdx_p1( rdof, jacInv );
+
+  std::array< real, 3 > nInt;
+  std::array< real, 3 > ref_n{0.0, 0.0, 0.0};
+  auto almax(0.0);
+  std::size_t kmax(0);
+
+  // Determine index of material present in majority
+  for (std::size_t k=0; k<nmat; ++k)
+  {
+    auto alk = alSol[k*rdof];
+    if (alk > almax)
+    {
+      almax = alk;
+      kmax = k;
+    }
+  }
+
+  // Get normals of material present in majority
+  // Get derivatives from moments in Dubiner space
+  for (std::size_t i=0; i<3; ++i)
+    nInt[i] = dBdx[i][1] * alSol[kmax*rdof+1]
+      + dBdx[i][2] * alSol[kmax*rdof+2]
+      + dBdx[i][3] * alSol[kmax*rdof+3];
+
+  auto nMag = std::sqrt(tk::dot(nInt, nInt)) + 1e-14;
+
+  for (std::size_t i=0; i<3; ++i)
+    nInt[i] /= nMag;
+
+  // project interface normal onto local/reference coordinate system
+  for (std::size_t i=0; i<3; ++i)
+  {
+    std::array< real, 3 > axis{
+      coordel[i+1][0]-coordel[0][0],
+      coordel[i+1][1]-coordel[0][1],
+      coordel[i+1][2]-coordel[0][2] };
+    ref_n[i] = tk::dot(nInt, axis);
+  }
+
+  // Step 2. Reconstruct volume fraction of majority material using THINC
+  // -------------------------------------------------------------------------
+
+  auto al_max = 1.0 - (static_cast<tk::real>(nmat-1)*1.0e-12);
+  auto al_min = 1e-12;
+  auto alsum(0.0);
+  // get location of material interface (volume fraction 0.5) from the
+  // assumed tanh volume fraction distribution, and cell-averaged
+  // volume fraction
+  auto alCC(alSol[kmax*rdof]);
+  auto Ac(0.0), Bc(0.0), Qc(0.0);
+  if ((std::abs(ref_n[0]) > std::abs(ref_n[1]))
+    && (std::abs(ref_n[0]) > std::abs(ref_n[2])))
+  {
+    Ac = std::exp(0.5*beta*ref_n[0]);
+    Bc = std::exp(0.5*beta*(ref_n[1]+ref_n[2]));
+    Qc = std::exp(0.5*beta*ref_n[0]*(2.0*alCC-1.0));
+  }
+  else if ((std::abs(ref_n[1]) > std::abs(ref_n[0]))
+    && (std::abs(ref_n[1]) > std::abs(ref_n[2])))
+  {
+    Ac = std::exp(0.5*beta*ref_n[1]);
+    Bc = std::exp(0.5*beta*(ref_n[0]+ref_n[2]));
+    Qc = std::exp(0.5*beta*ref_n[1]*(2.0*alCC-1.0));
+  }
+  else
+  {
+    Ac = std::exp(0.5*beta*ref_n[2]);
+    Bc = std::exp(0.5*beta*(ref_n[0]+ref_n[1]));
+    Qc = std::exp(0.5*beta*ref_n[2]*(2.0*alCC-1.0));
+  }
+  auto d = std::log((1.0-Ac*Qc) / (Ac*Bc*(Qc-Ac))) / (2.0*beta);
+
+  // THINC reconstruction
+  auto al_c = 0.5 * (1.0 + std::tanh(beta*(tk::dot(ref_n, ref_xp) + d)));
+
+  alReco[kmax] = std::min(al_max, std::max(al_min, al_c));
+  alsum += alReco[kmax];
+
+  // if this material does not have an interface close-by, the TVD
+  // reconstructions must be used for state variables. This is ensured by
+  // initializing the alReco vector as the TVD state.
+  for (std::size_t k=0; k<nmat; ++k) {
+    if (!matInt[k]) {
+      alsum += alReco[k];
+    }
+  }
+
+  // Step 3. Do multimaterial cell corrections
+  // -------------------------------------------------------------------------
+
+  // distribute remaining volume to rest of materials
+  auto sum_left = 1.0 - alsum;
+  real den = 0.0;
+  for (std::size_t k=0; k<nmat; ++k) {
+    if (matInt[k] && k != kmax) {
+      auto mark = k * rdof;
+      alReco[k] = sum_left * alSol[mark];
+      den += alSol[mark];
+    }
+  }
+  // the distributed volfracs might be below al_min, correct that
+  real err = 0.0;
+  for (std::size_t k=0; k<nmat; ++k) {
+    if (matInt[k] && k != kmax) {
+      alReco[k] /= den;
+      if (alReco[k] < al_min) {
+        err += al_min - alReco[k];
+        alReco[k] = al_min;
+      }
+    }
+  }
+
+  // balance out errors
+  alReco[kmax] -= err;
+}
+
+std::vector< tk::real >
+evalPolynomialSol( const std::vector< inciter::EOS >& mat_blk,
+                   int intsharp,
+                   std::size_t ncomp,
+                   std::size_t nprim,
+                   std::size_t rdof,
+                   std::size_t nmat,
+                   std::size_t e,
+                   std::size_t dof_e,
+                   const std::vector< std::size_t >& inpoel,
+                   const UnsMesh::Coords& coord,
+                   const Fields& geoElem,
+                   const std::array< real, 3 >& ref_gp,
+                   const std::vector< real >& B,
+                   const Fields& U,
+                   const Fields& P )
+// *****************************************************************************
+//  Evaluate polynomial solution at quadrature point
+//! \param[in] mat_blk EOS material block
+//! \param[in] intsharp Interface reconstruction indicator
+//! \param[in] ncomp Number of components in the PDE system
+//! \param[in] nprim Number of primitive quantities
+//! \param[in] rdof Total number of reconstructed dofs
+//! \param[in] nmat Total number of materials
+//! \param[in] e Element for which polynomial solution is being evaluated
+//! \param[in] dof_e Degrees of freedom for element
+//! \param[in] inpoel Element-node connectivity
+//! \param[in] coord Array of nodal coordinates
+//! \param[in] geoElem Element geometry array
+//! \param[in] ref_gp Quadrature point in reference space
+//! \param[in] B Basis function at given quadrature point
+//! \param[in] U Solution vector
+//! \param[in] P Vector of primitives
+//! \return High-order unknown/state vector at quadrature point, modified
+//!   if near interfaces using THINC
+// *****************************************************************************
+{
+  std::vector< real > state;
+  std::vector< real > sprim;
+
+  state = eval_state( ncomp, rdof, dof_e, e, U, B );
+  sprim = eval_state( nprim, rdof, dof_e, e, P, B );
+
+  // interface detection
+  std::vector< std::size_t > matInt(nmat, 0);
+  bool intInd(false);
+  if (nmat > 1) {
+    std::vector< tk::real > alAvg(nmat, 0.0);
+    for (std::size_t k=0; k<nmat; ++k)
+      alAvg[k] = U(e, inciter::volfracDofIdx(nmat,k,rdof,0));
+    intInd = inciter::interfaceIndicator(nmat, alAvg, matInt);
+  }
+
+  // consolidate primitives into state vector
+  state.insert(state.end(), sprim.begin(), sprim.end());
+
+  if (intsharp > 0)
+  {
+    std::vector< tk::real > vfmax(nmat, 0.0), vfmin(nmat, 0.0);
+
+    // Until the appropriate setup for activating THINC with Transport
+    // is ready, the following two chunks of code will need to be commented
+    // for using THINC with Transport
+    //for (std::size_t k=0; k<nmat; ++k) {
+    //  vfmin[k] = VolFracMax(el, 2*k, 0);
+    //  vfmax[k] = VolFracMax(el, 2*k+1, 0);
+    //}
+    tk::THINCReco(rdof, nmat, e, inpoel, coord, geoElem,
+      ref_gp, U, P, intInd, matInt, vfmin, vfmax, state);
+
+    // Until the appropriate setup for activating THINC with Transport
+    // is ready, the following lines will need to be uncommented for
+    // using THINC with Transport
+    //tk::THINCRecoTransport(rdof, nmat, el, inpoel, coord,
+    //  geoElem, ref_gp_l, U, P, vfmin, vfmax, state[0]);
+  }
+
+  // physical constraints
+  if (state.size() > ncomp) {
+    using inciter::pressureIdx;
+    using inciter::volfracIdx;
+    using inciter::densityIdx;
+
+    for (std::size_t k=0; k<nmat; ++k) {
+      state[ncomp+pressureIdx(nmat,k)] = constrain_pressure( mat_blk,
+        state[ncomp+pressureIdx(nmat,k)], state[densityIdx(nmat,k)],
+        state[volfracIdx(nmat,k)], k );
+    }
+  }
+
+  return state;
+}
+
+std::vector< tk::real >
+evalFVSol( const std::vector< inciter::EOS >& mat_blk,
+           int intsharp,
+           std::size_t ncomp,
+           std::size_t nprim,
+           std::size_t rdof,
+           std::size_t nmat,
+           std::size_t e,
+           const std::vector< std::size_t >& inpoel,
+           const UnsMesh::Coords& coord,
+           const Fields& geoElem,
+           const std::array< real, 3 >& ref_gp,
+           const std::vector< real >& B,
+           const Fields& U,
+           const Fields& P,
+           int srcFlag )
+// *****************************************************************************
+//  Evaluate second-order FV solution at quadrature point
+//! \param[in] mat_blk EOS material block
+//! \param[in] intsharp Interface reconstruction indicator
+//! \param[in] ncomp Number of components in the PDE system
+//! \param[in] nprim Number of primitive quantities
+//! \param[in] rdof Total number of reconstructed dofs
+//! \param[in] nmat Total number of materials
+//! \param[in] e Element for which polynomial solution is being evaluated
+//! \param[in] inpoel Element-node connectivity
+//! \param[in] coord Array of nodal coordinates
+//! \param[in] geoElem Element geometry array
+//! \param[in] ref_gp Quadrature point in reference space
+//! \param[in] B Basis function at given quadrature point
+//! \param[in] U Solution vector
+//! \param[in] P Vector of primitives
+//! \param[in] srcFlag Whether the energy source was added to element e
+//! \return High-order unknown/state vector at quadrature point, modified
+//!   if near interfaces using THINC
+// *****************************************************************************
+{
+  using inciter::pressureIdx;
+  using inciter::velocityIdx;
+  using inciter::volfracIdx;
+  using inciter::densityIdx;
+  using inciter::energyIdx;
+  using inciter::momentumIdx;
+
+  std::vector< real > state;
+  std::vector< real > sprim;
+
+  state = eval_state( ncomp, rdof, rdof, e, U, B );
+  sprim = eval_state( nprim, rdof, rdof, e, P, B );
+
+  // interface detection so that eos is called on the appropriate quantities
+  std::vector< std::size_t > matInt(nmat, 0);
+  std::vector< tk::real > alAvg(nmat, 0.0);
+  for (std::size_t k=0; k<nmat; ++k)
+    alAvg[k] = U(e, inciter::volfracDofIdx(nmat,k,rdof,0));
+  auto intInd = inciter::interfaceIndicator(nmat, alAvg, matInt);
+
+  // get mat-energy from reconstructed mat-pressure
+  auto rhob(0.0);
+  for (std::size_t k=0; k<nmat; ++k) {
+    auto alk = state[volfracIdx(nmat,k)];
+    if (matInt[k]) {
+      alk = std::max(std::min(alk, 1.0-static_cast<tk::real>(nmat-1)*1e-12),
+        1e-12);
+    }
+    state[energyIdx(nmat,k)] = alk *
+      mat_blk[k].compute< inciter::EOS::totalenergy >(
+      state[densityIdx(nmat,k)]/alk, sprim[velocityIdx(nmat,0)],
+      sprim[velocityIdx(nmat,1)], sprim[velocityIdx(nmat,2)],
+      sprim[pressureIdx(nmat,k)]/alk);
+    rhob += state[densityIdx(nmat,k)];
+  }
+  // get momentum from reconstructed velocity and bulk density
+  for (std::size_t i=0; i<3; ++i) {
+    state[momentumIdx(nmat,i)] = rhob * sprim[velocityIdx(nmat,i)];
+  }
+
+  // consolidate primitives into state vector
+  state.insert(state.end(), sprim.begin(), sprim.end());
+
+  if (intsharp > 0 && srcFlag == 0)
+  {
+    std::vector< tk::real > vfmax(nmat, 0.0), vfmin(nmat, 0.0);
+
+    tk::THINCReco(rdof, nmat, e, inpoel, coord, geoElem,
+      ref_gp, U, P, intInd, matInt, vfmin, vfmax, state);
+  }
+
+  // physical constraints
+  if (state.size() > ncomp) {
+    for (std::size_t k=0; k<nmat; ++k) {
+      state[ncomp+pressureIdx(nmat,k)] = constrain_pressure( mat_blk,
+        state[ncomp+pressureIdx(nmat,k)], state[densityIdx(nmat,k)],
+        state[volfracIdx(nmat,k)], k );
+    }
+  }
+
+  return state;
+}
+
+void
+safeReco( std::size_t rdof,
+          std::size_t nmat,
+          std::size_t el,
+          int er,
+          const Fields& U,
+          std::array< std::vector< real >, 2 >& state )
+// *****************************************************************************
+//  Compute safe reconstructions near material interfaces
+//! \param[in] rdof Total number of reconstructed dofs
+//! \param[in] nmat Total number of material is PDE system
+//! \param[in] el Element on the left-side of face
+//! \param[in] er Element on the right-side of face
+//! \param[in] U Solution vector at recent time-stage
+//! \param[in,out] state Second-order reconstructed state, at cell-face, that
+//!   is being modified for safety
+//! \details When the consistent limiting is applied, there is a possibility
+//!   that the material densities and energies violate TVD bounds. This function
+//!   enforces the TVD bounds locally
+// *****************************************************************************
+{
+  using inciter::densityIdx;
+  using inciter::energyIdx;
+  using inciter::densityDofIdx;
+  using inciter::energyDofIdx;
+
+  if (er < 0) Throw("safe limiting cannot be called for boundary cells");
+
+  auto eR = static_cast< std::size_t >(er);
+
+  // define a lambda for the safe limiting
+  auto safeLimit = [&]( std::size_t c, real ul, real ur )
+  {
+    // find min/max at the face
+    auto uMin = std::min(ul, ur);
+    auto uMax = std::max(ul, ur);
+
+    // left-state limiting
+    state[0][c] = std::min(uMax, std::max(uMin, state[0][c]));
+
+    // right-state limiting
+    state[1][c] = std::min(uMax, std::max(uMin, state[1][c]));
+  };
+
+  for (std::size_t k=0; k<nmat; ++k)
+  {
+    real ul(0.0), ur(0.0);
+
+    // Density
+    // establish left- and right-hand states
+    ul = U(el, densityDofIdx(nmat, k, rdof, 0));
+    ur = U(eR, densityDofIdx(nmat, k, rdof, 0));
+
+    // limit reconstructed density
+    safeLimit(densityIdx(nmat,k), ul, ur);
+
+    // Energy
+    // establish left- and right-hand states
+    ul = U(el, energyDofIdx(nmat, k, rdof, 0));
+    ur = U(eR, energyDofIdx(nmat, k, rdof, 0));
+
+    // limit reconstructed energy
+    safeLimit(energyIdx(nmat,k), ul, ur);
+  }
+}
+
+} // tk::
 
diff --git a/Debug/cppcheck/75.html b/Debug/cppcheck/75.html index a8e3a3f12a46..4b73e9080e54 100644 --- a/Debug/cppcheck/75.html +++ b/Debug/cppcheck/75.html @@ -152,12 +152,12 @@
  1
@@ -302,149 +302,159 @@ 

Cppcheck report - [

// *****************************************************************************
+143
+144
+145
+146
+147
+148
// *****************************************************************************
 /*!
-  \file      src/PDE/MultiMat/Physics/FVEnergyPill.cpp
+  \file      src/Statistics/UniPDF.hpp
   \copyright 2012-2015 J. Bakosi,
              2016-2018 Los Alamos National Security, LLC.,
              2019-2021 Triad National Security, LLC.
              All rights reserved. See the LICENSE file for details.
-  \brief     Physics policy for the Euler equation governing multi-material flow
-    using a finite volume method
-  \details   This file defines a Physics policy class for the compressible
-    flow equations class fv::MultiMat, defined in PDE/MultiMat/FVMultiMat.h.
-    This specific class allows energy pill initialization of a user defined
-    box/block for multi-material flow. See PDE/MultiMat/Physics/FV.h for general
-    requirements on Physics policy classes for fv::MultiMat.
-*/
-// *****************************************************************************
-
-#include "FVEnergyPill.hpp"
-#include "Inciter/InputDeck/InputDeck.hpp"
-#include "ContainerUtil.hpp"
-#include "MultiMat/MultiMatIndexing.hpp"
-#include "NoWarning/charm++.hpp"
+  \brief     Univariate PDF estimator
+  \details   Univariate PDF estimator. This class can be used to estimate a
+    probability density function of (PDF) a scalar variable from an ensemble.
+    The implementation uses the standard container std::unordered_map, which is
+    a hash-based associative container with linear algorithmic complexity for
+    insertion of a new sample.
+*/
+// *****************************************************************************
+#ifndef UniPDF_h
+#define UniPDF_h
+
+#include <array>
+#include <unordered_map>
+#include <algorithm>
+#include <cfenv>
 
-namespace inciter {
-
-extern ctr::InputDeck g_inputdeck;
+#include "Types.hpp"
+#include "Exception.hpp"
+#include "PUPUtil.hpp"
 
-} // inciter::
+namespace tk {
 
-using inciter::fv::MultiMatPhysicsEnergyPill;
-
-tk::real
-MultiMatPhysicsEnergyPill::dtRestriction(
-  const tk::Fields& geoElem,
-  std::size_t nelem,
-  const std::vector< int >& engSrcAd ) const
-// *****************************************************************************
-//  Compute the time step size restriction based on this physics
-//! \param[in] geoElem Element geometry array
-//! \param[in] nelem Number of elements
-//! \param[in] engSrcAd Whether the energy source was added
-//! \return Maximum allowable time step based on front propagation speed
-// *****************************************************************************
-{
-  auto mindt = std::numeric_limits< tk::real >::max();
-  // determine front propagation speed
-  const auto& icmbk = g_inputdeck.get< tag::ic, tag::meshblock >();
-  tk::real v_front(0.0);
-  for (const auto& b : icmbk) { // for all blocks
-    auto inittype = b.template get< tag::initiate >();
-    if (inittype == ctr::InitiateType::LINEAR) {
-      v_front = std::max(v_front,
-        b.template get< tag::front_speed >());
-    }
-  }
-
-  for (std::size_t e=0; e<nelem; ++e)
-  {
-    // characteristic length (radius of insphere)
-    auto dx = std::min(std::cbrt(geoElem(e,0)), geoElem(e,4))
-      /std::sqrt(24.0);
-
-    // element dt restriction if relevant energy sources were added
-    if (engSrcAd[e] > 0 && std::abs(v_front) > 1e-8)
-      mindt = std::min(mindt, dx/v_front);
-  }
-
-  return mindt;
-}
-
-void MultiMatPhysicsEnergyPill::
-physSrc(
-  std::size_t nmat,
-  tk::real t,
-  const tk::Fields& geoElem,
-  const std::unordered_map< std::size_t, std::set< std::size_t > >& elemblkid,
-  tk::Fields& R,<--- Parameter 'R' can be declared with const
-  std::vector< int >& engSrcAdded ) const
-// *****************************************************************************
-//! Compute sources corresponding to a propagating front in user-defined box
-//! \param[in] nmat Number of materials
-//! \param[in] t Physical time
-//! \param[in] geoElem Element geometry array
-//! \param[in] elemblkid Element ids associated with mesh block ids where
-//!   user ICs are set
-//! \param[in,out] R Right-hand side vector
-//! \param[in,out] engSrcAdded Whether the energy source was added
-//! \details This function adds the energy source corresponding to a
-//!   spherically growing wave-front propagating with a user-specified
-//!   velocity, within a user-configured mesh block initial condition.
-//!   Example (SI) units of the quantities involved:
-//!    * internal energy content (energy per unit volume): J/m^3
-//!    * specific energy (internal energy per unit mass): J/kg
-// *****************************************************************************
-{
-  const auto& icmbk = g_inputdeck.get< tag::ic, tag::meshblock >();
-  for (const auto& mb : icmbk) { // for all blocks
-    auto blid = mb.get< tag::blockid >();
-    if (elemblkid.find(blid) != elemblkid.end()) { // if elements exist in blk
-      const auto& initiate = mb.template get< tag::initiate >();
-      if (initiate == ctr::InitiateType::LINEAR) { // if propagating src
+//! Univariate PDF estimator
+class UniPDF {
+
+  public:
+    //! Number of sample space dimensions
+    static const std::size_t dim = 1;
+
+    //! Key type
+    using key_type = long;
+
+    //! Pair type
+    using pair_type = std::pair< const key_type, tk::real >;
+
+    //! \brief Univariate PDF
+    //! \details The underlying container type is an unordered_map where the key
+    //!   is one bin id corresponding to the single sample space dimension, and
+    //!   the mapped value is the sample counter. The hasher functor used here
+    //!   is the default for the key type provided by the standard library.
+    using map_type = std::unordered_map< key_type, tk::real >;
+
+    //! Empty constructor for Charm++
+    explicit UniPDF() : m_binsize( 0 ), m_nsample( 0 ), m_pdf() {}
+
+    //! Constructor: Initialize univariate PDF container
+    //! \param[in] bs Sample space bin size
+    explicit UniPDF( tk::real bs ) :
+      m_binsize( bs ), m_nsample( 0 ), m_pdf() {}
+
+    //! Accessor to number of samples
+    //! \return Number of samples collected
+    std::size_t nsample() const noexcept { return m_nsample; }
+
+    //! Add sample to univariate PDF
+    //! \param[in] sample Sample to insert
+    void add( tk::real sample ) {
+      Assert( m_binsize > 0, "Bin size must be positive" );
+      ++m_nsample;
+      fenv_t fe;
+      feholdexcept( &fe );
+      ++m_pdf[ std::lround( sample / m_binsize ) ];
+      feclearexcept( FE_UNDERFLOW );
+      feupdateenv( &fe );
+    }
+
+    //! Add multiple samples from a PDF
+    //! \param[in] p PDF whose samples to add
+    void addPDF( const UniPDF& p ) {
+      m_binsize = p.binsize();
+      m_nsample += p.nsample();
+      for (const auto& e : p.map()) m_pdf[ e.first ] += e.second;
+    }
+
+    //! Zero bins
+    void zero() noexcept { m_nsample = 0; m_pdf.clear(); }
+
+    //! Constant accessor to underlying PDF map
+    //! \return Constant reference to underlying map
+    const map_type& map() const noexcept { return m_pdf; }
+
+    //! Constant accessor to bin size
+    //! \return Sample space bin size
+    tk::real binsize() const noexcept { return m_binsize; }
+
+    //! Return minimum and maximum bin ids of sample space
+    //! \return {min,max} Minimum and maximum of the bin ids
+    std::array< long, 2*dim > extents() const {
+      Assert( !m_pdf.empty(), "PDF empty" );
+      auto x = std::minmax_element( begin(m_pdf), end(m_pdf),
+                 []( const pair_type& a, const pair_type& b )
+                 { return a.first < b.first; } );
+      return {{ x.first->first, x.second->first }};
+    }
 
-        const auto& blkelems = tk::cref_find(elemblkid,blid);
-
-        auto enc = mb.template get< tag::energy_content >();
-        Assert( enc > 0.0, "Box energy content must be nonzero" );
-        const auto& x0_front = mb.template get< tag::point >();
-        Assert(x0_front.size()==3, "Incorrectly sized front initial location");
-        auto blkmatid = mb.template get< tag::materialid >();
+    //! Compute integral of the distribution across the whole sample space
+    //! \return Integral of the distribution
+    tk::real integral() const {
+      return std::accumulate( m_pdf.cbegin(), m_pdf.cend(), 0.0,
+        [&]( tk::real i, const pair_type& p ){
+          return i + p.second; } ) / static_cast< tk::real >( m_nsample );
+    }
 
-        // determine times at which sourcing is initialized and terminated
-        auto v_front = mb.template get< tag::front_speed >();
-        auto w_front = mb.template get< tag::front_width >();
-        auto tInit = mb.template get< tag::init_time >();
-
-        if (t >= tInit) {
-          // current radius of front
-          tk::real r_front = v_front * (t-tInit);
-          // arbitrary shape form
-          auto amplE = enc * v_front / w_front;
-
-          for (auto e : blkelems) {
-            std::array< tk::real, 3 > node{{ geoElem(e,1), geoElem(e,2),
-              geoElem(e,3) }};
+    /** @name Pack/Unpack: Serialize UniPDF object for Charm++ */
+    ///@{
+    //! Pack/Unpack serialize member function
+    //! \param[in,out] p Charm++'s PUP::er serializer object reference
+    void pup( PUP::er& p ) {<--- Parameter 'p' can be declared with const
+      p | m_binsize;
+      p | m_nsample;
+      p | m_pdf;
+    }
+    //! \brief Pack/Unpack serialize operator|
+    //! \param[in,out] p Charm++'s PUP::er serializer object reference
+    //! \param[in,out] c UniPDF object reference
+    friend void operator|( PUP::er& p, UniPDF& c ) { c.pup(p); }
+    ///@}
 
-            auto r_e = std::sqrt(
-              (node[0]-x0_front[0])*(node[0]-x0_front[0]) +
-              (node[1]-x0_front[1])*(node[1]-x0_front[1]) +
-              (node[2]-x0_front[2])*(node[2]-x0_front[2]) );
-
-            // if element centroid lies within spherical shell add sources
-            if (r_e >= r_front && r_e <= r_front+w_front) {
-              // Add the source term to the rhs
-              R(e, energyDofIdx(nmat,blkmatid-1,1,0)) += geoElem(e,0) * amplE;
-              engSrcAdded[e] = 1;
-            }
-          }
-        }
-
-      }
-    }
-  }
-}
+  private:
+    tk::real m_binsize;         //!< Sample space bin size
+    std::size_t m_nsample;      //!< Number of samples collected
+    map_type m_pdf;             //!< Probability density function
+};
+
+//! Output univariate PDF to output stream
+//! \param[in,out] os Stream to output to
+//! \param[in] p PDF to output
+//! \return Updated stream
+//! \note Used for debugging.
+static inline
+std::ostream& operator<< ( std::ostream& os, const tk::UniPDF& p ) {
+  os << p.binsize() << ", " << p.nsample() << ": ";
+  std::map< typename tk::UniPDF::key_type, tk::real >
+    sorted( p.map().begin(), p.map().end() );
+  for (const auto& b : sorted) os << '(' << b.first << ',' << b.second << ") ";
+  return os;
+}
+
+} // tk::
+
+#endif // UniPDF_h
 
diff --git a/Debug/cppcheck/76.html b/Debug/cppcheck/76.html index 9594a13bb151..fbd5df192c2b 100644 --- a/Debug/cppcheck/76.html +++ b/Debug/cppcheck/76.html @@ -152,12 +152,12 @@
  1
@@ -292,169 +292,139 @@ 

Cppcheck report - [

// *****************************************************************************
+133
// *****************************************************************************
 /*!
-  \file      src/Statistics/UniPDF.hpp
+  \file      src/Statistics/BiPDF.hpp
   \copyright 2012-2015 J. Bakosi,
              2016-2018 Los Alamos National Security, LLC.,
              2019-2021 Triad National Security, LLC.
              All rights reserved. See the LICENSE file for details.
-  \brief     Univariate PDF estimator
-  \details   Univariate PDF estimator. This class can be used to estimate a
-    probability density function of (PDF) a scalar variable from an ensemble.
-    The implementation uses the standard container std::unordered_map, which is
-    a hash-based associative container with linear algorithmic complexity for
-    insertion of a new sample.
+  \brief     Joint bivariate PDF estimator
+  \details   Joint bivariate PDF estimator. This class can be used to estimate a
+    joint probability density function (PDF) of two scalar variables from an
+    ensemble. The implementation uses the standard container std::unordered_map,
+    which is a hash-based associative container with linear algorithmic
+    complexity for insertion of a new sample.
 */
 // *****************************************************************************
-#ifndef UniPDF_h
-#define UniPDF_h
+#ifndef BiPDF_h
+#define BiPDF_h
 
 #include <array>
 #include <unordered_map>
 #include <algorithm>
-#include <cfenv>
-
-#include "Types.hpp"
-#include "Exception.hpp"
-#include "PUPUtil.hpp"
+
+#include "Types.hpp"
+#include "PUPUtil.hpp"
+
+namespace tk {
 
-namespace tk {
-
-//! Univariate PDF estimator
-class UniPDF {
-
-  public:
-    //! Number of sample space dimensions
-    static const std::size_t dim = 1;
-
-    //! Key type
-    using key_type = long;
-
-    //! Pair type
-    using pair_type = std::pair< const key_type, tk::real >;
-
-    //! \brief Univariate PDF
-    //! \details The underlying container type is an unordered_map where the key
-    //!   is one bin id corresponding to the single sample space dimension, and
-    //!   the mapped value is the sample counter. The hasher functor used here
-    //!   is the default for the key type provided by the standard library.
-    using map_type = std::unordered_map< key_type, tk::real >;
-
-    //! Empty constructor for Charm++
-    explicit UniPDF() : m_binsize( 0 ), m_nsample( 0 ), m_pdf() {}
-
-    //! Constructor: Initialize univariate PDF container
-    //! \param[in] bs Sample space bin size
-    explicit UniPDF( tk::real bs ) :
-      m_binsize( bs ), m_nsample( 0 ), m_pdf() {}
+//! Joint bivariate PDF estimator
+class BiPDF {
+
+  public:
+    //! Number of sample space dimensions
+    static const std::size_t dim = 2;
+
+    //! Key type
+    using key_type = std::array< long, dim >;
+
+    //! Pair type
+    using pair_type = std::pair< const key_type, tk::real >;
+
+    // Hash functor for key_type
+    struct key_hash {
+      std::size_t operator()( const key_type& key ) const {
+        return std::hash< long >()( key[0] ) ^ std::hash< long >()( key[1] );
+      }
+    };
+
+    //! \brief Joint bivariate PDF
+    //! \details The underlying container type is an unordered_map where the key
+    //!   is two bin ids corresponding to the two sample space dimensions, and
+    //!   the mapped value is the sample counter. The hasher functor, defined by
+    //!   key_hash provides an XORed hash of the two bin ids.
+    using map_type = std::unordered_map< key_type, tk::real, key_hash >;
+
+    //! Empty constructor for Charm++
+    explicit BiPDF() : m_binsize( {{ 0, 0 }} ), m_nsample( 0 ), m_pdf() {}
 
-    //! Accessor to number of samples
-    //! \return Number of samples collected
-    std::size_t nsample() const noexcept { return m_nsample; }
-
-    //! Add sample to univariate PDF
-    //! \param[in] sample Sample to insert
-    void add( tk::real sample ) {
-      Assert( m_binsize > 0, "Bin size must be positive" );
-      ++m_nsample;
-      fenv_t fe;
-      feholdexcept( &fe );
-      ++m_pdf[ std::lround( sample / m_binsize ) ];
-      feclearexcept( FE_UNDERFLOW );
-      feupdateenv( &fe );
-    }
-
-    //! Add multiple samples from a PDF
-    //! \param[in] p PDF whose samples to add
-    void addPDF( const UniPDF& p ) {
-      m_binsize = p.binsize();
-      m_nsample += p.nsample();
-      for (const auto& e : p.map()) m_pdf[ e.first ] += e.second;
-    }
-
-    //! Zero bins
-    void zero() noexcept { m_nsample = 0; m_pdf.clear(); }
-
-    //! Constant accessor to underlying PDF map
-    //! \return Constant reference to underlying map
-    const map_type& map() const noexcept { return m_pdf; }
-
-    //! Constant accessor to bin size
-    //! \return Sample space bin size
-    tk::real binsize() const noexcept { return m_binsize; }
-
-    //! Return minimum and maximum bin ids of sample space
-    //! \return {min,max} Minimum and maximum of the bin ids
-    std::array< long, 2*dim > extents() const {
-      Assert( !m_pdf.empty(), "PDF empty" );
-      auto x = std::minmax_element( begin(m_pdf), end(m_pdf),
-                 []( const pair_type& a, const pair_type& b )
-                 { return a.first < b.first; } );
-      return {{ x.first->first, x.second->first }};
-    }
-
-    //! Compute integral of the distribution across the whole sample space
-    //! \return Integral of the distribution
-    tk::real integral() const {
-      return std::accumulate( m_pdf.cbegin(), m_pdf.cend(), 0.0,
-        [&]( tk::real i, const pair_type& p ){
-          return i + p.second; } ) / static_cast< tk::real >( m_nsample );
-    }
-
-    /** @name Pack/Unpack: Serialize UniPDF object for Charm++ */
-    ///@{
-    //! Pack/Unpack serialize member function
-    //! \param[in,out] p Charm++'s PUP::er serializer object reference
-    void pup( PUP::er& p ) {<--- Parameter 'p' can be declared with const
-      p | m_binsize;
-      p | m_nsample;
-      p | m_pdf;
-    }
-    //! \brief Pack/Unpack serialize operator|
-    //! \param[in,out] p Charm++'s PUP::er serializer object reference
-    //! \param[in,out] c UniPDF object reference
-    friend void operator|( PUP::er& p, UniPDF& c ) { c.pup(p); }
-    ///@}
-
-  private:
-    tk::real m_binsize;         //!< Sample space bin size
-    std::size_t m_nsample;      //!< Number of samples collected
-    map_type m_pdf;             //!< Probability density function
-};
-
-//! Output univariate PDF to output stream
-//! \param[in,out] os Stream to output to
-//! \param[in] p PDF to output
-//! \return Updated stream
-//! \note Used for debugging.
-static inline
-std::ostream& operator<< ( std::ostream& os, const tk::UniPDF& p ) {
-  os << p.binsize() << ", " << p.nsample() << ": ";
-  std::map< typename tk::UniPDF::key_type, tk::real >
-    sorted( p.map().begin(), p.map().end() );
-  for (const auto& b : sorted) os << '(' << b.first << ',' << b.second << ") ";
-  return os;
-}
-
-} // tk::
-
-#endif // UniPDF_h
+    //! Constructor: Initialize joint bivariate PDF container
+    //! \param[in] bs Sample space bin size in both directions
+    explicit BiPDF( const std::vector< tk::real >& bs ) :
+      m_binsize( {{ bs[0], bs[1] }} ), m_nsample( 0 ), m_pdf() {}
+
+    //! Accessor to number of samples
+    //! \return Number of samples collected
+    std::size_t nsample() const noexcept { return m_nsample; }
+
+    //! Add sample to bivariate PDF
+    //! \param[in] sample Sample to add
+    void add( std::array< tk::real, dim > sample ) {
+      ++m_nsample;
+      ++m_pdf[ {{ std::lround( sample[0] / m_binsize[0] ),
+                  std::lround( sample[1] / m_binsize[1] ) }} ];
+    }
+
+    //! Add multiple samples from a PDF
+    //! \param[in] p PDF whose samples to add
+    void addPDF( const BiPDF& p ) {
+      m_binsize = p.binsize();
+      m_nsample += p.nsample();
+      for (const auto& e : p.map()) m_pdf[ e.first ] += e.second;
+    }
+
+    //! Zero bins
+    void zero() noexcept { m_nsample = 0; m_pdf.clear(); }
+
+    //! Constant accessor to underlying PDF map
+    //! \return Constant reference to underlying map
+    const map_type& map() const noexcept { return m_pdf; }
+
+    //! Constant accessor to bin sizes
+    //! \return Constant reference to sample space bin sizes
+    const std::array< tk::real, dim >& binsize() const noexcept
+    { return m_binsize; }
+
+    //! Return minimum and maximum bin ids of sample space in both dimensions
+    //! \return {xmin,xmax,ymin,ymax} Minima and maxima of the bin ids in a
+    //!    std::array
+    std::array< long, 2*dim > extents() const {
+      Assert( !m_pdf.empty(), "PDF empty" );
+      auto x = std::minmax_element( begin(m_pdf), end(m_pdf),
+                 []( const pair_type& a, const pair_type& b )
+                 { return a.first[0] < b.first[0]; } );
+      auto y = std::minmax_element( begin(m_pdf), end(m_pdf),
+                 []( const pair_type& a, const pair_type& b )
+                 { return a.first[1] < b.first[1]; } );
+      return {{ x.first->first[0], x.second->first[0],
+                y.first->first[1], y.second->first[1] }};
+    }
+
+    /** @name Pack/Unpack: Serialize BiPDF object for Charm++ */
+    ///@{
+    //! Pack/Unpack serialize member function
+    //! \param[in,out] p Charm++'s PUP::er serializer object reference
+    void pup( PUP::er& p ) {<--- Parameter 'p' can be declared with const
+      p | m_binsize;
+      p | m_nsample;
+      p | m_pdf;
+    }
+    //! \brief Pack/Unpack serialize operator|
+    //! \param[in,out] p Charm++'s PUP::er serializer object reference
+    //! \param[in,out] c BiPDF object reference
+    friend void operator|( PUP::er& p, BiPDF& c ) { c.pup(p); }
+    ///@}
+
+  private:
+    std::array< tk::real, dim > m_binsize;  //!< Sample space bin sizes
+    std::size_t m_nsample;                  //!< Number of samples collected
+    map_type m_pdf;                         //!< Probability density function
+};
+
+} // tk::
+
+#endif // BiPDF_h
 
diff --git a/Debug/cppcheck/77.html b/Debug/cppcheck/77.html index bcc21cdbec2b..cd57a1006e39 100644 --- a/Debug/cppcheck/77.html +++ b/Debug/cppcheck/77.html @@ -152,12 +152,12 @@
  1
@@ -292,23 +292,32 @@ 

Cppcheck report - [

// *****************************************************************************
+133
+134
+135
+136
+137
+138
+139
+140
+141
+142
// *****************************************************************************
 /*!
-  \file      src/Statistics/BiPDF.hpp
+  \file      src/Statistics/TriPDF.hpp
   \copyright 2012-2015 J. Bakosi,
              2016-2018 Los Alamos National Security, LLC.,
              2019-2021 Triad National Security, LLC.
              All rights reserved. See the LICENSE file for details.
-  \brief     Joint bivariate PDF estimator
-  \details   Joint bivariate PDF estimator. This class can be used to estimate a
-    joint probability density function (PDF) of two scalar variables from an
+  \brief     Joint trivariate PDF estimator
+  \details   Joint trivariate PDF estimator. This class can be used to estimate
+    a joint probability density function (PDF) of three scalar variables from an
     ensemble. The implementation uses the standard container std::unordered_map,
     which is a hash-based associative container with linear algorithmic
     complexity for insertion of a new sample.
 */
 // *****************************************************************************
-#ifndef BiPDF_h
-#define BiPDF_h
+#ifndef TriPDF_h
+#define TriPDF_h
 
 #include <array>
 #include <unordered_map>
@@ -319,12 +328,12 @@ 

Cppcheck report - [ namespace tk { -//! Joint bivariate PDF estimator -class BiPDF { +//! Joint trivariate PDF estimator +class TriPDF { public: //! Number of sample space dimensions - static const std::size_t dim = 2; + static const std::size_t dim = 3; //! Key type using key_type = std::array< long, dim >; @@ -335,96 +344,105 @@

Cppcheck report - [ // Hash functor for key_type struct key_hash { std::size_t operator()( const key_type& key ) const { - return std::hash< long >()( key[0] ) ^ std::hash< long >()( key[1] ); - } - }; - - //! \brief Joint bivariate PDF - //! \details The underlying container type is an unordered_map where the key - //! is two bin ids corresponding to the two sample space dimensions, and - //! the mapped value is the sample counter. The hasher functor, defined by - //! key_hash provides an XORed hash of the two bin ids. - using map_type = std::unordered_map< key_type, tk::real, key_hash >; - - //! Empty constructor for Charm++ - explicit BiPDF() : m_binsize( {{ 0, 0 }} ), m_nsample( 0 ), m_pdf() {} - - //! Constructor: Initialize joint bivariate PDF container - //! \param[in] bs Sample space bin size in both directions - explicit BiPDF( const std::vector< tk::real >& bs ) : - m_binsize( {{ bs[0], bs[1] }} ), m_nsample( 0 ), m_pdf() {} - - //! Accessor to number of samples - //! \return Number of samples collected - std::size_t nsample() const noexcept { return m_nsample; } + return std::hash< long >()( key[0] ) ^ + std::hash< long >()( key[1] ) ^ + std::hash< long >()( key[2] ); + } + }; + + //! \brief Joint trivariate PDF + //! \details The underlying container type is an unordered_map where the key + //! is three bin ids corresponding to the three sample space dimensions, + //! and the mapped value is the sample counter. The hasher functor, + //! defined by key_hash provides an XORed hash of the three bin ids. + using map_type = std::unordered_map< key_type, tk::real, key_hash >; + + //! Empty constructor for Charm++ + explicit TriPDF() : m_binsize( {{ 0, 0, 0 }} ), m_nsample( 0 ), m_pdf() {} + + //! Constructor: Initialize joint trivariate PDF container + //! \param[in] bs Sample space bin size in all three directions + explicit TriPDF( const std::vector< tk::real >& bs ) : + m_binsize( {{ bs[0], bs[1], bs[2] }} ), + m_nsample( 0 ), + m_pdf() {} - //! Add sample to bivariate PDF - //! \param[in] sample Sample to add - void add( std::array< tk::real, dim > sample ) { - ++m_nsample; - ++m_pdf[ {{ std::lround( sample[0] / m_binsize[0] ), - std::lround( sample[1] / m_binsize[1] ) }} ]; - } - - //! Add multiple samples from a PDF - //! \param[in] p PDF whose samples to add - void addPDF( const BiPDF& p ) { - m_binsize = p.binsize(); - m_nsample += p.nsample(); - for (const auto& e : p.map()) m_pdf[ e.first ] += e.second; - } - - //! Zero bins - void zero() noexcept { m_nsample = 0; m_pdf.clear(); } - - //! Constant accessor to underlying PDF map - //! \return Constant reference to underlying map - const map_type& map() const noexcept { return m_pdf; } - - //! Constant accessor to bin sizes - //! \return Constant reference to sample space bin sizes - const std::array< tk::real, dim >& binsize() const noexcept - { return m_binsize; } + //! Accessor to number of samples + //! \return Number of samples collected + std::size_t nsample() const noexcept { return m_nsample; } + + //! Add sample to trivariate PDF + //! \param[in] sample Sample to add + void add( std::array< tk::real, dim > sample ) { + ++m_nsample; + ++m_pdf[ {{ std::lround( sample[0] / m_binsize[0] ), + std::lround( sample[1] / m_binsize[1] ), + std::lround( sample[2] / m_binsize[2] ) }} ]; + } + + //! Add multiple samples from a PDF + //! \param[in] p PDF whose samples to add + void addPDF( const TriPDF& p ) { + m_binsize = p.binsize(); + m_nsample += p.nsample(); + for (const auto& e : p.map()) m_pdf[ e.first ] += e.second; + } + + //! Zero bins + void zero() noexcept { m_nsample = 0; m_pdf.clear(); } + + //! Constant accessor to underlying PDF map + //! \return Constant reference to underlying map + const map_type& map() const noexcept { return m_pdf; } - //! Return minimum and maximum bin ids of sample space in both dimensions - //! \return {xmin,xmax,ymin,ymax} Minima and maxima of the bin ids in a - //! std::array - std::array< long, 2*dim > extents() const { - Assert( !m_pdf.empty(), "PDF empty" ); - auto x = std::minmax_element( begin(m_pdf), end(m_pdf), - []( const pair_type& a, const pair_type& b ) - { return a.first[0] < b.first[0]; } ); - auto y = std::minmax_element( begin(m_pdf), end(m_pdf), - []( const pair_type& a, const pair_type& b ) - { return a.first[1] < b.first[1]; } ); - return {{ x.first->first[0], x.second->first[0], - y.first->first[1], y.second->first[1] }}; - } - - /** @name Pack/Unpack: Serialize BiPDF object for Charm++ */ - ///@{ - //! Pack/Unpack serialize member function - //! \param[in,out] p Charm++'s PUP::er serializer object reference - void pup( PUP::er& p ) {<--- Parameter 'p' can be declared with const - p | m_binsize; - p | m_nsample; - p | m_pdf; - } - //! \brief Pack/Unpack serialize operator| - //! \param[in,out] p Charm++'s PUP::er serializer object reference - //! \param[in,out] c BiPDF object reference - friend void operator|( PUP::er& p, BiPDF& c ) { c.pup(p); } - ///@} - - private: - std::array< tk::real, dim > m_binsize; //!< Sample space bin sizes - std::size_t m_nsample; //!< Number of samples collected - map_type m_pdf; //!< Probability density function -}; - -} // tk:: - -#endif // BiPDF_h + //! Constant accessor to bin sizes + //! \return Constant reference to sample space bin sizes + const std::array< tk::real, dim >& binsize() const noexcept + { return m_binsize; } + + //! \brief Return minimum and maximum bin ids of sample space in all three + //! dimensions + //! \return {xmin,xmax,ymin,ymax,zmin,zmax} Minima and maxima of bin the ids + std::array< long, 2*dim > extents() const { + Assert( !m_pdf.empty(), "PDF empty" ); + auto x = std::minmax_element( begin(m_pdf), end(m_pdf), + []( const pair_type& a, const pair_type& b ) + { return a.first[0] < b.first[0]; } ); + auto y = std::minmax_element( begin(m_pdf), end(m_pdf), + []( const pair_type& a, const pair_type& b ) + { return a.first[1] < b.first[1]; } ); + auto z = std::minmax_element( begin(m_pdf), end(m_pdf), + []( const pair_type& a, const pair_type& b ) + { return a.first[2] < b.first[2]; } ); + return {{ x.first->first[0], x.second->first[0], + y.first->first[1], y.second->first[1], + z.first->first[2], z.second->first[2] }}; + } + + /** @name Pack/Unpack: Serialize BiPDF object for Charm++ */ + ///@{ + //! Pack/Unpack serialize member function + //! \param[in,out] p Charm++'s PUP::er serializer object reference + void pup( PUP::er& p ) {<--- Parameter 'p' can be declared with const + p | m_binsize; + p | m_nsample; + p | m_pdf; + } + //! \brief Pack/Unpack serialize operator| + //! \param[in,out] p Charm++'s PUP::er serializer object reference + //! \param[in,out] c TriPDF object reference + friend void operator|( PUP::er& p, TriPDF& c ) { c.pup(p); } + ///@} + + private: + std::array< tk::real, dim > m_binsize; //!< Sample space bin sizes + std::size_t m_nsample; //!< Number of samples collected + map_type m_pdf; //!< Probability density function +}; + +} // tk:: + +#endif // TriPDF_h

diff --git a/Debug/cppcheck/78.html b/Debug/cppcheck/78.html index 054d55b8eb14..08a47693f80c 100644 --- a/Debug/cppcheck/78.html +++ b/Debug/cppcheck/78.html @@ -152,12 +152,12 @@
  1
@@ -301,148 +301,192 @@ 

Cppcheck report - [

// *****************************************************************************
+142
+143
+144
+145
+146
+147
+148
+149
+150
+151
+152
+153
+154
+155
+156
+157
+158
+159
+160
+161
+162
+163
+164
// *****************************************************************************
 /*!
-  \file      src/Statistics/TriPDF.hpp
+  \file      src/Statistics/PDFReducer.cpp
   \copyright 2012-2015 J. Bakosi,
              2016-2018 Los Alamos National Security, LLC.,
              2019-2021 Triad National Security, LLC.
              All rights reserved. See the LICENSE file for details.
-  \brief     Joint trivariate PDF estimator
-  \details   Joint trivariate PDF estimator. This class can be used to estimate
-    a joint probability density function (PDF) of three scalar variables from an
-    ensemble. The implementation uses the standard container std::unordered_map,
-    which is a hash-based associative container with linear algorithmic
-    complexity for insertion of a new sample.
-*/
-// *****************************************************************************
-#ifndef TriPDF_h
-#define TriPDF_h
+  \brief     Custom Charm++ reducer for merging PDFs across PEs
+  \details   Custom Charm++ reducer for merging PDFs across PEs.
+*/
+// *****************************************************************************
+
+#include <memory>
+
+#include "PDFReducer.hpp"
+
+namespace tk {
 
-#include <array>
-#include <unordered_map>
-#include <algorithm>
-
-#include "Types.hpp"
-#include "PUPUtil.hpp"
-
-namespace tk {
-
-//! Joint trivariate PDF estimator
-class TriPDF {
-
-  public:
-    //! Number of sample space dimensions
-    static const std::size_t dim = 3;
-
-    //! Key type
-    using key_type = std::array< long, dim >;
-
-    //! Pair type
-    using pair_type = std::pair< const key_type, tk::real >;
+std::pair< int, std::unique_ptr<char[]> >
+serialize( std::size_t meshid, const std::vector< tk::UniPDF >& u )
+// *****************************************************************************
+// Serialize univariate PDFs to raw memory stream
+//! \param[in] meshid Mesh ID
+//! \param[in] u Univariate PDFs
+//! \return Pair of the length and the raw stream containing the serialized PDFs
+// *****************************************************************************
+{
+  // Prepare for serializing PDF to a raw binary stream, compute size
+  PUP::sizer sizer;
+  sizer | meshid;<--- Uninitialized variable: meshid
+  sizer | const_cast< std::vector< tk::UniPDF >& >( u );
+
+  // Create raw character stream to store the serialized PDF
+  std::unique_ptr<char[]> flatData = std::make_unique<char[]>( sizer.size() );
+
+  // Serialize PDF, the message will contain a univariate PDF
+  PUP::toMem packer( flatData.get() );
+  packer | meshid;<--- Uninitialized variable: meshid
+  packer | const_cast< std::vector< tk::UniPDF >& >( u );
 
-    // Hash functor for key_type
-    struct key_hash {
-      std::size_t operator()( const key_type& key ) const {
-        return std::hash< long >()( key[0] ) ^
-               std::hash< long >()( key[1] ) ^
-               std::hash< long >()( key[2] );
-      }
-    };
-
-    //! \brief Joint trivariate PDF
-    //! \details The underlying container type is an unordered_map where the key
-    //!   is three bin ids corresponding to the three sample space dimensions,
-    //!   and the mapped value is the sample counter. The hasher functor,
-    //!   defined by key_hash provides an XORed hash of the three bin ids.
-    using map_type = std::unordered_map< key_type, tk::real, key_hash >;
-
-    //! Empty constructor for Charm++
-    explicit TriPDF() : m_binsize( {{ 0, 0, 0 }} ), m_nsample( 0 ), m_pdf() {}
-
-    //! Constructor: Initialize joint trivariate PDF container
-    //! \param[in] bs Sample space bin size in all three directions
-    explicit TriPDF( const std::vector< tk::real >& bs ) :
-      m_binsize( {{ bs[0], bs[1], bs[2] }} ),
-      m_nsample( 0 ),
-      m_pdf() {}
-
-    //! Accessor to number of samples
-    //! \return Number of samples collected
-    std::size_t nsample() const noexcept { return m_nsample; }
-
-    //! Add sample to trivariate PDF
-    //! \param[in] sample Sample to add
-    void add( std::array< tk::real, dim > sample ) {
-      ++m_nsample;
-      ++m_pdf[ {{ std::lround( sample[0] / m_binsize[0] ),
-                  std::lround( sample[1] / m_binsize[1] ),
-                  std::lround( sample[2] / m_binsize[2] ) }} ];
-    }
-
-    //! Add multiple samples from a PDF
-    //! \param[in] p PDF whose samples to add
-    void addPDF( const TriPDF& p ) {
-      m_binsize = p.binsize();
-      m_nsample += p.nsample();
-      for (const auto& e : p.map()) m_pdf[ e.first ] += e.second;
-    }
-
-    //! Zero bins
-    void zero() noexcept { m_nsample = 0; m_pdf.clear(); }
-
-    //! Constant accessor to underlying PDF map
-    //! \return Constant reference to underlying map
-    const map_type& map() const noexcept { return m_pdf; }
-
-    //! Constant accessor to bin sizes
-    //! \return Constant reference to sample space bin sizes
-    const std::array< tk::real, dim >& binsize() const noexcept
-    { return m_binsize; }
-
-    //! \brief Return minimum and maximum bin ids of sample space in all three
-    //!   dimensions
-    //! \return {xmin,xmax,ymin,ymax,zmin,zmax} Minima and maxima of bin the ids
-    std::array< long, 2*dim > extents() const {
-      Assert( !m_pdf.empty(), "PDF empty" );
-      auto x = std::minmax_element( begin(m_pdf), end(m_pdf),
-                 []( const pair_type& a, const pair_type& b )
-                 { return a.first[0] < b.first[0]; } );
-      auto y = std::minmax_element( begin(m_pdf), end(m_pdf),
-                 []( const pair_type& a, const pair_type& b )
-                 { return a.first[1] < b.first[1]; } );
-      auto z = std::minmax_element( begin(m_pdf), end(m_pdf),
-                 []( const pair_type& a, const pair_type& b )
-                 { return a.first[2] < b.first[2]; } );
-      return {{ x.first->first[0], x.second->first[0],
-                y.first->first[1], y.second->first[1],
-                z.first->first[2], z.second->first[2] }};
-    }
-
-    /** @name Pack/Unpack: Serialize BiPDF object for Charm++ */
-    ///@{
-    //! Pack/Unpack serialize member function
-    //! \param[in,out] p Charm++'s PUP::er serializer object reference
-    void pup( PUP::er& p ) {<--- Parameter 'p' can be declared with const
-      p | m_binsize;
-      p | m_nsample;
-      p | m_pdf;
-    }
-    //! \brief Pack/Unpack serialize operator|
-    //! \param[in,out] p Charm++'s PUP::er serializer object reference
-    //! \param[in,out] c TriPDF object reference
-    friend void operator|( PUP::er& p, TriPDF& c ) { c.pup(p); }
-    ///@}
+  // Return size of and raw stream
+  return { sizer.size(), std::move(flatData) };
+}
+
+CkReductionMsg*
+mergeUniPDFs( int nmsg, CkReductionMsg **msgs )
+// *****************************************************************************
+// Charm++ custom reducer for merging a univariate PDFs during reduction across
+// PEs
+//! \param[in] nmsg Number of messages in msgs
+//! \param[in] msgs Charm++ reduction message containing the serialized PDF
+//! \return Aggregated PDF built for further aggregation if needed
+// *****************************************************************************
+{
+  // Will store deserialized univariate PDFs
+  std::size_t meshid;
+  std::vector< tk::UniPDF > updf;
+
+  // Create PUP deserializer based on message passed in
+  PUP::fromMem creator( msgs[0]->getData() );
+
+  // Deserialize PDFs from raw stream
+  creator | meshid;<--- Uninitialized variable: meshid
+  creator | updf;
+
+  for (int m=1; m<nmsg; ++m) {
+    // Unpack PDF
+    std::size_t mid;
+    std::vector< tk::UniPDF > u;
+    PUP::fromMem curCreator( msgs[m]->getData() );
+    curCreator | mid;<--- Uninitialized variable: mid
+    curCreator | u;
+    // Merge PDFs
+    meshid = mid;<--- Assignment 'meshid=mid', assigned value is <--- Assignment 'meshid=mid', assigned value is <--- Uninitialized variable: mid<--- Assignment 'meshid=mid', assigned value is 
+    std::size_t i = 0;
+    for (const auto& p : u) updf[i++].addPDF( p );<--- Access out of bounds<--- Iterating over container 'u' that is always empty.
+  }
+
+  // Serialize vector of merged PDF to raw stream
+  auto stream = tk::serialize( meshid, updf );<--- Calling function 'serialize', 1st argument 'meshid' value is <--- Calling function 'serialize', 1st argument 'meshid' value is <--- Uninitialized variable: meshid
+
+  // Forward serialized PDFs
+  return CkReductionMsg::buildNew( stream.first, stream.second.get() );
+}
+
+std::pair< int, std::unique_ptr<char[]> >
+serialize( const std::vector< tk::UniPDF >& u,
+           const std::vector< tk::BiPDF >& b,
+           const std::vector< tk::TriPDF >& t )
+// *****************************************************************************
+// Serialize vectors of PDFs to raw memory stream
+//! \param[in] u Vector of univariate PDFs
+//! \param[in] b Vector of bivariate PDFs
+//! \param[in] t Vector of trivariate PDFs
+//! \return Pair of the length and the raw stream containing the serialized PDFs
+// *****************************************************************************
+{
+  // Prepare for serializing PDFs to a raw binary stream, compute size
+  PUP::sizer sizer;
+  sizer | const_cast< std::vector< tk::UniPDF >& >( u );
+  sizer | const_cast< std::vector< tk::BiPDF >& >( b );
+  sizer | const_cast< std::vector< tk::TriPDF >& >( t );
+
+  // Create raw character stream to store the serialized PDFs
+  std::unique_ptr<char[]> flatData = std::make_unique<char[]>( sizer.size() );
+
+  // Serialize PDFs, each message will contain a vector of PDFs
+  PUP::toMem packer( flatData.get() );
+  packer | const_cast< std::vector< tk::UniPDF >& >( u );
+  packer | const_cast< std::vector< tk::BiPDF >& >( b );
+  packer | const_cast< std::vector< tk::TriPDF >& >( t );
+
+  // Return size of and raw stream
+  return { sizer.size(), std::move(flatData) };
+}
+
+CkReductionMsg*
+mergePDF( int nmsg, CkReductionMsg **msgs )
+// *****************************************************************************
+// Charm++ custom reducer for merging PDFs during reduction across PEs
+//! \param[in] nmsg Number of messages in msgs
+//! \param[in] msgs Charm++ reduction message containing the serialized PDFs
+//! \return Aggregated PDFs built for further aggregation if needed
+// *****************************************************************************
+{
+  // Will store deserialized uni-, bi-, and tri-variate PDFs
+  std::vector< tk::UniPDF > updf;
+  std::vector< tk::BiPDF > bpdf;
+  std::vector< tk::TriPDF > tpdf;
+
+  // Create PUP deserializer based on message passed in
+  PUP::fromMem creator( msgs[0]->getData() );
 
-  private:
-    std::array< tk::real, dim > m_binsize;   //!< Sample space bin sizes
-    std::size_t m_nsample;                   //!< Number of samples collected
-    map_type m_pdf;                          //!< Probability density function
-};
-
-} // tk::
-
-#endif // TriPDF_h
+  // Deserialize PDFs from raw stream
+  creator | updf;
+  creator | bpdf;
+  creator | tpdf;
+
+  for (int m=1; m<nmsg; ++m) {
+    // Unpack PDFs
+    std::vector< tk::UniPDF > u;
+    std::vector< tk::BiPDF > b;
+    std::vector< tk::TriPDF > t;
+    PUP::fromMem curCreator( msgs[m]->getData() );
+    curCreator | u;
+    curCreator | b;
+    curCreator | t;
+    // Merge PDFs
+    std::size_t i = 0;
+    for (const auto& p : u) updf[i++].addPDF( p );<--- Access out of bounds<--- Iterating over container 'u' that is always empty.
+    i = 0;
+    for (const auto& p : b) bpdf[i++].addPDF( p );<--- Access out of bounds<--- Iterating over container 'b' that is always empty.
+    i = 0;
+    for (const auto& p : t) tpdf[i++].addPDF( p );<--- Access out of bounds<--- Iterating over container 't' that is always empty.
+  }
+
+  // Serialize vector of merged PDFs to raw stream
+  auto stream = tk::serialize( updf, bpdf, tpdf );
+
+  // Forward serialized PDFs
+  return CkReductionMsg::buildNew( stream.first, stream.second.get() );
+}
+
+} // tk::
 
diff --git a/Debug/cppcheck/79.html b/Debug/cppcheck/79.html index 7971ce10fa47..3de84b2ac43f 100644 --- a/Debug/cppcheck/79.html +++ b/Debug/cppcheck/79.html @@ -152,341 +152,125 @@
- - + @@ -93,7 +93,7 @@ - + @@ -141,7 +141,7 @@ - + @@ -153,7 +153,7 @@ - + @@ -277,7 +277,7 @@ - + @@ -321,7 +321,7 @@ - + @@ -345,7 +345,7 @@ - + diff --git a/Debug/test_coverage/Base/Data.hpp.gcov.html b/Debug/test_coverage/Base/Data.hpp.gcov.html index 74970f41ac09..fdc034bea16b 100644 --- a/Debug/test_coverage/Base/Data.hpp.gcov.html +++ b/Debug/test_coverage/Base/Data.hpp.gcov.html @@ -33,7 +33,7 @@ - + @@ -115,7 +115,7 @@ 41 : : 42 : : public: 43 : : //! Default constructor (required for Charm++ migration) - 44 : 101213 : explicit Data() : m_vec(), m_nunk(), m_nprop() {} + 44 : 99896 : explicit Data() : m_vec(), m_nunk(), m_nprop() {} 45 : : 46 : : //! Constructor 47 : : //! \param[in] nu Number of unknowns to allocate memory for @@ -138,8 +138,8 @@ 64 : : //! a system 65 : : //! \return Const reference to data of type tk::real 66 : : const tk::real& - 67 :28894056056 : operator()( ncomp_t unknown, ncomp_t component ) const - 68 :28894056056 : { return access( unknown, component, int2type< Layout >() ); } + 67 :28894047140 : operator()( ncomp_t unknown, ncomp_t component ) const + 68 :28894047140 : { return access( unknown, component, int2type< Layout >() ); } 69 : : 70 : : //! Non-const data access dispatch 71 : : //! \details Public interface to non-const-ref data access to a single real @@ -155,10 +155,10 @@ 81 : : //! \see "Avoid Duplication in const and Non-const Member Function," and 82 : : //! "Use const whenever possible," Scott Meyers, Effective C++, 3d ed. 83 : : tk::real& - 84 :15471086849 : operator()( ncomp_t unknown, ncomp_t component ) { - 85 :15471086849 : return const_cast< tk::real& >( + 84 :15471085578 : operator()( ncomp_t unknown, ncomp_t component ) { + 85 :15471085578 : return const_cast< tk::real& >( 86 : : static_cast< const Data& >( *this ). - 87 :15471086821 : operator()( unknown, component ) ); + 87 :15471085550 : operator()( unknown, component ) ); 88 : : } 89 : : 90 : : //! Const ptr to physical variable access dispatch @@ -568,15 +568,15 @@ 481 : : ///@{ 482 : : //! \brief Pack/Unpack serialize member function 483 : : //! \param[in,out] p Charm++'s PUP::er serializer object reference - 484 : 303168 : void pup( PUP::er &p ) { - 485 : 303168 : p | m_vec; - 486 : 303168 : p | m_nunk; - 487 : 303168 : p | m_nprop; - 488 : 303168 : } + 484 : 299217 : void pup( PUP::er &p ) { + 485 : 299217 : p | m_vec; + 486 : 299217 : p | m_nunk; + 487 : 299217 : p | m_nprop; + 488 : 299217 : } 489 : : //! \brief Pack/Unpack serialize operator| 490 : : //! \param[in,out] p Charm++'s PUP::er serializer object reference 491 : : //! \param[in,out] d DataLyaout object reference - 492 : 303168 : friend void operator|( PUP::er& p, Data& d ) { d.pup(p); } + 492 : 299217 : friend void operator|( PUP::er& p, Data& d ) { d.pup(p); } 493 : : //@} 494 : : 495 : : private: @@ -595,15 +595,15 @@ 508 : : //! \see A. Alexandrescu, Modern C++ Design: Generic Programming and Design 509 : : //! Patterns Applied, Addison-Wesley Professional, 2001. 510 : : const tk::real& - 511 :28894055569 : access( ncomp_t unknown, ncomp_t component, int2type< UnkEqComp > ) const + 511 :28894046653 : access( ncomp_t unknown, ncomp_t component, int2type< UnkEqComp > ) const 512 : : { - 513 [ + + ][ + - ]:28894055569 : Assert( component < m_nprop, "Out-of-bounds access: " + 513 [ + + ][ + - ]:28894046653 : Assert( component < m_nprop, "Out-of-bounds access: " [ + - ][ + - ] 514 : : "component < number of properties" ); - 515 [ + + ][ + - ]:28894055561 : Assert( unknown < m_nunk, "Out-of-bounds access: unknown < number of " + 515 [ + + ][ + - ]:28894046645 : Assert( unknown < m_nunk, "Out-of-bounds access: unknown < number of " [ + - ][ + - ] 516 : : "unknowns" ); - 517 :28894055553 : return m_vec[ unknown*m_nprop + component ]; + 517 :28894046637 : return m_vec[ unknown*m_nprop + component ]; 518 : : } 519 : : const tk::real& 520 : 487 : access( ncomp_t unknown, ncomp_t component, int2type< EqCompUnk > ) const diff --git a/Debug/test_coverage/Base/Escaper.hpp.func-sort-c.html b/Debug/test_coverage/Base/Escaper.hpp.func-sort-c.html index 21fd4344b14f..c5a5e310277d 100644 --- a/Debug/test_coverage/Base/Escaper.hpp.func-sort-c.html +++ b/Debug/test_coverage/Base/Escaper.hpp.func-sort-c.html @@ -33,7 +33,7 @@ - + diff --git a/Debug/test_coverage/Base/Escaper.hpp.func.html b/Debug/test_coverage/Base/Escaper.hpp.func.html index f5856a3231e0..d72a999fb584 100644 --- a/Debug/test_coverage/Base/Escaper.hpp.func.html +++ b/Debug/test_coverage/Base/Escaper.hpp.func.html @@ -33,7 +33,7 @@ - + diff --git a/Debug/test_coverage/Base/Escaper.hpp.gcov.html b/Debug/test_coverage/Base/Escaper.hpp.gcov.html index 4eda6982e9a0..004478ac0fbf 100644 --- a/Debug/test_coverage/Base/Escaper.hpp.gcov.html +++ b/Debug/test_coverage/Base/Escaper.hpp.gcov.html @@ -33,7 +33,7 @@ - + diff --git a/Debug/test_coverage/Base/Exception.cpp.func-sort-c.html b/Debug/test_coverage/Base/Exception.cpp.func-sort-c.html index 00f2d823d824..ee0fd9071b67 100644 --- a/Debug/test_coverage/Base/Exception.cpp.func-sort-c.html +++ b/Debug/test_coverage/Base/Exception.cpp.func-sort-c.html @@ -33,7 +33,7 @@ - + diff --git a/Debug/test_coverage/Base/Exception.cpp.func.html b/Debug/test_coverage/Base/Exception.cpp.func.html index 9e86921404d7..77bf8bd132c7 100644 --- a/Debug/test_coverage/Base/Exception.cpp.func.html +++ b/Debug/test_coverage/Base/Exception.cpp.func.html @@ -33,7 +33,7 @@ - + diff --git a/Debug/test_coverage/Base/Exception.cpp.gcov.html b/Debug/test_coverage/Base/Exception.cpp.gcov.html index c80f0ca981cf..8bed6e8df1fb 100644 --- a/Debug/test_coverage/Base/Exception.cpp.gcov.html +++ b/Debug/test_coverage/Base/Exception.cpp.gcov.html @@ -33,7 +33,7 @@ - + diff --git a/Debug/test_coverage/Base/Exception.hpp.func-sort-c.html b/Debug/test_coverage/Base/Exception.hpp.func-sort-c.html index 4f5e89f06fe4..d31b5ada68ec 100644 --- a/Debug/test_coverage/Base/Exception.hpp.func-sort-c.html +++ b/Debug/test_coverage/Base/Exception.hpp.func-sort-c.html @@ -33,7 +33,7 @@ - + diff --git a/Debug/test_coverage/Base/Exception.hpp.func.html b/Debug/test_coverage/Base/Exception.hpp.func.html index d28eb5a5f542..8323812bd23d 100644 --- a/Debug/test_coverage/Base/Exception.hpp.func.html +++ b/Debug/test_coverage/Base/Exception.hpp.func.html @@ -33,7 +33,7 @@ - + diff --git a/Debug/test_coverage/Base/Exception.hpp.gcov.html b/Debug/test_coverage/Base/Exception.hpp.gcov.html index 03158412e286..a5c59c5ee404 100644 --- a/Debug/test_coverage/Base/Exception.hpp.gcov.html +++ b/Debug/test_coverage/Base/Exception.hpp.gcov.html @@ -33,7 +33,7 @@ - + diff --git a/Debug/test_coverage/Base/Factory.hpp.func-sort-c.html b/Debug/test_coverage/Base/Factory.hpp.func-sort-c.html index 043ef328fdd7..44de637efab9 100644 --- a/Debug/test_coverage/Base/Factory.hpp.func-sort-c.html +++ b/Debug/test_coverage/Base/Factory.hpp.func-sort-c.html @@ -33,7 +33,7 @@ - + diff --git a/Debug/test_coverage/Base/Factory.hpp.func.html b/Debug/test_coverage/Base/Factory.hpp.func.html index 02a231aca84b..065bee956c01 100644 --- a/Debug/test_coverage/Base/Factory.hpp.func.html +++ b/Debug/test_coverage/Base/Factory.hpp.func.html @@ -33,7 +33,7 @@ - + diff --git a/Debug/test_coverage/Base/Factory.hpp.gcov.html b/Debug/test_coverage/Base/Factory.hpp.gcov.html index 6a631148a279..3b2a8e371812 100644 --- a/Debug/test_coverage/Base/Factory.hpp.gcov.html +++ b/Debug/test_coverage/Base/Factory.hpp.gcov.html @@ -33,7 +33,7 @@ - + diff --git a/Debug/test_coverage/Base/Flip_map.hpp.func-sort-c.html b/Debug/test_coverage/Base/Flip_map.hpp.func-sort-c.html index cb3a5503c135..b889cbcb4429 100644 --- a/Debug/test_coverage/Base/Flip_map.hpp.func-sort-c.html +++ b/Debug/test_coverage/Base/Flip_map.hpp.func-sort-c.html @@ -33,7 +33,7 @@ - + diff --git a/Debug/test_coverage/Base/Flip_map.hpp.func.html b/Debug/test_coverage/Base/Flip_map.hpp.func.html index 0862e0541acd..65254b9afcb8 100644 --- a/Debug/test_coverage/Base/Flip_map.hpp.func.html +++ b/Debug/test_coverage/Base/Flip_map.hpp.func.html @@ -33,7 +33,7 @@ - + diff --git a/Debug/test_coverage/Base/Flip_map.hpp.gcov.html b/Debug/test_coverage/Base/Flip_map.hpp.gcov.html index 501d834a15b1..6959fa9ff5d6 100644 --- a/Debug/test_coverage/Base/Flip_map.hpp.gcov.html +++ b/Debug/test_coverage/Base/Flip_map.hpp.gcov.html @@ -33,7 +33,7 @@ - + diff --git a/Debug/test_coverage/Base/HashMapReducer.hpp.func-sort-c.html b/Debug/test_coverage/Base/HashMapReducer.hpp.func-sort-c.html index 1ef8f8afbc7a..f0a8b68ff581 100644 --- a/Debug/test_coverage/Base/HashMapReducer.hpp.func-sort-c.html +++ b/Debug/test_coverage/Base/HashMapReducer.hpp.func-sort-c.html @@ -33,7 +33,7 @@ - + diff --git a/Debug/test_coverage/Base/HashMapReducer.hpp.func.html b/Debug/test_coverage/Base/HashMapReducer.hpp.func.html index 09236b30e21f..fa0b533d6e6a 100644 --- a/Debug/test_coverage/Base/HashMapReducer.hpp.func.html +++ b/Debug/test_coverage/Base/HashMapReducer.hpp.func.html @@ -33,7 +33,7 @@ - + diff --git a/Debug/test_coverage/Base/HashMapReducer.hpp.gcov.html b/Debug/test_coverage/Base/HashMapReducer.hpp.gcov.html index 65a137a53a77..94adbcf034c3 100644 --- a/Debug/test_coverage/Base/HashMapReducer.hpp.gcov.html +++ b/Debug/test_coverage/Base/HashMapReducer.hpp.gcov.html @@ -33,7 +33,7 @@ - + diff --git a/Debug/test_coverage/Base/LoadDistributor.cpp.func-sort-c.html b/Debug/test_coverage/Base/LoadDistributor.cpp.func-sort-c.html index a87925a7974a..862b14459414 100644 --- a/Debug/test_coverage/Base/LoadDistributor.cpp.func-sort-c.html +++ b/Debug/test_coverage/Base/LoadDistributor.cpp.func-sort-c.html @@ -33,7 +33,7 @@ - + diff --git a/Debug/test_coverage/Base/LoadDistributor.cpp.func.html b/Debug/test_coverage/Base/LoadDistributor.cpp.func.html index e6fef8250160..ce71fa9ab247 100644 --- a/Debug/test_coverage/Base/LoadDistributor.cpp.func.html +++ b/Debug/test_coverage/Base/LoadDistributor.cpp.func.html @@ -33,7 +33,7 @@ - + diff --git a/Debug/test_coverage/Base/LoadDistributor.cpp.gcov.html b/Debug/test_coverage/Base/LoadDistributor.cpp.gcov.html index 699046575a90..438130a3af30 100644 --- a/Debug/test_coverage/Base/LoadDistributor.cpp.gcov.html +++ b/Debug/test_coverage/Base/LoadDistributor.cpp.gcov.html @@ -33,7 +33,7 @@ - + diff --git a/Debug/test_coverage/Base/PUPUtil.hpp.func-sort-c.html b/Debug/test_coverage/Base/PUPUtil.hpp.func-sort-c.html index e68fc3fd8e9f..00054c9420e6 100644 --- a/Debug/test_coverage/Base/PUPUtil.hpp.func-sort-c.html +++ b/Debug/test_coverage/Base/PUPUtil.hpp.func-sort-c.html @@ -33,7 +33,7 @@ - + @@ -189,83 +189,83 @@ - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + diff --git a/Debug/test_coverage/Base/PUPUtil.hpp.func.html b/Debug/test_coverage/Base/PUPUtil.hpp.func.html index 46003ad5d05e..e825a31408cd 100644 --- a/Debug/test_coverage/Base/PUPUtil.hpp.func.html +++ b/Debug/test_coverage/Base/PUPUtil.hpp.func.html @@ -33,7 +33,7 @@ - + @@ -73,19 +73,19 @@ - + - + - + - + @@ -97,7 +97,7 @@ - + @@ -193,27 +193,27 @@ - + - + - + - + - + - + @@ -221,7 +221,7 @@ - + @@ -229,7 +229,7 @@ - + @@ -241,27 +241,27 @@ - + - + - + - + - + - + @@ -269,7 +269,7 @@ - + diff --git a/Debug/test_coverage/Base/PUPUtil.hpp.gcov.html b/Debug/test_coverage/Base/PUPUtil.hpp.gcov.html index e6b974acfeaa..8ae34042f48c 100644 --- a/Debug/test_coverage/Base/PUPUtil.hpp.gcov.html +++ b/Debug/test_coverage/Base/PUPUtil.hpp.gcov.html @@ -33,7 +33,7 @@ - + @@ -141,21 +141,21 @@ 67 : : class T, 68 : : class Hash = std::hash< Key >, 69 : : class KeyEqual = std::equal_to< Key > > - 70 : 154986 : inline void pup( PUP::er& p, std::unordered_map< Key, T, Hash, KeyEqual >& m ) { - 71 : 154986 : auto size = PUP_stl_container_size( p, m ); - 72 [ + + ]: 154986 : if (p.isUnpacking()) { - 73 [ + + ]: 1977975 : for (decltype(size) s=0; s<size; ++s) { - 74 : 2304240 : std::pair< Key, T > node; - 75 [ + - ]: 1927571 : p | node; - 76 [ + - ]: 1927571 : m.emplace( node ); + 70 : 153912 : inline void pup( PUP::er& p, std::unordered_map< Key, T, Hash, KeyEqual >& m ) { + 71 : 153912 : auto size = PUP_stl_container_size( p, m ); + 72 [ + + ]: 153912 : if (p.isUnpacking()) { + 73 [ + + ]: 1974951 : for (decltype(size) s=0; s<size; ++s) { + 74 : 2298908 : std::pair< Key, T > node; + 75 [ + - ]: 1924905 : p | node; + 76 [ + - ]: 1924905 : m.emplace( node ); 77 : : } 78 : : } else { - 79 [ + + ]: 4234364 : for (auto& t : m) { - 80 [ + - ]: 5047585 : std::pair< Key, T > node( t ); - 81 [ + - ]: 4129782 : p | node; + 79 [ + + ]: 4228316 : for (auto& t : m) { + 80 [ + - ]: 5036921 : std::pair< Key, T > node( t ); + 81 [ + - ]: 4124450 : p | node; 82 : : } 83 : : } - 84 : 154986 : } + 84 : 153912 : } 85 : : //! Pack/Unpack std::unordered_map. 86 : : //! \param[in] p Charm++'s pack/unpack object 87 : : //! \param[in] m std::unordered_map< Key, T, Hash, KeyEqual > to pack/unpack @@ -163,9 +163,9 @@ 89 : : class T, 90 : : class Hash = std::hash< Key >, 91 : : class KeyEqual = std::equal_to< Key > > - 92 : 154986 : inline void operator|( PUP::er& p, + 92 : 153912 : inline void operator|( PUP::er& p, 93 : : std::unordered_map< Key, T, Hash, KeyEqual >& m ) - 94 : 154986 : { pup( p, m ); } + 94 : 153912 : { pup( p, m ); } 95 : : 96 : : //////////////////// Serialize std::unordered_set //////////////////// 97 : : @@ -175,30 +175,30 @@ 101 : : template< class Key, 102 : : class Hash = std::hash< Key >, 103 : : class KeyEqual = std::equal_to< Key > > - 104 : 849873 : inline void pup( PUP::er& p, std::unordered_set< Key, Hash, KeyEqual >& s ) { - 105 : 849873 : auto size = PUP_stl_container_size( p, s ); - 106 [ + + ]: 849873 : if (p.isUnpacking()) { - 107 [ + + ]: 3555087 : for (decltype(size) i=0; i<size; ++i) { + 104 : 844911 : inline void pup( PUP::er& p, std::unordered_set< Key, Hash, KeyEqual >& s ) { + 105 : 844911 : auto size = PUP_stl_container_size( p, s ); + 106 [ + + ]: 844911 : if (p.isUnpacking()) { + 107 [ + + ]: 3508563 : for (decltype(size) i=0; i<size; ++i) { 108 : : Key node; - 109 [ + - ]: 3277501 : p | node; - 110 [ + - ]: 3277501 : s.emplace( node ); + 109 [ + - ]: 3232631 : p | node; + 110 [ + - ]: 3232631 : s.emplace( node ); 111 : : } 112 : : } else { - 113 [ + + ]: 8292333 : for (auto& t : s) { - 114 : 7720046 : Key node( t ); - 115 [ + - ]: 7720046 : p | node; + 113 [ + + ]: 8199285 : for (auto& t : s) { + 114 : 7630306 : Key node( t ); + 115 [ + - ]: 7630306 : p | node; 116 : : } 117 : : } - 118 : 849873 : } + 118 : 844911 : } 119 : : //! Pack/Unpack std::unordered_set. 120 : : //! \param[in] p Charm++'s pack/unpack object 121 : : //! \param[in] s std::unordered_set< Key, Hash, KeyEqual > to pack/unpack 122 : : template< class Key, 123 : : class Hash = std::hash< Key >, 124 : : class KeyEqual = std::equal_to< Key > > - 125 : 849873 : inline void operator|( PUP::er& p, + 125 : 844911 : inline void operator|( PUP::er& p, 126 : : std::unordered_set< Key, Hash, KeyEqual >& s ) - 127 : 849873 : { pup( p, s ); } + 127 : 844911 : { pup( p, s ); } 128 : : 129 : : //////////////////// Serialize std::optional //////////////////// 130 : : @@ -242,44 +242,44 @@ 168 : : //! \param[in] p Charm++'s pack/unpack object 169 : : //! \param[in] var std::variant< Ts... > of arbitrary types to pack/unpack 170 : : template <class T, class... Ts> - 171 : 249184 : char pup_helper( std::size_t& index, + 171 : 247096 : char pup_helper( std::size_t& index, 172 : : const std::size_t send_index, 173 : : PUP::er& p, 174 : : std::variant<Ts...>& var ) 175 : : { - 176 [ + + ]: 249184 : if (index == send_index) { - 177 [ + + ]: 62299 : if (p.isUnpacking()) { - 178 : 40676 : T t{}; - 179 [ + - ]: 20339 : p | t; - 180 [ + - ]: 20339 : var = std::move(t); + 176 [ + + ]: 247096 : if (index == send_index) { + 177 [ + + ]: 61777 : if (p.isUnpacking()) { + 178 : 40328 : T t{}; + 179 [ + - ]: 20165 : p | t; + 180 [ + - ]: 20165 : var = std::move(t); 181 : : } else { - 182 : 41960 : p | std::get<T>(var); + 182 : 41612 : p | std::get<T>(var); 183 : : } 184 : : } - 185 : 249184 : index++; - 186 : 249184 : return '0'; + 185 : 247096 : index++; + 186 : 247096 : return '0'; 187 : : } 188 : : 189 : : //! Pack/Unpack std::variant 190 : : //! \param[in] p Charm++'s pack/unpack object 191 : : //! \param[in] var std::variant< Ts... > of arbitrary types to pack/unpack 192 : : template <class... Ts> - 193 : 62299 : void pup(PUP::er& p, std::variant<Ts...>& var) { - 194 : 62299 : std::size_t index = 0; - 195 : 62299 : auto send_index = var.index(); - 196 [ + - ]: 62299 : p | send_index; - 197 : 249184 : (void)std::initializer_list<char>{ - 198 [ + - ][ + - ]: 62299 : pup_helper<Ts>(index, send_index, p, var)...}; - [ + - ][ + - ] - 199 : 62299 : } + 193 : 61777 : void pup(PUP::er& p, std::variant<Ts...>& var) { + 194 : 61777 : std::size_t index = 0; + 195 : 61777 : auto send_index = var.index(); + 196 [ + - ]: 61777 : p | send_index; + 197 : 247096 : (void)std::initializer_list<char>{ + 198 [ + - ][ + - ]: 61777 : pup_helper<Ts>(index, send_index, p, var)...}; + [ + - ][ + - ] + 199 : 61777 : } 200 : : 201 : : //! Pack/Unpack std::variant 202 : : //! \param[in] p Charm++'s pack/unpack object 203 : : //! \param[in] d std::variant< Ts... > of arbitrary types to pack/unpack 204 : : template <typename... Ts> - 205 : 62299 : inline void operator|(PUP::er& p, std::variant<Ts...>& d) { - 206 : 62299 : pup(p, d); - 207 : 62299 : } + 205 : 61777 : inline void operator|(PUP::er& p, std::variant<Ts...>& d) { + 206 : 61777 : pup(p, d); + 207 : 61777 : } 208 : : 209 : : } // PUP:: 210 : : diff --git a/Debug/test_coverage/Base/Print.hpp.func-sort-c.html b/Debug/test_coverage/Base/Print.hpp.func-sort-c.html index 70acae1e2523..9021c85766e1 100644 --- a/Debug/test_coverage/Base/Print.hpp.func-sort-c.html +++ b/Debug/test_coverage/Base/Print.hpp.func-sort-c.html @@ -33,7 +33,7 @@ - + diff --git a/Debug/test_coverage/Base/Print.hpp.func.html b/Debug/test_coverage/Base/Print.hpp.func.html index dc538c40efaf..90ed1b63c972 100644 --- a/Debug/test_coverage/Base/Print.hpp.func.html +++ b/Debug/test_coverage/Base/Print.hpp.func.html @@ -33,7 +33,7 @@ - + diff --git a/Debug/test_coverage/Base/Print.hpp.gcov.html b/Debug/test_coverage/Base/Print.hpp.gcov.html index 001149ff7ca2..82edfad86b1c 100644 --- a/Debug/test_coverage/Base/Print.hpp.gcov.html +++ b/Debug/test_coverage/Base/Print.hpp.gcov.html @@ -33,7 +33,7 @@ - + diff --git a/Debug/test_coverage/Base/PrintUtil.cpp.func-sort-c.html b/Debug/test_coverage/Base/PrintUtil.cpp.func-sort-c.html index e1b2c152e985..0319d9e0d601 100644 --- a/Debug/test_coverage/Base/PrintUtil.cpp.func-sort-c.html +++ b/Debug/test_coverage/Base/PrintUtil.cpp.func-sort-c.html @@ -33,7 +33,7 @@ - + diff --git a/Debug/test_coverage/Base/PrintUtil.cpp.func.html b/Debug/test_coverage/Base/PrintUtil.cpp.func.html index 7560a06f7f83..a5b1db19dbe1 100644 --- a/Debug/test_coverage/Base/PrintUtil.cpp.func.html +++ b/Debug/test_coverage/Base/PrintUtil.cpp.func.html @@ -33,7 +33,7 @@ - + diff --git a/Debug/test_coverage/Base/PrintUtil.cpp.gcov.html b/Debug/test_coverage/Base/PrintUtil.cpp.gcov.html index 84ba790b7510..ced8970ec071 100644 --- a/Debug/test_coverage/Base/PrintUtil.cpp.gcov.html +++ b/Debug/test_coverage/Base/PrintUtil.cpp.gcov.html @@ -33,7 +33,7 @@ - + diff --git a/Debug/test_coverage/Base/PrintUtil.hpp.func-sort-c.html b/Debug/test_coverage/Base/PrintUtil.hpp.func-sort-c.html index f0641fe46b65..51f95d0b73c1 100644 --- a/Debug/test_coverage/Base/PrintUtil.hpp.func-sort-c.html +++ b/Debug/test_coverage/Base/PrintUtil.hpp.func-sort-c.html @@ -33,7 +33,7 @@ - + diff --git a/Debug/test_coverage/Base/PrintUtil.hpp.func.html b/Debug/test_coverage/Base/PrintUtil.hpp.func.html index ec0d14bf38ea..18c077789003 100644 --- a/Debug/test_coverage/Base/PrintUtil.hpp.func.html +++ b/Debug/test_coverage/Base/PrintUtil.hpp.func.html @@ -33,7 +33,7 @@ - + diff --git a/Debug/test_coverage/Base/PrintUtil.hpp.gcov.html b/Debug/test_coverage/Base/PrintUtil.hpp.gcov.html index b4f1ab5b4d73..1f39ba83edc4 100644 --- a/Debug/test_coverage/Base/PrintUtil.hpp.gcov.html +++ b/Debug/test_coverage/Base/PrintUtil.hpp.gcov.html @@ -33,7 +33,7 @@ - + diff --git a/Debug/test_coverage/Base/ProcessException.cpp.func-sort-c.html b/Debug/test_coverage/Base/ProcessException.cpp.func-sort-c.html index 433c6cfc6079..27bf3736028d 100644 --- a/Debug/test_coverage/Base/ProcessException.cpp.func-sort-c.html +++ b/Debug/test_coverage/Base/ProcessException.cpp.func-sort-c.html @@ -33,7 +33,7 @@ - + diff --git a/Debug/test_coverage/Base/ProcessException.cpp.func.html b/Debug/test_coverage/Base/ProcessException.cpp.func.html index dd305428771f..921ef05e3216 100644 --- a/Debug/test_coverage/Base/ProcessException.cpp.func.html +++ b/Debug/test_coverage/Base/ProcessException.cpp.func.html @@ -33,7 +33,7 @@ - + diff --git a/Debug/test_coverage/Base/ProcessException.cpp.gcov.html b/Debug/test_coverage/Base/ProcessException.cpp.gcov.html index 1f4e4a3197de..65189a0e6aed 100644 --- a/Debug/test_coverage/Base/ProcessException.cpp.gcov.html +++ b/Debug/test_coverage/Base/ProcessException.cpp.gcov.html @@ -33,7 +33,7 @@ - + diff --git a/Debug/test_coverage/Base/Progress.hpp.func-sort-c.html b/Debug/test_coverage/Base/Progress.hpp.func-sort-c.html index b27c181b2bac..a9f0ba086cd4 100644 --- a/Debug/test_coverage/Base/Progress.hpp.func-sort-c.html +++ b/Debug/test_coverage/Base/Progress.hpp.func-sort-c.html @@ -33,7 +33,7 @@ - + diff --git a/Debug/test_coverage/Base/Progress.hpp.func.html b/Debug/test_coverage/Base/Progress.hpp.func.html index de23cce352c9..bb0b8fa1eef7 100644 --- a/Debug/test_coverage/Base/Progress.hpp.func.html +++ b/Debug/test_coverage/Base/Progress.hpp.func.html @@ -33,7 +33,7 @@ - + diff --git a/Debug/test_coverage/Base/Progress.hpp.gcov.html b/Debug/test_coverage/Base/Progress.hpp.gcov.html index 66c687a6cc99..344a9491fdab 100644 --- a/Debug/test_coverage/Base/Progress.hpp.gcov.html +++ b/Debug/test_coverage/Base/Progress.hpp.gcov.html @@ -33,7 +33,7 @@ - + diff --git a/Debug/test_coverage/Base/Reader.cpp.func-sort-c.html b/Debug/test_coverage/Base/Reader.cpp.func-sort-c.html index c788f4b17344..cdbd3e607650 100644 --- a/Debug/test_coverage/Base/Reader.cpp.func-sort-c.html +++ b/Debug/test_coverage/Base/Reader.cpp.func-sort-c.html @@ -33,7 +33,7 @@ - + diff --git a/Debug/test_coverage/Base/Reader.cpp.func.html b/Debug/test_coverage/Base/Reader.cpp.func.html index 6bdea270b5cd..1067ddb41a36 100644 --- a/Debug/test_coverage/Base/Reader.cpp.func.html +++ b/Debug/test_coverage/Base/Reader.cpp.func.html @@ -33,7 +33,7 @@ - + diff --git a/Debug/test_coverage/Base/Reader.cpp.gcov.html b/Debug/test_coverage/Base/Reader.cpp.gcov.html index 061b184a757a..4c3f734e0592 100644 --- a/Debug/test_coverage/Base/Reader.cpp.gcov.html +++ b/Debug/test_coverage/Base/Reader.cpp.gcov.html @@ -33,7 +33,7 @@ - + diff --git a/Debug/test_coverage/Base/Table.hpp.func-sort-c.html b/Debug/test_coverage/Base/Table.hpp.func-sort-c.html index 1bfb5008c435..19e952e93094 100644 --- a/Debug/test_coverage/Base/Table.hpp.func-sort-c.html +++ b/Debug/test_coverage/Base/Table.hpp.func-sort-c.html @@ -33,7 +33,7 @@ - + diff --git a/Debug/test_coverage/Base/Table.hpp.func.html b/Debug/test_coverage/Base/Table.hpp.func.html index 0607993b2514..778033f58faf 100644 --- a/Debug/test_coverage/Base/Table.hpp.func.html +++ b/Debug/test_coverage/Base/Table.hpp.func.html @@ -33,7 +33,7 @@ - + diff --git a/Debug/test_coverage/Base/Table.hpp.gcov.html b/Debug/test_coverage/Base/Table.hpp.gcov.html index ec839f8a6f12..2d5221181b95 100644 --- a/Debug/test_coverage/Base/Table.hpp.gcov.html +++ b/Debug/test_coverage/Base/Table.hpp.gcov.html @@ -33,7 +33,7 @@ - + diff --git a/Debug/test_coverage/Base/TaggedTuple.hpp.func-sort-c.html b/Debug/test_coverage/Base/TaggedTuple.hpp.func-sort-c.html index 8b97f2dc0453..6fa61903cf5a 100644 --- a/Debug/test_coverage/Base/TaggedTuple.hpp.func-sort-c.html +++ b/Debug/test_coverage/Base/TaggedTuple.hpp.func-sort-c.html @@ -33,7 +33,7 @@ - + @@ -728,12 +728,12 @@ - + - - + + @@ -875,14 +875,6 @@ - - - - - - - - @@ -919,6 +911,14 @@ + + + + + + + + @@ -2972,12 +2972,12 @@ - - + + - - + + @@ -3021,7 +3021,7 @@ - + @@ -3039,17 +3039,17 @@ - - - - - + - + + + + + @@ -3177,11 +3177,11 @@ - + - + @@ -3513,11 +3513,11 @@ - + - +
  1
-  2
-  3
-  4
-  5
-  6
-  7
-  8
-  9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
- 37
- 38
- 39
- 40
- 41
- 42
- 43
- 44
- 45
- 46
- 47
- 48
- 49
- 50
- 51
- 52
- 53
- 54
- 55
- 56
- 57
- 58
- 59
- 60
- 61
- 62
- 63
- 64
- 65
- 66
- 67
- 68
- 69
- 70
- 71
- 72
- 73
- 74
- 75
- 76
- 77
- 78
- 79
- 80
- 81
- 82
- 83
- 84
- 85
- 86
- 87
- 88
- 89
- 90
- 91
- 92
- 93
- 94
- 95
- 96
- 97
- 98
- 99
-100
-101
-102
-103
-104
-105
-106
-107
-108
-109
-110
-111
-112
-113
-114
-115
-116
-117
-118
-119
-120
-121
-122
-123
-124
-125
-126
-127
-128
-129
-130
-131
-132
-133
-134
-135
-136
-137
-138
-139
-140
-141
-142
-143
-144
-145
-146
-147
-148
-149
-150
-151
-152
-153
-154
-155
-156
-157
-158
-159
-160
-161
-162
-163
-164
// *****************************************************************************
-/*!
-  \file      src/Statistics/PDFReducer.cpp
-  \copyright 2012-2015 J. Bakosi,
-             2016-2018 Los Alamos National Security, LLC.,
-             2019-2021 Triad National Security, LLC.
-             All rights reserved. See the LICENSE file for details.
-  \brief     Custom Charm++ reducer for merging PDFs across PEs
-  \details   Custom Charm++ reducer for merging PDFs across PEs.
-*/
-// *****************************************************************************
-
-#include <memory>
-
-#include "PDFReducer.hpp"
-
-namespace tk {
+
 1
+ 2
+ 3
+ 4
+ 5
+ 6
+ 7
+ 8
+ 9
+10
+11
+12
+13
+14
+15
+16
+17
+18
+19
+20
+21
+22
+23
+24
+25
+26
+27
+28
+29
+30
+31
+32
+33
+34
+35
+36
+37
+38
+39
+40
+41
+42
+43
+44
+45
+46
+47
+48
+49
+50
+51
+52
+53
+54
+55
+56
// Controller for the library
+
+#include "NoWarning/m2mtransfer.decl.h"
+
+#include "collidecharm.h"
+#include "Fields.hpp"
+
+namespace exam2m {
+
+void addMesh(CkArrayID p, int elem, CkCallback cb);
+void setSourceTets(CkArrayID p, int index, std::vector< std::size_t >* inpoel, tk::UnsMesh::Coords* coords, const tk::Fields& u);
+void setDestPoints(CkArrayID p, int index, tk::UnsMesh::Coords* coords, tk::Fields& u, CkCallback cb);
+
+class LibMain : public CBase_LibMain {
+public:
+  LibMain(CkArgMsg* msg);
+};
 
-std::pair< int, std::unique_ptr<char[]> >
-serialize( std::size_t meshid, const std::vector< tk::UniPDF >& u )
-// *****************************************************************************
-// Serialize univariate PDFs to raw memory stream
-//! \param[in] meshid Mesh ID
-//! \param[in] u Univariate PDFs
-//! \return Pair of the length and the raw stream containing the serialized PDFs
-// *****************************************************************************
-{
-  // Prepare for serializing PDF to a raw binary stream, compute size
-  PUP::sizer sizer;
-  sizer | meshid;<--- Uninitialized variable: meshid
-  sizer | const_cast< std::vector< tk::UniPDF >& >( u );
-
-  // Create raw character stream to store the serialized PDF
-  std::unique_ptr<char[]> flatData = std::make_unique<char[]>( sizer.size() );
-
-  // Serialize PDF, the message will contain a univariate PDF
-  PUP::toMem packer( flatData.get() );
-  packer | meshid;<--- Uninitialized variable: meshid
-  packer | const_cast< std::vector< tk::UniPDF >& >( u );
-
-  // Return size of and raw stream
-  return { sizer.size(), std::move(flatData) };
-}
-
-CkReductionMsg*
-mergeUniPDFs( int nmsg, CkReductionMsg **msgs )
-// *****************************************************************************
-// Charm++ custom reducer for merging a univariate PDFs during reduction across
-// PEs
-//! \param[in] nmsg Number of messages in msgs
-//! \param[in] msgs Charm++ reduction message containing the serialized PDF
-//! \return Aggregated PDF built for further aggregation if needed
-// *****************************************************************************
-{
-  // Will store deserialized univariate PDFs
-  std::size_t meshid;
-  std::vector< tk::UniPDF > updf;
-
-  // Create PUP deserializer based on message passed in
-  PUP::fromMem creator( msgs[0]->getData() );
-
-  // Deserialize PDFs from raw stream
-  creator | meshid;<--- Uninitialized variable: meshid
-  creator | updf;
-
-  for (int m=1; m<nmsg; ++m) {
-    // Unpack PDF
-    std::size_t mid;
-    std::vector< tk::UniPDF > u;
-    PUP::fromMem curCreator( msgs[m]->getData() );
-    curCreator | mid;<--- Uninitialized variable: mid
-    curCreator | u;
-    // Merge PDFs
-    meshid = mid;<--- Assignment 'meshid=mid', assigned value is <--- Assignment 'meshid=mid', assigned value is <--- Uninitialized variable: mid<--- Assignment 'meshid=mid', assigned value is 
-    std::size_t i = 0;
-    for (const auto& p : u) updf[i++].addPDF( p );<--- Access out of bounds<--- Iterating over container 'u' that is always empty.
-  }
-
-  // Serialize vector of merged PDF to raw stream
-  auto stream = tk::serialize( meshid, updf );<--- Calling function 'serialize', 1st argument 'meshid' value is <--- Calling function 'serialize', 1st argument 'meshid' value is <--- Uninitialized variable: meshid
-
-  // Forward serialized PDFs
-  return CkReductionMsg::buildNew( stream.first, stream.second.get() );
-}
-
-std::pair< int, std::unique_ptr<char[]> >
-serialize( const std::vector< tk::UniPDF >& u,
-           const std::vector< tk::BiPDF >& b,
-           const std::vector< tk::TriPDF >& t )
-// *****************************************************************************
-// Serialize vectors of PDFs to raw memory stream
-//! \param[in] u Vector of univariate PDFs
-//! \param[in] b Vector of bivariate PDFs
-//! \param[in] t Vector of trivariate PDFs
-//! \return Pair of the length and the raw stream containing the serialized PDFs
-// *****************************************************************************
-{
-  // Prepare for serializing PDFs to a raw binary stream, compute size
-  PUP::sizer sizer;
-  sizer | const_cast< std::vector< tk::UniPDF >& >( u );
-  sizer | const_cast< std::vector< tk::BiPDF >& >( b );
-  sizer | const_cast< std::vector< tk::TriPDF >& >( t );
-
-  // Create raw character stream to store the serialized PDFs
-  std::unique_ptr<char[]> flatData = std::make_unique<char[]>( sizer.size() );
-
-  // Serialize PDFs, each message will contain a vector of PDFs
-  PUP::toMem packer( flatData.get() );
-  packer | const_cast< std::vector< tk::UniPDF >& >( u );
-  packer | const_cast< std::vector< tk::BiPDF >& >( b );
-  packer | const_cast< std::vector< tk::TriPDF >& >( t );
-
-  // Return size of and raw stream
-  return { sizer.size(), std::move(flatData) };
-}
-
-CkReductionMsg*
-mergePDF( int nmsg, CkReductionMsg **msgs )
-// *****************************************************************************
-// Charm++ custom reducer for merging PDFs during reduction across PEs
-//! \param[in] nmsg Number of messages in msgs
-//! \param[in] msgs Charm++ reduction message containing the serialized PDFs
-//! \return Aggregated PDFs built for further aggregation if needed
-// *****************************************************************************
-{
-  // Will store deserialized uni-, bi-, and tri-variate PDFs
-  std::vector< tk::UniPDF > updf;
-  std::vector< tk::BiPDF > bpdf;
-  std::vector< tk::TriPDF > tpdf;
-
-  // Create PUP deserializer based on message passed in
-  PUP::fromMem creator( msgs[0]->getData() );
-
-  // Deserialize PDFs from raw stream
-  creator | updf;
-  creator | bpdf;
-  creator | tpdf;
-
-  for (int m=1; m<nmsg; ++m) {
-    // Unpack PDFs
-    std::vector< tk::UniPDF > u;
-    std::vector< tk::BiPDF > b;
-    std::vector< tk::TriPDF > t;
-    PUP::fromMem curCreator( msgs[m]->getData() );
-    curCreator | u;
-    curCreator | b;
-    curCreator | t;
-    // Merge PDFs
-    std::size_t i = 0;
-    for (const auto& p : u) updf[i++].addPDF( p );<--- Access out of bounds<--- Iterating over container 'u' that is always empty.
-    i = 0;
-    for (const auto& p : b) bpdf[i++].addPDF( p );<--- Access out of bounds<--- Iterating over container 'b' that is always empty.
-    i = 0;
-    for (const auto& p : t) tpdf[i++].addPDF( p );<--- Access out of bounds<--- Iterating over container 't' that is always empty.
-  }
-
-  // Serialize vector of merged PDFs to raw stream
-  auto stream = tk::serialize( updf, bpdf, tpdf );
-
-  // Forward serialized PDFs
-  return CkReductionMsg::buildNew( stream.first, stream.second.get() );
-}
-
-} // tk::
+class MeshData {
+  public:
+    CProxy_TransferDetails m_proxy;
+    int m_firstchunk;
+    int m_nchare;
+    void pup(PUP::er& p) {<--- Parameter 'p' can be declared with const
+      p | m_proxy;
+      p | m_firstchunk;
+      p | m_nchare;
+    }
+};
+
+class M2MTransfer : public CBase_M2MTransfer {
+  private:
+    std::unordered_map<CmiUInt8, MeshData> proxyMap;
+    int current_chunk;
+    CmiUInt8 m_sourcemesh, m_destmesh;
+
+  public:
+    M2MTransfer();
+    #if defined(__clang__)
+      #pragma clang diagnostic push
+      #pragma clang diagnostic ignored "-Wundefined-func-template"
+    #endif
+    explicit M2MTransfer( CkMigrateMessage* m ) : CBase_M2MTransfer( m ) {}<--- Member variable 'M2MTransfer::current_chunk' is not initialized in the constructor.
+    #if defined(__clang__)
+      #pragma clang diagnostic pop
+    #endif
+    void addMesh(CkArrayID p, int elem, CkCallback cb);
+    void setMesh(CkArrayID p, MeshData d);
+    void setSourceTets(CkArrayID p, int index, std::vector< std::size_t >* inpoel,
+                       tk::UnsMesh::Coords* coords, const tk::Fields& u);
+    void setDestPoints(CkArrayID p, int index, tk::UnsMesh::Coords* coords,
+                       tk::Fields& u, CkCallback cb);
+    void distributeCollisions(int nColl, Collision* colls);
+};
+
+}
 
diff --git a/Debug/cppcheck/8.html b/Debug/cppcheck/8.html index 26855bc0fc7f..e9239cc1bc5f 100644 --- a/Debug/cppcheck/8.html +++ b/Debug/cppcheck/8.html @@ -152,12 +152,12 @@
  1
@@ -357,1120 +357,204 @@ 

Cppcheck report - [

// *****************************************************************************
+198
// *****************************************************************************
 /*!
-  \file      src/Base/Vector.hpp
+  \file      src/Base/TaggedTuple.hpp
   \copyright 2012-2015 J. Bakosi,
              2016-2018 Los Alamos National Security, LLC.,
              2019-2021 Triad National Security, LLC.
              All rights reserved. See the LICENSE file for details.
-  \brief     Vector algebra
-  \details   Vector algebra.
-*/
-// *****************************************************************************
-#ifndef Vector_h
-#define Vector_h
-
-#include <array>
-#include <cmath>
-#include <vector>
-#include <cblas.h>
-
-#include "Types.hpp"
-#include "Exception.hpp"
-
-// ignore old-style-casts required for lapack/blas calls
-#if defined(__clang__)
-  #pragma clang diagnostic ignored "-Wold-style-cast"
-#endif
-
-// Lapacke forward declarations
-extern "C" {
+  \brief     Tagged tuple allowing tag-based access
+  \details   Tagged tuple allowing tag-based access. This is very much like
+    [std::tuple](http://en.cppreference.com/w/cpp/utility/tuple), but instead of
+    having to index the elements by integers, it allows access by a tag, which
+    can be an empty struct with a unique name. Credit goes to
+    ecatmur_at_stackoverflow.com, for more details, see
+    http://stackoverflow.com/questions/13065166/c11-tagged-tuple. For tags, see
+    Control/Tags.h. Tagged tuples are extensively used for transferring data
+    from the parser to an internal data structure in a type-save manner, which
+    is a tagged tuple containing a hierarchy of various containers. As an
+    example on how tagged tuples are used for parsing an input file, see
+    Control/Inciter/InputDeck/InputDeck.h. Another way to use a tagged tuple is
+    a compile-time associated container between tags and an arbitrary type.
+*/
+// *****************************************************************************
+#ifndef TaggedTuple_h
+#define TaggedTuple_h
+
+#include <type_traits>
+#include <tuple>
+
+#include <brigand/adapted/tuple.hpp>
 
-using lapack_int = long;
-
-#define LAPACK_ROW_MAJOR 101
-#define LAPACK_COL_MAJOR 102
-
-extern lapack_int LAPACKE_dgetrf( int, lapack_int, lapack_int, double*,
-  lapack_int, lapack_int* );
-extern lapack_int LAPACKE_dgetri( int, lapack_int, double*, lapack_int,
-  const lapack_int* );
-
-}
+#include "NoWarning/any.hpp"
+#include "NoWarning/partition.hpp"
+#include "NoWarning/index_of.hpp"
+
+#include "PUPUtil.hpp"
+#include "Exception.hpp"
+
+namespace tag {
+//! Printable tag for TaggedTuple that returns its name
+#define DEFTAG(n) struct n { static const char* name() { return #n; } }
+} // tag::
 
 namespace tk {
 
-//! Flip sign of vector components
-//! \param[in] v Vector whose components to multiply by -1.0
-inline void
-flip( std::array< real, 3 >& v )
-{
-  v[0] = -v[0];
-  v[1] = -v[1];
-  v[2] = -v[2];
-}
-
-//! Compute the cross-product of two vectors
-//! \param[in] v1x x coordinate of the 1st vector
-//! \param[in] v1y y coordinate of the 1st vector
-//! \param[in] v1z z coordinate of the 1st vector
-//! \param[in] v2x x coordinate of the 2nd vector
-//! \param[in] v2y y coordinate of the 2nd vector
-//! \param[in] v2z z coordinate of the 2nd vector
-//! \param[out] rx x coordinate of the product vector
-//! \param[out] ry y coordinate of the product vector
-//! \param[out] rz z coordinate of the product vector
-#pragma omp declare simd
-inline void
-cross( real v1x, real v1y, real v1z,
-       real v2x, real v2y, real v2z,
-       real& rx, real& ry, real& rz )
-{
-  rx = v1y*v2z - v2y*v1z;
-  ry = v1z*v2x - v2z*v1x;
-  rz = v1x*v2y - v2x*v1y;
-}
-
-//! Compute the cross-product of two vectors
-//! \param[in] v1 1st vector
-//! \param[in] v2 2nd vector
-//! \return Cross-product
-inline std::array< real, 3 >
-cross( const std::array< real, 3 >& v1, const std::array< real, 3 >& v2 )
-{
-  real rx, ry, rz;
-  cross( v1[0], v1[1], v1[2], v2[0], v2[1], v2[2], rx, ry, rz );
-  return { std::move(rx), std::move(ry), std::move(rz) };
-}
-
-//! Compute the cross-product of two vectors divided by a scalar
-//! \param[in] v1x x coordinate of the 1st vector
-//! \param[in] v1y y coordinate of the 1st vector
-//! \param[in] v1z z coordinate of the 1st vector
-//! \param[in] v2x x coordinate of the 2nd vector
-//! \param[in] v2y y coordinate of the 2nd vector
-//! \param[in] v2z z coordinate of the 2nd vector
-//! \param[in] j The scalar to divide the product with
-//! \param[out] rx x coordinate of the product vector
-//! \param[out] ry y coordinate of the product vector
-//! \param[out] rz z coordinate of the product vector
-#pragma omp declare simd uniform(j)
-inline void
-crossdiv( real v1x, real v1y, real v1z,
-          real v2x, real v2y, real v2z,
-          real j,
-          real& rx, real& ry, real& rz )
-{
-  cross( v1x, v1y, v1z, v2x, v2y, v2z, rx, ry, rz );
-  rx /= j;
-  ry /= j;
-  rz /= j;
-}
-
-//! Compute the cross-product of two vectors divided by a scalar
-//! \param[in] v1 1st vector
-//! \param[in] v2 2nd vector
-//! \param[in] j Scalar to divide each component by
-//! \return Cross-product divided by scalar
-inline std::array< real, 3 >
-crossdiv( const std::array< real, 3 >& v1,
-          const std::array< real, 3 >& v2,
-          real j )
-{
-  return {{ (v1[1]*v2[2] - v2[1]*v1[2]) / j,
-            (v1[2]*v2[0] - v2[2]*v1[0]) / j,
-            (v1[0]*v2[1] - v2[0]*v1[1]) / j }};
-}
-
-//! Compute the dot-product of two vectors
-//! \param[in] v1 1st vector
-//! \param[in] v2 2nd vector
-//! \return Dot-product
-inline real
-dot( const std::array< real, 3 >& v1, const std::array< real, 3 >& v2 )
-{
-  return v1[0]*v2[0] + v1[1]*v2[1] + v1[2]*v2[2];
-}
-
-//! Compute the dot-product of a matrix and a vector
-//! \param[in] m Matrix
-//! \param[in] v vector
-//! \return Dot-product
-inline std::array< real, 3 >
-matvec(
-  const std::array< std::array< real, 3 >, 3 >& m,
-  const std::array< real, 3 >& v )
-{
-  std::array< real, 3 > mv{0, 0, 0};
-  for (std::size_t i=0; i<3; ++i) {
-    for (std::size_t j=0; j<3; ++j)
-      mv[i] += m[i][j]*v[j];
-  }
-
-  return mv;
-}
-
-//! Compute length of a vector
-//! \param[in] x X coordinate of vector
-//! \param[in] y Y coordinate of vector
-//! \param[in] z Z coordinate of vector
-//! \return length
-#pragma omp declare simd
-inline real
-length( real x, real y, real z )
-{
-  return std::sqrt( x*x + y*y + z*z );
-}
-
-//! Compute length of a vector
-//! \param[in] v vector
-//! \return length
-inline real
-length( const std::array< real, 3 >& v )
-{
-  return std::sqrt( dot(v,v) );
-}
-
-//! Scale vector to unit length
-//! \param[in,out] v Vector to normalize
-inline void
-unit( std::array< real, 3 >& v ) noexcept(ndebug)
-{
-  auto len = length( v );
-  Assert( len > std::numeric_limits< tk::real >::epsilon(), "div by zero" );<--- Exception thrown in function declared not to throw exceptions.
-  v[0] /= len;
-  v[1] /= len;
-  v[2] /= len;
-}
-
-//! Compute the triple-product of three vectors
-//! \param[in] v1x x coordinate of the 1st vector
-//! \param[in] v1y y coordinate of the 1st vector
-//! \param[in] v1z z coordinate of the 1st vector
-//! \param[in] v2x x coordinate of the 2nd vector
-//! \param[in] v2y y coordinate of the 2nd vector
-//! \param[in] v2z z coordinate of the 2nd vector
-//! \param[in] v3x x coordinate of the 3rd vector
-//! \param[in] v3y y coordinate of the 3rd vector
-//! \param[in] v3z z coordinate of the 3rd vector
-//! \return Scalar value of the triple product
-#pragma omp declare simd
-inline tk::real
-triple( real v1x, real v1y, real v1z,
-        real v2x, real v2y, real v2z,
-        real v3x, real v3y, real v3z )
-{
-  real cx, cy, cz;
-  cross( v2x, v2y, v2z, v3x, v3y, v3z, cx, cy, cz );
-  return v1x*cx + v1y*cy + v1z*cz;
-}
-
-//! Compute the triple-product of three vectors
-//! \param[in] v1 1st vector
-//! \param[in] v2 2nd vector
-//! \param[in] v3 3rd vector
-//! \return Triple-product
-inline real
-triple( const std::array< real, 3 >& v1,
-        const std::array< real, 3 >& v2,
-        const std::array< real, 3 >& v3 )
-{
-  return dot( v1, cross(v2,v3) );
-}
-
-//! Rotate vector about X axis
-//! \param[in] v Vector to rotate
-//! \param[in] angle Angle to use to rotate with
-//! \return Rotated vector
-inline std::array< real, 3 >
-rotateX( const std::array< real, 3 >& v, real angle )
-{
-  using std::cos;  using std::sin;
-
-  std::array< std::array< real, 3 >, 3 >
-    R{{ {{ 1.0,         0.0,          0.0 }},
-        {{ 0.0,   cos(angle), -sin(angle) }},
-        {{ 0.0,   sin(angle),  cos(angle) }} }};
-
-  return {{ dot(R[0],v), dot(R[1],v), dot(R[2],v) }};
-}
-
-//! Rotate vector about Y axis
-//! \param[in] v Vector to rotate
-//! \param[in] angle Angle to use to rotate with
-//! \return Rotated vector
-inline std::array< real, 3 >
-rotateY( const std::array< real, 3 >& v, real angle )
-{
-  using std::cos;  using std::sin;
-
-  std::array< std::array< real, 3 >, 3 >
-    R{{ {{ cos(angle),  0.0, sin(angle) }},
-        {{ 0.0,         1.0,        0.0 }},
-        {{ -sin(angle), 0.0, cos(angle) }} }};
-
-  return {{ dot(R[0],v), dot(R[1],v), dot(R[2],v) }};
-}
-
-//! Rotate vector about Z axis
-//! \param[in] v Vector to rotate
-//! \param[in] angle Angle to use to rotate with
-//! \return Rotated vector
-inline std::array< real, 3 >
-rotateZ( const std::array< real, 3 >& v, real angle )
-{
-  using std::cos;  using std::sin;
-
-  std::array< std::array< real, 3 >, 3 >
-    R{{ {{ cos(angle), -sin(angle), 0.0 }},
-        {{ sin(angle),  cos(angle), 0.0 }},
-        {{ 0.0,         0.0,        1.0 }} }};
-
-  return {{ dot(R[0],v), dot(R[1],v), dot(R[2],v) }};
-}
-
-//! \brief Compute the determinant of the Jacobian of a coordinate
-//!  transformation over a tetrahedron
-//! \param[in] v1 (x,y,z) coordinates of 1st vertex of the tetrahedron
-//! \param[in] v2 (x,y,z) coordinates of 2nd vertex of the tetrahedron
-//! \param[in] v3 (x,y,z) coordinates of 3rd vertex of the tetrahedron
-//! \param[in] v4 (x,y,z) coordinates of 4th vertex of the tetrahedron
-//! \return Determinant of the Jacobian of transformation of physical
-//!   tetrahedron to reference (xi, eta, zeta) space
-inline real
-Jacobian( const std::array< real, 3 >& v1,
-          const std::array< real, 3 >& v2,
-          const std::array< real, 3 >& v3,
-          const std::array< real, 3 >& v4 )
-{
-  std::array< real, 3 > ba{{ v2[0]-v1[0], v2[1]-v1[1], v2[2]-v1[2] }},
-                        ca{{ v3[0]-v1[0], v3[1]-v1[1], v3[2]-v1[2] }},
-                        da{{ v4[0]-v1[0], v4[1]-v1[1], v4[2]-v1[2] }};
-  return triple( ba, ca, da );
-}
-
-//! \brief Compute the inverse of the Jacobian of a coordinate transformation
-//!   over a tetrahedron
-//! \param[in] v1 (x,y,z) coordinates of 1st vertex of the tetrahedron
-//! \param[in] v2 (x,y,z) coordinates of 2nd vertex of the tetrahedron
-//! \param[in] v3 (x,y,z) coordinates of 3rd vertex of the tetrahedron
-//! \param[in] v4 (x,y,z) coordinates of 4th vertex of the tetrahedron
-//! \return Inverse of the Jacobian of transformation of physical
-//!   tetrahedron to reference (xi, eta, zeta) space
-inline std::array< std::array< real, 3 >, 3 >
-inverseJacobian( const std::array< real, 3 >& v1,
-                 const std::array< real, 3 >& v2,
-                 const std::array< real, 3 >& v3,
-                 const std::array< real, 3 >& v4 )
-{
-  std::array< std::array< real, 3 >, 3 > jacInv;
-
-  auto detJ = Jacobian( v1, v2, v3, v4 );
-
-  jacInv[0][0] =  (  (v3[1]-v1[1])*(v4[2]-v1[2])
-                   - (v4[1]-v1[1])*(v3[2]-v1[2])) / detJ;
-  jacInv[1][0] = -(  (v2[1]-v1[1])*(v4[2]-v1[2])
-                   - (v4[1]-v1[1])*(v2[2]-v1[2])) / detJ;
-  jacInv[2][0] =  (  (v2[1]-v1[1])*(v3[2]-v1[2])
-                   - (v3[1]-v1[1])*(v2[2]-v1[2])) / detJ;
-
-  jacInv[0][1] = -(  (v3[0]-v1[0])*(v4[2]-v1[2])
-                   - (v4[0]-v1[0])*(v3[2]-v1[2])) / detJ;
-  jacInv[1][1] =  (  (v2[0]-v1[0])*(v4[2]-v1[2])
-                   - (v4[0]-v1[0])*(v2[2]-v1[2])) / detJ;
-  jacInv[2][1] = -(  (v2[0]-v1[0])*(v3[2]-v1[2])
-                   - (v3[0]-v1[0])*(v2[2]-v1[2])) / detJ;
-
-  jacInv[0][2] =  (  (v3[0]-v1[0])*(v4[1]-v1[1])
-                   - (v4[0]-v1[0])*(v3[1]-v1[1])) / detJ;
-  jacInv[1][2] = -(  (v2[0]-v1[0])*(v4[1]-v1[1])
-                   - (v4[0]-v1[0])*(v2[1]-v1[1])) / detJ;
-  jacInv[2][2] =  (  (v2[0]-v1[0])*(v3[1]-v1[1])
-                   - (v3[0]-v1[0])*(v2[1]-v1[1])) / detJ;
-
-  return jacInv;
-}
-
-//! Compute the determinant of 3x3 matrix
-//!  \param[in] a 3x3 matrix
-//!  \return Determinant of the 3x3 matrix
-inline tk::real
-determinant( const std::array< std::array< tk::real, 3 >, 3 >& a )
-{
-  return ( a[0][0] * (a[1][1]*a[2][2]-a[1][2]*a[2][1])
-         - a[0][1] * (a[1][0]*a[2][2]-a[1][2]*a[2][0])
-         + a[0][2] * (a[1][0]*a[2][1]-a[1][1]*a[2][0]) );
-}
-
-//! Compute the inverse of 3x3 matrix
-//!  \param[in] m 3x3 matrix
-//!  \return Inverse of the 3x3 matrix
-inline std::array< std::array< tk::real, 3 >, 3 >
-inverse( const std::array< std::array< tk::real, 3 >, 3 >& m )
-{
-  tk::real det = m[0][0] * (m[1][1] * m[2][2] - m[2][1] * m[1][2]) -
-                 m[0][1] * (m[1][0] * m[2][2] - m[1][2] * m[2][0]) +
-                 m[0][2] * (m[1][0] * m[2][1] - m[1][1] * m[2][0]);
-
-  tk::real invdet = 1.0 / det;
-
-  std::array< std::array< tk::real, 3 >, 3 > minv;
-  minv[0][0] = (m[1][1] * m[2][2] - m[2][1] * m[1][2]) * invdet;
-  minv[0][1] = (m[0][2] * m[2][1] - m[0][1] * m[2][2]) * invdet;
-  minv[0][2] = (m[0][1] * m[1][2] - m[0][2] * m[1][1]) * invdet;
-  minv[1][0] = (m[1][2] * m[2][0] - m[1][0] * m[2][2]) * invdet;
-  minv[1][1] = (m[0][0] * m[2][2] - m[0][2] * m[2][0]) * invdet;
-  minv[1][2] = (m[1][0] * m[0][2] - m[0][0] * m[1][2]) * invdet;
-  minv[2][0] = (m[1][0] * m[2][1] - m[2][0] * m[1][1]) * invdet;
-  minv[2][1] = (m[2][0] * m[0][1] - m[0][0] * m[2][1]) * invdet;
-  minv[2][2] = (m[0][0] * m[1][1] - m[1][0] * m[0][1]) * invdet;
-
-  return minv;
-}
-
-//! Solve a 3x3 system of equations using Cramer's rule
-//!  \param[in] a 3x3 lhs matrix
-//!  \param[in] b 3x1 rhs matrix
-//!  \return Array of solutions of the 3x3 system
-inline std::array < tk::real, 3 >
-cramer( const std::array< std::array< tk::real, 3 >, 3>& a,
-        const std::array< tk::real, 3 >& b )
-{
-  auto de = determinant( a );
-
-  auto nu(0.0);
-  std::array < real, 3 > x;
-
-  nu = determinant( {{{{b[0], a[0][1], a[0][2]}},
-                      {{b[1], a[1][1], a[1][2]}},
-                      {{b[2], a[2][1], a[2][2]}}}} );
-  x[0] = nu/de;
-
-  nu = determinant( {{{{a[0][0], b[0], a[0][2]}},
-                      {{a[1][0], b[1], a[1][2]}},
-                      {{a[2][0], b[2], a[2][2]}}}} );
-  x[1] = nu/de;
-
-  nu = determinant( {{{{a[0][0], a[0][1], b[0]}},
-                      {{a[1][0], a[1][1], b[1]}},
-                      {{a[2][0], a[2][1], b[2]}}}} );
-  x[2] = nu/de;
-
-  return x;
-}
-
-//! Move a point to a reference space given coordinates of origin of that space
-//!  \param[in] origin Origin of reference frame to which point is to be moved
-//!  \param[in,out] point Point that needs to be moved to reference frame
-inline void
-movePoint( const std::array< tk::real, 3 >& origin,
-  std::array< tk::real, 3 >& point )
-{
-  for (std::size_t i=0; i<3; ++i)
-    point[i] -= origin[i];
-}
-
-//! Rotate a point in 3D space by specifying rotation angles in degrees
-//!  \param[in] angles Angles in 3D space by which point is to be rotated
-//!  \param[in,out] point Point that needs to be rotated
-inline void
-rotatePoint( const std::array< tk::real, 3 >& angles,
-  std::array< tk::real, 3 >& point )
-{
-  // Convert angles to radian
-  tk::real pi = 4.0*std::atan(1.0);
-  auto a = angles[0] * pi/180.0;
-  auto b = angles[1] * pi/180.0;
-  auto c = angles[2] * pi/180.0;
-
-  // Rotation matrix
-  std::array< std::array< tk::real, 3 >, 3 > rotMat;
-  {
-    using namespace std;
-    rotMat[0][0] = cos(b)*cos(c);
-    rotMat[0][1] = - cos(b)*sin(c);
-    rotMat[0][2] = sin(b);
-
-    rotMat[1][0] = sin(a)*sin(b)*cos(c) + cos(a)*sin(c);
-    rotMat[1][1] = - sin(a)*sin(b)*sin(c) + cos(a)*cos(c);
-    rotMat[1][2] = - sin(a)*cos(b);
-
-    rotMat[2][0] = - cos(a)*sin(b)*cos(c) + sin(a)*sin(c);
-    rotMat[2][1] = cos(a)*sin(b)*sin(c) + sin(a)*cos(c);
-    rotMat[2][2] = cos(a)*cos(b);
-  }
-
-  // Apply rotation
-  std::array< tk::real, 3 > x{{0.0, 0.0, 0.0}};
-  for (std::size_t i=0; i<3; ++i) {
-    for (std::size_t j=0; j<3; ++j) {
-      x[i] += rotMat[i][j]*point[j];
-    }
-  }
-  point = x;
-}
-
-//! \brief Get the Right Cauchy-Green strain tensor from the inverse deformation
-//! gradient tensor.
-//! \param[in] g Inverse deformation gradient tensor
-//! \return Right Cauchy-Green tensor
-inline std::array< std::array< real, 3 >, 3 >
-getRightCauchyGreen(const std::array< std::array< real, 3 >, 3 >& g)
-{
-  // allocate matrices
-  double G[9], C[9];
-
-  // initialize c-matrices
-  for (std::size_t i=0; i<3; ++i) {
-    for (std::size_t j=0; j<3; ++j)
-      G[i*3+j] = g[i][j];
-  }
-
-  // get g.g^T
-  cblas_dgemm(CblasRowMajor, CblasNoTrans, CblasTrans,
-    3, 3, 3, 1.0, G, 3, G, 3, 0.0, C, 3);
-
-  // get inv(g.g^T)
-  lapack_int ipiv[3];
-
-  #ifndef NDEBUG
-  lapack_int ierr =
-  #endif
-    LAPACKE_dgetrf(LAPACK_ROW_MAJOR, 3, 3, C, 3, ipiv);
-  Assert(ierr==0, "Lapack error in LU factorization of g.g^T");
-
-  #ifndef NDEBUG
-  lapack_int jerr =
-  #endif
-    LAPACKE_dgetri(LAPACK_ROW_MAJOR, 3, C, 3, ipiv);
-  Assert(jerr==0, "Lapack error in inverting g.g^T");
-
-  // Output C as 2D array
-  return {{ {C[0], C[1], C[2]},
-            {C[3], C[4], C[5]},
-            {C[6], C[7], C[8]} }};
-}
-
-//! \brief Get the Left Cauchy-Green strain tensor from the inverse deformation
-//! gradient tensor.
-//! \param[in] g Inverse deformation gradient tensor
-//! \return Left Cauchy-Green tensor
-inline std::array< std::array< real, 3 >, 3 >
-getLeftCauchyGreen(const std::array< std::array< real, 3 >, 3 >& g)
-{
-  // allocate matrices
-  double G[9], b[9];
-
-  // initialize c-matrices
-  for (std::size_t i=0; i<3; ++i) {
-    for (std::size_t j=0; j<3; ++j)
-      G[i*3+j] = g[i][j];
-  }
-
-  // get g^T.g
-  cblas_dgemm(CblasRowMajor, CblasTrans, CblasNoTrans,
-    3, 3, 3, 1.0, G, 3, G, 3, 0.0, b, 3);
-
-  // get inv(g^T.g)
-  lapack_int ipiv[3];
-
-  #ifndef NDEBUG
-  lapack_int ierr =
-  #endif
-    LAPACKE_dgetrf(LAPACK_ROW_MAJOR, 3, 3, b, 3, ipiv);
-  Assert(ierr==0, "Lapack error in LU factorization of g^T.g");
-
-  #ifndef NDEBUG
-  lapack_int jerr =
-  #endif
-    LAPACKE_dgetri(LAPACK_ROW_MAJOR, 3, b, 3, ipiv);
-  Assert(jerr==0, "Lapack error in inverting g^T.g");
-
-  // Output b as 2D array
-  return {{ {b[0], b[1], b[2]},
-            {b[3], b[4], b[5]},
-            {b[6], b[7], b[8]} }};
-}
-
-//! \brief Rotate a second order tensor (e.g. a Strain/Stress matrix) from
-//! the (x,y,z) to a new (r,s,t) coordinate system.
-//! The first direction is given by a unit vector r = (rx,ry,rz).
-//! Then, the second is chosen to be:
-//! if |rx| > 0 or |ry| > 0:
-//! - s = (ry/sqrt(rx*rx+ry*ry),-rx/sqrt(rx*rx+ry*ry),0)
-//! else:
-//! - s = (1,0,0)
-//! Then, third basis vector is obtained from
-//! the cross-product between the first two.
-//! \param[in] mat matrix to be rotated.
-//! \param[in] r Coordinates of the first basis vector r = (rx,ry,rz).
-//! \return rotated tensor
-inline std::array< std::array< tk::real, 3 >, 3 >
-rotateTensor(const std::array< std::array< tk::real, 3 >, 3 >& mat,
-             const std::array< tk::real, 3 >& r )
-{
-  // define rotation matrix
-  tk::real eps = 1.0e-04;
-  double rotMat[9];
-  tk::real rx = r[0];
-  tk::real ry = r[1];
-  tk::real rz = r[2];
-  if (std::abs(rx) > eps || std::abs(ry) > eps)
-  {
-    tk::real rxryNorm = std::sqrt(rx*rx+ry*ry);
-    rotMat[0] = rx;
-    rotMat[1] = ry;
-    rotMat[2] = rz;
-    rotMat[3] = ry/rxryNorm;
-    rotMat[4] = -rx/rxryNorm;
-    rotMat[5] = 0.0;
-    rotMat[6] = rx*rz/rxryNorm;
-    rotMat[7] = ry*rz/rxryNorm;
-    rotMat[8] = -rxryNorm;
-  }
-  else
-  {
-    rotMat[0] = rx;
-    rotMat[1] = ry;
-    rotMat[2] = rz;
-    rotMat[3] = 1.0;
-    rotMat[4] = 0.0;
-    rotMat[5] = 0.0;
-    rotMat[6] = 0.0;
-    rotMat[7] = 1.0;
-    rotMat[8] = 0.0;
-  }
-
-  // define matrices
-  double matAuxIn[9], matAuxOut[9];
-  for (std::size_t i=0; i<3; ++i)
-    for (std::size_t j=0; j<3; ++j)
-      matAuxIn[i*3+j] = mat[i][j];
-
-  // compute matAuxIn*rotMat and store it into matAuxOut
-  cblas_dgemm(CblasRowMajor, CblasNoTrans, CblasNoTrans,
-    3, 3, 3, 1.0, matAuxIn, 3, rotMat, 3, 0.0, matAuxOut, 3);
-
-  // matAuxOut -> matAuxIn
-  for (std::size_t i=0; i<9; i++)
-  {
-    matAuxIn[i]  = matAuxOut[i];
-    matAuxOut[i] = 0.0;
-  }
-
-  // compute rotMat^T*matAuxIn and store it into matAuxOut
-  cblas_dgemm(CblasRowMajor, CblasTrans, CblasNoTrans,
-    3, 3, 3, 1.0, rotMat, 3, matAuxIn, 3, 0.0, matAuxOut, 3);
-
-  // return matAuxOut as a 2D array
-  return {{ {matAuxOut[0], matAuxOut[1], matAuxOut[2]},
-            {matAuxOut[3], matAuxOut[4], matAuxOut[5]},
-            {matAuxOut[6], matAuxOut[7], matAuxOut[8]} }};
-}
-
-//! \brief Reflect a second order tensor (e.g. a Strain/Stress matrix)
-//! \param[in] mat matrix to be rotated.
-//! \param[in] reflectMat Reflection matrix
-//! \return reflected tensor
-inline std::array< std::array< tk::real, 3 >, 3 >
-reflectTensor(const std::array< std::array< tk::real, 3 >, 3 >& mat,
-              const std::array< std::array< tk::real, 3 >, 3 >& reflectMat)
-{
-  // define reflection matrix
-  double refMat[9];
-  for (std::size_t i=0; i<3; ++i)
-    for (std::size_t j=0; j<3; ++j)
-      refMat[i*3+j] = reflectMat[i][j];
-
-  // define matAux (I need matrices as row major 1D arrays)
-  double matAuxIn[9], matAuxOut[9];
-  for (std::size_t i=0; i<3; ++i)
-    for (std::size_t j=0; j<3; ++j)
-      matAuxIn[i*3+j] = mat[i][j];
-
-  // compute matAuxIn*refMat and store it into matAuxOut
-  cblas_dgemm(CblasRowMajor, CblasNoTrans, CblasNoTrans,
-    3, 3, 3, 1.0, matAuxIn, 3, refMat, 3, 0.0, matAuxOut, 3);
-
-  // matAuxOut -> matAuxIn
-  for (std::size_t i=0; i<9; i++)
-  {
-    matAuxIn[i]  = matAuxOut[i];
-    matAuxOut[i] = 0.0;
-  }
-
-  // compute refMat^T*matAuxIn and store it into matAuxOut
-  cblas_dgemm(CblasRowMajor, CblasTrans, CblasNoTrans,
-    3, 3, 3, 1.0, refMat, 3, matAuxIn, 3, 0.0, matAuxOut, 3);
-
-  // return matAuxOut as a 2D array
-  return {{ {matAuxOut[0], matAuxOut[1], matAuxOut[2]},
-            {matAuxOut[3], matAuxOut[4], matAuxOut[5]},
-            {matAuxOut[6], matAuxOut[7], matAuxOut[8]} }};
-}
-
-} // tk::
-
-#endif // Vector_h
+//! \brief Tagged tuple, allowing tag-based access
+//! \details "Tag" here is any type, but mostly an empty struct with a good name
+//!   for the data member
+//! \tparam List Type list as brigand::list
+//! \see https://stackoverflow.com/a/42988897
+//! \see https://gist.github.com/underdoeg/4c5c616c1ad4cbb718f787eefcab902d
+template< class List >
+class TaggedTuple{
+
+  private:
+    //! Generate index for every 2nd type of a type list
+    template< typename T >
+    using is_odd = brigand::size_t< (brigand::index_of<List,T>::value%2) != 0 >;
+
+    //! Partition a type list into two lists with the even and the odd types
+    using Pair = brigand::partition< List, brigand::bind<is_odd,brigand::_1> >;
+
+    //! List of member types
+    using Data = typename Pair::first_type;
+
+    //! Tuple of member types
+    using Tuple = brigand::as_tuple< Data >;
+
+    //! False-overload for detecting if T is a tagged tuple
+    template< typename T, typename = std::void_t<> >
+    struct is_tagged_tuple_t : std::false_type {};
+
+    //! True-overload for detecting if T is a tagged tuple
+    template< typename T >
+    struct is_tagged_tuple_t< T, std::void_t< typename T::i_am_tagged_tuple > >
+     : std::true_type {};
+
+    //! Member data as a tuple
+    Tuple m_members;
+
+  public:
+    //! List of key-value pairs
+    using PairList = List;
+
+    //! List of keys
+    using Keys = typename Pair::second_type;
+
+    //! Typedef defining self for identifying self
+    using i_am_tagged_tuple = void;
+
+    //! Acces type in tuple behind tag
+    template< typename Tag >
+    using TupleElement =
+      std::tuple_element_t< brigand::index_of<Keys,Tag>::value, Tuple >;
+
+    //! Query if the type behind Tag is a TaggedTuple
+    //! Usage: if constexpr( is_tagged_tuple<Tag>::value ) { ... }
+    template< typename Tag >
+    using is_tagged_tuple =
+      is_tagged_tuple_t< std::decay_t< TupleElement<Tag> > >;
+
+    //! Default constructor
+    explicit TaggedTuple() = default;
+    //! Initializer constructor
+    explicit TaggedTuple( Tuple&& tuple ) : m_members( std::move(tuple) ) {}
+
+    //! Const-ref access to member tuple
+    const Tuple& tuple() const { return m_members; }
+
+    //! Const-reference data member accessor of field of tagged tuple at depth
+    template< typename Tag, typename... Tags >
+    const auto& get() const noexcept {
+      constexpr std::size_t idx = brigand::index_of< Keys, Tag >::value;
+      if constexpr( is_tagged_tuple<Tag>::value and sizeof...(Tags) != 0 )
+        return std::get< idx >( m_members ).template get< Tags... >();
+      else
+        return std::get< idx >( m_members );
+    }
+
+    //! Reference data member accessor of field of tagged tuple at depth
+    template< typename Tag, typename... Tags >
+    auto& get() noexcept {<--- Syntax Error: AST broken, binary operator '>' doesn't have two operands.
+      constexpr std::size_t idx = brigand::index_of< Keys, Tag >::value;
+      if constexpr( is_tagged_tuple<Tag>::value and sizeof...(Tags) != 0 )
+        return std::get< idx >( m_members ).template get< Tags... >();
+      else
+        return std::get< idx >( m_members );
+    }
+
+    //! Convert and store value converting from string at depth
+    //! \param[in] value Value to convert and store
+    template< typename Tag, typename... Tags >
+    void store( const std::string& value ) noexcept {
+      if constexpr( is_tagged_tuple<Tag>::value and sizeof...(Tags) != 0 )
+      {
+        using T = std::remove_reference_t< decltype( get<Tag,Tags...>() ) >;
+        get< Tag, Tags... >() = convert< T >( value );
+      } else {
+        using T = std::remove_reference_t< decltype( get< Tag >() ) >;
+        get< Tag >() = convert< T >( value );
+      }
+    }
+
+    //! Operator == between two TaggedTuple objects
+    //! \tparam L Type list as brigand::list for other TaggedTuple
+    //! \return True if the lhs and rhs equal
+    template< typename L >
+    bool operator== ( const TaggedTuple< L >& t ) const {
+      static_assert( std::is_same_v< L, List >, "Invoking operator== on "
+        "TaggedTuple objects with different typelists" );
+      static_assert( !brigand::any< List,
+        std::is_floating_point<brigand::_1> >::value, "Invoking operator== on "
+        "TaggedTuple objects containing a floating point type is unreliable" );
+      return m_members == t.tuple();
+    }
+
+    //! Operator < between two TaggedTuple objects
+    //! \tparam L Type list as brigand::list for other TaggedTuple
+    //! \return True if lhs < rhs
+    template< typename L >
+    bool operator< ( const TaggedTuple< L >& t ) const {
+      static_assert( std::is_same_v< L, List >, "Invoking operator< on "
+        "TaggedTuple objects with different typelists" );
+      return m_members < t.tuple();
+    }
+
+    //! Return number of tuple entries
+    static constexpr std::size_t size() { return std::tuple_size_v< Tuple >; }
+
+    //! Pack/Unpack
+    /** @name Charm++ pack/unpack serializer member functions */
+    ///@{
+    //! \brief Pack/Unpack serialize member function
+    //! \param[in,out] p Charm++'s PUP::er serializer object reference
+    void pup( PUP::er& p ) { p | m_members; }<--- Parameter 'p' can be declared with const
+    //! \brief Pack/Unpack serialize operator|
+    //! \param[in,out] p Charm++'s PUP::er serializer object reference
+    //! \param[in,out] t TaggedTuple object reference
+    friend void operator|( PUP::er& p, TaggedTuple<List>& t ) { t.pup(p); }
+    //@}
+
+    //! Convert/parse string to and return as type given by template argument
+    //! \param[in] str String to convert
+    //! \return A value of type given by the template argument
+    template< typename type >
+    type convert( const std::string& str ) {
+      std::stringstream ss( str );
+      type num;
+      ss >> std::boolalpha >> num;
+      if (ss.fail())
+        Throw( "Failed to convert '" + str +
+               "' to typeid " + typeid(num).name() );
+      return num;
+    }
+};
+
+} // tk::
+
+#endif // TaggedTuple_h
 
diff --git a/Debug/cppcheck/80.html b/Debug/cppcheck/80.html index c19d2648ce93..6f0d4b8b0527 100644 --- a/Debug/cppcheck/80.html +++ b/Debug/cppcheck/80.html @@ -152,125 +152,263 @@
- - + diff --git a/Debug/test_coverage/Base/ChareStateCollector.cpp.func.html b/Debug/test_coverage/Base/ChareStateCollector.cpp.func.html index d94c35082362..0d7d741d9124 100644 --- a/Debug/test_coverage/Base/ChareStateCollector.cpp.func.html +++ b/Debug/test_coverage/Base/ChareStateCollector.cpp.func.html @@ -33,7 +33,7 @@ - + diff --git a/Debug/test_coverage/Base/ChareStateCollector.cpp.gcov.html b/Debug/test_coverage/Base/ChareStateCollector.cpp.gcov.html index 31b0cbe28017..4fe0b5159bb1 100644 --- a/Debug/test_coverage/Base/ChareStateCollector.cpp.gcov.html +++ b/Debug/test_coverage/Base/ChareStateCollector.cpp.gcov.html @@ -33,7 +33,7 @@ - + diff --git a/Debug/test_coverage/Base/ChareStateCollector.hpp.func-sort-c.html b/Debug/test_coverage/Base/ChareStateCollector.hpp.func-sort-c.html index f1c1e4f4ae5d..3d0734acec66 100644 --- a/Debug/test_coverage/Base/ChareStateCollector.hpp.func-sort-c.html +++ b/Debug/test_coverage/Base/ChareStateCollector.hpp.func-sort-c.html @@ -33,7 +33,7 @@ - + diff --git a/Debug/test_coverage/Base/ChareStateCollector.hpp.func.html b/Debug/test_coverage/Base/ChareStateCollector.hpp.func.html index bea3f9418bd7..150bed845a34 100644 --- a/Debug/test_coverage/Base/ChareStateCollector.hpp.func.html +++ b/Debug/test_coverage/Base/ChareStateCollector.hpp.func.html @@ -33,7 +33,7 @@ - + diff --git a/Debug/test_coverage/Base/ChareStateCollector.hpp.gcov.html b/Debug/test_coverage/Base/ChareStateCollector.hpp.gcov.html index 9db11ff55fba..adabfcd7e5b9 100644 --- a/Debug/test_coverage/Base/ChareStateCollector.hpp.gcov.html +++ b/Debug/test_coverage/Base/ChareStateCollector.hpp.gcov.html @@ -33,7 +33,7 @@ - + diff --git a/Debug/test_coverage/Base/ContainerUtil.hpp.func-sort-c.html b/Debug/test_coverage/Base/ContainerUtil.hpp.func-sort-c.html index d609dd9702b2..695208318664 100644 --- a/Debug/test_coverage/Base/ContainerUtil.hpp.func-sort-c.html +++ b/Debug/test_coverage/Base/ContainerUtil.hpp.func-sort-c.html @@ -33,7 +33,7 @@ - + diff --git a/Debug/test_coverage/Base/ContainerUtil.hpp.func.html b/Debug/test_coverage/Base/ContainerUtil.hpp.func.html index 9d82f34b29fe..9bbda30adc7b 100644 --- a/Debug/test_coverage/Base/ContainerUtil.hpp.func.html +++ b/Debug/test_coverage/Base/ContainerUtil.hpp.func.html @@ -33,7 +33,7 @@ - + diff --git a/Debug/test_coverage/Base/ContainerUtil.hpp.gcov.html b/Debug/test_coverage/Base/ContainerUtil.hpp.gcov.html index cf2fc774d49d..0c95a39f2fe8 100644 --- a/Debug/test_coverage/Base/ContainerUtil.hpp.gcov.html +++ b/Debug/test_coverage/Base/ContainerUtil.hpp.gcov.html @@ -33,7 +33,7 @@ - + diff --git a/Debug/test_coverage/Base/Data.hpp.func-sort-c.html b/Debug/test_coverage/Base/Data.hpp.func-sort-c.html index fb7daf050360..10e5073b308a 100644 --- a/Debug/test_coverage/Base/Data.hpp.func-sort-c.html +++ b/Debug/test_coverage/Base/Data.hpp.func-sort-c.html @@ -33,7 +33,7 @@ - + @@ -420,12 +420,12 @@ - - + + - - + + @@ -445,11 +445,11 @@ - + - + @@ -509,15 +509,15 @@ - + - + - +
 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
-10
-11
-12
-13
-14
-15
-16
-17
-18
-19
-20
-21
-22
-23
-24
-25
-26
-27
-28
-29
-30
-31
-32
-33
-34
-35
-36
-37
-38
-39
-40
-41
-42
-43
-44
-45
-46
-47
-48
-49
-50
-51
-52
-53
-54
-55
-56
// Controller for the library
-
-#include "NoWarning/m2mtransfer.decl.h"
-
-#include "collidecharm.h"
-#include "Fields.hpp"
-
-namespace exam2m {
-
-void addMesh(CkArrayID p, int elem, CkCallback cb);
-void setSourceTets(CkArrayID p, int index, std::vector< std::size_t >* inpoel, tk::UnsMesh::Coords* coords, const tk::Fields& u);
-void setDestPoints(CkArrayID p, int index, tk::UnsMesh::Coords* coords, tk::Fields& u, CkCallback cb);
-
-class LibMain : public CBase_LibMain {
-public:
-  LibMain(CkArgMsg* msg);
-};
-
-class MeshData {
-  public:
-    CProxy_TransferDetails m_proxy;
-    int m_firstchunk;
-    int m_nchare;
-    void pup(PUP::er& p) {<--- Parameter 'p' can be declared with const
-      p | m_proxy;
-      p | m_firstchunk;
-      p | m_nchare;
-    }
-};
-
-class M2MTransfer : public CBase_M2MTransfer {
-  private:
-    std::unordered_map<CmiUInt8, MeshData> proxyMap;
-    int current_chunk;
-    CmiUInt8 m_sourcemesh, m_destmesh;
-
-  public:
-    M2MTransfer();
-    #if defined(__clang__)
-      #pragma clang diagnostic push
-      #pragma clang diagnostic ignored "-Wundefined-func-template"
-    #endif
-    explicit M2MTransfer( CkMigrateMessage* m ) : CBase_M2MTransfer( m ) {}<--- Member variable 'M2MTransfer::current_chunk' is not initialized in the constructor.
-    #if defined(__clang__)
-      #pragma clang diagnostic pop
-    #endif
-    void addMesh(CkArrayID p, int elem, CkCallback cb);
-    void setMesh(CkArrayID p, MeshData d);
-    void setSourceTets(CkArrayID p, int index, std::vector< std::size_t >* inpoel,
-                       tk::UnsMesh::Coords* coords, const tk::Fields& u);
-    void setDestPoints(CkArrayID p, int index, tk::UnsMesh::Coords* coords,
-                       tk::Fields& u, CkCallback cb);
-    void distributeCollisions(int nColl, Collision* colls);
-};
-
-}
+
  1
+  2
+  3
+  4
+  5
+  6
+  7
+  8
+  9
+ 10
+ 11
+ 12
+ 13
+ 14
+ 15
+ 16
+ 17
+ 18
+ 19
+ 20
+ 21
+ 22
+ 23
+ 24
+ 25
+ 26
+ 27
+ 28
+ 29
+ 30
+ 31
+ 32
+ 33
+ 34
+ 35
+ 36
+ 37
+ 38
+ 39
+ 40
+ 41
+ 42
+ 43
+ 44
+ 45
+ 46
+ 47
+ 48
+ 49
+ 50
+ 51
+ 52
+ 53
+ 54
+ 55
+ 56
+ 57
+ 58
+ 59
+ 60
+ 61
+ 62
+ 63
+ 64
+ 65
+ 66
+ 67
+ 68
+ 69
+ 70
+ 71
+ 72
+ 73
+ 74
+ 75
+ 76
+ 77
+ 78
+ 79
+ 80
+ 81
+ 82
+ 83
+ 84
+ 85
+ 86
+ 87
+ 88
+ 89
+ 90
+ 91
+ 92
+ 93
+ 94
+ 95
+ 96
+ 97
+ 98
+ 99
+100
+101
+102
+103
+104
+105
+106
+107
+108
+109
+110
+111
+112
+113
+114
+115
+116
+117
+118
+119
+120
+121
+122
+123
+124
+125
// *****************************************************************************
+/*!
+  \file      src/Transfer/TransferDetails.hpp
+  \copyright 2020 Charmworks, Inc.
+             All rights reserved. See the LICENSE file for details.
+  \brief     Chare class declaration for mesh transfer workers holding part of a
+    mesh
+  \details   Chare class declaration for mesh transfer workers holding part of a
+    mesh.
+*/
+// *****************************************************************************
+#ifndef TransferDetails_h
+#define TransferDetails_h
+
+#include "Types.hpp"
+#include "PUPUtil.hpp"
+#include "UnsMesh.hpp"
+#include "CommMap.hpp"
+#include "Fields.hpp"
+
+#include "NoWarning/transferdetails.decl.h"
+
+namespace exam2m {
+
+class PotentialCollision {
+  public:
+    std::size_t source_index, dest_index;
+    CkVector3d point;
+    void pup(PUP::er& p) { p | source_index; p | dest_index; p | point; }<--- Parameter 'p' can be declared with const
+};
+
+class SolutionData {
+  public:
+    std::size_t dest_index;
+    std::vector< tk::real > solution;
+    void pup(PUP::er& p) { p | dest_index; p | solution; }<--- Parameter 'p' can be declared with const
+};
+
+//! TransferDetails chare array holding part of a mesh
+class TransferDetails : public CBase_TransferDetails {
+
+  public:
+    //! Constructor
+    explicit TransferDetails( CkArrayID p, MeshData d, CkCallback cb );
+
+    #if defined(__clang__)
+      #pragma clang diagnostic push
+      #pragma clang diagnostic ignored "-Wundefined-func-template"
+    #endif
+    //! Migrate constructor
+    // cppcheck-suppress uninitMemberVar
+    explicit TransferDetails( CkMigrateMessage* ) {}
+    #if defined(__clang__)
+      #pragma clang diagnostic pop
+    #endif
+
+    //! Set the source mesh data
+    void setSourceTets( std::vector< std::size_t>* inpoel,
+                        tk::UnsMesh::Coords* coords,
+                        const tk::Fields& u );
+
+    //! Set the destination mesh data
+    void setDestPoints( tk::UnsMesh::Coords* coords,
+                        tk::Fields& u,
+                        CkCallback cb );
+
+    //! Process potential collisions in the destination mesh
+    void processCollisions( CProxy_TransferDetails proxy,
+                            int nchare,
+                            int offset,
+                            int nColls,
+                            Collision* colls );
+
+    //! Identify actual collisions in the source mesh
+    void determineActualCollisions( CProxy_TransferDetails proxy,
+                                    int index,
+                                    int nColls,
+                                    PotentialCollision* colls ) const;
+
+    //! Transfer the interpolated solution data back to destination mesh
+    void transferSolution( const std::vector< SolutionData >& soln );
+
+    /** @name Charm++ pack/unpack serializer member functions */
+    ///@{
+    //! \brief Pack/Unpack serialize member function
+    //! \param[in,out] p Charm++'s PUP::er serializer object reference
+    void pup( PUP::er &p ) override {
+      p | m_firstchunk;
+    }
+    //! \brief Pack/Unpack serialize operator|
+    //! \param[in,out] p Charm++'s PUP::er serializer object reference
+    //! \param[in,out] i TransferDetails object reference
+    friend void operator|( PUP::er& p, TransferDetails& i ) { i.pup(p); }
+    //@}
+
+  private:
+    //! The ID of my first chunk (used for collision detection library)
+    int m_firstchunk;
+    //! Pointer to element connectivity
+    std::vector< std::size_t >* m_inpoel;
+    //! Pointer to point coordinates
+    tk::UnsMesh::Coords* m_coord;
+    //! Pointer to solution in mesh nodes
+    tk::Fields* m_u;
+
+    //! The number of messages sent by the dest mesh
+    int m_numsent;
+    //! The number of messages received by the dest mesh
+    int m_numreceived;
+    //! Called once the transfer is complete (m_numsent == m_numreceived)
+    CkCallback m_donecb;
+
+    //! Initialize dest mesh solution with background data
+    void background();
+
+    //! Contribute vertex information to the collsion detection library
+    void collideVertices();
+
+    //! Contribute tet information to the collision detection library
+    void collideTets() const;
+};
+
+} // exam2m::
+
+#endif // TransferDetails_h
 
diff --git a/Debug/cppcheck/81.html b/Debug/cppcheck/81.html index 9a18cedc9383..d40669e11cdb 100644 --- a/Debug/cppcheck/81.html +++ b/Debug/cppcheck/81.html @@ -152,263 +152,183 @@
- - - - - - + + + + + @@ -148,204 +148,204 @@

Cppcheck report - [

- - - - - - - - - - - + + + + + + + + + + + - - - - - - - - - - + + + + + + + + + + - - - - - - - - - - + + + + + + + + + + - - - - - - - - + + + + + + + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - + + + @@ -362,33 +362,33 @@

Cppcheck report - [

- - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + - - - - + + + + + + + - - + + @@ -402,110 +402,110 @@

Cppcheck report - [

- - - - + + + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -519,66 +519,66 @@

Cppcheck report - [

- - - - + + + + - - + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - + + +
  1
-  2
-  3
-  4
-  5
-  6
-  7
-  8
-  9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
- 37
- 38
- 39
- 40
- 41
- 42
- 43
- 44
- 45
- 46
- 47
- 48
- 49
- 50
- 51
- 52
- 53
- 54
- 55
- 56
- 57
- 58
- 59
- 60
- 61
- 62
- 63
- 64
- 65
- 66
- 67
- 68
- 69
- 70
- 71
- 72
- 73
- 74
- 75
- 76
- 77
- 78
- 79
- 80
- 81
- 82
- 83
- 84
- 85
- 86
- 87
- 88
- 89
- 90
- 91
- 92
- 93
- 94
- 95
- 96
- 97
- 98
- 99
-100
-101
-102
-103
-104
-105
-106
-107
-108
-109
-110
-111
-112
-113
-114
-115
-116
-117
-118
-119
-120
-121
-122
-123
-124
-125
// *****************************************************************************
+
 1
+ 2
+ 3
+ 4
+ 5
+ 6
+ 7
+ 8
+ 9
+10
+11
+12
+13
+14
+15
+16
+17
+18
+19
+20
+21
+22
+23
+24
+25
+26
+27
+28
+29
+30
+31
+32
+33
+34
+35
+36
+37
+38
+39
+40
+41
+42
+43
+44
+45
+46
+47
+48
+49
+50
+51
+52
+53
+54
+55
+56
+57
+58
+59
+60
+61
+62
+63
+64
+65
+66
+67
+68
+69
+70
+71
+72
+73
+74
+75
+76
+77
+78
+79
+80
+81
+82
+83
+84
+85
// *****************************************************************************
 /*!
-  \file      src/Transfer/TransferDetails.hpp
-  \copyright 2020 Charmworks, Inc.
-             All rights reserved. See the LICENSE file for details.
-  \brief     Chare class declaration for mesh transfer workers holding part of a
-    mesh
-  \details   Chare class declaration for mesh transfer workers holding part of a
-    mesh.
-*/
-// *****************************************************************************
-#ifndef TransferDetails_h
-#define TransferDetails_h
-
-#include "Types.hpp"
-#include "PUPUtil.hpp"
-#include "UnsMesh.hpp"
-#include "CommMap.hpp"
-#include "Fields.hpp"
-
-#include "NoWarning/transferdetails.decl.h"
-
-namespace exam2m {
-
-class PotentialCollision {
-  public:
-    std::size_t source_index, dest_index;
-    CkVector3d point;
-    void pup(PUP::er& p) { p | source_index; p | dest_index; p | point; }<--- Parameter 'p' can be declared with const
-};
-
-class SolutionData {
-  public:
-    std::size_t dest_index;
-    std::vector< tk::real > solution;
-    void pup(PUP::er& p) { p | dest_index; p | solution; }<--- Parameter 'p' can be declared with const
-};
-
-//! TransferDetails chare array holding part of a mesh
-class TransferDetails : public CBase_TransferDetails {
-
-  public:
-    //! Constructor
-    explicit TransferDetails( CkArrayID p, MeshData d, CkCallback cb );
-
-    #if defined(__clang__)
-      #pragma clang diagnostic push
-      #pragma clang diagnostic ignored "-Wundefined-func-template"
-    #endif
-    //! Migrate constructor
-    // cppcheck-suppress uninitMemberVar
-    explicit TransferDetails( CkMigrateMessage* ) {}
-    #if defined(__clang__)
-      #pragma clang diagnostic pop
-    #endif
+  \file      src/PDE/Transport/Problem/CylVortex.cpp
+  \copyright 2012-2015 J. Bakosi,
+             2016-2018 Los Alamos National Security, LLC.,
+             2019-2021 Triad National Security, LLC.
+             All rights reserved. See the LICENSE file for details.
+  \brief     Problem configuration for transport equations
+  \details   This file defines a Problem policy class for the transport
+    equations, defined in PDE/Transport/CGTransport.hpp implementing
+    node-centered continuous Galerkin (CG) and PDE/Transport/DGTransport.hpp
+    implementing cell-centered discontinuous Galerkin (DG) discretizations.
+    See PDE/Transport/Problem.hpp for general requirements on Problem policy
+    classes for cg::Transport and dg::Transport.
+*/
+// *****************************************************************************
+
+#include "CylVortex.hpp"
+
+using inciter::TransportProblemCylVortex;
+
+std::vector< tk::real >
+TransportProblemCylVortex::initialize( ncomp_t ncomp,
+                                       const std::vector< EOS >&,
+                                       tk::real x, tk::real y, tk::real,
+                                       tk::real t )
+// *****************************************************************************
+//  Evaluate initial solution at (x,y,t) for all components
+//! \param[in] ncomp Number of components in this transport equation system
+//! \param[in] x X coordinate where to evaluate the solution
+//! \param[in] y Y coordinate where to evaluate the solution
+//! \param[in] t Time where to evaluate the solution
+//! \return Values of all components evaluated at (x,y,t=0)
+//! \details This function only gives the initial condition for the cylinder,
+//!   and not the solution at any time t>0.
+// *****************************************************************************
+{
+  const auto vel = prescribedVelocity( ncomp, x, y, 0.0, t );<--- Variable 'vel' is assigned a value that is never used.
+
+  if (ncomp != 4) Throw("Cylinder deformation in vortex is only set up for 4 "
+    "components");
+
+  std::vector< tk::real > s( ncomp, 0.0 );
+
+  // center of the cylinder
+  auto x0 = 0.5;
+  auto y0 = 0.75;
+  auto r = sqrt((x-x0)*(x-x0) + (y-y0)*(y-y0));
+
+  if (r<=0.15) {
+    if (x<x0 && y>=y0) s[0] = 1.0;
+    else if (x>=x0 && y>=y0) s[1] = 1.0;
+    else if (x>=x0 && y<y0) s[2] = 1.0;
+    else if (x<x0 && y<y0) s[3] = 1.0;
+  }
 
-    //! Set the source mesh data
-    void setSourceTets( std::vector< std::size_t>* inpoel,
-                        tk::UnsMesh::Coords* coords,
-                        const tk::Fields& u );
-
-    //! Set the destination mesh data
-    void setDestPoints( tk::UnsMesh::Coords* coords,
-                        tk::Fields& u,
-                        CkCallback cb );
-
-    //! Process potential collisions in the destination mesh
-    void processCollisions( CProxy_TransferDetails proxy,
-                            int nchare,
-                            int offset,
-                            int nColls,
-                            Collision* colls );
-
-    //! Identify actual collisions in the source mesh
-    void determineActualCollisions( CProxy_TransferDetails proxy,
-                                    int index,
-                                    int nColls,
-                                    PotentialCollision* colls ) const;
-
-    //! Transfer the interpolated solution data back to destination mesh
-    void transferSolution( const std::vector< SolutionData >& soln );
-
-    /** @name Charm++ pack/unpack serializer member functions */
-    ///@{
-    //! \brief Pack/Unpack serialize member function
-    //! \param[in,out] p Charm++'s PUP::er serializer object reference
-    void pup( PUP::er &p ) override {
-      p | m_firstchunk;
-    }
-    //! \brief Pack/Unpack serialize operator|
-    //! \param[in,out] p Charm++'s PUP::er serializer object reference
-    //! \param[in,out] i TransferDetails object reference
-    friend void operator|( PUP::er& p, TransferDetails& i ) { i.pup(p); }
-    //@}
-
-  private:
-    //! The ID of my first chunk (used for collision detection library)
-    int m_firstchunk;
-    //! Pointer to element connectivity
-    std::vector< std::size_t >* m_inpoel;
-    //! Pointer to point coordinates
-    tk::UnsMesh::Coords* m_coord;
-    //! Pointer to solution in mesh nodes
-    tk::Fields* m_u;
-
-    //! The number of messages sent by the dest mesh
-    int m_numsent;
-    //! The number of messages received by the dest mesh
-    int m_numreceived;
-    //! Called once the transfer is complete (m_numsent == m_numreceived)
-    CkCallback m_donecb;
-
-    //! Initialize dest mesh solution with background data
-    void background();
-
-    //! Contribute vertex information to the collsion detection library
-    void collideVertices();
-
-    //! Contribute tet information to the collision detection library
-    void collideTets() const;
-};
-
-} // exam2m::
-
-#endif // TransferDetails_h
+  return s;
+}
+
+std::vector< std::array< tk::real, 3 > >
+TransportProblemCylVortex::prescribedVelocity( ncomp_t ncomp,
+  tk::real x, tk::real y, tk::real, tk::real t )
+// *****************************************************************************
+//! Assign prescribed velocity at a point
+//! \param[in] ncomp Number of components in this transport equation
+//! \param[in] x x coordinate at which to assign velocity
+//! \param[in] y y coordinate at which to assign velocity
+//! \param[in] t time at which to assign velocity
+//! \return Velocity assigned to all vertices of a tetrehedron, size:
+//!   ncomp * ndim = [ncomp][3]
+// *****************************************************************************
+{
+  std::vector< std::array< tk::real, 3 > > vel( ncomp );
+
+  auto pi = 4.0 * std::atan(1.0);
+  for (ncomp_t c=0; c<ncomp; ++c) {
+    vel[c][0] = - 2.0*std::cos(t*pi/4.0) * std::pow(std::sin(pi*x), 2)
+      * std::sin(pi*y) * std::cos(pi*y);
+    vel[c][1] = 2.0*std::cos(t*pi/4.0) * std::pow(std::sin(pi*y), 2)
+      * std::sin(pi*x) * std::cos(pi*x);
+    vel[c][2] = 0.0;
+  }
+
+  return vel;
+}
 
diff --git a/Debug/cppcheck/9.html b/Debug/cppcheck/9.html index 07f50e2bfe03..be0e993b9b9e 100644 --- a/Debug/cppcheck/9.html +++ b/Debug/cppcheck/9.html @@ -152,12 +152,12 @@
  1
@@ -357,204 +357,336 @@ 

Cppcheck report - [

// *****************************************************************************
+198
+199
+200
+201
+202
+203
+204
+205
+206
+207
+208
+209
+210
+211
+212
+213
+214
+215
+216
+217
+218
+219
+220
+221
+222
+223
+224
+225
+226
+227
+228
+229
+230
+231
+232
+233
+234
+235
+236
+237
+238
+239
+240
+241
+242
+243
+244
+245
+246
+247
+248
+249
+250
+251
+252
+253
+254
+255
+256
+257
+258
+259
+260
+261
+262
+263
+264
// *****************************************************************************
 /*!
-  \file      src/Base/TaggedTuple.hpp
+  \file      src/LinearSolver/CSR.cpp
   \copyright 2012-2015 J. Bakosi,
              2016-2018 Los Alamos National Security, LLC.,
              2019-2021 Triad National Security, LLC.
              All rights reserved. See the LICENSE file for details.
-  \brief     Tagged tuple allowing tag-based access
-  \details   Tagged tuple allowing tag-based access. This is very much like
-    [std::tuple](http://en.cppreference.com/w/cpp/utility/tuple), but instead of
-    having to index the elements by integers, it allows access by a tag, which
-    can be an empty struct with a unique name. Credit goes to
-    ecatmur_at_stackoverflow.com, for more details, see
-    http://stackoverflow.com/questions/13065166/c11-tagged-tuple. For tags, see
-    Control/Tags.h. Tagged tuples are extensively used for transferring data
-    from the parser to an internal data structure in a type-save manner, which
-    is a tagged tuple containing a hierarchy of various containers. As an
-    example on how tagged tuples are used for parsing an input file, see
-    Control/Inciter/InputDeck/InputDeck.h. Another way to use a tagged tuple is
-    a compile-time associated container between tags and an arbitrary type.
-*/
-// *****************************************************************************
-#ifndef TaggedTuple_h
-#define TaggedTuple_h
-
-#include <type_traits>
-#include <tuple>
-
-#include <brigand/adapted/tuple.hpp>
-
-#include "NoWarning/any.hpp"
-#include "NoWarning/partition.hpp"
-#include "NoWarning/index_of.hpp"
+  \brief     Compressed sparse row (CSR) storage for a sparse matrix
+  \details   Compressed sparse row (CSR) storage for a sparse matrix.
+*/
+// *****************************************************************************
+
+#include "Exception.hpp"
+#include "CSR.hpp"
+
+using tk::CSR;
+
+CSR::CSR( std::size_t nc,
+          const std::pair< std::vector< std::size_t >,
+                           std::vector< std::size_t > >& psup )
+try :<--- syntax error: keyword 'try' is not allowed in global scope
+  ncomp( nc ),
+  rnz( psup.second.size()-1 ),
+  ia( rnz.size()*ncomp+1 )
+// *****************************************************************************
+//  Constructor: Create a CSR symmetric matrix with ncomp scalar components per
+//  non-zero matrix entry, storing only the upper triangular part
+//! \param[in] nc Number of scalar components (degrees of freedom)
+//! \param[in] psup Points surrounding points of mesh graph, see tk::genPsup
+// *****************************************************************************
+{
+  Assert( ncomp > 0, "Sparse matrix ncomp must be positive" );
+  Assert( rnz.size() > 0, "Sparse matrix size must be positive" );
 
-#include "PUPUtil.hpp"
-#include "Exception.hpp"
+  const auto& psup1 = psup.first;
+  const auto& psup2 = psup.second;
 
-namespace tag {
-//! Printable tag for TaggedTuple that returns its name
-#define DEFTAG(n) struct n { static const char* name() { return #n; } }
-} // tag::
-
-namespace tk {
-
-//! \brief Tagged tuple, allowing tag-based access
-//! \details "Tag" here is any type, but mostly an empty struct with a good name
-//!   for the data member
-//! \tparam List Type list as brigand::list
-//! \see https://stackoverflow.com/a/42988897
-//! \see https://gist.github.com/underdoeg/4c5c616c1ad4cbb718f787eefcab902d
-template< class List >
-class TaggedTuple{
-
-  private:
-    //! Generate index for every 2nd type of a type list
-    template< typename T >
-    using is_odd = brigand::size_t< (brigand::index_of<List,T>::value%2) != 0 >;
+  // Calculate number of nonzeros in each block row (rnz), total number of
+  // nonzeros (nnz), and fill in row indices (ia)
+  std::size_t nnz, i;
+  for (ia[0]=1, nnz=i=0; i<psup2.size()-1; ++i) {
+    // add up and store nonzeros of row i (only upper triangular part)
+    std::size_t j;
+    for (rnz[i]=1, j=psup2[i]+1; j<=psup2[i+1]; ++j)
+      ++rnz[i];
+
+    // add up total number of nonzeros
+    nnz += rnz[i] * ncomp;
+
+    // fill up row index
+    for (std::size_t k=0; k<ncomp; ++k)
+      ia[i*ncomp+k+1] = ia[i*ncomp+k] + rnz[i];
+  }
+
+  // Allocate storage for matrix values and column indices
+  a.resize( nnz, 0.0 );
+  ja.resize( nnz );
 
-    //! Partition a type list into two lists with the even and the odd types
-    using Pair = brigand::partition< List, brigand::bind<is_odd,brigand::_1> >;
-
-    //! List of member types
-    using Data = typename Pair::first_type;
-
-    //! Tuple of member types
-    using Tuple = brigand::as_tuple< Data >;
-
-    //! False-overload for detecting if T is a tagged tuple
-    template< typename T, typename = std::void_t<> >
-    struct is_tagged_tuple_t : std::false_type {};
-
-    //! True-overload for detecting if T is a tagged tuple
-    template< typename T >
-    struct is_tagged_tuple_t< T, std::void_t< typename T::i_am_tagged_tuple > >
-     : std::true_type {};
-
-    //! Member data as a tuple
-    Tuple m_members;
-
-  public:
-    //! List of key-value pairs
-    using PairList = List;
-
-    //! List of keys
-    using Keys = typename Pair::second_type;
-
-    //! Typedef defining self for identifying self
-    using i_am_tagged_tuple = void;
-
-    //! Acces type in tuple behind tag
-    template< typename Tag >
-    using TupleElement =
-      std::tuple_element_t< brigand::index_of<Keys,Tag>::value, Tuple >;
-
-    //! Query if the type behind Tag is a TaggedTuple
-    //! Usage: if constexpr( is_tagged_tuple<Tag>::value ) { ... }
-    template< typename Tag >
-    using is_tagged_tuple =
-      is_tagged_tuple_t< std::decay_t< TupleElement<Tag> > >;
-
-    //! Default constructor
-    explicit TaggedTuple() = default;
-    //! Initializer constructor
-    explicit TaggedTuple( Tuple&& tuple ) : m_members( std::move(tuple) ) {}
-
-    //! Const-ref access to member tuple
-    const Tuple& tuple() const { return m_members; }
-
-    //! Const-reference data member accessor of field of tagged tuple at depth
-    template< typename Tag, typename... Tags >
-    const auto& get() const noexcept {
-      constexpr std::size_t idx = brigand::index_of< Keys, Tag >::value;
-      if constexpr( is_tagged_tuple<Tag>::value and sizeof...(Tags) != 0 )
-        return std::get< idx >( m_members ).template get< Tags... >();
-      else
-        return std::get< idx >( m_members );
-    }
-
-    //! Reference data member accessor of field of tagged tuple at depth
-    template< typename Tag, typename... Tags >
-    auto& get() noexcept {<--- Syntax Error: AST broken, binary operator '>' doesn't have two operands.
-      constexpr std::size_t idx = brigand::index_of< Keys, Tag >::value;
-      if constexpr( is_tagged_tuple<Tag>::value and sizeof...(Tags) != 0 )
-        return std::get< idx >( m_members ).template get< Tags... >();
-      else
-        return std::get< idx >( m_members );
-    }
-
-    //! Convert and store value converting from string at depth
-    //! \param[in] value Value to convert and store
-    template< typename Tag, typename... Tags >
-    void store( const std::string& value ) noexcept {
-      if constexpr( is_tagged_tuple<Tag>::value and sizeof...(Tags) != 0 )
-      {
-        using T = std::remove_reference_t< decltype( get<Tag,Tags...>() ) >;
-        get< Tag, Tags... >() = convert< T >( value );
-      } else {
-        using T = std::remove_reference_t< decltype( get< Tag >() ) >;
-        get< Tag >() = convert< T >( value );
-      }
-    }
-
-    //! Operator == between two TaggedTuple objects
-    //! \tparam L Type list as brigand::list for other TaggedTuple
-    //! \return True if the lhs and rhs equal
-    template< typename L >
-    bool operator== ( const TaggedTuple< L >& t ) const {
-      static_assert( std::is_same_v< L, List >, "Invoking operator== on "
-        "TaggedTuple objects with different typelists" );
-      static_assert( !brigand::any< List,
-        std::is_floating_point<brigand::_1> >::value, "Invoking operator== on "
-        "TaggedTuple objects containing a floating point type is unreliable" );
-      return m_members == t.tuple();
-    }
-
-    //! Operator < between two TaggedTuple objects
-    //! \tparam L Type list as brigand::list for other TaggedTuple
-    //! \return True if lhs < rhs
-    template< typename L >
-    bool operator< ( const TaggedTuple< L >& t ) const {
-      static_assert( std::is_same_v< L, List >, "Invoking operator< on "
-        "TaggedTuple objects with different typelists" );
-      return m_members < t.tuple();
-    }
-
-    //! Return number of tuple entries
-    static constexpr std::size_t size() { return std::tuple_size_v< Tuple >; }
-
-    //! Pack/Unpack
-    /** @name Charm++ pack/unpack serializer member functions */
-    ///@{
-    //! \brief Pack/Unpack serialize member function
-    //! \param[in,out] p Charm++'s PUP::er serializer object reference
-    void pup( PUP::er& p ) { p | m_members; }<--- Parameter 'p' can be declared with const
-    //! \brief Pack/Unpack serialize operator|
-    //! \param[in,out] p Charm++'s PUP::er serializer object reference
-    //! \param[in,out] t TaggedTuple object reference
-    friend void operator|( PUP::er& p, TaggedTuple<List>& t ) { t.pup(p); }
-    //@}
+  // fill column indices
+  for (i=0; i<rnz.size(); ++i)
+    for (std::size_t k=0; k<ncomp; ++k) {
+      auto itmp = i*ncomp+k;
+      ja[ia[itmp]-1] = itmp+1;  // put in column index of diagonal
+      for (std::size_t n=1, j=psup2[i]+1; j<=psup2[i+1]; ++j) {
+        // put in column index of an off-diagonal
+	ja[ia[itmp]-1+(n++)] = psup1[j]*ncomp+k+1;
+      }
+    }
+
+  // (bubble-)sort column indices
+  for (i=0; i<rnz.size(); ++i)
+    for (std::size_t k=0; k<ncomp; ++k)
+      for (std::size_t j=psup2[i]+1; j<=psup2[i+1]; ++j)
+         for (std::size_t l=1; l<rnz[i]; ++l)   // sort column indices of row i
+            for (std::size_t e=0; e<rnz[i]-l; ++e)
+              if (ja[ia[i*ncomp+k]-1+e] > ja[ia[i*ncomp+k]+e])
+	        std::swap( ja[ia[i*ncomp+k]-1+e], ja[ia[i*ncomp+k]+e] );
+
+} // Catch std::exception
+  catch (std::exception& se) {
+    // (re-)throw tk::Excpetion
+    Throw( std::string("RUNTIME ERROR in CSR constructor: ") + se.what() );
+  }
+
+const tk::real&
+CSR::operator()( std::size_t row, std::size_t col, std::size_t pos ) const
+// *****************************************************************************
+//  Return const reference to sparse matrix entry at a position specified
+//  using relative addressing
+//! \param[in] row Block row
+//! \param[in] col Block column
+//! \param[in] pos Position in block
+//! \return Const reference to matrix entry at position specified
+// *****************************************************************************
+{
+  auto rncomp = row * ncomp;
+
+  for (std::size_t n=0, j=ia[rncomp+pos]-1; j<ia[rncomp+pos+1]-1; ++j, ++n)
+    if (col*ncomp+pos+1 == ja[j])
+      return a[ia[rncomp+pos]-1+n];
+
+  Throw("Sparse matrix index not found");
+}
+
+void
+CSR::dirichlet( std::size_t i,
+                const std::vector< std::size_t >& gid,
+                const NodeCommMap& nodecommap,
+                std::size_t pos )
+// *****************************************************************************
+//  Set Dirichlet boundary condition at a node
+//! \param[in] i Local id at which to set Dirichlet BC
+//! \param[in] gid Local->global node id map
+//! \param[in] nodecommap Node communication map with global node ids
+//! \param[in] pos Position in block
+//! \details In parallel there can be multiple contributions to a single node
+//!   on the mesh, and correspondingly, a single matrix row can be partially
+//!   represented on multiple partitions. Setting a Dirichlet BC entails
+//!   zeroing out the row of the matrix and putting 1/N into the diagonal entry,
+//!   where N is the number of partitions that contribute to the mesh node
+//!   (matrix row). As a result, when the matrix participates in a matrix-vector
+//!   product, where the partial contributions across all partitions are
+//!   aggregated, the diagonal will contain 1 after the sum across partitions.
+//! \note Both gid and nodecommap are optional - unused in serial. If nodecommap
+//!   is empty, serial is assumed and gid is unused.
+// *****************************************************************************
+{
+  auto incomp = i * ncomp;
+  auto diag = nodecommap.empty() ? 1.0 : 1.0/tk::count(nodecommap,gid[i]);
+
+  // zero column
+  for (std::size_t r=0; r<rnz.size()*ncomp; ++r)
+    for (std::size_t j=ia[r]-1; j<ia[r+1]-1; ++j)
+      if (incomp+pos+1==ja[j]) a[j] = 0.0;
+
+  // zero row and put in diagonal
+  for (std::size_t j=ia[incomp+pos]-1; j<ia[incomp+pos+1]-1; ++j)
+    if (incomp+pos+1==ja[j]) a[j] = diag; else a[j] = 0.0;
+}
+
+void
+CSR::mult( const std::vector< real >& x,
+           std::vector< real >& r,
+           const std::vector< tk::real >& bcmask ) const
+// *****************************************************************************
+//  Multiply CSR matrix with vector from the right: r = A * x
+//! \param[in] x Vector to multiply matrix with from the right
+//! \param[in] r Result vector of product r = A * x
+//! \param[in] bcmask Dirichlet BC mask
+//! \note This is only complete in serial. In parallel, this computes the own
+//!   contributions to the product, so it must be followed by communication
+//!   combining the rows stored on multiple partitions.
+// *****************************************************************************
+{
+  std::fill( begin(r), end(r), 0.0 );
+
+  for (std::size_t i=0; i<rnz.size()*ncomp; ++i)
+    for (std::size_t j=ia[i]-1; j<ia[i+1]-1; ++j)
+      r[i] += bcmask[i] * a[j] * x[ja[j]-1];
+}
+
+std::ostream&
+CSR::write_stored( std::ostream& os ) const
+// *****************************************************************************
+//  Write out CSR as stored
+//! \param[in,out] os Output stream to write to
+//! \return Updated output stream
+// *****************************************************************************
+{
+  os << "size (npoin) = " << rnz.size() << '\n';
+  os << "ncomp = " << ncomp << '\n';
+  os << "rsize (size*ncomp) = " << rnz.size() * ncomp << '\n';
+  os << "nnz = " << a.size() << '\n';
+
+  std::size_t i;
+
+  os << "rnz[npoin=" << rnz.size() << "] = { ";
+  for (i=0; i<rnz.size()-1; ++i) os << rnz[i] << ", ";
+  os << rnz[i] << " }\n";
 
-    //! Convert/parse string to and return as type given by template argument
-    //! \param[in] str String to convert
-    //! \return A value of type given by the template argument
-    template< typename type >
-    type convert( const std::string& str ) {
-      std::stringstream ss( str );
-      type num;
-      ss >> std::boolalpha >> num;
-      if (ss.fail())
-        Throw( "Failed to convert '" + str +
-               "' to typeid " + typeid(num).name() );
-      return num;
-    }
-};
+  os << "ia[rsize+1=" << rnz.size()*ncomp+1 << "] = { ";
+  for (i=0; i<ia.size()-1; ++i) os << ia[i] << ", ";
+  os << ia[i] << " }\n";
+
+  os << "ja[nnz=" << ja.size() << "] = { ";
+  for (i=0; i<ja.size()-1; ++i) os << ja[i] << ", ";
+  os << ja[i] << " }\n";
+
+  os << "a[nnz=" << a.size() << "] = { ";
+  for (i=0; i<a.size()-1; ++i) os << a[i] << ", ";
+  os << a[i] << " }\n";
+
+  return os;
+}
 
-} // tk::
-
-#endif // TaggedTuple_h
+std::ostream&
+CSR::write_structure( std::ostream& os ) const
+// *****************************************************************************
+//  Write out CSR nonzero structure
+//! \param[in,out] os Output stream to write to
+//! \return Updated output stream
+// *****************************************************************************
+{
+  for (std::size_t i=0; i<rnz.size()*ncomp; ++i) {
+    // leading zeros
+    for (std::size_t j=1; j<ja[ia[i]-1]; ++j) os << ". ";
+    for (std::size_t n=ia[i]-1; n<ia[i+1]-1; ++n) {
+      // zeros between nonzeros
+      if (n>ia[i]-1) for (std::size_t j=ja[n-1]; j<ja[n]-1; ++j) os << ". ";
+      // nonzero
+      os << "o ";
+    }
+    // trailing zeros
+    for (std::size_t j=ja[ia[i+1]-2]; j<rnz.size()*ncomp; ++j) os << ". ";
+    os << '\n';
+  }
+
+  return os;
+}
+
+std::ostream&
+CSR::write_matrix( std::ostream& os ) const
+// *****************************************************************************
+//  Write out CSR as a real matrix
+//! \param[in,out] os Output stream to write to
+//! \return Updated output stream
+// *****************************************************************************
+{
+  for (std::size_t i=0; i<rnz.size()*ncomp; ++i) {
+    for (std::size_t j=1; j<ja[ia[i]-1]; ++j) os << "0\t";
+    for (std::size_t n=ia[i]-1; n<ia[i+1]-1; ++n) {
+      if (n>ia[i]-1) for (std::size_t j=ja[n-1]; j<ja[n]-1; ++j ) os << "0\t";
+      os << a[n] << '\t';
+    }
+    for (std::size_t j=ja[ia[i+1]-2]; j<rnz.size()*ncomp; ++j) os << "0\t";
+    os << '\n';
+  }
+
+  return os;
+}
+
+std::ostream&
+CSR::write_matlab( std::ostream& os ) const
+// *****************************************************************************
+//  Write out CSR in Matlab/Octave format
+//! \param[in,out] os Output stream to write to
+//! \return Updated output stream
+// *****************************************************************************
+{
+  os << "A = [ ";
+  for (std::size_t i=0; i<rnz.size()*ncomp; ++i) {
+    for (std::size_t j=1; j<ja[ia[i]-1]; ++j) os << "0 ";
+    for ( std::size_t n=ia[i]-1; n<ia[i+1]-1; ++n) {
+      if (n > ia[i]-1)
+        for (std::size_t j=ja[n-1]; j<ja[n]-1; ++j) os << "0 ";
+      os << a[n] << ' ';
+    }
+    for (std::size_t j=ja[ia[i+1]-2]; j<rnz.size()*ncomp; ++j) os << "0 ";
+    os << ";\n";
+  }
+  os << "]\n";
+
+  return os;
+}
 
diff --git a/Debug/cppcheck/cppcheck-report.xml b/Debug/cppcheck/cppcheck-report.xml index 93f495b28141..2b99a45df5a1 100644 --- a/Debug/cppcheck/cppcheck-report.xml +++ b/Debug/cppcheck/cppcheck-report.xml @@ -32,6 +32,15 @@ + + + + + + + + + @@ -56,15 +65,6 @@ - - - - - - - - - @@ -77,21 +77,18 @@ - + - + - + - - - @@ -101,24 +98,33 @@ - - + + - - + + - - - + + + + + + + + + + + + @@ -131,86 +137,68 @@ - - - - - - - - - - - - - - - - - - + + + - - - - - - - - - - - + + + + + + + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + @@ -227,20 +215,29 @@ + + + + + + + + + + + + - - - - - + + @@ -275,9 +272,6 @@ - - - @@ -293,14 +287,50 @@ + + + + + + + + + + + + + + + + + + + + + + + + - - + + + + + + + + + + + + + + @@ -317,37 +347,18 @@ - - - - - - - - - - - - - - - - - - - @@ -360,8 +371,8 @@ - - + + @@ -378,78 +389,37 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + - - + + + + + + + + + + + @@ -462,14 +432,23 @@ + + + + + + + + + @@ -482,9 +461,6 @@ - - - @@ -509,9 +485,6 @@ - - - @@ -520,6 +493,9 @@ + + + @@ -564,9 +540,6 @@ - - - @@ -575,103 +548,58 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + - - + + - - + + @@ -685,11 +613,8 @@ - - - - - + + @@ -706,21 +631,12 @@ - - - - - - - - - @@ -730,6 +646,9 @@ + + + @@ -742,6 +661,9 @@ + + + @@ -763,15 +685,45 @@ - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -784,31 +736,42 @@ + + + + + + + + + + + + + + + + + + - - - - - - + + - - + + + + + - - - - - - @@ -824,6 +787,12 @@ + + + + + + @@ -848,6 +817,12 @@ + + + + + + @@ -857,6 +832,31 @@ + + + + + + + + + + + + + + + + + + + + + + + + + @@ -872,12 +872,12 @@ - - - + + + @@ -899,24 +899,21 @@ - - + + - - + + - - + + - - + + - - - @@ -932,39 +929,74 @@ - - - - - + + + - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -974,46 +1006,23 @@ + + + - - - - - - - - - - - - - - - - - - - - - - - - - - - + + - - - + + - - + + - - + + @@ -1021,12 +1030,6 @@ - - - - - - @@ -1042,12 +1045,12 @@ - - - + + + @@ -1063,12 +1066,6 @@ - - - - - - @@ -1140,6 +1137,9 @@ + + + diff --git a/Debug/cppcheck/index.html b/Debug/cppcheck/index.html index 223ad1659851..fad4552d690d 100644 --- a/Debug/cppcheck/index.html +++ b/Debug/cppcheck/index.html @@ -134,11 +134,11 @@

Cppcheck report - [

484constParameter398styleParameter 'p' can be declared with const
/tmp/TeamCity-1/work/5ad443c8abe7fc0a/src/Base/Exception.cpp
49syntaxErrorerrorsyntax error: keyword 'try' is not allowed in global scope
/tmp/TeamCity-1/work/5ad443c8abe7fc0a/src/Base/HashMapReducer.hpp
90knownEmptyContainer398styleIterating over container 'u' that is always empty.
/tmp/TeamCity-1/work/5ad443c8abe7fc0a/src/Base/TaggedTuple.hpp
121internalAstErrorerrorSyntax Error: AST broken, binary operator '>' doesn't have two operands.
174constParameter398styleParameter 'p' can be declared with const
/tmp/TeamCity-1/work/5ad443c8abe7fc0a/src/Base/HashMapReducer.hpp
90knownEmptyContainer398styleIterating over container 'u' that is always empty.
/tmp/TeamCity-1/work/5ad443c8abe7fc0a/src/Base/TaggedTuple.hpp
121internalAstErrorerrorSyntax Error: AST broken, binary operator '>' doesn't have two operands.
174constParameter398styleParameter 'p' can be declared with const
/tmp/TeamCity-1/work/5ad443c8abe7fc0a/src/Base/Types.hpp
37passedByValue398performanceFunction parameter 'k' should be passed by const reference.
38passedByValue398performanceFunction parameter 's' should be passed by const reference.
61passedByValue398performanceFunction parameter 'sDescr' should be passed by const reference.
62passedByValue398performanceFunction parameter 'lDescr' should be passed by const reference.
63passedByValue398performanceFunction parameter 'tDescr' should be passed by const reference.
/tmp/TeamCity-1/work/5ad443c8abe7fc0a/src/Base/Vector.hpp
182throwInNoexceptFunction398errorException thrown in function declared not to throw exceptions.
/tmp/TeamCity-1/work/5ad443c8abe7fc0a/src/Control/HelpFactory.hpp
51constParameter398styleParameter 'p' can be declared with const
84constParameter398styleParameter 'p' can be declared with const
/tmp/TeamCity-1/work/5ad443c8abe7fc0a/src/Control/Inciter/InputDeck/LuaParser.hpp
43passedByValue398performanceFunction parameter 'key' should be passed by const reference.
70passedByValue398performanceFunction parameter 'key' should be passed by const reference.
92passedByValue398performanceFunction parameter 'key' should be passed by const reference.
114passedByValue398performanceFunction parameter 'key' should be passed by const reference.
138passedByValue398performanceFunction parameter 'key' should be passed by const reference.
/tmp/TeamCity-1/work/5ad443c8abe7fc0a/src/Base/Vector.hpp
182throwInNoexceptFunction398errorException thrown in function declared not to throw exceptions.
/tmp/TeamCity-1/work/5ad443c8abe7fc0a/src/Control/HelpFactory.hpp
51constParameter398styleParameter 'p' can be declared with const
84constParameter398styleParameter 'p' can be declared with const
/tmp/TeamCity-1/work/5ad443c8abe7fc0a/src/Control/Inciter/InputDeck/LuaParser.hpp
43passedByValue398performanceFunction parameter 'key' should be passed by const reference.
70passedByValue398performanceFunction parameter 'key' should be passed by const reference.
92passedByValue398performanceFunction parameter 'key' should be passed by const reference.
114passedByValue398performanceFunction parameter 'key' should be passed by const reference.
138passedByValue398performanceFunction parameter 'key' should be passed by const reference.
/tmp/TeamCity-1/work/5ad443c8abe7fc0a/src/Control/Inciter/OutVar.hpp
47constParameter398styleParameter 'p' can be declared with const
/tmp/TeamCity-1/work/5ad443c8abe7fc0a/src/Control/MeshConv/CmdLine/Parser.cpp
119unreadVariable563styleVariable 'oalias' is assigned a value that is never used.
/tmp/TeamCity-1/work/5ad443c8abe7fc0a/src/Control/StatCtr.hpp
325constVariable398styleVariable 'kind' can be declared with const
/tmp/TeamCity-1/work/5ad443c8abe7fc0a/src/IO/ExodusIIMeshReader.cpp
25uninitMemberVar398warningMember variable 'ExodusIIMeshReader::m_nelem' is not initialized in the constructor.
338unreadVariable563styleVariable 'nnode' is assigned a value that is never used.
656useStlAlgorithm398styleConsider using std::transform algorithm instead of a raw loop.
899useStlAlgorithm398styleConsider using std::fill or std::generate algorithm instead of a raw loop.
948useStlAlgorithm398styleConsider using std::fill or std::generate algorithm instead of a raw loop.
/tmp/TeamCity-1/work/5ad443c8abe7fc0a/src/Control/MeshConv/CmdLine/Parser.cpp
119unreadVariable563styleVariable 'oalias' is assigned a value that is never used.
/tmp/TeamCity-1/work/5ad443c8abe7fc0a/src/Control/StatCtr.hpp
325constVariable398styleVariable 'kind' can be declared with const
/tmp/TeamCity-1/work/5ad443c8abe7fc0a/src/IO/ExodusIIMeshReader.cpp
25uninitMemberVar398warningMember variable 'ExodusIIMeshReader::m_nelem' is not initialized in the constructor.
338unreadVariable563styleVariable 'nnode' is assigned a value that is never used.
656useStlAlgorithm398styleConsider using std::transform algorithm instead of a raw loop.
899useStlAlgorithm398styleConsider using std::fill or std::generate algorithm instead of a raw loop.
948useStlAlgorithm398styleConsider using std::fill or std::generate algorithm instead of a raw loop.
/tmp/TeamCity-1/work/5ad443c8abe7fc0a/src/IO/MeshWriter.hpp
47uninitMemberVar398warningMember variable 'MeshWriter::m_filetype' is not initialized in the constructor.
47uninitMemberVar398warningMember variable 'MeshWriter::m_benchmark' is not initialized in the constructor.
47uninitMemberVar398warningMember variable 'MeshWriter::m_nmesh' is not initialized in the constructor.
/tmp/TeamCity-1/work/5ad443c8abe7fc0a/src/IO/Omega_h_MeshReader.cpp
134constParameter398styleParameter 'bface' can be declared with const
149constParameter398styleParameter 'bface' can be declared with const
150constParameter398styleParameter 'faces' can be declared with const
/tmp/TeamCity-1/work/5ad443c8abe7fc0a/src/IO/PDFWriter.cpp
962unreadVariable563styleVariable 'nbix' is assigned a value that is never used.
962unreadVariable563styleVariable 'nbiy' is assigned a value that is never used.
1097unreadVariable563styleVariable 'nbix' is assigned a value that is never used.
1097unreadVariable563styleVariable 'nbiy' is assigned a value that is never used.
1097unreadVariable563styleVariable 'nbiz' is assigned a value that is never used.
/tmp/TeamCity-1/work/5ad443c8abe7fc0a/src/IO/Omega_h_MeshReader.cpp
134constParameter398styleParameter 'bface' can be declared with const
149constParameter398styleParameter 'bface' can be declared with const
150constParameter398styleParameter 'faces' can be declared with const
/tmp/TeamCity-1/work/5ad443c8abe7fc0a/src/IO/PDFWriter.cpp
962unreadVariable563styleVariable 'nbix' is assigned a value that is never used.
962unreadVariable563styleVariable 'nbiy' is assigned a value that is never used.
1097unreadVariable563styleVariable 'nbix' is assigned a value that is never used.
1097unreadVariable563styleVariable 'nbiy' is assigned a value that is never used.
1097unreadVariable563styleVariable 'nbiz' is assigned a value that is never used.
/tmp/TeamCity-1/work/5ad443c8abe7fc0a/src/IO/UGRIDMeshReader.cpp
35unusedVariable563styleUnused variable: s
/tmp/TeamCity-1/work/5ad443c8abe7fc0a/src/Inciter/ALECG.cpp
120stlFindInsert398performanceSearching before insertion is not necessary.
122stlFindInsert398performanceSearching before insertion is not necessary.
160useStlAlgorithm398styleConsider using std::transform algorithm instead of a raw loop.
164useStlAlgorithm398styleConsider using std::transform algorithm instead of a raw loop.
792useStlAlgorithm398styleConsider using std::transform algorithm instead of a raw loop.
/tmp/TeamCity-1/work/5ad443c8abe7fc0a/src/Inciter/AMR/edge_store.hpp
98assertWithSideEffect398warningAssert statement calls a function which may have desired side effects: 'exists'.
/tmp/TeamCity-1/work/5ad443c8abe7fc0a/src/Inciter/ALECG.cpp
120stlFindInsert398performanceSearching before insertion is not necessary.
122stlFindInsert398performanceSearching before insertion is not necessary.
160useStlAlgorithm398styleConsider using std::transform algorithm instead of a raw loop.
164useStlAlgorithm398styleConsider using std::transform algorithm instead of a raw loop.
792useStlAlgorithm398styleConsider using std::transform algorithm instead of a raw loop.
/tmp/TeamCity-1/work/5ad443c8abe7fc0a/src/Inciter/AMR/edge_store.hpp
98assertWithSideEffect398warningAssert statement calls a function which may have desired side effects: 'exists'.
/tmp/TeamCity-1/work/5ad443c8abe7fc0a/src/Inciter/AMR/mesh_adapter.cpp
982constVariable398styleVariable 'element' can be declared with const
1477useStlAlgorithm398styleConsider using std::transform algorithm instead of a raw loop.
/tmp/TeamCity-1/work/5ad443c8abe7fc0a/src/Inciter/AMR/refinement.hpp
34noExplicitConstructor398styleClass 'refinement_t' has a constructor with 1 argument that is not explicit.
57constVariable398styleVariable 'master_element' can be declared with const
907constVariable398styleVariable 'parent' can be declared with const
956useStlAlgorithm398styleConsider using std::find_if algorithm instead of a raw loop.
1014constVariable398styleVariable 'parent' can be declared with const
1131constVariable398styleVariable 'master_element' can be declared with const
/tmp/TeamCity-1/work/5ad443c8abe7fc0a/src/Inciter/AMR/tet_store.hpp
720constVariable398styleVariable 'parent' can be declared with const
/tmp/TeamCity-1/work/5ad443c8abe7fc0a/src/Inciter/DG.cpp
271unreadVariable563styleVariable 'd' is assigned a value that is never used.
1152unusedVariable563styleUnused variable: ndof
1628unreadVariable563styleVariable 'pn' is assigned a value that is never used.
1629unreadVariable563styleVariable 'unprop' is assigned a value that is never used.
1630unreadVariable563styleVariable 'pnprop' is assigned a value that is never used.
2271invalidPrintfArgType_uint686portability%lu in format string (no. 1) requires 'unsigned long' but the argument type is 'std::size_t {aka unsigned long}'.
2272invalidPrintfArgType_uint686portability%lu in format string (no. 1) requires 'unsigned long' but the argument type is 'std::size_t {aka unsigned long}'.
/tmp/TeamCity-1/work/5ad443c8abe7fc0a/src/Inciter/DiagReducer.cpp
72uninitvar457errorUninitialized variable: meshid
73uninitvar457errorUninitialized variable: ncomp
81uninitvar457errorUninitialized variable: mid
82uninitvar457errorUninitialized variable: nc
85uninitvar457errorUninitialized variable: mid
85unreadVariable563styleVariable 'meshid' is assigned a value that is never used.
86uninitvar457errorUninitialized variable: nc
86unreadVariable563styleVariable 'ncomp' is assigned a value that is never used.
91unsignedLessThanZero570styleChecking if unsigned expression 'i' is less than zero.
/tmp/TeamCity-1/work/5ad443c8abe7fc0a/src/Inciter/Discretization.cpp
291useStlAlgorithm398styleConsider using std::copy_if algorithm instead of a raw loop.
331unreadVariable563styleVariable 'fromMesh' is assigned a value that is never used.
332unreadVariable563styleVariable 'toMesh' is assigned a value that is never used.
333unreadVariable563styleVariable 'cb_xfer' is assigned a value that is never used.
336unreadVariable563styleVariable 'fromMesh' is assigned a value that is never used.
337unreadVariable563styleVariable 'toMesh' is assigned a value that is never used.
338unreadVariable563styleVariable 'cb_xfer' is assigned a value that is never used.
361redundantAssignment563styleVariable 'm_ndst' is reassigned a value before the old one has been used.
815useStlAlgorithm398styleConsider using std::accumulate algorithm instead of a raw loop.
/tmp/TeamCity-1/work/5ad443c8abe7fc0a/src/Inciter/ElemDiagnostics.cpp
118funcArgOrderDifferent683warningFunction 'compute_diag' argument order different: declaration 'd, ndofel, nchGhost, geoElem, pIndex, u, un, diag' definition 'd, rdof, nchGhost, geoElem, ndofel, u, un, diag'
187unmatchedSuppressioninformationUnmatched suppression: useStlAlgorithm
224unmatchedSuppressioninformationUnmatched suppression: useStlAlgorithm
/tmp/TeamCity-1/work/5ad443c8abe7fc0a/src/Inciter/FV.cpp
196unreadVariable563styleVariable 'd' is assigned a value that is never used.
823unreadVariable563styleVariable 'pn' is assigned a value that is never used.
824unreadVariable563styleVariable 'unprop' is assigned a value that is never used.
825unreadVariable563styleVariable 'pnprop' is assigned a value that is never used.
/tmp/TeamCity-1/work/5ad443c8abe7fc0a/src/Inciter/AMR/refinement.hpp
34noExplicitConstructor398styleClass 'refinement_t' has a constructor with 1 argument that is not explicit.
57constVariable398styleVariable 'master_element' can be declared with const
907constVariable398styleVariable 'parent' can be declared with const
956useStlAlgorithm398styleConsider using std::find_if algorithm instead of a raw loop.
1014constVariable398styleVariable 'parent' can be declared with const
1131constVariable398styleVariable 'master_element' can be declared with const
/tmp/TeamCity-1/work/5ad443c8abe7fc0a/src/Inciter/AMR/tet_store.hpp
720constVariable398styleVariable 'parent' can be declared with const
/tmp/TeamCity-1/work/5ad443c8abe7fc0a/src/Inciter/DG.cpp
271unreadVariable563styleVariable 'd' is assigned a value that is never used.
1152unusedVariable563styleUnused variable: ndof
1628unreadVariable563styleVariable 'pn' is assigned a value that is never used.
1629unreadVariable563styleVariable 'unprop' is assigned a value that is never used.
1630unreadVariable563styleVariable 'pnprop' is assigned a value that is never used.
2271invalidPrintfArgType_uint686portability%lu in format string (no. 1) requires 'unsigned long' but the argument type is 'std::size_t {aka unsigned long}'.
2272invalidPrintfArgType_uint686portability%lu in format string (no. 1) requires 'unsigned long' but the argument type is 'std::size_t {aka unsigned long}'.
/tmp/TeamCity-1/work/5ad443c8abe7fc0a/src/Inciter/DiagReducer.cpp
72uninitvar457errorUninitialized variable: meshid
73uninitvar457errorUninitialized variable: ncomp
81uninitvar457errorUninitialized variable: mid
82uninitvar457errorUninitialized variable: nc
85uninitvar457errorUninitialized variable: mid
85unreadVariable563styleVariable 'meshid' is assigned a value that is never used.
86uninitvar457errorUninitialized variable: nc
86unreadVariable563styleVariable 'ncomp' is assigned a value that is never used.
91unsignedLessThanZero570styleChecking if unsigned expression 'i' is less than zero.
/tmp/TeamCity-1/work/5ad443c8abe7fc0a/src/Inciter/Discretization.cpp
291useStlAlgorithm398styleConsider using std::copy_if algorithm instead of a raw loop.
331unreadVariable563styleVariable 'fromMesh' is assigned a value that is never used.
332unreadVariable563styleVariable 'toMesh' is assigned a value that is never used.
333unreadVariable563styleVariable 'cb_xfer' is assigned a value that is never used.
336unreadVariable563styleVariable 'fromMesh' is assigned a value that is never used.
337unreadVariable563styleVariable 'toMesh' is assigned a value that is never used.
338unreadVariable563styleVariable 'cb_xfer' is assigned a value that is never used.
361redundantAssignment563styleVariable 'm_ndst' is reassigned a value before the old one has been used.
815useStlAlgorithm398styleConsider using std::accumulate algorithm instead of a raw loop.
/tmp/TeamCity-1/work/5ad443c8abe7fc0a/src/Inciter/ElemDiagnostics.cpp
118funcArgOrderDifferent683warningFunction 'compute_diag' argument order different: declaration 'd, ndofel, nchGhost, geoElem, pIndex, u, un, diag' definition 'd, rdof, nchGhost, geoElem, ndofel, u, un, diag'
187unmatchedSuppressioninformationUnmatched suppression: useStlAlgorithm
224unmatchedSuppressioninformationUnmatched suppression: useStlAlgorithm
/tmp/TeamCity-1/work/5ad443c8abe7fc0a/src/Inciter/FV.cpp
196unreadVariable563styleVariable 'd' is assigned a value that is never used.
823unreadVariable563styleVariable 'pn' is assigned a value that is never used.
824unreadVariable563styleVariable 'unprop' is assigned a value that is never used.
825unreadVariable563styleVariable 'pnprop' is assigned a value that is never used.
/tmp/TeamCity-1/work/5ad443c8abe7fc0a/src/Inciter/FaceData.hpp
76constParameter398styleParameter 'p' can be declared with const
/tmp/TeamCity-1/work/5ad443c8abe7fc0a/src/Inciter/Ghosts.cpp
469unreadVariable563styleVariable 'ncoord' is assigned a value that is never used.
478unreadVariable563styleVariable 'e' is assigned a value that is never used.
551unreadVariable563styleVariable 'ncoord' is assigned a value that is never used.
944unmatchedSuppressioninformationUnmatched suppression: useStlAlgorithm
968unreadVariable563styleVariable 'ip' is assigned a value that is never used.
1053unreadVariable563styleVariable 'nmatch' is assigned a value that is never used.
/tmp/TeamCity-1/work/5ad443c8abe7fc0a/src/Inciter/Ghosts.hpp
101constParameter398styleParameter 'p' can be declared with const
/tmp/TeamCity-1/work/5ad443c8abe7fc0a/src/Inciter/OversetFE.cpp
120stlFindInsert398performanceSearching before insertion is not necessary.
122stlFindInsert398performanceSearching before insertion is not necessary.
828useStlAlgorithm398styleConsider using std::transform algorithm instead of a raw loop.
910useStlAlgorithm398styleConsider using std::transform algorithm instead of a raw loop.
914useStlAlgorithm398styleConsider using std::transform algorithm instead of a raw loop.
1367unreadVariable563styleVariable 'elemsurfnames' is assigned a value that is never used.
/tmp/TeamCity-1/work/5ad443c8abe7fc0a/src/Inciter/Ghosts.cpp
469unreadVariable563styleVariable 'ncoord' is assigned a value that is never used.
478unreadVariable563styleVariable 'e' is assigned a value that is never used.
551unreadVariable563styleVariable 'ncoord' is assigned a value that is never used.
944unmatchedSuppressioninformationUnmatched suppression: useStlAlgorithm
968unreadVariable563styleVariable 'ip' is assigned a value that is never used.
1053unreadVariable563styleVariable 'nmatch' is assigned a value that is never used.
/tmp/TeamCity-1/work/5ad443c8abe7fc0a/src/Inciter/Ghosts.hpp
101constParameter398styleParameter 'p' can be declared with const
/tmp/TeamCity-1/work/5ad443c8abe7fc0a/src/Inciter/OversetFE.cpp
120stlFindInsert398performanceSearching before insertion is not necessary.
122stlFindInsert398performanceSearching before insertion is not necessary.
828useStlAlgorithm398styleConsider using std::transform algorithm instead of a raw loop.
910useStlAlgorithm398styleConsider using std::transform algorithm instead of a raw loop.
914useStlAlgorithm398styleConsider using std::transform algorithm instead of a raw loop.
1367unreadVariable563styleVariable 'elemsurfnames' is assigned a value that is never used.
/tmp/TeamCity-1/work/5ad443c8abe7fc0a/src/Inciter/Partitioner.cpp
425variableScope398styleThe scope of the variable 'added' can be reduced.
/tmp/TeamCity-1/work/5ad443c8abe7fc0a/src/Inciter/Partitioner.hpp
79uninitMemberVar398warningMember variable 'Partitioner::m_meshid' is not initialized in the constructor.
79uninitMemberVar398warningMember variable 'Partitioner::m_ndist' is not initialized in the constructor.
79uninitMemberVar398warningMember variable 'Partitioner::m_nchare' is not initialized in the constructor.
/tmp/TeamCity-1/work/5ad443c8abe7fc0a/src/Inciter/Refiner.cpp
377unreadVariable563styleVariable 'chunksize' is assigned a value that is never used.
388unreadVariable563styleVariable 'B' is assigned a value that is never used.
389unreadVariable563styleVariable 'C' is assigned a value that is never used.
459useStlAlgorithm398styleConsider using std::copy_if algorithm instead of a raw loop.
663unreadVariable563styleVariable 'nlocked' is assigned a value that is never used.
678unreadVariable563styleVariable 'local_needs_refining_orig' is assigned a value that is never used.
679unreadVariable563styleVariable 'local_needs_derefining_orig' is assigned a value that is never used.
680unreadVariable563styleVariable 'local_lock_case_orig' is assigned a value that is never used.
751unreadVariable563styleVariable 'nlocked' is assigned a value that is never used.
989variableScope398styleThe scope of the variable 'V' can be reduced.
1532variableScope398styleThe scope of the variable 'V' can be reduced.
1728redundantIfRemove398styleRedundant checking of STL container element existence before removing it.
1798unreadVariable563styleVariable 'addedNodes' is assigned a value that is never used.
1803unreadVariable563styleVariable 'rid[l]' is assigned a value that is never used.
1930unreadVariable563styleVariable 'c' is assigned a value that is never used.
2008variableScope398styleThe scope of the variable 'facecnt' can be reduced.
/tmp/TeamCity-1/work/5ad443c8abe7fc0a/src/Inciter/Scheme.hpp
174constParameter398styleParameter 'p' can be declared with const
237constParameter398styleParameter 'p' can be declared with const
279constParameter398styleParameter 'p' can be declared with const
/tmp/TeamCity-1/work/5ad443c8abe7fc0a/src/Inciter/Sorter.cpp
127unreadVariable563styleVariable 'scheme' is assigned a value that is never used.
570useStlAlgorithm398styleConsider using std::transform algorithm instead of a raw loop.
/tmp/TeamCity-1/work/5ad443c8abe7fc0a/src/Inciter/Transporter.cpp
165useStlAlgorithm398styleConsider using std::transform algorithm instead of a raw loop.
176useStlAlgorithm398styleConsider using std::transform algorithm instead of a raw loop.
1283uninitvar457errorUninitialized variable: meshid
1287uninitvar457errorUninitialized variable: meshid
1299containerOutOfBounds398errorOut of bounds access in expression 'pdf[1]' because 'pdf' is empty.
1305containerOutOfBounds398errorOut of bounds access in expression 'pdf[2]' because 'pdf' is empty.
1472uninitvar457errorUninitialized variable: meshid
1473uninitvar457errorUninitialized variable: ncomp
1477uninitvar457errorUninitialized variable: meshid
1477unreadVariable563styleVariable 'id' is assigned a value that is never used.
1479uninitvar457errorUninitialized variable: ncomp
1482unsignedLessThanZero570styleChecking if unsigned expression 'i' is less than zero.
1491uninitvar457errorUninitialized variable: meshid
1496unreadVariable563styleVariable 'n' is assigned a value that is never used.
1497unreadVariable563styleVariable 'n' is assigned a value that is never used.
1501uninitvar457errorUninitialized variable: meshid
1513uninitvar457errorUninitialized variable: meshid
1537uninitvar457errorUninitialized variable: meshid
/tmp/TeamCity-1/work/5ad443c8abe7fc0a/src/LinearSolver/CSR.cpp
21syntaxErrorerrorsyntax error: keyword 'try' is not allowed in global scope
/tmp/TeamCity-1/work/5ad443c8abe7fc0a/src/LinearSolver/CSR.hpp
83constParameter398styleParameter 'p' can be declared with const
/tmp/TeamCity-1/work/5ad443c8abe7fc0a/src/LinearSolver/ConjugateGradients.cpp
35uninitMemberVar398warningMember variable 'ConjugateGradients::m_tol' is not initialized in the constructor.
216useStlAlgorithm398styleConsider using std::transform algorithm instead of a raw loop.
/tmp/TeamCity-1/work/5ad443c8abe7fc0a/src/LinearSolver/ConjugateGradients.hpp
66uninitMemberVar398warningMember variable 'ConjugateGradients::m_tol' is not initialized in the constructor.
79uninitMemberVar398warningMember variable 'ConjugateGradients::m_nr' is not initialized in the constructor.
79uninitMemberVar398warningMember variable 'ConjugateGradients::m_nb' is not initialized in the constructor.
79uninitMemberVar398warningMember variable 'ConjugateGradients::m_nq' is not initialized in the constructor.
79uninitMemberVar398warningMember variable 'ConjugateGradients::m_normb' is not initialized in the constructor.
79uninitMemberVar398warningMember variable 'ConjugateGradients::m_it' is not initialized in the constructor.
79uninitMemberVar398warningMember variable 'ConjugateGradients::m_maxit' is not initialized in the constructor.
79uninitMemberVar398warningMember variable 'ConjugateGradients::m_tol' is not initialized in the constructor.
79uninitMemberVar398warningMember variable 'ConjugateGradients::m_rho' is not initialized in the constructor.
79uninitMemberVar398warningMember variable 'ConjugateGradients::m_rho0' is not initialized in the constructor.
79uninitMemberVar398warningMember variable 'ConjugateGradients::m_alpha' is not initialized in the constructor.
79uninitMemberVar398warningMember variable 'ConjugateGradients::m_converged' is not initialized in the constructor.
79uninitMemberVar398warningMember variable 'ConjugateGradients::m_nx' is not initialized in the constructor.
/tmp/TeamCity-1/work/5ad443c8abe7fc0a/src/Main/Inciter.cpp
188unmatchedSuppressioninformationUnmatched suppression: noConstructor
209noExplicitConstructor398styleClass 'Main' has a constructor with 1 argument that is not explicit.
/tmp/TeamCity-1/work/5ad443c8abe7fc0a/src/Main/InciterPrint.hpp
114unusedPrivateFunction398styleUnused private function: 'InciterPrint::PDEName'
/tmp/TeamCity-1/work/5ad443c8abe7fc0a/src/Main/MeshConv.cpp
58unmatchedSuppressioninformationUnmatched suppression: noConstructor
77noExplicitConstructor398styleClass 'Main' has a constructor with 1 argument that is not explicit.
/tmp/TeamCity-1/work/5ad443c8abe7fc0a/src/Inciter/Partitioner.hpp
79uninitMemberVar398warningMember variable 'Partitioner::m_meshid' is not initialized in the constructor.
79uninitMemberVar398warningMember variable 'Partitioner::m_ndist' is not initialized in the constructor.
79uninitMemberVar398warningMember variable 'Partitioner::m_nchare' is not initialized in the constructor.
/tmp/TeamCity-1/work/5ad443c8abe7fc0a/src/Inciter/Refiner.cpp
377unreadVariable563styleVariable 'chunksize' is assigned a value that is never used.
388unreadVariable563styleVariable 'B' is assigned a value that is never used.
389unreadVariable563styleVariable 'C' is assigned a value that is never used.
459useStlAlgorithm398styleConsider using std::copy_if algorithm instead of a raw loop.
663unreadVariable563styleVariable 'nlocked' is assigned a value that is never used.
678unreadVariable563styleVariable 'local_needs_refining_orig' is assigned a value that is never used.
679unreadVariable563styleVariable 'local_needs_derefining_orig' is assigned a value that is never used.
680unreadVariable563styleVariable 'local_lock_case_orig' is assigned a value that is never used.
751unreadVariable563styleVariable 'nlocked' is assigned a value that is never used.
989variableScope398styleThe scope of the variable 'V' can be reduced.
1532variableScope398styleThe scope of the variable 'V' can be reduced.
1728redundantIfRemove398styleRedundant checking of STL container element existence before removing it.
1798unreadVariable563styleVariable 'addedNodes' is assigned a value that is never used.
1803unreadVariable563styleVariable 'rid[l]' is assigned a value that is never used.
1930unreadVariable563styleVariable 'c' is assigned a value that is never used.
2008variableScope398styleThe scope of the variable 'facecnt' can be reduced.
/tmp/TeamCity-1/work/5ad443c8abe7fc0a/src/Inciter/Scheme.hpp
174constParameter398styleParameter 'p' can be declared with const
237constParameter398styleParameter 'p' can be declared with const
279constParameter398styleParameter 'p' can be declared with const
/tmp/TeamCity-1/work/5ad443c8abe7fc0a/src/Inciter/Sorter.cpp
127unreadVariable563styleVariable 'scheme' is assigned a value that is never used.
570useStlAlgorithm398styleConsider using std::transform algorithm instead of a raw loop.
/tmp/TeamCity-1/work/5ad443c8abe7fc0a/src/Inciter/Transporter.cpp
165useStlAlgorithm398styleConsider using std::transform algorithm instead of a raw loop.
176useStlAlgorithm398styleConsider using std::transform algorithm instead of a raw loop.
1283uninitvar457errorUninitialized variable: meshid
1287uninitvar457errorUninitialized variable: meshid
1299containerOutOfBounds398errorOut of bounds access in expression 'pdf[1]' because 'pdf' is empty.
1305containerOutOfBounds398errorOut of bounds access in expression 'pdf[2]' because 'pdf' is empty.
1472uninitvar457errorUninitialized variable: meshid
1473uninitvar457errorUninitialized variable: ncomp
1477uninitvar457errorUninitialized variable: meshid
1477unreadVariable563styleVariable 'id' is assigned a value that is never used.
1479uninitvar457errorUninitialized variable: ncomp
1482unsignedLessThanZero570styleChecking if unsigned expression 'i' is less than zero.
1491uninitvar457errorUninitialized variable: meshid
1496unreadVariable563styleVariable 'n' is assigned a value that is never used.
1497unreadVariable563styleVariable 'n' is assigned a value that is never used.
1501uninitvar457errorUninitialized variable: meshid
1513uninitvar457errorUninitialized variable: meshid
1537uninitvar457errorUninitialized variable: meshid
/tmp/TeamCity-1/work/5ad443c8abe7fc0a/src/LinearSolver/CSR.cpp
21syntaxErrorerrorsyntax error: keyword 'try' is not allowed in global scope
/tmp/TeamCity-1/work/5ad443c8abe7fc0a/src/LinearSolver/CSR.hpp
83constParameter398styleParameter 'p' can be declared with const
/tmp/TeamCity-1/work/5ad443c8abe7fc0a/src/LinearSolver/ConjugateGradients.cpp
35uninitMemberVar398warningMember variable 'ConjugateGradients::m_tol' is not initialized in the constructor.
216useStlAlgorithm398styleConsider using std::transform algorithm instead of a raw loop.
/tmp/TeamCity-1/work/5ad443c8abe7fc0a/src/LinearSolver/ConjugateGradients.hpp
66uninitMemberVar398warningMember variable 'ConjugateGradients::m_tol' is not initialized in the constructor.
79uninitMemberVar398warningMember variable 'ConjugateGradients::m_nr' is not initialized in the constructor.
79uninitMemberVar398warningMember variable 'ConjugateGradients::m_nb' is not initialized in the constructor.
79uninitMemberVar398warningMember variable 'ConjugateGradients::m_nq' is not initialized in the constructor.
79uninitMemberVar398warningMember variable 'ConjugateGradients::m_normb' is not initialized in the constructor.
79uninitMemberVar398warningMember variable 'ConjugateGradients::m_it' is not initialized in the constructor.
79uninitMemberVar398warningMember variable 'ConjugateGradients::m_maxit' is not initialized in the constructor.
79uninitMemberVar398warningMember variable 'ConjugateGradients::m_tol' is not initialized in the constructor.
79uninitMemberVar398warningMember variable 'ConjugateGradients::m_rho' is not initialized in the constructor.
79uninitMemberVar398warningMember variable 'ConjugateGradients::m_rho0' is not initialized in the constructor.
79uninitMemberVar398warningMember variable 'ConjugateGradients::m_alpha' is not initialized in the constructor.
79uninitMemberVar398warningMember variable 'ConjugateGradients::m_converged' is not initialized in the constructor.
79uninitMemberVar398warningMember variable 'ConjugateGradients::m_nx' is not initialized in the constructor.
/tmp/TeamCity-1/work/5ad443c8abe7fc0a/src/Main/Inciter.cpp
188unmatchedSuppressioninformationUnmatched suppression: noConstructor
209noExplicitConstructor398styleClass 'Main' has a constructor with 1 argument that is not explicit.
/tmp/TeamCity-1/work/5ad443c8abe7fc0a/src/Main/InciterPrint.hpp
114unusedPrivateFunction398styleUnused private function: 'InciterPrint::PDEName'
/tmp/TeamCity-1/work/5ad443c8abe7fc0a/src/Main/MeshConv.cpp
58unmatchedSuppressioninformationUnmatched suppression: noConstructor
77noExplicitConstructor398styleClass 'Main' has a constructor with 1 argument that is not explicit.
/tmp/TeamCity-1/work/5ad443c8abe7fc0a/src/Main/MeshConvDriver.cpp
40useInitializationList398performanceVariable 'm_input' is assigned in constructor body. Consider performing initialization in initialization list.
42useInitializationList398performanceVariable 'm_output' is assigned in constructor body. Consider performing initialization in initialization list.
/tmp/TeamCity-1/work/5ad443c8abe7fc0a/src/Main/UnitTest.cpp
120unmatchedSuppressioninformationUnmatched suppression: noConstructor
142noExplicitConstructor398styleClass 'Main' has a constructor with 1 argument that is not explicit.
/tmp/TeamCity-1/work/5ad443c8abe7fc0a/src/Main/UnitTest.cpp
120unmatchedSuppressioninformationUnmatched suppression: noConstructor
142noExplicitConstructor398styleClass 'Main' has a constructor with 1 argument that is not explicit.
/tmp/TeamCity-1/work/5ad443c8abe7fc0a/src/Mesh/DerivedData.cpp
305constVariable398styleVariable 'esup1' can be declared with const
306constVariable398styleVariable 'esup2' can be declared with const
1175unreadVariable563styleVariable 'nnpe' is assigned a value that is never used.
1175unreadVariable563styleVariable 'nnpf' is assigned a value that is never used.
1245unreadVariable563styleVariable 'tag' is assigned a value that is never used.
/tmp/TeamCity-1/work/5ad443c8abe7fc0a/src/Mesh/Reorder.cpp
157useStlAlgorithm398styleConsider using std::transform algorithm instead of a raw loop.
/tmp/TeamCity-1/work/5ad443c8abe7fc0a/src/PDE/CompFlow/CGCompFlow.hpp
722unreadVariable563styleVariable 'steady' is assigned a value that is never used.
866constParameter398styleParameter 'U' can be declared with const
1494constParameter398styleParameter 'R' can be declared with const
/tmp/TeamCity-1/work/5ad443c8abe7fc0a/src/PDE/CompFlow/DGCompFlow.hpp
299unreadVariable563styleVariable 'nelem' is assigned a value that is never used.
637unreadVariable563styleVariable 'dSV_l' is assigned a value that is never used.
754unreadVariable563styleVariable 'dgp' is assigned a value that is never used.
1094knownConditionTrueFalse571styleCondition 'fM>-1' is always true
1094knownConditionTrueFalse570styleCondition 'fM<0' is always false
1106knownConditionTrueFalse571styleCondition 'fM>=0' is always true
1158unreadVariable563styleVariable 'ndof' is assigned a value that is never used.
/tmp/TeamCity-1/work/5ad443c8abe7fc0a/src/PDE/ConfigureCompFlow.cpp
76unreadVariable563styleVariable 'c' is assigned a value that is never used.
159useStlAlgorithm398styleConsider using std::transform algorithm instead of a raw loop.
/tmp/TeamCity-1/work/5ad443c8abe7fc0a/src/PDE/ConfigureMultiMat.cpp
/tmp/TeamCity-1/work/5ad443c8abe7fc0a/src/Mesh/Reorder.cpp
157useStlAlgorithm398styleConsider using std::transform algorithm instead of a raw loop.
/tmp/TeamCity-1/work/5ad443c8abe7fc0a/src/PDE/CompFlow/CGCompFlow.hpp
722unreadVariable563styleVariable 'steady' is assigned a value that is never used.
866constParameter398styleParameter 'U' can be declared with const
1494constParameter398styleParameter 'R' can be declared with const
/tmp/TeamCity-1/work/5ad443c8abe7fc0a/src/PDE/CompFlow/DGCompFlow.hpp
299unreadVariable563styleVariable 'nelem' is assigned a value that is never used.
637unreadVariable563styleVariable 'dSV_l' is assigned a value that is never used.
754unreadVariable563styleVariable 'dgp' is assigned a value that is never used.
1094knownConditionTrueFalse571styleCondition 'fM>-1' is always true
1094knownConditionTrueFalse570styleCondition 'fM<0' is always false
1106knownConditionTrueFalse571styleCondition 'fM>=0' is always true
1158unreadVariable563styleVariable 'ndof' is assigned a value that is never used.
/tmp/TeamCity-1/work/5ad443c8abe7fc0a/src/PDE/ConfigureCompFlow.cpp
76unreadVariable563styleVariable 'c' is assigned a value that is never used.
/tmp/TeamCity-1/work/5ad443c8abe7fc0a/src/PDE/ConfigureTransport.cpp
74unreadVariable563styleVariable 'c' is assigned a value that is never used.
/tmp/TeamCity-1/work/5ad443c8abe7fc0a/src/PDE/DGPDE.hpp
65unreadVariable563styleVariable 'cfg' is assigned a value that is never used.
159useStlAlgorithm398styleConsider using std::transform algorithm instead of a raw loop.
/tmp/TeamCity-1/work/5ad443c8abe7fc0a/src/PDE/ConfigureMultiMat.cpp
76unreadVariable563styleVariable 'c' is assigned a value that is never used.
/tmp/TeamCity-1/work/5ad443c8abe7fc0a/src/PDE/ConfigureTransport.cpp
74unreadVariable563styleVariable 'c' is assigned a value that is never used.
/tmp/TeamCity-1/work/5ad443c8abe7fc0a/src/PDE/DGPDE.hpp
65unreadVariable563styleVariable 'cfg' is assigned a value that is never used.
/tmp/TeamCity-1/work/5ad443c8abe7fc0a/src/PDE/EoS/EOS.hpp
118constParameter398styleParameter 'p' can be declared with const
/tmp/TeamCity-1/work/5ad443c8abe7fc0a/src/PDE/EoS/JWL.cpp
365knownConditionTrueFalse570styleCondition 'idebug==1' is always false
/tmp/TeamCity-1/work/5ad443c8abe7fc0a/src/PDE/EoS/JWL.cpp
365knownConditionTrueFalse570styleCondition 'idebug==1' is always false
/tmp/TeamCity-1/work/5ad443c8abe7fc0a/src/PDE/Integrate/Basis.cpp
239duplicateAssignExpression398styleSame expression used in consecutive assignments of 'db5dxi2' and 'db5dxi3'.
/tmp/TeamCity-1/work/5ad443c8abe7fc0a/src/PDE/Integrate/Boundary.cpp
164constParameter398styleParameter 'unk' can be declared with const
/tmp/TeamCity-1/work/5ad443c8abe7fc0a/src/PDE/Integrate/Mass.cpp
32unreadVariable563styleVariable 'nelem' is assigned a value that is never used.
/tmp/TeamCity-1/work/5ad443c8abe7fc0a/src/PDE/Integrate/MultiMatTerms.cpp
596constParameter398styleParameter 'R' can be declared with const
887unreadVariable563styleVariable 'rho' is assigned a value that is never used.
889unreadVariable563styleVariable 'rho' is assigned a value that is never used.
/tmp/TeamCity-1/work/5ad443c8abe7fc0a/src/PDE/Integrate/MultiMatTerms.cpp
596constParameter398styleParameter 'R' can be declared with const
887unreadVariable563styleVariable 'rho' is assigned a value that is never used.
889unreadVariable563styleVariable 'rho' is assigned a value that is never used.
/tmp/TeamCity-1/work/5ad443c8abe7fc0a/src/PDE/Integrate/SolidTerms.cpp
169constParameter398styleParameter 'R' can be declared with const
/tmp/TeamCity-1/work/5ad443c8abe7fc0a/src/PDE/Integrate/Source.cpp
149constParameter398styleParameter 'R' can be declared with const
/tmp/TeamCity-1/work/5ad443c8abe7fc0a/src/PDE/Integrate/Surface.cpp
93unreadVariable563styleVariable 'ncomp' is assigned a value that is never used.
94unreadVariable563styleVariable 'nprim' is assigned a value that is never used.
203unreadVariable563styleVariable 'wt' is assigned a value that is never used.
243constParameter398styleParameter 'R' can be declared with const
396unreadVariable563styleVariable 'ncomp' is assigned a value that is never used.
397unreadVariable563styleVariable 'nprim' is assigned a value that is never used.
/tmp/TeamCity-1/work/5ad443c8abe7fc0a/src/PDE/Limiter.cpp
188unusedVariable563styleUnused variable: unk
188unusedVariable563styleUnused variable: prim
1465variableScope398styleThe scope of the variable 'phi_dir' can be reduced.
1473redundantAssignment563styleVariable 'phi_dir' is reassigned a value before the old one has been used.
1497constParameter398styleParameter 'U' can be declared with const
1889redundantAssignment563styleVariable 'phi_rho' is reassigned a value before the old one has been used.
1895redundantAssignment563styleVariable 'phi_rhoe' is reassigned a value before the old one has been used.
1904redundantAssignment563styleVariable 'phi_pre' is reassigned a value before the old one has been used.
1938redundantAssignment563styleVariable 'phi_rho' is reassigned a value before the old one has been used.
1944redundantAssignment563styleVariable 'phi_rhoe' is reassigned a value before the old one has been used.
1953redundantAssignment563styleVariable 'phi_pre' is reassigned a value before the old one has been used.
2116redundantAssignment563styleVariable 'phi_pre' is reassigned a value before the old one has been used.
2238unreadVariable563styleVariable 'ncomp' is assigned a value that is never used.
2239unreadVariable563styleVariable 'nprim' is assigned a value that is never used.
/tmp/TeamCity-1/work/5ad443c8abe7fc0a/src/PDE/MultiMat/DGMultiMat.hpp
95shadowFunction398styleLocal variable 'nmat' shadows outer function
131shadowFunction398styleLocal variable 'nmat' shadows outer function
155shadowFunction398styleLocal variable 'nmat' shadows outer function
173shadowFunction398styleLocal variable 'nmat' shadows outer function
286shadowFunction398styleLocal variable 'nmat' shadows outer function
326constParameter398styleParameter 'unk' can be declared with const
327constParameter398styleParameter 'rho0mat' can be declared with const
332shadowFunction398styleLocal variable 'nmat' shadows outer function
379constParameter398styleParameter 'unk' can be declared with const
389shadowFunction398styleLocal variable 'nmat' shadows outer function
441constParameter398styleParameter 'prim' can be declared with const
444unreadVariable563styleVariable 'rdof' is assigned a value that is never used.
445unreadVariable563styleVariable 'ndof' is assigned a value that is never used.
446shadowFunction398styleLocal variable 'nmat' shadows outer function
446unreadVariable563styleVariable 'nmat' is assigned a value that is never used.
574shadowFunction398styleLocal variable 'nmat' shadows outer function
574unreadVariable563styleVariable 'nmat' is assigned a value that is never used.
611unreadVariable563styleVariable 'is_p0p1' is assigned a value that is never used.
613unreadVariable563styleVariable 'is_p0p1' is assigned a value that is never used.
615unreadVariable563styleVariable 'nelem' is assigned a value that is never used.
616shadowFunction398styleLocal variable 'nmat' shadows outer function
616unreadVariable563styleVariable 'nmat' is assigned a value that is never used.
706shadowFunction398styleLocal variable 'nmat' shadows outer function
756shadowFunction398styleLocal variable 'nmat' shadows outer function
756unreadVariable563styleVariable 'nmat' is assigned a value that is never used.
779shadowFunction398styleLocal variable 'nmat' shadows outer function
831shadowFunction398styleLocal variable 'nmat' shadows outer function
960shadowFunction398styleLocal variable 'nmat' shadows outer function
994shadowFunction398styleLocal variable 'nmat' shadows outer function
1031constParameter398styleParameter 'R' can be declared with const
1033unreadVariable563styleVariable 'ndof' is assigned a value that is never used.
1034unreadVariable563styleVariable 'rdof' is assigned a value that is never used.
1035shadowFunction398styleLocal variable 'nmat' shadows outer function
1035unreadVariable563styleVariable 'nmat' is assigned a value that is never used.
1036unreadVariable563styleVariable 'intsharp' is assigned a value that is never used.
1059shadowFunction398styleLocal variable 'nprim' shadows outer function
1223shadowFunction398styleLocal variable 'nmat' shadows outer function
1259shadowFunction398styleLocal variable 'nmat' shadows outer function
1295shadowFunction398styleLocal variable 'nmat' shadows outer function
1344shadowFunction398styleLocal variable 'nmat' shadows outer function
1375shadowFunction398styleLocal variable 'nmat' shadows outer function
1409shadowFunction398styleLocal variable 'nmat' shadows outer function
1434shadowFunction398styleLocal variable 'nmat' shadows outer function
/tmp/TeamCity-1/work/5ad443c8abe7fc0a/src/PDE/MultiMat/FVMultiMat.hpp
91shadowFunction398styleLocal variable 'nmat' shadows outer function
204constParameter398styleParameter 'l' can be declared with const
221constParameter398styleParameter 'prim' can be declared with const
224unreadVariable563styleVariable 'rdof' is assigned a value that is never used.
225shadowFunction398styleLocal variable 'nmat' shadows outer function
225unreadVariable563styleVariable 'nmat' is assigned a value that is never used.
296shadowFunction398styleLocal variable 'nmat' shadows outer function
296unreadVariable563styleVariable 'nmat' is assigned a value that is never used.
331unreadVariable563styleVariable 'nelem' is assigned a value that is never used.
332shadowFunction398styleLocal variable 'nmat' shadows outer function
332unreadVariable563styleVariable 'nmat' is assigned a value that is never used.
397shadowFunction398styleLocal variable 'nmat' shadows outer function
435shadowFunction398styleLocal variable 'nmat' shadows outer function
435unreadVariable563styleVariable 'nmat' is assigned a value that is never used.
475shadowFunction398styleLocal variable 'nmat' shadows outer function
553shadowFunction398styleLocal variable 'nmat' shadows outer function
573shadowFunction398styleLocal variable 'nmat' shadows outer function
609shadowFunction398styleLocal variable 'nmat' shadows outer function
632shadowFunction398styleLocal variable 'nmat' shadows outer function
654shadowFunction398styleLocal variable 'nmat' shadows outer function
704shadowFunction398styleLocal variable 'nmat' shadows outer function
735shadowFunction398styleLocal variable 'nmat' shadows outer function
762shadowFunction398styleLocal variable 'nmat' shadows outer function
764shadowFunction398styleLocal variable 'nprim' shadows outer function
766unreadVariable563styleVariable 'ugp' is assigned a value that is never used.
766unreadVariable563styleVariable 'pgp' is assigned a value that is never used.
831shadowFunction398styleLocal variable 'nmat' shadows outer function
855shadowFunction398styleLocal variable 'nmat' shadows outer function
855unreadVariable563styleVariable 'nmat' is assigned a value that is never used.
/tmp/TeamCity-1/work/5ad443c8abe7fc0a/src/PDE/Integrate/Surface.cpp
93unreadVariable563styleVariable 'ncomp' is assigned a value that is never used.
94unreadVariable563styleVariable 'nprim' is assigned a value that is never used.
203unreadVariable563styleVariable 'wt' is assigned a value that is never used.
243constParameter398styleParameter 'R' can be declared with const
396unreadVariable563styleVariable 'ncomp' is assigned a value that is never used.
397unreadVariable563styleVariable 'nprim' is assigned a value that is never used.
/tmp/TeamCity-1/work/5ad443c8abe7fc0a/src/PDE/Limiter.cpp
188unusedVariable563styleUnused variable: unk
188unusedVariable563styleUnused variable: prim
1465variableScope398styleThe scope of the variable 'phi_dir' can be reduced.
1473redundantAssignment563styleVariable 'phi_dir' is reassigned a value before the old one has been used.
1497constParameter398styleParameter 'U' can be declared with const
1889redundantAssignment563styleVariable 'phi_rho' is reassigned a value before the old one has been used.
1895redundantAssignment563styleVariable 'phi_rhoe' is reassigned a value before the old one has been used.
1904redundantAssignment563styleVariable 'phi_pre' is reassigned a value before the old one has been used.
1938redundantAssignment563styleVariable 'phi_rho' is reassigned a value before the old one has been used.
1944redundantAssignment563styleVariable 'phi_rhoe' is reassigned a value before the old one has been used.
1953redundantAssignment563styleVariable 'phi_pre' is reassigned a value before the old one has been used.
2116redundantAssignment563styleVariable 'phi_pre' is reassigned a value before the old one has been used.
2238unreadVariable563styleVariable 'ncomp' is assigned a value that is never used.
2239unreadVariable563styleVariable 'nprim' is assigned a value that is never used.
/tmp/TeamCity-1/work/5ad443c8abe7fc0a/src/PDE/MultiMat/DGMultiMat.hpp
95shadowFunction398styleLocal variable 'nmat' shadows outer function
131shadowFunction398styleLocal variable 'nmat' shadows outer function
155shadowFunction398styleLocal variable 'nmat' shadows outer function
173shadowFunction398styleLocal variable 'nmat' shadows outer function
286shadowFunction398styleLocal variable 'nmat' shadows outer function
326constParameter398styleParameter 'unk' can be declared with const
327constParameter398styleParameter 'rho0mat' can be declared with const
332shadowFunction398styleLocal variable 'nmat' shadows outer function
379constParameter398styleParameter 'unk' can be declared with const
389shadowFunction398styleLocal variable 'nmat' shadows outer function
441constParameter398styleParameter 'prim' can be declared with const
444unreadVariable563styleVariable 'rdof' is assigned a value that is never used.
445unreadVariable563styleVariable 'ndof' is assigned a value that is never used.
446shadowFunction398styleLocal variable 'nmat' shadows outer function
446unreadVariable563styleVariable 'nmat' is assigned a value that is never used.
574shadowFunction398styleLocal variable 'nmat' shadows outer function
574unreadVariable563styleVariable 'nmat' is assigned a value that is never used.
611unreadVariable563styleVariable 'is_p0p1' is assigned a value that is never used.
613unreadVariable563styleVariable 'is_p0p1' is assigned a value that is never used.
615unreadVariable563styleVariable 'nelem' is assigned a value that is never used.
616shadowFunction398styleLocal variable 'nmat' shadows outer function
616unreadVariable563styleVariable 'nmat' is assigned a value that is never used.
706shadowFunction398styleLocal variable 'nmat' shadows outer function
756shadowFunction398styleLocal variable 'nmat' shadows outer function
756unreadVariable563styleVariable 'nmat' is assigned a value that is never used.
779shadowFunction398styleLocal variable 'nmat' shadows outer function
831shadowFunction398styleLocal variable 'nmat' shadows outer function
960shadowFunction398styleLocal variable 'nmat' shadows outer function
994shadowFunction398styleLocal variable 'nmat' shadows outer function
1031constParameter398styleParameter 'R' can be declared with const
1033unreadVariable563styleVariable 'ndof' is assigned a value that is never used.
1034unreadVariable563styleVariable 'rdof' is assigned a value that is never used.
1035shadowFunction398styleLocal variable 'nmat' shadows outer function
1035unreadVariable563styleVariable 'nmat' is assigned a value that is never used.
1036unreadVariable563styleVariable 'intsharp' is assigned a value that is never used.
1059shadowFunction398styleLocal variable 'nprim' shadows outer function
1223shadowFunction398styleLocal variable 'nmat' shadows outer function
1259shadowFunction398styleLocal variable 'nmat' shadows outer function
1295shadowFunction398styleLocal variable 'nmat' shadows outer function
1344shadowFunction398styleLocal variable 'nmat' shadows outer function
1375shadowFunction398styleLocal variable 'nmat' shadows outer function
1409shadowFunction398styleLocal variable 'nmat' shadows outer function
1434shadowFunction398styleLocal variable 'nmat' shadows outer function
/tmp/TeamCity-1/work/5ad443c8abe7fc0a/src/PDE/MultiMat/FVMultiMat.hpp
91shadowFunction398styleLocal variable 'nmat' shadows outer function
204constParameter398styleParameter 'l' can be declared with const
221constParameter398styleParameter 'prim' can be declared with const
224unreadVariable563styleVariable 'rdof' is assigned a value that is never used.
225shadowFunction398styleLocal variable 'nmat' shadows outer function
225unreadVariable563styleVariable 'nmat' is assigned a value that is never used.
296shadowFunction398styleLocal variable 'nmat' shadows outer function
296unreadVariable563styleVariable 'nmat' is assigned a value that is never used.
331unreadVariable563styleVariable 'nelem' is assigned a value that is never used.
332shadowFunction398styleLocal variable 'nmat' shadows outer function
332unreadVariable563styleVariable 'nmat' is assigned a value that is never used.
397shadowFunction398styleLocal variable 'nmat' shadows outer function
435shadowFunction398styleLocal variable 'nmat' shadows outer function
435unreadVariable563styleVariable 'nmat' is assigned a value that is never used.
475shadowFunction398styleLocal variable 'nmat' shadows outer function
553shadowFunction398styleLocal variable 'nmat' shadows outer function
573shadowFunction398styleLocal variable 'nmat' shadows outer function
609shadowFunction398styleLocal variable 'nmat' shadows outer function
632shadowFunction398styleLocal variable 'nmat' shadows outer function
654shadowFunction398styleLocal variable 'nmat' shadows outer function
704shadowFunction398styleLocal variable 'nmat' shadows outer function
735shadowFunction398styleLocal variable 'nmat' shadows outer function
762shadowFunction398styleLocal variable 'nmat' shadows outer function
764shadowFunction398styleLocal variable 'nprim' shadows outer function
766unreadVariable563styleVariable 'ugp' is assigned a value that is never used.
766unreadVariable563styleVariable 'pgp' is assigned a value that is never used.
831shadowFunction398styleLocal variable 'nmat' shadows outer function
855shadowFunction398styleLocal variable 'nmat' shadows outer function
855unreadVariable563styleVariable 'nmat' is assigned a value that is never used.
/tmp/TeamCity-1/work/5ad443c8abe7fc0a/src/PDE/MultiMat/MiscMultiMatFns.cpp
370variableScope398styleThe scope of the variable 'u' can be reduced.
370variableScope398styleThe scope of the variable 'v' can be reduced.
501unreadVariable563styleVariable 'pgp' is assigned a value that is never used.
568constParameter398styleParameter 'U' can be declared with const
569constParameter398styleParameter 'P' can be declared with const
/tmp/TeamCity-1/work/5ad443c8abe7fc0a/src/PDE/MultiMat/Physics/FVEnergyPill.cpp
77constParameter398styleParameter 'R' can be declared with const
/tmp/TeamCity-1/work/5ad443c8abe7fc0a/src/PDE/MultiMat/Problem/BoxInitialization.hpp
102identicalConditionAfterEarlyExit398warningIdentical condition 'boxenc<=1e-12', second condition is always false
/tmp/TeamCity-1/work/5ad443c8abe7fc0a/src/PDE/MultiMat/Physics/FVEnergyPill.cpp
77constParameter398styleParameter 'R' can be declared with const
/tmp/TeamCity-1/work/5ad443c8abe7fc0a/src/PDE/MultiMat/Problem/BoxInitialization.hpp
102identicalConditionAfterEarlyExit398warningIdentical condition 'boxenc<=1e-12', second condition is always false
/tmp/TeamCity-1/work/5ad443c8abe7fc0a/src/PDE/MultiMat/Problem/ShockDensityWave.cpp
53variableScope398styleThe scope of the variable 'alphamin' can be reduced.
/tmp/TeamCity-1/work/5ad443c8abe7fc0a/src/PDE/PDEStack.hpp
112unreadVariable563styleVariable 'c' is assigned a value that is never used.
/tmp/TeamCity-1/work/5ad443c8abe7fc0a/src/PDE/PDEStack.hpp
112unreadVariable563styleVariable 'c' is assigned a value that is never used.
/tmp/TeamCity-1/work/5ad443c8abe7fc0a/src/PDE/PrefIndicator.cpp
147unreadVariable563styleVariable 'ncomp' is assigned a value that is never used.
227unreadVariable563styleVariable 'state[1]' is assigned a value that is never used.
/tmp/TeamCity-1/work/5ad443c8abe7fc0a/src/PDE/Reconstruction.cpp
139unreadVariable563styleVariable 'nelem' is assigned a value that is never used.
276constParameter398styleParameter 'W' can be declared with const
316constParameter398styleParameter 'W' can be declared with const
397constParameter398styleParameter 'W' can be declared with const
/tmp/TeamCity-1/work/5ad443c8abe7fc0a/src/PDE/Transport/CGTransport.hpp
375unreadVariable563styleVariable 'steady' is assigned a value that is never used.
/tmp/TeamCity-1/work/5ad443c8abe7fc0a/src/PDE/Transport/DGTransport.hpp
239unreadVariable563styleVariable 'nelem' is assigned a value that is never used.
240unreadVariable563styleVariable 'intsharp' is assigned a value that is never used.
388unreadVariable563styleVariable 'ndof' is assigned a value that is never used.
389unreadVariable563styleVariable 'rdof' is assigned a value that is never used.
390unreadVariable563styleVariable 'intsharp' is assigned a value that is never used.
/tmp/TeamCity-1/work/5ad443c8abe7fc0a/src/PDE/Transport/Problem/CylVortex.cpp
38unreadVariable563styleVariable 'vel' is assigned a value that is never used.
/tmp/TeamCity-1/work/5ad443c8abe7fc0a/src/Statistics/BiPDF.hpp
114constParameter398styleParameter 'p' can be declared with const
/tmp/TeamCity-1/work/5ad443c8abe7fc0a/src/Statistics/PDFReducer.cpp
30uninitvar457errorUninitialized variable: meshid
38uninitvar457errorUninitialized variable: meshid
63uninitvar457errorUninitialized variable: meshid
71uninitvar457errorUninitialized variable: mid
74uninitvar457errorUninitialized variable: mid
76containerOutOfBounds398errorOut of bounds access in expression 'updf[i++]' because 'updf' is empty.
76knownEmptyContainer398styleIterating over container 'u' that is always empty.
80uninitvar457errorUninitialized variable: meshid
150containerOutOfBounds398errorOut of bounds access in expression 'updf[i++]' because 'updf' is empty.
150knownEmptyContainer398styleIterating over container 'u' that is always empty.
152containerOutOfBounds398errorOut of bounds access in expression 'bpdf[i++]' because 'bpdf' is empty.
152knownEmptyContainer398styleIterating over container 'b' that is always empty.
154containerOutOfBounds398errorOut of bounds access in expression 'tpdf[i++]' because 'tpdf' is empty.
154knownEmptyContainer398styleIterating over container 't' that is always empty.
/tmp/TeamCity-1/work/5ad443c8abe7fc0a/src/Statistics/TriPDF.hpp
123constParameter398styleParameter 'p' can be declared with const
/tmp/TeamCity-1/work/5ad443c8abe7fc0a/src/Statistics/UniPDF.hpp
115constParameter398styleParameter 'p' can be declared with const
/tmp/TeamCity-1/work/5ad443c8abe7fc0a/src/Transfer/M2MTransfer.hpp
16noExplicitConstructor398styleClass 'LibMain' has a constructor with 1 argument that is not explicit.
24constParameter398styleParameter 'p' can be declared with const
43uninitMemberVar398warningMember variable 'M2MTransfer::current_chunk' is not initialized in the constructor.
/tmp/TeamCity-1/work/5ad443c8abe7fc0a/src/PDE/Reconstruction.cpp
139unreadVariable563styleVariable 'nelem' is assigned a value that is never used.
276constParameter398styleParameter 'W' can be declared with const
316constParameter398styleParameter 'W' can be declared with const
397constParameter398styleParameter 'W' can be declared with const
/tmp/TeamCity-1/work/5ad443c8abe7fc0a/src/PDE/Transport/CGTransport.hpp
375unreadVariable563styleVariable 'steady' is assigned a value that is never used.
/tmp/TeamCity-1/work/5ad443c8abe7fc0a/src/PDE/Transport/DGTransport.hpp
239unreadVariable563styleVariable 'nelem' is assigned a value that is never used.
240unreadVariable563styleVariable 'intsharp' is assigned a value that is never used.
388unreadVariable563styleVariable 'ndof' is assigned a value that is never used.
389unreadVariable563styleVariable 'rdof' is assigned a value that is never used.
390unreadVariable563styleVariable 'intsharp' is assigned a value that is never used.
/tmp/TeamCity-1/work/5ad443c8abe7fc0a/src/PDE/Transport/Problem/CylVortex.cpp
38unreadVariable563styleVariable 'vel' is assigned a value that is never used.
/tmp/TeamCity-1/work/5ad443c8abe7fc0a/src/Statistics/BiPDF.hpp
114constParameter398styleParameter 'p' can be declared with const
/tmp/TeamCity-1/work/5ad443c8abe7fc0a/src/Statistics/PDFReducer.cpp
30uninitvar457errorUninitialized variable: meshid
38uninitvar457errorUninitialized variable: meshid
63uninitvar457errorUninitialized variable: meshid
71uninitvar457errorUninitialized variable: mid
74uninitvar457errorUninitialized variable: mid
76containerOutOfBounds398errorOut of bounds access in expression 'updf[i++]' because 'updf' is empty.
76knownEmptyContainer398styleIterating over container 'u' that is always empty.
80uninitvar457errorUninitialized variable: meshid
150containerOutOfBounds398errorOut of bounds access in expression 'updf[i++]' because 'updf' is empty.
150knownEmptyContainer398styleIterating over container 'u' that is always empty.
152containerOutOfBounds398errorOut of bounds access in expression 'bpdf[i++]' because 'bpdf' is empty.
152knownEmptyContainer398styleIterating over container 'b' that is always empty.
154containerOutOfBounds398errorOut of bounds access in expression 'tpdf[i++]' because 'tpdf' is empty.
154knownEmptyContainer398styleIterating over container 't' that is always empty.
/tmp/TeamCity-1/work/5ad443c8abe7fc0a/src/Statistics/TriPDF.hpp
123constParameter398styleParameter 'p' can be declared with const
/tmp/TeamCity-1/work/5ad443c8abe7fc0a/src/Statistics/UniPDF.hpp
115constParameter398styleParameter 'p' can be declared with const
/tmp/TeamCity-1/work/5ad443c8abe7fc0a/src/Transfer/M2MTransfer.hpp
16noExplicitConstructor398styleClass 'LibMain' has a constructor with 1 argument that is not explicit.
24constParameter398styleParameter 'p' can be declared with const
43uninitMemberVar398warningMember variable 'M2MTransfer::current_chunk' is not initialized in the constructor.
/tmp/TeamCity-1/work/5ad443c8abe7fc0a/src/Transfer/TransferDetails.cpp
38uninitMemberVar398warningMember variable 'TransferDetails::m_inpoel' is not initialized in the constructor.
38uninitMemberVar398warningMember variable 'TransferDetails::m_coord' is not initialized in the constructor.
38uninitMemberVar398warningMember variable 'TransferDetails::m_u' is not initialized in the constructor.
38uninitMemberVar398warningMember variable 'TransferDetails::m_numsent' is not initialized in the constructor.
38uninitMemberVar398warningMember variable 'TransferDetails::m_numreceived' is not initialized in the constructor.
/tmp/TeamCity-1/work/5ad443c8abe7fc0a/src/Transfer/TransferDetails.hpp
29constParameter398styleParameter 'p' can be declared with const
36constParameter398styleParameter 'p' can be declared with const
/tmp/TeamCity-1/work/5ad443c8abe7fc0a/src/Transfer/TransferDetails.hpp
29constParameter398styleParameter 'p' can be declared with const
36constParameter398styleParameter 'p' can be declared with const
diff --git a/Debug/cppcheck/stats.html b/Debug/cppcheck/stats.html index 8e1cef41fb9c..91fbffea9d3c 100644 --- a/Debug/cppcheck/stats.html +++ b/Debug/cppcheck/stats.html @@ -88,55 +88,55 @@

Cppcheck report - [

Top 10 files for error severity, total findings: 34
-   12 
/tmp/TeamCity-1/work/5ad443c8abe7fc0a/src/Inciter/Transporter.cpp
-   10  /tmp/TeamCity-1/work/5ad443c8abe7fc0a/src/Statistics/PDFReducer.cpp
-   6   /tmp/TeamCity-1/work/5ad443c8abe7fc0a/src/Inciter/DiagReducer.cpp
+   12  /tmp/TeamCity-1/work/5ad443c8abe7fc0a/src/Inciter/Transporter.cpp
+   10  /tmp/TeamCity-1/work/5ad443c8abe7fc0a/src/Statistics/PDFReducer.cpp
+   6   /tmp/TeamCity-1/work/5ad443c8abe7fc0a/src/Inciter/DiagReducer.cpp
   2   /tmp/TeamCity-1/work/5ad443c8abe7fc0a/src/Base/ContainerUtil.hpp
-   1   /tmp/TeamCity-1/work/5ad443c8abe7fc0a/src/LinearSolver/CSR.cpp
-   1   /tmp/TeamCity-1/work/5ad443c8abe7fc0a/src/Base/Vector.hpp
-   1   /tmp/TeamCity-1/work/5ad443c8abe7fc0a/src/Base/TaggedTuple.hpp
+   1   /tmp/TeamCity-1/work/5ad443c8abe7fc0a/src/LinearSolver/CSR.cpp
+   1   /tmp/TeamCity-1/work/5ad443c8abe7fc0a/src/Base/Vector.hpp
+   1   /tmp/TeamCity-1/work/5ad443c8abe7fc0a/src/Base/TaggedTuple.hpp
   1   /tmp/TeamCity-1/work/5ad443c8abe7fc0a/src/Base/Exception.cpp

Top 10 files for warning severity, total findings: 30
-   13  /tmp/TeamCity-1/work/5ad443c8abe7fc0a/src/LinearSolver/ConjugateGradients.hpp
+   13  /tmp/TeamCity-1/work/5ad443c8abe7fc0a/src/LinearSolver/ConjugateGradients.hpp
   5   /tmp/TeamCity-1/work/5ad443c8abe7fc0a/src/Transfer/TransferDetails.cpp
-   3   /tmp/TeamCity-1/work/5ad443c8abe7fc0a/src/Inciter/Partitioner.hpp
+   3   /tmp/TeamCity-1/work/5ad443c8abe7fc0a/src/Inciter/Partitioner.hpp
   3   /tmp/TeamCity-1/work/5ad443c8abe7fc0a/src/IO/MeshWriter.hpp
-   1   /tmp/TeamCity-1/work/5ad443c8abe7fc0a/src/Transfer/M2MTransfer.hpp
-   1   /tmp/TeamCity-1/work/5ad443c8abe7fc0a/src/PDE/MultiMat/Problem/BoxInitialization.hpp
-   1   /tmp/TeamCity-1/work/5ad443c8abe7fc0a/src/LinearSolver/ConjugateGradients.cpp
-   1   /tmp/TeamCity-1/work/5ad443c8abe7fc0a/src/Inciter/ElemDiagnostics.cpp
-   1   /tmp/TeamCity-1/work/5ad443c8abe7fc0a/src/Inciter/AMR/edge_store.hpp
-   1   /tmp/TeamCity-1/work/5ad443c8abe7fc0a/src/IO/ExodusIIMeshReader.cpp
+   1   /tmp/TeamCity-1/work/5ad443c8abe7fc0a/src/Transfer/M2MTransfer.hpp
+   1   /tmp/TeamCity-1/work/5ad443c8abe7fc0a/src/PDE/MultiMat/Problem/BoxInitialization.hpp
+   1   /tmp/TeamCity-1/work/5ad443c8abe7fc0a/src/LinearSolver/ConjugateGradients.cpp
+   1   /tmp/TeamCity-1/work/5ad443c8abe7fc0a/src/Inciter/ElemDiagnostics.cpp
+   1   /tmp/TeamCity-1/work/5ad443c8abe7fc0a/src/Inciter/AMR/edge_store.hpp
+   1   /tmp/TeamCity-1/work/5ad443c8abe7fc0a/src/IO/ExodusIIMeshReader.cpp

Top 10 files for portability severity, total findings: 2
-   2  /tmp/TeamCity-1/work/5ad443c8abe7fc0a/src/Inciter/DG.cpp
+   2  /tmp/TeamCity-1/work/5ad443c8abe7fc0a/src/Inciter/DG.cpp

Top 10 files for performance severity, total findings: 19
   8  /tmp/TeamCity-1/work/5ad443c8abe7fc0a/src/Base/Types.hpp
-   5  /tmp/TeamCity-1/work/5ad443c8abe7fc0a/src/Control/Inciter/InputDeck/LuaParser.hpp
+   5  /tmp/TeamCity-1/work/5ad443c8abe7fc0a/src/Control/Inciter/InputDeck/LuaParser.hpp
   2  /tmp/TeamCity-1/work/5ad443c8abe7fc0a/src/Main/MeshConvDriver.cpp
-   2  /tmp/TeamCity-1/work/5ad443c8abe7fc0a/src/Inciter/OversetFE.cpp
-   2  /tmp/TeamCity-1/work/5ad443c8abe7fc0a/src/Inciter/ALECG.cpp
+   2  /tmp/TeamCity-1/work/5ad443c8abe7fc0a/src/Inciter/OversetFE.cpp
+   2  /tmp/TeamCity-1/work/5ad443c8abe7fc0a/src/Inciter/ALECG.cpp

Top 10 files for style severity, total findings: 278
-   43  /tmp/TeamCity-1/work/5ad443c8abe7fc0a/src/PDE/MultiMat/DGMultiMat.hpp
-   29  /tmp/TeamCity-1/work/5ad443c8abe7fc0a/src/PDE/MultiMat/FVMultiMat.hpp
-   16  /tmp/TeamCity-1/work/5ad443c8abe7fc0a/src/Inciter/Refiner.cpp
+   43  /tmp/TeamCity-1/work/5ad443c8abe7fc0a/src/PDE/MultiMat/DGMultiMat.hpp
+   29  /tmp/TeamCity-1/work/5ad443c8abe7fc0a/src/PDE/MultiMat/FVMultiMat.hpp
+   16  /tmp/TeamCity-1/work/5ad443c8abe7fc0a/src/Inciter/Refiner.cpp
   15  /tmp/TeamCity-1/work/5ad443c8abe7fc0a/src/Mesh/DerivedData.cpp
-   14  /tmp/TeamCity-1/work/5ad443c8abe7fc0a/src/PDE/Limiter.cpp
+   14  /tmp/TeamCity-1/work/5ad443c8abe7fc0a/src/PDE/Limiter.cpp
   12  /tmp/TeamCity-1/work/5ad443c8abe7fc0a/src/PDE/MultiMat/MiscMultiMatFns.cpp
-   9   /tmp/TeamCity-1/work/5ad443c8abe7fc0a/src/Inciter/Discretization.cpp
-   7   /tmp/TeamCity-1/work/5ad443c8abe7fc0a/src/PDE/CompFlow/DGCompFlow.hpp
-   6   /tmp/TeamCity-1/work/5ad443c8abe7fc0a/src/PDE/Integrate/Surface.cpp
+   9   /tmp/TeamCity-1/work/5ad443c8abe7fc0a/src/Inciter/Discretization.cpp
+   7   /tmp/TeamCity-1/work/5ad443c8abe7fc0a/src/PDE/CompFlow/DGCompFlow.hpp
+   6   /tmp/TeamCity-1/work/5ad443c8abe7fc0a/src/PDE/Integrate/Surface.cpp
   6   /tmp/TeamCity-1/work/5ad443c8abe7fc0a/src/PDE/Integrate/Boundary.cpp

Top 10 files for information severity, total findings: 6
-   2  /tmp/TeamCity-1/work/5ad443c8abe7fc0a/src/Inciter/ElemDiagnostics.cpp
-   1  /tmp/TeamCity-1/work/5ad443c8abe7fc0a/src/Main/UnitTest.cpp
-   1  /tmp/TeamCity-1/work/5ad443c8abe7fc0a/src/Main/MeshConv.cpp
-   1  /tmp/TeamCity-1/work/5ad443c8abe7fc0a/src/Main/Inciter.cpp
-   1  /tmp/TeamCity-1/work/5ad443c8abe7fc0a/src/Inciter/Ghosts.cpp
+   2  /tmp/TeamCity-1/work/5ad443c8abe7fc0a/src/Inciter/ElemDiagnostics.cpp
+   1  /tmp/TeamCity-1/work/5ad443c8abe7fc0a/src/Main/UnitTest.cpp
+   1  /tmp/TeamCity-1/work/5ad443c8abe7fc0a/src/Main/MeshConv.cpp
+   1  /tmp/TeamCity-1/work/5ad443c8abe7fc0a/src/Main/Inciter.cpp
+   1  /tmp/TeamCity-1/work/5ad443c8abe7fc0a/src/Inciter/Ghosts.cpp

diff --git a/Debug/test_coverage/Base/ChareStateCollector.cpp.func-sort-c.html b/Debug/test_coverage/Base/ChareStateCollector.cpp.func-sort-c.html index e302ec7e4062..1c3dcd052510 100644 --- a/Debug/test_coverage/Base/ChareStateCollector.cpp.func-sort-c.html +++ b/Debug/test_coverage/Base/ChareStateCollector.cpp.func-sort-c.html @@ -33,7 +33,7 @@

Date:2024-07-10 11:43:412024-07-11 15:06:04 Functions: 3
Date:2024-07-10 11:43:412024-07-11 15:06:04 Functions: 3
Date:2024-07-10 11:43:412024-07-11 15:06:04 Functions: 3
Date:2024-07-10 11:43:412024-07-11 15:06:04 Functions: 3
Date:2024-07-10 11:43:412024-07-11 15:06:04 Functions: 3
Date:2024-07-10 11:43:412024-07-11 15:06:04 Functions: 3
Date:2024-07-10 11:43:412024-07-11 15:06:04 Functions: 107
Date:2024-07-10 11:43:412024-07-11 15:06:04 Functions: 107
Date:2024-07-10 11:43:412024-07-11 15:06:04 Functions: 107
Date:2024-07-10 11:43:412024-07-11 15:06:04 Functions: 11285170
tk::Data<(unsigned char)0>::extract_comp(unsigned long) const100093tk::Data<(unsigned char)0>::Data()99896
tk::Data<(unsigned char)0>::Data()101213tk::Data<(unsigned char)0>::extract_comp(unsigned long) const100093
tk::Data<(unsigned char)0>::fill(unsigned long, double)
tk::Data<(unsigned char)0>::pup(PUP::er&)303168299217
tk::operator|(PUP::er&, tk::Data<(unsigned char)0>&)303168299217
tk::Data<(unsigned char)0>::Data(unsigned long, unsigned long)
tk::Data<(unsigned char)0>::operator()(unsigned long, unsigned long)1547108673415471085463
tk::Data<(unsigned char)0>::access(unsigned long, unsigned long, tk::Data<(unsigned char)0>::int2type<(unsigned char)0>) const2889405556928894046653
tk::Data<(unsigned char)0>::operator()(unsigned long, unsigned long) const2889405556928894046653

diff --git a/Debug/test_coverage/Base/Data.hpp.func.html b/Debug/test_coverage/Base/Data.hpp.func.html index d3081f487b45..a12c8bda11c4 100644 --- a/Debug/test_coverage/Base/Data.hpp.func.html +++ b/Debug/test_coverage/Base/Data.hpp.func.html @@ -33,7 +33,7 @@
Date:2024-07-10 11:43:412024-07-11 15:06:04 Functions: 112
tk::Data<(unsigned char)0>::pup(PUP::er&)303168299217
tk::Data<(unsigned char)0>::var(double const*, unsigned long)
tk::Data<(unsigned char)0>::Data()10121399896
tk::Data<(unsigned char)0>::operator=(std::array<std::vector<double, std::allocator<double> >, 3ul> const&)
tk::Data<(unsigned char)0>::operator()(unsigned long, unsigned long)1547108673415471085463
tk::Data<(unsigned char)0>::operator/=(tk::Data<(unsigned char)0> const&)
tk::operator|(PUP::er&, tk::Data<(unsigned char)0>&)303168299217
tk::Data<(unsigned char)0>::extract_comp(unsigned long) const
tk::Data<(unsigned char)0>::access(unsigned long, unsigned long, tk::Data<(unsigned char)0>::int2type<(unsigned char)0>) const2889405556928894046653
tk::Data<(unsigned char)0>::extract(unsigned long) const
tk::Data<(unsigned char)0>::operator()(unsigned long, unsigned long) const2889405556928894046653
tk::Data<(unsigned char)0>::operator/(tk::Data<(unsigned char)0> const&) const
Date:2024-07-10 11:43:412024-07-11 15:06:04 Functions: 112
Date:2024-07-10 11:43:412024-07-11 15:06:04 Functions: 148
Date:2024-07-10 11:43:412024-07-11 15:06:04 Functions: 148
Date:2024-07-10 11:43:412024-07-11 15:06:04 Functions: 148
Date:2024-07-10 11:43:412024-07-11 15:06:04 Functions: 3
Date:2024-07-10 11:43:412024-07-11 15:06:04 Functions: 3
Date:2024-07-10 11:43:412024-07-11 15:06:04 Functions: 3
Date:2024-07-10 11:43:412024-07-11 15:06:04 Functions: 1
Date:2024-07-10 11:43:412024-07-11 15:06:04 Functions: 1
Date:2024-07-10 11:43:412024-07-11 15:06:04 Functions: 1
Date:2024-07-10 11:43:412024-07-11 15:06:04 Functions: 95
Date:2024-07-10 11:43:412024-07-11 15:06:04 Functions: 95
Date:2024-07-10 11:43:412024-07-11 15:06:04 Functions: 95
Date:2024-07-10 11:43:412024-07-11 15:06:04 Functions: 3
Date:2024-07-10 11:43:412024-07-11 15:06:04 Functions: 3
Date:2024-07-10 11:43:412024-07-11 15:06:04 Functions: 3
Date:2024-07-10 11:43:412024-07-11 15:06:04 Functions: 2
Date:2024-07-10 11:43:412024-07-11 15:06:04 Functions: 2
Date:2024-07-10 11:43:412024-07-11 15:06:04 Functions: 2
Date:2024-07-10 11:43:412024-07-11 15:06:04 Functions: 1
Date:2024-07-10 11:43:412024-07-11 15:06:04 Functions: 1
Date:2024-07-10 11:43:412024-07-11 15:06:04 Functions: 1
Date:2024-07-10 11:43:412024-07-11 15:06:04 Functions: 49
void PUP::pup<std::array<unsigned long, 2ul>, unsigned long, tk::UnsMesh::Hash<2ul>, tk::UnsMesh::Eq<2ul> >(PUP::er&, std::unordered_map<std::array<unsigned long, 2ul>, unsigned long, tk::UnsMesh::Hash<2ul>, tk::UnsMesh::Eq<2ul>, std::allocator<std::pair<std::array<unsigned long, 2ul> const, unsigned long> > >&)2439924138
void PUP::operator|<std::array<unsigned long, 2ul>, unsigned long, tk::UnsMesh::Hash<2ul>, tk::UnsMesh::Eq<2ul> >(PUP::er&, std::unordered_map<std::array<unsigned long, 2ul>, unsigned long, tk::UnsMesh::Hash<2ul>, tk::UnsMesh::Eq<2ul>, std::allocator<std::pair<std::array<unsigned long, 2ul> const, unsigned long> > >&)2439924138
void PUP::pup<std::array<unsigned long, 2ul>, std::tuple<int, int, AMR::Edge_Lock_Case>, tk::UnsMesh::Hash<2ul>, tk::UnsMesh::Eq<2ul> >(PUP::er&, std::unordered_map<std::array<unsigned long, 2ul>, std::tuple<int, int, AMR::Edge_Lock_Case>, tk::UnsMesh::Hash<2ul>, tk::UnsMesh::Eq<2ul>, std::allocator<std::pair<std::array<unsigned long, 2ul> const, std::tuple<int, int, AMR::Edge_Lock_Case> > > >&)2534725086
void PUP::operator|<std::array<unsigned long, 2ul>, std::tuple<int, int, AMR::Edge_Lock_Case>, tk::UnsMesh::Hash<2ul>, tk::UnsMesh::Eq<2ul> >(PUP::er&, std::unordered_map<std::array<unsigned long, 2ul>, std::tuple<int, int, AMR::Edge_Lock_Case>, tk::UnsMesh::Hash<2ul>, tk::UnsMesh::Eq<2ul>, std::allocator<std::pair<std::array<unsigned long, 2ul> const, std::tuple<int, int, AMR::Edge_Lock_Case> > > >&)2534725086
void PUP::pup<std::array<unsigned long, 2ul>, std::vector<int, std::allocator<int> >, tk::UnsMesh::Hash<2ul>, tk::UnsMesh::Eq<2ul> >(PUP::er&, std::unordered_map<std::array<unsigned long, 2ul>, std::vector<int, std::allocator<int> >, tk::UnsMesh::Hash<2ul>, tk::UnsMesh::Eq<2ul>, std::allocator<std::pair<std::array<unsigned long, 2ul> const, std::vector<int, std::allocator<int> > > > >&)4879848276
void PUP::operator|<std::array<unsigned long, 2ul>, std::vector<int, std::allocator<int> >, tk::UnsMesh::Hash<2ul>, tk::UnsMesh::Eq<2ul> >(PUP::er&, std::unordered_map<std::array<unsigned long, 2ul>, std::vector<int, std::allocator<int> >, tk::UnsMesh::Hash<2ul>, tk::UnsMesh::Eq<2ul>, std::allocator<std::pair<std::array<unsigned long, 2ul> const, std::vector<int, std::allocator<int> > > > >&)4879848276
void PUP::pup<std::array<unsigned long, 4ul>, tk::UnsMesh::Hash<4ul>, tk::UnsMesh::Eq<4ul> >(PUP::er&, std::unordered_set<std::array<unsigned long, 4ul>, tk::UnsMesh::Hash<4ul>, tk::UnsMesh::Eq<4ul>, std::allocator<std::array<unsigned long, 4ul> > >&)4881648294
void PUP::operator|<std::array<unsigned long, 4ul>, tk::UnsMesh::Hash<4ul>, tk::UnsMesh::Eq<4ul> >(PUP::er&, std::unordered_set<std::array<unsigned long, 4ul>, tk::UnsMesh::Hash<4ul>, tk::UnsMesh::Eq<4ul>, std::allocator<std::array<unsigned long, 4ul> > >&)4881648294
void PUP::pup<std::array<unsigned long, 2ul>, std::array<double, 3ul>, tk::UnsMesh::Hash<2ul>, tk::UnsMesh::Eq<2ul> >(PUP::er&, std::unordered_map<std::array<unsigned long, 2ul>, std::array<double, 3ul>, tk::UnsMesh::Hash<2ul>, tk::UnsMesh::Eq<2ul>, std::allocator<std::pair<std::array<unsigned long, 2ul> const, std::array<double, 3ul> > > >&)5644256412
void PUP::operator|<std::array<unsigned long, 2ul>, std::array<double, 3ul>, tk::UnsMesh::Hash<2ul>, tk::UnsMesh::Eq<2ul> >(PUP::er&, std::unordered_map<std::array<unsigned long, 2ul>, std::array<double, 3ul>, tk::UnsMesh::Hash<2ul>, tk::UnsMesh::Eq<2ul>, std::allocator<std::pair<std::array<unsigned long, 2ul> const, std::array<double, 3ul> > > >&)5644256412
char PUP::pup_helper<inciter::CProxy_ALECG, inciter::CProxy_DG, inciter::CProxy_ALECG, inciter::CProxy_OversetFE, inciter::CProxy_FV>(unsigned long&, unsigned long, PUP::er&, std::variant<inciter::CProxy_DG, inciter::CProxy_ALECG, inciter::CProxy_OversetFE, inciter::CProxy_FV>&)6229361771
char PUP::pup_helper<inciter::CProxy_OversetFE, inciter::CProxy_DG, inciter::CProxy_ALECG, inciter::CProxy_OversetFE, inciter::CProxy_FV>(unsigned long&, unsigned long, PUP::er&, std::variant<inciter::CProxy_DG, inciter::CProxy_ALECG, inciter::CProxy_OversetFE, inciter::CProxy_FV>&)6229361771
char PUP::pup_helper<inciter::CProxy_DG, inciter::CProxy_DG, inciter::CProxy_ALECG, inciter::CProxy_OversetFE, inciter::CProxy_FV>(unsigned long&, unsigned long, PUP::er&, std::variant<inciter::CProxy_DG, inciter::CProxy_ALECG, inciter::CProxy_OversetFE, inciter::CProxy_FV>&)6229361771
char PUP::pup_helper<inciter::CProxy_FV, inciter::CProxy_DG, inciter::CProxy_ALECG, inciter::CProxy_OversetFE, inciter::CProxy_FV>(unsigned long&, unsigned long, PUP::er&, std::variant<inciter::CProxy_DG, inciter::CProxy_ALECG, inciter::CProxy_OversetFE, inciter::CProxy_FV>&)6229361771
void PUP::pup<inciter::CProxy_DG, inciter::CProxy_ALECG, inciter::CProxy_OversetFE, inciter::CProxy_FV>(PUP::er&, std::variant<inciter::CProxy_DG, inciter::CProxy_ALECG, inciter::CProxy_OversetFE, inciter::CProxy_FV>&)6229361771
void PUP::operator|<inciter::CProxy_DG, inciter::CProxy_ALECG, inciter::CProxy_OversetFE, inciter::CProxy_FV>(PUP::er&, std::variant<inciter::CProxy_DG, inciter::CProxy_ALECG, inciter::CProxy_OversetFE, inciter::CProxy_FV>&)6229361771
void PUP::pup<std::array<unsigned long, 3ul>, tk::UnsMesh::Hash<3ul>, tk::UnsMesh::Eq<3ul> >(PUP::er&, std::unordered_set<std::array<unsigned long, 3ul>, tk::UnsMesh::Hash<3ul>, tk::UnsMesh::Eq<3ul>, std::allocator<std::array<unsigned long, 3ul> > >&)9689695774
void PUP::operator|<std::array<unsigned long, 3ul>, tk::UnsMesh::Hash<3ul>, tk::UnsMesh::Eq<3ul> >(PUP::er&, std::unordered_set<std::array<unsigned long, 3ul>, tk::UnsMesh::Hash<3ul>, tk::UnsMesh::Eq<3ul>, std::allocator<std::array<unsigned long, 3ul> > >&)9689695774
void PUP::pup<std::array<unsigned long, 2ul>, tk::UnsMesh::Hash<2ul>, tk::UnsMesh::Eq<2ul> >(PUP::er&, std::unordered_set<std::array<unsigned long, 2ul>, tk::UnsMesh::Hash<2ul>, tk::UnsMesh::Eq<2ul>, std::allocator<std::array<unsigned long, 2ul> > >&)704161700843
void PUP::operator|<std::array<unsigned long, 2ul>, tk::UnsMesh::Hash<2ul>, tk::UnsMesh::Eq<2ul> >(PUP::er&, std::unordered_set<std::array<unsigned long, 2ul>, tk::UnsMesh::Hash<2ul>, tk::UnsMesh::Eq<2ul>, std::allocator<std::array<unsigned long, 2ul> > >&)704161700843
void PUP::pup<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >(PUP::er&, std::optional<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >&)
Date:2024-07-10 11:43:412024-07-11 15:06:04 Functions: 49
char PUP::pup_helper<inciter::CProxy_ALECG, inciter::CProxy_DG, inciter::CProxy_ALECG, inciter::CProxy_OversetFE, inciter::CProxy_FV>(unsigned long&, unsigned long, PUP::er&, std::variant<inciter::CProxy_DG, inciter::CProxy_ALECG, inciter::CProxy_OversetFE, inciter::CProxy_FV>&)6229361771
char PUP::pup_helper<inciter::CProxy_OversetFE, inciter::CProxy_DG, inciter::CProxy_ALECG, inciter::CProxy_OversetFE, inciter::CProxy_FV>(unsigned long&, unsigned long, PUP::er&, std::variant<inciter::CProxy_DG, inciter::CProxy_ALECG, inciter::CProxy_OversetFE, inciter::CProxy_FV>&)6229361771
char PUP::pup_helper<inciter::CProxy_DG, inciter::CProxy_DG, inciter::CProxy_ALECG, inciter::CProxy_OversetFE, inciter::CProxy_FV>(unsigned long&, unsigned long, PUP::er&, std::variant<inciter::CProxy_DG, inciter::CProxy_ALECG, inciter::CProxy_OversetFE, inciter::CProxy_FV>&)6229361771
char PUP::pup_helper<inciter::CProxy_FV, inciter::CProxy_DG, inciter::CProxy_ALECG, inciter::CProxy_OversetFE, inciter::CProxy_FV>(unsigned long&, unsigned long, PUP::er&, std::variant<inciter::CProxy_DG, inciter::CProxy_ALECG, inciter::CProxy_OversetFE, inciter::CProxy_FV>&)6229361771
char PUP::pup_helper<double, int, double>(unsigned long&, unsigned long, PUP::er&, std::variant<int, double>&)
void PUP::pup<inciter::CProxy_DG, inciter::CProxy_ALECG, inciter::CProxy_OversetFE, inciter::CProxy_FV>(PUP::er&, std::variant<inciter::CProxy_DG, inciter::CProxy_ALECG, inciter::CProxy_OversetFE, inciter::CProxy_FV>&)6229361771
void PUP::pup<int, double>(PUP::er&, std::variant<int, double>&)
void PUP::pup<std::array<unsigned long, 2ul>, tk::UnsMesh::Hash<2ul>, tk::UnsMesh::Eq<2ul> >(PUP::er&, std::unordered_set<std::array<unsigned long, 2ul>, tk::UnsMesh::Hash<2ul>, tk::UnsMesh::Eq<2ul>, std::allocator<std::array<unsigned long, 2ul> > >&)704161700843
void PUP::pup<std::array<unsigned long, 2ul>, std::array<double, 3ul>, tk::UnsMesh::Hash<2ul>, tk::UnsMesh::Eq<2ul> >(PUP::er&, std::unordered_map<std::array<unsigned long, 2ul>, std::array<double, 3ul>, tk::UnsMesh::Hash<2ul>, tk::UnsMesh::Eq<2ul>, std::allocator<std::pair<std::array<unsigned long, 2ul> const, std::array<double, 3ul> > > >&)5644256412
void PUP::pup<std::array<unsigned long, 2ul>, std::tuple<int, int, AMR::Edge_Lock_Case>, tk::UnsMesh::Hash<2ul>, tk::UnsMesh::Eq<2ul> >(PUP::er&, std::unordered_map<std::array<unsigned long, 2ul>, std::tuple<int, int, AMR::Edge_Lock_Case>, tk::UnsMesh::Hash<2ul>, tk::UnsMesh::Eq<2ul>, std::allocator<std::pair<std::array<unsigned long, 2ul> const, std::tuple<int, int, AMR::Edge_Lock_Case> > > >&)2534725086
void PUP::pup<std::array<unsigned long, 2ul>, std::vector<int, std::allocator<int> >, tk::UnsMesh::Hash<2ul>, tk::UnsMesh::Eq<2ul> >(PUP::er&, std::unordered_map<std::array<unsigned long, 2ul>, std::vector<int, std::allocator<int> >, tk::UnsMesh::Hash<2ul>, tk::UnsMesh::Eq<2ul>, std::allocator<std::pair<std::array<unsigned long, 2ul> const, std::vector<int, std::allocator<int> > > > >&)4879848276
void PUP::pup<std::array<unsigned long, 2ul>, unsigned long, tk::UnsMesh::Hash<2ul>, tk::UnsMesh::Eq<2ul> >(PUP::er&, std::unordered_map<std::array<unsigned long, 2ul>, unsigned long, tk::UnsMesh::Hash<2ul>, tk::UnsMesh::Eq<2ul>, std::allocator<std::pair<std::array<unsigned long, 2ul> const, unsigned long> > >&)2439924138
void PUP::pup<std::array<unsigned long, 3ul>, tk::UnsMesh::Hash<3ul>, tk::UnsMesh::Eq<3ul> >(PUP::er&, std::unordered_set<std::array<unsigned long, 3ul>, tk::UnsMesh::Hash<3ul>, tk::UnsMesh::Eq<3ul>, std::allocator<std::array<unsigned long, 3ul> > >&)9689695774
void PUP::pup<std::array<unsigned long, 3ul>, std::array<unsigned long, 2ul>, tk::UnsMesh::Hash<3ul>, tk::UnsMesh::Eq<3ul> >(PUP::er&, std::unordered_map<std::array<unsigned long, 3ul>, std::array<unsigned long, 2ul>, tk::UnsMesh::Hash<3ul>, tk::UnsMesh::Eq<3ul>, std::allocator<std::pair<std::array<unsigned long, 3ul> const, std::array<unsigned long, 2ul> > > >&)
void PUP::pup<std::array<unsigned long, 4ul>, tk::UnsMesh::Hash<4ul>, tk::UnsMesh::Eq<4ul> >(PUP::er&, std::unordered_set<std::array<unsigned long, 4ul>, tk::UnsMesh::Hash<4ul>, tk::UnsMesh::Eq<4ul>, std::allocator<std::array<unsigned long, 4ul> > >&)4881648294
void PUP::pup<int>(PUP::er&, std::optional<int>&)
void PUP::operator|<inciter::CProxy_DG, inciter::CProxy_ALECG, inciter::CProxy_OversetFE, inciter::CProxy_FV>(PUP::er&, std::variant<inciter::CProxy_DG, inciter::CProxy_ALECG, inciter::CProxy_OversetFE, inciter::CProxy_FV>&)6229361771
void PUP::operator|<int, double>(PUP::er&, std::variant<int, double>&)
void PUP::operator|<std::array<unsigned long, 2ul>, tk::UnsMesh::Hash<2ul>, tk::UnsMesh::Eq<2ul> >(PUP::er&, std::unordered_set<std::array<unsigned long, 2ul>, tk::UnsMesh::Hash<2ul>, tk::UnsMesh::Eq<2ul>, std::allocator<std::array<unsigned long, 2ul> > >&)704161700843
void PUP::operator|<std::array<unsigned long, 2ul>, std::array<double, 3ul>, tk::UnsMesh::Hash<2ul>, tk::UnsMesh::Eq<2ul> >(PUP::er&, std::unordered_map<std::array<unsigned long, 2ul>, std::array<double, 3ul>, tk::UnsMesh::Hash<2ul>, tk::UnsMesh::Eq<2ul>, std::allocator<std::pair<std::array<unsigned long, 2ul> const, std::array<double, 3ul> > > >&)5644256412
void PUP::operator|<std::array<unsigned long, 2ul>, std::tuple<int, int, AMR::Edge_Lock_Case>, tk::UnsMesh::Hash<2ul>, tk::UnsMesh::Eq<2ul> >(PUP::er&, std::unordered_map<std::array<unsigned long, 2ul>, std::tuple<int, int, AMR::Edge_Lock_Case>, tk::UnsMesh::Hash<2ul>, tk::UnsMesh::Eq<2ul>, std::allocator<std::pair<std::array<unsigned long, 2ul> const, std::tuple<int, int, AMR::Edge_Lock_Case> > > >&)2534725086
void PUP::operator|<std::array<unsigned long, 2ul>, std::vector<int, std::allocator<int> >, tk::UnsMesh::Hash<2ul>, tk::UnsMesh::Eq<2ul> >(PUP::er&, std::unordered_map<std::array<unsigned long, 2ul>, std::vector<int, std::allocator<int> >, tk::UnsMesh::Hash<2ul>, tk::UnsMesh::Eq<2ul>, std::allocator<std::pair<std::array<unsigned long, 2ul> const, std::vector<int, std::allocator<int> > > > >&)4879848276
void PUP::operator|<std::array<unsigned long, 2ul>, unsigned long, tk::UnsMesh::Hash<2ul>, tk::UnsMesh::Eq<2ul> >(PUP::er&, std::unordered_map<std::array<unsigned long, 2ul>, unsigned long, tk::UnsMesh::Hash<2ul>, tk::UnsMesh::Eq<2ul>, std::allocator<std::pair<std::array<unsigned long, 2ul> const, unsigned long> > >&)2439924138
void PUP::operator|<std::array<unsigned long, 3ul>, tk::UnsMesh::Hash<3ul>, tk::UnsMesh::Eq<3ul> >(PUP::er&, std::unordered_set<std::array<unsigned long, 3ul>, tk::UnsMesh::Hash<3ul>, tk::UnsMesh::Eq<3ul>, std::allocator<std::array<unsigned long, 3ul> > >&)9689695774
void PUP::operator|<std::array<unsigned long, 3ul>, std::array<unsigned long, 2ul>, tk::UnsMesh::Hash<3ul>, tk::UnsMesh::Eq<3ul> >(PUP::er&, std::unordered_map<std::array<unsigned long, 3ul>, std::array<unsigned long, 2ul>, tk::UnsMesh::Hash<3ul>, tk::UnsMesh::Eq<3ul>, std::allocator<std::pair<std::array<unsigned long, 3ul> const, std::array<unsigned long, 2ul> > > >&)
void PUP::operator|<std::array<unsigned long, 4ul>, tk::UnsMesh::Hash<4ul>, tk::UnsMesh::Eq<4ul> >(PUP::er&, std::unordered_set<std::array<unsigned long, 4ul>, tk::UnsMesh::Hash<4ul>, tk::UnsMesh::Eq<4ul>, std::allocator<std::array<unsigned long, 4ul> > >&)4881648294
void PUP::operator|<int>(PUP::er&, std::optional<int>&)
Date:2024-07-10 11:43:412024-07-11 15:06:04 Functions: 49
Date:2024-07-10 11:43:412024-07-11 15:06:04 Functions: 68
Date:2024-07-10 11:43:412024-07-11 15:06:04 Functions: 68
Date:2024-07-10 11:43:412024-07-11 15:06:04 Functions: 68
Date:2024-07-10 11:43:412024-07-11 15:06:04 Functions: 5
Date:2024-07-10 11:43:412024-07-11 15:06:04 Functions: 5
Date:2024-07-10 11:43:412024-07-11 15:06:04 Functions: 5
Date:2024-07-10 11:43:412024-07-11 15:06:04 Functions: 50
Date:2024-07-10 11:43:412024-07-11 15:06:04 Functions: 50
Date:2024-07-10 11:43:412024-07-11 15:06:04 Functions: 50
Date:2024-07-10 11:43:412024-07-11 15:06:04 Functions: 1
Date:2024-07-10 11:43:412024-07-11 15:06:04 Functions: 1
Date:2024-07-10 11:43:412024-07-11 15:06:04 Functions: 1
Date:2024-07-10 11:43:412024-07-11 15:06:04 Functions: 11
Date:2024-07-10 11:43:412024-07-11 15:06:04 Functions: 11
Date:2024-07-10 11:43:412024-07-11 15:06:04 Functions: 11
Date:2024-07-10 11:43:412024-07-11 15:06:04 Functions: 4
Date:2024-07-10 11:43:412024-07-11 15:06:04 Functions: 4
Date:2024-07-10 11:43:412024-07-11 15:06:04 Functions: 4
Date:2024-07-10 11:43:412024-07-11 15:06:04 Functions: 6
Date:2024-07-10 11:43:412024-07-11 15:06:04 Functions: 6
Date:2024-07-10 11:43:412024-07-11 15:06:04 Functions: 6
Date:2024-07-10 11:43:412024-07-11 15:06:04 Functions: 83212
tk::TaggedTuple<brigand::list<tag::id, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, tag::elem, unsigned long, tag::coord, std::array<double, 3ul>, tag::fn, std::array<double, 4ul> > >::TaggedTuple()tk::TaggedTuple<brigand::list<tut::charm::tag::name, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, tut::charm::tag::age, int, tut::charm::tag::email, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > > >::TaggedTuple() 14
tk::TaggedTuple<brigand::list<tut::charm::tag::name, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, tut::charm::tag::age, int, tut::charm::tag::email, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > > >::TaggedTuple()14tk::TaggedTuple<brigand::list<tag::id, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, tag::elem, unsigned long, tag::coord, std::array<double, 3ul>, tag::fn, std::array<double, 4ul> > >::TaggedTuple()15
tk::TaggedTuple<brigand::list<tag::materialid, unsigned long, tag::volume, double, tag::mass, double, tag::density, double, tag::velocity, std::vector<double, std::allocator<double> >, tag::pressure, double, tag::energy, double, tag::energy_content, double, tag::temperature, double, tag::xmin, double, tag::xmax, double, tag::ymin, double, tag::ymax, double, tag::zmin, double, tag::zmax, double, tag::orientation, std::vector<double, std::allocator<double> >, tag::initiate, inciter::ctr::InitiateType, tag::point, std::vector<double, std::allocator<double> >, tag::init_time, double, tag::front_width, double, tag::front_speed, double> >::pup(PUP::er&)_ZN2tk11TaggedTupleIN7brigand4listIJN3tag5titleENSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEENS3_3cmdEN7inciter3ctr7CmdLineENS3_5nstepEmNS3_4termEdNS3_2t0EdNS3_2dtEdNS3_3cflEdNS3_4ttyiEjNS3_16imex_runge_kuttaEjNS3_12imex_maxiterEjNS3_11imex_reltolEdNS3_11imex_abstolEdNS3_12steady_stateEbNS3_8residualEdNS3_7rescompEjNS3_12partitioningENS_3ctr25PartitioningAlgorithmTypeENS3_15pelocal_reorderEbNS3_16operator_reorderEbNS3_6schemeENSD_10SchemeTypeENS3_4ndofEmNS3_4rdofEmNS3_4fluxENSD_8FluxTypeENS3_11lowspeed_kpEdNS3_7limiterENSD_11LimiterTypeENS3_7cweightEdNS3_20shock_detector_coeffEdNS3_13accuracy_testEbNS3_17limsol_projectionEbNS3_5ncompEmNS3_3pdeENSD_7PDETypeENS3_9transportENS0_INS2_IJNS3_7physicsENSD_11PhysicsTypeES1A_mNS3_8intsharpEiNS3_14intsharp_paramEdNS3_7problemENSD_11ProblemTypeENS3_11diffusivityESt6vectorIdSaIdEENS3_6lambdaES1N_NS3_2u0ES1N_EEEEENS3_8compflowENS0_INS2_IJS1E_S1F_S1I_S1J_NS3_5alphaEdNS3_4betaEdNS3_5betaxEdNS3_5betayEdNS3_5betazEdNS3_2r0EdNS3_2p0EdNS3_2ceEdNS3_5kappaEdEEEEENS3_8multimatENS0_INS2_IJS1E_S1F_NS3_4nmatEmNS3_6prelaxEmNS3_16prelax_timescaleEdS1G_iS1H_dNS3_14rho0constraintEmNS3_14dt_sos_massavgEiS1I_S1J_EEEEENS3_6depvarES1L_IcS9_ENS3_3sysESt3mapImmSt4lessImESaISt4pairIKmmEEENS3_8materialES1L_INS0_INS2_IJNS3_3eosENSD_12MaterialTypeENS3_2idES1L_ImSaImEENS3_5gammaES1N_NS3_6pstiffES1N_NS3_5w_gruES1N_NS3_5A_jwlES1N_NS3_5B_jwlES1N_NS3_5C_jwlES1N_NS3_6R1_jwlES1N_NS3_6R2_jwlES1N_NS3_8rho0_jwlES1N_NS3_6de_jwlES1N_NS3_8rhor_jwlES1N_NS3_6Tr_jwlES1N_NS3_6Pr_jwlES1N_NS3_2muES1N_NS3_12yield_stressES1N_NS3_2cvES1N_NS3_1kES1N_EEEEESaIS3B_EENS3_9matidxmapENS0_INS2_IJNS3_6eosidxES2S_NS3_6matidxES2S_NS3_6solidxES2S_EEEEENS3_2bcES1L_INS0_INS2_IJNS3_4meshES2S_NS3_9dirichletES2S_NS3_8symmetryES2S_NS3_5inletES2S_NS3_6outletES2S_NS3_8farfieldES2S_NS3_11extrapolateES2S_NS3_10stag_pointES1N_NS3_6radiusEdNS3_8velocityES1N_NS3_8pressureEdNS3_7densityEdNS3_7timedepES1L_INS0_INS2_IJNS3_7sidesetES2S_NS3_2fnES1N_EEEEESaIS41_EEEEEEESaIS45_EENS3_2icENS0_INS2_IJNS3_10materialidEmS3V_dNS3_11temperatureEdS3W_dNS3_6energyEdS3U_S1N_NS3_3boxES1L_INS0_INS2_IJS49_mNS3_6volumeEdNS3_4massEdS3W_dS3U_S1N_S3V_dS4B_dNS3_14energy_contentEdS4A_dNS3_4xminEdNS3_4xmaxEdNS3_4yminEdNS3_4ymaxEdNS3_4zminEdNS3_4zmaxEdNS3_11orientationES1N_NS3_8initiateENSD_12InitiateTypeENS3_5pointES1N_NS3_9init_timeEdNS3_11front_widthEdNS3_11front_speedEdEEEEESaIS4U_EENS3_9meshblockES1L_INS0_INS2_IJNS3_7blockidEmS49_mS4D_dS4E_dS3W_dS3U_S1N_S3V_dS4B_dS4F_dS4A_dS4N_S4O_S4P_S1N_S4Q_dS4R_dS4S_dEEEEESaIS50_EEEEEEES3L_S1L_INS0_INS2_IJNS3_8filenameESA_NS3_8locationES1N_S4M_S1N_S3U_S1N_EEEEESaIS58_EENS3_8transferES1L_INSC_8TransferESaIS5C_EENS3_3aleENS0_INS2_IJS5F_bNS3_8smootherENSD_24MeshVelocitySmootherTypeENS3_13mesh_velocityENSD_16MeshVelocityTypeENS3_11mesh_motionES2S_NS3_9meshforceES1N_NS3_5dvcflEdNS3_8vortmultEdNS3_5maxitEmNS3_9toleranceEdS3M_S2S_S3N_S2S_NS3_4moveES1L_INS0_INS2_IJS3Y_S2S_NS3_6fntypeENST_13UserTableTypeES3Z_S1N_EEEEESaIS5U_EEEEEEENS3_4prefENS0_INS2_IJS5Z_bNS3_9indicatorENSD_17PrefIndicatorTypeENS3_7ndofmaxEmNS3_6tolrefEdEEEEENS3_3amrENS0_INS2_IJS66_bNS3_5t0refEbNS3_5dtrefEbNS3_13dtref_uniformEbNS3_6dtfreqEmNS3_9maxlevelsEmNS3_7initialES1L_INSD_14AMRInitialTypeESaIS6D_EENS3_8edgelistES2S_NS3_6coordsENS0_INS2_IJNS3_6xminusEdNS3_5xplusEdNS3_6yminusEdNS3_5yplusEdNS3_6zminusEdNS3_5zplusEdEEEEENS3_5errorENSD_12AMRErrorTypeENS3_6refvarES2D_NS3_10tol_refineEdNS3_12tol_derefineEdEEEEENS3_12field_outputENS0_INS2_IJNS3_8intervalEjNS3_13time_intervalEdNS3_10time_rangeES1N_NS3_7refinedEbNS3_8filetypeENST_13FieldFileTypeES3Y_S2S_NS3_6outvarES1L_INSD_6OutVarESaIS75_EENS3_9elemaliasES1L_ISA_SaISA_EENS3_7elemvarES7A_NS3_9nodealiasES7A_NS3_7nodevarES7A_EEEEENS3_11diagnosticsENS0_INS2_IJS6Y_jS6Q_NST_9ErrorTypeENS3_6formatENST_18TxtFloatFormatTypeENS3_9precisionElEEEEENS3_14history_outputENS0_INS2_IJS6Y_jS6Z_dS70_S1N_S7I_S7J_S7K_lS4P_S1L_INS0_INS2_IJS2Q_SA_NS3_5coordES1N_EEEEESaIS7Q_EEEEEEEEEEE3getIS66_JS6H_EEERDav 44
tk::TaggedTuple<brigand::list<tag::id, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, tag::elem, unsigned long, tag::coord, std::array<double, 3ul>, tag::fn, std::array<double, 4ul> > >::pup(PUP::er&)52
tk::operator|(PUP::er&, tk::TaggedTuple<brigand::list<tag::id, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, tag::elem, unsigned long, tag::coord, std::array<double, 3ul>, tag::fn, std::array<double, 4ul> > >&)52
auto& tk::TaggedTuple<brigand::list<tag::io, tk::TaggedTuple<brigand::list<tag::nrestart, int, tag::input, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, tag::output, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, tag::screen, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > > >, tag::verbose, bool, tag::chare, bool, tag::reorder, bool, tag::help, bool, tag::quiescence, bool, tag::trace, bool, tag::version, bool, tag::license, bool, tag::cmdinfo, std::map<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, tk::ctr::KeywordInfo, std::less<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >, std::allocator<std::pair<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const, tk::ctr::KeywordInfo> > >, tag::ctrinfo, std::map<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, tk::ctr::KeywordInfo, std::less<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >, std::allocator<std::pair<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const, tk::ctr::KeywordInfo> > >, tag::helpkw, tk::ctr::HelpKw, tag::error, std::vector<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::allocator<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > > > > >::get<tag::io, tag::nrestart>() 54auto const& tk::TaggedTuple<brigand::list<tag::io, tk::TaggedTuple<brigand::list<tag::nrestart, int, tag::input, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, tag::output, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, tag::screen, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > > >, tag::verbose, bool, tag::chare, bool, tag::reorder, bool, tag::help, bool, tag::quiescence, bool, tag::trace, bool, tag::version, bool, tag::license, bool, tag::cmdinfo, std::map<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, tk::ctr::KeywordInfo, std::less<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >, std::allocator<std::pair<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const, tk::ctr::KeywordInfo> > >, tag::ctrinfo, std::map<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, tk::ctr::KeywordInfo, std::less<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >, std::allocator<std::pair<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const, tk::ctr::KeywordInfo> > >, tag::helpkw, tk::ctr::HelpKw, tag::error, std::vector<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::allocator<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > > > > >::get<tag::quiescence>() const 54
tk::TaggedTuple<brigand::list<tag::id, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, tag::elem, unsigned long, tag::coord, std::array<double, 3ul>, tag::fn, std::array<double, 4ul> > >::pup(PUP::er&)55
tk::operator|(PUP::er&, tk::TaggedTuple<brigand::list<tag::id, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, tag::elem, unsigned long, tag::coord, std::array<double, 3ul>, tag::fn, std::array<double, 4ul> > >&)55
auto& tk::TaggedTuple<brigand::list<tag::amr, bool, tag::t0ref, bool, tag::dtref, bool, tag::dtref_uniform, bool, tag::dtfreq, unsigned long, tag::maxlevels, unsigned long, tag::initial, std::vector<inciter::ctr::AMRInitialType, std::allocator<inciter::ctr::AMRInitialType> >, tag::edgelist, std::vector<unsigned long, std::allocator<unsigned long> >, tag::coords, tk::TaggedTuple<brigand::list<tag::xminus, double, tag::xplus, double, tag::yminus, double, tag::yplus, double, tag::zminus, double, tag::zplus, double> >, tag::error, inciter::ctr::AMRErrorType, tag::refvar, std::vector<char, std::allocator<char> >, tag::tol_refine, double, tag::tol_derefine, double> >::get<tag::tol_refine>() 5610125
_ZN2tk11TaggedTupleIN7brigand4listIJN3tag5titleENSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEENS3_3cmdEN7inciter3ctr7CmdLineENS3_5nstepEmNS3_4termEdNS3_2t0EdNS3_2dtEdNS3_3cflEdNS3_4ttyiEjNS3_16imex_runge_kuttaEjNS3_12imex_maxiterEjNS3_11imex_reltolEdNS3_11imex_abstolEdNS3_12steady_stateEbNS3_8residualEdNS3_7rescompEjNS3_12partitioningENS_3ctr25PartitioningAlgorithmTypeENS3_15pelocal_reorderEbNS3_16operator_reorderEbNS3_6schemeENSD_10SchemeTypeENS3_4ndofEmNS3_4rdofEmNS3_4fluxENSD_8FluxTypeENS3_11lowspeed_kpEdNS3_7limiterENSD_11LimiterTypeENS3_7cweightEdNS3_20shock_detector_coeffEdNS3_13accuracy_testEbNS3_17limsol_projectionEbNS3_5ncompEmNS3_3pdeENSD_7PDETypeENS3_9transportENS0_INS2_IJNS3_7physicsENSD_11PhysicsTypeES1A_mNS3_8intsharpEiNS3_14intsharp_paramEdNS3_7problemENSD_11ProblemTypeENS3_11diffusivityESt6vectorIdSaIdEENS3_6lambdaES1N_NS3_2u0ES1N_EEEEENS3_8compflowENS0_INS2_IJS1E_S1F_S1I_S1J_NS3_5alphaEdNS3_4betaEdNS3_5betaxEdNS3_5betayEdNS3_5betazEdNS3_2r0EdNS3_2p0EdNS3_2ceEdNS3_5kappaEdEEEEENS3_8multimatENS0_INS2_IJS1E_S1F_NS3_4nmatEmNS3_6prelaxEmNS3_16prelax_timescaleEdS1G_iS1H_dNS3_14rho0constraintEmNS3_14dt_sos_massavgEiS1I_S1J_EEEEENS3_6depvarES1L_IcS9_ENS3_3sysESt3mapImmSt4lessImESaISt4pairIKmmEEENS3_8materialES1L_INS0_INS2_IJNS3_3eosENSD_12MaterialTypeENS3_2idES1L_ImSaImEENS3_5gammaES1N_NS3_6pstiffES1N_NS3_5w_gruES1N_NS3_5A_jwlES1N_NS3_5B_jwlES1N_NS3_5C_jwlES1N_NS3_6R1_jwlES1N_NS3_6R2_jwlES1N_NS3_8rho0_jwlES1N_NS3_6de_jwlES1N_NS3_8rhor_jwlES1N_NS3_6Tr_jwlES1N_NS3_6Pr_jwlES1N_NS3_2muES1N_NS3_12yield_stressES1N_NS3_2cvES1N_NS3_1kES1N_EEEEESaIS3B_EENS3_9matidxmapENS0_INS2_IJNS3_6eosidxES2S_NS3_6matidxES2S_NS3_6solidxES2S_EEEEENS3_2bcES1L_INS0_INS2_IJNS3_4meshES2S_NS3_9dirichletES2S_NS3_8symmetryES2S_NS3_5inletES2S_NS3_6outletES2S_NS3_8farfieldES2S_NS3_11extrapolateES2S_NS3_10stag_pointES1N_NS3_6radiusEdNS3_8velocityES1N_NS3_8pressureEdNS3_7densityEdNS3_7timedepES1L_INS0_INS2_IJNS3_7sidesetES2S_NS3_2fnES1N_EEEEESaIS41_EEEEEEESaIS45_EENS3_2icENS0_INS2_IJNS3_10materialidEmS3V_dNS3_11temperatureEdS3W_dNS3_6energyEdS3U_S1N_NS3_3boxES1L_INS0_INS2_IJS49_mNS3_6volumeEdNS3_4massEdS3W_dS3U_S1N_S3V_dS4B_dNS3_14energy_contentEdS4A_dNS3_4xminEdNS3_4xmaxEdNS3_4yminEdNS3_4ymaxEdNS3_4zminEdNS3_4zmaxEdNS3_11orientationES1N_NS3_8initiateENSD_12InitiateTypeENS3_5pointES1N_NS3_9init_timeEdNS3_11front_widthEdNS3_11front_speedEdEEEEESaIS4U_EENS3_9meshblockES1L_INS0_INS2_IJNS3_7blockidEmS49_mS4D_dS4E_dS3W_dS3U_S1N_S3V_dS4B_dS4F_dS4A_dS4N_S4O_S4P_S1N_S4Q_dS4R_dS4S_dEEEEESaIS50_EEEEEEES3L_S1L_INS0_INS2_IJNS3_8filenameESA_NS3_8locationES1N_S4M_S1N_S3U_S1N_EEEEESaIS58_EENS3_8transferES1L_INSC_8TransferESaIS5C_EENS3_3aleENS0_INS2_IJS5F_bNS3_8smootherENSD_24MeshVelocitySmootherTypeENS3_13mesh_velocityENSD_16MeshVelocityTypeENS3_11mesh_motionES2S_NS3_9meshforceES1N_NS3_5dvcflEdNS3_8vortmultEdNS3_5maxitEmNS3_9toleranceEdS3M_S2S_S3N_S2S_NS3_4moveES1L_INS0_INS2_IJS3Y_S2S_NS3_6fntypeENST_13UserTableTypeES3Z_S1N_EEEEESaIS5U_EEEEEEENS3_4prefENS0_INS2_IJS5Z_bNS3_9indicatorENSD_17PrefIndicatorTypeENS3_7ndofmaxEmNS3_6tolrefEdEEEEENS3_3amrENS0_INS2_IJS66_bNS3_5t0refEbNS3_5dtrefEbNS3_13dtref_uniformEbNS3_6dtfreqEmNS3_9maxlevelsEmNS3_7initialES1L_INSD_14AMRInitialTypeESaIS6D_EENS3_8edgelistES2S_NS3_6coordsENS0_INS2_IJNS3_6xminusEdNS3_5xplusEdNS3_6yminusEdNS3_5yplusEdNS3_6zminusEdNS3_5zplusEdEEEEENS3_5errorENSD_12AMRErrorTypeENS3_6refvarES2D_NS3_10tol_refineEdNS3_12tol_derefineEdEEEEENS3_12field_outputENS0_INS2_IJNS3_8intervalEjNS3_13time_intervalEdNS3_10time_rangeES1N_NS3_7refinedEbNS3_8filetypeENST_13FieldFileTypeES3Y_S2S_NS3_6outvarES1L_INSD_6OutVarESaIS75_EENS3_9elemaliasES1L_ISA_SaISA_EENS3_7elemvarES7A_NS3_9nodealiasES7A_NS3_7nodevarES7A_EEEEENS3_11diagnosticsENS0_INS2_IJS6Y_jS6Q_NST_9ErrorTypeENS3_6formatENST_18TxtFloatFormatTypeENS3_9precisionElEEEEENS3_14history_outputENS0_INS2_IJS6Y_jS6Z_dS70_S1N_S7I_S7J_S7K_lS4P_S1L_INS0_INS2_IJS2Q_SA_NS3_5coordES1N_EEEEESaIS7Q_EEEEEEEEEEE3getIS17_JEEERDav10365tk::TaggedTuple<brigand::list<tag::queried, CkCallback, tag::responded, CkCallback, tag::compatibility, CkCallback, tag::bndint, CkCallback, tag::matched, CkCallback, tag::refined, CkCallback> >::TaggedTuple()10352
tk::TaggedTuple<brigand::list<tag::queried, CkCallback, tag::responded, CkCallback, tag::compatibility, CkCallback, tag::bndint, CkCallback, tag::matched, CkCallback, tag::refined, CkCallback> >::TaggedTuple()10439_ZN2tk11TaggedTupleIN7brigand4listIJN3tag5titleENSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEENS3_3cmdEN7inciter3ctr7CmdLineENS3_5nstepEmNS3_4termEdNS3_2t0EdNS3_2dtEdNS3_3cflEdNS3_4ttyiEjNS3_16imex_runge_kuttaEjNS3_12imex_maxiterEjNS3_11imex_reltolEdNS3_11imex_abstolEdNS3_12steady_stateEbNS3_8residualEdNS3_7rescompEjNS3_12partitioningENS_3ctr25PartitioningAlgorithmTypeENS3_15pelocal_reorderEbNS3_16operator_reorderEbNS3_6schemeENSD_10SchemeTypeENS3_4ndofEmNS3_4rdofEmNS3_4fluxENSD_8FluxTypeENS3_11lowspeed_kpEdNS3_7limiterENSD_11LimiterTypeENS3_7cweightEdNS3_20shock_detector_coeffEdNS3_13accuracy_testEbNS3_17limsol_projectionEbNS3_5ncompEmNS3_3pdeENSD_7PDETypeENS3_9transportENS0_INS2_IJNS3_7physicsENSD_11PhysicsTypeES1A_mNS3_8intsharpEiNS3_14intsharp_paramEdNS3_7problemENSD_11ProblemTypeENS3_11diffusivityESt6vectorIdSaIdEENS3_6lambdaES1N_NS3_2u0ES1N_EEEEENS3_8compflowENS0_INS2_IJS1E_S1F_S1I_S1J_NS3_5alphaEdNS3_4betaEdNS3_5betaxEdNS3_5betayEdNS3_5betazEdNS3_2r0EdNS3_2p0EdNS3_2ceEdNS3_5kappaEdEEEEENS3_8multimatENS0_INS2_IJS1E_S1F_NS3_4nmatEmNS3_6prelaxEmNS3_16prelax_timescaleEdS1G_iS1H_dNS3_14rho0constraintEmNS3_14dt_sos_massavgEiS1I_S1J_EEEEENS3_6depvarES1L_IcS9_ENS3_3sysESt3mapImmSt4lessImESaISt4pairIKmmEEENS3_8materialES1L_INS0_INS2_IJNS3_3eosENSD_12MaterialTypeENS3_2idES1L_ImSaImEENS3_5gammaES1N_NS3_6pstiffES1N_NS3_5w_gruES1N_NS3_5A_jwlES1N_NS3_5B_jwlES1N_NS3_5C_jwlES1N_NS3_6R1_jwlES1N_NS3_6R2_jwlES1N_NS3_8rho0_jwlES1N_NS3_6de_jwlES1N_NS3_8rhor_jwlES1N_NS3_6Tr_jwlES1N_NS3_6Pr_jwlES1N_NS3_2muES1N_NS3_12yield_stressES1N_NS3_2cvES1N_NS3_1kES1N_EEEEESaIS3B_EENS3_9matidxmapENS0_INS2_IJNS3_6eosidxES2S_NS3_6matidxES2S_NS3_6solidxES2S_EEEEENS3_2bcES1L_INS0_INS2_IJNS3_4meshES2S_NS3_9dirichletES2S_NS3_8symmetryES2S_NS3_5inletES2S_NS3_6outletES2S_NS3_8farfieldES2S_NS3_11extrapolateES2S_NS3_10stag_pointES1N_NS3_6radiusEdNS3_8velocityES1N_NS3_8pressureEdNS3_7densityEdNS3_7timedepES1L_INS0_INS2_IJNS3_7sidesetES2S_NS3_2fnES1N_EEEEESaIS41_EEEEEEESaIS45_EENS3_2icENS0_INS2_IJNS3_10materialidEmS3V_dNS3_11temperatureEdS3W_dNS3_6energyEdS3U_S1N_NS3_3boxES1L_INS0_INS2_IJS49_mNS3_6volumeEdNS3_4massEdS3W_dS3U_S1N_S3V_dS4B_dNS3_14energy_contentEdS4A_dNS3_4xminEdNS3_4xmaxEdNS3_4yminEdNS3_4ymaxEdNS3_4zminEdNS3_4zmaxEdNS3_11orientationES1N_NS3_8initiateENSD_12InitiateTypeENS3_5pointES1N_NS3_9init_timeEdNS3_11front_widthEdNS3_11front_speedEdEEEEESaIS4U_EENS3_9meshblockES1L_INS0_INS2_IJNS3_7blockidEmS49_mS4D_dS4E_dS3W_dS3U_S1N_S3V_dS4B_dS4F_dS4A_dS4N_S4O_S4P_S1N_S4Q_dS4R_dS4S_dEEEEESaIS50_EEEEEEES3L_S1L_INS0_INS2_IJNS3_8filenameESA_NS3_8locationES1N_S4M_S1N_S3U_S1N_EEEEESaIS58_EENS3_8transferES1L_INSC_8TransferESaIS5C_EENS3_3aleENS0_INS2_IJS5F_bNS3_8smootherENSD_24MeshVelocitySmootherTypeENS3_13mesh_velocityENSD_16MeshVelocityTypeENS3_11mesh_motionES2S_NS3_9meshforceES1N_NS3_5dvcflEdNS3_8vortmultEdNS3_5maxitEmNS3_9toleranceEdS3M_S2S_S3N_S2S_NS3_4moveES1L_INS0_INS2_IJS3Y_S2S_NS3_6fntypeENST_13UserTableTypeES3Z_S1N_EEEEESaIS5U_EEEEEEENS3_4prefENS0_INS2_IJS5Z_bNS3_9indicatorENSD_17PrefIndicatorTypeENS3_7ndofmaxEmNS3_6tolrefEdEEEEENS3_3amrENS0_INS2_IJS66_bNS3_5t0refEbNS3_5dtrefEbNS3_13dtref_uniformEbNS3_6dtfreqEmNS3_9maxlevelsEmNS3_7initialES1L_INSD_14AMRInitialTypeESaIS6D_EENS3_8edgelistES2S_NS3_6coordsENS0_INS2_IJNS3_6xminusEdNS3_5xplusEdNS3_6yminusEdNS3_5yplusEdNS3_6zminusEdNS3_5zplusEdEEEEENS3_5errorENSD_12AMRErrorTypeENS3_6refvarES2D_NS3_10tol_refineEdNS3_12tol_derefineEdEEEEENS3_12field_outputENS0_INS2_IJNS3_8intervalEjNS3_13time_intervalEdNS3_10time_rangeES1N_NS3_7refinedEbNS3_8filetypeENST_13FieldFileTypeES3Y_S2S_NS3_6outvarES1L_INSD_6OutVarESaIS75_EENS3_9elemaliasES1L_ISA_SaISA_EENS3_7elemvarES7A_NS3_9nodealiasES7A_NS3_7nodevarES7A_EEEEENS3_11diagnosticsENS0_INS2_IJS6Y_jS6Q_NST_9ErrorTypeENS3_6formatENST_18TxtFloatFormatTypeENS3_9precisionElEEEEENS3_14history_outputENS0_INS2_IJS6Y_jS6Z_dS70_S1N_S7I_S7J_S7K_lS4P_S1L_INS0_INS2_IJS2Q_SA_NS3_5coordES1N_EEEEESaIS7Q_EEEEEEEEEEE3getIS17_JEEERDav10365
auto const& tk::TaggedTuple<brigand::list<tag::materialid, unsigned long, tag::pressure, double, tag::temperature, double, tag::density, double, tag::energy, double, tag::velocity, std::vector<double, std::allocator<double> >, tag::box, std::vector<tk::TaggedTuple<brigand::list<tag::materialid, unsigned long, tag::volume, double, tag::mass, double, tag::density, double, tag::velocity, std::vector<double, std::allocator<double> >, tag::pressure, double, tag::energy, double, tag::energy_content, double, tag::temperature, double, tag::xmin, double, tag::xmax, double, tag::ymin, double, tag::ymax, double, tag::zmin, double, tag::zmax, double, tag::orientation, std::vector<double, std::allocator<double> >, tag::initiate, inciter::ctr::InitiateType, tag::point, std::vector<double, std::allocator<double> >, tag::init_time, double, tag::front_width, double, tag::front_speed, double> >, std::allocator<tk::TaggedTuple<brigand::list<tag::materialid, unsigned long, tag::volume, double, tag::mass, double, tag::density, double, tag::velocity, std::vector<double, std::allocator<double> >, tag::pressure, double, tag::energy, double, tag::energy_content, double, tag::temperature, double, tag::xmin, double, tag::xmax, double, tag::ymin, double, tag::ymax, double, tag::zmin, double, tag::zmax, double, tag::orientation, std::vector<double, std::allocator<double> >, tag::initiate, inciter::ctr::InitiateType, tag::point, std::vector<double, std::allocator<double> >, tag::init_time, double, tag::front_width, double, tag::front_speed, double> > > >, tag::meshblock, std::vector<tk::TaggedTuple<brigand::list<tag::blockid, unsigned long, tag::materialid, unsigned long, tag::volume, double, tag::mass, double, tag::density, double, tag::velocity, std::vector<double, std::allocator<double> >, tag::pressure, double, tag::energy, double, tag::energy_content, double, tag::temperature, double, tag::initiate, inciter::ctr::InitiateType, tag::point, std::vector<double, std::allocator<double> >, tag::init_time, double, tag::front_width, double, tag::front_speed, double> >, std::allocator<tk::TaggedTuple<brigand::list<tag::blockid, unsigned long, tag::materialid, unsigned long, tag::volume, double, tag::mass, double, tag::density, double, tag::velocity, std::vector<double, std::allocator<double> >, tag::pressure, double, tag::energy, double, tag::energy_content, double, tag::temperature, double, tag::initiate, inciter::ctr::InitiateType, tag::point, std::vector<double, std::allocator<double> >, tag::init_time, double, tag::front_width, double, tag::front_speed, double> > > > > >::get<tag::materialid>() const
tk::TaggedTuple<brigand::list<tag::queried, CkCallback, tag::responded, CkCallback, tag::discinserted, CkCallback, tag::workinserted, CkCallback> >::TaggedTuple()2028920115
_ZN2tk11TaggedTupleIN7brigand4listIJN3tag5titleENSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEENS3_3cmdEN7inciter3ctr7CmdLineENS3_5nstepEmNS3_4termEdNS3_2t0EdNS3_2dtEdNS3_3cflEdNS3_4ttyiEjNS3_16imex_runge_kuttaEjNS3_12imex_maxiterEjNS3_11imex_reltolEdNS3_11imex_abstolEdNS3_12steady_stateEbNS3_8residualEdNS3_7rescompEjNS3_12partitioningENS_3ctr25PartitioningAlgorithmTypeENS3_15pelocal_reorderEbNS3_16operator_reorderEbNS3_6schemeENSD_10SchemeTypeENS3_4ndofEmNS3_4rdofEmNS3_4fluxENSD_8FluxTypeENS3_11lowspeed_kpEdNS3_7limiterENSD_11LimiterTypeENS3_7cweightEdNS3_20shock_detector_coeffEdNS3_13accuracy_testEbNS3_17limsol_projectionEbNS3_5ncompEmNS3_3pdeENSD_7PDETypeENS3_9transportENS0_INS2_IJNS3_7physicsENSD_11PhysicsTypeES1A_mNS3_8intsharpEiNS3_14intsharp_paramEdNS3_7problemENSD_11ProblemTypeENS3_11diffusivityESt6vectorIdSaIdEENS3_6lambdaES1N_NS3_2u0ES1N_EEEEENS3_8compflowENS0_INS2_IJS1E_S1F_S1I_S1J_NS3_5alphaEdNS3_4betaEdNS3_5betaxEdNS3_5betayEdNS3_5betazEdNS3_2r0EdNS3_2p0EdNS3_2ceEdNS3_5kappaEdEEEEENS3_8multimatENS0_INS2_IJS1E_S1F_NS3_4nmatEmNS3_6prelaxEmNS3_16prelax_timescaleEdS1G_iS1H_dNS3_14rho0constraintEmNS3_14dt_sos_massavgEiS1I_S1J_EEEEENS3_6depvarES1L_IcS9_ENS3_3sysESt3mapImmSt4lessImESaISt4pairIKmmEEENS3_8materialES1L_INS0_INS2_IJNS3_3eosENSD_12MaterialTypeENS3_2idES1L_ImSaImEENS3_5gammaES1N_NS3_6pstiffES1N_NS3_5w_gruES1N_NS3_5A_jwlES1N_NS3_5B_jwlES1N_NS3_5C_jwlES1N_NS3_6R1_jwlES1N_NS3_6R2_jwlES1N_NS3_8rho0_jwlES1N_NS3_6de_jwlES1N_NS3_8rhor_jwlES1N_NS3_6Tr_jwlES1N_NS3_6Pr_jwlES1N_NS3_2muES1N_NS3_12yield_stressES1N_NS3_2cvES1N_NS3_1kES1N_EEEEESaIS3B_EENS3_9matidxmapENS0_INS2_IJNS3_6eosidxES2S_NS3_6matidxES2S_NS3_6solidxES2S_EEEEENS3_2bcES1L_INS0_INS2_IJNS3_4meshES2S_NS3_9dirichletES2S_NS3_8symmetryES2S_NS3_5inletES2S_NS3_6outletES2S_NS3_8farfieldES2S_NS3_11extrapolateES2S_NS3_10stag_pointES1N_NS3_6radiusEdNS3_8velocityES1N_NS3_8pressureEdNS3_7densityEdNS3_7timedepES1L_INS0_INS2_IJNS3_7sidesetES2S_NS3_2fnES1N_EEEEESaIS41_EEEEEEESaIS45_EENS3_2icENS0_INS2_IJNS3_10materialidEmS3V_dNS3_11temperatureEdS3W_dNS3_6energyEdS3U_S1N_NS3_3boxES1L_INS0_INS2_IJS49_mNS3_6volumeEdNS3_4massEdS3W_dS3U_S1N_S3V_dS4B_dNS3_14energy_contentEdS4A_dNS3_4xminEdNS3_4xmaxEdNS3_4yminEdNS3_4ymaxEdNS3_4zminEdNS3_4zmaxEdNS3_11orientationES1N_NS3_8initiateENSD_12InitiateTypeENS3_5pointES1N_NS3_9init_timeEdNS3_11front_widthEdNS3_11front_speedEdEEEEESaIS4U_EENS3_9meshblockES1L_INS0_INS2_IJNS3_7blockidEmS49_mS4D_dS4E_dS3W_dS3U_S1N_S3V_dS4B_dS4F_dS4A_dS4N_S4O_S4P_S1N_S4Q_dS4R_dS4S_dEEEEESaIS50_EEEEEEES3L_S1L_INS0_INS2_IJNS3_8filenameESA_NS3_8locationES1N_S4M_S1N_S3U_S1N_EEEEESaIS58_EENS3_8transferES1L_INSC_8TransferESaIS5C_EENS3_3aleENS0_INS2_IJS5F_bNS3_8smootherENSD_24MeshVelocitySmootherTypeENS3_13mesh_velocityENSD_16MeshVelocityTypeENS3_11mesh_motionES2S_NS3_9meshforceES1N_NS3_5dvcflEdNS3_8vortmultEdNS3_5maxitEmNS3_9toleranceEdS3M_S2S_S3N_S2S_NS3_4moveES1L_INS0_INS2_IJS3Y_S2S_NS3_6fntypeENST_13UserTableTypeES3Z_S1N_EEEEESaIS5U_EEEEEEENS3_4prefENS0_INS2_IJS5Z_bNS3_9indicatorENSD_17PrefIndicatorTypeENS3_7ndofmaxEmNS3_6tolrefEdEEEEENS3_3amrENS0_INS2_IJS66_bNS3_5t0refEbNS3_5dtrefEbNS3_13dtref_uniformEbNS3_6dtfreqEmNS3_9maxlevelsEmNS3_7initialES1L_INSD_14AMRInitialTypeESaIS6D_EENS3_8edgelistES2S_NS3_6coordsENS0_INS2_IJNS3_6xminusEdNS3_5xplusEdNS3_6yminusEdNS3_5yplusEdNS3_6zminusEdNS3_5zplusEdEEEEENS3_5errorENSD_12AMRErrorTypeENS3_6refvarES2D_NS3_10tol_refineEdNS3_12tol_derefineEdEEEEENS3_12field_outputENS0_INS2_IJNS3_8intervalEjNS3_13time_intervalEdNS3_10time_rangeES1N_NS3_7refinedEbNS3_8filetypeENST_13FieldFileTypeES3Y_S2S_NS3_6outvarES1L_INSD_6OutVarESaIS75_EENS3_9elemaliasES1L_ISA_SaISA_EENS3_7elemvarES7A_NS3_9nodealiasES7A_NS3_7nodevarES7A_EEEEENS3_11diagnosticsENS0_INS2_IJS6Y_jS6Q_NST_9ErrorTypeENS3_6formatENST_18TxtFloatFormatTypeENS3_9precisionElEEEEENS3_14history_outputENS0_INS2_IJS6Y_jS6Z_dS70_S1N_S7I_S7J_S7K_lS4P_S1L_INS0_INS2_IJS2Q_SA_NS3_5coordES1N_EEEEESaIS7Q_EEEEEEEEEEE3getIS6X_JS74_EEERDavauto& tk::TaggedTuple<brigand::list<tag::io, tk::TaggedTuple<brigand::list<tag::nrestart, int, tag::control, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, tag::input, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, tag::output, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, tag::refined, bool, tag::screen, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, tag::surface, std::vector<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::allocator<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > > >, tag::diag, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, tag::particles, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, tag::outvar, std::vector<inciter::ctr::OutVar, std::allocator<inciter::ctr::OutVar> >, tag::restart, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > > >, tag::virtualization, double, tag::verbose, bool, tag::chare, bool, tag::nonblocking, bool, tag::benchmark, bool, tag::feedback, bool, tag::help, bool, tag::helpctr, bool, tag::quiescence, bool, tag::trace, bool, tag::version, bool, tag::license, bool, tag::cmdinfo, std::map<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, tk::ctr::KeywordInfo, std::less<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >, std::allocator<std::pair<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const, tk::ctr::KeywordInfo> > >, tag::ctrinfo, std::map<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, tk::ctr::KeywordInfo, std::less<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >, std::allocator<std::pair<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const, tk::ctr::KeywordInfo> > >, tag::helpkw, tk::ctr::HelpKw, tag::error, std::vector<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::allocator<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > > >, tag::lbfreq, unsigned long, tag::rsfreq, unsigned long> >::get<tag::quiescence>() 30688
_ZN2tk11TaggedTupleIN7brigand4listIJN3tag5titleENSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEENS3_3cmdEN7inciter3ctr7CmdLineENS3_5nstepEmNS3_4termEdNS3_2t0EdNS3_2dtEdNS3_3cflEdNS3_4ttyiEjNS3_16imex_runge_kuttaEjNS3_12imex_maxiterEjNS3_11imex_reltolEdNS3_11imex_abstolEdNS3_12steady_stateEbNS3_8residualEdNS3_7rescompEjNS3_12partitioningENS_3ctr25PartitioningAlgorithmTypeENS3_15pelocal_reorderEbNS3_16operator_reorderEbNS3_6schemeENSD_10SchemeTypeENS3_4ndofEmNS3_4rdofEmNS3_4fluxENSD_8FluxTypeENS3_11lowspeed_kpEdNS3_7limiterENSD_11LimiterTypeENS3_7cweightEdNS3_20shock_detector_coeffEdNS3_13accuracy_testEbNS3_17limsol_projectionEbNS3_5ncompEmNS3_3pdeENSD_7PDETypeENS3_9transportENS0_INS2_IJNS3_7physicsENSD_11PhysicsTypeES1A_mNS3_8intsharpEiNS3_14intsharp_paramEdNS3_7problemENSD_11ProblemTypeENS3_11diffusivityESt6vectorIdSaIdEENS3_6lambdaES1N_NS3_2u0ES1N_EEEEENS3_8compflowENS0_INS2_IJS1E_S1F_S1I_S1J_NS3_5alphaEdNS3_4betaEdNS3_5betaxEdNS3_5betayEdNS3_5betazEdNS3_2r0EdNS3_2p0EdNS3_2ceEdNS3_5kappaEdEEEEENS3_8multimatENS0_INS2_IJS1E_S1F_NS3_4nmatEmNS3_6prelaxEmNS3_16prelax_timescaleEdS1G_iS1H_dNS3_14rho0constraintEmNS3_14dt_sos_massavgEiS1I_S1J_EEEEENS3_6depvarES1L_IcS9_ENS3_3sysESt3mapImmSt4lessImESaISt4pairIKmmEEENS3_8materialES1L_INS0_INS2_IJNS3_3eosENSD_12MaterialTypeENS3_2idES1L_ImSaImEENS3_5gammaES1N_NS3_6pstiffES1N_NS3_5w_gruES1N_NS3_5A_jwlES1N_NS3_5B_jwlES1N_NS3_5C_jwlES1N_NS3_6R1_jwlES1N_NS3_6R2_jwlES1N_NS3_8rho0_jwlES1N_NS3_6de_jwlES1N_NS3_8rhor_jwlES1N_NS3_6Tr_jwlES1N_NS3_6Pr_jwlES1N_NS3_2muES1N_NS3_12yield_stressES1N_NS3_2cvES1N_NS3_1kES1N_EEEEESaIS3B_EENS3_9matidxmapENS0_INS2_IJNS3_6eosidxES2S_NS3_6matidxES2S_NS3_6solidxES2S_EEEEENS3_2bcES1L_INS0_INS2_IJNS3_4meshES2S_NS3_9dirichletES2S_NS3_8symmetryES2S_NS3_5inletES2S_NS3_6outletES2S_NS3_8farfieldES2S_NS3_11extrapolateES2S_NS3_10stag_pointES1N_NS3_6radiusEdNS3_8velocityES1N_NS3_8pressureEdNS3_7densityEdNS3_7timedepES1L_INS0_INS2_IJNS3_7sidesetES2S_NS3_2fnES1N_EEEEESaIS41_EEEEEEESaIS45_EENS3_2icENS0_INS2_IJNS3_10materialidEmS3V_dNS3_11temperatureEdS3W_dNS3_6energyEdS3U_S1N_NS3_3boxES1L_INS0_INS2_IJS49_mNS3_6volumeEdNS3_4massEdS3W_dS3U_S1N_S3V_dS4B_dNS3_14energy_contentEdS4A_dNS3_4xminEdNS3_4xmaxEdNS3_4yminEdNS3_4ymaxEdNS3_4zminEdNS3_4zmaxEdNS3_11orientationES1N_NS3_8initiateENSD_12InitiateTypeENS3_5pointES1N_NS3_9init_timeEdNS3_11front_widthEdNS3_11front_speedEdEEEEESaIS4U_EENS3_9meshblockES1L_INS0_INS2_IJNS3_7blockidEmS49_mS4D_dS4E_dS3W_dS3U_S1N_S3V_dS4B_dS4F_dS4A_dS4N_S4O_S4P_S1N_S4Q_dS4R_dS4S_dEEEEESaIS50_EEEEEEES3L_S1L_INS0_INS2_IJNS3_8filenameESA_NS3_8locationES1N_S4M_S1N_S3U_S1N_EEEEESaIS58_EENS3_8transferES1L_INSC_8TransferESaIS5C_EENS3_3aleENS0_INS2_IJS5F_bNS3_8smootherENSD_24MeshVelocitySmootherTypeENS3_13mesh_velocityENSD_16MeshVelocityTypeENS3_11mesh_motionES2S_NS3_9meshforceES1N_NS3_5dvcflEdNS3_8vortmultEdNS3_5maxitEmNS3_9toleranceEdS3M_S2S_S3N_S2S_NS3_4moveES1L_INS0_INS2_IJS3Y_S2S_NS3_6fntypeENST_13UserTableTypeES3Z_S1N_EEEEESaIS5U_EEEEEEENS3_4prefENS0_INS2_IJS5Z_bNS3_9indicatorENSD_17PrefIndicatorTypeENS3_7ndofmaxEmNS3_6tolrefEdEEEEENS3_3amrENS0_INS2_IJS66_bNS3_5t0refEbNS3_5dtrefEbNS3_13dtref_uniformEbNS3_6dtfreqEmNS3_9maxlevelsEmNS3_7initialES1L_INSD_14AMRInitialTypeESaIS6D_EENS3_8edgelistES2S_NS3_6coordsENS0_INS2_IJNS3_6xminusEdNS3_5xplusEdNS3_6yminusEdNS3_5yplusEdNS3_6zminusEdNS3_5zplusEdEEEEENS3_5errorENSD_12AMRErrorTypeENS3_6refvarES2D_NS3_10tol_refineEdNS3_12tol_derefineEdEEEEENS3_12field_outputENS0_INS2_IJNS3_8intervalEjNS3_13time_intervalEdNS3_10time_rangeES1N_NS3_7refinedEbNS3_8filetypeENST_13FieldFileTypeES3Y_S2S_NS3_6outvarES1L_INSD_6OutVarESaIS75_EENS3_9elemaliasES1L_ISA_SaISA_EENS3_7elemvarES7A_NS3_9nodealiasES7A_NS3_7nodevarES7A_EEEEENS3_11diagnosticsENS0_INS2_IJS6Y_jS6Q_NST_9ErrorTypeENS3_6formatENST_18TxtFloatFormatTypeENS3_9precisionElEEEEENS3_14history_outputENS0_INS2_IJS6Y_jS6Z_dS70_S1N_S7I_S7J_S7K_lS4P_S1L_INS0_INS2_IJS2Q_SA_NS3_5coordES1N_EEEEESaIS7Q_EEEEEEEEEEE3getISB_JNS3_5chareEEEERDav31530
tk::TaggedTuple<brigand::list<tag::queried, CkCallback, tag::responded, CkCallback, tag::compatibility, CkCallback, tag::bndint, CkCallback, tag::matched, CkCallback, tag::refined, CkCallback> >::pup(PUP::er&)3164231381
tk::operator|(PUP::er&, tk::TaggedTuple<brigand::list<tag::queried, CkCallback, tag::responded, CkCallback, tag::compatibility, CkCallback, tag::bndint, CkCallback, tag::matched, CkCallback, tag::refined, CkCallback> >&)3164231381
_ZN2tk11TaggedTupleIN7brigand4listIJN3tag5titleENSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEENS3_3cmdEN7inciter3ctr7CmdLineENS3_5nstepEmNS3_4termEdNS3_2t0EdNS3_2dtEdNS3_3cflEdNS3_4ttyiEjNS3_16imex_runge_kuttaEjNS3_12imex_maxiterEjNS3_11imex_reltolEdNS3_11imex_abstolEdNS3_12steady_stateEbNS3_8residualEdNS3_7rescompEjNS3_12partitioningENS_3ctr25PartitioningAlgorithmTypeENS3_15pelocal_reorderEbNS3_16operator_reorderEbNS3_6schemeENSD_10SchemeTypeENS3_4ndofEmNS3_4rdofEmNS3_4fluxENSD_8FluxTypeENS3_11lowspeed_kpEdNS3_7limiterENSD_11LimiterTypeENS3_7cweightEdNS3_20shock_detector_coeffEdNS3_13accuracy_testEbNS3_17limsol_projectionEbNS3_5ncompEmNS3_3pdeENSD_7PDETypeENS3_9transportENS0_INS2_IJNS3_7physicsENSD_11PhysicsTypeES1A_mNS3_8intsharpEiNS3_14intsharp_paramEdNS3_7problemENSD_11ProblemTypeENS3_11diffusivityESt6vectorIdSaIdEENS3_6lambdaES1N_NS3_2u0ES1N_EEEEENS3_8compflowENS0_INS2_IJS1E_S1F_S1I_S1J_NS3_5alphaEdNS3_4betaEdNS3_5betaxEdNS3_5betayEdNS3_5betazEdNS3_2r0EdNS3_2p0EdNS3_2ceEdNS3_5kappaEdEEEEENS3_8multimatENS0_INS2_IJS1E_S1F_NS3_4nmatEmNS3_6prelaxEmNS3_16prelax_timescaleEdS1G_iS1H_dNS3_14rho0constraintEmNS3_14dt_sos_massavgEiS1I_S1J_EEEEENS3_6depvarES1L_IcS9_ENS3_3sysESt3mapImmSt4lessImESaISt4pairIKmmEEENS3_8materialES1L_INS0_INS2_IJNS3_3eosENSD_12MaterialTypeENS3_2idES1L_ImSaImEENS3_5gammaES1N_NS3_6pstiffES1N_NS3_5w_gruES1N_NS3_5A_jwlES1N_NS3_5B_jwlES1N_NS3_5C_jwlES1N_NS3_6R1_jwlES1N_NS3_6R2_jwlES1N_NS3_8rho0_jwlES1N_NS3_6de_jwlES1N_NS3_8rhor_jwlES1N_NS3_6Tr_jwlES1N_NS3_6Pr_jwlES1N_NS3_2muES1N_NS3_12yield_stressES1N_NS3_2cvES1N_NS3_1kES1N_EEEEESaIS3B_EENS3_9matidxmapENS0_INS2_IJNS3_6eosidxES2S_NS3_6matidxES2S_NS3_6solidxES2S_EEEEENS3_2bcES1L_INS0_INS2_IJNS3_4meshES2S_NS3_9dirichletES2S_NS3_8symmetryES2S_NS3_5inletES2S_NS3_6outletES2S_NS3_8farfieldES2S_NS3_11extrapolateES2S_NS3_10stag_pointES1N_NS3_6radiusEdNS3_8velocityES1N_NS3_8pressureEdNS3_7densityEdNS3_7timedepES1L_INS0_INS2_IJNS3_7sidesetES2S_NS3_2fnES1N_EEEEESaIS41_EEEEEEESaIS45_EENS3_2icENS0_INS2_IJNS3_10materialidEmS3V_dNS3_11temperatureEdS3W_dNS3_6energyEdS3U_S1N_NS3_3boxES1L_INS0_INS2_IJS49_mNS3_6volumeEdNS3_4massEdS3W_dS3U_S1N_S3V_dS4B_dNS3_14energy_contentEdS4A_dNS3_4xminEdNS3_4xmaxEdNS3_4yminEdNS3_4ymaxEdNS3_4zminEdNS3_4zmaxEdNS3_11orientationES1N_NS3_8initiateENSD_12InitiateTypeENS3_5pointES1N_NS3_9init_timeEdNS3_11front_widthEdNS3_11front_speedEdEEEEESaIS4U_EENS3_9meshblockES1L_INS0_INS2_IJNS3_7blockidEmS49_mS4D_dS4E_dS3W_dS3U_S1N_S3V_dS4B_dS4F_dS4A_dS4N_S4O_S4P_S1N_S4Q_dS4R_dS4S_dEEEEESaIS50_EEEEEEES3L_S1L_INS0_INS2_IJNS3_8filenameESA_NS3_8locationES1N_S4M_S1N_S3U_S1N_EEEEESaIS58_EENS3_8transferES1L_INSC_8TransferESaIS5C_EENS3_3aleENS0_INS2_IJS5F_bNS3_8smootherENSD_24MeshVelocitySmootherTypeENS3_13mesh_velocityENSD_16MeshVelocityTypeENS3_11mesh_motionES2S_NS3_9meshforceES1N_NS3_5dvcflEdNS3_8vortmultEdNS3_5maxitEmNS3_9toleranceEdS3M_S2S_S3N_S2S_NS3_4moveES1L_INS0_INS2_IJS3Y_S2S_NS3_6fntypeENST_13UserTableTypeES3Z_S1N_EEEEESaIS5U_EEEEEEENS3_4prefENS0_INS2_IJS5Z_bNS3_9indicatorENSD_17PrefIndicatorTypeENS3_7ndofmaxEmNS3_6tolrefEdEEEEENS3_3amrENS0_INS2_IJS66_bNS3_5t0refEbNS3_5dtrefEbNS3_13dtref_uniformEbNS3_6dtfreqEmNS3_9maxlevelsEmNS3_7initialES1L_INSD_14AMRInitialTypeESaIS6D_EENS3_8edgelistES2S_NS3_6coordsENS0_INS2_IJNS3_6xminusEdNS3_5xplusEdNS3_6yminusEdNS3_5yplusEdNS3_6zminusEdNS3_5zplusEdEEEEENS3_5errorENSD_12AMRErrorTypeENS3_6refvarES2D_NS3_10tol_refineEdNS3_12tol_derefineEdEEEEENS3_12field_outputENS0_INS2_IJNS3_8intervalEjNS3_13time_intervalEdNS3_10time_rangeES1N_NS3_7refinedEbNS3_8filetypeENST_13FieldFileTypeES3Y_S2S_NS3_6outvarES1L_INSD_6OutVarESaIS75_EENS3_9elemaliasES1L_ISA_SaISA_EENS3_7elemvarES7A_NS3_9nodealiasES7A_NS3_7nodevarES7A_EEEEENS3_11diagnosticsENS0_INS2_IJS6Y_jS6Q_NST_9ErrorTypeENS3_6formatENST_18TxtFloatFormatTypeENS3_9precisionElEEEEENS3_14history_outputENS0_INS2_IJS6Y_jS6Z_dS70_S1N_S7I_S7J_S7K_lS4P_S1L_INS0_INS2_IJS2Q_SA_NS3_5coordES1N_EEEEESaIS7Q_EEEEEEEEEEE3getISB_JNS3_5chareEEEERDav31530
_ZN2tk11TaggedTupleIN7brigand4listIJN3tag5titleENSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEENS3_3cmdEN7inciter3ctr7CmdLineENS3_5nstepEmNS3_4termEdNS3_2t0EdNS3_2dtEdNS3_3cflEdNS3_4ttyiEjNS3_16imex_runge_kuttaEjNS3_12imex_maxiterEjNS3_11imex_reltolEdNS3_11imex_abstolEdNS3_12steady_stateEbNS3_8residualEdNS3_7rescompEjNS3_12partitioningENS_3ctr25PartitioningAlgorithmTypeENS3_15pelocal_reorderEbNS3_16operator_reorderEbNS3_6schemeENSD_10SchemeTypeENS3_4ndofEmNS3_4rdofEmNS3_4fluxENSD_8FluxTypeENS3_11lowspeed_kpEdNS3_7limiterENSD_11LimiterTypeENS3_7cweightEdNS3_20shock_detector_coeffEdNS3_13accuracy_testEbNS3_17limsol_projectionEbNS3_5ncompEmNS3_3pdeENSD_7PDETypeENS3_9transportENS0_INS2_IJNS3_7physicsENSD_11PhysicsTypeES1A_mNS3_8intsharpEiNS3_14intsharp_paramEdNS3_7problemENSD_11ProblemTypeENS3_11diffusivityESt6vectorIdSaIdEENS3_6lambdaES1N_NS3_2u0ES1N_EEEEENS3_8compflowENS0_INS2_IJS1E_S1F_S1I_S1J_NS3_5alphaEdNS3_4betaEdNS3_5betaxEdNS3_5betayEdNS3_5betazEdNS3_2r0EdNS3_2p0EdNS3_2ceEdNS3_5kappaEdEEEEENS3_8multimatENS0_INS2_IJS1E_S1F_NS3_4nmatEmNS3_6prelaxEmNS3_16prelax_timescaleEdS1G_iS1H_dNS3_14rho0constraintEmNS3_14dt_sos_massavgEiS1I_S1J_EEEEENS3_6depvarES1L_IcS9_ENS3_3sysESt3mapImmSt4lessImESaISt4pairIKmmEEENS3_8materialES1L_INS0_INS2_IJNS3_3eosENSD_12MaterialTypeENS3_2idES1L_ImSaImEENS3_5gammaES1N_NS3_6pstiffES1N_NS3_5w_gruES1N_NS3_5A_jwlES1N_NS3_5B_jwlES1N_NS3_5C_jwlES1N_NS3_6R1_jwlES1N_NS3_6R2_jwlES1N_NS3_8rho0_jwlES1N_NS3_6de_jwlES1N_NS3_8rhor_jwlES1N_NS3_6Tr_jwlES1N_NS3_6Pr_jwlES1N_NS3_2muES1N_NS3_12yield_stressES1N_NS3_2cvES1N_NS3_1kES1N_EEEEESaIS3B_EENS3_9matidxmapENS0_INS2_IJNS3_6eosidxES2S_NS3_6matidxES2S_NS3_6solidxES2S_EEEEENS3_2bcES1L_INS0_INS2_IJNS3_4meshES2S_NS3_9dirichletES2S_NS3_8symmetryES2S_NS3_5inletES2S_NS3_6outletES2S_NS3_8farfieldES2S_NS3_11extrapolateES2S_NS3_10stag_pointES1N_NS3_6radiusEdNS3_8velocityES1N_NS3_8pressureEdNS3_7densityEdNS3_7timedepES1L_INS0_INS2_IJNS3_7sidesetES2S_NS3_2fnES1N_EEEEESaIS41_EEEEEEESaIS45_EENS3_2icENS0_INS2_IJNS3_10materialidEmS3V_dNS3_11temperatureEdS3W_dNS3_6energyEdS3U_S1N_NS3_3boxES1L_INS0_INS2_IJS49_mNS3_6volumeEdNS3_4massEdS3W_dS3U_S1N_S3V_dS4B_dNS3_14energy_contentEdS4A_dNS3_4xminEdNS3_4xmaxEdNS3_4yminEdNS3_4ymaxEdNS3_4zminEdNS3_4zmaxEdNS3_11orientationES1N_NS3_8initiateENSD_12InitiateTypeENS3_5pointES1N_NS3_9init_timeEdNS3_11front_widthEdNS3_11front_speedEdEEEEESaIS4U_EENS3_9meshblockES1L_INS0_INS2_IJNS3_7blockidEmS49_mS4D_dS4E_dS3W_dS3U_S1N_S3V_dS4B_dS4F_dS4A_dS4N_S4O_S4P_S1N_S4Q_dS4R_dS4S_dEEEEESaIS50_EEEEEEES3L_S1L_INS0_INS2_IJNS3_8filenameESA_NS3_8locationES1N_S4M_S1N_S3U_S1N_EEEEESaIS58_EENS3_8transferES1L_INSC_8TransferESaIS5C_EENS3_3aleENS0_INS2_IJS5F_bNS3_8smootherENSD_24MeshVelocitySmootherTypeENS3_13mesh_velocityENSD_16MeshVelocityTypeENS3_11mesh_motionES2S_NS3_9meshforceES1N_NS3_5dvcflEdNS3_8vortmultEdNS3_5maxitEmNS3_9toleranceEdS3M_S2S_S3N_S2S_NS3_4moveES1L_INS0_INS2_IJS3Y_S2S_NS3_6fntypeENST_13UserTableTypeES3Z_S1N_EEEEESaIS5U_EEEEEEENS3_4prefENS0_INS2_IJS5Z_bNS3_9indicatorENSD_17PrefIndicatorTypeENS3_7ndofmaxEmNS3_6tolrefEdEEEEENS3_3amrENS0_INS2_IJS66_bNS3_5t0refEbNS3_5dtrefEbNS3_13dtref_uniformEbNS3_6dtfreqEmNS3_9maxlevelsEmNS3_7initialES1L_INSD_14AMRInitialTypeESaIS6D_EENS3_8edgelistES2S_NS3_6coordsENS0_INS2_IJNS3_6xminusEdNS3_5xplusEdNS3_6yminusEdNS3_5yplusEdNS3_6zminusEdNS3_5zplusEdEEEEENS3_5errorENSD_12AMRErrorTypeENS3_6refvarES2D_NS3_10tol_refineEdNS3_12tol_derefineEdEEEEENS3_12field_outputENS0_INS2_IJNS3_8intervalEjNS3_13time_intervalEdNS3_10time_rangeES1N_NS3_7refinedEbNS3_8filetypeENST_13FieldFileTypeES3Y_S2S_NS3_6outvarES1L_INSD_6OutVarESaIS75_EENS3_9elemaliasES1L_ISA_SaISA_EENS3_7elemvarES7A_NS3_9nodealiasES7A_NS3_7nodevarES7A_EEEEENS3_11diagnosticsENS0_INS2_IJS6Y_jS6Q_NST_9ErrorTypeENS3_6formatENST_18TxtFloatFormatTypeENS3_9precisionElEEEEENS3_14history_outputENS0_INS2_IJS6Y_jS6Z_dS70_S1N_S7I_S7J_S7K_lS4P_S1L_INS0_INS2_IJS2Q_SA_NS3_5coordES1N_EEEEESaIS7Q_EEEEEEEEEEE3getIS48_JS4C_EEERDav
tk::TaggedTuple<brigand::list<tag::queried, CkCallback, tag::responded, CkCallback, tag::discinserted, CkCallback, tag::workinserted, CkCallback> >::pup(PUP::er&)6200861486
tk::operator|(PUP::er&, tk::TaggedTuple<brigand::list<tag::queried, CkCallback, tag::responded, CkCallback, tag::discinserted, CkCallback, tag::workinserted, CkCallback> >&)6200861486
_ZN2tk11TaggedTupleIN7brigand4listIJN3tag5titleENSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEENS3_3cmdEN7inciter3ctr7CmdLineENS3_5nstepEmNS3_4termEdNS3_2t0EdNS3_2dtEdNS3_3cflEdNS3_4ttyiEjNS3_16imex_runge_kuttaEjNS3_12imex_maxiterEjNS3_11imex_reltolEdNS3_11imex_abstolEdNS3_12steady_stateEbNS3_8residualEdNS3_7rescompEjNS3_12partitioningENS_3ctr25PartitioningAlgorithmTypeENS3_15pelocal_reorderEbNS3_16operator_reorderEbNS3_6schemeENSD_10SchemeTypeENS3_4ndofEmNS3_4rdofEmNS3_4fluxENSD_8FluxTypeENS3_11lowspeed_kpEdNS3_7limiterENSD_11LimiterTypeENS3_7cweightEdNS3_20shock_detector_coeffEdNS3_13accuracy_testEbNS3_17limsol_projectionEbNS3_5ncompEmNS3_3pdeENSD_7PDETypeENS3_9transportENS0_INS2_IJNS3_7physicsENSD_11PhysicsTypeES1A_mNS3_8intsharpEiNS3_14intsharp_paramEdNS3_7problemENSD_11ProblemTypeENS3_11diffusivityESt6vectorIdSaIdEENS3_6lambdaES1N_NS3_2u0ES1N_EEEEENS3_8compflowENS0_INS2_IJS1E_S1F_S1I_S1J_NS3_5alphaEdNS3_4betaEdNS3_5betaxEdNS3_5betayEdNS3_5betazEdNS3_2r0EdNS3_2p0EdNS3_2ceEdNS3_5kappaEdEEEEENS3_8multimatENS0_INS2_IJS1E_S1F_NS3_4nmatEmNS3_6prelaxEmNS3_16prelax_timescaleEdS1G_iS1H_dNS3_14rho0constraintEmNS3_14dt_sos_massavgEiS1I_S1J_EEEEENS3_6depvarES1L_IcS9_ENS3_3sysESt3mapImmSt4lessImESaISt4pairIKmmEEENS3_8materialES1L_INS0_INS2_IJNS3_3eosENSD_12MaterialTypeENS3_2idES1L_ImSaImEENS3_5gammaES1N_NS3_6pstiffES1N_NS3_5w_gruES1N_NS3_5A_jwlES1N_NS3_5B_jwlES1N_NS3_5C_jwlES1N_NS3_6R1_jwlES1N_NS3_6R2_jwlES1N_NS3_8rho0_jwlES1N_NS3_6de_jwlES1N_NS3_8rhor_jwlES1N_NS3_6Tr_jwlES1N_NS3_6Pr_jwlES1N_NS3_2muES1N_NS3_12yield_stressES1N_NS3_2cvES1N_NS3_1kES1N_EEEEESaIS3B_EENS3_9matidxmapENS0_INS2_IJNS3_6eosidxES2S_NS3_6matidxES2S_NS3_6solidxES2S_EEEEENS3_2bcES1L_INS0_INS2_IJNS3_4meshES2S_NS3_9dirichletES2S_NS3_8symmetryES2S_NS3_5inletES2S_NS3_6outletES2S_NS3_8farfieldES2S_NS3_11extrapolateES2S_NS3_10stag_pointES1N_NS3_6radiusEdNS3_8velocityES1N_NS3_8pressureEdNS3_7densityEdNS3_7timedepES1L_INS0_INS2_IJNS3_7sidesetES2S_NS3_2fnES1N_EEEEESaIS41_EEEEEEESaIS45_EENS3_2icENS0_INS2_IJNS3_10materialidEmS3V_dNS3_11temperatureEdS3W_dNS3_6energyEdS3U_S1N_NS3_3boxES1L_INS0_INS2_IJS49_mNS3_6volumeEdNS3_4massEdS3W_dS3U_S1N_S3V_dS4B_dNS3_14energy_contentEdS4A_dNS3_4xminEdNS3_4xmaxEdNS3_4yminEdNS3_4ymaxEdNS3_4zminEdNS3_4zmaxEdNS3_11orientationES1N_NS3_8initiateENSD_12InitiateTypeENS3_5pointES1N_NS3_9init_timeEdNS3_11front_widthEdNS3_11front_speedEdEEEEESaIS4U_EENS3_9meshblockES1L_INS0_INS2_IJNS3_7blockidEmS49_mS4D_dS4E_dS3W_dS3U_S1N_S3V_dS4B_dS4F_dS4A_dS4N_S4O_S4P_S1N_S4Q_dS4R_dS4S_dEEEEESaIS50_EEEEEEES3L_S1L_INS0_INS2_IJNS3_8filenameESA_NS3_8locationES1N_S4M_S1N_S3U_S1N_EEEEESaIS58_EENS3_8transferES1L_INSC_8TransferESaIS5C_EENS3_3aleENS0_INS2_IJS5F_bNS3_8smootherENSD_24MeshVelocitySmootherTypeENS3_13mesh_velocityENSD_16MeshVelocityTypeENS3_11mesh_motionES2S_NS3_9meshforceES1N_NS3_5dvcflEdNS3_8vortmultEdNS3_5maxitEmNS3_9toleranceEdS3M_S2S_S3N_S2S_NS3_4moveES1L_INS0_INS2_IJS3Y_S2S_NS3_6fntypeENST_13UserTableTypeES3Z_S1N_EEEEESaIS5U_EEEEEEENS3_4prefENS0_INS2_IJS5Z_bNS3_9indicatorENSD_17PrefIndicatorTypeENS3_7ndofmaxEmNS3_6tolrefEdEEEEENS3_3amrENS0_INS2_IJS66_bNS3_5t0refEbNS3_5dtrefEbNS3_13dtref_uniformEbNS3_6dtfreqEmNS3_9maxlevelsEmNS3_7initialES1L_INSD_14AMRInitialTypeESaIS6D_EENS3_8edgelistES2S_NS3_6coordsENS0_INS2_IJNS3_6xminusEdNS3_5xplusEdNS3_6yminusEdNS3_5yplusEdNS3_6zminusEdNS3_5zplusEdEEEEENS3_5errorENSD_12AMRErrorTypeENS3_6refvarES2D_NS3_10tol_refineEdNS3_12tol_derefineEdEEEEENS3_12field_outputENS0_INS2_IJNS3_8intervalEjNS3_13time_intervalEdNS3_10time_rangeES1N_NS3_7refinedEbNS3_8filetypeENST_13FieldFileTypeES3Y_S2S_NS3_6outvarES1L_INSD_6OutVarESaIS75_EENS3_9elemaliasES1L_ISA_SaISA_EENS3_7elemvarES7A_NS3_9nodealiasES7A_NS3_7nodevarES7A_EEEEENS3_11diagnosticsENS0_INS2_IJS6Y_jS6Q_NST_9ErrorTypeENS3_6formatENST_18TxtFloatFormatTypeENS3_9precisionElEEEEENS3_14history_outputENS0_INS2_IJS6Y_jS6Z_dS70_S1N_S7I_S7J_S7K_lS4P_S1L_INS0_INS2_IJS2Q_SA_NS3_5coordES1N_EEEEESaIS7Q_EEEEEEEEEEE3getISB_JNS3_11nonblockingEEEERDav
_ZN2tk11TaggedTupleIN7brigand4listIJN3tag5titleENSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEENS3_3cmdEN7inciter3ctr7CmdLineENS3_5nstepEmNS3_4termEdNS3_2t0EdNS3_2dtEdNS3_3cflEdNS3_4ttyiEjNS3_16imex_runge_kuttaEjNS3_12imex_maxiterEjNS3_11imex_reltolEdNS3_11imex_abstolEdNS3_12steady_stateEbNS3_8residualEdNS3_7rescompEjNS3_12partitioningENS_3ctr25PartitioningAlgorithmTypeENS3_15pelocal_reorderEbNS3_16operator_reorderEbNS3_6schemeENSD_10SchemeTypeENS3_4ndofEmNS3_4rdofEmNS3_4fluxENSD_8FluxTypeENS3_11lowspeed_kpEdNS3_7limiterENSD_11LimiterTypeENS3_7cweightEdNS3_20shock_detector_coeffEdNS3_13accuracy_testEbNS3_17limsol_projectionEbNS3_5ncompEmNS3_3pdeENSD_7PDETypeENS3_9transportENS0_INS2_IJNS3_7physicsENSD_11PhysicsTypeES1A_mNS3_8intsharpEiNS3_14intsharp_paramEdNS3_7problemENSD_11ProblemTypeENS3_11diffusivityESt6vectorIdSaIdEENS3_6lambdaES1N_NS3_2u0ES1N_EEEEENS3_8compflowENS0_INS2_IJS1E_S1F_S1I_S1J_NS3_5alphaEdNS3_4betaEdNS3_5betaxEdNS3_5betayEdNS3_5betazEdNS3_2r0EdNS3_2p0EdNS3_2ceEdNS3_5kappaEdEEEEENS3_8multimatENS0_INS2_IJS1E_S1F_NS3_4nmatEmNS3_6prelaxEmNS3_16prelax_timescaleEdS1G_iS1H_dNS3_14rho0constraintEmNS3_14dt_sos_massavgEiS1I_S1J_EEEEENS3_6depvarES1L_IcS9_ENS3_3sysESt3mapImmSt4lessImESaISt4pairIKmmEEENS3_8materialES1L_INS0_INS2_IJNS3_3eosENSD_12MaterialTypeENS3_2idES1L_ImSaImEENS3_5gammaES1N_NS3_6pstiffES1N_NS3_5w_gruES1N_NS3_5A_jwlES1N_NS3_5B_jwlES1N_NS3_5C_jwlES1N_NS3_6R1_jwlES1N_NS3_6R2_jwlES1N_NS3_8rho0_jwlES1N_NS3_6de_jwlES1N_NS3_8rhor_jwlES1N_NS3_6Tr_jwlES1N_NS3_6Pr_jwlES1N_NS3_2muES1N_NS3_12yield_stressES1N_NS3_2cvES1N_NS3_1kES1N_EEEEESaIS3B_EENS3_9matidxmapENS0_INS2_IJNS3_6eosidxES2S_NS3_6matidxES2S_NS3_6solidxES2S_EEEEENS3_2bcES1L_INS0_INS2_IJNS3_4meshES2S_NS3_9dirichletES2S_NS3_8symmetryES2S_NS3_5inletES2S_NS3_6outletES2S_NS3_8farfieldES2S_NS3_11extrapolateES2S_NS3_10stag_pointES1N_NS3_6radiusEdNS3_8velocityES1N_NS3_8pressureEdNS3_7densityEdNS3_7timedepES1L_INS0_INS2_IJNS3_7sidesetES2S_NS3_2fnES1N_EEEEESaIS41_EEEEEEESaIS45_EENS3_2icENS0_INS2_IJNS3_10materialidEmS3V_dNS3_11temperatureEdS3W_dNS3_6energyEdS3U_S1N_NS3_3boxES1L_INS0_INS2_IJS49_mNS3_6volumeEdNS3_4massEdS3W_dS3U_S1N_S3V_dS4B_dNS3_14energy_contentEdS4A_dNS3_4xminEdNS3_4xmaxEdNS3_4yminEdNS3_4ymaxEdNS3_4zminEdNS3_4zmaxEdNS3_11orientationES1N_NS3_8initiateENSD_12InitiateTypeENS3_5pointES1N_NS3_9init_timeEdNS3_11front_widthEdNS3_11front_speedEdEEEEESaIS4U_EENS3_9meshblockES1L_INS0_INS2_IJNS3_7blockidEmS49_mS4D_dS4E_dS3W_dS3U_S1N_S3V_dS4B_dS4F_dS4A_dS4N_S4O_S4P_S1N_S4Q_dS4R_dS4S_dEEEEESaIS50_EEEEEEES3L_S1L_INS0_INS2_IJNS3_8filenameESA_NS3_8locationES1N_S4M_S1N_S3U_S1N_EEEEESaIS58_EENS3_8transferES1L_INSC_8TransferESaIS5C_EENS3_3aleENS0_INS2_IJS5F_bNS3_8smootherENSD_24MeshVelocitySmootherTypeENS3_13mesh_velocityENSD_16MeshVelocityTypeENS3_11mesh_motionES2S_NS3_9meshforceES1N_NS3_5dvcflEdNS3_8vortmultEdNS3_5maxitEmNS3_9toleranceEdS3M_S2S_S3N_S2S_NS3_4moveES1L_INS0_INS2_IJS3Y_S2S_NS3_6fntypeENST_13UserTableTypeES3Z_S1N_EEEEESaIS5U_EEEEEEENS3_4prefENS0_INS2_IJS5Z_bNS3_9indicatorENSD_17PrefIndicatorTypeENS3_7ndofmaxEmNS3_6tolrefEdEEEEENS3_3amrENS0_INS2_IJS66_bNS3_5t0refEbNS3_5dtrefEbNS3_13dtref_uniformEbNS3_6dtfreqEmNS3_9maxlevelsEmNS3_7initialES1L_INSD_14AMRInitialTypeESaIS6D_EENS3_8edgelistES2S_NS3_6coordsENS0_INS2_IJNS3_6xminusEdNS3_5xplusEdNS3_6yminusEdNS3_5yplusEdNS3_6zminusEdNS3_5zplusEdEEEEENS3_5errorENSD_12AMRErrorTypeENS3_6refvarES2D_NS3_10tol_refineEdNS3_12tol_derefineEdEEEEENS3_12field_outputENS0_INS2_IJNS3_8intervalEjNS3_13time_intervalEdNS3_10time_rangeES1N_NS3_7refinedEbNS3_8filetypeENST_13FieldFileTypeES3Y_S2S_NS3_6outvarES1L_INSD_6OutVarESaIS75_EENS3_9elemaliasES1L_ISA_SaISA_EENS3_7elemvarES7A_NS3_9nodealiasES7A_NS3_7nodevarES7A_EEEEENS3_11diagnosticsENS0_INS2_IJS6Y_jS6Q_NST_9ErrorTypeENS3_6formatENST_18TxtFloatFormatTypeENS3_9precisionElEEEEENS3_14history_outputENS0_INS2_IJS6Y_jS6Z_dS70_S1N_S7I_S7J_S7K_lS4P_S1L_INS0_INS2_IJS2Q_SA_NS3_5coordES1N_EEEEESaIS7Q_EEEEEEEEEEE3getIS3E_JS3H_EEERDav113835329115378829
auto& tk::TaggedTuple<brigand::list<tag::eosidx, std::vector<unsigned long, std::allocator<unsigned long> >, tag::matidx, std::vector<unsigned long, std::allocator<unsigned long> >, tag::solidx, std::vector<unsigned long, std::allocator<unsigned long> > > >::get<tag::solidx>()113835329115378829

diff --git a/Debug/test_coverage/Base/TaggedTuple.hpp.func.html b/Debug/test_coverage/Base/TaggedTuple.hpp.func.html index 4bb650f347c4..b9f5239e2805 100644 --- a/Debug/test_coverage/Base/TaggedTuple.hpp.func.html +++ b/Debug/test_coverage/Base/TaggedTuple.hpp.func.html @@ -33,7 +33,7 @@
Date:2024-07-10 11:43:412024-07-11 15:06:04 Functions: 832
tk::TaggedTuple<brigand::list<tag::id, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, tag::elem, unsigned long, tag::coord, std::array<double, 3ul>, tag::fn, std::array<double, 4ul> > >::pup(PUP::er&)5255
tk::TaggedTuple<brigand::list<tag::id, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, tag::elem, unsigned long, tag::coord, std::array<double, 3ul>, tag::fn, std::array<double, 4ul> > >::TaggedTuple(std::tuple<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, unsigned long, std::array<double, 3ul>, std::array<double, 4ul> >&&)
tk::TaggedTuple<brigand::list<tag::id, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, tag::elem, unsigned long, tag::coord, std::array<double, 3ul>, tag::fn, std::array<double, 4ul> > >::TaggedTuple()1415
auto& tk::TaggedTuple<brigand::list<tag::id, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, tag::coord, std::vector<double, std::allocator<double> > > >::get<tag::id>()
_ZN2tk11TaggedTupleIN7brigand4listIJN3tag5titleENSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEENS3_3cmdEN7inciter3ctr7CmdLineENS3_5nstepEmNS3_4termEdNS3_2t0EdNS3_2dtEdNS3_3cflEdNS3_4ttyiEjNS3_16imex_runge_kuttaEjNS3_12imex_maxiterEjNS3_11imex_reltolEdNS3_11imex_abstolEdNS3_12steady_stateEbNS3_8residualEdNS3_7rescompEjNS3_12partitioningENS_3ctr25PartitioningAlgorithmTypeENS3_15pelocal_reorderEbNS3_16operator_reorderEbNS3_6schemeENSD_10SchemeTypeENS3_4ndofEmNS3_4rdofEmNS3_4fluxENSD_8FluxTypeENS3_11lowspeed_kpEdNS3_7limiterENSD_11LimiterTypeENS3_7cweightEdNS3_20shock_detector_coeffEdNS3_13accuracy_testEbNS3_17limsol_projectionEbNS3_5ncompEmNS3_3pdeENSD_7PDETypeENS3_9transportENS0_INS2_IJNS3_7physicsENSD_11PhysicsTypeES1A_mNS3_8intsharpEiNS3_14intsharp_paramEdNS3_7problemENSD_11ProblemTypeENS3_11diffusivityESt6vectorIdSaIdEENS3_6lambdaES1N_NS3_2u0ES1N_EEEEENS3_8compflowENS0_INS2_IJS1E_S1F_S1I_S1J_NS3_5alphaEdNS3_4betaEdNS3_5betaxEdNS3_5betayEdNS3_5betazEdNS3_2r0EdNS3_2p0EdNS3_2ceEdNS3_5kappaEdEEEEENS3_8multimatENS0_INS2_IJS1E_S1F_NS3_4nmatEmNS3_6prelaxEmNS3_16prelax_timescaleEdS1G_iS1H_dNS3_14rho0constraintEmNS3_14dt_sos_massavgEiS1I_S1J_EEEEENS3_6depvarES1L_IcS9_ENS3_3sysESt3mapImmSt4lessImESaISt4pairIKmmEEENS3_8materialES1L_INS0_INS2_IJNS3_3eosENSD_12MaterialTypeENS3_2idES1L_ImSaImEENS3_5gammaES1N_NS3_6pstiffES1N_NS3_5w_gruES1N_NS3_5A_jwlES1N_NS3_5B_jwlES1N_NS3_5C_jwlES1N_NS3_6R1_jwlES1N_NS3_6R2_jwlES1N_NS3_8rho0_jwlES1N_NS3_6de_jwlES1N_NS3_8rhor_jwlES1N_NS3_6Tr_jwlES1N_NS3_6Pr_jwlES1N_NS3_2muES1N_NS3_12yield_stressES1N_NS3_2cvES1N_NS3_1kES1N_EEEEESaIS3B_EENS3_9matidxmapENS0_INS2_IJNS3_6eosidxES2S_NS3_6matidxES2S_NS3_6solidxES2S_EEEEENS3_2bcES1L_INS0_INS2_IJNS3_4meshES2S_NS3_9dirichletES2S_NS3_8symmetryES2S_NS3_5inletES2S_NS3_6outletES2S_NS3_8farfieldES2S_NS3_11extrapolateES2S_NS3_10stag_pointES1N_NS3_6radiusEdNS3_8velocityES1N_NS3_8pressureEdNS3_7densityEdNS3_7timedepES1L_INS0_INS2_IJNS3_7sidesetES2S_NS3_2fnES1N_EEEEESaIS41_EEEEEEESaIS45_EENS3_2icENS0_INS2_IJNS3_10materialidEmS3V_dNS3_11temperatureEdS3W_dNS3_6energyEdS3U_S1N_NS3_3boxES1L_INS0_INS2_IJS49_mNS3_6volumeEdNS3_4massEdS3W_dS3U_S1N_S3V_dS4B_dNS3_14energy_contentEdS4A_dNS3_4xminEdNS3_4xmaxEdNS3_4yminEdNS3_4ymaxEdNS3_4zminEdNS3_4zmaxEdNS3_11orientationES1N_NS3_8initiateENSD_12InitiateTypeENS3_5pointES1N_NS3_9init_timeEdNS3_11front_widthEdNS3_11front_speedEdEEEEESaIS4U_EENS3_9meshblockES1L_INS0_INS2_IJNS3_7blockidEmS49_mS4D_dS4E_dS3W_dS3U_S1N_S3V_dS4B_dS4F_dS4A_dS4N_S4O_S4P_S1N_S4Q_dS4R_dS4S_dEEEEESaIS50_EEEEEEES3L_S1L_INS0_INS2_IJNS3_8filenameESA_NS3_8locationES1N_S4M_S1N_S3U_S1N_EEEEESaIS58_EENS3_8transferES1L_INSC_8TransferESaIS5C_EENS3_3aleENS0_INS2_IJS5F_bNS3_8smootherENSD_24MeshVelocitySmootherTypeENS3_13mesh_velocityENSD_16MeshVelocityTypeENS3_11mesh_motionES2S_NS3_9meshforceES1N_NS3_5dvcflEdNS3_8vortmultEdNS3_5maxitEmNS3_9toleranceEdS3M_S2S_S3N_S2S_NS3_4moveES1L_INS0_INS2_IJS3Y_S2S_NS3_6fntypeENST_13UserTableTypeES3Z_S1N_EEEEESaIS5U_EEEEEEENS3_4prefENS0_INS2_IJS5Z_bNS3_9indicatorENSD_17PrefIndicatorTypeENS3_7ndofmaxEmNS3_6tolrefEdEEEEENS3_3amrENS0_INS2_IJS66_bNS3_5t0refEbNS3_5dtrefEbNS3_13dtref_uniformEbNS3_6dtfreqEmNS3_9maxlevelsEmNS3_7initialES1L_INSD_14AMRInitialTypeESaIS6D_EENS3_8edgelistES2S_NS3_6coordsENS0_INS2_IJNS3_6xminusEdNS3_5xplusEdNS3_6yminusEdNS3_5yplusEdNS3_6zminusEdNS3_5zplusEdEEEEENS3_5errorENSD_12AMRErrorTypeENS3_6refvarES2D_NS3_10tol_refineEdNS3_12tol_derefineEdEEEEENS3_12field_outputENS0_INS2_IJNS3_8intervalEjNS3_13time_intervalEdNS3_10time_rangeES1N_NS3_7refinedEbNS3_8filetypeENST_13FieldFileTypeES3Y_S2S_NS3_6outvarES1L_INSD_6OutVarESaIS75_EENS3_9elemaliasES1L_ISA_SaISA_EENS3_7elemvarES7A_NS3_9nodealiasES7A_NS3_7nodevarES7A_EEEEENS3_11diagnosticsENS0_INS2_IJS6Y_jS6Q_NST_9ErrorTypeENS3_6formatENST_18TxtFloatFormatTypeENS3_9precisionElEEEEENS3_14history_outputENS0_INS2_IJS6Y_jS6Z_dS70_S1N_S7I_S7J_S7K_lS4P_S1L_INS0_INS2_IJS2Q_SA_NS3_5coordES1N_EEEEESaIS7Q_EEEEEEEEEEE3getIS3E_JS3H_EEERDav113835329115378829
_ZN2tk11TaggedTupleIN7brigand4listIJN3tag5titleENSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEENS3_3cmdEN7inciter3ctr7CmdLineENS3_5nstepEmNS3_4termEdNS3_2t0EdNS3_2dtEdNS3_3cflEdNS3_4ttyiEjNS3_16imex_runge_kuttaEjNS3_12imex_maxiterEjNS3_11imex_reltolEdNS3_11imex_abstolEdNS3_12steady_stateEbNS3_8residualEdNS3_7rescompEjNS3_12partitioningENS_3ctr25PartitioningAlgorithmTypeENS3_15pelocal_reorderEbNS3_16operator_reorderEbNS3_6schemeENSD_10SchemeTypeENS3_4ndofEmNS3_4rdofEmNS3_4fluxENSD_8FluxTypeENS3_11lowspeed_kpEdNS3_7limiterENSD_11LimiterTypeENS3_7cweightEdNS3_20shock_detector_coeffEdNS3_13accuracy_testEbNS3_17limsol_projectionEbNS3_5ncompEmNS3_3pdeENSD_7PDETypeENS3_9transportENS0_INS2_IJNS3_7physicsENSD_11PhysicsTypeES1A_mNS3_8intsharpEiNS3_14intsharp_paramEdNS3_7problemENSD_11ProblemTypeENS3_11diffusivityESt6vectorIdSaIdEENS3_6lambdaES1N_NS3_2u0ES1N_EEEEENS3_8compflowENS0_INS2_IJS1E_S1F_S1I_S1J_NS3_5alphaEdNS3_4betaEdNS3_5betaxEdNS3_5betayEdNS3_5betazEdNS3_2r0EdNS3_2p0EdNS3_2ceEdNS3_5kappaEdEEEEENS3_8multimatENS0_INS2_IJS1E_S1F_NS3_4nmatEmNS3_6prelaxEmNS3_16prelax_timescaleEdS1G_iS1H_dNS3_14rho0constraintEmNS3_14dt_sos_massavgEiS1I_S1J_EEEEENS3_6depvarES1L_IcS9_ENS3_3sysESt3mapImmSt4lessImESaISt4pairIKmmEEENS3_8materialES1L_INS0_INS2_IJNS3_3eosENSD_12MaterialTypeENS3_2idES1L_ImSaImEENS3_5gammaES1N_NS3_6pstiffES1N_NS3_5w_gruES1N_NS3_5A_jwlES1N_NS3_5B_jwlES1N_NS3_5C_jwlES1N_NS3_6R1_jwlES1N_NS3_6R2_jwlES1N_NS3_8rho0_jwlES1N_NS3_6de_jwlES1N_NS3_8rhor_jwlES1N_NS3_6Tr_jwlES1N_NS3_6Pr_jwlES1N_NS3_2muES1N_NS3_12yield_stressES1N_NS3_2cvES1N_NS3_1kES1N_EEEEESaIS3B_EENS3_9matidxmapENS0_INS2_IJNS3_6eosidxES2S_NS3_6matidxES2S_NS3_6solidxES2S_EEEEENS3_2bcES1L_INS0_INS2_IJNS3_4meshES2S_NS3_9dirichletES2S_NS3_8symmetryES2S_NS3_5inletES2S_NS3_6outletES2S_NS3_8farfieldES2S_NS3_11extrapolateES2S_NS3_10stag_pointES1N_NS3_6radiusEdNS3_8velocityES1N_NS3_8pressureEdNS3_7densityEdNS3_7timedepES1L_INS0_INS2_IJNS3_7sidesetES2S_NS3_2fnES1N_EEEEESaIS41_EEEEEEESaIS45_EENS3_2icENS0_INS2_IJNS3_10materialidEmS3V_dNS3_11temperatureEdS3W_dNS3_6energyEdS3U_S1N_NS3_3boxES1L_INS0_INS2_IJS49_mNS3_6volumeEdNS3_4massEdS3W_dS3U_S1N_S3V_dS4B_dNS3_14energy_contentEdS4A_dNS3_4xminEdNS3_4xmaxEdNS3_4yminEdNS3_4ymaxEdNS3_4zminEdNS3_4zmaxEdNS3_11orientationES1N_NS3_8initiateENSD_12InitiateTypeENS3_5pointES1N_NS3_9init_timeEdNS3_11front_widthEdNS3_11front_speedEdEEEEESaIS4U_EENS3_9meshblockES1L_INS0_INS2_IJNS3_7blockidEmS49_mS4D_dS4E_dS3W_dS3U_S1N_S3V_dS4B_dS4F_dS4A_dS4N_S4O_S4P_S1N_S4Q_dS4R_dS4S_dEEEEESaIS50_EEEEEEES3L_S1L_INS0_INS2_IJNS3_8filenameESA_NS3_8locationES1N_S4M_S1N_S3U_S1N_EEEEESaIS58_EENS3_8transferES1L_INSC_8TransferESaIS5C_EENS3_3aleENS0_INS2_IJS5F_bNS3_8smootherENSD_24MeshVelocitySmootherTypeENS3_13mesh_velocityENSD_16MeshVelocityTypeENS3_11mesh_motionES2S_NS3_9meshforceES1N_NS3_5dvcflEdNS3_8vortmultEdNS3_5maxitEmNS3_9toleranceEdS3M_S2S_S3N_S2S_NS3_4moveES1L_INS0_INS2_IJS3Y_S2S_NS3_6fntypeENST_13UserTableTypeES3Z_S1N_EEEEESaIS5U_EEEEEEENS3_4prefENS0_INS2_IJS5Z_bNS3_9indicatorENSD_17PrefIndicatorTypeENS3_7ndofmaxEmNS3_6tolrefEdEEEEENS3_3amrENS0_INS2_IJS66_bNS3_5t0refEbNS3_5dtrefEbNS3_13dtref_uniformEbNS3_6dtfreqEmNS3_9maxlevelsEmNS3_7initialES1L_INSD_14AMRInitialTypeESaIS6D_EENS3_8edgelistES2S_NS3_6coordsENS0_INS2_IJNS3_6xminusEdNS3_5xplusEdNS3_6yminusEdNS3_5yplusEdNS3_6zminusEdNS3_5zplusEdEEEEENS3_5errorENSD_12AMRErrorTypeENS3_6refvarES2D_NS3_10tol_refineEdNS3_12tol_derefineEdEEEEENS3_12field_outputENS0_INS2_IJNS3_8intervalEjNS3_13time_intervalEdNS3_10time_rangeES1N_NS3_7refinedEbNS3_8filetypeENST_13FieldFileTypeES3Y_S2S_NS3_6outvarES1L_INSD_6OutVarESaIS75_EENS3_9elemaliasES1L_ISA_SaISA_EENS3_7elemvarES7A_NS3_9nodealiasES7A_NS3_7nodevarES7A_EEEEENS3_11diagnosticsENS0_INS2_IJS6Y_jS6Q_NST_9ErrorTypeENS3_6formatENST_18TxtFloatFormatTypeENS3_9precisionElEEEEENS3_14history_outputENS0_INS2_IJS6Y_jS6Z_dS70_S1N_S7I_S7J_S7K_lS4P_S1L_INS0_INS2_IJS2Q_SA_NS3_5coordES1N_EEEEESaIS7Q_EEEEEEEEEEE3getIS3K_JEEERDav
auto& tk::TaggedTuple<brigand::list<tag::eosidx, std::vector<unsigned long, std::allocator<unsigned long> >, tag::matidx, std::vector<unsigned long, std::allocator<unsigned long> >, tag::solidx, std::vector<unsigned long, std::allocator<unsigned long> > > >::get<tag::solidx>()113835329115378829
tk::TaggedTuple<brigand::list<tag::eosidx, std::vector<unsigned long, std::allocator<unsigned long> >, tag::matidx, std::vector<unsigned long, std::allocator<unsigned long> >, tag::solidx, std::vector<unsigned long, std::allocator<unsigned long> > > >::pup(PUP::er&)
tk::TaggedTuple<brigand::list<tag::queried, CkCallback, tag::responded, CkCallback, tag::discinserted, CkCallback, tag::workinserted, CkCallback> >::pup(PUP::er&)6200861486
tk::TaggedTuple<brigand::list<tag::queried, CkCallback, tag::responded, CkCallback, tag::discinserted, CkCallback, tag::workinserted, CkCallback> >::TaggedTuple(std::tuple<CkCallback, CkCallback, CkCallback, CkCallback>&&)
tk::TaggedTuple<brigand::list<tag::queried, CkCallback, tag::responded, CkCallback, tag::discinserted, CkCallback, tag::workinserted, CkCallback> >::TaggedTuple()2028920115
auto& tk::TaggedTuple<brigand::list<tag::queried, CkCallback, tag::responded, CkCallback, tag::compatibility, CkCallback, tag::bndint, CkCallback, tag::matched, CkCallback, tag::refined, CkCallback> >::get<tag::queried>()
tk::TaggedTuple<brigand::list<tag::queried, CkCallback, tag::responded, CkCallback, tag::compatibility, CkCallback, tag::bndint, CkCallback, tag::matched, CkCallback, tag::refined, CkCallback> >::pup(PUP::er&)3164231381
tk::TaggedTuple<brigand::list<tag::queried, CkCallback, tag::responded, CkCallback, tag::compatibility, CkCallback, tag::bndint, CkCallback, tag::matched, CkCallback, tag::refined, CkCallback> >::TaggedTuple(std::tuple<CkCallback, CkCallback, CkCallback, CkCallback, CkCallback, CkCallback>&&)
tk::TaggedTuple<brigand::list<tag::queried, CkCallback, tag::responded, CkCallback, tag::compatibility, CkCallback, tag::bndint, CkCallback, tag::matched, CkCallback, tag::refined, CkCallback> >::TaggedTuple()1043910352
auto& tk::TaggedTuple<brigand::list<tag::sideset, std::vector<unsigned long, std::allocator<unsigned long> >, tag::fn, std::vector<double, std::allocator<double> > > >::get<tag::sideset>()
tk::operator|(PUP::er&, tk::TaggedTuple<brigand::list<tag::id, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, tag::elem, unsigned long, tag::coord, std::array<double, 3ul>, tag::fn, std::array<double, 4ul> > >&)5255
tk::operator|(PUP::er&, tk::TaggedTuple<brigand::list<tag::id, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, tag::coord, std::vector<double, std::allocator<double> > > >&)
tk::operator|(PUP::er&, tk::TaggedTuple<brigand::list<tag::queried, CkCallback, tag::responded, CkCallback, tag::discinserted, CkCallback, tag::workinserted, CkCallback> >&)6200861486
tk::operator|(PUP::er&, tk::TaggedTuple<brigand::list<tag::queried, CkCallback, tag::responded, CkCallback, tag::compatibility, CkCallback, tag::bndint, CkCallback, tag::matched, CkCallback, tag::refined, CkCallback> >&)3164231381
tk::operator|(PUP::er&, tk::TaggedTuple<brigand::list<tag::sideset, std::vector<unsigned long, std::allocator<unsigned long> >, tag::fn, std::vector<double, std::allocator<double> > > >&)
Date:2024-07-10 11:43:412024-07-11 15:06:04 Functions: 832
Date:2024-07-10 11:43:412024-07-11 15:06:04 Functions: 188
Date:2024-07-10 11:43:412024-07-11 15:06:04 Functions: 188
Date:2024-07-10 11:43:412024-07-11 15:06:04 Functions: 188
Date:2024-07-10 11:43:412024-07-11 15:06:04 Functions: 95
Date:2024-07-10 11:43:412024-07-11 15:06:04 Functions: 95
Date:2024-07-10 11:43:412024-07-11 15:06:04 Functions: 95
Date:2024-07-10 11:43:412024-07-11 15:06:04 Functions: 6
Date:2024-07-10 11:43:412024-07-11 15:06:04 Functions: 6
Date:2024-07-10 11:43:412024-07-11 15:06:04 Functions: 6
Date:2024-07-10 11:43:412024-07-11 15:06:04 Functions: 3
Date:2024-07-10 11:43:412024-07-11 15:06:04 Functions: 3
Date:2024-07-10 11:43:412024-07-11 15:06:04 Functions: 3
Date:2024-07-10 11:43:412024-07-11 15:06:04 Functions: 7
tk::Timer::Timer()1095910872
tk::Timer::dsec() const
tk::Timer::pup(PUP::er&)2502624765
tk::operator|(PUP::er&, tk::Timer&)2502624765

diff --git a/Debug/test_coverage/Base/Timer.hpp.func.html b/Debug/test_coverage/Base/Timer.hpp.func.html index 69cadeb5dfbf..78dbd37b50c6 100644 --- a/Debug/test_coverage/Base/Timer.hpp.func.html +++ b/Debug/test_coverage/Base/Timer.hpp.func.html @@ -33,7 +33,7 @@
Date:2024-07-10 11:43:412024-07-11 15:06:04 Functions: 7
tk::Timer::pup(PUP::er&)2502624765
tk::Timer::zero()
tk::Timer::Timer()1095910872
tk::operator|(PUP::er&, tk::Timer&)2502624765
tk::Timer::dsec() const
Date:2024-07-10 11:43:412024-07-11 15:06:04 Functions: 7
Date:2024-07-10 11:43:412024-07-11 15:06:04 Functions: 15
Date:2024-07-10 11:43:412024-07-11 15:06:04 Functions: 15
Date:2024-07-10 11:43:412024-07-11 15:06:04 Functions: 15-128-NOTFOUND Lines:156162 20177.6 %80.6 %
Date:2024-07-10 11:43:412024-07-11 15:06:04 Functions:2021 2483.3 %87.5 %
Legend: Branches:2125 10021.0 %25.0 %
@@ -83,10 +83,6 @@
tk::getRightCauchyGreen(std::array<std::array<double, 3ul>, 3ul> const&) 0
tk::matvec(std::array<std::array<double, 3ul>, 3ul> const&, std::array<double, 3ul> const&)0
tk::unit(std::array<double, 3ul>&) 2tk::rotateZ(std::array<double, 3ul> const&, double) 153116
tk::matvec(std::array<std::array<double, 3ul>, 3ul> const&, std::array<double, 3ul> const&)686000
tk::rotateTensor(std::array<std::array<double, 3ul>, 3ul> const&, std::array<double, 3ul> const&)8638751549875
tk::inverseJacobian(std::array<double, 3ul> const&, std::array<double, 3ul> const&, std::array<double, 3ul> const&, std::array<double, 3ul> const&)-128-NOTFOUND Lines:156162 20177.6 %80.6 %
Date:2024-07-10 11:43:412024-07-11 15:06:04 Functions:2021 2483.3 %87.5 %
Legend: Branches:2125 10021.0 %25.0 %
@@ -81,7 +81,7 @@
tk::rotateTensor(std::array<std::array<double, 3ul>, 3ul> const&, std::array<double, 3ul> const&)8638751549875
tk::reflectTensor(std::array<std::array<double, 3ul>, 3ul> const&, std::array<std::array<double, 3ul>, 3ul> const&)
tk::matvec(std::array<std::array<double, 3ul>, 3ul> const&, std::array<double, 3ul> const&)0686000
tk::triple(std::array<double, 3ul> const&, std::array<double, 3ul> const&, std::array<double, 3ul> const&)-128-NOTFOUND Lines:156162 20177.6 %80.6 %
Date:2024-07-10 11:43:412024-07-11 15:06:04 Functions:2021 2483.3 %87.5 %
Legend: Branches:2125 10021.0 %25.0 %
@@ -213,17 +213,17 @@ 139 : : //! \param[in] v vector 140 : : //! \return Dot-product 141 : : inline std::array< real, 3 > - 142 : 0 : matvec( + 142 : 686000 : matvec( 143 : : const std::array< std::array< real, 3 >, 3 >& m, 144 : : const std::array< real, 3 >& v ) 145 : : { - 146 : 0 : std::array< real, 3 > mv{0, 0, 0}; - 147 [ - - ]: 0 : for (std::size_t i=0; i<3; ++i) { - 148 [ - - ]: 0 : for (std::size_t j=0; j<3; ++j) - 149 : 0 : mv[i] += m[i][j]*v[j]; + 146 : 686000 : std::array< real, 3 > mv{0, 0, 0}; + 147 [ + + ]: 2744000 : for (std::size_t i=0; i<3; ++i) { + 148 [ + + ]: 8232000 : for (std::size_t j=0; j<3; ++j) + 149 : 6174000 : mv[i] += m[i][j]*v[j]; 150 : : } 151 : : - 152 : 0 : return mv; + 152 : 686000 : return mv; 153 : : } 154 : : 155 : : //! Compute length of a vector @@ -627,67 +627,67 @@ 548 : : //! \param[in] r Coordinates of the first basis vector r = (rx,ry,rz). 549 : : //! \return rotated tensor 550 : : inline std::array< std::array< tk::real, 3 >, 3 > - 551 : 863875 : rotateTensor(const std::array< std::array< tk::real, 3 >, 3 >& mat, + 551 : 1549875 : rotateTensor(const std::array< std::array< tk::real, 3 >, 3 >& mat, 552 : : const std::array< tk::real, 3 >& r ) 553 : : { 554 : : // define rotation matrix - 555 : 863875 : tk::real eps = 1.0e-04; + 555 : 1549875 : tk::real eps = 1.0e-04; 556 : : double rotMat[9]; - 557 : 863875 : tk::real rx = r[0]; - 558 : 863875 : tk::real ry = r[1]; - 559 : 863875 : tk::real rz = r[2]; - 560 [ + + ][ + + ]: 863875 : if (std::abs(rx) > eps || std::abs(ry) > eps) - [ + + ] + 557 : 1549875 : tk::real rx = r[0]; + 558 : 1549875 : tk::real ry = r[1]; + 559 : 1549875 : tk::real rz = r[2]; + 560 [ + + ][ + + ]: 1549875 : if (std::abs(rx) > eps || std::abs(ry) > eps) + [ + + ] 561 : : { - 562 : 791332 : tk::real rxryNorm = std::sqrt(rx*rx+ry*ry); - 563 : 791332 : rotMat[0] = rx; - 564 : 791332 : rotMat[1] = ry; - 565 : 791332 : rotMat[2] = rz; - 566 : 791332 : rotMat[3] = ry/rxryNorm; - 567 : 791332 : rotMat[4] = -rx/rxryNorm; - 568 : 791332 : rotMat[5] = 0.0; - 569 : 791332 : rotMat[6] = rx*rz/rxryNorm; - 570 : 791332 : rotMat[7] = ry*rz/rxryNorm; - 571 : 791332 : rotMat[8] = -rxryNorm; + 562 : 1373932 : tk::real rxryNorm = std::sqrt(rx*rx+ry*ry); + 563 : 1373932 : rotMat[0] = rx; + 564 : 1373932 : rotMat[1] = ry; + 565 : 1373932 : rotMat[2] = rz; + 566 : 1373932 : rotMat[3] = ry/rxryNorm; + 567 : 1373932 : rotMat[4] = -rx/rxryNorm; + 568 : 1373932 : rotMat[5] = 0.0; + 569 : 1373932 : rotMat[6] = rx*rz/rxryNorm; + 570 : 1373932 : rotMat[7] = ry*rz/rxryNorm; + 571 : 1373932 : rotMat[8] = -rxryNorm; 572 : : } 573 : : else 574 : : { - 575 : 72543 : rotMat[0] = rx; - 576 : 72543 : rotMat[1] = ry; - 577 : 72543 : rotMat[2] = rz; - 578 : 72543 : rotMat[3] = 1.0; - 579 : 72543 : rotMat[4] = 0.0; - 580 : 72543 : rotMat[5] = 0.0; - 581 : 72543 : rotMat[6] = 0.0; - 582 : 72543 : rotMat[7] = 1.0; - 583 : 72543 : rotMat[8] = 0.0; + 575 : 175943 : rotMat[0] = rx; + 576 : 175943 : rotMat[1] = ry; + 577 : 175943 : rotMat[2] = rz; + 578 : 175943 : rotMat[3] = 1.0; + 579 : 175943 : rotMat[4] = 0.0; + 580 : 175943 : rotMat[5] = 0.0; + 581 : 175943 : rotMat[6] = 0.0; + 582 : 175943 : rotMat[7] = 1.0; + 583 : 175943 : rotMat[8] = 0.0; 584 : : } 585 : : 586 : : // define matrices 587 : : double matAuxIn[9], matAuxOut[9]; - 588 [ + + ]: 3455500 : for (std::size_t i=0; i<3; ++i) - 589 [ + + ]: 10366500 : for (std::size_t j=0; j<3; ++j) - 590 : 7774875 : matAuxIn[i*3+j] = mat[i][j]; + 588 [ + + ]: 6199500 : for (std::size_t i=0; i<3; ++i) + 589 [ + + ]: 18598500 : for (std::size_t j=0; j<3; ++j) + 590 : 13948875 : matAuxIn[i*3+j] = mat[i][j]; 591 : : 592 : : // compute matAuxIn*rotMat and store it into matAuxOut - 593 [ + - ]: 863875 : cblas_dgemm(CblasRowMajor, CblasNoTrans, CblasNoTrans, + 593 [ + - ]: 1549875 : cblas_dgemm(CblasRowMajor, CblasNoTrans, CblasNoTrans, 594 : : 3, 3, 3, 1.0, matAuxIn, 3, rotMat, 3, 0.0, matAuxOut, 3); 595 : : 596 : : // matAuxOut -> matAuxIn - 597 [ + + ]: 8638750 : for (std::size_t i=0; i<9; i++) + 597 [ + + ]: 15498750 : for (std::size_t i=0; i<9; i++) 598 : : { - 599 : 7774875 : matAuxIn[i] = matAuxOut[i]; - 600 : 7774875 : matAuxOut[i] = 0.0; + 599 : 13948875 : matAuxIn[i] = matAuxOut[i]; + 600 : 13948875 : matAuxOut[i] = 0.0; 601 : : } 602 : : 603 : : // compute rotMat^T*matAuxIn and store it into matAuxOut - 604 [ + - ]: 863875 : cblas_dgemm(CblasRowMajor, CblasTrans, CblasNoTrans, + 604 [ + - ]: 1549875 : cblas_dgemm(CblasRowMajor, CblasTrans, CblasNoTrans, 605 : : 3, 3, 3, 1.0, rotMat, 3, matAuxIn, 3, 0.0, matAuxOut, 3); 606 : : 607 : : // return matAuxOut as a 2D array - 608 : 863875 : return {{ {matAuxOut[0], matAuxOut[1], matAuxOut[2]}, - 609 : 863875 : {matAuxOut[3], matAuxOut[4], matAuxOut[5]}, - 610 : 863875 : {matAuxOut[6], matAuxOut[7], matAuxOut[8]} }}; + 608 : 1549875 : return {{ {matAuxOut[0], matAuxOut[1], matAuxOut[2]}, + 609 : 1549875 : {matAuxOut[3], matAuxOut[4], matAuxOut[5]}, + 610 : 1549875 : {matAuxOut[6], matAuxOut[7], matAuxOut[8]} }}; 611 : : } 612 : : 613 : : //! \brief Reflect a second order tensor (e.g. a Strain/Stress matrix) diff --git a/Debug/test_coverage/Base/Writer.cpp.func-sort-c.html b/Debug/test_coverage/Base/Writer.cpp.func-sort-c.html index d4b47d0ab613..b56da7a4aa11 100644 --- a/Debug/test_coverage/Base/Writer.cpp.func-sort-c.html +++ b/Debug/test_coverage/Base/Writer.cpp.func-sort-c.html @@ -33,7 +33,7 @@
Date:2024-07-10 11:43:412024-07-11 15:06:04 Functions: 2
Date:2024-07-10 11:43:412024-07-11 15:06:04 Functions: 2
Date:2024-07-10 11:43:412024-07-11 15:06:04 Functions: 2
Date:2024-07-10 11:43:412024-07-11 15:06:04 Functions: 1
Date:2024-07-10 11:43:412024-07-11 15:06:04 Functions: 1
Date:2024-07-10 11:43:412024-07-11 15:06:04 Functions: 1-128-NOTFOUND Lines:10781084 129983.0 %83.4 %
Date:2024-07-10 11:43:412024-07-11 15:06:04 Functions:18411842 1955 94.2 %
Branches:714718 174141.0 %41.2 %
@@ -93,18 +93,6 @@
0.0 % 0 / 39
Vector.hpp -
77.6%77.6%
-
77.6 %156 / 20183.3 %20 / 2421.0 %21 / 100
Escaper.hpp @@ -129,6 +117,18 @@ 25.0 % 5 / 20
Vector.hpp +
80.6%80.6%
+
80.6 %162 / 20187.5 %21 / 2425.0 %25 / 100
Exception.cpp @@ -346,26 +346,26 @@ 17 / 30
Types.hppTable.hpp
100.0%
100.0 %27 / 2718 / 18 100.0 %15 / 156 / 6 60.0 % 12 / 20
Table.hppTypes.hpp
100.0%
100.0 %18 / 1827 / 27 100.0 %6 / 615 / 15 60.0 % 12 / 20
39 / 58
ChareStateCollector.hppWriter.hpp
100.0%
100.0 %7 / 71 / 1 100.0 %3 / 31 / 1 - 0 / 0
Writer.hppException.hpp
100.0%
100.0 %1 / 12 / 2 100.0 % 1 / 1 - 0 / 0
Exception.hppChareStateCollector.hpp
100.0%
100.0 %2 / 27 / 7 100.0 %1 / 13 / 3 - 0 / 0
-128-NOTFOUND Lines:10781084 129983.0 %83.4 %
Date:2024-07-10 11:43:412024-07-11 15:06:04 Functions:18411842 1955 94.2 %
Branches:714718 174141.0 %41.2 %
@@ -165,18 +165,6 @@
41.4 % 187 / 452
Vector.hpp -
77.6%77.6%
-
77.6 %156 / 20183.3 %20 / 2421.0 %21 / 100
TeeBuf.hpp @@ -189,6 +177,18 @@ 53.8 % 14 / 26
Vector.hpp +
80.6%80.6%
+
80.6 %162 / 20187.5 %21 / 2425.0 %25 / 100
PUPUtil.hpp @@ -226,40 +226,40 @@ 66 / 122
LoadDistributor.cppWriter.hpp
100.0%
100.0 %11 / 111 / 1 100.0 % 1 / 150.0 %13 / 26-0 / 0
Writer.hppException.hpp
100.0%
100.0 %1 / 12 / 2 100.0 % 1 / 1 - 0 / 0
Exception.hppLoadDistributor.cpp
100.0%
100.0 %2 / 211 / 11 100.0 % 1 / 1-0 / 050.0 %13 / 26
HashMapReducer.hpp17 / 30
ChareStateCollector.cppTimer.cpp -
100.0%
+
96.6%96.6%
100.0 %13 / 1396.6 %28 / 29 100.0 % 3 / 343.8 %7 / 1650.0 %32 / 64
Flip_map.hppChareStateCollector.cpp
100.0%
100.0 %6 / 613 / 13 100.0 % 3 / 350.0 %2 / 443.8 %7 / 16
Timer.cppChareStateCollector.hpp -
96.6%96.6%
+
100.0%
96.6 %28 / 29100.0 %7 / 7 100.0 % 3 / 350.0 %32 / 64-0 / 0
ChareStateCollector.hppFlip_map.hpp
100.0%
100.0 %7 / 76 / 6 100.0 % 3 / 3-0 / 050.0 %2 / 4
PrintUtil.cpp-128-NOTFOUND Lines:10781084 129983.0 %83.4 %
Date:2024-07-10 11:43:412024-07-11 15:06:04 Functions:18411842 1955 94.2 %
Branches:714718 174141.0 %41.2 %
@@ -141,18 +141,6 @@
38.3 % 36 / 94
Vector.hpp -
77.6%77.6%
-
77.6 %156 / 20183.3 %20 / 2421.0 %21 / 100
Print.hpp @@ -165,6 +153,18 @@ 41.4 % 187 / 452
Vector.hpp +
80.6%80.6%
+
80.6 %162 / 20187.5 %21 / 2425.0 %25 / 100
Progress.hpp @@ -274,28 +274,28 @@ 0 / 0
TaggedTuplePrint.hppLoadDistributor.cpp
100.0%
100.0 % 11 / 11 100.0 %95 / 951 / 1 50.0 %1 / 213 / 26
LoadDistributor.cppTaggedTuplePrint.hpp
100.0%
100.0 % 11 / 11 100.0 %1 / 195 / 95 50.0 %13 / 261 / 2
ChareStateCollector.cpp50.0 % 5 / 10
Factory.hpp -
100.0%
-
100.0 %18 / 18100.0 %95 / 9552.8 %19 / 36
Table.hpp @@ -357,6 +345,18 @@ 56.7 % 17 / 30
Factory.hpp +
100.0%
+
100.0 %18 / 18100.0 %95 / 9552.8 %19 / 36
PrintUtil.hpp diff --git a/Debug/test_coverage/Base/index.html b/Debug/test_coverage/Base/index.html index f71a887b2cd3..011376eeb0af 100644 --- a/Debug/test_coverage/Base/index.html +++ b/Debug/test_coverage/Base/index.html @@ -27,16 +27,16 @@ -128-NOTFOUND Lines:10781084 129983.0 %83.4 %
Date:2024-07-10 11:43:412024-07-11 15:06:04 Functions:18411842 1955 94.2 %
Branches:714718 174141.0 %41.2 %
@@ -396,14 +396,14 @@
Vector.hpp -
77.6%77.6%
+
80.6%80.6%
77.6 %156 / 20183.3 %20 / 2421.0 %21 / 10080.6 %162 / 20187.5 %21 / 2425.0 %25 / 100
Writer.cpp
Date:2024-07-10 11:43:412024-07-11 15:06:04 Functions: 24
Date:2024-07-10 11:43:412024-07-11 15:06:04 Functions: 24
Date:2024-07-10 11:43:412024-07-11 15:06:04 Functions: 24
Date:2024-07-10 11:43:412024-07-11 15:06:04 Functions: 29
Date:2024-07-10 11:43:412024-07-11 15:06:04 Functions: 29
Date:2024-07-10 11:43:412024-07-11 15:06:04 Functions: 29
Date:2024-07-10 11:43:412024-07-11 15:06:04 Functions: 4
Date:2024-07-10 11:43:412024-07-11 15:06:04 Functions: 4
Date:2024-07-10 11:43:412024-07-11 15:06:04 Functions: 4
Date:2024-07-10 11:43:412024-07-11 15:06:04 Functions: 1
Date:2024-07-10 11:43:412024-07-11 15:06:04 Functions: 1
Date:2024-07-10 11:43:412024-07-11 15:06:04 Functions: 1
Date:2024-07-10 11:43:412024-07-11 15:06:04 Functions: 5
Date:2024-07-10 11:43:412024-07-11 15:06:04 Functions: 5
Date:2024-07-10 11:43:412024-07-11 15:06:04 Functions: 5
Date:2024-07-10 11:43:412024-07-11 15:06:04 Functions: 5
Date:2024-07-10 11:43:412024-07-11 15:06:04 Functions: 4
Date:2024-07-10 11:43:412024-07-11 15:06:04 Functions: 4
Date:2024-07-10 11:43:412024-07-11 15:06:04 Functions: 4
Date:2024-07-10 11:43:412024-07-11 15:06:04 Functions: 5
Date:2024-07-10 11:43:412024-07-11 15:06:04 Functions: 5
Date:2024-07-10 11:43:412024-07-11 15:06:04 Functions: 5
Date:2024-07-10 11:43:412024-07-11 15:06:04 Functions: 131
Date:2024-07-10 11:43:412024-07-11 15:06:04 Functions: 131
Date:2024-07-10 11:43:412024-07-11 15:06:04 Functions: 131
Date:2024-07-10 11:43:412024-07-11 15:06:04 Functions: 140
Date:2024-07-10 11:43:412024-07-11 15:06:04 Functions: 140
Date:2024-07-10 11:43:412024-07-11 15:06:04 Functions: 140
Date:2024-07-10 11:43:412024-07-11 15:06:04 Functions: 140
Date:2024-07-10 11:43:412024-07-11 15:06:04 Functions: 2
Date:2024-07-10 11:43:412024-07-11 15:06:04 Functions: 2
Date:2024-07-10 11:43:412024-07-11 15:06:04 Functions: 2
Date:2024-07-10 11:43:412024-07-11 15:06:04 Functions: 2
Date:2024-07-10 11:43:412024-07-11 15:06:04 Functions: 2
Date:2024-07-10 11:43:412024-07-11 15:06:04 Functions: 2
Date:2024-07-10 11:43:412024-07-11 15:06:04 Functions: 2
Date:2024-07-10 11:43:412024-07-11 15:06:04 Functions: 2
Date:2024-07-10 11:43:412024-07-11 15:06:04 Functions: 2
Date:2024-07-10 11:43:412024-07-11 15:06:04 Functions: 2
Date:2024-07-10 11:43:412024-07-11 15:06:04 Functions: 2
Date:2024-07-10 11:43:412024-07-11 15:06:04 Functions: 2
Date:2024-07-10 11:43:412024-07-11 15:06:04 Functions: 2
Date:2024-07-10 11:43:412024-07-11 15:06:04 Functions: 2
Date:2024-07-10 11:43:412024-07-11 15:06:04 Functions: 2
Date:2024-07-10 11:43:412024-07-11 15:06:04 Functions: 2
Date:2024-07-10 11:43:412024-07-11 15:06:04 Functions: 2
Date:2024-07-10 11:43:412024-07-11 15:06:04 Functions: 2
Date:2024-07-10 11:43:412024-07-11 15:06:04 Functions: 2
Date:2024-07-10 11:43:412024-07-11 15:06:04 Functions: 2
Date:2024-07-10 11:43:412024-07-11 15:06:04 Functions: 2
Date:2024-07-10 11:43:412024-07-11 15:06:04 Functions: 2
Date:2024-07-10 11:43:412024-07-11 15:06:04 Functions: 2
Date:2024-07-10 11:43:412024-07-11 15:06:04 Functions: 2
Date:2024-07-10 11:43:412024-07-11 15:06:04 Functions: 2
Date:2024-07-10 11:43:412024-07-11 15:06:04 Functions: 2
Date:2024-07-10 11:43:412024-07-11 15:06:04 Functions: 2
Date:2024-07-10 11:43:412024-07-11 15:06:04 Functions: 2
Date:2024-07-10 11:43:412024-07-11 15:06:04 Functions: 2
Date:2024-07-10 11:43:412024-07-11 15:06:04 Functions: 2
Date:2024-07-10 11:43:412024-07-11 15:06:04 Functions: 2
Date:2024-07-10 11:43:412024-07-11 15:06:04 Functions: 2
Date:2024-07-10 11:43:412024-07-11 15:06:04 Functions: 2
Date:2024-07-10 11:43:412024-07-11 15:06:04 Functions: 2
Date:2024-07-10 11:43:412024-07-11 15:06:04 Functions: 2
Date:2024-07-10 11:43:412024-07-11 15:06:04 Functions: 2
Date:2024-07-10 11:43:412024-07-11 15:06:04 Functions: 3
Date:2024-07-10 11:43:412024-07-11 15:06:04 Functions: 3
Date:2024-07-10 11:43:412024-07-11 15:06:04 Functions: 3
Date:2024-07-10 11:43:412024-07-11 15:06:04 Functions: 27Branches Sort by branch coverage
Initiate.hppPrefIndicator.hpp -
71.4%71.4%
+
66.7%66.7%
71.4 %5 / 766.7 %4 / 6 100.0 % 2 / 2 50.0 % 12 / 24
PrefIndicator.hppInitiate.hpp -
66.7%66.7%
+
71.4%71.4%
66.7 %4 / 671.4 %5 / 7 100.0 % 2 / 2 50.0 %12 / 24
PDE.hppMeshVelocity.hpp
50.0%50.0%
50.0 %4 / 85 / 10 100.0 % 2 / 2 50.0 % 14 / 28
Material.hppPDE.hpp
50.0%50.0%
50.0 %5 / 104 / 8 100.0 % 2 / 2 50.0 % 14 / 28
MeshVelocity.hppMeshVelocitySmoother.hpp -
50.0%50.0%
+
54.5%54.5%
50.0 %5 / 1054.5 %6 / 11 100.0 % 2 / 2 50.0 % 14 / 28
MeshVelocitySmoother.hppMaterial.hpp -
54.5%54.5%
+
50.0%50.0%
54.5 %6 / 1150.0 %5 / 10 100.0 % 2 / 2 50.0 %
Date:2024-07-10 11:43:412024-07-11 15:06:04 Functions: 27Branches Sort by branch coverage
PDE.hppMeshVelocity.hpp
50.0%50.0%
50.0 %4 / 85 / 10 100.0 % 2 / 2 50.0 % 14 / 28
Initiate.hppPrefIndicator.hpp -
71.4%71.4%
+
66.7%66.7%
71.4 %5 / 766.7 %4 / 6 100.0 % 2 / 2 50.0 % 12 / 24
PrefIndicator.hppLimiter.hpp -
66.7%66.7%
+
45.5%45.5%
66.7 %4 / 645.5 %5 / 11 100.0 % 2 / 2 50.0 %12 / 2416 / 32
Material.hppInitiate.hpp -
50.0%50.0%
+
71.4%71.4%
50.0 %5 / 1071.4 %5 / 7 100.0 % 2 / 2 50.0 %14 / 2812 / 24
AMRError.hppFlux.hpp -
66.7%66.7%
+
35.7%35.7%
66.7 %4 / 635.7 %5 / 14 100.0 % 2 / 2 50.0 %12 / 2418 / 36
Problem.hpp55 / 110
MeshVelocity.hppPhysics.hpp -
50.0%50.0%
+
35.7%35.7%
50.0 %5 / 1035.7 %5 / 14 100.0 % 2 / 2 50.0 %14 / 2818 / 36
Limiter.hppPDE.hpp -
45.5%45.5%
+
50.0%50.0%
45.5 %5 / 11100.0 %2 / 2 50.0 %16 / 32
Flux.hpp -
35.7%35.7%
-
35.7 %5 / 144 / 8 100.0 % 2 / 2 50.0 %18 / 3614 / 28
Physics.hppAMRError.hpp -
35.7%35.7%
+
66.7%66.7%
35.7 %5 / 1466.7 %4 / 6 100.0 % 2 / 2 50.0 %18 / 3612 / 24
AMRInitial.hpp50.0 % 14 / 28
Material.hpp +
50.0%50.0%
+
50.0 %5 / 10100.0 %2 / 250.0 %14 / 28
Scheme.hpp diff --git a/Debug/test_coverage/Control/Inciter/Options/index-sort-l.html b/Debug/test_coverage/Control/Inciter/Options/index-sort-l.html index f1b89e43d065..0362e0dbecd1 100644 --- a/Debug/test_coverage/Control/Inciter/Options/index-sort-l.html +++ b/Debug/test_coverage/Control/Inciter/Options/index-sort-l.html @@ -33,7 +33,7 @@
Date:2024-07-10 11:43:412024-07-11 15:06:04 Functions: 2714 / 28
Material.hppMeshVelocity.hpp
50.0%50.0%
14 / 28
MeshVelocity.hppMaterial.hpp
50.0%50.0%
Date:2024-07-10 11:43:412024-07-11 15:06:04 Functions: 27
Date:2024-07-10 11:43:412024-07-11 15:06:04 Functions: 6
Date:2024-07-10 11:43:412024-07-11 15:06:04 Functions: 6
Date:2024-07-10 11:43:412024-07-11 15:06:04 Functions: 6
Date:2024-07-10 11:43:412024-07-11 15:06:04 Functions: 6
Date:2024-07-10 11:43:412024-07-11 15:06:04 Functions: 6
Date:2024-07-10 11:43:412024-07-11 15:06:04 Functions: 6
Date:2024-07-10 11:43:412024-07-11 15:06:04 Functions: 6
Date:2024-07-10 11:43:412024-07-11 15:06:04 Functions: 184
Date:2024-07-10 11:43:412024-07-11 15:06:04 Functions: 184
Date:2024-07-10 11:43:412024-07-11 15:06:04 Functions: 184
Date:2024-07-10 11:43:412024-07-11 15:06:04 Functions: 61
Date:2024-07-10 11:43:412024-07-11 15:06:04 Functions: 61
Date:2024-07-10 11:43:412024-07-11 15:06:04 Functions: 61
Date:2024-07-10 11:43:412024-07-11 15:06:04 Functions: 2
Date:2024-07-10 11:43:412024-07-11 15:06:04 Functions: 2
Date:2024-07-10 11:43:412024-07-11 15:06:04 Functions: 2
Date:2024-07-10 11:43:412024-07-11 15:06:04 Functions: 1
Date:2024-07-10 11:43:412024-07-11 15:06:04 Functions: 1
Date:2024-07-10 11:43:412024-07-11 15:06:04 Functions: 1
Date:2024-07-10 11:43:412024-07-11 15:06:04 Functions: 3
Date:2024-07-10 11:43:412024-07-11 15:06:04 Functions: 3
Date:2024-07-10 11:43:412024-07-11 15:06:04 Functions: 3
Date:2024-07-10 11:43:412024-07-11 15:06:04 Functions: 3
Date:2024-07-10 11:43:412024-07-11 15:06:04 Functions: 2
Date:2024-07-10 11:43:412024-07-11 15:06:04 Functions: 2
Date:2024-07-10 11:43:412024-07-11 15:06:04 Functions: 2
Date:2024-07-10 11:43:412024-07-11 15:06:04 Functions: 2
Date:2024-07-10 11:43:412024-07-11 15:06:04 Functions: 2
Date:2024-07-10 11:43:412024-07-11 15:06:04 Functions: 2
Date:2024-07-10 11:43:412024-07-11 15:06:04 Functions: 3
Date:2024-07-10 11:43:412024-07-11 15:06:04 Functions: 3
Date:2024-07-10 11:43:412024-07-11 15:06:04 Functions: 3
Date:2024-07-10 11:43:412024-07-11 15:06:04 Functions: 2
Date:2024-07-10 11:43:412024-07-11 15:06:04 Functions: 2
Date:2024-07-10 11:43:412024-07-11 15:06:04 Functions: 2
Date:2024-07-10 11:43:412024-07-11 15:06:04 Functions: 2
Date:2024-07-10 11:43:412024-07-11 15:06:04 Functions: 2
Date:2024-07-10 11:43:412024-07-11 15:06:04 Functions: 2
Date:2024-07-10 11:43:412024-07-11 15:06:04 Functions: 11
Date:2024-07-10 11:43:412024-07-11 15:06:04 Functions: 11Branches Sort by branch coverage
FieldFile.hppTxtFloatFormat.hpp -
80.0%80.0%
+
44.4%44.4%
80.0 %4 / 544.4 %4 / 9 100.0 % 2 / 2 50.0 %10 / 2014 / 28
Error.hppFieldFile.hpp -
57.1%57.1%
+
80.0%80.0%
57.1 %4 / 780.0 %4 / 5 100.0 % 2 / 2 50.0 %12 / 2410 / 20
TxtFloatFormat.hppUserTable.hpp -
44.4%44.4%
+
50.0%50.0%
44.4 %4 / 950.0 %4 / 8 100.0 % 2 / 2 50.0 % 14 / 28
UserTable.hppError.hpp -
50.0%50.0%
+
57.1%57.1%
50.0 %4 / 857.1 %4 / 7 100.0 % 2 / 2 50.0 %14 / 2812 / 24
PartitioningAlgorithm.hpp
Date:2024-07-10 11:43:412024-07-11 15:06:04 Functions: 11
Date:2024-07-10 11:43:412024-07-11 15:06:04 Functions: 11
Date:2024-07-10 11:43:412024-07-11 15:06:04 Functions: 5
Date:2024-07-10 11:43:412024-07-11 15:06:04 Functions: 5
Date:2024-07-10 11:43:412024-07-11 15:06:04 Functions: 5
Date:2024-07-10 11:43:412024-07-11 15:06:04 Functions: 2
Date:2024-07-10 11:43:412024-07-11 15:06:04 Functions: 2
Date:2024-07-10 11:43:412024-07-11 15:06:04 Functions: 2
Date:2024-07-10 11:43:412024-07-11 15:06:04 Functions: 1
Date:2024-07-10 11:43:412024-07-11 15:06:04 Functions: 1
Date:2024-07-10 11:43:412024-07-11 15:06:04 Functions: 1
Date:2024-07-10 11:43:412024-07-11 15:06:04 Functions: 195
Date:2024-07-10 11:43:412024-07-11 15:06:04 Functions: 195
Date:2024-07-10 11:43:412024-07-11 15:06:04 Functions: 195
Date:2024-07-10 11:43:412024-07-11 15:06:04 Functions: 63
Date:2024-07-10 11:43:412024-07-11 15:06:04 Functions: 63
Date:2024-07-10 11:43:412024-07-11 15:06:04 Functions: 63
Date:2024-07-10 11:43:412024-07-11 15:06:04 Functions: 4
Date:2024-07-10 11:43:412024-07-11 15:06:04 Functions: 4
Date:2024-07-10 11:43:412024-07-11 15:06:04 Functions: 4
Date:2024-07-10 11:43:412024-07-11 15:06:04 Functions: 1
Date:2024-07-10 11:43:412024-07-11 15:06:04 Functions: 1
Date:2024-07-10 11:43:412024-07-11 15:06:04 Functions: 1
Date:2024-07-10 11:43:412024-07-11 15:06:04 Functions: 5
Date:2024-07-10 11:43:412024-07-11 15:06:04 Functions: 5
Date:2024-07-10 11:43:412024-07-11 15:06:04 Functions: 5
Date:2024-07-10 11:43:412024-07-11 15:06:04 Functions: 5
Date:2024-07-10 11:43:412024-07-11 15:06:04 Functions: 564
Date:2024-07-10 11:43:412024-07-11 15:06:04 Functions: 564
Date:2024-07-10 11:43:412024-07-11 15:06:04 Functions: 564
Date:2024-07-10 11:43:412024-07-11 15:06:04 Functions: 564
Date:2024-07-10 11:43:412024-07-11 15:06:04 Functions: 4
Date:2024-07-10 11:43:412024-07-11 15:06:04 Functions: 4
Date:2024-07-10 11:43:412024-07-11 15:06:04 Functions: 4
Date:2024-07-10 11:43:412024-07-11 15:06:04 Functions: 1
Date:2024-07-10 11:43:412024-07-11 15:06:04 Functions: 1
Date:2024-07-10 11:43:412024-07-11 15:06:04 Functions: 1
Date:2024-07-10 11:43:412024-07-11 15:06:04 Functions: 3
Date:2024-07-10 11:43:412024-07-11 15:06:04 Functions: 3
Date:2024-07-10 11:43:412024-07-11 15:06:04 Functions: 3
Date:2024-07-10 11:43:412024-07-11 15:06:04 Functions: 28
Date:2024-07-10 11:43:412024-07-11 15:06:04 Functions: 28
Date:2024-07-10 11:43:412024-07-11 15:06:04 Functions: 28
Date:2024-07-10 11:43:412024-07-11 15:06:04 Functions: 5
Date:2024-07-10 11:43:412024-07-11 15:06:04 Functions: 5
Date:2024-07-10 11:43:412024-07-11 15:06:04 Functions: 5
Date:2024-07-10 11:43:412024-07-11 15:06:04 Functions: 19
Date:2024-07-10 11:43:412024-07-11 15:06:04 Functions: 19
Date:2024-07-10 11:43:412024-07-11 15:06:04 Functions: 19
Date:2024-07-10 11:43:412024-07-11 15:06:04 Functions: 2
Date:2024-07-10 11:43:412024-07-11 15:06:04 Functions: 2
Date:2024-07-10 11:43:412024-07-11 15:06:04 Functions: 2
Date:2024-07-10 11:43:412024-07-11 15:06:04 Functions: 4
Date:2024-07-10 11:43:412024-07-11 15:06:04 Functions: 4
Date:2024-07-10 11:43:412024-07-11 15:06:04 Functions: 4
Date:2024-07-10 11:43:412024-07-11 15:06:04 Functions: 3
Date:2024-07-10 11:43:412024-07-11 15:06:04 Functions: 3
Date:2024-07-10 11:43:412024-07-11 15:06:04 Functions: 3
Date:2024-07-10 11:43:412024-07-11 15:06:04 Functions: 5
Date:2024-07-10 11:43:412024-07-11 15:06:04 Functions: 5
Date:2024-07-10 11:43:412024-07-11 15:06:04 Functions: 5
Date:2024-07-10 11:43:412024-07-11 15:06:04 Functions: 2
Date:2024-07-10 11:43:412024-07-11 15:06:04 Functions: 2
Date:2024-07-10 11:43:412024-07-11 15:06:04 Functions: 2
Date:2024-07-10 11:43:412024-07-11 15:06:04 Functions: 4
Date:2024-07-10 11:43:412024-07-11 15:06:04 Functions: 4
Date:2024-07-10 11:43:412024-07-11 15:06:04 Functions: 4
Date:2024-07-10 11:43:412024-07-11 15:06:04 Functions: 1
Date:2024-07-10 11:43:412024-07-11 15:06:04 Functions: 1
Date:2024-07-10 11:43:412024-07-11 15:06:04 Functions: 1
Date:2024-07-10 11:43:412024-07-11 15:06:04 Functions: 2
Date:2024-07-10 11:43:412024-07-11 15:06:04 Functions: 2
Date:2024-07-10 11:43:412024-07-11 15:06:04 Functions: 2
Date:2024-07-10 11:43:412024-07-11 15:06:04 Functions: 2
Date:2024-07-10 11:43:412024-07-11 15:06:04 Functions: 2
Date:2024-07-10 11:43:412024-07-11 15:06:04 Functions: 2
Date:2024-07-10 11:43:412024-07-11 15:06:04 Functions: 22
Date:2024-07-10 11:43:412024-07-11 15:06:04 Functions: 22
Date:2024-07-10 11:43:412024-07-11 15:06:04 Functions: 22
Date:2024-07-10 11:43:412024-07-11 15:06:04 Functions: 4
Date:2024-07-10 11:43:412024-07-11 15:06:04 Functions: 4
Date:2024-07-10 11:43:412024-07-11 15:06:04 Functions: 4
Date:2024-07-10 11:43:412024-07-11 15:06:04 Functions: 2
Date:2024-07-10 11:43:412024-07-11 15:06:04 Functions: 2
Date:2024-07-10 11:43:412024-07-11 15:06:04 Functions: 2
Date:2024-07-10 11:43:412024-07-11 15:06:04 Functions: 3
Date:2024-07-10 11:43:412024-07-11 15:06:04 Functions: 3
Date:2024-07-10 11:43:412024-07-11 15:06:04 Functions: 3
Date:2024-07-10 11:43:412024-07-11 15:06:04 Functions: 1
Date:2024-07-10 11:43:412024-07-11 15:06:04 Functions: 1
Date:2024-07-10 11:43:412024-07-11 15:06:04 Functions: 1
Date:2024-07-10 11:43:412024-07-11 15:06:04 Functions: 3
Date:2024-07-10 11:43:412024-07-11 15:06:04 Functions: 3
Date:2024-07-10 11:43:412024-07-11 15:06:04 Functions: 3
Date:2024-07-10 11:43:412024-07-11 15:06:04 Functions: 1
Date:2024-07-10 11:43:412024-07-11 15:06:04 Functions: 1
Date:2024-07-10 11:43:412024-07-11 15:06:04 Functions: 1
Date:2024-07-10 11:43:412024-07-11 15:06:04 Functions: 3
Date:2024-07-10 11:43:412024-07-11 15:06:04 Functions: 3
Date:2024-07-10 11:43:412024-07-11 15:06:04 Functions: 3
Date:2024-07-10 11:43:412024-07-11 15:06:04 Functions: 2
Date:2024-07-10 11:43:412024-07-11 15:06:04 Functions: 2
Date:2024-07-10 11:43:412024-07-11 15:06:04 Functions: 2
Date:2024-07-10 11:43:412024-07-11 15:06:04 Functions: 4
Date:2024-07-10 11:43:412024-07-11 15:06:04 Functions: 4
Date:2024-07-10 11:43:412024-07-11 15:06:04 Functions: 4
Date:2024-07-10 11:43:412024-07-11 15:06:04 Functions: 1
Date:2024-07-10 11:43:412024-07-11 15:06:04 Functions: 1
Date:2024-07-10 11:43:412024-07-11 15:06:04 Functions: 1
Date:2024-07-10 11:43:412024-07-11 15:06:04 Functions: 0
Date:2024-07-10 11:43:412024-07-11 15:06:04 Functions: 0
Date:2024-07-10 11:43:412024-07-11 15:06:04 Functions: 0
Date:2024-07-10 11:43:412024-07-11 15:06:04 Functions: 0
Date:2024-07-10 11:43:412024-07-11 15:06:04 Functions: 0
Date:2024-07-10 11:43:412024-07-11 15:06:04 Functions: 0
Date:2024-07-10 11:43:412024-07-11 15:06:04 Functions: 0
Date:2024-07-10 11:43:412024-07-11 15:06:04 Functions: 0
Date:2024-07-10 11:43:412024-07-11 15:06:04 Functions: 0
Date:2024-07-10 11:43:412024-07-11 15:06:04 Functions: 4
Date:2024-07-10 11:43:412024-07-11 15:06:04 Functions: 4
Date:2024-07-10 11:43:412024-07-11 15:06:04 Functions: 4
Date:2024-07-10 11:43:412024-07-11 15:06:04 Functions: 1
Date:2024-07-10 11:43:412024-07-11 15:06:04 Functions: 1
Date:2024-07-10 11:43:412024-07-11 15:06:04 Functions: 1
Date:2024-07-10 11:43:412024-07-11 15:06:04 Functions: 1360 / 14
TxtStatWriter.cppSTLTxtMeshReader.cpp
0.0%
0.0 %0 / 390 / 55 0.0 % 0 / 3 0.0 % 0 / 114
STLTxtMeshReader.cppTxtStatWriter.cpp
0.0%
0.0 %0 / 550 / 39 0.0 % 0 / 3 0.0 %40 / 72
RDGFLOMeshReader.hppMeshWriter.hpp
100.0%
100.0 %2 / 28 / 8 100.0 %1 / 12 / 2 - 0 / 0
0 / 0
NetgenMeshReader.hppHyperMeshReader.hpp
100.0%
0 / 0
ASCMeshReader.hppNetgenMeshReader.hpp
100.0%
0 / 0
MeshWriter.hppRDGFLOMeshReader.hpp
100.0%
100.0 %8 / 8100.0 % 2 / 2100.0 %1 / 1 - 0 / 0
HyperMeshReader.hppASCMeshReader.hpp
100.0%
0 / 0
GmshMeshWriter.hppNetgenMeshWriter.hpp
100.0%
100.0 %4 / 4100.0 % 2 / 2100.0 %1 / 1 - 0 / 0
NetgenMeshWriter.hppGmshMeshWriter.hpp
100.0%
100.0 %2 / 24 / 4 100.0 %1 / 12 / 2 - 0 / 0
Date:2024-07-10 11:43:412024-07-11 15:06:04 Functions: 1360 / 14
TxtStatWriter.cppSTLTxtMeshReader.cpp
0.0%
0.0 %0 / 390 / 55 0.0 % 0 / 3 0.0 % 0 / 114
STLTxtMeshReader.cppTxtStatWriter.cpp
0.0%
0.0 %0 / 550 / 39 0.0 % 0 / 3 0.0 %8 / 20
RDGFLOMeshReader.hppUGRIDMeshReader.hpp
100.0%
0 / 0
UGRIDMeshReader.hppHyperMeshReader.hpp
100.0%
0 / 0
ASCMeshReader.hppRDGFLOMeshReader.hpp
100.0%
0 / 0
HyperMeshReader.hppASCMeshReader.hpp
100.0%
0 / 0
MeshFactory.cppMeshWriter.hpp -
89.2%89.2%
+
100.0%
89.2 %66 / 74100.0 %8 / 8 100.0 % 2 / 253.9 %96 / 178-0 / 0
ExodusIIMeshWriter.hpp43 / 84
MeshWriter.hppGmshMeshWriter.hpp
100.0%
100.0 %8 / 84 / 4 100.0 % 2 / 2 - 0 / 0
GmshMeshWriter.hppMeshFactory.cpp +
89.2%89.2%
+
89.2 %66 / 74100.0 %2 / 253.9 %96 / 178
NetgenMeshWriter.cpp
100.0%
100.0 %4 / 438 / 38 100.0 %2 / 2-0 / 03 / 350.0 %45 / 90
DiagWriter.cpp31 / 64
GmshMeshReader.hppNetgenMeshReader.cpp
100.0%
100.0 %9 / 940 / 40 100.0 % 3 / 316.7 %3 / 1844.9 %44 / 98
NetgenMeshWriter.cppGmshMeshReader.hpp
100.0%
100.0 %38 / 389 / 9 100.0 % 3 / 350.0 %45 / 9016.7 %3 / 18
NetgenMeshReader.cppUGRIDMeshReader.cpp
100.0%
100.0 %40 / 4041 / 41 100.0 %3 / 344.9 %44 / 984 / 455.6 %40 / 72
HyperMeshReader.cpp41 / 126
UGRIDMeshReader.cppGmshMeshWriter.cpp
100.0%
100.0 %41 / 4178 / 78 100.0 %4 / 455.6 %40 / 725 / 550.0 %68 / 136
ExodusIIMeshReader.hpp36.4 % 24 / 66
GmshMeshWriter.cpp -
100.0%
-
100.0 %78 / 78100.0 %5 / 550.0 %68 / 136

diff --git a/Debug/test_coverage/IO/index-sort-l.html b/Debug/test_coverage/IO/index-sort-l.html index 5a38972f80db..bda1b4ef02e8 100644 --- a/Debug/test_coverage/IO/index-sort-l.html +++ b/Debug/test_coverage/IO/index-sort-l.html @@ -33,7 +33,7 @@
Date:2024-07-10 11:43:412024-07-11 15:06:04 Functions: 1368 / 20
RDGFLOMeshReader.hppUGRIDMeshReader.hpp
100.0%
0 / 0
UGRIDMeshReader.hppHyperMeshReader.hpp
100.0%
0 / 0
ASCMeshReader.hppRDGFLOMeshReader.hpp
100.0%
0 / 0
HyperMeshReader.hppASCMeshReader.hpp
100.0%
Date:2024-07-10 11:43:412024-07-11 15:06:04 Functions: 136
Date:2024-07-10 11:43:412024-07-11 15:06:04 Functions: 19
Date:2024-07-10 11:43:412024-07-11 15:06:04 Functions: 19
Date:2024-07-10 11:43:412024-07-11 15:06:04 Functions: 19
Date:2024-07-10 11:43:412024-07-11 15:06:04 Functions: 3
inciter::ALE::ALE(CkMigrateMessage*)108101
inciter::ALE::pup(PUP::er&)355334
inciter::ALE::meshvel() const
Date:2024-07-10 11:43:412024-07-11 15:06:04 Functions: 3
inciter::ALE::pup(PUP::er&)355334
inciter::ALE::ALE(CkMigrateMessage*)108101
inciter::ALE::meshvel() const
Date:2024-07-10 11:43:412024-07-11 15:06:04 Functions: 3
Date:2024-07-10 11:43:412024-07-11 15:06:04 Functions: 43
Date:2024-07-10 11:43:412024-07-11 15:06:04 Functions: 43
Date:2024-07-10 11:43:412024-07-11 15:06:04 Functions: 43
Date:2024-07-10 11:43:412024-07-11 15:06:04 Functions: 3
inciter::ALECG::ALECG(CkMigrateMessage*)16481637
inciter::ALECG::pup(PUP::er&)51845151
inciter::ALECG::Disc() const
Date:2024-07-10 11:43:412024-07-11 15:06:04 Functions: 3
inciter::ALECG::pup(PUP::er&)51845151
inciter::ALECG::ALECG(CkMigrateMessage*)16481637
inciter::ALECG::Disc() const
Date:2024-07-10 11:43:412024-07-11 15:06:04 Functions: 3
Date:2024-07-10 11:43:412024-07-11 15:06:04 Functions: 2
AMR::Edge_Refinement::Edge_Refinement()17764741735453
AMR::Edge_Refinement::Edge_Refinement(unsigned long, unsigned long, int, bool, AMR::Edge_Lock_Case)
Date:2024-07-10 11:43:412024-07-11 15:06:04 Functions: 2
AMR::Edge_Refinement::Edge_Refinement()17764741735453

diff --git a/Debug/test_coverage/Inciter/AMR/AMR_types.hpp.gcov.html b/Debug/test_coverage/Inciter/AMR/AMR_types.hpp.gcov.html index 6970fa700ee0..da0f22e6bafa 100644 --- a/Debug/test_coverage/Inciter/AMR/AMR_types.hpp.gcov.html +++ b/Debug/test_coverage/Inciter/AMR/AMR_types.hpp.gcov.html @@ -33,7 +33,7 @@
Date:2024-07-10 11:43:412024-07-11 15:06:04 Functions: 2
Date:2024-07-10 11:43:412024-07-11 15:06:04 Functions: 3
Date:2024-07-10 11:43:412024-07-11 15:06:04 Functions: 3
Date:2024-07-10 11:43:412024-07-11 15:06:04 Functions: 3
Date:2024-07-10 11:43:412024-07-11 15:06:04 Functions: 2
AMR::Refinement_State::Refinement_State()1024146998784

diff --git a/Debug/test_coverage/Inciter/AMR/Refinement_State.hpp.func.html b/Debug/test_coverage/Inciter/AMR/Refinement_State.hpp.func.html index a9d1e2c9696c..a19488d1be82 100644 --- a/Debug/test_coverage/Inciter/AMR/Refinement_State.hpp.func.html +++ b/Debug/test_coverage/Inciter/AMR/Refinement_State.hpp.func.html @@ -33,7 +33,7 @@
Date:2024-07-10 11:43:412024-07-11 15:06:04 Functions: 2
AMR::Refinement_State::Refinement_State()1024146998784

diff --git a/Debug/test_coverage/Inciter/AMR/Refinement_State.hpp.gcov.html b/Debug/test_coverage/Inciter/AMR/Refinement_State.hpp.gcov.html index 1efa598f237f..79dabbd9df2b 100644 --- a/Debug/test_coverage/Inciter/AMR/Refinement_State.hpp.gcov.html +++ b/Debug/test_coverage/Inciter/AMR/Refinement_State.hpp.gcov.html @@ -33,7 +33,7 @@
Date:2024-07-10 11:43:412024-07-11 15:06:04 Functions: 2
Date:2024-07-10 11:43:412024-07-11 15:06:04 Functions: 4
AMR::active_element_store_t::data()2439924138
AMR::active_element_store_t::erase(unsigned long)
Date:2024-07-10 11:43:412024-07-11 15:06:04 Functions: 4
AMR::active_element_store_t::data()2439924138
AMR::active_element_store_t::erase(unsigned long)
Date:2024-07-10 11:43:412024-07-11 15:06:04 Functions: 4
Date:2024-07-10 11:43:412024-07-11 15:06:04 Functions: 0
Date:2024-07-10 11:43:412024-07-11 15:06:04 Functions: 0
Date:2024-07-10 11:43:412024-07-11 15:06:04 Functions: 0
Date:2024-07-10 11:43:412024-07-11 15:06:04 Functions: 8
AMR::edge_t::get_data()61817776058714
AMR::edge_t::first() const
AMR::edge_t::edge_t()3234793832306917
AMR::edge_t::operator<(AMR::edge_t const&) const13184760381317941146
AMR::edge_t::get_data() const52739041525271764584

diff --git a/Debug/test_coverage/Inciter/AMR/edge.hpp.func.html b/Debug/test_coverage/Inciter/AMR/edge.hpp.func.html index 902c4a5ad2dd..18fc0d43e77b 100644 --- a/Debug/test_coverage/Inciter/AMR/edge.hpp.func.html +++ b/Debug/test_coverage/Inciter/AMR/edge.hpp.func.html @@ -33,7 +33,7 @@
Date:2024-07-10 11:43:412024-07-11 15:06:04 Functions: 8
AMR::edge_t::get_data()61817776058714
AMR::edge_t::edge_t(std::array<unsigned long, 2ul>)
AMR::edge_t::edge_t()3234793832306917
AMR::edge_t::first() const
AMR::edge_t::get_data() const52739041525271764584
AMR::edge_t::operator==(AMR::edge_t const&) const
AMR::edge_t::operator<(AMR::edge_t const&) const13184760381317941146

diff --git a/Debug/test_coverage/Inciter/AMR/edge.hpp.gcov.html b/Debug/test_coverage/Inciter/AMR/edge.hpp.gcov.html index 2aa2fc007960..cca2dd2b2abb 100644 --- a/Debug/test_coverage/Inciter/AMR/edge.hpp.gcov.html +++ b/Debug/test_coverage/Inciter/AMR/edge.hpp.gcov.html @@ -33,7 +33,7 @@
Date:2024-07-10 11:43:412024-07-11 15:06:04 Functions: 8
Date:2024-07-10 11:43:412024-07-11 15:06:04 Functions: 11
Date:2024-07-10 11:43:412024-07-11 15:06:04 Functions: 11
Date:2024-07-10 11:43:412024-07-11 15:06:04 Functions: 11
Date:2024-07-10 11:43:412024-07-11 15:06:04 Functions: 3
AMR::id_generator_t::id_generator_t(unsigned long)98689781
AMR::id_generator_t::generate_child_ids(unsigned long, unsigned long)
Date:2024-07-10 11:43:412024-07-11 15:06:04 Functions: 3
AMR::id_generator_t::id_generator_t(unsigned long)98689781

diff --git a/Debug/test_coverage/Inciter/AMR/id_generator.hpp.gcov.html b/Debug/test_coverage/Inciter/AMR/id_generator.hpp.gcov.html index fa12e99c1634..964317d7df12 100644 --- a/Debug/test_coverage/Inciter/AMR/id_generator.hpp.gcov.html +++ b/Debug/test_coverage/Inciter/AMR/id_generator.hpp.gcov.html @@ -33,7 +33,7 @@
Date:2024-07-10 11:43:412024-07-11 15:06:04 Functions: 3
Date:2024-07-10 11:43:412024-07-11 15:06:04 Functions: 147
Date:2024-07-10 11:43:412024-07-11 15:06:04 Functions: 14775 / 128
Refinement_State.hppmesh_adapter.hpp
100.0%
100.0 %6 / 67 / 7 100.0 % 2 / 2 50.0 %1 / 24 / 8
mesh_adapter.hppRefinement_State.hpp
100.0%
100.0 %7 / 76 / 6 100.0 % 2 / 2 50.0 %4 / 81 / 2
AMR_types.hpp- 0 / 0
id_generator.hpp -
100.0%
-
100.0 %12 / 12100.0 %3 / 375.0 %3 / 4
Error.cpp @@ -225,6 +213,18 @@ 43.8 % 7 / 16
id_generator.hpp +
100.0%
+
100.0 %12 / 12100.0 %3 / 375.0 %3 / 4
active_element_store.hpp diff --git a/Debug/test_coverage/Inciter/AMR/index-sort-l.html b/Debug/test_coverage/Inciter/AMR/index-sort-l.html index c57886daf403..6f08fca82ec1 100644 --- a/Debug/test_coverage/Inciter/AMR/index-sort-l.html +++ b/Debug/test_coverage/Inciter/AMR/index-sort-l.html @@ -33,7 +33,7 @@
Date:2024-07-10 11:43:412024-07-11 15:06:04 Functions: 147
Date:2024-07-10 11:43:412024-07-11 15:06:04 Functions: 147
Date:2024-07-10 11:43:412024-07-11 15:06:04 Functions: 14
AMR::marked_refinements_store_t<AMR::Refinement_Case>::data()2439924138
AMR::marked_refinements_store_t<AMR::Derefinement_Case>::data()2439924138
AMR::marked_refinements_store_t<AMR::Derefinement_Case>::get_state_changed()2471724456
AMR::marked_refinements_store_t<AMR::Refinement_Case>::get_state_changed()2493324672
AMR::marked_refinements_store_t<AMR::Derefinement_Case>::get(unsigned long)
Date:2024-07-10 11:43:412024-07-11 15:06:04 Functions: 14
AMR::marked_refinements_store_t<AMR::Refinement_Case>::get_state_changed()2493324672
AMR::marked_refinements_store_t<AMR::Refinement_Case>::add(unsigned long, AMR::Refinement_Case)
AMR::marked_refinements_store_t<AMR::Refinement_Case>::data()2439924138
AMR::marked_refinements_store_t<AMR::Refinement_Case>::erase(unsigned long)
AMR::marked_refinements_store_t<AMR::Derefinement_Case>::get_state_changed()2471724456
AMR::marked_refinements_store_t<AMR::Derefinement_Case>::add(unsigned long, AMR::Derefinement_Case)
AMR::marked_refinements_store_t<AMR::Derefinement_Case>::data()2439924138
AMR::marked_refinements_store_t<AMR::Derefinement_Case>::erase(unsigned long)
Date:2024-07-10 11:43:412024-07-11 15:06:04 Functions: 14
Date:2024-07-10 11:43:412024-07-11 15:06:04 Functions: 9
AMR::master_element_store_t::data()2439924138
AMR::master_element_store_t::erase(unsigned long)
Date:2024-07-10 11:43:412024-07-11 15:06:04 Functions: 9
AMR::master_element_store_t::data()2439924138
AMR::master_element_store_t::erase(unsigned long)
Date:2024-07-10 11:43:412024-07-11 15:06:04 Functions: 9
Date:2024-07-10 11:43:412024-07-11 15:06:04 Functions: 22
Date:2024-07-10 11:43:412024-07-11 15:06:04 Functions: 22
Date:2024-07-10 11:43:412024-07-11 15:06:04 Functions: 22
Date:2024-07-10 11:43:412024-07-11 15:06:04 Functions: 2
AMR::mesh_adapter_t::mesh_adapter_t()78617774

diff --git a/Debug/test_coverage/Inciter/AMR/mesh_adapter.hpp.func.html b/Debug/test_coverage/Inciter/AMR/mesh_adapter.hpp.func.html index 0cec6501afe1..a93c62e41d7e 100644 --- a/Debug/test_coverage/Inciter/AMR/mesh_adapter.hpp.func.html +++ b/Debug/test_coverage/Inciter/AMR/mesh_adapter.hpp.func.html @@ -33,7 +33,7 @@
Date:2024-07-10 11:43:412024-07-11 15:06:04 Functions: 2
AMR::mesh_adapter_t::mesh_adapter_t()78617774

diff --git a/Debug/test_coverage/Inciter/AMR/mesh_adapter.hpp.gcov.html b/Debug/test_coverage/Inciter/AMR/mesh_adapter.hpp.gcov.html index a08ea4671f02..aa01afe38d4d 100644 --- a/Debug/test_coverage/Inciter/AMR/mesh_adapter.hpp.gcov.html +++ b/Debug/test_coverage/Inciter/AMR/mesh_adapter.hpp.gcov.html @@ -33,7 +33,7 @@
Date:2024-07-10 11:43:412024-07-11 15:06:04 Functions: 2
Date:2024-07-10 11:43:412024-07-11 15:06:04 Functions: 8
AMR::node_connectivity_t::node_connectivity_t()78617774
AMR::node_connectivity_t::data()2439924138
AMR::node_connectivity_t::inv_data()2439924138
AMR::node_connectivity_t::add(unsigned long, unsigned long)
Date:2024-07-10 11:43:412024-07-11 15:06:04 Functions: 8
AMR::node_connectivity_t::data()2439924138
AMR::node_connectivity_t::print()
AMR::node_connectivity_t::inv_data()2439924138
AMR::node_connectivity_t::node_connectivity_t(unsigned long)
AMR::node_connectivity_t::node_connectivity_t()78617774

diff --git a/Debug/test_coverage/Inciter/AMR/node_connectivity.hpp.gcov.html b/Debug/test_coverage/Inciter/AMR/node_connectivity.hpp.gcov.html index e4ea97efb6da..9808ef25f2d6 100644 --- a/Debug/test_coverage/Inciter/AMR/node_connectivity.hpp.gcov.html +++ b/Debug/test_coverage/Inciter/AMR/node_connectivity.hpp.gcov.html @@ -33,7 +33,7 @@
Date:2024-07-10 11:43:412024-07-11 15:06:04 Functions: 8
Date:2024-07-10 11:43:412024-07-11 15:06:04 Functions: 19
AMR::refinement_t::refinement_t()78617774
AMR::refinement_t::generic_derefine(AMR::tet_store_t&, unsigned long)
Date:2024-07-10 11:43:412024-07-11 15:06:04 Functions: 19
AMR::refinement_t::refinement_t()78617774

diff --git a/Debug/test_coverage/Inciter/AMR/refinement.hpp.gcov.html b/Debug/test_coverage/Inciter/AMR/refinement.hpp.gcov.html index 690b0ad6736f..32acf433adc3 100644 --- a/Debug/test_coverage/Inciter/AMR/refinement.hpp.gcov.html +++ b/Debug/test_coverage/Inciter/AMR/refinement.hpp.gcov.html @@ -33,7 +33,7 @@
Date:2024-07-10 11:43:412024-07-11 15:06:04 Functions: 19
Date:2024-07-10 11:43:412024-07-11 15:06:04 Functions: 40
Date:2024-07-10 11:43:412024-07-11 15:06:04 Functions: 40
Date:2024-07-10 11:43:412024-07-11 15:06:04 Functions: 40
Date:2024-07-10 11:43:412024-07-11 15:06:04 Functions: 0
Date:2024-07-10 11:43:412024-07-11 15:06:04 Functions: 0
Date:2024-07-10 11:43:412024-07-11 15:06:04 Functions: 0
Date:2024-07-10 11:43:412024-07-11 15:06:04 Functions: 39
auto inciter::DG::writeFields(CkCallback, std::unordered_map<unsigned long, unsigned long, std::hash<unsigned long>, std::equal_to<unsigned long>, std::allocator<std::pair<unsigned long const, unsigned long> > > const&)::{lambda(unsigned long)#1}::operator()(unsigned long) const::{lambda(auto:1 const&)#1}::operator()<std::pair<int const, std::unordered_set<unsigned long, std::hash<unsigned long>, std::equal_to<unsigned long>, std::allocator<unsigned long> > > >(std::pair<int const, std::unordered_set<unsigned long, std::hash<unsigned long>, std::equal_to<unsigned long>, std::allocator<unsigned long> > > const) const703271702890

diff --git a/Debug/test_coverage/Inciter/DG.cpp.func.html b/Debug/test_coverage/Inciter/DG.cpp.func.html index 521baa33fb4f..854553a991f4 100644 --- a/Debug/test_coverage/Inciter/DG.cpp.func.html +++ b/Debug/test_coverage/Inciter/DG.cpp.func.html @@ -33,7 +33,7 @@
Date:2024-07-10 11:43:412024-07-11 15:06:04 Functions: 39
auto inciter::DG::writeFields(CkCallback, std::unordered_map<unsigned long, unsigned long, std::hash<unsigned long>, std::equal_to<unsigned long>, std::allocator<std::pair<unsigned long const, unsigned long> > > const&)::{lambda(unsigned long)#1}::operator()(unsigned long) const::{lambda(auto:1 const&)#1}::operator()<std::pair<int const, std::unordered_set<unsigned long, std::hash<unsigned long>, std::equal_to<unsigned long>, std::allocator<unsigned long> > > >(std::pair<int const, std::unordered_set<unsigned long, std::hash<unsigned long>, std::equal_to<unsigned long>, std::allocator<unsigned long> > > const) const703271702890

diff --git a/Debug/test_coverage/Inciter/DG.cpp.gcov.html b/Debug/test_coverage/Inciter/DG.cpp.gcov.html index 324bb63c558e..0b6f2390aeb6 100644 --- a/Debug/test_coverage/Inciter/DG.cpp.gcov.html +++ b/Debug/test_coverage/Inciter/DG.cpp.gcov.html @@ -33,7 +33,7 @@
Date:2024-07-10 11:43:412024-07-11 15:06:04 Functions: 39
Date:2024-07-10 11:43:412024-07-11 15:06:04 Functions: 4
inciter::DG::DG(CkMigrateMessage*)51225047
inciter::DG::pup(PUP::er&)1592215697
inciter::DG::Disc() const
Date:2024-07-10 11:43:412024-07-11 15:06:04 Functions: 4
inciter::DG::pup(PUP::er&)1592215697
inciter::DG::advance(double, double)
inciter::DG::DG(CkMigrateMessage*)51225047
inciter::DG::Disc() const
Date:2024-07-10 11:43:412024-07-11 15:06:04 Functions: 4
Date:2024-07-10 11:43:412024-07-11 15:06:04 Functions: 2
inciter::mergeDiag(int, CkReductionMsg**)51165112
inciter::serialize(unsigned long, unsigned long, std::vector<std::vector<double, std::allocator<double> >, std::allocator<std::vector<double, std::allocator<double> > > > const&)3584435840

diff --git a/Debug/test_coverage/Inciter/DiagReducer.cpp.func.html b/Debug/test_coverage/Inciter/DiagReducer.cpp.func.html index 8237c78309c6..3921f62435ec 100644 --- a/Debug/test_coverage/Inciter/DiagReducer.cpp.func.html +++ b/Debug/test_coverage/Inciter/DiagReducer.cpp.func.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:43:41 + 2024-07-11 15:06:04 Functions: 2 @@ -73,11 +73,11 @@ inciter::mergeDiag(int, CkReductionMsg**) - 5116 + 5112 inciter::serialize(unsigned long, unsigned long, std::vector<std::vector<double, std::allocator<double> >, std::allocator<std::vector<double, std::allocator<double> > > > const&) - 35844 + 35840
diff --git a/Debug/test_coverage/Inciter/DiagReducer.cpp.gcov.html b/Debug/test_coverage/Inciter/DiagReducer.cpp.gcov.html index e97374fb67c7..aade371236b3 100644 --- a/Debug/test_coverage/Inciter/DiagReducer.cpp.gcov.html +++ b/Debug/test_coverage/Inciter/DiagReducer.cpp.gcov.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:43:41 + 2024-07-11 15:06:04 Functions: 2 @@ -95,7 +95,7 @@ 21 : : namespace inciter { 22 : : 23 : : std::pair< int, std::unique_ptr<char[]> > - 24 : 35844 : serialize( std::size_t meshid, + 24 : 35840 : serialize( std::size_t meshid, 25 : : std::size_t ncomp, 26 : : const std::vector< std::vector< tk::real > >& d ) 27 : : // ***************************************************************************** @@ -108,26 +108,26 @@ 34 : : // ***************************************************************************** 35 : : { 36 : : // Prepare for serializing diagnostics to a raw binary stream, compute size - 37 [ + - ]: 71688 : PUP::sizer sizer; - 38 [ + - ]: 35844 : sizer | meshid; - 39 [ + - ]: 35844 : sizer | ncomp; - 40 [ + - ]: 35844 : sizer | const_cast< std::vector< std::vector< tk::real > >& >( d ); + 37 [ + - ]: 71680 : PUP::sizer sizer; + 38 [ + - ]: 35840 : sizer | meshid; + 39 [ + - ]: 35840 : sizer | ncomp; + 40 [ + - ]: 35840 : sizer | const_cast< std::vector< std::vector< tk::real > >& >( d ); 41 : : 42 : : // Create raw character stream to store the serialized vectors - 43 [ + - ]: 71688 : std::unique_ptr<char[]> flatData = std::make_unique<char[]>( sizer.size() ); + 43 [ + - ]: 71680 : std::unique_ptr<char[]> flatData = std::make_unique<char[]>( sizer.size() ); 44 : : 45 : : // Serialize vector, each message will contain a vector - 46 [ + - ]: 35844 : PUP::toMem packer( flatData.get() ); - 47 [ + - ]: 35844 : packer | meshid; - 48 [ + - ]: 35844 : packer | ncomp; - 49 [ + - ]: 35844 : packer | const_cast< std::vector< std::vector< tk::real > >& >( d ); + 46 [ + - ]: 35840 : PUP::toMem packer( flatData.get() ); + 47 [ + - ]: 35840 : packer | meshid; + 48 [ + - ]: 35840 : packer | ncomp; + 49 [ + - ]: 35840 : packer | const_cast< std::vector< std::vector< tk::real > >& >( d ); 50 : : 51 : : // Return size of and raw stream - 52 : 71688 : return { sizer.size(), std::move(flatData) }; + 52 : 71680 : return { sizer.size(), std::move(flatData) }; 53 : : } 54 : : 55 : : CkReductionMsg* - 56 : 5116 : mergeDiag( int nmsg, CkReductionMsg **msgs ) + 56 : 5112 : mergeDiag( int nmsg, CkReductionMsg **msgs ) 57 : : // ***************************************************************************** 58 : : // Charm++ custom reducer for merging diagnostics during reduction across PEs 59 : : //! \param[in] nmsg Number of messages in msgs @@ -137,17 +137,17 @@ 63 : : // ***************************************************************************** 64 : : { 65 : : std::size_t meshid, ncomp; - 66 : 10232 : std::vector< std::vector< tk::real > > v; + 66 : 10224 : std::vector< std::vector< tk::real > > v; 67 : : 68 : : // Create PUP deserializer based on message passed in - 69 [ + - ]: 10232 : PUP::fromMem creator( msgs[0]->getData() ); + 69 [ + - ]: 10224 : PUP::fromMem creator( msgs[0]->getData() ); 70 : : 71 : : // Deserialize vector from raw stream - 72 [ + - ]: 5116 : creator | meshid; - 73 [ + - ]: 5116 : creator | ncomp; - 74 [ + - ]: 5116 : creator | v; + 72 [ + - ]: 5112 : creator | meshid; + 73 [ + - ]: 5112 : creator | ncomp; + 74 [ + - ]: 5112 : creator | v; 75 : : - 76 [ + + ]: 32480 : for (int m=1; m<nmsg; ++m) { + 76 [ + + ]: 32476 : for (int m=1; m<nmsg; ++m) { 77 : : // Unpack vector 78 : : std::size_t mid, nc; 79 : 54728 : std::vector< std::vector< tk::real > > w; @@ -177,7 +177,7 @@ 100 [ + + ]: 106518 : for (std::size_t i=0; i<v[L2RES].size(); ++i) v[L2RES][i] += w[L2RES][i]; 101 : : // Max for the Linf norm of the numerical - analytical solution for all comp 102 [ + + ]: 106518 : for (std::size_t i=0; i<v[LINFERR].size(); ++i) - 103 [ + + ]: 79154 : if (w[LINFERR][i] > v[LINFERR][i]) v[LINFERR][i] = w[LINFERR][i]; + 103 [ + + ]: 79154 : if (w[LINFERR][i] > v[LINFERR][i]) v[LINFERR][i] = w[LINFERR][i]; 104 : : // Sum of the total energy over the entire domain 105 : 27364 : v[TOTALSOL][0] += w[TOTALSOL][0]; 106 : : // Copy ITER, TIME, DT @@ -187,10 +187,10 @@ 110 : : } 111 : : 112 : : // Serialize concatenated diagnostics vector to raw stream - 113 [ + - ]: 10232 : auto stream = serialize( meshid, ncomp, v ); + 113 [ + - ]: 10224 : auto stream = serialize( meshid, ncomp, v ); 114 : : 115 : : // Forward serialized diagnostics - 116 [ + - ]: 10232 : return CkReductionMsg::buildNew( stream.first, stream.second.get() ); + 116 [ + - ]: 10224 : return CkReductionMsg::buildNew( stream.first, stream.second.get() ); 117 : : } 118 : : 119 : : } // inciter:: diff --git a/Debug/test_coverage/Inciter/Discretization.cpp.func-sort-c.html b/Debug/test_coverage/Inciter/Discretization.cpp.func-sort-c.html index 3e2f8ee27bef..4f66d2fa7fad 100644 --- a/Debug/test_coverage/Inciter/Discretization.cpp.func-sort-c.html +++ b/Debug/test_coverage/Inciter/Discretization.cpp.func-sort-c.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:43:41 + 2024-07-11 15:06:04 Functions: 42 diff --git a/Debug/test_coverage/Inciter/Discretization.cpp.func.html b/Debug/test_coverage/Inciter/Discretization.cpp.func.html index 54275e0c13d1..a2af64431af7 100644 --- a/Debug/test_coverage/Inciter/Discretization.cpp.func.html +++ b/Debug/test_coverage/Inciter/Discretization.cpp.func.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:43:41 + 2024-07-11 15:06:04 Functions: 42 diff --git a/Debug/test_coverage/Inciter/Discretization.cpp.gcov.html b/Debug/test_coverage/Inciter/Discretization.cpp.gcov.html index 42e0ae9a79a0..ff929e338dd0 100644 --- a/Debug/test_coverage/Inciter/Discretization.cpp.gcov.html +++ b/Debug/test_coverage/Inciter/Discretization.cpp.gcov.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:43:41 + 2024-07-11 15:06:04 Functions: 42 @@ -234,8 +234,8 @@ 148 : : std::array< tk::real, 4 > N; 149 : 52 : const auto& l = pt[p].get< tag::coord >(); 150 : 52 : const auto& id = pt[p].get< tag::id >(); - 151 [ + + ]: 25042 : for (std::size_t e=0; e<m_inpoel.size()/4; ++e) { - 152 [ + - ][ + + ]: 25000 : if (tk::intet( m_coord, m_inpoel, l, e, N )) { + 151 [ + + ]: 25008 : for (std::size_t e=0; e<m_inpoel.size()/4; ++e) { + 152 [ + - ][ + + ]: 24966 : if (tk::intet( m_coord, m_inpoel, l, e, N )) { 153 [ + - ][ + - ]: 10 : m_histdata.push_back( HistData{{ id, e, {l[0],l[1],l[2]}, N }} ); 154 : 10 : break; 155 : : } @@ -521,8 +521,8 @@ 428 : : { 429 : : // Lambda to find out if a mesh node is shared with another chare 430 : 10327604 : auto shared = [this]( std::size_t i ){ - 431 [ + + ]: 29355575 : for (const auto& [c,n] : m_nodeCommMap) - 432 [ + - ][ + + ]: 21108177 : if (n.find(i) != end(n)) return true; + 431 [ + + ]: 29311427 : for (const auto& [c,n] : m_nodeCommMap) + 432 [ + - ][ + + ]: 21064029 : if (n.find(i) != end(n)) return true; 433 : 8247398 : return false; 434 : 8329 : }; 435 : : @@ -876,7 +876,7 @@ 749 : 1808158 : const auto dz = z[ i ] - z[ p ]; 750 : 1808158 : const auto length = std::sqrt( dx*dx + dy*dy + dz*dz ); 751 [ + + ]: 1808158 : if (length < min[0]) min[0] = length; - 752 [ + + ]: 1808158 : if (length > max[0]) max[0] = length; + 752 [ + + ]: 1808158 : if (length > max[0]) max[0] = length; 753 : 1808158 : sum[0] += 1.0; 754 : 1808158 : sum[1] += length; 755 [ + - ]: 1808158 : edgePDF.add( length ); @@ -891,8 +891,8 @@ 764 : 557492 : ca{{ x[N[2]]-x[N[0]], y[N[2]]-y[N[0]], z[N[2]]-z[N[0]] }}, 765 : 557492 : da{{ x[N[3]]-x[N[0]], y[N[3]]-y[N[0]], z[N[3]]-z[N[0]] }}; 766 : 557492 : const auto L = std::cbrt( tk::triple( ba, ca, da ) / 6.0 ); - 767 [ + + ]: 557492 : if (L < min[1]) min[1] = L; - 768 [ + + ]: 557492 : if (L > max[1]) max[1] = L; + 767 [ + + ]: 557492 : if (L < min[1]) min[1] = L; + 768 [ + + ]: 557492 : if (L > max[1]) max[1] = L; 769 : 557492 : sum[2] += 1.0; 770 : 557492 : sum[3] += L; 771 [ + - ]: 557492 : volPDF.add( L ); diff --git a/Debug/test_coverage/Inciter/Discretization.hpp.func-sort-c.html b/Debug/test_coverage/Inciter/Discretization.hpp.func-sort-c.html index 8a0a4f9a07da..bc10714104b3 100644 --- a/Debug/test_coverage/Inciter/Discretization.hpp.func-sort-c.html +++ b/Debug/test_coverage/Inciter/Discretization.hpp.func-sort-c.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:43:41 + 2024-07-11 15:06:04 Functions: 39 @@ -121,7 +121,7 @@ inciter::Discretization::Discretization(CkMigrateMessage*) - 7861 + 7774 inciter::Discretization::Coord() const @@ -141,7 +141,7 @@ inciter::Discretization::pup(PUP::er&) - 24399 + 24138 inciter::Discretization::Voln() diff --git a/Debug/test_coverage/Inciter/Discretization.hpp.func.html b/Debug/test_coverage/Inciter/Discretization.hpp.func.html index ec56919f26f0..57187beba504 100644 --- a/Debug/test_coverage/Inciter/Discretization.hpp.func.html +++ b/Debug/test_coverage/Inciter/Discretization.hpp.func.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:43:41 + 2024-07-11 15:06:04 Functions: 39 @@ -101,7 +101,7 @@ inciter::Discretization::pup(PUP::er&) - 24399 + 24138 inciter::Discretization::Voln() @@ -133,7 +133,7 @@ inciter::Discretization::Discretization(CkMigrateMessage*) - 7861 + 7774 inciter::Discretization::EdgeCommMap() const diff --git a/Debug/test_coverage/Inciter/Discretization.hpp.gcov.html b/Debug/test_coverage/Inciter/Discretization.hpp.gcov.html index 76dc1dd8ed6c..0a7c8aca575a 100644 --- a/Debug/test_coverage/Inciter/Discretization.hpp.gcov.html +++ b/Debug/test_coverage/Inciter/Discretization.hpp.gcov.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:43:41 + 2024-07-11 15:06:04 Functions: 39 @@ -158,7 +158,7 @@ 84 : : #endif 85 : : //! Migrate constructor 86 : : // cppcheck-suppress uninitMemberVar - 87 [ + - ]: 7861 : explicit Discretization( CkMigrateMessage* ) {} + 87 [ + - ]: 7774 : explicit Discretization( CkMigrateMessage* ) {} 88 : : #if defined(__clang__) 89 : : #pragma clang diagnostic pop 90 : : #endif @@ -513,63 +513,63 @@ 437 : : ///@{ 438 : : //! \brief Pack/Unpack serialize member function 439 : : //! \param[in,out] p Charm++'s PUP::er serializer object reference - 440 : 24399 : void pup( PUP::er &p ) override { - 441 : 24399 : p | m_meshid; - 442 : 24399 : p | m_transfer_complete; - 443 : 24399 : p | m_transfer; - 444 : 24399 : p | m_mytransfer; - 445 : 24399 : p | m_disc; - 446 : 24399 : p | m_nchare; - 447 : 24399 : p | m_it; - 448 : 24399 : p | m_itr; - 449 : 24399 : p | m_itf; - 450 : 24399 : p | m_initial; - 451 : 24399 : p | m_t; - 452 : 24399 : p | m_lastDumpTime; - 453 : 24399 : p | m_physFieldFloor; - 454 : 24399 : p | m_physHistFloor; - 455 : 24399 : p | m_rangeFieldFloor; - 456 : 24399 : p | m_rangeHistFloor; - 457 : 24399 : p | m_dt; - 458 : 24399 : p | m_dtn; - 459 : 24399 : p | m_nvol; - 460 : 24399 : p | m_nxfer; - 461 : 24399 : p | m_ale; - 462 : 24399 : p | m_transporter; - 463 : 24399 : p | m_meshwriter; - 464 : 24399 : p | m_refiner; - 465 : 24399 : p | m_el; - 466 [ + + ]: 24399 : if (p.isUnpacking()) { - 467 : 7861 : m_inpoel = std::get< 0 >( m_el ); - 468 : 7861 : m_gid = std::get< 1 >( m_el ); - 469 : 7861 : m_lid = std::get< 2 >( m_el ); + 440 : 24138 : void pup( PUP::er &p ) override { + 441 : 24138 : p | m_meshid; + 442 : 24138 : p | m_transfer_complete; + 443 : 24138 : p | m_transfer; + 444 : 24138 : p | m_mytransfer; + 445 : 24138 : p | m_disc; + 446 : 24138 : p | m_nchare; + 447 : 24138 : p | m_it; + 448 : 24138 : p | m_itr; + 449 : 24138 : p | m_itf; + 450 : 24138 : p | m_initial; + 451 : 24138 : p | m_t; + 452 : 24138 : p | m_lastDumpTime; + 453 : 24138 : p | m_physFieldFloor; + 454 : 24138 : p | m_physHistFloor; + 455 : 24138 : p | m_rangeFieldFloor; + 456 : 24138 : p | m_rangeHistFloor; + 457 : 24138 : p | m_dt; + 458 : 24138 : p | m_dtn; + 459 : 24138 : p | m_nvol; + 460 : 24138 : p | m_nxfer; + 461 : 24138 : p | m_ale; + 462 : 24138 : p | m_transporter; + 463 : 24138 : p | m_meshwriter; + 464 : 24138 : p | m_refiner; + 465 : 24138 : p | m_el; + 466 [ + + ]: 24138 : if (p.isUnpacking()) { + 467 : 7774 : m_inpoel = std::get< 0 >( m_el ); + 468 : 7774 : m_gid = std::get< 1 >( m_el ); + 469 : 7774 : m_lid = std::get< 2 >( m_el ); 470 : : } - 471 : 24399 : p | m_coord; - 472 : 24399 : p | m_coordn; - 473 : 24399 : p | m_nodeCommMap; - 474 : 24399 : p | m_edgeCommMap; - 475 : 24399 : p | m_meshvol; - 476 : 24399 : p | m_v; - 477 : 24399 : p | m_vol; - 478 : 24399 : p | m_volc; - 479 : 24399 : p | m_voln; - 480 : 24399 : p | m_vol0; - 481 : 24399 : p | m_boxvol; - 482 : 24399 : p | m_meshblkvol; - 483 : 24399 : p | m_bid; - 484 : 24399 : p | m_timer; - 485 : 24399 : p | m_refined; - 486 : 24399 : p( reinterpret_cast<char*>(&m_prevstatus), sizeof(Clock::time_point) ); - 487 : 24399 : p | m_nrestart; - 488 : 24399 : p | m_histdata; - 489 : 24399 : p | m_nsrc; - 490 : 24399 : p | m_ndst; - 491 : 24399 : p | m_meshvel; - 492 : 24399 : p | m_meshvel_converged; - 493 : 24399 : p | m_bface; - 494 : 24399 : p | m_triinpoel; - 495 : 24399 : p | m_elemblockid; - 496 : 24399 : } + 471 : 24138 : p | m_coord; + 472 : 24138 : p | m_coordn; + 473 : 24138 : p | m_nodeCommMap; + 474 : 24138 : p | m_edgeCommMap; + 475 : 24138 : p | m_meshvol; + 476 : 24138 : p | m_v; + 477 : 24138 : p | m_vol; + 478 : 24138 : p | m_volc; + 479 : 24138 : p | m_voln; + 480 : 24138 : p | m_vol0; + 481 : 24138 : p | m_boxvol; + 482 : 24138 : p | m_meshblkvol; + 483 : 24138 : p | m_bid; + 484 : 24138 : p | m_timer; + 485 : 24138 : p | m_refined; + 486 : 24138 : p( reinterpret_cast<char*>(&m_prevstatus), sizeof(Clock::time_point) ); + 487 : 24138 : p | m_nrestart; + 488 : 24138 : p | m_histdata; + 489 : 24138 : p | m_nsrc; + 490 : 24138 : p | m_ndst; + 491 : 24138 : p | m_meshvel; + 492 : 24138 : p | m_meshvel_converged; + 493 : 24138 : p | m_bface; + 494 : 24138 : p | m_triinpoel; + 495 : 24138 : p | m_elemblockid; + 496 : 24138 : } 497 : : //! \brief Pack/Unpack serialize operator| 498 : : //! \param[in,out] p Charm++'s PUP::er serializer object reference 499 : : //! \param[in,out] i Discretization object reference diff --git a/Debug/test_coverage/Inciter/ElemDiagnostics.cpp.func-sort-c.html b/Debug/test_coverage/Inciter/ElemDiagnostics.cpp.func-sort-c.html index e9e3e14ac6a8..697755d5b4bb 100644 --- a/Debug/test_coverage/Inciter/ElemDiagnostics.cpp.func-sort-c.html +++ b/Debug/test_coverage/Inciter/ElemDiagnostics.cpp.func-sort-c.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:43:41 + 2024-07-11 15:06:04 Functions: 3 diff --git a/Debug/test_coverage/Inciter/ElemDiagnostics.cpp.func.html b/Debug/test_coverage/Inciter/ElemDiagnostics.cpp.func.html index f3fad594e8c1..55bb3343f497 100644 --- a/Debug/test_coverage/Inciter/ElemDiagnostics.cpp.func.html +++ b/Debug/test_coverage/Inciter/ElemDiagnostics.cpp.func.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:43:41 + 2024-07-11 15:06:04 Functions: 3 diff --git a/Debug/test_coverage/Inciter/ElemDiagnostics.cpp.gcov.html b/Debug/test_coverage/Inciter/ElemDiagnostics.cpp.gcov.html index e898f47ddde2..59e9d6b94e5c 100644 --- a/Debug/test_coverage/Inciter/ElemDiagnostics.cpp.gcov.html +++ b/Debug/test_coverage/Inciter/ElemDiagnostics.cpp.gcov.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:43:41 + 2024-07-11 15:06:04 Functions: 3 @@ -291,7 +291,7 @@ 216 : : 217 : : // Compute max for Linf norm of the numerical-analytic solution 218 : 28773245 : auto err = std::abs( ugp - s[c] ); - 219 [ + + ]: 28773245 : if (err > diag[LINFERR][c]) diag[LINFERR][c] = err; + 219 [ + + ]: 28773245 : if (err > diag[LINFERR][c]) diag[LINFERR][c] = err; 220 : : } 221 : : } 222 : 3599087 : tk::real sp_te(0.0); diff --git a/Debug/test_coverage/Inciter/ElemDiagnostics.hpp.func-sort-c.html b/Debug/test_coverage/Inciter/ElemDiagnostics.hpp.func-sort-c.html index 95e92d97066b..80f7d91f8d2a 100644 --- a/Debug/test_coverage/Inciter/ElemDiagnostics.hpp.func-sort-c.html +++ b/Debug/test_coverage/Inciter/ElemDiagnostics.hpp.func-sort-c.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:43:41 + 2024-07-11 15:06:04 Functions: 2 @@ -73,11 +73,11 @@ inciter::ElemDiagnostics::pup(PUP::er&) - 16260 + 16014 inciter::operator|(PUP::er&, inciter::ElemDiagnostics&) - 16260 + 16014
diff --git a/Debug/test_coverage/Inciter/ElemDiagnostics.hpp.func.html b/Debug/test_coverage/Inciter/ElemDiagnostics.hpp.func.html index 6e673e18b91b..878926a07791 100644 --- a/Debug/test_coverage/Inciter/ElemDiagnostics.hpp.func.html +++ b/Debug/test_coverage/Inciter/ElemDiagnostics.hpp.func.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:43:41 + 2024-07-11 15:06:04 Functions: 2 @@ -73,11 +73,11 @@ inciter::ElemDiagnostics::pup(PUP::er&) - 16260 + 16014 inciter::operator|(PUP::er&, inciter::ElemDiagnostics&) - 16260 + 16014
diff --git a/Debug/test_coverage/Inciter/ElemDiagnostics.hpp.gcov.html b/Debug/test_coverage/Inciter/ElemDiagnostics.hpp.gcov.html index 8cb60aaaae5c..6a93880982fe 100644 --- a/Debug/test_coverage/Inciter/ElemDiagnostics.hpp.gcov.html +++ b/Debug/test_coverage/Inciter/ElemDiagnostics.hpp.gcov.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:43:41 + 2024-07-11 15:06:04 Functions: 2 @@ -111,11 +111,11 @@ 37 : : /** @name Charm++ pack/unpack serializer member functions */ 38 : : ///@{ 39 : : //! \brief Pack/Unpack serialize member function - 40 : 16260 : void pup( PUP::er& ) {} + 40 : 16014 : void pup( PUP::er& ) {} 41 : : //! \brief Pack/Unpack serialize operator| 42 : : //! \param[in,out] p Charm++'s PUP::er serializer object reference 43 : : //! \param[in,out] d Diagnostics object reference - 44 : 16260 : friend void operator|( PUP::er& p, ElemDiagnostics& d ) { d.pup(p); } + 44 : 16014 : friend void operator|( PUP::er& p, ElemDiagnostics& d ) { d.pup(p); } 45 : : //@} 46 : : 47 : : private: diff --git a/Debug/test_coverage/Inciter/FV.cpp.func-sort-c.html b/Debug/test_coverage/Inciter/FV.cpp.func-sort-c.html index 184738fca5cf..91d6e1be1557 100644 --- a/Debug/test_coverage/Inciter/FV.cpp.func-sort-c.html +++ b/Debug/test_coverage/Inciter/FV.cpp.func-sort-c.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:43:41 + 2024-07-11 15:06:04 Functions: 28 diff --git a/Debug/test_coverage/Inciter/FV.cpp.func.html b/Debug/test_coverage/Inciter/FV.cpp.func.html index 869411da5f16..a18203be7ec0 100644 --- a/Debug/test_coverage/Inciter/FV.cpp.func.html +++ b/Debug/test_coverage/Inciter/FV.cpp.func.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:43:41 + 2024-07-11 15:06:04 Functions: 28 diff --git a/Debug/test_coverage/Inciter/FV.cpp.gcov.html b/Debug/test_coverage/Inciter/FV.cpp.gcov.html index c4674f3f818b..bf24263522a7 100644 --- a/Debug/test_coverage/Inciter/FV.cpp.gcov.html +++ b/Debug/test_coverage/Inciter/FV.cpp.gcov.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:43:41 + 2024-07-11 15:06:04 Functions: 28 diff --git a/Debug/test_coverage/Inciter/FV.hpp.func-sort-c.html b/Debug/test_coverage/Inciter/FV.hpp.func-sort-c.html index 0049b6bb8355..35edc312e516 100644 --- a/Debug/test_coverage/Inciter/FV.hpp.func-sort-c.html +++ b/Debug/test_coverage/Inciter/FV.hpp.func-sort-c.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:43:41 + 2024-07-11 15:06:04 Functions: 4 @@ -89,11 +89,11 @@ inciter::FV::FV(CkMigrateMessage*) - 111 + 104 inciter::FV::pup(PUP::er&) - 338 + 317 inciter::FV::Disc() const diff --git a/Debug/test_coverage/Inciter/FV.hpp.func.html b/Debug/test_coverage/Inciter/FV.hpp.func.html index 5b788230ae30..424930327ae2 100644 --- a/Debug/test_coverage/Inciter/FV.hpp.func.html +++ b/Debug/test_coverage/Inciter/FV.hpp.func.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:43:41 + 2024-07-11 15:06:04 Functions: 4 @@ -77,7 +77,7 @@ inciter::FV::pup(PUP::er&) - 338 + 317 inciter::FV::advance(double, double) @@ -89,7 +89,7 @@ inciter::FV::FV(CkMigrateMessage*) - 111 + 104 inciter::FV::Disc() const diff --git a/Debug/test_coverage/Inciter/FV.hpp.gcov.html b/Debug/test_coverage/Inciter/FV.hpp.gcov.html index 0245556b2c62..79e555162e68 100644 --- a/Debug/test_coverage/Inciter/FV.hpp.gcov.html +++ b/Debug/test_coverage/Inciter/FV.hpp.gcov.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:43:41 + 2024-07-11 15:06:04 Functions: 4 @@ -151,7 +151,7 @@ 77 : : #endif 78 : : //! Migrate constructor 79 : : // cppcheck-suppress uninitMemberVar - 80 : 111 : explicit FV( CkMigrateMessage* msg ) : CBase_FV( msg ) {} + 80 : 104 : explicit FV( CkMigrateMessage* msg ) : CBase_FV( msg ) {} 81 : : #if defined(__clang__) 82 : : #pragma clang diagnostic pop 83 : : #endif @@ -257,37 +257,37 @@ 183 : : ///@{ 184 : : //! \brief Pack/Unpack serialize member function 185 : : //! \param[in,out] p Charm++'s PUP::er serializer object reference - 186 : 338 : void pup( PUP::er &p ) override { - 187 : 338 : p | m_disc; - 188 : 338 : p | m_ghosts; - 189 : 338 : p | m_nsol; - 190 : 338 : p | m_ninitsol; - 191 : 338 : p | m_nlim; - 192 : 338 : p | m_nnod; - 193 : 338 : p | m_u; - 194 : 338 : p | m_un; - 195 : 338 : p | m_p; - 196 : 338 : p | m_lhs; - 197 : 338 : p | m_rhs; - 198 : 338 : p | m_npoin; - 199 : 338 : p | m_diag; - 200 : 338 : p | m_stage; - 201 : 338 : p | m_uc; - 202 : 338 : p | m_pc; - 203 : 338 : p | m_initial; - 204 : 338 : p | m_uElemfields; - 205 : 338 : p | m_pElemfields; - 206 : 338 : p | m_uNodefields; - 207 : 338 : p | m_pNodefields; - 208 : 338 : p | m_uNodefieldsc; - 209 : 338 : p | m_pNodefieldsc; - 210 : 338 : p | m_boxelems; - 211 : 338 : p | m_srcFlag; - 212 : 338 : p | m_rkcoef; - 213 : 338 : p | m_nrk; - 214 : 338 : p | m_dte; - 215 : 338 : p | m_finished; - 216 : 338 : } + 186 : 317 : void pup( PUP::er &p ) override { + 187 : 317 : p | m_disc; + 188 : 317 : p | m_ghosts; + 189 : 317 : p | m_nsol; + 190 : 317 : p | m_ninitsol; + 191 : 317 : p | m_nlim; + 192 : 317 : p | m_nnod; + 193 : 317 : p | m_u; + 194 : 317 : p | m_un; + 195 : 317 : p | m_p; + 196 : 317 : p | m_lhs; + 197 : 317 : p | m_rhs; + 198 : 317 : p | m_npoin; + 199 : 317 : p | m_diag; + 200 : 317 : p | m_stage; + 201 : 317 : p | m_uc; + 202 : 317 : p | m_pc; + 203 : 317 : p | m_initial; + 204 : 317 : p | m_uElemfields; + 205 : 317 : p | m_pElemfields; + 206 : 317 : p | m_uNodefields; + 207 : 317 : p | m_pNodefields; + 208 : 317 : p | m_uNodefieldsc; + 209 : 317 : p | m_pNodefieldsc; + 210 : 317 : p | m_boxelems; + 211 : 317 : p | m_srcFlag; + 212 : 317 : p | m_rkcoef; + 213 : 317 : p | m_nrk; + 214 : 317 : p | m_dte; + 215 : 317 : p | m_finished; + 216 : 317 : } 217 : : //! \brief Pack/Unpack serialize operator| 218 : : //! \param[in,out] p Charm++'s PUP::er serializer object reference 219 : : //! \param[in,out] i FV object reference diff --git a/Debug/test_coverage/Inciter/FaceData.cpp.func-sort-c.html b/Debug/test_coverage/Inciter/FaceData.cpp.func-sort-c.html index 9e304e54a3ff..d4d72f98a5c4 100644 --- a/Debug/test_coverage/Inciter/FaceData.cpp.func-sort-c.html +++ b/Debug/test_coverage/Inciter/FaceData.cpp.func-sort-c.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:43:41 + 2024-07-11 15:06:04 Functions: 1 diff --git a/Debug/test_coverage/Inciter/FaceData.cpp.func.html b/Debug/test_coverage/Inciter/FaceData.cpp.func.html index 137e3bc78b9b..06b0c3db54b9 100644 --- a/Debug/test_coverage/Inciter/FaceData.cpp.func.html +++ b/Debug/test_coverage/Inciter/FaceData.cpp.func.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:43:41 + 2024-07-11 15:06:04 Functions: 1 diff --git a/Debug/test_coverage/Inciter/FaceData.cpp.gcov.html b/Debug/test_coverage/Inciter/FaceData.cpp.gcov.html index 8506ed09838d..fc26d354552a 100644 --- a/Debug/test_coverage/Inciter/FaceData.cpp.gcov.html +++ b/Debug/test_coverage/Inciter/FaceData.cpp.gcov.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:43:41 + 2024-07-11 15:06:04 Functions: 1 diff --git a/Debug/test_coverage/Inciter/FaceData.hpp.func-sort-c.html b/Debug/test_coverage/Inciter/FaceData.hpp.func-sort-c.html index 1d03661caef6..cc7ffc4248e0 100644 --- a/Debug/test_coverage/Inciter/FaceData.hpp.func-sort-c.html +++ b/Debug/test_coverage/Inciter/FaceData.hpp.func-sort-c.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:43:41 + 2024-07-11 15:06:04 Functions: 13 @@ -81,15 +81,15 @@ inciter::FaceData::FaceData() - 5233 + 5151 inciter::FaceData::pup(PUP::er&) - 16260 + 16014 inciter::operator|(PUP::er&, inciter::FaceData&) - 16260 + 16014 inciter::FaceData::Inpofa() diff --git a/Debug/test_coverage/Inciter/FaceData.hpp.func.html b/Debug/test_coverage/Inciter/FaceData.hpp.func.html index bd799f21d92f..92a608b71093 100644 --- a/Debug/test_coverage/Inciter/FaceData.hpp.func.html +++ b/Debug/test_coverage/Inciter/FaceData.hpp.func.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:43:41 + 2024-07-11 15:06:04 Functions: 13 @@ -73,7 +73,7 @@ inciter::FaceData::pup(PUP::er&) - 16260 + 16014 inciter::FaceData::Esuf() @@ -89,11 +89,11 @@ inciter::FaceData::FaceData() - 5233 + 5151 inciter::operator|(PUP::er&, inciter::FaceData&) - 16260 + 16014 inciter::FaceData::Esuf() const diff --git a/Debug/test_coverage/Inciter/FaceData.hpp.gcov.html b/Debug/test_coverage/Inciter/FaceData.hpp.gcov.html index 451adb2de082..a30940c3e50c 100644 --- a/Debug/test_coverage/Inciter/FaceData.hpp.gcov.html +++ b/Debug/test_coverage/Inciter/FaceData.hpp.gcov.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:43:41 + 2024-07-11 15:06:04 Functions: 13 @@ -116,7 +116,7 @@ 42 : : 43 : : public: 44 : : //! Empty constructor for Charm++ - 45 : 5233 : explicit FaceData() {} + 45 : 5151 : explicit FaceData() {} 46 : : 47 : : //! \brief Constructor: compute (element-face) data for internal and 48 : : //! domain-boundary faces @@ -147,19 +147,19 @@ 73 : : ///@{ 74 : : //! \brief Pack/Unpack serialize member function 75 : : //! \param[in,out] p Charm++'s PUP::er serializer object reference - 76 : 16260 : void pup( PUP::er &p ) { - 77 : 16260 : p | m_bface; - 78 : 16260 : p | m_triinpoel; - 79 : 16260 : p | m_esuel; - 80 : 16260 : p | m_nipfac; - 81 : 16260 : p | m_inpofa; - 82 : 16260 : p | m_belem; - 83 : 16260 : p | m_esuf; - 84 : 16260 : } + 76 : 16014 : void pup( PUP::er &p ) { + 77 : 16014 : p | m_bface; + 78 : 16014 : p | m_triinpoel; + 79 : 16014 : p | m_esuel; + 80 : 16014 : p | m_nipfac; + 81 : 16014 : p | m_inpofa; + 82 : 16014 : p | m_belem; + 83 : 16014 : p | m_esuf; + 84 : 16014 : } 85 : : //! \brief Pack/Unpack serialize operator| 86 : : //! \param[in,out] p Charm++'s PUP::er serializer object reference 87 : : //! \param[in,out] i FaceData object reference - 88 : 16260 : friend void operator|( PUP::er& p, FaceData& i ) { i.pup(p); } + 88 : 16014 : friend void operator|( PUP::er& p, FaceData& i ) { i.pup(p); } 89 : : //@} 90 : : 91 : : private: diff --git a/Debug/test_coverage/Inciter/FieldOutput.cpp.func-sort-c.html b/Debug/test_coverage/Inciter/FieldOutput.cpp.func-sort-c.html index d57e6bc64f9e..e5da6b7ddfe3 100644 --- a/Debug/test_coverage/Inciter/FieldOutput.cpp.func-sort-c.html +++ b/Debug/test_coverage/Inciter/FieldOutput.cpp.func-sort-c.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:43:41 + 2024-07-11 15:06:04 Functions: 3 diff --git a/Debug/test_coverage/Inciter/FieldOutput.cpp.func.html b/Debug/test_coverage/Inciter/FieldOutput.cpp.func.html index ab333f554276..e01a6c412028 100644 --- a/Debug/test_coverage/Inciter/FieldOutput.cpp.func.html +++ b/Debug/test_coverage/Inciter/FieldOutput.cpp.func.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:43:41 + 2024-07-11 15:06:04 Functions: 3 diff --git a/Debug/test_coverage/Inciter/FieldOutput.cpp.gcov.html b/Debug/test_coverage/Inciter/FieldOutput.cpp.gcov.html index aca2e264172c..adff0ccbe351 100644 --- a/Debug/test_coverage/Inciter/FieldOutput.cpp.gcov.html +++ b/Debug/test_coverage/Inciter/FieldOutput.cpp.gcov.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:43:41 + 2024-07-11 15:06:04 Functions: 3 diff --git a/Debug/test_coverage/Inciter/FieldOutput.hpp.func-sort-c.html b/Debug/test_coverage/Inciter/FieldOutput.hpp.func-sort-c.html index bd6e7fa46e72..1fcfeb2e1927 100644 --- a/Debug/test_coverage/Inciter/FieldOutput.hpp.func-sort-c.html +++ b/Debug/test_coverage/Inciter/FieldOutput.hpp.func-sort-c.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:43:41 + 2024-07-11 15:06:04 Functions: 6 diff --git a/Debug/test_coverage/Inciter/FieldOutput.hpp.func.html b/Debug/test_coverage/Inciter/FieldOutput.hpp.func.html index edbbe704d7b4..ab4c78db4a23 100644 --- a/Debug/test_coverage/Inciter/FieldOutput.hpp.func.html +++ b/Debug/test_coverage/Inciter/FieldOutput.hpp.func.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:43:41 + 2024-07-11 15:06:04 Functions: 6 diff --git a/Debug/test_coverage/Inciter/FieldOutput.hpp.gcov.html b/Debug/test_coverage/Inciter/FieldOutput.hpp.gcov.html index e55e4c97699e..dc1ac1c5d6c1 100644 --- a/Debug/test_coverage/Inciter/FieldOutput.hpp.gcov.html +++ b/Debug/test_coverage/Inciter/FieldOutput.hpp.gcov.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:43:41 + 2024-07-11 15:06:04 Functions: 6 diff --git a/Debug/test_coverage/Inciter/Ghosts.cpp.func-sort-c.html b/Debug/test_coverage/Inciter/Ghosts.cpp.func-sort-c.html index a67f5d5e81bf..a39ff2eb106b 100644 --- a/Debug/test_coverage/Inciter/Ghosts.cpp.func-sort-c.html +++ b/Debug/test_coverage/Inciter/Ghosts.cpp.func-sort-c.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:43:41 + 2024-07-11 15:06:04 Functions: 22 diff --git a/Debug/test_coverage/Inciter/Ghosts.cpp.func.html b/Debug/test_coverage/Inciter/Ghosts.cpp.func.html index ca854d85a249..82318adbaa70 100644 --- a/Debug/test_coverage/Inciter/Ghosts.cpp.func.html +++ b/Debug/test_coverage/Inciter/Ghosts.cpp.func.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:43:41 + 2024-07-11 15:06:04 Functions: 22 diff --git a/Debug/test_coverage/Inciter/Ghosts.cpp.gcov.html b/Debug/test_coverage/Inciter/Ghosts.cpp.gcov.html index d1c811e4e512..dc69aa8b980a 100644 --- a/Debug/test_coverage/Inciter/Ghosts.cpp.gcov.html +++ b/Debug/test_coverage/Inciter/Ghosts.cpp.gcov.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:43:41 + 2024-07-11 15:06:04 Functions: 22 @@ -1103,9 +1103,9 @@ 939 : : //! faces with, -1 if the face cannot be found. 940 : : // ***************************************************************************** 941 : : { - 942 [ + + ]: 845710 : for (const auto& cf : m_bndFace) + 942 [ + + ]: 846598 : for (const auto& cf : m_bndFace) 943 : : // cppcheck-suppress useStlAlgorithm - 944 [ + - ][ + + ]: 695750 : if (cf.second.find(t) != end(cf.second)) + 944 [ + - ][ + + ]: 696638 : if (cf.second.find(t) != end(cf.second)) 945 : 78356 : return cf.first; 946 : 149960 : return -1; 947 : : } diff --git a/Debug/test_coverage/Inciter/Ghosts.hpp.func-sort-c.html b/Debug/test_coverage/Inciter/Ghosts.hpp.func-sort-c.html index 269cd717b570..b1300e4727ae 100644 --- a/Debug/test_coverage/Inciter/Ghosts.hpp.func-sort-c.html +++ b/Debug/test_coverage/Inciter/Ghosts.hpp.func-sort-c.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:43:41 + 2024-07-11 15:06:04 Functions: 5 @@ -73,15 +73,15 @@ inciter::Ghosts::Ghosts(CkMigrateMessage*) - 5233 + 5151 inciter::Ghosts::OutMesh::pup(PUP::er&) - 15922 + 15697 inciter::Ghosts::pup(PUP::er&) - 16260 + 16014 inciter::Ghosts::OutMesh::destroy() diff --git a/Debug/test_coverage/Inciter/Ghosts.hpp.func.html b/Debug/test_coverage/Inciter/Ghosts.hpp.func.html index 96fdf2a5476c..dba3bb25ffcc 100644 --- a/Debug/test_coverage/Inciter/Ghosts.hpp.func.html +++ b/Debug/test_coverage/Inciter/Ghosts.hpp.func.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:43:41 + 2024-07-11 15:06:04 Functions: 5 @@ -73,11 +73,11 @@ inciter::Ghosts::pup(PUP::er&) - 16260 + 16014 inciter::Ghosts::OutMesh::pup(PUP::er&) - 15922 + 15697 inciter::Ghosts::OutMesh::destroy() @@ -85,7 +85,7 @@ inciter::Ghosts::Ghosts(CkMigrateMessage*) - 5233 + 5151 inciter::Ghosts::Disc() const diff --git a/Debug/test_coverage/Inciter/Ghosts.hpp.gcov.html b/Debug/test_coverage/Inciter/Ghosts.hpp.gcov.html index f60e2fc1b2d8..35f80fab5c95 100644 --- a/Debug/test_coverage/Inciter/Ghosts.hpp.gcov.html +++ b/Debug/test_coverage/Inciter/Ghosts.hpp.gcov.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:43:41 + 2024-07-11 15:06:04 Functions: 5 @@ -143,7 +143,7 @@ 69 : : #endif 70 : : //! Migrate constructor 71 : : // cppcheck-suppress uninitMemberVar - 72 : 5233 : explicit Ghosts( CkMigrateMessage* ) {} + 72 : 5151 : explicit Ghosts( CkMigrateMessage* ) {} 73 : : #if defined(__clang__) 74 : : #pragma clang diagnostic pop 75 : : #endif @@ -172,9 +172,9 @@ 98 : : tk::NodeCommMap nodeCommMap; 99 : : //! \brief Pack/Unpack serialize member function 100 : : //! \param[in,out] p Charm++'s PUP::er serializer object reference - 101 : 15922 : void pup( PUP::er& p ) { - 102 : 15922 : p|chunk; p|coord; p|triinpoel; p|bface; p|nodeCommMap; - 103 : 15922 : } + 101 : 15697 : void pup( PUP::er& p ) { + 102 : 15697 : p|chunk; p|coord; p|triinpoel; p|bface; p|nodeCommMap; + 103 : 15697 : } 104 : : //! Destroyer 105 : 24958 : void destroy() { 106 : 24958 : tk::destroy( std::get<0>(chunk) ); @@ -259,33 +259,33 @@ 185 : : ///@{ 186 : : //! \brief Pack/Unpack serialize member function 187 : : //! \param[in,out] p Charm++'s PUP::er serializer object reference - 188 : 16260 : void pup( PUP::er &p ) override { - 189 : 16260 : p | m_disc; - 190 : 16260 : p | m_nunk; - 191 : 16260 : p | m_inpoel; - 192 : 16260 : p | m_coord; - 193 : 16260 : p | m_fd; - 194 : 16260 : p | m_geoFace; - 195 : 16260 : p | m_geoElem; - 196 : 16260 : p | m_nfac; - 197 : 16260 : p | m_bndFace; - 198 : 16260 : p | m_sendGhost; - 199 : 16260 : p | m_ghost; - 200 : 16260 : p | m_exptGhost; - 201 : 16260 : p | m_bid; - 202 : 16260 : p | m_esup; - 203 : 16260 : p | m_initial; - 204 : 16260 : p | m_ncomfac; - 205 : 16260 : p | m_nadj; - 206 : 16260 : p | m_ncomEsup; - 207 : 16260 : p | m_ipface; - 208 : 16260 : p | m_ghostData; - 209 : 16260 : p | m_ghostReq; - 210 : 16260 : p | m_expChBndFace; - 211 : 16260 : p | m_infaces; - 212 : 16260 : p | m_esupc; - 213 : 16260 : p | m_cbAfterDone; - 214 : 16260 : } + 188 : 16014 : void pup( PUP::er &p ) override { + 189 : 16014 : p | m_disc; + 190 : 16014 : p | m_nunk; + 191 : 16014 : p | m_inpoel; + 192 : 16014 : p | m_coord; + 193 : 16014 : p | m_fd; + 194 : 16014 : p | m_geoFace; + 195 : 16014 : p | m_geoElem; + 196 : 16014 : p | m_nfac; + 197 : 16014 : p | m_bndFace; + 198 : 16014 : p | m_sendGhost; + 199 : 16014 : p | m_ghost; + 200 : 16014 : p | m_exptGhost; + 201 : 16014 : p | m_bid; + 202 : 16014 : p | m_esup; + 203 : 16014 : p | m_initial; + 204 : 16014 : p | m_ncomfac; + 205 : 16014 : p | m_nadj; + 206 : 16014 : p | m_ncomEsup; + 207 : 16014 : p | m_ipface; + 208 : 16014 : p | m_ghostData; + 209 : 16014 : p | m_ghostReq; + 210 : 16014 : p | m_expChBndFace; + 211 : 16014 : p | m_infaces; + 212 : 16014 : p | m_esupc; + 213 : 16014 : p | m_cbAfterDone; + 214 : 16014 : } 215 : : //! \brief Pack/Unpack serialize operator| 216 : : //! \param[in,out] p Charm++'s PUP::er serializer object reference 217 : : //! \param[in,out] a Ghosts object reference diff --git a/Debug/test_coverage/Inciter/NodeBC.cpp.func-sort-c.html b/Debug/test_coverage/Inciter/NodeBC.cpp.func-sort-c.html index 03cfb52c5064..ae49541b6e89 100644 --- a/Debug/test_coverage/Inciter/NodeBC.cpp.func-sort-c.html +++ b/Debug/test_coverage/Inciter/NodeBC.cpp.func-sort-c.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:43:41 + 2024-07-11 15:06:04 Functions: 3 diff --git a/Debug/test_coverage/Inciter/NodeBC.cpp.func.html b/Debug/test_coverage/Inciter/NodeBC.cpp.func.html index 1f1dd7e51da3..ad8a5eb07119 100644 --- a/Debug/test_coverage/Inciter/NodeBC.cpp.func.html +++ b/Debug/test_coverage/Inciter/NodeBC.cpp.func.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:43:41 + 2024-07-11 15:06:04 Functions: 3 diff --git a/Debug/test_coverage/Inciter/NodeBC.cpp.gcov.html b/Debug/test_coverage/Inciter/NodeBC.cpp.gcov.html index 36ee0e0ab471..1fe2341441a0 100644 --- a/Debug/test_coverage/Inciter/NodeBC.cpp.gcov.html +++ b/Debug/test_coverage/Inciter/NodeBC.cpp.gcov.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:43:41 + 2024-07-11 15:06:04 Functions: 3 diff --git a/Debug/test_coverage/Inciter/NodeDiagnostics.cpp.func-sort-c.html b/Debug/test_coverage/Inciter/NodeDiagnostics.cpp.func-sort-c.html index 4c7a2572ff09..4a2a0888506d 100644 --- a/Debug/test_coverage/Inciter/NodeDiagnostics.cpp.func-sort-c.html +++ b/Debug/test_coverage/Inciter/NodeDiagnostics.cpp.func-sort-c.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:43:41 + 2024-07-11 15:06:04 Functions: 2 diff --git a/Debug/test_coverage/Inciter/NodeDiagnostics.cpp.func.html b/Debug/test_coverage/Inciter/NodeDiagnostics.cpp.func.html index db354800b9f8..a67060e76daf 100644 --- a/Debug/test_coverage/Inciter/NodeDiagnostics.cpp.func.html +++ b/Debug/test_coverage/Inciter/NodeDiagnostics.cpp.func.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:43:41 + 2024-07-11 15:06:04 Functions: 2 diff --git a/Debug/test_coverage/Inciter/NodeDiagnostics.cpp.gcov.html b/Debug/test_coverage/Inciter/NodeDiagnostics.cpp.gcov.html index 94a2c65799d0..65e40001e100 100644 --- a/Debug/test_coverage/Inciter/NodeDiagnostics.cpp.gcov.html +++ b/Debug/test_coverage/Inciter/NodeDiagnostics.cpp.gcov.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:43:41 + 2024-07-11 15:06:04 Functions: 2 @@ -199,7 +199,7 @@ 122 : : // Compute max for Linf norm of the numerical-analytic solution 123 [ + + ]: 6368960 : for (std::size_t c=0; c<u.nprop(); ++c) { 124 [ + - ][ + - ]: 4848864 : auto err = std::abs( u(i,c) - an(i,c) ); - 125 [ + + ]: 4848864 : if (err > diag[LINFERR][c]) diag[LINFERR][c] = err; + 125 [ + + ]: 4848864 : if (err > diag[LINFERR][c]) diag[LINFERR][c] = err; 126 : : } 127 : : // Compute sum of the total energy over the entire domain (only the first 128 : : // entry is used) diff --git a/Debug/test_coverage/Inciter/NodeDiagnostics.hpp.func-sort-c.html b/Debug/test_coverage/Inciter/NodeDiagnostics.hpp.func-sort-c.html index da36f1e76aa0..eb3504904c73 100644 --- a/Debug/test_coverage/Inciter/NodeDiagnostics.hpp.func-sort-c.html +++ b/Debug/test_coverage/Inciter/NodeDiagnostics.hpp.func-sort-c.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:43:41 + 2024-07-11 15:06:04 Functions: 2 @@ -73,11 +73,11 @@ inciter::NodeDiagnostics::pup(PUP::er&) - 8139 + 8124 inciter::operator|(PUP::er&, inciter::NodeDiagnostics&) - 8139 + 8124
diff --git a/Debug/test_coverage/Inciter/NodeDiagnostics.hpp.func.html b/Debug/test_coverage/Inciter/NodeDiagnostics.hpp.func.html index 5ef78c09a4e3..5763036b8ea7 100644 --- a/Debug/test_coverage/Inciter/NodeDiagnostics.hpp.func.html +++ b/Debug/test_coverage/Inciter/NodeDiagnostics.hpp.func.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:43:41 + 2024-07-11 15:06:04 Functions: 2 @@ -73,11 +73,11 @@ inciter::NodeDiagnostics::pup(PUP::er&) - 8139 + 8124 inciter::operator|(PUP::er&, inciter::NodeDiagnostics&) - 8139 + 8124
diff --git a/Debug/test_coverage/Inciter/NodeDiagnostics.hpp.gcov.html b/Debug/test_coverage/Inciter/NodeDiagnostics.hpp.gcov.html index 8ae6b3d0f3f0..0d61c9c5c5cf 100644 --- a/Debug/test_coverage/Inciter/NodeDiagnostics.hpp.gcov.html +++ b/Debug/test_coverage/Inciter/NodeDiagnostics.hpp.gcov.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:43:41 + 2024-07-11 15:06:04 Functions: 2 @@ -115,11 +115,11 @@ 41 : : /** @name Charm++ pack/unpack serializer member functions */ 42 : : ///@{ 43 : : //! \brief Pack/Unpack serialize member function - 44 : 8139 : void pup( PUP::er & ) {} + 44 : 8124 : void pup( PUP::er & ) {} 45 : : //! \brief Pack/Unpack serialize operator| 46 : : //! \param[in,out] p Charm++'s PUP::er serializer object reference 47 : : //! \param[in,out] d Diagnostics object reference - 48 : 8139 : friend void operator|( PUP::er& p, NodeDiagnostics& d ) { d.pup(p); } + 48 : 8124 : friend void operator|( PUP::er& p, NodeDiagnostics& d ) { d.pup(p); } 49 : : //@} 50 : : }; 51 : : diff --git a/Debug/test_coverage/Inciter/OversetFE.cpp.func-sort-c.html b/Debug/test_coverage/Inciter/OversetFE.cpp.func-sort-c.html index a07cef3d16d4..db81ef8fdbf6 100644 --- a/Debug/test_coverage/Inciter/OversetFE.cpp.func-sort-c.html +++ b/Debug/test_coverage/Inciter/OversetFE.cpp.func-sort-c.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:43:41 + 2024-07-11 15:06:04 Functions: 37 diff --git a/Debug/test_coverage/Inciter/OversetFE.cpp.func.html b/Debug/test_coverage/Inciter/OversetFE.cpp.func.html index b2c66ae14adb..2423ffeb3523 100644 --- a/Debug/test_coverage/Inciter/OversetFE.cpp.func.html +++ b/Debug/test_coverage/Inciter/OversetFE.cpp.func.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:43:41 + 2024-07-11 15:06:04 Functions: 37 diff --git a/Debug/test_coverage/Inciter/OversetFE.cpp.gcov.html b/Debug/test_coverage/Inciter/OversetFE.cpp.gcov.html index 67d41609810a..462eb5ac78ef 100644 --- a/Debug/test_coverage/Inciter/OversetFE.cpp.gcov.html +++ b/Debug/test_coverage/Inciter/OversetFE.cpp.gcov.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:43:41 + 2024-07-11 15:06:04 Functions: 37 @@ -1133,7 +1133,7 @@ 1027 [ + - ]: 3396 : if (m_stage == 0) d->setdt( newdt ); 1028 : : 1029 : : // TODO: this is a hacky way to know if any chunk moved. redesign it - 1030 [ + + ]: 3396 : if (nmovedmesh < -0.1) m_movedmesh = 1; + 1030 [ + + ]: 3396 : if (nmovedmesh < -0.1) m_movedmesh = 1; 1031 : : 1032 : : // Compute gradients for next time step 1033 : 3396 : chBndGrad(); diff --git a/Debug/test_coverage/Inciter/OversetFE.hpp.func-sort-c.html b/Debug/test_coverage/Inciter/OversetFE.hpp.func-sort-c.html index 7e283103065a..3f59ed926cf5 100644 --- a/Debug/test_coverage/Inciter/OversetFE.hpp.func-sort-c.html +++ b/Debug/test_coverage/Inciter/OversetFE.hpp.func-sort-c.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:43:41 + 2024-07-11 15:06:04 Functions: 3 @@ -97,11 +97,11 @@ inciter::OversetFE::OversetFE(CkMigrateMessage*) - 980 + 986 inciter::OversetFE::pup(PUP::er&) - 2955 + 2973 inciter::OversetFE::Disc() const diff --git a/Debug/test_coverage/Inciter/OversetFE.hpp.func.html b/Debug/test_coverage/Inciter/OversetFE.hpp.func.html index d1671acd9351..c3c1ad63328f 100644 --- a/Debug/test_coverage/Inciter/OversetFE.hpp.func.html +++ b/Debug/test_coverage/Inciter/OversetFE.hpp.func.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:43:41 + 2024-07-11 15:06:04 Functions: 3 @@ -89,7 +89,7 @@ inciter::OversetFE::pup(PUP::er&) - 2955 + 2973 inciter::OversetFE::resized() @@ -97,7 +97,7 @@ inciter::OversetFE::OversetFE(CkMigrateMessage*) - 980 + 986 inciter::OversetFE::Disc() const diff --git a/Debug/test_coverage/Inciter/OversetFE.hpp.gcov.html b/Debug/test_coverage/Inciter/OversetFE.hpp.gcov.html index b00302eca041..4a0c2d03808c 100644 --- a/Debug/test_coverage/Inciter/OversetFE.hpp.gcov.html +++ b/Debug/test_coverage/Inciter/OversetFE.hpp.gcov.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:43:41 + 2024-07-11 15:06:04 Functions: 3 @@ -151,7 +151,7 @@ 77 : : #endif 78 : : //! Migrate constructor 79 : : // cppcheck-suppress uninitMemberVar - 80 : 980 : explicit OversetFE( CkMigrateMessage* msg ) : CBase_OversetFE( msg ) {} + 80 : 986 : explicit OversetFE( CkMigrateMessage* msg ) : CBase_OversetFE( msg ) {} 81 : : #if defined(__clang__) 82 : : #pragma clang diagnostic pop 83 : : #endif @@ -265,54 +265,54 @@ 191 : : ///@{ 192 : : //! \brief Pack/Unpack serialize member function 193 : : //! \param[in,out] p Charm++'s PUP::er serializer object reference - 194 : 2955 : void pup( PUP::er &p ) override { - 195 : 2955 : p | m_disc; - 196 : 2955 : p | m_nsol; - 197 : 2955 : p | m_ngrad; - 198 : 2955 : p | m_nrhs; - 199 : 2955 : p | m_nbnorm; - 200 : 2955 : p | m_ndfnorm; - 201 : 2955 : p | m_nmblk; - 202 : 2955 : p | m_bnode; - 203 : 2955 : p | m_bface; - 204 : 2955 : p | m_triinpoel; - 205 : 2955 : p | m_bndel; - 206 : 2955 : p | m_dfnorm; - 207 : 2955 : p | m_dfnormc; - 208 : 2955 : p | m_dfn; - 209 : 2955 : p | m_esup; - 210 : 2955 : p | m_psup; - 211 : 2955 : p | m_u; - 212 : 2955 : p | m_uc; - 213 : 2955 : p | m_un; - 214 : 2955 : p | m_rhs; - 215 : 2955 : p | m_rhsc; - 216 : 2955 : p | m_chBndGrad; - 217 : 2955 : p | m_dirbc; - 218 : 2955 : p | m_chBndGradc; - 219 : 2955 : p | m_blank; - 220 : 2955 : p | m_diag; - 221 : 2955 : p | m_bnorm; - 222 : 2955 : p | m_bnormc; - 223 : 2955 : p | m_symbcnodes; - 224 : 2955 : p | m_farfieldbcnodes; - 225 : 2955 : p | m_symbctri; - 226 : 2955 : p | m_timedepbcnodes; - 227 : 2955 : p | m_timedepbcFn; - 228 : 2955 : p | m_stage; - 229 : 2955 : p | m_boxnodes; - 230 : 2955 : p | m_edgenode; - 231 : 2955 : p | m_edgeid; - 232 : 2955 : p | m_dtp; - 233 : 2955 : p | m_tp; - 234 : 2955 : p | m_finished; - 235 : 2955 : p | m_movedmesh; - 236 : 2955 : p | m_nusermeshblk; - 237 : 2955 : p | m_nodeblockid; - 238 : 2955 : p | m_nodeblockidc; - 239 : 2955 : p | m_ixfer; - 240 : 2955 : p | m_uservel; - 241 : 2955 : } + 194 : 2973 : void pup( PUP::er &p ) override { + 195 : 2973 : p | m_disc; + 196 : 2973 : p | m_nsol; + 197 : 2973 : p | m_ngrad; + 198 : 2973 : p | m_nrhs; + 199 : 2973 : p | m_nbnorm; + 200 : 2973 : p | m_ndfnorm; + 201 : 2973 : p | m_nmblk; + 202 : 2973 : p | m_bnode; + 203 : 2973 : p | m_bface; + 204 : 2973 : p | m_triinpoel; + 205 : 2973 : p | m_bndel; + 206 : 2973 : p | m_dfnorm; + 207 : 2973 : p | m_dfnormc; + 208 : 2973 : p | m_dfn; + 209 : 2973 : p | m_esup; + 210 : 2973 : p | m_psup; + 211 : 2973 : p | m_u; + 212 : 2973 : p | m_uc; + 213 : 2973 : p | m_un; + 214 : 2973 : p | m_rhs; + 215 : 2973 : p | m_rhsc; + 216 : 2973 : p | m_chBndGrad; + 217 : 2973 : p | m_dirbc; + 218 : 2973 : p | m_chBndGradc; + 219 : 2973 : p | m_blank; + 220 : 2973 : p | m_diag; + 221 : 2973 : p | m_bnorm; + 222 : 2973 : p | m_bnormc; + 223 : 2973 : p | m_symbcnodes; + 224 : 2973 : p | m_farfieldbcnodes; + 225 : 2973 : p | m_symbctri; + 226 : 2973 : p | m_timedepbcnodes; + 227 : 2973 : p | m_timedepbcFn; + 228 : 2973 : p | m_stage; + 229 : 2973 : p | m_boxnodes; + 230 : 2973 : p | m_edgenode; + 231 : 2973 : p | m_edgeid; + 232 : 2973 : p | m_dtp; + 233 : 2973 : p | m_tp; + 234 : 2973 : p | m_finished; + 235 : 2973 : p | m_movedmesh; + 236 : 2973 : p | m_nusermeshblk; + 237 : 2973 : p | m_nodeblockid; + 238 : 2973 : p | m_nodeblockidc; + 239 : 2973 : p | m_ixfer; + 240 : 2973 : p | m_uservel; + 241 : 2973 : } 242 : : //! \brief Pack/Unpack serialize operator| 243 : : //! \param[in,out] p Charm++'s PUP::er serializer object reference 244 : : //! \param[in,out] i OversetFE object reference diff --git a/Debug/test_coverage/Inciter/PUPAMR.cpp.func-sort-c.html b/Debug/test_coverage/Inciter/PUPAMR.cpp.func-sort-c.html index 50b892e64c08..d1e16d1ae6ce 100644 --- a/Debug/test_coverage/Inciter/PUPAMR.cpp.func-sort-c.html +++ b/Debug/test_coverage/Inciter/PUPAMR.cpp.func-sort-c.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:43:41 + 2024-07-11 15:06:04 Functions: 9 @@ -81,39 +81,39 @@ PUP::pup(PUP::er&, AMR::tet_store_t&) - 24399 + 24138 PUP::pup(PUP::er&, AMR::edge_store_t&) - 24399 + 24138 PUP::pup(PUP::er&, AMR::refinement_t&) - 24399 + 24138 PUP::pup(PUP::er&, AMR::id_generator_t&) - 24399 + 24138 PUP::pup(PUP::er&, AMR::mesh_adapter_t&) - 24399 + 24138 PUP::pup(PUP::er&, AMR::node_connectivity_t&) - 24399 + 24138 PUP::pup(PUP::er&, AMR::Refinement_State&) - 3577663 + 3501577 PUP::pup(PUP::er&, AMR::Edge_Refinement&) - 6181777 + 6058714 PUP::pup(PUP::er&, AMR::edge_t&) - 6181777 + 6058714
diff --git a/Debug/test_coverage/Inciter/PUPAMR.cpp.func.html b/Debug/test_coverage/Inciter/PUPAMR.cpp.func.html index 9517260ec191..6a499a708c5c 100644 --- a/Debug/test_coverage/Inciter/PUPAMR.cpp.func.html +++ b/Debug/test_coverage/Inciter/PUPAMR.cpp.func.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:43:41 + 2024-07-11 15:06:04 Functions: 9 @@ -73,35 +73,35 @@ PUP::pup(PUP::er&, AMR::tet_store_t&) - 24399 + 24138 PUP::pup(PUP::er&, AMR::edge_store_t&) - 24399 + 24138 PUP::pup(PUP::er&, AMR::refinement_t&) - 24399 + 24138 PUP::pup(PUP::er&, AMR::id_generator_t&) - 24399 + 24138 PUP::pup(PUP::er&, AMR::mesh_adapter_t&) - 24399 + 24138 PUP::pup(PUP::er&, AMR::Edge_Refinement&) - 6181777 + 6058714 PUP::pup(PUP::er&, AMR::Refinement_State&) - 3577663 + 3501577 PUP::pup(PUP::er&, AMR::node_connectivity_t&) - 24399 + 24138 PUP::pup(PUP::er&, AMR::active_element_store_t&) @@ -113,7 +113,7 @@ PUP::pup(PUP::er&, AMR::edge_t&) - 6181777 + 6058714
diff --git a/Debug/test_coverage/Inciter/PUPAMR.cpp.gcov.html b/Debug/test_coverage/Inciter/PUPAMR.cpp.gcov.html index bf181f3c8b90..e0afa548a874 100644 --- a/Debug/test_coverage/Inciter/PUPAMR.cpp.gcov.html +++ b/Debug/test_coverage/Inciter/PUPAMR.cpp.gcov.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:43:41 + 2024-07-11 15:06:04 Functions: 9 @@ -87,55 +87,55 @@ 13 : : 14 : : #include "PUPAMR.hpp" 15 : : - 16 : 3577663 : void PUP::pup( PUP::er &p, AMR::Refinement_State& s ) + 16 : 3501577 : void PUP::pup( PUP::er &p, AMR::Refinement_State& s ) 17 : : // ***************************************************************************** 18 : : // Pack/Unpack Refinement_State 19 : : //! \param[in] p Charm++'s pack/unpack object 20 : : //! \param[in,out] s Refinement_State object reference 21 : : // ***************************************************************************** 22 : : { - 23 : 3577663 : p | s.active_element_number; - 24 : 3577663 : p | s.refinement_case; - 25 : 3577663 : p | s.children; - 26 : 3577663 : p | s.refinement_level; - 27 : 3577663 : p | s.child_number; - 28 : 3577663 : p | s.parent_id; - 29 : 3577663 : p | s.normal; - 30 : 3577663 : } + 23 : 3501577 : p | s.active_element_number; + 24 : 3501577 : p | s.refinement_case; + 25 : 3501577 : p | s.children; + 26 : 3501577 : p | s.refinement_level; + 27 : 3501577 : p | s.child_number; + 28 : 3501577 : p | s.parent_id; + 29 : 3501577 : p | s.normal; + 30 : 3501577 : } 31 : : - 32 : 6181777 : void PUP::pup( PUP::er &p, AMR::Edge_Refinement& e ) + 32 : 6058714 : void PUP::pup( PUP::er &p, AMR::Edge_Refinement& e ) 33 : : // ***************************************************************************** 34 : : // Pack/Unpack Edge_Refinement 35 : : //! \param[in] p Charm++'s pack/unpack object 36 : : //! \param[in,out] e Edge_Refinement object reference 37 : : // ***************************************************************************** 38 : : { - 39 : 6181777 : p | e.A; - 40 : 6181777 : p | e.B; - 41 : 6181777 : p | e.needs_refining; - 42 : 6181777 : p | e.needs_derefining; - 43 : 6181777 : p | e.lock_case; - 44 : 6181777 : } + 39 : 6058714 : p | e.A; + 40 : 6058714 : p | e.B; + 41 : 6058714 : p | e.needs_refining; + 42 : 6058714 : p | e.needs_derefining; + 43 : 6058714 : p | e.lock_case; + 44 : 6058714 : } 45 : : - 46 : 24399 : void PUP::pup( PUP::er &p, AMR::edge_store_t& e ) + 46 : 24138 : void PUP::pup( PUP::er &p, AMR::edge_store_t& e ) 47 : : // ***************************************************************************** 48 : : // Pack/Unpack edge_store_t 49 : : //! \param[in] p Charm++'s pack/unpack object 50 : : //! \param[in,out] e edge_store_t object reference 51 : : // ***************************************************************************** 52 : : { - 53 : 24399 : p | e.edges; - 54 : 24399 : } + 53 : 24138 : p | e.edges; + 54 : 24138 : } 55 : : - 56 : 6181777 : void PUP::pup( PUP::er &p, AMR::edge_t& e ) + 56 : 6058714 : void PUP::pup( PUP::er &p, AMR::edge_t& e ) 57 : : // ***************************************************************************** 58 : : // Pack/Unpack edge_t 59 : : //! \param[in] p Charm++'s pack/unpack object 60 : : //! \param[in,out] e edge_t object reference 61 : : // ***************************************************************************** 62 : : { - 63 : 6181777 : p | e.get_data(); - 64 : 6181777 : } + 63 : 6058714 : p | e.get_data(); + 64 : 6058714 : } 65 : : 66 : 0 : void PUP::pup( PUP::er &p, AMR::active_element_store_t& a ) 67 : : // ***************************************************************************** @@ -157,55 +157,55 @@ 83 : 0 : p | m.data(); 84 : 0 : } 85 : : - 86 : 24399 : void PUP::pup( PUP::er &p, AMR::id_generator_t& i ) + 86 : 24138 : void PUP::pup( PUP::er &p, AMR::id_generator_t& i ) 87 : : // ***************************************************************************** 88 : : // Pack/Unpack id_generator_t 89 : : //! \param[in] p Charm++'s pack/unpack object 90 : : //! \param[in,out] i id_generator_t object reference 91 : : // ***************************************************************************** 92 : : { - 93 : 24399 : p | i.start_id; - 94 : 24399 : p | i.next_tet_id; - 95 : 24399 : } + 93 : 24138 : p | i.start_id; + 94 : 24138 : p | i.next_tet_id; + 95 : 24138 : } 96 : : - 97 : 24399 : void PUP::pup( PUP::er &p, AMR::tet_store_t& t ) + 97 : 24138 : void PUP::pup( PUP::er &p, AMR::tet_store_t& t ) 98 : : // ***************************************************************************** 99 : : // Pack/Unpack tet_store_t 100 : : //! \param[in] p Charm++'s pack/unpack object 101 : : //! \param[in,out] t tet_store_t object reference 102 : : // ***************************************************************************** 103 : : { - 104 : 24399 : p | t.center_tets; - 105 : 24399 : p | t.delete_list; - 106 : 24399 : p | t.active_elements.data(); - 107 : 24399 : p | t.master_elements.data(); - 108 : 24399 : p | t.active_tetinpoel; - 109 : 24399 : p | t.active_nodes; - 110 : 24399 : p | t.id_generator; - 111 : 24399 : p | t.intermediate_list; - 112 : 24399 : p | t.active_id_mapping; - 113 : 24399 : p | t.tets; - 114 : 24399 : p | t.edge_store; - 115 : 24399 : p | t.marked_refinements; - 116 : 24399 : p | t.marked_derefinements; - 117 : 24399 : } + 104 : 24138 : p | t.center_tets; + 105 : 24138 : p | t.delete_list; + 106 : 24138 : p | t.active_elements.data(); + 107 : 24138 : p | t.master_elements.data(); + 108 : 24138 : p | t.active_tetinpoel; + 109 : 24138 : p | t.active_nodes; + 110 : 24138 : p | t.id_generator; + 111 : 24138 : p | t.intermediate_list; + 112 : 24138 : p | t.active_id_mapping; + 113 : 24138 : p | t.tets; + 114 : 24138 : p | t.edge_store; + 115 : 24138 : p | t.marked_refinements; + 116 : 24138 : p | t.marked_derefinements; + 117 : 24138 : } 118 : : - 119 : 24399 : void PUP::pup( PUP::er &p, AMR::mesh_adapter_t& m ) + 119 : 24138 : void PUP::pup( PUP::er &p, AMR::mesh_adapter_t& m ) 120 : : // ***************************************************************************** 121 : : // Pack/Unpack mesh_adapter_t 122 : : //! \param[in] p Charm++'s pack/unpack object 123 : : //! \param[in,out] m mesh_adapter_t object reference 124 : : // ***************************************************************************** 125 : : { - 126 : 24399 : p | m.derefinement_cut_off; - 127 : 24399 : p | m.refinement_cut_off; - 128 : 24399 : p | m.tet_store; - 129 : 24399 : p | m.node_connectivity; + 126 : 24138 : p | m.derefinement_cut_off; + 127 : 24138 : p | m.refinement_cut_off; + 128 : 24138 : p | m.tet_store; + 129 : 24138 : p | m.node_connectivity; 130 : : #ifdef ENABLE_NODE_STORE 131 : : p | m.node_store; 132 : : #endif - 133 : 24399 : p | m.refiner; - 134 : 24399 : } + 133 : 24138 : p | m.refiner; + 134 : 24138 : } 135 : : 136 : : #ifdef ENABLE_NODE_STORE 137 : : void PUP::pup( PUP::er &p, AMR::node_store_t& n ) @@ -222,27 +222,27 @@ 148 : : #endif 149 : : 150 : : - 151 : 24399 : void PUP::pup( PUP::er &p, AMR::node_connectivity_t& n ) + 151 : 24138 : void PUP::pup( PUP::er &p, AMR::node_connectivity_t& n ) 152 : : // ***************************************************************************** 153 : : // Pack/Unpack node_connectivity_t 154 : : //! \param[in] p Charm++'s pack/unpack object 155 : : //! \param[in,out] n node_connectivity_t object reference 156 : : // ***************************************************************************** 157 : : { - 158 : 24399 : p | n.data(); - 159 : 24399 : p | n.inv_data(); - 160 : 24399 : p | n.empty_node_count; - 161 : 24399 : } + 158 : 24138 : p | n.data(); + 159 : 24138 : p | n.inv_data(); + 160 : 24138 : p | n.empty_node_count; + 161 : 24138 : } 162 : : - 163 : 24399 : void PUP::pup( PUP::er &p, AMR::refinement_t& r ) + 163 : 24138 : void PUP::pup( PUP::er &p, AMR::refinement_t& r ) 164 : : // ***************************************************************************** 165 : : // Pack/Unpack refinement_t 166 : : //! \param[in] p Charm++'s pack/unpack object 167 : : //! \param[in,out] r refinement_t object reference 168 : : // ***************************************************************************** 169 : : { - 170 : 24399 : p | r.MAX_REFINEMENT_LEVEL; - 171 : 24399 : } + 170 : 24138 : p | r.MAX_REFINEMENT_LEVEL; + 171 : 24138 : } diff --git a/Debug/test_coverage/Inciter/PUPAMR.hpp.func-sort-c.html b/Debug/test_coverage/Inciter/PUPAMR.hpp.func-sort-c.html index 06586607382e..15dd4cc1bd8a 100644 --- a/Debug/test_coverage/Inciter/PUPAMR.hpp.func-sort-c.html +++ b/Debug/test_coverage/Inciter/PUPAMR.hpp.func-sort-c.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:43:41 + 2024-07-11 15:06:04 Functions: 13 @@ -73,55 +73,55 @@ void PUP::pup<AMR::Refinement_Case>(PUP::er&, AMR::marked_refinements_store_t<AMR::Refinement_Case>&) - 24399 + 24138 void PUP::pup<AMR::Derefinement_Case>(PUP::er&, AMR::marked_refinements_store_t<AMR::Derefinement_Case>&) - 24399 + 24138 PUP::operator|(PUP::er&, AMR::tet_store_t&) - 24399 + 24138 PUP::operator|(PUP::er&, AMR::edge_store_t&) - 24399 + 24138 PUP::operator|(PUP::er&, AMR::refinement_t&) - 24399 + 24138 PUP::operator|(PUP::er&, AMR::id_generator_t&) - 24399 + 24138 PUP::operator|(PUP::er&, AMR::mesh_adapter_t&) - 24399 + 24138 PUP::operator|(PUP::er&, AMR::node_connectivity_t&) - 24399 + 24138 void PUP::operator|<AMR::Refinement_Case>(PUP::er&, AMR::marked_refinements_store_t<AMR::Refinement_Case>&) - 24399 + 24138 void PUP::operator|<AMR::Derefinement_Case>(PUP::er&, AMR::marked_refinements_store_t<AMR::Derefinement_Case>&) - 24399 + 24138 PUP::operator|(PUP::er&, AMR::Refinement_State&) - 3577663 + 3501577 PUP::operator|(PUP::er&, AMR::Edge_Refinement&) - 6181777 + 6058714 PUP::operator|(PUP::er&, AMR::edge_t&) - 6181777 + 6058714
diff --git a/Debug/test_coverage/Inciter/PUPAMR.hpp.func.html b/Debug/test_coverage/Inciter/PUPAMR.hpp.func.html index a467e0e0959b..93efd04f24ed 100644 --- a/Debug/test_coverage/Inciter/PUPAMR.hpp.func.html +++ b/Debug/test_coverage/Inciter/PUPAMR.hpp.func.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:43:41 + 2024-07-11 15:06:04 Functions: 13 @@ -73,55 +73,55 @@ void PUP::pup<AMR::Refinement_Case>(PUP::er&, AMR::marked_refinements_store_t<AMR::Refinement_Case>&) - 24399 + 24138 void PUP::pup<AMR::Derefinement_Case>(PUP::er&, AMR::marked_refinements_store_t<AMR::Derefinement_Case>&) - 24399 + 24138 PUP::operator|(PUP::er&, AMR::tet_store_t&) - 24399 + 24138 PUP::operator|(PUP::er&, AMR::edge_store_t&) - 24399 + 24138 PUP::operator|(PUP::er&, AMR::refinement_t&) - 24399 + 24138 PUP::operator|(PUP::er&, AMR::id_generator_t&) - 24399 + 24138 PUP::operator|(PUP::er&, AMR::mesh_adapter_t&) - 24399 + 24138 PUP::operator|(PUP::er&, AMR::Edge_Refinement&) - 6181777 + 6058714 PUP::operator|(PUP::er&, AMR::Refinement_State&) - 3577663 + 3501577 PUP::operator|(PUP::er&, AMR::node_connectivity_t&) - 24399 + 24138 PUP::operator|(PUP::er&, AMR::edge_t&) - 6181777 + 6058714 void PUP::operator|<AMR::Refinement_Case>(PUP::er&, AMR::marked_refinements_store_t<AMR::Refinement_Case>&) - 24399 + 24138 void PUP::operator|<AMR::Derefinement_Case>(PUP::er&, AMR::marked_refinements_store_t<AMR::Derefinement_Case>&) - 24399 + 24138
diff --git a/Debug/test_coverage/Inciter/PUPAMR.hpp.gcov.html b/Debug/test_coverage/Inciter/PUPAMR.hpp.gcov.html index 1d220a4b0127..fcedfe5c7dea 100644 --- a/Debug/test_coverage/Inciter/PUPAMR.hpp.gcov.html +++ b/Debug/test_coverage/Inciter/PUPAMR.hpp.gcov.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:43:41 + 2024-07-11 15:06:04 Functions: 13 @@ -110,7 +110,7 @@ 36 : : //! Pack/Unpack serialize operator| 37 : : //! \param[in,out] p Charm++'s PUP::er serializer object reference 38 : : //! \param[in,out] s Refinement_State object reference - 39 : 3577663 : inline void operator|( PUP::er& p, AMR::Refinement_State& s ) { pup(p,s); } + 39 : 3501577 : inline void operator|( PUP::er& p, AMR::Refinement_State& s ) { pup(p,s); } 40 : : //@} 41 : : 42 : : /** @name Charm++ pack/unpack serializer member functions for Edge_Refinement */ @@ -120,7 +120,7 @@ 46 : : //! Pack/Unpack serialize operator| 47 : : //! \param[in,out] p Charm++'s PUP::er serializer object reference 48 : : //! \param[in,out] e Edge_Refinement object reference - 49 : 6181777 : inline void operator|( PUP::er& p, AMR::Edge_Refinement& e ) { pup(p,e); } + 49 : 6058714 : inline void operator|( PUP::er& p, AMR::Edge_Refinement& e ) { pup(p,e); } 50 : : //@} 51 : : 52 : : /** @name Charm++ pack/unpack serializer member functions for edge_store_t */ @@ -130,7 +130,7 @@ 56 : : //! Pack/Unpack serialize operator| 57 : : //! \param[in,out] p Charm++'s PUP::er serializer object reference 58 : : //! \param[in,out] e edge_store_t object reference - 59 : 24399 : inline void operator|( PUP::er& p, AMR::edge_store_t& e ) { pup(p,e); } + 59 : 24138 : inline void operator|( PUP::er& p, AMR::edge_store_t& e ) { pup(p,e); } 60 : : //@} 61 : : 62 : : /** @name Charm++ pack/unpack serializer member functions for edge_t */ @@ -140,7 +140,7 @@ 66 : : //! Pack/Unpack serialize operator| 67 : : //! \param[in,out] p Charm++'s PUP::er serializer object reference 68 : : //! \param[in,out] e edge_t object reference - 69 : 6181777 : inline void operator|( PUP::er& p, AMR::edge_t& e ) { pup(p,e); } + 69 : 6058714 : inline void operator|( PUP::er& p, AMR::edge_t& e ) { pup(p,e); } 70 : : //@} 71 : : 72 : : /** @name Charm++ pack/unpack serializer member functions for marked_refinements_store_t */ @@ -149,16 +149,16 @@ 75 : : //! \param[in] p Charm++'s pack/unpack object 76 : : //! \param[in,out] m marked_refinements_store_t object reference 77 : : template< class case_t > - 78 : 48798 : void pup( PUP::er &p, AMR::marked_refinements_store_t< case_t >& m ) { - 79 : 48798 : p | m.data(); - 80 : 48798 : p | m.get_state_changed(); - 81 : 48798 : } + 78 : 48276 : void pup( PUP::er &p, AMR::marked_refinements_store_t< case_t >& m ) { + 79 : 48276 : p | m.data(); + 80 : 48276 : p | m.get_state_changed(); + 81 : 48276 : } 82 : : //! Pack/Unpack serialize operator| 83 : : //! \param[in,out] p Charm++'s PUP::er serializer object reference 84 : : //! \param[in,out] m marked_refinements_store_t object reference 85 : : template< class case_t > - 86 : 48798 : inline void operator|( PUP::er& p, AMR::marked_refinements_store_t<case_t>& m ) - 87 : 48798 : { pup(p,m); } + 86 : 48276 : inline void operator|( PUP::er& p, AMR::marked_refinements_store_t<case_t>& m ) + 87 : 48276 : { pup(p,m); } 88 : : //@} 89 : : 90 : : /** @name Charm++ pack/unpack serializer member functions for active_element_store_t */ @@ -190,8 +190,8 @@ 116 : : //! Pack/Unpack serialize operator| 117 : : //! \param[in,out] p Charm++'s PUP::er serializer object reference 118 : : //! \param[in,out] i id_generator_t object reference - 119 : 24399 : inline void operator|( PUP::er& p, AMR::id_generator_t& i ) - 120 : 24399 : { pup(p,i); } + 119 : 24138 : inline void operator|( PUP::er& p, AMR::id_generator_t& i ) + 120 : 24138 : { pup(p,i); } 121 : : //@} 122 : : 123 : : /** @name Charm++ pack/unpack serializer member functions for tet_store_t */ @@ -201,7 +201,7 @@ 127 : : //! Pack/Unpack serialize operator| 128 : : //! \param[in,out] p Charm++'s PUP::er serializer object reference 129 : : //! \param[in,out] t tet_store_t object reference - 130 : 24399 : inline void operator|( PUP::er& p, AMR::tet_store_t& t ) { pup(p,t); } + 130 : 24138 : inline void operator|( PUP::er& p, AMR::tet_store_t& t ) { pup(p,t); } 131 : : //@} 132 : : 133 : : /** @name Charm++ pack/unpack serializer member functions for mesh_adapter_t */ @@ -211,7 +211,7 @@ 137 : : //! Pack/Unpack serialize operator| 138 : : //! \param[in,out] p Charm++'s PUP::er serializer object reference 139 : : //! \param[in,out] m mesh_adapter_t object reference - 140 : 24399 : inline void operator|( PUP::er& p, AMR::mesh_adapter_t& m ) { pup(p,m); } + 140 : 24138 : inline void operator|( PUP::er& p, AMR::mesh_adapter_t& m ) { pup(p,m); } 141 : : //@} 142 : : 143 : : /** @name Charm++ pack/unpack serializer member functions for node_store_t */ @@ -231,7 +231,7 @@ 157 : : //! Pack/Unpack serialize operator| 158 : : //! \param[in,out] p Charm++'s PUP::er serializer object reference 159 : : //! \param[in,out] n node_connectivity_t object reference - 160 : 24399 : inline void operator|( PUP::er& p, AMR::node_connectivity_t& n ) { pup(p,n); } + 160 : 24138 : inline void operator|( PUP::er& p, AMR::node_connectivity_t& n ) { pup(p,n); } 161 : : //@} 162 : : 163 : : /** @name Charm++ pack/unpack serializer member functions for refinement_t */ @@ -241,7 +241,7 @@ 167 : : //! Pack/Unpack serialize operator| 168 : : //! \param[in,out] p Charm++'s PUP::er serializer object reference 169 : : //! \param[in,out] r refinement_t object reference - 170 : 24399 : inline void operator|( PUP::er& p, AMR::refinement_t& r ) { pup(p,r); } + 170 : 24138 : inline void operator|( PUP::er& p, AMR::refinement_t& r ) { pup(p,r); } 171 : : //@} 172 : : 173 : : } // PUP:: diff --git a/Debug/test_coverage/Inciter/Partitioner.cpp.func-sort-c.html b/Debug/test_coverage/Inciter/Partitioner.cpp.func-sort-c.html index 1bfbbaf1f293..06d3e6832f19 100644 --- a/Debug/test_coverage/Inciter/Partitioner.cpp.func-sort-c.html +++ b/Debug/test_coverage/Inciter/Partitioner.cpp.func-sort-c.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:43:41 + 2024-07-11 15:06:04 Functions: 12 diff --git a/Debug/test_coverage/Inciter/Partitioner.cpp.func.html b/Debug/test_coverage/Inciter/Partitioner.cpp.func.html index 9a26de37ff0b..950ec3445e98 100644 --- a/Debug/test_coverage/Inciter/Partitioner.cpp.func.html +++ b/Debug/test_coverage/Inciter/Partitioner.cpp.func.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:43:41 + 2024-07-11 15:06:04 Functions: 12 diff --git a/Debug/test_coverage/Inciter/Partitioner.cpp.gcov.html b/Debug/test_coverage/Inciter/Partitioner.cpp.gcov.html index 74525ee651dc..afecceea66d4 100644 --- a/Debug/test_coverage/Inciter/Partitioner.cpp.gcov.html +++ b/Debug/test_coverage/Inciter/Partitioner.cpp.gcov.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:43:41 + 2024-07-11 15:06:04 Functions: 12 diff --git a/Debug/test_coverage/Inciter/Partitioner.hpp.func-sort-c.html b/Debug/test_coverage/Inciter/Partitioner.hpp.func-sort-c.html index 4b5369871841..8fd615385974 100644 --- a/Debug/test_coverage/Inciter/Partitioner.hpp.func-sort-c.html +++ b/Debug/test_coverage/Inciter/Partitioner.hpp.func-sort-c.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:43:41 + 2024-07-11 15:06:04 Functions: 2 diff --git a/Debug/test_coverage/Inciter/Partitioner.hpp.func.html b/Debug/test_coverage/Inciter/Partitioner.hpp.func.html index 3b5a803b63ac..1c53729cdca2 100644 --- a/Debug/test_coverage/Inciter/Partitioner.hpp.func.html +++ b/Debug/test_coverage/Inciter/Partitioner.hpp.func.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:43:41 + 2024-07-11 15:06:04 Functions: 2 diff --git a/Debug/test_coverage/Inciter/Partitioner.hpp.gcov.html b/Debug/test_coverage/Inciter/Partitioner.hpp.gcov.html index 889555f29842..8315b633f226 100644 --- a/Debug/test_coverage/Inciter/Partitioner.hpp.gcov.html +++ b/Debug/test_coverage/Inciter/Partitioner.hpp.gcov.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:43:41 + 2024-07-11 15:06:04 Functions: 2 diff --git a/Debug/test_coverage/Inciter/Refiner.cpp.func-sort-c.html b/Debug/test_coverage/Inciter/Refiner.cpp.func-sort-c.html index e324191bed89..654a661b72df 100644 --- a/Debug/test_coverage/Inciter/Refiner.cpp.func-sort-c.html +++ b/Debug/test_coverage/Inciter/Refiner.cpp.func-sort-c.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:43:41 + 2024-07-11 15:06:04 Functions: 42 diff --git a/Debug/test_coverage/Inciter/Refiner.cpp.func.html b/Debug/test_coverage/Inciter/Refiner.cpp.func.html index 119263ed6c68..0bf68a9772b0 100644 --- a/Debug/test_coverage/Inciter/Refiner.cpp.func.html +++ b/Debug/test_coverage/Inciter/Refiner.cpp.func.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:43:41 + 2024-07-11 15:06:04 Functions: 42 diff --git a/Debug/test_coverage/Inciter/Refiner.cpp.gcov.html b/Debug/test_coverage/Inciter/Refiner.cpp.gcov.html index 3cfaa497b992..b356816d63b8 100644 --- a/Debug/test_coverage/Inciter/Refiner.cpp.gcov.html +++ b/Debug/test_coverage/Inciter/Refiner.cpp.gcov.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:43:41 + 2024-07-11 15:06:04 Functions: 42 @@ -1774,8 +1774,8 @@ 1631 [ + - ]: 72 : auto& nodes = tk::ref_find( m_nodeCommMap, neighborchare ); 1632 [ + + ]: 24192 : for (const auto& e : edges) { 1633 : : // If parent nodes were part of the node communication map for chare - 1634 [ + - ][ + + ]: 24120 : if (nodes.find(e[0]) != end(nodes) && nodes.find(e[1]) != end(nodes)) { - [ + - ][ + + ] + 1634 [ + - ][ + + ]: 24120 : if (nodes.find(e[0]) != end(nodes) && nodes.find(e[1]) != end(nodes)) { + [ + - ][ + + ] [ + + ] 1635 : : // Add new node if local id was generated for it 1636 [ + - ]: 2418 : auto n = Hash<2>()( e ); diff --git a/Debug/test_coverage/Inciter/Refiner.hpp.func-sort-c.html b/Debug/test_coverage/Inciter/Refiner.hpp.func-sort-c.html index 835654085b0d..ef2376052e6c 100644 --- a/Debug/test_coverage/Inciter/Refiner.hpp.func-sort-c.html +++ b/Debug/test_coverage/Inciter/Refiner.hpp.func-sort-c.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:43:41 + 2024-07-11 15:06:04 Functions: 3 @@ -73,11 +73,11 @@ inciter::Refiner::Refiner(CkMigrateMessage*) - 7861 + 7774 inciter::Refiner::pup(PUP::er&) - 24399 + 24138 std::unordered_set<int, std::hash<int>, std::equal_to<int>, std::allocator<int> > inciter::Refiner::keys<std::unordered_map<int, std::unordered_set<unsigned long, std::hash<unsigned long>, std::equal_to<unsigned long>, std::allocator<unsigned long> >, std::hash<int>, std::equal_to<int>, std::allocator<std::pair<int const, std::unordered_set<unsigned long, std::hash<unsigned long>, std::equal_to<unsigned long>, std::allocator<unsigned long> > > > >, unsigned long>(std::unordered_map<int, std::unordered_set<unsigned long, std::hash<unsigned long>, std::equal_to<unsigned long>, std::allocator<unsigned long> >, std::hash<int>, std::equal_to<int>, std::allocator<std::pair<int const, std::unordered_set<unsigned long, std::hash<unsigned long>, std::equal_to<unsigned long>, std::allocator<unsigned long> > > > > const&, unsigned long const&) diff --git a/Debug/test_coverage/Inciter/Refiner.hpp.func.html b/Debug/test_coverage/Inciter/Refiner.hpp.func.html index 668d07905269..a73303c5233a 100644 --- a/Debug/test_coverage/Inciter/Refiner.hpp.func.html +++ b/Debug/test_coverage/Inciter/Refiner.hpp.func.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:43:41 + 2024-07-11 15:06:04 Functions: 3 @@ -73,7 +73,7 @@ inciter::Refiner::pup(PUP::er&) - 24399 + 24138 std::unordered_set<int, std::hash<int>, std::equal_to<int>, std::allocator<int> > inciter::Refiner::keys<std::unordered_map<int, std::unordered_set<unsigned long, std::hash<unsigned long>, std::equal_to<unsigned long>, std::allocator<unsigned long> >, std::hash<int>, std::equal_to<int>, std::allocator<std::pair<int const, std::unordered_set<unsigned long, std::hash<unsigned long>, std::equal_to<unsigned long>, std::allocator<unsigned long> > > > >, unsigned long>(std::unordered_map<int, std::unordered_set<unsigned long, std::hash<unsigned long>, std::equal_to<unsigned long>, std::allocator<unsigned long> >, std::hash<int>, std::equal_to<int>, std::allocator<std::pair<int const, std::unordered_set<unsigned long, std::hash<unsigned long>, std::equal_to<unsigned long>, std::allocator<unsigned long> > > > > const&, unsigned long const&) @@ -81,7 +81,7 @@ inciter::Refiner::Refiner(CkMigrateMessage*) - 7861 + 7774
diff --git a/Debug/test_coverage/Inciter/Refiner.hpp.gcov.html b/Debug/test_coverage/Inciter/Refiner.hpp.gcov.html index 00985e78b867..e44d77c420ca 100644 --- a/Debug/test_coverage/Inciter/Refiner.hpp.gcov.html +++ b/Debug/test_coverage/Inciter/Refiner.hpp.gcov.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:43:41 + 2024-07-11 15:06:04 Functions: 3 @@ -164,8 +164,8 @@ 90 : : #endif 91 : : //! Migrate constructor 92 : : // cppcheck-suppress uninitMemberVar - 93 [ + - ][ + - ]: 7861 : explicit Refiner( CkMigrateMessage* ) {} - [ + - ][ + - ] + 93 [ + - ][ + - ]: 7774 : explicit Refiner( CkMigrateMessage* ) {} + [ + - ][ + - ] 94 : : #if defined(__clang__) 95 : : #pragma clang diagnostic pop 96 : : #endif @@ -234,68 +234,68 @@ 159 : : ///@{ 160 : : //! \brief Pack/Unpack serialize member function 161 : : //! \param[in,out] p Charm++'s PUP::er serializer object reference - 162 : 24399 : void pup( PUP::er &p ) override { - 163 : 24399 : p | m_meshid; - 164 : 24399 : p | m_ncit; - 165 : 24399 : p | m_host; - 166 : 24399 : p | m_sorter; - 167 : 24399 : p | m_meshwriter; - 168 : 24399 : p | m_scheme; - 169 : 24399 : p | m_cbr; - 170 : 24399 : p | m_cbs; - 171 : 24399 : p | m_ginpoel; - 172 : 24399 : p | m_el; - 173 [ + + ]: 24399 : if (p.isUnpacking()) { - 174 : 7861 : m_inpoel = std::get< 0 >( m_el ); - 175 : 7861 : m_gid = std::get< 1 >( m_el ); - 176 : 7861 : m_lid = std::get< 2 >( m_el ); + 162 : 24138 : void pup( PUP::er &p ) override { + 163 : 24138 : p | m_meshid; + 164 : 24138 : p | m_ncit; + 165 : 24138 : p | m_host; + 166 : 24138 : p | m_sorter; + 167 : 24138 : p | m_meshwriter; + 168 : 24138 : p | m_scheme; + 169 : 24138 : p | m_cbr; + 170 : 24138 : p | m_cbs; + 171 : 24138 : p | m_ginpoel; + 172 : 24138 : p | m_el; + 173 [ + + ]: 24138 : if (p.isUnpacking()) { + 174 : 7774 : m_inpoel = std::get< 0 >( m_el ); + 175 : 7774 : m_gid = std::get< 1 >( m_el ); + 176 : 7774 : m_lid = std::get< 2 >( m_el ); 177 : : } - 178 : 24399 : p | m_coordmap; - 179 : 24399 : p | m_coord; - 180 : 24399 : p | m_bface; - 181 : 24399 : p | m_bnode; - 182 : 24399 : p | m_triinpoel; - 183 : 24399 : p | m_elemblockid; - 184 : 24399 : p | m_nchare; - 185 : 24399 : p | m_mode; - 186 : 24399 : p | m_initref; - 187 : 24399 : p | m_refiner; - 188 : 24399 : p | m_nref; - 189 : 24399 : p | m_nbnd; - 190 : 24399 : p | m_extra; - 191 : 24399 : p | m_ch; - 192 : 24399 : p | m_edgech; - 193 : 24399 : p | m_chedge; - 194 : 24399 : p | m_localEdgeData; - 195 : 24399 : p | m_remoteEdgeData; - 196 : 24399 : p | m_remoteEdges; - 197 : 24399 : p | m_intermediates; - 198 : 24399 : p | m_nodeCommMap; - 199 : 24399 : p | m_oldTets; - 200 : 24399 : p | m_addedNodes; - 201 : 24399 : p | m_addedTets; - 202 : 24399 : p | m_removedNodes; - 203 : 24399 : p | m_amrNodeMap; - 204 : 24399 : p | m_oldntets; - 205 : 24399 : p | m_coarseBndFaces; - 206 : 24399 : p | m_coarseBndNodes; - 207 : 24399 : p | m_coarseBlkElems; - 208 : 24399 : p | m_rid; + 178 : 24138 : p | m_coordmap; + 179 : 24138 : p | m_coord; + 180 : 24138 : p | m_bface; + 181 : 24138 : p | m_bnode; + 182 : 24138 : p | m_triinpoel; + 183 : 24138 : p | m_elemblockid; + 184 : 24138 : p | m_nchare; + 185 : 24138 : p | m_mode; + 186 : 24138 : p | m_initref; + 187 : 24138 : p | m_refiner; + 188 : 24138 : p | m_nref; + 189 : 24138 : p | m_nbnd; + 190 : 24138 : p | m_extra; + 191 : 24138 : p | m_ch; + 192 : 24138 : p | m_edgech; + 193 : 24138 : p | m_chedge; + 194 : 24138 : p | m_localEdgeData; + 195 : 24138 : p | m_remoteEdgeData; + 196 : 24138 : p | m_remoteEdges; + 197 : 24138 : p | m_intermediates; + 198 : 24138 : p | m_nodeCommMap; + 199 : 24138 : p | m_oldTets; + 200 : 24138 : p | m_addedNodes; + 201 : 24138 : p | m_addedTets; + 202 : 24138 : p | m_removedNodes; + 203 : 24138 : p | m_amrNodeMap; + 204 : 24138 : p | m_oldntets; + 205 : 24138 : p | m_coarseBndFaces; + 206 : 24138 : p | m_coarseBndNodes; + 207 : 24138 : p | m_coarseBlkElems; + 208 : 24138 : p | m_rid; 209 : : //p | m_oldrid; - 210 : 24399 : p | m_lref; + 210 : 24138 : p | m_lref; 211 : : //p | m_oldlref; 212 : : //p | m_oldparent; - 213 : 24399 : p | m_writeCallback; - 214 : 24399 : p | m_outref_ginpoel; - 215 : 24399 : p | m_outref_el; - 216 : 24399 : p | m_outref_coord; - 217 : 24399 : p | m_outref_addedNodes; - 218 : 24399 : p | m_outref_addedTets; - 219 : 24399 : p | m_outref_nodeCommMap; - 220 : 24399 : p | m_outref_bface; - 221 : 24399 : p | m_outref_bnode; - 222 : 24399 : p | m_outref_triinpoel; - 223 : 24399 : } + 213 : 24138 : p | m_writeCallback; + 214 : 24138 : p | m_outref_ginpoel; + 215 : 24138 : p | m_outref_el; + 216 : 24138 : p | m_outref_coord; + 217 : 24138 : p | m_outref_addedNodes; + 218 : 24138 : p | m_outref_addedTets; + 219 : 24138 : p | m_outref_nodeCommMap; + 220 : 24138 : p | m_outref_bface; + 221 : 24138 : p | m_outref_bnode; + 222 : 24138 : p | m_outref_triinpoel; + 223 : 24138 : } 224 : : //! \brief Pack/Unpack serialize operator| 225 : : //! \param[in,out] p Charm++'s PUP::er serializer object reference 226 : : //! \param[in,out] r Refiner object reference diff --git a/Debug/test_coverage/Inciter/Scheme.hpp.func-sort-c.html b/Debug/test_coverage/Inciter/Scheme.hpp.func-sort-c.html index b8495fdd08c3..76499e519e41 100644 --- a/Debug/test_coverage/Inciter/Scheme.hpp.func-sort-c.html +++ b/Debug/test_coverage/Inciter/Scheme.hpp.func-sort-c.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:43:41 + 2024-07-11 15:06:04 Functions: 53 @@ -385,15 +385,15 @@ inciter::Scheme::Scheme() - 20337 + 20163 inciter::Scheme::pup(PUP::er&) - 62293 + 61771 inciter::operator|(PUP::er&, inciter::Scheme&) - 62293 + 61771
diff --git a/Debug/test_coverage/Inciter/Scheme.hpp.func.html b/Debug/test_coverage/Inciter/Scheme.hpp.func.html index 88ada4b871da..40748f200e1e 100644 --- a/Debug/test_coverage/Inciter/Scheme.hpp.func.html +++ b/Debug/test_coverage/Inciter/Scheme.hpp.func.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:43:41 + 2024-07-11 15:06:04 Functions: 53 @@ -85,7 +85,7 @@ inciter::Scheme::pup(PUP::er&) - 62293 + 61771 inciter::Scheme::disc() @@ -141,11 +141,11 @@ inciter::Scheme::Scheme() - 20337 + 20163 inciter::operator|(PUP::er&, inciter::Scheme&) - 62293 + 61771 inciter::Scheme::index_element() const diff --git a/Debug/test_coverage/Inciter/Scheme.hpp.gcov.html b/Debug/test_coverage/Inciter/Scheme.hpp.gcov.html index de76ee8231a8..97be53c9f0ab 100644 --- a/Debug/test_coverage/Inciter/Scheme.hpp.gcov.html +++ b/Debug/test_coverage/Inciter/Scheme.hpp.gcov.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:43:41 + 2024-07-11 15:06:04 Functions: 53 @@ -182,7 +182,7 @@ 108 : : , CProxy_FV::element_t >; 109 : : 110 : : //! Empty constructor for Charm++ - 111 [ + - ]: 20337 : explicit Scheme() {} + 111 [ + - ]: 20163 : explicit Scheme() {} 112 : : 113 : : //! Constructor 114 : : //! \param[in] scheme Discretization scheme @@ -359,18 +359,18 @@ 276 : : ///@{ 277 : : //! \brief Pack/Unpack serialize member function 278 : : //! \param[in,out] p Charm++'s PUP::er serializer object reference - 279 : 62293 : void pup( PUP::er &p ) { - 280 : 62293 : p | proxy; - 281 : 62293 : p | discproxy; - 282 : 62293 : p | aleproxy; - 283 : 62293 : p | conjugategradientsproxy; - 284 : 62293 : p | ghostsproxy; - 285 : 62293 : p | bound; - 286 : 62293 : } + 279 : 61771 : void pup( PUP::er &p ) { + 280 : 61771 : p | proxy; + 281 : 61771 : p | discproxy; + 282 : 61771 : p | aleproxy; + 283 : 61771 : p | conjugategradientsproxy; + 284 : 61771 : p | ghostsproxy; + 285 : 61771 : p | bound; + 286 : 61771 : } 287 : : //! \brief Pack/Unpack serialize operator| 288 : : //! \param[in,out] p Charm++'s PUP::er serializer object reference 289 : : //! \param[in,out] s Scheme object reference - 290 : 62293 : friend void operator|( PUP::er& p, Scheme& s ) { s.pup(p); } + 290 : 61771 : friend void operator|( PUP::er& p, Scheme& s ) { s.pup(p); } 291 : : //@} 292 : : 293 : : private: diff --git a/Debug/test_coverage/Inciter/Sorter.cpp.func-sort-c.html b/Debug/test_coverage/Inciter/Sorter.cpp.func-sort-c.html index a720583182ff..0f0a782447e7 100644 --- a/Debug/test_coverage/Inciter/Sorter.cpp.func-sort-c.html +++ b/Debug/test_coverage/Inciter/Sorter.cpp.func-sort-c.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:43:41 + 2024-07-11 15:06:04 Functions: 22 diff --git a/Debug/test_coverage/Inciter/Sorter.cpp.func.html b/Debug/test_coverage/Inciter/Sorter.cpp.func.html index 5e9937ee04cd..d6928240208f 100644 --- a/Debug/test_coverage/Inciter/Sorter.cpp.func.html +++ b/Debug/test_coverage/Inciter/Sorter.cpp.func.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:43:41 + 2024-07-11 15:06:04 Functions: 22 diff --git a/Debug/test_coverage/Inciter/Sorter.cpp.gcov.html b/Debug/test_coverage/Inciter/Sorter.cpp.gcov.html index ee6c0758ce55..6d15eceef3f9 100644 --- a/Debug/test_coverage/Inciter/Sorter.cpp.gcov.html +++ b/Debug/test_coverage/Inciter/Sorter.cpp.gcov.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:43:41 + 2024-07-11 15:06:04 Functions: 22 diff --git a/Debug/test_coverage/Inciter/Sorter.hpp.func-sort-c.html b/Debug/test_coverage/Inciter/Sorter.hpp.func-sort-c.html index 21c280a4f349..b5fa6192a5e3 100644 --- a/Debug/test_coverage/Inciter/Sorter.hpp.func-sort-c.html +++ b/Debug/test_coverage/Inciter/Sorter.hpp.func-sort-c.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:43:41 + 2024-07-11 15:06:04 Functions: 2 @@ -73,11 +73,11 @@ inciter::Sorter::Sorter(CkMigrateMessage*) - 7861 + 7774 inciter::Sorter::pup(PUP::er&) - 24399 + 24138
diff --git a/Debug/test_coverage/Inciter/Sorter.hpp.func.html b/Debug/test_coverage/Inciter/Sorter.hpp.func.html index 62b163d5582a..8682b8aad328 100644 --- a/Debug/test_coverage/Inciter/Sorter.hpp.func.html +++ b/Debug/test_coverage/Inciter/Sorter.hpp.func.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:43:41 + 2024-07-11 15:06:04 Functions: 2 @@ -73,11 +73,11 @@ inciter::Sorter::pup(PUP::er&) - 24399 + 24138 inciter::Sorter::Sorter(CkMigrateMessage*) - 7861 + 7774
diff --git a/Debug/test_coverage/Inciter/Sorter.hpp.gcov.html b/Debug/test_coverage/Inciter/Sorter.hpp.gcov.html index f95ef2737530..a278f141f923 100644 --- a/Debug/test_coverage/Inciter/Sorter.hpp.gcov.html +++ b/Debug/test_coverage/Inciter/Sorter.hpp.gcov.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:43:41 + 2024-07-11 15:06:04 Functions: 2 @@ -156,7 +156,7 @@ 82 : : #endif 83 : : //! Migrate constructor 84 : : // cppcheck-suppress uninitMemberVarPrivate - 85 [ + - ][ + - ]: 7861 : explicit Sorter( CkMigrateMessage* ) {} + 85 [ + - ][ + - ]: 7774 : explicit Sorter( CkMigrateMessage* ) {} 86 : : #if defined(__clang__) 87 : : #pragma clang diagnostic pop 88 : : #endif @@ -208,37 +208,37 @@ 134 : : ///@{ 135 : : //! \brief Pack/Unpack serialize member function 136 : : //! \param[in,out] p Charm++'s PUP::er serializer object reference - 137 : 24399 : void pup( PUP::er &p ) override { - 138 : 24399 : p | m_meshid; - 139 : 24399 : p | m_host; - 140 : 24399 : p | m_meshwriter; - 141 : 24399 : p | m_cbs; - 142 : 24399 : p | m_scheme; - 143 : 24399 : p | m_reorderRefiner; - 144 : 24399 : p | m_ginpoel; - 145 : 24399 : p | m_coordmap; - 146 : 24399 : p | m_el; - 147 : 24399 : p | m_nbnd; - 148 : 24399 : p | m_bface; - 149 : 24399 : p | m_triinpoel; - 150 : 24399 : p | m_bnode; - 151 : 24399 : p | m_elemblockid; - 152 : 24399 : p | m_nchare; - 153 : 24399 : p | m_nodeset; - 154 : 24399 : p | m_noffset; - 155 : 24399 : p | m_nodech; - 156 : 24399 : p | m_chnode; - 157 : 24399 : p | m_edgech; - 158 : 24399 : p | m_chedge; - 159 : 24399 : p | m_msum; - 160 : 24399 : p | m_reordcomm; - 161 : 24399 : p | m_start; - 162 : 24399 : p | m_newnodes; - 163 : 24399 : p | m_newcoordmap; - 164 : 24399 : p | m_reqnodes; - 165 : 24399 : p | m_lower; - 166 : 24399 : p | m_upper; - 167 : 24399 : } + 137 : 24138 : void pup( PUP::er &p ) override { + 138 : 24138 : p | m_meshid; + 139 : 24138 : p | m_host; + 140 : 24138 : p | m_meshwriter; + 141 : 24138 : p | m_cbs; + 142 : 24138 : p | m_scheme; + 143 : 24138 : p | m_reorderRefiner; + 144 : 24138 : p | m_ginpoel; + 145 : 24138 : p | m_coordmap; + 146 : 24138 : p | m_el; + 147 : 24138 : p | m_nbnd; + 148 : 24138 : p | m_bface; + 149 : 24138 : p | m_triinpoel; + 150 : 24138 : p | m_bnode; + 151 : 24138 : p | m_elemblockid; + 152 : 24138 : p | m_nchare; + 153 : 24138 : p | m_nodeset; + 154 : 24138 : p | m_noffset; + 155 : 24138 : p | m_nodech; + 156 : 24138 : p | m_chnode; + 157 : 24138 : p | m_edgech; + 158 : 24138 : p | m_chedge; + 159 : 24138 : p | m_msum; + 160 : 24138 : p | m_reordcomm; + 161 : 24138 : p | m_start; + 162 : 24138 : p | m_newnodes; + 163 : 24138 : p | m_newcoordmap; + 164 : 24138 : p | m_reqnodes; + 165 : 24138 : p | m_lower; + 166 : 24138 : p | m_upper; + 167 : 24138 : } 168 : : //! \brief Pack/Unpack serialize operator| 169 : : //! \param[in,out] p Charm++'s PUP::er serializer object reference 170 : : //! \param[in,out] s Sorter object reference diff --git a/Debug/test_coverage/Inciter/Transfer.hpp.func-sort-c.html b/Debug/test_coverage/Inciter/Transfer.hpp.func-sort-c.html index 1332f313560a..0ee93db57f91 100644 --- a/Debug/test_coverage/Inciter/Transfer.hpp.func-sort-c.html +++ b/Debug/test_coverage/Inciter/Transfer.hpp.func-sort-c.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:43:41 + 2024-07-11 15:06:04 Functions: 5 diff --git a/Debug/test_coverage/Inciter/Transfer.hpp.func.html b/Debug/test_coverage/Inciter/Transfer.hpp.func.html index 687c9c72c412..0019fcc24f1b 100644 --- a/Debug/test_coverage/Inciter/Transfer.hpp.func.html +++ b/Debug/test_coverage/Inciter/Transfer.hpp.func.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:43:41 + 2024-07-11 15:06:04 Functions: 5 diff --git a/Debug/test_coverage/Inciter/Transfer.hpp.gcov.html b/Debug/test_coverage/Inciter/Transfer.hpp.gcov.html index 5b1f56a37f78..ad02affce4da 100644 --- a/Debug/test_coverage/Inciter/Transfer.hpp.gcov.html +++ b/Debug/test_coverage/Inciter/Transfer.hpp.gcov.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:43:41 + 2024-07-11 15:06:04 Functions: 5 diff --git a/Debug/test_coverage/Inciter/Transporter.cpp.func-sort-c.html b/Debug/test_coverage/Inciter/Transporter.cpp.func-sort-c.html index b7b73d35435c..f35db4770516 100644 --- a/Debug/test_coverage/Inciter/Transporter.cpp.func-sort-c.html +++ b/Debug/test_coverage/Inciter/Transporter.cpp.func-sort-c.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:43:41 + 2024-07-11 15:06:04 Functions: 44 diff --git a/Debug/test_coverage/Inciter/Transporter.cpp.func.html b/Debug/test_coverage/Inciter/Transporter.cpp.func.html index 467465af628f..f2b272b2b444 100644 --- a/Debug/test_coverage/Inciter/Transporter.cpp.func.html +++ b/Debug/test_coverage/Inciter/Transporter.cpp.func.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:43:41 + 2024-07-11 15:06:04 Functions: 44 diff --git a/Debug/test_coverage/Inciter/Transporter.cpp.gcov.html b/Debug/test_coverage/Inciter/Transporter.cpp.gcov.html index eec4a66e4882..8d17e0243f56 100644 --- a/Debug/test_coverage/Inciter/Transporter.cpp.gcov.html +++ b/Debug/test_coverage/Inciter/Transporter.cpp.gcov.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:43:41 + 2024-07-11 15:06:04 Functions: 44 diff --git a/Debug/test_coverage/Inciter/Transporter.hpp.func-sort-c.html b/Debug/test_coverage/Inciter/Transporter.hpp.func-sort-c.html index 9c993bdfaa6a..be91f67fb622 100644 --- a/Debug/test_coverage/Inciter/Transporter.hpp.func-sort-c.html +++ b/Debug/test_coverage/Inciter/Transporter.hpp.func-sort-c.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:43:41 + 2024-07-11 15:06:04 Functions: 12 diff --git a/Debug/test_coverage/Inciter/Transporter.hpp.func.html b/Debug/test_coverage/Inciter/Transporter.hpp.func.html index 4ceab7f063a1..d637bfe7f7ad 100644 --- a/Debug/test_coverage/Inciter/Transporter.hpp.func.html +++ b/Debug/test_coverage/Inciter/Transporter.hpp.func.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:43:41 + 2024-07-11 15:06:04 Functions: 12 diff --git a/Debug/test_coverage/Inciter/Transporter.hpp.gcov.html b/Debug/test_coverage/Inciter/Transporter.hpp.gcov.html index 291631f462cf..cfcac94bc309 100644 --- a/Debug/test_coverage/Inciter/Transporter.hpp.gcov.html +++ b/Debug/test_coverage/Inciter/Transporter.hpp.gcov.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:43:41 + 2024-07-11 15:06:04 Functions: 12 diff --git a/Debug/test_coverage/Inciter/ale.ci.func-sort-c.html b/Debug/test_coverage/Inciter/ale.ci.func-sort-c.html index c0c611ddde9b..5863692bd7a3 100644 --- a/Debug/test_coverage/Inciter/ale.ci.func-sort-c.html +++ b/Debug/test_coverage/Inciter/ale.ci.func-sort-c.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:43:41 + 2024-07-11 15:06:04 Functions: 0 diff --git a/Debug/test_coverage/Inciter/ale.ci.func.html b/Debug/test_coverage/Inciter/ale.ci.func.html index 0c08a6181e13..11a59e49c746 100644 --- a/Debug/test_coverage/Inciter/ale.ci.func.html +++ b/Debug/test_coverage/Inciter/ale.ci.func.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:43:41 + 2024-07-11 15:06:04 Functions: 0 diff --git a/Debug/test_coverage/Inciter/ale.ci.gcov.html b/Debug/test_coverage/Inciter/ale.ci.gcov.html index 85f26b95ad45..b9189b6420b3 100644 --- a/Debug/test_coverage/Inciter/ale.ci.gcov.html +++ b/Debug/test_coverage/Inciter/ale.ci.gcov.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:43:41 + 2024-07-11 15:06:04 Functions: 0 diff --git a/Debug/test_coverage/Inciter/alecg.ci.func-sort-c.html b/Debug/test_coverage/Inciter/alecg.ci.func-sort-c.html index b0a0980b6bf0..698c28e65277 100644 --- a/Debug/test_coverage/Inciter/alecg.ci.func-sort-c.html +++ b/Debug/test_coverage/Inciter/alecg.ci.func-sort-c.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:43:41 + 2024-07-11 15:06:04 Functions: 0 diff --git a/Debug/test_coverage/Inciter/alecg.ci.func.html b/Debug/test_coverage/Inciter/alecg.ci.func.html index ed89fd5a0d65..7fcdd3a4a0a0 100644 --- a/Debug/test_coverage/Inciter/alecg.ci.func.html +++ b/Debug/test_coverage/Inciter/alecg.ci.func.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:43:41 + 2024-07-11 15:06:04 Functions: 0 diff --git a/Debug/test_coverage/Inciter/alecg.ci.gcov.html b/Debug/test_coverage/Inciter/alecg.ci.gcov.html index 45aa46af10a4..e482bd2b3155 100644 --- a/Debug/test_coverage/Inciter/alecg.ci.gcov.html +++ b/Debug/test_coverage/Inciter/alecg.ci.gcov.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:43:41 + 2024-07-11 15:06:04 Functions: 0 diff --git a/Debug/test_coverage/Inciter/dg.ci.func-sort-c.html b/Debug/test_coverage/Inciter/dg.ci.func-sort-c.html index c434af7f7b2b..b9e8868cf2a6 100644 --- a/Debug/test_coverage/Inciter/dg.ci.func-sort-c.html +++ b/Debug/test_coverage/Inciter/dg.ci.func-sort-c.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:43:41 + 2024-07-11 15:06:04 Functions: 0 diff --git a/Debug/test_coverage/Inciter/dg.ci.func.html b/Debug/test_coverage/Inciter/dg.ci.func.html index 0556c917610e..921293544d10 100644 --- a/Debug/test_coverage/Inciter/dg.ci.func.html +++ b/Debug/test_coverage/Inciter/dg.ci.func.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:43:41 + 2024-07-11 15:06:04 Functions: 0 diff --git a/Debug/test_coverage/Inciter/dg.ci.gcov.html b/Debug/test_coverage/Inciter/dg.ci.gcov.html index d2112c2a9dd6..11d11a909a40 100644 --- a/Debug/test_coverage/Inciter/dg.ci.gcov.html +++ b/Debug/test_coverage/Inciter/dg.ci.gcov.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:43:41 + 2024-07-11 15:06:04 Functions: 0 diff --git a/Debug/test_coverage/Inciter/discretization.ci.func-sort-c.html b/Debug/test_coverage/Inciter/discretization.ci.func-sort-c.html index f20fe73e6d87..750f5a694685 100644 --- a/Debug/test_coverage/Inciter/discretization.ci.func-sort-c.html +++ b/Debug/test_coverage/Inciter/discretization.ci.func-sort-c.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:43:41 + 2024-07-11 15:06:04 Functions: 0 diff --git a/Debug/test_coverage/Inciter/discretization.ci.func.html b/Debug/test_coverage/Inciter/discretization.ci.func.html index aef9a314c420..320aad0b9702 100644 --- a/Debug/test_coverage/Inciter/discretization.ci.func.html +++ b/Debug/test_coverage/Inciter/discretization.ci.func.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:43:41 + 2024-07-11 15:06:04 Functions: 0 diff --git a/Debug/test_coverage/Inciter/discretization.ci.gcov.html b/Debug/test_coverage/Inciter/discretization.ci.gcov.html index 50fa1c0dc6ab..26b366decdaf 100644 --- a/Debug/test_coverage/Inciter/discretization.ci.gcov.html +++ b/Debug/test_coverage/Inciter/discretization.ci.gcov.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:43:41 + 2024-07-11 15:06:04 Functions: 0 diff --git a/Debug/test_coverage/Inciter/fv.ci.func-sort-c.html b/Debug/test_coverage/Inciter/fv.ci.func-sort-c.html index b805c22c90d9..e3de53fcdbb2 100644 --- a/Debug/test_coverage/Inciter/fv.ci.func-sort-c.html +++ b/Debug/test_coverage/Inciter/fv.ci.func-sort-c.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:43:41 + 2024-07-11 15:06:04 Functions: 0 diff --git a/Debug/test_coverage/Inciter/fv.ci.func.html b/Debug/test_coverage/Inciter/fv.ci.func.html index 357c78992b6f..170db39d1f93 100644 --- a/Debug/test_coverage/Inciter/fv.ci.func.html +++ b/Debug/test_coverage/Inciter/fv.ci.func.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:43:41 + 2024-07-11 15:06:04 Functions: 0 diff --git a/Debug/test_coverage/Inciter/fv.ci.gcov.html b/Debug/test_coverage/Inciter/fv.ci.gcov.html index 46defda64c73..1f44d94526aa 100644 --- a/Debug/test_coverage/Inciter/fv.ci.gcov.html +++ b/Debug/test_coverage/Inciter/fv.ci.gcov.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:43:41 + 2024-07-11 15:06:04 Functions: 0 diff --git a/Debug/test_coverage/Inciter/ghosts.ci.func-sort-c.html b/Debug/test_coverage/Inciter/ghosts.ci.func-sort-c.html index b0d57165a4de..a9ced2beee57 100644 --- a/Debug/test_coverage/Inciter/ghosts.ci.func-sort-c.html +++ b/Debug/test_coverage/Inciter/ghosts.ci.func-sort-c.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:43:41 + 2024-07-11 15:06:04 Functions: 0 diff --git a/Debug/test_coverage/Inciter/ghosts.ci.func.html b/Debug/test_coverage/Inciter/ghosts.ci.func.html index 50bf21f8c955..af76390794ce 100644 --- a/Debug/test_coverage/Inciter/ghosts.ci.func.html +++ b/Debug/test_coverage/Inciter/ghosts.ci.func.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:43:41 + 2024-07-11 15:06:04 Functions: 0 diff --git a/Debug/test_coverage/Inciter/ghosts.ci.gcov.html b/Debug/test_coverage/Inciter/ghosts.ci.gcov.html index 14a4745f1f79..77b0d992e339 100644 --- a/Debug/test_coverage/Inciter/ghosts.ci.gcov.html +++ b/Debug/test_coverage/Inciter/ghosts.ci.gcov.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:43:41 + 2024-07-11 15:06:04 Functions: 0 diff --git a/Debug/test_coverage/Inciter/index-sort-b.html b/Debug/test_coverage/Inciter/index-sort-b.html index 74c23a7cf4a8..3cd5abd5a7a2 100644 --- a/Debug/test_coverage/Inciter/index-sort-b.html +++ b/Debug/test_coverage/Inciter/index-sort-b.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:43:41 + 2024-07-11 15:06:04 Functions: 547 @@ -82,14 +82,14 @@ Branches Sort by branch coverage - Ghosts.hpp + OversetFE.hpp -
100.0%
+
86.7%86.7%
- 100.0 % - 45 / 45 - 100.0 % - 5 / 5 + 86.7 % + 52 / 60 + 33.3 % + 3 / 9 25.0 % 3 / 12 @@ -106,14 +106,14 @@ 3 / 12 - OversetFE.hpp + Ghosts.hpp -
86.7%86.7%
+
100.0%
- 86.7 % - 52 / 60 - 33.3 % - 3 / 9 + 100.0 % + 45 / 45 + 100.0 % + 5 / 5 25.0 % 3 / 12 @@ -250,38 +250,38 @@ 761 / 1554 - fv.ci + dg.ci
100.0%
100.0 % - 3 / 3 + 7 / 7 - 0 / 0 50.0 % 2 / 4 - Sorter.hpp + fv.ci
100.0%
100.0 % - 32 / 32 - 100.0 % - 2 / 2 + 3 / 3 + - + 0 / 0 50.0 % 2 / 4 - dg.ci + Sorter.hpp
100.0%
100.0 % - 7 / 7 - - - 0 / 0 + 32 / 32 + 100.0 % + 2 / 2 50.0 % 2 / 4 @@ -465,18 +465,6 @@ - 0 / 0 - - ghosts.ci - -
100.0%
- - 100.0 % - 3 / 3 - - - 0 / 0 - - - 0 / 0 - PUPAMR.hpp @@ -490,38 +478,38 @@ 0 / 0 - Transfer.hpp + sorter.ci
100.0%
100.0 % - 11 / 11 - 100.0 % - 5 / 5 + 1 / 1 + - + 0 / 0 - 0 / 0 - sorter.ci + ghosts.ci
100.0%
100.0 % - 1 / 1 + 3 / 3 - 0 / 0 - 0 / 0 - transporter.ci + Transfer.hpp
100.0%
100.0 % - 1 / 1 - - - 0 / 0 + 11 / 11 + 100.0 % + 5 / 5 - 0 / 0 @@ -538,12 +526,24 @@ 0 / 0 - oversetfe.ci + transporter.ci
100.0%
100.0 % - 4 / 4 + 1 / 1 + - + 0 / 0 + - + 0 / 0 + + + discretization.ci + +
100.0%
+ + 100.0 % + 1 / 1 - 0 / 0 - @@ -562,26 +562,26 @@ 0 / 0 - ale.ci + oversetfe.ci
100.0%
100.0 % - 3 / 3 + 4 / 4 - 0 / 0 - 0 / 0 - ElemDiagnostics.hpp + ale.ci
100.0%
100.0 % - 2 / 2 - 100.0 % - 2 / 2 + 3 / 3 + - + 0 / 0 - 0 / 0 @@ -598,14 +598,14 @@ 0 / 0 - discretization.ci + ElemDiagnostics.hpp
100.0%
100.0 % - 1 / 1 - - - 0 / 0 + 2 / 2 + 100.0 % + 2 / 2 - 0 / 0 diff --git a/Debug/test_coverage/Inciter/index-sort-f.html b/Debug/test_coverage/Inciter/index-sort-f.html index 5cf61898d1cc..37205a0a142b 100644 --- a/Debug/test_coverage/Inciter/index-sort-f.html +++ b/Debug/test_coverage/Inciter/index-sort-f.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:43:41 + 2024-07-11 15:06:04 Functions: 547 @@ -298,36 +298,48 @@ 485 / 864 - alecg.ci + dg.ci
100.0%
100.0 % - 5 / 5 + 7 / 7 - 0 / 0 - 100.0 % - 2 / 2 + 50.0 % + 2 / 4 - ghosts.ci + sorter.ci
100.0%
100.0 % - 3 / 3 + 1 / 1 - 0 / 0 - 0 / 0 - sorter.ci + fv.ci
100.0%
100.0 % - 1 / 1 + 3 / 3 + - + 0 / 0 + 50.0 % + 2 / 4 + + + ghosts.ci + +
100.0%
+ + 100.0 % + 3 / 3 - 0 / 0 - @@ -346,16 +358,16 @@ 0 / 0 - fv.ci + discretization.ci
100.0%
100.0 % - 3 / 3 + 1 / 1 + - + 0 / 0 - 0 / 0 - 50.0 % - 2 / 4 oversetfe.ci @@ -382,40 +394,40 @@ 0 / 0 - dg.ci + alecg.ci
100.0%
100.0 % - 7 / 7 + 5 / 5 - 0 / 0 - 50.0 % - 2 / 4 + 100.0 % + 2 / 2 - discretization.ci + FaceData.cpp
100.0%
100.0 % + 12 / 12 + 100.0 % 1 / 1 - - - 0 / 0 - - - 0 / 0 + 36.4 % + 8 / 22 - FaceData.cpp + DiagReducer.cpp
100.0%
100.0 % - 12 / 12 + 40 / 40 100.0 % - 1 / 1 - 36.4 % - 8 / 22 + 2 / 2 + 50.0 % + 40 / 80 NodeDiagnostics.cpp @@ -453,18 +465,6 @@ - 0 / 0 - - DiagReducer.cpp - -
100.0%
- - 100.0 % - 40 / 40 - 100.0 % - 2 / 2 - 50.0 % - 40 / 80 - Sorter.hpp @@ -489,6 +489,18 @@ - 0 / 0 + + Refiner.hpp + +
100.0%
+ + 100.0 % + 65 / 65 + 100.0 % + 3 / 3 + 66.7 % + 12 / 18 + FieldOutput.cpp @@ -525,18 +537,6 @@ 50.0 % 23 / 46 - - Refiner.hpp - -
100.0%
- - 100.0 % - 65 / 65 - 100.0 % - 3 / 3 - 66.7 % - 12 / 18 - ALE.hpp diff --git a/Debug/test_coverage/Inciter/index-sort-l.html b/Debug/test_coverage/Inciter/index-sort-l.html index 2864029671aa..1dab8bed6892 100644 --- a/Debug/test_coverage/Inciter/index-sort-l.html +++ b/Debug/test_coverage/Inciter/index-sort-l.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:43:41 + 2024-07-11 15:06:04 Functions: 547 @@ -358,7 +358,7 @@ 0 / 0 - ghosts.ci + fv.ci
100.0%
@@ -366,11 +366,11 @@ 3 / 3 - 0 / 0 - - - 0 / 0 + 50.0 % + 2 / 4 - fv.ci + ghosts.ci
100.0%
@@ -378,8 +378,8 @@ 3 / 3 - 0 / 0 - 50.0 % - 2 / 4 + - + 0 / 0 ale.ci @@ -538,7 +538,7 @@ 0 / 0 - NodeDiagnostics.cpp + DiagReducer.cpp
100.0%
@@ -546,11 +546,11 @@ 40 / 40 100.0 % 2 / 2 - 57.7 % - 45 / 78 + 50.0 % + 40 / 80 - DiagReducer.cpp + NodeDiagnostics.cpp
100.0%
@@ -558,8 +558,8 @@ 40 / 40 100.0 % 2 / 2 - 50.0 % - 40 / 80 + 57.7 % + 45 / 78 Ghosts.hpp diff --git a/Debug/test_coverage/Inciter/index.html b/Debug/test_coverage/Inciter/index.html index 0013eb92b7fd..e566d39be7af 100644 --- a/Debug/test_coverage/Inciter/index.html +++ b/Debug/test_coverage/Inciter/index.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:43:41 + 2024-07-11 15:06:04 Functions: 547 diff --git a/Debug/test_coverage/Inciter/oversetfe.ci.func-sort-c.html b/Debug/test_coverage/Inciter/oversetfe.ci.func-sort-c.html index a2004d4e9ce2..6550958ef261 100644 --- a/Debug/test_coverage/Inciter/oversetfe.ci.func-sort-c.html +++ b/Debug/test_coverage/Inciter/oversetfe.ci.func-sort-c.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:43:41 + 2024-07-11 15:06:04 Functions: 0 diff --git a/Debug/test_coverage/Inciter/oversetfe.ci.func.html b/Debug/test_coverage/Inciter/oversetfe.ci.func.html index 68b69713384e..c7477c715590 100644 --- a/Debug/test_coverage/Inciter/oversetfe.ci.func.html +++ b/Debug/test_coverage/Inciter/oversetfe.ci.func.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:43:41 + 2024-07-11 15:06:04 Functions: 0 diff --git a/Debug/test_coverage/Inciter/oversetfe.ci.gcov.html b/Debug/test_coverage/Inciter/oversetfe.ci.gcov.html index 34df8e4eece9..c6b4ca2666e9 100644 --- a/Debug/test_coverage/Inciter/oversetfe.ci.gcov.html +++ b/Debug/test_coverage/Inciter/oversetfe.ci.gcov.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:43:41 + 2024-07-11 15:06:04 Functions: 0 diff --git a/Debug/test_coverage/Inciter/sorter.ci.func-sort-c.html b/Debug/test_coverage/Inciter/sorter.ci.func-sort-c.html index 187304798000..966f67b53e67 100644 --- a/Debug/test_coverage/Inciter/sorter.ci.func-sort-c.html +++ b/Debug/test_coverage/Inciter/sorter.ci.func-sort-c.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:43:41 + 2024-07-11 15:06:04 Functions: 0 diff --git a/Debug/test_coverage/Inciter/sorter.ci.func.html b/Debug/test_coverage/Inciter/sorter.ci.func.html index 0c84c59ed8b2..3316b04822bf 100644 --- a/Debug/test_coverage/Inciter/sorter.ci.func.html +++ b/Debug/test_coverage/Inciter/sorter.ci.func.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:43:41 + 2024-07-11 15:06:04 Functions: 0 diff --git a/Debug/test_coverage/Inciter/sorter.ci.gcov.html b/Debug/test_coverage/Inciter/sorter.ci.gcov.html index fbdeb7dd6d81..fe5cb8e1b307 100644 --- a/Debug/test_coverage/Inciter/sorter.ci.gcov.html +++ b/Debug/test_coverage/Inciter/sorter.ci.gcov.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:43:41 + 2024-07-11 15:06:04 Functions: 0 diff --git a/Debug/test_coverage/Inciter/transporter.ci.func-sort-c.html b/Debug/test_coverage/Inciter/transporter.ci.func-sort-c.html index 4580be2bd7d1..baf8ac80e678 100644 --- a/Debug/test_coverage/Inciter/transporter.ci.func-sort-c.html +++ b/Debug/test_coverage/Inciter/transporter.ci.func-sort-c.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:43:41 + 2024-07-11 15:06:04 Functions: 0 diff --git a/Debug/test_coverage/Inciter/transporter.ci.func.html b/Debug/test_coverage/Inciter/transporter.ci.func.html index 0505716b10bf..a52430667024 100644 --- a/Debug/test_coverage/Inciter/transporter.ci.func.html +++ b/Debug/test_coverage/Inciter/transporter.ci.func.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:43:41 + 2024-07-11 15:06:04 Functions: 0 diff --git a/Debug/test_coverage/Inciter/transporter.ci.gcov.html b/Debug/test_coverage/Inciter/transporter.ci.gcov.html index 3e9b5e05bd3c..a5165cad1d90 100644 --- a/Debug/test_coverage/Inciter/transporter.ci.gcov.html +++ b/Debug/test_coverage/Inciter/transporter.ci.gcov.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:43:41 + 2024-07-11 15:06:04 Functions: 0 diff --git a/Debug/test_coverage/LinearSolver/CSR.cpp.func-sort-c.html b/Debug/test_coverage/LinearSolver/CSR.cpp.func-sort-c.html index abf8ea2d4854..dac13b04526a 100644 --- a/Debug/test_coverage/LinearSolver/CSR.cpp.func-sort-c.html +++ b/Debug/test_coverage/LinearSolver/CSR.cpp.func-sort-c.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:43:41 + 2024-07-11 15:06:04 Functions: 8 diff --git a/Debug/test_coverage/LinearSolver/CSR.cpp.func.html b/Debug/test_coverage/LinearSolver/CSR.cpp.func.html index b82e1e5e85c4..eda10f25b7d9 100644 --- a/Debug/test_coverage/LinearSolver/CSR.cpp.func.html +++ b/Debug/test_coverage/LinearSolver/CSR.cpp.func.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:43:41 + 2024-07-11 15:06:04 Functions: 8 diff --git a/Debug/test_coverage/LinearSolver/CSR.cpp.gcov.html b/Debug/test_coverage/LinearSolver/CSR.cpp.gcov.html index 7f0463b91ca1..d3c9633eefb3 100644 --- a/Debug/test_coverage/LinearSolver/CSR.cpp.gcov.html +++ b/Debug/test_coverage/LinearSolver/CSR.cpp.gcov.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:43:41 + 2024-07-11 15:06:04 Functions: 8 @@ -172,8 +172,8 @@ 95 : : { 96 : 13371648 : auto rncomp = row * ncomp; 97 : : - 98 [ + - ]: 94245243 : for (std::size_t n=0, j=ia[rncomp+pos]-1; j<ia[rncomp+pos+1]-1; ++j, ++n) - 99 [ + + ]: 94245243 : if (col*ncomp+pos+1 == ja[j]) + 98 [ + - ]: 94251750 : for (std::size_t n=0, j=ia[rncomp+pos]-1; j<ia[rncomp+pos+1]-1; ++j, ++n) + 99 [ + + ]: 94251750 : if (col*ncomp+pos+1 == ja[j]) 100 : 13371648 : return a[ia[rncomp+pos]-1+n]; 101 : : 102 [ - - ][ - - ]: 0 : Throw("Sparse matrix index not found"); diff --git a/Debug/test_coverage/LinearSolver/CSR.hpp.func-sort-c.html b/Debug/test_coverage/LinearSolver/CSR.hpp.func-sort-c.html index 78d54185f009..83b04be2a546 100644 --- a/Debug/test_coverage/LinearSolver/CSR.hpp.func-sort-c.html +++ b/Debug/test_coverage/LinearSolver/CSR.hpp.func-sort-c.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:43:41 + 2024-07-11 15:06:04 Functions: 6 @@ -73,7 +73,7 @@ tk::CSR::CSR() - 86 + 84 tk::CSR::rsize() const @@ -81,11 +81,11 @@ tk::CSR::pup(PUP::er&) - 279 + 273 tk::operator|(PUP::er&, tk::CSR&) - 279 + 273 tk::CSR::Ncomp() const diff --git a/Debug/test_coverage/LinearSolver/CSR.hpp.func.html b/Debug/test_coverage/LinearSolver/CSR.hpp.func.html index 290074db5484..66826a287114 100644 --- a/Debug/test_coverage/LinearSolver/CSR.hpp.func.html +++ b/Debug/test_coverage/LinearSolver/CSR.hpp.func.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:43:41 + 2024-07-11 15:06:04 Functions: 6 @@ -73,11 +73,11 @@ tk::CSR::pup(PUP::er&) - 279 + 273 tk::CSR::CSR() - 86 + 84 tk::CSR::operator()(unsigned long, unsigned long, unsigned long) @@ -85,7 +85,7 @@ tk::operator|(PUP::er&, tk::CSR&) - 279 + 273 tk::CSR::Ncomp() const diff --git a/Debug/test_coverage/LinearSolver/CSR.hpp.gcov.html b/Debug/test_coverage/LinearSolver/CSR.hpp.gcov.html index 391664db2fa6..dc07a8d9d14f 100644 --- a/Debug/test_coverage/LinearSolver/CSR.hpp.gcov.html +++ b/Debug/test_coverage/LinearSolver/CSR.hpp.gcov.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:43:41 + 2024-07-11 15:06:04 Functions: 6 @@ -107,7 +107,7 @@ 33 : : std::vector< std::size_t > >& psup ); 34 : : 35 : : //! Empty constructor for Charm++ - 36 : 86 : explicit CSR() = default; + 36 : 84 : explicit CSR() = default; 37 : : 38 : : //! Return const reference to sparse matrix entry at a position 39 : : const real& @@ -154,17 +154,17 @@ 80 : : ///@{ 81 : : //! \brief Pack/Unpack serialize member function 82 : : //! \param[in,out] p Charm++'s PUP::er serializer object reference - 83 : 279 : void pup( PUP::er &p ) { - 84 : 279 : p | ncomp; - 85 : 279 : p | rnz; - 86 : 279 : p | ia; - 87 : 279 : p | ja; - 88 : 279 : p | a; - 89 : 279 : } + 83 : 273 : void pup( PUP::er &p ) { + 84 : 273 : p | ncomp; + 85 : 273 : p | rnz; + 86 : 273 : p | ia; + 87 : 273 : p | ja; + 88 : 273 : p | a; + 89 : 273 : } 90 : : //! \brief Pack/Unpack serialize operator| 91 : : //! \param[in,out] p Charm++'s PUP::er serializer object reference 92 : : //! \param[in,out] c CSR object reference - 93 : 279 : friend void operator|( PUP::er& p, CSR& c ) { c.pup(p); } + 93 : 273 : friend void operator|( PUP::er& p, CSR& c ) { c.pup(p); } 94 : : ///@} 95 : : 96 : : private: diff --git a/Debug/test_coverage/LinearSolver/ConjugateGradients.cpp.func-sort-c.html b/Debug/test_coverage/LinearSolver/ConjugateGradients.cpp.func-sort-c.html index 699eb4d40832..6314c24860ad 100644 --- a/Debug/test_coverage/LinearSolver/ConjugateGradients.cpp.func-sort-c.html +++ b/Debug/test_coverage/LinearSolver/ConjugateGradients.cpp.func-sort-c.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:43:41 + 2024-07-11 15:06:04 Functions: 20 diff --git a/Debug/test_coverage/LinearSolver/ConjugateGradients.cpp.func.html b/Debug/test_coverage/LinearSolver/ConjugateGradients.cpp.func.html index c004391b6e8a..e8005b764c07 100644 --- a/Debug/test_coverage/LinearSolver/ConjugateGradients.cpp.func.html +++ b/Debug/test_coverage/LinearSolver/ConjugateGradients.cpp.func.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:43:41 + 2024-07-11 15:06:04 Functions: 20 diff --git a/Debug/test_coverage/LinearSolver/ConjugateGradients.cpp.gcov.html b/Debug/test_coverage/LinearSolver/ConjugateGradients.cpp.gcov.html index fa73845983f6..2613e617b52d 100644 --- a/Debug/test_coverage/LinearSolver/ConjugateGradients.cpp.gcov.html +++ b/Debug/test_coverage/LinearSolver/ConjugateGradients.cpp.gcov.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:43:41 + 2024-07-11 15:06:04 Functions: 20 diff --git a/Debug/test_coverage/LinearSolver/ConjugateGradients.hpp.func-sort-c.html b/Debug/test_coverage/LinearSolver/ConjugateGradients.hpp.func-sort-c.html index 080e807e380a..66dd985ebe4f 100644 --- a/Debug/test_coverage/LinearSolver/ConjugateGradients.hpp.func-sort-c.html +++ b/Debug/test_coverage/LinearSolver/ConjugateGradients.hpp.func-sort-c.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:43:41 + 2024-07-11 15:06:04 Functions: 5 @@ -77,11 +77,11 @@ tk::ConjugateGradients::ConjugateGradients(CkMigrateMessage*) - 59 + 57 tk::ConjugateGradients::pup(PUP::er&) - 198 + 192 tk::ConjugateGradients::solution() const diff --git a/Debug/test_coverage/LinearSolver/ConjugateGradients.hpp.func.html b/Debug/test_coverage/LinearSolver/ConjugateGradients.hpp.func.html index 70133a5e3f23..d48f90631f0b 100644 --- a/Debug/test_coverage/LinearSolver/ConjugateGradients.hpp.func.html +++ b/Debug/test_coverage/LinearSolver/ConjugateGradients.hpp.func.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:43:41 + 2024-07-11 15:06:04 Functions: 5 @@ -73,7 +73,7 @@ tk::ConjugateGradients::pup(PUP::er&) - 198 + 192 tk::ConjugateGradients::ConjugateGradients(std::tuple<tk::CSR, std::vector<double, std::allocator<double> >, std::vector<double, std::allocator<double> > >&&, std::vector<unsigned long, std::allocator<unsigned long> > const&, std::unordered_map<unsigned long, unsigned long, std::hash<unsigned long>, std::equal_to<unsigned long>, std::allocator<std::pair<unsigned long const, unsigned long> > > const&, std::unordered_map<int, std::unordered_set<unsigned long, std::hash<unsigned long>, std::equal_to<unsigned long>, std::allocator<unsigned long> >, std::hash<int>, std::equal_to<int>, std::allocator<std::pair<int const, std::unordered_set<unsigned long, std::hash<unsigned long>, std::equal_to<unsigned long>, std::allocator<unsigned long> > > > > const&) @@ -81,7 +81,7 @@ tk::ConjugateGradients::ConjugateGradients(CkMigrateMessage*) - 59 + 57 tk::ConjugateGradients::solution() const diff --git a/Debug/test_coverage/LinearSolver/ConjugateGradients.hpp.gcov.html b/Debug/test_coverage/LinearSolver/ConjugateGradients.hpp.gcov.html index 70f0264bedaa..48ead760fb05 100644 --- a/Debug/test_coverage/LinearSolver/ConjugateGradients.hpp.gcov.html +++ b/Debug/test_coverage/LinearSolver/ConjugateGradients.hpp.gcov.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:43:41 + 2024-07-11 15:06:04 Functions: 5 @@ -150,7 +150,7 @@ 76 : 21 : gid, lid, nodecommmap ) {} 77 : : 78 : : //! Migrate constructor - 79 : 59 : explicit ConjugateGradients( CkMigrateMessage* ) {} + 79 : 57 : explicit ConjugateGradients( CkMigrateMessage* ) {} 80 : : #if defined(__clang__) 81 : : #pragma clang diagnostic pop 82 : : #endif @@ -206,37 +206,37 @@ 132 : : ///@{ 133 : : //! \brief Pack/Unpack serialize member function 134 : : //! \param[in,out] p Charm++'s PUP::er serializer object reference - 135 : 198 : void pup( PUP::er &p ) override { - 136 : 198 : p | m_A; - 137 : 198 : p | m_x; - 138 : 198 : p | m_b; - 139 : 198 : p | m_gid; - 140 : 198 : p | m_lid; - 141 : 198 : p | m_nodeCommMap; - 142 : 198 : p | m_r; - 143 : 198 : p | m_rc; - 144 : 198 : p | m_nr; - 145 : 198 : p | m_bc; - 146 : 198 : p | m_bcc; - 147 : 198 : p | m_bcmask; - 148 : 198 : p | m_nb; - 149 : 198 : p | m_p; - 150 : 198 : p | m_q; - 151 : 198 : p | m_qc; - 152 : 198 : p | m_nq; - 153 : 198 : p | m_initres; - 154 : 198 : p | m_solved; - 155 : 198 : p | m_normb; - 156 : 198 : p | m_it; - 157 : 198 : p | m_maxit; - 158 : 198 : p | m_tol; - 159 : 198 : p | m_rho; - 160 : 198 : p | m_rho0; - 161 : 198 : p | m_alpha; - 162 : 198 : p | m_converged; - 163 : 198 : p | m_xc; - 164 : 198 : p | m_nx; - 165 : 198 : } + 135 : 192 : void pup( PUP::er &p ) override { + 136 : 192 : p | m_A; + 137 : 192 : p | m_x; + 138 : 192 : p | m_b; + 139 : 192 : p | m_gid; + 140 : 192 : p | m_lid; + 141 : 192 : p | m_nodeCommMap; + 142 : 192 : p | m_r; + 143 : 192 : p | m_rc; + 144 : 192 : p | m_nr; + 145 : 192 : p | m_bc; + 146 : 192 : p | m_bcc; + 147 : 192 : p | m_bcmask; + 148 : 192 : p | m_nb; + 149 : 192 : p | m_p; + 150 : 192 : p | m_q; + 151 : 192 : p | m_qc; + 152 : 192 : p | m_nq; + 153 : 192 : p | m_initres; + 154 : 192 : p | m_solved; + 155 : 192 : p | m_normb; + 156 : 192 : p | m_it; + 157 : 192 : p | m_maxit; + 158 : 192 : p | m_tol; + 159 : 192 : p | m_rho; + 160 : 192 : p | m_rho0; + 161 : 192 : p | m_alpha; + 162 : 192 : p | m_converged; + 163 : 192 : p | m_xc; + 164 : 192 : p | m_nx; + 165 : 192 : } 166 : : //! \brief Pack/Unpack serialize operator| 167 : : //! \param[in,out] p Charm++'s PUP::er serializer object reference 168 : : //! \param[in,out] c ConjugateGradients object reference diff --git a/Debug/test_coverage/LinearSolver/conjugategradients.ci.func-sort-c.html b/Debug/test_coverage/LinearSolver/conjugategradients.ci.func-sort-c.html index 67b907776265..29de81a3a30a 100644 --- a/Debug/test_coverage/LinearSolver/conjugategradients.ci.func-sort-c.html +++ b/Debug/test_coverage/LinearSolver/conjugategradients.ci.func-sort-c.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:43:41 + 2024-07-11 15:06:04 Functions: 0 diff --git a/Debug/test_coverage/LinearSolver/conjugategradients.ci.func.html b/Debug/test_coverage/LinearSolver/conjugategradients.ci.func.html index ed41271cc772..23f22322b7e0 100644 --- a/Debug/test_coverage/LinearSolver/conjugategradients.ci.func.html +++ b/Debug/test_coverage/LinearSolver/conjugategradients.ci.func.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:43:41 + 2024-07-11 15:06:04 Functions: 0 diff --git a/Debug/test_coverage/LinearSolver/conjugategradients.ci.gcov.html b/Debug/test_coverage/LinearSolver/conjugategradients.ci.gcov.html index 166bc96c23ea..4ff2c3d00de7 100644 --- a/Debug/test_coverage/LinearSolver/conjugategradients.ci.gcov.html +++ b/Debug/test_coverage/LinearSolver/conjugategradients.ci.gcov.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:43:41 + 2024-07-11 15:06:04 Functions: 0 diff --git a/Debug/test_coverage/LinearSolver/index-sort-b.html b/Debug/test_coverage/LinearSolver/index-sort-b.html index e68757e0b39d..0c15f06963e9 100644 --- a/Debug/test_coverage/LinearSolver/index-sort-b.html +++ b/Debug/test_coverage/LinearSolver/index-sort-b.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:43:41 + 2024-07-11 15:06:04 Functions: 39 diff --git a/Debug/test_coverage/LinearSolver/index-sort-f.html b/Debug/test_coverage/LinearSolver/index-sort-f.html index 919d8e79a960..23b51ecd2217 100644 --- a/Debug/test_coverage/LinearSolver/index-sort-f.html +++ b/Debug/test_coverage/LinearSolver/index-sort-f.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:43:41 + 2024-07-11 15:06:04 Functions: 39 diff --git a/Debug/test_coverage/LinearSolver/index-sort-l.html b/Debug/test_coverage/LinearSolver/index-sort-l.html index d0fbbef97211..770929a7a969 100644 --- a/Debug/test_coverage/LinearSolver/index-sort-l.html +++ b/Debug/test_coverage/LinearSolver/index-sort-l.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:43:41 + 2024-07-11 15:06:04 Functions: 39 diff --git a/Debug/test_coverage/LinearSolver/index.html b/Debug/test_coverage/LinearSolver/index.html index 1e69961623b9..92c0cd9cb992 100644 --- a/Debug/test_coverage/LinearSolver/index.html +++ b/Debug/test_coverage/LinearSolver/index.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:43:41 + 2024-07-11 15:06:04 Functions: 39 diff --git a/Debug/test_coverage/LoadBalance/LinearMap.cpp.func-sort-c.html b/Debug/test_coverage/LoadBalance/LinearMap.cpp.func-sort-c.html index e3bc363dd6ec..434ab717c656 100644 --- a/Debug/test_coverage/LoadBalance/LinearMap.cpp.func-sort-c.html +++ b/Debug/test_coverage/LoadBalance/LinearMap.cpp.func-sort-c.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:43:41 + 2024-07-11 15:06:04 Functions: 2 diff --git a/Debug/test_coverage/LoadBalance/LinearMap.cpp.func.html b/Debug/test_coverage/LoadBalance/LinearMap.cpp.func.html index 474f5a48a834..a1fcaf580adc 100644 --- a/Debug/test_coverage/LoadBalance/LinearMap.cpp.func.html +++ b/Debug/test_coverage/LoadBalance/LinearMap.cpp.func.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:43:41 + 2024-07-11 15:06:04 Functions: 2 diff --git a/Debug/test_coverage/LoadBalance/LinearMap.cpp.gcov.html b/Debug/test_coverage/LoadBalance/LinearMap.cpp.gcov.html index 47e487c5f560..3c8b89c23c17 100644 --- a/Debug/test_coverage/LoadBalance/LinearMap.cpp.gcov.html +++ b/Debug/test_coverage/LoadBalance/LinearMap.cpp.gcov.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:43:41 + 2024-07-11 15:06:04 Functions: 2 diff --git a/Debug/test_coverage/LoadBalance/LinearMap.hpp.func-sort-c.html b/Debug/test_coverage/LoadBalance/LinearMap.hpp.func-sort-c.html index 5ec926d311af..1a3a67cf19d7 100644 --- a/Debug/test_coverage/LoadBalance/LinearMap.hpp.func-sort-c.html +++ b/Debug/test_coverage/LoadBalance/LinearMap.hpp.func-sort-c.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:43:41 + 2024-07-11 15:06:04 Functions: 1 diff --git a/Debug/test_coverage/LoadBalance/LinearMap.hpp.func.html b/Debug/test_coverage/LoadBalance/LinearMap.hpp.func.html index ba4962edd9a4..ad806008877a 100644 --- a/Debug/test_coverage/LoadBalance/LinearMap.hpp.func.html +++ b/Debug/test_coverage/LoadBalance/LinearMap.hpp.func.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:43:41 + 2024-07-11 15:06:04 Functions: 1 diff --git a/Debug/test_coverage/LoadBalance/LinearMap.hpp.gcov.html b/Debug/test_coverage/LoadBalance/LinearMap.hpp.gcov.html index 78857c72d246..3259bdca0645 100644 --- a/Debug/test_coverage/LoadBalance/LinearMap.hpp.gcov.html +++ b/Debug/test_coverage/LoadBalance/LinearMap.hpp.gcov.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:43:41 + 2024-07-11 15:06:04 Functions: 1 diff --git a/Debug/test_coverage/LoadBalance/UnsMeshMap.cpp.func-sort-c.html b/Debug/test_coverage/LoadBalance/UnsMeshMap.cpp.func-sort-c.html index 19261119bb7e..2c2077bd4321 100644 --- a/Debug/test_coverage/LoadBalance/UnsMeshMap.cpp.func-sort-c.html +++ b/Debug/test_coverage/LoadBalance/UnsMeshMap.cpp.func-sort-c.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:43:41 + 2024-07-11 15:06:04 Functions: 5 diff --git a/Debug/test_coverage/LoadBalance/UnsMeshMap.cpp.func.html b/Debug/test_coverage/LoadBalance/UnsMeshMap.cpp.func.html index ae44e03627a4..79b95dd49ad7 100644 --- a/Debug/test_coverage/LoadBalance/UnsMeshMap.cpp.func.html +++ b/Debug/test_coverage/LoadBalance/UnsMeshMap.cpp.func.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:43:41 + 2024-07-11 15:06:04 Functions: 5 diff --git a/Debug/test_coverage/LoadBalance/UnsMeshMap.cpp.gcov.html b/Debug/test_coverage/LoadBalance/UnsMeshMap.cpp.gcov.html index 274c04937f60..7ca5931b5efb 100644 --- a/Debug/test_coverage/LoadBalance/UnsMeshMap.cpp.gcov.html +++ b/Debug/test_coverage/LoadBalance/UnsMeshMap.cpp.gcov.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:43:41 + 2024-07-11 15:06:04 Functions: 5 diff --git a/Debug/test_coverage/LoadBalance/ZoltanInterOp.cpp.func-sort-c.html b/Debug/test_coverage/LoadBalance/ZoltanInterOp.cpp.func-sort-c.html index f72ed6becd09..c30f6a6d0110 100644 --- a/Debug/test_coverage/LoadBalance/ZoltanInterOp.cpp.func-sort-c.html +++ b/Debug/test_coverage/LoadBalance/ZoltanInterOp.cpp.func-sort-c.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:43:41 + 2024-07-11 15:06:04 Functions: 6 diff --git a/Debug/test_coverage/LoadBalance/ZoltanInterOp.cpp.func.html b/Debug/test_coverage/LoadBalance/ZoltanInterOp.cpp.func.html index 0db3d8ef5d5d..bc89d03ee592 100644 --- a/Debug/test_coverage/LoadBalance/ZoltanInterOp.cpp.func.html +++ b/Debug/test_coverage/LoadBalance/ZoltanInterOp.cpp.func.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:43:41 + 2024-07-11 15:06:04 Functions: 6 diff --git a/Debug/test_coverage/LoadBalance/ZoltanInterOp.cpp.gcov.html b/Debug/test_coverage/LoadBalance/ZoltanInterOp.cpp.gcov.html index d3994713238a..49c9e4e6ff85 100644 --- a/Debug/test_coverage/LoadBalance/ZoltanInterOp.cpp.gcov.html +++ b/Debug/test_coverage/LoadBalance/ZoltanInterOp.cpp.gcov.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:43:41 + 2024-07-11 15:06:04 Functions: 6 diff --git a/Debug/test_coverage/LoadBalance/index-sort-b.html b/Debug/test_coverage/LoadBalance/index-sort-b.html index 7f2deaf1e15c..ab9d7193b038 100644 --- a/Debug/test_coverage/LoadBalance/index-sort-b.html +++ b/Debug/test_coverage/LoadBalance/index-sort-b.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:43:41 + 2024-07-11 15:06:04 Functions: 14 diff --git a/Debug/test_coverage/LoadBalance/index-sort-f.html b/Debug/test_coverage/LoadBalance/index-sort-f.html index 0b499b3ef1a4..cc00ae1a876e 100644 --- a/Debug/test_coverage/LoadBalance/index-sort-f.html +++ b/Debug/test_coverage/LoadBalance/index-sort-f.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:43:41 + 2024-07-11 15:06:04 Functions: 14 diff --git a/Debug/test_coverage/LoadBalance/index-sort-l.html b/Debug/test_coverage/LoadBalance/index-sort-l.html index f436cb98773c..d5a535597e1a 100644 --- a/Debug/test_coverage/LoadBalance/index-sort-l.html +++ b/Debug/test_coverage/LoadBalance/index-sort-l.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:43:41 + 2024-07-11 15:06:04 Functions: 14 diff --git a/Debug/test_coverage/LoadBalance/index.html b/Debug/test_coverage/LoadBalance/index.html index 2894fb03e4f0..2d6566bd1a0b 100644 --- a/Debug/test_coverage/LoadBalance/index.html +++ b/Debug/test_coverage/LoadBalance/index.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:43:41 + 2024-07-11 15:06:04 Functions: 14 diff --git a/Debug/test_coverage/Main/Inciter.cpp.func-sort-c.html b/Debug/test_coverage/Main/Inciter.cpp.func-sort-c.html index d23e1df9bd99..9eeb081f7544 100644 --- a/Debug/test_coverage/Main/Inciter.cpp.func-sort-c.html +++ b/Debug/test_coverage/Main/Inciter.cpp.func-sort-c.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:43:41 + 2024-07-11 15:06:04 Functions: 11 diff --git a/Debug/test_coverage/Main/Inciter.cpp.func.html b/Debug/test_coverage/Main/Inciter.cpp.func.html index 9bc9cf3a4e39..edd47891cd85 100644 --- a/Debug/test_coverage/Main/Inciter.cpp.func.html +++ b/Debug/test_coverage/Main/Inciter.cpp.func.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:43:41 + 2024-07-11 15:06:04 Functions: 11 diff --git a/Debug/test_coverage/Main/Inciter.cpp.gcov.html b/Debug/test_coverage/Main/Inciter.cpp.gcov.html index c545905de987..27cb9c82b55c 100644 --- a/Debug/test_coverage/Main/Inciter.cpp.gcov.html +++ b/Debug/test_coverage/Main/Inciter.cpp.gcov.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:43:41 + 2024-07-11 15:06:04 Functions: 11 diff --git a/Debug/test_coverage/Main/InciterDriver.cpp.func-sort-c.html b/Debug/test_coverage/Main/InciterDriver.cpp.func-sort-c.html index 301ffd261d04..a9637461af6e 100644 --- a/Debug/test_coverage/Main/InciterDriver.cpp.func-sort-c.html +++ b/Debug/test_coverage/Main/InciterDriver.cpp.func-sort-c.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:43:41 + 2024-07-11 15:06:04 Functions: 2 diff --git a/Debug/test_coverage/Main/InciterDriver.cpp.func.html b/Debug/test_coverage/Main/InciterDriver.cpp.func.html index dc7a8771a340..c7bcd5ac039d 100644 --- a/Debug/test_coverage/Main/InciterDriver.cpp.func.html +++ b/Debug/test_coverage/Main/InciterDriver.cpp.func.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:43:41 + 2024-07-11 15:06:04 Functions: 2 diff --git a/Debug/test_coverage/Main/InciterDriver.cpp.gcov.html b/Debug/test_coverage/Main/InciterDriver.cpp.gcov.html index a59192da967d..50a820fa0b02 100644 --- a/Debug/test_coverage/Main/InciterDriver.cpp.gcov.html +++ b/Debug/test_coverage/Main/InciterDriver.cpp.gcov.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:43:41 + 2024-07-11 15:06:04 Functions: 2 diff --git a/Debug/test_coverage/Main/InciterPrint.cpp.func-sort-c.html b/Debug/test_coverage/Main/InciterPrint.cpp.func-sort-c.html index 6445f6bbfb16..c0a110ad2ed8 100644 --- a/Debug/test_coverage/Main/InciterPrint.cpp.func-sort-c.html +++ b/Debug/test_coverage/Main/InciterPrint.cpp.func-sort-c.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:43:41 + 2024-07-11 15:06:04 Functions: 2 diff --git a/Debug/test_coverage/Main/InciterPrint.cpp.func.html b/Debug/test_coverage/Main/InciterPrint.cpp.func.html index b7b502f1c599..e7d1497de54d 100644 --- a/Debug/test_coverage/Main/InciterPrint.cpp.func.html +++ b/Debug/test_coverage/Main/InciterPrint.cpp.func.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:43:41 + 2024-07-11 15:06:04 Functions: 2 diff --git a/Debug/test_coverage/Main/InciterPrint.cpp.gcov.html b/Debug/test_coverage/Main/InciterPrint.cpp.gcov.html index 6bc410f8a94d..84277fce487c 100644 --- a/Debug/test_coverage/Main/InciterPrint.cpp.gcov.html +++ b/Debug/test_coverage/Main/InciterPrint.cpp.gcov.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:43:41 + 2024-07-11 15:06:04 Functions: 2 diff --git a/Debug/test_coverage/Main/InciterPrint.hpp.func-sort-c.html b/Debug/test_coverage/Main/InciterPrint.hpp.func-sort-c.html index fdb6f56193bd..1b93708813ab 100644 --- a/Debug/test_coverage/Main/InciterPrint.hpp.func-sort-c.html +++ b/Debug/test_coverage/Main/InciterPrint.hpp.func-sort-c.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:43:41 + 2024-07-11 15:06:04 Functions: 11 diff --git a/Debug/test_coverage/Main/InciterPrint.hpp.func.html b/Debug/test_coverage/Main/InciterPrint.hpp.func.html index 125defc40851..a1a2c9ac2b3b 100644 --- a/Debug/test_coverage/Main/InciterPrint.hpp.func.html +++ b/Debug/test_coverage/Main/InciterPrint.hpp.func.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:43:41 + 2024-07-11 15:06:04 Functions: 11 diff --git a/Debug/test_coverage/Main/InciterPrint.hpp.gcov.html b/Debug/test_coverage/Main/InciterPrint.hpp.gcov.html index fb4e6bdb58d1..e193bff65b39 100644 --- a/Debug/test_coverage/Main/InciterPrint.hpp.gcov.html +++ b/Debug/test_coverage/Main/InciterPrint.hpp.gcov.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:43:41 + 2024-07-11 15:06:04 Functions: 11 diff --git a/Debug/test_coverage/Main/Init.cpp.func-sort-c.html b/Debug/test_coverage/Main/Init.cpp.func-sort-c.html index 8721ab80fe32..41adc05b0f0c 100644 --- a/Debug/test_coverage/Main/Init.cpp.func-sort-c.html +++ b/Debug/test_coverage/Main/Init.cpp.func-sort-c.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:43:41 + 2024-07-11 15:06:04 Functions: 5 diff --git a/Debug/test_coverage/Main/Init.cpp.func.html b/Debug/test_coverage/Main/Init.cpp.func.html index d6d307cc37a2..6d047d6220a1 100644 --- a/Debug/test_coverage/Main/Init.cpp.func.html +++ b/Debug/test_coverage/Main/Init.cpp.func.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:43:41 + 2024-07-11 15:06:04 Functions: 5 diff --git a/Debug/test_coverage/Main/Init.cpp.gcov.html b/Debug/test_coverage/Main/Init.cpp.gcov.html index 2905c96e3683..62df0718df02 100644 --- a/Debug/test_coverage/Main/Init.cpp.gcov.html +++ b/Debug/test_coverage/Main/Init.cpp.gcov.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:43:41 + 2024-07-11 15:06:04 Functions: 5 diff --git a/Debug/test_coverage/Main/Init.hpp.func-sort-c.html b/Debug/test_coverage/Main/Init.hpp.func-sort-c.html index 9ea5cc93ac6d..9b2daa49c1df 100644 --- a/Debug/test_coverage/Main/Init.hpp.func-sort-c.html +++ b/Debug/test_coverage/Main/Init.hpp.func-sort-c.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:43:41 + 2024-07-11 15:06:04 Functions: 11 diff --git a/Debug/test_coverage/Main/Init.hpp.func.html b/Debug/test_coverage/Main/Init.hpp.func.html index c9c5e4836191..e6a1a306c39b 100644 --- a/Debug/test_coverage/Main/Init.hpp.func.html +++ b/Debug/test_coverage/Main/Init.hpp.func.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:43:41 + 2024-07-11 15:06:04 Functions: 11 diff --git a/Debug/test_coverage/Main/Init.hpp.gcov.html b/Debug/test_coverage/Main/Init.hpp.gcov.html index 5b1ccdcd87ce..f7afeed9580a 100644 --- a/Debug/test_coverage/Main/Init.hpp.gcov.html +++ b/Debug/test_coverage/Main/Init.hpp.gcov.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:43:41 + 2024-07-11 15:06:04 Functions: 11 diff --git a/Debug/test_coverage/Main/LBSwitch.cpp.func-sort-c.html b/Debug/test_coverage/Main/LBSwitch.cpp.func-sort-c.html index b64ed6fd8d3f..af6fd70d994f 100644 --- a/Debug/test_coverage/Main/LBSwitch.cpp.func-sort-c.html +++ b/Debug/test_coverage/Main/LBSwitch.cpp.func-sort-c.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:43:41 + 2024-07-11 15:06:04 Functions: 2 diff --git a/Debug/test_coverage/Main/LBSwitch.cpp.func.html b/Debug/test_coverage/Main/LBSwitch.cpp.func.html index 876aadfc086c..6a72a13413ee 100644 --- a/Debug/test_coverage/Main/LBSwitch.cpp.func.html +++ b/Debug/test_coverage/Main/LBSwitch.cpp.func.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:43:41 + 2024-07-11 15:06:04 Functions: 2 diff --git a/Debug/test_coverage/Main/LBSwitch.cpp.gcov.html b/Debug/test_coverage/Main/LBSwitch.cpp.gcov.html index 60985f30ec87..5426696c6e1d 100644 --- a/Debug/test_coverage/Main/LBSwitch.cpp.gcov.html +++ b/Debug/test_coverage/Main/LBSwitch.cpp.gcov.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:43:41 + 2024-07-11 15:06:04 Functions: 2 diff --git a/Debug/test_coverage/Main/LBSwitch.hpp.func-sort-c.html b/Debug/test_coverage/Main/LBSwitch.hpp.func-sort-c.html index c48cac5bf849..d0bca86dccba 100644 --- a/Debug/test_coverage/Main/LBSwitch.hpp.func-sort-c.html +++ b/Debug/test_coverage/Main/LBSwitch.hpp.func-sort-c.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:43:41 + 2024-07-11 15:06:04 Functions: 1 diff --git a/Debug/test_coverage/Main/LBSwitch.hpp.func.html b/Debug/test_coverage/Main/LBSwitch.hpp.func.html index a9f038c11839..bd461fe8b552 100644 --- a/Debug/test_coverage/Main/LBSwitch.hpp.func.html +++ b/Debug/test_coverage/Main/LBSwitch.hpp.func.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:43:41 + 2024-07-11 15:06:04 Functions: 1 diff --git a/Debug/test_coverage/Main/LBSwitch.hpp.gcov.html b/Debug/test_coverage/Main/LBSwitch.hpp.gcov.html index 348d0405a88b..d1453983eb8d 100644 --- a/Debug/test_coverage/Main/LBSwitch.hpp.gcov.html +++ b/Debug/test_coverage/Main/LBSwitch.hpp.gcov.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:43:41 + 2024-07-11 15:06:04 Functions: 1 diff --git a/Debug/test_coverage/Main/MeshConv.cpp.func-sort-c.html b/Debug/test_coverage/Main/MeshConv.cpp.func-sort-c.html index a3695fc34adb..615a3e2e3f0e 100644 --- a/Debug/test_coverage/Main/MeshConv.cpp.func-sort-c.html +++ b/Debug/test_coverage/Main/MeshConv.cpp.func-sort-c.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:43:41 + 2024-07-11 15:06:04 Functions: 7 diff --git a/Debug/test_coverage/Main/MeshConv.cpp.func.html b/Debug/test_coverage/Main/MeshConv.cpp.func.html index 6b577d8e09de..42f934086a72 100644 --- a/Debug/test_coverage/Main/MeshConv.cpp.func.html +++ b/Debug/test_coverage/Main/MeshConv.cpp.func.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:43:41 + 2024-07-11 15:06:04 Functions: 7 diff --git a/Debug/test_coverage/Main/MeshConv.cpp.gcov.html b/Debug/test_coverage/Main/MeshConv.cpp.gcov.html index 923851618b55..9a9a48738b50 100644 --- a/Debug/test_coverage/Main/MeshConv.cpp.gcov.html +++ b/Debug/test_coverage/Main/MeshConv.cpp.gcov.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:43:41 + 2024-07-11 15:06:04 Functions: 7 diff --git a/Debug/test_coverage/Main/MeshConvDriver.cpp.func-sort-c.html b/Debug/test_coverage/Main/MeshConvDriver.cpp.func-sort-c.html index a3ceeff8df2a..41cc4b8e5581 100644 --- a/Debug/test_coverage/Main/MeshConvDriver.cpp.func-sort-c.html +++ b/Debug/test_coverage/Main/MeshConvDriver.cpp.func-sort-c.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:43:41 + 2024-07-11 15:06:04 Functions: 3 diff --git a/Debug/test_coverage/Main/MeshConvDriver.cpp.func.html b/Debug/test_coverage/Main/MeshConvDriver.cpp.func.html index 030418d1ea9f..34d468d93eab 100644 --- a/Debug/test_coverage/Main/MeshConvDriver.cpp.func.html +++ b/Debug/test_coverage/Main/MeshConvDriver.cpp.func.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:43:41 + 2024-07-11 15:06:04 Functions: 3 diff --git a/Debug/test_coverage/Main/MeshConvDriver.cpp.gcov.html b/Debug/test_coverage/Main/MeshConvDriver.cpp.gcov.html index d537bb09ed43..f491927c0c0d 100644 --- a/Debug/test_coverage/Main/MeshConvDriver.cpp.gcov.html +++ b/Debug/test_coverage/Main/MeshConvDriver.cpp.gcov.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:43:41 + 2024-07-11 15:06:04 Functions: 3 diff --git a/Debug/test_coverage/Main/UnitTest.cpp.func-sort-c.html b/Debug/test_coverage/Main/UnitTest.cpp.func-sort-c.html index 1a02796c7ce3..96ba0e4db484 100644 --- a/Debug/test_coverage/Main/UnitTest.cpp.func-sort-c.html +++ b/Debug/test_coverage/Main/UnitTest.cpp.func-sort-c.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:43:41 + 2024-07-11 15:06:04 Functions: 5 diff --git a/Debug/test_coverage/Main/UnitTest.cpp.func.html b/Debug/test_coverage/Main/UnitTest.cpp.func.html index ae6c314d7f70..6420cbdcdccc 100644 --- a/Debug/test_coverage/Main/UnitTest.cpp.func.html +++ b/Debug/test_coverage/Main/UnitTest.cpp.func.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:43:41 + 2024-07-11 15:06:04 Functions: 5 diff --git a/Debug/test_coverage/Main/UnitTest.cpp.gcov.html b/Debug/test_coverage/Main/UnitTest.cpp.gcov.html index cb70a322cffa..5a0555d27526 100644 --- a/Debug/test_coverage/Main/UnitTest.cpp.gcov.html +++ b/Debug/test_coverage/Main/UnitTest.cpp.gcov.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:43:41 + 2024-07-11 15:06:04 Functions: 5 diff --git a/Debug/test_coverage/Main/UnitTestDriver.cpp.func-sort-c.html b/Debug/test_coverage/Main/UnitTestDriver.cpp.func-sort-c.html index c1914bd7240a..7a555cf0946d 100644 --- a/Debug/test_coverage/Main/UnitTestDriver.cpp.func-sort-c.html +++ b/Debug/test_coverage/Main/UnitTestDriver.cpp.func-sort-c.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:43:41 + 2024-07-11 15:06:04 Functions: 1 diff --git a/Debug/test_coverage/Main/UnitTestDriver.cpp.func.html b/Debug/test_coverage/Main/UnitTestDriver.cpp.func.html index 15c98c8be01b..193445826e8a 100644 --- a/Debug/test_coverage/Main/UnitTestDriver.cpp.func.html +++ b/Debug/test_coverage/Main/UnitTestDriver.cpp.func.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:43:41 + 2024-07-11 15:06:04 Functions: 1 diff --git a/Debug/test_coverage/Main/UnitTestDriver.cpp.gcov.html b/Debug/test_coverage/Main/UnitTestDriver.cpp.gcov.html index e35245b54b73..9639f072143b 100644 --- a/Debug/test_coverage/Main/UnitTestDriver.cpp.gcov.html +++ b/Debug/test_coverage/Main/UnitTestDriver.cpp.gcov.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:43:41 + 2024-07-11 15:06:04 Functions: 1 diff --git a/Debug/test_coverage/Main/UnitTestDriver.hpp.func-sort-c.html b/Debug/test_coverage/Main/UnitTestDriver.hpp.func-sort-c.html index 084a3c449f17..a74f63d29ca3 100644 --- a/Debug/test_coverage/Main/UnitTestDriver.hpp.func-sort-c.html +++ b/Debug/test_coverage/Main/UnitTestDriver.hpp.func-sort-c.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:43:41 + 2024-07-11 15:06:04 Functions: 1 diff --git a/Debug/test_coverage/Main/UnitTestDriver.hpp.func.html b/Debug/test_coverage/Main/UnitTestDriver.hpp.func.html index 3179d9aadede..d33fbf9cf1bb 100644 --- a/Debug/test_coverage/Main/UnitTestDriver.hpp.func.html +++ b/Debug/test_coverage/Main/UnitTestDriver.hpp.func.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:43:41 + 2024-07-11 15:06:04 Functions: 1 diff --git a/Debug/test_coverage/Main/UnitTestDriver.hpp.gcov.html b/Debug/test_coverage/Main/UnitTestDriver.hpp.gcov.html index 246db0a014b8..63a535805402 100644 --- a/Debug/test_coverage/Main/UnitTestDriver.hpp.gcov.html +++ b/Debug/test_coverage/Main/UnitTestDriver.hpp.gcov.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:43:41 + 2024-07-11 15:06:04 Functions: 1 diff --git a/Debug/test_coverage/Main/UnitTestPrint.hpp.func-sort-c.html b/Debug/test_coverage/Main/UnitTestPrint.hpp.func-sort-c.html index 021b6f8c00e3..204798e42fe8 100644 --- a/Debug/test_coverage/Main/UnitTestPrint.hpp.func-sort-c.html +++ b/Debug/test_coverage/Main/UnitTestPrint.hpp.func-sort-c.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:43:41 + 2024-07-11 15:06:04 Functions: 4 diff --git a/Debug/test_coverage/Main/UnitTestPrint.hpp.func.html b/Debug/test_coverage/Main/UnitTestPrint.hpp.func.html index 1c26bb115d9e..bf704b2792a7 100644 --- a/Debug/test_coverage/Main/UnitTestPrint.hpp.func.html +++ b/Debug/test_coverage/Main/UnitTestPrint.hpp.func.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:43:41 + 2024-07-11 15:06:04 Functions: 4 diff --git a/Debug/test_coverage/Main/UnitTestPrint.hpp.gcov.html b/Debug/test_coverage/Main/UnitTestPrint.hpp.gcov.html index 1f79bde00457..d7077c1a659b 100644 --- a/Debug/test_coverage/Main/UnitTestPrint.hpp.gcov.html +++ b/Debug/test_coverage/Main/UnitTestPrint.hpp.gcov.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:43:41 + 2024-07-11 15:06:04 Functions: 4 diff --git a/Debug/test_coverage/Main/index-sort-b.html b/Debug/test_coverage/Main/index-sort-b.html index 53650d0fcc44..f638e7590536 100644 --- a/Debug/test_coverage/Main/index-sort-b.html +++ b/Debug/test_coverage/Main/index-sort-b.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:43:41 + 2024-07-11 15:06:04 Functions: 66 @@ -226,7 +226,7 @@ 7 / 12 - UnitTestDriver.hpp + LBSwitch.hpp
100.0%
@@ -238,7 +238,7 @@ 0 / 0 - LBSwitch.hpp + UnitTestDriver.hpp
100.0%
diff --git a/Debug/test_coverage/Main/index-sort-f.html b/Debug/test_coverage/Main/index-sort-f.html index 35a8102ed1b1..1ad8af8ab3f7 100644 --- a/Debug/test_coverage/Main/index-sort-f.html +++ b/Debug/test_coverage/Main/index-sort-f.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:43:41 + 2024-07-11 15:06:04 Functions: 66 @@ -129,18 +129,6 @@ 41.7 % 30 / 72 - - Init.hpp - -
90.5%90.5%
- - 90.5 % - 38 / 42 - 91.7 % - 11 / 12 - 47.9 % - 46 / 96 - Inciter.cpp @@ -154,16 +142,28 @@ 49 / 104 - UnitTestDriver.cpp + Init.hpp + +
90.5%90.5%
+ + 90.5 % + 38 / 42 + 91.7 % + 11 / 12 + 47.9 % + 46 / 96 + + + LBSwitch.hpp
100.0%
100.0 % - 3 / 3 + 1 / 1 100.0 % 1 / 1 - 50.0 % - 1 / 2 + - + 0 / 0 UnitTestDriver.hpp @@ -178,16 +178,16 @@ 0 / 0 - LBSwitch.hpp + UnitTestDriver.cpp
100.0%
100.0 % - 1 / 1 + 3 / 3 100.0 % 1 / 1 - - - 0 / 0 + 50.0 % + 1 / 2 InciterDriver.cpp diff --git a/Debug/test_coverage/Main/index-sort-l.html b/Debug/test_coverage/Main/index-sort-l.html index af8ea98b264a..2d4581fc98d1 100644 --- a/Debug/test_coverage/Main/index-sort-l.html +++ b/Debug/test_coverage/Main/index-sort-l.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:43:41 + 2024-07-11 15:06:04 Functions: 66 @@ -190,7 +190,7 @@ 114 / 228 - UnitTestDriver.hpp + LBSwitch.hpp
100.0%
@@ -202,7 +202,7 @@ 0 / 0 - LBSwitch.hpp + UnitTestDriver.hpp
100.0%
diff --git a/Debug/test_coverage/Main/index.html b/Debug/test_coverage/Main/index.html index e6e1ee3d93a0..dd138edf27e9 100644 --- a/Debug/test_coverage/Main/index.html +++ b/Debug/test_coverage/Main/index.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:43:41 + 2024-07-11 15:06:04 Functions: 66 diff --git a/Debug/test_coverage/Mesh/Around.hpp.func-sort-c.html b/Debug/test_coverage/Mesh/Around.hpp.func-sort-c.html index 9a3358bc0f0c..a6c3fae243cf 100644 --- a/Debug/test_coverage/Mesh/Around.hpp.func-sort-c.html +++ b/Debug/test_coverage/Mesh/Around.hpp.func-sort-c.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:43:41 + 2024-07-11 15:06:04 Functions: 5 diff --git a/Debug/test_coverage/Mesh/Around.hpp.func.html b/Debug/test_coverage/Mesh/Around.hpp.func.html index c67280ffc761..b697f8f1f41f 100644 --- a/Debug/test_coverage/Mesh/Around.hpp.func.html +++ b/Debug/test_coverage/Mesh/Around.hpp.func.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:43:41 + 2024-07-11 15:06:04 Functions: 5 diff --git a/Debug/test_coverage/Mesh/Around.hpp.gcov.html b/Debug/test_coverage/Mesh/Around.hpp.gcov.html index 0cd255e90b0f..0c40ce14dbfb 100644 --- a/Debug/test_coverage/Mesh/Around.hpp.gcov.html +++ b/Debug/test_coverage/Mesh/Around.hpp.gcov.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:43:41 + 2024-07-11 15:06:04 Functions: 5 diff --git a/Debug/test_coverage/Mesh/CommMap.cpp.func-sort-c.html b/Debug/test_coverage/Mesh/CommMap.cpp.func-sort-c.html index a059b8eb6242..c62e77930dd0 100644 --- a/Debug/test_coverage/Mesh/CommMap.cpp.func-sort-c.html +++ b/Debug/test_coverage/Mesh/CommMap.cpp.func-sort-c.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:43:41 + 2024-07-11 15:06:04 Functions: 4 @@ -85,7 +85,7 @@ auto tk::slave(std::unordered_map<int, std::unordered_set<unsigned long, std::hash<unsigned long>, std::equal_to<unsigned long>, std::allocator<unsigned long> >, std::hash<int>, std::equal_to<int>, std::allocator<std::pair<int const, std::unordered_set<unsigned long, std::hash<unsigned long>, std::equal_to<unsigned long>, std::allocator<unsigned long> > > > > const&, unsigned long, int)::{lambda(auto:1 const&)#1}::operator()<std::pair<int const, std::unordered_set<unsigned long, std::hash<unsigned long>, std::equal_to<unsigned long>, std::allocator<unsigned long> > > >(std::pair<int const, std::unordered_set<unsigned long, std::hash<unsigned long>, std::equal_to<unsigned long>, std::allocator<unsigned long> > > const&) const - 20090799 + 20091139
diff --git a/Debug/test_coverage/Mesh/CommMap.cpp.func.html b/Debug/test_coverage/Mesh/CommMap.cpp.func.html index f7ffa60014cf..4774878e7117 100644 --- a/Debug/test_coverage/Mesh/CommMap.cpp.func.html +++ b/Debug/test_coverage/Mesh/CommMap.cpp.func.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:43:41 + 2024-07-11 15:06:04 Functions: 4 @@ -85,7 +85,7 @@ auto tk::slave(std::unordered_map<int, std::unordered_set<unsigned long, std::hash<unsigned long>, std::equal_to<unsigned long>, std::allocator<unsigned long> >, std::hash<int>, std::equal_to<int>, std::allocator<std::pair<int const, std::unordered_set<unsigned long, std::hash<unsigned long>, std::equal_to<unsigned long>, std::allocator<unsigned long> > > > > const&, unsigned long, int)::{lambda(auto:1 const&)#1}::operator()<std::pair<int const, std::unordered_set<unsigned long, std::hash<unsigned long>, std::equal_to<unsigned long>, std::allocator<unsigned long> > > >(std::pair<int const, std::unordered_set<unsigned long, std::hash<unsigned long>, std::equal_to<unsigned long>, std::allocator<unsigned long> > > const&) const - 20090799 + 20091139
diff --git a/Debug/test_coverage/Mesh/CommMap.cpp.gcov.html b/Debug/test_coverage/Mesh/CommMap.cpp.gcov.html index 624fcc3357b3..18bf9ca8656c 100644 --- a/Debug/test_coverage/Mesh/CommMap.cpp.gcov.html +++ b/Debug/test_coverage/Mesh/CommMap.cpp.gcov.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:43:41 + 2024-07-11 15:06:04 Functions: 4 @@ -105,8 +105,8 @@ 31 : : { 32 : : return 33 : 17886651 : std::any_of( map.cbegin(), map.cend(), - 34 : 20090799 : [&](const auto& s) { - 35 [ + - ][ + + ]: 37977450 : return s.second.find(node) != s.second.cend() && s.first > chare; } ); + 34 : 20091139 : [&](const auto& s) { + 35 [ + - ][ + + ]: 37977790 : return s.second.find(node) != s.second.cend() && s.first > chare; } ); [ + + ] 36 : : } 37 : : diff --git a/Debug/test_coverage/Mesh/DerivedData.cpp.func-sort-c.html b/Debug/test_coverage/Mesh/DerivedData.cpp.func-sort-c.html index cb3ecfd3720e..efe7a43fa72e 100644 --- a/Debug/test_coverage/Mesh/DerivedData.cpp.func-sort-c.html +++ b/Debug/test_coverage/Mesh/DerivedData.cpp.func-sort-c.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:43:41 + 2024-07-11 15:06:04 Functions: 30 @@ -177,15 +177,15 @@ tk::intet(std::array<std::vector<double, std::allocator<double> >, 3ul> const&, std::vector<unsigned long, std::allocator<unsigned long> > const&, std::vector<double, std::allocator<double> > const&, unsigned long, std::array<double, 4ul>&) - 3486022 + 3485988 tk::conforming(std::vector<unsigned long, std::allocator<unsigned long> > const&, std::array<std::vector<double, std::allocator<double> >, 3ul> const&, bool, std::vector<unsigned long, std::allocator<unsigned long> > const&)::CoordLess::operator()(std::array<double, 3ul> const&, std::array<double, 3ul> const&) const - 118763778 + 118759812 tk::genEsued(std::vector<unsigned long, std::allocator<unsigned long> > const&, unsigned long, std::pair<std::vector<unsigned long, std::allocator<unsigned long> >, std::vector<unsigned long, std::allocator<unsigned long> > > const&)::{lambda(unsigned long, unsigned long, unsigned long)#1}::operator()(unsigned long, unsigned long, unsigned long) const - 239506253 + 239489823 tk::orient(std::array<unsigned long, 2ul> const&, std::array<unsigned long, 2ul> const&) diff --git a/Debug/test_coverage/Mesh/DerivedData.cpp.func.html b/Debug/test_coverage/Mesh/DerivedData.cpp.func.html index 47f3fdc36625..6073fa69b077 100644 --- a/Debug/test_coverage/Mesh/DerivedData.cpp.func.html +++ b/Debug/test_coverage/Mesh/DerivedData.cpp.func.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:43:41 + 2024-07-11 15:06:04 Functions: 30 @@ -129,7 +129,7 @@ tk::intet(std::array<std::vector<double, std::allocator<double> >, 3ul> const&, std::vector<unsigned long, std::allocator<unsigned long> > const&, std::vector<double, std::allocator<double> > const&, unsigned long, std::array<double, 4ul>&) - 3486022 + 3485988 tk::normal(std::array<double, 3ul> const&, std::array<double, 3ul> const&, std::array<double, 3ul> const&) @@ -181,11 +181,11 @@ tk::conforming(std::vector<unsigned long, std::allocator<unsigned long> > const&, std::array<std::vector<double, std::allocator<double> >, 3ul> const&, bool, std::vector<unsigned long, std::allocator<unsigned long> > const&)::CoordLess::operator()(std::array<double, 3ul> const&, std::array<double, 3ul> const&) const - 118763778 + 118759812 tk::genEsued(std::vector<unsigned long, std::allocator<unsigned long> > const&, unsigned long, std::pair<std::vector<unsigned long, std::allocator<unsigned long> >, std::vector<unsigned long, std::allocator<unsigned long> > > const&)::{lambda(unsigned long, unsigned long, unsigned long)#1}::operator()(unsigned long, unsigned long, unsigned long) const - 239506253 + 239489823 tk::genEsuel(std::vector<unsigned long, std::allocator<unsigned long> > const&, unsigned long, std::pair<std::vector<unsigned long, std::allocator<unsigned long> >, std::vector<unsigned long, std::allocator<unsigned long> > > const&)::{lambda(unsigned long, unsigned long)#1}::operator()(unsigned long, unsigned long) const diff --git a/Debug/test_coverage/Mesh/DerivedData.cpp.gcov.html b/Debug/test_coverage/Mesh/DerivedData.cpp.gcov.html index a2d00b826412..918c213767c5 100644 --- a/Debug/test_coverage/Mesh/DerivedData.cpp.gcov.html +++ b/Debug/test_coverage/Mesh/DerivedData.cpp.gcov.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:43:41 + 2024-07-11 15:06:04 Functions: 30 @@ -927,12 +927,12 @@ 792 [ + - ]: 65756 : std::vector< std::size_t > lpoin( npoin, 0 ); 793 : : 794 : : // lambda that returns true if element e contains edge (p < q) - 795 : 3113580641 : auto has = [ &inpoel, nnpe ]( std::size_t e, std::size_t p, std::size_t q ) { - 796 : 239506253 : int sp = 0; - 797 [ + + ]: 1197531049 : for (std::size_t n=0; n<nnpe; ++n) - 798 [ + + ][ + + ]: 958024796 : if (inpoel[e*nnpe+n] == p || inpoel[e*nnpe+n] == q) ++sp; - [ + + ] - 799 : 239506253 : return sp == 2; + 795 : 3113367051 : auto has = [ &inpoel, nnpe ]( std::size_t e, std::size_t p, std::size_t q ) { + 796 : 239489823 : int sp = 0; + 797 [ + + ]: 1197448899 : for (std::size_t n=0; n<nnpe; ++n) + 798 [ + + ][ + + ]: 957959076 : if (inpoel[e*nnpe+n] == p || inpoel[e*nnpe+n] == q) ++sp; + [ + + ] + 799 : 239489823 : return sp == 2; 800 : 32878 : }; 801 : : 802 : : // map to associate edges to unique surrounding element ids @@ -947,9 +947,9 @@ 811 [ + + ][ + + ]: 162036296 : if (q != p && lpoin[q] != p+1) { [ + + ] 812 [ + + ]: 34539934 : if (p < q) { // for edge given point ids p < q - 813 [ + + ]: 256776220 : for (std::size_t j=esup2[p]+1; j<=esup2[p+1]; ++j ) { - 814 : 239506253 : auto e = esup1[j]; - 815 [ + + ][ + - ]: 239506253 : if (has(e,p,q)) esued[{p,q}].push_back(e); + 813 [ + + ]: 256759790 : for (std::size_t j=esup2[p]+1; j<=esup2[p+1]; ++j ) { + 814 : 239489823 : auto e = esup1[j]; + 815 [ + + ][ + - ]: 239489823 : if (has(e,p,q)) esued[{p,q}].push_back(e); [ + - ] 816 : : } 817 : : } @@ -1421,19 +1421,19 @@ 1267 : : } 1268 : : 1269 : : // loop over element cluster to find repeating elements - 1270 [ + - ]: 802855 : for(std::size_t i=0; i<elemcluster.size(); ++i) + 1270 [ + - ]: 804213 : for(std::size_t i=0; i<elemcluster.size(); ++i) 1271 : : { - 1272 : 802855 : auto ge = elemcluster[i]; - 1273 : 802855 : tag = 1; - 1274 [ + + ]: 27506145 : for(std::size_t j=0; j<elemcluster.size(); ++j) + 1272 : 804213 : auto ge = elemcluster[i]; + 1273 : 804213 : tag = 1; + 1274 [ + + ]: 27553766 : for(std::size_t j=0; j<elemcluster.size(); ++j) 1275 : : { - 1276 [ + + ][ + + ]: 26703290 : if ( i != j && elemcluster[j] == ge ) - [ + + ] + 1276 [ + + ][ + + ]: 26749553 : if ( i != j && elemcluster[j] == ge ) + [ + + ] 1277 : : { - 1278 : 483785 : tag++; + 1278 : 484111 : tag++; 1279 : : } 1280 : : } - 1281 [ + + ]: 802855 : if (tag == nnpf) + 1281 [ + + ]: 804213 : if (tag == nnpf) 1282 : : { 1283 : : // this is the required boundary element 1284 : 130728 : belem[f] = ge; @@ -1764,19 +1764,19 @@ 1599 : : // implemented as a lexicographic ordering. 1600 : : struct CoordLess { 1601 : : const real eps = std::numeric_limits< real >::epsilon(); - 1602 : 118763778 : bool operator() ( const Coord& lhs, const Coord& rhs ) const { - 1603 [ + + ]: 118763778 : if (lhs[0] < rhs[0]) - 1604 : 51856777 : return true; - 1605 [ + + ][ + + ]: 66907001 : else if (std::abs(lhs[0]-rhs[0]) < eps && lhs[1] < rhs[1]) - [ + + ] - 1606 : 5627033 : return true; - 1607 : 61279968 : else if (std::abs(lhs[0]-rhs[0]) < eps && - 1608 [ + + ][ + + ]: 74904482 : std::abs(lhs[1]-rhs[1]) < eps && - [ + + ] - 1609 [ + + ]: 13624514 : lhs[2] < rhs[2]) - 1610 : 794138 : return true; + 1602 : 118759812 : bool operator() ( const Coord& lhs, const Coord& rhs ) const { + 1603 [ + + ]: 118759812 : if (lhs[0] < rhs[0]) + 1604 : 51840914 : return true; + 1605 [ + + ][ + + ]: 66918898 : else if (std::abs(lhs[0]-rhs[0]) < eps && lhs[1] < rhs[1]) + [ + + ] + 1606 : 5630054 : return true; + 1607 : 61288844 : else if (std::abs(lhs[0]-rhs[0]) < eps && + 1608 [ + + ][ + + ]: 74912990 : std::abs(lhs[1]-rhs[1]) < eps && + [ + + ] + 1609 [ + + ]: 13624146 : lhs[2] < rhs[2]) + 1610 : 793388 : return true; 1611 : : else - 1612 : 60485830 : return false; + 1612 : 60495456 : return false; 1613 : : } 1614 : : }; 1615 : : @@ -1861,7 +1861,7 @@ 1689 : : } 1690 : : 1691 : : bool - 1692 : 3486022 : intet( const std::array< std::vector< real >, 3 >& coord, + 1692 : 3485988 : intet( const std::array< std::vector< real >, 3 >& coord, 1693 : : const std::vector< std::size_t >& inpoel, 1694 : : const std::vector< real >& p, 1695 : : std::size_t e, @@ -1877,24 +1877,24 @@ 1705 : : //! \see Lohner, An Introduction to Applied CFD Techniques, Wiley, 2008 1706 : : // ***************************************************************************** 1707 : : { - 1708 [ - + ][ - - ]: 3486022 : Assert( p.size() == 3, "Size mismatch" ); + 1708 [ - + ][ - - ]: 3485988 : Assert( p.size() == 3, "Size mismatch" ); [ - - ][ - - ] 1709 : : 1710 : : // Tetrahedron node indices - 1711 : 3486022 : const auto A = inpoel[e*4+0]; - 1712 : 3486022 : const auto B = inpoel[e*4+1]; - 1713 : 3486022 : const auto C = inpoel[e*4+2]; - 1714 : 3486022 : const auto D = inpoel[e*4+3]; + 1711 : 3485988 : const auto A = inpoel[e*4+0]; + 1712 : 3485988 : const auto B = inpoel[e*4+1]; + 1713 : 3485988 : const auto C = inpoel[e*4+2]; + 1714 : 3485988 : const auto D = inpoel[e*4+3]; 1715 : : 1716 : : // Tetrahedron node coordinates - 1717 : 3486022 : const auto& x = coord[0]; - 1718 : 3486022 : const auto& y = coord[1]; - 1719 : 3486022 : const auto& z = coord[2]; + 1717 : 3485988 : const auto& x = coord[0]; + 1718 : 3485988 : const auto& y = coord[1]; + 1719 : 3485988 : const auto& z = coord[2]; 1720 : : 1721 : : // Point coordinates - 1722 : 3486022 : const auto& xp = p[0]; - 1723 : 3486022 : const auto& yp = p[1]; - 1724 : 3486022 : const auto& zp = p[2]; + 1722 : 3485988 : const auto& xp = p[0]; + 1723 : 3485988 : const auto& yp = p[1]; + 1724 : 3485988 : const auto& zp = p[2]; 1725 : : 1726 : : // Evaluate linear shapefunctions at point locations using Cramer's Rule 1727 : : // | xp | | x1 x2 x3 x4 | | N1 | @@ -1902,55 +1902,55 @@ 1729 : : // | zp | | z1 z2 z3 z4 | | N3 | 1730 : : // | 1 | | 1 1 1 1 | | N4 | 1731 : : - 1732 : 3486022 : real DetX = (y[B]*z[C] - y[C]*z[B] - y[B]*z[D] + y[D]*z[B] + - 1733 : 3486022 : y[C]*z[D] - y[D]*z[C])*x[A] + x[B]*y[C]*z[A] - x[B]*y[A]*z[C] + - 1734 : 3486022 : x[C]*y[A]*z[B] - x[C]*y[B]*z[A] + x[B]*y[A]*z[D] - x[B]*y[D]*z[A] - - 1735 : 3486022 : x[D]*y[A]*z[B] + x[D]*y[B]*z[A] - x[C]*y[A]*z[D] + x[C]*y[D]*z[A] + - 1736 : 3486022 : x[D]*y[A]*z[C] - x[D]*y[C]*z[A] - x[B]*y[C]*z[D] + x[B]*y[D]*z[C] + - 1737 : 3486022 : x[C]*y[B]*z[D] - x[C]*y[D]*z[B] - x[D]*y[B]*z[C] + x[D]*y[C]*z[B]; + 1732 : 3485988 : real DetX = (y[B]*z[C] - y[C]*z[B] - y[B]*z[D] + y[D]*z[B] + + 1733 : 3485988 : y[C]*z[D] - y[D]*z[C])*x[A] + x[B]*y[C]*z[A] - x[B]*y[A]*z[C] + + 1734 : 3485988 : x[C]*y[A]*z[B] - x[C]*y[B]*z[A] + x[B]*y[A]*z[D] - x[B]*y[D]*z[A] - + 1735 : 3485988 : x[D]*y[A]*z[B] + x[D]*y[B]*z[A] - x[C]*y[A]*z[D] + x[C]*y[D]*z[A] + + 1736 : 3485988 : x[D]*y[A]*z[C] - x[D]*y[C]*z[A] - x[B]*y[C]*z[D] + x[B]*y[D]*z[C] + + 1737 : 3485988 : x[C]*y[B]*z[D] - x[C]*y[D]*z[B] - x[D]*y[B]*z[C] + x[D]*y[C]*z[B]; 1738 : : - 1739 : 3486022 : real DetX1 = (y[D]*z[C] - y[C]*z[D] + y[C]*zp - yp*z[C] - - 1740 : 3486022 : y[D]*zp + yp*z[D])*x[B] + x[C]*y[B]*z[D] - x[C]*y[D]*z[B] - - 1741 : 3486022 : x[D]*y[B]*z[C] + x[D]*y[C]*z[B] - x[C]*y[B]*zp + x[C]*yp*z[B] + - 1742 : 3486022 : xp*y[B]*z[C] - xp*y[C]*z[B] + x[D]*y[B]*zp - x[D]*yp*z[B] - - 1743 : 3486022 : xp*y[B]*z[D] + xp*y[D]*z[B] + x[C]*y[D]*zp - x[C]*yp*z[D] - - 1744 : 3486022 : x[D]*y[C]*zp + x[D]*yp*z[C] + xp*y[C]*z[D] - xp*y[D]*z[C]; + 1739 : 3485988 : real DetX1 = (y[D]*z[C] - y[C]*z[D] + y[C]*zp - yp*z[C] - + 1740 : 3485988 : y[D]*zp + yp*z[D])*x[B] + x[C]*y[B]*z[D] - x[C]*y[D]*z[B] - + 1741 : 3485988 : x[D]*y[B]*z[C] + x[D]*y[C]*z[B] - x[C]*y[B]*zp + x[C]*yp*z[B] + + 1742 : 3485988 : xp*y[B]*z[C] - xp*y[C]*z[B] + x[D]*y[B]*zp - x[D]*yp*z[B] - + 1743 : 3485988 : xp*y[B]*z[D] + xp*y[D]*z[B] + x[C]*y[D]*zp - x[C]*yp*z[D] - + 1744 : 3485988 : x[D]*y[C]*zp + x[D]*yp*z[C] + xp*y[C]*z[D] - xp*y[D]*z[C]; 1745 : : - 1746 : 3486022 : real DetX2 = (y[C]*z[D] - y[D]*z[C] - y[C]*zp + yp*z[C] + - 1747 : 3486022 : y[D]*zp - yp*z[D])*x[A] + x[C]*y[D]*z[A] - x[C]*y[A]*z[D] + - 1748 : 3486022 : x[D]*y[A]*z[C] - x[D]*y[C]*z[A] + x[C]*y[A]*zp - x[C]*yp*z[A] - - 1749 : 3486022 : xp*y[A]*z[C] + xp*y[C]*z[A] - x[D]*y[A]*zp + x[D]*yp*z[A] + - 1750 : 3486022 : xp*y[A]*z[D] - xp*y[D]*z[A] - x[C]*y[D]*zp + x[C]*yp*z[D] + - 1751 : 3486022 : x[D]*y[C]*zp - x[D]*yp*z[C] - xp*y[C]*z[D] + xp*y[D]*z[C]; + 1746 : 3485988 : real DetX2 = (y[C]*z[D] - y[D]*z[C] - y[C]*zp + yp*z[C] + + 1747 : 3485988 : y[D]*zp - yp*z[D])*x[A] + x[C]*y[D]*z[A] - x[C]*y[A]*z[D] + + 1748 : 3485988 : x[D]*y[A]*z[C] - x[D]*y[C]*z[A] + x[C]*y[A]*zp - x[C]*yp*z[A] - + 1749 : 3485988 : xp*y[A]*z[C] + xp*y[C]*z[A] - x[D]*y[A]*zp + x[D]*yp*z[A] + + 1750 : 3485988 : xp*y[A]*z[D] - xp*y[D]*z[A] - x[C]*y[D]*zp + x[C]*yp*z[D] + + 1751 : 3485988 : x[D]*y[C]*zp - x[D]*yp*z[C] - xp*y[C]*z[D] + xp*y[D]*z[C]; 1752 : : - 1753 : 3486022 : real DetX3 = (y[D]*z[B] - y[B]*z[D] + y[B]*zp - yp*z[B] - - 1754 : 3486022 : y[D]*zp + yp*z[D])*x[A] + x[B]*y[A]*z[D] - x[B]*y[D]*z[A] - - 1755 : 3486022 : x[D]*y[A]*z[B] + x[D]*y[B]*z[A] - x[B]*y[A]*zp + x[B]*yp*z[A] + - 1756 : 3486022 : xp*y[A]*z[B] - xp*y[B]*z[A] + x[D]*y[A]*zp - x[D]*yp*z[A] - - 1757 : 3486022 : xp*y[A]*z[D] + xp*y[D]*z[A] + x[B]*y[D]*zp - x[B]*yp*z[D] - - 1758 : 3486022 : x[D]*y[B]*zp + x[D]*yp*z[B] + xp*y[B]*z[D] - xp*y[D]*z[B]; + 1753 : 3485988 : real DetX3 = (y[D]*z[B] - y[B]*z[D] + y[B]*zp - yp*z[B] - + 1754 : 3485988 : y[D]*zp + yp*z[D])*x[A] + x[B]*y[A]*z[D] - x[B]*y[D]*z[A] - + 1755 : 3485988 : x[D]*y[A]*z[B] + x[D]*y[B]*z[A] - x[B]*y[A]*zp + x[B]*yp*z[A] + + 1756 : 3485988 : xp*y[A]*z[B] - xp*y[B]*z[A] + x[D]*y[A]*zp - x[D]*yp*z[A] - + 1757 : 3485988 : xp*y[A]*z[D] + xp*y[D]*z[A] + x[B]*y[D]*zp - x[B]*yp*z[D] - + 1758 : 3485988 : x[D]*y[B]*zp + x[D]*yp*z[B] + xp*y[B]*z[D] - xp*y[D]*z[B]; 1759 : : - 1760 : 3486022 : real DetX4 = (y[B]*z[C] - y[C]*z[B] - y[B]*zp + yp*z[B] + - 1761 : 3486022 : y[C]*zp - yp*z[C])*x[A] + x[B]*y[C]*z[A] - x[B]*y[A]*z[C] + - 1762 : 3486022 : x[C]*y[A]*z[B] - x[C]*y[B]*z[A] + x[B]*y[A]*zp - x[B]*yp*z[A] - - 1763 : 3486022 : xp*y[A]*z[B] + xp*y[B]*z[A] - x[C]*y[A]*zp + x[C]*yp*z[A] + - 1764 : 3486022 : xp*y[A]*z[C] - xp*y[C]*z[A] - x[B]*y[C]*zp + x[B]*yp*z[C] + - 1765 : 3486022 : x[C]*y[B]*zp - x[C]*yp*z[B] - xp*y[B]*z[C] + xp*y[C]*z[B]; + 1760 : 3485988 : real DetX4 = (y[B]*z[C] - y[C]*z[B] - y[B]*zp + yp*z[B] + + 1761 : 3485988 : y[C]*zp - yp*z[C])*x[A] + x[B]*y[C]*z[A] - x[B]*y[A]*z[C] + + 1762 : 3485988 : x[C]*y[A]*z[B] - x[C]*y[B]*z[A] + x[B]*y[A]*zp - x[B]*yp*z[A] - + 1763 : 3485988 : xp*y[A]*z[B] + xp*y[B]*z[A] - x[C]*y[A]*zp + x[C]*yp*z[A] + + 1764 : 3485988 : xp*y[A]*z[C] - xp*y[C]*z[A] - x[B]*y[C]*zp + x[B]*yp*z[C] + + 1765 : 3485988 : x[C]*y[B]*zp - x[C]*yp*z[B] - xp*y[B]*z[C] + xp*y[C]*z[B]; 1766 : : 1767 : : // Shape functions evaluated at point - 1768 : 3486022 : N[0] = DetX1/DetX; - 1769 : 3486022 : N[1] = DetX2/DetX; - 1770 : 3486022 : N[2] = DetX3/DetX; - 1771 : 3486022 : N[3] = DetX4/DetX; + 1768 : 3485988 : N[0] = DetX1/DetX; + 1769 : 3485988 : N[1] = DetX2/DetX; + 1770 : 3485988 : N[2] = DetX3/DetX; + 1771 : 3485988 : N[3] = DetX4/DetX; 1772 : : 1773 : : // if min( N^i, 1-N^i ) > 0 for all i, point is in cell - 1774 [ + + ]: 6107165 : if ( std::min(N[0],1.0-N[0]) > 0 && std::min(N[1],1.0-N[1]) > 0 && - 1775 [ + + ][ + + ]: 6107165 : std::min(N[2],1.0-N[2]) > 0 && std::min(N[3],1.0-N[3]) > 0 ) - [ + + ][ + + ] + 1774 [ + + ]: 6107123 : if ( std::min(N[0],1.0-N[0]) > 0 && std::min(N[1],1.0-N[1]) > 0 && + 1775 [ + + ][ + + ]: 6107123 : std::min(N[2],1.0-N[2]) > 0 && std::min(N[3],1.0-N[3]) > 0 ) + [ + + ][ + + ] 1776 : : { 1777 : 460107 : return true; 1778 : : } else { - 1779 : 3025915 : return false; + 1779 : 3025881 : return false; 1780 : : } 1781 : : } 1782 : : diff --git a/Debug/test_coverage/Mesh/DerivedData.hpp.func-sort-c.html b/Debug/test_coverage/Mesh/DerivedData.hpp.func-sort-c.html index f741bce541ae..577fcb18e629 100644 --- a/Debug/test_coverage/Mesh/DerivedData.hpp.func-sort-c.html +++ b/Debug/test_coverage/Mesh/DerivedData.hpp.func-sort-c.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:43:41 + 2024-07-11 15:06:04 Functions: 2 diff --git a/Debug/test_coverage/Mesh/DerivedData.hpp.func.html b/Debug/test_coverage/Mesh/DerivedData.hpp.func.html index 4afd298ee815..cb8d6d35b0da 100644 --- a/Debug/test_coverage/Mesh/DerivedData.hpp.func.html +++ b/Debug/test_coverage/Mesh/DerivedData.hpp.func.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:43:41 + 2024-07-11 15:06:04 Functions: 2 diff --git a/Debug/test_coverage/Mesh/DerivedData.hpp.gcov.html b/Debug/test_coverage/Mesh/DerivedData.hpp.gcov.html index b737eb48939e..d697f04aeb02 100644 --- a/Debug/test_coverage/Mesh/DerivedData.hpp.gcov.html +++ b/Debug/test_coverage/Mesh/DerivedData.hpp.gcov.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:43:41 + 2024-07-11 15:06:04 Functions: 2 diff --git a/Debug/test_coverage/Mesh/Gradients.cpp.func-sort-c.html b/Debug/test_coverage/Mesh/Gradients.cpp.func-sort-c.html index 2b56fac0a711..d7498c1ed3f2 100644 --- a/Debug/test_coverage/Mesh/Gradients.cpp.func-sort-c.html +++ b/Debug/test_coverage/Mesh/Gradients.cpp.func-sort-c.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:43:41 + 2024-07-11 15:06:04 Functions: 2 diff --git a/Debug/test_coverage/Mesh/Gradients.cpp.func.html b/Debug/test_coverage/Mesh/Gradients.cpp.func.html index b2157dcf19bf..39f366807011 100644 --- a/Debug/test_coverage/Mesh/Gradients.cpp.func.html +++ b/Debug/test_coverage/Mesh/Gradients.cpp.func.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:43:41 + 2024-07-11 15:06:04 Functions: 2 diff --git a/Debug/test_coverage/Mesh/Gradients.cpp.gcov.html b/Debug/test_coverage/Mesh/Gradients.cpp.gcov.html index 1ead7afa3b8a..b10985fa04ae 100644 --- a/Debug/test_coverage/Mesh/Gradients.cpp.gcov.html +++ b/Debug/test_coverage/Mesh/Gradients.cpp.gcov.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:43:41 + 2024-07-11 15:06:04 Functions: 2 diff --git a/Debug/test_coverage/Mesh/Reorder.cpp.func-sort-c.html b/Debug/test_coverage/Mesh/Reorder.cpp.func-sort-c.html index b00448618f6f..273bf9a8c2ad 100644 --- a/Debug/test_coverage/Mesh/Reorder.cpp.func-sort-c.html +++ b/Debug/test_coverage/Mesh/Reorder.cpp.func-sort-c.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:43:41 + 2024-07-11 15:06:04 Functions: 12 diff --git a/Debug/test_coverage/Mesh/Reorder.cpp.func.html b/Debug/test_coverage/Mesh/Reorder.cpp.func.html index e79c7794231e..4fe80d8e9ac4 100644 --- a/Debug/test_coverage/Mesh/Reorder.cpp.func.html +++ b/Debug/test_coverage/Mesh/Reorder.cpp.func.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:43:41 + 2024-07-11 15:06:04 Functions: 12 diff --git a/Debug/test_coverage/Mesh/Reorder.cpp.gcov.html b/Debug/test_coverage/Mesh/Reorder.cpp.gcov.html index 7bef38929b8a..ad5842fd5060 100644 --- a/Debug/test_coverage/Mesh/Reorder.cpp.gcov.html +++ b/Debug/test_coverage/Mesh/Reorder.cpp.gcov.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:43:41 + 2024-07-11 15:06:04 Functions: 12 diff --git a/Debug/test_coverage/Mesh/STLMesh.cpp.func-sort-c.html b/Debug/test_coverage/Mesh/STLMesh.cpp.func-sort-c.html index db08ceb63a4d..6546909da7fb 100644 --- a/Debug/test_coverage/Mesh/STLMesh.cpp.func-sort-c.html +++ b/Debug/test_coverage/Mesh/STLMesh.cpp.func-sort-c.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:43:41 + 2024-07-11 15:06:04 Functions: 0 diff --git a/Debug/test_coverage/Mesh/STLMesh.cpp.func.html b/Debug/test_coverage/Mesh/STLMesh.cpp.func.html index 24a860f6c5c8..6dacfe572365 100644 --- a/Debug/test_coverage/Mesh/STLMesh.cpp.func.html +++ b/Debug/test_coverage/Mesh/STLMesh.cpp.func.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:43:41 + 2024-07-11 15:06:04 Functions: 0 diff --git a/Debug/test_coverage/Mesh/STLMesh.cpp.gcov.html b/Debug/test_coverage/Mesh/STLMesh.cpp.gcov.html index dbb3f54fc8e2..a01cee42ea2f 100644 --- a/Debug/test_coverage/Mesh/STLMesh.cpp.gcov.html +++ b/Debug/test_coverage/Mesh/STLMesh.cpp.gcov.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:43:41 + 2024-07-11 15:06:04 Functions: 0 diff --git a/Debug/test_coverage/Mesh/STLMesh.hpp.func-sort-c.html b/Debug/test_coverage/Mesh/STLMesh.hpp.func-sort-c.html index a18ce970486a..b0a1c91ef721 100644 --- a/Debug/test_coverage/Mesh/STLMesh.hpp.func-sort-c.html +++ b/Debug/test_coverage/Mesh/STLMesh.hpp.func-sort-c.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:43:41 + 2024-07-11 15:06:04 Functions: 0 diff --git a/Debug/test_coverage/Mesh/STLMesh.hpp.func.html b/Debug/test_coverage/Mesh/STLMesh.hpp.func.html index cb8e37ed6c55..d3d891d4075d 100644 --- a/Debug/test_coverage/Mesh/STLMesh.hpp.func.html +++ b/Debug/test_coverage/Mesh/STLMesh.hpp.func.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:43:41 + 2024-07-11 15:06:04 Functions: 0 diff --git a/Debug/test_coverage/Mesh/STLMesh.hpp.gcov.html b/Debug/test_coverage/Mesh/STLMesh.hpp.gcov.html index 4589d38eec06..3dec315b441b 100644 --- a/Debug/test_coverage/Mesh/STLMesh.hpp.gcov.html +++ b/Debug/test_coverage/Mesh/STLMesh.hpp.gcov.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:43:41 + 2024-07-11 15:06:04 Functions: 0 diff --git a/Debug/test_coverage/Mesh/UnsMesh.hpp.func-sort-c.html b/Debug/test_coverage/Mesh/UnsMesh.hpp.func-sort-c.html index 349df6c26498..7fb3693c1a81 100644 --- a/Debug/test_coverage/Mesh/UnsMesh.hpp.func-sort-c.html +++ b/Debug/test_coverage/Mesh/UnsMesh.hpp.func-sort-c.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:43:41 + 2024-07-11 15:06:04 Functions: 43 @@ -229,11 +229,11 @@ tk::UnsMesh::Hash<4ul>::operator()(std::array<unsigned long, 4ul> const&) const - 2569702 + 2544340 tk::UnsMesh::Hash<3ul>::operator()(std::array<unsigned long, 3ul> const&) const - 8378519 + 8370673 tk::UnsMesh::Eq<2ul>::operator()(std::array<unsigned long, 2ul> const&, std::array<unsigned long, 2ul> const&) const @@ -241,7 +241,7 @@ tk::UnsMesh::Hash<2ul>::operator()(std::array<unsigned long, 2ul> const&) const - 182505974 + 182492534
diff --git a/Debug/test_coverage/Mesh/UnsMesh.hpp.func.html b/Debug/test_coverage/Mesh/UnsMesh.hpp.func.html index 5c056d00a8c9..3f3f7cbe0b05 100644 --- a/Debug/test_coverage/Mesh/UnsMesh.hpp.func.html +++ b/Debug/test_coverage/Mesh/UnsMesh.hpp.func.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:43:41 + 2024-07-11 15:06:04 Functions: 43 @@ -189,15 +189,15 @@ tk::UnsMesh::Hash<2ul>::operator()(std::array<unsigned long, 2ul> const&) const - 182505974 + 182492534 tk::UnsMesh::Hash<3ul>::operator()(std::array<unsigned long, 3ul> const&) const - 8378519 + 8370673 tk::UnsMesh::Hash<4ul>::operator()(std::array<unsigned long, 4ul> const&) const - 2569702 + 2544340 tk::UnsMesh::bface() const diff --git a/Debug/test_coverage/Mesh/UnsMesh.hpp.gcov.html b/Debug/test_coverage/Mesh/UnsMesh.hpp.gcov.html index 6918d59f72c1..b8c3cddd8368 100644 --- a/Debug/test_coverage/Mesh/UnsMesh.hpp.gcov.html +++ b/Debug/test_coverage/Mesh/UnsMesh.hpp.gcov.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:43:41 + 2024-07-11 15:06:04 Functions: 43 @@ -153,12 +153,12 @@ 79 : : //! \return Unique hash value for the same array of node IDs 80 : : //! \note The order of the nodes does not matter: the IDs are sorted 81 : : //! before the hash is computed. - 82 : 193454195 : std::size_t operator()( const std::array< std::size_t, N >& p ) const { + 82 : 193407547 : std::size_t operator()( const std::array< std::size_t, N >& p ) const { 83 : : using highwayhash::SipHash; 84 : : Shaper< N > shaper; - 85 [ + + ]: 593880508 : for (std::size_t i=0; i<N; ++i) shaper.sizets[i] = p[i]; - 86 [ + - ]: 193454195 : std::sort( std::begin(shaper.sizets), std::end(shaper.sizets) ); - 87 [ + - ]: 386908390 : return SipHash( hh_key, shaper.bytes, N*sizeof(std::size_t) ); + 85 [ + + ]: 593681994 : for (std::size_t i=0; i<N; ++i) shaper.sizets[i] = p[i]; + 86 [ + - ]: 193407547 : std::sort( std::begin(shaper.sizets), std::end(shaper.sizets) ); + 87 [ + - ]: 386815094 : return SipHash( hh_key, shaper.bytes, N*sizeof(std::size_t) ); 88 : : } 89 : : }; 90 : : diff --git a/Debug/test_coverage/Mesh/index-sort-b.html b/Debug/test_coverage/Mesh/index-sort-b.html index ffec2f66a7af..6b316c94d035 100644 --- a/Debug/test_coverage/Mesh/index-sort-b.html +++ b/Debug/test_coverage/Mesh/index-sort-b.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:43:41 + 2024-07-11 15:06:04 Functions: 98 @@ -142,14 +142,14 @@ 6 / 8 - STLMesh.hpp + DerivedData.hpp -
0.0%
+
100.0%
- 0.0 % - 0 / 4 - 0.0 % - 0 / 4 + 100.0 % + 21 / 21 + 100.0 % + 2 / 2 - 0 / 0 @@ -166,26 +166,26 @@ 0 / 0 - STLMesh.cpp + STLMesh.hpp
0.0%
0.0 % - 0 / 6 + 0 / 4 0.0 % - 0 / 1 + 0 / 4 - 0 / 0 - DerivedData.hpp + STLMesh.cpp -
100.0%
+
0.0%
- 100.0 % - 21 / 21 - 100.0 % - 2 / 2 + 0.0 % + 0 / 6 + 0.0 % + 0 / 1 - 0 / 0 diff --git a/Debug/test_coverage/Mesh/index-sort-f.html b/Debug/test_coverage/Mesh/index-sort-f.html index d1c697195a5b..a2dbe41b3845 100644 --- a/Debug/test_coverage/Mesh/index-sort-f.html +++ b/Debug/test_coverage/Mesh/index-sort-f.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:43:41 + 2024-07-11 15:06:04 Functions: 98 @@ -106,28 +106,28 @@ 0 / 0 - Gradients.cpp + DerivedData.hpp
100.0%
100.0 % - 54 / 54 + 21 / 21 100.0 % 2 / 2 - 46.4 % - 26 / 56 + - + 0 / 0 - DerivedData.hpp + Gradients.cpp
100.0%
100.0 % - 21 / 21 + 54 / 54 100.0 % 2 / 2 - - - 0 / 0 + 46.4 % + 26 / 56 CommMap.cpp diff --git a/Debug/test_coverage/Mesh/index-sort-l.html b/Debug/test_coverage/Mesh/index-sort-l.html index 0e6c63af4ed9..f68a8908e84b 100644 --- a/Debug/test_coverage/Mesh/index-sort-l.html +++ b/Debug/test_coverage/Mesh/index-sort-l.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:43:41 + 2024-07-11 15:06:04 Functions: 98 diff --git a/Debug/test_coverage/Mesh/index.html b/Debug/test_coverage/Mesh/index.html index 0f2e95498edc..5f5acc72079a 100644 --- a/Debug/test_coverage/Mesh/index.html +++ b/Debug/test_coverage/Mesh/index.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:43:41 + 2024-07-11 15:06:04 Functions: 98 diff --git a/Debug/test_coverage/PDE/CGPDE.cpp.func-sort-c.html b/Debug/test_coverage/PDE/CGPDE.cpp.func-sort-c.html index b69d045d6fa8..9959fa9cbed2 100644 --- a/Debug/test_coverage/PDE/CGPDE.cpp.func-sort-c.html +++ b/Debug/test_coverage/PDE/CGPDE.cpp.func-sort-c.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:43:41 + 2024-07-11 15:06:04 Functions: 2 diff --git a/Debug/test_coverage/PDE/CGPDE.cpp.func.html b/Debug/test_coverage/PDE/CGPDE.cpp.func.html index f0cf77841384..2a8087d953c8 100644 --- a/Debug/test_coverage/PDE/CGPDE.cpp.func.html +++ b/Debug/test_coverage/PDE/CGPDE.cpp.func.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:43:41 + 2024-07-11 15:06:04 Functions: 2 diff --git a/Debug/test_coverage/PDE/CGPDE.cpp.gcov.html b/Debug/test_coverage/PDE/CGPDE.cpp.gcov.html index 8e157a2c2f49..2c2fe2d42a27 100644 --- a/Debug/test_coverage/PDE/CGPDE.cpp.gcov.html +++ b/Debug/test_coverage/PDE/CGPDE.cpp.gcov.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:43:41 + 2024-07-11 15:06:04 Functions: 2 diff --git a/Debug/test_coverage/PDE/CGPDE.hpp.func-sort-c.html b/Debug/test_coverage/PDE/CGPDE.hpp.func-sort-c.html index 488aadf5e2c7..1e79898bb339 100644 --- a/Debug/test_coverage/PDE/CGPDE.hpp.func-sort-c.html +++ b/Debug/test_coverage/PDE/CGPDE.hpp.func-sort-c.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:43:41 + 2024-07-11 15:06:04 Functions: 190 diff --git a/Debug/test_coverage/PDE/CGPDE.hpp.func.html b/Debug/test_coverage/PDE/CGPDE.hpp.func.html index 573395cddcfc..586a44ca7620 100644 --- a/Debug/test_coverage/PDE/CGPDE.hpp.func.html +++ b/Debug/test_coverage/PDE/CGPDE.hpp.func.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:43:41 + 2024-07-11 15:06:04 Functions: 190 diff --git a/Debug/test_coverage/PDE/CGPDE.hpp.gcov.html b/Debug/test_coverage/PDE/CGPDE.hpp.gcov.html index dfe8b3fe2d3d..0e126515debe 100644 --- a/Debug/test_coverage/PDE/CGPDE.hpp.gcov.html +++ b/Debug/test_coverage/PDE/CGPDE.hpp.gcov.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:43:41 + 2024-07-11 15:06:04 Functions: 190 diff --git a/Debug/test_coverage/PDE/CompFlow/CGCompFlow.hpp.func-sort-c.html b/Debug/test_coverage/PDE/CompFlow/CGCompFlow.hpp.func-sort-c.html index 018a466830c0..14e9968be78b 100644 --- a/Debug/test_coverage/PDE/CompFlow/CGCompFlow.hpp.func-sort-c.html +++ b/Debug/test_coverage/PDE/CompFlow/CGCompFlow.hpp.func-sort-c.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:43:41 + 2024-07-11 15:06:04 Functions: 155 diff --git a/Debug/test_coverage/PDE/CompFlow/CGCompFlow.hpp.func.html b/Debug/test_coverage/PDE/CompFlow/CGCompFlow.hpp.func.html index 5acc773a68ed..a9c7bad5876a 100644 --- a/Debug/test_coverage/PDE/CompFlow/CGCompFlow.hpp.func.html +++ b/Debug/test_coverage/PDE/CompFlow/CGCompFlow.hpp.func.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:43:41 + 2024-07-11 15:06:04 Functions: 155 diff --git a/Debug/test_coverage/PDE/CompFlow/CGCompFlow.hpp.gcov.html b/Debug/test_coverage/PDE/CompFlow/CGCompFlow.hpp.gcov.html index a74db150a2ae..b139c07713f7 100644 --- a/Debug/test_coverage/PDE/CompFlow/CGCompFlow.hpp.gcov.html +++ b/Debug/test_coverage/PDE/CompFlow/CGCompFlow.hpp.gcov.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:43:41 + 2024-07-11 15:06:04 Functions: 155 @@ -717,7 +717,7 @@ 627 : : } 628 : : } 629 : : - 630 [ + + ]: 19922100 : if (v > maxvel) maxvel = v; + 630 [ + + ]: 19922100 : if (v > maxvel) maxvel = v; 631 : : } 632 : : // compute element dt for the Euler equations 633 : 4980525 : auto euler_dt = L / maxvel; diff --git a/Debug/test_coverage/PDE/CompFlow/DGCompFlow.hpp.func-sort-c.html b/Debug/test_coverage/PDE/CompFlow/DGCompFlow.hpp.func-sort-c.html index 6439e8f94fc0..ce6976bced12 100644 --- a/Debug/test_coverage/PDE/CompFlow/DGCompFlow.hpp.func-sort-c.html +++ b/Debug/test_coverage/PDE/CompFlow/DGCompFlow.hpp.func-sort-c.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:43:41 + 2024-07-11 15:06:04 Functions: 184 diff --git a/Debug/test_coverage/PDE/CompFlow/DGCompFlow.hpp.func.html b/Debug/test_coverage/PDE/CompFlow/DGCompFlow.hpp.func.html index 6abea3a1b316..3fbba742f442 100644 --- a/Debug/test_coverage/PDE/CompFlow/DGCompFlow.hpp.func.html +++ b/Debug/test_coverage/PDE/CompFlow/DGCompFlow.hpp.func.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:43:41 + 2024-07-11 15:06:04 Functions: 184 diff --git a/Debug/test_coverage/PDE/CompFlow/DGCompFlow.hpp.gcov.html b/Debug/test_coverage/PDE/CompFlow/DGCompFlow.hpp.gcov.html index 68c2070814a0..449411dfd3aa 100644 --- a/Debug/test_coverage/PDE/CompFlow/DGCompFlow.hpp.gcov.html +++ b/Debug/test_coverage/PDE/CompFlow/DGCompFlow.hpp.gcov.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:43:41 + 2024-07-11 15:06:04 Functions: 184 @@ -754,18 +754,18 @@ 659 : 20758845 : auto mark = c*rdof; 660 [ + - ][ + - ]: 20758845 : ugp[0].push_back( U(el, mark) ); 661 : : - 662 [ + + ]: 20758845 : if(ndofel[el] > 1) //DG(P1) - 663 [ + - ]: 34637610 : ugp[0][c] += U(el, mark+1) * B_l[1] - 664 [ + - ]: 17318805 : + U(el, mark+2) * B_l[2] - 665 [ + - ]: 17318805 : + U(el, mark+3) * B_l[3]; + 662 [ + + ]: 20758845 : if(ndofel[el] > 1) //DG(P1) + 663 [ + - ]: 34636890 : ugp[0][c] += U(el, mark+1) * B_l[1] + 664 [ + - ]: 17318445 : + U(el, mark+2) * B_l[2] + 665 [ + - ]: 17318445 : + U(el, mark+3) * B_l[3]; 666 : : - 667 [ + + ]: 20758845 : if(ndofel[el] > 4) //DG(P2) - 668 [ + - ]: 20979360 : ugp[0][c] += U(el, mark+4) * B_l[4] - 669 [ + - ]: 10489680 : + U(el, mark+5) * B_l[5] - 670 [ + - ]: 10489680 : + U(el, mark+6) * B_l[6] - 671 [ + - ]: 10489680 : + U(el, mark+7) * B_l[7] - 672 [ + - ]: 10489680 : + U(el, mark+8) * B_l[8] - 673 [ + - ]: 10489680 : + U(el, mark+9) * B_l[9]; + 667 [ + + ]: 20758845 : if(ndofel[el] > 4) //DG(P2) + 668 [ + - ]: 20980980 : ugp[0][c] += U(el, mark+4) * B_l[4] + 669 [ + - ]: 10490490 : + U(el, mark+5) * B_l[5] + 670 [ + - ]: 10490490 : + U(el, mark+6) * B_l[6] + 671 [ + - ]: 10490490 : + U(el, mark+7) * B_l[7] + 672 [ + - ]: 10490490 : + U(el, mark+8) * B_l[8] + 673 [ + - ]: 10490490 : + U(el, mark+9) * B_l[9]; 674 : : } 675 : : 676 : 4151769 : rho = ugp[0][0]; @@ -814,18 +814,18 @@ 718 : 15412820 : auto mark = c*rdof; 719 [ + - ][ + - ]: 15412820 : ugp[1].push_back( U(eR, mark) ); 720 : : - 721 [ + + ]: 15412820 : if(ndofel[eR] > 1) //DG(P1) - 722 [ + - ]: 25658220 : ugp[1][c] += U(eR, mark+1) * B_r[1] - 723 [ + - ]: 12829110 : + U(eR, mark+2) * B_r[2] - 724 [ + - ]: 12829110 : + U(eR, mark+3) * B_r[3]; + 721 [ + + ]: 15412820 : if(ndofel[eR] > 1) //DG(P1) + 722 [ + - ]: 25658940 : ugp[1][c] += U(eR, mark+1) * B_r[1] + 723 [ + - ]: 12829470 : + U(eR, mark+2) * B_r[2] + 724 [ + - ]: 12829470 : + U(eR, mark+3) * B_r[3]; 725 : : - 726 [ + + ]: 15412820 : if(ndofel[eR] > 4) //DG(P2) - 727 [ + - ]: 15725400 : ugp[1][c] += U(eR, mark+4) * B_r[4] - 728 [ + - ]: 7862700 : + U(eR, mark+5) * B_r[5] - 729 [ + - ]: 7862700 : + U(eR, mark+6) * B_r[6] - 730 [ + - ]: 7862700 : + U(eR, mark+7) * B_r[7] - 731 [ + - ]: 7862700 : + U(eR, mark+8) * B_r[8] - 732 [ + - ]: 7862700 : + U(eR, mark+9) * B_r[9]; + 726 [ + + ]: 15412820 : if(ndofel[eR] > 4) //DG(P2) + 727 [ + - ]: 15723780 : ugp[1][c] += U(eR, mark+4) * B_r[4] + 728 [ + - ]: 7861890 : + U(eR, mark+5) * B_r[5] + 729 [ + - ]: 7861890 : + U(eR, mark+6) * B_r[6] + 730 [ + - ]: 7861890 : + U(eR, mark+7) * B_r[7] + 731 [ + - ]: 7861890 : + U(eR, mark+8) * B_r[8] + 732 [ + - ]: 7861890 : + U(eR, mark+9) * B_r[9]; 733 : : } 734 : : 735 : 3082564 : rho = ugp[1][0]; diff --git a/Debug/test_coverage/PDE/CompFlow/Physics/CGEuler.hpp.func-sort-c.html b/Debug/test_coverage/PDE/CompFlow/Physics/CGEuler.hpp.func-sort-c.html index d06d2f018aa0..0c4204677d9b 100644 --- a/Debug/test_coverage/PDE/CompFlow/Physics/CGEuler.hpp.func-sort-c.html +++ b/Debug/test_coverage/PDE/CompFlow/Physics/CGEuler.hpp.func-sort-c.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:43:41 + 2024-07-11 15:06:04 Functions: 3 diff --git a/Debug/test_coverage/PDE/CompFlow/Physics/CGEuler.hpp.func.html b/Debug/test_coverage/PDE/CompFlow/Physics/CGEuler.hpp.func.html index 7ad562671363..07c716d6da41 100644 --- a/Debug/test_coverage/PDE/CompFlow/Physics/CGEuler.hpp.func.html +++ b/Debug/test_coverage/PDE/CompFlow/Physics/CGEuler.hpp.func.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:43:41 + 2024-07-11 15:06:04 Functions: 3 diff --git a/Debug/test_coverage/PDE/CompFlow/Physics/CGEuler.hpp.gcov.html b/Debug/test_coverage/PDE/CompFlow/Physics/CGEuler.hpp.gcov.html index 9ecf300f7e90..5e01b4857600 100644 --- a/Debug/test_coverage/PDE/CompFlow/Physics/CGEuler.hpp.gcov.html +++ b/Debug/test_coverage/PDE/CompFlow/Physics/CGEuler.hpp.gcov.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:43:41 + 2024-07-11 15:06:04 Functions: 3 diff --git a/Debug/test_coverage/PDE/CompFlow/Physics/CGNavierStokes.cpp.func-sort-c.html b/Debug/test_coverage/PDE/CompFlow/Physics/CGNavierStokes.cpp.func-sort-c.html index 5ffc36aa50b6..dad0b5406a17 100644 --- a/Debug/test_coverage/PDE/CompFlow/Physics/CGNavierStokes.cpp.func-sort-c.html +++ b/Debug/test_coverage/PDE/CompFlow/Physics/CGNavierStokes.cpp.func-sort-c.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:43:41 + 2024-07-11 15:06:04 Functions: 0 diff --git a/Debug/test_coverage/PDE/CompFlow/Physics/CGNavierStokes.cpp.func.html b/Debug/test_coverage/PDE/CompFlow/Physics/CGNavierStokes.cpp.func.html index 1acdc2e9cd13..6bd8a7432576 100644 --- a/Debug/test_coverage/PDE/CompFlow/Physics/CGNavierStokes.cpp.func.html +++ b/Debug/test_coverage/PDE/CompFlow/Physics/CGNavierStokes.cpp.func.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:43:41 + 2024-07-11 15:06:04 Functions: 0 diff --git a/Debug/test_coverage/PDE/CompFlow/Physics/CGNavierStokes.cpp.gcov.html b/Debug/test_coverage/PDE/CompFlow/Physics/CGNavierStokes.cpp.gcov.html index 06d404c5aebb..ede58fe22e0c 100644 --- a/Debug/test_coverage/PDE/CompFlow/Physics/CGNavierStokes.cpp.gcov.html +++ b/Debug/test_coverage/PDE/CompFlow/Physics/CGNavierStokes.cpp.gcov.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:43:41 + 2024-07-11 15:06:04 Functions: 0 diff --git a/Debug/test_coverage/PDE/CompFlow/Physics/CGNavierStokes.hpp.func-sort-c.html b/Debug/test_coverage/PDE/CompFlow/Physics/CGNavierStokes.hpp.func-sort-c.html index 0e6fd55f15a4..a253909659d1 100644 --- a/Debug/test_coverage/PDE/CompFlow/Physics/CGNavierStokes.hpp.func-sort-c.html +++ b/Debug/test_coverage/PDE/CompFlow/Physics/CGNavierStokes.hpp.func-sort-c.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:43:41 + 2024-07-11 15:06:04 Functions: 1 diff --git a/Debug/test_coverage/PDE/CompFlow/Physics/CGNavierStokes.hpp.func.html b/Debug/test_coverage/PDE/CompFlow/Physics/CGNavierStokes.hpp.func.html index 341ef52dc6e0..ba01fbe6763f 100644 --- a/Debug/test_coverage/PDE/CompFlow/Physics/CGNavierStokes.hpp.func.html +++ b/Debug/test_coverage/PDE/CompFlow/Physics/CGNavierStokes.hpp.func.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:43:41 + 2024-07-11 15:06:04 Functions: 1 diff --git a/Debug/test_coverage/PDE/CompFlow/Physics/CGNavierStokes.hpp.gcov.html b/Debug/test_coverage/PDE/CompFlow/Physics/CGNavierStokes.hpp.gcov.html index f37c3bcaea71..59547fc9c537 100644 --- a/Debug/test_coverage/PDE/CompFlow/Physics/CGNavierStokes.hpp.gcov.html +++ b/Debug/test_coverage/PDE/CompFlow/Physics/CGNavierStokes.hpp.gcov.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:43:41 + 2024-07-11 15:06:04 Functions: 1 diff --git a/Debug/test_coverage/PDE/CompFlow/Physics/DGEuler.hpp.func-sort-c.html b/Debug/test_coverage/PDE/CompFlow/Physics/DGEuler.hpp.func-sort-c.html index 60b30fdb793f..c43a0713f269 100644 --- a/Debug/test_coverage/PDE/CompFlow/Physics/DGEuler.hpp.func-sort-c.html +++ b/Debug/test_coverage/PDE/CompFlow/Physics/DGEuler.hpp.func-sort-c.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:43:41 + 2024-07-11 15:06:04 Functions: 1 diff --git a/Debug/test_coverage/PDE/CompFlow/Physics/DGEuler.hpp.func.html b/Debug/test_coverage/PDE/CompFlow/Physics/DGEuler.hpp.func.html index 2638e12b7080..9060db260180 100644 --- a/Debug/test_coverage/PDE/CompFlow/Physics/DGEuler.hpp.func.html +++ b/Debug/test_coverage/PDE/CompFlow/Physics/DGEuler.hpp.func.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:43:41 + 2024-07-11 15:06:04 Functions: 1 diff --git a/Debug/test_coverage/PDE/CompFlow/Physics/DGEuler.hpp.gcov.html b/Debug/test_coverage/PDE/CompFlow/Physics/DGEuler.hpp.gcov.html index 04cd5b47c8d7..662ebdd3f864 100644 --- a/Debug/test_coverage/PDE/CompFlow/Physics/DGEuler.hpp.gcov.html +++ b/Debug/test_coverage/PDE/CompFlow/Physics/DGEuler.hpp.gcov.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:43:41 + 2024-07-11 15:06:04 Functions: 1 diff --git a/Debug/test_coverage/PDE/CompFlow/Physics/index-sort-b.html b/Debug/test_coverage/PDE/CompFlow/Physics/index-sort-b.html index 509df2cbf228..bea224415faa 100644 --- a/Debug/test_coverage/PDE/CompFlow/Physics/index-sort-b.html +++ b/Debug/test_coverage/PDE/CompFlow/Physics/index-sort-b.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:43:41 + 2024-07-11 15:06:04 Functions: 5 @@ -94,7 +94,7 @@ 0 / 50 - CGNavierStokes.hpp + DGEuler.hpp
100.0%
@@ -106,7 +106,7 @@ 0 / 0 - DGEuler.hpp + CGNavierStokes.hpp
100.0%
diff --git a/Debug/test_coverage/PDE/CompFlow/Physics/index-sort-f.html b/Debug/test_coverage/PDE/CompFlow/Physics/index-sort-f.html index ba08d97fc6f3..2cad632872e6 100644 --- a/Debug/test_coverage/PDE/CompFlow/Physics/index-sort-f.html +++ b/Debug/test_coverage/PDE/CompFlow/Physics/index-sort-f.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:43:41 + 2024-07-11 15:06:04 Functions: 5 @@ -94,7 +94,7 @@ 0 / 50 - CGNavierStokes.hpp + DGEuler.hpp
100.0%
@@ -106,7 +106,7 @@ 0 / 0 - DGEuler.hpp + CGNavierStokes.hpp
100.0%
diff --git a/Debug/test_coverage/PDE/CompFlow/Physics/index-sort-l.html b/Debug/test_coverage/PDE/CompFlow/Physics/index-sort-l.html index dd963ffc0675..0e8b90688689 100644 --- a/Debug/test_coverage/PDE/CompFlow/Physics/index-sort-l.html +++ b/Debug/test_coverage/PDE/CompFlow/Physics/index-sort-l.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:43:41 + 2024-07-11 15:06:04 Functions: 5 @@ -94,7 +94,7 @@ 0 / 50 - CGNavierStokes.hpp + DGEuler.hpp
100.0%
@@ -106,7 +106,7 @@ 0 / 0 - DGEuler.hpp + CGNavierStokes.hpp
100.0%
diff --git a/Debug/test_coverage/PDE/CompFlow/Physics/index.html b/Debug/test_coverage/PDE/CompFlow/Physics/index.html index cfffd5352916..fe130a08d9cc 100644 --- a/Debug/test_coverage/PDE/CompFlow/Physics/index.html +++ b/Debug/test_coverage/PDE/CompFlow/Physics/index.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:43:41 + 2024-07-11 15:06:04 Functions: 5 diff --git a/Debug/test_coverage/PDE/CompFlow/Problem/BoxInitialization.hpp.func-sort-c.html b/Debug/test_coverage/PDE/CompFlow/Problem/BoxInitialization.hpp.func-sort-c.html index 9b2cd1e5edf2..6e42da7377d8 100644 --- a/Debug/test_coverage/PDE/CompFlow/Problem/BoxInitialization.hpp.func-sort-c.html +++ b/Debug/test_coverage/PDE/CompFlow/Problem/BoxInitialization.hpp.func-sort-c.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:43:41 + 2024-07-11 15:06:04 Functions: 1 diff --git a/Debug/test_coverage/PDE/CompFlow/Problem/BoxInitialization.hpp.func.html b/Debug/test_coverage/PDE/CompFlow/Problem/BoxInitialization.hpp.func.html index 591180855561..d6388eae9961 100644 --- a/Debug/test_coverage/PDE/CompFlow/Problem/BoxInitialization.hpp.func.html +++ b/Debug/test_coverage/PDE/CompFlow/Problem/BoxInitialization.hpp.func.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:43:41 + 2024-07-11 15:06:04 Functions: 1 diff --git a/Debug/test_coverage/PDE/CompFlow/Problem/BoxInitialization.hpp.gcov.html b/Debug/test_coverage/PDE/CompFlow/Problem/BoxInitialization.hpp.gcov.html index 5a0ea7d4457c..ff3a901e0703 100644 --- a/Debug/test_coverage/PDE/CompFlow/Problem/BoxInitialization.hpp.gcov.html +++ b/Debug/test_coverage/PDE/CompFlow/Problem/BoxInitialization.hpp.gcov.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:43:41 + 2024-07-11 15:06:04 Functions: 1 diff --git a/Debug/test_coverage/PDE/CompFlow/Problem/FieldOutput.cpp.func-sort-c.html b/Debug/test_coverage/PDE/CompFlow/Problem/FieldOutput.cpp.func-sort-c.html index b127efffaa6c..c6388606d4b8 100644 --- a/Debug/test_coverage/PDE/CompFlow/Problem/FieldOutput.cpp.func-sort-c.html +++ b/Debug/test_coverage/PDE/CompFlow/Problem/FieldOutput.cpp.func-sort-c.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:43:41 + 2024-07-11 15:06:04 Functions: 6 diff --git a/Debug/test_coverage/PDE/CompFlow/Problem/FieldOutput.cpp.func.html b/Debug/test_coverage/PDE/CompFlow/Problem/FieldOutput.cpp.func.html index b484c2ec43ca..aed4e8cf931a 100644 --- a/Debug/test_coverage/PDE/CompFlow/Problem/FieldOutput.cpp.func.html +++ b/Debug/test_coverage/PDE/CompFlow/Problem/FieldOutput.cpp.func.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:43:41 + 2024-07-11 15:06:04 Functions: 6 diff --git a/Debug/test_coverage/PDE/CompFlow/Problem/FieldOutput.cpp.gcov.html b/Debug/test_coverage/PDE/CompFlow/Problem/FieldOutput.cpp.gcov.html index dddf67536ca2..90e518867dc7 100644 --- a/Debug/test_coverage/PDE/CompFlow/Problem/FieldOutput.cpp.gcov.html +++ b/Debug/test_coverage/PDE/CompFlow/Problem/FieldOutput.cpp.gcov.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:43:41 + 2024-07-11 15:06:04 Functions: 6 diff --git a/Debug/test_coverage/PDE/CompFlow/Problem/GaussHumpCompflow.cpp.func-sort-c.html b/Debug/test_coverage/PDE/CompFlow/Problem/GaussHumpCompflow.cpp.func-sort-c.html index 9a68a7d3019c..5eaed0e1d0f6 100644 --- a/Debug/test_coverage/PDE/CompFlow/Problem/GaussHumpCompflow.cpp.func-sort-c.html +++ b/Debug/test_coverage/PDE/CompFlow/Problem/GaussHumpCompflow.cpp.func-sort-c.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:43:41 + 2024-07-11 15:06:04 Functions: 5 diff --git a/Debug/test_coverage/PDE/CompFlow/Problem/GaussHumpCompflow.cpp.func.html b/Debug/test_coverage/PDE/CompFlow/Problem/GaussHumpCompflow.cpp.func.html index 51b33a754092..c92cceee58bf 100644 --- a/Debug/test_coverage/PDE/CompFlow/Problem/GaussHumpCompflow.cpp.func.html +++ b/Debug/test_coverage/PDE/CompFlow/Problem/GaussHumpCompflow.cpp.func.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:43:41 + 2024-07-11 15:06:04 Functions: 5 diff --git a/Debug/test_coverage/PDE/CompFlow/Problem/GaussHumpCompflow.cpp.gcov.html b/Debug/test_coverage/PDE/CompFlow/Problem/GaussHumpCompflow.cpp.gcov.html index ce149d7476bd..4fd9353030a1 100644 --- a/Debug/test_coverage/PDE/CompFlow/Problem/GaussHumpCompflow.cpp.gcov.html +++ b/Debug/test_coverage/PDE/CompFlow/Problem/GaussHumpCompflow.cpp.gcov.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:43:41 + 2024-07-11 15:06:04 Functions: 5 diff --git a/Debug/test_coverage/PDE/CompFlow/Problem/GaussHumpCompflow.hpp.func-sort-c.html b/Debug/test_coverage/PDE/CompFlow/Problem/GaussHumpCompflow.hpp.func-sort-c.html index 9047b55b6ebc..1e98f86a9fd6 100644 --- a/Debug/test_coverage/PDE/CompFlow/Problem/GaussHumpCompflow.hpp.func-sort-c.html +++ b/Debug/test_coverage/PDE/CompFlow/Problem/GaussHumpCompflow.hpp.func-sort-c.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:43:41 + 2024-07-11 15:06:04 Functions: 2 diff --git a/Debug/test_coverage/PDE/CompFlow/Problem/GaussHumpCompflow.hpp.func.html b/Debug/test_coverage/PDE/CompFlow/Problem/GaussHumpCompflow.hpp.func.html index 18e462813da1..327d8f359472 100644 --- a/Debug/test_coverage/PDE/CompFlow/Problem/GaussHumpCompflow.hpp.func.html +++ b/Debug/test_coverage/PDE/CompFlow/Problem/GaussHumpCompflow.hpp.func.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:43:41 + 2024-07-11 15:06:04 Functions: 2 diff --git a/Debug/test_coverage/PDE/CompFlow/Problem/GaussHumpCompflow.hpp.gcov.html b/Debug/test_coverage/PDE/CompFlow/Problem/GaussHumpCompflow.hpp.gcov.html index 6a89169ad2ed..8a91ecc35bca 100644 --- a/Debug/test_coverage/PDE/CompFlow/Problem/GaussHumpCompflow.hpp.gcov.html +++ b/Debug/test_coverage/PDE/CompFlow/Problem/GaussHumpCompflow.hpp.gcov.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:43:41 + 2024-07-11 15:06:04 Functions: 2 diff --git a/Debug/test_coverage/PDE/CompFlow/Problem/NLEnergyGrowth.cpp.func-sort-c.html b/Debug/test_coverage/PDE/CompFlow/Problem/NLEnergyGrowth.cpp.func-sort-c.html index b0e67e75236c..aae8781a5ec1 100644 --- a/Debug/test_coverage/PDE/CompFlow/Problem/NLEnergyGrowth.cpp.func-sort-c.html +++ b/Debug/test_coverage/PDE/CompFlow/Problem/NLEnergyGrowth.cpp.func-sort-c.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:43:41 + 2024-07-11 15:06:04 Functions: 6 diff --git a/Debug/test_coverage/PDE/CompFlow/Problem/NLEnergyGrowth.cpp.func.html b/Debug/test_coverage/PDE/CompFlow/Problem/NLEnergyGrowth.cpp.func.html index 535f672072b4..2042ccad2415 100644 --- a/Debug/test_coverage/PDE/CompFlow/Problem/NLEnergyGrowth.cpp.func.html +++ b/Debug/test_coverage/PDE/CompFlow/Problem/NLEnergyGrowth.cpp.func.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:43:41 + 2024-07-11 15:06:04 Functions: 6 diff --git a/Debug/test_coverage/PDE/CompFlow/Problem/NLEnergyGrowth.cpp.gcov.html b/Debug/test_coverage/PDE/CompFlow/Problem/NLEnergyGrowth.cpp.gcov.html index 4e98943da3cc..d680f3ea451a 100644 --- a/Debug/test_coverage/PDE/CompFlow/Problem/NLEnergyGrowth.cpp.gcov.html +++ b/Debug/test_coverage/PDE/CompFlow/Problem/NLEnergyGrowth.cpp.gcov.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:43:41 + 2024-07-11 15:06:04 Functions: 6 diff --git a/Debug/test_coverage/PDE/CompFlow/Problem/NLEnergyGrowth.hpp.func-sort-c.html b/Debug/test_coverage/PDE/CompFlow/Problem/NLEnergyGrowth.hpp.func-sort-c.html index b86195bc4344..c5f65e7562d9 100644 --- a/Debug/test_coverage/PDE/CompFlow/Problem/NLEnergyGrowth.hpp.func-sort-c.html +++ b/Debug/test_coverage/PDE/CompFlow/Problem/NLEnergyGrowth.hpp.func-sort-c.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:43:41 + 2024-07-11 15:06:04 Functions: 2 diff --git a/Debug/test_coverage/PDE/CompFlow/Problem/NLEnergyGrowth.hpp.func.html b/Debug/test_coverage/PDE/CompFlow/Problem/NLEnergyGrowth.hpp.func.html index b5ca53a86b58..29c17bd6f3b8 100644 --- a/Debug/test_coverage/PDE/CompFlow/Problem/NLEnergyGrowth.hpp.func.html +++ b/Debug/test_coverage/PDE/CompFlow/Problem/NLEnergyGrowth.hpp.func.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:43:41 + 2024-07-11 15:06:04 Functions: 2 diff --git a/Debug/test_coverage/PDE/CompFlow/Problem/NLEnergyGrowth.hpp.gcov.html b/Debug/test_coverage/PDE/CompFlow/Problem/NLEnergyGrowth.hpp.gcov.html index ac919bd3e55c..5f1ac937e68d 100644 --- a/Debug/test_coverage/PDE/CompFlow/Problem/NLEnergyGrowth.hpp.gcov.html +++ b/Debug/test_coverage/PDE/CompFlow/Problem/NLEnergyGrowth.hpp.gcov.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:43:41 + 2024-07-11 15:06:04 Functions: 2 diff --git a/Debug/test_coverage/PDE/CompFlow/Problem/RayleighTaylor.cpp.func-sort-c.html b/Debug/test_coverage/PDE/CompFlow/Problem/RayleighTaylor.cpp.func-sort-c.html index 45f8405d8598..0b30927471df 100644 --- a/Debug/test_coverage/PDE/CompFlow/Problem/RayleighTaylor.cpp.func-sort-c.html +++ b/Debug/test_coverage/PDE/CompFlow/Problem/RayleighTaylor.cpp.func-sort-c.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:43:41 + 2024-07-11 15:06:04 Functions: 2 diff --git a/Debug/test_coverage/PDE/CompFlow/Problem/RayleighTaylor.cpp.func.html b/Debug/test_coverage/PDE/CompFlow/Problem/RayleighTaylor.cpp.func.html index d3e96891e2bd..65b95f80d302 100644 --- a/Debug/test_coverage/PDE/CompFlow/Problem/RayleighTaylor.cpp.func.html +++ b/Debug/test_coverage/PDE/CompFlow/Problem/RayleighTaylor.cpp.func.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:43:41 + 2024-07-11 15:06:04 Functions: 2 diff --git a/Debug/test_coverage/PDE/CompFlow/Problem/RayleighTaylor.cpp.gcov.html b/Debug/test_coverage/PDE/CompFlow/Problem/RayleighTaylor.cpp.gcov.html index f950c61f2f58..1ba1b8fd8eac 100644 --- a/Debug/test_coverage/PDE/CompFlow/Problem/RayleighTaylor.cpp.gcov.html +++ b/Debug/test_coverage/PDE/CompFlow/Problem/RayleighTaylor.cpp.gcov.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:43:41 + 2024-07-11 15:06:04 Functions: 2 diff --git a/Debug/test_coverage/PDE/CompFlow/Problem/RayleighTaylor.hpp.func-sort-c.html b/Debug/test_coverage/PDE/CompFlow/Problem/RayleighTaylor.hpp.func-sort-c.html index c8c79a86fd5d..633fa917108c 100644 --- a/Debug/test_coverage/PDE/CompFlow/Problem/RayleighTaylor.hpp.func-sort-c.html +++ b/Debug/test_coverage/PDE/CompFlow/Problem/RayleighTaylor.hpp.func-sort-c.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:43:41 + 2024-07-11 15:06:04 Functions: 2 diff --git a/Debug/test_coverage/PDE/CompFlow/Problem/RayleighTaylor.hpp.func.html b/Debug/test_coverage/PDE/CompFlow/Problem/RayleighTaylor.hpp.func.html index 4e482c0c83b9..b96772060252 100644 --- a/Debug/test_coverage/PDE/CompFlow/Problem/RayleighTaylor.hpp.func.html +++ b/Debug/test_coverage/PDE/CompFlow/Problem/RayleighTaylor.hpp.func.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:43:41 + 2024-07-11 15:06:04 Functions: 2 diff --git a/Debug/test_coverage/PDE/CompFlow/Problem/RayleighTaylor.hpp.gcov.html b/Debug/test_coverage/PDE/CompFlow/Problem/RayleighTaylor.hpp.gcov.html index f1ae5854ac69..3e4b4b30ea45 100644 --- a/Debug/test_coverage/PDE/CompFlow/Problem/RayleighTaylor.hpp.gcov.html +++ b/Debug/test_coverage/PDE/CompFlow/Problem/RayleighTaylor.hpp.gcov.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:43:41 + 2024-07-11 15:06:04 Functions: 2 diff --git a/Debug/test_coverage/PDE/CompFlow/Problem/RotatedSodShocktube.cpp.func-sort-c.html b/Debug/test_coverage/PDE/CompFlow/Problem/RotatedSodShocktube.cpp.func-sort-c.html index 3b68814dee1c..b69560aea2bc 100644 --- a/Debug/test_coverage/PDE/CompFlow/Problem/RotatedSodShocktube.cpp.func-sort-c.html +++ b/Debug/test_coverage/PDE/CompFlow/Problem/RotatedSodShocktube.cpp.func-sort-c.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:43:41 + 2024-07-11 15:06:04 Functions: 1 diff --git a/Debug/test_coverage/PDE/CompFlow/Problem/RotatedSodShocktube.cpp.func.html b/Debug/test_coverage/PDE/CompFlow/Problem/RotatedSodShocktube.cpp.func.html index 9ae9eb356427..2d626c4899ea 100644 --- a/Debug/test_coverage/PDE/CompFlow/Problem/RotatedSodShocktube.cpp.func.html +++ b/Debug/test_coverage/PDE/CompFlow/Problem/RotatedSodShocktube.cpp.func.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:43:41 + 2024-07-11 15:06:04 Functions: 1 diff --git a/Debug/test_coverage/PDE/CompFlow/Problem/RotatedSodShocktube.cpp.gcov.html b/Debug/test_coverage/PDE/CompFlow/Problem/RotatedSodShocktube.cpp.gcov.html index cb3bef6a29af..5d3e71b09a22 100644 --- a/Debug/test_coverage/PDE/CompFlow/Problem/RotatedSodShocktube.cpp.gcov.html +++ b/Debug/test_coverage/PDE/CompFlow/Problem/RotatedSodShocktube.cpp.gcov.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:43:41 + 2024-07-11 15:06:04 Functions: 1 diff --git a/Debug/test_coverage/PDE/CompFlow/Problem/RotatedSodShocktube.hpp.func-sort-c.html b/Debug/test_coverage/PDE/CompFlow/Problem/RotatedSodShocktube.hpp.func-sort-c.html index 9f50568b89d3..1525bd445acb 100644 --- a/Debug/test_coverage/PDE/CompFlow/Problem/RotatedSodShocktube.hpp.func-sort-c.html +++ b/Debug/test_coverage/PDE/CompFlow/Problem/RotatedSodShocktube.hpp.func-sort-c.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:43:41 + 2024-07-11 15:06:04 Functions: 1 diff --git a/Debug/test_coverage/PDE/CompFlow/Problem/RotatedSodShocktube.hpp.func.html b/Debug/test_coverage/PDE/CompFlow/Problem/RotatedSodShocktube.hpp.func.html index 312300cd251d..029a7d74fd12 100644 --- a/Debug/test_coverage/PDE/CompFlow/Problem/RotatedSodShocktube.hpp.func.html +++ b/Debug/test_coverage/PDE/CompFlow/Problem/RotatedSodShocktube.hpp.func.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:43:41 + 2024-07-11 15:06:04 Functions: 1 diff --git a/Debug/test_coverage/PDE/CompFlow/Problem/RotatedSodShocktube.hpp.gcov.html b/Debug/test_coverage/PDE/CompFlow/Problem/RotatedSodShocktube.hpp.gcov.html index 4279ba0afd51..85ba2d8c66b8 100644 --- a/Debug/test_coverage/PDE/CompFlow/Problem/RotatedSodShocktube.hpp.gcov.html +++ b/Debug/test_coverage/PDE/CompFlow/Problem/RotatedSodShocktube.hpp.gcov.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:43:41 + 2024-07-11 15:06:04 Functions: 1 diff --git a/Debug/test_coverage/PDE/CompFlow/Problem/SedovBlastwave.cpp.func-sort-c.html b/Debug/test_coverage/PDE/CompFlow/Problem/SedovBlastwave.cpp.func-sort-c.html index 0c4be830b556..0e69683de3d7 100644 --- a/Debug/test_coverage/PDE/CompFlow/Problem/SedovBlastwave.cpp.func-sort-c.html +++ b/Debug/test_coverage/PDE/CompFlow/Problem/SedovBlastwave.cpp.func-sort-c.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:43:41 + 2024-07-11 15:06:04 Functions: 2 diff --git a/Debug/test_coverage/PDE/CompFlow/Problem/SedovBlastwave.cpp.func.html b/Debug/test_coverage/PDE/CompFlow/Problem/SedovBlastwave.cpp.func.html index 793bf32e45fe..cf2005d398df 100644 --- a/Debug/test_coverage/PDE/CompFlow/Problem/SedovBlastwave.cpp.func.html +++ b/Debug/test_coverage/PDE/CompFlow/Problem/SedovBlastwave.cpp.func.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:43:41 + 2024-07-11 15:06:04 Functions: 2 diff --git a/Debug/test_coverage/PDE/CompFlow/Problem/SedovBlastwave.cpp.gcov.html b/Debug/test_coverage/PDE/CompFlow/Problem/SedovBlastwave.cpp.gcov.html index c0fd815664a0..57943b7cf009 100644 --- a/Debug/test_coverage/PDE/CompFlow/Problem/SedovBlastwave.cpp.gcov.html +++ b/Debug/test_coverage/PDE/CompFlow/Problem/SedovBlastwave.cpp.gcov.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:43:41 + 2024-07-11 15:06:04 Functions: 2 diff --git a/Debug/test_coverage/PDE/CompFlow/Problem/SedovBlastwave.hpp.func-sort-c.html b/Debug/test_coverage/PDE/CompFlow/Problem/SedovBlastwave.hpp.func-sort-c.html index b4ef45ddcac9..52b78d716db6 100644 --- a/Debug/test_coverage/PDE/CompFlow/Problem/SedovBlastwave.hpp.func-sort-c.html +++ b/Debug/test_coverage/PDE/CompFlow/Problem/SedovBlastwave.hpp.func-sort-c.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:43:41 + 2024-07-11 15:06:04 Functions: 2 diff --git a/Debug/test_coverage/PDE/CompFlow/Problem/SedovBlastwave.hpp.func.html b/Debug/test_coverage/PDE/CompFlow/Problem/SedovBlastwave.hpp.func.html index 336834e1eca2..19d5f95fc05d 100644 --- a/Debug/test_coverage/PDE/CompFlow/Problem/SedovBlastwave.hpp.func.html +++ b/Debug/test_coverage/PDE/CompFlow/Problem/SedovBlastwave.hpp.func.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:43:41 + 2024-07-11 15:06:04 Functions: 2 diff --git a/Debug/test_coverage/PDE/CompFlow/Problem/SedovBlastwave.hpp.gcov.html b/Debug/test_coverage/PDE/CompFlow/Problem/SedovBlastwave.hpp.gcov.html index bc184cd8b0b2..ae5fdd62f8fa 100644 --- a/Debug/test_coverage/PDE/CompFlow/Problem/SedovBlastwave.hpp.gcov.html +++ b/Debug/test_coverage/PDE/CompFlow/Problem/SedovBlastwave.hpp.gcov.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:43:41 + 2024-07-11 15:06:04 Functions: 2 diff --git a/Debug/test_coverage/PDE/CompFlow/Problem/SheddingFlow.cpp.func-sort-c.html b/Debug/test_coverage/PDE/CompFlow/Problem/SheddingFlow.cpp.func-sort-c.html index 9da41926ff8d..4d484b4f3ab1 100644 --- a/Debug/test_coverage/PDE/CompFlow/Problem/SheddingFlow.cpp.func-sort-c.html +++ b/Debug/test_coverage/PDE/CompFlow/Problem/SheddingFlow.cpp.func-sort-c.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:43:41 + 2024-07-11 15:06:04 Functions: 0 diff --git a/Debug/test_coverage/PDE/CompFlow/Problem/SheddingFlow.cpp.func.html b/Debug/test_coverage/PDE/CompFlow/Problem/SheddingFlow.cpp.func.html index 1ca05dc61f80..398661a6ad94 100644 --- a/Debug/test_coverage/PDE/CompFlow/Problem/SheddingFlow.cpp.func.html +++ b/Debug/test_coverage/PDE/CompFlow/Problem/SheddingFlow.cpp.func.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:43:41 + 2024-07-11 15:06:04 Functions: 0 diff --git a/Debug/test_coverage/PDE/CompFlow/Problem/SheddingFlow.cpp.gcov.html b/Debug/test_coverage/PDE/CompFlow/Problem/SheddingFlow.cpp.gcov.html index bf1823661ed7..43fcb0ddf123 100644 --- a/Debug/test_coverage/PDE/CompFlow/Problem/SheddingFlow.cpp.gcov.html +++ b/Debug/test_coverage/PDE/CompFlow/Problem/SheddingFlow.cpp.gcov.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:43:41 + 2024-07-11 15:06:04 Functions: 0 diff --git a/Debug/test_coverage/PDE/CompFlow/Problem/SheddingFlow.hpp.func-sort-c.html b/Debug/test_coverage/PDE/CompFlow/Problem/SheddingFlow.hpp.func-sort-c.html index 4c276751ef01..e54d962e1c67 100644 --- a/Debug/test_coverage/PDE/CompFlow/Problem/SheddingFlow.hpp.func-sort-c.html +++ b/Debug/test_coverage/PDE/CompFlow/Problem/SheddingFlow.hpp.func-sort-c.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:43:41 + 2024-07-11 15:06:04 Functions: 1 diff --git a/Debug/test_coverage/PDE/CompFlow/Problem/SheddingFlow.hpp.func.html b/Debug/test_coverage/PDE/CompFlow/Problem/SheddingFlow.hpp.func.html index ad329470cb0d..7130ce47a573 100644 --- a/Debug/test_coverage/PDE/CompFlow/Problem/SheddingFlow.hpp.func.html +++ b/Debug/test_coverage/PDE/CompFlow/Problem/SheddingFlow.hpp.func.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:43:41 + 2024-07-11 15:06:04 Functions: 1 diff --git a/Debug/test_coverage/PDE/CompFlow/Problem/SheddingFlow.hpp.gcov.html b/Debug/test_coverage/PDE/CompFlow/Problem/SheddingFlow.hpp.gcov.html index 9f0ee3616d5c..37d73358c9a0 100644 --- a/Debug/test_coverage/PDE/CompFlow/Problem/SheddingFlow.hpp.gcov.html +++ b/Debug/test_coverage/PDE/CompFlow/Problem/SheddingFlow.hpp.gcov.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:43:41 + 2024-07-11 15:06:04 Functions: 1 diff --git a/Debug/test_coverage/PDE/CompFlow/Problem/ShockDensityWave.cpp.func-sort-c.html b/Debug/test_coverage/PDE/CompFlow/Problem/ShockDensityWave.cpp.func-sort-c.html index 52aec871f9c8..2989f3ee174b 100644 --- a/Debug/test_coverage/PDE/CompFlow/Problem/ShockDensityWave.cpp.func-sort-c.html +++ b/Debug/test_coverage/PDE/CompFlow/Problem/ShockDensityWave.cpp.func-sort-c.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:43:41 + 2024-07-11 15:06:04 Functions: 0 diff --git a/Debug/test_coverage/PDE/CompFlow/Problem/ShockDensityWave.cpp.func.html b/Debug/test_coverage/PDE/CompFlow/Problem/ShockDensityWave.cpp.func.html index 417a97309dfa..fa63c447c9c4 100644 --- a/Debug/test_coverage/PDE/CompFlow/Problem/ShockDensityWave.cpp.func.html +++ b/Debug/test_coverage/PDE/CompFlow/Problem/ShockDensityWave.cpp.func.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:43:41 + 2024-07-11 15:06:04 Functions: 0 diff --git a/Debug/test_coverage/PDE/CompFlow/Problem/ShockDensityWave.cpp.gcov.html b/Debug/test_coverage/PDE/CompFlow/Problem/ShockDensityWave.cpp.gcov.html index 1bfdef952d48..414341ac480e 100644 --- a/Debug/test_coverage/PDE/CompFlow/Problem/ShockDensityWave.cpp.gcov.html +++ b/Debug/test_coverage/PDE/CompFlow/Problem/ShockDensityWave.cpp.gcov.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:43:41 + 2024-07-11 15:06:04 Functions: 0 diff --git a/Debug/test_coverage/PDE/CompFlow/Problem/ShockDensityWave.hpp.func-sort-c.html b/Debug/test_coverage/PDE/CompFlow/Problem/ShockDensityWave.hpp.func-sort-c.html index 915122a6d19c..7e437a4e2d58 100644 --- a/Debug/test_coverage/PDE/CompFlow/Problem/ShockDensityWave.hpp.func-sort-c.html +++ b/Debug/test_coverage/PDE/CompFlow/Problem/ShockDensityWave.hpp.func-sort-c.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:43:41 + 2024-07-11 15:06:04 Functions: 1 diff --git a/Debug/test_coverage/PDE/CompFlow/Problem/ShockDensityWave.hpp.func.html b/Debug/test_coverage/PDE/CompFlow/Problem/ShockDensityWave.hpp.func.html index d781a23f45fe..9ef54715b2de 100644 --- a/Debug/test_coverage/PDE/CompFlow/Problem/ShockDensityWave.hpp.func.html +++ b/Debug/test_coverage/PDE/CompFlow/Problem/ShockDensityWave.hpp.func.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:43:41 + 2024-07-11 15:06:04 Functions: 1 diff --git a/Debug/test_coverage/PDE/CompFlow/Problem/ShockDensityWave.hpp.gcov.html b/Debug/test_coverage/PDE/CompFlow/Problem/ShockDensityWave.hpp.gcov.html index 60ee4c43c06e..b539b5720368 100644 --- a/Debug/test_coverage/PDE/CompFlow/Problem/ShockDensityWave.hpp.gcov.html +++ b/Debug/test_coverage/PDE/CompFlow/Problem/ShockDensityWave.hpp.gcov.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:43:41 + 2024-07-11 15:06:04 Functions: 1 diff --git a/Debug/test_coverage/PDE/CompFlow/Problem/SodShocktube.cpp.func-sort-c.html b/Debug/test_coverage/PDE/CompFlow/Problem/SodShocktube.cpp.func-sort-c.html index f7a62984498a..3a7ab9526cf7 100644 --- a/Debug/test_coverage/PDE/CompFlow/Problem/SodShocktube.cpp.func-sort-c.html +++ b/Debug/test_coverage/PDE/CompFlow/Problem/SodShocktube.cpp.func-sort-c.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:43:41 + 2024-07-11 15:06:04 Functions: 2 diff --git a/Debug/test_coverage/PDE/CompFlow/Problem/SodShocktube.cpp.func.html b/Debug/test_coverage/PDE/CompFlow/Problem/SodShocktube.cpp.func.html index 91d95917fb13..709fa1f2f044 100644 --- a/Debug/test_coverage/PDE/CompFlow/Problem/SodShocktube.cpp.func.html +++ b/Debug/test_coverage/PDE/CompFlow/Problem/SodShocktube.cpp.func.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:43:41 + 2024-07-11 15:06:04 Functions: 2 diff --git a/Debug/test_coverage/PDE/CompFlow/Problem/SodShocktube.cpp.gcov.html b/Debug/test_coverage/PDE/CompFlow/Problem/SodShocktube.cpp.gcov.html index 3d57a26fef1f..422400ca7715 100644 --- a/Debug/test_coverage/PDE/CompFlow/Problem/SodShocktube.cpp.gcov.html +++ b/Debug/test_coverage/PDE/CompFlow/Problem/SodShocktube.cpp.gcov.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:43:41 + 2024-07-11 15:06:04 Functions: 2 diff --git a/Debug/test_coverage/PDE/CompFlow/Problem/SodShocktube.hpp.func-sort-c.html b/Debug/test_coverage/PDE/CompFlow/Problem/SodShocktube.hpp.func-sort-c.html index cb9458777bc3..b81b215298b3 100644 --- a/Debug/test_coverage/PDE/CompFlow/Problem/SodShocktube.hpp.func-sort-c.html +++ b/Debug/test_coverage/PDE/CompFlow/Problem/SodShocktube.hpp.func-sort-c.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:43:41 + 2024-07-11 15:06:04 Functions: 2 diff --git a/Debug/test_coverage/PDE/CompFlow/Problem/SodShocktube.hpp.func.html b/Debug/test_coverage/PDE/CompFlow/Problem/SodShocktube.hpp.func.html index da1a610c0224..cd39866258ba 100644 --- a/Debug/test_coverage/PDE/CompFlow/Problem/SodShocktube.hpp.func.html +++ b/Debug/test_coverage/PDE/CompFlow/Problem/SodShocktube.hpp.func.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:43:41 + 2024-07-11 15:06:04 Functions: 2 diff --git a/Debug/test_coverage/PDE/CompFlow/Problem/SodShocktube.hpp.gcov.html b/Debug/test_coverage/PDE/CompFlow/Problem/SodShocktube.hpp.gcov.html index 2c027bab924d..27f8e2ebc4fa 100644 --- a/Debug/test_coverage/PDE/CompFlow/Problem/SodShocktube.hpp.gcov.html +++ b/Debug/test_coverage/PDE/CompFlow/Problem/SodShocktube.hpp.gcov.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:43:41 + 2024-07-11 15:06:04 Functions: 2 diff --git a/Debug/test_coverage/PDE/CompFlow/Problem/TaylorGreen.cpp.func-sort-c.html b/Debug/test_coverage/PDE/CompFlow/Problem/TaylorGreen.cpp.func-sort-c.html index 899e33b1444b..19425b4aca7e 100644 --- a/Debug/test_coverage/PDE/CompFlow/Problem/TaylorGreen.cpp.func-sort-c.html +++ b/Debug/test_coverage/PDE/CompFlow/Problem/TaylorGreen.cpp.func-sort-c.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:43:41 + 2024-07-11 15:06:04 Functions: 4 diff --git a/Debug/test_coverage/PDE/CompFlow/Problem/TaylorGreen.cpp.func.html b/Debug/test_coverage/PDE/CompFlow/Problem/TaylorGreen.cpp.func.html index 9b4aeb45827c..766f7ff90257 100644 --- a/Debug/test_coverage/PDE/CompFlow/Problem/TaylorGreen.cpp.func.html +++ b/Debug/test_coverage/PDE/CompFlow/Problem/TaylorGreen.cpp.func.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:43:41 + 2024-07-11 15:06:04 Functions: 4 diff --git a/Debug/test_coverage/PDE/CompFlow/Problem/TaylorGreen.cpp.gcov.html b/Debug/test_coverage/PDE/CompFlow/Problem/TaylorGreen.cpp.gcov.html index 39df1b70e5cb..3b41a761b9ac 100644 --- a/Debug/test_coverage/PDE/CompFlow/Problem/TaylorGreen.cpp.gcov.html +++ b/Debug/test_coverage/PDE/CompFlow/Problem/TaylorGreen.cpp.gcov.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:43:41 + 2024-07-11 15:06:04 Functions: 4 diff --git a/Debug/test_coverage/PDE/CompFlow/Problem/TaylorGreen.hpp.func-sort-c.html b/Debug/test_coverage/PDE/CompFlow/Problem/TaylorGreen.hpp.func-sort-c.html index 1fc4ccd187ad..532327f95e51 100644 --- a/Debug/test_coverage/PDE/CompFlow/Problem/TaylorGreen.hpp.func-sort-c.html +++ b/Debug/test_coverage/PDE/CompFlow/Problem/TaylorGreen.hpp.func-sort-c.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:43:41 + 2024-07-11 15:06:04 Functions: 2 diff --git a/Debug/test_coverage/PDE/CompFlow/Problem/TaylorGreen.hpp.func.html b/Debug/test_coverage/PDE/CompFlow/Problem/TaylorGreen.hpp.func.html index 612d5b67209f..a95a18673e89 100644 --- a/Debug/test_coverage/PDE/CompFlow/Problem/TaylorGreen.hpp.func.html +++ b/Debug/test_coverage/PDE/CompFlow/Problem/TaylorGreen.hpp.func.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:43:41 + 2024-07-11 15:06:04 Functions: 2 diff --git a/Debug/test_coverage/PDE/CompFlow/Problem/TaylorGreen.hpp.gcov.html b/Debug/test_coverage/PDE/CompFlow/Problem/TaylorGreen.hpp.gcov.html index 742dca0ed640..92c41a194eec 100644 --- a/Debug/test_coverage/PDE/CompFlow/Problem/TaylorGreen.hpp.gcov.html +++ b/Debug/test_coverage/PDE/CompFlow/Problem/TaylorGreen.hpp.gcov.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:43:41 + 2024-07-11 15:06:04 Functions: 2 diff --git a/Debug/test_coverage/PDE/CompFlow/Problem/UserDefined.cpp.func-sort-c.html b/Debug/test_coverage/PDE/CompFlow/Problem/UserDefined.cpp.func-sort-c.html index d53ba75669f0..f0d62f01248d 100644 --- a/Debug/test_coverage/PDE/CompFlow/Problem/UserDefined.cpp.func-sort-c.html +++ b/Debug/test_coverage/PDE/CompFlow/Problem/UserDefined.cpp.func-sort-c.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:43:41 + 2024-07-11 15:06:04 Functions: 2 diff --git a/Debug/test_coverage/PDE/CompFlow/Problem/UserDefined.cpp.func.html b/Debug/test_coverage/PDE/CompFlow/Problem/UserDefined.cpp.func.html index 583ba12548cf..6ef6e52dc863 100644 --- a/Debug/test_coverage/PDE/CompFlow/Problem/UserDefined.cpp.func.html +++ b/Debug/test_coverage/PDE/CompFlow/Problem/UserDefined.cpp.func.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:43:41 + 2024-07-11 15:06:04 Functions: 2 diff --git a/Debug/test_coverage/PDE/CompFlow/Problem/UserDefined.cpp.gcov.html b/Debug/test_coverage/PDE/CompFlow/Problem/UserDefined.cpp.gcov.html index a2821eb8a850..235d553e3c48 100644 --- a/Debug/test_coverage/PDE/CompFlow/Problem/UserDefined.cpp.gcov.html +++ b/Debug/test_coverage/PDE/CompFlow/Problem/UserDefined.cpp.gcov.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:43:41 + 2024-07-11 15:06:04 Functions: 2 diff --git a/Debug/test_coverage/PDE/CompFlow/Problem/UserDefined.hpp.func-sort-c.html b/Debug/test_coverage/PDE/CompFlow/Problem/UserDefined.hpp.func-sort-c.html index 6512f1d09ebe..2a745b7d8ab4 100644 --- a/Debug/test_coverage/PDE/CompFlow/Problem/UserDefined.hpp.func-sort-c.html +++ b/Debug/test_coverage/PDE/CompFlow/Problem/UserDefined.hpp.func-sort-c.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:43:41 + 2024-07-11 15:06:04 Functions: 2 diff --git a/Debug/test_coverage/PDE/CompFlow/Problem/UserDefined.hpp.func.html b/Debug/test_coverage/PDE/CompFlow/Problem/UserDefined.hpp.func.html index 09fc67c805e5..d7addd04fd27 100644 --- a/Debug/test_coverage/PDE/CompFlow/Problem/UserDefined.hpp.func.html +++ b/Debug/test_coverage/PDE/CompFlow/Problem/UserDefined.hpp.func.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:43:41 + 2024-07-11 15:06:04 Functions: 2 diff --git a/Debug/test_coverage/PDE/CompFlow/Problem/UserDefined.hpp.gcov.html b/Debug/test_coverage/PDE/CompFlow/Problem/UserDefined.hpp.gcov.html index 38e788791ef4..2552ca330134 100644 --- a/Debug/test_coverage/PDE/CompFlow/Problem/UserDefined.hpp.gcov.html +++ b/Debug/test_coverage/PDE/CompFlow/Problem/UserDefined.hpp.gcov.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:43:41 + 2024-07-11 15:06:04 Functions: 2 diff --git a/Debug/test_coverage/PDE/CompFlow/Problem/VorticalFlow.cpp.func-sort-c.html b/Debug/test_coverage/PDE/CompFlow/Problem/VorticalFlow.cpp.func-sort-c.html index 4e5c4c056340..fb33e2723e64 100644 --- a/Debug/test_coverage/PDE/CompFlow/Problem/VorticalFlow.cpp.func-sort-c.html +++ b/Debug/test_coverage/PDE/CompFlow/Problem/VorticalFlow.cpp.func-sort-c.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:43:41 + 2024-07-11 15:06:04 Functions: 4 diff --git a/Debug/test_coverage/PDE/CompFlow/Problem/VorticalFlow.cpp.func.html b/Debug/test_coverage/PDE/CompFlow/Problem/VorticalFlow.cpp.func.html index 2268b8bde3ac..345b22cc3dfc 100644 --- a/Debug/test_coverage/PDE/CompFlow/Problem/VorticalFlow.cpp.func.html +++ b/Debug/test_coverage/PDE/CompFlow/Problem/VorticalFlow.cpp.func.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:43:41 + 2024-07-11 15:06:04 Functions: 4 diff --git a/Debug/test_coverage/PDE/CompFlow/Problem/VorticalFlow.cpp.gcov.html b/Debug/test_coverage/PDE/CompFlow/Problem/VorticalFlow.cpp.gcov.html index 3fc543ebc8ea..dbfba08f8c26 100644 --- a/Debug/test_coverage/PDE/CompFlow/Problem/VorticalFlow.cpp.gcov.html +++ b/Debug/test_coverage/PDE/CompFlow/Problem/VorticalFlow.cpp.gcov.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:43:41 + 2024-07-11 15:06:04 Functions: 4 diff --git a/Debug/test_coverage/PDE/CompFlow/Problem/VorticalFlow.hpp.func-sort-c.html b/Debug/test_coverage/PDE/CompFlow/Problem/VorticalFlow.hpp.func-sort-c.html index 3c06f73f9454..9a8f5662eeff 100644 --- a/Debug/test_coverage/PDE/CompFlow/Problem/VorticalFlow.hpp.func-sort-c.html +++ b/Debug/test_coverage/PDE/CompFlow/Problem/VorticalFlow.hpp.func-sort-c.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:43:41 + 2024-07-11 15:06:04 Functions: 2 diff --git a/Debug/test_coverage/PDE/CompFlow/Problem/VorticalFlow.hpp.func.html b/Debug/test_coverage/PDE/CompFlow/Problem/VorticalFlow.hpp.func.html index 132581d2cd61..5e126e215332 100644 --- a/Debug/test_coverage/PDE/CompFlow/Problem/VorticalFlow.hpp.func.html +++ b/Debug/test_coverage/PDE/CompFlow/Problem/VorticalFlow.hpp.func.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:43:41 + 2024-07-11 15:06:04 Functions: 2 diff --git a/Debug/test_coverage/PDE/CompFlow/Problem/VorticalFlow.hpp.gcov.html b/Debug/test_coverage/PDE/CompFlow/Problem/VorticalFlow.hpp.gcov.html index 0500cd0c824e..8d94424f2333 100644 --- a/Debug/test_coverage/PDE/CompFlow/Problem/VorticalFlow.hpp.gcov.html +++ b/Debug/test_coverage/PDE/CompFlow/Problem/VorticalFlow.hpp.gcov.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:43:41 + 2024-07-11 15:06:04 Functions: 2 diff --git a/Debug/test_coverage/PDE/CompFlow/Problem/index-sort-b.html b/Debug/test_coverage/PDE/CompFlow/Problem/index-sort-b.html index 08ebc106e07c..8c66f78a1c8a 100644 --- a/Debug/test_coverage/PDE/CompFlow/Problem/index-sort-b.html +++ b/Debug/test_coverage/PDE/CompFlow/Problem/index-sort-b.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:43:41 + 2024-07-11 15:06:04 Functions: 54 @@ -130,26 +130,26 @@ 0 / 46 - TaylorGreen.hpp + GaussHumpCompflow.hpp
100.0%
100.0 % - 8 / 8 + 6 / 6 100.0 % 2 / 2 12.5 % 1 / 8 - GaussHumpCompflow.hpp + UserDefined.hpp -
100.0%
+
60.0%60.0%
- 100.0 % - 6 / 6 - 100.0 % - 2 / 2 + 60.0 % + 6 / 10 + 50.0 % + 2 / 4 12.5 % 1 / 8 @@ -166,26 +166,26 @@ 1 / 8 - SodShocktube.hpp + TaylorGreen.hpp
100.0%
100.0 % - 6 / 6 + 8 / 8 100.0 % 2 / 2 12.5 % 1 / 8 - UserDefined.hpp + SodShocktube.hpp -
60.0%60.0%
+
100.0%
- 60.0 % - 6 / 10 - 50.0 % - 2 / 4 + 100.0 % + 6 / 6 + 100.0 % + 2 / 2 12.5 % 1 / 8 diff --git a/Debug/test_coverage/PDE/CompFlow/Problem/index-sort-f.html b/Debug/test_coverage/PDE/CompFlow/Problem/index-sort-f.html index f249ca3eebda..55fdea49c409 100644 --- a/Debug/test_coverage/PDE/CompFlow/Problem/index-sort-f.html +++ b/Debug/test_coverage/PDE/CompFlow/Problem/index-sort-f.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:43:41 + 2024-07-11 15:06:04 Functions: 54 @@ -117,6 +117,18 @@ 0.0 % 0 / 8 + + BoxInitialization.hpp + +
83.9%83.9%
+ + 83.9 % + 47 / 56 + 50.0 % + 1 / 2 + 34.8 % + 16 / 46 + ShockDensityWave.hpp @@ -130,16 +142,28 @@ 0 / 8 - BoxInitialization.hpp + UserDefined.hpp -
83.9%83.9%
+
60.0%60.0%
- 83.9 % - 47 / 56 + 60.0 % + 6 / 10 50.0 % - 1 / 2 - 34.8 % - 16 / 46 + 2 / 4 + 12.5 % + 1 / 8 + + + SodShocktube.cpp + +
59.3%59.3%
+ + 59.3 % + 16 / 27 + 50.0 % + 2 / 4 + 26.1 % + 12 / 46 SedovBlastwave.cpp @@ -166,28 +190,16 @@ 10 / 48 - UserDefined.hpp - -
60.0%60.0%
- - 60.0 % - 6 / 10 - 50.0 % - 2 / 4 - 12.5 % - 1 / 8 - - - SodShocktube.cpp + RotatedSodShocktube.hpp -
59.3%59.3%
+
100.0%
- 59.3 % - 16 / 27 - 50.0 % - 2 / 4 - 26.1 % - 12 / 46 + 100.0 % + 2 / 2 + 100.0 % + 1 / 1 + - + 0 / 0 RotatedSodShocktube.cpp @@ -202,24 +214,36 @@ 1 / 2 - RotatedSodShocktube.hpp + GaussHumpCompflow.hpp
100.0%
100.0 % + 6 / 6 + 100.0 % 2 / 2 + 12.5 % + 1 / 8 + + + UserDefined.cpp + +
75.0%75.0%
+ + 75.0 % + 18 / 24 100.0 % - 1 / 1 - - - 0 / 0 + 2 / 2 + 32.4 % + 11 / 34 - TaylorGreen.hpp + SedovBlastwave.hpp
100.0%
100.0 % - 8 / 8 + 6 / 6 100.0 % 2 / 2 12.5 % @@ -250,31 +274,19 @@ 3 / 12 - UserDefined.cpp - -
75.0%75.0%
- - 75.0 % - 18 / 24 - 100.0 % - 2 / 2 - 32.4 % - 11 / 34 - - - GaussHumpCompflow.hpp + TaylorGreen.hpp
100.0%
100.0 % - 6 / 6 + 8 / 8 100.0 % 2 / 2 12.5 % 1 / 8 - SedovBlastwave.hpp + SodShocktube.hpp
100.0%
@@ -298,16 +310,16 @@ 4 / 14 - SodShocktube.hpp + TaylorGreen.cpp
100.0%
100.0 % - 6 / 6 + 27 / 27 100.0 % - 2 / 2 - 12.5 % - 1 / 8 + 4 / 4 + 50.0 % + 24 / 48 VorticalFlow.cpp @@ -321,18 +333,6 @@ 50.0 % 22 / 44 - - TaylorGreen.cpp - -
100.0%
- - 100.0 % - 27 / 27 - 100.0 % - 4 / 4 - 50.0 % - 24 / 48 - GaussHumpCompflow.cpp @@ -346,28 +346,28 @@ 31 / 72 - FieldOutput.cpp + NLEnergyGrowth.cpp
100.0%
100.0 % - 99 / 99 + 44 / 44 100.0 % 6 / 6 50.0 % - 86 / 172 + 25 / 50 - NLEnergyGrowth.cpp + FieldOutput.cpp
100.0%
100.0 % - 44 / 44 + 99 / 99 100.0 % 6 / 6 50.0 % - 25 / 50 + 86 / 172 diff --git a/Debug/test_coverage/PDE/CompFlow/Problem/index-sort-l.html b/Debug/test_coverage/PDE/CompFlow/Problem/index-sort-l.html index f85f67ad4338..f8579ea775b4 100644 --- a/Debug/test_coverage/PDE/CompFlow/Problem/index-sort-l.html +++ b/Debug/test_coverage/PDE/CompFlow/Problem/index-sort-l.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:43:41 + 2024-07-11 15:06:04 Functions: 54 diff --git a/Debug/test_coverage/PDE/CompFlow/Problem/index.html b/Debug/test_coverage/PDE/CompFlow/Problem/index.html index d799305de83d..626c61b58ead 100644 --- a/Debug/test_coverage/PDE/CompFlow/Problem/index.html +++ b/Debug/test_coverage/PDE/CompFlow/Problem/index.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:43:41 + 2024-07-11 15:06:04 Functions: 54 diff --git a/Debug/test_coverage/PDE/CompFlow/RiemannChoice.hpp.func-sort-c.html b/Debug/test_coverage/PDE/CompFlow/RiemannChoice.hpp.func-sort-c.html index 1cf57022d328..a697b8805f67 100644 --- a/Debug/test_coverage/PDE/CompFlow/RiemannChoice.hpp.func-sort-c.html +++ b/Debug/test_coverage/PDE/CompFlow/RiemannChoice.hpp.func-sort-c.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:43:41 + 2024-07-11 15:06:04 Functions: 1 diff --git a/Debug/test_coverage/PDE/CompFlow/RiemannChoice.hpp.func.html b/Debug/test_coverage/PDE/CompFlow/RiemannChoice.hpp.func.html index 659d909ac60b..a005042e8821 100644 --- a/Debug/test_coverage/PDE/CompFlow/RiemannChoice.hpp.func.html +++ b/Debug/test_coverage/PDE/CompFlow/RiemannChoice.hpp.func.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:43:41 + 2024-07-11 15:06:04 Functions: 1 diff --git a/Debug/test_coverage/PDE/CompFlow/RiemannChoice.hpp.gcov.html b/Debug/test_coverage/PDE/CompFlow/RiemannChoice.hpp.gcov.html index 1be6f1405629..a2195111ddf4 100644 --- a/Debug/test_coverage/PDE/CompFlow/RiemannChoice.hpp.gcov.html +++ b/Debug/test_coverage/PDE/CompFlow/RiemannChoice.hpp.gcov.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:43:41 + 2024-07-11 15:06:04 Functions: 1 diff --git a/Debug/test_coverage/PDE/CompFlow/index-sort-b.html b/Debug/test_coverage/PDE/CompFlow/index-sort-b.html index bb5a840de87e..25207ecc1d41 100644 --- a/Debug/test_coverage/PDE/CompFlow/index-sort-b.html +++ b/Debug/test_coverage/PDE/CompFlow/index-sort-b.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:43:41 + 2024-07-11 15:06:04 Functions: 340 diff --git a/Debug/test_coverage/PDE/CompFlow/index-sort-f.html b/Debug/test_coverage/PDE/CompFlow/index-sort-f.html index a1be83a9514a..49e2bbecb69c 100644 --- a/Debug/test_coverage/PDE/CompFlow/index-sort-f.html +++ b/Debug/test_coverage/PDE/CompFlow/index-sort-f.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:43:41 + 2024-07-11 15:06:04 Functions: 340 diff --git a/Debug/test_coverage/PDE/CompFlow/index-sort-l.html b/Debug/test_coverage/PDE/CompFlow/index-sort-l.html index f07814ffea69..acb70338cd69 100644 --- a/Debug/test_coverage/PDE/CompFlow/index-sort-l.html +++ b/Debug/test_coverage/PDE/CompFlow/index-sort-l.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:43:41 + 2024-07-11 15:06:04 Functions: 340 diff --git a/Debug/test_coverage/PDE/CompFlow/index.html b/Debug/test_coverage/PDE/CompFlow/index.html index bf6a7210c843..7dc2533b7699 100644 --- a/Debug/test_coverage/PDE/CompFlow/index.html +++ b/Debug/test_coverage/PDE/CompFlow/index.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:43:41 + 2024-07-11 15:06:04 Functions: 340 diff --git a/Debug/test_coverage/PDE/ConfigureCompFlow.cpp.func-sort-c.html b/Debug/test_coverage/PDE/ConfigureCompFlow.cpp.func-sort-c.html index 651352577aec..4ddfa88d170a 100644 --- a/Debug/test_coverage/PDE/ConfigureCompFlow.cpp.func-sort-c.html +++ b/Debug/test_coverage/PDE/ConfigureCompFlow.cpp.func-sort-c.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:43:41 + 2024-07-11 15:06:04 Functions: 2 diff --git a/Debug/test_coverage/PDE/ConfigureCompFlow.cpp.func.html b/Debug/test_coverage/PDE/ConfigureCompFlow.cpp.func.html index ecc98cadde9e..721b6ee673e5 100644 --- a/Debug/test_coverage/PDE/ConfigureCompFlow.cpp.func.html +++ b/Debug/test_coverage/PDE/ConfigureCompFlow.cpp.func.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:43:41 + 2024-07-11 15:06:04 Functions: 2 diff --git a/Debug/test_coverage/PDE/ConfigureCompFlow.cpp.gcov.html b/Debug/test_coverage/PDE/ConfigureCompFlow.cpp.gcov.html index bf04785bb621..4ea70807dbc3 100644 --- a/Debug/test_coverage/PDE/ConfigureCompFlow.cpp.gcov.html +++ b/Debug/test_coverage/PDE/ConfigureCompFlow.cpp.gcov.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:43:41 + 2024-07-11 15:06:04 Functions: 2 diff --git a/Debug/test_coverage/PDE/ConfigureCompFlow.hpp.func-sort-c.html b/Debug/test_coverage/PDE/ConfigureCompFlow.hpp.func-sort-c.html index 5415b9bcee54..43d691a981d7 100644 --- a/Debug/test_coverage/PDE/ConfigureCompFlow.hpp.func-sort-c.html +++ b/Debug/test_coverage/PDE/ConfigureCompFlow.hpp.func-sort-c.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:43:41 + 2024-07-11 15:06:04 Functions: 6 diff --git a/Debug/test_coverage/PDE/ConfigureCompFlow.hpp.func.html b/Debug/test_coverage/PDE/ConfigureCompFlow.hpp.func.html index 422f94380146..0397a448edc8 100644 --- a/Debug/test_coverage/PDE/ConfigureCompFlow.hpp.func.html +++ b/Debug/test_coverage/PDE/ConfigureCompFlow.hpp.func.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:43:41 + 2024-07-11 15:06:04 Functions: 6 diff --git a/Debug/test_coverage/PDE/ConfigureCompFlow.hpp.gcov.html b/Debug/test_coverage/PDE/ConfigureCompFlow.hpp.gcov.html index 5d53e6c70700..a5a4c37e9a83 100644 --- a/Debug/test_coverage/PDE/ConfigureCompFlow.hpp.gcov.html +++ b/Debug/test_coverage/PDE/ConfigureCompFlow.hpp.gcov.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:43:41 + 2024-07-11 15:06:04 Functions: 6 diff --git a/Debug/test_coverage/PDE/ConfigureMultiMat.cpp.func-sort-c.html b/Debug/test_coverage/PDE/ConfigureMultiMat.cpp.func-sort-c.html index 3e02c52459fb..06cf82ee3143 100644 --- a/Debug/test_coverage/PDE/ConfigureMultiMat.cpp.func-sort-c.html +++ b/Debug/test_coverage/PDE/ConfigureMultiMat.cpp.func-sort-c.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:43:41 + 2024-07-11 15:06:04 Functions: 2 diff --git a/Debug/test_coverage/PDE/ConfigureMultiMat.cpp.func.html b/Debug/test_coverage/PDE/ConfigureMultiMat.cpp.func.html index 4d2fc55cea1d..96c49ca5731a 100644 --- a/Debug/test_coverage/PDE/ConfigureMultiMat.cpp.func.html +++ b/Debug/test_coverage/PDE/ConfigureMultiMat.cpp.func.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:43:41 + 2024-07-11 15:06:04 Functions: 2 diff --git a/Debug/test_coverage/PDE/ConfigureMultiMat.cpp.gcov.html b/Debug/test_coverage/PDE/ConfigureMultiMat.cpp.gcov.html index 738f4ddcb27f..cfeaa112ece1 100644 --- a/Debug/test_coverage/PDE/ConfigureMultiMat.cpp.gcov.html +++ b/Debug/test_coverage/PDE/ConfigureMultiMat.cpp.gcov.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:43:41 + 2024-07-11 15:06:04 Functions: 2 diff --git a/Debug/test_coverage/PDE/ConfigureMultiMat.hpp.func-sort-c.html b/Debug/test_coverage/PDE/ConfigureMultiMat.hpp.func-sort-c.html index 964a50ccd5b6..df09e8d7b1f3 100644 --- a/Debug/test_coverage/PDE/ConfigureMultiMat.hpp.func-sort-c.html +++ b/Debug/test_coverage/PDE/ConfigureMultiMat.hpp.func-sort-c.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:43:41 + 2024-07-11 15:06:04 Functions: 7 diff --git a/Debug/test_coverage/PDE/ConfigureMultiMat.hpp.func.html b/Debug/test_coverage/PDE/ConfigureMultiMat.hpp.func.html index 61dcb6abfd4a..ff623b7df8d7 100644 --- a/Debug/test_coverage/PDE/ConfigureMultiMat.hpp.func.html +++ b/Debug/test_coverage/PDE/ConfigureMultiMat.hpp.func.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:43:41 + 2024-07-11 15:06:04 Functions: 7 diff --git a/Debug/test_coverage/PDE/ConfigureMultiMat.hpp.gcov.html b/Debug/test_coverage/PDE/ConfigureMultiMat.hpp.gcov.html index 673b168b544a..fece228fd1fa 100644 --- a/Debug/test_coverage/PDE/ConfigureMultiMat.hpp.gcov.html +++ b/Debug/test_coverage/PDE/ConfigureMultiMat.hpp.gcov.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:43:41 + 2024-07-11 15:06:04 Functions: 7 diff --git a/Debug/test_coverage/PDE/ConfigureTransport.cpp.func-sort-c.html b/Debug/test_coverage/PDE/ConfigureTransport.cpp.func-sort-c.html index fa3075896f38..57c6e5f6d540 100644 --- a/Debug/test_coverage/PDE/ConfigureTransport.cpp.func-sort-c.html +++ b/Debug/test_coverage/PDE/ConfigureTransport.cpp.func-sort-c.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:43:41 + 2024-07-11 15:06:04 Functions: 2 diff --git a/Debug/test_coverage/PDE/ConfigureTransport.cpp.func.html b/Debug/test_coverage/PDE/ConfigureTransport.cpp.func.html index d3daf99273e8..c68b6f0ccc3f 100644 --- a/Debug/test_coverage/PDE/ConfigureTransport.cpp.func.html +++ b/Debug/test_coverage/PDE/ConfigureTransport.cpp.func.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:43:41 + 2024-07-11 15:06:04 Functions: 2 diff --git a/Debug/test_coverage/PDE/ConfigureTransport.cpp.gcov.html b/Debug/test_coverage/PDE/ConfigureTransport.cpp.gcov.html index d59c1ca6c9a9..00230df78709 100644 --- a/Debug/test_coverage/PDE/ConfigureTransport.cpp.gcov.html +++ b/Debug/test_coverage/PDE/ConfigureTransport.cpp.gcov.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:43:41 + 2024-07-11 15:06:04 Functions: 2 diff --git a/Debug/test_coverage/PDE/ConfigureTransport.hpp.func-sort-c.html b/Debug/test_coverage/PDE/ConfigureTransport.hpp.func-sort-c.html index da26dddb64bb..b6270f3a0792 100644 --- a/Debug/test_coverage/PDE/ConfigureTransport.hpp.func-sort-c.html +++ b/Debug/test_coverage/PDE/ConfigureTransport.hpp.func-sort-c.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:43:41 + 2024-07-11 15:06:04 Functions: 0 diff --git a/Debug/test_coverage/PDE/ConfigureTransport.hpp.func.html b/Debug/test_coverage/PDE/ConfigureTransport.hpp.func.html index b6f506d0793f..3594c46d1da7 100644 --- a/Debug/test_coverage/PDE/ConfigureTransport.hpp.func.html +++ b/Debug/test_coverage/PDE/ConfigureTransport.hpp.func.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:43:41 + 2024-07-11 15:06:04 Functions: 0 diff --git a/Debug/test_coverage/PDE/ConfigureTransport.hpp.gcov.html b/Debug/test_coverage/PDE/ConfigureTransport.hpp.gcov.html index 4add5ef38d49..7bbfbaa155b5 100644 --- a/Debug/test_coverage/PDE/ConfigureTransport.hpp.gcov.html +++ b/Debug/test_coverage/PDE/ConfigureTransport.hpp.gcov.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:43:41 + 2024-07-11 15:06:04 Functions: 0 diff --git a/Debug/test_coverage/PDE/DGPDE.cpp.func-sort-c.html b/Debug/test_coverage/PDE/DGPDE.cpp.func-sort-c.html index 3eed2d5c1d05..99daf588566d 100644 --- a/Debug/test_coverage/PDE/DGPDE.cpp.func-sort-c.html +++ b/Debug/test_coverage/PDE/DGPDE.cpp.func-sort-c.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:43:41 + 2024-07-11 15:06:04 Functions: 0 diff --git a/Debug/test_coverage/PDE/DGPDE.cpp.func.html b/Debug/test_coverage/PDE/DGPDE.cpp.func.html index 8a8a9d948aa3..34dcfd2a71fc 100644 --- a/Debug/test_coverage/PDE/DGPDE.cpp.func.html +++ b/Debug/test_coverage/PDE/DGPDE.cpp.func.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:43:41 + 2024-07-11 15:06:04 Functions: 0 diff --git a/Debug/test_coverage/PDE/DGPDE.cpp.gcov.html b/Debug/test_coverage/PDE/DGPDE.cpp.gcov.html index 3bb487d5f0c0..121668dd8154 100644 --- a/Debug/test_coverage/PDE/DGPDE.cpp.gcov.html +++ b/Debug/test_coverage/PDE/DGPDE.cpp.gcov.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:43:41 + 2024-07-11 15:06:04 Functions: 0 diff --git a/Debug/test_coverage/PDE/DGPDE.hpp.func-sort-c.html b/Debug/test_coverage/PDE/DGPDE.hpp.func-sort-c.html index c9db8c02abb3..4104825a0bb6 100644 --- a/Debug/test_coverage/PDE/DGPDE.hpp.func-sort-c.html +++ b/Debug/test_coverage/PDE/DGPDE.hpp.func-sort-c.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:43:41 + 2024-07-11 15:06:04 Functions: 337 diff --git a/Debug/test_coverage/PDE/DGPDE.hpp.func.html b/Debug/test_coverage/PDE/DGPDE.hpp.func.html index 484a00efa1ff..354b6d70a9e0 100644 --- a/Debug/test_coverage/PDE/DGPDE.hpp.func.html +++ b/Debug/test_coverage/PDE/DGPDE.hpp.func.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:43:41 + 2024-07-11 15:06:04 Functions: 337 diff --git a/Debug/test_coverage/PDE/DGPDE.hpp.gcov.html b/Debug/test_coverage/PDE/DGPDE.hpp.gcov.html index 3b2db22c63ef..4c322bb2c50c 100644 --- a/Debug/test_coverage/PDE/DGPDE.hpp.gcov.html +++ b/Debug/test_coverage/PDE/DGPDE.hpp.gcov.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:43:41 + 2024-07-11 15:06:04 Functions: 337 diff --git a/Debug/test_coverage/PDE/EoS/EOS.cpp.func-sort-c.html b/Debug/test_coverage/PDE/EoS/EOS.cpp.func-sort-c.html index 6850ef72ba12..5a47b4df6cca 100644 --- a/Debug/test_coverage/PDE/EoS/EOS.cpp.func-sort-c.html +++ b/Debug/test_coverage/PDE/EoS/EOS.cpp.func-sort-c.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:43:41 + 2024-07-11 15:06:04 Functions: 1 diff --git a/Debug/test_coverage/PDE/EoS/EOS.cpp.func.html b/Debug/test_coverage/PDE/EoS/EOS.cpp.func.html index ade42e9d43de..d16fb6b65606 100644 --- a/Debug/test_coverage/PDE/EoS/EOS.cpp.func.html +++ b/Debug/test_coverage/PDE/EoS/EOS.cpp.func.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:43:41 + 2024-07-11 15:06:04 Functions: 1 diff --git a/Debug/test_coverage/PDE/EoS/EOS.cpp.gcov.html b/Debug/test_coverage/PDE/EoS/EOS.cpp.gcov.html index 1fd014cb32fb..8aee3c606ece 100644 --- a/Debug/test_coverage/PDE/EoS/EOS.cpp.gcov.html +++ b/Debug/test_coverage/PDE/EoS/EOS.cpp.gcov.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:43:41 + 2024-07-11 15:06:04 Functions: 1 diff --git a/Debug/test_coverage/PDE/EoS/EOS.hpp.func-sort-c.html b/Debug/test_coverage/PDE/EoS/EOS.hpp.func-sort-c.html index 362f8ba15c6d..19ae421e2bd7 100644 --- a/Debug/test_coverage/PDE/EoS/EOS.hpp.func-sort-c.html +++ b/Debug/test_coverage/PDE/EoS/EOS.hpp.func-sort-c.html @@ -33,12 +33,12 @@ Date: - 2024-07-10 11:43:41 + 2024-07-11 15:06:04 Functions: - 68 + 70 156 - 43.6 % + 44.9 % Legend: @@ -79,10 +79,6 @@ std::array<std::array<double, 3ul>, 3ul> inciter::EOS::computeTensor<inciter::EOS::CauchyStress, double, double, double, double, double, double&, unsigned long&, std::array<std::array<double, 3ul>, 3ul>&>(double&&, double&&, double&&, double&&, double&&, double&, unsigned long&, std::array<std::array<double, 3ul>, 3ul>&) const 0 - - double inciter::EOS::compute<inciter::EOS::soundspeed, double const&, double&, double&, unsigned long&, std::array<std::array<double, 3ul>, 3ul>&>(double const&, double&, double&, unsigned long&, std::array<std::array<double, 3ul>, 3ul>&) const - 0 - double inciter::EOS::compute<inciter::EOS::soundspeed, double const&, double const&, double const&, unsigned long&>(double const&, double const&, double const&, unsigned long&) const 0 @@ -131,10 +127,6 @@ double inciter::EOS::compute<inciter::EOS::soundspeed, double const&, double&, double&, unsigned long&>(double const&, double&, double&, unsigned long&) const::{lambda(auto:1 const&)#1}::operator()<inciter::JWL>(inciter::JWL const&) const 0 - - double inciter::EOS::compute<inciter::EOS::soundspeed, double const&, double&, double&, unsigned long&, std::array<std::array<double, 3ul>, 3ul>&>(double const&, double&, double&, unsigned long&, std::array<std::array<double, 3ul>, 3ul>&) const::{lambda(auto:1 const&)#1}::operator()<inciter::StiffenedGas>(inciter::StiffenedGas const&) const - 0 - double inciter::EOS::compute<inciter::EOS::soundspeed, double const&, double&, double&, unsigned long&, std::array<std::array<double, 3ul>, 3ul>&>(double const&, double&, double&, unsigned long&, std::array<std::array<double, 3ul>, 3ul>&) const::{lambda(auto:1 const&)#1}::operator()<inciter::SmallShearSolid>(inciter::SmallShearSolid const&) const 0 @@ -551,6 +543,14 @@ double inciter::EOS::compute<inciter::EOS::totalenergy, double&, double, double, double, double const&>(double&, double&&, double&&, double&&, double const&) const::{lambda(auto:1 const&)#1}::operator()<inciter::StiffenedGas>(inciter::StiffenedGas const&) const 547066 + + double inciter::EOS::compute<inciter::EOS::soundspeed, double const&, double&, double&, unsigned long&, std::array<std::array<double, 3ul>, 3ul>&>(double const&, double&, double&, unsigned long&, std::array<std::array<double, 3ul>, 3ul>&) const + 686000 + + + double inciter::EOS::compute<inciter::EOS::soundspeed, double const&, double&, double&, unsigned long&, std::array<std::array<double, 3ul>, 3ul>&>(double const&, double&, double&, unsigned long&, std::array<std::array<double, 3ul>, 3ul>&) const::{lambda(auto:1 const&)#1}::operator()<inciter::StiffenedGas>(inciter::StiffenedGas const&) const + 686000 + double inciter::EOS::compute<inciter::EOS::density, double&, double>(double&, double&&) const 770128 @@ -657,11 +657,11 @@ double inciter::EOS::compute<inciter::EOS::soundspeed, double const&, double&, double&, unsigned long&>(double const&, double&, double&, unsigned long&) const - 38295696 + 37609696 double inciter::EOS::compute<inciter::EOS::soundspeed, double const&, double&, double&, unsigned long&>(double const&, double&, double&, unsigned long&) const::{lambda(auto:1 const&)#1}::operator()<inciter::StiffenedGas>(inciter::StiffenedGas const&) const - 38295696 + 37609696 double inciter::EOS::compute<inciter::EOS::pressure, double&, double&, double&, double&, double const&>(double&, double&, double&, double&, double const&) const diff --git a/Debug/test_coverage/PDE/EoS/EOS.hpp.func.html b/Debug/test_coverage/PDE/EoS/EOS.hpp.func.html index a8079a41580d..7cb6dc1d8361 100644 --- a/Debug/test_coverage/PDE/EoS/EOS.hpp.func.html +++ b/Debug/test_coverage/PDE/EoS/EOS.hpp.func.html @@ -33,12 +33,12 @@ Date: - 2024-07-10 11:43:41 + 2024-07-11 15:06:04 Functions: - 68 + 70 156 - 43.6 % + 44.9 % Legend: @@ -85,11 +85,11 @@ double inciter::EOS::compute<inciter::EOS::soundspeed, double const&, double&, double&, unsigned long&>(double const&, double&, double&, unsigned long&) const - 38295696 + 37609696 double inciter::EOS::compute<inciter::EOS::soundspeed, double const&, double&, double&, unsigned long&, std::array<std::array<double, 3ul>, 3ul>&>(double const&, double&, double&, unsigned long&, std::array<std::array<double, 3ul>, 3ul>&) const - 0 + 686000 double inciter::EOS::compute<inciter::EOS::soundspeed, double const&, double const&, double const&, unsigned long&>(double const&, double const&, double const&, unsigned long&) const @@ -265,7 +265,7 @@ double inciter::EOS::compute<inciter::EOS::soundspeed, double const&, double&, double&, unsigned long&>(double const&, double&, double&, unsigned long&) const::{lambda(auto:1 const&)#1}::operator()<inciter::StiffenedGas>(inciter::StiffenedGas const&) const - 38295696 + 37609696 double inciter::EOS::compute<inciter::EOS::soundspeed, double const&, double&, double&, unsigned long&>(double const&, double&, double&, unsigned long&) const::{lambda(auto:1 const&)#1}::operator()<inciter::SmallShearSolid>(inciter::SmallShearSolid const&) const @@ -277,7 +277,7 @@ double inciter::EOS::compute<inciter::EOS::soundspeed, double const&, double&, double&, unsigned long&, std::array<std::array<double, 3ul>, 3ul>&>(double const&, double&, double&, unsigned long&, std::array<std::array<double, 3ul>, 3ul>&) const::{lambda(auto:1 const&)#1}::operator()<inciter::StiffenedGas>(inciter::StiffenedGas const&) const - 0 + 686000 double inciter::EOS::compute<inciter::EOS::soundspeed, double const&, double&, double&, unsigned long&, std::array<std::array<double, 3ul>, 3ul>&>(double const&, double&, double&, unsigned long&, std::array<std::array<double, 3ul>, 3ul>&) const::{lambda(auto:1 const&)#1}::operator()<inciter::SmallShearSolid>(inciter::SmallShearSolid const&) const diff --git a/Debug/test_coverage/PDE/EoS/EOS.hpp.gcov.html b/Debug/test_coverage/PDE/EoS/EOS.hpp.gcov.html index a0f7d4d52a89..50e951501954 100644 --- a/Debug/test_coverage/PDE/EoS/EOS.hpp.gcov.html +++ b/Debug/test_coverage/PDE/EoS/EOS.hpp.gcov.html @@ -33,12 +33,12 @@ Date: - 2024-07-10 11:43:41 + 2024-07-11 15:06:04 Functions: - 68 + 70 156 - 43.6 % + 44.9 % Legend: @@ -155,8 +155,8 @@ [ + - ][ - - ] [ - - ][ + - ] [ - - ][ - - ] - [ + - ][ - - ] - [ - - ][ + - ] + [ + - ][ - - ] + [ - - ][ + - ] 74 : : 75 : : else if constexpr( std::is_same_v< Fn, shearspeed > ) 76 : : return m.shearspeed( std::forward< Args >( args )... ); diff --git a/Debug/test_coverage/PDE/EoS/GetMatProp.hpp.func-sort-c.html b/Debug/test_coverage/PDE/EoS/GetMatProp.hpp.func-sort-c.html index d8cfc340ea22..1610b69dd40c 100644 --- a/Debug/test_coverage/PDE/EoS/GetMatProp.hpp.func-sort-c.html +++ b/Debug/test_coverage/PDE/EoS/GetMatProp.hpp.func-sort-c.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:43:41 + 2024-07-11 15:06:04 Functions: 3 diff --git a/Debug/test_coverage/PDE/EoS/GetMatProp.hpp.func.html b/Debug/test_coverage/PDE/EoS/GetMatProp.hpp.func.html index 53d2559d2a03..316244c2ec8f 100644 --- a/Debug/test_coverage/PDE/EoS/GetMatProp.hpp.func.html +++ b/Debug/test_coverage/PDE/EoS/GetMatProp.hpp.func.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:43:41 + 2024-07-11 15:06:04 Functions: 3 diff --git a/Debug/test_coverage/PDE/EoS/GetMatProp.hpp.gcov.html b/Debug/test_coverage/PDE/EoS/GetMatProp.hpp.gcov.html index ed6ce2d22279..b04d6dad83e3 100644 --- a/Debug/test_coverage/PDE/EoS/GetMatProp.hpp.gcov.html +++ b/Debug/test_coverage/PDE/EoS/GetMatProp.hpp.gcov.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:43:41 + 2024-07-11 15:06:04 Functions: 3 diff --git a/Debug/test_coverage/PDE/EoS/JWL.cpp.func-sort-c.html b/Debug/test_coverage/PDE/EoS/JWL.cpp.func-sort-c.html index 727f57a41a39..22cd64387887 100644 --- a/Debug/test_coverage/PDE/EoS/JWL.cpp.func-sort-c.html +++ b/Debug/test_coverage/PDE/EoS/JWL.cpp.func-sort-c.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:43:41 + 2024-07-11 15:06:04 Functions: 0 diff --git a/Debug/test_coverage/PDE/EoS/JWL.cpp.func.html b/Debug/test_coverage/PDE/EoS/JWL.cpp.func.html index b6780f004291..28e7528171f7 100644 --- a/Debug/test_coverage/PDE/EoS/JWL.cpp.func.html +++ b/Debug/test_coverage/PDE/EoS/JWL.cpp.func.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:43:41 + 2024-07-11 15:06:04 Functions: 0 diff --git a/Debug/test_coverage/PDE/EoS/JWL.cpp.gcov.html b/Debug/test_coverage/PDE/EoS/JWL.cpp.gcov.html index babeb5404da4..837fd45c547a 100644 --- a/Debug/test_coverage/PDE/EoS/JWL.cpp.gcov.html +++ b/Debug/test_coverage/PDE/EoS/JWL.cpp.gcov.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:43:41 + 2024-07-11 15:06:04 Functions: 0 diff --git a/Debug/test_coverage/PDE/EoS/SmallShearSolid.cpp.func-sort-c.html b/Debug/test_coverage/PDE/EoS/SmallShearSolid.cpp.func-sort-c.html index 883b0d290597..48deb81d61a8 100644 --- a/Debug/test_coverage/PDE/EoS/SmallShearSolid.cpp.func-sort-c.html +++ b/Debug/test_coverage/PDE/EoS/SmallShearSolid.cpp.func-sort-c.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:43:41 + 2024-07-11 15:06:04 Functions: 0 diff --git a/Debug/test_coverage/PDE/EoS/SmallShearSolid.cpp.func.html b/Debug/test_coverage/PDE/EoS/SmallShearSolid.cpp.func.html index 27b3e675df65..3b4668b0c53d 100644 --- a/Debug/test_coverage/PDE/EoS/SmallShearSolid.cpp.func.html +++ b/Debug/test_coverage/PDE/EoS/SmallShearSolid.cpp.func.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:43:41 + 2024-07-11 15:06:04 Functions: 0 diff --git a/Debug/test_coverage/PDE/EoS/SmallShearSolid.cpp.gcov.html b/Debug/test_coverage/PDE/EoS/SmallShearSolid.cpp.gcov.html index 3da283c6c2b3..747e6e0d3036 100644 --- a/Debug/test_coverage/PDE/EoS/SmallShearSolid.cpp.gcov.html +++ b/Debug/test_coverage/PDE/EoS/SmallShearSolid.cpp.gcov.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:43:41 + 2024-07-11 15:06:04 Functions: 0 diff --git a/Debug/test_coverage/PDE/EoS/StiffenedGas.cpp.func-sort-c.html b/Debug/test_coverage/PDE/EoS/StiffenedGas.cpp.func-sort-c.html index 664b3860f9ff..249618369193 100644 --- a/Debug/test_coverage/PDE/EoS/StiffenedGas.cpp.func-sort-c.html +++ b/Debug/test_coverage/PDE/EoS/StiffenedGas.cpp.func-sort-c.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:43:41 + 2024-07-11 15:06:04 Functions: 7 diff --git a/Debug/test_coverage/PDE/EoS/StiffenedGas.cpp.func.html b/Debug/test_coverage/PDE/EoS/StiffenedGas.cpp.func.html index d1cc2026f387..6e7cf8d88354 100644 --- a/Debug/test_coverage/PDE/EoS/StiffenedGas.cpp.func.html +++ b/Debug/test_coverage/PDE/EoS/StiffenedGas.cpp.func.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:43:41 + 2024-07-11 15:06:04 Functions: 7 diff --git a/Debug/test_coverage/PDE/EoS/StiffenedGas.cpp.gcov.html b/Debug/test_coverage/PDE/EoS/StiffenedGas.cpp.gcov.html index b7a3975a4a90..e11e82335f62 100644 --- a/Debug/test_coverage/PDE/EoS/StiffenedGas.cpp.gcov.html +++ b/Debug/test_coverage/PDE/EoS/StiffenedGas.cpp.gcov.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:43:41 + 2024-07-11 15:06:04 Functions: 7 diff --git a/Debug/test_coverage/PDE/EoS/index-sort-b.html b/Debug/test_coverage/PDE/EoS/index-sort-b.html index d632710b630d..f887c6f7bf56 100644 --- a/Debug/test_coverage/PDE/EoS/index-sort-b.html +++ b/Debug/test_coverage/PDE/EoS/index-sort-b.html @@ -33,12 +33,12 @@ Date: - 2024-07-10 11:43:41 + 2024-07-11 15:06:04 Functions: - 79 + 81 202 - 39.1 % + 40.1 % Legend: @@ -136,8 +136,8 @@ 69.2 % 9 / 13 - 43.6 % - 68 / 156 + 44.9 % + 70 / 156 17.0 % 18 / 106 diff --git a/Debug/test_coverage/PDE/EoS/index-sort-f.html b/Debug/test_coverage/PDE/EoS/index-sort-f.html index c809acc17209..0a481f102c81 100644 --- a/Debug/test_coverage/PDE/EoS/index-sort-f.html +++ b/Debug/test_coverage/PDE/EoS/index-sort-f.html @@ -33,12 +33,12 @@ Date: - 2024-07-10 11:43:41 + 2024-07-11 15:06:04 Functions: - 79 + 81 202 - 39.1 % + 40.1 % Legend: @@ -124,8 +124,8 @@ 69.2 % 9 / 13 - 43.6 % - 68 / 156 + 44.9 % + 70 / 156 17.0 % 18 / 106 diff --git a/Debug/test_coverage/PDE/EoS/index-sort-l.html b/Debug/test_coverage/PDE/EoS/index-sort-l.html index 916a1bd0e143..165f39a403b6 100644 --- a/Debug/test_coverage/PDE/EoS/index-sort-l.html +++ b/Debug/test_coverage/PDE/EoS/index-sort-l.html @@ -33,12 +33,12 @@ Date: - 2024-07-10 11:43:41 + 2024-07-11 15:06:04 Functions: - 79 + 81 202 - 39.1 % + 40.1 % Legend: @@ -124,8 +124,8 @@ 69.2 % 9 / 13 - 43.6 % - 68 / 156 + 44.9 % + 70 / 156 17.0 % 18 / 106 diff --git a/Debug/test_coverage/PDE/EoS/index.html b/Debug/test_coverage/PDE/EoS/index.html index f682eefaca8d..e83596b9c29f 100644 --- a/Debug/test_coverage/PDE/EoS/index.html +++ b/Debug/test_coverage/PDE/EoS/index.html @@ -33,12 +33,12 @@ Date: - 2024-07-10 11:43:41 + 2024-07-11 15:06:04 Functions: - 79 + 81 202 - 39.1 % + 40.1 % Legend: @@ -100,8 +100,8 @@ 69.2 % 9 / 13 - 43.6 % - 68 / 156 + 44.9 % + 70 / 156 17.0 % 18 / 106 diff --git a/Debug/test_coverage/PDE/FVPDE.hpp.func-sort-c.html b/Debug/test_coverage/PDE/FVPDE.hpp.func-sort-c.html index a2bfdb08dde7..5b3b5483bbe5 100644 --- a/Debug/test_coverage/PDE/FVPDE.hpp.func-sort-c.html +++ b/Debug/test_coverage/PDE/FVPDE.hpp.func-sort-c.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:43:41 + 2024-07-11 15:06:04 Functions: 64 diff --git a/Debug/test_coverage/PDE/FVPDE.hpp.func.html b/Debug/test_coverage/PDE/FVPDE.hpp.func.html index b5e8c0d93ca4..0035a65be5f4 100644 --- a/Debug/test_coverage/PDE/FVPDE.hpp.func.html +++ b/Debug/test_coverage/PDE/FVPDE.hpp.func.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:43:41 + 2024-07-11 15:06:04 Functions: 64 diff --git a/Debug/test_coverage/PDE/FVPDE.hpp.gcov.html b/Debug/test_coverage/PDE/FVPDE.hpp.gcov.html index 31bdbea47580..19c590800a14 100644 --- a/Debug/test_coverage/PDE/FVPDE.hpp.gcov.html +++ b/Debug/test_coverage/PDE/FVPDE.hpp.gcov.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:43:41 + 2024-07-11 15:06:04 Functions: 64 diff --git a/Debug/test_coverage/PDE/Integrate/Basis.cpp.func-sort-c.html b/Debug/test_coverage/PDE/Integrate/Basis.cpp.func-sort-c.html index b376446d3519..a30a4b992c23 100644 --- a/Debug/test_coverage/PDE/Integrate/Basis.cpp.func-sort-c.html +++ b/Debug/test_coverage/PDE/Integrate/Basis.cpp.func-sort-c.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:43:41 + 2024-07-11 15:06:04 Functions: 10 diff --git a/Debug/test_coverage/PDE/Integrate/Basis.cpp.func.html b/Debug/test_coverage/PDE/Integrate/Basis.cpp.func.html index a58fda50da0e..f34b971f5f53 100644 --- a/Debug/test_coverage/PDE/Integrate/Basis.cpp.func.html +++ b/Debug/test_coverage/PDE/Integrate/Basis.cpp.func.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:43:41 + 2024-07-11 15:06:04 Functions: 10 diff --git a/Debug/test_coverage/PDE/Integrate/Basis.cpp.gcov.html b/Debug/test_coverage/PDE/Integrate/Basis.cpp.gcov.html index 09205b220ff5..2486ce8efe9a 100644 --- a/Debug/test_coverage/PDE/Integrate/Basis.cpp.gcov.html +++ b/Debug/test_coverage/PDE/Integrate/Basis.cpp.gcov.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:43:41 + 2024-07-11 15:06:04 Functions: 10 diff --git a/Debug/test_coverage/PDE/Integrate/Boundary.cpp.func-sort-c.html b/Debug/test_coverage/PDE/Integrate/Boundary.cpp.func-sort-c.html index b502c9f1786b..8af58b484579 100644 --- a/Debug/test_coverage/PDE/Integrate/Boundary.cpp.func-sort-c.html +++ b/Debug/test_coverage/PDE/Integrate/Boundary.cpp.func-sort-c.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:43:41 + 2024-07-11 15:06:04 Functions: 3 diff --git a/Debug/test_coverage/PDE/Integrate/Boundary.cpp.func.html b/Debug/test_coverage/PDE/Integrate/Boundary.cpp.func.html index 9355bb4c7e1e..5d99c5651685 100644 --- a/Debug/test_coverage/PDE/Integrate/Boundary.cpp.func.html +++ b/Debug/test_coverage/PDE/Integrate/Boundary.cpp.func.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:43:41 + 2024-07-11 15:06:04 Functions: 3 diff --git a/Debug/test_coverage/PDE/Integrate/Boundary.cpp.gcov.html b/Debug/test_coverage/PDE/Integrate/Boundary.cpp.gcov.html index d1ff987800c3..6596dcf29e90 100644 --- a/Debug/test_coverage/PDE/Integrate/Boundary.cpp.gcov.html +++ b/Debug/test_coverage/PDE/Integrate/Boundary.cpp.gcov.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:43:41 + 2024-07-11 15:06:04 Functions: 3 diff --git a/Debug/test_coverage/PDE/Integrate/Initialize.cpp.func-sort-c.html b/Debug/test_coverage/PDE/Integrate/Initialize.cpp.func-sort-c.html index b3a1e9d51b3e..970729f4fc32 100644 --- a/Debug/test_coverage/PDE/Integrate/Initialize.cpp.func-sort-c.html +++ b/Debug/test_coverage/PDE/Integrate/Initialize.cpp.func-sort-c.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:43:41 + 2024-07-11 15:06:04 Functions: 3 diff --git a/Debug/test_coverage/PDE/Integrate/Initialize.cpp.func.html b/Debug/test_coverage/PDE/Integrate/Initialize.cpp.func.html index 071368b09229..90e300c18690 100644 --- a/Debug/test_coverage/PDE/Integrate/Initialize.cpp.func.html +++ b/Debug/test_coverage/PDE/Integrate/Initialize.cpp.func.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:43:41 + 2024-07-11 15:06:04 Functions: 3 diff --git a/Debug/test_coverage/PDE/Integrate/Initialize.cpp.gcov.html b/Debug/test_coverage/PDE/Integrate/Initialize.cpp.gcov.html index e94654b40836..d14a220b5163 100644 --- a/Debug/test_coverage/PDE/Integrate/Initialize.cpp.gcov.html +++ b/Debug/test_coverage/PDE/Integrate/Initialize.cpp.gcov.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:43:41 + 2024-07-11 15:06:04 Functions: 3 diff --git a/Debug/test_coverage/PDE/Integrate/Initialize.hpp.func-sort-c.html b/Debug/test_coverage/PDE/Integrate/Initialize.hpp.func-sort-c.html index d9ce4c7a8e16..af44787833cb 100644 --- a/Debug/test_coverage/PDE/Integrate/Initialize.hpp.func-sort-c.html +++ b/Debug/test_coverage/PDE/Integrate/Initialize.hpp.func-sort-c.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:43:41 + 2024-07-11 15:06:04 Functions: 2 diff --git a/Debug/test_coverage/PDE/Integrate/Initialize.hpp.func.html b/Debug/test_coverage/PDE/Integrate/Initialize.hpp.func.html index a473608bd481..872fca31c367 100644 --- a/Debug/test_coverage/PDE/Integrate/Initialize.hpp.func.html +++ b/Debug/test_coverage/PDE/Integrate/Initialize.hpp.func.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:43:41 + 2024-07-11 15:06:04 Functions: 2 diff --git a/Debug/test_coverage/PDE/Integrate/Initialize.hpp.gcov.html b/Debug/test_coverage/PDE/Integrate/Initialize.hpp.gcov.html index 8c480faf22c3..e303c2201d78 100644 --- a/Debug/test_coverage/PDE/Integrate/Initialize.hpp.gcov.html +++ b/Debug/test_coverage/PDE/Integrate/Initialize.hpp.gcov.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:43:41 + 2024-07-11 15:06:04 Functions: 2 diff --git a/Debug/test_coverage/PDE/Integrate/Mass.cpp.func-sort-c.html b/Debug/test_coverage/PDE/Integrate/Mass.cpp.func-sort-c.html index 331ea7ccdf5b..90008ee6e62e 100644 --- a/Debug/test_coverage/PDE/Integrate/Mass.cpp.func-sort-c.html +++ b/Debug/test_coverage/PDE/Integrate/Mass.cpp.func-sort-c.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:43:41 + 2024-07-11 15:06:04 Functions: 2 diff --git a/Debug/test_coverage/PDE/Integrate/Mass.cpp.func.html b/Debug/test_coverage/PDE/Integrate/Mass.cpp.func.html index bdd864aabe62..5ccf43049362 100644 --- a/Debug/test_coverage/PDE/Integrate/Mass.cpp.func.html +++ b/Debug/test_coverage/PDE/Integrate/Mass.cpp.func.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:43:41 + 2024-07-11 15:06:04 Functions: 2 diff --git a/Debug/test_coverage/PDE/Integrate/Mass.cpp.gcov.html b/Debug/test_coverage/PDE/Integrate/Mass.cpp.gcov.html index 3111613beff0..c26111d51f0f 100644 --- a/Debug/test_coverage/PDE/Integrate/Mass.cpp.gcov.html +++ b/Debug/test_coverage/PDE/Integrate/Mass.cpp.gcov.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:43:41 + 2024-07-11 15:06:04 Functions: 2 diff --git a/Debug/test_coverage/PDE/Integrate/MultiMatTerms.cpp.func-sort-c.html b/Debug/test_coverage/PDE/Integrate/MultiMatTerms.cpp.func-sort-c.html index 3d9a05e105fd..6eae8292d554 100644 --- a/Debug/test_coverage/PDE/Integrate/MultiMatTerms.cpp.func-sort-c.html +++ b/Debug/test_coverage/PDE/Integrate/MultiMatTerms.cpp.func-sort-c.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:43:41 + 2024-07-11 15:06:04 Functions: 7 diff --git a/Debug/test_coverage/PDE/Integrate/MultiMatTerms.cpp.func.html b/Debug/test_coverage/PDE/Integrate/MultiMatTerms.cpp.func.html index c544b2178e3e..3193dc5fe3cd 100644 --- a/Debug/test_coverage/PDE/Integrate/MultiMatTerms.cpp.func.html +++ b/Debug/test_coverage/PDE/Integrate/MultiMatTerms.cpp.func.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:43:41 + 2024-07-11 15:06:04 Functions: 7 diff --git a/Debug/test_coverage/PDE/Integrate/MultiMatTerms.cpp.gcov.html b/Debug/test_coverage/PDE/Integrate/MultiMatTerms.cpp.gcov.html index 39807cf00c64..53158e7ca1e0 100644 --- a/Debug/test_coverage/PDE/Integrate/MultiMatTerms.cpp.gcov.html +++ b/Debug/test_coverage/PDE/Integrate/MultiMatTerms.cpp.gcov.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:43:41 + 2024-07-11 15:06:04 Functions: 7 diff --git a/Debug/test_coverage/PDE/Integrate/Quadrature.cpp.func-sort-c.html b/Debug/test_coverage/PDE/Integrate/Quadrature.cpp.func-sort-c.html index 0245f4ebbe9a..7ebd621580f1 100644 --- a/Debug/test_coverage/PDE/Integrate/Quadrature.cpp.func-sort-c.html +++ b/Debug/test_coverage/PDE/Integrate/Quadrature.cpp.func-sort-c.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:43:41 + 2024-07-11 15:06:04 Functions: 2 diff --git a/Debug/test_coverage/PDE/Integrate/Quadrature.cpp.func.html b/Debug/test_coverage/PDE/Integrate/Quadrature.cpp.func.html index 614c6da578e6..7eebf9d15d84 100644 --- a/Debug/test_coverage/PDE/Integrate/Quadrature.cpp.func.html +++ b/Debug/test_coverage/PDE/Integrate/Quadrature.cpp.func.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:43:41 + 2024-07-11 15:06:04 Functions: 2 diff --git a/Debug/test_coverage/PDE/Integrate/Quadrature.cpp.gcov.html b/Debug/test_coverage/PDE/Integrate/Quadrature.cpp.gcov.html index f222ac048e1f..1db716c5b014 100644 --- a/Debug/test_coverage/PDE/Integrate/Quadrature.cpp.gcov.html +++ b/Debug/test_coverage/PDE/Integrate/Quadrature.cpp.gcov.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:43:41 + 2024-07-11 15:06:04 Functions: 2 diff --git a/Debug/test_coverage/PDE/Integrate/Quadrature.hpp.func-sort-c.html b/Debug/test_coverage/PDE/Integrate/Quadrature.hpp.func-sort-c.html index c1a1a137d0e5..3775d131107b 100644 --- a/Debug/test_coverage/PDE/Integrate/Quadrature.hpp.func-sort-c.html +++ b/Debug/test_coverage/PDE/Integrate/Quadrature.hpp.func-sort-c.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:43:41 + 2024-07-11 15:06:04 Functions: 4 diff --git a/Debug/test_coverage/PDE/Integrate/Quadrature.hpp.func.html b/Debug/test_coverage/PDE/Integrate/Quadrature.hpp.func.html index c7c81ee1dc35..460c5d6dfaf2 100644 --- a/Debug/test_coverage/PDE/Integrate/Quadrature.hpp.func.html +++ b/Debug/test_coverage/PDE/Integrate/Quadrature.hpp.func.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:43:41 + 2024-07-11 15:06:04 Functions: 4 diff --git a/Debug/test_coverage/PDE/Integrate/Quadrature.hpp.gcov.html b/Debug/test_coverage/PDE/Integrate/Quadrature.hpp.gcov.html index 8e93090d816c..2d5df62222bc 100644 --- a/Debug/test_coverage/PDE/Integrate/Quadrature.hpp.gcov.html +++ b/Debug/test_coverage/PDE/Integrate/Quadrature.hpp.gcov.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:43:41 + 2024-07-11 15:06:04 Functions: 4 diff --git a/Debug/test_coverage/PDE/Integrate/SolidTerms.cpp.func-sort-c.html b/Debug/test_coverage/PDE/Integrate/SolidTerms.cpp.func-sort-c.html index f995986af47a..bb71fcb5938c 100644 --- a/Debug/test_coverage/PDE/Integrate/SolidTerms.cpp.func-sort-c.html +++ b/Debug/test_coverage/PDE/Integrate/SolidTerms.cpp.func-sort-c.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:43:41 + 2024-07-11 15:06:04 Functions: 0 diff --git a/Debug/test_coverage/PDE/Integrate/SolidTerms.cpp.func.html b/Debug/test_coverage/PDE/Integrate/SolidTerms.cpp.func.html index 04e630772d90..57831c2247b7 100644 --- a/Debug/test_coverage/PDE/Integrate/SolidTerms.cpp.func.html +++ b/Debug/test_coverage/PDE/Integrate/SolidTerms.cpp.func.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:43:41 + 2024-07-11 15:06:04 Functions: 0 diff --git a/Debug/test_coverage/PDE/Integrate/SolidTerms.cpp.gcov.html b/Debug/test_coverage/PDE/Integrate/SolidTerms.cpp.gcov.html index a02322ab76d8..111cf52626b6 100644 --- a/Debug/test_coverage/PDE/Integrate/SolidTerms.cpp.gcov.html +++ b/Debug/test_coverage/PDE/Integrate/SolidTerms.cpp.gcov.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:43:41 + 2024-07-11 15:06:04 Functions: 0 diff --git a/Debug/test_coverage/PDE/Integrate/Source.cpp.func-sort-c.html b/Debug/test_coverage/PDE/Integrate/Source.cpp.func-sort-c.html index 74686366f485..3c335935566b 100644 --- a/Debug/test_coverage/PDE/Integrate/Source.cpp.func-sort-c.html +++ b/Debug/test_coverage/PDE/Integrate/Source.cpp.func-sort-c.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:43:41 + 2024-07-11 15:06:04 Functions: 3 diff --git a/Debug/test_coverage/PDE/Integrate/Source.cpp.func.html b/Debug/test_coverage/PDE/Integrate/Source.cpp.func.html index 8d9c3fe6b630..9087f5968e87 100644 --- a/Debug/test_coverage/PDE/Integrate/Source.cpp.func.html +++ b/Debug/test_coverage/PDE/Integrate/Source.cpp.func.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:43:41 + 2024-07-11 15:06:04 Functions: 3 diff --git a/Debug/test_coverage/PDE/Integrate/Source.cpp.gcov.html b/Debug/test_coverage/PDE/Integrate/Source.cpp.gcov.html index 65da414f122e..8f22b71e892e 100644 --- a/Debug/test_coverage/PDE/Integrate/Source.cpp.gcov.html +++ b/Debug/test_coverage/PDE/Integrate/Source.cpp.gcov.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:43:41 + 2024-07-11 15:06:04 Functions: 3 diff --git a/Debug/test_coverage/PDE/Integrate/Surface.cpp.func-sort-c.html b/Debug/test_coverage/PDE/Integrate/Surface.cpp.func-sort-c.html index d4a65f100240..999ddae756e4 100644 --- a/Debug/test_coverage/PDE/Integrate/Surface.cpp.func-sort-c.html +++ b/Debug/test_coverage/PDE/Integrate/Surface.cpp.func-sort-c.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:43:41 + 2024-07-11 15:06:04 Functions: 3 diff --git a/Debug/test_coverage/PDE/Integrate/Surface.cpp.func.html b/Debug/test_coverage/PDE/Integrate/Surface.cpp.func.html index ee8a6996ce3d..ba084032aa07 100644 --- a/Debug/test_coverage/PDE/Integrate/Surface.cpp.func.html +++ b/Debug/test_coverage/PDE/Integrate/Surface.cpp.func.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:43:41 + 2024-07-11 15:06:04 Functions: 3 diff --git a/Debug/test_coverage/PDE/Integrate/Surface.cpp.gcov.html b/Debug/test_coverage/PDE/Integrate/Surface.cpp.gcov.html index 3c4a81cf835e..c104586082dc 100644 --- a/Debug/test_coverage/PDE/Integrate/Surface.cpp.gcov.html +++ b/Debug/test_coverage/PDE/Integrate/Surface.cpp.gcov.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:43:41 + 2024-07-11 15:06:04 Functions: 3 @@ -357,38 +357,38 @@ 278 : 193132950 : R(el, mark) -= wt * fl[c]; 279 : 193132950 : R(er, mark) += wt * fl[c]; 280 : : - 281 [ + + ]: 193132950 : if(ndof_l > 1) //DG(P1) + 281 [ + + ]: 193132950 : if(ndof_l > 1) //DG(P1) 282 : : { - 283 : 116702595 : R(el, mark+1) -= wt * fl[c] * B_l[1]; - 284 : 116702595 : R(el, mark+2) -= wt * fl[c] * B_l[2]; - 285 : 116702595 : R(el, mark+3) -= wt * fl[c] * B_l[3]; + 283 : 116701515 : R(el, mark+1) -= wt * fl[c] * B_l[1]; + 284 : 116701515 : R(el, mark+2) -= wt * fl[c] * B_l[2]; + 285 : 116701515 : R(el, mark+3) -= wt * fl[c] * B_l[3]; 286 : : } 287 : : - 288 [ + + ]: 193132950 : if(ndof_r > 1) //DG(P1) + 288 [ + + ]: 193132950 : if(ndof_r > 1) //DG(P1) 289 : : { - 290 : 116685720 : R(er, mark+1) += wt * fl[c] * B_r[1]; - 291 : 116685720 : R(er, mark+2) += wt * fl[c] * B_r[2]; - 292 : 116685720 : R(er, mark+3) += wt * fl[c] * B_r[3]; + 290 : 116686800 : R(er, mark+1) += wt * fl[c] * B_r[1]; + 291 : 116686800 : R(er, mark+2) += wt * fl[c] * B_r[2]; + 292 : 116686800 : R(er, mark+3) += wt * fl[c] * B_r[3]; 293 : : } 294 : : - 295 [ + + ]: 193132950 : if(ndof_l > 4) //DG(P2) + 295 [ + + ]: 193132950 : if(ndof_l > 4) //DG(P2) 296 : : { - 297 : 47892780 : R(el, mark+4) -= wt * fl[c] * B_l[4]; - 298 : 47892780 : R(el, mark+5) -= wt * fl[c] * B_l[5]; - 299 : 47892780 : R(el, mark+6) -= wt * fl[c] * B_l[6]; - 300 : 47892780 : R(el, mark+7) -= wt * fl[c] * B_l[7]; - 301 : 47892780 : R(el, mark+8) -= wt * fl[c] * B_l[8]; - 302 : 47892780 : R(el, mark+9) -= wt * fl[c] * B_l[9]; + 297 : 47895210 : R(el, mark+4) -= wt * fl[c] * B_l[4]; + 298 : 47895210 : R(el, mark+5) -= wt * fl[c] * B_l[5]; + 299 : 47895210 : R(el, mark+6) -= wt * fl[c] * B_l[6]; + 300 : 47895210 : R(el, mark+7) -= wt * fl[c] * B_l[7]; + 301 : 47895210 : R(el, mark+8) -= wt * fl[c] * B_l[8]; + 302 : 47895210 : R(el, mark+9) -= wt * fl[c] * B_l[9]; 303 : : } 304 : : - 305 [ + + ]: 193132950 : if(ndof_r > 4) //DG(P2) + 305 [ + + ]: 193132950 : if(ndof_r > 4) //DG(P2) 306 : : { - 307 : 47864250 : R(er, mark+4) += wt * fl[c] * B_r[4]; - 308 : 47864250 : R(er, mark+5) += wt * fl[c] * B_r[5]; - 309 : 47864250 : R(er, mark+6) += wt * fl[c] * B_r[6]; - 310 : 47864250 : R(er, mark+7) += wt * fl[c] * B_r[7]; - 311 : 47864250 : R(er, mark+8) += wt * fl[c] * B_r[8]; - 312 : 47864250 : R(er, mark+9) += wt * fl[c] * B_r[9]; + 307 : 47861820 : R(er, mark+4) += wt * fl[c] * B_r[4]; + 308 : 47861820 : R(er, mark+5) += wt * fl[c] * B_r[5]; + 309 : 47861820 : R(er, mark+6) += wt * fl[c] * B_r[6]; + 310 : 47861820 : R(er, mark+7) += wt * fl[c] * B_r[7]; + 311 : 47861820 : R(er, mark+8) += wt * fl[c] * B_r[8]; + 312 : 47861820 : R(er, mark+9) += wt * fl[c] * B_r[9]; 313 : : } 314 : : } 315 : : diff --git a/Debug/test_coverage/PDE/Integrate/Volume.cpp.func-sort-c.html b/Debug/test_coverage/PDE/Integrate/Volume.cpp.func-sort-c.html index 65ce51b9fed0..3035967c9b9d 100644 --- a/Debug/test_coverage/PDE/Integrate/Volume.cpp.func-sort-c.html +++ b/Debug/test_coverage/PDE/Integrate/Volume.cpp.func-sort-c.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:43:41 + 2024-07-11 15:06:04 Functions: 2 diff --git a/Debug/test_coverage/PDE/Integrate/Volume.cpp.func.html b/Debug/test_coverage/PDE/Integrate/Volume.cpp.func.html index e1d971190698..602063290ce1 100644 --- a/Debug/test_coverage/PDE/Integrate/Volume.cpp.func.html +++ b/Debug/test_coverage/PDE/Integrate/Volume.cpp.func.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:43:41 + 2024-07-11 15:06:04 Functions: 2 diff --git a/Debug/test_coverage/PDE/Integrate/Volume.cpp.gcov.html b/Debug/test_coverage/PDE/Integrate/Volume.cpp.gcov.html index 9b8fff5824a9..098c78007804 100644 --- a/Debug/test_coverage/PDE/Integrate/Volume.cpp.gcov.html +++ b/Debug/test_coverage/PDE/Integrate/Volume.cpp.gcov.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:43:41 + 2024-07-11 15:06:04 Functions: 2 diff --git a/Debug/test_coverage/PDE/Integrate/index-sort-b.html b/Debug/test_coverage/PDE/Integrate/index-sort-b.html index 47935e29e586..c57527e39576 100644 --- a/Debug/test_coverage/PDE/Integrate/index-sort-b.html +++ b/Debug/test_coverage/PDE/Integrate/index-sort-b.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:43:41 + 2024-07-11 15:06:04 Functions: 41 diff --git a/Debug/test_coverage/PDE/Integrate/index-sort-f.html b/Debug/test_coverage/PDE/Integrate/index-sort-f.html index 3ecc93d185a1..387d1c256aab 100644 --- a/Debug/test_coverage/PDE/Integrate/index-sort-f.html +++ b/Debug/test_coverage/PDE/Integrate/index-sort-f.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:43:41 + 2024-07-11 15:06:04 Functions: 41 @@ -141,18 +141,6 @@ 40.5 % 133 / 328 - - Quadrature.cpp - -
94.1%94.1%
- - 94.1 % - 222 / 236 - 100.0 % - 2 / 2 - 22.4 % - 15 / 67 - Volume.cpp @@ -165,6 +153,18 @@ 41.9 % 31 / 74 + + Quadrature.cpp + +
94.1%94.1%
+ + 94.1 % + 222 / 236 + 100.0 % + 2 / 2 + 22.4 % + 15 / 67 + Surface.cpp @@ -178,16 +178,16 @@ 78 / 162 - Initialize.cpp + Boundary.cpp -
100.0%
+
96.4%96.4%
- 100.0 % - 68 / 68 + 96.4 % + 107 / 111 100.0 % 3 / 3 - 55.0 % - 33 / 60 + 53.6 % + 74 / 138 Source.cpp @@ -202,16 +202,16 @@ 34 / 60 - Boundary.cpp + Initialize.cpp -
96.4%96.4%
+
100.0%
- 96.4 % - 107 / 111 + 100.0 % + 68 / 68 100.0 % 3 / 3 - 53.6 % - 74 / 138 + 55.0 % + 33 / 60 Quadrature.hpp diff --git a/Debug/test_coverage/PDE/Integrate/index-sort-l.html b/Debug/test_coverage/PDE/Integrate/index-sort-l.html index f4aa2c8d6c0a..d2cbede2607f 100644 --- a/Debug/test_coverage/PDE/Integrate/index-sort-l.html +++ b/Debug/test_coverage/PDE/Integrate/index-sort-l.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:43:41 + 2024-07-11 15:06:04 Functions: 41 diff --git a/Debug/test_coverage/PDE/Integrate/index.html b/Debug/test_coverage/PDE/Integrate/index.html index 4cfab48759df..511b2bd20877 100644 --- a/Debug/test_coverage/PDE/Integrate/index.html +++ b/Debug/test_coverage/PDE/Integrate/index.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:43:41 + 2024-07-11 15:06:04 Functions: 41 diff --git a/Debug/test_coverage/PDE/Limiter.cpp.func-sort-c.html b/Debug/test_coverage/PDE/Limiter.cpp.func-sort-c.html index 9247890db8de..044d5475de58 100644 --- a/Debug/test_coverage/PDE/Limiter.cpp.func-sort-c.html +++ b/Debug/test_coverage/PDE/Limiter.cpp.func-sort-c.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:43:41 + 2024-07-11 15:06:04 Functions: 18 diff --git a/Debug/test_coverage/PDE/Limiter.cpp.func.html b/Debug/test_coverage/PDE/Limiter.cpp.func.html index 4481b0fe0186..abbd9061c188 100644 --- a/Debug/test_coverage/PDE/Limiter.cpp.func.html +++ b/Debug/test_coverage/PDE/Limiter.cpp.func.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:43:41 + 2024-07-11 15:06:04 Functions: 18 diff --git a/Debug/test_coverage/PDE/Limiter.cpp.gcov.html b/Debug/test_coverage/PDE/Limiter.cpp.gcov.html index 112bde3ccadc..f3503c565a8a 100644 --- a/Debug/test_coverage/PDE/Limiter.cpp.gcov.html +++ b/Debug/test_coverage/PDE/Limiter.cpp.gcov.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:43:41 + 2024-07-11 15:06:04 Functions: 18 @@ -1263,19 +1263,19 @@ 1183 : 72811680 : auto phi_gp = 1.0; 1184 : 72811680 : auto mark = c*rdof; 1185 [ + - ]: 72811680 : auto uNeg = state[c] - U(e, mark); - 1186 [ + + ]: 72811680 : if (uNeg > 1.0e-14) + 1186 [ + + ]: 72811680 : if (uNeg > 1.0e-14) 1187 : : { - 1188 : 7325863 : uNeg = std::max(uNeg, 1.0e-08); - 1189 [ + - ]: 7325863 : phi_gp = std::min( 1.0, (uMax[c]-U(e, mark))/(2.0*uNeg) ); + 1188 : 7325854 : uNeg = std::max(uNeg, 1.0e-08); + 1189 [ + - ]: 7325854 : phi_gp = std::min( 1.0, (uMax[c]-U(e, mark))/(2.0*uNeg) ); 1190 : : } - 1191 [ + + ]: 65485817 : else if (uNeg < -1.0e-14) + 1191 [ + + ]: 65485826 : else if (uNeg < -1.0e-14) 1192 : : { - 1193 : 7800847 : uNeg = std::min(uNeg, -1.0e-08); - 1194 [ + - ]: 7800847 : phi_gp = std::min( 1.0, (uMin[c]-U(e, mark))/(2.0*uNeg) ); + 1193 : 7800806 : uNeg = std::min(uNeg, -1.0e-08); + 1194 [ + - ]: 7800806 : phi_gp = std::min( 1.0, (uMin[c]-U(e, mark))/(2.0*uNeg) ); 1195 : : } 1196 : : else 1197 : : { - 1198 : 57684970 : phi_gp = 1.0; + 1198 : 57685020 : phi_gp = 1.0; 1199 : : } 1200 : 145623360 : phi_gp = std::max( 0.0, 1201 : 145623360 : std::max( std::min(beta_lim*phi_gp, 1.0), @@ -1386,17 +1386,17 @@ 1305 : 47235680 : auto mark = c*rdof; 1306 [ + - ]: 47235680 : auto uNeg = state[c] - U(e, mark); 1307 [ + - ]: 47235680 : auto uref = std::max(std::fabs(U(e,mark)), 1e-14); - 1308 [ + + ]: 47235680 : if (uNeg > 1.0e-06*uref) + 1308 [ + + ]: 47235680 : if (uNeg > 1.0e-06*uref) 1309 : : { - 1310 [ + - ]: 8657049 : phi_gp = std::min( 1.0, (uMax[i]-U(e, mark))/uNeg ); + 1310 [ + - ]: 8654685 : phi_gp = std::min( 1.0, (uMax[i]-U(e, mark))/uNeg ); 1311 : : } - 1312 [ + + ]: 38578631 : else if (uNeg < -1.0e-06*uref) + 1312 [ + + ]: 38580995 : else if (uNeg < -1.0e-06*uref) 1313 : : { - 1314 [ + - ]: 8807882 : phi_gp = std::min( 1.0, (uMin[i]-U(e, mark))/uNeg ); + 1314 [ + - ]: 8802651 : phi_gp = std::min( 1.0, (uMin[i]-U(e, mark))/uNeg ); 1315 : : } 1316 : : else 1317 : : { - 1318 : 29770749 : phi_gp = 1.0; + 1318 : 29778344 : phi_gp = 1.0; 1319 : : } 1320 : : 1321 : : // ----- Step-3: take the minimum of the nodal-limiter functions diff --git a/Debug/test_coverage/PDE/MultiMat/BCFunctions.hpp.func-sort-c.html b/Debug/test_coverage/PDE/MultiMat/BCFunctions.hpp.func-sort-c.html index d3d581841564..3f0807f29482 100644 --- a/Debug/test_coverage/PDE/MultiMat/BCFunctions.hpp.func-sort-c.html +++ b/Debug/test_coverage/PDE/MultiMat/BCFunctions.hpp.func-sort-c.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:43:41 + 2024-07-11 15:06:04 Functions: 2 diff --git a/Debug/test_coverage/PDE/MultiMat/BCFunctions.hpp.func.html b/Debug/test_coverage/PDE/MultiMat/BCFunctions.hpp.func.html index e913ff149431..f992c93858ff 100644 --- a/Debug/test_coverage/PDE/MultiMat/BCFunctions.hpp.func.html +++ b/Debug/test_coverage/PDE/MultiMat/BCFunctions.hpp.func.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:43:41 + 2024-07-11 15:06:04 Functions: 2 diff --git a/Debug/test_coverage/PDE/MultiMat/BCFunctions.hpp.gcov.html b/Debug/test_coverage/PDE/MultiMat/BCFunctions.hpp.gcov.html index 6b943ecac64e..a1db1ff806e3 100644 --- a/Debug/test_coverage/PDE/MultiMat/BCFunctions.hpp.gcov.html +++ b/Debug/test_coverage/PDE/MultiMat/BCFunctions.hpp.gcov.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:43:41 + 2024-07-11 15:06:04 Functions: 2 diff --git a/Debug/test_coverage/PDE/MultiMat/DGMultiMat.hpp.func-sort-c.html b/Debug/test_coverage/PDE/MultiMat/DGMultiMat.hpp.func-sort-c.html index 6a7117cb8c24..bcf169653371 100644 --- a/Debug/test_coverage/PDE/MultiMat/DGMultiMat.hpp.func-sort-c.html +++ b/Debug/test_coverage/PDE/MultiMat/DGMultiMat.hpp.func-sort-c.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:43:41 + 2024-07-11 15:06:04 Functions: 71 diff --git a/Debug/test_coverage/PDE/MultiMat/DGMultiMat.hpp.func.html b/Debug/test_coverage/PDE/MultiMat/DGMultiMat.hpp.func.html index a89d46c2b667..6fe2b6fd05d9 100644 --- a/Debug/test_coverage/PDE/MultiMat/DGMultiMat.hpp.func.html +++ b/Debug/test_coverage/PDE/MultiMat/DGMultiMat.hpp.func.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:43:41 + 2024-07-11 15:06:04 Functions: 71 diff --git a/Debug/test_coverage/PDE/MultiMat/DGMultiMat.hpp.gcov.html b/Debug/test_coverage/PDE/MultiMat/DGMultiMat.hpp.gcov.html index c252baac0fc4..f94e73f820a3 100644 --- a/Debug/test_coverage/PDE/MultiMat/DGMultiMat.hpp.gcov.html +++ b/Debug/test_coverage/PDE/MultiMat/DGMultiMat.hpp.gcov.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:43:41 + 2024-07-11 15:06:04 Functions: 71 @@ -627,8 +627,8 @@ 543 [ + + ]: 32811692 : for(std::size_t idof = 0; idof < ndof; idof++) 544 : : { 545 [ + - ][ + - ]: 20214796 : prim(e, rmark+idof) = R[mark+idof] / L(e, mark+idof); - 546 [ + - ][ + + ]: 20214796 : if(fabs(prim(e, rmark+idof)) < 1e-16) - 547 [ + - ]: 5193418 : prim(e, rmark+idof) = 0; + 546 [ + - ][ + + ]: 20214796 : if(fabs(prim(e, rmark+idof)) < 1e-16) + 547 [ + - ]: 5193776 : prim(e, rmark+idof) = 0; 548 : : } 549 : : } 550 : : } diff --git a/Debug/test_coverage/PDE/MultiMat/FVMultiMat.hpp.func-sort-c.html b/Debug/test_coverage/PDE/MultiMat/FVMultiMat.hpp.func-sort-c.html index e8fbca7f44cf..0e41ab1f7b70 100644 --- a/Debug/test_coverage/PDE/MultiMat/FVMultiMat.hpp.func-sort-c.html +++ b/Debug/test_coverage/PDE/MultiMat/FVMultiMat.hpp.func-sort-c.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:43:41 + 2024-07-11 15:06:04 Functions: 46 diff --git a/Debug/test_coverage/PDE/MultiMat/FVMultiMat.hpp.func.html b/Debug/test_coverage/PDE/MultiMat/FVMultiMat.hpp.func.html index c6805926dbbb..38fedcc6cd57 100644 --- a/Debug/test_coverage/PDE/MultiMat/FVMultiMat.hpp.func.html +++ b/Debug/test_coverage/PDE/MultiMat/FVMultiMat.hpp.func.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:43:41 + 2024-07-11 15:06:04 Functions: 46 diff --git a/Debug/test_coverage/PDE/MultiMat/FVMultiMat.hpp.gcov.html b/Debug/test_coverage/PDE/MultiMat/FVMultiMat.hpp.gcov.html index 3691eb101065..fde80751475a 100644 --- a/Debug/test_coverage/PDE/MultiMat/FVMultiMat.hpp.gcov.html +++ b/Debug/test_coverage/PDE/MultiMat/FVMultiMat.hpp.gcov.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:43:41 + 2024-07-11 15:06:04 Functions: 46 diff --git a/Debug/test_coverage/PDE/MultiMat/MiscMultiMatFns.cpp.func-sort-c.html b/Debug/test_coverage/PDE/MultiMat/MiscMultiMatFns.cpp.func-sort-c.html index e15d55cb8a17..ec53391daee2 100644 --- a/Debug/test_coverage/PDE/MultiMat/MiscMultiMatFns.cpp.func-sort-c.html +++ b/Debug/test_coverage/PDE/MultiMat/MiscMultiMatFns.cpp.func-sort-c.html @@ -27,18 +27,18 @@ -128-NOTFOUND Lines: - 224 + 229 266 - 84.2 % + 86.1 % Date: - 2024-07-10 11:43:41 + 2024-07-11 15:06:04 Functions: - 8 + 9 10 - 80.0 % + 90.0 % Legend: @@ -52,9 +52,9 @@ Branches: - 167 + 168 302 - 55.3 % + 55.6 % @@ -71,10 +71,6 @@ Function Name Sort by function name Hit count Sort by hit count - - inciter::getCauchyStress(unsigned long, unsigned long, unsigned long, std::vector<double, std::allocator<double> > const&) - 0 - inciter::cleanTraceMultiMat(double, unsigned long, std::vector<inciter::EOS, std::allocator<inciter::EOS> > const&, tk::Data<(unsigned char)0> const&, unsigned long, tk::Data<(unsigned char)0>&, tk::Data<(unsigned char)0>&)::{lambda()#1}::operator()() const 0 @@ -99,9 +95,13 @@ inciter::cleanTraceMultiMat(double, unsigned long, std::vector<inciter::EOS, std::allocator<inciter::EOS> > const&, tk::Data<(unsigned char)0> const&, unsigned long, tk::Data<(unsigned char)0>&, tk::Data<(unsigned char)0>&) 6898 + + inciter::getCauchyStress(unsigned long, unsigned long, unsigned long, std::vector<double, std::allocator<double> > const&) + 686000 + inciter::numSolids(unsigned long, std::vector<unsigned long, std::allocator<unsigned long> > const&) - 1891116 + 2062616 inciter::haveSolid(unsigned long, std::vector<unsigned long, std::allocator<unsigned long> > const&) @@ -109,7 +109,7 @@ inciter::getDeformGrad(unsigned long, unsigned long, std::vector<double, std::allocator<double> > const&) - 17848474 + 18534474
diff --git a/Debug/test_coverage/PDE/MultiMat/MiscMultiMatFns.cpp.func.html b/Debug/test_coverage/PDE/MultiMat/MiscMultiMatFns.cpp.func.html index 0b634d27dd0d..17db1893b378 100644 --- a/Debug/test_coverage/PDE/MultiMat/MiscMultiMatFns.cpp.func.html +++ b/Debug/test_coverage/PDE/MultiMat/MiscMultiMatFns.cpp.func.html @@ -27,18 +27,18 @@ -128-NOTFOUND Lines: - 224 + 229 266 - 84.2 % + 86.1 % Date: - 2024-07-10 11:43:41 + 2024-07-11 15:06:04 Functions: - 8 + 9 10 - 80.0 % + 90.0 % Legend: @@ -52,9 +52,9 @@ Branches: - 167 + 168 302 - 55.3 % + 55.6 % @@ -73,11 +73,11 @@ inciter::getDeformGrad(unsigned long, unsigned long, std::vector<double, std::allocator<double> > const&) - 17848474 + 18534474 inciter::getCauchyStress(unsigned long, unsigned long, unsigned long, std::vector<double, std::allocator<double> > const&) - 0 + 686000 inciter::resetSolidTensors(unsigned long, unsigned long, unsigned long, tk::Data<(unsigned char)0>&, tk::Data<(unsigned char)0>&) @@ -105,7 +105,7 @@ inciter::numSolids(unsigned long, std::vector<unsigned long, std::allocator<unsigned long> > const&) - 1891116 + 2062616 inciter::cleanTraceMultiMat(double, unsigned long, std::vector<inciter::EOS, std::allocator<inciter::EOS> > const&, tk::Data<(unsigned char)0> const&, unsigned long, tk::Data<(unsigned char)0>&, tk::Data<(unsigned char)0>&)::{lambda()#1}::operator()() const diff --git a/Debug/test_coverage/PDE/MultiMat/MiscMultiMatFns.cpp.gcov.html b/Debug/test_coverage/PDE/MultiMat/MiscMultiMatFns.cpp.gcov.html index 5a6336d96bb3..a931adbb08e1 100644 --- a/Debug/test_coverage/PDE/MultiMat/MiscMultiMatFns.cpp.gcov.html +++ b/Debug/test_coverage/PDE/MultiMat/MiscMultiMatFns.cpp.gcov.html @@ -27,18 +27,18 @@ -128-NOTFOUND Lines: - 224 + 229 266 - 84.2 % + 86.1 % Date: - 2024-07-10 11:43:41 + 2024-07-11 15:06:04 Functions: - 8 + 9 10 - 80.0 % + 90.0 % Legend: @@ -52,9 +52,9 @@ Branches: - 167 + 168 302 - 55.3 % + 55.6 % @@ -480,12 +480,12 @@ 404 : 470350 : a = 0.0; 405 [ + + ]: 1411050 : for (std::size_t k=0; k<nmat; ++k) 406 : : { - 407 [ + + ]: 940700 : if (ugp[volfracIdx(nmat, k)] > 1.0e-04) { - 408 [ + - ]: 487421 : auto gk = getDeformGrad(nmat, k, ugp); - 409 [ + - ]: 487421 : gk = tk::rotateTensor(gk, fn); - 410 [ + - ]: 1462263 : a = std::max( a, mat_blk[k].compute< EOS::soundspeed >( - 411 : 487421 : ugp[densityIdx(nmat, k)], - 412 : 974842 : pgp[pressureIdx(nmat, k)], ugp[volfracIdx(nmat, k)], k, gk ) ); + 407 [ + + ]: 940700 : if (ugp[volfracIdx(nmat, k)] > 1.0e-04) { + 408 [ + - ]: 487354 : auto gk = getDeformGrad(nmat, k, ugp); + 409 [ + - ]: 487354 : gk = tk::rotateTensor(gk, fn); + 410 [ + - ]: 1462062 : a = std::max( a, mat_blk[k].compute< EOS::soundspeed >( + 411 : 487354 : ugp[densityIdx(nmat, k)], + 412 : 974708 : pgp[pressureIdx(nmat, k)], ugp[volfracIdx(nmat, k)], k, gk ) ); 413 : : } 414 : : } 415 : : @@ -516,12 +516,12 @@ 439 : 362890 : a = 0.0; 440 [ + + ]: 1088670 : for (std::size_t k=0; k<nmat; ++k) 441 : : { - 442 [ + + ]: 725780 : if (ugp[volfracIdx(nmat, k)] > 1.0e-04) { - 443 [ + - ]: 376454 : auto gk = getDeformGrad(nmat, k, ugp); - 444 [ + - ]: 376454 : gk = tk::rotateTensor(gk, fn); - 445 [ + - ]: 1129362 : a = std::max( a, mat_blk[k].compute< EOS::soundspeed >( - 446 : 376454 : ugp[densityIdx(nmat, k)], - 447 : 752908 : pgp[pressureIdx(nmat, k)], ugp[volfracIdx(nmat, k)], k, gk ) ); + 442 [ + + ]: 725780 : if (ugp[volfracIdx(nmat, k)] > 1.0e-04) { + 443 [ + - ]: 376521 : auto gk = getDeformGrad(nmat, k, ugp); + 444 [ + - ]: 376521 : gk = tk::rotateTensor(gk, fn); + 445 [ + - ]: 1129563 : a = std::max( a, mat_blk[k].compute< EOS::soundspeed >( + 446 : 376521 : ugp[densityIdx(nmat, k)], + 447 : 753042 : pgp[pressureIdx(nmat, k)], ugp[volfracIdx(nmat, k)], k, gk ) ); 448 : : } 449 : : } 450 : : @@ -677,7 +677,7 @@ 600 : 10 : } 601 : : 602 : : std::array< std::array< tk::real, 3 >, 3 > - 603 : 17848474 : getDeformGrad( + 603 : 18534474 : getDeformGrad( 604 : : std::size_t nmat, 605 : : std::size_t k, 606 : : const std::vector< tk::real >& state ) @@ -689,10 +689,10 @@ 612 : : //! \return Inverse deformation gradient tensor (g_k) of material k 613 : : // ***************************************************************************** 614 : : { - 615 : 17848474 : const auto& solidx = g_inputdeck.get< tag::matidxmap, tag::solidx >(); + 615 : 18534474 : const auto& solidx = g_inputdeck.get< tag::matidxmap, tag::solidx >(); 616 : : std::array< std::array< tk::real, 3 >, 3 > gk; 617 : : - 618 [ - + ]: 17848474 : if (solidx[k] > 0) { + 618 [ - + ]: 18534474 : if (solidx[k] > 0) { 619 : : // deformation gradient for solids 620 [ - - ]: 0 : for (std::size_t i=0; i<3; ++i) { 621 [ - - ]: 0 : for (std::size_t j=0; j<3; ++j) @@ -701,14 +701,14 @@ 624 : : } 625 : : else { 626 : : // empty vector for fluids - 627 : 17848474 : gk = {{}}; + 627 : 18534474 : gk = {{}}; 628 : : } 629 : : - 630 : 17848474 : return gk; + 630 : 18534474 : return gk; 631 : : } 632 : : 633 : : std::array< std::array< tk::real, 3 >, 3 > - 634 : 0 : getCauchyStress( + 634 : 686000 : getCauchyStress( 635 : : std::size_t nmat, 636 : : std::size_t k, 637 : : std::size_t ncomp, @@ -722,12 +722,12 @@ 645 : : //! \return Elastic Cauchy stress tensor (alpha * \sigma_ij) of material k 646 : : // ***************************************************************************** 647 : : { - 648 : 0 : const auto& solidx = g_inputdeck.get< tag::matidxmap, tag::solidx >(); + 648 : 686000 : const auto& solidx = g_inputdeck.get< tag::matidxmap, tag::solidx >(); 649 : : std::array< std::array< tk::real, 3 >, 3 > - 650 : 0 : asigk{{ {{0,0,0}}, {{0,0,0}}, {{0,0,0}} }}; + 650 : 686000 : asigk{{ {{0,0,0}}, {{0,0,0}}, {{0,0,0}} }}; 651 : : 652 : : // elastic Cauchy stress for solids - 653 [ - - ]: 0 : if (solidx[k] > 0) { + 653 [ - + ]: 686000 : if (solidx[k] > 0) { 654 [ - - ]: 0 : for (std::size_t i=0; i<3; ++i) { 655 [ - - ]: 0 : for (std::size_t j=0; j<3; ++j) 656 : 0 : asigk[i][j] = state[ncomp + @@ -735,7 +735,7 @@ 658 : : } 659 : : } 660 : : - 661 : 0 : return asigk; + 661 : 686000 : return asigk; 662 : : } 663 : : 664 : : bool @@ -756,7 +756,7 @@ 679 : 7379280 : return haveSolid; 680 : : } 681 : : - 682 : 1891116 : std::size_t numSolids( + 682 : 2062616 : std::size_t numSolids( 683 : : std::size_t nmat, 684 : : const std::vector< std::size_t >& solidx ) 685 : : // ***************************************************************************** @@ -767,11 +767,11 @@ 690 : : // ***************************************************************************** 691 : : { 692 : : // count number of solid materials - 693 : 1891116 : std::size_t nsld(0); - 694 [ + + ]: 6345528 : for (std::size_t k=0; k<nmat; ++k) - 695 [ - + ]: 4454412 : if (solidx[k] > 0) ++nsld; + 693 : 2062616 : std::size_t nsld(0); + 694 [ + + ]: 6860028 : for (std::size_t k=0; k<nmat; ++k) + 695 [ - + ]: 4797412 : if (solidx[k] > 0) ++nsld; 696 : : - 697 : 1891116 : return nsld; + 697 : 2062616 : return nsld; 698 : : } 699 : : 700 : : } //inciter:: diff --git a/Debug/test_coverage/PDE/MultiMat/MultiMatIndexing.hpp.func-sort-c.html b/Debug/test_coverage/PDE/MultiMat/MultiMatIndexing.hpp.func-sort-c.html index b1933394e16d..bdefb238f9f4 100644 --- a/Debug/test_coverage/PDE/MultiMat/MultiMatIndexing.hpp.func-sort-c.html +++ b/Debug/test_coverage/PDE/MultiMat/MultiMatIndexing.hpp.func-sort-c.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:43:41 + 2024-07-11 15:06:04 Functions: 13 @@ -117,7 +117,7 @@ inciter::velocityIdx(unsigned long, unsigned long) - 137932973 + 139990973 inciter::volfracDofIdx(unsigned long, unsigned long, unsigned long, unsigned long) @@ -133,7 +133,7 @@ inciter::energyIdx(unsigned long, unsigned long) - 377720983 + 379778983 inciter::volfracIdx(unsigned long, unsigned long) diff --git a/Debug/test_coverage/PDE/MultiMat/MultiMatIndexing.hpp.func.html b/Debug/test_coverage/PDE/MultiMat/MultiMatIndexing.hpp.func.html index ee7e9fe3ba25..5dfd4ffb17a8 100644 --- a/Debug/test_coverage/PDE/MultiMat/MultiMatIndexing.hpp.func.html +++ b/Debug/test_coverage/PDE/MultiMat/MultiMatIndexing.hpp.func.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:43:41 + 2024-07-11 15:06:04 Functions: 13 @@ -89,7 +89,7 @@ inciter::velocityIdx(unsigned long, unsigned long) - 137932973 + 139990973 inciter::deformDofIdx(unsigned long, unsigned long, unsigned long, unsigned long, unsigned long, unsigned long) @@ -133,7 +133,7 @@ inciter::energyIdx(unsigned long, unsigned long) - 377720983 + 379778983 inciter::matExists(double) diff --git a/Debug/test_coverage/PDE/MultiMat/MultiMatIndexing.hpp.gcov.html b/Debug/test_coverage/PDE/MultiMat/MultiMatIndexing.hpp.gcov.html index d4f521991d75..a55bde7602dd 100644 --- a/Debug/test_coverage/PDE/MultiMat/MultiMatIndexing.hpp.gcov.html +++ b/Debug/test_coverage/PDE/MultiMat/MultiMatIndexing.hpp.gcov.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:43:41 + 2024-07-11 15:06:04 Functions: 13 @@ -121,8 +121,8 @@ 47 : : //! \param[in] nmat Number of materials 48 : : //! \param[in] kmat Index of required material 49 : : //! \return Index of the required material total energy equation - 50 : 377720983 : inline std::size_t energyIdx( std::size_t nmat, std::size_t kmat ) - 51 : 377720983 : { return (2*nmat+3+kmat); } + 50 : 379778983 : inline std::size_t energyIdx( std::size_t nmat, std::size_t kmat ) + 51 : 379778983 : { return (2*nmat+3+kmat); } 52 : : 53 : : //! Get the index of the required material deformation gradient equation 54 : : //! \param[in] nmat Number of materials @@ -141,8 +141,8 @@ 67 : : //! 1: Y-component, 68 : : //! 2: Z-component. 69 : : //! \return Index of the required velocity component from vector of primitives - 70 : 137932973 : inline std::size_t velocityIdx( std::size_t nmat, std::size_t idir ) - 71 : 137932973 : { return nmat+idir; } + 70 : 139990973 : inline std::size_t velocityIdx( std::size_t nmat, std::size_t idir ) + 71 : 139990973 : { return nmat+idir; } 72 : : 73 : : //! Get the index of the required material pressure from vector of primitives 74 : : //! \param[in] kmat Index of required material diff --git a/Debug/test_coverage/PDE/MultiMat/Physics/DGEuler.hpp.func-sort-c.html b/Debug/test_coverage/PDE/MultiMat/Physics/DGEuler.hpp.func-sort-c.html index 18bd8f7dc0f5..29efa375f930 100644 --- a/Debug/test_coverage/PDE/MultiMat/Physics/DGEuler.hpp.func-sort-c.html +++ b/Debug/test_coverage/PDE/MultiMat/Physics/DGEuler.hpp.func-sort-c.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:43:41 + 2024-07-11 15:06:04 Functions: 1 diff --git a/Debug/test_coverage/PDE/MultiMat/Physics/DGEuler.hpp.func.html b/Debug/test_coverage/PDE/MultiMat/Physics/DGEuler.hpp.func.html index d65784a31b77..6d36faa1acf5 100644 --- a/Debug/test_coverage/PDE/MultiMat/Physics/DGEuler.hpp.func.html +++ b/Debug/test_coverage/PDE/MultiMat/Physics/DGEuler.hpp.func.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:43:41 + 2024-07-11 15:06:04 Functions: 1 diff --git a/Debug/test_coverage/PDE/MultiMat/Physics/DGEuler.hpp.gcov.html b/Debug/test_coverage/PDE/MultiMat/Physics/DGEuler.hpp.gcov.html index 7176c37ca27f..3fdf4ce0093d 100644 --- a/Debug/test_coverage/PDE/MultiMat/Physics/DGEuler.hpp.gcov.html +++ b/Debug/test_coverage/PDE/MultiMat/Physics/DGEuler.hpp.gcov.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:43:41 + 2024-07-11 15:06:04 Functions: 1 diff --git a/Debug/test_coverage/PDE/MultiMat/Physics/FVEnergyPill.cpp.func-sort-c.html b/Debug/test_coverage/PDE/MultiMat/Physics/FVEnergyPill.cpp.func-sort-c.html index 5e30eaebffeb..076e2c9f0a54 100644 --- a/Debug/test_coverage/PDE/MultiMat/Physics/FVEnergyPill.cpp.func-sort-c.html +++ b/Debug/test_coverage/PDE/MultiMat/Physics/FVEnergyPill.cpp.func-sort-c.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:43:41 + 2024-07-11 15:06:04 Functions: 2 diff --git a/Debug/test_coverage/PDE/MultiMat/Physics/FVEnergyPill.cpp.func.html b/Debug/test_coverage/PDE/MultiMat/Physics/FVEnergyPill.cpp.func.html index c018818ac046..1e1c528d93d6 100644 --- a/Debug/test_coverage/PDE/MultiMat/Physics/FVEnergyPill.cpp.func.html +++ b/Debug/test_coverage/PDE/MultiMat/Physics/FVEnergyPill.cpp.func.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:43:41 + 2024-07-11 15:06:04 Functions: 2 diff --git a/Debug/test_coverage/PDE/MultiMat/Physics/FVEnergyPill.cpp.gcov.html b/Debug/test_coverage/PDE/MultiMat/Physics/FVEnergyPill.cpp.gcov.html index eaaaef3a68b9..434491ae6bbd 100644 --- a/Debug/test_coverage/PDE/MultiMat/Physics/FVEnergyPill.cpp.gcov.html +++ b/Debug/test_coverage/PDE/MultiMat/Physics/FVEnergyPill.cpp.gcov.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:43:41 + 2024-07-11 15:06:04 Functions: 2 diff --git a/Debug/test_coverage/PDE/MultiMat/Physics/FVEnergyPill.hpp.func-sort-c.html b/Debug/test_coverage/PDE/MultiMat/Physics/FVEnergyPill.hpp.func-sort-c.html index 1c7914059645..2c490677b9b4 100644 --- a/Debug/test_coverage/PDE/MultiMat/Physics/FVEnergyPill.hpp.func-sort-c.html +++ b/Debug/test_coverage/PDE/MultiMat/Physics/FVEnergyPill.hpp.func-sort-c.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:43:41 + 2024-07-11 15:06:04 Functions: 1 diff --git a/Debug/test_coverage/PDE/MultiMat/Physics/FVEnergyPill.hpp.func.html b/Debug/test_coverage/PDE/MultiMat/Physics/FVEnergyPill.hpp.func.html index 365f0a9cb94d..9d7c0ca4cb2e 100644 --- a/Debug/test_coverage/PDE/MultiMat/Physics/FVEnergyPill.hpp.func.html +++ b/Debug/test_coverage/PDE/MultiMat/Physics/FVEnergyPill.hpp.func.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:43:41 + 2024-07-11 15:06:04 Functions: 1 diff --git a/Debug/test_coverage/PDE/MultiMat/Physics/FVEnergyPill.hpp.gcov.html b/Debug/test_coverage/PDE/MultiMat/Physics/FVEnergyPill.hpp.gcov.html index b2f25f8fe1c3..6f6a21cc631e 100644 --- a/Debug/test_coverage/PDE/MultiMat/Physics/FVEnergyPill.hpp.gcov.html +++ b/Debug/test_coverage/PDE/MultiMat/Physics/FVEnergyPill.hpp.gcov.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:43:41 + 2024-07-11 15:06:04 Functions: 1 diff --git a/Debug/test_coverage/PDE/MultiMat/Physics/FVEuler.hpp.func-sort-c.html b/Debug/test_coverage/PDE/MultiMat/Physics/FVEuler.hpp.func-sort-c.html index 11d81e3c4b86..cbc8a68148dc 100644 --- a/Debug/test_coverage/PDE/MultiMat/Physics/FVEuler.hpp.func-sort-c.html +++ b/Debug/test_coverage/PDE/MultiMat/Physics/FVEuler.hpp.func-sort-c.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:43:41 + 2024-07-11 15:06:04 Functions: 3 diff --git a/Debug/test_coverage/PDE/MultiMat/Physics/FVEuler.hpp.func.html b/Debug/test_coverage/PDE/MultiMat/Physics/FVEuler.hpp.func.html index 9957268da98b..77e12440c3de 100644 --- a/Debug/test_coverage/PDE/MultiMat/Physics/FVEuler.hpp.func.html +++ b/Debug/test_coverage/PDE/MultiMat/Physics/FVEuler.hpp.func.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:43:41 + 2024-07-11 15:06:04 Functions: 3 diff --git a/Debug/test_coverage/PDE/MultiMat/Physics/FVEuler.hpp.gcov.html b/Debug/test_coverage/PDE/MultiMat/Physics/FVEuler.hpp.gcov.html index a31fa28e80a3..99cdfa640c59 100644 --- a/Debug/test_coverage/PDE/MultiMat/Physics/FVEuler.hpp.gcov.html +++ b/Debug/test_coverage/PDE/MultiMat/Physics/FVEuler.hpp.gcov.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:43:41 + 2024-07-11 15:06:04 Functions: 3 diff --git a/Debug/test_coverage/PDE/MultiMat/Physics/index-sort-b.html b/Debug/test_coverage/PDE/MultiMat/Physics/index-sort-b.html index 0afc6adb1c98..3d158ab4625d 100644 --- a/Debug/test_coverage/PDE/MultiMat/Physics/index-sort-b.html +++ b/Debug/test_coverage/PDE/MultiMat/Physics/index-sort-b.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:43:41 + 2024-07-11 15:06:04 Functions: 7 diff --git a/Debug/test_coverage/PDE/MultiMat/Physics/index-sort-f.html b/Debug/test_coverage/PDE/MultiMat/Physics/index-sort-f.html index 885282f24ba7..4cfc0924bcb0 100644 --- a/Debug/test_coverage/PDE/MultiMat/Physics/index-sort-f.html +++ b/Debug/test_coverage/PDE/MultiMat/Physics/index-sort-f.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:43:41 + 2024-07-11 15:06:04 Functions: 7 diff --git a/Debug/test_coverage/PDE/MultiMat/Physics/index-sort-l.html b/Debug/test_coverage/PDE/MultiMat/Physics/index-sort-l.html index d1feb8979aad..be20e84d4589 100644 --- a/Debug/test_coverage/PDE/MultiMat/Physics/index-sort-l.html +++ b/Debug/test_coverage/PDE/MultiMat/Physics/index-sort-l.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:43:41 + 2024-07-11 15:06:04 Functions: 7 diff --git a/Debug/test_coverage/PDE/MultiMat/Physics/index.html b/Debug/test_coverage/PDE/MultiMat/Physics/index.html index f7e2b8afe735..fca04e53c3bd 100644 --- a/Debug/test_coverage/PDE/MultiMat/Physics/index.html +++ b/Debug/test_coverage/PDE/MultiMat/Physics/index.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:43:41 + 2024-07-11 15:06:04 Functions: 7 diff --git a/Debug/test_coverage/PDE/MultiMat/Problem/BoxInitialization.hpp.func-sort-c.html b/Debug/test_coverage/PDE/MultiMat/Problem/BoxInitialization.hpp.func-sort-c.html index 5fa89f34f4e6..43ea3b8bee50 100644 --- a/Debug/test_coverage/PDE/MultiMat/Problem/BoxInitialization.hpp.func-sort-c.html +++ b/Debug/test_coverage/PDE/MultiMat/Problem/BoxInitialization.hpp.func-sort-c.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:43:41 + 2024-07-11 15:06:04 Functions: 1 diff --git a/Debug/test_coverage/PDE/MultiMat/Problem/BoxInitialization.hpp.func.html b/Debug/test_coverage/PDE/MultiMat/Problem/BoxInitialization.hpp.func.html index da9fb042e42b..d4e634856b3a 100644 --- a/Debug/test_coverage/PDE/MultiMat/Problem/BoxInitialization.hpp.func.html +++ b/Debug/test_coverage/PDE/MultiMat/Problem/BoxInitialization.hpp.func.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:43:41 + 2024-07-11 15:06:04 Functions: 1 diff --git a/Debug/test_coverage/PDE/MultiMat/Problem/BoxInitialization.hpp.gcov.html b/Debug/test_coverage/PDE/MultiMat/Problem/BoxInitialization.hpp.gcov.html index 6b802e89b6bc..363d4116bd56 100644 --- a/Debug/test_coverage/PDE/MultiMat/Problem/BoxInitialization.hpp.gcov.html +++ b/Debug/test_coverage/PDE/MultiMat/Problem/BoxInitialization.hpp.gcov.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:43:41 + 2024-07-11 15:06:04 Functions: 1 diff --git a/Debug/test_coverage/PDE/MultiMat/Problem/EquilInterfaceAdvect.cpp.func-sort-c.html b/Debug/test_coverage/PDE/MultiMat/Problem/EquilInterfaceAdvect.cpp.func-sort-c.html index b90f50f570e0..9c2229acdfea 100644 --- a/Debug/test_coverage/PDE/MultiMat/Problem/EquilInterfaceAdvect.cpp.func-sort-c.html +++ b/Debug/test_coverage/PDE/MultiMat/Problem/EquilInterfaceAdvect.cpp.func-sort-c.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:43:41 + 2024-07-11 15:06:04 Functions: 0 diff --git a/Debug/test_coverage/PDE/MultiMat/Problem/EquilInterfaceAdvect.cpp.func.html b/Debug/test_coverage/PDE/MultiMat/Problem/EquilInterfaceAdvect.cpp.func.html index a1c6df169dff..73771cc31fe6 100644 --- a/Debug/test_coverage/PDE/MultiMat/Problem/EquilInterfaceAdvect.cpp.func.html +++ b/Debug/test_coverage/PDE/MultiMat/Problem/EquilInterfaceAdvect.cpp.func.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:43:41 + 2024-07-11 15:06:04 Functions: 0 diff --git a/Debug/test_coverage/PDE/MultiMat/Problem/EquilInterfaceAdvect.cpp.gcov.html b/Debug/test_coverage/PDE/MultiMat/Problem/EquilInterfaceAdvect.cpp.gcov.html index 30b8d5a91ecb..deef7de845a0 100644 --- a/Debug/test_coverage/PDE/MultiMat/Problem/EquilInterfaceAdvect.cpp.gcov.html +++ b/Debug/test_coverage/PDE/MultiMat/Problem/EquilInterfaceAdvect.cpp.gcov.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:43:41 + 2024-07-11 15:06:04 Functions: 0 diff --git a/Debug/test_coverage/PDE/MultiMat/Problem/EquilInterfaceAdvect.hpp.func-sort-c.html b/Debug/test_coverage/PDE/MultiMat/Problem/EquilInterfaceAdvect.hpp.func-sort-c.html index e7d7a5b628fa..ebf8de21086c 100644 --- a/Debug/test_coverage/PDE/MultiMat/Problem/EquilInterfaceAdvect.hpp.func-sort-c.html +++ b/Debug/test_coverage/PDE/MultiMat/Problem/EquilInterfaceAdvect.hpp.func-sort-c.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:43:41 + 2024-07-11 15:06:04 Functions: 1 diff --git a/Debug/test_coverage/PDE/MultiMat/Problem/EquilInterfaceAdvect.hpp.func.html b/Debug/test_coverage/PDE/MultiMat/Problem/EquilInterfaceAdvect.hpp.func.html index 8cf10ab51b60..e270aadabcc8 100644 --- a/Debug/test_coverage/PDE/MultiMat/Problem/EquilInterfaceAdvect.hpp.func.html +++ b/Debug/test_coverage/PDE/MultiMat/Problem/EquilInterfaceAdvect.hpp.func.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:43:41 + 2024-07-11 15:06:04 Functions: 1 diff --git a/Debug/test_coverage/PDE/MultiMat/Problem/EquilInterfaceAdvect.hpp.gcov.html b/Debug/test_coverage/PDE/MultiMat/Problem/EquilInterfaceAdvect.hpp.gcov.html index 43371cd61f10..72bd42577d67 100644 --- a/Debug/test_coverage/PDE/MultiMat/Problem/EquilInterfaceAdvect.hpp.gcov.html +++ b/Debug/test_coverage/PDE/MultiMat/Problem/EquilInterfaceAdvect.hpp.gcov.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:43:41 + 2024-07-11 15:06:04 Functions: 1 diff --git a/Debug/test_coverage/PDE/MultiMat/Problem/FieldOutput.cpp.func-sort-c.html b/Debug/test_coverage/PDE/MultiMat/Problem/FieldOutput.cpp.func-sort-c.html index efe9250523f2..e8eb556fc7cd 100644 --- a/Debug/test_coverage/PDE/MultiMat/Problem/FieldOutput.cpp.func-sort-c.html +++ b/Debug/test_coverage/PDE/MultiMat/Problem/FieldOutput.cpp.func-sort-c.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:43:41 + 2024-07-11 15:06:04 Functions: 4 diff --git a/Debug/test_coverage/PDE/MultiMat/Problem/FieldOutput.cpp.func.html b/Debug/test_coverage/PDE/MultiMat/Problem/FieldOutput.cpp.func.html index bba86f6ed2b5..1598e7b3abec 100644 --- a/Debug/test_coverage/PDE/MultiMat/Problem/FieldOutput.cpp.func.html +++ b/Debug/test_coverage/PDE/MultiMat/Problem/FieldOutput.cpp.func.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:43:41 + 2024-07-11 15:06:04 Functions: 4 diff --git a/Debug/test_coverage/PDE/MultiMat/Problem/FieldOutput.cpp.gcov.html b/Debug/test_coverage/PDE/MultiMat/Problem/FieldOutput.cpp.gcov.html index 7fd27614a69d..adbeb17b1b80 100644 --- a/Debug/test_coverage/PDE/MultiMat/Problem/FieldOutput.cpp.gcov.html +++ b/Debug/test_coverage/PDE/MultiMat/Problem/FieldOutput.cpp.gcov.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:43:41 + 2024-07-11 15:06:04 Functions: 4 diff --git a/Debug/test_coverage/PDE/MultiMat/Problem/InterfaceAdvection.cpp.func-sort-c.html b/Debug/test_coverage/PDE/MultiMat/Problem/InterfaceAdvection.cpp.func-sort-c.html index d2e0fd1d55a5..8151e655a9f9 100644 --- a/Debug/test_coverage/PDE/MultiMat/Problem/InterfaceAdvection.cpp.func-sort-c.html +++ b/Debug/test_coverage/PDE/MultiMat/Problem/InterfaceAdvection.cpp.func-sort-c.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:43:41 + 2024-07-11 15:06:04 Functions: 1 diff --git a/Debug/test_coverage/PDE/MultiMat/Problem/InterfaceAdvection.cpp.func.html b/Debug/test_coverage/PDE/MultiMat/Problem/InterfaceAdvection.cpp.func.html index 1f178227c3c5..8e2423a412c1 100644 --- a/Debug/test_coverage/PDE/MultiMat/Problem/InterfaceAdvection.cpp.func.html +++ b/Debug/test_coverage/PDE/MultiMat/Problem/InterfaceAdvection.cpp.func.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:43:41 + 2024-07-11 15:06:04 Functions: 1 diff --git a/Debug/test_coverage/PDE/MultiMat/Problem/InterfaceAdvection.cpp.gcov.html b/Debug/test_coverage/PDE/MultiMat/Problem/InterfaceAdvection.cpp.gcov.html index 981ea6bc0037..699c722bec83 100644 --- a/Debug/test_coverage/PDE/MultiMat/Problem/InterfaceAdvection.cpp.gcov.html +++ b/Debug/test_coverage/PDE/MultiMat/Problem/InterfaceAdvection.cpp.gcov.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:43:41 + 2024-07-11 15:06:04 Functions: 1 diff --git a/Debug/test_coverage/PDE/MultiMat/Problem/InterfaceAdvection.hpp.func-sort-c.html b/Debug/test_coverage/PDE/MultiMat/Problem/InterfaceAdvection.hpp.func-sort-c.html index 29cc85ec9efa..34807fe4921b 100644 --- a/Debug/test_coverage/PDE/MultiMat/Problem/InterfaceAdvection.hpp.func-sort-c.html +++ b/Debug/test_coverage/PDE/MultiMat/Problem/InterfaceAdvection.hpp.func-sort-c.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:43:41 + 2024-07-11 15:06:04 Functions: 2 diff --git a/Debug/test_coverage/PDE/MultiMat/Problem/InterfaceAdvection.hpp.func.html b/Debug/test_coverage/PDE/MultiMat/Problem/InterfaceAdvection.hpp.func.html index 4843587b5537..2432df19cac1 100644 --- a/Debug/test_coverage/PDE/MultiMat/Problem/InterfaceAdvection.hpp.func.html +++ b/Debug/test_coverage/PDE/MultiMat/Problem/InterfaceAdvection.hpp.func.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:43:41 + 2024-07-11 15:06:04 Functions: 2 diff --git a/Debug/test_coverage/PDE/MultiMat/Problem/InterfaceAdvection.hpp.gcov.html b/Debug/test_coverage/PDE/MultiMat/Problem/InterfaceAdvection.hpp.gcov.html index f9ebbc41be9c..108f460606ed 100644 --- a/Debug/test_coverage/PDE/MultiMat/Problem/InterfaceAdvection.hpp.gcov.html +++ b/Debug/test_coverage/PDE/MultiMat/Problem/InterfaceAdvection.hpp.gcov.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:43:41 + 2024-07-11 15:06:04 Functions: 2 diff --git a/Debug/test_coverage/PDE/MultiMat/Problem/RichtmyerMeshkov.cpp.func-sort-c.html b/Debug/test_coverage/PDE/MultiMat/Problem/RichtmyerMeshkov.cpp.func-sort-c.html index ea189687c41a..a58651edd316 100644 --- a/Debug/test_coverage/PDE/MultiMat/Problem/RichtmyerMeshkov.cpp.func-sort-c.html +++ b/Debug/test_coverage/PDE/MultiMat/Problem/RichtmyerMeshkov.cpp.func-sort-c.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:43:41 + 2024-07-11 15:06:04 Functions: 0 diff --git a/Debug/test_coverage/PDE/MultiMat/Problem/RichtmyerMeshkov.cpp.func.html b/Debug/test_coverage/PDE/MultiMat/Problem/RichtmyerMeshkov.cpp.func.html index dbe1e46affb5..2b318f5eb9c4 100644 --- a/Debug/test_coverage/PDE/MultiMat/Problem/RichtmyerMeshkov.cpp.func.html +++ b/Debug/test_coverage/PDE/MultiMat/Problem/RichtmyerMeshkov.cpp.func.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:43:41 + 2024-07-11 15:06:04 Functions: 0 diff --git a/Debug/test_coverage/PDE/MultiMat/Problem/RichtmyerMeshkov.cpp.gcov.html b/Debug/test_coverage/PDE/MultiMat/Problem/RichtmyerMeshkov.cpp.gcov.html index ee349cf812a0..e4948a5ed3cb 100644 --- a/Debug/test_coverage/PDE/MultiMat/Problem/RichtmyerMeshkov.cpp.gcov.html +++ b/Debug/test_coverage/PDE/MultiMat/Problem/RichtmyerMeshkov.cpp.gcov.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:43:41 + 2024-07-11 15:06:04 Functions: 0 diff --git a/Debug/test_coverage/PDE/MultiMat/Problem/RichtmyerMeshkov.hpp.func-sort-c.html b/Debug/test_coverage/PDE/MultiMat/Problem/RichtmyerMeshkov.hpp.func-sort-c.html index 34d7d4b87df9..52ded92fcddd 100644 --- a/Debug/test_coverage/PDE/MultiMat/Problem/RichtmyerMeshkov.hpp.func-sort-c.html +++ b/Debug/test_coverage/PDE/MultiMat/Problem/RichtmyerMeshkov.hpp.func-sort-c.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:43:41 + 2024-07-11 15:06:04 Functions: 1 diff --git a/Debug/test_coverage/PDE/MultiMat/Problem/RichtmyerMeshkov.hpp.func.html b/Debug/test_coverage/PDE/MultiMat/Problem/RichtmyerMeshkov.hpp.func.html index b5f3ae8353ec..098ea69ca08e 100644 --- a/Debug/test_coverage/PDE/MultiMat/Problem/RichtmyerMeshkov.hpp.func.html +++ b/Debug/test_coverage/PDE/MultiMat/Problem/RichtmyerMeshkov.hpp.func.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:43:41 + 2024-07-11 15:06:04 Functions: 1 diff --git a/Debug/test_coverage/PDE/MultiMat/Problem/RichtmyerMeshkov.hpp.gcov.html b/Debug/test_coverage/PDE/MultiMat/Problem/RichtmyerMeshkov.hpp.gcov.html index 2370de7b4717..b735970152d4 100644 --- a/Debug/test_coverage/PDE/MultiMat/Problem/RichtmyerMeshkov.hpp.gcov.html +++ b/Debug/test_coverage/PDE/MultiMat/Problem/RichtmyerMeshkov.hpp.gcov.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:43:41 + 2024-07-11 15:06:04 Functions: 1 diff --git a/Debug/test_coverage/PDE/MultiMat/Problem/ShockDensityWave.cpp.func-sort-c.html b/Debug/test_coverage/PDE/MultiMat/Problem/ShockDensityWave.cpp.func-sort-c.html index 793abf1b4600..e3253a65a85e 100644 --- a/Debug/test_coverage/PDE/MultiMat/Problem/ShockDensityWave.cpp.func-sort-c.html +++ b/Debug/test_coverage/PDE/MultiMat/Problem/ShockDensityWave.cpp.func-sort-c.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:43:41 + 2024-07-11 15:06:04 Functions: 0 diff --git a/Debug/test_coverage/PDE/MultiMat/Problem/ShockDensityWave.cpp.func.html b/Debug/test_coverage/PDE/MultiMat/Problem/ShockDensityWave.cpp.func.html index ab407641815c..892565d3c738 100644 --- a/Debug/test_coverage/PDE/MultiMat/Problem/ShockDensityWave.cpp.func.html +++ b/Debug/test_coverage/PDE/MultiMat/Problem/ShockDensityWave.cpp.func.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:43:41 + 2024-07-11 15:06:04 Functions: 0 diff --git a/Debug/test_coverage/PDE/MultiMat/Problem/ShockDensityWave.cpp.gcov.html b/Debug/test_coverage/PDE/MultiMat/Problem/ShockDensityWave.cpp.gcov.html index 35b425d3a162..9538c5bc1945 100644 --- a/Debug/test_coverage/PDE/MultiMat/Problem/ShockDensityWave.cpp.gcov.html +++ b/Debug/test_coverage/PDE/MultiMat/Problem/ShockDensityWave.cpp.gcov.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:43:41 + 2024-07-11 15:06:04 Functions: 0 diff --git a/Debug/test_coverage/PDE/MultiMat/Problem/ShockDensityWave.hpp.func-sort-c.html b/Debug/test_coverage/PDE/MultiMat/Problem/ShockDensityWave.hpp.func-sort-c.html index f49cee68b4cd..90d5af202914 100644 --- a/Debug/test_coverage/PDE/MultiMat/Problem/ShockDensityWave.hpp.func-sort-c.html +++ b/Debug/test_coverage/PDE/MultiMat/Problem/ShockDensityWave.hpp.func-sort-c.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:43:41 + 2024-07-11 15:06:04 Functions: 1 diff --git a/Debug/test_coverage/PDE/MultiMat/Problem/ShockDensityWave.hpp.func.html b/Debug/test_coverage/PDE/MultiMat/Problem/ShockDensityWave.hpp.func.html index 5d6f33cd4eb5..5b159883bd7d 100644 --- a/Debug/test_coverage/PDE/MultiMat/Problem/ShockDensityWave.hpp.func.html +++ b/Debug/test_coverage/PDE/MultiMat/Problem/ShockDensityWave.hpp.func.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:43:41 + 2024-07-11 15:06:04 Functions: 1 diff --git a/Debug/test_coverage/PDE/MultiMat/Problem/ShockDensityWave.hpp.gcov.html b/Debug/test_coverage/PDE/MultiMat/Problem/ShockDensityWave.hpp.gcov.html index bb5b104aff00..77fbd717ad2c 100644 --- a/Debug/test_coverage/PDE/MultiMat/Problem/ShockDensityWave.hpp.gcov.html +++ b/Debug/test_coverage/PDE/MultiMat/Problem/ShockDensityWave.hpp.gcov.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:43:41 + 2024-07-11 15:06:04 Functions: 1 diff --git a/Debug/test_coverage/PDE/MultiMat/Problem/ShockHeBubble.cpp.func-sort-c.html b/Debug/test_coverage/PDE/MultiMat/Problem/ShockHeBubble.cpp.func-sort-c.html index da1fa09b3a42..794e1e74fed4 100644 --- a/Debug/test_coverage/PDE/MultiMat/Problem/ShockHeBubble.cpp.func-sort-c.html +++ b/Debug/test_coverage/PDE/MultiMat/Problem/ShockHeBubble.cpp.func-sort-c.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:43:41 + 2024-07-11 15:06:04 Functions: 0 diff --git a/Debug/test_coverage/PDE/MultiMat/Problem/ShockHeBubble.cpp.func.html b/Debug/test_coverage/PDE/MultiMat/Problem/ShockHeBubble.cpp.func.html index f47a92518fb0..de2a6bf585e3 100644 --- a/Debug/test_coverage/PDE/MultiMat/Problem/ShockHeBubble.cpp.func.html +++ b/Debug/test_coverage/PDE/MultiMat/Problem/ShockHeBubble.cpp.func.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:43:41 + 2024-07-11 15:06:04 Functions: 0 diff --git a/Debug/test_coverage/PDE/MultiMat/Problem/ShockHeBubble.cpp.gcov.html b/Debug/test_coverage/PDE/MultiMat/Problem/ShockHeBubble.cpp.gcov.html index 9120e0bae37d..b2d489e053ba 100644 --- a/Debug/test_coverage/PDE/MultiMat/Problem/ShockHeBubble.cpp.gcov.html +++ b/Debug/test_coverage/PDE/MultiMat/Problem/ShockHeBubble.cpp.gcov.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:43:41 + 2024-07-11 15:06:04 Functions: 0 diff --git a/Debug/test_coverage/PDE/MultiMat/Problem/ShockHeBubble.hpp.func-sort-c.html b/Debug/test_coverage/PDE/MultiMat/Problem/ShockHeBubble.hpp.func-sort-c.html index 7a69110c06a2..ecfa943ffa19 100644 --- a/Debug/test_coverage/PDE/MultiMat/Problem/ShockHeBubble.hpp.func-sort-c.html +++ b/Debug/test_coverage/PDE/MultiMat/Problem/ShockHeBubble.hpp.func-sort-c.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:43:41 + 2024-07-11 15:06:04 Functions: 1 diff --git a/Debug/test_coverage/PDE/MultiMat/Problem/ShockHeBubble.hpp.func.html b/Debug/test_coverage/PDE/MultiMat/Problem/ShockHeBubble.hpp.func.html index 545cf6c4a063..95c6b6b36501 100644 --- a/Debug/test_coverage/PDE/MultiMat/Problem/ShockHeBubble.hpp.func.html +++ b/Debug/test_coverage/PDE/MultiMat/Problem/ShockHeBubble.hpp.func.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:43:41 + 2024-07-11 15:06:04 Functions: 1 diff --git a/Debug/test_coverage/PDE/MultiMat/Problem/ShockHeBubble.hpp.gcov.html b/Debug/test_coverage/PDE/MultiMat/Problem/ShockHeBubble.hpp.gcov.html index b115cf2b429e..727d7f7c0eab 100644 --- a/Debug/test_coverage/PDE/MultiMat/Problem/ShockHeBubble.hpp.gcov.html +++ b/Debug/test_coverage/PDE/MultiMat/Problem/ShockHeBubble.hpp.gcov.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:43:41 + 2024-07-11 15:06:04 Functions: 1 diff --git a/Debug/test_coverage/PDE/MultiMat/Problem/SinewavePacket.cpp.func-sort-c.html b/Debug/test_coverage/PDE/MultiMat/Problem/SinewavePacket.cpp.func-sort-c.html index d4cd9d43ab82..c95a0eb3be83 100644 --- a/Debug/test_coverage/PDE/MultiMat/Problem/SinewavePacket.cpp.func-sort-c.html +++ b/Debug/test_coverage/PDE/MultiMat/Problem/SinewavePacket.cpp.func-sort-c.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:43:41 + 2024-07-11 15:06:04 Functions: 0 diff --git a/Debug/test_coverage/PDE/MultiMat/Problem/SinewavePacket.cpp.func.html b/Debug/test_coverage/PDE/MultiMat/Problem/SinewavePacket.cpp.func.html index c97cc0397bad..16e867bfd30f 100644 --- a/Debug/test_coverage/PDE/MultiMat/Problem/SinewavePacket.cpp.func.html +++ b/Debug/test_coverage/PDE/MultiMat/Problem/SinewavePacket.cpp.func.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:43:41 + 2024-07-11 15:06:04 Functions: 0 diff --git a/Debug/test_coverage/PDE/MultiMat/Problem/SinewavePacket.cpp.gcov.html b/Debug/test_coverage/PDE/MultiMat/Problem/SinewavePacket.cpp.gcov.html index a2c54ec1168b..7857edd06781 100644 --- a/Debug/test_coverage/PDE/MultiMat/Problem/SinewavePacket.cpp.gcov.html +++ b/Debug/test_coverage/PDE/MultiMat/Problem/SinewavePacket.cpp.gcov.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:43:41 + 2024-07-11 15:06:04 Functions: 0 diff --git a/Debug/test_coverage/PDE/MultiMat/Problem/SinewavePacket.hpp.func-sort-c.html b/Debug/test_coverage/PDE/MultiMat/Problem/SinewavePacket.hpp.func-sort-c.html index 0471fcf8f540..67842a0f33aa 100644 --- a/Debug/test_coverage/PDE/MultiMat/Problem/SinewavePacket.hpp.func-sort-c.html +++ b/Debug/test_coverage/PDE/MultiMat/Problem/SinewavePacket.hpp.func-sort-c.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:43:41 + 2024-07-11 15:06:04 Functions: 1 diff --git a/Debug/test_coverage/PDE/MultiMat/Problem/SinewavePacket.hpp.func.html b/Debug/test_coverage/PDE/MultiMat/Problem/SinewavePacket.hpp.func.html index f98b54a4badf..d385c42fe2cc 100644 --- a/Debug/test_coverage/PDE/MultiMat/Problem/SinewavePacket.hpp.func.html +++ b/Debug/test_coverage/PDE/MultiMat/Problem/SinewavePacket.hpp.func.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:43:41 + 2024-07-11 15:06:04 Functions: 1 diff --git a/Debug/test_coverage/PDE/MultiMat/Problem/SinewavePacket.hpp.gcov.html b/Debug/test_coverage/PDE/MultiMat/Problem/SinewavePacket.hpp.gcov.html index 35cfa890086a..856921cbd634 100644 --- a/Debug/test_coverage/PDE/MultiMat/Problem/SinewavePacket.hpp.gcov.html +++ b/Debug/test_coverage/PDE/MultiMat/Problem/SinewavePacket.hpp.gcov.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:43:41 + 2024-07-11 15:06:04 Functions: 1 diff --git a/Debug/test_coverage/PDE/MultiMat/Problem/SodShocktube.cpp.func-sort-c.html b/Debug/test_coverage/PDE/MultiMat/Problem/SodShocktube.cpp.func-sort-c.html index abbe19b9c10d..1ac73cae063b 100644 --- a/Debug/test_coverage/PDE/MultiMat/Problem/SodShocktube.cpp.func-sort-c.html +++ b/Debug/test_coverage/PDE/MultiMat/Problem/SodShocktube.cpp.func-sort-c.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:43:41 + 2024-07-11 15:06:04 Functions: 1 diff --git a/Debug/test_coverage/PDE/MultiMat/Problem/SodShocktube.cpp.func.html b/Debug/test_coverage/PDE/MultiMat/Problem/SodShocktube.cpp.func.html index f7a7f34a3cd3..3da750551b2b 100644 --- a/Debug/test_coverage/PDE/MultiMat/Problem/SodShocktube.cpp.func.html +++ b/Debug/test_coverage/PDE/MultiMat/Problem/SodShocktube.cpp.func.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:43:41 + 2024-07-11 15:06:04 Functions: 1 diff --git a/Debug/test_coverage/PDE/MultiMat/Problem/SodShocktube.cpp.gcov.html b/Debug/test_coverage/PDE/MultiMat/Problem/SodShocktube.cpp.gcov.html index 873b15bdcd1d..7d41bfd1dc4e 100644 --- a/Debug/test_coverage/PDE/MultiMat/Problem/SodShocktube.cpp.gcov.html +++ b/Debug/test_coverage/PDE/MultiMat/Problem/SodShocktube.cpp.gcov.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:43:41 + 2024-07-11 15:06:04 Functions: 1 diff --git a/Debug/test_coverage/PDE/MultiMat/Problem/SodShocktube.hpp.func-sort-c.html b/Debug/test_coverage/PDE/MultiMat/Problem/SodShocktube.hpp.func-sort-c.html index f58aca3286bf..da0962223b99 100644 --- a/Debug/test_coverage/PDE/MultiMat/Problem/SodShocktube.hpp.func-sort-c.html +++ b/Debug/test_coverage/PDE/MultiMat/Problem/SodShocktube.hpp.func-sort-c.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:43:41 + 2024-07-11 15:06:04 Functions: 2 diff --git a/Debug/test_coverage/PDE/MultiMat/Problem/SodShocktube.hpp.func.html b/Debug/test_coverage/PDE/MultiMat/Problem/SodShocktube.hpp.func.html index d1c4fa2f1911..7fdca2e040d0 100644 --- a/Debug/test_coverage/PDE/MultiMat/Problem/SodShocktube.hpp.func.html +++ b/Debug/test_coverage/PDE/MultiMat/Problem/SodShocktube.hpp.func.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:43:41 + 2024-07-11 15:06:04 Functions: 2 diff --git a/Debug/test_coverage/PDE/MultiMat/Problem/SodShocktube.hpp.gcov.html b/Debug/test_coverage/PDE/MultiMat/Problem/SodShocktube.hpp.gcov.html index 6ce68c8a6b8f..bd1e9c40525a 100644 --- a/Debug/test_coverage/PDE/MultiMat/Problem/SodShocktube.hpp.gcov.html +++ b/Debug/test_coverage/PDE/MultiMat/Problem/SodShocktube.hpp.gcov.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:43:41 + 2024-07-11 15:06:04 Functions: 2 diff --git a/Debug/test_coverage/PDE/MultiMat/Problem/UnderwaterEx.cpp.func-sort-c.html b/Debug/test_coverage/PDE/MultiMat/Problem/UnderwaterEx.cpp.func-sort-c.html index 65b9fe0b82c5..98f5b547aa14 100644 --- a/Debug/test_coverage/PDE/MultiMat/Problem/UnderwaterEx.cpp.func-sort-c.html +++ b/Debug/test_coverage/PDE/MultiMat/Problem/UnderwaterEx.cpp.func-sort-c.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:43:41 + 2024-07-11 15:06:04 Functions: 0 diff --git a/Debug/test_coverage/PDE/MultiMat/Problem/UnderwaterEx.cpp.func.html b/Debug/test_coverage/PDE/MultiMat/Problem/UnderwaterEx.cpp.func.html index b4bd1505bd0b..d80021852484 100644 --- a/Debug/test_coverage/PDE/MultiMat/Problem/UnderwaterEx.cpp.func.html +++ b/Debug/test_coverage/PDE/MultiMat/Problem/UnderwaterEx.cpp.func.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:43:41 + 2024-07-11 15:06:04 Functions: 0 diff --git a/Debug/test_coverage/PDE/MultiMat/Problem/UnderwaterEx.cpp.gcov.html b/Debug/test_coverage/PDE/MultiMat/Problem/UnderwaterEx.cpp.gcov.html index 113a8c4aeadc..4f2575e4e5db 100644 --- a/Debug/test_coverage/PDE/MultiMat/Problem/UnderwaterEx.cpp.gcov.html +++ b/Debug/test_coverage/PDE/MultiMat/Problem/UnderwaterEx.cpp.gcov.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:43:41 + 2024-07-11 15:06:04 Functions: 0 diff --git a/Debug/test_coverage/PDE/MultiMat/Problem/UnderwaterEx.hpp.func-sort-c.html b/Debug/test_coverage/PDE/MultiMat/Problem/UnderwaterEx.hpp.func-sort-c.html index a1ead9800848..fa0a08d39aa7 100644 --- a/Debug/test_coverage/PDE/MultiMat/Problem/UnderwaterEx.hpp.func-sort-c.html +++ b/Debug/test_coverage/PDE/MultiMat/Problem/UnderwaterEx.hpp.func-sort-c.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:43:41 + 2024-07-11 15:06:04 Functions: 1 diff --git a/Debug/test_coverage/PDE/MultiMat/Problem/UnderwaterEx.hpp.func.html b/Debug/test_coverage/PDE/MultiMat/Problem/UnderwaterEx.hpp.func.html index ea183e3b3424..073646cf8d8b 100644 --- a/Debug/test_coverage/PDE/MultiMat/Problem/UnderwaterEx.hpp.func.html +++ b/Debug/test_coverage/PDE/MultiMat/Problem/UnderwaterEx.hpp.func.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:43:41 + 2024-07-11 15:06:04 Functions: 1 diff --git a/Debug/test_coverage/PDE/MultiMat/Problem/UnderwaterEx.hpp.gcov.html b/Debug/test_coverage/PDE/MultiMat/Problem/UnderwaterEx.hpp.gcov.html index ecbdfef02855..9602a6b44c38 100644 --- a/Debug/test_coverage/PDE/MultiMat/Problem/UnderwaterEx.hpp.gcov.html +++ b/Debug/test_coverage/PDE/MultiMat/Problem/UnderwaterEx.hpp.gcov.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:43:41 + 2024-07-11 15:06:04 Functions: 1 diff --git a/Debug/test_coverage/PDE/MultiMat/Problem/UserDefined.cpp.func-sort-c.html b/Debug/test_coverage/PDE/MultiMat/Problem/UserDefined.cpp.func-sort-c.html index 20acbe273446..2d366c873fe4 100644 --- a/Debug/test_coverage/PDE/MultiMat/Problem/UserDefined.cpp.func-sort-c.html +++ b/Debug/test_coverage/PDE/MultiMat/Problem/UserDefined.cpp.func-sort-c.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:43:41 + 2024-07-11 15:06:04 Functions: 1 diff --git a/Debug/test_coverage/PDE/MultiMat/Problem/UserDefined.cpp.func.html b/Debug/test_coverage/PDE/MultiMat/Problem/UserDefined.cpp.func.html index 32857498a2e6..bc1b76285adc 100644 --- a/Debug/test_coverage/PDE/MultiMat/Problem/UserDefined.cpp.func.html +++ b/Debug/test_coverage/PDE/MultiMat/Problem/UserDefined.cpp.func.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:43:41 + 2024-07-11 15:06:04 Functions: 1 diff --git a/Debug/test_coverage/PDE/MultiMat/Problem/UserDefined.cpp.gcov.html b/Debug/test_coverage/PDE/MultiMat/Problem/UserDefined.cpp.gcov.html index 8f890cc8f03f..7fe0279ab71c 100644 --- a/Debug/test_coverage/PDE/MultiMat/Problem/UserDefined.cpp.gcov.html +++ b/Debug/test_coverage/PDE/MultiMat/Problem/UserDefined.cpp.gcov.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:43:41 + 2024-07-11 15:06:04 Functions: 1 diff --git a/Debug/test_coverage/PDE/MultiMat/Problem/UserDefined.hpp.func-sort-c.html b/Debug/test_coverage/PDE/MultiMat/Problem/UserDefined.hpp.func-sort-c.html index 080312b37e92..b15ef887bd7a 100644 --- a/Debug/test_coverage/PDE/MultiMat/Problem/UserDefined.hpp.func-sort-c.html +++ b/Debug/test_coverage/PDE/MultiMat/Problem/UserDefined.hpp.func-sort-c.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:43:41 + 2024-07-11 15:06:04 Functions: 2 diff --git a/Debug/test_coverage/PDE/MultiMat/Problem/UserDefined.hpp.func.html b/Debug/test_coverage/PDE/MultiMat/Problem/UserDefined.hpp.func.html index 4dd2fff33075..a7e44e1ccaa1 100644 --- a/Debug/test_coverage/PDE/MultiMat/Problem/UserDefined.hpp.func.html +++ b/Debug/test_coverage/PDE/MultiMat/Problem/UserDefined.hpp.func.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:43:41 + 2024-07-11 15:06:04 Functions: 2 diff --git a/Debug/test_coverage/PDE/MultiMat/Problem/UserDefined.hpp.gcov.html b/Debug/test_coverage/PDE/MultiMat/Problem/UserDefined.hpp.gcov.html index 2541aafe5f77..db9695cd8b36 100644 --- a/Debug/test_coverage/PDE/MultiMat/Problem/UserDefined.hpp.gcov.html +++ b/Debug/test_coverage/PDE/MultiMat/Problem/UserDefined.hpp.gcov.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:43:41 + 2024-07-11 15:06:04 Functions: 2 diff --git a/Debug/test_coverage/PDE/MultiMat/Problem/WaterAirShocktube.cpp.func-sort-c.html b/Debug/test_coverage/PDE/MultiMat/Problem/WaterAirShocktube.cpp.func-sort-c.html index 3ba5b1408583..0161d11a9ffc 100644 --- a/Debug/test_coverage/PDE/MultiMat/Problem/WaterAirShocktube.cpp.func-sort-c.html +++ b/Debug/test_coverage/PDE/MultiMat/Problem/WaterAirShocktube.cpp.func-sort-c.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:43:41 + 2024-07-11 15:06:04 Functions: 1 diff --git a/Debug/test_coverage/PDE/MultiMat/Problem/WaterAirShocktube.cpp.func.html b/Debug/test_coverage/PDE/MultiMat/Problem/WaterAirShocktube.cpp.func.html index 1496fa554b62..c81f44671508 100644 --- a/Debug/test_coverage/PDE/MultiMat/Problem/WaterAirShocktube.cpp.func.html +++ b/Debug/test_coverage/PDE/MultiMat/Problem/WaterAirShocktube.cpp.func.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:43:41 + 2024-07-11 15:06:04 Functions: 1 diff --git a/Debug/test_coverage/PDE/MultiMat/Problem/WaterAirShocktube.cpp.gcov.html b/Debug/test_coverage/PDE/MultiMat/Problem/WaterAirShocktube.cpp.gcov.html index 62a58a6f68fe..5199de1ffacc 100644 --- a/Debug/test_coverage/PDE/MultiMat/Problem/WaterAirShocktube.cpp.gcov.html +++ b/Debug/test_coverage/PDE/MultiMat/Problem/WaterAirShocktube.cpp.gcov.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:43:41 + 2024-07-11 15:06:04 Functions: 1 diff --git a/Debug/test_coverage/PDE/MultiMat/Problem/WaterAirShocktube.hpp.func-sort-c.html b/Debug/test_coverage/PDE/MultiMat/Problem/WaterAirShocktube.hpp.func-sort-c.html index 62a04ce13c55..9d5db93a6d7f 100644 --- a/Debug/test_coverage/PDE/MultiMat/Problem/WaterAirShocktube.hpp.func-sort-c.html +++ b/Debug/test_coverage/PDE/MultiMat/Problem/WaterAirShocktube.hpp.func-sort-c.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:43:41 + 2024-07-11 15:06:04 Functions: 2 diff --git a/Debug/test_coverage/PDE/MultiMat/Problem/WaterAirShocktube.hpp.func.html b/Debug/test_coverage/PDE/MultiMat/Problem/WaterAirShocktube.hpp.func.html index 7d8be3432eb8..5aa1feecd506 100644 --- a/Debug/test_coverage/PDE/MultiMat/Problem/WaterAirShocktube.hpp.func.html +++ b/Debug/test_coverage/PDE/MultiMat/Problem/WaterAirShocktube.hpp.func.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:43:41 + 2024-07-11 15:06:04 Functions: 2 diff --git a/Debug/test_coverage/PDE/MultiMat/Problem/WaterAirShocktube.hpp.gcov.html b/Debug/test_coverage/PDE/MultiMat/Problem/WaterAirShocktube.hpp.gcov.html index 0277d3dc8632..75973aa8f21d 100644 --- a/Debug/test_coverage/PDE/MultiMat/Problem/WaterAirShocktube.hpp.gcov.html +++ b/Debug/test_coverage/PDE/MultiMat/Problem/WaterAirShocktube.hpp.gcov.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:43:41 + 2024-07-11 15:06:04 Functions: 2 diff --git a/Debug/test_coverage/PDE/MultiMat/Problem/index-sort-b.html b/Debug/test_coverage/PDE/MultiMat/Problem/index-sort-b.html index 3e7ea8bebc13..2aa2b0999d53 100644 --- a/Debug/test_coverage/PDE/MultiMat/Problem/index-sort-b.html +++ b/Debug/test_coverage/PDE/MultiMat/Problem/index-sort-b.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:43:41 + 2024-07-11 15:06:04 Functions: 23 @@ -82,7 +82,7 @@ Branches Sort by branch coverage - ShockDensityWave.hpp + SinewavePacket.hpp
25.0%25.0%
@@ -94,7 +94,7 @@ 0 / 2 - ShockHeBubble.hpp + ShockDensityWave.hpp
25.0%25.0%
@@ -106,7 +106,7 @@ 0 / 2 - SinewavePacket.hpp + UnderwaterEx.hpp
25.0%25.0%
@@ -118,7 +118,7 @@ 0 / 2 - UnderwaterEx.hpp + RichtmyerMeshkov.hpp
25.0%25.0%
@@ -130,7 +130,7 @@ 0 / 2 - RichtmyerMeshkov.hpp + ShockHeBubble.hpp
25.0%25.0%
@@ -190,24 +190,24 @@ 0 / 20 - UnderwaterEx.cpp + ShockHeBubble.cpp
0.0%
0.0 % - 0 / 36 + 0 / 33 0.0 % 0 / 1 0.0 % 0 / 22 - ShockHeBubble.cpp + UnderwaterEx.cpp
0.0%
0.0 % - 0 / 33 + 0 / 36 0.0 % 0 / 1 0.0 % @@ -298,7 +298,7 @@ 20 / 32 - InterfaceAdvection.hpp + UserDefined.hpp
75.0%75.0%
@@ -310,7 +310,7 @@ 2 / 2 - UserDefined.hpp + WaterAirShocktube.hpp
75.0%75.0%
@@ -334,7 +334,7 @@ 2 / 2 - WaterAirShocktube.hpp + InterfaceAdvection.hpp
75.0%75.0%
diff --git a/Debug/test_coverage/PDE/MultiMat/Problem/index-sort-f.html b/Debug/test_coverage/PDE/MultiMat/Problem/index-sort-f.html index cc46ebff7feb..de045d6b1244 100644 --- a/Debug/test_coverage/PDE/MultiMat/Problem/index-sort-f.html +++ b/Debug/test_coverage/PDE/MultiMat/Problem/index-sort-f.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:43:41 + 2024-07-11 15:06:04 Functions: 23 @@ -82,16 +82,16 @@ Branches Sort by branch coverage - RichtmyerMeshkov.cpp + ShockHeBubble.cpp
0.0%
0.0 % - 0 / 32 + 0 / 33 0.0 % 0 / 1 0.0 % - 0 / 20 + 0 / 22 UnderwaterEx.cpp @@ -106,28 +106,28 @@ 0 / 22 - ShockHeBubble.cpp + RichtmyerMeshkov.cpp
0.0%
0.0 % - 0 / 33 + 0 / 32 0.0 % 0 / 1 0.0 % - 0 / 22 + 0 / 20 - EquilInterfaceAdvect.cpp + SinewavePacket.cpp
0.0%
0.0 % - 0 / 26 + 0 / 21 0.0 % 0 / 1 0.0 % - 0 / 14 + 0 / 20 ShockDensityWave.cpp @@ -142,31 +142,31 @@ 0 / 28 - SinewavePacket.cpp + EquilInterfaceAdvect.cpp
0.0%
0.0 % - 0 / 21 + 0 / 26 0.0 % 0 / 1 0.0 % - 0 / 20 + 0 / 14 - ShockDensityWave.hpp + EquilInterfaceAdvect.hpp -
25.0%25.0%
+
8.7%8.7%
- 25.0 % - 2 / 8 + 8.7 % + 2 / 23 33.3 % 1 / 3 0.0 % - 0 / 2 + 0 / 18 - ShockHeBubble.hpp + SinewavePacket.hpp
25.0%25.0%
@@ -178,7 +178,7 @@ 0 / 2 - SinewavePacket.hpp + ShockDensityWave.hpp
25.0%25.0%
@@ -214,16 +214,16 @@ 0 / 2 - EquilInterfaceAdvect.hpp + ShockHeBubble.hpp -
8.7%8.7%
+
25.0%25.0%
- 8.7 % - 2 / 23 + 25.0 % + 2 / 8 33.3 % 1 / 3 0.0 % - 0 / 18 + 0 / 2 BoxInitialization.hpp @@ -250,7 +250,7 @@ 128 / 440 - InterfaceAdvection.hpp + UserDefined.hpp
75.0%75.0%
@@ -262,7 +262,7 @@ 2 / 2 - UserDefined.hpp + WaterAirShocktube.hpp
75.0%75.0%
@@ -286,7 +286,7 @@ 2 / 2 - WaterAirShocktube.hpp + InterfaceAdvection.hpp
75.0%75.0%
@@ -298,28 +298,16 @@ 2 / 2 - UserDefined.cpp + WaterAirShocktube.cpp -
84.6%84.6%
+
100.0%
- 84.6 % - 33 / 39 100.0 % - 1 / 1 - 30.4 % - 14 / 46 - - - InterfaceAdvection.cpp - -
94.7%94.7%
- - 94.7 % - 36 / 38 + 27 / 27 100.0 % 1 / 1 - 62.5 % - 20 / 32 + 53.8 % + 14 / 26 SodShocktube.cpp @@ -334,16 +322,28 @@ 6 / 16 - WaterAirShocktube.cpp + UserDefined.cpp -
100.0%
+
84.6%84.6%
+ 84.6 % + 33 / 39 100.0 % - 27 / 27 + 1 / 1 + 30.4 % + 14 / 46 + + + InterfaceAdvection.cpp + +
94.7%94.7%
+ + 94.7 % + 36 / 38 100.0 % 1 / 1 - 53.8 % - 14 / 26 + 62.5 % + 20 / 32 diff --git a/Debug/test_coverage/PDE/MultiMat/Problem/index-sort-l.html b/Debug/test_coverage/PDE/MultiMat/Problem/index-sort-l.html index 8b97cd029aeb..bdd3e6779a5a 100644 --- a/Debug/test_coverage/PDE/MultiMat/Problem/index-sort-l.html +++ b/Debug/test_coverage/PDE/MultiMat/Problem/index-sort-l.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:43:41 + 2024-07-11 15:06:04 Functions: 23 @@ -166,7 +166,7 @@ 0 / 18 - ShockDensityWave.hpp + SinewavePacket.hpp
25.0%25.0%
@@ -178,7 +178,7 @@ 0 / 2 - ShockHeBubble.hpp + ShockDensityWave.hpp
25.0%25.0%
@@ -190,7 +190,7 @@ 0 / 2 - SinewavePacket.hpp + UnderwaterEx.hpp
25.0%25.0%
@@ -202,7 +202,7 @@ 0 / 2 - UnderwaterEx.hpp + RichtmyerMeshkov.hpp
25.0%25.0%
@@ -214,7 +214,7 @@ 0 / 2 - RichtmyerMeshkov.hpp + ShockHeBubble.hpp
25.0%25.0%
@@ -250,7 +250,7 @@ 26 / 98 - InterfaceAdvection.hpp + UserDefined.hpp
75.0%75.0%
@@ -262,7 +262,7 @@ 2 / 2 - UserDefined.hpp + WaterAirShocktube.hpp
75.0%75.0%
@@ -286,7 +286,7 @@ 2 / 2 - WaterAirShocktube.hpp + InterfaceAdvection.hpp
75.0%75.0%
@@ -322,7 +322,7 @@ 20 / 32 - SodShocktube.cpp + WaterAirShocktube.cpp
100.0%
@@ -330,11 +330,11 @@ 27 / 27 100.0 % 1 / 1 - 37.5 % - 6 / 16 + 53.8 % + 14 / 26 - WaterAirShocktube.cpp + SodShocktube.cpp
100.0%
@@ -342,8 +342,8 @@ 27 / 27 100.0 % 1 / 1 - 53.8 % - 14 / 26 + 37.5 % + 6 / 16 diff --git a/Debug/test_coverage/PDE/MultiMat/Problem/index.html b/Debug/test_coverage/PDE/MultiMat/Problem/index.html index f649ba9b2714..b66e6dfde151 100644 --- a/Debug/test_coverage/PDE/MultiMat/Problem/index.html +++ b/Debug/test_coverage/PDE/MultiMat/Problem/index.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:43:41 + 2024-07-11 15:06:04 Functions: 23 diff --git a/Debug/test_coverage/PDE/MultiMat/RiemannChoice.hpp.func-sort-c.html b/Debug/test_coverage/PDE/MultiMat/RiemannChoice.hpp.func-sort-c.html index 42686db6e3ea..10ab278ddd56 100644 --- a/Debug/test_coverage/PDE/MultiMat/RiemannChoice.hpp.func-sort-c.html +++ b/Debug/test_coverage/PDE/MultiMat/RiemannChoice.hpp.func-sort-c.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:43:41 + 2024-07-11 15:06:04 Functions: 1 diff --git a/Debug/test_coverage/PDE/MultiMat/RiemannChoice.hpp.func.html b/Debug/test_coverage/PDE/MultiMat/RiemannChoice.hpp.func.html index 52c96a738b80..753c0de5bc62 100644 --- a/Debug/test_coverage/PDE/MultiMat/RiemannChoice.hpp.func.html +++ b/Debug/test_coverage/PDE/MultiMat/RiemannChoice.hpp.func.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:43:41 + 2024-07-11 15:06:04 Functions: 1 diff --git a/Debug/test_coverage/PDE/MultiMat/RiemannChoice.hpp.gcov.html b/Debug/test_coverage/PDE/MultiMat/RiemannChoice.hpp.gcov.html index f136ee9192ac..1c61b91b1f0c 100644 --- a/Debug/test_coverage/PDE/MultiMat/RiemannChoice.hpp.gcov.html +++ b/Debug/test_coverage/PDE/MultiMat/RiemannChoice.hpp.gcov.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:43:41 + 2024-07-11 15:06:04 Functions: 1 diff --git a/Debug/test_coverage/PDE/MultiMat/index-sort-b.html b/Debug/test_coverage/PDE/MultiMat/index-sort-b.html index bab53ca095a4..a1779f91aef3 100644 --- a/Debug/test_coverage/PDE/MultiMat/index-sort-b.html +++ b/Debug/test_coverage/PDE/MultiMat/index-sort-b.html @@ -27,16 +27,16 @@ -128-NOTFOUND Lines: - 755 + 760 1198 - 63.0 % + 63.4 % Date: - 2024-07-10 11:43:41 + 2024-07-11 15:06:04 Functions: - 141 + 142 1252 11.3 % @@ -49,7 +49,7 @@ Branches: - 505 + 506 1574 32.1 % @@ -132,14 +132,14 @@ MiscMultiMatFns.cpp -
84.2%84.2%
+
86.1%86.1%
- 84.2 % - 224 / 266 - 80.0 % - 8 / 10 - 55.3 % - 167 / 302 + 86.1 % + 229 / 266 + 90.0 % + 9 / 10 + 55.6 % + 168 / 302 MultiMatIndexing.hpp diff --git a/Debug/test_coverage/PDE/MultiMat/index-sort-f.html b/Debug/test_coverage/PDE/MultiMat/index-sort-f.html index 869cd2791bc0..af03171f55a4 100644 --- a/Debug/test_coverage/PDE/MultiMat/index-sort-f.html +++ b/Debug/test_coverage/PDE/MultiMat/index-sort-f.html @@ -27,16 +27,16 @@ -128-NOTFOUND Lines: - 755 + 760 1198 - 63.0 % + 63.4 % Date: - 2024-07-10 11:43:41 + 2024-07-11 15:06:04 Functions: - 141 + 142 1252 11.3 % @@ -49,7 +49,7 @@ Branches: - 505 + 506 1574 32.1 % @@ -132,14 +132,14 @@ MiscMultiMatFns.cpp -
84.2%84.2%
+
86.1%86.1%
- 84.2 % - 224 / 266 - 80.0 % - 8 / 10 - 55.3 % - 167 / 302 + 86.1 % + 229 / 266 + 90.0 % + 9 / 10 + 55.6 % + 168 / 302 RiemannChoice.hpp diff --git a/Debug/test_coverage/PDE/MultiMat/index-sort-l.html b/Debug/test_coverage/PDE/MultiMat/index-sort-l.html index 4ab9ec148565..1039cfdf5b2e 100644 --- a/Debug/test_coverage/PDE/MultiMat/index-sort-l.html +++ b/Debug/test_coverage/PDE/MultiMat/index-sort-l.html @@ -27,16 +27,16 @@ -128-NOTFOUND Lines: - 755 + 760 1198 - 63.0 % + 63.4 % Date: - 2024-07-10 11:43:41 + 2024-07-11 15:06:04 Functions: - 141 + 142 1252 11.3 % @@ -49,7 +49,7 @@ Branches: - 505 + 506 1574 32.1 % @@ -144,14 +144,14 @@ MiscMultiMatFns.cpp -
84.2%84.2%
+
86.1%86.1%
- 84.2 % - 224 / 266 - 80.0 % - 8 / 10 - 55.3 % - 167 / 302 + 86.1 % + 229 / 266 + 90.0 % + 9 / 10 + 55.6 % + 168 / 302 diff --git a/Debug/test_coverage/PDE/MultiMat/index.html b/Debug/test_coverage/PDE/MultiMat/index.html index 664d6fc9cdca..206a9ad80077 100644 --- a/Debug/test_coverage/PDE/MultiMat/index.html +++ b/Debug/test_coverage/PDE/MultiMat/index.html @@ -27,16 +27,16 @@ -128-NOTFOUND Lines: - 755 + 760 1198 - 63.0 % + 63.4 % Date: - 2024-07-10 11:43:41 + 2024-07-11 15:06:04 Functions: - 141 + 142 1252 11.3 % @@ -49,7 +49,7 @@ Branches: - 505 + 506 1574 32.1 % @@ -120,14 +120,14 @@ MiscMultiMatFns.cpp -
84.2%84.2%
+
86.1%86.1%
- 84.2 % - 224 / 266 - 80.0 % - 8 / 10 - 55.3 % - 167 / 302 + 86.1 % + 229 / 266 + 90.0 % + 9 / 10 + 55.6 % + 168 / 302 MultiMatIndexing.hpp diff --git a/Debug/test_coverage/PDE/PDEFactory.hpp.func-sort-c.html b/Debug/test_coverage/PDE/PDEFactory.hpp.func-sort-c.html index 00c5a35ac9f7..682532fcbae6 100644 --- a/Debug/test_coverage/PDE/PDEFactory.hpp.func-sort-c.html +++ b/Debug/test_coverage/PDE/PDEFactory.hpp.func-sort-c.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:43:41 + 2024-07-11 15:06:04 Functions: 100 diff --git a/Debug/test_coverage/PDE/PDEFactory.hpp.func.html b/Debug/test_coverage/PDE/PDEFactory.hpp.func.html index 2ae4973a976e..5110b2932c14 100644 --- a/Debug/test_coverage/PDE/PDEFactory.hpp.func.html +++ b/Debug/test_coverage/PDE/PDEFactory.hpp.func.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:43:41 + 2024-07-11 15:06:04 Functions: 100 diff --git a/Debug/test_coverage/PDE/PDEFactory.hpp.gcov.html b/Debug/test_coverage/PDE/PDEFactory.hpp.gcov.html index 5b2c01061444..47ffe7f448b6 100644 --- a/Debug/test_coverage/PDE/PDEFactory.hpp.gcov.html +++ b/Debug/test_coverage/PDE/PDEFactory.hpp.gcov.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:43:41 + 2024-07-11 15:06:04 Functions: 100 diff --git a/Debug/test_coverage/PDE/PDEStack.cpp.func-sort-c.html b/Debug/test_coverage/PDE/PDEStack.cpp.func-sort-c.html index ba982bc61e77..3c53954be1eb 100644 --- a/Debug/test_coverage/PDE/PDEStack.cpp.func-sort-c.html +++ b/Debug/test_coverage/PDE/PDEStack.cpp.func-sort-c.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:43:41 + 2024-07-11 15:06:04 Functions: 5 diff --git a/Debug/test_coverage/PDE/PDEStack.cpp.func.html b/Debug/test_coverage/PDE/PDEStack.cpp.func.html index fe27ea19609f..3e9d00ff39fe 100644 --- a/Debug/test_coverage/PDE/PDEStack.cpp.func.html +++ b/Debug/test_coverage/PDE/PDEStack.cpp.func.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:43:41 + 2024-07-11 15:06:04 Functions: 5 diff --git a/Debug/test_coverage/PDE/PDEStack.cpp.gcov.html b/Debug/test_coverage/PDE/PDEStack.cpp.gcov.html index f09d188fe2a1..8b08713e5070 100644 --- a/Debug/test_coverage/PDE/PDEStack.cpp.gcov.html +++ b/Debug/test_coverage/PDE/PDEStack.cpp.gcov.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:43:41 + 2024-07-11 15:06:04 Functions: 5 diff --git a/Debug/test_coverage/PDE/PDEStack.hpp.func-sort-c.html b/Debug/test_coverage/PDE/PDEStack.hpp.func-sort-c.html index a35b6d15e0ff..5f6856c7aeef 100644 --- a/Debug/test_coverage/PDE/PDEStack.hpp.func-sort-c.html +++ b/Debug/test_coverage/PDE/PDEStack.hpp.func-sort-c.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:43:41 + 2024-07-11 15:06:04 Functions: 18 diff --git a/Debug/test_coverage/PDE/PDEStack.hpp.func.html b/Debug/test_coverage/PDE/PDEStack.hpp.func.html index b419af802ad4..cb4a1b19dd07 100644 --- a/Debug/test_coverage/PDE/PDEStack.hpp.func.html +++ b/Debug/test_coverage/PDE/PDEStack.hpp.func.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:43:41 + 2024-07-11 15:06:04 Functions: 18 diff --git a/Debug/test_coverage/PDE/PDEStack.hpp.gcov.html b/Debug/test_coverage/PDE/PDEStack.hpp.gcov.html index 38d8932c49b9..7d11a2b75ba5 100644 --- a/Debug/test_coverage/PDE/PDEStack.hpp.gcov.html +++ b/Debug/test_coverage/PDE/PDEStack.hpp.gcov.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:43:41 + 2024-07-11 15:06:04 Functions: 18 diff --git a/Debug/test_coverage/PDE/PrefIndicator.cpp.func-sort-c.html b/Debug/test_coverage/PDE/PrefIndicator.cpp.func-sort-c.html index 36106188b4be..33ba6dcb4bb6 100644 --- a/Debug/test_coverage/PDE/PrefIndicator.cpp.func-sort-c.html +++ b/Debug/test_coverage/PDE/PrefIndicator.cpp.func-sort-c.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:43:41 + 2024-07-11 15:06:04 Functions: 2 diff --git a/Debug/test_coverage/PDE/PrefIndicator.cpp.func.html b/Debug/test_coverage/PDE/PrefIndicator.cpp.func.html index 643005c5d553..65ddebf48f62 100644 --- a/Debug/test_coverage/PDE/PrefIndicator.cpp.func.html +++ b/Debug/test_coverage/PDE/PrefIndicator.cpp.func.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:43:41 + 2024-07-11 15:06:04 Functions: 2 diff --git a/Debug/test_coverage/PDE/PrefIndicator.cpp.gcov.html b/Debug/test_coverage/PDE/PrefIndicator.cpp.gcov.html index 9faeff5a5197..e558f0159beb 100644 --- a/Debug/test_coverage/PDE/PrefIndicator.cpp.gcov.html +++ b/Debug/test_coverage/PDE/PrefIndicator.cpp.gcov.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:43:41 + 2024-07-11 15:06:04 Functions: 2 diff --git a/Debug/test_coverage/PDE/Reconstruction.cpp.func-sort-c.html b/Debug/test_coverage/PDE/Reconstruction.cpp.func-sort-c.html index 7fbd9daba40a..8b14478158fe 100644 --- a/Debug/test_coverage/PDE/Reconstruction.cpp.func-sort-c.html +++ b/Debug/test_coverage/PDE/Reconstruction.cpp.func-sort-c.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:43:41 + 2024-07-11 15:06:04 Functions: 11 diff --git a/Debug/test_coverage/PDE/Reconstruction.cpp.func.html b/Debug/test_coverage/PDE/Reconstruction.cpp.func.html index 8bad3aec5e3a..08e017debbaf 100644 --- a/Debug/test_coverage/PDE/Reconstruction.cpp.func.html +++ b/Debug/test_coverage/PDE/Reconstruction.cpp.func.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:43:41 + 2024-07-11 15:06:04 Functions: 11 diff --git a/Debug/test_coverage/PDE/Reconstruction.cpp.gcov.html b/Debug/test_coverage/PDE/Reconstruction.cpp.gcov.html index e0cf412aac35..d0815895f190 100644 --- a/Debug/test_coverage/PDE/Reconstruction.cpp.gcov.html +++ b/Debug/test_coverage/PDE/Reconstruction.cpp.gcov.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:43:41 + 2024-07-11 15:06:04 Functions: 11 diff --git a/Debug/test_coverage/PDE/Riemann/AUSM.hpp.func-sort-c.html b/Debug/test_coverage/PDE/Riemann/AUSM.hpp.func-sort-c.html index be4e07e4f614..ce4da054d859 100644 --- a/Debug/test_coverage/PDE/Riemann/AUSM.hpp.func-sort-c.html +++ b/Debug/test_coverage/PDE/Riemann/AUSM.hpp.func-sort-c.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:43:41 + 2024-07-11 15:06:04 Functions: 2 diff --git a/Debug/test_coverage/PDE/Riemann/AUSM.hpp.func.html b/Debug/test_coverage/PDE/Riemann/AUSM.hpp.func.html index 607b3fe668aa..08764ecf88a5 100644 --- a/Debug/test_coverage/PDE/Riemann/AUSM.hpp.func.html +++ b/Debug/test_coverage/PDE/Riemann/AUSM.hpp.func.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:43:41 + 2024-07-11 15:06:04 Functions: 2 diff --git a/Debug/test_coverage/PDE/Riemann/AUSM.hpp.gcov.html b/Debug/test_coverage/PDE/Riemann/AUSM.hpp.gcov.html index 0048b1dcba1d..7f22db6e14ec 100644 --- a/Debug/test_coverage/PDE/Riemann/AUSM.hpp.gcov.html +++ b/Debug/test_coverage/PDE/Riemann/AUSM.hpp.gcov.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:43:41 + 2024-07-11 15:06:04 Functions: 2 @@ -230,20 +230,20 @@ 156 : 8054891 : l_minus = l_minus/( std::fabs(vriem) + 1.0e-12 ); 157 : : 158 : : // Store Riemann-advected partial pressures - 159 [ + + ]: 8054891 : if (std::fabs(l_plus) > 1.0e-10) + 159 [ + + ]: 8054891 : if (std::fabs(l_plus) > 1.0e-10) 160 : : { - 161 [ + + ]: 9029606 : for (std::size_t k=0; k<nmat; ++k) - 162 [ + - ]: 6357799 : flx.push_back( pml[k] ); + 161 [ + + ]: 9068992 : for (std::size_t k=0; k<nmat; ++k) + 162 [ + - ]: 6385307 : flx.push_back( pml[k] ); 163 : : } - 164 [ + + ]: 5383084 : else if (std::fabs(l_minus) > 1.0e-10) + 164 [ + + ]: 5371206 : else if (std::fabs(l_minus) > 1.0e-10) 165 : : { - 166 [ + + ]: 9107412 : for (std::size_t k=0; k<nmat; ++k) - 167 [ + - ]: 6420177 : flx.push_back( pmr[k] ); + 166 [ + + ]: 9057126 : for (std::size_t k=0; k<nmat; ++k) + 167 [ + - ]: 6385362 : flx.push_back( pmr[k] ); 168 : : } 169 : : else 170 : : { - 171 [ + + ]: 8722721 : for (std::size_t k=0; k<nmat; ++k) - 172 [ + - ]: 6026872 : flx.push_back( 0.5*(pml[k] + pmr[k]) ); + 171 [ + + ]: 8733621 : for (std::size_t k=0; k<nmat; ++k) + 172 [ + - ]: 6034179 : flx.push_back( 0.5*(pml[k] + pmr[k]) ); 173 : : } 174 : : 175 : : // Store Riemann velocity diff --git a/Debug/test_coverage/PDE/Riemann/HLL.hpp.func-sort-c.html b/Debug/test_coverage/PDE/Riemann/HLL.hpp.func-sort-c.html index bbd5ef8d0f7f..2871b2430119 100644 --- a/Debug/test_coverage/PDE/Riemann/HLL.hpp.func-sort-c.html +++ b/Debug/test_coverage/PDE/Riemann/HLL.hpp.func-sort-c.html @@ -27,13 +27,13 @@ -128-NOTFOUND Lines: - 67 - 75 - 89.3 % + 91 + 111 + 82.0 % Date: - 2024-07-10 11:43:41 + 2024-07-11 15:06:04 Functions: 1 @@ -52,9 +52,9 @@ Branches: - 26 - 52 - 50.0 % + 56 + 110 + 50.9 % diff --git a/Debug/test_coverage/PDE/Riemann/HLL.hpp.func.html b/Debug/test_coverage/PDE/Riemann/HLL.hpp.func.html index 2394288d4242..e6f6982c72cd 100644 --- a/Debug/test_coverage/PDE/Riemann/HLL.hpp.func.html +++ b/Debug/test_coverage/PDE/Riemann/HLL.hpp.func.html @@ -27,13 +27,13 @@ -128-NOTFOUND Lines: - 67 - 75 - 89.3 % + 91 + 111 + 82.0 % Date: - 2024-07-10 11:43:41 + 2024-07-11 15:06:04 Functions: 1 @@ -52,9 +52,9 @@ Branches: - 26 - 52 - 50.0 % + 56 + 110 + 50.9 % diff --git a/Debug/test_coverage/PDE/Riemann/HLL.hpp.gcov.html b/Debug/test_coverage/PDE/Riemann/HLL.hpp.gcov.html index 251e1fbdfa43..768cc830b094 100644 --- a/Debug/test_coverage/PDE/Riemann/HLL.hpp.gcov.html +++ b/Debug/test_coverage/PDE/Riemann/HLL.hpp.gcov.html @@ -27,13 +27,13 @@ -128-NOTFOUND Lines: - 67 - 75 - 89.3 % + 91 + 111 + 82.0 % Date: - 2024-07-10 11:43:41 + 2024-07-11 15:06:04 Functions: 1 @@ -52,9 +52,9 @@ Branches: - 26 - 52 - 50.0 % + 56 + 110 + 50.9 % @@ -112,134 +112,210 @@ 38 : : const std::vector< std::array< tk::real, 3 > >& ) 39 : : { 40 : 171500 : auto nmat = g_inputdeck.get< tag::multimat, tag::nmat >(); - 41 : : - 42 : 171500 : auto ncomp = u[0].size()-(3+nmat); - 43 [ + - ][ + - ]: 343000 : std::vector< tk::real > flx(ncomp, 0), fl(ncomp, 0), fr(ncomp, 0); + 41 : 171500 : const auto& solidx = g_inputdeck.get< tag::matidxmap, tag::solidx >(); + 42 : : + 43 [ + - ]: 171500 : auto nsld = numSolids(nmat, solidx); + 44 : 171500 : auto ncomp = u[0].size()-(3+nmat+nsld*6); + 45 [ + - ][ + - ]: 343000 : std::vector< tk::real > flx(ncomp, 0), fl(ncomp, 0), fr(ncomp, 0); [ + - ] - 44 : : - 45 : : // Primitive quantities - 46 : 171500 : tk::real rhol(0.0), rhor(0.0); - 47 : 171500 : tk::real pl(0.0), pr(0.0), amatl(0.0), amatr(0.0), ac_l(0.0), ac_r(0.0); - 48 [ + - ][ + - ]: 343000 : std::vector< tk::real > al_l(nmat, 0.0), al_r(nmat, 0.0), - 49 [ + - ][ + - ]: 343000 : hml(nmat, 0.0), hmr(nmat, 0.0), - 50 [ + - ][ + - ]: 343000 : pml(nmat, 0.0), pmr(nmat, 0.0); - 51 [ + + ]: 514500 : for (std::size_t k=0; k<nmat; ++k) - 52 : : { - 53 : 343000 : al_l[k] = u[0][volfracIdx(nmat, k)]; - 54 : 343000 : pml[k] = u[0][ncomp+pressureIdx(nmat, k)]; - 55 : 343000 : pl += pml[k]; - 56 : 343000 : hml[k] = u[0][energyIdx(nmat, k)] + pml[k]; - 57 [ + - ]: 686000 : amatl = mat_blk[k].compute< EOS::soundspeed >( - 58 : 343000 : u[0][densityIdx(nmat, k)], pml[k], al_l[k], k ); - 59 : 343000 : rhol += u[0][densityIdx(nmat, k)]; - 60 : : - 61 : 343000 : al_r[k] = u[1][volfracIdx(nmat, k)]; - 62 : 343000 : pmr[k] = u[1][ncomp+pressureIdx(nmat, k)]; - 63 : 343000 : pr += pmr[k]; - 64 : 343000 : hmr[k] = u[1][energyIdx(nmat, k)] + pmr[k]; - 65 [ + - ]: 686000 : amatr = mat_blk[k].compute< EOS::soundspeed >( - 66 : 343000 : u[1][densityIdx(nmat, k)], pmr[k], al_r[k], k ); - 67 : 343000 : rhor += u[1][densityIdx(nmat, k)]; - 68 : : - 69 : : // Mixture speed of sound - 70 : 343000 : ac_l += u[0][densityIdx(nmat, k)] * amatl * amatl; - 71 : 343000 : ac_r += u[1][densityIdx(nmat, k)] * amatr * amatr; - 72 : : } - 73 : : - 74 : 171500 : ac_l = std::sqrt(ac_l/rhol); - 75 : 171500 : ac_r = std::sqrt(ac_r/rhor); - 76 : : - 77 : : // Independently limited velocities for advection - 78 : 171500 : auto ul = u[0][ncomp+velocityIdx(nmat, 0)]; - 79 : 171500 : auto vl = u[0][ncomp+velocityIdx(nmat, 1)]; - 80 : 171500 : auto wl = u[0][ncomp+velocityIdx(nmat, 2)]; - 81 : 171500 : auto ur = u[1][ncomp+velocityIdx(nmat, 0)]; - 82 : 171500 : auto vr = u[1][ncomp+velocityIdx(nmat, 1)]; - 83 : 171500 : auto wr = u[1][ncomp+velocityIdx(nmat, 2)]; - 84 : : - 85 : : // Face-normal velocities from advective velocities - 86 : 171500 : auto vnl = ul*fn[0] + vl*fn[1] + wl*fn[2]; - 87 : 171500 : auto vnr = ur*fn[0] + vr*fn[1] + wr*fn[2]; - 88 : : - 89 : : // Flux functions - 90 [ + + ]: 514500 : for (std::size_t k=0; k<nmat; ++k) - 91 : : { - 92 : 343000 : fl[volfracIdx(nmat, k)] = vnl * al_l[k]; - 93 : 343000 : fl[densityIdx(nmat, k)] = vnl * u[0][densityIdx(nmat, k)]; - 94 : 343000 : fl[energyIdx(nmat, k)] = vnl * hml[k]; + 46 : : + 47 : : // Primitive quantities + 48 : 171500 : tk::real rhol(0.0), rhor(0.0); + 49 : 171500 : tk::real amatl(0.0), amatr(0.0), ac_l(0.0), ac_r(0.0); + 50 [ + - ][ + - ]: 343000 : std::vector< tk::real > al_l(nmat, 0.0), al_r(nmat, 0.0), + 51 [ + - ][ + - ]: 343000 : pml(nmat, 0.0), pmr(nmat, 0.0); + 52 : 343000 : std::vector< std::array< std::array< tk::real, 3 >, 3 > > g_l, g_r, + 53 : 343000 : asig_l, asig_r; + 54 : 343000 : std::vector< std::array< tk::real, 3 > > asign_l, asign_r; + 55 : 343000 : std::vector< std::array< std::array< tk::real, 3 >, 3 > > gn_l, gn_r; + 56 : 171500 : std::array< tk::real, 3 > sign_l {{0, 0, 0}}, sign_r {{0, 0, 0}}; + 57 [ + + ]: 514500 : for (std::size_t k=0; k<nmat; ++k) + 58 : : { + 59 : : // Left state + 60 : : // ----------------------------------------------------------------------- + 61 : 343000 : al_l[k] = u[0][volfracIdx(nmat, k)]; + 62 : 343000 : pml[k] = u[0][ncomp+pressureIdx(nmat, k)]; + 63 : 343000 : rhol += u[0][densityIdx(nmat, k)]; + 64 : : + 65 : : // inv deformation gradient and Cauchy stress tensors + 66 [ + - ][ + - ]: 343000 : g_l.push_back(getDeformGrad(nmat, k, u[0])); + 67 [ + - ][ + - ]: 343000 : asig_l.push_back(getCauchyStress(nmat, k, ncomp, u[0])); + 68 [ + + ]: 1372000 : for (std::size_t i=0; i<3; ++i) asig_l[k][i][i] -= pml[k]; + 69 : : + 70 : : // normal stress (traction) vector + 71 [ + - ]: 343000 : asign_l.push_back(tk::matvec(asig_l[k], fn)); + 72 [ + + ]: 1372000 : for (std::size_t i=0; i<3; ++i) + 73 : 1029000 : sign_l[i] += asign_l[k][i]; + 74 : : + 75 : : // rotate deformation gradient tensor for speed of sound in normal dir + 76 [ + - ][ + - ]: 343000 : gn_l.push_back(tk::rotateTensor(g_l[k], fn)); + 77 [ + - ]: 686000 : amatl = mat_blk[k].compute< EOS::soundspeed >( + 78 : 343000 : u[0][densityIdx(nmat, k)], pml[k], al_l[k], k, gn_l[k] ); + 79 : : + 80 : : // Right state + 81 : : // ----------------------------------------------------------------------- + 82 : 343000 : al_r[k] = u[1][volfracIdx(nmat, k)]; + 83 : 343000 : pmr[k] = u[1][ncomp+pressureIdx(nmat, k)]; + 84 : 343000 : rhor += u[1][densityIdx(nmat, k)]; + 85 : : + 86 : : // inv deformation gradient and Cauchy stress tensors + 87 [ + - ][ + - ]: 343000 : g_r.push_back(getDeformGrad(nmat, k, u[1])); + 88 [ + - ][ + - ]: 343000 : asig_r.push_back(getCauchyStress(nmat, k, ncomp, u[1])); + 89 [ + + ]: 1372000 : for (std::size_t i=0; i<3; ++i) asig_r[k][i][i] -= pmr[k]; + 90 : : + 91 : : // normal stress (traction) vector + 92 [ + - ]: 343000 : asign_r.push_back(tk::matvec(asig_r[k], fn)); + 93 [ + + ]: 1372000 : for (std::size_t i=0; i<3; ++i) + 94 : 1029000 : sign_r[i] += asign_r[k][i]; 95 : : - 96 : 343000 : fr[volfracIdx(nmat, k)] = vnr * al_r[k]; - 97 : 343000 : fr[densityIdx(nmat, k)] = vnr * u[1][densityIdx(nmat, k)]; - 98 : 343000 : fr[energyIdx(nmat, k)] = vnr * hmr[k]; - 99 : : } + 96 : : // rotate deformation gradient tensor for speed of sound in normal dir + 97 [ + - ][ + - ]: 343000 : gn_r.push_back(tk::rotateTensor(g_r[k], fn)); + 98 [ + - ]: 686000 : amatr = mat_blk[k].compute< EOS::soundspeed >( + 99 : 343000 : u[1][densityIdx(nmat, k)], pmr[k], al_r[k], k, gn_r[k] ); 100 : : - 101 [ + + ]: 686000 : for (std::size_t idir=0; idir<3; ++idir) - 102 : : { - 103 : 1029000 : fl[momentumIdx(nmat, idir)] = vnl * u[0][momentumIdx(nmat, idir)] - 104 : 514500 : + pl*fn[idir]; - 105 : : - 106 : 1029000 : fr[momentumIdx(nmat, idir)] = vnr * u[1][momentumIdx(nmat, idir)] - 107 : 514500 : + pr*fn[idir]; - 108 : : } + 101 : : // Mixture speed of sound + 102 : : // ----------------------------------------------------------------------- + 103 : 343000 : ac_l += u[0][densityIdx(nmat, k)] * amatl * amatl; + 104 : 343000 : ac_r += u[1][densityIdx(nmat, k)] * amatr * amatr; + 105 : : } + 106 : : + 107 : 171500 : ac_l = std::sqrt(ac_l/rhol); + 108 : 171500 : ac_r = std::sqrt(ac_r/rhor); 109 : : - 110 : : // Signal velocities - 111 : 171500 : auto Sl = std::min((vnl-ac_l), (vnr-ac_r)); - 112 : 171500 : auto Sr = std::max((vnl+ac_l), (vnr+ac_r)); - 113 : : - 114 : : // Numerical flux functions and wave-speeds - 115 : 171500 : auto c_plus(0.0), c_minus(0.0), p_plus(0.0), p_minus(0.0); - 116 [ - + ]: 171500 : if (Sl >= 0.0) - 117 : : { - 118 [ - - ]: 0 : for (std::size_t k=0; k<flx.size(); ++k) - 119 : 0 : flx[k] = fl[k]; - 120 : 0 : c_plus = vnl; - 121 : 0 : p_plus = vnl; - 122 : : } - 123 [ - + ]: 171500 : else if (Sr <= 0.0) - 124 : : { - 125 [ - - ]: 0 : for (std::size_t k=0; k<flx.size(); ++k) - 126 : 0 : flx[k] = fr[k]; - 127 : 0 : c_minus = vnr; - 128 : 0 : p_minus = vnr; - 129 : : } - 130 : : else - 131 : : { - 132 [ + + ]: 1715000 : for (std::size_t k=0; k<flx.size(); ++k) - 133 : 1543500 : flx[k] = (Sr*fl[k] - Sl*fr[k] + Sl*Sr*(u[1][k]-u[0][k])) / (Sr-Sl); - 134 : 171500 : c_plus = (Sr*vnl - Sr*Sl) / (Sr-Sl); - 135 : 171500 : c_minus = (Sr*Sl - Sl*vnr) / (Sr-Sl); - 136 : 171500 : p_plus = Sr * vnl / (Sr-Sl); - 137 : 171500 : p_minus = -Sl * vnr / (Sr-Sl); - 138 : : } - 139 : : - 140 : 171500 : auto vriem = c_plus+c_minus; - 141 : : - 142 : 171500 : p_plus = p_plus/( vriem + std::copysign(1.0e-16,vriem) ); - 143 : 171500 : p_minus = p_minus/( vriem + std::copysign(1.0e-16,vriem) ); + 110 : : // Independently limited velocities for advection + 111 : 171500 : auto ul = u[0][ncomp+velocityIdx(nmat, 0)]; + 112 : 171500 : auto vl = u[0][ncomp+velocityIdx(nmat, 1)]; + 113 : 171500 : auto wl = u[0][ncomp+velocityIdx(nmat, 2)]; + 114 : 171500 : auto ur = u[1][ncomp+velocityIdx(nmat, 0)]; + 115 : 171500 : auto vr = u[1][ncomp+velocityIdx(nmat, 1)]; + 116 : 171500 : auto wr = u[1][ncomp+velocityIdx(nmat, 2)]; + 117 : : + 118 : : // Face-normal velocities from advective velocities + 119 : 171500 : auto vnl = ul*fn[0] + vl*fn[1] + wl*fn[2]; + 120 : 171500 : auto vnr = ur*fn[0] + vr*fn[1] + wr*fn[2]; + 121 : : + 122 : : // Conservative flux functions + 123 : : // ------------------------------------------------------------------------- + 124 [ + + ]: 514500 : for (std::size_t k=0; k<nmat; ++k) + 125 : : { + 126 : : // Left fluxes + 127 : 343000 : fl[volfracIdx(nmat, k)] = vnl * al_l[k]; + 128 : 343000 : fl[densityIdx(nmat, k)] = vnl * u[0][densityIdx(nmat, k)]; + 129 : 343000 : fl[energyIdx(nmat, k)] = vnl * u[0][energyIdx(nmat, k)]; + 130 [ + + ]: 1372000 : for (std::size_t i=0; i<3; ++i) { + 131 : 2058000 : fl[energyIdx(nmat, k)] -= u[0][ncomp+velocityIdx(nmat,i)] * + 132 : 1029000 : asign_l[k][i]; + 133 : : } + 134 : : + 135 : : // inv deformation gradient tensor + 136 [ - + ]: 343000 : if (solidx[k] > 0) { + 137 [ - - ]: 0 : for (std::size_t i=0; i<3; ++i) + 138 [ - - ]: 0 : for (std::size_t j=0; j<3; ++j) + 139 : 0 : fl[deformIdx(nmat,solidx[k],i,j)] = ( + 140 : 0 : g_l[k][i][0] * ul + + 141 : 0 : g_l[k][i][1] * vl + + 142 : 0 : g_l[k][i][2] * wl ) * fn[j]; + 143 : : } 144 : : - 145 : : // Store Riemann-advected partial pressures - 146 [ + + ]: 514500 : for (std::size_t k=0; k<nmat; ++k) - 147 [ + - ]: 343000 : flx.push_back(p_plus*pml[k] + p_minus*pmr[k]); - 148 : : - 149 : : // Store Riemann velocity - 150 [ + - ]: 171500 : flx.push_back( vriem ); - 151 : : - 152 [ - + ][ - - ]: 171500 : Assert( flx.size() == (3*nmat+3+nmat+1), "Size of multi-material flux " + 145 : : // Right fluxes + 146 : 343000 : fr[volfracIdx(nmat, k)] = vnr * al_r[k]; + 147 : 343000 : fr[densityIdx(nmat, k)] = vnr * u[1][densityIdx(nmat, k)]; + 148 : 343000 : fr[energyIdx(nmat, k)] = vnr * u[1][energyIdx(nmat, k)]; + 149 [ + + ]: 1372000 : for (std::size_t i=0; i<3; ++i) { + 150 : 2058000 : fr[energyIdx(nmat, k)] -= u[1][ncomp+velocityIdx(nmat,i)] * + 151 : 1029000 : asign_r[k][i]; + 152 : : } + 153 : : + 154 : : // inv deformation gradient tensor + 155 [ - + ]: 343000 : if (solidx[k] > 0) { + 156 [ - - ]: 0 : for (std::size_t i=0; i<3; ++i) + 157 [ - - ]: 0 : for (std::size_t j=0; j<3; ++j) + 158 : 0 : fr[deformIdx(nmat,solidx[k],i,j)] = ( + 159 : 0 : g_r[k][i][0] * ur + + 160 : 0 : g_r[k][i][1] * vr + + 161 : 0 : g_r[k][i][2] * wr ) * fn[j]; + 162 : : } + 163 : : } + 164 : : + 165 : : // bulk momentum + 166 [ + + ]: 686000 : for (std::size_t idir=0; idir<3; ++idir) + 167 : : { + 168 : 1029000 : fl[momentumIdx(nmat, idir)] = vnl*u[0][momentumIdx(nmat, idir)] + 169 : 514500 : - sign_l[idir]; + 170 : 1029000 : fr[momentumIdx(nmat, idir)] = vnr*u[1][momentumIdx(nmat, idir)] + 171 : 514500 : - sign_r[idir]; + 172 : : } + 173 : : + 174 : : // Numerical fluxes + 175 : : // ------------------------------------------------------------------------- + 176 : : + 177 : : // Signal velocities + 178 : 171500 : auto Sl = std::min((vnl-ac_l), (vnr-ac_r)); + 179 : 171500 : auto Sr = std::max((vnl+ac_l), (vnr+ac_r)); + 180 : : //// Signal velocities by Einfeldt (HLLE) + 181 : : //auto Sl = std::min( 0.0, std::min((vnl-ac_l), 0.5*((vnl+vnr)-(ac_l+ac_r))) ); + 182 : : //auto Sr = std::max( 0.0, std::max((vnr+ac_r), 0.5*((vnl+vnr)+(ac_l+ac_r))) ); + 183 : : + 184 : : // Numerical flux functions and wave-speeds + 185 : 171500 : auto c_plus(0.0), c_minus(0.0), p_plus(0.0), p_minus(0.0); + 186 [ - + ]: 171500 : if (Sl >= 0.0) + 187 : : { + 188 [ - - ]: 0 : flx = fl; + 189 : 0 : c_plus = vnl; + 190 : 0 : p_plus = 1.0; + 191 : : } + 192 [ - + ]: 171500 : else if (Sr <= 0.0) + 193 : : { + 194 [ - - ]: 0 : flx = fr; + 195 : 0 : c_minus = vnr; + 196 : 0 : p_minus = 1.0; + 197 : : } + 198 : : else + 199 : : { + 200 [ + + ]: 1715000 : for (std::size_t k=0; k<flx.size(); ++k) + 201 : 1543500 : flx[k] = (Sr*fl[k] - Sl*fr[k] + Sl*Sr*(u[1][k]-u[0][k])) / (Sr-Sl); + 202 : 171500 : c_plus = (Sr*vnl - Sr*Sl) / (Sr-Sl); + 203 : 171500 : c_minus = (Sr*Sl - Sl*vnr) / (Sr-Sl); + 204 : 171500 : p_plus = Sr / (Sr-Sl); + 205 : 171500 : p_minus = -Sl / (Sr-Sl); + 206 : : } + 207 : : + 208 : : // Quantities for non-conservative terms + 209 : : // ------------------------------------------------------------------------- + 210 : : + 211 : 171500 : auto vriem = c_plus+c_minus; + 212 : : + 213 : : // Store Riemann-advected partial pressures + 214 [ + + ]: 514500 : for (std::size_t k=0; k<nmat; ++k) + 215 [ + - ]: 343000 : flx.push_back(p_plus*pml[k] + p_minus*pmr[k]); + 216 : : + 217 : : // Store Riemann velocity + 218 [ + - ]: 171500 : flx.push_back( vriem ); + 219 : : + 220 : : // Store Riemann asign_ij (3*nsld) + 221 [ + + ]: 514500 : for (std::size_t k=0; k<nmat; ++k) { + 222 [ - + ]: 343000 : if (solidx[k] > 0) { + 223 [ - - ]: 0 : for (std::size_t i=0; i<3; ++i) + 224 [ - - ]: 0 : flx.push_back(p_plus*asign_l[k][i] + p_minus*asign_r[k][i]); + 225 : : } + 226 : : } + 227 : : + 228 [ - + ][ - - ]: 171500 : Assert( flx.size() == (ncomp+nmat+1+3*nsld), "Size of " [ - - ][ - - ] - 153 : : "vector incorrect" ); - 154 : : - 155 : 343000 : return flx; - 156 : : } - 157 : : - 158 : : //! Flux type accessor - 159 : : //! \return Flux type - 160 : : static ctr::FluxType type() noexcept { return ctr::FluxType::HLL; } - 161 : : - 162 : : }; - 163 : : - 164 : : } // inciter:: - 165 : : - 166 : : #endif // HLL_h + 229 : : "multi-material flux vector incorrect" ); + 230 : : + 231 : 343000 : return flx; + 232 : : } + 233 : : + 234 : : //! Flux type accessor + 235 : : //! \return Flux type + 236 : : static ctr::FluxType type() noexcept { return ctr::FluxType::HLL; } + 237 : : + 238 : : }; + 239 : : + 240 : : } // inciter:: + 241 : : + 242 : : #endif // HLL_h diff --git a/Debug/test_coverage/PDE/Riemann/HLLC.hpp.func-sort-c.html b/Debug/test_coverage/PDE/Riemann/HLLC.hpp.func-sort-c.html index c2dabcf782dc..8a434a430f92 100644 --- a/Debug/test_coverage/PDE/Riemann/HLLC.hpp.func-sort-c.html +++ b/Debug/test_coverage/PDE/Riemann/HLLC.hpp.func-sort-c.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:43:41 + 2024-07-11 15:06:04 Functions: 1 diff --git a/Debug/test_coverage/PDE/Riemann/HLLC.hpp.func.html b/Debug/test_coverage/PDE/Riemann/HLLC.hpp.func.html index b25171827c79..e5967cc5736c 100644 --- a/Debug/test_coverage/PDE/Riemann/HLLC.hpp.func.html +++ b/Debug/test_coverage/PDE/Riemann/HLLC.hpp.func.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:43:41 + 2024-07-11 15:06:04 Functions: 1 diff --git a/Debug/test_coverage/PDE/Riemann/HLLC.hpp.gcov.html b/Debug/test_coverage/PDE/Riemann/HLLC.hpp.gcov.html index ae0dba978ff5..b7a2de2a5778 100644 --- a/Debug/test_coverage/PDE/Riemann/HLLC.hpp.gcov.html +++ b/Debug/test_coverage/PDE/Riemann/HLLC.hpp.gcov.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:43:41 + 2024-07-11 15:06:04 Functions: 1 @@ -165,33 +165,33 @@ 91 : 25431867 : uStar[1][4] = ((Sr-vnr) * u[1][4] - pr*vnr + pStar*Sm) / (Sr-Sm); 92 : : 93 : : // Numerical fluxes - 94 [ + + ]: 25431867 : if (Sl > 0.0) { - 95 : 230360 : flx[0] = u[0][0] * vnl; - 96 : 230360 : flx[1] = u[0][1] * vnl + pl*fn[0]; - 97 : 230360 : flx[2] = u[0][2] * vnl + pl*fn[1]; - 98 : 230360 : flx[3] = u[0][3] * vnl + pl*fn[2]; - 99 : 230360 : flx[4] = ( u[0][4] + pl ) * vnl; + 94 [ + + ]: 25431867 : if (Sl > 0.0) { + 95 : 231989 : flx[0] = u[0][0] * vnl; + 96 : 231989 : flx[1] = u[0][1] * vnl + pl*fn[0]; + 97 : 231989 : flx[2] = u[0][2] * vnl + pl*fn[1]; + 98 : 231989 : flx[3] = u[0][3] * vnl + pl*fn[2]; + 99 : 231989 : flx[4] = ( u[0][4] + pl ) * vnl; 100 : : } - 101 [ + - ][ + + ]: 25201507 : else if (Sl <= 0.0 && Sm > 0.0) { - 102 : 9810528 : flx[0] = uStar[0][0] * Sm; - 103 : 9810528 : flx[1] = uStar[0][1] * Sm + pStar*fn[0]; - 104 : 9810528 : flx[2] = uStar[0][2] * Sm + pStar*fn[1]; - 105 : 9810528 : flx[3] = uStar[0][3] * Sm + pStar*fn[2]; - 106 : 9810528 : flx[4] = ( uStar[0][4] + pStar ) * Sm; + 101 [ + - ][ + + ]: 25199878 : else if (Sl <= 0.0 && Sm > 0.0) { + 102 : 9809117 : flx[0] = uStar[0][0] * Sm; + 103 : 9809117 : flx[1] = uStar[0][1] * Sm + pStar*fn[0]; + 104 : 9809117 : flx[2] = uStar[0][2] * Sm + pStar*fn[1]; + 105 : 9809117 : flx[3] = uStar[0][3] * Sm + pStar*fn[2]; + 106 : 9809117 : flx[4] = ( uStar[0][4] + pStar ) * Sm; 107 : : } - 108 [ + - ][ + + ]: 15390979 : else if (Sm <= 0.0 && Sr >= 0.0) { - 109 : 15141103 : flx[0] = uStar[1][0] * Sm; - 110 : 15141103 : flx[1] = uStar[1][1] * Sm + pStar*fn[0]; - 111 : 15141103 : flx[2] = uStar[1][2] * Sm + pStar*fn[1]; - 112 : 15141103 : flx[3] = uStar[1][3] * Sm + pStar*fn[2]; - 113 : 15141103 : flx[4] = ( uStar[1][4] + pStar ) * Sm; + 108 [ + - ][ + + ]: 15390761 : else if (Sm <= 0.0 && Sr >= 0.0) { + 109 : 15142514 : flx[0] = uStar[1][0] * Sm; + 110 : 15142514 : flx[1] = uStar[1][1] * Sm + pStar*fn[0]; + 111 : 15142514 : flx[2] = uStar[1][2] * Sm + pStar*fn[1]; + 112 : 15142514 : flx[3] = uStar[1][3] * Sm + pStar*fn[2]; + 113 : 15142514 : flx[4] = ( uStar[1][4] + pStar ) * Sm; 114 : : } 115 : : else { - 116 : 249876 : flx[0] = u[1][0] * vnr; - 117 : 249876 : flx[1] = u[1][1] * vnr + pr*fn[0]; - 118 : 249876 : flx[2] = u[1][2] * vnr + pr*fn[1]; - 119 : 249876 : flx[3] = u[1][3] * vnr + pr*fn[2]; - 120 : 249876 : flx[4] = ( u[1][4] + pr ) * vnr; + 116 : 248247 : flx[0] = u[1][0] * vnr; + 117 : 248247 : flx[1] = u[1][1] * vnr + pr*fn[0]; + 118 : 248247 : flx[2] = u[1][2] * vnr + pr*fn[1]; + 119 : 248247 : flx[3] = u[1][3] * vnr + pr*fn[2]; + 120 : 248247 : flx[4] = ( u[1][4] + pr ) * vnr; 121 : : } 122 : : 123 : 50863734 : return flx; diff --git a/Debug/test_coverage/PDE/Riemann/LaxFriedrichs.hpp.func-sort-c.html b/Debug/test_coverage/PDE/Riemann/LaxFriedrichs.hpp.func-sort-c.html index a787c0aee53e..00986be76a2a 100644 --- a/Debug/test_coverage/PDE/Riemann/LaxFriedrichs.hpp.func-sort-c.html +++ b/Debug/test_coverage/PDE/Riemann/LaxFriedrichs.hpp.func-sort-c.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:43:41 + 2024-07-11 15:06:04 Functions: 1 diff --git a/Debug/test_coverage/PDE/Riemann/LaxFriedrichs.hpp.func.html b/Debug/test_coverage/PDE/Riemann/LaxFriedrichs.hpp.func.html index 1cb101709141..b7f0aabf0014 100644 --- a/Debug/test_coverage/PDE/Riemann/LaxFriedrichs.hpp.func.html +++ b/Debug/test_coverage/PDE/Riemann/LaxFriedrichs.hpp.func.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:43:41 + 2024-07-11 15:06:04 Functions: 1 diff --git a/Debug/test_coverage/PDE/Riemann/LaxFriedrichs.hpp.gcov.html b/Debug/test_coverage/PDE/Riemann/LaxFriedrichs.hpp.gcov.html index ba376c46ecb8..f24600100a35 100644 --- a/Debug/test_coverage/PDE/Riemann/LaxFriedrichs.hpp.gcov.html +++ b/Debug/test_coverage/PDE/Riemann/LaxFriedrichs.hpp.gcov.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:43:41 + 2024-07-11 15:06:04 Functions: 1 diff --git a/Debug/test_coverage/PDE/Riemann/LaxFriedrichsSolids.hpp.func-sort-c.html b/Debug/test_coverage/PDE/Riemann/LaxFriedrichsSolids.hpp.func-sort-c.html index b310391202af..48559ffd8cfb 100644 --- a/Debug/test_coverage/PDE/Riemann/LaxFriedrichsSolids.hpp.func-sort-c.html +++ b/Debug/test_coverage/PDE/Riemann/LaxFriedrichsSolids.hpp.func-sort-c.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:43:41 + 2024-07-11 15:06:04 Functions: 0 diff --git a/Debug/test_coverage/PDE/Riemann/LaxFriedrichsSolids.hpp.func.html b/Debug/test_coverage/PDE/Riemann/LaxFriedrichsSolids.hpp.func.html index c5e9a84cf385..4f0e72089bc7 100644 --- a/Debug/test_coverage/PDE/Riemann/LaxFriedrichsSolids.hpp.func.html +++ b/Debug/test_coverage/PDE/Riemann/LaxFriedrichsSolids.hpp.func.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:43:41 + 2024-07-11 15:06:04 Functions: 0 diff --git a/Debug/test_coverage/PDE/Riemann/LaxFriedrichsSolids.hpp.gcov.html b/Debug/test_coverage/PDE/Riemann/LaxFriedrichsSolids.hpp.gcov.html index ec200d2a5364..84a3ea32c58a 100644 --- a/Debug/test_coverage/PDE/Riemann/LaxFriedrichsSolids.hpp.gcov.html +++ b/Debug/test_coverage/PDE/Riemann/LaxFriedrichsSolids.hpp.gcov.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:43:41 + 2024-07-11 15:06:04 Functions: 0 diff --git a/Debug/test_coverage/PDE/Riemann/Rusanov.hpp.func-sort-c.html b/Debug/test_coverage/PDE/Riemann/Rusanov.hpp.func-sort-c.html index 002cd491e745..66269cd17f94 100644 --- a/Debug/test_coverage/PDE/Riemann/Rusanov.hpp.func-sort-c.html +++ b/Debug/test_coverage/PDE/Riemann/Rusanov.hpp.func-sort-c.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:43:41 + 2024-07-11 15:06:04 Functions: 1 diff --git a/Debug/test_coverage/PDE/Riemann/Rusanov.hpp.func.html b/Debug/test_coverage/PDE/Riemann/Rusanov.hpp.func.html index 8450485334a3..5094356fd12b 100644 --- a/Debug/test_coverage/PDE/Riemann/Rusanov.hpp.func.html +++ b/Debug/test_coverage/PDE/Riemann/Rusanov.hpp.func.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:43:41 + 2024-07-11 15:06:04 Functions: 1 diff --git a/Debug/test_coverage/PDE/Riemann/Rusanov.hpp.gcov.html b/Debug/test_coverage/PDE/Riemann/Rusanov.hpp.gcov.html index a49aa5df42ba..9783246338ef 100644 --- a/Debug/test_coverage/PDE/Riemann/Rusanov.hpp.gcov.html +++ b/Debug/test_coverage/PDE/Riemann/Rusanov.hpp.gcov.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:43:41 + 2024-07-11 15:06:04 Functions: 1 diff --git a/Debug/test_coverage/PDE/Riemann/Upwind.hpp.func-sort-c.html b/Debug/test_coverage/PDE/Riemann/Upwind.hpp.func-sort-c.html index fbec8cfeb63e..3254ea51c147 100644 --- a/Debug/test_coverage/PDE/Riemann/Upwind.hpp.func-sort-c.html +++ b/Debug/test_coverage/PDE/Riemann/Upwind.hpp.func-sort-c.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:43:41 + 2024-07-11 15:06:04 Functions: 1 diff --git a/Debug/test_coverage/PDE/Riemann/Upwind.hpp.func.html b/Debug/test_coverage/PDE/Riemann/Upwind.hpp.func.html index 3001ef3049ca..c68de679ee61 100644 --- a/Debug/test_coverage/PDE/Riemann/Upwind.hpp.func.html +++ b/Debug/test_coverage/PDE/Riemann/Upwind.hpp.func.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:43:41 + 2024-07-11 15:06:04 Functions: 1 diff --git a/Debug/test_coverage/PDE/Riemann/Upwind.hpp.gcov.html b/Debug/test_coverage/PDE/Riemann/Upwind.hpp.gcov.html index 424e6bd4bcc2..f90f3330a629 100644 --- a/Debug/test_coverage/PDE/Riemann/Upwind.hpp.gcov.html +++ b/Debug/test_coverage/PDE/Riemann/Upwind.hpp.gcov.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:43:41 + 2024-07-11 15:06:04 Functions: 1 diff --git a/Debug/test_coverage/PDE/Riemann/index-sort-b.html b/Debug/test_coverage/PDE/Riemann/index-sort-b.html index c4871625f022..9495b2189fbb 100644 --- a/Debug/test_coverage/PDE/Riemann/index-sort-b.html +++ b/Debug/test_coverage/PDE/Riemann/index-sort-b.html @@ -27,13 +27,13 @@ -128-NOTFOUND Lines: - 298 - 410 - 72.7 % + 322 + 446 + 72.2 % Date: - 2024-07-10 11:43:41 + 2024-07-11 15:06:04 Functions: 7 @@ -49,9 +49,9 @@ Branches: - 93 - 272 - 34.2 % + 123 + 330 + 37.3 % @@ -120,14 +120,14 @@ HLL.hpp -
89.3%89.3%
+
82.0%82.0%
- 89.3 % - 67 / 75 + 82.0 % + 91 / 111 100.0 % 1 / 1 - 50.0 % - 26 / 52 + 50.9 % + 56 / 110 LaxFriedrichs.hpp diff --git a/Debug/test_coverage/PDE/Riemann/index-sort-f.html b/Debug/test_coverage/PDE/Riemann/index-sort-f.html index 7c23f798346d..791ad16709ad 100644 --- a/Debug/test_coverage/PDE/Riemann/index-sort-f.html +++ b/Debug/test_coverage/PDE/Riemann/index-sort-f.html @@ -27,13 +27,13 @@ -128-NOTFOUND Lines: - 298 - 410 - 72.7 % + 322 + 446 + 72.2 % Date: - 2024-07-10 11:43:41 + 2024-07-11 15:06:04 Functions: 7 @@ -49,9 +49,9 @@ Branches: - 93 - 272 - 34.2 % + 123 + 330 + 37.3 % @@ -94,40 +94,40 @@ 0 / 106 - HLL.hpp + Rusanov.hpp -
89.3%89.3%
+
100.0%
- 89.3 % - 67 / 75 + 100.0 % + 26 / 26 100.0 % 1 / 1 50.0 % - 26 / 52 + 2 / 4 - HLLC.hpp + Upwind.hpp
100.0%
100.0 % - 62 / 62 + 9 / 9 100.0 % 1 / 1 - 63.6 % - 14 / 22 + 33.3 % + 4 / 12 - Rusanov.hpp + HLLC.hpp
100.0%
100.0 % - 26 / 26 + 62 / 62 100.0 % 1 / 1 - 50.0 % - 2 / 4 + 63.6 % + 14 / 22 LaxFriedrichs.hpp @@ -142,16 +142,16 @@ 9 / 16 - Upwind.hpp + HLL.hpp -
100.0%
+
82.0%82.0%
- 100.0 % - 9 / 9 + 82.0 % + 91 / 111 100.0 % 1 / 1 - 33.3 % - 4 / 12 + 50.9 % + 56 / 110 AUSM.hpp diff --git a/Debug/test_coverage/PDE/Riemann/index-sort-l.html b/Debug/test_coverage/PDE/Riemann/index-sort-l.html index 5fcbaa240edf..442182e81152 100644 --- a/Debug/test_coverage/PDE/Riemann/index-sort-l.html +++ b/Debug/test_coverage/PDE/Riemann/index-sort-l.html @@ -27,13 +27,13 @@ -128-NOTFOUND Lines: - 298 - 410 - 72.7 % + 322 + 446 + 72.2 % Date: - 2024-07-10 11:43:41 + 2024-07-11 15:06:04 Functions: 7 @@ -49,9 +49,9 @@ Branches: - 93 - 272 - 34.2 % + 123 + 330 + 37.3 % @@ -96,14 +96,14 @@ HLL.hpp -
89.3%89.3%
+
82.0%82.0%
- 89.3 % - 67 / 75 + 82.0 % + 91 / 111 100.0 % 1 / 1 - 50.0 % - 26 / 52 + 50.9 % + 56 / 110 Upwind.hpp diff --git a/Debug/test_coverage/PDE/Riemann/index.html b/Debug/test_coverage/PDE/Riemann/index.html index 0cf903ccb715..bd6827da8ea9 100644 --- a/Debug/test_coverage/PDE/Riemann/index.html +++ b/Debug/test_coverage/PDE/Riemann/index.html @@ -27,13 +27,13 @@ -128-NOTFOUND Lines: - 298 - 410 - 72.7 % + 322 + 446 + 72.2 % Date: - 2024-07-10 11:43:41 + 2024-07-11 15:06:04 Functions: 7 @@ -49,9 +49,9 @@ Branches: - 93 - 272 - 34.2 % + 123 + 330 + 37.3 % @@ -96,14 +96,14 @@ HLL.hpp -
89.3%89.3%
+
82.0%82.0%
- 89.3 % - 67 / 75 + 82.0 % + 91 / 111 100.0 % 1 / 1 - 50.0 % - 26 / 52 + 50.9 % + 56 / 110 HLLC.hpp diff --git a/Debug/test_coverage/PDE/Transport/CGTransport.hpp.func-sort-c.html b/Debug/test_coverage/PDE/Transport/CGTransport.hpp.func-sort-c.html index 78e1d4597ec5..ea1ccdbe78ba 100644 --- a/Debug/test_coverage/PDE/Transport/CGTransport.hpp.func-sort-c.html +++ b/Debug/test_coverage/PDE/Transport/CGTransport.hpp.func-sort-c.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:43:41 + 2024-07-11 15:06:04 Functions: 47 diff --git a/Debug/test_coverage/PDE/Transport/CGTransport.hpp.func.html b/Debug/test_coverage/PDE/Transport/CGTransport.hpp.func.html index 8d43afb458be..c6964b1c03c4 100644 --- a/Debug/test_coverage/PDE/Transport/CGTransport.hpp.func.html +++ b/Debug/test_coverage/PDE/Transport/CGTransport.hpp.func.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:43:41 + 2024-07-11 15:06:04 Functions: 47 diff --git a/Debug/test_coverage/PDE/Transport/CGTransport.hpp.gcov.html b/Debug/test_coverage/PDE/Transport/CGTransport.hpp.gcov.html index 9675818eee93..3398f93fa50c 100644 --- a/Debug/test_coverage/PDE/Transport/CGTransport.hpp.gcov.html +++ b/Debug/test_coverage/PDE/Transport/CGTransport.hpp.gcov.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:43:41 + 2024-07-11 15:06:04 Functions: 47 @@ -413,7 +413,7 @@ 333 : : // compute minimum element dt 334 : 180432 : auto elemdt = std::min( advection_dt, diffusion_dt ); 335 : : // find minimum dt across all elements - 336 [ + + ]: 180432 : if (elemdt < mindt) mindt = elemdt; + 336 [ + + ]: 180432 : if (elemdt < mindt) mindt = elemdt; 337 : : } 338 : 75 : return mindt * g_inputdeck.get< tag::cfl >(); 339 : : } diff --git a/Debug/test_coverage/PDE/Transport/DGTransport.hpp.func-sort-c.html b/Debug/test_coverage/PDE/Transport/DGTransport.hpp.func-sort-c.html index 2d89fb5f03fe..e6dc0ba9eec7 100644 --- a/Debug/test_coverage/PDE/Transport/DGTransport.hpp.func-sort-c.html +++ b/Debug/test_coverage/PDE/Transport/DGTransport.hpp.func-sort-c.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:43:41 + 2024-07-11 15:06:04 Functions: 76 diff --git a/Debug/test_coverage/PDE/Transport/DGTransport.hpp.func.html b/Debug/test_coverage/PDE/Transport/DGTransport.hpp.func.html index f0f36bb2a669..9841b4636186 100644 --- a/Debug/test_coverage/PDE/Transport/DGTransport.hpp.func.html +++ b/Debug/test_coverage/PDE/Transport/DGTransport.hpp.func.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:43:41 + 2024-07-11 15:06:04 Functions: 76 diff --git a/Debug/test_coverage/PDE/Transport/DGTransport.hpp.gcov.html b/Debug/test_coverage/PDE/Transport/DGTransport.hpp.gcov.html index 4e0696004cd6..c5879580316b 100644 --- a/Debug/test_coverage/PDE/Transport/DGTransport.hpp.gcov.html +++ b/Debug/test_coverage/PDE/Transport/DGTransport.hpp.gcov.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:43:41 + 2024-07-11 15:06:04 Functions: 76 diff --git a/Debug/test_coverage/PDE/Transport/Physics/CGAdvDiff.cpp.func-sort-c.html b/Debug/test_coverage/PDE/Transport/Physics/CGAdvDiff.cpp.func-sort-c.html index db856e096947..0941f66f15a1 100644 --- a/Debug/test_coverage/PDE/Transport/Physics/CGAdvDiff.cpp.func-sort-c.html +++ b/Debug/test_coverage/PDE/Transport/Physics/CGAdvDiff.cpp.func-sort-c.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:43:41 + 2024-07-11 15:06:04 Functions: 0 diff --git a/Debug/test_coverage/PDE/Transport/Physics/CGAdvDiff.cpp.func.html b/Debug/test_coverage/PDE/Transport/Physics/CGAdvDiff.cpp.func.html index f10932085cf6..1ffb2d796275 100644 --- a/Debug/test_coverage/PDE/Transport/Physics/CGAdvDiff.cpp.func.html +++ b/Debug/test_coverage/PDE/Transport/Physics/CGAdvDiff.cpp.func.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:43:41 + 2024-07-11 15:06:04 Functions: 0 diff --git a/Debug/test_coverage/PDE/Transport/Physics/CGAdvDiff.cpp.gcov.html b/Debug/test_coverage/PDE/Transport/Physics/CGAdvDiff.cpp.gcov.html index af3092fc9fd6..f7681faf59ed 100644 --- a/Debug/test_coverage/PDE/Transport/Physics/CGAdvDiff.cpp.gcov.html +++ b/Debug/test_coverage/PDE/Transport/Physics/CGAdvDiff.cpp.gcov.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:43:41 + 2024-07-11 15:06:04 Functions: 0 diff --git a/Debug/test_coverage/PDE/Transport/Physics/CGAdvDiff.hpp.func-sort-c.html b/Debug/test_coverage/PDE/Transport/Physics/CGAdvDiff.hpp.func-sort-c.html index 9a6f53888221..71c7fbb8abec 100644 --- a/Debug/test_coverage/PDE/Transport/Physics/CGAdvDiff.hpp.func-sort-c.html +++ b/Debug/test_coverage/PDE/Transport/Physics/CGAdvDiff.hpp.func-sort-c.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:43:41 + 2024-07-11 15:06:04 Functions: 1 diff --git a/Debug/test_coverage/PDE/Transport/Physics/CGAdvDiff.hpp.func.html b/Debug/test_coverage/PDE/Transport/Physics/CGAdvDiff.hpp.func.html index 2d8fbaa0592d..ef5560042d16 100644 --- a/Debug/test_coverage/PDE/Transport/Physics/CGAdvDiff.hpp.func.html +++ b/Debug/test_coverage/PDE/Transport/Physics/CGAdvDiff.hpp.func.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:43:41 + 2024-07-11 15:06:04 Functions: 1 diff --git a/Debug/test_coverage/PDE/Transport/Physics/CGAdvDiff.hpp.gcov.html b/Debug/test_coverage/PDE/Transport/Physics/CGAdvDiff.hpp.gcov.html index 18992fa50d21..9f1101db6482 100644 --- a/Debug/test_coverage/PDE/Transport/Physics/CGAdvDiff.hpp.gcov.html +++ b/Debug/test_coverage/PDE/Transport/Physics/CGAdvDiff.hpp.gcov.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:43:41 + 2024-07-11 15:06:04 Functions: 1 diff --git a/Debug/test_coverage/PDE/Transport/Physics/CGAdvection.hpp.func-sort-c.html b/Debug/test_coverage/PDE/Transport/Physics/CGAdvection.hpp.func-sort-c.html index 25bd519e824f..2d224c75a283 100644 --- a/Debug/test_coverage/PDE/Transport/Physics/CGAdvection.hpp.func-sort-c.html +++ b/Debug/test_coverage/PDE/Transport/Physics/CGAdvection.hpp.func-sort-c.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:43:41 + 2024-07-11 15:06:04 Functions: 2 diff --git a/Debug/test_coverage/PDE/Transport/Physics/CGAdvection.hpp.func.html b/Debug/test_coverage/PDE/Transport/Physics/CGAdvection.hpp.func.html index 9aaafd5fd8a2..ef6294bfd9e5 100644 --- a/Debug/test_coverage/PDE/Transport/Physics/CGAdvection.hpp.func.html +++ b/Debug/test_coverage/PDE/Transport/Physics/CGAdvection.hpp.func.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:43:41 + 2024-07-11 15:06:04 Functions: 2 diff --git a/Debug/test_coverage/PDE/Transport/Physics/CGAdvection.hpp.gcov.html b/Debug/test_coverage/PDE/Transport/Physics/CGAdvection.hpp.gcov.html index 3dcd85462f8a..7ee45e80466c 100644 --- a/Debug/test_coverage/PDE/Transport/Physics/CGAdvection.hpp.gcov.html +++ b/Debug/test_coverage/PDE/Transport/Physics/CGAdvection.hpp.gcov.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:43:41 + 2024-07-11 15:06:04 Functions: 2 diff --git a/Debug/test_coverage/PDE/Transport/Physics/DGAdvection.hpp.func-sort-c.html b/Debug/test_coverage/PDE/Transport/Physics/DGAdvection.hpp.func-sort-c.html index d8fc4ac2db6b..bd601997eae8 100644 --- a/Debug/test_coverage/PDE/Transport/Physics/DGAdvection.hpp.func-sort-c.html +++ b/Debug/test_coverage/PDE/Transport/Physics/DGAdvection.hpp.func-sort-c.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:43:41 + 2024-07-11 15:06:04 Functions: 1 diff --git a/Debug/test_coverage/PDE/Transport/Physics/DGAdvection.hpp.func.html b/Debug/test_coverage/PDE/Transport/Physics/DGAdvection.hpp.func.html index f432e73f2045..f1045d3a36a7 100644 --- a/Debug/test_coverage/PDE/Transport/Physics/DGAdvection.hpp.func.html +++ b/Debug/test_coverage/PDE/Transport/Physics/DGAdvection.hpp.func.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:43:41 + 2024-07-11 15:06:04 Functions: 1 diff --git a/Debug/test_coverage/PDE/Transport/Physics/DGAdvection.hpp.gcov.html b/Debug/test_coverage/PDE/Transport/Physics/DGAdvection.hpp.gcov.html index ea5b38f7d265..ddf528c5b1b3 100644 --- a/Debug/test_coverage/PDE/Transport/Physics/DGAdvection.hpp.gcov.html +++ b/Debug/test_coverage/PDE/Transport/Physics/DGAdvection.hpp.gcov.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:43:41 + 2024-07-11 15:06:04 Functions: 1 diff --git a/Debug/test_coverage/PDE/Transport/Physics/index-sort-b.html b/Debug/test_coverage/PDE/Transport/Physics/index-sort-b.html index dcc3fccbec6c..d54b15e413e2 100644 --- a/Debug/test_coverage/PDE/Transport/Physics/index-sort-b.html +++ b/Debug/test_coverage/PDE/Transport/Physics/index-sort-b.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:43:41 + 2024-07-11 15:06:04 Functions: 4 @@ -94,7 +94,7 @@ 0 / 18 - CGAdvDiff.hpp + DGAdvection.hpp
100.0%
@@ -106,7 +106,7 @@ 0 / 0 - DGAdvection.hpp + CGAdvDiff.hpp
100.0%
diff --git a/Debug/test_coverage/PDE/Transport/Physics/index-sort-f.html b/Debug/test_coverage/PDE/Transport/Physics/index-sort-f.html index 26d5e3bbdf02..14bede011ad5 100644 --- a/Debug/test_coverage/PDE/Transport/Physics/index-sort-f.html +++ b/Debug/test_coverage/PDE/Transport/Physics/index-sort-f.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:43:41 + 2024-07-11 15:06:04 Functions: 4 @@ -94,7 +94,7 @@ 0 / 18 - CGAdvDiff.hpp + DGAdvection.hpp
100.0%
@@ -106,7 +106,7 @@ 0 / 0 - DGAdvection.hpp + CGAdvDiff.hpp
100.0%
diff --git a/Debug/test_coverage/PDE/Transport/Physics/index-sort-l.html b/Debug/test_coverage/PDE/Transport/Physics/index-sort-l.html index 130fe459fc74..9b498735b964 100644 --- a/Debug/test_coverage/PDE/Transport/Physics/index-sort-l.html +++ b/Debug/test_coverage/PDE/Transport/Physics/index-sort-l.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:43:41 + 2024-07-11 15:06:04 Functions: 4 @@ -94,7 +94,7 @@ 0 / 18 - CGAdvDiff.hpp + DGAdvection.hpp
100.0%
@@ -106,7 +106,7 @@ 0 / 0 - DGAdvection.hpp + CGAdvDiff.hpp
100.0%
diff --git a/Debug/test_coverage/PDE/Transport/Physics/index.html b/Debug/test_coverage/PDE/Transport/Physics/index.html index c74d7cdde3fb..c166af2f5080 100644 --- a/Debug/test_coverage/PDE/Transport/Physics/index.html +++ b/Debug/test_coverage/PDE/Transport/Physics/index.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:43:41 + 2024-07-11 15:06:04 Functions: 4 diff --git a/Debug/test_coverage/PDE/Transport/Problem/CylAdvect.cpp.func-sort-c.html b/Debug/test_coverage/PDE/Transport/Problem/CylAdvect.cpp.func-sort-c.html index daaf882a99d4..9ecf2d0cd3a8 100644 --- a/Debug/test_coverage/PDE/Transport/Problem/CylAdvect.cpp.func-sort-c.html +++ b/Debug/test_coverage/PDE/Transport/Problem/CylAdvect.cpp.func-sort-c.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:43:41 + 2024-07-11 15:06:04 Functions: 2 diff --git a/Debug/test_coverage/PDE/Transport/Problem/CylAdvect.cpp.func.html b/Debug/test_coverage/PDE/Transport/Problem/CylAdvect.cpp.func.html index 2a939dc48392..aa23adcd4085 100644 --- a/Debug/test_coverage/PDE/Transport/Problem/CylAdvect.cpp.func.html +++ b/Debug/test_coverage/PDE/Transport/Problem/CylAdvect.cpp.func.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:43:41 + 2024-07-11 15:06:04 Functions: 2 diff --git a/Debug/test_coverage/PDE/Transport/Problem/CylAdvect.cpp.gcov.html b/Debug/test_coverage/PDE/Transport/Problem/CylAdvect.cpp.gcov.html index ccca40b6e8ee..d8a1798519da 100644 --- a/Debug/test_coverage/PDE/Transport/Problem/CylAdvect.cpp.gcov.html +++ b/Debug/test_coverage/PDE/Transport/Problem/CylAdvect.cpp.gcov.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:43:41 + 2024-07-11 15:06:04 Functions: 2 diff --git a/Debug/test_coverage/PDE/Transport/Problem/CylAdvect.hpp.func-sort-c.html b/Debug/test_coverage/PDE/Transport/Problem/CylAdvect.hpp.func-sort-c.html index 4be402c29874..16cdb18eb791 100644 --- a/Debug/test_coverage/PDE/Transport/Problem/CylAdvect.hpp.func-sort-c.html +++ b/Debug/test_coverage/PDE/Transport/Problem/CylAdvect.hpp.func-sort-c.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:43:41 + 2024-07-11 15:06:04 Functions: 3 diff --git a/Debug/test_coverage/PDE/Transport/Problem/CylAdvect.hpp.func.html b/Debug/test_coverage/PDE/Transport/Problem/CylAdvect.hpp.func.html index f133e3ceea20..919aa65240bd 100644 --- a/Debug/test_coverage/PDE/Transport/Problem/CylAdvect.hpp.func.html +++ b/Debug/test_coverage/PDE/Transport/Problem/CylAdvect.hpp.func.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:43:41 + 2024-07-11 15:06:04 Functions: 3 diff --git a/Debug/test_coverage/PDE/Transport/Problem/CylAdvect.hpp.gcov.html b/Debug/test_coverage/PDE/Transport/Problem/CylAdvect.hpp.gcov.html index 48097a786934..a9e2c452d004 100644 --- a/Debug/test_coverage/PDE/Transport/Problem/CylAdvect.hpp.gcov.html +++ b/Debug/test_coverage/PDE/Transport/Problem/CylAdvect.hpp.gcov.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:43:41 + 2024-07-11 15:06:04 Functions: 3 diff --git a/Debug/test_coverage/PDE/Transport/Problem/CylVortex.cpp.func-sort-c.html b/Debug/test_coverage/PDE/Transport/Problem/CylVortex.cpp.func-sort-c.html index 551b6a6da8d8..a61d72647d2b 100644 --- a/Debug/test_coverage/PDE/Transport/Problem/CylVortex.cpp.func-sort-c.html +++ b/Debug/test_coverage/PDE/Transport/Problem/CylVortex.cpp.func-sort-c.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:43:41 + 2024-07-11 15:06:04 Functions: 0 diff --git a/Debug/test_coverage/PDE/Transport/Problem/CylVortex.cpp.func.html b/Debug/test_coverage/PDE/Transport/Problem/CylVortex.cpp.func.html index e754e957557e..b1dac8c7fc7a 100644 --- a/Debug/test_coverage/PDE/Transport/Problem/CylVortex.cpp.func.html +++ b/Debug/test_coverage/PDE/Transport/Problem/CylVortex.cpp.func.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:43:41 + 2024-07-11 15:06:04 Functions: 0 diff --git a/Debug/test_coverage/PDE/Transport/Problem/CylVortex.cpp.gcov.html b/Debug/test_coverage/PDE/Transport/Problem/CylVortex.cpp.gcov.html index 71f844ee4635..7ae7b853363a 100644 --- a/Debug/test_coverage/PDE/Transport/Problem/CylVortex.cpp.gcov.html +++ b/Debug/test_coverage/PDE/Transport/Problem/CylVortex.cpp.gcov.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:43:41 + 2024-07-11 15:06:04 Functions: 0 diff --git a/Debug/test_coverage/PDE/Transport/Problem/CylVortex.hpp.func-sort-c.html b/Debug/test_coverage/PDE/Transport/Problem/CylVortex.hpp.func-sort-c.html index 062aa9daf1e7..e59b0fe578bc 100644 --- a/Debug/test_coverage/PDE/Transport/Problem/CylVortex.hpp.func-sort-c.html +++ b/Debug/test_coverage/PDE/Transport/Problem/CylVortex.hpp.func-sort-c.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:43:41 + 2024-07-11 15:06:04 Functions: 1 diff --git a/Debug/test_coverage/PDE/Transport/Problem/CylVortex.hpp.func.html b/Debug/test_coverage/PDE/Transport/Problem/CylVortex.hpp.func.html index 7738bc6720c2..01cb5f9f5d7b 100644 --- a/Debug/test_coverage/PDE/Transport/Problem/CylVortex.hpp.func.html +++ b/Debug/test_coverage/PDE/Transport/Problem/CylVortex.hpp.func.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:43:41 + 2024-07-11 15:06:04 Functions: 1 diff --git a/Debug/test_coverage/PDE/Transport/Problem/CylVortex.hpp.gcov.html b/Debug/test_coverage/PDE/Transport/Problem/CylVortex.hpp.gcov.html index b578b8fe7b80..5eb680e1d244 100644 --- a/Debug/test_coverage/PDE/Transport/Problem/CylVortex.hpp.gcov.html +++ b/Debug/test_coverage/PDE/Transport/Problem/CylVortex.hpp.gcov.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:43:41 + 2024-07-11 15:06:04 Functions: 1 diff --git a/Debug/test_coverage/PDE/Transport/Problem/GaussHump.cpp.func-sort-c.html b/Debug/test_coverage/PDE/Transport/Problem/GaussHump.cpp.func-sort-c.html index ac0d87eb0832..f329c74f4ebb 100644 --- a/Debug/test_coverage/PDE/Transport/Problem/GaussHump.cpp.func-sort-c.html +++ b/Debug/test_coverage/PDE/Transport/Problem/GaussHump.cpp.func-sort-c.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:43:41 + 2024-07-11 15:06:04 Functions: 2 diff --git a/Debug/test_coverage/PDE/Transport/Problem/GaussHump.cpp.func.html b/Debug/test_coverage/PDE/Transport/Problem/GaussHump.cpp.func.html index b21a3a4b0754..259ccad324b7 100644 --- a/Debug/test_coverage/PDE/Transport/Problem/GaussHump.cpp.func.html +++ b/Debug/test_coverage/PDE/Transport/Problem/GaussHump.cpp.func.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:43:41 + 2024-07-11 15:06:04 Functions: 2 diff --git a/Debug/test_coverage/PDE/Transport/Problem/GaussHump.cpp.gcov.html b/Debug/test_coverage/PDE/Transport/Problem/GaussHump.cpp.gcov.html index 0c6187eba4e9..690d3fc53911 100644 --- a/Debug/test_coverage/PDE/Transport/Problem/GaussHump.cpp.gcov.html +++ b/Debug/test_coverage/PDE/Transport/Problem/GaussHump.cpp.gcov.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:43:41 + 2024-07-11 15:06:04 Functions: 2 diff --git a/Debug/test_coverage/PDE/Transport/Problem/GaussHump.hpp.func-sort-c.html b/Debug/test_coverage/PDE/Transport/Problem/GaussHump.hpp.func-sort-c.html index 9aabc4a883e8..f38d4aa22efd 100644 --- a/Debug/test_coverage/PDE/Transport/Problem/GaussHump.hpp.func-sort-c.html +++ b/Debug/test_coverage/PDE/Transport/Problem/GaussHump.hpp.func-sort-c.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:43:41 + 2024-07-11 15:06:04 Functions: 3 diff --git a/Debug/test_coverage/PDE/Transport/Problem/GaussHump.hpp.func.html b/Debug/test_coverage/PDE/Transport/Problem/GaussHump.hpp.func.html index 02bd9c30fd84..0dd8a5b190a1 100644 --- a/Debug/test_coverage/PDE/Transport/Problem/GaussHump.hpp.func.html +++ b/Debug/test_coverage/PDE/Transport/Problem/GaussHump.hpp.func.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:43:41 + 2024-07-11 15:06:04 Functions: 3 diff --git a/Debug/test_coverage/PDE/Transport/Problem/GaussHump.hpp.gcov.html b/Debug/test_coverage/PDE/Transport/Problem/GaussHump.hpp.gcov.html index 825485cc2e2b..93e43e621d47 100644 --- a/Debug/test_coverage/PDE/Transport/Problem/GaussHump.hpp.gcov.html +++ b/Debug/test_coverage/PDE/Transport/Problem/GaussHump.hpp.gcov.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:43:41 + 2024-07-11 15:06:04 Functions: 3 diff --git a/Debug/test_coverage/PDE/Transport/Problem/ShearDiff.cpp.func-sort-c.html b/Debug/test_coverage/PDE/Transport/Problem/ShearDiff.cpp.func-sort-c.html index 8eb94375bea5..5b2321a6cae5 100644 --- a/Debug/test_coverage/PDE/Transport/Problem/ShearDiff.cpp.func-sort-c.html +++ b/Debug/test_coverage/PDE/Transport/Problem/ShearDiff.cpp.func-sort-c.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:43:41 + 2024-07-11 15:06:04 Functions: 0 diff --git a/Debug/test_coverage/PDE/Transport/Problem/ShearDiff.cpp.func.html b/Debug/test_coverage/PDE/Transport/Problem/ShearDiff.cpp.func.html index 5a4c1e1dad61..4b5aae104a31 100644 --- a/Debug/test_coverage/PDE/Transport/Problem/ShearDiff.cpp.func.html +++ b/Debug/test_coverage/PDE/Transport/Problem/ShearDiff.cpp.func.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:43:41 + 2024-07-11 15:06:04 Functions: 0 diff --git a/Debug/test_coverage/PDE/Transport/Problem/ShearDiff.cpp.gcov.html b/Debug/test_coverage/PDE/Transport/Problem/ShearDiff.cpp.gcov.html index 2e26f14348b8..d07fb93babeb 100644 --- a/Debug/test_coverage/PDE/Transport/Problem/ShearDiff.cpp.gcov.html +++ b/Debug/test_coverage/PDE/Transport/Problem/ShearDiff.cpp.gcov.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:43:41 + 2024-07-11 15:06:04 Functions: 0 diff --git a/Debug/test_coverage/PDE/Transport/Problem/ShearDiff.hpp.func-sort-c.html b/Debug/test_coverage/PDE/Transport/Problem/ShearDiff.hpp.func-sort-c.html index e1e5b5190ec1..37f9ee4eaa98 100644 --- a/Debug/test_coverage/PDE/Transport/Problem/ShearDiff.hpp.func-sort-c.html +++ b/Debug/test_coverage/PDE/Transport/Problem/ShearDiff.hpp.func-sort-c.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:43:41 + 2024-07-11 15:06:04 Functions: 1 diff --git a/Debug/test_coverage/PDE/Transport/Problem/ShearDiff.hpp.func.html b/Debug/test_coverage/PDE/Transport/Problem/ShearDiff.hpp.func.html index abdfb3f74aa5..ec3676be7767 100644 --- a/Debug/test_coverage/PDE/Transport/Problem/ShearDiff.hpp.func.html +++ b/Debug/test_coverage/PDE/Transport/Problem/ShearDiff.hpp.func.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:43:41 + 2024-07-11 15:06:04 Functions: 1 diff --git a/Debug/test_coverage/PDE/Transport/Problem/ShearDiff.hpp.gcov.html b/Debug/test_coverage/PDE/Transport/Problem/ShearDiff.hpp.gcov.html index bc1f6994c51c..d8c8b39bc780 100644 --- a/Debug/test_coverage/PDE/Transport/Problem/ShearDiff.hpp.gcov.html +++ b/Debug/test_coverage/PDE/Transport/Problem/ShearDiff.hpp.gcov.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:43:41 + 2024-07-11 15:06:04 Functions: 1 diff --git a/Debug/test_coverage/PDE/Transport/Problem/SlotCyl.cpp.func-sort-c.html b/Debug/test_coverage/PDE/Transport/Problem/SlotCyl.cpp.func-sort-c.html index b9e6798c08b9..1c28cc25f783 100644 --- a/Debug/test_coverage/PDE/Transport/Problem/SlotCyl.cpp.func-sort-c.html +++ b/Debug/test_coverage/PDE/Transport/Problem/SlotCyl.cpp.func-sort-c.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:43:41 + 2024-07-11 15:06:04 Functions: 2 diff --git a/Debug/test_coverage/PDE/Transport/Problem/SlotCyl.cpp.func.html b/Debug/test_coverage/PDE/Transport/Problem/SlotCyl.cpp.func.html index 08e57a4bf40e..a0902c44f3dc 100644 --- a/Debug/test_coverage/PDE/Transport/Problem/SlotCyl.cpp.func.html +++ b/Debug/test_coverage/PDE/Transport/Problem/SlotCyl.cpp.func.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:43:41 + 2024-07-11 15:06:04 Functions: 2 diff --git a/Debug/test_coverage/PDE/Transport/Problem/SlotCyl.cpp.gcov.html b/Debug/test_coverage/PDE/Transport/Problem/SlotCyl.cpp.gcov.html index 7cd822e31ef0..09e779129a38 100644 --- a/Debug/test_coverage/PDE/Transport/Problem/SlotCyl.cpp.gcov.html +++ b/Debug/test_coverage/PDE/Transport/Problem/SlotCyl.cpp.gcov.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:43:41 + 2024-07-11 15:06:04 Functions: 2 diff --git a/Debug/test_coverage/PDE/Transport/Problem/SlotCyl.hpp.func-sort-c.html b/Debug/test_coverage/PDE/Transport/Problem/SlotCyl.hpp.func-sort-c.html index 9c37625b1479..5e2bdb229b46 100644 --- a/Debug/test_coverage/PDE/Transport/Problem/SlotCyl.hpp.func-sort-c.html +++ b/Debug/test_coverage/PDE/Transport/Problem/SlotCyl.hpp.func-sort-c.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:43:41 + 2024-07-11 15:06:04 Functions: 3 diff --git a/Debug/test_coverage/PDE/Transport/Problem/SlotCyl.hpp.func.html b/Debug/test_coverage/PDE/Transport/Problem/SlotCyl.hpp.func.html index 22fe6abb540e..667465bc00b7 100644 --- a/Debug/test_coverage/PDE/Transport/Problem/SlotCyl.hpp.func.html +++ b/Debug/test_coverage/PDE/Transport/Problem/SlotCyl.hpp.func.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:43:41 + 2024-07-11 15:06:04 Functions: 3 diff --git a/Debug/test_coverage/PDE/Transport/Problem/SlotCyl.hpp.gcov.html b/Debug/test_coverage/PDE/Transport/Problem/SlotCyl.hpp.gcov.html index e6374bf2207b..b6af88a81634 100644 --- a/Debug/test_coverage/PDE/Transport/Problem/SlotCyl.hpp.gcov.html +++ b/Debug/test_coverage/PDE/Transport/Problem/SlotCyl.hpp.gcov.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:43:41 + 2024-07-11 15:06:04 Functions: 3 diff --git a/Debug/test_coverage/PDE/Transport/Problem/index-sort-b.html b/Debug/test_coverage/PDE/Transport/Problem/index-sort-b.html index c03ff1a3d9c8..54f93e118145 100644 --- a/Debug/test_coverage/PDE/Transport/Problem/index-sort-b.html +++ b/Debug/test_coverage/PDE/Transport/Problem/index-sort-b.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:43:41 + 2024-07-11 15:06:04 Functions: 17 @@ -141,18 +141,6 @@ 90.0 % 18 / 20 - - CylVortex.hpp - -
40.0%40.0%
- - 40.0 % - 2 / 5 - 33.3 % - 1 / 3 - - - 0 / 0 - SlotCyl.hpp @@ -166,7 +154,19 @@ 0 / 0 - CylAdvect.hpp + CylVortex.hpp + +
40.0%40.0%
+ + 40.0 % + 2 / 5 + 33.3 % + 1 / 3 + - + 0 / 0 + + + GaussHump.hpp
100.0%
@@ -190,7 +190,7 @@ 0 / 0 - GaussHump.hpp + CylAdvect.hpp
100.0%
diff --git a/Debug/test_coverage/PDE/Transport/Problem/index-sort-f.html b/Debug/test_coverage/PDE/Transport/Problem/index-sort-f.html index b6d17f138461..064771fb26f1 100644 --- a/Debug/test_coverage/PDE/Transport/Problem/index-sort-f.html +++ b/Debug/test_coverage/PDE/Transport/Problem/index-sort-f.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:43:41 + 2024-07-11 15:06:04 Functions: 17 @@ -142,28 +142,28 @@ 18 / 20 - GaussHump.cpp + CylAdvect.cpp
100.0%
100.0 % - 13 / 13 + 16 / 16 100.0 % 2 / 2 - 70.0 % - 7 / 10 + 75.0 % + 9 / 12 - CylAdvect.cpp + GaussHump.cpp
100.0%
100.0 % - 16 / 16 + 13 / 13 100.0 % 2 / 2 - 75.0 % - 9 / 12 + 70.0 % + 7 / 10 SlotCyl.hpp @@ -178,7 +178,7 @@ 0 / 0 - CylAdvect.hpp + GaussHump.hpp
100.0%
@@ -190,7 +190,7 @@ 0 / 0 - GaussHump.hpp + CylAdvect.hpp
100.0%
diff --git a/Debug/test_coverage/PDE/Transport/Problem/index-sort-l.html b/Debug/test_coverage/PDE/Transport/Problem/index-sort-l.html index e27659415b5d..6fd815433376 100644 --- a/Debug/test_coverage/PDE/Transport/Problem/index-sort-l.html +++ b/Debug/test_coverage/PDE/Transport/Problem/index-sort-l.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:43:41 + 2024-07-11 15:06:04 Functions: 17 @@ -142,7 +142,7 @@ 0 / 0 - CylAdvect.hpp + GaussHump.hpp
100.0%
@@ -154,7 +154,7 @@ 0 / 0 - GaussHump.hpp + CylAdvect.hpp
100.0%
diff --git a/Debug/test_coverage/PDE/Transport/Problem/index.html b/Debug/test_coverage/PDE/Transport/Problem/index.html index ce85e2f7a8dd..b16999bae8ac 100644 --- a/Debug/test_coverage/PDE/Transport/Problem/index.html +++ b/Debug/test_coverage/PDE/Transport/Problem/index.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:43:41 + 2024-07-11 15:06:04 Functions: 17 diff --git a/Debug/test_coverage/PDE/Transport/index-sort-b.html b/Debug/test_coverage/PDE/Transport/index-sort-b.html index 91a2a51be4ab..3db5f7b6fcee 100644 --- a/Debug/test_coverage/PDE/Transport/index-sort-b.html +++ b/Debug/test_coverage/PDE/Transport/index-sort-b.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:43:41 + 2024-07-11 15:06:04 Functions: 123 diff --git a/Debug/test_coverage/PDE/Transport/index-sort-f.html b/Debug/test_coverage/PDE/Transport/index-sort-f.html index 41bcaece6b2b..d6dd5f660007 100644 --- a/Debug/test_coverage/PDE/Transport/index-sort-f.html +++ b/Debug/test_coverage/PDE/Transport/index-sort-f.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:43:41 + 2024-07-11 15:06:04 Functions: 123 diff --git a/Debug/test_coverage/PDE/Transport/index-sort-l.html b/Debug/test_coverage/PDE/Transport/index-sort-l.html index db250fd4e314..51cbe6b0d10b 100644 --- a/Debug/test_coverage/PDE/Transport/index-sort-l.html +++ b/Debug/test_coverage/PDE/Transport/index-sort-l.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:43:41 + 2024-07-11 15:06:04 Functions: 123 diff --git a/Debug/test_coverage/PDE/Transport/index.html b/Debug/test_coverage/PDE/Transport/index.html index ddd3d51fa3e4..c719cfd18da5 100644 --- a/Debug/test_coverage/PDE/Transport/index.html +++ b/Debug/test_coverage/PDE/Transport/index.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:43:41 + 2024-07-11 15:06:04 Functions: 123 diff --git a/Debug/test_coverage/PDE/index-sort-b.html b/Debug/test_coverage/PDE/index-sort-b.html index e97f22710dee..30e1a6690d16 100644 --- a/Debug/test_coverage/PDE/index-sort-b.html +++ b/Debug/test_coverage/PDE/index-sort-b.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:43:41 + 2024-07-11 15:06:04 Functions: 766 diff --git a/Debug/test_coverage/PDE/index-sort-f.html b/Debug/test_coverage/PDE/index-sort-f.html index 1dc971458f38..a1bc330fd517 100644 --- a/Debug/test_coverage/PDE/index-sort-f.html +++ b/Debug/test_coverage/PDE/index-sort-f.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:43:41 + 2024-07-11 15:06:04 Functions: 766 @@ -213,18 +213,6 @@ 41.1 % 486 / 1182 - - ConfigureMultiMat.cpp - -
75.4%75.4%
- - 75.4 % - 46 / 61 - 100.0 % - 2 / 2 - 38.3 % - 49 / 128 - ConfigureTransport.cpp @@ -249,6 +237,18 @@ 53.3 % 65 / 122 + + ConfigureMultiMat.cpp + +
75.4%75.4%
+ + 75.4 % + 46 / 61 + 100.0 % + 2 / 2 + 38.3 % + 49 / 128 + PDEStack.cpp diff --git a/Debug/test_coverage/PDE/index-sort-l.html b/Debug/test_coverage/PDE/index-sort-l.html index 1f3ae9bf6b73..fa368c8bfa60 100644 --- a/Debug/test_coverage/PDE/index-sort-l.html +++ b/Debug/test_coverage/PDE/index-sort-l.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:43:41 + 2024-07-11 15:06:04 Functions: 766 diff --git a/Debug/test_coverage/PDE/index.html b/Debug/test_coverage/PDE/index.html index 86d2ba73ca1c..76b3397d7afb 100644 --- a/Debug/test_coverage/PDE/index.html +++ b/Debug/test_coverage/PDE/index.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:43:41 + 2024-07-11 15:06:04 Functions: 766 diff --git a/Debug/test_coverage/Statistics/BiPDF.hpp.func-sort-c.html b/Debug/test_coverage/Statistics/BiPDF.hpp.func-sort-c.html index 326e35ff0e58..c34182a63a76 100644 --- a/Debug/test_coverage/Statistics/BiPDF.hpp.func-sort-c.html +++ b/Debug/test_coverage/Statistics/BiPDF.hpp.func-sort-c.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:43:41 + 2024-07-11 15:06:04 Functions: 0 diff --git a/Debug/test_coverage/Statistics/BiPDF.hpp.func.html b/Debug/test_coverage/Statistics/BiPDF.hpp.func.html index b01e5ac21819..2394ccc82428 100644 --- a/Debug/test_coverage/Statistics/BiPDF.hpp.func.html +++ b/Debug/test_coverage/Statistics/BiPDF.hpp.func.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:43:41 + 2024-07-11 15:06:04 Functions: 0 diff --git a/Debug/test_coverage/Statistics/BiPDF.hpp.gcov.html b/Debug/test_coverage/Statistics/BiPDF.hpp.gcov.html index 5613da3a9c6b..b68af380f245 100644 --- a/Debug/test_coverage/Statistics/BiPDF.hpp.gcov.html +++ b/Debug/test_coverage/Statistics/BiPDF.hpp.gcov.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:43:41 + 2024-07-11 15:06:04 Functions: 0 diff --git a/Debug/test_coverage/Statistics/PDFReducer.cpp.func-sort-c.html b/Debug/test_coverage/Statistics/PDFReducer.cpp.func-sort-c.html index d4ef887aa5de..88c540e92a2c 100644 --- a/Debug/test_coverage/Statistics/PDFReducer.cpp.func-sort-c.html +++ b/Debug/test_coverage/Statistics/PDFReducer.cpp.func-sort-c.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:43:41 + 2024-07-11 15:06:04 Functions: 2 diff --git a/Debug/test_coverage/Statistics/PDFReducer.cpp.func.html b/Debug/test_coverage/Statistics/PDFReducer.cpp.func.html index 8a4924b01569..b92a328b0110 100644 --- a/Debug/test_coverage/Statistics/PDFReducer.cpp.func.html +++ b/Debug/test_coverage/Statistics/PDFReducer.cpp.func.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:43:41 + 2024-07-11 15:06:04 Functions: 2 diff --git a/Debug/test_coverage/Statistics/PDFReducer.cpp.gcov.html b/Debug/test_coverage/Statistics/PDFReducer.cpp.gcov.html index d350ee6e2d22..f70cb654cd3f 100644 --- a/Debug/test_coverage/Statistics/PDFReducer.cpp.gcov.html +++ b/Debug/test_coverage/Statistics/PDFReducer.cpp.gcov.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:43:41 + 2024-07-11 15:06:04 Functions: 2 diff --git a/Debug/test_coverage/Statistics/Statistics.cpp.func-sort-c.html b/Debug/test_coverage/Statistics/Statistics.cpp.func-sort-c.html index fe7732856450..e721928e1aac 100644 --- a/Debug/test_coverage/Statistics/Statistics.cpp.func-sort-c.html +++ b/Debug/test_coverage/Statistics/Statistics.cpp.func-sort-c.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:43:41 + 2024-07-11 15:06:04 Functions: 0 diff --git a/Debug/test_coverage/Statistics/Statistics.cpp.func.html b/Debug/test_coverage/Statistics/Statistics.cpp.func.html index a90ceafbc97a..387c7bff191b 100644 --- a/Debug/test_coverage/Statistics/Statistics.cpp.func.html +++ b/Debug/test_coverage/Statistics/Statistics.cpp.func.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:43:41 + 2024-07-11 15:06:04 Functions: 0 diff --git a/Debug/test_coverage/Statistics/Statistics.cpp.gcov.html b/Debug/test_coverage/Statistics/Statistics.cpp.gcov.html index ed96a90d138d..5db131c1a227 100644 --- a/Debug/test_coverage/Statistics/Statistics.cpp.gcov.html +++ b/Debug/test_coverage/Statistics/Statistics.cpp.gcov.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:43:41 + 2024-07-11 15:06:04 Functions: 0 diff --git a/Debug/test_coverage/Statistics/TriPDF.hpp.func-sort-c.html b/Debug/test_coverage/Statistics/TriPDF.hpp.func-sort-c.html index 9679d177d3c2..49a7d4451ec6 100644 --- a/Debug/test_coverage/Statistics/TriPDF.hpp.func-sort-c.html +++ b/Debug/test_coverage/Statistics/TriPDF.hpp.func-sort-c.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:43:41 + 2024-07-11 15:06:04 Functions: 0 diff --git a/Debug/test_coverage/Statistics/TriPDF.hpp.func.html b/Debug/test_coverage/Statistics/TriPDF.hpp.func.html index 19288856d0f8..878c974ddba0 100644 --- a/Debug/test_coverage/Statistics/TriPDF.hpp.func.html +++ b/Debug/test_coverage/Statistics/TriPDF.hpp.func.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:43:41 + 2024-07-11 15:06:04 Functions: 0 diff --git a/Debug/test_coverage/Statistics/TriPDF.hpp.gcov.html b/Debug/test_coverage/Statistics/TriPDF.hpp.gcov.html index 7d88fa6e1600..58d3ef45a768 100644 --- a/Debug/test_coverage/Statistics/TriPDF.hpp.gcov.html +++ b/Debug/test_coverage/Statistics/TriPDF.hpp.gcov.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:43:41 + 2024-07-11 15:06:04 Functions: 0 diff --git a/Debug/test_coverage/Statistics/UniPDF.hpp.func-sort-c.html b/Debug/test_coverage/Statistics/UniPDF.hpp.func-sort-c.html index b5479a708db1..b0c97a049a4e 100644 --- a/Debug/test_coverage/Statistics/UniPDF.hpp.func-sort-c.html +++ b/Debug/test_coverage/Statistics/UniPDF.hpp.func-sort-c.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:43:41 + 2024-07-11 15:06:04 Functions: 13 @@ -121,7 +121,7 @@ tk::UniPDF::extents() const::{lambda(std::pair<long const, double> const&, std::pair<long const, double> const&)#1}::operator()(std::pair<long const, double> const&, std::pair<long const, double> const&) const - 191880 + 191879 tk::UniPDF::add(double) diff --git a/Debug/test_coverage/Statistics/UniPDF.hpp.func.html b/Debug/test_coverage/Statistics/UniPDF.hpp.func.html index 85741a90f5f2..21917d6c136e 100644 --- a/Debug/test_coverage/Statistics/UniPDF.hpp.func.html +++ b/Debug/test_coverage/Statistics/UniPDF.hpp.func.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:43:41 + 2024-07-11 15:06:04 Functions: 13 @@ -121,7 +121,7 @@ tk::UniPDF::extents() const::{lambda(std::pair<long const, double> const&, std::pair<long const, double> const&)#1}::operator()(std::pair<long const, double> const&, std::pair<long const, double> const&) const - 191880 + 191879 tk::UniPDF::integral() const::{lambda(double, std::pair<long const, double> const&)#1}::operator()(double, std::pair<long const, double> const&) const diff --git a/Debug/test_coverage/Statistics/UniPDF.hpp.gcov.html b/Debug/test_coverage/Statistics/UniPDF.hpp.gcov.html index 59c0cfeb04df..25da38b06f70 100644 --- a/Debug/test_coverage/Statistics/UniPDF.hpp.gcov.html +++ b/Debug/test_coverage/Statistics/UniPDF.hpp.gcov.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:43:41 + 2024-07-11 15:06:04 Functions: 13 @@ -151,7 +151,7 @@ 76 : 5388 : void addPDF( const UniPDF& p ) { 77 : 5388 : m_binsize = p.binsize(); 78 : 5388 : m_nsample += p.nsample(); - 79 [ + + ][ + - ]: 294606 : for (const auto& e : p.map()) m_pdf[ e.first ] += e.second; + 79 [ + + ][ + - ]: 294607 : for (const auto& e : p.map()) m_pdf[ e.first ] += e.second; 80 : 5388 : } 81 : : 82 : : //! Zero bins @@ -171,8 +171,8 @@ 96 [ - + ][ - - ]: 579 : Assert( !m_pdf.empty(), "PDF empty" ); [ - - ][ - - ] 97 : 1158 : auto x = std::minmax_element( begin(m_pdf), end(m_pdf), - 98 : 191880 : []( const pair_type& a, const pair_type& b ) - 99 [ + - ]: 192459 : { return a.first < b.first; } ); + 98 : 191879 : []( const pair_type& a, const pair_type& b ) + 99 [ + - ]: 192458 : { return a.first < b.first; } ); 100 : 579 : return {{ x.first->first, x.second->first }}; 101 : : } 102 : : diff --git a/Debug/test_coverage/Statistics/index-sort-b.html b/Debug/test_coverage/Statistics/index-sort-b.html index 8be47450cf4e..fd1cd5c8e286 100644 --- a/Debug/test_coverage/Statistics/index-sort-b.html +++ b/Debug/test_coverage/Statistics/index-sort-b.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:43:41 + 2024-07-11 15:06:04 Functions: 15 diff --git a/Debug/test_coverage/Statistics/index-sort-f.html b/Debug/test_coverage/Statistics/index-sort-f.html index 234d52d4fccc..dca24116be67 100644 --- a/Debug/test_coverage/Statistics/index-sort-f.html +++ b/Debug/test_coverage/Statistics/index-sort-f.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:43:41 + 2024-07-11 15:06:04 Functions: 15 diff --git a/Debug/test_coverage/Statistics/index-sort-l.html b/Debug/test_coverage/Statistics/index-sort-l.html index d6285110767d..eb766e016035 100644 --- a/Debug/test_coverage/Statistics/index-sort-l.html +++ b/Debug/test_coverage/Statistics/index-sort-l.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:43:41 + 2024-07-11 15:06:04 Functions: 15 diff --git a/Debug/test_coverage/Statistics/index.html b/Debug/test_coverage/Statistics/index.html index d2bdda58e0d8..4fd98737b370 100644 --- a/Debug/test_coverage/Statistics/index.html +++ b/Debug/test_coverage/Statistics/index.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:43:41 + 2024-07-11 15:06:04 Functions: 15 diff --git a/Debug/test_coverage/Transfer/M2MTransfer.cpp.func-sort-c.html b/Debug/test_coverage/Transfer/M2MTransfer.cpp.func-sort-c.html index 731ae6bdccff..36c47dcc1627 100644 --- a/Debug/test_coverage/Transfer/M2MTransfer.cpp.func-sort-c.html +++ b/Debug/test_coverage/Transfer/M2MTransfer.cpp.func-sort-c.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:43:41 + 2024-07-11 15:06:04 Functions: 11 diff --git a/Debug/test_coverage/Transfer/M2MTransfer.cpp.func.html b/Debug/test_coverage/Transfer/M2MTransfer.cpp.func.html index d408ed2bd940..5365f217d230 100644 --- a/Debug/test_coverage/Transfer/M2MTransfer.cpp.func.html +++ b/Debug/test_coverage/Transfer/M2MTransfer.cpp.func.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:43:41 + 2024-07-11 15:06:04 Functions: 11 diff --git a/Debug/test_coverage/Transfer/M2MTransfer.cpp.gcov.html b/Debug/test_coverage/Transfer/M2MTransfer.cpp.gcov.html index d49da31abf7f..7f3f35e90fa0 100644 --- a/Debug/test_coverage/Transfer/M2MTransfer.cpp.gcov.html +++ b/Debug/test_coverage/Transfer/M2MTransfer.cpp.gcov.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:43:41 + 2024-07-11 15:06:04 Functions: 11 diff --git a/Debug/test_coverage/Transfer/M2MTransfer.hpp.func-sort-c.html b/Debug/test_coverage/Transfer/M2MTransfer.hpp.func-sort-c.html index 0fb3ac54898e..f792f529a307 100644 --- a/Debug/test_coverage/Transfer/M2MTransfer.hpp.func-sort-c.html +++ b/Debug/test_coverage/Transfer/M2MTransfer.hpp.func-sort-c.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:43:41 + 2024-07-11 15:06:04 Functions: 2 diff --git a/Debug/test_coverage/Transfer/M2MTransfer.hpp.func.html b/Debug/test_coverage/Transfer/M2MTransfer.hpp.func.html index 488fc924462c..b76b5794f7cc 100644 --- a/Debug/test_coverage/Transfer/M2MTransfer.hpp.func.html +++ b/Debug/test_coverage/Transfer/M2MTransfer.hpp.func.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:43:41 + 2024-07-11 15:06:04 Functions: 2 diff --git a/Debug/test_coverage/Transfer/M2MTransfer.hpp.gcov.html b/Debug/test_coverage/Transfer/M2MTransfer.hpp.gcov.html index 2c0579993003..ee3b75864bfd 100644 --- a/Debug/test_coverage/Transfer/M2MTransfer.hpp.gcov.html +++ b/Debug/test_coverage/Transfer/M2MTransfer.hpp.gcov.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:43:41 + 2024-07-11 15:06:04 Functions: 2 diff --git a/Debug/test_coverage/Transfer/TransferDetails.cpp.func-sort-c.html b/Debug/test_coverage/Transfer/TransferDetails.cpp.func-sort-c.html index ae69a3e8a463..16aa98534806 100644 --- a/Debug/test_coverage/Transfer/TransferDetails.cpp.func-sort-c.html +++ b/Debug/test_coverage/Transfer/TransferDetails.cpp.func-sort-c.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:43:41 + 2024-07-11 15:06:04 Functions: 9 diff --git a/Debug/test_coverage/Transfer/TransferDetails.cpp.func.html b/Debug/test_coverage/Transfer/TransferDetails.cpp.func.html index 6423c83755a6..b26adce57556 100644 --- a/Debug/test_coverage/Transfer/TransferDetails.cpp.func.html +++ b/Debug/test_coverage/Transfer/TransferDetails.cpp.func.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:43:41 + 2024-07-11 15:06:04 Functions: 9 diff --git a/Debug/test_coverage/Transfer/TransferDetails.cpp.gcov.html b/Debug/test_coverage/Transfer/TransferDetails.cpp.gcov.html index e95e5503fa33..ca8d5b7cf8c7 100644 --- a/Debug/test_coverage/Transfer/TransferDetails.cpp.gcov.html +++ b/Debug/test_coverage/Transfer/TransferDetails.cpp.gcov.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:43:41 + 2024-07-11 15:06:04 Functions: 9 diff --git a/Debug/test_coverage/Transfer/TransferDetails.hpp.func-sort-c.html b/Debug/test_coverage/Transfer/TransferDetails.hpp.func-sort-c.html index 8d8f174623af..2e421933f5e4 100644 --- a/Debug/test_coverage/Transfer/TransferDetails.hpp.func-sort-c.html +++ b/Debug/test_coverage/Transfer/TransferDetails.hpp.func-sort-c.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:43:41 + 2024-07-11 15:06:04 Functions: 2 diff --git a/Debug/test_coverage/Transfer/TransferDetails.hpp.func.html b/Debug/test_coverage/Transfer/TransferDetails.hpp.func.html index e0d2d981e3e9..002c2b8b95ea 100644 --- a/Debug/test_coverage/Transfer/TransferDetails.hpp.func.html +++ b/Debug/test_coverage/Transfer/TransferDetails.hpp.func.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:43:41 + 2024-07-11 15:06:04 Functions: 2 diff --git a/Debug/test_coverage/Transfer/TransferDetails.hpp.gcov.html b/Debug/test_coverage/Transfer/TransferDetails.hpp.gcov.html index 71cfd2dc96bb..9c3dab6c31ff 100644 --- a/Debug/test_coverage/Transfer/TransferDetails.hpp.gcov.html +++ b/Debug/test_coverage/Transfer/TransferDetails.hpp.gcov.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:43:41 + 2024-07-11 15:06:04 Functions: 2 diff --git a/Debug/test_coverage/Transfer/index-sort-b.html b/Debug/test_coverage/Transfer/index-sort-b.html index 50ae8a98fd18..4f3502ff0cf2 100644 --- a/Debug/test_coverage/Transfer/index-sort-b.html +++ b/Debug/test_coverage/Transfer/index-sort-b.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:43:41 + 2024-07-11 15:06:04 Functions: 24 diff --git a/Debug/test_coverage/Transfer/index-sort-f.html b/Debug/test_coverage/Transfer/index-sort-f.html index 5f900289a6c9..e26c5fd9912a 100644 --- a/Debug/test_coverage/Transfer/index-sort-f.html +++ b/Debug/test_coverage/Transfer/index-sort-f.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:43:41 + 2024-07-11 15:06:04 Functions: 24 diff --git a/Debug/test_coverage/Transfer/index-sort-l.html b/Debug/test_coverage/Transfer/index-sort-l.html index 5b836ebbd30f..7b2f59e023bc 100644 --- a/Debug/test_coverage/Transfer/index-sort-l.html +++ b/Debug/test_coverage/Transfer/index-sort-l.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:43:41 + 2024-07-11 15:06:04 Functions: 24 diff --git a/Debug/test_coverage/Transfer/index.html b/Debug/test_coverage/Transfer/index.html index fb6689c59c1a..6cdc513dc4cd 100644 --- a/Debug/test_coverage/Transfer/index.html +++ b/Debug/test_coverage/Transfer/index.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:43:41 + 2024-07-11 15:06:04 Functions: 24 diff --git a/Debug/test_coverage/UnitTest/Assessment.cpp.func-sort-c.html b/Debug/test_coverage/UnitTest/Assessment.cpp.func-sort-c.html index 950db5386e2e..ca9155384794 100644 --- a/Debug/test_coverage/UnitTest/Assessment.cpp.func-sort-c.html +++ b/Debug/test_coverage/UnitTest/Assessment.cpp.func-sort-c.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:43:41 + 2024-07-11 15:06:04 Functions: 2 diff --git a/Debug/test_coverage/UnitTest/Assessment.cpp.func.html b/Debug/test_coverage/UnitTest/Assessment.cpp.func.html index 5a9a686367f6..35bdec928008 100644 --- a/Debug/test_coverage/UnitTest/Assessment.cpp.func.html +++ b/Debug/test_coverage/UnitTest/Assessment.cpp.func.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:43:41 + 2024-07-11 15:06:04 Functions: 2 diff --git a/Debug/test_coverage/UnitTest/Assessment.cpp.gcov.html b/Debug/test_coverage/UnitTest/Assessment.cpp.gcov.html index e178495918f1..4481eed6fccd 100644 --- a/Debug/test_coverage/UnitTest/Assessment.cpp.gcov.html +++ b/Debug/test_coverage/UnitTest/Assessment.cpp.gcov.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:43:41 + 2024-07-11 15:06:04 Functions: 2 diff --git a/Debug/test_coverage/UnitTest/MPIRunner.hpp.func-sort-c.html b/Debug/test_coverage/UnitTest/MPIRunner.hpp.func-sort-c.html index 0304d59a9de6..0e9c2c999058 100644 --- a/Debug/test_coverage/UnitTest/MPIRunner.hpp.func-sort-c.html +++ b/Debug/test_coverage/UnitTest/MPIRunner.hpp.func-sort-c.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:43:41 + 2024-07-11 15:06:04 Functions: 2 diff --git a/Debug/test_coverage/UnitTest/MPIRunner.hpp.func.html b/Debug/test_coverage/UnitTest/MPIRunner.hpp.func.html index 7c3c0b9f1c29..36e456dc26ae 100644 --- a/Debug/test_coverage/UnitTest/MPIRunner.hpp.func.html +++ b/Debug/test_coverage/UnitTest/MPIRunner.hpp.func.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:43:41 + 2024-07-11 15:06:04 Functions: 2 diff --git a/Debug/test_coverage/UnitTest/MPIRunner.hpp.gcov.html b/Debug/test_coverage/UnitTest/MPIRunner.hpp.gcov.html index 07824fabf486..eb3e2201f224 100644 --- a/Debug/test_coverage/UnitTest/MPIRunner.hpp.gcov.html +++ b/Debug/test_coverage/UnitTest/MPIRunner.hpp.gcov.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:43:41 + 2024-07-11 15:06:04 Functions: 2 diff --git a/Debug/test_coverage/UnitTest/QuietCerr.cpp.func-sort-c.html b/Debug/test_coverage/UnitTest/QuietCerr.cpp.func-sort-c.html index e79dba7235bc..a3a0038976d8 100644 --- a/Debug/test_coverage/UnitTest/QuietCerr.cpp.func-sort-c.html +++ b/Debug/test_coverage/UnitTest/QuietCerr.cpp.func-sort-c.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:43:41 + 2024-07-11 15:06:04 Functions: 1 diff --git a/Debug/test_coverage/UnitTest/QuietCerr.cpp.func.html b/Debug/test_coverage/UnitTest/QuietCerr.cpp.func.html index 0a7b877713b4..975288c8456d 100644 --- a/Debug/test_coverage/UnitTest/QuietCerr.cpp.func.html +++ b/Debug/test_coverage/UnitTest/QuietCerr.cpp.func.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:43:41 + 2024-07-11 15:06:04 Functions: 1 diff --git a/Debug/test_coverage/UnitTest/QuietCerr.cpp.gcov.html b/Debug/test_coverage/UnitTest/QuietCerr.cpp.gcov.html index 32687b9e9d01..e08e6cb8ff29 100644 --- a/Debug/test_coverage/UnitTest/QuietCerr.cpp.gcov.html +++ b/Debug/test_coverage/UnitTest/QuietCerr.cpp.gcov.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:43:41 + 2024-07-11 15:06:04 Functions: 1 diff --git a/Debug/test_coverage/UnitTest/TUTSuite.cpp.func-sort-c.html b/Debug/test_coverage/UnitTest/TUTSuite.cpp.func-sort-c.html index 947e4428158b..46b8666d31d7 100644 --- a/Debug/test_coverage/UnitTest/TUTSuite.cpp.func-sort-c.html +++ b/Debug/test_coverage/UnitTest/TUTSuite.cpp.func-sort-c.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:43:41 + 2024-07-11 15:06:04 Functions: 3 diff --git a/Debug/test_coverage/UnitTest/TUTSuite.cpp.func.html b/Debug/test_coverage/UnitTest/TUTSuite.cpp.func.html index 7585dc1eefc6..a391fac742fd 100644 --- a/Debug/test_coverage/UnitTest/TUTSuite.cpp.func.html +++ b/Debug/test_coverage/UnitTest/TUTSuite.cpp.func.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:43:41 + 2024-07-11 15:06:04 Functions: 3 diff --git a/Debug/test_coverage/UnitTest/TUTSuite.cpp.gcov.html b/Debug/test_coverage/UnitTest/TUTSuite.cpp.gcov.html index 0e208d66b321..e0c3e72979d5 100644 --- a/Debug/test_coverage/UnitTest/TUTSuite.cpp.gcov.html +++ b/Debug/test_coverage/UnitTest/TUTSuite.cpp.gcov.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:43:41 + 2024-07-11 15:06:04 Functions: 3 diff --git a/Debug/test_coverage/UnitTest/TUTSuite.hpp.func-sort-c.html b/Debug/test_coverage/UnitTest/TUTSuite.hpp.func-sort-c.html index 3233fe3f90de..3a44dd423f59 100644 --- a/Debug/test_coverage/UnitTest/TUTSuite.hpp.func-sort-c.html +++ b/Debug/test_coverage/UnitTest/TUTSuite.hpp.func-sort-c.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:43:41 + 2024-07-11 15:06:04 Functions: 1 diff --git a/Debug/test_coverage/UnitTest/TUTSuite.hpp.func.html b/Debug/test_coverage/UnitTest/TUTSuite.hpp.func.html index f8e835d318a9..e98342442734 100644 --- a/Debug/test_coverage/UnitTest/TUTSuite.hpp.func.html +++ b/Debug/test_coverage/UnitTest/TUTSuite.hpp.func.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:43:41 + 2024-07-11 15:06:04 Functions: 1 diff --git a/Debug/test_coverage/UnitTest/TUTSuite.hpp.gcov.html b/Debug/test_coverage/UnitTest/TUTSuite.hpp.gcov.html index 152adc6d3fb4..083551ddfb72 100644 --- a/Debug/test_coverage/UnitTest/TUTSuite.hpp.gcov.html +++ b/Debug/test_coverage/UnitTest/TUTSuite.hpp.gcov.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:43:41 + 2024-07-11 15:06:04 Functions: 1 diff --git a/Debug/test_coverage/UnitTest/TUTTest.hpp.func-sort-c.html b/Debug/test_coverage/UnitTest/TUTTest.hpp.func-sort-c.html index 6b4bf89a142f..7e767b98f11e 100644 --- a/Debug/test_coverage/UnitTest/TUTTest.hpp.func-sort-c.html +++ b/Debug/test_coverage/UnitTest/TUTTest.hpp.func-sort-c.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:43:41 + 2024-07-11 15:06:04 Functions: 1 diff --git a/Debug/test_coverage/UnitTest/TUTTest.hpp.func.html b/Debug/test_coverage/UnitTest/TUTTest.hpp.func.html index 01bf1094e2ec..5b066f73af01 100644 --- a/Debug/test_coverage/UnitTest/TUTTest.hpp.func.html +++ b/Debug/test_coverage/UnitTest/TUTTest.hpp.func.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:43:41 + 2024-07-11 15:06:04 Functions: 1 diff --git a/Debug/test_coverage/UnitTest/TUTTest.hpp.gcov.html b/Debug/test_coverage/UnitTest/TUTTest.hpp.gcov.html index 198b034af1b8..21eaa4527284 100644 --- a/Debug/test_coverage/UnitTest/TUTTest.hpp.gcov.html +++ b/Debug/test_coverage/UnitTest/TUTTest.hpp.gcov.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:43:41 + 2024-07-11 15:06:04 Functions: 1 diff --git a/Debug/test_coverage/UnitTest/TUTUtil.hpp.func-sort-c.html b/Debug/test_coverage/UnitTest/TUTUtil.hpp.func-sort-c.html index 0f24902411f8..d673a63f595b 100644 --- a/Debug/test_coverage/UnitTest/TUTUtil.hpp.func-sort-c.html +++ b/Debug/test_coverage/UnitTest/TUTUtil.hpp.func-sort-c.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:43:41 + 2024-07-11 15:06:04 Functions: 6 diff --git a/Debug/test_coverage/UnitTest/TUTUtil.hpp.func.html b/Debug/test_coverage/UnitTest/TUTUtil.hpp.func.html index bc3f9c86d467..ba77687ce032 100644 --- a/Debug/test_coverage/UnitTest/TUTUtil.hpp.func.html +++ b/Debug/test_coverage/UnitTest/TUTUtil.hpp.func.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:43:41 + 2024-07-11 15:06:04 Functions: 6 diff --git a/Debug/test_coverage/UnitTest/TUTUtil.hpp.gcov.html b/Debug/test_coverage/UnitTest/TUTUtil.hpp.gcov.html index 815620042d8b..699276750c96 100644 --- a/Debug/test_coverage/UnitTest/TUTUtil.hpp.gcov.html +++ b/Debug/test_coverage/UnitTest/TUTUtil.hpp.gcov.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:43:41 + 2024-07-11 15:06:04 Functions: 6 diff --git a/Debug/test_coverage/UnitTest/index-sort-b.html b/Debug/test_coverage/UnitTest/index-sort-b.html index 99f3bc66edef..36fdd5390c83 100644 --- a/Debug/test_coverage/UnitTest/index-sort-b.html +++ b/Debug/test_coverage/UnitTest/index-sort-b.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:43:41 + 2024-07-11 15:06:04 Functions: 16 diff --git a/Debug/test_coverage/UnitTest/index-sort-f.html b/Debug/test_coverage/UnitTest/index-sort-f.html index 122f3b8177a8..af0d68ec7124 100644 --- a/Debug/test_coverage/UnitTest/index-sort-f.html +++ b/Debug/test_coverage/UnitTest/index-sort-f.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:43:41 + 2024-07-11 15:06:04 Functions: 16 @@ -105,18 +105,6 @@ 47.5 % 58 / 122 - - TUTSuite.hpp - -
100.0%
- - 100.0 % - 10 / 10 - 100.0 % - 1 / 1 - 29.2 % - 7 / 24 - TUTTest.hpp @@ -130,16 +118,16 @@ 10 / 20 - MPIRunner.hpp + TUTSuite.hpp
100.0%
100.0 % - 11 / 11 + 10 / 10 100.0 % - 2 / 2 - 62.5 % - 20 / 32 + 1 / 1 + 29.2 % + 7 / 24 Assessment.cpp @@ -153,6 +141,18 @@ 16.3 % 15 / 92 + + MPIRunner.hpp + +
100.0%
+ + 100.0 % + 11 / 11 + 100.0 % + 2 / 2 + 62.5 % + 20 / 32 + TUTUtil.hpp diff --git a/Debug/test_coverage/UnitTest/index-sort-l.html b/Debug/test_coverage/UnitTest/index-sort-l.html index 82749d248346..62dca4f2b831 100644 --- a/Debug/test_coverage/UnitTest/index-sort-l.html +++ b/Debug/test_coverage/UnitTest/index-sort-l.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:43:41 + 2024-07-11 15:06:04 Functions: 16 @@ -130,28 +130,28 @@ 10 / 20 - TUTSuite.hpp + TUTUtil.hpp
100.0%
100.0 % 10 / 10 100.0 % - 1 / 1 - 29.2 % - 7 / 24 + 6 / 6 + - + 0 / 0 - TUTUtil.hpp + TUTSuite.hpp
100.0%
100.0 % 10 / 10 100.0 % - 6 / 6 - - - 0 / 0 + 1 / 1 + 29.2 % + 7 / 24 MPIRunner.hpp diff --git a/Debug/test_coverage/UnitTest/index.html b/Debug/test_coverage/UnitTest/index.html index c5a6e00b1a5c..7dbb197e5dab 100644 --- a/Debug/test_coverage/UnitTest/index.html +++ b/Debug/test_coverage/UnitTest/index.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:43:41 + 2024-07-11 15:06:04 Functions: 16 diff --git a/Debug/test_coverage/index-sort-b.html b/Debug/test_coverage/index-sort-b.html index 480cf8b914d2..bfcff8c520cd 100644 --- a/Debug/test_coverage/index-sort-b.html +++ b/Debug/test_coverage/index-sort-b.html @@ -27,16 +27,16 @@ -128-NOTFOUND Lines: - 20122 - 26165 + 20157 + 26201 76.9 % Date: - 2024-07-10 11:43:41 + 2024-07-11 15:06:04 Functions: - 5321 + 5325 10318 51.6 % @@ -49,8 +49,8 @@ Branches: - 17064 - 42017 + 17099 + 42075 40.6 % @@ -112,8 +112,8 @@ 10.9 % 62 / 569 - 39.1 % - 79 / 202 + 40.1 % + 81 / 202 5.1 % 23 / 448 @@ -228,26 +228,14 @@ PDE/MultiMat -
63.0%63.0%
+
63.4%63.4%
- 63.0 % - 755 / 1198 + 63.4 % + 760 / 1198 11.3 % - 141 / 1252 + 142 / 1252 32.1 % - 505 / 1574 - - - PDE/Riemann - -
72.7%72.7%
- - 72.7 % - 298 / 410 - 87.5 % - 7 / 8 - 34.2 % - 93 / 272 + 506 / 1574 PDE/CompFlow/Problem @@ -273,6 +261,18 @@ 35.9 % 513 / 1429 + + PDE/Riemann + +
72.2%72.2%
+ + 72.2 % + 322 / 446 + 87.5 % + 7 / 8 + 37.3 % + 123 / 330 + UnitTest @@ -312,14 +312,14 @@ Base -
83.0%83.0%
+
83.4%83.4%
- 83.0 % - 1078 / 1299 + 83.4 % + 1084 / 1299 94.2 % - 1841 / 1955 - 41.0 % - 714 / 1741 + 1842 / 1955 + 41.2 % + 718 / 1741 Main diff --git a/Debug/test_coverage/index-sort-f.html b/Debug/test_coverage/index-sort-f.html index e85c199f3390..a521be465365 100644 --- a/Debug/test_coverage/index-sort-f.html +++ b/Debug/test_coverage/index-sort-f.html @@ -27,16 +27,16 @@ -128-NOTFOUND Lines: - 20122 - 26165 + 20157 + 26201 76.9 % Date: - 2024-07-10 11:43:41 + 2024-07-11 15:06:04 Functions: - 5321 + 5325 10318 51.6 % @@ -49,8 +49,8 @@ Branches: - 17064 - 42017 + 17099 + 42075 40.6 % @@ -84,14 +84,14 @@ PDE/MultiMat -
63.0%63.0%
+
63.4%63.4%
- 63.0 % - 755 / 1198 + 63.4 % + 760 / 1198 11.3 % - 141 / 1252 + 142 / 1252 32.1 % - 505 / 1574 + 506 / 1574 PDE/Transport @@ -148,8 +148,8 @@ 10.9 % 62 / 569 - 39.1 % - 79 / 202 + 40.1 % + 81 / 202 5.1 % 23 / 448 @@ -312,14 +312,14 @@ PDE/Riemann -
72.7%72.7%
+
72.2%72.2%
- 72.7 % - 298 / 410 + 72.2 % + 322 / 446 87.5 % 7 / 8 - 34.2 % - 93 / 272 + 37.3 % + 123 / 330 LoadBalance @@ -348,14 +348,14 @@ Base -
83.0%83.0%
+
83.4%83.4%
- 83.0 % - 1078 / 1299 + 83.4 % + 1084 / 1299 94.2 % - 1841 / 1955 - 41.0 % - 714 / 1741 + 1842 / 1955 + 41.2 % + 718 / 1741 Mesh @@ -393,18 +393,6 @@ 15.8 % 29 / 184 - - Control/UnitTest/CmdLine - -
73.1%73.1%
- - 73.1 % - 38 / 52 - 100.0 % - 5 / 5 - 24.5 % - 23 / 94 - Control/Inciter/CmdLine @@ -417,6 +405,18 @@ 18.9 % 34 / 180 + + Control/UnitTest/CmdLine + +
73.1%73.1%
+ + 73.1 % + 38 / 52 + 100.0 % + 5 / 5 + 24.5 % + 23 / 94 + Control/Inciter diff --git a/Debug/test_coverage/index-sort-l.html b/Debug/test_coverage/index-sort-l.html index 7a7220380a85..e757663bd585 100644 --- a/Debug/test_coverage/index-sort-l.html +++ b/Debug/test_coverage/index-sort-l.html @@ -27,16 +27,16 @@ -128-NOTFOUND Lines: - 20122 - 26165 + 20157 + 26201 76.9 % Date: - 2024-07-10 11:43:41 + 2024-07-11 15:06:04 Functions: - 5321 + 5325 10318 51.6 % @@ -49,8 +49,8 @@ Branches: - 17064 - 42017 + 17099 + 42075 40.6 % @@ -100,8 +100,8 @@ 10.9 % 62 / 569 - 39.1 % - 79 / 202 + 40.1 % + 81 / 202 5.1 % 23 / 448 @@ -204,14 +204,14 @@ PDE/MultiMat -
63.0%63.0%
+
63.4%63.4%
- 63.0 % - 755 / 1198 + 63.4 % + 760 / 1198 11.3 % - 141 / 1252 + 142 / 1252 32.1 % - 505 / 1574 + 506 / 1574 Control/MeshConv/CmdLine @@ -249,6 +249,18 @@ 35.9 % 513 / 1429 + + PDE/Riemann + +
72.2%72.2%
+ + 72.2 % + 322 / 446 + 87.5 % + 7 / 8 + 37.3 % + 123 / 330 + Control/Inciter/CmdLine @@ -261,18 +273,6 @@ 18.9 % 34 / 180 - - PDE/Riemann - -
72.7%72.7%
- - 72.7 % - 298 / 410 - 87.5 % - 7 / 8 - 34.2 % - 93 / 272 - Control/UnitTest/CmdLine @@ -348,14 +348,14 @@ Base -
83.0%83.0%
+
83.4%83.4%
- 83.0 % - 1078 / 1299 + 83.4 % + 1084 / 1299 94.2 % - 1841 / 1955 - 41.0 % - 714 / 1741 + 1842 / 1955 + 41.2 % + 718 / 1741 PDE/Transport diff --git a/Debug/test_coverage/index.html b/Debug/test_coverage/index.html index a3a2d235da21..543668cdf7ad 100644 --- a/Debug/test_coverage/index.html +++ b/Debug/test_coverage/index.html @@ -27,16 +27,16 @@ -128-NOTFOUND Lines: - 20122 - 26165 + 20157 + 26201 76.9 % Date: - 2024-07-10 11:43:41 + 2024-07-11 15:06:04 Functions: - 5321 + 5325 10318 51.6 % @@ -49,8 +49,8 @@ Branches: - 17064 - 42017 + 17099 + 42075 40.6 % @@ -96,14 +96,14 @@ Base -
83.0%83.0%
+
83.4%83.4%
- 83.0 % - 1078 / 1299 + 83.4 % + 1084 / 1299 94.2 % - 1841 / 1955 - 41.0 % - 714 / 1741 + 1842 / 1955 + 41.2 % + 718 / 1741 Control @@ -340,8 +340,8 @@ 10.9 % 62 / 569 - 39.1 % - 79 / 202 + 40.1 % + 81 / 202 5.1 % 23 / 448 @@ -360,14 +360,14 @@ PDE/MultiMat -
63.0%63.0%
+
63.4%63.4%
- 63.0 % - 755 / 1198 + 63.4 % + 760 / 1198 11.3 % - 141 / 1252 + 142 / 1252 32.1 % - 505 / 1574 + 506 / 1574 PDE/MultiMat/Physics @@ -396,14 +396,14 @@ PDE/Riemann -
72.7%72.7%
+
72.2%72.2%
- 72.7 % - 298 / 410 + 72.2 % + 322 / 446 87.5 % 7 / 8 - 34.2 % - 93 / 272 + 37.3 % + 123 / 330 PDE/Transport diff --git a/Debug/test_coverage/tmp/TeamCity-1/work/5ad443c8abe7fc0a/build/Main/QuinoaConfig.cpp.func-sort-c.html b/Debug/test_coverage/tmp/TeamCity-1/work/5ad443c8abe7fc0a/build/Main/QuinoaConfig.cpp.func-sort-c.html index 9af54151331a..62e36acb50a5 100644 --- a/Debug/test_coverage/tmp/TeamCity-1/work/5ad443c8abe7fc0a/build/Main/QuinoaConfig.cpp.func-sort-c.html +++ b/Debug/test_coverage/tmp/TeamCity-1/work/5ad443c8abe7fc0a/build/Main/QuinoaConfig.cpp.func-sort-c.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:43:41 + 2024-07-11 15:06:04 Functions: 10 diff --git a/Debug/test_coverage/tmp/TeamCity-1/work/5ad443c8abe7fc0a/build/Main/QuinoaConfig.cpp.func.html b/Debug/test_coverage/tmp/TeamCity-1/work/5ad443c8abe7fc0a/build/Main/QuinoaConfig.cpp.func.html index 0cb58682e13e..dad43ae91ae6 100644 --- a/Debug/test_coverage/tmp/TeamCity-1/work/5ad443c8abe7fc0a/build/Main/QuinoaConfig.cpp.func.html +++ b/Debug/test_coverage/tmp/TeamCity-1/work/5ad443c8abe7fc0a/build/Main/QuinoaConfig.cpp.func.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:43:41 + 2024-07-11 15:06:04 Functions: 10 diff --git a/Debug/test_coverage/tmp/TeamCity-1/work/5ad443c8abe7fc0a/build/Main/QuinoaConfig.cpp.gcov.html b/Debug/test_coverage/tmp/TeamCity-1/work/5ad443c8abe7fc0a/build/Main/QuinoaConfig.cpp.gcov.html index d06c9dc8c0d4..d814dba5ed6e 100644 --- a/Debug/test_coverage/tmp/TeamCity-1/work/5ad443c8abe7fc0a/build/Main/QuinoaConfig.cpp.gcov.html +++ b/Debug/test_coverage/tmp/TeamCity-1/work/5ad443c8abe7fc0a/build/Main/QuinoaConfig.cpp.gcov.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:43:41 + 2024-07-11 15:06:04 Functions: 10 @@ -103,7 +103,7 @@ 29 : : #define COMPILER "/usr/bin/g++" 30 : : #define BUILD_HOSTNAME "lagrange" 31 : : #define BUILD_TYPE "DEBUG" - 32 : : #define BUILD_DATE "Wed 10 Jul 2024 11:35:53 AM MDT" + 32 : : #define BUILD_DATE "Thu 11 Jul 2024 02:58:13 PM MDT" 33 : : #define REGRESSION_DIR "/tmp/TeamCity-1/work/5ad443c8abe7fc0a/tests/regression" 34 : : 35 : : // Accessor definitions as strings of configuration values imported from cmake diff --git a/Debug/test_coverage/tmp/TeamCity-1/work/5ad443c8abe7fc0a/build/Main/index-sort-b.html b/Debug/test_coverage/tmp/TeamCity-1/work/5ad443c8abe7fc0a/build/Main/index-sort-b.html index ec063fef9f24..63fe10673cb4 100644 --- a/Debug/test_coverage/tmp/TeamCity-1/work/5ad443c8abe7fc0a/build/Main/index-sort-b.html +++ b/Debug/test_coverage/tmp/TeamCity-1/work/5ad443c8abe7fc0a/build/Main/index-sort-b.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:43:41 + 2024-07-11 15:06:04 Functions: 10 diff --git a/Debug/test_coverage/tmp/TeamCity-1/work/5ad443c8abe7fc0a/build/Main/index-sort-f.html b/Debug/test_coverage/tmp/TeamCity-1/work/5ad443c8abe7fc0a/build/Main/index-sort-f.html index 6a3d6a1249c2..d93a6c42716c 100644 --- a/Debug/test_coverage/tmp/TeamCity-1/work/5ad443c8abe7fc0a/build/Main/index-sort-f.html +++ b/Debug/test_coverage/tmp/TeamCity-1/work/5ad443c8abe7fc0a/build/Main/index-sort-f.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:43:41 + 2024-07-11 15:06:04 Functions: 10 diff --git a/Debug/test_coverage/tmp/TeamCity-1/work/5ad443c8abe7fc0a/build/Main/index-sort-l.html b/Debug/test_coverage/tmp/TeamCity-1/work/5ad443c8abe7fc0a/build/Main/index-sort-l.html index 3c5022e0fac4..10a2909cacd1 100644 --- a/Debug/test_coverage/tmp/TeamCity-1/work/5ad443c8abe7fc0a/build/Main/index-sort-l.html +++ b/Debug/test_coverage/tmp/TeamCity-1/work/5ad443c8abe7fc0a/build/Main/index-sort-l.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:43:41 + 2024-07-11 15:06:04 Functions: 10 diff --git a/Debug/test_coverage/tmp/TeamCity-1/work/5ad443c8abe7fc0a/build/Main/index.html b/Debug/test_coverage/tmp/TeamCity-1/work/5ad443c8abe7fc0a/build/Main/index.html index 4f53d45d0ac8..497abb5e8dd5 100644 --- a/Debug/test_coverage/tmp/TeamCity-1/work/5ad443c8abe7fc0a/build/Main/index.html +++ b/Debug/test_coverage/tmp/TeamCity-1/work/5ad443c8abe7fc0a/build/Main/index.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:43:41 + 2024-07-11 15:06:04 Functions: 10 diff --git a/Release/cppcheck/10.html b/Release/cppcheck/10.html index f0fd967a65de..ad4558917c43 100644 --- a/Release/cppcheck/10.html +++ b/Release/cppcheck/10.html @@ -152,1463 +152,2121 @@
- - + @@ -164,7 +164,7 @@ 90 : : #endif 91 : : //! Migrate constructor 92 : : // cppcheck-suppress uninitMemberVar - 93 : 23574 : explicit Refiner( CkMigrateMessage* ) {} + 93 : 23265 : explicit Refiner( CkMigrateMessage* ) {} 94 : : #if defined(__clang__) 95 : : #pragma clang diagnostic pop 96 : : #endif @@ -233,68 +233,68 @@ 159 : : ///@{ 160 : : //! \brief Pack/Unpack serialize member function 161 : : //! \param[in,out] p Charm++'s PUP::er serializer object reference - 162 : 24390 : void pup( PUP::er &p ) override { - 163 : 24390 : p | m_meshid; - 164 : 24390 : p | m_ncit; - 165 : 24390 : p | m_host; - 166 : 24390 : p | m_sorter; - 167 : 24390 : p | m_meshwriter; - 168 : 24390 : p | m_scheme; + 162 : 24081 : void pup( PUP::er &p ) override { + 163 : 24081 : p | m_meshid; + 164 : 24081 : p | m_ncit; + 165 : 24081 : p | m_host; + 166 : 24081 : p | m_sorter; + 167 : 24081 : p | m_meshwriter; + 168 : 24081 : p | m_scheme; 169 : : p | m_cbr; 170 : : p | m_cbs; - 171 : 24390 : p | m_ginpoel; - 172 : 24390 : p | m_el; - 173 [ + + ]: 24390 : if (p.isUnpacking()) { - 174 : 7858 : m_inpoel = std::get< 0 >( m_el ); - 175 : 7858 : m_gid = std::get< 1 >( m_el ); - 176 [ - + ]: 7858 : m_lid = std::get< 2 >( m_el ); + 171 : 24081 : p | m_ginpoel; + 172 : 24081 : p | m_el; + 173 [ + + ]: 24081 : if (p.isUnpacking()) { + 174 : 7755 : m_inpoel = std::get< 0 >( m_el ); + 175 : 7755 : m_gid = std::get< 1 >( m_el ); + 176 [ - + ]: 7755 : m_lid = std::get< 2 >( m_el ); 177 : : } - 178 : 24390 : p | m_coordmap; + 178 : 24081 : p | m_coordmap; 179 : : p | m_coord; 180 : : p | m_bface; - 181 : 24390 : p | m_bnode; - 182 : 24390 : p | m_triinpoel; - 183 : 24390 : p | m_elemblockid; - 184 : 24390 : p | m_nchare; - 185 : 24390 : p | m_mode; - 186 : 24390 : p | m_initref; - 187 : 24390 : p | m_refiner; - 188 : 24390 : p | m_nref; - 189 : 24390 : p | m_nbnd; - 190 : 24390 : p | m_extra; - 191 : 24390 : p | m_ch; - 192 : 24390 : p | m_edgech; - 193 : 24390 : p | m_chedge; - 194 : 24390 : p | m_localEdgeData; - 195 : 24390 : p | m_remoteEdgeData; - 196 : 24390 : p | m_remoteEdges; - 197 : 24390 : p | m_intermediates; - 198 : 24390 : p | m_nodeCommMap; - 199 : 24390 : p | m_oldTets; - 200 : 24390 : p | m_addedNodes; - 201 : 24390 : p | m_addedTets; - 202 : 24390 : p | m_removedNodes; - 203 : 24390 : p | m_amrNodeMap; - 204 : 24390 : p | m_oldntets; - 205 : 24390 : p | m_coarseBndFaces; - 206 : 24390 : p | m_coarseBndNodes; - 207 : 24390 : p | m_coarseBlkElems; - 208 : 24390 : p | m_rid; + 181 : 24081 : p | m_bnode; + 182 : 24081 : p | m_triinpoel; + 183 : 24081 : p | m_elemblockid; + 184 : 24081 : p | m_nchare; + 185 : 24081 : p | m_mode; + 186 : 24081 : p | m_initref; + 187 : 24081 : p | m_refiner; + 188 : 24081 : p | m_nref; + 189 : 24081 : p | m_nbnd; + 190 : 24081 : p | m_extra; + 191 : 24081 : p | m_ch; + 192 : 24081 : p | m_edgech; + 193 : 24081 : p | m_chedge; + 194 : 24081 : p | m_localEdgeData; + 195 : 24081 : p | m_remoteEdgeData; + 196 : 24081 : p | m_remoteEdges; + 197 : 24081 : p | m_intermediates; + 198 : 24081 : p | m_nodeCommMap; + 199 : 24081 : p | m_oldTets; + 200 : 24081 : p | m_addedNodes; + 201 : 24081 : p | m_addedTets; + 202 : 24081 : p | m_removedNodes; + 203 : 24081 : p | m_amrNodeMap; + 204 : 24081 : p | m_oldntets; + 205 : 24081 : p | m_coarseBndFaces; + 206 : 24081 : p | m_coarseBndNodes; + 207 : 24081 : p | m_coarseBlkElems; + 208 : 24081 : p | m_rid; 209 : : //p | m_oldrid; - 210 : 24390 : p | m_lref; + 210 : 24081 : p | m_lref; 211 : : //p | m_oldlref; 212 : : //p | m_oldparent; - 213 : 24390 : p | m_writeCallback; - 214 : 24390 : p | m_outref_ginpoel; - 215 : 24390 : p | m_outref_el; + 213 : 24081 : p | m_writeCallback; + 214 : 24081 : p | m_outref_ginpoel; + 215 : 24081 : p | m_outref_el; 216 : : p | m_outref_coord; 217 : : p | m_outref_addedNodes; - 218 : 24390 : p | m_outref_addedTets; - 219 : 24390 : p | m_outref_nodeCommMap; - 220 : 24390 : p | m_outref_bface; - 221 : 24390 : p | m_outref_bnode; - 222 : 24390 : p | m_outref_triinpoel; - 223 : 24390 : } + 218 : 24081 : p | m_outref_addedTets; + 219 : 24081 : p | m_outref_nodeCommMap; + 220 : 24081 : p | m_outref_bface; + 221 : 24081 : p | m_outref_bnode; + 222 : 24081 : p | m_outref_triinpoel; + 223 : 24081 : } 224 : : //! \brief Pack/Unpack serialize operator| 225 : : //! \param[in,out] p Charm++'s PUP::er serializer object reference 226 : : //! \param[in,out] r Refiner object reference diff --git a/Release/test_coverage/Inciter/Scheme.hpp.func-sort-c.html b/Release/test_coverage/Inciter/Scheme.hpp.func-sort-c.html index df6484b15a64..4ea6afe28e22 100644 --- a/Release/test_coverage/Inciter/Scheme.hpp.func-sort-c.html +++ b/Release/test_coverage/Inciter/Scheme.hpp.func-sort-c.html @@ -33,7 +33,7 @@ - + @@ -157,11 +157,11 @@ - + - +
  1
-  2
-  3
-  4
-  5
-  6
-  7
-  8
-  9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
- 37
- 38
- 39
- 40
- 41
- 42
- 43
- 44
- 45
- 46
- 47
- 48
- 49
- 50
- 51
- 52
- 53
- 54
- 55
- 56
- 57
- 58
- 59
- 60
- 61
- 62
- 63
- 64
- 65
- 66
- 67
- 68
- 69
- 70
- 71
- 72
- 73
- 74
- 75
- 76
- 77
- 78
- 79
- 80
- 81
- 82
- 83
- 84
- 85
- 86
- 87
- 88
- 89
- 90
- 91
- 92
- 93
- 94
- 95
- 96
- 97
- 98
- 99
-100
-101
-102
-103
-104
-105
-106
-107
-108
-109
-110
-111
-112
-113
-114
-115
-116
-117
-118
-119
-120
-121
-122
-123
-124
-125
-126
-127
-128
-129
-130
-131
-132
-133
-134
-135
-136
-137
-138
-139
-140
-141
-142
-143
-144
-145
-146
-147
-148
-149
-150
-151
-152
-153
-154
-155
-156
-157
-158
-159
-160
-161
-162
-163
-164
-165
-166
-167
-168
-169
-170
-171
-172
-173
-174
-175
-176
-177
-178
-179
-180
-181
-182
-183
-184
-185
-186
-187
-188
-189
-190
-191
-192
-193
-194
-195
-196
-197
-198
-199
-200
-201
-202
-203
-204
-205
-206
-207
-208
-209
-210
-211
-212
-213
-214
-215
-216
-217
-218
-219
-220
-221
-222
-223
-224
-225
-226
-227
-228
-229
-230
-231
-232
-233
-234
-235
-236
-237
-238
-239
-240
-241
-242
-243
-244
-245
-246
-247
-248
-249
-250
-251
-252
-253
-254
-255
-256
-257
-258
-259
-260
-261
-262
-263
-264
-265
-266
-267
-268
-269
-270
-271
-272
-273
-274
-275
-276
-277
-278
-279
-280
-281
-282
-283
-284
-285
-286
-287
-288
-289
-290
-291
-292
-293
-294
-295
-296
-297
-298
-299
-300
-301
-302
-303
-304
-305
-306
-307
-308
-309
-310
-311
-312
-313
-314
-315
-316
-317
-318
-319
-320
-321
-322
-323
-324
-325
-326
-327
-328
-329
-330
-331
-332
-333
-334
-335
-336
-337
-338
-339
-340
-341
-342
-343
-344
-345
-346
-347
-348
-349
-350
-351
-352
-353
-354
-355
-356
-357
-358
-359
-360
-361
-362
-363
-364
-365
-366
-367
-368
-369
-370
-371
-372
-373
-374
-375
-376
-377
-378
-379
-380
-381
-382
-383
-384
-385
-386
-387
-388
-389
-390
-391
-392
-393
-394
-395
-396
-397
-398
-399
-400
-401
-402
-403
-404
-405
-406
-407
-408
-409
-410
-411
-412
-413
-414
-415
-416
-417
-418
-419
-420
-421
-422
-423
-424
-425
-426
-427
-428
-429
-430
-431
-432
-433
-434
-435
-436
-437
-438
-439
-440
-441
-442
-443
-444
-445
-446
-447
-448
-449
-450
-451
-452
-453
-454
-455
-456
-457
-458
-459
-460
-461
-462
-463
-464
-465
-466
-467
-468
-469
-470
-471
-472
-473
-474
-475
-476
-477
-478
-479
-480
-481
-482
-483
-484
-485
-486
-487
-488
-489
-490
-491
-492
-493
-494
-495
-496
-497
-498
-499
-500
-501
-502
-503
-504
-505
-506
-507
-508
-509
-510
-511
-512
-513
-514
-515
-516
-517
-518
-519
-520
-521
-522
-523
-524
-525
-526
-527
-528
-529
-530
-531
-532
-533
-534
-535
-536
-537
-538
-539
-540
-541
-542
-543
-544
-545
-546
-547
-548
-549
-550
-551
-552
-553
-554
-555
-556
-557
-558
-559
-560
-561
-562
-563
-564
-565
-566
-567
-568
-569
-570
-571
-572
-573
-574
-575
-576
-577
-578
-579
-580
-581
-582
-583
-584
-585
-586
-587
-588
-589
-590
-591
-592
-593
-594
-595
-596
-597
-598
-599
-600
-601
-602
-603
-604
-605
-606
-607
-608
-609
-610
-611
-612
-613
-614
-615
-616
-617
-618
-619
-620
-621
-622
-623
-624
-625
-626
-627
-628
-629
-630
-631
-632
-633
-634
-635
-636
-637
-638
-639
-640
-641
-642
-643
-644
-645
-646
-647
-648
-649
-650
-651
-652
-653
-654
-655
-656
-657
-658
-659
-660
-661
-662
-663
-664
-665
-666
-667
-668
-669
-670
-671
-672
-673
-674
-675
-676
-677
-678
-679
-680
-681
-682
-683
-684
-685
-686
-687
-688
-689
-690
-691
-692
-693
-694
-695
-696
-697
-698
-699
-700
-701
-702
-703
-704
-705
-706
-707
-708
-709
-710
-711
-712
-713
-714
-715
-716
-717
-718
-719
-720
-721
-722
-723
-724
-725
// *****************************************************************************
+
   1
+   2
+   3
+   4
+   5
+   6
+   7
+   8
+   9
+  10
+  11
+  12
+  13
+  14
+  15
+  16
+  17
+  18
+  19
+  20
+  21
+  22
+  23
+  24
+  25
+  26
+  27
+  28
+  29
+  30
+  31
+  32
+  33
+  34
+  35
+  36
+  37
+  38
+  39
+  40
+  41
+  42
+  43
+  44
+  45
+  46
+  47
+  48
+  49
+  50
+  51
+  52
+  53
+  54
+  55
+  56
+  57
+  58
+  59
+  60
+  61
+  62
+  63
+  64
+  65
+  66
+  67
+  68
+  69
+  70
+  71
+  72
+  73
+  74
+  75
+  76
+  77
+  78
+  79
+  80
+  81
+  82
+  83
+  84
+  85
+  86
+  87
+  88
+  89
+  90
+  91
+  92
+  93
+  94
+  95
+  96
+  97
+  98
+  99
+ 100
+ 101
+ 102
+ 103
+ 104
+ 105
+ 106
+ 107
+ 108
+ 109
+ 110
+ 111
+ 112
+ 113
+ 114
+ 115
+ 116
+ 117
+ 118
+ 119
+ 120
+ 121
+ 122
+ 123
+ 124
+ 125
+ 126
+ 127
+ 128
+ 129
+ 130
+ 131
+ 132
+ 133
+ 134
+ 135
+ 136
+ 137
+ 138
+ 139
+ 140
+ 141
+ 142
+ 143
+ 144
+ 145
+ 146
+ 147
+ 148
+ 149
+ 150
+ 151
+ 152
+ 153
+ 154
+ 155
+ 156
+ 157
+ 158
+ 159
+ 160
+ 161
+ 162
+ 163
+ 164
+ 165
+ 166
+ 167
+ 168
+ 169
+ 170
+ 171
+ 172
+ 173
+ 174
+ 175
+ 176
+ 177
+ 178
+ 179
+ 180
+ 181
+ 182
+ 183
+ 184
+ 185
+ 186
+ 187
+ 188
+ 189
+ 190
+ 191
+ 192
+ 193
+ 194
+ 195
+ 196
+ 197
+ 198
+ 199
+ 200
+ 201
+ 202
+ 203
+ 204
+ 205
+ 206
+ 207
+ 208
+ 209
+ 210
+ 211
+ 212
+ 213
+ 214
+ 215
+ 216
+ 217
+ 218
+ 219
+ 220
+ 221
+ 222
+ 223
+ 224
+ 225
+ 226
+ 227
+ 228
+ 229
+ 230
+ 231
+ 232
+ 233
+ 234
+ 235
+ 236
+ 237
+ 238
+ 239
+ 240
+ 241
+ 242
+ 243
+ 244
+ 245
+ 246
+ 247
+ 248
+ 249
+ 250
+ 251
+ 252
+ 253
+ 254
+ 255
+ 256
+ 257
+ 258
+ 259
+ 260
+ 261
+ 262
+ 263
+ 264
+ 265
+ 266
+ 267
+ 268
+ 269
+ 270
+ 271
+ 272
+ 273
+ 274
+ 275
+ 276
+ 277
+ 278
+ 279
+ 280
+ 281
+ 282
+ 283
+ 284
+ 285
+ 286
+ 287
+ 288
+ 289
+ 290
+ 291
+ 292
+ 293
+ 294
+ 295
+ 296
+ 297
+ 298
+ 299
+ 300
+ 301
+ 302
+ 303
+ 304
+ 305
+ 306
+ 307
+ 308
+ 309
+ 310
+ 311
+ 312
+ 313
+ 314
+ 315
+ 316
+ 317
+ 318
+ 319
+ 320
+ 321
+ 322
+ 323
+ 324
+ 325
+ 326
+ 327
+ 328
+ 329
+ 330
+ 331
+ 332
+ 333
+ 334
+ 335
+ 336
+ 337
+ 338
+ 339
+ 340
+ 341
+ 342
+ 343
+ 344
+ 345
+ 346
+ 347
+ 348
+ 349
+ 350
+ 351
+ 352
+ 353
+ 354
+ 355
+ 356
+ 357
+ 358
+ 359
+ 360
+ 361
+ 362
+ 363
+ 364
+ 365
+ 366
+ 367
+ 368
+ 369
+ 370
+ 371
+ 372
+ 373
+ 374
+ 375
+ 376
+ 377
+ 378
+ 379
+ 380
+ 381
+ 382
+ 383
+ 384
+ 385
+ 386
+ 387
+ 388
+ 389
+ 390
+ 391
+ 392
+ 393
+ 394
+ 395
+ 396
+ 397
+ 398
+ 399
+ 400
+ 401
+ 402
+ 403
+ 404
+ 405
+ 406
+ 407
+ 408
+ 409
+ 410
+ 411
+ 412
+ 413
+ 414
+ 415
+ 416
+ 417
+ 418
+ 419
+ 420
+ 421
+ 422
+ 423
+ 424
+ 425
+ 426
+ 427
+ 428
+ 429
+ 430
+ 431
+ 432
+ 433
+ 434
+ 435
+ 436
+ 437
+ 438
+ 439
+ 440
+ 441
+ 442
+ 443
+ 444
+ 445
+ 446
+ 447
+ 448
+ 449
+ 450
+ 451
+ 452
+ 453
+ 454
+ 455
+ 456
+ 457
+ 458
+ 459
+ 460
+ 461
+ 462
+ 463
+ 464
+ 465
+ 466
+ 467
+ 468
+ 469
+ 470
+ 471
+ 472
+ 473
+ 474
+ 475
+ 476
+ 477
+ 478
+ 479
+ 480
+ 481
+ 482
+ 483
+ 484
+ 485
+ 486
+ 487
+ 488
+ 489
+ 490
+ 491
+ 492
+ 493
+ 494
+ 495
+ 496
+ 497
+ 498
+ 499
+ 500
+ 501
+ 502
+ 503
+ 504
+ 505
+ 506
+ 507
+ 508
+ 509
+ 510
+ 511
+ 512
+ 513
+ 514
+ 515
+ 516
+ 517
+ 518
+ 519
+ 520
+ 521
+ 522
+ 523
+ 524
+ 525
+ 526
+ 527
+ 528
+ 529
+ 530
+ 531
+ 532
+ 533
+ 534
+ 535
+ 536
+ 537
+ 538
+ 539
+ 540
+ 541
+ 542
+ 543
+ 544
+ 545
+ 546
+ 547
+ 548
+ 549
+ 550
+ 551
+ 552
+ 553
+ 554
+ 555
+ 556
+ 557
+ 558
+ 559
+ 560
+ 561
+ 562
+ 563
+ 564
+ 565
+ 566
+ 567
+ 568
+ 569
+ 570
+ 571
+ 572
+ 573
+ 574
+ 575
+ 576
+ 577
+ 578
+ 579
+ 580
+ 581
+ 582
+ 583
+ 584
+ 585
+ 586
+ 587
+ 588
+ 589
+ 590
+ 591
+ 592
+ 593
+ 594
+ 595
+ 596
+ 597
+ 598
+ 599
+ 600
+ 601
+ 602
+ 603
+ 604
+ 605
+ 606
+ 607
+ 608
+ 609
+ 610
+ 611
+ 612
+ 613
+ 614
+ 615
+ 616
+ 617
+ 618
+ 619
+ 620
+ 621
+ 622
+ 623
+ 624
+ 625
+ 626
+ 627
+ 628
+ 629
+ 630
+ 631
+ 632
+ 633
+ 634
+ 635
+ 636
+ 637
+ 638
+ 639
+ 640
+ 641
+ 642
+ 643
+ 644
+ 645
+ 646
+ 647
+ 648
+ 649
+ 650
+ 651
+ 652
+ 653
+ 654
+ 655
+ 656
+ 657
+ 658
+ 659
+ 660
+ 661
+ 662
+ 663
+ 664
+ 665
+ 666
+ 667
+ 668
+ 669
+ 670
+ 671
+ 672
+ 673
+ 674
+ 675
+ 676
+ 677
+ 678
+ 679
+ 680
+ 681
+ 682
+ 683
+ 684
+ 685
+ 686
+ 687
+ 688
+ 689
+ 690
+ 691
+ 692
+ 693
+ 694
+ 695
+ 696
+ 697
+ 698
+ 699
+ 700
+ 701
+ 702
+ 703
+ 704
+ 705
+ 706
+ 707
+ 708
+ 709
+ 710
+ 711
+ 712
+ 713
+ 714
+ 715
+ 716
+ 717
+ 718
+ 719
+ 720
+ 721
+ 722
+ 723
+ 724
+ 725
+ 726
+ 727
+ 728
+ 729
+ 730
+ 731
+ 732
+ 733
+ 734
+ 735
+ 736
+ 737
+ 738
+ 739
+ 740
+ 741
+ 742
+ 743
+ 744
+ 745
+ 746
+ 747
+ 748
+ 749
+ 750
+ 751
+ 752
+ 753
+ 754
+ 755
+ 756
+ 757
+ 758
+ 759
+ 760
+ 761
+ 762
+ 763
+ 764
+ 765
+ 766
+ 767
+ 768
+ 769
+ 770
+ 771
+ 772
+ 773
+ 774
+ 775
+ 776
+ 777
+ 778
+ 779
+ 780
+ 781
+ 782
+ 783
+ 784
+ 785
+ 786
+ 787
+ 788
+ 789
+ 790
+ 791
+ 792
+ 793
+ 794
+ 795
+ 796
+ 797
+ 798
+ 799
+ 800
+ 801
+ 802
+ 803
+ 804
+ 805
+ 806
+ 807
+ 808
+ 809
+ 810
+ 811
+ 812
+ 813
+ 814
+ 815
+ 816
+ 817
+ 818
+ 819
+ 820
+ 821
+ 822
+ 823
+ 824
+ 825
+ 826
+ 827
+ 828
+ 829
+ 830
+ 831
+ 832
+ 833
+ 834
+ 835
+ 836
+ 837
+ 838
+ 839
+ 840
+ 841
+ 842
+ 843
+ 844
+ 845
+ 846
+ 847
+ 848
+ 849
+ 850
+ 851
+ 852
+ 853
+ 854
+ 855
+ 856
+ 857
+ 858
+ 859
+ 860
+ 861
+ 862
+ 863
+ 864
+ 865
+ 866
+ 867
+ 868
+ 869
+ 870
+ 871
+ 872
+ 873
+ 874
+ 875
+ 876
+ 877
+ 878
+ 879
+ 880
+ 881
+ 882
+ 883
+ 884
+ 885
+ 886
+ 887
+ 888
+ 889
+ 890
+ 891
+ 892
+ 893
+ 894
+ 895
+ 896
+ 897
+ 898
+ 899
+ 900
+ 901
+ 902
+ 903
+ 904
+ 905
+ 906
+ 907
+ 908
+ 909
+ 910
+ 911
+ 912
+ 913
+ 914
+ 915
+ 916
+ 917
+ 918
+ 919
+ 920
+ 921
+ 922
+ 923
+ 924
+ 925
+ 926
+ 927
+ 928
+ 929
+ 930
+ 931
+ 932
+ 933
+ 934
+ 935
+ 936
+ 937
+ 938
+ 939
+ 940
+ 941
+ 942
+ 943
+ 944
+ 945
+ 946
+ 947
+ 948
+ 949
+ 950
+ 951
+ 952
+ 953
+ 954
+ 955
+ 956
+ 957
+ 958
+ 959
+ 960
+ 961
+ 962
+ 963
+ 964
+ 965
+ 966
+ 967
+ 968
+ 969
+ 970
+ 971
+ 972
+ 973
+ 974
+ 975
+ 976
+ 977
+ 978
+ 979
+ 980
+ 981
+ 982
+ 983
+ 984
+ 985
+ 986
+ 987
+ 988
+ 989
+ 990
+ 991
+ 992
+ 993
+ 994
+ 995
+ 996
+ 997
+ 998
+ 999
+1000
+1001
+1002
+1003
+1004
+1005
+1006
+1007
+1008
+1009
+1010
+1011
+1012
+1013
+1014
+1015
+1016
+1017
+1018
+1019
+1020
+1021
+1022
+1023
+1024
+1025
+1026
+1027
+1028
+1029
+1030
+1031
+1032
+1033
+1034
+1035
+1036
+1037
+1038
+1039
+1040
+1041
+1042
+1043
+1044
+1045
+1046
+1047
+1048
+1049
+1050
+1051
+1052
+1053
+1054
// *****************************************************************************
 /*!
-  \file      src/Base/Data.hpp
+  \file      src/IO/ExodusIIMeshReader.cpp
   \copyright 2012-2015 J. Bakosi,
              2016-2018 Los Alamos National Security, LLC.,
              2019-2021 Triad National Security, LLC.
              All rights reserved. See the LICENSE file for details.
-  \brief     Generic data storage with different memory layouts
-  \details   Generic data storage with different memory layouts. See also the
-    rationale discussed in the [design](layout.html) document.
-*/
-// *****************************************************************************
-#ifndef Data_h
-#define Data_h
-
-#include <array>
-#include <string>
-#include <cstdint>
-#include <vector>
-#include <set>
-#include <algorithm>
+  \brief     ExodusII mesh reader
+  \details   ExodusII mesh reader class definition.
+*/
+// *****************************************************************************
+
+#include <numeric>
+
+#include "NoWarning/exodusII.hpp"
+
+#include "ExodusIIMeshReader.hpp"
+#include "ContainerUtil.hpp"
+#include "Exception.hpp"
+#include "UnsMesh.hpp"
+#include "Reorder.hpp"
 
-#include "Types.hpp"
-#include "Exception.hpp"
-
-#include "NoWarning/pup_stl.hpp"
-
-namespace tk {
-
-//! Tags for selecting data layout policies
-const uint8_t UnkEqComp = 0;
-const uint8_t EqCompUnk = 1;
-
-//! Zero-runtime-cost data-layout wrappers with type-based compile-time dispatch
-template< uint8_t Layout >
-class Data {
-
-  private:
-    //! \brief Inherit type of number of components from keyword 'ncomp'
-    using ncomp_t = tk::ncomp_t;
-
-  public:
-    //! Default constructor (required for Charm++ migration)
-    explicit Data() : m_vec(), m_nunk(), m_nprop() {}
-
-    //! Constructor
-    //! \param[in] nu Number of unknowns to allocate memory for
-    //! \param[in] np Total number of properties, i.e., scalar variables or
-    //!   components, per unknown
-    explicit Data( ncomp_t nu, ncomp_t np ) :
-      m_vec( nu*np ),
-      m_nunk( nu ),
-      m_nprop( np ) {}
-
-    //! Const data access dispatch
-    //! \details Public interface to const-ref data access to a single real
-    //!   value. Use it as Data(p,c), where p is the unknown index, and c is
-    //!   the component index specifying the scalar equation within a system of
-    //!   equations. Requirement: component <
-    //!   nprop, unknown < nunk, enforced with an assert in DEBUG mode, see also
-    //!   the constructor.
-    //! \param[in] unknown Unknown index
-    //! \param[in] component Component index, i.e., position of a scalar within
-    //!   a system
-    //! \return Const reference to data of type tk::real
-    const tk::real&
-    operator()( ncomp_t unknown, ncomp_t component ) const
-    { return access( unknown, component, int2type< Layout >() ); }
-
-    //! Non-const data access dispatch
-    //! \details Public interface to non-const-ref data access to a single real
-    //!   value. Use it as Data(p,c), where p is the unknown index, and c is
-    //!   the component index specifying the scalar equation within a system of
-    //!   equations. Requirement: component <
-    //!   nprop, unknown < nunk, enforced with an assert in DEBUG mode, see also
-    //!   the constructor.
-    //! \param[in] unknown Unknown index
-    //! \param[in] component Component index, i.e., position of a scalar within
-    //!   a system
-    //! \return Non-const reference to data of type tk::real
-    //! \see "Avoid Duplication in const and Non-const Member Function," and
-    //!   "Use const whenever possible," Scott Meyers, Effective C++, 3d ed.
-    tk::real&
-    operator()( ncomp_t unknown, ncomp_t component ) {
-      return const_cast< tk::real& >(
-               static_cast< const Data& >( *this ).
-                 operator()( unknown, component ) );
-    }
-
-    //! Const ptr to physical variable access dispatch
-    //! \details Public interface to the first half of a physical variable
-    //!   access. cptr() and var() are two member functions intended to be used
-    //!   together in case when component would be expensive to
-    //!   compute for data access via the function call operator, i.e., cptr()
-    //!   can be used to pre-compute part of the address, which returns a
-    //!   pointer and var() can be used to finish the data access using the
-    //!   pointer returned by cptr(). In other words, cptr() returns part of the
-    //!   address known based on component and intended to be used in
-    //!   a setup phase. Then var() takes this partial address and finishes the
-    //!   address calculation given the unknown id. Thus the following two data
-    //!   accesses are equivalent (modulo constness):
-    //!   * real& value = operator()( unk, comp ); and
-    //!   * const real* p = cptr( comp ); and
-    //!     const real& value = var( p, unk ); or real& value = var( p, unk );
-    //!   Requirement: component < nprop, enforced with an assert in
-    //!   DEBUG mode, see also the constructor.
-    //! \param[in] component Component index, i.e., position of a scalar within
-    //!   a system
-    //! \return Pointer to data of type tk::real for use with var()
-    //! \see Example client code in Statistics::setupOrdinary() and
-    //!   Statistics::accumulateOrd() in Statistics/Statistics.C.
-    const tk::real*
-    cptr( ncomp_t component ) const
-    { return cptr( component, int2type< Layout >() ); }
-
-    //! Const-ref data-access dispatch
-    //! \details Public interface to the second half of a physical variable
-    //!   access. cptr() and var() are two member functions intended to be used
-    //!   together in case when component would be expensive to
-    //!   compute for data access via the function call operator, i.e., cptr()
-    //!   can be used to pre-compute part of the address, which returns a
-    //!   pointer and var() can be used to finish the data access using the
-    //!   pointer returned by cptr(). In other words, cptr() returns part of the
-    //!   address known based on component and intended to be used in
-    //!   a setup phase. Then var() takes this partial address and finishes the
-    //!   address calculation given the unknown id. Thus the following two data
-    //!   accesses are equivalent (modulo constness):
-    //!   * real& value = operator()( unk, comp ); and
-    //!   * const real* p = cptr( comp ); and
-    //!     const real& value = var( p, unk ); or real& value = var( p, unk );
-    //!   Requirement: unknown < nunk, enforced with an assert in DEBUG mode,
-    //!   see also the constructor.
-    //! \param[in] pt Pointer to data of type tk::real as returned from cptr()
-    //! \param[in] unknown Unknown index
-    //! \return Const reference to data of type tk::real
-    //! \see Example client code in Statistics::setupOrdinary() and
-    //!   Statistics::accumulateOrd() in Statistics/Statistics.C.
-    const tk::real&
-    var( const tk::real* pt, ncomp_t unknown ) const
-    { return var( pt, unknown, int2type< Layout >() ); }
-
-    //! Non-const-ref data-access dispatch
-    //! \details Public interface to the second half of a physical variable
-    //!   access. cptr() and var() are two member functions intended to be used
-    //!   together in case when component would be expensive to
-    //!   compute for data access via the function call operator, i.e., cptr()
-    //!   can be used to pre-compute part of the address, which returns a
-    //!   pointer and var() can be used to finish the data access using the
-    //!   pointer returned by cptr(). In other words, cptr() returns part of the
-    //!   address known based on component and intended to be used in
-    //!   a setup phase. Then var() takes this partial address and finishes the
-    //!   address calculation given the unknown id. Thus the following two data
-    //!   accesses are equivalent (modulo constness):
-    //!   * real& value = operator()( unk, comp ); and
-    //!   * const real* p = cptr( comp ); and
-    //!     const real& value = var( p, unk ); or real& value = var( p, unk );
-    //!   Requirement: unknown < nunk, enforced with an assert in DEBUG mode,
-    //!   see also the constructor.
-    //! \param[in] pt Pointer to data of type tk::real as returned from cptr()
-    //! \param[in] unknown Unknown index
-    //! \return Non-const reference to data of type tk::real
-    //! \see Example client code in Statistics::setupOrdinary() and
-    //!   Statistics::accumulateOrd() in Statistics/Statistics.C.
-    //! \see "Avoid Duplication in const and Non-const Member Function," and
-    //!   "Use const whenever possible," Scott Meyers, Effective C++, 3d ed.
-    tk::real&
-    var( const tk::real* pt, ncomp_t unknown ) {
-      return const_cast< tk::real& >(
-               static_cast< const Data& >( *this ).var( pt, unknown ) );
-    }
-
-    //! Access to number of unknowns
-    //! \return Number of unknowns
-    ncomp_t nunk() const noexcept { return m_nunk; }
-
-    //! Access to number of properties
-    //! \details This is the total number of scalar components per unknown
-    //! \return Number of propertes/unknown
-    ncomp_t nprop() const noexcept { return m_nprop; }
-
-    //! Extract flat vector of all unknowns
-    //! \return Flat vector of reals
-    std::vector< tk::real >
-    flat() const {
-      std::vector< tk::real > w( m_nunk * m_nprop );
-      for (std::size_t j=0; j<m_nprop; ++j)
-        for (std::size_t i=0; i<m_nunk; ++i)
-          w[i*m_nprop+j] = operator()( i, j );
-      return w;
-    }
+using tk::ExodusIIMeshReader;
+
+ExodusIIMeshReader::ExodusIIMeshReader( const std::string& filename,<--- Member variable 'ExodusIIMeshReader::m_nelem' is not initialized in the constructor.
+                                        int cpuwordsize,
+                                        int iowordsize ) :
+  m_filename( filename ),
+  m_cpuwordsize( cpuwordsize ),
+  m_iowordsize( iowordsize ),
+  m_inFile( 0 ),
+  m_nnode( 0 ),
+  m_neblk( 0 ),
+  m_neset( 0 ),
+  m_from( 0 ),
+  m_till( 0 ),
+  m_blockid(),
+  m_blockid_by_type( ExoNnpe.size() ),
+  m_nel( ExoNnpe.size() ),
+  m_elemblocks(),
+  m_tri()
+// *****************************************************************************
+//  Constructor: open Exodus II file
+//! \param[in] filename File to open as ExodusII file
+//! \param[in] cpuwordsize Set CPU word size, see ExodusII documentation
+//! \param[in] iowordsize Set I/O word size, see ExodusII documentation
+// *****************************************************************************
+{
+  // Increase verbosity from ExodusII library in debug mode
+  #ifndef NDEBUG
+  ex_opts( EX_DEBUG | EX_VERBOSE );
+  #endif
+
+  float version;
+
+  m_inFile = ex_open( filename.c_str(), EX_READ, &cpuwordsize, &iowordsize,
+                      &version );
+
+  // output exodusII/netcdf configuration
+  //ex_print_config();
+
+  ErrChk( m_inFile > 0, "Failed to open ExodusII file: " + filename );
+}
+
+ExodusIIMeshReader::~ExodusIIMeshReader() noexcept
+// *****************************************************************************
+//  Destructor
+// *****************************************************************************
+{
+  if ( ex_close(m_inFile) < 0 )
+    printf( ">>> WARNING: Failed to close ExodusII file: %s\n",
+            m_filename.c_str() );
+}
+
+void
+ExodusIIMeshReader::readMesh( UnsMesh& mesh )
+// *****************************************************************************
+//  Read ExodusII mesh file
+//! \param[in] mesh Unstructured mesh object
+// *****************************************************************************
+{
+  readHeader( mesh );
+  readAllElements( mesh );
+  readAllNodes( mesh );
+  readSidesetFaces( mesh.bface(), mesh.faceid() );
+  readTimeValues( mesh.vartimes() );
+  readNodeVarNames( mesh.nodevarnames() );
+  readElemVarNames( mesh.elemvarnames() );
+  readNodeScalars( mesh.vartimes().size(),
+                   mesh.nodevarnames().size(),
+                   mesh.nodevars() );
+  readElemScalars( mesh.vartimes().size(),
+                   mesh.elemvarnames().size(),
+                   mesh.elemvars() );
+}
+
+void
+ExodusIIMeshReader::readGraph( UnsMesh& mesh )
+// *****************************************************************************
+//  Read only connectivity graph from file
+//! \param[in] mesh Unstructured mesh object
+// *****************************************************************************
+{
+  readHeader( mesh );
+  readAllElements( mesh );
+}
+
+void
+ExodusIIMeshReader::readMeshPart(
+  std::vector< std::size_t >& ginpoel,
+  std::vector< std::size_t >& inpoel,
+  std::vector< std::size_t >& triinp,
+  std::unordered_map< std::size_t, std::size_t >& lid,
+  tk::UnsMesh::Coords& coord,
+  std::unordered_map< std::size_t, std::set< std::size_t > >& elemBlockId,
+  int numpes, int mype )
+// *****************************************************************************
+//  Read a part of the mesh (graph and coordinates) from ExodusII file
+//! \param[in,out] ginpoel Container to store element connectivity of this PE's
+//!   chunk of the mesh (global ids)
+//! \param[in,out] inpoel Container to store element connectivity with local
+//!   node IDs of this PE's mesh chunk
+//! \param[in,out] triinp Container to store triangle element connectivity
+//!   (if exists in file) with global node indices
+//! \param[in,out] lid Container to store global->local node IDs of elements of
+//!   this PE's mesh chunk
+//! \param[in,out] coord Container to store coordinates of mesh nodes of this
+//!   PE's mesh chunk
+//! \param[in,out] elemBlockId List of elements for each block-id.
+//! \param[in] numpes Total number of PEs (default n = 1, for a single-CPU read)
+//! \param[in] mype This PE (default m = 0, for a single-CPU read)
+// *****************************************************************************
+{
+  Assert( mype < numpes, "Invalid input: PE id must be lower than NumPEs" );
+  Assert( ginpoel.empty() && inpoel.empty() && lid.empty() &&
+          coord[0].empty() && coord[1].empty() && coord[2].empty(),
+          "Containers to store mesh must be empty" );
+
+  // Read info on element blocks from ExodusII file
+  readElemBlockIDs();
+  // Get number of number of tetrahedron elements in file
+  auto nel = nelem( tk::ExoElemType::TET );
+
+  // Compute extents of element IDs of this PE's mesh chunk to read
+  auto npes = static_cast< std::size_t >( numpes );
+  auto pe = static_cast< std::size_t >( mype );
+  auto chunk = nel / npes;
+  m_from = pe * chunk;
+  m_till = m_from + chunk;
+  if (pe == npes-1) m_till += nel % npes;
+
+  // Read tetrahedron connectivity between from and till
+  readElements( {{m_from, m_till-1}}, tk::ExoElemType::TET, ginpoel );
+  elemBlockId = m_elemInBlockId;
+
+  // Compute local data from global mesh connectivity
+  std::vector< std::size_t > gid;
+  std::tie( inpoel, gid, lid ) = tk::global2local( ginpoel );
+
+  // Read this PE's chunk of the mesh node coordinates from file
+  coord = readCoords( gid );
+
+  // Generate set of unique faces
+  tk::UnsMesh::FaceSet faces;
+  for (std::size_t e=0; e<ginpoel.size()/4; ++e)
+    for (std::size_t f=0; f<4; ++f) {
+      const auto& tri = tk::expofa[f];
+      faces.insert( {{{ ginpoel[ e*4+tri[0] ],
+                        ginpoel[ e*4+tri[1] ],
+                        ginpoel[ e*4+tri[2] ] }}} );
+    }
+
+  // Read triangle element connectivity (all triangle blocks in file)
+  auto ntri = nelem( tk::ExoElemType::TRI );
+  if ( ntri !=0 ) readElements( {{0,ntri-1}}, tk::ExoElemType::TRI, triinp );
+
+  // Keep triangles shared in (partially-read) tetrahedron mesh
+  std::vector< std::size_t > triinp_own;
+  std::size_t ltrid = 0;        // local triangle id
+  for (std::size_t e=0; e<triinp.size()/3; ++e) {
+    auto i = faces.find( {{ triinp[e*3+0], triinp[e*3+1], triinp[e*3+2] }} );
+    if (i != end(faces)) {
+      m_tri[e] = ltrid++;       // generate global->local triangle ids
+      triinp_own.push_back( triinp[e*3+0] );
+      triinp_own.push_back( triinp[e*3+1] );
+      triinp_own.push_back( triinp[e*3+2] );
+    }
+  }
+  triinp = std::move(triinp_own);
+}
 
-    //! Assign from flat vector
-    //! \param[in] rhs Flat vector to assign from
-    //! \note This is the opposite of flat().
-    void operator=( const std::vector< tk::real >& rhs ) {
-      Assert( rhs.size() == m_nunk * m_nprop, "Size mismatch" );
-      for (std::size_t j=0; j<m_nprop; ++j)
-        for (std::size_t i=0; i<m_nunk; ++i)
-          operator()( i, j ) = rhs[i*m_nprop+j];
-    }
-
-    //! Assign from array(3) of vectors
-    //! \param[in] rhs Array(3) of vectors to assign from
-    void operator=( const std::array< std::vector< tk::real >, 3 >& rhs ) {
-      Assert( m_nprop == 3, "Size mismatch" );
-      Assert( rhs[0].size() == m_nunk, "Size mismatch" );
-      Assert( rhs[1].size() == m_nunk, "Size mismatch" );
-      Assert( rhs[2].size() == m_nunk, "Size mismatch" );
-      for (std::size_t j=0; j<3; ++j)
-        for (std::size_t i=0; i<m_nunk; ++i)
-          operator()( i, j ) = rhs[j][i];
-    }
+std::array< std::vector< tk::real >, 3 >
+ExodusIIMeshReader::readCoords( const std::vector< std::size_t >& gid ) const
+// *****************************************************************************
+//  Read coordinates of a number of mesh nodes from ExodusII file
+//! \param[in] gid Global node IDs whose coordinates to read
+//! \return Vector of node coordinates read from file
+// *****************************************************************************
+{
+  // Read node coordinates from file with global node IDs given in gid
+  return readNodes( gid );
+}
+
+std::size_t
+ExodusIIMeshReader::readHeader()
+// *****************************************************************************
+//  Read ExodusII header without setting mesh size
+//! \return Number of nodes in mesh
+// *****************************************************************************
+{
+  char title[MAX_LINE_LENGTH+1];
+  int ndim, nelem, nnodeset, nelemset, nnode, neblk;
 
-    //! Extract vector of unknowns given component
-    //! \details Requirement: component < nprop, enforced with an
-    //!   assert in DEBUG mode, see also the constructor.
-    //! \param[in] component Component index, i.e., position of a scalar within
-    //!   a system
-    //! \return A vector of unknowns given by component (length:
-    //!   nunk(), i.e., the first constructor argument)
-    std::vector< tk::real >
-    extract_comp( ncomp_t component ) const {
-      std::vector< tk::real > w( m_nunk );
-      for (ncomp_t i=0; i<m_nunk; ++i)
-        w[i] = operator()( i, component );
-      return w;
-    }
-
-    //! Extract (a copy of) all components for an unknown
-    //! \details Requirement: unknown < nunk, enforced with an assert in DEBUG
-    //!   mode, see also the constructor.
-    //! \param[in] unknown Index of unknown
-    //! \return A vector of components for a single unknown (length: nprop,
-    //!   i.e., the second constructor argument)
-    std::vector< tk::real >
-    extract( ncomp_t unknown ) const {
-      std::vector< tk::real > w( m_nprop );
-      for (ncomp_t i=0; i<m_nprop; ++i) w[i] = operator()( unknown, i );
-      return w;
-    }
-
-    //! Extract all components for unknown
-    //! \details Requirement: unknown < nunk, enforced with an assert in DEBUG
-    //!   mode, see also the constructor.
-    //! \param[in] unknown Index of unknown
-    //! \return A vector of components for a single unknown (length: nprop,
-    //!   i.e., the second constructor argument)
-    //! \note This is simply an alias for extract( unknown )
-    std::vector< tk::real >
-    operator[]( ncomp_t unknown ) const { return extract( unknown ); }
-
-    //! Extract (a copy of) four values of unknowns
-    //! \details Requirement: component < nprop, [A,B,C,D] < nunk,
-    //!   enforced with an assert in DEBUG mode, see also the constructor.
-    //! \param[in] component Component index, i.e., position of a scalar within
-    //!   a system
-    //! \param[in] A Index of 1st unknown
-    //! \param[in] B Index of 2nd unknown
-    //! \param[in] C Index of 3rd unknown
-    //! \param[in] D Index of 4th unknown
-    //! \return Array of the four values of component
-    std::array< tk::real, 4 >
-    extract( ncomp_t component,
-             ncomp_t A, ncomp_t B, ncomp_t C, ncomp_t D ) const
-    {
-      auto p = cptr( component );
-      return {{ var(p,A), var(p,B), var(p,C), var(p,D) }};
-    }
-
-    //! Extract (a copy of) four values of unknowns
-    //! \details Requirement: component < nprop, for all N[i] < nunk,
-    //!   enforced with an assert in DEBUG mode, see also the constructor.
-    //! \param[in] component Component index, i.e., position of a scalar within
-    //!   a system
-    //! \param[in] N Indices of the 4 unknowns
-    //! \return Array of the four values of component
-    std::array< tk::real, 4 >
-    extract( ncomp_t component,
-             const std::array< ncomp_t, 4 >& N ) const
-    {
-      return extract( component, N[0], N[1], N[2], N[3] );
-    }
-
-    //! Extract (a copy of) three values of unknowns
-    //! \details Requirement: component < nprop, [A,B,C] < nunk,
-    //!   enforced with an assert in DEBUG mode, see also the constructor.
-    //! \param[in] component Component index, i.e., position of a scalar within
-    //!   a system
-    //! \param[in] A Index of 1st unknown
-    //! \param[in] B Index of 2nd unknown
-    //! \param[in] C Index of 3rd unknown
-    //! \return Array of the four values of component
-    std::array< tk::real, 3 >
-    extract( ncomp_t component,
-             ncomp_t A, ncomp_t B, ncomp_t C ) const
-    {
-      auto p = cptr( component );
-      return {{ var(p,A), var(p,B), var(p,C) }};
-    }
-
-    //! Extract (a copy of) three values of unknowns
-    //! \details Requirement: component < nprop, for all N[i] < nunk,
-    //!   enforced with an assert in DEBUG mode, see also the constructor.
-    //! \param[in] component Component index, i.e., position of a scalar within
-    //!   a system
-    //! \param[in] N Indices of the 3 unknowns
-    //! \return Array of the three values of component
-    std::array< tk::real, 3 >
-    extract( ncomp_t component,
-             const std::array< ncomp_t, 3 >& N ) const
-    {
-      return extract( component, N[0], N[1], N[2] );
-    }
-
-    //! Const-ref accessor to underlying raw data as a std::vector
-    //! \return Constant reference to underlying raw data
-    const std::vector< tk::real >& vec() const { return m_vec; }
-
-    //! Non-const-ref accessor to underlying raw data as a std::vector
-    //! \return Non-constant reference to underlying raw data
-    std::vector< tk::real >& vec() { return m_vec; }
-
-    //! Compound operator-=
-    //! \param[in] rhs Data object to subtract
-    //! \return Reference to ourselves after subtraction
-    Data< Layout >& operator-= ( const Data< Layout >& rhs ) {
-      Assert( rhs.nunk() == m_nunk, "Incorrect number of unknowns" );
-      Assert( rhs.nprop() == m_nprop, "Incorrect number of properties" );
-      std::transform( rhs.vec().cbegin(), rhs.vec().cend(),
-                      m_vec.cbegin(), m_vec.begin(),
-                      []( tk::real s, tk::real d ){ return d-s; } );
-      return *this;
-    }
-    //! Operator -
-    //! \param[in] rhs Data object to subtract
-    //! \return Copy of Data object after rhs has been subtracted
-    //! \details Implemented in terms of compound operator-=
-    Data< Layout > operator- ( const Data< Layout >& rhs )
-    const { return Data< Layout >( *this ) -= rhs; }
-
-    //! Compound operator+=
-    //! \param[in] rhs Data object to add
-    //! \return Reference to ourselves after addition
-    Data< Layout >& operator+= ( const Data< Layout >& rhs ) {
-      Assert( rhs.nunk() == m_nunk, "Incorrect number of unknowns" );
-      Assert( rhs.nprop() == m_nprop, "Incorrect number of properties" );
-      std::transform( rhs.vec().cbegin(), rhs.vec().cend(),
-                      m_vec.cbegin(), m_vec.begin(),
-                      []( tk::real s, tk::real d ){ return d+s; } );
-      return *this;
-    }
-    //! Operator +
-    //! \param[in] rhs Data object to add
-    //! \return Copy of Data object after rhs has been multiplied with
-    //! \details Implemented in terms of compound operator+=
-    Data< Layout > operator+ ( const Data< Layout >& rhs )
-    const { return Data< Layout >( *this ) += rhs; }
-
-    //! Compound operator*= multiplying by another Data object item by item
-    //! \param[in] rhs Data object to multiply with
-    //! \return Reference to ourselves after multiplication
-    Data< Layout >& operator*= ( const Data< Layout >& rhs ) {
-      Assert( rhs.nunk() == m_nunk, "Incorrect number of unknowns" );
-      Assert( rhs.nprop() == m_nprop, "Incorrect number of properties" );
-      std::transform( rhs.vec().cbegin(), rhs.vec().cend(),
-                      m_vec.cbegin(), m_vec.begin(),
-                      []( tk::real s, tk::real d ){ return d*s; } );
-      return *this;
-    }
-    //! Operator * multiplying by another Data object item by item
-    //! \param[in] rhs Data object to multiply with
-    //! \return Copy of Data object after rhs has been multiplied with
-    //! \details Implemented in terms of compound operator*=
-    Data< Layout > operator* ( const Data< Layout >& rhs )
-    const { return Data< Layout >( *this ) *= rhs; }
-
-    //! Compound operator*= multiplying all items by a scalar
-    //! \param[in] rhs Scalar to multiply with
-    //! \return Reference to ourselves after multiplication
-    Data< Layout >& operator*= ( tk::real rhs ) {
-      // cppcheck-suppress useStlAlgorithm
-      for (auto& v : m_vec) v *= rhs;
-      return *this;
-    }
-    //! Operator * multiplying all items by a scalar
-    //! \param[in] rhs Scalar to multiply with
-    //! \return Copy of Data object after rhs has been multiplied with
-    //! \details Implemented in terms of compound operator*=
-    Data< Layout > operator* ( tk::real rhs )
-    const { return Data< Layout >( *this ) *= rhs; }
+  ErrChk(
+    ex_get_init( m_inFile, title, &ndim, &nnode, &nelem, &neblk, &nnodeset,
+                 &nelemset ) == 0,
+    "Failed to read header from ExodusII file: " + m_filename );
+
+  ErrChk( nnode > 0,
+          "Number of nodes read from ExodusII file must be larger than zero" );
+  ErrChk( neblk > 0,
+          "Number of element blocks read from ExodusII file must be larger "
+          "than zero" );
+  ErrChk( ndim == 3, "Need a 3D mesh from ExodusII file " + m_filename );
+
+  m_nelem = static_cast< std::size_t >( nelem );
+  m_neblk = static_cast< std::size_t >( neblk );
+  m_neset = static_cast< std::size_t >( nelemset );
+
+  return static_cast< std::size_t >( nnode );
+}
+
+void
+ExodusIIMeshReader::readHeader( UnsMesh& mesh )
+// *****************************************************************************
+//  Read ExodusII header with setting mesh size
+//! \param[in] mesh Unstructured mesh object
+// *****************************************************************************
+{
+  // Read ExodusII file header and set mesh graph size
+  mesh.size() = m_nnode = static_cast< std::size_t >( readHeader() );
+}
+
+void
+ExodusIIMeshReader::readAllNodes( UnsMesh& mesh ) const
+// *****************************************************************************
+//  Read all node coordinates from ExodusII file
+//! \param[in] mesh Unstructured mesh object
+// *****************************************************************************
+{
+  mesh.x().resize( m_nnode );
+  mesh.y().resize( m_nnode );
+  mesh.z().resize( m_nnode );
+
+  ErrChk( ex_get_coord( m_inFile, mesh.x().data(), mesh.y().data(),
+                        mesh.z().data() ) == 0,
+          "Failed to read coordinates from ExodusII file: " + m_filename );
+}
+
+void
+ExodusIIMeshReader::readNode( std::size_t fid,
+                              std::size_t mid,
+                              std::vector< tk::real >& x,
+                              std::vector< tk::real >& y,
+                              std::vector< tk::real >& z ) const
+// *****************************************************************************
+//  Read coordinates of a single mesh node from ExodusII file
+//! \param[in] fid Node id in file whose coordinates to read
+//! \param[in] mid Node id in memory to which to put new cordinates
+//! \param[in,out] x Vector of x coordinates to push to
+//! \param[in,out] y Vector of y coordinates to push to
+//! \param[in,out] z Vector of z coordinates to push to
+// *****************************************************************************
+{
+  Assert( x.size() == y.size() && x.size() == z.size(), "Size mismatch" );
+  Assert( mid < x.size() && mid < y.size() && mid < z.size(),
+          "Indexing out of bounds" );
+
+  readNode( fid, x[mid], y[mid], z[mid] );
+}
+
+void
+ExodusIIMeshReader::readNode( std::size_t id,
+                              std::array< tk::real, 3 >& coord ) const
+// *****************************************************************************
+//  Read coordinates of a single mesh node from ExodusII file
+//! \param[in] id Node id whose coordinates to read
+//! \param[in,out] coord Array of x, y, and z coordinates
+// *****************************************************************************
+{
+  readNode( id, coord[0], coord[1], coord[2] );
+}
+
+void
+ExodusIIMeshReader::readNode( std::size_t id,
+                              tk::real& x,
+                              tk::real& y,
+                              tk::real& z ) const
+// *****************************************************************************
+// Read coordinates of a single mesh node from file
+//! \param[in] id Node id whose coordinates to read
+//! \param[in,out] x X coordinate to write to
+//! \param[in,out] y Y coordinate to write to
+//! \param[in,out] z Z coordinate to write to
+// *****************************************************************************
+{
+  ErrChk(
+    ex_get_partial_coord( m_inFile, static_cast<int64_t>(id)+1, 1,
+                          &x, &y, &z ) == 0,
+    "Failed to read coordinates of node " + std::to_string(id) +
+    " from ExodusII file: " + m_filename );
+}
+
+std::array< std::vector< tk::real >, 3 >
+ExodusIIMeshReader::readNodes( const std::vector< std::size_t >& gid ) const
+// *****************************************************************************
+//  Read coordinates of a number of mesh nodes from ExodusII file
+//! \param[in] gid Node IDs whose coordinates to read
+//! \return Mesh node coordinates
+// *****************************************************************************
+{
+  std::vector< tk::real > px( gid.size() ), py( gid.size() ), pz( gid.size() );
+
+  std::size_t i=0;
+  for (auto g : gid) readNode( g, i++, px, py, pz );
+
+  return {{ std::move(px), std::move(py), std::move(pz) }};
+}
+
+std::size_t
+ExodusIIMeshReader::readElemBlockIDs()
+// *****************************************************************************
+//  Read element block IDs from ExodusII file
+//! \return Total number of nodes in mesh
+// *****************************************************************************
+{
+  // Read ExodusII file header
+  auto nnode = readHeader();<--- Variable 'nnode' is assigned a value that is never used.
+
+  std::vector< int > bid( m_neblk );
+
+  // Read element block ids
+  ErrChk( ex_get_ids( m_inFile, EX_ELEM_BLOCK, bid.data()) == 0,
+          "Failed to read element block ids from ExodusII file: " +
+          m_filename );
+
+  m_elemblocks.clear();
+  m_nel.clear();
+  m_nel.resize( ExoNnpe.size() );
+  m_blockid_by_type.clear();
+  m_blockid_by_type.resize( ExoNnpe.size() );
+
+  // Fill element block ID vector
+  for (auto id : bid) {
+    char eltype[MAX_STR_LENGTH+1];
+    int n, nnpe, nattr;
+
+    // Read element block information
+    ErrChk( ex_get_block( m_inFile, EX_ELEM_BLOCK, id, eltype, &n, &nnpe,
+                          &nattr, nullptr, nullptr ) == 0,
+      "Failed to read element block information from ExodusII file: " +
+      m_filename );
+
+    // Store ExodusII element block ID
+    m_blockid.push_back( id );
+
+    auto nel = static_cast< std::size_t >( n );
+
+    // Store info on ExodusII element blocks
+    if (nnpe == 4) {        // tetrahedra
+
+      m_elemblocks.push_back( { ExoElemType::TET, nel } );
+      auto e = static_cast< std::size_t >( ExoElemType::TET );
+      m_blockid_by_type[ e ].push_back( id );
+      m_nel[ e ].push_back( nel );
+      Assert( m_blockid_by_type[e].size() == m_nel[e].size(), "Size mismatch" );
+
+    } else if (nnpe == 3) { // triangles
+
+      m_elemblocks.push_back( { ExoElemType::TRI, nel } );
+      auto e = static_cast< std::size_t >( ExoElemType::TRI );
+      m_blockid_by_type[ e ].push_back( id );
+      m_nel[ e ].push_back( nel );
+      Assert( m_blockid_by_type[e].size() == m_nel[e].size(), "Size mismatch" );
+
+    }
+  }
+
+  return nnode;
+}
 
-    //! Compound operator/=
-    //! \param[in] rhs Data object to divide by
-    //! \return Reference to ourselves after division
-    Data< Layout >& operator/= ( const Data< Layout >& rhs ) {
-      Assert( rhs.nunk() == m_nunk, "Incorrect number of unknowns" );
-      Assert( rhs.nprop() == m_nprop, "Incorrect number of properties" );
-      std::transform( rhs.vec().cbegin(), rhs.vec().cend(),
-                      m_vec.cbegin(), m_vec.begin(),
-                      []( tk::real s, tk::real d ){ return d/s; } );
-      return *this;
-    }
-    //! Operator /
-    //! \param[in] rhs Data object to divide by
-    //! \return Copy of Data object after rhs has been divided by
-    //! \details Implemented in terms of compound operator/=
-    Data< Layout > operator/ ( const Data< Layout >& rhs )
-    const { return Data< Layout >( *this ) /= rhs; }
-
-    //! Compound operator/= dividing all items by a scalar
-    //! \param[in] rhs Scalar to divide with
-    //! \return Reference to ourselves after division
-    Data< Layout >& operator/= ( tk::real rhs ) {
-      // cppcheck-suppress useStlAlgorithm
-      for (auto& v : m_vec) v /= rhs;
-      return *this;
-    }
-    //! Operator / dividing all items by a scalar
-    //! \param[in] rhs Scalar to divide with
-    //! \return Copy of Data object after rhs has been divided by
-    //! \details Implemented in terms of compound operator/=
-    Data< Layout > operator/ ( tk::real rhs )
-    const { return Data< Layout >( *this ) /= rhs; }
-
-    //! Add new unknown at the end of the container
-    //! \param[in] prop Vector of properties to initialize the new unknown with
-    void push_back( const std::vector< tk::real >& prop )
-    { return push_back( prop, int2type< Layout >() ); }
-
-    //! Resize data store to contain 'count' elements
-    //! \param[in] count Resize store to contain count * nprop elements
-    //! \param[in] value Value to initialize new data with (default: 0.0)
-    //! \note This works for both shrinking and enlarging, as this simply
-    //!   translates to std::vector::resize(). Note that count changes, nprop
-    //!   does not, see the private overload resize().
-    void resize( std::size_t count, tk::real value = 0.0 )
-    { resize( count, value, int2type< Layout >() ); }
-
-    //! Remove a number of unknowns
-    //! \param[in] unknown Set of indices of unknowns to remove
-    void rm( const std::set< ncomp_t >& unknown ) {
-      auto remove = [ &unknown ]( std::size_t i ) -> bool {
-        if (unknown.find(i) != end(unknown)) return true;
-        return false;
-      };
-      std::size_t last = 0;
-      for(std::size_t i=0; i<m_nunk; ++i, ++last) {
-        while( remove(i) ) ++i;
-        if (i >= m_nunk) break;
-        for (ncomp_t p = 0; p<m_nprop; ++p)
-          m_vec[ last*m_nprop+p ] = m_vec[ i*m_nprop+p ];
-      }
-      m_vec.resize( last*m_nprop );
-      m_nunk -= unknown.size();
-    }
-
-    //! Fill vector of unknowns with the same value
-    //! \details Requirement: component < nprop, enforced with an
-    //!   assert in DEBUG mode, see also the constructor.
-    //! \param[in] component Component index, i.e., position of a scalar within
-    //!   a system
-    //! \param[in] value Value to fill vector of unknowns with
-    inline void fill( ncomp_t component, tk::real value ) {
-      auto p = cptr( component );
-      for (ncomp_t i=0; i<m_nunk; ++i) var(p,i) = value;
-    }
-
-    //! Fill full data storage with value
-    //! \param[in] value Value to fill data with
-    void fill( tk::real value )
-    { std::fill( begin(m_vec), end(m_vec), value ); }
-
-    //! Check if vector of unknowns is empty
-    bool empty() const noexcept { return m_vec.empty(); }
-
-    //! Layout name dispatch
-    //! \return The name of the data layout used
-    static std::string layout() { return layout( int2type< Layout >() ); }
-
-    /** @name Pack/Unpack: Serialize Data object for Charm++ */
-    ///@{
-    //! \brief Pack/Unpack serialize member function
-    //! \param[in,out] p Charm++'s PUP::er serializer object reference
-    void pup( PUP::er &p ) {<--- Parameter 'p' can be declared with const
-      p | m_vec;
-      p | m_nunk;
-      p | m_nprop;
-    }
-    //! \brief Pack/Unpack serialize operator|
-    //! \param[in,out] p Charm++'s PUP::er serializer object reference
-    //! \param[in,out] d DataLyaout object reference
-    friend void operator|( PUP::er& p, Data& d ) { d.pup(p); }
-    //@}
+void
+ExodusIIMeshReader::readAllElements( UnsMesh& mesh )
+// *****************************************************************************
+//  Read all element blocks and mesh connectivity from ExodusII file
+//! \param[inout] mesh Unstructured mesh object to store mesh in
+// *****************************************************************************
+{
+  // Read element block ids
+  readElemBlockIDs();
+
+  for (auto id : m_blockid) {
+    char eltype[MAX_STR_LENGTH+1];
+    int nel, nnpe, nattr;
+
+    // Read element block information
+    ErrChk( ex_get_block( m_inFile, EX_ELEM_BLOCK, id, eltype, &nel, &nnpe,
+                          &nattr, nullptr, nullptr ) == 0,
+      "Failed to read element block information from ExodusII file: " +
+      m_filename );
+
+    // Read element connectivity
+    auto connectsize = static_cast< std::size_t >( nel*nnpe );
+    if (nnpe == 4) {    // tetrahedra
+
+      std::vector< int > inpoel( connectsize );
+      ErrChk( ex_get_conn( m_inFile, EX_ELEM_BLOCK, id, inpoel.data(),
+                           nullptr, nullptr ) == 0,
+        "Failed to read " + std::string(eltype) + " element connectivity from "
+        "ExodusII file: " + m_filename );
+      for (auto n : inpoel)
+        mesh.tetinpoel().push_back( static_cast< std::size_t >( n ) );
+
+    } else if (nnpe == 3) {    // triangles
+
+      std::vector< int > inpoel( connectsize );
+      ErrChk( ex_get_conn( m_inFile, EX_ELEM_BLOCK, id, inpoel.data(),
+                           nullptr, nullptr ) == 0,
+        "Failed to read " + std::string(eltype) + " element connectivity from "
+        "ExodusII file: " + m_filename );
+      for (auto n : inpoel)
+        mesh.triinpoel().push_back( static_cast< std::size_t >( n ) );
+
+    }
+  }
+
+  // Shift node IDs to start from zero
+  shiftToZero( mesh.triinpoel() );
+  shiftToZero( mesh.tetinpoel() );
+}
+
+void
+ExodusIIMeshReader::readElements( const std::array< std::size_t, 2 >& ext,
+                                  tk::ExoElemType elemtype,
+                                  std::vector< std::size_t >& conn )
+// *****************************************************************************
+//  Read element connectivity of a number of mesh cells from ExodusII file
+//! \param[in] ext Extents of element IDs whose connectivity to read:
+//!   [from...till), using zero-based element IDs, where 'from' >=0, inclusive
+//!   and 'till < 'maxelements', where 'maxelements' is the total number of
+//!   elements of all element blocks in the file of the requested cell type.
+//!   Note that 'maxelements' can be queried by nelem().
+//! \param[in] elemtype Element type
+//! \param[inout] conn Connectivity vector to push to
+//! \note Must be preceded by a call to readElemBlockIDs()
+//! \details This function takes the extents of element IDs in a zero-based
+//!   fashion. These input extents can be thought of "absolute" extents that
+//!   denote lowest and the largest-1 element IDs to be read from file.
+//!   The mesh block-wise element set is also updated.
+// *****************************************************************************
+{
+  Assert( tk::sumsize(m_blockid_by_type) > 0,
+          "A call to this function must be preceded by a call to "
+          "ExodusIIMeshReader::readElemBlockIDs()" );
+  Assert( ext[0] <= ext[1] &&
+          ext[0] < nelem(elemtype) &&
+          ext[1] < nelem(elemtype),
+          "Invalid element ID extents. Of the requested extents [from...till), "
+          "'from' must be lower than or equal to 'till', and they must be in "
+          "the range [0...maxelements), where 'maxelements' is the total "
+          "number of elements of all element blocks in the file of the "
+          "requested cell type. Requested element ID extents: ["
+          + std::to_string(ext[0]) + "..." + std::to_string(ext[1])
+          + "), 'maxelements' of cell type with "
+          + std::to_string( ExoNnpe[ static_cast<std::size_t>(elemtype) ] )
+          + " nodes per cell in file '" + m_filename + "': "
+          + std::to_string( nelem( elemtype ) ) );
+
+  auto e = static_cast< std::size_t >( elemtype );
+  // List of number of elements of all blocks of element type requested
+  const auto& nel = m_nel[e];
+  // List of element block IDs for element type requested
+  const auto& bid = m_blockid_by_type[e];
+
+  // Compute lower and upper element block ids to read from based on extents
+  std::size_t lo_bid = 0, hi_bid = 0, offset = 0;
+  for (std::size_t b=0; b<nel.size(); ++b) {
+    std::size_t lo = offset;                    // lo (min) elem ID in block
+    std::size_t hi = offset + nel[b] - 1;       // hi (max) elem ID in block
+    if (ext[0] >= lo && ext[0] <= hi) lo_bid = b;
+    if (ext[1] >= lo && ext[1] <= hi) hi_bid = b;
+    offset += nel[b];
+  }
 
-  private:
-    //! Transform a compile-time uint8_t into a type, used for dispatch
-    //! \see A. Alexandrescu, Modern C++ Design: Generic Programming and Design
-    //!   Patterns Applied, Addison-Wesley Professional, 2001.
-    template< uint8_t m > struct int2type { enum { value = m }; };
-
-    //! Overloads for the various const data accesses
-    //! \details Requirement: component < nprop, unknown < nunk,
-    //!   enforced with an assert in DEBUG mode, see also the constructor.
-    //! \param[in] unknown Unknown index
-    //! \param[in] component Component index, i.e., position of a scalar within
-    //!   a system
-    //! \return Const reference to data of type tk::real
-    //! \see A. Alexandrescu, Modern C++ Design: Generic Programming and Design
-    //!   Patterns Applied, Addison-Wesley Professional, 2001.
-    const tk::real&
-    access( ncomp_t unknown, ncomp_t component, int2type< UnkEqComp > ) const
-    {
-      Assert( component < m_nprop, "Out-of-bounds access: "
-              "component < number of properties" );
-      Assert( unknown < m_nunk, "Out-of-bounds access: unknown < number of "
-              "unknowns" );
-      return m_vec[ unknown*m_nprop + component ];
-    }
-    const tk::real&
-    access( ncomp_t unknown, ncomp_t component, int2type< EqCompUnk > ) const
-    {
-      Assert( component < m_nprop, "Out-of-bounds access: "
-              "component < number of properties" );
-      Assert( unknown < m_nunk, "Out-of-bounds access: unknown < number of "
-              "unknowns" );
-      return m_vec[ (component)*m_nunk + unknown ];
-    }
-
-    // Overloads for the various const ptr to physical variable accesses
-    //! \details Requirement: component < nprop, unknown < nunk,
-    //!   enforced with an assert in DEBUG mode, see also the constructor.
-    //! \param[in] component Component index, i.e., position of a scalar within
-    //!   a system
-    //! \return Pointer to data of type tk::real for use with var()
-    //! \see A. Alexandrescu, Modern C++ Design: Generic Programming and Design
-    //!   Patterns Applied, Addison-Wesley Professional, 2001.
-    const tk::real*
-    cptr( ncomp_t component, int2type< UnkEqComp > ) const {
-      Assert( component < m_nprop, "Out-of-bounds access: "
-              "component < number of properties" );
-      return m_vec.data() + component;
-    }
-    const tk::real*
-    cptr( ncomp_t component, int2type< EqCompUnk > ) const {
-      Assert( component < m_nprop, "Out-of-bounds access: "
-              "component < number of properties" );
-      return m_vec.data() + (component)*m_nunk;
-    }
-
-    // Overloads for the various const physical variable accesses
-    //!   Requirement: unknown < nunk, enforced with an assert in DEBUG mode,
-    //!   see also the constructor.
-    //! \param[in] pt Pointer to data of type tk::real as returned from cptr()
-    //! \param[in] unknown Unknown index
-    //! \return Const reference to data of type tk::real
-    //! \see A. Alexandrescu, Modern C++ Design: Generic Programming and Design
-    //!   Patterns Applied, Addison-Wesley Professional, 2001.
-    inline const tk::real&
-    var( const tk::real* const pt, ncomp_t unknown, int2type< UnkEqComp > )
-    const {
-      Assert( unknown < m_nunk, "Out-of-bounds access: unknown < number of "
-              "unknowns" );
-      return *(pt + unknown*m_nprop);
-    }
-    inline const tk::real&
-    var( const tk::real* const pt, ncomp_t unknown, int2type< EqCompUnk > )
-    const {
-      Assert( unknown < m_nunk, "Out-of-bounds access: unknown < number of "
-              "unknowns" );
-      return *(pt + unknown);
-    }
-
-    //! Add new unknown
-    //! \param[in] prop Vector of properties to initialize the new unknown with
-    //! \note Only the UnkEqComp overload is provided as this operation would be
-    //!   too inefficient with the EqCompUnk data layout.
-    void push_back( const std::vector< tk::real >& prop, int2type< UnkEqComp > )
-    {
-      Assert( prop.size() == m_nprop, "Incorrect number of properties" );
-      m_vec.resize( (m_nunk+1) * m_nprop );
-      ncomp_t u = m_nunk;
-      ++m_nunk;
-      for (ncomp_t i=0; i<m_nprop; ++i) operator()( u, i ) = prop[i];
-    }
-
-    void push_back( const std::vector< tk::real >&, int2type< EqCompUnk > )
-    { Throw( "Not implented. It would be inefficient" ); }
-
-    //! Resize data store to contain 'count' elements
-    //! \param[in] count Resize store to contain 'count' elements
-    //! \param[in] value Value to initialize new data with
-    //! \note Only the UnkEqComp overload is provided as this operation would be
-    //!   too inefficient with the EqCompUnk data layout.
-    //! \note This works for both shrinking and enlarging, as this simply
-    //!   translates to std::vector::resize().
-    void resize( std::size_t count, tk::real value, int2type< UnkEqComp > ) {
-      m_vec.resize( count * m_nprop, value );
-      m_nunk = count;
-    }
+  Assert( lo_bid < nel.size() && lo_bid < bid.size(),
+          "Invalid start block ID" );
+  Assert( hi_bid < nel.size() && hi_bid < bid.size(),
+          "Invalid end block ID" );
+
+  // Compute relative extents based on absolute ones for each block to read from
+  std::vector< std::array< std::size_t, 2 > > rext;
+  offset = 0;
+  for (std::size_t b=0; b<lo_bid; ++b) offset += nel[b];
+  for (std::size_t b=lo_bid; b<=hi_bid; ++b) {
+    std::size_t lo = offset;
+    std::size_t hi = offset + nel[b] - 1;
+    std::size_t le = 1, he = nel[b];
+    if (ext[0] >= lo && ext[0] <= hi) le = ext[0] - lo + 1;
+    if (ext[1] >= lo && ext[1] <= hi) he = ext[1] - lo + 1;
+    Assert( le >= 1 && le <= nel[b] && he >= 1 && he <= nel[b],
+            "Relative index out of block" );
+    rext.push_back( {{ le, he }} );
+    offset += nel[b];
+  }
+
+  Assert( std::accumulate(
+            std::next(rext.cbegin()), rext.cend(), rext[0][1]-rext[0][0]+1,
+            []( std::size_t n, const std::array< std::size_t, 2 >& r )
+            { return n + r[1] - r[0] + 1; }
+          ) == ext[1]-ext[0]+1,
+          "Total number of elements to read incorrect, requested extents: " +
+          std::to_string(ext[0]) + " ... " + std::to_string(ext[1]) );
+
+  std::vector< int > inpoel;
+
+  // Read element connectivity from file
+  std::size_t B = 0;
+  for (auto b=lo_bid; b<=hi_bid; ++b, ++B) {
+    const auto& r = rext[B];
+    std::vector< int > c( (r[1]-r[0]+1) * ExoNnpe[e] );
+    ErrChk( ex_get_partial_conn( m_inFile,
+                                 EX_ELEM_BLOCK,
+                                 bid[b],
+                                 static_cast< int64_t >( r[0] ),
+                                 static_cast< int64_t >( r[1]-r[0]+1 ),
+                                 c.data(),
+                                 nullptr,
+                                 nullptr ) == 0,
+            "Failed to read element connectivity of elements [" +
+            std::to_string(r[0]) + "..." + std::to_string(r[1]) +
+            "] from element block " + std::to_string(bid[b]) + " in ExodusII "
+            "file: " + m_filename );
+
+    // Store tet-elements under their respective mesh block ids
+    if (elemtype == ExoElemType::TET) {
+      for (std::size_t i=0; i<c.size()/ExoNnpe[e]; ++i) {
+        auto& tetblk = m_elemInBlockId[static_cast<std::size_t>(bid[b])];
+        tetblk.insert((inpoel.size()/ExoNnpe[e]) + i);
+      }
+    }
+
+    inpoel.reserve( inpoel.size() + c.size() );
+    std::move( begin(c), end(c), std::back_inserter(inpoel) );
+  }
+
+  Assert( inpoel.size() == (ext[1]-ext[0]+1)*ExoNnpe[e],
+          "Failed to read element connectivity of elements [" +
+          std::to_string(ext[0]) + "..." + std::to_string(ext[1]) + ") from "
+          "ExodusII file: " + m_filename );
+
+  // Put in element connectivity using zero-based node indexing
+  for (auto& i : inpoel) --i;
+  conn.reserve( conn.size() + inpoel.size() );
+  std::move( begin(inpoel), end(inpoel), std::back_inserter(conn) );
+}
+
+void
+ExodusIIMeshReader::readFaces( std::vector< std::size_t >& conn )
+// *****************************************************************************
+//  Read face connectivity of a number of boundary faces from ExodusII file
+//! \param[inout] conn Connectivity vector to push to
+//! \details This function reads in the total number of boundary faces,
+//!   also called triangle-elements in the EXO2 file, and their connectivity.
+// *****************************************************************************
+{
+  // Return quietly if no triangle elements in file
+  if (nelem(tk::ExoElemType::TRI) == 0) return;
+
+  // Read triangle boundary-face connectivity (all the triangle element block)
+  readElements( {{0,nelem(tk::ExoElemType::TRI)-1}}, tk::ExoElemType::TRI,
+                conn );
+}
+
+std::vector< std::size_t >
+ExodusIIMeshReader::readNodemap()
+// *****************************************************************************
+//  Read local to global node-ID map from ExodusII file
+//! \return node_map Vector mapping the local Exodus node-IDs to global node-IDs
+//! \details The node-map is required to get the "Exodus-global" node-IDs from
+//!   the "Exodus-internal" node-IDs, which are returned from the exodus APIs.
+//!   The node-IDs in the exodus file are referred to as the "Exodus-global"
+//!   node-IDs or "fileIDs" in Quinoa.
+// *****************************************************************************
+{
+  // Read triangle boundary-face connectivity
+  auto nnode = readElemBlockIDs();
+
+  // Create array to store node-number map
+  std::vector< int > node_map( nnode );
 
-    void resize( std::size_t, tk::real, int2type< EqCompUnk > ) {
-      Throw( "Not implemented. It would be inefficient" );
-    }
+  // Read in the node number map to map the above nodes to the global node-IDs
+  ErrChk( ex_get_id_map( m_inFile, EX_NODE_MAP, node_map.data() ) == 0,
+          "Failed to read node map length from ExodusII file: " );
 
-    // Overloads for the name-queries of data lauouts
-    //! \return The name of the data layout used
-    //! \see A. Alexandrescu, Modern C++ Design: Generic Programming and Design
-    //!   Patterns Applied, Addison-Wesley Professional, 2001.
-    static std::string layout( int2type< UnkEqComp > )
-    { return "unknown-major"; }
-    static std::string layout( int2type< EqCompUnk > )
-    { return "equation-major"; }
-
-    std::vector< tk::real > m_vec;      //!< Data pointer
-    ncomp_t m_nunk;                     //!< Number of unknowns
-    ncomp_t m_nprop;                    //!< Number of properties/unknown
-};
-
-//! Operator * multiplying all items by a scalar from the left
-//! \param[in] lhs Scalar to multiply with
-//! \param[in] rhs Date object to multiply
-//! \return New Data object with all items multipled with lhs
-template< uint8_t Layout >
-Data< Layout > operator* ( tk::real lhs, const Data< Layout >& rhs ) {
-  return Data< Layout >( rhs ) *= lhs;
-}
+  std::vector< std::size_t > node_map1( nnode );
+
+  for (std::size_t i=0; i<nnode; ++i)
+  {
+          node_map1[i] = static_cast< std::size_t >(node_map[i]-1);
+  }
+
+  return node_map1;
+}
+
+std::map< int, std::vector< std::size_t > >
+ExodusIIMeshReader::readSidesetNodes()
+// *****************************************************************************
+//  Read node list of all side sets from ExodusII file
+//! \return Node lists mapped to side set ids
+// *****************************************************************************
+{
+  // Read ExodusII file header (fills m_neset)
+  readHeader();
+
+  // Node lists mapped to side set ids
+  std::map< int, std::vector< std::size_t > > side;
 
-//! Operator min between two Data objects
-//! \param[in] a 1st Data object
-//! \param[in] b 2nd Data object
-//! \return New Data object containing the minimum of all values for each
-//!   value in _a_ and _b_
-//! \note The Data objects _a_ and _b_ must have the same number of
-//!   unknowns and properties.
-//! \note As opposed to std::min, this function creates and returns a new object
-//!   instead of returning a reference to one of the operands.
-template< uint8_t Layout >
-Data< Layout > min( const Data< Layout >& a, const Data< Layout >& b ) {
-  Assert( a.nunk() == b.nunk(), "Number of unknowns unequal" );
-  Assert( a.nprop() == b.nprop(), "Number of properties unequal" );
-  Data< Layout > r( a.nunk(), a.nprop() );
-  std::transform( a.vec().cbegin(), a.vec().cend(),
-                  b.vec().cbegin(), r.vec().begin(),
-                  []( tk::real s, tk::real d ){ return std::min(s,d); } );
-
-  return r;
-}
-
-//! Operator max between two Data objects
-//! \param[in] a 1st Data object
-//! \param[in] b 2nd Data object
-//! \return New Data object containing the maximum of all values for each
-//!   value in _a_ and _b_
-//! \note The Data objects _a_ and _b_ must have the same number of
-//!   unknowns and properties.
-//! \note As opposed to std::max, this function creates and returns a new object
-//!   instead of returning a reference to one of the operands.
-template< uint8_t Layout >
-Data< Layout > max( const Data< Layout >& a, const Data< Layout >& b ) {
-  Assert( a.nunk() == b.nunk(), "Number of unknowns unequal" );
-  Assert( a.nprop() == b.nprop(), "Number of properties unequal" );
-  Data< Layout > r( a.nunk(), a.nprop() );
-  std::transform( a.vec().cbegin(), a.vec().cend(),
-                  b.vec().cbegin(), r.vec().begin(),
-                  []( tk::real s, tk::real d ){ return std::max(s,d); } );
-  return r;
-}
-
-//! Operator == between two Data objects
-//! \param[in] lhs Data object to compare
-//! \param[in] rhs Data object to compare
-//! \return True if all entries are equal up to epsilon
-template< uint8_t Layout >
-bool operator== ( const Data< Layout >& lhs, const Data< Layout >& rhs ) {
-  Assert( rhs.nunk() == lhs.nunk(), "Incorrect number of unknowns" );
-  Assert( rhs.nprop() == lhs.nprop(), "Incorrect number of properties" );
-  auto l = lhs.vec().cbegin();
-  auto r = rhs.vec().cbegin();
-  while (l != lhs.vec().cend()) {
-    if (std::abs(*l - *r) > std::numeric_limits< tk::real >::epsilon())
-     return false;
-    ++l; ++r;
-  }
-  return true;
-}
-
-//! Operator != between two Data objects
-//! \param[in] lhs Data object to compare
-//! \param[in] rhs Data object to compare
-//! \return True if all entries are unequal up to epsilon
-template< uint8_t Layout >
-bool operator!= ( const Data< Layout >& lhs, const Data< Layout >& rhs )
-{ return !(lhs == rhs); }
-
-//! Compute the maximum difference between the elements of two Data objects
-//! \param[in] lhs 1st Data object
-//! \param[in] rhs 2nd Data object
-//! \return The index, i.e., the raw position, of and the largest absolute value
-//!   of the difference between all corresponding elements of _lhs_ and _rhs_.
-//! \details The position returned is the position in the underlying raw data
-//!   structure, independent of components, etc. If lhs == rhs with
-//!   precision  std::numeric_limits< tk::real >::epsilon(), a pair of (0,0.0)
-//!   is returned.
-//! \note The Data objects _lhs_ and _rhs_ must have the same number of
-//!   unknowns and properties.
-template< uint8_t Layout >
-std::pair< std::size_t, tk::real >
-maxdiff( const Data< Layout >& lhs, const Data< Layout >& rhs ) {
-  Assert( lhs.nunk() == rhs.nunk(), "Number of unknowns unequal" );
-  Assert( lhs.nprop() == rhs.nprop(), "Number of properties unequal" );
-  auto l = lhs.vec().cbegin();
-  auto r = rhs.vec().cbegin();
-  std::pair< std::size_t, tk::real > m( 0, std::abs(*l - *r) );
-  ++l; ++r;
-  while (l != lhs.vec().cend()) {
-    const auto d = std::abs(*l - *r);
-    if (d > m.second) m = { std::distance(lhs.vec().cbegin(),l), d };
-    ++l; ++r;
-  }
-  return m;
-}
-
-} // tk::
-
-#endif // Data_h
+  if (m_neset > 0) {
+    // Read all side set ids from file
+    std::vector< int > ids( m_neset );
+    ErrChk( ex_get_ids( m_inFile, EX_SIDE_SET, ids.data() ) == 0,
+            "Failed to read side set ids from ExodusII file: " + m_filename );
+    // Read in node list for all side sets
+    for (auto i : ids) {
+      int nface, nnode;
+      // Read number of faces and number of distribution factors in side set i
+      ErrChk( ex_get_set_param( m_inFile, EX_SIDE_SET, i, &nface, &nnode ) == 0,
+              "Failed to read side set " + std::to_string(i) + " parameters "
+              "from ExodusII file: " + m_filename );
+      // Read number of nodes in side set i (overwrite nnode)
+      ErrChk( ex_get_side_set_node_list_len( m_inFile, i, &nnode ) == 0,
+              "Failed to read side set " + std::to_string(i) + " node list "
+              "length from ExodusII file: " + m_filename );
+      Assert(nnode > 0, "Number of nodes = 0 in side set" + std::to_string(i));
+      std::vector< int > df( static_cast< std::size_t >( nface ) );
+      std::vector< int > nodes( static_cast< std::size_t >( nnode ) );
+      // Read in node list for side set i
+      ErrChk( ex_get_side_set_node_list( m_inFile, i, df.data(), nodes.data() )
+                == 0, "Failed to read node list of side set " +
+                      std::to_string(i) + " from ExodusII file: " +
+                      m_filename );
+      // Make node list unique
+      tk::unique( nodes );
+      // Store 0-based node ID list as std::size_t vector instead of ints
+      auto& list = side[ i ];
+      for (auto n : nodes) list.push_back( static_cast<std::size_t>(n-1) );<--- Consider using std::transform algorithm instead of a raw loop.
+    }
+  }
+
+  return side;
+}
+
+void
+ExodusIIMeshReader::readSidesetFaces(
+  std::map< int, std::vector< std::size_t > >& bface,
+  std::map< int, std::vector< std::size_t > >& faces )
+// *****************************************************************************
+//  Read side sets from ExodusII file
+//! \param[in,out] bface Elem ids of side sets to read into
+//! \param[in,out] faces Elem-relative face ids of tets of side sets
+// *****************************************************************************
+{
+  // Read element block ids
+  readElemBlockIDs();
+
+  if (m_neset > 0) {
+    // Read side set ids from file
+    std::vector< int > ids( m_neset );
+    ErrChk( ex_get_ids( m_inFile, EX_SIDE_SET, ids.data() ) == 0,
+            "Failed to read side set ids from ExodusII file: " + m_filename );
+
+    // Read all side sets from file
+    for (auto i : ids) {
+      int nface, nnode;
+
+      // Read number of faces in side set
+      ErrChk( ex_get_set_param( m_inFile, EX_SIDE_SET, i, &nface, &nnode ) == 0,
+              "Failed to read side set " + std::to_string(i) + " parameters "
+              "from ExodusII file: " + m_filename );
+
+      Assert(nface > 0, "Number of faces = 0 in side set" + std::to_string(i));
+
+      std::vector< int > exoelem( static_cast< std::size_t >( nface ) );
+      std::vector< int > exoface( static_cast< std::size_t >( nface ) );
+
+      // Read in file-internal element ids and relative face ids for side set
+      ErrChk( ex_get_set( m_inFile, EX_SIDE_SET, i, exoelem.data(),
+                          exoface.data() ) == 0,
+              "Failed to read side set " + std::to_string(i) );
+
+      // Store file-internal element ids of side set
+      auto& elem = bface[i];
+      elem.resize( exoelem.size() );
+      std::size_t j = 0;
+      for (auto e : exoelem) elem[j++] = static_cast< std::size_t >( e-1 );
+
+      // Store zero-based relative face ids of side set
+      auto& face = faces[i];
+      face.resize( exoface.size() );
+      j = 0;
+      for (auto n : exoface) face[j++] = static_cast< std::size_t >( n-1 );
+
+      Assert( std::all_of( begin(face), end(face),
+                           [](std::size_t f){ return f<4; } ),
+              "Relative face id of side set must be between 0 and 3" );
+      Assert( elem.size() == face.size(), "Size mismatch" );
+    }
+  }
+}
+
+std::pair< tk::ExoElemType, std::size_t >
+ExodusIIMeshReader::blkRelElemId( std::size_t id ) const
+// *****************************************************************************
+// Compute element-block-relative element id and element type
+//! \param[in] id (ExodusII) file-internal element id
+//! \return Element type the internal id points to and element id relative to
+//!   cell-type
+//! \details This function takes an internal element id, which in general can
+//!   point to any element block in the ExodusII file and thus we do not know
+//!   which element type a block contains. It then computes which cell type the
+//!   id points to and computes the relative index for the given cell type. This
+//!   is necessary because elements are read in from file by from potentially
+//!   multiple blocks by cell type.
+//! \note Must be preceded by a call to readElemBlockIDs()
+// *****************************************************************************
+{
+  auto TRI = tk::ExoElemType::TRI;
+  auto TET = tk::ExoElemType::TET;
+
+  std::size_t e = 0;            // counts elements (independent of cell type)
+  std::size_t ntri = 0;         // counts triangle elements
+  std::size_t ntet = 0;         // counts tetrahedron elements
+
+  for (const auto& b : m_elemblocks) {  // walk all element blocks in order
+    e += b.second;                      // increment file-internal element id
+    if (e > id) {                       // found element block for internal id
+      if (b.first == TRI) {             // if triangle block
+        return { TRI, id-ntet };        // return cell type and triangle id
+      } else if (b.first == TET) {      // if tetrahedron block
+        return { TET, id-ntri };        // return cell type and tetrahedron id
+      }
+    }
+    // increment triangle and tetrahedron elements independently
+    if (b.first == TRI)
+      ntri += b.second;
+    else if (b.first == TET)
+      ntet += b.second;
+  }
+
+  Throw( " Exodus internal element id not found" );
+}
+
+std::vector< std::size_t >
+ExodusIIMeshReader::triinpoel(
+  std::map< int, std::vector< std::size_t > >& belem,
+  const std::map< int, std::vector< std::size_t > >& faces,
+  const std::vector< std::size_t >& ginpoel,
+  const std::vector< std::size_t >& triinp ) const
+// *****************************************************************************
+//  Generate triangle face connectivity for side sets
+//! \param[in,out] belem File-internal elem ids of side sets
+//! \param[in] faces Elem-relative face ids of side sets
+//! \param[in] ginpoel Tetrahedron element connectivity with global nodes
+//! \param[in] triinp Triangle element connectivity with global nodes
+//!   (if exists in file)
+//! \return Triangle face connectivity with global node IDs of side sets
+//! \details This function takes lists of file-internal element ids (in belem)
+//!   for side sets and does two things: (1) generates face connectivity (with
+//!   global node IDs) for side sets, and (2) converts the (ExodusII)
+//!   file-internal element IDs to face ids so that they can be used to index
+//!   into the face connectivity. The IDs in belem are modified and the face
+//!   connectivity (for boundary faces only) is returned.
+//! \note Must be preceded by a call to readElemBlockIDs()
+// *****************************************************************************
+{
+  Assert( !(m_from == 0 && m_till == 0),
+          "Lower and upper tetrahedron id bounds must not both be zero" );
+
+  // This will contain one of our final results: face (triangle) connectivity
+  // for the side sets only. The difference between bnd_triinpoel and triinpoel
+  // is that triinpoel is a triangle element connectivity, independent of side
+  // sets, while bnd_triinpoel is a triangle connectivity only for side sets.
+  std::vector< std::size_t > bnd_triinpoel;
+
+  // Storage for boundary face lists for each side set on this PE
+  std::map< int, std::vector< std::size_t > > belem_own;
+
+  std::size_t f = 0;            // counts all faces
+  for (auto& ss : belem) {      // for all side sets
+
+    // insert side set id into new map
+    auto& b = belem_own[ ss.first ];
+    // get element-relative face ids for side set
+    const auto& face = tk::cref_find( faces, ss.first );
+    std::size_t s = 0;          // counts side set faces
+    for (auto& i : ss.second) { // for all faces on side set
+
+      // compute element-block-relative element id and element type
+      auto r = blkRelElemId( i );
+
+      // extract boundary face connectivity based on element type
+      bool localface = false;
+      if (r.first == tk::ExoElemType::TRI) {
+
+        auto t = m_tri.find(r.second);
+        if (t != end(m_tri)) {  // only if triangle id exists on this PE
+          Assert( t->second < triinp.size()/3,
+                  "Indexing out of triangle connectivity" );
+          // generate triangle (face) connectivity using global node ids
+          bnd_triinpoel.push_back( triinp[ t->second*3 + 0 ] );
+          bnd_triinpoel.push_back( triinp[ t->second*3 + 1 ] );
+          bnd_triinpoel.push_back( triinp[ t->second*3 + 2 ] );
+          localface = true;
+        }
+
+      } else if (r.first == tk::ExoElemType::TET) {
+
+        if (r.second >= m_from && r.second < m_till) {  // if tet is on this PE
+          auto t = r.second - m_from;
+          Assert( t < ginpoel.size()/4,
+                  "Indexing out of tetrahedron connectivity" );
+          // get ExodusII face-node numbering for side sets, see ExodusII
+          // manual figure on "Sideset side Numbering"
+          const auto& tri = tk::expofa[ face[s] ];
+          // generate triangle (face) connectivity using global node ids, note
+          // the switched node order, 0,2,1, as lpofa is different from expofa
+          bnd_triinpoel.push_back( ginpoel[ t*4 + tri[0] ] );
+          bnd_triinpoel.push_back( ginpoel[ t*4 + tri[1] ] );
+          bnd_triinpoel.push_back( ginpoel[ t*4 + tri[2] ] );
+          localface = true;
+        }
+
+      }
+
+      ++s;
+
+      // generate PE-local face id for side set (this is to be used to index
+      // into triinpoel)
+      if (localface) b.push_back( f++ );
+    }
+
+    // if no faces on this side set (on this PE), remove side set id
+    if (b.empty()) belem_own.erase( ss.first );
+  }
+
+  belem = std::move(belem_own);
+
+  return bnd_triinpoel;
+}
+
+void
+ExodusIIMeshReader::readNodeVarNames( std::vector< std::string >& nv ) const
+// *****************************************************************************
+//  Read the names of nodal output variables from ExodusII file
+//! \param[in,out] nv Nodal variable names
+// *****************************************************************************
+{
+  #if defined(__clang__)
+    #pragma clang diagnostic push
+    #pragma clang diagnostic ignored "-Wvla"
+    #pragma clang diagnostic ignored "-Wvla-extension"
+  #elif defined(STRICT_GNUC)
+    #pragma GCC diagnostic push
+    #pragma GCC diagnostic ignored "-Wvla"
+  #endif
+
+  int numvars = 0;
+
+  ErrChk(
+    ex_get_variable_param( m_inFile, EX_NODE_BLOCK, &numvars ) == 0,
+    "Failed to read nodal output variable parameters from ExodusII file: " +
+    m_filename );
+
+  if (numvars) {
+
+    char* names[ static_cast< std::size_t >( numvars ) ];
+    for (int i=0; i<numvars; ++i)
+      names[i] = static_cast<char*>( calloc((MAX_STR_LENGTH+1), sizeof(char)) );
+
+    ErrChk( ex_get_variable_names( m_inFile,
+                                   EX_NODAL,
+                                   numvars,
+                                   names ) == 0,
+            "Failed to read nodal variable names from ExodusII file: " +
+            m_filename );
+
+    nv.resize( static_cast< std::size_t >( numvars ) );
+    std::size_t i = 0;
+    for (auto& n : nv) n = names[ i++ ];<--- Consider using std::fill or std::generate algorithm instead of a raw loop.
+
+  }
+
+  #if defined(__clang__)
+    #pragma clang diagnostic pop
+  #elif defined(STRICT_GNUC)
+    #pragma GCC diagnostic pop
+  #endif
+}
+
+void
+ExodusIIMeshReader::readElemVarNames( std::vector< std::string >& ev ) const
+// *****************************************************************************
+//  Read the names of elemental output variables from ExodusII file
+//! \param[in,out] ev Elemental variable names
+// *****************************************************************************
+{
+  #if defined(__clang__)
+    #pragma clang diagnostic push
+    #pragma clang diagnostic ignored "-Wvla"
+    #pragma clang diagnostic ignored "-Wvla-extension"
+  #elif defined(STRICT_GNUC)
+    #pragma GCC diagnostic push
+    #pragma GCC diagnostic ignored "-Wvla"
+  #endif
+
+  int numvars = 0;
+
+  ErrChk(
+    ex_get_variable_param( m_inFile, EX_ELEM_BLOCK, &numvars ) == 0,
+    "Failed to read element output variable parameters from ExodusII file: " +
+    m_filename );
+
+  if (numvars) {
+
+    char* names[ static_cast< std::size_t >( numvars ) ];
+    for (int i=0; i<numvars; ++i)
+      names[i] = static_cast<char*>( calloc((MAX_STR_LENGTH+1), sizeof(char)) );
+
+    ErrChk( ex_get_variable_names( m_inFile,
+                                   EX_ELEM_BLOCK,
+                                   numvars,
+                                   names ) == 0,
+            "Failed to read element variable names from ExodusII file: " +
+            m_filename );
+
+    ev.resize( static_cast< std::size_t >( numvars ) );
+    std::size_t i = 0;
+    for (auto& n : ev) n = names[ i++ ];<--- Consider using std::fill or std::generate algorithm instead of a raw loop.
+
+  }
+
+  #if defined(__clang__)
+    #pragma clang diagnostic pop
+  #elif defined(STRICT_GNUC)
+    #pragma GCC diagnostic pop
+  #endif
+}
+
+void
+ExodusIIMeshReader::readTimeValues( std::vector< tk::real >& tv ) const
+// *****************************************************************************
+//  Read time values from ExodusII file
+//! \param[in] tv Vector of time values at which field data is saved
+// *****************************************************************************
+{
+  auto num_time_steps =
+    static_cast< std::size_t >( ex_inquire_int( m_inFile, EX_INQ_TIME ) );
+
+  if (num_time_steps) {
+    tv.resize( num_time_steps, 0.0 );
+    ErrChk( ex_get_all_times( m_inFile, tv.data() ) == 0,
+             "Failed to read time values from ExodusII file: " + m_filename );
+  }
+}
+
+void
+ExodusIIMeshReader::readNodeScalars(
+  std::size_t ntime,
+  std::size_t nvar,
+  std::vector< std::vector< std::vector< tk::real > > >& var ) const
+// *****************************************************************************
+//  Read node scalar fields from ExodusII file
+//! \param[in] ntime Number of time steps to read
+//! \param[in] nvar Number of variables to read
+//! \param[in] var Vector of nodal variables to read to: inner vector: nodes,
+//!   middle vector: (physics) variable, outer vector: time step
+// *****************************************************************************
+{
+  var.resize( ntime );
+  for (auto& v : var) {
+    v.resize( nvar );
+    for (auto& n : v) n.resize( m_nnode );
+  }
+
+  for (std::size_t t=0; t<var.size(); ++t) {
+    for (std::size_t id=0; id<var[t].size(); ++id) {
+      ErrChk( ex_get_var( m_inFile,
+                          static_cast< int >( t+1 ),
+                          EX_NODAL,
+                          static_cast< int >( id+1 ),
+                          1,
+                          static_cast< int64_t >( var[t][id].size() ),
+                          var[t][id].data() ) == 0,
+              "Failed to read node scalar from ExodusII file: " + m_filename );
+    }
+  }
+}
+
+void
+ExodusIIMeshReader::readElemScalars(
+  std::size_t ntime,
+  std::size_t nvar,
+  std::vector< std::vector< std::vector< tk::real > > >& var ) const
+// *****************************************************************************
+//  Read element scalar fields from ExodusII file
+//! \param[in] ntime Number of time steps to read
+//! \param[in] nvar Number of variables to read
+//! \param[in] var Vector of elemental variables to read to: inner vector:
+//!   elements, middle vector: (physics) variable, outer vector: time step
+// *****************************************************************************
+{
+  var.resize( ntime );
+  for (auto& v : var) {
+    v.resize( nvar );
+    for (auto& n : v) n.resize( m_nelem );
+  }
+
+  for (std::size_t t=0; t<var.size(); ++t) {
+    for (std::size_t id=0; id<var[t].size(); ++id) {
+      ErrChk( ex_get_var( m_inFile,
+                          static_cast< int >( t+1 ),
+                          EX_ELEM_BLOCK,
+                          static_cast< int >( id+1 ),
+                          1,
+                          static_cast< int64_t >( var[t][id].size() ),
+                          var[t][id].data() ) == 0,
+              "Failed to read element scalar from ExodusII file: " +
+              m_filename );
+    }
+  }
+}
+
+std::size_t
+ExodusIIMeshReader::nelem( tk::ExoElemType elemtype ) const
+// *****************************************************************************
+//  Return number of elements in all mesh blocks for a given elem type in file
+//! \param[in] elemtype Element type
+//! \return Number of elements in all blocks for the elem type
+//! \note Must be preceded by a call to readElemBlockIDs()
+// *****************************************************************************
+{
+  auto e = static_cast< std::size_t >( elemtype );
+  return std::accumulate( m_nel[e].cbegin(), m_nel[e].cend(), 0u );
+}
 
diff --git a/Release/cppcheck/11.html b/Release/cppcheck/11.html index 8021e003c8cf..fa6ee5e40701 100644 --- a/Release/cppcheck/11.html +++ b/Release/cppcheck/11.html @@ -152,12 +152,12 @@
  1
@@ -357,204 +357,1258 @@ 

Cppcheck report - [

// *****************************************************************************
+198
+199
+200
+201
+202
+203
+204
+205
+206
+207
+208
+209
+210
+211
+212
+213
+214
+215
+216
+217
+218
+219
+220
+221
+222
+223
+224
+225
+226
+227
+228
+229
+230
+231
+232
+233
+234
+235
+236
+237
+238
+239
+240
+241
+242
+243
+244
+245
+246
+247
+248
+249
+250
+251
+252
+253
+254
+255
+256
+257
+258
+259
+260
+261
+262
+263
+264
+265
+266
+267
+268
+269
+270
+271
+272
+273
+274
+275
+276
+277
+278
+279
+280
+281
+282
+283
+284
+285
+286
+287
+288
+289
+290
+291
+292
+293
+294
+295
+296
+297
+298
+299
+300
+301
+302
+303
+304
+305
+306
+307
+308
+309
+310
+311
+312
+313
+314
+315
+316
+317
+318
+319
+320
+321
+322
+323
+324
+325
+326
+327
+328
+329
+330
+331
+332
+333
+334
+335
+336
+337
+338
+339
+340
+341
+342
+343
+344
+345
+346
+347
+348
+349
+350
+351
+352
+353
+354
+355
+356
+357
+358
+359
+360
+361
+362
+363
+364
+365
+366
+367
+368
+369
+370
+371
+372
+373
+374
+375
+376
+377
+378
+379
+380
+381
+382
+383
+384
+385
+386
+387
+388
+389
+390
+391
+392
+393
+394
+395
+396
+397
+398
+399
+400
+401
+402
+403
+404
+405
+406
+407
+408
+409
+410
+411
+412
+413
+414
+415
+416
+417
+418
+419
+420
+421
+422
+423
+424
+425
+426
+427
+428
+429
+430
+431
+432
+433
+434
+435
+436
+437
+438
+439
+440
+441
+442
+443
+444
+445
+446
+447
+448
+449
+450
+451
+452
+453
+454
+455
+456
+457
+458
+459
+460
+461
+462
+463
+464
+465
+466
+467
+468
+469
+470
+471
+472
+473
+474
+475
+476
+477
+478
+479
+480
+481
+482
+483
+484
+485
+486
+487
+488
+489
+490
+491
+492
+493
+494
+495
+496
+497
+498
+499
+500
+501
+502
+503
+504
+505
+506
+507
+508
+509
+510
+511
+512
+513
+514
+515
+516
+517
+518
+519
+520
+521
+522
+523
+524
+525
+526
+527
+528
+529
+530
+531
+532
+533
+534
+535
+536
+537
+538
+539
+540
+541
+542
+543
+544
+545
+546
+547
+548
+549
+550
+551
+552
+553
+554
+555
+556
+557
+558
+559
+560
+561
+562
+563
+564
+565
+566
+567
+568
+569
+570
+571
+572
+573
+574
+575
+576
+577
+578
+579
+580
+581
+582
+583
+584
+585
+586
+587
+588
+589
+590
+591
+592
+593
+594
+595
+596
+597
+598
+599
+600
+601
+602
+603
+604
+605
+606
+607
+608
+609
+610
+611
+612
+613
+614
+615
+616
+617
+618
+619
+620
+621
+622
+623
+624
+625
+626
+627
+628
+629
+630
+631
+632
+633
+634
+635
+636
+637
+638
+639
+640
+641
+642
+643
+644
+645
+646
+647
+648
+649
+650
+651
+652
+653
+654
+655
+656
+657
+658
+659
+660
+661
+662
+663
+664
+665
+666
+667
+668
+669
+670
+671
+672
+673
+674
+675
+676
+677
+678
+679
+680
+681
+682
+683
+684
+685
+686
+687
+688
+689
+690
+691
+692
+693
+694
+695
+696
+697
+698
+699
+700
+701
+702
+703
+704
+705
+706
+707
+708
+709
+710
+711
+712
+713
+714
+715
+716
+717
+718
+719
+720
+721
+722
+723
+724
+725
// *****************************************************************************
 /*!
-  \file      src/Base/TaggedTuple.hpp
+  \file      src/Base/Data.hpp
   \copyright 2012-2015 J. Bakosi,
              2016-2018 Los Alamos National Security, LLC.,
              2019-2021 Triad National Security, LLC.
              All rights reserved. See the LICENSE file for details.
-  \brief     Tagged tuple allowing tag-based access
-  \details   Tagged tuple allowing tag-based access. This is very much like
-    [std::tuple](http://en.cppreference.com/w/cpp/utility/tuple), but instead of
-    having to index the elements by integers, it allows access by a tag, which
-    can be an empty struct with a unique name. Credit goes to
-    ecatmur_at_stackoverflow.com, for more details, see
-    http://stackoverflow.com/questions/13065166/c11-tagged-tuple. For tags, see
-    Control/Tags.h. Tagged tuples are extensively used for transferring data
-    from the parser to an internal data structure in a type-save manner, which
-    is a tagged tuple containing a hierarchy of various containers. As an
-    example on how tagged tuples are used for parsing an input file, see
-    Control/Inciter/InputDeck/InputDeck.h. Another way to use a tagged tuple is
-    a compile-time associated container between tags and an arbitrary type.
-*/
-// *****************************************************************************
-#ifndef TaggedTuple_h
-#define TaggedTuple_h
+  \brief     Generic data storage with different memory layouts
+  \details   Generic data storage with different memory layouts. See also the
+    rationale discussed in the [design](layout.html) document.
+*/
+// *****************************************************************************
+#ifndef Data_h
+#define Data_h
+
+#include <array>
+#include <string>
+#include <cstdint>
+#include <vector>
+#include <set>
+#include <algorithm>
+
+#include "Types.hpp"
+#include "Exception.hpp"
 
-#include <type_traits>
-#include <tuple>
-
-#include <brigand/adapted/tuple.hpp>
-
-#include "NoWarning/any.hpp"
-#include "NoWarning/partition.hpp"
-#include "NoWarning/index_of.hpp"
-
-#include "PUPUtil.hpp"
-#include "Exception.hpp"
+#include "NoWarning/pup_stl.hpp"
+
+namespace tk {
+
+//! Tags for selecting data layout policies
+const uint8_t UnkEqComp = 0;
+const uint8_t EqCompUnk = 1;
+
+//! Zero-runtime-cost data-layout wrappers with type-based compile-time dispatch
+template< uint8_t Layout >
+class Data {
 
-namespace tag {
-//! Printable tag for TaggedTuple that returns its name
-#define DEFTAG(n) struct n { static const char* name() { return #n; } }
-} // tag::
-
-namespace tk {
-
-//! \brief Tagged tuple, allowing tag-based access
-//! \details "Tag" here is any type, but mostly an empty struct with a good name
-//!   for the data member
-//! \tparam List Type list as brigand::list
-//! \see https://stackoverflow.com/a/42988897
-//! \see https://gist.github.com/underdoeg/4c5c616c1ad4cbb718f787eefcab902d
-template< class List >
-class TaggedTuple{
-
-  private:
-    //! Generate index for every 2nd type of a type list
-    template< typename T >
-    using is_odd = brigand::size_t< (brigand::index_of<List,T>::value%2) != 0 >;
-
-    //! Partition a type list into two lists with the even and the odd types
-    using Pair = brigand::partition< List, brigand::bind<is_odd,brigand::_1> >;
-
-    //! List of member types
-    using Data = typename Pair::first_type;
-
-    //! Tuple of member types
-    using Tuple = brigand::as_tuple< Data >;
-
-    //! False-overload for detecting if T is a tagged tuple
-    template< typename T, typename = std::void_t<> >
-    struct is_tagged_tuple_t : std::false_type {};
-
-    //! True-overload for detecting if T is a tagged tuple
-    template< typename T >
-    struct is_tagged_tuple_t< T, std::void_t< typename T::i_am_tagged_tuple > >
-     : std::true_type {};
-
-    //! Member data as a tuple
-    Tuple m_members;
-
-  public:
-    //! List of key-value pairs
-    using PairList = List;
-
-    //! List of keys
-    using Keys = typename Pair::second_type;
-
-    //! Typedef defining self for identifying self
-    using i_am_tagged_tuple = void;
+  private:
+    //! \brief Inherit type of number of components from keyword 'ncomp'
+    using ncomp_t = tk::ncomp_t;
+
+  public:
+    //! Default constructor (required for Charm++ migration)
+    explicit Data() : m_vec(), m_nunk(), m_nprop() {}
+
+    //! Constructor
+    //! \param[in] nu Number of unknowns to allocate memory for
+    //! \param[in] np Total number of properties, i.e., scalar variables or
+    //!   components, per unknown
+    explicit Data( ncomp_t nu, ncomp_t np ) :
+      m_vec( nu*np ),
+      m_nunk( nu ),
+      m_nprop( np ) {}
+
+    //! Const data access dispatch
+    //! \details Public interface to const-ref data access to a single real
+    //!   value. Use it as Data(p,c), where p is the unknown index, and c is
+    //!   the component index specifying the scalar equation within a system of
+    //!   equations. Requirement: component <
+    //!   nprop, unknown < nunk, enforced with an assert in DEBUG mode, see also
+    //!   the constructor.
+    //! \param[in] unknown Unknown index
+    //! \param[in] component Component index, i.e., position of a scalar within
+    //!   a system
+    //! \return Const reference to data of type tk::real
+    const tk::real&
+    operator()( ncomp_t unknown, ncomp_t component ) const
+    { return access( unknown, component, int2type< Layout >() ); }
+
+    //! Non-const data access dispatch
+    //! \details Public interface to non-const-ref data access to a single real
+    //!   value. Use it as Data(p,c), where p is the unknown index, and c is
+    //!   the component index specifying the scalar equation within a system of
+    //!   equations. Requirement: component <
+    //!   nprop, unknown < nunk, enforced with an assert in DEBUG mode, see also
+    //!   the constructor.
+    //! \param[in] unknown Unknown index
+    //! \param[in] component Component index, i.e., position of a scalar within
+    //!   a system
+    //! \return Non-const reference to data of type tk::real
+    //! \see "Avoid Duplication in const and Non-const Member Function," and
+    //!   "Use const whenever possible," Scott Meyers, Effective C++, 3d ed.
+    tk::real&
+    operator()( ncomp_t unknown, ncomp_t component ) {
+      return const_cast< tk::real& >(
+               static_cast< const Data& >( *this ).
+                 operator()( unknown, component ) );
+    }
 
-    //! Acces type in tuple behind tag
-    template< typename Tag >
-    using TupleElement =
-      std::tuple_element_t< brigand::index_of<Keys,Tag>::value, Tuple >;
-
-    //! Query if the type behind Tag is a TaggedTuple
-    //! Usage: if constexpr( is_tagged_tuple<Tag>::value ) { ... }
-    template< typename Tag >
-    using is_tagged_tuple =
-      is_tagged_tuple_t< std::decay_t< TupleElement<Tag> > >;
-
-    //! Default constructor
-    explicit TaggedTuple() = default;
-    //! Initializer constructor
-    explicit TaggedTuple( Tuple&& tuple ) : m_members( std::move(tuple) ) {}
-
-    //! Const-ref access to member tuple
-    const Tuple& tuple() const { return m_members; }
-
-    //! Const-reference data member accessor of field of tagged tuple at depth
-    template< typename Tag, typename... Tags >
-    const auto& get() const noexcept {
-      constexpr std::size_t idx = brigand::index_of< Keys, Tag >::value;
-      if constexpr( is_tagged_tuple<Tag>::value and sizeof...(Tags) != 0 )
-        return std::get< idx >( m_members ).template get< Tags... >();
-      else
-        return std::get< idx >( m_members );
-    }
-
-    //! Reference data member accessor of field of tagged tuple at depth
-    template< typename Tag, typename... Tags >
-    auto& get() noexcept {<--- Syntax Error: AST broken, binary operator '>' doesn't have two operands.
-      constexpr std::size_t idx = brigand::index_of< Keys, Tag >::value;
-      if constexpr( is_tagged_tuple<Tag>::value and sizeof...(Tags) != 0 )
-        return std::get< idx >( m_members ).template get< Tags... >();
-      else
-        return std::get< idx >( m_members );
-    }
-
-    //! Convert and store value converting from string at depth
-    //! \param[in] value Value to convert and store
-    template< typename Tag, typename... Tags >
-    void store( const std::string& value ) noexcept {
-      if constexpr( is_tagged_tuple<Tag>::value and sizeof...(Tags) != 0 )
-      {
-        using T = std::remove_reference_t< decltype( get<Tag,Tags...>() ) >;
-        get< Tag, Tags... >() = convert< T >( value );
-      } else {
-        using T = std::remove_reference_t< decltype( get< Tag >() ) >;
-        get< Tag >() = convert< T >( value );
-      }
-    }
-
-    //! Operator == between two TaggedTuple objects
-    //! \tparam L Type list as brigand::list for other TaggedTuple
-    //! \return True if the lhs and rhs equal
-    template< typename L >
-    bool operator== ( const TaggedTuple< L >& t ) const {
-      static_assert( std::is_same_v< L, List >, "Invoking operator== on "
-        "TaggedTuple objects with different typelists" );
-      static_assert( !brigand::any< List,
-        std::is_floating_point<brigand::_1> >::value, "Invoking operator== on "
-        "TaggedTuple objects containing a floating point type is unreliable" );
-      return m_members == t.tuple();
-    }
-
-    //! Operator < between two TaggedTuple objects
-    //! \tparam L Type list as brigand::list for other TaggedTuple
-    //! \return True if lhs < rhs
-    template< typename L >
-    bool operator< ( const TaggedTuple< L >& t ) const {
-      static_assert( std::is_same_v< L, List >, "Invoking operator< on "
-        "TaggedTuple objects with different typelists" );
-      return m_members < t.tuple();
-    }
-
-    //! Return number of tuple entries
-    static constexpr std::size_t size() { return std::tuple_size_v< Tuple >; }
-
-    //! Pack/Unpack
-    /** @name Charm++ pack/unpack serializer member functions */
-    ///@{
-    //! \brief Pack/Unpack serialize member function
-    //! \param[in,out] p Charm++'s PUP::er serializer object reference
-    void pup( PUP::er& p ) { p | m_members; }<--- Parameter 'p' can be declared with const
-    //! \brief Pack/Unpack serialize operator|
-    //! \param[in,out] p Charm++'s PUP::er serializer object reference
-    //! \param[in,out] t TaggedTuple object reference
-    friend void operator|( PUP::er& p, TaggedTuple<List>& t ) { t.pup(p); }
-    //@}
+    //! Const ptr to physical variable access dispatch
+    //! \details Public interface to the first half of a physical variable
+    //!   access. cptr() and var() are two member functions intended to be used
+    //!   together in case when component would be expensive to
+    //!   compute for data access via the function call operator, i.e., cptr()
+    //!   can be used to pre-compute part of the address, which returns a
+    //!   pointer and var() can be used to finish the data access using the
+    //!   pointer returned by cptr(). In other words, cptr() returns part of the
+    //!   address known based on component and intended to be used in
+    //!   a setup phase. Then var() takes this partial address and finishes the
+    //!   address calculation given the unknown id. Thus the following two data
+    //!   accesses are equivalent (modulo constness):
+    //!   * real& value = operator()( unk, comp ); and
+    //!   * const real* p = cptr( comp ); and
+    //!     const real& value = var( p, unk ); or real& value = var( p, unk );
+    //!   Requirement: component < nprop, enforced with an assert in
+    //!   DEBUG mode, see also the constructor.
+    //! \param[in] component Component index, i.e., position of a scalar within
+    //!   a system
+    //! \return Pointer to data of type tk::real for use with var()
+    //! \see Example client code in Statistics::setupOrdinary() and
+    //!   Statistics::accumulateOrd() in Statistics/Statistics.C.
+    const tk::real*
+    cptr( ncomp_t component ) const
+    { return cptr( component, int2type< Layout >() ); }
+
+    //! Const-ref data-access dispatch
+    //! \details Public interface to the second half of a physical variable
+    //!   access. cptr() and var() are two member functions intended to be used
+    //!   together in case when component would be expensive to
+    //!   compute for data access via the function call operator, i.e., cptr()
+    //!   can be used to pre-compute part of the address, which returns a
+    //!   pointer and var() can be used to finish the data access using the
+    //!   pointer returned by cptr(). In other words, cptr() returns part of the
+    //!   address known based on component and intended to be used in
+    //!   a setup phase. Then var() takes this partial address and finishes the
+    //!   address calculation given the unknown id. Thus the following two data
+    //!   accesses are equivalent (modulo constness):
+    //!   * real& value = operator()( unk, comp ); and
+    //!   * const real* p = cptr( comp ); and
+    //!     const real& value = var( p, unk ); or real& value = var( p, unk );
+    //!   Requirement: unknown < nunk, enforced with an assert in DEBUG mode,
+    //!   see also the constructor.
+    //! \param[in] pt Pointer to data of type tk::real as returned from cptr()
+    //! \param[in] unknown Unknown index
+    //! \return Const reference to data of type tk::real
+    //! \see Example client code in Statistics::setupOrdinary() and
+    //!   Statistics::accumulateOrd() in Statistics/Statistics.C.
+    const tk::real&
+    var( const tk::real* pt, ncomp_t unknown ) const
+    { return var( pt, unknown, int2type< Layout >() ); }
+
+    //! Non-const-ref data-access dispatch
+    //! \details Public interface to the second half of a physical variable
+    //!   access. cptr() and var() are two member functions intended to be used
+    //!   together in case when component would be expensive to
+    //!   compute for data access via the function call operator, i.e., cptr()
+    //!   can be used to pre-compute part of the address, which returns a
+    //!   pointer and var() can be used to finish the data access using the
+    //!   pointer returned by cptr(). In other words, cptr() returns part of the
+    //!   address known based on component and intended to be used in
+    //!   a setup phase. Then var() takes this partial address and finishes the
+    //!   address calculation given the unknown id. Thus the following two data
+    //!   accesses are equivalent (modulo constness):
+    //!   * real& value = operator()( unk, comp ); and
+    //!   * const real* p = cptr( comp ); and
+    //!     const real& value = var( p, unk ); or real& value = var( p, unk );
+    //!   Requirement: unknown < nunk, enforced with an assert in DEBUG mode,
+    //!   see also the constructor.
+    //! \param[in] pt Pointer to data of type tk::real as returned from cptr()
+    //! \param[in] unknown Unknown index
+    //! \return Non-const reference to data of type tk::real
+    //! \see Example client code in Statistics::setupOrdinary() and
+    //!   Statistics::accumulateOrd() in Statistics/Statistics.C.
+    //! \see "Avoid Duplication in const and Non-const Member Function," and
+    //!   "Use const whenever possible," Scott Meyers, Effective C++, 3d ed.
+    tk::real&
+    var( const tk::real* pt, ncomp_t unknown ) {
+      return const_cast< tk::real& >(
+               static_cast< const Data& >( *this ).var( pt, unknown ) );
+    }
+
+    //! Access to number of unknowns
+    //! \return Number of unknowns
+    ncomp_t nunk() const noexcept { return m_nunk; }
+
+    //! Access to number of properties
+    //! \details This is the total number of scalar components per unknown
+    //! \return Number of propertes/unknown
+    ncomp_t nprop() const noexcept { return m_nprop; }
 
-    //! Convert/parse string to and return as type given by template argument
-    //! \param[in] str String to convert
-    //! \return A value of type given by the template argument
-    template< typename type >
-    type convert( const std::string& str ) {
-      std::stringstream ss( str );
-      type num;
-      ss >> std::boolalpha >> num;
-      if (ss.fail())
-        Throw( "Failed to convert '" + str +
-               "' to typeid " + typeid(num).name() );
-      return num;
-    }
-};
-
-} // tk::
-
-#endif // TaggedTuple_h
+    //! Extract flat vector of all unknowns
+    //! \return Flat vector of reals
+    std::vector< tk::real >
+    flat() const {
+      std::vector< tk::real > w( m_nunk * m_nprop );
+      for (std::size_t j=0; j<m_nprop; ++j)
+        for (std::size_t i=0; i<m_nunk; ++i)
+          w[i*m_nprop+j] = operator()( i, j );
+      return w;
+    }
+
+    //! Assign from flat vector
+    //! \param[in] rhs Flat vector to assign from
+    //! \note This is the opposite of flat().
+    void operator=( const std::vector< tk::real >& rhs ) {
+      Assert( rhs.size() == m_nunk * m_nprop, "Size mismatch" );
+      for (std::size_t j=0; j<m_nprop; ++j)
+        for (std::size_t i=0; i<m_nunk; ++i)
+          operator()( i, j ) = rhs[i*m_nprop+j];
+    }
+
+    //! Assign from array(3) of vectors
+    //! \param[in] rhs Array(3) of vectors to assign from
+    void operator=( const std::array< std::vector< tk::real >, 3 >& rhs ) {
+      Assert( m_nprop == 3, "Size mismatch" );
+      Assert( rhs[0].size() == m_nunk, "Size mismatch" );
+      Assert( rhs[1].size() == m_nunk, "Size mismatch" );
+      Assert( rhs[2].size() == m_nunk, "Size mismatch" );
+      for (std::size_t j=0; j<3; ++j)
+        for (std::size_t i=0; i<m_nunk; ++i)
+          operator()( i, j ) = rhs[j][i];
+    }
+
+    //! Extract vector of unknowns given component
+    //! \details Requirement: component < nprop, enforced with an
+    //!   assert in DEBUG mode, see also the constructor.
+    //! \param[in] component Component index, i.e., position of a scalar within
+    //!   a system
+    //! \return A vector of unknowns given by component (length:
+    //!   nunk(), i.e., the first constructor argument)
+    std::vector< tk::real >
+    extract_comp( ncomp_t component ) const {
+      std::vector< tk::real > w( m_nunk );
+      for (ncomp_t i=0; i<m_nunk; ++i)
+        w[i] = operator()( i, component );
+      return w;
+    }
+
+    //! Extract (a copy of) all components for an unknown
+    //! \details Requirement: unknown < nunk, enforced with an assert in DEBUG
+    //!   mode, see also the constructor.
+    //! \param[in] unknown Index of unknown
+    //! \return A vector of components for a single unknown (length: nprop,
+    //!   i.e., the second constructor argument)
+    std::vector< tk::real >
+    extract( ncomp_t unknown ) const {
+      std::vector< tk::real > w( m_nprop );
+      for (ncomp_t i=0; i<m_nprop; ++i) w[i] = operator()( unknown, i );
+      return w;
+    }
+
+    //! Extract all components for unknown
+    //! \details Requirement: unknown < nunk, enforced with an assert in DEBUG
+    //!   mode, see also the constructor.
+    //! \param[in] unknown Index of unknown
+    //! \return A vector of components for a single unknown (length: nprop,
+    //!   i.e., the second constructor argument)
+    //! \note This is simply an alias for extract( unknown )
+    std::vector< tk::real >
+    operator[]( ncomp_t unknown ) const { return extract( unknown ); }
+
+    //! Extract (a copy of) four values of unknowns
+    //! \details Requirement: component < nprop, [A,B,C,D] < nunk,
+    //!   enforced with an assert in DEBUG mode, see also the constructor.
+    //! \param[in] component Component index, i.e., position of a scalar within
+    //!   a system
+    //! \param[in] A Index of 1st unknown
+    //! \param[in] B Index of 2nd unknown
+    //! \param[in] C Index of 3rd unknown
+    //! \param[in] D Index of 4th unknown
+    //! \return Array of the four values of component
+    std::array< tk::real, 4 >
+    extract( ncomp_t component,
+             ncomp_t A, ncomp_t B, ncomp_t C, ncomp_t D ) const
+    {
+      auto p = cptr( component );
+      return {{ var(p,A), var(p,B), var(p,C), var(p,D) }};
+    }
+
+    //! Extract (a copy of) four values of unknowns
+    //! \details Requirement: component < nprop, for all N[i] < nunk,
+    //!   enforced with an assert in DEBUG mode, see also the constructor.
+    //! \param[in] component Component index, i.e., position of a scalar within
+    //!   a system
+    //! \param[in] N Indices of the 4 unknowns
+    //! \return Array of the four values of component
+    std::array< tk::real, 4 >
+    extract( ncomp_t component,
+             const std::array< ncomp_t, 4 >& N ) const
+    {
+      return extract( component, N[0], N[1], N[2], N[3] );
+    }
+
+    //! Extract (a copy of) three values of unknowns
+    //! \details Requirement: component < nprop, [A,B,C] < nunk,
+    //!   enforced with an assert in DEBUG mode, see also the constructor.
+    //! \param[in] component Component index, i.e., position of a scalar within
+    //!   a system
+    //! \param[in] A Index of 1st unknown
+    //! \param[in] B Index of 2nd unknown
+    //! \param[in] C Index of 3rd unknown
+    //! \return Array of the four values of component
+    std::array< tk::real, 3 >
+    extract( ncomp_t component,
+             ncomp_t A, ncomp_t B, ncomp_t C ) const
+    {
+      auto p = cptr( component );
+      return {{ var(p,A), var(p,B), var(p,C) }};
+    }
+
+    //! Extract (a copy of) three values of unknowns
+    //! \details Requirement: component < nprop, for all N[i] < nunk,
+    //!   enforced with an assert in DEBUG mode, see also the constructor.
+    //! \param[in] component Component index, i.e., position of a scalar within
+    //!   a system
+    //! \param[in] N Indices of the 3 unknowns
+    //! \return Array of the three values of component
+    std::array< tk::real, 3 >
+    extract( ncomp_t component,
+             const std::array< ncomp_t, 3 >& N ) const
+    {
+      return extract( component, N[0], N[1], N[2] );
+    }
+
+    //! Const-ref accessor to underlying raw data as a std::vector
+    //! \return Constant reference to underlying raw data
+    const std::vector< tk::real >& vec() const { return m_vec; }
+
+    //! Non-const-ref accessor to underlying raw data as a std::vector
+    //! \return Non-constant reference to underlying raw data
+    std::vector< tk::real >& vec() { return m_vec; }
+
+    //! Compound operator-=
+    //! \param[in] rhs Data object to subtract
+    //! \return Reference to ourselves after subtraction
+    Data< Layout >& operator-= ( const Data< Layout >& rhs ) {
+      Assert( rhs.nunk() == m_nunk, "Incorrect number of unknowns" );
+      Assert( rhs.nprop() == m_nprop, "Incorrect number of properties" );
+      std::transform( rhs.vec().cbegin(), rhs.vec().cend(),
+                      m_vec.cbegin(), m_vec.begin(),
+                      []( tk::real s, tk::real d ){ return d-s; } );
+      return *this;
+    }
+    //! Operator -
+    //! \param[in] rhs Data object to subtract
+    //! \return Copy of Data object after rhs has been subtracted
+    //! \details Implemented in terms of compound operator-=
+    Data< Layout > operator- ( const Data< Layout >& rhs )
+    const { return Data< Layout >( *this ) -= rhs; }
+
+    //! Compound operator+=
+    //! \param[in] rhs Data object to add
+    //! \return Reference to ourselves after addition
+    Data< Layout >& operator+= ( const Data< Layout >& rhs ) {
+      Assert( rhs.nunk() == m_nunk, "Incorrect number of unknowns" );
+      Assert( rhs.nprop() == m_nprop, "Incorrect number of properties" );
+      std::transform( rhs.vec().cbegin(), rhs.vec().cend(),
+                      m_vec.cbegin(), m_vec.begin(),
+                      []( tk::real s, tk::real d ){ return d+s; } );
+      return *this;
+    }
+    //! Operator +
+    //! \param[in] rhs Data object to add
+    //! \return Copy of Data object after rhs has been multiplied with
+    //! \details Implemented in terms of compound operator+=
+    Data< Layout > operator+ ( const Data< Layout >& rhs )
+    const { return Data< Layout >( *this ) += rhs; }
+
+    //! Compound operator*= multiplying by another Data object item by item
+    //! \param[in] rhs Data object to multiply with
+    //! \return Reference to ourselves after multiplication
+    Data< Layout >& operator*= ( const Data< Layout >& rhs ) {
+      Assert( rhs.nunk() == m_nunk, "Incorrect number of unknowns" );
+      Assert( rhs.nprop() == m_nprop, "Incorrect number of properties" );
+      std::transform( rhs.vec().cbegin(), rhs.vec().cend(),
+                      m_vec.cbegin(), m_vec.begin(),
+                      []( tk::real s, tk::real d ){ return d*s; } );
+      return *this;
+    }
+    //! Operator * multiplying by another Data object item by item
+    //! \param[in] rhs Data object to multiply with
+    //! \return Copy of Data object after rhs has been multiplied with
+    //! \details Implemented in terms of compound operator*=
+    Data< Layout > operator* ( const Data< Layout >& rhs )
+    const { return Data< Layout >( *this ) *= rhs; }
+
+    //! Compound operator*= multiplying all items by a scalar
+    //! \param[in] rhs Scalar to multiply with
+    //! \return Reference to ourselves after multiplication
+    Data< Layout >& operator*= ( tk::real rhs ) {
+      // cppcheck-suppress useStlAlgorithm
+      for (auto& v : m_vec) v *= rhs;
+      return *this;
+    }
+    //! Operator * multiplying all items by a scalar
+    //! \param[in] rhs Scalar to multiply with
+    //! \return Copy of Data object after rhs has been multiplied with
+    //! \details Implemented in terms of compound operator*=
+    Data< Layout > operator* ( tk::real rhs )
+    const { return Data< Layout >( *this ) *= rhs; }
+
+    //! Compound operator/=
+    //! \param[in] rhs Data object to divide by
+    //! \return Reference to ourselves after division
+    Data< Layout >& operator/= ( const Data< Layout >& rhs ) {
+      Assert( rhs.nunk() == m_nunk, "Incorrect number of unknowns" );
+      Assert( rhs.nprop() == m_nprop, "Incorrect number of properties" );
+      std::transform( rhs.vec().cbegin(), rhs.vec().cend(),
+                      m_vec.cbegin(), m_vec.begin(),
+                      []( tk::real s, tk::real d ){ return d/s; } );
+      return *this;
+    }
+    //! Operator /
+    //! \param[in] rhs Data object to divide by
+    //! \return Copy of Data object after rhs has been divided by
+    //! \details Implemented in terms of compound operator/=
+    Data< Layout > operator/ ( const Data< Layout >& rhs )
+    const { return Data< Layout >( *this ) /= rhs; }
+
+    //! Compound operator/= dividing all items by a scalar
+    //! \param[in] rhs Scalar to divide with
+    //! \return Reference to ourselves after division
+    Data< Layout >& operator/= ( tk::real rhs ) {
+      // cppcheck-suppress useStlAlgorithm
+      for (auto& v : m_vec) v /= rhs;
+      return *this;
+    }
+    //! Operator / dividing all items by a scalar
+    //! \param[in] rhs Scalar to divide with
+    //! \return Copy of Data object after rhs has been divided by
+    //! \details Implemented in terms of compound operator/=
+    Data< Layout > operator/ ( tk::real rhs )
+    const { return Data< Layout >( *this ) /= rhs; }
+
+    //! Add new unknown at the end of the container
+    //! \param[in] prop Vector of properties to initialize the new unknown with
+    void push_back( const std::vector< tk::real >& prop )
+    { return push_back( prop, int2type< Layout >() ); }
+
+    //! Resize data store to contain 'count' elements
+    //! \param[in] count Resize store to contain count * nprop elements
+    //! \param[in] value Value to initialize new data with (default: 0.0)
+    //! \note This works for both shrinking and enlarging, as this simply
+    //!   translates to std::vector::resize(). Note that count changes, nprop
+    //!   does not, see the private overload resize().
+    void resize( std::size_t count, tk::real value = 0.0 )
+    { resize( count, value, int2type< Layout >() ); }
+
+    //! Remove a number of unknowns
+    //! \param[in] unknown Set of indices of unknowns to remove
+    void rm( const std::set< ncomp_t >& unknown ) {
+      auto remove = [ &unknown ]( std::size_t i ) -> bool {
+        if (unknown.find(i) != end(unknown)) return true;
+        return false;
+      };
+      std::size_t last = 0;
+      for(std::size_t i=0; i<m_nunk; ++i, ++last) {
+        while( remove(i) ) ++i;
+        if (i >= m_nunk) break;
+        for (ncomp_t p = 0; p<m_nprop; ++p)
+          m_vec[ last*m_nprop+p ] = m_vec[ i*m_nprop+p ];
+      }
+      m_vec.resize( last*m_nprop );
+      m_nunk -= unknown.size();
+    }
+
+    //! Fill vector of unknowns with the same value
+    //! \details Requirement: component < nprop, enforced with an
+    //!   assert in DEBUG mode, see also the constructor.
+    //! \param[in] component Component index, i.e., position of a scalar within
+    //!   a system
+    //! \param[in] value Value to fill vector of unknowns with
+    inline void fill( ncomp_t component, tk::real value ) {
+      auto p = cptr( component );
+      for (ncomp_t i=0; i<m_nunk; ++i) var(p,i) = value;
+    }
+
+    //! Fill full data storage with value
+    //! \param[in] value Value to fill data with
+    void fill( tk::real value )
+    { std::fill( begin(m_vec), end(m_vec), value ); }
+
+    //! Check if vector of unknowns is empty
+    bool empty() const noexcept { return m_vec.empty(); }
+
+    //! Layout name dispatch
+    //! \return The name of the data layout used
+    static std::string layout() { return layout( int2type< Layout >() ); }
+
+    /** @name Pack/Unpack: Serialize Data object for Charm++ */
+    ///@{
+    //! \brief Pack/Unpack serialize member function
+    //! \param[in,out] p Charm++'s PUP::er serializer object reference
+    void pup( PUP::er &p ) {<--- Parameter 'p' can be declared with const
+      p | m_vec;
+      p | m_nunk;
+      p | m_nprop;
+    }
+    //! \brief Pack/Unpack serialize operator|
+    //! \param[in,out] p Charm++'s PUP::er serializer object reference
+    //! \param[in,out] d DataLyaout object reference
+    friend void operator|( PUP::er& p, Data& d ) { d.pup(p); }
+    //@}
+
+  private:
+    //! Transform a compile-time uint8_t into a type, used for dispatch
+    //! \see A. Alexandrescu, Modern C++ Design: Generic Programming and Design
+    //!   Patterns Applied, Addison-Wesley Professional, 2001.
+    template< uint8_t m > struct int2type { enum { value = m }; };
+
+    //! Overloads for the various const data accesses
+    //! \details Requirement: component < nprop, unknown < nunk,
+    //!   enforced with an assert in DEBUG mode, see also the constructor.
+    //! \param[in] unknown Unknown index
+    //! \param[in] component Component index, i.e., position of a scalar within
+    //!   a system
+    //! \return Const reference to data of type tk::real
+    //! \see A. Alexandrescu, Modern C++ Design: Generic Programming and Design
+    //!   Patterns Applied, Addison-Wesley Professional, 2001.
+    const tk::real&
+    access( ncomp_t unknown, ncomp_t component, int2type< UnkEqComp > ) const
+    {
+      Assert( component < m_nprop, "Out-of-bounds access: "
+              "component < number of properties" );
+      Assert( unknown < m_nunk, "Out-of-bounds access: unknown < number of "
+              "unknowns" );
+      return m_vec[ unknown*m_nprop + component ];
+    }
+    const tk::real&
+    access( ncomp_t unknown, ncomp_t component, int2type< EqCompUnk > ) const
+    {
+      Assert( component < m_nprop, "Out-of-bounds access: "
+              "component < number of properties" );
+      Assert( unknown < m_nunk, "Out-of-bounds access: unknown < number of "
+              "unknowns" );
+      return m_vec[ (component)*m_nunk + unknown ];
+    }
+
+    // Overloads for the various const ptr to physical variable accesses
+    //! \details Requirement: component < nprop, unknown < nunk,
+    //!   enforced with an assert in DEBUG mode, see also the constructor.
+    //! \param[in] component Component index, i.e., position of a scalar within
+    //!   a system
+    //! \return Pointer to data of type tk::real for use with var()
+    //! \see A. Alexandrescu, Modern C++ Design: Generic Programming and Design
+    //!   Patterns Applied, Addison-Wesley Professional, 2001.
+    const tk::real*
+    cptr( ncomp_t component, int2type< UnkEqComp > ) const {
+      Assert( component < m_nprop, "Out-of-bounds access: "
+              "component < number of properties" );
+      return m_vec.data() + component;
+    }
+    const tk::real*
+    cptr( ncomp_t component, int2type< EqCompUnk > ) const {
+      Assert( component < m_nprop, "Out-of-bounds access: "
+              "component < number of properties" );
+      return m_vec.data() + (component)*m_nunk;
+    }
+
+    // Overloads for the various const physical variable accesses
+    //!   Requirement: unknown < nunk, enforced with an assert in DEBUG mode,
+    //!   see also the constructor.
+    //! \param[in] pt Pointer to data of type tk::real as returned from cptr()
+    //! \param[in] unknown Unknown index
+    //! \return Const reference to data of type tk::real
+    //! \see A. Alexandrescu, Modern C++ Design: Generic Programming and Design
+    //!   Patterns Applied, Addison-Wesley Professional, 2001.
+    inline const tk::real&
+    var( const tk::real* const pt, ncomp_t unknown, int2type< UnkEqComp > )
+    const {
+      Assert( unknown < m_nunk, "Out-of-bounds access: unknown < number of "
+              "unknowns" );
+      return *(pt + unknown*m_nprop);
+    }
+    inline const tk::real&
+    var( const tk::real* const pt, ncomp_t unknown, int2type< EqCompUnk > )
+    const {
+      Assert( unknown < m_nunk, "Out-of-bounds access: unknown < number of "
+              "unknowns" );
+      return *(pt + unknown);
+    }
+
+    //! Add new unknown
+    //! \param[in] prop Vector of properties to initialize the new unknown with
+    //! \note Only the UnkEqComp overload is provided as this operation would be
+    //!   too inefficient with the EqCompUnk data layout.
+    void push_back( const std::vector< tk::real >& prop, int2type< UnkEqComp > )
+    {
+      Assert( prop.size() == m_nprop, "Incorrect number of properties" );
+      m_vec.resize( (m_nunk+1) * m_nprop );
+      ncomp_t u = m_nunk;
+      ++m_nunk;
+      for (ncomp_t i=0; i<m_nprop; ++i) operator()( u, i ) = prop[i];
+    }
+
+    void push_back( const std::vector< tk::real >&, int2type< EqCompUnk > )
+    { Throw( "Not implented. It would be inefficient" ); }
+
+    //! Resize data store to contain 'count' elements
+    //! \param[in] count Resize store to contain 'count' elements
+    //! \param[in] value Value to initialize new data with
+    //! \note Only the UnkEqComp overload is provided as this operation would be
+    //!   too inefficient with the EqCompUnk data layout.
+    //! \note This works for both shrinking and enlarging, as this simply
+    //!   translates to std::vector::resize().
+    void resize( std::size_t count, tk::real value, int2type< UnkEqComp > ) {
+      m_vec.resize( count * m_nprop, value );
+      m_nunk = count;
+    }
+
+    void resize( std::size_t, tk::real, int2type< EqCompUnk > ) {
+      Throw( "Not implemented. It would be inefficient" );
+    }
+
+    // Overloads for the name-queries of data lauouts
+    //! \return The name of the data layout used
+    //! \see A. Alexandrescu, Modern C++ Design: Generic Programming and Design
+    //!   Patterns Applied, Addison-Wesley Professional, 2001.
+    static std::string layout( int2type< UnkEqComp > )
+    { return "unknown-major"; }
+    static std::string layout( int2type< EqCompUnk > )
+    { return "equation-major"; }
+
+    std::vector< tk::real > m_vec;      //!< Data pointer
+    ncomp_t m_nunk;                     //!< Number of unknowns
+    ncomp_t m_nprop;                    //!< Number of properties/unknown
+};
+
+//! Operator * multiplying all items by a scalar from the left
+//! \param[in] lhs Scalar to multiply with
+//! \param[in] rhs Date object to multiply
+//! \return New Data object with all items multipled with lhs
+template< uint8_t Layout >
+Data< Layout > operator* ( tk::real lhs, const Data< Layout >& rhs ) {
+  return Data< Layout >( rhs ) *= lhs;
+}
+
+//! Operator min between two Data objects
+//! \param[in] a 1st Data object
+//! \param[in] b 2nd Data object
+//! \return New Data object containing the minimum of all values for each
+//!   value in _a_ and _b_
+//! \note The Data objects _a_ and _b_ must have the same number of
+//!   unknowns and properties.
+//! \note As opposed to std::min, this function creates and returns a new object
+//!   instead of returning a reference to one of the operands.
+template< uint8_t Layout >
+Data< Layout > min( const Data< Layout >& a, const Data< Layout >& b ) {
+  Assert( a.nunk() == b.nunk(), "Number of unknowns unequal" );
+  Assert( a.nprop() == b.nprop(), "Number of properties unequal" );
+  Data< Layout > r( a.nunk(), a.nprop() );
+  std::transform( a.vec().cbegin(), a.vec().cend(),
+                  b.vec().cbegin(), r.vec().begin(),
+                  []( tk::real s, tk::real d ){ return std::min(s,d); } );
+
+  return r;
+}
+
+//! Operator max between two Data objects
+//! \param[in] a 1st Data object
+//! \param[in] b 2nd Data object
+//! \return New Data object containing the maximum of all values for each
+//!   value in _a_ and _b_
+//! \note The Data objects _a_ and _b_ must have the same number of
+//!   unknowns and properties.
+//! \note As opposed to std::max, this function creates and returns a new object
+//!   instead of returning a reference to one of the operands.
+template< uint8_t Layout >
+Data< Layout > max( const Data< Layout >& a, const Data< Layout >& b ) {
+  Assert( a.nunk() == b.nunk(), "Number of unknowns unequal" );
+  Assert( a.nprop() == b.nprop(), "Number of properties unequal" );
+  Data< Layout > r( a.nunk(), a.nprop() );
+  std::transform( a.vec().cbegin(), a.vec().cend(),
+                  b.vec().cbegin(), r.vec().begin(),
+                  []( tk::real s, tk::real d ){ return std::max(s,d); } );
+  return r;
+}
+
+//! Operator == between two Data objects
+//! \param[in] lhs Data object to compare
+//! \param[in] rhs Data object to compare
+//! \return True if all entries are equal up to epsilon
+template< uint8_t Layout >
+bool operator== ( const Data< Layout >& lhs, const Data< Layout >& rhs ) {
+  Assert( rhs.nunk() == lhs.nunk(), "Incorrect number of unknowns" );
+  Assert( rhs.nprop() == lhs.nprop(), "Incorrect number of properties" );
+  auto l = lhs.vec().cbegin();
+  auto r = rhs.vec().cbegin();
+  while (l != lhs.vec().cend()) {
+    if (std::abs(*l - *r) > std::numeric_limits< tk::real >::epsilon())
+     return false;
+    ++l; ++r;
+  }
+  return true;
+}
+
+//! Operator != between two Data objects
+//! \param[in] lhs Data object to compare
+//! \param[in] rhs Data object to compare
+//! \return True if all entries are unequal up to epsilon
+template< uint8_t Layout >
+bool operator!= ( const Data< Layout >& lhs, const Data< Layout >& rhs )
+{ return !(lhs == rhs); }
+
+//! Compute the maximum difference between the elements of two Data objects
+//! \param[in] lhs 1st Data object
+//! \param[in] rhs 2nd Data object
+//! \return The index, i.e., the raw position, of and the largest absolute value
+//!   of the difference between all corresponding elements of _lhs_ and _rhs_.
+//! \details The position returned is the position in the underlying raw data
+//!   structure, independent of components, etc. If lhs == rhs with
+//!   precision  std::numeric_limits< tk::real >::epsilon(), a pair of (0,0.0)
+//!   is returned.
+//! \note The Data objects _lhs_ and _rhs_ must have the same number of
+//!   unknowns and properties.
+template< uint8_t Layout >
+std::pair< std::size_t, tk::real >
+maxdiff( const Data< Layout >& lhs, const Data< Layout >& rhs ) {
+  Assert( lhs.nunk() == rhs.nunk(), "Number of unknowns unequal" );
+  Assert( lhs.nprop() == rhs.nprop(), "Number of properties unequal" );
+  auto l = lhs.vec().cbegin();
+  auto r = rhs.vec().cbegin();
+  std::pair< std::size_t, tk::real > m( 0, std::abs(*l - *r) );
+  ++l; ++r;
+  while (l != lhs.vec().cend()) {
+    const auto d = std::abs(*l - *r);
+    if (d > m.second) m = { std::distance(lhs.vec().cbegin(),l), d };
+    ++l; ++r;
+  }
+  return m;
+}
+
+} // tk::
+
+#endif // Data_h
 
diff --git a/Release/cppcheck/12.html b/Release/cppcheck/12.html index 40c4015d0c50..ceb8598f1983 100644 --- a/Release/cppcheck/12.html +++ b/Release/cppcheck/12.html @@ -152,12 +152,12 @@
  1
@@ -357,962 +357,204 @@ 

Cppcheck report - [

// *****************************************************************************
+198
// *****************************************************************************
 /*!
-  \file      src/LinearSolver/ConjugateGradients.cpp
+  \file      src/Base/TaggedTuple.hpp
   \copyright 2012-2015 J. Bakosi,
              2016-2018 Los Alamos National Security, LLC.,
              2019-2021 Triad National Security, LLC.
              All rights reserved. See the LICENSE file for details.
-  \brief     Charm++ chare array for distributed conjugate gradients.
-  \details   Charm++ chare array for asynchronous distributed
-    conjugate gradients linear solver.
-  \see Y. Saad, Iterative Methods for Sparse Linear Systems: Second Edition,
-    ISBN 9780898718003, 2003, Algorithm 6.18, conjugate gradients to solve the
-    linear system A * x = b, reproduced here:
-
-    Compute r0:=b-A*x0, p0:=r0
-    For j=0,1,..., until convergence, do
-      alpha_j := (r_j,r_j) / (Ap_j,p_j)
-      x_{j+1} := x_j + alpha_j p_j
-      r_{j+1} := r_j - alpha_j A p_j
-      beta_j := (r_{j+1},r_{j+1}) / (r_j,r_j)
-      p_{j+1} := r_{j+1} + beta_j p_j
-    end
-*/
-// *****************************************************************************
+  \brief     Tagged tuple allowing tag-based access
+  \details   Tagged tuple allowing tag-based access. This is very much like
+    [std::tuple](http://en.cppreference.com/w/cpp/utility/tuple), but instead of
+    having to index the elements by integers, it allows access by a tag, which
+    can be an empty struct with a unique name. Credit goes to
+    ecatmur_at_stackoverflow.com, for more details, see
+    http://stackoverflow.com/questions/13065166/c11-tagged-tuple. For tags, see
+    Control/Tags.h. Tagged tuples are extensively used for transferring data
+    from the parser to an internal data structure in a type-save manner, which
+    is a tagged tuple containing a hierarchy of various containers. As an
+    example on how tagged tuples are used for parsing an input file, see
+    Control/Inciter/InputDeck/InputDeck.h. Another way to use a tagged tuple is
+    a compile-time associated container between tags and an arbitrary type.
+*/
+// *****************************************************************************
+#ifndef TaggedTuple_h
+#define TaggedTuple_h
 
-#include <numeric>
-#include <iostream>
+#include <type_traits>
+#include <tuple>
 
-#include "Exception.hpp"
-#include "ConjugateGradients.hpp"
-#include "Vector.hpp"
-
-using tk::ConjugateGradients;
+#include <brigand/adapted/tuple.hpp>
+
+#include "NoWarning/any.hpp"
+#include "NoWarning/partition.hpp"
+#include "NoWarning/index_of.hpp"
 
-ConjugateGradients::ConjugateGradients(<--- Member variable 'ConjugateGradients::m_tol' is not initialized in the constructor.
-  const CSR& A,
-  const std::vector< tk::real >& x,
-  const std::vector< tk::real >& b,
-  const std::vector< std::size_t >& gid,
-  const std::unordered_map< std::size_t, std::size_t >& lid,
-  const NodeCommMap& nodecommmap ) :
-  m_A( A ),
-  m_x( x ),
-  m_b( b ),
-  m_gid( gid ),
-  m_lid( lid ),
-  m_nodeCommMap( nodecommmap ),
-  m_r( m_A.rsize(), 0.0 ),
-  m_rc(),
-  m_nr( 0 ),
-  m_bc(),
-  m_bcc(),
-  m_bcmask( m_A.rsize(), 1.0 ),
-  m_nb( 0 ),
-  m_p( m_A.rsize(), 0.0 ),
-  m_q( m_A.rsize(), 0.0 ),
-  m_qc(),
-  m_nq( 0 ),
-  m_initres(),
-  m_solved(),
-  m_normb( 0.0 ),
-  m_it( 0 ),
-  m_maxit( 0 ),
-  m_rho( 0.0 ),
-  m_rho0( 0.0 ),
-  m_alpha( 0.0 ),
-  m_converged( false ),
-  m_xc(),
-  m_nx( 0 )
-// *****************************************************************************
-//  Constructor
-//! \param[in] A Left hand side matrix of the linear system to solve in Ax=b
-//! \param[in] x Solution (initial guess) of the linear system to solve in Ax=b
-//! \param[in] b Right hand side of the linear system to solve in Ax=b
-//! \param[in] gid Global node ids
-//! \param[in] lid Local node ids associated to global ones
-//! \param[in] nodecommmap Global mesh node IDs shared with other chares
-//!   associated to their chare IDs
-// *****************************************************************************
-{
-  // Fill in gid and lid for serial solve
-  if (gid.empty() || lid.empty() || nodecommmap.empty()) {
-    m_gid.resize( m_A.rsize()/m_A.Ncomp() );
-    std::iota( begin(m_gid), end(m_gid), 0 );
-    for (auto g : m_gid) m_lid[g] = g;
-  }
-
-  Assert( m_A.rsize() == m_gid.size()*A.Ncomp(), "Size mismatch" );
-  Assert( m_x.size() == m_gid.size()*A.Ncomp(), "Size mismatch" );
-  Assert( m_b.size() == m_gid.size()*A.Ncomp(), "Size mismatch" );
-}
-
-void
-ConjugateGradients::setup( CkCallback c )
-// *****************************************************************************
-//  Setup solver
-//! \param[in] c Call to continue with after initialization is complete
-//! \details This function initiates computing the residual (r=b-A*x), its dot
-//!   product, and the rhs norm.
-// *****************************************************************************
-{
-  m_initres = c;
-
-  // initiate computing A * x (for the initial residual)
-  thisProxy[ thisIndex ].wait4res();
-  residual();
-
-  // initiate computing norm of right hand side
-  dot( m_b, m_b,
-       CkCallback( CkReductionTarget(ConjugateGradients,normb), thisProxy ) );
-}
-
-void
-ConjugateGradients::dot( const std::vector< tk::real >& a,
-                         const std::vector< tk::real >& b,
-                         CkCallback c )
-// *****************************************************************************
-//  Initiate computation of dot product of two vectors
-//! \param[in] a 1st vector of dot product
-//! \param[in] b 2nd vector of dot product
-//! \param[in] c Callback to target with the final result
-// *****************************************************************************
-{
-  Assert( a.size() == b.size(), "Size mismatch" );
-
-  tk::real D = 0.0;
-  auto ncomp = m_A.Ncomp();
-  for (std::size_t i=0; i<a.size()/ncomp; ++i) {
-    auto incomp = i*ncomp;
-    if (not slave(m_nodeCommMap,m_gid[i],thisIndex))
-      for (std::size_t d=0; d<ncomp; ++d)
-        D += a[incomp+d] * b[incomp+d];
-  }
-
-  contribute( sizeof(tk::real), &D, CkReduction::sum_double, c );
-}
-
-void
-ConjugateGradients::normb( tk::real n )
-// *****************************************************************************
-// Compute the norm of the right hand side
-//! \param[in] n Norm of right hand side (aggregated across all chares)
-// *****************************************************************************
-{
-  m_normb = std::sqrt(n);
-  normb_complete();
-}
-
-void
-ConjugateGradients::residual()
-// *****************************************************************************
-//  Initiate A * x for computing the initial residual, r = b - A * x
-// *****************************************************************************
-{
-  // Compute own contribution to r = A * x
-  m_A.mult( m_x, m_r, m_bcmask );
-
-  // Send partial product on chare-boundary nodes to fellow chares
-  if (m_nodeCommMap.empty()) {
-    comres_complete();
-  } else {
-    auto ncomp = m_A.Ncomp();
-    for (const auto& [c,n] : m_nodeCommMap) {
-      std::vector< std::vector< tk::real > > rc( n.size() );
-      std::size_t j = 0;
-      for (auto g : n) {
-        std::vector< tk::real > nr( ncomp );
-        auto i = tk::cref_find( m_lid, g );
-        for (std::size_t d=0; d<ncomp; ++d) nr[d] = m_r[ i*ncomp+d ];
-        rc[j++] = std::move(nr);
-      }
-      thisProxy[c].comres( std::vector<std::size_t>(begin(n),end(n)), rc );
-    }
-  }
-
-  ownres_complete();
-}
-
-void
-ConjugateGradients::comres( const std::vector< std::size_t >& gid,
-                            const std::vector< std::vector< tk::real > >& rc )
-// *****************************************************************************
-//  Receive contributions to A * x on chare-boundaries
-//! \param[in] gid Global mesh node IDs at which we receive contributions
-//! \param[in] rc Partial contributions at chare-boundary nodes
-// *****************************************************************************
-{
-  Assert( rc.size() == gid.size(), "Size mismatch" );
-
-  using tk::operator+=;
-
-  for (std::size_t i=0; i<gid.size(); ++i)
-    m_rc[ gid[i] ] += rc[i];
-
-  if (++m_nr == m_nodeCommMap.size()) {
-    m_nr = 0;
-    comres_complete();
-  }
-}
-
-void
-ConjugateGradients::initres()
-// *****************************************************************************
-// Finish computing the initial residual, r = b - A * x
-// *****************************************************************************
-{
-  // Combine own and communicated contributions to r = A * x
-  auto ncomp = m_A.Ncomp();
-  for (const auto& [gid,r] : m_rc) {
-    auto i = tk::cref_find( m_lid, gid );
-    for (std::size_t c=0; c<ncomp; ++c) m_r[i*ncomp+c] += r[c];
-  }
-  tk::destroy( m_rc );
-
-  // Finish computing the initial residual, r = b - A * x
-  for (auto& r : m_r) r *= -1.0;<--- Consider using std::transform algorithm instead of a raw loop.
-  m_r += m_b;
-
-  // Initialize p
-  m_p = m_r;
-
-  // initiate computing the dot product of the initial residual, rho = (r,r)
-  dot( m_r, m_r,
-       CkCallback( CkReductionTarget(ConjugateGradients,rho), thisProxy ) );
-}
-
-void
-ConjugateGradients::rho( tk::real r )
-// *****************************************************************************
-// Compute rho = (r,r)
-//! \param[in] r Dot product, rho = (r,r) (aggregated across all chares)
-// *****************************************************************************
-{
-  // store dot product of residual
-  m_rho = r;
-
-  // send back rhs norm to caller
-  m_initres.send( CkDataMsg::buildNew( sizeof(tk::real), &m_normb ) );
-}
-
-void
-ConjugateGradients::init(
-  const std::vector< tk::real >& x,
-  const std::vector< tk::real >& b,
-  const std::unordered_map< std::size_t,
-          std::vector< std::pair< bool, tk::real > > >& bc,
-  std::size_t ignorebc,
-  CkCallback cb )
-// *****************************************************************************
-//  Initialize linear solve: set initial guess and boundary conditions
-//! \param[in] x Initial guess
-//! \param[in] b Right hand side vector
-//! \param[in] bc Local node ids and associated Dirichlet BCs
-//! \param[in] ignorebc True if applyin BCs should be skipped
-//! \param[in] cb Call to continue with when initialized and ready for a solve
-//! \details This function allows setting the initial guess and boundary
-//!   conditions, followed by computing the initial residual and the rhs norm.
-// *****************************************************************************
-{
-  // Optionally set initial guess
-  if (not x.empty()) m_x = x;
-
-  // Optionally update rhs
-  if (not b.empty()) m_b = b;
-
-  if (ignorebc) {
-
-    setup( cb );
-
-  } else {
-
-    // Store incoming BCs
-    m_bc = bc;
-
-    // Get ready to communicate boundary conditions. This is necessary because
-    // there can be nodes a chare contributes to but does not apply BCs on. This
-    // happens if a node is in the node communication map but not on the list of
-    // incoming BCs on this chare. To have all chares share the same view on all
-    // BC nodes, we send the global node ids together with the Dirichlet BCs at
-    // which BCs are set to those fellow chares that also contribute to those BC
-    // nodes. Only after this communication step we apply the BCs on the matrix,
-    // which then will correctly setup the BC rows that exist on multiple chares
-    // (which now will be the same as the results of making the BCs consistent
-    // across all chares that contribute.
-    thisProxy[ thisIndex ].wait4bc();
-
-    // Send boundary conditions to those who contribute to those rows
-    if (m_nodeCommMap.empty()) {
-      combc_complete();
-    } else {
-      for (const auto& [c,n] : m_nodeCommMap) {
-        std::unordered_map< std::size_t,
-          std::vector< std::pair< bool, tk::real > > > expbc;
-        for (auto g : n) {
-          auto i = tk::cref_find( m_lid, g );
-          auto j = bc.find(i);
-          if (j != end(bc)) expbc[g] = j->second;
-        }
-        thisProxy[c].combc( expbc );
-      }
-    }
-
-    ownbc_complete( cb );
-
-  }
-}
-
-void
-ConjugateGradients::combc(
-  const std::unordered_map< std::size_t,
-     std::vector< std::pair< bool, tk::real > > >& bc )
-// *****************************************************************************
-//  Receive contributions to boundary conditions on chare-boundaries
-//! \param[in] bc Contributions to boundary conditions
-// *****************************************************************************
-{
-  for (const auto& [g,dirbc] : bc) m_bcc[ tk::cref_find(m_lid,g) ] = dirbc;
-
-  if (++m_nb == m_nodeCommMap.size()) {
-    m_nb = 0;
-    combc_complete();
-  }
-}
-
-void
-ConjugateGradients::apply( CkCallback cb )
-// *****************************************************************************
-//  Apply boundary conditions
-//! \param[in] cb Call to continue with after applying the BCs is complete
-// *****************************************************************************
-{
-  // Merge own and received contributions to boundary conditions
-  for (const auto& [i,dirbc] : m_bcc) m_bc[i] = dirbc;
-  tk::destroy( m_bcc );
-
-  auto ncomp = m_A.Ncomp();
-
-  // Setup Dirichlet BC map as contiguous mask
-  for (const auto& [i,bc] : m_bc)
-    for (std::size_t j=0; j<ncomp; ++j)
-      m_bcmask[i*ncomp+j] = 0.0;
-
-  // Apply Dirichlet BCs on matrix and rhs
-  for (const auto& [i,dirbc] : m_bc) {
-    for (std::size_t j=0; j<ncomp; ++j) {
-      if (dirbc[j].first) {
-        m_A.dirichlet( i, m_gid, m_nodeCommMap, j );
-        m_b[i*ncomp+j] = dirbc[j].second;
-      }
-    }
-  }
-
-  // Recompute initial residual (r=b-A*x), its dot product, and the rhs norm
-  setup( cb );
-}
-
-void
-ConjugateGradients::solve( std::size_t maxit, tk::real tol, CkCallback c )
-// *****************************************************************************
-//  Solve linear system
-//! \param[in] maxit Max iteration count
-//! \param[in] tol Stop tolerance
-//! \param[in] c Call to continue with after solve is complete
-// *****************************************************************************
-{
-  m_maxit = maxit;
-  m_tol = tol;
-  m_solved = c;
-  m_it = 0;
-
-  next();
-}
-
-void
-ConjugateGradients::next()
-// *****************************************************************************
-//  Start next linear solver iteration
-// *****************************************************************************
-{
-  if (m_it == 0) m_alpha = 0.0; else m_alpha = m_rho/m_rho0;
-  m_rho0 = m_rho;
-
-  // compute p = r + alpha * p
-  for (std::size_t i=0; i<m_p.size(); ++i) m_p[i] = m_r[i] + m_alpha * m_p[i];
-
-  // initiate computing q = A * p
-  thisProxy[ thisIndex ].wait4q();
-  qAp();
-}
-
-
-void
-ConjugateGradients::qAp()
-// *****************************************************************************
-//  Initiate computing q = A * p
-// *****************************************************************************
-{
-  // Compute own contribution to q = A * p
-  m_A.mult( m_p, m_q, m_bcmask );
-
-  // Send partial product on chare-boundary nodes to fellow chares
-  if (m_nodeCommMap.empty()) {
-    comq_complete();
-  } else {
-    auto ncomp = m_A.Ncomp();
-    for (const auto& [c,n] : m_nodeCommMap) {
-      std::vector< std::vector< tk::real > > qc( n.size() );
-      std::size_t j = 0;
-      for (auto g : n) {
-        std::vector< tk::real > nq( ncomp );
-        auto i = tk::cref_find( m_lid, g );
-        for (std::size_t d=0; d<ncomp; ++d) nq[d] = m_q[ i*ncomp+d ];
-        qc[j++] = std::move(nq);
-      }
-      thisProxy[c].comq( std::vector<std::size_t>(begin(n),end(n)), qc );
-    }
-  }
-
-  ownq_complete();
-}
-
-void
-ConjugateGradients::comq( const std::vector< std::size_t >& gid,
-                          const std::vector< std::vector< tk::real > >& qc )
-// *****************************************************************************
-//  Receive contributions to q = A * p on chare-boundaries
-//! \param[in] gid Global mesh node IDs at which we receive contributions
-//! \param[in] qc Partial contributions at chare-boundary nodes
-// *****************************************************************************
-{
-  Assert( qc.size() == gid.size(), "Size mismatch" );
-
-  using tk::operator+=;
-
-  for (std::size_t i=0; i<gid.size(); ++i)
-    m_qc[ gid[i] ] += qc[i];
-
-  if (++m_nq == m_nodeCommMap.size()) {
-    m_nq = 0;
-    comq_complete();
-  }
-}
-
-void
-ConjugateGradients::q()
-// *****************************************************************************
-// Finish computing q = A * p
-// *****************************************************************************
-{
-  // Combine own and communicated contributions to q = A * p
-  auto ncomp = m_A.Ncomp();
-  for (const auto& [gid,q] : m_qc) {
-    auto i = tk::cref_find( m_lid, gid );
-    for (std::size_t c=0; c<ncomp; ++c)
-      m_q[i*ncomp+c] += q[c];
-  }
-  tk::destroy( m_qc );
-
-  // initiate computing (p,q)
-  dot( m_p, m_q,
-       CkCallback( CkReductionTarget(ConjugateGradients,pq), thisProxy ) );
-}
-
-void
-ConjugateGradients::pq( tk::real d )
-// *****************************************************************************
-// Compute the dot product (p,q)
-//! \param[in] d Dot product of (p,q) (aggregated across all chares)
-// *****************************************************************************
-{
-  // If (p,q)=0, then p and q are orthogonal and the system either has a trivial
-  // solution, x=x0, or the BCs are incomplete or wrong, in either case the
-  // solve cannot continue.
-  const auto eps = std::numeric_limits< tk::real >::epsilon();
-  if (std::abs(d) < eps) {
-    m_it = m_maxit;
-    m_alpha = 0.0;
-  } else {
-    m_alpha = m_rho / d;
-  }
-
-  // compute r = r - alpha * q
-  for (std::size_t i=0; i<m_r.size(); ++i) m_r[i] -= m_alpha * m_q[i];
-
-  // initiate computing norm of residual: (r,r)
-  dot( m_r, m_r,
-       CkCallback( CkReductionTarget(ConjugateGradients,normres), thisProxy ) );
-}
-
-void
-ConjugateGradients::normres( tk::real r )
-// *****************************************************************************
-// Compute norm of residual: (r,r)
-//! \param[in] r Dot product, (r,r) (aggregated across all chares)
-// *****************************************************************************
-{
-  m_rho = r;
-
-  // Advance solution: x = x + alpha * p
-  for (std::size_t i=0; i<m_x.size(); ++i) m_x[i] += m_alpha * m_p[i];
-
-  // Communicate solution
-  thisProxy[ thisIndex ].wait4x();
-
-  // Send solution on chare-boundary nodes to fellow chares
-  if (m_nodeCommMap.empty()) {
-    comx_complete();
-  } else {
-    auto ncomp = m_A.Ncomp();
-    for (const auto& [c,n] : m_nodeCommMap) {
-      std::vector< std::vector< tk::real > > xc( n.size() );
-      std::size_t j = 0;
-      for (auto g : n) {
-        std::vector< tk::real > nx( ncomp );
-        auto i = tk::cref_find( m_lid, g );
-        for (std::size_t d=0; d<ncomp; ++d) nx[d] = m_x[ i*ncomp+d ];
-        xc[j++] = std::move(nx);
-      }
-      thisProxy[c].comx( std::vector<std::size_t>(begin(n),end(n)), xc );
-    }
-  }
-
-  ownx_complete();
-}
-
-void
-ConjugateGradients::comx( const std::vector< std::size_t >& gid,
-                          const std::vector< std::vector< tk::real > >& xc )
-// *****************************************************************************
-//  Receive contributions to final solution on chare-boundaries
-//! \param[in] gid Global mesh node IDs at which we receive contributions
-//! \param[in] xc Partial contributions at chare-boundary nodes
-// *****************************************************************************
-{
-  Assert( xc.size() == gid.size(), "Size mismatch" );
-
-  for (std::size_t i=0; i<gid.size(); ++i) m_xc[ gid[i] ] += xc[i];
-
-  if (++m_nx == m_nodeCommMap.size()) {
-    m_nx = 0;
-    comx_complete();
-  }
-}
-
-void
-ConjugateGradients::x()
-// *****************************************************************************
-// Assemble solution on chare boundaries
-// *****************************************************************************
-{
-  // Assemble solution on chare boundaries by averaging
-  auto ncomp = m_A.Ncomp();
-  for (const auto& [g,x] : m_xc) {
-    auto i = tk::cref_find(m_lid,g);
-    for (std::size_t d=0; d<ncomp; ++d) m_x[i*ncomp+d] += x[d];
-    auto c = tk::count(m_nodeCommMap,g);
-    for (std::size_t d=0; d<ncomp; ++d) m_x[i*ncomp+d] /= c;
-  }
-  tk::destroy( m_xc );
-
-  ++m_it;
-  auto normb = m_normb > 1.0e-14 ? m_normb : 1.0;
-  auto normr = std::sqrt( m_rho );
-
-  if ( m_it < m_maxit && normr > m_tol*normb ) {
-
-    next();
-
-  } else {
-
-    m_converged = m_it == m_maxit && normr > m_tol*normb ? false : true;
-    m_solved.send( CkDataMsg::buildNew( sizeof(tk::real), &normr ) );
-
-  }
-}
-
-#include "NoWarning/conjugategradients.def.h"
+#include "PUPUtil.hpp"
+#include "Exception.hpp"
+
+namespace tag {
+//! Printable tag for TaggedTuple that returns its name
+#define DEFTAG(n) struct n { static const char* name() { return #n; } }
+} // tag::
+
+namespace tk {
+
+//! \brief Tagged tuple, allowing tag-based access
+//! \details "Tag" here is any type, but mostly an empty struct with a good name
+//!   for the data member
+//! \tparam List Type list as brigand::list
+//! \see https://stackoverflow.com/a/42988897
+//! \see https://gist.github.com/underdoeg/4c5c616c1ad4cbb718f787eefcab902d
+template< class List >
+class TaggedTuple{
+
+  private:
+    //! Generate index for every 2nd type of a type list
+    template< typename T >
+    using is_odd = brigand::size_t< (brigand::index_of<List,T>::value%2) != 0 >;
+
+    //! Partition a type list into two lists with the even and the odd types
+    using Pair = brigand::partition< List, brigand::bind<is_odd,brigand::_1> >;
+
+    //! List of member types
+    using Data = typename Pair::first_type;
+
+    //! Tuple of member types
+    using Tuple = brigand::as_tuple< Data >;
+
+    //! False-overload for detecting if T is a tagged tuple
+    template< typename T, typename = std::void_t<> >
+    struct is_tagged_tuple_t : std::false_type {};
+
+    //! True-overload for detecting if T is a tagged tuple
+    template< typename T >
+    struct is_tagged_tuple_t< T, std::void_t< typename T::i_am_tagged_tuple > >
+     : std::true_type {};
+
+    //! Member data as a tuple
+    Tuple m_members;
+
+  public:
+    //! List of key-value pairs
+    using PairList = List;
+
+    //! List of keys
+    using Keys = typename Pair::second_type;
+
+    //! Typedef defining self for identifying self
+    using i_am_tagged_tuple = void;
+
+    //! Acces type in tuple behind tag
+    template< typename Tag >
+    using TupleElement =
+      std::tuple_element_t< brigand::index_of<Keys,Tag>::value, Tuple >;
+
+    //! Query if the type behind Tag is a TaggedTuple
+    //! Usage: if constexpr( is_tagged_tuple<Tag>::value ) { ... }
+    template< typename Tag >
+    using is_tagged_tuple =
+      is_tagged_tuple_t< std::decay_t< TupleElement<Tag> > >;
+
+    //! Default constructor
+    explicit TaggedTuple() = default;
+    //! Initializer constructor
+    explicit TaggedTuple( Tuple&& tuple ) : m_members( std::move(tuple) ) {}
+
+    //! Const-ref access to member tuple
+    const Tuple& tuple() const { return m_members; }
+
+    //! Const-reference data member accessor of field of tagged tuple at depth
+    template< typename Tag, typename... Tags >
+    const auto& get() const noexcept {
+      constexpr std::size_t idx = brigand::index_of< Keys, Tag >::value;
+      if constexpr( is_tagged_tuple<Tag>::value and sizeof...(Tags) != 0 )
+        return std::get< idx >( m_members ).template get< Tags... >();
+      else
+        return std::get< idx >( m_members );
+    }
+
+    //! Reference data member accessor of field of tagged tuple at depth
+    template< typename Tag, typename... Tags >
+    auto& get() noexcept {<--- Syntax Error: AST broken, binary operator '>' doesn't have two operands.
+      constexpr std::size_t idx = brigand::index_of< Keys, Tag >::value;
+      if constexpr( is_tagged_tuple<Tag>::value and sizeof...(Tags) != 0 )
+        return std::get< idx >( m_members ).template get< Tags... >();
+      else
+        return std::get< idx >( m_members );
+    }
+
+    //! Convert and store value converting from string at depth
+    //! \param[in] value Value to convert and store
+    template< typename Tag, typename... Tags >
+    void store( const std::string& value ) noexcept {
+      if constexpr( is_tagged_tuple<Tag>::value and sizeof...(Tags) != 0 )
+      {
+        using T = std::remove_reference_t< decltype( get<Tag,Tags...>() ) >;
+        get< Tag, Tags... >() = convert< T >( value );
+      } else {
+        using T = std::remove_reference_t< decltype( get< Tag >() ) >;
+        get< Tag >() = convert< T >( value );
+      }
+    }
+
+    //! Operator == between two TaggedTuple objects
+    //! \tparam L Type list as brigand::list for other TaggedTuple
+    //! \return True if the lhs and rhs equal
+    template< typename L >
+    bool operator== ( const TaggedTuple< L >& t ) const {
+      static_assert( std::is_same_v< L, List >, "Invoking operator== on "
+        "TaggedTuple objects with different typelists" );
+      static_assert( !brigand::any< List,
+        std::is_floating_point<brigand::_1> >::value, "Invoking operator== on "
+        "TaggedTuple objects containing a floating point type is unreliable" );
+      return m_members == t.tuple();
+    }
+
+    //! Operator < between two TaggedTuple objects
+    //! \tparam L Type list as brigand::list for other TaggedTuple
+    //! \return True if lhs < rhs
+    template< typename L >
+    bool operator< ( const TaggedTuple< L >& t ) const {
+      static_assert( std::is_same_v< L, List >, "Invoking operator< on "
+        "TaggedTuple objects with different typelists" );
+      return m_members < t.tuple();
+    }
+
+    //! Return number of tuple entries
+    static constexpr std::size_t size() { return std::tuple_size_v< Tuple >; }
+
+    //! Pack/Unpack
+    /** @name Charm++ pack/unpack serializer member functions */
+    ///@{
+    //! \brief Pack/Unpack serialize member function
+    //! \param[in,out] p Charm++'s PUP::er serializer object reference
+    void pup( PUP::er& p ) { p | m_members; }<--- Parameter 'p' can be declared with const
+    //! \brief Pack/Unpack serialize operator|
+    //! \param[in,out] p Charm++'s PUP::er serializer object reference
+    //! \param[in,out] t TaggedTuple object reference
+    friend void operator|( PUP::er& p, TaggedTuple<List>& t ) { t.pup(p); }
+    //@}
+
+    //! Convert/parse string to and return as type given by template argument
+    //! \param[in] str String to convert
+    //! \return A value of type given by the template argument
+    template< typename type >
+    type convert( const std::string& str ) {
+      std::stringstream ss( str );
+      type num;
+      ss >> std::boolalpha >> num;
+      if (ss.fail())
+        Throw( "Failed to convert '" + str +
+               "' to typeid " + typeid(num).name() );
+      return num;
+    }
+};
+
+} // tk::
+
+#endif // TaggedTuple_h
 
diff --git a/Release/cppcheck/13.html b/Release/cppcheck/13.html index 6877ddee6b61..6ca2d114be4e 100644 --- a/Release/cppcheck/13.html +++ b/Release/cppcheck/13.html @@ -152,12 +152,12 @@
  1
@@ -261,426 +261,108 @@ 

Cppcheck report - [

// *****************************************************************************
+102
// *****************************************************************************
 /*!
-  \file      src/LinearSolver/ConjugateGradients.hpp
+  \file      src/Base/HashMapReducer.hpp
   \copyright 2012-2015 J. Bakosi,
              2016-2018 Los Alamos National Security, LLC.,
              2019-2021 Triad National Security, LLC.
              All rights reserved. See the LICENSE file for details.
-  \brief     Charm++ chare array for distributed conjugate gradients
-  \details   Charm++ chare array for asynchronous distributed
-    conjugate gradients linear solver.
-
-    There are a potentially large number of ConjugateGradients Charm++ chares.
-    Each ConjugateGradient chare gets a chunk of the full load, due to partiting
-    the mesh, on which the solve is performed.
-
-    The implementation uses the Charm++ runtime system and is fully
-    asynchronous, overlapping computation and communication. The algorithm
-    utilizes the structured dagger (SDAG) Charm++ functionality.
-*/
-// *****************************************************************************
-#ifndef ConjugateGradients_h
-#define ConjugateGradients_h
+  \brief     Custom Charm++ reducer for merging std::unordered_maps across PEs
+  \details   Custom Charm++ reducer for merging std::unordered_maps across PEs.
+*/
+// *****************************************************************************
+#ifndef HashMapReducer_h
+#define HashMapReducer_h
+
+#include <vector>
+#include <unordered_map>
+#include <unordered_set>
+#include <memory>
+
+#include "NoWarning/charm++.hpp"
+
+#include "ContainerUtil.hpp"
 
-#include "Types.hpp"
-#include "CSR.hpp"
-
-#include "NoWarning/conjugategradients.decl.h"
-
-namespace tk {
-
-//! \brief ConjugateGradients Charm++ chare array used to perform a distributed
-//!   linear solve with the conjugate gradients algorithm
-class ConjugateGradients : public CBase_ConjugateGradients {
-
-  public:
-    #if defined(__clang__)
-      #pragma clang diagnostic push
-      #pragma clang diagnostic ignored "-Wunused-parameter"
-    #elif defined(STRICT_GNUC)
-      #pragma GCC diagnostic push
-      #pragma GCC diagnostic ignored "-Wunused-parameter"
-    #endif
-    // Include Charm++ SDAG code. See http://charm.cs.illinois.edu/manuals/html/
-    // charm++/manual.html, Sec. "Structured Control Flow: Structured Dagger".
-    ConjugateGradients_SDAG_CODE
-    #if defined(__clang__)
-      #pragma clang diagnostic pop
-    #elif defined(STRICT_GNUC)
-      #pragma GCC diagnostic pop
-    #endif
-
-    //! Constructor
-    explicit ConjugateGradients(
-      const CSR& A,
-      const std::vector< tk::real >& x,
-      const std::vector< tk::real >& b,
-      const std::vector< std::size_t >& gid,
-      const std::unordered_map< std::size_t, std::size_t >& lid,
-      const NodeCommMap& nodecommmap );
-
-    #if defined(__clang__)
-      #pragma clang diagnostic push
-      #pragma clang diagnostic ignored "-Wundefined-func-template"
-    #endif
-    //! Constructor taking a tuple of {A,x,b} by rvalue reference
-    explicit ConjugateGradients(<--- Member variable 'ConjugateGradients::m_tol' is not initialized in the constructor.
-      std::tuple< tk::CSR,
-                  std::vector< tk::real >,
-                  std::vector< tk::real > >&& system,
-      const std::vector< std::size_t >& gid,
-      const std::unordered_map< std::size_t, std::size_t >& lid,
-      const NodeCommMap& nodecommmap ) :
-      ConjugateGradients( std::move(std::get<0>(system)),
-                          std::move(std::get<1>(system)),
-                          std::move(std::get<2>(system)),
-                          gid, lid, nodecommmap ) {}
+namespace tk {
+
+//! Serialize std::unordered_map to raw memory stream
+//! \tparam Key Map key
+//! \tparam T Map value
+//! \tparam Hash Map hasher
+//! \tparam Eq Map equality operator
+//! \param[in] m Hash map to serialize
+//! \return Pair of the length and the raw stream containing the serialized map
+template< class Key,
+          class T,
+          class Hash = std::hash< Key >,
+          class Eq = std::equal_to< Key > >
+std::pair< int, std::unique_ptr<char[]> >
+serialize( const std::unordered_map< Key, T, Hash, Eq >& m ) {
+   // Prepare for serializing map to a raw binary stream, compute size
+  PUP::sizer sizer;
+  sizer | const_cast< std::unordered_map< Key, T, Hash, Eq >& >( m );
+
+  // Create raw character stream to store the serialized map
+  std::unique_ptr<char[]> flatData = std::make_unique<char[]>( sizer.size() );
+
+  // Serialize map, each message will contain a map
+  PUP::toMem packer( flatData.get() );
+  packer | const_cast< std::unordered_map< Key, T, Hash, Eq >& >( m );
+
+  // Return size of and raw stream
+  return { sizer.size(), std::move(flatData) };
+}
+
+//! \brief Charm++ custom reducer for merging std::unordered_maps during
+//!   reduction across PEs
+//! \tparam Key Map key
+//! \tparam T Map value
+//! \tparam Hash Map hasher
+//! \tparam Eq Map equality operator
+//! \param[in] nmsg Number of messages in msgs
+//! \param[in] msgs Charm++ reduction message containing the serialized maps
+//! \return Aggregated std::unordered_maps built for further aggregation if
+//!    needed
+//! \details During aggregation the map keys are inserted, i.e., the keys remain
+//!   unique and the mapped values, assuming containers defining begin() and
+//!   end() iterators() are concatenated.
+//! \note The mapped type must be a container, i.e., must provide iterators
+//!   begin() and end().
+template< class Key,
+          class T,
+          class Hash = std::hash< Key >,
+          class Eq = std::equal_to< Key > >
+CkReductionMsg*
+mergeHashMap( int nmsg, CkReductionMsg **msgs ) {
+  // Will store deserialized map
+  std::unordered_map< Key, T, Hash, Eq > p;
 
-    //! Migrate constructor
-    explicit ConjugateGradients( CkMigrateMessage* ) {}<--- Member variable 'ConjugateGradients::m_nr' is not initialized in the constructor.<--- Member variable 'ConjugateGradients::m_nb' is not initialized in the constructor.<--- Member variable 'ConjugateGradients::m_nq' is not initialized in the constructor.<--- Member variable 'ConjugateGradients::m_normb' is not initialized in the constructor.<--- Member variable 'ConjugateGradients::m_it' is not initialized in the constructor.<--- Member variable 'ConjugateGradients::m_maxit' is not initialized in the constructor.<--- Member variable 'ConjugateGradients::m_tol' is not initialized in the constructor.<--- Member variable 'ConjugateGradients::m_rho' is not initialized in the constructor.<--- Member variable 'ConjugateGradients::m_rho0' is not initialized in the constructor.<--- Member variable 'ConjugateGradients::m_alpha' is not initialized in the constructor.<--- Member variable 'ConjugateGradients::m_converged' is not initialized in the constructor.<--- Member variable 'ConjugateGradients::m_nx' is not initialized in the constructor.
-    #if defined(__clang__)
-      #pragma clang diagnostic pop
-    #endif
+  // Create PUP deserializer based on message passed in
+  PUP::fromMem creator( msgs[0]->getData() );
+
+  // Deserialize map from raw stream
+  creator | p;
 
-    //! Solve linear system
-    void solve( std::size_t maxit, tk::real tol, CkCallback c );
-
-    //! Initialize linear solve: set initial guess and boundary conditions
-    void init( const std::vector< tk::real >& x,
-               const std::vector< tk::real >& b,
-               const std::unordered_map< std::size_t,
-                       std::vector< std::pair< bool, tk::real > > >& bc,
-               std::size_t ignorebc,
-               CkCallback cb );
-
-    //! Setup solver
-    void setup( CkCallback c );
-
-    //! Compute the norm of the right hand side
-    void normb( tk::real n );
-
-    //! Compute rho = (r,r)
-    void rho( tk::real r );
-
-    //! Receive contributions to r = b - A * x on chare-boundaries
-    void comres( const std::vector< std::size_t >& gid,
-                 const std::vector< std::vector< tk::real > >& rc );
-
-    //! Receive contributions to boundary conditions on chare-boundaries
-    void combc( const std::unordered_map< std::size_t,
-                       std::vector< std::pair< bool, tk::real > > >& bc );
-
-    //! Receive contributions to q = A * p on chare-boundaries
-    void comq( const std::vector< std::size_t >& gid,
-               const std::vector< std::vector< tk::real > >& qc );
-
-    void comx( const std::vector< std::size_t >& gid,
-               const std::vector< std::vector< tk::real > >& xc );
-
-    //! Compute the dot product (p,q)
-    void pq( tk::real d );
-
-    //! Compute the norm of the residual: (r,r)
-    void normres( tk::real r );
-
-    //! Access solution
-    std::vector< tk::real > solution() const { return m_x; }
-
-    //! Return convergence flag
-    bool converged() const { return m_converged; }
-
-    /** @name Pack/unpack (Charm++ serialization) routines */
-    ///@{
-    //! \brief Pack/Unpack serialize member function
-    //! \param[in,out] p Charm++'s PUP::er serializer object reference
-    void pup( PUP::er &p ) override {
-      p | m_A;
-      p | m_x;
-      p | m_b;
-      p | m_gid;
-      p | m_lid;
-      p | m_nodeCommMap;
-      p | m_r;
-      p | m_rc;
-      p | m_nr;
-      p | m_bc;
-      p | m_bcc;
-      p | m_bcmask;
-      p | m_nb;
-      p | m_p;
-      p | m_q;
-      p | m_qc;
-      p | m_nq;
-      p | m_initres;
-      p | m_solved;
-      p | m_normb;
-      p | m_it;
-      p | m_maxit;
-      p | m_tol;
-      p | m_rho;
-      p | m_rho0;
-      p | m_alpha;
-      p | m_converged;
-      p | m_xc;
-      p | m_nx;
-    }
-    //! \brief Pack/Unpack serialize operator|
-    //! \param[in,out] p Charm++'s PUP::er serializer object reference
-    //! \param[in,out] c ConjugateGradients object reference
-    friend void operator|( PUP::er& p, ConjugateGradients& c ) { c.pup(p); }
-    ///@}
-
-  private:
-    //! Sparse matrix
-    CSR m_A;
-    //! Solution/unknown
-    std::vector< tk::real > m_x;
-    //! Right hand side
-    std::vector< tk::real > m_b;
-    //! Global node IDs
-    std::vector< std::size_t > m_gid;
-    //! Local node IDs associated to global ones
-    std::unordered_map< std::size_t, std::size_t > m_lid;
-    //! Global mesh node IDs shared with other chares associated to chare IDs
-    NodeCommMap m_nodeCommMap;
-    //! Auxiliary vector for CG solve
-    std::vector< tk::real > m_r;
-    //! Receive buffer for communication of r = b - A * x
-    std::unordered_map< std::size_t, std::vector< tk::real > > m_rc;
-    //! Counter for assembling m_r
-    std::size_t m_nr;
-    //! Dirichlet boundary conditions
-    std::unordered_map< std::size_t,
-        std::vector< std::pair< bool, tk::real > > > m_bc;
-    //! Dirichlet boundary conditions communication buffer
-    std::unordered_map< std::size_t,
-        std::vector< std::pair< bool, tk::real > > > m_bcc;
-    //! Dirichlet boundary condition mask
-    std::vector< tk::real > m_bcmask;
-    //! Counter for assembling boundary conditions
-    std::size_t m_nb;
-    //! Auxiliary vector for CG solve
-    std::vector< tk::real > m_p;
-    //! Auxiliary vector for CG solve
-    std::vector< tk::real > m_q;
-    //! Receive buffer for communication of q = A * p
-    std::unordered_map< std::size_t, std::vector< tk::real > > m_qc;
-    //! Counter for assembling m_q
-    std::size_t m_nq;
-    //! Charm++ callback to continue with when the setup is complete
-    CkCallback m_initres;
-    //! Charm++ callback to continue with when the solve is complete
-    CkCallback m_solved;
-    //! L2 norm of the right hand side
-    tk::real m_normb;
-    //! Iteration count
-    std::size_t m_it;
-    //! Max iteration count
-    std::size_t m_maxit;
-    //! Stop tolerance
-    tk::real m_tol;
-    //! Helper scalar for CG algorithm
-    tk::real m_rho;
-    //! Helper scalar for CG algorithm
-    tk::real m_rho0;
-    //! Helper scalar for CG algorithm
-    tk::real m_alpha;
-    //! Convergence flag: true if linear smoother converged to tolerance
-    bool m_converged;
-    //! Receive buffer for solution
-    std::unordered_map< std::size_t, std::vector< tk::real > > m_xc;
-    //! Counter for assembling the solution on chare boundaries
-    std::size_t m_nx;
-
-    //! Initiate computationa of dot product of two vectors
-    void dot( const std::vector< tk::real >& a,
-              const std::vector< tk::real >& b,
-              CkCallback c );
-
-    //! Initiate A * x for computing the residual, r = b - A * x
-    void residual();
-    //! Finish computing the initial residual, r = b - A * x
-    void initres();
-
-    //! Apply boundary conditions
-    void apply( CkCallback cb );
-
-    //! Initiate computing q = A * p
-    void qAp();
-    //! Finish computing q = A * p
-    void q();
-
-    //! Start next linear solver iteration
-    void next();
-
-    //! Assemble solution on chare boundaries
-    void x();
-};
-
-} // tk::
-
-#endif // ConjugateGradients_h
+  for (int m=1; m<nmsg; ++m) {
+    // Unpack map
+    std::unordered_map< Key, T, Hash, Eq > u;
+    PUP::fromMem curCreator( msgs[m]->getData() );
+    curCreator | u;
+    // Concatenate maps
+    for (auto&& c : u) concat( std::move(c.second), p[c.first] );<--- Iterating over container 'u' that is always empty.
+  }
+
+  // Serialize concatenated maps to raw stream
+  auto stream = tk::serialize( p );
+
+  // Forward serialized hash map
+  return CkReductionMsg::buildNew( stream.first, stream.second.get() );
+}
+
+} // tk::
+
+#endif // HashMapReducer_h
 
diff --git a/Release/cppcheck/14.html b/Release/cppcheck/14.html index 915d8391a8ff..60bf71e415f5 100644 --- a/Release/cppcheck/14.html +++ b/Release/cppcheck/14.html @@ -152,12 +152,12 @@
  1
@@ -261,108 +261,1058 @@ 

Cppcheck report - [

// *****************************************************************************
+102
+103
+104
+105
+106
+107
+108
+109
+110
+111
+112
+113
+114
+115
+116
+117
+118
+119
+120
+121
+122
+123
+124
+125
+126
+127
+128
+129
+130
+131
+132
+133
+134
+135
+136
+137
+138
+139
+140
+141
+142
+143
+144
+145
+146
+147
+148
+149
+150
+151
+152
+153
+154
+155
+156
+157
+158
+159
+160
+161
+162
+163
+164
+165
+166
+167
+168
+169
+170
+171
+172
+173
+174
+175
+176
+177
+178
+179
+180
+181
+182
+183
+184
+185
+186
+187
+188
+189
+190
+191
+192
+193
+194
+195
+196
+197
+198
+199
+200
+201
+202
+203
+204
+205
+206
+207
+208
+209
+210
+211
+212
+213
+214
+215
+216
+217
+218
+219
+220
+221
+222
+223
+224
+225
+226
+227
+228
+229
+230
+231
+232
+233
+234
+235
+236
+237
+238
+239
+240
+241
+242
+243
+244
+245
+246
+247
+248
+249
+250
+251
+252
+253
+254
+255
+256
+257
+258
+259
+260
+261
+262
+263
+264
+265
+266
+267
+268
+269
+270
+271
+272
+273
+274
+275
+276
+277
+278
+279
+280
+281
+282
+283
+284
+285
+286
+287
+288
+289
+290
+291
+292
+293
+294
+295
+296
+297
+298
+299
+300
+301
+302
+303
+304
+305
+306
+307
+308
+309
+310
+311
+312
+313
+314
+315
+316
+317
+318
+319
+320
+321
+322
+323
+324
+325
+326
+327
+328
+329
+330
+331
+332
+333
+334
+335
+336
+337
+338
+339
+340
+341
+342
+343
+344
+345
+346
+347
+348
+349
+350
+351
+352
+353
+354
+355
+356
+357
+358
+359
+360
+361
+362
+363
+364
+365
+366
+367
+368
+369
+370
+371
+372
+373
+374
+375
+376
+377
+378
+379
+380
+381
+382
+383
+384
+385
+386
+387
+388
+389
+390
+391
+392
+393
+394
+395
+396
+397
+398
+399
+400
+401
+402
+403
+404
+405
+406
+407
+408
+409
+410
+411
+412
+413
+414
+415
+416
+417
+418
+419
+420
+421
+422
+423
+424
+425
+426
+427
+428
+429
+430
+431
+432
+433
+434
+435
+436
+437
+438
+439
+440
+441
+442
+443
+444
+445
+446
+447
+448
+449
+450
+451
+452
+453
+454
+455
+456
+457
+458
+459
+460
+461
+462
+463
+464
+465
+466
+467
+468
+469
+470
+471
+472
+473
+474
+475
+476
+477
+478
+479
+480
+481
+482
+483
+484
+485
+486
+487
+488
+489
+490
+491
+492
+493
+494
+495
+496
+497
+498
+499
+500
+501
+502
+503
+504
+505
+506
+507
+508
+509
+510
+511
+512
+513
+514
+515
+516
+517
+518
+519
+520
+521
+522
+523
+524
+525
+526
+527
+528
+529
+530
+531
+532
+533
+534
+535
+536
+537
+538
+539
+540
+541
+542
+543
+544
+545
+546
+547
+548
+549
+550
+551
+552
+553
+554
+555
+556
+557
+558
+559
+560
+561
+562
+563
+564
+565
+566
+567
+568
+569
+570
+571
+572
+573
+574
+575
+576
+577
// *****************************************************************************
 /*!
-  \file      src/Base/HashMapReducer.hpp
+  \file      src/LinearSolver/ConjugateGradients.cpp
   \copyright 2012-2015 J. Bakosi,
              2016-2018 Los Alamos National Security, LLC.,
              2019-2021 Triad National Security, LLC.
              All rights reserved. See the LICENSE file for details.
-  \brief     Custom Charm++ reducer for merging std::unordered_maps across PEs
-  \details   Custom Charm++ reducer for merging std::unordered_maps across PEs.
-*/
-// *****************************************************************************
-#ifndef HashMapReducer_h
-#define HashMapReducer_h
+  \brief     Charm++ chare array for distributed conjugate gradients.
+  \details   Charm++ chare array for asynchronous distributed
+    conjugate gradients linear solver.
+  \see Y. Saad, Iterative Methods for Sparse Linear Systems: Second Edition,
+    ISBN 9780898718003, 2003, Algorithm 6.18, conjugate gradients to solve the
+    linear system A * x = b, reproduced here:
 
-#include <vector>
-#include <unordered_map>
-#include <unordered_set>
-#include <memory>
-
-#include "NoWarning/charm++.hpp"
-
-#include "ContainerUtil.hpp"
-
-namespace tk {
+    Compute r0:=b-A*x0, p0:=r0
+    For j=0,1,..., until convergence, do
+      alpha_j := (r_j,r_j) / (Ap_j,p_j)
+      x_{j+1} := x_j + alpha_j p_j
+      r_{j+1} := r_j - alpha_j A p_j
+      beta_j := (r_{j+1},r_{j+1}) / (r_j,r_j)
+      p_{j+1} := r_{j+1} + beta_j p_j
+    end
+*/
+// *****************************************************************************
 
-//! Serialize std::unordered_map to raw memory stream
-//! \tparam Key Map key
-//! \tparam T Map value
-//! \tparam Hash Map hasher
-//! \tparam Eq Map equality operator
-//! \param[in] m Hash map to serialize
-//! \return Pair of the length and the raw stream containing the serialized map
-template< class Key,
-          class T,
-          class Hash = std::hash< Key >,
-          class Eq = std::equal_to< Key > >
-std::pair< int, std::unique_ptr<char[]> >
-serialize( const std::unordered_map< Key, T, Hash, Eq >& m ) {
-   // Prepare for serializing map to a raw binary stream, compute size
-  PUP::sizer sizer;
-  sizer | const_cast< std::unordered_map< Key, T, Hash, Eq >& >( m );
-
-  // Create raw character stream to store the serialized map
-  std::unique_ptr<char[]> flatData = std::make_unique<char[]>( sizer.size() );
-
-  // Serialize map, each message will contain a map
-  PUP::toMem packer( flatData.get() );
-  packer | const_cast< std::unordered_map< Key, T, Hash, Eq >& >( m );
-
-  // Return size of and raw stream
-  return { sizer.size(), std::move(flatData) };
-}
-
-//! \brief Charm++ custom reducer for merging std::unordered_maps during
-//!   reduction across PEs
-//! \tparam Key Map key
-//! \tparam T Map value
-//! \tparam Hash Map hasher
-//! \tparam Eq Map equality operator
-//! \param[in] nmsg Number of messages in msgs
-//! \param[in] msgs Charm++ reduction message containing the serialized maps
-//! \return Aggregated std::unordered_maps built for further aggregation if
-//!    needed
-//! \details During aggregation the map keys are inserted, i.e., the keys remain
-//!   unique and the mapped values, assuming containers defining begin() and
-//!   end() iterators() are concatenated.
-//! \note The mapped type must be a container, i.e., must provide iterators
-//!   begin() and end().
-template< class Key,
-          class T,
-          class Hash = std::hash< Key >,
-          class Eq = std::equal_to< Key > >
-CkReductionMsg*
-mergeHashMap( int nmsg, CkReductionMsg **msgs ) {
-  // Will store deserialized map
-  std::unordered_map< Key, T, Hash, Eq > p;
-
-  // Create PUP deserializer based on message passed in
-  PUP::fromMem creator( msgs[0]->getData() );
-
-  // Deserialize map from raw stream
-  creator | p;
-
-  for (int m=1; m<nmsg; ++m) {
-    // Unpack map
-    std::unordered_map< Key, T, Hash, Eq > u;
-    PUP::fromMem curCreator( msgs[m]->getData() );
-    curCreator | u;
-    // Concatenate maps
-    for (auto&& c : u) concat( std::move(c.second), p[c.first] );<--- Iterating over container 'u' that is always empty.
-  }
+#include <numeric>
+#include <iostream>
+
+#include "Exception.hpp"
+#include "ConjugateGradients.hpp"
+#include "Vector.hpp"
+
+using tk::ConjugateGradients;
+
+ConjugateGradients::ConjugateGradients(<--- Member variable 'ConjugateGradients::m_tol' is not initialized in the constructor.
+  const CSR& A,
+  const std::vector< tk::real >& x,
+  const std::vector< tk::real >& b,
+  const std::vector< std::size_t >& gid,
+  const std::unordered_map< std::size_t, std::size_t >& lid,
+  const NodeCommMap& nodecommmap ) :
+  m_A( A ),
+  m_x( x ),
+  m_b( b ),
+  m_gid( gid ),
+  m_lid( lid ),
+  m_nodeCommMap( nodecommmap ),
+  m_r( m_A.rsize(), 0.0 ),
+  m_rc(),
+  m_nr( 0 ),
+  m_bc(),
+  m_bcc(),
+  m_bcmask( m_A.rsize(), 1.0 ),
+  m_nb( 0 ),
+  m_p( m_A.rsize(), 0.0 ),
+  m_q( m_A.rsize(), 0.0 ),
+  m_qc(),
+  m_nq( 0 ),
+  m_initres(),
+  m_solved(),
+  m_normb( 0.0 ),
+  m_it( 0 ),
+  m_maxit( 0 ),
+  m_rho( 0.0 ),
+  m_rho0( 0.0 ),
+  m_alpha( 0.0 ),
+  m_converged( false ),
+  m_xc(),
+  m_nx( 0 )
+// *****************************************************************************
+//  Constructor
+//! \param[in] A Left hand side matrix of the linear system to solve in Ax=b
+//! \param[in] x Solution (initial guess) of the linear system to solve in Ax=b
+//! \param[in] b Right hand side of the linear system to solve in Ax=b
+//! \param[in] gid Global node ids
+//! \param[in] lid Local node ids associated to global ones
+//! \param[in] nodecommmap Global mesh node IDs shared with other chares
+//!   associated to their chare IDs
+// *****************************************************************************
+{
+  // Fill in gid and lid for serial solve
+  if (gid.empty() || lid.empty() || nodecommmap.empty()) {
+    m_gid.resize( m_A.rsize()/m_A.Ncomp() );
+    std::iota( begin(m_gid), end(m_gid), 0 );
+    for (auto g : m_gid) m_lid[g] = g;
+  }
+
+  Assert( m_A.rsize() == m_gid.size()*A.Ncomp(), "Size mismatch" );
+  Assert( m_x.size() == m_gid.size()*A.Ncomp(), "Size mismatch" );
+  Assert( m_b.size() == m_gid.size()*A.Ncomp(), "Size mismatch" );
+}
 
-  // Serialize concatenated maps to raw stream
-  auto stream = tk::serialize( p );
-
-  // Forward serialized hash map
-  return CkReductionMsg::buildNew( stream.first, stream.second.get() );
-}
-
-} // tk::
-
-#endif // HashMapReducer_h
+void
+ConjugateGradients::setup( CkCallback c )
+// *****************************************************************************
+//  Setup solver
+//! \param[in] c Call to continue with after initialization is complete
+//! \details This function initiates computing the residual (r=b-A*x), its dot
+//!   product, and the rhs norm.
+// *****************************************************************************
+{
+  m_initres = c;
+
+  // initiate computing A * x (for the initial residual)
+  thisProxy[ thisIndex ].wait4res();
+  residual();
+
+  // initiate computing norm of right hand side
+  dot( m_b, m_b,
+       CkCallback( CkReductionTarget(ConjugateGradients,normb), thisProxy ) );
+}
+
+void
+ConjugateGradients::dot( const std::vector< tk::real >& a,
+                         const std::vector< tk::real >& b,
+                         CkCallback c )
+// *****************************************************************************
+//  Initiate computation of dot product of two vectors
+//! \param[in] a 1st vector of dot product
+//! \param[in] b 2nd vector of dot product
+//! \param[in] c Callback to target with the final result
+// *****************************************************************************
+{
+  Assert( a.size() == b.size(), "Size mismatch" );
+
+  tk::real D = 0.0;
+  auto ncomp = m_A.Ncomp();
+  for (std::size_t i=0; i<a.size()/ncomp; ++i) {
+    auto incomp = i*ncomp;
+    if (not slave(m_nodeCommMap,m_gid[i],thisIndex))
+      for (std::size_t d=0; d<ncomp; ++d)
+        D += a[incomp+d] * b[incomp+d];
+  }
+
+  contribute( sizeof(tk::real), &D, CkReduction::sum_double, c );
+}
+
+void
+ConjugateGradients::normb( tk::real n )
+// *****************************************************************************
+// Compute the norm of the right hand side
+//! \param[in] n Norm of right hand side (aggregated across all chares)
+// *****************************************************************************
+{
+  m_normb = std::sqrt(n);
+  normb_complete();
+}
+
+void
+ConjugateGradients::residual()
+// *****************************************************************************
+//  Initiate A * x for computing the initial residual, r = b - A * x
+// *****************************************************************************
+{
+  // Compute own contribution to r = A * x
+  m_A.mult( m_x, m_r, m_bcmask );
+
+  // Send partial product on chare-boundary nodes to fellow chares
+  if (m_nodeCommMap.empty()) {
+    comres_complete();
+  } else {
+    auto ncomp = m_A.Ncomp();
+    for (const auto& [c,n] : m_nodeCommMap) {
+      std::vector< std::vector< tk::real > > rc( n.size() );
+      std::size_t j = 0;
+      for (auto g : n) {
+        std::vector< tk::real > nr( ncomp );
+        auto i = tk::cref_find( m_lid, g );
+        for (std::size_t d=0; d<ncomp; ++d) nr[d] = m_r[ i*ncomp+d ];
+        rc[j++] = std::move(nr);
+      }
+      thisProxy[c].comres( std::vector<std::size_t>(begin(n),end(n)), rc );
+    }
+  }
+
+  ownres_complete();
+}
+
+void
+ConjugateGradients::comres( const std::vector< std::size_t >& gid,
+                            const std::vector< std::vector< tk::real > >& rc )
+// *****************************************************************************
+//  Receive contributions to A * x on chare-boundaries
+//! \param[in] gid Global mesh node IDs at which we receive contributions
+//! \param[in] rc Partial contributions at chare-boundary nodes
+// *****************************************************************************
+{
+  Assert( rc.size() == gid.size(), "Size mismatch" );
+
+  using tk::operator+=;
+
+  for (std::size_t i=0; i<gid.size(); ++i)
+    m_rc[ gid[i] ] += rc[i];
+
+  if (++m_nr == m_nodeCommMap.size()) {
+    m_nr = 0;
+    comres_complete();
+  }
+}
+
+void
+ConjugateGradients::initres()
+// *****************************************************************************
+// Finish computing the initial residual, r = b - A * x
+// *****************************************************************************
+{
+  // Combine own and communicated contributions to r = A * x
+  auto ncomp = m_A.Ncomp();
+  for (const auto& [gid,r] : m_rc) {
+    auto i = tk::cref_find( m_lid, gid );
+    for (std::size_t c=0; c<ncomp; ++c) m_r[i*ncomp+c] += r[c];
+  }
+  tk::destroy( m_rc );
+
+  // Finish computing the initial residual, r = b - A * x
+  for (auto& r : m_r) r *= -1.0;<--- Consider using std::transform algorithm instead of a raw loop.
+  m_r += m_b;
+
+  // Initialize p
+  m_p = m_r;
+
+  // initiate computing the dot product of the initial residual, rho = (r,r)
+  dot( m_r, m_r,
+       CkCallback( CkReductionTarget(ConjugateGradients,rho), thisProxy ) );
+}
+
+void
+ConjugateGradients::rho( tk::real r )
+// *****************************************************************************
+// Compute rho = (r,r)
+//! \param[in] r Dot product, rho = (r,r) (aggregated across all chares)
+// *****************************************************************************
+{
+  // store dot product of residual
+  m_rho = r;
+
+  // send back rhs norm to caller
+  m_initres.send( CkDataMsg::buildNew( sizeof(tk::real), &m_normb ) );
+}
+
+void
+ConjugateGradients::init(
+  const std::vector< tk::real >& x,
+  const std::vector< tk::real >& b,
+  const std::unordered_map< std::size_t,
+          std::vector< std::pair< bool, tk::real > > >& bc,
+  std::size_t ignorebc,
+  CkCallback cb )
+// *****************************************************************************
+//  Initialize linear solve: set initial guess and boundary conditions
+//! \param[in] x Initial guess
+//! \param[in] b Right hand side vector
+//! \param[in] bc Local node ids and associated Dirichlet BCs
+//! \param[in] ignorebc True if applyin BCs should be skipped
+//! \param[in] cb Call to continue with when initialized and ready for a solve
+//! \details This function allows setting the initial guess and boundary
+//!   conditions, followed by computing the initial residual and the rhs norm.
+// *****************************************************************************
+{
+  // Optionally set initial guess
+  if (not x.empty()) m_x = x;
+
+  // Optionally update rhs
+  if (not b.empty()) m_b = b;
+
+  if (ignorebc) {
+
+    setup( cb );
+
+  } else {
+
+    // Store incoming BCs
+    m_bc = bc;
+
+    // Get ready to communicate boundary conditions. This is necessary because
+    // there can be nodes a chare contributes to but does not apply BCs on. This
+    // happens if a node is in the node communication map but not on the list of
+    // incoming BCs on this chare. To have all chares share the same view on all
+    // BC nodes, we send the global node ids together with the Dirichlet BCs at
+    // which BCs are set to those fellow chares that also contribute to those BC
+    // nodes. Only after this communication step we apply the BCs on the matrix,
+    // which then will correctly setup the BC rows that exist on multiple chares
+    // (which now will be the same as the results of making the BCs consistent
+    // across all chares that contribute.
+    thisProxy[ thisIndex ].wait4bc();
+
+    // Send boundary conditions to those who contribute to those rows
+    if (m_nodeCommMap.empty()) {
+      combc_complete();
+    } else {
+      for (const auto& [c,n] : m_nodeCommMap) {
+        std::unordered_map< std::size_t,
+          std::vector< std::pair< bool, tk::real > > > expbc;
+        for (auto g : n) {
+          auto i = tk::cref_find( m_lid, g );
+          auto j = bc.find(i);
+          if (j != end(bc)) expbc[g] = j->second;
+        }
+        thisProxy[c].combc( expbc );
+      }
+    }
+
+    ownbc_complete( cb );
+
+  }
+}
+
+void
+ConjugateGradients::combc(
+  const std::unordered_map< std::size_t,
+     std::vector< std::pair< bool, tk::real > > >& bc )
+// *****************************************************************************
+//  Receive contributions to boundary conditions on chare-boundaries
+//! \param[in] bc Contributions to boundary conditions
+// *****************************************************************************
+{
+  for (const auto& [g,dirbc] : bc) m_bcc[ tk::cref_find(m_lid,g) ] = dirbc;
+
+  if (++m_nb == m_nodeCommMap.size()) {
+    m_nb = 0;
+    combc_complete();
+  }
+}
+
+void
+ConjugateGradients::apply( CkCallback cb )
+// *****************************************************************************
+//  Apply boundary conditions
+//! \param[in] cb Call to continue with after applying the BCs is complete
+// *****************************************************************************
+{
+  // Merge own and received contributions to boundary conditions
+  for (const auto& [i,dirbc] : m_bcc) m_bc[i] = dirbc;
+  tk::destroy( m_bcc );
+
+  auto ncomp = m_A.Ncomp();
+
+  // Setup Dirichlet BC map as contiguous mask
+  for (const auto& [i,bc] : m_bc)
+    for (std::size_t j=0; j<ncomp; ++j)
+      m_bcmask[i*ncomp+j] = 0.0;
+
+  // Apply Dirichlet BCs on matrix and rhs
+  for (const auto& [i,dirbc] : m_bc) {
+    for (std::size_t j=0; j<ncomp; ++j) {
+      if (dirbc[j].first) {
+        m_A.dirichlet( i, m_gid, m_nodeCommMap, j );
+        m_b[i*ncomp+j] = dirbc[j].second;
+      }
+    }
+  }
+
+  // Recompute initial residual (r=b-A*x), its dot product, and the rhs norm
+  setup( cb );
+}
+
+void
+ConjugateGradients::solve( std::size_t maxit, tk::real tol, CkCallback c )
+// *****************************************************************************
+//  Solve linear system
+//! \param[in] maxit Max iteration count
+//! \param[in] tol Stop tolerance
+//! \param[in] c Call to continue with after solve is complete
+// *****************************************************************************
+{
+  m_maxit = maxit;
+  m_tol = tol;
+  m_solved = c;
+  m_it = 0;
+
+  next();
+}
+
+void
+ConjugateGradients::next()
+// *****************************************************************************
+//  Start next linear solver iteration
+// *****************************************************************************
+{
+  if (m_it == 0) m_alpha = 0.0; else m_alpha = m_rho/m_rho0;
+  m_rho0 = m_rho;
+
+  // compute p = r + alpha * p
+  for (std::size_t i=0; i<m_p.size(); ++i) m_p[i] = m_r[i] + m_alpha * m_p[i];
+
+  // initiate computing q = A * p
+  thisProxy[ thisIndex ].wait4q();
+  qAp();
+}
+
+
+void
+ConjugateGradients::qAp()
+// *****************************************************************************
+//  Initiate computing q = A * p
+// *****************************************************************************
+{
+  // Compute own contribution to q = A * p
+  m_A.mult( m_p, m_q, m_bcmask );
+
+  // Send partial product on chare-boundary nodes to fellow chares
+  if (m_nodeCommMap.empty()) {
+    comq_complete();
+  } else {
+    auto ncomp = m_A.Ncomp();
+    for (const auto& [c,n] : m_nodeCommMap) {
+      std::vector< std::vector< tk::real > > qc( n.size() );
+      std::size_t j = 0;
+      for (auto g : n) {
+        std::vector< tk::real > nq( ncomp );
+        auto i = tk::cref_find( m_lid, g );
+        for (std::size_t d=0; d<ncomp; ++d) nq[d] = m_q[ i*ncomp+d ];
+        qc[j++] = std::move(nq);
+      }
+      thisProxy[c].comq( std::vector<std::size_t>(begin(n),end(n)), qc );
+    }
+  }
+
+  ownq_complete();
+}
+
+void
+ConjugateGradients::comq( const std::vector< std::size_t >& gid,
+                          const std::vector< std::vector< tk::real > >& qc )
+// *****************************************************************************
+//  Receive contributions to q = A * p on chare-boundaries
+//! \param[in] gid Global mesh node IDs at which we receive contributions
+//! \param[in] qc Partial contributions at chare-boundary nodes
+// *****************************************************************************
+{
+  Assert( qc.size() == gid.size(), "Size mismatch" );
+
+  using tk::operator+=;
+
+  for (std::size_t i=0; i<gid.size(); ++i)
+    m_qc[ gid[i] ] += qc[i];
+
+  if (++m_nq == m_nodeCommMap.size()) {
+    m_nq = 0;
+    comq_complete();
+  }
+}
+
+void
+ConjugateGradients::q()
+// *****************************************************************************
+// Finish computing q = A * p
+// *****************************************************************************
+{
+  // Combine own and communicated contributions to q = A * p
+  auto ncomp = m_A.Ncomp();
+  for (const auto& [gid,q] : m_qc) {
+    auto i = tk::cref_find( m_lid, gid );
+    for (std::size_t c=0; c<ncomp; ++c)
+      m_q[i*ncomp+c] += q[c];
+  }
+  tk::destroy( m_qc );
+
+  // initiate computing (p,q)
+  dot( m_p, m_q,
+       CkCallback( CkReductionTarget(ConjugateGradients,pq), thisProxy ) );
+}
+
+void
+ConjugateGradients::pq( tk::real d )
+// *****************************************************************************
+// Compute the dot product (p,q)
+//! \param[in] d Dot product of (p,q) (aggregated across all chares)
+// *****************************************************************************
+{
+  // If (p,q)=0, then p and q are orthogonal and the system either has a trivial
+  // solution, x=x0, or the BCs are incomplete or wrong, in either case the
+  // solve cannot continue.
+  const auto eps = std::numeric_limits< tk::real >::epsilon();
+  if (std::abs(d) < eps) {
+    m_it = m_maxit;
+    m_alpha = 0.0;
+  } else {
+    m_alpha = m_rho / d;
+  }
+
+  // compute r = r - alpha * q
+  for (std::size_t i=0; i<m_r.size(); ++i) m_r[i] -= m_alpha * m_q[i];
+
+  // initiate computing norm of residual: (r,r)
+  dot( m_r, m_r,
+       CkCallback( CkReductionTarget(ConjugateGradients,normres), thisProxy ) );
+}
+
+void
+ConjugateGradients::normres( tk::real r )
+// *****************************************************************************
+// Compute norm of residual: (r,r)
+//! \param[in] r Dot product, (r,r) (aggregated across all chares)
+// *****************************************************************************
+{
+  m_rho = r;
+
+  // Advance solution: x = x + alpha * p
+  for (std::size_t i=0; i<m_x.size(); ++i) m_x[i] += m_alpha * m_p[i];
+
+  // Communicate solution
+  thisProxy[ thisIndex ].wait4x();
+
+  // Send solution on chare-boundary nodes to fellow chares
+  if (m_nodeCommMap.empty()) {
+    comx_complete();
+  } else {
+    auto ncomp = m_A.Ncomp();
+    for (const auto& [c,n] : m_nodeCommMap) {
+      std::vector< std::vector< tk::real > > xc( n.size() );
+      std::size_t j = 0;
+      for (auto g : n) {
+        std::vector< tk::real > nx( ncomp );
+        auto i = tk::cref_find( m_lid, g );
+        for (std::size_t d=0; d<ncomp; ++d) nx[d] = m_x[ i*ncomp+d ];
+        xc[j++] = std::move(nx);
+      }
+      thisProxy[c].comx( std::vector<std::size_t>(begin(n),end(n)), xc );
+    }
+  }
+
+  ownx_complete();
+}
+
+void
+ConjugateGradients::comx( const std::vector< std::size_t >& gid,
+                          const std::vector< std::vector< tk::real > >& xc )
+// *****************************************************************************
+//  Receive contributions to final solution on chare-boundaries
+//! \param[in] gid Global mesh node IDs at which we receive contributions
+//! \param[in] xc Partial contributions at chare-boundary nodes
+// *****************************************************************************
+{
+  Assert( xc.size() == gid.size(), "Size mismatch" );
+
+  for (std::size_t i=0; i<gid.size(); ++i) m_xc[ gid[i] ] += xc[i];
+
+  if (++m_nx == m_nodeCommMap.size()) {
+    m_nx = 0;
+    comx_complete();
+  }
+}
+
+void
+ConjugateGradients::x()
+// *****************************************************************************
+// Assemble solution on chare boundaries
+// *****************************************************************************
+{
+  // Assemble solution on chare boundaries by averaging
+  auto ncomp = m_A.Ncomp();
+  for (const auto& [g,x] : m_xc) {
+    auto i = tk::cref_find(m_lid,g);
+    for (std::size_t d=0; d<ncomp; ++d) m_x[i*ncomp+d] += x[d];
+    auto c = tk::count(m_nodeCommMap,g);
+    for (std::size_t d=0; d<ncomp; ++d) m_x[i*ncomp+d] /= c;
+  }
+  tk::destroy( m_xc );
+
+  ++m_it;
+  auto normb = m_normb > 1.0e-14 ? m_normb : 1.0;
+  auto normr = std::sqrt( m_rho );
+
+  if ( m_it < m_maxit && normr > m_tol*normb ) {
+
+    next();
+
+  } else {
+
+    m_converged = m_it == m_maxit && normr > m_tol*normb ? false : true;
+    m_solved.send( CkDataMsg::buildNew( sizeof(tk::real), &normr ) );
+
+  }
+}
+
+#include "NoWarning/conjugategradients.def.h"
 
diff --git a/Release/cppcheck/15.html b/Release/cppcheck/15.html index 463573949a45..b128b5d1e77f 100644 --- a/Release/cppcheck/15.html +++ b/Release/cppcheck/15.html @@ -152,12 +152,12 @@
  1
@@ -265,112 +265,422 @@ 

Cppcheck report - [

// *****************************************************************************
+106
+107
+108
+109
+110
+111
+112
+113
+114
+115
+116
+117
+118
+119
+120
+121
+122
+123
+124
+125
+126
+127
+128
+129
+130
+131
+132
+133
+134
+135
+136
+137
+138
+139
+140
+141
+142
+143
+144
+145
+146
+147
+148
+149
+150
+151
+152
+153
+154
+155
+156
+157
+158
+159
+160
+161
+162
+163
+164
+165
+166
+167
+168
+169
+170
+171
+172
+173
+174
+175
+176
+177
+178
+179
+180
+181
+182
+183
+184
+185
+186
+187
+188
+189
+190
+191
+192
+193
+194
+195
+196
+197
+198
+199
+200
+201
+202
+203
+204
+205
+206
+207
+208
+209
+210
+211
+212
+213
+214
+215
+216
+217
+218
+219
+220
+221
+222
+223
+224
+225
+226
+227
+228
+229
+230
+231
+232
+233
+234
+235
+236
+237
+238
+239
+240
+241
+242
+243
+244
+245
+246
+247
+248
+249
+250
+251
+252
+253
+254
+255
+256
+257
+258
+259
+260
+261
// *****************************************************************************
 /*!
-  \file      src/LinearSolver/CSR.hpp
+  \file      src/LinearSolver/ConjugateGradients.hpp
   \copyright 2012-2015 J. Bakosi,
              2016-2018 Los Alamos National Security, LLC.,
              2019-2021 Triad National Security, LLC.
              All rights reserved. See the LICENSE file for details.
-  \brief     Compressed sparse row (CSR) storage for a sparse matrix
-  \details   Compressed sparse row (CSR) storage for a sparse matrix.
-*/
-// *****************************************************************************
-#ifndef CSR_h
-#define CSR_h
-
-#include <vector>
-#include <ostream>
-
-#include "NoWarning/pup_stl.hpp"
-
-#include "Types.hpp"
-#include "CommMap.hpp"
-
-namespace tk {
-
-//! Compressed sparse row (CSR) storage for a sparse matrix
-class CSR {
-
-  public:
-    //! \brief Constructor: Create a CSR symmetric matrix with ncomp scalar
-    //!   components, storing only the upper triangular part
-    explicit CSR( std::size_t nc,
-                  const std::pair< std::vector< std::size_t >,
-                                   std::vector< std::size_t > >& psup );
+  \brief     Charm++ chare array for distributed conjugate gradients
+  \details   Charm++ chare array for asynchronous distributed
+    conjugate gradients linear solver.
+
+    There are a potentially large number of ConjugateGradients Charm++ chares.
+    Each ConjugateGradient chare gets a chunk of the full load, due to partiting
+    the mesh, on which the solve is performed.
+
+    The implementation uses the Charm++ runtime system and is fully
+    asynchronous, overlapping computation and communication. The algorithm
+    utilizes the structured dagger (SDAG) Charm++ functionality.
+*/
+// *****************************************************************************
+#ifndef ConjugateGradients_h
+#define ConjugateGradients_h
+
+#include "Types.hpp"
+#include "CSR.hpp"
+
+#include "NoWarning/conjugategradients.decl.h"
+
+namespace tk {
+
+//! \brief ConjugateGradients Charm++ chare array used to perform a distributed
+//!   linear solve with the conjugate gradients algorithm
+class ConjugateGradients : public CBase_ConjugateGradients {
 
-    //! Empty constructor for Charm++
-    explicit CSR() = default;
-
-    //! Return const reference to sparse matrix entry at a position
-    const real&
-    operator()( std::size_t row, std::size_t col, std::size_t pos=0 ) const;
-
-    //! Return non-const reference to sparse matrix entry at a position
-    //! \see "Avoid Duplication in const and Non-const Member Function," and
-    //!   "Use const whenever possible," Scott Meyers, Effective C++, 3d ed.
-    real&
-    operator()( std::size_t row, std::size_t col, std::size_t pos=0 ) {
-      return const_cast< real& >(
-               static_cast< const CSR& >( *this ).operator()( row, col, pos ) );
-    }
-
-    //! Set Dirichlet boundary condition at a node
-    void dirichlet(
-      std::size_t i,
-      const std::vector< std::size_t >& gid = {},
-      const NodeCommMap& nodecommap = {},
-      std::size_t pos=0 );
-
-    //! Multiply CSR matrix with vector from the right: r = A * x
-    void mult( const std::vector< real >& x, std::vector< real >& r,
-               const std::vector< tk::real >& bcmask ) const;
-
-    //! Access real size of matrix
-    std::size_t rsize() const { return rnz.size()*ncomp; }
-
-    //! Access the number of scalar components per non-zero matrix entry
-    std::size_t Ncomp() const { return ncomp; }
-
-    //! Write out CSR as stored
-    std::ostream& write_stored( std::ostream &os ) const;
-    //! Write out CSR nonzero structure
-    std::ostream& write_structure( std::ostream &os ) const;
-    //! Write out CSR contribute structure
-    std::ostream& write_contribute( std::ostream &os ) const;
-    //! Write out CSR as a real matrix
-    std::ostream& write_matrix( std::ostream &os ) const;
-    //! Write out CSR in Matlab/Octave format
-    std::ostream& write_matlab( std::ostream &os ) const;
-
-    /** @name Pack/unpack (Charm++ serialization) routines */
-    ///@{
-    //! \brief Pack/Unpack serialize member function
-    //! \param[in,out] p Charm++'s PUP::er serializer object reference
-    void pup( PUP::er &p ) {<--- Parameter 'p' can be declared with const
-      p | ncomp;
-      p | rnz;
-      p | ia;
-      p | ja;
-      p | a;
-    }
-    //! \brief Pack/Unpack serialize operator|
-    //! \param[in,out] p Charm++'s PUP::er serializer object reference
-    //! \param[in,out] c CSR object reference
-    friend void operator|( PUP::er& p, CSR& c ) { c.pup(p); }
-    ///@}
-
-  private:
-    std::size_t ncomp;                  //!< Number of scalars per non-zero
-    std::vector< std::size_t > rnz;     //!< Number of nonzeros in each row
-    std::vector< std::size_t > ia;      //!< Row pointers
-    std::vector< std::size_t > ja;      //!< Column indices
-    std::vector< real > a;              //!< Nonzero matrix values
-};
+  public:
+    #if defined(__clang__)
+      #pragma clang diagnostic push
+      #pragma clang diagnostic ignored "-Wunused-parameter"
+    #elif defined(STRICT_GNUC)
+      #pragma GCC diagnostic push
+      #pragma GCC diagnostic ignored "-Wunused-parameter"
+    #endif
+    // Include Charm++ SDAG code. See http://charm.cs.illinois.edu/manuals/html/
+    // charm++/manual.html, Sec. "Structured Control Flow: Structured Dagger".
+    ConjugateGradients_SDAG_CODE
+    #if defined(__clang__)
+      #pragma clang diagnostic pop
+    #elif defined(STRICT_GNUC)
+      #pragma GCC diagnostic pop
+    #endif
+
+    //! Constructor
+    explicit ConjugateGradients(
+      const CSR& A,
+      const std::vector< tk::real >& x,
+      const std::vector< tk::real >& b,
+      const std::vector< std::size_t >& gid,
+      const std::unordered_map< std::size_t, std::size_t >& lid,
+      const NodeCommMap& nodecommmap );
+
+    #if defined(__clang__)
+      #pragma clang diagnostic push
+      #pragma clang diagnostic ignored "-Wundefined-func-template"
+    #endif
+    //! Constructor taking a tuple of {A,x,b} by rvalue reference
+    explicit ConjugateGradients(<--- Member variable 'ConjugateGradients::m_tol' is not initialized in the constructor.
+      std::tuple< tk::CSR,
+                  std::vector< tk::real >,
+                  std::vector< tk::real > >&& system,
+      const std::vector< std::size_t >& gid,
+      const std::unordered_map< std::size_t, std::size_t >& lid,
+      const NodeCommMap& nodecommmap ) :
+      ConjugateGradients( std::move(std::get<0>(system)),
+                          std::move(std::get<1>(system)),
+                          std::move(std::get<2>(system)),
+                          gid, lid, nodecommmap ) {}
+
+    //! Migrate constructor
+    explicit ConjugateGradients( CkMigrateMessage* ) {}<--- Member variable 'ConjugateGradients::m_nr' is not initialized in the constructor.<--- Member variable 'ConjugateGradients::m_nb' is not initialized in the constructor.<--- Member variable 'ConjugateGradients::m_nq' is not initialized in the constructor.<--- Member variable 'ConjugateGradients::m_normb' is not initialized in the constructor.<--- Member variable 'ConjugateGradients::m_it' is not initialized in the constructor.<--- Member variable 'ConjugateGradients::m_maxit' is not initialized in the constructor.<--- Member variable 'ConjugateGradients::m_tol' is not initialized in the constructor.<--- Member variable 'ConjugateGradients::m_rho' is not initialized in the constructor.<--- Member variable 'ConjugateGradients::m_rho0' is not initialized in the constructor.<--- Member variable 'ConjugateGradients::m_alpha' is not initialized in the constructor.<--- Member variable 'ConjugateGradients::m_converged' is not initialized in the constructor.<--- Member variable 'ConjugateGradients::m_nx' is not initialized in the constructor.
+    #if defined(__clang__)
+      #pragma clang diagnostic pop
+    #endif
+
+    //! Solve linear system
+    void solve( std::size_t maxit, tk::real tol, CkCallback c );
+
+    //! Initialize linear solve: set initial guess and boundary conditions
+    void init( const std::vector< tk::real >& x,
+               const std::vector< tk::real >& b,
+               const std::unordered_map< std::size_t,
+                       std::vector< std::pair< bool, tk::real > > >& bc,
+               std::size_t ignorebc,
+               CkCallback cb );
+
+    //! Setup solver
+    void setup( CkCallback c );
+
+    //! Compute the norm of the right hand side
+    void normb( tk::real n );
+
+    //! Compute rho = (r,r)
+    void rho( tk::real r );
 
-} // tk::
-
-#endif // CSR_h
+    //! Receive contributions to r = b - A * x on chare-boundaries
+    void comres( const std::vector< std::size_t >& gid,
+                 const std::vector< std::vector< tk::real > >& rc );
+
+    //! Receive contributions to boundary conditions on chare-boundaries
+    void combc( const std::unordered_map< std::size_t,
+                       std::vector< std::pair< bool, tk::real > > >& bc );
+
+    //! Receive contributions to q = A * p on chare-boundaries
+    void comq( const std::vector< std::size_t >& gid,
+               const std::vector< std::vector< tk::real > >& qc );
+
+    void comx( const std::vector< std::size_t >& gid,
+               const std::vector< std::vector< tk::real > >& xc );
+
+    //! Compute the dot product (p,q)
+    void pq( tk::real d );
+
+    //! Compute the norm of the residual: (r,r)
+    void normres( tk::real r );
+
+    //! Access solution
+    std::vector< tk::real > solution() const { return m_x; }
+
+    //! Return convergence flag
+    bool converged() const { return m_converged; }
+
+    /** @name Pack/unpack (Charm++ serialization) routines */
+    ///@{
+    //! \brief Pack/Unpack serialize member function
+    //! \param[in,out] p Charm++'s PUP::er serializer object reference
+    void pup( PUP::er &p ) override {
+      p | m_A;
+      p | m_x;
+      p | m_b;
+      p | m_gid;
+      p | m_lid;
+      p | m_nodeCommMap;
+      p | m_r;
+      p | m_rc;
+      p | m_nr;
+      p | m_bc;
+      p | m_bcc;
+      p | m_bcmask;
+      p | m_nb;
+      p | m_p;
+      p | m_q;
+      p | m_qc;
+      p | m_nq;
+      p | m_initres;
+      p | m_solved;
+      p | m_normb;
+      p | m_it;
+      p | m_maxit;
+      p | m_tol;
+      p | m_rho;
+      p | m_rho0;
+      p | m_alpha;
+      p | m_converged;
+      p | m_xc;
+      p | m_nx;
+    }
+    //! \brief Pack/Unpack serialize operator|
+    //! \param[in,out] p Charm++'s PUP::er serializer object reference
+    //! \param[in,out] c ConjugateGradients object reference
+    friend void operator|( PUP::er& p, ConjugateGradients& c ) { c.pup(p); }
+    ///@}
+
+  private:
+    //! Sparse matrix
+    CSR m_A;
+    //! Solution/unknown
+    std::vector< tk::real > m_x;
+    //! Right hand side
+    std::vector< tk::real > m_b;
+    //! Global node IDs
+    std::vector< std::size_t > m_gid;
+    //! Local node IDs associated to global ones
+    std::unordered_map< std::size_t, std::size_t > m_lid;
+    //! Global mesh node IDs shared with other chares associated to chare IDs
+    NodeCommMap m_nodeCommMap;
+    //! Auxiliary vector for CG solve
+    std::vector< tk::real > m_r;
+    //! Receive buffer for communication of r = b - A * x
+    std::unordered_map< std::size_t, std::vector< tk::real > > m_rc;
+    //! Counter for assembling m_r
+    std::size_t m_nr;
+    //! Dirichlet boundary conditions
+    std::unordered_map< std::size_t,
+        std::vector< std::pair< bool, tk::real > > > m_bc;
+    //! Dirichlet boundary conditions communication buffer
+    std::unordered_map< std::size_t,
+        std::vector< std::pair< bool, tk::real > > > m_bcc;
+    //! Dirichlet boundary condition mask
+    std::vector< tk::real > m_bcmask;
+    //! Counter for assembling boundary conditions
+    std::size_t m_nb;
+    //! Auxiliary vector for CG solve
+    std::vector< tk::real > m_p;
+    //! Auxiliary vector for CG solve
+    std::vector< tk::real > m_q;
+    //! Receive buffer for communication of q = A * p
+    std::unordered_map< std::size_t, std::vector< tk::real > > m_qc;
+    //! Counter for assembling m_q
+    std::size_t m_nq;
+    //! Charm++ callback to continue with when the setup is complete
+    CkCallback m_initres;
+    //! Charm++ callback to continue with when the solve is complete
+    CkCallback m_solved;
+    //! L2 norm of the right hand side
+    tk::real m_normb;
+    //! Iteration count
+    std::size_t m_it;
+    //! Max iteration count
+    std::size_t m_maxit;
+    //! Stop tolerance
+    tk::real m_tol;
+    //! Helper scalar for CG algorithm
+    tk::real m_rho;
+    //! Helper scalar for CG algorithm
+    tk::real m_rho0;
+    //! Helper scalar for CG algorithm
+    tk::real m_alpha;
+    //! Convergence flag: true if linear smoother converged to tolerance
+    bool m_converged;
+    //! Receive buffer for solution
+    std::unordered_map< std::size_t, std::vector< tk::real > > m_xc;
+    //! Counter for assembling the solution on chare boundaries
+    std::size_t m_nx;
+
+    //! Initiate computationa of dot product of two vectors
+    void dot( const std::vector< tk::real >& a,
+              const std::vector< tk::real >& b,
+              CkCallback c );
+
+    //! Initiate A * x for computing the residual, r = b - A * x
+    void residual();
+    //! Finish computing the initial residual, r = b - A * x
+    void initres();
+
+    //! Apply boundary conditions
+    void apply( CkCallback cb );
+
+    //! Initiate computing q = A * p
+    void qAp();
+    //! Finish computing q = A * p
+    void q();
+
+    //! Start next linear solver iteration
+    void next();
+
+    //! Assemble solution on chare boundaries
+    void x();
+};
+
+} // tk::
+
+#endif // ConjugateGradients_h
 
diff --git a/Release/cppcheck/16.html b/Release/cppcheck/16.html index fc0fb1636387..76333a970baa 100644 --- a/Release/cppcheck/16.html +++ b/Release/cppcheck/16.html @@ -152,2121 +152,225 @@
- - + @@ -110,7 +110,7 @@ 36 : : //! Pack/Unpack serialize operator| 37 : : //! \param[in,out] p Charm++'s PUP::er serializer object reference 38 : : //! \param[in,out] s Refinement_State object reference - 39 [ + - ]: 3620053 : inline void operator|( PUP::er& p, AMR::Refinement_State& s ) { pup(p,s); } + 39 [ + - ]: 3630532 : inline void operator|( PUP::er& p, AMR::Refinement_State& s ) { pup(p,s); } 40 : : //@} 41 : : 42 : : /** @name Charm++ pack/unpack serializer member functions for Edge_Refinement */ @@ -120,7 +120,7 @@ 46 : : //! Pack/Unpack serialize operator| 47 : : //! \param[in,out] p Charm++'s PUP::er serializer object reference 48 : : //! \param[in,out] e Edge_Refinement object reference - 49 : 6225622 : inline void operator|( PUP::er& p, AMR::Edge_Refinement& e ) { pup(p,e); } + 49 : 6227284 : inline void operator|( PUP::er& p, AMR::Edge_Refinement& e ) { pup(p,e); } 50 : : //@} 51 : : 52 : : /** @name Charm++ pack/unpack serializer member functions for edge_store_t */ @@ -130,7 +130,7 @@ 56 : : //! Pack/Unpack serialize operator| 57 : : //! \param[in,out] p Charm++'s PUP::er serializer object reference 58 : : //! \param[in,out] e edge_store_t object reference - 59 : 24390 : inline void operator|( PUP::er& p, AMR::edge_store_t& e ) { pup(p,e); } + 59 : 24081 : inline void operator|( PUP::er& p, AMR::edge_store_t& e ) { pup(p,e); } 60 : : //@} 61 : : 62 : : /** @name Charm++ pack/unpack serializer member functions for edge_t */ @@ -140,7 +140,7 @@ 66 : : //! Pack/Unpack serialize operator| 67 : : //! \param[in,out] p Charm++'s PUP::er serializer object reference 68 : : //! \param[in,out] e edge_t object reference - 69 : 6225622 : inline void operator|( PUP::er& p, AMR::edge_t& e ) { pup(p,e); } + 69 : 6227284 : inline void operator|( PUP::er& p, AMR::edge_t& e ) { pup(p,e); } 70 : : //@} 71 : : 72 : : /** @name Charm++ pack/unpack serializer member functions for marked_refinements_store_t */ @@ -149,16 +149,16 @@ 75 : : //! \param[in] p Charm++'s pack/unpack object 76 : : //! \param[in,out] m marked_refinements_store_t object reference 77 : : template< class case_t > - 78 : 48780 : void pup( PUP::er &p, AMR::marked_refinements_store_t< case_t >& m ) { + 78 : 48162 : void pup( PUP::er &p, AMR::marked_refinements_store_t< case_t >& m ) { 79 : : p | m.data(); 80 : : p | m.get_state_changed(); - 81 : 48780 : } + 81 : 48162 : } 82 : : //! Pack/Unpack serialize operator| 83 : : //! \param[in,out] p Charm++'s PUP::er serializer object reference 84 : : //! \param[in,out] m marked_refinements_store_t object reference 85 : : template< class case_t > 86 : : inline void operator|( PUP::er& p, AMR::marked_refinements_store_t<case_t>& m ) - 87 : 24390 : { pup(p,m); } + 87 : 24081 : { pup(p,m); } 88 : : //@} 89 : : 90 : : /** @name Charm++ pack/unpack serializer member functions for active_element_store_t */ @@ -191,7 +191,7 @@ 117 : : //! \param[in,out] p Charm++'s PUP::er serializer object reference 118 : : //! \param[in,out] i id_generator_t object reference 119 : : inline void operator|( PUP::er& p, AMR::id_generator_t& i ) - 120 : 24390 : { pup(p,i); } + 120 : 24081 : { pup(p,i); } 121 : : //@} 122 : : 123 : : /** @name Charm++ pack/unpack serializer member functions for tet_store_t */ @@ -201,7 +201,7 @@ 127 : : //! Pack/Unpack serialize operator| 128 : : //! \param[in,out] p Charm++'s PUP::er serializer object reference 129 : : //! \param[in,out] t tet_store_t object reference - 130 : 24390 : inline void operator|( PUP::er& p, AMR::tet_store_t& t ) { pup(p,t); } + 130 : 24081 : inline void operator|( PUP::er& p, AMR::tet_store_t& t ) { pup(p,t); } 131 : : //@} 132 : : 133 : : /** @name Charm++ pack/unpack serializer member functions for mesh_adapter_t */ @@ -211,7 +211,7 @@ 137 : : //! Pack/Unpack serialize operator| 138 : : //! \param[in,out] p Charm++'s PUP::er serializer object reference 139 : : //! \param[in,out] m mesh_adapter_t object reference - 140 : 24390 : inline void operator|( PUP::er& p, AMR::mesh_adapter_t& m ) { pup(p,m); } + 140 : 24081 : inline void operator|( PUP::er& p, AMR::mesh_adapter_t& m ) { pup(p,m); } 141 : : //@} 142 : : 143 : : /** @name Charm++ pack/unpack serializer member functions for node_store_t */ @@ -231,7 +231,7 @@ 157 : : //! Pack/Unpack serialize operator| 158 : : //! \param[in,out] p Charm++'s PUP::er serializer object reference 159 : : //! \param[in,out] n node_connectivity_t object reference - 160 : 24390 : inline void operator|( PUP::er& p, AMR::node_connectivity_t& n ) { pup(p,n); } + 160 : 24081 : inline void operator|( PUP::er& p, AMR::node_connectivity_t& n ) { pup(p,n); } 161 : : //@} 162 : : 163 : : /** @name Charm++ pack/unpack serializer member functions for refinement_t */ @@ -241,7 +241,7 @@ 167 : : //! Pack/Unpack serialize operator| 168 : : //! \param[in,out] p Charm++'s PUP::er serializer object reference 169 : : //! \param[in,out] r refinement_t object reference - 170 : 24390 : inline void operator|( PUP::er& p, AMR::refinement_t& r ) { pup(p,r); } + 170 : 24081 : inline void operator|( PUP::er& p, AMR::refinement_t& r ) { pup(p,r); } 171 : : //@} 172 : : 173 : : } // PUP:: diff --git a/Release/test_coverage/Inciter/Partitioner.cpp.func-sort-c.html b/Release/test_coverage/Inciter/Partitioner.cpp.func-sort-c.html index e5a33e2cee18..c07d97aa20e8 100644 --- a/Release/test_coverage/Inciter/Partitioner.cpp.func-sort-c.html +++ b/Release/test_coverage/Inciter/Partitioner.cpp.func-sort-c.html @@ -33,7 +33,7 @@ - + diff --git a/Release/test_coverage/Inciter/Partitioner.cpp.func.html b/Release/test_coverage/Inciter/Partitioner.cpp.func.html index 8b8cb6112db0..1a7c0c7b68d5 100644 --- a/Release/test_coverage/Inciter/Partitioner.cpp.func.html +++ b/Release/test_coverage/Inciter/Partitioner.cpp.func.html @@ -33,7 +33,7 @@ - + diff --git a/Release/test_coverage/Inciter/Partitioner.cpp.gcov.html b/Release/test_coverage/Inciter/Partitioner.cpp.gcov.html index 1f46da1e0b36..e8fde2e1eecd 100644 --- a/Release/test_coverage/Inciter/Partitioner.cpp.gcov.html +++ b/Release/test_coverage/Inciter/Partitioner.cpp.gcov.html @@ -33,7 +33,7 @@ - + diff --git a/Release/test_coverage/Inciter/Partitioner.hpp.func-sort-c.html b/Release/test_coverage/Inciter/Partitioner.hpp.func-sort-c.html index 8a97c13f25d4..f6be1c9a4c5d 100644 --- a/Release/test_coverage/Inciter/Partitioner.hpp.func-sort-c.html +++ b/Release/test_coverage/Inciter/Partitioner.hpp.func-sort-c.html @@ -33,7 +33,7 @@ - + diff --git a/Release/test_coverage/Inciter/Partitioner.hpp.func.html b/Release/test_coverage/Inciter/Partitioner.hpp.func.html index 4f5e1ee5eed8..3a2df3d30a39 100644 --- a/Release/test_coverage/Inciter/Partitioner.hpp.func.html +++ b/Release/test_coverage/Inciter/Partitioner.hpp.func.html @@ -33,7 +33,7 @@ - + diff --git a/Release/test_coverage/Inciter/Partitioner.hpp.gcov.html b/Release/test_coverage/Inciter/Partitioner.hpp.gcov.html index 2e27554d4432..c347050b0b97 100644 --- a/Release/test_coverage/Inciter/Partitioner.hpp.gcov.html +++ b/Release/test_coverage/Inciter/Partitioner.hpp.gcov.html @@ -33,7 +33,7 @@ - + diff --git a/Release/test_coverage/Inciter/Refiner.cpp.func-sort-c.html b/Release/test_coverage/Inciter/Refiner.cpp.func-sort-c.html index 754abcef85a2..a8ecae6243dd 100644 --- a/Release/test_coverage/Inciter/Refiner.cpp.func-sort-c.html +++ b/Release/test_coverage/Inciter/Refiner.cpp.func-sort-c.html @@ -33,7 +33,7 @@ - + diff --git a/Release/test_coverage/Inciter/Refiner.cpp.func.html b/Release/test_coverage/Inciter/Refiner.cpp.func.html index f112a9172a51..d6e9d064ffb6 100644 --- a/Release/test_coverage/Inciter/Refiner.cpp.func.html +++ b/Release/test_coverage/Inciter/Refiner.cpp.func.html @@ -33,7 +33,7 @@ - + diff --git a/Release/test_coverage/Inciter/Refiner.cpp.gcov.html b/Release/test_coverage/Inciter/Refiner.cpp.gcov.html index de2fb98143c0..0a19ebbd827c 100644 --- a/Release/test_coverage/Inciter/Refiner.cpp.gcov.html +++ b/Release/test_coverage/Inciter/Refiner.cpp.gcov.html @@ -33,7 +33,7 @@ - + @@ -935,7 +935,7 @@ 848 : : std::array<Edge,6> edges{{ {{A,B}}, {{B,C}}, {{A,C}}, 849 : 589554 : {{A,D}}, {{B,D}}, {{C,D}} }}; 850 [ + + ]: 4126878 : for (const auto& ed : edges) { - 851 [ + + ]: 5771428 : auto ae = AMR::edge_t{{{ std::min(ed[0],ed[1]), std::max(ed[0],ed[1]) }}}; + 851 [ + + ]: 5771260 : auto ae = AMR::edge_t{{{ std::min(ed[0],ed[1]), std::max(ed[0],ed[1]) }}}; 852 : 3537324 : auto r = tk::cref_find( ref_edges, ae ); 853 : 7074648 : const auto ged = Edge{{ m_gid[ tk::cref_find( m_lref, ed[0] ) ], 854 : 7074648 : m_gid[ tk::cref_find( m_lref, ed[1] ) ] }}; @@ -972,7 +972,7 @@ 885 : : std::array<Edge,6> edges{{ {{A,B}}, {{B,C}}, {{A,C}}, 886 : 109575 : {{A,D}}, {{B,D}}, {{C,D}} }}; 887 [ + + ]: 767025 : for (const auto& ed : edges) { - 888 [ + + ]: 1075500 : auto ae = AMR::edge_t{{{ std::min(ed[0],ed[1]), std::max(ed[0],ed[1]) }}}; + 888 [ + + ]: 1075416 : auto ae = AMR::edge_t{{{ std::min(ed[0],ed[1]), std::max(ed[0],ed[1]) }}}; 889 : 657450 : auto r = tk::cref_find( ref_edges, ae ); 890 : 1314900 : const auto ged = Edge{{ m_gid[ tk::cref_find( m_lref, ed[0] ) ], 891 : 1314900 : m_gid[ tk::cref_find( m_lref, ed[1] ) ] }}; @@ -1748,7 +1748,7 @@ 1631 : : auto& nodes = tk::ref_find( m_nodeCommMap, neighborchare ); 1632 [ + + ]: 24192 : for (const auto& e : edges) { 1633 : : // If parent nodes were part of the node communication map for chare - 1634 [ + + ][ + + ]: 28374 : if (nodes.find(e[0]) != end(nodes) && nodes.find(e[1]) != end(nodes)) { + 1634 [ + + ][ + + ]: 28338 : if (nodes.find(e[0]) != end(nodes) && nodes.find(e[1]) != end(nodes)) { 1635 : : // Add new node if local id was generated for it 1636 : 2418 : auto n = Hash<2>()( e ); 1637 [ + + ]: 4836 : if (m_lid.find(n) != end(m_lid)) nodes.insert( n ); diff --git a/Release/test_coverage/Inciter/Refiner.hpp.func-sort-c.html b/Release/test_coverage/Inciter/Refiner.hpp.func-sort-c.html index d0595d5319b1..a50be0b8ffca 100644 --- a/Release/test_coverage/Inciter/Refiner.hpp.func-sort-c.html +++ b/Release/test_coverage/Inciter/Refiner.hpp.func-sort-c.html @@ -33,7 +33,7 @@ - + @@ -73,11 +73,11 @@ - + - + diff --git a/Release/test_coverage/Inciter/Refiner.hpp.func.html b/Release/test_coverage/Inciter/Refiner.hpp.func.html index 7293d6985fde..1387a54ce204 100644 --- a/Release/test_coverage/Inciter/Refiner.hpp.func.html +++ b/Release/test_coverage/Inciter/Refiner.hpp.func.html @@ -33,7 +33,7 @@ - + @@ -73,7 +73,7 @@ - + @@ -81,7 +81,7 @@ - +
   1
-   2
-   3
-   4
-   5
-   6
-   7
-   8
-   9
-  10
-  11
-  12
-  13
-  14
-  15
-  16
-  17
-  18
-  19
-  20
-  21
-  22
-  23
-  24
-  25
-  26
-  27
-  28
-  29
-  30
-  31
-  32
-  33
-  34
-  35
-  36
-  37
-  38
-  39
-  40
-  41
-  42
-  43
-  44
-  45
-  46
-  47
-  48
-  49
-  50
-  51
-  52
-  53
-  54
-  55
-  56
-  57
-  58
-  59
-  60
-  61
-  62
-  63
-  64
-  65
-  66
-  67
-  68
-  69
-  70
-  71
-  72
-  73
-  74
-  75
-  76
-  77
-  78
-  79
-  80
-  81
-  82
-  83
-  84
-  85
-  86
-  87
-  88
-  89
-  90
-  91
-  92
-  93
-  94
-  95
-  96
-  97
-  98
-  99
- 100
- 101
- 102
- 103
- 104
- 105
- 106
- 107
- 108
- 109
- 110
- 111
- 112
- 113
- 114
- 115
- 116
- 117
- 118
- 119
- 120
- 121
- 122
- 123
- 124
- 125
- 126
- 127
- 128
- 129
- 130
- 131
- 132
- 133
- 134
- 135
- 136
- 137
- 138
- 139
- 140
- 141
- 142
- 143
- 144
- 145
- 146
- 147
- 148
- 149
- 150
- 151
- 152
- 153
- 154
- 155
- 156
- 157
- 158
- 159
- 160
- 161
- 162
- 163
- 164
- 165
- 166
- 167
- 168
- 169
- 170
- 171
- 172
- 173
- 174
- 175
- 176
- 177
- 178
- 179
- 180
- 181
- 182
- 183
- 184
- 185
- 186
- 187
- 188
- 189
- 190
- 191
- 192
- 193
- 194
- 195
- 196
- 197
- 198
- 199
- 200
- 201
- 202
- 203
- 204
- 205
- 206
- 207
- 208
- 209
- 210
- 211
- 212
- 213
- 214
- 215
- 216
- 217
- 218
- 219
- 220
- 221
- 222
- 223
- 224
- 225
- 226
- 227
- 228
- 229
- 230
- 231
- 232
- 233
- 234
- 235
- 236
- 237
- 238
- 239
- 240
- 241
- 242
- 243
- 244
- 245
- 246
- 247
- 248
- 249
- 250
- 251
- 252
- 253
- 254
- 255
- 256
- 257
- 258
- 259
- 260
- 261
- 262
- 263
- 264
- 265
- 266
- 267
- 268
- 269
- 270
- 271
- 272
- 273
- 274
- 275
- 276
- 277
- 278
- 279
- 280
- 281
- 282
- 283
- 284
- 285
- 286
- 287
- 288
- 289
- 290
- 291
- 292
- 293
- 294
- 295
- 296
- 297
- 298
- 299
- 300
- 301
- 302
- 303
- 304
- 305
- 306
- 307
- 308
- 309
- 310
- 311
- 312
- 313
- 314
- 315
- 316
- 317
- 318
- 319
- 320
- 321
- 322
- 323
- 324
- 325
- 326
- 327
- 328
- 329
- 330
- 331
- 332
- 333
- 334
- 335
- 336
- 337
- 338
- 339
- 340
- 341
- 342
- 343
- 344
- 345
- 346
- 347
- 348
- 349
- 350
- 351
- 352
- 353
- 354
- 355
- 356
- 357
- 358
- 359
- 360
- 361
- 362
- 363
- 364
- 365
- 366
- 367
- 368
- 369
- 370
- 371
- 372
- 373
- 374
- 375
- 376
- 377
- 378
- 379
- 380
- 381
- 382
- 383
- 384
- 385
- 386
- 387
- 388
- 389
- 390
- 391
- 392
- 393
- 394
- 395
- 396
- 397
- 398
- 399
- 400
- 401
- 402
- 403
- 404
- 405
- 406
- 407
- 408
- 409
- 410
- 411
- 412
- 413
- 414
- 415
- 416
- 417
- 418
- 419
- 420
- 421
- 422
- 423
- 424
- 425
- 426
- 427
- 428
- 429
- 430
- 431
- 432
- 433
- 434
- 435
- 436
- 437
- 438
- 439
- 440
- 441
- 442
- 443
- 444
- 445
- 446
- 447
- 448
- 449
- 450
- 451
- 452
- 453
- 454
- 455
- 456
- 457
- 458
- 459
- 460
- 461
- 462
- 463
- 464
- 465
- 466
- 467
- 468
- 469
- 470
- 471
- 472
- 473
- 474
- 475
- 476
- 477
- 478
- 479
- 480
- 481
- 482
- 483
- 484
- 485
- 486
- 487
- 488
- 489
- 490
- 491
- 492
- 493
- 494
- 495
- 496
- 497
- 498
- 499
- 500
- 501
- 502
- 503
- 504
- 505
- 506
- 507
- 508
- 509
- 510
- 511
- 512
- 513
- 514
- 515
- 516
- 517
- 518
- 519
- 520
- 521
- 522
- 523
- 524
- 525
- 526
- 527
- 528
- 529
- 530
- 531
- 532
- 533
- 534
- 535
- 536
- 537
- 538
- 539
- 540
- 541
- 542
- 543
- 544
- 545
- 546
- 547
- 548
- 549
- 550
- 551
- 552
- 553
- 554
- 555
- 556
- 557
- 558
- 559
- 560
- 561
- 562
- 563
- 564
- 565
- 566
- 567
- 568
- 569
- 570
- 571
- 572
- 573
- 574
- 575
- 576
- 577
- 578
- 579
- 580
- 581
- 582
- 583
- 584
- 585
- 586
- 587
- 588
- 589
- 590
- 591
- 592
- 593
- 594
- 595
- 596
- 597
- 598
- 599
- 600
- 601
- 602
- 603
- 604
- 605
- 606
- 607
- 608
- 609
- 610
- 611
- 612
- 613
- 614
- 615
- 616
- 617
- 618
- 619
- 620
- 621
- 622
- 623
- 624
- 625
- 626
- 627
- 628
- 629
- 630
- 631
- 632
- 633
- 634
- 635
- 636
- 637
- 638
- 639
- 640
- 641
- 642
- 643
- 644
- 645
- 646
- 647
- 648
- 649
- 650
- 651
- 652
- 653
- 654
- 655
- 656
- 657
- 658
- 659
- 660
- 661
- 662
- 663
- 664
- 665
- 666
- 667
- 668
- 669
- 670
- 671
- 672
- 673
- 674
- 675
- 676
- 677
- 678
- 679
- 680
- 681
- 682
- 683
- 684
- 685
- 686
- 687
- 688
- 689
- 690
- 691
- 692
- 693
- 694
- 695
- 696
- 697
- 698
- 699
- 700
- 701
- 702
- 703
- 704
- 705
- 706
- 707
- 708
- 709
- 710
- 711
- 712
- 713
- 714
- 715
- 716
- 717
- 718
- 719
- 720
- 721
- 722
- 723
- 724
- 725
- 726
- 727
- 728
- 729
- 730
- 731
- 732
- 733
- 734
- 735
- 736
- 737
- 738
- 739
- 740
- 741
- 742
- 743
- 744
- 745
- 746
- 747
- 748
- 749
- 750
- 751
- 752
- 753
- 754
- 755
- 756
- 757
- 758
- 759
- 760
- 761
- 762
- 763
- 764
- 765
- 766
- 767
- 768
- 769
- 770
- 771
- 772
- 773
- 774
- 775
- 776
- 777
- 778
- 779
- 780
- 781
- 782
- 783
- 784
- 785
- 786
- 787
- 788
- 789
- 790
- 791
- 792
- 793
- 794
- 795
- 796
- 797
- 798
- 799
- 800
- 801
- 802
- 803
- 804
- 805
- 806
- 807
- 808
- 809
- 810
- 811
- 812
- 813
- 814
- 815
- 816
- 817
- 818
- 819
- 820
- 821
- 822
- 823
- 824
- 825
- 826
- 827
- 828
- 829
- 830
- 831
- 832
- 833
- 834
- 835
- 836
- 837
- 838
- 839
- 840
- 841
- 842
- 843
- 844
- 845
- 846
- 847
- 848
- 849
- 850
- 851
- 852
- 853
- 854
- 855
- 856
- 857
- 858
- 859
- 860
- 861
- 862
- 863
- 864
- 865
- 866
- 867
- 868
- 869
- 870
- 871
- 872
- 873
- 874
- 875
- 876
- 877
- 878
- 879
- 880
- 881
- 882
- 883
- 884
- 885
- 886
- 887
- 888
- 889
- 890
- 891
- 892
- 893
- 894
- 895
- 896
- 897
- 898
- 899
- 900
- 901
- 902
- 903
- 904
- 905
- 906
- 907
- 908
- 909
- 910
- 911
- 912
- 913
- 914
- 915
- 916
- 917
- 918
- 919
- 920
- 921
- 922
- 923
- 924
- 925
- 926
- 927
- 928
- 929
- 930
- 931
- 932
- 933
- 934
- 935
- 936
- 937
- 938
- 939
- 940
- 941
- 942
- 943
- 944
- 945
- 946
- 947
- 948
- 949
- 950
- 951
- 952
- 953
- 954
- 955
- 956
- 957
- 958
- 959
- 960
- 961
- 962
- 963
- 964
- 965
- 966
- 967
- 968
- 969
- 970
- 971
- 972
- 973
- 974
- 975
- 976
- 977
- 978
- 979
- 980
- 981
- 982
- 983
- 984
- 985
- 986
- 987
- 988
- 989
- 990
- 991
- 992
- 993
- 994
- 995
- 996
- 997
- 998
- 999
-1000
-1001
-1002
-1003
-1004
-1005
-1006
-1007
-1008
-1009
-1010
-1011
-1012
-1013
-1014
-1015
-1016
-1017
-1018
-1019
-1020
-1021
-1022
-1023
-1024
-1025
-1026
-1027
-1028
-1029
-1030
-1031
-1032
-1033
-1034
-1035
-1036
-1037
-1038
-1039
-1040
-1041
-1042
-1043
-1044
-1045
-1046
-1047
-1048
-1049
-1050
-1051
-1052
-1053
-1054
// *****************************************************************************
+
  1
+  2
+  3
+  4
+  5
+  6
+  7
+  8
+  9
+ 10
+ 11
+ 12
+ 13
+ 14
+ 15
+ 16
+ 17
+ 18
+ 19
+ 20
+ 21
+ 22
+ 23
+ 24
+ 25
+ 26
+ 27
+ 28
+ 29
+ 30
+ 31
+ 32
+ 33
+ 34
+ 35
+ 36
+ 37
+ 38
+ 39
+ 40
+ 41
+ 42
+ 43
+ 44
+ 45
+ 46
+ 47
+ 48
+ 49
+ 50
+ 51
+ 52
+ 53
+ 54
+ 55
+ 56
+ 57
+ 58
+ 59
+ 60
+ 61
+ 62
+ 63
+ 64
+ 65
+ 66
+ 67
+ 68
+ 69
+ 70
+ 71
+ 72
+ 73
+ 74
+ 75
+ 76
+ 77
+ 78
+ 79
+ 80
+ 81
+ 82
+ 83
+ 84
+ 85
+ 86
+ 87
+ 88
+ 89
+ 90
+ 91
+ 92
+ 93
+ 94
+ 95
+ 96
+ 97
+ 98
+ 99
+100
+101
+102
+103
+104
+105
+106
// *****************************************************************************
 /*!
-  \file      src/IO/ExodusIIMeshReader.cpp
+  \file      src/LinearSolver/CSR.hpp
   \copyright 2012-2015 J. Bakosi,
              2016-2018 Los Alamos National Security, LLC.,
              2019-2021 Triad National Security, LLC.
              All rights reserved. See the LICENSE file for details.
-  \brief     ExodusII mesh reader
-  \details   ExodusII mesh reader class definition.
+  \brief     Compressed sparse row (CSR) storage for a sparse matrix
+  \details   Compressed sparse row (CSR) storage for a sparse matrix.
 */
 // *****************************************************************************
-
-#include <numeric>
+#ifndef CSR_h
+#define CSR_h
 
-#include "NoWarning/exodusII.hpp"
-
-#include "ExodusIIMeshReader.hpp"
-#include "ContainerUtil.hpp"
-#include "Exception.hpp"
-#include "UnsMesh.hpp"
-#include "Reorder.hpp"
+#include <vector>
+#include <ostream>
+
+#include "NoWarning/pup_stl.hpp"
+
+#include "Types.hpp"
+#include "CommMap.hpp"
 
-using tk::ExodusIIMeshReader;
+namespace tk {
 
-ExodusIIMeshReader::ExodusIIMeshReader( const std::string& filename,<--- Member variable 'ExodusIIMeshReader::m_nelem' is not initialized in the constructor.
-                                        int cpuwordsize,
-                                        int iowordsize ) :
-  m_filename( filename ),
-  m_cpuwordsize( cpuwordsize ),
-  m_iowordsize( iowordsize ),
-  m_inFile( 0 ),
-  m_nnode( 0 ),
-  m_neblk( 0 ),
-  m_neset( 0 ),
-  m_from( 0 ),
-  m_till( 0 ),
-  m_blockid(),
-  m_blockid_by_type( ExoNnpe.size() ),
-  m_nel( ExoNnpe.size() ),
-  m_elemblocks(),
-  m_tri()
-// *****************************************************************************
-//  Constructor: open Exodus II file
-//! \param[in] filename File to open as ExodusII file
-//! \param[in] cpuwordsize Set CPU word size, see ExodusII documentation
-//! \param[in] iowordsize Set I/O word size, see ExodusII documentation
-// *****************************************************************************
-{
-  // Increase verbosity from ExodusII library in debug mode
-  #ifndef NDEBUG
-  ex_opts( EX_DEBUG | EX_VERBOSE );
-  #endif
-
-  float version;
-
-  m_inFile = ex_open( filename.c_str(), EX_READ, &cpuwordsize, &iowordsize,
-                      &version );
-
-  // output exodusII/netcdf configuration
-  //ex_print_config();
+//! Compressed sparse row (CSR) storage for a sparse matrix
+class CSR {
+
+  public:
+    //! \brief Constructor: Create a CSR symmetric matrix with ncomp scalar
+    //!   components, storing only the upper triangular part
+    explicit CSR( std::size_t nc,
+                  const std::pair< std::vector< std::size_t >,
+                                   std::vector< std::size_t > >& psup );
+
+    //! Empty constructor for Charm++
+    explicit CSR() = default;
+
+    //! Return const reference to sparse matrix entry at a position
+    const real&
+    operator()( std::size_t row, std::size_t col, std::size_t pos=0 ) const;
+
+    //! Return non-const reference to sparse matrix entry at a position
+    //! \see "Avoid Duplication in const and Non-const Member Function," and
+    //!   "Use const whenever possible," Scott Meyers, Effective C++, 3d ed.
+    real&
+    operator()( std::size_t row, std::size_t col, std::size_t pos=0 ) {
+      return const_cast< real& >(
+               static_cast< const CSR& >( *this ).operator()( row, col, pos ) );
+    }
+
+    //! Set Dirichlet boundary condition at a node
+    void dirichlet(
+      std::size_t i,
+      const std::vector< std::size_t >& gid = {},
+      const NodeCommMap& nodecommap = {},
+      std::size_t pos=0 );
+
+    //! Multiply CSR matrix with vector from the right: r = A * x
+    void mult( const std::vector< real >& x, std::vector< real >& r,
+               const std::vector< tk::real >& bcmask ) const;
 
-  ErrChk( m_inFile > 0, "Failed to open ExodusII file: " + filename );
-}
+    //! Access real size of matrix
+    std::size_t rsize() const { return rnz.size()*ncomp; }
 
-ExodusIIMeshReader::~ExodusIIMeshReader() noexcept
-// *****************************************************************************
-//  Destructor
-// *****************************************************************************
-{
-  if ( ex_close(m_inFile) < 0 )
-    printf( ">>> WARNING: Failed to close ExodusII file: %s\n",
-            m_filename.c_str() );
-}
-
-void
-ExodusIIMeshReader::readMesh( UnsMesh& mesh )
-// *****************************************************************************
-//  Read ExodusII mesh file
-//! \param[in] mesh Unstructured mesh object
-// *****************************************************************************
-{
-  readHeader( mesh );
-  readAllElements( mesh );
-  readAllNodes( mesh );
-  readSidesetFaces( mesh.bface(), mesh.faceid() );
-  readTimeValues( mesh.vartimes() );
-  readNodeVarNames( mesh.nodevarnames() );
-  readElemVarNames( mesh.elemvarnames() );
-  readNodeScalars( mesh.vartimes().size(),
-                   mesh.nodevarnames().size(),
-                   mesh.nodevars() );
-  readElemScalars( mesh.vartimes().size(),
-                   mesh.elemvarnames().size(),
-                   mesh.elemvars() );
-}
-
-void
-ExodusIIMeshReader::readGraph( UnsMesh& mesh )
-// *****************************************************************************
-//  Read only connectivity graph from file
-//! \param[in] mesh Unstructured mesh object
-// *****************************************************************************
-{
-  readHeader( mesh );
-  readAllElements( mesh );
-}
-
-void
-ExodusIIMeshReader::readMeshPart(
-  std::vector< std::size_t >& ginpoel,
-  std::vector< std::size_t >& inpoel,
-  std::vector< std::size_t >& triinp,
-  std::unordered_map< std::size_t, std::size_t >& lid,
-  tk::UnsMesh::Coords& coord,
-  std::unordered_map< std::size_t, std::set< std::size_t > >& elemBlockId,
-  int numpes, int mype )
-// *****************************************************************************
-//  Read a part of the mesh (graph and coordinates) from ExodusII file
-//! \param[in,out] ginpoel Container to store element connectivity of this PE's
-//!   chunk of the mesh (global ids)
-//! \param[in,out] inpoel Container to store element connectivity with local
-//!   node IDs of this PE's mesh chunk
-//! \param[in,out] triinp Container to store triangle element connectivity
-//!   (if exists in file) with global node indices
-//! \param[in,out] lid Container to store global->local node IDs of elements of
-//!   this PE's mesh chunk
-//! \param[in,out] coord Container to store coordinates of mesh nodes of this
-//!   PE's mesh chunk
-//! \param[in,out] elemBlockId List of elements for each block-id.
-//! \param[in] numpes Total number of PEs (default n = 1, for a single-CPU read)
-//! \param[in] mype This PE (default m = 0, for a single-CPU read)
-// *****************************************************************************
-{
-  Assert( mype < numpes, "Invalid input: PE id must be lower than NumPEs" );
-  Assert( ginpoel.empty() && inpoel.empty() && lid.empty() &&
-          coord[0].empty() && coord[1].empty() && coord[2].empty(),
-          "Containers to store mesh must be empty" );
-
-  // Read info on element blocks from ExodusII file
-  readElemBlockIDs();
-  // Get number of number of tetrahedron elements in file
-  auto nel = nelem( tk::ExoElemType::TET );
-
-  // Compute extents of element IDs of this PE's mesh chunk to read
-  auto npes = static_cast< std::size_t >( numpes );
-  auto pe = static_cast< std::size_t >( mype );
-  auto chunk = nel / npes;
-  m_from = pe * chunk;
-  m_till = m_from + chunk;
-  if (pe == npes-1) m_till += nel % npes;
-
-  // Read tetrahedron connectivity between from and till
-  readElements( {{m_from, m_till-1}}, tk::ExoElemType::TET, ginpoel );
-  elemBlockId = m_elemInBlockId;
-
-  // Compute local data from global mesh connectivity
-  std::vector< std::size_t > gid;
-  std::tie( inpoel, gid, lid ) = tk::global2local( ginpoel );
-
-  // Read this PE's chunk of the mesh node coordinates from file
-  coord = readCoords( gid );
-
-  // Generate set of unique faces
-  tk::UnsMesh::FaceSet faces;
-  for (std::size_t e=0; e<ginpoel.size()/4; ++e)
-    for (std::size_t f=0; f<4; ++f) {
-      const auto& tri = tk::expofa[f];
-      faces.insert( {{{ ginpoel[ e*4+tri[0] ],
-                        ginpoel[ e*4+tri[1] ],
-                        ginpoel[ e*4+tri[2] ] }}} );
-    }
-
-  // Read triangle element connectivity (all triangle blocks in file)
-  auto ntri = nelem( tk::ExoElemType::TRI );
-  if ( ntri !=0 ) readElements( {{0,ntri-1}}, tk::ExoElemType::TRI, triinp );
-
-  // Keep triangles shared in (partially-read) tetrahedron mesh
-  std::vector< std::size_t > triinp_own;
-  std::size_t ltrid = 0;        // local triangle id
-  for (std::size_t e=0; e<triinp.size()/3; ++e) {
-    auto i = faces.find( {{ triinp[e*3+0], triinp[e*3+1], triinp[e*3+2] }} );
-    if (i != end(faces)) {
-      m_tri[e] = ltrid++;       // generate global->local triangle ids
-      triinp_own.push_back( triinp[e*3+0] );
-      triinp_own.push_back( triinp[e*3+1] );
-      triinp_own.push_back( triinp[e*3+2] );
-    }
-  }
-  triinp = std::move(triinp_own);
-}
-
-std::array< std::vector< tk::real >, 3 >
-ExodusIIMeshReader::readCoords( const std::vector< std::size_t >& gid ) const
-// *****************************************************************************
-//  Read coordinates of a number of mesh nodes from ExodusII file
-//! \param[in] gid Global node IDs whose coordinates to read
-//! \return Vector of node coordinates read from file
-// *****************************************************************************
-{
-  // Read node coordinates from file with global node IDs given in gid
-  return readNodes( gid );
-}
-
-std::size_t
-ExodusIIMeshReader::readHeader()
-// *****************************************************************************
-//  Read ExodusII header without setting mesh size
-//! \return Number of nodes in mesh
-// *****************************************************************************
-{
-  char title[MAX_LINE_LENGTH+1];
-  int ndim, nelem, nnodeset, nelemset, nnode, neblk;
-
-  ErrChk(
-    ex_get_init( m_inFile, title, &ndim, &nnode, &nelem, &neblk, &nnodeset,
-                 &nelemset ) == 0,
-    "Failed to read header from ExodusII file: " + m_filename );
-
-  ErrChk( nnode > 0,
-          "Number of nodes read from ExodusII file must be larger than zero" );
-  ErrChk( neblk > 0,
-          "Number of element blocks read from ExodusII file must be larger "
-          "than zero" );
-  ErrChk( ndim == 3, "Need a 3D mesh from ExodusII file " + m_filename );
-
-  m_nelem = static_cast< std::size_t >( nelem );
-  m_neblk = static_cast< std::size_t >( neblk );
-  m_neset = static_cast< std::size_t >( nelemset );
-
-  return static_cast< std::size_t >( nnode );
-}
-
-void
-ExodusIIMeshReader::readHeader( UnsMesh& mesh )
-// *****************************************************************************
-//  Read ExodusII header with setting mesh size
-//! \param[in] mesh Unstructured mesh object
-// *****************************************************************************
-{
-  // Read ExodusII file header and set mesh graph size
-  mesh.size() = m_nnode = static_cast< std::size_t >( readHeader() );
-}
-
-void
-ExodusIIMeshReader::readAllNodes( UnsMesh& mesh ) const
-// *****************************************************************************
-//  Read all node coordinates from ExodusII file
-//! \param[in] mesh Unstructured mesh object
-// *****************************************************************************
-{
-  mesh.x().resize( m_nnode );
-  mesh.y().resize( m_nnode );
-  mesh.z().resize( m_nnode );
-
-  ErrChk( ex_get_coord( m_inFile, mesh.x().data(), mesh.y().data(),
-                        mesh.z().data() ) == 0,
-          "Failed to read coordinates from ExodusII file: " + m_filename );
-}
-
-void
-ExodusIIMeshReader::readNode( std::size_t fid,
-                              std::size_t mid,
-                              std::vector< tk::real >& x,
-                              std::vector< tk::real >& y,
-                              std::vector< tk::real >& z ) const
-// *****************************************************************************
-//  Read coordinates of a single mesh node from ExodusII file
-//! \param[in] fid Node id in file whose coordinates to read
-//! \param[in] mid Node id in memory to which to put new cordinates
-//! \param[in,out] x Vector of x coordinates to push to
-//! \param[in,out] y Vector of y coordinates to push to
-//! \param[in,out] z Vector of z coordinates to push to
-// *****************************************************************************
-{
-  Assert( x.size() == y.size() && x.size() == z.size(), "Size mismatch" );
-  Assert( mid < x.size() && mid < y.size() && mid < z.size(),
-          "Indexing out of bounds" );
-
-  readNode( fid, x[mid], y[mid], z[mid] );
-}
-
-void
-ExodusIIMeshReader::readNode( std::size_t id,
-                              std::array< tk::real, 3 >& coord ) const
-// *****************************************************************************
-//  Read coordinates of a single mesh node from ExodusII file
-//! \param[in] id Node id whose coordinates to read
-//! \param[in,out] coord Array of x, y, and z coordinates
-// *****************************************************************************
-{
-  readNode( id, coord[0], coord[1], coord[2] );
-}
-
-void
-ExodusIIMeshReader::readNode( std::size_t id,
-                              tk::real& x,
-                              tk::real& y,
-                              tk::real& z ) const
-// *****************************************************************************
-// Read coordinates of a single mesh node from file
-//! \param[in] id Node id whose coordinates to read
-//! \param[in,out] x X coordinate to write to
-//! \param[in,out] y Y coordinate to write to
-//! \param[in,out] z Z coordinate to write to
-// *****************************************************************************
-{
-  ErrChk(
-    ex_get_partial_coord( m_inFile, static_cast<int64_t>(id)+1, 1,
-                          &x, &y, &z ) == 0,
-    "Failed to read coordinates of node " + std::to_string(id) +
-    " from ExodusII file: " + m_filename );
-}
-
-std::array< std::vector< tk::real >, 3 >
-ExodusIIMeshReader::readNodes( const std::vector< std::size_t >& gid ) const
-// *****************************************************************************
-//  Read coordinates of a number of mesh nodes from ExodusII file
-//! \param[in] gid Node IDs whose coordinates to read
-//! \return Mesh node coordinates
-// *****************************************************************************
-{
-  std::vector< tk::real > px( gid.size() ), py( gid.size() ), pz( gid.size() );
-
-  std::size_t i=0;
-  for (auto g : gid) readNode( g, i++, px, py, pz );
-
-  return {{ std::move(px), std::move(py), std::move(pz) }};
-}
-
-std::size_t
-ExodusIIMeshReader::readElemBlockIDs()
-// *****************************************************************************
-//  Read element block IDs from ExodusII file
-//! \return Total number of nodes in mesh
-// *****************************************************************************
-{
-  // Read ExodusII file header
-  auto nnode = readHeader();<--- Variable 'nnode' is assigned a value that is never used.
-
-  std::vector< int > bid( m_neblk );
-
-  // Read element block ids
-  ErrChk( ex_get_ids( m_inFile, EX_ELEM_BLOCK, bid.data()) == 0,
-          "Failed to read element block ids from ExodusII file: " +
-          m_filename );
-
-  m_elemblocks.clear();
-  m_nel.clear();
-  m_nel.resize( ExoNnpe.size() );
-  m_blockid_by_type.clear();
-  m_blockid_by_type.resize( ExoNnpe.size() );
-
-  // Fill element block ID vector
-  for (auto id : bid) {
-    char eltype[MAX_STR_LENGTH+1];
-    int n, nnpe, nattr;
-
-    // Read element block information
-    ErrChk( ex_get_block( m_inFile, EX_ELEM_BLOCK, id, eltype, &n, &nnpe,
-                          &nattr, nullptr, nullptr ) == 0,
-      "Failed to read element block information from ExodusII file: " +
-      m_filename );
-
-    // Store ExodusII element block ID
-    m_blockid.push_back( id );
-
-    auto nel = static_cast< std::size_t >( n );
-
-    // Store info on ExodusII element blocks
-    if (nnpe == 4) {        // tetrahedra
-
-      m_elemblocks.push_back( { ExoElemType::TET, nel } );
-      auto e = static_cast< std::size_t >( ExoElemType::TET );
-      m_blockid_by_type[ e ].push_back( id );
-      m_nel[ e ].push_back( nel );
-      Assert( m_blockid_by_type[e].size() == m_nel[e].size(), "Size mismatch" );
-
-    } else if (nnpe == 3) { // triangles
-
-      m_elemblocks.push_back( { ExoElemType::TRI, nel } );
-      auto e = static_cast< std::size_t >( ExoElemType::TRI );
-      m_blockid_by_type[ e ].push_back( id );
-      m_nel[ e ].push_back( nel );
-      Assert( m_blockid_by_type[e].size() == m_nel[e].size(), "Size mismatch" );
-
-    }
-  }
-
-  return nnode;
-}
-
-void
-ExodusIIMeshReader::readAllElements( UnsMesh& mesh )
-// *****************************************************************************
-//  Read all element blocks and mesh connectivity from ExodusII file
-//! \param[inout] mesh Unstructured mesh object to store mesh in
-// *****************************************************************************
-{
-  // Read element block ids
-  readElemBlockIDs();
-
-  for (auto id : m_blockid) {
-    char eltype[MAX_STR_LENGTH+1];
-    int nel, nnpe, nattr;
-
-    // Read element block information
-    ErrChk( ex_get_block( m_inFile, EX_ELEM_BLOCK, id, eltype, &nel, &nnpe,
-                          &nattr, nullptr, nullptr ) == 0,
-      "Failed to read element block information from ExodusII file: " +
-      m_filename );
-
-    // Read element connectivity
-    auto connectsize = static_cast< std::size_t >( nel*nnpe );
-    if (nnpe == 4) {    // tetrahedra
-
-      std::vector< int > inpoel( connectsize );
-      ErrChk( ex_get_conn( m_inFile, EX_ELEM_BLOCK, id, inpoel.data(),
-                           nullptr, nullptr ) == 0,
-        "Failed to read " + std::string(eltype) + " element connectivity from "
-        "ExodusII file: " + m_filename );
-      for (auto n : inpoel)
-        mesh.tetinpoel().push_back( static_cast< std::size_t >( n ) );
-
-    } else if (nnpe == 3) {    // triangles
-
-      std::vector< int > inpoel( connectsize );
-      ErrChk( ex_get_conn( m_inFile, EX_ELEM_BLOCK, id, inpoel.data(),
-                           nullptr, nullptr ) == 0,
-        "Failed to read " + std::string(eltype) + " element connectivity from "
-        "ExodusII file: " + m_filename );
-      for (auto n : inpoel)
-        mesh.triinpoel().push_back( static_cast< std::size_t >( n ) );
-
-    }
-  }
-
-  // Shift node IDs to start from zero
-  shiftToZero( mesh.triinpoel() );
-  shiftToZero( mesh.tetinpoel() );
-}
-
-void
-ExodusIIMeshReader::readElements( const std::array< std::size_t, 2 >& ext,
-                                  tk::ExoElemType elemtype,
-                                  std::vector< std::size_t >& conn )
-// *****************************************************************************
-//  Read element connectivity of a number of mesh cells from ExodusII file
-//! \param[in] ext Extents of element IDs whose connectivity to read:
-//!   [from...till), using zero-based element IDs, where 'from' >=0, inclusive
-//!   and 'till < 'maxelements', where 'maxelements' is the total number of
-//!   elements of all element blocks in the file of the requested cell type.
-//!   Note that 'maxelements' can be queried by nelem().
-//! \param[in] elemtype Element type
-//! \param[inout] conn Connectivity vector to push to
-//! \note Must be preceded by a call to readElemBlockIDs()
-//! \details This function takes the extents of element IDs in a zero-based
-//!   fashion. These input extents can be thought of "absolute" extents that
-//!   denote lowest and the largest-1 element IDs to be read from file.
-//!   The mesh block-wise element set is also updated.
-// *****************************************************************************
-{
-  Assert( tk::sumsize(m_blockid_by_type) > 0,
-          "A call to this function must be preceded by a call to "
-          "ExodusIIMeshReader::readElemBlockIDs()" );
-  Assert( ext[0] <= ext[1] &&
-          ext[0] < nelem(elemtype) &&
-          ext[1] < nelem(elemtype),
-          "Invalid element ID extents. Of the requested extents [from...till), "
-          "'from' must be lower than or equal to 'till', and they must be in "
-          "the range [0...maxelements), where 'maxelements' is the total "
-          "number of elements of all element blocks in the file of the "
-          "requested cell type. Requested element ID extents: ["
-          + std::to_string(ext[0]) + "..." + std::to_string(ext[1])
-          + "), 'maxelements' of cell type with "
-          + std::to_string( ExoNnpe[ static_cast<std::size_t>(elemtype) ] )
-          + " nodes per cell in file '" + m_filename + "': "
-          + std::to_string( nelem( elemtype ) ) );
-
-  auto e = static_cast< std::size_t >( elemtype );
-  // List of number of elements of all blocks of element type requested
-  const auto& nel = m_nel[e];
-  // List of element block IDs for element type requested
-  const auto& bid = m_blockid_by_type[e];
-
-  // Compute lower and upper element block ids to read from based on extents
-  std::size_t lo_bid = 0, hi_bid = 0, offset = 0;
-  for (std::size_t b=0; b<nel.size(); ++b) {
-    std::size_t lo = offset;                    // lo (min) elem ID in block
-    std::size_t hi = offset + nel[b] - 1;       // hi (max) elem ID in block
-    if (ext[0] >= lo && ext[0] <= hi) lo_bid = b;
-    if (ext[1] >= lo && ext[1] <= hi) hi_bid = b;
-    offset += nel[b];
-  }
-
-  Assert( lo_bid < nel.size() && lo_bid < bid.size(),
-          "Invalid start block ID" );
-  Assert( hi_bid < nel.size() && hi_bid < bid.size(),
-          "Invalid end block ID" );
-
-  // Compute relative extents based on absolute ones for each block to read from
-  std::vector< std::array< std::size_t, 2 > > rext;
-  offset = 0;
-  for (std::size_t b=0; b<lo_bid; ++b) offset += nel[b];
-  for (std::size_t b=lo_bid; b<=hi_bid; ++b) {
-    std::size_t lo = offset;
-    std::size_t hi = offset + nel[b] - 1;
-    std::size_t le = 1, he = nel[b];
-    if (ext[0] >= lo && ext[0] <= hi) le = ext[0] - lo + 1;
-    if (ext[1] >= lo && ext[1] <= hi) he = ext[1] - lo + 1;
-    Assert( le >= 1 && le <= nel[b] && he >= 1 && he <= nel[b],
-            "Relative index out of block" );
-    rext.push_back( {{ le, he }} );
-    offset += nel[b];
-  }
-
-  Assert( std::accumulate(
-            std::next(rext.cbegin()), rext.cend(), rext[0][1]-rext[0][0]+1,
-            []( std::size_t n, const std::array< std::size_t, 2 >& r )
-            { return n + r[1] - r[0] + 1; }
-          ) == ext[1]-ext[0]+1,
-          "Total number of elements to read incorrect, requested extents: " +
-          std::to_string(ext[0]) + " ... " + std::to_string(ext[1]) );
-
-  std::vector< int > inpoel;
-
-  // Read element connectivity from file
-  std::size_t B = 0;
-  for (auto b=lo_bid; b<=hi_bid; ++b, ++B) {
-    const auto& r = rext[B];
-    std::vector< int > c( (r[1]-r[0]+1) * ExoNnpe[e] );
-    ErrChk( ex_get_partial_conn( m_inFile,
-                                 EX_ELEM_BLOCK,
-                                 bid[b],
-                                 static_cast< int64_t >( r[0] ),
-                                 static_cast< int64_t >( r[1]-r[0]+1 ),
-                                 c.data(),
-                                 nullptr,
-                                 nullptr ) == 0,
-            "Failed to read element connectivity of elements [" +
-            std::to_string(r[0]) + "..." + std::to_string(r[1]) +
-            "] from element block " + std::to_string(bid[b]) + " in ExodusII "
-            "file: " + m_filename );
-
-    // Store tet-elements under their respective mesh block ids
-    if (elemtype == ExoElemType::TET) {
-      for (std::size_t i=0; i<c.size()/ExoNnpe[e]; ++i) {
-        auto& tetblk = m_elemInBlockId[static_cast<std::size_t>(bid[b])];
-        tetblk.insert((inpoel.size()/ExoNnpe[e]) + i);
-      }
-    }
-
-    inpoel.reserve( inpoel.size() + c.size() );
-    std::move( begin(c), end(c), std::back_inserter(inpoel) );
-  }
-
-  Assert( inpoel.size() == (ext[1]-ext[0]+1)*ExoNnpe[e],
-          "Failed to read element connectivity of elements [" +
-          std::to_string(ext[0]) + "..." + std::to_string(ext[1]) + ") from "
-          "ExodusII file: " + m_filename );
-
-  // Put in element connectivity using zero-based node indexing
-  for (auto& i : inpoel) --i;
-  conn.reserve( conn.size() + inpoel.size() );
-  std::move( begin(inpoel), end(inpoel), std::back_inserter(conn) );
-}
-
-void
-ExodusIIMeshReader::readFaces( std::vector< std::size_t >& conn )
-// *****************************************************************************
-//  Read face connectivity of a number of boundary faces from ExodusII file
-//! \param[inout] conn Connectivity vector to push to
-//! \details This function reads in the total number of boundary faces,
-//!   also called triangle-elements in the EXO2 file, and their connectivity.
-// *****************************************************************************
-{
-  // Return quietly if no triangle elements in file
-  if (nelem(tk::ExoElemType::TRI) == 0) return;
-
-  // Read triangle boundary-face connectivity (all the triangle element block)
-  readElements( {{0,nelem(tk::ExoElemType::TRI)-1}}, tk::ExoElemType::TRI,
-                conn );
-}
-
-std::vector< std::size_t >
-ExodusIIMeshReader::readNodemap()
-// *****************************************************************************
-//  Read local to global node-ID map from ExodusII file
-//! \return node_map Vector mapping the local Exodus node-IDs to global node-IDs
-//! \details The node-map is required to get the "Exodus-global" node-IDs from
-//!   the "Exodus-internal" node-IDs, which are returned from the exodus APIs.
-//!   The node-IDs in the exodus file are referred to as the "Exodus-global"
-//!   node-IDs or "fileIDs" in Quinoa.
-// *****************************************************************************
-{
-  // Read triangle boundary-face connectivity
-  auto nnode = readElemBlockIDs();
-
-  // Create array to store node-number map
-  std::vector< int > node_map( nnode );
-
-  // Read in the node number map to map the above nodes to the global node-IDs
-  ErrChk( ex_get_id_map( m_inFile, EX_NODE_MAP, node_map.data() ) == 0,
-          "Failed to read node map length from ExodusII file: " );
-
-  std::vector< std::size_t > node_map1( nnode );
-
-  for (std::size_t i=0; i<nnode; ++i)
-  {
-          node_map1[i] = static_cast< std::size_t >(node_map[i]-1);
-  }
-
-  return node_map1;
-}
-
-std::map< int, std::vector< std::size_t > >
-ExodusIIMeshReader::readSidesetNodes()
-// *****************************************************************************
-//  Read node list of all side sets from ExodusII file
-//! \return Node lists mapped to side set ids
-// *****************************************************************************
-{
-  // Read ExodusII file header (fills m_neset)
-  readHeader();
-
-  // Node lists mapped to side set ids
-  std::map< int, std::vector< std::size_t > > side;
-
-  if (m_neset > 0) {
-    // Read all side set ids from file
-    std::vector< int > ids( m_neset );
-    ErrChk( ex_get_ids( m_inFile, EX_SIDE_SET, ids.data() ) == 0,
-            "Failed to read side set ids from ExodusII file: " + m_filename );
-    // Read in node list for all side sets
-    for (auto i : ids) {
-      int nface, nnode;
-      // Read number of faces and number of distribution factors in side set i
-      ErrChk( ex_get_set_param( m_inFile, EX_SIDE_SET, i, &nface, &nnode ) == 0,
-              "Failed to read side set " + std::to_string(i) + " parameters "
-              "from ExodusII file: " + m_filename );
-      // Read number of nodes in side set i (overwrite nnode)
-      ErrChk( ex_get_side_set_node_list_len( m_inFile, i, &nnode ) == 0,
-              "Failed to read side set " + std::to_string(i) + " node list "
-              "length from ExodusII file: " + m_filename );
-      Assert(nnode > 0, "Number of nodes = 0 in side set" + std::to_string(i));
-      std::vector< int > df( static_cast< std::size_t >( nface ) );
-      std::vector< int > nodes( static_cast< std::size_t >( nnode ) );
-      // Read in node list for side set i
-      ErrChk( ex_get_side_set_node_list( m_inFile, i, df.data(), nodes.data() )
-                == 0, "Failed to read node list of side set " +
-                      std::to_string(i) + " from ExodusII file: " +
-                      m_filename );
-      // Make node list unique
-      tk::unique( nodes );
-      // Store 0-based node ID list as std::size_t vector instead of ints
-      auto& list = side[ i ];
-      for (auto n : nodes) list.push_back( static_cast<std::size_t>(n-1) );<--- Consider using std::transform algorithm instead of a raw loop.
-    }
-  }
-
-  return side;
-}
-
-void
-ExodusIIMeshReader::readSidesetFaces(
-  std::map< int, std::vector< std::size_t > >& bface,
-  std::map< int, std::vector< std::size_t > >& faces )
-// *****************************************************************************
-//  Read side sets from ExodusII file
-//! \param[in,out] bface Elem ids of side sets to read into
-//! \param[in,out] faces Elem-relative face ids of tets of side sets
-// *****************************************************************************
-{
-  // Read element block ids
-  readElemBlockIDs();
-
-  if (m_neset > 0) {
-    // Read side set ids from file
-    std::vector< int > ids( m_neset );
-    ErrChk( ex_get_ids( m_inFile, EX_SIDE_SET, ids.data() ) == 0,
-            "Failed to read side set ids from ExodusII file: " + m_filename );
-
-    // Read all side sets from file
-    for (auto i : ids) {
-      int nface, nnode;
-
-      // Read number of faces in side set
-      ErrChk( ex_get_set_param( m_inFile, EX_SIDE_SET, i, &nface, &nnode ) == 0,
-              "Failed to read side set " + std::to_string(i) + " parameters "
-              "from ExodusII file: " + m_filename );
-
-      Assert(nface > 0, "Number of faces = 0 in side set" + std::to_string(i));
-
-      std::vector< int > exoelem( static_cast< std::size_t >( nface ) );
-      std::vector< int > exoface( static_cast< std::size_t >( nface ) );
-
-      // Read in file-internal element ids and relative face ids for side set
-      ErrChk( ex_get_set( m_inFile, EX_SIDE_SET, i, exoelem.data(),
-                          exoface.data() ) == 0,
-              "Failed to read side set " + std::to_string(i) );
-
-      // Store file-internal element ids of side set
-      auto& elem = bface[i];
-      elem.resize( exoelem.size() );
-      std::size_t j = 0;
-      for (auto e : exoelem) elem[j++] = static_cast< std::size_t >( e-1 );
-
-      // Store zero-based relative face ids of side set
-      auto& face = faces[i];
-      face.resize( exoface.size() );
-      j = 0;
-      for (auto n : exoface) face[j++] = static_cast< std::size_t >( n-1 );
-
-      Assert( std::all_of( begin(face), end(face),
-                           [](std::size_t f){ return f<4; } ),
-              "Relative face id of side set must be between 0 and 3" );
-      Assert( elem.size() == face.size(), "Size mismatch" );
-    }
-  }
-}
-
-std::pair< tk::ExoElemType, std::size_t >
-ExodusIIMeshReader::blkRelElemId( std::size_t id ) const
-// *****************************************************************************
-// Compute element-block-relative element id and element type
-//! \param[in] id (ExodusII) file-internal element id
-//! \return Element type the internal id points to and element id relative to
-//!   cell-type
-//! \details This function takes an internal element id, which in general can
-//!   point to any element block in the ExodusII file and thus we do not know
-//!   which element type a block contains. It then computes which cell type the
-//!   id points to and computes the relative index for the given cell type. This
-//!   is necessary because elements are read in from file by from potentially
-//!   multiple blocks by cell type.
-//! \note Must be preceded by a call to readElemBlockIDs()
-// *****************************************************************************
-{
-  auto TRI = tk::ExoElemType::TRI;
-  auto TET = tk::ExoElemType::TET;
-
-  std::size_t e = 0;            // counts elements (independent of cell type)
-  std::size_t ntri = 0;         // counts triangle elements
-  std::size_t ntet = 0;         // counts tetrahedron elements
-
-  for (const auto& b : m_elemblocks) {  // walk all element blocks in order
-    e += b.second;                      // increment file-internal element id
-    if (e > id) {                       // found element block for internal id
-      if (b.first == TRI) {             // if triangle block
-        return { TRI, id-ntet };        // return cell type and triangle id
-      } else if (b.first == TET) {      // if tetrahedron block
-        return { TET, id-ntri };        // return cell type and tetrahedron id
-      }
-    }
-    // increment triangle and tetrahedron elements independently
-    if (b.first == TRI)
-      ntri += b.second;
-    else if (b.first == TET)
-      ntet += b.second;
-  }
-
-  Throw( " Exodus internal element id not found" );
-}
-
-std::vector< std::size_t >
-ExodusIIMeshReader::triinpoel(
-  std::map< int, std::vector< std::size_t > >& belem,
-  const std::map< int, std::vector< std::size_t > >& faces,
-  const std::vector< std::size_t >& ginpoel,
-  const std::vector< std::size_t >& triinp ) const
-// *****************************************************************************
-//  Generate triangle face connectivity for side sets
-//! \param[in,out] belem File-internal elem ids of side sets
-//! \param[in] faces Elem-relative face ids of side sets
-//! \param[in] ginpoel Tetrahedron element connectivity with global nodes
-//! \param[in] triinp Triangle element connectivity with global nodes
-//!   (if exists in file)
-//! \return Triangle face connectivity with global node IDs of side sets
-//! \details This function takes lists of file-internal element ids (in belem)
-//!   for side sets and does two things: (1) generates face connectivity (with
-//!   global node IDs) for side sets, and (2) converts the (ExodusII)
-//!   file-internal element IDs to face ids so that they can be used to index
-//!   into the face connectivity. The IDs in belem are modified and the face
-//!   connectivity (for boundary faces only) is returned.
-//! \note Must be preceded by a call to readElemBlockIDs()
-// *****************************************************************************
-{
-  Assert( !(m_from == 0 && m_till == 0),
-          "Lower and upper tetrahedron id bounds must not both be zero" );
-
-  // This will contain one of our final results: face (triangle) connectivity
-  // for the side sets only. The difference between bnd_triinpoel and triinpoel
-  // is that triinpoel is a triangle element connectivity, independent of side
-  // sets, while bnd_triinpoel is a triangle connectivity only for side sets.
-  std::vector< std::size_t > bnd_triinpoel;
-
-  // Storage for boundary face lists for each side set on this PE
-  std::map< int, std::vector< std::size_t > > belem_own;
-
-  std::size_t f = 0;            // counts all faces
-  for (auto& ss : belem) {      // for all side sets
-
-    // insert side set id into new map
-    auto& b = belem_own[ ss.first ];
-    // get element-relative face ids for side set
-    const auto& face = tk::cref_find( faces, ss.first );
-    std::size_t s = 0;          // counts side set faces
-    for (auto& i : ss.second) { // for all faces on side set
-
-      // compute element-block-relative element id and element type
-      auto r = blkRelElemId( i );
-
-      // extract boundary face connectivity based on element type
-      bool localface = false;
-      if (r.first == tk::ExoElemType::TRI) {
-
-        auto t = m_tri.find(r.second);
-        if (t != end(m_tri)) {  // only if triangle id exists on this PE
-          Assert( t->second < triinp.size()/3,
-                  "Indexing out of triangle connectivity" );
-          // generate triangle (face) connectivity using global node ids
-          bnd_triinpoel.push_back( triinp[ t->second*3 + 0 ] );
-          bnd_triinpoel.push_back( triinp[ t->second*3 + 1 ] );
-          bnd_triinpoel.push_back( triinp[ t->second*3 + 2 ] );
-          localface = true;
-        }
-
-      } else if (r.first == tk::ExoElemType::TET) {
-
-        if (r.second >= m_from && r.second < m_till) {  // if tet is on this PE
-          auto t = r.second - m_from;
-          Assert( t < ginpoel.size()/4,
-                  "Indexing out of tetrahedron connectivity" );
-          // get ExodusII face-node numbering for side sets, see ExodusII
-          // manual figure on "Sideset side Numbering"
-          const auto& tri = tk::expofa[ face[s] ];
-          // generate triangle (face) connectivity using global node ids, note
-          // the switched node order, 0,2,1, as lpofa is different from expofa
-          bnd_triinpoel.push_back( ginpoel[ t*4 + tri[0] ] );
-          bnd_triinpoel.push_back( ginpoel[ t*4 + tri[1] ] );
-          bnd_triinpoel.push_back( ginpoel[ t*4 + tri[2] ] );
-          localface = true;
-        }
-
-      }
-
-      ++s;
-
-      // generate PE-local face id for side set (this is to be used to index
-      // into triinpoel)
-      if (localface) b.push_back( f++ );
-    }
-
-    // if no faces on this side set (on this PE), remove side set id
-    if (b.empty()) belem_own.erase( ss.first );
-  }
-
-  belem = std::move(belem_own);
-
-  return bnd_triinpoel;
-}
-
-void
-ExodusIIMeshReader::readNodeVarNames( std::vector< std::string >& nv ) const
-// *****************************************************************************
-//  Read the names of nodal output variables from ExodusII file
-//! \param[in,out] nv Nodal variable names
-// *****************************************************************************
-{
-  #if defined(__clang__)
-    #pragma clang diagnostic push
-    #pragma clang diagnostic ignored "-Wvla"
-    #pragma clang diagnostic ignored "-Wvla-extension"
-  #elif defined(STRICT_GNUC)
-    #pragma GCC diagnostic push
-    #pragma GCC diagnostic ignored "-Wvla"
-  #endif
-
-  int numvars = 0;
-
-  ErrChk(
-    ex_get_variable_param( m_inFile, EX_NODE_BLOCK, &numvars ) == 0,
-    "Failed to read nodal output variable parameters from ExodusII file: " +
-    m_filename );
-
-  if (numvars) {
-
-    char* names[ static_cast< std::size_t >( numvars ) ];
-    for (int i=0; i<numvars; ++i)
-      names[i] = static_cast<char*>( calloc((MAX_STR_LENGTH+1), sizeof(char)) );
-
-    ErrChk( ex_get_variable_names( m_inFile,
-                                   EX_NODAL,
-                                   numvars,
-                                   names ) == 0,
-            "Failed to read nodal variable names from ExodusII file: " +
-            m_filename );
-
-    nv.resize( static_cast< std::size_t >( numvars ) );
-    std::size_t i = 0;
-    for (auto& n : nv) n = names[ i++ ];<--- Consider using std::fill or std::generate algorithm instead of a raw loop.
-
-  }
-
-  #if defined(__clang__)
-    #pragma clang diagnostic pop
-  #elif defined(STRICT_GNUC)
-    #pragma GCC diagnostic pop
-  #endif
-}
-
-void
-ExodusIIMeshReader::readElemVarNames( std::vector< std::string >& ev ) const
-// *****************************************************************************
-//  Read the names of elemental output variables from ExodusII file
-//! \param[in,out] ev Elemental variable names
-// *****************************************************************************
-{
-  #if defined(__clang__)
-    #pragma clang diagnostic push
-    #pragma clang diagnostic ignored "-Wvla"
-    #pragma clang diagnostic ignored "-Wvla-extension"
-  #elif defined(STRICT_GNUC)
-    #pragma GCC diagnostic push
-    #pragma GCC diagnostic ignored "-Wvla"
-  #endif
-
-  int numvars = 0;
-
-  ErrChk(
-    ex_get_variable_param( m_inFile, EX_ELEM_BLOCK, &numvars ) == 0,
-    "Failed to read element output variable parameters from ExodusII file: " +
-    m_filename );
-
-  if (numvars) {
-
-    char* names[ static_cast< std::size_t >( numvars ) ];
-    for (int i=0; i<numvars; ++i)
-      names[i] = static_cast<char*>( calloc((MAX_STR_LENGTH+1), sizeof(char)) );
-
-    ErrChk( ex_get_variable_names( m_inFile,
-                                   EX_ELEM_BLOCK,
-                                   numvars,
-                                   names ) == 0,
-            "Failed to read element variable names from ExodusII file: " +
-            m_filename );
-
-    ev.resize( static_cast< std::size_t >( numvars ) );
-    std::size_t i = 0;
-    for (auto& n : ev) n = names[ i++ ];<--- Consider using std::fill or std::generate algorithm instead of a raw loop.
-
-  }
-
-  #if defined(__clang__)
-    #pragma clang diagnostic pop
-  #elif defined(STRICT_GNUC)
-    #pragma GCC diagnostic pop
-  #endif
-}
-
-void
-ExodusIIMeshReader::readTimeValues( std::vector< tk::real >& tv ) const
-// *****************************************************************************
-//  Read time values from ExodusII file
-//! \param[in] tv Vector of time values at which field data is saved
-// *****************************************************************************
-{
-  auto num_time_steps =
-    static_cast< std::size_t >( ex_inquire_int( m_inFile, EX_INQ_TIME ) );
-
-  if (num_time_steps) {
-    tv.resize( num_time_steps, 0.0 );
-    ErrChk( ex_get_all_times( m_inFile, tv.data() ) == 0,
-             "Failed to read time values from ExodusII file: " + m_filename );
-  }
-}
-
-void
-ExodusIIMeshReader::readNodeScalars(
-  std::size_t ntime,
-  std::size_t nvar,
-  std::vector< std::vector< std::vector< tk::real > > >& var ) const
-// *****************************************************************************
-//  Read node scalar fields from ExodusII file
-//! \param[in] ntime Number of time steps to read
-//! \param[in] nvar Number of variables to read
-//! \param[in] var Vector of nodal variables to read to: inner vector: nodes,
-//!   middle vector: (physics) variable, outer vector: time step
-// *****************************************************************************
-{
-  var.resize( ntime );
-  for (auto& v : var) {
-    v.resize( nvar );
-    for (auto& n : v) n.resize( m_nnode );
-  }
-
-  for (std::size_t t=0; t<var.size(); ++t) {
-    for (std::size_t id=0; id<var[t].size(); ++id) {
-      ErrChk( ex_get_var( m_inFile,
-                          static_cast< int >( t+1 ),
-                          EX_NODAL,
-                          static_cast< int >( id+1 ),
-                          1,
-                          static_cast< int64_t >( var[t][id].size() ),
-                          var[t][id].data() ) == 0,
-              "Failed to read node scalar from ExodusII file: " + m_filename );
-    }
-  }
-}
-
-void
-ExodusIIMeshReader::readElemScalars(
-  std::size_t ntime,
-  std::size_t nvar,
-  std::vector< std::vector< std::vector< tk::real > > >& var ) const
-// *****************************************************************************
-//  Read element scalar fields from ExodusII file
-//! \param[in] ntime Number of time steps to read
-//! \param[in] nvar Number of variables to read
-//! \param[in] var Vector of elemental variables to read to: inner vector:
-//!   elements, middle vector: (physics) variable, outer vector: time step
-// *****************************************************************************
-{
-  var.resize( ntime );
-  for (auto& v : var) {
-    v.resize( nvar );
-    for (auto& n : v) n.resize( m_nelem );
-  }
-
-  for (std::size_t t=0; t<var.size(); ++t) {
-    for (std::size_t id=0; id<var[t].size(); ++id) {
-      ErrChk( ex_get_var( m_inFile,
-                          static_cast< int >( t+1 ),
-                          EX_ELEM_BLOCK,
-                          static_cast< int >( id+1 ),
-                          1,
-                          static_cast< int64_t >( var[t][id].size() ),
-                          var[t][id].data() ) == 0,
-              "Failed to read element scalar from ExodusII file: " +
-              m_filename );
-    }
-  }
-}
-
-std::size_t
-ExodusIIMeshReader::nelem( tk::ExoElemType elemtype ) const
-// *****************************************************************************
-//  Return number of elements in all mesh blocks for a given elem type in file
-//! \param[in] elemtype Element type
-//! \return Number of elements in all blocks for the elem type
-//! \note Must be preceded by a call to readElemBlockIDs()
-// *****************************************************************************
-{
-  auto e = static_cast< std::size_t >( elemtype );
-  return std::accumulate( m_nel[e].cbegin(), m_nel[e].cend(), 0u );
-}
+    //! Access the number of scalar components per non-zero matrix entry
+    std::size_t Ncomp() const { return ncomp; }
+
+    //! Write out CSR as stored
+    std::ostream& write_stored( std::ostream &os ) const;
+    //! Write out CSR nonzero structure
+    std::ostream& write_structure( std::ostream &os ) const;
+    //! Write out CSR contribute structure
+    std::ostream& write_contribute( std::ostream &os ) const;
+    //! Write out CSR as a real matrix
+    std::ostream& write_matrix( std::ostream &os ) const;
+    //! Write out CSR in Matlab/Octave format
+    std::ostream& write_matlab( std::ostream &os ) const;
+
+    /** @name Pack/unpack (Charm++ serialization) routines */
+    ///@{
+    //! \brief Pack/Unpack serialize member function
+    //! \param[in,out] p Charm++'s PUP::er serializer object reference
+    void pup( PUP::er &p ) {<--- Parameter 'p' can be declared with const
+      p | ncomp;
+      p | rnz;
+      p | ia;
+      p | ja;
+      p | a;
+    }
+    //! \brief Pack/Unpack serialize operator|
+    //! \param[in,out] p Charm++'s PUP::er serializer object reference
+    //! \param[in,out] c CSR object reference
+    friend void operator|( PUP::er& p, CSR& c ) { c.pup(p); }
+    ///@}
+
+  private:
+    std::size_t ncomp;                  //!< Number of scalars per non-zero
+    std::vector< std::size_t > rnz;     //!< Number of nonzeros in each row
+    std::vector< std::size_t > ia;      //!< Row pointers
+    std::vector< std::size_t > ja;      //!< Column indices
+    std::vector< real > a;              //!< Nonzero matrix values
+};
+
+} // tk::
+
+#endif // CSR_h
 
diff --git a/Release/cppcheck/2.html b/Release/cppcheck/2.html index 710a78e5c836..cfebe6f3a78b 100644 --- a/Release/cppcheck/2.html +++ b/Release/cppcheck/2.html @@ -152,12 +152,12 @@
  1
@@ -291,238 +291,138 @@ 

Cppcheck report - [

// *****************************************************************************
+132
// *****************************************************************************
 /*!
-  \file      src/IO/Omega_h_MeshReader.cpp
+  \file      src/IO/UGRIDMeshReader.cpp
   \copyright 2012-2015 J. Bakosi,
              2016-2018 Los Alamos National Security, LLC.,
              2019-2021 Triad National Security, LLC.
              All rights reserved. See the LICENSE file for details.
-  \brief     Omega_h mesh reader
-  \details   Omega_h mesh reader class definition.
-*/
-// *****************************************************************************
-
-#include "NoWarning/Omega_h_file.hpp"
-#include <Omega_h_library.hpp>
-
-#include "Macro.hpp"
-#include "Omega_h_MeshReader.hpp"
-#include "Reorder.hpp"
-
-using tk::Omega_h_MeshReader;
-
-void
-Omega_h_MeshReader::readMeshPart(
-  std::vector< std::size_t >& ginpoel,
-  std::vector< std::size_t >& inpoel,
-  [[maybe_unused]] std::vector< std::size_t >& triinp,
-  std::unordered_map< std::size_t, std::size_t >& lid,
-  tk::UnsMesh::Coords& coord,
-  std::unordered_map< std::size_t, std::set< std::size_t > >&,
-  int numpes,
-  [[maybe_unused]] int mype )
-// *****************************************************************************
-//  Read a part of the mesh (graph and coordinates) from Omega_h file
-//! \param[in,out] ginpoel Container to store element connectivity of this PE's
-//!   chunk of the mesh (global ids)
-//! \param[in,out] inpoel Container to store element connectivity with local
-//!   node IDs of this PE's mesh chunk
-//! \param[in,out] triinp Container to store triangle element connectivity
-//!   (if exists in file) with global node indices
-//! \param[in,out] lid Container to store global->local node IDs of elements of
-//!   this PE's mesh chunk
-//! \param[in,out] coord Container to store coordinates of mesh nodes of this
-//!   PE's mesh chunk
-//! \param[in] numpes Total number of PEs (default n = 1, for a single-CPU read)
-//! \param[in] mype This PE (default m = 0, for a single-CPU read)
-//! \note The last two integer arguments are unused. They are needed because
-//!   this function can be used via a polymorphic interface via a base class,
-//!   see tk::MeshReader, and other specialized mesh readers, e.g.,
-//!   tk::ExodusIIMeshReader, use these arguments. Here we require the Omega_h
-//!   input mesh to be pre-partitioned, with Omega_h's osh_part tool, into the
-//!   number of partitions that is equal to the number of PEs this fuinction is
-//!   called on in parallel.
-// *****************************************************************************
-{
-  Assert( mype < numpes, "Invalid input: PE id must be lower than NumPEs" );
-  Assert( ginpoel.empty() && inpoel.empty() && lid.empty() &&
-          coord[0].empty() && coord[1].empty() && coord[2].empty(),
-          "Containers to store mesh must be empty" );
-
-  #if defined(__clang__)
-    #pragma clang diagnostic push
-    #pragma clang diagnostic ignored "-Wold-style-cast"
-  #endif
-
-  // Create Omega_h library instance
-  auto lib = Omega_h::Library( nullptr, nullptr, MPI_COMM_WORLD );
-
-  #if defined(__clang__)
-    #pragma clang diagnostic pop
-  #endif
-
-  // Find out how many partitions the Omega_h mesh was saved with
-  auto nparts = Omega_h::binary::read_nparts( m_filename, lib.world() );
-
-  if (numpes < nparts)
-    Throw( "The Omega_h mesh reader only supports NumPEs >= nparts, where "
-           "nparts is the number of partitions the mesh is partitioned into. "
-           "Also note that NumPEs must be a power of 2 if NumPEs > nparts." );
-
-  // Read mesh
-  auto mesh = Omega_h::binary::read( m_filename, &lib );
-
-  // Lambda to check if int is a power of two
-  auto isPowerOfTwo = []( int x ) { return (x != 0) && ((x & (x - 1)) == 0); };
-
-  if (nparts != numpes) {
-    if (!isPowerOfTwo(numpes))
-      Throw( "The Omega_h mesh reader only supports NumPEs of power of 2" );
-    else
-      mesh.balance();
-  }
-
-  // Extract connectivity from Omega_h's mesh object
-  auto ntets = mesh.nelems();
-  ginpoel.resize( static_cast< std::size_t >( ntets ) * 4 );
-  auto o_inpoel = mesh.ask_elem_verts();
-  auto o_gid = mesh.globals( Omega_h::VERT );
-  for (int i=0; i<ntets; ++i)
-    for (int j=0; j<4; ++j) {
-      auto I = static_cast< std::size_t >( i );
-      auto J = static_cast< std::size_t >( j );
-      ginpoel[ I*4+J ] = static_cast<std::size_t>( o_gid[ o_inpoel[i*4+j] ] );
-    }
-
-  // Extract node coordinates from Omega_h's mesh object
-  auto o_coord = mesh.coords();
-
-  // Extract number of vertices from Omega_h's mesh object
-  auto nnode = static_cast< std::size_t >( mesh.nverts() );
+  \brief     UGRID mesh reader class declaration
+  \details   UGRID mesh reader class declaration. Mesh reader facilitating
+             reading a mesh from a simple text file used by NASA.
+  \see       http://www.simcenter.msstate.edu/software/downloads/doc/ug_io/3d_grid_file_type_ugrid.html, http://www.simcenter.msstate.edu/software/downloads/doc/aflr3/aflr3_io_summary.html
+*/
+// *****************************************************************************
+
+#include <array>
+#include <istream>
+#include <string>
+#include <vector>
+#include <cstddef>
+
+#include "Types.hpp"
+#include "Exception.hpp"
+#include "UnsMesh.hpp"
+#include "Reorder.hpp"
+#include "UGRIDMeshReader.hpp"
+
+using tk::UGRIDMeshReader;
+
+void
+UGRIDMeshReader::readHeader()
+// *****************************************************************************
+//  Read UGRID mesh header
+// *****************************************************************************
+{
+  std::string s;<--- Unused variable: s
+
+  // Number_of_Nodes
+  m_inFile >> m_nnode;
+
+  // Number_of_Surf_Trias
+  m_inFile >> m_ntri;
+
+  // Number_of_Surf_Quads
+  int nquad;
+  m_inFile >> nquad;
+
+  // Number_of_Vol_Tets
+  m_inFile >> m_ntet;
+
+  // Number_of_Vol_Pents_5
+  int pent5;
+  m_inFile >> pent5;
+
+  // Number_of_Vol_Pents_6
+  int pent6;
+  m_inFile >> pent6;
+
+  // Number_of_Vol_Hexs
+  int nhex;
+  m_inFile >> nhex;
+}
+
+void
+UGRIDMeshReader::readMesh( UnsMesh& mesh )
+// *****************************************************************************
+//  Read UGRID mesh
+//! \param[in] mesh Unstructured mesh object
+// *****************************************************************************
+{
+  // Read header
+  readHeader();
+  // Read nodes
+  readNodes( mesh );
+  // Read elements
+  readElements( mesh );
+}
+
+void
+UGRIDMeshReader::readNodes( UnsMesh& mesh )
+// *****************************************************************************
+//  Read nodes
+//! \param[in] mesh Unstructured mesh object
+// *****************************************************************************
+{
+  // Read in node coordinates: x-coord y-coord z-coord
+  for (std::size_t i=0; i<m_nnode; ++i) {
+    tk::real x, y, z;
+    m_inFile >> x >> y >> z;
+    mesh.x().push_back( x );
+    mesh.y().push_back( y );
+    mesh.z().push_back( z );
+  }
+}
+
+void
+UGRIDMeshReader::readElements( UnsMesh& mesh )
+// *****************************************************************************
+//  Read element connectivity
+//! \param[in] mesh Unstructured mesh object
+// *****************************************************************************
+{
+  // Read in triangle element connectivity
+  for (std::size_t i=0; i<m_ntri; ++i) {
+    std::array< std::size_t, 3 > n;
+    m_inFile >> n[0] >> n[1] >> n[2];
+    mesh.triinpoel().push_back( n[0] );
+    mesh.triinpoel().push_back( n[1] );
+    mesh.triinpoel().push_back( n[2] );
+  }
 
-  // Extract node coordinates from Omega_h's mesh object
-  auto& x = coord[0];
-  auto& y = coord[1];
-  auto& z = coord[2];
-  x.resize( nnode );
-  y.resize( nnode );
-  z.resize( nnode );
+  // Read side sets of triangle elements
+  for (std::size_t i=0; i<m_ntri; ++i) {
+    int setid;
+    m_inFile >> setid;
+    mesh.bface()[ setid ].push_back( m_ntet + i );
+    mesh.faceid()[ setid ].push_back( 0 );
+  }
 
-  for (std::size_t I=0; I<nnode; ++I) {
-    auto i = static_cast< int >( I );
-    x[I] = o_coord[ i*3+0 ];
-    y[I] = o_coord[ i*3+1 ];
-    z[I] = o_coord[ i*3+2 ];
-  }
-
-  // Compute local data from global mesh connectivity
-  std::vector< std::size_t > gid;
-  std::tie( inpoel, gid, lid ) = tk::global2local( ginpoel );
-}
-
-
-std::vector< std::size_t >
-Omega_h_MeshReader::triinpoel(
-  [[maybe_unused]] std::map< int, std::vector< std::size_t > >& bface,<--- Parameter 'bface' can be declared with const
-  [[maybe_unused]] const std::map< int, std::vector< std::size_t > >& faces,
-  [[maybe_unused]] const std::vector< std::size_t >& ginpoel,
-  [[maybe_unused]] const std::vector< std::size_t >& triinp ) const
-// *****************************************************************************
-// ...
-//! \note Must be preceded by a call to readElemBlockIDs()
-// *****************************************************************************
-{
-  std::vector< std::size_t > bnd_triinpoel;
-  return bnd_triinpoel;
-}
-
-void
-Omega_h_MeshReader::readSidesetFaces(
-  [[maybe_unused]] std::map< int, std::vector< std::size_t > >& bface,<--- Parameter 'bface' can be declared with const
-  [[maybe_unused]] std::map< int, std::vector< std::size_t > >& faces )<--- Parameter 'faces' can be declared with const
-// *****************************************************************************
-//  Read side sets from Omega_h file
-//! \param[in,out] bface Elem ids of side sets to read into
-//! \param[in,out] faces Elem-relative face ids of tets of side sets
-// *****************************************************************************
-{
-}
-
-void
-Omega_h_MeshReader::readFaces(
-  [[maybe_unused]] std::vector< std::size_t >& conn )
-// *****************************************************************************
-//  Read face connectivity of a number of boundary faces from Omega_h file
-//! \param[in,out] conn Connectivity vector to push to
-//! \details This function reads in the total number of boundary faces,
-//!   also called triangle-elements, and their connectivity.
-// *****************************************************************************
-{
-}
-
-std::map< int, std::vector< std::size_t > >
-Omega_h_MeshReader::readSidesetNodes()
-// *****************************************************************************
-//  Read node list of all side sets from Omega_h file
-//! \return Node lists mapped to side set ids
-// *****************************************************************************
-{
-  // Node lists mapped to side set ids
-  std::map< int, std::vector< std::size_t > > side;
-
-  return side;
-}
+  // Read in tetrahedra element connectivity
+  for (std::size_t i=0; i<m_ntet; ++i) {
+    std::array< std::size_t, 4 > n;
+    m_inFile >> n[0] >> n[1] >> n[2] >> n[3];
+    mesh.tetinpoel().push_back( n[0] );
+    mesh.tetinpoel().push_back( n[1] );
+    mesh.tetinpoel().push_back( n[2] );
+    mesh.tetinpoel().push_back( n[3] );
+  }
+
+  // Shift node IDs to start from zero
+  shiftToZero( mesh.triinpoel() );
+  shiftToZero( mesh.tetinpoel() );
+}
 
diff --git a/Release/cppcheck/22.html b/Release/cppcheck/22.html index 75dcc710ccc1..8ba2c5638ad9 100644 --- a/Release/cppcheck/22.html +++ b/Release/cppcheck/22.html @@ -152,269 +152,3237 @@
- - + @@ -73,11 +73,11 @@ - + - +
  1
-  2
-  3
-  4
-  5
-  6
-  7
-  8
-  9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
- 37
- 38
- 39
- 40
- 41
- 42
- 43
- 44
- 45
- 46
- 47
- 48
- 49
- 50
- 51
- 52
- 53
- 54
- 55
- 56
- 57
- 58
- 59
- 60
- 61
- 62
- 63
- 64
- 65
- 66
- 67
- 68
- 69
- 70
- 71
- 72
- 73
- 74
- 75
- 76
- 77
- 78
- 79
- 80
- 81
- 82
- 83
- 84
- 85
- 86
- 87
- 88
- 89
- 90
- 91
- 92
- 93
- 94
- 95
- 96
- 97
- 98
- 99
-100
-101
-102
-103
-104
-105
-106
-107
-108
-109
-110
-111
-112
-113
-114
-115
-116
-117
-118
-119
-120
-121
-122
-123
-124
-125
-126
-127
-128
// *****************************************************************************
-/*!
-  \file      src/Control/HelpFactory.hpp
-  \copyright 2012-2015 J. Bakosi,
-             2016-2018 Los Alamos National Security, LLC.,
-             2019-2021 Triad National Security, LLC.
-             All rights reserved. See the LICENSE file for details.
-  \brief     Command-line and input deck help factory
-  \details   This file contains some types that facilitate the generation of
-     on-screen help.
-*/
-// *****************************************************************************
-#ifndef HelpFactory_h
-#define HelpFactory_h
-
-#include <brigand/sequences/list.hpp>
-#include <brigand/algorithms/for_each.hpp>
-
-#include "PUPUtil.hpp"
-#include "Factory.hpp"
-#include "Has.hpp"
-#include "Types.hpp"
+
   1
+   2
+   3
+   4
+   5
+   6
+   7
+   8
+   9
+  10
+  11
+  12
+  13
+  14
+  15
+  16
+  17
+  18
+  19
+  20
+  21
+  22
+  23
+  24
+  25
+  26
+  27
+  28
+  29
+  30
+  31
+  32
+  33
+  34
+  35
+  36
+  37
+  38
+  39
+  40
+  41
+  42
+  43
+  44
+  45
+  46
+  47
+  48
+  49
+  50
+  51
+  52
+  53
+  54
+  55
+  56
+  57
+  58
+  59
+  60
+  61
+  62
+  63
+  64
+  65
+  66
+  67
+  68
+  69
+  70
+  71
+  72
+  73
+  74
+  75
+  76
+  77
+  78
+  79
+  80
+  81
+  82
+  83
+  84
+  85
+  86
+  87
+  88
+  89
+  90
+  91
+  92
+  93
+  94
+  95
+  96
+  97
+  98
+  99
+ 100
+ 101
+ 102
+ 103
+ 104
+ 105
+ 106
+ 107
+ 108
+ 109
+ 110
+ 111
+ 112
+ 113
+ 114
+ 115
+ 116
+ 117
+ 118
+ 119
+ 120
+ 121
+ 122
+ 123
+ 124
+ 125
+ 126
+ 127
+ 128
+ 129
+ 130
+ 131
+ 132
+ 133
+ 134
+ 135
+ 136
+ 137
+ 138
+ 139
+ 140
+ 141
+ 142
+ 143
+ 144
+ 145
+ 146
+ 147
+ 148
+ 149
+ 150
+ 151
+ 152
+ 153
+ 154
+ 155
+ 156
+ 157
+ 158
+ 159
+ 160
+ 161
+ 162
+ 163
+ 164
+ 165
+ 166
+ 167
+ 168
+ 169
+ 170
+ 171
+ 172
+ 173
+ 174
+ 175
+ 176
+ 177
+ 178
+ 179
+ 180
+ 181
+ 182
+ 183
+ 184
+ 185
+ 186
+ 187
+ 188
+ 189
+ 190
+ 191
+ 192
+ 193
+ 194
+ 195
+ 196
+ 197
+ 198
+ 199
+ 200
+ 201
+ 202
+ 203
+ 204
+ 205
+ 206
+ 207
+ 208
+ 209
+ 210
+ 211
+ 212
+ 213
+ 214
+ 215
+ 216
+ 217
+ 218
+ 219
+ 220
+ 221
+ 222
+ 223
+ 224
+ 225
+ 226
+ 227
+ 228
+ 229
+ 230
+ 231
+ 232
+ 233
+ 234
+ 235
+ 236
+ 237
+ 238
+ 239
+ 240
+ 241
+ 242
+ 243
+ 244
+ 245
+ 246
+ 247
+ 248
+ 249
+ 250
+ 251
+ 252
+ 253
+ 254
+ 255
+ 256
+ 257
+ 258
+ 259
+ 260
+ 261
+ 262
+ 263
+ 264
+ 265
+ 266
+ 267
+ 268
+ 269
+ 270
+ 271
+ 272
+ 273
+ 274
+ 275
+ 276
+ 277
+ 278
+ 279
+ 280
+ 281
+ 282
+ 283
+ 284
+ 285
+ 286
+ 287
+ 288
+ 289
+ 290
+ 291
+ 292
+ 293
+ 294
+ 295
+ 296
+ 297
+ 298
+ 299
+ 300
+ 301
+ 302
+ 303
+ 304
+ 305
+ 306
+ 307
+ 308
+ 309
+ 310
+ 311
+ 312
+ 313
+ 314
+ 315
+ 316
+ 317
+ 318
+ 319
+ 320
+ 321
+ 322
+ 323
+ 324
+ 325
+ 326
+ 327
+ 328
+ 329
+ 330
+ 331
+ 332
+ 333
+ 334
+ 335
+ 336
+ 337
+ 338
+ 339
+ 340
+ 341
+ 342
+ 343
+ 344
+ 345
+ 346
+ 347
+ 348
+ 349
+ 350
+ 351
+ 352
+ 353
+ 354
+ 355
+ 356
+ 357
+ 358
+ 359
+ 360
+ 361
+ 362
+ 363
+ 364
+ 365
+ 366
+ 367
+ 368
+ 369
+ 370
+ 371
+ 372
+ 373
+ 374
+ 375
+ 376
+ 377
+ 378
+ 379
+ 380
+ 381
+ 382
+ 383
+ 384
+ 385
+ 386
+ 387
+ 388
+ 389
+ 390
+ 391
+ 392
+ 393
+ 394
+ 395
+ 396
+ 397
+ 398
+ 399
+ 400
+ 401
+ 402
+ 403
+ 404
+ 405
+ 406
+ 407
+ 408
+ 409
+ 410
+ 411
+ 412
+ 413
+ 414
+ 415
+ 416
+ 417
+ 418
+ 419
+ 420
+ 421
+ 422
+ 423
+ 424
+ 425
+ 426
+ 427
+ 428
+ 429
+ 430
+ 431
+ 432
+ 433
+ 434
+ 435
+ 436
+ 437
+ 438
+ 439
+ 440
+ 441
+ 442
+ 443
+ 444
+ 445
+ 446
+ 447
+ 448
+ 449
+ 450
+ 451
+ 452
+ 453
+ 454
+ 455
+ 456
+ 457
+ 458
+ 459
+ 460
+ 461
+ 462
+ 463
+ 464
+ 465
+ 466
+ 467
+ 468
+ 469
+ 470
+ 471
+ 472
+ 473
+ 474
+ 475
+ 476
+ 477
+ 478
+ 479
+ 480
+ 481
+ 482
+ 483
+ 484
+ 485
+ 486
+ 487
+ 488
+ 489
+ 490
+ 491
+ 492
+ 493
+ 494
+ 495
+ 496
+ 497
+ 498
+ 499
+ 500
+ 501
+ 502
+ 503
+ 504
+ 505
+ 506
+ 507
+ 508
+ 509
+ 510
+ 511
+ 512
+ 513
+ 514
+ 515
+ 516
+ 517
+ 518
+ 519
+ 520
+ 521
+ 522
+ 523
+ 524
+ 525
+ 526
+ 527
+ 528
+ 529
+ 530
+ 531
+ 532
+ 533
+ 534
+ 535
+ 536
+ 537
+ 538
+ 539
+ 540
+ 541
+ 542
+ 543
+ 544
+ 545
+ 546
+ 547
+ 548
+ 549
+ 550
+ 551
+ 552
+ 553
+ 554
+ 555
+ 556
+ 557
+ 558
+ 559
+ 560
+ 561
+ 562
+ 563
+ 564
+ 565
+ 566
+ 567
+ 568
+ 569
+ 570
+ 571
+ 572
+ 573
+ 574
+ 575
+ 576
+ 577
+ 578
+ 579
+ 580
+ 581
+ 582
+ 583
+ 584
+ 585
+ 586
+ 587
+ 588
+ 589
+ 590
+ 591
+ 592
+ 593
+ 594
+ 595
+ 596
+ 597
+ 598
+ 599
+ 600
+ 601
+ 602
+ 603
+ 604
+ 605
+ 606
+ 607
+ 608
+ 609
+ 610
+ 611
+ 612
+ 613
+ 614
+ 615
+ 616
+ 617
+ 618
+ 619
+ 620
+ 621
+ 622
+ 623
+ 624
+ 625
+ 626
+ 627
+ 628
+ 629
+ 630
+ 631
+ 632
+ 633
+ 634
+ 635
+ 636
+ 637
+ 638
+ 639
+ 640
+ 641
+ 642
+ 643
+ 644
+ 645
+ 646
+ 647
+ 648
+ 649
+ 650
+ 651
+ 652
+ 653
+ 654
+ 655
+ 656
+ 657
+ 658
+ 659
+ 660
+ 661
+ 662
+ 663
+ 664
+ 665
+ 666
+ 667
+ 668
+ 669
+ 670
+ 671
+ 672
+ 673
+ 674
+ 675
+ 676
+ 677
+ 678
+ 679
+ 680
+ 681
+ 682
+ 683
+ 684
+ 685
+ 686
+ 687
+ 688
+ 689
+ 690
+ 691
+ 692
+ 693
+ 694
+ 695
+ 696
+ 697
+ 698
+ 699
+ 700
+ 701
+ 702
+ 703
+ 704
+ 705
+ 706
+ 707
+ 708
+ 709
+ 710
+ 711
+ 712
+ 713
+ 714
+ 715
+ 716
+ 717
+ 718
+ 719
+ 720
+ 721
+ 722
+ 723
+ 724
+ 725
+ 726
+ 727
+ 728
+ 729
+ 730
+ 731
+ 732
+ 733
+ 734
+ 735
+ 736
+ 737
+ 738
+ 739
+ 740
+ 741
+ 742
+ 743
+ 744
+ 745
+ 746
+ 747
+ 748
+ 749
+ 750
+ 751
+ 752
+ 753
+ 754
+ 755
+ 756
+ 757
+ 758
+ 759
+ 760
+ 761
+ 762
+ 763
+ 764
+ 765
+ 766
+ 767
+ 768
+ 769
+ 770
+ 771
+ 772
+ 773
+ 774
+ 775
+ 776
+ 777
+ 778
+ 779
+ 780
+ 781
+ 782
+ 783
+ 784
+ 785
+ 786
+ 787
+ 788
+ 789
+ 790
+ 791
+ 792
+ 793
+ 794
+ 795
+ 796
+ 797
+ 798
+ 799
+ 800
+ 801
+ 802
+ 803
+ 804
+ 805
+ 806
+ 807
+ 808
+ 809
+ 810
+ 811
+ 812
+ 813
+ 814
+ 815
+ 816
+ 817
+ 818
+ 819
+ 820
+ 821
+ 822
+ 823
+ 824
+ 825
+ 826
+ 827
+ 828
+ 829
+ 830
+ 831
+ 832
+ 833
+ 834
+ 835
+ 836
+ 837
+ 838
+ 839
+ 840
+ 841
+ 842
+ 843
+ 844
+ 845
+ 846
+ 847
+ 848
+ 849
+ 850
+ 851
+ 852
+ 853
+ 854
+ 855
+ 856
+ 857
+ 858
+ 859
+ 860
+ 861
+ 862
+ 863
+ 864
+ 865
+ 866
+ 867
+ 868
+ 869
+ 870
+ 871
+ 872
+ 873
+ 874
+ 875
+ 876
+ 877
+ 878
+ 879
+ 880
+ 881
+ 882
+ 883
+ 884
+ 885
+ 886
+ 887
+ 888
+ 889
+ 890
+ 891
+ 892
+ 893
+ 894
+ 895
+ 896
+ 897
+ 898
+ 899
+ 900
+ 901
+ 902
+ 903
+ 904
+ 905
+ 906
+ 907
+ 908
+ 909
+ 910
+ 911
+ 912
+ 913
+ 914
+ 915
+ 916
+ 917
+ 918
+ 919
+ 920
+ 921
+ 922
+ 923
+ 924
+ 925
+ 926
+ 927
+ 928
+ 929
+ 930
+ 931
+ 932
+ 933
+ 934
+ 935
+ 936
+ 937
+ 938
+ 939
+ 940
+ 941
+ 942
+ 943
+ 944
+ 945
+ 946
+ 947
+ 948
+ 949
+ 950
+ 951
+ 952
+ 953
+ 954
+ 955
+ 956
+ 957
+ 958
+ 959
+ 960
+ 961
+ 962
+ 963
+ 964
+ 965
+ 966
+ 967
+ 968
+ 969
+ 970
+ 971
+ 972
+ 973
+ 974
+ 975
+ 976
+ 977
+ 978
+ 979
+ 980
+ 981
+ 982
+ 983
+ 984
+ 985
+ 986
+ 987
+ 988
+ 989
+ 990
+ 991
+ 992
+ 993
+ 994
+ 995
+ 996
+ 997
+ 998
+ 999
+1000
+1001
+1002
+1003
+1004
+1005
+1006
+1007
+1008
+1009
+1010
+1011
+1012
+1013
+1014
+1015
+1016
+1017
+1018
+1019
+1020
+1021
+1022
+1023
+1024
+1025
+1026
+1027
+1028
+1029
+1030
+1031
+1032
+1033
+1034
+1035
+1036
+1037
+1038
+1039
+1040
+1041
+1042
+1043
+1044
+1045
+1046
+1047
+1048
+1049
+1050
+1051
+1052
+1053
+1054
+1055
+1056
+1057
+1058
+1059
+1060
+1061
+1062
+1063
+1064
+1065
+1066
+1067
+1068
+1069
+1070
+1071
+1072
+1073
+1074
+1075
+1076
+1077
+1078
+1079
+1080
+1081
+1082
+1083
+1084
+1085
+1086
+1087
+1088
+1089
+1090
+1091
+1092
+1093
+1094
+1095
+1096
+1097
+1098
+1099
+1100
+1101
+1102
+1103
+1104
+1105
+1106
+1107
+1108
+1109
+1110
+1111
+1112
+1113
+1114
+1115
+1116
+1117
+1118
+1119
+1120
+1121
+1122
+1123
+1124
+1125
+1126
+1127
+1128
+1129
+1130
+1131
+1132
+1133
+1134
+1135
+1136
+1137
+1138
+1139
+1140
+1141
+1142
+1143
+1144
+1145
+1146
+1147
+1148
+1149
+1150
+1151
+1152
+1153
+1154
+1155
+1156
+1157
+1158
+1159
+1160
+1161
+1162
+1163
+1164
+1165
+1166
+1167
+1168
+1169
+1170
+1171
+1172
+1173
+1174
+1175
+1176
+1177
+1178
+1179
+1180
+1181
+1182
+1183
+1184
+1185
+1186
+1187
+1188
+1189
+1190
+1191
+1192
+1193
+1194
+1195
+1196
+1197
+1198
+1199
+1200
+1201
+1202
+1203
+1204
+1205
+1206
+1207
+1208
+1209
+1210
+1211
+1212
+1213
+1214
+1215
+1216
+1217
+1218
+1219
+1220
+1221
+1222
+1223
+1224
+1225
+1226
+1227
+1228
+1229
+1230
+1231
+1232
+1233
+1234
+1235
+1236
+1237
+1238
+1239
+1240
+1241
+1242
+1243
+1244
+1245
+1246
+1247
+1248
+1249
+1250
+1251
+1252
+1253
+1254
+1255
+1256
+1257
+1258
+1259
+1260
+1261
+1262
+1263
+1264
+1265
+1266
+1267
+1268
+1269
+1270
+1271
+1272
+1273
+1274
+1275
+1276
+1277
+1278
+1279
+1280
+1281
+1282
+1283
+1284
+1285
+1286
+1287
+1288
+1289
+1290
+1291
+1292
+1293
+1294
+1295
+1296
+1297
+1298
+1299
+1300
+1301
+1302
+1303
+1304
+1305
+1306
+1307
+1308
+1309
+1310
+1311
+1312
+1313
+1314
+1315
+1316
+1317
+1318
+1319
+1320
+1321
+1322
+1323
+1324
+1325
+1326
+1327
+1328
+1329
+1330
+1331
+1332
+1333
+1334
+1335
+1336
+1337
+1338
+1339
+1340
+1341
+1342
+1343
+1344
+1345
+1346
+1347
+1348
+1349
+1350
+1351
+1352
+1353
+1354
+1355
+1356
+1357
+1358
+1359
+1360
+1361
+1362
+1363
+1364
+1365
+1366
+1367
+1368
+1369
+1370
+1371
+1372
+1373
+1374
+1375
+1376
+1377
+1378
+1379
+1380
+1381
+1382
+1383
+1384
+1385
+1386
+1387
+1388
+1389
+1390
+1391
+1392
+1393
+1394
+1395
+1396
+1397
+1398
+1399
+1400
+1401
+1402
+1403
+1404
+1405
+1406
+1407
+1408
+1409
+1410
+1411
+1412
+1413
+1414
+1415
+1416
+1417
+1418
+1419
+1420
+1421
+1422
+1423
+1424
+1425
+1426
+1427
+1428
+1429
+1430
+1431
+1432
+1433
+1434
+1435
+1436
+1437
+1438
+1439
+1440
+1441
+1442
+1443
+1444
+1445
+1446
+1447
+1448
+1449
+1450
+1451
+1452
+1453
+1454
+1455
+1456
+1457
+1458
+1459
+1460
+1461
+1462
+1463
+1464
+1465
+1466
+1467
+1468
+1469
+1470
+1471
+1472
+1473
+1474
+1475
+1476
+1477
+1478
+1479
+1480
+1481
+1482
+1483
+1484
+1485
+1486
+1487
+1488
+1489
+1490
+1491
+1492
+1493
+1494
+1495
+1496
+1497
+1498
+1499
+1500
+1501
+1502
+1503
+1504
+1505
+1506
+1507
+1508
+1509
+1510
+1511
+1512
+1513
+1514
+1515
+1516
+1517
+1518
+1519
+1520
+1521
+1522
+1523
+1524
+1525
+1526
+1527
+1528
+1529
+1530
+1531
+1532
+1533
+1534
+1535
+1536
+1537
+1538
+1539
+1540
+1541
+1542
+1543
+1544
+1545
+1546
+1547
+1548
+1549
+1550
+1551
+1552
+1553
+1554
+1555
+1556
+1557
+1558
+1559
+1560
+1561
+1562
+1563
+1564
+1565
+1566
+1567
+1568
+1569
+1570
+1571
+1572
+1573
+1574
+1575
+1576
+1577
+1578
+1579
+1580
+1581
+1582
+1583
+1584
+1585
+1586
+1587
+1588
+1589
+1590
+1591
+1592
+1593
+1594
+1595
+1596
+1597
+1598
+1599
+1600
+1601
+1602
+1603
+1604
+1605
+1606
+1607
+1608
+1609
+1610
+1611
+1612
#include "mesh_adapter.hpp"
+
+#include <assert.h>                        // for assert
+#include <cstddef>                         // for size_t
+#include <iostream>                        // for operator<<, endl, basic_os...
+#include <set>                             // for set
+#include <utility>                         // for pair
+#include "AMR/AMR_types.hpp"                 // for Edge_Refinement, edge_list_t
+#include "AMR/Loggers.hpp"                   // for trace_out
+#include "AMR/Refinement_State.hpp"          // for Refinement_Case, Refinemen...
+#include "AMR/edge.hpp"                      // for operator<<, edge_t
+#include "AMR/edge_store.hpp"                // for edge_store_t
+#include "AMR/marked_refinements_store.hpp"  // for marked_refinements_store_t
+#include "AMR/node_connectivity.hpp"         // for node_connectivity_t
+#include "AMR/refinement.hpp"                // for refinement_t
+#include "AMR/tet_store.hpp"                 // for tet_store_t
+
+#if defined(__clang__)
+  #pragma clang diagnostic push
+  #pragma clang diagnostic ignored "-Wunreachable-code"
+  #pragma clang diagnostic ignored "-Wdocumentation"
+#endif
 
-namespace tk {
-namespace ctr {
+namespace AMR {
+
 
-//! \brief Keyword information bundle
-//! \details This bundle contains the information that is used to display
-//!    on-screen help on all command-line arguments and control file keywords
-//!    for an exectuable. This struct is stored in a container that associates
-//!    keywords (used by a grammar and parser) to this struct. The container, an
-//!    runtime, std::map, is filled by the CmdLine and InputDeck objects'
-//!    constructors by one or more brigand::for_each which loops through the
-//!    set of all keywords used in a grammar. The maps are stored in the CmdLine
-//!    and InputDeck objects (which are tagged tuples) and thus can be migrated
-//!    through the network, thus the Charm++ parck/unpack routines are defined.
-//! \see Info functor used to fill the std::maps
-struct KeywordInfo {
-  std::string shortDescription;           //!< Short description
-  std::string longDescription;            //!< Long description
-  std::optional< std::string > alias;     //!< Keyword alias
-  std::optional< std::string > expt;      //!< Expected type description
-  std::optional< std::string > lower;     //!< Lower bound as string
-  std::optional< std::string > upper;     //!< Upper bound as string
-  std::optional< std::string > choices;   //!< Expected choices description
-
-  /** @name Pack/Unpack: Serialize KeywordInfo object for Charm++ */
-  ///@{
-  //! \brief Pack/Unpack serialize member function
-  //! \param[in,out] p Charm++'s PUP::er serializer object reference
-  void pup( PUP::er& p ) {<--- Parameter 'p' can be declared with const
-    p | shortDescription;
-    p | longDescription;
-    p | alias;
-    p | expt;
-    p | lower;
-    p | upper;
-    p | choices;
-  }
-  //! \brief Pack/Unpack serialize operator|
-  //! \param[in,out] p Charm++'s PUP::er serializer object reference
-  //! \param[in,out] info KeywordInfo object reference
-  friend void operator|( PUP::er& p, KeywordInfo& info ) { info.pup(p); }
-  ///@}
-};
-
-//! \brief A typedef for associating a keyword-string with its associated
-//!   information stored in a KeywordInfo struct
-using HelpFactory = std::map< std::string, KeywordInfo >;
-
-//! \brief Help bundle on a single keyword
-//! \details This is used for delivering help on a single keyword. This struct
-//!    also differentiates between command-line arguments and control file
-//!    keywords.
-struct HelpKw {
-  HelpFactory::key_type keyword;        //!< Keyword string
-  HelpFactory::mapped_type info;        //!< Keyword information
-  bool cmd;                             //!< True if command-line keyword
-
-  /** @name Pack/Unpack: Serialize HelpKw object for Charm++ */
-  ///@{
-  //! \brief Pack/Unpack serialize member function
-  //! \param[in,out] p Charm++'s PUP::er serializer object reference
-  void pup( PUP::er& p ) { p|keyword; p|info; p|cmd; }<--- Parameter 'p' can be declared with const
-  //! \brief Pack/Unpack serialize operator|
-  //! \param[in,out] p Charm++'s PUP::er serializer object reference
-  //! \param[in,out] h HelpKw object reference
-  friend void operator|( PUP::er& p, HelpKw& h ) { h.pup(p); }
-  ///@}
-};
-
-//! \brief Function object for filling a HelpFactory (std::map) with keywords
-//!   and their associated information bundle
-//! \details This struct is used as a functor to loop through a set of keywords
-//!   at compile-time and generate code for filling up the std::map.
-struct Info {
-  //! Store reference to map we are filling
-  tk::ctr::HelpFactory& m_factory;
-  //! Constructor: store reference to map to fill
-  explicit Info( tk::ctr::HelpFactory& factory ) : m_factory( factory ) {}
-  //! \brief Function call operator templated on the type that does the filling
-  template< typename U > void operator()( brigand::type_<U> ) {
-    m_factory[ U::string() ] = { U::shortDescription(),
-                                 U::longDescription(),
-                                 U::alias(),
-                                 U::expt(),
-                                 U::lower(),
-                                 U::upper(),
-                                 U::choices() };
-  }
-
-  //! Fill map in a simpler way passing a string rather than a brigand-type
-  void fill( const tk::entry_t& kw )
-  {
-    m_factory[kw.string()] = { kw.shortDescription(),
-                               kw.longDescription(),
-                               kw.alias(),
-                               kw.expt(),
-                               kw.lower(),
-                               kw.upper(),
-                               kw.choices() };
-  }
-};
-
-} // ctr::
-} // tk::
-
-#endif // HelpFactory_h
+#ifdef ENABLE_NODE_STORE
+    /**
+     * @brief This accepts external coord arrays and allows the node_store to
+     * track the new node positions as they are added
+     *
+     * @param m_x X coodinates
+     * @param m_y Y coodinates
+     * @param m_z Z coodinates
+     * @param graph_size Total number of nodes
+     */
+    // TODO: remove graph size and use m.size()
+    // TODO: remove these pointers
+    //void mesh_adapter_t::init_node_store(coord_type* m_x, coord_type* m_y, coord_type* m_z)
+    //{
+    //    assert( m_x->size() == m_y->size() );
+    //    assert( m_x->size() == m_z->size() );
+
+    //    node_store.set_x(*m_x);
+    //    node_store.set_y(*m_y);
+    //    node_store.set_z(*m_z);
+    //}
+#endif
+
+    std::pair< bool, std::size_t > mesh_adapter_t::check_same_face(
+      std::size_t tet_id,
+      const std::unordered_set<std::size_t>& inactive_nodes)
+    {
+       edge_list_t edge_list = tet_store.generate_edge_keys(tet_id);
+
+       Assert(inactive_nodes.size()==3 || inactive_nodes.size()==2,
+         "Incorrectly sized inactive nodes set");
+
+       // for a tet ABCD, the keys (edges) are ordered
+       // A-B, A-C, A-D, B-C, B-D, C-D
+       // 0-1, 0-2, 0-3, 1-2, 1-3, 2-3
+
+       std::array< std::array< std::size_t, 3 >, 4 >
+         edges_on_face;
+
+       // A-B-C
+       edges_on_face[0][0] =
+         tk::cref_find(node_connectivity.data(),edge_list[0].get_data());
+       edges_on_face[0][1] =
+         tk::cref_find(node_connectivity.data(),edge_list[1].get_data());
+       edges_on_face[0][2] =
+         tk::cref_find(node_connectivity.data(),edge_list[3].get_data());
+
+       // A-B-D
+       edges_on_face[1][0] =
+         tk::cref_find(node_connectivity.data(),edge_list[0].get_data());
+       edges_on_face[1][1] =
+         tk::cref_find(node_connectivity.data(),edge_list[2].get_data());
+       edges_on_face[1][2] =
+         tk::cref_find(node_connectivity.data(),edge_list[4].get_data());
+
+       // B-C-D
+       edges_on_face[2][0] =
+         tk::cref_find(node_connectivity.data(),edge_list[3].get_data());
+       edges_on_face[2][1] =
+         tk::cref_find(node_connectivity.data(),edge_list[4].get_data());
+       edges_on_face[2][2] =
+         tk::cref_find(node_connectivity.data(),edge_list[5].get_data());
+
+       // A-C-D
+       edges_on_face[3][0] =
+         tk::cref_find(node_connectivity.data(),edge_list[1].get_data());
+       edges_on_face[3][1] =
+         tk::cref_find(node_connectivity.data(),edge_list[2].get_data());
+       edges_on_face[3][2] =
+         tk::cref_find(node_connectivity.data(),edge_list[5].get_data());
+
+       //Iterate over edges to determine if inactive_nodes are all part of a face
+       bool same_face(false);
+       [[maybe_unused]] bool tnode_set(false);
+       std::size_t third_node = 0;
+       for(const auto& face : edges_on_face)
+       {
+         std::size_t icount = 0;
+         for (const auto& np_node : face) {
+           if (inactive_nodes.count(np_node)) ++icount;
+         }
+         if (inactive_nodes.size() == icount) {
+           same_face = true;
+           // if the two inactive_nodes being checked are on the same parent
+           // face, determine the third node on that face
+           if (inactive_nodes.size() == 2) {
+             for (auto fn:face) {
+               if (inactive_nodes.count(fn) == 0) {
+                 third_node = fn;
+                 tnode_set = true;
+                 break;
+               }
+             }
+           }
+         }
+       }
+
+       if (same_face && inactive_nodes.size() == 2)
+         Assert(tnode_set, "Third node on face not set in derefine");
+
+       return {same_face, third_node};
+    }
+
+    /** @brief Consume an existing mesh, and turn it into the AMRs
+     * representations of tets and nodes
+     *
+     * @param tetinpoel Vector of nodes grouped together in blocks of 4 to
+     * represent tets
+     */
+    void mesh_adapter_t::consume_tets(const std::vector< std::size_t >& tetinpoel )
+    {
+        for (size_t i = 0; i < tetinpoel.size(); i+=4)
+        {
+            tet_t t = {
+                {
+                    tetinpoel[i],
+                    tetinpoel[i+1],
+                    tetinpoel[i+2],
+                    tetinpoel[i+3]
+                }
+            };
+
+            trace_out << "Consume tet " << i << std::endl;
+            tet_store.add(t, AMR::Refinement_Case::initial_grid);
+        }
+    }
+
+    /**
+     * @brief Place holder function to evaluate error estimate at
+     * nodes, and therefor mark things as needing to be refined
+     */
+    //void mesh_adapter_t::evaluate_error_estimate() {
+    //    for (auto& kv : tet_store.edge_store.edges)
+    //    {
+    //        // Mark them as needing refinement
+    //        if (kv.second.refinement_criteria > refinement_cut_off)
+    //        {
+    //            kv.second.needs_refining = 1;
+    //        }
+    //        else
+    //        {
+    //            // TODO: Check this won't be overwriting valuable
+    //            // information from last iteration
+    //            kv.second.needs_refining = 0;
+    //        }
+    //    }
+    //}
+
+    /**
+     * @brief Helper function to apply uniform refinement to all tets
+     */
+    void mesh_adapter_t::mark_uniform_refinement()
+    {
+        for (auto& kv : tet_store.edge_store.edges) {
+           auto& local = kv.second;
+           if (local.lock_case == Edge_Lock_Case::unlocked)
+             local.needs_refining = 1;
+        }
+        mark_refinement();
+    }
+
+    /**
+     * @brief Helper function to apply uniform derefinement to all tets
+     */
+    void mesh_adapter_t::mark_uniform_derefinement()
+    {
+      const auto& inp = tet_store.get_active_inpoel();
+      auto& edge_store = tet_store.edge_store;
+      for (std::size_t t=0; t<inp.size()/4; ++t) {
+        const auto edges =
+          edge_store.generate_keys(
+            {inp[t*4+0], inp[t*4+1], inp[t*4+2], inp[t*4+3]});
+        for (const auto& tetedge : edges) {
+          auto e = edge_store.edges.find(tetedge);
+          if (e != end(edge_store.edges)) {
+            auto& local = e->second;
+            local.needs_derefining = 1;
+          }
+        }
+      }
+      mark_derefinement();
+    }
+
+    /**
+     * @brief For a given set of edges, set their refinement criteria for
+     * refinement
+     *
+     * @param remote Vector of edges and edge tags
+     */
+    void mesh_adapter_t::mark_error_refinement(
+            const std::vector< std::pair< edge_t, edge_tag > >& remote )
+    {
+       for (const auto& r : remote) {
+         auto& local = tet_store.edge_store.get( r.first );
+         if (r.second == edge_tag::REFINE) {
+           if (local.lock_case > Edge_Lock_Case::unlocked) {
+             local.needs_refining = 0;
+           } else {
+             local.needs_refining = 1;
+             // an edge deemed to be 'needing refinement', cannot be derefined
+             local.needs_derefining = 0;
+           }
+         } else if (r.second == edge_tag::DEREFINE) {
+           local.needs_derefining = 1;
+         }
+       }
+
+       mark_refinement();
+       mark_derefinement();
+    }
+
+   void mesh_adapter_t::mark_error_refinement_corr( const EdgeData& edges )
+    {
+       for (const auto& r : edges)
+       {
+           auto& edgeref = tet_store.edge_store.get( edge_t(r.first) );
+           edgeref.needs_refining = std::get<0>(r.second);
+           edgeref.needs_derefining = std::get<1>(r.second);
+           Assert(edgeref.lock_case == Edge_Lock_Case::unlocked ?
+             edgeref.lock_case <= std::get<2>(r.second) : true,
+             "Edge " + std::to_string(r.first[0]) +
+             "-" + std::to_string(r.first[1]) +
+             " : current edge-lock " + std::to_string(edgeref.lock_case) +
+             " stricter than received edge-lock " +
+             std::to_string(std::get<2>(r.second)));
+           edgeref.lock_case = std::get<2>(r.second);
+       }
+       mark_refinement();
+       mark_derefinement();
+    }
+
+    /**
+     * @brief Function to detect the compatibility class (1,
+     * 2, or 3) based on the number of locked edges and the existence
+     * of intermediate edges
+     *
+     * @param num_locked_edges The number of locked edges
+     * @param num_intermediate_edges The number of intermediate edges
+     * @param refinement_case The refinement case of the tet
+     * @param normal TODO: Document this!
+     *
+     * @return The compatibili4y class of the current scenario
+     */
+    int mesh_adapter_t::detect_compatibility(
+            int num_locked_edges,
+            int num_intermediate_edges,
+            AMR::Refinement_Case refinement_case,
+            int normal
+    )
+    {
+        int compatibility = 0;
+        num_locked_edges += num_intermediate_edges;
+
+        /*
+        // Split this into three categories
+        // 1. Normal elements without locked edges. => 1
+        //if (normal) {
+
+            // 3. Intermediate elements with at least one edge marked for refinement => 3
+            if (num_intermediate_edges > 0)
+            {
+                compatibility = 3;
+            }
+            else if (num_locked_edges == 0) {
+                compatibility = 1;
+            }
+        // 2. Normal elements with locked edges. => 2
+            else {
+                compatibility = 2;
+            }
+        //}
+        */
+
+        //else {
+            //if (num_intermediate_edges > 0) { compatibility = 3; }
+        //}
+
+
+
+        // Only 1:2 and 1:4 are intermediates and eligible for class3 // NOT TRUE!
+        /*
+        if (num_intermediate_edges > 0)
+        {
+            if (!normal) {
+                trace_out << " not normal 3 " << std::endl;
+                compatibility = 3;
+            }
+            else { // Attempt to allow for "normal" 1:4 and 1:8
+                compatibility = 2;
+                trace_out << " normal 3 " << std::endl;
+            }
+
+        }
+        else {
+            if (num_locked_edges == 0) {
+                trace_out << " no lock 1 " << std::endl;
+                compatibility = 1;
+            }
+            else {
+                trace_out << " lock 2 " << std::endl;
+                compatibility = 2;
+            }
+        }
+        */
+
+
+        // Old implementation
+        // Only 1:2 and 1:4 are intermediates and eligible for class3 // NOT TRUE!
+        if (
+                (refinement_case == AMR::Refinement_Case::one_to_two) or
+                (refinement_case == AMR::Refinement_Case::one_to_four)
+           )
+        {
+            if (!normal) {
+                trace_out << " not normal 3 " << std::endl;
+                compatibility = 3;
+            }
+            else { // Attempt to allow for "normal" 1:4 and 1:8
+                compatibility = 2;
+                trace_out << " normal 3 " << std::endl;
+            }
+
+        }
+        else {
+            if (num_locked_edges == 0) {
+                trace_out << " no lock 1 " << std::endl;
+                compatibility = 1;
+            }
+            else {
+                trace_out << " lock 2 " << std::endl;
+                compatibility = 2;
+            }
+        }
+
+        assert(compatibility > 0);
+        assert(compatibility < 4);
+        return compatibility;
+    }
+
+    /**
+     * @brief Function which implements the main refinement algorithm from
+     * the paper Iterating over the cells, deciding which refinement and
+     * compatibility types are appropriate etc
+     */
+    void mesh_adapter_t::mark_refinement() {
+
+#ifndef AMR_MAX_ROUNDS
+        // Paper says the average actual num rounds will be 5-15
+#define AMR_MAX_ROUNDS 50
+#endif
+        const size_t max_num_rounds = AMR_MAX_ROUNDS;
+
+        // Mark refinements
+        size_t iter;
+        //Iterate until convergence
+        for (iter = 0; iter < max_num_rounds; iter++)
+        {
+
+            tet_store.marked_refinements.get_state_changed() = false;
+
+            // Loop over Tets.
+            for (const auto& kv : tet_store.tets)
+            {
+                size_t tet_id = kv.first;
+
+                trace_out << "Process tet " << tet_id << std::endl;
+
+                // Only apply checks to tets on the active list
+                if (tet_store.is_active(tet_id)) {
+                    int num_locked_edges = 0;
+                    int num_intermediate_edges = 0;
+
+                    // Loop over nodes and count the number which need refining
+                    int num_to_refine = 0;
+
+                    // This is useful for later inspection
+                    edge_list_t edge_list = tet_store.generate_edge_keys(tet_id);
+
+                    //Iterate over edges
+                    for(auto & key : edge_list)
+                    {
+
+                        trace_out << "Edge " << key << std::endl;
+
+                        //Count locked edges and edges in need of
+                        // refinement
+                        // Count Locked Edges
+                        if(tet_store.edge_store.get(key).lock_case == AMR::Edge_Lock_Case::locked)
+                        {
+                            trace_out << "Found locked edge " << key << std::endl;
+                            trace_out << "Locked :" << tet_store.edge_store.get(key).lock_case << std::endl;
+                            num_locked_edges++;
+                        }
+                        else if(tet_store.edge_store.get(key).lock_case == AMR::Edge_Lock_Case::intermediate
+                          || tet_store.edge_store.get(key).lock_case == AMR::Edge_Lock_Case::temporary)
+                        {
+                            trace_out << "Found intermediate edge " << key << std::endl;
+                            num_intermediate_edges++;
+                        }
+                        else
+                        {
+                            // Count edges which need refining
+                            //  We check in here as we won't refine a
+                            //  locked edge and will thus ignore it
+                            if (tet_store.edge_store.get(key).needs_refining == 1)
+                            {
+                                num_to_refine++;
+                                trace_out << "key needs ref " << key << std::endl;
+                            }
+                        }
+                    }
+
+                    // TODO: Should this be a reference?
+                    AMR::Refinement_Case refinement_case = tet_store.get_refinement_case(tet_id);
+                    int normal = tet_store.is_normal(tet_id);
+
+                    trace_out << "Checking " << tet_id <<
+                        " ref case " << refinement_case <<
+                        " num ref " << num_to_refine <<
+                        " normal " << normal <<
+                        std::endl;
+
+
+
+                    //If we have any tets to refine
+                    if (num_to_refine > 0)
+                    {
+                        //Determine compatibility case
+
+                        int compatibility = detect_compatibility(num_locked_edges,
+                                num_intermediate_edges, refinement_case, normal);
+
+                        trace_out << "Compat " << compatibility << std::endl;
+
+                        // Now check num_to_refine against situations
+                        if (compatibility == 1)
+                        {
+                            refinement_class_one(num_to_refine, tet_id);
+                        }
+                        else if (compatibility == 2)
+                        {
+                            refinement_class_two(edge_list, tet_id);
+                        }
+                        else if (compatibility == 3)
+                        {
+                            refinement_class_three(tet_id);
+                        }
+
+                        /*
+                        // Write temp mesh out
+                        std::string temp_file =  "temp." +
+                        std::to_string(iter) + "." +
+                        std::to_string(tet_id) + ".exo";
+
+                        std::cout << "Writing " << temp_file << std::endl;
+                        Adaptive_UnsMesh outmesh(
+                        get_active_inpoel(), x(), y(), z()
+                        );
+                        tk::ExodusIIMeshWriter( temp_file, tk::ExoWriter::CREATE ).
+                        writeMesh(outmesh);
+                        */
+
+                    } // if num_to_refine
+                    else {
+                        // If we got here, we don't want to refine this guy
+                        tet_store.marked_refinements.add(tet_id, AMR::Refinement_Case::none);
+                    }
+                } // if active
+                else {
+                    trace_out << "Inactive" << std::endl;
+                }
+            } // For
+
+            // If nothing changed during that round, break
+            if (!tet_store.marked_refinements.get_state_changed())
+            {
+                trace_out << "Terminating loop at iter " << iter << std::endl;
+                break;
+            }
+            trace_out << "End iter " << iter << std::endl;
+        }
+        trace_out << "Loop took " << iter << " rounds." << std::endl;
+
+        //std::cout << "Print Tets" << std::endl;
+        //print_tets();
+    }
+
+    /**
+     * @brief Helper function to print tet information when needed
+     */
+    void mesh_adapter_t::print_tets() {
+        tet_store.print_tets();
+    }
+
+    /**
+     * @brief Function to call refinement after each tet has had it's
+     * refinement case marked and calculated
+     */
+    void mesh_adapter_t::perform_refinement()
+    {
+        // Track tets which need to be deleted this iteration
+        std::set<size_t> round_two;
+
+        trace_out << "Perform ref" << std::endl;
+
+        // Do refinements
+        for (const auto& kv : tet_store.tets)
+        {
+            size_t tet_id = kv.first;
+
+            trace_out << "Do refine of " << tet_id << std::endl;
+            if (tet_store.has_refinement_decision(tet_id))
+            {
+                switch(tet_store.marked_refinements.get(tet_id))
+                {
+                    case AMR::Refinement_Case::one_to_two:
+                        refiner.refine_one_to_two(tet_store,node_connectivity,tet_id);
+                        break;
+                    case AMR::Refinement_Case::one_to_four:
+                        refiner.refine_one_to_four(tet_store,node_connectivity,tet_id);
+                        break;
+                    case AMR::Refinement_Case::one_to_eight:
+                        refiner.refine_one_to_eight(tet_store,node_connectivity,tet_id);
+                        break;
+                    case AMR::Refinement_Case::two_to_eight:
+                        round_two.insert( tet_store.get_parent_id(tet_id) );
+                        //std::cout << "2->8\n";
+                        break;
+                    case AMR::Refinement_Case::four_to_eight:
+                        round_two.insert( tet_store.get_parent_id(tet_id));
+                        //std::cout << "4->8\n";
+                        break;
+                    case AMR::Refinement_Case::initial_grid:
+                        // Do nothing
+                    case AMR::Refinement_Case::none:
+                        // Do nothing
+                        break;
+                        // No need for default as enum is explicitly covered
+                }
+                // Mark tet as not needing refinement
+                tet_store.marked_refinements.erase(tet_id);
+            }
+        }
+
+        trace_out << "round_two size " << round_two.size() << std::endl;
+        for (const auto i : round_two)
+        {
+            trace_out << "round two i " << i << std::endl;
+
+            // Cache children as we're about to change this data
+            auto former_children = tet_store.data(i).children;
+
+            AMR::Refinement_State& element = tet_store.data(i);
+
+            if (element.children.size() == 2)
+            {
+                trace_out << "perform 2:8" << std::endl;
+                refiner.derefine_two_to_one(tet_store,node_connectivity,i);
+            }
+            else if (element.children.size() == 4)
+            {
+                trace_out << "perform 4:8" << std::endl;
+                refiner.derefine_four_to_one(tet_store,node_connectivity,i);
+            }
+            else {
+                std::cout << "num children " << element.children.size() << std::endl;
+                assert(0);
+            }
+            // remove tets and edges marked for deletion above
+            refiner.delete_intermediates_of_children(tet_store);
+            tet_store.process_delete_list();
+
+            refiner.refine_one_to_eight(tet_store,node_connectivity,i);
+
+            // Grab children after it has been updated
+            auto current_children = tet_store.data(i).children;
+
+            // I want to set the children stored in *my* own children, to be
+            // the value of my new children....
+            //refiner.overwrite_children(tet_store, former_children, current_children);
+
+            tet_store.unset_marked_children(i); // FIXME: This will not work well in parallel
+            element.refinement_case = AMR::Refinement_Case::one_to_eight;
+        }
+
+        // Clean up dead edges
+        // clean_up_dead_edges(); // Nothing get's marked as "dead" atm?
+
+        //std::cout << "Total Edges : " << tet_store.edge_store.size() << std::endl;
+        //std::cout << "Total Tets : " << tet_store.size() << std::endl;
+        //std::cout << "Total Nodes : " << m_x.size() << std::endl;
+
+        trace_out << "Done ref" << std::endl;
+        node_connectivity.print();
+        node_connectivity.print();
+        tet_store.print_node_types();
+        tet_store.print_tets();
+        //node_connectivity.print();
+
+        //reset_intermediate_edges();
+        remove_edge_locks(1);
+        remove_normals();
+
+        lock_intermediates();
+
+        for (auto& kv : tet_store.edge_store.edges) {
+           auto& local = kv.second;
+           if (local.needs_refining == 1) local.needs_refining = 0;
+        }
+    }
+
+    void mesh_adapter_t::lock_intermediates()
+    {
+        /*
+        for (auto k : tet_store.intermediate_list)
+        {
+            refiner.lock_edges_from_node(tet_store,k, Edge_Lock_Case::intermediate);
+        }
+        */
+        // TODO: Passing tet_store twice probably isn't the best
+        refiner.lock_intermediates(tet_store, tet_store.intermediate_list, Edge_Lock_Case::intermediate);
+    }
+
+    /**
+     * @brief A method implementing "Algorithm 1" from the paper
+     *
+     * @param num_to_refine Number of edges to refine
+     * @param tet_id The id of the given tet
+     */
+    void mesh_adapter_t::refinement_class_one(int num_to_refine, size_t tet_id)
+    {
+        trace_out << "Refinement Class One" << std::endl;
+
+        // "If nrefine = 1
+        // Accept as a 1:2 refinement"
+        if (num_to_refine == 1)
+        {
+            tet_store.mark_one_to_two(tet_id);
+        }
+
+        // "Else if nrefine = 2 OR nrefine = 3"
+        else if (num_to_refine > 1 && num_to_refine < 4)
+        {
+
+            // We need to detect if the edges which need to refine are
+            // on the same face
+            // and if so which face so we know how to 1:4
+
+            face_list_t face_list = tet_store.generate_face_lists(tet_id);
+            bool edges_on_same_face = false;
+            size_t face_refine_id = 0;
+
+            // Iterate over each face
+            for (size_t face = 0; face < NUM_TET_FACES; face++)
+            {
+                int num_face_refine_edges = 0;
+                face_ids_t face_ids = face_list[face];
+
+                trace_out << "Face is " <<
+                    face_ids[0] << ", " <<
+                    face_ids[1] << ", " <<
+                    face_ids[2] << ", " <<
+                    std::endl;
+
+                edge_list_t face_edge_list = AMR::edge_store_t::generate_keys_from_face_ids(face_ids);
+                // For this face list, see which ones need refining
+                for (size_t k = 0; k < NUM_FACE_NODES; k++)
+                {
+                    edge_t key = face_edge_list[k];
+                    if (tet_store.edge_store.get(key).needs_refining == 1)
+                    {
+                        num_face_refine_edges++;
+                    }
+                }
+                if (num_face_refine_edges == num_to_refine)
+                {
+                    edges_on_same_face = true;
+                    face_refine_id = face;
+                    trace_out << "Breaking with face value " << face << std::endl;
+                    break;
+                }
+            }
+
+            // "If active edges are on the same face
+            // Activate any inactive edges of the face
+            // Accept as a 1:4 // refinement"
+            if (edges_on_same_face)
+            {
+                size_t opposite_offset = AMR::node_connectivity_t::face_list_opposite(face_list,
+                        face_refine_id);
+
+                tet_t tet = tet_store.get(tet_id);
+                size_t opposite_id = tet[opposite_offset];
+
+                trace_out << "face_refine_id " << face_refine_id << std::endl;
+                trace_out << "opposite_offset " << opposite_offset << std::endl;
+                trace_out << "opposite_id " << opposite_id << std::endl;
+
+                // Activate edges on this face
+                edge_list_t face_edge_list = AMR::edge_store_t::generate_keys_from_face_ids(face_list[face_refine_id]);
+
+                for (size_t k = 0; k < NUM_FACE_NODES; k++)
+                {
+                    edge_t key = face_edge_list[k];
+                    tet_store.edge_store.mark_for_refinement(key);
+                }
+
+                //refiner.refine_one_to_four(tet_id, face_list[face_refine_id],
+                //opposite_id);
+                tet_store.mark_one_to_four(tet_id);
+            }
+            // "Else if active edges are not on the same face
+            // Activate all edges
+            // Accept as a 1:8 refinement"
+            else {
+                //refiner.refine_one_to_eight(tet_id);
+                tet_store.mark_edges_for_refinement(tet_id);
+                tet_store.mark_one_to_eight(tet_id);
+            }
+
+        }
+
+        // "Else if nrefine > 3
+        // Activate any inactive edges
+        // Accept as a 1:8 refinement"
+        else if (num_to_refine > 3)
+        {
+            //refiner.refine_one_to_eight(tet_id);
+            tet_store.mark_edges_for_refinement(tet_id);
+            tet_store.mark_one_to_eight(tet_id);
+        }
+    }
+
+    // TODO: Document this
+    void mesh_adapter_t::lock_tet_edges(size_t tet_id) {
+        edge_list_t edge_list = tet_store.generate_edge_keys(tet_id);
+        for (size_t k = 0; k < NUM_TET_EDGES; k++)
+        {
+            edge_t key = edge_list[k];
+            if (tet_store.edge_store.get(key).lock_case == AMR::Edge_Lock_Case::unlocked)
+            {
+                trace_out << "LOCKING! " << key << std::endl;
+                tet_store.edge_store.get(key).lock_case = AMR::Edge_Lock_Case::locked;
+            }
+        }
+    }
+
+    // TODO: Document this
+    // TODO: This has too similar a name to deactivate_tet
+    void mesh_adapter_t::deactivate_tet_edges(size_t tet_id) {
+        edge_list_t edge_list = tet_store.generate_edge_keys(tet_id);
+        for (size_t k = 0; k < NUM_TET_EDGES; k++)
+        {
+            edge_t key = edge_list[k];
+
+            tet_store.edge_store.unmark_for_refinement(key);
+            trace_out << "Deactivating " << key << std::endl;
+            tet_store.edge_store.get(key).needs_derefining = false;
+        }
+    }
+
+    /**
+     * @brief Unmarks edges of given tet for derefinement only
+     *
+     * @param tet_id The id of the given tet
+     */
+    void mesh_adapter_t::deactivate_deref_tet_edges(size_t tet_id) {
+        edge_list_t edge_list = tet_store.generate_edge_keys(tet_id);
+        for (size_t k = 0; k < NUM_TET_EDGES; k++)
+        {
+            edge_t key = edge_list[k];
+
+            trace_out << "Deactivating " << key << std::endl;
+            tet_store.edge_store.get(key).needs_derefining = false;
+        }
+    }
+
+    /**
+     * @brief An implementation of "Algorithm 2" from the paper
+     *
+     * @param edge_list The list of edges for the given tet
+     * @param tet_id The id of the given tet
+     */
+    void mesh_adapter_t::refinement_class_two(edge_list_t edge_list, size_t tet_id)
+    {
+        trace_out << "Refinement Class Two" << std::endl;
+
+
+        // "Deactivate all locked edges"
+
+        // count number of active edges
+        int num_active_edges = 0;
+        for (size_t k = 0; k < NUM_TET_EDGES; k++)
+        {
+            edge_t key = edge_list[k];
+            if (tet_store.edge_store.get(key).lock_case != AMR::Edge_Lock_Case::unlocked)
+            {
+                tet_store.edge_store.unmark_for_refinement(key);
+            }
+            // "Count number of active edges"
+            if (tet_store.edge_store.get(key).needs_refining == 1) {
+                num_active_edges++;
+            }
+        }
+
+        // Find out of two active edges live on the same face
+        bool face_refine = false;
+        size_t face_refine_id = 0; // FIXME: Does this need a better default
+        face_list_t face_list = tet_store.generate_face_lists(tet_id);
+
+        // Iterate over each face
+        for (size_t face = 0; face < NUM_TET_FACES; face++)
+        {
+            trace_out << "face " << face << std::endl;
+            int num_face_refine_edges = 0;
+            int num_face_locked_edges = 0;
+
+            face_ids_t face_ids = face_list[face];
+            edge_list_t face_edge_list = AMR::edge_store_t::generate_keys_from_face_ids(face_ids);
+            // For this face list, see which ones need refining
+            for (size_t k = 0; k < NUM_FACE_NODES; k++)
+            {
+                edge_t key = face_edge_list[k];
+                trace_out << "Checking " << key << std::endl;
+                if (tet_store.edge_store.get(key).needs_refining == 1)
+                {
+                    num_face_refine_edges++;
+                    trace_out << "ref! " << key << std::endl;
+                }
+
+                // Check for locked edges
+                // This case only cares about faces with no locks
+                if (tet_store.edge_store.get(key).lock_case != AMR::Edge_Lock_Case::unlocked)
+                {
+                    num_face_locked_edges++;
+                    trace_out << "locked! " << key << std::endl;
+                }
+            }
+
+
+            // Decide if we want to process this face
+            if (num_face_refine_edges >= 2 && num_face_locked_edges == 0)
+            {
+                // We can refine this face
+                face_refine = true;
+                face_refine_id = face;
+                break;
+            }
+        }
+
+        // "If nrefine = 1
+        // Accept as 1:2 refinement"
+        // TODO: can we hoist this higher
+        if (num_active_edges == 1)
+        {
+            //node_pair_t nodes = find_single_refinement_nodes(edge_list);
+            //refine_one_to_two( tet_id, nodes[0], nodes[1]);
+            tet_store.mark_one_to_two(tet_id);
+        }
+        // "Else if any face has nrefine >= 2 AND no locked edges
+        // Active any inactive edges of the face
+        // Accept as a 1:4 refinement"
+        else if (face_refine)
+        {
+            size_t opposite_offset = AMR::node_connectivity_t::face_list_opposite(face_list, face_refine_id);
+
+            tet_t tet = tet_store.get(tet_id);
+            size_t opposite_id = tet[opposite_offset];
+
+            trace_out << "Tet ID " << tet_id << std::endl;
+            trace_out << "Opposite offset " << opposite_offset << std::endl;
+            trace_out << "Opposite id " << opposite_id << std::endl;
+            trace_out << "Face refine id " << face_refine_id << std::endl;
+
+            edge_list_t face_edge_list =
+                AMR::edge_store_t::generate_keys_from_face_ids(face_list[face_refine_id]);
+
+            for (size_t k = 0; k < NUM_FACE_NODES; k++)
+            {
+                edge_t key = face_edge_list[k];
+                tet_store.edge_store.mark_for_refinement(key);
+            }
+
+            //refiner.refine_one_to_four(tet_id, face_list[face_refine_id], opposite_id);
+            tet_store.mark_one_to_four(tet_id);
+        }
+
+        // "Else
+        // Deactivate all edges
+        // Mark all edges as locked"
+        else {
+            trace_out << "Class 2 causes some locking.." << std::endl;
+            deactivate_tet_edges(tet_id);
+            lock_tet_edges(tet_id);
+        }
+
+    }
+
+    /**
+     * @brief Based on a tet_id, decide if it's current state of locked
+     * and marked edges maps to a valid refinement case. The logic for
+     * this was derived from talking to JW and reading Chicoma.
+     *
+     * It basically just checks if something a 1:2 and has 3
+     * intermediates and 3 makred edges, or is a 1:4 and has 5/6
+     * intermediates
+     *
+     * @param child_id the id of the tet to check
+     *
+     * @return A bool saying if the tet is in a valid state to be refined
+     */
+    bool mesh_adapter_t::check_valid_refinement_case(size_t child_id) {
+
+        trace_out << "check valid ref " << child_id << std::endl;
+        edge_list_t edge_list = tet_store.generate_edge_keys(child_id);
+
+        size_t num_to_refine = 0;
+        size_t num_intermediate = 0;
+        size_t unlocked = 0;
+        size_t locked = 0;
+
+        for (size_t k = 0; k < NUM_TET_EDGES; k++)
+        {
+            edge_t key = edge_list[k];
+            trace_out << "Key " << key << std::endl;
+
+            // Count intermediate edges
+            if (tet_store.edge_store.get(key).lock_case == AMR::Edge_Lock_Case::intermediate
+              || tet_store.edge_store.get(key).lock_case == AMR::Edge_Lock_Case::temporary)
+            {
+                trace_out << "found intermediate" << std::endl;
+                num_intermediate++;
+            }
+
+            // Count number of marked for refinement
+            if (tet_store.edge_store.get(key).needs_refining == 1)
+            {
+                trace_out << "found refine" << std::endl;
+                num_to_refine++;
+            }
+
+            if (tet_store.edge_store.get(key).lock_case == AMR::Edge_Lock_Case::unlocked)
+            {
+                trace_out << "found unlocked" << std::endl;
+                unlocked++;
+            }
+
+            if (tet_store.edge_store.get(key).lock_case == AMR::Edge_Lock_Case::locked)
+            {
+                trace_out << "found locked" << std::endl;
+                locked++;
+            }
+
+        }
+
+        AMR::Refinement_State& element = tet_store.data(child_id);<--- Variable 'element' can be declared with const
+
+        trace_out <<
+            "Intermediates " << num_intermediate <<
+            " num to refine " << num_to_refine <<
+            " unlocked " << unlocked <<
+            " locked " << locked <<
+            " Case " << element.refinement_case <<
+            std::endl;
+
+        // check if element is 1:2
+        if (element.refinement_case == AMR::Refinement_Case::one_to_two)
+        {
+            // If so check it has 3 intermediates and 3 which need refining
+            if (num_intermediate != 3 || num_to_refine != 3) {
+                return false;
+            }
+            else {
+                trace_out << "True " <<
+                    "Intermediates " << num_intermediate <<
+                    " num to refine " << num_to_refine <<
+                    " Case " << element.refinement_case <<
+                    " 2:1 " << AMR::Refinement_Case::one_to_two <<
+                    std::endl;
+            }
+        }
+
+        // check if element is 1:4
+        else if (element.refinement_case == AMR::Refinement_Case::one_to_four)
+        {
+            // TODO: Check if it's a center tet for a 1:4
+            // FIXME: Is this even needed? How else would you get these
+            // combinations? Can't we just combine these two checks?
+
+            bool is_center_tet = tet_store.is_center(child_id);
+
+            if (is_center_tet)
+            {
+                if (num_to_refine != 0 || num_intermediate != 6)
+                {
+                    trace_out << "Fail compat 1:4 center" << std::endl;
+                    return false;
+                }
+            }
+            else { // Is one of the outsides (not center)
+                if (num_to_refine != 1 || num_intermediate != 5)
+                {
+                    trace_out << "Fail compat 1:4 non center" << std::endl;
+                    return false;
+                }
+            }
+        }
+
+        // If it makes it here, it's compatible
+        return true;
+
+    }
+
+    /**
+     * @brief Place holder method for the implementation of "Algorithm
+     * 3" from the paper
+     */
+    // TODO: Does this parse a childs siblings multiple times?
+    void mesh_adapter_t::refinement_class_three(size_t tet_id) {
+
+        trace_out << "Refinement Class Three" << std::endl;
+
+        // "Identify parent element iparent"
+        // TODO: WE should either always use the id to fetch, or always do the data lookup
+        //size_t parent_id = master_elements.get_parent(tet_id);
+        size_t parent_id = tet_store.get_parent_id(tet_id);
+
+        trace_out << "Parent id = " << parent_id << std::endl;
+
+        // NOTE: This implies comms when we use these ids?
+        child_id_list_t children = tet_store.data(parent_id).children;
+
+        // "Do for each child element ielement
+        // Activate all non-locked edges
+        // Deactivate all locked edges"
+        for (size_t i = 0; i < children.size(); i++)
+        {
+            // TODO: Is this in element or tet ids?
+            trace_out << "Checking child " << children[i] << std::endl;
+            edge_list_t edge_list = tet_store.generate_edge_keys(children[i]);
+            for (size_t k = 0; k < NUM_TET_EDGES; k++)
+            {
+                edge_t key = edge_list[k];
+                trace_out << "Compat 3 " << key << std::endl;
+                if (tet_store.edge_store.get(key).lock_case == AMR::Edge_Lock_Case::unlocked)
+		{
+                    trace_out << "Compat 3 marking edge " << key << std::endl;
+                    tet_store.edge_store.mark_for_refinement(key);
+                }
+                else {
+                    tet_store.edge_store.unmark_for_refinement(key);
+                }
+            }
+        }
+
+        // "Set compatible = TRUE
+        bool compatible = true;
+
+        // Do for each child element ielement
+        // If ielement is not a valid refinement case
+        // compatible = FALSE"
+        for (size_t i = 0; i < children.size(); i++)
+        {
+            size_t child = children[i];
+            if ( !check_valid_refinement_case(child) )
+            {
+                trace_out << "Compat 3 Marking compatible false because of invalid refinement case" << std::endl;
+
+                compatible = false;
+            }
+            else {
+                trace_out << "Is compatible" << std::endl;
+            }
+        }
+
+        // "If compatible = FALSE
+        // Do for each child element ielement
+        // Deactive all edges of ielement
+        // Mark all edges of ielement as locked
+        // Mark ielement as normal"
+        if (compatible == false)
+        {
+            for (size_t i = 0; i < children.size(); i++)
+            {
+                size_t child = children[i];
+                deactivate_tet_edges(child);
+                lock_tet_edges(child);
+                trace_out << "Compat 3 locking edges of " << child << std::endl;
+                // Here we interpret normal to mean "don't treat it like it has intermediates"
+                tet_store.mark_normal(child);
+                trace_out << "Compat 3 " << child << std::endl;
+            }
+        }
+        else {
+            trace_out << "TIME TO 2:8 " << tet_id << std::endl;
+            // Accept as 2:8 or 4:8
+            AMR::Refinement_State& element = tet_store.data(tet_id);
+            if (element.refinement_case == AMR::Refinement_Case::one_to_two)
+            {
+                tet_store.mark_two_to_eight(tet_id);
+            }
+            else if (element.refinement_case == AMR::Refinement_Case::one_to_four)
+            {
+                tet_store.mark_four_to_eight(tet_id);
+            }
+            else {
+                trace_out << " I don't know what to do with this..it looks like you're trying to 2/4:8 an 8... " << std::endl;
+            }
+
+        }
+    }
+
+    void mesh_adapter_t::remove_normals()
+    {
+        for (const auto& kv : tet_store.tets)
+        {
+            size_t tet_id = kv.first;
+            tet_store.set_normal(tet_id, 0);
+        }
+    }
+
+    void mesh_adapter_t::remove_edge_locks(int intermediate)
+    {
+        for (const auto& kv : tet_store.tets)
+        {
+            size_t tet_id = kv.first;
+
+            trace_out << "Process tet removelock " << tet_id << std::endl;
+
+            // Only apply checks to tets on the active list
+            if (tet_store.is_active(tet_id)) {
+                // change it from intermediate to locked
+                update_tet_edges_lock_type(tet_id, AMR::Edge_Lock_Case::locked, AMR::Edge_Lock_Case::unlocked);
+                if (intermediate) {
+                    update_tet_edges_lock_type(tet_id, AMR::Edge_Lock_Case::intermediate, AMR::Edge_Lock_Case::unlocked);
+                }
+            }
+        }
+
+    }
+    //void mesh_adapter_t::reset_intermediate_edges()
+    //{
+    //    for (const auto& kv : tet_store.tets)
+    //    {
+    //        size_t tet_id = kv.first;
+
+    //        trace_out << "Process tet reset " << tet_id << std::endl;
+
+    //        // Only apply checks to tets on the active list
+    //        if (tet_store.is_active(tet_id)) {
+    //            // change it from intermediate to locked
+    //            update_tet_edges_lock_type(tet_id, AMR::Edge_Lock_Case::intermediate, AMR::Edge_Lock_Case::locked);
+    //        }
+    //    }
+    //}
+
+    void mesh_adapter_t::update_tet_edges_lock_type(size_t tet_id, AMR::Edge_Lock_Case check, AMR::Edge_Lock_Case new_case) {
+        edge_list_t edge_list = tet_store.generate_edge_keys(tet_id);
+        for (size_t k = 0; k < NUM_TET_EDGES; k++)
+        {
+            edge_t key = edge_list[k];
+            if (tet_store.edge_store.get(key).lock_case == check)
+            {
+                tet_store.edge_store.get(key).lock_case = new_case;
+            }
+        }
+    }
+
+    /**
+     * @brief This unlocks edges that were previously locked with a `temporary'
+     * lock, indicating a parallel compatibility induced locking
+     */
+    void mesh_adapter_t::remove_edge_temp_locks()
+    {
+      for (const auto& kv : tet_store.tets)
+      {
+        size_t tet_id = kv.first;
+
+        trace_out << "Process tet remove temp lock " << tet_id << std::endl;
+
+        // Only apply checks to tets on the active list
+        if (tet_store.is_active(tet_id)) {
+          // change it from temporary to unlocked
+          update_tet_edges_lock_type(tet_id, AMR::Edge_Lock_Case::temporary,
+            AMR::Edge_Lock_Case::unlocked);
+        }
+      }
+    }
+
+    void mesh_adapter_t::mark_derefinement()
+    {
+        const size_t max_num_rounds = AMR_MAX_ROUNDS;
+
+        // Mark refinements
+        size_t iter;
+        //Iterate until convergence
+        for (iter = 0; iter < max_num_rounds; iter++)
+        {
+            tet_store.marked_derefinements.get_state_changed() = false;
+
+            // set of elements which have been considered for derefinement
+            std::unordered_set< size_t > done_deref_marking;
+
+            // Loop over tets
+            for (const auto& kv : tet_store.tets)
+            {
+                // this loop only runs for active tets
+                if (!tet_store.is_active(kv.first)) {
+                  deactivate_deref_tet_edges(kv.first);
+                  continue;
+                }
+                size_t activetet_id = kv.first;
+
+                // check if activetet_id has a parent (assign to tet_id)
+                // if it does not, activetet_id is not a derefinement candidate
+                size_t tet_id;
+                const auto& activetet_data = tet_store.data(activetet_id);
+                if (!activetet_data.has_parent) {
+                  deactivate_deref_tet_edges(activetet_id);
+                  continue;
+                }
+                else {
+                  tet_id = activetet_data.parent_id;
+                }
+
+                // if already considered for deref, do not reconsider
+                if (done_deref_marking.count(tet_id) > 0) {
+                  continue;
+                }
+                done_deref_marking.insert(tet_id);
+
+                child_id_list_t children = tet_store.data(tet_id).children;
+
+                // check if any child of tet_id (i.e. any active tet) is marked
+                // for refinement
+                bool is_child_ref(false);
+                for (size_t i=0; i<children.size(); i++) {
+                  edge_list_t chedge_list = tet_store.generate_edge_keys(children[i]);
+                  // Check each edge, see if it is marked for refinement
+                  for (size_t k=0; k<NUM_TET_EDGES; k++) {
+                    edge_t edge = chedge_list[k];
+
+                    if (tet_store.edge_store.get(edge).needs_refining == 1) {
+                      is_child_ref = true;
+                      continue;
+                    }
+                  }
+                }
+                // deactivate from deref if marked for ref
+                if (is_child_ref) {
+                  trace_out << tet_id << " Looping cancelled since child marked for refinement." << std::endl;
+                  for (auto child_id : children) {
+                    deactivate_deref_tet_edges(child_id);
+                  }
+                  deactivate_deref_tet_edges(tet_id);
+                  tet_store.mark_derefinement_decision(tet_id, AMR::Derefinement_Case::skip);
+                  continue;
+                }
+
+                // check if tet_id has been marked for deref-ref
+                edge_list_t pedge_list = tet_store.generate_edge_keys(tet_id);
+                // Check each edge, see if it is marked for refinement
+                for (size_t k=0; k<NUM_TET_EDGES; k++) {
+                  edge_t edge = pedge_list[k];
+
+                  // deactivate child-edges from deref if marked '2'
+                  if (tet_store.edge_store.get(edge).needs_refining == 2) {
+                    auto edge_nodes = edge.get_data();
+                    auto ch_node = node_connectivity.data().at(edge_nodes);
+                    std::array< edge_t, 2> ch_edge;
+                    ch_edge[0] = {edge_nodes[0], ch_node};
+                    ch_edge[1] = {edge_nodes[1], ch_node};
+                    tet_store.edge_store.get(ch_edge[0]).needs_derefining = 0;
+                    tet_store.edge_store.get(ch_edge[1]).needs_derefining = 0;
+                  }
+                }
+
+                // This is useful for later inspection
+                //edge_list_t edge_list = tet_store.generate_edge_keys(tet_id);
+                std::size_t num_to_derefine = 0; // Nodes
+
+                AMR::Refinement_Case refinement_case = tet_store.get_refinement_case(tet_id);
+
+                auto derefine_node_set = refiner.find_derefine_node_set(tet_store, tet_id);
+                // Find the set of nodes which are not in the parent
+                std::unordered_set<size_t> non_parent_nodes =
+                  refiner.child_exclusive_nodes(tet_store, tet_id);
+
+                //for (auto drnode: derefine_node_set)
+                //  trace_out << "derefine node: " << drnode << std::endl;
+
+                num_to_derefine = derefine_node_set.size();
+
+                if (num_to_derefine > 0) {
+                    trace_out << "num_to_derefine " << num_to_derefine << std::endl;
+                    trace_out << "ref_case " << refinement_case << std::endl;
+                    trace_out << "num children " << children.size() << std::endl;
+                }
+
+                //num_to_derefine = convert_derefine_edges_to_points(tet_store, tet_id, num_edges_to_derefine, refinement_case);
+
+                // "If nderefine = 1
+                if (num_to_derefine == 1)
+                {
+                    // If icase = 1:2
+
+                    //if (refinement_case == AMR::Refinement_Case::one_to_two)
+                    if (children.size() == 2)
+                    {
+                        // Accept as 2:1 derefine"
+                        trace_out << "Accept as 2:1" << std::endl;
+                        //refiner.derefine_two_to_one(tet_store, node_connectivity, tet_id);
+                        tet_store.mark_derefinement_decision(tet_id, AMR::Derefinement_Case::two_to_one);
+                    }
+                    // "Else
+                    else {
+                        // Deactivate all points"
+                        for (auto child_id : children) {
+                          deactivate_deref_tet_edges(child_id);
+                        }
+                        tet_store.mark_derefinement_decision(tet_id, AMR::Derefinement_Case::skip);
+                        trace_out << "giving up on deref decision. deactivate near 2:1 ntd = 1" << std::endl;
+                    }
+                }
+
+
+                // "If nderefine = 2
+                else if (num_to_derefine == 2)
+                {
+                    // If icase = 1:4
+                    //if (refinement_case == AMR::Refinement_Case::one_to_four)
+                    if (children.size() == 4)
+                    {
+                        // Accept as 4:2 derefine"
+                        trace_out << "Accept as 4:2" << std::endl;
+                        //refiner.derefine_four_to_two(tet_store,  node_connectivity, tet_id);
+                        tet_store.mark_derefinement_decision(tet_id, AMR::Derefinement_Case::four_to_two);
+                    }
+                    // "Else
+                    else {
+                        // Deactivate all points"
+                        for (auto child_id : children) {
+                          deactivate_deref_tet_edges(child_id);
+                        }
+                        tet_store.mark_derefinement_decision(tet_id, AMR::Derefinement_Case::skip);
+                        trace_out << "giving up on deref decision. deactivate near 4:2 ntd = 2" << std::endl;
+                    }
+                }
+
+                // "If nderefine = 3
+                else if (num_to_derefine == 3)
+                {
+                    // If icase = 1:4
+                    //if (refinement_case == AMR::Refinement_Case::one_to_four)
+                    if (children.size() == 4)
+                    {
+                        // Accept as 4:1 derefine"
+                        trace_out << "Accept as 4:1" << std::endl;
+                        //refiner.derefine_four_to_one(tet_store,  node_connectivity, tet_id);
+                        tet_store.mark_derefinement_decision(tet_id, AMR::Derefinement_Case::four_to_one);
+                    }
+                    // "Else if icase = 1:8
+                    //else if (refinement_case == AMR::Refinement_Case::one_to_eight)
+                    else if (children.size() == 8)
+                    {
+                        // we have a list of (non-parent) nodes that is marked
+                        // for derefinement. First, determine the nodes that are
+                        // unmarked for derefinement (or inactive_nodes). Then,
+                        // determine if these are on a single face.
+                        std::unordered_set<size_t> inactive_node_set;
+                        for (auto npn : non_parent_nodes) {
+                          if (derefine_node_set.count(npn) == 0)
+                            inactive_node_set.insert(npn);
+                        }
+                        Assert(inactive_node_set.size() == 3, "Incorrectly "
+                          "sized inactive-node set");
+                        auto same_face = check_same_face(tet_id, inactive_node_set);
+                        // If inactive points lie on same face
+                        if (same_face.first == true)
+                        {
+                            // Accept as 8:4 derefinement
+                            trace_out << "Accept as 8:4" << std::endl;
+
+                            // create a vector of node-array-pairs to mark edges
+                            // for refinement 1:4
+                            std::vector< std::array< std::size_t, 2 > > ref_edges;
+                            trace_out << "inactive nodes on same face: ";
+                            for (auto n:inactive_node_set) {
+                              trace_out << n << ", ";
+                              ref_edges.push_back(node_connectivity.get(n));
+                            }
+                            trace_out << std::endl;
+
+                            tet_store.edge_store.mark_edges_for_deref_ref(ref_edges);
+                            //refiner.derefine_eight_to_four(tet_store,  node_connectivity, tet_id);
+                            tet_store.mark_derefinement_decision(tet_id, AMR::Derefinement_Case::eight_to_four);
+                        }
+                        // "Else
+                        else {
+                            // Deactivate all points"
+                            for (auto child_id : children) {
+                              deactivate_deref_tet_edges(child_id);
+                            }
+                            tet_store.mark_derefinement_decision(tet_id, AMR::Derefinement_Case::skip);
+                            trace_out << "giving up on deref decision. deactivate near 8:4 ntd = 3" << std::endl;
+                        }
+
+                    }
+                }
+
+                // "If nderefine = 4
+                else if (num_to_derefine == 4)
+                //else if (children.size() == 4)
+                {
+                    // we have a list of (non-parent) nodes that is marked
+                    // for derefinement. First, determine the nodes that are
+                    // unmarked for derefinement (or inactive_nodes). Then,
+                    // determine if these are on a single face.
+                    std::unordered_set<size_t> inactive_node_set;
+                    for (auto npn : non_parent_nodes) {
+                      if (derefine_node_set.count(npn) == 0)
+                        inactive_node_set.insert(npn);
+                    }
+                    Assert(inactive_node_set.size() == 2, "Incorrectly "
+                      "sized inactive-node set");
+                    // Check if the inactive point belong to the same parent
+                    // face and deactivate the third point on that face
+                    auto same_face = check_same_face(tet_id, inactive_node_set);
+
+                    if (same_face.first == true)
+                    {
+                        // deactivate the edges associated with same_face.second
+                        for (size_t i = 0; i < children.size(); i++)
+                        {
+                          edge_list_t edge_list = tet_store.generate_edge_keys(children[i]);
+                          for (size_t k = 0; k < NUM_TET_EDGES; k++)
+                          {
+                            edge_t edge = edge_list[k];
+                            size_t A = edge.first();
+                            size_t B = edge.second();
+                            if (A == same_face.second || B == same_face.second)
+                              tet_store.edge_store.get(edge).needs_derefining = false;
+                          }
+                        }
+
+                        // create a vector of node-array-pairs to mark edges
+                        // for refinement 1:4
+                        inactive_node_set.insert(same_face.second);
+                        std::vector< std::array< std::size_t, 2 > > ref_edges;
+                        for (auto n:inactive_node_set) {
+                          ref_edges.push_back(node_connectivity.get(n));<--- Consider using std::transform algorithm instead of a raw loop.
+                        }
+
+                        tet_store.edge_store.mark_edges_for_deref_ref(ref_edges);
+
+                        // Accept as 8:4 derefinement
+                        trace_out << "Accept as 8:4" << std::endl;
+                        //refiner.derefine_eight_to_four(tet_store,  node_connectivity, tet_id);
+                        tet_store.mark_derefinement_decision(tet_id, AMR::Derefinement_Case::eight_to_four);
+                    }
+                    // "Else
+                    else {
+                        // Deactivate all points"
+                        for (auto child_id : children) {
+                          deactivate_deref_tet_edges(child_id);
+                        }
+                        tet_store.mark_derefinement_decision(tet_id, AMR::Derefinement_Case::skip);
+                        trace_out << "giving up on deref decision. deactivate near 8:4 ntd = 4" << std::endl;
+                    }
+                }
+
+                // "If nderefine = 5
+                else if (num_to_derefine == 5)
+                {
+                    // Accept as 8:2 derefine"
+                    trace_out << "Accept as 8:2 " << std::endl;
+                    //refiner.derefine_eight_to_two(tet_store,  node_connectivity, tet_id);
+                    tet_store.mark_derefinement_decision(tet_id, AMR::Derefinement_Case::eight_to_two);
+                }
+
+                // "If nderefine = 6
+                else if (num_to_derefine == 6)
+                {
+                    // Accept as 8:1 derefine"
+                    trace_out << "Accept as 8:1" << std::endl;
+                    //refiner.derefine_eight_to_one(tet_store,  node_connectivity, tet_id);
+                    tet_store.mark_derefinement_decision(tet_id, AMR::Derefinement_Case::eight_to_one);
+                }
+
+                // "If nderefine = 0
+                else {
+                    tet_store.mark_derefinement_decision(tet_id, AMR::Derefinement_Case::skip);
+                    // Deactivate all points"
+                    for (auto child_id : children) {
+                      deactivate_deref_tet_edges(child_id);
+                    }
+                    trace_out << "giving up with no deref decision because nderefine = 0" << std::endl;
+                }
+            }
+
+            // If nothing changed during that round, break
+            if (!tet_store.marked_derefinements.get_state_changed())
+            {
+                trace_out << "Terminating loop at iter " << iter << std::endl;
+                break;
+            }
+            trace_out << "End iter " << iter << std::endl;
+            // clear out set of elements considered during this iteration
+            done_deref_marking.clear();
+        }
+        trace_out << "Deref Loop took " << iter << " rounds." << std::endl;
+    }
+
+    // TODO: document
+    void mesh_adapter_t::perform_derefinement()
+    {
+        trace_out << "Perform deref" << std::endl;
+
+        // Do derefinements
+        for (const auto& kv : tet_store.tets)
+        {
+            size_t tet_id = kv.first;
+            //size_t parent_id = 0;
+
+            // TODO: Do I really want to loop all tets?
+
+            // TODO: is this doing a double lookup?
+            if (tet_store.has_derefinement_decision(tet_id))
+            {
+                trace_out << "Do derefine of " << tet_id << std::endl;
+                //size_t parent_id = tet_store.get_parent_id(tet_id);
+                //trace_out << "Parent = " << parent_id << std::endl;
+                switch(tet_store.marked_derefinements.get(tet_id))
+                {
+                    case AMR::Derefinement_Case::two_to_one:
+                        refiner.derefine_two_to_one(tet_store,node_connectivity,tet_id);
+                        trace_out << "Completed derefine 2:1 of " << tet_id << std::endl;
+                        break;
+                    case AMR::Derefinement_Case::four_to_one:
+                        refiner.derefine_four_to_one(tet_store,node_connectivity,tet_id);
+                        trace_out << "Completed derefine 4:1 of " << tet_id << std::endl;
+                        break;
+                    case AMR::Derefinement_Case::four_to_two:
+                        refiner.derefine_four_to_two(tet_store,node_connectivity,tet_id);
+                        trace_out << "Completed derefine 4:2 of " << tet_id << std::endl;
+                        break;
+                    case AMR::Derefinement_Case::eight_to_one:
+                        refiner.derefine_eight_to_one(tet_store,node_connectivity,tet_id);
+                        trace_out << "Completed derefine 8:1 of " << tet_id << std::endl;
+                        break;
+                    case AMR::Derefinement_Case::eight_to_two:
+                        refiner.derefine_eight_to_two(tet_store,node_connectivity,tet_id);
+                        trace_out << "Completed derefine 8:2 of " << tet_id << std::endl;
+                        break;
+                    case AMR::Derefinement_Case::eight_to_four:
+                        refiner.derefine_eight_to_four(tet_store,node_connectivity,tet_id);
+                        trace_out << "Completed derefine 8:4 of " << tet_id << std::endl;
+                        break;
+                    case AMR::Derefinement_Case::skip:
+                        // What do we do with skip?
+                        break;
+                }
+                // Mark tet as not needing derefinement
+                tet_store.marked_derefinements.erase(tet_id);
+            }
+        }
+
+        node_connectivity.print();
+        refiner.delete_intermediates_of_children(tet_store);
+        tet_store.process_delete_list();
+        tet_store.print_node_types();
+
+        lock_intermediates();
+
+        for (auto& kv : tet_store.edge_store.edges) {
+           auto& local = kv.second;
+           local.needs_derefining = 0;
+           if (local.needs_refining == 2) local.needs_refining = 0;
+        }
+    }
+
+}
+
+#if defined(__clang__)
+  #pragma clang diagnostic pop
+#endif
 
diff --git a/Release/cppcheck/23.html b/Release/cppcheck/23.html index 076b907f0173..0bf8f63d4312 100644 --- a/Release/cppcheck/23.html +++ b/Release/cppcheck/23.html @@ -152,12 +152,12 @@
  1
@@ -289,132 +289,132 @@ 

Cppcheck report - [

// *****************************************************************************
 /*!
-  \file      src/Control/MeshConv/CmdLine/Parser.cpp
+  \file      src/Control/HelpFactory.hpp
   \copyright 2012-2015 J. Bakosi,
              2016-2018 Los Alamos National Security, LLC.,
              2019-2021 Triad National Security, LLC.
              All rights reserved. See the LICENSE file for details.
-  \brief     MeshConv's command line parser
-  \details   This file defines the command-line argument parser for the mesh
-     file converter, MeshConv.
+  \brief     Command-line and input deck help factory
+  \details   This file contains some types that facilitate the generation of
+     on-screen help.
 */
 // *****************************************************************************
-
-#include "NoWarning/pegtl.hpp"
-#include "NoWarning/charm.hpp"
-
-#include "QuinoaConfig.hpp"
-#include "Exception.hpp"
-#include "Print.hpp"
-#include "Keywords.hpp"
-#include "MeshConv/Types.hpp"
-#include "MeshConv/CmdLine/Parser.hpp"
-#include "MeshConv/CmdLine/Grammar.hpp"
-
-namespace tk {
-namespace grm {
-
-tk::Print g_print;
-
-} // grm::
-} // tk::
-
-using meshconv::CmdLineParser;
-
-CmdLineParser::CmdLineParser( int argc,
-                              char** argv,
-                              const tk::Print& print,
-                              ctr::CmdLine& cmdline ) :
-  StringParser( argc, argv )
-// *****************************************************************************
-//  Contructor: parse the command line for MeshConv
-//! \param[in] argc Number of C-style character arrays in argv
-//! \param[in] argv C-style character array of character arrays
-//! \param[in] print Pretty printer
-//! \param[inout] cmdline Command-line stack where data is stored from parsing
-// *****************************************************************************
-{
-  // Create CmdLine (a tagged tuple) to store parsed input
-  ctr::CmdLine cmd;
-
-  // Reset parser's output stream to that of print's. This is so that mild
-  // warnings emitted during parsing can be output using the pretty printer.
-  // Usually, errors and warnings are simply accumulated during parsing and
-  // printed during diagnostics after the parser has finished. However, in some
-  // special cases we can provide a more user-friendly message right during
-  // parsing since there is more information available to construct a more
-  // sensible message. This is done in e.g., tk::grm::store_option. Resetting
-  // the global g_print, to that of passed in as the constructor argument allows
-  // not to have to create a new pretty printer, but use the existing one.
-  tk::grm::g_print.reset( print.save() );
-
-  // Parse command line string by populating the underlying tagged tuple
-  tao::pegtl::memory_input<> in( m_string, "command line" );
-  tao::pegtl::parse< cmd::read_string, tk::grm::action >( in, cmd );
-
-  // Echo errors and warnings accumulated during parsing
-  diagnostics( print, cmd.get< tag::error >() );
-
-  // Strip command line (and its underlying tagged tuple) from PEGTL instruments
-  // and transfer it out
-  cmdline = std::move( cmd );
-
-  // If we got here, the parser has succeeded
-  print.item("Parsed command line", "success");
-
-  // Print out help on all command-line arguments if the executable was invoked
-  // without arguments or the help was requested
-  const auto helpcmd = cmdline.get< tag::help >();
-  if (argc == 1 || helpcmd) {
-    print.help< tk::QUIET >( tk::meshconv_executable(),
-                             cmdline.get< tag::cmdinfo >(),
-                             "Command-line Parameters:", "-" );
-    print.mandatory< tk::QUIET >(
-     "The '--" + kw::input().string() + " <filename>' and the "
-     "'--" + kw::output().string() + " <filename>' arguments are mandatory." );
-    print.usage< tk::QUIET >(
-      tk::meshconv_executable(),
-      tk::meshconv_executable() + " -" + *kw::input().alias() + " in.msh -" +
-        *kw::output().alias() + " out.exo",
-      "will read data from 'in.msh' (in Gmsh format) and output it to "
-      "out.exo' (in ExodusII format)" );
-  }
-
-  // Print out verbose help for a single keyword if requested
-  const auto helpkw = cmdline.get< tag::helpkw >();
-  if (!helpkw.keyword.empty())
-    print.helpkw< tk::QUIET >( tk::meshconv_executable(), helpkw );
-
-  // Print out version information if it was requested
-  const auto version = cmdline.get< tag::version >();
-  if (version)
-    print.version< tk::QUIET >( tk::meshconv_executable(),
-                                tk::quinoa_version(),
-                                tk::git_commit(),
-                                tk::copyright() );
-
-  // Print out license information if it was requested
-  const auto license = cmdline.get< tag::license >();
-  if (license)
-    print.license< tk::QUIET >( tk::meshconv_executable(), tk::license() );
+#ifndef HelpFactory_h
+#define HelpFactory_h
+
+#include <brigand/sequences/list.hpp>
+#include <brigand/algorithms/for_each.hpp>
+
+#include "PUPUtil.hpp"
+#include "Factory.hpp"
+#include "Has.hpp"
+#include "Types.hpp"
+
+namespace tk {
+namespace ctr {
+
+//! \brief Keyword information bundle
+//! \details This bundle contains the information that is used to display
+//!    on-screen help on all command-line arguments and control file keywords
+//!    for an exectuable. This struct is stored in a container that associates
+//!    keywords (used by a grammar and parser) to this struct. The container, an
+//!    runtime, std::map, is filled by the CmdLine and InputDeck objects'
+//!    constructors by one or more brigand::for_each which loops through the
+//!    set of all keywords used in a grammar. The maps are stored in the CmdLine
+//!    and InputDeck objects (which are tagged tuples) and thus can be migrated
+//!    through the network, thus the Charm++ parck/unpack routines are defined.
+//! \see Info functor used to fill the std::maps
+struct KeywordInfo {
+  std::string shortDescription;           //!< Short description
+  std::string longDescription;            //!< Long description
+  std::optional< std::string > alias;     //!< Keyword alias
+  std::optional< std::string > expt;      //!< Expected type description
+  std::optional< std::string > lower;     //!< Lower bound as string
+  std::optional< std::string > upper;     //!< Upper bound as string
+  std::optional< std::string > choices;   //!< Expected choices description
+
+  /** @name Pack/Unpack: Serialize KeywordInfo object for Charm++ */
+  ///@{
+  //! \brief Pack/Unpack serialize member function
+  //! \param[in,out] p Charm++'s PUP::er serializer object reference
+  void pup( PUP::er& p ) {<--- Parameter 'p' can be declared with const
+    p | shortDescription;
+    p | longDescription;
+    p | alias;
+    p | expt;
+    p | lower;
+    p | upper;
+    p | choices;
+  }
+  //! \brief Pack/Unpack serialize operator|
+  //! \param[in,out] p Charm++'s PUP::er serializer object reference
+  //! \param[in,out] info KeywordInfo object reference
+  friend void operator|( PUP::er& p, KeywordInfo& info ) { info.pup(p); }
+  ///@}
+};
+
+//! \brief A typedef for associating a keyword-string with its associated
+//!   information stored in a KeywordInfo struct
+using HelpFactory = std::map< std::string, KeywordInfo >;
+
+//! \brief Help bundle on a single keyword
+//! \details This is used for delivering help on a single keyword. This struct
+//!    also differentiates between command-line arguments and control file
+//!    keywords.
+struct HelpKw {
+  HelpFactory::key_type keyword;        //!< Keyword string
+  HelpFactory::mapped_type info;        //!< Keyword information
+  bool cmd;                             //!< True if command-line keyword
+
+  /** @name Pack/Unpack: Serialize HelpKw object for Charm++ */
+  ///@{
+  //! \brief Pack/Unpack serialize member function
+  //! \param[in,out] p Charm++'s PUP::er serializer object reference
+  void pup( PUP::er& p ) { p|keyword; p|info; p|cmd; }<--- Parameter 'p' can be declared with const
+  //! \brief Pack/Unpack serialize operator|
+  //! \param[in,out] p Charm++'s PUP::er serializer object reference
+  //! \param[in,out] h HelpKw object reference
+  friend void operator|( PUP::er& p, HelpKw& h ) { h.pup(p); }
+  ///@}
+};
+
+//! \brief Function object for filling a HelpFactory (std::map) with keywords
+//!   and their associated information bundle
+//! \details This struct is used as a functor to loop through a set of keywords
+//!   at compile-time and generate code for filling up the std::map.
+struct Info {
+  //! Store reference to map we are filling
+  tk::ctr::HelpFactory& m_factory;
+  //! Constructor: store reference to map to fill
+  explicit Info( tk::ctr::HelpFactory& factory ) : m_factory( factory ) {}
+  //! \brief Function call operator templated on the type that does the filling
+  template< typename U > void operator()( brigand::type_<U> ) {
+    m_factory[ U::string() ] = { U::shortDescription(),
+                                 U::longDescription(),
+                                 U::alias(),
+                                 U::expt(),
+                                 U::lower(),
+                                 U::upper(),
+                                 U::choices() };
+  }
 
-  // Immediately exit if any help was output or was called without any argument
-  // or version or license info was requested with zero exit code
-  if (argc == 1 || helpcmd || !helpkw.keyword.empty() || version || license)
-    CkExit();
-
-  // Make sure mandatory arguments are set
-  auto ialias = kw::input().alias();
-  auto oalias = kw::output().alias();<--- Variable 'oalias' is assigned a value that is never used.
-  ErrChk( !(cmdline.get< tag::io, tag::input >().empty()),
-          "Mandatory input file not specified. "
-          "Use '--" + kw::input().string() + " <filename>'" +
-          ( ialias ? " or '-" + *ialias + " <filename>'" : "" ) + '.' );
-  ErrChk( !(cmdline.get< tag::io, tag::output >().empty()),
-          "Mandatory output file not specified. "
-          "Use '--" + kw::output().string() + " <filename>'" +
-          ( oalias ? " or '-" + *oalias + " <filename>'" : "" ) + '.' );
-}
+  //! Fill map in a simpler way passing a string rather than a brigand-type
+  void fill( const tk::entry_t& kw )
+  {
+    m_factory[kw.string()] = { kw.shortDescription(),
+                               kw.longDescription(),
+                               kw.alias(),
+                               kw.expt(),
+                               kw.lower(),
+                               kw.upper(),
+                               kw.choices() };
+  }
+};
+
+} // ctr::
+} // tk::
+
+#endif // HelpFactory_h
 
diff --git a/Release/cppcheck/24.html b/Release/cppcheck/24.html index 9ab14c57b4e5..be89a12b4797 100644 --- a/Release/cppcheck/24.html +++ b/Release/cppcheck/24.html @@ -152,12 +152,12 @@
  1
@@ -328,245 +328,175 @@ 

Cppcheck report - [

// *****************************************************************************
+169
// *****************************************************************************
 /*!
-  \file      src/Main/MeshConvDriver.cpp
+  \file      src/Main/MeshConv.cpp
   \copyright 2012-2015 J. Bakosi,
              2016-2018 Los Alamos National Security, LLC.,
              2019-2021 Triad National Security, LLC.
              All rights reserved. See the LICENSE file for details.
-  \brief     Mesh converter driver
-  \details   Mesh converter driver.
-*/
-// *****************************************************************************
-
-#include "Types.hpp"
-#include "Tags.hpp"
-#include "MeshConvDriver.hpp"
-#include "MeshFactory.hpp"
-#include "Writer.hpp"
-
-#include "NoWarning/meshconv.decl.h"
-
-using meshconv::MeshConvDriver;
-
-extern CProxy_Main mainProxy;
-
-MeshConvDriver::MeshConvDriver( const ctr::CmdLine& cmdline, int ) :
-  m_print( cmdline.logname( cmdline.get< tag::io, tag::screen >(),
-                            cmdline.get< tag::io, tag::nrestart >() ),
-           cmdline.get< tag::verbose >() ? std::cout : std::clog,
-           std::ios_base::app ),
-  m_reorder( cmdline.get< tag::reorder >() ),
-  m_input(),
-  m_output()
-// *****************************************************************************
-//  Constructor
-//! \param[in] cmdline Command line object storing data parsed from the command
-//!   line arguments
-// *****************************************************************************
-{
-  // Save input file name
-  m_input = cmdline.get< tag::io, tag::input >();
-  // Save output file name
-  m_output = cmdline.get< tag::io, tag::output >();
-}
+  \brief     Mesh file converter Charm++ main chare
+  \details   Mesh file converter Charm++ main chare. This file contains the
+    definition of the Charm++ main chare, equivalent to main() in Charm++-land.
+*/
+// *****************************************************************************
+
+#include <vector>
+#include <utility>
+#include <iostream>
+
+#include "Print.hpp"
+#include "Timer.hpp"
+#include "Types.hpp"
+#include "QuinoaConfig.hpp"
+#include "Init.hpp"
+#include "Tags.hpp"
+#include "MeshConvDriver.hpp"
+#include "MeshConv/CmdLine/CmdLine.hpp"
+#include "MeshConv/CmdLine/Parser.hpp"
+#include "ProcessException.hpp"
+#include "ChareStateCollector.hpp"
+
+#include "NoWarning/charm.hpp"
+#include "NoWarning/meshconv.decl.h"
+
+#if defined(__clang__)
+  #pragma clang diagnostic push
+  #pragma clang diagnostic ignored "-Wmissing-variable-declarations"
+#endif
+
+//! \brief Charm handle to the main proxy, facilitates call-back to finalize,
+//!    etc., must be in global scope, unique per executable
+CProxy_Main mainProxy;
+
+//! Chare state collector Charm++ chare group proxy
+tk::CProxy_ChareStateCollector stateProxy;
 
-void
-MeshConvDriver::execute() const
-// *****************************************************************************
-//  Execute: Convert mesh file
-// *****************************************************************************
-{
-  m_print.endsubsection();
-
-  std::vector< std::pair< std::string, tk::real > > times;
+//! If true, call and stack traces are to be output with exceptions
+//! \note This is true by default so that the trace is always output between
+//!   program start and the Main ctor in which the user-input from command line
+//!   setting for this overrides this true setting.
+bool g_trace = true;
+
+#if defined(__clang__)
+  #pragma clang diagnostic pop
+#endif
 
-  // If input filename contains a '%', we aggregate multiple files
-  if (m_input.find('%') == std::string::npos) {
-
-    // Convert single mesh
-
-    times.push_back( {} );
-    auto mesh = tk::readUnsMesh( m_print, m_input, times[0] );
-    auto wtimes = tk::writeUnsMesh( m_print, m_output, mesh, m_reorder );
-    times.insert( end(times), begin(wtimes), end(wtimes) );
-
-  } else {
-
-    // Aggregate multiple meshes containing surface output
-
-    // Find a '%' sign in the input filename, and assuming a syntax of
-    // '.<nfile>.%', find '<nfile>' as the number of files to aggregate.
-    auto percent_pos = m_input.find( '%' );
-    auto input_basename = m_input.substr( 0, percent_pos );
-    auto dot1 = m_input.find_last_of( '.', percent_pos );
-    auto dot2 = m_input.find_last_of( '.', dot1-1 );
-    auto nfile_str = m_input.substr( dot2+1, dot1-dot2-1  );
-    std::stringstream ss( nfile_str );
-    if (nfile_str.empty())
-      Throw( "The percent sign must be followed by an "
-             "integer, the number of files to aggregate" );
-    std::size_t nfile;
-    ss >> nfile;
-    m_print.diag( "Aggregating " + std::to_string(nfile) +
-                  " files from base filename: '" + input_basename +'\'' );
-
-    const auto eps = std::numeric_limits< tk::real >::epsilon();
-
-    // Lambda to echo some diagnostics on the mesh being processes to screen
-    auto diag = [&]( const std::string& name, const tk::UnsMesh& mesh ){
-      m_print.diag( name + ": ntri: " +
-        std::to_string(mesh.triinpoel().size()/3) +
-        ", ntime: " + std::to_string(mesh.vartimes().size()) +
-        (!mesh.nodevars().empty() ? ", node_var: " +
-           std::to_string(mesh.nodevars()[0].size()) : "") +
-        (!mesh.nodevars()[0].empty() ? ", npoin: " +
-           std::to_string(mesh.nodevars()[0][0].size()) : "") +
-        (!mesh.elemvars().empty() ? ", elem_var: " +
-           std::to_string(mesh.elemvars()[0].size()) : "") +
-        (!mesh.elemvars()[0].empty() ? ", nelem: " +
-           std::to_string(mesh.elemvars()[0][0].size()) : "") );
-    };
-
-    // Output-mesh containers, will store aggregated surface(s) and field output
-    tk::UnsMesh::Coords coords;
-    auto& X = coords[0];
-    auto& Y = coords[1];
-    auto& Z = coords[2];
-    std::size_t npoin = 0;
-    std::size_t nelem = 0;
-    std::vector< std::size_t > otriinpoel;
-    std::vector< std::string > nodevarnames;
-    std::vector< std::string > elemvarnames;
-    std::vector< tk::real > vartimes;
-    std::vector< std::vector< std::vector< tk::real > > > nodevars;
-    std::vector< std::vector< std::vector< tk::real > > > elemvars;
-    // Counter for number of non-empty meshes processed
-    std::size_t k = 0;
-    for (std::size_t m=0; m<nfile; ++m) {
-      std::string name = input_basename + std::to_string(m);
-      times.push_back( {} );
-      auto mesh = tk::readUnsMesh( m_print, name, times.back() );
-      const auto& triinpoel = mesh.triinpoel();
-      // Skip meshes with a single triange cell
-      if (triinpoel.size() == 3) continue;
-      const auto& x = mesh.x();
-      const auto& y = mesh.y();
-      const auto& z = mesh.z();
-      nodevarnames = mesh.nodevarnames();
-      elemvarnames = mesh.elemvarnames();
-      vartimes = mesh.vartimes();
-      // Echo some diagnostics on the mesh being processes to screen
-      diag( name, mesh );
-      // Aggregate data from each triangle element in mesh
-      for (std::size_t e=0; e<triinpoel.size()/3; ++e) {
-        for (std::size_t n=0; n<3; ++n) {
-          auto j = triinpoel[ e*3+n ];
-          bool visited = false;
-          // WARNING: linear search below, will not scale well
-          for (std::size_t i=0; i<X.size(); ++i) {
-            // If mesh point has already been seen (on a previous mesh)
-            if (std::abs(x[j]-X[i]) < eps &&
-                std::abs(y[j]-Y[i]) < eps &&
-                std::abs(z[j]-Z[i]) < eps)
-            { // no point in connectivity but nothing else
-              visited = true;
-              otriinpoel.push_back( i );
-            }
-          }
-          if (!visited) { // Mesh point not yet seen
-            // save coordinates and (global) point id in aggregated connectivity
-            X.push_back( x[j] );
-            Y.push_back( y[j] );
-            Z.push_back( z[j] );
-            otriinpoel.push_back( npoin );
-            // aggregate nodal field data for all times and variables
-            std::size_t time = 0;
-            std::size_t varid = 0;
-            for (const auto& t : mesh.nodevars()) {  // for all times
-              if (k == 0 && npoin == 0) nodevars.push_back( {} );
-              for (const auto& v : t) {              // for all variables
-                if (k == 0 && npoin == 0) nodevars.back().push_back( {} );
-                nodevars[time][varid].push_back( v[j] );
-                ++varid;
-              }
-              ++time;
-              varid = 0;
-            }
-            ++npoin;      // increase number of nodes in output mesh
-          }
-        }
-
-        // aggregate elemental field data for all times and variables
-        std::size_t etime = 0;
-        std::size_t evarid = 0;
-        for (const auto& t : mesh.elemvars()) {  // for all times
-          if (k == 0 && nelem == 0) elemvars.push_back( {} );
-          for (const auto& v : t) {              // for all variables
-            if (k == 0 && nelem == 0) elemvars.back().push_back( {} );
-            elemvars[etime][evarid].push_back( v[e] );
-            ++evarid;
-          }
-          ++etime;
-          evarid = 0;
-        }
-        ++nelem;    // increase number of elements in output mesh
-      }
-      ++k;        // increase number of non-empty meshes processed
-    }
-
-    // Construct aggregated output mesh
-    tk::UnsMesh outmesh( coords, otriinpoel, nodevarnames, elemvarnames,
-      vartimes, nodevars, elemvars );
-    // Echo diagnostics on the aggreegate output mesh
-    diag( m_output, outmesh );
-    // Write output mesh to file
-    auto wtimes = tk::writeUnsMesh( m_print, m_output, outmesh, m_reorder );
-    // Collect wall-clock time data
-    times.insert( end(times), begin(wtimes), end(wtimes) );
-
-  }
-
-  mainProxy.timestamp( times );
-
-  mainProxy.finalize();
-}
+//! \brief Charm++ main chare for the mesh converter executable, meshconv.
+//! \details Note that this object should not be in a namespace.
+// cppcheck-suppress noConstructor
+class Main : public CBase_Main {<--- Unmatched suppression: noConstructor
+
+  public:
+    //! \brief Constructor
+    //! \details MeshConv's main chare constructor is the entry point of the
+    //!   program, called by the Charm++ runtime system. The constructor does
+    //!   basic initialization steps, e.g., parser the command-line, prints out
+    //!   some useful information to screen (in verbose mode), and instantiates
+    //!   a driver. Since Charm++ is fully asynchronous, the constructor
+    //!   usually spawns asynchronous objects and immediately exits. Thus in the
+    //!   body of the main chare constructor we fire up an 'execute' chare,
+    //!   which then calls back to Main::execute(). Finishing the main chare
+    //!   constructor the Charm++ runtime system then starts the
+    //!   network-migration of all global-scope data (if any). The execute chare
+    //!   calling back to Main::execute() signals the end of the migration of
+    //!   the global-scope data. Then we are ready to execute the driver which
+    //!   calls back to Main::finalize() when it finished. Then finalize() exits
+    //!   by calling Charm++'s CkExit(), shutting down the runtime system.
+    //! \see http://charm.cs.illinois.edu/manuals/html/charm++/manual.html
+    Main( CkArgMsg* msg )
+    try :
+      m_signal( tk::setSignalHandlers() ),
+      m_cmdline(),
+      // Parse command line into m_cmdline using default simple pretty printer
+      m_cmdParser( msg->argc, msg->argv, tk::Print(), m_cmdline ),
+      // Create MeshConv driver
+      m_driver( tk::Main< meshconv::MeshConvDriver >
+                        ( msg->argc, msg->argv,
+                          m_cmdline,
+                          tk::HeaderType::MESHCONV,
+                          tk::meshconv_executable(),
+                          m_cmdline.get< tag::io, tag::screen >(),
+                          m_cmdline.get< tag::io, tag::nrestart >() ) ),
+      m_timer(1),       // Start new timer measuring the total runtime
+      m_timestamp()
+    {
+      delete msg;
+      g_trace = m_cmdline.get< tag::trace >();
+      tk::MainCtor( mainProxy, thisProxy, m_timer, m_cmdline,
+                    CkCallback( CkIndex_Main::quiescence(), thisProxy ) );
+      // If quiescence detection is on or user requested it, create chare state
+      // collector Charm++ chare group
+      if ( m_cmdline.get< tag::chare >() || m_cmdline.get< tag::quiescence >() )
+        stateProxy = tk::CProxy_ChareStateCollector::ckNew();
+      // Fire up an asynchronous execute object, which when created at some
+      // future point in time will call back to this->execute(). This is
+      // necessary so that this->execute() can access already migrated
+      // global-scope data.
+      CProxy_execute::ckNew();
+    } catch (...) { tk::processExceptionCharm(); }
+
+    void execute() {
+      try {
+        m_timestamp.emplace_back("Migrate global-scope data", m_timer[1].hms());
+        m_driver.execute();
+      } catch (...) { tk::processExceptionCharm(); }
+    }
+
+    //! Towards normal exit but collect chare state first (if any)
+    void finalize() {
+      tk::finalize( m_cmdline, m_timer, stateProxy, m_timestamp,
+        m_cmdline.get< tag::io, tag::screen >(),
+        m_cmdline.get< tag::io, tag::nrestart >(),
+        CkCallback( CkIndex_Main::dumpstate(nullptr), thisProxy ) );
+    }
+
+    //! Add a time stamp contributing to final timers output
+    void timestamp( std::string label, tk::real stamp ) {
+      try {
+        m_timestamp.emplace_back( label, tk::hms( stamp ) );
+      } catch (...) { tk::processExceptionCharm(); }
+    }
+    //! Add multiple time stamps contributing to final timers output
+    void timestamp( const std::vector< std::pair< std::string, tk::real > >& s )
+    { for (const auto& t : s) timestamp( t.first, t.second ); }
+
+    //! Entry method triggered when quiescence is detected
+    void quiescence() {
+      try {
+        stateProxy.collect( /* error= */ true,
+          CkCallback( CkIndex_Main::dumpstate(nullptr), thisProxy ) );
+      } catch (...) { tk::processExceptionCharm(); }
+    }
+
+    //! Dump chare state
+    void dumpstate( CkReductionMsg* msg ) {
+      tk::dumpstate( m_cmdline,
+        m_cmdline.get< tag::io, tag::screen >(),
+        m_cmdline.get< tag::io, tag::nrestart >(),
+        msg );
+    }
+
+  private:
+    int m_signal;                               //!< Used to set signal handlers
+    meshconv::ctr::CmdLine m_cmdline;           //!< Command line
+    meshconv::CmdLineParser m_cmdParser;        //!< Command line parser
+    meshconv::MeshConvDriver m_driver;          //!< Driver
+    std::vector< tk::Timer > m_timer;           //!< Timers
+
+    //! Time stamps in h:m:s with labels
+    std::vector< std::pair< std::string, tk::Timer::Watch > > m_timestamp;
+};
+
+//! \brief Charm++ chare execute
+//! \details By the time this object is constructed, the Charm++ runtime system
+//!    has finished migrating all global-scoped read-only objects which happens
+//!    after the main chare constructor has finished.
+class execute : public CBase_execute {
+  public: execute() { mainProxy.execute(); }
+};
+
+#include "NoWarning/meshconv.def.h"
 
diff --git a/Release/cppcheck/25.html b/Release/cppcheck/25.html index 966c06532a9b..1f374c8f62d4 100644 --- a/Release/cppcheck/25.html +++ b/Release/cppcheck/25.html @@ -152,3237 +152,269 @@
- - + @@ -87,47 +87,47 @@ 13 : : 14 : : #include "PUPAMR.hpp" 15 : : - 16 : 3620053 : void PUP::pup( PUP::er &p, AMR::Refinement_State& s ) + 16 : 3630532 : void PUP::pup( PUP::er &p, AMR::Refinement_State& s ) 17 : : // ***************************************************************************** 18 : : // Pack/Unpack Refinement_State 19 : : //! \param[in] p Charm++'s pack/unpack object 20 : : //! \param[in,out] s Refinement_State object reference 21 : : // ***************************************************************************** 22 : : { - 23 : 3620053 : p | s.active_element_number; - 24 : 3620053 : p | s.refinement_case; - 25 : 3620053 : p | s.children; - 26 : 3620053 : p | s.refinement_level; - 27 : 3620053 : p | s.child_number; - 28 : 3620053 : p | s.parent_id; - 29 : 3620053 : p | s.normal; - 30 : 3620053 : } + 23 : 3630532 : p | s.active_element_number; + 24 : 3630532 : p | s.refinement_case; + 25 : 3630532 : p | s.children; + 26 : 3630532 : p | s.refinement_level; + 27 : 3630532 : p | s.child_number; + 28 : 3630532 : p | s.parent_id; + 29 : 3630532 : p | s.normal; + 30 : 3630532 : } 31 : : - 32 : 6225622 : void PUP::pup( PUP::er &p, AMR::Edge_Refinement& e ) + 32 : 6227284 : void PUP::pup( PUP::er &p, AMR::Edge_Refinement& e ) 33 : : // ***************************************************************************** 34 : : // Pack/Unpack Edge_Refinement 35 : : //! \param[in] p Charm++'s pack/unpack object 36 : : //! \param[in,out] e Edge_Refinement object reference 37 : : // ***************************************************************************** 38 : : { - 39 : 6225622 : p | e.A; - 40 : 6225622 : p | e.B; - 41 : 6225622 : p | e.needs_refining; - 42 : 6225622 : p | e.needs_derefining; - 43 : 6225622 : p | e.lock_case; - 44 : 6225622 : } + 39 : 6227284 : p | e.A; + 40 : 6227284 : p | e.B; + 41 : 6227284 : p | e.needs_refining; + 42 : 6227284 : p | e.needs_derefining; + 43 : 6227284 : p | e.lock_case; + 44 : 6227284 : } 45 : : - 46 : 24390 : void PUP::pup( PUP::er &p, AMR::edge_store_t& e ) + 46 : 24081 : void PUP::pup( PUP::er &p, AMR::edge_store_t& e ) 47 : : // ***************************************************************************** 48 : : // Pack/Unpack edge_store_t 49 : : //! \param[in] p Charm++'s pack/unpack object 50 : : //! \param[in,out] e edge_store_t object reference 51 : : // ***************************************************************************** 52 : : { - 53 : 24390 : p | e.edges; - 54 : 24390 : } + 53 : 24081 : p | e.edges; + 54 : 24081 : } 55 : : - 56 : 6225622 : void PUP::pup( PUP::er &p, AMR::edge_t& e ) + 56 : 6227284 : void PUP::pup( PUP::er &p, AMR::edge_t& e ) 57 : : // ***************************************************************************** 58 : : // Pack/Unpack edge_t 59 : : //! \param[in] p Charm++'s pack/unpack object @@ -135,7 +135,7 @@ 61 : : // ***************************************************************************** 62 : : { 63 : : p | e.get_data(); - 64 : 6225622 : } + 64 : 6227284 : } 65 : : 66 : 0 : void PUP::pup( PUP::er &p, AMR::active_element_store_t& a ) 67 : : // ***************************************************************************** @@ -157,55 +157,55 @@ 83 : : p | m.data(); 84 : 0 : } 85 : : - 86 : 24390 : void PUP::pup( PUP::er &p, AMR::id_generator_t& i ) + 86 : 24081 : void PUP::pup( PUP::er &p, AMR::id_generator_t& i ) 87 : : // ***************************************************************************** 88 : : // Pack/Unpack id_generator_t 89 : : //! \param[in] p Charm++'s pack/unpack object 90 : : //! \param[in,out] i id_generator_t object reference 91 : : // ***************************************************************************** 92 : : { - 93 : 24390 : p | i.start_id; - 94 : 24390 : p | i.next_tet_id; - 95 : 24390 : } + 93 : 24081 : p | i.start_id; + 94 : 24081 : p | i.next_tet_id; + 95 : 24081 : } 96 : : - 97 : 24390 : void PUP::pup( PUP::er &p, AMR::tet_store_t& t ) + 97 : 24081 : void PUP::pup( PUP::er &p, AMR::tet_store_t& t ) 98 : : // ***************************************************************************** 99 : : // Pack/Unpack tet_store_t 100 : : //! \param[in] p Charm++'s pack/unpack object 101 : : //! \param[in,out] t tet_store_t object reference 102 : : // ***************************************************************************** 103 : : { - 104 : 24390 : p | t.center_tets; - 105 : 24390 : p | t.delete_list; + 104 : 24081 : p | t.center_tets; + 105 : 24081 : p | t.delete_list; 106 : : p | t.active_elements.data(); 107 : : p | t.master_elements.data(); - 108 : 24390 : p | t.active_tetinpoel; - 109 : 24390 : p | t.active_nodes; - 110 : 24390 : p | t.id_generator; - 111 : 24390 : p | t.intermediate_list; - 112 : 24390 : p | t.active_id_mapping; - 113 : 24390 : p | t.tets; - 114 : 24390 : p | t.edge_store; - 115 : 24390 : p | t.marked_refinements; - 116 : 24390 : p | t.marked_derefinements; - 117 : 24390 : } + 108 : 24081 : p | t.active_tetinpoel; + 109 : 24081 : p | t.active_nodes; + 110 : 24081 : p | t.id_generator; + 111 : 24081 : p | t.intermediate_list; + 112 : 24081 : p | t.active_id_mapping; + 113 : 24081 : p | t.tets; + 114 : 24081 : p | t.edge_store; + 115 : 24081 : p | t.marked_refinements; + 116 : 24081 : p | t.marked_derefinements; + 117 : 24081 : } 118 : : - 119 : 24390 : void PUP::pup( PUP::er &p, AMR::mesh_adapter_t& m ) + 119 : 24081 : void PUP::pup( PUP::er &p, AMR::mesh_adapter_t& m ) 120 : : // ***************************************************************************** 121 : : // Pack/Unpack mesh_adapter_t 122 : : //! \param[in] p Charm++'s pack/unpack object 123 : : //! \param[in,out] m mesh_adapter_t object reference 124 : : // ***************************************************************************** 125 : : { - 126 : 24390 : p | m.derefinement_cut_off; - 127 : 24390 : p | m.refinement_cut_off; - 128 : 24390 : p | m.tet_store; - 129 : 24390 : p | m.node_connectivity; + 126 : 24081 : p | m.derefinement_cut_off; + 127 : 24081 : p | m.refinement_cut_off; + 128 : 24081 : p | m.tet_store; + 129 : 24081 : p | m.node_connectivity; 130 : : #ifdef ENABLE_NODE_STORE 131 : : p | m.node_store; 132 : : #endif - 133 : 24390 : p | m.refiner; - 134 : 24390 : } + 133 : 24081 : p | m.refiner; + 134 : 24081 : } 135 : : 136 : : #ifdef ENABLE_NODE_STORE 137 : : void PUP::pup( PUP::er &p, AMR::node_store_t& n ) @@ -222,7 +222,7 @@ 148 : : #endif 149 : : 150 : : - 151 : 24390 : void PUP::pup( PUP::er &p, AMR::node_connectivity_t& n ) + 151 : 24081 : void PUP::pup( PUP::er &p, AMR::node_connectivity_t& n ) 152 : : // ***************************************************************************** 153 : : // Pack/Unpack node_connectivity_t 154 : : //! \param[in] p Charm++'s pack/unpack object @@ -231,18 +231,18 @@ 157 : : { 158 : : p | n.data(); 159 : : p | n.inv_data(); - 160 : 24390 : p | n.empty_node_count; - 161 : 24390 : } + 160 : 24081 : p | n.empty_node_count; + 161 : 24081 : } 162 : : - 163 : 24390 : void PUP::pup( PUP::er &p, AMR::refinement_t& r ) + 163 : 24081 : void PUP::pup( PUP::er &p, AMR::refinement_t& r ) 164 : : // ***************************************************************************** 165 : : // Pack/Unpack refinement_t 166 : : //! \param[in] p Charm++'s pack/unpack object 167 : : //! \param[in,out] r refinement_t object reference 168 : : // ***************************************************************************** 169 : : { - 170 : 24390 : p | r.MAX_REFINEMENT_LEVEL; - 171 : 24390 : } + 170 : 24081 : p | r.MAX_REFINEMENT_LEVEL; + 171 : 24081 : } diff --git a/Release/test_coverage/Inciter/PUPAMR.hpp.func-sort-c.html b/Release/test_coverage/Inciter/PUPAMR.hpp.func-sort-c.html index bbd01c5327a6..7f1cdab4ec12 100644 --- a/Release/test_coverage/Inciter/PUPAMR.hpp.func-sort-c.html +++ b/Release/test_coverage/Inciter/PUPAMR.hpp.func-sort-c.html @@ -33,7 +33,7 @@ - + @@ -73,11 +73,11 @@ - + - +
   1
-   2
-   3
-   4
-   5
-   6
-   7
-   8
-   9
-  10
-  11
-  12
-  13
-  14
-  15
-  16
-  17
-  18
-  19
-  20
-  21
-  22
-  23
-  24
-  25
-  26
-  27
-  28
-  29
-  30
-  31
-  32
-  33
-  34
-  35
-  36
-  37
-  38
-  39
-  40
-  41
-  42
-  43
-  44
-  45
-  46
-  47
-  48
-  49
-  50
-  51
-  52
-  53
-  54
-  55
-  56
-  57
-  58
-  59
-  60
-  61
-  62
-  63
-  64
-  65
-  66
-  67
-  68
-  69
-  70
-  71
-  72
-  73
-  74
-  75
-  76
-  77
-  78
-  79
-  80
-  81
-  82
-  83
-  84
-  85
-  86
-  87
-  88
-  89
-  90
-  91
-  92
-  93
-  94
-  95
-  96
-  97
-  98
-  99
- 100
- 101
- 102
- 103
- 104
- 105
- 106
- 107
- 108
- 109
- 110
- 111
- 112
- 113
- 114
- 115
- 116
- 117
- 118
- 119
- 120
- 121
- 122
- 123
- 124
- 125
- 126
- 127
- 128
- 129
- 130
- 131
- 132
- 133
- 134
- 135
- 136
- 137
- 138
- 139
- 140
- 141
- 142
- 143
- 144
- 145
- 146
- 147
- 148
- 149
- 150
- 151
- 152
- 153
- 154
- 155
- 156
- 157
- 158
- 159
- 160
- 161
- 162
- 163
- 164
- 165
- 166
- 167
- 168
- 169
- 170
- 171
- 172
- 173
- 174
- 175
- 176
- 177
- 178
- 179
- 180
- 181
- 182
- 183
- 184
- 185
- 186
- 187
- 188
- 189
- 190
- 191
- 192
- 193
- 194
- 195
- 196
- 197
- 198
- 199
- 200
- 201
- 202
- 203
- 204
- 205
- 206
- 207
- 208
- 209
- 210
- 211
- 212
- 213
- 214
- 215
- 216
- 217
- 218
- 219
- 220
- 221
- 222
- 223
- 224
- 225
- 226
- 227
- 228
- 229
- 230
- 231
- 232
- 233
- 234
- 235
- 236
- 237
- 238
- 239
- 240
- 241
- 242
- 243
- 244
- 245
- 246
- 247
- 248
- 249
- 250
- 251
- 252
- 253
- 254
- 255
- 256
- 257
- 258
- 259
- 260
- 261
- 262
- 263
- 264
- 265
- 266
- 267
- 268
- 269
- 270
- 271
- 272
- 273
- 274
- 275
- 276
- 277
- 278
- 279
- 280
- 281
- 282
- 283
- 284
- 285
- 286
- 287
- 288
- 289
- 290
- 291
- 292
- 293
- 294
- 295
- 296
- 297
- 298
- 299
- 300
- 301
- 302
- 303
- 304
- 305
- 306
- 307
- 308
- 309
- 310
- 311
- 312
- 313
- 314
- 315
- 316
- 317
- 318
- 319
- 320
- 321
- 322
- 323
- 324
- 325
- 326
- 327
- 328
- 329
- 330
- 331
- 332
- 333
- 334
- 335
- 336
- 337
- 338
- 339
- 340
- 341
- 342
- 343
- 344
- 345
- 346
- 347
- 348
- 349
- 350
- 351
- 352
- 353
- 354
- 355
- 356
- 357
- 358
- 359
- 360
- 361
- 362
- 363
- 364
- 365
- 366
- 367
- 368
- 369
- 370
- 371
- 372
- 373
- 374
- 375
- 376
- 377
- 378
- 379
- 380
- 381
- 382
- 383
- 384
- 385
- 386
- 387
- 388
- 389
- 390
- 391
- 392
- 393
- 394
- 395
- 396
- 397
- 398
- 399
- 400
- 401
- 402
- 403
- 404
- 405
- 406
- 407
- 408
- 409
- 410
- 411
- 412
- 413
- 414
- 415
- 416
- 417
- 418
- 419
- 420
- 421
- 422
- 423
- 424
- 425
- 426
- 427
- 428
- 429
- 430
- 431
- 432
- 433
- 434
- 435
- 436
- 437
- 438
- 439
- 440
- 441
- 442
- 443
- 444
- 445
- 446
- 447
- 448
- 449
- 450
- 451
- 452
- 453
- 454
- 455
- 456
- 457
- 458
- 459
- 460
- 461
- 462
- 463
- 464
- 465
- 466
- 467
- 468
- 469
- 470
- 471
- 472
- 473
- 474
- 475
- 476
- 477
- 478
- 479
- 480
- 481
- 482
- 483
- 484
- 485
- 486
- 487
- 488
- 489
- 490
- 491
- 492
- 493
- 494
- 495
- 496
- 497
- 498
- 499
- 500
- 501
- 502
- 503
- 504
- 505
- 506
- 507
- 508
- 509
- 510
- 511
- 512
- 513
- 514
- 515
- 516
- 517
- 518
- 519
- 520
- 521
- 522
- 523
- 524
- 525
- 526
- 527
- 528
- 529
- 530
- 531
- 532
- 533
- 534
- 535
- 536
- 537
- 538
- 539
- 540
- 541
- 542
- 543
- 544
- 545
- 546
- 547
- 548
- 549
- 550
- 551
- 552
- 553
- 554
- 555
- 556
- 557
- 558
- 559
- 560
- 561
- 562
- 563
- 564
- 565
- 566
- 567
- 568
- 569
- 570
- 571
- 572
- 573
- 574
- 575
- 576
- 577
- 578
- 579
- 580
- 581
- 582
- 583
- 584
- 585
- 586
- 587
- 588
- 589
- 590
- 591
- 592
- 593
- 594
- 595
- 596
- 597
- 598
- 599
- 600
- 601
- 602
- 603
- 604
- 605
- 606
- 607
- 608
- 609
- 610
- 611
- 612
- 613
- 614
- 615
- 616
- 617
- 618
- 619
- 620
- 621
- 622
- 623
- 624
- 625
- 626
- 627
- 628
- 629
- 630
- 631
- 632
- 633
- 634
- 635
- 636
- 637
- 638
- 639
- 640
- 641
- 642
- 643
- 644
- 645
- 646
- 647
- 648
- 649
- 650
- 651
- 652
- 653
- 654
- 655
- 656
- 657
- 658
- 659
- 660
- 661
- 662
- 663
- 664
- 665
- 666
- 667
- 668
- 669
- 670
- 671
- 672
- 673
- 674
- 675
- 676
- 677
- 678
- 679
- 680
- 681
- 682
- 683
- 684
- 685
- 686
- 687
- 688
- 689
- 690
- 691
- 692
- 693
- 694
- 695
- 696
- 697
- 698
- 699
- 700
- 701
- 702
- 703
- 704
- 705
- 706
- 707
- 708
- 709
- 710
- 711
- 712
- 713
- 714
- 715
- 716
- 717
- 718
- 719
- 720
- 721
- 722
- 723
- 724
- 725
- 726
- 727
- 728
- 729
- 730
- 731
- 732
- 733
- 734
- 735
- 736
- 737
- 738
- 739
- 740
- 741
- 742
- 743
- 744
- 745
- 746
- 747
- 748
- 749
- 750
- 751
- 752
- 753
- 754
- 755
- 756
- 757
- 758
- 759
- 760
- 761
- 762
- 763
- 764
- 765
- 766
- 767
- 768
- 769
- 770
- 771
- 772
- 773
- 774
- 775
- 776
- 777
- 778
- 779
- 780
- 781
- 782
- 783
- 784
- 785
- 786
- 787
- 788
- 789
- 790
- 791
- 792
- 793
- 794
- 795
- 796
- 797
- 798
- 799
- 800
- 801
- 802
- 803
- 804
- 805
- 806
- 807
- 808
- 809
- 810
- 811
- 812
- 813
- 814
- 815
- 816
- 817
- 818
- 819
- 820
- 821
- 822
- 823
- 824
- 825
- 826
- 827
- 828
- 829
- 830
- 831
- 832
- 833
- 834
- 835
- 836
- 837
- 838
- 839
- 840
- 841
- 842
- 843
- 844
- 845
- 846
- 847
- 848
- 849
- 850
- 851
- 852
- 853
- 854
- 855
- 856
- 857
- 858
- 859
- 860
- 861
- 862
- 863
- 864
- 865
- 866
- 867
- 868
- 869
- 870
- 871
- 872
- 873
- 874
- 875
- 876
- 877
- 878
- 879
- 880
- 881
- 882
- 883
- 884
- 885
- 886
- 887
- 888
- 889
- 890
- 891
- 892
- 893
- 894
- 895
- 896
- 897
- 898
- 899
- 900
- 901
- 902
- 903
- 904
- 905
- 906
- 907
- 908
- 909
- 910
- 911
- 912
- 913
- 914
- 915
- 916
- 917
- 918
- 919
- 920
- 921
- 922
- 923
- 924
- 925
- 926
- 927
- 928
- 929
- 930
- 931
- 932
- 933
- 934
- 935
- 936
- 937
- 938
- 939
- 940
- 941
- 942
- 943
- 944
- 945
- 946
- 947
- 948
- 949
- 950
- 951
- 952
- 953
- 954
- 955
- 956
- 957
- 958
- 959
- 960
- 961
- 962
- 963
- 964
- 965
- 966
- 967
- 968
- 969
- 970
- 971
- 972
- 973
- 974
- 975
- 976
- 977
- 978
- 979
- 980
- 981
- 982
- 983
- 984
- 985
- 986
- 987
- 988
- 989
- 990
- 991
- 992
- 993
- 994
- 995
- 996
- 997
- 998
- 999
-1000
-1001
-1002
-1003
-1004
-1005
-1006
-1007
-1008
-1009
-1010
-1011
-1012
-1013
-1014
-1015
-1016
-1017
-1018
-1019
-1020
-1021
-1022
-1023
-1024
-1025
-1026
-1027
-1028
-1029
-1030
-1031
-1032
-1033
-1034
-1035
-1036
-1037
-1038
-1039
-1040
-1041
-1042
-1043
-1044
-1045
-1046
-1047
-1048
-1049
-1050
-1051
-1052
-1053
-1054
-1055
-1056
-1057
-1058
-1059
-1060
-1061
-1062
-1063
-1064
-1065
-1066
-1067
-1068
-1069
-1070
-1071
-1072
-1073
-1074
-1075
-1076
-1077
-1078
-1079
-1080
-1081
-1082
-1083
-1084
-1085
-1086
-1087
-1088
-1089
-1090
-1091
-1092
-1093
-1094
-1095
-1096
-1097
-1098
-1099
-1100
-1101
-1102
-1103
-1104
-1105
-1106
-1107
-1108
-1109
-1110
-1111
-1112
-1113
-1114
-1115
-1116
-1117
-1118
-1119
-1120
-1121
-1122
-1123
-1124
-1125
-1126
-1127
-1128
-1129
-1130
-1131
-1132
-1133
-1134
-1135
-1136
-1137
-1138
-1139
-1140
-1141
-1142
-1143
-1144
-1145
-1146
-1147
-1148
-1149
-1150
-1151
-1152
-1153
-1154
-1155
-1156
-1157
-1158
-1159
-1160
-1161
-1162
-1163
-1164
-1165
-1166
-1167
-1168
-1169
-1170
-1171
-1172
-1173
-1174
-1175
-1176
-1177
-1178
-1179
-1180
-1181
-1182
-1183
-1184
-1185
-1186
-1187
-1188
-1189
-1190
-1191
-1192
-1193
-1194
-1195
-1196
-1197
-1198
-1199
-1200
-1201
-1202
-1203
-1204
-1205
-1206
-1207
-1208
-1209
-1210
-1211
-1212
-1213
-1214
-1215
-1216
-1217
-1218
-1219
-1220
-1221
-1222
-1223
-1224
-1225
-1226
-1227
-1228
-1229
-1230
-1231
-1232
-1233
-1234
-1235
-1236
-1237
-1238
-1239
-1240
-1241
-1242
-1243
-1244
-1245
-1246
-1247
-1248
-1249
-1250
-1251
-1252
-1253
-1254
-1255
-1256
-1257
-1258
-1259
-1260
-1261
-1262
-1263
-1264
-1265
-1266
-1267
-1268
-1269
-1270
-1271
-1272
-1273
-1274
-1275
-1276
-1277
-1278
-1279
-1280
-1281
-1282
-1283
-1284
-1285
-1286
-1287
-1288
-1289
-1290
-1291
-1292
-1293
-1294
-1295
-1296
-1297
-1298
-1299
-1300
-1301
-1302
-1303
-1304
-1305
-1306
-1307
-1308
-1309
-1310
-1311
-1312
-1313
-1314
-1315
-1316
-1317
-1318
-1319
-1320
-1321
-1322
-1323
-1324
-1325
-1326
-1327
-1328
-1329
-1330
-1331
-1332
-1333
-1334
-1335
-1336
-1337
-1338
-1339
-1340
-1341
-1342
-1343
-1344
-1345
-1346
-1347
-1348
-1349
-1350
-1351
-1352
-1353
-1354
-1355
-1356
-1357
-1358
-1359
-1360
-1361
-1362
-1363
-1364
-1365
-1366
-1367
-1368
-1369
-1370
-1371
-1372
-1373
-1374
-1375
-1376
-1377
-1378
-1379
-1380
-1381
-1382
-1383
-1384
-1385
-1386
-1387
-1388
-1389
-1390
-1391
-1392
-1393
-1394
-1395
-1396
-1397
-1398
-1399
-1400
-1401
-1402
-1403
-1404
-1405
-1406
-1407
-1408
-1409
-1410
-1411
-1412
-1413
-1414
-1415
-1416
-1417
-1418
-1419
-1420
-1421
-1422
-1423
-1424
-1425
-1426
-1427
-1428
-1429
-1430
-1431
-1432
-1433
-1434
-1435
-1436
-1437
-1438
-1439
-1440
-1441
-1442
-1443
-1444
-1445
-1446
-1447
-1448
-1449
-1450
-1451
-1452
-1453
-1454
-1455
-1456
-1457
-1458
-1459
-1460
-1461
-1462
-1463
-1464
-1465
-1466
-1467
-1468
-1469
-1470
-1471
-1472
-1473
-1474
-1475
-1476
-1477
-1478
-1479
-1480
-1481
-1482
-1483
-1484
-1485
-1486
-1487
-1488
-1489
-1490
-1491
-1492
-1493
-1494
-1495
-1496
-1497
-1498
-1499
-1500
-1501
-1502
-1503
-1504
-1505
-1506
-1507
-1508
-1509
-1510
-1511
-1512
-1513
-1514
-1515
-1516
-1517
-1518
-1519
-1520
-1521
-1522
-1523
-1524
-1525
-1526
-1527
-1528
-1529
-1530
-1531
-1532
-1533
-1534
-1535
-1536
-1537
-1538
-1539
-1540
-1541
-1542
-1543
-1544
-1545
-1546
-1547
-1548
-1549
-1550
-1551
-1552
-1553
-1554
-1555
-1556
-1557
-1558
-1559
-1560
-1561
-1562
-1563
-1564
-1565
-1566
-1567
-1568
-1569
-1570
-1571
-1572
-1573
-1574
-1575
-1576
-1577
-1578
-1579
-1580
-1581
-1582
-1583
-1584
-1585
-1586
-1587
-1588
-1589
-1590
-1591
-1592
-1593
-1594
-1595
-1596
-1597
-1598
-1599
-1600
-1601
-1602
-1603
-1604
-1605
-1606
-1607
-1608
-1609
-1610
-1611
-1612
#include "mesh_adapter.hpp"
-
-#include <assert.h>                        // for assert
-#include <cstddef>                         // for size_t
-#include <iostream>                        // for operator<<, endl, basic_os...
-#include <set>                             // for set
-#include <utility>                         // for pair
-#include "AMR/AMR_types.hpp"                 // for Edge_Refinement, edge_list_t
-#include "AMR/Loggers.hpp"                   // for trace_out
-#include "AMR/Refinement_State.hpp"          // for Refinement_Case, Refinemen...
-#include "AMR/edge.hpp"                      // for operator<<, edge_t
-#include "AMR/edge_store.hpp"                // for edge_store_t
-#include "AMR/marked_refinements_store.hpp"  // for marked_refinements_store_t
-#include "AMR/node_connectivity.hpp"         // for node_connectivity_t
-#include "AMR/refinement.hpp"                // for refinement_t
-#include "AMR/tet_store.hpp"                 // for tet_store_t
-
-#if defined(__clang__)
-  #pragma clang diagnostic push
-  #pragma clang diagnostic ignored "-Wunreachable-code"
-  #pragma clang diagnostic ignored "-Wdocumentation"
-#endif
-
-namespace AMR {
-
-
-#ifdef ENABLE_NODE_STORE
-    /**
-     * @brief This accepts external coord arrays and allows the node_store to
-     * track the new node positions as they are added
-     *
-     * @param m_x X coodinates
-     * @param m_y Y coodinates
-     * @param m_z Z coodinates
-     * @param graph_size Total number of nodes
-     */
-    // TODO: remove graph size and use m.size()
-    // TODO: remove these pointers
-    //void mesh_adapter_t::init_node_store(coord_type* m_x, coord_type* m_y, coord_type* m_z)
-    //{
-    //    assert( m_x->size() == m_y->size() );
-    //    assert( m_x->size() == m_z->size() );
-
-    //    node_store.set_x(*m_x);
-    //    node_store.set_y(*m_y);
-    //    node_store.set_z(*m_z);
-    //}
-#endif
-
-    std::pair< bool, std::size_t > mesh_adapter_t::check_same_face(
-      std::size_t tet_id,
-      const std::unordered_set<std::size_t>& inactive_nodes)
-    {
-       edge_list_t edge_list = tet_store.generate_edge_keys(tet_id);
-
-       Assert(inactive_nodes.size()==3 || inactive_nodes.size()==2,
-         "Incorrectly sized inactive nodes set");
-
-       // for a tet ABCD, the keys (edges) are ordered
-       // A-B, A-C, A-D, B-C, B-D, C-D
-       // 0-1, 0-2, 0-3, 1-2, 1-3, 2-3
-
-       std::array< std::array< std::size_t, 3 >, 4 >
-         edges_on_face;
+
  1
+  2
+  3
+  4
+  5
+  6
+  7
+  8
+  9
+ 10
+ 11
+ 12
+ 13
+ 14
+ 15
+ 16
+ 17
+ 18
+ 19
+ 20
+ 21
+ 22
+ 23
+ 24
+ 25
+ 26
+ 27
+ 28
+ 29
+ 30
+ 31
+ 32
+ 33
+ 34
+ 35
+ 36
+ 37
+ 38
+ 39
+ 40
+ 41
+ 42
+ 43
+ 44
+ 45
+ 46
+ 47
+ 48
+ 49
+ 50
+ 51
+ 52
+ 53
+ 54
+ 55
+ 56
+ 57
+ 58
+ 59
+ 60
+ 61
+ 62
+ 63
+ 64
+ 65
+ 66
+ 67
+ 68
+ 69
+ 70
+ 71
+ 72
+ 73
+ 74
+ 75
+ 76
+ 77
+ 78
+ 79
+ 80
+ 81
+ 82
+ 83
+ 84
+ 85
+ 86
+ 87
+ 88
+ 89
+ 90
+ 91
+ 92
+ 93
+ 94
+ 95
+ 96
+ 97
+ 98
+ 99
+100
+101
+102
+103
+104
+105
+106
+107
+108
+109
+110
+111
+112
+113
+114
+115
+116
+117
+118
+119
+120
+121
+122
+123
+124
+125
+126
+127
+128
// *****************************************************************************
+/*!
+  \file      src/Control/MeshConv/CmdLine/Parser.cpp
+  \copyright 2012-2015 J. Bakosi,
+             2016-2018 Los Alamos National Security, LLC.,
+             2019-2021 Triad National Security, LLC.
+             All rights reserved. See the LICENSE file for details.
+  \brief     MeshConv's command line parser
+  \details   This file defines the command-line argument parser for the mesh
+     file converter, MeshConv.
+*/
+// *****************************************************************************
+
+#include "NoWarning/pegtl.hpp"
+#include "NoWarning/charm.hpp"
+
+#include "QuinoaConfig.hpp"
+#include "Exception.hpp"
+#include "Print.hpp"
+#include "Keywords.hpp"
+#include "MeshConv/Types.hpp"
+#include "MeshConv/CmdLine/Parser.hpp"
+#include "MeshConv/CmdLine/Grammar.hpp"
+
+namespace tk {
+namespace grm {
+
+tk::Print g_print;
+
+} // grm::
+} // tk::
+
+using meshconv::CmdLineParser;
+
+CmdLineParser::CmdLineParser( int argc,
+                              char** argv,
+                              const tk::Print& print,
+                              ctr::CmdLine& cmdline ) :
+  StringParser( argc, argv )
+// *****************************************************************************
+//  Contructor: parse the command line for MeshConv
+//! \param[in] argc Number of C-style character arrays in argv
+//! \param[in] argv C-style character array of character arrays
+//! \param[in] print Pretty printer
+//! \param[inout] cmdline Command-line stack where data is stored from parsing
+// *****************************************************************************
+{
+  // Create CmdLine (a tagged tuple) to store parsed input
+  ctr::CmdLine cmd;
+
+  // Reset parser's output stream to that of print's. This is so that mild
+  // warnings emitted during parsing can be output using the pretty printer.
+  // Usually, errors and warnings are simply accumulated during parsing and
+  // printed during diagnostics after the parser has finished. However, in some
+  // special cases we can provide a more user-friendly message right during
+  // parsing since there is more information available to construct a more
+  // sensible message. This is done in e.g., tk::grm::store_option. Resetting
+  // the global g_print, to that of passed in as the constructor argument allows
+  // not to have to create a new pretty printer, but use the existing one.
+  tk::grm::g_print.reset( print.save() );
+
+  // Parse command line string by populating the underlying tagged tuple
+  tao::pegtl::memory_input<> in( m_string, "command line" );
+  tao::pegtl::parse< cmd::read_string, tk::grm::action >( in, cmd );
 
-       // A-B-C
-       edges_on_face[0][0] =
-         tk::cref_find(node_connectivity.data(),edge_list[0].get_data());
-       edges_on_face[0][1] =
-         tk::cref_find(node_connectivity.data(),edge_list[1].get_data());
-       edges_on_face[0][2] =
-         tk::cref_find(node_connectivity.data(),edge_list[3].get_data());
-
-       // A-B-D
-       edges_on_face[1][0] =
-         tk::cref_find(node_connectivity.data(),edge_list[0].get_data());
-       edges_on_face[1][1] =
-         tk::cref_find(node_connectivity.data(),edge_list[2].get_data());
-       edges_on_face[1][2] =
-         tk::cref_find(node_connectivity.data(),edge_list[4].get_data());
-
-       // B-C-D
-       edges_on_face[2][0] =
-         tk::cref_find(node_connectivity.data(),edge_list[3].get_data());
-       edges_on_face[2][1] =
-         tk::cref_find(node_connectivity.data(),edge_list[4].get_data());
-       edges_on_face[2][2] =
-         tk::cref_find(node_connectivity.data(),edge_list[5].get_data());
-
-       // A-C-D
-       edges_on_face[3][0] =
-         tk::cref_find(node_connectivity.data(),edge_list[1].get_data());
-       edges_on_face[3][1] =
-         tk::cref_find(node_connectivity.data(),edge_list[2].get_data());
-       edges_on_face[3][2] =
-         tk::cref_find(node_connectivity.data(),edge_list[5].get_data());
-
-       //Iterate over edges to determine if inactive_nodes are all part of a face
-       bool same_face(false);
-       [[maybe_unused]] bool tnode_set(false);
-       std::size_t third_node = 0;
-       for(const auto& face : edges_on_face)
-       {
-         std::size_t icount = 0;
-         for (const auto& np_node : face) {
-           if (inactive_nodes.count(np_node)) ++icount;
-         }
-         if (inactive_nodes.size() == icount) {
-           same_face = true;
-           // if the two inactive_nodes being checked are on the same parent
-           // face, determine the third node on that face
-           if (inactive_nodes.size() == 2) {
-             for (auto fn:face) {
-               if (inactive_nodes.count(fn) == 0) {
-                 third_node = fn;
-                 tnode_set = true;
-                 break;
-               }
-             }
-           }
-         }
-       }
-
-       if (same_face && inactive_nodes.size() == 2)
-         Assert(tnode_set, "Third node on face not set in derefine");
-
-       return {same_face, third_node};
-    }
-
-    /** @brief Consume an existing mesh, and turn it into the AMRs
-     * representations of tets and nodes
-     *
-     * @param tetinpoel Vector of nodes grouped together in blocks of 4 to
-     * represent tets
-     */
-    void mesh_adapter_t::consume_tets(const std::vector< std::size_t >& tetinpoel )
-    {
-        for (size_t i = 0; i < tetinpoel.size(); i+=4)
-        {
-            tet_t t = {
-                {
-                    tetinpoel[i],
-                    tetinpoel[i+1],
-                    tetinpoel[i+2],
-                    tetinpoel[i+3]
-                }
-            };
-
-            trace_out << "Consume tet " << i << std::endl;
-            tet_store.add(t, AMR::Refinement_Case::initial_grid);
-        }
-    }
-
-    /**
-     * @brief Place holder function to evaluate error estimate at
-     * nodes, and therefor mark things as needing to be refined
-     */
-    //void mesh_adapter_t::evaluate_error_estimate() {
-    //    for (auto& kv : tet_store.edge_store.edges)
-    //    {
-    //        // Mark them as needing refinement
-    //        if (kv.second.refinement_criteria > refinement_cut_off)
-    //        {
-    //            kv.second.needs_refining = 1;
-    //        }
-    //        else
-    //        {
-    //            // TODO: Check this won't be overwriting valuable
-    //            // information from last iteration
-    //            kv.second.needs_refining = 0;
-    //        }
-    //    }
-    //}
-
-    /**
-     * @brief Helper function to apply uniform refinement to all tets
-     */
-    void mesh_adapter_t::mark_uniform_refinement()
-    {
-        for (auto& kv : tet_store.edge_store.edges) {
-           auto& local = kv.second;
-           if (local.lock_case == Edge_Lock_Case::unlocked)
-             local.needs_refining = 1;
-        }
-        mark_refinement();
-    }
-
-    /**
-     * @brief Helper function to apply uniform derefinement to all tets
-     */
-    void mesh_adapter_t::mark_uniform_derefinement()
-    {
-      const auto& inp = tet_store.get_active_inpoel();
-      auto& edge_store = tet_store.edge_store;
-      for (std::size_t t=0; t<inp.size()/4; ++t) {
-        const auto edges =
-          edge_store.generate_keys(
-            {inp[t*4+0], inp[t*4+1], inp[t*4+2], inp[t*4+3]});
-        for (const auto& tetedge : edges) {
-          auto e = edge_store.edges.find(tetedge);
-          if (e != end(edge_store.edges)) {
-            auto& local = e->second;
-            local.needs_derefining = 1;
-          }
-        }
-      }
-      mark_derefinement();
-    }
-
-    /**
-     * @brief For a given set of edges, set their refinement criteria for
-     * refinement
-     *
-     * @param remote Vector of edges and edge tags
-     */
-    void mesh_adapter_t::mark_error_refinement(
-            const std::vector< std::pair< edge_t, edge_tag > >& remote )
-    {
-       for (const auto& r : remote) {
-         auto& local = tet_store.edge_store.get( r.first );
-         if (r.second == edge_tag::REFINE) {
-           if (local.lock_case > Edge_Lock_Case::unlocked) {
-             local.needs_refining = 0;
-           } else {
-             local.needs_refining = 1;
-             // an edge deemed to be 'needing refinement', cannot be derefined
-             local.needs_derefining = 0;
-           }
-         } else if (r.second == edge_tag::DEREFINE) {
-           local.needs_derefining = 1;
-         }
-       }
-
-       mark_refinement();
-       mark_derefinement();
-    }
-
-   void mesh_adapter_t::mark_error_refinement_corr( const EdgeData& edges )
-    {
-       for (const auto& r : edges)
-       {
-           auto& edgeref = tet_store.edge_store.get( edge_t(r.first) );
-           edgeref.needs_refining = std::get<0>(r.second);
-           edgeref.needs_derefining = std::get<1>(r.second);
-           Assert(edgeref.lock_case == Edge_Lock_Case::unlocked ?
-             edgeref.lock_case <= std::get<2>(r.second) : true,
-             "Edge " + std::to_string(r.first[0]) +
-             "-" + std::to_string(r.first[1]) +
-             " : current edge-lock " + std::to_string(edgeref.lock_case) +
-             " stricter than received edge-lock " +
-             std::to_string(std::get<2>(r.second)));
-           edgeref.lock_case = std::get<2>(r.second);
-       }
-       mark_refinement();
-       mark_derefinement();
-    }
-
-    /**
-     * @brief Function to detect the compatibility class (1,
-     * 2, or 3) based on the number of locked edges and the existence
-     * of intermediate edges
-     *
-     * @param num_locked_edges The number of locked edges
-     * @param num_intermediate_edges The number of intermediate edges
-     * @param refinement_case The refinement case of the tet
-     * @param normal TODO: Document this!
-     *
-     * @return The compatibili4y class of the current scenario
-     */
-    int mesh_adapter_t::detect_compatibility(
-            int num_locked_edges,
-            int num_intermediate_edges,
-            AMR::Refinement_Case refinement_case,
-            int normal
-    )
-    {
-        int compatibility = 0;
-        num_locked_edges += num_intermediate_edges;
-
-        /*
-        // Split this into three categories
-        // 1. Normal elements without locked edges. => 1
-        //if (normal) {
-
-            // 3. Intermediate elements with at least one edge marked for refinement => 3
-            if (num_intermediate_edges > 0)
-            {
-                compatibility = 3;
-            }
-            else if (num_locked_edges == 0) {
-                compatibility = 1;
-            }
-        // 2. Normal elements with locked edges. => 2
-            else {
-                compatibility = 2;
-            }
-        //}
-        */
-
-        //else {
-            //if (num_intermediate_edges > 0) { compatibility = 3; }
-        //}
-
-
-
-        // Only 1:2 and 1:4 are intermediates and eligible for class3 // NOT TRUE!
-        /*
-        if (num_intermediate_edges > 0)
-        {
-            if (!normal) {
-                trace_out << " not normal 3 " << std::endl;
-                compatibility = 3;
-            }
-            else { // Attempt to allow for "normal" 1:4 and 1:8
-                compatibility = 2;
-                trace_out << " normal 3 " << std::endl;
-            }
-
-        }
-        else {
-            if (num_locked_edges == 0) {
-                trace_out << " no lock 1 " << std::endl;
-                compatibility = 1;
-            }
-            else {
-                trace_out << " lock 2 " << std::endl;
-                compatibility = 2;
-            }
-        }
-        */
-
-
-        // Old implementation
-        // Only 1:2 and 1:4 are intermediates and eligible for class3 // NOT TRUE!
-        if (
-                (refinement_case == AMR::Refinement_Case::one_to_two) or
-                (refinement_case == AMR::Refinement_Case::one_to_four)
-           )
-        {
-            if (!normal) {
-                trace_out << " not normal 3 " << std::endl;
-                compatibility = 3;
-            }
-            else { // Attempt to allow for "normal" 1:4 and 1:8
-                compatibility = 2;
-                trace_out << " normal 3 " << std::endl;
-            }
-
-        }
-        else {
-            if (num_locked_edges == 0) {
-                trace_out << " no lock 1 " << std::endl;
-                compatibility = 1;
-            }
-            else {
-                trace_out << " lock 2 " << std::endl;
-                compatibility = 2;
-            }
-        }
-
-        assert(compatibility > 0);
-        assert(compatibility < 4);
-        return compatibility;
-    }
-
-    /**
-     * @brief Function which implements the main refinement algorithm from
-     * the paper Iterating over the cells, deciding which refinement and
-     * compatibility types are appropriate etc
-     */
-    void mesh_adapter_t::mark_refinement() {
-
-#ifndef AMR_MAX_ROUNDS
-        // Paper says the average actual num rounds will be 5-15
-#define AMR_MAX_ROUNDS 50
-#endif
-        const size_t max_num_rounds = AMR_MAX_ROUNDS;
-
-        // Mark refinements
-        size_t iter;
-        //Iterate until convergence
-        for (iter = 0; iter < max_num_rounds; iter++)
-        {
-
-            tet_store.marked_refinements.get_state_changed() = false;
-
-            // Loop over Tets.
-            for (const auto& kv : tet_store.tets)
-            {
-                size_t tet_id = kv.first;
-
-                trace_out << "Process tet " << tet_id << std::endl;
-
-                // Only apply checks to tets on the active list
-                if (tet_store.is_active(tet_id)) {
-                    int num_locked_edges = 0;
-                    int num_intermediate_edges = 0;
-
-                    // Loop over nodes and count the number which need refining
-                    int num_to_refine = 0;
-
-                    // This is useful for later inspection
-                    edge_list_t edge_list = tet_store.generate_edge_keys(tet_id);
-
-                    //Iterate over edges
-                    for(auto & key : edge_list)
-                    {
-
-                        trace_out << "Edge " << key << std::endl;
-
-                        //Count locked edges and edges in need of
-                        // refinement
-                        // Count Locked Edges
-                        if(tet_store.edge_store.get(key).lock_case == AMR::Edge_Lock_Case::locked)
-                        {
-                            trace_out << "Found locked edge " << key << std::endl;
-                            trace_out << "Locked :" << tet_store.edge_store.get(key).lock_case << std::endl;
-                            num_locked_edges++;
-                        }
-                        else if(tet_store.edge_store.get(key).lock_case == AMR::Edge_Lock_Case::intermediate
-                          || tet_store.edge_store.get(key).lock_case == AMR::Edge_Lock_Case::temporary)
-                        {
-                            trace_out << "Found intermediate edge " << key << std::endl;
-                            num_intermediate_edges++;
-                        }
-                        else
-                        {
-                            // Count edges which need refining
-                            //  We check in here as we won't refine a
-                            //  locked edge and will thus ignore it
-                            if (tet_store.edge_store.get(key).needs_refining == 1)
-                            {
-                                num_to_refine++;
-                                trace_out << "key needs ref " << key << std::endl;
-                            }
-                        }
-                    }
-
-                    // TODO: Should this be a reference?
-                    AMR::Refinement_Case refinement_case = tet_store.get_refinement_case(tet_id);
-                    int normal = tet_store.is_normal(tet_id);
-
-                    trace_out << "Checking " << tet_id <<
-                        " ref case " << refinement_case <<
-                        " num ref " << num_to_refine <<
-                        " normal " << normal <<
-                        std::endl;
-
-
-
-                    //If we have any tets to refine
-                    if (num_to_refine > 0)
-                    {
-                        //Determine compatibility case
-
-                        int compatibility = detect_compatibility(num_locked_edges,
-                                num_intermediate_edges, refinement_case, normal);
-
-                        trace_out << "Compat " << compatibility << std::endl;
-
-                        // Now check num_to_refine against situations
-                        if (compatibility == 1)
-                        {
-                            refinement_class_one(num_to_refine, tet_id);
-                        }
-                        else if (compatibility == 2)
-                        {
-                            refinement_class_two(edge_list, tet_id);
-                        }
-                        else if (compatibility == 3)
-                        {
-                            refinement_class_three(tet_id);
-                        }
-
-                        /*
-                        // Write temp mesh out
-                        std::string temp_file =  "temp." +
-                        std::to_string(iter) + "." +
-                        std::to_string(tet_id) + ".exo";
-
-                        std::cout << "Writing " << temp_file << std::endl;
-                        Adaptive_UnsMesh outmesh(
-                        get_active_inpoel(), x(), y(), z()
-                        );
-                        tk::ExodusIIMeshWriter( temp_file, tk::ExoWriter::CREATE ).
-                        writeMesh(outmesh);
-                        */
-
-                    } // if num_to_refine
-                    else {
-                        // If we got here, we don't want to refine this guy
-                        tet_store.marked_refinements.add(tet_id, AMR::Refinement_Case::none);
-                    }
-                } // if active
-                else {
-                    trace_out << "Inactive" << std::endl;
-                }
-            } // For
-
-            // If nothing changed during that round, break
-            if (!tet_store.marked_refinements.get_state_changed())
-            {
-                trace_out << "Terminating loop at iter " << iter << std::endl;
-                break;
-            }
-            trace_out << "End iter " << iter << std::endl;
-        }
-        trace_out << "Loop took " << iter << " rounds." << std::endl;
-
-        //std::cout << "Print Tets" << std::endl;
-        //print_tets();
-    }
-
-    /**
-     * @brief Helper function to print tet information when needed
-     */
-    void mesh_adapter_t::print_tets() {
-        tet_store.print_tets();
-    }
-
-    /**
-     * @brief Function to call refinement after each tet has had it's
-     * refinement case marked and calculated
-     */
-    void mesh_adapter_t::perform_refinement()
-    {
-        // Track tets which need to be deleted this iteration
-        std::set<size_t> round_two;
-
-        trace_out << "Perform ref" << std::endl;
-
-        // Do refinements
-        for (const auto& kv : tet_store.tets)
-        {
-            size_t tet_id = kv.first;
-
-            trace_out << "Do refine of " << tet_id << std::endl;
-            if (tet_store.has_refinement_decision(tet_id))
-            {
-                switch(tet_store.marked_refinements.get(tet_id))
-                {
-                    case AMR::Refinement_Case::one_to_two:
-                        refiner.refine_one_to_two(tet_store,node_connectivity,tet_id);
-                        break;
-                    case AMR::Refinement_Case::one_to_four:
-                        refiner.refine_one_to_four(tet_store,node_connectivity,tet_id);
-                        break;
-                    case AMR::Refinement_Case::one_to_eight:
-                        refiner.refine_one_to_eight(tet_store,node_connectivity,tet_id);
-                        break;
-                    case AMR::Refinement_Case::two_to_eight:
-                        round_two.insert( tet_store.get_parent_id(tet_id) );
-                        //std::cout << "2->8\n";
-                        break;
-                    case AMR::Refinement_Case::four_to_eight:
-                        round_two.insert( tet_store.get_parent_id(tet_id));
-                        //std::cout << "4->8\n";
-                        break;
-                    case AMR::Refinement_Case::initial_grid:
-                        // Do nothing
-                    case AMR::Refinement_Case::none:
-                        // Do nothing
-                        break;
-                        // No need for default as enum is explicitly covered
-                }
-                // Mark tet as not needing refinement
-                tet_store.marked_refinements.erase(tet_id);
-            }
-        }
-
-        trace_out << "round_two size " << round_two.size() << std::endl;
-        for (const auto i : round_two)
-        {
-            trace_out << "round two i " << i << std::endl;
-
-            // Cache children as we're about to change this data
-            auto former_children = tet_store.data(i).children;
-
-            AMR::Refinement_State& element = tet_store.data(i);
-
-            if (element.children.size() == 2)
-            {
-                trace_out << "perform 2:8" << std::endl;
-                refiner.derefine_two_to_one(tet_store,node_connectivity,i);
-            }
-            else if (element.children.size() == 4)
-            {
-                trace_out << "perform 4:8" << std::endl;
-                refiner.derefine_four_to_one(tet_store,node_connectivity,i);
-            }
-            else {
-                std::cout << "num children " << element.children.size() << std::endl;
-                assert(0);
-            }
-            // remove tets and edges marked for deletion above
-            refiner.delete_intermediates_of_children(tet_store);
-            tet_store.process_delete_list();
-
-            refiner.refine_one_to_eight(tet_store,node_connectivity,i);
-
-            // Grab children after it has been updated
-            auto current_children = tet_store.data(i).children;
-
-            // I want to set the children stored in *my* own children, to be
-            // the value of my new children....
-            //refiner.overwrite_children(tet_store, former_children, current_children);
-
-            tet_store.unset_marked_children(i); // FIXME: This will not work well in parallel
-            element.refinement_case = AMR::Refinement_Case::one_to_eight;
-        }
-
-        // Clean up dead edges
-        // clean_up_dead_edges(); // Nothing get's marked as "dead" atm?
-
-        //std::cout << "Total Edges : " << tet_store.edge_store.size() << std::endl;
-        //std::cout << "Total Tets : " << tet_store.size() << std::endl;
-        //std::cout << "Total Nodes : " << m_x.size() << std::endl;
-
-        trace_out << "Done ref" << std::endl;
-        node_connectivity.print();
-        node_connectivity.print();
-        tet_store.print_node_types();
-        tet_store.print_tets();
-        //node_connectivity.print();
-
-        //reset_intermediate_edges();
-        remove_edge_locks(1);
-        remove_normals();
-
-        lock_intermediates();
-
-        for (auto& kv : tet_store.edge_store.edges) {
-           auto& local = kv.second;
-           if (local.needs_refining == 1) local.needs_refining = 0;
-        }
-    }
-
-    void mesh_adapter_t::lock_intermediates()
-    {
-        /*
-        for (auto k : tet_store.intermediate_list)
-        {
-            refiner.lock_edges_from_node(tet_store,k, Edge_Lock_Case::intermediate);
-        }
-        */
-        // TODO: Passing tet_store twice probably isn't the best
-        refiner.lock_intermediates(tet_store, tet_store.intermediate_list, Edge_Lock_Case::intermediate);
-    }
-
-    /**
-     * @brief A method implementing "Algorithm 1" from the paper
-     *
-     * @param num_to_refine Number of edges to refine
-     * @param tet_id The id of the given tet
-     */
-    void mesh_adapter_t::refinement_class_one(int num_to_refine, size_t tet_id)
-    {
-        trace_out << "Refinement Class One" << std::endl;
-
-        // "If nrefine = 1
-        // Accept as a 1:2 refinement"
-        if (num_to_refine == 1)
-        {
-            tet_store.mark_one_to_two(tet_id);
-        }
-
-        // "Else if nrefine = 2 OR nrefine = 3"
-        else if (num_to_refine > 1 && num_to_refine < 4)
-        {
-
-            // We need to detect if the edges which need to refine are
-            // on the same face
-            // and if so which face so we know how to 1:4
-
-            face_list_t face_list = tet_store.generate_face_lists(tet_id);
-            bool edges_on_same_face = false;
-            size_t face_refine_id = 0;
-
-            // Iterate over each face
-            for (size_t face = 0; face < NUM_TET_FACES; face++)
-            {
-                int num_face_refine_edges = 0;
-                face_ids_t face_ids = face_list[face];
-
-                trace_out << "Face is " <<
-                    face_ids[0] << ", " <<
-                    face_ids[1] << ", " <<
-                    face_ids[2] << ", " <<
-                    std::endl;
-
-                edge_list_t face_edge_list = AMR::edge_store_t::generate_keys_from_face_ids(face_ids);
-                // For this face list, see which ones need refining
-                for (size_t k = 0; k < NUM_FACE_NODES; k++)
-                {
-                    edge_t key = face_edge_list[k];
-                    if (tet_store.edge_store.get(key).needs_refining == 1)
-                    {
-                        num_face_refine_edges++;
-                    }
-                }
-                if (num_face_refine_edges == num_to_refine)
-                {
-                    edges_on_same_face = true;
-                    face_refine_id = face;
-                    trace_out << "Breaking with face value " << face << std::endl;
-                    break;
-                }
-            }
-
-            // "If active edges are on the same face
-            // Activate any inactive edges of the face
-            // Accept as a 1:4 // refinement"
-            if (edges_on_same_face)
-            {
-                size_t opposite_offset = AMR::node_connectivity_t::face_list_opposite(face_list,
-                        face_refine_id);
-
-                tet_t tet = tet_store.get(tet_id);
-                size_t opposite_id = tet[opposite_offset];
-
-                trace_out << "face_refine_id " << face_refine_id << std::endl;
-                trace_out << "opposite_offset " << opposite_offset << std::endl;
-                trace_out << "opposite_id " << opposite_id << std::endl;
-
-                // Activate edges on this face
-                edge_list_t face_edge_list = AMR::edge_store_t::generate_keys_from_face_ids(face_list[face_refine_id]);
-
-                for (size_t k = 0; k < NUM_FACE_NODES; k++)
-                {
-                    edge_t key = face_edge_list[k];
-                    tet_store.edge_store.mark_for_refinement(key);
-                }
-
-                //refiner.refine_one_to_four(tet_id, face_list[face_refine_id],
-                //opposite_id);
-                tet_store.mark_one_to_four(tet_id);
-            }
-            // "Else if active edges are not on the same face
-            // Activate all edges
-            // Accept as a 1:8 refinement"
-            else {
-                //refiner.refine_one_to_eight(tet_id);
-                tet_store.mark_edges_for_refinement(tet_id);
-                tet_store.mark_one_to_eight(tet_id);
-            }
-
-        }
-
-        // "Else if nrefine > 3
-        // Activate any inactive edges
-        // Accept as a 1:8 refinement"
-        else if (num_to_refine > 3)
-        {
-            //refiner.refine_one_to_eight(tet_id);
-            tet_store.mark_edges_for_refinement(tet_id);
-            tet_store.mark_one_to_eight(tet_id);
-        }
-    }
-
-    // TODO: Document this
-    void mesh_adapter_t::lock_tet_edges(size_t tet_id) {
-        edge_list_t edge_list = tet_store.generate_edge_keys(tet_id);
-        for (size_t k = 0; k < NUM_TET_EDGES; k++)
-        {
-            edge_t key = edge_list[k];
-            if (tet_store.edge_store.get(key).lock_case == AMR::Edge_Lock_Case::unlocked)
-            {
-                trace_out << "LOCKING! " << key << std::endl;
-                tet_store.edge_store.get(key).lock_case = AMR::Edge_Lock_Case::locked;
-            }
-        }
-    }
-
-    // TODO: Document this
-    // TODO: This has too similar a name to deactivate_tet
-    void mesh_adapter_t::deactivate_tet_edges(size_t tet_id) {
-        edge_list_t edge_list = tet_store.generate_edge_keys(tet_id);
-        for (size_t k = 0; k < NUM_TET_EDGES; k++)
-        {
-            edge_t key = edge_list[k];
-
-            tet_store.edge_store.unmark_for_refinement(key);
-            trace_out << "Deactivating " << key << std::endl;
-            tet_store.edge_store.get(key).needs_derefining = false;
-        }
-    }
-
-    /**
-     * @brief Unmarks edges of given tet for derefinement only
-     *
-     * @param tet_id The id of the given tet
-     */
-    void mesh_adapter_t::deactivate_deref_tet_edges(size_t tet_id) {
-        edge_list_t edge_list = tet_store.generate_edge_keys(tet_id);
-        for (size_t k = 0; k < NUM_TET_EDGES; k++)
-        {
-            edge_t key = edge_list[k];
-
-            trace_out << "Deactivating " << key << std::endl;
-            tet_store.edge_store.get(key).needs_derefining = false;
-        }
-    }
-
-    /**
-     * @brief An implementation of "Algorithm 2" from the paper
-     *
-     * @param edge_list The list of edges for the given tet
-     * @param tet_id The id of the given tet
-     */
-    void mesh_adapter_t::refinement_class_two(edge_list_t edge_list, size_t tet_id)
-    {
-        trace_out << "Refinement Class Two" << std::endl;
-
-
-        // "Deactivate all locked edges"
-
-        // count number of active edges
-        int num_active_edges = 0;
-        for (size_t k = 0; k < NUM_TET_EDGES; k++)
-        {
-            edge_t key = edge_list[k];
-            if (tet_store.edge_store.get(key).lock_case != AMR::Edge_Lock_Case::unlocked)
-            {
-                tet_store.edge_store.unmark_for_refinement(key);
-            }
-            // "Count number of active edges"
-            if (tet_store.edge_store.get(key).needs_refining == 1) {
-                num_active_edges++;
-            }
-        }
-
-        // Find out of two active edges live on the same face
-        bool face_refine = false;
-        size_t face_refine_id = 0; // FIXME: Does this need a better default
-        face_list_t face_list = tet_store.generate_face_lists(tet_id);
-
-        // Iterate over each face
-        for (size_t face = 0; face < NUM_TET_FACES; face++)
-        {
-            trace_out << "face " << face << std::endl;
-            int num_face_refine_edges = 0;
-            int num_face_locked_edges = 0;
-
-            face_ids_t face_ids = face_list[face];
-            edge_list_t face_edge_list = AMR::edge_store_t::generate_keys_from_face_ids(face_ids);
-            // For this face list, see which ones need refining
-            for (size_t k = 0; k < NUM_FACE_NODES; k++)
-            {
-                edge_t key = face_edge_list[k];
-                trace_out << "Checking " << key << std::endl;
-                if (tet_store.edge_store.get(key).needs_refining == 1)
-                {
-                    num_face_refine_edges++;
-                    trace_out << "ref! " << key << std::endl;
-                }
-
-                // Check for locked edges
-                // This case only cares about faces with no locks
-                if (tet_store.edge_store.get(key).lock_case != AMR::Edge_Lock_Case::unlocked)
-                {
-                    num_face_locked_edges++;
-                    trace_out << "locked! " << key << std::endl;
-                }
-            }
-
-
-            // Decide if we want to process this face
-            if (num_face_refine_edges >= 2 && num_face_locked_edges == 0)
-            {
-                // We can refine this face
-                face_refine = true;
-                face_refine_id = face;
-                break;
-            }
-        }
-
-        // "If nrefine = 1
-        // Accept as 1:2 refinement"
-        // TODO: can we hoist this higher
-        if (num_active_edges == 1)
-        {
-            //node_pair_t nodes = find_single_refinement_nodes(edge_list);
-            //refine_one_to_two( tet_id, nodes[0], nodes[1]);
-            tet_store.mark_one_to_two(tet_id);
-        }
-        // "Else if any face has nrefine >= 2 AND no locked edges
-        // Active any inactive edges of the face
-        // Accept as a 1:4 refinement"
-        else if (face_refine)
-        {
-            size_t opposite_offset = AMR::node_connectivity_t::face_list_opposite(face_list, face_refine_id);
-
-            tet_t tet = tet_store.get(tet_id);
-            size_t opposite_id = tet[opposite_offset];
-
-            trace_out << "Tet ID " << tet_id << std::endl;
-            trace_out << "Opposite offset " << opposite_offset << std::endl;
-            trace_out << "Opposite id " << opposite_id << std::endl;
-            trace_out << "Face refine id " << face_refine_id << std::endl;
-
-            edge_list_t face_edge_list =
-                AMR::edge_store_t::generate_keys_from_face_ids(face_list[face_refine_id]);
-
-            for (size_t k = 0; k < NUM_FACE_NODES; k++)
-            {
-                edge_t key = face_edge_list[k];
-                tet_store.edge_store.mark_for_refinement(key);
-            }
-
-            //refiner.refine_one_to_four(tet_id, face_list[face_refine_id], opposite_id);
-            tet_store.mark_one_to_four(tet_id);
-        }
-
-        // "Else
-        // Deactivate all edges
-        // Mark all edges as locked"
-        else {
-            trace_out << "Class 2 causes some locking.." << std::endl;
-            deactivate_tet_edges(tet_id);
-            lock_tet_edges(tet_id);
-        }
-
-    }
-
-    /**
-     * @brief Based on a tet_id, decide if it's current state of locked
-     * and marked edges maps to a valid refinement case. The logic for
-     * this was derived from talking to JW and reading Chicoma.
-     *
-     * It basically just checks if something a 1:2 and has 3
-     * intermediates and 3 makred edges, or is a 1:4 and has 5/6
-     * intermediates
-     *
-     * @param child_id the id of the tet to check
-     *
-     * @return A bool saying if the tet is in a valid state to be refined
-     */
-    bool mesh_adapter_t::check_valid_refinement_case(size_t child_id) {
-
-        trace_out << "check valid ref " << child_id << std::endl;
-        edge_list_t edge_list = tet_store.generate_edge_keys(child_id);
-
-        size_t num_to_refine = 0;
-        size_t num_intermediate = 0;
-        size_t unlocked = 0;
-        size_t locked = 0;
-
-        for (size_t k = 0; k < NUM_TET_EDGES; k++)
-        {
-            edge_t key = edge_list[k];
-            trace_out << "Key " << key << std::endl;
-
-            // Count intermediate edges
-            if (tet_store.edge_store.get(key).lock_case == AMR::Edge_Lock_Case::intermediate
-              || tet_store.edge_store.get(key).lock_case == AMR::Edge_Lock_Case::temporary)
-            {
-                trace_out << "found intermediate" << std::endl;
-                num_intermediate++;
-            }
-
-            // Count number of marked for refinement
-            if (tet_store.edge_store.get(key).needs_refining == 1)
-            {
-                trace_out << "found refine" << std::endl;
-                num_to_refine++;
-            }
-
-            if (tet_store.edge_store.get(key).lock_case == AMR::Edge_Lock_Case::unlocked)
-            {
-                trace_out << "found unlocked" << std::endl;
-                unlocked++;
-            }
-
-            if (tet_store.edge_store.get(key).lock_case == AMR::Edge_Lock_Case::locked)
-            {
-                trace_out << "found locked" << std::endl;
-                locked++;
-            }
-
-        }
-
-        AMR::Refinement_State& element = tet_store.data(child_id);<--- Variable 'element' can be declared with const
-
-        trace_out <<
-            "Intermediates " << num_intermediate <<
-            " num to refine " << num_to_refine <<
-            " unlocked " << unlocked <<
-            " locked " << locked <<
-            " Case " << element.refinement_case <<
-            std::endl;
-
-        // check if element is 1:2
-        if (element.refinement_case == AMR::Refinement_Case::one_to_two)
-        {
-            // If so check it has 3 intermediates and 3 which need refining
-            if (num_intermediate != 3 || num_to_refine != 3) {
-                return false;
-            }
-            else {
-                trace_out << "True " <<
-                    "Intermediates " << num_intermediate <<
-                    " num to refine " << num_to_refine <<
-                    " Case " << element.refinement_case <<
-                    " 2:1 " << AMR::Refinement_Case::one_to_two <<
-                    std::endl;
-            }
-        }
-
-        // check if element is 1:4
-        else if (element.refinement_case == AMR::Refinement_Case::one_to_four)
-        {
-            // TODO: Check if it's a center tet for a 1:4
-            // FIXME: Is this even needed? How else would you get these
-            // combinations? Can't we just combine these two checks?
-
-            bool is_center_tet = tet_store.is_center(child_id);
-
-            if (is_center_tet)
-            {
-                if (num_to_refine != 0 || num_intermediate != 6)
-                {
-                    trace_out << "Fail compat 1:4 center" << std::endl;
-                    return false;
-                }
-            }
-            else { // Is one of the outsides (not center)
-                if (num_to_refine != 1 || num_intermediate != 5)
-                {
-                    trace_out << "Fail compat 1:4 non center" << std::endl;
-                    return false;
-                }
-            }
-        }
-
-        // If it makes it here, it's compatible
-        return true;
-
-    }
-
-    /**
-     * @brief Place holder method for the implementation of "Algorithm
-     * 3" from the paper
-     */
-    // TODO: Does this parse a childs siblings multiple times?
-    void mesh_adapter_t::refinement_class_three(size_t tet_id) {
-
-        trace_out << "Refinement Class Three" << std::endl;
-
-        // "Identify parent element iparent"
-        // TODO: WE should either always use the id to fetch, or always do the data lookup
-        //size_t parent_id = master_elements.get_parent(tet_id);
-        size_t parent_id = tet_store.get_parent_id(tet_id);
-
-        trace_out << "Parent id = " << parent_id << std::endl;
-
-        // NOTE: This implies comms when we use these ids?
-        child_id_list_t children = tet_store.data(parent_id).children;
-
-        // "Do for each child element ielement
-        // Activate all non-locked edges
-        // Deactivate all locked edges"
-        for (size_t i = 0; i < children.size(); i++)
-        {
-            // TODO: Is this in element or tet ids?
-            trace_out << "Checking child " << children[i] << std::endl;
-            edge_list_t edge_list = tet_store.generate_edge_keys(children[i]);
-            for (size_t k = 0; k < NUM_TET_EDGES; k++)
-            {
-                edge_t key = edge_list[k];
-                trace_out << "Compat 3 " << key << std::endl;
-                if (tet_store.edge_store.get(key).lock_case == AMR::Edge_Lock_Case::unlocked)
-		{
-                    trace_out << "Compat 3 marking edge " << key << std::endl;
-                    tet_store.edge_store.mark_for_refinement(key);
-                }
-                else {
-                    tet_store.edge_store.unmark_for_refinement(key);
-                }
-            }
-        }
-
-        // "Set compatible = TRUE
-        bool compatible = true;
-
-        // Do for each child element ielement
-        // If ielement is not a valid refinement case
-        // compatible = FALSE"
-        for (size_t i = 0; i < children.size(); i++)
-        {
-            size_t child = children[i];
-            if ( !check_valid_refinement_case(child) )
-            {
-                trace_out << "Compat 3 Marking compatible false because of invalid refinement case" << std::endl;
-
-                compatible = false;
-            }
-            else {
-                trace_out << "Is compatible" << std::endl;
-            }
-        }
-
-        // "If compatible = FALSE
-        // Do for each child element ielement
-        // Deactive all edges of ielement
-        // Mark all edges of ielement as locked
-        // Mark ielement as normal"
-        if (compatible == false)
-        {
-            for (size_t i = 0; i < children.size(); i++)
-            {
-                size_t child = children[i];
-                deactivate_tet_edges(child);
-                lock_tet_edges(child);
-                trace_out << "Compat 3 locking edges of " << child << std::endl;
-                // Here we interpret normal to mean "don't treat it like it has intermediates"
-                tet_store.mark_normal(child);
-                trace_out << "Compat 3 " << child << std::endl;
-            }
-        }
-        else {
-            trace_out << "TIME TO 2:8 " << tet_id << std::endl;
-            // Accept as 2:8 or 4:8
-            AMR::Refinement_State& element = tet_store.data(tet_id);
-            if (element.refinement_case == AMR::Refinement_Case::one_to_two)
-            {
-                tet_store.mark_two_to_eight(tet_id);
-            }
-            else if (element.refinement_case == AMR::Refinement_Case::one_to_four)
-            {
-                tet_store.mark_four_to_eight(tet_id);
-            }
-            else {
-                trace_out << " I don't know what to do with this..it looks like you're trying to 2/4:8 an 8... " << std::endl;
-            }
-
-        }
-    }
-
-    void mesh_adapter_t::remove_normals()
-    {
-        for (const auto& kv : tet_store.tets)
-        {
-            size_t tet_id = kv.first;
-            tet_store.set_normal(tet_id, 0);
-        }
-    }
-
-    void mesh_adapter_t::remove_edge_locks(int intermediate)
-    {
-        for (const auto& kv : tet_store.tets)
-        {
-            size_t tet_id = kv.first;
-
-            trace_out << "Process tet removelock " << tet_id << std::endl;
-
-            // Only apply checks to tets on the active list
-            if (tet_store.is_active(tet_id)) {
-                // change it from intermediate to locked
-                update_tet_edges_lock_type(tet_id, AMR::Edge_Lock_Case::locked, AMR::Edge_Lock_Case::unlocked);
-                if (intermediate) {
-                    update_tet_edges_lock_type(tet_id, AMR::Edge_Lock_Case::intermediate, AMR::Edge_Lock_Case::unlocked);
-                }
-            }
-        }
-
-    }
-    //void mesh_adapter_t::reset_intermediate_edges()
-    //{
-    //    for (const auto& kv : tet_store.tets)
-    //    {
-    //        size_t tet_id = kv.first;
-
-    //        trace_out << "Process tet reset " << tet_id << std::endl;
-
-    //        // Only apply checks to tets on the active list
-    //        if (tet_store.is_active(tet_id)) {
-    //            // change it from intermediate to locked
-    //            update_tet_edges_lock_type(tet_id, AMR::Edge_Lock_Case::intermediate, AMR::Edge_Lock_Case::locked);
-    //        }
-    //    }
-    //}
-
-    void mesh_adapter_t::update_tet_edges_lock_type(size_t tet_id, AMR::Edge_Lock_Case check, AMR::Edge_Lock_Case new_case) {
-        edge_list_t edge_list = tet_store.generate_edge_keys(tet_id);
-        for (size_t k = 0; k < NUM_TET_EDGES; k++)
-        {
-            edge_t key = edge_list[k];
-            if (tet_store.edge_store.get(key).lock_case == check)
-            {
-                tet_store.edge_store.get(key).lock_case = new_case;
-            }
-        }
-    }
-
-    /**
-     * @brief This unlocks edges that were previously locked with a `temporary'
-     * lock, indicating a parallel compatibility induced locking
-     */
-    void mesh_adapter_t::remove_edge_temp_locks()
-    {
-      for (const auto& kv : tet_store.tets)
-      {
-        size_t tet_id = kv.first;
-
-        trace_out << "Process tet remove temp lock " << tet_id << std::endl;
-
-        // Only apply checks to tets on the active list
-        if (tet_store.is_active(tet_id)) {
-          // change it from temporary to unlocked
-          update_tet_edges_lock_type(tet_id, AMR::Edge_Lock_Case::temporary,
-            AMR::Edge_Lock_Case::unlocked);
-        }
-      }
-    }
-
-    void mesh_adapter_t::mark_derefinement()
-    {
-        const size_t max_num_rounds = AMR_MAX_ROUNDS;
-
-        // Mark refinements
-        size_t iter;
-        //Iterate until convergence
-        for (iter = 0; iter < max_num_rounds; iter++)
-        {
-            tet_store.marked_derefinements.get_state_changed() = false;
-
-            // set of elements which have been considered for derefinement
-            std::unordered_set< size_t > done_deref_marking;
-
-            // Loop over tets
-            for (const auto& kv : tet_store.tets)
-            {
-                // this loop only runs for active tets
-                if (!tet_store.is_active(kv.first)) {
-                  deactivate_deref_tet_edges(kv.first);
-                  continue;
-                }
-                size_t activetet_id = kv.first;
-
-                // check if activetet_id has a parent (assign to tet_id)
-                // if it does not, activetet_id is not a derefinement candidate
-                size_t tet_id;
-                const auto& activetet_data = tet_store.data(activetet_id);
-                if (!activetet_data.has_parent) {
-                  deactivate_deref_tet_edges(activetet_id);
-                  continue;
-                }
-                else {
-                  tet_id = activetet_data.parent_id;
-                }
-
-                // if already considered for deref, do not reconsider
-                if (done_deref_marking.count(tet_id) > 0) {
-                  continue;
-                }
-                done_deref_marking.insert(tet_id);
-
-                child_id_list_t children = tet_store.data(tet_id).children;
-
-                // check if any child of tet_id (i.e. any active tet) is marked
-                // for refinement
-                bool is_child_ref(false);
-                for (size_t i=0; i<children.size(); i++) {
-                  edge_list_t chedge_list = tet_store.generate_edge_keys(children[i]);
-                  // Check each edge, see if it is marked for refinement
-                  for (size_t k=0; k<NUM_TET_EDGES; k++) {
-                    edge_t edge = chedge_list[k];
-
-                    if (tet_store.edge_store.get(edge).needs_refining == 1) {
-                      is_child_ref = true;
-                      continue;
-                    }
-                  }
-                }
-                // deactivate from deref if marked for ref
-                if (is_child_ref) {
-                  trace_out << tet_id << " Looping cancelled since child marked for refinement." << std::endl;
-                  for (auto child_id : children) {
-                    deactivate_deref_tet_edges(child_id);
-                  }
-                  deactivate_deref_tet_edges(tet_id);
-                  tet_store.mark_derefinement_decision(tet_id, AMR::Derefinement_Case::skip);
-                  continue;
-                }
-
-                // check if tet_id has been marked for deref-ref
-                edge_list_t pedge_list = tet_store.generate_edge_keys(tet_id);
-                // Check each edge, see if it is marked for refinement
-                for (size_t k=0; k<NUM_TET_EDGES; k++) {
-                  edge_t edge = pedge_list[k];
-
-                  // deactivate child-edges from deref if marked '2'
-                  if (tet_store.edge_store.get(edge).needs_refining == 2) {
-                    auto edge_nodes = edge.get_data();
-                    auto ch_node = node_connectivity.data().at(edge_nodes);
-                    std::array< edge_t, 2> ch_edge;
-                    ch_edge[0] = {edge_nodes[0], ch_node};
-                    ch_edge[1] = {edge_nodes[1], ch_node};
-                    tet_store.edge_store.get(ch_edge[0]).needs_derefining = 0;
-                    tet_store.edge_store.get(ch_edge[1]).needs_derefining = 0;
-                  }
-                }
-
-                // This is useful for later inspection
-                //edge_list_t edge_list = tet_store.generate_edge_keys(tet_id);
-                std::size_t num_to_derefine = 0; // Nodes
-
-                AMR::Refinement_Case refinement_case = tet_store.get_refinement_case(tet_id);
-
-                auto derefine_node_set = refiner.find_derefine_node_set(tet_store, tet_id);
-                // Find the set of nodes which are not in the parent
-                std::unordered_set<size_t> non_parent_nodes =
-                  refiner.child_exclusive_nodes(tet_store, tet_id);
-
-                //for (auto drnode: derefine_node_set)
-                //  trace_out << "derefine node: " << drnode << std::endl;
-
-                num_to_derefine = derefine_node_set.size();
-
-                if (num_to_derefine > 0) {
-                    trace_out << "num_to_derefine " << num_to_derefine << std::endl;
-                    trace_out << "ref_case " << refinement_case << std::endl;
-                    trace_out << "num children " << children.size() << std::endl;
-                }
-
-                //num_to_derefine = convert_derefine_edges_to_points(tet_store, tet_id, num_edges_to_derefine, refinement_case);
-
-                // "If nderefine = 1
-                if (num_to_derefine == 1)
-                {
-                    // If icase = 1:2
-
-                    //if (refinement_case == AMR::Refinement_Case::one_to_two)
-                    if (children.size() == 2)
-                    {
-                        // Accept as 2:1 derefine"
-                        trace_out << "Accept as 2:1" << std::endl;
-                        //refiner.derefine_two_to_one(tet_store, node_connectivity, tet_id);
-                        tet_store.mark_derefinement_decision(tet_id, AMR::Derefinement_Case::two_to_one);
-                    }
-                    // "Else
-                    else {
-                        // Deactivate all points"
-                        for (auto child_id : children) {
-                          deactivate_deref_tet_edges(child_id);
-                        }
-                        tet_store.mark_derefinement_decision(tet_id, AMR::Derefinement_Case::skip);
-                        trace_out << "giving up on deref decision. deactivate near 2:1 ntd = 1" << std::endl;
-                    }
-                }
-
-
-                // "If nderefine = 2
-                else if (num_to_derefine == 2)
-                {
-                    // If icase = 1:4
-                    //if (refinement_case == AMR::Refinement_Case::one_to_four)
-                    if (children.size() == 4)
-                    {
-                        // Accept as 4:2 derefine"
-                        trace_out << "Accept as 4:2" << std::endl;
-                        //refiner.derefine_four_to_two(tet_store,  node_connectivity, tet_id);
-                        tet_store.mark_derefinement_decision(tet_id, AMR::Derefinement_Case::four_to_two);
-                    }
-                    // "Else
-                    else {
-                        // Deactivate all points"
-                        for (auto child_id : children) {
-                          deactivate_deref_tet_edges(child_id);
-                        }
-                        tet_store.mark_derefinement_decision(tet_id, AMR::Derefinement_Case::skip);
-                        trace_out << "giving up on deref decision. deactivate near 4:2 ntd = 2" << std::endl;
-                    }
-                }
-
-                // "If nderefine = 3
-                else if (num_to_derefine == 3)
-                {
-                    // If icase = 1:4
-                    //if (refinement_case == AMR::Refinement_Case::one_to_four)
-                    if (children.size() == 4)
-                    {
-                        // Accept as 4:1 derefine"
-                        trace_out << "Accept as 4:1" << std::endl;
-                        //refiner.derefine_four_to_one(tet_store,  node_connectivity, tet_id);
-                        tet_store.mark_derefinement_decision(tet_id, AMR::Derefinement_Case::four_to_one);
-                    }
-                    // "Else if icase = 1:8
-                    //else if (refinement_case == AMR::Refinement_Case::one_to_eight)
-                    else if (children.size() == 8)
-                    {
-                        // we have a list of (non-parent) nodes that is marked
-                        // for derefinement. First, determine the nodes that are
-                        // unmarked for derefinement (or inactive_nodes). Then,
-                        // determine if these are on a single face.
-                        std::unordered_set<size_t> inactive_node_set;
-                        for (auto npn : non_parent_nodes) {
-                          if (derefine_node_set.count(npn) == 0)
-                            inactive_node_set.insert(npn);
-                        }
-                        Assert(inactive_node_set.size() == 3, "Incorrectly "
-                          "sized inactive-node set");
-                        auto same_face = check_same_face(tet_id, inactive_node_set);
-                        // If inactive points lie on same face
-                        if (same_face.first == true)
-                        {
-                            // Accept as 8:4 derefinement
-                            trace_out << "Accept as 8:4" << std::endl;
-
-                            // create a vector of node-array-pairs to mark edges
-                            // for refinement 1:4
-                            std::vector< std::array< std::size_t, 2 > > ref_edges;
-                            trace_out << "inactive nodes on same face: ";
-                            for (auto n:inactive_node_set) {
-                              trace_out << n << ", ";
-                              ref_edges.push_back(node_connectivity.get(n));
-                            }
-                            trace_out << std::endl;
-
-                            tet_store.edge_store.mark_edges_for_deref_ref(ref_edges);
-                            //refiner.derefine_eight_to_four(tet_store,  node_connectivity, tet_id);
-                            tet_store.mark_derefinement_decision(tet_id, AMR::Derefinement_Case::eight_to_four);
-                        }
-                        // "Else
-                        else {
-                            // Deactivate all points"
-                            for (auto child_id : children) {
-                              deactivate_deref_tet_edges(child_id);
-                            }
-                            tet_store.mark_derefinement_decision(tet_id, AMR::Derefinement_Case::skip);
-                            trace_out << "giving up on deref decision. deactivate near 8:4 ntd = 3" << std::endl;
-                        }
-
-                    }
-                }
-
-                // "If nderefine = 4
-                else if (num_to_derefine == 4)
-                //else if (children.size() == 4)
-                {
-                    // we have a list of (non-parent) nodes that is marked
-                    // for derefinement. First, determine the nodes that are
-                    // unmarked for derefinement (or inactive_nodes). Then,
-                    // determine if these are on a single face.
-                    std::unordered_set<size_t> inactive_node_set;
-                    for (auto npn : non_parent_nodes) {
-                      if (derefine_node_set.count(npn) == 0)
-                        inactive_node_set.insert(npn);
-                    }
-                    Assert(inactive_node_set.size() == 2, "Incorrectly "
-                      "sized inactive-node set");
-                    // Check if the inactive point belong to the same parent
-                    // face and deactivate the third point on that face
-                    auto same_face = check_same_face(tet_id, inactive_node_set);
-
-                    if (same_face.first == true)
-                    {
-                        // deactivate the edges associated with same_face.second
-                        for (size_t i = 0; i < children.size(); i++)
-                        {
-                          edge_list_t edge_list = tet_store.generate_edge_keys(children[i]);
-                          for (size_t k = 0; k < NUM_TET_EDGES; k++)
-                          {
-                            edge_t edge = edge_list[k];
-                            size_t A = edge.first();
-                            size_t B = edge.second();
-                            if (A == same_face.second || B == same_face.second)
-                              tet_store.edge_store.get(edge).needs_derefining = false;
-                          }
-                        }
-
-                        // create a vector of node-array-pairs to mark edges
-                        // for refinement 1:4
-                        inactive_node_set.insert(same_face.second);
-                        std::vector< std::array< std::size_t, 2 > > ref_edges;
-                        for (auto n:inactive_node_set) {
-                          ref_edges.push_back(node_connectivity.get(n));<--- Consider using std::transform algorithm instead of a raw loop.
-                        }
-
-                        tet_store.edge_store.mark_edges_for_deref_ref(ref_edges);
-
-                        // Accept as 8:4 derefinement
-                        trace_out << "Accept as 8:4" << std::endl;
-                        //refiner.derefine_eight_to_four(tet_store,  node_connectivity, tet_id);
-                        tet_store.mark_derefinement_decision(tet_id, AMR::Derefinement_Case::eight_to_four);
-                    }
-                    // "Else
-                    else {
-                        // Deactivate all points"
-                        for (auto child_id : children) {
-                          deactivate_deref_tet_edges(child_id);
-                        }
-                        tet_store.mark_derefinement_decision(tet_id, AMR::Derefinement_Case::skip);
-                        trace_out << "giving up on deref decision. deactivate near 8:4 ntd = 4" << std::endl;
-                    }
-                }
-
-                // "If nderefine = 5
-                else if (num_to_derefine == 5)
-                {
-                    // Accept as 8:2 derefine"
-                    trace_out << "Accept as 8:2 " << std::endl;
-                    //refiner.derefine_eight_to_two(tet_store,  node_connectivity, tet_id);
-                    tet_store.mark_derefinement_decision(tet_id, AMR::Derefinement_Case::eight_to_two);
-                }
-
-                // "If nderefine = 6
-                else if (num_to_derefine == 6)
-                {
-                    // Accept as 8:1 derefine"
-                    trace_out << "Accept as 8:1" << std::endl;
-                    //refiner.derefine_eight_to_one(tet_store,  node_connectivity, tet_id);
-                    tet_store.mark_derefinement_decision(tet_id, AMR::Derefinement_Case::eight_to_one);
-                }
-
-                // "If nderefine = 0
-                else {
-                    tet_store.mark_derefinement_decision(tet_id, AMR::Derefinement_Case::skip);
-                    // Deactivate all points"
-                    for (auto child_id : children) {
-                      deactivate_deref_tet_edges(child_id);
-                    }
-                    trace_out << "giving up with no deref decision because nderefine = 0" << std::endl;
-                }
-            }
-
-            // If nothing changed during that round, break
-            if (!tet_store.marked_derefinements.get_state_changed())
-            {
-                trace_out << "Terminating loop at iter " << iter << std::endl;
-                break;
-            }
-            trace_out << "End iter " << iter << std::endl;
-            // clear out set of elements considered during this iteration
-            done_deref_marking.clear();
-        }
-        trace_out << "Deref Loop took " << iter << " rounds." << std::endl;
-    }
-
-    // TODO: document
-    void mesh_adapter_t::perform_derefinement()
-    {
-        trace_out << "Perform deref" << std::endl;
-
-        // Do derefinements
-        for (const auto& kv : tet_store.tets)
-        {
-            size_t tet_id = kv.first;
-            //size_t parent_id = 0;
-
-            // TODO: Do I really want to loop all tets?
-
-            // TODO: is this doing a double lookup?
-            if (tet_store.has_derefinement_decision(tet_id))
-            {
-                trace_out << "Do derefine of " << tet_id << std::endl;
-                //size_t parent_id = tet_store.get_parent_id(tet_id);
-                //trace_out << "Parent = " << parent_id << std::endl;
-                switch(tet_store.marked_derefinements.get(tet_id))
-                {
-                    case AMR::Derefinement_Case::two_to_one:
-                        refiner.derefine_two_to_one(tet_store,node_connectivity,tet_id);
-                        trace_out << "Completed derefine 2:1 of " << tet_id << std::endl;
-                        break;
-                    case AMR::Derefinement_Case::four_to_one:
-                        refiner.derefine_four_to_one(tet_store,node_connectivity,tet_id);
-                        trace_out << "Completed derefine 4:1 of " << tet_id << std::endl;
-                        break;
-                    case AMR::Derefinement_Case::four_to_two:
-                        refiner.derefine_four_to_two(tet_store,node_connectivity,tet_id);
-                        trace_out << "Completed derefine 4:2 of " << tet_id << std::endl;
-                        break;
-                    case AMR::Derefinement_Case::eight_to_one:
-                        refiner.derefine_eight_to_one(tet_store,node_connectivity,tet_id);
-                        trace_out << "Completed derefine 8:1 of " << tet_id << std::endl;
-                        break;
-                    case AMR::Derefinement_Case::eight_to_two:
-                        refiner.derefine_eight_to_two(tet_store,node_connectivity,tet_id);
-                        trace_out << "Completed derefine 8:2 of " << tet_id << std::endl;
-                        break;
-                    case AMR::Derefinement_Case::eight_to_four:
-                        refiner.derefine_eight_to_four(tet_store,node_connectivity,tet_id);
-                        trace_out << "Completed derefine 8:4 of " << tet_id << std::endl;
-                        break;
-                    case AMR::Derefinement_Case::skip:
-                        // What do we do with skip?
-                        break;
-                }
-                // Mark tet as not needing derefinement
-                tet_store.marked_derefinements.erase(tet_id);
-            }
-        }
-
-        node_connectivity.print();
-        refiner.delete_intermediates_of_children(tet_store);
-        tet_store.process_delete_list();
-        tet_store.print_node_types();
-
-        lock_intermediates();
-
-        for (auto& kv : tet_store.edge_store.edges) {
-           auto& local = kv.second;
-           local.needs_derefining = 0;
-           if (local.needs_refining == 2) local.needs_refining = 0;
-        }
-    }
-
-}
-
-#if defined(__clang__)
-  #pragma clang diagnostic pop
-#endif
+  // Echo errors and warnings accumulated during parsing
+  diagnostics( print, cmd.get< tag::error >() );
+
+  // Strip command line (and its underlying tagged tuple) from PEGTL instruments
+  // and transfer it out
+  cmdline = std::move( cmd );
+
+  // If we got here, the parser has succeeded
+  print.item("Parsed command line", "success");
+
+  // Print out help on all command-line arguments if the executable was invoked
+  // without arguments or the help was requested
+  const auto helpcmd = cmdline.get< tag::help >();
+  if (argc == 1 || helpcmd) {
+    print.help< tk::QUIET >( tk::meshconv_executable(),
+                             cmdline.get< tag::cmdinfo >(),
+                             "Command-line Parameters:", "-" );
+    print.mandatory< tk::QUIET >(
+     "The '--" + kw::input().string() + " <filename>' and the "
+     "'--" + kw::output().string() + " <filename>' arguments are mandatory." );
+    print.usage< tk::QUIET >(
+      tk::meshconv_executable(),
+      tk::meshconv_executable() + " -" + *kw::input().alias() + " in.msh -" +
+        *kw::output().alias() + " out.exo",
+      "will read data from 'in.msh' (in Gmsh format) and output it to "
+      "out.exo' (in ExodusII format)" );
+  }
+
+  // Print out verbose help for a single keyword if requested
+  const auto helpkw = cmdline.get< tag::helpkw >();
+  if (!helpkw.keyword.empty())
+    print.helpkw< tk::QUIET >( tk::meshconv_executable(), helpkw );
+
+  // Print out version information if it was requested
+  const auto version = cmdline.get< tag::version >();
+  if (version)
+    print.version< tk::QUIET >( tk::meshconv_executable(),
+                                tk::quinoa_version(),
+                                tk::git_commit(),
+                                tk::copyright() );
+
+  // Print out license information if it was requested
+  const auto license = cmdline.get< tag::license >();
+  if (license)
+    print.license< tk::QUIET >( tk::meshconv_executable(), tk::license() );
+
+  // Immediately exit if any help was output or was called without any argument
+  // or version or license info was requested with zero exit code
+  if (argc == 1 || helpcmd || !helpkw.keyword.empty() || version || license)
+    CkExit();
+
+  // Make sure mandatory arguments are set
+  auto ialias = kw::input().alias();
+  auto oalias = kw::output().alias();<--- Variable 'oalias' is assigned a value that is never used.
+  ErrChk( !(cmdline.get< tag::io, tag::input >().empty()),
+          "Mandatory input file not specified. "
+          "Use '--" + kw::input().string() + " <filename>'" +
+          ( ialias ? " or '-" + *ialias + " <filename>'" : "" ) + '.' );
+  ErrChk( !(cmdline.get< tag::io, tag::output >().empty()),
+          "Mandatory output file not specified. "
+          "Use '--" + kw::output().string() + " <filename>'" +
+          ( oalias ? " or '-" + *oalias + " <filename>'" : "" ) + '.' );
+}
 
diff --git a/Release/cppcheck/26.html b/Release/cppcheck/26.html index 150e4b1ac0be..439d99754d61 100644 --- a/Release/cppcheck/26.html +++ b/Release/cppcheck/26.html @@ -152,12 +152,12 @@
  1
@@ -328,175 +328,305 @@ 

Cppcheck report - [

// *****************************************************************************
+169
+170
+171
+172
+173
+174
+175
+176
+177
+178
+179
+180
+181
+182
+183
+184
+185
+186
+187
+188
+189
+190
+191
+192
+193
+194
+195
+196
+197
+198
+199
+200
+201
+202
+203
+204
+205
+206
+207
+208
+209
+210
+211
+212
+213
+214
+215
+216
+217
+218
+219
+220
+221
+222
+223
+224
+225
+226
+227
+228
+229
+230
+231
+232
+233
+234
// *****************************************************************************
 /*!
-  \file      src/Main/MeshConv.cpp
+  \file      src/Main/UnitTest.cpp
   \copyright 2012-2015 J. Bakosi,
              2016-2018 Los Alamos National Security, LLC.,
              2019-2021 Triad National Security, LLC.
              All rights reserved. See the LICENSE file for details.
-  \brief     Mesh file converter Charm++ main chare
-  \details   Mesh file converter Charm++ main chare. This file contains the
-    definition of the Charm++ main chare, equivalent to main() in Charm++-land.
-*/
-// *****************************************************************************
-
-#include <vector>
-#include <utility>
-#include <iostream>
-
-#include "Print.hpp"
-#include "Timer.hpp"
-#include "Types.hpp"
-#include "QuinoaConfig.hpp"
-#include "Init.hpp"
-#include "Tags.hpp"
-#include "MeshConvDriver.hpp"
-#include "MeshConv/CmdLine/CmdLine.hpp"
-#include "MeshConv/CmdLine/Parser.hpp"
-#include "ProcessException.hpp"
-#include "ChareStateCollector.hpp"
-
-#include "NoWarning/charm.hpp"
-#include "NoWarning/meshconv.decl.h"
-
-#if defined(__clang__)
-  #pragma clang diagnostic push
-  #pragma clang diagnostic ignored "-Wmissing-variable-declarations"
-#endif
-
-//! \brief Charm handle to the main proxy, facilitates call-back to finalize,
-//!    etc., must be in global scope, unique per executable
-CProxy_Main mainProxy;
-
-//! Chare state collector Charm++ chare group proxy
-tk::CProxy_ChareStateCollector stateProxy;
+  \brief     UnitTest's Charm++ main chare and main().
+  \details   UnitTest's Charm++ main chare and main(). This file contains
+    the definition of the Charm++ main chare, equivalent to main() in Charm++-
+    land, running the serial and Charm++ unit tests as well as the ordinary
+    main() function, running the MPI unit test suite.
+*/
+// *****************************************************************************
+
+#include <map>
+#include <vector>
+#include <string>
+#include <iostream>
+#include <utility>
+#include <cstddef>
+
+#include "NoWarning/tut_runner.hpp"
+
+#include "NoWarning/tutsuite.decl.h"
+#include "NoWarning/unittest.decl.h"
+
+#include "Print.hpp"
+#include "Timer.hpp"
+#include "Tags.hpp"
+#include "Exception.hpp"
+#include "Init.hpp"
+#include "QuinoaConfig.hpp"
+#include "HelpFactory.hpp"
+#include "Assessment.hpp"
+#include "ProcessException.hpp"
+#include "UnitTest/CmdLine/CmdLine.hpp"
+#include "UnitTestPrint.hpp"
+#include "UnitTestDriver.hpp"
+#include "UnitTest/CmdLine/Parser.hpp"
+#include "TUTConfig.hpp"
+#include "ChareStateCollector.hpp"
+#include "QuietCerr.hpp"
 
-//! If true, call and stack traces are to be output with exceptions
-//! \note This is true by default so that the trace is always output between
-//!   program start and the Main ctor in which the user-input from command line
-//!   setting for this overrides this true setting.
-bool g_trace = true;
-
-#if defined(__clang__)
-  #pragma clang diagnostic pop
-#endif
-
-//! \brief Charm++ main chare for the mesh converter executable, meshconv.
-//! \details Note that this object should not be in a namespace.
-// cppcheck-suppress noConstructor
-class Main : public CBase_Main {<--- Unmatched suppression: noConstructor
-
-  public:
-    //! \brief Constructor
-    //! \details MeshConv's main chare constructor is the entry point of the
-    //!   program, called by the Charm++ runtime system. The constructor does
-    //!   basic initialization steps, e.g., parser the command-line, prints out
-    //!   some useful information to screen (in verbose mode), and instantiates
-    //!   a driver. Since Charm++ is fully asynchronous, the constructor
-    //!   usually spawns asynchronous objects and immediately exits. Thus in the
-    //!   body of the main chare constructor we fire up an 'execute' chare,
-    //!   which then calls back to Main::execute(). Finishing the main chare
-    //!   constructor the Charm++ runtime system then starts the
-    //!   network-migration of all global-scope data (if any). The execute chare
-    //!   calling back to Main::execute() signals the end of the migration of
-    //!   the global-scope data. Then we are ready to execute the driver which
-    //!   calls back to Main::finalize() when it finished. Then finalize() exits
-    //!   by calling Charm++'s CkExit(), shutting down the runtime system.
-    //! \see http://charm.cs.illinois.edu/manuals/html/charm++/manual.html
-    Main( CkArgMsg* msg )
-    try :
-      m_signal( tk::setSignalHandlers() ),
-      m_cmdline(),
-      // Parse command line into m_cmdline using default simple pretty printer
-      m_cmdParser( msg->argc, msg->argv, tk::Print(), m_cmdline ),
-      // Create MeshConv driver
-      m_driver( tk::Main< meshconv::MeshConvDriver >
-                        ( msg->argc, msg->argv,
-                          m_cmdline,
-                          tk::HeaderType::MESHCONV,
-                          tk::meshconv_executable(),
-                          m_cmdline.get< tag::io, tag::screen >(),
-                          m_cmdline.get< tag::io, tag::nrestart >() ) ),
-      m_timer(1),       // Start new timer measuring the total runtime
-      m_timestamp()
-    {
-      delete msg;
-      g_trace = m_cmdline.get< tag::trace >();
-      tk::MainCtor( mainProxy, thisProxy, m_timer, m_cmdline,
-                    CkCallback( CkIndex_Main::quiescence(), thisProxy ) );
-      // If quiescence detection is on or user requested it, create chare state
-      // collector Charm++ chare group
-      if ( m_cmdline.get< tag::chare >() || m_cmdline.get< tag::quiescence >() )
-        stateProxy = tk::CProxy_ChareStateCollector::ckNew();
-      // Fire up an asynchronous execute object, which when created at some
-      // future point in time will call back to this->execute(). This is
-      // necessary so that this->execute() can access already migrated
-      // global-scope data.
-      CProxy_execute::ckNew();
-    } catch (...) { tk::processExceptionCharm(); }
-
-    void execute() {
-      try {
-        m_timestamp.emplace_back("Migrate global-scope data", m_timer[1].hms());
-        m_driver.execute();
-      } catch (...) { tk::processExceptionCharm(); }
-    }
-
-    //! Towards normal exit but collect chare state first (if any)
-    void finalize() {
-      tk::finalize( m_cmdline, m_timer, stateProxy, m_timestamp,
-        m_cmdline.get< tag::io, tag::screen >(),
-        m_cmdline.get< tag::io, tag::nrestart >(),
-        CkCallback( CkIndex_Main::dumpstate(nullptr), thisProxy ) );
-    }
-
-    //! Add a time stamp contributing to final timers output
-    void timestamp( std::string label, tk::real stamp ) {
-      try {
-        m_timestamp.emplace_back( label, tk::hms( stamp ) );
-      } catch (...) { tk::processExceptionCharm(); }
-    }
-    //! Add multiple time stamps contributing to final timers output
-    void timestamp( const std::vector< std::pair< std::string, tk::real > >& s )
-    { for (const auto& t : s) timestamp( t.first, t.second ); }
-
-    //! Entry method triggered when quiescence is detected
-    void quiescence() {
-      try {
-        stateProxy.collect( /* error= */ true,
-          CkCallback( CkIndex_Main::dumpstate(nullptr), thisProxy ) );
-      } catch (...) { tk::processExceptionCharm(); }
-    }
-
-    //! Dump chare state
-    void dumpstate( CkReductionMsg* msg ) {
-      tk::dumpstate( m_cmdline,
-        m_cmdline.get< tag::io, tag::screen >(),
-        m_cmdline.get< tag::io, tag::nrestart >(),
-        msg );
-    }
-
-  private:
-    int m_signal;                               //!< Used to set signal handlers
-    meshconv::ctr::CmdLine m_cmdline;           //!< Command line
-    meshconv::CmdLineParser m_cmdParser;        //!< Command line parser
-    meshconv::MeshConvDriver m_driver;          //!< Driver
-    std::vector< tk::Timer > m_timer;           //!< Timers
-
-    //! Time stamps in h:m:s with labels
-    std::vector< std::pair< std::string, tk::Timer::Watch > > m_timestamp;
-};
-
-//! \brief Charm++ chare execute
-//! \details By the time this object is constructed, the Charm++ runtime system
-//!    has finished migrating all global-scoped read-only objects which happens
-//!    after the main chare constructor has finished.
-class execute : public CBase_execute {
-  public: execute() { mainProxy.execute(); }
-};
-
-#include "NoWarning/meshconv.def.h"
+#if defined(__clang__)
+  #pragma clang diagnostic push
+  #pragma clang diagnostic ignored "-Wmissing-variable-declarations"
+#endif
+
+//! \brief Charm handle to the main proxy, facilitates call-back to finalize,
+//!    etc., must be in global scope, unique per executable
+CProxy_Main mainProxy;
+
+//! Chare state collector Charm++ chare group proxy
+tk::CProxy_ChareStateCollector stateProxy;
+
+//! If true, call and stack traces are to be output with exceptions
+//! \note This is true by default so that the trace is always output between
+//!   program start and the Main ctor in which the user-input from command line
+//!   setting for this overrides this true setting.
+bool g_trace = true;
+
+#if defined(__clang__)
+  #pragma clang diagnostic pop
+#endif
+
+//! UnitTest declarations and definitions
+namespace unittest {
+
+//! Global-scope data. Initialized by the main chare and distibuted to all PEs
+//! by the Charm++ runtime system. Though semantically not const, all these
+//! global data should be considered read-only. See also
+//! http://charm.cs.illinois.edu/manuals/html/charm++/manual.html. The data
+//! below is global-scope because they must be available to all PEs which could
+//! be on different machines.
+
+#if defined(__clang__)
+  #pragma clang diagnostic push
+  #pragma clang diagnostic ignored "-Wmissing-variable-declarations"
+#endif
+
+//! Template Unit Test test runner
+tut::test_runner_singleton g_runner;
+
+//! Test suite Charm++ proxy facilitating call-back to unit test suite by
+//! individual unit tests spawning Charm++ chares
+CProxy_TUTSuite g_suiteProxy;
+
+//! UnitTest executable name. So that FileParser's unit tests can access a file
+//! for opening.
+std::string g_executable;
+
+//! Max number of tests in every group
+int g_maxTestsInGroup = tut::MAX_TESTS_IN_GROUP;
+
+#if defined(__clang__)
+  #pragma clang diagnostic pop
+#endif
+
+//! Pack/Unpack test runner. This Pack/Unpack method (re-)creates the
+//! test runner singleton on all processing elements. Therefore we circumvent
+//! Charm's usual pack/unpack for this type, and thus sizing does not make
+//! sense: sizing is a no-op. We could initialize the stack in UnitTestDriver's
+//! constructor and let this function re-create the runner only when unpacking,
+//! but that leads to repeating the same code twice: once in UnitTestDriver's
+//! constructor, once here. Another option is to use this pack/unpack routine to
+//! both initially create (when packing) and to re-create (when unpacking) the
+//! runner, which eliminates the need for pre-creating the object in
+//! UnitTestDriver's constructor and therefore eliminates the repeated code.
+//! This explains the guard for sizing: the code below is called for packing
+//! only (in serial) and packing and unpacking (in parallel).
+inline void operator|( PUP::er& p, tut::test_runner_singleton& runner )
+{ if (!p.isSizing()) runner = tut::test_runner_singleton(); }
+
+} // unittest::
+
+//! \brief Charm++ main chare for the unit test suite executable, unittest.
+//! \details Note that this object should not be in a namespace.
+// cppcheck-suppress noConstructor
+class Main : public CBase_Main {<--- Unmatched suppression: noConstructor
+
+  public:
+    //! \brief Constructor
+    //! \details UnitTest's main chare constructor is the entry point of the
+    //!   program, called by the Charm++ runtime system. The constructor does
+    //!   basic initialization steps, e.g., parser the command-line, prints out
+    //!   some useful information to screen (in verbose mode), and instantiates
+    //!   a driver. Since Charm++ is fully asynchronous, the constructor
+    //!   usually spawns asynchronous objects and immediately exits. Thus in the
+    //!   body of the main chare constructor we fire up an 'execute' chare,
+    //!   which then calls back to Main::execute(). Finishing the main chare
+    //!   constructor the Charm++ runtime system then starts the
+    //!   network-migration of all global-scope data (if any). The execute chare
+    //!   calling back to Main::execute() signals the end of the migration of
+    //!   the global-scope data. Then we are ready to execute the driver. Since
+    //!   the unit test suite is parallel and asynchronous, its driver fires up
+    //!   additional Charm++ chare objects which then call back to
+    //!   Main::finalize() at some point in the future when all work has been
+    //!   finished. finalize() then exits by calling Charm++'s CkExit(),
+    //!   shutting down the runtime system.
+    //! \see http://charm.cs.illinois.edu/manuals/html/charm++/manual.html
+    Main( CkArgMsg* msg )
+    try :
+      m_signal( tk::setSignalHandlers() ),
+      m_helped( false ),
+      m_cmdline(),
+      // Parse command line into m_cmdline using default simple pretty printer
+      m_cmdParser( msg->argc, msg->argv, tk::Print(), m_cmdline, m_helped ),
+      // Create UnitTest driver
+      m_driver( tk::Main< unittest::UnitTestDriver >
+                        ( msg->argc, msg->argv,
+                          m_cmdline,
+                          tk::HeaderType::UNITTEST,
+                          tk::unittest_executable(),
+                          m_cmdline.get< tag::io, tag::screen >(),
+                          m_cmdline.get< tag::io, tag::nrestart >() ) ),
+      m_timer(1), // Start new timer measuring the serial+Charm++ runtime
+      m_timestamp()
+    {
+      g_trace = m_cmdline.get< tag::trace >();
+      // Immediately exit if any help was requested; help is printed in main()
+      if (m_helped) CkExit();
+      // Save executable name to global-scope string so FileParser can access it
+      unittest::g_executable = msg->argv[0];
+      delete msg;
+      // Call generic mainchare contructor
+      tk::MainCtor( mainProxy, thisProxy, m_timer, m_cmdline,
+                    CkCallback( CkIndex_Main::quiescence(), thisProxy ) );
+      // If quiescence detection is on or user requested it, create chare state
+      // collector Charm++ chare group
+      if ( m_cmdline.get< tag::chare >() || m_cmdline.get< tag::quiescence >() )
+        stateProxy = tk::CProxy_ChareStateCollector::ckNew();
+      // Fire up an asynchronous execute object, which when created at some
+      // future point in time will call back to this->execute(). This is
+      // necessary so that this->execute() can access already migrated
+      // global-scope data.
+      CProxy_execute::ckNew();
+      // Quiet std::cerr
+      tk::CProxy_QuietCerr::ckNew();
+    } catch (...) { tk::processExceptionCharm(); }
+
+    void execute() {
+      try {
+        m_timestamp.emplace_back("Migrate global-scope data", m_timer[1].hms());
+        m_driver.execute();       // fires up async chares
+      } catch (...) { tk::processExceptionCharm(); }
+    }
+
+    //! Towards normal exit but collect chare state first (if any)
+    void finalize( bool pass ) {
+      tk::finalize( m_cmdline, m_timer, stateProxy, m_timestamp,
+        m_cmdline.get< tag::io, tag::screen >(),
+        m_cmdline.get< tag::io, tag::nrestart >(),
+        CkCallback( CkIndex_Main::dumpstate(nullptr), thisProxy ),
+        pass );
+    }
+
+    //! Entry method triggered when quiescence is detected
+    void quiescence() {
+      try {
+        stateProxy.collect( /* error= */ true,
+          CkCallback( CkIndex_Main::dumpstate(nullptr), thisProxy ) );
+      } catch (...) { tk::processExceptionCharm(); }
+    }
+
+    //! Dump chare state
+    void dumpstate( CkReductionMsg* msg ) {
+      tk::dumpstate( m_cmdline,
+        m_cmdline.get< tag::io, tag::screen >(),
+        m_cmdline.get< tag::io, tag::nrestart >(),
+        msg );
+    }
+
+  private:
+    int m_signal;                               //!< Used to set signal handlers
+    bool m_helped;      //!< Indicates if help was requested on the command line
+    unittest::ctr::CmdLine m_cmdline;                   //!< Command line
+    unittest::CmdLineParser m_cmdParser;                //!< Command line parser
+    unittest::UnitTestDriver m_driver;                  //!< Driver
+    std::vector< tk::Timer > m_timer;                   //!< Timers
+
+    //! Time stamps in h:m:s with labels
+    std::vector< std::pair< std::string, tk::Timer::Watch > > m_timestamp;
+};
+
+//! \brief Charm++ chare execute
+//! \details By the time this object is constructed, the Charm++ runtime system
+//!    has finished migrating all global-scoped read-only objects which happens
+//!    after the main chare constructor has finished.
+class execute : public CBase_execute {
+  public: execute() { mainProxy.execute(); }
+};
+
+#include "NoWarning/unittest.def.h"
 
diff --git a/Release/cppcheck/27.html b/Release/cppcheck/27.html index 61d20a942438..98511b10b2c7 100644 --- a/Release/cppcheck/27.html +++ b/Release/cppcheck/27.html @@ -152,12 +152,12 @@
  1
@@ -393,240 +393,524 @@ 

Cppcheck report - [

// *****************************************************************************
+234
+235
+236
+237
+238
+239
+240
+241
+242
+243
+244
+245
+246
+247
+248
+249
+250
+251
+252
+253
+254
+255
+256
+257
+258
+259
+260
+261
+262
+263
+264
+265
+266
+267
+268
+269
+270
+271
+272
+273
+274
+275
+276
+277
+278
+279
+280
+281
+282
+283
+284
+285
+286
+287
+288
+289
+290
+291
+292
+293
+294
+295
+296
+297
+298
+299
+300
+301
+302
+303
+304
+305
+306
+307
+308
+309
+310
+311
+312
+313
+314
+315
+316
+317
+318
+319
+320
+321
+322
+323
+324
+325
+326
+327
+328
+329
+330
+331
+332
+333
+334
+335
+336
+337
+338
+339
+340
+341
+342
+343
+344
+345
+346
+347
+348
+349
+350
+351
+352
+353
+354
+355
+356
+357
+358
+359
+360
+361
+362
+363
+364
+365
+366
+367
+368
+369
+370
+371
+372
+373
+374
+375
+376
// *****************************************************************************
 /*!
-  \file      src/Main/UnitTest.cpp
+  \file      src/Mesh/Reorder.cpp
   \copyright 2012-2015 J. Bakosi,
              2016-2018 Los Alamos National Security, LLC.,
              2019-2021 Triad National Security, LLC.
              All rights reserved. See the LICENSE file for details.
-  \brief     UnitTest's Charm++ main chare and main().
-  \details   UnitTest's Charm++ main chare and main(). This file contains
-    the definition of the Charm++ main chare, equivalent to main() in Charm++-
-    land, running the serial and Charm++ unit tests as well as the ordinary
-    main() function, running the MPI unit test suite.
-*/
-// *****************************************************************************
-
+  \brief     Mesh reordering routines for unstructured meshes
+  \details   Mesh reordering routines for unstructured meshes.
+*/
+// *****************************************************************************
+
+#include <algorithm>
+#include <iterator>
+#include <unordered_map>
 #include <map>
-#include <vector>
-#include <string>
-#include <iostream>
-#include <utility>
-#include <cstddef>
-
-#include "NoWarning/tut_runner.hpp"
+#include <tuple>
+#include <cstddef>
+
+#include "Reorder.hpp"
+#include "Exception.hpp"
+#include "ContainerUtil.hpp"
+#include "Vector.hpp"
 
-#include "NoWarning/tutsuite.decl.h"
-#include "NoWarning/unittest.decl.h"
-
-#include "Print.hpp"
-#include "Timer.hpp"
-#include "Tags.hpp"
-#include "Exception.hpp"
-#include "Init.hpp"
-#include "QuinoaConfig.hpp"
-#include "HelpFactory.hpp"
-#include "Assessment.hpp"
-#include "ProcessException.hpp"
-#include "UnitTest/CmdLine/CmdLine.hpp"
-#include "UnitTestPrint.hpp"
-#include "UnitTestDriver.hpp"
-#include "UnitTest/CmdLine/Parser.hpp"
-#include "TUTConfig.hpp"
-#include "ChareStateCollector.hpp"
-#include "QuietCerr.hpp"
+namespace tk {
+
+std::size_t
+shiftToZero( std::vector< std::size_t >& inpoel )
+// *****************************************************************************
+//  Shift node IDs to start with zero in element connectivity
+//! \param[inout] inpoel Inteconnectivity of points and elements
+//! \return Amount shifted
+//! \details This function implements a simple reordering of the node ids of the
+//!   element connectivity in inpoel by shifting the node ids so that the
+//!   smallest is zero.
+//! \note It is okay to call this function with an empty container; it will
+//!    simply return without throwing an exception.
+// *****************************************************************************
+{
+  if (inpoel.empty()) return 0;
+
+  // find smallest node id
+  auto minId = *std::min_element( begin(inpoel), end(inpoel) );
 
-#if defined(__clang__)
-  #pragma clang diagnostic push
-  #pragma clang diagnostic ignored "-Wmissing-variable-declarations"
-#endif
-
-//! \brief Charm handle to the main proxy, facilitates call-back to finalize,
-//!    etc., must be in global scope, unique per executable
-CProxy_Main mainProxy;
-
-//! Chare state collector Charm++ chare group proxy
-tk::CProxy_ChareStateCollector stateProxy;
-
-//! If true, call and stack traces are to be output with exceptions
-//! \note This is true by default so that the trace is always output between
-//!   program start and the Main ctor in which the user-input from command line
-//!   setting for this overrides this true setting.
-bool g_trace = true;
-
-#if defined(__clang__)
-  #pragma clang diagnostic pop
-#endif
-
-//! UnitTest declarations and definitions
-namespace unittest {
+  // shift node ids to start from zero
+  // cppcheck-suppress useStlAlgorithm
+  for (auto& n : inpoel) n -= minId;
+
+  return minId;
+}
+
+void
+remap( std::vector< std::size_t >& ids, const std::vector< std::size_t >& map )
+// *****************************************************************************
+//  Apply new maping to vector of indices
+//! \param[inout] ids Vector of integer IDs to remap
+//! \param[in] map Array of indices creating a new order
+//! \details This function applies a mapping (reordering) to the integer IDs
+//!   passed in using the map passed in. The mapping is expressed between the
+//!   array index and its value. The function overwrites every value, i, of
+//!   vector ids with map[i].
+//! \note The sizes of ids and map need not equal. Only the maximum index in ids
+//!   must be lower than the size of map.
+//! \note It is okay to call this function with either of the containers empty;
+//!   it will simply return without throwing an exception.
+// *****************************************************************************
+{
+  if (ids.empty() || map.empty()) return;
 
-//! Global-scope data. Initialized by the main chare and distibuted to all PEs
-//! by the Charm++ runtime system. Though semantically not const, all these
-//! global data should be considered read-only. See also
-//! http://charm.cs.illinois.edu/manuals/html/charm++/manual.html. The data
-//! below is global-scope because they must be available to all PEs which could
-//! be on different machines.
-
-#if defined(__clang__)
-  #pragma clang diagnostic push
-  #pragma clang diagnostic ignored "-Wmissing-variable-declarations"
-#endif
-
-//! Template Unit Test test runner
-tut::test_runner_singleton g_runner;
-
-//! Test suite Charm++ proxy facilitating call-back to unit test suite by
-//! individual unit tests spawning Charm++ chares
-CProxy_TUTSuite g_suiteProxy;
-
-//! UnitTest executable name. So that FileParser's unit tests can access a file
-//! for opening.
-std::string g_executable;
-
-//! Max number of tests in every group
-int g_maxTestsInGroup = tut::MAX_TESTS_IN_GROUP;
+  Assert( *max_element( begin(ids), end(ids) ) < map.size(),
+          "Indexing out of bounds" );
+
+  // remap integer IDs in vector ids
+  // cppcheck-suppress useStlAlgorithm
+  for (auto& i : ids) i = map[i];
+}
+
+void
+remap( std::vector< tk::real >& r, const std::vector< std::size_t >& map )
+// *****************************************************************************
+//  Apply new maping to vector of real numbers
+//! \param[inout] r Vector of real numbers to remap
+//! \param[in] map Array of indices creating a new order
+//! \details This function applies a mapping (reordering) to the real values
+//!   passed in using the map passed in. The mapping is expressed between the
+//!   array index and its value. The function moves every value r[i] to
+//!   r[ map[i] ].
+//! \note The sizes of r and map must be equal and the maximum index in map must
+//!   be lower than the size of map.
+//! \note It is okay to call this function with either of the containers empty;
+//!   it will simply return without throwing an exception.
+// *****************************************************************************
+{
+  if (r.empty() || map.empty()) return;
 
-#if defined(__clang__)
-  #pragma clang diagnostic pop
-#endif
+  Assert( r.size() == map.size(), "Size mismatch" );
+  Assert( *max_element( begin(map), end(map) ) < map.size(),
+          "Indexing out of bounds" );
 
-//! Pack/Unpack test runner. This Pack/Unpack method (re-)creates the
-//! test runner singleton on all processing elements. Therefore we circumvent
-//! Charm's usual pack/unpack for this type, and thus sizing does not make
-//! sense: sizing is a no-op. We could initialize the stack in UnitTestDriver's
-//! constructor and let this function re-create the runner only when unpacking,
-//! but that leads to repeating the same code twice: once in UnitTestDriver's
-//! constructor, once here. Another option is to use this pack/unpack routine to
-//! both initially create (when packing) and to re-create (when unpacking) the
-//! runner, which eliminates the need for pre-creating the object in
-//! UnitTestDriver's constructor and therefore eliminates the repeated code.
-//! This explains the guard for sizing: the code below is called for packing
-//! only (in serial) and packing and unpacking (in parallel).
-inline void operator|( PUP::er& p, tut::test_runner_singleton& runner )
-{ if (!p.isSizing()) runner = tut::test_runner_singleton(); }
-
-} // unittest::
-
-//! \brief Charm++ main chare for the unit test suite executable, unittest.
-//! \details Note that this object should not be in a namespace.
-// cppcheck-suppress noConstructor
-class Main : public CBase_Main {<--- Unmatched suppression: noConstructor
-
-  public:
-    //! \brief Constructor
-    //! \details UnitTest's main chare constructor is the entry point of the
-    //!   program, called by the Charm++ runtime system. The constructor does
-    //!   basic initialization steps, e.g., parser the command-line, prints out
-    //!   some useful information to screen (in verbose mode), and instantiates
-    //!   a driver. Since Charm++ is fully asynchronous, the constructor
-    //!   usually spawns asynchronous objects and immediately exits. Thus in the
-    //!   body of the main chare constructor we fire up an 'execute' chare,
-    //!   which then calls back to Main::execute(). Finishing the main chare
-    //!   constructor the Charm++ runtime system then starts the
-    //!   network-migration of all global-scope data (if any). The execute chare
-    //!   calling back to Main::execute() signals the end of the migration of
-    //!   the global-scope data. Then we are ready to execute the driver. Since
-    //!   the unit test suite is parallel and asynchronous, its driver fires up
-    //!   additional Charm++ chare objects which then call back to
-    //!   Main::finalize() at some point in the future when all work has been
-    //!   finished. finalize() then exits by calling Charm++'s CkExit(),
-    //!   shutting down the runtime system.
-    //! \see http://charm.cs.illinois.edu/manuals/html/charm++/manual.html
-    Main( CkArgMsg* msg )
-    try :
-      m_signal( tk::setSignalHandlers() ),
-      m_helped( false ),
-      m_cmdline(),
-      // Parse command line into m_cmdline using default simple pretty printer
-      m_cmdParser( msg->argc, msg->argv, tk::Print(), m_cmdline, m_helped ),
-      // Create UnitTest driver
-      m_driver( tk::Main< unittest::UnitTestDriver >
-                        ( msg->argc, msg->argv,
-                          m_cmdline,
-                          tk::HeaderType::UNITTEST,
-                          tk::unittest_executable(),
-                          m_cmdline.get< tag::io, tag::screen >(),
-                          m_cmdline.get< tag::io, tag::nrestart >() ) ),
-      m_timer(1), // Start new timer measuring the serial+Charm++ runtime
-      m_timestamp()
-    {
-      g_trace = m_cmdline.get< tag::trace >();
-      // Immediately exit if any help was requested; help is printed in main()
-      if (m_helped) CkExit();
-      // Save executable name to global-scope string so FileParser can access it
-      unittest::g_executable = msg->argv[0];
-      delete msg;
-      // Call generic mainchare contructor
-      tk::MainCtor( mainProxy, thisProxy, m_timer, m_cmdline,
-                    CkCallback( CkIndex_Main::quiescence(), thisProxy ) );
-      // If quiescence detection is on or user requested it, create chare state
-      // collector Charm++ chare group
-      if ( m_cmdline.get< tag::chare >() || m_cmdline.get< tag::quiescence >() )
-        stateProxy = tk::CProxy_ChareStateCollector::ckNew();
-      // Fire up an asynchronous execute object, which when created at some
-      // future point in time will call back to this->execute(). This is
-      // necessary so that this->execute() can access already migrated
-      // global-scope data.
-      CProxy_execute::ckNew();
-      // Quiet std::cerr
-      tk::CProxy_QuietCerr::ckNew();
-    } catch (...) { tk::processExceptionCharm(); }
-
-    void execute() {
-      try {
-        m_timestamp.emplace_back("Migrate global-scope data", m_timer[1].hms());
-        m_driver.execute();       // fires up async chares
-      } catch (...) { tk::processExceptionCharm(); }
-    }
-
-    //! Towards normal exit but collect chare state first (if any)
-    void finalize( bool pass ) {
-      tk::finalize( m_cmdline, m_timer, stateProxy, m_timestamp,
-        m_cmdline.get< tag::io, tag::screen >(),
-        m_cmdline.get< tag::io, tag::nrestart >(),
-        CkCallback( CkIndex_Main::dumpstate(nullptr), thisProxy ),
-        pass );
-    }
-
-    //! Entry method triggered when quiescence is detected
-    void quiescence() {
-      try {
-        stateProxy.collect( /* error= */ true,
-          CkCallback( CkIndex_Main::dumpstate(nullptr), thisProxy ) );
-      } catch (...) { tk::processExceptionCharm(); }
-    }
-
-    //! Dump chare state
-    void dumpstate( CkReductionMsg* msg ) {
-      tk::dumpstate( m_cmdline,
-        m_cmdline.get< tag::io, tag::screen >(),
-        m_cmdline.get< tag::io, tag::nrestart >(),
-        msg );
-    }
-
-  private:
-    int m_signal;                               //!< Used to set signal handlers
-    bool m_helped;      //!< Indicates if help was requested on the command line
-    unittest::ctr::CmdLine m_cmdline;                   //!< Command line
-    unittest::CmdLineParser m_cmdParser;                //!< Command line parser
-    unittest::UnitTestDriver m_driver;                  //!< Driver
-    std::vector< tk::Timer > m_timer;                   //!< Timers
-
-    //! Time stamps in h:m:s with labels
-    std::vector< std::pair< std::string, tk::Timer::Watch > > m_timestamp;
-};
-
-//! \brief Charm++ chare execute
-//! \details By the time this object is constructed, the Charm++ runtime system
-//!    has finished migrating all global-scoped read-only objects which happens
-//!    after the main chare constructor has finished.
-class execute : public CBase_execute {
-  public: execute() { mainProxy.execute(); }
-};
-
-#include "NoWarning/unittest.def.h"
+  // remap real numbers in vector
+  auto m = r;
+  for (std::size_t i=0; i<map.size(); ++i) r[ map[i] ] = m[ i ];
+}
+
+std::vector< std::size_t >
+remap( const std::vector< std::size_t >& ids,
+       const std::vector< std::size_t >& map )
+// *****************************************************************************
+//  Create remapped vector of indices using a vector
+//! \param[in] ids Vector of integer IDs to remap
+//! \param[in] map Array of indices creating a new order
+//! \return Remapped vector of ids
+//! \details This function applies a mapping (reordering) to the integer IDs
+//!   passed in using the map passed in. The mapping is expressed between the
+//!   array index and its value. The function creates and returns a new container
+//!   with remapped ids of identical size of the origin ids container.
+//! \note The sizes of ids and map must be equal and the maximum index in map
+//!   must be lower than the size of map.
+//! \note It is okay to call this function with either of the containers empty;
+//!   if ids is empty, it returns an empty container; if map is empty, it will
+//!   return the original container.
+// *****************************************************************************
+{
+  if (ids.empty()) return {};
+  if (map.empty()) return ids;
+
+  Assert( *max_element( begin(ids), end(ids) ) < map.size(),
+          "Indexing out of bounds" );
+
+  // in terms of the in-place remap of a vector usinga vector
+  auto newids = ids;
+  remap( newids, map );
+
+  return newids;
+}
+
+void
+remap( std::vector< std::size_t >& ids,
+       const std::unordered_map< std::size_t, std::size_t >& map )
+// *****************************************************************************
+//  In-place remap vector of indices using a map
+//! \param[in] ids Vector of integer IDs to remap
+//! \param[in] map Hash-map of key->value creating a new order
+//! \details This function applies a mapping (reordering) to the integer IDs
+//!   passed in using the map passed in. The mapping is expressed as a hash-map
+//!   of key->value pairs, where the key is the original and the value is the
+//!   new ids of the mapping. The function overwrites the ids container with the
+//!   remapped ids of identical size.
+//! \note All ids in the input ids container must have a key in the map.
+//!   Otherwise an exception is thrown.
+//! \note It is okay to call this function with the ids container empty but not
+//!   okay to pass an empty map.
+// *****************************************************************************
+{
+  Assert( !map.empty(), "Map must not be empty" );
+
+  for (auto& i : ids) i = tk::cref_find( map, i );<--- Consider using std::transform algorithm instead of a raw loop.
+}
+
+std::vector< std::size_t >
+remap( const std::vector< std::size_t >& ids,
+       const std::unordered_map< std::size_t, std::size_t >& map )
+// *****************************************************************************
+//  Create remapped vector of indices using a map
+//! \param[in] ids Vector of integer IDs to create new container of ids from
+//! \param[in] map Hash-map of key->value creating a new order
+//! \return Remapped vector of ids
+//! \details This function applies a mapping (reordering) to the integer IDs
+//!   passed in using the map passed in. The mapping is expressed as a hash-map
+//!   of key->value pairs, where the key is the original and the value is the
+//!   new ids of the mapping. The function creates and returns a new container
+//!   with the remapped ids of identical size of the original ids container.
+//! \note All ids in the input ids container must have a key in the map.
+//!   Otherwise an exception is thrown.
+//! \note It is okay to call this function with the ids container empty but not
+//!   okay to pass an empty map.
+// *****************************************************************************
+{
+  Assert( !map.empty(), "Map must not be empty" );
+
+  // in terms of the in-place remap of a vector using a map
+  auto newids = ids;
+  remap( newids, map );
+
+  return newids;
+}
+
+std::map< int, std::vector< std::size_t > >
+remap( const std::map< int, std::vector< std::size_t > >& ids,
+       const std::unordered_map< std::size_t, std::size_t >& map )
+// *****************************************************************************
+//  Create remapped map of vector of indices using a map
+//! \param[in] ids Map of vector of integer IDs to create new container of ids
+//!   from
+//! \param[in] map Hash-map of key->value creating a new order
+//! \return Remapped vector of ids
+//! \details This function applies a mapping (reordering) to the map of integer
+//!   IDs passed in using the map passed in by applying remap(vector,map) on
+//!   each vector of ids. The keys in the returned map will be the same as in
+//!   ids.
+// *****************************************************************************
+{
+  Assert( !map.empty(), "Map must not be empty" );
+
+  // in terms of the in-place remap of a vector using a map
+  auto newids = ids;
+  for (auto& m : newids) remap( m.second, map );
+
+  return newids;
+}
+
+std::vector< std::size_t >
+renumber( const std::pair< std::vector< std::size_t >,
+                           std::vector< std::size_t > >& psup )
+// *****************************************************************************
+//  Reorder mesh points with the advancing front technique
+//! \param[in] psup Points surrounding points
+//! \return Mapping created by renumbering (reordering)
+// *****************************************************************************
+{
+  // Find out number of nodes in graph
+  auto npoin = psup.second.size()-1;
+
+  // Construct mapping using advancing front
+  std::vector< int > hpoin( npoin, -1 ), lpoin( npoin, 0 );
+  std::vector< std::size_t > map( npoin, 0 );
+  hpoin[0] = 0;
+  lpoin[0] = 1;
+  std::size_t num = 1;
+  while (num < npoin) {
+    std::size_t cnt = 0;
+    std::size_t i = 0;
+    std::vector< int > kpoin( npoin, -1 );
+    int p;
+    while ((p = hpoin[i]) != -1) {
+      ++i;
+      auto P = static_cast< std::size_t >( p );
+      for (auto j=psup.second[P]+1; j<=psup.second[P+1]; ++j) {
+        auto q = psup.first[j];
+        if (lpoin[q] != 1) {    // consider points not yet counted
+          map[q] = num++;
+          kpoin[cnt] = static_cast< int >( q ); // register point as counted
+          lpoin[q] = 1;                         // register the point as counted
+          ++cnt;
+        }
+      }
+    }
+    hpoin = kpoin;
+  }
+
+//   // Construct new->old id map
+//   std::size_t i = 0;
+//   std::vector< std::size_t > oldmap( npoin );
+//   for (auto n : map) oldmap[n] = i++;
+
+  // Return old->new and new->old maps
+  return map;
+}
+
+std::unordered_map< std::size_t, std::size_t >
+assignLid( const std::vector< std::size_t >& gid )
+// *****************************************************************************
+//  Assign local ids to global ids
+//! \param[in] gid Global ids
+//! \return Map associating global ids to local ids
+// *****************************************************************************
+{
+  std::unordered_map< std::size_t, std::size_t > lid;
+  std::size_t l = 0;
+  for (auto p : gid) lid[p] = l++;
+  return lid;
+}
+
+std::tuple< std::vector< std::size_t >,
+            std::vector< std::size_t >,
+            std::unordered_map< std::size_t, std::size_t > >
+global2local( const std::vector< std::size_t >& ginpoel )
+// *****************************************************************************
+//  Generate element connectivity of local node IDs from connectivity of global
+//  node IDs also returning the mapping between local to global IDs
+//! \param[in] ginpoel Element connectivity with global node IDs
+//! \return Tuple of (1) element connectivity with local node IDs, (2) the
+//!   vector of unique global node IDs (i.e., the mapping between local to
+//!   global node IDs), and (3) mapping between global to local node IDs.
+// *****************************************************************************
+{
+  // Make a copy of the element connectivity with global node ids
+  auto gid = ginpoel;
+
+  // Generate a vector that holds only the unique global mesh node ids
+  tk::unique( gid );
+
+  // Assign local node ids to global node ids
+  const auto lid = tk::assignLid( gid );
+
+  Assert( gid.size() == lid.size(), "Size mismatch" );
+
+  // Generate element connectivity using local node ids
+  std::vector< std::size_t > inpoel( ginpoel.size() );
+  std::size_t j = 0;
+  for (auto p : ginpoel) inpoel[ j++ ] = tk::cref_find( lid, p );
+
+  // Return element connectivty with local node IDs
+  return std::make_tuple( inpoel, gid, lid );
+}
+
+bool
+positiveJacobians( const std::vector< std::size_t >& inpoel,
+                   const std::array< std::vector< real >, 3 >& coord )
+// *****************************************************************************
+// Test for positivity of the Jacobian for all cells in mesh
+//! \param[in] inpoel Element connectivity (zero-based, i.e., local if parallel)
+//! \param[in] coord Node coordinates
+//! \return True if Jacobians of all mesh cells are positive
+// *****************************************************************************
+{
+  Assert( !inpoel.empty(), "Mesh connectivity empty" );
+  Assert( inpoel.size() % 4 == 0,
+          "Mesh connectivity size must be divisible by 4 " );
+  Assert( tk::uniquecopy(inpoel).size() == coord[0].size(), "Number of unique "
+          "nodes in mesh connectivity must equal the number of nodes to which "
+          "coordinates have been supplied" );
+  Assert( tk::uniquecopy(inpoel).size() == coord[1].size(), "Number of unique "
+          "nodes in mesh connectivity must equal the number of nodes to which "
+          "coordinates have been supplied" );
+  Assert( tk::uniquecopy(inpoel).size() == coord[2].size(), "Number of unique "
+          "nodes in mesh connectivity must equal the number of nodes to which "
+          "coordinates have been supplied" );
+  Assert( *std::minmax_element( begin(inpoel), end(inpoel) ).first == 0,
+          "node ids should start from zero" );
+
+  const auto& x = coord[0];
+  const auto& y = coord[1];
+  const auto& z = coord[2];
+
+  for (std::size_t e=0; e<inpoel.size()/4; ++e) {
+    const std::array< std::size_t, 4 > N{{ inpoel[e*4+0], inpoel[e*4+1],
+                                           inpoel[e*4+2], inpoel[e*4+3] }};
+    // compute element Jacobi determinant / (5/120) = element volume * 4
+    const std::array< tk::real, 3 >
+      ba{{ x[N[1]]-x[N[0]], y[N[1]]-y[N[0]], z[N[1]]-z[N[0]] }},
+      ca{{ x[N[2]]-x[N[0]], y[N[2]]-y[N[0]], z[N[2]]-z[N[0]] }},
+      da{{ x[N[3]]-x[N[0]], y[N[3]]-y[N[0]], z[N[3]]-z[N[0]] }};
+    if (tk::triple( ba, ca, da ) < 0) return false;
+ }
+
+ return true;
+}
+
+std::map< int, std::vector< std::size_t > >
+bfacenodes( const std::map< int, std::vector< std::size_t > >& bface,
+            const std::vector< std::size_t >& triinpoel )
+// *****************************************************************************
+// Generate nodes of side set faces
+//! \param[in] bface Boundary-faces mapped to side set ids
+//! \param[in] triinpoel Boundary-face connectivity
+//! \return Nodes of side set faces for each side set passed in
+// *****************************************************************************
+{
+  auto bfn = bface;
+
+  for (auto& [s,b] : bfn) {
+    std::vector< std::size_t > nodes;
+    for (auto f : b) {
+      nodes.push_back( triinpoel[f*3+0] );
+      nodes.push_back( triinpoel[f*3+1] );
+      nodes.push_back( triinpoel[f*3+2] );
+    }
+    tk::unique( nodes );
+    b = std::move( nodes );
+  }
+
+  return bfn;
+}
+
+} // tk::
 
diff --git a/Release/cppcheck/28.html b/Release/cppcheck/28.html index 8cc71c6f1ffd..adc08bf1f425 100644 --- a/Release/cppcheck/28.html +++ b/Release/cppcheck/28.html @@ -152,12 +152,12 @@
  1
@@ -363,554 +363,210 @@ 

Cppcheck report - [

// *****************************************************************************
+204
// *****************************************************************************
 /*!
-  \file      src/Mesh/Reorder.cpp
+  \file      src/Main/MeshConvDriver.cpp
   \copyright 2012-2015 J. Bakosi,
              2016-2018 Los Alamos National Security, LLC.,
              2019-2021 Triad National Security, LLC.
              All rights reserved. See the LICENSE file for details.
-  \brief     Mesh reordering routines for unstructured meshes
-  \details   Mesh reordering routines for unstructured meshes.
+  \brief     Mesh converter driver
+  \details   Mesh converter driver.
 */
 // *****************************************************************************
 
-#include <algorithm>
-#include <iterator>
-#include <unordered_map>
-#include <map>
-#include <tuple>
-#include <cstddef>
-
-#include "Reorder.hpp"
-#include "Exception.hpp"
-#include "ContainerUtil.hpp"
-#include "Vector.hpp"
+#include "Types.hpp"
+#include "Tags.hpp"
+#include "MeshConvDriver.hpp"
+#include "MeshFactory.hpp"
+#include "Writer.hpp"
+
+#include "NoWarning/meshconv.decl.h"
+
+using meshconv::MeshConvDriver;
+
+extern CProxy_Main mainProxy;
 
-namespace tk {
-
-std::size_t
-shiftToZero( std::vector< std::size_t >& inpoel )
-// *****************************************************************************
-//  Shift node IDs to start with zero in element connectivity
-//! \param[inout] inpoel Inteconnectivity of points and elements
-//! \return Amount shifted
-//! \details This function implements a simple reordering of the node ids of the
-//!   element connectivity in inpoel by shifting the node ids so that the
-//!   smallest is zero.
-//! \note It is okay to call this function with an empty container; it will
-//!    simply return without throwing an exception.
-// *****************************************************************************
-{
-  if (inpoel.empty()) return 0;
-
-  // find smallest node id
-  auto minId = *std::min_element( begin(inpoel), end(inpoel) );
+MeshConvDriver::MeshConvDriver( const ctr::CmdLine& cmdline, int ) :
+  m_print( cmdline.logname( cmdline.get< tag::io, tag::screen >(),
+                            cmdline.get< tag::io, tag::nrestart >() ),
+           cmdline.get< tag::verbose >() ? std::cout : std::clog,
+           std::ios_base::app ),
+  m_reorder( cmdline.get< tag::reorder >() ),
+  m_input(),
+  m_output()
+// *****************************************************************************
+//  Constructor
+//! \param[in] cmdline Command line object storing data parsed from the command
+//!   line arguments
+// *****************************************************************************
+{
+  // Save input file name
+  m_input = cmdline.get< tag::io, tag::input >();
+  // Save output file name
+  m_output = cmdline.get< tag::io, tag::output >();
+}
 
-  // shift node ids to start from zero
-  // cppcheck-suppress useStlAlgorithm
-  for (auto& n : inpoel) n -= minId;
-
-  return minId;
-}
-
-void
-remap( std::vector< std::size_t >& ids, const std::vector< std::size_t >& map )
-// *****************************************************************************
-//  Apply new maping to vector of indices
-//! \param[inout] ids Vector of integer IDs to remap
-//! \param[in] map Array of indices creating a new order
-//! \details This function applies a mapping (reordering) to the integer IDs
-//!   passed in using the map passed in. The mapping is expressed between the
-//!   array index and its value. The function overwrites every value, i, of
-//!   vector ids with map[i].
-//! \note The sizes of ids and map need not equal. Only the maximum index in ids
-//!   must be lower than the size of map.
-//! \note It is okay to call this function with either of the containers empty;
-//!   it will simply return without throwing an exception.
-// *****************************************************************************
-{
-  if (ids.empty() || map.empty()) return;
-
-  Assert( *max_element( begin(ids), end(ids) ) < map.size(),
-          "Indexing out of bounds" );
-
-  // remap integer IDs in vector ids
-  // cppcheck-suppress useStlAlgorithm
-  for (auto& i : ids) i = map[i];
-}
-
-void
-remap( std::vector< tk::real >& r, const std::vector< std::size_t >& map )
-// *****************************************************************************
-//  Apply new maping to vector of real numbers
-//! \param[inout] r Vector of real numbers to remap
-//! \param[in] map Array of indices creating a new order
-//! \details This function applies a mapping (reordering) to the real values
-//!   passed in using the map passed in. The mapping is expressed between the
-//!   array index and its value. The function moves every value r[i] to
-//!   r[ map[i] ].
-//! \note The sizes of r and map must be equal and the maximum index in map must
-//!   be lower than the size of map.
-//! \note It is okay to call this function with either of the containers empty;
-//!   it will simply return without throwing an exception.
-// *****************************************************************************
-{
-  if (r.empty() || map.empty()) return;
-
-  Assert( r.size() == map.size(), "Size mismatch" );
-  Assert( *max_element( begin(map), end(map) ) < map.size(),
-          "Indexing out of bounds" );
-
-  // remap real numbers in vector
-  auto m = r;
-  for (std::size_t i=0; i<map.size(); ++i) r[ map[i] ] = m[ i ];
-}
-
-std::vector< std::size_t >
-remap( const std::vector< std::size_t >& ids,
-       const std::vector< std::size_t >& map )
-// *****************************************************************************
-//  Create remapped vector of indices using a vector
-//! \param[in] ids Vector of integer IDs to remap
-//! \param[in] map Array of indices creating a new order
-//! \return Remapped vector of ids
-//! \details This function applies a mapping (reordering) to the integer IDs
-//!   passed in using the map passed in. The mapping is expressed between the
-//!   array index and its value. The function creates and returns a new container
-//!   with remapped ids of identical size of the origin ids container.
-//! \note The sizes of ids and map must be equal and the maximum index in map
-//!   must be lower than the size of map.
-//! \note It is okay to call this function with either of the containers empty;
-//!   if ids is empty, it returns an empty container; if map is empty, it will
-//!   return the original container.
-// *****************************************************************************
-{
-  if (ids.empty()) return {};
-  if (map.empty()) return ids;
-
-  Assert( *max_element( begin(ids), end(ids) ) < map.size(),
-          "Indexing out of bounds" );
-
-  // in terms of the in-place remap of a vector usinga vector
-  auto newids = ids;
-  remap( newids, map );
-
-  return newids;
-}
-
-void
-remap( std::vector< std::size_t >& ids,
-       const std::unordered_map< std::size_t, std::size_t >& map )
-// *****************************************************************************
-//  In-place remap vector of indices using a map
-//! \param[in] ids Vector of integer IDs to remap
-//! \param[in] map Hash-map of key->value creating a new order
-//! \details This function applies a mapping (reordering) to the integer IDs
-//!   passed in using the map passed in. The mapping is expressed as a hash-map
-//!   of key->value pairs, where the key is the original and the value is the
-//!   new ids of the mapping. The function overwrites the ids container with the
-//!   remapped ids of identical size.
-//! \note All ids in the input ids container must have a key in the map.
-//!   Otherwise an exception is thrown.
-//! \note It is okay to call this function with the ids container empty but not
-//!   okay to pass an empty map.
-// *****************************************************************************
-{
-  Assert( !map.empty(), "Map must not be empty" );
-
-  for (auto& i : ids) i = tk::cref_find( map, i );<--- Consider using std::transform algorithm instead of a raw loop.
-}
-
-std::vector< std::size_t >
-remap( const std::vector< std::size_t >& ids,
-       const std::unordered_map< std::size_t, std::size_t >& map )
-// *****************************************************************************
-//  Create remapped vector of indices using a map
-//! \param[in] ids Vector of integer IDs to create new container of ids from
-//! \param[in] map Hash-map of key->value creating a new order
-//! \return Remapped vector of ids
-//! \details This function applies a mapping (reordering) to the integer IDs
-//!   passed in using the map passed in. The mapping is expressed as a hash-map
-//!   of key->value pairs, where the key is the original and the value is the
-//!   new ids of the mapping. The function creates and returns a new container
-//!   with the remapped ids of identical size of the original ids container.
-//! \note All ids in the input ids container must have a key in the map.
-//!   Otherwise an exception is thrown.
-//! \note It is okay to call this function with the ids container empty but not
-//!   okay to pass an empty map.
-// *****************************************************************************
-{
-  Assert( !map.empty(), "Map must not be empty" );
-
-  // in terms of the in-place remap of a vector using a map
-  auto newids = ids;
-  remap( newids, map );
-
-  return newids;
-}
-
-std::map< int, std::vector< std::size_t > >
-remap( const std::map< int, std::vector< std::size_t > >& ids,
-       const std::unordered_map< std::size_t, std::size_t >& map )
-// *****************************************************************************
-//  Create remapped map of vector of indices using a map
-//! \param[in] ids Map of vector of integer IDs to create new container of ids
-//!   from
-//! \param[in] map Hash-map of key->value creating a new order
-//! \return Remapped vector of ids
-//! \details This function applies a mapping (reordering) to the map of integer
-//!   IDs passed in using the map passed in by applying remap(vector,map) on
-//!   each vector of ids. The keys in the returned map will be the same as in
-//!   ids.
-// *****************************************************************************
-{
-  Assert( !map.empty(), "Map must not be empty" );
-
-  // in terms of the in-place remap of a vector using a map
-  auto newids = ids;
-  for (auto& m : newids) remap( m.second, map );
-
-  return newids;
-}
-
-std::vector< std::size_t >
-renumber( const std::pair< std::vector< std::size_t >,
-                           std::vector< std::size_t > >& psup )
-// *****************************************************************************
-//  Reorder mesh points with the advancing front technique
-//! \param[in] psup Points surrounding points
-//! \return Mapping created by renumbering (reordering)
-// *****************************************************************************
-{
-  // Find out number of nodes in graph
-  auto npoin = psup.second.size()-1;
-
-  // Construct mapping using advancing front
-  std::vector< int > hpoin( npoin, -1 ), lpoin( npoin, 0 );
-  std::vector< std::size_t > map( npoin, 0 );
-  hpoin[0] = 0;
-  lpoin[0] = 1;
-  std::size_t num = 1;
-  while (num < npoin) {
-    std::size_t cnt = 0;
-    std::size_t i = 0;
-    std::vector< int > kpoin( npoin, -1 );
-    int p;
-    while ((p = hpoin[i]) != -1) {
-      ++i;
-      auto P = static_cast< std::size_t >( p );
-      for (auto j=psup.second[P]+1; j<=psup.second[P+1]; ++j) {
-        auto q = psup.first[j];
-        if (lpoin[q] != 1) {    // consider points not yet counted
-          map[q] = num++;
-          kpoin[cnt] = static_cast< int >( q ); // register point as counted
-          lpoin[q] = 1;                         // register the point as counted
-          ++cnt;
-        }
-      }
-    }
-    hpoin = kpoin;
-  }
-
-//   // Construct new->old id map
-//   std::size_t i = 0;
-//   std::vector< std::size_t > oldmap( npoin );
-//   for (auto n : map) oldmap[n] = i++;
-
-  // Return old->new and new->old maps
-  return map;
-}
-
-std::unordered_map< std::size_t, std::size_t >
-assignLid( const std::vector< std::size_t >& gid )
-// *****************************************************************************
-//  Assign local ids to global ids
-//! \param[in] gid Global ids
-//! \return Map associating global ids to local ids
-// *****************************************************************************
-{
-  std::unordered_map< std::size_t, std::size_t > lid;
-  std::size_t l = 0;
-  for (auto p : gid) lid[p] = l++;
-  return lid;
-}
-
-std::tuple< std::vector< std::size_t >,
-            std::vector< std::size_t >,
-            std::unordered_map< std::size_t, std::size_t > >
-global2local( const std::vector< std::size_t >& ginpoel )
-// *****************************************************************************
-//  Generate element connectivity of local node IDs from connectivity of global
-//  node IDs also returning the mapping between local to global IDs
-//! \param[in] ginpoel Element connectivity with global node IDs
-//! \return Tuple of (1) element connectivity with local node IDs, (2) the
-//!   vector of unique global node IDs (i.e., the mapping between local to
-//!   global node IDs), and (3) mapping between global to local node IDs.
-// *****************************************************************************
-{
-  // Make a copy of the element connectivity with global node ids
-  auto gid = ginpoel;
-
-  // Generate a vector that holds only the unique global mesh node ids
-  tk::unique( gid );
-
-  // Assign local node ids to global node ids
-  const auto lid = tk::assignLid( gid );
-
-  Assert( gid.size() == lid.size(), "Size mismatch" );
-
-  // Generate element connectivity using local node ids
-  std::vector< std::size_t > inpoel( ginpoel.size() );
-  std::size_t j = 0;
-  for (auto p : ginpoel) inpoel[ j++ ] = tk::cref_find( lid, p );
-
-  // Return element connectivty with local node IDs
-  return std::make_tuple( inpoel, gid, lid );
-}
-
-bool
-positiveJacobians( const std::vector< std::size_t >& inpoel,
-                   const std::array< std::vector< real >, 3 >& coord )
-// *****************************************************************************
-// Test for positivity of the Jacobian for all cells in mesh
-//! \param[in] inpoel Element connectivity (zero-based, i.e., local if parallel)
-//! \param[in] coord Node coordinates
-//! \return True if Jacobians of all mesh cells are positive
-// *****************************************************************************
-{
-  Assert( !inpoel.empty(), "Mesh connectivity empty" );
-  Assert( inpoel.size() % 4 == 0,
-          "Mesh connectivity size must be divisible by 4 " );
-  Assert( tk::uniquecopy(inpoel).size() == coord[0].size(), "Number of unique "
-          "nodes in mesh connectivity must equal the number of nodes to which "
-          "coordinates have been supplied" );
-  Assert( tk::uniquecopy(inpoel).size() == coord[1].size(), "Number of unique "
-          "nodes in mesh connectivity must equal the number of nodes to which "
-          "coordinates have been supplied" );
-  Assert( tk::uniquecopy(inpoel).size() == coord[2].size(), "Number of unique "
-          "nodes in mesh connectivity must equal the number of nodes to which "
-          "coordinates have been supplied" );
-  Assert( *std::minmax_element( begin(inpoel), end(inpoel) ).first == 0,
-          "node ids should start from zero" );
-
-  const auto& x = coord[0];
-  const auto& y = coord[1];
-  const auto& z = coord[2];
-
-  for (std::size_t e=0; e<inpoel.size()/4; ++e) {
-    const std::array< std::size_t, 4 > N{{ inpoel[e*4+0], inpoel[e*4+1],
-                                           inpoel[e*4+2], inpoel[e*4+3] }};
-    // compute element Jacobi determinant / (5/120) = element volume * 4
-    const std::array< tk::real, 3 >
-      ba{{ x[N[1]]-x[N[0]], y[N[1]]-y[N[0]], z[N[1]]-z[N[0]] }},
-      ca{{ x[N[2]]-x[N[0]], y[N[2]]-y[N[0]], z[N[2]]-z[N[0]] }},
-      da{{ x[N[3]]-x[N[0]], y[N[3]]-y[N[0]], z[N[3]]-z[N[0]] }};
-    if (tk::triple( ba, ca, da ) < 0) return false;
- }
-
- return true;
-}
-
-std::map< int, std::vector< std::size_t > >
-bfacenodes( const std::map< int, std::vector< std::size_t > >& bface,
-            const std::vector< std::size_t >& triinpoel )
-// *****************************************************************************
-// Generate nodes of side set faces
-//! \param[in] bface Boundary-faces mapped to side set ids
-//! \param[in] triinpoel Boundary-face connectivity
-//! \return Nodes of side set faces for each side set passed in
-// *****************************************************************************
-{
-  auto bfn = bface;
-
-  for (auto& [s,b] : bfn) {
-    std::vector< std::size_t > nodes;
-    for (auto f : b) {
-      nodes.push_back( triinpoel[f*3+0] );
-      nodes.push_back( triinpoel[f*3+1] );
-      nodes.push_back( triinpoel[f*3+2] );
-    }
-    tk::unique( nodes );
-    b = std::move( nodes );
-  }
-
-  return bfn;
-}
-
-} // tk::
+void
+MeshConvDriver::execute() const
+// *****************************************************************************
+//  Execute: Convert mesh file
+// *****************************************************************************
+{
+  m_print.endsubsection();
+
+  std::vector< std::pair< std::string, tk::real > > times;
+
+  // If input filename contains a '%', we aggregate multiple files
+  if (m_input.find('%') == std::string::npos) {
+
+    // Convert single mesh
+
+    times.push_back( {} );
+    auto mesh = tk::readUnsMesh( m_print, m_input, times[0] );
+    auto wtimes = tk::writeUnsMesh( m_print, m_output, mesh, m_reorder );
+    times.insert( end(times), begin(wtimes), end(wtimes) );
+
+  } else {
+
+    // Aggregate multiple meshes containing surface output
+
+    // Find a '%' sign in the input filename, and assuming a syntax of
+    // '.<nfile>.%', find '<nfile>' as the number of files to aggregate.
+    auto percent_pos = m_input.find( '%' );
+    auto input_basename = m_input.substr( 0, percent_pos );
+    auto dot1 = m_input.find_last_of( '.', percent_pos );
+    auto dot2 = m_input.find_last_of( '.', dot1-1 );
+    auto nfile_str = m_input.substr( dot2+1, dot1-dot2-1  );
+    std::stringstream ss( nfile_str );
+    if (nfile_str.empty())
+      Throw( "The percent sign must be followed by an "
+             "integer, the number of files to aggregate" );
+    std::size_t nfile;
+    ss >> nfile;
+    m_print.diag( "Aggregating " + std::to_string(nfile) +
+                  " files from base filename: '" + input_basename +'\'' );
+
+    const auto eps = std::numeric_limits< tk::real >::epsilon();
+
+    // Lambda to echo some diagnostics on the mesh being processes to screen
+    auto diag = [&]( const std::string& name, const tk::UnsMesh& mesh ){
+      m_print.diag( name + ": ntri: " +
+        std::to_string(mesh.triinpoel().size()/3) +
+        ", ntime: " + std::to_string(mesh.vartimes().size()) +
+        (!mesh.nodevars().empty() ? ", node_var: " +
+           std::to_string(mesh.nodevars()[0].size()) : "") +
+        (!mesh.nodevars()[0].empty() ? ", npoin: " +
+           std::to_string(mesh.nodevars()[0][0].size()) : "") +
+        (!mesh.elemvars().empty() ? ", elem_var: " +
+           std::to_string(mesh.elemvars()[0].size()) : "") +
+        (!mesh.elemvars()[0].empty() ? ", nelem: " +
+           std::to_string(mesh.elemvars()[0][0].size()) : "") );
+    };
+
+    // Output-mesh containers, will store aggregated surface(s) and field output
+    tk::UnsMesh::Coords coords;
+    auto& X = coords[0];
+    auto& Y = coords[1];
+    auto& Z = coords[2];
+    std::size_t npoin = 0;
+    std::size_t nelem = 0;
+    std::vector< std::size_t > otriinpoel;
+    std::vector< std::string > nodevarnames;
+    std::vector< std::string > elemvarnames;
+    std::vector< tk::real > vartimes;
+    std::vector< std::vector< std::vector< tk::real > > > nodevars;
+    std::vector< std::vector< std::vector< tk::real > > > elemvars;
+    // Counter for number of non-empty meshes processed
+    std::size_t k = 0;
+    for (std::size_t m=0; m<nfile; ++m) {
+      std::string name = input_basename + std::to_string(m);
+      times.push_back( {} );
+      auto mesh = tk::readUnsMesh( m_print, name, times.back() );
+      const auto& triinpoel = mesh.triinpoel();
+      // Skip meshes with a single triange cell
+      if (triinpoel.size() == 3) continue;
+      const auto& x = mesh.x();
+      const auto& y = mesh.y();
+      const auto& z = mesh.z();
+      nodevarnames = mesh.nodevarnames();
+      elemvarnames = mesh.elemvarnames();
+      vartimes = mesh.vartimes();
+      // Echo some diagnostics on the mesh being processes to screen
+      diag( name, mesh );
+      // Aggregate data from each triangle element in mesh
+      for (std::size_t e=0; e<triinpoel.size()/3; ++e) {
+        for (std::size_t n=0; n<3; ++n) {
+          auto j = triinpoel[ e*3+n ];
+          bool visited = false;
+          // WARNING: linear search below, will not scale well
+          for (std::size_t i=0; i<X.size(); ++i) {
+            // If mesh point has already been seen (on a previous mesh)
+            if (std::abs(x[j]-X[i]) < eps &&
+                std::abs(y[j]-Y[i]) < eps &&
+                std::abs(z[j]-Z[i]) < eps)
+            { // no point in connectivity but nothing else
+              visited = true;
+              otriinpoel.push_back( i );
+            }
+          }
+          if (!visited) { // Mesh point not yet seen
+            // save coordinates and (global) point id in aggregated connectivity
+            X.push_back( x[j] );
+            Y.push_back( y[j] );
+            Z.push_back( z[j] );
+            otriinpoel.push_back( npoin );
+            // aggregate nodal field data for all times and variables
+            std::size_t time = 0;
+            std::size_t varid = 0;
+            for (const auto& t : mesh.nodevars()) {  // for all times
+              if (k == 0 && npoin == 0) nodevars.push_back( {} );
+              for (const auto& v : t) {              // for all variables
+                if (k == 0 && npoin == 0) nodevars.back().push_back( {} );
+                nodevars[time][varid].push_back( v[j] );
+                ++varid;
+              }
+              ++time;
+              varid = 0;
+            }
+            ++npoin;      // increase number of nodes in output mesh
+          }
+        }
+
+        // aggregate elemental field data for all times and variables
+        std::size_t etime = 0;
+        std::size_t evarid = 0;
+        for (const auto& t : mesh.elemvars()) {  // for all times
+          if (k == 0 && nelem == 0) elemvars.push_back( {} );
+          for (const auto& v : t) {              // for all variables
+            if (k == 0 && nelem == 0) elemvars.back().push_back( {} );
+            elemvars[etime][evarid].push_back( v[e] );
+            ++evarid;
+          }
+          ++etime;
+          evarid = 0;
+        }
+        ++nelem;    // increase number of elements in output mesh
+      }
+      ++k;        // increase number of non-empty meshes processed
+    }
+
+    // Construct aggregated output mesh
+    tk::UnsMesh outmesh( coords, otriinpoel, nodevarnames, elemvarnames,
+      vartimes, nodevars, elemvars );
+    // Echo diagnostics on the aggreegate output mesh
+    diag( m_output, outmesh );
+    // Write output mesh to file
+    auto wtimes = tk::writeUnsMesh( m_print, m_output, outmesh, m_reorder );
+    // Collect wall-clock time data
+    times.insert( end(times), begin(wtimes), end(wtimes) );
+
+  }
+
+  mainProxy.timestamp( times );
+
+  mainProxy.finalize();
+}
 
diff --git a/Release/cppcheck/3.html b/Release/cppcheck/3.html index 4c62a1a73425..1b602d10f108 100644 --- a/Release/cppcheck/3.html +++ b/Release/cppcheck/3.html @@ -152,12 +152,12 @@
  1
@@ -278,125 +278,251 @@ 

Cppcheck report - [

// *****************************************************************************
+119
+120
+121
+122
+123
+124
+125
+126
+127
+128
+129
+130
+131
+132
+133
+134
+135
+136
+137
+138
+139
+140
+141
+142
+143
+144
+145
+146
+147
+148
+149
+150
+151
+152
+153
+154
+155
+156
+157
+158
+159
+160
+161
+162
+163
+164
+165
+166
+167
+168
+169
+170
+171
+172
+173
+174
+175
+176
+177
+178
+179
+180
+181
+182
// *****************************************************************************
 /*!
-  \file      src/Inciter/DiagReducer.cpp
+  \file      src/IO/Omega_h_MeshReader.cpp
   \copyright 2012-2015 J. Bakosi,
              2016-2018 Los Alamos National Security, LLC.,
              2019-2021 Triad National Security, LLC.
              All rights reserved. See the LICENSE file for details.
-  \brief     Custom Charm++ reducer for merging std::vectors across PEs
-  \details   Custom Charm++ reducer for merging std::vectors across PEs.
+  \brief     Omega_h mesh reader
+  \details   Omega_h mesh reader class definition.
 */
 // *****************************************************************************
 
-#include <stddef.h>
-#include <type_traits>
-#include <memory>
-
-#include "DiagReducer.hpp"
-#include "Diagnostics.hpp"
-#include "Exception.hpp"
-
-namespace inciter {
-
-std::pair< int, std::unique_ptr<char[]> >
-serialize( std::size_t meshid,
-           std::size_t ncomp,
-           const std::vector< std::vector< tk::real > >& d )
-// *****************************************************************************
-// Serialize std::vectors to raw memory stream
-//! \param[in] meshid Mesh ID
-//! \param[in] ncomp Number of scalar components being solved
-//! \param[in] d Diagnostics vector of vectors (of eq components)
-//! \return Pair of the length and the raw stream containing the serialized
-//!   vectors
-// *****************************************************************************
-{
-  // Prepare for serializing diagnostics to a raw binary stream, compute size
-  PUP::sizer sizer;
-  sizer | meshid;
-  sizer | ncomp;
-  sizer | const_cast< std::vector< std::vector< tk::real > >& >( d );
-
-  // Create raw character stream to store the serialized vectors
-  std::unique_ptr<char[]> flatData = std::make_unique<char[]>( sizer.size() );
-
-  // Serialize vector, each message will contain a vector
-  PUP::toMem packer( flatData.get() );
-  packer | meshid;
-  packer | ncomp;
-  packer | const_cast< std::vector< std::vector< tk::real > >& >( d );
-
-  // Return size of and raw stream
-  return { sizer.size(), std::move(flatData) };
-}
-
-CkReductionMsg*
-mergeDiag( int nmsg, CkReductionMsg **msgs )
-// *****************************************************************************
-// Charm++ custom reducer for merging diagnostics during reduction across PEs
-//! \param[in] nmsg Number of messages in msgs
-//! \param[in] msgs Charm++ reduction message containing the serialized
-//!   diagnostics
-//! \return Aggregated diagnostics built for further aggregation if needed
-// *****************************************************************************
-{
-  std::size_t meshid, ncomp;
-  std::vector< std::vector< tk::real > > v;
+#include "NoWarning/Omega_h_file.hpp"
+#include <Omega_h_library.hpp>
+
+#include "Macro.hpp"
+#include "Omega_h_MeshReader.hpp"
+#include "Reorder.hpp"
+
+using tk::Omega_h_MeshReader;
+
+void
+Omega_h_MeshReader::readMeshPart(
+  std::vector< std::size_t >& ginpoel,
+  std::vector< std::size_t >& inpoel,
+  [[maybe_unused]] std::vector< std::size_t >& triinp,
+  std::unordered_map< std::size_t, std::size_t >& lid,
+  tk::UnsMesh::Coords& coord,
+  std::unordered_map< std::size_t, std::set< std::size_t > >&,
+  int numpes,
+  [[maybe_unused]] int mype )
+// *****************************************************************************
+//  Read a part of the mesh (graph and coordinates) from Omega_h file
+//! \param[in,out] ginpoel Container to store element connectivity of this PE's
+//!   chunk of the mesh (global ids)
+//! \param[in,out] inpoel Container to store element connectivity with local
+//!   node IDs of this PE's mesh chunk
+//! \param[in,out] triinp Container to store triangle element connectivity
+//!   (if exists in file) with global node indices
+//! \param[in,out] lid Container to store global->local node IDs of elements of
+//!   this PE's mesh chunk
+//! \param[in,out] coord Container to store coordinates of mesh nodes of this
+//!   PE's mesh chunk
+//! \param[in] numpes Total number of PEs (default n = 1, for a single-CPU read)
+//! \param[in] mype This PE (default m = 0, for a single-CPU read)
+//! \note The last two integer arguments are unused. They are needed because
+//!   this function can be used via a polymorphic interface via a base class,
+//!   see tk::MeshReader, and other specialized mesh readers, e.g.,
+//!   tk::ExodusIIMeshReader, use these arguments. Here we require the Omega_h
+//!   input mesh to be pre-partitioned, with Omega_h's osh_part tool, into the
+//!   number of partitions that is equal to the number of PEs this fuinction is
+//!   called on in parallel.
+// *****************************************************************************
+{
+  Assert( mype < numpes, "Invalid input: PE id must be lower than NumPEs" );
+  Assert( ginpoel.empty() && inpoel.empty() && lid.empty() &&
+          coord[0].empty() && coord[1].empty() && coord[2].empty(),
+          "Containers to store mesh must be empty" );
+
+  #if defined(__clang__)
+    #pragma clang diagnostic push
+    #pragma clang diagnostic ignored "-Wold-style-cast"
+  #endif
+
+  // Create Omega_h library instance
+  auto lib = Omega_h::Library( nullptr, nullptr, MPI_COMM_WORLD );
 
-  // Create PUP deserializer based on message passed in
-  PUP::fromMem creator( msgs[0]->getData() );
-
-  // Deserialize vector from raw stream
-  creator | meshid;<--- Uninitialized variable: meshid
-  creator | ncomp;<--- Uninitialized variable: ncomp
-  creator | v;
-
-  for (int m=1; m<nmsg; ++m) {
-    // Unpack vector
-    std::size_t mid, nc;
-    std::vector< std::vector< tk::real > > w;
-    PUP::fromMem curCreator( msgs[m]->getData() );
-    curCreator | mid;<--- Uninitialized variable: mid
-    curCreator | nc;<--- Uninitialized variable: nc
-    curCreator | w;
-    // Aggregate diagnostics vector
-    meshid = mid;<--- Uninitialized variable: mid<--- Variable 'meshid' is assigned a value that is never used.
-    ncomp = nc;<--- Uninitialized variable: nc<--- Variable 'ncomp' is assigned a value that is never used.
-    Assert( v.size() == w.size(),
-            "Size mismatch during diagnostics aggregation" );
-    Assert( v.size() == inciter::NUMDIAG,
-            "Size mismatch during diagnostics aggregation" );
-    for (std::size_t i=0; i<v.size(); ++i)<--- Unsigned less than zero
-      Assert( v[i].size() == w[i].size(),
-              "Size mismatch during diagnostics aggregation" );
-    // Apply diagnostics aggregation policy
-    // Sum for L2 normal of the numerical solution for all scalar components
-    for (std::size_t i=0; i<v[L2SOL].size(); ++i) v[L2SOL][i] += w[L2SOL][i];
-    // Sum for the L2 norm of the numerical - analytical solution for all comps
-    for (std::size_t i=0; i<v[L2ERR].size(); ++i) v[L2ERR][i] += w[L2ERR][i];
-    // Sum for the L2 norm of the residual of all components
-    for (std::size_t i=0; i<v[L2RES].size(); ++i) v[L2RES][i] += w[L2RES][i];
-    // Max for the Linf norm of the numerical - analytical solution for all comp
-    for (std::size_t i=0; i<v[LINFERR].size(); ++i)
-      if (w[LINFERR][i] > v[LINFERR][i]) v[LINFERR][i] = w[LINFERR][i];
-    // Sum of the total energy over the entire domain
-    v[TOTALSOL][0] += w[TOTALSOL][0];
-    // Copy ITER, TIME, DT
-    for (std::size_t j=v.size()-3; j<v.size(); ++j)
-      for (std::size_t i=0; i<v[j].size(); ++i)
-        v[j][i] = w[j][i];
-  }
-
-  // Serialize concatenated diagnostics vector to raw stream
-  auto stream = serialize( meshid, ncomp, v );
-
-  // Forward serialized diagnostics
-  return CkReductionMsg::buildNew( stream.first, stream.second.get() );
-}
+  #if defined(__clang__)
+    #pragma clang diagnostic pop
+  #endif
+
+  // Find out how many partitions the Omega_h mesh was saved with
+  auto nparts = Omega_h::binary::read_nparts( m_filename, lib.world() );
+
+  if (numpes < nparts)
+    Throw( "The Omega_h mesh reader only supports NumPEs >= nparts, where "
+           "nparts is the number of partitions the mesh is partitioned into. "
+           "Also note that NumPEs must be a power of 2 if NumPEs > nparts." );
+
+  // Read mesh
+  auto mesh = Omega_h::binary::read( m_filename, &lib );
+
+  // Lambda to check if int is a power of two
+  auto isPowerOfTwo = []( int x ) { return (x != 0) && ((x & (x - 1)) == 0); };
+
+  if (nparts != numpes) {
+    if (!isPowerOfTwo(numpes))
+      Throw( "The Omega_h mesh reader only supports NumPEs of power of 2" );
+    else
+      mesh.balance();
+  }
+
+  // Extract connectivity from Omega_h's mesh object
+  auto ntets = mesh.nelems();
+  ginpoel.resize( static_cast< std::size_t >( ntets ) * 4 );
+  auto o_inpoel = mesh.ask_elem_verts();
+  auto o_gid = mesh.globals( Omega_h::VERT );
+  for (int i=0; i<ntets; ++i)
+    for (int j=0; j<4; ++j) {
+      auto I = static_cast< std::size_t >( i );
+      auto J = static_cast< std::size_t >( j );
+      ginpoel[ I*4+J ] = static_cast<std::size_t>( o_gid[ o_inpoel[i*4+j] ] );
+    }
+
+  // Extract node coordinates from Omega_h's mesh object
+  auto o_coord = mesh.coords();
+
+  // Extract number of vertices from Omega_h's mesh object
+  auto nnode = static_cast< std::size_t >( mesh.nverts() );
+
+  // Extract node coordinates from Omega_h's mesh object
+  auto& x = coord[0];
+  auto& y = coord[1];
+  auto& z = coord[2];
+  x.resize( nnode );
+  y.resize( nnode );
+  z.resize( nnode );
 
-} // inciter::
+  for (std::size_t I=0; I<nnode; ++I) {
+    auto i = static_cast< int >( I );
+    x[I] = o_coord[ i*3+0 ];
+    y[I] = o_coord[ i*3+1 ];
+    z[I] = o_coord[ i*3+2 ];
+  }
+
+  // Compute local data from global mesh connectivity
+  std::vector< std::size_t > gid;
+  std::tie( inpoel, gid, lid ) = tk::global2local( ginpoel );
+}
+
+
+std::vector< std::size_t >
+Omega_h_MeshReader::triinpoel(
+  [[maybe_unused]] std::map< int, std::vector< std::size_t > >& bface,<--- Parameter 'bface' can be declared with const
+  [[maybe_unused]] const std::map< int, std::vector< std::size_t > >& faces,
+  [[maybe_unused]] const std::vector< std::size_t >& ginpoel,
+  [[maybe_unused]] const std::vector< std::size_t >& triinp ) const
+// *****************************************************************************
+// ...
+//! \note Must be preceded by a call to readElemBlockIDs()
+// *****************************************************************************
+{
+  std::vector< std::size_t > bnd_triinpoel;
+  return bnd_triinpoel;
+}
+
+void
+Omega_h_MeshReader::readSidesetFaces(
+  [[maybe_unused]] std::map< int, std::vector< std::size_t > >& bface,<--- Parameter 'bface' can be declared with const
+  [[maybe_unused]] std::map< int, std::vector< std::size_t > >& faces )<--- Parameter 'faces' can be declared with const
+// *****************************************************************************
+//  Read side sets from Omega_h file
+//! \param[in,out] bface Elem ids of side sets to read into
+//! \param[in,out] faces Elem-relative face ids of tets of side sets
+// *****************************************************************************
+{
+}
+
+void
+Omega_h_MeshReader::readFaces(
+  [[maybe_unused]] std::vector< std::size_t >& conn )
+// *****************************************************************************
+//  Read face connectivity of a number of boundary faces from Omega_h file
+//! \param[in,out] conn Connectivity vector to push to
+//! \details This function reads in the total number of boundary faces,
+//!   also called triangle-elements, and their connectivity.
+// *****************************************************************************
+{
+}
+
+std::map< int, std::vector< std::size_t > >
+Omega_h_MeshReader::readSidesetNodes()
+// *****************************************************************************
+//  Read node list of all side sets from Omega_h file
+//! \return Node lists mapped to side set ids
+// *****************************************************************************
+{
+  // Node lists mapped to side set ids
+  std::map< int, std::vector< std::size_t > > side;
+
+  return side;
+}
 
diff --git a/Release/cppcheck/33.html b/Release/cppcheck/33.html index 11047edb4f44..e794169870d9 100644 --- a/Release/cppcheck/33.html +++ b/Release/cppcheck/33.html @@ -152,12 +152,12 @@
  1
@@ -279,526 +279,126 @@ 

Cppcheck report - [

// *****************************************************************************
+120
// *****************************************************************************
 /*!
-  \file      src/Inciter/Scheme.hpp
+  \file      src/Main/InciterPrint.hpp
   \copyright 2012-2015 J. Bakosi,
              2016-2018 Los Alamos National Security, LLC.,
              2019-2021 Triad National Security, LLC.
              All rights reserved. See the LICENSE file for details.
-  \brief     Polymorphic glue for calling Charm++ entry methods to base class
-    Discretization, its children implementing specific discretization schemes,
-    and helper classes
-  \details
-    The purpose of this class is to hide, behind a single type, different
-    Charm++  proxy types that model a single concept, i.e., define some common
-    functions as Charm++ entry methods that can be used in either a broadcast
-    and/or in a way of addressing a single array element. As a result, member
-    functions can be invoked by client code without knowing the underlying type
-    or any specifics to the underlying differences of the classes that model the
-    same concept, i.e., expose the same member functions. The idea is very
-    similar to inheritance and runtime polymorphism with base classes and
-    virtual functions: some member functions and data are common to all types
-    modeled (and thus are not repeated and/or copied), while some are specific.
-    A difference is that the "base" and "child" classes are Charm++ proxies.
-    Note that while Charm++ does support inheritance and runtime polymorphism
-    with chare arrays, we still prefer the implementation below because it uses
-    entirely value semantics (inside and in client code) and thus it keeps the
-    complexity of the dispatch behind this class and does not expose it to
-    client code.
-
-    The advantages of this class over traditional runtime polymorphism are (1)
-    value semantics (both internally and to client code), (2) not templated,
-    and (3) PUPable, i.e., an instance of Scheme can be sent across the network
-    using Charm++'s pup framework. Also, since the class only holds a couple of
-    chare proxies, it is lightweight.
-
-    Example usage from client code:
-
-    \code{.cpp}
-      // Instantiate a Scheme object
-      Scheme s( ctr::SchemeType::DG );  // see Control/Inciter/Options/Scheme.h
-
-      // Issue broadcast to child scheme entry method
-      s.bcast< Scheme::setup >(...);
-
-      // Issue broadcast to base (Discretization) entry method
-      s.disc().totalvol();
-    \endcode
+  \brief     Inciter-specific pretty printer functionality
+  \details   Inciter-specific pretty printer functionality.
+*/
+// *****************************************************************************
+#ifndef InciterPrint_h
+#define InciterPrint_h
+
+#include <iostream>
+#include <string>
+
+#include "NoWarning/format.hpp"
+
+#include "Print.hpp"
+#include "ContainerUtil.hpp"
+#include "Inciter/InputDeck/InputDeck.hpp"
+#include "Inciter/Options/Physics.hpp"
+#include "Inciter/Options/Problem.hpp"
+
+namespace inciter {
+
+extern ctr::InputDeck g_inputdeck_defaults;
+extern ctr::InputDeck g_inputdeck;
+
+//! InciterPrint : tk::Print
+class InciterPrint : public tk::Print {
+
+  public:
+    //! Constructor
+    //! \param[in] screen Screen output filename
+    //! \param[in,out] str Verbose stream
+    //! \param[in] mode Open mode for screen output file, see
+    //!   http://en.cppreference.com/w/cpp/io/ios_base/openmode
+    //! \param[in,out] qstr Quiet stream
+    //! \see tk::RNGPrint::RNGPrint and tk::Print::Print
+    explicit InciterPrint( const std::string& screen,
+                           std::ostream& str = std::clog,
+                           std::ios_base::openmode mode = std::ios_base::out,
+                           std::ostream& qstr = std::cout ) :
+      Print( screen, str, mode, qstr ) {}
 
-    Organization, implementation details, end extension of the class:
-
-    Scheme contains (at least) two Charm++ proxies: discproxy and proxy. The
-    former contains data and functionality common to all discretizations, and
-    this can be considered as an equivalent to a base class in the OOP sense.
-    The latter, proxy, contains data and functionality specific to a particular
-    discretization. When instantiated, Scheme is configured for a single
-    specific discretization which must be selected from the list of types in
-    SchemeBase::Proxy.
-
-    The underlying type of proxy is a variant, which allows storing exactly one
-    object. A variant is a type-safe union. An instance of a variant at any
-    given time either holds a value of one of its alternative types. Read more
-    on std::variant on how they work.
-
-    Adding a new child scheme is done by
-    (1) Adding a new type of Charm++ chare array proxy to Scheme::Proxy,
-    (2) Adding a new type of Charm++ chare array element proxy to
-        Scheme::ProxyElem, and
-    (3) Adding a new branch to the if test in Scheme's constructor.
-
-  \see A talk on "Concept-based runtime polymorphism with Charm++ chare arrays
-    using value semantics given by J. Bakosi at the 16th Annual Workshop on
-    Charm++ and its Applications, April 2018, discussing an earlier, more
-    verbose implementation of the idea, using C++11.
-*/
-// *****************************************************************************
-#ifndef Scheme_h
-#define Scheme_h
-
-#include "Exception.hpp"
-#include "PUPUtil.hpp"
-#include "Inciter/Options/Scheme.hpp"
-
-#include "NoWarning/discretization.decl.h"
-#include "NoWarning/alecg.decl.h"
-#include "NoWarning/oversetfe.decl.h"
-#include "NoWarning/dg.decl.h"
-#include "NoWarning/fv.decl.h"
-#include "NoWarning/ale.decl.h"
-#include "NoWarning/conjugategradients.decl.h"
-#include "NoWarning/ghosts.decl.h"
-
-namespace inciter {
-
-//! Base class for generic forwarding interface to discretization proxies
-class Scheme {
+    //! Print control option: 'group : option'
+    template< typename Option, typename... tags >
+    void Item() const {
+      Option opt;
+      m_stream << m_item_name_value_fmt
+                  % m_item_indent % opt.group()
+                  % opt.name( g_inputdeck.get< tags... >() );
+    }
+
+    // Helper class for compact output of PDE policies
+    class Policies {
+      public:
+        // Default constructor
+        explicit Policies() : phys(), prob() {}
+        // Initializer constructor
+        explicit Policies( const std::string& p, const std::string& t ) :
+          phys(p), prob(t) {}
+        // Operator += for adding up two Policies structs
+        Policies& operator+= ( const Policies& p ) {
+          phys += p.phys;
+          prob += p.prob;
+          return *this;
+        }
+
+      private:
+        // Make all policies unique
+        void unique() { tk::unique( phys ); tk::unique( prob ); }
+
+        std::string phys;
+        std::string prob;
+    };
+
+    //! Print equation list with policies
+    //! \param[in] t Section title
+    //! \param[in] factory Factory to get equation data from
+    //! \param[in] ntypes Unique equation types
+    template< class Factory >
+    void eqlist( const std::string& t,
+                 const Factory& factory,
+                 std::size_t ntypes ) const
+    {
+      if (!factory.empty()) {
+        section( t );
+        item( "Unique equation types", ntypes );
+        item( "With all policy combinations", factory.size() );
+      }
+    }
 
-  private:
-    //! Variant type listing all chare proxy types modeling the same concept
-    using Proxy = std::variant< CProxy_DG
-                              , CProxy_ALECG
-                              , CProxy_OversetFE
-                              , CProxy_FV >;
-
-  public:
-    //! Variant type listing all chare element proxy types
-    using ProxyElem = std::variant< CProxy_DG::element_t
-                                  , CProxy_ALECG::element_t
-                                  , CProxy_OversetFE::element_t
-                                  , CProxy_FV::element_t >;
-
-    //! Empty constructor for Charm++
-    explicit Scheme() {}
-
-    //! Constructor
-    //! \param[in] scheme Discretization scheme
-    //! \param[in] ale True if enable ALE
-    //! \param[in] linearsolver True if enable a linear solver
-    //! \details Based on the input enum we create at least two empty chare
-    //!   arrays: (1) discproxy which contains common functionality and data for
-    //!   all discretizations, and (2) proxy, which have functionality and data
-    //!   specific to a given discretization. Note that proxy is bound (in
-    //!   migration behavior and properties) to discproxy.
-    //! \note There may be other bound proxy arrays created depending on the
-    //!   specific discretization configured by the enum.
-    explicit Scheme( ctr::SchemeType scheme,
-                     bool ale = false,
-                     bool linearsolver = false,
-                     tk::Centering centering = tk::Centering::NODE ) :
-      discproxy( CProxy_Discretization::ckNew() )
-    {
-      bound.bindTo( discproxy );
-      if (scheme == ctr::SchemeType::DG ||
-                 scheme == ctr::SchemeType::P0P1 ||
-                 scheme == ctr::SchemeType::DGP1 ||
-                 scheme == ctr::SchemeType::DGP2 ||
-                 scheme == ctr::SchemeType::PDG)
-      {
-        proxy = static_cast< CProxy_DG >( CProxy_DG::ckNew(bound) );
-      } else if (scheme == ctr::SchemeType::ALECG) {
-        proxy = static_cast< CProxy_ALECG >( CProxy_ALECG::ckNew(bound) );
-      } else if (scheme == ctr::SchemeType::OversetFE) {
-        proxy = static_cast< CProxy_OversetFE >( CProxy_OversetFE::ckNew(bound) );
-      } else if (scheme == ctr::SchemeType::FV) {
-        proxy = static_cast< CProxy_FV >( CProxy_FV::ckNew(bound) );
-      } else Throw( "Unknown discretization scheme" );
-      if (ale) aleproxy = CProxy_ALE::ckNew(bound);
-      if (linearsolver)
-        conjugategradientsproxy = tk::CProxy_ConjugateGradients::ckNew(bound);
-      if (centering == tk::Centering::ELEM)
-        ghostsproxy = CProxy_Ghosts::ckNew(bound);
-    }
-
-    //! Entry method tags for specific Scheme classes to use with bcast()
-    struct setup {};
-    struct box {};
-    struct transferSol {};
-    struct advance {};
-    struct resized {};
-    struct resizeComm {};
-    struct refine {};
-    struct lhs {};
-    struct nodeNeighSetup {};
-    struct diag {};
-    struct evalLB {};
-    struct doneInserting {};
-    //! Issue broadcast to Scheme entry method
-    //! \tparam Fn Function tag identifying the entry method to call
-    //! \tparam Args Types of arguments to pass to entry method
-    //! \param[in] args Arguments to member function entry method to be called
-    //! \details This function issues a broadcast to a member function entry
-    //!   method of the Scheme chare array (the child of Discretization) and is
-    //!   thus equivalent to proxy.Fn(...).
-    template< typename Fn, typename... Args >
-    void bcast( Args&&... args ) {
-      std::visit( [&]( auto& p ){<--- Parameter 'p' can be declared with const
-          if constexpr( std::is_same_v< Fn, setup > )
-            p.setup( std::forward< Args >( args )... );
-          if constexpr( std::is_same_v< Fn, box > )
-            p.box( std::forward< Args >( args )... );
-          else if constexpr( std::is_same_v< Fn, transferSol > )
-            p.transferSol( std::forward< Args >( args )... );
-          else if constexpr( std::is_same_v< Fn, advance > )
-            p.advance( std::forward< Args >( args )... );
-          else if constexpr( std::is_same_v< Fn, resized > )
-            p.resized( std::forward< Args >( args )... );
-          else if constexpr( std::is_same_v< Fn, resizeComm > )
-            p.resizeComm( std::forward< Args >( args )... );
-          else if constexpr( std::is_same_v< Fn, refine > )
-            p.refine( std::forward< Args >( args )... );
-          else if constexpr( std::is_same_v< Fn, lhs > )
-            p.lhs( std::forward< Args >( args )... );
-          else if constexpr( std::is_same_v< Fn, nodeNeighSetup > )
-            p.nodeNeighSetup( std::forward< Args >( args )... );
-          else if constexpr( std::is_same_v< Fn, diag > )
-            p.diag( std::forward< Args >( args )... );
-          else if constexpr( std::is_same_v< Fn, evalLB > )
-            p.evalLB( std::forward< Args >( args )... );
-          else if constexpr( std::is_same_v< Fn, doneInserting > )
-            p.doneInserting( std::forward< Args >( args )... );
-        }, proxy );
-    }
-
-    //! Function tags for specific Scheme classes to use with ckLocal()
-    struct resizePostAMR {};
-    struct extractFieldOutput {};
-    struct solution {};
-    //! Call Scheme function via Charm++ chare array element's ckLocal()
-    //! \tparam Fn Function tag identifying the function to call
-    //! \tparam Args Types of arguments to pass to function
-    //! \param[in] x Chare array element index
-    //! \param[in] args Arguments to member function function to be called
-    //! \details This function calls a member function via Charm++'s ckLocal()
-    //!    behind the element proxy configured, indexed by the array index x.
-    //!    Since the call is behind ckLocal(), the member function does not have
-    //!    to be a Charm++ entry method.
-    template< typename Fn, typename... Args >
-    auto ckLocal( const CkArrayIndex1D& x, Args&&... args ) const {
-      auto e = element( x );
-      return std::visit( [&]( auto& p ){
-          if constexpr( std::is_same_v< Fn, resizePostAMR > )
-            return p.ckLocal()->resizePostAMR( std::forward<Args>(args)... );
-          else if constexpr( std::is_same_v< Fn, extractFieldOutput > )
-            return p.ckLocal()->extractFieldOutput(std::forward<Args>(args)...);
-          else if constexpr( std::is_same_v< Fn, solution > )
-            return p.ckLocal()->solution( std::forward<Args>(args)... );
-        }, e );
-    }
-
-    //! Function to call the insert entry method of an element proxy
-    //! \param[in] x Chare array element index
-    //! \param[in] args Arguments to member function (entry method) to be called
-    //! \details This function calls the insert member function of a chare array
-    //!   element proxy and thus equivalent to proxy[x].insert(...), using the
-    //!   last argument as default.
-    template< typename... Args >
-    void insert( const CkArrayIndex1D& x, Args&&... args ) {
-      auto e = element( x );
-      std::visit( [&]( auto& p ){ p.insert(std::forward<Args>(args)...); }, e );<--- Parameter 'p' can be declared with const
-    }
-
-    //! Get reference to discretization proxy
-    //! \return Discretization Charm++ chare array proxy
-    CProxy_Discretization& disc() noexcept { return discproxy; }
-
-    //! Get reference to ALE proxy
-    //! \return ALE Charm++ chare array proxy
-    CProxy_ALE& ale() noexcept { return aleproxy; }
-
-    //! Get reference to ConjugateGradients proxy
-    //! \return ConjugateGradients Charm++ chare array proxy
-    tk::CProxy_ConjugateGradients& conjugategradients() noexcept
-    { return conjugategradientsproxy; }
-
-    //! Get reference to Ghosts proxy
-    //! \return Ghosts Charm++ chare array proxy
-    CProxy_Ghosts& ghosts() noexcept { return ghostsproxy; }
-
-    //! Get reference to scheme proxy
-    //! Get reference to scheme proxy
-    //! \return Variant storing Charm++ chare array proxy configured
-    const Proxy& getProxy() noexcept { return proxy; }
-
-    //! Query underlying proxy type
-    //! \return Zero-based index into the set of types of Proxy
-    std::size_t index() const noexcept { return proxy.index(); }
-
-    //! Query underlying proxy element type
-    //! \return Zero-based index that can be used, e.g., indexing into the set
-    //!   of types of ProxyElem
-    std::size_t index_element() const noexcept { return element(0).index(); }
-
-    //! Charm++ array options accessor for binding external proxies
-    //! \return Charm++ array options object reference
-    const CkArrayOptions& arrayoptions() { return bound; }
-
-    /** @name Charm++ pack/unpack serializer member functions */
-    ///@{
-    //! \brief Pack/Unpack serialize member function
-    //! \param[in,out] p Charm++'s PUP::er serializer object reference
-    void pup( PUP::er &p ) {<--- Parameter 'p' can be declared with const
-      p | proxy;
-      p | discproxy;
-      p | aleproxy;
-      p | conjugategradientsproxy;
-      p | ghostsproxy;
-      p | bound;
-    }
-    //! \brief Pack/Unpack serialize operator|
-    //! \param[in,out] p Charm++'s PUP::er serializer object reference
-    //! \param[in,out] s Scheme object reference
-    friend void operator|( PUP::er& p, Scheme& s ) { s.pup(p); }
-    //@}
-
-  private:
-    //! Variant storing one proxy to which this class is configured for
-    Proxy proxy;
-    //! Charm++ proxy to data and code common to all discretizations
-    CProxy_Discretization discproxy;
-    //! Charm++ proxy to ALE class
-    CProxy_ALE aleproxy;
-    //! Charm++ proxy to conjugate gradients linear solver class
-    tk::CProxy_ConjugateGradients conjugategradientsproxy;
-    //! Charm++ proxy to Ghosts class
-    CProxy_Ghosts ghostsproxy;
-    //! Charm++ array options for binding chares
-    CkArrayOptions bound;
-
-    //! Function dereferencing operator[] of chare proxy inside variant
-    //! \param[in] x Chare array element index
-    //! \return Chare array element proxy as a variant, defined by ProxyElem
-    //! \details The returning element proxy is a variant, depending on the
-    //!   input proxy.
-    ProxyElem element( const CkArrayIndex1D& x ) const {
-      return std::visit( [&]( const auto& p ){
-               return static_cast< ProxyElem >( p[x] ); }, proxy );
-    }
-};
-
-} // inciter::
-
-#endif // Scheme_h
+    //! Print configuration of a stack of partial differential equations
+    void pdes( const std::string& t,
+      const std::vector< std::vector< std::pair< std::string, std::string > > >&
+        info ) const;
+
+    //! Print out info on solver coupling
+    void couple( const std::vector< Transfer >& transfer,
+                 const std::vector< char >& depvar ) const;
+
+    //! Print time integration header
+    void inthead( const std::string& t, const std::string& name,
+                  const std::string& legend, const std::string& head ) const;
+
+  private:
+    //! Return partial differential equation name
+    //! \param[in] key Equation key
+    //! \return Partial differential equation name based on key
+    template< class Key >
+    std::string PDEName ( const Key& key ) const<--- Unused private function: 'InciterPrint::PDEName'
+    { return ctr::PDE().name( key.template get< tag::pde >() ); }
+};
+
+} // inciter::
+
+#endif // InciterPrint_h
 
diff --git a/Release/cppcheck/34.html b/Release/cppcheck/34.html index 4dd999bc168e..7a2c94d672a4 100644 --- a/Release/cppcheck/34.html +++ b/Release/cppcheck/34.html @@ -152,12 +152,12 @@
  1
@@ -350,1061 +350,197 @@ 

Cppcheck report - [

// *****************************************************************************
+191
// *****************************************************************************
 /*!
-  \file      src/Inciter/Sorter.cpp
-  \copyright 2012-2015 J. Bakosi,
-             2016-2018 Los Alamos National Security, LLC.,
-             2019-2021 Triad National Security, LLC.
-             All rights reserved. See the LICENSE file for details.
-  \brief     Mesh sorter for global distributed mesh reordering
-  \see       Sorter.h for more info.
-*/
-// *****************************************************************************
-
-#include <vector>
-#include <algorithm>
+  \file      src/Control/Inciter/InputDeck/LuaParser.hpp
+  \copyright 2019-2023 Triad National Security, LLC.
+             All rights reserved. See the LICENSE file for details.
+  \brief     Inciter's lua input deck file parser
+  \details   This file declares the input deck, i.e., control file, parser for
+    the computational shock hydrodynamics tool, Inciter.
+*/
+// *****************************************************************************
+#ifndef InciterLuaParser_h
+#define InciterLuaParser_h
+
+#include "NoWarning/sol.hpp"
 
-#include "Sorter.hpp"
-#include "Reorder.hpp"
-#include "DerivedData.hpp"
-#include "Inciter/InputDeck/InputDeck.hpp"
+#include "Inciter/CmdLine/CmdLine.hpp"
+#include "InputDeck.hpp"
+
+namespace tk { class Print; }
 
 namespace inciter {
 
-extern ctr::InputDeck g_inputdeck;
-
-} // inciter::
-
-using inciter::Sorter;
+//! \brief Control file lua-parser for Inciter.
+//! \details This class is used to interface with sol2, for the purpose of
+//!   parsing the control file for the computational shock hydrodynamics tool,
+//!   Inciter.
+class LuaParser {
 
-Sorter::Sorter( std::size_t meshid,
-                const CProxy_Transporter& transporter,
-                const tk::CProxy_MeshWriter& meshwriter,
-                const tk::SorterCallback& cbs,
-                const std::vector< Scheme >& scheme,
-                CkCallback reorderRefiner,
-                const std::vector< std::size_t >& ginpoel,
-                const tk::UnsMesh::CoordMap& coordmap,
-                const tk::UnsMesh::Chunk& el,
-                const std::map< int, std::vector< std::size_t > >& bface,
-                const std::vector< std::size_t >& triinpoel,
-                const std::map< int, std::vector< std::size_t > >& bnode,
-                const std::unordered_map< std::size_t, std::set< std::size_t > >&
-                  elemblockid,
-                int nchare ) :
-  m_meshid( meshid ),
-  m_host( transporter ),
-  m_meshwriter( meshwriter ),
-  m_cbs( cbs ),
-  m_scheme( scheme ),
-  m_reorderRefiner( reorderRefiner ),
-  m_ginpoel( ginpoel ),
-  m_coordmap( coordmap ),
-  m_el( el ),
-  m_nbnd( 0 ),
-  m_bface( bface ),
-  m_triinpoel( triinpoel ),
-  m_bnode( bnode ),
-  m_elemblockid( elemblockid ),
-  m_nchare( nchare ),
-  m_nodeset( begin(ginpoel), end(ginpoel) ),
-  m_noffset( 0 ),
-  m_nodech(),
-  m_chnode(),
-  m_edgech(),
-  m_chedge(),
-  m_msum(),
-  m_reordcomm(),
-  m_start( 0 ),
-  m_newnodes(),
-  m_newcoordmap(),
-  m_reqnodes(),
-  m_lower( 0 ),
-  m_upper( 0 )
-// *****************************************************************************
-//  Constructor: prepare owned mesh node IDs for reordering
-//! \param[in] meshid Mesh ID
-//! \param[in] transporter Transporter (host) Charm++ proxy
-//! \param[in] meshwriter Mesh writer Charm++ proxy
-//! \param[in] cbs Charm++ callbacks for Sorter
-//! \param[in] scheme Discretization schemes (one per mesh)
-//! \param[in] reorderRefiner Callback to use to send reordered mesh to Refiner
-//! \param[in] ginpoel Mesh connectivity (this chare) using global node IDs
-//! \param[in] coordmap Mesh node coordinates (this chare) for global node IDs
-//! \param[in] bface Face lists mapped to side set ids
-//! \param[in] triinpoel Interconnectivity of points and boundary-faces
-//! \param[in] bnode Node ids mapped to side set ids
-//! \param[in] elemblockid Local tet ids associated to mesh block ids
-//! \param[in] nchare Total number of Charm++ worker chares
-// *****************************************************************************
-{
-  // Ensure boundary face ids will not index out of face connectivity
-  Assert( std::all_of( begin(m_bface), end(m_bface),
-            [&](const auto& s)
-            { return std::all_of( begin(s.second), end(s.second),
-                       [&](auto f){ return f*3+2 < m_triinpoel.size(); } ); } ),
-          "Boundary face data structures inconsistent" );
-}
-
-void
-Sorter::setup( std::size_t npoin )
-// *****************************************************************************
-// Setup chare mesh boundary node communication map
-//! \param[in] npoin Total number of mesh points in mesh. Note that the number
-//!   of mesh points does not have to be exactly the total number of points in
-//!   the mesh. It can be a larger number, but not less. This is only used here
-//!   to assign nodes to workers that will assign ids to mesh nodes during node
-//!   reordering.
-// *****************************************************************************
-{
-  // Compute the number of nodes (chunksize) a chare will build a node
-  // communication map for. We compute two values of chunksize: one for when
-  // the global node ids are abounded between [0...npoin-1], inclusive, and
-  // another one for when the global node ids are assigned by a hash algorithm
-  // during initial mesh refinement. In the latter case, the maximum
-  // representable value of a std::size_t is assumed to be the large global node
-  // id and is used to compute the chunksize. To compute the bin id, we attempt
-  // to use the first chunksize first: if it gives a chare id that is
-  // (strictly) lower than the number of chares, that's good. If not, we compute
-  // the bin id based on the second chunksize, which almost always will give a
-  // bin id strictly lower than the number of chares, except if the global node
-  // id assigned by the hash algorithm in Refiner hits the maximum
-  // representable number in std::size_t. If that is the case, we just assign
-  // that node to the last chare.
-  auto N = static_cast< std::size_t >( m_nchare );
-  std::array< std::size_t, 2 > chunksize{{
-     npoin / N, std::numeric_limits< std::size_t >::max() / N }};
+  public:
+    //! Constructor
+    explicit LuaParser( const tk::Print& print,
+                              const ctr::CmdLine& cmdline,
+                              ctr::InputDeck& inputdeck );
+
+    //! Store lua inputdeck in custom struct
+    void storeInputDeck(
+      const sol::table& lua_ideck,
+      ctr::InputDeck& gideck );
+
+    //! Check and store material property into inpudeck storage
+    void checkStoreMatProp(
+      const sol::table table,
+      const std::string key,
+      std::size_t vecsize,
+      std::vector< tk::real >& storage );
+
+    //! Check and store field output variables
+    void addOutVar(
+      const std::string& varname,
+      const std::string& alias,
+      std::vector< char >& depv,
+      std::size_t nmat,
+      inciter::ctr::PDEType pde,
+      tk::Centering c,
+      std::vector< inciter::ctr::OutVar >& foutvar );
+
+  private:
+    const std::string m_filename;             //!< Name of file to parse
+
+    //! Assign parameter to inputdeck entry if specified, else default
+    //! \tparam N Type of parameter being read/assigned
+    //! \param[in] table Sol-table which contains said parameter
+    //! \param[in] key Key for said parameter in Sol-table
+    //! \param[in,out] storage Storage space in inputdeck where said parameter
+    //!   is to be stored
+    //! \param[in] dflt Default value of said parameter, if unspecified
+    template< typename N > void
+    storeIfSpecd(
+      const sol::table table,
+      const std::string key,
+      N& storage,
+      const N dflt )
+    {
+      auto sol_var = table[key];
+      if (sol_var.valid())
+        storage = sol_var;
+      else
+        storage = dflt;
+    }
+
+    //! Assign Option to inputdeck entry if specified, else default
+    //! \tparam Op Option-Type of parameter being read/assigned
+    //! \tparam OpClass Option-class of parameter being read/assigned
+    //! \param[in] table Sol-table which contains said parameter
+    //! \param[in] key Key for said parameter in Sol-table
+    //! \param[in,out] storage Storage space in inputdeck where said parameter
+    //!   is to be stored
+    //! \param[in] dflt Default value of said parameter, if unspecified
+    template< typename Op, class OpClass > void
+    storeOptIfSpecd(
+      const sol::table table,
+      const std::string key,
+      Op& storage,
+      const Op dflt )
+    {
+      OpClass opt;
+      auto sol_var = table[key];
+      if (sol_var.valid())
+        storage = opt.value(sol_var);
+      else
+        storage = dflt;
+    }
+
+    //! Assign vector parameter to inputdeck entry if specified, else default
+    //! \tparam N Type of parameter vector being read/assigned
+    //! \param[in] table Sol-table which contains said parameter
+    //! \param[in] key Key for said parameter in Sol-table
+    //! \param[in,out] storage Storage space in inputdeck where said parameter
+    //!   is to be stored
+    //! \param[in] dflt Default value of said parameter, if unspecified
+    template< typename N > void
+    storeVecIfSpecd(
+      const sol::table table,
+      const std::string key,
+      std::vector< N >& storage,
+      const std::vector< N >& dflt )
+    {
+      auto sol_vec = table[key];
+      if (sol_vec.valid()) {
+        for (std::size_t i=0; i<sol::table(sol_vec).size(); ++i)
+          storage.push_back(sol_vec[i+1]);
+      }
+      else
+        storage = dflt;
+    }
 
-  const auto scheme = g_inputdeck.get< tag::scheme >();<--- Variable 'scheme' is assigned a value that is never used.
-
-  // Find chare-boundary nodes and edges of our mesh chunk. This algorithm
-  // collects the global mesh node ids and edges on the chare boundary. A node
-  // is on a chare boundary if it belongs to a face of a tetrahedron that has
-  // no neighbor tet at a face. The edge is on the chare boundary if its first
-  // edge-end point is on a chare boundary. The nodes are categorized to bins
-  // that will be sent to different chares to build point-to-point
-  // communication maps across all chares. The binning is determined by the
-  // global node id divided by the chunksizes. See discussion above on how we
-  // use two chunksizes for global node ids assigned by the hash algorithm in
-  // Refiner (if initial mesh refinement has been done).
-  tk::CommMaps chbnd;
-  auto el = tk::global2local( m_ginpoel );      // generate local mesh data
-  const auto& inpoel = std::get< 0 >( el );     // local connectivity
-  auto esup = tk::genEsup( inpoel, 4 );         // elements surrounding points
-  auto esuel = tk::genEsuelTet( inpoel, esup ); // elems surrounding elements
-  for (std::size_t e=0; e<esuel.size()/4; ++e) {
-    auto mark = e*4;
-    for (std::size_t f=0; f<4; ++f)
-      if (esuel[mark+f] == -1)
-        for (std::size_t n=0; n<3; ++n) {
-          auto g = m_ginpoel[ mark+tk::lpofa[f][n] ];
-          auto bin = g / chunksize[0];
-          if (bin >= N) bin = g / chunksize[1];
-          if (bin >= N) bin = N - 1;
-          Assert( bin < N, "Will index out of number of chares" );
-          auto& b = chbnd[ static_cast< int >( bin ) ];
-          b.get< tag::node >().insert( g );
-          if (scheme == ctr::SchemeType::ALECG ||
-            scheme == ctr::SchemeType::OversetFE) {
-            auto h = m_ginpoel[ mark + tk::lpofa[ f ][ tk::lpoet[n][1] ] ];
-            b.get< tag::edge >().insert( { std::min(g,h), std::max(g,h) } );
-          }
-        }
-  }
-
-  // Send boundary data in bins to chares that will compute communication maps
-  // for the data in the bin. These bins form a distributed table.  Note that
-  // we only send data to those chares that have data to work on. The receiving
-  // sides do not know in advance if they receive messages or not.  Completion
-  // is detected by having the receiver respond back and counting the responses
-  // on the sender side, i.e., this chare.
-  m_nbnd = chbnd.size();
-  if (m_nbnd == 0)
-    contribute( sizeof(std::size_t), &m_meshid, CkReduction::nop,
-                m_cbs.get< tag::queried >() );
-  else
-    for (const auto& [ targetchare, bnd ] : chbnd)
-      thisProxy[ targetchare ].query( thisIndex, bnd );
-}
-
-void
-Sorter::query( int fromch, const tk::AllCommMaps& bnd )
-// *****************************************************************************
-// Incoming query for a list of mesh nodes for which this chare compiles node
-// communication maps
-//! \param[in] fromch Sender chare ID
-//! \param[in] bnd Chare-boundary data from another chare
-// *****************************************************************************
-{
-  // Store incoming nodes in node->chare and its inverse, chare->node, maps
-  const auto& nodes = bnd.get< tag::node >();
-  for (auto n : nodes) m_nodech[ n ].push_back( fromch );
-  m_chnode[ fromch ].insert( begin(nodes), end(nodes) );
-
-  // Store incoming edges in edge->chare and its inverse, chare->edge, maps
-  const auto& edges = bnd.get< tag::edge >();
-  for (const auto& e : edges) m_edgech[ e ].push_back( fromch );
-  m_chedge[ fromch ].insert( begin(edges), end(edges) );
-
-  // Report back to chare message received from
-  thisProxy[ fromch ].recvquery();
-}
-
-void
-Sorter::recvquery()
-// *****************************************************************************
-// Receive receipt of boundary node lists to query
-// *****************************************************************************
-{
-  if (--m_nbnd == 0)
-    contribute( sizeof(std::size_t), &m_meshid, CkReduction::nop,
-                m_cbs.get< tag::queried >() );
-}
-
-void
-Sorter::response()
-// *****************************************************************************
-//  Respond to boundary node list queries
-// *****************************************************************************
-{
-  std::unordered_map< int, tk::CommMaps > exp;
-
-  // Compute node communication map to be sent back to chares
-  for (const auto& [ neighborchare, bndnodes ] : m_chnode) {
-    auto& nc = exp[ neighborchare ];
-    for (auto n : bndnodes)
-      for (auto d : tk::cref_find(m_nodech,n))
-        if (d != neighborchare)
-          nc[d].get< tag::node >().insert( n );
-  }
-
-  // Compute edge communication map to be sent back to chares
-  for (const auto& [ neighborchare, bndedges ] : m_chedge) {
-    auto& ec = exp[ neighborchare ];
-    for (const auto& e : bndedges)
-      for (auto d : tk::cref_find(m_edgech,e))
-        if (d != neighborchare)
-          ec[d].get< tag::edge >().insert( e );
-  }
-
-  // Send communication maps to chares that issued a query to us. Communication
-  // maps were computed above for those chares that queried this map from us.
-  // This data form a distributed table and we only work on a chunk of it. Note
-  // that we only send data back to those chares that have queried us. The
-  // receiving sides do not know in advance if the receive messages or not.
-  // Completion is detected by having the receiver respond back and counting
-  // the responses on the sender side, i.e., this chare.
-  m_nbnd = exp.size();
-  if (m_nbnd == 0)
-    contribute( sizeof(std::size_t), &m_meshid, CkReduction::nop,
-                m_cbs.get< tag::responded >() );
-  else
-    for (const auto& [ targetchare, maps ] : exp)
-      thisProxy[ targetchare ].bnd( thisIndex, maps );
-}
-
-void
-Sorter::bnd( int fromch, const tk::CommMaps& msum )
-// *****************************************************************************
-// Receive boundary node communication maps for our mesh chunk
-//! \param[in] fromch Sender chare ID
-//! \param[in] msum Communication map(s) assembled by chare fromch
-// *****************************************************************************
-{
-  for (const auto& [ neighborchare, maps ] : msum) {
-    auto& m = m_msum[ neighborchare ];
-    const auto& nodemap = maps.get< tag::node >();
-    m.get< tag::node >().insert( begin(nodemap), end(nodemap) );
-    const auto& edgemap = maps.get< tag::edge >();
-    m.get< tag::edge >().insert( begin(edgemap), end(edgemap) );
-  }
-
-  // Report back to chare message received from
-  thisProxy[ fromch ].recvbnd();
-}
-
-void
-Sorter::recvbnd()
-// *****************************************************************************
-// Receive receipt of boundary node communication map
-// *****************************************************************************
-{
-  if (--m_nbnd == 0)
-    contribute( sizeof(std::size_t), &m_meshid, CkReduction::nop,
-                m_cbs.get< tag::responded >() );
-}
-
-void
-Sorter::start()
-// *****************************************************************************
-//  Start reordering (if enabled)
-// *****************************************************************************
-{
-  // Keep only those edges in edge comm map whose both end-points are in the
-  // node comm map
-  for (auto& [ neighborchare, maps ] : m_msum) {
-    const auto& nodes = maps.get< tag::node >();
-    tk::EdgeSet edges;
-    for (const auto& e : maps.get< tag::edge >())
-      if (nodes.find(e[0]) != end(nodes) && nodes.find(e[1]) != end(nodes))
-        edges.insert( e );
-    maps.get< tag::edge >() = std::move(edges);
-  }
-
-  if (g_inputdeck.get< tag::cmd, tag::feedback >()) m_host.chcomm();
-
-  tk::destroy( m_nodech );
-  tk::destroy( m_chnode );
-
-  if (g_inputdeck.get< tag::pelocal_reorder >())
-    mask();   // continue with mesh node reordering if requested (or required)
-  else
-    createDiscWorkers();  // skip mesh node reordering
-}
-
-void
-Sorter::mask()
-// *****************************************************************************
-//  Start preparing for mesh node reordering in parallel
-// *****************************************************************************
-{
-  // Compute asymmetric communcation map that will be used for reordering. This
-  // communication map is asymmetric because it associates global mesh node IDs
-  // to chares only with lower IDs than thisIndex. That is because this chare
-  // will need to receive new (reorderd) node IDs only from chares with lower
-  // IDs than thisIndex during node reordering. Since it only stores data for
-  // lower chare IDs, it is asymmetric. Note that because of this algorithm the
-  // type of m_msum is an ordered map, because of the std::none_of() algorithm
-  // needs to look at ALL chares this chare potentially communicates nodes with
-  // that have lower chare IDs that thisIndex. Since the map is ordered, it can
-  // walk through from the beginning of m_msum until the outer loop variable c,
-  // which is the chare ID the outer loop works on in a given cycle.
-  for (auto c=m_msum.cbegin(); c!=m_msum.cend(); ++c)
-    if (thisIndex > c->first) {
-      auto& n = m_reordcomm[ c->first ];
-      for (auto j : c->second.get< tag::node >())
-        if (std::none_of( m_msum.cbegin(), c,
-             [j]( const auto& s ) {
-               const auto& nodemap = s.second.template get< tag::node >();
-               return nodemap.find(j) != end(nodemap); } ))
-        {
-          n.insert(j);
-        }
-      if (n.empty()) m_reordcomm.erase( c->first );
-    }
-
-  // Count up total number of nodes this chare will need to receive
-  auto nrecv = tk::sumvalsize( m_reordcomm );
-
-  if ( g_inputdeck.get< tag::cmd, tag::feedback >() ) m_host.chmask();
-
-  // Compute number of mesh node IDs we will assign IDs to
-  auto nuniq = m_nodeset.size() - nrecv;
-
-  // Start computing offsets for node reordering
-  thisProxy.offset( thisIndex, nuniq );
-}
-
-void
-Sorter::offset( int c, std::size_t u )
-// *****************************************************************************
-//  Receive number of uniquely assigned global mesh node IDs from chares with
-//  lower IDs than thisIndex
-//! \param[in] c Chare ID
-//! \param[in] u Number of mesh node IDs chare c will assign IDs to
-//! \details This function computes the offset each chare will need to start
-//!   assigning its new node IDs from. The offset for a chare is the
-//!   offset for the previous chare plus the number of node IDs the previous
-//!   chare (uniquely) assigns new IDs for minus the number of node IDs the
-//!   previous chare receives from others (lower chares). This is computed here
-//!   in a parallel/distributed fashion by each chare sending its number of node
-//!   IDs (that it uniquely assigns) to all chares. Note that each chare would
-//!   only need to send this information to chares with higher IDs, but instead
-//!   this function is called in a broadcast fashion, because that is more
-//!   efficient than individual calls to only chares with higher IDs. Therefore
-//!   when computing the offsets, we only count the lower chares. When this is
-//!   done, we have the precise asymmetric communication map as well as the
-//!   start offset on all chares and so we can start the distributed global mesh
-//!   node ID reordering.
-// *****************************************************************************
-{
-  if (c < thisIndex) m_start += u;
-  if (++m_noffset == m_nchare) reorder();
-}
-
-void
-Sorter::reorder()
-// *****************************************************************************
-//  Reorder global mesh node IDs
-// *****************************************************************************
-{
-  // Activate SDAG waits for arriving requests from other chares requesting new
-  // node IDs for node IDs we assign new IDs to during reordering; and for
-  // computing/receiving lower and upper bounds of global node IDs our chare's
-  // linear system will operate on after reordering.
-  thisProxy[ thisIndex ].wait4prep();
-
-  // Send out request for new global node IDs for nodes we do not reorder
-  for (const auto& [ targetchare, nodes ] : m_reordcomm)
-    thisProxy[ targetchare ].request( thisIndex, nodes );
-
-  // Lambda to decide if node is assigned a new ID by this chare. If node is not
-  // found in the asymmetric communication map, it is owned, i.e., this chare
-  // assigns its new id.
-  auto ownnode = [ this ]( std::size_t p ) {
-    return std::all_of( m_reordcomm.cbegin(), m_reordcomm.cend(),
-                        [&](const auto& s)
-                        { return s.second.find(p) == s.second.cend(); } );
-  };
-
-  // Reorder our chunk of the mesh node IDs. Looping through all of our node
-  // IDs, we test if we are to assign a new ID to a node ID, and if so, we
-  // assign a new ID, i.e., reorder, by constructing a map associating new to
-  // old IDs (m_newnodes). We also count up the reordered nodes, which serves as
-  // the new node id. We also store the node coordinates associated to the new
-  // node ID.
-  for (auto p : m_nodeset)
-    if (ownnode(p)) {
-      m_newnodes[ p ] = m_start;        // assign new node ID (reorder)
-      m_newcoordmap.emplace( m_start, tk::cref_find(m_coordmap,p) );
-      ++m_start;
-    }
-
-  // Trigger SDAG wait indicating that reordering our node IDs are complete
-  reorderowned_complete();
-
-  // If all our nodes have new IDs assigned, reordering complete on this chare
-  if (m_newnodes.size() == m_nodeset.size()) finish();
-}
-
-void
-Sorter::request( int c, const std::unordered_set< std::size_t >& nd )
-// *****************************************************************************
-//  Request new global node IDs for old node IDs
-//! \param[in] c Chare request coming from and to which we send new IDs to
-//! \param[in] nd Set of old node IDs whose new IDs are requested
-// *****************************************************************************
-{
-  // Queue up requesting chare and node IDs
-  m_reqnodes.push_back( { c, nd } );
-  // Trigger SDAG wait signaling that node IDs have been requested from us
-  nodes_requested_complete();
-}
-
-void
-Sorter::prepare()
-// *****************************************************************************
-//  Find new node IDs for old ones and return them to the requestor(s)
-// *****************************************************************************
-{
-  // Find and return new node IDs to sender
-  for (const auto& [ requestorchare, nodes ] : m_reqnodes) {
-    std::unordered_map< std::size_t,
-      std::tuple< std::size_t, tk::UnsMesh::Coord > > n;
-    for (auto p : nodes) {
-      auto newid = tk::cref_find( m_newnodes, p );
-      n.emplace( p,
-        std::make_tuple( newid, tk::cref_find(m_newcoordmap,newid) ) );
-    }
-    thisProxy[ requestorchare ].neworder( n );
-  }
-
-  tk::destroy( m_reqnodes ); // Clear queue of requests just fulfilled
-
-  // Re-enable SDAG wait for preparing new node requests
-  thisProxy[ thisIndex ].wait4prep();
-
-  // Re-enable trigger signaling that reordering of owned node IDs are
-  // complete right away
-  reorderowned_complete();
-}
-
-void
-Sorter::neworder( const std::unordered_map< std::size_t,
-                        std::tuple< std::size_t, tk::UnsMesh::Coord > >& nodes )
-// *****************************************************************************
-//  Receive new (reordered) global node IDs
-//! \param[in] nodes Map associating new to old node IDs
-// *****************************************************************************
-{
-  // Store new node IDs associated to old ones, and node coordinates associated
-  // to new node IDs.
-  for (const auto& [ oldid, newnodes ] : nodes) {
-    auto newid = std::get< 0 >( newnodes );
-    m_newnodes[ oldid ] = newid;
-    m_newcoordmap.emplace( newid, std::get< 1 >( newnodes ) );
-  }
-
-  // If all our nodes have new IDs assigned, reorder complete on this PE
-  if (m_newnodes.size() == m_nodeset.size()) finish();
-}
-
-void
-Sorter::finish()
-// *****************************************************************************
-//  Compute final result of reordering
-//! \details Reordering is now complete on this chare. We now remap all mesh
-//!   data to reflect the new ordering.
-// *****************************************************************************
-{
-  // Update elem connectivity with the reordered node IDs
-  tk::remap( m_ginpoel, m_newnodes );
-
-  // Update node coordinate map with the reordered IDs
-  m_coordmap = m_newcoordmap;
-
-  // Update mesh chunk data structure held in our state with new node order
-  m_el = tk::global2local( m_ginpoel );
-
-  // Update symmetric chare-node communication map with the reordered IDs
-  for (auto& [ neighborchare, maps ] : m_msum) {
-
-    tk::NodeSet n;
-    for (auto p : maps.get< tag::node >())
-      n.insert( tk::cref_find( m_newnodes, p ) );
-    maps.get< tag::node >() = std::move( n );
-
-    tk::EdgeSet e;
-    for (const auto& ed : maps.get< tag::edge >()) {
-      e.insert( { tk::cref_find(m_newnodes,ed[0]),
-                  tk::cref_find(m_newnodes,ed[1]) } );
-    }
-    maps.get< tag::edge >() = std::move( e );
-
-  }
-
-  // Update boundary face-node connectivity with the reordered node IDs
-  tk::remap( m_triinpoel, m_newnodes );
-
-  // Update boundary node lists with the reordered node IDs
-  for (auto& [ setid, nodes ] : m_bnode) tk::remap( nodes, m_newnodes );
-
-  // Update mesh in Refiner after reordering
-  m_reorderRefiner.send();
-
-  // Progress report to host
-  if ( g_inputdeck.get< tag::cmd, tag::feedback >() ) m_host.chreordered();
-
-  createDiscWorkers();
-}
-
-void
-Sorter::mesh( std::vector< std::size_t >& ginpoel,
-              tk::UnsMesh::CoordMap& coordmap,
-              std::vector< std::size_t >& triinpoel,
-              std::map< int, std::vector< std::size_t > >& bnode )
-// *****************************************************************************
-// Update mesh data we hold for whoever calls this function
-//! \param[in,out] ginpoel Mesh connectivity using global IDs
-//! \param[in,out] coordmap Map of mesh node coordinates
-//! \param[in,out] triinpoel Boundary face-node connectivity
-//! \param[in] bnode Node lists of side sets
-// *****************************************************************************
-{
-  ginpoel = m_ginpoel;
-  coordmap = m_coordmap;
-  triinpoel = m_triinpoel;
-  bnode = m_bnode;
-}
-
-void
-Sorter::createDiscWorkers()
-// *****************************************************************************
-//  Create Discretization chare array elements on this PE
-//! \details We create chare array elements by calling the insert() member
-//!   function, which allows specifying the PE on which the array element is
-//!   created. and we send each chare array element the chunk of mesh it will
-//!   operate on.
-// *****************************************************************************
-{
-  std::vector< CProxy_Discretization > disc;
-  for (auto& d : m_scheme) disc.push_back( d.disc() );<--- Consider using std::transform algorithm instead of a raw loop.
-
-  // Create worker array element using Charm++ dynamic chare array element
-  // insertion: last arg: PE chare is created on. See also Charm++ manual, Sec.
-  // "Dynamic Insertion".
-
-  m_scheme[m_meshid].disc()[ thisIndex ].insert( m_meshid, disc,
-    m_scheme[m_meshid].ale(),
-    m_scheme[m_meshid].conjugategradients(), m_host, m_meshwriter, m_coordmap,
-    m_el, m_msum, m_bface, m_triinpoel, m_elemblockid, m_nchare );
-
-  contribute( sizeof(std::size_t), &m_meshid, CkReduction::nop,
-              m_cbs.get< tag::discinserted >() );
-}
-
-void
-Sorter::createWorkers()
-// *****************************************************************************
-//  Create worker chare array element
-// *****************************************************************************
-{
-  // Make sure (bound) base is already created and accessible
-  Assert( m_scheme[m_meshid].disc()[thisIndex].ckLocal() != nullptr,
-          "About to pass nullptr" );
-
-  // Create worker array element using Charm++ dynamic chare array element
-  // insertion: 1st arg: chare id, other args: Discretization's child ctor args.
-  // See also Charm++ manual, Sec. "Dynamic Insertion".
-
-  m_scheme[m_meshid].insert( thisIndex, m_scheme[m_meshid].disc(),
-    m_scheme[m_meshid].ghosts(), m_bface, m_bnode, m_triinpoel );
-
-  if ( g_inputdeck.get< tag::cmd, tag::feedback >() ) m_host.chcreated();
-
-  contribute( sizeof(std::size_t), &m_meshid, CkReduction::nop,
-              m_cbs.get< tag::workinserted >() );
-
-  // Free up some memory
-  tk::destroy( m_ginpoel );
-  tk::destroy( m_coordmap );
-  tk::destroy( m_bface );
-  tk::destroy( m_triinpoel );
-  tk::destroy( m_elemblockid );
-  tk::destroy( m_bnode );
-  tk::destroy( m_nodeset );
-  tk::destroy( m_nodech );
-  tk::destroy( m_chnode );
-  tk::destroy( m_msum );
-  tk::destroy( m_reordcomm );
-  tk::destroy( m_newnodes );
-  tk::destroy( m_reqnodes );
-}
-
-#include "NoWarning/sorter.def.h"
+    //! Assign vector of Options to inputdeck entry if specified, else default
+    //! \tparam Op Option-Type of parameter being read/assigned
+    //! \tparam OpClass Option-class of parameter being read/assigned
+    //! \param[in] table Sol-table which contains said parameter
+    //! \param[in] key Key for said parameter in Sol-table
+    //! \param[in,out] storage Storage space in inputdeck where said parameter
+    //!   is to be stored
+    //! \param[in] dflt Default value of said parameter, if unspecified
+    template< typename Op, class OpClass > void
+    storeOptVecIfSpecd(
+      const sol::table table,
+      const std::string key,
+      std::vector< Op >& storage,
+      const std::vector< Op >& dflt )
+    {
+      OpClass opt;
+      auto sol_vec = table[key];
+      if (sol_vec.valid()) {
+        for (std::size_t i=0; i<sol::table(sol_vec).size(); ++i)
+          storage.push_back(opt.value(sol_vec[i+1]));
+      }
+      else
+        storage = dflt;
+    }
+
+    //! \brief Check validity of keywords within a particular block
+    //! \tparam tags Tags addressing the said block in the input deck
+    //! \param[in] block Sol table of the input deck block read in from the
+    //!   lua file
+    //! \param[in] blk_name Name of the block, for error clarity
+    template< typename... tags >
+    void checkBlock(const sol::table& block, const std::string& blk_name) const
+    {
+      for (const auto& kvp : block) {
+        bool is_valid(false);
+        auto ukw = kvp.first.as<std::string>();
+        brigand::for_each< tags... >( checkKw(ukw, is_valid) );
+        if (!is_valid)
+          Throw("Invalid keyword '" + ukw + "' in '" + blk_name + "' block.");
+      }
+    }
+
+    // Check if a keyword matches the existing ones
+    struct checkKw {
+      std::string user_kw;
+      // reference to bool keeping track of kw-match
+      bool& is_valid;
+      // Constructor
+      checkKw( const std::string& ukw, bool& isv ) :
+        user_kw(ukw), is_valid(isv) {}
+      //! Function to call for each keyword type
+      template< typename U > void operator()( brigand::type_<U> ) {
+        auto spec_key = U::name();
+        // only check if not previously matched
+        if (!is_valid) {
+          if (user_kw == spec_key) is_valid = true;
+          else is_valid = false;
+        }
+      }
+    };
+};
+
+} // namespace inciter
+
+#endif // InciterLuaParser_h
 
diff --git a/Release/cppcheck/36.html b/Release/cppcheck/36.html index da238f4453a7..394418cea451 100644 --- a/Release/cppcheck/36.html +++ b/Release/cppcheck/36.html @@ -152,2505 +152,653 @@
- - + @@ -73,35 +73,35 @@ - + - + - + - + - + - + - + - + @@ -113,7 +113,7 @@ - +
   1
-   2
-   3
-   4
-   5
-   6
-   7
-   8
-   9
-  10
-  11
-  12
-  13
-  14
-  15
-  16
-  17
-  18
-  19
-  20
-  21
-  22
-  23
-  24
-  25
-  26
-  27
-  28
-  29
-  30
-  31
-  32
-  33
-  34
-  35
-  36
-  37
-  38
-  39
-  40
-  41
-  42
-  43
-  44
-  45
-  46
-  47
-  48
-  49
-  50
-  51
-  52
-  53
-  54
-  55
-  56
-  57
-  58
-  59
-  60
-  61
-  62
-  63
-  64
-  65
-  66
-  67
-  68
-  69
-  70
-  71
-  72
-  73
-  74
-  75
-  76
-  77
-  78
-  79
-  80
-  81
-  82
-  83
-  84
-  85
-  86
-  87
-  88
-  89
-  90
-  91
-  92
-  93
-  94
-  95
-  96
-  97
-  98
-  99
- 100
- 101
- 102
- 103
- 104
- 105
- 106
- 107
- 108
- 109
- 110
- 111
- 112
- 113
- 114
- 115
- 116
- 117
- 118
- 119
- 120
- 121
- 122
- 123
- 124
- 125
- 126
- 127
- 128
- 129
- 130
- 131
- 132
- 133
- 134
- 135
- 136
- 137
- 138
- 139
- 140
- 141
- 142
- 143
- 144
- 145
- 146
- 147
- 148
- 149
- 150
- 151
- 152
- 153
- 154
- 155
- 156
- 157
- 158
- 159
- 160
- 161
- 162
- 163
- 164
- 165
- 166
- 167
- 168
- 169
- 170
- 171
- 172
- 173
- 174
- 175
- 176
- 177
- 178
- 179
- 180
- 181
- 182
- 183
- 184
- 185
- 186
- 187
- 188
- 189
- 190
- 191
- 192
- 193
- 194
- 195
- 196
- 197
- 198
- 199
- 200
- 201
- 202
- 203
- 204
- 205
- 206
- 207
- 208
- 209
- 210
- 211
- 212
- 213
- 214
- 215
- 216
- 217
- 218
- 219
- 220
- 221
- 222
- 223
- 224
- 225
- 226
- 227
- 228
- 229
- 230
- 231
- 232
- 233
- 234
- 235
- 236
- 237
- 238
- 239
- 240
- 241
- 242
- 243
- 244
- 245
- 246
- 247
- 248
- 249
- 250
- 251
- 252
- 253
- 254
- 255
- 256
- 257
- 258
- 259
- 260
- 261
- 262
- 263
- 264
- 265
- 266
- 267
- 268
- 269
- 270
- 271
- 272
- 273
- 274
- 275
- 276
- 277
- 278
- 279
- 280
- 281
- 282
- 283
- 284
- 285
- 286
- 287
- 288
- 289
- 290
- 291
- 292
- 293
- 294
- 295
- 296
- 297
- 298
- 299
- 300
- 301
- 302
- 303
- 304
- 305
- 306
- 307
- 308
- 309
- 310
- 311
- 312
- 313
- 314
- 315
- 316
- 317
- 318
- 319
- 320
- 321
- 322
- 323
- 324
- 325
- 326
- 327
- 328
- 329
- 330
- 331
- 332
- 333
- 334
- 335
- 336
- 337
- 338
- 339
- 340
- 341
- 342
- 343
- 344
- 345
- 346
- 347
- 348
- 349
- 350
- 351
- 352
- 353
- 354
- 355
- 356
- 357
- 358
- 359
- 360
- 361
- 362
- 363
- 364
- 365
- 366
- 367
- 368
- 369
- 370
- 371
- 372
- 373
- 374
- 375
- 376
- 377
- 378
- 379
- 380
- 381
- 382
- 383
- 384
- 385
- 386
- 387
- 388
- 389
- 390
- 391
- 392
- 393
- 394
- 395
- 396
- 397
- 398
- 399
- 400
- 401
- 402
- 403
- 404
- 405
- 406
- 407
- 408
- 409
- 410
- 411
- 412
- 413
- 414
- 415
- 416
- 417
- 418
- 419
- 420
- 421
- 422
- 423
- 424
- 425
- 426
- 427
- 428
- 429
- 430
- 431
- 432
- 433
- 434
- 435
- 436
- 437
- 438
- 439
- 440
- 441
- 442
- 443
- 444
- 445
- 446
- 447
- 448
- 449
- 450
- 451
- 452
- 453
- 454
- 455
- 456
- 457
- 458
- 459
- 460
- 461
- 462
- 463
- 464
- 465
- 466
- 467
- 468
- 469
- 470
- 471
- 472
- 473
- 474
- 475
- 476
- 477
- 478
- 479
- 480
- 481
- 482
- 483
- 484
- 485
- 486
- 487
- 488
- 489
- 490
- 491
- 492
- 493
- 494
- 495
- 496
- 497
- 498
- 499
- 500
- 501
- 502
- 503
- 504
- 505
- 506
- 507
- 508
- 509
- 510
- 511
- 512
- 513
- 514
- 515
- 516
- 517
- 518
- 519
- 520
- 521
- 522
- 523
- 524
- 525
- 526
- 527
- 528
- 529
- 530
- 531
- 532
- 533
- 534
- 535
- 536
- 537
- 538
- 539
- 540
- 541
- 542
- 543
- 544
- 545
- 546
- 547
- 548
- 549
- 550
- 551
- 552
- 553
- 554
- 555
- 556
- 557
- 558
- 559
- 560
- 561
- 562
- 563
- 564
- 565
- 566
- 567
- 568
- 569
- 570
- 571
- 572
- 573
- 574
- 575
- 576
- 577
- 578
- 579
- 580
- 581
- 582
- 583
- 584
- 585
- 586
- 587
- 588
- 589
- 590
- 591
- 592
- 593
- 594
- 595
- 596
- 597
- 598
- 599
- 600
- 601
- 602
- 603
- 604
- 605
- 606
- 607
- 608
- 609
- 610
- 611
- 612
- 613
- 614
- 615
- 616
- 617
- 618
- 619
- 620
- 621
- 622
- 623
- 624
- 625
- 626
- 627
- 628
- 629
- 630
- 631
- 632
- 633
- 634
- 635
- 636
- 637
- 638
- 639
- 640
- 641
- 642
- 643
- 644
- 645
- 646
- 647
- 648
- 649
- 650
- 651
- 652
- 653
- 654
- 655
- 656
- 657
- 658
- 659
- 660
- 661
- 662
- 663
- 664
- 665
- 666
- 667
- 668
- 669
- 670
- 671
- 672
- 673
- 674
- 675
- 676
- 677
- 678
- 679
- 680
- 681
- 682
- 683
- 684
- 685
- 686
- 687
- 688
- 689
- 690
- 691
- 692
- 693
- 694
- 695
- 696
- 697
- 698
- 699
- 700
- 701
- 702
- 703
- 704
- 705
- 706
- 707
- 708
- 709
- 710
- 711
- 712
- 713
- 714
- 715
- 716
- 717
- 718
- 719
- 720
- 721
- 722
- 723
- 724
- 725
- 726
- 727
- 728
- 729
- 730
- 731
- 732
- 733
- 734
- 735
- 736
- 737
- 738
- 739
- 740
- 741
- 742
- 743
- 744
- 745
- 746
- 747
- 748
- 749
- 750
- 751
- 752
- 753
- 754
- 755
- 756
- 757
- 758
- 759
- 760
- 761
- 762
- 763
- 764
- 765
- 766
- 767
- 768
- 769
- 770
- 771
- 772
- 773
- 774
- 775
- 776
- 777
- 778
- 779
- 780
- 781
- 782
- 783
- 784
- 785
- 786
- 787
- 788
- 789
- 790
- 791
- 792
- 793
- 794
- 795
- 796
- 797
- 798
- 799
- 800
- 801
- 802
- 803
- 804
- 805
- 806
- 807
- 808
- 809
- 810
- 811
- 812
- 813
- 814
- 815
- 816
- 817
- 818
- 819
- 820
- 821
- 822
- 823
- 824
- 825
- 826
- 827
- 828
- 829
- 830
- 831
- 832
- 833
- 834
- 835
- 836
- 837
- 838
- 839
- 840
- 841
- 842
- 843
- 844
- 845
- 846
- 847
- 848
- 849
- 850
- 851
- 852
- 853
- 854
- 855
- 856
- 857
- 858
- 859
- 860
- 861
- 862
- 863
- 864
- 865
- 866
- 867
- 868
- 869
- 870
- 871
- 872
- 873
- 874
- 875
- 876
- 877
- 878
- 879
- 880
- 881
- 882
- 883
- 884
- 885
- 886
- 887
- 888
- 889
- 890
- 891
- 892
- 893
- 894
- 895
- 896
- 897
- 898
- 899
- 900
- 901
- 902
- 903
- 904
- 905
- 906
- 907
- 908
- 909
- 910
- 911
- 912
- 913
- 914
- 915
- 916
- 917
- 918
- 919
- 920
- 921
- 922
- 923
- 924
- 925
- 926
- 927
- 928
- 929
- 930
- 931
- 932
- 933
- 934
- 935
- 936
- 937
- 938
- 939
- 940
- 941
- 942
- 943
- 944
- 945
- 946
- 947
- 948
- 949
- 950
- 951
- 952
- 953
- 954
- 955
- 956
- 957
- 958
- 959
- 960
- 961
- 962
- 963
- 964
- 965
- 966
- 967
- 968
- 969
- 970
- 971
- 972
- 973
- 974
- 975
- 976
- 977
- 978
- 979
- 980
- 981
- 982
- 983
- 984
- 985
- 986
- 987
- 988
- 989
- 990
- 991
- 992
- 993
- 994
- 995
- 996
- 997
- 998
- 999
-1000
-1001
-1002
-1003
-1004
-1005
-1006
-1007
-1008
-1009
-1010
-1011
-1012
-1013
-1014
-1015
-1016
-1017
-1018
-1019
-1020
-1021
-1022
-1023
-1024
-1025
-1026
-1027
-1028
-1029
-1030
-1031
-1032
-1033
-1034
-1035
-1036
-1037
-1038
-1039
-1040
-1041
-1042
-1043
-1044
-1045
-1046
-1047
-1048
-1049
-1050
-1051
-1052
-1053
-1054
-1055
-1056
-1057
-1058
-1059
-1060
-1061
-1062
-1063
-1064
-1065
-1066
-1067
-1068
-1069
-1070
-1071
-1072
-1073
-1074
-1075
-1076
-1077
-1078
-1079
-1080
-1081
-1082
-1083
-1084
-1085
-1086
-1087
-1088
-1089
-1090
-1091
-1092
-1093
-1094
-1095
-1096
-1097
-1098
-1099
-1100
-1101
-1102
-1103
-1104
-1105
-1106
-1107
-1108
-1109
-1110
-1111
-1112
-1113
-1114
-1115
-1116
-1117
-1118
-1119
-1120
-1121
-1122
-1123
-1124
-1125
-1126
-1127
-1128
-1129
-1130
-1131
-1132
-1133
-1134
-1135
-1136
-1137
-1138
-1139
-1140
-1141
-1142
-1143
-1144
-1145
-1146
-1147
-1148
-1149
-1150
-1151
-1152
-1153
-1154
-1155
-1156
-1157
-1158
-1159
-1160
-1161
-1162
-1163
-1164
-1165
-1166
-1167
-1168
-1169
-1170
-1171
-1172
-1173
-1174
-1175
-1176
-1177
-1178
-1179
-1180
-1181
-1182
-1183
-1184
-1185
-1186
-1187
-1188
-1189
-1190
-1191
-1192
-1193
-1194
-1195
-1196
-1197
-1198
-1199
-1200
-1201
-1202
-1203
-1204
-1205
-1206
-1207
-1208
-1209
-1210
-1211
-1212
-1213
-1214
-1215
-1216
-1217
-1218
-1219
-1220
-1221
-1222
-1223
-1224
-1225
-1226
-1227
-1228
-1229
-1230
-1231
-1232
-1233
-1234
-1235
-1236
-1237
-1238
-1239
-1240
-1241
-1242
-1243
-1244
-1245
-1246
// *****************************************************************************
+
  1
+  2
+  3
+  4
+  5
+  6
+  7
+  8
+  9
+ 10
+ 11
+ 12
+ 13
+ 14
+ 15
+ 16
+ 17
+ 18
+ 19
+ 20
+ 21
+ 22
+ 23
+ 24
+ 25
+ 26
+ 27
+ 28
+ 29
+ 30
+ 31
+ 32
+ 33
+ 34
+ 35
+ 36
+ 37
+ 38
+ 39
+ 40
+ 41
+ 42
+ 43
+ 44
+ 45
+ 46
+ 47
+ 48
+ 49
+ 50
+ 51
+ 52
+ 53
+ 54
+ 55
+ 56
+ 57
+ 58
+ 59
+ 60
+ 61
+ 62
+ 63
+ 64
+ 65
+ 66
+ 67
+ 68
+ 69
+ 70
+ 71
+ 72
+ 73
+ 74
+ 75
+ 76
+ 77
+ 78
+ 79
+ 80
+ 81
+ 82
+ 83
+ 84
+ 85
+ 86
+ 87
+ 88
+ 89
+ 90
+ 91
+ 92
+ 93
+ 94
+ 95
+ 96
+ 97
+ 98
+ 99
+100
+101
+102
+103
+104
+105
+106
+107
+108
+109
+110
+111
+112
+113
+114
+115
+116
+117
+118
+119
+120
+121
+122
+123
+124
+125
+126
+127
+128
+129
+130
+131
+132
+133
+134
+135
+136
+137
+138
+139
+140
+141
+142
+143
+144
+145
+146
+147
+148
+149
+150
+151
+152
+153
+154
+155
+156
+157
+158
+159
+160
+161
+162
+163
+164
+165
+166
+167
+168
+169
+170
+171
+172
+173
+174
+175
+176
+177
+178
+179
+180
+181
+182
+183
+184
+185
+186
+187
+188
+189
+190
+191
+192
+193
+194
+195
+196
+197
+198
+199
+200
+201
+202
+203
+204
+205
+206
+207
+208
+209
+210
+211
+212
+213
+214
+215
+216
+217
+218
+219
+220
+221
+222
+223
+224
+225
+226
+227
+228
+229
+230
+231
+232
+233
+234
+235
+236
+237
+238
+239
+240
+241
+242
+243
+244
+245
+246
+247
+248
+249
+250
+251
+252
+253
+254
+255
+256
+257
+258
+259
+260
+261
+262
+263
+264
+265
+266
+267
+268
+269
+270
+271
+272
+273
+274
+275
+276
+277
+278
+279
+280
+281
+282
+283
+284
+285
+286
+287
+288
+289
+290
+291
+292
+293
+294
+295
+296
+297
+298
+299
+300
+301
+302
+303
+304
+305
+306
+307
+308
+309
+310
+311
+312
+313
+314
+315
+316
+317
+318
+319
+320
// *****************************************************************************
 /*!
-  \file      src/Inciter/Discretization.cpp
+  \file      src/Inciter/Scheme.hpp
   \copyright 2012-2015 J. Bakosi,
              2016-2018 Los Alamos National Security, LLC.,
              2019-2021 Triad National Security, LLC.
              All rights reserved. See the LICENSE file for details.
-  \details   Data and functionality common to all discretization schemes
-  \see       Discretization.h and Discretization.C for more info.
-*/
-// *****************************************************************************
-
-#include "Tags.hpp"
-#include "Reorder.hpp"
-#include "Vector.hpp"
-#include "DerivedData.hpp"
-#include "Discretization.hpp"
-#include "MeshWriter.hpp"
-#include "DiagWriter.hpp"
-#include "Inciter/InputDeck/InputDeck.hpp"
-#include "Inciter/Options/Scheme.hpp"
-#include "Print.hpp"
-#include "Around.hpp"
-#include "QuinoaBuildConfig.hpp"
-#include "ConjugateGradients.hpp"
-#include "ALE.hpp"
-
-#include "M2MTransfer.hpp"
-
-namespace inciter {
-
-static CkReduction::reducerType PDFMerger;
-extern ctr::InputDeck g_inputdeck;
-extern ctr::InputDeck g_inputdeck_defaults;
-
-} // inciter::
-
-using inciter::Discretization;
-
-Discretization::Discretization(
-  std::size_t meshid,
-  const std::vector< CProxy_Discretization >& disc,
-  const CProxy_ALE& aleproxy,
-  const tk::CProxy_ConjugateGradients& conjugategradientsproxy,
-  const CProxy_Transporter& transporter,
-  const tk::CProxy_MeshWriter& meshwriter,
-  const tk::UnsMesh::CoordMap& coordmap,
-  const tk::UnsMesh::Chunk& el,
-  const tk::CommMaps& msum,
-  const std::map< int, std::vector< std::size_t > >& bface,
-  const std::vector< std::size_t >& triinpoel,
-  const std::unordered_map< std::size_t, std::set< std::size_t > >& elemblockid,
-  int nc ) :
-  m_meshid( meshid ),
-  m_transfer( g_inputdeck.get< tag::transfer >() ),
-  m_disc( disc ),
-  m_nchare( nc ),
-  m_it( 0 ),
-  m_itr( 0 ),
-  m_itf( 0 ),
-  m_initial( 1 ),
-  m_t( g_inputdeck.get< tag::t0 >() ),
-  m_lastDumpTime( -std::numeric_limits< tk::real >::max() ),
-  m_physFieldFloor( 0.0 ),
-  m_physHistFloor( 0.0 ),
-  m_rangeFieldFloor( 0.0 ),
-  m_rangeHistFloor( 0.0 ),
-  m_dt( g_inputdeck.get< tag::dt >() ),
-  m_dtn( m_dt ),
-  m_nvol( 0 ),
-  m_nxfer( 0 ),
-  m_ale( aleproxy ),
-  m_transporter( transporter ),
-  m_meshwriter( meshwriter ),
-  m_el( el ),     // fills m_inpoel, m_gid, m_lid
-  m_coord( setCoord( coordmap ) ),
-  m_coordn( m_coord ),
-  m_nodeCommMap(),
-  m_edgeCommMap(),
-  m_meshvol( 0.0 ),
-  m_v( m_gid.size(), 0.0 ),
-  m_vol( m_gid.size(), 0.0 ),
-  m_volc(),
-  m_voln( m_vol ),
-  m_vol0( m_inpoel.size()/4, 0.0 ),
-  m_bid(),
-  m_timer(),
-  m_refined( 0 ),
-  m_prevstatus( std::chrono::high_resolution_clock::now() ),
-  m_nrestart( 0 ),
-  m_histdata(),
-  m_nsrc( 0 ),
-  m_ndst( 0 ),
-  m_meshvel( 0, 3 ),
-  m_meshvel_converged( true ),
-  m_bface( bface ),
-  m_triinpoel( triinpoel ),
-  m_elemblockid( elemblockid )
-// *****************************************************************************
-//  Constructor
-//! \param[in] meshid Mesh ID
-//! \param[in] disc All Discretization proxies (one per mesh)
-//! \param[in] aleproxy Distributed ALE proxy
-//! \param[in] conjugategradientsproxy Distributed Conjugrate Gradients linear
-//!   solver proxy
-//! \param[in] transporter Host (Transporter) proxy
-//! \param[in] meshwriter Mesh writer proxy
-//! \param[in] coordmap Coordinates of mesh nodes and their global IDs
-//! \param[in] el Elements of the mesh chunk we operate on
-//! \param[in] msum Communication maps associated to chare IDs bordering the
-//!   mesh chunk we operate on
-//! \param[in] bface Face lists mapped to side set ids
-//! \param[in] triinpoel Interconnectivity of points and boundary-faces
-//! \param[in] elemblockid Local tet ids associated with mesh block ids
-//! \param[in] nc Total number of Discretization chares
-// *****************************************************************************
-{
-  Assert( !m_inpoel.empty(), "No elements assigned to Discretization chare" );
-  Assert( tk::positiveJacobians( m_inpoel, m_coord ),
-          "Jacobian in input mesh to Discretization non-positive" );
-  #if not defined(__INTEL_COMPILER) || defined(NDEBUG)
-  // The above ifdef skips running the conformity test with the intel compiler
-  // in debug mode only. This is necessary because in tk::conforming(), filling
-  // up the map can fail with some meshes (only in parallel), e.g., tube.exo,
-  // used by some regression tests, due to the intel compiler generating some
-  // garbage incorrect code - only in debug, only in parallel, only with that
-  // mesh.
-  Assert( tk::conforming( m_inpoel, m_coord ),
-          "Input mesh to Discretization not conforming" );
-  #endif
-
-  // Store communication maps
-  for (const auto& [ c, maps ] : msum) {
-    m_nodeCommMap[c] = maps.get< tag::node >();
-    m_edgeCommMap[c] = maps.get< tag::edge >();
-  }
-
-  // Get ready for computing/communicating nodal volumes
-  startvol();
-
-  // Get chare-boundary node-id map
-  m_bid = genBid();
-
-  // Find host elements of user-specified points where time histories are
-  // saved, and save the shape functions evaluated at the point locations
-  const auto& pt = g_inputdeck.get< tag::history_output, tag::point >();
-  for (std::size_t p=0; p<pt.size(); ++p) {
-    std::array< tk::real, 4 > N;
-    const auto& l = pt[p].get< tag::coord >();
-    const auto& id = pt[p].get< tag::id >();
-    for (std::size_t e=0; e<m_inpoel.size()/4; ++e) {
-      if (tk::intet( m_coord, m_inpoel, l, e, N )) {
-        m_histdata.push_back( HistData{{ id, e, {l[0],l[1],l[2]}, N }} );
-        break;
-      }
-    }
-  }
-
-  // Insert ConjugrateGradients solver chare array element if needed
-  if (g_inputdeck.get< tag::ale, tag::ale >()) {
-    m_ale[ thisIndex ].insert( conjugategradientsproxy,
-                               m_coord, m_inpoel,
-                               m_gid, m_lid, m_nodeCommMap );
-  } else {
-    m_meshvel.resize( m_gid.size() );
-  }
-
-  // Register mesh with mesh-transfer lib
-  if (m_disc.size() == 1 || m_transfer.empty()) {
-    // skip transfer if single mesh or if not involved in coupling
-    transferInit();
-  } else {
-    if (thisIndex == 0) {
-      exam2m::addMesh( thisProxy, m_nchare,
-        CkCallback( CkIndex_Discretization::transferInit(), thisProxy ) );
-      //std::cout << "Disc: " << m_meshid << " m2m::addMesh()\n";
-    }
-  }
-}
-
-std::unordered_map< std::size_t, std::size_t >
-Discretization::genBid()
-// *****************************************************************************
-// Generate the Bid data-structure based on the node communication-map
-// *****************************************************************************
-{
-  // Count the number of mesh nodes at which we receive data from other chares
-  // and compute map associating boundary-chare node ID to global node ID
-  std::vector< std::size_t > c( tk::sumvalsize( m_nodeCommMap ) );
-  std::size_t j = 0;
-  for (const auto& [ch,n] : m_nodeCommMap) for (auto i : n) c[j++] = i;
-  tk::unique( c );
-  return tk::assignLid( c );
-}
-
-void
-Discretization::transferInit()
-// *****************************************************************************
-// Our mesh has been registered with the mesh-to-mesh transfer library (if
-// coupled to other solver)
-// *****************************************************************************
-{
-  // Compute number of mesh points owned
-  std::size_t npoin = m_gid.size();
-  for (auto g : m_gid) if (tk::slave(m_nodeCommMap,g,thisIndex)) --npoin;
-
-  // Tell the RTS that the Discretization chares have been created and compute
-  // the total number of mesh points across the distributed mesh
-  std::vector< std::size_t > meshdata{ m_meshid, npoin };
-  contribute( meshdata, CkReduction::sum_ulong,
-    CkCallback( CkReductionTarget(Transporter,disccreated), m_transporter ) );
-}
-
-void
-Discretization::meshvelStart(
-  const tk::UnsMesh::Coords vel,
-  const std::vector< tk::real >& soundspeed,
-  const std::unordered_map< int,
-    std::unordered_map< std::size_t, std::array< tk::real, 4 > > >& bnorm,
-  tk::real adt,
-  CkCallback done ) const
-// *****************************************************************************
-// Start computing new mesh velocity for ALE mesh motion
-//! \param[in] vel Fluid velocity at mesh nodes
-//! \param[in] soundspeed Speed of sound at mesh nodes
-//! \param[in] bnorm Face normals in boundary points associated to side sets
-//! \param[in] adt alpha*dt of the RK time step
-//! \param[in] done Function to continue with when mesh velocity has been
-//!   computed
-// *****************************************************************************
-{
-  if (g_inputdeck.get< tag::ale, tag::ale >())
-    m_ale[ thisIndex ].ckLocal()->start( vel, soundspeed, done,
-      m_coord, m_coordn, m_vol0, m_vol, bnorm, m_initial, m_it, m_t, adt );
-  else
-    done.send();
-}
-
-const tk::Fields&
-Discretization::meshvel() const
-// *****************************************************************************
-//! Query the mesh velocity
-//! \return Mesh velocity
-// *****************************************************************************
-{
-  if (g_inputdeck.get< tag::ale, tag::ale >())
-    return m_ale[ thisIndex ].ckLocal()->meshvel();
-  else
-    return m_meshvel;
-}
-
-void
-Discretization::meshvelBnd(
-  const std::map< int, std::vector< std::size_t > >& bface,
-  const std::map< int, std::vector< std::size_t > >& bnode,
-  const std::vector< std::size_t >& triinpoel) const
-// *****************************************************************************
-// Query ALE mesh velocity boundary condition node lists and node lists at
-// which ALE moves boundaries
-// *****************************************************************************
-{
-  if (g_inputdeck.get< tag::ale, tag::ale >())
-    m_ale[ thisIndex ].ckLocal()->meshvelBnd( bface, bnode, triinpoel );
-}
+  \brief     Polymorphic glue for calling Charm++ entry methods to base class
+    Discretization, its children implementing specific discretization schemes,
+    and helper classes
+  \details
+    The purpose of this class is to hide, behind a single type, different
+    Charm++  proxy types that model a single concept, i.e., define some common
+    functions as Charm++ entry methods that can be used in either a broadcast
+    and/or in a way of addressing a single array element. As a result, member
+    functions can be invoked by client code without knowing the underlying type
+    or any specifics to the underlying differences of the classes that model the
+    same concept, i.e., expose the same member functions. The idea is very
+    similar to inheritance and runtime polymorphism with base classes and
+    virtual functions: some member functions and data are common to all types
+    modeled (and thus are not repeated and/or copied), while some are specific.
+    A difference is that the "base" and "child" classes are Charm++ proxies.
+    Note that while Charm++ does support inheritance and runtime polymorphism
+    with chare arrays, we still prefer the implementation below because it uses
+    entirely value semantics (inside and in client code) and thus it keeps the
+    complexity of the dispatch behind this class and does not expose it to
+    client code.
+
+    The advantages of this class over traditional runtime polymorphism are (1)
+    value semantics (both internally and to client code), (2) not templated,
+    and (3) PUPable, i.e., an instance of Scheme can be sent across the network
+    using Charm++'s pup framework. Also, since the class only holds a couple of
+    chare proxies, it is lightweight.
+
+    Example usage from client code:
+
+    \code{.cpp}
+      // Instantiate a Scheme object
+      Scheme s( ctr::SchemeType::DG );  // see Control/Inciter/Options/Scheme.h
+
+      // Issue broadcast to child scheme entry method
+      s.bcast< Scheme::setup >(...);
+
+      // Issue broadcast to base (Discretization) entry method
+      s.disc().totalvol();
+    \endcode
+
+    Organization, implementation details, end extension of the class:
+
+    Scheme contains (at least) two Charm++ proxies: discproxy and proxy. The
+    former contains data and functionality common to all discretizations, and
+    this can be considered as an equivalent to a base class in the OOP sense.
+    The latter, proxy, contains data and functionality specific to a particular
+    discretization. When instantiated, Scheme is configured for a single
+    specific discretization which must be selected from the list of types in
+    SchemeBase::Proxy.
+
+    The underlying type of proxy is a variant, which allows storing exactly one
+    object. A variant is a type-safe union. An instance of a variant at any
+    given time either holds a value of one of its alternative types. Read more
+    on std::variant on how they work.
+
+    Adding a new child scheme is done by
+    (1) Adding a new type of Charm++ chare array proxy to Scheme::Proxy,
+    (2) Adding a new type of Charm++ chare array element proxy to
+        Scheme::ProxyElem, and
+    (3) Adding a new branch to the if test in Scheme's constructor.
+
+  \see A talk on "Concept-based runtime polymorphism with Charm++ chare arrays
+    using value semantics given by J. Bakosi at the 16th Annual Workshop on
+    Charm++ and its Applications, April 2018, discussing an earlier, more
+    verbose implementation of the idea, using C++11.
+*/
+// *****************************************************************************
+#ifndef Scheme_h
+#define Scheme_h
+
+#include "Exception.hpp"
+#include "PUPUtil.hpp"
+#include "Inciter/Options/Scheme.hpp"
+
+#include "NoWarning/discretization.decl.h"
+#include "NoWarning/alecg.decl.h"
+#include "NoWarning/oversetfe.decl.h"
+#include "NoWarning/dg.decl.h"
+#include "NoWarning/fv.decl.h"
+#include "NoWarning/ale.decl.h"
+#include "NoWarning/conjugategradients.decl.h"
+#include "NoWarning/ghosts.decl.h"
+
+namespace inciter {
+
+//! Base class for generic forwarding interface to discretization proxies
+class Scheme {
+
+  private:
+    //! Variant type listing all chare proxy types modeling the same concept
+    using Proxy = std::variant< CProxy_DG
+                              , CProxy_ALECG
+                              , CProxy_OversetFE
+                              , CProxy_FV >;
+
+  public:
+    //! Variant type listing all chare element proxy types
+    using ProxyElem = std::variant< CProxy_DG::element_t
+                                  , CProxy_ALECG::element_t
+                                  , CProxy_OversetFE::element_t
+                                  , CProxy_FV::element_t >;
+
+    //! Empty constructor for Charm++
+    explicit Scheme() {}
+
+    //! Constructor
+    //! \param[in] scheme Discretization scheme
+    //! \param[in] ale True if enable ALE
+    //! \param[in] linearsolver True if enable a linear solver
+    //! \details Based on the input enum we create at least two empty chare
+    //!   arrays: (1) discproxy which contains common functionality and data for
+    //!   all discretizations, and (2) proxy, which have functionality and data
+    //!   specific to a given discretization. Note that proxy is bound (in
+    //!   migration behavior and properties) to discproxy.
+    //! \note There may be other bound proxy arrays created depending on the
+    //!   specific discretization configured by the enum.
+    explicit Scheme( ctr::SchemeType scheme,
+                     bool ale = false,
+                     bool linearsolver = false,
+                     tk::Centering centering = tk::Centering::NODE ) :
+      discproxy( CProxy_Discretization::ckNew() )
+    {
+      bound.bindTo( discproxy );
+      if (scheme == ctr::SchemeType::DG ||
+                 scheme == ctr::SchemeType::P0P1 ||
+                 scheme == ctr::SchemeType::DGP1 ||
+                 scheme == ctr::SchemeType::DGP2 ||
+                 scheme == ctr::SchemeType::PDG)
+      {
+        proxy = static_cast< CProxy_DG >( CProxy_DG::ckNew(bound) );
+      } else if (scheme == ctr::SchemeType::ALECG) {
+        proxy = static_cast< CProxy_ALECG >( CProxy_ALECG::ckNew(bound) );
+      } else if (scheme == ctr::SchemeType::OversetFE) {
+        proxy = static_cast< CProxy_OversetFE >( CProxy_OversetFE::ckNew(bound) );
+      } else if (scheme == ctr::SchemeType::FV) {
+        proxy = static_cast< CProxy_FV >( CProxy_FV::ckNew(bound) );
+      } else Throw( "Unknown discretization scheme" );
+      if (ale) aleproxy = CProxy_ALE::ckNew(bound);
+      if (linearsolver)
+        conjugategradientsproxy = tk::CProxy_ConjugateGradients::ckNew(bound);
+      if (centering == tk::Centering::ELEM)
+        ghostsproxy = CProxy_Ghosts::ckNew(bound);
+    }
+
+    //! Entry method tags for specific Scheme classes to use with bcast()
+    struct setup {};
+    struct box {};
+    struct transferSol {};
+    struct advance {};
+    struct resized {};
+    struct resizeComm {};
+    struct refine {};
+    struct lhs {};
+    struct nodeNeighSetup {};
+    struct diag {};
+    struct evalLB {};
+    struct doneInserting {};
+    //! Issue broadcast to Scheme entry method
+    //! \tparam Fn Function tag identifying the entry method to call
+    //! \tparam Args Types of arguments to pass to entry method
+    //! \param[in] args Arguments to member function entry method to be called
+    //! \details This function issues a broadcast to a member function entry
+    //!   method of the Scheme chare array (the child of Discretization) and is
+    //!   thus equivalent to proxy.Fn(...).
+    template< typename Fn, typename... Args >
+    void bcast( Args&&... args ) {
+      std::visit( [&]( auto& p ){<--- Parameter 'p' can be declared with const
+          if constexpr( std::is_same_v< Fn, setup > )
+            p.setup( std::forward< Args >( args )... );
+          if constexpr( std::is_same_v< Fn, box > )
+            p.box( std::forward< Args >( args )... );
+          else if constexpr( std::is_same_v< Fn, transferSol > )
+            p.transferSol( std::forward< Args >( args )... );
+          else if constexpr( std::is_same_v< Fn, advance > )
+            p.advance( std::forward< Args >( args )... );
+          else if constexpr( std::is_same_v< Fn, resized > )
+            p.resized( std::forward< Args >( args )... );
+          else if constexpr( std::is_same_v< Fn, resizeComm > )
+            p.resizeComm( std::forward< Args >( args )... );
+          else if constexpr( std::is_same_v< Fn, refine > )
+            p.refine( std::forward< Args >( args )... );
+          else if constexpr( std::is_same_v< Fn, lhs > )
+            p.lhs( std::forward< Args >( args )... );
+          else if constexpr( std::is_same_v< Fn, nodeNeighSetup > )
+            p.nodeNeighSetup( std::forward< Args >( args )... );
+          else if constexpr( std::is_same_v< Fn, diag > )
+            p.diag( std::forward< Args >( args )... );
+          else if constexpr( std::is_same_v< Fn, evalLB > )
+            p.evalLB( std::forward< Args >( args )... );
+          else if constexpr( std::is_same_v< Fn, doneInserting > )
+            p.doneInserting( std::forward< Args >( args )... );
+        }, proxy );
+    }
+
+    //! Function tags for specific Scheme classes to use with ckLocal()
+    struct resizePostAMR {};
+    struct extractFieldOutput {};
+    struct solution {};
+    //! Call Scheme function via Charm++ chare array element's ckLocal()
+    //! \tparam Fn Function tag identifying the function to call
+    //! \tparam Args Types of arguments to pass to function
+    //! \param[in] x Chare array element index
+    //! \param[in] args Arguments to member function function to be called
+    //! \details This function calls a member function via Charm++'s ckLocal()
+    //!    behind the element proxy configured, indexed by the array index x.
+    //!    Since the call is behind ckLocal(), the member function does not have
+    //!    to be a Charm++ entry method.
+    template< typename Fn, typename... Args >
+    auto ckLocal( const CkArrayIndex1D& x, Args&&... args ) const {
+      auto e = element( x );
+      return std::visit( [&]( auto& p ){
+          if constexpr( std::is_same_v< Fn, resizePostAMR > )
+            return p.ckLocal()->resizePostAMR( std::forward<Args>(args)... );
+          else if constexpr( std::is_same_v< Fn, extractFieldOutput > )
+            return p.ckLocal()->extractFieldOutput(std::forward<Args>(args)...);
+          else if constexpr( std::is_same_v< Fn, solution > )
+            return p.ckLocal()->solution( std::forward<Args>(args)... );
+        }, e );
+    }
+
+    //! Function to call the insert entry method of an element proxy
+    //! \param[in] x Chare array element index
+    //! \param[in] args Arguments to member function (entry method) to be called
+    //! \details This function calls the insert member function of a chare array
+    //!   element proxy and thus equivalent to proxy[x].insert(...), using the
+    //!   last argument as default.
+    template< typename... Args >
+    void insert( const CkArrayIndex1D& x, Args&&... args ) {
+      auto e = element( x );
+      std::visit( [&]( auto& p ){ p.insert(std::forward<Args>(args)...); }, e );<--- Parameter 'p' can be declared with const
+    }
+
+    //! Get reference to discretization proxy
+    //! \return Discretization Charm++ chare array proxy
+    CProxy_Discretization& disc() noexcept { return discproxy; }
+
+    //! Get reference to ALE proxy
+    //! \return ALE Charm++ chare array proxy
+    CProxy_ALE& ale() noexcept { return aleproxy; }
+
+    //! Get reference to ConjugateGradients proxy
+    //! \return ConjugateGradients Charm++ chare array proxy
+    tk::CProxy_ConjugateGradients& conjugategradients() noexcept
+    { return conjugategradientsproxy; }
+
+    //! Get reference to Ghosts proxy
+    //! \return Ghosts Charm++ chare array proxy
+    CProxy_Ghosts& ghosts() noexcept { return ghostsproxy; }
+
+    //! Get reference to scheme proxy
+    //! Get reference to scheme proxy
+    //! \return Variant storing Charm++ chare array proxy configured
+    const Proxy& getProxy() noexcept { return proxy; }
+
+    //! Query underlying proxy type
+    //! \return Zero-based index into the set of types of Proxy
+    std::size_t index() const noexcept { return proxy.index(); }
 
-void
-Discretization::meshvelConv()
-// *****************************************************************************
-//! Assess and record mesh velocity linear solver convergence
-// *****************************************************************************
-{
-  auto smoother = g_inputdeck.get< tag::ale, tag::smoother >();
-
-  if (g_inputdeck.get< tag::ale, tag::ale >() &&
-      (smoother == ctr::MeshVelocitySmootherType::LAPLACE or
-       smoother == ctr::MeshVelocitySmootherType::HELMHOLTZ))
-  {
-    m_meshvel_converged &= m_ale[ thisIndex ].ckLocal()->converged();
-  }
-}
-
-void
-Discretization::comfinal()
-// *****************************************************************************
-// Finish setting up communication maps and solution transfer callbacks
-// *****************************************************************************
-{
-  // Generate own subset of solver/mesh transfer list
-  for (const auto& t : m_transfer) {
-    if (t.src == m_meshid || t.dst == m_meshid) {
-      m_mytransfer.push_back( t );<--- Consider using std::copy_if algorithm instead of a raw loop.
-    }
-  }
-
-  // Signal the runtime system that the workers have been created
-  std::vector< std::size_t > meshdata{ /* initial = */ 1, m_meshid };
-  contribute( meshdata, CkReduction::sum_ulong,
-    CkCallback(CkReductionTarget(Transporter,comfinal), m_transporter) );
-}
-
-void
-Discretization::transfer(
-  tk::Fields& u,
-  std::size_t dirn,
-  CkCallback cb )
-// *****************************************************************************
-//  Start solution transfer (if coupled)
-//! \param[in,out] u Solution to transfer from/to
-//! \param[in] dirn Direction of solution transfer. 0: from background to
-//!   overset, 1: from overset to background
-//! \param[in] cb Callback to call when back and forth transfers complete.
-//! \details This function initiates the solution transfer (direction dependent
-//!   on 'dirn') between meshes. It invokes a reduction to Transporter when the
-//!   transfer in one direction is complete (dirn == 0), or calls back the
-//!   'cb' function in Scheme when transfers both directions are complete.
-//!   The function relies on 'dirn' to make this decision.
-// *****************************************************************************
-{
-  if (m_mytransfer.empty()) {   // skip transfer if not involved in coupling
-
-    cb.send();
-
-  } else {
-
-    m_transfer_complete = cb;
-
-    // determine source and destination mesh depending on direction of transfer
-    std::size_t fromMesh(0), toMesh(0);
-    CkCallback cb_xfer;
-    if (dirn == 0) {
-      fromMesh = m_mytransfer[m_nsrc].src;<--- Variable 'fromMesh' is assigned a value that is never used.
-      toMesh = m_mytransfer[m_ndst].dst;<--- Variable 'toMesh' is assigned a value that is never used.
-      cb_xfer = CkCallback( CkIndex_Discretization::to_complete(), thisProxy[thisIndex] );<--- Variable 'cb_xfer' is assigned a value that is never used.
-    }
-    else {
-      fromMesh = m_mytransfer[m_nsrc].dst;<--- Variable 'fromMesh' is assigned a value that is never used.
-      toMesh = m_mytransfer[m_ndst].src;<--- Variable 'toMesh' is assigned a value that is never used.
-      cb_xfer = CkCallback( CkIndex_Discretization::from_complete(), thisProxy[thisIndex] );<--- Variable 'cb_xfer' is assigned a value that is never used.
-    }
-
-    // Pass source and destination meshes to mesh transfer lib (if coupled)
-    Assert( m_nsrc < m_mytransfer.size(), "Indexing out of mytransfer[src]" );
-    if (fromMesh == m_meshid) {
-      exam2m::setSourceTets( thisProxy, thisIndex, &m_inpoel, &m_coord, u );
-      ++m_nsrc;
-    } else {
-      m_nsrc = 0;
-    }
-    Assert( m_ndst < m_mytransfer.size(), "Indexing out of mytransfer[dst]" );
-    if (toMesh == m_meshid) {
-      exam2m::setDestPoints( thisProxy, thisIndex, &m_coord, u,
-        cb_xfer );
-      ++m_ndst;<--- m_ndst is assigned
-    } else {
-      m_ndst = 0;
-    }
-
-  }
-
-  m_nsrc = 0;
-  m_ndst = 0;<--- m_ndst is overwritten
-}
-
-void Discretization::to_complete()
-// *****************************************************************************
-//! Solution transfer from background to overset mesh completed (from ExaM2M)
-//! \brief This is called by ExaM2M on the destination mesh when the
-//!   transfer completes. Since this is called only on the destination, we find
-//!   and notify the corresponding source of the completion.
-// *****************************************************************************
-{
-  // Lookup the source disc and notify it of completion
-  for (auto& t : m_transfer) {
-    if (m_meshid == t.dst) {
-      m_disc[ t.src ][ thisIndex ].transfer_complete();
-    }
-  }
-
-  thisProxy[ thisIndex ].transfer_complete();
-}
-
-void Discretization::from_complete()
-// *****************************************************************************
-//! Solution transfer from overset to background mesh completed (from ExaM2M)
-//! \brief This is called by ExaM2M on the destination mesh when the
-//!   transfer completes. Since this is called only on the destination, we find
-//!   and notify the corresponding source of the completion.
-// *****************************************************************************
-{
-  // Lookup the source disc and notify it of completion
-  for (auto& t : m_transfer) {
-    if (m_meshid == t.src) {
-      m_disc[ t.dst ][ thisIndex ].transfer_complete_from_dest();
-    }
-  }
-
-  m_transfer_complete.send();
-}
-
-void Discretization::transfer_complete_from_dest()
-// *****************************************************************************
-//! Solution transfer completed (from dest Discretization)
-//! \details Called on the source only by the destination when a back and forth
-//!   transfer step completes.
-// *****************************************************************************
-{
-  m_transfer_complete.send();
-}
-
-void Discretization::transfer_complete()
-// *****************************************************************************
-//! Solution transfer completed (one-way)
-//! \note Single exit point after solution transfer between meshes
-// *****************************************************************************
-{
-  contribute( sizeof(nullptr), nullptr, CkReduction::nop,
-    CkCallback(CkReductionTarget(Transporter,solutionTransferred),
-    m_transporter) );
-}
-
-std::vector< std::size_t >
-Discretization::bndel() const
-// *****************************************************************************
-// Find elements along our mesh chunk boundary
-//! \return List of local element ids that have at least a single node
-//!   contributing to a chare boundary
-// *****************************************************************************
-{
-  // Lambda to find out if a mesh node is shared with another chare
-  auto shared = [this]( std::size_t i ){
-    for (const auto& [c,n] : m_nodeCommMap)
-      if (n.find(i) != end(n)) return true;
-    return false;
-  };
-
-  // Find elements along our mesh chunk boundary
-  std::vector< std::size_t > e;
-  for (std::size_t n=0; n<m_inpoel.size(); ++n)
-    if (shared( m_gid[ m_inpoel[n] ] )) e.push_back( n/4 );
-  tk::unique( e );
-
-  return e;
-}
-
-void
-Discretization::resizePostAMR(
-  const tk::UnsMesh::Chunk& chunk,
-  const tk::UnsMesh::Coords& coord,
-  const std::unordered_map< std::size_t, std::size_t >& /*amrNodeMap*/,
-  const tk::NodeCommMap& nodeCommMap,
-  const std::set< std::size_t >& /*removedNodes*/,
-  const std::unordered_map< std::size_t, std::set< std::size_t > >& elemblockid )
-// *****************************************************************************
-//  Resize mesh data structures after mesh refinement
-//! \param[in] chunk New mesh chunk (connectivity and global<->local id maps)
-//! \param[in] coord New mesh node coordinates
-//! \param[in] amrNodeMap Node id map after amr (local ids)
-//! \param[in] nodeCommMap New node communication map
-//! \param[in] removedNodes Newly removed mesh node local ids
-//! \param[in] elemblockid New local tet ids associated with mesh block ids
-// *****************************************************************************
-{
-  m_el = chunk;         // updates m_inpoel, m_gid, m_lid
-  m_nodeCommMap.clear();
-  m_nodeCommMap = nodeCommMap;        // update node communication map
-  m_elemblockid.clear();
-  m_elemblockid = elemblockid;
-
-  // Update mesh volume container size
-  m_vol.resize( m_gid.size(), 0.0 );
-  if (!m_voln.empty()) m_voln.resize( m_gid.size(), 0.0 );
-
-  // Regenerate bid data
-  tk::destroy(m_bid);
-  m_bid = genBid();
-
-  // update mesh node coordinates
-  m_coord = coord;
-
-  // we are no longer during setup
-  m_initial = 0;
-}
-
-void
-Discretization::startvol()
-// *****************************************************************************
-//  Get ready for (re-)computing/communicating nodal volumes
-// *****************************************************************************
-{
-  m_nvol = 0;
-  thisProxy[ thisIndex ].wait4vol();
-
-  // Zero out mesh volume container
-  std::fill( begin(m_vol), end(m_vol), 0.0 );
-
-  // Clear receive buffer that will be used for collecting nodal volumes
-  m_volc.clear();
-}
-
-void
-Discretization::registerReducers()
-// *****************************************************************************
-//  Configure Charm++ reduction types
-//!  \details Since this is a [initnode] routine, see the .ci file, the
-//!   Charm++ runtime system executes the routine exactly once on every
-//!   logical node early on in the Charm++ init sequence. Must be static as
-//!   it is called without an object. See also: Section "Initializations at
-//!   Program Startup" at in the Charm++ manual
-//!   http://charm.cs.illinois.edu/manuals/html/charm++/manual.html.
-// *****************************************************************************
-{
-  PDFMerger = CkReduction::addReducer( tk::mergeUniPDFs );
-}
-
-tk::UnsMesh::Coords
-Discretization::setCoord( const tk::UnsMesh::CoordMap& coordmap )
-// *****************************************************************************
-// Set mesh coordinates based on coordinates map
-// *****************************************************************************
-{
-  Assert( coordmap.size() == m_gid.size(), "Size mismatch" );
-  Assert( coordmap.size() == m_lid.size(), "Size mismatch" );
-
-  tk::UnsMesh::Coords coord;
-  coord[0].resize( coordmap.size() );
-  coord[1].resize( coordmap.size() );
-  coord[2].resize( coordmap.size() );
-
-  for (const auto& [ gid, coords ] : coordmap) {
-    auto i = tk::cref_find( m_lid, gid );
-    coord[0][i] = coords[0];
-    coord[1][i] = coords[1];
-    coord[2][i] = coords[2];
-  }
-
-  return coord;
-}
-
-void
-Discretization::remap(
-  const std::unordered_map< std::size_t, std::size_t >& map )
-// *****************************************************************************
-//  Remap mesh data based on new local ids
-//! \param[in] map Mapping of old->new local ids
-// *****************************************************************************
-{
-  // Remap connectivity containing local IDs
-  for (auto& l : m_inpoel) l = tk::cref_find(map,l);
-
-  // Remap global->local id map
-  for (auto& [g,l] : m_lid) l = tk::cref_find(map,l);
-
-  // Remap global->local id map
-  auto maxid = std::numeric_limits< std::size_t >::max();
-  std::vector< std::size_t > newgid( m_gid.size(), maxid );
-  for (const auto& [o,n] : map) newgid[n] = m_gid[o];
-  m_gid = std::move( newgid );
-
-  Assert( std::all_of( m_gid.cbegin(), m_gid.cend(),
-            [=](std::size_t i){ return i < maxid; } ),
-          "Not all gid have been remapped" );
-
-  // Remap nodal volumes (with contributions along chare-boundaries)
-  std::vector< tk::real > newvol( m_vol.size(), 0.0 );
-  for (const auto& [o,n] : map) newvol[n] = m_vol[o];
-  m_vol = std::move( newvol );
-
-  // Remap nodal volumes (without contributions along chare-boundaries)
-  std::vector< tk::real > newv( m_v.size(), 0.0 );
-  for (const auto& [o,n] : map) newv[n] = m_v[o];
-  m_v = std::move( newv );
-
-  // Remap locations of node coordinates
-  tk::UnsMesh::Coords newcoord;
-  auto npoin = m_coord[0].size();
-  newcoord[0].resize( npoin );
-  newcoord[1].resize( npoin );
-  newcoord[2].resize( npoin );
-  for (const auto& [o,n] : map) {
-    newcoord[0][n] = m_coord[0][o];
-    newcoord[1][n] = m_coord[1][o];
-    newcoord[2][n] = m_coord[2][o];
-  }
-  m_coord = std::move( newcoord );
-}
-
-void
-Discretization::setRefiner( const CProxy_Refiner& ref )
-// *****************************************************************************
-//  Set Refiner Charm++ proxy
-//! \param[in] ref Incoming refiner proxy to store
-// *****************************************************************************
-{
-  m_refiner = ref;
-}
-
-void
-Discretization::vol()
-// *****************************************************************************
-// Sum mesh volumes to nodes, start communicating them on chare-boundaries
-// *****************************************************************************
-{
-  const auto& x = m_coord[0];
-  const auto& y = m_coord[1];
-  const auto& z = m_coord[2];
-
-  // Compute nodal volumes on our chunk of the mesh
-  for (std::size_t e=0; e<m_inpoel.size()/4; ++e) {
-    const std::array< std::size_t, 4 > N{{ m_inpoel[e*4+0], m_inpoel[e*4+1],
-                                           m_inpoel[e*4+2], m_inpoel[e*4+3] }};
-    // compute element Jacobi determinant * 5/120 = element volume / 4
-    const std::array< tk::real, 3 >
-      ba{{ x[N[1]]-x[N[0]], y[N[1]]-y[N[0]], z[N[1]]-z[N[0]] }},
-      ca{{ x[N[2]]-x[N[0]], y[N[2]]-y[N[0]], z[N[2]]-z[N[0]] }},
-      da{{ x[N[3]]-x[N[0]], y[N[3]]-y[N[0]], z[N[3]]-z[N[0]] }};
-    const auto J = tk::triple( ba, ca, da ) * 5.0 / 120.0;
-    ErrChk( J > 0, "Element Jacobian non-positive: PE:" +
-                   std::to_string(CkMyPe()) + ", node IDs: " +
-                   std::to_string(m_gid[N[0]]) + ',' +
-                   std::to_string(m_gid[N[1]]) + ',' +
-                   std::to_string(m_gid[N[2]]) + ',' +
-                   std::to_string(m_gid[N[3]]) + ", coords: (" +
-                   std::to_string(x[N[0]]) + ", " +
-                   std::to_string(y[N[0]]) + ", " +
-                   std::to_string(z[N[0]]) + "), (" +
-                   std::to_string(x[N[1]]) + ", " +
-                   std::to_string(y[N[1]]) + ", " +
-                   std::to_string(z[N[1]]) + "), (" +
-                   std::to_string(x[N[2]]) + ", " +
-                   std::to_string(y[N[2]]) + ", " +
-                   std::to_string(z[N[2]]) + "), (" +
-                   std::to_string(x[N[3]]) + ", " +
-                   std::to_string(y[N[3]]) + ", " +
-                   std::to_string(z[N[3]]) + ')' );
-    // scatter add V/4 to nodes
-    for (std::size_t j=0; j<4; ++j) m_vol[N[j]] += J;
-
-    // save element volumes at t=t0
-    if (m_it == 0) m_vol0[e] = J * 4.0;
-  }
-
-  // Store nodal volumes without contributions from other chares on
-  // chare-boundaries
-  m_v = m_vol;
-
-  // Send our nodal volume contributions to neighbor chares
-  if (m_nodeCommMap.empty())
-   totalvol();
-  else
-    for (const auto& [c,n] : m_nodeCommMap) {
-      std::vector< tk::real > v( n.size() );
-      std::size_t j = 0;
-      for (auto i : n) v[ j++ ] = m_vol[ tk::cref_find(m_lid,i) ];
-      thisProxy[c].comvol( std::vector<std::size_t>(begin(n), end(n)), v );
-    }
-
-  ownvol_complete();
-}
-
-void
-Discretization::comvol( const std::vector< std::size_t >& gid,
-                        const std::vector< tk::real >& nodevol )
-// *****************************************************************************
-//  Receive nodal volumes on chare-boundaries
-//! \param[in] gid Global mesh node IDs at which we receive volume contributions
-//! \param[in] nodevol Partial sums of nodal volume contributions to
-//!    chare-boundary nodes
-//! \details This function receives contributions to m_vol, which stores the
-//!   nodal volumes. While m_vol stores own contributions, m_volc collects the
-//!   neighbor chare contributions during communication. This way work on m_vol
-//!   and m_volc is overlapped. The contributions are applied in totalvol().
-// *****************************************************************************
-{
-  Assert( nodevol.size() == gid.size(), "Size mismatch" );
-
-  for (std::size_t i=0; i<gid.size(); ++i)
-    m_volc[ gid[i] ] += nodevol[i];
-
-  if (++m_nvol == m_nodeCommMap.size()) {
-    m_nvol = 0;
-    comvol_complete();
-  }
-}
-
-void
-Discretization::totalvol()
-// *****************************************************************************
-// Sum mesh volumes and contribute own mesh volume to total volume
-// *****************************************************************************
-{
-  // Add received contributions to nodal volumes
-  for (const auto& [gid, vol] : m_volc)
-    m_vol[ tk::cref_find(m_lid,gid) ] += vol;
-
-  // Clear receive buffer
-  tk::destroy(m_volc);
-
-  // Sum mesh volume to host
-  std::vector< tk::real > tvol{ 0.0,
-                                static_cast<tk::real>(m_initial),
-                                static_cast<tk::real>(m_meshid) };
-  for (auto v : m_v) tvol[0] += v;
-  contribute( tvol, CkReduction::sum_double,
-    CkCallback(CkReductionTarget(Transporter,totalvol), m_transporter) );
-}
-
-void
-Discretization::stat( tk::real mesh_volume )
-// *****************************************************************************
-// Compute mesh cell statistics
-//! \param[in] mesh_volume Total mesh volume
-// *****************************************************************************
-{
-  // Store total mesh volume
-  m_meshvol = mesh_volume;
-
-  const auto& x = m_coord[0];
-  const auto& y = m_coord[1];
-  const auto& z = m_coord[2];
-
-  auto MIN = -std::numeric_limits< tk::real >::max();
-  auto MAX = std::numeric_limits< tk::real >::max();
-  std::vector< tk::real > min{ MAX, MAX, MAX };
-  std::vector< tk::real > max{ MIN, MIN, MIN };
-  std::vector< tk::real > sum{ 0.0, 0.0, 0.0, 0.0, 0.0, 0.0 };
-  tk::UniPDF edgePDF( 1e-4 );
-  tk::UniPDF volPDF( 1e-4 );
-  tk::UniPDF ntetPDF( 1e-4 );
-
-  // Compute points surrounding points
-  auto psup = tk::genPsup( m_inpoel, 4, tk::genEsup(m_inpoel,4) );
-  Assert( psup.second.size()-1 == m_gid.size(),
-          "Number of mesh points and number of global IDs unequal" );
-
-  // Compute edge length statistics
-  // Note that while the min and max edge lengths are independent of the number
-  // of CPUs (by the time they are aggregated across all chares), the sum of
-  // the edge lengths and the edge length PDF are not. This is because the
-  // edges on the chare-boundary are counted multiple times and we
-  // conscientiously do not make an effort to precisely compute this, because
-  // that would require communication and more complex logic. Since these
-  // statistics are intended as simple average diagnostics, we ignore these
-  // small differences. For reproducible average edge lengths and edge length
-  // PDFs, run the mesh in serial.
-  for (std::size_t p=0; p<m_gid.size(); ++p)
-    for (auto i : tk::Around(psup,p)) {
-       const auto dx = x[ i ] - x[ p ];
-       const auto dy = y[ i ] - y[ p ];
-       const auto dz = z[ i ] - z[ p ];
-       const auto length = std::sqrt( dx*dx + dy*dy + dz*dz );
-       if (length < min[0]) min[0] = length;
-       if (length > max[0]) max[0] = length;
-       sum[0] += 1.0;
-       sum[1] += length;
-       edgePDF.add( length );
-    }
-
-  // Compute mesh cell volume statistics
-  for (std::size_t e=0; e<m_inpoel.size()/4; ++e) {
-    const std::array< std::size_t, 4 > N{{ m_inpoel[e*4+0], m_inpoel[e*4+1],
-                                           m_inpoel[e*4+2], m_inpoel[e*4+3] }};
-    const std::array< tk::real, 3 >
-      ba{{ x[N[1]]-x[N[0]], y[N[1]]-y[N[0]], z[N[1]]-z[N[0]] }},
-      ca{{ x[N[2]]-x[N[0]], y[N[2]]-y[N[0]], z[N[2]]-z[N[0]] }},
-      da{{ x[N[3]]-x[N[0]], y[N[3]]-y[N[0]], z[N[3]]-z[N[0]] }};
-    const auto L = std::cbrt( tk::triple( ba, ca, da ) / 6.0 );
-    if (L < min[1]) min[1] = L;
-    if (L > max[1]) max[1] = L;
-    sum[2] += 1.0;
-    sum[3] += L;
-    volPDF.add( L );
-  }
-
-  // Contribute stats of number of tetrahedra (ntets)
-  sum[4] = 1.0;
-  min[2] = max[2] = sum[5] = static_cast< tk::real >( m_inpoel.size() / 4 );
-  ntetPDF.add( min[2] );
-
-  min.push_back( static_cast<tk::real>(m_meshid) );
-  max.push_back( static_cast<tk::real>(m_meshid) );
-  sum.push_back( static_cast<tk::real>(m_meshid) );
-
-  // Contribute to mesh statistics across all Discretization chares
-  contribute( min, CkReduction::min_double,
-    CkCallback(CkReductionTarget(Transporter,minstat), m_transporter) );
-  contribute( max, CkReduction::max_double,
-    CkCallback(CkReductionTarget(Transporter,maxstat), m_transporter) );
-  contribute( sum, CkReduction::sum_double,
-    CkCallback(CkReductionTarget(Transporter,sumstat), m_transporter) );
-
-  // Serialize PDFs to raw stream
-  auto stream = tk::serialize( m_meshid, { edgePDF, volPDF, ntetPDF } );
-  // Create Charm++ callback function for reduction of PDFs with
-  // Transporter::pdfstat() as the final target where the results will appear.
-  CkCallback cb( CkIndex_Transporter::pdfstat(nullptr), m_transporter );
-  // Contribute serialized PDF of partial sums to host via Charm++ reduction
-  contribute( stream.first, stream.second.get(), PDFMerger, cb );
-}
-
-void
-Discretization::boxvol(
-  const std::vector< std::unordered_set< std::size_t > >& nodes,
-  const std::unordered_map< std::size_t, std::set< std::size_t > >& nodeblk,
-  std::size_t nuserblk )
-// *****************************************************************************
-// Compute total box IC volume
-//! \param[in] nodes Node list contributing to box IC volume (for each IC box)
-//! \param[in] nodeblk Node list associated to mesh blocks contributing to block
-//!   volumes (for each IC box)
-//! \param[in] nuserblk Number of user IC mesh blocks
-// *****************************************************************************
-{
-  // Compute partial box IC volume (just add up all boxes)
-  tk::real boxvol = 0.0;
-  for (const auto& b : nodes) for (auto i : b) boxvol += m_v[i];<--- Consider using std::accumulate algorithm instead of a raw loop.
-
-  // Compute partial IC mesh block volume
-  std::vector< tk::real > blockvols;
-  if (nuserblk > 0) {
-    blockvols.resize(nuserblk,0.0);
-    for (const auto& [blid, ndset] : nodeblk) {
-      // The following if-test makes sure we access volumes only of mesh blocks
-      // with user-specified ICs
-      if (blid < nuserblk) {
-        for (const auto& n : ndset) blockvols[blid] += m_v[n];
-      }
-    }
-  }
-
-  // Sum up box IC volume across all chares
-  auto meshdata = blockvols;
-  meshdata.push_back(boxvol);
-  meshdata.push_back(static_cast<tk::real>(m_meshid));
-  contribute( meshdata, CkReduction::sum_double,
-    CkCallback(CkReductionTarget(Transporter,boxvol), m_transporter) );
-}
-
-void
-Discretization::write(
-  const std::vector< std::size_t >& inpoel,
-  const tk::UnsMesh::Coords& coord,
-  const std::map< int, std::vector< std::size_t > >& bface,
-  const std::map< int, std::vector< std::size_t > >& bnode,
-  const std::vector< std::size_t >& triinpoel,
-  const std::vector< std::string>& elemfieldnames,
-  const std::vector< std::string>& nodefieldnames,
-  const std::vector< std::string>& elemsurfnames,
-  const std::vector< std::string>& nodesurfnames,
-  const std::vector< std::vector< tk::real > >& elemfields,
-  const std::vector< std::vector< tk::real > >& nodefields,
-  const std::vector< std::vector< tk::real > >& elemsurfs,
-  const std::vector< std::vector< tk::real > >& nodesurfs,
-  CkCallback c )
-// *****************************************************************************
-//  Output mesh and fields data (solution dump) to file(s)
-//! \param[in] inpoel Mesh connectivity for the mesh chunk to be written
-//! \param[in] coord Node coordinates of the mesh chunk to be written
-//! \param[in] bface Map of boundary-face lists mapped to corresponding side set
-//!   ids for this mesh chunk
-//! \param[in] bnode Map of boundary-node lists mapped to corresponding side set
-//!   ids for this mesh chunk
-//! \param[in] triinpoel Interconnectivity of points and boundary-face in this
-//!   mesh chunk
-//! \param[in] elemfieldnames Names of element fields to be output to file
-//! \param[in] nodefieldnames Names of node fields to be output to file
-//! \param[in] elemsurfnames Names of elemental surface fields to be output to
-//!   file
-//! \param[in] nodesurfnames Names of node surface fields to be output to file
-//! \param[in] elemfields Field data in mesh elements to output to file
-//! \param[in] nodefields Field data in mesh nodes to output to file
-//! \param[in] elemsurfs Surface field data in mesh elements to output to file
-//! \param[in] nodesurfs Surface field data in mesh nodes to output to file
-//! \param[in] c Function to continue with after the write
-//! \details Since m_meshwriter is a Charm++ chare group, it never migrates and
-//!   an instance is guaranteed on every PE. We index the first PE on every
-//!   logical compute node. In Charm++'s non-SMP mode, a node is the same as a
-//!   PE, so the index is the same as CkMyPe(). In SMP mode the index is the
-//!   first PE on every logical node. In non-SMP mode this yields one or more
-//!   output files per PE with zero or non-zero virtualization, respectively. If
-//!   there are multiple chares on a PE, the writes are serialized per PE, since
-//!   only a single entry method call can be executed at any given time. In SMP
-//!   mode, still the same number of files are output (one per chare), but the
-//!   output is serialized through the first PE of each compute node. In SMP
-//!   mode, channeling multiple files via a single PE on each node is required
-//!   by NetCDF and HDF5, as well as ExodusII, since none of these libraries are
-//!   thread-safe.
-// *****************************************************************************
-{
-  // If the previous iteration refined (or moved) the mesh or this is called
-  // before the first time step, we also output the mesh.
-  bool meshoutput = m_itf == 0 ? true : false;
-
-  auto eps = std::numeric_limits< tk::real >::epsilon();
-  bool fieldoutput = false;
-
-  // Output field data only if there is no dump at this physical time yet
-  if (std::abs(m_lastDumpTime - m_t) > eps ) {
-    m_lastDumpTime = m_t;
-    ++m_itf;
-    fieldoutput = true;
-  }
-
-  // set of sidesets where fieldoutput is required
-  std::set< int > outsets;
-  const auto& osv = g_inputdeck.get< tag::field_output, tag::sideset >();
-  outsets.insert(osv.begin(), osv.end());
-
-  m_meshwriter[ CkNodeFirst( CkMyNode() ) ].
-    write( m_meshid, meshoutput, fieldoutput, m_itr, m_itf, m_t, thisIndex,
-           g_inputdeck.get< tag::cmd, tag::io, tag::output >(),
-           inpoel, coord, bface, bnode, triinpoel, elemfieldnames,
-           nodefieldnames, elemsurfnames, nodesurfnames, elemfields, nodefields,
-           elemsurfs, nodesurfs, outsets, c );
-}
-
-void
-Discretization::setdt( tk::real newdt )
-// *****************************************************************************
-// Set time step size
-//! \param[in] newdt Size of the new time step
-// *****************************************************************************
-{
-  m_dtn = m_dt;
-  m_dt = newdt;
-
-  // Truncate the size of last time step
-  const auto term = g_inputdeck.get< tag::term >();
-  if (m_t+m_dt > term) m_dt = term - m_t;
-}
-
-void
-Discretization::next()
-// *****************************************************************************
-// Prepare for next step
-// *****************************************************************************
-{
-  // Update floor of physics time divided by output interval times
-  const auto eps = std::numeric_limits< tk::real >::epsilon();
-  const auto ft = g_inputdeck.get< tag::field_output, tag::time_interval >();
-  if (ft > eps) m_physFieldFloor = std::floor( m_t / ft );
-  const auto ht = g_inputdeck.get< tag::history_output, tag::time_interval >();
-  if (ht > eps) m_physHistFloor = std::floor( m_t / ht );
-
-  // Update floors of physics time divided by output interval times for ranges
-  const auto& rf = g_inputdeck.get< tag::field_output, tag::time_range >();
-  if (!rf.empty()) {
-    if (m_t > rf[0] and m_t < rf[1])
-      m_rangeFieldFloor = std::floor( m_t / rf[2] );
-    const auto& rh = g_inputdeck.get< tag::history_output, tag::time_range >();
-    if (m_t > rh[0] and m_t < rh[1])
-      m_rangeHistFloor = std::floor( m_t / rh[2] );
-  }
-
-  ++m_it;
-  m_t += m_dt;
-}
-
-void
-Discretization::grindZero()
-// *****************************************************************************
-//  Zero grind-time
-// *****************************************************************************
-{
-  m_prevstatus = std::chrono::high_resolution_clock::now();
-
-  if (thisIndex == 0 && m_meshid == 0) {
-    const auto verbose = g_inputdeck.get< tag::cmd, tag::verbose >();
-    const auto& def =
-      g_inputdeck_defaults.get< tag::cmd, tag::io, tag::screen >();
-    tk::Print print( g_inputdeck.get< tag::cmd >().logname( def, m_nrestart ),
-                     verbose ? std::cout : std::clog,
-                     std::ios_base::app );
-    print.diag( "Starting time stepping ..." );
-  }
-}
-
-bool
-Discretization::restarted( int nrestart )
-// *****************************************************************************
-//  Detect if just returned from a checkpoint and if so, zero timers
-//! \param[in] nrestart Number of times restarted
-//! \return True if restart detected
-// *****************************************************************************
-{
-  // Detect if just restarted from checkpoint:
-  //   nrestart == -1 if there was no checkpoint this step
-  //   d->Nrestart() == nrestart if there was a checkpoint this step
-  //   if both false, just restarted from a checkpoint
-  bool restarted = nrestart != -1 and m_nrestart != nrestart;
-
-   // If just restarted from checkpoint
-  if (restarted) {
-    // Update number of restarts
-    m_nrestart = nrestart;
-    // Start timer measuring time stepping wall clock time
-    m_timer.zero();
-    // Zero grind-timer
-    grindZero();
-  }
-
-  return restarted;
-}
-
-std::string
-Discretization::histfilename( const std::string& id,
-                              std::streamsize precision )
-// *****************************************************************************
-//  Construct history output filename
-//! \param[in] id History point id
-//! \param[in] precision Floating point precision to use for output
-//! \return History file name
-// *****************************************************************************
-{
-  auto of = g_inputdeck.get< tag::cmd, tag::io, tag::output >();
-  std::stringstream ss;
-
-  auto mid =
-    m_disc.size() > 1 ? std::string( '.' + std::to_string(m_meshid) ) : "";
-  ss << std::setprecision(static_cast<int>(precision)) << of << mid << ".hist." << id;
-
-  return ss.str();
-}
-
-void
-Discretization::histheader( std::vector< std::string >&& names )
-// *****************************************************************************
-//  Output headers for time history files (one for each point)
-//! \param[in] names History output variable names
-// *****************************************************************************
-{
-  for (const auto& h : m_histdata) {
-    auto prec = g_inputdeck.get< tag::history_output, tag::precision >();
-    tk::DiagWriter hw( histfilename( h.get< tag::id >(), prec ),
-                       g_inputdeck.get< tag::history_output, tag::format >(),
-                       prec );
-    hw.header( names );
-  }
-}
-
-void
-Discretization::history( std::vector< std::vector< tk::real > >&& data )
-// *****************************************************************************
-//  Output time history for a time step
-//! \param[in] data Time history data for all variables and equations integrated
-// *****************************************************************************
-{
-  Assert( data.size() == m_histdata.size(), "Size mismatch" );
-
-  std::size_t i = 0;
-  for (const auto& h : m_histdata) {
-    auto prec = g_inputdeck.get< tag::history_output, tag::precision >();
-    tk::DiagWriter hw( histfilename( h.get< tag::id >(), prec ),
-                       g_inputdeck.get< tag::history_output, tag::format >(),
-                       prec,
-                       std::ios_base::app );
-    hw.diag( m_it, m_t, m_dt, data[i] );
-    ++i;
-  }
-}
-
-bool
-Discretization::fielditer() const
-// *****************************************************************************
-//  Decide if field output iteration count interval is hit
-//! \return True if field output iteration count interval is hit
-// *****************************************************************************
-{
-  if (g_inputdeck.get< tag::cmd, tag::benchmark >()) return false;
-
-  return m_it % g_inputdeck.get< tag::field_output, tag::interval >() == 0;
-}
-
-bool
-Discretization::fieldtime() const
-// *****************************************************************************
-//  Decide if field output physics time interval is hit
-//! \return True if field output physics time interval is hit
-// *****************************************************************************
-{
-  if (g_inputdeck.get< tag::cmd, tag::benchmark >()) return false;
-
-  const auto eps = std::numeric_limits< tk::real >::epsilon();
-  const auto ft = g_inputdeck.get< tag::field_output, tag::time_interval >();
-
-  if (ft < eps) return false;
-
-  return std::floor(m_t/ft) - m_physFieldFloor > eps;
-}
-
-bool
-Discretization::fieldrange() const
-// *****************************************************************************
-//  Decide if physics time falls into a field output time range
-//! \return True if physics time falls into a field output time range
-// *****************************************************************************
-{
-  if (g_inputdeck.get< tag::cmd, tag::benchmark >()) return false;
-
-  const auto eps = std::numeric_limits< tk::real >::epsilon();
-
-  bool output = false;
-
-  const auto& rf = g_inputdeck.get< tag::field_output, tag::time_range >();
-  if (!rf.empty()) {
-    if (m_t > rf[0] and m_t < rf[1])
-      output |= std::floor(m_t/rf[2]) - m_rangeFieldFloor > eps;
-  }
-
-  return output;
-}
-
-bool
-Discretization::histiter() const
-// *****************************************************************************
-//  Decide if history output iteration count interval is hit
-//! \return True if history output iteration count interval is hit
-// *****************************************************************************
-{
-  const auto hist = g_inputdeck.get< tag::history_output, tag::interval >();
-  const auto& hist_points = g_inputdeck.get< tag::history_output, tag::point >();
-
-  return m_it % hist == 0 and not hist_points.empty();
-}
-
-bool
-Discretization::histtime() const
-// *****************************************************************************
-//  Decide if history output physics time interval is hit
-//! \return True if history output physics time interval is hit
-// *****************************************************************************
-{
-  if (g_inputdeck.get< tag::cmd, tag::benchmark >()) return false;
-
-  const auto eps = std::numeric_limits< tk::real >::epsilon();
-  const auto ht = g_inputdeck.get< tag::history_output, tag::time_interval >();
-
-  if (ht < eps) return false;
-
-  return std::floor(m_t/ht) - m_physHistFloor > eps;
-}
-
-bool
-Discretization::histrange() const
-// *****************************************************************************
-//  Decide if physics time falls into a history output time range
-//! \return True if physics time falls into a history output time range
-// *****************************************************************************
-{
-  if (g_inputdeck.get< tag::cmd, tag::benchmark >()) return false;
-
-  const auto eps = std::numeric_limits< tk::real >::epsilon();
-
-  bool output = false;
-
-  const auto& rh = g_inputdeck.get< tag::history_output, tag::time_range >();
-  if (!rh.empty()) {
-    if (m_t > rh[0] and m_t < rh[1])
-      output |= std::floor(m_t/rh[2]) - m_rangeHistFloor > eps;
-  }
-
-  return output;
-}
-
-bool
-Discretization::finished() const
-// *****************************************************************************
-//  Decide if this is the last time step
-//! \return True if this is the last time step
-// *****************************************************************************
-{
-  const auto eps = std::numeric_limits< tk::real >::epsilon();
-  const auto nstep = g_inputdeck.get< tag::nstep >();
-  const auto term = g_inputdeck.get< tag::term >();
-
-  return std::abs(m_t-term) < eps or m_it >= nstep;
-}
-
-void
-Discretization::status()
-// *****************************************************************************
-// Output one-liner status report
-// *****************************************************************************
-{
-  // Query after how many time steps user wants TTY dump
-  const auto tty = g_inputdeck.get< tag::ttyi >();
-
-  // estimate grind time (taken between this and the previous time step)
-  using std::chrono::duration_cast;
-  using ms = std::chrono::milliseconds;
-  using clock = std::chrono::high_resolution_clock;
-  auto grind_time = duration_cast< ms >(clock::now() - m_prevstatus).count();
-  m_prevstatus = clock::now();
-
-  if (thisIndex==0 and m_meshid == 0 and not (m_it%tty)) {
-
-    const auto term = g_inputdeck.get< tag::term >();
-    const auto t0 = g_inputdeck.get< tag::t0 >();
-    const auto nstep = g_inputdeck.get< tag::nstep >();
-    const auto diag = g_inputdeck.get< tag::diagnostics, tag::interval >();
-    const auto lbfreq = g_inputdeck.get< tag::cmd, tag::lbfreq >();
-    const auto rsfreq = g_inputdeck.get< tag::cmd, tag::rsfreq >();
-    const auto verbose = g_inputdeck.get< tag::cmd, tag::verbose >();
-    const auto benchmark = g_inputdeck.get< tag::cmd, tag::benchmark >();
-    const auto steady = g_inputdeck.get< tag::steady_state >();
-
-    // estimate time elapsed and time for accomplishment
-    tk::Timer::Watch ete, eta;
-    if (not steady) m_timer.eta( term-t0, m_t-t0, nstep, m_it, ete, eta );
-
-    const auto& def =
-      g_inputdeck_defaults.get< tag::cmd, tag::io, tag::screen >();
-    tk::Print print( g_inputdeck.get< tag::cmd >().logname( def, m_nrestart ),
-                     verbose ? std::cout : std::clog,
-                     std::ios_base::app );
-
-    // Output one-liner
-    print << std::setfill(' ') << std::setw(8) << m_it << "  "
-          << std::scientific << std::setprecision(6)
-          << std::setw(12) << m_t << "  "
-          << m_dt << "  "
-          << std::setfill('0')
-          << std::setw(3) << ete.hrs.count() << ":"
-          << std::setw(2) << ete.min.count() << ":"
-          << std::setw(2) << ete.sec.count() << "  "
-          << std::setw(3) << eta.hrs.count() << ":"
-          << std::setw(2) << eta.min.count() << ":"
-          << std::setw(2) << eta.sec.count() << "  "
-          << std::scientific << std::setprecision(6) << std::setfill(' ')
-          << std::setw(9) << grind_time << "  ";
-
-    // Augment one-liner status with output indicators
-    if (fielditer() or fieldtime() or fieldrange()) print << 'f';
-    if (not (m_it % diag)) print << 'd';
-    if (histiter() or histtime() or histrange()) print << 't';
-    if (m_refined) print << 'h';
-    if (not (m_it % lbfreq) && not finished()) print << 'l';
-    if (not benchmark && (not (m_it % rsfreq) || finished())) print << 'r';
-
-    if (not m_meshvel_converged) print << 'a';
-    m_meshvel_converged = true; // get ready for next time step
-
-    print << std::endl;
-  }
-}
-
-#include "NoWarning/discretization.def.h"
+    //! Query underlying proxy element type
+    //! \return Zero-based index that can be used, e.g., indexing into the set
+    //!   of types of ProxyElem
+    std::size_t index_element() const noexcept { return element(0).index(); }
+
+    //! Charm++ array options accessor for binding external proxies
+    //! \return Charm++ array options object reference
+    const CkArrayOptions& arrayoptions() { return bound; }
+
+    /** @name Charm++ pack/unpack serializer member functions */
+    ///@{
+    //! \brief Pack/Unpack serialize member function
+    //! \param[in,out] p Charm++'s PUP::er serializer object reference
+    void pup( PUP::er &p ) {<--- Parameter 'p' can be declared with const
+      p | proxy;
+      p | discproxy;
+      p | aleproxy;
+      p | conjugategradientsproxy;
+      p | ghostsproxy;
+      p | bound;
+    }
+    //! \brief Pack/Unpack serialize operator|
+    //! \param[in,out] p Charm++'s PUP::er serializer object reference
+    //! \param[in,out] s Scheme object reference
+    friend void operator|( PUP::er& p, Scheme& s ) { s.pup(p); }
+    //@}
+
+  private:
+    //! Variant storing one proxy to which this class is configured for
+    Proxy proxy;
+    //! Charm++ proxy to data and code common to all discretizations
+    CProxy_Discretization discproxy;
+    //! Charm++ proxy to ALE class
+    CProxy_ALE aleproxy;
+    //! Charm++ proxy to conjugate gradients linear solver class
+    tk::CProxy_ConjugateGradients conjugategradientsproxy;
+    //! Charm++ proxy to Ghosts class
+    CProxy_Ghosts ghostsproxy;
+    //! Charm++ array options for binding chares
+    CkArrayOptions bound;
+
+    //! Function dereferencing operator[] of chare proxy inside variant
+    //! \param[in] x Chare array element index
+    //! \return Chare array element proxy as a variant, defined by ProxyElem
+    //! \details The returning element proxy is a variant, depending on the
+    //!   input proxy.
+    ProxyElem element( const CkArrayIndex1D& x ) const {
+      return std::visit( [&]( const auto& p ){
+               return static_cast< ProxyElem >( p[x] ); }, proxy );
+    }
+};
+
+} // inciter::
+
+#endif // Scheme_h
 
diff --git a/Release/cppcheck/37.html b/Release/cppcheck/37.html index 131d3e17a278..d88cdd172deb 100644 --- a/Release/cppcheck/37.html +++ b/Release/cppcheck/37.html @@ -152,12 +152,12 @@
  1
@@ -461,308 +461,950 @@ 

Cppcheck report - [

// *****************************************************************************
+302
+303
+304
+305
+306
+307
+308
+309
+310
+311
+312
+313
+314
+315
+316
+317
+318
+319
+320
+321
+322
+323
+324
+325
+326
+327
+328
+329
+330
+331
+332
+333
+334
+335
+336
+337
+338
+339
+340
+341
+342
+343
+344
+345
+346
+347
+348
+349
+350
+351
+352
+353
+354
+355
+356
+357
+358
+359
+360
+361
+362
+363
+364
+365
+366
+367
+368
+369
+370
+371
+372
+373
+374
+375
+376
+377
+378
+379
+380
+381
+382
+383
+384
+385
+386
+387
+388
+389
+390
+391
+392
+393
+394
+395
+396
+397
+398
+399
+400
+401
+402
+403
+404
+405
+406
+407
+408
+409
+410
+411
+412
+413
+414
+415
+416
+417
+418
+419
+420
+421
+422
+423
+424
+425
+426
+427
+428
+429
+430
+431
+432
+433
+434
+435
+436
+437
+438
+439
+440
+441
+442
+443
+444
+445
+446
+447
+448
+449
+450
+451
+452
+453
+454
+455
+456
+457
+458
+459
+460
+461
+462
+463
+464
+465
+466
+467
+468
+469
+470
+471
+472
+473
+474
+475
+476
+477
+478
+479
+480
+481
+482
+483
+484
+485
+486
+487
+488
+489
+490
+491
+492
+493
+494
+495
+496
+497
+498
+499
+500
+501
+502
+503
+504
+505
+506
+507
+508
+509
+510
+511
+512
+513
+514
+515
+516
+517
+518
+519
+520
+521
+522
+523
+524
+525
+526
+527
+528
+529
+530
+531
+532
+533
+534
+535
+536
+537
+538
+539
+540
+541
+542
+543
+544
+545
+546
+547
+548
+549
+550
+551
+552
+553
+554
+555
+556
+557
+558
+559
+560
+561
+562
+563
+564
+565
+566
+567
+568
+569
+570
+571
+572
+573
+574
+575
+576
+577
+578
+579
+580
+581
+582
+583
+584
+585
+586
+587
+588
+589
+590
+591
+592
+593
+594
+595
+596
+597
+598
+599
+600
+601
+602
+603
+604
+605
+606
+607
+608
+609
+610
+611
+612
+613
+614
+615
+616
+617
+618
+619
+620
+621
+622
+623
// *****************************************************************************
 /*!
-  \file      src/Inciter/Ghosts.hpp
+  \file      src/Inciter/Sorter.cpp
   \copyright 2012-2015 J. Bakosi,
              2016-2018 Los Alamos National Security, LLC.,
              2019-2021 Triad National Security, LLC.
              All rights reserved. See the LICENSE file for details.
-  \brief     Declarations file for generating ghost data structures
-  \details   Declarations file for asynchronous distributed
-             ghost data structures using Charm++.
-
-    There are a potentially large number of Ghosts Charm++ chares.
-    Each Ghosts chare gets a chunk of the full load, due to partiting the mesh.
-
-    The implementation uses the Charm++ runtime system and is fully
-    asynchronous, overlapping computation and communication. The algorithm
-    utilizes the structured dagger (SDAG) Charm++ functionality.
-*/
-// *****************************************************************************
-#ifndef Ghosts_h
-#define Ghosts_h
+  \brief     Mesh sorter for global distributed mesh reordering
+  \see       Sorter.h for more info.
+*/
+// *****************************************************************************
+
+#include <vector>
+#include <algorithm>
+
+#include "Sorter.hpp"
+#include "Reorder.hpp"
+#include "DerivedData.hpp"
+#include "Inciter/InputDeck/InputDeck.hpp"
+
+namespace inciter {
 
-#include "Fields.hpp"
-#include "FaceData.hpp"
-#include "Discretization.hpp"
+extern ctr::InputDeck g_inputdeck;
+
+} // inciter::
 
-#include "NoWarning/ghosts.decl.h"
+using inciter::Sorter;
 
-namespace inciter {
-
-//! Ghosts Charm++ chare array used to determine ghost data structures
-class Ghosts : public CBase_Ghosts {
-
-  public:
-    #if defined(__clang__)
-      #pragma clang diagnostic push
-      #pragma clang diagnostic ignored "-Wunused-parameter"
-      #pragma clang diagnostic ignored "-Wdeprecated-declarations"
-    #elif defined(STRICT_GNUC)
-      #pragma GCC diagnostic push
-      #pragma GCC diagnostic ignored "-Wunused-parameter"
-      #pragma GCC diagnostic ignored "-Wdeprecated-declarations"
-    #elif defined(__INTEL_COMPILER)
-      #pragma warning( push )
-      #pragma warning( disable: 1478 )
-    #endif
-    // Include Charm++ SDAG code. See http://charm.cs.illinois.edu/manuals/html/
-    // charm++/manual.html, Sec. "Structured Control Flow: Structured Dagger".
-    Ghosts_SDAG_CODE
-    #if defined(__clang__)
-      #pragma clang diagnostic pop
-    #elif defined(STRICT_GNUC)
-      #pragma GCC diagnostic pop
-    #elif defined(__INTEL_COMPILER)
-      #pragma warning( pop )
-    #endif
-
-    //! Constructor
-    explicit
-    Ghosts( const CProxy_Discretization& disc,
-      const std::map< int, std::vector< std::size_t > >& bface,
-      const std::vector< std::size_t >& triinpoel,
-      std::size_t nunk,
-      CkCallback cbDone );
-
-    #if defined(__clang__)
-      #pragma clang diagnostic push
-      #pragma clang diagnostic ignored "-Wundefined-func-template"
-    #endif
-    //! Migrate constructor
-    // cppcheck-suppress uninitMemberVar
-    explicit Ghosts( CkMigrateMessage* ) {}
-    #if defined(__clang__)
-      #pragma clang diagnostic pop
-    #endif
-
-    //! Local face & tet IDs associated to 3 global node IDs
-    //! \details This map stores tetrahedron cell faces (map key) and their
-    //!   associated local face ID and inner local tet id adjacent to the face
-    //!   (map value). A face is given by 3 global node IDs.
-    using FaceMap =
-      std::unordered_map< tk::UnsMesh::Face,  // 3 global node IDs
-                          std::array< std::size_t, 2 >, // local face & tet ID
-                          tk::UnsMesh::Hash<3>,
-                          tk::UnsMesh::Eq<3> >;
-
-    //! Storage type for refined mesh used for field output
-    struct OutMesh {
-      //! Element connectivity, local->global node ids, global->local nodes ids
-      tk::UnsMesh::Chunk chunk;
-      //! Node coordinates
-      tk::UnsMesh::Coords coord;
-      //! Triangle element connectivity
-      std::vector< std::size_t > triinpoel;
-      //! Boundary-face connectivity
-      std::map< int, std::vector< std::size_t > > bface;
-      //! Node communinaction map
-      tk::NodeCommMap nodeCommMap;
-      //! \brief Pack/Unpack serialize member function
-      //! \param[in,out] p Charm++'s PUP::er serializer object reference
-      void pup( PUP::er& p ) {<--- Parameter 'p' can be declared with const
-        p|chunk; p|coord; p|triinpoel; p|bface; p|nodeCommMap;
-      }
-      //! Destroyer
-      void destroy() {
-        tk::destroy( std::get<0>(chunk) );
-        tk::destroy( std::get<1>(chunk) );
-        tk::destroy( std::get<2>(chunk) );
-        tk::destroy( coord[0] );
-        tk::destroy( coord[1] );
-        tk::destroy( coord[2] );
-        tk::destroy( triinpoel );
-        tk::destroy( bface );
-        tk::destroy( nodeCommMap );
-      }
-    };
-
-    //! Discretization proxy
-    CProxy_Discretization m_disc;
-    //! Counter for number of unknowns on this chare (including ghosts)
-    std::size_t m_nunk;
-    //! Mesh connectivity extended
-    std::vector< std::size_t > m_inpoel;
-    //! Node coordinates extended
-    tk::UnsMesh::Coords m_coord;
-    //! Face data
-    FaceData m_fd;
-    //! Face geometry
-    tk::Fields m_geoFace;
-    //! Element geometry
-    tk::Fields m_geoElem;
-    //! Counter for number of faces on this chare (including chare boundaries)
-    std::size_t m_nfac;
-    //! Face & tet IDs associated to global node IDs of the face for each chare
-    //! \details This map stores not only the unique faces associated to
-    //!   fellow chares, but also a newly assigned local face ID and adjacent
-    //!   local tet ID.
-    std::unordered_map< int, FaceMap > m_bndFace;
-    //! Elements which are ghosts for other chares associated to those chare IDs
-    std::unordered_map< int, std::unordered_set< std::size_t > > m_sendGhost;
-    //! Local element id associated to ghost remote id charewise
-    //! \details This map associates the local element id (inner map value) to
-    //!    the (remote) element id of the ghost (inner map key) based on the
-    //!    chare id (outer map key) this remote element lies in.
-    std::unordered_map< int,
-      std::unordered_map< std::size_t, std::size_t > > m_ghost;
-    //! Expected ghost tet ids (used only in DEBUG)
-    std::set< std::size_t > m_exptGhost;
-    //! Map local ghost tet ids (value) and zero-based boundary ids (key)
-    std::unordered_map< std::size_t, std::size_t > m_bid;
-    //! Elements (value) surrounding point (key) data-structure
-    std::map< std::size_t, std::vector< std::size_t > > m_esup;
-    //! 1 if starting time stepping, 0 if during time stepping
-    std::size_t m_initial;
-
-    //1 Start setup of communication maps for cell-centered schemes
-    void startCommSetup();
-
-    //! Start sizing communication buffers and setting up ghost data
-    void resizeComm();
-
-    //! Receive unique set of faces we potentially share with/from another chare
-    void comfac( int fromch, const tk::UnsMesh::FaceSet& infaces );
-
-    //! Receive ghost data on chare boundaries from fellow chare
-    void comGhost( int fromch, const GhostData& ghost );
-
-    //! Receive requests for ghost data
-    void reqGhost();
-
-    //! Send all of our ghost data to fellow chares
-    void sendGhost();
-
-    //! Setup node-neighborhood (esup)
-    void nodeNeighSetup();
-
-    //! Receive element-surr-points data on chare boundaries from fellow chare
-    void comEsup( int fromch,
-      const std::unordered_map< std::size_t, std::vector< std::size_t > >&
-        bndEsup,
-      const std::unordered_map< std::size_t, std::vector< tk::real > >&
-        nodeBndCells );
-
-    /** @name Pack/unpack (Charm++ serialization) routines */
-    ///@{
-    //! \brief Pack/Unpack serialize member function
-    //! \param[in,out] p Charm++'s PUP::er serializer object reference
-    void pup( PUP::er &p ) override {
-      p | m_disc;
-      p | m_nunk;
-      p | m_inpoel;
-      p | m_coord;
-      p | m_fd;
-      p | m_geoFace;
-      p | m_geoElem;
-      p | m_nfac;
-      p | m_bndFace;
-      p | m_sendGhost;
-      p | m_ghost;
-      p | m_exptGhost;
-      p | m_bid;
-      p | m_esup;
-      p | m_initial;
-      p | m_ncomfac;
-      p | m_nadj;
-      p | m_ncomEsup;
-      p | m_ipface;
-      p | m_ghostData;
-      p | m_ghostReq;
-      p | m_expChBndFace;
-      p | m_infaces;
-      p | m_esupc;
-      p | m_cbAfterDone;
-    }
-    //! \brief Pack/Unpack serialize operator|
-    //! \param[in,out] p Charm++'s PUP::er serializer object reference
-    //! \param[in,out] a Ghosts object reference
-    friend void operator|( PUP::er& p, Ghosts& a ) { a.pup(p); }
-    ///@}
+Sorter::Sorter( std::size_t meshid,
+                const CProxy_Transporter& transporter,
+                const tk::CProxy_MeshWriter& meshwriter,
+                const tk::SorterCallback& cbs,
+                const std::vector< Scheme >& scheme,
+                CkCallback reorderRefiner,
+                const std::vector< std::size_t >& ginpoel,
+                const tk::UnsMesh::CoordMap& coordmap,
+                const tk::UnsMesh::Chunk& el,
+                const std::map< int, std::vector< std::size_t > >& bface,
+                const std::vector< std::size_t >& triinpoel,
+                const std::map< int, std::vector< std::size_t > >& bnode,
+                const std::unordered_map< std::size_t, std::set< std::size_t > >&
+                  elemblockid,
+                int nchare ) :
+  m_meshid( meshid ),
+  m_host( transporter ),
+  m_meshwriter( meshwriter ),
+  m_cbs( cbs ),
+  m_scheme( scheme ),
+  m_reorderRefiner( reorderRefiner ),
+  m_ginpoel( ginpoel ),
+  m_coordmap( coordmap ),
+  m_el( el ),
+  m_nbnd( 0 ),
+  m_bface( bface ),
+  m_triinpoel( triinpoel ),
+  m_bnode( bnode ),
+  m_elemblockid( elemblockid ),
+  m_nchare( nchare ),
+  m_nodeset( begin(ginpoel), end(ginpoel) ),
+  m_noffset( 0 ),
+  m_nodech(),
+  m_chnode(),
+  m_edgech(),
+  m_chedge(),
+  m_msum(),
+  m_reordcomm(),
+  m_start( 0 ),
+  m_newnodes(),
+  m_newcoordmap(),
+  m_reqnodes(),
+  m_lower( 0 ),
+  m_upper( 0 )
+// *****************************************************************************
+//  Constructor: prepare owned mesh node IDs for reordering
+//! \param[in] meshid Mesh ID
+//! \param[in] transporter Transporter (host) Charm++ proxy
+//! \param[in] meshwriter Mesh writer Charm++ proxy
+//! \param[in] cbs Charm++ callbacks for Sorter
+//! \param[in] scheme Discretization schemes (one per mesh)
+//! \param[in] reorderRefiner Callback to use to send reordered mesh to Refiner
+//! \param[in] ginpoel Mesh connectivity (this chare) using global node IDs
+//! \param[in] coordmap Mesh node coordinates (this chare) for global node IDs
+//! \param[in] bface Face lists mapped to side set ids
+//! \param[in] triinpoel Interconnectivity of points and boundary-faces
+//! \param[in] bnode Node ids mapped to side set ids
+//! \param[in] elemblockid Local tet ids associated to mesh block ids
+//! \param[in] nchare Total number of Charm++ worker chares
+// *****************************************************************************
+{
+  // Ensure boundary face ids will not index out of face connectivity
+  Assert( std::all_of( begin(m_bface), end(m_bface),
+            [&](const auto& s)
+            { return std::all_of( begin(s.second), end(s.second),
+                       [&](auto f){ return f*3+2 < m_triinpoel.size(); } ); } ),
+          "Boundary face data structures inconsistent" );
+}
+
+void
+Sorter::setup( std::size_t npoin )
+// *****************************************************************************
+// Setup chare mesh boundary node communication map
+//! \param[in] npoin Total number of mesh points in mesh. Note that the number
+//!   of mesh points does not have to be exactly the total number of points in
+//!   the mesh. It can be a larger number, but not less. This is only used here
+//!   to assign nodes to workers that will assign ids to mesh nodes during node
+//!   reordering.
+// *****************************************************************************
+{
+  // Compute the number of nodes (chunksize) a chare will build a node
+  // communication map for. We compute two values of chunksize: one for when
+  // the global node ids are abounded between [0...npoin-1], inclusive, and
+  // another one for when the global node ids are assigned by a hash algorithm
+  // during initial mesh refinement. In the latter case, the maximum
+  // representable value of a std::size_t is assumed to be the large global node
+  // id and is used to compute the chunksize. To compute the bin id, we attempt
+  // to use the first chunksize first: if it gives a chare id that is
+  // (strictly) lower than the number of chares, that's good. If not, we compute
+  // the bin id based on the second chunksize, which almost always will give a
+  // bin id strictly lower than the number of chares, except if the global node
+  // id assigned by the hash algorithm in Refiner hits the maximum
+  // representable number in std::size_t. If that is the case, we just assign
+  // that node to the last chare.
+  auto N = static_cast< std::size_t >( m_nchare );
+  std::array< std::size_t, 2 > chunksize{{
+     npoin / N, std::numeric_limits< std::size_t >::max() / N }};
+
+  const auto scheme = g_inputdeck.get< tag::scheme >();<--- Variable 'scheme' is assigned a value that is never used.
+
+  // Find chare-boundary nodes and edges of our mesh chunk. This algorithm
+  // collects the global mesh node ids and edges on the chare boundary. A node
+  // is on a chare boundary if it belongs to a face of a tetrahedron that has
+  // no neighbor tet at a face. The edge is on the chare boundary if its first
+  // edge-end point is on a chare boundary. The nodes are categorized to bins
+  // that will be sent to different chares to build point-to-point
+  // communication maps across all chares. The binning is determined by the
+  // global node id divided by the chunksizes. See discussion above on how we
+  // use two chunksizes for global node ids assigned by the hash algorithm in
+  // Refiner (if initial mesh refinement has been done).
+  tk::CommMaps chbnd;
+  auto el = tk::global2local( m_ginpoel );      // generate local mesh data
+  const auto& inpoel = std::get< 0 >( el );     // local connectivity
+  auto esup = tk::genEsup( inpoel, 4 );         // elements surrounding points
+  auto esuel = tk::genEsuelTet( inpoel, esup ); // elems surrounding elements
+  for (std::size_t e=0; e<esuel.size()/4; ++e) {
+    auto mark = e*4;
+    for (std::size_t f=0; f<4; ++f)
+      if (esuel[mark+f] == -1)
+        for (std::size_t n=0; n<3; ++n) {
+          auto g = m_ginpoel[ mark+tk::lpofa[f][n] ];
+          auto bin = g / chunksize[0];
+          if (bin >= N) bin = g / chunksize[1];
+          if (bin >= N) bin = N - 1;
+          Assert( bin < N, "Will index out of number of chares" );
+          auto& b = chbnd[ static_cast< int >( bin ) ];
+          b.get< tag::node >().insert( g );
+          if (scheme == ctr::SchemeType::ALECG ||
+            scheme == ctr::SchemeType::OversetFE) {
+            auto h = m_ginpoel[ mark + tk::lpofa[ f ][ tk::lpoet[n][1] ] ];
+            b.get< tag::edge >().insert( { std::min(g,h), std::max(g,h) } );
+          }
+        }
+  }
+
+  // Send boundary data in bins to chares that will compute communication maps
+  // for the data in the bin. These bins form a distributed table.  Note that
+  // we only send data to those chares that have data to work on. The receiving
+  // sides do not know in advance if they receive messages or not.  Completion
+  // is detected by having the receiver respond back and counting the responses
+  // on the sender side, i.e., this chare.
+  m_nbnd = chbnd.size();
+  if (m_nbnd == 0)
+    contribute( sizeof(std::size_t), &m_meshid, CkReduction::nop,
+                m_cbs.get< tag::queried >() );
+  else
+    for (const auto& [ targetchare, bnd ] : chbnd)
+      thisProxy[ targetchare ].query( thisIndex, bnd );
+}
+
+void
+Sorter::query( int fromch, const tk::AllCommMaps& bnd )
+// *****************************************************************************
+// Incoming query for a list of mesh nodes for which this chare compiles node
+// communication maps
+//! \param[in] fromch Sender chare ID
+//! \param[in] bnd Chare-boundary data from another chare
+// *****************************************************************************
+{
+  // Store incoming nodes in node->chare and its inverse, chare->node, maps
+  const auto& nodes = bnd.get< tag::node >();
+  for (auto n : nodes) m_nodech[ n ].push_back( fromch );
+  m_chnode[ fromch ].insert( begin(nodes), end(nodes) );
+
+  // Store incoming edges in edge->chare and its inverse, chare->edge, maps
+  const auto& edges = bnd.get< tag::edge >();
+  for (const auto& e : edges) m_edgech[ e ].push_back( fromch );
+  m_chedge[ fromch ].insert( begin(edges), end(edges) );
+
+  // Report back to chare message received from
+  thisProxy[ fromch ].recvquery();
+}
+
+void
+Sorter::recvquery()
+// *****************************************************************************
+// Receive receipt of boundary node lists to query
+// *****************************************************************************
+{
+  if (--m_nbnd == 0)
+    contribute( sizeof(std::size_t), &m_meshid, CkReduction::nop,
+                m_cbs.get< tag::queried >() );
+}
+
+void
+Sorter::response()
+// *****************************************************************************
+//  Respond to boundary node list queries
+// *****************************************************************************
+{
+  std::unordered_map< int, tk::CommMaps > exp;
 
-  private:
-    using ncomp_t = tk::ncomp_t;
-
-    //! Counter for face adjacency communication map
-    std::size_t m_ncomfac;
-    //! Counter signaling that all ghost data have been received
-    std::size_t m_nadj;
-    //! Counter for element-surr-node adjacency communication map
-    std::size_t m_ncomEsup;
-    //! Internal + physical boundary faces (inverse of inpofa)
-    tk::UnsMesh::FaceSet m_ipface;
-    //! Ghost data associated to chare IDs we communicate with
-    std::unordered_map< int, GhostData > m_ghostData;
-    //! Number of chares requesting ghost data
-    std::size_t m_ghostReq;
-    //! Unique set of chare-boundary faces this chare is expected to receive
-    tk::UnsMesh::FaceSet m_expChBndFace;
-    //! Incoming communication buffer during chare-boundary face communication
-    std::unordered_map< int, tk::UnsMesh::FaceSet > m_infaces;
-    //! Communication buffer for esup data-structure
-    std::map< std::size_t, std::vector< std::size_t > > m_esupc;
-    //! Function call to continue with in Scheme when Ghosts is done
-    CkCallback m_cbAfterDone;
-
-    //! Access bound Discretization class pointer
-    Discretization* Disc() const {
-      Assert( m_disc[ thisIndex ].ckLocal() != nullptr, "ckLocal() null" );
-      return m_disc[ thisIndex ].ckLocal();
-    }
-
-    //! Compute chare-boundary faces
-    void bndFaces();
-
-    //! Setup own ghost data on this chare
-    void setupGhost();
-
-    //! Continue after face adjacency communication map completed on this chare
-    void faceAdj();
-
-    //! Compute partial boundary surface integral and sum across all chares
-    void bndIntegral();
-
-    //! Continue after node adjacency communication map completed on this chare
-    void adj();
-
-    //! Perform leak-test on chare boundary faces
-    bool leakyAdjacency();
-
-    //! Check if esuf of chare-boundary faces matches
-    bool faceMatch();
-
-    //! Verify that all chare-boundary faces have been received
-    bool receivedChBndFaces();
+  // Compute node communication map to be sent back to chares
+  for (const auto& [ neighborchare, bndnodes ] : m_chnode) {
+    auto& nc = exp[ neighborchare ];
+    for (auto n : bndnodes)
+      for (auto d : tk::cref_find(m_nodech,n))
+        if (d != neighborchare)
+          nc[d].get< tag::node >().insert( n );
+  }
+
+  // Compute edge communication map to be sent back to chares
+  for (const auto& [ neighborchare, bndedges ] : m_chedge) {
+    auto& ec = exp[ neighborchare ];
+    for (const auto& e : bndedges)
+      for (auto d : tk::cref_find(m_edgech,e))
+        if (d != neighborchare)
+          ec[d].get< tag::edge >().insert( e );
+  }
+
+  // Send communication maps to chares that issued a query to us. Communication
+  // maps were computed above for those chares that queried this map from us.
+  // This data form a distributed table and we only work on a chunk of it. Note
+  // that we only send data back to those chares that have queried us. The
+  // receiving sides do not know in advance if the receive messages or not.
+  // Completion is detected by having the receiver respond back and counting
+  // the responses on the sender side, i.e., this chare.
+  m_nbnd = exp.size();
+  if (m_nbnd == 0)
+    contribute( sizeof(std::size_t), &m_meshid, CkReduction::nop,
+                m_cbs.get< tag::responded >() );
+  else
+    for (const auto& [ targetchare, maps ] : exp)
+      thisProxy[ targetchare ].bnd( thisIndex, maps );
+}
+
+void
+Sorter::bnd( int fromch, const tk::CommMaps& msum )
+// *****************************************************************************
+// Receive boundary node communication maps for our mesh chunk
+//! \param[in] fromch Sender chare ID
+//! \param[in] msum Communication map(s) assembled by chare fromch
+// *****************************************************************************
+{
+  for (const auto& [ neighborchare, maps ] : msum) {
+    auto& m = m_msum[ neighborchare ];
+    const auto& nodemap = maps.get< tag::node >();
+    m.get< tag::node >().insert( begin(nodemap), end(nodemap) );
+    const auto& edgemap = maps.get< tag::edge >();
+    m.get< tag::edge >().insert( begin(edgemap), end(edgemap) );
+  }
+
+  // Report back to chare message received from
+  thisProxy[ fromch ].recvbnd();
+}
 
-    //! Find any chare for face (given by 3 global node IDs)
-    int findchare( const tk::UnsMesh::Face& t );
-
-    //! Check if entries in inpoel, inpofa and node-triplet are consistent
-    std::size_t nodetripletMatch(
-      const std::array< std::size_t, 2 >& id,
-      const tk::UnsMesh::Face& t );
-
-    //! Fill elements surrounding a face along chare boundary
-    void addEsuf(
-      const std::array< std::size_t, 2 >& id,
-      std::size_t ghostid );
-
-    //! Fill elements surrounding a element along chare boundary
-    void addEsuel(
-      const std::array< std::size_t, 2 >& id,
-      std::size_t ghostid,
-      const tk::UnsMesh::Face& t );
-
-    //! Fill face-geometry data along chare boundary
-    void addGeoFace(
-      const tk::UnsMesh::Face& t,
-      const std::array< std::size_t, 2 >& id );
-};
-
-} // inciter::
-
-#endif // Ghosts_h
+void
+Sorter::recvbnd()
+// *****************************************************************************
+// Receive receipt of boundary node communication map
+// *****************************************************************************
+{
+  if (--m_nbnd == 0)
+    contribute( sizeof(std::size_t), &m_meshid, CkReduction::nop,
+                m_cbs.get< tag::responded >() );
+}
+
+void
+Sorter::start()
+// *****************************************************************************
+//  Start reordering (if enabled)
+// *****************************************************************************
+{
+  // Keep only those edges in edge comm map whose both end-points are in the
+  // node comm map
+  for (auto& [ neighborchare, maps ] : m_msum) {
+    const auto& nodes = maps.get< tag::node >();
+    tk::EdgeSet edges;
+    for (const auto& e : maps.get< tag::edge >())
+      if (nodes.find(e[0]) != end(nodes) && nodes.find(e[1]) != end(nodes))
+        edges.insert( e );
+    maps.get< tag::edge >() = std::move(edges);
+  }
+
+  if (g_inputdeck.get< tag::cmd, tag::feedback >()) m_host.chcomm();
+
+  tk::destroy( m_nodech );
+  tk::destroy( m_chnode );
+
+  if (g_inputdeck.get< tag::pelocal_reorder >())
+    mask();   // continue with mesh node reordering if requested (or required)
+  else
+    createDiscWorkers();  // skip mesh node reordering
+}
+
+void
+Sorter::mask()
+// *****************************************************************************
+//  Start preparing for mesh node reordering in parallel
+// *****************************************************************************
+{
+  // Compute asymmetric communcation map that will be used for reordering. This
+  // communication map is asymmetric because it associates global mesh node IDs
+  // to chares only with lower IDs than thisIndex. That is because this chare
+  // will need to receive new (reorderd) node IDs only from chares with lower
+  // IDs than thisIndex during node reordering. Since it only stores data for
+  // lower chare IDs, it is asymmetric. Note that because of this algorithm the
+  // type of m_msum is an ordered map, because of the std::none_of() algorithm
+  // needs to look at ALL chares this chare potentially communicates nodes with
+  // that have lower chare IDs that thisIndex. Since the map is ordered, it can
+  // walk through from the beginning of m_msum until the outer loop variable c,
+  // which is the chare ID the outer loop works on in a given cycle.
+  for (auto c=m_msum.cbegin(); c!=m_msum.cend(); ++c)
+    if (thisIndex > c->first) {
+      auto& n = m_reordcomm[ c->first ];
+      for (auto j : c->second.get< tag::node >())
+        if (std::none_of( m_msum.cbegin(), c,
+             [j]( const auto& s ) {
+               const auto& nodemap = s.second.template get< tag::node >();
+               return nodemap.find(j) != end(nodemap); } ))
+        {
+          n.insert(j);
+        }
+      if (n.empty()) m_reordcomm.erase( c->first );
+    }
+
+  // Count up total number of nodes this chare will need to receive
+  auto nrecv = tk::sumvalsize( m_reordcomm );
+
+  if ( g_inputdeck.get< tag::cmd, tag::feedback >() ) m_host.chmask();
+
+  // Compute number of mesh node IDs we will assign IDs to
+  auto nuniq = m_nodeset.size() - nrecv;
+
+  // Start computing offsets for node reordering
+  thisProxy.offset( thisIndex, nuniq );
+}
+
+void
+Sorter::offset( int c, std::size_t u )
+// *****************************************************************************
+//  Receive number of uniquely assigned global mesh node IDs from chares with
+//  lower IDs than thisIndex
+//! \param[in] c Chare ID
+//! \param[in] u Number of mesh node IDs chare c will assign IDs to
+//! \details This function computes the offset each chare will need to start
+//!   assigning its new node IDs from. The offset for a chare is the
+//!   offset for the previous chare plus the number of node IDs the previous
+//!   chare (uniquely) assigns new IDs for minus the number of node IDs the
+//!   previous chare receives from others (lower chares). This is computed here
+//!   in a parallel/distributed fashion by each chare sending its number of node
+//!   IDs (that it uniquely assigns) to all chares. Note that each chare would
+//!   only need to send this information to chares with higher IDs, but instead
+//!   this function is called in a broadcast fashion, because that is more
+//!   efficient than individual calls to only chares with higher IDs. Therefore
+//!   when computing the offsets, we only count the lower chares. When this is
+//!   done, we have the precise asymmetric communication map as well as the
+//!   start offset on all chares and so we can start the distributed global mesh
+//!   node ID reordering.
+// *****************************************************************************
+{
+  if (c < thisIndex) m_start += u;
+  if (++m_noffset == m_nchare) reorder();
+}
+
+void
+Sorter::reorder()
+// *****************************************************************************
+//  Reorder global mesh node IDs
+// *****************************************************************************
+{
+  // Activate SDAG waits for arriving requests from other chares requesting new
+  // node IDs for node IDs we assign new IDs to during reordering; and for
+  // computing/receiving lower and upper bounds of global node IDs our chare's
+  // linear system will operate on after reordering.
+  thisProxy[ thisIndex ].wait4prep();
+
+  // Send out request for new global node IDs for nodes we do not reorder
+  for (const auto& [ targetchare, nodes ] : m_reordcomm)
+    thisProxy[ targetchare ].request( thisIndex, nodes );
+
+  // Lambda to decide if node is assigned a new ID by this chare. If node is not
+  // found in the asymmetric communication map, it is owned, i.e., this chare
+  // assigns its new id.
+  auto ownnode = [ this ]( std::size_t p ) {
+    return std::all_of( m_reordcomm.cbegin(), m_reordcomm.cend(),
+                        [&](const auto& s)
+                        { return s.second.find(p) == s.second.cend(); } );
+  };
+
+  // Reorder our chunk of the mesh node IDs. Looping through all of our node
+  // IDs, we test if we are to assign a new ID to a node ID, and if so, we
+  // assign a new ID, i.e., reorder, by constructing a map associating new to
+  // old IDs (m_newnodes). We also count up the reordered nodes, which serves as
+  // the new node id. We also store the node coordinates associated to the new
+  // node ID.
+  for (auto p : m_nodeset)
+    if (ownnode(p)) {
+      m_newnodes[ p ] = m_start;        // assign new node ID (reorder)
+      m_newcoordmap.emplace( m_start, tk::cref_find(m_coordmap,p) );
+      ++m_start;
+    }
+
+  // Trigger SDAG wait indicating that reordering our node IDs are complete
+  reorderowned_complete();
+
+  // If all our nodes have new IDs assigned, reordering complete on this chare
+  if (m_newnodes.size() == m_nodeset.size()) finish();
+}
+
+void
+Sorter::request( int c, const std::unordered_set< std::size_t >& nd )
+// *****************************************************************************
+//  Request new global node IDs for old node IDs
+//! \param[in] c Chare request coming from and to which we send new IDs to
+//! \param[in] nd Set of old node IDs whose new IDs are requested
+// *****************************************************************************
+{
+  // Queue up requesting chare and node IDs
+  m_reqnodes.push_back( { c, nd } );
+  // Trigger SDAG wait signaling that node IDs have been requested from us
+  nodes_requested_complete();
+}
+
+void
+Sorter::prepare()
+// *****************************************************************************
+//  Find new node IDs for old ones and return them to the requestor(s)
+// *****************************************************************************
+{
+  // Find and return new node IDs to sender
+  for (const auto& [ requestorchare, nodes ] : m_reqnodes) {
+    std::unordered_map< std::size_t,
+      std::tuple< std::size_t, tk::UnsMesh::Coord > > n;
+    for (auto p : nodes) {
+      auto newid = tk::cref_find( m_newnodes, p );
+      n.emplace( p,
+        std::make_tuple( newid, tk::cref_find(m_newcoordmap,newid) ) );
+    }
+    thisProxy[ requestorchare ].neworder( n );
+  }
+
+  tk::destroy( m_reqnodes ); // Clear queue of requests just fulfilled
+
+  // Re-enable SDAG wait for preparing new node requests
+  thisProxy[ thisIndex ].wait4prep();
+
+  // Re-enable trigger signaling that reordering of owned node IDs are
+  // complete right away
+  reorderowned_complete();
+}
+
+void
+Sorter::neworder( const std::unordered_map< std::size_t,
+                        std::tuple< std::size_t, tk::UnsMesh::Coord > >& nodes )
+// *****************************************************************************
+//  Receive new (reordered) global node IDs
+//! \param[in] nodes Map associating new to old node IDs
+// *****************************************************************************
+{
+  // Store new node IDs associated to old ones, and node coordinates associated
+  // to new node IDs.
+  for (const auto& [ oldid, newnodes ] : nodes) {
+    auto newid = std::get< 0 >( newnodes );
+    m_newnodes[ oldid ] = newid;
+    m_newcoordmap.emplace( newid, std::get< 1 >( newnodes ) );
+  }
+
+  // If all our nodes have new IDs assigned, reorder complete on this PE
+  if (m_newnodes.size() == m_nodeset.size()) finish();
+}
+
+void
+Sorter::finish()
+// *****************************************************************************
+//  Compute final result of reordering
+//! \details Reordering is now complete on this chare. We now remap all mesh
+//!   data to reflect the new ordering.
+// *****************************************************************************
+{
+  // Update elem connectivity with the reordered node IDs
+  tk::remap( m_ginpoel, m_newnodes );
+
+  // Update node coordinate map with the reordered IDs
+  m_coordmap = m_newcoordmap;
+
+  // Update mesh chunk data structure held in our state with new node order
+  m_el = tk::global2local( m_ginpoel );
+
+  // Update symmetric chare-node communication map with the reordered IDs
+  for (auto& [ neighborchare, maps ] : m_msum) {
+
+    tk::NodeSet n;
+    for (auto p : maps.get< tag::node >())
+      n.insert( tk::cref_find( m_newnodes, p ) );
+    maps.get< tag::node >() = std::move( n );
+
+    tk::EdgeSet e;
+    for (const auto& ed : maps.get< tag::edge >()) {
+      e.insert( { tk::cref_find(m_newnodes,ed[0]),
+                  tk::cref_find(m_newnodes,ed[1]) } );
+    }
+    maps.get< tag::edge >() = std::move( e );
+
+  }
+
+  // Update boundary face-node connectivity with the reordered node IDs
+  tk::remap( m_triinpoel, m_newnodes );
+
+  // Update boundary node lists with the reordered node IDs
+  for (auto& [ setid, nodes ] : m_bnode) tk::remap( nodes, m_newnodes );
+
+  // Update mesh in Refiner after reordering
+  m_reorderRefiner.send();
+
+  // Progress report to host
+  if ( g_inputdeck.get< tag::cmd, tag::feedback >() ) m_host.chreordered();
+
+  createDiscWorkers();
+}
+
+void
+Sorter::mesh( std::vector< std::size_t >& ginpoel,
+              tk::UnsMesh::CoordMap& coordmap,
+              std::vector< std::size_t >& triinpoel,
+              std::map< int, std::vector< std::size_t > >& bnode )
+// *****************************************************************************
+// Update mesh data we hold for whoever calls this function
+//! \param[in,out] ginpoel Mesh connectivity using global IDs
+//! \param[in,out] coordmap Map of mesh node coordinates
+//! \param[in,out] triinpoel Boundary face-node connectivity
+//! \param[in] bnode Node lists of side sets
+// *****************************************************************************
+{
+  ginpoel = m_ginpoel;
+  coordmap = m_coordmap;
+  triinpoel = m_triinpoel;
+  bnode = m_bnode;
+}
+
+void
+Sorter::createDiscWorkers()
+// *****************************************************************************
+//  Create Discretization chare array elements on this PE
+//! \details We create chare array elements by calling the insert() member
+//!   function, which allows specifying the PE on which the array element is
+//!   created. and we send each chare array element the chunk of mesh it will
+//!   operate on.
+// *****************************************************************************
+{
+  std::vector< CProxy_Discretization > disc;
+  for (auto& d : m_scheme) disc.push_back( d.disc() );<--- Consider using std::transform algorithm instead of a raw loop.
+
+  // Create worker array element using Charm++ dynamic chare array element
+  // insertion: last arg: PE chare is created on. See also Charm++ manual, Sec.
+  // "Dynamic Insertion".
+
+  m_scheme[m_meshid].disc()[ thisIndex ].insert( m_meshid, disc,
+    m_scheme[m_meshid].ale(),
+    m_scheme[m_meshid].conjugategradients(), m_host, m_meshwriter, m_coordmap,
+    m_el, m_msum, m_bface, m_triinpoel, m_elemblockid, m_nchare );
+
+  contribute( sizeof(std::size_t), &m_meshid, CkReduction::nop,
+              m_cbs.get< tag::discinserted >() );
+}
+
+void
+Sorter::createWorkers()
+// *****************************************************************************
+//  Create worker chare array element
+// *****************************************************************************
+{
+  // Make sure (bound) base is already created and accessible
+  Assert( m_scheme[m_meshid].disc()[thisIndex].ckLocal() != nullptr,
+          "About to pass nullptr" );
+
+  // Create worker array element using Charm++ dynamic chare array element
+  // insertion: 1st arg: chare id, other args: Discretization's child ctor args.
+  // See also Charm++ manual, Sec. "Dynamic Insertion".
+
+  m_scheme[m_meshid].insert( thisIndex, m_scheme[m_meshid].disc(),
+    m_scheme[m_meshid].ghosts(), m_bface, m_bnode, m_triinpoel );
+
+  if ( g_inputdeck.get< tag::cmd, tag::feedback >() ) m_host.chcreated();
+
+  contribute( sizeof(std::size_t), &m_meshid, CkReduction::nop,
+              m_cbs.get< tag::workinserted >() );
+
+  // Free up some memory
+  tk::destroy( m_ginpoel );
+  tk::destroy( m_coordmap );
+  tk::destroy( m_bface );
+  tk::destroy( m_triinpoel );
+  tk::destroy( m_elemblockid );
+  tk::destroy( m_bnode );
+  tk::destroy( m_nodeset );
+  tk::destroy( m_nodech );
+  tk::destroy( m_chnode );
+  tk::destroy( m_msum );
+  tk::destroy( m_reordcomm );
+  tk::destroy( m_newnodes );
+  tk::destroy( m_reqnodes );
+}
+
+#include "NoWarning/sorter.def.h"
 
diff --git a/Release/cppcheck/38.html b/Release/cppcheck/38.html index dd1fd6d2c60f..76f14ac6bf4d 100644 --- a/Release/cppcheck/38.html +++ b/Release/cppcheck/38.html @@ -152,12 +152,12 @@
   1
@@ -1252,1099 +1252,1405 @@ 

Cppcheck report - [

// *****************************************************************************
+1093
+1094
+1095
+1096
+1097
+1098
+1099
+1100
+1101
+1102
+1103
+1104
+1105
+1106
+1107
+1108
+1109
+1110
+1111
+1112
+1113
+1114
+1115
+1116
+1117
+1118
+1119
+1120
+1121
+1122
+1123
+1124
+1125
+1126
+1127
+1128
+1129
+1130
+1131
+1132
+1133
+1134
+1135
+1136
+1137
+1138
+1139
+1140
+1141
+1142
+1143
+1144
+1145
+1146
+1147
+1148
+1149
+1150
+1151
+1152
+1153
+1154
+1155
+1156
+1157
+1158
+1159
+1160
+1161
+1162
+1163
+1164
+1165
+1166
+1167
+1168
+1169
+1170
+1171
+1172
+1173
+1174
+1175
+1176
+1177
+1178
+1179
+1180
+1181
+1182
+1183
+1184
+1185
+1186
+1187
+1188
+1189
+1190
+1191
+1192
+1193
+1194
+1195
+1196
+1197
+1198
+1199
+1200
+1201
+1202
+1203
+1204
+1205
+1206
+1207
+1208
+1209
+1210
+1211
+1212
+1213
+1214
+1215
+1216
+1217
+1218
+1219
+1220
+1221
+1222
+1223
+1224
+1225
+1226
+1227
+1228
+1229
+1230
+1231
+1232
+1233
+1234
+1235
+1236
+1237
+1238
+1239
+1240
+1241
+1242
+1243
+1244
+1245
+1246
// *****************************************************************************
 /*!
-  \file      src/Inciter/Ghosts.cpp
+  \file      src/Inciter/Discretization.cpp
   \copyright 2012-2015 J. Bakosi,
              2016-2018 Los Alamos National Security, LLC.,
              2019-2021 Triad National Security, LLC.
              All rights reserved. See the LICENSE file for details.
-  \brief     Definitions file for generating ghost data structures
-  \details   Definitions file for asynchronous distributed
-             ghost data structures using Charm++.
-*/
-// *****************************************************************************
-
-#include "Ghosts.hpp"
-#include "DerivedData.hpp"
-#include "Reorder.hpp"
-#include "Around.hpp"
-#include "ChareStateCollector.hpp"
-
-extern tk::CProxy_ChareStateCollector stateProxy;
-
-using inciter::Ghosts;
-
-Ghosts::Ghosts( const CProxy_Discretization& disc,
-  const std::map< int, std::vector< std::size_t > >& bface,
-  const std::vector< std::size_t >& triinpoel,
-  std::size_t nunk,
-  CkCallback cbDone ) :
-  m_disc( disc ),
-  m_nunk( nunk ),
-  m_inpoel( Disc()->Inpoel() ),
-  m_coord( Disc()->Coord() ),
-  m_fd( m_inpoel, bface, tk::remap(triinpoel,Disc()->Lid()) ),
-  m_geoFace( tk::genGeoFaceTri( m_fd.Nipfac(), m_fd.Inpofa(), m_coord) ),
-  m_geoElem( tk::genGeoElemTet( m_inpoel, m_coord ) ),
-  m_nfac( m_fd.Inpofa().size()/3 ),
-  m_bndFace(),
-  m_sendGhost(),
-  m_ghost(),
-  m_exptGhost(),
-  m_bid(),
-  m_esup(),
-  m_initial( 1 ),
-  m_ncomfac( 0 ),
-  m_nadj( 0 ),
-  m_ncomEsup( 0 ),
-  m_ipface(),
-  m_ghostData(),
-  m_ghostReq( 0 ),
-  m_expChBndFace(),
-  m_infaces(),
-  m_esupc(),
-  m_cbAfterDone( cbDone )
-// *****************************************************************************
-//  Constructor
-//! \param[in] disc Discretization proxy
-//! \param[in] bface Boundary-faces mapped to side set ids
-//! \param[in] triinpoel Boundary-face connectivity
-//! \param[in] nunk Number of unknowns
-//! \param[in] cbDone Function to continue with when Ghosts have been computed
-// *****************************************************************************
-{
-  if (g_inputdeck.get< tag::cmd, tag::chare >() ||
-      g_inputdeck.get< tag::cmd, tag::quiescence >())
-    stateProxy.ckLocalBranch()->insert( "Ghosts", thisIndex, CkMyPe(), Disc()->It(),
-                                        "Ghosts" );
-}
-
-void
-Ghosts::startCommSetup()
-// *****************************************************************************
-//  Start setup of communication maps for cell-centered schemes
-// *****************************************************************************
-{
-  // Ensure that mesh partition is not leaky
-  Assert( !tk::leakyPartition(m_fd.Esuel(), m_inpoel, m_coord),
-    "Input mesh to Ghosts leaky" );
-
-  // Ensure mesh physical boundary for the entire problem not leaky,
-  // effectively checking if the user has specified boundary conditions on all
-  // physical boundary faces
-  bndIntegral();
-}
-
-void
-Ghosts::bndIntegral()
-// *****************************************************************************
-//  Compute partial boundary surface integral and sum across all chares
-//! \details This function computes a partial surface integral over the boundary
-//!   of the faces of this mesh partition then sends its contribution to perform
-//!   the integral acorss the total problem boundary. After the global sum a
-//!   non-zero vector result indicates a leak, e.g., a hole in the boundary
-//!   which indicates an error in the boundary face data structures used to
-//!   compute the partial surface integrals.
-// *****************************************************************************
-{
-  // Storage for surface integral over our mesh chunk physical boundary
-  std::vector< tk::real > s{{ 0.0, 0.0, 0.0 }};
-
-  // Integrate over all physical boundary faces
-  for (std::size_t f=0; f<m_fd.Nbfac(); ++f) {
-    s[0] += m_geoFace(f,0) * m_geoFace(f,1);
-    s[1] += m_geoFace(f,0) * m_geoFace(f,2);
-    s[2] += m_geoFace(f,0) * m_geoFace(f,3);
-  }
-
-  s.push_back( 1.0 );  // positive: call-back to resizeComm() after reduction
-  s.push_back( static_cast< tk::real >( Disc()->MeshId() ) );
-
-  // Send contribution to host summing partial surface integrals
-  contribute( s, CkReduction::sum_double,
-    CkCallback(CkReductionTarget(Transporter,bndint), Disc()->Tr()) );
-}
-
-void
-Ghosts::resizeComm()
-// *****************************************************************************
-//  Start sizing communication buffers and setting up ghost data
-// *****************************************************************************
-{
-  // Enable SDAG wait for setting up chare boundary faces
-  thisProxy[ thisIndex ].wait4fac();
-
-  auto d = Disc();
-
-  const auto& gid = d->Gid();
-  const auto& inpofa = m_fd.Inpofa();
-  const auto& esuel = m_fd.Esuel();
-
-  // Perform leak test on mesh partition
-  Assert( !tk::leakyPartition( esuel, m_inpoel, m_coord ),
-          "Mesh partition leaky" );
-
-  // Activate SDAG waits for face adjacency map (ghost data) calculation
-  thisProxy[ thisIndex ].wait4ghost();
-  thisProxy[ thisIndex ].wait4esup();
+  \details   Data and functionality common to all discretization schemes
+  \see       Discretization.h and Discretization.C for more info.
+*/
+// *****************************************************************************
+
+#include "Tags.hpp"
+#include "Reorder.hpp"
+#include "Vector.hpp"
+#include "DerivedData.hpp"
+#include "Discretization.hpp"
+#include "MeshWriter.hpp"
+#include "DiagWriter.hpp"
+#include "Inciter/InputDeck/InputDeck.hpp"
+#include "Inciter/Options/Scheme.hpp"
+#include "Print.hpp"
+#include "Around.hpp"
+#include "QuinoaBuildConfig.hpp"
+#include "ConjugateGradients.hpp"
+#include "ALE.hpp"
+
+#include "M2MTransfer.hpp"
+
+namespace inciter {
+
+static CkReduction::reducerType PDFMerger;
+extern ctr::InputDeck g_inputdeck;
+extern ctr::InputDeck g_inputdeck_defaults;
+
+} // inciter::
+
+using inciter::Discretization;
+
+Discretization::Discretization(
+  std::size_t meshid,
+  const std::vector< CProxy_Discretization >& disc,
+  const CProxy_ALE& aleproxy,
+  const tk::CProxy_ConjugateGradients& conjugategradientsproxy,
+  const CProxy_Transporter& transporter,
+  const tk::CProxy_MeshWriter& meshwriter,
+  const tk::UnsMesh::CoordMap& coordmap,
+  const tk::UnsMesh::Chunk& el,
+  const tk::CommMaps& msum,
+  const std::map< int, std::vector< std::size_t > >& bface,
+  const std::vector< std::size_t >& triinpoel,
+  const std::unordered_map< std::size_t, std::set< std::size_t > >& elemblockid,
+  int nc ) :
+  m_meshid( meshid ),
+  m_transfer( g_inputdeck.get< tag::transfer >() ),
+  m_disc( disc ),
+  m_nchare( nc ),
+  m_it( 0 ),
+  m_itr( 0 ),
+  m_itf( 0 ),
+  m_initial( 1 ),
+  m_t( g_inputdeck.get< tag::t0 >() ),
+  m_lastDumpTime( -std::numeric_limits< tk::real >::max() ),
+  m_physFieldFloor( 0.0 ),
+  m_physHistFloor( 0.0 ),
+  m_rangeFieldFloor( 0.0 ),
+  m_rangeHistFloor( 0.0 ),
+  m_dt( g_inputdeck.get< tag::dt >() ),
+  m_dtn( m_dt ),
+  m_nvol( 0 ),
+  m_nxfer( 0 ),
+  m_ale( aleproxy ),
+  m_transporter( transporter ),
+  m_meshwriter( meshwriter ),
+  m_el( el ),     // fills m_inpoel, m_gid, m_lid
+  m_coord( setCoord( coordmap ) ),
+  m_coordn( m_coord ),
+  m_nodeCommMap(),
+  m_edgeCommMap(),
+  m_meshvol( 0.0 ),
+  m_v( m_gid.size(), 0.0 ),
+  m_vol( m_gid.size(), 0.0 ),
+  m_volc(),
+  m_voln( m_vol ),
+  m_vol0( m_inpoel.size()/4, 0.0 ),
+  m_bid(),
+  m_timer(),
+  m_refined( 0 ),
+  m_prevstatus( std::chrono::high_resolution_clock::now() ),
+  m_nrestart( 0 ),
+  m_histdata(),
+  m_nsrc( 0 ),
+  m_ndst( 0 ),
+  m_meshvel( 0, 3 ),
+  m_meshvel_converged( true ),
+  m_bface( bface ),
+  m_triinpoel( triinpoel ),
+  m_elemblockid( elemblockid )
+// *****************************************************************************
+//  Constructor
+//! \param[in] meshid Mesh ID
+//! \param[in] disc All Discretization proxies (one per mesh)
+//! \param[in] aleproxy Distributed ALE proxy
+//! \param[in] conjugategradientsproxy Distributed Conjugrate Gradients linear
+//!   solver proxy
+//! \param[in] transporter Host (Transporter) proxy
+//! \param[in] meshwriter Mesh writer proxy
+//! \param[in] coordmap Coordinates of mesh nodes and their global IDs
+//! \param[in] el Elements of the mesh chunk we operate on
+//! \param[in] msum Communication maps associated to chare IDs bordering the
+//!   mesh chunk we operate on
+//! \param[in] bface Face lists mapped to side set ids
+//! \param[in] triinpoel Interconnectivity of points and boundary-faces
+//! \param[in] elemblockid Local tet ids associated with mesh block ids
+//! \param[in] nc Total number of Discretization chares
+// *****************************************************************************
+{
+  Assert( !m_inpoel.empty(), "No elements assigned to Discretization chare" );
+  Assert( tk::positiveJacobians( m_inpoel, m_coord ),
+          "Jacobian in input mesh to Discretization non-positive" );
+  #if not defined(__INTEL_COMPILER) || defined(NDEBUG)
+  // The above ifdef skips running the conformity test with the intel compiler
+  // in debug mode only. This is necessary because in tk::conforming(), filling
+  // up the map can fail with some meshes (only in parallel), e.g., tube.exo,
+  // used by some regression tests, due to the intel compiler generating some
+  // garbage incorrect code - only in debug, only in parallel, only with that
+  // mesh.
+  Assert( tk::conforming( m_inpoel, m_coord ),
+          "Input mesh to Discretization not conforming" );
+  #endif
+
+  // Store communication maps
+  for (const auto& [ c, maps ] : msum) {
+    m_nodeCommMap[c] = maps.get< tag::node >();
+    m_edgeCommMap[c] = maps.get< tag::edge >();
+  }
 
-  // Invert inpofa to enable searching for faces based on (global) node triplets
-  Assert( inpofa.size() % 3 == 0, "Inpofa must contain triplets" );
-  for (std::size_t f=0; f<inpofa.size()/3; ++f)
-    m_ipface.insert( {{{ gid[ inpofa[f*3+0] ],
-                         gid[ inpofa[f*3+1] ],
-                         gid[ inpofa[f*3+2] ] }}} );
-
-  // At this point ipface has node-id-triplets (faces) on the internal
-  // chare-domain and on the physical boundary but not on chare boundaries,
-  // hence the name internal + physical boundary faces.
-
-  // Build a set of faces (each face given by 3 global node IDs) associated to
-  // chares we potentially share boundary faces with.
-  tk::UnsMesh::FaceSet potbndface;
-  for (std::size_t e=0; e<esuel.size()/4; ++e) {   // for all our tets
-    auto mark = e*4;
-    for (std::size_t f=0; f<4; ++f)     // for all tet faces
-      if (esuel[mark+f] == -1) {        // if face has no outside-neighbor tet
-        // if does not exist among the internal and physical boundary faces,
-        // store as a potential chare-boundary face
-        tk::UnsMesh::Face t{{ gid[ m_inpoel[ mark + tk::lpofa[f][0] ] ],
-                              gid[ m_inpoel[ mark + tk::lpofa[f][1] ] ],
-                              gid[ m_inpoel[ mark + tk::lpofa[f][2] ] ] }};
-        if (m_ipface.find(t) == end(m_ipface)) {
-          Assert( m_expChBndFace.insert(t).second,
-                  "Store expected chare-boundary face" );
-          potbndface.insert( t );
-        }
-      }
-  }
-
-  if ( g_inputdeck.get< tag::cmd, tag::feedback >() ) d->Tr().chbndface();
-
-  // In the following we assume that the size of the (potential) boundary-face
-  // adjacency map above does not necessarily equal to that of the node
-  // adjacency map. This is because while a node can be shared at a single
-  // corner or along an edge, that does not necessarily share a face as well
-  // (in other words, shared nodes or edges can exist that are not part of a
-  // shared face). So the chares we communicate with across faces are not
-  // necessarily the same as the chares we would communicate nodes with.
-  //
-  // Since the sizes of the node and face adjacency maps are not the same, while
-  // sending the faces on chare boundaries would be okay, however, the receiver
-  // would not necessarily know how many chares it must receive from. To solve
-  // this problem we send to chares which we share at least a single node with,
-  // i.e., rely on the node-adjacency map. Note that to all chares we share at
-  // least a single node with we send all our potential chare-boundary faces.
-  // This is the same list of faces to all chares we send.
-  //
-  // Another underlying assumption here is, of course, that the size of the face
-  // adjacency map is always smaller than or equal to that of the node adjacency
-  // map, which is always true. Since the receive side already knows how many
-  // fellow chares it must receive shared node ids from, we use that to detect
-  // completion of the number of receives in comfac(). This simplifies the
-  // communication pattern and code.
-
-  // Send sets of faces adjacent to chare boundaries to fellow workers (if any)
-  if (d->NodeCommMap().empty())  // in serial, skip setting up ghosts altogether
-    faceAdj();
-  else
-    // for all chares we share nodes with
-    for (const auto& c : d->NodeCommMap()) {
-      thisProxy[ c.first ].comfac( thisIndex, potbndface );
-    }
-
-  ownfac_complete();
-}
-
-void
-Ghosts::comfac( int fromch, const tk::UnsMesh::FaceSet& infaces )
-// *****************************************************************************
-//  Receive unique set of faces we potentially share with/from another chare
-//! \param[in] fromch Sender chare id
-//! \param[in] infaces Unique set of faces we potentially share with fromch
-// *****************************************************************************
-{
-  if (g_inputdeck.get< tag::cmd, tag::chare >() ||
-      g_inputdeck.get< tag::cmd, tag::quiescence >())
-    stateProxy.ckLocalBranch()->insert( "Ghosts", thisIndex, CkMyPe(), Disc()->It(),
-                                        "comfac" );
-
-  // Buffer up incoming data
-  m_infaces[ fromch ] = infaces;
-
-  // if we have heard from all fellow chares that we share at least a single
-  // node, edge, or face with
-  if (++m_ncomfac == Disc()->NodeCommMap().size()) {
-    m_ncomfac = 0;
-    comfac_complete();
-  }
-}
-
-void
-Ghosts::bndFaces()
-// *****************************************************************************
-// Compute chare-boundary faces
-//! \details This is called when both send and receives are completed on a
-//!  chare and thus we are ready to compute chare-boundary faces and ghost data.
-// *****************************************************************************
-{
-  auto d = Disc();
-  if ( g_inputdeck.get< tag::cmd, tag::feedback >() ) d->Tr().chcomfac();
-  const auto& esuel = m_fd.Esuel();
-  const auto& gid = d->Gid();
-
-  for (const auto& in : m_infaces) {
-    // Find sender chare among chares we potentially share faces with. Note that
-    // it is feasible that a sender chare called us but we do not have a set of
-    // faces associated to that chare. This can happen if we only share a single
-    // node or an edge but not a face with that chare.
-    auto& bndface = m_bndFace[ in.first ];  // will associate to sender chare
-    // Try to find incoming faces on our chare boundary with other chares. If
-    // found, generate and assign new local face ID, associated to sender chare.
-    for (std::size_t e=0; e<esuel.size()/4; ++e) {  // for all our tets
-      auto mark = e*4;
-      for (std::size_t f=0; f<4; ++f) {  // for all cell faces
-        if (esuel[mark+f] == -1) {  // if face has no outside-neighbor tet
-          tk::UnsMesh::Face t{{ gid[ m_inpoel[ mark + tk::lpofa[f][0] ] ],
-                                gid[ m_inpoel[ mark + tk::lpofa[f][1] ] ],
-                                gid[ m_inpoel[ mark + tk::lpofa[f][2] ] ] }};
-          // if found among the incoming faces and if not one of our internal
-          // nor physical boundary faces
-          if ( in.second.find(t) != end(in.second) &&
-               m_ipface.find(t) == end(m_ipface) ) {
-            bndface[t][0] = m_nfac++;    // assign new local face ID
-          }
-        }
-      }
-    }
-    // If at this point if we have not found any face among our faces we
-    // potentially share with fromch, there is no need to keep an empty set of
-    // faces associated to fromch as we only share nodes or edges with it, but
-    // not faces.
-    if (bndface.empty()) m_bndFace.erase( in.first );
-  }
+  // Get ready for computing/communicating nodal volumes
+  startvol();
+
+  // Get chare-boundary node-id map
+  m_bid = genBid();
+
+  // Find host elements of user-specified points where time histories are
+  // saved, and save the shape functions evaluated at the point locations
+  const auto& pt = g_inputdeck.get< tag::history_output, tag::point >();
+  for (std::size_t p=0; p<pt.size(); ++p) {
+    std::array< tk::real, 4 > N;
+    const auto& l = pt[p].get< tag::coord >();
+    const auto& id = pt[p].get< tag::id >();
+    for (std::size_t e=0; e<m_inpoel.size()/4; ++e) {
+      if (tk::intet( m_coord, m_inpoel, l, e, N )) {
+        m_histdata.push_back( HistData{{ id, e, {l[0],l[1],l[2]}, N }} );
+        break;
+      }
+    }
+  }
+
+  // Insert ConjugrateGradients solver chare array element if needed
+  if (g_inputdeck.get< tag::ale, tag::ale >()) {
+    m_ale[ thisIndex ].insert( conjugategradientsproxy,
+                               m_coord, m_inpoel,
+                               m_gid, m_lid, m_nodeCommMap );
+  } else {
+    m_meshvel.resize( m_gid.size() );
+  }
+
+  // Register mesh with mesh-transfer lib
+  if (m_disc.size() == 1 || m_transfer.empty()) {
+    // skip transfer if single mesh or if not involved in coupling
+    transferInit();
+  } else {
+    if (thisIndex == 0) {
+      exam2m::addMesh( thisProxy, m_nchare,
+        CkCallback( CkIndex_Discretization::transferInit(), thisProxy ) );
+      //std::cout << "Disc: " << m_meshid << " m2m::addMesh()\n";
+    }
+  }
+}
+
+std::unordered_map< std::size_t, std::size_t >
+Discretization::genBid()
+// *****************************************************************************
+// Generate the Bid data-structure based on the node communication-map
+// *****************************************************************************
+{
+  // Count the number of mesh nodes at which we receive data from other chares
+  // and compute map associating boundary-chare node ID to global node ID
+  std::vector< std::size_t > c( tk::sumvalsize( m_nodeCommMap ) );
+  std::size_t j = 0;
+  for (const auto& [ch,n] : m_nodeCommMap) for (auto i : n) c[j++] = i;
+  tk::unique( c );
+  return tk::assignLid( c );
+}
+
+void
+Discretization::transferInit()
+// *****************************************************************************
+// Our mesh has been registered with the mesh-to-mesh transfer library (if
+// coupled to other solver)
+// *****************************************************************************
+{
+  // Compute number of mesh points owned
+  std::size_t npoin = m_gid.size();
+  for (auto g : m_gid) if (tk::slave(m_nodeCommMap,g,thisIndex)) --npoin;
+
+  // Tell the RTS that the Discretization chares have been created and compute
+  // the total number of mesh points across the distributed mesh
+  std::vector< std::size_t > meshdata{ m_meshid, npoin };
+  contribute( meshdata, CkReduction::sum_ulong,
+    CkCallback( CkReductionTarget(Transporter,disccreated), m_transporter ) );
+}
+
+void
+Discretization::meshvelStart(
+  const tk::UnsMesh::Coords vel,
+  const std::vector< tk::real >& soundspeed,
+  const std::unordered_map< int,
+    std::unordered_map< std::size_t, std::array< tk::real, 4 > > >& bnorm,
+  tk::real adt,
+  CkCallback done ) const
+// *****************************************************************************
+// Start computing new mesh velocity for ALE mesh motion
+//! \param[in] vel Fluid velocity at mesh nodes
+//! \param[in] soundspeed Speed of sound at mesh nodes
+//! \param[in] bnorm Face normals in boundary points associated to side sets
+//! \param[in] adt alpha*dt of the RK time step
+//! \param[in] done Function to continue with when mesh velocity has been
+//!   computed
+// *****************************************************************************
+{
+  if (g_inputdeck.get< tag::ale, tag::ale >())
+    m_ale[ thisIndex ].ckLocal()->start( vel, soundspeed, done,
+      m_coord, m_coordn, m_vol0, m_vol, bnorm, m_initial, m_it, m_t, adt );
+  else
+    done.send();
+}
+
+const tk::Fields&
+Discretization::meshvel() const
+// *****************************************************************************
+//! Query the mesh velocity
+//! \return Mesh velocity
+// *****************************************************************************
+{
+  if (g_inputdeck.get< tag::ale, tag::ale >())
+    return m_ale[ thisIndex ].ckLocal()->meshvel();
+  else
+    return m_meshvel;
+}
+
+void
+Discretization::meshvelBnd(
+  const std::map< int, std::vector< std::size_t > >& bface,
+  const std::map< int, std::vector< std::size_t > >& bnode,
+  const std::vector< std::size_t >& triinpoel) const
+// *****************************************************************************
+// Query ALE mesh velocity boundary condition node lists and node lists at
+// which ALE moves boundaries
+// *****************************************************************************
+{
+  if (g_inputdeck.get< tag::ale, tag::ale >())
+    m_ale[ thisIndex ].ckLocal()->meshvelBnd( bface, bnode, triinpoel );
+}
+
+void
+Discretization::meshvelConv()
+// *****************************************************************************
+//! Assess and record mesh velocity linear solver convergence
+// *****************************************************************************
+{
+  auto smoother = g_inputdeck.get< tag::ale, tag::smoother >();
 
-  tk::destroy(m_ipface);
-  tk::destroy(m_infaces);
-
-  // Ensure all expected faces have been received
-  Assert( receivedChBndFaces(),
-    "Expected and received chare boundary faces mismatch" );
-
-  // Basic error checking on chare-boundary-face map
-  Assert( m_bndFace.find( thisIndex ) == m_bndFace.cend(),
-          "Face-communication map should not contain data for own chare ID" );
-
-  // Store (local) tet ID adjacent to our chare boundary from the inside
-  for (std::size_t e=0; e<esuel.size()/4; ++e) {  // for all our tets
-    auto mark = e*4;
-    for (std::size_t f=0; f<4; ++f) {  // for all cell faces
-      if (esuel[mark+f] == -1) {  // if face has no outside-neighbor tet
-        tk::UnsMesh::Face t{{ gid[ m_inpoel[ mark + tk::lpofa[f][0] ] ],
-                              gid[ m_inpoel[ mark + tk::lpofa[f][1] ] ],
-                              gid[ m_inpoel[ mark + tk::lpofa[f][2] ] ] }};
-        auto c = findchare(t);
-        if (c > -1) {
-          auto& lbndface = tk::ref_find( m_bndFace, c );
-          auto& face = tk::ref_find( lbndface, t );
-          face[1] = e;  // store (local) inner tet ID adjacent to face
-        }
-      }
-    }
-  }
-
-  // At this point m_bndFace is complete on this PE. This means that starting
-  // from the sets of faces we potentially share with fellow chares we now
-  // only have those faces we actually share faces with (through which we need
-  // to communicate later). Also, m_bndFace not only has the unique faces
-  // associated to fellow chares, but also a newly assigned local face ID as
-  // well as the local id of the inner tet adjacent to the face. Continue by
-  // starting setting up ghost data
-  setupGhost();
-  // Besides setting up our own ghost data, we also issue requests (for ghost
-  // data) to those chares which we share faces with. Note that similar to
-  // comfac() we are calling reqGhost() by going through the node communication
-  // map instead, which may send requests to those chare we do not share faces
-  // with. This is so that we can test for completing by querying the size of
-  // the already complete node commincation map in reqGhost. Requests in
-  // sendGhost will only be fullfilled based on m_ghostData.
-  for (const auto& c : d->NodeCommMap())  // for all chares we share nodes with
-    thisProxy[ c.first ].reqGhost();
-}
-
-void
-Ghosts::setupGhost()
-// *****************************************************************************
-// Setup own ghost data on this chare
-// *****************************************************************************
-{
-  auto d = Disc();
-  const auto& gid = d->Gid();
-
-  // Enlarge elements surrounding faces data structure for ghosts
-  m_fd.Esuf().resize( 2*m_nfac, -2 );
-  m_fd.Inpofa().resize( 3*m_nfac, 0 );
-  // Enlarge face geometry data structure for ghosts
-  m_geoFace.resize( m_nfac, 0.0 );
-
-  const auto& esuel = m_fd.Esuel();
-
-  // Collect tet ids, their face connectivity (given by 3 global node IDs, each
-  // triplet for potentially multiple faces on the chare boundary), and their
-  // elem geometry data (see GhostData) associated to fellow chares adjacent to
-  // chare boundaries. Once received by fellow chares, these tets will become
-  // known as ghost elements and their data as ghost data.
-  for (std::size_t e=0; e<esuel.size()/4; ++e) {  // for all our tets
-    auto mark = e*4;
-    for (std::size_t f=0; f<4; ++f) {  // for all cell faces
-      if (esuel[mark+f] == -1) {  // if face has no outside-neighbor tet
-        tk::UnsMesh::Face t{{ gid[ m_inpoel[ mark + tk::lpofa[f][0] ] ],
-                              gid[ m_inpoel[ mark + tk::lpofa[f][1] ] ],
-                              gid[ m_inpoel[ mark + tk::lpofa[f][2] ] ] }};
-        auto c = findchare(t);
-        // It is possible that we do not find the chare for this face. We are
-        // looping through all of our tets and interrogating all faces that do
-        // not have neighboring tets but we only care about chare-boundary faces
-        // here as only those need ghost data. (esuel may also contain
-        // physical boundary faces)
-        if (c > -1) {
-          // Will store ghost data associated to neighbor chare
-          auto& ghost = m_ghostData[ c ];
-          // Store tet id adjacent to chare boundary as key for ghost data
-          auto& tuple = ghost[ e ];
-          // If tetid e has not yet been encountered, store geometry (only once)
-          auto& nodes = std::get< 0 >( tuple );
-          if (nodes.empty()) {
-            std::get< 1 >( tuple ) = m_geoElem[ e ];
-
-            auto& ncoord = std::get< 2 >( tuple );
-            ncoord[0] = m_coord[0][ m_inpoel[ mark+f ] ];
-            ncoord[1] = m_coord[1][ m_inpoel[ mark+f ] ];
-            ncoord[2] = m_coord[2][ m_inpoel[ mark+f ] ];
-
-            std::get< 3 >( tuple ) = f;
-
-            std::get< 4 >( tuple ) = {{ gid[ m_inpoel[ mark ] ],
-                                        gid[ m_inpoel[ mark+1 ] ],
-                                        gid[ m_inpoel[ mark+2 ] ],
-                                        gid[ m_inpoel[ mark+3 ] ] }};
-          }
-          // (Always) store face node IDs on chare boundary, even if tetid e has
-          // already been stored. Thus we store potentially multiple faces along
-          // the same chare-boundary. This happens, e.g., when the boundary
-          // between chares is zig-zaggy enough to have 2 or even 3 faces of the
-          // same tet.
-          nodes.push_back( t[0] );
-          nodes.push_back( t[1] );
-          nodes.push_back( t[2] );
-          Assert( nodes.size() <= 4*3, "Overflow of faces/tet to send" );
-        }
-      }
-    }
-  }
-
-  // Basic error checking on local ghost data
-  Assert( m_ghostData.find( thisIndex ) == m_ghostData.cend(),
-          "Chare-node adjacency map should not contain data for own chare ID" );
+  if (g_inputdeck.get< tag::ale, tag::ale >() &&
+      (smoother == ctr::MeshVelocitySmootherType::LAPLACE or
+       smoother == ctr::MeshVelocitySmootherType::HELMHOLTZ))
+  {
+    m_meshvel_converged &= m_ale[ thisIndex ].ckLocal()->converged();
+  }
+}
+
+void
+Discretization::comfinal()
+// *****************************************************************************
+// Finish setting up communication maps and solution transfer callbacks
+// *****************************************************************************
+{
+  // Generate own subset of solver/mesh transfer list
+  for (const auto& t : m_transfer) {
+    if (t.src == m_meshid || t.dst == m_meshid) {
+      m_mytransfer.push_back( t );<--- Consider using std::copy_if algorithm instead of a raw loop.
+    }
+  }
+
+  // Signal the runtime system that the workers have been created
+  std::vector< std::size_t > meshdata{ /* initial = */ 1, m_meshid };
+  contribute( meshdata, CkReduction::sum_ulong,
+    CkCallback(CkReductionTarget(Transporter,comfinal), m_transporter) );
+}
+
+void
+Discretization::transfer(
+  tk::Fields& u,
+  std::size_t dirn,
+  CkCallback cb )
+// *****************************************************************************
+//  Start solution transfer (if coupled)
+//! \param[in,out] u Solution to transfer from/to
+//! \param[in] dirn Direction of solution transfer. 0: from background to
+//!   overset, 1: from overset to background
+//! \param[in] cb Callback to call when back and forth transfers complete.
+//! \details This function initiates the solution transfer (direction dependent
+//!   on 'dirn') between meshes. It invokes a reduction to Transporter when the
+//!   transfer in one direction is complete (dirn == 0), or calls back the
+//!   'cb' function in Scheme when transfers both directions are complete.
+//!   The function relies on 'dirn' to make this decision.
+// *****************************************************************************
+{
+  if (m_mytransfer.empty()) {   // skip transfer if not involved in coupling
+
+    cb.send();
+
+  } else {
+
+    m_transfer_complete = cb;
+
+    // determine source and destination mesh depending on direction of transfer
+    std::size_t fromMesh(0), toMesh(0);
+    CkCallback cb_xfer;
+    if (dirn == 0) {
+      fromMesh = m_mytransfer[m_nsrc].src;<--- Variable 'fromMesh' is assigned a value that is never used.
+      toMesh = m_mytransfer[m_ndst].dst;<--- Variable 'toMesh' is assigned a value that is never used.
+      cb_xfer = CkCallback( CkIndex_Discretization::to_complete(), thisProxy[thisIndex] );<--- Variable 'cb_xfer' is assigned a value that is never used.
+    }
+    else {
+      fromMesh = m_mytransfer[m_nsrc].dst;<--- Variable 'fromMesh' is assigned a value that is never used.
+      toMesh = m_mytransfer[m_ndst].src;<--- Variable 'toMesh' is assigned a value that is never used.
+      cb_xfer = CkCallback( CkIndex_Discretization::from_complete(), thisProxy[thisIndex] );<--- Variable 'cb_xfer' is assigned a value that is never used.
+    }
+
+    // Pass source and destination meshes to mesh transfer lib (if coupled)
+    Assert( m_nsrc < m_mytransfer.size(), "Indexing out of mytransfer[src]" );
+    if (fromMesh == m_meshid) {
+      exam2m::setSourceTets( thisProxy, thisIndex, &m_inpoel, &m_coord, u );
+      ++m_nsrc;
+    } else {
+      m_nsrc = 0;
+    }
+    Assert( m_ndst < m_mytransfer.size(), "Indexing out of mytransfer[dst]" );
+    if (toMesh == m_meshid) {
+      exam2m::setDestPoints( thisProxy, thisIndex, &m_coord, u,
+        cb_xfer );
+      ++m_ndst;<--- m_ndst is assigned
+    } else {
+      m_ndst = 0;
+    }
+
+  }
+
+  m_nsrc = 0;
+  m_ndst = 0;<--- m_ndst is overwritten
+}
+
+void Discretization::to_complete()
+// *****************************************************************************
+//! Solution transfer from background to overset mesh completed (from ExaM2M)
+//! \brief This is called by ExaM2M on the destination mesh when the
+//!   transfer completes. Since this is called only on the destination, we find
+//!   and notify the corresponding source of the completion.
+// *****************************************************************************
+{
+  // Lookup the source disc and notify it of completion
+  for (auto& t : m_transfer) {
+    if (m_meshid == t.dst) {
+      m_disc[ t.src ][ thisIndex ].transfer_complete();
+    }
+  }
+
+  thisProxy[ thisIndex ].transfer_complete();
+}
+
+void Discretization::from_complete()
+// *****************************************************************************
+//! Solution transfer from overset to background mesh completed (from ExaM2M)
+//! \brief This is called by ExaM2M on the destination mesh when the
+//!   transfer completes. Since this is called only on the destination, we find
+//!   and notify the corresponding source of the completion.
+// *****************************************************************************
+{
+  // Lookup the source disc and notify it of completion
+  for (auto& t : m_transfer) {
+    if (m_meshid == t.src) {
+      m_disc[ t.dst ][ thisIndex ].transfer_complete_from_dest();
+    }
+  }
 
-  // More in-depth error checking on local ghost data
-  for (const auto& c : m_ghostData)
-    for ([[maybe_unused]] const auto& t : c.second) {
-      Assert( !std::get< 0 >( t.second ).empty(),
-              "Emtpy face vector in ghost data" );
-      Assert( std::get< 0 >( t.second ).size() % 3 == 0,
-              "Face node IDs must be triplets" );
-      Assert( std::get< 0 >( t.second ).size() <= 4*3,    // <= 4*3 (4*numfaces)
-              "Max number of faces for a single ghost tet is 4" );
-      Assert( !std::get< 1 >( t.second ).empty(),
-              "No elem geometry data for ghost" );
-      Assert( std::get< 1 >( t.second ).size() == m_geoElem.nprop(),
-              "Elem geometry data for ghost must be for single tet" );
-      Assert( !std::get< 2 >( t.second ).empty(),
-              "No nodal coordinate data for ghost" );
-    }
-
-  ownghost_complete();
-}
-
-void
-Ghosts::reqGhost()
-// *****************************************************************************
-// Receive requests for ghost data
-// *****************************************************************************
-{
-  if (g_inputdeck.get< tag::cmd, tag::chare >() ||
-      g_inputdeck.get< tag::cmd, tag::quiescence >())
-    stateProxy.ckLocalBranch()->insert( "Ghosts", thisIndex, CkMyPe(), Disc()->It(),
-                                        "reqGhost" );
-
-  // If every chare we communicate with has requested ghost data from us, we may
-  // fulfill the requests, but only if we have already setup our ghost data.
-  if (++m_ghostReq == Disc()->NodeCommMap().size()) {
-    m_ghostReq = 0;
-    reqghost_complete();
-  }
-}
+  m_transfer_complete.send();
+}
+
+void Discretization::transfer_complete_from_dest()
+// *****************************************************************************
+//! Solution transfer completed (from dest Discretization)
+//! \details Called on the source only by the destination when a back and forth
+//!   transfer step completes.
+// *****************************************************************************
+{
+  m_transfer_complete.send();
+}
+
+void Discretization::transfer_complete()
+// *****************************************************************************
+//! Solution transfer completed (one-way)
+//! \note Single exit point after solution transfer between meshes
+// *****************************************************************************
+{
+  contribute( sizeof(nullptr), nullptr, CkReduction::nop,
+    CkCallback(CkReductionTarget(Transporter,solutionTransferred),
+    m_transporter) );
+}
+
+std::vector< std::size_t >
+Discretization::bndel() const
+// *****************************************************************************
+// Find elements along our mesh chunk boundary
+//! \return List of local element ids that have at least a single node
+//!   contributing to a chare boundary
+// *****************************************************************************
+{
+  // Lambda to find out if a mesh node is shared with another chare
+  auto shared = [this]( std::size_t i ){
+    for (const auto& [c,n] : m_nodeCommMap)
+      if (n.find(i) != end(n)) return true;
+    return false;
+  };
 
-void
-Ghosts::sendGhost()
-// *****************************************************************************
-// Send all of our ghost data to fellow chares
-// *****************************************************************************
-{
-  if (g_inputdeck.get< tag::cmd, tag::chare >() ||
-      g_inputdeck.get< tag::cmd, tag::quiescence >())
-    stateProxy.ckLocalBranch()->insert( "Ghosts", thisIndex, CkMyPe(), Disc()->It(),
-                                        "sendGhost" );
-
-  for (const auto& c : m_ghostData)
-    thisProxy[ c.first ].comGhost( thisIndex, c.second );
-
-  if ( g_inputdeck.get< tag::cmd, tag::feedback >() ) Disc()->Tr().chghost();
-}
-
-void
-Ghosts::comGhost( int fromch, const GhostData& ghost )
-// *****************************************************************************
-// Receive ghost data on chare boundaries from fellow chare
-//! \param[in] fromch Caller chare ID
-//! \param[in] ghost Ghost data, see Inciter/FaceData.h for the type
-// *****************************************************************************
-{
-  if (g_inputdeck.get< tag::cmd, tag::chare >() ||
-      g_inputdeck.get< tag::cmd, tag::quiescence >())
-    stateProxy.ckLocalBranch()->insert( "Ghosts", thisIndex, CkMyPe(), Disc()->It(),
-                                        "comGhost" );
-
-  auto d = Disc();
-  const auto& lid = d->Lid();
-  auto& inpofa = m_fd.Inpofa();
-  auto ncoord = m_coord[0].size();<--- Variable 'ncoord' is assigned a value that is never used.
-
-  // nodelist with fromch, currently only used for an assert
-  [[maybe_unused]] const auto& nl = tk::cref_find( d->NodeCommMap(), fromch );
-
-  auto& ghostelem = m_ghost[ fromch ];  // will associate to sender chare
-
-  // Store ghost data coming from chare
-  for (const auto& g : ghost) {  // loop over incoming ghost data
-    auto e = g.first;  // remote/ghost tet id outside of chare boundary<--- Variable 'e' is assigned a value that is never used.
-    const auto& nodes = std::get< 0 >( g.second );  // node IDs of face(s)
-    const auto& geo = std::get< 1 >( g.second );    // ghost elem geometry data
-    const auto& coordg = std::get< 2 >( g.second );  // coordinate of ghost node
-    const auto& inpoelg = std::get< 4 >( g.second ); // inpoel of ghost tet
+  // Find elements along our mesh chunk boundary
+  std::vector< std::size_t > e;
+  for (std::size_t n=0; n<m_inpoel.size(); ++n)
+    if (shared( m_gid[ m_inpoel[n] ] )) e.push_back( n/4 );
+  tk::unique( e );
+
+  return e;
+}
+
+void
+Discretization::resizePostAMR(
+  const tk::UnsMesh::Chunk& chunk,
+  const tk::UnsMesh::Coords& coord,
+  const std::unordered_map< std::size_t, std::size_t >& /*amrNodeMap*/,
+  const tk::NodeCommMap& nodeCommMap,
+  const std::set< std::size_t >& /*removedNodes*/,
+  const std::unordered_map< std::size_t, std::set< std::size_t > >& elemblockid )
+// *****************************************************************************
+//  Resize mesh data structures after mesh refinement
+//! \param[in] chunk New mesh chunk (connectivity and global<->local id maps)
+//! \param[in] coord New mesh node coordinates
+//! \param[in] amrNodeMap Node id map after amr (local ids)
+//! \param[in] nodeCommMap New node communication map
+//! \param[in] removedNodes Newly removed mesh node local ids
+//! \param[in] elemblockid New local tet ids associated with mesh block ids
+// *****************************************************************************
+{
+  m_el = chunk;         // updates m_inpoel, m_gid, m_lid
+  m_nodeCommMap.clear();
+  m_nodeCommMap = nodeCommMap;        // update node communication map
+  m_elemblockid.clear();
+  m_elemblockid = elemblockid;
+
+  // Update mesh volume container size
+  m_vol.resize( m_gid.size(), 0.0 );
+  if (!m_voln.empty()) m_voln.resize( m_gid.size(), 0.0 );
+
+  // Regenerate bid data
+  tk::destroy(m_bid);
+  m_bid = genBid();
+
+  // update mesh node coordinates
+  m_coord = coord;
+
+  // we are no longer during setup
+  m_initial = 0;
+}
 
-    Assert( nodes.size() % 3 == 0, "Face node IDs must be triplets" );
-    Assert( nodes.size() <= 4*3, "Overflow of faces/tet received" );
-    Assert( geo.size() % 5 == 0, "Ghost geometry size mismatch" );
-    Assert( geo.size() == m_geoElem.nprop(), "Ghost geometry number mismatch" );
-    Assert( coordg.size() == 3, "Incorrect ghost node coordinate size" );
-    Assert( inpoelg.size() == 4, "Incorrect ghost inpoel size" );
-
-    for (std::size_t n=0; n<nodes.size()/3; ++n) {  // face(s) of ghost e
-      // node IDs of face on chare boundary
-      tk::UnsMesh::Face t{{ nodes[n*3+0], nodes[n*3+1], nodes[n*3+2] }};
-      // must find t in nodelist of chare-boundary adjacent to fromch
-      Assert( nl.find(t[0]) != end(nl) &&
-              nl.find(t[1]) != end(nl) &&
-              nl.find(t[2]) != end(nl),
-           "Ghost face not found in chare-node adjacency map on receiving end" );
-      // must find face in boundary-face adjacency map for fromch
-      Assert( tk::cref_find(m_bndFace,fromch).find( t ) !=
-              tk::cref_find(m_bndFace,fromch).cend(), "Ghost face not "
-              "found in boundary-face adjacency map on receiving end" );
-      // find local face & tet ids for t
-      auto id = tk::cref_find( tk::cref_find(m_bndFace,fromch), t );
-      // compute face geometry for chare-boundary face
-      addGeoFace(t, id);
-      // add node-triplet to node-face connectivity
-      inpofa[3*id[0]+0] = tk::cref_find( lid, t[2] );
-      inpofa[3*id[0]+1] = tk::cref_find( lid, t[1] );
-      inpofa[3*id[0]+2] = tk::cref_find( lid, t[0] );
-
-      // if ghost tet id not yet encountered on boundary with fromch
-      auto i = ghostelem.find( e );
-      if (i != end(ghostelem)) {
-        // fill in elements surrounding face
-        addEsuf(id, i->second);
-        // fill in elements surrounding element
-        addEsuel(id, i->second, t);
-      } else {
-        // fill in elements surrounding face
-        addEsuf(id, m_nunk);
-        // fill in elements surrounding element
-        addEsuel(id, m_nunk, t);
-        ghostelem[e] = m_nunk;     // assign new local tet id to remote ghost id
-        m_geoElem.push_back( geo );// store ghost elem geometry
-        ++m_nunk;                  // increase number of unknowns on this chare
-        std::size_t counter = 0;
-        for (std::size_t gp=0; gp<4; ++gp) {
-          auto it = lid.find( inpoelg[gp] );
-          std::size_t lp;
-          if (it != end(lid))
-            lp = it->second;
-          else {
-            Assert( nodes.size() == 3, "Expected node not found in lid" );
-            Assert( gp == std::get< 3 >( g.second ),
-                    "Ghost node not matching correct entry in ghost inpoel" );
-            lp = ncoord;
-            ++counter;
-          }
-          m_inpoel.push_back( lp );       // store ghost element connectivity
-        }
-        // only a single or no ghost node should be found
-        Assert( counter <= 1, "Incorrect number of ghost nodes detected. "
-                "Detected "+ std::to_string(counter) +" ghost nodes" );
-        if (counter == 1) {
-          m_coord[0].push_back( coordg[0] ); // store ghost node coordinate
-          m_coord[1].push_back( coordg[1] );
-          m_coord[2].push_back( coordg[2] );
-          Assert( m_inpoel[ 4*(m_nunk-1)+std::get< 3 >( g.second ) ] == ncoord,
-                  "Mismatch in extended inpoel for ghost element" );
-          ++ncoord;                // increase number of nodes on this chare<--- Variable 'ncoord' is assigned a value that is never used.
-        }
-      }
-
-      // additional tests to ensure that entries in inpoel and t/inpofa match
-      Assert( nodetripletMatch(id, t) == 3,
-        "Mismatch/Overmatch in inpoel and inpofa at chare-boundary face" );
-    }
-  }
-
-  // Signal the runtime system that all workers have received their
-  // face-adjacency
-  if (++m_nadj == m_ghostData.size()) faceAdj();
-}
-
-void
-Ghosts::faceAdj()
-// *****************************************************************************
-// Continue after face adjacency communication map completed on this chare
-//! \details At this point the face communication map has been established
-//!    on this chare. Proceed to set up the nodal-comm map.
-// *****************************************************************************
-{
-  m_nadj = 0;
-
-  tk::destroy(m_bndFace);
-
-  // Ensure that all elements surrounding faces (are correct) including those at
-  // chare boundaries
-  for (std::size_t f=0; f<m_nfac; ++f) {
-    Assert( m_fd.Esuf()[2*f] > -1,
-            "Left element in esuf cannot be physical ghost" );
-    if (f >= m_fd.Nbfac())
-      Assert( m_fd.Esuf()[2*f+1] > -1,
-           "Right element in esuf for internal/chare faces cannot be a ghost" );
-  }
-
-  // Ensure that all elements surrounding elements are correct including those
-  // at chare boundaries
-  const auto& esuel = m_fd.Esuel();
-  std::size_t nbound = 0;
-  for (std::size_t e=0; e<esuel.size()/4; ++e) {
-    for (std::size_t f=0; f<4; ++f)
-      if (esuel[4*e+f] == -1) ++nbound;
-  }
-  Assert( nbound == m_fd.Nbfac(), "Incorrect number of ghost-element -1's in "
-         "updated esuel" );
-
-  // Error checking on ghost data
-  for(const auto& n : m_ghostData)
-    for([[maybe_unused]] const auto& i : n.second)
-      Assert( i.first < m_fd.Esuel().size()/4, "Sender contains ghost tet id " );
-
-  // Perform leak test on face geometry data structure enlarged by ghosts
-  Assert( !leakyAdjacency(), "Face adjacency leaky" );
-  Assert( faceMatch(), "Chare-boundary element-face "
-    "connectivity (esuf) does not match" );
-
-  // Create new map of elements along chare boundary which are ghosts for
-  // neighboring chare, associated with that chare ID
-  for (const auto& [cid, cgd] : m_ghostData)
-  {
-    auto& sg = m_sendGhost[cid];
-    for (const auto& e : cgd)
-    {
-      Assert(sg.find(e.first) == sg.end(), "Repeating element found in "
-        "ghost data");
-      sg.insert(e.first);
-    }
-    Assert(sg.size() == cgd.size(), "Incorrect size for sendGhost");
-  }
-  Assert(m_sendGhost.size() == m_ghostData.size(), "Incorrect number of "
-    "chares in sendGhost");
-
-  // Error checking on ghost data
-  for(const auto& n : m_sendGhost)
-    for([[maybe_unused]] const auto& i : n.second)
-      Assert( i < m_fd.Esuel().size()/4, "Sender contains ghost tet id. " );
-
-  // Generate and store Esup data-structure in a map
-  auto esup = tk::genEsup(m_inpoel, 4);
-  for (std::size_t p=0; p<Disc()->Gid().size(); ++p)
-  {
-    for (auto e : tk::Around(esup, p))
-    {
-      // since inpoel has been augmented with the face-ghost cell previously,
-      // esup also contains cells which are not on this mesh-chunk, hence the
-      // following test
-      if (e < m_fd.Esuel().size()/4) m_esup[p].push_back(e);
-    }
-  }
-
-  // Error checking on Esup map
-  for(const auto& p : m_esup)
-    for([[maybe_unused]] const auto& e : p.second)
-      Assert( e < m_fd.Esuel().size()/4, "Esup contains tet id greater than "
-      + std::to_string(m_fd.Esuel().size()/4-1) +" : "+ std::to_string(e) );
-
-  auto meshid = Disc()->MeshId();
-  contribute( sizeof(std::size_t), &meshid, CkReduction::nop,
-    CkCallback(CkReductionTarget(Transporter,startEsup), Disc()->Tr()) );
-}
-
-void
-Ghosts::nodeNeighSetup()
-// *****************************************************************************
-// Setup node-neighborhood (esup)
-//! \details At this point the face-ghost communication map has been established
-//!    on this chare. This function begins generating the node-ghost comm map.
-// *****************************************************************************
-{
-  if (Disc()->NodeCommMap().empty())
-  // in serial, skip setting up node-neighborhood
-  { comesup_complete(); }
-  else
-  {
-    const auto& nodeCommMap = Disc()->NodeCommMap();
-
-    // send out node-neighborhood map
-    for (const auto& [cid, nlist] : nodeCommMap)
-    {
-      std::unordered_map< std::size_t, std::vector< std::size_t > > bndEsup;
-      std::unordered_map< std::size_t, std::vector< tk::real > > nodeBndCells;
-      for (const auto& p : nlist)
-      {
-        auto pl = tk::cref_find(Disc()->Lid(), p);
-        // fill in the esup for the chare-boundary
-        const auto& pesup = tk::cref_find(m_esup, pl);
-        bndEsup[p] = pesup;
-
-        // fill a map with the element ids from esup as keys and geoElem as
-        // values, and another map containing these elements associated with
-        // the chare id with which they are node-neighbors.
-        for (const auto& e : pesup)
-        {
-          nodeBndCells[e] = m_geoElem[e];
-
-          // add these esup-elements into map of elements along chare boundary
-          Assert( e < m_fd.Esuel().size()/4, "Sender contains ghost tet id." );
-          m_sendGhost[cid].insert(e);
-        }
-      }
-
-      thisProxy[cid].comEsup(thisIndex, bndEsup, nodeBndCells);
-    }
-  }
+void
+Discretization::startvol()
+// *****************************************************************************
+//  Get ready for (re-)computing/communicating nodal volumes
+// *****************************************************************************
+{
+  m_nvol = 0;
+  thisProxy[ thisIndex ].wait4vol();
+
+  // Zero out mesh volume container
+  std::fill( begin(m_vol), end(m_vol), 0.0 );
+
+  // Clear receive buffer that will be used for collecting nodal volumes
+  m_volc.clear();
+}
+
+void
+Discretization::registerReducers()
+// *****************************************************************************
+//  Configure Charm++ reduction types
+//!  \details Since this is a [initnode] routine, see the .ci file, the
+//!   Charm++ runtime system executes the routine exactly once on every
+//!   logical node early on in the Charm++ init sequence. Must be static as
+//!   it is called without an object. See also: Section "Initializations at
+//!   Program Startup" at in the Charm++ manual
+//!   http://charm.cs.illinois.edu/manuals/html/charm++/manual.html.
+// *****************************************************************************
+{
+  PDFMerger = CkReduction::addReducer( tk::mergeUniPDFs );
+}
+
+tk::UnsMesh::Coords
+Discretization::setCoord( const tk::UnsMesh::CoordMap& coordmap )
+// *****************************************************************************
+// Set mesh coordinates based on coordinates map
+// *****************************************************************************
+{
+  Assert( coordmap.size() == m_gid.size(), "Size mismatch" );
+  Assert( coordmap.size() == m_lid.size(), "Size mismatch" );
+
+  tk::UnsMesh::Coords coord;
+  coord[0].resize( coordmap.size() );
+  coord[1].resize( coordmap.size() );
+  coord[2].resize( coordmap.size() );
+
+  for (const auto& [ gid, coords ] : coordmap) {
+    auto i = tk::cref_find( m_lid, gid );
+    coord[0][i] = coords[0];
+    coord[1][i] = coords[1];
+    coord[2][i] = coords[2];
+  }
+
+  return coord;
+}
+
+void
+Discretization::remap(
+  const std::unordered_map< std::size_t, std::size_t >& map )
+// *****************************************************************************
+//  Remap mesh data based on new local ids
+//! \param[in] map Mapping of old->new local ids
+// *****************************************************************************
+{
+  // Remap connectivity containing local IDs
+  for (auto& l : m_inpoel) l = tk::cref_find(map,l);
+
+  // Remap global->local id map
+  for (auto& [g,l] : m_lid) l = tk::cref_find(map,l);
+
+  // Remap global->local id map
+  auto maxid = std::numeric_limits< std::size_t >::max();
+  std::vector< std::size_t > newgid( m_gid.size(), maxid );
+  for (const auto& [o,n] : map) newgid[n] = m_gid[o];
+  m_gid = std::move( newgid );
+
+  Assert( std::all_of( m_gid.cbegin(), m_gid.cend(),
+            [=](std::size_t i){ return i < maxid; } ),
+          "Not all gid have been remapped" );
+
+  // Remap nodal volumes (with contributions along chare-boundaries)
+  std::vector< tk::real > newvol( m_vol.size(), 0.0 );
+  for (const auto& [o,n] : map) newvol[n] = m_vol[o];
+  m_vol = std::move( newvol );
+
+  // Remap nodal volumes (without contributions along chare-boundaries)
+  std::vector< tk::real > newv( m_v.size(), 0.0 );
+  for (const auto& [o,n] : map) newv[n] = m_v[o];
+  m_v = std::move( newv );
+
+  // Remap locations of node coordinates
+  tk::UnsMesh::Coords newcoord;
+  auto npoin = m_coord[0].size();
+  newcoord[0].resize( npoin );
+  newcoord[1].resize( npoin );
+  newcoord[2].resize( npoin );
+  for (const auto& [o,n] : map) {
+    newcoord[0][n] = m_coord[0][o];
+    newcoord[1][n] = m_coord[1][o];
+    newcoord[2][n] = m_coord[2][o];
+  }
+  m_coord = std::move( newcoord );
+}
+
+void
+Discretization::setRefiner( const CProxy_Refiner& ref )
+// *****************************************************************************
+//  Set Refiner Charm++ proxy
+//! \param[in] ref Incoming refiner proxy to store
+// *****************************************************************************
+{
+  m_refiner = ref;
+}
+
+void
+Discretization::vol()
+// *****************************************************************************
+// Sum mesh volumes to nodes, start communicating them on chare-boundaries
+// *****************************************************************************
+{
+  const auto& x = m_coord[0];
+  const auto& y = m_coord[1];
+  const auto& z = m_coord[2];
+
+  // Compute nodal volumes on our chunk of the mesh
+  for (std::size_t e=0; e<m_inpoel.size()/4; ++e) {
+    const std::array< std::size_t, 4 > N{{ m_inpoel[e*4+0], m_inpoel[e*4+1],
+                                           m_inpoel[e*4+2], m_inpoel[e*4+3] }};
+    // compute element Jacobi determinant * 5/120 = element volume / 4
+    const std::array< tk::real, 3 >
+      ba{{ x[N[1]]-x[N[0]], y[N[1]]-y[N[0]], z[N[1]]-z[N[0]] }},
+      ca{{ x[N[2]]-x[N[0]], y[N[2]]-y[N[0]], z[N[2]]-z[N[0]] }},
+      da{{ x[N[3]]-x[N[0]], y[N[3]]-y[N[0]], z[N[3]]-z[N[0]] }};
+    const auto J = tk::triple( ba, ca, da ) * 5.0 / 120.0;
+    ErrChk( J > 0, "Element Jacobian non-positive: PE:" +
+                   std::to_string(CkMyPe()) + ", node IDs: " +
+                   std::to_string(m_gid[N[0]]) + ',' +
+                   std::to_string(m_gid[N[1]]) + ',' +
+                   std::to_string(m_gid[N[2]]) + ',' +
+                   std::to_string(m_gid[N[3]]) + ", coords: (" +
+                   std::to_string(x[N[0]]) + ", " +
+                   std::to_string(y[N[0]]) + ", " +
+                   std::to_string(z[N[0]]) + "), (" +
+                   std::to_string(x[N[1]]) + ", " +
+                   std::to_string(y[N[1]]) + ", " +
+                   std::to_string(z[N[1]]) + "), (" +
+                   std::to_string(x[N[2]]) + ", " +
+                   std::to_string(y[N[2]]) + ", " +
+                   std::to_string(z[N[2]]) + "), (" +
+                   std::to_string(x[N[3]]) + ", " +
+                   std::to_string(y[N[3]]) + ", " +
+                   std::to_string(z[N[3]]) + ')' );
+    // scatter add V/4 to nodes
+    for (std::size_t j=0; j<4; ++j) m_vol[N[j]] += J;
+
+    // save element volumes at t=t0
+    if (m_it == 0) m_vol0[e] = J * 4.0;
+  }
+
+  // Store nodal volumes without contributions from other chares on
+  // chare-boundaries
+  m_v = m_vol;
+
+  // Send our nodal volume contributions to neighbor chares
+  if (m_nodeCommMap.empty())
+   totalvol();
+  else
+    for (const auto& [c,n] : m_nodeCommMap) {
+      std::vector< tk::real > v( n.size() );
+      std::size_t j = 0;
+      for (auto i : n) v[ j++ ] = m_vol[ tk::cref_find(m_lid,i) ];
+      thisProxy[c].comvol( std::vector<std::size_t>(begin(n), end(n)), v );
+    }
+
+  ownvol_complete();
+}
+
+void
+Discretization::comvol( const std::vector< std::size_t >& gid,
+                        const std::vector< tk::real >& nodevol )
+// *****************************************************************************
+//  Receive nodal volumes on chare-boundaries
+//! \param[in] gid Global mesh node IDs at which we receive volume contributions
+//! \param[in] nodevol Partial sums of nodal volume contributions to
+//!    chare-boundary nodes
+//! \details This function receives contributions to m_vol, which stores the
+//!   nodal volumes. While m_vol stores own contributions, m_volc collects the
+//!   neighbor chare contributions during communication. This way work on m_vol
+//!   and m_volc is overlapped. The contributions are applied in totalvol().
+// *****************************************************************************
+{
+  Assert( nodevol.size() == gid.size(), "Size mismatch" );
+
+  for (std::size_t i=0; i<gid.size(); ++i)
+    m_volc[ gid[i] ] += nodevol[i];
+
+  if (++m_nvol == m_nodeCommMap.size()) {
+    m_nvol = 0;
+    comvol_complete();
+  }
+}
+
+void
+Discretization::totalvol()
+// *****************************************************************************
+// Sum mesh volumes and contribute own mesh volume to total volume
+// *****************************************************************************
+{
+  // Add received contributions to nodal volumes
+  for (const auto& [gid, vol] : m_volc)
+    m_vol[ tk::cref_find(m_lid,gid) ] += vol;
+
+  // Clear receive buffer
+  tk::destroy(m_volc);
 
-  ownesup_complete();
-}
-
-void
-Ghosts::comEsup( int fromch,
-  const std::unordered_map< std::size_t, std::vector< std::size_t > >& bndEsup,
-  const std::unordered_map< std::size_t, std::vector< tk::real > >&
-    nodeBndCells )
-// *****************************************************************************
-//! \brief Receive elements-surrounding-points data-structure for points on
-//    common boundary between receiving and sending neighbor chare, and the
-//    element geometries for these new elements
-//! \param[in] fromch Sender chare id
-//! \param[in] bndEsup Elements-surrounding-points data-structure from fromch
-//! \param[in] nodeBndCells Map containing element geometries associated with
-//!   remote element IDs in the esup
-// *****************************************************************************
-{
-  auto& chghost = m_ghost[fromch];
-
-  // Extend remote-local element id map and element geometry array
-  for (const auto& e : nodeBndCells)
-  {
-    // need to check following, because 'e' could have been added previously in
-    // remote-local element id map as a part of face-communication, i.e. as a
-    // face-ghost element
-    if (chghost.find(e.first) == chghost.end())
-    {
-      chghost[e.first] = m_nunk;
-      m_geoElem.push_back(e.second);
-      ++m_nunk;
-    }
-  }
-
-  // Store incoming data in comm-map buffer for Esup
-  for (const auto& [node, elist] : bndEsup)
-  {
-    auto pl = tk::cref_find(Disc()->Lid(), node);
-    auto& pesup = m_esupc[pl];
-    for (auto e : elist)
-    {
-      auto el = tk::cref_find(chghost, e);
-      pesup.push_back(el);
-    }
-  }
-
-  // if we have heard from all fellow chares that we share at least a single
-  // node, edge, or face with
-  if (++m_ncomEsup == Disc()->NodeCommMap().size()) {
-    m_ncomEsup = 0;
-    comesup_complete();
-  }
-}
-
-void
-Ghosts::adj()
-// *****************************************************************************
-// Finish up with adjacency maps, and do a global-sync to begin problem setup
-//! \details At this point, the nodal- and face-adjacency has been set up. This
-//    function does some error checking on the nodal-adjacency and prepares
-//    for problem setup.
-// *****************************************************************************
-{
-  // combine own and communicated contributions to elements surrounding points
-  for (auto& [p, elist] : m_esupc)
-  {
-    auto& pesup = tk::ref_find(m_esup, p);
-    for ([[maybe_unused]] auto e : elist)
-    {
-      Assert( e >= m_fd.Esuel().size()/4, "Non-ghost element received from "
-        "esup buffer." );
-    }
-    tk::concat< std::size_t >(std::move(elist), pesup);
-  }
-
-  tk::destroy(m_ghostData);
-  tk::destroy(m_esupc);
-
-  if ( g_inputdeck.get< tag::cmd, tag::feedback >() ) Disc()->Tr().chadj();
-
-  // Error checking on ghost data
-  for(const auto& n : m_sendGhost)
-    for([[maybe_unused]] const auto& i : n.second)
-      Assert( i < m_fd.Esuel().size()/4, "Sender contains ghost tet id. ");
+  // Sum mesh volume to host
+  std::vector< tk::real > tvol{ 0.0,
+                                static_cast<tk::real>(m_initial),
+                                static_cast<tk::real>(m_meshid) };
+  for (auto v : m_v) tvol[0] += v;
+  contribute( tvol, CkReduction::sum_double,
+    CkCallback(CkReductionTarget(Transporter,totalvol), m_transporter) );
+}
+
+void
+Discretization::stat( tk::real mesh_volume )
+// *****************************************************************************
+// Compute mesh cell statistics
+//! \param[in] mesh_volume Total mesh volume
+// *****************************************************************************
+{
+  // Store total mesh volume
+  m_meshvol = mesh_volume;
+
+  const auto& x = m_coord[0];
+  const auto& y = m_coord[1];
+  const auto& z = m_coord[2];
+
+  auto MIN = -std::numeric_limits< tk::real >::max();
+  auto MAX = std::numeric_limits< tk::real >::max();
+  std::vector< tk::real > min{ MAX, MAX, MAX };
+  std::vector< tk::real > max{ MIN, MIN, MIN };
+  std::vector< tk::real > sum{ 0.0, 0.0, 0.0, 0.0, 0.0, 0.0 };
+  tk::UniPDF edgePDF( 1e-4 );
+  tk::UniPDF volPDF( 1e-4 );
+  tk::UniPDF ntetPDF( 1e-4 );
+
+  // Compute points surrounding points
+  auto psup = tk::genPsup( m_inpoel, 4, tk::genEsup(m_inpoel,4) );
+  Assert( psup.second.size()-1 == m_gid.size(),
+          "Number of mesh points and number of global IDs unequal" );
+
+  // Compute edge length statistics
+  // Note that while the min and max edge lengths are independent of the number
+  // of CPUs (by the time they are aggregated across all chares), the sum of
+  // the edge lengths and the edge length PDF are not. This is because the
+  // edges on the chare-boundary are counted multiple times and we
+  // conscientiously do not make an effort to precisely compute this, because
+  // that would require communication and more complex logic. Since these
+  // statistics are intended as simple average diagnostics, we ignore these
+  // small differences. For reproducible average edge lengths and edge length
+  // PDFs, run the mesh in serial.
+  for (std::size_t p=0; p<m_gid.size(); ++p)
+    for (auto i : tk::Around(psup,p)) {
+       const auto dx = x[ i ] - x[ p ];
+       const auto dy = y[ i ] - y[ p ];
+       const auto dz = z[ i ] - z[ p ];
+       const auto length = std::sqrt( dx*dx + dy*dy + dz*dz );
+       if (length < min[0]) min[0] = length;
+       if (length > max[0]) max[0] = length;
+       sum[0] += 1.0;
+       sum[1] += length;
+       edgePDF.add( length );
+    }
+
+  // Compute mesh cell volume statistics
+  for (std::size_t e=0; e<m_inpoel.size()/4; ++e) {
+    const std::array< std::size_t, 4 > N{{ m_inpoel[e*4+0], m_inpoel[e*4+1],
+                                           m_inpoel[e*4+2], m_inpoel[e*4+3] }};
+    const std::array< tk::real, 3 >
+      ba{{ x[N[1]]-x[N[0]], y[N[1]]-y[N[0]], z[N[1]]-z[N[0]] }},
+      ca{{ x[N[2]]-x[N[0]], y[N[2]]-y[N[0]], z[N[2]]-z[N[0]] }},
+      da{{ x[N[3]]-x[N[0]], y[N[3]]-y[N[0]], z[N[3]]-z[N[0]] }};
+    const auto L = std::cbrt( tk::triple( ba, ca, da ) / 6.0 );
+    if (L < min[1]) min[1] = L;
+    if (L > max[1]) max[1] = L;
+    sum[2] += 1.0;
+    sum[3] += L;
+    volPDF.add( L );
+  }
+
+  // Contribute stats of number of tetrahedra (ntets)
+  sum[4] = 1.0;
+  min[2] = max[2] = sum[5] = static_cast< tk::real >( m_inpoel.size() / 4 );
+  ntetPDF.add( min[2] );
+
+  min.push_back( static_cast<tk::real>(m_meshid) );
+  max.push_back( static_cast<tk::real>(m_meshid) );
+  sum.push_back( static_cast<tk::real>(m_meshid) );
 
-  // Create a mapping between local ghost tet ids and zero-based boundary ids
-  std::vector< std::size_t > c( tk::sumvalsize( m_ghost ) );
-  std::size_t j = 0;
-  for (const auto& n : m_ghost) {
-    for(const auto& i : n.second) {
-      c[j++] = i.second;
-    }
-  }
-  m_bid = tk::assignLid( c );
-
-  // Basic error checking on ghost tet ID map
-  Assert( m_ghost.find( thisIndex ) == m_ghost.cend(),
-          "Ghost id map should not contain data for own chare ID" );
-
-  // Store expected ghost tet IDs
-  for (const auto& n : m_ghost)
-    for ([[maybe_unused]] const auto& g : n.second)
-      Assert( m_exptGhost.insert( g.second ).second,
-              "Failed to store local tetid as exptected ghost id" );
-
-  // Callback function from DG/FV after ghost-setup is done
-  m_cbAfterDone.send();
-}
-
-bool
-Ghosts::leakyAdjacency()
-// *****************************************************************************
-// Perform leak-test on chare boundary faces
-//! \details This function computes a surface integral over the boundary of the
-//!   faces after the face adjacency communication map is completed. A non-zero
-//!   vector result indicates a leak, e.g., a hole in the partition (covered by
-//!   the faces of the face adjacency communication map), which indicates an
-//!   error upstream in the code that sets up the face communication data
-//!   structures.
-//! \note Compared to tk::leakyPartition() this function performs the leak-test
-//!   on the face geometry data structure enlarged by ghost faces on this
-//!   partition by computing a discrete surface integral considering the
-//!   physical and chare boundary faces, which should be equal to zero for a
-//!   closed domain.
-//! \return True if our chare face adjacency leaks.
-// *****************************************************************************
-{
-  // Storage for surface integral over our chunk of the adjacency
-  std::array< tk::real, 3 > s{{ 0.0, 0.0, 0.0 }};
-
-  // physical boundary faces
-  for (std::size_t f=0; f<m_fd.Nbfac(); ++f) {
-    s[0] += m_geoFace(f,0) * m_geoFace(f,1);
-    s[1] += m_geoFace(f,0) * m_geoFace(f,2);
-    s[2] += m_geoFace(f,0) * m_geoFace(f,3);
-  }
-
-  // chare-boundary faces
-  for (std::size_t f=m_fd.Nipfac(); f<m_fd.Esuf().size()/2; ++f) {
-    s[0] += m_geoFace(f,0) * m_geoFace(f,1);
-    s[1] += m_geoFace(f,0) * m_geoFace(f,2);
-    s[2] += m_geoFace(f,0) * m_geoFace(f,3);
-  }
-
-  auto eps = std::numeric_limits< tk::real >::epsilon() * 100;
-  return std::abs(s[0]) > eps || std::abs(s[1]) > eps || std::abs(s[2]) > eps;
-}
-
-bool
-Ghosts::faceMatch()
-// *****************************************************************************
-// Check if esuf of chare-boundary faces matches
-//! \details This function checks each chare-boundary esuf entry for the left
-//!   and right elements. Then, it tries to match all vertices of these
-//!   elements. Exactly three of these vertices must match if the esuf entry
-//!   has been updated correctly at chare-boundaries.
-//! \return True if chare-boundary faces match.
-// *****************************************************************************
-{
-  const auto& esuf = m_fd.Esuf();
-  bool match(true);
-
-  auto eps = std::numeric_limits< tk::real >::epsilon() * 100;
-
-  for (auto f=m_fd.Nipfac(); f<esuf.size()/2; ++f)
-  {
-    std::size_t el = static_cast< std::size_t >(esuf[2*f]);
-    std::size_t er = static_cast< std::size_t >(esuf[2*f+1]);
-
-    std::size_t count = 0;
-
-    for (std::size_t i=0; i<4; ++i)
-    {
-      auto ip = m_inpoel[4*el+i];
-      for (std::size_t j=0; j<4; ++j)
-      {
-        auto jp = m_inpoel[4*er+j];
-        auto xdiff = std::abs( m_coord[0][ip] - m_coord[0][jp] );
-        auto ydiff = std::abs( m_coord[1][ip] - m_coord[1][jp] );
-        auto zdiff = std::abs( m_coord[2][ip] - m_coord[2][jp] );
-
-        if ( xdiff<=eps && ydiff<=eps && zdiff<=eps ) ++count;
-      }
-    }
-
-    match = (match && count == 3);
-  }
-
-  return match;
-}
-
-bool
-Ghosts::receivedChBndFaces()
-// *****************************************************************************
-// Verify that all chare-boundary faces have been received
-//! \return True if all chare-boundary faces have been received
-// *****************************************************************************
-{
-  const auto& lid = Disc()->Lid();
-  tk::UnsMesh::FaceSet recvBndFace;
-
-  // Collect chare-boundary faces that have been received and expected
-  for (const auto& c : m_bndFace)
-    for (const auto& f : c.second)
-      if (m_expChBndFace.find(f.first) != end(m_expChBndFace))
-        recvBndFace.insert(f.first);
-
-   // Collect info on expected but not received faces
-   std::stringstream msg;
-   for (const auto& f : m_expChBndFace)
-     if (recvBndFace.find(f) == end(recvBndFace)) {
-       const auto& x = m_coord[0];
-       const auto& y = m_coord[1];
-       const auto& z = m_coord[2];
-       auto A = tk::cref_find( lid, f[0] );
-       auto B = tk::cref_find( lid, f[1] );
-       auto C = tk::cref_find( lid, f[2] );
-       msg << '{' << A << ',' << B << ',' << C << "}:("
-           << x[A] << ',' << y[A] << ',' << z[A] << ' '
-           << x[B] << ',' << y[B] << ',' << z[B] << ' '
-           << x[C] << ',' << y[C] << ',' << z[C] << ") ";
-     }
-
-  tk::destroy( m_expChBndFace );
-
-  // Error out with info on missing faces
-  auto s = msg.str();
-  if (!s.empty()) {
-    Throw( "Ghosts chare " + std::to_string(thisIndex) +
-           " missing face(s) {local node ids} (node coords): " + s );
-  } else {
-    return true;
-  }
-}
-
-int
-Ghosts::findchare( const tk::UnsMesh::Face& t )
+  // Contribute to mesh statistics across all Discretization chares
+  contribute( min, CkReduction::min_double,
+    CkCallback(CkReductionTarget(Transporter,minstat), m_transporter) );
+  contribute( max, CkReduction::max_double,
+    CkCallback(CkReductionTarget(Transporter,maxstat), m_transporter) );
+  contribute( sum, CkReduction::sum_double,
+    CkCallback(CkReductionTarget(Transporter,sumstat), m_transporter) );
+
+  // Serialize PDFs to raw stream
+  auto stream = tk::serialize( m_meshid, { edgePDF, volPDF, ntetPDF } );
+  // Create Charm++ callback function for reduction of PDFs with
+  // Transporter::pdfstat() as the final target where the results will appear.
+  CkCallback cb( CkIndex_Transporter::pdfstat(nullptr), m_transporter );
+  // Contribute serialized PDF of partial sums to host via Charm++ reduction
+  contribute( stream.first, stream.second.get(), PDFMerger, cb );
+}
+
+void
+Discretization::boxvol(
+  const std::vector< std::unordered_set< std::size_t > >& nodes,
+  const std::unordered_map< std::size_t, std::set< std::size_t > >& nodeblk,
+  std::size_t nuserblk )
+// *****************************************************************************
+// Compute total box IC volume
+//! \param[in] nodes Node list contributing to box IC volume (for each IC box)
+//! \param[in] nodeblk Node list associated to mesh blocks contributing to block
+//!   volumes (for each IC box)
+//! \param[in] nuserblk Number of user IC mesh blocks
+// *****************************************************************************
+{
+  // Compute partial box IC volume (just add up all boxes)
+  tk::real boxvol = 0.0;
+  for (const auto& b : nodes) for (auto i : b) boxvol += m_v[i];<--- Consider using std::accumulate algorithm instead of a raw loop.
+
+  // Compute partial IC mesh block volume
+  std::vector< tk::real > blockvols;
+  if (nuserblk > 0) {
+    blockvols.resize(nuserblk,0.0);
+    for (const auto& [blid, ndset] : nodeblk) {
+      // The following if-test makes sure we access volumes only of mesh blocks
+      // with user-specified ICs
+      if (blid < nuserblk) {
+        for (const auto& n : ndset) blockvols[blid] += m_v[n];
+      }
+    }
+  }
+
+  // Sum up box IC volume across all chares
+  auto meshdata = blockvols;
+  meshdata.push_back(boxvol);
+  meshdata.push_back(static_cast<tk::real>(m_meshid));
+  contribute( meshdata, CkReduction::sum_double,
+    CkCallback(CkReductionTarget(Transporter,boxvol), m_transporter) );
+}
+
+void
+Discretization::write(
+  const std::vector< std::size_t >& inpoel,
+  const tk::UnsMesh::Coords& coord,
+  const std::map< int, std::vector< std::size_t > >& bface,
+  const std::map< int, std::vector< std::size_t > >& bnode,
+  const std::vector< std::size_t >& triinpoel,
+  const std::vector< std::string>& elemfieldnames,
+  const std::vector< std::string>& nodefieldnames,
+  const std::vector< std::string>& elemsurfnames,
+  const std::vector< std::string>& nodesurfnames,
+  const std::vector< std::vector< tk::real > >& elemfields,
+  const std::vector< std::vector< tk::real > >& nodefields,
+  const std::vector< std::vector< tk::real > >& elemsurfs,
+  const std::vector< std::vector< tk::real > >& nodesurfs,
+  CkCallback c )
+// *****************************************************************************
+//  Output mesh and fields data (solution dump) to file(s)
+//! \param[in] inpoel Mesh connectivity for the mesh chunk to be written
+//! \param[in] coord Node coordinates of the mesh chunk to be written
+//! \param[in] bface Map of boundary-face lists mapped to corresponding side set
+//!   ids for this mesh chunk
+//! \param[in] bnode Map of boundary-node lists mapped to corresponding side set
+//!   ids for this mesh chunk
+//! \param[in] triinpoel Interconnectivity of points and boundary-face in this
+//!   mesh chunk
+//! \param[in] elemfieldnames Names of element fields to be output to file
+//! \param[in] nodefieldnames Names of node fields to be output to file
+//! \param[in] elemsurfnames Names of elemental surface fields to be output to
+//!   file
+//! \param[in] nodesurfnames Names of node surface fields to be output to file
+//! \param[in] elemfields Field data in mesh elements to output to file
+//! \param[in] nodefields Field data in mesh nodes to output to file
+//! \param[in] elemsurfs Surface field data in mesh elements to output to file
+//! \param[in] nodesurfs Surface field data in mesh nodes to output to file
+//! \param[in] c Function to continue with after the write
+//! \details Since m_meshwriter is a Charm++ chare group, it never migrates and
+//!   an instance is guaranteed on every PE. We index the first PE on every
+//!   logical compute node. In Charm++'s non-SMP mode, a node is the same as a
+//!   PE, so the index is the same as CkMyPe(). In SMP mode the index is the
+//!   first PE on every logical node. In non-SMP mode this yields one or more
+//!   output files per PE with zero or non-zero virtualization, respectively. If
+//!   there are multiple chares on a PE, the writes are serialized per PE, since
+//!   only a single entry method call can be executed at any given time. In SMP
+//!   mode, still the same number of files are output (one per chare), but the
+//!   output is serialized through the first PE of each compute node. In SMP
+//!   mode, channeling multiple files via a single PE on each node is required
+//!   by NetCDF and HDF5, as well as ExodusII, since none of these libraries are
+//!   thread-safe.
+// *****************************************************************************
+{
+  // If the previous iteration refined (or moved) the mesh or this is called
+  // before the first time step, we also output the mesh.
+  bool meshoutput = m_itf == 0 ? true : false;
+
+  auto eps = std::numeric_limits< tk::real >::epsilon();
+  bool fieldoutput = false;
+
+  // Output field data only if there is no dump at this physical time yet
+  if (std::abs(m_lastDumpTime - m_t) > eps ) {
+    m_lastDumpTime = m_t;
+    ++m_itf;
+    fieldoutput = true;
+  }
+
+  // set of sidesets where fieldoutput is required
+  std::set< int > outsets;
+  const auto& osv = g_inputdeck.get< tag::field_output, tag::sideset >();
+  outsets.insert(osv.begin(), osv.end());
+
+  m_meshwriter[ CkNodeFirst( CkMyNode() ) ].
+    write( m_meshid, meshoutput, fieldoutput, m_itr, m_itf, m_t, thisIndex,
+           g_inputdeck.get< tag::cmd, tag::io, tag::output >(),
+           inpoel, coord, bface, bnode, triinpoel, elemfieldnames,
+           nodefieldnames, elemsurfnames, nodesurfnames, elemfields, nodefields,
+           elemsurfs, nodesurfs, outsets, c );
+}
+
+void
+Discretization::setdt( tk::real newdt )
+// *****************************************************************************
+// Set time step size
+//! \param[in] newdt Size of the new time step
+// *****************************************************************************
+{
+  m_dtn = m_dt;
+  m_dt = newdt;
+
+  // Truncate the size of last time step
+  const auto term = g_inputdeck.get< tag::term >();
+  if (m_t+m_dt > term) m_dt = term - m_t;
+}
+
+void
+Discretization::next()
+// *****************************************************************************
+// Prepare for next step
 // *****************************************************************************
-// Find any chare for face (given by 3 global node IDs)
-//! \param[in] t Face given by three global node IDs
-//! \return Chare ID if found among any of the chares we communicate along
-//!   faces with, -1 if the face cannot be found.
-// *****************************************************************************
-{
-  for (const auto& cf : m_bndFace)
-    // cppcheck-suppress useStlAlgorithm
-    if (cf.second.find(t) != end(cf.second))<--- Unmatched suppression: useStlAlgorithm
-      return cf.first;
-  return -1;
-}
-
-std::size_t
-Ghosts::nodetripletMatch(
-  const std::array< std::size_t, 2 >& id,
-  const tk::UnsMesh::Face& t )
-// *****************************************************************************
-// Check if entries in inpoel, inpofa and node-triplet are consistent
-//! \param[in] id Local face and (inner) tet id adjacent to it
-//! \param[in] t node-triplet associated with the chare boundary face
-//! \return number of nodes in inpoel that matched with t and inpofa
-// *****************************************************************************
-{
-  const auto& esuf = m_fd.Esuf();
-  const auto& inpofa = m_fd.Inpofa();
-  const auto& lid = Disc()->Lid();
-
-  std::size_t counter = 0;
-  for (std::size_t k=0; k<4; ++k)
-  {
-    auto el = esuf[ 2*id[0] ];
-    auto ip = m_inpoel[ 4*static_cast< std::size_t >( el )+k ];<--- Variable 'ip' is assigned a value that is never used.
-    Assert( el == static_cast< int >( id[1] ), "Mismatch in id and esuf" );
-    for (std::size_t j=0; j<3; ++j)
-    {
-      auto jp = tk::cref_find( lid, t[j] );
-      auto fp = inpofa[ 3*id[0]+(2-j) ];
-      if (ip == jp && ip == fp) ++counter;
-    }
-  }
-
-  return counter;
-}
-
-void
-Ghosts::addEsuf(
-  const std::array< std::size_t, 2 >& id,
-  std::size_t ghostid )
-// *****************************************************************************
-// Fill elements surrounding a face along chare boundary
-//! \param[in] id Local face and (inner) tet id adjacent to it
-//! \param[in] ghostid Local ID for ghost tet
-//! \details This function extends and fills in the elements surrounding faces
-//!   data structure (esuf) so that the left and right element id is filled
-//!   in correctly on chare boundaries to contain the correct inner tet id and
-//!   the local tet id for the outer (ghost) tet, both adjacent to the given
-//!   chare-face boundary. Prior to this function, this data structure does not
-//!   have yet face-element connectivity adjacent to chare-boundary faces, only
-//!   for physical boundaries and internal faces that are not on the chare
-//!   boundary (this latter purely as a result of mesh partitioning). The remote
-//!   element id of the ghost is stored in a location that is local to our own
-//!   esuf. The face numbering is such that esuf stores the element-face
-//!   connectivity first for the physical-boundary faces, followed by that of
-//!   the internal faces, followed by the chare-boundary faces. As a result,
-//!   esuf can be used by physics algorithms in exactly the same way as would be
-//!   used in serial. In serial, of course, this data structure is not extended
-//!   at the end by the chare-boundaries.
-// *****************************************************************************
-{
-  auto& esuf = m_fd.Esuf();
-
-  Assert( 2*id[0]+1 < esuf.size(), "Indexing out of esuf" );
-
-  // put in inner tet id
-  Assert( esuf[ 2*id[0] ] == -2 && esuf[ 2*id[0]+1 ] == -2, "Updating esuf at "
-          "wrong location instead of chare-boundary" );
-  esuf[ 2*id[0]+0 ] = static_cast< int >( id[1] );
-  // put in local id for outer/ghost tet
-  esuf[ 2*id[0]+1 ] = static_cast< int >( ghostid );
-}
-
-void
-Ghosts::addEsuel(
-  const std::array< std::size_t, 2 >& id,
-  std::size_t ghostid,
-  const tk::UnsMesh::Face& t )
-// *****************************************************************************
-// Fill elements surrounding a element along chare boundary
-//! \param[in] id Local face and (inner) tet id adjacent to it
-//! \param[in] ghostid Local ID for ghost tet
-//! \param[in] t node-triplet associated with the chare boundary face
-//! \details This function updates the elements surrounding element (esuel) data
-//    structure for the (inner) tets adjacent to the chare-boundaries. It fills
-//    esuel of this inner tet with the local tet-id that has been assigned to
-//    the outer ghost tet in Ghosts::comGhost in place of the -1 before.
-// *****************************************************************************
-{
-  const auto& lid = Disc()->Lid();
-  [[maybe_unused]] const auto& esuf = m_fd.Esuf();
-  auto& esuel = m_fd.Esuel();
-
-  std::array< tk::UnsMesh::Face, 4 > face;
-  for (std::size_t f = 0; f<4; ++f)
-    for (std::size_t i = 0; i<3; ++i)
-      face[f][i] = m_inpoel[ id[1]*4 + tk::lpofa[f][i] ];
-
-  tk::UnsMesh::Face tl{{ tk::cref_find( lid, t[0] ),
-                         tk::cref_find( lid, t[1] ),
-                         tk::cref_find( lid, t[2] ) }};
-
-  std::size_t i(0), nmatch(0);
-  for (const auto& f : face) {
-    if (tk::UnsMesh::Eq< 3 >()( tl, f )) {
-      Assert( esuel[ id[1]*4 + i ] == -1, "Incorrect boundary element found in "
-             "esuel");
-      esuel[ id[1]*4 + i ] = static_cast<int>(ghostid);
-      ++nmatch;<--- Variable 'nmatch' is assigned a value that is never used.
-      Assert( esuel[ id[1]*4 + i ] == esuf[ 2*id[0]+1 ], "Incorrect boundary "
-             "element entered in esuel" );
-      Assert( static_cast<int>(id[1]) == esuf[ 2*id[0]+0 ], "Boundary "
-             "element entered in incorrect esuel location" );
-    }
-    ++i;
-  }
-
-  // ensure that exactly one face matched
-  Assert( nmatch == 1, "Incorrect number of node-triplets (faces) matched for "
-         "updating esuel; matching faces = "+ std::to_string(nmatch) );
-}
-
-void
-Ghosts::addGeoFace(
-  const tk::UnsMesh::Face& t,
-  const std::array< std::size_t, 2 >& id )
-// *****************************************************************************
-// Fill face-geometry data along chare boundary
-//! \param[in] t Face (given by 3 global node IDs) on the chare boundary
-//! \param[in] id Local face and (inner) tet id adjacent to face t
-//! \details This function fills in the face geometry data along a chare
-//!    boundary.
-// *****************************************************************************
-{
-  const auto& lid = Disc()->Lid();
-
-  // get global node IDs reversing order to get outward-pointing normal
-  auto A = tk::cref_find( lid, t[2] );
-  auto B = tk::cref_find( lid, t[1] );
-  auto C = tk::cref_find( lid, t[0] );
-  auto geochf = tk::geoFaceTri( {{m_coord[0][A], m_coord[0][B], m_coord[0][C]}},
-                                {{m_coord[1][A], m_coord[1][B], m_coord[1][C]}},
-                                {{m_coord[2][A], m_coord[2][B], m_coord[2][C]}} );
-
-  for (std::size_t i=0; i<7; ++i)
-    m_geoFace(id[0],i) = geochf(0,i);
-}
-
-#include "NoWarning/ghosts.def.h"
+{
+  // Update floor of physics time divided by output interval times
+  const auto eps = std::numeric_limits< tk::real >::epsilon();
+  const auto ft = g_inputdeck.get< tag::field_output, tag::time_interval >();
+  if (ft > eps) m_physFieldFloor = std::floor( m_t / ft );
+  const auto ht = g_inputdeck.get< tag::history_output, tag::time_interval >();
+  if (ht > eps) m_physHistFloor = std::floor( m_t / ht );
+
+  // Update floors of physics time divided by output interval times for ranges
+  const auto& rf = g_inputdeck.get< tag::field_output, tag::time_range >();
+  if (!rf.empty()) {
+    if (m_t > rf[0] and m_t < rf[1])
+      m_rangeFieldFloor = std::floor( m_t / rf[2] );
+    const auto& rh = g_inputdeck.get< tag::history_output, tag::time_range >();
+    if (m_t > rh[0] and m_t < rh[1])
+      m_rangeHistFloor = std::floor( m_t / rh[2] );
+  }
+
+  ++m_it;
+  m_t += m_dt;
+}
+
+void
+Discretization::grindZero()
+// *****************************************************************************
+//  Zero grind-time
+// *****************************************************************************
+{
+  m_prevstatus = std::chrono::high_resolution_clock::now();
+
+  if (thisIndex == 0 && m_meshid == 0) {
+    const auto verbose = g_inputdeck.get< tag::cmd, tag::verbose >();
+    const auto& def =
+      g_inputdeck_defaults.get< tag::cmd, tag::io, tag::screen >();
+    tk::Print print( g_inputdeck.get< tag::cmd >().logname( def, m_nrestart ),
+                     verbose ? std::cout : std::clog,
+                     std::ios_base::app );
+    print.diag( "Starting time stepping ..." );
+  }
+}
+
+bool
+Discretization::restarted( int nrestart )
+// *****************************************************************************
+//  Detect if just returned from a checkpoint and if so, zero timers
+//! \param[in] nrestart Number of times restarted
+//! \return True if restart detected
+// *****************************************************************************
+{
+  // Detect if just restarted from checkpoint:
+  //   nrestart == -1 if there was no checkpoint this step
+  //   d->Nrestart() == nrestart if there was a checkpoint this step
+  //   if both false, just restarted from a checkpoint
+  bool restarted = nrestart != -1 and m_nrestart != nrestart;
+
+   // If just restarted from checkpoint
+  if (restarted) {
+    // Update number of restarts
+    m_nrestart = nrestart;
+    // Start timer measuring time stepping wall clock time
+    m_timer.zero();
+    // Zero grind-timer
+    grindZero();
+  }
+
+  return restarted;
+}
+
+std::string
+Discretization::histfilename( const std::string& id,
+                              std::streamsize precision )
+// *****************************************************************************
+//  Construct history output filename
+//! \param[in] id History point id
+//! \param[in] precision Floating point precision to use for output
+//! \return History file name
+// *****************************************************************************
+{
+  auto of = g_inputdeck.get< tag::cmd, tag::io, tag::output >();
+  std::stringstream ss;
+
+  auto mid =
+    m_disc.size() > 1 ? std::string( '.' + std::to_string(m_meshid) ) : "";
+  ss << std::setprecision(static_cast<int>(precision)) << of << mid << ".hist." << id;
+
+  return ss.str();
+}
+
+void
+Discretization::histheader( std::vector< std::string >&& names )
+// *****************************************************************************
+//  Output headers for time history files (one for each point)
+//! \param[in] names History output variable names
+// *****************************************************************************
+{
+  for (const auto& h : m_histdata) {
+    auto prec = g_inputdeck.get< tag::history_output, tag::precision >();
+    tk::DiagWriter hw( histfilename( h.get< tag::id >(), prec ),
+                       g_inputdeck.get< tag::history_output, tag::format >(),
+                       prec );
+    hw.header( names );
+  }
+}
+
+void
+Discretization::history( std::vector< std::vector< tk::real > >&& data )
+// *****************************************************************************
+//  Output time history for a time step
+//! \param[in] data Time history data for all variables and equations integrated
+// *****************************************************************************
+{
+  Assert( data.size() == m_histdata.size(), "Size mismatch" );
+
+  std::size_t i = 0;
+  for (const auto& h : m_histdata) {
+    auto prec = g_inputdeck.get< tag::history_output, tag::precision >();
+    tk::DiagWriter hw( histfilename( h.get< tag::id >(), prec ),
+                       g_inputdeck.get< tag::history_output, tag::format >(),
+                       prec,
+                       std::ios_base::app );
+    hw.diag( m_it, m_t, m_dt, data[i] );
+    ++i;
+  }
+}
+
+bool
+Discretization::fielditer() const
+// *****************************************************************************
+//  Decide if field output iteration count interval is hit
+//! \return True if field output iteration count interval is hit
+// *****************************************************************************
+{
+  if (g_inputdeck.get< tag::cmd, tag::benchmark >()) return false;
+
+  return m_it % g_inputdeck.get< tag::field_output, tag::interval >() == 0;
+}
+
+bool
+Discretization::fieldtime() const
+// *****************************************************************************
+//  Decide if field output physics time interval is hit
+//! \return True if field output physics time interval is hit
+// *****************************************************************************
+{
+  if (g_inputdeck.get< tag::cmd, tag::benchmark >()) return false;
+
+  const auto eps = std::numeric_limits< tk::real >::epsilon();
+  const auto ft = g_inputdeck.get< tag::field_output, tag::time_interval >();
+
+  if (ft < eps) return false;
+
+  return std::floor(m_t/ft) - m_physFieldFloor > eps;
+}
+
+bool
+Discretization::fieldrange() const
+// *****************************************************************************
+//  Decide if physics time falls into a field output time range
+//! \return True if physics time falls into a field output time range
+// *****************************************************************************
+{
+  if (g_inputdeck.get< tag::cmd, tag::benchmark >()) return false;
+
+  const auto eps = std::numeric_limits< tk::real >::epsilon();
+
+  bool output = false;
+
+  const auto& rf = g_inputdeck.get< tag::field_output, tag::time_range >();
+  if (!rf.empty()) {
+    if (m_t > rf[0] and m_t < rf[1])
+      output |= std::floor(m_t/rf[2]) - m_rangeFieldFloor > eps;
+  }
+
+  return output;
+}
+
+bool
+Discretization::histiter() const
+// *****************************************************************************
+//  Decide if history output iteration count interval is hit
+//! \return True if history output iteration count interval is hit
+// *****************************************************************************
+{
+  const auto hist = g_inputdeck.get< tag::history_output, tag::interval >();
+  const auto& hist_points = g_inputdeck.get< tag::history_output, tag::point >();
+
+  return m_it % hist == 0 and not hist_points.empty();
+}
+
+bool
+Discretization::histtime() const
+// *****************************************************************************
+//  Decide if history output physics time interval is hit
+//! \return True if history output physics time interval is hit
+// *****************************************************************************
+{
+  if (g_inputdeck.get< tag::cmd, tag::benchmark >()) return false;
+
+  const auto eps = std::numeric_limits< tk::real >::epsilon();
+  const auto ht = g_inputdeck.get< tag::history_output, tag::time_interval >();
+
+  if (ht < eps) return false;
+
+  return std::floor(m_t/ht) - m_physHistFloor > eps;
+}
+
+bool
+Discretization::histrange() const
+// *****************************************************************************
+//  Decide if physics time falls into a history output time range
+//! \return True if physics time falls into a history output time range
+// *****************************************************************************
+{
+  if (g_inputdeck.get< tag::cmd, tag::benchmark >()) return false;
+
+  const auto eps = std::numeric_limits< tk::real >::epsilon();
+
+  bool output = false;
+
+  const auto& rh = g_inputdeck.get< tag::history_output, tag::time_range >();
+  if (!rh.empty()) {
+    if (m_t > rh[0] and m_t < rh[1])
+      output |= std::floor(m_t/rh[2]) - m_rangeHistFloor > eps;
+  }
+
+  return output;
+}
+
+bool
+Discretization::finished() const
+// *****************************************************************************
+//  Decide if this is the last time step
+//! \return True if this is the last time step
+// *****************************************************************************
+{
+  const auto eps = std::numeric_limits< tk::real >::epsilon();
+  const auto nstep = g_inputdeck.get< tag::nstep >();
+  const auto term = g_inputdeck.get< tag::term >();
+
+  return std::abs(m_t-term) < eps or m_it >= nstep;
+}
+
+void
+Discretization::status()
+// *****************************************************************************
+// Output one-liner status report
+// *****************************************************************************
+{
+  // Query after how many time steps user wants TTY dump
+  const auto tty = g_inputdeck.get< tag::ttyi >();
+
+  // estimate grind time (taken between this and the previous time step)
+  using std::chrono::duration_cast;
+  using ms = std::chrono::milliseconds;
+  using clock = std::chrono::high_resolution_clock;
+  auto grind_time = duration_cast< ms >(clock::now() - m_prevstatus).count();
+  m_prevstatus = clock::now();
+
+  if (thisIndex==0 and m_meshid == 0 and not (m_it%tty)) {
+
+    const auto term = g_inputdeck.get< tag::term >();
+    const auto t0 = g_inputdeck.get< tag::t0 >();
+    const auto nstep = g_inputdeck.get< tag::nstep >();
+    const auto diag = g_inputdeck.get< tag::diagnostics, tag::interval >();
+    const auto lbfreq = g_inputdeck.get< tag::cmd, tag::lbfreq >();
+    const auto rsfreq = g_inputdeck.get< tag::cmd, tag::rsfreq >();
+    const auto verbose = g_inputdeck.get< tag::cmd, tag::verbose >();
+    const auto benchmark = g_inputdeck.get< tag::cmd, tag::benchmark >();
+    const auto steady = g_inputdeck.get< tag::steady_state >();
+
+    // estimate time elapsed and time for accomplishment
+    tk::Timer::Watch ete, eta;
+    if (not steady) m_timer.eta( term-t0, m_t-t0, nstep, m_it, ete, eta );
+
+    const auto& def =
+      g_inputdeck_defaults.get< tag::cmd, tag::io, tag::screen >();
+    tk::Print print( g_inputdeck.get< tag::cmd >().logname( def, m_nrestart ),
+                     verbose ? std::cout : std::clog,
+                     std::ios_base::app );
+
+    // Output one-liner
+    print << std::setfill(' ') << std::setw(8) << m_it << "  "
+          << std::scientific << std::setprecision(6)
+          << std::setw(12) << m_t << "  "
+          << m_dt << "  "
+          << std::setfill('0')
+          << std::setw(3) << ete.hrs.count() << ":"
+          << std::setw(2) << ete.min.count() << ":"
+          << std::setw(2) << ete.sec.count() << "  "
+          << std::setw(3) << eta.hrs.count() << ":"
+          << std::setw(2) << eta.min.count() << ":"
+          << std::setw(2) << eta.sec.count() << "  "
+          << std::scientific << std::setprecision(6) << std::setfill(' ')
+          << std::setw(9) << grind_time << "  ";
+
+    // Augment one-liner status with output indicators
+    if (fielditer() or fieldtime() or fieldrange()) print << 'f';
+    if (not (m_it % diag)) print << 'd';
+    if (histiter() or histtime() or histrange()) print << 't';
+    if (m_refined) print << 'h';
+    if (not (m_it % lbfreq) && not finished()) print << 'l';
+    if (not benchmark && (not (m_it % rsfreq) || finished())) print << 'r';
+
+    if (not m_meshvel_converged) print << 'a';
+    m_meshvel_converged = true; // get ready for next time step
+
+    print << std::endl;
+  }
+}
+
+#include "NoWarning/discretization.def.h"
 
diff --git a/Release/cppcheck/39.html b/Release/cppcheck/39.html index 59f4cd477c14..bd7dd783a207 100644 --- a/Release/cppcheck/39.html +++ b/Release/cppcheck/39.html @@ -152,12 +152,12 @@
  1
@@ -279,126 +279,568 @@ 

Cppcheck report - [

// *****************************************************************************
+120
+121
+122
+123
+124
+125
+126
+127
+128
+129
+130
+131
+132
+133
+134
+135
+136
+137
+138
+139
+140
+141
+142
+143
+144
+145
+146
+147
+148
+149
+150
+151
+152
+153
+154
+155
+156
+157
+158
+159
+160
+161
+162
+163
+164
+165
+166
+167
+168
+169
+170
+171
+172
+173
+174
+175
+176
+177
+178
+179
+180
+181
+182
+183
+184
+185
+186
+187
+188
+189
+190
+191
+192
+193
+194
+195
+196
+197
+198
+199
+200
+201
+202
+203
+204
+205
+206
+207
+208
+209
+210
+211
+212
+213
+214
+215
+216
+217
+218
+219
+220
+221
+222
+223
+224
+225
+226
+227
+228
+229
+230
+231
+232
+233
+234
+235
+236
+237
+238
+239
+240
+241
+242
+243
+244
+245
+246
+247
+248
+249
+250
+251
+252
+253
+254
+255
+256
+257
+258
+259
+260
+261
+262
+263
+264
+265
+266
+267
+268
+269
+270
+271
+272
+273
+274
+275
+276
+277
+278
+279
+280
+281
+282
+283
+284
+285
+286
+287
+288
+289
+290
+291
+292
+293
+294
+295
+296
+297
+298
+299
+300
+301
+302
+303
+304
+305
+306
+307
+308
+309
+310
+311
+312
+313
+314
+315
+316
+317
+318
+319
+320
+321
+322
+323
+324
+325
+326
+327
+328
+329
+330
+331
+332
+333
+334
+335
+336
+337
+338
+339
+340
+341
// *****************************************************************************
 /*!
-  \file      src/Main/InciterPrint.hpp
+  \file      src/Main/Inciter.cpp
   \copyright 2012-2015 J. Bakosi,
              2016-2018 Los Alamos National Security, LLC.,
              2019-2021 Triad National Security, LLC.
              All rights reserved. See the LICENSE file for details.
-  \brief     Inciter-specific pretty printer functionality
-  \details   Inciter-specific pretty printer functionality.
-*/
-// *****************************************************************************
-#ifndef InciterPrint_h
-#define InciterPrint_h
-
-#include <iostream>
-#include <string>
-
-#include "NoWarning/format.hpp"
+  \brief     Inciter, computational shock hydrodynamics tool, Charm++ main
+    chare.
+  \details   Inciter, computational shock hydrodynamics tool, Charm++ main
+    chare. This file contains the definition of the Charm++ main chare,
+    equivalent to main() in Charm++-land.
+*/
+// *****************************************************************************
+
+#include <unordered_map>
+#include <vector>
+#include <iostream>
 
-#include "Print.hpp"
-#include "ContainerUtil.hpp"
-#include "Inciter/InputDeck/InputDeck.hpp"
-#include "Inciter/Options/Physics.hpp"
-#include "Inciter/Options/Problem.hpp"
-
-namespace inciter {
-
-extern ctr::InputDeck g_inputdeck_defaults;
-extern ctr::InputDeck g_inputdeck;
-
-//! InciterPrint : tk::Print
-class InciterPrint : public tk::Print {
-
-  public:
-    //! Constructor
-    //! \param[in] screen Screen output filename
-    //! \param[in,out] str Verbose stream
-    //! \param[in] mode Open mode for screen output file, see
-    //!   http://en.cppreference.com/w/cpp/io/ios_base/openmode
-    //! \param[in,out] qstr Quiet stream
-    //! \see tk::RNGPrint::RNGPrint and tk::Print::Print
-    explicit InciterPrint( const std::string& screen,
-                           std::ostream& str = std::clog,
-                           std::ios_base::openmode mode = std::ios_base::out,
-                           std::ostream& qstr = std::cout ) :
-      Print( screen, str, mode, qstr ) {}
-
-    //! Print control option: 'group : option'
-    template< typename Option, typename... tags >
-    void Item() const {
-      Option opt;
-      m_stream << m_item_name_value_fmt
-                  % m_item_indent % opt.group()
-                  % opt.name( g_inputdeck.get< tags... >() );
-    }
-
-    // Helper class for compact output of PDE policies
-    class Policies {
-      public:
-        // Default constructor
-        explicit Policies() : phys(), prob() {}
-        // Initializer constructor
-        explicit Policies( const std::string& p, const std::string& t ) :
-          phys(p), prob(t) {}
-        // Operator += for adding up two Policies structs
-        Policies& operator+= ( const Policies& p ) {
-          phys += p.phys;
-          prob += p.prob;
-          return *this;
-        }
-
-      private:
-        // Make all policies unique
-        void unique() { tk::unique( phys ); tk::unique( prob ); }
-
-        std::string phys;
-        std::string prob;
-    };
+#include "Types.hpp"
+#include "Init.hpp"
+#include "QuinoaConfig.hpp"
+#include "Timer.hpp"
+#include "Exception.hpp"
+#include "CGPDE.hpp"
+#include "DGPDE.hpp"
+#include "FVPDE.hpp"
+#include "PDEStack.hpp"
+#include "ProcessException.hpp"
+#include "InciterPrint.hpp"
+#include "InciterDriver.hpp"
+#include "Inciter/CmdLine/Parser.hpp"
+#include "Inciter/CmdLine/CmdLine.hpp"
+#include "Inciter/InputDeck/InputDeck.hpp"
+#include "ChareStateCollector.hpp"
+#include "LBSwitch.hpp"
+
+#include "NoWarning/inciter.decl.h"
+
+#if defined(__clang__)
+  #pragma clang diagnostic push
+  #pragma clang diagnostic ignored "-Wmissing-variable-declarations"
+#endif
+
+//! \brief Charm handle to the main proxy, facilitates call-back to finalize,
+//!    etc., must be in global scope, unique per executable
+CProxy_Main mainProxy;
+
+//! Chare state collector Charm++ chare group proxy
+tk::CProxy_ChareStateCollector stateProxy;
+
+//! Load balancer switch group proxy
+tk::CProxy_LBSwitch LBSwitchProxy;
+
+//! If true, call and stack traces are to be output with exceptions
+//! \note This is true by default so that the trace is always output between
+//!   program start and the Main ctor in which the user-input from command line
+//!   setting for this overrides this true setting.
+bool g_trace = true;
+
+#if defined(__clang__)
+  #pragma clang diagnostic pop
+#endif
+
+//! Inciter declarations and definitions
+namespace inciter {
+
+//! Global-scope data. Initialized by the main chare and distibuted to all PEs
+//! by the Charm++ runtime system. Though semantically not const, all these
+//! global data should be considered read-only. See also
+//! http://charm.cs.illinois.edu/manuals/html/charm++/manual.html. The data
+//! below is global-scope because they must be available to all PEs which could
+//! be on different machines.
+
+#if defined(__clang__)
+  #pragma clang diagnostic push
+  #pragma clang diagnostic ignored "-Wmissing-variable-declarations"
+#endif
 
-    //! Print equation list with policies
-    //! \param[in] t Section title
-    //! \param[in] factory Factory to get equation data from
-    //! \param[in] ntypes Unique equation types
-    template< class Factory >
-    void eqlist( const std::string& t,
-                 const Factory& factory,
-                 std::size_t ntypes ) const
-    {
-      if (!factory.empty()) {
-        section( t );
-        item( "Unique equation types", ntypes );
-        item( "With all policy combinations", factory.size() );
-      }
-    }
-
-    //! Print configuration of a stack of partial differential equations
-    void pdes( const std::string& t,
-      const std::vector< std::vector< std::pair< std::string, std::string > > >&
-        info ) const;
-
-    //! Print out info on solver coupling
-    void couple( const std::vector< Transfer >& transfer,
-                 const std::vector< char >& depvar ) const;
-
-    //! Print time integration header
-    void inthead( const std::string& t, const std::string& name,
-                  const std::string& legend, const std::string& head ) const;
-
-  private:
-    //! Return partial differential equation name
-    //! \param[in] key Equation key
-    //! \return Partial differential equation name based on key
-    template< class Key >
-    std::string PDEName ( const Key& key ) const<--- Unused private function: 'InciterPrint::PDEName'
-    { return ctr::PDE().name( key.template get< tag::pde >() ); }
-};
-
-} // inciter::
-
-#endif // InciterPrint_h
+//! Defaults of input deck, facilitates detection what is set by user
+//! \details This object is in global scope, it contains the default of all
+//!   possible user input, and thus it is made available to all PEs for
+//!   convenience reasons. The runtime system distributes it to all PEs during
+//!   initialization. Once distributed, the object does not change.
+ctr::InputDeck g_inputdeck_defaults;
+//! Lua Input deck filled by LuaParser, containing all input data
+//! \details This object is in global scope, it contains all of user input, and
+//!   thus it is made available to all PEs for convenience reasons. The runtime
+//!   system distributes it to all PEs during initialization. Once distributed,
+//!   the object does not change.
+ctr::InputDeck g_inputdeck;
+//! Partial differential equations using continuous Galerkin selected by user
+//! \details This vector is in global scope, because it holds polymorphic
+//!   objects, and thus must be distributed to all PEs during initialization.
+//!   Once distributed by the runtime system, the objects do not change.
+std::vector< CGPDE > g_cgpde;
+//! Partial differential equations using discontinuous Galerkin selected by user
+//! \details This vector is in global scope, because it holds polymorphic
+//!   objects, and thus must be distributed to all PEs during initialization.
+//!   Once distributed by the runtime system, the objects do not change.
+std::vector< DGPDE > g_dgpde;
+//! Partial differential equations using finite volume selected by user
+//! \details This vector is in global scope, because it holds polymorphic
+//!   objects, and thus must be distributed to all PEs during initialization.
+//!   Once distributed by the runtime system, the objects do not change.
+std::vector< FVPDE > g_fvpde;
+
+#if defined(__clang__)
+  #pragma clang diagnostic pop
+#endif
+
+//! \brief Pack/Unpack selected partial differential equations using continuous
+//!   Galerkin discretization.
+//! \details This Pack/Unpack method (re-)creates the PDE factory since it needs
+//!   to (re-)bind function pointers on different processing elements. Therefore
+//!   we circumvent Charm's usual pack/unpack for this type, and thus sizing
+//!   does not make sense: sizing is a no-op. We could initialize the factory in
+//!   InciterDriver's constructor and let this function re-create the stack only
+//!   when unpacking, but that leads to repeating the same code twice: once in
+//!   InciterDriver's constructor, once here. Another option is to use this
+//!   pack/unpack routine to both initially create (when packing) and to
+//!   re-create (when unpacking) the factory, which eliminates the need for
+//!   pre-creating the object in InciterDriver's constructor and therefore
+//!   eliminates the repeated code. This explains the guard for sizing: the code
+//!   below is called for packing only (in serial) and packing and unpacking (in
+//!   parallel).
+inline
+void operator|( PUP::er& p, std::vector< CGPDE >& eqs ) {
+  try {
+    if (!p.isSizing()) eqs = PDEStack().selectedCG();
+  } catch (...) { tk::processExceptionCharm(); }
+}
+
+//! \brief Pack/Unpack selected partial differential equations using
+//!   discontinuous Galerkin discretization.
+//! \details This Pack/Unpack method (re-)creates the PDE factory since it needs
+//!   to (re-)bind function pointers on different processing elements. Therefore
+//!   we circumvent Charm's usual pack/unpack for this type, and thus sizing
+//!   does not make sense: sizing is a no-op. We could initialize the factory in
+//!   InciterDriver's constructor and let this function re-create the stack only
+//!   when unpacking, but that leads to repeating the same code twice: once in
+//!   InciterDriver's constructor, once here. Another option is to use this
+//!   pack/unpack routine to both initially create (when packing) and to
+//!   re-create (when unpacking) the factory, which eliminates the need for
+//!   pre-creating the object in InciterDriver's constructor and therefore
+//!   eliminates the repeated code. This explains the guard for sizing: the code
+//!   below is called for packing only (in serial) and packing and unpacking (in
+//!   parallel).
+inline
+void operator|( PUP::er& p, std::vector< DGPDE >& eqs ) {
+  try {
+    if (!p.isSizing()) eqs = PDEStack().selectedDG();
+  } catch (...) { tk::processExceptionCharm(); }
+}
+
+//! \brief Pack/Unpack selected partial differential equations using
+//!   finite volume discretization.
+//! \details This Pack/Unpack method (re-)creates the PDE factory since it needs
+//!   to (re-)bind function pointers on different processing elements. Therefore
+//!   we circumvent Charm's usual pack/unpack for this type, and thus sizing
+//!   does not make sense: sizing is a no-op. We could initialize the factory in
+//!   InciterDriver's constructor and let this function re-create the stack only
+//!   when unpacking, but that leads to repeating the same code twice: once in
+//!   InciterDriver's constructor, once here. Another option is to use this
+//!   pack/unpack routine to both initially create (when packing) and to
+//!   re-create (when unpacking) the factory, which eliminates the need for
+//!   pre-creating the object in InciterDriver's constructor and therefore
+//!   eliminates the repeated code. This explains the guard for sizing: the code
+//!   below is called for packing only (in serial) and packing and unpacking (in
+//!   parallel).
+inline
+void operator|( PUP::er& p, std::vector< FVPDE >& eqs ) {
+  try {
+    if (!p.isSizing()) eqs = PDEStack().selectedFV();
+  } catch (...) { tk::processExceptionCharm(); }
+}
+
+} // inciter::
+
+//! \brief Charm++ main chare for the shock hydrodynamics executable, inciter.
+//! \details In inciter the Charm++ runtime system is initialized only after the
+//!   mesh has been read in, partitioned, and the necessary data structures,
+//!   e.g., communication maps, have been generated. This delayed initialization
+//!   of the Charm++ runtime system is required since the mesh partitioning is
+//!   done by Zoltan, an MPI library. Note that this Charm++ main chare object
+//!   should not be in a namespace.
+// cppcheck-suppress noConstructor
+class Main : public CBase_Main {<--- Unmatched suppression: noConstructor
+
+  public:
+    //! \brief Constructor
+    //! \details Inciter's main chare constructor is the entry point of the
+    //!   Charm++ portion of inciter, called by the Charm++ runtime system. The
+    //!   constructor does basic initialization steps, prints out some useful
+    //!   information to screen (in verbose mode), and instantiates a driver.
+    //!   Since Charm++ is fully asynchronous, the constructor usually spawns
+    //!   asynchronous objects and immediately exits. Thus in the body of the
+    //!   main chare constructor we fire up an 'execute' chare, which then calls
+    //!   back to Main::execute(). Finishing the main chare constructor the
+    //!   Charm++ runtime system then starts the network-migration of all
+    //!   global-scope data (if any). The execute chare calling back to
+    //!   Main::execute() signals the end of the migration of the global-scope
+    //!   data. Then we are ready to execute the driver. Since inciter is
+    //!   parallel and asynchronous, its driver fires up additional Charm++
+    //!   chare objects which then call back to Main::finalize() at some point
+    //!   in the future when all work has been finished. finalize() then exits
+    //!   by calling Charm++'s CkExit(), shutting down the runtime system.
+    //! \see http://charm.cs.illinois.edu/manuals/html/charm++/manual.html
+    Main( CkArgMsg* msg )
+    try :
+      m_signal( tk::setSignalHandlers() ),
+      m_cmdline(),
+      // Parse command line into m_cmdline using default simple pretty printer
+      m_cmdParser( msg->argc, msg->argv, tk::Print(), m_cmdline ),
+      // Create Inciter driver
+      m_driver( tk::Main< inciter::InciterDriver >
+                        ( msg->argc, msg->argv,
+                          m_cmdline,
+                          tk::HeaderType::INCITER,
+                          tk::inciter_executable(),
+                          inciter::g_inputdeck_defaults.get< tag::cmd, tag::io,
+                            tag::screen >(),
+                          inciter::g_inputdeck_defaults.get< tag::cmd, tag::io,
+                            tag::nrestart >() ) ),
+      // Start new timer measuring the total runtime
+      m_timer(1),
+      m_timestamp()
+    {
+      delete msg;
+      g_trace = m_cmdline.get< tag::trace >();
+      tk::MainCtor( mainProxy, thisProxy, m_timer, m_cmdline,
+                    CkCallback( CkIndex_Main::quiescence(), thisProxy ) );
+      // If quiescence detection is on or user requested it, create chare state
+      // collector Charm++ chare group
+      if ( m_cmdline.get< tag::chare >() || m_cmdline.get< tag::quiescence >() )
+        stateProxy = tk::CProxy_ChareStateCollector::ckNew();
+      // Fire up an asynchronous execute object, which when created at some
+      // future point in time will call back to this->execute(). This is
+      // necessary so that this->execute() can access already migrated
+      // global-scope data.
+      CProxy_execute::ckNew();
+    } catch (...) { tk::processExceptionCharm(); }
+
+    //! Migrate constructor: returning from a checkpoint
+    explicit Main( CkMigrateMessage* msg ) : CBase_Main( msg ),
+      m_signal( tk::setSignalHandlers() ),
+      m_cmdline(),
+      m_cmdParser( reinterpret_cast<CkArgMsg*>(msg)->argc,
+                   reinterpret_cast<CkArgMsg*>(msg)->argv,
+                   tk::Print(),
+                   m_cmdline ),
+      m_driver( tk::Main< inciter::InciterDriver >
+                        ( reinterpret_cast<CkArgMsg*>(msg)->argc,
+                          reinterpret_cast<CkArgMsg*>(msg)->argv,
+                          m_cmdline,
+                          tk::HeaderType::INCITER,
+                          tk::inciter_executable(),
+                          inciter::g_inputdeck_defaults.get< tag::cmd,
+                            tag::io, tag::screen >(),
+                          inciter::g_inputdeck.get< tag::cmd,
+                            tag::io, tag::nrestart >()+1 ) ),
+      m_timer(1),
+      m_timestamp()
+    {
+      // increase number of restarts (available for Transporter on PE 0)
+      ++inciter::g_inputdeck.get< tag::cmd, tag::io, tag::nrestart >();
+      g_trace = m_cmdline.get< tag::trace >();
+      tk::MainCtor( mainProxy, thisProxy, m_timer, m_cmdline,
+                    CkCallback( CkIndex_Main::quiescence(), thisProxy ) );
+    }
+
+    //! Execute driver created and initialized by constructor
+    void execute() {
+      try {
+        m_timestamp.emplace_back("Migrate global-scope data", m_timer[1].hms());
+        m_driver.execute();
+      } catch (...) { tk::processExceptionCharm(); }
+    }
+
+    //! Towards normal exit but collect chare state first (if any)
+    void finalize() {
+      tk::finalize( m_cmdline, m_timer, stateProxy, m_timestamp,
+        inciter::g_inputdeck_defaults.get< tag::cmd, tag::io, tag::screen >(),
+        inciter::g_inputdeck.get< tag::cmd, tag::io, tag::nrestart >(),
+        CkCallback( CkIndex_Main::dumpstate(nullptr), thisProxy ) );
+    }
+
+    //! Entry method triggered when quiescence is detected
+    void quiescence() {
+      try {
+        stateProxy.collect( /* error= */ true,
+          CkCallback( CkIndex_Main::dumpstate(nullptr), thisProxy ) );
+      } catch (...) { tk::processExceptionCharm(); }
+    }
+
+    //! Dump chare state
+    void dumpstate( CkReductionMsg* msg ) {
+      tk::dumpstate( m_cmdline,
+        inciter::g_inputdeck_defaults.get< tag::cmd, tag::io, tag::screen >(),
+        inciter::g_inputdeck.get< tag::cmd, tag::io, tag::nrestart >(),
+        msg );
+    }
+
+    /** @name Charm++ pack/unpack serializer member functions */
+    ///@{
+    //! \brief Pack/Unpack serialize member function
+    //! \param[in,out] p Charm++'s PUP::er serializer object reference
+    //! \note This is a Charm++ mainchare, pup() is thus only for
+    //!    checkpoint/restart.
+    void pup( PUP::er &p ) override {
+      p | m_timer;
+    }
+    //! \brief Pack/Unpack serialize operator|
+    //! \param[in,out] p Charm++'s PUP::er serializer object reference
+    //! \param[in,out] m Mainchare object reference
+    friend void operator|( PUP::er& p, Main& m ) { m.pup(p); }
+    //@}
+
+  private:
+    int m_signal;                               //!< Used to set signal handlers
+    inciter::ctr::CmdLine m_cmdline;            //!< Command line
+    inciter::CmdLineParser m_cmdParser;         //!< Command line parser
+    inciter::InciterDriver m_driver;            //!< Driver
+    std::vector< tk::Timer > m_timer;           //!< Timers
+    //! Time stamps in h:m:s with labels
+    std::vector< std::pair< std::string, tk::Timer::Watch > > m_timestamp;
+};
+
+//! \brief Charm++ chare execute
+//! \details By the time this object is constructed, the Charm++ runtime system
+//!    has finished migrating all global-scoped read-only objects which happens
+//!    after the main chare constructor has finished.
+class execute : public CBase_execute {
+  public:
+    //! Constructor
+    execute() { mainProxy.execute(); }
+    //! Migrate constructor
+    explicit execute( CkMigrateMessage* m ) : CBase_execute( m ) {}
+};
+
+#include "NoWarning/inciter.def.h"
 
diff --git a/Release/cppcheck/4.html b/Release/cppcheck/4.html index c6f94849c200..aefb215d2cb6 100644 --- a/Release/cppcheck/4.html +++ b/Release/cppcheck/4.html @@ -152,12 +152,12 @@
  1
@@ -280,149 +280,127 @@ 

Cppcheck report - [

// *****************************************************************************
+121
// *****************************************************************************
 /*!
-  \file      src/IO/UGRIDMeshReader.cpp
+  \file      src/IO/MeshWriter.hpp
   \copyright 2012-2015 J. Bakosi,
              2016-2018 Los Alamos National Security, LLC.,
              2019-2021 Triad National Security, LLC.
              All rights reserved. See the LICENSE file for details.
-  \brief     UGRID mesh reader class declaration
-  \details   UGRID mesh reader class declaration. Mesh reader facilitating
-             reading a mesh from a simple text file used by NASA.
-  \see       http://www.simcenter.msstate.edu/software/downloads/doc/ug_io/3d_grid_file_type_ugrid.html, http://www.simcenter.msstate.edu/software/downloads/doc/aflr3/aflr3_io_summary.html
-*/
-// *****************************************************************************
-
-#include <array>
-#include <istream>
-#include <string>
+  \brief     Charm++ group for outputing mesh data to file
+  \details   Charm++ group declaration used to output data associated to
+     unstructured meshes to file(s). Charm++ chares (work units) send mesh and
+     field data associated to mesh entities to the MeshWriter class defined here
+     to write the data to file(s).
+*/
+// *****************************************************************************
+#ifndef MeshWriter_h
+#define MeshWriter_h
+
 #include <vector>
-#include <cstddef>
-
-#include "Types.hpp"
-#include "Exception.hpp"
-#include "UnsMesh.hpp"
-#include "Reorder.hpp"
-#include "UGRIDMeshReader.hpp"
-
-using tk::UGRIDMeshReader;
-
-void
-UGRIDMeshReader::readHeader()
-// *****************************************************************************
-//  Read UGRID mesh header
-// *****************************************************************************
-{
-  std::string s;<--- Unused variable: s
-
-  // Number_of_Nodes
-  m_inFile >> m_nnode;
-
-  // Number_of_Surf_Trias
-  m_inFile >> m_ntri;
-
-  // Number_of_Surf_Quads
-  int nquad;
-  m_inFile >> nquad;
-
-  // Number_of_Vol_Tets
-  m_inFile >> m_ntet;
-
-  // Number_of_Vol_Pents_5
-  int pent5;
-  m_inFile >> pent5;
-
-  // Number_of_Vol_Pents_6
-  int pent6;
-  m_inFile >> pent6;
-
-  // Number_of_Vol_Hexs
-  int nhex;
-  m_inFile >> nhex;
-}
-
-void
-UGRIDMeshReader::readMesh( UnsMesh& mesh )
-// *****************************************************************************
-//  Read UGRID mesh
-//! \param[in] mesh Unstructured mesh object
-// *****************************************************************************
-{
-  // Read header
-  readHeader();
-  // Read nodes
-  readNodes( mesh );
-  // Read elements
-  readElements( mesh );
-}
-
-void
-UGRIDMeshReader::readNodes( UnsMesh& mesh )
-// *****************************************************************************
-//  Read nodes
-//! \param[in] mesh Unstructured mesh object
-// *****************************************************************************
-{
-  // Read in node coordinates: x-coord y-coord z-coord
-  for (std::size_t i=0; i<m_nnode; ++i) {
-    tk::real x, y, z;
-    m_inFile >> x >> y >> z;
-    mesh.x().push_back( x );
-    mesh.y().push_back( y );
-    mesh.z().push_back( z );
-  }
-}
-
-void
-UGRIDMeshReader::readElements( UnsMesh& mesh )
-// *****************************************************************************
-//  Read element connectivity
-//! \param[in] mesh Unstructured mesh object
-// *****************************************************************************
-{
-  // Read in triangle element connectivity
-  for (std::size_t i=0; i<m_ntri; ++i) {
-    std::array< std::size_t, 3 > n;
-    m_inFile >> n[0] >> n[1] >> n[2];
-    mesh.triinpoel().push_back( n[0] );
-    mesh.triinpoel().push_back( n[1] );
-    mesh.triinpoel().push_back( n[2] );
-  }
+#include <string>
+#include <tuple>
+#include <map>
+
+#include "Types.hpp"
+#include "Options/FieldFile.hpp"
+#include "Centering.hpp"
+#include "UnsMesh.hpp"
+
+#include "NoWarning/meshwriter.decl.h"
+
+namespace tk {
+
+//! Charm++ group used to output particle data to file in parallel
+class MeshWriter : public CBase_MeshWriter {
+
+  public:
+    //! Constructor: set some defaults that stay constant at all times
+    MeshWriter( ctr::FieldFileType filetype,
+                Centering bnd_centering,
+                bool benchmark,
+                std::size_t nmesh );
+
+    #if defined(__clang__)
+      #pragma clang diagnostic push
+      #pragma clang diagnostic ignored "-Wundefined-func-template"
+    #endif
+    //! Migrate constructor
+    explicit MeshWriter( CkMigrateMessage* m ) : CBase_MeshWriter( m ) {}<--- Member variable 'MeshWriter::m_filetype' is not initialized in the constructor.<--- Member variable 'MeshWriter::m_benchmark' is not initialized in the constructor.<--- Member variable 'MeshWriter::m_nmesh' is not initialized in the constructor.
+    #if defined(__clang__)
+      #pragma clang diagnostic pop
+    #endif
+
+    //! Set the total number of chares
+    void nchare( std::size_t meshid, int n );
+
+    //! Output unstructured mesh into file
+    void write( std::size_t meshid,
+                bool meshoutput,
+                bool fieldoutput,
+                uint64_t itr,
+                uint64_t itf,
+                tk::real time,
+                int chareid,
+                const std::string& basefilename,
+                const std::vector< std::size_t >& inpoel,
+                const UnsMesh::Coords& coord,
+                const std::map< int, std::vector< std::size_t > >& bface,
+                const std::map< int, std::vector< std::size_t > >& bnode,
+                const std::vector< std::size_t >& triinpoel,
+                const std::vector< std::string >& elemfieldnames,
+                const std::vector< std::string >& nodefieldnames,
+                const std::vector< std::string >& elemsurfnames,
+                const std::vector< std::string >& nodesurfnames,
+                const std::vector< std::vector< tk::real > >& elemfields,
+                const std::vector< std::vector< tk::real > >& nodefields,
+                const std::vector< std::vector< tk::real > >& elemsurfs,
+                const std::vector< std::vector< tk::real > >& nodesurfs,
+                const std::set< int >& outsets,
+                CkCallback c );
+
+    /** @name Charm++ pack/unpack serializer member functions */
+    ///@{
+    //! \brief Pack/Unpack serialize member function
+    //! \param[in,out] p Charm++'s PUP::er serializer object reference
+    //! \note This is a Charm++ group, pup() is thus only for
+    //!    checkpoint/restart.
+    void pup( PUP::er &p ) override {
+      p | m_filetype;
+      p | m_bndCentering;
+      p | m_benchmark;
+      p | m_nmesh;
+      p | m_nchare;
+    }
+    //! \brief Pack/Unpack serialize operator|
+    //! \param[in,out] p Charm++'s PUP::er serializer object reference
+    //! \param[in,out] m MeshWriter object reference
+    friend void operator|( PUP::er& p, MeshWriter& m ) { m.pup(p); }
+    //@}
+
+  private:
+    //! Output file format type
+    ctr::FieldFileType m_filetype;
+    //! Centering to identify what boundary data to write.
+    Centering m_bndCentering;
+    //! True if benchmark mode
+    bool m_benchmark;
+    //! Total number of meshes
+    std::size_t m_nmesh;
+    //! Total number chares across the whole problem (one per mesh)
+    std::vector< int > m_nchare;
 
-  // Read side sets of triangle elements
-  for (std::size_t i=0; i<m_ntri; ++i) {
-    int setid;
-    m_inFile >> setid;
-    mesh.bface()[ setid ].push_back( m_ntet + i );
-    mesh.faceid()[ setid ].push_back( 0 );
-  }
+    //! Compute filename
+    std::string filename( const std::string& basefilename,
+                          std::size_t meshid,
+                          uint64_t itr,
+                          int chareid,
+                          int surfid = 0 ) const;
+};
 
-  // Read in tetrahedra element connectivity
-  for (std::size_t i=0; i<m_ntet; ++i) {
-    std::array< std::size_t, 4 > n;
-    m_inFile >> n[0] >> n[1] >> n[2] >> n[3];
-    mesh.tetinpoel().push_back( n[0] );
-    mesh.tetinpoel().push_back( n[1] );
-    mesh.tetinpoel().push_back( n[2] );
-    mesh.tetinpoel().push_back( n[3] );
-  }
-
-  // Shift node IDs to start from zero
-  shiftToZero( mesh.triinpoel() );
-  shiftToZero( mesh.tetinpoel() );
-}
+} // tk::
+
+#endif // MeshWriter_h
 
diff --git a/Release/cppcheck/40.html b/Release/cppcheck/40.html index 222e171fa668..46a37a5f70b1 100644 --- a/Release/cppcheck/40.html +++ b/Release/cppcheck/40.html @@ -152,12 +152,12 @@
  1
@@ -350,197 +350,419 @@ 

Cppcheck report - [

// *****************************************************************************
+191
+192
+193
+194
+195
+196
+197
+198
+199
+200
+201
+202
+203
+204
+205
+206
+207
+208
+209
+210
+211
+212
+213
+214
+215
+216
+217
+218
+219
+220
+221
+222
+223
+224
+225
+226
+227
+228
+229
+230
+231
+232
+233
+234
+235
+236
+237
+238
+239
+240
+241
+242
+243
+244
+245
+246
+247
+248
+249
+250
+251
+252
+253
+254
+255
+256
+257
+258
+259
+260
+261
+262
+263
+264
+265
+266
+267
+268
+269
+270
+271
+272
+273
+274
+275
+276
+277
+278
+279
+280
+281
+282
+283
+284
+285
+286
+287
+288
+289
+290
+291
+292
+293
+294
+295
+296
+297
+298
+299
+300
+301
+302
// *****************************************************************************
 /*!
-  \file      src/Control/Inciter/InputDeck/LuaParser.hpp
-  \copyright 2019-2023 Triad National Security, LLC.
-             All rights reserved. See the LICENSE file for details.
-  \brief     Inciter's lua input deck file parser
-  \details   This file declares the input deck, i.e., control file, parser for
-    the computational shock hydrodynamics tool, Inciter.
-*/
-// *****************************************************************************
-#ifndef InciterLuaParser_h
-#define InciterLuaParser_h
-
-#include "NoWarning/sol.hpp"
-
-#include "Inciter/CmdLine/CmdLine.hpp"
-#include "InputDeck.hpp"
-
-namespace tk { class Print; }
-
-namespace inciter {
+  \file      src/Inciter/Ghosts.hpp
+  \copyright 2012-2015 J. Bakosi,
+             2016-2018 Los Alamos National Security, LLC.,
+             2019-2021 Triad National Security, LLC.
+             All rights reserved. See the LICENSE file for details.
+  \brief     Declarations file for generating ghost data structures
+  \details   Declarations file for asynchronous distributed
+             ghost data structures using Charm++.
+
+    There are a potentially large number of Ghosts Charm++ chares.
+    Each Ghosts chare gets a chunk of the full load, due to partiting the mesh.
+
+    The implementation uses the Charm++ runtime system and is fully
+    asynchronous, overlapping computation and communication. The algorithm
+    utilizes the structured dagger (SDAG) Charm++ functionality.
+*/
+// *****************************************************************************
+#ifndef Ghosts_h
+#define Ghosts_h
 
-//! \brief Control file lua-parser for Inciter.
-//! \details This class is used to interface with sol2, for the purpose of
-//!   parsing the control file for the computational shock hydrodynamics tool,
-//!   Inciter.
-class LuaParser {
+#include "Fields.hpp"
+#include "FaceData.hpp"
+#include "Discretization.hpp"
+
+#include "NoWarning/ghosts.decl.h"
 
-  public:
-    //! Constructor
-    explicit LuaParser( const tk::Print& print,
-                              const ctr::CmdLine& cmdline,
-                              ctr::InputDeck& inputdeck );
-
-    //! Store lua inputdeck in custom struct
-    void storeInputDeck(
-      const sol::table& lua_ideck,
-      ctr::InputDeck& gideck );
-
-    //! Check and store material property into inpudeck storage
-    void checkStoreMatProp(
-      const sol::table table,
-      const std::string key,
-      std::size_t vecsize,
-      std::vector< tk::real >& storage );
-
-    //! Check and store field output variables
-    void addOutVar(
-      const std::string& varname,
-      const std::string& alias,
-      std::vector< char >& depv,
-      std::size_t nmat,
-      inciter::ctr::PDEType pde,
-      tk::Centering c,
-      std::vector< inciter::ctr::OutVar >& foutvar );
-
-  private:
-    const std::string m_filename;             //!< Name of file to parse
-
-    //! Assign parameter to inputdeck entry if specified, else default
-    //! \tparam N Type of parameter being read/assigned
-    //! \param[in] table Sol-table which contains said parameter
-    //! \param[in] key Key for said parameter in Sol-table
-    //! \param[in,out] storage Storage space in inputdeck where said parameter
-    //!   is to be stored
-    //! \param[in] dflt Default value of said parameter, if unspecified
-    template< typename N > void
-    storeIfSpecd(
-      const sol::table table,
-      const std::string key,
-      N& storage,
-      const N dflt )
-    {
-      auto sol_var = table[key];
-      if (sol_var.valid())
-        storage = sol_var;
-      else
-        storage = dflt;
-    }
-
-    //! Assign Option to inputdeck entry if specified, else default
-    //! \tparam Op Option-Type of parameter being read/assigned
-    //! \tparam OpClass Option-class of parameter being read/assigned
-    //! \param[in] table Sol-table which contains said parameter
-    //! \param[in] key Key for said parameter in Sol-table
-    //! \param[in,out] storage Storage space in inputdeck where said parameter
-    //!   is to be stored
-    //! \param[in] dflt Default value of said parameter, if unspecified
-    template< typename Op, class OpClass > void
-    storeOptIfSpecd(
-      const sol::table table,
-      const std::string key,
-      Op& storage,
-      const Op dflt )
-    {
-      OpClass opt;
-      auto sol_var = table[key];
-      if (sol_var.valid())
-        storage = opt.value(sol_var);
-      else
-        storage = dflt;
-    }
-
-    //! Assign vector parameter to inputdeck entry if specified, else default
-    //! \tparam N Type of parameter vector being read/assigned
-    //! \param[in] table Sol-table which contains said parameter
-    //! \param[in] key Key for said parameter in Sol-table
-    //! \param[in,out] storage Storage space in inputdeck where said parameter
-    //!   is to be stored
-    //! \param[in] dflt Default value of said parameter, if unspecified
-    template< typename N > void
-    storeVecIfSpecd(
-      const sol::table table,
-      const std::string key,
-      std::vector< N >& storage,
-      const std::vector< N >& dflt )
-    {
-      auto sol_vec = table[key];
-      if (sol_vec.valid()) {
-        for (std::size_t i=0; i<sol::table(sol_vec).size(); ++i)
-          storage.push_back(sol_vec[i+1]);
-      }
-      else
-        storage = dflt;
-    }
-
-    //! Assign vector of Options to inputdeck entry if specified, else default
-    //! \tparam Op Option-Type of parameter being read/assigned
-    //! \tparam OpClass Option-class of parameter being read/assigned
-    //! \param[in] table Sol-table which contains said parameter
-    //! \param[in] key Key for said parameter in Sol-table
-    //! \param[in,out] storage Storage space in inputdeck where said parameter
-    //!   is to be stored
-    //! \param[in] dflt Default value of said parameter, if unspecified
-    template< typename Op, class OpClass > void
-    storeOptVecIfSpecd(
-      const sol::table table,
-      const std::string key,
-      std::vector< Op >& storage,
-      const std::vector< Op >& dflt )
-    {
-      OpClass opt;
-      auto sol_vec = table[key];
-      if (sol_vec.valid()) {
-        for (std::size_t i=0; i<sol::table(sol_vec).size(); ++i)
-          storage.push_back(opt.value(sol_vec[i+1]));
-      }
-      else
-        storage = dflt;
-    }
-
-    //! \brief Check validity of keywords within a particular block
-    //! \tparam tags Tags addressing the said block in the input deck
-    //! \param[in] block Sol table of the input deck block read in from the
-    //!   lua file
-    //! \param[in] blk_name Name of the block, for error clarity
-    template< typename... tags >
-    void checkBlock(const sol::table& block, const std::string& blk_name) const
-    {
-      for (const auto& kvp : block) {
-        bool is_valid(false);
-        auto ukw = kvp.first.as<std::string>();
-        brigand::for_each< tags... >( checkKw(ukw, is_valid) );
-        if (!is_valid)
-          Throw("Invalid keyword '" + ukw + "' in '" + blk_name + "' block.");
-      }
-    }
-
-    // Check if a keyword matches the existing ones
-    struct checkKw {
-      std::string user_kw;
-      // reference to bool keeping track of kw-match
-      bool& is_valid;
-      // Constructor
-      checkKw( const std::string& ukw, bool& isv ) :
-        user_kw(ukw), is_valid(isv) {}
-      //! Function to call for each keyword type
-      template< typename U > void operator()( brigand::type_<U> ) {
-        auto spec_key = U::name();
-        // only check if not previously matched
-        if (!is_valid) {
-          if (user_kw == spec_key) is_valid = true;
-          else is_valid = false;
-        }
-      }
-    };
-};
-
-} // namespace inciter
-
-#endif // InciterLuaParser_h
+namespace inciter {
+
+//! Ghosts Charm++ chare array used to determine ghost data structures
+class Ghosts : public CBase_Ghosts {
+
+  public:
+    #if defined(__clang__)
+      #pragma clang diagnostic push
+      #pragma clang diagnostic ignored "-Wunused-parameter"
+      #pragma clang diagnostic ignored "-Wdeprecated-declarations"
+    #elif defined(STRICT_GNUC)
+      #pragma GCC diagnostic push
+      #pragma GCC diagnostic ignored "-Wunused-parameter"
+      #pragma GCC diagnostic ignored "-Wdeprecated-declarations"
+    #elif defined(__INTEL_COMPILER)
+      #pragma warning( push )
+      #pragma warning( disable: 1478 )
+    #endif
+    // Include Charm++ SDAG code. See http://charm.cs.illinois.edu/manuals/html/
+    // charm++/manual.html, Sec. "Structured Control Flow: Structured Dagger".
+    Ghosts_SDAG_CODE
+    #if defined(__clang__)
+      #pragma clang diagnostic pop
+    #elif defined(STRICT_GNUC)
+      #pragma GCC diagnostic pop
+    #elif defined(__INTEL_COMPILER)
+      #pragma warning( pop )
+    #endif
+
+    //! Constructor
+    explicit
+    Ghosts( const CProxy_Discretization& disc,
+      const std::map< int, std::vector< std::size_t > >& bface,
+      const std::vector< std::size_t >& triinpoel,
+      std::size_t nunk,
+      CkCallback cbDone );
+
+    #if defined(__clang__)
+      #pragma clang diagnostic push
+      #pragma clang diagnostic ignored "-Wundefined-func-template"
+    #endif
+    //! Migrate constructor
+    // cppcheck-suppress uninitMemberVar
+    explicit Ghosts( CkMigrateMessage* ) {}
+    #if defined(__clang__)
+      #pragma clang diagnostic pop
+    #endif
+
+    //! Local face & tet IDs associated to 3 global node IDs
+    //! \details This map stores tetrahedron cell faces (map key) and their
+    //!   associated local face ID and inner local tet id adjacent to the face
+    //!   (map value). A face is given by 3 global node IDs.
+    using FaceMap =
+      std::unordered_map< tk::UnsMesh::Face,  // 3 global node IDs
+                          std::array< std::size_t, 2 >, // local face & tet ID
+                          tk::UnsMesh::Hash<3>,
+                          tk::UnsMesh::Eq<3> >;
+
+    //! Storage type for refined mesh used for field output
+    struct OutMesh {
+      //! Element connectivity, local->global node ids, global->local nodes ids
+      tk::UnsMesh::Chunk chunk;
+      //! Node coordinates
+      tk::UnsMesh::Coords coord;
+      //! Triangle element connectivity
+      std::vector< std::size_t > triinpoel;
+      //! Boundary-face connectivity
+      std::map< int, std::vector< std::size_t > > bface;
+      //! Node communinaction map
+      tk::NodeCommMap nodeCommMap;
+      //! \brief Pack/Unpack serialize member function
+      //! \param[in,out] p Charm++'s PUP::er serializer object reference
+      void pup( PUP::er& p ) {<--- Parameter 'p' can be declared with const
+        p|chunk; p|coord; p|triinpoel; p|bface; p|nodeCommMap;
+      }
+      //! Destroyer
+      void destroy() {
+        tk::destroy( std::get<0>(chunk) );
+        tk::destroy( std::get<1>(chunk) );
+        tk::destroy( std::get<2>(chunk) );
+        tk::destroy( coord[0] );
+        tk::destroy( coord[1] );
+        tk::destroy( coord[2] );
+        tk::destroy( triinpoel );
+        tk::destroy( bface );
+        tk::destroy( nodeCommMap );
+      }
+    };
+
+    //! Discretization proxy
+    CProxy_Discretization m_disc;
+    //! Counter for number of unknowns on this chare (including ghosts)
+    std::size_t m_nunk;
+    //! Mesh connectivity extended
+    std::vector< std::size_t > m_inpoel;
+    //! Node coordinates extended
+    tk::UnsMesh::Coords m_coord;
+    //! Face data
+    FaceData m_fd;
+    //! Face geometry
+    tk::Fields m_geoFace;
+    //! Element geometry
+    tk::Fields m_geoElem;
+    //! Counter for number of faces on this chare (including chare boundaries)
+    std::size_t m_nfac;
+    //! Face & tet IDs associated to global node IDs of the face for each chare
+    //! \details This map stores not only the unique faces associated to
+    //!   fellow chares, but also a newly assigned local face ID and adjacent
+    //!   local tet ID.
+    std::unordered_map< int, FaceMap > m_bndFace;
+    //! Elements which are ghosts for other chares associated to those chare IDs
+    std::unordered_map< int, std::unordered_set< std::size_t > > m_sendGhost;
+    //! Local element id associated to ghost remote id charewise
+    //! \details This map associates the local element id (inner map value) to
+    //!    the (remote) element id of the ghost (inner map key) based on the
+    //!    chare id (outer map key) this remote element lies in.
+    std::unordered_map< int,
+      std::unordered_map< std::size_t, std::size_t > > m_ghost;
+    //! Expected ghost tet ids (used only in DEBUG)
+    std::set< std::size_t > m_exptGhost;
+    //! Map local ghost tet ids (value) and zero-based boundary ids (key)
+    std::unordered_map< std::size_t, std::size_t > m_bid;
+    //! Elements (value) surrounding point (key) data-structure
+    std::map< std::size_t, std::vector< std::size_t > > m_esup;
+    //! 1 if starting time stepping, 0 if during time stepping
+    std::size_t m_initial;
+
+    //1 Start setup of communication maps for cell-centered schemes
+    void startCommSetup();
+
+    //! Start sizing communication buffers and setting up ghost data
+    void resizeComm();
+
+    //! Receive unique set of faces we potentially share with/from another chare
+    void comfac( int fromch, const tk::UnsMesh::FaceSet& infaces );
+
+    //! Receive ghost data on chare boundaries from fellow chare
+    void comGhost( int fromch, const GhostData& ghost );
+
+    //! Receive requests for ghost data
+    void reqGhost();
+
+    //! Send all of our ghost data to fellow chares
+    void sendGhost();
+
+    //! Setup node-neighborhood (esup)
+    void nodeNeighSetup();
+
+    //! Receive element-surr-points data on chare boundaries from fellow chare
+    void comEsup( int fromch,
+      const std::unordered_map< std::size_t, std::vector< std::size_t > >&
+        bndEsup,
+      const std::unordered_map< std::size_t, std::vector< tk::real > >&
+        nodeBndCells );
+
+    /** @name Pack/unpack (Charm++ serialization) routines */
+    ///@{
+    //! \brief Pack/Unpack serialize member function
+    //! \param[in,out] p Charm++'s PUP::er serializer object reference
+    void pup( PUP::er &p ) override {
+      p | m_disc;
+      p | m_nunk;
+      p | m_inpoel;
+      p | m_coord;
+      p | m_fd;
+      p | m_geoFace;
+      p | m_geoElem;
+      p | m_nfac;
+      p | m_bndFace;
+      p | m_sendGhost;
+      p | m_ghost;
+      p | m_exptGhost;
+      p | m_bid;
+      p | m_esup;
+      p | m_initial;
+      p | m_ncomfac;
+      p | m_nadj;
+      p | m_ncomEsup;
+      p | m_ipface;
+      p | m_ghostData;
+      p | m_ghostReq;
+      p | m_expChBndFace;
+      p | m_infaces;
+      p | m_esupc;
+      p | m_cbAfterDone;
+    }
+    //! \brief Pack/Unpack serialize operator|
+    //! \param[in,out] p Charm++'s PUP::er serializer object reference
+    //! \param[in,out] a Ghosts object reference
+    friend void operator|( PUP::er& p, Ghosts& a ) { a.pup(p); }
+    ///@}
+
+  private:
+    using ncomp_t = tk::ncomp_t;
+
+    //! Counter for face adjacency communication map
+    std::size_t m_ncomfac;
+    //! Counter signaling that all ghost data have been received
+    std::size_t m_nadj;
+    //! Counter for element-surr-node adjacency communication map
+    std::size_t m_ncomEsup;
+    //! Internal + physical boundary faces (inverse of inpofa)
+    tk::UnsMesh::FaceSet m_ipface;
+    //! Ghost data associated to chare IDs we communicate with
+    std::unordered_map< int, GhostData > m_ghostData;
+    //! Number of chares requesting ghost data
+    std::size_t m_ghostReq;
+    //! Unique set of chare-boundary faces this chare is expected to receive
+    tk::UnsMesh::FaceSet m_expChBndFace;
+    //! Incoming communication buffer during chare-boundary face communication
+    std::unordered_map< int, tk::UnsMesh::FaceSet > m_infaces;
+    //! Communication buffer for esup data-structure
+    std::map< std::size_t, std::vector< std::size_t > > m_esupc;
+    //! Function call to continue with in Scheme when Ghosts is done
+    CkCallback m_cbAfterDone;
+
+    //! Access bound Discretization class pointer
+    Discretization* Disc() const {
+      Assert( m_disc[ thisIndex ].ckLocal() != nullptr, "ckLocal() null" );
+      return m_disc[ thisIndex ].ckLocal();
+    }
+
+    //! Compute chare-boundary faces
+    void bndFaces();
+
+    //! Setup own ghost data on this chare
+    void setupGhost();
+
+    //! Continue after face adjacency communication map completed on this chare
+    void faceAdj();
+
+    //! Compute partial boundary surface integral and sum across all chares
+    void bndIntegral();
+
+    //! Continue after node adjacency communication map completed on this chare
+    void adj();
+
+    //! Perform leak-test on chare boundary faces
+    bool leakyAdjacency();
+
+    //! Check if esuf of chare-boundary faces matches
+    bool faceMatch();
+
+    //! Verify that all chare-boundary faces have been received
+    bool receivedChBndFaces();
+
+    //! Find any chare for face (given by 3 global node IDs)
+    int findchare( const tk::UnsMesh::Face& t );
+
+    //! Check if entries in inpoel, inpofa and node-triplet are consistent
+    std::size_t nodetripletMatch(
+      const std::array< std::size_t, 2 >& id,
+      const tk::UnsMesh::Face& t );
+
+    //! Fill elements surrounding a face along chare boundary
+    void addEsuf(
+      const std::array< std::size_t, 2 >& id,
+      std::size_t ghostid );
+
+    //! Fill elements surrounding a element along chare boundary
+    void addEsuel(
+      const std::array< std::size_t, 2 >& id,
+      std::size_t ghostid,
+      const tk::UnsMesh::Face& t );
+
+    //! Fill face-geometry data along chare boundary
+    void addGeoFace(
+      const tk::UnsMesh::Face& t,
+      const std::array< std::size_t, 2 >& id );
+};
+
+} // inciter::
+
+#endif // Ghosts_h
 
diff --git a/Release/cppcheck/41.html b/Release/cppcheck/41.html index 0f1ec1cbfa96..77bfaea037e3 100644 --- a/Release/cppcheck/41.html +++ b/Release/cppcheck/41.html @@ -152,695 +152,2199 @@
- - + @@ -116,7 +116,7 @@ 42 : : 43 : : public: 44 : : //! Empty constructor for Charm++ - 45 : 5246 : explicit FaceData() {} + 45 : 5159 : explicit FaceData() {} 46 : : 47 : : //! \brief Constructor: compute (element-face) data for internal and 48 : : //! domain-boundary faces @@ -157,19 +157,19 @@ 73 : : ///@{ 74 : : //! \brief Pack/Unpack serialize member function 75 : : //! \param[in,out] p Charm++'s PUP::er serializer object reference - 76 : 16299 : void pup( PUP::er &p ) { - 77 : 16299 : p | m_bface; - 78 : 16299 : p | m_triinpoel; - 79 : 16299 : p | m_esuel; - 80 : 16299 : p | m_nipfac; - 81 : 16299 : p | m_inpofa; - 82 : 16299 : p | m_belem; - 83 : 16299 : p | m_esuf; - 84 : 16299 : } + 76 : 16038 : void pup( PUP::er &p ) { + 77 : 16038 : p | m_bface; + 78 : 16038 : p | m_triinpoel; + 79 : 16038 : p | m_esuel; + 80 : 16038 : p | m_nipfac; + 81 : 16038 : p | m_inpofa; + 82 : 16038 : p | m_belem; + 83 : 16038 : p | m_esuf; + 84 : 16038 : } 85 : : //! \brief Pack/Unpack serialize operator| 86 : : //! \param[in,out] p Charm++'s PUP::er serializer object reference 87 : : //! \param[in,out] i FaceData object reference - 88 : 16299 : friend void operator|( PUP::er& p, FaceData& i ) { i.pup(p); } + 88 : 16038 : friend void operator|( PUP::er& p, FaceData& i ) { i.pup(p); } 89 : : //@} 90 : : 91 : : private: diff --git a/Release/test_coverage/Inciter/FieldOutput.cpp.func-sort-c.html b/Release/test_coverage/Inciter/FieldOutput.cpp.func-sort-c.html index c0c34af56394..30dcfbdf51fb 100644 --- a/Release/test_coverage/Inciter/FieldOutput.cpp.func-sort-c.html +++ b/Release/test_coverage/Inciter/FieldOutput.cpp.func-sort-c.html @@ -33,7 +33,7 @@ - + diff --git a/Release/test_coverage/Inciter/FieldOutput.cpp.func.html b/Release/test_coverage/Inciter/FieldOutput.cpp.func.html index bafc77ea6f91..8f9fbe57c481 100644 --- a/Release/test_coverage/Inciter/FieldOutput.cpp.func.html +++ b/Release/test_coverage/Inciter/FieldOutput.cpp.func.html @@ -33,7 +33,7 @@ - + diff --git a/Release/test_coverage/Inciter/FieldOutput.cpp.gcov.html b/Release/test_coverage/Inciter/FieldOutput.cpp.gcov.html index 049ca187e41e..a43c4fb94f9e 100644 --- a/Release/test_coverage/Inciter/FieldOutput.cpp.gcov.html +++ b/Release/test_coverage/Inciter/FieldOutput.cpp.gcov.html @@ -33,7 +33,7 @@ - + diff --git a/Release/test_coverage/Inciter/FieldOutput.hpp.func-sort-c.html b/Release/test_coverage/Inciter/FieldOutput.hpp.func-sort-c.html index 8524224a81f4..76629be0b7f6 100644 --- a/Release/test_coverage/Inciter/FieldOutput.hpp.func-sort-c.html +++ b/Release/test_coverage/Inciter/FieldOutput.hpp.func-sort-c.html @@ -33,7 +33,7 @@ - + diff --git a/Release/test_coverage/Inciter/FieldOutput.hpp.func.html b/Release/test_coverage/Inciter/FieldOutput.hpp.func.html index 7bb46118d8d2..f5fb6cfd287c 100644 --- a/Release/test_coverage/Inciter/FieldOutput.hpp.func.html +++ b/Release/test_coverage/Inciter/FieldOutput.hpp.func.html @@ -33,7 +33,7 @@ - + diff --git a/Release/test_coverage/Inciter/FieldOutput.hpp.gcov.html b/Release/test_coverage/Inciter/FieldOutput.hpp.gcov.html index 526a51b5b32e..e9229bf3987c 100644 --- a/Release/test_coverage/Inciter/FieldOutput.hpp.gcov.html +++ b/Release/test_coverage/Inciter/FieldOutput.hpp.gcov.html @@ -33,7 +33,7 @@ - + diff --git a/Release/test_coverage/Inciter/Ghosts.cpp.func-sort-c.html b/Release/test_coverage/Inciter/Ghosts.cpp.func-sort-c.html index 9c1b6491e39c..4c01d2b2c021 100644 --- a/Release/test_coverage/Inciter/Ghosts.cpp.func-sort-c.html +++ b/Release/test_coverage/Inciter/Ghosts.cpp.func-sort-c.html @@ -33,7 +33,7 @@ - + diff --git a/Release/test_coverage/Inciter/Ghosts.cpp.func.html b/Release/test_coverage/Inciter/Ghosts.cpp.func.html index 02b782e0f9a0..c2b641fe7f88 100644 --- a/Release/test_coverage/Inciter/Ghosts.cpp.func.html +++ b/Release/test_coverage/Inciter/Ghosts.cpp.func.html @@ -33,7 +33,7 @@ - + diff --git a/Release/test_coverage/Inciter/Ghosts.cpp.gcov.html b/Release/test_coverage/Inciter/Ghosts.cpp.gcov.html index 084fc343a8cb..a1d8a8edf2fc 100644 --- a/Release/test_coverage/Inciter/Ghosts.cpp.gcov.html +++ b/Release/test_coverage/Inciter/Ghosts.cpp.gcov.html @@ -33,7 +33,7 @@ - + @@ -1041,9 +1041,9 @@ 939 : : //! faces with, -1 if the face cannot be found. 940 : : // ***************************************************************************** 941 : : { - 942 [ + + ]: 849778 : for (const auto& cf : m_bndFace) + 942 [ + + ]: 847106 : for (const auto& cf : m_bndFace) 943 : : // cppcheck-suppress useStlAlgorithm - 944 [ + + ]: 699818 : if (cf.second.find(t) != end(cf.second)) + 944 [ + + ]: 697146 : if (cf.second.find(t) != end(cf.second)) 945 : 78356 : return cf.first; 946 : : return -1; 947 : : } diff --git a/Release/test_coverage/Inciter/Ghosts.hpp.func-sort-c.html b/Release/test_coverage/Inciter/Ghosts.hpp.func-sort-c.html index 0678ae2785f0..5a999818c1f7 100644 --- a/Release/test_coverage/Inciter/Ghosts.hpp.func-sort-c.html +++ b/Release/test_coverage/Inciter/Ghosts.hpp.func-sort-c.html @@ -33,7 +33,7 @@ - + @@ -73,15 +73,15 @@ - + - + - + diff --git a/Release/test_coverage/Inciter/Ghosts.hpp.func.html b/Release/test_coverage/Inciter/Ghosts.hpp.func.html index ebb54dbb7f49..6977ead1fcd7 100644 --- a/Release/test_coverage/Inciter/Ghosts.hpp.func.html +++ b/Release/test_coverage/Inciter/Ghosts.hpp.func.html @@ -33,7 +33,7 @@ - + @@ -73,11 +73,11 @@ - + - + @@ -85,7 +85,7 @@ - + diff --git a/Release/test_coverage/Inciter/Ghosts.hpp.gcov.html b/Release/test_coverage/Inciter/Ghosts.hpp.gcov.html index 204c059542f8..148bf3a10264 100644 --- a/Release/test_coverage/Inciter/Ghosts.hpp.gcov.html +++ b/Release/test_coverage/Inciter/Ghosts.hpp.gcov.html @@ -33,7 +33,7 @@ - + @@ -143,7 +143,7 @@ 69 : : #endif 70 : : //! Migrate constructor 71 : : // cppcheck-suppress uninitMemberVar - 72 : 5246 : explicit Ghosts( CkMigrateMessage* ) {} + 72 : 5159 : explicit Ghosts( CkMigrateMessage* ) {} 73 : : #if defined(__clang__) 74 : : #pragma clang diagnostic pop 75 : : #endif @@ -172,9 +172,9 @@ 98 : : tk::NodeCommMap nodeCommMap; 99 : : //! \brief Pack/Unpack serialize member function 100 : : //! \param[in,out] p Charm++'s PUP::er serializer object reference - 101 : 15976 : void pup( PUP::er& p ) { - 102 : 31952 : p|chunk; p|coord; p|triinpoel; p|bface; p|nodeCommMap; - 103 : 15976 : } + 101 : 15703 : void pup( PUP::er& p ) { + 102 : 31406 : p|chunk; p|coord; p|triinpoel; p|bface; p|nodeCommMap; + 103 : 15703 : } 104 : : //! Destroyer 105 [ + + ]: 24958 : void destroy() { 106 : : tk::destroy( std::get<0>(chunk) ); @@ -259,33 +259,33 @@ 185 : : ///@{ 186 : : //! \brief Pack/Unpack serialize member function 187 : : //! \param[in,out] p Charm++'s PUP::er serializer object reference - 188 : 16299 : void pup( PUP::er &p ) override { - 189 : 16299 : p | m_disc; - 190 : 16299 : p | m_nunk; - 191 : 16299 : p | m_inpoel; + 188 : 16038 : void pup( PUP::er &p ) override { + 189 : 16038 : p | m_disc; + 190 : 16038 : p | m_nunk; + 191 : 16038 : p | m_inpoel; 192 : : p | m_coord; 193 : : p | m_fd; - 194 : 16299 : p | m_geoFace; - 195 : 16299 : p | m_geoElem; - 196 : 16299 : p | m_nfac; - 197 : 16299 : p | m_bndFace; - 198 : 16299 : p | m_sendGhost; - 199 : 16299 : p | m_ghost; - 200 : 16299 : p | m_exptGhost; - 201 : 16299 : p | m_bid; - 202 : 16299 : p | m_esup; - 203 : 16299 : p | m_initial; - 204 : 16299 : p | m_ncomfac; - 205 : 16299 : p | m_nadj; - 206 : 16299 : p | m_ncomEsup; - 207 : 16299 : p | m_ipface; - 208 : 16299 : p | m_ghostData; - 209 : 16299 : p | m_ghostReq; - 210 : 16299 : p | m_expChBndFace; - 211 : 16299 : p | m_infaces; - 212 : 16299 : p | m_esupc; - 213 : 16299 : p | m_cbAfterDone; - 214 : 16299 : } + 194 : 16038 : p | m_geoFace; + 195 : 16038 : p | m_geoElem; + 196 : 16038 : p | m_nfac; + 197 : 16038 : p | m_bndFace; + 198 : 16038 : p | m_sendGhost; + 199 : 16038 : p | m_ghost; + 200 : 16038 : p | m_exptGhost; + 201 : 16038 : p | m_bid; + 202 : 16038 : p | m_esup; + 203 : 16038 : p | m_initial; + 204 : 16038 : p | m_ncomfac; + 205 : 16038 : p | m_nadj; + 206 : 16038 : p | m_ncomEsup; + 207 : 16038 : p | m_ipface; + 208 : 16038 : p | m_ghostData; + 209 : 16038 : p | m_ghostReq; + 210 : 16038 : p | m_expChBndFace; + 211 : 16038 : p | m_infaces; + 212 : 16038 : p | m_esupc; + 213 : 16038 : p | m_cbAfterDone; + 214 : 16038 : } 215 : : //! \brief Pack/Unpack serialize operator| 216 : : //! \param[in,out] p Charm++'s PUP::er serializer object reference 217 : : //! \param[in,out] a Ghosts object reference diff --git a/Release/test_coverage/Inciter/NodeBC.cpp.func-sort-c.html b/Release/test_coverage/Inciter/NodeBC.cpp.func-sort-c.html index 106a52933755..7275eb5ea797 100644 --- a/Release/test_coverage/Inciter/NodeBC.cpp.func-sort-c.html +++ b/Release/test_coverage/Inciter/NodeBC.cpp.func-sort-c.html @@ -33,7 +33,7 @@ - + diff --git a/Release/test_coverage/Inciter/NodeBC.cpp.func.html b/Release/test_coverage/Inciter/NodeBC.cpp.func.html index 05c37d258daf..fe9702b05f31 100644 --- a/Release/test_coverage/Inciter/NodeBC.cpp.func.html +++ b/Release/test_coverage/Inciter/NodeBC.cpp.func.html @@ -33,7 +33,7 @@ - + diff --git a/Release/test_coverage/Inciter/NodeBC.cpp.gcov.html b/Release/test_coverage/Inciter/NodeBC.cpp.gcov.html index 2b0ac738e884..a83494eab59e 100644 --- a/Release/test_coverage/Inciter/NodeBC.cpp.gcov.html +++ b/Release/test_coverage/Inciter/NodeBC.cpp.gcov.html @@ -33,7 +33,7 @@ - + diff --git a/Release/test_coverage/Inciter/NodeDiagnostics.cpp.func-sort-c.html b/Release/test_coverage/Inciter/NodeDiagnostics.cpp.func-sort-c.html index 0155dc26935e..0d73a8dd7fa9 100644 --- a/Release/test_coverage/Inciter/NodeDiagnostics.cpp.func-sort-c.html +++ b/Release/test_coverage/Inciter/NodeDiagnostics.cpp.func-sort-c.html @@ -33,7 +33,7 @@ - + diff --git a/Release/test_coverage/Inciter/NodeDiagnostics.cpp.func.html b/Release/test_coverage/Inciter/NodeDiagnostics.cpp.func.html index 0769d18dcdfb..6764388b36c1 100644 --- a/Release/test_coverage/Inciter/NodeDiagnostics.cpp.func.html +++ b/Release/test_coverage/Inciter/NodeDiagnostics.cpp.func.html @@ -33,7 +33,7 @@ - + diff --git a/Release/test_coverage/Inciter/NodeDiagnostics.cpp.gcov.html b/Release/test_coverage/Inciter/NodeDiagnostics.cpp.gcov.html index 0cce5da57982..b7731b0929e7 100644 --- a/Release/test_coverage/Inciter/NodeDiagnostics.cpp.gcov.html +++ b/Release/test_coverage/Inciter/NodeDiagnostics.cpp.gcov.html @@ -33,7 +33,7 @@ - + @@ -196,8 +196,8 @@ 121 : 4848864 : diag[L2RES][c] += (u(i,c)-un(i,c)) * (u(i,c)-un(i,c)) * v[i]; 122 : : // Compute max for Linf norm of the numerical-analytic solution 123 [ + + ]: 6368960 : for (std::size_t c=0; c<u.nprop(); ++c) { - 124 [ + + ]: 4848864 : auto err = std::abs( u(i,c) - an(i,c) ); - 125 [ + + ]: 4848864 : if (err > diag[LINFERR][c]) diag[LINFERR][c] = err; + 124 [ + + ]: 4848864 : auto err = std::abs( u(i,c) - an(i,c) ); + 125 [ + + ]: 4848864 : if (err > diag[LINFERR][c]) diag[LINFERR][c] = err; 126 : : } 127 : : // Compute sum of the total energy over the entire domain (only the first 128 : : // entry is used) diff --git a/Release/test_coverage/Inciter/OversetFE.cpp.func-sort-c.html b/Release/test_coverage/Inciter/OversetFE.cpp.func-sort-c.html index 72568b76a955..f111ac8b2857 100644 --- a/Release/test_coverage/Inciter/OversetFE.cpp.func-sort-c.html +++ b/Release/test_coverage/Inciter/OversetFE.cpp.func-sort-c.html @@ -33,7 +33,7 @@ - + diff --git a/Release/test_coverage/Inciter/OversetFE.cpp.func.html b/Release/test_coverage/Inciter/OversetFE.cpp.func.html index f3a4861b0367..b5f5359b0904 100644 --- a/Release/test_coverage/Inciter/OversetFE.cpp.func.html +++ b/Release/test_coverage/Inciter/OversetFE.cpp.func.html @@ -33,7 +33,7 @@ - + diff --git a/Release/test_coverage/Inciter/OversetFE.cpp.gcov.html b/Release/test_coverage/Inciter/OversetFE.cpp.gcov.html index 1bc2dbc93bb4..23e27eeee403 100644 --- a/Release/test_coverage/Inciter/OversetFE.cpp.gcov.html +++ b/Release/test_coverage/Inciter/OversetFE.cpp.gcov.html @@ -33,7 +33,7 @@ - + @@ -1119,7 +1119,7 @@ 1027 [ + - ]: 3396 : if (m_stage == 0) d->setdt( newdt ); 1028 : : 1029 : : // TODO: this is a hacky way to know if any chunk moved. redesign it - 1030 [ + + ]: 3396 : if (nmovedmesh < -0.1) m_movedmesh = 1; + 1030 [ + + ]: 3396 : if (nmovedmesh < -0.1) m_movedmesh = 1; 1031 : : 1032 : : // Compute gradients for next time step 1033 : 3396 : chBndGrad(); diff --git a/Release/test_coverage/Inciter/OversetFE.hpp.func-sort-c.html b/Release/test_coverage/Inciter/OversetFE.hpp.func-sort-c.html index 1551b9a7673f..e799fb1bb1fd 100644 --- a/Release/test_coverage/Inciter/OversetFE.hpp.func-sort-c.html +++ b/Release/test_coverage/Inciter/OversetFE.hpp.func-sort-c.html @@ -33,7 +33,7 @@ - + @@ -73,11 +73,11 @@ - + - + diff --git a/Release/test_coverage/Inciter/OversetFE.hpp.func.html b/Release/test_coverage/Inciter/OversetFE.hpp.func.html index f74527067cc1..eb0ada129944 100644 --- a/Release/test_coverage/Inciter/OversetFE.hpp.func.html +++ b/Release/test_coverage/Inciter/OversetFE.hpp.func.html @@ -33,7 +33,7 @@ - + @@ -73,11 +73,11 @@ - + - + diff --git a/Release/test_coverage/Inciter/OversetFE.hpp.gcov.html b/Release/test_coverage/Inciter/OversetFE.hpp.gcov.html index 809de1497724..f6d5de50bb91 100644 --- a/Release/test_coverage/Inciter/OversetFE.hpp.gcov.html +++ b/Release/test_coverage/Inciter/OversetFE.hpp.gcov.html @@ -33,7 +33,7 @@ - + @@ -151,7 +151,7 @@ 77 : : #endif 78 : : //! Migrate constructor 79 : : // cppcheck-suppress uninitMemberVar - 80 : 980 : explicit OversetFE( CkMigrateMessage* msg ) : CBase_OversetFE( msg ) {} + 80 : 971 : explicit OversetFE( CkMigrateMessage* msg ) : CBase_OversetFE( msg ) {} 81 : : #if defined(__clang__) 82 : : #pragma clang diagnostic pop 83 : : #endif @@ -265,54 +265,54 @@ 191 : : ///@{ 192 : : //! \brief Pack/Unpack serialize member function 193 : : //! \param[in,out] p Charm++'s PUP::er serializer object reference - 194 : 2955 : void pup( PUP::er &p ) override { - 195 : 2955 : p | m_disc; - 196 : 2955 : p | m_nsol; - 197 : 2955 : p | m_ngrad; - 198 : 2955 : p | m_nrhs; - 199 : 2955 : p | m_nbnorm; - 200 : 2955 : p | m_ndfnorm; - 201 : 2955 : p | m_nmblk; - 202 : 2955 : p | m_bnode; - 203 : 2955 : p | m_bface; - 204 : 2955 : p | m_triinpoel; - 205 : 2955 : p | m_bndel; - 206 : 2955 : p | m_dfnorm; - 207 : 2955 : p | m_dfnormc; - 208 : 2955 : p | m_dfn; - 209 : 2955 : p | m_esup; - 210 : 2955 : p | m_psup; - 211 : 2955 : p | m_u; - 212 : 2955 : p | m_uc; - 213 : 2955 : p | m_un; - 214 : 2955 : p | m_rhs; - 215 : 2955 : p | m_rhsc; - 216 : 2955 : p | m_chBndGrad; - 217 : 2955 : p | m_dirbc; - 218 : 2955 : p | m_chBndGradc; - 219 : 2955 : p | m_blank; + 194 : 2928 : void pup( PUP::er &p ) override { + 195 : 2928 : p | m_disc; + 196 : 2928 : p | m_nsol; + 197 : 2928 : p | m_ngrad; + 198 : 2928 : p | m_nrhs; + 199 : 2928 : p | m_nbnorm; + 200 : 2928 : p | m_ndfnorm; + 201 : 2928 : p | m_nmblk; + 202 : 2928 : p | m_bnode; + 203 : 2928 : p | m_bface; + 204 : 2928 : p | m_triinpoel; + 205 : 2928 : p | m_bndel; + 206 : 2928 : p | m_dfnorm; + 207 : 2928 : p | m_dfnormc; + 208 : 2928 : p | m_dfn; + 209 : 2928 : p | m_esup; + 210 : 2928 : p | m_psup; + 211 : 2928 : p | m_u; + 212 : 2928 : p | m_uc; + 213 : 2928 : p | m_un; + 214 : 2928 : p | m_rhs; + 215 : 2928 : p | m_rhsc; + 216 : 2928 : p | m_chBndGrad; + 217 : 2928 : p | m_dirbc; + 218 : 2928 : p | m_chBndGradc; + 219 : 2928 : p | m_blank; 220 : : p | m_diag; - 221 : 2955 : p | m_bnorm; - 222 : 2955 : p | m_bnormc; - 223 : 2955 : p | m_symbcnodes; - 224 : 2955 : p | m_farfieldbcnodes; - 225 : 2955 : p | m_symbctri; - 226 : 2955 : p | m_timedepbcnodes; - 227 : 2955 : p | m_timedepbcFn; - 228 : 2955 : p | m_stage; - 229 : 2955 : p | m_boxnodes; - 230 : 2955 : p | m_edgenode; - 231 : 2955 : p | m_edgeid; - 232 : 2955 : p | m_dtp; - 233 : 2955 : p | m_tp; - 234 : 2955 : p | m_finished; - 235 : 2955 : p | m_movedmesh; - 236 : 2955 : p | m_nusermeshblk; - 237 : 2955 : p | m_nodeblockid; - 238 : 2955 : p | m_nodeblockidc; - 239 : 2955 : p | m_ixfer; + 221 : 2928 : p | m_bnorm; + 222 : 2928 : p | m_bnormc; + 223 : 2928 : p | m_symbcnodes; + 224 : 2928 : p | m_farfieldbcnodes; + 225 : 2928 : p | m_symbctri; + 226 : 2928 : p | m_timedepbcnodes; + 227 : 2928 : p | m_timedepbcFn; + 228 : 2928 : p | m_stage; + 229 : 2928 : p | m_boxnodes; + 230 : 2928 : p | m_edgenode; + 231 : 2928 : p | m_edgeid; + 232 : 2928 : p | m_dtp; + 233 : 2928 : p | m_tp; + 234 : 2928 : p | m_finished; + 235 : 2928 : p | m_movedmesh; + 236 : 2928 : p | m_nusermeshblk; + 237 : 2928 : p | m_nodeblockid; + 238 : 2928 : p | m_nodeblockidc; + 239 : 2928 : p | m_ixfer; 240 : : p | m_uservel; - 241 : 2955 : } + 241 : 2928 : } 242 : : //! \brief Pack/Unpack serialize operator| 243 : : //! \param[in,out] p Charm++'s PUP::er serializer object reference 244 : : //! \param[in,out] i OversetFE object reference diff --git a/Release/test_coverage/Inciter/PUPAMR.cpp.func-sort-c.html b/Release/test_coverage/Inciter/PUPAMR.cpp.func-sort-c.html index 9c3d10010927..2ffde00adf31 100644 --- a/Release/test_coverage/Inciter/PUPAMR.cpp.func-sort-c.html +++ b/Release/test_coverage/Inciter/PUPAMR.cpp.func-sort-c.html @@ -33,7 +33,7 @@ - + @@ -81,39 +81,39 @@ - + - + - + - + - + - + - + - + - +
  1
-  2
-  3
-  4
-  5
-  6
-  7
-  8
-  9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
- 37
- 38
- 39
- 40
- 41
- 42
- 43
- 44
- 45
- 46
- 47
- 48
- 49
- 50
- 51
- 52
- 53
- 54
- 55
- 56
- 57
- 58
- 59
- 60
- 61
- 62
- 63
- 64
- 65
- 66
- 67
- 68
- 69
- 70
- 71
- 72
- 73
- 74
- 75
- 76
- 77
- 78
- 79
- 80
- 81
- 82
- 83
- 84
- 85
- 86
- 87
- 88
- 89
- 90
- 91
- 92
- 93
- 94
- 95
- 96
- 97
- 98
- 99
-100
-101
-102
-103
-104
-105
-106
-107
-108
-109
-110
-111
-112
-113
-114
-115
-116
-117
-118
-119
-120
-121
-122
-123
-124
-125
-126
-127
-128
-129
-130
-131
-132
-133
-134
-135
-136
-137
-138
-139
-140
-141
-142
-143
-144
-145
-146
-147
-148
-149
-150
-151
-152
-153
-154
-155
-156
-157
-158
-159
-160
-161
-162
-163
-164
-165
-166
-167
-168
-169
-170
-171
-172
-173
-174
-175
-176
-177
-178
-179
-180
-181
-182
-183
-184
-185
-186
-187
-188
-189
-190
-191
-192
-193
-194
-195
-196
-197
-198
-199
-200
-201
-202
-203
-204
-205
-206
-207
-208
-209
-210
-211
-212
-213
-214
-215
-216
-217
-218
-219
-220
-221
-222
-223
-224
-225
-226
-227
-228
-229
-230
-231
-232
-233
-234
-235
-236
-237
-238
-239
-240
-241
-242
-243
-244
-245
-246
-247
-248
-249
-250
-251
-252
-253
-254
-255
-256
-257
-258
-259
-260
-261
-262
-263
-264
-265
-266
-267
-268
-269
-270
-271
-272
-273
-274
-275
-276
-277
-278
-279
-280
-281
-282
-283
-284
-285
-286
-287
-288
-289
-290
-291
-292
-293
-294
-295
-296
-297
-298
-299
-300
-301
-302
-303
-304
-305
-306
-307
-308
-309
-310
-311
-312
-313
-314
-315
-316
-317
-318
-319
-320
-321
-322
-323
-324
-325
-326
-327
-328
-329
-330
-331
-332
-333
-334
-335
-336
-337
-338
-339
-340
-341
// *****************************************************************************
+
   1
+   2
+   3
+   4
+   5
+   6
+   7
+   8
+   9
+  10
+  11
+  12
+  13
+  14
+  15
+  16
+  17
+  18
+  19
+  20
+  21
+  22
+  23
+  24
+  25
+  26
+  27
+  28
+  29
+  30
+  31
+  32
+  33
+  34
+  35
+  36
+  37
+  38
+  39
+  40
+  41
+  42
+  43
+  44
+  45
+  46
+  47
+  48
+  49
+  50
+  51
+  52
+  53
+  54
+  55
+  56
+  57
+  58
+  59
+  60
+  61
+  62
+  63
+  64
+  65
+  66
+  67
+  68
+  69
+  70
+  71
+  72
+  73
+  74
+  75
+  76
+  77
+  78
+  79
+  80
+  81
+  82
+  83
+  84
+  85
+  86
+  87
+  88
+  89
+  90
+  91
+  92
+  93
+  94
+  95
+  96
+  97
+  98
+  99
+ 100
+ 101
+ 102
+ 103
+ 104
+ 105
+ 106
+ 107
+ 108
+ 109
+ 110
+ 111
+ 112
+ 113
+ 114
+ 115
+ 116
+ 117
+ 118
+ 119
+ 120
+ 121
+ 122
+ 123
+ 124
+ 125
+ 126
+ 127
+ 128
+ 129
+ 130
+ 131
+ 132
+ 133
+ 134
+ 135
+ 136
+ 137
+ 138
+ 139
+ 140
+ 141
+ 142
+ 143
+ 144
+ 145
+ 146
+ 147
+ 148
+ 149
+ 150
+ 151
+ 152
+ 153
+ 154
+ 155
+ 156
+ 157
+ 158
+ 159
+ 160
+ 161
+ 162
+ 163
+ 164
+ 165
+ 166
+ 167
+ 168
+ 169
+ 170
+ 171
+ 172
+ 173
+ 174
+ 175
+ 176
+ 177
+ 178
+ 179
+ 180
+ 181
+ 182
+ 183
+ 184
+ 185
+ 186
+ 187
+ 188
+ 189
+ 190
+ 191
+ 192
+ 193
+ 194
+ 195
+ 196
+ 197
+ 198
+ 199
+ 200
+ 201
+ 202
+ 203
+ 204
+ 205
+ 206
+ 207
+ 208
+ 209
+ 210
+ 211
+ 212
+ 213
+ 214
+ 215
+ 216
+ 217
+ 218
+ 219
+ 220
+ 221
+ 222
+ 223
+ 224
+ 225
+ 226
+ 227
+ 228
+ 229
+ 230
+ 231
+ 232
+ 233
+ 234
+ 235
+ 236
+ 237
+ 238
+ 239
+ 240
+ 241
+ 242
+ 243
+ 244
+ 245
+ 246
+ 247
+ 248
+ 249
+ 250
+ 251
+ 252
+ 253
+ 254
+ 255
+ 256
+ 257
+ 258
+ 259
+ 260
+ 261
+ 262
+ 263
+ 264
+ 265
+ 266
+ 267
+ 268
+ 269
+ 270
+ 271
+ 272
+ 273
+ 274
+ 275
+ 276
+ 277
+ 278
+ 279
+ 280
+ 281
+ 282
+ 283
+ 284
+ 285
+ 286
+ 287
+ 288
+ 289
+ 290
+ 291
+ 292
+ 293
+ 294
+ 295
+ 296
+ 297
+ 298
+ 299
+ 300
+ 301
+ 302
+ 303
+ 304
+ 305
+ 306
+ 307
+ 308
+ 309
+ 310
+ 311
+ 312
+ 313
+ 314
+ 315
+ 316
+ 317
+ 318
+ 319
+ 320
+ 321
+ 322
+ 323
+ 324
+ 325
+ 326
+ 327
+ 328
+ 329
+ 330
+ 331
+ 332
+ 333
+ 334
+ 335
+ 336
+ 337
+ 338
+ 339
+ 340
+ 341
+ 342
+ 343
+ 344
+ 345
+ 346
+ 347
+ 348
+ 349
+ 350
+ 351
+ 352
+ 353
+ 354
+ 355
+ 356
+ 357
+ 358
+ 359
+ 360
+ 361
+ 362
+ 363
+ 364
+ 365
+ 366
+ 367
+ 368
+ 369
+ 370
+ 371
+ 372
+ 373
+ 374
+ 375
+ 376
+ 377
+ 378
+ 379
+ 380
+ 381
+ 382
+ 383
+ 384
+ 385
+ 386
+ 387
+ 388
+ 389
+ 390
+ 391
+ 392
+ 393
+ 394
+ 395
+ 396
+ 397
+ 398
+ 399
+ 400
+ 401
+ 402
+ 403
+ 404
+ 405
+ 406
+ 407
+ 408
+ 409
+ 410
+ 411
+ 412
+ 413
+ 414
+ 415
+ 416
+ 417
+ 418
+ 419
+ 420
+ 421
+ 422
+ 423
+ 424
+ 425
+ 426
+ 427
+ 428
+ 429
+ 430
+ 431
+ 432
+ 433
+ 434
+ 435
+ 436
+ 437
+ 438
+ 439
+ 440
+ 441
+ 442
+ 443
+ 444
+ 445
+ 446
+ 447
+ 448
+ 449
+ 450
+ 451
+ 452
+ 453
+ 454
+ 455
+ 456
+ 457
+ 458
+ 459
+ 460
+ 461
+ 462
+ 463
+ 464
+ 465
+ 466
+ 467
+ 468
+ 469
+ 470
+ 471
+ 472
+ 473
+ 474
+ 475
+ 476
+ 477
+ 478
+ 479
+ 480
+ 481
+ 482
+ 483
+ 484
+ 485
+ 486
+ 487
+ 488
+ 489
+ 490
+ 491
+ 492
+ 493
+ 494
+ 495
+ 496
+ 497
+ 498
+ 499
+ 500
+ 501
+ 502
+ 503
+ 504
+ 505
+ 506
+ 507
+ 508
+ 509
+ 510
+ 511
+ 512
+ 513
+ 514
+ 515
+ 516
+ 517
+ 518
+ 519
+ 520
+ 521
+ 522
+ 523
+ 524
+ 525
+ 526
+ 527
+ 528
+ 529
+ 530
+ 531
+ 532
+ 533
+ 534
+ 535
+ 536
+ 537
+ 538
+ 539
+ 540
+ 541
+ 542
+ 543
+ 544
+ 545
+ 546
+ 547
+ 548
+ 549
+ 550
+ 551
+ 552
+ 553
+ 554
+ 555
+ 556
+ 557
+ 558
+ 559
+ 560
+ 561
+ 562
+ 563
+ 564
+ 565
+ 566
+ 567
+ 568
+ 569
+ 570
+ 571
+ 572
+ 573
+ 574
+ 575
+ 576
+ 577
+ 578
+ 579
+ 580
+ 581
+ 582
+ 583
+ 584
+ 585
+ 586
+ 587
+ 588
+ 589
+ 590
+ 591
+ 592
+ 593
+ 594
+ 595
+ 596
+ 597
+ 598
+ 599
+ 600
+ 601
+ 602
+ 603
+ 604
+ 605
+ 606
+ 607
+ 608
+ 609
+ 610
+ 611
+ 612
+ 613
+ 614
+ 615
+ 616
+ 617
+ 618
+ 619
+ 620
+ 621
+ 622
+ 623
+ 624
+ 625
+ 626
+ 627
+ 628
+ 629
+ 630
+ 631
+ 632
+ 633
+ 634
+ 635
+ 636
+ 637
+ 638
+ 639
+ 640
+ 641
+ 642
+ 643
+ 644
+ 645
+ 646
+ 647
+ 648
+ 649
+ 650
+ 651
+ 652
+ 653
+ 654
+ 655
+ 656
+ 657
+ 658
+ 659
+ 660
+ 661
+ 662
+ 663
+ 664
+ 665
+ 666
+ 667
+ 668
+ 669
+ 670
+ 671
+ 672
+ 673
+ 674
+ 675
+ 676
+ 677
+ 678
+ 679
+ 680
+ 681
+ 682
+ 683
+ 684
+ 685
+ 686
+ 687
+ 688
+ 689
+ 690
+ 691
+ 692
+ 693
+ 694
+ 695
+ 696
+ 697
+ 698
+ 699
+ 700
+ 701
+ 702
+ 703
+ 704
+ 705
+ 706
+ 707
+ 708
+ 709
+ 710
+ 711
+ 712
+ 713
+ 714
+ 715
+ 716
+ 717
+ 718
+ 719
+ 720
+ 721
+ 722
+ 723
+ 724
+ 725
+ 726
+ 727
+ 728
+ 729
+ 730
+ 731
+ 732
+ 733
+ 734
+ 735
+ 736
+ 737
+ 738
+ 739
+ 740
+ 741
+ 742
+ 743
+ 744
+ 745
+ 746
+ 747
+ 748
+ 749
+ 750
+ 751
+ 752
+ 753
+ 754
+ 755
+ 756
+ 757
+ 758
+ 759
+ 760
+ 761
+ 762
+ 763
+ 764
+ 765
+ 766
+ 767
+ 768
+ 769
+ 770
+ 771
+ 772
+ 773
+ 774
+ 775
+ 776
+ 777
+ 778
+ 779
+ 780
+ 781
+ 782
+ 783
+ 784
+ 785
+ 786
+ 787
+ 788
+ 789
+ 790
+ 791
+ 792
+ 793
+ 794
+ 795
+ 796
+ 797
+ 798
+ 799
+ 800
+ 801
+ 802
+ 803
+ 804
+ 805
+ 806
+ 807
+ 808
+ 809
+ 810
+ 811
+ 812
+ 813
+ 814
+ 815
+ 816
+ 817
+ 818
+ 819
+ 820
+ 821
+ 822
+ 823
+ 824
+ 825
+ 826
+ 827
+ 828
+ 829
+ 830
+ 831
+ 832
+ 833
+ 834
+ 835
+ 836
+ 837
+ 838
+ 839
+ 840
+ 841
+ 842
+ 843
+ 844
+ 845
+ 846
+ 847
+ 848
+ 849
+ 850
+ 851
+ 852
+ 853
+ 854
+ 855
+ 856
+ 857
+ 858
+ 859
+ 860
+ 861
+ 862
+ 863
+ 864
+ 865
+ 866
+ 867
+ 868
+ 869
+ 870
+ 871
+ 872
+ 873
+ 874
+ 875
+ 876
+ 877
+ 878
+ 879
+ 880
+ 881
+ 882
+ 883
+ 884
+ 885
+ 886
+ 887
+ 888
+ 889
+ 890
+ 891
+ 892
+ 893
+ 894
+ 895
+ 896
+ 897
+ 898
+ 899
+ 900
+ 901
+ 902
+ 903
+ 904
+ 905
+ 906
+ 907
+ 908
+ 909
+ 910
+ 911
+ 912
+ 913
+ 914
+ 915
+ 916
+ 917
+ 918
+ 919
+ 920
+ 921
+ 922
+ 923
+ 924
+ 925
+ 926
+ 927
+ 928
+ 929
+ 930
+ 931
+ 932
+ 933
+ 934
+ 935
+ 936
+ 937
+ 938
+ 939
+ 940
+ 941
+ 942
+ 943
+ 944
+ 945
+ 946
+ 947
+ 948
+ 949
+ 950
+ 951
+ 952
+ 953
+ 954
+ 955
+ 956
+ 957
+ 958
+ 959
+ 960
+ 961
+ 962
+ 963
+ 964
+ 965
+ 966
+ 967
+ 968
+ 969
+ 970
+ 971
+ 972
+ 973
+ 974
+ 975
+ 976
+ 977
+ 978
+ 979
+ 980
+ 981
+ 982
+ 983
+ 984
+ 985
+ 986
+ 987
+ 988
+ 989
+ 990
+ 991
+ 992
+ 993
+ 994
+ 995
+ 996
+ 997
+ 998
+ 999
+1000
+1001
+1002
+1003
+1004
+1005
+1006
+1007
+1008
+1009
+1010
+1011
+1012
+1013
+1014
+1015
+1016
+1017
+1018
+1019
+1020
+1021
+1022
+1023
+1024
+1025
+1026
+1027
+1028
+1029
+1030
+1031
+1032
+1033
+1034
+1035
+1036
+1037
+1038
+1039
+1040
+1041
+1042
+1043
+1044
+1045
+1046
+1047
+1048
+1049
+1050
+1051
+1052
+1053
+1054
+1055
+1056
+1057
+1058
+1059
+1060
+1061
+1062
+1063
+1064
+1065
+1066
+1067
+1068
+1069
+1070
+1071
+1072
+1073
+1074
+1075
+1076
+1077
+1078
+1079
+1080
+1081
+1082
+1083
+1084
+1085
+1086
+1087
+1088
+1089
+1090
+1091
+1092
+1093
// *****************************************************************************
 /*!
-  \file      src/Main/Inciter.cpp
+  \file      src/Inciter/Ghosts.cpp
   \copyright 2012-2015 J. Bakosi,
              2016-2018 Los Alamos National Security, LLC.,
              2019-2021 Triad National Security, LLC.
              All rights reserved. See the LICENSE file for details.
-  \brief     Inciter, computational shock hydrodynamics tool, Charm++ main
-    chare.
-  \details   Inciter, computational shock hydrodynamics tool, Charm++ main
-    chare. This file contains the definition of the Charm++ main chare,
-    equivalent to main() in Charm++-land.
-*/
-// *****************************************************************************
-
-#include <unordered_map>
-#include <vector>
-#include <iostream>
+  \brief     Definitions file for generating ghost data structures
+  \details   Definitions file for asynchronous distributed
+             ghost data structures using Charm++.
+*/
+// *****************************************************************************
+
+#include "Ghosts.hpp"
+#include "DerivedData.hpp"
+#include "Reorder.hpp"
+#include "Around.hpp"
+#include "ChareStateCollector.hpp"
 
-#include "Types.hpp"
-#include "Init.hpp"
-#include "QuinoaConfig.hpp"
-#include "Timer.hpp"
-#include "Exception.hpp"
-#include "CGPDE.hpp"
-#include "DGPDE.hpp"
-#include "FVPDE.hpp"
-#include "PDEStack.hpp"
-#include "ProcessException.hpp"
-#include "InciterPrint.hpp"
-#include "InciterDriver.hpp"
-#include "Inciter/CmdLine/Parser.hpp"
-#include "Inciter/CmdLine/CmdLine.hpp"
-#include "Inciter/InputDeck/InputDeck.hpp"
-#include "ChareStateCollector.hpp"
-#include "LBSwitch.hpp"
-
-#include "NoWarning/inciter.decl.h"
-
-#if defined(__clang__)
-  #pragma clang diagnostic push
-  #pragma clang diagnostic ignored "-Wmissing-variable-declarations"
-#endif
-
-//! \brief Charm handle to the main proxy, facilitates call-back to finalize,
-//!    etc., must be in global scope, unique per executable
-CProxy_Main mainProxy;
-
-//! Chare state collector Charm++ chare group proxy
-tk::CProxy_ChareStateCollector stateProxy;
-
-//! Load balancer switch group proxy
-tk::CProxy_LBSwitch LBSwitchProxy;
-
-//! If true, call and stack traces are to be output with exceptions
-//! \note This is true by default so that the trace is always output between
-//!   program start and the Main ctor in which the user-input from command line
-//!   setting for this overrides this true setting.
-bool g_trace = true;
-
-#if defined(__clang__)
-  #pragma clang diagnostic pop
-#endif
-
-//! Inciter declarations and definitions
-namespace inciter {
-
-//! Global-scope data. Initialized by the main chare and distibuted to all PEs
-//! by the Charm++ runtime system. Though semantically not const, all these
-//! global data should be considered read-only. See also
-//! http://charm.cs.illinois.edu/manuals/html/charm++/manual.html. The data
-//! below is global-scope because they must be available to all PEs which could
-//! be on different machines.
-
-#if defined(__clang__)
-  #pragma clang diagnostic push
-  #pragma clang diagnostic ignored "-Wmissing-variable-declarations"
-#endif
-
-//! Defaults of input deck, facilitates detection what is set by user
-//! \details This object is in global scope, it contains the default of all
-//!   possible user input, and thus it is made available to all PEs for
-//!   convenience reasons. The runtime system distributes it to all PEs during
-//!   initialization. Once distributed, the object does not change.
-ctr::InputDeck g_inputdeck_defaults;
-//! Lua Input deck filled by LuaParser, containing all input data
-//! \details This object is in global scope, it contains all of user input, and
-//!   thus it is made available to all PEs for convenience reasons. The runtime
-//!   system distributes it to all PEs during initialization. Once distributed,
-//!   the object does not change.
-ctr::InputDeck g_inputdeck;
-//! Partial differential equations using continuous Galerkin selected by user
-//! \details This vector is in global scope, because it holds polymorphic
-//!   objects, and thus must be distributed to all PEs during initialization.
-//!   Once distributed by the runtime system, the objects do not change.
-std::vector< CGPDE > g_cgpde;
-//! Partial differential equations using discontinuous Galerkin selected by user
-//! \details This vector is in global scope, because it holds polymorphic
-//!   objects, and thus must be distributed to all PEs during initialization.
-//!   Once distributed by the runtime system, the objects do not change.
-std::vector< DGPDE > g_dgpde;
-//! Partial differential equations using finite volume selected by user
-//! \details This vector is in global scope, because it holds polymorphic
-//!   objects, and thus must be distributed to all PEs during initialization.
-//!   Once distributed by the runtime system, the objects do not change.
-std::vector< FVPDE > g_fvpde;
-
-#if defined(__clang__)
-  #pragma clang diagnostic pop
-#endif
-
-//! \brief Pack/Unpack selected partial differential equations using continuous
-//!   Galerkin discretization.
-//! \details This Pack/Unpack method (re-)creates the PDE factory since it needs
-//!   to (re-)bind function pointers on different processing elements. Therefore
-//!   we circumvent Charm's usual pack/unpack for this type, and thus sizing
-//!   does not make sense: sizing is a no-op. We could initialize the factory in
-//!   InciterDriver's constructor and let this function re-create the stack only
-//!   when unpacking, but that leads to repeating the same code twice: once in
-//!   InciterDriver's constructor, once here. Another option is to use this
-//!   pack/unpack routine to both initially create (when packing) and to
-//!   re-create (when unpacking) the factory, which eliminates the need for
-//!   pre-creating the object in InciterDriver's constructor and therefore
-//!   eliminates the repeated code. This explains the guard for sizing: the code
-//!   below is called for packing only (in serial) and packing and unpacking (in
-//!   parallel).
-inline
-void operator|( PUP::er& p, std::vector< CGPDE >& eqs ) {
-  try {
-    if (!p.isSizing()) eqs = PDEStack().selectedCG();
-  } catch (...) { tk::processExceptionCharm(); }
-}
+extern tk::CProxy_ChareStateCollector stateProxy;
+
+using inciter::Ghosts;
+
+Ghosts::Ghosts( const CProxy_Discretization& disc,
+  const std::map< int, std::vector< std::size_t > >& bface,
+  const std::vector< std::size_t >& triinpoel,
+  std::size_t nunk,
+  CkCallback cbDone ) :
+  m_disc( disc ),
+  m_nunk( nunk ),
+  m_inpoel( Disc()->Inpoel() ),
+  m_coord( Disc()->Coord() ),
+  m_fd( m_inpoel, bface, tk::remap(triinpoel,Disc()->Lid()) ),
+  m_geoFace( tk::genGeoFaceTri( m_fd.Nipfac(), m_fd.Inpofa(), m_coord) ),
+  m_geoElem( tk::genGeoElemTet( m_inpoel, m_coord ) ),
+  m_nfac( m_fd.Inpofa().size()/3 ),
+  m_bndFace(),
+  m_sendGhost(),
+  m_ghost(),
+  m_exptGhost(),
+  m_bid(),
+  m_esup(),
+  m_initial( 1 ),
+  m_ncomfac( 0 ),
+  m_nadj( 0 ),
+  m_ncomEsup( 0 ),
+  m_ipface(),
+  m_ghostData(),
+  m_ghostReq( 0 ),
+  m_expChBndFace(),
+  m_infaces(),
+  m_esupc(),
+  m_cbAfterDone( cbDone )
+// *****************************************************************************
+//  Constructor
+//! \param[in] disc Discretization proxy
+//! \param[in] bface Boundary-faces mapped to side set ids
+//! \param[in] triinpoel Boundary-face connectivity
+//! \param[in] nunk Number of unknowns
+//! \param[in] cbDone Function to continue with when Ghosts have been computed
+// *****************************************************************************
+{
+  if (g_inputdeck.get< tag::cmd, tag::chare >() ||
+      g_inputdeck.get< tag::cmd, tag::quiescence >())
+    stateProxy.ckLocalBranch()->insert( "Ghosts", thisIndex, CkMyPe(), Disc()->It(),
+                                        "Ghosts" );
+}
+
+void
+Ghosts::startCommSetup()
+// *****************************************************************************
+//  Start setup of communication maps for cell-centered schemes
+// *****************************************************************************
+{
+  // Ensure that mesh partition is not leaky
+  Assert( !tk::leakyPartition(m_fd.Esuel(), m_inpoel, m_coord),
+    "Input mesh to Ghosts leaky" );
+
+  // Ensure mesh physical boundary for the entire problem not leaky,
+  // effectively checking if the user has specified boundary conditions on all
+  // physical boundary faces
+  bndIntegral();
+}
+
+void
+Ghosts::bndIntegral()
+// *****************************************************************************
+//  Compute partial boundary surface integral and sum across all chares
+//! \details This function computes a partial surface integral over the boundary
+//!   of the faces of this mesh partition then sends its contribution to perform
+//!   the integral acorss the total problem boundary. After the global sum a
+//!   non-zero vector result indicates a leak, e.g., a hole in the boundary
+//!   which indicates an error in the boundary face data structures used to
+//!   compute the partial surface integrals.
+// *****************************************************************************
+{
+  // Storage for surface integral over our mesh chunk physical boundary
+  std::vector< tk::real > s{{ 0.0, 0.0, 0.0 }};
+
+  // Integrate over all physical boundary faces
+  for (std::size_t f=0; f<m_fd.Nbfac(); ++f) {
+    s[0] += m_geoFace(f,0) * m_geoFace(f,1);
+    s[1] += m_geoFace(f,0) * m_geoFace(f,2);
+    s[2] += m_geoFace(f,0) * m_geoFace(f,3);
+  }
+
+  s.push_back( 1.0 );  // positive: call-back to resizeComm() after reduction
+  s.push_back( static_cast< tk::real >( Disc()->MeshId() ) );
+
+  // Send contribution to host summing partial surface integrals
+  contribute( s, CkReduction::sum_double,
+    CkCallback(CkReductionTarget(Transporter,bndint), Disc()->Tr()) );
+}
+
+void
+Ghosts::resizeComm()
+// *****************************************************************************
+//  Start sizing communication buffers and setting up ghost data
+// *****************************************************************************
+{
+  // Enable SDAG wait for setting up chare boundary faces
+  thisProxy[ thisIndex ].wait4fac();
+
+  auto d = Disc();
+
+  const auto& gid = d->Gid();
+  const auto& inpofa = m_fd.Inpofa();
+  const auto& esuel = m_fd.Esuel();
+
+  // Perform leak test on mesh partition
+  Assert( !tk::leakyPartition( esuel, m_inpoel, m_coord ),
+          "Mesh partition leaky" );
 
-//! \brief Pack/Unpack selected partial differential equations using
-//!   discontinuous Galerkin discretization.
-//! \details This Pack/Unpack method (re-)creates the PDE factory since it needs
-//!   to (re-)bind function pointers on different processing elements. Therefore
-//!   we circumvent Charm's usual pack/unpack for this type, and thus sizing
-//!   does not make sense: sizing is a no-op. We could initialize the factory in
-//!   InciterDriver's constructor and let this function re-create the stack only
-//!   when unpacking, but that leads to repeating the same code twice: once in
-//!   InciterDriver's constructor, once here. Another option is to use this
-//!   pack/unpack routine to both initially create (when packing) and to
-//!   re-create (when unpacking) the factory, which eliminates the need for
-//!   pre-creating the object in InciterDriver's constructor and therefore
-//!   eliminates the repeated code. This explains the guard for sizing: the code
-//!   below is called for packing only (in serial) and packing and unpacking (in
-//!   parallel).
-inline
-void operator|( PUP::er& p, std::vector< DGPDE >& eqs ) {
-  try {
-    if (!p.isSizing()) eqs = PDEStack().selectedDG();
-  } catch (...) { tk::processExceptionCharm(); }
-}
-
-//! \brief Pack/Unpack selected partial differential equations using
-//!   finite volume discretization.
-//! \details This Pack/Unpack method (re-)creates the PDE factory since it needs
-//!   to (re-)bind function pointers on different processing elements. Therefore
-//!   we circumvent Charm's usual pack/unpack for this type, and thus sizing
-//!   does not make sense: sizing is a no-op. We could initialize the factory in
-//!   InciterDriver's constructor and let this function re-create the stack only
-//!   when unpacking, but that leads to repeating the same code twice: once in
-//!   InciterDriver's constructor, once here. Another option is to use this
-//!   pack/unpack routine to both initially create (when packing) and to
-//!   re-create (when unpacking) the factory, which eliminates the need for
-//!   pre-creating the object in InciterDriver's constructor and therefore
-//!   eliminates the repeated code. This explains the guard for sizing: the code
-//!   below is called for packing only (in serial) and packing and unpacking (in
-//!   parallel).
-inline
-void operator|( PUP::er& p, std::vector< FVPDE >& eqs ) {
-  try {
-    if (!p.isSizing()) eqs = PDEStack().selectedFV();
-  } catch (...) { tk::processExceptionCharm(); }
-}
-
-} // inciter::
-
-//! \brief Charm++ main chare for the shock hydrodynamics executable, inciter.
-//! \details In inciter the Charm++ runtime system is initialized only after the
-//!   mesh has been read in, partitioned, and the necessary data structures,
-//!   e.g., communication maps, have been generated. This delayed initialization
-//!   of the Charm++ runtime system is required since the mesh partitioning is
-//!   done by Zoltan, an MPI library. Note that this Charm++ main chare object
-//!   should not be in a namespace.
-// cppcheck-suppress noConstructor
-class Main : public CBase_Main {<--- Unmatched suppression: noConstructor
-
-  public:
-    //! \brief Constructor
-    //! \details Inciter's main chare constructor is the entry point of the
-    //!   Charm++ portion of inciter, called by the Charm++ runtime system. The
-    //!   constructor does basic initialization steps, prints out some useful
-    //!   information to screen (in verbose mode), and instantiates a driver.
-    //!   Since Charm++ is fully asynchronous, the constructor usually spawns
-    //!   asynchronous objects and immediately exits. Thus in the body of the
-    //!   main chare constructor we fire up an 'execute' chare, which then calls
-    //!   back to Main::execute(). Finishing the main chare constructor the
-    //!   Charm++ runtime system then starts the network-migration of all
-    //!   global-scope data (if any). The execute chare calling back to
-    //!   Main::execute() signals the end of the migration of the global-scope
-    //!   data. Then we are ready to execute the driver. Since inciter is
-    //!   parallel and asynchronous, its driver fires up additional Charm++
-    //!   chare objects which then call back to Main::finalize() at some point
-    //!   in the future when all work has been finished. finalize() then exits
-    //!   by calling Charm++'s CkExit(), shutting down the runtime system.
-    //! \see http://charm.cs.illinois.edu/manuals/html/charm++/manual.html
-    Main( CkArgMsg* msg )
-    try :
-      m_signal( tk::setSignalHandlers() ),
-      m_cmdline(),
-      // Parse command line into m_cmdline using default simple pretty printer
-      m_cmdParser( msg->argc, msg->argv, tk::Print(), m_cmdline ),
-      // Create Inciter driver
-      m_driver( tk::Main< inciter::InciterDriver >
-                        ( msg->argc, msg->argv,
-                          m_cmdline,
-                          tk::HeaderType::INCITER,
-                          tk::inciter_executable(),
-                          inciter::g_inputdeck_defaults.get< tag::cmd, tag::io,
-                            tag::screen >(),
-                          inciter::g_inputdeck_defaults.get< tag::cmd, tag::io,
-                            tag::nrestart >() ) ),
-      // Start new timer measuring the total runtime
-      m_timer(1),
-      m_timestamp()
-    {
-      delete msg;
-      g_trace = m_cmdline.get< tag::trace >();
-      tk::MainCtor( mainProxy, thisProxy, m_timer, m_cmdline,
-                    CkCallback( CkIndex_Main::quiescence(), thisProxy ) );
-      // If quiescence detection is on or user requested it, create chare state
-      // collector Charm++ chare group
-      if ( m_cmdline.get< tag::chare >() || m_cmdline.get< tag::quiescence >() )
-        stateProxy = tk::CProxy_ChareStateCollector::ckNew();
-      // Fire up an asynchronous execute object, which when created at some
-      // future point in time will call back to this->execute(). This is
-      // necessary so that this->execute() can access already migrated
-      // global-scope data.
-      CProxy_execute::ckNew();
-    } catch (...) { tk::processExceptionCharm(); }
-
-    //! Migrate constructor: returning from a checkpoint
-    explicit Main( CkMigrateMessage* msg ) : CBase_Main( msg ),
-      m_signal( tk::setSignalHandlers() ),
-      m_cmdline(),
-      m_cmdParser( reinterpret_cast<CkArgMsg*>(msg)->argc,
-                   reinterpret_cast<CkArgMsg*>(msg)->argv,
-                   tk::Print(),
-                   m_cmdline ),
-      m_driver( tk::Main< inciter::InciterDriver >
-                        ( reinterpret_cast<CkArgMsg*>(msg)->argc,
-                          reinterpret_cast<CkArgMsg*>(msg)->argv,
-                          m_cmdline,
-                          tk::HeaderType::INCITER,
-                          tk::inciter_executable(),
-                          inciter::g_inputdeck_defaults.get< tag::cmd,
-                            tag::io, tag::screen >(),
-                          inciter::g_inputdeck.get< tag::cmd,
-                            tag::io, tag::nrestart >()+1 ) ),
-      m_timer(1),
-      m_timestamp()
-    {
-      // increase number of restarts (available for Transporter on PE 0)
-      ++inciter::g_inputdeck.get< tag::cmd, tag::io, tag::nrestart >();
-      g_trace = m_cmdline.get< tag::trace >();
-      tk::MainCtor( mainProxy, thisProxy, m_timer, m_cmdline,
-                    CkCallback( CkIndex_Main::quiescence(), thisProxy ) );
-    }
-
-    //! Execute driver created and initialized by constructor
-    void execute() {
-      try {
-        m_timestamp.emplace_back("Migrate global-scope data", m_timer[1].hms());
-        m_driver.execute();
-      } catch (...) { tk::processExceptionCharm(); }
-    }
-
-    //! Towards normal exit but collect chare state first (if any)
-    void finalize() {
-      tk::finalize( m_cmdline, m_timer, stateProxy, m_timestamp,
-        inciter::g_inputdeck_defaults.get< tag::cmd, tag::io, tag::screen >(),
-        inciter::g_inputdeck.get< tag::cmd, tag::io, tag::nrestart >(),
-        CkCallback( CkIndex_Main::dumpstate(nullptr), thisProxy ) );
-    }
-
-    //! Entry method triggered when quiescence is detected
-    void quiescence() {
-      try {
-        stateProxy.collect( /* error= */ true,
-          CkCallback( CkIndex_Main::dumpstate(nullptr), thisProxy ) );
-      } catch (...) { tk::processExceptionCharm(); }
-    }
-
-    //! Dump chare state
-    void dumpstate( CkReductionMsg* msg ) {
-      tk::dumpstate( m_cmdline,
-        inciter::g_inputdeck_defaults.get< tag::cmd, tag::io, tag::screen >(),
-        inciter::g_inputdeck.get< tag::cmd, tag::io, tag::nrestart >(),
-        msg );
-    }
-
-    /** @name Charm++ pack/unpack serializer member functions */
-    ///@{
-    //! \brief Pack/Unpack serialize member function
-    //! \param[in,out] p Charm++'s PUP::er serializer object reference
-    //! \note This is a Charm++ mainchare, pup() is thus only for
-    //!    checkpoint/restart.
-    void pup( PUP::er &p ) override {
-      p | m_timer;
-    }
-    //! \brief Pack/Unpack serialize operator|
-    //! \param[in,out] p Charm++'s PUP::er serializer object reference
-    //! \param[in,out] m Mainchare object reference
-    friend void operator|( PUP::er& p, Main& m ) { m.pup(p); }
-    //@}
-
-  private:
-    int m_signal;                               //!< Used to set signal handlers
-    inciter::ctr::CmdLine m_cmdline;            //!< Command line
-    inciter::CmdLineParser m_cmdParser;         //!< Command line parser
-    inciter::InciterDriver m_driver;            //!< Driver
-    std::vector< tk::Timer > m_timer;           //!< Timers
-    //! Time stamps in h:m:s with labels
-    std::vector< std::pair< std::string, tk::Timer::Watch > > m_timestamp;
-};
-
-//! \brief Charm++ chare execute
-//! \details By the time this object is constructed, the Charm++ runtime system
-//!    has finished migrating all global-scoped read-only objects which happens
-//!    after the main chare constructor has finished.
-class execute : public CBase_execute {
-  public:
-    //! Constructor
-    execute() { mainProxy.execute(); }
-    //! Migrate constructor
-    explicit execute( CkMigrateMessage* m ) : CBase_execute( m ) {}
-};
-
-#include "NoWarning/inciter.def.h"
+  // Activate SDAG waits for face adjacency map (ghost data) calculation
+  thisProxy[ thisIndex ].wait4ghost();
+  thisProxy[ thisIndex ].wait4esup();
+
+  // Invert inpofa to enable searching for faces based on (global) node triplets
+  Assert( inpofa.size() % 3 == 0, "Inpofa must contain triplets" );
+  for (std::size_t f=0; f<inpofa.size()/3; ++f)
+    m_ipface.insert( {{{ gid[ inpofa[f*3+0] ],
+                         gid[ inpofa[f*3+1] ],
+                         gid[ inpofa[f*3+2] ] }}} );
+
+  // At this point ipface has node-id-triplets (faces) on the internal
+  // chare-domain and on the physical boundary but not on chare boundaries,
+  // hence the name internal + physical boundary faces.
+
+  // Build a set of faces (each face given by 3 global node IDs) associated to
+  // chares we potentially share boundary faces with.
+  tk::UnsMesh::FaceSet potbndface;
+  for (std::size_t e=0; e<esuel.size()/4; ++e) {   // for all our tets
+    auto mark = e*4;
+    for (std::size_t f=0; f<4; ++f)     // for all tet faces
+      if (esuel[mark+f] == -1) {        // if face has no outside-neighbor tet
+        // if does not exist among the internal and physical boundary faces,
+        // store as a potential chare-boundary face
+        tk::UnsMesh::Face t{{ gid[ m_inpoel[ mark + tk::lpofa[f][0] ] ],
+                              gid[ m_inpoel[ mark + tk::lpofa[f][1] ] ],
+                              gid[ m_inpoel[ mark + tk::lpofa[f][2] ] ] }};
+        if (m_ipface.find(t) == end(m_ipface)) {
+          Assert( m_expChBndFace.insert(t).second,
+                  "Store expected chare-boundary face" );
+          potbndface.insert( t );
+        }
+      }
+  }
+
+  if ( g_inputdeck.get< tag::cmd, tag::feedback >() ) d->Tr().chbndface();
+
+  // In the following we assume that the size of the (potential) boundary-face
+  // adjacency map above does not necessarily equal to that of the node
+  // adjacency map. This is because while a node can be shared at a single
+  // corner or along an edge, that does not necessarily share a face as well
+  // (in other words, shared nodes or edges can exist that are not part of a
+  // shared face). So the chares we communicate with across faces are not
+  // necessarily the same as the chares we would communicate nodes with.
+  //
+  // Since the sizes of the node and face adjacency maps are not the same, while
+  // sending the faces on chare boundaries would be okay, however, the receiver
+  // would not necessarily know how many chares it must receive from. To solve
+  // this problem we send to chares which we share at least a single node with,
+  // i.e., rely on the node-adjacency map. Note that to all chares we share at
+  // least a single node with we send all our potential chare-boundary faces.
+  // This is the same list of faces to all chares we send.
+  //
+  // Another underlying assumption here is, of course, that the size of the face
+  // adjacency map is always smaller than or equal to that of the node adjacency
+  // map, which is always true. Since the receive side already knows how many
+  // fellow chares it must receive shared node ids from, we use that to detect
+  // completion of the number of receives in comfac(). This simplifies the
+  // communication pattern and code.
+
+  // Send sets of faces adjacent to chare boundaries to fellow workers (if any)
+  if (d->NodeCommMap().empty())  // in serial, skip setting up ghosts altogether
+    faceAdj();
+  else
+    // for all chares we share nodes with
+    for (const auto& c : d->NodeCommMap()) {
+      thisProxy[ c.first ].comfac( thisIndex, potbndface );
+    }
+
+  ownfac_complete();
+}
+
+void
+Ghosts::comfac( int fromch, const tk::UnsMesh::FaceSet& infaces )
+// *****************************************************************************
+//  Receive unique set of faces we potentially share with/from another chare
+//! \param[in] fromch Sender chare id
+//! \param[in] infaces Unique set of faces we potentially share with fromch
+// *****************************************************************************
+{
+  if (g_inputdeck.get< tag::cmd, tag::chare >() ||
+      g_inputdeck.get< tag::cmd, tag::quiescence >())
+    stateProxy.ckLocalBranch()->insert( "Ghosts", thisIndex, CkMyPe(), Disc()->It(),
+                                        "comfac" );
+
+  // Buffer up incoming data
+  m_infaces[ fromch ] = infaces;
+
+  // if we have heard from all fellow chares that we share at least a single
+  // node, edge, or face with
+  if (++m_ncomfac == Disc()->NodeCommMap().size()) {
+    m_ncomfac = 0;
+    comfac_complete();
+  }
+}
+
+void
+Ghosts::bndFaces()
+// *****************************************************************************
+// Compute chare-boundary faces
+//! \details This is called when both send and receives are completed on a
+//!  chare and thus we are ready to compute chare-boundary faces and ghost data.
+// *****************************************************************************
+{
+  auto d = Disc();
+  if ( g_inputdeck.get< tag::cmd, tag::feedback >() ) d->Tr().chcomfac();
+  const auto& esuel = m_fd.Esuel();
+  const auto& gid = d->Gid();
+
+  for (const auto& in : m_infaces) {
+    // Find sender chare among chares we potentially share faces with. Note that
+    // it is feasible that a sender chare called us but we do not have a set of
+    // faces associated to that chare. This can happen if we only share a single
+    // node or an edge but not a face with that chare.
+    auto& bndface = m_bndFace[ in.first ];  // will associate to sender chare
+    // Try to find incoming faces on our chare boundary with other chares. If
+    // found, generate and assign new local face ID, associated to sender chare.
+    for (std::size_t e=0; e<esuel.size()/4; ++e) {  // for all our tets
+      auto mark = e*4;
+      for (std::size_t f=0; f<4; ++f) {  // for all cell faces
+        if (esuel[mark+f] == -1) {  // if face has no outside-neighbor tet
+          tk::UnsMesh::Face t{{ gid[ m_inpoel[ mark + tk::lpofa[f][0] ] ],
+                                gid[ m_inpoel[ mark + tk::lpofa[f][1] ] ],
+                                gid[ m_inpoel[ mark + tk::lpofa[f][2] ] ] }};
+          // if found among the incoming faces and if not one of our internal
+          // nor physical boundary faces
+          if ( in.second.find(t) != end(in.second) &&
+               m_ipface.find(t) == end(m_ipface) ) {
+            bndface[t][0] = m_nfac++;    // assign new local face ID
+          }
+        }
+      }
+    }
+    // If at this point if we have not found any face among our faces we
+    // potentially share with fromch, there is no need to keep an empty set of
+    // faces associated to fromch as we only share nodes or edges with it, but
+    // not faces.
+    if (bndface.empty()) m_bndFace.erase( in.first );
+  }
+
+  tk::destroy(m_ipface);
+  tk::destroy(m_infaces);
+
+  // Ensure all expected faces have been received
+  Assert( receivedChBndFaces(),
+    "Expected and received chare boundary faces mismatch" );
+
+  // Basic error checking on chare-boundary-face map
+  Assert( m_bndFace.find( thisIndex ) == m_bndFace.cend(),
+          "Face-communication map should not contain data for own chare ID" );
+
+  // Store (local) tet ID adjacent to our chare boundary from the inside
+  for (std::size_t e=0; e<esuel.size()/4; ++e) {  // for all our tets
+    auto mark = e*4;
+    for (std::size_t f=0; f<4; ++f) {  // for all cell faces
+      if (esuel[mark+f] == -1) {  // if face has no outside-neighbor tet
+        tk::UnsMesh::Face t{{ gid[ m_inpoel[ mark + tk::lpofa[f][0] ] ],
+                              gid[ m_inpoel[ mark + tk::lpofa[f][1] ] ],
+                              gid[ m_inpoel[ mark + tk::lpofa[f][2] ] ] }};
+        auto c = findchare(t);
+        if (c > -1) {
+          auto& lbndface = tk::ref_find( m_bndFace, c );
+          auto& face = tk::ref_find( lbndface, t );
+          face[1] = e;  // store (local) inner tet ID adjacent to face
+        }
+      }
+    }
+  }
+
+  // At this point m_bndFace is complete on this PE. This means that starting
+  // from the sets of faces we potentially share with fellow chares we now
+  // only have those faces we actually share faces with (through which we need
+  // to communicate later). Also, m_bndFace not only has the unique faces
+  // associated to fellow chares, but also a newly assigned local face ID as
+  // well as the local id of the inner tet adjacent to the face. Continue by
+  // starting setting up ghost data
+  setupGhost();
+  // Besides setting up our own ghost data, we also issue requests (for ghost
+  // data) to those chares which we share faces with. Note that similar to
+  // comfac() we are calling reqGhost() by going through the node communication
+  // map instead, which may send requests to those chare we do not share faces
+  // with. This is so that we can test for completing by querying the size of
+  // the already complete node commincation map in reqGhost. Requests in
+  // sendGhost will only be fullfilled based on m_ghostData.
+  for (const auto& c : d->NodeCommMap())  // for all chares we share nodes with
+    thisProxy[ c.first ].reqGhost();
+}
+
+void
+Ghosts::setupGhost()
+// *****************************************************************************
+// Setup own ghost data on this chare
+// *****************************************************************************
+{
+  auto d = Disc();
+  const auto& gid = d->Gid();
+
+  // Enlarge elements surrounding faces data structure for ghosts
+  m_fd.Esuf().resize( 2*m_nfac, -2 );
+  m_fd.Inpofa().resize( 3*m_nfac, 0 );
+  // Enlarge face geometry data structure for ghosts
+  m_geoFace.resize( m_nfac, 0.0 );
+
+  const auto& esuel = m_fd.Esuel();
+
+  // Collect tet ids, their face connectivity (given by 3 global node IDs, each
+  // triplet for potentially multiple faces on the chare boundary), and their
+  // elem geometry data (see GhostData) associated to fellow chares adjacent to
+  // chare boundaries. Once received by fellow chares, these tets will become
+  // known as ghost elements and their data as ghost data.
+  for (std::size_t e=0; e<esuel.size()/4; ++e) {  // for all our tets
+    auto mark = e*4;
+    for (std::size_t f=0; f<4; ++f) {  // for all cell faces
+      if (esuel[mark+f] == -1) {  // if face has no outside-neighbor tet
+        tk::UnsMesh::Face t{{ gid[ m_inpoel[ mark + tk::lpofa[f][0] ] ],
+                              gid[ m_inpoel[ mark + tk::lpofa[f][1] ] ],
+                              gid[ m_inpoel[ mark + tk::lpofa[f][2] ] ] }};
+        auto c = findchare(t);
+        // It is possible that we do not find the chare for this face. We are
+        // looping through all of our tets and interrogating all faces that do
+        // not have neighboring tets but we only care about chare-boundary faces
+        // here as only those need ghost data. (esuel may also contain
+        // physical boundary faces)
+        if (c > -1) {
+          // Will store ghost data associated to neighbor chare
+          auto& ghost = m_ghostData[ c ];
+          // Store tet id adjacent to chare boundary as key for ghost data
+          auto& tuple = ghost[ e ];
+          // If tetid e has not yet been encountered, store geometry (only once)
+          auto& nodes = std::get< 0 >( tuple );
+          if (nodes.empty()) {
+            std::get< 1 >( tuple ) = m_geoElem[ e ];
+
+            auto& ncoord = std::get< 2 >( tuple );
+            ncoord[0] = m_coord[0][ m_inpoel[ mark+f ] ];
+            ncoord[1] = m_coord[1][ m_inpoel[ mark+f ] ];
+            ncoord[2] = m_coord[2][ m_inpoel[ mark+f ] ];
+
+            std::get< 3 >( tuple ) = f;
+
+            std::get< 4 >( tuple ) = {{ gid[ m_inpoel[ mark ] ],
+                                        gid[ m_inpoel[ mark+1 ] ],
+                                        gid[ m_inpoel[ mark+2 ] ],
+                                        gid[ m_inpoel[ mark+3 ] ] }};
+          }
+          // (Always) store face node IDs on chare boundary, even if tetid e has
+          // already been stored. Thus we store potentially multiple faces along
+          // the same chare-boundary. This happens, e.g., when the boundary
+          // between chares is zig-zaggy enough to have 2 or even 3 faces of the
+          // same tet.
+          nodes.push_back( t[0] );
+          nodes.push_back( t[1] );
+          nodes.push_back( t[2] );
+          Assert( nodes.size() <= 4*3, "Overflow of faces/tet to send" );
+        }
+      }
+    }
+  }
+
+  // Basic error checking on local ghost data
+  Assert( m_ghostData.find( thisIndex ) == m_ghostData.cend(),
+          "Chare-node adjacency map should not contain data for own chare ID" );
+
+  // More in-depth error checking on local ghost data
+  for (const auto& c : m_ghostData)
+    for ([[maybe_unused]] const auto& t : c.second) {
+      Assert( !std::get< 0 >( t.second ).empty(),
+              "Emtpy face vector in ghost data" );
+      Assert( std::get< 0 >( t.second ).size() % 3 == 0,
+              "Face node IDs must be triplets" );
+      Assert( std::get< 0 >( t.second ).size() <= 4*3,    // <= 4*3 (4*numfaces)
+              "Max number of faces for a single ghost tet is 4" );
+      Assert( !std::get< 1 >( t.second ).empty(),
+              "No elem geometry data for ghost" );
+      Assert( std::get< 1 >( t.second ).size() == m_geoElem.nprop(),
+              "Elem geometry data for ghost must be for single tet" );
+      Assert( !std::get< 2 >( t.second ).empty(),
+              "No nodal coordinate data for ghost" );
+    }
+
+  ownghost_complete();
+}
+
+void
+Ghosts::reqGhost()
+// *****************************************************************************
+// Receive requests for ghost data
+// *****************************************************************************
+{
+  if (g_inputdeck.get< tag::cmd, tag::chare >() ||
+      g_inputdeck.get< tag::cmd, tag::quiescence >())
+    stateProxy.ckLocalBranch()->insert( "Ghosts", thisIndex, CkMyPe(), Disc()->It(),
+                                        "reqGhost" );
+
+  // If every chare we communicate with has requested ghost data from us, we may
+  // fulfill the requests, but only if we have already setup our ghost data.
+  if (++m_ghostReq == Disc()->NodeCommMap().size()) {
+    m_ghostReq = 0;
+    reqghost_complete();
+  }
+}
+
+void
+Ghosts::sendGhost()
+// *****************************************************************************
+// Send all of our ghost data to fellow chares
+// *****************************************************************************
+{
+  if (g_inputdeck.get< tag::cmd, tag::chare >() ||
+      g_inputdeck.get< tag::cmd, tag::quiescence >())
+    stateProxy.ckLocalBranch()->insert( "Ghosts", thisIndex, CkMyPe(), Disc()->It(),
+                                        "sendGhost" );
+
+  for (const auto& c : m_ghostData)
+    thisProxy[ c.first ].comGhost( thisIndex, c.second );
+
+  if ( g_inputdeck.get< tag::cmd, tag::feedback >() ) Disc()->Tr().chghost();
+}
+
+void
+Ghosts::comGhost( int fromch, const GhostData& ghost )
+// *****************************************************************************
+// Receive ghost data on chare boundaries from fellow chare
+//! \param[in] fromch Caller chare ID
+//! \param[in] ghost Ghost data, see Inciter/FaceData.h for the type
+// *****************************************************************************
+{
+  if (g_inputdeck.get< tag::cmd, tag::chare >() ||
+      g_inputdeck.get< tag::cmd, tag::quiescence >())
+    stateProxy.ckLocalBranch()->insert( "Ghosts", thisIndex, CkMyPe(), Disc()->It(),
+                                        "comGhost" );
+
+  auto d = Disc();
+  const auto& lid = d->Lid();
+  auto& inpofa = m_fd.Inpofa();
+  auto ncoord = m_coord[0].size();<--- Variable 'ncoord' is assigned a value that is never used.
+
+  // nodelist with fromch, currently only used for an assert
+  [[maybe_unused]] const auto& nl = tk::cref_find( d->NodeCommMap(), fromch );
+
+  auto& ghostelem = m_ghost[ fromch ];  // will associate to sender chare
+
+  // Store ghost data coming from chare
+  for (const auto& g : ghost) {  // loop over incoming ghost data
+    auto e = g.first;  // remote/ghost tet id outside of chare boundary<--- Variable 'e' is assigned a value that is never used.
+    const auto& nodes = std::get< 0 >( g.second );  // node IDs of face(s)
+    const auto& geo = std::get< 1 >( g.second );    // ghost elem geometry data
+    const auto& coordg = std::get< 2 >( g.second );  // coordinate of ghost node
+    const auto& inpoelg = std::get< 4 >( g.second ); // inpoel of ghost tet
+
+    Assert( nodes.size() % 3 == 0, "Face node IDs must be triplets" );
+    Assert( nodes.size() <= 4*3, "Overflow of faces/tet received" );
+    Assert( geo.size() % 5 == 0, "Ghost geometry size mismatch" );
+    Assert( geo.size() == m_geoElem.nprop(), "Ghost geometry number mismatch" );
+    Assert( coordg.size() == 3, "Incorrect ghost node coordinate size" );
+    Assert( inpoelg.size() == 4, "Incorrect ghost inpoel size" );
+
+    for (std::size_t n=0; n<nodes.size()/3; ++n) {  // face(s) of ghost e
+      // node IDs of face on chare boundary
+      tk::UnsMesh::Face t{{ nodes[n*3+0], nodes[n*3+1], nodes[n*3+2] }};
+      // must find t in nodelist of chare-boundary adjacent to fromch
+      Assert( nl.find(t[0]) != end(nl) &&
+              nl.find(t[1]) != end(nl) &&
+              nl.find(t[2]) != end(nl),
+           "Ghost face not found in chare-node adjacency map on receiving end" );
+      // must find face in boundary-face adjacency map for fromch
+      Assert( tk::cref_find(m_bndFace,fromch).find( t ) !=
+              tk::cref_find(m_bndFace,fromch).cend(), "Ghost face not "
+              "found in boundary-face adjacency map on receiving end" );
+      // find local face & tet ids for t
+      auto id = tk::cref_find( tk::cref_find(m_bndFace,fromch), t );
+      // compute face geometry for chare-boundary face
+      addGeoFace(t, id);
+      // add node-triplet to node-face connectivity
+      inpofa[3*id[0]+0] = tk::cref_find( lid, t[2] );
+      inpofa[3*id[0]+1] = tk::cref_find( lid, t[1] );
+      inpofa[3*id[0]+2] = tk::cref_find( lid, t[0] );
+
+      // if ghost tet id not yet encountered on boundary with fromch
+      auto i = ghostelem.find( e );
+      if (i != end(ghostelem)) {
+        // fill in elements surrounding face
+        addEsuf(id, i->second);
+        // fill in elements surrounding element
+        addEsuel(id, i->second, t);
+      } else {
+        // fill in elements surrounding face
+        addEsuf(id, m_nunk);
+        // fill in elements surrounding element
+        addEsuel(id, m_nunk, t);
+        ghostelem[e] = m_nunk;     // assign new local tet id to remote ghost id
+        m_geoElem.push_back( geo );// store ghost elem geometry
+        ++m_nunk;                  // increase number of unknowns on this chare
+        std::size_t counter = 0;
+        for (std::size_t gp=0; gp<4; ++gp) {
+          auto it = lid.find( inpoelg[gp] );
+          std::size_t lp;
+          if (it != end(lid))
+            lp = it->second;
+          else {
+            Assert( nodes.size() == 3, "Expected node not found in lid" );
+            Assert( gp == std::get< 3 >( g.second ),
+                    "Ghost node not matching correct entry in ghost inpoel" );
+            lp = ncoord;
+            ++counter;
+          }
+          m_inpoel.push_back( lp );       // store ghost element connectivity
+        }
+        // only a single or no ghost node should be found
+        Assert( counter <= 1, "Incorrect number of ghost nodes detected. "
+                "Detected "+ std::to_string(counter) +" ghost nodes" );
+        if (counter == 1) {
+          m_coord[0].push_back( coordg[0] ); // store ghost node coordinate
+          m_coord[1].push_back( coordg[1] );
+          m_coord[2].push_back( coordg[2] );
+          Assert( m_inpoel[ 4*(m_nunk-1)+std::get< 3 >( g.second ) ] == ncoord,
+                  "Mismatch in extended inpoel for ghost element" );
+          ++ncoord;                // increase number of nodes on this chare<--- Variable 'ncoord' is assigned a value that is never used.
+        }
+      }
+
+      // additional tests to ensure that entries in inpoel and t/inpofa match
+      Assert( nodetripletMatch(id, t) == 3,
+        "Mismatch/Overmatch in inpoel and inpofa at chare-boundary face" );
+    }
+  }
+
+  // Signal the runtime system that all workers have received their
+  // face-adjacency
+  if (++m_nadj == m_ghostData.size()) faceAdj();
+}
+
+void
+Ghosts::faceAdj()
+// *****************************************************************************
+// Continue after face adjacency communication map completed on this chare
+//! \details At this point the face communication map has been established
+//!    on this chare. Proceed to set up the nodal-comm map.
+// *****************************************************************************
+{
+  m_nadj = 0;
+
+  tk::destroy(m_bndFace);
+
+  // Ensure that all elements surrounding faces (are correct) including those at
+  // chare boundaries
+  for (std::size_t f=0; f<m_nfac; ++f) {
+    Assert( m_fd.Esuf()[2*f] > -1,
+            "Left element in esuf cannot be physical ghost" );
+    if (f >= m_fd.Nbfac())
+      Assert( m_fd.Esuf()[2*f+1] > -1,
+           "Right element in esuf for internal/chare faces cannot be a ghost" );
+  }
+
+  // Ensure that all elements surrounding elements are correct including those
+  // at chare boundaries
+  const auto& esuel = m_fd.Esuel();
+  std::size_t nbound = 0;
+  for (std::size_t e=0; e<esuel.size()/4; ++e) {
+    for (std::size_t f=0; f<4; ++f)
+      if (esuel[4*e+f] == -1) ++nbound;
+  }
+  Assert( nbound == m_fd.Nbfac(), "Incorrect number of ghost-element -1's in "
+         "updated esuel" );
+
+  // Error checking on ghost data
+  for(const auto& n : m_ghostData)
+    for([[maybe_unused]] const auto& i : n.second)
+      Assert( i.first < m_fd.Esuel().size()/4, "Sender contains ghost tet id " );
+
+  // Perform leak test on face geometry data structure enlarged by ghosts
+  Assert( !leakyAdjacency(), "Face adjacency leaky" );
+  Assert( faceMatch(), "Chare-boundary element-face "
+    "connectivity (esuf) does not match" );
+
+  // Create new map of elements along chare boundary which are ghosts for
+  // neighboring chare, associated with that chare ID
+  for (const auto& [cid, cgd] : m_ghostData)
+  {
+    auto& sg = m_sendGhost[cid];
+    for (const auto& e : cgd)
+    {
+      Assert(sg.find(e.first) == sg.end(), "Repeating element found in "
+        "ghost data");
+      sg.insert(e.first);
+    }
+    Assert(sg.size() == cgd.size(), "Incorrect size for sendGhost");
+  }
+  Assert(m_sendGhost.size() == m_ghostData.size(), "Incorrect number of "
+    "chares in sendGhost");
+
+  // Error checking on ghost data
+  for(const auto& n : m_sendGhost)
+    for([[maybe_unused]] const auto& i : n.second)
+      Assert( i < m_fd.Esuel().size()/4, "Sender contains ghost tet id. " );
+
+  // Generate and store Esup data-structure in a map
+  auto esup = tk::genEsup(m_inpoel, 4);
+  for (std::size_t p=0; p<Disc()->Gid().size(); ++p)
+  {
+    for (auto e : tk::Around(esup, p))
+    {
+      // since inpoel has been augmented with the face-ghost cell previously,
+      // esup also contains cells which are not on this mesh-chunk, hence the
+      // following test
+      if (e < m_fd.Esuel().size()/4) m_esup[p].push_back(e);
+    }
+  }
+
+  // Error checking on Esup map
+  for(const auto& p : m_esup)
+    for([[maybe_unused]] const auto& e : p.second)
+      Assert( e < m_fd.Esuel().size()/4, "Esup contains tet id greater than "
+      + std::to_string(m_fd.Esuel().size()/4-1) +" : "+ std::to_string(e) );
+
+  auto meshid = Disc()->MeshId();
+  contribute( sizeof(std::size_t), &meshid, CkReduction::nop,
+    CkCallback(CkReductionTarget(Transporter,startEsup), Disc()->Tr()) );
+}
+
+void
+Ghosts::nodeNeighSetup()
+// *****************************************************************************
+// Setup node-neighborhood (esup)
+//! \details At this point the face-ghost communication map has been established
+//!    on this chare. This function begins generating the node-ghost comm map.
+// *****************************************************************************
+{
+  if (Disc()->NodeCommMap().empty())
+  // in serial, skip setting up node-neighborhood
+  { comesup_complete(); }
+  else
+  {
+    const auto& nodeCommMap = Disc()->NodeCommMap();
+
+    // send out node-neighborhood map
+    for (const auto& [cid, nlist] : nodeCommMap)
+    {
+      std::unordered_map< std::size_t, std::vector< std::size_t > > bndEsup;
+      std::unordered_map< std::size_t, std::vector< tk::real > > nodeBndCells;
+      for (const auto& p : nlist)
+      {
+        auto pl = tk::cref_find(Disc()->Lid(), p);
+        // fill in the esup for the chare-boundary
+        const auto& pesup = tk::cref_find(m_esup, pl);
+        bndEsup[p] = pesup;
+
+        // fill a map with the element ids from esup as keys and geoElem as
+        // values, and another map containing these elements associated with
+        // the chare id with which they are node-neighbors.
+        for (const auto& e : pesup)
+        {
+          nodeBndCells[e] = m_geoElem[e];
+
+          // add these esup-elements into map of elements along chare boundary
+          Assert( e < m_fd.Esuel().size()/4, "Sender contains ghost tet id." );
+          m_sendGhost[cid].insert(e);
+        }
+      }
+
+      thisProxy[cid].comEsup(thisIndex, bndEsup, nodeBndCells);
+    }
+  }
+
+  ownesup_complete();
+}
+
+void
+Ghosts::comEsup( int fromch,
+  const std::unordered_map< std::size_t, std::vector< std::size_t > >& bndEsup,
+  const std::unordered_map< std::size_t, std::vector< tk::real > >&
+    nodeBndCells )
+// *****************************************************************************
+//! \brief Receive elements-surrounding-points data-structure for points on
+//    common boundary between receiving and sending neighbor chare, and the
+//    element geometries for these new elements
+//! \param[in] fromch Sender chare id
+//! \param[in] bndEsup Elements-surrounding-points data-structure from fromch
+//! \param[in] nodeBndCells Map containing element geometries associated with
+//!   remote element IDs in the esup
+// *****************************************************************************
+{
+  auto& chghost = m_ghost[fromch];
+
+  // Extend remote-local element id map and element geometry array
+  for (const auto& e : nodeBndCells)
+  {
+    // need to check following, because 'e' could have been added previously in
+    // remote-local element id map as a part of face-communication, i.e. as a
+    // face-ghost element
+    if (chghost.find(e.first) == chghost.end())
+    {
+      chghost[e.first] = m_nunk;
+      m_geoElem.push_back(e.second);
+      ++m_nunk;
+    }
+  }
+
+  // Store incoming data in comm-map buffer for Esup
+  for (const auto& [node, elist] : bndEsup)
+  {
+    auto pl = tk::cref_find(Disc()->Lid(), node);
+    auto& pesup = m_esupc[pl];
+    for (auto e : elist)
+    {
+      auto el = tk::cref_find(chghost, e);
+      pesup.push_back(el);
+    }
+  }
+
+  // if we have heard from all fellow chares that we share at least a single
+  // node, edge, or face with
+  if (++m_ncomEsup == Disc()->NodeCommMap().size()) {
+    m_ncomEsup = 0;
+    comesup_complete();
+  }
+}
+
+void
+Ghosts::adj()
+// *****************************************************************************
+// Finish up with adjacency maps, and do a global-sync to begin problem setup
+//! \details At this point, the nodal- and face-adjacency has been set up. This
+//    function does some error checking on the nodal-adjacency and prepares
+//    for problem setup.
+// *****************************************************************************
+{
+  // combine own and communicated contributions to elements surrounding points
+  for (auto& [p, elist] : m_esupc)
+  {
+    auto& pesup = tk::ref_find(m_esup, p);
+    for ([[maybe_unused]] auto e : elist)
+    {
+      Assert( e >= m_fd.Esuel().size()/4, "Non-ghost element received from "
+        "esup buffer." );
+    }
+    tk::concat< std::size_t >(std::move(elist), pesup);
+  }
+
+  tk::destroy(m_ghostData);
+  tk::destroy(m_esupc);
+
+  if ( g_inputdeck.get< tag::cmd, tag::feedback >() ) Disc()->Tr().chadj();
+
+  // Error checking on ghost data
+  for(const auto& n : m_sendGhost)
+    for([[maybe_unused]] const auto& i : n.second)
+      Assert( i < m_fd.Esuel().size()/4, "Sender contains ghost tet id. ");
+
+  // Create a mapping between local ghost tet ids and zero-based boundary ids
+  std::vector< std::size_t > c( tk::sumvalsize( m_ghost ) );
+  std::size_t j = 0;
+  for (const auto& n : m_ghost) {
+    for(const auto& i : n.second) {
+      c[j++] = i.second;
+    }
+  }
+  m_bid = tk::assignLid( c );
+
+  // Basic error checking on ghost tet ID map
+  Assert( m_ghost.find( thisIndex ) == m_ghost.cend(),
+          "Ghost id map should not contain data for own chare ID" );
+
+  // Store expected ghost tet IDs
+  for (const auto& n : m_ghost)
+    for ([[maybe_unused]] const auto& g : n.second)
+      Assert( m_exptGhost.insert( g.second ).second,
+              "Failed to store local tetid as exptected ghost id" );
+
+  // Callback function from DG/FV after ghost-setup is done
+  m_cbAfterDone.send();
+}
+
+bool
+Ghosts::leakyAdjacency()
+// *****************************************************************************
+// Perform leak-test on chare boundary faces
+//! \details This function computes a surface integral over the boundary of the
+//!   faces after the face adjacency communication map is completed. A non-zero
+//!   vector result indicates a leak, e.g., a hole in the partition (covered by
+//!   the faces of the face adjacency communication map), which indicates an
+//!   error upstream in the code that sets up the face communication data
+//!   structures.
+//! \note Compared to tk::leakyPartition() this function performs the leak-test
+//!   on the face geometry data structure enlarged by ghost faces on this
+//!   partition by computing a discrete surface integral considering the
+//!   physical and chare boundary faces, which should be equal to zero for a
+//!   closed domain.
+//! \return True if our chare face adjacency leaks.
+// *****************************************************************************
+{
+  // Storage for surface integral over our chunk of the adjacency
+  std::array< tk::real, 3 > s{{ 0.0, 0.0, 0.0 }};
+
+  // physical boundary faces
+  for (std::size_t f=0; f<m_fd.Nbfac(); ++f) {
+    s[0] += m_geoFace(f,0) * m_geoFace(f,1);
+    s[1] += m_geoFace(f,0) * m_geoFace(f,2);
+    s[2] += m_geoFace(f,0) * m_geoFace(f,3);
+  }
+
+  // chare-boundary faces
+  for (std::size_t f=m_fd.Nipfac(); f<m_fd.Esuf().size()/2; ++f) {
+    s[0] += m_geoFace(f,0) * m_geoFace(f,1);
+    s[1] += m_geoFace(f,0) * m_geoFace(f,2);
+    s[2] += m_geoFace(f,0) * m_geoFace(f,3);
+  }
+
+  auto eps = std::numeric_limits< tk::real >::epsilon() * 100;
+  return std::abs(s[0]) > eps || std::abs(s[1]) > eps || std::abs(s[2]) > eps;
+}
+
+bool
+Ghosts::faceMatch()
+// *****************************************************************************
+// Check if esuf of chare-boundary faces matches
+//! \details This function checks each chare-boundary esuf entry for the left
+//!   and right elements. Then, it tries to match all vertices of these
+//!   elements. Exactly three of these vertices must match if the esuf entry
+//!   has been updated correctly at chare-boundaries.
+//! \return True if chare-boundary faces match.
+// *****************************************************************************
+{
+  const auto& esuf = m_fd.Esuf();
+  bool match(true);
+
+  auto eps = std::numeric_limits< tk::real >::epsilon() * 100;
+
+  for (auto f=m_fd.Nipfac(); f<esuf.size()/2; ++f)
+  {
+    std::size_t el = static_cast< std::size_t >(esuf[2*f]);
+    std::size_t er = static_cast< std::size_t >(esuf[2*f+1]);
+
+    std::size_t count = 0;
+
+    for (std::size_t i=0; i<4; ++i)
+    {
+      auto ip = m_inpoel[4*el+i];
+      for (std::size_t j=0; j<4; ++j)
+      {
+        auto jp = m_inpoel[4*er+j];
+        auto xdiff = std::abs( m_coord[0][ip] - m_coord[0][jp] );
+        auto ydiff = std::abs( m_coord[1][ip] - m_coord[1][jp] );
+        auto zdiff = std::abs( m_coord[2][ip] - m_coord[2][jp] );
+
+        if ( xdiff<=eps && ydiff<=eps && zdiff<=eps ) ++count;
+      }
+    }
+
+    match = (match && count == 3);
+  }
+
+  return match;
+}
+
+bool
+Ghosts::receivedChBndFaces()
+// *****************************************************************************
+// Verify that all chare-boundary faces have been received
+//! \return True if all chare-boundary faces have been received
+// *****************************************************************************
+{
+  const auto& lid = Disc()->Lid();
+  tk::UnsMesh::FaceSet recvBndFace;
+
+  // Collect chare-boundary faces that have been received and expected
+  for (const auto& c : m_bndFace)
+    for (const auto& f : c.second)
+      if (m_expChBndFace.find(f.first) != end(m_expChBndFace))
+        recvBndFace.insert(f.first);
+
+   // Collect info on expected but not received faces
+   std::stringstream msg;
+   for (const auto& f : m_expChBndFace)
+     if (recvBndFace.find(f) == end(recvBndFace)) {
+       const auto& x = m_coord[0];
+       const auto& y = m_coord[1];
+       const auto& z = m_coord[2];
+       auto A = tk::cref_find( lid, f[0] );
+       auto B = tk::cref_find( lid, f[1] );
+       auto C = tk::cref_find( lid, f[2] );
+       msg << '{' << A << ',' << B << ',' << C << "}:("
+           << x[A] << ',' << y[A] << ',' << z[A] << ' '
+           << x[B] << ',' << y[B] << ',' << z[B] << ' '
+           << x[C] << ',' << y[C] << ',' << z[C] << ") ";
+     }
+
+  tk::destroy( m_expChBndFace );
+
+  // Error out with info on missing faces
+  auto s = msg.str();
+  if (!s.empty()) {
+    Throw( "Ghosts chare " + std::to_string(thisIndex) +
+           " missing face(s) {local node ids} (node coords): " + s );
+  } else {
+    return true;
+  }
+}
+
+int
+Ghosts::findchare( const tk::UnsMesh::Face& t )
+// *****************************************************************************
+// Find any chare for face (given by 3 global node IDs)
+//! \param[in] t Face given by three global node IDs
+//! \return Chare ID if found among any of the chares we communicate along
+//!   faces with, -1 if the face cannot be found.
+// *****************************************************************************
+{
+  for (const auto& cf : m_bndFace)
+    // cppcheck-suppress useStlAlgorithm
+    if (cf.second.find(t) != end(cf.second))<--- Unmatched suppression: useStlAlgorithm
+      return cf.first;
+  return -1;
+}
+
+std::size_t
+Ghosts::nodetripletMatch(
+  const std::array< std::size_t, 2 >& id,
+  const tk::UnsMesh::Face& t )
+// *****************************************************************************
+// Check if entries in inpoel, inpofa and node-triplet are consistent
+//! \param[in] id Local face and (inner) tet id adjacent to it
+//! \param[in] t node-triplet associated with the chare boundary face
+//! \return number of nodes in inpoel that matched with t and inpofa
+// *****************************************************************************
+{
+  const auto& esuf = m_fd.Esuf();
+  const auto& inpofa = m_fd.Inpofa();
+  const auto& lid = Disc()->Lid();
+
+  std::size_t counter = 0;
+  for (std::size_t k=0; k<4; ++k)
+  {
+    auto el = esuf[ 2*id[0] ];
+    auto ip = m_inpoel[ 4*static_cast< std::size_t >( el )+k ];<--- Variable 'ip' is assigned a value that is never used.
+    Assert( el == static_cast< int >( id[1] ), "Mismatch in id and esuf" );
+    for (std::size_t j=0; j<3; ++j)
+    {
+      auto jp = tk::cref_find( lid, t[j] );
+      auto fp = inpofa[ 3*id[0]+(2-j) ];
+      if (ip == jp && ip == fp) ++counter;
+    }
+  }
+
+  return counter;
+}
+
+void
+Ghosts::addEsuf(
+  const std::array< std::size_t, 2 >& id,
+  std::size_t ghostid )
+// *****************************************************************************
+// Fill elements surrounding a face along chare boundary
+//! \param[in] id Local face and (inner) tet id adjacent to it
+//! \param[in] ghostid Local ID for ghost tet
+//! \details This function extends and fills in the elements surrounding faces
+//!   data structure (esuf) so that the left and right element id is filled
+//!   in correctly on chare boundaries to contain the correct inner tet id and
+//!   the local tet id for the outer (ghost) tet, both adjacent to the given
+//!   chare-face boundary. Prior to this function, this data structure does not
+//!   have yet face-element connectivity adjacent to chare-boundary faces, only
+//!   for physical boundaries and internal faces that are not on the chare
+//!   boundary (this latter purely as a result of mesh partitioning). The remote
+//!   element id of the ghost is stored in a location that is local to our own
+//!   esuf. The face numbering is such that esuf stores the element-face
+//!   connectivity first for the physical-boundary faces, followed by that of
+//!   the internal faces, followed by the chare-boundary faces. As a result,
+//!   esuf can be used by physics algorithms in exactly the same way as would be
+//!   used in serial. In serial, of course, this data structure is not extended
+//!   at the end by the chare-boundaries.
+// *****************************************************************************
+{
+  auto& esuf = m_fd.Esuf();
+
+  Assert( 2*id[0]+1 < esuf.size(), "Indexing out of esuf" );
+
+  // put in inner tet id
+  Assert( esuf[ 2*id[0] ] == -2 && esuf[ 2*id[0]+1 ] == -2, "Updating esuf at "
+          "wrong location instead of chare-boundary" );
+  esuf[ 2*id[0]+0 ] = static_cast< int >( id[1] );
+  // put in local id for outer/ghost tet
+  esuf[ 2*id[0]+1 ] = static_cast< int >( ghostid );
+}
+
+void
+Ghosts::addEsuel(
+  const std::array< std::size_t, 2 >& id,
+  std::size_t ghostid,
+  const tk::UnsMesh::Face& t )
+// *****************************************************************************
+// Fill elements surrounding a element along chare boundary
+//! \param[in] id Local face and (inner) tet id adjacent to it
+//! \param[in] ghostid Local ID for ghost tet
+//! \param[in] t node-triplet associated with the chare boundary face
+//! \details This function updates the elements surrounding element (esuel) data
+//    structure for the (inner) tets adjacent to the chare-boundaries. It fills
+//    esuel of this inner tet with the local tet-id that has been assigned to
+//    the outer ghost tet in Ghosts::comGhost in place of the -1 before.
+// *****************************************************************************
+{
+  const auto& lid = Disc()->Lid();
+  [[maybe_unused]] const auto& esuf = m_fd.Esuf();
+  auto& esuel = m_fd.Esuel();
+
+  std::array< tk::UnsMesh::Face, 4 > face;
+  for (std::size_t f = 0; f<4; ++f)
+    for (std::size_t i = 0; i<3; ++i)
+      face[f][i] = m_inpoel[ id[1]*4 + tk::lpofa[f][i] ];
+
+  tk::UnsMesh::Face tl{{ tk::cref_find( lid, t[0] ),
+                         tk::cref_find( lid, t[1] ),
+                         tk::cref_find( lid, t[2] ) }};
+
+  std::size_t i(0), nmatch(0);
+  for (const auto& f : face) {
+    if (tk::UnsMesh::Eq< 3 >()( tl, f )) {
+      Assert( esuel[ id[1]*4 + i ] == -1, "Incorrect boundary element found in "
+             "esuel");
+      esuel[ id[1]*4 + i ] = static_cast<int>(ghostid);
+      ++nmatch;<--- Variable 'nmatch' is assigned a value that is never used.
+      Assert( esuel[ id[1]*4 + i ] == esuf[ 2*id[0]+1 ], "Incorrect boundary "
+             "element entered in esuel" );
+      Assert( static_cast<int>(id[1]) == esuf[ 2*id[0]+0 ], "Boundary "
+             "element entered in incorrect esuel location" );
+    }
+    ++i;
+  }
+
+  // ensure that exactly one face matched
+  Assert( nmatch == 1, "Incorrect number of node-triplets (faces) matched for "
+         "updating esuel; matching faces = "+ std::to_string(nmatch) );
+}
+
+void
+Ghosts::addGeoFace(
+  const tk::UnsMesh::Face& t,
+  const std::array< std::size_t, 2 >& id )
+// *****************************************************************************
+// Fill face-geometry data along chare boundary
+//! \param[in] t Face (given by 3 global node IDs) on the chare boundary
+//! \param[in] id Local face and (inner) tet id adjacent to face t
+//! \details This function fills in the face geometry data along a chare
+//!    boundary.
+// *****************************************************************************
+{
+  const auto& lid = Disc()->Lid();
+
+  // get global node IDs reversing order to get outward-pointing normal
+  auto A = tk::cref_find( lid, t[2] );
+  auto B = tk::cref_find( lid, t[1] );
+  auto C = tk::cref_find( lid, t[0] );
+  auto geochf = tk::geoFaceTri( {{m_coord[0][A], m_coord[0][B], m_coord[0][C]}},
+                                {{m_coord[1][A], m_coord[1][B], m_coord[1][C]}},
+                                {{m_coord[2][A], m_coord[2][B], m_coord[2][C]}} );
+
+  for (std::size_t i=0; i<7; ++i)
+    m_geoFace(id[0],i) = geochf(0,i);
+}
+
+#include "NoWarning/ghosts.def.h"
 
diff --git a/Release/cppcheck/43.html b/Release/cppcheck/43.html index 15640a103c5e..f778524a2d31 100644 --- a/Release/cppcheck/43.html +++ b/Release/cppcheck/43.html @@ -152,1457 +152,4685 @@
- - + @@ -73,7 +73,7 @@ - +
  1
-  2
-  3
-  4
-  5
-  6
-  7
-  8
-  9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
- 37
- 38
- 39
- 40
- 41
- 42
- 43
- 44
- 45
- 46
- 47
- 48
- 49
- 50
- 51
- 52
- 53
- 54
- 55
- 56
- 57
- 58
- 59
- 60
- 61
- 62
- 63
- 64
- 65
- 66
- 67
- 68
- 69
- 70
- 71
- 72
- 73
- 74
- 75
- 76
- 77
- 78
- 79
- 80
- 81
- 82
- 83
- 84
- 85
- 86
- 87
- 88
- 89
- 90
- 91
- 92
- 93
- 94
- 95
- 96
- 97
- 98
- 99
-100
-101
-102
-103
-104
-105
-106
-107
-108
-109
-110
-111
-112
-113
-114
-115
-116
-117
-118
-119
-120
-121
-122
-123
-124
-125
-126
-127
-128
-129
-130
-131
-132
-133
-134
-135
-136
-137
-138
-139
-140
-141
-142
-143
-144
-145
-146
-147
-148
-149
-150
-151
-152
-153
-154
-155
-156
-157
-158
-159
-160
-161
-162
-163
-164
-165
-166
-167
-168
-169
-170
-171
-172
-173
-174
-175
-176
-177
-178
-179
-180
-181
-182
-183
-184
-185
-186
-187
-188
-189
-190
-191
-192
-193
-194
-195
-196
-197
-198
-199
-200
-201
-202
-203
-204
-205
-206
-207
-208
-209
-210
-211
-212
-213
-214
-215
-216
-217
-218
-219
-220
-221
-222
-223
-224
-225
-226
-227
-228
-229
-230
-231
-232
-233
-234
-235
-236
-237
-238
-239
-240
-241
-242
-243
-244
-245
-246
-247
-248
-249
-250
-251
-252
-253
-254
-255
-256
-257
-258
-259
-260
-261
-262
-263
-264
-265
-266
-267
-268
-269
-270
-271
-272
-273
-274
-275
-276
-277
-278
-279
-280
-281
-282
-283
-284
-285
-286
-287
-288
-289
-290
-291
-292
-293
-294
-295
-296
-297
-298
-299
-300
-301
-302
-303
-304
-305
-306
-307
-308
-309
-310
-311
-312
-313
-314
-315
-316
-317
-318
-319
-320
-321
-322
-323
-324
-325
-326
-327
-328
-329
-330
-331
-332
-333
-334
-335
-336
-337
-338
-339
-340
-341
-342
-343
-344
-345
-346
-347
-348
-349
-350
-351
-352
-353
-354
-355
-356
-357
-358
-359
-360
-361
-362
-363
-364
-365
-366
-367
-368
-369
-370
-371
-372
-373
-374
-375
-376
-377
-378
-379
-380
-381
-382
-383
-384
-385
-386
-387
-388
-389
-390
-391
-392
-393
-394
-395
-396
-397
-398
-399
-400
-401
-402
-403
-404
-405
-406
-407
-408
-409
-410
-411
-412
-413
-414
-415
-416
-417
-418
-419
-420
-421
-422
-423
-424
-425
-426
-427
-428
-429
-430
-431
-432
-433
-434
-435
-436
-437
-438
-439
-440
-441
-442
-443
-444
-445
-446
-447
-448
-449
-450
-451
-452
-453
-454
-455
-456
-457
-458
-459
-460
-461
-462
-463
-464
-465
-466
-467
-468
-469
-470
-471
-472
-473
-474
-475
-476
-477
-478
-479
-480
-481
-482
-483
-484
-485
-486
-487
-488
-489
-490
-491
-492
-493
-494
-495
-496
-497
-498
-499
-500
-501
-502
-503
-504
-505
-506
-507
-508
-509
-510
-511
-512
-513
-514
-515
-516
-517
-518
-519
-520
-521
-522
-523
-524
-525
-526
-527
-528
-529
-530
-531
-532
-533
-534
-535
-536
-537
-538
-539
-540
-541
-542
-543
-544
-545
-546
-547
-548
-549
-550
-551
-552
-553
-554
-555
-556
-557
-558
-559
-560
-561
-562
-563
-564
-565
-566
-567
-568
-569
-570
-571
-572
-573
-574
-575
-576
-577
-578
-579
-580
-581
-582
-583
-584
-585
-586
-587
-588
-589
-590
-591
-592
-593
-594
-595
-596
-597
-598
-599
-600
-601
-602
-603
-604
-605
-606
-607
-608
-609
-610
-611
-612
-613
-614
-615
-616
-617
-618
-619
-620
-621
-622
-623
-624
-625
-626
-627
-628
-629
-630
-631
-632
-633
-634
-635
-636
-637
-638
-639
-640
-641
-642
-643
-644
-645
-646
-647
-648
-649
-650
-651
-652
-653
-654
-655
-656
-657
-658
-659
-660
-661
-662
-663
-664
-665
-666
-667
-668
-669
-670
-671
-672
-673
-674
-675
-676
-677
-678
-679
-680
-681
-682
-683
-684
-685
-686
-687
-688
-689
-690
-691
-692
-693
-694
-695
-696
-697
-698
-699
-700
-701
-702
-703
-704
-705
-706
-707
-708
-709
-710
-711
-712
-713
-714
-715
-716
-717
-718
-719
-720
-721
-722
// *****************************************************************************
+
   1
+   2
+   3
+   4
+   5
+   6
+   7
+   8
+   9
+  10
+  11
+  12
+  13
+  14
+  15
+  16
+  17
+  18
+  19
+  20
+  21
+  22
+  23
+  24
+  25
+  26
+  27
+  28
+  29
+  30
+  31
+  32
+  33
+  34
+  35
+  36
+  37
+  38
+  39
+  40
+  41
+  42
+  43
+  44
+  45
+  46
+  47
+  48
+  49
+  50
+  51
+  52
+  53
+  54
+  55
+  56
+  57
+  58
+  59
+  60
+  61
+  62
+  63
+  64
+  65
+  66
+  67
+  68
+  69
+  70
+  71
+  72
+  73
+  74
+  75
+  76
+  77
+  78
+  79
+  80
+  81
+  82
+  83
+  84
+  85
+  86
+  87
+  88
+  89
+  90
+  91
+  92
+  93
+  94
+  95
+  96
+  97
+  98
+  99
+ 100
+ 101
+ 102
+ 103
+ 104
+ 105
+ 106
+ 107
+ 108
+ 109
+ 110
+ 111
+ 112
+ 113
+ 114
+ 115
+ 116
+ 117
+ 118
+ 119
+ 120
+ 121
+ 122
+ 123
+ 124
+ 125
+ 126
+ 127
+ 128
+ 129
+ 130
+ 131
+ 132
+ 133
+ 134
+ 135
+ 136
+ 137
+ 138
+ 139
+ 140
+ 141
+ 142
+ 143
+ 144
+ 145
+ 146
+ 147
+ 148
+ 149
+ 150
+ 151
+ 152
+ 153
+ 154
+ 155
+ 156
+ 157
+ 158
+ 159
+ 160
+ 161
+ 162
+ 163
+ 164
+ 165
+ 166
+ 167
+ 168
+ 169
+ 170
+ 171
+ 172
+ 173
+ 174
+ 175
+ 176
+ 177
+ 178
+ 179
+ 180
+ 181
+ 182
+ 183
+ 184
+ 185
+ 186
+ 187
+ 188
+ 189
+ 190
+ 191
+ 192
+ 193
+ 194
+ 195
+ 196
+ 197
+ 198
+ 199
+ 200
+ 201
+ 202
+ 203
+ 204
+ 205
+ 206
+ 207
+ 208
+ 209
+ 210
+ 211
+ 212
+ 213
+ 214
+ 215
+ 216
+ 217
+ 218
+ 219
+ 220
+ 221
+ 222
+ 223
+ 224
+ 225
+ 226
+ 227
+ 228
+ 229
+ 230
+ 231
+ 232
+ 233
+ 234
+ 235
+ 236
+ 237
+ 238
+ 239
+ 240
+ 241
+ 242
+ 243
+ 244
+ 245
+ 246
+ 247
+ 248
+ 249
+ 250
+ 251
+ 252
+ 253
+ 254
+ 255
+ 256
+ 257
+ 258
+ 259
+ 260
+ 261
+ 262
+ 263
+ 264
+ 265
+ 266
+ 267
+ 268
+ 269
+ 270
+ 271
+ 272
+ 273
+ 274
+ 275
+ 276
+ 277
+ 278
+ 279
+ 280
+ 281
+ 282
+ 283
+ 284
+ 285
+ 286
+ 287
+ 288
+ 289
+ 290
+ 291
+ 292
+ 293
+ 294
+ 295
+ 296
+ 297
+ 298
+ 299
+ 300
+ 301
+ 302
+ 303
+ 304
+ 305
+ 306
+ 307
+ 308
+ 309
+ 310
+ 311
+ 312
+ 313
+ 314
+ 315
+ 316
+ 317
+ 318
+ 319
+ 320
+ 321
+ 322
+ 323
+ 324
+ 325
+ 326
+ 327
+ 328
+ 329
+ 330
+ 331
+ 332
+ 333
+ 334
+ 335
+ 336
+ 337
+ 338
+ 339
+ 340
+ 341
+ 342
+ 343
+ 344
+ 345
+ 346
+ 347
+ 348
+ 349
+ 350
+ 351
+ 352
+ 353
+ 354
+ 355
+ 356
+ 357
+ 358
+ 359
+ 360
+ 361
+ 362
+ 363
+ 364
+ 365
+ 366
+ 367
+ 368
+ 369
+ 370
+ 371
+ 372
+ 373
+ 374
+ 375
+ 376
+ 377
+ 378
+ 379
+ 380
+ 381
+ 382
+ 383
+ 384
+ 385
+ 386
+ 387
+ 388
+ 389
+ 390
+ 391
+ 392
+ 393
+ 394
+ 395
+ 396
+ 397
+ 398
+ 399
+ 400
+ 401
+ 402
+ 403
+ 404
+ 405
+ 406
+ 407
+ 408
+ 409
+ 410
+ 411
+ 412
+ 413
+ 414
+ 415
+ 416
+ 417
+ 418
+ 419
+ 420
+ 421
+ 422
+ 423
+ 424
+ 425
+ 426
+ 427
+ 428
+ 429
+ 430
+ 431
+ 432
+ 433
+ 434
+ 435
+ 436
+ 437
+ 438
+ 439
+ 440
+ 441
+ 442
+ 443
+ 444
+ 445
+ 446
+ 447
+ 448
+ 449
+ 450
+ 451
+ 452
+ 453
+ 454
+ 455
+ 456
+ 457
+ 458
+ 459
+ 460
+ 461
+ 462
+ 463
+ 464
+ 465
+ 466
+ 467
+ 468
+ 469
+ 470
+ 471
+ 472
+ 473
+ 474
+ 475
+ 476
+ 477
+ 478
+ 479
+ 480
+ 481
+ 482
+ 483
+ 484
+ 485
+ 486
+ 487
+ 488
+ 489
+ 490
+ 491
+ 492
+ 493
+ 494
+ 495
+ 496
+ 497
+ 498
+ 499
+ 500
+ 501
+ 502
+ 503
+ 504
+ 505
+ 506
+ 507
+ 508
+ 509
+ 510
+ 511
+ 512
+ 513
+ 514
+ 515
+ 516
+ 517
+ 518
+ 519
+ 520
+ 521
+ 522
+ 523
+ 524
+ 525
+ 526
+ 527
+ 528
+ 529
+ 530
+ 531
+ 532
+ 533
+ 534
+ 535
+ 536
+ 537
+ 538
+ 539
+ 540
+ 541
+ 542
+ 543
+ 544
+ 545
+ 546
+ 547
+ 548
+ 549
+ 550
+ 551
+ 552
+ 553
+ 554
+ 555
+ 556
+ 557
+ 558
+ 559
+ 560
+ 561
+ 562
+ 563
+ 564
+ 565
+ 566
+ 567
+ 568
+ 569
+ 570
+ 571
+ 572
+ 573
+ 574
+ 575
+ 576
+ 577
+ 578
+ 579
+ 580
+ 581
+ 582
+ 583
+ 584
+ 585
+ 586
+ 587
+ 588
+ 589
+ 590
+ 591
+ 592
+ 593
+ 594
+ 595
+ 596
+ 597
+ 598
+ 599
+ 600
+ 601
+ 602
+ 603
+ 604
+ 605
+ 606
+ 607
+ 608
+ 609
+ 610
+ 611
+ 612
+ 613
+ 614
+ 615
+ 616
+ 617
+ 618
+ 619
+ 620
+ 621
+ 622
+ 623
+ 624
+ 625
+ 626
+ 627
+ 628
+ 629
+ 630
+ 631
+ 632
+ 633
+ 634
+ 635
+ 636
+ 637
+ 638
+ 639
+ 640
+ 641
+ 642
+ 643
+ 644
+ 645
+ 646
+ 647
+ 648
+ 649
+ 650
+ 651
+ 652
+ 653
+ 654
+ 655
+ 656
+ 657
+ 658
+ 659
+ 660
+ 661
+ 662
+ 663
+ 664
+ 665
+ 666
+ 667
+ 668
+ 669
+ 670
+ 671
+ 672
+ 673
+ 674
+ 675
+ 676
+ 677
+ 678
+ 679
+ 680
+ 681
+ 682
+ 683
+ 684
+ 685
+ 686
+ 687
+ 688
+ 689
+ 690
+ 691
+ 692
+ 693
+ 694
+ 695
+ 696
+ 697
+ 698
+ 699
+ 700
+ 701
+ 702
+ 703
+ 704
+ 705
+ 706
+ 707
+ 708
+ 709
+ 710
+ 711
+ 712
+ 713
+ 714
+ 715
+ 716
+ 717
+ 718
+ 719
+ 720
+ 721
+ 722
+ 723
+ 724
+ 725
+ 726
+ 727
+ 728
+ 729
+ 730
+ 731
+ 732
+ 733
+ 734
+ 735
+ 736
+ 737
+ 738
+ 739
+ 740
+ 741
+ 742
+ 743
+ 744
+ 745
+ 746
+ 747
+ 748
+ 749
+ 750
+ 751
+ 752
+ 753
+ 754
+ 755
+ 756
+ 757
+ 758
+ 759
+ 760
+ 761
+ 762
+ 763
+ 764
+ 765
+ 766
+ 767
+ 768
+ 769
+ 770
+ 771
+ 772
+ 773
+ 774
+ 775
+ 776
+ 777
+ 778
+ 779
+ 780
+ 781
+ 782
+ 783
+ 784
+ 785
+ 786
+ 787
+ 788
+ 789
+ 790
+ 791
+ 792
+ 793
+ 794
+ 795
+ 796
+ 797
+ 798
+ 799
+ 800
+ 801
+ 802
+ 803
+ 804
+ 805
+ 806
+ 807
+ 808
+ 809
+ 810
+ 811
+ 812
+ 813
+ 814
+ 815
+ 816
+ 817
+ 818
+ 819
+ 820
+ 821
+ 822
+ 823
+ 824
+ 825
+ 826
+ 827
+ 828
+ 829
+ 830
+ 831
+ 832
+ 833
+ 834
+ 835
+ 836
+ 837
+ 838
+ 839
+ 840
+ 841
+ 842
+ 843
+ 844
+ 845
+ 846
+ 847
+ 848
+ 849
+ 850
+ 851
+ 852
+ 853
+ 854
+ 855
+ 856
+ 857
+ 858
+ 859
+ 860
+ 861
+ 862
+ 863
+ 864
+ 865
+ 866
+ 867
+ 868
+ 869
+ 870
+ 871
+ 872
+ 873
+ 874
+ 875
+ 876
+ 877
+ 878
+ 879
+ 880
+ 881
+ 882
+ 883
+ 884
+ 885
+ 886
+ 887
+ 888
+ 889
+ 890
+ 891
+ 892
+ 893
+ 894
+ 895
+ 896
+ 897
+ 898
+ 899
+ 900
+ 901
+ 902
+ 903
+ 904
+ 905
+ 906
+ 907
+ 908
+ 909
+ 910
+ 911
+ 912
+ 913
+ 914
+ 915
+ 916
+ 917
+ 918
+ 919
+ 920
+ 921
+ 922
+ 923
+ 924
+ 925
+ 926
+ 927
+ 928
+ 929
+ 930
+ 931
+ 932
+ 933
+ 934
+ 935
+ 936
+ 937
+ 938
+ 939
+ 940
+ 941
+ 942
+ 943
+ 944
+ 945
+ 946
+ 947
+ 948
+ 949
+ 950
+ 951
+ 952
+ 953
+ 954
+ 955
+ 956
+ 957
+ 958
+ 959
+ 960
+ 961
+ 962
+ 963
+ 964
+ 965
+ 966
+ 967
+ 968
+ 969
+ 970
+ 971
+ 972
+ 973
+ 974
+ 975
+ 976
+ 977
+ 978
+ 979
+ 980
+ 981
+ 982
+ 983
+ 984
+ 985
+ 986
+ 987
+ 988
+ 989
+ 990
+ 991
+ 992
+ 993
+ 994
+ 995
+ 996
+ 997
+ 998
+ 999
+1000
+1001
+1002
+1003
+1004
+1005
+1006
+1007
+1008
+1009
+1010
+1011
+1012
+1013
+1014
+1015
+1016
+1017
+1018
+1019
+1020
+1021
+1022
+1023
+1024
+1025
+1026
+1027
+1028
+1029
+1030
+1031
+1032
+1033
+1034
+1035
+1036
+1037
+1038
+1039
+1040
+1041
+1042
+1043
+1044
+1045
+1046
+1047
+1048
+1049
+1050
+1051
+1052
+1053
+1054
+1055
+1056
+1057
+1058
+1059
+1060
+1061
+1062
+1063
+1064
+1065
+1066
+1067
+1068
+1069
+1070
+1071
+1072
+1073
+1074
+1075
+1076
+1077
+1078
+1079
+1080
+1081
+1082
+1083
+1084
+1085
+1086
+1087
+1088
+1089
+1090
+1091
+1092
+1093
+1094
+1095
+1096
+1097
+1098
+1099
+1100
+1101
+1102
+1103
+1104
+1105
+1106
+1107
+1108
+1109
+1110
+1111
+1112
+1113
+1114
+1115
+1116
+1117
+1118
+1119
+1120
+1121
+1122
+1123
+1124
+1125
+1126
+1127
+1128
+1129
+1130
+1131
+1132
+1133
+1134
+1135
+1136
+1137
+1138
+1139
+1140
+1141
+1142
+1143
+1144
+1145
+1146
+1147
+1148
+1149
+1150
+1151
+1152
+1153
+1154
+1155
+1156
+1157
+1158
+1159
+1160
+1161
+1162
+1163
+1164
+1165
+1166
+1167
+1168
+1169
+1170
+1171
+1172
+1173
+1174
+1175
+1176
+1177
+1178
+1179
+1180
+1181
+1182
+1183
+1184
+1185
+1186
+1187
+1188
+1189
+1190
+1191
+1192
+1193
+1194
+1195
+1196
+1197
+1198
+1199
+1200
+1201
+1202
+1203
+1204
+1205
+1206
+1207
+1208
+1209
+1210
+1211
+1212
+1213
+1214
+1215
+1216
+1217
+1218
+1219
+1220
+1221
+1222
+1223
+1224
+1225
+1226
+1227
+1228
+1229
+1230
+1231
+1232
+1233
+1234
+1235
+1236
+1237
+1238
+1239
+1240
+1241
+1242
+1243
+1244
+1245
+1246
+1247
+1248
+1249
+1250
+1251
+1252
+1253
+1254
+1255
+1256
+1257
+1258
+1259
+1260
+1261
+1262
+1263
+1264
+1265
+1266
+1267
+1268
+1269
+1270
+1271
+1272
+1273
+1274
+1275
+1276
+1277
+1278
+1279
+1280
+1281
+1282
+1283
+1284
+1285
+1286
+1287
+1288
+1289
+1290
+1291
+1292
+1293
+1294
+1295
+1296
+1297
+1298
+1299
+1300
+1301
+1302
+1303
+1304
+1305
+1306
+1307
+1308
+1309
+1310
+1311
+1312
+1313
+1314
+1315
+1316
+1317
+1318
+1319
+1320
+1321
+1322
+1323
+1324
+1325
+1326
+1327
+1328
+1329
+1330
+1331
+1332
+1333
+1334
+1335
+1336
+1337
+1338
+1339
+1340
+1341
+1342
+1343
+1344
+1345
+1346
+1347
+1348
+1349
+1350
+1351
+1352
+1353
+1354
+1355
+1356
+1357
+1358
+1359
+1360
+1361
+1362
+1363
+1364
+1365
+1366
+1367
+1368
+1369
+1370
+1371
+1372
+1373
+1374
+1375
+1376
+1377
+1378
+1379
+1380
+1381
+1382
+1383
+1384
+1385
+1386
+1387
+1388
+1389
+1390
+1391
+1392
+1393
+1394
+1395
+1396
+1397
+1398
+1399
+1400
+1401
+1402
+1403
+1404
+1405
+1406
+1407
+1408
+1409
+1410
+1411
+1412
+1413
+1414
+1415
+1416
+1417
+1418
+1419
+1420
+1421
+1422
+1423
+1424
+1425
+1426
+1427
+1428
+1429
+1430
+1431
+1432
+1433
+1434
+1435
+1436
+1437
+1438
+1439
+1440
+1441
+1442
+1443
+1444
+1445
+1446
+1447
+1448
+1449
+1450
+1451
+1452
+1453
+1454
+1455
+1456
+1457
+1458
+1459
+1460
+1461
+1462
+1463
+1464
+1465
+1466
+1467
+1468
+1469
+1470
+1471
+1472
+1473
+1474
+1475
+1476
+1477
+1478
+1479
+1480
+1481
+1482
+1483
+1484
+1485
+1486
+1487
+1488
+1489
+1490
+1491
+1492
+1493
+1494
+1495
+1496
+1497
+1498
+1499
+1500
+1501
+1502
+1503
+1504
+1505
+1506
+1507
+1508
+1509
+1510
+1511
+1512
+1513
+1514
+1515
+1516
+1517
+1518
+1519
+1520
+1521
+1522
+1523
+1524
+1525
+1526
+1527
+1528
+1529
+1530
+1531
+1532
+1533
+1534
+1535
+1536
+1537
+1538
+1539
+1540
+1541
+1542
+1543
+1544
+1545
+1546
+1547
+1548
+1549
+1550
+1551
+1552
+1553
+1554
+1555
+1556
+1557
+1558
+1559
+1560
+1561
+1562
+1563
+1564
+1565
+1566
+1567
+1568
+1569
+1570
+1571
+1572
+1573
+1574
+1575
+1576
+1577
+1578
+1579
+1580
+1581
+1582
+1583
+1584
+1585
+1586
+1587
+1588
+1589
+1590
+1591
+1592
+1593
+1594
+1595
+1596
+1597
+1598
+1599
+1600
+1601
+1602
+1603
+1604
+1605
+1606
+1607
+1608
+1609
+1610
+1611
+1612
+1613
+1614
+1615
+1616
+1617
+1618
+1619
+1620
+1621
+1622
+1623
+1624
+1625
+1626
+1627
+1628
+1629
+1630
+1631
+1632
+1633
+1634
+1635
+1636
+1637
+1638
+1639
+1640
+1641
+1642
+1643
+1644
+1645
+1646
+1647
+1648
+1649
+1650
+1651
+1652
+1653
+1654
+1655
+1656
+1657
+1658
+1659
+1660
+1661
+1662
+1663
+1664
+1665
+1666
+1667
+1668
+1669
+1670
+1671
+1672
+1673
+1674
+1675
+1676
+1677
+1678
+1679
+1680
+1681
+1682
+1683
+1684
+1685
+1686
+1687
+1688
+1689
+1690
+1691
+1692
+1693
+1694
+1695
+1696
+1697
+1698
+1699
+1700
+1701
+1702
+1703
+1704
+1705
+1706
+1707
+1708
+1709
+1710
+1711
+1712
+1713
+1714
+1715
+1716
+1717
+1718
+1719
+1720
+1721
+1722
+1723
+1724
+1725
+1726
+1727
+1728
+1729
+1730
+1731
+1732
+1733
+1734
+1735
+1736
+1737
+1738
+1739
+1740
+1741
+1742
+1743
+1744
+1745
+1746
+1747
+1748
+1749
+1750
+1751
+1752
+1753
+1754
+1755
+1756
+1757
+1758
+1759
+1760
+1761
+1762
+1763
+1764
+1765
+1766
+1767
+1768
+1769
+1770
+1771
+1772
+1773
+1774
+1775
+1776
+1777
+1778
+1779
+1780
+1781
+1782
+1783
+1784
+1785
+1786
+1787
+1788
+1789
+1790
+1791
+1792
+1793
+1794
+1795
+1796
+1797
+1798
+1799
+1800
+1801
+1802
+1803
+1804
+1805
+1806
+1807
+1808
+1809
+1810
+1811
+1812
+1813
+1814
+1815
+1816
+1817
+1818
+1819
+1820
+1821
+1822
+1823
+1824
+1825
+1826
+1827
+1828
+1829
+1830
+1831
+1832
+1833
+1834
+1835
+1836
+1837
+1838
+1839
+1840
+1841
+1842
+1843
+1844
+1845
+1846
+1847
+1848
+1849
+1850
+1851
+1852
+1853
+1854
+1855
+1856
+1857
+1858
+1859
+1860
+1861
+1862
+1863
+1864
+1865
+1866
+1867
+1868
+1869
+1870
+1871
+1872
+1873
+1874
+1875
+1876
+1877
+1878
+1879
+1880
+1881
+1882
+1883
+1884
+1885
+1886
+1887
+1888
+1889
+1890
+1891
+1892
+1893
+1894
+1895
+1896
+1897
+1898
+1899
+1900
+1901
+1902
+1903
+1904
+1905
+1906
+1907
+1908
+1909
+1910
+1911
+1912
+1913
+1914
+1915
+1916
+1917
+1918
+1919
+1920
+1921
+1922
+1923
+1924
+1925
+1926
+1927
+1928
+1929
+1930
+1931
+1932
+1933
+1934
+1935
+1936
+1937
+1938
+1939
+1940
+1941
+1942
+1943
+1944
+1945
+1946
+1947
+1948
+1949
+1950
+1951
+1952
+1953
+1954
+1955
+1956
+1957
+1958
+1959
+1960
+1961
+1962
+1963
+1964
+1965
+1966
+1967
+1968
+1969
+1970
+1971
+1972
+1973
+1974
+1975
+1976
+1977
+1978
+1979
+1980
+1981
+1982
+1983
+1984
+1985
+1986
+1987
+1988
+1989
+1990
+1991
+1992
+1993
+1994
+1995
+1996
+1997
+1998
+1999
+2000
+2001
+2002
+2003
+2004
+2005
+2006
+2007
+2008
+2009
+2010
+2011
+2012
+2013
+2014
+2015
+2016
+2017
+2018
+2019
+2020
+2021
+2022
+2023
+2024
+2025
+2026
+2027
+2028
+2029
+2030
+2031
+2032
+2033
+2034
+2035
+2036
+2037
+2038
+2039
+2040
+2041
+2042
+2043
+2044
+2045
+2046
+2047
+2048
+2049
+2050
+2051
+2052
+2053
+2054
+2055
+2056
+2057
+2058
+2059
+2060
+2061
+2062
+2063
+2064
+2065
+2066
+2067
+2068
+2069
+2070
+2071
+2072
+2073
+2074
+2075
+2076
+2077
+2078
+2079
+2080
+2081
+2082
+2083
+2084
+2085
+2086
+2087
+2088
+2089
+2090
+2091
+2092
+2093
+2094
+2095
+2096
+2097
+2098
+2099
+2100
+2101
+2102
+2103
+2104
+2105
+2106
+2107
+2108
+2109
+2110
+2111
+2112
+2113
+2114
+2115
+2116
+2117
+2118
+2119
+2120
+2121
+2122
+2123
+2124
+2125
+2126
+2127
+2128
+2129
+2130
+2131
+2132
+2133
+2134
+2135
+2136
+2137
+2138
+2139
+2140
+2141
+2142
+2143
+2144
+2145
+2146
+2147
+2148
+2149
+2150
+2151
+2152
+2153
+2154
+2155
+2156
+2157
+2158
+2159
+2160
+2161
+2162
+2163
+2164
+2165
+2166
+2167
+2168
+2169
+2170
+2171
+2172
+2173
+2174
+2175
+2176
+2177
+2178
+2179
+2180
+2181
+2182
+2183
+2184
+2185
+2186
+2187
+2188
+2189
+2190
+2191
+2192
+2193
+2194
+2195
+2196
+2197
+2198
+2199
+2200
+2201
+2202
+2203
+2204
+2205
+2206
+2207
+2208
+2209
+2210
+2211
+2212
+2213
+2214
+2215
+2216
+2217
+2218
+2219
+2220
+2221
+2222
+2223
+2224
+2225
+2226
+2227
+2228
+2229
+2230
+2231
+2232
+2233
+2234
+2235
+2236
+2237
+2238
+2239
+2240
+2241
+2242
+2243
+2244
+2245
+2246
+2247
+2248
+2249
+2250
+2251
+2252
+2253
+2254
+2255
+2256
+2257
+2258
+2259
+2260
+2261
+2262
+2263
+2264
+2265
+2266
+2267
+2268
+2269
+2270
+2271
+2272
+2273
+2274
+2275
+2276
+2277
+2278
+2279
+2280
+2281
+2282
+2283
+2284
+2285
+2286
+2287
+2288
+2289
+2290
+2291
+2292
+2293
+2294
+2295
+2296
+2297
+2298
+2299
+2300
+2301
+2302
+2303
+2304
+2305
+2306
+2307
+2308
+2309
+2310
+2311
+2312
+2313
+2314
+2315
+2316
+2317
+2318
+2319
+2320
+2321
+2322
+2323
+2324
+2325
+2326
+2327
+2328
+2329
+2330
+2331
+2332
+2333
+2334
+2335
+2336
// *****************************************************************************
 /*!
-  \file      src/PDE/DGPDE.hpp
+  \file      src/Inciter/DG.cpp
   \copyright 2012-2015 J. Bakosi,
              2016-2018 Los Alamos National Security, LLC.,
              2019-2021 Triad National Security, LLC.
              All rights reserved. See the LICENSE file for details.
-  \brief     Partial differential equation base for discontinuous Galerkin PDEs
-  \details   This file defines a generic partial differential equation (PDE)
-    class for PDEs that use discontinuous Galerkin spatial discretization.
-    The class uses runtime polymorphism without client-side inheritance:
-    inheritance is confined to the internals of the class, invisible to
-    client-code. The class exclusively deals with ownership enabling client-side
-    value semantics. Credit goes to Sean Parent at Adobe:
-    https://github.com/sean-parent/sean-parent.github.com/wiki/
-    Papers-and-Presentations.
-*/
-// *****************************************************************************
-#ifndef DGPDE_h
-#define DGPDE_h
-
-#include <array>
-#include <string>
-#include <vector>
-#include <memory>
-#include <unordered_set>
-#include <functional>
-
-#include "Types.hpp"
-#include "Fields.hpp"
-#include "FaceData.hpp"
-#include "UnsMesh.hpp"
-#include "Inciter/InputDeck/InputDeck.hpp"
-#include "FunctionPrototypes.hpp"
-#include "History.hpp"
+  \brief     DG advances a system of PDEs with the discontinuous Galerkin scheme
+  \details   DG advances a system of partial differential equations (PDEs) using
+    discontinuous Galerkin (DG) finite element (FE) spatial discretization (on
+    tetrahedron elements) combined with Runge-Kutta (RK) time stepping.
+  \see The documentation in DG.h.
+*/
+// *****************************************************************************
+
+#include <algorithm>
+#include <numeric>
+#include <sstream>
+
+#include "DG.hpp"
+#include "Discretization.hpp"
+#include "DGPDE.hpp"
+#include "DiagReducer.hpp"
+#include "DerivedData.hpp"
+#include "ElemDiagnostics.hpp"
+#include "Inciter/InputDeck/InputDeck.hpp"
+#include "Refiner.hpp"
+#include "Limiter.hpp"
+#include "Reorder.hpp"
+#include "Vector.hpp"
+#include "Around.hpp"
+#include "Integrate/Basis.hpp"
+#include "FieldOutput.hpp"
+#include "ChareStateCollector.hpp"
+#include "PDE/MultiMat/MultiMatIndexing.hpp"
 
 namespace inciter {
 
 extern ctr::InputDeck g_inputdeck;
-
-using ncomp_t = tk::ncomp_t;
-using BCStateFn =
-  std::vector< std::pair< std::vector< std::size_t >, tk::StateFn > >;
-
-//! Extract BC configuration ignoring if BC not specified
-//! \note A more preferable way of catching errors such as this function
-//!   hides is during parsing, so that we don't even get here if BCs are
-//!   not correctly specified. For now we simply ignore if BCs are not
-//!   specified by allowing empty BC vectors from the user input.
-struct ConfigBC {
-  BCStateFn& state;    //!< BC state config: sidesets + statefn
-  const std::vector< tk::StateFn >& fn;    //!< BC state functions
-  std::size_t c;       //!< Counts BC types configured
-  //! Constructor
-  ConfigBC( BCStateFn& s,
-            const std::vector< tk::StateFn >& f ) :
-    state(s), fn(f), c(0) {}
-  //! Function to call for each BC type
-  template< typename U > void operator()( brigand::type_<U> ) {
-    std::vector< std::size_t > cfg, v;
-    // collect sidesets across all meshes
-    for (const auto& ibc : g_inputdeck.get< tag::bc >()) {
-      v.insert(v.end(), ibc.get< U >().begin(), ibc.get< U >().end());
-    }
-    if (v.size() > 0) cfg = v;<--- Variable 'cfg' is assigned a value that is never used.
-    Assert( fn.size() > c, "StateFn missing for BC type" );
-    state.push_back( { cfg, fn[c++] } );
-  }
-};
+extern std::vector< DGPDE > g_dgpde;
+
+//! Runge-Kutta coefficients
+static const std::array< std::array< tk::real, 3 >, 2 >
+  rkcoef{{ {{ 0.0, 3.0/4.0, 1.0/3.0 }}, {{ 1.0, 1.0/4.0, 2.0/3.0 }} }};
+
+//! Implicit-Explicit Runge-Kutta Coefficients
+static const tk::real rk_gamma = (2.0-std::sqrt(2.0))/2.0;
+static const tk::real rk_delta = -2.0*std::sqrt(2.0)/3.0;
+static const tk::real c2 =
+  (27.0 + std::pow(2187.0-1458.0*std::sqrt(2.0),1.0/3.0)
+   + 9.0*std::pow(3.0+2.0*std::sqrt(2.0),1.0/3.0))/54.0;
+static const tk::real c3 = c2/(6.0*std::pow(c2,2.0)-3.0*c2+1.0);
+static const tk::real b2 = (3.0*c2-1.0)/(6.0*std::pow(c2,2.0));
+static const tk::real b3 =
+  (6.0*std::pow(c2,2.0)-3.0*c2+1.0)/(6.0*std::pow(c2,2.0));
+static const tk::real a22_impl = c2;
+static const tk::real a21_expl = c2;
+static const tk::real a32_expl = c3;
+static const tk::real a33_impl =
+  (1.0/6.0-b2*std::pow(c2,2.0)-b3*c2*c3)/(b3*(c3-c2));
+static const tk::real a32_impl = a33_impl-c3;
+static const std::array< std::array< tk::real, 3 >, 2 >
+  expl_rkcoef{{ {{ 0.0, 0.0, b2 }},
+                {{ a21_expl, a32_expl, b3 }} }};
+static const std::array< std::array< tk::real, 3 >, 2>
+  impl_rkcoef{{ {{ 0.0, a32_impl, b2 }},
+                {{ a22_impl, a33_impl, b3}} }};
+
+} // inciter::
 
-//! State function for invalid/un-configured boundary conditions
-[[noreturn]] tk::StateFn::result_type
-invalidBC( ncomp_t, const std::vector< EOS >&,
-           const std::vector< tk::real >&, tk::real, tk::real, tk::real,
-           tk::real, const std::array< tk::real, 3> & );
-
-//! \brief Partial differential equation base for discontinuous Galerkin PDEs
-//! \details This class uses runtime polymorphism without client-side
-//!   inheritance: inheritance is confined to the internals of the this class,
-//!   invisible to client-code. The class exclusively deals with ownership
-//!   enabling client-side value semantics. Credit goes to Sean Parent at Adobe:
-//!   https://github.com/sean-parent/sean-parent.github.com/wiki/
-//!   Papers-and-Presentations. For example client code that models a DGPDE,
-//!   see inciter::CompFlow.
-class DGPDE {
-
-  private:
-    using ncomp_t = tk::ncomp_t;
-
-  public:
-    //! Default constructor taking no arguments for Charm++
-    explicit DGPDE() = default;
-
-    //! \brief Constructor taking an object modeling Concept.
-    //! \details The object of class T comes pre-constructed.
-    //! \param[in] x Instantiated object of type T given by the template
-    //!   argument.
-    template< typename T > explicit DGPDE( T x ) :
-      self( std::make_unique< Model<T> >( std::move(x) ) ) {}
-
-    //! \brief Constructor taking a function pointer to a constructor of an
-    //!   object modeling Concept.
-    //! \details Passing std::function allows late execution of the constructor,
-    //!   i.e., as late as inside this class' constructor, and thus usage from
-    //!   a factory. Note that there are at least two different ways of using
-    //!   this constructor:
-    //!   - Bind T's constructor arguments and place it in std::function<T()>
-    //!   and passing no arguments as args.... This case then instantiates the
-    //!   model via its constructor and stores it in here.
-    //!   - Bind a single placeholder argument to T's constructor and pass it in
-    //!   as host's args..., which then forwards it to model's constructor. This
-    //!   allows late binding, i.e., binding the argument only here.
-    //! \see See also the wrapper tk::recordModel() which does the former and
-    //!   tk::recordModelLate() which does the latter, both defined in
-    //!   src/Base/Factory.h.
-    //! \param[in] x Function pointer to a constructor of an object modeling
-    //!    Concept.
-    //! \param[in] args Zero or more constructor arguments
-    template< typename T, typename...Args >
-    explicit DGPDE( std::function<T(Args...)> x, Args&&... args ) :
-      self( std::make_unique< Model<T> >(
-              std::move( x( std::forward<Args>(args)... ) ) ) ) {}
-
-    //! Public interface to find number of primitive quantities for the diff eq
-    std::size_t nprim() const
-    { return self->nprim(); }
-
-    //! Public interface to find number of materials for the diff eq
-    std::size_t nmat() const
-    { return self->nmat(); }
-
-    //! Public interface to find Dofs for each equation in pde system
-    void numEquationDofs(std::vector< std::size_t >& numEqDof) const
-    { return self->numEquationDofs(numEqDof); }
-
-    //! Public interface to find how 'stiff equations', which are the inverse
-    //! deformation equations because of plasticity
-    std::size_t nstiffeq() const
-    { return self->nstiffeq(); }
-
-    //! Public interface to find how 'nonstiff equations', which are the inverse
-    //! deformation equations because of plasticity
-    std::size_t nnonstiffeq() const
-    { return self->nnonstiffeq(); }
-
-    //! Public function to locate the stiff equations
-    void setStiffEqIdx( std::vector< std::size_t >& stiffEqIdx ) const
-    { return self->setStiffEqIdx( stiffEqIdx ); }
-
-    //! Public function to locate the nonstiff equations
-    void setNonStiffEqIdx( std::vector< std::size_t >& nonStiffEqIdx ) const
-    { return self->setNonStiffEqIdx( nonStiffEqIdx ); }
+extern tk::CProxy_ChareStateCollector stateProxy;
+
+using inciter::DG;
+
+DG::DG( const CProxy_Discretization& disc,
+        const CProxy_Ghosts& ghostsproxy,
+        const std::map< int, std::vector< std::size_t > >& bface,
+        const std::map< int, std::vector< std::size_t > >& /* bnode */,
+        const std::vector< std::size_t >& triinpoel ) :
+  m_disc( disc ),
+  m_ghosts( ghostsproxy ),
+  m_ndof_NodalExtrm( 3 ), // for the first order derivatives in 3 directions
+  m_nsol( 0 ),
+  m_ninitsol( 0 ),
+  m_nlim( 0 ),
+  m_nnod( 0 ),
+  m_nrefine( 0 ),
+  m_nsmooth( 0 ),
+  m_nreco( 0 ),
+  m_nnodalExtrema( 0 ),
+  m_nstiffeq( g_dgpde[Disc()->MeshId()].nstiffeq() ),
+  m_nnonstiffeq( g_dgpde[Disc()->MeshId()].nnonstiffeq() ),
+  m_u( Disc()->Inpoel().size()/4,
+       g_inputdeck.get< tag::rdof >()*
+       g_inputdeck.get< tag::ncomp >() ),
+  m_un( m_u.nunk(), m_u.nprop() ),
+  m_p( m_u.nunk(), g_inputdeck.get< tag::rdof >()*
+    g_dgpde[Disc()->MeshId()].nprim() ),
+  m_lhs( m_u.nunk(),
+         g_inputdeck.get< tag::ndof >()*
+         g_inputdeck.get< tag::ncomp >() ),
+  m_rhs( m_u.nunk(), m_lhs.nprop() ),
+  m_rhsprev( m_u.nunk(), m_lhs.nprop() ),
+  m_stiffrhs( m_u.nunk(), g_inputdeck.get< tag::ndof >()*
+              g_dgpde[Disc()->MeshId()].nstiffeq() ),
+  m_stiffrhsprev( m_u.nunk(), g_inputdeck.get< tag::ndof >()*
+                  g_dgpde[Disc()->MeshId()].nstiffeq() ),
+  m_stiffEqIdx( g_dgpde[Disc()->MeshId()].nstiffeq() ),
+  m_nonStiffEqIdx( g_dgpde[Disc()->MeshId()].nnonstiffeq() ),
+  m_mtInv(
+    tk::invMassMatTaylorRefEl(g_inputdeck.get< tag::rdof >()) ),
+  m_uNodalExtrm(),
+  m_pNodalExtrm(),
+  m_uNodalExtrmc(),
+  m_pNodalExtrmc(),
+  m_npoin( Disc()->Coord()[0].size() ),
+  m_diag(),
+  m_stage( 0 ),
+  m_ndof(),
+  m_numEqDof(),
+  m_uc(),
+  m_pc(),
+  m_ndofc(),
+  m_initial( 1 ),
+  m_uElemfields( m_u.nunk(),
+                 g_inputdeck.get< tag::ncomp >() ),
+  m_pElemfields( m_u.nunk(),
+                 m_p.nprop() / g_inputdeck.get< tag::rdof >() ),
+  m_uNodefields( m_npoin,
+                 g_inputdeck.get< tag::ncomp >() ),
+  m_pNodefields( m_npoin,
+                 m_p.nprop() / g_inputdeck.get< tag::rdof >() ),
+  m_uNodefieldsc(),
+  m_pNodefieldsc(),
+  m_outmesh(),
+  m_boxelems(),
+  m_shockmarker(m_u.nunk(), 1),
+  m_rho0mat()
+// *****************************************************************************
+//  Constructor
+//! \param[in] disc Discretization proxy
+//! \param[in] bface Boundary-faces mapped to side set ids
+//! \param[in] triinpoel Boundary-face connectivity
+// *****************************************************************************
+{
+  if (g_inputdeck.get< tag::cmd, tag::chare >() ||
+      g_inputdeck.get< tag::cmd, tag::quiescence >())
+    stateProxy.ckLocalBranch()->insert( "DG", thisIndex, CkMyPe(), Disc()->It(),
+                                        "DG" );
+
+  // assign number of dofs for each equation in all pde systems
+  g_dgpde[Disc()->MeshId()].numEquationDofs(m_numEqDof);
 
-    //! Public interface to determine elements that lie inside the IC box
-    void IcBoxElems( const tk::Fields& geoElem,
-      std::size_t nielem,
-      std::vector< std::unordered_set< std::size_t > >& inbox ) const
-    { self->IcBoxElems( geoElem, nielem, inbox ); }
-
-    //! Public interface to setting the initial conditions for the diff eq
-    void initialize(
-      const tk::Fields& L,
-      const std::vector< std::size_t >& inpoel,
-      const tk::UnsMesh::Coords& coord,
-      const std::vector< std::unordered_set< std::size_t > >& inbox,
-      const std::unordered_map< std::size_t, std::set< std::size_t > >&
-        elemblkid,
-      tk::Fields& unk,
-      tk::real t,
-      const std::size_t nielem ) const
-    { self->initialize( L, inpoel, coord, inbox, elemblkid, unk, t, nielem ); }
-
-    //! Public interface for saving initial densities of materials
-    void setRho0mat( std::vector< tk::real >& rho0mat) const
-    { return self->setRho0mat( rho0mat ); }
-
-    //! Public interface for computing density constraint
-    void computeDensityConstr( std::size_t nelem,
-                               tk::Fields& unk,
-                               std::vector< tk::real >& rho0mat,
-                               std::vector< tk::real >& densityConstr) const
-    { self->computeDensityConstr( nelem, unk, rho0mat, densityConstr); }
-
-    //! Public interface to computing the left-hand side matrix for the diff eq
-    void lhs( const tk::Fields& geoElem, tk::Fields& l ) const
-    { self->lhs( geoElem, l ); }
+  // Allocate storage for the vector of nodal extrema
+  m_uNodalExtrm.resize( Disc()->Bid().size(),
+    std::vector<tk::real>( 2 * m_ndof_NodalExtrm *
+    g_inputdeck.get< tag::ncomp >() ) );
+  m_pNodalExtrm.resize( Disc()->Bid().size(),
+    std::vector<tk::real>( 2 * m_ndof_NodalExtrm *
+    m_p.nprop() / g_inputdeck.get< tag::rdof >() ) );
+
+  // Initialization for the buffer vector of nodal extrema
+  resizeNodalExtremac();
+
+  usesAtSync = true;    // enable migration at AtSync
+
+  // Enable SDAG wait for initially building the solution vector and limiting
+  if (m_initial) {
+    thisProxy[ thisIndex ].wait4sol();
+    thisProxy[ thisIndex ].wait4refine();
+    thisProxy[ thisIndex ].wait4smooth();
+    thisProxy[ thisIndex ].wait4lim();
+    thisProxy[ thisIndex ].wait4nod();
+    thisProxy[ thisIndex ].wait4reco();
+    thisProxy[ thisIndex ].wait4nodalExtrema();
+  }
+
+  m_ghosts[thisIndex].insert(m_disc, bface, triinpoel, m_u.nunk(),
+    CkCallback(CkIndex_DG::resizeSolVectors(), thisProxy[thisIndex]));
+
+  // global-sync to call doneInserting on m_ghosts
+  auto meshid = Disc()->MeshId();
+  contribute( sizeof(std::size_t), &meshid, CkReduction::nop,
+    CkCallback(CkReductionTarget(Transporter,doneInsertingGhosts),
+    Disc()->Tr()) );
+}
 
-    //! Public interface to updating the interface cells for the diff eq
-    void updateInterfaceCells( tk::Fields& unk,
-                               std::size_t nielem,
-                               std::vector< std::size_t >& ndofel ) const
-    { self->updateInterfaceCells( unk, nielem, ndofel ); }
-
-    //! Public interface to updating the primitives for the diff eq
-    void updatePrimitives( const tk::Fields& unk,
-                           const tk::Fields& L,
-                           const tk::Fields& geoElem,
-                           tk::Fields& prim,
-                           std::size_t nielem ) const
-    { self->updatePrimitives( unk, L, geoElem, prim, nielem ); }
+void
+DG::registerReducers()
+// *****************************************************************************
+//  Configure Charm++ reduction types
+//! \details Since this is a [initnode] routine, the runtime system executes the
+//!   routine exactly once on every logical node early on in the Charm++ init
+//!   sequence. Must be static as it is called without an object. See also:
+//!   Section "Initializations at Program Startup" at in the Charm++ manual
+//!   http://charm.cs.illinois.edu/manuals/html/charm++/manual.html.
+// *****************************************************************************
+{
+  ElemDiagnostics::registerReducers();
+}
 
-    //! Public interface to cleaning up trace materials for the diff eq
-    void cleanTraceMaterial( tk::real t,
-                             const tk::Fields& geoElem,
-                             tk::Fields& unk,
-                             tk::Fields& prim,
-                             std::size_t nielem ) const
-    { self->cleanTraceMaterial( t, geoElem, unk, prim, nielem ); }
-
-    //! Public interface to reconstructing the second-order solution
-    void reconstruct( tk::real t,
-                      const tk::Fields& geoFace,
-                      const tk::Fields& geoElem,
-                      const inciter::FaceData& fd,
-                      const std::map< std::size_t, std::vector< std::size_t > >&
-                        esup,
-                      const std::vector< std::size_t >& inpoel,
-                      const tk::UnsMesh::Coords& coord,
-                      tk::Fields& U,
-                      tk::Fields& P ) const
-    {
-      self->reconstruct( t, geoFace, geoElem, fd, esup, inpoel, coord, U, P );
-    }
-
-    //! Public interface to limiting the second-order solution
-    void limit( tk::real t,
-                const tk::Fields& geoFace,
-                const tk::Fields& geoElem,
-                const inciter::FaceData& fd,
-                const std::map< std::size_t, std::vector< std::size_t > >& esup,
-                const std::vector< std::size_t >& inpoel,
-                const tk::UnsMesh::Coords& coord,
-                const std::vector< std::size_t >& ndofel,
-                const std::vector< std::size_t >& gid,
-                const std::unordered_map< std::size_t, std::size_t >& bid,
-                const std::vector< std::vector<tk::real> >& uNodalExtrm,
-                const std::vector< std::vector<tk::real> >& pNodalExtrm,
-                const std::vector< std::vector<tk::real> >& mtInv,
-                tk::Fields& U,
-                tk::Fields& P,
-                std::vector< std::size_t >& shockmarker ) const
-    {
-      self->limit( t, geoFace, geoElem, fd, esup, inpoel, coord, ndofel, gid,
-                   bid, uNodalExtrm, pNodalExtrm, mtInv, U, P, shockmarker );
-    }
-
-    //! Public interface to update the conservative variable solution
-    void CPL( const tk::Fields& prim,
-              const tk::Fields& geoElem,
-              const std::vector< std::size_t >& inpoel,
-              const tk::UnsMesh::Coords& coord,
-              tk::Fields& unk,
-              std::size_t nielem ) const
-    {
-      self->CPL( prim, geoElem, inpoel, coord, unk, nielem );
-    }
-
-    //! Public interface to getting the cell-averaged deformation gradients
-    std::array< std::vector< tk::real >, 9 > cellAvgDeformGrad(
-      const tk::Fields& U,
-      std::size_t nielem ) const
-    {
-      return self->cellAvgDeformGrad( U, nielem );
-    }
-
-    //! Public interface to computing the P1 right-hand side vector
-    void rhs( tk::real t,
-              const tk::Fields& geoFace,
-              const tk::Fields& geoElem,
-              const inciter::FaceData& fd,
-              const std::vector< std::size_t >& inpoel,
-              const std::vector< std::unordered_set< std::size_t > >& boxelems,
-              const tk::UnsMesh::Coords& coord,
-              const tk::Fields& U,
-              const tk::Fields& P,
-              const std::vector< std::size_t >& ndofel,
-              const std::vector< tk::real >& rho0mat,
-              const tk::real dt,
-              tk::Fields& R ) const
-    {
-      self->rhs( t, geoFace, geoElem, fd, inpoel, boxelems, coord, U, P,
-                 ndofel, rho0mat, dt, R );
-    }
-
-    //! Evaluate the adaptive indicator and mark the ndof for each element
-    void eval_ndof( std::size_t nunk,
-                    const tk::UnsMesh::Coords& coord,
-                    const std::vector< std::size_t >& inpoel,
-                    const inciter::FaceData& fd,
-                    const tk::Fields& unk,
-                    const tk::Fields& prim,
-                    inciter::ctr::PrefIndicatorType indicator,
-                    std::size_t ndof,
-                    std::size_t ndofmax,
-                    tk::real tolref,
-                    std::vector< std::size_t >& ndofel ) const
-    {
-      self->eval_ndof( nunk, coord, inpoel, fd, unk, prim, indicator, ndof,
-        ndofmax, tolref, ndofel );
-    }
-
-    //! Public interface for computing the minimum time step size
-    tk::real dt( const std::array< std::vector< tk::real >, 3 >& coord,
-                 const std::vector< std::size_t >& inpoel,
-                 const inciter::FaceData& fd,
-                 const tk::Fields& geoFace,
-                 const tk::Fields& geoElem,
-                 const std::vector< std::size_t >& ndofel,
-                 const tk::Fields& U,
-                 const tk::Fields& P,
-                 const std::size_t nielem ) const
-    { return self->dt( coord, inpoel, fd, geoFace, geoElem, ndofel, U,
-                       P, nielem ); }
-
-    //! Public interface for computing stiff terms for an element
-    void stiff_rhs( std::size_t e,
-                    const tk::Fields& geoElem,
-                    const std::vector< std::size_t >& inpoel,
-                    const tk::UnsMesh::Coords& coord,
-                    const tk::Fields& U,
-                    const tk::Fields& P,
-                    const std::vector< std::size_t >& ndofel,
-                    tk::Fields& R ) const
-    { return self->stiff_rhs( e, geoElem, inpoel, coord, U, P, ndofel, R); }
-
-    //! Public interface to returning maps of output var functions
-    std::map< std::string, tk::GetVarFn > OutVarFn() const
-    { return self->OutVarFn(); }
-
-    //! Public interface to returning analytic field output labels
-    std::vector< std::string > analyticFieldNames() const
-    { return self->analyticFieldNames(); }
-
-    //! Public interface to returning time history field output labels
-    std::vector< std::string > histNames() const { return self->histNames(); }
-
-    //! Public interface to returning variable names
-    std::vector< std::string > names() const { return self->names(); }
+void
+DG::ResumeFromSync()
+// *****************************************************************************
+//  Return from migration
+//! \details This is called when load balancing (LB) completes. The presence of
+//!   this function does not affect whether or not we block on LB.
+// *****************************************************************************
+{
+  if (Disc()->It() == 0) Throw( "it = 0 in ResumeFromSync()" );
+
+  if (!g_inputdeck.get< tag::cmd, tag::nonblocking >()) next();
+}
+
+void
+DG::resizeSolVectors()
+// *****************************************************************************
+// Resize solution vectors after extension due to Ghosts and continue with setup
+// *****************************************************************************
+{
+  // Resize solution vectors, lhs and rhs by the number of ghost tets
+  m_u.resize( myGhosts()->m_nunk );
+  m_un.resize( myGhosts()->m_nunk );
+  m_p.resize( myGhosts()->m_nunk );
+  m_lhs.resize( myGhosts()->m_nunk );
+  m_rhs.resize( myGhosts()->m_nunk );
+  m_rhsprev.resize( myGhosts()->m_nunk );
+  m_stiffrhs.resize( myGhosts()->m_nunk );
+  m_stiffrhsprev.resize( myGhosts()->m_nunk );
+
+  // Size communication buffer for solution and number of degrees of freedom
+  for (auto& n : m_ndofc) n.resize( myGhosts()->m_bid.size() );
+  for (auto& u : m_uc) u.resize( myGhosts()->m_bid.size() );
+  for (auto& p : m_pc) p.resize( myGhosts()->m_bid.size() );
+
+  // Initialize number of degrees of freedom in mesh elements
+  const auto pref = g_inputdeck.get< tag::pref, tag::pref >();
+  if( pref )
+  {
+    const auto ndofmax = g_inputdeck.get< tag::pref, tag::ndofmax >();
+    m_ndof.resize( myGhosts()->m_nunk, ndofmax );
+  }
+  else
+  {
+    const auto ndof = g_inputdeck.get< tag::ndof >();
+    m_ndof.resize( myGhosts()->m_nunk, ndof );
+  }
+
+  // Ensure that we also have all the geometry and connectivity data
+  // (including those of ghosts)
+  Assert( myGhosts()->m_geoElem.nunk() == m_u.nunk(),
+    "GeoElem unknowns size mismatch" );
+
+  // Signal the runtime system that all workers have received their adjacency
+  std::vector< std::size_t > meshdata{ myGhosts()->m_initial, Disc()->MeshId() };
+  contribute( meshdata, CkReduction::sum_ulong,
+    CkCallback(CkReductionTarget(Transporter,comfinal), Disc()->Tr()) );
+}
+
+void
+DG::setup()
+// *****************************************************************************
+// Set initial conditions, generate lhs, output mesh
+// *****************************************************************************
+{
+  if (g_inputdeck.get< tag::cmd, tag::chare >() ||
+      g_inputdeck.get< tag::cmd, tag::quiescence >())
+    stateProxy.ckLocalBranch()->insert( "DG", thisIndex, CkMyPe(), Disc()->It(),
+                                        "setup" );
+
+  auto d = Disc();<--- Variable 'd' is assigned a value that is never used.
+
+  // Basic error checking on sizes of element geometry data and connectivity
+  Assert( myGhosts()->m_geoElem.nunk() == m_lhs.nunk(),
+    "Size mismatch in DG::setup()" );
+
+  // Compute left-hand side of discrete PDEs
+  lhs();
+
+  // Determine elements inside user-defined IC box
+  g_dgpde[d->MeshId()].IcBoxElems( myGhosts()->m_geoElem,
+    myGhosts()->m_fd.Esuel().size()/4, m_boxelems );
+
+  // Compute volume of user-defined box IC
+  d->boxvol( {}, {}, 0 );      // punt for now
+
+  // Query time history field output labels from all PDEs integrated
+  const auto& hist_points = g_inputdeck.get< tag::history_output, tag::point >();
+  if (!hist_points.empty()) {
+    std::vector< std::string > histnames;
+    auto n = g_dgpde[d->MeshId()].histNames();
+    histnames.insert( end(histnames), begin(n), end(n) );
+    d->histheader( std::move(histnames) );
+  }
+
+  // If working with IMEX-RK, Store stiff equations into m_stiffEqIdx
+  if (g_inputdeck.get< tag::imex_runge_kutta >())
+  {
+    g_dgpde[Disc()->MeshId()].setStiffEqIdx(m_stiffEqIdx);
+    g_dgpde[Disc()->MeshId()].setNonStiffEqIdx(m_nonStiffEqIdx);
+  }
+}
+
+void
+DG::box( tk::real v, const std::vector< tk::real >& )
+// *****************************************************************************
+// Receive total box IC volume and set conditions in box
+//! \param[in] v Total volume within user-specified box
+// *****************************************************************************
+{
+  auto d = Disc();
+
+  // Store user-defined box IC volume
+  d->Boxvol() = v;
+
+  // Set initial conditions for all PDEs
+  g_dgpde[d->MeshId()].initialize( m_lhs, myGhosts()->m_inpoel,
+    myGhosts()->m_coord, m_boxelems, d->ElemBlockId(), m_u, d->T(),
+    myGhosts()->m_fd.Esuel().size()/4 );
+  g_dgpde[d->MeshId()].updatePrimitives( m_u, m_lhs, myGhosts()->m_geoElem, m_p,
+    myGhosts()->m_fd.Esuel().size()/4 );
+  // Save initial densities of all materials
+  g_dgpde[d->MeshId()].setRho0mat( m_rho0mat );
+
+  m_un = m_u;
+
+  // Output initial conditions to file (regardless of whether it was requested)
+  startFieldOutput( CkCallback(CkIndex_DG::start(), thisProxy[thisIndex]) );
+}
+
+void
+DG::start()
+// *****************************************************************************
+//  Start time stepping
+// *****************************************************************************
+{
+  // Free memory storing output mesh
+  m_outmesh.destroy();
 
-    //! Public interface to returning surface field output
-    std::vector< std::vector< tk::real > >
-    surfOutput( const std::map< int, std::vector< std::size_t > >& bnd,
-                tk::Fields& U ) const
-    { return self->surfOutput( bnd, U ); }
-
-    //! Public interface to return point history output
-    std::vector< std::vector< tk::real > >
-    histOutput( const std::vector< HistData >& h,
-      const std::vector< std::size_t >& inpoel,
-      const tk::UnsMesh::Coords& coord,
-      const tk::Fields& U,
-      const tk::Fields& P ) const
-    { return self->histOutput( h, inpoel, coord, U, P ); }
-
-    //! Public interface to returning analytic solution
-    tk::InitializeFn::result_type
-    analyticSolution( tk::real xi, tk::real yi, tk::real zi, tk::real t ) const
-    { return self->analyticSolution( xi, yi, zi, t ); }
+  // Start timer measuring time stepping wall clock time
+  Disc()->Timer().zero();
+  // Zero grind-timer
+  Disc()->grindZero();
+  // Start time stepping by computing the size of the next time step)
+  next();
+}
+
+void
+DG::startFieldOutput( CkCallback c )
+// *****************************************************************************
+// Start preparing fields for output to file
+//! \param[in] c Function to continue with after the write
+// *****************************************************************************
+{
+  // No field output in benchmark mode or if field output frequency not hit
+  if (g_inputdeck.get< tag::cmd, tag::benchmark >() || !fieldOutput()) {
+
+    c.send();
 
-    //! Public interface to returning the analytic solution for conserved vars
-    tk::InitializeFn::result_type
-    solution( tk::real xi, tk::real yi, tk::real zi, tk::real t ) const
-    { return self->solution( xi, yi, zi, t ); }
+  } else {
+
+    // Optionally refine mesh for field output
+    auto d = Disc();
 
-    //! Public interface to returning the specific total energy
-    tk::real
-    sp_totalenergy( std::size_t e, const tk::Fields& unk ) const
-    { return self->sp_totalenergy( e, unk ); }
+    if (refinedOutput()) {
+
+      const auto& tr = tk::remap( myGhosts()->m_fd.Triinpoel(), d->Gid() );
+      d->Ref()->outref( myGhosts()->m_fd.Bface(), {}, tr, c );
 
-    //! Copy assignment
-    DGPDE& operator=( const DGPDE& x )
-    { DGPDE tmp(x); *this = std::move(tmp); return *this; }
-    //! Copy constructor
-    DGPDE( const DGPDE& x ) : self( x.self->copy() ) {}
-    //! Move assignment
-    DGPDE& operator=( DGPDE&& ) noexcept = default;
-    //! Move constructor
-    DGPDE( DGPDE&& ) noexcept = default;
-
-  private:
-    //! \brief Concept is a pure virtual base class specifying the requirements
-    //!   of polymorphic objects deriving from it
-    struct Concept {
-      Concept() = default;
-      Concept( const Concept& ) = default;
-      virtual ~Concept() = default;
-      virtual Concept* copy() const = 0;
-      virtual std::size_t nprim() const = 0;
-      virtual std::size_t nmat() const = 0;
-      virtual void numEquationDofs(std::vector< std::size_t >&) const = 0;
-      virtual std::size_t nstiffeq() const = 0;
-      virtual std::size_t nnonstiffeq() const = 0;
-      virtual void setStiffEqIdx( std::vector< std::size_t >& ) const = 0;
-      virtual void setNonStiffEqIdx( std::vector< std::size_t >& ) const = 0;
-      virtual void IcBoxElems( const tk::Fields&,
-        std::size_t,
-        std::vector< std::unordered_set< std::size_t > >& ) const = 0;
-      virtual void initialize(
-        const tk::Fields&,
-        const std::vector< std::size_t >&,
-        const tk::UnsMesh::Coords&,
-        const std::vector< std::unordered_set< std::size_t > >&,
-        const std::unordered_map< std::size_t, std::set< std::size_t > >&,
-        tk::Fields&,
-        tk::real,
-        const std::size_t nielem ) const = 0;
-      virtual void setRho0mat( std::vector< tk::real >& ) const = 0;
-      virtual void computeDensityConstr( std::size_t nelem,
-                                         tk::Fields& unk,
-                                         std::vector< tk::real >& rho0mat,
-                                         std::vector< tk::real >& densityConstr)
-                                         const = 0;
-      virtual void lhs( const tk::Fields&, tk::Fields& ) const = 0;
-      virtual void updateInterfaceCells( tk::Fields&,
-                                         std::size_t,
-                                         std::vector< std::size_t >& ) const = 0;
-      virtual void updatePrimitives( const tk::Fields&,
-                                     const tk::Fields&,
-                                     const tk::Fields&,
-                                     tk::Fields&,
-                                     std::size_t ) const = 0;
-      virtual void cleanTraceMaterial( tk::real,
-                                       const tk::Fields&,
-                                       tk::Fields&,
-                                       tk::Fields&,
-                                       std::size_t ) const = 0;
-      virtual void reconstruct( tk::real,
-                                const tk::Fields&,
-                                const tk::Fields&,
-                                const inciter::FaceData&,
-                                const std::map< std::size_t,
-                                  std::vector< std::size_t > >&,
-                                const std::vector< std::size_t >&,
-                                const tk::UnsMesh::Coords&,
-                                tk::Fields&,
-                                tk::Fields& ) const = 0;
-      virtual void limit( tk::real,
-                          const tk::Fields&,
-                          const tk::Fields&,
-                          const inciter::FaceData&,
-                          const std::map< std::size_t,
-                            std::vector< std::size_t > >&,
-                          const std::vector< std::size_t >&,
-                          const tk::UnsMesh::Coords&,
-                          const std::vector< std::size_t >&,
-                          const std::vector< std::size_t >&,
-                          const std::unordered_map< std::size_t, std::size_t >&,
-                          const std::vector< std::vector<tk::real> >&,
-                          const std::vector< std::vector<tk::real> >&,
-                          const std::vector< std::vector<tk::real> >&,
-                          tk::Fields&,
-                          tk::Fields&,
-                          std::vector< std::size_t >& ) const = 0;
-      virtual void CPL( const tk::Fields&,
-                        const tk::Fields&,
-                        const std::vector< std::size_t >&,
-                        const tk::UnsMesh::Coords&,
-                        tk::Fields&,
-                        std::size_t ) const = 0;
-      virtual std::array< std::vector< tk::real >, 9 > cellAvgDeformGrad(
-        const tk::Fields&,
-        std::size_t ) const = 0;
-      virtual void rhs( tk::real,
-                        const tk::Fields&,
-                        const tk::Fields&,
-                        const inciter::FaceData&,
-                        const std::vector< std::size_t >&,
-                        const std::vector< std::unordered_set< std::size_t > >&,
-                        const tk::UnsMesh::Coords&,
-                        const tk::Fields&,
-                        const tk::Fields&,
-                        const std::vector< std::size_t >&,
-                        const std::vector< tk::real >&,
-                        const tk::real,
-                        tk::Fields& ) const = 0;
-      virtual void eval_ndof( std::size_t,
-                              const tk::UnsMesh::Coords&,
-                              const std::vector< std::size_t >&,
-                              const inciter::FaceData&,
-                              const tk::Fields&,
-                              const tk::Fields&,
-                              inciter::ctr::PrefIndicatorType,
-                              std::size_t,
-                              std::size_t,
-                              tk::real,
-                              std::vector< std::size_t >& ) const = 0;
-      virtual tk::real dt( const std::array< std::vector< tk::real >, 3 >&,
-                           const std::vector< std::size_t >&,
-                           const inciter::FaceData&,
-                           const tk::Fields&,
-                           const tk::Fields&,
-                           const std::vector< std::size_t >&,
-                           const tk::Fields&,
-                           const tk::Fields&,
-                           const std::size_t ) const = 0;
-      virtual void stiff_rhs( std::size_t,
-                              const tk::Fields&,
-                              const std::vector< std::size_t >&,
-                              const tk::UnsMesh::Coords&,
-                              const tk::Fields&,
-                              const tk::Fields&,
-                              const std::vector< std::size_t >&,
-                              tk::Fields& ) const = 0;
-      virtual std::map< std::string, tk::GetVarFn > OutVarFn() const = 0;
-      virtual std::vector< std::string > analyticFieldNames() const = 0;
-      virtual std::vector< std::string > histNames() const = 0;
-      virtual std::vector< std::string > names() const = 0;
-      virtual std::vector< std::vector< tk::real > > surfOutput(
-        const std::map< int, std::vector< std::size_t > >&,
-        tk::Fields& ) const = 0;
-      virtual std::vector< std::vector< tk::real > > histOutput(
-        const std::vector< HistData >&,
-        const std::vector< std::size_t >&,
-        const tk::UnsMesh::Coords&,
-        const tk::Fields&,
-        const tk::Fields& ) const = 0;
-      virtual tk::InitializeFn::result_type analyticSolution(
-        tk::real xi, tk::real yi, tk::real zi, tk::real t ) const = 0;
-      virtual tk::InitializeFn::result_type solution(
-        tk::real xi, tk::real yi, tk::real zi, tk::real t ) const = 0;
-      virtual tk::real sp_totalenergy(
-        std::size_t, const tk::Fields& ) const = 0;
-    };
-
-    //! \brief Model models the Concept above by deriving from it and overriding
-    //!   the virtual functions required by Concept
-    template< typename T >
-    struct Model : Concept {
-      explicit Model( T x ) : data( std::move(x) ) {}
-      Concept* copy() const override { return new Model( *this ); }
-      std::size_t nprim() const override
-      { return data.nprim(); }
-      std::size_t nmat() const override
-      { return data.nmat(); }
-      void numEquationDofs(std::vector< std::size_t >& numEqDof) const override
-      { data.numEquationDofs(numEqDof); }
-      std::size_t nstiffeq() const override
-      { return data.nstiffeq(); }
-      std::size_t nnonstiffeq() const override
-      { return data.nnonstiffeq(); }
-      void setStiffEqIdx( std::vector< std::size_t >& stiffEqIdx ) const override
-      { data.setStiffEqIdx(stiffEqIdx); }
-      void setNonStiffEqIdx( std::vector< std::size_t >& nonStiffEqIdx ) const override
-      { data.setNonStiffEqIdx(nonStiffEqIdx); }
-      void IcBoxElems( const tk::Fields& geoElem,
-        std::size_t nielem,
-        std::vector< std::unordered_set< std::size_t > >& inbox )
-      const override { data.IcBoxElems( geoElem, nielem, inbox ); }
-      void initialize(
-        const tk::Fields& L,
-        const std::vector< std::size_t >& inpoel,
-        const tk::UnsMesh::Coords& coord,
-        const std::vector< std::unordered_set< std::size_t > >& inbox,
-        const std::unordered_map< std::size_t, std::set< std::size_t > >&
-          elemblkid,
-        tk::Fields& unk,
-        tk::real t,
-        const std::size_t nielem )
-      const override { data.initialize( L, inpoel, coord, inbox, elemblkid, unk,
-        t, nielem ); }
-      void setRho0mat( std::vector< tk::real >& rho0mat ) const override
-      { data.setRho0mat( rho0mat ); }
-      void computeDensityConstr( std::size_t nelem,
-                                 tk::Fields& unk,
-                                 std::vector< tk::real >& rho0mat,
-                                 std::vector< tk::real >& densityConstr)
-                                 const override
-      { data.computeDensityConstr( nelem, unk, rho0mat, densityConstr ); }
-      void lhs( const tk::Fields& geoElem, tk::Fields& l ) const override
-      { data.lhs( geoElem, l ); }
-      void updateInterfaceCells( tk::Fields& unk,
-                                 std::size_t nielem,
-                                 std::vector< std::size_t >& ndofel )
-      const override { data.updateInterfaceCells( unk, nielem, ndofel ); }
-      void updatePrimitives( const tk::Fields& unk,
-                             const tk::Fields& L,
-                             const tk::Fields& geoElem,
-                             tk::Fields& prim,
-                             std::size_t nielem )
-      const override { data.updatePrimitives( unk, L, geoElem, prim, nielem ); }
-      void cleanTraceMaterial( tk::real t,
-                               const tk::Fields& geoElem,
-                               tk::Fields& unk,
-                               tk::Fields& prim,
-                               std::size_t nielem )
-      const override { data.cleanTraceMaterial( t, geoElem, unk, prim, nielem ); }
-      void reconstruct( tk::real t,
-                        const tk::Fields& geoFace,
-                        const tk::Fields& geoElem,
-                        const inciter::FaceData& fd,
-                        const std::map< std::size_t,
-                          std::vector< std::size_t > >& esup,
-                        const std::vector< std::size_t >& inpoel,
-                        const tk::UnsMesh::Coords& coord,
-                        tk::Fields& U,
-                        tk::Fields& P ) const override
-      {
-        data.reconstruct( t, geoFace, geoElem, fd, esup, inpoel, coord, U, P );
-      }
-      void limit( tk::real t,
-                  const tk::Fields& geoFace,
-                  const tk::Fields& geoElem,
-                  const inciter::FaceData& fd,
-                  const std::map< std::size_t, std::vector< std::size_t > >&
-                    esup,
-                  const std::vector< std::size_t >& inpoel,
-                  const tk::UnsMesh::Coords& coord,
-                  const std::vector< std::size_t >& ndofel,
-                  const std::vector< std::size_t >& gid,
-                  const std::unordered_map< std::size_t, std::size_t >& bid,
-                  const std::vector< std::vector<tk::real> >& uNodalExtrm,
-                  const std::vector< std::vector<tk::real> >& pNodalExtrm,
-                  const std::vector< std::vector<tk::real> >& mtInv,
-                  tk::Fields& U,
-                  tk::Fields& P,
-                  std::vector< std::size_t >& shockmarker ) const override
-      {
-        data.limit( t, geoFace, geoElem, fd, esup, inpoel, coord, ndofel, gid,
-                    bid, uNodalExtrm, pNodalExtrm, mtInv, U, P, shockmarker );
-      }
-      void CPL( const tk::Fields& prim,
-                const tk::Fields& geoElem,
-                const std::vector< std::size_t >& inpoel,
-                const tk::UnsMesh::Coords& coord,
-                tk::Fields& unk,
-                std::size_t nielem ) const override
-      {
-        data.CPL( prim, geoElem, inpoel, coord, unk, nielem );
-      }
-      std::array< std::vector< tk::real >, 9 > cellAvgDeformGrad(
-        const tk::Fields& U,
-        std::size_t nielem ) const override
-      {
-        return data.cellAvgDeformGrad( U, nielem );
-      }
-      void rhs(
-        tk::real t,
-        const tk::Fields& geoFace,
-        const tk::Fields& geoElem,
-        const inciter::FaceData& fd,
-        const std::vector< std::size_t >& inpoel,
-        const std::vector< std::unordered_set< std::size_t > >& boxelems,
-        const tk::UnsMesh::Coords& coord,
-        const tk::Fields& U,
-        const tk::Fields& P,
-        const std::vector< std::size_t >& ndofel,
-        const std::vector< tk::real >& rho0mat,
-        const tk::real dt,
-        tk::Fields& R ) const override
-      {
-        data.rhs( t, geoFace, geoElem, fd, inpoel, boxelems, coord, U, P,
-                  ndofel, rho0mat, dt, R );
-      }
-      void eval_ndof( std::size_t nunk,
-                      const tk::UnsMesh::Coords& coord,
-                      const std::vector< std::size_t >& inpoel,
-                      const inciter::FaceData& fd,
-                      const tk::Fields& unk,
-                      const tk::Fields& prim,
-                      inciter::ctr::PrefIndicatorType indicator,
-                      std::size_t ndof,
-                      std::size_t ndofmax,
-                      tk::real tolref,
-                      std::vector< std::size_t >& ndofel ) const override
-      { data.eval_ndof( nunk, coord, inpoel, fd, unk, prim, indicator, ndof,
-                        ndofmax, tolref, ndofel ); }
-      tk::real dt( const std::array< std::vector< tk::real >, 3 >& coord,
-                   const std::vector< std::size_t >& inpoel,
-                   const inciter::FaceData& fd,
-                   const tk::Fields& geoFace,
-                   const tk::Fields& geoElem,
-                   const std::vector< std::size_t >& ndofel,
-                   const tk::Fields& U,
-                   const tk::Fields& P,
-                   const std::size_t nielem ) const override
-      { return data.dt( coord, inpoel, fd, geoFace, geoElem, ndofel,
-                        U, P, nielem ); }
-      void stiff_rhs( std::size_t e,
-                      const tk::Fields& geoElem,
-                      const std::vector< std::size_t >& inpoel,
-                      const tk::UnsMesh::Coords& coord,
-                      const tk::Fields& U,
-                      const tk::Fields& P,
-                      const std::vector< std::size_t >& ndofel,
-                      tk::Fields& R ) const override
-      { return data.stiff_rhs( e, geoElem, inpoel, coord, U, P, ndofel, R ); }
-      std::map< std::string, tk::GetVarFn > OutVarFn() const override
-      { return data.OutVarFn(); }
-      std::vector< std::string > analyticFieldNames() const override
-      { return data.analyticFieldNames(); }
-      std::vector< std::string > histNames() const override
-      { return data.histNames(); }
-      std::vector< std::string > names() const override
-      { return data.names(); }
-      std::vector< std::vector< tk::real > > surfOutput(
-        const std::map< int, std::vector< std::size_t > >& bnd,
-        tk::Fields& U ) const override
-      { return data.surfOutput( bnd, U ); }
-      std::vector< std::vector< tk::real > > histOutput(
-        const std::vector< HistData >& h,
-        const std::vector< std::size_t >& inpoel,
-        const tk::UnsMesh::Coords& coord,
-        const tk::Fields& U,
-        const tk::Fields& P ) const override
-      { return data.histOutput( h, inpoel, coord, U, P ); }
-      tk::InitializeFn::result_type
-      analyticSolution( tk::real xi, tk::real yi, tk::real zi, tk::real t )
-       const override { return data.analyticSolution( xi, yi, zi, t ); }
-      tk::InitializeFn::result_type
-      solution( tk::real xi, tk::real yi, tk::real zi, tk::real t )
-       const override { return data.solution( xi, yi, zi, t ); }
-      tk::real sp_totalenergy( std::size_t e, const tk::Fields& unk )
-       const override { return data.sp_totalenergy( e, unk ); }
-      T data;
-    };
-
-    std::unique_ptr< Concept > self;    //!< Base pointer used polymorphically
-};
-
-} // inciter::
+    } else {
+
+      // cut off ghosts from mesh connectivity and coordinates
+      const auto& tr = tk::remap( myGhosts()->m_fd.Triinpoel(), d->Gid() );
+      extractFieldOutput( {}, d->Chunk(), d->Coord(), {}, {},
+                          d->NodeCommMap(), myGhosts()->m_fd.Bface(), {}, tr, c );
+
+    }
+
+  }
+}
+
+void
+DG::next()
+// *****************************************************************************
+// Advance equations to next time step
+// *****************************************************************************
+{
+  const auto pref = g_inputdeck.get< tag::pref, tag::pref >();
+
+  auto d = Disc();
+
+  if (pref && m_stage == 0 && d->T() > 0)
+    g_dgpde[d->MeshId()].eval_ndof( myGhosts()->m_nunk, myGhosts()->m_coord,
+                  myGhosts()->m_inpoel,
+                  myGhosts()->m_fd, m_u, m_p,
+                  g_inputdeck.get< tag::pref, tag::indicator >(),
+                  g_inputdeck.get< tag::ndof >(),
+                  g_inputdeck.get< tag::pref, tag::ndofmax >(),
+                  g_inputdeck.get< tag::pref, tag::tolref >(),
+                  m_ndof );
+
+  // communicate solution ghost data (if any)
+  if (myGhosts()->m_sendGhost.empty())
+    comsol_complete();
+  else
+    for(const auto& [cid, ghostdata] : myGhosts()->m_sendGhost) {
+      std::vector< std::size_t > tetid( ghostdata.size() );
+      std::vector< std::vector< tk::real > > u( ghostdata.size() ),
+                                             prim( ghostdata.size() );
+      std::vector< std::size_t > ndof;
+      std::size_t j = 0;
+      for(const auto& i : ghostdata) {
+        Assert( i < myGhosts()->m_fd.Esuel().size()/4,
+          "Sending solution ghost data" );
+        tetid[j] = i;
+        u[j] = m_u[i];
+        prim[j] = m_p[i];
+        if (pref && m_stage == 0) ndof.push_back( m_ndof[i] );
+        ++j;
+      }
+      thisProxy[ cid ].comsol( thisIndex, m_stage, tetid, u, prim, ndof );
+    }
+
+  ownsol_complete();
+}
+
+void
+DG::comsol( int fromch,
+            std::size_t fromstage,
+            const std::vector< std::size_t >& tetid,
+            const std::vector< std::vector< tk::real > >& u,
+            const std::vector< std::vector< tk::real > >& prim,
+            const std::vector< std::size_t >& ndof )
+// *****************************************************************************
+//  Receive chare-boundary solution ghost data from neighboring chares
+//! \param[in] fromch Sender chare id
+//! \param[in] fromstage Sender chare time step stage
+//! \param[in] tetid Ghost tet ids we receive solution data for
+//! \param[in] u Solution ghost data
+//! \param[in] prim Primitive variables in ghost cells
+//! \param[in] ndof Number of degrees of freedom for chare-boundary elements
+//! \details This function receives contributions to the unlimited solution
+//!   from fellow chares.
+// *****************************************************************************
+{
+  Assert( u.size() == tetid.size(), "Size mismatch in DG::comsol()" );
+  Assert( prim.size() == tetid.size(), "Size mismatch in DG::comsol()" );
+
+  const auto pref = g_inputdeck.get< tag::pref, tag::pref >();
+
+  if (pref && fromstage == 0)
+    Assert( ndof.size() == tetid.size(), "Size mismatch in DG::comsol()" );
+
+  // Find local-to-ghost tet id map for sender chare
+  const auto& n = tk::cref_find( myGhosts()->m_ghost, fromch );
+
+  for (std::size_t i=0; i<tetid.size(); ++i) {
+    auto j = tk::cref_find( n, tetid[i] );
+    Assert( j >= myGhosts()->m_fd.Esuel().size()/4,
+      "Receiving solution non-ghost data" );
+    auto b = tk::cref_find( myGhosts()->m_bid, j );
+    Assert( b < m_uc[0].size(), "Indexing out of bounds" );
+    m_uc[0][b] = u[i];
+    m_pc[0][b] = prim[i];
+    if (pref && fromstage == 0) {
+      Assert( b < m_ndofc[0].size(), "Indexing out of bounds" );
+      m_ndofc[0][b] = ndof[i];
+    }
+  }
+
+  // if we have received all solution ghost contributions from neighboring
+  // chares (chares we communicate along chare-boundary faces with), and
+  // contributed our solution to these neighbors, proceed to reconstructions
+  if (++m_nsol == myGhosts()->m_sendGhost.size()) {
+    m_nsol = 0;
+    comsol_complete();
+  }
+}
+
+void
+DG::extractFieldOutput(
+  const std::vector< std::size_t >& /*ginpoel*/,
+  const tk::UnsMesh::Chunk& chunk,
+  const tk::UnsMesh::Coords& coord,
+  const std::unordered_map< std::size_t, tk::UnsMesh::Edge >& /*addedNodes*/,
+  const std::unordered_map< std::size_t, std::size_t >& addedTets,
+  const tk::NodeCommMap& nodeCommMap,
+  const std::map< int, std::vector< std::size_t > >& bface,
+  const std::map< int, std::vector< std::size_t > >& /* bnode */,
+  const std::vector< std::size_t >& triinpoel,
+  CkCallback c )
+// *****************************************************************************
+// Extract field output going to file
+//! \param[in] chunk Field-output mesh chunk (connectivity and global<->local
+//!    id maps)
+//! \param[in] coord Field-output mesh node coordinates
+//! \param[in] addedTets Field-output mesh cells and their parents (local ids)
+//! \param[in] nodeCommMap Field-output mesh node communication map
+//! \param[in] bface Field-output meshndary-faces mapped to side set ids
+//! \param[in] triinpoel Field-output mesh boundary-face connectivity
+//! \param[in] c Function to continue with after the write
+// *****************************************************************************
+{
+  m_outmesh.chunk = chunk;
+  m_outmesh.coord = coord;
+  m_outmesh.triinpoel = triinpoel;
+  m_outmesh.bface = bface;
+  m_outmesh.nodeCommMap = nodeCommMap;
+
+  const auto& inpoel = std::get< 0 >( chunk );
+
+  // Evaluate element solution on incoming mesh
+  evalSolution( *Disc(), inpoel, coord, addedTets, m_ndof, m_u, m_p,
+    m_uElemfields, m_pElemfields, m_uNodefields, m_pNodefields );
+
+  // Send node fields contributions to neighbor chares
+  if (nodeCommMap.empty())
+    comnodeout_complete();
+  else {
+    const auto& lid = std::get< 2 >( chunk );
+    auto esup = tk::genEsup( inpoel, 4 );
+    for(const auto& [ch,nodes] : nodeCommMap) {
+      // Pack node field data in chare boundary nodes
+      std::vector< std::vector< tk::real > >
+        lu( m_uNodefields.nprop(), std::vector< tk::real >( nodes.size() ) );
+      std::vector< std::vector< tk::real > >
+        lp( m_pNodefields.nprop(), std::vector< tk::real >( nodes.size() ) );
+      for (std::size_t f=0; f<m_uNodefields.nprop(); ++f) {
+        std::size_t j = 0;
+        for (auto g : nodes)
+          lu[f][j++] = m_uNodefields(tk::cref_find(lid,g),f);
+      }
+      for (std::size_t f=0; f<m_pNodefields.nprop(); ++f) {
+        std::size_t j = 0;
+        for (auto g : nodes)
+          lp[f][j++] = m_pNodefields(tk::cref_find(lid,g),f);
+      }
+      // Pack (partial) number of elements surrounding chare boundary nodes
+      std::vector< std::size_t > nesup( nodes.size() );
+      std::size_t j = 0;
+      for (auto g : nodes) {
+        auto i = tk::cref_find( lid, g );
+        nesup[j++] = esup.second[i+1] - esup.second[i];
+      }
+      thisProxy[ch].comnodeout(
+        std::vector<std::size_t>(begin(nodes),end(nodes)), nesup, lu, lp );
+    }
+  }
+
+  ownnod_complete( c, addedTets );
+}
+
+void
+DG::lhs()
+// *****************************************************************************
+// Compute left-hand side of discrete transport equations
+// *****************************************************************************
+{
+  g_dgpde[Disc()->MeshId()].lhs( myGhosts()->m_geoElem, m_lhs );
+
+  if (!m_initial) stage();
+}
+
+void DG::refine()
+// *****************************************************************************
+// Add the protective layer for ndof refinement
+// *****************************************************************************
+{
+  const auto pref = g_inputdeck.get< tag::pref, tag::pref >();
+
+  // Combine own and communicated contributions of unreconstructed solution and
+  // degrees of freedom in cells (if p-adaptive)
+  for (const auto& b : myGhosts()->m_bid) {
+    Assert( m_uc[0][b.second].size() == m_u.nprop(), "ncomp size mismatch" );
+    Assert( m_pc[0][b.second].size() == m_p.nprop(), "ncomp size mismatch" );
+    for (std::size_t c=0; c<m_u.nprop(); ++c) {
+      m_u(b.first,c) = m_uc[0][b.second][c];
+    }
+    for (std::size_t c=0; c<m_p.nprop(); ++c) {
+      m_p(b.first,c) = m_pc[0][b.second][c];
+    }
+    if (pref && m_stage == 0) {
+      m_ndof[ b.first ] = m_ndofc[0][ b.second ];
+    }
+  }
+
+  if (pref && m_stage==0) refine_ndof();
+
+  if (myGhosts()->m_sendGhost.empty())
+    comrefine_complete();
+  else
+    for(const auto& [cid, ghostdata] : myGhosts()->m_sendGhost) {
+      std::vector< std::size_t > tetid( ghostdata.size() );
+      std::vector< std::vector< tk::real > > u( ghostdata.size() ),
+                                             prim( ghostdata.size() );
+      std::vector< std::size_t > ndof( ghostdata.size() );
+      std::size_t j = 0;
+      for(const auto& i : ghostdata) {
+        Assert( i < myGhosts()->m_fd.Esuel().size()/4, "Sending refined ndof  "
+          "data" );
+        tetid[j] = i;
+        if (pref && m_stage == 0) ndof[j] = m_ndof[i];
+        ++j;
+      }
+      thisProxy[ cid ].comrefine( thisIndex, tetid, ndof );
+    }
+
+  ownrefine_complete();
+}
+
+void
+DG::comrefine( int fromch,
+               const std::vector< std::size_t >& tetid,
+               const std::vector< std::size_t >& ndof )
+// *****************************************************************************
+//  Receive chare-boundary ghost data from neighboring chares
+//! \param[in] fromch Sender chare id
+//! \param[in] tetid Ghost tet ids we receive solution data for
+//! \param[in] ndof Number of degrees of freedom for chare-boundary elements
+//! \details This function receives contributions to the refined ndof data
+//!   from fellow chares.
+// *****************************************************************************
+{
+  const auto pref = g_inputdeck.get< tag::pref, tag::pref >();
+
+  if (pref && m_stage == 0)
+    Assert( ndof.size() == tetid.size(), "Size mismatch in DG::comrefine()" );
+
+  // Find local-to-ghost tet id map for sender chare
+  const auto& n = tk::cref_find( myGhosts()->m_ghost, fromch );
+
+  for (std::size_t i=0; i<tetid.size(); ++i) {
+    auto j = tk::cref_find( n, tetid[i] );
+    Assert( j >= myGhosts()->m_fd.Esuel().size()/4,
+      "Receiving solution non-ghost data" );
+    auto b = tk::cref_find( myGhosts()->m_bid, j );
+    if (pref && m_stage == 0) {
+      Assert( b < m_ndofc[1].size(), "Indexing out of bounds" );
+      m_ndofc[1][b] = ndof[i];
+    }
+  }
+
+  // if we have received all solution ghost contributions from neighboring
+  // chares (chares we communicate along chare-boundary faces with), and
+  // contributed our solution to these neighbors, proceed to limiting
+  if (++m_nrefine == myGhosts()->m_sendGhost.size()) {
+    m_nrefine = 0;
+    comrefine_complete();
+  }
+}
+
+void
+DG::smooth()
+// *****************************************************************************
+// Smooth the refined ndof distribution
+// *****************************************************************************
+{
+  const auto pref = g_inputdeck.get< tag::pref, tag::pref >();
+
+  for (const auto& b : myGhosts()->m_bid) {
+    if (pref && m_stage == 0)
+      m_ndof[ b.first ] = m_ndofc[1][ b.second ];
+  }
+
+  if (pref && m_stage==0) smooth_ndof();
+
+  if (myGhosts()->m_sendGhost.empty())
+    comsmooth_complete();
+  else
+    for(const auto& [cid, ghostdata] : myGhosts()->m_sendGhost) {
+      std::vector< std::size_t > tetid( ghostdata.size() );
+      std::vector< std::size_t > ndof;
+      std::size_t j = 0;
+      for(const auto& i : ghostdata) {
+        Assert( i < myGhosts()->m_fd.Esuel().size()/4, "Sending ndof data" );
+        tetid[j] = i;
+        if (pref && m_stage == 0) ndof.push_back( m_ndof[i] );
+        ++j;
+      }
+      thisProxy[ cid ].comsmooth( thisIndex, tetid, ndof );
+    }
+
+  ownsmooth_complete();
+}
+
+void
+DG::comsmooth( int fromch,
+               const std::vector< std::size_t >& tetid,
+               const std::vector< std::size_t >& ndof )
+// *****************************************************************************
+//  Receive chare-boundary ghost data from neighboring chares
+//! \param[in] fromch Sender chare id
+//! \param[in] tetid Ghost tet ids we receive solution data for
+//! \param[in] ndof Number of degrees of freedom for chare-boundary elements
+//! \details This function receives contributions to the smoothed ndof data
+//!   from fellow chares.
+// *****************************************************************************
+{
+  const auto pref = g_inputdeck.get< tag::pref, tag::pref >();
+
+  if (pref && m_stage == 0)
+    Assert( ndof.size() == tetid.size(), "Size mismatch in DG::comsmooth()" );
+
+  const auto& n = tk::cref_find( myGhosts()->m_ghost, fromch );
+
+  for (std::size_t i=0; i<tetid.size(); ++i) {
+    auto j = tk::cref_find( n, tetid[i] );
+    Assert( j >= myGhosts()->m_fd.Esuel().size()/4, "Receiving ndof data" );
+    auto b = tk::cref_find( myGhosts()->m_bid, j );
+    if (pref && m_stage == 0) {
+      Assert( b < m_ndofc[2].size(), "Indexing out of bounds" );
+      m_ndofc[2][b] = ndof[i];
+    }
+  }
+
+  if (++m_nsmooth == myGhosts()->m_sendGhost.size()) {
+    m_nsmooth = 0;
+    comsmooth_complete();
+  }
+}
 
-#endif // DGPDE_h
+void
+DG::reco()
+// *****************************************************************************
+// Compute reconstructions
+// *****************************************************************************
+{
+  const auto pref = g_inputdeck.get< tag::pref, tag::pref >();
+  const auto rdof = g_inputdeck.get< tag::rdof >();
+
+  // Combine own and communicated contributions of unreconstructed solution and
+  // degrees of freedom in cells (if p-adaptive)
+  for (const auto& b : myGhosts()->m_bid) {
+    if (pref && m_stage == 0) {
+      m_ndof[ b.first ] = m_ndofc[2][ b.second ];
+    }
+  }
+
+  auto d = Disc();
+  if (rdof > 1)
+    // Reconstruct second-order solution and primitive quantities
+    g_dgpde[d->MeshId()].reconstruct( d->T(), myGhosts()->m_geoFace,
+      myGhosts()->m_geoElem,
+      myGhosts()->m_fd, myGhosts()->m_esup, myGhosts()->m_inpoel,
+      myGhosts()->m_coord, m_u, m_p );
+
+  // Send reconstructed solution to neighboring chares
+  if (myGhosts()->m_sendGhost.empty())
+    comreco_complete();
+  else
+    for(const auto& [cid, ghostdata] : myGhosts()->m_sendGhost) {
+      std::vector< std::size_t > tetid( ghostdata.size() );
+      std::vector< std::vector< tk::real > > u( ghostdata.size() ),
+                                             prim( ghostdata.size() );
+      std::size_t j = 0;
+      for(const auto& i : ghostdata) {
+        Assert( i < myGhosts()->m_fd.Esuel().size()/4, "Sending reconstructed ghost "
+          "data" );
+        tetid[j] = i;
+        u[j] = m_u[i];
+        prim[j] = m_p[i];
+        ++j;
+      }
+      thisProxy[ cid ].comreco( thisIndex, tetid, u, prim );
+    }
+
+  ownreco_complete();
+}
+
+void
+DG::comreco( int fromch,
+             const std::vector< std::size_t >& tetid,
+             const std::vector< std::vector< tk::real > >& u,
+             const std::vector< std::vector< tk::real > >& prim )
+// *****************************************************************************
+//  Receive chare-boundary reconstructed ghost data from neighboring chares
+//! \param[in] fromch Sender chare id
+//! \param[in] tetid Ghost tet ids we receive solution data for
+//! \param[in] u Reconstructed high-order solution
+//! \param[in] prim Limited high-order primitive quantities
+//! \details This function receives contributions to the reconstructed solution
+//!   from fellow chares.
+// *****************************************************************************
+{
+  Assert( u.size() == tetid.size(), "Size mismatch in DG::comreco()" );
+  Assert( prim.size() == tetid.size(), "Size mismatch in DG::comreco()" );
+
+  // Find local-to-ghost tet id map for sender chare
+  const auto& n = tk::cref_find( myGhosts()->m_ghost, fromch );
+
+  for (std::size_t i=0; i<tetid.size(); ++i) {
+    auto j = tk::cref_find( n, tetid[i] );
+    Assert( j >= myGhosts()->m_fd.Esuel().size()/4,
+      "Receiving solution non-ghost data" );
+    auto b = tk::cref_find( myGhosts()->m_bid, j );
+    Assert( b < m_uc[1].size(), "Indexing out of bounds" );
+    Assert( b < m_pc[1].size(), "Indexing out of bounds" );
+    m_uc[1][b] = u[i];
+    m_pc[1][b] = prim[i];
+  }
+
+  // if we have received all solution ghost contributions from neighboring
+  // chares (chares we communicate along chare-boundary faces with), and
+  // contributed our solution to these neighbors, proceed to limiting
+  if (++m_nreco == myGhosts()->m_sendGhost.size()) {
+    m_nreco = 0;
+    comreco_complete();
+  }
+}
+
+void
+DG::nodalExtrema()
+// *****************************************************************************
+// Compute nodal extrema at chare-boundary nodes. Extrema at internal nodes
+// are calculated in limiter function.
+// *****************************************************************************
+{
+  auto d = Disc();
+  auto gid = d->Gid();
+  auto bid = d->Bid();
+  const auto rdof = g_inputdeck.get< tag::rdof >();
+  const auto ncomp = m_u.nprop() / rdof;
+  const auto nprim = m_p.nprop() / rdof;
+
+  // Combine own and communicated contributions of unlimited solution, and
+  // if a p-adaptive algorithm is used, degrees of freedom in cells
+  for (const auto& [boundary, localtet] : myGhosts()->m_bid) {
+    Assert( m_uc[1][localtet].size() == m_u.nprop(), "ncomp size mismatch" );
+    Assert( m_pc[1][localtet].size() == m_p.nprop(), "ncomp size mismatch" );
+    for (std::size_t c=0; c<m_u.nprop(); ++c) {
+      m_u(boundary,c) = m_uc[1][localtet][c];
+    }
+    for (std::size_t c=0; c<m_p.nprop(); ++c) {
+      m_p(boundary,c) = m_pc[1][localtet][c];
+    }
+  }
+
+  // Initialize nodal extrema vector
+  auto large = std::numeric_limits< tk::real >::max();
+  for(std::size_t i = 0; i<bid.size(); i++)
+  {
+    for (std::size_t c=0; c<ncomp; ++c)
+    {
+      for(std::size_t idof=0; idof<m_ndof_NodalExtrm; idof++)
+      {
+        auto max_mark = 2*c*m_ndof_NodalExtrm + 2*idof;
+        auto min_mark = max_mark + 1;
+        m_uNodalExtrm[i][max_mark] = -large;
+        m_uNodalExtrm[i][min_mark] =  large;
+      }
+    }
+    for (std::size_t c=0; c<nprim; ++c)
+    {
+      for(std::size_t idof=0; idof<m_ndof_NodalExtrm; idof++)
+      {
+        auto max_mark = 2*c*m_ndof_NodalExtrm + 2*idof;
+        auto min_mark = max_mark + 1;
+        m_pNodalExtrm[i][max_mark] = -large;
+        m_pNodalExtrm[i][min_mark] =  large;
+      }
+    }
+  }
+
+  // Evaluate the max/min value for the chare-boundary nodes
+  if(rdof > 4) {
+      evalNodalExtrmRefEl(ncomp, nprim, m_ndof_NodalExtrm, d->bndel(),
+        myGhosts()->m_inpoel, gid, bid, m_u, m_p, m_uNodalExtrm, m_pNodalExtrm);
+  }
+
+  // Communicate extrema at nodes to other chares on chare-boundary
+  if (d->NodeCommMap().empty())        // in serial we are done
+    comnodalExtrema_complete();
+  else  // send nodal extrema to chare-boundary nodes to fellow chares
+  {
+    for (const auto& [c,n] : d->NodeCommMap()) {
+      std::vector< std::vector< tk::real > > g1( n.size() ), g2( n.size() );
+      std::size_t j = 0;
+      for (auto i : n)
+      {
+        auto p = tk::cref_find(d->Bid(),i);
+        g1[ j   ] = m_uNodalExtrm[ p ];
+        g2[ j++ ] = m_pNodalExtrm[ p ];
+      }
+      thisProxy[c].comnodalExtrema( std::vector<std::size_t>(begin(n),end(n)),
+        g1, g2 );
+    }
+  }
+  ownnodalExtrema_complete();
+}
+
+void
+DG::comnodalExtrema( const std::vector< std::size_t >& gid,
+                     const std::vector< std::vector< tk::real > >& G1,
+                     const std::vector< std::vector< tk::real > >& G2 )
+// *****************************************************************************
+//  Receive contributions to nodal extrema on chare-boundaries
+//! \param[in] gid Global mesh node IDs at which we receive grad contributions
+//! \param[in] G1 Partial contributions of extrema for conservative variables to
+//!   chare-boundary nodes
+//! \param[in] G2 Partial contributions of extrema for primitive variables to
+//!   chare-boundary nodes
+//! \details This function receives contributions to m_uNodalExtrm/m_pNodalExtrm
+//!   , which stores nodal extrems at mesh chare-boundary nodes. While
+//!   m_uNodalExtrm/m_pNodalExtrm stores own contributions, m_uNodalExtrmc
+//!   /m_pNodalExtrmc collects the neighbor chare contributions during
+//!   communication.
+// *****************************************************************************
+{
+  Assert( G1.size() == gid.size(), "Size mismatch" );
+  Assert( G2.size() == gid.size(), "Size mismatch" );
+
+  const auto rdof = g_inputdeck.get< tag::rdof >();
+  const auto ncomp = m_u.nprop() / rdof;
+  const auto nprim = m_p.nprop() / rdof;
+
+  for (std::size_t i=0; i<gid.size(); ++i)
+  {
+    auto& u = m_uNodalExtrmc[gid[i]];
+    auto& p = m_pNodalExtrmc[gid[i]];
+    for (std::size_t c=0; c<ncomp; ++c)
+    {
+      for(std::size_t idof=0; idof<m_ndof_NodalExtrm; idof++)
+      {
+        auto max_mark = 2*c*m_ndof_NodalExtrm + 2*idof;
+        auto min_mark = max_mark + 1;
+        u[max_mark] = std::max( G1[i][max_mark], u[max_mark] );
+        u[min_mark] = std::min( G1[i][min_mark], u[min_mark] );
+      }
+    }
+    for (std::size_t c=0; c<nprim; ++c)
+    {
+      for(std::size_t idof=0; idof<m_ndof_NodalExtrm; idof++)
+      {
+        auto max_mark = 2*c*m_ndof_NodalExtrm + 2*idof;
+        auto min_mark = max_mark + 1;
+        p[max_mark] = std::max( G2[i][max_mark], p[max_mark] );
+        p[min_mark] = std::min( G2[i][min_mark], p[min_mark] );
+      }
+    }
+  }
+
+  if (++m_nnodalExtrema == Disc()->NodeCommMap().size())
+  {
+    m_nnodalExtrema = 0;
+    comnodalExtrema_complete();
+  }
+}
+
+void DG::resizeNodalExtremac()
+// *****************************************************************************
+//  Resize the buffer vector of nodal extrema
+// *****************************************************************************
+{
+  const auto rdof = g_inputdeck.get< tag::rdof >();
+  const auto ncomp = m_u.nprop() / rdof;
+  const auto nprim = m_p.nprop() / rdof;
+
+  auto large = std::numeric_limits< tk::real >::max();
+  for (const auto& [c,n] : Disc()->NodeCommMap())
+  {
+    for (auto i : n) {
+      auto& u = m_uNodalExtrmc[i];
+      auto& p = m_pNodalExtrmc[i];
+      u.resize( 2*m_ndof_NodalExtrm*ncomp, large );
+      p.resize( 2*m_ndof_NodalExtrm*nprim, large );
+
+      // Initialize the minimum nodal extrema
+      for(std::size_t idof=0; idof<m_ndof_NodalExtrm; idof++)
+      {
+        for(std::size_t k = 0; k < ncomp; k++)
+          u[2*k*m_ndof_NodalExtrm+2*idof] = -large;
+        for(std::size_t k = 0; k < nprim; k++)
+          p[2*k*m_ndof_NodalExtrm+2*idof] = -large;
+      }
+    }
+  }
+}
+
+void DG::evalNodalExtrmRefEl(
+  const std::size_t ncomp,
+  const std::size_t nprim,
+  const std::size_t ndof_NodalExtrm,
+  const std::vector< std::size_t >& bndel,
+  const std::vector< std::size_t >& inpoel,
+  const std::vector< std::size_t >& gid,
+  const std::unordered_map< std::size_t, std::size_t >& bid,
+  const tk::Fields& U,
+  const tk::Fields& P,
+  std::vector< std::vector<tk::real> >& uNodalExtrm,
+  std::vector< std::vector<tk::real> >& pNodalExtrm )
+// *****************************************************************************
+//  Compute the nodal extrema of ref el derivatives for chare-boundary nodes
+//! \param[in] ncomp Number of conservative variables
+//! \param[in] nprim Number of primitive variables
+//! \param[in] ndof_NodalExtrm Degree of freedom for nodal extrema
+//! \param[in] bndel List of elements contributing to chare-boundary nodes
+//! \param[in] inpoel Element-node connectivity for element e
+//! \param[in] gid Local->global node id map
+//! \param[in] bid Local chare-boundary node ids (value) associated to
+//!   global node ids (key)
+//! \param[in] U Vector of conservative variables
+//! \param[in] P Vector of primitive variables
+//! \param[in,out] uNodalExtrm Chare-boundary nodal extrema for conservative
+//!   variables
+//! \param[in,out] pNodalExtrm Chare-boundary nodal extrema for primitive
+//!   variables
+// *****************************************************************************
+{
+  const auto rdof = g_inputdeck.get< tag::rdof >();
+
+  for (auto e : bndel)
+  {
+    // access node IDs
+    const std::vector<std::size_t> N
+      { inpoel[e*4+0], inpoel[e*4+1], inpoel[e*4+2], inpoel[e*4+3] };
+
+    // Loop over nodes of element e
+    for(std::size_t ip=0; ip<4; ++ip)
+    {
+      auto i = bid.find( gid[N[ip]] );
+      if (i != end(bid))      // If ip is the chare boundary point
+      {
+        // If DG(P2) is applied, find the nodal extrema of the gradients of
+        // conservative/primitive variables in the reference element
+
+        // Vector used to store the first order derivatives for both
+        // conservative and primitive variables
+        std::vector< std::array< tk::real, 3 > > gradc(ncomp, {0.0, 0.0, 0.0});
+        std::vector< std::array< tk::real, 3 > > gradp(ncomp, {0.0, 0.0, 0.0});
+
+        // Derivatives of the Dubiner basis
+        std::array< tk::real, 3 > center {{0.25, 0.25, 0.25}};
+        auto dBdxi = tk::eval_dBdxi(rdof, center);
+
+        // Evaluate the first order derivative
+        for(std::size_t icomp = 0; icomp < ncomp; icomp++)
+        {
+          auto mark = icomp * rdof;
+          for(std::size_t idir = 0; idir < 3; idir++)
+          {
+            gradc[icomp][idir] = 0;
+            for(std::size_t idof = 1; idof < rdof; idof++)
+              gradc[icomp][idir] += U(e, mark+idof) * dBdxi[idir][idof];
+          }
+        }
+        for(std::size_t icomp = 0; icomp < nprim; icomp++)
+        {
+          auto mark = icomp * rdof;
+          for(std::size_t idir = 0; idir < 3; idir++)
+          {
+            gradp[icomp][idir] = 0;
+            for(std::size_t idof = 1; idof < rdof; idof++)
+              gradp[icomp][idir] += P(e, mark+idof) * dBdxi[idir][idof];
+          }
+        }
+
+        // Store the extrema for the gradients
+        for (std::size_t c=0; c<ncomp; ++c)
+        {
+          for (std::size_t idof = 0; idof < ndof_NodalExtrm; idof++)
+          {
+            auto max_mark = 2*c*m_ndof_NodalExtrm + 2*idof;
+            auto min_mark = max_mark + 1;
+            auto& ex = uNodalExtrm[i->second];
+            ex[max_mark] = std::max(ex[max_mark], gradc[c][idof]);
+            ex[min_mark] = std::min(ex[min_mark], gradc[c][idof]);
+          }
+        }
+        for (std::size_t c=0; c<nprim; ++c)
+        {
+          for (std::size_t idof = 0; idof < ndof_NodalExtrm; idof++)
+          {
+            auto max_mark = 2*c*m_ndof_NodalExtrm + 2*idof;
+            auto min_mark = max_mark + 1;
+            auto& ex = pNodalExtrm[i->second];
+            ex[max_mark] = std::max(ex[max_mark], gradp[c][idof]);
+            ex[min_mark] = std::min(ex[min_mark], gradp[c][idof]);
+          }
+        }
+      }
+    }
+  }
+}
+
+void
+DG::lim()
+// *****************************************************************************
+// Compute limiter function
+// *****************************************************************************
+{
+  auto d = Disc();
+  const auto rdof = g_inputdeck.get< tag::rdof >();
+  const auto ncomp = m_u.nprop() / rdof;
+  const auto nprim = m_p.nprop() / rdof;
+
+  // Combine own and communicated contributions to nodal extrema
+  for (const auto& [gid,g] : m_uNodalExtrmc) {
+    auto bid = tk::cref_find( d->Bid(), gid );
+    for (ncomp_t c=0; c<ncomp; ++c)
+    {
+      for(std::size_t idof=0; idof<m_ndof_NodalExtrm; idof++)
+      {
+        auto max_mark = 2*c*m_ndof_NodalExtrm + 2*idof;
+        auto min_mark = max_mark + 1;
+        m_uNodalExtrm[bid][max_mark] =
+          std::max(g[max_mark], m_uNodalExtrm[bid][max_mark]);
+        m_uNodalExtrm[bid][min_mark] =
+          std::min(g[min_mark], m_uNodalExtrm[bid][min_mark]);
+      }
+    }
+  }
+  for (const auto& [gid,g] : m_pNodalExtrmc) {
+    auto bid = tk::cref_find( d->Bid(), gid );
+    for (ncomp_t c=0; c<nprim; ++c)
+    {
+      for(std::size_t idof=0; idof<m_ndof_NodalExtrm; idof++)
+      {
+        auto max_mark = 2*c*m_ndof_NodalExtrm + 2*idof;
+        auto min_mark = max_mark + 1;
+        m_pNodalExtrm[bid][max_mark] =
+          std::max(g[max_mark], m_pNodalExtrm[bid][max_mark]);
+        m_pNodalExtrm[bid][min_mark] =
+          std::min(g[min_mark], m_pNodalExtrm[bid][min_mark]);
+      }
+    }
+  }
+
+  // clear gradients receive buffer
+  tk::destroy(m_uNodalExtrmc);
+  tk::destroy(m_pNodalExtrmc);
+
+  if (rdof > 1) {
+    g_dgpde[d->MeshId()].limit( d->T(), myGhosts()->m_geoFace, myGhosts()->m_geoElem,
+              myGhosts()->m_fd, myGhosts()->m_esup, myGhosts()->m_inpoel,
+              myGhosts()->m_coord, m_ndof, d->Gid(), d->Bid(), m_uNodalExtrm,
+              m_pNodalExtrm, m_mtInv, m_u, m_p, m_shockmarker );
+
+    if (g_inputdeck.get< tag::limsol_projection >())
+      g_dgpde[d->MeshId()].CPL(m_p, myGhosts()->m_geoElem,
+        myGhosts()->m_inpoel, myGhosts()->m_coord, m_u,
+        myGhosts()->m_fd.Esuel().size()/4);
+  }
+
+  // Send limited solution to neighboring chares
+  if (myGhosts()->m_sendGhost.empty())
+    comlim_complete();
+  else
+    for(const auto& [cid, ghostdata] : myGhosts()->m_sendGhost) {
+      std::vector< std::size_t > tetid( ghostdata.size() );
+      std::vector< std::vector< tk::real > > u( ghostdata.size() ),
+                                             prim( ghostdata.size() );
+      std::vector< std::size_t > ndof;<--- Unused variable: ndof
+      std::size_t j = 0;
+      for(const auto& i : ghostdata) {
+        Assert( i < myGhosts()->m_fd.Esuel().size()/4,
+          "Sending limiter ghost data" );
+        tetid[j] = i;
+        u[j] = m_u[i];
+        prim[j] = m_p[i];
+        ++j;
+      }
+      thisProxy[ cid ].comlim( thisIndex, tetid, u, prim );
+    }
+
+  ownlim_complete();
+}
+
+void
+DG::refine_ndof()
+// *****************************************************************************
+//  p-refine all elements that are adjacent to p-refined elements
+//! \details This function p-refines all the neighbors of an element that has
+//!   been p-refined as a result of an error indicator.
+// *****************************************************************************
+{
+  auto d = Disc();
+  const auto& inpoel = d->Inpoel();
+  const auto npoin = d->Coord()[0].size();
+  const auto nelem = myGhosts()->m_fd.Esuel().size()/4;
+  std::vector<std::size_t> node_ndof(npoin, 1);
+
+  // Mark the max ndof for each node and store in node_ndof
+  for(std::size_t ip=0; ip<npoin; ip++)
+  {
+    const auto& pesup = tk::cref_find(myGhosts()->m_esup, ip);
+    for(auto er : pesup)
+      node_ndof[ip] = std::max(m_ndof[er], node_ndof[ip]);
+  }
+
+  for(std::size_t e = 0; e < nelem; e++)
+  {
+    // Find if any node of this element has p1/p2 ndofs
+    std::size_t counter_p2(0);
+    std::size_t counter_p1(0);
+    for(std::size_t inode = 0; inode < 4; inode++)
+    {
+      auto node = inpoel[4*e+inode];
+      if(node_ndof[node] == 10)
+        counter_p2++;
+      else if (node_ndof[node] == 4)
+        counter_p1++;
+    }
+
+    // If there is at least one node with p1/p2 ndofs, all of the elements
+    // around this node are refined to p1/p2.
+    if(counter_p2 > 0 && m_ndof[e] < 10)
+    {
+      if(m_ndof[e] == 4)
+        m_ndof[e] = 10;
+      if(m_ndof[e] == 1)
+        m_ndof[e] = 4;
+    }
+    else if(counter_p1 > 0 && m_ndof[e] < 4)
+      m_ndof[e] = 4;
+  }
+}
+
+void DG::smooth_ndof()
+// *****************************************************************************
+//  Smooth the refined ndof distribution to avoid zigzag refinement
+// *****************************************************************************
+{
+  auto d = Disc();
+  const auto& inpoel = d->Inpoel();
+  const auto npoin = d->Coord()[0].size();
+  const auto nelem = myGhosts()->m_fd.Esuel().size()/4;
+  std::vector<std::size_t> node_ndof(npoin, 1);
+
+  // Mark the max ndof for each node and store in node_ndof
+  for(std::size_t ip=0; ip<npoin; ip++)
+  {
+    const auto& pesup = tk::cref_find(myGhosts()->m_esup, ip);
+    for(auto er : pesup)
+      node_ndof[ip] = std::max(m_ndof[er], node_ndof[ip]);
+  }
+
+  for(std::size_t e = 0; e < nelem; e++)
+  {
+    // Find if any node of this element has p1/p2 ndofs
+    std::size_t counter_p2(0);
+    std::size_t counter_p1(0);
+    for(std::size_t inode = 0; inode < 4; inode++)
+    {
+      auto node = inpoel[4*e+inode];
+      if(node_ndof[node] == 10)
+        counter_p2++;
+      else if (node_ndof[node] == 4)
+        counter_p1++;
+    }
+
+    // If all the nodes in the element are p1/p2, this element is refined to
+    // p1/p2.
+    if(counter_p2 == 4 && m_ndof[e] == 4)
+      m_ndof[e] = 10;
+    else if(counter_p1 == 4 && m_ndof[e] == 1)
+      m_ndof[e] = 4;
+  }
+}
+
+void
+DG::comlim( int fromch,
+            const std::vector< std::size_t >& tetid,
+            const std::vector< std::vector< tk::real > >& u,
+            const std::vector< std::vector< tk::real > >& prim )
+// *****************************************************************************
+//  Receive chare-boundary limiter ghost data from neighboring chares
+//! \param[in] fromch Sender chare id
+//! \param[in] tetid Ghost tet ids we receive solution data for
+//! \param[in] u Limited high-order solution
+//! \param[in] prim Limited high-order primitive quantities
+//! \details This function receives contributions to the limited solution from
+//!   fellow chares.
+// *****************************************************************************
+{
+  Assert( u.size() == tetid.size(), "Size mismatch in DG::comlim()" );
+  Assert( prim.size() == tetid.size(), "Size mismatch in DG::comlim()" );
+
+  // Find local-to-ghost tet id map for sender chare
+  const auto& n = tk::cref_find( myGhosts()->m_ghost, fromch );
+
+  for (std::size_t i=0; i<tetid.size(); ++i) {
+    auto j = tk::cref_find( n, tetid[i] );
+    Assert( j >= myGhosts()->m_fd.Esuel().size()/4,
+      "Receiving solution non-ghost data" );
+    auto b = tk::cref_find( myGhosts()->m_bid, j );
+    Assert( b < m_uc[2].size(), "Indexing out of bounds" );
+    Assert( b < m_pc[2].size(), "Indexing out of bounds" );
+    m_uc[2][b] = u[i];
+    m_pc[2][b] = prim[i];
+  }
+
+  // if we have received all solution ghost contributions from neighboring
+  // chares (chares we communicate along chare-boundary faces with), and
+  // contributed our solution to these neighbors, proceed to limiting
+  if (++m_nlim == myGhosts()->m_sendGhost.size()) {
+    m_nlim = 0;
+    comlim_complete();
+  }
+}
+
+void
+DG::dt()
+// *****************************************************************************
+// Compute time step size
+// *****************************************************************************
+{
+  auto d = Disc();
+
+  // Combine own and communicated contributions of limited solution and degrees
+  // of freedom in cells (if p-adaptive)
+  for (const auto& b : myGhosts()->m_bid) {
+    Assert( m_uc[2][b.second].size() == m_u.nprop(), "ncomp size mismatch" );
+    Assert( m_pc[2][b.second].size() == m_p.nprop(), "ncomp size mismatch" );
+    for (std::size_t c=0; c<m_u.nprop(); ++c) {
+      m_u(b.first,c) = m_uc[2][b.second][c];
+    }
+    for (std::size_t c=0; c<m_p.nprop(); ++c) {
+      m_p(b.first,c) = m_pc[2][b.second][c];
+    }
+  }
+
+  auto mindt = std::numeric_limits< tk::real >::max();
+
+  if (m_stage == 0)
+  {
+    auto const_dt = g_inputdeck.get< tag::dt >();
+    auto eps = std::numeric_limits< tk::real >::epsilon();
+
+    // use constant dt if configured
+    if (std::abs(const_dt) > eps) {
+
+      mindt = const_dt;
+
+    } else {      // compute dt based on CFL
+
+      // find the minimum dt across all PDEs integrated
+      auto eqdt =
+        g_dgpde[d->MeshId()].dt( myGhosts()->m_coord, myGhosts()->m_inpoel,
+          myGhosts()->m_fd,
+          myGhosts()->m_geoFace, myGhosts()->m_geoElem, m_ndof, m_u, m_p,
+          myGhosts()->m_fd.Esuel().size()/4 );
+      if (eqdt < mindt) mindt = eqdt;
+
+      mindt *= g_inputdeck.get< tag::cfl >();
+    }
+  }
+  else
+  {
+    mindt = d->Dt();
+  }
+
+  // Resize the buffer vector of nodal extrema
+  resizeNodalExtremac();
+
+  // Contribute to minimum dt across all chares then advance to next step
+  contribute( sizeof(tk::real), &mindt, CkReduction::min_double,
+              CkCallback(CkReductionTarget(DG,solve), thisProxy) );
+}
+
+void
+DG::solve( tk::real newdt )
+// *****************************************************************************
+// Compute right-hand side of discrete transport equations
+//! \param[in] newdt Size of this new time step
+// *****************************************************************************
+{
+  // Enable SDAG wait for building the solution vector during the next stage
+  thisProxy[ thisIndex ].wait4sol();
+  thisProxy[ thisIndex ].wait4refine();
+  thisProxy[ thisIndex ].wait4smooth();
+  thisProxy[ thisIndex ].wait4reco();
+  thisProxy[ thisIndex ].wait4nodalExtrema();
+  thisProxy[ thisIndex ].wait4lim();
+  thisProxy[ thisIndex ].wait4nod();
+
+  auto d = Disc();
+  const auto rdof = g_inputdeck.get< tag::rdof >();
+  const auto ndof = g_inputdeck.get< tag::ndof >();
+  const auto neq = m_u.nprop()/rdof;
+
+  // Set new time step size
+  if (m_stage == 0) d->setdt( newdt );
+
+  const auto pref = g_inputdeck.get< tag::pref, tag::pref >();
+  if (pref && m_stage == 0)
+  {
+    // When the element are coarsened, high order terms should be zero
+    for(std::size_t e = 0; e < myGhosts()->m_nunk; e++)
+    {
+      const auto ncomp= m_u.nprop()/rdof;
+      if(m_ndof[e] == 1)
+      {
+        for (std::size_t c=0; c<ncomp; ++c)
+        {
+          auto mark = c*rdof;
+          m_u(e, mark+1) = 0.0;
+          m_u(e, mark+2) = 0.0;
+          m_u(e, mark+3) = 0.0;
+        }
+      } else if(m_ndof[e] == 4)
+      {
+        for (std::size_t c=0; c<ncomp; ++c)
+        {
+          auto mark = c*ndof;
+          m_u(e, mark+4) = 0.0;
+          m_u(e, mark+5) = 0.0;
+          m_u(e, mark+6) = 0.0;
+          m_u(e, mark+7) = 0.0;
+          m_u(e, mark+8) = 0.0;
+          m_u(e, mark+9) = 0.0;
+        }
+      }
+    }
+  }
+
+  // Update Un
+  if (m_stage == 0) m_un = m_u;
+
+  // Explicit or IMEX
+  const auto imex_runge_kutta = g_inputdeck.get< tag::imex_runge_kutta >();
+
+  // physical time at time-stage for computing exact source terms
+  tk::real physT(d->T());
+  if (m_stage == 1) {
+    physT += d->Dt();
+  }
+  else if (m_stage == 2) {
+    physT += 0.5*d->Dt();
+  }
+
+  if (imex_runge_kutta) {
+    if (m_stage == 0)
+    {
+      // Save previous rhs
+      m_rhsprev = m_rhs;
+      // Initialize m_stiffrhs to zero
+      m_stiffrhs.fill(0.0);
+      m_stiffrhsprev.fill(0.0);
+    }
+  }
+
+  g_dgpde[d->MeshId()].rhs( physT, myGhosts()->m_geoFace, myGhosts()->m_geoElem,
+    myGhosts()->m_fd, myGhosts()->m_inpoel, m_boxelems, myGhosts()->m_coord,
+    m_u, m_p, m_ndof, m_rho0mat, d->Dt(), m_rhs );
+
+  if (!imex_runge_kutta) {
+    // Explicit time-stepping using RK3 to discretize time-derivative
+    for(std::size_t e=0; e<myGhosts()->m_nunk; ++e)
+      for(std::size_t c=0; c<neq; ++c)
+      {
+        for (std::size_t k=0; k<m_numEqDof[c]; ++k)
+        {
+          auto rmark = c*rdof+k;
+          auto mark = c*ndof+k;
+          m_u(e, rmark) =  rkcoef[0][m_stage] * m_un(e, rmark)
+            + rkcoef[1][m_stage] * ( m_u(e, rmark)
+              + d->Dt() * m_rhs(e, mark)/m_lhs(e, mark) );
+          if(fabs(m_u(e, rmark)) < 1e-16)
+            m_u(e, rmark) = 0;
+        }
+      }
+  }
+  else {
+    // Implicit-Explicit time-stepping using RK3 to discretize time-derivative
+    DG::imex_integrate();
+  }
+
+  for(std::size_t e=0; e<myGhosts()->m_nunk; ++e)
+    for(std::size_t c=0; c<neq; ++c)
+    {
+      // zero out unused/reconstructed dofs of equations using reduced dofs
+      // (see DGMultiMat::numEquationDofs())
+      if (m_numEqDof[c] < rdof) {
+        for (std::size_t k=m_numEqDof[c]; k<rdof; ++k)
+        {
+          auto rmark = c*rdof+k;
+          m_u(e, rmark) = 0.0;
+        }
+      }
+    }
+
+  // Update primitives based on the evolved solution
+  g_dgpde[d->MeshId()].updateInterfaceCells( m_u,
+    myGhosts()->m_fd.Esuel().size()/4, m_ndof );
+  g_dgpde[d->MeshId()].updatePrimitives( m_u, m_lhs, myGhosts()->m_geoElem, m_p,
+    myGhosts()->m_fd.Esuel().size()/4 );
+  if (!g_inputdeck.get< tag::accuracy_test >()) {
+    g_dgpde[d->MeshId()].cleanTraceMaterial( physT, myGhosts()->m_geoElem, m_u,
+      m_p, myGhosts()->m_fd.Esuel().size()/4 );
+  }
+
+  if (m_stage < 2) {
+
+    // continue with next time step stage
+    stage();
+
+  } else {
+
+    // Increase number of iterations and physical time
+    d->next();
+
+    // Compute diagnostics, e.g., residuals
+    auto diag_computed = m_diag.compute( *d,
+      m_u.nunk()-myGhosts()->m_fd.Esuel().size()/4, myGhosts()->m_geoElem,
+      m_ndof, m_u, m_un );
+
+    // Continue to mesh refinement (if configured)
+    if (!diag_computed) refine( std::vector< tk::real >( m_u.nprop(), 0.0 ) );
+
+  }
+}
+
+void
+DG::refine( [[maybe_unused]] const std::vector< tk::real >& l2res )
+// *****************************************************************************
+// Optionally refine/derefine mesh
+//! \param[in] l2res L2-norms of the residual for each scalar component
+//!   computed across the whole problem
+// *****************************************************************************
+{
+  auto d = Disc();
+
+  auto dtref = g_inputdeck.get< tag::amr, tag::dtref >();
+  auto dtfreq = g_inputdeck.get< tag::amr, tag::dtfreq >();
+
+  // if t>0 refinement enabled and we hit the dtref frequency
+  if (dtref && !(d->It() % dtfreq)) {   // refine
+
+    d->startvol();
+    d->Ref()->dtref( myGhosts()->m_fd.Bface(), {},
+      tk::remap(myGhosts()->m_fd.Triinpoel(),d->Gid()) );
+    d->refined() = 1;
+
+  } else {      // do not refine
+
+    d->refined() = 0;
+    stage();
+
+  }
+}
+
+void
+DG::resizePostAMR(
+  const std::vector< std::size_t >& /*ginpoel*/,
+  const tk::UnsMesh::Chunk& chunk,
+  const tk::UnsMesh::Coords& coord,
+  const std::unordered_map< std::size_t, tk::UnsMesh::Edge >& /*addedNodes*/,
+  const std::unordered_map< std::size_t, std::size_t >& addedTets,
+  const std::set< std::size_t >& removedNodes,
+  const std::unordered_map< std::size_t, std::size_t >& amrNodeMap,
+  const tk::NodeCommMap& nodeCommMap,
+  const std::map< int, std::vector< std::size_t > >& bface,
+  const std::map< int, std::vector< std::size_t > >& /* bnode */,
+  const std::vector< std::size_t >& triinpoel,
+  const std::unordered_map< std::size_t, std::set< std::size_t > >& elemblockid )
+// *****************************************************************************
+//  Receive new mesh from Refiner
+//! \param[in] chunk New mesh chunk (connectivity and global<->local id maps)
+//! \param[in] coord New mesh node coordinates
+//! \param[in] addedTets Newly added mesh cells and their parents (local ids)
+//! \param[in] removedNodes Newly removed mesh node local ids
+//! \param[in] amrNodeMap Node id map after amr (local ids)
+//! \param[in] nodeCommMap New node communication map
+//! \param[in] bface Boundary-faces mapped to side set ids
+//! \param[in] triinpoel Boundary-face connectivity
+//! \param[in] elemblockid Local tet ids associated with mesh block ids
+// *****************************************************************************
+{
+  auto d = Disc();
+
+  // Set flag that indicates that we are during time stepping
+  m_initial = 0;
+  myGhosts()->m_initial = 0;
+
+  // Zero field output iteration count between two mesh refinement steps
+  d->Itf() = 0;
+
+  // Increase number of iterations with mesh refinement
+  ++d->Itr();
+
+  // Save old number of elements
+  [[maybe_unused]] auto old_nelem = myGhosts()->m_inpoel.size()/4;
+
+  // Resize mesh data structures
+  d->resizePostAMR( chunk, coord, amrNodeMap, nodeCommMap, removedNodes,
+    elemblockid );
+
+  // Update state
+  myGhosts()->m_inpoel = d->Inpoel();
+  myGhosts()->m_coord = d->Coord();
+  auto nelem = myGhosts()->m_inpoel.size()/4;
+  m_p.resize( nelem );
+  m_u.resize( nelem );
+  m_un.resize( nelem );
+  m_lhs.resize( nelem );
+  m_rhs.resize( nelem );
+  m_rhsprev.resize( nelem );
+  m_stiffrhs.resize( nelem );
+  m_stiffrhsprev.resize( nelem );
+  m_uNodalExtrm.resize( Disc()->Bid().size(), std::vector<tk::real>( 2*
+    m_ndof_NodalExtrm*g_inputdeck.get< tag::ncomp >() ) );
+  m_pNodalExtrm.resize( Disc()->Bid().size(), std::vector<tk::real>( 2*
+    m_ndof_NodalExtrm*m_p.nprop()/g_inputdeck.get< tag::rdof >()));
+
+  // Resize the buffer vector of nodal extrema
+  resizeNodalExtremac();
+
+  myGhosts()->m_fd = FaceData( myGhosts()->m_inpoel, bface,
+    tk::remap(triinpoel,d->Lid()) );
+
+  myGhosts()->m_geoFace =
+    tk::Fields( tk::genGeoFaceTri( myGhosts()->m_fd.Nipfac(),
+    myGhosts()->m_fd.Inpofa(), coord ) );
+  myGhosts()->m_geoElem = tk::Fields( tk::genGeoElemTet( myGhosts()->m_inpoel,
+    coord ) );
+
+  myGhosts()->m_nfac = myGhosts()->m_fd.Inpofa().size()/3;
+  myGhosts()->m_nunk = nelem;
+  m_npoin = coord[0].size();
+  myGhosts()->m_bndFace.clear();
+  myGhosts()->m_exptGhost.clear();
+  myGhosts()->m_sendGhost.clear();
+  myGhosts()->m_ghost.clear();
+  myGhosts()->m_esup.clear();
+
+  // Update solution on new mesh, P0 (cell center value) only for now
+  m_un = m_u;
+  auto pn = m_p;<--- Variable 'pn' is assigned a value that is never used.
+  auto unprop = m_u.nprop();<--- Variable 'unprop' is assigned a value that is never used.
+  auto pnprop = m_p.nprop();<--- Variable 'pnprop' is assigned a value that is never used.
+  for (const auto& [child,parent] : addedTets) {
+    Assert( child < nelem, "Indexing out of new solution vector" );
+    Assert( parent < old_nelem, "Indexing out of old solution vector" );
+    for (std::size_t i=0; i<unprop; ++i) m_u(child,i) = m_un(parent,i);
+    for (std::size_t i=0; i<pnprop; ++i) m_p(child,i) = pn(parent,i);
+  }
+  m_un = m_u;
+
+  // Resize communication buffers
+  m_ghosts[thisIndex].resizeComm();
+}
+
+bool
+DG::fieldOutput() const
+// *****************************************************************************
+// Decide wether to output field data
+//! \return True if field data is output in this step
+// *****************************************************************************
+{
+  auto d = Disc();
+
+  // Output field data
+  return d->fielditer() or d->fieldtime() or d->fieldrange() or d->finished();
+}
+
+bool
+DG::refinedOutput() const
+// *****************************************************************************
+// Decide if we write field output using a refined mesh
+//! \return True if field output will use a refined mesh
+// *****************************************************************************
+{
+  return g_inputdeck.get< tag::field_output, tag::refined >() &&
+         g_inputdeck.get< tag::scheme >() != ctr::SchemeType::DG;
+}
+
+void
+DG::writeFields(
+  CkCallback c,
+  const std::unordered_map< std::size_t, std::size_t >& addedTets )
+// *****************************************************************************
+// Output mesh field data
+//! \param[in] c Function to continue with after the write
+//! \param[in] addedTets Newly added mesh cells and their parents (local ids)
+// *****************************************************************************
+{
+  auto d = Disc();
+
+  const auto& inpoel = std::get< 0 >( m_outmesh.chunk );
+  auto esup = tk::genEsup( inpoel, 4 );
+  auto nelem = inpoel.size() / 4;
+
+  // Combine own and communicated contributions and finish averaging of node
+  // field output in chare boundary nodes
+  const auto& lid = std::get< 2 >( m_outmesh.chunk );
+  for (const auto& [g,f] : m_uNodefieldsc) {
+    Assert( m_uNodefields.nprop() == f.first.size(), "Size mismatch" );
+    auto p = tk::cref_find( lid, g );
+    for (std::size_t i=0; i<f.first.size(); ++i) {
+      m_uNodefields(p,i) += f.first[i];
+      m_uNodefields(p,i) /= static_cast< tk::real >(
+                              esup.second[p+1] - esup.second[p] + f.second );
+    }
+  }
+  tk::destroy( m_uNodefieldsc );
+  for (const auto& [g,f] : m_pNodefieldsc) {
+    Assert( m_pNodefields.nprop() == f.first.size(), "Size mismatch" );
+    auto p = tk::cref_find( lid, g );
+    for (std::size_t i=0; i<f.first.size(); ++i) {
+      m_pNodefields(p,i) += f.first[i];
+      m_pNodefields(p,i) /= static_cast< tk::real >(
+                              esup.second[p+1] - esup.second[p] + f.second );
+    }
+  }
+  tk::destroy( m_pNodefieldsc );
+
+  // Lambda to decide if a node (global id) is on a chare boundary of the field
+  // output mesh. p - global node id, return true if node is on the chare
+  // boundary.
+  auto chbnd = [ this ]( std::size_t p ) {
+    return
+      std::any_of( m_outmesh.nodeCommMap.cbegin(), m_outmesh.nodeCommMap.cend(),
+        [&](const auto& s) { return s.second.find(p) != s.second.cend(); } );
+  };
+
+  // Finish computing node field output averages in internal nodes
+  auto npoin = m_outmesh.coord[0].size();
+  auto& gid = std::get< 1 >( m_outmesh.chunk );
+  for (std::size_t p=0; p<npoin; ++p) {
+    if (!chbnd(gid[p])) {
+      auto n = static_cast< tk::real >( esup.second[p+1] - esup.second[p] );
+      for (std::size_t i=0; i<m_uNodefields.nprop(); ++i)
+        m_uNodefields(p,i) /= n;
+      for (std::size_t i=0; i<m_pNodefields.nprop(); ++i)
+        m_pNodefields(p,i) /= n;
+    }
+  }
+
+  // Collect field output from numerical solution requested by user
+  auto elemfields = numericFieldOutput( m_uElemfields, tk::Centering::ELEM,
+    g_dgpde[Disc()->MeshId()].OutVarFn(), m_pElemfields );
+  auto nodefields = numericFieldOutput( m_uNodefields, tk::Centering::NODE,
+    g_dgpde[Disc()->MeshId()].OutVarFn(), m_pNodefields );
+
+  // Collect field output from analytical solutions (if exist)
+  const auto& coord = m_outmesh.coord;
+  auto geoElem = tk::genGeoElemTet( inpoel, coord );
+  auto t = Disc()->T();
+  analyticFieldOutput( g_dgpde[d->MeshId()], tk::Centering::ELEM,
+    geoElem.extract_comp(1), geoElem.extract_comp(2), geoElem.extract_comp(3),
+    t, elemfields );
+  analyticFieldOutput( g_dgpde[d->MeshId()], tk::Centering::NODE, coord[0],
+    coord[1], coord[2], t, nodefields );
+
+  // Add adaptive indicator array to element-centered field output
+  if (g_inputdeck.get< tag::pref, tag::pref >()) {
+    std::vector< tk::real > ndof( begin(m_ndof), end(m_ndof) );
+    ndof.resize( nelem );
+    for (const auto& [child,parent] : addedTets)
+      ndof[child] = static_cast< tk::real >( m_ndof[parent] );
+    elemfields.push_back( ndof );
+  }
+
+  // Add shock detection marker array to element-centered field output
+  std::vector< tk::real > shockmarker( begin(m_shockmarker), end(m_shockmarker) );
+  // Here m_shockmarker has a size of m_u.nunk() which is the number of the
+  // elements within this partition (nelem) plus the ghost partition cells. In
+  // terms of output purpose, we only need the solution data within this
+  // partition. Therefore, resizing it to nelem removes the extra partition
+  // boundary allocations in the shockmarker vector. Since the code assumes that
+  // the boundary elements are on the top, the resize operation keeps the lower
+  // portion.
+  shockmarker.resize( nelem );
+  for (const auto& [child,parent] : addedTets)
+    shockmarker[child] = static_cast< tk::real >(m_shockmarker[parent]);
+  elemfields.push_back( shockmarker );
+
+  // Add rho0*det(g)/rho to make sure it is staying close to 1,
+  // averaged for all materials
+  std::vector< tk::real > densityConstr(nelem);
+  g_dgpde[d->MeshId()].computeDensityConstr(nelem, m_u, m_rho0mat,
+                                            densityConstr);
+  for (const auto& [child,parent] : addedTets)
+    densityConstr[child] = 0.0;
+  if (densityConstr.size() > 0) elemfields.push_back( densityConstr );
+
+  // Query fields names requested by user
+  auto elemfieldnames = numericFieldNames( tk::Centering::ELEM );
+  auto nodefieldnames = numericFieldNames( tk::Centering::NODE );
+
+  // Collect field output names for analytical solutions
+  analyticFieldNames( g_dgpde[d->MeshId()], tk::Centering::ELEM, elemfieldnames );
+  analyticFieldNames( g_dgpde[d->MeshId()], tk::Centering::NODE, nodefieldnames );
+
+  if (g_inputdeck.get< tag::pref, tag::pref >())
+    elemfieldnames.push_back( "NDOF" );
+
+  elemfieldnames.push_back( "shock_marker" );
+
+  if (densityConstr.size() > 0)
+    elemfieldnames.push_back( "density_constraint" );
+
+  Assert( elemfieldnames.size() == elemfields.size(), "Size mismatch" );
+  Assert( nodefieldnames.size() == nodefields.size(), "Size mismatch" );
+
+  // Output chare mesh and fields metadata to file
+  const auto& triinpoel = m_outmesh.triinpoel;
+  d->write( inpoel, m_outmesh.coord, m_outmesh.bface, {},
+            tk::remap( triinpoel, lid ), elemfieldnames, nodefieldnames,
+            {}, {}, elemfields, nodefields, {}, {}, c );
+}
+
+void
+DG::comnodeout( const std::vector< std::size_t >& gid,
+                const std::vector< std::size_t >& nesup,
+                const std::vector< std::vector< tk::real > >& Lu,
+                const std::vector< std::vector< tk::real > >& Lp )
+// *****************************************************************************
+//  Receive chare-boundary nodal solution (for field output) contributions from
+//  neighboring chares
+//! \param[in] gid Global mesh node IDs at which we receive contributions
+//! \param[in] nesup Number of elements surrounding points
+//! \param[in] Lu Partial contributions of solution nodal fields to
+//!   chare-boundary nodes
+//! \param[in] Lp Partial contributions of primitive quantity nodal fields to
+//!   chare-boundary nodes
+// *****************************************************************************
+{
+  Assert( gid.size() == nesup.size(), "Size mismatch" );
+  Assert(Lu.size() == m_uNodefields.nprop(), "Fields size mismatch");
+  Assert(Lp.size() == m_pNodefields.nprop(), "Fields size mismatch");
+  for (std::size_t f=0; f<Lu.size(); ++f)
+    Assert( gid.size() == Lu[f].size(), "Size mismatch" );
+  for (std::size_t f=0; f<Lp.size(); ++f)
+    Assert( gid.size() == Lp[f].size(), "Size mismatch" );
+
+  for (std::size_t i=0; i<gid.size(); ++i) {
+    auto& nfu = m_uNodefieldsc[ gid[i] ];
+    nfu.first.resize( Lu.size() );
+    for (std::size_t f=0; f<Lu.size(); ++f) nfu.first[f] += Lu[f][i];
+    nfu.second += nesup[i];
+    auto& nfp = m_pNodefieldsc[ gid[i] ];
+    nfp.first.resize( Lp.size() );
+    for (std::size_t f=0; f<Lp.size(); ++f) nfp.first[f] += Lp[f][i];
+    nfp.second += nesup[i];
+  }
+
+  // When we have heard from all chares we communicate with, this chare is done
+  if (++m_nnod == Disc()->NodeCommMap().size()) {
+    m_nnod = 0;
+    comnodeout_complete();
+  }
+}
+
+void
+DG::stage()
+// *****************************************************************************
+// Evaluate whether to continue with next time step stage
+// *****************************************************************************
+{
+  // Increment Runge-Kutta stage counter
+  ++m_stage;
+
+  // if not all Runge-Kutta stages complete, continue to next time stage,
+  // otherwise prepare for nodal field output
+  if (m_stage < 3)
+    next();
+  else
+    startFieldOutput( CkCallback(CkIndex_DG::step(), thisProxy[thisIndex]) );
+}
+
+void
+DG::evalLB( int nrestart )
+// *****************************************************************************
+// Evaluate whether to do load balancing
+//! \param[in] nrestart Number of times restarted
+// *****************************************************************************
+{
+  auto d = Disc();
+
+  // Detect if just returned from a checkpoint and if so, zero timers
+  d->restarted( nrestart );
+
+  const auto lbfreq = g_inputdeck.get< tag::cmd, tag::lbfreq >();
+  const auto nonblocking = g_inputdeck.get< tag::cmd, tag::nonblocking >();
+
+  // Load balancing if user frequency is reached or after the second time-step
+  if ( (d->It()) % lbfreq == 0 || d->It() == 2 ) {
+
+    AtSync();
+    if (nonblocking) next();
+
+  } else {
+
+    next();
+
+  }
+}
+
+void
+DG::evalRestart()
+// *****************************************************************************
+// Evaluate whether to save checkpoint/restart
+// *****************************************************************************
+{
+  auto d = Disc();
+
+  const auto rsfreq = g_inputdeck.get< tag::cmd, tag::rsfreq >();
+  const auto benchmark = g_inputdeck.get< tag::cmd, tag::benchmark >();
+
+  if (not benchmark and not (d->It() % rsfreq)) {
+
+    std::vector< std::size_t > meshdata{ /* finished = */ 0, d->MeshId() };
+    contribute( meshdata, CkReduction::nop,
+      CkCallback(CkReductionTarget(Transporter,checkpoint), d->Tr()) );
+
+  } else {
+
+    evalLB( /* nrestart = */ -1 );
+
+  }
+}
+
+void
+DG::step()
+// *****************************************************************************
+// Evaluate wether to continue with next time step
+// *****************************************************************************
+{
+  auto d = Disc();
+
+  // Output time history
+  if (d->histiter() or d->histtime() or d->histrange()) {
+    std::vector< std::vector< tk::real > > hist;
+    auto h = g_dgpde[d->MeshId()].histOutput( d->Hist(), myGhosts()->m_inpoel,
+      myGhosts()->m_coord, m_u, m_p );
+    hist.insert( end(hist), begin(h), end(h) );
+    d->history( std::move(hist) );
+  }
+
+  // Free memory storing output mesh
+  m_outmesh.destroy();
+
+  // Output one-liner status report to screen
+  d->status();
+  // Reset Runge-Kutta stage counter
+  m_stage = 0;
+
+  const auto term = g_inputdeck.get< tag::term >();
+  const auto nstep = g_inputdeck.get< tag::nstep >();
+  const auto eps = std::numeric_limits< tk::real >::epsilon();
+
+  // If neither max iterations nor max time reached, continue, otherwise finish
+  if (std::fabs(d->T()-term) > eps && d->It() < nstep) {
+
+    evalRestart();
+ 
+  } else {
+
+    auto meshid = d->MeshId();
+    d->contribute( sizeof(std::size_t), &meshid, CkReduction::nop,
+                   CkCallback(CkReductionTarget(Transporter,finish), d->Tr()) );
+
+  }
+}
+
+void
+DG::imex_integrate()
+{
+  /*****************************************************************************
+  Performs the Implicit-Explicit Runge-Kutta step.
+
+  \details Performs the Implicit-Explicit Runge-Kutta step. Scheme taken from
+  Cavaglieri, D., & Bewley, T. (2015). Low-storage implicit/explicit Runge–Kutta
+  schemes for the simulation of stiff high-dimensional ODE systems. Journal of
+  Computational Physics, 286, 172-193.
+
+  Scheme given by equations (25a,b):
+
+  u[0] = u[n] + dt * (expl_rkcoef[1,0]*R_ex(u[n])+impl_rkcoef[1,1]*R_im(u[0]))
+
+  u[1] = u[n] + dt * (expl_rkcoef[2,1]*R_ex(u[0])+impl_rkcoef[2,1]*R_im(u[0])
+                                                 +impl_rkcoef[2,2]*R_im(u[1]))
+
+  u[n+1] = u[n] + dt * (expl_rkcoef[3,1]*R_ex(u[0])+impl_rkcoef[3,1]*R_im(u[0])
+                        expl_rkcoef[3,2]*R_ex(u[1])+impl_rkcoef[3,2]*R_im(u[1]))
+
+  In order to solve the first two equations we need to solve a series of systems
+  of non-linear equations:
+
+  F1(u[0]) = B1 + R1(u[0]) = 0, and
+  F2(u[1]) = B2 + R2(u[1]) = 0,
+
+  where
+
+  B1 = u[n] + dt * expl_rkcoef[1,0]*R_ex(u[n]),
+  R1 = dt * impl_rkcoef[1,1]*R_im(u[0]) - u([0]),
+  B2 = u[n] + dt * (expl_rkcoef[2,1]*R_ex(u[0])+impl_rkcoef[2,1]*R_im(u[0])),
+  R2 = dt * impl_rkcoef[2,2]*R_im(u[1]) - u([1]).
+
+  In order to solve the non-linear system F(U) = 0, we employ Broyden's method.
+  Taken from https://en.wikipedia.org/wiki/Broyden%27s_method.
+  The method consists in obtaining an approximation for the inverse of the
+  Jacobian H = J^(-1) and advancing in a quasi-newton step:
+
+  U[k+1] = U[k] - H[k]*F(U[k]),
+
+  until F(U) is close enough to zero.
+
+  The approximation H[k] is improved at every iteration following
+
+  H[k] = H[k-1] + (DU[k]-H[k-1]*DF[k])/(DU[k]^T*H[k-1]*DF[k]) * DU[k]^T*H[k-1],
+
+  where DU[k] = U[k] - U[k-1] and DF[k] = F(U[k]) - F(U[k-1)).
+
+  This function performs the following main algorithmic steps:
+  - If stage == 0 or stage == 1:
+    - Take Initial value:
+      U[0] = U[n] + dt * expl_rkcoef[1,0]*R_ex(U[n]) (for stage 0)
+      U[1] = U[n] + dt * (expl_rkcoef[2,1]*R_ex(U[0])
+                         +impl_rkcoef[2,1]*R_im(U[0])) (for stage 1)
+    - Loop over the Elements (e++)
+      - Initialize Jacobian inverse approximation as the identity
+      - Compute implicit right-hand-side (F_im) with current U
+      - Iterate for the solution (iter++)
+        - Compute new solution U[k+1] = U[k] - H[k]*F(U[k])
+        - Compute implicit right-hand-side (F_im) with current U
+        - Compute DU and DF
+        - Update inverse Jacobian approximation by:
+          - Compute V1 = H[k-1]*DF[k] and V2 = DU[k]^T*H[k-1]
+          - Compute d = DU[k]^T*V1 and V3 = DU[k]-V1
+          - Compute V4 = V3/d
+          - Update H[k] = H[k-1] + V4*V2
+        - Save old U and F
+        - Compute absolute and relative errors
+        - Break iterations if error < tol or iter == max_iter
+     - Update explicit equations using only the explicit terms.
+  - Else if stage == 2:
+     - Update explicit equations using only the explicit terms.
+     - Update implicit equations using:
+     u[n+1] = u[n]+dt*(expl_rkcoef[3,1]*R_ex(u[0])+impl_rkcoef[3,1]*R_im(u[0])
+                       expl_rkcoef[3,2]*R_ex(u[1])+impl_rkcoef[3,2]*R_im(u[1]))
+
+  ******************************************************************************/
+  auto d = Disc();
+  const auto rdof = g_inputdeck.get< tag::rdof >();
+  const auto ndof = g_inputdeck.get< tag::ndof >();
+  if (m_stage < 2) {
+    // Save previous stiff_rhs
+    m_stiffrhsprev = m_stiffrhs;
+
+    // Compute the imex update
+
+    // Integrate explicitly on the imex equations
+    // (To use as initial values)
+    for (std::size_t e=0; e<myGhosts()->m_nunk; ++e)
+      for (std::size_t c=0; c<m_nstiffeq; ++c)
+      {
+        for (std::size_t k=0; k<m_numEqDof[c]; ++k)
+        {
+          auto rmark = m_stiffEqIdx[c]*rdof+k;
+          auto mark = m_stiffEqIdx[c]*ndof+k;
+          m_u(e, rmark) =  m_un(e, rmark) + d->Dt() * (
+            expl_rkcoef[0][m_stage] * m_rhsprev(e, mark)/m_lhs(e, mark)
+            + expl_rkcoef[1][m_stage] * m_rhs(e, mark)/m_lhs(e, mark)
+            + impl_rkcoef[0][m_stage]
+            * m_stiffrhsprev(e,c*ndof+k)/m_lhs(e, mark) );
+          if(fabs(m_u(e, rmark)) < 1e-16)
+            m_u(e, rmark) = 0;
+        }
+      }
+
+    // Solve for implicit-explicit equations
+    const auto nelem = myGhosts()->m_fd.Esuel().size()/4;
+    for (std::size_t e=0; e<nelem; ++e)
+    {
+      // Non-linear system f(u) = 0 to be solved
+      // Broyden's method
+      // Control parameters
+      std::size_t max_iter = g_inputdeck.get< tag::imex_maxiter >();
+      tk::real rel_tol = g_inputdeck.get< tag::imex_reltol >();
+      tk::real abs_tol = g_inputdeck.get< tag::imex_abstol >();
+      tk::real rel_err = rel_tol+1;
+      tk::real abs_err = abs_tol+1;
+      std::size_t nstiff = m_nstiffeq*ndof;
+
+      // Initialize Jacobian to be the identity
+      std::vector< std::vector< tk::real > >
+        approx_jacob(nstiff, std::vector< tk::real >(nstiff, 0.0));
+      for (std::size_t i=0; i<nstiff; ++i)
+        approx_jacob[i][i] = 1.0e+00;
+
+      // Save explicit terms to be re-used
+      std::vector< tk::real > expl_terms(nstiff, 0.0);
+      for (size_t ieq=0; ieq<m_nstiffeq; ++ieq)
+        for (size_t idof=0; idof<m_numEqDof[ieq]; ++idof)
+        {
+          auto stiffmark = m_stiffEqIdx[ieq]*ndof+idof;
+          auto stiffrmark = m_stiffEqIdx[ieq]*rdof+idof;
+          expl_terms[ieq*ndof+idof] = m_un(e, stiffrmark)
+            + d->Dt() * ( expl_rkcoef[0][m_stage]
+            * m_rhsprev(e,stiffmark)/m_lhs(e,stiffmark)
+            + expl_rkcoef[1][m_stage]
+            * m_rhs(e,stiffmark)/m_lhs(e,stiffmark)
+            + impl_rkcoef[0][m_stage]
+            * m_stiffrhsprev(e,ieq*ndof+idof)/m_lhs(e,stiffmark) );
+        }
+
+      // Compute stiff_rhs with initial u
+      g_dgpde[d->MeshId()].stiff_rhs( e, myGhosts()->m_geoElem,
+        myGhosts()->m_inpoel, myGhosts()->m_coord,
+        m_u, m_p, m_ndof, m_stiffrhs );
+
+      // Make auxiliary u_old and f_old to store previous values
+      std::vector< tk::real > u_old(nstiff, 0.0), f_old(nstiff, 0.0);
+      // Make delta_u and delta_f
+      std::vector< tk::real > delta_u(nstiff, 0.0), delta_f(nstiff, 0.0);
+      // Store f
+      std::vector< tk::real > f(nstiff, 0.0);
+      for (std::size_t ieq=0; ieq<m_nstiffeq; ++ieq)
+        for (std::size_t idof=0; idof<m_numEqDof[ieq]; ++idof)
+        {
+          auto stiffrmark = m_stiffEqIdx[ieq]*rdof+idof;
+          auto stiffmark = m_stiffEqIdx[ieq]*ndof+idof;
+          f[ieq*ndof+idof] = expl_terms[ieq*ndof+idof]
+            + d->Dt() * impl_rkcoef[1][m_stage]
+            * m_stiffrhs(e,ieq*ndof+idof)/m_lhs(e,stiffmark)
+            - m_u(e, stiffrmark);
+        }
+
+      // Initialize u_old and f_old
+      for (std::size_t ieq=0; ieq<m_nstiffeq; ++ieq)
+        for (std::size_t idof=0; idof<m_numEqDof[ieq]; ++idof)
+        {
+          u_old[ieq*ndof+idof] = m_u(e, m_stiffEqIdx[ieq]*rdof+idof);
+          f_old[ieq*ndof+idof] = f[ieq*ndof+idof];
+        }
+
+      // Store the norm of f initially, for relative error measure
+      tk::real err0 = 0.0;
+      for (std::size_t ieq=0; ieq<m_nstiffeq; ++ieq)
+        for (std::size_t idof=0; idof<m_numEqDof[ieq]; ++idof)
+          err0 += f[ieq*ndof+idof]*f[ieq*ndof+idof];
+      err0 = std::sqrt(err0);
+
+      // Iterate for the solution if err0 > 0
+      if (err0 > abs_tol)
+        for (size_t iter=0; iter<max_iter; ++iter)
+        {
+
+          // Compute new solution
+          tk::real delta;
+          for (std::size_t ieq=0; ieq<m_nstiffeq; ++ieq)
+            for (std::size_t idof=0; idof<m_numEqDof[ieq]; ++idof)
+            {
+              delta = 0.0;
+              for (std::size_t jeq=0; jeq<m_nstiffeq; ++jeq)
+                for (std::size_t jdof=0; jdof<m_numEqDof[jeq]; ++jdof)
+                  delta +=
+                    approx_jacob[ieq*ndof+idof][jeq*ndof+jdof] * f[jeq*ndof+jdof];
+              // Update u
+              auto stiffrmark = m_stiffEqIdx[ieq]*rdof+idof;
+              m_u(e, stiffrmark) -= delta;
+            }
+
+          // Compute new stiff_rhs
+          g_dgpde[d->MeshId()].stiff_rhs( e, myGhosts()->m_geoElem,
+            myGhosts()->m_inpoel, myGhosts()->m_coord,
+            m_u, m_p, m_ndof, m_stiffrhs );
+
+          // Compute new f(u)
+          for (std::size_t ieq=0; ieq<m_nstiffeq; ++ieq)
+            for (std::size_t idof=0; idof<m_numEqDof[ieq]; ++idof)
+            {
+              auto stiffrmark = m_stiffEqIdx[ieq]*rdof+idof;
+              auto stiffmark = m_stiffEqIdx[ieq]*ndof+idof;
+              f[ieq*ndof+idof] = expl_terms[ieq*ndof+idof]
+                + d->Dt() * impl_rkcoef[1][m_stage]
+                * m_stiffrhs(e,ieq*ndof+idof)/m_lhs(e,stiffmark)
+                - m_u(e, stiffrmark);
+            }
+
+          // Compute delta_u and delta_f
+          for (std::size_t ieq=0; ieq<m_nstiffeq; ++ieq)
+            for (std::size_t idof=0; idof<m_numEqDof[ieq]; ++idof)
+            {
+              auto stiffrmark = m_stiffEqIdx[ieq]*rdof+idof;
+              delta_u[ieq*ndof+idof] = m_u(e, stiffrmark) - u_old[ieq*ndof+idof];
+              delta_f[ieq*ndof+idof] = f[ieq*ndof+idof] - f_old[ieq*ndof+idof];
+            }
+
+          // Update inverse Jacobian approximation
+
+          // 1. Compute approx_jacob*delta_f and delta_u*jacob_approx
+          tk::real sum1, sum2;
+          std::vector< tk::real > auxvec1(nstiff, 0.0), auxvec2(nstiff, 0.0);
+          for (std::size_t ieq=0; ieq<m_nstiffeq; ++ieq)
+            for (std::size_t idof=0; idof<m_numEqDof[ieq]; ++idof)
+            {
+              sum1 = 0.0;
+              sum2 = 0.0;
+              for (std::size_t jeq=0; jeq<m_nstiffeq; ++jeq)
+                for (std::size_t jdof=0; jdof<m_numEqDof[jeq]; ++jdof)
+                {
+                  sum1 += approx_jacob[ieq*ndof+idof][jeq*ndof+jdof] *
+                    delta_f[jeq*ndof+jdof];
+                  sum2 += delta_u[jeq*ndof+jdof] *
+                    approx_jacob[jeq*ndof+jdof][ieq*ndof+idof];
+                }
+              auxvec1[ieq*ndof+idof] = sum1;
+              auxvec2[ieq*ndof+idof] = sum2;
+            }
+
+          // 2. Compute delta_u*approx_jacob*delta_f
+          // and delta_u-approx_jacob*delta_f
+          tk::real denom = 0.0;
+          for (std::size_t jeq=0; jeq<m_nstiffeq; ++jeq)
+            for (std::size_t jdof=0; jdof<m_numEqDof[jeq]; ++jdof)
+            {
+              denom += delta_u[jeq*ndof+jdof]*auxvec1[jeq*ndof+jdof];
+              auxvec1[jeq*ndof+jdof] =
+                delta_u[jeq*ndof+jdof]-auxvec1[jeq*ndof+jdof];
+            }
+
+          // 3. Divide delta_u+approx_jacob*delta_f
+          // by delta_u*(approx_jacob*delta_f)
+          if (std::abs(denom) < 1.0e-18)
+          {
+            if (denom < 0.0)
+            {
+              for (std::size_t jeq=0; jeq<m_nstiffeq; ++jeq)
+                for (std::size_t jdof=0; jdof<m_numEqDof[jeq]; ++jdof)
+                  auxvec1[jeq*ndof+jdof] /= -1.0e-18;
+            }
+            else
+            {
+              for (std::size_t jeq=0; jeq<m_nstiffeq; ++jeq)
+                for (std::size_t jdof=0; jdof<m_numEqDof[jeq]; ++jdof)
+                  auxvec1[jeq*ndof+jdof] /= 1.0e-18;
+            }
+          }
+          else
+          {
+            for (std::size_t jeq=0; jeq<m_nstiffeq; ++jeq)
+              for (std::size_t jdof=0; jdof<m_numEqDof[jeq]; ++jdof)
+                auxvec1[jeq*ndof+jdof] /= denom;
+          }
+
+          // 4. Perform outter product between the two arrays and
+          // add that quantity to the new jacobian approximation
+          for (std::size_t ieq=0; ieq<m_nstiffeq; ++ieq)
+            for (std::size_t idof=0; idof<m_numEqDof[ieq]; ++idof)
+              for (std::size_t jeq=0; jeq<m_nstiffeq; ++jeq)
+                for (std::size_t jdof=0; jdof<m_numEqDof[jeq]; ++jdof)
+                  approx_jacob[ieq*ndof+idof][jeq*ndof+jdof] +=
+                    auxvec1[ieq*ndof+idof] * auxvec2[jeq*ndof+jdof];
+
+          // Save solution and f
+          for (std::size_t ieq=0; ieq<m_nstiffeq; ++ieq)
+            for (std::size_t idof=0; idof<m_numEqDof[ieq]; ++idof)
+            {
+              u_old[ieq*ndof+idof] = m_u(e, m_stiffEqIdx[ieq]*rdof+idof);
+              f_old[ieq*ndof+idof] = f[ieq*ndof+idof];
+            }
+
+          // Compute a measure of error, use norm of f
+          tk::real err = 0.0;
+          for (std::size_t ieq=0; ieq<m_nstiffeq; ++ieq)
+            for (std::size_t idof=0; idof<m_numEqDof[ieq]; ++idof)
+              err += f[ieq*ndof+idof]*f[ieq*ndof+idof];
+          abs_err = std::sqrt(err);
+          rel_err = abs_err/err0;
+
+          // Check if error condition is met and loop back
+          if (rel_err < rel_tol || abs_err < abs_tol)
+            break;
+
+          // If we did not converge, print a message
+          if (iter == max_iter-1)
+          {
+            printf("\nIMEX-RK: Non-linear solver did not converge in %lu iterations\n", max_iter);<--- %lu in format string (no. 1) requires 'unsigned long' but the argument type is 'std::size_t {aka unsigned long}'.
+            printf("Element #%lu\n", e);<--- %lu in format string (no. 1) requires 'unsigned long' but the argument type is 'std::size_t {aka unsigned long}'.
+            printf("Relative error: %e\n", rel_err);
+            printf("Absolute error: %e\n\n", abs_err);
+          }
+        }
+    }
+
+    // Then, integrate explicitly on the remaining equations
+    for (std::size_t e=0; e<nelem; ++e)
+      for (std::size_t c=0; c<m_nnonstiffeq; ++c)
+      {
+        for (std::size_t k=0; k<m_numEqDof[c]; ++k)
+        {
+          auto rmark = m_nonStiffEqIdx[c]*rdof+k;
+          auto mark = m_nonStiffEqIdx[c]*ndof+k;
+          m_u(e, rmark) =  m_un(e, rmark) + d->Dt() * (
+            expl_rkcoef[0][m_stage] * m_rhsprev(e, mark)/m_lhs(e, mark)
+            + expl_rkcoef[1][m_stage] * m_rhs(e, mark)/m_lhs(e, mark));
+          if(fabs(m_u(e, rmark)) < 1e-16)
+            m_u(e, rmark) = 0;
+        }
+      }
+  }
+  else {
+    // For last stage just use all previously computed stages
+    const auto nelem = myGhosts()->m_fd.Esuel().size()/4;
+    for (std::size_t e=0; e<nelem; ++e)
+    {
+      // First integrate explicitly on nonstiff equations
+      for (std::size_t c=0; c<m_nnonstiffeq; ++c)
+      {
+        for (std::size_t k=0; k<m_numEqDof[c]; ++k)
+        {
+          auto rmark = m_nonStiffEqIdx[c]*rdof+k;
+          auto mark = m_nonStiffEqIdx[c]*ndof+k;
+          m_u(e, rmark) =  m_un(e, rmark) + d->Dt() * (
+            expl_rkcoef[0][m_stage] * m_rhsprev(e, mark)/m_lhs(e, mark)
+            + expl_rkcoef[1][m_stage] * m_rhs(e, mark)/m_lhs(e, mark));
+          if(fabs(m_u(e, rmark)) < 1e-16)
+            m_u(e, rmark) = 0;
+        }
+      }
+      // Then, integrate the imex-equations
+      for (std::size_t ieq=0; ieq<m_nstiffeq; ++ieq)
+        for (std::size_t idof=0; idof<m_numEqDof[ieq]; ++idof)
+        {
+          auto rmark = m_stiffEqIdx[ieq]*rdof+idof;
+          auto mark = m_stiffEqIdx[ieq]*ndof+idof;
+          m_u(e, rmark) = m_un(e, rmark)
+            + d->Dt() * (expl_rkcoef[0][m_stage]
+                         * m_rhsprev(e,mark)/m_lhs(e,mark)
+                         + expl_rkcoef[1][m_stage]
+                         * m_rhs(e,mark)/m_lhs(e,mark)
+                         + impl_rkcoef[0][m_stage]
+                         * m_stiffrhsprev(e,ieq*ndof+idof)/m_lhs(e,mark)
+                         + impl_rkcoef[1][m_stage]
+                         * m_stiffrhs(e,ieq*ndof+idof)/m_lhs(e,mark) );
+          if(fabs(m_u(e, rmark)) < 1e-16)
+            m_u(e, rmark) = 0;
+        }
+    }
+  }
+}
+
+#include "NoWarning/dg.def.h"
 
diff --git a/Release/cppcheck/44.html b/Release/cppcheck/44.html index b8ec4618bc49..248ba5dae6c6 100644 --- a/Release/cppcheck/44.html +++ b/Release/cppcheck/44.html @@ -152,1609 +152,2597 @@
- - + @@ -95,7 +95,7 @@ 21 : : namespace inciter { 22 : : 23 : : std::pair< int, std::unique_ptr<char[]> > - 24 : 35832 : serialize( std::size_t meshid, + 24 : 35827 : serialize( std::size_t meshid, 25 : : std::size_t ncomp, 26 : : const std::vector< std::vector< tk::real > >& d ) 27 : : // ***************************************************************************** @@ -108,7 +108,7 @@ 34 : : // ***************************************************************************** 35 : : { 36 : : // Prepare for serializing diagnostics to a raw binary stream, compute size - 37 : 35832 : PUP::sizer sizer; + 37 : 35827 : PUP::sizer sizer; 38 : : sizer | meshid; 39 : : sizer | ncomp; 40 : : sizer | const_cast< std::vector< std::vector< tk::real > >& >( d ); @@ -123,11 +123,11 @@ 49 : : packer | const_cast< std::vector< std::vector< tk::real > >& >( d ); 50 : : 51 : : // Return size of and raw stream - 52 : 35832 : return { sizer.size(), std::move(flatData) }; + 52 : 35827 : return { sizer.size(), std::move(flatData) }; 53 : : } 54 : : 55 : : CkReductionMsg* - 56 [ + - ]: 5104 : mergeDiag( int nmsg, CkReductionMsg **msgs ) + 56 [ + - ]: 5099 : mergeDiag( int nmsg, CkReductionMsg **msgs ) 57 : : // ***************************************************************************** 58 : : // Charm++ custom reducer for merging diagnostics during reduction across PEs 59 : : //! \param[in] nmsg Number of messages in msgs @@ -137,17 +137,17 @@ 63 : : // ***************************************************************************** 64 : : { 65 : : std::size_t meshid, ncomp; - 66 : 5104 : std::vector< std::vector< tk::real > > v; + 66 : 5099 : std::vector< std::vector< tk::real > > v; 67 : : 68 : : // Create PUP deserializer based on message passed in - 69 [ + - ]: 5104 : PUP::fromMem creator( msgs[0]->getData() ); + 69 [ + - ]: 5099 : PUP::fromMem creator( msgs[0]->getData() ); 70 : : 71 : : // Deserialize vector from raw stream 72 : : creator | meshid; 73 : : creator | ncomp; 74 : : creator | v; 75 : : - 76 [ + + ]: 32468 : for (int m=1; m<nmsg; ++m) { + 76 [ + + ]: 32463 : for (int m=1; m<nmsg; ++m) { 77 : : // Unpack vector 78 : : std::size_t mid, nc; 79 : 27364 : std::vector< std::vector< tk::real > > w; @@ -174,7 +174,7 @@ 100 [ + + ]: 106518 : for (std::size_t i=0; i<v[L2RES].size(); ++i) v[L2RES][i] += w[L2RES][i]; 101 : : // Max for the Linf norm of the numerical - analytical solution for all comp 102 [ + + ]: 106518 : for (std::size_t i=0; i<v[LINFERR].size(); ++i) - 103 [ + + ]: 79154 : if (w[LINFERR][i] > v[LINFERR][i]) v[LINFERR][i] = w[LINFERR][i]; + 103 [ + + ]: 79154 : if (w[LINFERR][i] > v[LINFERR][i]) v[LINFERR][i] = w[LINFERR][i]; 104 : : // Sum of the total energy over the entire domain 105 : 27364 : v[TOTALSOL][0] += w[TOTALSOL][0]; 106 : : // Copy ITER, TIME, DT @@ -184,10 +184,10 @@ 110 : : } 111 : : 112 : : // Serialize concatenated diagnostics vector to raw stream - 113 [ + - ]: 5104 : auto stream = serialize( meshid, ncomp, v ); + 113 [ + - ]: 5099 : auto stream = serialize( meshid, ncomp, v ); 114 : : 115 : : // Forward serialized diagnostics - 116 [ + - ]: 10208 : return CkReductionMsg::buildNew( stream.first, stream.second.get() ); + 116 [ + - ]: 10198 : return CkReductionMsg::buildNew( stream.first, stream.second.get() ); 117 : : } 118 : : 119 : : } // inciter:: diff --git a/Release/test_coverage/Inciter/Discretization.cpp.func-sort-c.html b/Release/test_coverage/Inciter/Discretization.cpp.func-sort-c.html index 1c029c8dfa57..b015691694e2 100644 --- a/Release/test_coverage/Inciter/Discretization.cpp.func-sort-c.html +++ b/Release/test_coverage/Inciter/Discretization.cpp.func-sort-c.html @@ -33,7 +33,7 @@ - + diff --git a/Release/test_coverage/Inciter/Discretization.cpp.func.html b/Release/test_coverage/Inciter/Discretization.cpp.func.html index eb05ef085702..d9df73541268 100644 --- a/Release/test_coverage/Inciter/Discretization.cpp.func.html +++ b/Release/test_coverage/Inciter/Discretization.cpp.func.html @@ -33,7 +33,7 @@ - + diff --git a/Release/test_coverage/Inciter/Discretization.cpp.gcov.html b/Release/test_coverage/Inciter/Discretization.cpp.gcov.html index 8f5dae6e29cb..a7560c7b01c2 100644 --- a/Release/test_coverage/Inciter/Discretization.cpp.gcov.html +++ b/Release/test_coverage/Inciter/Discretization.cpp.gcov.html @@ -33,7 +33,7 @@ - + @@ -228,8 +228,8 @@ 148 : : std::array< tk::real, 4 > N; 149 : : const auto& l = pt[p].get< tag::coord >(); 150 : : const auto& id = pt[p].get< tag::id >(); - 151 [ + + ]: 25021 : for (std::size_t e=0; e<m_inpoel.size()/4; ++e) { - 152 [ + - ][ + + ]: 24979 : if (tk::intet( m_coord, m_inpoel, l, e, N )) { + 151 [ + + ]: 25008 : for (std::size_t e=0; e<m_inpoel.size()/4; ++e) { + 152 [ + - ][ + + ]: 24966 : if (tk::intet( m_coord, m_inpoel, l, e, N )) { 153 [ + - ][ - + ]: 20 : m_histdata.push_back( HistData{{ id, e, {l[0],l[1],l[2]}, N }} ); [ - - ] 154 : 10 : break; @@ -514,8 +514,8 @@ 428 : : { 429 : : // Lambda to find out if a mesh node is shared with another chare 430 : 10327604 : auto shared = [this]( std::size_t i ){ - 431 [ + + ]: 29332280 : for (const auto& [c,n] : m_nodeCommMap) - 432 [ + + ]: 21084882 : if (n.find(i) != end(n)) return true; + 431 [ + + ]: 29351753 : for (const auto& [c,n] : m_nodeCommMap) + 432 [ + + ]: 21104355 : if (n.find(i) != end(n)) return true; 433 : : return false; 434 : : }; 435 : : @@ -917,7 +917,7 @@ 749 : 1808158 : const auto dz = z[ i ] - z[ p ]; 750 : 1808158 : const auto length = std::sqrt( dx*dx + dy*dy + dz*dz ); 751 [ + + ]: 1808158 : if (length < min[0]) min[0] = length; - 752 [ + + ]: 1808158 : if (length > max[0]) max[0] = length; + 752 [ + + ]: 1808158 : if (length > max[0]) max[0] = length; 753 : 1808158 : sum[0] += 1.0; 754 : 1808158 : sum[1] += length; 755 [ + - ]: 1808158 : edgePDF.add( length ); @@ -925,15 +925,15 @@ 757 : : 758 : : // Compute mesh cell volume statistics 759 [ + + ]: 559481 : for (std::size_t e=0; e<m_inpoel.size()/4; ++e) { - 760 [ + + ]: 557492 : const std::array< std::size_t, 4 > N{{ m_inpoel[e*4+0], m_inpoel[e*4+1], + 760 [ + + ]: 557492 : const std::array< std::size_t, 4 > N{{ m_inpoel[e*4+0], m_inpoel[e*4+1], 761 : 557492 : m_inpoel[e*4+2], m_inpoel[e*4+3] }}; 762 : : const std::array< tk::real, 3 > - 763 [ + + ]: 557492 : ba{{ x[N[1]]-x[N[0]], y[N[1]]-y[N[0]], z[N[1]]-z[N[0]] }}, + 763 [ + + ]: 557492 : ba{{ x[N[1]]-x[N[0]], y[N[1]]-y[N[0]], z[N[1]]-z[N[0]] }}, 764 : 557492 : ca{{ x[N[2]]-x[N[0]], y[N[2]]-y[N[0]], z[N[2]]-z[N[0]] }}, - 765 [ + + ]: 557492 : da{{ x[N[3]]-x[N[0]], y[N[3]]-y[N[0]], z[N[3]]-z[N[0]] }}; + 765 [ + + ]: 557492 : da{{ x[N[3]]-x[N[0]], y[N[3]]-y[N[0]], z[N[3]]-z[N[0]] }}; 766 : 557492 : const auto L = std::cbrt( tk::triple( ba, ca, da ) / 6.0 ); - 767 [ + + ]: 557492 : if (L < min[1]) min[1] = L; - 768 [ + + ]: 557492 : if (L > max[1]) max[1] = L; + 767 [ + + ]: 557492 : if (L < min[1]) min[1] = L; + 768 [ + + ]: 557492 : if (L > max[1]) max[1] = L; 769 : 557492 : sum[2] += 1.0; 770 : 557492 : sum[3] += L; 771 [ + - ]: 557492 : volPDF.add( L ); diff --git a/Release/test_coverage/Inciter/Discretization.hpp.func-sort-c.html b/Release/test_coverage/Inciter/Discretization.hpp.func-sort-c.html index 58eb6f15503e..05f7f4812fcb 100644 --- a/Release/test_coverage/Inciter/Discretization.hpp.func-sort-c.html +++ b/Release/test_coverage/Inciter/Discretization.hpp.func-sort-c.html @@ -33,7 +33,7 @@ - + @@ -77,11 +77,11 @@ - + - + diff --git a/Release/test_coverage/Inciter/Discretization.hpp.func.html b/Release/test_coverage/Inciter/Discretization.hpp.func.html index 3b7ed99ce270..6689f7010861 100644 --- a/Release/test_coverage/Inciter/Discretization.hpp.func.html +++ b/Release/test_coverage/Inciter/Discretization.hpp.func.html @@ -33,7 +33,7 @@ - + @@ -81,11 +81,11 @@ - + - + diff --git a/Release/test_coverage/Inciter/Discretization.hpp.gcov.html b/Release/test_coverage/Inciter/Discretization.hpp.gcov.html index fb2500e260a7..fb1e167f6838 100644 --- a/Release/test_coverage/Inciter/Discretization.hpp.gcov.html +++ b/Release/test_coverage/Inciter/Discretization.hpp.gcov.html @@ -33,7 +33,7 @@ - + @@ -158,7 +158,7 @@ 84 : : #endif 85 : : //! Migrate constructor 86 : : // cppcheck-suppress uninitMemberVar - 87 : 15716 : explicit Discretization( CkMigrateMessage* ) {} + 87 : 15510 : explicit Discretization( CkMigrateMessage* ) {} 88 : : #if defined(__clang__) 89 : : #pragma clang diagnostic pop 90 : : #endif @@ -514,63 +514,63 @@ 437 : : ///@{ 438 : : //! \brief Pack/Unpack serialize member function 439 : : //! \param[in,out] p Charm++'s PUP::er serializer object reference - 440 : 24390 : void pup( PUP::er &p ) override { - 441 : 24390 : p | m_meshid; - 442 : 24390 : p | m_transfer_complete; - 443 : 24390 : p | m_transfer; - 444 : 24390 : p | m_mytransfer; - 445 : 24390 : p | m_disc; - 446 : 24390 : p | m_nchare; - 447 : 24390 : p | m_it; - 448 : 24390 : p | m_itr; - 449 : 24390 : p | m_itf; - 450 : 24390 : p | m_initial; - 451 : 24390 : p | m_t; - 452 : 24390 : p | m_lastDumpTime; - 453 : 24390 : p | m_physFieldFloor; - 454 : 24390 : p | m_physHistFloor; - 455 : 24390 : p | m_rangeFieldFloor; - 456 : 24390 : p | m_rangeHistFloor; - 457 : 24390 : p | m_dt; - 458 : 24390 : p | m_dtn; - 459 : 24390 : p | m_nvol; - 460 : 24390 : p | m_nxfer; - 461 : 24390 : p | m_ale; - 462 : 24390 : p | m_transporter; - 463 : 24390 : p | m_meshwriter; - 464 : 24390 : p | m_refiner; - 465 : 24390 : p | m_el; - 466 [ + + ]: 24390 : if (p.isUnpacking()) { - 467 : 7858 : m_inpoel = std::get< 0 >( m_el ); - 468 : 7858 : m_gid = std::get< 1 >( m_el ); - 469 [ - + ]: 7858 : m_lid = std::get< 2 >( m_el ); + 440 : 24081 : void pup( PUP::er &p ) override { + 441 : 24081 : p | m_meshid; + 442 : 24081 : p | m_transfer_complete; + 443 : 24081 : p | m_transfer; + 444 : 24081 : p | m_mytransfer; + 445 : 24081 : p | m_disc; + 446 : 24081 : p | m_nchare; + 447 : 24081 : p | m_it; + 448 : 24081 : p | m_itr; + 449 : 24081 : p | m_itf; + 450 : 24081 : p | m_initial; + 451 : 24081 : p | m_t; + 452 : 24081 : p | m_lastDumpTime; + 453 : 24081 : p | m_physFieldFloor; + 454 : 24081 : p | m_physHistFloor; + 455 : 24081 : p | m_rangeFieldFloor; + 456 : 24081 : p | m_rangeHistFloor; + 457 : 24081 : p | m_dt; + 458 : 24081 : p | m_dtn; + 459 : 24081 : p | m_nvol; + 460 : 24081 : p | m_nxfer; + 461 : 24081 : p | m_ale; + 462 : 24081 : p | m_transporter; + 463 : 24081 : p | m_meshwriter; + 464 : 24081 : p | m_refiner; + 465 : 24081 : p | m_el; + 466 [ + + ]: 24081 : if (p.isUnpacking()) { + 467 : 7755 : m_inpoel = std::get< 0 >( m_el ); + 468 : 7755 : m_gid = std::get< 1 >( m_el ); + 469 [ - + ]: 7755 : m_lid = std::get< 2 >( m_el ); 470 : : } 471 : : p | m_coord; 472 : : p | m_coordn; 473 : : p | m_nodeCommMap; - 474 : 24390 : p | m_edgeCommMap; - 475 : 24390 : p | m_meshvol; - 476 : 24390 : p | m_v; - 477 : 24390 : p | m_vol; - 478 : 24390 : p | m_volc; - 479 : 24390 : p | m_voln; - 480 : 24390 : p | m_vol0; - 481 : 24390 : p | m_boxvol; - 482 : 24390 : p | m_meshblkvol; - 483 : 24390 : p | m_bid; + 474 : 24081 : p | m_edgeCommMap; + 475 : 24081 : p | m_meshvol; + 476 : 24081 : p | m_v; + 477 : 24081 : p | m_vol; + 478 : 24081 : p | m_volc; + 479 : 24081 : p | m_voln; + 480 : 24081 : p | m_vol0; + 481 : 24081 : p | m_boxvol; + 482 : 24081 : p | m_meshblkvol; + 483 : 24081 : p | m_bid; 484 : : p | m_timer; - 485 : 24390 : p | m_refined; - 486 : 24390 : p( reinterpret_cast<char*>(&m_prevstatus), sizeof(Clock::time_point) ); - 487 : 24390 : p | m_nrestart; - 488 : 24390 : p | m_histdata; - 489 : 24390 : p | m_nsrc; - 490 : 24390 : p | m_ndst; - 491 : 24390 : p | m_meshvel; - 492 : 24390 : p | m_meshvel_converged; - 493 : 24390 : p | m_bface; - 494 : 24390 : p | m_triinpoel; - 495 : 24390 : p | m_elemblockid; - 496 : 24390 : } + 485 : 24081 : p | m_refined; + 486 : 24081 : p( reinterpret_cast<char*>(&m_prevstatus), sizeof(Clock::time_point) ); + 487 : 24081 : p | m_nrestart; + 488 : 24081 : p | m_histdata; + 489 : 24081 : p | m_nsrc; + 490 : 24081 : p | m_ndst; + 491 : 24081 : p | m_meshvel; + 492 : 24081 : p | m_meshvel_converged; + 493 : 24081 : p | m_bface; + 494 : 24081 : p | m_triinpoel; + 495 : 24081 : p | m_elemblockid; + 496 : 24081 : } 497 : : //! \brief Pack/Unpack serialize operator| 498 : : //! \param[in,out] p Charm++'s PUP::er serializer object reference 499 : : //! \param[in,out] i Discretization object reference diff --git a/Release/test_coverage/Inciter/ElemDiagnostics.cpp.func-sort-c.html b/Release/test_coverage/Inciter/ElemDiagnostics.cpp.func-sort-c.html index 48f131bdb6a6..e6fa01b1b10f 100644 --- a/Release/test_coverage/Inciter/ElemDiagnostics.cpp.func-sort-c.html +++ b/Release/test_coverage/Inciter/ElemDiagnostics.cpp.func-sort-c.html @@ -33,7 +33,7 @@ - + diff --git a/Release/test_coverage/Inciter/ElemDiagnostics.cpp.func.html b/Release/test_coverage/Inciter/ElemDiagnostics.cpp.func.html index a873714700a5..4dc8d1649681 100644 --- a/Release/test_coverage/Inciter/ElemDiagnostics.cpp.func.html +++ b/Release/test_coverage/Inciter/ElemDiagnostics.cpp.func.html @@ -33,7 +33,7 @@ - + diff --git a/Release/test_coverage/Inciter/ElemDiagnostics.cpp.gcov.html b/Release/test_coverage/Inciter/ElemDiagnostics.cpp.gcov.html index 32e982ccb859..d23819edd550 100644 --- a/Release/test_coverage/Inciter/ElemDiagnostics.cpp.gcov.html +++ b/Release/test_coverage/Inciter/ElemDiagnostics.cpp.gcov.html @@ -33,7 +33,7 @@ - + @@ -284,14 +284,14 @@ 209 : : } 210 : : 211 : : // Compute sum for L2 norm of the numerical solution - 212 [ + + ]: 28773245 : diag[L2SOL][c] += wt * ugp * ugp; + 212 [ + + ]: 28773245 : diag[L2SOL][c] += wt * ugp * ugp; 213 : : 214 : : // Compute sum for L2 norm of the numerical-analytic solution 215 : 28773245 : diag[L2ERR][c] += wt * (ugp-s[c]) * (ugp-s[c]); 216 : : 217 : : // Compute max for Linf norm of the numerical-analytic solution - 218 [ + + ]: 28773245 : auto err = std::abs( ugp - s[c] ); - 219 [ + + ]: 28773245 : if (err > diag[LINFERR][c]) diag[LINFERR][c] = err; + 218 [ + + ]: 28773245 : auto err = std::abs( ugp - s[c] ); + 219 [ + + ]: 28773245 : if (err > diag[LINFERR][c]) diag[LINFERR][c] = err; 220 : : } 221 : : } 222 : : tk::real sp_te(0.0); diff --git a/Release/test_coverage/Inciter/FV.cpp.func-sort-c.html b/Release/test_coverage/Inciter/FV.cpp.func-sort-c.html index 7dec5bae7604..5b0e730cff91 100644 --- a/Release/test_coverage/Inciter/FV.cpp.func-sort-c.html +++ b/Release/test_coverage/Inciter/FV.cpp.func-sort-c.html @@ -33,7 +33,7 @@ - + diff --git a/Release/test_coverage/Inciter/FV.cpp.func.html b/Release/test_coverage/Inciter/FV.cpp.func.html index 6f88023ffe7f..0f376b65c2ad 100644 --- a/Release/test_coverage/Inciter/FV.cpp.func.html +++ b/Release/test_coverage/Inciter/FV.cpp.func.html @@ -33,7 +33,7 @@ - + diff --git a/Release/test_coverage/Inciter/FV.cpp.gcov.html b/Release/test_coverage/Inciter/FV.cpp.gcov.html index a2104ad1d282..1d13fbef6727 100644 --- a/Release/test_coverage/Inciter/FV.cpp.gcov.html +++ b/Release/test_coverage/Inciter/FV.cpp.gcov.html @@ -33,7 +33,7 @@ - + diff --git a/Release/test_coverage/Inciter/FV.hpp.func-sort-c.html b/Release/test_coverage/Inciter/FV.hpp.func-sort-c.html index 166109f6edf1..84a3427bfb72 100644 --- a/Release/test_coverage/Inciter/FV.hpp.func-sort-c.html +++ b/Release/test_coverage/Inciter/FV.hpp.func-sort-c.html @@ -33,7 +33,7 @@ - + @@ -73,11 +73,11 @@ - + - + diff --git a/Release/test_coverage/Inciter/FV.hpp.func.html b/Release/test_coverage/Inciter/FV.hpp.func.html index 761ebe623f6c..358c8cbb353d 100644 --- a/Release/test_coverage/Inciter/FV.hpp.func.html +++ b/Release/test_coverage/Inciter/FV.hpp.func.html @@ -33,7 +33,7 @@ - + @@ -73,11 +73,11 @@ - + - + diff --git a/Release/test_coverage/Inciter/FV.hpp.gcov.html b/Release/test_coverage/Inciter/FV.hpp.gcov.html index b12b30530fb0..42537b2b027a 100644 --- a/Release/test_coverage/Inciter/FV.hpp.gcov.html +++ b/Release/test_coverage/Inciter/FV.hpp.gcov.html @@ -33,7 +33,7 @@ - + @@ -151,7 +151,7 @@ 77 : : #endif 78 : : //! Migrate constructor 79 : : // cppcheck-suppress uninitMemberVar - 80 : 106 : explicit FV( CkMigrateMessage* msg ) : CBase_FV( msg ) {} + 80 : 110 : explicit FV( CkMigrateMessage* msg ) : CBase_FV( msg ) {} 81 : : #if defined(__clang__) 82 : : #pragma clang diagnostic pop 83 : : #endif @@ -257,37 +257,37 @@ 183 : : ///@{ 184 : : //! \brief Pack/Unpack serialize member function 185 : : //! \param[in,out] p Charm++'s PUP::er serializer object reference - 186 : 323 : void pup( PUP::er &p ) override { - 187 : 323 : p | m_disc; - 188 : 323 : p | m_ghosts; - 189 : 323 : p | m_nsol; - 190 : 323 : p | m_ninitsol; - 191 : 323 : p | m_nlim; - 192 : 323 : p | m_nnod; - 193 : 323 : p | m_u; - 194 : 323 : p | m_un; - 195 : 323 : p | m_p; - 196 : 323 : p | m_lhs; - 197 : 323 : p | m_rhs; - 198 : 323 : p | m_npoin; + 186 : 335 : void pup( PUP::er &p ) override { + 187 : 335 : p | m_disc; + 188 : 335 : p | m_ghosts; + 189 : 335 : p | m_nsol; + 190 : 335 : p | m_ninitsol; + 191 : 335 : p | m_nlim; + 192 : 335 : p | m_nnod; + 193 : 335 : p | m_u; + 194 : 335 : p | m_un; + 195 : 335 : p | m_p; + 196 : 335 : p | m_lhs; + 197 : 335 : p | m_rhs; + 198 : 335 : p | m_npoin; 199 : : p | m_diag; - 200 : 323 : p | m_stage; + 200 : 335 : p | m_stage; 201 : : p | m_uc; 202 : : p | m_pc; 203 : : p | m_initial; - 204 : 323 : p | m_uElemfields; - 205 : 323 : p | m_pElemfields; - 206 : 323 : p | m_uNodefields; - 207 : 323 : p | m_pNodefields; - 208 : 323 : p | m_uNodefieldsc; - 209 : 323 : p | m_pNodefieldsc; - 210 : 323 : p | m_boxelems; - 211 : 323 : p | m_srcFlag; + 204 : 335 : p | m_uElemfields; + 205 : 335 : p | m_pElemfields; + 206 : 335 : p | m_uNodefields; + 207 : 335 : p | m_pNodefields; + 208 : 335 : p | m_uNodefieldsc; + 209 : 335 : p | m_pNodefieldsc; + 210 : 335 : p | m_boxelems; + 211 : 335 : p | m_srcFlag; 212 : : p | m_rkcoef; 213 : : p | m_nrk; - 214 : 323 : p | m_dte; - 215 : 323 : p | m_finished; - 216 : 323 : } + 214 : 335 : p | m_dte; + 215 : 335 : p | m_finished; + 216 : 335 : } 217 : : //! \brief Pack/Unpack serialize operator| 218 : : //! \param[in,out] p Charm++'s PUP::er serializer object reference 219 : : //! \param[in,out] i FV object reference diff --git a/Release/test_coverage/Inciter/FaceData.cpp.func-sort-c.html b/Release/test_coverage/Inciter/FaceData.cpp.func-sort-c.html index b24639a21cf2..70fc05b81dd9 100644 --- a/Release/test_coverage/Inciter/FaceData.cpp.func-sort-c.html +++ b/Release/test_coverage/Inciter/FaceData.cpp.func-sort-c.html @@ -33,7 +33,7 @@ - + diff --git a/Release/test_coverage/Inciter/FaceData.cpp.func.html b/Release/test_coverage/Inciter/FaceData.cpp.func.html index 0a536031166b..d4369f6093f5 100644 --- a/Release/test_coverage/Inciter/FaceData.cpp.func.html +++ b/Release/test_coverage/Inciter/FaceData.cpp.func.html @@ -33,7 +33,7 @@ - + diff --git a/Release/test_coverage/Inciter/FaceData.cpp.gcov.html b/Release/test_coverage/Inciter/FaceData.cpp.gcov.html index b8f610fb609d..87f3af7296d0 100644 --- a/Release/test_coverage/Inciter/FaceData.cpp.gcov.html +++ b/Release/test_coverage/Inciter/FaceData.cpp.gcov.html @@ -33,7 +33,7 @@ - + diff --git a/Release/test_coverage/Inciter/FaceData.hpp.func-sort-c.html b/Release/test_coverage/Inciter/FaceData.hpp.func-sort-c.html index 76c975d672c6..65dffab29066 100644 --- a/Release/test_coverage/Inciter/FaceData.hpp.func-sort-c.html +++ b/Release/test_coverage/Inciter/FaceData.hpp.func-sort-c.html @@ -33,7 +33,7 @@ - + @@ -73,7 +73,7 @@ - +
  1
-  2
-  3
-  4
-  5
-  6
-  7
-  8
-  9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
- 37
- 38
- 39
- 40
- 41
- 42
- 43
- 44
- 45
- 46
- 47
- 48
- 49
- 50
- 51
- 52
- 53
- 54
- 55
- 56
- 57
- 58
- 59
- 60
- 61
- 62
- 63
- 64
- 65
- 66
- 67
- 68
- 69
- 70
- 71
- 72
- 73
- 74
- 75
- 76
- 77
- 78
- 79
- 80
- 81
- 82
- 83
- 84
- 85
- 86
- 87
- 88
- 89
- 90
- 91
- 92
- 93
- 94
- 95
- 96
- 97
- 98
- 99
-100
-101
-102
-103
-104
-105
-106
-107
-108
-109
-110
-111
-112
-113
-114
-115
-116
-117
-118
-119
-120
-121
-122
-123
-124
-125
-126
-127
-128
-129
-130
-131
-132
-133
-134
-135
-136
-137
-138
-139
-140
-141
-142
-143
-144
-145
-146
-147
-148
-149
-150
-151
-152
-153
-154
-155
-156
-157
-158
-159
-160
-161
-162
-163
-164
-165
-166
-167
-168
-169
-170
-171
-172
-173
-174
-175
-176
-177
-178
-179
-180
-181
-182
-183
-184
-185
-186
-187
-188
-189
-190
-191
-192
-193
-194
-195
-196
-197
-198
-199
-200
-201
-202
-203
-204
-205
-206
-207
-208
-209
-210
-211
-212
-213
-214
-215
-216
-217
-218
-219
-220
-221
-222
-223
-224
-225
-226
-227
-228
-229
-230
-231
-232
-233
-234
-235
-236
-237
-238
-239
-240
-241
-242
-243
-244
-245
-246
-247
-248
-249
-250
-251
-252
-253
-254
-255
-256
-257
-258
-259
-260
-261
-262
-263
-264
-265
-266
-267
-268
-269
-270
-271
-272
-273
-274
-275
-276
-277
-278
-279
-280
-281
-282
-283
-284
-285
-286
-287
-288
-289
-290
-291
-292
-293
-294
-295
-296
-297
-298
-299
-300
-301
-302
-303
-304
-305
-306
-307
-308
-309
-310
-311
-312
-313
-314
-315
-316
-317
-318
-319
-320
-321
-322
-323
-324
-325
-326
-327
-328
-329
-330
-331
-332
-333
-334
-335
-336
-337
-338
-339
-340
-341
-342
-343
-344
-345
-346
-347
-348
-349
-350
-351
-352
-353
-354
-355
-356
-357
-358
-359
-360
-361
-362
-363
-364
-365
-366
-367
-368
-369
-370
-371
-372
-373
-374
-375
-376
-377
-378
-379
-380
-381
-382
-383
-384
-385
-386
-387
-388
-389
-390
-391
-392
-393
-394
-395
-396
-397
-398
-399
-400
-401
-402
-403
-404
-405
-406
-407
-408
-409
-410
-411
-412
-413
-414
-415
-416
-417
-418
-419
-420
-421
-422
-423
-424
-425
-426
-427
-428
-429
-430
-431
-432
-433
-434
-435
-436
-437
-438
-439
-440
-441
-442
-443
-444
-445
-446
-447
-448
-449
-450
-451
-452
-453
-454
-455
-456
-457
-458
-459
-460
-461
-462
-463
-464
-465
-466
-467
-468
-469
-470
-471
-472
-473
-474
-475
-476
-477
-478
-479
-480
-481
-482
-483
-484
-485
-486
-487
-488
-489
-490
-491
-492
-493
-494
-495
-496
-497
-498
-499
-500
-501
-502
-503
-504
-505
-506
-507
-508
-509
-510
-511
-512
-513
-514
-515
-516
-517
-518
-519
-520
-521
-522
-523
-524
-525
-526
-527
-528
-529
-530
-531
-532
-533
-534
-535
-536
-537
-538
-539
-540
-541
-542
-543
-544
-545
-546
-547
-548
-549
-550
-551
-552
-553
-554
-555
-556
-557
-558
-559
-560
-561
-562
-563
-564
-565
-566
-567
-568
-569
-570
-571
-572
-573
-574
-575
-576
-577
-578
-579
-580
-581
-582
-583
-584
-585
-586
-587
-588
-589
-590
-591
-592
-593
-594
-595
-596
-597
-598
-599
-600
-601
-602
-603
-604
-605
-606
-607
-608
-609
-610
-611
-612
-613
-614
-615
-616
-617
-618
-619
-620
-621
-622
-623
-624
-625
-626
-627
-628
-629
-630
-631
-632
-633
-634
-635
-636
-637
-638
-639
-640
-641
-642
-643
-644
-645
-646
-647
-648
-649
-650
-651
-652
-653
-654
-655
-656
-657
-658
-659
-660
-661
-662
-663
-664
-665
-666
-667
-668
-669
-670
-671
-672
-673
-674
-675
-676
-677
-678
-679
-680
-681
-682
-683
-684
-685
-686
-687
-688
-689
-690
-691
-692
-693
-694
-695
-696
-697
-698
-699
-700
-701
-702
-703
-704
-705
-706
-707
-708
-709
-710
-711
-712
-713
-714
-715
-716
-717
-718
-719
-720
-721
-722
-723
-724
-725
-726
-727
-728
-729
-730
-731
-732
-733
-734
-735
-736
-737
-738
-739
-740
-741
-742
-743
-744
-745
-746
-747
-748
-749
-750
-751
-752
-753
-754
-755
-756
-757
-758
-759
-760
-761
-762
-763
-764
-765
-766
-767
-768
-769
-770
-771
-772
-773
-774
-775
-776
-777
-778
-779
-780
-781
-782
-783
-784
-785
-786
-787
-788
-789
-790
-791
-792
-793
-794
-795
-796
-797
-798
// *****************************************************************************
+
   1
+   2
+   3
+   4
+   5
+   6
+   7
+   8
+   9
+  10
+  11
+  12
+  13
+  14
+  15
+  16
+  17
+  18
+  19
+  20
+  21
+  22
+  23
+  24
+  25
+  26
+  27
+  28
+  29
+  30
+  31
+  32
+  33
+  34
+  35
+  36
+  37
+  38
+  39
+  40
+  41
+  42
+  43
+  44
+  45
+  46
+  47
+  48
+  49
+  50
+  51
+  52
+  53
+  54
+  55
+  56
+  57
+  58
+  59
+  60
+  61
+  62
+  63
+  64
+  65
+  66
+  67
+  68
+  69
+  70
+  71
+  72
+  73
+  74
+  75
+  76
+  77
+  78
+  79
+  80
+  81
+  82
+  83
+  84
+  85
+  86
+  87
+  88
+  89
+  90
+  91
+  92
+  93
+  94
+  95
+  96
+  97
+  98
+  99
+ 100
+ 101
+ 102
+ 103
+ 104
+ 105
+ 106
+ 107
+ 108
+ 109
+ 110
+ 111
+ 112
+ 113
+ 114
+ 115
+ 116
+ 117
+ 118
+ 119
+ 120
+ 121
+ 122
+ 123
+ 124
+ 125
+ 126
+ 127
+ 128
+ 129
+ 130
+ 131
+ 132
+ 133
+ 134
+ 135
+ 136
+ 137
+ 138
+ 139
+ 140
+ 141
+ 142
+ 143
+ 144
+ 145
+ 146
+ 147
+ 148
+ 149
+ 150
+ 151
+ 152
+ 153
+ 154
+ 155
+ 156
+ 157
+ 158
+ 159
+ 160
+ 161
+ 162
+ 163
+ 164
+ 165
+ 166
+ 167
+ 168
+ 169
+ 170
+ 171
+ 172
+ 173
+ 174
+ 175
+ 176
+ 177
+ 178
+ 179
+ 180
+ 181
+ 182
+ 183
+ 184
+ 185
+ 186
+ 187
+ 188
+ 189
+ 190
+ 191
+ 192
+ 193
+ 194
+ 195
+ 196
+ 197
+ 198
+ 199
+ 200
+ 201
+ 202
+ 203
+ 204
+ 205
+ 206
+ 207
+ 208
+ 209
+ 210
+ 211
+ 212
+ 213
+ 214
+ 215
+ 216
+ 217
+ 218
+ 219
+ 220
+ 221
+ 222
+ 223
+ 224
+ 225
+ 226
+ 227
+ 228
+ 229
+ 230
+ 231
+ 232
+ 233
+ 234
+ 235
+ 236
+ 237
+ 238
+ 239
+ 240
+ 241
+ 242
+ 243
+ 244
+ 245
+ 246
+ 247
+ 248
+ 249
+ 250
+ 251
+ 252
+ 253
+ 254
+ 255
+ 256
+ 257
+ 258
+ 259
+ 260
+ 261
+ 262
+ 263
+ 264
+ 265
+ 266
+ 267
+ 268
+ 269
+ 270
+ 271
+ 272
+ 273
+ 274
+ 275
+ 276
+ 277
+ 278
+ 279
+ 280
+ 281
+ 282
+ 283
+ 284
+ 285
+ 286
+ 287
+ 288
+ 289
+ 290
+ 291
+ 292
+ 293
+ 294
+ 295
+ 296
+ 297
+ 298
+ 299
+ 300
+ 301
+ 302
+ 303
+ 304
+ 305
+ 306
+ 307
+ 308
+ 309
+ 310
+ 311
+ 312
+ 313
+ 314
+ 315
+ 316
+ 317
+ 318
+ 319
+ 320
+ 321
+ 322
+ 323
+ 324
+ 325
+ 326
+ 327
+ 328
+ 329
+ 330
+ 331
+ 332
+ 333
+ 334
+ 335
+ 336
+ 337
+ 338
+ 339
+ 340
+ 341
+ 342
+ 343
+ 344
+ 345
+ 346
+ 347
+ 348
+ 349
+ 350
+ 351
+ 352
+ 353
+ 354
+ 355
+ 356
+ 357
+ 358
+ 359
+ 360
+ 361
+ 362
+ 363
+ 364
+ 365
+ 366
+ 367
+ 368
+ 369
+ 370
+ 371
+ 372
+ 373
+ 374
+ 375
+ 376
+ 377
+ 378
+ 379
+ 380
+ 381
+ 382
+ 383
+ 384
+ 385
+ 386
+ 387
+ 388
+ 389
+ 390
+ 391
+ 392
+ 393
+ 394
+ 395
+ 396
+ 397
+ 398
+ 399
+ 400
+ 401
+ 402
+ 403
+ 404
+ 405
+ 406
+ 407
+ 408
+ 409
+ 410
+ 411
+ 412
+ 413
+ 414
+ 415
+ 416
+ 417
+ 418
+ 419
+ 420
+ 421
+ 422
+ 423
+ 424
+ 425
+ 426
+ 427
+ 428
+ 429
+ 430
+ 431
+ 432
+ 433
+ 434
+ 435
+ 436
+ 437
+ 438
+ 439
+ 440
+ 441
+ 442
+ 443
+ 444
+ 445
+ 446
+ 447
+ 448
+ 449
+ 450
+ 451
+ 452
+ 453
+ 454
+ 455
+ 456
+ 457
+ 458
+ 459
+ 460
+ 461
+ 462
+ 463
+ 464
+ 465
+ 466
+ 467
+ 468
+ 469
+ 470
+ 471
+ 472
+ 473
+ 474
+ 475
+ 476
+ 477
+ 478
+ 479
+ 480
+ 481
+ 482
+ 483
+ 484
+ 485
+ 486
+ 487
+ 488
+ 489
+ 490
+ 491
+ 492
+ 493
+ 494
+ 495
+ 496
+ 497
+ 498
+ 499
+ 500
+ 501
+ 502
+ 503
+ 504
+ 505
+ 506
+ 507
+ 508
+ 509
+ 510
+ 511
+ 512
+ 513
+ 514
+ 515
+ 516
+ 517
+ 518
+ 519
+ 520
+ 521
+ 522
+ 523
+ 524
+ 525
+ 526
+ 527
+ 528
+ 529
+ 530
+ 531
+ 532
+ 533
+ 534
+ 535
+ 536
+ 537
+ 538
+ 539
+ 540
+ 541
+ 542
+ 543
+ 544
+ 545
+ 546
+ 547
+ 548
+ 549
+ 550
+ 551
+ 552
+ 553
+ 554
+ 555
+ 556
+ 557
+ 558
+ 559
+ 560
+ 561
+ 562
+ 563
+ 564
+ 565
+ 566
+ 567
+ 568
+ 569
+ 570
+ 571
+ 572
+ 573
+ 574
+ 575
+ 576
+ 577
+ 578
+ 579
+ 580
+ 581
+ 582
+ 583
+ 584
+ 585
+ 586
+ 587
+ 588
+ 589
+ 590
+ 591
+ 592
+ 593
+ 594
+ 595
+ 596
+ 597
+ 598
+ 599
+ 600
+ 601
+ 602
+ 603
+ 604
+ 605
+ 606
+ 607
+ 608
+ 609
+ 610
+ 611
+ 612
+ 613
+ 614
+ 615
+ 616
+ 617
+ 618
+ 619
+ 620
+ 621
+ 622
+ 623
+ 624
+ 625
+ 626
+ 627
+ 628
+ 629
+ 630
+ 631
+ 632
+ 633
+ 634
+ 635
+ 636
+ 637
+ 638
+ 639
+ 640
+ 641
+ 642
+ 643
+ 644
+ 645
+ 646
+ 647
+ 648
+ 649
+ 650
+ 651
+ 652
+ 653
+ 654
+ 655
+ 656
+ 657
+ 658
+ 659
+ 660
+ 661
+ 662
+ 663
+ 664
+ 665
+ 666
+ 667
+ 668
+ 669
+ 670
+ 671
+ 672
+ 673
+ 674
+ 675
+ 676
+ 677
+ 678
+ 679
+ 680
+ 681
+ 682
+ 683
+ 684
+ 685
+ 686
+ 687
+ 688
+ 689
+ 690
+ 691
+ 692
+ 693
+ 694
+ 695
+ 696
+ 697
+ 698
+ 699
+ 700
+ 701
+ 702
+ 703
+ 704
+ 705
+ 706
+ 707
+ 708
+ 709
+ 710
+ 711
+ 712
+ 713
+ 714
+ 715
+ 716
+ 717
+ 718
+ 719
+ 720
+ 721
+ 722
+ 723
+ 724
+ 725
+ 726
+ 727
+ 728
+ 729
+ 730
+ 731
+ 732
+ 733
+ 734
+ 735
+ 736
+ 737
+ 738
+ 739
+ 740
+ 741
+ 742
+ 743
+ 744
+ 745
+ 746
+ 747
+ 748
+ 749
+ 750
+ 751
+ 752
+ 753
+ 754
+ 755
+ 756
+ 757
+ 758
+ 759
+ 760
+ 761
+ 762
+ 763
+ 764
+ 765
+ 766
+ 767
+ 768
+ 769
+ 770
+ 771
+ 772
+ 773
+ 774
+ 775
+ 776
+ 777
+ 778
+ 779
+ 780
+ 781
+ 782
+ 783
+ 784
+ 785
+ 786
+ 787
+ 788
+ 789
+ 790
+ 791
+ 792
+ 793
+ 794
+ 795
+ 796
+ 797
+ 798
+ 799
+ 800
+ 801
+ 802
+ 803
+ 804
+ 805
+ 806
+ 807
+ 808
+ 809
+ 810
+ 811
+ 812
+ 813
+ 814
+ 815
+ 816
+ 817
+ 818
+ 819
+ 820
+ 821
+ 822
+ 823
+ 824
+ 825
+ 826
+ 827
+ 828
+ 829
+ 830
+ 831
+ 832
+ 833
+ 834
+ 835
+ 836
+ 837
+ 838
+ 839
+ 840
+ 841
+ 842
+ 843
+ 844
+ 845
+ 846
+ 847
+ 848
+ 849
+ 850
+ 851
+ 852
+ 853
+ 854
+ 855
+ 856
+ 857
+ 858
+ 859
+ 860
+ 861
+ 862
+ 863
+ 864
+ 865
+ 866
+ 867
+ 868
+ 869
+ 870
+ 871
+ 872
+ 873
+ 874
+ 875
+ 876
+ 877
+ 878
+ 879
+ 880
+ 881
+ 882
+ 883
+ 884
+ 885
+ 886
+ 887
+ 888
+ 889
+ 890
+ 891
+ 892
+ 893
+ 894
+ 895
+ 896
+ 897
+ 898
+ 899
+ 900
+ 901
+ 902
+ 903
+ 904
+ 905
+ 906
+ 907
+ 908
+ 909
+ 910
+ 911
+ 912
+ 913
+ 914
+ 915
+ 916
+ 917
+ 918
+ 919
+ 920
+ 921
+ 922
+ 923
+ 924
+ 925
+ 926
+ 927
+ 928
+ 929
+ 930
+ 931
+ 932
+ 933
+ 934
+ 935
+ 936
+ 937
+ 938
+ 939
+ 940
+ 941
+ 942
+ 943
+ 944
+ 945
+ 946
+ 947
+ 948
+ 949
+ 950
+ 951
+ 952
+ 953
+ 954
+ 955
+ 956
+ 957
+ 958
+ 959
+ 960
+ 961
+ 962
+ 963
+ 964
+ 965
+ 966
+ 967
+ 968
+ 969
+ 970
+ 971
+ 972
+ 973
+ 974
+ 975
+ 976
+ 977
+ 978
+ 979
+ 980
+ 981
+ 982
+ 983
+ 984
+ 985
+ 986
+ 987
+ 988
+ 989
+ 990
+ 991
+ 992
+ 993
+ 994
+ 995
+ 996
+ 997
+ 998
+ 999
+1000
+1001
+1002
+1003
+1004
+1005
+1006
+1007
+1008
+1009
+1010
+1011
+1012
+1013
+1014
+1015
+1016
+1017
+1018
+1019
+1020
+1021
+1022
+1023
+1024
+1025
+1026
+1027
+1028
+1029
+1030
+1031
+1032
+1033
+1034
+1035
+1036
+1037
+1038
+1039
+1040
+1041
+1042
+1043
+1044
+1045
+1046
+1047
+1048
+1049
+1050
+1051
+1052
+1053
+1054
+1055
+1056
+1057
+1058
+1059
+1060
+1061
+1062
+1063
+1064
+1065
+1066
+1067
+1068
+1069
+1070
+1071
+1072
+1073
+1074
+1075
+1076
+1077
+1078
+1079
+1080
+1081
+1082
+1083
+1084
+1085
+1086
+1087
+1088
+1089
+1090
+1091
+1092
+1093
+1094
+1095
+1096
+1097
+1098
+1099
+1100
+1101
+1102
+1103
+1104
+1105
+1106
+1107
+1108
+1109
+1110
+1111
+1112
+1113
+1114
+1115
+1116
+1117
+1118
+1119
+1120
+1121
+1122
+1123
+1124
+1125
+1126
+1127
+1128
+1129
+1130
+1131
+1132
+1133
+1134
+1135
+1136
+1137
+1138
+1139
+1140
+1141
+1142
+1143
+1144
+1145
+1146
+1147
+1148
+1149
+1150
+1151
+1152
+1153
+1154
+1155
+1156
+1157
+1158
+1159
+1160
+1161
+1162
+1163
+1164
+1165
+1166
+1167
+1168
+1169
+1170
+1171
+1172
+1173
+1174
+1175
+1176
+1177
+1178
+1179
+1180
+1181
+1182
+1183
+1184
+1185
+1186
+1187
+1188
+1189
+1190
+1191
+1192
+1193
+1194
+1195
+1196
+1197
+1198
+1199
+1200
+1201
+1202
+1203
+1204
+1205
+1206
+1207
+1208
+1209
+1210
+1211
+1212
+1213
+1214
+1215
+1216
+1217
+1218
+1219
+1220
+1221
+1222
+1223
+1224
+1225
+1226
+1227
+1228
+1229
+1230
+1231
+1232
+1233
+1234
+1235
+1236
+1237
+1238
+1239
+1240
+1241
+1242
+1243
+1244
+1245
+1246
+1247
+1248
+1249
+1250
+1251
+1252
+1253
+1254
+1255
+1256
+1257
+1258
+1259
+1260
+1261
+1262
+1263
+1264
+1265
+1266
+1267
+1268
+1269
+1270
+1271
+1272
+1273
+1274
+1275
+1276
+1277
+1278
+1279
+1280
+1281
+1282
+1283
+1284
+1285
+1286
+1287
+1288
+1289
+1290
+1291
+1292
// *****************************************************************************
 /*!
-  \file      src/PDE/Transport/CGTransport.hpp
+  \file      src/PDE/CompFlow/DGCompFlow.hpp
   \copyright 2012-2015 J. Bakosi,
              2016-2018 Los Alamos National Security, LLC.,
              2019-2021 Triad National Security, LLC.
              All rights reserved. See the LICENSE file for details.
-  \brief     Scalar transport using continous Galerkin discretization
-  \details   This file implements the physics operators governing transported
-     scalars using continuous Galerkin discretization.
-*/
-// *****************************************************************************
-#ifndef CGTransport_h
-#define CGTransport_h
-
-#include <vector>
-#include <array>
-#include <limits>
-#include <cmath>
+  \brief     Compressible single-material flow using discontinuous Galerkin
+     finite elements
+  \details   This file implements calls to the physics operators governing
+    compressible single-material flow using discontinuous Galerkin
+    discretizations.
+*/
+// *****************************************************************************
+#ifndef DGCompFlow_h
+#define DGCompFlow_h
+
+#include <cmath>
+#include <algorithm>
 #include <unordered_set>
-#include <unordered_map>
+#include <map>
 
-#include "Exception.hpp"
-#include "Vector.hpp"
-#include "DerivedData.hpp"
-#include "Around.hpp"
-#include "Reconstruction.hpp"
-#include "Inciter/InputDeck/InputDeck.hpp"
-#include "CGPDE.hpp"
-#include "History.hpp"
-
-namespace inciter {
-
-extern ctr::InputDeck g_inputdeck;
-
-namespace cg {
-
-//! \brief Transport equation used polymorphically with tk::CGPDE
-//! \details The template argument(s) specify policies and are used to configure
-//!   the behavior of the class. The policies are:
-//!   - Physics - physics configuration, see PDE/Transport/Physics/CG.h
-//!   - Problem - problem configuration, see PDE/Transport/Problem.h
-//! \note The default physics is CGAdvection, set in
-//!    inciter::deck::check_transport()
-template< class Physics, class Problem >
-class Transport {
-
-  private:
-    using ncomp_t = tk::ncomp_t;
-    using real = tk::real;
-    using eq = tag::transport;
-
-    static constexpr real muscl_eps = 1.0e-9;
-    static constexpr real muscl_const = 1.0/3.0;
-    static constexpr real muscl_m1 = 1.0 - muscl_const;
-    static constexpr real muscl_p1 = 1.0 + muscl_const;
-
-  public:
-    //! Constructor
-    explicit Transport() :
-      m_physics( Physics() ),
-      m_problem( Problem() ),
-      m_ncomp(g_inputdeck.get< tag::ncomp >())
-    {
-      m_problem.errchk( m_ncomp );
-    }
-
-    //! Determine nodes that lie inside the user-defined IC box
-    void
-    IcBoxNodes( const tk::UnsMesh::Coords&,
-                const std::vector< std::size_t >&,
-                const std::unordered_map< std::size_t, std::set< std::size_t > >&,
-                std::vector< std::unordered_set< std::size_t > >&,
-                std::unordered_map< std::size_t, std::set< std::size_t > >&,
-                std::size_t& ) const {}
-
-    //! Initalize the transport equations using problem policy
-    //! \param[in] coord Mesh node coordinates
-    //! \param[in,out] unk Array of unknowns
-    //! \param[in] t Physical time
-    void
-    initialize( const std::array< std::vector< real >, 3 >& coord,
-                tk::Fields& unk,
-                real t,
-                real,
-                const std::vector< std::unordered_set< std::size_t > >&,
-                const std::vector< tk::real >&,
-                const std::unordered_map< std::size_t, std::set< std::size_t > >&
-              ) const
-    {
-      Assert( coord[0].size() == unk.nunk(), "Size mismatch" );
-      const auto& x = coord[0];
-      const auto& y = coord[1];
-      const auto& z = coord[2];
-      for (ncomp_t i=0; i<x.size(); ++i) {
-        auto s = Problem::initialize( m_ncomp, m_mat_blk, x[i], y[i],
-                                      z[i], t );
-        for (ncomp_t c=0; c<m_ncomp; ++c)
-          unk( i, c ) = s[c];
-      }
-    }
-
-    //! Query a velocity
-    //! \note Since this function does not touch its output argument, that
-    //!   means this system does not define a "velocity".
-    void velocity( const tk::Fields&, tk::UnsMesh::Coords& ) const {}
-
-    //! Query the sound speed
-    //! \note Since this function does not touch its output argument, that
-    //!   means this system does not define a "sound speed".
-    void soundspeed( const tk::Fields&, std::vector< tk::real >& ) const {}
-
-    //! Return analytic solution (if defined by Problem) at xi, yi, zi, t
-    //! \param[in] xi X-coordinate
-    //! \param[in] yi Y-coordinate
-    //! \param[in] zi Z-coordinate
-    //! \param[in] t Physical time
-    //! \return Vector of analytic solution at given location and time
-    std::vector< real >
-    analyticSolution( real xi, real yi, real zi, real t ) const
-    { return Problem::analyticSolution( m_ncomp, m_mat_blk, xi, yi, zi, t ); }
-
-    //! Return analytic solution for conserved variables
-    //! \param[in] xi X-coordinate at which to evaluate the analytic solution
-    //! \param[in] yi Y-coordinate at which to evaluate the analytic solution
-    //! \param[in] zi Z-coordinate at which to evaluate the analytic solution
-    //! \param[in] t Physical time at which to evaluate the analytic solution
-    //! \return Vector of analytic solution at given location and time
-    std::vector< tk::real >
-    solution( tk::real xi, tk::real yi, tk::real zi, tk::real t ) const
-    { return Problem::initialize( m_ncomp, m_mat_blk, xi, yi, zi, t ); }
-
-    //! Compute nodal gradients of primitive variables for ALECG
-    //! \param[in] coord Mesh node coordinates
-    //! \param[in] inpoel Mesh element connectivity
-    //! \param[in] bndel List of elements contributing to chare-boundary nodes
-    //! \param[in] gid Local->global node id map
-    //! \param[in] bid Local chare-boundary node ids (value) associated to
-    //!    global node ids (key)
-    //! \param[in] U Solution vector at recent time step
-    //! \param[in,out] G Nodal gradients of primitive variables
-    void chBndGrad( const std::array< std::vector< real >, 3 >& coord,
-      const std::vector< std::size_t >& inpoel,
-      const std::vector< std::size_t >& bndel,
-      const std::vector< std::size_t >& gid,
-      const std::unordered_map< std::size_t, std::size_t >& bid,
-      const tk::Fields& U,
-      tk::Fields& G ) const
-    {
-      Assert( U.nunk() == coord[0].size(), "Number of unknowns in solution "
-              "vector at recent time step incorrect" );
-
-      // compute gradients of primitive variables in points
-      G.fill( 0.0 );
-
-      // access node cooordinates
-      const auto& x = coord[0];
-      const auto& y = coord[1];
-      const auto& z = coord[2];
-
-      for (auto e : bndel) {  // elements contributing to chare boundary nodes
-        // access node IDs
-        std::size_t N[4] =
-          { inpoel[e*4+0], inpoel[e*4+1], inpoel[e*4+2], inpoel[e*4+3] };
-        // compute element Jacobi determinant, J = 6V
-        real bax = x[N[1]]-x[N[0]];
-        real bay = y[N[1]]-y[N[0]];
-        real baz = z[N[1]]-z[N[0]];
-        real cax = x[N[2]]-x[N[0]];
-        real cay = y[N[2]]-y[N[0]];
-        real caz = z[N[2]]-z[N[0]];
-        real dax = x[N[3]]-x[N[0]];
-        real day = y[N[3]]-y[N[0]];
-        real daz = z[N[3]]-z[N[0]];
-        auto J = tk::triple( bax, bay, baz, cax, cay, caz, dax, day, daz );
-        auto J24 = J/24.0;
-        // shape function derivatives, nnode*ndim [4][3]
-        real g[4][3];
-        tk::crossdiv( cax, cay, caz, dax, day, daz, J,
-                      g[1][0], g[1][1], g[1][2] );
-        tk::crossdiv( dax, day, daz, bax, bay, baz, J,
-                      g[2][0], g[2][1], g[2][2] );
-        tk::crossdiv( bax, bay, baz, cax, cay, caz, J,
-                      g[3][0], g[3][1], g[3][2] );
-        for (std::size_t i=0; i<3; ++i)
-          g[0][i] = -g[1][i] - g[2][i] - g[3][i];
-        // scatter-add gradient contributions to boundary nodes
-        for (std::size_t a=0; a<4; ++a) {
-          auto i = bid.find( gid[N[a]] );
-          if (i != end(bid))
-            for (std::size_t c=0; c<m_ncomp; ++c)
-              for (std::size_t b=0; b<4; ++b)
-                for (std::size_t j=0; j<3; ++j)
-                  G(i->second,c*3+j) += J24 * g[b][j] * U(N[b],c);
-        }
-      }
-    }
-
-    //! Compute right hand side for ALECG
-    //! \param[in] coord Mesh node coordinates
-    //! \param[in] inpoel Mesh element connectivity
-    //! \param[in] triinpoel Boundary triangle face connecitivity
-    //! \param[in] bid Local chare-boundary node ids (value) associated to
-    //!    global node ids (key)
-    //! \param[in] lid Global->local node ids
-    //! \param[in] dfn Dual-face normals
-    //! \param[in] psup Points surrounding points
-    //! \param[in] esup Elements surrounding points
-    //! \param[in] symbctri Vector with 1 at symmetry BC nodes
-    //! \param[in] vol Nodal volumes
-    //! \param[in] edgeid Local node id pair -> edge id map
-    //! \param[in] G Nodal gradients in chare-boundary nodes
-    //! \param[in] U Solution vector at recent time step
-    //! \param[in] W Mesh velocity
-    //! \param[in,out] R Right-hand side vector computed
-    void rhs(
-      real,
-      const std::array< std::vector< real >, 3 >&  coord,
-      const std::vector< std::size_t >& inpoel,
-      const std::vector< std::size_t >& triinpoel,
-      const std::vector< std::size_t >&,
-      const std::unordered_map< std::size_t, std::size_t >& bid,
-      const std::unordered_map< std::size_t, std::size_t >& lid,
-      const std::vector< real >& dfn,
-      const std::pair< std::vector< std::size_t >,
-                       std::vector< std::size_t > >& psup,
-      const std::pair< std::vector< std::size_t >,
-                       std::vector< std::size_t > >& esup,
-      const std::vector< int >& symbctri,
-      const std::vector< real >& vol,
-      const std::vector< std::size_t >&,
-      const std::vector< std::size_t >& edgeid,
-      const std::vector< std::unordered_set< std::size_t > >&,
-      const tk::Fields& G,
-      const tk::Fields& U,
-      [[maybe_unused]] const tk::Fields& W,
-      const std::vector< tk::real >&,
-      real,
-      tk::Fields& R ) const
-    {
-      Assert( G.nprop() == m_ncomp*3,
-              "Number of components in gradient vector incorrect" );
-      Assert( U.nunk() == coord[0].size(), "Number of unknowns in solution "
-              "vector at recent time step incorrect" );
-      Assert( R.nunk() == coord[0].size(),
-              "Number of unknowns and/or number of components in right-hand "
-              "side vector incorrect" );
+#include <brigand/algorithms/for_each.hpp>
+
+#include "Macro.hpp"
+#include "Exception.hpp"
+#include "Vector.hpp"
+#include "ContainerUtil.hpp"
+#include "UnsMesh.hpp"
+#include "Inciter/InputDeck/InputDeck.hpp"
+#include "Integrate/Basis.hpp"
+#include "Integrate/Quadrature.hpp"
+#include "Integrate/Initialize.hpp"
+#include "Integrate/Mass.hpp"
+#include "Integrate/Surface.hpp"
+#include "Integrate/Boundary.hpp"
+#include "Integrate/Volume.hpp"
+#include "Integrate/Source.hpp"
+#include "RiemannChoice.hpp"
+#include "EoS/EOS.hpp"
+#include "Reconstruction.hpp"
+#include "Limiter.hpp"
+#include "PrefIndicator.hpp"
+
+namespace inciter {
+
+extern ctr::InputDeck g_inputdeck;
+
+namespace dg {
+
+//! \brief CompFlow used polymorphically with tk::DGPDE
+//! \details The template arguments specify policies and are used to configure
+//!   the behavior of the class. The policies are:
+//!   - Physics - physics configuration, see PDE/CompFlow/Physics.h
+//!   - Problem - problem configuration, see PDE/CompFlow/Problem.h
+//! \note The default physics is Euler, set in inciter::deck::check_compflow()
+template< class Physics, class Problem >
+class CompFlow {
+
+  private:
+    using eq = tag::compflow;
+
+  public:
+    //! Constructor
+    explicit CompFlow() :
+      m_physics(),
+      m_problem(),
+      m_ncomp( g_inputdeck.get< tag::ncomp >() ),
+      m_riemann( compflowRiemannSolver(
+        g_inputdeck.get< tag::flux >() ) )
+    {
+      // associate boundary condition configurations with state functions, the
+      // order in which the state functions listed matters, see ctr::bc::Keys
+      brigand::for_each< ctr::bclist::Keys >( ConfigBC( m_bc,
+        { dirichlet
+        , symmetry
+        , invalidBC         // Inlet BC not implemented
+        , invalidBC         // Outlet BC not implemented
+        , farfield
+        , extrapolate } ) );
+
+      // EoS initialization
+      const auto& matprop =
+        g_inputdeck.get< tag::material >();
+      const auto& matidxmap =
+        g_inputdeck.get< tag::matidxmap >();
+      auto mateos = matprop[matidxmap.get< tag::eosidx >()[0]].get<tag::eos>();
+      m_mat_blk.emplace_back(mateos, EqType::compflow, 0);
+
+    }
+
+    //! Find the number of primitive quantities required for this PDE system
+    //! \return The number of primitive quantities required to be stored for
+    //!   this PDE system
+    std::size_t nprim() const
+    {
+      // compflow does not need/store any primitive quantities currently
+      return 0;
+    }
+
+    //! Find the number of materials set up for this PDE system
+    //! \return The number of materials set up for this PDE system
+    std::size_t nmat() const
+    {
+      // compflow does not need nmat
+      return 0;
+    }
+
+    //! Assign number of DOFs per equation in the PDE system
+    //! \param[in,out] numEqDof Array storing number of Dofs for each PDE
+    //!   equation
+    void numEquationDofs(std::vector< std::size_t >& numEqDof) const
+    {
+      // all equation-dofs initialized to ndof
+      for (std::size_t i=0; i<m_ncomp; ++i) {
+        numEqDof.push_back(g_inputdeck.get< tag::ndof >());
+      }
+    }
+
+    //! Determine elements that lie inside the user-defined IC box
+    //! \param[in] geoElem Element geometry array
+    //! \param[in] nielem Number of internal elements
+    //! \param[in,out] inbox List of nodes at which box user ICs are set for
+    //!    each IC box
+    void IcBoxElems( const tk::Fields& geoElem,
+      std::size_t nielem,
+      std::vector< std::unordered_set< std::size_t > >& inbox ) const
+    {
+      tk::BoxElems< eq >(geoElem, nielem, inbox);
+    }
+
+    //! Find how 'stiff equations', which we currently
+    //! have none for Compflow
+    //! \return number of stiff equations
+    std::size_t nstiffeq() const
+    { return 0; }
+
+    //! Find how 'nonstiff equations', which we currently
+    //! don't use for Compflow
+    //! \return number of non-stiff equations
+    std::size_t nnonstiffeq() const
+    { return 0; }
+
+    //! Locate the stiff equations. Unused for compflow.
+    //! \param[out] stiffEqIdx list
+    void setStiffEqIdx( std::vector< std::size_t >& stiffEqIdx ) const
+    {
+      stiffEqIdx.resize(0);
+    }
+
+    //! Locate the nonstiff equations. Unused for compflow.
+    //! \param[out] nonStiffEqIdx list
+    void setNonStiffEqIdx( std::vector< std::size_t >& nonStiffEqIdx ) const
+    {
+      nonStiffEqIdx.resize(0);
+    }
+
+    //! Initalize the compressible flow equations, prepare for time integration
+    //! \param[in] L Block diagonal mass matrix
+    //! \param[in] inpoel Element-node connectivity
+    //! \param[in] coord Array of nodal coordinates
+    //! \param[in] inbox List of elements at which box user ICs are set for
+    //!    each IC box
+    //! \param[in,out] unk Array of unknowns
+    //! \param[in] t Physical time
+    //! \param[in] nielem Number of internal elements
+    void
+    initialize( const tk::Fields& L,
+                const std::vector< std::size_t >& inpoel,
+                const tk::UnsMesh::Coords& coord,
+                const std::vector< std::unordered_set< std::size_t > >& inbox,
+                const std::unordered_map< std::size_t,
+                  std::set< std::size_t > >&,
+                tk::Fields& unk,
+                tk::real t,
+                const std::size_t nielem ) const
+    {
+      tk::initialize( m_ncomp, m_mat_blk, L, inpoel, coord,
+                      Problem::initialize, unk, t, nielem );
+
+      const auto rdof = g_inputdeck.get< tag::rdof >();
+      const auto& ic = g_inputdeck.get< tag::ic >();
+      const auto& icbox = ic.get< tag::box >();
+      const auto& bgpreic = ic.get< tag::pressure >();
+      auto c_v = getmatprop< tag::cv >();
+
+      // Set initial conditions inside user-defined IC box
+      std::vector< tk::real > s(m_ncomp, 0.0);
+      for (std::size_t e=0; e<nielem; ++e) {
+        if (icbox.size() > 0) {
+          std::size_t bcnt = 0;
+          for (const auto& b : icbox) {   // for all boxes
+            if (inbox.size() > bcnt && inbox[bcnt].find(e) != inbox[bcnt].end())
+            {
+              std::vector< tk::real > box
+              { b.template get< tag::xmin >(), b.template get< tag::xmax >(),
+                b.template get< tag::ymin >(), b.template get< tag::ymax >(),
+                b.template get< tag::zmin >(), b.template get< tag::zmax >() };
+              auto V_ex = (box[1]-box[0]) * (box[3]-box[2]) * (box[5]-box[4]);
+              for (std::size_t c=0; c<m_ncomp; ++c) {
+                auto mark = c*rdof;
+                s[c] = unk(e,mark);
+                // set high-order DOFs to zero
+                for (std::size_t i=1; i<rdof; ++i)
+                  unk(e,mark+i) = 0.0;
+              }
+              initializeBox<ctr::boxList>( m_mat_blk, 1.0, V_ex,
+                t, b, bgpreic, c_v, s );
+              // store box-initialization in solution vector
+              for (std::size_t c=0; c<m_ncomp; ++c) {
+                auto mark = c*rdof;
+                unk(e,mark) = s[c];
+              }
+            }
+            ++bcnt;
+          }
+        }
+      }
+    }
+
+    //! Save initial densities for all materials
+    //! \param[out] rho0mat List of initial densities
+    void setRho0mat( std::vector< tk::real >& rho0mat ) const
+    {
+      rho0mat.resize(0);
+    }
+
+    //! Compute density constraint for a given material
+    // //! \param[in] nelem Number of elements
+    // //! \param[in] unk Array of unknowns
+    // //! \param[in] rho0mat List of initial densities
+    //! \param[out] densityConstr Density Constraint: rho/(rho0*det(g))
+    void computeDensityConstr( std::size_t /*nelem*/,
+                               tk::Fields& /*unk*/,
+                               std::vector< tk::real >& /*rho0mat*/,
+                               std::vector< tk::real >& densityConstr) const
+    {
+      densityConstr.resize(0);
+    }
+
+    //! Compute the left hand side block-diagonal mass matrix
+    //! \param[in] geoElem Element geometry array
+    //! \param[in,out] l Block diagonal mass matrix
+    void lhs( const tk::Fields& geoElem, tk::Fields& l ) const {
+      const auto ndof = g_inputdeck.get< tag::ndof >();
+      tk::mass( m_ncomp, ndof, geoElem, l );
+    }
 
-      // compute/assemble gradients in points
-      auto Grad = nodegrad( coord, inpoel, lid, bid, vol, esup, U, G );
-
-      // zero right hand side for all components
-      for (ncomp_t c=0; c<m_ncomp; ++c) R.fill( c, 0.0 );
-
-      // compute domain-edge integral
-      domainint( coord, inpoel, edgeid, psup, dfn, U, Grad, R );
-
-      // compute boundary integrals
-      bndint( coord, triinpoel, symbctri, U, R );
-    }
-
-    //! Compute overset mesh motion for OversetFE (no-op for transport)
-    void getMeshVel(
-      real,
-      const std::array< std::vector< real >, 3 >&,
-      const std::pair< std::vector< std::size_t >,
-                       std::vector< std::size_t > >&,
-      const std::unordered_set< std::size_t >&,
-      const std::array< tk::real, 3 >&,
-      const tk::Fields&,
-      tk::Fields&,
-      int& ) const
-    { }
-
-    //! Compute the minimum time step size (for unsteady time stepping)
-    //! \param[in] U Solution vector at recent time step
-    //! \param[in] coord Mesh node coordinates
-    //! \param[in] inpoel Mesh element connectivity
-    //! \param[in] t Physical time
-    //! \return Minimum time step size
-    real dt( const std::array< std::vector< real >, 3 >& coord,
-             const std::vector< std::size_t >& inpoel,
-             tk::real t,
-             tk::real,
-             const tk::Fields& U,
-             const std::vector< tk::real >&,
-             const std::vector< tk::real >& ) const
-    {
-      using tag::transport;
-      Assert( U.nunk() == coord[0].size(), "Number of unknowns in solution "
-              "vector at recent time step incorrect" );
-      const auto& x = coord[0];
-      const auto& y = coord[1];
-      const auto& z = coord[2];
-      // compute the minimum dt across all elements we own
-      auto mindt = std::numeric_limits< tk::real >::max();
-      auto eps = std::numeric_limits< tk::real >::epsilon();
-      auto large = std::numeric_limits< tk::real >::max();
-      for (std::size_t e=0; e<inpoel.size()/4; ++e) {
-        const std::array< std::size_t, 4 >
-          N{{ inpoel[e*4+0], inpoel[e*4+1], inpoel[e*4+2], inpoel[e*4+3] }};
-        // compute cubic root of element volume as the characteristic length
-        const std::array< real, 3 >
-          ba{{ x[N[1]]-x[N[0]], y[N[1]]-y[N[0]], z[N[1]]-z[N[0]] }},
-          ca{{ x[N[2]]-x[N[0]], y[N[2]]-y[N[0]], z[N[2]]-z[N[0]] }},
-          da{{ x[N[3]]-x[N[0]], y[N[3]]-y[N[0]], z[N[3]]-z[N[0]] }};
-        const auto L = std::cbrt( tk::triple( ba, ca, da ) / 6.0 );
-        // access solution at element nodes at recent time step
-        std::vector< std::array< real, 4 > > u( m_ncomp );
-        for (ncomp_t c=0; c<m_ncomp; ++c) u[c] = U.extract( c, N );
-        // get velocity for problem
-        const std::array< std::vector<std::array<real,3>>, 4 > vel{{
-          Problem::prescribedVelocity( m_ncomp,
-                                       x[N[0]], y[N[0]], z[N[0]], t ),
-          Problem::prescribedVelocity( m_ncomp,
-                                       x[N[1]], y[N[1]], z[N[1]], t ),
-          Problem::prescribedVelocity( m_ncomp,
-                                       x[N[2]], y[N[2]], z[N[2]], t ),
-          Problem::prescribedVelocity( m_ncomp,
-                                       x[N[3]], y[N[3]], z[N[3]], t ) }};
-        // compute the maximum length of the characteristic velocity (advection
-        // velocity) across the four element nodes
-        real maxvel = 0.0;
-        for (ncomp_t c=0; c<m_ncomp; ++c)
-          for (std::size_t i=0; i<4; ++i) {
-            auto v = tk::length( vel[i][c] );
-            if (v > maxvel) maxvel = v;
-          }
-        // compute element dt for the advection
-        auto advection_dt = std::abs(maxvel) > eps ? L / maxvel : large;
-        // compute element dt based on diffusion
-        auto diffusion_dt = m_physics.diffusion_dt( m_ncomp, L, u );
-        // compute minimum element dt
-        auto elemdt = std::min( advection_dt, diffusion_dt );
-        // find minimum dt across all elements
-        if (elemdt < mindt) mindt = elemdt;
-      }
-      return mindt * g_inputdeck.get< tag::cfl >();
-    }
-
-    //! Compute a time step size for each mesh node (for steady time stepping)
-    void dt( uint64_t,
-             const std::vector< tk::real >&,
-             const tk::Fields&,
-             std::vector< tk::real >& ) const {}
-
-    //! \brief Query Dirichlet boundary condition value on a given side set for
-    //!    all components in this PDE system
-    //! \param[in] t Physical time
-    //! \param[in] deltat Time step size
-    //! \param[in] tp Physical time for each mesh node
-    //! \param[in] dtp Time step size for each mesh node
-    //! \param[in] ss Pair of side set ID and list of node IDs on the side set
-    //! \param[in] coord Mesh node coordinates
-    //! \param[in] increment If true, evaluate the solution increment between
-    //!   t and t+dt for Dirichlet BCs. If false, evlauate the solution instead.
-    //! \return Vector of pairs of bool and boundary condition value associated
-    //!   to mesh node IDs at which Dirichlet boundary conditions are set. Note
-    //!   that if increment is true, instead of the actual boundary condition
-    //!   value, we return the increment between t+deltat and t, since,
-    //!   depending on client code and solver, that may be what the solution
-    //!   requires.
-    std::map< std::size_t, std::vector< std::pair<bool,real> > >
-    dirbc( real t,
-           real deltat,
-           const std::vector< tk::real >& tp,
-           const std::vector< tk::real >& dtp,
-           const std::pair< const int, std::vector< std::size_t > >& ss,
-           const std::array< std::vector< real >, 3 >& coord,
-           bool increment ) const
-    {
-      using NodeBC = std::vector< std::pair< bool, real > >;
-      std::map< std::size_t, NodeBC > bc;
-      const auto& ubc = g_inputdeck.get< tag::bc >()[0].get< tag::dirichlet >();
-      const auto steady = g_inputdeck.get< tag::steady_state >();<--- Variable 'steady' is assigned a value that is never used.
-      if (!ubc.empty()) {
-        Assert( ubc.size() > 0, "Indexing out of Dirichlet BC eq-vector" );
-        const auto& x = coord[0];
-        const auto& y = coord[1];
-        const auto& z = coord[2];
-        for (const auto& b : ubc)
-          if (static_cast<int>(b) == ss.first)
-            for (auto n : ss.second) {
-              Assert( x.size() > n, "Indexing out of coordinate array" );
-              if (steady) { t = tp[n]; deltat = dtp[n]; }
-              const auto s = increment ?
-                solinc( m_ncomp, m_mat_blk, x[n], y[n], z[n],
-                        t, deltat, Problem::initialize ) :
-                Problem::initialize( m_ncomp, m_mat_blk, x[n], y[n],
-                                     z[n], t+deltat );
-              auto& nbc = bc[n] = NodeBC( m_ncomp );
-              for (ncomp_t c=0; c<m_ncomp; ++c)
-                nbc[c] = { true, s[c] };
-            }
-      }
-      return bc;
-    }
-
-    //! Set symmetry boundary conditions at nodes
-    void
-    symbc(
-      tk::Fields&,
-      const std::array< std::vector< real >, 3 >&,
-      const std::unordered_map< int,
-              std::unordered_map< std::size_t,
-                std::array< real, 4 > > >&,
-      const std::unordered_set< std::size_t >& ) const {}
-
-    //! Set farfield boundary conditions at nodes
-    void farfieldbc(
-      tk::Fields&,
-      const std::array< std::vector< real >, 3 >&,
-      const std::unordered_map< int,
-              std::unordered_map< std::size_t,
-                std::array< real, 4 > > >&,
-      const std::unordered_set< std::size_t >& ) const {}
-
-    //! Apply user defined time dependent BCs (no-op for transport)
-    void
-    timedepbc( tk::real,
-      tk::Fields&,
-      const std::vector< std::unordered_set< std::size_t > >&,
-      const std::vector< tk::Table<5> >& ) const {}
-
-    //! Return a map that associates user-specified strings to functions
-    //! \return Map that associates user-specified strings to functions that
-    //!  compute relevant quantities to be output to file
-    std::map< std::string, tk::GetVarFn > OutVarFn() const {
-      std::map< std::string, tk::GetVarFn > OutFnMap;
-      OutFnMap["material_indicator"] = transport::matIndicatorOutVar;
-
-      return OutFnMap;
-    }
-
-    //! Return analytic field names to be output to file
-    //! \return Vector of strings labelling analytic fields output in file
-    std::vector< std::string > analyticFieldNames() const {
-      std::vector< std::string > n;
-      auto depvar = g_inputdeck.get< tag::depvar >()[0];
-      for (ncomp_t c=0; c<m_ncomp; ++c)
-        n.push_back( depvar + std::to_string(c) + "_analytic" );
-      return n;
-    }
-
-    //! Return surface field names to be output to file
-    //! \return Vector of strings labelling surface fields output in file
-    //! \details This functions should be written in conjunction with
-    //!   surfOutput(), which provides the vector of surface fields to be output
-    std::vector< std::string > surfNames() const { return {}; }
-
-    //! Return nodal surface field output going to file
-    std::vector< std::vector< real > >
-    surfOutput( const std::map< int, std::vector< std::size_t > >&,
-                const tk::Fields& ) const { return {}; }
-
-    //! Return elemental surface field output (on triangle faces) going to file
-    std::vector< std::vector< real > >
-    elemSurfOutput( const std::map< int, std::vector< std::size_t > >&,
-      const std::vector< std::size_t >&,
-      const tk::Fields& ) const { return {}; }
-
-    //! Return time history field names to be output to file
-    //! \return Vector of strings labelling time history fields output in file
-    std::vector< std::string > histNames() const { return {}; }
-
-    //! Return time history field output evaluated at time history points
-    std::vector< std::vector< real > >
-    histOutput( const std::vector< HistData >&,
-                const std::vector< std::size_t >&,
-                const tk::Fields& ) const { return {}; }
+    //! Update the interface cells to first order dofs
+    //! \details This function resets the high-order terms in interface cells,
+    //!   and is currently not used in compflow.
+    void updateInterfaceCells( tk::Fields&,
+      std::size_t,
+      std::vector< std::size_t >& ) const {}
+
+    //! Update the primitives for this PDE system
+    //! \details This function computes and stores the dofs for primitive
+    //!   quantities, which is currently unused for compflow. But if a limiter
+    //!   requires primitive variables for example, this would be the place to
+    //!   add the computation of the primitive variables.
+    void updatePrimitives( const tk::Fields&,
+                           const tk::Fields&,
+                           const tk::Fields&,
+                           tk::Fields&,
+                           std::size_t ) const {}
+
+    //! Clean up the state of trace materials for this PDE system
+    //! \details This function cleans up the state of materials present in trace
+    //!   quantities in each cell. This is unused for compflow.
+    void cleanTraceMaterial( tk::real,
+                             const tk::Fields&,
+                             tk::Fields&,
+                             tk::Fields&,
+                             std::size_t ) const {}
+
+    //! Reconstruct second-order solution from first-order using least-squares
+    //! \param[in] t Physical time
+    //! \param[in] geoFace Face geometry array
+    //! \param[in] geoElem Element geometry array
+    //! \param[in] fd Face connectivity and boundary conditions object
+    //! \param[in] inpoel Element-node connectivity
+    //! \param[in] coord Array of nodal coordinates
+    //! \param[in,out] U Solution vector at recent time step
+    //! \param[in,out] P Primitive vector at recent time step
+    void reconstruct( tk::real t,
+                      const tk::Fields& geoFace,
+                      const tk::Fields& geoElem,
+                      const inciter::FaceData& fd,
+                      const std::map< std::size_t, std::vector< std::size_t > >&,
+                      const std::vector< std::size_t >& inpoel,
+                      const tk::UnsMesh::Coords& coord,
+                      tk::Fields& U,
+                      tk::Fields& P ) const
+    {
+      const auto rdof = g_inputdeck.get< tag::rdof >();
+
+      // do reconstruction only if P0P1
+      if (rdof == 4 && g_inputdeck.get< tag::ndof >() == 1) {
+        const auto nelem = fd.Esuel().size()/4;<--- Variable 'nelem' is assigned a value that is never used.
+
+        Assert( U.nprop() == rdof*5, "Number of components in solution "
+                "vector must equal "+ std::to_string(rdof*5) );
+        Assert( fd.Inpofa().size()/3 == fd.Esuf().size()/2,
+                "Mismatch in inpofa size" );
+
+        // allocate and initialize matrix and vector for reconstruction
+        std::vector< std::array< std::array< tk::real, 3 >, 3 > >
+          lhs_ls( nelem, {{ {{0.0, 0.0, 0.0}},
+                            {{0.0, 0.0, 0.0}},
+                            {{0.0, 0.0, 0.0}} }} );
+        std::vector< std::vector< std::array< tk::real, 3 > > >
+          rhs_ls( nelem, std::vector< std::array< tk::real, 3 > >
+            ( m_ncomp,
+              {{ 0.0, 0.0, 0.0 }} ) );
+
+        // reconstruct x,y,z-derivatives of unknowns
+        // 0. get lhs matrix, which is only geometry dependent
+        tk::lhsLeastSq_P0P1(fd, geoElem, geoFace, lhs_ls);
+
+        // 1. internal face contributions
+        std::vector< std::size_t > vars;
+        for (std::size_t c=0; c<m_ncomp; ++c) vars.push_back(c);
+        tk::intLeastSq_P0P1( rdof, fd, geoElem, U, rhs_ls, vars );
+
+        // 2. boundary face contributions
+        for (const auto& b : m_bc)
+          tk::bndLeastSqConservedVar_P0P1( m_ncomp,
+            m_mat_blk, rdof, b.first, fd, geoFace, geoElem, t, b.second,
+            P, U, rhs_ls, vars );
+
+        // 3. solve 3x3 least-squares system
+        tk::solveLeastSq_P0P1( rdof, lhs_ls, rhs_ls, U, vars );
+
+        // 4. transform reconstructed derivatives to Dubiner dofs
+        tk::transform_P0P1( rdof, nelem, inpoel, coord, U, vars );
+      }
+    }
+
+    //! Limit second-order solution
+    //! \param[in] t Physical time
+    //! \param[in] geoFace Face geometry array
+    //! \param[in] geoElem Element geometry array
+    //! \param[in] fd Face connectivity and boundary conditions object
+    //! \param[in] esup Elements surrounding points
+    //! \param[in] inpoel Element-node connectivity
+    //! \param[in] coord Array of nodal coordinates
+    //! \param[in] ndofel Vector of local number of degrees of freedome
+    //! \param[in] gid Local->global node id map
+    //! \param[in] bid Local chare-boundary node ids (value) associated to
+    //!   global node ids (key)
+    //! \param[in] uNodalExtrm Chare-boundary nodal extrema for conservative
+    //!   variables
+    //! \param[in] mtInv Inverse of Taylor mass matrix
+    //! \param[in,out] U Solution vector at recent time step
+    //! \param[in,out] shockmarker Vector of shock-marker values
+    void limit( [[maybe_unused]] tk::real t,
+                [[maybe_unused]] const tk::Fields& geoFace,
+                const tk::Fields& geoElem,
+                const inciter::FaceData& fd,
+                const std::map< std::size_t, std::vector< std::size_t > >& esup,
+                const std::vector< std::size_t >& inpoel,
+                const tk::UnsMesh::Coords& coord,
+                const std::vector< std::size_t >& ndofel,
+                const std::vector< std::size_t >& gid,
+                const std::unordered_map< std::size_t, std::size_t >& bid,
+                const std::vector< std::vector<tk::real> >& uNodalExtrm,
+                const std::vector< std::vector<tk::real> >&,
+                const std::vector< std::vector<tk::real> >& mtInv,
+                tk::Fields& U,
+                tk::Fields&,
+                std::vector< std::size_t >& shockmarker) const
+    {
+      const auto limiter = g_inputdeck.get< tag::limiter >();
+      const auto rdof = g_inputdeck.get< tag::rdof >();
+      const auto& solidx = g_inputdeck.get< tag::matidxmap, tag::solidx >();
+
+      if (limiter == ctr::LimiterType::WENOP1)
+        WENO_P1( fd.Esuel(), U );
+      else if (limiter == ctr::LimiterType::SUPERBEEP1)
+        Superbee_P1( fd.Esuel(), inpoel, ndofel, coord, U );
+      else if (limiter == ctr::LimiterType::VERTEXBASEDP1 && rdof == 4)
+        VertexBasedCompflow_P1( esup, inpoel, ndofel, fd.Esuel().size()/4,
+          m_mat_blk, fd, geoFace, geoElem, coord, flux, solidx, U,
+          shockmarker);
+      else if (limiter == ctr::LimiterType::VERTEXBASEDP1 && rdof == 10)
+        VertexBasedCompflow_P2( esup, inpoel, ndofel, fd.Esuel().size()/4,
+          m_mat_blk, fd, geoFace, geoElem, coord, gid, bid,
+          uNodalExtrm, mtInv, flux, solidx, U, shockmarker);
+    }
+
+    //! Update the conservative variable solution for this PDE system
+    //! \details This function computes the updated dofs for conservative
+    //!   quantities based on the limited solution and is currently not used in
+    //!   compflow.
+    void CPL( const tk::Fields&,
+              const tk::Fields&,
+              const std::vector< std::size_t >&,
+              const tk::UnsMesh::Coords&,
+              tk::Fields&,
+              std::size_t ) const {}
+
+    //! Return cell-average deformation gradient tensor (no-op for compflow)
+    //! \details This function is a no-op in compflow.
+    std::array< std::vector< tk::real >, 9 > cellAvgDeformGrad(
+      const tk::Fields&,
+      std::size_t ) const
+    {
+      return {};
+    }
+
+    //! Compute right hand side
+    //! \param[in] t Physical time
+    //! \param[in] geoFace Face geometry array
+    //! \param[in] geoElem Element geometry array
+    //! \param[in] fd Face connectivity and boundary conditions object
+    //! \param[in] inpoel Element-node connectivity
+    //! \param[in] boxelems Mesh node ids within user-defined IC boxes
+    //! \param[in] coord Array of nodal coordinates
+    //! \param[in] U Solution vector at recent time step
+    //! \param[in] P Primitive vector at recent time step
+    //! \param[in] ndofel Vector of local number of degrees of freedom
+    // //! \param[in] rho0mat Initial densities of all materials
+    //! \param[in] dt Delta time
+    //! \param[in,out] R Right-hand side vector computed
+    void rhs( tk::real t,
+              const tk::Fields& geoFace,
+              const tk::Fields& geoElem,
+              const inciter::FaceData& fd,
+              const std::vector< std::size_t >& inpoel,
+              const std::vector< std::unordered_set< std::size_t > >& boxelems,
+              const tk::UnsMesh::Coords& coord,
+              const tk::Fields& U,
+              const tk::Fields& P,
+              const std::vector< std::size_t >& ndofel,
+              const std::vector< tk::real >& /*rho0mat*/,
+              const tk::real dt,
+              tk::Fields& R ) const
+    {
+      const auto ndof = g_inputdeck.get< tag::ndof >();
+      const auto rdof = g_inputdeck.get< tag::rdof >();
+
+      const auto& solidx = g_inputdeck.get< tag::matidxmap, tag::solidx >();
+
+      Assert( U.nunk() == P.nunk(), "Number of unknowns in solution "
+              "vector and primitive vector at recent time step incorrect" );
+      Assert( U.nunk() == R.nunk(), "Number of unknowns in solution "
+              "vector and right-hand side at recent time step incorrect" );
+      Assert( U.nprop() == rdof*5, "Number of components in solution "
+              "vector must equal "+ std::to_string(rdof*5) );
+      Assert( P.nprop() == 0, "Number of components in primitive "
+              "vector must equal "+ std::to_string(0) );
+      Assert( R.nprop() == ndof*5, "Number of components in right-hand "
+              "side vector must equal "+ std::to_string(ndof*5) );
+      Assert( fd.Inpofa().size()/3 == fd.Esuf().size()/2,
+              "Mismatch in inpofa size" );
+
+      // set rhs to zero
+      R.fill(0.0);
+
+      // empty vector for non-conservative terms. This vector is unused for
+      // single-material hydrodynamics since, there are no non-conservative
+      // terms in the system of PDEs.
+      std::vector< std::vector < tk::real > > riemannDeriv;
+
+      std::vector< std::vector< tk::real > > vriem;
+      std::vector< std::vector< tk::real > > riemannLoc;
+
+      // configure a no-op lambda for prescribed velocity
+      auto velfn = []( ncomp_t, tk::real, tk::real, tk::real, tk::real ){
+        return tk::VelFn::result_type(); };
 
-    //! Return names of integral variables to be output to diagnostics file
-    //! \return Vector of strings labelling integral variables output
-    std::vector< std::string > names() const {
-      std::vector< std::string > n;
-      const auto& depvar =
-        g_inputdeck.get< tag::depvar >().at(0);
-      // construct the name of the numerical solution for all components
-      for (ncomp_t c=0; c<m_ncomp; ++c)
-        n.push_back( depvar + std::to_string(c) );
-      return n;
-    }
-
-  private:
-    const Physics m_physics;            //!< Physics policy
-    const Problem m_problem;            //!< Problem policy
-    const ncomp_t m_ncomp;              //!< Number of components in this PDE
-    //! EOS material block
-    const std::vector< EOS > m_mat_blk;
-
-    //! \brief Compute/assemble nodal gradients of primitive variables for
-    //!   ALECG in all points
-    //! \param[in] coord Mesh node coordinates
-    //! \param[in] inpoel Mesh element connectivity
-    //! \param[in] lid Global->local node ids
-    //! \param[in] bid Local chare-boundary node ids (value) associated to
-    //!    global node ids (key)
-    //! \param[in] vol Nodal volumes
-    //! \param[in] esup Elements surrounding points
-    //! \param[in] U Solution vector at recent time step
-    //! \param[in] G Nodal gradients of primitive variables in chare-boundary nodes
-    //! \return Gradients of primitive variables in all mesh points
-    tk::Fields
-    nodegrad( const std::array< std::vector< real >, 3 >& coord,
-              const std::vector< std::size_t >& inpoel,
-              const std::unordered_map< std::size_t, std::size_t >& lid,
-              const std::unordered_map< std::size_t, std::size_t >& bid,
-              const std::vector< real >& vol,
-              const std::pair< std::vector< std::size_t >,
-                               std::vector< std::size_t > >& esup,
-              const tk::Fields& U,
-              const tk::Fields& G ) const
-    {
-      // allocate storage for nodal gradients of primitive variables
-      tk::Fields Grad( U.nunk(), m_ncomp*3 );
-      Grad.fill( 0.0 );
-
-      // access node cooordinates
-      const auto& x = coord[0];
-      const auto& y = coord[1];
-      const auto& z = coord[2];
-
-      // compute gradients of primitive variables in points
-      auto npoin = U.nunk();
-      #pragma omp simd
-      for (std::size_t p=0; p<npoin; ++p)
-        for (auto e : tk::Around(esup,p)) {
-          // access node IDs
-          std::size_t N[4] =
-            { inpoel[e*4+0], inpoel[e*4+1], inpoel[e*4+2], inpoel[e*4+3] };
-          // compute element Jacobi determinant, J = 6V
-          real bax = x[N[1]]-x[N[0]];
-          real bay = y[N[1]]-y[N[0]];
-          real baz = z[N[1]]-z[N[0]];
-          real cax = x[N[2]]-x[N[0]];
-          real cay = y[N[2]]-y[N[0]];
-          real caz = z[N[2]]-z[N[0]];
-          real dax = x[N[3]]-x[N[0]];
-          real day = y[N[3]]-y[N[0]];
-          real daz = z[N[3]]-z[N[0]];
-          auto J = tk::triple( bax, bay, baz, cax, cay, caz, dax, day, daz );
-          auto J24 = J/24.0;
-          // shape function derivatives, nnode*ndim [4][3]
-          real g[4][3];
-          tk::crossdiv( cax, cay, caz, dax, day, daz, J,
-                        g[1][0], g[1][1], g[1][2] );
-          tk::crossdiv( dax, day, daz, bax, bay, baz, J,
-                        g[2][0], g[2][1], g[2][2] );
-          tk::crossdiv( bax, bay, baz, cax, cay, caz, J,
-                        g[3][0], g[3][1], g[3][2] );
-          for (std::size_t i=0; i<3; ++i)
-            g[0][i] = -g[1][i] - g[2][i] - g[3][i];
-          // scatter-add gradient contributions to boundary nodes
-          for (std::size_t c=0; c<m_ncomp; ++c)
-            for (std::size_t b=0; b<4; ++b)
-              for (std::size_t i=0; i<3; ++i)
-                Grad(p,c*3+i) += J24 * g[b][i] * U(N[b],c);
-        }
-
-      // put in nodal gradients of chare-boundary points
-      for (const auto& [g,b] : bid) {
-        auto i = tk::cref_find( lid, g );
-        for (ncomp_t c=0; c<Grad.nprop(); ++c)
-          Grad(i,c) = G(b,c);
-      }
-
-      // divide weak result in gradients by nodal volume
-      for (std::size_t p=0; p<npoin; ++p)
-        for (std::size_t c=0; c<m_ncomp*3; ++c)
-          Grad(p,c) /= vol[p];
+      // compute internal surface flux integrals
+      tk::surfInt( 1, m_mat_blk, t, ndof, rdof, inpoel, solidx,
+                   coord, fd, geoFace, geoElem, m_riemann, velfn, U, P, ndofel,
+                   dt, R, vriem, riemannLoc, riemannDeriv );
+
+      // compute optional source term
+      tk::srcInt( m_mat_blk, t, ndof, fd.Esuel().size()/4,
+                  inpoel, coord, geoElem, Problem::src, ndofel, R );
+
+      if(ndof > 1)
+        // compute volume integrals
+        tk::volInt( 1, t, m_mat_blk, ndof, rdof,
+                    fd.Esuel().size()/4, inpoel, coord, geoElem, flux, velfn,
+                    U, P, ndofel, R );
+
+      // compute boundary surface flux integrals
+      for (const auto& b : m_bc)
+        tk::bndSurfInt( 1, m_mat_blk, ndof, rdof, b.first,
+                        fd, geoFace, geoElem, inpoel, coord, t, m_riemann,
+                        velfn, b.second, U, P, ndofel, R, vriem, riemannLoc,
+                        riemannDeriv );
+
+     // compute external (energy) sources
+      const auto& ic = g_inputdeck.get< tag::ic >();
+      const auto& icbox = ic.get< tag::box >();
+
+      if (!icbox.empty() && !boxelems.empty()) {
+        std::size_t bcnt = 0;
+        for (const auto& b : icbox) {   // for all boxes for this eq
+          std::vector< tk::real > box
+           { b.template get< tag::xmin >(), b.template get< tag::xmax >(),
+             b.template get< tag::ymin >(), b.template get< tag::ymax >(),
+             b.template get< tag::zmin >(), b.template get< tag::zmax >() };
+
+          const auto& initiate = b.template get< tag::initiate >();
+          if (initiate == ctr::InitiateType::LINEAR) {
+            boxSrc( t, inpoel, boxelems[bcnt], coord, geoElem, ndofel, R );
+          }
+          ++bcnt;
+        }
+      }
+    }
+
+    //! Evaluate the adaptive indicator and mark the ndof for each element
+    //! \param[in] nunk Number of unknowns
+    //! \param[in] coord Array of nodal coordinates
+    //! \param[in] inpoel Element-node connectivity
+    //! \param[in] fd Face connectivity and boundary conditions object
+    //! \param[in] unk Array of unknowns
+    //! \param[in] prim Array of primitive quantities
+    //! \param[in] indicator p-refinement indicator type
+    //! \param[in] ndof Number of degrees of freedom in the solution
+    //! \param[in] ndofmax Max number of degrees of freedom for p-refinement
+    //! \param[in] tolref Tolerance for p-refinement
+    //! \param[in,out] ndofel Vector of local number of degrees of freedome
+    void eval_ndof( std::size_t nunk,
+                    const tk::UnsMesh::Coords& coord,
+                    const std::vector< std::size_t >& inpoel,
+                    const inciter::FaceData& fd,
+                    const tk::Fields& unk,
+                    const tk::Fields& prim,
+                    inciter::ctr::PrefIndicatorType indicator,
+                    std::size_t ndof,
+                    std::size_t ndofmax,
+                    tk::real tolref,
+                    std::vector< std::size_t >& ndofel ) const
+    {
+      const auto& esuel = fd.Esuel();
+
+      if(indicator == inciter::ctr::PrefIndicatorType::SPECTRAL_DECAY)
+        spectral_decay( 1, nunk, esuel, unk, prim, ndof, ndofmax, tolref,
+          ndofel );
+      else if(indicator == inciter::ctr::PrefIndicatorType::NON_CONFORMITY)
+        non_conformity( nunk, fd.Nbfac(), inpoel, coord, esuel, fd.Esuf(),
+          fd.Inpofa(), unk, ndof, ndofmax, ndofel );
+      else
+        Throw( "No such adaptive indicator type" );
+    }
+
+    //! Compute the minimum time step size
+    //! \param[in] coord Mesh node coordinates
+    //! \param[in] inpoel Mesh element connectivity
+    //! \param[in] fd Face connectivity and boundary conditions object
+    //! \param[in] geoFace Face geometry array
+    //! \param[in] geoElem Element geometry array
+    //! \param[in] ndofel Vector of local number of degrees of freedom
+    //! \param[in] U Solution vector at recent time step
+    //! \return Minimum time step size
+    tk::real dt( const std::array< std::vector< tk::real >, 3 >& coord,
+                 const std::vector< std::size_t >& inpoel,
+                 const inciter::FaceData& fd,
+                 const tk::Fields& geoFace,
+                 const tk::Fields& geoElem,
+                 const std::vector< std::size_t >& ndofel,
+                 const tk::Fields& U,
+                 const tk::Fields&,
+                 const std::size_t /*nielem*/ ) const
+    {
+      const auto rdof = g_inputdeck.get< tag::rdof >();
 
-      return Grad;
-    }
+      const auto& esuf = fd.Esuf();
+      const auto& inpofa = fd.Inpofa();
 
-    //! \brief Compute MUSCL reconstruction in edge-end points using a MUSCL
-    //!    procedure with van Leer limiting
-    //! \param[in] p Left node id of edge-end
-    //! \param[in] q Right node id of edge-end
-    //! \param[in] coord Array of nodal coordinates
-    //! \param[in] G Gradient of all unknowns in mesh points
-    //! \param[in,out] uL Primitive variables at left edge-end point
-    //! \param[in,out] uR Primitive variables at right edge-end point
-    void
-    muscl( std::size_t p,
-           std::size_t q,
-           const tk::UnsMesh::Coords& coord,
-           const tk::Fields& G,
-           std::vector< real >& uL,
-           std::vector< real >& uR ) const
-    {
-      Assert( uL.size() == m_ncomp && uR.size() == m_ncomp, "Size mismatch" );
-      Assert( G.nprop()/3 == m_ncomp, "Size mismatch" );
-
-      const auto& x = coord[0];
-      const auto& y = coord[1];
-      const auto& z = coord[2];
-
-      // edge vector
-      std::array< real, 3 > vw{ x[q]-x[p], y[q]-y[p], z[q]-z[p] };
-
-      std::vector< real >
-        delta1( m_ncomp, 0.0 ), delta2( m_ncomp, 0.0 ), delta3( m_ncomp, 0.0 );
-
-      // MUSCL reconstruction of edge-end-point primitive variables
-      for (std::size_t c=0; c<m_ncomp; ++c) {
-        // gradients
-        std::array< real, 3 >
-          g1{ G(p,c*3+0), G(p,c*3+1), G(p,c*3+2) },
-          g2{ G(q,c*3+0), G(q,c*3+1), G(q,c*3+2) };
-
-        delta2[c] = uR[c] - uL[c];
-        delta1[c] = 2.0 * tk::dot(g1,vw) - delta2[c];
-        delta3[c] = 2.0 * tk::dot(g2,vw) - delta2[c];
-
-        // form limiters
-        auto rL = (delta2[c] + muscl_eps) / (delta1[c] + muscl_eps);
-        auto rR = (delta2[c] + muscl_eps) / (delta3[c] + muscl_eps);
-        auto rLinv = (delta1[c] + muscl_eps) / (delta2[c] + muscl_eps);
-        auto rRinv = (delta3[c] + muscl_eps) / (delta2[c] + muscl_eps);
-
-        auto phiL = (std::abs(rL) + rL) / (std::abs(rL) + 1.0);
-        auto phiR = (std::abs(rR) + rR) / (std::abs(rR) + 1.0);
-        auto phi_L_inv = (std::abs(rLinv) + rLinv) / (std::abs(rLinv) + 1.0);
-        auto phi_R_inv = (std::abs(rRinv) + rRinv) / (std::abs(rRinv) + 1.0);
+      tk::real rho, u, v, w, rhoE, p, a, vn, dSV_l, dSV_r;
+      std::vector< tk::real > delt( U.nunk(), 0.0 );
+
+      const auto& cx = coord[0];
+      const auto& cy = coord[1];
+      const auto& cz = coord[2];
+
+      // compute internal surface maximum characteristic speed
+      for (std::size_t f=0; f<esuf.size()/2; ++f)
+      {
+
+        std::size_t el = static_cast< std::size_t >(esuf[2*f]);
+        auto er = esuf[2*f+1];
+
+        // Number of quadrature points for  face integration
+        std::size_t ng;
+
+        if(er > -1)
+        {
+          auto eR = static_cast< std::size_t >( er );
+
+          auto ng_l = tk::NGfa(ndofel[el]);
+          auto ng_r = tk::NGfa(ndofel[eR]);
+
+          // When the number of gauss points for the left and right element are
+          // different, choose the larger ng
+          ng = std::max( ng_l, ng_r );
+        }
+        else
+        {
+          ng = tk::NGfa(ndofel[el]);
+        }
+
+        // arrays for quadrature points
+        std::array< std::vector< tk::real >, 2 > coordgp;
+        std::vector< tk::real > wgp;
+
+        coordgp[0].resize( ng );
+        coordgp[1].resize( ng );
+        wgp.resize( ng );
+
+        // get quadrature point weights and coordinates for triangle
+        tk::GaussQuadratureTri( ng, coordgp, wgp );
+
+        // Extract the left element coordinates
+        std::array< std::array< tk::real, 3>, 4 > coordel_l {{
+          {{ cx[inpoel[4*el  ]], cy[inpoel[4*el  ]], cz[inpoel[4*el  ]] }},
+          {{ cx[inpoel[4*el+1]], cy[inpoel[4*el+1]], cz[inpoel[4*el+1]] }},
+          {{ cx[inpoel[4*el+2]], cy[inpoel[4*el+2]], cz[inpoel[4*el+2]] }},
+          {{ cx[inpoel[4*el+3]], cy[inpoel[4*el+3]], cz[inpoel[4*el+3]] }} }};
 
-        // update unknowns with reconstructed unknowns
-        uL[c] += 0.25*(delta1[c]*muscl_m1*phiL + delta2[c]*muscl_p1*phi_L_inv);
-        uR[c] -= 0.25*(delta3[c]*muscl_m1*phiR + delta2[c]*muscl_p1*phi_R_inv);
-      }
-    }
-
-    //! Compute domain-edge integral for ALECG
-    //! \param[in] coord Mesh node coordinates
-    //! \param[in] inpoel Mesh element connectivity
-    //! \param[in] edgeid Local node id pair -> edge id map
-    //! \param[in] psup Points surrounding points
-    //! \param[in] dfn Dual-face normals
-    //! \param[in] U Solution vector at recent time step
-    //! \param[in] G Nodal gradients
-    //! \param[in,out] R Right-hand side vector computed
-    void domainint( const std::array< std::vector< real >, 3 >& coord,
-                    const std::vector< std::size_t >& inpoel,
-                    const std::vector< std::size_t >& edgeid,
-                    const std::pair< std::vector< std::size_t >,
-                                     std::vector< std::size_t > >& psup,
-                    const std::vector< real >& dfn,
-                    const tk::Fields& U,
-                    const tk::Fields& G,
-                    tk::Fields& R ) const
-    {
-      // access node cooordinates
-      const auto& x = coord[0];
-      const auto& y = coord[1];
-      const auto& z = coord[2];
+        // Compute the determinant of Jacobian matrix
+        auto detT_l = 
+           tk::Jacobian(coordel_l[0], coordel_l[1], coordel_l[2], coordel_l[3]);
+
+        // Extract the face coordinates
+        std::array< std::array< tk::real, 3>, 3 > coordfa {{
+          {{ cx[ inpofa[3*f  ] ], cy[ inpofa[3*f  ] ], cz[ inpofa[3*f  ] ] }},
+          {{ cx[ inpofa[3*f+1] ], cy[ inpofa[3*f+1] ], cz[ inpofa[3*f+1] ] }},
+          {{ cx[ inpofa[3*f+2] ], cy[ inpofa[3*f+2] ], cz[ inpofa[3*f+2] ] }}
+        }};
+
+        dSV_l = 0.0;<--- Variable 'dSV_l' is assigned a value that is never used.
+        dSV_r = 0.0;
+
+        // Gaussian quadrature
+        for (std::size_t igp=0; igp<ng; ++igp)
+        {
+          // Compute the coordinates of quadrature point at physical domain
+          auto gp = tk::eval_gp( igp, coordfa, coordgp );
+
+          // Compute the basis function for the left element
+          auto B_l = tk::eval_basis( ndofel[el],
+            tk::Jacobian(coordel_l[0], gp, coordel_l[2], coordel_l[3])/detT_l,
+            tk::Jacobian(coordel_l[0], coordel_l[1], gp, coordel_l[3])/detT_l,
+            tk::Jacobian(coordel_l[0], coordel_l[1], coordel_l[2], gp)/detT_l );
+
+          auto wt = wgp[igp] * geoFace(f,0);
+
+          std::array< std::vector< tk::real >, 2 > ugp;
 
-      // compute derived data structures
-      auto esued = tk::genEsued( inpoel, 4, tk::genEsup( inpoel, 4 ) );
-
-      // access pointer to right hand side at component
-      std::vector< const real* > r( m_ncomp );
-      for (ncomp_t c=0; c<m_ncomp; ++c) r[c] = R.cptr( c );
-
-      // domain-edge integral
-      for (std::size_t p=0,k=0; p<U.nunk(); ++p) {
-        for (auto q : tk::Around(psup,p)) {
-          // access dual-face normals for edge p-q
-          auto ed = edgeid[k++];
-          std::array< tk::real, 3 > n{ dfn[ed*6+0], dfn[ed*6+1], dfn[ed*6+2] };
-
-          std::vector< tk::real > uL( m_ncomp, 0.0 );
-          std::vector< tk::real > uR( m_ncomp, 0.0 );
-          for (std::size_t c=0; c<m_ncomp; ++c) {
-            uL[c] = U(p,c);
-            uR[c] = U(q,c);
-          }
-          // compute MUSCL reconstruction in edge-end points
-          muscl( p, q, coord, G, uL, uR );
-
-          // evaluate prescribed velocity
-          auto v =
-            Problem::prescribedVelocity( m_ncomp, x[p], y[p], z[p], 0.0 );
-          // sum donain-edge contributions
-          for (auto e : tk::cref_find(esued,{p,q})) {
-            const std::array< std::size_t, 4 >
-              N{{ inpoel[e*4+0], inpoel[e*4+1], inpoel[e*4+2], inpoel[e*4+3] }};
-            // compute element Jacobi determinant
-            const std::array< tk::real, 3 >
-              ba{{ x[N[1]]-x[N[0]], y[N[1]]-y[N[0]], z[N[1]]-z[N[0]] }},
-              ca{{ x[N[2]]-x[N[0]], y[N[2]]-y[N[0]], z[N[2]]-z[N[0]] }},
-              da{{ x[N[3]]-x[N[0]], y[N[3]]-y[N[0]], z[N[3]]-z[N[0]] }};
-            const auto J = tk::triple( ba, ca, da );        // J = 6V
-            // shape function derivatives, nnode*ndim [4][3]
-            std::array< std::array< tk::real, 3 >, 4 > grad;
-            grad[1] = tk::crossdiv( ca, da, J );
-            grad[2] = tk::crossdiv( da, ba, J );
-            grad[3] = tk::crossdiv( ba, ca, J );
-            for (std::size_t i=0; i<3; ++i)
-              grad[0][i] = -grad[1][i]-grad[2][i]-grad[3][i];
-            auto J48 = J/48.0;
-            for (const auto& [a,b] : tk::lpoed) {
-              auto s = tk::orient( {N[a],N[b]}, {p,q} );
-              for (std::size_t j=0; j<3; ++j) {
-                for (std::size_t c=0; c<m_ncomp; ++c) {
-                  R.var(r[c],p) -= J48 * s * (grad[a][j] - grad[b][j])
-                                   * v[c][j]*(uL[c] + uR[c])
-                    - J48 * std::abs(s * (grad[a][j] - grad[b][j]))
-                          * std::abs(tk::dot(v[c],n)) * (uR[c] - uL[c]);
-                }
-              }
-            }
-          }
-        }
-      }
-    }
-
-    //! Compute boundary integrals for ALECG
-    //! \param[in] coord Mesh node coordinates
-    //! \param[in] triinpoel Boundary triangle face connecitivity with local ids
-    //! \param[in] symbctri Vector with 1 at symmetry BC boundary triangles
-    //! \param[in] U Solution vector at recent time step
-    //! \param[in,out] R Right-hand side vector computed
-    void bndint( const std::array< std::vector< real >, 3 >& coord,
-                 const std::vector< std::size_t >& triinpoel,
-                 const std::vector< int >& symbctri,
-                 const tk::Fields& U,
-                 tk::Fields& R ) const
-    {
-      // access node coordinates
-      const auto& x = coord[0];
-      const auto& y = coord[1];
-      const auto& z = coord[2];
-
-      // boundary integrals: compute fluxes in edges
-      std::vector< real > bflux( triinpoel.size() * m_ncomp * 2 );
-
-      for (std::size_t e=0; e<triinpoel.size()/3; ++e) {
-        // access node IDs
-        std::array< std::size_t, 3 >
-          N{ triinpoel[e*3+0], triinpoel[e*3+1], triinpoel[e*3+2] };
-        // apply symmetry BCs
-        if (symbctri[e]) continue;
-        // node coordinates
-        std::array< tk::real, 3 > xp{ x[N[0]], x[N[1]], x[N[2]] },
-                                  yp{ y[N[0]], y[N[1]], y[N[2]] },
-                                  zp{ z[N[0]], z[N[1]], z[N[2]] };
-        // access solution at element nodes
-        std::vector< std::array< real, 3 > > u( m_ncomp );
-        for (ncomp_t c=0; c<m_ncomp; ++c) u[c] = U.extract( c, N );
-        // evaluate prescribed velocity
-        auto v =
-          Problem::prescribedVelocity( m_ncomp, xp[0], yp[0], zp[0], 0.0 );
-        // compute face area
-        auto A6 = tk::area( x[N[0]], x[N[1]], x[N[2]],
-                            y[N[0]], y[N[1]], y[N[2]],
-                            z[N[0]], z[N[1]], z[N[2]] ) / 6.0;
-        auto A24 = A6/4.0;
-        // compute face normal
-        auto n = tk::normal( xp, yp, zp );
-        // store flux in boundary elements
-        for (std::size_t c=0; c<m_ncomp; ++c) {
-          auto eb = (e*m_ncomp+c)*6;
-          auto vdotn = tk::dot( v[c], n );
-          auto Bab = A24 * vdotn * (u[c][0] + u[c][1]);
-          bflux[eb+0] = Bab + A6 * vdotn * u[c][0];
-          bflux[eb+1] = Bab;
-          Bab = A24 * vdotn * (u[c][1] + u[c][2]);
-          bflux[eb+2] = Bab + A6 * vdotn * u[c][1];
-          bflux[eb+3] = Bab;
-          Bab = A24 * vdotn * (u[c][2] + u[c][0]);
-          bflux[eb+4] = Bab + A6 * vdotn * u[c][2];
-          bflux[eb+5] = Bab;
-        }
-      }
-
-      // access pointer to right hand side at component
-      std::vector< const real* > r( m_ncomp );
-      for (ncomp_t c=0; c<m_ncomp; ++c) r[c] = R.cptr( c );
-
-      // boundary integrals: sum flux contributions to points
-      for (std::size_t e=0; e<triinpoel.size()/3; ++e) {
-        std::size_t N[3] =
-          { triinpoel[e*3+0], triinpoel[e*3+1], triinpoel[e*3+2] };
-        for (std::size_t c=0; c<m_ncomp; ++c) {
-          auto eb = (e*m_ncomp+c)*6;
-          R.var(r[c],N[0]) -= bflux[eb+0] + bflux[eb+5];
-          R.var(r[c],N[1]) -= bflux[eb+1] + bflux[eb+2];
-          R.var(r[c],N[2]) -= bflux[eb+3] + bflux[eb+4];
-        }
-      }
-
-      tk::destroy(bflux);
-    }
-};
-
-} // cg::
-} // inciter::
-
-#endif // Transport_h
+          // left element
+          for (ncomp_t c=0; c<5; ++c)
+          {
+            auto mark = c*rdof;
+            ugp[0].push_back( U(el, mark) );
+
+            if(ndofel[el] > 1)          //DG(P1)
+              ugp[0][c] +=  U(el, mark+1) * B_l[1]
+                          + U(el, mark+2) * B_l[2]
+                          + U(el, mark+3) * B_l[3];
+
+            if(ndofel[el] > 4)          //DG(P2)
+              ugp[0][c] +=  U(el, mark+4) * B_l[4]
+                          + U(el, mark+5) * B_l[5]
+                          + U(el, mark+6) * B_l[6]
+                          + U(el, mark+7) * B_l[7]
+                          + U(el, mark+8) * B_l[8]
+                          + U(el, mark+9) * B_l[9];
+          }
+
+          rho = ugp[0][0];
+          u = ugp[0][1]/rho;
+          v = ugp[0][2]/rho;
+          w = ugp[0][3]/rho;
+          rhoE = ugp[0][4];
+          p = m_mat_blk[0].compute< EOS::pressure >( rho, u, v, w, rhoE );
+
+          a = m_mat_blk[0].compute< EOS::soundspeed >( rho, p );
+
+          vn = u*geoFace(f,1) + v*geoFace(f,2) + w*geoFace(f,3);
+
+          dSV_l = wt * (std::fabs(vn) + a);
+
+          // right element
+          if (er > -1) {
+
+            // nodal coordinates of the right element
+            std::size_t eR = static_cast< std::size_t >( er );
+
+            // Extract the left element coordinates
+            std::array< std::array< tk::real, 3>, 4 > coordel_r {{
+              {{ cx[inpoel[4*eR  ]], cy[inpoel[4*eR  ]], cz[inpoel[4*eR  ]] }},
+              {{ cx[inpoel[4*eR+1]], cy[inpoel[4*eR+1]], cz[inpoel[4*eR+1]] }},
+              {{ cx[inpoel[4*eR+2]], cy[inpoel[4*eR+2]], cz[inpoel[4*eR+2]] }},
+              {{ cx[inpoel[4*eR+3]], cy[inpoel[4*eR+3]], cz[inpoel[4*eR+3]] }}
+            }};
+
+            // Compute the determinant of Jacobian matrix
+            auto detT_r =
+              tk::Jacobian(coordel_r[0],coordel_r[1],coordel_r[2],coordel_r[3]);
+
+            // Compute the coordinates of quadrature point at physical domain
+            gp = tk::eval_gp( igp, coordfa, coordgp );
+
+            // Compute the basis function for the right element
+            auto B_r = tk::eval_basis( ndofel[eR],
+              tk::Jacobian(coordel_r[0],gp,coordel_r[2],coordel_r[3])/detT_r,
+              tk::Jacobian(coordel_r[0],coordel_r[1],gp,coordel_r[3])/detT_r,
+              tk::Jacobian(coordel_r[0],coordel_r[1],coordel_r[2],gp)/detT_r );
+ 
+            for (ncomp_t c=0; c<5; ++c)
+            {
+              auto mark = c*rdof;
+              ugp[1].push_back( U(eR, mark) );
+
+              if(ndofel[eR] > 1)          //DG(P1)
+                ugp[1][c] +=  U(eR, mark+1) * B_r[1]
+                            + U(eR, mark+2) * B_r[2]
+                            + U(eR, mark+3) * B_r[3];
+
+              if(ndofel[eR] > 4)         //DG(P2)
+                ugp[1][c] +=  U(eR, mark+4) * B_r[4]
+                            + U(eR, mark+5) * B_r[5]
+                            + U(eR, mark+6) * B_r[6]
+                            + U(eR, mark+7) * B_r[7]
+                            + U(eR, mark+8) * B_r[8]
+                            + U(eR, mark+9) * B_r[9];
+            }
+
+            rho = ugp[1][0];
+            u = ugp[1][1]/rho;
+            v = ugp[1][2]/rho;
+            w = ugp[1][3]/rho;
+            rhoE = ugp[1][4];
+            p = m_mat_blk[0].compute< EOS::pressure >( rho, u, v, w, rhoE );
+            a = m_mat_blk[0].compute< EOS::soundspeed >( rho, p );
+
+            vn = u*geoFace(f,1) + v*geoFace(f,2) + w*geoFace(f,3);
+
+            dSV_r = wt * (std::fabs(vn) + a);
+            delt[eR] += std::max( dSV_l, dSV_r );
+          }
+
+          delt[el] += std::max( dSV_l, dSV_r );
+        }
+      }
+
+      tk::real mindt = std::numeric_limits< tk::real >::max();
+      tk::real dgp = 0.0;<--- Variable 'dgp' is assigned a value that is never used.
+
+      // compute allowable dt
+      for (std::size_t e=0; e<fd.Esuel().size()/4; ++e)
+      {
+        dgp = 0.0;
+        if (ndofel[e] == 4)
+        {
+          dgp = 1.0;
+        }
+        else if (ndofel[e] == 10)
+        {
+          dgp = 2.0;
+        }
+
+        // Scale smallest dt with CFL coefficient and the CFL is scaled by (2*p+1)
+        // where p is the order of the DG polynomial by linear stability theory.
+        mindt = std::min( mindt, geoElem(e,0)/ (delt[e] * (2.0*dgp + 1.0)) );
+      }
+
+      return mindt;
+    }
+
+    //! Compute stiff terms for a single element, not implemented here
+    // //! \param[in] e Element number
+    // //! \param[in] geoElem Element geometry array
+    // //! \param[in] inpoel Element-node connectivity
+    // //! \param[in] coord Array of nodal coordinates
+    // //! \param[in] U Solution vector at recent time step
+    // //! \param[in] P Primitive vector at recent time step
+    // //! \param[in] ndofel Vector of local number of degrees of freedom
+    // //! \param[in,out] R Right-hand side vector computed
+    void stiff_rhs( std::size_t /*e*/,
+                    const tk::Fields& /*geoElem*/,
+                    const std::vector< std::size_t >& /*inpoel*/,
+                    const tk::UnsMesh::Coords& /*coord*/,
+                    const tk::Fields& /*U*/,
+                    const tk::Fields& /*P*/,
+                    const std::vector< std::size_t >& /*ndofel*/,
+                    tk::Fields& /*R*/ ) const
+    {}
+
+    //! Extract the velocity field at cell nodes. Currently unused.
+    //! \param[in] U Solution vector at recent time step
+    //! \param[in] N Element node indices
+    //! \return Array of the four values of the velocity field
+    std::array< std::array< tk::real, 4 >, 3 >
+    velocity( const tk::Fields& U,
+              const std::array< std::vector< tk::real >, 3 >&,
+              const std::array< std::size_t, 4 >& N ) const
+    {
+      std::array< std::array< tk::real, 4 >, 3 > v;
+      v[0] = U.extract( 1, N );
+      v[1] = U.extract( 2, N );
+      v[2] = U.extract( 3, N );
+      auto r = U.extract( 0, N );
+      std::transform( r.begin(), r.end(), v[0].begin(), v[0].begin(),
+                      []( tk::real s, tk::real& d ){ return d /= s; } );
+      std::transform( r.begin(), r.end(), v[1].begin(), v[1].begin(),
+                      []( tk::real s, tk::real& d ){ return d /= s; } );
+      std::transform( r.begin(), r.end(), v[2].begin(), v[2].begin(),
+                      []( tk::real s, tk::real& d ){ return d /= s; } );
+      return v;
+    }
+
+    //! Return a map that associates user-specified strings to functions
+    //! \return Map that associates user-specified strings to functions that
+    //!   compute relevant quantities to be output to file
+    std::map< std::string, tk::GetVarFn > OutVarFn() const
+    { return CompFlowOutVarFn(); }
+
+    //! Return analytic field names to be output to file
+    //! \return Vector of strings labelling analytic fields output in file
+    std::vector< std::string > analyticFieldNames() const
+    { return m_problem.analyticFieldNames( m_ncomp ); }
+
+    //! Return time history field names to be output to file
+    //! \return Vector of strings labeling time history fields output in file
+    std::vector< std::string > histNames() const
+    { return CompFlowHistNames(); }
+
+    //! Return surface field output going to file
+    std::vector< std::vector< tk::real > >
+    surfOutput( const std::map< int, std::vector< std::size_t > >&,
+                tk::Fields& ) const
+    {
+      std::vector< std::vector< tk::real > > s; // punt for now
+      return s;
+    }
+
+    //! Return time history field output evaluated at time history points
+    //! \param[in] h History point data
+    //! \param[in] inpoel Element-node connectivity
+    //! \param[in] coord Array of nodal coordinates
+    //! \param[in] U Array of unknowns
+    std::vector< std::vector< tk::real > >
+    histOutput( const std::vector< HistData >& h,
+                const std::vector< std::size_t >& inpoel,
+                const tk::UnsMesh::Coords& coord,
+                const tk::Fields& U,
+                const tk::Fields& ) const
+    {
+      const auto rdof = g_inputdeck.get< tag::rdof >();
+
+      const auto& x = coord[0];
+      const auto& y = coord[1];
+      const auto& z = coord[2];
+
+      std::vector< std::vector< tk::real > > Up(h.size());
+
+      std::size_t j = 0;
+      for (const auto& p : h) {
+        auto e = p.get< tag::elem >();
+        auto chp = p.get< tag::coord >();
+
+        // Evaluate inverse Jacobian
+        std::array< std::array< tk::real, 3>, 4 > cp{{
+          {{ x[inpoel[4*e  ]], y[inpoel[4*e  ]], z[inpoel[4*e  ]] }},
+          {{ x[inpoel[4*e+1]], y[inpoel[4*e+1]], z[inpoel[4*e+1]] }},
+          {{ x[inpoel[4*e+2]], y[inpoel[4*e+2]], z[inpoel[4*e+2]] }},
+          {{ x[inpoel[4*e+3]], y[inpoel[4*e+3]], z[inpoel[4*e+3]] }} }};
+        auto J = tk::inverseJacobian( cp[0], cp[1], cp[2], cp[3] );
+
+        // evaluate solution at history-point
+        std::array< tk::real, 3 > dc{{chp[0]-cp[0][0], chp[1]-cp[0][1],
+          chp[2]-cp[0][2]}};
+        auto B = tk::eval_basis(rdof, tk::dot(J[0],dc), tk::dot(J[1],dc),
+          tk::dot(J[2],dc));
+        auto uhp = eval_state(m_ncomp, rdof, rdof, e, U, B);
+
+        // store solution in history output vector
+        Up[j].resize(6, 0.0);
+        Up[j][0] = uhp[0];
+        Up[j][1] = uhp[1]/uhp[0];
+        Up[j][2] = uhp[2]/uhp[0];
+        Up[j][3] = uhp[3]/uhp[0];
+        Up[j][4] = uhp[4]/uhp[0];
+        Up[j][5] = m_mat_blk[0].compute< EOS::pressure >( uhp[0], uhp[1]/uhp[0],
+          uhp[2]/uhp[0], uhp[3]/uhp[0], uhp[4] );
+        ++j;
+      }
+
+      return Up;
+    }
+
+    //! Return names of integral variables to be output to diagnostics file
+    //! \return Vector of strings labelling integral variables output
+    std::vector< std::string > names() const
+    { return m_problem.names( m_ncomp ); }
+
+    //! Return analytic solution (if defined by Problem) at xi, yi, zi, t
+    //! \param[in] xi X-coordinate at which to evaluate the analytic solution
+    //! \param[in] yi Y-coordinate at which to evaluate the analytic solution
+    //! \param[in] zi Z-coordinate at which to evaluate the analytic solution
+    //! \param[in] t Physical time at which to evaluate the analytic solution
+    //! \return Vector of analytic solution at given location and time
+    std::vector< tk::real >
+    analyticSolution( tk::real xi, tk::real yi, tk::real zi, tk::real t ) const
+    { return Problem::analyticSolution( m_ncomp, m_mat_blk, xi, yi,
+                                        zi, t ); }
+
+    //! Return analytic solution for conserved variables
+    //! \param[in] xi X-coordinate at which to evaluate the analytic solution
+    //! \param[in] yi Y-coordinate at which to evaluate the analytic solution
+    //! \param[in] zi Z-coordinate at which to evaluate the analytic solution
+    //! \param[in] t Physical time at which to evaluate the analytic solution
+    //! \return Vector of analytic solution at given location and time
+    std::vector< tk::real >
+    solution( tk::real xi, tk::real yi, tk::real zi, tk::real t ) const
+    { return Problem::initialize( m_ncomp, m_mat_blk, xi, yi, zi, t ); }
+
+    //! Return cell-averaged specific total energy for an element
+    //! \param[in] e Element id for which total energy is required
+    //! \param[in] unk Vector of conserved quantities
+    //! \return Cell-averaged specific total energy for given element
+    tk::real sp_totalenergy(std::size_t e, const tk::Fields& unk) const
+    {
+      const auto rdof = g_inputdeck.get< tag::rdof >();
+
+      return unk(e,4*rdof);
+    }
+
+  private:
+    //! Physics policy
+    const Physics m_physics;
+    //! Problem policy
+    const Problem m_problem;
+    //! Number of components in this PDE system
+    const ncomp_t m_ncomp;
+    //! Riemann solver
+    tk::RiemannFluxFn m_riemann;
+    //! BC configuration
+    BCStateFn m_bc;
+    //! EOS material block
+    std::vector< EOS > m_mat_blk;
+
+    //! Evaluate physical flux function for this PDE system
+    //! \param[in] ncomp Number of scalar components in this PDE system
+    //! \param[in] mat_blk EOS material block
+    //! \param[in] ugp Numerical solution at the Gauss point at which to
+    //!   evaluate the flux
+    //! \return Flux vectors for all components in this PDE system
+    //! \note The function signature must follow tk::FluxFn
+    static tk::FluxFn::result_type
+    flux( [[maybe_unused]] ncomp_t ncomp,
+          const std::vector< EOS >& mat_blk,
+          const std::vector< tk::real >& ugp,
+          const std::vector< std::array< tk::real, 3 > >& )
+    {
+      Assert( ugp.size() == ncomp, "Size mismatch" );
+
+      auto u = ugp[1] / ugp[0];
+      auto v = ugp[2] / ugp[0];
+      auto w = ugp[3] / ugp[0];
+      auto p = mat_blk[0].compute< EOS::pressure >( ugp[0], u, v, w, ugp[4] );
+
+      std::vector< std::array< tk::real, 3 > > fl( ugp.size() );
+
+      fl[0][0] = ugp[1];
+      fl[1][0] = ugp[1] * u + p;
+      fl[2][0] = ugp[1] * v;
+      fl[3][0] = ugp[1] * w;
+      fl[4][0] = u * (ugp[4] + p);
+
+      fl[0][1] = ugp[2];
+      fl[1][1] = ugp[2] * u;
+      fl[2][1] = ugp[2] * v + p;
+      fl[3][1] = ugp[2] * w;
+      fl[4][1] = v * (ugp[4] + p);
+
+      fl[0][2] = ugp[3];
+      fl[1][2] = ugp[3] * u;
+      fl[2][2] = ugp[3] * v;
+      fl[3][2] = ugp[3] * w + p;
+      fl[4][2] = w * (ugp[4] + p);
+
+      return fl;
+    }
+
+    //! \brief Boundary state function providing the left and right state of a
+    //!   face at Dirichlet boundaries
+    //! \param[in] ncomp Number of scalar components in this PDE system
+    //! \param[in] mat_blk EOS material block
+    //! \param[in] ul Left (domain-internal) state
+    //! \param[in] x X-coordinate at which to compute the states
+    //! \param[in] y Y-coordinate at which to compute the states
+    //! \param[in] z Z-coordinate at which to compute the states
+    //! \param[in] t Physical time
+    //! \return Left and right states for all scalar components in this PDE
+    //!   system
+    //! \note The function signature must follow tk::StateFn
+    static tk::StateFn::result_type
+    dirichlet( ncomp_t ncomp,
+               const std::vector< EOS >& mat_blk,
+               const std::vector< tk::real >& ul, tk::real x, tk::real y,
+               tk::real z, tk::real t, const std::array< tk::real, 3 >& )
+    {
+      return {{ ul, Problem::initialize( ncomp, mat_blk, x, y, z, t ) }};
+    }
+
+    //! \brief Boundary state function providing the left and right state of a
+    //!   face at symmetry boundaries
+    //! \param[in] ul Left (domain-internal) state
+    //! \param[in] fn Unit face normal
+    //! \return Left and right states for all scalar components in this PDE
+    //!   system
+    //! \note The function signature must follow tk::StateFn
+    static tk::StateFn::result_type
+    symmetry( ncomp_t, const std::vector< EOS >&,
+              const std::vector< tk::real >& ul, tk::real, tk::real, tk::real,
+              tk::real, const std::array< tk::real, 3 >& fn )
+    {
+      std::vector< tk::real > ur(5);
+      // Internal cell velocity components
+      auto v1l = ul[1]/ul[0];
+      auto v2l = ul[2]/ul[0];
+      auto v3l = ul[3]/ul[0];
+      // Normal component of velocity
+      auto vnl = v1l*fn[0] + v2l*fn[1] + v3l*fn[2];
+      // Ghost state velocity components
+      auto v1r = v1l - 2.0*vnl*fn[0];
+      auto v2r = v2l - 2.0*vnl*fn[1];
+      auto v3r = v3l - 2.0*vnl*fn[2];
+      // Boundary condition
+      ur[0] = ul[0];
+      ur[1] = ur[0] * v1r;
+      ur[2] = ur[0] * v2r;
+      ur[3] = ur[0] * v3r;
+      ur[4] = ul[4];
+      return {{ std::move(ul), std::move(ur) }};
+    }
+
+    //! \brief Boundary state function providing the left and right state of a
+    //!   face at farfield boundaries
+    //! \param[in] mat_blk EOS material block
+    //! \param[in] ul Left (domain-internal) state
+    //! \param[in] fn Unit face normal
+    //! \return Left and right states for all scalar components in this PDE
+    //!   system
+    //! \note The function signature must follow tk::StateFn
+    static tk::StateFn::result_type
+    farfield( ncomp_t, const std::vector< EOS >& mat_blk,
+              const std::vector< tk::real >& ul, tk::real, tk::real, tk::real,
+              tk::real, const std::array< tk::real, 3 >& fn )
+    {
+      // Primitive variables from farfield
+      const auto& bc = g_inputdeck.get< tag::bc >()[0];
+      auto frho = bc.get< tag::density >();
+      auto fp   = bc.get< tag::pressure >();
+      const auto& fu = bc.get< tag::velocity >();
+
+      // Speed of sound from farfield
+      auto fa = mat_blk[0].compute< EOS::soundspeed >( frho, fp );
+
+      // Normal component from farfield
+      auto fvn = fu[0]*fn[0] + fu[1]*fn[1] + fu[2]*fn[2];
+
+      // Mach number from farfield
+      auto fM = fvn / fa;
+
+      // Specific total energy from farfield
+      auto frhoE = mat_blk[0].compute< EOS::totalenergy >( frho, fu[0], fu[1],
+        fu[2], fp );
+
+      // Pressure from internal cell
+      auto p = mat_blk[0].compute< EOS::pressure >( ul[0], ul[1]/ul[0],
+        ul[2]/ul[0], ul[3]/ul[0], ul[4] );
+
+      auto ur = ul;
+
+      if(fM <= -1)                         // Supersonic inflow<--- Assuming that condition 'fM<=-1' is not redundant<--- Assuming that condition 'fM<=-1' is not redundant<--- Assuming that condition 'fM<=-1' is not redundant
+      {
+        // For supersonic inflow, all the characteristics are from outside.
+        // Therefore, we calculate the ghost cell state using the primitive
+        // variables from outside.
+        ur[0] = frho;
+        ur[1] = frho * fu[0];
+        ur[2] = frho * fu[1];
+        ur[3] = frho * fu[2];
+        ur[4] = frhoE;
+      } else if(fM > -1 && fM < 0)       // Subsonic inflow<--- Condition 'fM>-1' is always true<--- Condition 'fM<0' is always false
+      {
+        // For subsonic inflow, there are 1 outgoing characteristcs and 4
+        // incoming characteristic. Therefore, we calculate the ghost cell state
+        // by taking pressure from the internal cell and other quantities from
+        // the outside.
+        ur[0] = frho;
+        ur[1] = frho * fu[0];
+        ur[2] = frho * fu[1];
+        ur[3] = frho * fu[2];
+        ur[4] = mat_blk[0].compute< EOS::totalenergy >( frho, fu[0], fu[1],
+          fu[2], p );
+      } else if(fM >= 0 && fM < 1)       // Subsonic outflow<--- Condition 'fM>=0' is always true
+      {
+        // For subsonic outflow, there are 1 incoming characteristcs and 4
+        // outgoing characteristic. Therefore, we calculate the ghost cell state
+        // by taking pressure from the outside and other quantities from the
+        // internal cell.
+        ur[4] = mat_blk[0].compute< EOS::totalenergy >( ul[0], ul[1]/ul[0],
+          ul[2]/ul[0], ul[3]/ul[0], fp );
+      }
+      // Otherwise, for supersonic outflow, all the characteristics are from
+      // internal cell. Therefore, we calculate the ghost cell state using the
+      // conservative variables from outside.
+
+      return {{ ul, ur }};
+    }
+
+    //! \brief Boundary state function providing the left and right state of a
+    //!   face at extrapolation boundaries
+    //! \param[in] ul Left (domain-internal) state
+    //! \return Left and right states for all scalar components in this PDE
+    //!   system
+    //! \note The function signature must follow tk::StateFn
+    static tk::StateFn::result_type
+    extrapolate( ncomp_t, const std::vector< EOS >&,
+                 const std::vector< tk::real >& ul, tk::real, tk::real,
+                 tk::real, tk::real, const std::array< tk::real, 3 >& )
+    {
+      return {{ ul, ul }};
+    }
+
+    //! Compute sources corresponding to a propagating front in user-defined box
+    //! \param[in] t Physical time
+    //! \param[in] inpoel Element point connectivity
+    //! \param[in] boxelems Mesh node ids within user-defined box
+    //! \param[in] coord Mesh node coordinates
+    //! \param[in] geoElem Element geometry array
+    //! \param[in] ndofel Vector of local number of degrees of freedome
+    //! \param[in] R Right-hand side vector
+    //! \details This function add the energy source corresponding to a planar
+    //!   wave-front propagating along the z-direction with a user-specified
+    //!   velocity, within a box initial condition, configured by the user.
+    //!   Example (SI) units of the quantities involved:
+    //!    * internal energy content (energy per unit volume): J/m^3
+    //!    * specific energy (internal energy per unit mass): J/kg
+    void boxSrc( tk::real t,
+                 const std::vector< std::size_t >& inpoel,
+                 const std::unordered_set< std::size_t >& boxelems,
+                 const tk::UnsMesh::Coords& coord,
+                 const tk::Fields& geoElem,
+                 const std::vector< std::size_t >& ndofel,
+                 tk::Fields& R ) const
+    {
+      const auto ndof = g_inputdeck.get< tag::ndof >();<--- Variable 'ndof' is assigned a value that is never used.
+      const auto& ic = g_inputdeck.get< tag::ic >();
+      const auto& icbox = ic.get< tag::box >();
+
+      for (const auto& b : icbox) {   // for all boxes for this eq
+        std::vector< tk::real > box
+         { b.template get< tag::xmin >(), b.template get< tag::xmax >(),
+           b.template get< tag::ymin >(), b.template get< tag::ymax >(),
+           b.template get< tag::zmin >(), b.template get< tag::zmax >() };
+
+        auto boxenc = b.template get< tag::energy_content >();
+        Assert( boxenc > 0.0, "Box energy content must be nonzero" );
+
+        auto V_ex = (box[1]-box[0]) * (box[3]-box[2]) * (box[5]-box[4]);
+
+        // determine times at which sourcing is initialized and terminated
+        auto iv = b.template get< tag::front_speed >();
+        auto wFront = 0.1;
+        auto tInit = 0.0;
+        auto tFinal = tInit + (box[5] - box[4] - 2.0*wFront) / std::fabs(iv);
+        auto aBox = (box[1]-box[0]) * (box[3]-box[2]);
+
+        const auto& cx = coord[0];
+        const auto& cy = coord[1];
+        const auto& cz = coord[2];
+
+        if (t >= tInit && t <= tFinal) {
+          // The energy front is assumed to have a half-sine-wave shape. The
+          // half wave-length is the width of the front. At t=0, the center of
+          // this front (i.e. the peak of the partial-sine-wave) is at X_0 +
+          // W_0.  W_0 is calculated based on the width of the front and the
+          // direction of propagation (which is assumed to be along the
+          // z-direction).  If the front propagation velocity is positive, it
+          // is assumed that the initial position of the energy source is the
+          // minimum z-coordinate of the box; whereas if this velocity is
+          // negative, the initial position is the maximum z-coordinate of the
+          // box.
+
+          // Orientation of box
+          std::array< tk::real, 3 > b_orientn{{
+            b.template get< tag::orientation >()[0],
+            b.template get< tag::orientation >()[1],
+            b.template get< tag::orientation >()[2] }};
+          std::array< tk::real, 3 > b_centroid{{ 0.5*(box[0]+box[1]),
+            0.5*(box[2]+box[3]), 0.5*(box[4]+box[5]) }};
+          // Transform box to reference space
+          std::array< tk::real, 3 > b_min{{box[0], box[2], box[4]}};
+          std::array< tk::real, 3 > b_max{{box[1], box[3], box[5]}};
+          tk::movePoint(b_centroid, b_min);
+          tk::movePoint(b_centroid, b_max);
+
+          // initial center of front
+          tk::real zInit(b_min[2]);
+          if (iv < 0.0) zInit = b_max[2];
+          // current location of front
+          auto z0 = zInit + iv*t;
+          auto z1 = z0 + std::copysign(wFront, iv);
+          tk::real s0(z0), s1(z1);
+          // if velocity of propagation is negative, initial position is z1
+          if (iv < 0.0) {
+            s0 = z1;
+            s1 = z0;
+          }
+          // Sine-wave (positive part of the wave) source term amplitude
+          auto pi = 4.0 * std::atan(1.0);
+          auto amplE = boxenc * V_ex * pi
+            / (aBox * wFront * 2.0 * (tFinal-tInit));
+          //// Square wave (constant) source term amplitude
+          //auto amplE = boxenc * V_ex
+          //  / (aBox * wFront * (tFinal-tInit));
+
+          // add source
+          for (auto e : boxelems) {
+            std::array< tk::real, 3 > node{{ geoElem(e,1), geoElem(e,2),
+              geoElem(e,3) }};
+            // Transform node to reference space of box
+            tk::movePoint(b_centroid, node);
+            tk::rotatePoint({{-b_orientn[0], -b_orientn[1], -b_orientn[2]}},
+              node);
+
+            if (node[2] >= s0 && node[2] <= s1) {
+              auto ng = tk::NGvol(ndofel[e]);
+
+              // arrays for quadrature points
+              std::array< std::vector< tk::real >, 3 > coordgp;
+              std::vector< tk::real > wgp;
+
+              coordgp[0].resize( ng );
+              coordgp[1].resize( ng );
+              coordgp[2].resize( ng );
+              wgp.resize( ng );
+
+              tk::GaussQuadratureTet( ng, coordgp, wgp );
+
+              // Extract the element coordinates
+              std::array< std::array< tk::real, 3>, 4 > coordel{{
+              {{ cx[inpoel[4*e  ]], cy[inpoel[4*e  ]], cz[inpoel[4*e  ]] }},
+              {{ cx[inpoel[4*e+1]], cy[inpoel[4*e+1]], cz[inpoel[4*e+1]] }},
+              {{ cx[inpoel[4*e+2]], cy[inpoel[4*e+2]], cz[inpoel[4*e+2]] }},
+              {{ cx[inpoel[4*e+3]], cy[inpoel[4*e+3]], cz[inpoel[4*e+3]] }}}};
+
+              for (std::size_t igp=0; igp<ng; ++igp) {
+                // Compute the coordinates of quadrature point at physical
+                // domain
+                auto gp = tk::eval_gp( igp, coordel, coordgp );
+
+                // Transform quadrature point to reference space of box
+                tk::movePoint(b_centroid, gp);
+                tk::rotatePoint({{-b_orientn[0], -b_orientn[1], -b_orientn[2]}},
+                  gp);
+
+                // Compute the basis function
+                auto B = tk::eval_basis( ndofel[e], coordgp[0][igp],
+                                         coordgp[1][igp], coordgp[2][igp] );
+
+                // Compute the source term variable
+                std::vector< tk::real > s(5, 0.0);
+                s[4] = amplE * std::sin(pi*(gp[2]-s0)/wFront);
+
+                auto wt = wgp[igp] * geoElem(e, 0);
+
+                tk::update_rhs( ndof, ndofel[e], wt, e, B, s, R );
+              }
+            }
+          }
+        }
+      }
+    }
+};
+
+} // dg::
+
+} // inciter::
+
+#endif // DGCompFlow_h
 
diff --git a/Release/cppcheck/45.html b/Release/cppcheck/45.html index 56099a0059ca..df43e2a86c18 100644 --- a/Release/cppcheck/45.html +++ b/Release/cppcheck/45.html @@ -152,1437 +152,4403 @@
- - + @@ -73,11 +73,11 @@ - + - +
  1
-  2
-  3
-  4
-  5
-  6
-  7
-  8
-  9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
- 37
- 38
- 39
- 40
- 41
- 42
- 43
- 44
- 45
- 46
- 47
- 48
- 49
- 50
- 51
- 52
- 53
- 54
- 55
- 56
- 57
- 58
- 59
- 60
- 61
- 62
- 63
- 64
- 65
- 66
- 67
- 68
- 69
- 70
- 71
- 72
- 73
- 74
- 75
- 76
- 77
- 78
- 79
- 80
- 81
- 82
- 83
- 84
- 85
- 86
- 87
- 88
- 89
- 90
- 91
- 92
- 93
- 94
- 95
- 96
- 97
- 98
- 99
-100
-101
-102
-103
-104
-105
-106
-107
-108
-109
-110
-111
-112
-113
-114
-115
-116
-117
-118
-119
-120
-121
-122
-123
-124
-125
-126
-127
-128
-129
-130
-131
-132
-133
-134
-135
-136
-137
-138
-139
-140
-141
-142
-143
-144
-145
-146
-147
-148
-149
-150
-151
-152
-153
-154
-155
-156
-157
-158
-159
-160
-161
-162
-163
-164
-165
-166
-167
-168
-169
-170
-171
-172
-173
-174
-175
-176
-177
-178
-179
-180
-181
-182
-183
-184
-185
-186
-187
-188
-189
-190
-191
-192
-193
-194
-195
-196
-197
-198
-199
-200
-201
-202
-203
-204
-205
-206
-207
-208
-209
-210
-211
-212
-213
-214
-215
-216
-217
-218
-219
-220
-221
-222
-223
-224
-225
-226
-227
-228
-229
-230
-231
-232
-233
-234
-235
-236
-237
-238
-239
-240
-241
-242
-243
-244
-245
-246
-247
-248
-249
-250
-251
-252
-253
-254
-255
-256
-257
-258
-259
-260
-261
-262
-263
-264
-265
-266
-267
-268
-269
-270
-271
-272
-273
-274
-275
-276
-277
-278
-279
-280
-281
-282
-283
-284
-285
-286
-287
-288
-289
-290
-291
-292
-293
-294
-295
-296
-297
-298
-299
-300
-301
-302
-303
-304
-305
-306
-307
-308
-309
-310
-311
-312
-313
-314
-315
-316
-317
-318
-319
-320
-321
-322
-323
-324
-325
-326
-327
-328
-329
-330
-331
-332
-333
-334
-335
-336
-337
-338
-339
-340
-341
-342
-343
-344
-345
-346
-347
-348
-349
-350
-351
-352
-353
-354
-355
-356
-357
-358
-359
-360
-361
-362
-363
-364
-365
-366
-367
-368
-369
-370
-371
-372
-373
-374
-375
-376
-377
-378
-379
-380
-381
-382
-383
-384
-385
-386
-387
-388
-389
-390
-391
-392
-393
-394
-395
-396
-397
-398
-399
-400
-401
-402
-403
-404
-405
-406
-407
-408
-409
-410
-411
-412
-413
-414
-415
-416
-417
-418
-419
-420
-421
-422
-423
-424
-425
-426
-427
-428
-429
-430
-431
-432
-433
-434
-435
-436
-437
-438
-439
-440
-441
-442
-443
-444
-445
-446
-447
-448
-449
-450
-451
-452
-453
-454
-455
-456
-457
-458
-459
-460
-461
-462
-463
-464
-465
-466
-467
-468
-469
-470
-471
-472
-473
-474
-475
-476
-477
-478
-479
-480
-481
-482
-483
-484
-485
-486
-487
-488
-489
-490
-491
-492
-493
-494
-495
-496
-497
-498
-499
-500
-501
-502
-503
-504
-505
-506
-507
-508
-509
-510
-511
-512
-513
-514
-515
-516
-517
-518
-519
-520
-521
-522
-523
-524
-525
-526
-527
-528
-529
-530
-531
-532
-533
-534
-535
-536
-537
-538
-539
-540
-541
-542
-543
-544
-545
-546
-547
-548
-549
-550
-551
-552
-553
-554
-555
-556
-557
-558
-559
-560
-561
-562
-563
-564
-565
-566
-567
-568
-569
-570
-571
-572
-573
-574
-575
-576
-577
-578
-579
-580
-581
-582
-583
-584
-585
-586
-587
-588
-589
-590
-591
-592
-593
-594
-595
-596
-597
-598
-599
-600
-601
-602
-603
-604
-605
-606
-607
-608
-609
-610
-611
-612
-613
-614
-615
-616
-617
-618
-619
-620
-621
-622
-623
-624
-625
-626
-627
-628
-629
-630
-631
-632
-633
-634
-635
-636
-637
-638
-639
-640
-641
-642
-643
-644
-645
-646
-647
-648
-649
-650
-651
-652
-653
-654
-655
-656
-657
-658
-659
-660
-661
-662
-663
-664
-665
-666
-667
-668
-669
-670
-671
-672
-673
-674
-675
-676
-677
-678
-679
-680
-681
-682
-683
-684
-685
-686
-687
-688
-689
-690
-691
-692
-693
-694
-695
-696
-697
-698
-699
-700
-701
-702
-703
-704
-705
-706
-707
-708
-709
-710
-711
-712
// *****************************************************************************
+
   1
+   2
+   3
+   4
+   5
+   6
+   7
+   8
+   9
+  10
+  11
+  12
+  13
+  14
+  15
+  16
+  17
+  18
+  19
+  20
+  21
+  22
+  23
+  24
+  25
+  26
+  27
+  28
+  29
+  30
+  31
+  32
+  33
+  34
+  35
+  36
+  37
+  38
+  39
+  40
+  41
+  42
+  43
+  44
+  45
+  46
+  47
+  48
+  49
+  50
+  51
+  52
+  53
+  54
+  55
+  56
+  57
+  58
+  59
+  60
+  61
+  62
+  63
+  64
+  65
+  66
+  67
+  68
+  69
+  70
+  71
+  72
+  73
+  74
+  75
+  76
+  77
+  78
+  79
+  80
+  81
+  82
+  83
+  84
+  85
+  86
+  87
+  88
+  89
+  90
+  91
+  92
+  93
+  94
+  95
+  96
+  97
+  98
+  99
+ 100
+ 101
+ 102
+ 103
+ 104
+ 105
+ 106
+ 107
+ 108
+ 109
+ 110
+ 111
+ 112
+ 113
+ 114
+ 115
+ 116
+ 117
+ 118
+ 119
+ 120
+ 121
+ 122
+ 123
+ 124
+ 125
+ 126
+ 127
+ 128
+ 129
+ 130
+ 131
+ 132
+ 133
+ 134
+ 135
+ 136
+ 137
+ 138
+ 139
+ 140
+ 141
+ 142
+ 143
+ 144
+ 145
+ 146
+ 147
+ 148
+ 149
+ 150
+ 151
+ 152
+ 153
+ 154
+ 155
+ 156
+ 157
+ 158
+ 159
+ 160
+ 161
+ 162
+ 163
+ 164
+ 165
+ 166
+ 167
+ 168
+ 169
+ 170
+ 171
+ 172
+ 173
+ 174
+ 175
+ 176
+ 177
+ 178
+ 179
+ 180
+ 181
+ 182
+ 183
+ 184
+ 185
+ 186
+ 187
+ 188
+ 189
+ 190
+ 191
+ 192
+ 193
+ 194
+ 195
+ 196
+ 197
+ 198
+ 199
+ 200
+ 201
+ 202
+ 203
+ 204
+ 205
+ 206
+ 207
+ 208
+ 209
+ 210
+ 211
+ 212
+ 213
+ 214
+ 215
+ 216
+ 217
+ 218
+ 219
+ 220
+ 221
+ 222
+ 223
+ 224
+ 225
+ 226
+ 227
+ 228
+ 229
+ 230
+ 231
+ 232
+ 233
+ 234
+ 235
+ 236
+ 237
+ 238
+ 239
+ 240
+ 241
+ 242
+ 243
+ 244
+ 245
+ 246
+ 247
+ 248
+ 249
+ 250
+ 251
+ 252
+ 253
+ 254
+ 255
+ 256
+ 257
+ 258
+ 259
+ 260
+ 261
+ 262
+ 263
+ 264
+ 265
+ 266
+ 267
+ 268
+ 269
+ 270
+ 271
+ 272
+ 273
+ 274
+ 275
+ 276
+ 277
+ 278
+ 279
+ 280
+ 281
+ 282
+ 283
+ 284
+ 285
+ 286
+ 287
+ 288
+ 289
+ 290
+ 291
+ 292
+ 293
+ 294
+ 295
+ 296
+ 297
+ 298
+ 299
+ 300
+ 301
+ 302
+ 303
+ 304
+ 305
+ 306
+ 307
+ 308
+ 309
+ 310
+ 311
+ 312
+ 313
+ 314
+ 315
+ 316
+ 317
+ 318
+ 319
+ 320
+ 321
+ 322
+ 323
+ 324
+ 325
+ 326
+ 327
+ 328
+ 329
+ 330
+ 331
+ 332
+ 333
+ 334
+ 335
+ 336
+ 337
+ 338
+ 339
+ 340
+ 341
+ 342
+ 343
+ 344
+ 345
+ 346
+ 347
+ 348
+ 349
+ 350
+ 351
+ 352
+ 353
+ 354
+ 355
+ 356
+ 357
+ 358
+ 359
+ 360
+ 361
+ 362
+ 363
+ 364
+ 365
+ 366
+ 367
+ 368
+ 369
+ 370
+ 371
+ 372
+ 373
+ 374
+ 375
+ 376
+ 377
+ 378
+ 379
+ 380
+ 381
+ 382
+ 383
+ 384
+ 385
+ 386
+ 387
+ 388
+ 389
+ 390
+ 391
+ 392
+ 393
+ 394
+ 395
+ 396
+ 397
+ 398
+ 399
+ 400
+ 401
+ 402
+ 403
+ 404
+ 405
+ 406
+ 407
+ 408
+ 409
+ 410
+ 411
+ 412
+ 413
+ 414
+ 415
+ 416
+ 417
+ 418
+ 419
+ 420
+ 421
+ 422
+ 423
+ 424
+ 425
+ 426
+ 427
+ 428
+ 429
+ 430
+ 431
+ 432
+ 433
+ 434
+ 435
+ 436
+ 437
+ 438
+ 439
+ 440
+ 441
+ 442
+ 443
+ 444
+ 445
+ 446
+ 447
+ 448
+ 449
+ 450
+ 451
+ 452
+ 453
+ 454
+ 455
+ 456
+ 457
+ 458
+ 459
+ 460
+ 461
+ 462
+ 463
+ 464
+ 465
+ 466
+ 467
+ 468
+ 469
+ 470
+ 471
+ 472
+ 473
+ 474
+ 475
+ 476
+ 477
+ 478
+ 479
+ 480
+ 481
+ 482
+ 483
+ 484
+ 485
+ 486
+ 487
+ 488
+ 489
+ 490
+ 491
+ 492
+ 493
+ 494
+ 495
+ 496
+ 497
+ 498
+ 499
+ 500
+ 501
+ 502
+ 503
+ 504
+ 505
+ 506
+ 507
+ 508
+ 509
+ 510
+ 511
+ 512
+ 513
+ 514
+ 515
+ 516
+ 517
+ 518
+ 519
+ 520
+ 521
+ 522
+ 523
+ 524
+ 525
+ 526
+ 527
+ 528
+ 529
+ 530
+ 531
+ 532
+ 533
+ 534
+ 535
+ 536
+ 537
+ 538
+ 539
+ 540
+ 541
+ 542
+ 543
+ 544
+ 545
+ 546
+ 547
+ 548
+ 549
+ 550
+ 551
+ 552
+ 553
+ 554
+ 555
+ 556
+ 557
+ 558
+ 559
+ 560
+ 561
+ 562
+ 563
+ 564
+ 565
+ 566
+ 567
+ 568
+ 569
+ 570
+ 571
+ 572
+ 573
+ 574
+ 575
+ 576
+ 577
+ 578
+ 579
+ 580
+ 581
+ 582
+ 583
+ 584
+ 585
+ 586
+ 587
+ 588
+ 589
+ 590
+ 591
+ 592
+ 593
+ 594
+ 595
+ 596
+ 597
+ 598
+ 599
+ 600
+ 601
+ 602
+ 603
+ 604
+ 605
+ 606
+ 607
+ 608
+ 609
+ 610
+ 611
+ 612
+ 613
+ 614
+ 615
+ 616
+ 617
+ 618
+ 619
+ 620
+ 621
+ 622
+ 623
+ 624
+ 625
+ 626
+ 627
+ 628
+ 629
+ 630
+ 631
+ 632
+ 633
+ 634
+ 635
+ 636
+ 637
+ 638
+ 639
+ 640
+ 641
+ 642
+ 643
+ 644
+ 645
+ 646
+ 647
+ 648
+ 649
+ 650
+ 651
+ 652
+ 653
+ 654
+ 655
+ 656
+ 657
+ 658
+ 659
+ 660
+ 661
+ 662
+ 663
+ 664
+ 665
+ 666
+ 667
+ 668
+ 669
+ 670
+ 671
+ 672
+ 673
+ 674
+ 675
+ 676
+ 677
+ 678
+ 679
+ 680
+ 681
+ 682
+ 683
+ 684
+ 685
+ 686
+ 687
+ 688
+ 689
+ 690
+ 691
+ 692
+ 693
+ 694
+ 695
+ 696
+ 697
+ 698
+ 699
+ 700
+ 701
+ 702
+ 703
+ 704
+ 705
+ 706
+ 707
+ 708
+ 709
+ 710
+ 711
+ 712
+ 713
+ 714
+ 715
+ 716
+ 717
+ 718
+ 719
+ 720
+ 721
+ 722
+ 723
+ 724
+ 725
+ 726
+ 727
+ 728
+ 729
+ 730
+ 731
+ 732
+ 733
+ 734
+ 735
+ 736
+ 737
+ 738
+ 739
+ 740
+ 741
+ 742
+ 743
+ 744
+ 745
+ 746
+ 747
+ 748
+ 749
+ 750
+ 751
+ 752
+ 753
+ 754
+ 755
+ 756
+ 757
+ 758
+ 759
+ 760
+ 761
+ 762
+ 763
+ 764
+ 765
+ 766
+ 767
+ 768
+ 769
+ 770
+ 771
+ 772
+ 773
+ 774
+ 775
+ 776
+ 777
+ 778
+ 779
+ 780
+ 781
+ 782
+ 783
+ 784
+ 785
+ 786
+ 787
+ 788
+ 789
+ 790
+ 791
+ 792
+ 793
+ 794
+ 795
+ 796
+ 797
+ 798
+ 799
+ 800
+ 801
+ 802
+ 803
+ 804
+ 805
+ 806
+ 807
+ 808
+ 809
+ 810
+ 811
+ 812
+ 813
+ 814
+ 815
+ 816
+ 817
+ 818
+ 819
+ 820
+ 821
+ 822
+ 823
+ 824
+ 825
+ 826
+ 827
+ 828
+ 829
+ 830
+ 831
+ 832
+ 833
+ 834
+ 835
+ 836
+ 837
+ 838
+ 839
+ 840
+ 841
+ 842
+ 843
+ 844
+ 845
+ 846
+ 847
+ 848
+ 849
+ 850
+ 851
+ 852
+ 853
+ 854
+ 855
+ 856
+ 857
+ 858
+ 859
+ 860
+ 861
+ 862
+ 863
+ 864
+ 865
+ 866
+ 867
+ 868
+ 869
+ 870
+ 871
+ 872
+ 873
+ 874
+ 875
+ 876
+ 877
+ 878
+ 879
+ 880
+ 881
+ 882
+ 883
+ 884
+ 885
+ 886
+ 887
+ 888
+ 889
+ 890
+ 891
+ 892
+ 893
+ 894
+ 895
+ 896
+ 897
+ 898
+ 899
+ 900
+ 901
+ 902
+ 903
+ 904
+ 905
+ 906
+ 907
+ 908
+ 909
+ 910
+ 911
+ 912
+ 913
+ 914
+ 915
+ 916
+ 917
+ 918
+ 919
+ 920
+ 921
+ 922
+ 923
+ 924
+ 925
+ 926
+ 927
+ 928
+ 929
+ 930
+ 931
+ 932
+ 933
+ 934
+ 935
+ 936
+ 937
+ 938
+ 939
+ 940
+ 941
+ 942
+ 943
+ 944
+ 945
+ 946
+ 947
+ 948
+ 949
+ 950
+ 951
+ 952
+ 953
+ 954
+ 955
+ 956
+ 957
+ 958
+ 959
+ 960
+ 961
+ 962
+ 963
+ 964
+ 965
+ 966
+ 967
+ 968
+ 969
+ 970
+ 971
+ 972
+ 973
+ 974
+ 975
+ 976
+ 977
+ 978
+ 979
+ 980
+ 981
+ 982
+ 983
+ 984
+ 985
+ 986
+ 987
+ 988
+ 989
+ 990
+ 991
+ 992
+ 993
+ 994
+ 995
+ 996
+ 997
+ 998
+ 999
+1000
+1001
+1002
+1003
+1004
+1005
+1006
+1007
+1008
+1009
+1010
+1011
+1012
+1013
+1014
+1015
+1016
+1017
+1018
+1019
+1020
+1021
+1022
+1023
+1024
+1025
+1026
+1027
+1028
+1029
+1030
+1031
+1032
+1033
+1034
+1035
+1036
+1037
+1038
+1039
+1040
+1041
+1042
+1043
+1044
+1045
+1046
+1047
+1048
+1049
+1050
+1051
+1052
+1053
+1054
+1055
+1056
+1057
+1058
+1059
+1060
+1061
+1062
+1063
+1064
+1065
+1066
+1067
+1068
+1069
+1070
+1071
+1072
+1073
+1074
+1075
+1076
+1077
+1078
+1079
+1080
+1081
+1082
+1083
+1084
+1085
+1086
+1087
+1088
+1089
+1090
+1091
+1092
+1093
+1094
+1095
+1096
+1097
+1098
+1099
+1100
+1101
+1102
+1103
+1104
+1105
+1106
+1107
+1108
+1109
+1110
+1111
+1112
+1113
+1114
+1115
+1116
+1117
+1118
+1119
+1120
+1121
+1122
+1123
+1124
+1125
+1126
+1127
+1128
+1129
+1130
+1131
+1132
+1133
+1134
+1135
+1136
+1137
+1138
+1139
+1140
+1141
+1142
+1143
+1144
+1145
+1146
+1147
+1148
+1149
+1150
+1151
+1152
+1153
+1154
+1155
+1156
+1157
+1158
+1159
+1160
+1161
+1162
+1163
+1164
+1165
+1166
+1167
+1168
+1169
+1170
+1171
+1172
+1173
+1174
+1175
+1176
+1177
+1178
+1179
+1180
+1181
+1182
+1183
+1184
+1185
+1186
+1187
+1188
+1189
+1190
+1191
+1192
+1193
+1194
+1195
+1196
+1197
+1198
+1199
+1200
+1201
+1202
+1203
+1204
+1205
+1206
+1207
+1208
+1209
+1210
+1211
+1212
+1213
+1214
+1215
+1216
+1217
+1218
+1219
+1220
+1221
+1222
+1223
+1224
+1225
+1226
+1227
+1228
+1229
+1230
+1231
+1232
+1233
+1234
+1235
+1236
+1237
+1238
+1239
+1240
+1241
+1242
+1243
+1244
+1245
+1246
+1247
+1248
+1249
+1250
+1251
+1252
+1253
+1254
+1255
+1256
+1257
+1258
+1259
+1260
+1261
+1262
+1263
+1264
+1265
+1266
+1267
+1268
+1269
+1270
+1271
+1272
+1273
+1274
+1275
+1276
+1277
+1278
+1279
+1280
+1281
+1282
+1283
+1284
+1285
+1286
+1287
+1288
+1289
+1290
+1291
+1292
+1293
+1294
+1295
+1296
+1297
+1298
+1299
+1300
+1301
+1302
+1303
+1304
+1305
+1306
+1307
+1308
+1309
+1310
+1311
+1312
+1313
+1314
+1315
+1316
+1317
+1318
+1319
+1320
+1321
+1322
+1323
+1324
+1325
+1326
+1327
+1328
+1329
+1330
+1331
+1332
+1333
+1334
+1335
+1336
+1337
+1338
+1339
+1340
+1341
+1342
+1343
+1344
+1345
+1346
+1347
+1348
+1349
+1350
+1351
+1352
+1353
+1354
+1355
+1356
+1357
+1358
+1359
+1360
+1361
+1362
+1363
+1364
+1365
+1366
+1367
+1368
+1369
+1370
+1371
+1372
+1373
+1374
+1375
+1376
+1377
+1378
+1379
+1380
+1381
+1382
+1383
+1384
+1385
+1386
+1387
+1388
+1389
+1390
+1391
+1392
+1393
+1394
+1395
+1396
+1397
+1398
+1399
+1400
+1401
+1402
+1403
+1404
+1405
+1406
+1407
+1408
+1409
+1410
+1411
+1412
+1413
+1414
+1415
+1416
+1417
+1418
+1419
+1420
+1421
+1422
+1423
+1424
+1425
+1426
+1427
+1428
+1429
+1430
+1431
+1432
+1433
+1434
+1435
+1436
+1437
+1438
+1439
+1440
+1441
+1442
+1443
+1444
+1445
+1446
+1447
+1448
+1449
+1450
+1451
+1452
+1453
+1454
+1455
+1456
+1457
+1458
+1459
+1460
+1461
+1462
+1463
+1464
+1465
+1466
+1467
+1468
+1469
+1470
+1471
+1472
+1473
+1474
+1475
+1476
+1477
+1478
+1479
+1480
+1481
+1482
+1483
+1484
+1485
+1486
+1487
+1488
+1489
+1490
+1491
+1492
+1493
+1494
+1495
+1496
+1497
+1498
+1499
+1500
+1501
+1502
+1503
+1504
+1505
+1506
+1507
+1508
+1509
+1510
+1511
+1512
+1513
+1514
+1515
+1516
+1517
+1518
+1519
+1520
+1521
+1522
+1523
+1524
+1525
+1526
+1527
+1528
+1529
+1530
+1531
+1532
+1533
+1534
+1535
+1536
+1537
+1538
+1539
+1540
+1541
+1542
+1543
+1544
+1545
+1546
+1547
+1548
+1549
+1550
+1551
+1552
+1553
+1554
+1555
+1556
+1557
+1558
+1559
+1560
+1561
+1562
+1563
+1564
+1565
+1566
+1567
+1568
+1569
+1570
+1571
+1572
+1573
+1574
+1575
+1576
+1577
+1578
+1579
+1580
+1581
+1582
+1583
+1584
+1585
+1586
+1587
+1588
+1589
+1590
+1591
+1592
+1593
+1594
+1595
+1596
+1597
+1598
+1599
+1600
+1601
+1602
+1603
+1604
+1605
+1606
+1607
+1608
+1609
+1610
+1611
+1612
+1613
+1614
+1615
+1616
+1617
+1618
+1619
+1620
+1621
+1622
+1623
+1624
+1625
+1626
+1627
+1628
+1629
+1630
+1631
+1632
+1633
+1634
+1635
+1636
+1637
+1638
+1639
+1640
+1641
+1642
+1643
+1644
+1645
+1646
+1647
+1648
+1649
+1650
+1651
+1652
+1653
+1654
+1655
+1656
+1657
+1658
+1659
+1660
+1661
+1662
+1663
+1664
+1665
+1666
+1667
+1668
+1669
+1670
+1671
+1672
+1673
+1674
+1675
+1676
+1677
+1678
+1679
+1680
+1681
+1682
+1683
+1684
+1685
+1686
+1687
+1688
+1689
+1690
+1691
+1692
+1693
+1694
+1695
+1696
+1697
+1698
+1699
+1700
+1701
+1702
+1703
+1704
+1705
+1706
+1707
+1708
+1709
+1710
+1711
+1712
+1713
+1714
+1715
+1716
+1717
+1718
+1719
+1720
+1721
+1722
+1723
+1724
+1725
+1726
+1727
+1728
+1729
+1730
+1731
+1732
+1733
+1734
+1735
+1736
+1737
+1738
+1739
+1740
+1741
+1742
+1743
+1744
+1745
+1746
+1747
+1748
+1749
+1750
+1751
+1752
+1753
+1754
+1755
+1756
+1757
+1758
+1759
+1760
+1761
+1762
+1763
+1764
+1765
+1766
+1767
+1768
+1769
+1770
+1771
+1772
+1773
+1774
+1775
+1776
+1777
+1778
+1779
+1780
+1781
+1782
+1783
+1784
+1785
+1786
+1787
+1788
+1789
+1790
+1791
+1792
+1793
+1794
+1795
+1796
+1797
+1798
+1799
+1800
+1801
+1802
+1803
+1804
+1805
+1806
+1807
+1808
+1809
+1810
+1811
+1812
+1813
+1814
+1815
+1816
+1817
+1818
+1819
+1820
+1821
+1822
+1823
+1824
+1825
+1826
+1827
+1828
+1829
+1830
+1831
+1832
+1833
+1834
+1835
+1836
+1837
+1838
+1839
+1840
+1841
+1842
+1843
+1844
+1845
+1846
+1847
+1848
+1849
+1850
+1851
+1852
+1853
+1854
+1855
+1856
+1857
+1858
+1859
+1860
+1861
+1862
+1863
+1864
+1865
+1866
+1867
+1868
+1869
+1870
+1871
+1872
+1873
+1874
+1875
+1876
+1877
+1878
+1879
+1880
+1881
+1882
+1883
+1884
+1885
+1886
+1887
+1888
+1889
+1890
+1891
+1892
+1893
+1894
+1895
+1896
+1897
+1898
+1899
+1900
+1901
+1902
+1903
+1904
+1905
+1906
+1907
+1908
+1909
+1910
+1911
+1912
+1913
+1914
+1915
+1916
+1917
+1918
+1919
+1920
+1921
+1922
+1923
+1924
+1925
+1926
+1927
+1928
+1929
+1930
+1931
+1932
+1933
+1934
+1935
+1936
+1937
+1938
+1939
+1940
+1941
+1942
+1943
+1944
+1945
+1946
+1947
+1948
+1949
+1950
+1951
+1952
+1953
+1954
+1955
+1956
+1957
+1958
+1959
+1960
+1961
+1962
+1963
+1964
+1965
+1966
+1967
+1968
+1969
+1970
+1971
+1972
+1973
+1974
+1975
+1976
+1977
+1978
+1979
+1980
+1981
+1982
+1983
+1984
+1985
+1986
+1987
+1988
+1989
+1990
+1991
+1992
+1993
+1994
+1995
+1996
+1997
+1998
+1999
+2000
+2001
+2002
+2003
+2004
+2005
+2006
+2007
+2008
+2009
+2010
+2011
+2012
+2013
+2014
+2015
+2016
+2017
+2018
+2019
+2020
+2021
+2022
+2023
+2024
+2025
+2026
+2027
+2028
+2029
+2030
+2031
+2032
+2033
+2034
+2035
+2036
+2037
+2038
+2039
+2040
+2041
+2042
+2043
+2044
+2045
+2046
+2047
+2048
+2049
+2050
+2051
+2052
+2053
+2054
+2055
+2056
+2057
+2058
+2059
+2060
+2061
+2062
+2063
+2064
+2065
+2066
+2067
+2068
+2069
+2070
+2071
+2072
+2073
+2074
+2075
+2076
+2077
+2078
+2079
+2080
+2081
+2082
+2083
+2084
+2085
+2086
+2087
+2088
+2089
+2090
+2091
+2092
+2093
+2094
+2095
+2096
+2097
+2098
+2099
+2100
+2101
+2102
+2103
+2104
+2105
+2106
+2107
+2108
+2109
+2110
+2111
+2112
+2113
+2114
+2115
+2116
+2117
+2118
+2119
+2120
+2121
+2122
+2123
+2124
+2125
+2126
+2127
+2128
+2129
+2130
+2131
+2132
+2133
+2134
+2135
+2136
+2137
+2138
+2139
+2140
+2141
+2142
+2143
+2144
+2145
+2146
+2147
+2148
+2149
+2150
+2151
+2152
+2153
+2154
+2155
+2156
+2157
+2158
+2159
+2160
+2161
+2162
+2163
+2164
+2165
+2166
+2167
+2168
+2169
+2170
+2171
+2172
+2173
+2174
+2175
+2176
+2177
// *****************************************************************************
 /*!
-  \file      src/PDE/Transport/DGTransport.hpp
+  \file      src/Inciter/Refiner.cpp
   \copyright 2012-2015 J. Bakosi,
              2016-2018 Los Alamos National Security, LLC.,
              2019-2021 Triad National Security, LLC.
              All rights reserved. See the LICENSE file for details.
-  \brief     Scalar transport using disccontinous Galerkin discretization
-  \details   This file implements the physics operators governing transported
-     scalars using disccontinuous Galerkin discretization.
-*/
-// *****************************************************************************
-#ifndef DGTransport_h
-#define DGTransport_h
+  \brief     Mesh refiner for interfacing the mesh refinement library
+  \see       Refiner.h for more info.
+*/
+// *****************************************************************************
+
+#include <vector>
+#include <algorithm>
 
-#include <vector>
-#include <array>
-#include <limits>
-#include <cmath>
-#include <unordered_set>
-#include <map>
-
-#include "Macro.hpp"
-#include "Exception.hpp"
-#include "Vector.hpp"
-#include "UnsMesh.hpp"
-#include "Integrate/Basis.hpp"
-#include "Integrate/Quadrature.hpp"
-#include "Integrate/Initialize.hpp"
-#include "Integrate/Mass.hpp"
-#include "Integrate/Surface.hpp"
-#include "Integrate/Boundary.hpp"
-#include "Integrate/Volume.hpp"
-#include "Riemann/Upwind.hpp"
-#include "Reconstruction.hpp"
-#include "Limiter.hpp"
-#include "PrefIndicator.hpp"
-#include "EoS/EOS.hpp"
-#include "FunctionPrototypes.hpp"
-#include "ConfigureTransport.hpp"
-
-namespace inciter {
-
-extern ctr::InputDeck g_inputdeck;
-
-namespace dg {
-
-//! \brief Transport equation used polymorphically with tk::DGPDE
-//! \details The template argument(s) specify policies and are used to configure
-//!   the behavior of the class. The policies are:
-//!   - Physics - physics configuration, see PDE/Transport/Physics.h
-//!   - Problem - problem configuration, see PDE/Transport/Problem.h
-//! \note The default physics is DGAdvection, set in
-//!    inciter::deck::check_transport()
-template< class Physics, class Problem >
-class Transport {
-
-  private:
-    using eq = tag::transport;
-
-  public:
-    //! Constructor
-    explicit Transport() :
-      m_physics( Physics() ),
-      m_problem( Problem() ),
-      m_ncomp( g_inputdeck.get< tag::ncomp >() )
-    {
-      // associate boundary condition configurations with state functions, the
-      // order in which the state functions listed matters, see ctr::bc::Keys
-      brigand::for_each< ctr::bclist::Keys >( ConfigBC( m_bc,
-        { dirichlet
-        , invalidBC  // Symmetry BC not implemented
-        , inlet
-        , outlet
-        , invalidBC  // Characteristic BC not implemented
-        , extrapolate } ) );
-      m_problem.errchk( m_ncomp );
-    }
-
-    //! Find the number of primitive quantities required for this PDE system
-    //! \return The number of primitive quantities required to be stored for
-    //!   this PDE system
-    std::size_t nprim() const
-    {
-      // transport does not need/store any primitive quantities currently
-      return 0;
-    }
-
-    //! Find the number of materials set up for this PDE system
-    //! \return The number of materials set up for this PDE system
-    std::size_t nmat() const
-    {
-      return m_ncomp;
-    }
-
-    //! Assign number of DOFs per equation in the PDE system
-    //! \param[in,out] numEqDof Array storing number of Dofs for each PDE
-    //!   equation
-    void numEquationDofs(std::vector< std::size_t >& numEqDof) const
-    {
-      // all equation-dofs initialized to ndofs
-      for (std::size_t i=0; i<m_ncomp; ++i) {
-        numEqDof.push_back(g_inputdeck.get< tag::ndof >());
-      }
-    }
-
-    //! Find how 'stiff equations', which we currently
-    //! have none for Transport
-    //! \return number of stiff equations
-    std::size_t nstiffeq() const
-    { return 0; }
-
-    //! Find how 'nonstiff equations', which we currently
-    //! don't use for Transport
-    //! \return number of non-stiff equations
-    std::size_t nnonstiffeq() const
-    { return 0; }
-
-    //! Locate the stiff equations. Unused for transport.
-    //! \param[out] stiffEqIdx list
-    void setStiffEqIdx( std::vector< std::size_t >& stiffEqIdx ) const
-    {
-      stiffEqIdx.resize(0);
-    }
-
-    //! Locate the nonstiff equations. Unused for transport.
-    //! \param[out] nonStiffEqIdx list
-    void setNonStiffEqIdx( std::vector< std::size_t >& nonStiffEqIdx ) const
-    {
-      nonStiffEqIdx.resize(0);
-    }
-
-    //! Determine elements that lie inside the user-defined IC box
-    void IcBoxElems( const tk::Fields&,
-      std::size_t,
-      std::vector< std::unordered_set< std::size_t > >& ) const
-    {}
-
-    //! Initalize the transport equations for DG
-    //! \param[in] L Element mass matrix
-    //! \param[in] inpoel Element-node connectivity
-    //! \param[in] coord Array of nodal coordinates
-    //! \param[in,out] unk Array of unknowns
-    //! \param[in] t Physical time
-    //! \param[in] nielem Number of internal elements
-    void
-    initialize(
-      const tk::Fields& L,
-      const std::vector< std::size_t >& inpoel,
-      const tk::UnsMesh::Coords& coord,
-      const std::vector< std::unordered_set< std::size_t > >& /*inbox*/,
-      const std::unordered_map< std::size_t, std::set< std::size_t > >&,
-      tk::Fields& unk,
-      tk::real t,
-      const std::size_t nielem ) const
-    {
-      tk::initialize( m_ncomp, m_mat_blk, L, inpoel, coord,
-                      Problem::initialize, unk, t, nielem );
-    }
+#include "Refiner.hpp"
+#include "Reorder.hpp"
+#include "AMR/mesh_adapter.hpp"
+#include "AMR/Error.hpp"
+#include "Inciter/InputDeck/InputDeck.hpp"
+#include "CGPDE.hpp"
+#include "DGPDE.hpp"
+#include "FVPDE.hpp"
+#include "DerivedData.hpp"
+#include "UnsMesh.hpp"
+#include "Centering.hpp"
+#include "Around.hpp"
+#include "Sorter.hpp"
+#include "Discretization.hpp"
+
+namespace inciter {
+
+extern ctr::InputDeck g_inputdeck;
+extern ctr::InputDeck g_inputdeck_defaults;
+extern std::vector< CGPDE > g_cgpde;
+extern std::vector< DGPDE > g_dgpde;
+extern std::vector< FVPDE > g_fvpde;
+
+} // inciter::
+
+using inciter::Refiner;
+
+Refiner::Refiner( std::size_t meshid,
+                  const CProxy_Transporter& transporter,
+                  const CProxy_Sorter& sorter,
+                  const tk::CProxy_MeshWriter& meshwriter,
+                  const std::vector< Scheme >& scheme,
+                  const tk::RefinerCallback& cbr,
+                  const tk::SorterCallback& cbs,
+                  const std::vector< std::size_t >& ginpoel,
+                  const tk::UnsMesh::CoordMap& coordmap,
+                  const std::map< int, std::vector< std::size_t > >& bface,
+                  const std::vector< std::size_t >& triinpoel,
+                  const std::map< int, std::vector< std::size_t > >& bnode,
+                  const std::vector< std::size_t >& elemblid,
+                  int nchare ) :
+  m_meshid( meshid ),
+  m_ncit(0),
+  m_host( transporter ),
+  m_sorter( sorter ),
+  m_meshwriter( meshwriter ),
+  m_scheme( scheme ),
+  m_cbr( cbr ),
+  m_cbs( cbs ),
+  m_ginpoel( ginpoel ),
+  m_el( tk::global2local( ginpoel ) ),     // fills m_inpoel, m_gid, m_lid
+  m_coordmap( coordmap ),
+  m_coord( flatcoord(coordmap) ),
+  m_bface( bface ),
+  m_bnode( bnode ),
+  m_triinpoel( triinpoel ),
+  m_elemblockid(),
+  m_nchare( nchare ),
+  m_mode( RefMode::T0REF ),
+  m_initref( g_inputdeck.get< tag::amr, tag::initial >() ),
+  m_ninitref( g_inputdeck.get< tag::amr, tag::initial >().size() ),
+  m_refiner( g_inputdeck.get< tag::amr, tag::maxlevels >(), m_inpoel ),
+  m_nref( 0 ),
+  m_nbnd( 0 ),
+  m_extra( 0 ),
+  m_ch(),
+  m_edgech(),
+  m_chedge(),
+  m_localEdgeData(),
+  m_remoteEdgeData(),
+  m_nodeCommMap(),
+  m_oldTets(),
+  m_addedNodes(),
+  m_addedTets(),
+  m_removedNodes(),
+  m_amrNodeMap(),
+  m_oldntets( 0 ),
+  m_coarseBndFaces(),
+  m_coarseBndNodes(),
+  m_coarseBlkElems(),
+  m_rid( m_coord[0].size() ),
+//  m_oldrid(),
+  m_lref( m_rid.size() ),
+//  m_oldparent(),
+  m_writeCallback(),
+  m_outref_ginpoel(),
+  m_outref_el(),
+  m_outref_coord(),
+  m_outref_addedNodes(),
+  m_outref_addedTets(),
+  m_outref_nodeCommMap(),
+  m_outref_bface(),
+  m_outref_bnode(),
+  m_outref_triinpoel()
+// *****************************************************************************
+//  Constructor
+//! \param[in] meshid Mesh ID
+//! \param[in] transporter Transporter (host) proxy
+//! \param[in] sorter Mesh reordering (sorter) proxy
+//! \param[in] meshwriter Mesh writer proxy
+//! \param[in] scheme Discretization schemes (one per mesh)
+//! \param[in] cbr Charm++ callbacks for Refiner
+//! \param[in] cbs Charm++ callbacks for Sorter
+//! \param[in] ginpoel Mesh connectivity (this chare) using global node IDs
+//! \param[in] coordmap Mesh node coordinates (this chare) for global node IDs
+//! \param[in] bface File-internal elem ids of side sets
+//! \param[in] triinpoel Triangle face connectivity with global IDs
+//! \param[in] bnode Node lists of side sets
+//! \param[in] elemblid Mesh block ids associated to local tet ids
+//! \param[in] nchare Total number of refiner chares (chare array elements)
+// *****************************************************************************
+{
+  Assert( !m_ginpoel.empty(), "No elements assigned to refiner chare" );
+  Assert( tk::positiveJacobians( m_inpoel, m_coord ),
+          "Input mesh to Refiner Jacobian non-positive" );
+  Assert( !tk::leakyPartition(
+            tk::genEsuelTet( m_inpoel, tk::genEsup(m_inpoel,4) ),
+            m_inpoel, m_coord ),
+          "Input mesh to Refiner leaky" );
+
+  // Construct data structure assigning sets of element ids to mesh blocks
+  for (std::size_t ie=0; ie<elemblid.size(); ++ie) {
+    m_elemblockid[elemblid[ie]].insert(ie);
+  }
+
+  #if not defined(__INTEL_COMPILER) || defined(NDEBUG)
+  // The above ifdef skips running the conformity test with the intel compiler
+  // in debug mode only. This is necessary because in tk::conforming(), filling
+  // up the map can fail with some meshes (only in parallel), e.g., tube.exo,
+  // used by some regression tests, due to the intel compiler generating some
+  // garbage incorrect code - only in debug, only in parallel, only with that
+  // mesh.
+  Assert( tk::conforming( m_inpoel, m_coord, true, m_rid ),
+          "Input mesh to Refiner not conforming" );
+  #endif
+
+  // Generate local -> refiner lib node id map and its inverse
+  libmap();
+
+  // Reverse initial mesh refinement type list (will pop from back)
+  std::reverse( begin(m_initref), end(m_initref) );
+
+  // Generate boundary data structures for coarse mesh
+  coarseMesh();
 
-    //! Save initial densities for all materials
-    //! \param[out] rho0mat List of initial densities
-    void setRho0mat( std::vector< tk::real >& rho0mat ) const
-    {
-      rho0mat.resize(0);
-    }
-
-    //! Compute density constraint for a given material
-    // //! \param[in] nelem Number of elements
-    // //! \param[in] unk Array of unknowns
-    // //! \param[in] rho0mat List of initial densities
-    //! \param[out] densityConstr Density Constraint: rho/(rho0*det(g))
-    void computeDensityConstr( std::size_t /*nelem*/,
-                               tk::Fields& /*unk*/,
-                               std::vector< tk::real >& /*rho0mat*/,
-                               std::vector< tk::real >& densityConstr) const
-    {
-      densityConstr.resize(0);
-    }
-
-    //! Compute the left hand side mass matrix
-    //! \param[in] geoElem Element geometry array
-    //! \param[in,out] l Block diagonal mass matrix
-    void lhs( const tk::Fields& geoElem, tk::Fields& l ) const {
-      const auto ndof = g_inputdeck.get< tag::ndof >();
-      tk::mass( m_ncomp, ndof, geoElem, l );
-    }
-
-    //! Update the interface cells to first order dofs
-    //! \details This function resets the high-order terms in interface cells,
-    //!   and is currently not used in transport.
-    void updateInterfaceCells( tk::Fields&,
-      std::size_t,
-      std::vector< std::size_t >& ) const {}
-
-    //! Update the primitives for this PDE system
-    //! \details This function computes and stores the dofs for primitive
-    //!   quantities, which are currently unused for transport.
-    void updatePrimitives( const tk::Fields&,
-                           const tk::Fields&,
-                           const tk::Fields&,
-                           tk::Fields&,
-                           std::size_t ) const {}
+  // If initial mesh refinement is configured, start initial mesh refinement.
+  // See also tk::grm::check_amr_errors in Control/Inciter/InputDeck/Ggrammar.h.
+  if (g_inputdeck.get< tag::amr, tag::t0ref >() && m_ninitref > 0)
+    t0ref();
+  else
+    endt0ref();
+}
+
+void
+Refiner::libmap()
+// *****************************************************************************
+// (Re-)generate local -> refiner lib node id map and its inverse
+// *****************************************************************************
+{
+  // Fill initial (matching) mapping between local and refiner node ids
+  std::iota( begin(m_rid), end(m_rid), 0 );
+
+  // Fill in inverse, mapping refiner to local node ids
+  std::size_t i = 0;
+  for (auto r : m_rid) m_lref[r] = i++;
+}
+
+void
+Refiner::coarseMesh()
+// *****************************************************************************
+// (Re-)generate side set and block data structures for coarse mesh
+// *****************************************************************************
+{
+  // Generate unique set of faces for each side set of the input (coarsest) mesh
+  m_coarseBndFaces.clear();
+  for (const auto& [ setid, faceids ] : m_bface) {
+    auto& faces = m_coarseBndFaces[ setid ];
+    for (auto f : faceids) {
+      faces.insert(
+        {{{ m_triinpoel[f*3+0], m_triinpoel[f*3+1], m_triinpoel[f*3+2] }}} );
+    }
+  }
+
+  // Generate unique set of nodes for each side set of the input (coarsest) mesh
+  m_coarseBndNodes.clear();
+  for (const auto& [ setid, nodes ] : m_bnode) {
+    m_coarseBndNodes[ setid ].insert( begin(nodes), end(nodes) );
+  }
 
-    //! Clean up the state of trace materials for this PDE system
-    //! \details This function cleans up the state of materials present in trace
-    //!   quantities in each cell. This is currently unused for transport.
-    void cleanTraceMaterial( tk::real,
-                             const tk::Fields&,
-                             tk::Fields&,
-                             tk::Fields&,
-                             std::size_t ) const {}
-
-    //! Reconstruct second-order solution from first-order
-    //! \param[in] t Physical time
-    //! \param[in] geoFace Face geometry array
-    //! \param[in] geoElem Element geometry array
-    //! \param[in] fd Face connectivity and boundary conditions object
-    //! \param[in] esup Elements-surrounding-nodes connectivity
-    //! \param[in] inpoel Element-node connectivity
-    //! \param[in] coord Array of nodal coordinates
-    //! \param[in,out] U Solution vector at recent time step
-    //! \param[in,out] P Primitive vector at recent time step
-    void reconstruct( tk::real t,
-                      const tk::Fields& geoFace,
-                      const tk::Fields& geoElem,
-                      const inciter::FaceData& fd,
-                      const std::map< std::size_t, std::vector< std::size_t > >&
-                        esup,
-                      const std::vector< std::size_t >& inpoel,
-                      const tk::UnsMesh::Coords& coord,
-                      tk::Fields& U,
-                      tk::Fields& P ) const
-    {
-      const auto rdof = g_inputdeck.get< tag::rdof >();
-
-      // do reconstruction only if P0P1
-      if (rdof == 4 && g_inputdeck.get< tag::ndof >() == 1) {
-        const auto nelem = fd.Esuel().size()/4;<--- Variable 'nelem' is assigned a value that is never used.
-        const auto intsharp = g_inputdeck.get< tag::transport,<--- Variable 'intsharp' is assigned a value that is never used.
-          tag::intsharp >();
-
-        Assert( U.nprop() == rdof*m_ncomp, "Number of components in solution "
-                "vector must equal "+ std::to_string(rdof*m_ncomp) );
-        Assert( fd.Inpofa().size()/3 == fd.Esuf().size()/2,
-                "Mismatch in inpofa size" );
-
-        // allocate and initialize matrix and vector for reconstruction
-        std::vector< std::array< std::array< tk::real, 3 >, 3 > >
-          lhs_ls( nelem, {{ {{0.0, 0.0, 0.0}},
-                            {{0.0, 0.0, 0.0}},
-                            {{0.0, 0.0, 0.0}} }} );
-        // specify how many variables need to be reconstructed
-        std::vector< std::size_t > vars;
-        for (std::size_t c=0; c<m_ncomp; ++c) vars.push_back(c);
-
-        std::vector< std::vector< std::array< tk::real, 3 > > >
-          rhs_ls( nelem, std::vector< std::array< tk::real, 3 > >
-            ( m_ncomp,
-              {{ 0.0, 0.0, 0.0 }} ) );
-
-        // reconstruct x,y,z-derivatives of unknowns
-        // 0. get lhs matrix, which is only geometry dependent
-        tk::lhsLeastSq_P0P1(fd, geoElem, geoFace, lhs_ls);
-
-        // 1. internal face contributions
-        tk::intLeastSq_P0P1( rdof, fd, geoElem, U, rhs_ls, vars );
-
-        // 2. boundary face contributions
-        for (const auto& b : m_bc)
-          tk::bndLeastSqConservedVar_P0P1( m_ncomp, 
-            m_mat_blk, rdof, b.first, fd, geoFace, geoElem, t, b.second, 
-            P, U, rhs_ls, vars );
-
-        // 3. solve 3x3 least-squares system
-        tk::solveLeastSq_P0P1( rdof, lhs_ls, rhs_ls, U, vars );
-
-        for (std::size_t e=0; e<nelem; ++e)
-        {
-          std::vector< std::size_t > matInt(m_ncomp, 0);
-          std::vector< tk::real > alAvg(m_ncomp, 0.0);
-          for (std::size_t k=0; k<m_ncomp; ++k)
-            alAvg[k] = U(e, k*rdof);
-          auto intInd = interfaceIndicator(m_ncomp, alAvg, matInt);
-          if ((intsharp > 0) && intInd)
-          {
-            // Reconstruct second-order dofs of volume-fractions in Taylor space
-            // using nodal-stencils, for a good interface-normal estimate
-            tk::recoLeastSqExtStencil( rdof, e, esup, inpoel, geoElem,
-              U, vars );
-          }
-        }
-
-        // 4. transform reconstructed derivatives to Dubiner dofs
-        tk::transform_P0P1( rdof, nelem, inpoel, coord, U, vars );
-      }
-    }
-
-    //! Limit second-order solution
-    //! \param[in] t Physical time
-    //! \param[in] geoFace Face geometry array
-    //! \param[in] fd Face connectivity and boundary conditions object
-    //! \param[in] esup Elements surrounding points
-    //! \param[in] inpoel Element-node connectivity
-    //! \param[in] coord Array of nodal coordinates
-    //! \param[in] ndofel Vector of local number of degrees of freedome
-//    //! \param[in] gid Local->global node id map
-//    //! \param[in] bid Local chare-boundary node ids (value) associated to
-//    //!   global node ids (key)
-//    //! \param[in] uNodalExtrm Chare-boundary nodal extrema for conservative
-//    //!   variables
-    //! \param[in,out] U Solution vector at recent time step
-    void limit( [[maybe_unused]] tk::real t,
-                [[maybe_unused]] const tk::Fields& geoFace,
-                const tk::Fields&,
-                const inciter::FaceData& fd,
-                const std::map< std::size_t, std::vector< std::size_t > >& esup,
-                const std::vector< std::size_t >& inpoel,
-                const tk::UnsMesh::Coords& coord,
-                const std::vector< std::size_t >& ndofel,
-                const std::vector< std::size_t >&,
-                const std::unordered_map< std::size_t, std::size_t >&,
-                const std::vector< std::vector<tk::real> >&,
-                const std::vector< std::vector<tk::real> >&,
-                const std::vector< std::vector<tk::real> >&,
-                tk::Fields& U,
-                tk::Fields&,
-                std::vector< std::size_t >& ) const
-    {
-      const auto limiter = g_inputdeck.get< tag::limiter >();
-
-      if (limiter == ctr::LimiterType::WENOP1)
-        WENO_P1( fd.Esuel(), U );
-      else if (limiter == ctr::LimiterType::SUPERBEEP1)
-        Superbee_P1( fd.Esuel(), inpoel, ndofel, coord, U );
-      else if (limiter == ctr::LimiterType::VERTEXBASEDP1)
-        VertexBasedTransport_P1( esup, inpoel, ndofel, fd.Esuel().size()/4,
-          coord, U );
-    }
-
-    //! Update the conservative variable solution for this PDE system
-    //! \details This function computes the updated dofs for conservative
-    //!   quantities based on the limited solution and is currently not used in
-    //!   transport.
-    void CPL( const tk::Fields&,
-              const tk::Fields&,
-              const std::vector< std::size_t >&,
-              const tk::UnsMesh::Coords&,
-              tk::Fields&,
-              std::size_t ) const {}
-
-    //! Return cell-average deformation gradient tensor (no-op for transport)
-    //! \details This function is a no-op in transport.
-    std::array< std::vector< tk::real >, 9 > cellAvgDeformGrad(
-      const tk::Fields&,
-      std::size_t ) const
-    {
-      return {};
-    }
+  // Generate set of elements for each mesh block of the input (coarsest) mesh
+  m_coarseBlkElems.clear();
+  for (const auto& [blid, elids] : m_elemblockid) {
+    for (auto ie : elids) {
+      m_coarseBlkElems[blid].insert( {{{m_inpoel[ie*4+0], m_inpoel[ie*4+1],
+        m_inpoel[ie*4+2], m_inpoel[ie*4+3]}}} );
+    }
+  }
+}
+
+void
+Refiner::sendProxy()
+// *****************************************************************************
+// Send Refiner proxy to Discretization objects
+//! \details This should be called when bound Discretization chare array
+//!   elements have already been created.
+// *****************************************************************************
+{
+  // Make sure (bound) Discretization chare is already created and accessible
+  Assert( m_scheme[m_meshid].disc()[thisIndex].ckLocal() != nullptr,
+          "About to dereference nullptr" );
+
+  // Pass Refiner Charm++ chare proxy to fellow (bound) Discretization object
+  m_scheme[m_meshid].disc()[thisIndex].ckLocal()->setRefiner( thisProxy );
+}
+
+void
+Refiner::reorder()
+// *****************************************************************************
+// Query Sorter and update local mesh with the reordered one
+// *****************************************************************************
+{
+  m_sorter[thisIndex].ckLocal()->
+    mesh( m_ginpoel, m_coordmap, m_triinpoel, m_bnode );
+
+  // Update local mesh data based on data just received from Sorter
+  m_el = tk::global2local( m_ginpoel );     // fills m_inpoel, m_gid, m_lid
+  m_coord = flatcoord( m_coordmap );
+
+  // Re-generate boundary data structures for coarse mesh
+  coarseMesh();
+
+  // WARNING: This re-creates the AMR lib which is probably not what we
+  // ultimately want, beacuse this deletes its history recorded during initial
+  // (t<0) refinement. However, this appears to correctly update the local mesh
+  // based on the reordered one (from Sorter) at least when t0ref is off.
+  m_refiner = AMR::mesh_adapter_t(
+    g_inputdeck.get< tag::amr, tag::maxlevels >(), m_inpoel );
+}
+
+tk::UnsMesh::Coords
+Refiner::flatcoord( const tk::UnsMesh::CoordMap& coordmap )
+// *****************************************************************************
+// Generate flat coordinate data from coordinate map
+//! \param[in] coordmap Coordinates associated to global node IDs of mesh chunk
+//! \return Flat coordinate data
+// *****************************************************************************
+{
+  tk::UnsMesh::Coords coord;
+
+  // Convert node coordinates associated to global node IDs to a flat vector
+  auto npoin = coordmap.size();
+  Assert( m_gid.size() == npoin, "Size mismatch" );
+  coord[0].resize( npoin );
+  coord[1].resize( npoin );
+  coord[2].resize( npoin );
+  for (const auto& [ gid, coords ] : coordmap) {
+    auto i = tk::cref_find( m_lid, gid );
+    Assert( i < npoin, "Indexing out of coordinate map" );
+    coord[0][i] = coords[0];
+    coord[1][i] = coords[1];
+    coord[2][i] = coords[2];
+  }
+
+  return coord;
+}
+
+void
+Refiner::dtref( const std::map< int, std::vector< std::size_t > >& bface,
+                const std::map< int, std::vector< std::size_t > >& bnode,
+                const std::vector< std::size_t >& triinpoel )
+// *****************************************************************************
+// Start mesh refinement (during time stepping, t>0)
+//! \param[in] bface Boundary-faces mapped to side set ids
+//! \param[in] bnode Boundary-node lists mapped to side set ids
+//! \param[in] triinpoel Boundary-face connectivity
+// *****************************************************************************
+{
+  m_mode = RefMode::DTREF;
+
+  // Update boundary node lists
+  m_bface = bface;
+  m_bnode = bnode;
+  m_triinpoel = tk::remap(triinpoel, m_gid);
+
+  start();
+}
+
+void
+Refiner::outref( const std::map< int, std::vector< std::size_t > >& bface,
+                 const std::map< int, std::vector< std::size_t > >& bnode,
+                 const std::vector< std::size_t >& triinpoel,
+                 CkCallback c,
+                 RefMode mode )
+// *****************************************************************************
+// Start mesh refinement (for field output)
+//! \param[in] bface Boundary-faces mapped to side set ids
+//! \param[in] bnode Boundary-node lists mapped to side set ids
+//! \param[in] triinpoel Boundary-face connectivity
+//! \param[in] c Function to continue with after the writing field output
+//! \param[in] mode Refinement mode
+// *****************************************************************************
+{
+  m_mode = mode;
+
+  m_writeCallback = c;
+
+  // Update boundary node lists
+  m_bface = bface;
+  m_bnode = bnode;
+  m_triinpoel = triinpoel;
+
+  start();
+}
+
+void
+Refiner::t0ref()
+// *****************************************************************************
+// Output mesh to file before a new step mesh refinement
+// *****************************************************************************
+{
+  Assert( m_ninitref > 0, "No initial mesh refinement steps configured" );
+  // Output initial mesh to file
+  auto l = m_ninitref - m_initref.size();  // num initref steps completed
+  auto t0 = g_inputdeck.get< tag::t0 >();
+  if (l == 0) {
+    writeMesh( "t0ref", l, t0-1.0,
+      CkCallback( CkIndex_Refiner::start(), thisProxy[thisIndex] ) );
+  } else {
+    start();
+  }
+}
+
+void
+Refiner::start()
+// *****************************************************************************
+//  Start new step of mesh refinement
+// *****************************************************************************
+{
+  m_extra = 0;
+  m_ch.clear();
+  m_remoteEdgeData.clear();
+  m_remoteEdges.clear();
+
+  updateEdgeData();
 
-    //! Compute right hand side
-    //! \param[in] t Physical time
-    //! \param[in] geoFace Face geometry array
-    //! \param[in] geoElem Element geometry array
-    //! \param[in] fd Face connectivity and boundary conditions object
-    //! \param[in] inpoel Element-node connectivity
-    //! \param[in] coord Array of nodal coordinates
-    //! \param[in] U Solution vector at recent time step
-    //! \param[in] P Primitive vector at recent time step
-    //! \param[in] ndofel Vector of local number of degrees of freedom
-    // //! \param[in] rho0mat Initial densities of all materials
-    //! \param[in] dt Delta time
-    //! \param[in,out] R Right-hand side vector computed
-    void rhs( tk::real t,
-              const tk::Fields& geoFace,
-              const tk::Fields& geoElem,
-              const inciter::FaceData& fd,
-              const std::vector< std::size_t >& inpoel,
-              const std::vector< std::unordered_set< std::size_t > >&,
-              const tk::UnsMesh::Coords& coord,
-              const tk::Fields& U,
-              const tk::Fields& P,
-              const std::vector< std::size_t >& ndofel,
-              const std::vector< tk::real >& /*rho0mat*/,
-              const tk::real dt,
-              tk::Fields& R ) const
-    {
-      const auto ndof = g_inputdeck.get< tag::ndof >();<--- Variable 'ndof' is assigned a value that is never used.
-      const auto rdof = g_inputdeck.get< tag::rdof >();<--- Variable 'rdof' is assigned a value that is never used.
-      const auto intsharp = g_inputdeck.get< tag::transport,<--- Variable 'intsharp' is assigned a value that is never used.
-        tag::intsharp >();
-
-      Assert( U.nunk() == P.nunk(), "Number of unknowns in solution "
-              "vector and primitive vector at recent time step incorrect" );
-      Assert( U.nunk() == R.nunk(), "Number of unknowns in solution "
-              "vector and right-hand side at recent time step incorrect" );
-      Assert( U.nprop() == rdof*m_ncomp, "Number of components in solution "
-              "vector must equal "+ std::to_string(rdof*m_ncomp) );
-      Assert( P.nprop() == 0, "Number of components in primitive "
-              "vector must equal "+ std::to_string(0) );
-      Assert( R.nprop() == ndof*m_ncomp, "Number of components in right-hand "
-              "side vector must equal "+ std::to_string(ndof*m_ncomp) );
-      Assert( fd.Inpofa().size()/3 == fd.Esuf().size()/2,
-              "Mismatch in inpofa size" );
-
-      // set rhs to zero
-      R.fill(0.0);
-
-      // empty vector for non-conservative terms. This vector is unused for
-      // linear transport since, there are no non-conservative terms in the
-      // system of PDEs.
-      std::vector< std::vector < tk::real > > riemannDeriv;
-
-      std::vector< std::vector< tk::real > > vriem;
-      std::vector< std::vector< tk::real > > riemannLoc;
-
-      // compute internal surface flux integrals
-      std::vector< std::size_t > solidx(1, 0);
-      tk::surfInt( m_ncomp, m_mat_blk, t, ndof, rdof,
-                   inpoel, solidx, coord, fd, geoFace, geoElem, Upwind::flux,
-                   Problem::prescribedVelocity, U, P, ndofel, dt, R, vriem,
-                   riemannLoc, riemannDeriv, intsharp );
-
-      if(ndof > 1)
-        // compute volume integrals
-        tk::volInt( m_ncomp, t, m_mat_blk, ndof, rdof,
-                    fd.Esuel().size()/4, inpoel, coord, geoElem, flux,
-                    Problem::prescribedVelocity, U, P, ndofel, R, intsharp );
-
-      // compute boundary surface flux integrals
-      for (const auto& b : m_bc)
-        tk::bndSurfInt( m_ncomp, m_mat_blk, ndof, rdof,
-          b.first, fd, geoFace, geoElem, inpoel, coord, t, Upwind::flux,
-          Problem::prescribedVelocity, b.second, U, P, ndofel, R, vriem,
-          riemannLoc, riemannDeriv, intsharp );
-    }
-
-    //! Evaluate the adaptive indicator and mark the ndof for each element
-    //! \param[in] nunk Number of unknowns
-    //! \param[in] coord Array of nodal coordinates
-    //! \param[in] inpoel Element-node connectivity
-    //! \param[in] fd Face connectivity and boundary conditions object
-    //! \param[in] unk Array of unknowns
-    //! \param[in] prim Array of primitive quantities
-    //! \param[in] indicator p-refinement indicator type
-    //! \param[in] ndof Number of degrees of freedom in the solution
-    //! \param[in] ndofmax Max number of degrees of freedom for p-refinement
-    //! \param[in] tolref Tolerance for p-refinement
-    //! \param[in,out] ndofel Vector of local number of degrees of freedome
-    void eval_ndof( std::size_t nunk,
-                    [[maybe_unused]] const tk::UnsMesh::Coords& coord,
-                    [[maybe_unused]] const std::vector< std::size_t >& inpoel,
-                    const inciter::FaceData& fd,
-                    const tk::Fields& unk,
-                    const tk::Fields& prim,
-                    inciter::ctr::PrefIndicatorType indicator,
-                    std::size_t ndof,
-                    std::size_t ndofmax,
-                    tk::real tolref,
-                    std::vector< std::size_t >& ndofel ) const
-    {
-      const auto& esuel = fd.Esuel();
-
-      if(indicator == inciter::ctr::PrefIndicatorType::SPECTRAL_DECAY)
-        spectral_decay( 1, nunk, esuel, unk, prim, ndof, ndofmax, tolref,
-          ndofel );
-      else
-        Throw( "No such adaptive indicator type" );
-    }
-
-    //! Compute the minimum time step size
-//     //! \param[in] U Solution vector at recent time step
-//     //! \param[in] coord Mesh node coordinates
-//     //! \param[in] inpoel Mesh element connectivity
-    //! \return Minimum time step size
-    tk::real dt( const std::array< std::vector< tk::real >, 3 >& /*coord*/,
-                 const std::vector< std::size_t >& /*inpoel*/,
-                 const inciter::FaceData& /*fd*/,
-                 const tk::Fields& /*geoFace*/,
-                 const tk::Fields& /*geoElem*/,
-                 const std::vector< std::size_t >& /*ndofel*/,
-                 const tk::Fields& /*U*/,
-                 const tk::Fields&,
-                 const std::size_t /*nielem*/ ) const
-    {
-      tk::real mindt = std::numeric_limits< tk::real >::max();
-      return mindt;
-    }
+  // Generate and communicate boundary edges
+  bndEdges();
+}
+
+void
+Refiner::bndEdges()
+// *****************************************************************************
+// Generate boundary edges and send them to all chares
+//! \details Extract edges on the boundary only. The boundary edges (shared by
+//!   multiple chares) will be agreed on a refinement that yields a conforming
+//!   mesh across chares boundaries.
+// *****************************************************************************
+{
+  // Compute the number of edges (chunksize) a chare will respond to when
+  // computing shared edges
+  auto N = static_cast< std::size_t >( m_nchare );
+  std::size_t chunksize = std::numeric_limits< std::size_t >::max() / N;<--- Variable 'chunksize' is assigned a value that is never used.
+
+  // Generate boundary edges of our mesh chunk
+  std::unordered_map< int, EdgeSet > chbedges;
+  auto esup = tk::genEsup( m_inpoel, 4 );         // elements surrounding points
+  auto esuel = tk::genEsuelTet( m_inpoel, esup ); // elems surrounding elements
+  for (std::size_t e=0; e<esuel.size()/4; ++e) {
+    auto mark = e*4;
+    for (std::size_t f=0; f<4; ++f) {
+      if (esuel[mark+f] == -1) {
+        auto A = m_ginpoel[ mark+tk::lpofa[f][0] ];
+        auto B = m_ginpoel[ mark+tk::lpofa[f][1] ];<--- Variable 'B' is assigned a value that is never used.
+        auto C = m_ginpoel[ mark+tk::lpofa[f][2] ];<--- Variable 'C' is assigned a value that is never used.
+        Assert( m_lid.find( A ) != end(m_lid), "Local node ID not found" );
+        Assert( m_lid.find( B ) != end(m_lid), "Local node ID not found" );
+        Assert( m_lid.find( C ) != end(m_lid), "Local node ID not found" );
+        // assign edges to bins a single chare will respond to when computing
+        // shared edges
+        auto bin = A / chunksize;
+        Assert( bin < N, "Will index out of number of chares" );
+        chbedges[ static_cast<int>(bin) ].insert( {A,B} );
+        bin = B / chunksize;
+        Assert( bin < N, "Will index out of number of chares" );
+        chbedges[ static_cast<int>(bin) ].insert( {B,C} );
+        bin = C / chunksize;
+        Assert( bin < N, "Will index out of number of chares" );
+        chbedges[ static_cast<int>(bin) ].insert( {C,A} );
+      }
+    }
+  }
+
+  // Send edges in bins to chares that will compute shared edges
+  m_nbnd = chbedges.size();
+  if (m_nbnd == 0)
+    contribute( sizeof(std::size_t), &m_meshid, CkReduction::nop,
+                m_cbr.get< tag::queried >() );
+  else
+    for (const auto& [ targetchare, bndedges ] : chbedges)
+      thisProxy[ targetchare ].query( thisIndex, bndedges );
+}
+
+void
+Refiner::query( int fromch, const EdgeSet& edges )
+// *****************************************************************************
+// Incoming query for a list boundary edges for which this chare compiles
+// shared edges
+//! \param[in] fromch Sender chare ID
+//! \param[in] edges Chare-boundary edge list from another chare
+// *****************************************************************************
+{
+  // Store incoming edges in edge->chare and its inverse, chare->edge, maps
+  for (const auto& e : edges) m_edgech[ e ].push_back( fromch );
+  m_chedge[ fromch ].insert( begin(edges), end(edges) );
+  // Report back to chare message received from
+  thisProxy[ fromch ].recvquery();
+}
+
+void
+Refiner::recvquery()
+// *****************************************************************************
+// Receive receipt of boundary edge lists to query
+// *****************************************************************************
+{
+  if (--m_nbnd == 0)
+    contribute( sizeof(std::size_t), &m_meshid, CkReduction::nop,
+                m_cbr.get< tag::queried >() );
+}
+
+void
+Refiner::response()
+// *****************************************************************************
+//  Respond to boundary edge list queries
+// *****************************************************************************
+{
+  std::unordered_map< int, std::vector< int > > exp;
+
+  // Compute shared edges whose chare ids will be sent back to querying chares
+  for (const auto& [ neighborchare, bndedges ] : m_chedge) {
+    auto& e = exp[ neighborchare ];
+    for (const auto& ed : bndedges)
+      for (auto d : tk::cref_find(m_edgech,ed))
+        if (d != neighborchare)
+          e.push_back( d );<--- Consider using std::copy_if algorithm instead of a raw loop.
+  }
+
+  // Send chare ids of shared edges to chares that issued a query to us. Shared
+  // boundary edges assigned to chare ids sharing the boundary edge were
+  // computed above for those chares that queried this map from us. These
+  // boundary edges form a distributed table and we only work on a chunk of it.
+  // Note that we only send data back to those chares that have queried us. The
+  // receiving sides do not know in advance if they receive messages or not.
+  // Completion is detected by having the receiver respond back and counting
+  // the responses on the sender side, i.e., this chare.
+  m_nbnd = exp.size();
+  if (m_nbnd == 0)
+    contribute( sizeof(std::size_t), &m_meshid, CkReduction::nop,
+                m_cbr.get< tag::responded >() );
+  else
+    for (const auto& [ targetchare, bndedges ] : exp)
+      thisProxy[ targetchare ].bnd( thisIndex, bndedges );
+}
+
+void
+Refiner::bnd( int fromch, const std::vector< int >& chares )
+// *****************************************************************************
+// Receive shared boundary edges for our mesh chunk
+//! \param[in] fromch Sender chare ID
+//! \param[in] chares Chare ids we share edges with
+// *****************************************************************************
+{
+  // Store chare ids we share edges with
+  m_ch.insert( begin(chares), end(chares) );
 
-    //! Compute stiff terms for a single element, not implemented here
-    // //! \param[in] e Element number
-    // //! \param[in] geoElem Element geometry array
-    // //! \param[in] inpoel Element-node connectivity
-    // //! \param[in] coord Array of nodal coordinates
-    // //! \param[in] U Solution vector at recent time step
-    // //! \param[in] P Primitive vector at recent time step
-    // //! \param[in] ndofel Vector of local number of degrees of freedom
-    // //! \param[in,out] R Right-hand side vector computed
-    void stiff_rhs( std::size_t /*e*/,
-                    const tk::Fields& /*geoElem*/,
-                    const std::vector< std::size_t >& /*inpoel*/,
-                    const tk::UnsMesh::Coords& /*coord*/,
-                    const tk::Fields& /*U*/,
-                    const tk::Fields& /*P*/,
-                    const std::vector< std::size_t >& /*ndofel*/,
-                    tk::Fields& /*R*/ ) const
-    {}
-
-    //! Return a map that associates user-specified strings to functions
-    //! \return Map that associates user-specified strings to functions that
-    //!  compute relevant quantities to be output to file
-    std::map< std::string, tk::GetVarFn > OutVarFn() const {
-      std::map< std::string, tk::GetVarFn > OutFnMap;
-      OutFnMap["material_indicator"] = transport::matIndicatorOutVar;
-
-      return OutFnMap;
-    }
-
-    //! Return analytic field names to be output to file
-    //! \return Vector of strings labelling analytic fields output in file
-    std::vector< std::string > analyticFieldNames() const {
-      std::vector< std::string > n;
-      auto depvar = g_inputdeck.get< tag::depvar >()[0];
-      for (ncomp_t c=0; c<m_ncomp; ++c)
-        n.push_back( depvar + std::to_string(c) + "_analytic" );
-      return n;
-    }
-
-    //! Return surface field output going to file
-    std::vector< std::vector< tk::real > >
-    surfOutput( const std::map< int, std::vector< std::size_t > >&,
-                tk::Fields& ) const
-    {
-      std::vector< std::vector< tk::real > > s; // punt for now
-      return s;
-    }
-
-    //! Return time history field names to be output to file
-    //! \return Vector of strings labelling time history fields output in file
-    std::vector< std::string > histNames() const {
-      std::vector< std::string > s; // punt for now
-      return s;
-    }
-
-    //! Return names of integral variables to be output to diagnostics file
-    //! \return Vector of strings labelling integral variables output
-    std::vector< std::string > names() const {
-      std::vector< std::string > n;
-      const auto& depvar =
-      g_inputdeck.get< tag::depvar >().at(0);
-      // construct the name of the numerical solution for all components
-      for (ncomp_t c=0; c<m_ncomp; ++c)
-        n.push_back( depvar + std::to_string(c) );
-      return n;
-    }
-
-    //! Return analytic solution (if defined by Problem) at xi, yi, zi, t
-    //! \param[in] xi X-coordinate at which to evaluate the analytic solution
-    //! \param[in] yi Y-coordinate at which to evaluate the analytic solution
-    //! \param[in] zi Z-coordinate at which to evaluate the analytic solution
-    //! \param[in] t Physical time at which to evaluate the analytic solution
-    //! \return Vector of analytic solution at given spatial location and time
-    std::vector< tk::real >
-    analyticSolution( tk::real xi, tk::real yi, tk::real zi, tk::real t ) const
-    { return Problem::analyticSolution( m_ncomp, m_mat_blk, xi, yi,
-                                        zi, t ); }
+  // Report back to chare message received from
+  thisProxy[ fromch ].recvbnd();
+}
+
+void
+Refiner::recvbnd()
+// *****************************************************************************
+// Receive receipt of shared boundary edges
+// *****************************************************************************
+{
+  if (--m_nbnd == 0)
+    contribute( sizeof(std::size_t), &m_meshid, CkReduction::nop,
+                m_cbr.get< tag::responded >() );
+}
+
+void
+Refiner::refine()
+// *****************************************************************************
+//  Do a single step of mesh refinement (really, only tag edges)
+//! \details During initial (t<0, t0ref) mesh refinement, this is a single step
+//!   in a potentially multiple-entry list of initial adaptive mesh refinement
+//!   steps. Distribution of the chare-boundary edges must have preceded this
+//!   step, so that boundary edges (shared by multiple chares) can agree on a
+//!   refinement that yields a conforming mesh across chare boundaries.
+//!
+//!   During-timestepping (t>0, dtref) mesh refinement this is called once, as
+//!   we only do a single step during time stepping.
+//!
+//!   During field-output (outref) mesh refinement, this may be called multiple
+//!   times, depending the number of refinement levels needed for the field
+//!   output.
+// *****************************************************************************
+{
+  // Free memory used for computing shared boundary edges
+  tk::destroy( m_edgech );
+  tk::destroy( m_chedge );
+
+  // Perform leak test on old mesh
+  Assert( !tk::leakyPartition(
+            tk::genEsuelTet( m_inpoel, tk::genEsup(m_inpoel,4) ),
+            m_inpoel, m_coord ),
+          "Mesh partition before refinement leaky" );
+
+  if (m_mode == RefMode::T0REF) {
+
+    // Refine mesh based on next initial refinement type
+    if (!m_initref.empty()) {
+      auto r = m_initref.back();    // consume (reversed) list from its back
+      if (r == ctr::AMRInitialType::UNIFORM)
+        uniformRefine();
+      else if (r == ctr::AMRInitialType::UNIFORM_DEREFINE)
+        uniformDeRefine();
+      else if (r == ctr::AMRInitialType::INITIAL_CONDITIONS)
+        errorRefine();
+      else if (r == ctr::AMRInitialType::COORDINATES)
+        coordRefine();
+      else if (r == ctr::AMRInitialType::EDGELIST)
+        edgelistRefine();
+      else Throw( "Initial AMR type not implemented" );
+    }
+
+  } else if (m_mode == RefMode::DTREF) {
+
+    if (g_inputdeck.get< tag::amr, tag::dtref_uniform >())
+      uniformRefine();
+    else
+      errorRefine();
+
+  } else if (m_mode == RefMode::OUTREF) {
+
+    uniformRefine();
+
+  } else if (m_mode == RefMode::OUTDEREF) {
+
+    uniformDeRefine();
+
+  } else Throw( "RefMode not implemented" );
 
-    //! Return analytic solution for conserved variables
-    //! \param[in] xi X-coordinate at which to evaluate the analytic solution
-    //! \param[in] yi Y-coordinate at which to evaluate the analytic solution
-    //! \param[in] zi Z-coordinate at which to evaluate the analytic solution
-    //! \param[in] t Physical time at which to evaluate the analytic solution
-    //! \return Vector of analytic solution at given location and time
-    std::vector< tk::real >
-    solution( tk::real xi, tk::real yi, tk::real zi, tk::real t ) const
-    { return Problem::initialize( m_ncomp, m_mat_blk, xi, yi, zi, t ); }
-
-    //! Return time history field output evaluated at time history points
-    //! \param[in] h History point data
-    std::vector< std::vector< tk::real > >
-    histOutput( const std::vector< HistData >& h,
-                const std::vector< std::size_t >&,
-                const tk::UnsMesh::Coords&,
-                const tk::Fields&,
-                const tk::Fields& ) const
-    {
-      std::vector< std::vector< tk::real > > Up(h.size()); //punt for now
-      return Up;
-    }
-
-    //! Return cell-averaged total component mass per unit volume for an element
-    //! \param[in] e Element id for which total energy is required
-    //! \param[in] unk Vector of conserved quantities
-    //! \return Cell-averaged total component mass per unit volume for given
-    //!   element. Since transport does not have an associated total energy,
-    //!   return total mass.
-    tk::real sp_totalenergy(std::size_t e, const tk::Fields& unk) const
-    {
-      const auto rdof = g_inputdeck.get< tag::rdof >();
-
-      tk::real sp_m(0.0);
-      for (std::size_t c=0; c<m_ncomp; ++c) {
-        sp_m += unk(e,c*rdof);
-      }
-      return sp_m;
-    }
-
-  private:
-    const Physics m_physics;            //!< Physics policy
-    const Problem m_problem;            //!< Problem policy
-    const ncomp_t m_ncomp;              //!< Number of components in this PDE
-    //! BC configuration
-    BCStateFn m_bc;
-    //! \brief EOS material block - This PDE does not require an EOS block,
-    //! thus this variable has not been intialized.
-    std::vector< EOS > m_mat_blk;
-
-    //! Evaluate physical flux function for this PDE system
-    //! \param[in] ncomp Number of scalar components in this PDE system
-    //! \param[in] ugp Numerical solution at the Gauss point at which to
-    //!   evaluate the flux
-    //! \param[in] v Prescribed velocity evaluated at the Gauss point at which
-    //!   to evaluate the flux
-    //! \return Flux vectors for all components in this PDE system
-    //! \note The function signature must follow tk::FluxFn
-    static tk::FluxFn::result_type
-    flux( ncomp_t ncomp,
-          const std::vector< EOS >&,
-          const std::vector< tk::real >& ugp,
-          const std::vector< std::array< tk::real, 3 > >& v )
-
-    {
-      Assert( ugp.size() == ncomp, "Size mismatch" );
-      Assert( v.size() == ncomp, "Size mismatch" );
-
-      std::vector< std::array< tk::real, 3 > > fl( ugp.size() );
-
-      for (ncomp_t c=0; c<ncomp; ++c)
-        fl[c] = {{ v[c][0] * ugp[c], v[c][1] * ugp[c], v[c][2] * ugp[c] }};
+  // Communicate extra edges
+  comExtra();
+}
+
+void
+Refiner::comExtra()
+// *****************************************************************************
+// Communicate extra edges along chare boundaries
+// *****************************************************************************
+{
+  // Export extra added nodes on our mesh chunk boundary to other chares
+  if (m_ch.empty()) {
+    correctref();
+  } else {
+    for (auto c : m_ch) {  // for all chares we share at least an edge with
+      thisProxy[c].addRefBndEdges(thisIndex, m_localEdgeData, m_intermediates);
+    }
+  }
+}
+
+void
+Refiner::addRefBndEdges(
+  int fromch,
+  const AMR::EdgeData& ed,
+  const std::unordered_set< std::size_t >& intermediates )
+// *****************************************************************************
+//! Receive edges on our chare boundary from other chares
+//! \param[in] fromch Chare call coming from
+//! \param[in] ed Edges on chare boundary
+//! \param[in] intermediates Intermediate nodes
+//! \details Other than update remoteEdge data, this function also updates
+//!   locking information for such edges whos nodes are marked as intermediate
+//!   by neighboring chares.
+// *****************************************************************************
+{
+  // Save/augment buffers of edge data for each sender chare
+  auto& red = m_remoteEdgeData[ fromch ];
+  auto& re = m_remoteEdges[ fromch ];
+  using edge_data_t = std::tuple< Edge, int, int, AMR::Edge_Lock_Case >;
+  for (const auto& [ edge, data ] : ed) {
+    red.push_back( edge_data_t{ edge, std::get<0>(data), std::get<1>(data),
+      std::get<2>(data) } );
+    re.push_back( edge );
+  }
+
+  // Add intermediates to mesh refiner lib
+  // needs to be done only when mesh has been actually updated, i.e. first iter
+  if (m_ncit == 0) {
+    auto esup = tk::genEsup( m_inpoel, 4 );
+    auto psup = tk::genPsup( m_inpoel, 4, esup );
+    for (const auto g : intermediates) {
+      auto l = m_lid.find( g ); // convert to local node ids
+      if (l != end(m_lid)) {
+        // lock all edges connected to intermediate node
+        auto p = l->second;
+        for (auto q : tk::Around(psup,p)) {
+          AMR::edge_t e(m_rid[p], m_rid[q]);
+          auto& refedge = m_refiner.tet_store.edge_store.get(e);
+          if (refedge.lock_case == AMR::Edge_Lock_Case::unlocked) {
+            refedge.lock_case = AMR::Edge_Lock_Case::temporary; //intermediate;
+            refedge.needs_refining = 0;
+          }
+        }
+      }
+    }
+  }
+
+  // Heard from every worker we share at least a single edge with
+  if (++m_nref == m_ch.size()) {
+    m_nref = 0;
+
+    updateBndEdgeData();
 
-      return fl;
-    }
-
-    //! \brief Boundary state function providing the left and right state of a
-    //!   face at extrapolation boundaries
-    //! \param[in] ul Left (domain-internal) state
-    //! \return Left and right states for all scalar components in this PDE
-    //!   system
-    //! \note The function signature must follow tk::StateFn
-    static tk::StateFn::result_type
-    extrapolate( ncomp_t, const std::vector< EOS >&,
-                 const std::vector< tk::real >& ul, tk::real, tk::real,
-                 tk::real, tk::real, const std::array< tk::real, 3 >& )
-    {
-      return {{ ul, ul }};
-    }
+    std::vector< std::size_t > meshdata{ m_meshid };
+    contribute( meshdata, CkReduction::max_ulong,
+                m_cbr.get< tag::compatibility >() );
+  }
+}
+
+void
+Refiner::correctref()
+// *****************************************************************************
+//  Correct extra edges to arrive at conforming mesh across chare boundaries
+//! \details This function is called repeatedly until there is not a a single
+//!    edge that needs correction for the whole distributed problem to arrive at
+//!    a conforming mesh across chare boundaries during a mesh refinement step.
+// *****************************************************************************
+{
+  auto unlocked = AMR::Edge_Lock_Case::unlocked;
 
-    //! \brief Boundary state function providing the left and right state of a
-    //!   face at extrapolation boundaries
-    //! \param[in] ul Left (domain-internal) state
-    //! \return Left and right states for all scalar components in this PDE
-    //!   system
-    //! \note The function signature must follow tk::StateFn
-    static tk::StateFn::result_type
-    inlet( ncomp_t, const std::vector< EOS >&,
-           const std::vector< tk::real >& ul, tk::real, tk::real, tk::real,
-           tk::real, const std::array< tk::real, 3 >& )
-    {
-      auto ur = ul;
-      std::fill( begin(ur), end(ur), 0.0 );
-      return {{ ul, std::move(ur) }};
-    }
-
-    //! \brief Boundary state function providing the left and right state of a
-    //!   face at outlet boundaries
-    //! \param[in] ul Left (domain-internal) state
-    //! \return Left and right states for all scalar components in this PDE
-    //!   system
-    //! \note The function signature must follow tk::StateFn
-    static tk::StateFn::result_type
-    outlet( ncomp_t, const std::vector< EOS >&,
-            const std::vector< tk::real >& ul, tk::real, tk::real, tk::real,
-            tk::real, const std::array< tk::real, 3 >& )
-    {
-      return {{ ul, ul }};
-    }
-
-    //! \brief Boundary state function providing the left and right state of a
-    //!   face at Dirichlet boundaries
-    //! \param[in] ncomp Number of scalar components in this PDE system
-    //! \param[in] ul Left (domain-internal) state
-    //! \param[in] x X-coordinate at which to compute the states
-    //! \param[in] y Y-coordinate at which to compute the states
-    //! \param[in] z Z-coordinate at which to compute the states
-    //! \param[in] t Physical time
-    //! \return Left and right states for all scalar components in this PDE
-    //!   system
-    //! \note The function signature must follow tk::StateFn
-    static tk::StateFn::result_type
-    dirichlet( ncomp_t ncomp, 
-               const std::vector< EOS >& mat_blk,
-               const std::vector< tk::real >& ul, tk::real x, tk::real y,
-               tk::real z, tk::real t, const std::array< tk::real, 3 >& )
-    {
-      return {{ ul, Problem::initialize( ncomp, mat_blk, x, y, z, t ) }};
-    }
-};
-
-} // dg::
-} // inciter::
-
-#endif // DGTransport_h
+  // Storage for edge data that need correction to yield a conforming mesh
+  AMR::EdgeData extra;
+  std::size_t neigh_extra(0);
+
+  // Vars for debugging purposes
+  std::size_t nlocked(0);<--- Variable 'nlocked' is assigned a value that is never used.
+  std::array< std::size_t, 4 > ncorrcase{{0,0,0,0}};
+
+  // loop through all edges shared with other chares
+  for (const auto& [ neighborchare, edgedata ] : m_remoteEdgeData) {
+    for (const auto& [edge,remote_needs_refining,remote_needs_derefining,
+      remote_lock_case] : edgedata) {
+      // find local data of remote edge
+      auto it = m_localEdgeData.find( edge );
+      if (it != end(m_localEdgeData)) {
+        auto& local = it->second;
+        auto& local_needs_refining = std::get<0>(local);
+        auto& local_needs_derefining = std::get<1>(local);
+        auto& local_lock_case = std::get<2>(local);
+
+        auto local_needs_refining_orig = local_needs_refining;<--- Variable 'local_needs_refining_orig' is assigned a value that is never used.
+        auto local_needs_derefining_orig = local_needs_derefining;<--- Variable 'local_needs_derefining_orig' is assigned a value that is never used.
+        auto local_lock_case_orig = local_lock_case;<--- Variable 'local_lock_case_orig' is assigned a value that is never used.
+
+        Assert( !(local_lock_case > unlocked && local_needs_refining),
+                "Invalid local edge: locked & needs refining" );
+        Assert( !(remote_lock_case > unlocked && remote_needs_refining),
+                "Invalid remote edge: locked & needs refining" );
+        Assert( !(local_needs_derefining == 1 && local_needs_refining > 0),
+                "Invalid local edge: needs refining and derefining" );
+
+        // The parallel compatibility (par-compat) algorithm
+
+        // compute lock from local and remote locks as most restrictive
+        local_lock_case = std::max( local_lock_case, remote_lock_case );
+
+        if (local_lock_case > unlocked) {
+          local_needs_refining = 0;
+          if (local_needs_refining != local_needs_refining_orig ||
+            local_lock_case != local_lock_case_orig)
+            ++ncorrcase[0];
+        }
+
+        // Possible combinations of remote-local ref-deref decisions
+        // rows 1, 5, 9: no action needed.
+        // rows 4, 7, 8: no action on local-side; comm needed.
+        //
+        //    LOCAL          |        REMOTE    |  Result
+        // 1  d              |        d         |  d
+        // 2  d              |        -         |  -
+        // 3  d              |        r         |  r
+        // 4  -              |        d         |  -
+        // 5  -              |        -         |  -
+        // 6  -              |        r         |  r
+        // 7  r              |        d         |  r
+        // 8  r              |        -         |  r
+        // 9  r              |        r         |  r
+
+        // Rows 3, 6
+        // If remote wants to refine
+        if (remote_needs_refining == 1) {
+          if (local_lock_case == unlocked) {
+            local_needs_refining = 1;
+            local_needs_derefining = false;
+            if (local_needs_refining != local_needs_refining_orig ||
+              local_needs_derefining != local_needs_derefining_orig)
+              ++ncorrcase[1];
+          }
+          else {
+           ++nlocked;
+          }
+        }
+
+        // Row 2
+        // If remote neither wants to refine nor derefine
+        if (remote_needs_refining == 0 && remote_needs_derefining == false) {
+          local_needs_derefining = false;
+          if (local_needs_derefining != local_needs_derefining_orig)
+            ++ncorrcase[2];
+        }
+
+        // Row 1: special case
+        // If remote wants to deref-ref (either of 8:4, 8:2, 4:2)
+        // and local does not want to refine (neither pure ref nor deref-ref)
+        if (remote_needs_refining == 2 && local_needs_refining == 0) {
+          if (local_lock_case == unlocked) {
+            local_needs_refining = 1;
+            local_needs_derefining = false;
+            if (local_needs_refining != local_needs_refining_orig ||
+              local_needs_derefining != local_needs_derefining_orig)
+              ++ncorrcase[3];
+          }
+          else {
+            ++nlocked;<--- Variable 'nlocked' is assigned a value that is never used.
+          }
+        }
+
+        // Rows 4, 7, 8
+
+        // if the remote sent us data that makes us change our local state,
+        // e.g., local{-,0} + remote{r,0} -> local{r,0}, i.e., I changed my
+        // state I need to tell the world about it
+        if (local_lock_case != local_lock_case_orig ||
+            local_needs_refining != local_needs_refining_orig ||
+            local_needs_derefining != local_needs_derefining_orig)
+        {
+          auto l1 = tk::cref_find( m_lid, edge[0] );
+          auto l2 = tk::cref_find( m_lid, edge[1] );
+          Assert( l1 != l2, "Edge end-points local ids are the same" );
+          auto r1 = m_rid[ l1 ];
+          auto r2 = m_rid[ l2 ];
+          Assert( r1 != r2, "Edge end-points refiner ids are the same" );
+          //std::cout << thisIndex << ": " << r1 << ", " << r2 << std::endl;
+          //if (m_refiner.tet_store.edge_store.get(AMR::edge_t(r1,r2)).lock_case > local_lock_case) {
+          //  std::cout << thisIndex << ": edge " << r1 << "-" << r2 <<
+          //    "; prev=" << local_lock_case_orig <<
+          //    "; new=" << local_lock_case <<
+          //    "; amr-lib=" << m_refiner.tet_store.edge_store.get(AMR::edge_t(r1,r2)).lock_case <<
+          //    " | parcompatiter " << m_ncit << std::endl;
+          //}
+           extra[ {{ std::min(r1,r2), std::max(r1,r2) }} ] =
+             { local_needs_refining, local_needs_derefining, local_lock_case };
+        }
+        // or if the remote data is inconsistent with what I think, e.g.,
+        // local{r,0} + remote{-,0} -> local{r,0}, i.e., the remote does not
+        // yet agree, so another par-compat iteration will be pursued. but
+        // I do not have to locally run ref-compat.
+        else if (local_lock_case != remote_lock_case ||
+          local_needs_refining != remote_needs_refining ||
+          local_needs_derefining != remote_needs_derefining)
+        {
+          ++neigh_extra;
+        }
+      }
+    }
+  }
+
+  m_remoteEdgeData.clear();
+  m_extra = extra.size();
+  //std::cout << thisIndex << ": amr correction reqd for nedge: " << m_extra << std::endl;
+  //std::cout << thisIndex << ": amr correction reqd for neighbor edges: " << neigh_extra << std::endl;
+  //std::cout << thisIndex << ": edge counts by correction case: " << ncorrcase[0]
+  //  << ", " << ncorrcase[1] << ", " << ncorrcase[2] << ", " << ncorrcase[3] << std::endl;
+  //std::cout << thisIndex << ": locked edges that req corr: " << nlocked << std::endl;
+
+  if (!extra.empty()) {
+    //std::cout << thisIndex << ": redoing markings" << std::endl;
+    // Do refinement compatibility (ref-compat) for edges that need correction
+    m_refiner.mark_error_refinement_corr( extra );
+    ++m_ncit;
+    // Update our extra-edge store based on refiner
+    updateEdgeData();
+    m_remoteEdges.clear();
+  }
+  else if (neigh_extra == 0) {
+    m_ncit = 0;
+  }
+
+  // Aggregate number of extra edges that still need correction and some
+  // refinement/derefinement statistics
+  const auto& tet_store = m_refiner.tet_store;
+  std::vector< std::size_t >
+    m{ m_meshid,
+       m_extra,
+       tet_store.marked_refinements.size(),
+       tet_store.marked_derefinements.size(),
+       static_cast< std::underlying_type_t< RefMode > >( m_mode ) };
+  contribute( m, CkReduction::sum_ulong, m_cbr.get< tag::matched >() );
+}
+
+void
+Refiner::updateEdgeData()
+// *****************************************************************************
+// Query AMR lib and update our local store of edge data
+// *****************************************************************************
+{
+  m_localEdgeData.clear();
+  m_intermediates.clear();
+
+  // This currently takes ALL edges from the AMR lib, i.e., on the whole
+  // domain. We should eventually only collect edges here that are shared with
+  // other chares.
+  const auto& ref_edges = m_refiner.tet_store.edge_store.edges;
+  const auto& refinpoel = m_refiner.tet_store.get_active_inpoel();
+
+  for (std::size_t e=0; e<refinpoel.size()/4; ++e) {
+    auto A = refinpoel[e*4+0];
+    auto B = refinpoel[e*4+1];
+    auto C = refinpoel[e*4+2];
+    auto D = refinpoel[e*4+3];
+    std::array<Edge,6> edges{{ {{A,B}}, {{B,C}}, {{A,C}},
+                               {{A,D}}, {{B,D}}, {{C,D}} }};
+    for (const auto& ed : edges) {
+      auto ae = AMR::edge_t{{{ std::min(ed[0],ed[1]), std::max(ed[0],ed[1]) }}};
+      auto r = tk::cref_find( ref_edges, ae );
+      const auto ged = Edge{{ m_gid[ tk::cref_find( m_lref, ed[0] ) ],
+                              m_gid[ tk::cref_find( m_lref, ed[1] ) ] }};
+      m_localEdgeData[ ged ] = { r.needs_refining, r.needs_derefining,
+        r.lock_case };
+    }
+  }
+
+  // Build intermediates to send. This currently takes ALL intermediates from
+  // the AMR lib, i.e., on the whole domain. We should eventually only collect
+  // edges here that are shared with other chares.
+  for (const auto& r : m_refiner.tet_store.intermediate_list) {
+    m_intermediates.insert( m_gid[ tk::cref_find( m_lref, r ) ] );
+  }
+}
+
+void
+Refiner::updateBndEdgeData()
+// *****************************************************************************
+// Query AMR lib and update our local store of boundary edge data
+// *****************************************************************************
+{
+  // This currently takes ALL edges from the AMR lib, i.e., on the whole
+  // domain. We should eventually only collect edges here that are shared with
+  // other chares.
+  const auto& ref_edges = m_refiner.tet_store.edge_store.edges;
+  const auto& refinpoel = m_refiner.tet_store.get_active_inpoel();
+
+  for (std::size_t e=0; e<refinpoel.size()/4; ++e) {
+    auto A = refinpoel[e*4+0];
+    auto B = refinpoel[e*4+1];
+    auto C = refinpoel[e*4+2];
+    auto D = refinpoel[e*4+3];
+    std::array<Edge,6> edges{{ {{A,B}}, {{B,C}}, {{A,C}},
+                               {{A,D}}, {{B,D}}, {{C,D}} }};
+    for (const auto& ed : edges) {
+      auto ae = AMR::edge_t{{{ std::min(ed[0],ed[1]), std::max(ed[0],ed[1]) }}};
+      auto r = tk::cref_find( ref_edges, ae );
+      const auto ged = Edge{{ m_gid[ tk::cref_find( m_lref, ed[0] ) ],
+                              m_gid[ tk::cref_find( m_lref, ed[1] ) ] }};
+      // only update edges that are on chare boundary OR unlocked
+      if (m_localEdgeData.find(ged) == m_localEdgeData.end() ||
+        std::get<2>(m_localEdgeData[ged]) == AMR::Edge_Lock_Case::unlocked) {
+        m_localEdgeData[ ged ] = { r.needs_refining, r.needs_derefining,
+          r.lock_case };
+      }
+    }
+  }
+}
+
+std::tuple< std::vector< std::string >,
+            std::vector< std::vector< tk::real > >,
+            std::vector< std::string >,
+            std::vector< std::vector< tk::real > > >
+Refiner::refinementFields() const
+// *****************************************************************************
+//  Collect mesh output fields from refiner lib
+//! \return Names and fields of mesh refinement data in mesh cells and nodes
+// *****************************************************************************
+{
+  // Find number of nodes in current mesh
+  auto npoin = tk::npoin_in_graph( m_inpoel );
+  // Generate edges surrounding points in current mesh
+  auto esup = tk::genEsup( m_inpoel, 4 );
+
+  // Update solution on current mesh
+  const auto& u = solution( npoin, esup );
+  Assert( u.nunk() == npoin, "Solution uninitialized or wrong size" );
+
+  // Compute error in edges on current mesh
+  auto edgeError = errorsInEdges( npoin, esup, u );
+
+  // Transfer error from edges to cells for field output
+  std::vector< tk::real > error( m_inpoel.size()/4, 0.0 );
+  for (std::size_t e=0; e<m_inpoel.size()/4; ++e) {
+    auto A = m_inpoel[e*4+0];
+    auto B = m_inpoel[e*4+1];
+    auto C = m_inpoel[e*4+2];
+    auto D = m_inpoel[e*4+3];
+    std::array<Edge,6> edges{{ {{A,B}}, {{B,C}}, {{A,C}},
+                               {{A,D}}, {{B,D}}, {{C,D}} }};
+    // sum error from edges to elements
+    for (const auto& ed : edges) error[e] += tk::cref_find( edgeError, ed );
+    error[e] /= 6.0;    // assign edge-average error to element
+  }
+
+  // Prepare element fields with mesh refinement data
+  std::vector< std::string >
+    elemfieldnames{ "refinement level", "cell type", "error" };
+  auto& tet_store = m_refiner.tet_store;
+  std::vector< std::vector< tk::real > > elemfields{
+    tet_store.get_refinement_level_list(),
+    tet_store.get_cell_type_list(),
+    error };
+
+  using tuple_t = std::tuple< std::vector< std::string >,
+                              std::vector< std::vector< tk::real > >,
+                              std::vector< std::string >,
+                              std::vector< std::vector< tk::real > > >;
+  return tuple_t{ elemfieldnames, elemfields, {}, {} };
+}
+
+void
+Refiner::writeMesh( const std::string& basefilename,
+                    uint64_t itr,
+                    tk::real t,
+                    CkCallback c ) const
+// *****************************************************************************
+//  Output mesh to file(s)
+//! \param[in] basefilename File name to append to
+//! \param[in] itr Iteration count since a new mesh
+//! \param[in] t "Physical time" to write to file. "Time" here is used to
+//!   designate a new time step at which the mesh is saved.
+//! \param[in] c Function to continue with after the write
+// *****************************************************************************
+{
+  auto r = refinementFields();
+  auto& elemfieldnames = std::get< 0 >( r );
+  auto& elemfields = std::get< 1 >( r );
+  auto& nodefieldnames = std::get< 2 >( r );
+  auto& nodefields = std::get< 3 >( r );
+
+  // Prepare solution field names: depvar + component id for all eqs
+  auto nprop = g_inputdeck.get< tag::ncomp >();
+  std::vector< std::string > solfieldnames;
+  for (std::size_t i=0; i<nprop; ++i) {
+    solfieldnames.push_back(
+      g_inputdeck.get< tag::depvar >()[0] + std::to_string(i+1) );
+  }
+  Assert( solfieldnames.size() == nprop, "Size mismatch" );
+
+  const auto scheme = g_inputdeck.get< tag::scheme >();
+  const auto centering = ctr::Scheme().centering( scheme );
+  auto t0 = g_inputdeck.get< tag::t0 >();
+
+  // list of nodes/elements at which box ICs are defined
+  std::vector< std::unordered_set< std::size_t > > inbox;
+  tk::real V = 1.0;
+  std::vector< tk::real > blkvols;
+  std::unordered_map< std::size_t, std::set< std::size_t > > nodeblockid,
+    elemblockid;
+
+  // Prepare node or element fields for output to file
+  if (centering == tk::Centering::NODE) {
+
+    // Augment element field names with solution variable names + field ids
+    nodefieldnames.insert( end(nodefieldnames),
+                           begin(solfieldnames), end(solfieldnames) );
+
+    // Evaluate initial conditions on current mesh at t0
+    tk::Fields u( m_coord[0].size(), nprop );
+    g_cgpde[m_meshid].initialize( m_coord, u, t0, V, inbox, blkvols,
+      nodeblockid );
+
+    // Extract all scalar components from solution for output to file
+    for (std::size_t i=0; i<nprop; ++i)
+      nodefields.push_back( u.extract_comp( i ) );
+
+  } else if (centering == tk::Centering::ELEM) {
+
+    // Augment element field names with solution variable names + field ids
+    elemfieldnames.insert( end(elemfieldnames),
+                           begin(solfieldnames), end(solfieldnames) );
+
+    auto ndof = g_inputdeck.get< tag::ndof >();
+    tk::Fields lhs( m_inpoel.size()/4, ndof*nprop );
+
+    // Generate left hand side for DG and evaluate initial conditions on
+    // current mesh at t0
+    auto geoElem = tk::genGeoElemTet( m_inpoel, m_coord );
+    auto u = lhs;
+    if (scheme == ctr::SchemeType::FV) {
+      g_fvpde[m_meshid].lhs( geoElem, lhs );
+      g_fvpde[m_meshid].initialize( lhs, m_inpoel, m_coord, inbox, elemblockid,
+        u, t0, m_inpoel.size()/4 );
+    }
+    else {
+      g_dgpde[m_meshid].lhs( geoElem, lhs );
+      g_dgpde[m_meshid].initialize( lhs, m_inpoel, m_coord, inbox, elemblockid,
+        u, t0, m_inpoel.size()/4 );
+    }
+
+    // Extract all scalar components from solution for output to file
+    for (std::size_t i=0; i<nprop; ++i)
+      elemfields.push_back( u.extract_comp( i ) );
+  }
+
+  // Output mesh
+  m_meshwriter[ CkNodeFirst( CkMyNode() ) ].
+    write( m_meshid, /*meshoutput = */ true, /*fieldoutput = */ true, itr, 1, t,
+           thisIndex, basefilename, m_inpoel, m_coord, m_bface,
+           tk::remap(m_bnode,m_lid), tk::remap(m_triinpoel,m_lid),
+           elemfieldnames, nodefieldnames, {}, {}, elemfields, nodefields, {},
+           {}, {}, c );
+}
+
+void
+Refiner::perform()
+// *****************************************************************************
+// Perform mesh refinement and decide how to continue
+//! \details First the mesh refiner object is called to perform a single step
+//!   of mesh refinement. Then, if this function is called during a step
+//!   (potentially multiple levels of) initial AMR, it evaluates whether to do
+//!   another one. If it is called during time stepping, this concludes the
+//!   single mesh refinement step and the new mesh is sent to the PDE worker
+//!   (Discretization).
+// *****************************************************************************
+{
+  // Save old tets and their ids before performing refinement. Outref is always
+  // followed by outderef, so to the outside world, the mesh is uchanged, thus
+  // no update.
+  if (m_mode != RefMode::OUTREF && m_mode != RefMode::OUTDEREF) {
+    m_oldTets.clear();
+    for (const auto& [ id, tet ] : m_refiner.tet_store.tets) {
+      m_oldTets.insert( tet );
+    }
+    m_oldntets = m_oldTets.size();
+  }
+
+  if (m_mode == RefMode::T0REF) {
+
+    // Refine mesh based on next initial refinement type
+    if (!m_initref.empty()) {
+      auto r = m_initref.back();    // consume (reversed) list from its back
+      if (r == ctr::AMRInitialType::UNIFORM_DEREFINE)
+        m_refiner.perform_derefinement();
+      else
+        m_refiner.perform_refinement();
+    }
+
+  } else {
+
+    // TODO: does not work yet, fix as above
+    m_refiner.perform_refinement();
+    m_refiner.perform_derefinement();
+  }
+
+  // Remove temporary edge-locks resulting from the parallel compatibility
+  m_refiner.remove_edge_locks(1);
+  m_refiner.remove_edge_temp_locks();
+
+  //auto& tet_store = m_refiner.tet_store;
+  //std::cout << "before ref: " << tet_store.marked_refinements.size() << ", " << tet_store.marked_derefinements.size() << ", " << tet_store.size() << ", " << tet_store.get_active_inpoel().size() << '\n';
+  //std::cout << "after ref: " << tet_store.marked_refinements.size() << ", " << tet_store.marked_derefinements.size() << ", " << tet_store.size() << ", " << tet_store.get_active_inpoel().size() << '\n';
+  //std::cout << "after deref: " << tet_store.marked_refinements.size() << ", " << tet_store.marked_derefinements.size() << ", " << tet_store.size() << ", " << tet_store.get_active_inpoel().size() << '\n';
+
+  // Update volume and boundary mesh
+  updateMesh();
+
+  // Save mesh at every initial refinement step (mainly for debugging). Will
+  // replace with just a 'next()' in production.
+  if (m_mode == RefMode::T0REF) {
+
+    auto l = m_ninitref - m_initref.size() + 1;  // num initref steps completed
+    auto t0 = g_inputdeck.get< tag::t0 >();
+    // Generate times equally subdividing t0-1...t0 to ninitref steps
+    auto t =
+      t0 - 1.0 + static_cast<tk::real>(l)/static_cast<tk::real>(m_ninitref);
+    auto itr = l;
+    // Output mesh after refinement step
+    writeMesh( "t0ref", itr, t,
+               CkCallback( CkIndex_Refiner::next(), thisProxy[thisIndex] ) );
+
+  } else {
+
+    next();
+
+  }
+}
+
+void
+Refiner::next()
+// *****************************************************************************
+// Continue after finishing a refinement step
+// *****************************************************************************
+{
+  if (m_mode == RefMode::T0REF) {
+
+    // Remove initial mesh refinement step from list
+    if (!m_initref.empty()) m_initref.pop_back();
+    // Continue to next initial AMR step or finish
+    if (!m_initref.empty()) t0ref(); else endt0ref();
+
+  } else if (m_mode == RefMode::DTREF) {
+
+    // Send new mesh, solution, and communication data back to PDE worker
+    m_scheme[m_meshid].ckLocal< Scheme::resizePostAMR >( thisIndex,  m_ginpoel,
+      m_el, m_coord, m_addedNodes, m_addedTets, m_removedNodes, m_amrNodeMap,
+      m_nodeCommMap, m_bface, m_bnode, m_triinpoel, m_elemblockid );
+
+  } else if (m_mode == RefMode::OUTREF) {
+
+    // Store field output mesh
+    m_outref_ginpoel = m_ginpoel;
+    m_outref_el = m_el;
+    m_outref_coord = m_coord;
+    m_outref_addedNodes = m_addedNodes;
+    m_outref_addedTets = m_addedTets;
+    m_outref_nodeCommMap = m_nodeCommMap;
+    m_outref_bface = m_bface;
+    m_outref_bnode = m_bnode;
+    m_outref_triinpoel = m_triinpoel;
+
+    // Derefine mesh to the state previous to field output
+    outref( m_outref_bface, m_outref_bnode, m_outref_triinpoel, m_writeCallback,
+            RefMode::OUTDEREF );
+
+  } else if (m_mode == RefMode::OUTDEREF) {
+
+    // Send field output mesh to PDE worker
+    m_scheme[m_meshid].ckLocal< Scheme::extractFieldOutput >( thisIndex,
+      m_outref_ginpoel, m_outref_el, m_outref_coord, m_outref_addedNodes,
+      m_outref_addedTets, m_outref_nodeCommMap, m_outref_bface, m_outref_bnode,
+      m_outref_triinpoel, m_writeCallback );
+
+  } else Throw( "RefMode not implemented" );
+}
+
+void
+Refiner::endt0ref()
+// *****************************************************************************
+// Finish initial mesh refinement
+//! \details This function is called as after initial mesh refinement has
+//!   finished. If initial mesh reifnement was not configured by the user, this
+//!   is the point where we continue after the constructor, by computing the
+//!   total number of elements across the whole problem.
+// *****************************************************************************
+{
+  // create sorter Charm++ chare array elements using dynamic insertion
+  m_sorter[ thisIndex ].insert( m_meshid, m_host, m_meshwriter, m_cbs, m_scheme,
+    CkCallback(CkIndex_Refiner::reorder(), thisProxy[thisIndex]), m_ginpoel,
+    m_coordmap, m_el, m_bface, m_triinpoel, m_bnode, m_elemblockid, m_nchare );
+
+  // Compute final number of cells across whole problem
+  std::vector< std::size_t >
+    meshdata{ m_meshid, m_ginpoel.size()/4, m_coord[0].size() };
+  contribute( meshdata, CkReduction::sum_ulong, m_cbr.get< tag::refined >() );
+
+  // // Free up memory if no dtref
+  // if (!g_inputdeck.get< tag::amr, tag::dtref >()) {
+  //   tk::destroy( m_ginpoel );
+  //   tk::destroy( m_el );
+  //   tk::destroy( m_coordmap );
+  //   tk::destroy( m_coord );
+  //   tk::destroy( m_bface );
+  //   tk::destroy( m_bnode );
+  //   tk::destroy( m_triinpoel );
+  //   tk::destroy( m_initref );
+  //   tk::destroy( m_ch );
+  //   tk::destroy( m_edgech );
+  //   tk::destroy( m_chedge );
+  //   tk::destroy( m_localEdgeData );
+  //   tk::destroy( m_remoteEdgeData );
+  //   tk::destroy( m_remoteEdges );
+  //   tk::destroy( m_intermediates );
+  //   tk::destroy( m_nodeCommMap );
+  //   tk::destroy( m_oldTets );
+  //   tk::destroy( m_addedNodes );
+  //   tk::destroy( m_addedTets );
+  //   tk::destroy( m_coarseBndFaces );
+  //   tk::destroy( m_coarseBndNodes );
+  //   tk::destroy( m_rid );
+//  //   tk::destroy( m_oldrid );
+  //   tk::destroy( m_lref );
+//  //   tk::destroy( m_oldparent );
+  // }
+}
+
+void
+Refiner::uniformRefine()
+// *****************************************************************************
+// Do uniform mesh refinement
+// *****************************************************************************
+{
+  // Do uniform refinement
+  m_refiner.mark_uniform_refinement();
+
+  // Update our extra-edge store based on refiner
+  updateEdgeData();
+
+  // Set number of extra edges to be zero, skipping correction (if this is the
+  // only step in this refinement step)
+  m_extra = 0;
+}
+
+void
+Refiner::uniformDeRefine()
+// *****************************************************************************
+// Do uniform mesh derefinement
+// *****************************************************************************
+{
+  // Do uniform derefinement
+  m_refiner.mark_uniform_derefinement();
+
+  // Update our extra-edge store based on refiner
+  updateEdgeData();
+
+  // Set number of extra edges to be zero, skipping correction (if this is the
+  // only step in this refinement step)
+  m_extra = 0;
+}
+
+Refiner::EdgeError
+Refiner::errorsInEdges(
+  std::size_t npoin,
+  const std::pair< std::vector<std::size_t>, std::vector<std::size_t> >& esup,
+  const tk::Fields& u ) const
+// *****************************************************************************
+//  Compute errors in edges
+//! \param[in] npoin Number nodes in current mesh (partition)
+//! \param[in] esup Elements surrounding points linked vectors
+//! \param[in] u Solution evaluated at mesh nodes for all scalar components
+//! \return A map associating errors (real values between 0.0 and 1.0 incusive)
+//!   to edges (2 local node IDs)
+// *****************************************************************************
+{
+  // Get the indices (in the system of systems) of refinement variables and the
+  // error indicator configured
+  auto ncomp = g_inputdeck.get< tag::ncomp >();
+  auto errtype = g_inputdeck.get< tag::amr, tag::error >();
+
+  // Compute points surrounding points
+  auto psup = tk::genPsup( m_inpoel, 4, esup );
+
+  // Compute errors in ICs and define refinement criteria for edges
+  AMR::Error error;
+  EdgeError edgeError;
+
+  for (std::size_t p=0; p<npoin; ++p) { // for all mesh nodes on this chare
+    for (auto q : tk::Around(psup,p)) { // for all nodes surrounding p
+      tk::real cmax = 0.0;
+      AMR::edge_t e(p,q);
+      for (std::size_t i=0; i<ncomp; ++i) { // for all refinement variables
+        auto c = error.scalar( u, e, i, m_coord, m_inpoel, esup, errtype );
+        if (c > cmax) cmax = c;        // find max error at edge
+      }
+      edgeError[ {{p,q}} ] = cmax;       // associate error to edge
+    }
+  }
+
+  return edgeError;
+}
+
+tk::Fields
+Refiner::solution( std::size_t npoin,
+                   const std::pair< std::vector< std::size_t >,
+                                    std::vector< std::size_t > >& esup ) const
+// *****************************************************************************
+//  Update (or evaluate) solution on current mesh
+//! \param[in] npoin Number nodes in current mesh (partition)
+//! \param[in] esup Elements surrounding points linked vectors
+//! \return Solution updated/evaluated for all scalar components
+// *****************************************************************************
+{
+  // Get solution whose error to evaluate
+  tk::Fields u;
+
+  if (m_mode == RefMode::T0REF) {
+
+    // Evaluate initial conditions at mesh nodes
+    u = nodeinit( npoin, esup );
+
+  } else if (m_mode == RefMode::DTREF) {
+
+    // Query current solution
+    u = m_scheme[m_meshid].ckLocal< Scheme::solution >( thisIndex );
+ 
+    const auto scheme = g_inputdeck.get< tag::scheme >();
+    const auto centering = ctr::Scheme().centering( scheme );
+    if (centering == tk::Centering::ELEM) {
+
+      // ...
+      Throw("Element-based solution handling not implemented in Refiner");
+
+    }
+
+  } else if (m_mode == RefMode::OUTREF) {
+
+
+
+  } else if (m_mode == RefMode::OUTDEREF) {
+
+
+
+  } else Throw( "RefMode not implemented" );
+
+  return u;
+}
+
+void
+Refiner::errorRefine()
+// *****************************************************************************
+// Do error-based mesh refinement and derefinement
+// *****************************************************************************
+{
+  // Find number of nodes in old mesh
+  auto npoin = tk::npoin_in_graph( m_inpoel );
+  // Generate edges surrounding points in old mesh
+  auto esup = tk::genEsup( m_inpoel, 4 );
+
+  // Update solution on current mesh
+  const auto& u = solution( npoin, esup );
+  Assert( u.nunk() == npoin, "Solution uninitialized or wrong size" );
+
+  using AMR::edge_t;
+  using AMR::edge_tag;
+
+  // Compute error in edges. Tag edge for refinement if error exceeds
+  // refinement tolerance, tag edge for derefinement if error is below
+  // derefinement tolerance.
+  auto tolref = g_inputdeck.get< tag::amr, tag::tol_refine >();
+  auto tolderef = g_inputdeck.get< tag::amr, tag::tol_derefine >();
+  std::vector< std::pair< edge_t, edge_tag > > tagged_edges;
+  for (const auto& e : errorsInEdges(npoin,esup,u)) {
+    if (e.second > tolref) {
+      tagged_edges.push_back( { edge_t( m_rid[e.first[0]], m_rid[e.first[1]] ),
+                                edge_tag::REFINE } );
+    } else if (e.second < tolderef) {
+      tagged_edges.push_back( { edge_t( m_rid[e.first[0]], m_rid[e.first[1]] ),
+                                edge_tag::DEREFINE } );
+    }
+  }
+
+  // Do error-based refinement
+  m_refiner.mark_error_refinement( tagged_edges );
+
+  // Update our extra-edge store based on refiner
+  updateEdgeData();
+
+  // Set number of extra edges to a nonzero number, triggering correction
+  m_extra = 1;
+}
+
+void
+Refiner::edgelistRefine()
+// *****************************************************************************
+// Do mesh refinement based on user explicitly tagging edges
+// *****************************************************************************
+{
+  // Get user-defined node-pairs (edges) to tag for refinement
+  const auto& edgenodelist = g_inputdeck.get< tag::amr, tag::edgelist >();
+
+  if (!edgenodelist.empty()) {  // if user explicitly tagged edges
+    // Find number of nodes in old mesh
+    auto npoin = tk::npoin_in_graph( m_inpoel );
+    // Generate edges surrounding points in old mesh
+    auto esup = tk::genEsup( m_inpoel, 4 );
+    auto psup = tk::genPsup( m_inpoel, 4, esup );
+
+    EdgeSet useredges;
+    for (std::size_t i=0; i<edgenodelist.size()/2; ++i)
+      useredges.insert( {{ {edgenodelist[i*2+0], edgenodelist[i*2+1]} }} );
+
+    using AMR::edge_t;
+    using AMR::edge_tag;
+
+    // Tag edges the user configured
+    std::vector< std::pair< edge_t, edge_tag > > tagged_edges;
+    for (std::size_t p=0; p<npoin; ++p)        // for all mesh nodes on this chare
+      for (auto q : tk::Around(psup,p)) {      // for all nodes surrounding p
+        Edge e{{ m_gid[p], m_gid[q] }};
+        auto f = useredges.find(e);
+        if (f != end(useredges)) { // tag edge if on user's list
+          tagged_edges.push_back( { edge_t( m_rid[p], m_rid[q] ),
+                                    edge_tag::REFINE } );
+          useredges.erase( f );
+        }
+      }
+
+    // Do error-based refinement
+    m_refiner.mark_error_refinement( tagged_edges );
+
+    // Update our extra-edge store based on refiner
+    updateEdgeData();
+
+    // Set number of extra edges to a nonzero number, triggering correction
+    m_extra = 1;
+  }
+}
+
+void
+Refiner::coordRefine()
+// *****************************************************************************
+// Do mesh refinement based on tagging edges based on end-point coordinates
+// *****************************************************************************
+{
+  // Get user-defined half-world coordinates
+  const auto& amr_coord = g_inputdeck.get< tag::amr, tag::coords >();
+  auto xminus = amr_coord.get< tag::xminus >();
+  auto xplus  = amr_coord.get< tag::xplus >();
+  auto yminus = amr_coord.get< tag::yminus >();
+  auto yplus  = amr_coord.get< tag::yplus >();
+  auto zminus = amr_coord.get< tag::zminus >();
+  auto zplus  = amr_coord.get< tag::zplus >();
+
+  // The default is the largest representable double
+  auto eps =
+    std::numeric_limits< tk::real >::epsilon();
+  const auto& amr_defcoord = g_inputdeck_defaults.get< tag::amr, tag::coords >();
+  auto xminus_default = amr_defcoord.get< tag::xminus >();
+  auto xplus_default = amr_defcoord.get< tag::xplus >();
+  auto yminus_default = amr_defcoord.get< tag::yminus >();
+  auto yplus_default = amr_defcoord.get< tag::yplus >();
+  auto zminus_default = amr_defcoord.get< tag::zminus >();
+  auto zplus_default = amr_defcoord.get< tag::zplus >();
+
+  // Decide if user has configured the half-world
+  bool xm = std::abs(xminus - xminus_default) > eps ? true : false;
+  bool xp = std::abs(xplus - xplus_default) > eps ? true : false;
+  bool ym = std::abs(yminus - yminus_default) > eps ? true : false;
+  bool yp = std::abs(yplus - yplus_default) > eps ? true : false;
+  bool zm = std::abs(zminus - zminus_default) > eps ? true : false;
+  bool zp = std::abs(zplus - zplus_default) > eps ? true : false;
+
+  using AMR::edge_t;
+  using AMR::edge_tag;
+
+  if (xm || xp || ym || yp || zm || zp) {       // if any half-world configured
+    // Find number of nodes in old mesh
+    auto npoin = tk::npoin_in_graph( m_inpoel );
+    // Generate edges surrounding points in old mesh
+    auto esup = tk::genEsup( m_inpoel, 4 );
+    auto psup = tk::genPsup( m_inpoel, 4, esup );
+    // Get access to node coordinates
+    const auto& x = m_coord[0];
+    const auto& y = m_coord[1];
+    const auto& z = m_coord[2];
+    // Compute edges to be tagged for refinement
+    std::vector< std::pair< edge_t, edge_tag > > tagged_edges;
+    for (std::size_t p=0; p<npoin; ++p)    // for all mesh nodes on this chare
+      for (auto q : tk::Around(psup,p)) {  // for all nodes surrounding p
+        Edge e{{p,q}};
+
+        bool t = true;
+        if (xm) { if (x[p]>xminus && x[q]>xminus) t = false; }
+        if (xp) { if (x[p]<xplus && x[q]<xplus) t = false; }
+        if (ym) { if (y[p]>yminus && y[q]>yminus) t = false; }
+        if (yp) { if (y[p]<yplus && y[q]<yplus) t = false; }
+        if (zm) { if (z[p]>zminus && z[q]>zminus) t = false; }
+        if (zp) { if (z[p]<zplus && z[q]<zplus) t = false; }
+
+        if (t) {
+          tagged_edges.push_back( { edge_t( m_rid[e[0]], m_rid[e[1]] ),
+                                    edge_tag::REFINE } );
+        }
+      }
+
+    // Do error-based refinement
+    m_refiner.mark_error_refinement( tagged_edges );
+
+    // Update our extra-edge store based on refiner
+    updateEdgeData();
+
+    // Set number of extra edges to a nonzero number, triggering correction
+    m_extra = 1;
+  }
+}
+
+tk::Fields
+Refiner::nodeinit( std::size_t npoin,
+                   const std::pair< std::vector< std::size_t >,
+                                    std::vector< std::size_t > >& esup ) const
+// *****************************************************************************
+// Evaluate initial conditions (IC) at mesh nodes
+//! \param[in] npoin Number points in mesh (on this chare)
+//! \param[in] esup Elements surrounding points as linked lists, see tk::genEsup
+//! \return Initial conditions (evaluated at t0) at nodes
+// *****************************************************************************
+{
+  auto t0 = g_inputdeck.get< tag::t0 >();
+  auto nprop = g_inputdeck.get< tag::ncomp >();
+
+  // Will store nodal ICs
+  tk::Fields u( m_coord[0].size(), nprop );
+
+  // Evaluate ICs differently depending on nodal or cell-centered discretization
+  const auto scheme = g_inputdeck.get< tag::scheme >();
+  const auto centering = ctr::Scheme().centering( scheme );
+  // list of nodes/elements at which box ICs are defined
+  std::vector< std::unordered_set< std::size_t > > inbox;
+  tk::real V = 1.0;
+  std::vector< tk::real > blkvols;
+  std::unordered_map< std::size_t, std::set< std::size_t > > nodeblockid,
+    elemblockid;
+
+  if (centering == tk::Centering::NODE) {
+
+    // Evaluate ICs for all scalar components integrated
+    g_cgpde[m_meshid].initialize( m_coord, u, t0, V, inbox, blkvols,
+      nodeblockid );
+
+  } else if (centering == tk::Centering::ELEM) {
+
+    auto esuel = tk::genEsuelTet( m_inpoel, esup ); // elems surrounding elements
+    // Initialize cell-based unknowns
+    tk::Fields ue( m_inpoel.size()/4, nprop );
+    auto lhs = ue;
+    auto geoElem = tk::genGeoElemTet( m_inpoel, m_coord );
+    if (scheme == ctr::SchemeType::FV) {
+    g_fvpde[m_meshid].lhs( geoElem, lhs );
+    g_fvpde[m_meshid].initialize( lhs, m_inpoel, m_coord, inbox, elemblockid,
+      ue, t0, esuel.size()/4 );
+    }
+    else {
+    g_dgpde[m_meshid].lhs( geoElem, lhs );
+    g_dgpde[m_meshid].initialize( lhs, m_inpoel, m_coord, inbox, elemblockid,
+      ue, t0, esuel.size()/4 );
+    }
+
+    // Transfer initial conditions from cells to nodes
+    for (std::size_t p=0; p<npoin; ++p) {    // for all mesh nodes on this chare
+      std::vector< tk::real > up( nprop, 0.0 );
+      tk::real vol = 0.0;
+      for (auto e : tk::Around(esup,p)) {       // for all cells around node p
+        // compute nodal volume: every element contributes their volume / 4
+        vol += geoElem(e,0) / 4.0;
+        // sum cell value to node weighed by cell volume / 4
+        for (std::size_t c=0; c<nprop; ++c)
+          up[c] += ue[e][c] * geoElem(e,0) / 4.0;
+      }
+      // store nodal value
+      for (std::size_t c=0; c<nprop; ++c) u(p,c) = up[c] / vol;
+    }
+
+  } else Throw( "Scheme centring not handled for nodal initialization" );
+
+  Assert( u.nunk() == m_coord[0].size(), "Size mismatch" );
+  Assert( u.nprop() == nprop, "Size mismatch" );
+
+  return u;
+}
+
+void
+Refiner::updateMesh()
+// *****************************************************************************
+// Update old mesh after refinement
+// *****************************************************************************
+{
+  // Get refined mesh connectivity
+  const auto& refinpoel = m_refiner.tet_store.get_active_inpoel();
+  Assert( refinpoel.size()%4 == 0, "Inconsistent refined mesh connectivity" );
+
+  // Generate unique node lists of old and refined mesh using local ids
+  auto rinpoel = m_inpoel;
+  tk::remap( rinpoel, m_rid );
+  std::unordered_set< std::size_t > old( begin(rinpoel), end(rinpoel) );
+  std::unordered_set< std::size_t > ref( begin(refinpoel), end(refinpoel) );
+
+  // Augment refiner id -> local node id map with newly added nodes
+  std::size_t l = m_lref.size();
+  for (auto r : ref) if (old.find(r) == end(old)) m_lref[r] = l++;
+
+  // Get nodal communication map from Discretization worker
+  if ( m_mode == RefMode::DTREF ||
+       m_mode == RefMode::OUTREF ||
+       m_mode == RefMode::OUTDEREF ) {
+    m_nodeCommMap =
+      m_scheme[m_meshid].disc()[thisIndex].ckLocal()->NodeCommMap();
+  }
+
+  // Update mesh and solution after refinement
+  newVolMesh( old, ref );
+
+  // Update mesh connectivity from refiner lib, remapping refiner to local ids
+  m_inpoel = m_refiner.tet_store.get_active_inpoel();
+  tk::remap( m_inpoel, m_lref );
+
+  // Update mesh connectivity with new global node ids
+  m_ginpoel = m_inpoel;
+  Assert( tk::uniquecopy(m_ginpoel).size() == m_coord[0].size(),
+          "Size mismatch" );
+  tk::remap( m_ginpoel, m_gid );
+
+  // Update boundary face and node information
+  newBndMesh( ref );
+
+  // Augment node communication map with newly added nodes on chare-boundary
+  if (m_mode == RefMode::DTREF || m_mode == RefMode::OUTREF) {
+    for (const auto& [ neighborchare, edges ] : m_remoteEdges) {
+      auto& nodes = tk::ref_find( m_nodeCommMap, neighborchare );
+      for (const auto& e : edges) {
+        // If parent nodes were part of the node communication map for chare
+        if (nodes.find(e[0]) != end(nodes) && nodes.find(e[1]) != end(nodes)) {
+          // Add new node if local id was generated for it
+          auto n = Hash<2>()( e );
+          if (m_lid.find(n) != end(m_lid)) nodes.insert( n );
+        }
+      }
+    }
+  }
+
+  // Ensure valid mesh after refinement
+  Assert( tk::positiveJacobians( m_inpoel, m_coord ),
+          "Refined mesh cell Jacobian non-positive" );
+
+  Assert( tk::conforming( m_inpoel, m_coord, true, m_rid ),
+          "Chare-"+std::to_string(thisIndex)+
+          " mesh not conforming after updating mesh after mesh refinement" );
+
+  // Perform leak test on new mesh
+  Assert( !tk::leakyPartition(
+            tk::genEsuelTet( m_inpoel, tk::genEsup(m_inpoel,4) ),
+            m_inpoel, m_coord ),
+          "Refined mesh partition leaky" );
+}
+
+void
+Refiner::newVolMesh( const std::unordered_set< std::size_t >& old,
+                     const std::unordered_set< std::size_t >& ref )
+// *****************************************************************************
+//  Compute new volume mesh after mesh refinement
+//! \param[in] old Unique nodes of the old (unrefined) mesh using
+//!   refiner-lib ids
+//! \param[in] ref Unique nodes of the refined mesh using refiner-lib ids
+// *****************************************************************************
+{
+  const auto& x = m_coord[0];
+  const auto& y = m_coord[1];
+  const auto& z = m_coord[2];
+
+  // Generate coordinates and ids to newly added nodes after refinement
+  std::unordered_map< std::size_t, std::size_t > gid_add;
+  tk::destroy( m_addedNodes );
+  tk::destroy( m_removedNodes );
+  tk::destroy( m_amrNodeMap );
+  for (auto r : ref) {               // for all unique nodes of the refined mesh
+    if (old.find(r) == end(old)) {   // if node is newly added
+      // get (local) parent ids of newly added node
+      auto p = m_refiner.node_connectivity.get( r );
+      Assert(p[0] != p[1], "Node without parent edge in newVolMesh");
+      Assert( old.find(p[0]) != end(old) && old.find(p[1]) != end(old),
+              "Parent(s) not in old mesh" );
+      // local parent ids
+      decltype(p) lp{{tk::cref_find(m_lref,p[0]), tk::cref_find(m_lref,p[1])}};
+      // global parent ids
+      decltype(p) gp{{m_gid[lp[0]], m_gid[lp[1]]}};
+      // generate new global ID for newly added node
+      auto g = Hash<2>()( gp );
+
+      // if node added by AMR lib has not yet been added to Refiner's new mesh
+      if (m_coordmap.find(g) == end(m_coordmap)) {
+        Assert( g >= old.size(), "Hashed id overwriting old id" );
+        Assert( m_lid.find(g) == end(m_lid),
+                "Overwriting entry global->local node ID map" );
+        auto l = tk::cref_find( m_lref, r );
+        // store newly added node id and their parent ids (local ids)
+        m_addedNodes[r] = lp;   // key = r for later update to local
+        // assign new node to refiner->global map
+        gid_add[r] = g; // key = r for later search
+        // assign new node to global->local map
+        m_lid[g] = l;
+        // generate and store coordinates for newly added node
+        m_coordmap.insert( {g, {{ (x[lp[0]] + x[lp[1]])/2.0,
+                                  (y[lp[0]] + y[lp[1]])/2.0,
+                                  (z[lp[0]] + z[lp[1]])/2.0 }} } );
+      }
+    }
+  }
+  tk::destroy( m_coord );
+
+  // generate a node map based on oldnodes+addednodes
+  std::vector< size_t > nodeVec(m_coordmap.size());
+  for (size_t j=0; j<nodeVec.size(); ++j) {
+    nodeVec[j] = j;
+  }
+
+  // Remove coordinates and ids of removed nodes due to derefinement
+  std::unordered_map< std::size_t, std::size_t > gid_rem;
+  for (auto o : old) {               // for all unique nodes of the old mesh
+    if (ref.find(o) == end(ref)) {   // if node is no longer in new mesh
+      auto l = tk::cref_find( m_lref, o );
+      auto g = m_gid[l];
+      // store local-ids of removed nodes
+      m_removedNodes.insert(l);
+      // remove derefined nodes from node comm map
+      for (auto& [neighborchare, sharednodes] : m_nodeCommMap) {
+        if (sharednodes.find(g) != sharednodes.end()) {
+          sharednodes.erase(g);
+        }
+      }
+      gid_rem[l] = g;
+      m_lid.erase( g );
+      m_coordmap.erase( g );
+    }
+  }
+
+  // update the node map by removing the derefined nodes
+  if (m_mode == RefMode::DTREF && m_removedNodes.size() > 0) {
+    // remove derefined nodes
+    size_t remCount = 0;
+    size_t origSize = nodeVec.size();
+    for (size_t j=0; j<origSize; ++j) {
+      auto nd = nodeVec[j-remCount];
+
+      bool no_change = false;
+      size_t nodeidx = 0;
+      for (const auto& rn : m_removedNodes) {
+        if (nd < *m_removedNodes.cbegin()) {
+          no_change = true;
+          break;
+        }
+        else if (nd <= rn) {
+          nodeidx = rn;
+          break;
+        }
+      }
+
+      // if node is out-or-range of removed nodes list, continue with next entry
+      if (no_change)
+        continue;
+      // if not is within range of removed nodes list, erase node appropriately
+      else if (nodeidx == nd) {
+        //! Difference type for iterator/pointer arithmetics
+        using diff_type = std::vector< std::size_t >::difference_type;
+        nodeVec.erase(nodeVec.begin()+static_cast< diff_type >(j-remCount));
+        ++remCount;
+      }
+    }
+
+    Assert(remCount == m_removedNodes.size(), "Incorrect number of nodes removed "
+      "from node map.");
+  }
+
+  // invert node vector to get node map
+  for (size_t i=0; i<nodeVec.size(); ++i) {
+    m_amrNodeMap[nodeVec[i]] = i;
+  }
+
+  //// Save previous states of refiner-local node id maps before update
+  //m_oldrid = m_rid;
+  //m_oldlref = m_lref;
+
+  // Generate new node id maps for nodes kept
+  tk::destroy( m_lref );
+  std::vector< std::size_t > rid( ref.size() );
+  std::vector< std::size_t > gid( ref.size() );
+  std::size_t l = 0;    // will generate new local node id
+  for (std::size_t i=0; i<m_gid.size(); ++i) {
+    if (gid_rem.find(i) == end(gid_rem)) {
+      gid[l] = m_gid[i];
+      rid[l] = m_rid[i];
+      m_lref[ m_rid[i] ] = l;
+      ++l;
+    }
+  }
+  // Add newly added nodes due to refinement to node id maps
+  decltype(m_addedNodes) addedNodes( m_addedNodes.size() );<--- Variable 'addedNodes' is assigned a value that is never used.
+  for (const auto& n : gid_add) {
+    auto r = n.first;
+    auto g = n.second;
+    gid[l] = g;
+    rid[l] = r;<--- Variable 'rid[l]' is assigned a value that is never used.
+    Assert(m_lref.find(r) == m_lref.end(), "Overwriting lref");
+    m_lref[r] = l;
+    auto it = m_addedNodes.find( r );
+    Assert( it != end(m_addedNodes), "Cannot find added node" );
+    addedNodes[l] = std::move(it->second);
+    addedNodes.at(l)[0] = m_amrNodeMap[addedNodes.at(l)[0]];
+    addedNodes.at(l)[1] = m_amrNodeMap[addedNodes.at(l)[1]];
+    ++l;
+  }
+  Assert( m_lref.size() == ref.size(), "Size mismatch" );
+  //for (auto r : ref) {
+  //  Assert(m_lref.find(r) != m_lref.end(), "Node missing in lref");
+  //}
+  //const auto& int_list = m_refiner.tet_store.intermediate_list;
+  //for (auto in : int_list) {
+  //  Assert(m_lref.find(in) != m_lref.end(), "Interm node missing in lref: "
+  //    + std::to_string(in));
+  //}
+  m_rid = std::move( rid );
+  Assert( m_rid.size() == ref.size(), "Size mismatch" );
+  m_addedNodes = std::move( addedNodes );
+
+  // Update node coordinates, ids, and id maps
+  auto& rx = m_coord[0];
+  auto& ry = m_coord[1];
+  auto& rz = m_coord[2];
+  rx.resize( ref.size() );
+  ry.resize( ref.size() );
+  rz.resize( ref.size() );
+  for (std::size_t i=0; i<gid.size(); ++i) {
+    tk::ref_find( m_lid, gid[i] ) = i;
+    const auto& c = tk::cref_find( m_coordmap, gid[i] );
+    rx[i] = c[0];
+    ry[i] = c[1];
+    rz[i] = c[2];
+  }
+  m_gid = std::move( gid );
+  Assert( m_gid.size() == m_lid.size() && m_gid.size() == ref.size(),
+    "Size mismatch" );
+}
+
+std::unordered_set< std::size_t >
+Refiner::ancestors( std::size_t n )
+// *****************************************************************************
+// Find the oldest parents of a mesh node in the AMR hierarchy
+//! \param[in] n Local node id whose ancestors to search
+//! \return Parents of local node id from the coarsest (original) mesh
+// *****************************************************************************
+{
+  auto d = m_refiner.node_connectivity.get( m_rid[n] );
+  decltype(d) p{{ tk::cref_find( m_lref, d[0] ),
+                  tk::cref_find( m_lref, d[1] ) }};
+
+  std::unordered_set< std::size_t > s;
+
+  if (p != AMR::node_pair_t{{n,n}}) {
+    auto q = ancestors( p[0] );
+    s.insert( begin(q), end(q) );
+    auto r = ancestors( p[1] );
+    s.insert( begin(r), end(r) );
+  } else {
+    s.insert( begin(p), end(p) );
+  }
+
+  return s;
+}
+
+Refiner::BndFaceData
+Refiner::boundary()
+// *****************************************************************************
+//  Generate boundary data structures used to update refined/derefined boundary
+//  faces and nodes of side sets
+//! \return A tuple of boundary face data
+//! \details The output of this function is used to regenerate physical boundary
+//!   face and node data structures after refinement, see updateBndData().
+// *****************************************************************************
+{
+  // Generate the inverse of AMR's tet store.
+  std::unordered_map< Tet, std::size_t, Hash<4>, Eq<4> > invtets;
+  for (const auto& [key, tet] : m_refiner.tet_store.tets)
+    invtets[ tet ] = key;
+
+  //std::cout << thisIndex << " invt: " << invtets.size() << '\n';
+  //std::cout << thisIndex << " active inpoel size: " << m_refiner.tet_store.get_active_inpoel().size() << '\n';
+  //std::cout << thisIndex << " marked derefinement size: " << m_refiner.tet_store.marked_derefinements.size() << '\n';
+
+  // Generate data structure pcFaceTets for the new (post-AMR) mesh:
+  // pcFaceTets is a map that associates all triangle boundary faces (physical
+  // and chare) to the id of the tet adjacent to the said face.
+  // Key: Face-nodes' global id; Value: tet-id.
+  std::unordered_map< Face, std::size_t, Hash<3>, Eq<3> > pcFaceTets;
+  auto esuel = tk::genEsuelTet( m_inpoel, tk::genEsup(m_inpoel,4) );
+  for (std::size_t e=0; e<esuel.size()/4; ++e) {
+    auto m = e*4;
+    for (std::size_t f=0; f<4; ++f) {
+      if (esuel[m+f] == -1) {  // if a face does not have an adjacent tet
+        Face b{{ m_ginpoel[ m+tk::lpofa[f][0] ],
+                 m_ginpoel[ m+tk::lpofa[f][1] ],
+                 m_ginpoel[ m+tk::lpofa[f][2] ] }};
+        Assert( m_inpoel[m+0] < m_rid.size() &&
+                m_inpoel[m+1] < m_rid.size() &&
+                m_inpoel[m+2] < m_rid.size() &&
+                m_inpoel[m+3] < m_rid.size(), "Indexing out of rid" );
+        Tet t{{ m_rid[ m_inpoel[m+0] ], m_rid[ m_inpoel[m+1] ],
+                m_rid[ m_inpoel[m+2] ], m_rid[ m_inpoel[m+3] ] }};
+        //Tet t{{ m_inpoel[m+0], m_inpoel[m+1],
+        //        m_inpoel[m+2], m_inpoel[m+3] }};
+        // associate tet id to adjacent (physical or chare) boundary face
+        auto i = invtets.find( t );
+        Assert(m_refiner.tet_store.is_active(i->second),
+          "Inactive element while regenerating boundary data");
+        if (i != end(invtets)) {
+          //std::cout << "refacetets: " <<
+          //  b[0] << "-" << b[1] << "-" << b[2] << std::endl;
+          pcFaceTets[ b ] = i->second;
+        } else {
+          Throw("Active element not found in tet_store");
+        }
+      }
+    }
+  }
+
+  // Generate child->parent tet and id maps after refinement/derefinement step
+//  tk::destroy( m_oldparent );
+  m_addedTets.clear();
+  std::size_t p = 0;
+  std::size_t c = 0;<--- Variable 'c' is assigned a value that is never used.
+  const auto& tet_store = m_refiner.tet_store;
+  for (const auto& t : tet_store.tets) {
+    // query number of children of tet
+    auto nc = tet_store.data( t.first ).children.size();
+    for (decltype(nc) i=0; i<nc; ++i ) {      // for all child tets
+      // get child tet id
+      auto childtet = tet_store.get_child_id( t.first, i );
+      auto ct = tet_store.tets.find( childtet );
+      Assert(ct != tet_store.tets.end(), "Child not found in tet store");
+//      //auto cA = tk::cref_find( m_lref, ct->second[0] );
+//      //auto cB = tk::cref_find( m_lref, ct->second[1] );
+//      //auto cC = tk::cref_find( m_lref, ct->second[2] );
+//      //auto cD = tk::cref_find( m_lref, ct->second[3] );
+//      // get nodes of parent tet
+//      //auto pA = tk::cref_find( m_lref, t.second[0] );
+//      //auto pB = tk::cref_find( m_lref, t.second[1] );
+//      //auto pC = tk::cref_find( m_lref, t.second[2] );
+//      //auto pD = tk::cref_find( m_lref, t.second[3] );
+//      // assign parent tet to child tet
+//      //m_oldparent[ {{cA,cB,cC,cD}} ] = {{pA,pB,pC,pD}};
+//      m_oldparent[ ct->second ] = t.second; //{{pA,pB,pC,pD}};
+      if (m_oldTets.find(ct->second) == end(m_oldTets)) {
+        // TODO: the following code can assign negative ids to newly added tets.
+        // This needs to be corrected before applying to cell-based schemes.
+        //Assert((p-m_oldntets) > 0, "Negative id assigned to added tet");
+        m_addedTets[ c++ ] = p - m_oldntets;
+      }
+    }
+    ++p;
+  }
+
+  //std::cout << thisIndex << " added: " << m_addedTets.size() << '\n';
+  //std::cout << thisIndex << " parent: " << m_oldparent.size() << '\n';
+  //std::cout << thisIndex << " pcret: " << pcFaceTets.size() << '\n';
+
+  //for (std::size_t f=0; f<m_triinpoel.size()/3; ++f) {
+  //  std::cout << "triinpoel: " <<
+  //    m_triinpoel[f*3+0] << "-" << m_triinpoel[f*3+1] << "-" <<
+  //    m_triinpoel[f*3+2] << std::endl;
+  //}
+
+  return pcFaceTets;
+}
+
+void
+Refiner::newBndMesh( const std::unordered_set< std::size_t >& ref )
+// *****************************************************************************
+// Update boundary data structures after mesh refinement
+//! \param[in] ref Unique nodes of the refined mesh using refiner-lib ids
+// *****************************************************************************
+{
+  // Generate boundary face data structures used to regenerate boundary face
+  // and node data after mesh refinement
+  auto pcFaceTets = boundary();
+
+  // Regerate boundary faces and nodes after AMR step
+  updateBndData( ref, pcFaceTets );
+}
+
+void
+Refiner::updateBndData(
+  [[maybe_unused]] const std::unordered_set< std::size_t >& ref,
+  const BndFaceData& pcFaceTets )
+// *****************************************************************************
+// Regenerate boundary faces and nodes after AMR step
+//! \param[in] ref Unique nodes of the refined mesh using refiner-lib ids
+//! \param[in] pcFaceTets Boundary face data
+// *****************************************************************************
+{
+  // storage for boundary faces associated to side-set IDs of the refined mesh
+  tk::destroy( m_bface );
+  // storage for boundary faces-node connectivity of the refined mesh
+  tk::destroy( m_triinpoel );
+  // storage for boundary nodes associated to side-set IDs of the refined mesh
+  tk::destroy( m_bnode );
+
+  // face id counter
+  std::size_t facecnt = 0;
+  // will collect unique faces added for each side set
+  std::unordered_map< int, FaceSet > bf;
+
+  // Lambda to associate a boundary face and connectivity to a side set.
+  // Argument 's' is the list of faces (ids) to add the new face to. Argument
+  // 'ss' is the side set id to which the face is added. Argument 'f' is the
+  // triangle face connectivity to add.
+  auto addBndFace = [&]( std::vector< std::size_t >& s, int ss, const Face& f )
+  {
+    // only add face if it has not yet been aded to this side set
+    if (bf[ ss ].insert( f ).second) {
+      s.push_back( facecnt++ );
+      m_triinpoel.insert( end(m_triinpoel), begin(f), end(f) );
+      Assert(m_triinpoel.size()/3 == facecnt, "Incorrect size of triinpoel");
+    }
+  };
+
+  // Lambda to search the parents in the coarsest mesh of a mesh node and if
+  // found, add its global id to boundary node lists associated to the side
+  // set(s) of its parents. Argument 'n' is the local id of the mesh node id
+  // whose parents to search.
+  auto addBndNodes = [&]( std::size_t n ){
+    auto a = ancestors( n );  // find parents of n in coarse mesh
+    if (a.size() == 1) {
+      // node was part of the coarse mesh
+      Assert(*a.cbegin() == n, "Single ancestor not self");
+      auto ss = keys( m_coarseBndNodes, m_gid[*a.cbegin()] );
+      for (auto s : ss)
+        m_bnode[ s ].push_back( m_gid[n] );
+    } else if (a.size() == 2) {
+      // node was added to an edge of a coarse face
+      std::vector< std::size_t > p( begin(a), end(a) );
+      auto ss1 = keys( m_coarseBndNodes, m_gid[p[0]] );
+      auto ss2 = keys( m_coarseBndNodes, m_gid[p[1]] );
+      for (auto s : ss1) {
+        // only add 'n' to bnode if all parent nodes are in same side set, else
+        // 'n' is not a boundary node
+        if (ss2.find(s) != end(ss2)) {
+          m_bnode[ s ].push_back( m_gid[n] );
+        }
+      }
+    } else if (a.size() == 3) {
+      // node was added inside of a coarse face
+      std::vector< std::size_t > p( begin(a), end(a) );
+      auto ss1 = keys( m_coarseBndNodes, m_gid[p[0]] );
+      auto ss2 = keys( m_coarseBndNodes, m_gid[p[1]] );
+      auto ss3 = keys( m_coarseBndNodes, m_gid[p[2]] );
+      for (auto s : ss1) {
+        // only add 'n' to bnode if all parent nodes are in same side set, else
+        // 'n' is not a boundary node
+        if (ss2.find(s) != end(ss2) && ss3.find(s) != end(ss3)) {
+          m_bnode[ s ].push_back( m_gid[n] );
+        }
+      }
+    }
+  };
+
+  // Regenerate boundary faces for new mesh along side sets. For all faces
+  // associated to side sets, we find the ancestors (parents of nodes in the
+  // original/coarsest mesh) of the nodes comprising the physical and chare
+  // boundary faces of the new mesh.
+  //bool faceNoSs = false;
+  // for all P/C faces in current (post-AMR) mesh
+  for (const auto& [ face, tetid ] : pcFaceTets) {
+    // find ancestors of face
+    std::unordered_set< std::size_t > ans;
+    for (std::size_t i=0; i<3; ++i) {
+      auto ai = ancestors(tk::cref_find(m_lid, face[i]));
+      ans.insert(ai.begin(), ai.end());
+    }
+    Assert(ans.size() == 3, "Incorrect number of ancestors in refined face");
+    Face af;
+    std::size_t i = 0;
+    for (auto ai:ans) {
+      af[i] = m_gid[ai];
+      ++i;
+    }
+    // for all boundary faces in original mesh
+    //std::size_t fss = 0;
+    for (const auto& [ss, cfaceset] : m_coarseBndFaces) {
+      if (cfaceset.find(af) != cfaceset.end()) {
+        addBndFace(m_bface[ss], ss, face);
+        //++fss;
+      }
+      for (auto j : face) {
+        addBndNodes(tk::cref_find(m_lid, j));
+      }
+    }
+    //if (fss==0) {
+    //  std::cout << "Face added to no/multiple side sets; " << fss << std::endl;
+    //  faceNoSs = true;
+    //}
+  }
+
+  // Commented code below, since diagcg can work without sideset/bcs
+  //Assert(!faceNoSs, "Face/s added to incorrect number of side sets");
+
+  // Make boundary node IDs unique for each physical boundary (side set)
+  for (auto& s : m_bnode) tk::unique( s.second );
+
+  //for (const auto& [ setid, faceids ] : m_bface) {
+  //  std::cout << "sset: " << setid << std::endl;
+  //  for (auto f : faceids) {
+  //    Assert(f<m_triinpoel.size()/3, "Out of bounds access into triinpoel");
+  //    std::cout << "new bndfaces: " <<
+  //      m_triinpoel[f*3+0] << "-" << m_triinpoel[f*3+1] << "-" <<
+  //      m_triinpoel[f*3+2] << std::endl;
+  //  }
+  //}
+
+  //for (std::size_t f=0; f<m_triinpoel.size()/3; ++f) {
+  //  std::cout << "new triinpoel: " <<
+  //    m_triinpoel[f*3+0] << "-" << m_triinpoel[f*3+1] << "-" <<
+  //    m_triinpoel[f*3+2] << std::endl;
+  //}
+
+  //std::cout << thisIndex << " bf: " << tk::sumvalsize( m_bface ) << '\n';
+
+  //std::cout << thisIndex << " bn: " << tk::sumvalsize( m_bnode ) << '\n';
+
+  // Perform leak-test on boundary face data just updated (only in DEBUG)
+  Assert( bndIntegral(), "Partial boundary integral" );
+}
+
+bool
+Refiner::bndIntegral()
+// *****************************************************************************
+//  Compute partial boundary surface integral and sum across all chares
+//! \return true so we don't trigger assert in client code
+//! \details This function computes a partial surface integral over the boundary
+//!   of the faces of this mesh partition then sends its contribution to perform
+//!   the integral acorss the total problem boundary. After the global sum a
+//!   non-zero vector result indicates a leak, e.g., a hole in the boundary
+//!   which indicates an error in the boundary face data structures used to
+//!   compute the partial surface integrals.
+// *****************************************************************************
+{
+  const auto& x = m_coord[0];
+  const auto& y = m_coord[1];
+  const auto& z = m_coord[2];
+
+  std::vector< tk::real > s{{ 0.0, 0.0, 0.0 }};
+
+  for (const auto& [ setid, faceids ] : m_bface) {
+    for (auto f : faceids) {
+      auto A = tk::cref_find( m_lid, m_triinpoel[f*3+0] );
+      auto B = tk::cref_find( m_lid, m_triinpoel[f*3+1] );
+      auto C = tk::cref_find( m_lid, m_triinpoel[f*3+2] );
+      // Compute geometry data for face
+      auto geoface = tk::geoFaceTri( {{x[A], x[B], x[C]}},
+                                     {{y[A], y[B], y[C]}},
+                                     {{z[A], z[B], z[C]}} );
+      // Sum up face area * face unit-normal
+      s[0] += geoface(0,0) * geoface(0,1);
+      s[1] += geoface(0,0) * geoface(0,2);
+      s[2] += geoface(0,0) * geoface(0,3);
+    }
+  }
+
+  s.push_back( -1.0 );  // negative: no call-back after reduction
+  s.push_back( static_cast< tk::real >( m_meshid ) );
+
+  // Send contribution to host summing partial surface integrals
+  contribute( s, CkReduction::sum_double, m_cbr.get< tag::bndint >() );
+
+  return true;  // don't trigger the assert in client code
+}
+
+#include "NoWarning/refiner.def.h"
 
diff --git a/Release/cppcheck/46.html b/Release/cppcheck/46.html index 9efde2d77a4d..e8d402145eda 100644 --- a/Release/cppcheck/46.html +++ b/Release/cppcheck/46.html @@ -152,259 +152,3239 @@
- - + @@ -99,7 +99,7 @@ 25 : : public: 26 : : 27 : : //! Default constructor for migration - 28 : 7858 : mesh_adapter_t() {} + 28 : 7755 : mesh_adapter_t() {} 29 : : 30 : : //! Constructor taking a max refinement level and a mesh graph 31 : 2007 : explicit mesh_adapter_t( std::size_t u_mrl, diff --git a/Release/test_coverage/Inciter/AMR/node_connectivity.hpp.func-sort-c.html b/Release/test_coverage/Inciter/AMR/node_connectivity.hpp.func-sort-c.html index 5b1292b8e912..f6aacce8bcde 100644 --- a/Release/test_coverage/Inciter/AMR/node_connectivity.hpp.func-sort-c.html +++ b/Release/test_coverage/Inciter/AMR/node_connectivity.hpp.func-sort-c.html @@ -33,7 +33,7 @@ - + diff --git a/Release/test_coverage/Inciter/AMR/node_connectivity.hpp.func.html b/Release/test_coverage/Inciter/AMR/node_connectivity.hpp.func.html index cf40c48e6fe3..8500ec315336 100644 --- a/Release/test_coverage/Inciter/AMR/node_connectivity.hpp.func.html +++ b/Release/test_coverage/Inciter/AMR/node_connectivity.hpp.func.html @@ -33,7 +33,7 @@ - + diff --git a/Release/test_coverage/Inciter/AMR/node_connectivity.hpp.gcov.html b/Release/test_coverage/Inciter/AMR/node_connectivity.hpp.gcov.html index 79492529bbe0..ec7c541849b2 100644 --- a/Release/test_coverage/Inciter/AMR/node_connectivity.hpp.gcov.html +++ b/Release/test_coverage/Inciter/AMR/node_connectivity.hpp.gcov.html @@ -33,7 +33,7 @@ - + @@ -105,12 +105,12 @@ 31 : : size_t empty_node_count = 0; 32 : : 33 : : - 34 : 7858 : node_connectivity_t() { } // default cons + 34 : 7755 : node_connectivity_t() { } // default cons 35 : : 36 : : //! Non-const-ref accessor to state 37 : : //! \return All node pairs - 38 : 24390 : node_list_t& data() { return nodes; } - 39 : 24390 : inv_node_list_t& inv_data() { return inv_nodes; } + 38 : 24081 : node_list_t& data() { return nodes; } + 39 : 24081 : inv_node_list_t& inv_data() { return inv_nodes; } 40 : : 41 : : /** 42 : : * @brief Method to add initial nodes to the store diff --git a/Release/test_coverage/Inciter/AMR/refinement.hpp.func-sort-c.html b/Release/test_coverage/Inciter/AMR/refinement.hpp.func-sort-c.html index 3782d3133935..e25c1c8d009f 100644 --- a/Release/test_coverage/Inciter/AMR/refinement.hpp.func-sort-c.html +++ b/Release/test_coverage/Inciter/AMR/refinement.hpp.func-sort-c.html @@ -33,7 +33,7 @@ - + diff --git a/Release/test_coverage/Inciter/AMR/refinement.hpp.func.html b/Release/test_coverage/Inciter/AMR/refinement.hpp.func.html index 8c5dc1b68345..1172a9d4cb47 100644 --- a/Release/test_coverage/Inciter/AMR/refinement.hpp.func.html +++ b/Release/test_coverage/Inciter/AMR/refinement.hpp.func.html @@ -33,7 +33,7 @@ - + diff --git a/Release/test_coverage/Inciter/AMR/refinement.hpp.gcov.html b/Release/test_coverage/Inciter/AMR/refinement.hpp.gcov.html index fa9c2d40eaf9..5598c971af0d 100644 --- a/Release/test_coverage/Inciter/AMR/refinement.hpp.gcov.html +++ b/Release/test_coverage/Inciter/AMR/refinement.hpp.gcov.html @@ -33,7 +33,7 @@ - + @@ -102,7 +102,7 @@ 28 : : public: 29 : : 30 : : //! Default constructor for migration - 31 : 7858 : refinement_t() {} + 31 : 7755 : refinement_t() {} 32 : : 33 : : //! Constructor taking a user-specified max refinement level 34 : 2007 : refinement_t( size_t u_mrl ) : diff --git a/Release/test_coverage/Inciter/AMR/tet_store.hpp.func-sort-c.html b/Release/test_coverage/Inciter/AMR/tet_store.hpp.func-sort-c.html index 34797974842a..7f22714939e1 100644 --- a/Release/test_coverage/Inciter/AMR/tet_store.hpp.func-sort-c.html +++ b/Release/test_coverage/Inciter/AMR/tet_store.hpp.func-sort-c.html @@ -33,7 +33,7 @@ - + diff --git a/Release/test_coverage/Inciter/AMR/tet_store.hpp.func.html b/Release/test_coverage/Inciter/AMR/tet_store.hpp.func.html index da0da0e282f1..cff76dfb4fed 100644 --- a/Release/test_coverage/Inciter/AMR/tet_store.hpp.func.html +++ b/Release/test_coverage/Inciter/AMR/tet_store.hpp.func.html @@ -33,7 +33,7 @@ - + diff --git a/Release/test_coverage/Inciter/AMR/tet_store.hpp.gcov.html b/Release/test_coverage/Inciter/AMR/tet_store.hpp.gcov.html index 3430d1944331..aa82db2c70d1 100644 --- a/Release/test_coverage/Inciter/AMR/tet_store.hpp.gcov.html +++ b/Release/test_coverage/Inciter/AMR/tet_store.hpp.gcov.html @@ -33,7 +33,7 @@ - + diff --git a/Release/test_coverage/Inciter/AMR/util.cpp.func-sort-c.html b/Release/test_coverage/Inciter/AMR/util.cpp.func-sort-c.html index d46c7657f836..8eada27697f2 100644 --- a/Release/test_coverage/Inciter/AMR/util.cpp.func-sort-c.html +++ b/Release/test_coverage/Inciter/AMR/util.cpp.func-sort-c.html @@ -33,7 +33,7 @@ - + diff --git a/Release/test_coverage/Inciter/AMR/util.cpp.func.html b/Release/test_coverage/Inciter/AMR/util.cpp.func.html index dc1df563da0b..b53d7c54e99f 100644 --- a/Release/test_coverage/Inciter/AMR/util.cpp.func.html +++ b/Release/test_coverage/Inciter/AMR/util.cpp.func.html @@ -33,7 +33,7 @@ - + diff --git a/Release/test_coverage/Inciter/AMR/util.cpp.gcov.html b/Release/test_coverage/Inciter/AMR/util.cpp.gcov.html index 5e5918321631..6bc6d1979d71 100644 --- a/Release/test_coverage/Inciter/AMR/util.cpp.gcov.html +++ b/Release/test_coverage/Inciter/AMR/util.cpp.gcov.html @@ -33,7 +33,7 @@ - + diff --git a/Release/test_coverage/Inciter/DG.cpp.func-sort-c.html b/Release/test_coverage/Inciter/DG.cpp.func-sort-c.html index 455a63df0084..81c669d5831a 100644 --- a/Release/test_coverage/Inciter/DG.cpp.func-sort-c.html +++ b/Release/test_coverage/Inciter/DG.cpp.func-sort-c.html @@ -33,7 +33,7 @@ - + diff --git a/Release/test_coverage/Inciter/DG.cpp.func.html b/Release/test_coverage/Inciter/DG.cpp.func.html index de1112aef364..ef2fd29837c0 100644 --- a/Release/test_coverage/Inciter/DG.cpp.func.html +++ b/Release/test_coverage/Inciter/DG.cpp.func.html @@ -33,7 +33,7 @@ - + diff --git a/Release/test_coverage/Inciter/DG.cpp.gcov.html b/Release/test_coverage/Inciter/DG.cpp.gcov.html index b5725ffc2dc6..9d511e327f6b 100644 --- a/Release/test_coverage/Inciter/DG.cpp.gcov.html +++ b/Release/test_coverage/Inciter/DG.cpp.gcov.html @@ -33,7 +33,7 @@ - + @@ -1034,7 +1034,7 @@ 923 : : { 924 : 34620750 : auto max_mark = 2*c*m_ndof_NodalExtrm + 2*idof; 925 : 34620750 : auto min_mark = max_mark + 1; - 926 [ + + ][ + + ]: 35195096 : u[max_mark] = std::max( G1[i][max_mark], u[max_mark] ); + 926 [ + + ][ + + ]: 35192629 : u[max_mark] = std::max( G1[i][max_mark], u[max_mark] ); 927 : 34620750 : u[min_mark] = std::min( G1[i][min_mark], u[min_mark] ); 928 : : } 929 : : } @@ -1172,8 +1172,8 @@ 1061 : : { 1062 : 26641125 : auto max_mark = 2*c*m_ndof_NodalExtrm + 2*idof; 1063 : 26641125 : auto min_mark = max_mark + 1; - 1064 [ + + ]: 26641125 : auto& ex = uNodalExtrm[i->second]; - 1065 [ + + ][ + + ]: 33461114 : ex[max_mark] = std::max(ex[max_mark], gradc[c][idof]); + 1064 [ + + ]: 26641125 : auto& ex = uNodalExtrm[i->second]; + 1065 [ + + ][ + + ]: 33468479 : ex[max_mark] = std::max(ex[max_mark], gradc[c][idof]); 1066 : 26641125 : ex[min_mark] = std::min(ex[min_mark], gradc[c][idof]); 1067 : : } 1068 : : } @@ -1214,7 +1214,7 @@ 1103 : 17634420 : auto max_mark = 2*c*m_ndof_NodalExtrm + 2*idof; 1104 : 17634420 : auto min_mark = max_mark + 1; 1105 : 17634420 : m_uNodalExtrm[bid][max_mark] = - 1106 [ + + ][ + + ]: 18397437 : std::max(g[max_mark], m_uNodalExtrm[bid][max_mark]); + 1106 [ + + ][ + + ]: 18397331 : std::max(g[max_mark], m_uNodalExtrm[bid][max_mark]); 1107 : 17634420 : m_uNodalExtrm[bid][min_mark] = 1108 : 17634420 : std::min(g[min_mark], m_uNodalExtrm[bid][min_mark]); 1109 : : } @@ -1296,7 +1296,7 @@ 1184 : : { 1185 [ + - ]: 186770 : const auto& pesup = tk::cref_find(myGhosts()->m_esup, ip); 1186 [ + + ]: 2641810 : for(auto er : pesup) - 1187 [ + + ]: 2536838 : node_ndof[ip] = std::max(m_ndof[er], node_ndof[ip]); + 1187 [ + + ]: 2536343 : node_ndof[ip] = std::max(m_ndof[er], node_ndof[ip]); 1188 : : } 1189 : : 1190 [ + + ]: 414490 : for(std::size_t e = 0; e < nelem; e++) @@ -1343,7 +1343,7 @@ 1231 : : { 1232 [ + - ]: 186770 : const auto& pesup = tk::cref_find(myGhosts()->m_esup, ip); 1233 [ + + ]: 2641810 : for(auto er : pesup) - 1234 [ + + ]: 2543471 : node_ndof[ip] = std::max(m_ndof[er], node_ndof[ip]); + 1234 [ + + ]: 2541950 : node_ndof[ip] = std::max(m_ndof[er], node_ndof[ip]); 1235 : : } 1236 : : 1237 [ + + ]: 414490 : for(std::size_t e = 0; e < nelem; e++) @@ -1564,11 +1564,11 @@ 1452 : : { 1453 : 291386250 : auto rmark = c*rdof+k; 1454 : 291386250 : auto mark = c*ndof+k; - 1455 [ + + ]: 291386250 : m_u(e, rmark) = rkcoef[0][m_stage] * m_un(e, rmark) + 1455 [ + + ]: 291386250 : m_u(e, rmark) = rkcoef[0][m_stage] * m_un(e, rmark) 1456 : 291386250 : + rkcoef[1][m_stage] * ( m_u(e, rmark) 1457 : 291386250 : + d->Dt() * m_rhs(e, mark)/m_lhs(e, mark) ); - 1458 [ + + ]: 291386250 : if(fabs(m_u(e, rmark)) < 1e-16) - 1459 : 135097092 : m_u(e, rmark) = 0; + 1458 [ + + ]: 291386250 : if(fabs(m_u(e, rmark)) < 1e-16) + 1459 : 135098633 : m_u(e, rmark) = 0; 1460 : : } 1461 : : } 1462 : : } diff --git a/Release/test_coverage/Inciter/DG.hpp.func-sort-c.html b/Release/test_coverage/Inciter/DG.hpp.func-sort-c.html index b4fbf257b721..1cdf91e4fc0f 100644 --- a/Release/test_coverage/Inciter/DG.hpp.func-sort-c.html +++ b/Release/test_coverage/Inciter/DG.hpp.func-sort-c.html @@ -33,7 +33,7 @@ - + @@ -73,11 +73,11 @@ - + - + diff --git a/Release/test_coverage/Inciter/DG.hpp.func.html b/Release/test_coverage/Inciter/DG.hpp.func.html index a0839dfe28bf..57c58921cc81 100644 --- a/Release/test_coverage/Inciter/DG.hpp.func.html +++ b/Release/test_coverage/Inciter/DG.hpp.func.html @@ -33,7 +33,7 @@ - + @@ -73,11 +73,11 @@ - + - + diff --git a/Release/test_coverage/Inciter/DG.hpp.gcov.html b/Release/test_coverage/Inciter/DG.hpp.gcov.html index b08338a6678c..4587607e363e 100644 --- a/Release/test_coverage/Inciter/DG.hpp.gcov.html +++ b/Release/test_coverage/Inciter/DG.hpp.gcov.html @@ -33,7 +33,7 @@ - + @@ -152,7 +152,7 @@ 78 : : #endif 79 : : //! Migrate constructor 80 : : // cppcheck-suppress uninitMemberVar - 81 : 10280 : explicit DG( CkMigrateMessage* msg ) : CBase_DG( msg ) {} + 81 : 10098 : explicit DG( CkMigrateMessage* msg ) : CBase_DG( msg ) {} 82 : : #if defined(__clang__) 83 : : #pragma clang diagnostic pop 84 : : #endif @@ -299,56 +299,56 @@ 225 : : ///@{ 226 : : //! \brief Pack/Unpack serialize member function 227 : : //! \param[in,out] p Charm++'s PUP::er serializer object reference - 228 : 15976 : void pup( PUP::er &p ) override { - 229 : 15976 : p | m_disc; - 230 : 15976 : p | m_ghosts; - 231 : 15976 : p | m_ndof_NodalExtrm; - 232 : 15976 : p | m_nsol; - 233 : 15976 : p | m_ninitsol; - 234 : 15976 : p | m_nlim; - 235 : 15976 : p | m_nnod; - 236 : 15976 : p | m_nrefine; - 237 : 15976 : p | m_nsmooth; - 238 : 15976 : p | m_nreco; - 239 : 15976 : p | m_nnodalExtrema; - 240 : 15976 : p | m_u; - 241 : 15976 : p | m_un; - 242 : 15976 : p | m_p; - 243 : 15976 : p | m_geoElem; - 244 : 15976 : p | m_lhs; - 245 : 15976 : p | m_mtInv; - 246 : 15976 : p | m_uNodalExtrm; - 247 : 15976 : p | m_pNodalExtrm; - 248 : 15976 : p | m_uNodalExtrmc; - 249 : 15976 : p | m_pNodalExtrmc; - 250 : 15976 : p | m_rhs; - 251 : 15976 : p | m_rhsprev; - 252 : 15976 : p | m_stiffrhs; - 253 : 15976 : p | m_stiffrhsprev; - 254 : 15976 : p | m_stiffEqIdx; - 255 : 15976 : p | m_nonStiffEqIdx; - 256 : 15976 : p | m_nstiffeq; - 257 : 15976 : p | m_nnonstiffeq; - 258 : 15976 : p | m_npoin; + 228 : 15703 : void pup( PUP::er &p ) override { + 229 : 15703 : p | m_disc; + 230 : 15703 : p | m_ghosts; + 231 : 15703 : p | m_ndof_NodalExtrm; + 232 : 15703 : p | m_nsol; + 233 : 15703 : p | m_ninitsol; + 234 : 15703 : p | m_nlim; + 235 : 15703 : p | m_nnod; + 236 : 15703 : p | m_nrefine; + 237 : 15703 : p | m_nsmooth; + 238 : 15703 : p | m_nreco; + 239 : 15703 : p | m_nnodalExtrema; + 240 : 15703 : p | m_u; + 241 : 15703 : p | m_un; + 242 : 15703 : p | m_p; + 243 : 15703 : p | m_geoElem; + 244 : 15703 : p | m_lhs; + 245 : 15703 : p | m_mtInv; + 246 : 15703 : p | m_uNodalExtrm; + 247 : 15703 : p | m_pNodalExtrm; + 248 : 15703 : p | m_uNodalExtrmc; + 249 : 15703 : p | m_pNodalExtrmc; + 250 : 15703 : p | m_rhs; + 251 : 15703 : p | m_rhsprev; + 252 : 15703 : p | m_stiffrhs; + 253 : 15703 : p | m_stiffrhsprev; + 254 : 15703 : p | m_stiffEqIdx; + 255 : 15703 : p | m_nonStiffEqIdx; + 256 : 15703 : p | m_nstiffeq; + 257 : 15703 : p | m_nnonstiffeq; + 258 : 15703 : p | m_npoin; 259 : : p | m_diag; - 260 : 15976 : p | m_stage; - 261 : 15976 : p | m_ndof; - 262 : 15976 : p | m_numEqDof; + 260 : 15703 : p | m_stage; + 261 : 15703 : p | m_ndof; + 262 : 15703 : p | m_numEqDof; 263 : : p | m_uc; 264 : : p | m_pc; 265 : : p | m_ndofc; 266 : : p | m_initial; - 267 : 15976 : p | m_uElemfields; - 268 : 15976 : p | m_pElemfields; - 269 : 15976 : p | m_uNodefields; - 270 : 15976 : p | m_pNodefields; - 271 : 15976 : p | m_uNodefieldsc; - 272 : 15976 : p | m_pNodefieldsc; - 273 : 15976 : p | m_outmesh; - 274 : 15976 : p | m_boxelems; - 275 : 15976 : p | m_shockmarker; - 276 : 15976 : p | m_rho0mat; - 277 : 15976 : } + 267 : 15703 : p | m_uElemfields; + 268 : 15703 : p | m_pElemfields; + 269 : 15703 : p | m_uNodefields; + 270 : 15703 : p | m_pNodefields; + 271 : 15703 : p | m_uNodefieldsc; + 272 : 15703 : p | m_pNodefieldsc; + 273 : 15703 : p | m_outmesh; + 274 : 15703 : p | m_boxelems; + 275 : 15703 : p | m_shockmarker; + 276 : 15703 : p | m_rho0mat; + 277 : 15703 : } 278 : : //! \brief Pack/Unpack serialize operator| 279 : : //! \param[in,out] p Charm++'s PUP::er serializer object reference 280 : : //! \param[in,out] i DG object reference diff --git a/Release/test_coverage/Inciter/DiagReducer.cpp.func-sort-c.html b/Release/test_coverage/Inciter/DiagReducer.cpp.func-sort-c.html index 8065fde62aa1..982a24bf2953 100644 --- a/Release/test_coverage/Inciter/DiagReducer.cpp.func-sort-c.html +++ b/Release/test_coverage/Inciter/DiagReducer.cpp.func-sort-c.html @@ -33,7 +33,7 @@ - + @@ -73,11 +73,11 @@ - + - +
  1
-  2
-  3
-  4
-  5
-  6
-  7
-  8
-  9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
- 37
- 38
- 39
- 40
- 41
- 42
- 43
- 44
- 45
- 46
- 47
- 48
- 49
- 50
- 51
- 52
- 53
- 54
- 55
- 56
- 57
- 58
- 59
- 60
- 61
- 62
- 63
- 64
- 65
- 66
- 67
- 68
- 69
- 70
- 71
- 72
- 73
- 74
- 75
- 76
- 77
- 78
- 79
- 80
- 81
- 82
- 83
- 84
- 85
- 86
- 87
- 88
- 89
- 90
- 91
- 92
- 93
- 94
- 95
- 96
- 97
- 98
- 99
-100
-101
-102
-103
-104
-105
-106
-107
-108
-109
-110
-111
-112
-113
-114
-115
-116
-117
-118
-119
-120
-121
-122
-123
// *****************************************************************************
+
   1
+   2
+   3
+   4
+   5
+   6
+   7
+   8
+   9
+  10
+  11
+  12
+  13
+  14
+  15
+  16
+  17
+  18
+  19
+  20
+  21
+  22
+  23
+  24
+  25
+  26
+  27
+  28
+  29
+  30
+  31
+  32
+  33
+  34
+  35
+  36
+  37
+  38
+  39
+  40
+  41
+  42
+  43
+  44
+  45
+  46
+  47
+  48
+  49
+  50
+  51
+  52
+  53
+  54
+  55
+  56
+  57
+  58
+  59
+  60
+  61
+  62
+  63
+  64
+  65
+  66
+  67
+  68
+  69
+  70
+  71
+  72
+  73
+  74
+  75
+  76
+  77
+  78
+  79
+  80
+  81
+  82
+  83
+  84
+  85
+  86
+  87
+  88
+  89
+  90
+  91
+  92
+  93
+  94
+  95
+  96
+  97
+  98
+  99
+ 100
+ 101
+ 102
+ 103
+ 104
+ 105
+ 106
+ 107
+ 108
+ 109
+ 110
+ 111
+ 112
+ 113
+ 114
+ 115
+ 116
+ 117
+ 118
+ 119
+ 120
+ 121
+ 122
+ 123
+ 124
+ 125
+ 126
+ 127
+ 128
+ 129
+ 130
+ 131
+ 132
+ 133
+ 134
+ 135
+ 136
+ 137
+ 138
+ 139
+ 140
+ 141
+ 142
+ 143
+ 144
+ 145
+ 146
+ 147
+ 148
+ 149
+ 150
+ 151
+ 152
+ 153
+ 154
+ 155
+ 156
+ 157
+ 158
+ 159
+ 160
+ 161
+ 162
+ 163
+ 164
+ 165
+ 166
+ 167
+ 168
+ 169
+ 170
+ 171
+ 172
+ 173
+ 174
+ 175
+ 176
+ 177
+ 178
+ 179
+ 180
+ 181
+ 182
+ 183
+ 184
+ 185
+ 186
+ 187
+ 188
+ 189
+ 190
+ 191
+ 192
+ 193
+ 194
+ 195
+ 196
+ 197
+ 198
+ 199
+ 200
+ 201
+ 202
+ 203
+ 204
+ 205
+ 206
+ 207
+ 208
+ 209
+ 210
+ 211
+ 212
+ 213
+ 214
+ 215
+ 216
+ 217
+ 218
+ 219
+ 220
+ 221
+ 222
+ 223
+ 224
+ 225
+ 226
+ 227
+ 228
+ 229
+ 230
+ 231
+ 232
+ 233
+ 234
+ 235
+ 236
+ 237
+ 238
+ 239
+ 240
+ 241
+ 242
+ 243
+ 244
+ 245
+ 246
+ 247
+ 248
+ 249
+ 250
+ 251
+ 252
+ 253
+ 254
+ 255
+ 256
+ 257
+ 258
+ 259
+ 260
+ 261
+ 262
+ 263
+ 264
+ 265
+ 266
+ 267
+ 268
+ 269
+ 270
+ 271
+ 272
+ 273
+ 274
+ 275
+ 276
+ 277
+ 278
+ 279
+ 280
+ 281
+ 282
+ 283
+ 284
+ 285
+ 286
+ 287
+ 288
+ 289
+ 290
+ 291
+ 292
+ 293
+ 294
+ 295
+ 296
+ 297
+ 298
+ 299
+ 300
+ 301
+ 302
+ 303
+ 304
+ 305
+ 306
+ 307
+ 308
+ 309
+ 310
+ 311
+ 312
+ 313
+ 314
+ 315
+ 316
+ 317
+ 318
+ 319
+ 320
+ 321
+ 322
+ 323
+ 324
+ 325
+ 326
+ 327
+ 328
+ 329
+ 330
+ 331
+ 332
+ 333
+ 334
+ 335
+ 336
+ 337
+ 338
+ 339
+ 340
+ 341
+ 342
+ 343
+ 344
+ 345
+ 346
+ 347
+ 348
+ 349
+ 350
+ 351
+ 352
+ 353
+ 354
+ 355
+ 356
+ 357
+ 358
+ 359
+ 360
+ 361
+ 362
+ 363
+ 364
+ 365
+ 366
+ 367
+ 368
+ 369
+ 370
+ 371
+ 372
+ 373
+ 374
+ 375
+ 376
+ 377
+ 378
+ 379
+ 380
+ 381
+ 382
+ 383
+ 384
+ 385
+ 386
+ 387
+ 388
+ 389
+ 390
+ 391
+ 392
+ 393
+ 394
+ 395
+ 396
+ 397
+ 398
+ 399
+ 400
+ 401
+ 402
+ 403
+ 404
+ 405
+ 406
+ 407
+ 408
+ 409
+ 410
+ 411
+ 412
+ 413
+ 414
+ 415
+ 416
+ 417
+ 418
+ 419
+ 420
+ 421
+ 422
+ 423
+ 424
+ 425
+ 426
+ 427
+ 428
+ 429
+ 430
+ 431
+ 432
+ 433
+ 434
+ 435
+ 436
+ 437
+ 438
+ 439
+ 440
+ 441
+ 442
+ 443
+ 444
+ 445
+ 446
+ 447
+ 448
+ 449
+ 450
+ 451
+ 452
+ 453
+ 454
+ 455
+ 456
+ 457
+ 458
+ 459
+ 460
+ 461
+ 462
+ 463
+ 464
+ 465
+ 466
+ 467
+ 468
+ 469
+ 470
+ 471
+ 472
+ 473
+ 474
+ 475
+ 476
+ 477
+ 478
+ 479
+ 480
+ 481
+ 482
+ 483
+ 484
+ 485
+ 486
+ 487
+ 488
+ 489
+ 490
+ 491
+ 492
+ 493
+ 494
+ 495
+ 496
+ 497
+ 498
+ 499
+ 500
+ 501
+ 502
+ 503
+ 504
+ 505
+ 506
+ 507
+ 508
+ 509
+ 510
+ 511
+ 512
+ 513
+ 514
+ 515
+ 516
+ 517
+ 518
+ 519
+ 520
+ 521
+ 522
+ 523
+ 524
+ 525
+ 526
+ 527
+ 528
+ 529
+ 530
+ 531
+ 532
+ 533
+ 534
+ 535
+ 536
+ 537
+ 538
+ 539
+ 540
+ 541
+ 542
+ 543
+ 544
+ 545
+ 546
+ 547
+ 548
+ 549
+ 550
+ 551
+ 552
+ 553
+ 554
+ 555
+ 556
+ 557
+ 558
+ 559
+ 560
+ 561
+ 562
+ 563
+ 564
+ 565
+ 566
+ 567
+ 568
+ 569
+ 570
+ 571
+ 572
+ 573
+ 574
+ 575
+ 576
+ 577
+ 578
+ 579
+ 580
+ 581
+ 582
+ 583
+ 584
+ 585
+ 586
+ 587
+ 588
+ 589
+ 590
+ 591
+ 592
+ 593
+ 594
+ 595
+ 596
+ 597
+ 598
+ 599
+ 600
+ 601
+ 602
+ 603
+ 604
+ 605
+ 606
+ 607
+ 608
+ 609
+ 610
+ 611
+ 612
+ 613
+ 614
+ 615
+ 616
+ 617
+ 618
+ 619
+ 620
+ 621
+ 622
+ 623
+ 624
+ 625
+ 626
+ 627
+ 628
+ 629
+ 630
+ 631
+ 632
+ 633
+ 634
+ 635
+ 636
+ 637
+ 638
+ 639
+ 640
+ 641
+ 642
+ 643
+ 644
+ 645
+ 646
+ 647
+ 648
+ 649
+ 650
+ 651
+ 652
+ 653
+ 654
+ 655
+ 656
+ 657
+ 658
+ 659
+ 660
+ 661
+ 662
+ 663
+ 664
+ 665
+ 666
+ 667
+ 668
+ 669
+ 670
+ 671
+ 672
+ 673
+ 674
+ 675
+ 676
+ 677
+ 678
+ 679
+ 680
+ 681
+ 682
+ 683
+ 684
+ 685
+ 686
+ 687
+ 688
+ 689
+ 690
+ 691
+ 692
+ 693
+ 694
+ 695
+ 696
+ 697
+ 698
+ 699
+ 700
+ 701
+ 702
+ 703
+ 704
+ 705
+ 706
+ 707
+ 708
+ 709
+ 710
+ 711
+ 712
+ 713
+ 714
+ 715
+ 716
+ 717
+ 718
+ 719
+ 720
+ 721
+ 722
+ 723
+ 724
+ 725
+ 726
+ 727
+ 728
+ 729
+ 730
+ 731
+ 732
+ 733
+ 734
+ 735
+ 736
+ 737
+ 738
+ 739
+ 740
+ 741
+ 742
+ 743
+ 744
+ 745
+ 746
+ 747
+ 748
+ 749
+ 750
+ 751
+ 752
+ 753
+ 754
+ 755
+ 756
+ 757
+ 758
+ 759
+ 760
+ 761
+ 762
+ 763
+ 764
+ 765
+ 766
+ 767
+ 768
+ 769
+ 770
+ 771
+ 772
+ 773
+ 774
+ 775
+ 776
+ 777
+ 778
+ 779
+ 780
+ 781
+ 782
+ 783
+ 784
+ 785
+ 786
+ 787
+ 788
+ 789
+ 790
+ 791
+ 792
+ 793
+ 794
+ 795
+ 796
+ 797
+ 798
+ 799
+ 800
+ 801
+ 802
+ 803
+ 804
+ 805
+ 806
+ 807
+ 808
+ 809
+ 810
+ 811
+ 812
+ 813
+ 814
+ 815
+ 816
+ 817
+ 818
+ 819
+ 820
+ 821
+ 822
+ 823
+ 824
+ 825
+ 826
+ 827
+ 828
+ 829
+ 830
+ 831
+ 832
+ 833
+ 834
+ 835
+ 836
+ 837
+ 838
+ 839
+ 840
+ 841
+ 842
+ 843
+ 844
+ 845
+ 846
+ 847
+ 848
+ 849
+ 850
+ 851
+ 852
+ 853
+ 854
+ 855
+ 856
+ 857
+ 858
+ 859
+ 860
+ 861
+ 862
+ 863
+ 864
+ 865
+ 866
+ 867
+ 868
+ 869
+ 870
+ 871
+ 872
+ 873
+ 874
+ 875
+ 876
+ 877
+ 878
+ 879
+ 880
+ 881
+ 882
+ 883
+ 884
+ 885
+ 886
+ 887
+ 888
+ 889
+ 890
+ 891
+ 892
+ 893
+ 894
+ 895
+ 896
+ 897
+ 898
+ 899
+ 900
+ 901
+ 902
+ 903
+ 904
+ 905
+ 906
+ 907
+ 908
+ 909
+ 910
+ 911
+ 912
+ 913
+ 914
+ 915
+ 916
+ 917
+ 918
+ 919
+ 920
+ 921
+ 922
+ 923
+ 924
+ 925
+ 926
+ 927
+ 928
+ 929
+ 930
+ 931
+ 932
+ 933
+ 934
+ 935
+ 936
+ 937
+ 938
+ 939
+ 940
+ 941
+ 942
+ 943
+ 944
+ 945
+ 946
+ 947
+ 948
+ 949
+ 950
+ 951
+ 952
+ 953
+ 954
+ 955
+ 956
+ 957
+ 958
+ 959
+ 960
+ 961
+ 962
+ 963
+ 964
+ 965
+ 966
+ 967
+ 968
+ 969
+ 970
+ 971
+ 972
+ 973
+ 974
+ 975
+ 976
+ 977
+ 978
+ 979
+ 980
+ 981
+ 982
+ 983
+ 984
+ 985
+ 986
+ 987
+ 988
+ 989
+ 990
+ 991
+ 992
+ 993
+ 994
+ 995
+ 996
+ 997
+ 998
+ 999
+1000
+1001
+1002
+1003
+1004
+1005
+1006
+1007
+1008
+1009
+1010
+1011
+1012
+1013
+1014
+1015
+1016
+1017
+1018
+1019
+1020
+1021
+1022
+1023
+1024
+1025
+1026
+1027
+1028
+1029
+1030
+1031
+1032
+1033
+1034
+1035
+1036
+1037
+1038
+1039
+1040
+1041
+1042
+1043
+1044
+1045
+1046
+1047
+1048
+1049
+1050
+1051
+1052
+1053
+1054
+1055
+1056
+1057
+1058
+1059
+1060
+1061
+1062
+1063
+1064
+1065
+1066
+1067
+1068
+1069
+1070
+1071
+1072
+1073
+1074
+1075
+1076
+1077
+1078
+1079
+1080
+1081
+1082
+1083
+1084
+1085
+1086
+1087
+1088
+1089
+1090
+1091
+1092
+1093
+1094
+1095
+1096
+1097
+1098
+1099
+1100
+1101
+1102
+1103
+1104
+1105
+1106
+1107
+1108
+1109
+1110
+1111
+1112
+1113
+1114
+1115
+1116
+1117
+1118
+1119
+1120
+1121
+1122
+1123
+1124
+1125
+1126
+1127
+1128
+1129
+1130
+1131
+1132
+1133
+1134
+1135
+1136
+1137
+1138
+1139
+1140
+1141
+1142
+1143
+1144
+1145
+1146
+1147
+1148
+1149
+1150
+1151
+1152
+1153
+1154
+1155
+1156
+1157
+1158
+1159
+1160
+1161
+1162
+1163
+1164
+1165
+1166
+1167
+1168
+1169
+1170
+1171
+1172
+1173
+1174
+1175
+1176
+1177
+1178
+1179
+1180
+1181
+1182
+1183
+1184
+1185
+1186
+1187
+1188
+1189
+1190
+1191
+1192
+1193
+1194
+1195
+1196
+1197
+1198
+1199
+1200
+1201
+1202
+1203
+1204
+1205
+1206
+1207
+1208
+1209
+1210
+1211
+1212
+1213
+1214
+1215
+1216
+1217
+1218
+1219
+1220
+1221
+1222
+1223
+1224
+1225
+1226
+1227
+1228
+1229
+1230
+1231
+1232
+1233
+1234
+1235
+1236
+1237
+1238
+1239
+1240
+1241
+1242
+1243
+1244
+1245
+1246
+1247
+1248
+1249
+1250
+1251
+1252
+1253
+1254
+1255
+1256
+1257
+1258
+1259
+1260
+1261
+1262
+1263
+1264
+1265
+1266
+1267
+1268
+1269
+1270
+1271
+1272
+1273
+1274
+1275
+1276
+1277
+1278
+1279
+1280
+1281
+1282
+1283
+1284
+1285
+1286
+1287
+1288
+1289
+1290
+1291
+1292
+1293
+1294
+1295
+1296
+1297
+1298
+1299
+1300
+1301
+1302
+1303
+1304
+1305
+1306
+1307
+1308
+1309
+1310
+1311
+1312
+1313
+1314
+1315
+1316
+1317
+1318
+1319
+1320
+1321
+1322
+1323
+1324
+1325
+1326
+1327
+1328
+1329
+1330
+1331
+1332
+1333
+1334
+1335
+1336
+1337
+1338
+1339
+1340
+1341
+1342
+1343
+1344
+1345
+1346
+1347
+1348
+1349
+1350
+1351
+1352
+1353
+1354
+1355
+1356
+1357
+1358
+1359
+1360
+1361
+1362
+1363
+1364
+1365
+1366
+1367
+1368
+1369
+1370
+1371
+1372
+1373
+1374
+1375
+1376
+1377
+1378
+1379
+1380
+1381
+1382
+1383
+1384
+1385
+1386
+1387
+1388
+1389
+1390
+1391
+1392
+1393
+1394
+1395
+1396
+1397
+1398
+1399
+1400
+1401
+1402
+1403
+1404
+1405
+1406
+1407
+1408
+1409
+1410
+1411
+1412
+1413
+1414
+1415
+1416
+1417
+1418
+1419
+1420
+1421
+1422
+1423
+1424
+1425
+1426
+1427
+1428
+1429
+1430
+1431
+1432
+1433
+1434
+1435
+1436
+1437
+1438
+1439
+1440
+1441
+1442
+1443
+1444
+1445
+1446
+1447
+1448
+1449
+1450
+1451
+1452
+1453
+1454
+1455
+1456
+1457
+1458
+1459
+1460
+1461
+1462
+1463
+1464
+1465
+1466
+1467
+1468
+1469
+1470
+1471
+1472
+1473
+1474
+1475
+1476
+1477
+1478
+1479
+1480
+1481
+1482
+1483
+1484
+1485
+1486
+1487
+1488
+1489
+1490
+1491
+1492
+1493
+1494
+1495
+1496
+1497
+1498
+1499
+1500
+1501
+1502
+1503
+1504
+1505
+1506
+1507
+1508
+1509
+1510
+1511
+1512
+1513
+1514
+1515
+1516
+1517
+1518
+1519
+1520
+1521
+1522
+1523
+1524
+1525
+1526
+1527
+1528
+1529
+1530
+1531
+1532
+1533
+1534
+1535
+1536
+1537
+1538
+1539
+1540
+1541
+1542
+1543
+1544
+1545
+1546
+1547
+1548
+1549
+1550
+1551
+1552
+1553
+1554
+1555
+1556
+1557
+1558
+1559
+1560
+1561
+1562
+1563
+1564
+1565
+1566
+1567
+1568
+1569
+1570
+1571
+1572
+1573
+1574
+1575
+1576
+1577
+1578
+1579
+1580
+1581
+1582
+1583
+1584
+1585
+1586
+1587
+1588
+1589
+1590
+1591
+1592
+1593
+1594
+1595
+1596
+1597
+1598
+1599
+1600
+1601
+1602
+1603
+1604
+1605
+1606
+1607
+1608
+1609
+1610
+1611
+1612
+1613
// *****************************************************************************
 /*!
-  \file      src/PDE/ConfigureTransport.cpp
+  \file      src/PDE/CompFlow/CGCompFlow.hpp
   \copyright 2012-2015 J. Bakosi,
              2016-2018 Los Alamos National Security, LLC.,
              2019-2021 Triad National Security, LLC.
              All rights reserved. See the LICENSE file for details.
-  \brief     Register and compile configuration on the transport PDE
-  \details   Register and compile configuration on the transport PDE.
-*/
-// *****************************************************************************
-
-#include <set>
-#include <map>
-#include <vector>
-#include <string>
-
-#include <brigand/algorithms/for_each.hpp>
-
-#include "Tags.hpp"
-#include "CartesianProduct.hpp"
-#include "PDEFactory.hpp"
-#include "Inciter/Options/PDE.hpp"
-#include "ContainerUtil.hpp"
-#include "ConfigureTransport.hpp"
-#include "Transport/Physics/CG.hpp"
-#include "Transport/Physics/DG.hpp"
-#include "Transport/CGTransport.hpp"
-#include "Transport/DGTransport.hpp"
-#include "Transport/Problem.hpp"
-
-namespace inciter {
+  \brief     Compressible single-material flow using continuous Galerkin
+  \details   This file implements the physics operators governing compressible
+    single-material flow using continuous Galerkin discretization.
+*/
+// *****************************************************************************
+#ifndef CGCompFlow_h
+#define CGCompFlow_h
+
+#include <cmath>
+#include <algorithm>
+#include <unordered_set>
+#include <unordered_map>
+
+#include "DerivedData.hpp"
+#include "Exception.hpp"
+#include "Vector.hpp"
+#include "Mesh/Around.hpp"
+#include "Reconstruction.hpp"
+#include "Problem/FieldOutput.hpp"
+#include "Problem/BoxInitialization.hpp"
+#include "Riemann/Rusanov.hpp"
+#include "NodeBC.hpp"
+#include "EoS/EOS.hpp"
+#include "History.hpp"
+#include "Table.hpp"
 
-void
-registerTransport( CGFactory& cf,
-                   DGFactory& df,
-                   std::set< ctr::PDEType >& cgt,
-                   std::set< ctr::PDEType >& dgt )
-// *****************************************************************************
-// Register transport PDE into PDE factory
-//! \param[in,out] cf Continuous Galerkin PDE factory to register to
-//! \param[in,out] df Discontinuous Galerkin PDE factory to register to
-//! \param[in,out] cgt Counters for equation types registered into CG factory
-//! \param[in,out] dgt Counters for equation types registered into DG factory
-// *****************************************************************************
-{
-  // Construct vector of vectors for all possible policies
-  using CGTransportPolicies =
-    tk::cartesian_product< cg::TransportPhysics, TransportProblems >;
-  // Register PDEs for all combinations of policies
-  brigand::for_each< CGTransportPolicies >(
-    registerCG< cg::Transport >( cf, cgt, ctr::PDEType::TRANSPORT ) );
+namespace inciter {
+
+extern ctr::InputDeck g_inputdeck;
+
+namespace cg {
+
+//! \brief CompFlow used polymorphically with tk::CGPDE
+//! \details The template arguments specify policies and are used to configure
+//!   the behavior of the class. The policies are:
+//!   - Physics - physics configuration, see PDE/CompFlow/Physics.h
+//!   - Problem - problem configuration, see PDE/CompFlow/Problems.h
+//! \note The default physics is Euler, set in inciter::deck::check_compflow()
+template< class Physics, class Problem >
+class CompFlow {
+
+  private:
+    using ncomp_t = tk::ncomp_t;
+    using eq = tag::compflow;
+    using real = tk::real;
 
-  // Construct vector of vectors for all possible policies
-  using DGTransportPolicies =
-    tk::cartesian_product< dg::TransportPhysics, TransportProblems >;
-  // Register PDEs for all combinations of policies
-  brigand::for_each< DGTransportPolicies >(
-    registerDG< dg::Transport >( df, dgt, ctr::PDEType::TRANSPORT ) );
-}
-
-std::vector< std::pair< std::string, std::string > >
-infoTransport( std::map< ctr::PDEType, tk::ncomp_t >& cnt )
-// *****************************************************************************
-//  Return information on the transport PDE
-//! \param[inout] cnt std::map of counters for all PDE types
-//! \return vector of string pairs describing the PDE configuration
-// *****************************************************************************
-{
-  using tk::parameters;
-  using eq = tag::transport;
+    static constexpr std::size_t m_ncomp = 5;
+    static constexpr real muscl_eps = 1.0e-9;
+    static constexpr real muscl_const = 1.0/3.0;
+    static constexpr real muscl_m1 = 1.0 - muscl_const;
+    static constexpr real muscl_p1 = 1.0 + muscl_const;
+
+  public:
+    //! \brief Constructor
+    explicit CompFlow() :
+      m_physics(),
+      m_problem(),
+      m_stagCnf(),
+      m_fr(),
+      m_fp(),
+      m_fu()
+    {
+      Assert( g_inputdeck.get< tag::ncomp >() == m_ncomp,
+       "Number of CompFlow PDE components must be " + std::to_string(m_ncomp) );
 
-  auto c = ++cnt[ ctr::PDEType::TRANSPORT ];       // count eqs
-  --c;  // used to index vectors starting with 0<--- Variable 'c' is assigned a value that is never used.
-
-  std::vector< std::pair< std::string, std::string > > nfo;
-
-  nfo.emplace_back( ctr::PDE().name( ctr::PDEType::TRANSPORT ), "" );
-
-  nfo.emplace_back( "problem", ctr::Problem().name(
-    g_inputdeck.get< eq, tag::problem >() ) );
-
-  auto intsharp = g_inputdeck.get< eq, tag::intsharp >();
-  nfo.emplace_back( "interface sharpening", std::to_string( intsharp ) );
-
-  auto ncomp = g_inputdeck.get< tag::ncomp >();
-  nfo.emplace_back( "number of components", std::to_string( ncomp ) );
-
-  const auto& bc = g_inputdeck.get< tag::bc >();
-  for (const auto& ib : bc) {
-    const auto& bcdir = ib.get< tag::dirichlet >();
-    if (!bcdir.empty())
-      nfo.emplace_back( "Dirichlet boundary [" + std::to_string( ncomp ) + "]",
-        parameters( bcdir ) );
+      // EoS initialization
+      const auto& matprop =
+        g_inputdeck.get< tag::material >();
+      const auto& matidxmap =
+        g_inputdeck.get< tag::matidxmap >();
+      auto mateos = matprop[matidxmap.get< tag::eosidx >()[0]].get<tag::eos>();
+      m_mat_blk.emplace_back( mateos, EqType::compflow, 0 );
+
+      // Boundary condition configurations
+      for (const auto& bci : g_inputdeck.get< tag::bc >()) {
+        // store stag-point coordinates
+        auto& spt = std::get< 0 >(m_stagCnf);
+        spt.insert( spt.end(), bci.get< tag::stag_point >().begin(),
+          bci.get< tag::stag_point >().end() );
+        // store stag-radius
+        std::get< 1 >(m_stagCnf).push_back( bci.get< tag::radius >() );
+        // freestream quantities
+        m_fr = bci.get< tag::density >();
+        m_fp = bci.get< tag::pressure >();
+        m_fu = bci.get< tag::velocity >();
+      }
+    }
 
-    const auto& bcsym = ib.get< tag::symmetry >();
-    if (!bcsym.empty())
-      nfo.emplace_back( "Symmetry boundary [" + std::to_string( ncomp ) + "]",
-        parameters( bcsym ) );
-
-    const auto& bcinlet =
-      ib.get< tag::inlet >();
-    if (!bcinlet.empty())
-      nfo.emplace_back( "Inlet boundary [" + std::to_string( ncomp ) + "]",
-        parameters( bcinlet ) );
-
-    const auto& bcoutlet =
-      ib.get< tag::outlet >();
-    if (!bcoutlet.empty())
-      nfo.emplace_back( "Outlet boundary [" + std::to_string( ncomp ) + "]",
-        parameters( bcoutlet ) );
-
-    const auto& bcextrapolate =
-      ib.get< tag::extrapolate >();
-    if (!bcextrapolate.empty())
-      nfo.emplace_back( "Symmetry boundary [" + std::to_string( ncomp ) + "]",
-        parameters( bcextrapolate ) );
-  }
-
-  return nfo;
-}
-
-}  // inciter::
+    //! Determine nodes that lie inside the user-defined IC box and mesh blocks
+    //! \param[in] coord Mesh node coordinates
+    //! \param[in] inpoel Element node connectivity
+    //! \param[in,out] inbox List of nodes at which box user ICs are set for
+    //!    each IC box
+    //! \param[in] elemblkid Element ids associated with mesh block ids where
+    //!   user ICs are set
+    //! \param[in,out] nodeblkid Node ids associated to mesh block ids, where
+    //!   user ICs are set
+    //! \param[in,out] nuserblk number of mesh blocks where user ICs are set
+    void IcBoxNodes( const tk::UnsMesh::Coords& coord,
+      const std::vector< std::size_t >& inpoel,
+      const std::unordered_map< std::size_t, std::set< std::size_t > >& elemblkid,
+      std::vector< std::unordered_set< std::size_t > >& inbox,
+      std::unordered_map< std::size_t, std::set< std::size_t > >& nodeblkid,
+      std::size_t& nuserblk ) const
+    {
+      const auto& x = coord[0];
+      const auto& y = coord[1];
+      const auto& z = coord[2];
+
+      // Detect if user has configured IC boxes
+      const auto& icbox = g_inputdeck.get<tag::ic, tag::box>();
+      if (!icbox.empty()) {
+        std::size_t bcnt = 0;
+        for (const auto& b : icbox) {   // for all boxes for this eq
+          inbox.emplace_back();
+          std::vector< tk::real > box
+            { b.template get< tag::xmin >(), b.template get< tag::xmax >(),
+              b.template get< tag::ymin >(), b.template get< tag::ymax >(),
+              b.template get< tag::zmin >(), b.template get< tag::zmax >() };
+
+          // Determine orientation of box
+          std::array< tk::real, 3 > b_orientn{{
+            b.template get< tag::orientation >()[0],
+            b.template get< tag::orientation >()[1],
+            b.template get< tag::orientation >()[2] }};
+          std::array< tk::real, 3 > b_centroid{{ 0.5*(box[0]+box[1]),
+            0.5*(box[2]+box[3]), 0.5*(box[4]+box[5]) }};
+
+          const auto eps = std::numeric_limits< tk::real >::epsilon();
+          // Determine which nodes lie in the IC box
+          if ( std::any_of( begin(box), end(box), [=](auto p)
+                            { return abs(p) > eps; } ) )
+          {
+            // Transform box to reference space
+            std::array< tk::real, 3 > b_min{{box[0], box[2], box[4]}};
+            std::array< tk::real, 3 > b_max{{box[1], box[3], box[5]}};
+            tk::movePoint(b_centroid, b_min);
+            tk::movePoint(b_centroid, b_max);
+
+            for (ncomp_t i=0; i<x.size(); ++i) {
+              std::array< tk::real, 3 > node{{ x[i], y[i], z[i] }};
+              // Transform node to reference space of box
+              tk::movePoint(b_centroid, node);
+              tk::rotatePoint({{-b_orientn[0], -b_orientn[1], -b_orientn[2]}},
+                node);
+              if ( node[0]>b_min[0] && node[0]<b_max[0] &&
+                node[1]>b_min[1] && node[1]<b_max[1] &&
+                node[2]>b_min[2] && node[2]<b_max[2] )
+              {
+                inbox[bcnt].insert( i );
+              }
+            }
+          }
+          ++bcnt;
+        }
+      }
+
+      // size IC mesh blocks volume vector
+      const auto& mblks = g_inputdeck.get< tag::ic, tag::meshblock >();
+      // if mesh blocks have been specified for this system
+      if (!mblks.empty()) {
+        std::size_t idMax(0);
+        for (const auto& imb : mblks) {
+          idMax = std::max(idMax, imb.get< tag::blockid >());
+        }
+        // size is idMax+1 since block ids are usually 1-based
+        nuserblk = nuserblk+idMax+1;
+      }
+
+      // determine node set for IC mesh blocks
+      for (const auto& [blid, elset] : elemblkid) {
+        if (!elset.empty()) {
+          auto& ndset = nodeblkid[blid];
+          for (auto ie : elset) {
+            for (std::size_t i=0; i<4; ++i) ndset.insert(inpoel[4*ie+i]);
+          }
+        }
+      }
+    }
+
+    //! Initalize the compressible flow equations, prepare for time integration
+    //! \param[in] coord Mesh node coordinates
+    //! \param[in,out] unk Array of unknowns
+    //! \param[in] t Physical time
+    //! \param[in] V Discrete volume of user-defined IC box
+    //! \param[in] inbox List of nodes at which box user ICs are set (for each
+    //!    box IC)
+    //! \param[in] nodeblkid Node ids associated to mesh block ids, where
+    //!   user ICs are set
+    //! \param[in] blkvols Vector of discrete volumes of each block where user
+    //!   ICs are set
+    void initialize(
+      const std::array< std::vector< real >, 3 >& coord,
+      tk::Fields& unk,
+      real t,
+      real V,
+      const std::vector< std::unordered_set< std::size_t > >& inbox,
+      const std::vector< tk::real >& blkvols,
+      const std::unordered_map< std::size_t, std::set< std::size_t > >&
+        nodeblkid ) const
+    {
+      Assert( coord[0].size() == unk.nunk(), "Size mismatch" );
+
+      const auto& x = coord[0];
+      const auto& y = coord[1];
+      const auto& z = coord[2];
+
+      const auto& ic = g_inputdeck.get< tag::ic >();
+      const auto& icbox = ic.get< tag::box >();
+      const auto& mblks = ic.get< tag::meshblock >();
+
+      const auto eps = 1000.0 * std::numeric_limits< tk::real >::epsilon();
+
+      tk::real bgpre = ic.get< tag::pressure >();
+
+      auto c_v = getmatprop< tag::cv >();
+
+      // Set initial and boundary conditions using problem policy
+      for (ncomp_t i=0; i<x.size(); ++i) {
+        auto s = Problem::initialize( m_ncomp, m_mat_blk, x[i], y[i], z[i], t );
+
+        // initialize the user-defined box IC
+        if (!icbox.empty()) {
+          std::size_t bcnt = 0;
+          for (const auto& b : icbox) { // for all boxes
+            if (inbox.size() > bcnt && inbox[bcnt].find(i) != inbox[bcnt].end())
+            {
+              std::vector< tk::real > box
+              { b.template get< tag::xmin >(), b.template get< tag::xmax >(),
+                b.template get< tag::ymin >(), b.template get< tag::ymax >(),
+                b.template get< tag::zmin >(), b.template get< tag::zmax >() };
+              auto V_ex = (box[1]-box[0]) * (box[3]-box[2]) * (box[5]-box[4]);
+              if (V_ex < eps) V = 1.0;
+              initializeBox<ctr::boxList>( m_mat_blk, V_ex/V,
+                V_ex, t, b, bgpre, c_v, s );
+            }
+            ++bcnt;
+          }
+        }
+
+        // initialize user-defined mesh block ICs
+        for (const auto& b : mblks) { // for all blocks
+          auto blid = b.get< tag::blockid >();
+          auto V_ex = b.get< tag::volume >();
+          if (blid >= blkvols.size()) Throw("Block volume not found");
+          if (nodeblkid.find(blid) != nodeblkid.end()) {
+            const auto& ndset = tk::cref_find(nodeblkid, blid);
+            if (ndset.find(i) != ndset.end()) {
+              initializeBox<ctr::meshblockList>( m_mat_blk,
+                V_ex/blkvols[blid], V_ex, t, b, bgpre, c_v, s );
+            }
+          }
+        }
+
+        unk(i,0) = s[0]; // rho
+        if (stagPoint(x[i],y[i],z[i])) {
+          unk(i,1) = unk(i,2) = unk(i,3) = 0.0;
+        } else {
+          unk(i,1) = s[1]; // rho * u
+          unk(i,2) = s[2]; // rho * v
+          unk(i,3) = s[3]; // rho * w
+        }
+        unk(i,4) = s[4]; // rho * e, e: total = kinetic + internal
+      }
+    }
+
+    //! Query the fluid velocity
+    //! \param[in] u Solution vector of conserved variables
+    //! \param[in,out] v Velocity components
+    void velocity( const tk::Fields& u, tk::UnsMesh::Coords& v ) const {
+      for (std::size_t j=0; j<3; ++j) {
+        // extract momentum
+        v[j] = u.extract_comp( 1+j );
+        Assert( v[j].size() == u.nunk(), "Size mismatch" );
+        // divide by density
+        for (std::size_t i=0; i<u.nunk(); ++i) v[j][i] /= u(i,0);
+      }
+    }
+
+    //! Query the sound speed
+    //! \param[in] U Solution vector of conserved variables
+    //! \param[in,out] s Speed of sound in mesh nodes
+    void soundspeed( const tk::Fields& U, std::vector< tk::real >& s ) const {
+      s.resize( U.nunk() );
+      for (std::size_t i=0; i<U.nunk(); ++i) {
+        auto r  = U(i,0);
+        auto ru = U(i,1);
+        auto rv = U(i,2);
+        auto rw = U(i,3);
+        auto re = U(i,4);
+        auto p = m_mat_blk[0].compute< EOS::pressure >(r, ru/r, rv/r, rw/r, re);
+        s[i] = m_mat_blk[0].compute< EOS::soundspeed >( r, p );
+      }
+    }
+
+    //! Return analytic solution (if defined by Problem) at xi, yi, zi, t
+    //! \param[in] xi X-coordinate
+    //! \param[in] yi Y-coordinate
+    //! \param[in] zi Z-coordinate
+    //! \param[in] t Physical time
+    //! \return Vector of analytic solution at given location and time
+    std::vector< real >
+    analyticSolution( real xi, real yi, real zi, real t ) const
+    { return Problem::analyticSolution( m_ncomp, m_mat_blk, xi, yi, zi, t ); }
+
+    //! Return analytic solution for conserved variables
+    //! \param[in] xi X-coordinate at which to evaluate the analytic solution
+    //! \param[in] yi Y-coordinate at which to evaluate the analytic solution
+    //! \param[in] zi Z-coordinate at which to evaluate the analytic solution
+    //! \param[in] t Physical time at which to evaluate the analytic solution
+    //! \return Vector of analytic solution at given location and time
+    std::vector< tk::real >
+    solution( tk::real xi, tk::real yi, tk::real zi, tk::real t ) const
+    { return Problem::initialize( m_ncomp, m_mat_blk, xi, yi, zi, t ); }
+
+    //! \brief Compute nodal gradients of primitive variables for ALECG along
+    //!   chare-boundary
+    //! \param[in] coord Mesh node coordinates
+    //! \param[in] inpoel Mesh element connectivity
+    //! \param[in] bndel List of elements contributing to chare-boundary nodes
+    //! \param[in] gid Local->global node id map
+    //! \param[in] bid Local chare-boundary node ids (value) associated to
+    //!    global node ids (key)
+    //! \param[in] U Solution vector at recent time step
+    //! \param[in,out] G Nodal gradients of primitive variables
+    //! \details This function only computes local contributions to gradients
+    //!   at chare-boundary nodes. Internal node gradients are calculated as
+    //!   required, and do not need to be stored.
+    void chBndGrad( const std::array< std::vector< real >, 3 >& coord,
+                    const std::vector< std::size_t >& inpoel,
+                    const std::vector< std::size_t >& bndel,
+                    const std::vector< std::size_t >& gid,
+                    const std::unordered_map< std::size_t, std::size_t >& bid,
+                    const tk::Fields& U,
+                    tk::Fields& G ) const
+    {
+      Assert( U.nunk() == coord[0].size(), "Number of unknowns in solution "
+              "vector at recent time step incorrect" );
+
+      // compute gradients of primitive variables in points
+      G.fill( 0.0 );
+
+      // access node cooordinates
+      const auto& x = coord[0];
+      const auto& y = coord[1];
+      const auto& z = coord[2];
+
+      for (auto e : bndel) {  // elements contributing to chare boundary nodes
+        // access node IDs
+        std::size_t N[4] =
+          { inpoel[e*4+0], inpoel[e*4+1], inpoel[e*4+2], inpoel[e*4+3] };
+        // compute element Jacobi determinant, J = 6V
+        real bax = x[N[1]]-x[N[0]];
+        real bay = y[N[1]]-y[N[0]];
+        real baz = z[N[1]]-z[N[0]];
+        real cax = x[N[2]]-x[N[0]];
+        real cay = y[N[2]]-y[N[0]];
+        real caz = z[N[2]]-z[N[0]];
+        real dax = x[N[3]]-x[N[0]];
+        real day = y[N[3]]-y[N[0]];
+        real daz = z[N[3]]-z[N[0]];
+        auto J = tk::triple( bax, bay, baz, cax, cay, caz, dax, day, daz );
+        ErrChk( J > 0, "Element Jacobian non-positive" );
+        auto J24 = J/24.0;
+        // shape function derivatives, nnode*ndim [4][3]
+        real g[4][3];
+        tk::crossdiv( cax, cay, caz, dax, day, daz, J,
+                      g[1][0], g[1][1], g[1][2] );
+        tk::crossdiv( dax, day, daz, bax, bay, baz, J,
+                      g[2][0], g[2][1], g[2][2] );
+        tk::crossdiv( bax, bay, baz, cax, cay, caz, J,
+                      g[3][0], g[3][1], g[3][2] );
+        for (std::size_t i=0; i<3; ++i)
+          g[0][i] = -g[1][i] - g[2][i] - g[3][i];
+        // scatter-add gradient contributions to boundary nodes
+        for (std::size_t a=0; a<4; ++a) {
+          auto i = bid.find( gid[N[a]] );
+          if (i != end(bid)) {
+            real u[5];
+            for (std::size_t b=0; b<4; ++b) {
+              u[0] = U(N[b],0);
+              u[1] = U(N[b],1)/u[0];
+              u[2] = U(N[b],2)/u[0];
+              u[3] = U(N[b],3)/u[0];
+              u[4] = U(N[b],4)/u[0]
+                     - 0.5*(u[1]*u[1] + u[2]*u[2] + u[3]*u[3]);
+              if ( stagPoint(x[N[b]],y[N[b]],z[N[b]]) )
+              {
+                u[1] = u[2] = u[3] = 0.0;
+              }
+              for (std::size_t c=0; c<5; ++c)
+                for (std::size_t j=0; j<3; ++j)
+                  G(i->second,c*3+j) += J24 * g[b][j] * u[c];
+            }
+          }
+        }
+      }
+    }
+
+    //! Compute right hand side for ALECG
+    //! \param[in] t Physical time
+    //! \param[in] coord Mesh node coordinates
+    //! \param[in] inpoel Mesh element connectivity
+    //! \param[in] triinpoel Boundary triangle face connecitivity with local ids
+    //! \param[in] bid Local chare-boundary node ids (value) associated to
+    //!    global node ids (key)
+    //! \param[in] gid Local->glocal node ids
+    //! \param[in] lid Global->local node ids
+    //! \param[in] dfn Dual-face normals
+    //! \param[in] psup Points surrounding points
+    //! \param[in] esup Elements surrounding points
+    //! \param[in] symbctri Vector with 1 at symmetry BC boundary triangles
+    //! \param[in] vol Nodal volumes
+    //! \param[in] edgenode Local node IDs of edges
+    //! \param[in] edgeid Edge ids in the order of access
+    //! \param[in] boxnodes Mesh node ids within user-defined IC boxes
+    //! \param[in] G Nodal gradients for chare-boundary nodes
+    //! \param[in] U Solution vector at recent time step
+    //! \param[in] W Mesh velocity
+    //! \param[in] tp Physical time for each mesh node
+    //! \param[in] V Total box volume
+    //! \param[in,out] R Right-hand side vector computed
+    void rhs( real t,
+              const std::array< std::vector< real >, 3 >& coord,
+              const std::vector< std::size_t >& inpoel,
+              const std::vector< std::size_t >& triinpoel,
+              const std::vector< std::size_t >& gid,
+              const std::unordered_map< std::size_t, std::size_t >& bid,
+              const std::unordered_map< std::size_t, std::size_t >& lid,
+              const std::vector< real >& dfn,
+              const std::pair< std::vector< std::size_t >,
+                               std::vector< std::size_t > >& psup,
+              const std::pair< std::vector< std::size_t >,
+                               std::vector< std::size_t > >& esup,
+              const std::vector< int >& symbctri,
+              const std::vector< real >& vol,
+              const std::vector< std::size_t >& edgenode,
+              const std::vector< std::size_t >& edgeid,
+              const std::vector< std::unordered_set< std::size_t > >& boxnodes,
+              const tk::Fields& G,
+              const tk::Fields& U,
+              const tk::Fields& W,
+              const std::vector< tk::real >& tp,
+              real V,
+              tk::Fields& R ) const
+    {
+      Assert( G.nprop() == m_ncomp*3,
+              "Number of components in gradient vector incorrect" );
+      Assert( U.nunk() == coord[0].size(), "Number of unknowns in solution "
+              "vector at recent time step incorrect" );
+      Assert( R.nunk() == coord[0].size(),
+              "Number of unknowns and/or number of components in right-hand "
+              "side vector incorrect" );
+      Assert( W.nunk() == coord[0].size(), "Size mismatch " );
+
+      // compute/assemble gradients in points
+      auto Grad = nodegrad( coord, inpoel, lid, bid, vol, esup, U, G );
+
+      // zero right hand side for all components
+      for (ncomp_t c=0; c<m_ncomp; ++c) R.fill( c, 0.0 );
+
+      // compute domain-edge integral
+      domainint( coord, gid, edgenode, edgeid, psup, dfn, U, W, Grad, R );
+
+      // compute boundary integrals
+      bndint( coord, triinpoel, symbctri, U, W, R );
+
+      // compute external (energy) sources
+      const auto& icbox = g_inputdeck.get< tag::ic, tag::box >();
+
+      if (!icbox.empty() && !boxnodes.empty()) {
+        std::size_t bcnt = 0;
+        for (const auto& b : icbox) {   // for all boxes for this eq
+          std::vector< tk::real > box
+           { b.template get< tag::xmin >(), b.template get< tag::xmax >(),
+             b.template get< tag::ymin >(), b.template get< tag::ymax >(),
+             b.template get< tag::zmin >(), b.template get< tag::zmax >() };
+
+          const auto& initiate = b.template get< tag::initiate >();
+          if (initiate == ctr::InitiateType::LINEAR) {
+            boxSrc( V, t, inpoel, esup, boxnodes[bcnt], coord, R );
+          }
+          ++bcnt;
+        }
+      }
+
+      // compute optional source integral
+      src( coord, inpoel, t, tp, R );
+    }
+
+    //! Compute overset mesh motion for OversetFE
+//    //! \param[in] t Physical time
+//    //! \param[in] coord Mesh node coordinates
+    //! \param[in] psup Points surrounding points
+    //! \param[in] symbcnodes Symmetry BC node list
+    //! \param[in] uservel User specified constant mesh velocity
+    //! \param[in] U Solution vector at recent time step
+//    //! \param[in,out] meshvel Velocity of each mesh node based on user input
+    //! \param[in,out] movedmesh True/false if mesh moved
+    void getMeshVel(
+      real /*t*/,
+      const std::array< std::vector< real >, 3 >& /*coord*/,
+      const std::pair< std::vector< std::size_t >,
+                       std::vector< std::size_t > >& psup,
+      const std::unordered_set< std::size_t >& symbcnodes,
+      const std::array< tk::real, 3 >& uservel,
+      const tk::Fields& U,
+      tk::Fields& /*meshvel*/,
+      int& movedmesh ) const
+    {
+      //Assert( meshvel.nunk() == U.nunk(),
+      //  "Mesh-velocity vector has incorrect size" );
+
+      auto uvelmag = std::sqrt(tk::dot(uservel, uservel));
+
+      // Check for pressure differential only if mesh has not moved before
+      if (movedmesh == 0 && uvelmag > 1e-8) {
+        for (auto p : symbcnodes) {
+          for (auto q : tk::Around(psup,p)) {
+            // compute pressure difference
+            real rL  = U(p,0);
+            real ruL = U(p,1) / rL;
+            real rvL = U(p,2) / rL;
+            real rwL = U(p,3) / rL;
+            real reL = U(p,4) / rL - 0.5*(ruL*ruL + rvL*rvL + rwL*rwL);
+            real rR  = U(q,0);
+            real ruR = U(q,1) / rR;
+            real rvR = U(q,2) / rR;
+            real rwR = U(q,3) / rR;
+            real reR = U(q,4) / rR - 0.5*(ruR*ruR + rvR*rvR + rwR*rwR);
+            real pL = m_mat_blk[0].compute< EOS::pressure >( rL, ruL/rL, rvL/rL,
+              rwL/rL, reL );
+            real pR = m_mat_blk[0].compute< EOS::pressure >( rR, ruR/rR, rvR/rR,
+              rwR/rR, reR );
+
+            if (std::abs(pR/pL) > 2.0) {
+              movedmesh = 1;
+              break;
+            }
+          }
+          if (movedmesh) break;
+        }
+      }
+    }
+
+    //! Compute the minimum time step size (for unsteady time stepping)
+    //! \param[in] coord Mesh node coordinates
+    //! \param[in] inpoel Mesh element connectivity
+    //! \param[in] t Physical time
+    //! \param[in] dtn Time step size at the previous time step
+    //! \param[in] U Solution vector at recent time step
+    //! \param[in] vol Nodal volume (with contributions from other chares)
+    //! \param[in] voln Nodal volume (with contributions from other chares) at
+    //!   the previous time step
+    //! \return Minimum time step size
+    real dt( const std::array< std::vector< real >, 3 >& coord,
+             const std::vector< std::size_t >& inpoel,
+             tk::real t,
+             tk::real dtn,
+             const tk::Fields& U,
+             const std::vector< tk::real >& vol,
+             const std::vector< tk::real >& voln ) const
+    {
+      Assert( U.nunk() == coord[0].size(), "Number of unknowns in solution "
+              "vector at recent time step incorrect" );
+
+      // energy source propagation time and velocity
+      const auto& icbox = g_inputdeck.get< tag::ic, tag::box >();
+
+      const auto& x = coord[0];
+      const auto& y = coord[1];
+      const auto& z = coord[2];
+
+      // ratio of specific heats
+      auto g = getmatprop< tag::gamma >();
+      // compute the minimum dt across all elements we own
+      real mindt = std::numeric_limits< real >::max();
+      for (std::size_t e=0; e<inpoel.size()/4; ++e) {
+        const std::array< std::size_t, 4 > N{{ inpoel[e*4+0], inpoel[e*4+1],
+                                               inpoel[e*4+2], inpoel[e*4+3] }};
+        // compute cubic root of element volume as the characteristic length
+        const std::array< real, 3 >
+          ba{{ x[N[1]]-x[N[0]], y[N[1]]-y[N[0]], z[N[1]]-z[N[0]] }},
+          ca{{ x[N[2]]-x[N[0]], y[N[2]]-y[N[0]], z[N[2]]-z[N[0]] }},
+          da{{ x[N[3]]-x[N[0]], y[N[3]]-y[N[0]], z[N[3]]-z[N[0]] }};
+        const auto L = std::cbrt( tk::triple( ba, ca, da ) / 6.0 );
+        // access solution at element nodes at recent time step
+        std::array< std::array< real, 4 >, m_ncomp > u;
+        for (ncomp_t c=0; c<m_ncomp; ++c) u[c] = U.extract( c, N );
+        // compute the maximum length of the characteristic velocity (fluid
+        // velocity + sound velocity) across the four element nodes
+        real maxvel = 0.0;
+        for (std::size_t j=0; j<4; ++j) {
+          auto& r  = u[0][j];    // rho
+          auto& ru = u[1][j];    // rho * u
+          auto& rv = u[2][j];    // rho * v
+          auto& rw = u[3][j];    // rho * w
+          auto& re = u[4][j];    // rho * e
+          auto p = m_mat_blk[0].compute< EOS::pressure >( r, ru/r, rv/r, rw/r,
+            re );
+          if (p < 0) p = 0.0;
+          auto c = m_mat_blk[0].compute< EOS::soundspeed >( r, p );
+          auto v = std::sqrt((ru*ru + rv*rv + rw*rw)/r/r) + c; // char. velocity
+
+          // energy source propagation velocity (in all IC boxes configured)
+          if (!icbox.empty()) {
+            for (const auto& b : icbox) {   // for all boxes for this eq
+              const auto& initiate = b.template get< tag::initiate >();
+              auto iv = b.template get< tag::front_speed >();
+              if (initiate == ctr::InitiateType::LINEAR) {
+                auto zmin = b.template get< tag::zmin >();
+                auto zmax = b.template get< tag::zmax >();
+                auto wFront = 0.08;
+                auto tInit = 0.0;
+                auto tFinal = tInit + (zmax - zmin - 2.0*wFront) /
+                  std::fabs(iv);
+                if (t >= tInit && t <= tFinal)
+                  v = std::max(v, std::fabs(iv));
+              }
+            }
+          }
+
+          if (v > maxvel) maxvel = v;
+        }
+        // compute element dt for the Euler equations
+        auto euler_dt = L / maxvel;
+        // compute element dt based on the viscous force
+        auto viscous_dt = m_physics.viscous_dt( L, u );
+        // compute element dt based on thermal diffusion
+        auto conduct_dt = m_physics.conduct_dt( L, g, u );
+        // compute minimum element dt
+        auto elemdt = std::min( euler_dt, std::min( viscous_dt, conduct_dt ) );
+        // find minimum dt across all elements
+        mindt = std::min( elemdt, mindt );
+      }
+      mindt *= g_inputdeck.get< tag::cfl >();
+
+      // compute the minimum dt across all nodes we contribute to due to volume
+      // change in time
+      auto dvcfl = g_inputdeck.get< tag::ale, tag::dvcfl >();
+      if (dtn > 0.0 && dvcfl > 0.0) {
+        Assert( vol.size() == voln.size(), "Size mismatch" );
+        for (std::size_t p=0; p<vol.size(); ++p) {
+          auto vol_dt = dtn *
+            std::min(voln[p],vol[p]) / std::abs(voln[p]-vol[p]+1.0e-14);
+          mindt = std::min( vol_dt, mindt );
+        }
+        mindt *= dvcfl;
+      }
+
+      return mindt;
+    }
+
+    //! Compute a time step size for each mesh node (for steady time stepping)
+    //! \param[in] U Solution vector at recent time step
+    //! \param[in] vol Nodal volume (with contributions from other chares)
+    //! \param[in,out] dtp Time step size for each mesh node
+    void dt( uint64_t,
+             const std::vector< tk::real >& vol,
+             const tk::Fields& U,
+             std::vector< tk::real >& dtp ) const
+    {
+      for (std::size_t i=0; i<U.nunk(); ++i) {
+        // compute cubic root of element volume as the characteristic length
+        const auto L = std::cbrt( vol[i] );
+        // access solution at node p at recent time step
+        const auto u = U[i];
+        // compute pressure
+        auto p = m_mat_blk[0].compute< EOS::pressure >( u[0], u[1]/u[0],
+          u[2]/u[0], u[3]/u[0], u[4] );
+        if (p < 0) p = 0.0;
+        auto c = m_mat_blk[0].compute< EOS::soundspeed >( u[0], p );
+        // characteristic velocity
+        auto v = std::sqrt((u[1]*u[1] + u[2]*u[2] + u[3]*u[3])/u[0]/u[0]) + c;
+        // compute dt for node
+        dtp[i] = L / v * g_inputdeck.get< tag::cfl >();
+      }
+    }
+
+    //! \brief Query Dirichlet boundary condition value on a given side set for
+    //!    all components in this PDE system
+    //! \param[in] t Physical time
+    //! \param[in] deltat Time step size
+    //! \param[in] tp Physical time for each mesh node
+    //! \param[in] dtp Time step size for each mesh node
+    //! \param[in] ss Pair of side set ID and (local) node IDs on the side set
+    //! \param[in] coord Mesh node coordinates
+    //! \param[in] increment If true, evaluate the solution increment between
+    //!   t and t+dt for Dirichlet BCs. If false, evlauate the solution instead.
+    //! \return Vector of pairs of bool and boundary condition value associated
+    //!   to mesh node IDs at which Dirichlet boundary conditions are set. Note
+    //!   that if increment is true, instead of the actual boundary condition
+    //!   value, we return the increment between t+deltat and t, since,
+    //!   depending on client code and solver, that may be what the solution
+    //!   requires.
+    std::map< std::size_t, std::vector< std::pair<bool,real> > >
+    dirbc( real t,
+           real deltat,
+           const std::vector< tk::real >& tp,
+           const std::vector< tk::real >& dtp,
+           const std::pair< const int, std::vector< std::size_t > >& ss,
+           const std::array< std::vector< real >, 3 >& coord,
+           bool increment ) const
+    {
+      using NodeBC = std::vector< std::pair< bool, real > >;
+      std::map< std::size_t, NodeBC > bc;
+
+      // collect sidesets across all meshes
+      std::vector< std::size_t > ubc;
+      for (const auto& ibc : g_inputdeck.get< tag::bc >()) {
+        ubc.insert(ubc.end(), ibc.get< tag::dirichlet >().begin(),
+          ibc.get< tag::dirichlet >().end());
+      }
+
+      const auto steady = g_inputdeck.get< tag::steady_state >();<--- Variable 'steady' is assigned a value that is never used.
+      if (!ubc.empty()) {
+        Assert( ubc.size() > 0, "Indexing out of Dirichlet BC eq-vector" );
+        const auto& x = coord[0];
+        const auto& y = coord[1];
+        const auto& z = coord[2];
+        for (const auto& b : ubc)
+          if (static_cast<int>(b) == ss.first)
+            for (auto n : ss.second) {
+              Assert( x.size() > n, "Indexing out of coordinate array" );
+              if (steady) { t = tp[n]; deltat = dtp[n]; }
+              auto s = increment ?
+                solinc( m_ncomp, m_mat_blk, x[n], y[n], z[n],
+                        t, deltat, Problem::initialize ) :
+                Problem::initialize( m_ncomp, m_mat_blk, x[n], y[n],
+                                     z[n], t+deltat );
+              if ( stagPoint(x[n],y[n],z[n]) ) {
+                s[1] = s[2] = s[3] = 0.0;
+              }
+              bc[n] = {{ {true,s[0]}, {true,s[1]}, {true,s[2]}, {true,s[3]},
+                         {true,s[4]} }};
+            }
+      }
+      return bc;
+    }
+
+    //! Set symmetry boundary conditions at nodes
+    //! \param[in] U Solution vector at recent time step
+    //! \param[in] bnorm Face normals in boundary points, key local node id,
+    //!   first 3 reals of value: unit normal, outer key: side set id
+    //! \param[in] nodes Unique set of node ids at which to set symmetry BCs
+    void
+    symbc( tk::Fields& U,
+           const std::array< std::vector< real >, 3 >&,
+           const std::unordered_map< int,
+             std::unordered_map< std::size_t, std::array< real, 4 > > >& bnorm,
+           const std::unordered_set< std::size_t >& nodes ) const
+    {
+      // collect sidesets across all meshes
+      std::vector< std::size_t > sbc;
+      for (const auto& ibc : g_inputdeck.get< tag::bc >()) {
+        sbc.insert(sbc.end(), ibc.get< tag::symmetry >().begin(),
+          ibc.get< tag::symmetry >().end());
+      }
+
+      if (sbc.size() > 0) {             // use symbcs for this system
+        for (auto p : nodes) {                 // for all symbc nodes
+          // for all user-def symbc sets
+          for (std::size_t s=0; s<sbc.size(); ++s) {
+            // find nodes & normals for side
+            auto j = bnorm.find(static_cast<int>(sbc[s]));
+            if (j != end(bnorm)) {
+              auto i = j->second.find(p);      // find normal for node
+              if (i != end(j->second)) {
+                std::array< real, 3 >
+                  n{ i->second[0], i->second[1], i->second[2] },
+                  v{ U(p,1), U(p,2), U(p,3) };
+                auto v_dot_n = tk::dot( v, n );
+                // symbc: remove normal component of velocity
+                U(p,1) -= v_dot_n * n[0];
+                U(p,2) -= v_dot_n * n[1];
+                U(p,3) -= v_dot_n * n[2];
+              }
+            }
+          }
+        }
+      }
+    }
+
+    //! Set farfield boundary conditions at nodes
+    //! \param[in] U Solution vector at recent time step
+    //! \param[in] bnorm Face normals in boundary points, key local node id,
+    //!   first 3 reals of value: unit normal, outer key: side set id
+    //! \param[in] nodes Unique set of node ids at which to set farfield BCs
+    void
+    farfieldbc(
+      tk::Fields& U,
+      const std::array< std::vector< real >, 3 >&,
+      const std::unordered_map< int,
+        std::unordered_map< std::size_t, std::array< real, 4 > > >& bnorm,
+      const std::unordered_set< std::size_t >& nodes ) const
+    {
+      // collect sidesets across all meshes
+      std::vector< std::size_t > fbc;
+      for (const auto& ibc : g_inputdeck.get< tag::bc >()) {
+        fbc.insert(fbc.end(), ibc.get< tag::farfield >().begin(),
+          ibc.get< tag::farfield >().end());
+      }
+
+      if (fbc.size() > 0)               // use farbcs for this system
+        for (auto p : nodes)                   // for all farfieldbc nodes
+          for (const auto& s : fbc) {// for all user-def farbc sets
+            auto j = bnorm.find(static_cast<int>(s));// find nodes & normals for side
+            if (j != end(bnorm)) {
+              auto i = j->second.find(p);      // find normal for node
+              if (i != end(j->second)) {
+                auto& r  = U(p,0);
+                auto& ru = U(p,1);
+                auto& rv = U(p,2);
+                auto& rw = U(p,3);
+                auto& re = U(p,4);
+                auto vn =
+                  (ru*i->second[0] + rv*i->second[1] + rw*i->second[2]) / r;
+                auto a = m_mat_blk[0].compute< EOS::soundspeed >( r,
+                  m_mat_blk[0].compute< EOS::pressure >( r, ru/r, rv/r, rw/r,
+                  re ) );
+                auto M = vn / a;
+                if (M <= -1.0) {                      // supersonic inflow
+                  r  = m_fr;
+                  ru = m_fr * m_fu[0];
+                  rv = m_fr * m_fu[1];
+                  rw = m_fr * m_fu[2];
+                  re = m_mat_blk[0].compute< EOS::totalenergy >( m_fr,
+                    m_fu[0], m_fu[1], m_fu[2], m_fp );
+                } else if (M > -1.0 && M < 0.0) {     // subsonic inflow
+                  auto pr = m_mat_blk[0].compute< EOS::pressure >
+                                                ( r, ru/r, rv/r, rw/r, re );
+                  r  = m_fr;
+                  ru = m_fr * m_fu[0];
+                  rv = m_fr * m_fu[1];
+                  rw = m_fr * m_fu[2];
+                  re = m_mat_blk[0].compute< EOS::totalenergy >( m_fr,
+                    m_fu[0], m_fu[1], m_fu[2], pr );
+                } else if (M >= 0.0 && M < 1.0) {     // subsonic outflow
+                  re = m_mat_blk[0].compute< EOS::totalenergy >( r, ru/r,
+                    rv/r, rw/r, m_fp );
+                }
+              }
+            }
+          }
+    }
+
+    //! Apply user defined time dependent BCs
+    //! \param[in] t Physical time
+    //! \param[in,out] U Solution vector at recent time step
+    //! \param[in] nodes Vector of unique sets of node ids at which to apply BCs
+    //! \details This function applies user defined time dependent boundary
+    //!   conditions on groups of side sets specified in the input file.
+    //!   The user specifies pressure, density, and velocity as discrete
+    //!   functions of time, in the control file, associated with a group of
+    //!   side sets. Several such groups can be specified, each with their
+    //!   own discrete function: p(t), rho(t), vx(t), vy(t), vz(t).
+    void
+    timedepbc( tk::real t,
+      tk::Fields& U,<--- Parameter 'U' can be declared with const
+      const std::vector< std::unordered_set< std::size_t > >& nodes,
+      const std::vector< tk::Table<5> >& timedepfn ) const
+    {
+      for (std::size_t ib=0; ib<nodes.size(); ++ib) {
+        for (auto p:nodes[ib]) {
+          // sample primitive vars from discrete data at time t
+          auto unk = tk::sample<5>(t, timedepfn[ib]);
+
+          // apply BCs after converting to conserved vars
+          U(p,0) = unk[1];
+          U(p,1) = unk[1]*unk[2];
+          U(p,2) = unk[1]*unk[3];
+          U(p,3) = unk[1]*unk[4];
+          U(p,4) = m_mat_blk[0].compute< EOS::totalenergy >( unk[1], unk[2],
+            unk[3], unk[4], unk[0]);
+        }
+      }
+    }
+
+    //! Return a map that associates user-specified strings to functions
+    //! \return Map that associates user-specified strings to functions that
+    //!   compute relevant quantities to be output to file
+    std::map< std::string, tk::GetVarFn > OutVarFn() const
+    { return CompFlowOutVarFn(); }
+
+    //! Return analytic field names to be output to file
+    //! \return Vector of strings labelling analytic fields output in file
+    std::vector< std::string > analyticFieldNames() const
+    { return m_problem.analyticFieldNames( m_ncomp ); }
+
+    //! Return surface field names to be output to file
+    //! \return Vector of strings labelling surface fields output in file
+    std::vector< std::string > surfNames() const
+    { return CompFlowSurfNames(); }
+
+    //! Return time history field names to be output to file
+    //! \return Vector of strings labelling time history fields output in file
+    std::vector< std::string > histNames() const
+    { return CompFlowHistNames(); }
+
+    //! Return nodal surface field output going to file
+    std::vector< std::vector< real > >
+    surfOutput( const std::map< int, std::vector< std::size_t > >& bnd,
+                const tk::Fields& U ) const
+    { return CompFlowSurfOutput( m_mat_blk, bnd, U ); }
+
+    //! Return elemental surface field output (on triangle faces) going to file
+    std::vector< std::vector< real > >
+    elemSurfOutput( const std::map< int, std::vector< std::size_t > >& bface,
+      const std::vector< std::size_t >& triinpoel,
+      const tk::Fields& U ) const
+    {
+      return CompFlowElemSurfOutput( m_mat_blk, bface, triinpoel, U );
+    }
+
+    //! Return time history field output evaluated at time history points
+    std::vector< std::vector< real > >
+    histOutput( const std::vector< HistData >& h,
+                const std::vector< std::size_t >& inpoel,
+                const tk::Fields& U ) const
+    { return CompFlowHistOutput( m_mat_blk, h, inpoel, U ); }
+
+    //! Return names of integral variables to be output to diagnostics file
+    //! \return Vector of strings labelling integral variables output
+    std::vector< std::string > names() const
+    { return m_problem.names( m_ncomp ); }
+
+  private:
+    const Physics m_physics;            //!< Physics policy
+    const Problem m_problem;            //!< Problem policy
+    //! Stagnation BC user configuration: point coordinates and radii
+    std::tuple< std::vector< real >, std::vector< real > > m_stagCnf;
+    real m_fr;                    //!< Farfield density
+    real m_fp;                    //!< Farfield pressure
+    std::vector< real > m_fu;     //!< Farfield velocity
+    //! EOS material block
+    std::vector< EOS > m_mat_blk;
+
+    //! Decide if point is a stagnation point
+    //! \param[in] x X mesh point coordinates to query
+    //! \param[in] y Y mesh point coordinates to query
+    //! \param[in] z Z mesh point coordinates to query
+    //! \return True if point is configured as a stagnation point by the user
+    #pragma omp declare simd
+    bool
+    stagPoint( real x, real y, real z ) const {
+      const auto& pnt = std::get< 0 >( m_stagCnf );
+      const auto& rad = std::get< 1 >( m_stagCnf );
+      for (std::size_t i=0; i<pnt.size()/3; ++i) {
+        if (tk::length( x-pnt[i*3+0], y-pnt[i*3+1], z-pnt[i*3+2] ) < rad[i])
+          return true;
+      }
+      return false;
+    }
+
+    //! \brief Compute/assemble nodal gradients of primitive variables for
+    //!   ALECG in all points
+    //! \param[in] coord Mesh node coordinates
+    //! \param[in] inpoel Mesh element connectivity
+    //! \param[in] lid Global->local node ids
+    //! \param[in] bid Local chare-boundary node ids (value) associated to
+    //!    global node ids (key)
+    //! \param[in] vol Nodal volumes
+    //! \param[in] esup Elements surrounding points
+    //! \param[in] U Solution vector at recent time step
+    //! \param[in] G Nodal gradients of primitive variables in chare-boundary
+    //!    nodes
+    //! \return Gradients of primitive variables in all mesh points
+    tk::Fields
+    nodegrad( const std::array< std::vector< real >, 3 >& coord,
+              const std::vector< std::size_t >& inpoel,
+              const std::unordered_map< std::size_t, std::size_t >& lid,
+              const std::unordered_map< std::size_t, std::size_t >& bid,
+              const std::vector< real >& vol,
+              const std::pair< std::vector< std::size_t >,
+                               std::vector< std::size_t > >& esup,
+              const tk::Fields& U,
+              const tk::Fields& G ) const
+    {
+      // allocate storage for nodal gradients of primitive variables
+      tk::Fields Grad( U.nunk(), m_ncomp*3 );
+      Grad.fill( 0.0 );
+
+      // access node cooordinates
+      const auto& x = coord[0];
+      const auto& y = coord[1];
+      const auto& z = coord[2];
+
+      // compute gradients of primitive variables in points
+      auto npoin = U.nunk();
+      #pragma omp simd
+      for (std::size_t p=0; p<npoin; ++p)
+        for (auto e : tk::Around(esup,p)) {
+          // access node IDs
+          std::size_t N[4] =
+            { inpoel[e*4+0], inpoel[e*4+1], inpoel[e*4+2], inpoel[e*4+3] };
+          // compute element Jacobi determinant, J = 6V
+          real bax = x[N[1]]-x[N[0]];
+          real bay = y[N[1]]-y[N[0]];
+          real baz = z[N[1]]-z[N[0]];
+          real cax = x[N[2]]-x[N[0]];
+          real cay = y[N[2]]-y[N[0]];
+          real caz = z[N[2]]-z[N[0]];
+          real dax = x[N[3]]-x[N[0]];
+          real day = y[N[3]]-y[N[0]];
+          real daz = z[N[3]]-z[N[0]];
+          auto J = tk::triple( bax, bay, baz, cax, cay, caz, dax, day, daz );
+          auto J24 = J/24.0;
+          // shape function derivatives, nnode*ndim [4][3]
+          real g[4][3];
+          tk::crossdiv( cax, cay, caz, dax, day, daz, J,
+                        g[1][0], g[1][1], g[1][2] );
+          tk::crossdiv( dax, day, daz, bax, bay, baz, J,
+                        g[2][0], g[2][1], g[2][2] );
+          tk::crossdiv( bax, bay, baz, cax, cay, caz, J,
+                        g[3][0], g[3][1], g[3][2] );
+          for (std::size_t i=0; i<3; ++i)
+            g[0][i] = -g[1][i] - g[2][i] - g[3][i];
+          // scatter-add gradient contributions to boundary nodes
+          real u[m_ncomp];
+          for (std::size_t b=0; b<4; ++b) {
+            u[0] = U(N[b],0);
+            u[1] = U(N[b],1)/u[0];
+            u[2] = U(N[b],2)/u[0];
+            u[3] = U(N[b],3)/u[0];
+            u[4] = U(N[b],4)/u[0]
+                   - 0.5*(u[1]*u[1] + u[2]*u[2] + u[3]*u[3]);
+            if ( stagPoint(x[N[b]],y[N[b]],z[N[b]]) )
+            {
+              u[1] = u[2] = u[3] = 0.0;
+            }
+            for (std::size_t c=0; c<m_ncomp; ++c)
+              for (std::size_t i=0; i<3; ++i)
+                Grad(p,c*3+i) += J24 * g[b][i] * u[c];
+          }
+        }
+
+      // put in nodal gradients of chare-boundary points
+      for (const auto& [g,b] : bid) {
+        auto i = tk::cref_find( lid, g );
+        for (ncomp_t c=0; c<Grad.nprop(); ++c)
+          Grad(i,c) = G(b,c);
+      }
+
+      // divide weak result in gradients by nodal volume
+      for (std::size_t p=0; p<npoin; ++p)
+        for (std::size_t c=0; c<m_ncomp*3; ++c)
+          Grad(p,c) /= vol[p];
+
+      return Grad;
+    }
+
+    //! Compute domain-edge integral for ALECG
+    //! \param[in] coord Mesh node coordinates
+    //! \param[in] gid Local->glocal node ids
+    //! \param[in] edgenode Local node ids of edges
+    //! \param[in] edgeid Local node id pair -> edge id map
+    //! \param[in] psup Points surrounding points
+    //! \param[in] dfn Dual-face normals
+    //! \param[in] U Solution vector at recent time step
+    //! \param[in] W Mesh velocity
+    //! \param[in] G Nodal gradients
+    //! \param[in,out] R Right-hand side vector computed
+    void domainint( const std::array< std::vector< real >, 3 >& coord,
+                    const std::vector< std::size_t >& gid,
+                    const std::vector< std::size_t >& edgenode,
+                    const std::vector< std::size_t >& edgeid,
+                    const std::pair< std::vector< std::size_t >,
+                                     std::vector< std::size_t > >& psup,
+                    const std::vector< real >& dfn,
+                    const tk::Fields& U,
+                    const tk::Fields& W,
+                    const tk::Fields& G,
+                    tk::Fields& R ) const
+    {
+      // domain-edge integral: compute fluxes in edges
+      std::vector< real > dflux( edgenode.size()/2 * m_ncomp );
+
+      // access node coordinates
+      const auto& x = coord[0];
+      const auto& y = coord[1];
+      const auto& z = coord[2];
+
+      #pragma omp simd
+      for (std::size_t e=0; e<edgenode.size()/2; ++e) {
+        auto p = edgenode[e*2+0];
+        auto q = edgenode[e*2+1];
+
+        // compute primitive variables at edge-end points
+        real rL  = U(p,0);
+        real ruL = U(p,1) / rL;
+        real rvL = U(p,2) / rL;
+        real rwL = U(p,3) / rL;
+        real reL = U(p,4) / rL - 0.5*(ruL*ruL + rvL*rvL + rwL*rwL);
+        real w1L = W(p,0);
+        real w2L = W(p,1);
+        real w3L = W(p,2);
+        real rR  = U(q,0);
+        real ruR = U(q,1) / rR;
+        real rvR = U(q,2) / rR;
+        real rwR = U(q,3) / rR;
+        real reR = U(q,4) / rR - 0.5*(ruR*ruR + rvR*rvR + rwR*rwR);
+        real w1R = W(q,0);
+        real w2R = W(q,1);
+        real w3R = W(q,2);
+
+        // apply stagnation BCs to primitive variables
+        if ( stagPoint(x[p],y[p],z[p]) )
+          ruL = rvL = rwL = 0.0;
+        if ( stagPoint(x[q],y[q],z[q]) )
+          ruR = rvR = rwR = 0.0;
+
+        // compute MUSCL reconstruction in edge-end points
+        muscl( p, q, coord, G,
+               rL, ruL, rvL, rwL, reL, rR, ruR, rvR, rwR, reR );
+
+        // convert back to conserved variables
+        reL = (reL + 0.5*(ruL*ruL + rvL*rvL + rwL*rwL)) * rL;
+        ruL *= rL;
+        rvL *= rL;
+        rwL *= rL;
+        reR = (reR + 0.5*(ruR*ruR + rvR*rvR + rwR*rwR)) * rR;
+        ruR *= rR;
+        rvR *= rR;
+        rwR *= rR;
+
+        // evaluate pressure at edge-end points
+        real pL = m_mat_blk[0].compute< EOS::pressure >( rL, ruL/rL, rvL/rL,
+          rwL/rL, reL );
+        real pR = m_mat_blk[0].compute< EOS::pressure >( rR, ruR/rR, rvR/rR,
+          rwR/rR, reR );
+
+        // compute Riemann flux using edge-end point states
+        real f[m_ncomp];
+        Rusanov::flux( m_mat_blk,
+                       dfn[e*6+0], dfn[e*6+1], dfn[e*6+2],
+                       dfn[e*6+3], dfn[e*6+4], dfn[e*6+5],
+                       rL, ruL, rvL, rwL, reL,
+                       rR, ruR, rvR, rwR, reR,
+                       w1L, w2L, w3L, w1R, w2R, w3R,
+                       pL, pR,
+                       f[0], f[1], f[2], f[3], f[4] );
+        // store flux in edges
+        for (std::size_t c=0; c<m_ncomp; ++c) dflux[e*m_ncomp+c] = f[c];
+      }
+
+      // access pointer to right hand side at component
+      std::array< const real*, m_ncomp > r;
+      for (ncomp_t c=0; c<m_ncomp; ++c) r[c] = R.cptr( c );
+
+      // domain-edge integral: sum flux contributions to points
+      for (std::size_t p=0,k=0; p<U.nunk(); ++p)
+        for (auto q : tk::Around(psup,p)) {
+          auto s = gid[p] > gid[q] ? -1.0 : 1.0;
+          auto e = edgeid[k++];
+          // the 2.0 in the following expression is so that the RHS contribution
+          // conforms with Eq 12 (Waltz et al. Computers & fluids (92) 2014);
+          // The 1/2 in Eq 12 is extracted from the flux function (Rusanov).
+          // However, Rusanov::flux computes the flux with the 1/2. This 2
+          // cancels with the 1/2 in Rusanov::flux, so that the 1/2 can be
+          // extracted out and multiplied as in Eq 12
+          for (std::size_t c=0; c<m_ncomp; ++c)
+            R.var(r[c],p) -= 2.0*s*dflux[e*m_ncomp+c];
+        }
+
+      tk::destroy(dflux);
+    }
+
+    //! \brief Compute MUSCL reconstruction in edge-end points using a MUSCL
+    //!    procedure with van Leer limiting
+    //! \param[in] p Left node id of edge-end
+    //! \param[in] q Right node id of edge-end
+    //! \param[in] coord Array of nodal coordinates
+    //! \param[in] G Gradient of all unknowns in mesh points
+    //! \param[in,out] rL Left density
+    //! \param[in,out] uL Left X velocity
+    //! \param[in,out] vL Left Y velocity
+    //! \param[in,out] wL Left Z velocity
+    //! \param[in,out] eL Left internal energy
+    //! \param[in,out] rR Right density
+    //! \param[in,out] uR Right X velocity
+    //! \param[in,out] vR Right Y velocity
+    //! \param[in,out] wR Right Z velocity
+    //! \param[in,out] eR Right internal energy
+    void muscl( std::size_t p,
+                std::size_t q,
+                const tk::UnsMesh::Coords& coord,
+                const tk::Fields& G,
+                real& rL, real& uL, real& vL, real& wL, real& eL,
+                real& rR, real& uR, real& vR, real& wR, real& eR ) const
+    {
+      // access node coordinates
+      const auto& x = coord[0];
+      const auto& y = coord[1];
+      const auto& z = coord[2];
+
+      // edge vector
+      std::array< real, 3 > vw{ x[q]-x[p], y[q]-y[p], z[q]-z[p] };
+
+      real delta1[5], delta2[5], delta3[5];
+      std::array< real, 5 > ls{ rL, uL, vL, wL, eL };
+      std::array< real, 5 > rs{ rR, uR, vR, wR, eR };
+      auto url = ls;
+      auto urr = rs;
+
+      // MUSCL reconstruction of edge-end-point primitive variables
+      for (std::size_t c=0; c<5; ++c) {
+        // gradients
+        std::array< real, 3 > g1{ G(p,c*3+0), G(p,c*3+1), G(p,c*3+2) },
+                              g2{ G(q,c*3+0), G(q,c*3+1), G(q,c*3+2) };
+
+        delta2[c] = rs[c] - ls[c];
+        delta1[c] = 2.0 * tk::dot(g1,vw) - delta2[c];
+        delta3[c] = 2.0 * tk::dot(g2,vw) - delta2[c];
+
+        // MUSCL extrapolation option 1:
+        // ---------------------------------------------------------------------
+        // Uncomment the following 3 blocks of code if this version is required.
+        // this reconstruction is from the following paper:
+        // Waltz, J., Morgan, N. R., Canfield, T. R., Charest, M. R.,
+        // Risinger, L. D., & Wohlbier, J. G. (2014). A three-dimensional
+        // finite element arbitrary Lagrangian–Eulerian method for shock
+        // hydrodynamics on unstructured grids. Computers & Fluids, 92,
+        // 172-187.
+
+        //// form limiters
+        //auto rcL = (delta2[c] + muscl_eps) / (delta1[c] + muscl_eps);
+        //auto rcR = (delta2[c] + muscl_eps) / (delta3[c] + muscl_eps);
+        //auto rLinv = (delta1[c] + muscl_eps) / (delta2[c] + muscl_eps);
+        //auto rRinv = (delta3[c] + muscl_eps) / (delta2[c] + muscl_eps);
+
+        //// van Leer limiter
+        //// any other symmetric limiter could be used instead too
+        //auto phiL = (std::abs(rcL) + rcL) / (std::abs(rcL) + 1.0);
+        //auto phiR = (std::abs(rcR) + rcR) / (std::abs(rcR) + 1.0);
+        //auto phi_L_inv = (std::abs(rLinv) + rLinv) / (std::abs(rLinv) + 1.0);
+        //auto phi_R_inv = (std::abs(rRinv) + rRinv) / (std::abs(rRinv) + 1.0);
+
+        //// update unknowns with reconstructed unknowns
+        //url[c] += 0.25*(delta1[c]*muscl_m1*phiL + delta2[c]*muscl_p1*phi_L_inv);
+        //urr[c] -= 0.25*(delta3[c]*muscl_m1*phiR + delta2[c]*muscl_p1*phi_R_inv);
+
+        // ---------------------------------------------------------------------
+
+        // MUSCL extrapolation option 2:
+        // ---------------------------------------------------------------------
+        // The following 2 blocks of code.
+        // this reconstruction is from the following paper:
+        // Luo, H., Baum, J. D., & Lohner, R. (1994). Edge-based finite element
+        // scheme for the Euler equations. AIAA journal, 32(6), 1183-1190.
+        // Van Leer, B. (1974). Towards the ultimate conservative difference
+        // scheme. II. Monotonicity and conservation combined in a second-order
+        // scheme. Journal of computational physics, 14(4), 361-370.
+
+        // get Van Albada limiter
+        // the following form is derived from the flux limiter phi as:
+        // s = phi_inv - (1 - phi)
+        auto sL = std::max(0.0, (2.0*delta1[c]*delta2[c] + muscl_eps)
+          /(delta1[c]*delta1[c] + delta2[c]*delta2[c] + muscl_eps));
+        auto sR = std::max(0.0, (2.0*delta3[c]*delta2[c] + muscl_eps)
+          /(delta3[c]*delta3[c] + delta2[c]*delta2[c] + muscl_eps));
+
+        // update unknowns with reconstructed unknowns
+        url[c] += 0.25*sL*(delta1[c]*(1.0-muscl_const*sL)
+          + delta2[c]*(1.0+muscl_const*sL));
+        urr[c] -= 0.25*sR*(delta3[c]*(1.0-muscl_const*sR)
+          + delta2[c]*(1.0+muscl_const*sR));
+
+        // ---------------------------------------------------------------------
+      }
+
+      // force first order if the reconstructions for density or internal energy
+      // would have allowed negative values
+      if (ls[0] < delta1[0] || ls[4] < delta1[4]) url = ls;
+      if (rs[0] < -delta3[0] || rs[4] < -delta3[4]) urr = rs;
+
+      rL = url[0];
+      uL = url[1];
+      vL = url[2];
+      wL = url[3];
+      eL = url[4];
+
+      rR = urr[0];
+      uR = urr[1];
+      vR = urr[2];
+      wR = urr[3];
+      eR = urr[4];
+    }
+
+    //! Compute boundary integrals for ALECG
+    //! \param[in] coord Mesh node coordinates
+    //! \param[in] triinpoel Boundary triangle face connecitivity with local ids
+    //! \param[in] symbctri Vector with 1 at symmetry BC boundary triangles
+    //! \param[in] U Solution vector at recent time step
+    //! \param[in] W Mesh velocity
+    //! \param[in,out] R Right-hand side vector computed
+    void bndint( const std::array< std::vector< real >, 3 >& coord,
+                 const std::vector< std::size_t >& triinpoel,
+                 const std::vector< int >& symbctri,
+                 const tk::Fields& U,
+                 const tk::Fields& W,
+                 tk::Fields& R ) const
+    {
+
+      // access node coordinates
+      const auto& x = coord[0];
+      const auto& y = coord[1];
+      const auto& z = coord[2];
+
+      // boundary integrals: compute fluxes in edges
+      std::vector< real > bflux( triinpoel.size() * m_ncomp * 2 );
+
+      #pragma omp simd
+      for (std::size_t e=0; e<triinpoel.size()/3; ++e) {
+        // access node IDs
+        std::size_t N[3] =
+          { triinpoel[e*3+0], triinpoel[e*3+1], triinpoel[e*3+2] };
+        // access solution at element nodes
+        real rA  = U(N[0],0);
+        real rB  = U(N[1],0);
+        real rC  = U(N[2],0);
+        real ruA = U(N[0],1);
+        real ruB = U(N[1],1);
+        real ruC = U(N[2],1);
+        real rvA = U(N[0],2);
+        real rvB = U(N[1],2);
+        real rvC = U(N[2],2);
+        real rwA = U(N[0],3);
+        real rwB = U(N[1],3);
+        real rwC = U(N[2],3);
+        real reA = U(N[0],4);
+        real reB = U(N[1],4);
+        real reC = U(N[2],4);
+        real w1A = W(N[0],0);
+        real w2A = W(N[0],1);
+        real w3A = W(N[0],2);
+        real w1B = W(N[1],0);
+        real w2B = W(N[1],1);
+        real w3B = W(N[1],2);
+        real w1C = W(N[2],0);
+        real w2C = W(N[2],1);
+        real w3C = W(N[2],2);
+        // apply stagnation BCs
+        if ( stagPoint(x[N[0]],y[N[0]],z[N[0]]) )
+        {
+          ruA = rvA = rwA = 0.0;
+        }
+        if ( stagPoint(x[N[1]],y[N[1]],z[N[1]]) )
+        {
+          ruB = rvB = rwB = 0.0;
+        }
+        if ( stagPoint(x[N[2]],y[N[2]],z[N[2]]) )
+        {
+          ruC = rvC = rwC = 0.0;
+        }
+        // compute face normal
+        real nx, ny, nz;
+        tk::normal( x[N[0]], x[N[1]], x[N[2]],
+                    y[N[0]], y[N[1]], y[N[2]],
+                    z[N[0]], z[N[1]], z[N[2]],
+                    nx, ny, nz );
+        // compute boundary flux
+        real f[m_ncomp][3];
+        real p, vn;
+        int sym = symbctri[e];
+        p = m_mat_blk[0].compute< EOS::pressure >( rA, ruA/rA, rvA/rA, rwA/rA,
+          reA );
+        vn = sym ? 0.0 : (nx*(ruA/rA-w1A) + ny*(rvA/rA-w2A) + nz*(rwA/rA-w3A));
+        f[0][0] = rA*vn;
+        f[1][0] = ruA*vn + p*nx;
+        f[2][0] = rvA*vn + p*ny;
+        f[3][0] = rwA*vn + p*nz;
+        f[4][0] = reA*vn + p*(sym ? 0.0 : (nx*ruA + ny*rvA + nz*rwA)/rA);
+        p = m_mat_blk[0].compute< EOS::pressure >( rB, ruB/rB, rvB/rB, rwB/rB,
+          reB );
+        vn = sym ? 0.0 : (nx*(ruB/rB-w1B) + ny*(rvB/rB-w2B) + nz*(rwB/rB-w3B));
+        f[0][1] = rB*vn;
+        f[1][1] = ruB*vn + p*nx;
+        f[2][1] = rvB*vn + p*ny;
+        f[3][1] = rwB*vn + p*nz;
+        f[4][1] = reB*vn + p*(sym ? 0.0 : (nx*ruB + ny*rvB + nz*rwB)/rB);
+        p = m_mat_blk[0].compute< EOS::pressure >( rC, ruC/rC, rvC/rC, rwC/rC,
+          reC );
+        vn = sym ? 0.0 : (nx*(ruC/rC-w1C) + ny*(rvC/rC-w2C) + nz*(rwC/rC-w3C));
+        f[0][2] = rC*vn;
+        f[1][2] = ruC*vn + p*nx;
+        f[2][2] = rvC*vn + p*ny;
+        f[3][2] = rwC*vn + p*nz;
+        f[4][2] = reC*vn + p*(sym ? 0.0 : (nx*ruC + ny*rvC + nz*rwC)/rC);
+        // compute face area
+        auto A6 = tk::area( x[N[0]], x[N[1]], x[N[2]],
+                            y[N[0]], y[N[1]], y[N[2]],
+                            z[N[0]], z[N[1]], z[N[2]] ) / 6.0;
+        auto A24 = A6/4.0;
+        // store flux in boundary elements
+        for (std::size_t c=0; c<m_ncomp; ++c) {
+          auto eb = (e*m_ncomp+c)*6;
+          auto Bab = A24 * (f[c][0] + f[c][1]);
+          bflux[eb+0] = Bab + A6 * f[c][0];
+          bflux[eb+1] = Bab;
+          Bab = A24 * (f[c][1] + f[c][2]);
+          bflux[eb+2] = Bab + A6 * f[c][1];
+          bflux[eb+3] = Bab;
+          Bab = A24 * (f[c][2] + f[c][0]);
+          bflux[eb+4] = Bab + A6 * f[c][2];
+          bflux[eb+5] = Bab;
+        }
+      }
+
+      // access pointer to right hand side at component
+      std::array< const real*, m_ncomp > r;
+      for (ncomp_t c=0; c<m_ncomp; ++c) r[c] = R.cptr( c );
+
+      // boundary integrals: sum flux contributions to points
+      for (std::size_t e=0; e<triinpoel.size()/3; ++e)
+        for (std::size_t c=0; c<m_ncomp; ++c) {
+          auto eb = (e*m_ncomp+c)*6;
+          R.var(r[c],triinpoel[e*3+0]) -= bflux[eb+0] + bflux[eb+5];
+          R.var(r[c],triinpoel[e*3+1]) -= bflux[eb+1] + bflux[eb+2];
+          R.var(r[c],triinpoel[e*3+2]) -= bflux[eb+3] + bflux[eb+4];
+        }
+
+      tk::destroy(bflux);
+    }
+
+    //! Compute optional source integral
+    //! \param[in] coord Mesh node coordinates
+    //! \param[in] inpoel Mesh element connectivity
+    //! \param[in] t Physical time
+    //! \param[in] tp Physical time for each mesh node
+    //! \param[in,out] R Right-hand side vector computed
+    void src( const std::array< std::vector< real >, 3 >& coord,
+              const std::vector< std::size_t >& inpoel,
+              real t,
+              const std::vector< tk::real >& tp,
+              tk::Fields& R ) const
+    {
+      // access node coordinates
+      const auto& x = coord[0];
+      const auto& y = coord[1];
+      const auto& z = coord[2];
+
+      // access pointer to right hand side at component
+      std::array< const real*, m_ncomp > r;
+      for (ncomp_t c=0; c<m_ncomp; ++c) r[c] = R.cptr( c );
+
+      // source integral
+      for (std::size_t e=0; e<inpoel.size()/4; ++e) {
+        std::size_t N[4] =
+          { inpoel[e*4+0], inpoel[e*4+1], inpoel[e*4+2], inpoel[e*4+3] };
+        // compute element Jacobi determinant, J = 6V
+        auto J24 = tk::triple(
+          x[N[1]]-x[N[0]], y[N[1]]-y[N[0]], z[N[1]]-z[N[0]],
+          x[N[2]]-x[N[0]], y[N[2]]-y[N[0]], z[N[2]]-z[N[0]],
+          x[N[3]]-x[N[0]], y[N[3]]-y[N[0]], z[N[3]]-z[N[0]] ) / 24.0;
+        // sum source contributions to nodes
+        for (std::size_t a=0; a<4; ++a) {
+          std::vector< real > s(m_ncomp);
+          if (g_inputdeck.get< tag::steady_state >()) t = tp[N[a]];
+          Problem::src( 1, m_mat_blk, x[N[a]], y[N[a]], z[N[a]], t, s );
+          for (std::size_t c=0; c<m_ncomp; ++c)
+            R.var(r[c],N[a]) += J24 * s[c];
+        }
+      }
+    }
+
+    //! Compute sources corresponding to a propagating front in user-defined box
+    //! \param[in] V Total box volume
+    //! \param[in] t Physical time
+    //! \param[in] inpoel Element point connectivity
+    //! \param[in] esup Elements surrounding points
+    //! \param[in] boxnodes Mesh node ids within user-defined box
+    //! \param[in] coord Mesh node coordinates
+    //! \param[in] R Right-hand side vector
+    //! \details This function add the energy source corresponding to a planar
+    //!   wave-front propagating along the z-direction with a user-specified
+    //!   velocity, within a box initial condition, configured by the user.
+    //!   Example (SI) units of the quantities involved:
+    //!    * internal energy content (energy per unit volume): J/m^3
+    //!    * specific energy (internal energy per unit mass): J/kg
+    void boxSrc( real V,
+                 real t,
+                 const std::vector< std::size_t >& inpoel,
+                 const std::pair< std::vector< std::size_t >,
+                                  std::vector< std::size_t > >& esup,
+                 const std::unordered_set< std::size_t >& boxnodes,
+                 const std::array< std::vector< real >, 3 >& coord,
+                 tk::Fields& R ) const<--- Parameter 'R' can be declared with const
+    {
+      const auto& icbox = g_inputdeck.get< tag::ic, tag::box >();
+
+      if (!icbox.empty()) {
+        for (const auto& b : icbox) {   // for all boxes for this eq
+          std::vector< tk::real > box
+           { b.template get< tag::xmin >(), b.template get< tag::xmax >(),
+             b.template get< tag::ymin >(), b.template get< tag::ymax >(),
+             b.template get< tag::zmin >(), b.template get< tag::zmax >() };
+
+          auto boxenc = b.template get< tag::energy_content >();
+          Assert( boxenc > 0.0, "Box energy content must be nonzero" );
+
+          auto V_ex = (box[1]-box[0]) * (box[3]-box[2]) * (box[5]-box[4]);
+
+          // determine times at which sourcing is initialized and terminated
+          auto iv = b.template get< tag::front_speed >();
+          auto wFront = b.template get< tag::front_width >();
+          auto tInit = b.template get< tag::init_time >();
+          auto tFinal = tInit + (box[5] - box[4] - wFront) / std::fabs(iv);
+          auto aBox = (box[1]-box[0]) * (box[3]-box[2]);
+
+          const auto& x = coord[0];
+          const auto& y = coord[1];
+          const auto& z = coord[2];
+
+          if (t >= tInit && t <= tFinal) {
+            // The energy front is assumed to have a half-sine-wave shape. The
+            // half wave-length is the width of the front. At t=0, the center of
+            // this front (i.e. the peak of the partial-sine-wave) is at X_0 +
+            // W_0.  W_0 is calculated based on the width of the front and the
+            // direction of propagation (which is assumed to be along the
+            // z-direction).  If the front propagation velocity is positive, it
+            // is assumed that the initial position of the energy source is the
+            // minimum z-coordinate of the box; whereas if this velocity is
+            // negative, the initial position is the maximum z-coordinate of the
+            // box.
+
+            // Orientation of box
+            std::array< tk::real, 3 > b_orientn{{
+              b.template get< tag::orientation >()[0],
+              b.template get< tag::orientation >()[1],
+              b.template get< tag::orientation >()[2] }};
+            std::array< tk::real, 3 > b_centroid{{ 0.5*(box[0]+box[1]),
+              0.5*(box[2]+box[3]), 0.5*(box[4]+box[5]) }};
+            // Transform box to reference space
+            std::array< tk::real, 3 > b_min{{box[0], box[2], box[4]}};
+            std::array< tk::real, 3 > b_max{{box[1], box[3], box[5]}};
+            tk::movePoint(b_centroid, b_min);
+            tk::movePoint(b_centroid, b_max);
+
+            // initial center of front
+            tk::real zInit(b_min[2]);
+            if (iv < 0.0) zInit = b_max[2];
+            // current location of front
+            auto z0 = zInit + iv * (t-tInit);
+            auto z1 = z0 + std::copysign(wFront, iv);
+            tk::real s0(z0), s1(z1);
+            // if velocity of propagation is negative, initial position is z1
+            if (iv < 0.0) {
+              s0 = z1;
+              s1 = z0;
+            }
+            // Sine-wave (positive part of the wave) source term amplitude
+            auto pi = 4.0 * std::atan(1.0);
+            auto amplE = boxenc * V_ex * pi
+              / (aBox * wFront * 2.0 * (tFinal-tInit));
+            //// Square wave (constant) source term amplitude
+            //auto amplE = boxenc * V_ex
+            //  / (aBox * wFront * (tFinal-tInit));
+            //// arbitrary shape form
+            //auto amplE = boxenc * std::abs(iv) / wFront;
+            amplE *= V_ex / V;
+
+            // add source
+            for (auto p : boxnodes) {
+              std::array< tk::real, 3 > node{{ x[p], y[p], z[p] }};
+              // Transform node to reference space of box
+              tk::movePoint(b_centroid, node);
+              tk::rotatePoint({{-b_orientn[0], -b_orientn[1], -b_orientn[2]}},
+                node);
+
+              if (node[2] >= s0 && node[2] <= s1) {
+                auto S = amplE * std::sin(pi*(node[2]-s0)/wFront);
+                //// arbitrary shape form
+                //auto S = amplE;
+                for (auto e : tk::Around(esup,p)) {
+                  // access node IDs
+                  std::size_t N[4] =
+                    {inpoel[e*4+0], inpoel[e*4+1], inpoel[e*4+2], inpoel[e*4+3]};
+                  // compute element Jacobi determinant, J = 6V
+                  real bax = x[N[1]]-x[N[0]];
+                  real bay = y[N[1]]-y[N[0]];
+                  real baz = z[N[1]]-z[N[0]];
+                  real cax = x[N[2]]-x[N[0]];
+                  real cay = y[N[2]]-y[N[0]];
+                  real caz = z[N[2]]-z[N[0]];
+                  real dax = x[N[3]]-x[N[0]];
+                  real day = y[N[3]]-y[N[0]];
+                  real daz = z[N[3]]-z[N[0]];
+                  auto J =
+                    tk::triple( bax, bay, baz, cax, cay, caz, dax, day, daz );
+                  auto J24 = J/24.0;
+                  R(p,4) += J24 * S;
+                }
+              }
+            }
+          }
+        }
+      }
+    }
+
+};
+
+} // cg::
+
+} // inciter::
+
+#endif // CGCompFlow_h
 
diff --git a/Release/cppcheck/47.html b/Release/cppcheck/47.html index 2762d8d04fed..fb83b9a23f29 100644 --- a/Release/cppcheck/47.html +++ b/Release/cppcheck/47.html @@ -152,12 +152,12 @@
   1
@@ -1451,1298 +1451,1894 @@ 

Cppcheck report - [

// *****************************************************************************
+1292
+1293
+1294
+1295
+1296
+1297
+1298
+1299
+1300
+1301
+1302
+1303
+1304
+1305
+1306
+1307
+1308
+1309
+1310
+1311
+1312
+1313
+1314
+1315
+1316
+1317
+1318
+1319
+1320
+1321
+1322
+1323
+1324
+1325
+1326
+1327
+1328
+1329
+1330
+1331
+1332
+1333
+1334
+1335
+1336
+1337
+1338
+1339
+1340
+1341
+1342
+1343
+1344
+1345
+1346
+1347
+1348
+1349
+1350
+1351
+1352
+1353
+1354
+1355
+1356
+1357
+1358
+1359
+1360
+1361
+1362
+1363
+1364
+1365
+1366
+1367
+1368
+1369
+1370
+1371
+1372
+1373
+1374
+1375
+1376
+1377
+1378
+1379
+1380
+1381
+1382
+1383
+1384
+1385
+1386
+1387
+1388
+1389
+1390
+1391
+1392
+1393
+1394
+1395
+1396
+1397
+1398
+1399
+1400
+1401
+1402
+1403
+1404
+1405
+1406
+1407
+1408
+1409
+1410
+1411
+1412
+1413
+1414
+1415
+1416
+1417
+1418
+1419
+1420
+1421
+1422
+1423
+1424
+1425
+1426
+1427
+1428
+1429
+1430
+1431
+1432
+1433
+1434
+1435
+1436
+1437
+1438
+1439
+1440
+1441
+1442
+1443
+1444
+1445
+1446
+1447
+1448
+1449
+1450
+1451
+1452
+1453
+1454
+1455
+1456
+1457
+1458
+1459
+1460
+1461
+1462
+1463
+1464
+1465
+1466
+1467
+1468
+1469
+1470
+1471
+1472
+1473
+1474
+1475
+1476
+1477
+1478
+1479
+1480
+1481
+1482
+1483
+1484
+1485
+1486
+1487
+1488
+1489
+1490
+1491
+1492
+1493
+1494
+1495
+1496
+1497
+1498
+1499
+1500
+1501
+1502
+1503
+1504
+1505
+1506
+1507
+1508
+1509
+1510
+1511
+1512
+1513
+1514
+1515
+1516
+1517
+1518
+1519
+1520
+1521
+1522
+1523
+1524
+1525
+1526
+1527
+1528
+1529
+1530
+1531
+1532
+1533
+1534
+1535
+1536
+1537
+1538
+1539
+1540
+1541
+1542
+1543
+1544
+1545
+1546
+1547
+1548
+1549
+1550
+1551
+1552
+1553
+1554
+1555
+1556
+1557
+1558
+1559
+1560
+1561
+1562
+1563
+1564
+1565
+1566
+1567
+1568
+1569
+1570
+1571
+1572
+1573
+1574
+1575
+1576
+1577
+1578
+1579
+1580
+1581
+1582
+1583
+1584
+1585
+1586
+1587
+1588
+1589
+1590
// *****************************************************************************
 /*!
-  \file      src/PDE/CompFlow/DGCompFlow.hpp
+  \file      src/Inciter/Transporter.cpp
   \copyright 2012-2015 J. Bakosi,
              2016-2018 Los Alamos National Security, LLC.,
              2019-2021 Triad National Security, LLC.
              All rights reserved. See the LICENSE file for details.
-  \brief     Compressible single-material flow using discontinuous Galerkin
-     finite elements
-  \details   This file implements calls to the physics operators governing
-    compressible single-material flow using discontinuous Galerkin
-    discretizations.
-*/
-// *****************************************************************************
-#ifndef DGCompFlow_h
-#define DGCompFlow_h
+  \brief     Transporter drives the time integration of transport equations
+  \details   Transporter drives the time integration of transport equations.
+    The implementation uses the Charm++ runtime system and is fully asynchronous,
+    overlapping computation, communication as well as I/O. The algorithm
+    utilizes the structured dagger (SDAG) Charm++ functionality. The high-level
+    overview of the algorithm structure and how it interfaces with Charm++ is
+    discussed in the Charm++ interface file src/Inciter/transporter.ci.
+*/
+// *****************************************************************************
 
-#include <cmath>
-#include <algorithm>
-#include <unordered_set>
-#include <map>
-
-#include <brigand/algorithms/for_each.hpp>
+#include <string>
+#include <iostream>
+#include <cstddef>
+#include <unordered_set>
+#include <limits>
+#include <cmath>
 
-#include "Macro.hpp"
-#include "Exception.hpp"
-#include "Vector.hpp"
-#include "ContainerUtil.hpp"
-#include "UnsMesh.hpp"
-#include "Inciter/InputDeck/InputDeck.hpp"
-#include "Integrate/Basis.hpp"
-#include "Integrate/Quadrature.hpp"
-#include "Integrate/Initialize.hpp"
-#include "Integrate/Mass.hpp"
-#include "Integrate/Surface.hpp"
-#include "Integrate/Boundary.hpp"
-#include "Integrate/Volume.hpp"
-#include "Integrate/Source.hpp"
-#include "RiemannChoice.hpp"
-#include "EoS/EOS.hpp"
-#include "Reconstruction.hpp"
-#include "Limiter.hpp"
-#include "PrefIndicator.hpp"
-
-namespace inciter {
-
-extern ctr::InputDeck g_inputdeck;
-
-namespace dg {
-
-//! \brief CompFlow used polymorphically with tk::DGPDE
-//! \details The template arguments specify policies and are used to configure
-//!   the behavior of the class. The policies are:
-//!   - Physics - physics configuration, see PDE/CompFlow/Physics.h
-//!   - Problem - problem configuration, see PDE/CompFlow/Problem.h
-//! \note The default physics is Euler, set in inciter::deck::check_compflow()
-template< class Physics, class Problem >
-class CompFlow {
+#include <brigand/algorithms/for_each.hpp>
+
+#include "Macro.hpp"
+#include "Transporter.hpp"
+#include "Fields.hpp"
+#include "PDEStack.hpp"
+#include "UniPDF.hpp"
+#include "PDFWriter.hpp"
+#include "ContainerUtil.hpp"
+#include "LoadDistributor.hpp"
+#include "MeshReader.hpp"
+#include "Inciter/InputDeck/InputDeck.hpp"
+#include "NodeDiagnostics.hpp"
+#include "ElemDiagnostics.hpp"
+#include "DiagWriter.hpp"
+#include "Callback.hpp"
+#include "CartesianProduct.hpp"
+
+#include "NoWarning/inciter.decl.h"
+#include "NoWarning/partitioner.decl.h"
+
+extern CProxy_Main mainProxy;
+
+namespace inciter {
+
+extern ctr::InputDeck g_inputdeck_defaults;
+extern ctr::InputDeck g_inputdeck;
+extern std::vector< CGPDE > g_cgpde;
+extern std::vector< DGPDE > g_dgpde;
+extern std::vector< FVPDE > g_fvpde;
+
+}
+
+using inciter::Transporter;
 
-  private:
-    using eq = tag::compflow;
-
-  public:
-    //! Constructor
-    explicit CompFlow() :
-      m_physics(),
-      m_problem(),
-      m_ncomp( g_inputdeck.get< tag::ncomp >() ),
-      m_riemann( compflowRiemannSolver(
-        g_inputdeck.get< tag::flux >() ) )
-    {
-      // associate boundary condition configurations with state functions, the
-      // order in which the state functions listed matters, see ctr::bc::Keys
-      brigand::for_each< ctr::bclist::Keys >( ConfigBC( m_bc,
-        { dirichlet
-        , symmetry
-        , invalidBC         // Inlet BC not implemented
-        , invalidBC         // Outlet BC not implemented
-        , farfield
-        , extrapolate } ) );
-
-      // EoS initialization
-      const auto& matprop =
-        g_inputdeck.get< tag::material >();
-      const auto& matidxmap =
-        g_inputdeck.get< tag::matidxmap >();
-      auto mateos = matprop[matidxmap.get< tag::eosidx >()[0]].get<tag::eos>();
-      m_mat_blk.emplace_back(mateos, EqType::compflow, 0);
-
-    }
-
-    //! Find the number of primitive quantities required for this PDE system
-    //! \return The number of primitive quantities required to be stored for
-    //!   this PDE system
-    std::size_t nprim() const
-    {
-      // compflow does not need/store any primitive quantities currently
-      return 0;
-    }
-
-    //! Find the number of materials set up for this PDE system
-    //! \return The number of materials set up for this PDE system
-    std::size_t nmat() const
-    {
-      // compflow does not need nmat
-      return 0;
-    }
-
-    //! Assign number of DOFs per equation in the PDE system
-    //! \param[in,out] numEqDof Array storing number of Dofs for each PDE
-    //!   equation
-    void numEquationDofs(std::vector< std::size_t >& numEqDof) const
-    {
-      // all equation-dofs initialized to ndof
-      for (std::size_t i=0; i<m_ncomp; ++i) {
-        numEqDof.push_back(g_inputdeck.get< tag::ndof >());
-      }
-    }
-
-    //! Determine elements that lie inside the user-defined IC box
-    //! \param[in] geoElem Element geometry array
-    //! \param[in] nielem Number of internal elements
-    //! \param[in,out] inbox List of nodes at which box user ICs are set for
-    //!    each IC box
-    void IcBoxElems( const tk::Fields& geoElem,
-      std::size_t nielem,
-      std::vector< std::unordered_set< std::size_t > >& inbox ) const
-    {
-      tk::BoxElems< eq >(geoElem, nielem, inbox);
-    }
-
-    //! Find how 'stiff equations', which we currently
-    //! have none for Compflow
-    //! \return number of stiff equations
-    std::size_t nstiffeq() const
-    { return 0; }
-
-    //! Find how 'nonstiff equations', which we currently
-    //! don't use for Compflow
-    //! \return number of non-stiff equations
-    std::size_t nnonstiffeq() const
-    { return 0; }
+Transporter::Transporter() :
+  m_input( input() ),
+  m_nchare( m_input.size() ),
+  m_meshid(),
+  m_ncit( m_nchare.size(), 0 ),
+  m_nload( 0 ),
+  m_ntrans( 0 ),
+  m_ndtmsh( 0 ),
+  m_dtmsh(),
+  m_npart( 0 ),
+  m_nstat( 0 ),
+  m_ndisc( 0 ),
+  m_nchk( 0 ),
+  m_ncom( 0 ),
+  m_nt0refit( m_nchare.size(), 0 ),
+  m_ndtrefit( m_nchare.size(), 0 ),
+  m_noutrefit( m_nchare.size(), 0 ),
+  m_noutderefit( m_nchare.size(), 0 ),
+  m_scheme(),
+  m_partitioner(),
+  m_refiner(),
+  m_meshwriter(),
+  m_sorter(),
+  m_nelem( m_nchare.size() ),
+  m_npoin(),
+  m_finished( m_nchare.size(), 0 ),
+  m_meshvol( m_nchare.size() ),
+  m_minstat( m_nchare.size() ),
+  m_maxstat( m_nchare.size() ),
+  m_avgstat( m_nchare.size() ),
+  m_timer(),
+  m_progMesh( g_inputdeck.get< tag::cmd, tag::feedback >(),
+              ProgMeshPrefix, ProgMeshLegend ),
+  m_progWork( g_inputdeck.get< tag::cmd, tag::feedback >(),
+              ProgWorkPrefix, ProgWorkLegend )
+// *****************************************************************************
+//  Constructor
+// *****************************************************************************
+{
+  // Echo configuration to screen
+  info( printer() );
+
+  const auto nstep = g_inputdeck.get< tag::nstep >();
+  const auto t0 = g_inputdeck.get< tag::t0 >();
+  const auto term = g_inputdeck.get< tag::term >();
+  const auto constdt = g_inputdeck.get< tag::dt >();
+
+  // If the desired max number of time steps is larger than zero, and the
+  // termination time is larger than the initial time, and the constant time
+  // step size (if that is used) is smaller than the duration of the time to be
+  // simulated, we have work to do, otherwise, finish right away. If a constant
+  // dt is not used, that part of the logic is always true as the default
+  // constdt is zero, see inciter::ctr::InputDeck::InputDeck().
+  if ( nstep != 0 && term > t0 && constdt < term-t0 ) {
+
+    // Enable SDAG waits for collecting mesh statistics
+    thisProxy.wait4stat();
+
+    // Configure and write diagnostics file header
+    diagHeader();
+
+    // Create mesh partitioner AND boundary condition object group
+    createPartitioner();
+
+  } else finish();      // stop if no time stepping requested
+}
+
+Transporter::Transporter( CkMigrateMessage* m ) :
+  CBase_Transporter( m ),
+  m_progMesh( g_inputdeck.get< tag::cmd, tag::feedback >(),
+              ProgMeshPrefix, ProgMeshLegend ),
+  m_progWork( g_inputdeck.get< tag::cmd, tag::feedback >(),
+              ProgWorkPrefix, ProgWorkLegend )
+// *****************************************************************************
+//  Migrate constructor: returning from a checkpoint
+//! \param[in] m Charm++ migrate message
+// *****************************************************************************
+{
+   auto print = printer();
+   print.diag( "Restarted from checkpoint" );
+   info( print );
+   inthead( print );
+}
 
-    //! Locate the stiff equations. Unused for compflow.
-    //! \param[out] stiffEqIdx list
-    void setStiffEqIdx( std::vector< std::size_t >& stiffEqIdx ) const
-    {
-      stiffEqIdx.resize(0);
-    }
-
-    //! Locate the nonstiff equations. Unused for compflow.
-    //! \param[out] nonStiffEqIdx list
-    void setNonStiffEqIdx( std::vector< std::size_t >& nonStiffEqIdx ) const
-    {
-      nonStiffEqIdx.resize(0);
-    }
-
-    //! Initalize the compressible flow equations, prepare for time integration
-    //! \param[in] L Block diagonal mass matrix
-    //! \param[in] inpoel Element-node connectivity
-    //! \param[in] coord Array of nodal coordinates
-    //! \param[in] inbox List of elements at which box user ICs are set for
-    //!    each IC box
-    //! \param[in,out] unk Array of unknowns
-    //! \param[in] t Physical time
-    //! \param[in] nielem Number of internal elements
-    void
-    initialize( const tk::Fields& L,
-                const std::vector< std::size_t >& inpoel,
-                const tk::UnsMesh::Coords& coord,
-                const std::vector< std::unordered_set< std::size_t > >& inbox,
-                const std::unordered_map< std::size_t,
-                  std::set< std::size_t > >&,
-                tk::Fields& unk,
-                tk::real t,
-                const std::size_t nielem ) const
-    {
-      tk::initialize( m_ncomp, m_mat_blk, L, inpoel, coord,
-                      Problem::initialize, unk, t, nielem );
-
-      const auto rdof = g_inputdeck.get< tag::rdof >();
-      const auto& ic = g_inputdeck.get< tag::ic >();
-      const auto& icbox = ic.get< tag::box >();
-      const auto& bgpreic = ic.get< tag::pressure >();
-      auto c_v = getmatprop< tag::cv >();
-
-      // Set initial conditions inside user-defined IC box
-      std::vector< tk::real > s(m_ncomp, 0.0);
-      for (std::size_t e=0; e<nielem; ++e) {
-        if (icbox.size() > 0) {
-          std::size_t bcnt = 0;
-          for (const auto& b : icbox) {   // for all boxes
-            if (inbox.size() > bcnt && inbox[bcnt].find(e) != inbox[bcnt].end())
-            {
-              std::vector< tk::real > box
-              { b.template get< tag::xmin >(), b.template get< tag::xmax >(),
-                b.template get< tag::ymin >(), b.template get< tag::ymax >(),
-                b.template get< tag::zmin >(), b.template get< tag::zmax >() };
-              auto V_ex = (box[1]-box[0]) * (box[3]-box[2]) * (box[5]-box[4]);
-              for (std::size_t c=0; c<m_ncomp; ++c) {
-                auto mark = c*rdof;
-                s[c] = unk(e,mark);
-                // set high-order DOFs to zero
-                for (std::size_t i=1; i<rdof; ++i)
-                  unk(e,mark+i) = 0.0;
-              }
-              initializeBox<ctr::boxList>( m_mat_blk, 1.0, V_ex,
-                t, b, bgpreic, c_v, s );
-              // store box-initialization in solution vector
-              for (std::size_t c=0; c<m_ncomp; ++c) {
-                auto mark = c*rdof;
-                unk(e,mark) = s[c];
-              }
-            }
-            ++bcnt;
-          }
-        }
-      }
-    }
+std::vector< std::string >
+Transporter::input()
+// *****************************************************************************
+// Generate list of input mesh filenames configured by the user
+//! \return List of input mesh filenames configured by the user
+//! \details If the input file is given on the command line, a single solver
+//!   will be instantiated on the single mesh, solving potentially multiple
+//!   systems of (potentially coupled) equations. If the input file is not given
+//!   on the command line, the mesh files are expected to be configured in the
+//!   control/input file, associating a potentially different mesh to each
+//!   solver. Both configurations allow the solution of coupled systems, but the
+//!   first one solves all equations on the same mesh, while the latter can
+//!   couple solutions computed on multiple different meshes.
+// *****************************************************************************
+{
+  // Query input mesh filename specified on the command line
+  const auto& cmdinput = g_inputdeck.get< tag::cmd, tag::io, tag::input >();
+
+  // Extract mesh filenames specified in the control file (assigned to solvers)
+  std::vector< std::string > ctrinput;
+  for (const auto& im : g_inputdeck.get< tag::mesh >()) {
+    ctrinput.push_back(im.get< tag::filename >());<--- Consider using std::transform algorithm instead of a raw loop.
+  }
+
+  ErrChk( not cmdinput.empty() or not ctrinput.empty(),
+    "Either a single input mesh must be given on the command line or multiple "
+    "meshes must be configured in the control file." );
+
+   // Prepend control file path to mesh filenames in given in control file
+  if (not ctrinput.empty()) {
+     const auto& ctr = g_inputdeck.get< tag::cmd, tag::io, tag::control >();
+     auto path = ctr.substr( 0, ctr.find_last_of("/")+1 );
+     for (auto& f : ctrinput) f = path + f;<--- Consider using std::transform algorithm instead of a raw loop.
+  }
+
+  if (cmdinput.empty()) return ctrinput; else return { cmdinput };
+}
+
+void
+Transporter::info( const InciterPrint& print )
+// *****************************************************************************
+// Echo configuration to screen
+//! \param[in] print Pretty printer object to use for printing
+// *****************************************************************************
+{
+  print.part( "Factory" );
+
+  // Print out info data layout
+  print.list( "Unknowns data layout (CMake: FIELD_DATA_LAYOUT)",
+              std::list< std::string >{ tk::Fields::layout() } );
+
+  // Re-create partial differential equations stack for output
+  PDEStack stack;
+
+  // Print out information on PDE factories
+  print.eqlist( "Registered PDEs using continuous Galerkin (CG) methods",
+                stack.cgfactory(), stack.cgntypes() );
+  print.eqlist( "Registered PDEs using discontinuous Galerkin (DG) methods",
+                stack.dgfactory(), stack.dgntypes() );
+  print.eqlist( "Registered PDEs using finite volume (DG) methods",
+                stack.fvfactory(), stack.fvntypes() );
+  print.endpart();
+
+  // Print out information on problem
+  print.part( "Problem" );
+
+  // Print out info on problem title
+  if ( !g_inputdeck.get< tag::title >().empty() )
+    print.title( g_inputdeck.get< tag::title >() );
+
+  const auto nstep = g_inputdeck.get< tag::nstep >();
+  const auto t0 = g_inputdeck.get< tag::t0 >();
+  const auto term = g_inputdeck.get< tag::term >();
+  const auto constdt = g_inputdeck.get< tag::dt >();
+  const auto cfl = g_inputdeck.get< tag::cfl >();
+  const auto scheme = g_inputdeck.get< tag::scheme >();
 
-    //! Save initial densities for all materials
-    //! \param[out] rho0mat List of initial densities
-    void setRho0mat( std::vector< tk::real >& rho0mat ) const
-    {
-      rho0mat.resize(0);
-    }
-
-    //! Compute density constraint for a given material
-    // //! \param[in] nelem Number of elements
-    // //! \param[in] unk Array of unknowns
-    // //! \param[in] rho0mat List of initial densities
-    //! \param[out] densityConstr Density Constraint: rho/(rho0*det(g))
-    void computeDensityConstr( std::size_t /*nelem*/,
-                               tk::Fields& /*unk*/,
-                               std::vector< tk::real >& /*rho0mat*/,
-                               std::vector< tk::real >& densityConstr) const
-    {
-      densityConstr.resize(0);
-    }
-
-    //! Compute the left hand side block-diagonal mass matrix
-    //! \param[in] geoElem Element geometry array
-    //! \param[in,out] l Block diagonal mass matrix
-    void lhs( const tk::Fields& geoElem, tk::Fields& l ) const {
-      const auto ndof = g_inputdeck.get< tag::ndof >();
-      tk::mass( m_ncomp, ndof, geoElem, l );
-    }
-
-    //! Update the interface cells to first order dofs
-    //! \details This function resets the high-order terms in interface cells,
-    //!   and is currently not used in compflow.
-    void updateInterfaceCells( tk::Fields&,
-      std::size_t,
-      std::vector< std::size_t >& ) const {}
-
-    //! Update the primitives for this PDE system
-    //! \details This function computes and stores the dofs for primitive
-    //!   quantities, which is currently unused for compflow. But if a limiter
-    //!   requires primitive variables for example, this would be the place to
-    //!   add the computation of the primitive variables.
-    void updatePrimitives( const tk::Fields&,
-                           const tk::Fields&,
-                           const tk::Fields&,
-                           tk::Fields&,
-                           std::size_t ) const {}
-
-    //! Clean up the state of trace materials for this PDE system
-    //! \details This function cleans up the state of materials present in trace
-    //!   quantities in each cell. This is unused for compflow.
-    void cleanTraceMaterial( tk::real,
-                             const tk::Fields&,
-                             tk::Fields&,
-                             tk::Fields&,
-                             std::size_t ) const {}
+  // Print discretization parameters
+  print.section( "Discretization parameters" );
+  print.Item< ctr::Scheme, tag::scheme >();
+  print.item( "Implicit-Explicit Runge-Kutta",
+              g_inputdeck.get< tag::imex_runge_kutta >() );
+
+  if (g_inputdeck.centering() == tk::Centering::ELEM)
+  {
+    print.Item< ctr::Limiter, tag::limiter >();
+
+    print.item("Shock detection based limiting",
+      g_inputdeck.get< tag::shock_detector_coeff >());
+
+    if (g_inputdeck.get< tag::accuracy_test >())
+    {
+      print.item("WARNING: order-of-accuracy testing enabled",
+        "robustness corrections inactive");
+    }
+
+    print.item("Limited solution projection",
+      g_inputdeck.get< tag::limsol_projection >());
+  }
+  print.item( "PE-locality mesh reordering",
+              g_inputdeck.get< tag::pelocal_reorder >() );
+  print.item( "Operator-access mesh reordering",
+              g_inputdeck.get< tag::operator_reorder >() );
+  auto steady = g_inputdeck.get< tag::steady_state >();
+  print.item( "Local time stepping", steady );
+  if (steady) {
+    print.item( "L2-norm residual convergence criterion",
+                g_inputdeck.get< tag::residual >() );
+    print.item( "Convergence criterion component index",
+                g_inputdeck.get< tag::rescomp >() );
+  }
+  print.item( "Number of time steps", nstep );
+  print.item( "Start time", t0 );
+  print.item( "Terminate time", term );
+
+  if (constdt > std::numeric_limits< tk::real >::epsilon())
+    print.item( "Constant time step size", constdt );
+  else if (cfl > std::numeric_limits< tk::real >::epsilon())
+  {
+    print.item( "CFL coefficient", cfl );
+  }
+
+  const auto& meshes = g_inputdeck.get< tag::mesh >();
+  const auto& depvars = g_inputdeck.get< tag::depvar >();
+  for (std::size_t i=0; i<meshes.size(); ++i) {
+    print.item( "Dependent var name and assoc. mesh", std::string{depvars[i]}
+      + " - " + meshes[i].get< tag::filename >() );
+  }
+
+  // Print out info on settings of selected partial differential equations
+  print.pdes( "Partial differential equations integrated", stack.info() );
 
-    //! Reconstruct second-order solution from first-order using least-squares
-    //! \param[in] t Physical time
-    //! \param[in] geoFace Face geometry array
-    //! \param[in] geoElem Element geometry array
-    //! \param[in] fd Face connectivity and boundary conditions object
-    //! \param[in] inpoel Element-node connectivity
-    //! \param[in] coord Array of nodal coordinates
-    //! \param[in,out] U Solution vector at recent time step
-    //! \param[in,out] P Primitive vector at recent time step
-    void reconstruct( tk::real t,
-                      const tk::Fields& geoFace,
-                      const tk::Fields& geoElem,
-                      const inciter::FaceData& fd,
-                      const std::map< std::size_t, std::vector< std::size_t > >&,
-                      const std::vector< std::size_t >& inpoel,
-                      const tk::UnsMesh::Coords& coord,
-                      tk::Fields& U,
-                      tk::Fields& P ) const
-    {
-      const auto rdof = g_inputdeck.get< tag::rdof >();
-
-      // do reconstruction only if P0P1
-      if (rdof == 4 && g_inputdeck.get< tag::ndof >() == 1) {
-        const auto nelem = fd.Esuel().size()/4;<--- Variable 'nelem' is assigned a value that is never used.
-
-        Assert( U.nprop() == rdof*5, "Number of components in solution "
-                "vector must equal "+ std::to_string(rdof*5) );
-        Assert( fd.Inpofa().size()/3 == fd.Esuf().size()/2,
-                "Mismatch in inpofa size" );
+  // Print out adaptive polynomial refinement configuration
+  if (scheme == ctr::SchemeType::PDG) {
+    print.section( "Polynomial refinement (p-ref)" );
+    print.item( "p-refinement",
+                g_inputdeck.get< tag::pref, tag::pref >() );
+    print.Item< ctr::PrefIndicator, tag::pref, tag::indicator >();
+    print.item( "Max degrees of freedom",
+                g_inputdeck.get< tag::pref, tag::ndofmax >() );
+    print.item( "Tolerance",
+                g_inputdeck.get< tag::pref, tag::tolref >() );
+  }
+
+  // Print out adaptive mesh refinement configuration
+  const auto amr = g_inputdeck.get< tag::amr, tag::amr >();
+  if (amr) {
+    print.section( "Mesh refinement (h-ref)" );
+    auto maxlevels = g_inputdeck.get< tag::amr, tag::maxlevels >();
+    print.item( "Maximum mesh refinement levels", maxlevels );
+    print.Item< ctr::AMRError, tag::amr, tag::error >();
+    auto t0ref = g_inputdeck.get< tag::amr, tag::t0ref >();
+    print.item( "Refinement at t<0 (t0ref)", t0ref );
+    if (t0ref) {
+      const auto& initref = g_inputdeck.get< tag::amr, tag::initial >();
+      print.item( "Initial refinement steps", initref.size() );
+
+      auto eps = std::numeric_limits< tk::real >::epsilon();
+
+      const auto& amr_coord = g_inputdeck.get< tag::amr, tag::coords >();
+      const auto& amr_defcoord = g_inputdeck_defaults.get< tag::amr, tag::coords >();
 
-        // allocate and initialize matrix and vector for reconstruction
-        std::vector< std::array< std::array< tk::real, 3 >, 3 > >
-          lhs_ls( nelem, {{ {{0.0, 0.0, 0.0}},
-                            {{0.0, 0.0, 0.0}},
-                            {{0.0, 0.0, 0.0}} }} );
-        std::vector< std::vector< std::array< tk::real, 3 > > >
-          rhs_ls( nelem, std::vector< std::array< tk::real, 3 > >
-            ( m_ncomp,
-              {{ 0.0, 0.0, 0.0 }} ) );
-
-        // reconstruct x,y,z-derivatives of unknowns
-        // 0. get lhs matrix, which is only geometry dependent
-        tk::lhsLeastSq_P0P1(fd, geoElem, geoFace, lhs_ls);
-
-        // 1. internal face contributions
-        std::vector< std::size_t > vars;
-        for (std::size_t c=0; c<m_ncomp; ++c) vars.push_back(c);
-        tk::intLeastSq_P0P1( rdof, fd, geoElem, U, rhs_ls, vars );
-
-        // 2. boundary face contributions
-        for (const auto& b : m_bc)
-          tk::bndLeastSqConservedVar_P0P1( m_ncomp,
-            m_mat_blk, rdof, b.first, fd, geoFace, geoElem, t, b.second,
-            P, U, rhs_ls, vars );
-
-        // 3. solve 3x3 least-squares system
-        tk::solveLeastSq_P0P1( rdof, lhs_ls, rhs_ls, U, vars );
-
-        // 4. transform reconstructed derivatives to Dubiner dofs
-        tk::transform_P0P1( rdof, nelem, inpoel, coord, U, vars );
-      }
-    }
-
-    //! Limit second-order solution
-    //! \param[in] t Physical time
-    //! \param[in] geoFace Face geometry array
-    //! \param[in] geoElem Element geometry array
-    //! \param[in] fd Face connectivity and boundary conditions object
-    //! \param[in] esup Elements surrounding points
-    //! \param[in] inpoel Element-node connectivity
-    //! \param[in] coord Array of nodal coordinates
-    //! \param[in] ndofel Vector of local number of degrees of freedome
-    //! \param[in] gid Local->global node id map
-    //! \param[in] bid Local chare-boundary node ids (value) associated to
-    //!   global node ids (key)
-    //! \param[in] uNodalExtrm Chare-boundary nodal extrema for conservative
-    //!   variables
-    //! \param[in] mtInv Inverse of Taylor mass matrix
-    //! \param[in,out] U Solution vector at recent time step
-    //! \param[in,out] shockmarker Vector of shock-marker values
-    void limit( [[maybe_unused]] tk::real t,
-                [[maybe_unused]] const tk::Fields& geoFace,
-                const tk::Fields& geoElem,
-                const inciter::FaceData& fd,
-                const std::map< std::size_t, std::vector< std::size_t > >& esup,
-                const std::vector< std::size_t >& inpoel,
-                const tk::UnsMesh::Coords& coord,
-                const std::vector< std::size_t >& ndofel,
-                const std::vector< std::size_t >& gid,
-                const std::unordered_map< std::size_t, std::size_t >& bid,
-                const std::vector< std::vector<tk::real> >& uNodalExtrm,
-                const std::vector< std::vector<tk::real> >&,
-                const std::vector< std::vector<tk::real> >& mtInv,
-                tk::Fields& U,
-                tk::Fields&,
-                std::vector< std::size_t >& shockmarker) const
-    {
-      const auto limiter = g_inputdeck.get< tag::limiter >();
-      const auto rdof = g_inputdeck.get< tag::rdof >();
-      const auto& solidx = g_inputdeck.get< tag::matidxmap, tag::solidx >();
-
-      if (limiter == ctr::LimiterType::WENOP1)
-        WENO_P1( fd.Esuel(), U );
-      else if (limiter == ctr::LimiterType::SUPERBEEP1)
-        Superbee_P1( fd.Esuel(), inpoel, ndofel, coord, U );
-      else if (limiter == ctr::LimiterType::VERTEXBASEDP1 && rdof == 4)
-        VertexBasedCompflow_P1( esup, inpoel, ndofel, fd.Esuel().size()/4,
-          m_mat_blk, fd, geoFace, geoElem, coord, flux, solidx, U,
-          shockmarker);
-      else if (limiter == ctr::LimiterType::VERTEXBASEDP1 && rdof == 10)
-        VertexBasedCompflow_P2( esup, inpoel, ndofel, fd.Esuel().size()/4,
-          m_mat_blk, fd, geoFace, geoElem, coord, gid, bid,
-          uNodalExtrm, mtInv, flux, solidx, U, shockmarker);
-    }
-
-    //! Update the conservative variable solution for this PDE system
-    //! \details This function computes the updated dofs for conservative
-    //!   quantities based on the limited solution and is currently not used in
-    //!   compflow.
-    void CPL( const tk::Fields&,
-              const tk::Fields&,
-              const std::vector< std::size_t >&,
-              const tk::UnsMesh::Coords&,
-              tk::Fields&,
-              std::size_t ) const {}
-
-    //! Return cell-average deformation gradient tensor (no-op for compflow)
-    //! \details This function is a no-op in compflow.
-    std::array< std::vector< tk::real >, 9 > cellAvgDeformGrad(
-      const tk::Fields&,
-      std::size_t ) const
-    {
-      return {};
-    }
-
-    //! Compute right hand side
-    //! \param[in] t Physical time
-    //! \param[in] geoFace Face geometry array
-    //! \param[in] geoElem Element geometry array
-    //! \param[in] fd Face connectivity and boundary conditions object
-    //! \param[in] inpoel Element-node connectivity
-    //! \param[in] boxelems Mesh node ids within user-defined IC boxes
-    //! \param[in] coord Array of nodal coordinates
-    //! \param[in] U Solution vector at recent time step
-    //! \param[in] P Primitive vector at recent time step
-    //! \param[in] ndofel Vector of local number of degrees of freedom
-    // //! \param[in] rho0mat Initial densities of all materials
-    //! \param[in] dt Delta time
-    //! \param[in,out] R Right-hand side vector computed
-    void rhs( tk::real t,
-              const tk::Fields& geoFace,
-              const tk::Fields& geoElem,
-              const inciter::FaceData& fd,
-              const std::vector< std::size_t >& inpoel,
-              const std::vector< std::unordered_set< std::size_t > >& boxelems,
-              const tk::UnsMesh::Coords& coord,
-              const tk::Fields& U,
-              const tk::Fields& P,
-              const std::vector< std::size_t >& ndofel,
-              const std::vector< tk::real >& /*rho0mat*/,
-              const tk::real dt,
-              tk::Fields& R ) const
-    {
-      const auto ndof = g_inputdeck.get< tag::ndof >();
-      const auto rdof = g_inputdeck.get< tag::rdof >();
-
-      const auto& solidx = g_inputdeck.get< tag::matidxmap, tag::solidx >();
-
-      Assert( U.nunk() == P.nunk(), "Number of unknowns in solution "
-              "vector and primitive vector at recent time step incorrect" );
-      Assert( U.nunk() == R.nunk(), "Number of unknowns in solution "
-              "vector and right-hand side at recent time step incorrect" );
-      Assert( U.nprop() == rdof*5, "Number of components in solution "
-              "vector must equal "+ std::to_string(rdof*5) );
-      Assert( P.nprop() == 0, "Number of components in primitive "
-              "vector must equal "+ std::to_string(0) );
-      Assert( R.nprop() == ndof*5, "Number of components in right-hand "
-              "side vector must equal "+ std::to_string(ndof*5) );
-      Assert( fd.Inpofa().size()/3 == fd.Esuf().size()/2,
-              "Mismatch in inpofa size" );
-
-      // set rhs to zero
-      R.fill(0.0);
-
-      // empty vector for non-conservative terms. This vector is unused for
-      // single-material hydrodynamics since, there are no non-conservative
-      // terms in the system of PDEs.
-      std::vector< std::vector < tk::real > > riemannDeriv;
-
-      std::vector< std::vector< tk::real > > vriem;
-      std::vector< std::vector< tk::real > > riemannLoc;
-
-      // configure a no-op lambda for prescribed velocity
-      auto velfn = []( ncomp_t, tk::real, tk::real, tk::real, tk::real ){
-        return tk::VelFn::result_type(); };
-
-      // compute internal surface flux integrals
-      tk::surfInt( 1, m_mat_blk, t, ndof, rdof, inpoel, solidx,
-                   coord, fd, geoFace, geoElem, m_riemann, velfn, U, P, ndofel,
-                   dt, R, vriem, riemannLoc, riemannDeriv );
-
-      // compute optional source term
-      tk::srcInt( m_mat_blk, t, ndof, fd.Esuel().size()/4,
-                  inpoel, coord, geoElem, Problem::src, ndofel, R );
-
-      if(ndof > 1)
-        // compute volume integrals
-        tk::volInt( 1, t, m_mat_blk, ndof, rdof,
-                    fd.Esuel().size()/4, inpoel, coord, geoElem, flux, velfn,
-                    U, P, ndofel, R );
-
-      // compute boundary surface flux integrals
-      for (const auto& b : m_bc)
-        tk::bndSurfInt( 1, m_mat_blk, ndof, rdof, b.first,
-                        fd, geoFace, geoElem, inpoel, coord, t, m_riemann,
-                        velfn, b.second, U, P, ndofel, R, vriem, riemannLoc,
-                        riemannDeriv );
-
-     // compute external (energy) sources
-      const auto& ic = g_inputdeck.get< tag::ic >();
-      const auto& icbox = ic.get< tag::box >();
-
-      if (!icbox.empty() && !boxelems.empty()) {
-        std::size_t bcnt = 0;
-        for (const auto& b : icbox) {   // for all boxes for this eq
-          std::vector< tk::real > box
-           { b.template get< tag::xmin >(), b.template get< tag::xmax >(),
-             b.template get< tag::ymin >(), b.template get< tag::ymax >(),
-             b.template get< tag::zmin >(), b.template get< tag::zmax >() };
+      auto xminus = amr_coord.get< tag::xminus >();
+      auto xminus_default = amr_defcoord.get< tag::xminus >();
+      if (std::abs( xminus - xminus_default ) > eps)
+        print.item( "Initial refinement x-", xminus );
+      auto xplus = amr_coord.get< tag::xplus >();
+      auto xplus_default = amr_defcoord.get< tag::xplus >();
+      if (std::abs( xplus - xplus_default ) > eps)
+        print.item( "Initial refinement x+", xplus );
+
+      auto yminus = amr_coord.get< tag::yminus >();
+      auto yminus_default = amr_defcoord.get< tag::yminus >();
+      if (std::abs( yminus - yminus_default ) > eps)
+        print.item( "Initial refinement y-", yminus );
+      auto yplus = amr_coord.get< tag::yplus >();
+      auto yplus_default = amr_defcoord.get< tag::yplus >();
+      if (std::abs( yplus - yplus_default ) > eps)
+        print.item( "Initial refinement y+", yplus );
+
+      auto zminus = amr_coord.get< tag::zminus >();
+      auto zminus_default = amr_defcoord.get< tag::zminus >();
+      if (std::abs( zminus - zminus_default ) > eps)
+        print.item( "Initial refinement z-", zminus );
+      auto zplus = amr_coord.get< tag::zplus >();
+      auto zplus_default = amr_defcoord.get< tag::zplus >();
+      if (std::abs( zplus - zplus_default ) > eps)
+        print.item( "Initial refinement z+", zplus );
+    }
+    auto dtref = g_inputdeck.get< tag::amr, tag::dtref >();
+    print.item( "Refinement at t>0 (dtref)", dtref );
+    if (dtref) {
+      auto dtfreq = g_inputdeck.get< tag::amr, tag::dtfreq >();
+      print.item( "Mesh refinement frequency, t>0", dtfreq );
+      print.item( "Uniform-only mesh refinement, t>0",
+                  g_inputdeck.get< tag::amr, tag::dtref_uniform >() );
+    }
+    print.item( "Refinement tolerance",
+                g_inputdeck.get< tag::amr, tag::tol_refine >() );
+    print.item( "De-refinement tolerance",
+                g_inputdeck.get< tag::amr, tag::tol_derefine >() );
+  }
+
+  // Print out ALE configuration
+  const auto ale = g_inputdeck.get< tag::ale, tag::ale >();
+  if (ale) {
+    print.section( "Arbitrary Lagrangian-Eulerian (ALE) mesh motion" );
+    auto dvcfl = g_inputdeck.get< tag::ale, tag::dvcfl >();
+    print.item( "Volume-change CFL coefficient", dvcfl );
+    print.Item< ctr::MeshVelocity, tag::ale, tag::mesh_velocity >();
+    print.Item< ctr::MeshVelocitySmoother, tag::ale, tag::smoother >();
+    print.item( "Mesh motion dimensions", tk::parameters(
+                g_inputdeck.get< tag::ale, tag::mesh_motion >() ) );
+    const auto& meshforce = g_inputdeck.get< tag::ale, tag::meshforce >();
+    print.item( "Mesh velocity force coefficients", tk::parameters(meshforce) );
+    print.item( "Vorticity multiplier",
+                g_inputdeck.get< tag::ale, tag::vortmult >() );
+    print.item( "Mesh velocity linear solver tolerance",
+                g_inputdeck.get< tag::ale, tag::tolerance >() );
+    print.item( "Mesh velocity linear solver maxit",
+                g_inputdeck.get< tag::ale, tag::maxit >() );
+    const auto& dir = g_inputdeck.get< tag::ale, tag::dirichlet >();
+    if (not dir.empty())
+      print.item( "Mesh velocity Dirichlet BC sideset(s)",
+                  tk::parameters( dir ) );
+    const auto& sym = g_inputdeck.get< tag::ale, tag::symmetry >();
+    if (not sym.empty())
+      print.item( "Mesh velocity symmetry BC sideset(s)",
+                  tk::parameters( sym ) );
+    std::size_t i = 1;
+    for (const auto& m : g_inputdeck.get< tag::ale, tag::move >()) {
+       tk::ctr::UserTable opt;
+       print.item( opt.group() + ' ' + std::to_string(i) + " interpreted as",
+                   opt.name( m.get< tag::fntype >() ) );
+       const auto& s = m.get< tag::sideset >();
+       if (not s.empty())
+         print.item( "Moving sideset(s) with table " + std::to_string(i),
+                     tk::parameters(s));
+       ++i;
+    }
+  }
+
+  // Print I/O filenames
+  print.section( "Input/Output filenames and directories" );
+  print.item( "Input mesh(es)", tk::parameters( m_input ) );
+  const auto& of = g_inputdeck.get< tag::cmd, tag::io, tag::output >();
+  print.item( "Volume field output file(s)",
+              of + ".e-s.<meshid>.<numchares>.<chareid>" );
+  print.item( "Surface field output file(s)",
+              of + "-surf.<surfid>.e-s.<meshid>.<numchares>.<chareid>" );
+  print.item( "History output file(s)", of + ".hist.{pointid}" );
+  print.item( "Diagnostics file",
+              g_inputdeck.get< tag::cmd, tag::io, tag::diag >() );
+  print.item( "Checkpoint/restart directory",
+              g_inputdeck.get< tag::cmd, tag::io, tag::restart >() + '/' );
+
+  // Print output intervals
+  print.section( "Output intervals (in units of iteration count)" );
+  print.item( "TTY", g_inputdeck.get< tag::ttyi>() );
+  print.item( "Field and surface",
+              g_inputdeck.get< tag::field_output, tag::interval >() );
+  print.item( "History",
+              g_inputdeck.get< tag::history_output, tag::interval >() );
+  print.item( "Diagnostics",
+              g_inputdeck.get< tag::diagnostics, tag::interval >() );
+  print.item( "Checkpoint/restart",
+              g_inputdeck.get< tag::cmd, tag::rsfreq >() );
+  auto tf = g_inputdeck.get< tag::field_output, tag::time_interval >();
+  auto th = g_inputdeck.get< tag::history_output, tag::time_interval >();
+  if (tf>0.0 || th>0.0) {
+    print.section( "Output intervals (in units of physics time)" );
+    if (tf > 0.0) print.item( "Field and surface", tf );
+    if (th > 0.0) print.item( "History", th );
+  }
+  const auto& rf = g_inputdeck.get< tag::field_output, tag::time_range >();
+  const auto& rh = g_inputdeck.get< tag::history_output, tag::time_range >();
+  if (not rf.empty() or not rh.empty()) {
+    print.section( "Output time ranges (in units of physics time)" );
+    print.item("Field output { mintime, maxtime, dt }", tk::parameters(rf));
+    print.item("History output { mintime, maxtime, dt }", tk::parameters(rh));
+  }
+
+  //// Print output variables: fields and surfaces
+  //const auto nodeoutvars = g_inputdeck.outvars( tk::Centering::NODE );
+  //const auto elemoutvars = g_inputdeck.outvars( tk::Centering::ELEM );
+  //const auto outsets = g_inputdeck.outsets();
+  //if (!nodeoutvars.empty() || !elemoutvars.empty() || !outsets.empty())
+  //   print.section( "Output fields" );
+  //if (!nodeoutvars.empty())
+  //  print.item( "Node field(s)", tk::parameters(nodeoutvars) );
+  //if (!elemoutvars.empty())
+  //  print.item( "Elem field(s)", tk::parameters(elemoutvars) );
+  //if (!aliases.empty())
+  //  print.item( "Alias(es)", tk::parameters(aliases) );
+  //if (!outsets.empty())
+  //  print.item( "Surface side set(s)", tk::parameters(outsets) );
+
+  // Print output variables: history
+  const auto& pt = g_inputdeck.get< tag::history_output, tag::point >();
+  if (!pt.empty()) {
+    print.section( "Output time history" );
+    for (std::size_t p=0; p<pt.size(); ++p) {
+      const auto& id = pt[p].get< tag::id >();
+      std::stringstream ss;
+      auto prec = g_inputdeck.get< tag::history_output, tag::precision >();
+      ss << std::setprecision( static_cast<int>(prec) );
+      ss << of << ".hist." << id;
+      print.longitem( "At point " + id + ' ' +
+        tk::parameters(pt[p].get<tag::coord>()), ss.str() );
+    }
+  }
+
+  print.endsubsection();
+}
+
+bool
+Transporter::matchBCs( std::map< int, std::vector< std::size_t > >& bnd )
+// *****************************************************************************
+ // Verify that side sets specified in the control file exist in mesh file
+ //! \details This function does two things: (1) it verifies that the side
+ //!   sets used in the input file (either to which boundary conditions (BC)
+ //!   are assigned or listed as field output by the user in the
+ //!   input file) all exist among the side sets read from the input mesh
+ //!   file and errors out if at least one does not, and (2) it matches the
+ //!   side set ids at which the user has configured BCs (or listed as an output
+ //!   surface) to side set ids read from the mesh file and removes those face
+ //!   and node lists associated to side sets that the user did not set BCs or
+ //!   listed as field output on (as they will not need processing further since
+ //!   they will not be used).
+ //! \param[in,out] bnd Node or face lists mapped to side set ids
+ //! \return True if sidesets have been used and found in mesh
+// *****************************************************************************
+{
+  // Query side set ids at which BCs assigned for all BC types for all PDEs
+  using bclist = ctr::bclist::Keys;
+  std::unordered_set< int > usedsets;
+  brigand::for_each< bclist >( UserBC( g_inputdeck, usedsets ) );
+
+  // Query side sets of time dependent BCs (since tag::bctimedep is not a part
+  // of tag::bc)
+  const auto& bcs = g_inputdeck.get< tag::bc >();
+  for (const auto& bci : bcs) {
+    for (const auto& b : bci.get< tag::timedep >()) {
+      for (auto i : b.get< tag::sideset >())
+        usedsets.insert(static_cast<int>(i));
+    }
+  }
+
+  // Query side sets of boundaries prescribed as moving with ALE
+  for (const auto& move : g_inputdeck.get< tag::ale, tag::move >())
+    for (auto i : move.get< tag::sideset >())
+      usedsets.insert(static_cast<int>(i));
+
+  // Add sidesets requested for field output
+  const auto& ss = g_inputdeck.get< tag::cmd, tag::io, tag::surface >();
+  for (const auto& s : ss) {
+    std::stringstream conv( s );
+    int num;
+    conv >> num;
+    usedsets.insert( num );
+  }
 
-          const auto& initiate = b.template get< tag::initiate >();
-          if (initiate == ctr::InitiateType::LINEAR) {
-            boxSrc( t, inpoel, boxelems[bcnt], coord, geoElem, ndofel, R );
-          }
-          ++bcnt;
-        }
-      }
-    }
-
-    //! Evaluate the adaptive indicator and mark the ndof for each element
-    //! \param[in] nunk Number of unknowns
-    //! \param[in] coord Array of nodal coordinates
-    //! \param[in] inpoel Element-node connectivity
-    //! \param[in] fd Face connectivity and boundary conditions object
-    //! \param[in] unk Array of unknowns
-    //! \param[in] prim Array of primitive quantities
-    //! \param[in] indicator p-refinement indicator type
-    //! \param[in] ndof Number of degrees of freedom in the solution
-    //! \param[in] ndofmax Max number of degrees of freedom for p-refinement
-    //! \param[in] tolref Tolerance for p-refinement
-    //! \param[in,out] ndofel Vector of local number of degrees of freedome
-    void eval_ndof( std::size_t nunk,
-                    const tk::UnsMesh::Coords& coord,
-                    const std::vector< std::size_t >& inpoel,
-                    const inciter::FaceData& fd,
-                    const tk::Fields& unk,
-                    const tk::Fields& prim,
-                    inciter::ctr::PrefIndicatorType indicator,
-                    std::size_t ndof,
-                    std::size_t ndofmax,
-                    tk::real tolref,
-                    std::vector< std::size_t >& ndofel ) const
-    {
-      const auto& esuel = fd.Esuel();
-
-      if(indicator == inciter::ctr::PrefIndicatorType::SPECTRAL_DECAY)
-        spectral_decay( 1, nunk, esuel, unk, prim, ndof, ndofmax, tolref,
-          ndofel );
-      else if(indicator == inciter::ctr::PrefIndicatorType::NON_CONFORMITY)
-        non_conformity( nunk, fd.Nbfac(), inpoel, coord, esuel, fd.Esuf(),
-          fd.Inpofa(), unk, ndof, ndofmax, ndofel );
-      else
-        Throw( "No such adaptive indicator type" );
-    }
-
-    //! Compute the minimum time step size
-    //! \param[in] coord Mesh node coordinates
-    //! \param[in] inpoel Mesh element connectivity
-    //! \param[in] fd Face connectivity and boundary conditions object
-    //! \param[in] geoFace Face geometry array
-    //! \param[in] geoElem Element geometry array
-    //! \param[in] ndofel Vector of local number of degrees of freedom
-    //! \param[in] U Solution vector at recent time step
-    //! \return Minimum time step size
-    tk::real dt( const std::array< std::vector< tk::real >, 3 >& coord,
-                 const std::vector< std::size_t >& inpoel,
-                 const inciter::FaceData& fd,
-                 const tk::Fields& geoFace,
-                 const tk::Fields& geoElem,
-                 const std::vector< std::size_t >& ndofel,
-                 const tk::Fields& U,
-                 const tk::Fields&,
-                 const std::size_t /*nielem*/ ) const
-    {
-      const auto rdof = g_inputdeck.get< tag::rdof >();
-
-      const auto& esuf = fd.Esuf();
-      const auto& inpofa = fd.Inpofa();
+  // Find user-configured side set ids among side sets read from mesh file
+  std::unordered_set< int > sidesets_used;
+  for (auto i : usedsets) {       // for all side sets used in control file
+    if (bnd.find(i) != end(bnd))  // used set found among side sets in file
+      sidesets_used.insert( i );  // store side set id configured as BC
+    //else {
+    //  Throw( "Boundary conditions specified on side set " +
+    //    std::to_string(i) + " which does not exist in mesh file" );
+    //}
+  }
+
+  // Remove sidesets not used (will not process those further)
+  tk::erase_if( bnd, [&]( auto& item ) {
+    return sidesets_used.find( item.first ) == end(sidesets_used);
+  });
+
+  return !bnd.empty();
+}
+
+void
+Transporter::createPartitioner()
+// *****************************************************************************
+// Create mesh partitioner AND boundary conditions group
+// *****************************************************************************
+{
+  auto scheme = g_inputdeck.get< tag::scheme >();
+  auto centering = ctr::Scheme().centering( scheme );
+  auto print = printer();
+
+  // Create partitioner callbacks (order important)
+  tk::PartitionerCallback cbp {{
+      CkCallback( CkReductionTarget(Transporter,load), thisProxy )
+    , CkCallback( CkReductionTarget(Transporter,partitioned), thisProxy )
+    , CkCallback( CkReductionTarget(Transporter,distributed), thisProxy )
+    , CkCallback( CkReductionTarget(Transporter,refinserted), thisProxy )
+    , CkCallback( CkReductionTarget(Transporter,refined), thisProxy )
+  }};
+
+  // Create refiner callbacks (order important)
+  tk::RefinerCallback cbr {{
+      CkCallback( CkReductionTarget(Transporter,queriedRef), thisProxy )
+    , CkCallback( CkReductionTarget(Transporter,respondedRef), thisProxy )
+    , CkCallback( CkReductionTarget(Transporter,compatibility), thisProxy )
+    , CkCallback( CkReductionTarget(Transporter,bndint), thisProxy )
+    , CkCallback( CkReductionTarget(Transporter,matched), thisProxy )
+    , CkCallback( CkReductionTarget(Transporter,refined), thisProxy )
+  }};
+
+  // Create sorter callbacks (order important)
+  tk::SorterCallback cbs {{
+      CkCallback( CkReductionTarget(Transporter,queried), thisProxy )
+    , CkCallback( CkReductionTarget(Transporter,responded), thisProxy )
+    , CkCallback( CkReductionTarget(Transporter,discinserted), thisProxy )
+    , CkCallback( CkReductionTarget(Transporter,workinserted), thisProxy )
+  }};
+
+  // Start timer measuring preparation of mesh(es) for partitioning
+  m_timer[ TimerTag::MESH_READ ];
+
+  // Start preparing mesh(es)
+  print.diag( "Reading mesh(es)" );
+
+  // Create (discretization) Scheme chare worker arrays for all meshes
+  for ([[maybe_unused]] const auto& filename : m_input)
+    m_scheme.emplace_back( g_inputdeck.get< tag::scheme >(),
+                           g_inputdeck.get< tag::ale, tag::ale >(),
+                           need_linearsolver(),
+                           centering );
 
-      tk::real rho, u, v, w, rhoE, p, a, vn, dSV_l, dSV_r;
-      std::vector< tk::real > delt( U.nunk(), 0.0 );
-
-      const auto& cx = coord[0];
-      const auto& cy = coord[1];
-      const auto& cz = coord[2];
-
-      // compute internal surface maximum characteristic speed
-      for (std::size_t f=0; f<esuf.size()/2; ++f)
-      {
+  ErrChk( !m_input.empty(), "No input mesh" );
+
+  // Read boundary (side set) data from a list of input mesh files
+  std::size_t meshid = 0;
+  for (const auto& filename : m_input) {
+    // Create mesh reader for reading side sets from file
+    tk::MeshReader mr( filename );
+
+    // Read out total number of mesh points from mesh file
+    m_npoin.push_back( mr.npoin() );
 
-        std::size_t el = static_cast< std::size_t >(esuf[2*f]);
-        auto er = esuf[2*f+1];
-
-        // Number of quadrature points for  face integration
-        std::size_t ng;
-
-        if(er > -1)
-        {
-          auto eR = static_cast< std::size_t >( er );
+    std::map< int, std::vector< std::size_t > > bface;
+    std::map< int, std::vector< std::size_t > > faces;
+    std::map< int, std::vector< std::size_t > > bnode;
+
+    // Read boundary-face connectivity on side sets
+    mr.readSidesetFaces( bface, faces );
+
+    bool bcs_set = false;
+    if (centering == tk::Centering::ELEM) {
 
-          auto ng_l = tk::NGfa(ndofel[el]);
-          auto ng_r = tk::NGfa(ndofel[eR]);
+      // Verify boundarty condition (BC) side sets used exist in mesh file
+      bcs_set = matchBCs( bface );
 
-          // When the number of gauss points for the left and right element are
-          // different, choose the larger ng
-          ng = std::max( ng_l, ng_r );
-        }
-        else
-        {
-          ng = tk::NGfa(ndofel[el]);
-        }
-
-        // arrays for quadrature points
-        std::array< std::vector< tk::real >, 2 > coordgp;
-        std::vector< tk::real > wgp;
+    } else if (centering == tk::Centering::NODE) {
+
+      // Read node lists on side sets
+      bnode = mr.readSidesetNodes();
+      // Verify boundarty condition (BC) side sets used exist in mesh file
+      bool bcnode_set = matchBCs( bnode );
+      bool bcface_set = matchBCs( bface );
+      bcs_set = bcface_set or bcnode_set;
+    }
+
+    // Warn on no BCs
+    if (!bcs_set) print << "\n>>> WARNING: No boundary conditions set\n\n";
 
-        coordgp[0].resize( ng );
-        coordgp[1].resize( ng );
-        wgp.resize( ng );
-
-        // get quadrature point weights and coordinates for triangle
-        tk::GaussQuadratureTri( ng, coordgp, wgp );
-
-        // Extract the left element coordinates
-        std::array< std::array< tk::real, 3>, 4 > coordel_l {{
-          {{ cx[inpoel[4*el  ]], cy[inpoel[4*el  ]], cz[inpoel[4*el  ]] }},
-          {{ cx[inpoel[4*el+1]], cy[inpoel[4*el+1]], cz[inpoel[4*el+1]] }},
-          {{ cx[inpoel[4*el+2]], cy[inpoel[4*el+2]], cz[inpoel[4*el+2]] }},
-          {{ cx[inpoel[4*el+3]], cy[inpoel[4*el+3]], cz[inpoel[4*el+3]] }} }};
+    auto opt = m_scheme[meshid].arrayoptions();
+    // Create empty mesh refiner chare array (bound to workers)
+    m_refiner.push_back( CProxy_Refiner::ckNew(opt) );
+    // Create empty mesh sorter Charm++ chare array (bound to workers)
+    m_sorter.push_back( CProxy_Sorter::ckNew(opt) );
+
+    // Create MeshWriter chare group for mesh
+    m_meshwriter.push_back(
+      tk::CProxy_MeshWriter::ckNew(
+        g_inputdeck.get< tag::field_output, tag::filetype >(),
+        centering,
+        g_inputdeck.get< tag::cmd, tag::benchmark >(),
+        m_input.size() ) );
 
-        // Compute the determinant of Jacobian matrix
-        auto detT_l = 
-           tk::Jacobian(coordel_l[0], coordel_l[1], coordel_l[2], coordel_l[3]);
-
-        // Extract the face coordinates
-        std::array< std::array< tk::real, 3>, 3 > coordfa {{
-          {{ cx[ inpofa[3*f  ] ], cy[ inpofa[3*f  ] ], cz[ inpofa[3*f  ] ] }},
-          {{ cx[ inpofa[3*f+1] ], cy[ inpofa[3*f+1] ], cz[ inpofa[3*f+1] ] }},
-          {{ cx[ inpofa[3*f+2] ], cy[ inpofa[3*f+2] ], cz[ inpofa[3*f+2] ] }}
-        }};
-
-        dSV_l = 0.0;<--- Variable 'dSV_l' is assigned a value that is never used.
-        dSV_r = 0.0;
-
-        // Gaussian quadrature
-        for (std::size_t igp=0; igp<ng; ++igp)
-        {
-          // Compute the coordinates of quadrature point at physical domain
-          auto gp = tk::eval_gp( igp, coordfa, coordgp );
-
-          // Compute the basis function for the left element
-          auto B_l = tk::eval_basis( ndofel[el],
-            tk::Jacobian(coordel_l[0], gp, coordel_l[2], coordel_l[3])/detT_l,
-            tk::Jacobian(coordel_l[0], coordel_l[1], gp, coordel_l[3])/detT_l,
-            tk::Jacobian(coordel_l[0], coordel_l[1], coordel_l[2], gp)/detT_l );
-
-          auto wt = wgp[igp] * geoFace(f,0);
-
-          std::array< std::vector< tk::real >, 2 > ugp;
-
-          // left element
-          for (ncomp_t c=0; c<5; ++c)
-          {
-            auto mark = c*rdof;
-            ugp[0].push_back( U(el, mark) );
+    // Create mesh partitioner Charm++ chare nodegroup for all meshes
+    m_partitioner.push_back(
+      CProxy_Partitioner::ckNew( meshid, filename, cbp, cbr, cbs,
+        thisProxy, m_refiner.back(), m_sorter.back(), m_meshwriter.back(),
+        m_scheme, bface, faces, bnode ) );
+
+    ++meshid;
+  }
+}
+
+void
+Transporter::load( std::size_t meshid, std::size_t nelem )
+// *****************************************************************************
+// Reduction target: the mesh has been read from file on all PEs
+//! \param[in] meshid Mesh id (summed accross all compute nodes)
+//! \param[in] nelem Number of mesh elements per mesh (summed across all
+//!    compute nodes)
+// *****************************************************************************
+{
+  meshid /= static_cast< std::size_t >( CkNumNodes() );
+  Assert( meshid < m_nelem.size(), "MeshId indexing out" );
+  m_nelem[meshid] = nelem;
+
+  // Compute load distribution given total work (nelem) and user-specified
+  // virtualization
+  uint64_t chunksize, remainder;
+  m_nchare[meshid] = static_cast<int>(
+    tk::linearLoadDistributor(
+       g_inputdeck.get< tag::cmd, tag::virtualization >(),
+       m_nelem[meshid], CkNumPes(), chunksize, remainder ) );
+
+  // Store sum of meshids (across all chares, key) for each meshid (value).
+  // This is used to look up the mesh id after collectives that sum their data.
+  m_meshid[ static_cast<std::size_t>(m_nchare[meshid])*meshid ] = meshid;
+  Assert( meshid < m_nelem.size(), "MeshId indexing out" );
 
-            if(ndofel[el] > 1)          //DG(P1)
-              ugp[0][c] +=  U(el, mark+1) * B_l[1]
-                          + U(el, mark+2) * B_l[2]
-                          + U(el, mark+3) * B_l[3];
-
-            if(ndofel[el] > 4)          //DG(P2)
-              ugp[0][c] +=  U(el, mark+4) * B_l[4]
-                          + U(el, mark+5) * B_l[5]
-                          + U(el, mark+6) * B_l[6]
-                          + U(el, mark+7) * B_l[7]
-                          + U(el, mark+8) * B_l[8]
-                          + U(el, mark+9) * B_l[9];
-          }
-
-          rho = ugp[0][0];
-          u = ugp[0][1]/rho;
-          v = ugp[0][2]/rho;
-          w = ugp[0][3]/rho;
-          rhoE = ugp[0][4];
-          p = m_mat_blk[0].compute< EOS::pressure >( rho, u, v, w, rhoE );
-
-          a = m_mat_blk[0].compute< EOS::soundspeed >( rho, p );
-
-          vn = u*geoFace(f,1) + v*geoFace(f,2) + w*geoFace(f,3);
+  // Tell the meshwriter for this mesh the total number of its chares
+  m_meshwriter[meshid].nchare( meshid, m_nchare[meshid] );
+
+  if (++m_nload == m_nelem.size()) {     // all meshes have been loaded
+    m_nload = 0;
+    auto print = printer();
+
+    // Start timer measuring preparation of the mesh for partitioning
+    const auto& timer = tk::cref_find( m_timer, TimerTag::MESH_READ );
+    print.diag( "Mesh read time: " + std::to_string( timer.dsec() ) + " sec" );
+
+    // Print out mesh partitioning configuration
+    print.section( "Mesh partitioning" );
+    print.Item< tk::ctr::PartitioningAlgorithm, tag::partitioning >();
+    print.item( "Virtualization [0.0...1.0]",
+                g_inputdeck.get< tag::cmd, tag::virtualization >() );
+    // Print out initial mesh statistics
+    meshstat( "Initial load distribution" );
+
+    // Query number of initial mesh refinement steps
+    int nref = 0;
+    if (g_inputdeck.get< tag::amr, tag::t0ref >())
+      nref = static_cast<int>(g_inputdeck.get< tag::amr,
+        tag::initial >().size());
 
-          dSV_l = wt * (std::fabs(vn) + a);
-
-          // right element
-          if (er > -1) {
-
-            // nodal coordinates of the right element
-            std::size_t eR = static_cast< std::size_t >( er );
+    m_progMesh.start( print, "Preparing mesh", {{ CkNumPes(), CkNumPes(), nref,
+      m_nchare[0], m_nchare[0], m_nchare[0], m_nchare[0] }} );
+
+    // Partition first mesh
+    m_partitioner[0].partition( m_nchare[0] );
+  }
+}
 
-            // Extract the left element coordinates
-            std::array< std::array< tk::real, 3>, 4 > coordel_r {{
-              {{ cx[inpoel[4*eR  ]], cy[inpoel[4*eR  ]], cz[inpoel[4*eR  ]] }},
-              {{ cx[inpoel[4*eR+1]], cy[inpoel[4*eR+1]], cz[inpoel[4*eR+1]] }},
-              {{ cx[inpoel[4*eR+2]], cy[inpoel[4*eR+2]], cz[inpoel[4*eR+2]] }},
-              {{ cx[inpoel[4*eR+3]], cy[inpoel[4*eR+3]], cz[inpoel[4*eR+3]] }}
-            }};
-
-            // Compute the determinant of Jacobian matrix
-            auto detT_r =
-              tk::Jacobian(coordel_r[0],coordel_r[1],coordel_r[2],coordel_r[3]);
-
-            // Compute the coordinates of quadrature point at physical domain
-            gp = tk::eval_gp( igp, coordfa, coordgp );
-
-            // Compute the basis function for the right element
-            auto B_r = tk::eval_basis( ndofel[eR],
-              tk::Jacobian(coordel_r[0],gp,coordel_r[2],coordel_r[3])/detT_r,
-              tk::Jacobian(coordel_r[0],coordel_r[1],gp,coordel_r[3])/detT_r,
-              tk::Jacobian(coordel_r[0],coordel_r[1],coordel_r[2],gp)/detT_r );
- 
-            for (ncomp_t c=0; c<5; ++c)
-            {
-              auto mark = c*rdof;
-              ugp[1].push_back( U(eR, mark) );
-
-              if(ndofel[eR] > 1)          //DG(P1)
-                ugp[1][c] +=  U(eR, mark+1) * B_r[1]
-                            + U(eR, mark+2) * B_r[2]
-                            + U(eR, mark+3) * B_r[3];
-
-              if(ndofel[eR] > 4)         //DG(P2)
-                ugp[1][c] +=  U(eR, mark+4) * B_r[4]
-                            + U(eR, mark+5) * B_r[5]
-                            + U(eR, mark+6) * B_r[6]
-                            + U(eR, mark+7) * B_r[7]
-                            + U(eR, mark+8) * B_r[8]
-                            + U(eR, mark+9) * B_r[9];
-            }
-
-            rho = ugp[1][0];
-            u = ugp[1][1]/rho;
-            v = ugp[1][2]/rho;
-            w = ugp[1][3]/rho;
-            rhoE = ugp[1][4];
-            p = m_mat_blk[0].compute< EOS::pressure >( rho, u, v, w, rhoE );
-            a = m_mat_blk[0].compute< EOS::soundspeed >( rho, p );
-
-            vn = u*geoFace(f,1) + v*geoFace(f,2) + w*geoFace(f,3);
-
-            dSV_r = wt * (std::fabs(vn) + a);
-            delt[eR] += std::max( dSV_l, dSV_r );
-          }
-
-          delt[el] += std::max( dSV_l, dSV_r );
-        }
-      }
+void
+Transporter::partitioned( std::size_t meshid )
+// *****************************************************************************
+// Reduction target: a mesh has been partitioned
+//! \param[in] meshid Mesh id
+// *****************************************************************************
+{
+  if (++m_npart == m_nelem.size()) {     // all meshes have been partitioned
+    m_npart = 0;
+  } else { // partition next mesh
+    m_partitioner[meshid+1].partition( m_nchare[meshid+1] );
+  }
+}
+
+void
+Transporter::distributed( std::size_t meshid )
+// *****************************************************************************
+// Reduction target: all compute nodes have distributed their mesh after
+// partitioning
+//! \param[in] meshid Mesh id
+// *****************************************************************************
+{
+  m_partitioner[meshid].refine();
+}
+
+void
+Transporter::refinserted( std::size_t meshid, std::size_t error )
+// *****************************************************************************
+// Reduction target: all compute nodes have created the mesh refiners
+//! \param[in] meshid Mesh id (aggregated across all compute nodes with operator
+//!   max)
+//! \param[in] error Error code (aggregated across all compute nodes with
+//!   operator max)
+// *****************************************************************************
+{
+  if (error) {
+
+    printer() << "\n>>> ERROR: A worker chare was not assigned any mesh "
+              "elements after distributing mesh " + std::to_string(meshid) +
+              ". This can happen in SMP-mode with a large +ppn "
+              "parameter (number of worker threads per logical node) and is "
+              "most likely the fault of the mesh partitioning algorithm not "
+              "tolerating the case when it is asked to divide the "
+              "computational domain into a number of partitions different "
+              "than the number of ranks it is called on, i.e., in case of "
+              "overdecomposition and/or calling the partitioner in SMP mode "
+              "with +ppn larger than 1. Solution 1: Try a different "
+              "partitioning algorithm (e.g., rcb instead of mj). Solution 2: "
+              "Decrease +ppn.";
+    finish( meshid );
+
+  } else {
+
+     m_refiner[meshid].doneInserting();
+
+  }
+}
 
-      tk::real mindt = std::numeric_limits< tk::real >::max();
-      tk::real dgp = 0.0;<--- Variable 'dgp' is assigned a value that is never used.
-
-      // compute allowable dt
-      for (std::size_t e=0; e<fd.Esuel().size()/4; ++e)
-      {
-        dgp = 0.0;
-        if (ndofel[e] == 4)
-        {
-          dgp = 1.0;
-        }
-        else if (ndofel[e] == 10)
-        {
-          dgp = 2.0;
-        }
-
-        // Scale smallest dt with CFL coefficient and the CFL is scaled by (2*p+1)
-        // where p is the order of the DG polynomial by linear stability theory.
-        mindt = std::min( mindt, geoElem(e,0)/ (delt[e] * (2.0*dgp + 1.0)) );
-      }
-
-      return mindt;
-    }
-
-    //! Compute stiff terms for a single element, not implemented here
-    // //! \param[in] e Element number
-    // //! \param[in] geoElem Element geometry array
-    // //! \param[in] inpoel Element-node connectivity
-    // //! \param[in] coord Array of nodal coordinates
-    // //! \param[in] U Solution vector at recent time step
-    // //! \param[in] P Primitive vector at recent time step
-    // //! \param[in] ndofel Vector of local number of degrees of freedom
-    // //! \param[in,out] R Right-hand side vector computed
-    void stiff_rhs( std::size_t /*e*/,
-                    const tk::Fields& /*geoElem*/,
-                    const std::vector< std::size_t >& /*inpoel*/,
-                    const tk::UnsMesh::Coords& /*coord*/,
-                    const tk::Fields& /*U*/,
-                    const tk::Fields& /*P*/,
-                    const std::vector< std::size_t >& /*ndofel*/,
-                    tk::Fields& /*R*/ ) const
-    {}
-
-    //! Extract the velocity field at cell nodes. Currently unused.
-    //! \param[in] U Solution vector at recent time step
-    //! \param[in] N Element node indices
-    //! \return Array of the four values of the velocity field
-    std::array< std::array< tk::real, 4 >, 3 >
-    velocity( const tk::Fields& U,
-              const std::array< std::vector< tk::real >, 3 >&,
-              const std::array< std::size_t, 4 >& N ) const
-    {
-      std::array< std::array< tk::real, 4 >, 3 > v;
-      v[0] = U.extract( 1, N );
-      v[1] = U.extract( 2, N );
-      v[2] = U.extract( 3, N );
-      auto r = U.extract( 0, N );
-      std::transform( r.begin(), r.end(), v[0].begin(), v[0].begin(),
-                      []( tk::real s, tk::real& d ){ return d /= s; } );
-      std::transform( r.begin(), r.end(), v[1].begin(), v[1].begin(),
-                      []( tk::real s, tk::real& d ){ return d /= s; } );
-      std::transform( r.begin(), r.end(), v[2].begin(), v[2].begin(),
-                      []( tk::real s, tk::real& d ){ return d /= s; } );
-      return v;
-    }
+void
+Transporter::queriedRef( std::size_t meshid )
+// *****************************************************************************
+// Reduction target: all Refiner chares have queried their boundary edges
+//! \param[in] meshid Mesh id
+// *****************************************************************************
+{
+  m_refiner[meshid].response();
+}
+
+void
+Transporter::respondedRef( std::size_t meshid )
+// *****************************************************************************
+// Reduction target: all Refiner chares have setup their boundary edges
+//! \param[in] meshid Mesh id
+// *****************************************************************************
+{
+  m_refiner[meshid].refine();
+}
+
+void
+Transporter::compatibility( std::size_t meshid )
+// *****************************************************************************
+// Reduction target: all Refiner chares have received a round of edges,
+// and have run their compatibility algorithm
+//! \param[in] meshid Mesh id (aggregated across all chares using operator max)
+//! \details This is called iteratively, until convergence by Refiner. At this
+//!   point all Refiner chares have received a round of edge data (tags whether
+//!   an edge needs to be refined, etc.), and applied the compatibility
+//!   algorithm independent of other Refiner chares. We keep going until the
+//!   mesh is no longer modified by the compatibility algorithm, based on a new
+//!   round of edge data communication started in Refiner::comExtra().
+// *****************************************************************************
+{
+  m_refiner[meshid].correctref();
+}
+
+void
+Transporter::matched( std::size_t summeshid,
+                      std::size_t nextra,
+                      std::size_t nref,
+                      std::size_t nderef,
+                      std::size_t sumrefmode )
+// *****************************************************************************
+// Reduction target: all Refiner chares have matched/corrected the tagging
+// of chare-boundary edges, all chares are ready to perform refinement.
+//! \param[in] summeshid Mesh id (summed across all chares)
+//! \param[in] nextra Sum (across all chares) of the number of edges on each
+//!   chare that need correction along chare boundaries
+//! \param[in] nref Sum of number of refined tetrahedra across all chares.
+//! \param[in] nderef Sum of number of derefined tetrahedra across all chares.
+//! \param[in] sumrefmode Sum of contributions from all chares, encoding
+//!   refinement mode of operation.
+// *****************************************************************************
+{
+  auto meshid = tk::cref_find( m_meshid, summeshid );
+
+  // If at least a single edge on a chare still needs correction, do correction,
+  // otherwise, this mesh refinement step is complete
+  if (nextra > 0) {
+
+    ++m_ncit[meshid];
+    m_refiner[meshid].comExtra();
+
+  } else {
 
-    //! Return a map that associates user-specified strings to functions
-    //! \return Map that associates user-specified strings to functions that
-    //!   compute relevant quantities to be output to file
-    std::map< std::string, tk::GetVarFn > OutVarFn() const
-    { return CompFlowOutVarFn(); }
+    auto print = printer();
+
+    // decode refmode
+    auto refmode = static_cast< Refiner::RefMode >(
+                     sumrefmode / static_cast<std::size_t>(m_nchare[meshid]) );
 
-    //! Return analytic field names to be output to file
-    //! \return Vector of strings labelling analytic fields output in file
-    std::vector< std::string > analyticFieldNames() const
-    { return m_problem.analyticFieldNames( m_ncomp ); }
-
-    //! Return time history field names to be output to file
-    //! \return Vector of strings labeling time history fields output in file
-    std::vector< std::string > histNames() const
-    { return CompFlowHistNames(); }
-
-    //! Return surface field output going to file
-    std::vector< std::vector< tk::real > >
-    surfOutput( const std::map< int, std::vector< std::size_t > >&,
-                tk::Fields& ) const
-    {
-      std::vector< std::vector< tk::real > > s; // punt for now
-      return s;
-    }
-
-    //! Return time history field output evaluated at time history points
-    //! \param[in] h History point data
-    //! \param[in] inpoel Element-node connectivity
-    //! \param[in] coord Array of nodal coordinates
-    //! \param[in] U Array of unknowns
-    std::vector< std::vector< tk::real > >
-    histOutput( const std::vector< HistData >& h,
-                const std::vector< std::size_t >& inpoel,
-                const tk::UnsMesh::Coords& coord,
-                const tk::Fields& U,
-                const tk::Fields& ) const
-    {
-      const auto rdof = g_inputdeck.get< tag::rdof >();
-
-      const auto& x = coord[0];
-      const auto& y = coord[1];
-      const auto& z = coord[2];
-
-      std::vector< std::vector< tk::real > > Up(h.size());
-
-      std::size_t j = 0;
-      for (const auto& p : h) {
-        auto e = p.get< tag::elem >();
-        auto chp = p.get< tag::coord >();
-
-        // Evaluate inverse Jacobian
-        std::array< std::array< tk::real, 3>, 4 > cp{{
-          {{ x[inpoel[4*e  ]], y[inpoel[4*e  ]], z[inpoel[4*e  ]] }},
-          {{ x[inpoel[4*e+1]], y[inpoel[4*e+1]], z[inpoel[4*e+1]] }},
-          {{ x[inpoel[4*e+2]], y[inpoel[4*e+2]], z[inpoel[4*e+2]] }},
-          {{ x[inpoel[4*e+3]], y[inpoel[4*e+3]], z[inpoel[4*e+3]] }} }};
-        auto J = tk::inverseJacobian( cp[0], cp[1], cp[2], cp[3] );
-
-        // evaluate solution at history-point
-        std::array< tk::real, 3 > dc{{chp[0]-cp[0][0], chp[1]-cp[0][1],
-          chp[2]-cp[0][2]}};
-        auto B = tk::eval_basis(rdof, tk::dot(J[0],dc), tk::dot(J[1],dc),
-          tk::dot(J[2],dc));
-        auto uhp = eval_state(m_ncomp, rdof, rdof, e, U, B);
-
-        // store solution in history output vector
-        Up[j].resize(6, 0.0);
-        Up[j][0] = uhp[0];
-        Up[j][1] = uhp[1]/uhp[0];
-        Up[j][2] = uhp[2]/uhp[0];
-        Up[j][3] = uhp[3]/uhp[0];
-        Up[j][4] = uhp[4]/uhp[0];
-        Up[j][5] = m_mat_blk[0].compute< EOS::pressure >( uhp[0], uhp[1]/uhp[0],
-          uhp[2]/uhp[0], uhp[3]/uhp[0], uhp[4] );
-        ++j;
-      }
-
-      return Up;
-    }
-
-    //! Return names of integral variables to be output to diagnostics file
-    //! \return Vector of strings labelling integral variables output
-    std::vector< std::string > names() const
-    { return m_problem.names( m_ncomp ); }
-
-    //! Return analytic solution (if defined by Problem) at xi, yi, zi, t
-    //! \param[in] xi X-coordinate at which to evaluate the analytic solution
-    //! \param[in] yi Y-coordinate at which to evaluate the analytic solution
-    //! \param[in] zi Z-coordinate at which to evaluate the analytic solution
-    //! \param[in] t Physical time at which to evaluate the analytic solution
-    //! \return Vector of analytic solution at given location and time
-    std::vector< tk::real >
-    analyticSolution( tk::real xi, tk::real yi, tk::real zi, tk::real t ) const
-    { return Problem::analyticSolution( m_ncomp, m_mat_blk, xi, yi,
-                                        zi, t ); }
-
-    //! Return analytic solution for conserved variables
-    //! \param[in] xi X-coordinate at which to evaluate the analytic solution
-    //! \param[in] yi Y-coordinate at which to evaluate the analytic solution
-    //! \param[in] zi Z-coordinate at which to evaluate the analytic solution
-    //! \param[in] t Physical time at which to evaluate the analytic solution
-    //! \return Vector of analytic solution at given location and time
-    std::vector< tk::real >
-    solution( tk::real xi, tk::real yi, tk::real zi, tk::real t ) const
-    { return Problem::initialize( m_ncomp, m_mat_blk, xi, yi, zi, t ); }
-
-    //! Return cell-averaged specific total energy for an element
-    //! \param[in] e Element id for which total energy is required
-    //! \param[in] unk Vector of conserved quantities
-    //! \return Cell-averaged specific total energy for given element
-    tk::real sp_totalenergy(std::size_t e, const tk::Fields& unk) const
-    {
-      const auto rdof = g_inputdeck.get< tag::rdof >();
-
-      return unk(e,4*rdof);
-    }
-
-  private:
-    //! Physics policy
-    const Physics m_physics;
-    //! Problem policy
-    const Problem m_problem;
-    //! Number of components in this PDE system
-    const ncomp_t m_ncomp;
-    //! Riemann solver
-    tk::RiemannFluxFn m_riemann;
-    //! BC configuration
-    BCStateFn m_bc;
-    //! EOS material block
-    std::vector< EOS > m_mat_blk;
-
-    //! Evaluate physical flux function for this PDE system
-    //! \param[in] ncomp Number of scalar components in this PDE system
-    //! \param[in] mat_blk EOS material block
-    //! \param[in] ugp Numerical solution at the Gauss point at which to
-    //!   evaluate the flux
-    //! \return Flux vectors for all components in this PDE system
-    //! \note The function signature must follow tk::FluxFn
-    static tk::FluxFn::result_type
-    flux( [[maybe_unused]] ncomp_t ncomp,
-          const std::vector< EOS >& mat_blk,
-          const std::vector< tk::real >& ugp,
-          const std::vector< std::array< tk::real, 3 > >& )
-    {
-      Assert( ugp.size() == ncomp, "Size mismatch" );
-
-      auto u = ugp[1] / ugp[0];
-      auto v = ugp[2] / ugp[0];
-      auto w = ugp[3] / ugp[0];
-      auto p = mat_blk[0].compute< EOS::pressure >( ugp[0], u, v, w, ugp[4] );
-
-      std::vector< std::array< tk::real, 3 > > fl( ugp.size() );
-
-      fl[0][0] = ugp[1];
-      fl[1][0] = ugp[1] * u + p;
-      fl[2][0] = ugp[1] * v;
-      fl[3][0] = ugp[1] * w;
-      fl[4][0] = u * (ugp[4] + p);
-
-      fl[0][1] = ugp[2];
-      fl[1][1] = ugp[2] * u;
-      fl[2][1] = ugp[2] * v + p;
-      fl[3][1] = ugp[2] * w;
-      fl[4][1] = v * (ugp[4] + p);
-
-      fl[0][2] = ugp[3];
-      fl[1][2] = ugp[3] * u;
-      fl[2][2] = ugp[3] * v;
-      fl[3][2] = ugp[3] * w + p;
-      fl[4][2] = w * (ugp[4] + p);
-
-      return fl;
-    }
-
-    //! \brief Boundary state function providing the left and right state of a
-    //!   face at Dirichlet boundaries
-    //! \param[in] ncomp Number of scalar components in this PDE system
-    //! \param[in] mat_blk EOS material block
-    //! \param[in] ul Left (domain-internal) state
-    //! \param[in] x X-coordinate at which to compute the states
-    //! \param[in] y Y-coordinate at which to compute the states
-    //! \param[in] z Z-coordinate at which to compute the states
-    //! \param[in] t Physical time
-    //! \return Left and right states for all scalar components in this PDE
-    //!   system
-    //! \note The function signature must follow tk::StateFn
-    static tk::StateFn::result_type
-    dirichlet( ncomp_t ncomp,
-               const std::vector< EOS >& mat_blk,
-               const std::vector< tk::real >& ul, tk::real x, tk::real y,
-               tk::real z, tk::real t, const std::array< tk::real, 3 >& )
-    {
-      return {{ ul, Problem::initialize( ncomp, mat_blk, x, y, z, t ) }};
-    }
-
-    //! \brief Boundary state function providing the left and right state of a
-    //!   face at symmetry boundaries
-    //! \param[in] ul Left (domain-internal) state
-    //! \param[in] fn Unit face normal
-    //! \return Left and right states for all scalar components in this PDE
-    //!   system
-    //! \note The function signature must follow tk::StateFn
-    static tk::StateFn::result_type
-    symmetry( ncomp_t, const std::vector< EOS >&,
-              const std::vector< tk::real >& ul, tk::real, tk::real, tk::real,
-              tk::real, const std::array< tk::real, 3 >& fn )
-    {
-      std::vector< tk::real > ur(5);
-      // Internal cell velocity components
-      auto v1l = ul[1]/ul[0];
-      auto v2l = ul[2]/ul[0];
-      auto v3l = ul[3]/ul[0];
-      // Normal component of velocity
-      auto vnl = v1l*fn[0] + v2l*fn[1] + v3l*fn[2];
-      // Ghost state velocity components
-      auto v1r = v1l - 2.0*vnl*fn[0];
-      auto v2r = v2l - 2.0*vnl*fn[1];
-      auto v3r = v3l - 2.0*vnl*fn[2];
-      // Boundary condition
-      ur[0] = ul[0];
-      ur[1] = ur[0] * v1r;
-      ur[2] = ur[0] * v2r;
-      ur[3] = ur[0] * v3r;
-      ur[4] = ul[4];
-      return {{ std::move(ul), std::move(ur) }};
-    }
-
-    //! \brief Boundary state function providing the left and right state of a
-    //!   face at farfield boundaries
-    //! \param[in] mat_blk EOS material block
-    //! \param[in] ul Left (domain-internal) state
-    //! \param[in] fn Unit face normal
-    //! \return Left and right states for all scalar components in this PDE
-    //!   system
-    //! \note The function signature must follow tk::StateFn
-    static tk::StateFn::result_type
-    farfield( ncomp_t, const std::vector< EOS >& mat_blk,
-              const std::vector< tk::real >& ul, tk::real, tk::real, tk::real,
-              tk::real, const std::array< tk::real, 3 >& fn )
-    {
-      // Primitive variables from farfield
-      const auto& bc = g_inputdeck.get< tag::bc >()[0];
-      auto frho = bc.get< tag::density >();
-      auto fp   = bc.get< tag::pressure >();
-      const auto& fu = bc.get< tag::velocity >();
-
-      // Speed of sound from farfield
-      auto fa = mat_blk[0].compute< EOS::soundspeed >( frho, fp );
+    if (refmode == Refiner::RefMode::T0REF) {
+
+      if (!g_inputdeck.get< tag::cmd, tag::feedback >()) {
+        ctr::AMRInitial opt;
+        print.diag( { "meshid", "t0ref", "type", "nref", "nderef", "ncorr" },
+                    { std::to_string(meshid),
+                      std::to_string(m_nt0refit[meshid]),
+                      "initial",
+                      std::to_string(nref),
+                      std::to_string(nderef),
+                      std::to_string(m_ncit[meshid]) } );
+        ++m_nt0refit[meshid];
+      }
+      m_progMesh.inc< REFINE >( print );
+
+    } else if (refmode == Refiner::RefMode::DTREF) {
+
+      auto dtref_uni = g_inputdeck.get< tag::amr, tag::dtref_uniform >();
+      print.diag( { "meshid", "dtref", "type", "nref", "nderef", "ncorr" },
+                  { std::to_string(meshid),
+                    std::to_string(++m_ndtrefit[meshid]),
+                    (dtref_uni?"uniform":"error"),
+                    std::to_string(nref),
+                    std::to_string(nderef),
+                    std::to_string(m_ncit[meshid]) },
+                  false );
+
+    } else if (refmode == Refiner::RefMode::OUTREF) {
+
+      print.diag( { "meshid", "outref", "nref", "nderef", "ncorr" },
+                  { std::to_string(meshid),
+                    std::to_string(++m_noutrefit[meshid]),
+                    std::to_string(nref),
+                    std::to_string(nderef),
+                    std::to_string(m_ncit[meshid]) }, false );
+
+    } else if (refmode == Refiner::RefMode::OUTDEREF) {
+
+      print.diag( { "meshid", "outderef", "nref", "nderef", "ncorr" },
+                  { std::to_string(meshid),
+                    std::to_string(++m_noutderefit[meshid]),
+                    std::to_string(nref),
+                    std::to_string(nderef),
+                    std::to_string(m_ncit[meshid]) },
+                  false );
+
+    } else Throw( "RefMode not implemented" );
+
+    m_ncit[meshid] = 0;
+    m_refiner[meshid].perform();
+
+  }
+}
+
+void
+Transporter::bndint( tk::real sx, tk::real sy, tk::real sz, tk::real cb,
+                     tk::real summeshid )
+// *****************************************************************************
+// Compute surface integral across the whole problem and perform leak-test
+//! \param[in] sx X component of vector summed
+//! \param[in] sy Y component of vector summed
+//! \param[in] sz Z component of vector summed
+//! \param[in] cb Invoke callback if positive
+//! \param[in] summeshid Mesh id (summed accross all chares)
+//! \details This function aggregates partial surface integrals across the
+//!   boundary faces of the whole problem. After this global sum a
+//!   non-zero vector result indicates a leak, e.g., a hole in the boundary,
+//!   which indicates an error in the boundary face data structures used to
+//!   compute the partial surface integrals.
+// *****************************************************************************
+{
+  auto meshid = tk::cref_find( m_meshid, static_cast<std::size_t>(summeshid) );
+
+  std::stringstream err;
+  if (cb < 0.0) {
+    err << "Mesh boundary leaky after mesh refinement step; this is due to a "
+     "problem with updating the side sets used to specify boundary conditions "
+     "on faces: ";
+  } else if (cb > 0.0) {
+    err << "Mesh boundary leaky during initialization; this is due to "
+    "incorrect or incompletely specified boundary conditions for a given input "
+    "mesh: ";
+  }
+
+  auto eps = 1.0e-10;
+  if (std::abs(sx) > eps || std::abs(sy) > eps || std::abs(sz) > eps) {
+    err << "Integral result must be a zero vector: " << std::setprecision(12) <<
+           std::abs(sx) << ", " << std::abs(sy) << ", " << std::abs(sz) <<
+           ", eps = " << eps;
+    Throw( err.str() );
+  }
+
+  if (cb > 0.0) m_scheme[meshid].ghosts().resizeComm();
+}
+
+void
+Transporter::refined( std::size_t summeshid,
+                      std::size_t nelem,
+                      std::size_t npoin )
+// *****************************************************************************
+// Reduction target: all chares have refined their mesh
+//! \param[in] summeshid Mesh id (summed accross all Refiner chares)
+//! \param[in] nelem Total number of elements in mesh summed across the
+//!   distributed mesh
+//! \param[in] npoin Total number of mesh points summed across the distributed
+//!   mesh. Note that in parallel this is larger than the number of points in
+//!   the mesh, because the boundary nodes are multi-counted. But we only need
+//!   an equal or larger than npoin for Sorter::setup, so this is okay.
+// *****************************************************************************
+{
+  auto meshid = tk::cref_find( m_meshid, summeshid );
+
+  // Store new number of elements for initially refined mesh
+  m_nelem[meshid] = nelem;
+
+  m_sorter[meshid].doneInserting();
+  m_sorter[meshid].setup( npoin );
+}
+
+void
+Transporter::queried( std::size_t meshid )
+// *****************************************************************************
+// Reduction target: all Sorter chares have queried their boundary edges
+//! \param[in] meshid Mesh id
+// *****************************************************************************
+{
+  m_sorter[meshid].response();
+}
+
+void
+Transporter::responded( std::size_t meshid )
+// *****************************************************************************
+// Reduction target: all Sorter chares have responded with their boundary edges
+//! \param[in] meshid Mesh id
+// *****************************************************************************
+{
+  m_sorter[meshid].start();
+}
+
+void
+Transporter::resized( std::size_t meshid )
+// *****************************************************************************
+// Reduction target: all worker chares have resized their own mesh data after
+// AMR or ALE
+//! \param[in] meshid Mesh id
+//! \note Only used for nodal schemes
+// *****************************************************************************
+{
+  m_scheme[meshid].disc().vol();
+  m_scheme[meshid].bcast< Scheme::lhs >();
+}
+
+void
+Transporter::startEsup( std::size_t meshid )
+// *****************************************************************************
+// Reduction target: all worker chares have generated their own esup
+//! \param[in] meshid Mesh id
+//! \note Only used for cell-centered schemes
+// *****************************************************************************
+{
+  m_scheme[meshid].ghosts().nodeNeighSetup();
+}
+
+void
+Transporter::discinserted( std::size_t meshid )
+// *****************************************************************************
+// Reduction target: all Discretization chares have been inserted
+//! \param[in] meshid Mesh id
+// *****************************************************************************
+{
+  m_scheme[meshid].disc().doneInserting();
+}
+
+void
+Transporter::meshstat( const std::string& header ) const
+// *****************************************************************************
+// Print out mesh statistics
+//! \param[in] header Section header
+// *****************************************************************************
+{
+  auto print = printer();
+
+  print.section( header );
+
+  if (m_nelem.size() > 1) {
+    print.item( "Number of tetrahedra (per mesh)",tk::parameters(m_nelem) );
+    print.item( "Number of points (per mesh)", tk::parameters(m_npoin) );
+    print.item( "Number of work units (per mesh)", tk::parameters(m_nchare) );
+  }
+
+  print.item( "Total number of tetrahedra",
+              std::accumulate( begin(m_nelem), end(m_nelem), 0UL ) );
+  print.item( "Total number of points",
+              std::accumulate( begin(m_npoin), end(m_npoin), 0UL ) );
+  print.item( "Total number of work units",
+              std::accumulate( begin(m_nchare), end(m_nchare), 0 ) );
+
+  print.endsubsection();
+}
+
+bool
+Transporter::need_linearsolver() const
+// *****************************************************************************
+//  Decide if we need a linear solver for ALE
+//! \return True if ALE will neeed a linear solver
+// *****************************************************************************
+{
+  auto smoother = g_inputdeck.get< tag::ale, tag::smoother >();
+
+  if ( g_inputdeck.get< tag::ale, tag::ale >() and
+       (smoother == ctr::MeshVelocitySmootherType::LAPLACE ||
+        smoother == ctr::MeshVelocitySmootherType::HELMHOLTZ) )
+  {
+     return true;
+  } else {
+     return false;
+  }
+}
+
+void
+Transporter::disccreated( std::size_t summeshid, std::size_t npoin )
+// *****************************************************************************
+// Reduction target: all Discretization constructors have been called
+//! \param[in] summeshid Mesh id (summed accross all chares)
+//! \param[in] npoin Total number of mesh points (summed across all chares)
+//!  Note that as opposed to npoin in refined(), this npoin is not
+//!  multi-counted, and thus should be correct in parallel.
+// *****************************************************************************
+{
+  auto meshid = tk::cref_find( m_meshid, summeshid );
+  //std::cout << "Trans: " << meshid << " Transporter::disccreated()\n";
+
+  // Update number of mesh points for mesh, since it may have been refined
+  if (g_inputdeck.get< tag::amr, tag::t0ref >()) m_npoin[meshid] = npoin;
+
+  if (++m_ndisc == m_nelem.size()) { // all Disc arrays have been created
+    m_ndisc = 0;
+    auto print = printer();
+    m_progMesh.end( print );
+    if (g_inputdeck.get< tag::amr, tag::t0ref >())
+      meshstat( "Initially (t<0) refined mesh graph statistics" );
+  }
 
-      // Normal component from farfield
-      auto fvn = fu[0]*fn[0] + fu[1]*fn[1] + fu[2]*fn[2];
-
-      // Mach number from farfield
-      auto fM = fvn / fa;
-
-      // Specific total energy from farfield
-      auto frhoE = mat_blk[0].compute< EOS::totalenergy >( frho, fu[0], fu[1],
-        fu[2], fp );
-
-      // Pressure from internal cell
-      auto p = mat_blk[0].compute< EOS::pressure >( ul[0], ul[1]/ul[0],
-        ul[2]/ul[0], ul[3]/ul[0], ul[4] );
-
-      auto ur = ul;
-
-      if(fM <= -1)                         // Supersonic inflow<--- Assuming that condition 'fM<=-1' is not redundant<--- Assuming that condition 'fM<=-1' is not redundant<--- Assuming that condition 'fM<=-1' is not redundant
-      {
-        // For supersonic inflow, all the characteristics are from outside.
-        // Therefore, we calculate the ghost cell state using the primitive
-        // variables from outside.
-        ur[0] = frho;
-        ur[1] = frho * fu[0];
-        ur[2] = frho * fu[1];
-        ur[3] = frho * fu[2];
-        ur[4] = frhoE;
-      } else if(fM > -1 && fM < 0)       // Subsonic inflow<--- Condition 'fM>-1' is always true<--- Condition 'fM<0' is always false
-      {
-        // For subsonic inflow, there are 1 outgoing characteristcs and 4
-        // incoming characteristic. Therefore, we calculate the ghost cell state
-        // by taking pressure from the internal cell and other quantities from
-        // the outside.
-        ur[0] = frho;
-        ur[1] = frho * fu[0];
-        ur[2] = frho * fu[1];
-        ur[3] = frho * fu[2];
-        ur[4] = mat_blk[0].compute< EOS::totalenergy >( frho, fu[0], fu[1],
-          fu[2], p );
-      } else if(fM >= 0 && fM < 1)       // Subsonic outflow<--- Condition 'fM>=0' is always true
-      {
-        // For subsonic outflow, there are 1 incoming characteristcs and 4
-        // outgoing characteristic. Therefore, we calculate the ghost cell state
-        // by taking pressure from the outside and other quantities from the
-        // internal cell.
-        ur[4] = mat_blk[0].compute< EOS::totalenergy >( ul[0], ul[1]/ul[0],
-          ul[2]/ul[0], ul[3]/ul[0], fp );
-      }
-      // Otherwise, for supersonic outflow, all the characteristics are from
-      // internal cell. Therefore, we calculate the ghost cell state using the
-      // conservative variables from outside.
-
-      return {{ ul, ur }};
-    }
-
-    //! \brief Boundary state function providing the left and right state of a
-    //!   face at extrapolation boundaries
-    //! \param[in] ul Left (domain-internal) state
-    //! \return Left and right states for all scalar components in this PDE
-    //!   system
-    //! \note The function signature must follow tk::StateFn
-    static tk::StateFn::result_type
-    extrapolate( ncomp_t, const std::vector< EOS >&,
-                 const std::vector< tk::real >& ul, tk::real, tk::real,
-                 tk::real, tk::real, const std::array< tk::real, 3 >& )
-    {
-      return {{ ul, ul }};
-    }
+  m_refiner[meshid].sendProxy();
+
+  if (g_inputdeck.get< tag::ale, tag::ale >())
+    m_scheme[meshid].ale().doneInserting();
+
+  if (need_linearsolver())
+    m_scheme[meshid].conjugategradients().doneInserting();
+
+  m_scheme[meshid].disc().vol();
+}
+
+void
+Transporter::workinserted( std::size_t meshid )
+// *****************************************************************************
+// Reduction target: all worker (derived discretization) chares have been
+// inserted
+//! \param[in] meshid Mesh id
+// *****************************************************************************
+{
+  m_scheme[meshid].bcast< Scheme::doneInserting >();
+}
+
+void
+Transporter::diagHeader()
+// *****************************************************************************
+// Configure and write diagnostics file header
+// *****************************************************************************
+{
+  for (std::size_t m=0; m<m_input.size(); ++m) {
+
+   // Output header for diagnostics output file
+    auto mid = m_input.size() > 1 ? std::string( '.' + std::to_string(m) ) : "";
+    tk::DiagWriter dw( g_inputdeck.get< tag::cmd, tag::io, tag::diag >() + mid,
+      g_inputdeck.get< tag::diagnostics, tag::format >(),
+      g_inputdeck.get< tag::diagnostics, tag::precision >() );
+
+    // Collect variables names for integral/diagnostics output
+    std::vector< std::string > var;
+    const auto scheme = g_inputdeck.get< tag::scheme >();
+    if ( scheme == ctr::SchemeType::ALECG ||
+         scheme == ctr::SchemeType::OversetFE )
+      for (const auto& eq : g_cgpde) varnames( eq, var );
+    else if ( scheme == ctr::SchemeType::DG ||
+              scheme == ctr::SchemeType::P0P1 ||
+              scheme == ctr::SchemeType::DGP1 ||
+              scheme == ctr::SchemeType::DGP2 ||
+              scheme == ctr::SchemeType::PDG )
+      for (const auto& eq : g_dgpde) varnames( eq, var );
+    else if (scheme == ctr::SchemeType::FV)
+      for (const auto& eq : g_fvpde) varnames( eq, var );
+    else Throw( "Diagnostics header not handled for discretization scheme" );
+
+    const tk::ctr::Error opt;
+    auto nv = var.size() / m_input.size();
+    std::vector< std::string > d;
+
+    // Add 'L2(var)' for all variables as those are always computed
+    const auto& l2name = opt.name( tk::ctr::ErrorType::L2 );
+    for (std::size_t i=0; i<nv; ++i) d.push_back( l2name + '(' + var[i] + ')' );
+
+    // Query user-requested diagnostics and augment diagnostics file header by
+    // 'err(var)', where 'err' is the error type  configured, and var is the
+    // variable computed, for all variables and all error types configured.
+    const auto& err = g_inputdeck.get< tag::diagnostics, tag::error >();
+    const auto& errname = opt.name( err );
+    for (std::size_t i=0; i<nv; ++i)
+      d.push_back( errname + '(' + var[i] + "-IC)" );
 
-    //! Compute sources corresponding to a propagating front in user-defined box
-    //! \param[in] t Physical time
-    //! \param[in] inpoel Element point connectivity
-    //! \param[in] boxelems Mesh node ids within user-defined box
-    //! \param[in] coord Mesh node coordinates
-    //! \param[in] geoElem Element geometry array
-    //! \param[in] ndofel Vector of local number of degrees of freedome
-    //! \param[in] R Right-hand side vector
-    //! \details This function add the energy source corresponding to a planar
-    //!   wave-front propagating along the z-direction with a user-specified
-    //!   velocity, within a box initial condition, configured by the user.
-    //!   Example (SI) units of the quantities involved:
-    //!    * internal energy content (energy per unit volume): J/m^3
-    //!    * specific energy (internal energy per unit mass): J/kg
-    void boxSrc( tk::real t,
-                 const std::vector< std::size_t >& inpoel,
-                 const std::unordered_set< std::size_t >& boxelems,
-                 const tk::UnsMesh::Coords& coord,
-                 const tk::Fields& geoElem,
-                 const std::vector< std::size_t >& ndofel,
-                 tk::Fields& R ) const
-    {
-      const auto ndof = g_inputdeck.get< tag::ndof >();<--- Variable 'ndof' is assigned a value that is never used.
-      const auto& ic = g_inputdeck.get< tag::ic >();
-      const auto& icbox = ic.get< tag::box >();
+    // Augment diagnostics variables by L2-norm of the residual and total energy
+    if ( scheme == ctr::SchemeType::ALECG ||
+         scheme == ctr::SchemeType::OversetFE ||
+         scheme == ctr::SchemeType::FV )
+    {
+      for (std::size_t i=0; i<nv; ++i) d.push_back( "L2(d" + var[i] + ')' );
+    }
+    d.push_back( "mE" );
+
+    // Write diagnostics header
+    dw.header( d );
+
+  }
+}
+
+void
+Transporter::doneInsertingGhosts(std::size_t meshid)
+// *****************************************************************************
+// Reduction target indicating all "ghosts" insertions are done
+//! \param[in] meshid Mesh id
+// *****************************************************************************
+{
+  m_scheme[meshid].ghosts().doneInserting();
+  m_scheme[meshid].ghosts().startCommSetup();
+}
 
-      for (const auto& b : icbox) {   // for all boxes for this eq
-        std::vector< tk::real > box
-         { b.template get< tag::xmin >(), b.template get< tag::xmax >(),
-           b.template get< tag::ymin >(), b.template get< tag::ymax >(),
-           b.template get< tag::zmin >(), b.template get< tag::zmax >() };
-
-        auto boxenc = b.template get< tag::energy_content >();
-        Assert( boxenc > 0.0, "Box energy content must be nonzero" );
-
-        auto V_ex = (box[1]-box[0]) * (box[3]-box[2]) * (box[5]-box[4]);
-
-        // determine times at which sourcing is initialized and terminated
-        auto iv = b.template get< tag::front_speed >();
-        auto wFront = 0.1;
-        auto tInit = 0.0;
-        auto tFinal = tInit + (box[5] - box[4] - 2.0*wFront) / std::fabs(iv);
-        auto aBox = (box[1]-box[0]) * (box[3]-box[2]);
-
-        const auto& cx = coord[0];
-        const auto& cy = coord[1];
-        const auto& cz = coord[2];
-
-        if (t >= tInit && t <= tFinal) {
-          // The energy front is assumed to have a half-sine-wave shape. The
-          // half wave-length is the width of the front. At t=0, the center of
-          // this front (i.e. the peak of the partial-sine-wave) is at X_0 +
-          // W_0.  W_0 is calculated based on the width of the front and the
-          // direction of propagation (which is assumed to be along the
-          // z-direction).  If the front propagation velocity is positive, it
-          // is assumed that the initial position of the energy source is the
-          // minimum z-coordinate of the box; whereas if this velocity is
-          // negative, the initial position is the maximum z-coordinate of the
-          // box.
-
-          // Orientation of box
-          std::array< tk::real, 3 > b_orientn{{
-            b.template get< tag::orientation >()[0],
-            b.template get< tag::orientation >()[1],
-            b.template get< tag::orientation >()[2] }};
-          std::array< tk::real, 3 > b_centroid{{ 0.5*(box[0]+box[1]),
-            0.5*(box[2]+box[3]), 0.5*(box[4]+box[5]) }};
-          // Transform box to reference space
-          std::array< tk::real, 3 > b_min{{box[0], box[2], box[4]}};
-          std::array< tk::real, 3 > b_max{{box[1], box[3], box[5]}};
-          tk::movePoint(b_centroid, b_min);
-          tk::movePoint(b_centroid, b_max);
-
-          // initial center of front
-          tk::real zInit(b_min[2]);
-          if (iv < 0.0) zInit = b_max[2];
-          // current location of front
-          auto z0 = zInit + iv*t;
-          auto z1 = z0 + std::copysign(wFront, iv);
-          tk::real s0(z0), s1(z1);
-          // if velocity of propagation is negative, initial position is z1
-          if (iv < 0.0) {
-            s0 = z1;
-            s1 = z0;
-          }
-          // Sine-wave (positive part of the wave) source term amplitude
-          auto pi = 4.0 * std::atan(1.0);
-          auto amplE = boxenc * V_ex * pi
-            / (aBox * wFront * 2.0 * (tFinal-tInit));
-          //// Square wave (constant) source term amplitude
-          //auto amplE = boxenc * V_ex
-          //  / (aBox * wFront * (tFinal-tInit));
+void
+Transporter::comfinal( std::size_t initial, std::size_t summeshid )
+// *****************************************************************************
+// Reduction target indicating that communication maps have been setup
+//! \param[in] initial Sum of contributions from all chares. If larger than
+//!    zero, we are during time stepping and if zero we are during setup.
+//! \param[in] summeshid Mesh id (summed accross the distributed mesh)
+// *****************************************************************************
+// [Discretization-specific communication maps]
+{
+  auto meshid = tk::cref_find( m_meshid, static_cast<std::size_t>(summeshid) );
+
+  if (initial > 0) {
+    m_scheme[meshid].bcast< Scheme::setup >();
+    // Turn on automatic load balancing
+    if (++m_ncom == m_nelem.size()) { // all worker arrays have finished
+      m_ncom = 0;
+      auto print = printer();
+      m_progWork.end( print );
+      tk::CProxy_LBSwitch::ckNew();
+      print.diag( "Load balancing on (if enabled in Charm++)" );
+    }
+  } else {
+    m_scheme[meshid].bcast< Scheme::lhs >();
+  }
+}
+// [Discretization-specific communication maps]
+
+void
+Transporter::totalvol( tk::real v, tk::real initial, tk::real summeshid )
+// *****************************************************************************
+// Reduction target summing total mesh volume across all workers
+//! \param[in] v Mesh volume summed across the distributed mesh
+//! \param[in] initial Sum of contributions from all chares. If larger than
+//!    zero, we are during setup, if zero, during time stepping.
+//! \param[in] summeshid Mesh id (summed accross the distributed mesh)
+// *****************************************************************************
+{
+  auto meshid = tk::cref_find( m_meshid, static_cast<std::size_t>(summeshid) );
+
+  m_meshvol[meshid] = v;
+
+  if (initial > 0.0)   // during initialization
+    m_scheme[meshid].disc().stat( v );
+  else                  // during ALE or AMR
+    m_scheme[meshid].bcast< Scheme::resized >();
+}
+
+void
+Transporter::minstat( tk::real d0, tk::real d1, tk::real d2, tk::real rmeshid )
+// *****************************************************************************
+// Reduction target yielding minimum mesh statistcs across all workers
+//! \param[in] d0 Minimum mesh statistics collected over all chares
+//! \param[in] d1 Minimum mesh statistics collected over all chares
+//! \param[in] d2 Minimum mesh statistics collected over all chares
+//! \param[in] rmeshid Mesh id as a real
+// *****************************************************************************
+{
+  auto meshid = static_cast<std::size_t>(rmeshid);
+
+  m_minstat[meshid][0] = d0;  // minimum edge length
+  m_minstat[meshid][1] = d1;  // minimum cell volume cubic root
+  m_minstat[meshid][2] = d2;  // minimum number of cells on chare
+
+  minstat_complete(meshid);
+}
 
-          // add source
-          for (auto e : boxelems) {
-            std::array< tk::real, 3 > node{{ geoElem(e,1), geoElem(e,2),
-              geoElem(e,3) }};
-            // Transform node to reference space of box
-            tk::movePoint(b_centroid, node);
-            tk::rotatePoint({{-b_orientn[0], -b_orientn[1], -b_orientn[2]}},
-              node);
-
-            if (node[2] >= s0 && node[2] <= s1) {
-              auto ng = tk::NGvol(ndofel[e]);
+void
+Transporter::maxstat( tk::real d0, tk::real d1, tk::real d2, tk::real rmeshid )
+// *****************************************************************************
+// Reduction target yielding the maximum mesh statistics across all workers
+//! \param[in] d0 Maximum mesh statistics collected over all chares
+//! \param[in] d1 Maximum mesh statistics collected over all chares
+//! \param[in] d2 Maximum mesh statistics collected over all chares
+//! \param[in] rmeshid Mesh id as a real
+// *****************************************************************************
+{
+  auto meshid = static_cast<std::size_t>(rmeshid);
 
-              // arrays for quadrature points
-              std::array< std::vector< tk::real >, 3 > coordgp;
-              std::vector< tk::real > wgp;
+  m_maxstat[meshid][0] = d0;  // maximum edge length
+  m_maxstat[meshid][1] = d1;  // maximum cell volume cubic root
+  m_maxstat[meshid][2] = d2;  // maximum number of cells on chare
 
-              coordgp[0].resize( ng );
-              coordgp[1].resize( ng );
-              coordgp[2].resize( ng );
-              wgp.resize( ng );
-
-              tk::GaussQuadratureTet( ng, coordgp, wgp );
-
-              // Extract the element coordinates
-              std::array< std::array< tk::real, 3>, 4 > coordel{{
-              {{ cx[inpoel[4*e  ]], cy[inpoel[4*e  ]], cz[inpoel[4*e  ]] }},
-              {{ cx[inpoel[4*e+1]], cy[inpoel[4*e+1]], cz[inpoel[4*e+1]] }},
-              {{ cx[inpoel[4*e+2]], cy[inpoel[4*e+2]], cz[inpoel[4*e+2]] }},
-              {{ cx[inpoel[4*e+3]], cy[inpoel[4*e+3]], cz[inpoel[4*e+3]] }}}};
-
-              for (std::size_t igp=0; igp<ng; ++igp) {
-                // Compute the coordinates of quadrature point at physical
-                // domain
-                auto gp = tk::eval_gp( igp, coordel, coordgp );
+  maxstat_complete(meshid);
+}
+
+void
+Transporter::sumstat( tk::real d0, tk::real d1, tk::real d2, tk::real d3,
+                      tk::real d4, tk::real d5, tk::real summeshid )
+// *****************************************************************************
+// Reduction target yielding the sum mesh statistics across all workers
+//! \param[in] d0 Sum mesh statistics collected over all chares
+//! \param[in] d1 Sum mesh statistics collected over all chares
+//! \param[in] d2 Sum mesh statistics collected over all chares
+//! \param[in] d3 Sum mesh statistics collected over all chares
+//! \param[in] d4 Sum mesh statistics collected over all chares
+//! \param[in] d5 Sum mesh statistics collected over all chares
+//! \param[in] summeshid Mesh id (summed accross the distributed mesh)
+// *****************************************************************************
+{
+  auto meshid = tk::cref_find( m_meshid, static_cast<std::size_t>(summeshid) );
 
-                // Transform quadrature point to reference space of box
-                tk::movePoint(b_centroid, gp);
-                tk::rotatePoint({{-b_orientn[0], -b_orientn[1], -b_orientn[2]}},
-                  gp);
-
-                // Compute the basis function
-                auto B = tk::eval_basis( ndofel[e], coordgp[0][igp],
-                                         coordgp[1][igp], coordgp[2][igp] );
-
-                // Compute the source term variable
-                std::vector< tk::real > s(5, 0.0);
-                s[4] = amplE * std::sin(pi*(gp[2]-s0)/wFront);
-
-                auto wt = wgp[igp] * geoElem(e, 0);
-
-                tk::update_rhs( ndof, ndofel[e], wt, e, B, s, R );
-              }
-            }
-          }
-        }
-      }
-    }
-};
-
-} // dg::
-
-} // inciter::
-
-#endif // DGCompFlow_h
+  m_avgstat[meshid][0] = d1 / d0;      // average edge length
+  m_avgstat[meshid][1] = d3 / d2;      // average cell volume cubic root
+  m_avgstat[meshid][2] = d5 / d4;      // average number of cells per chare
+
+  sumstat_complete(meshid);
+}
+
+void
+Transporter::pdfstat( CkReductionMsg* msg )
+// *****************************************************************************
+// Reduction target yielding PDF of mesh statistics across all workers
+//! \param[in] msg Serialized PDF
+// *****************************************************************************
+{
+  std::size_t meshid;
+  std::vector< tk::UniPDF > pdf;
+
+  // Deserialize final PDF
+  PUP::fromMem creator( msg->getData() );
+  creator | meshid;<--- Uninitialized variable: meshid
+  creator | pdf;
+  delete msg;
+
+  auto id = std::to_string(meshid);<--- Uninitialized variable: meshid
+
+  // Create new PDF file (overwrite if exists)
+  tk::PDFWriter pdfe( "mesh_edge_pdf." + id + ".txt" );
+  // Output edgelength PDF
+  // cppcheck-suppress containerOutOfBounds
+  pdfe.writeTxt( pdf[0],
+                 tk::ctr::PDFInfo{ {"PDF"}, {}, {"edgelength"}, 0, 0.0 } );
+
+  // Create new PDF file (overwrite if exists)
+  tk::PDFWriter pdfv( "mesh_vol_pdf." + id + ".txt" );
+  // Output cell volume cubic root PDF
+  pdfv.writeTxt( pdf[1],<--- Access out of bounds
+                 tk::ctr::PDFInfo{ {"PDF"}, {}, {"V^{1/3}"}, 0, 0.0 } );
+
+  // Create new PDF file (overwrite if exists)
+  tk::PDFWriter pdfn( "mesh_ntet_pdf." + id + ".txt" );
+  // Output number of cells PDF
+  pdfn.writeTxt( pdf[2],<--- Access out of bounds
+                 tk::ctr::PDFInfo{ {"PDF"}, {}, {"ntets"}, 0, 0.0 } );
+
+  pdfstat_complete(meshid);
+}
+
+void
+Transporter::stat()
+// *****************************************************************************
+// Echo diagnostics on mesh statistics
+// *****************************************************************************
+{
+  auto print = printer();
+
+  if (++m_nstat == m_nelem.size()) {     // stats from all meshes have arrived
+    m_nstat = 0;
+    for (std::size_t i=0; i<m_nelem.size(); ++i) {
+      print.diag(
+        "Mesh " + std::to_string(i) +
+        " distribution statistics: min/max/avg(edgelength) = " +
+        std::to_string( m_minstat[i][0] ) + " / " +
+        std::to_string( m_maxstat[i][0] ) + " / " +
+        std::to_string( m_avgstat[i][0] ) + ", " +
+        "min/max/avg(V^{1/3}) = " +
+        std::to_string( m_minstat[i][1] ) + " / " +
+        std::to_string( m_maxstat[i][1] ) + " / " +
+        std::to_string( m_avgstat[i][1] ) + ", " +
+        "min/max/avg(ntets) = " +
+        std::to_string( static_cast<std::size_t>(m_minstat[i][2]) ) + " / " +
+        std::to_string( static_cast<std::size_t>(m_maxstat[i][2]) ) + " / " +
+        std::to_string( static_cast<std::size_t>(m_avgstat[i][2]) ) );
+    }
+
+    // Print out time integration header to screen
+    inthead( print );
+
+    m_progWork.start( print, "Preparing workers",
+      {{ m_nchare[0], m_nchare[0], m_nchare[0], m_nchare[0], m_nchare[0] }} );
+
+    // Create "derived-class" workers
+    for (std::size_t i=0; i<m_nelem.size(); ++i) m_sorter[i].createWorkers();
+  }
+}
+
+void
+Transporter::boxvol( tk::real* meshdata, int n )
+// *****************************************************************************
+// Reduction target computing total volume of IC mesh blocks and box
+//! \param[in] meshdata Vector containing volumes of all IC mesh blocks,
+//!   volume of IC box, and mesh id as a real summed across the distributed mesh
+//! \param[in] n Size of vector, automatically computed by Charm
+// *****************************************************************************
+{
+  Assert(n>=2, "mesh data size incorrect");
+
+  // extract summed mesh id from vector
+  tk::real summeshid = meshdata[n-1];
+  auto meshid = tk::cref_find( m_meshid, static_cast<std::size_t>(summeshid) );
+
+  // extract summed box volume from vector
+  tk::real v = meshdata[n-2];
+  if (v > 0.0) printer().diag( "Box IC volume: " + std::to_string(v) );
+
+  // extract summed mesh block volumes from the vector
+  std::vector< tk::real > blockvols;
+  for (std::size_t blid=0; blid<(static_cast<std::size_t>(n)-2); ++blid) {
+    blockvols.push_back(meshdata[blid]);
+    if (blockvols[blid] > 0.0)
+      printer().diag( "Mesh block " + std::to_string(blid) +
+        " discrete volume: " + std::to_string(blockvols[blid]) );
+  }
+
+  m_scheme[meshid].bcast< Scheme::box >( v, blockvols );
+}
+
+void
+Transporter::solutionTransferred()
+// *****************************************************************************
+// Reduction target broadcasting to Schemes after mesh transfer
+// *****************************************************************************
+{
+  if (++m_ntrans == m_nelem.size()) {    // all meshes have been loaded
+    m_ntrans = 0;
+    for (auto& m : m_scheme) m.bcast< Scheme::transferSol >();
+  }
+}
+
+void
+Transporter::minDtAcrossMeshes( tk::real* reducndata, [[maybe_unused]] int n )
+// *****************************************************************************
+// Reduction target that computes minimum timestep across all meshes
+//! \param[in] reducndata Vector containing minimum values of dt and mesh-moved
+//!   flags, collected across all meshes
+//! \param[in] n Size of vector, automatically computed by Charm
+// *****************************************************************************
+{
+  Assert(static_cast<std::size_t>(n-1) == m_nelem.size(),
+    "Incorrectly sized reduction vector");
+  m_dtmsh.push_back(reducndata[0]);
+
+  if (++m_ndtmsh == m_nelem.size()) {    // all meshes have been loaded
+    Assert(m_dtmsh.size() == m_nelem.size(), "Incorrect size of dtmsh");
+
+    // compute minimum dt across meshes
+    tk::real dt = std::numeric_limits< tk::real >::max();
+    for (auto idt : m_dtmsh) dt = std::min(dt, idt);
+
+    // clear dt-vector and counter
+    m_dtmsh.clear();
+    m_ndtmsh = 0;
+
+    // broadcast to advance time step
+    std::size_t ic(0);
+    for (auto& m : m_scheme) {
+      m.bcast< Scheme::advance >( dt, reducndata[ic+1] );
+      ++ic;
+    }
+  }
+}
+
+void
+Transporter::inthead( const InciterPrint& print )
+// *****************************************************************************
+// Print out time integration header to screen
+//! \param[in] print Pretty printer object to use for printing
+// *****************************************************************************
+{
+  auto refined = g_inputdeck.get< tag::field_output, tag::refined >();
+  const auto scheme = g_inputdeck.get< tag::scheme >();
+  if (refined && scheme == ctr::SchemeType::DG) {
+    printer() << "\n>>> WARNING: Ignoring refined field output for DG(P0)\n\n";
+    refined = false;
+  }
+
+  print.inthead( "Time integration", "Navier-Stokes solver",
+  "Legend: it - iteration count\n"
+  "         t - physics time\n"
+  "        dt - physics time step size\n"
+  "       ETE - estimated wall-clock time elapsed (h:m:s)\n"
+  "       ETA - estimated wall-clock time for accomplishment (h:m:s)\n"
+  "       EGT - estimated grind wall-clock time (ms/timestep)\n"
+  "       flg - status flags, legend:\n"
+  "             f - " + std::string(refined ? "refined " : "")
+                      + "field (volume and surface)\n"
+  "             d - diagnostics\n"
+  "             t - physics time history\n"
+  "             h - h-refinement\n"
+  "             l - load balancing\n"
+  "             r - checkpoint\n"
+  "             a - ALE mesh velocity linear solver did not converge\n",
+  "\n      it             t            dt        ETE        ETA        EGT  flg\n"
+    " -------------------------------------------------------------------------\n" );
+}
+
+void
+Transporter::diagnostics( CkReductionMsg* msg )
+// *****************************************************************************
+// Reduction target optionally collecting diagnostics, e.g., residuals
+//! \param[in] msg Serialized diagnostics vector aggregated across all PEs
+//! \note Only used for nodal schemes
+// *****************************************************************************
+{
+  std::size_t meshid, ncomp;
+  std::vector< std::vector< tk::real > > d;
+
+  // Deserialize diagnostics vector
+  PUP::fromMem creator( msg->getData() );
+  creator | meshid;<--- Uninitialized variable: meshid
+  creator | ncomp;<--- Uninitialized variable: ncomp
+  creator | d;
+  delete msg;
+
+  auto id = std::to_string(meshid);<--- Uninitialized variable: meshid<--- Variable 'id' is assigned a value that is never used.
+
+  Assert( ncomp > 0, "Number of scalar components must be positive");<--- Uninitialized variable: ncomp
+  Assert( d.size() == NUMDIAG, "Diagnostics vector size mismatch" );
+
+  for (std::size_t i=0; i<d.size(); ++i)<--- Unsigned less than zero
+     Assert( d[i].size() == ncomp, "Size mismatch at final stage of "
+             "diagnostics aggregation for mesh " + id );
+
+  // Allocate storage for those diagnostics that are always computed
+  std::vector< tk::real > diag( ncomp, 0.0 );
+
+  // Finish computing diagnostics
+  for (std::size_t i=0; i<d[L2SOL].size(); ++i)
+    diag[i] = sqrt( d[L2SOL][i] / m_meshvol[meshid] );<--- Uninitialized variable: meshid
+  
+  // Query user-requested error types to output
+  const auto& error = g_inputdeck.get< tag::diagnostics, tag::error >();
+
+  decltype(ncomp) n = 0;<--- Variable 'n' is assigned a value that is never used.
+  n += ncomp;<--- Variable 'n' is assigned a value that is never used.
+  if (error == tk::ctr::ErrorType::L2) {
+   // Finish computing the L2 norm of the numerical - analytical solution
+   for (std::size_t i=0; i<d[L2ERR].size(); ++i)
+     diag.push_back( sqrt( d[L2ERR][i] / m_meshvol[meshid] ) );<--- Uninitialized variable: meshid
+  } else if (error == tk::ctr::ErrorType::LINF) {
+    // Finish computing the Linf norm of the numerical - analytical solution
+    for (std::size_t i=0; i<d[LINFERR].size(); ++i)
+      diag.push_back( d[LINFERR][i] );
+  }
+
+  // Finish computing the L2 norm of the residual and append
+  const auto scheme = g_inputdeck.get< tag::scheme >();
+  std::vector< tk::real > l2res( d[L2RES].size(), 0.0 );
+  if (scheme == ctr::SchemeType::ALECG || scheme == ctr::SchemeType::OversetFE) {
+    for (std::size_t i=0; i<d[L2RES].size(); ++i) {
+      l2res[i] = std::sqrt( d[L2RES][i] / m_meshvol[meshid] );<--- Uninitialized variable: meshid
+      diag.push_back( l2res[i] );
+    }
+  }
+  else if (scheme == ctr::SchemeType::FV) {
+    for (std::size_t i=0; i<d[L2RES].size(); ++i) {
+      l2res[i] = std::sqrt( d[L2RES][i] );
+      diag.push_back( l2res[i] );
+    }
+  }
+
+  // Append total energy
+  diag.push_back( d[TOTALSOL][0] );
+
+  // Append diagnostics file at selected times
+  auto filename = g_inputdeck.get< tag::cmd, tag::io, tag::diag >();
+  if (m_nelem.size() > 1) filename += '.' + id;
+  tk::DiagWriter dw( filename,
+    g_inputdeck.get< tag::diagnostics, tag::format >(),
+    g_inputdeck.get< tag::diagnostics, tag::precision >(),
+    std::ios_base::app );
+  dw.diag( static_cast<uint64_t>(d[ITER][0]), d[TIME][0], d[DT][0], diag );
+
+  // Continue time step
+  m_scheme[meshid].bcast< Scheme::refine >( l2res );<--- Uninitialized variable: meshid
+}
+
+void
+Transporter::resume()
+// *****************************************************************************
+// Resume execution from checkpoint/restart files
+//! \details This is invoked by Charm++ after the checkpoint is done, as well as
+//!   when the restart (returning from a checkpoint) is complete
+// *****************************************************************************
+{
+  if (std::any_of(begin(m_finished), end(m_finished), [](auto f){return !f;})) {
+    // If just restarted from a checkpoint, Main( CkMigrateMessage* msg ) has
+    // increased nrestart in g_inputdeck, but only on PE 0, so broadcast.
+    auto nrestart = g_inputdeck.get< tag::cmd, tag::io, tag::nrestart >();
+    for (std::size_t i=0; i<m_nelem.size(); ++i)
+      m_scheme[i].bcast< Scheme::evalLB >( nrestart );
+  } else
+    mainProxy.finalize();
+}
+
+void
+Transporter::checkpoint( std::size_t finished, std::size_t meshid )
+// *****************************************************************************
+// Save checkpoint/restart files
+//! \param[in] finished Nonzero if finished with time stepping
+//! \param[in] meshid Mesh id
+// *****************************************************************************
+{
+  m_finished[meshid] = finished;
+
+  if (++m_nchk == m_nelem.size()) { // all worker arrays have checkpointed
+    m_nchk = 0;
+    if (not g_inputdeck.get< tag::cmd, tag::benchmark >()) {
+      const auto& restart = g_inputdeck.get< tag::cmd, tag::io, tag::restart >();
+      CkCallback res( CkIndex_Transporter::resume(), thisProxy );
+      CkStartCheckpoint( restart.c_str(), res );
+    } else {
+      resume();
+    }
+  }
+}
+
+void
+Transporter::finish( std::size_t meshid )
+// *****************************************************************************
+// Normal finish of time stepping
+//! \param[in] meshid Mesh id
+// *****************************************************************************
+{
+  checkpoint( /* finished = */ 1, meshid );
+}
+
+#include "NoWarning/transporter.def.h"
 
diff --git a/Release/cppcheck/48.html b/Release/cppcheck/48.html index 74454e80fb06..2d91213b4905 100644 --- a/Release/cppcheck/48.html +++ b/Release/cppcheck/48.html @@ -152,2985 +152,349 @@
- - + @@ -77,7 +77,7 @@ - +
   1
-   2
-   3
-   4
-   5
-   6
-   7
-   8
-   9
-  10
-  11
-  12
-  13
-  14
-  15
-  16
-  17
-  18
-  19
-  20
-  21
-  22
-  23
-  24
-  25
-  26
-  27
-  28
-  29
-  30
-  31
-  32
-  33
-  34
-  35
-  36
-  37
-  38
-  39
-  40
-  41
-  42
-  43
-  44
-  45
-  46
-  47
-  48
-  49
-  50
-  51
-  52
-  53
-  54
-  55
-  56
-  57
-  58
-  59
-  60
-  61
-  62
-  63
-  64
-  65
-  66
-  67
-  68
-  69
-  70
-  71
-  72
-  73
-  74
-  75
-  76
-  77
-  78
-  79
-  80
-  81
-  82
-  83
-  84
-  85
-  86
-  87
-  88
-  89
-  90
-  91
-  92
-  93
-  94
-  95
-  96
-  97
-  98
-  99
- 100
- 101
- 102
- 103
- 104
- 105
- 106
- 107
- 108
- 109
- 110
- 111
- 112
- 113
- 114
- 115
- 116
- 117
- 118
- 119
- 120
- 121
- 122
- 123
- 124
- 125
- 126
- 127
- 128
- 129
- 130
- 131
- 132
- 133
- 134
- 135
- 136
- 137
- 138
- 139
- 140
- 141
- 142
- 143
- 144
- 145
- 146
- 147
- 148
- 149
- 150
- 151
- 152
- 153
- 154
- 155
- 156
- 157
- 158
- 159
- 160
- 161
- 162
- 163
- 164
- 165
- 166
- 167
- 168
- 169
- 170
- 171
- 172
- 173
- 174
- 175
- 176
- 177
- 178
- 179
- 180
- 181
- 182
- 183
- 184
- 185
- 186
- 187
- 188
- 189
- 190
- 191
- 192
- 193
- 194
- 195
- 196
- 197
- 198
- 199
- 200
- 201
- 202
- 203
- 204
- 205
- 206
- 207
- 208
- 209
- 210
- 211
- 212
- 213
- 214
- 215
- 216
- 217
- 218
- 219
- 220
- 221
- 222
- 223
- 224
- 225
- 226
- 227
- 228
- 229
- 230
- 231
- 232
- 233
- 234
- 235
- 236
- 237
- 238
- 239
- 240
- 241
- 242
- 243
- 244
- 245
- 246
- 247
- 248
- 249
- 250
- 251
- 252
- 253
- 254
- 255
- 256
- 257
- 258
- 259
- 260
- 261
- 262
- 263
- 264
- 265
- 266
- 267
- 268
- 269
- 270
- 271
- 272
- 273
- 274
- 275
- 276
- 277
- 278
- 279
- 280
- 281
- 282
- 283
- 284
- 285
- 286
- 287
- 288
- 289
- 290
- 291
- 292
- 293
- 294
- 295
- 296
- 297
- 298
- 299
- 300
- 301
- 302
- 303
- 304
- 305
- 306
- 307
- 308
- 309
- 310
- 311
- 312
- 313
- 314
- 315
- 316
- 317
- 318
- 319
- 320
- 321
- 322
- 323
- 324
- 325
- 326
- 327
- 328
- 329
- 330
- 331
- 332
- 333
- 334
- 335
- 336
- 337
- 338
- 339
- 340
- 341
- 342
- 343
- 344
- 345
- 346
- 347
- 348
- 349
- 350
- 351
- 352
- 353
- 354
- 355
- 356
- 357
- 358
- 359
- 360
- 361
- 362
- 363
- 364
- 365
- 366
- 367
- 368
- 369
- 370
- 371
- 372
- 373
- 374
- 375
- 376
- 377
- 378
- 379
- 380
- 381
- 382
- 383
- 384
- 385
- 386
- 387
- 388
- 389
- 390
- 391
- 392
- 393
- 394
- 395
- 396
- 397
- 398
- 399
- 400
- 401
- 402
- 403
- 404
- 405
- 406
- 407
- 408
- 409
- 410
- 411
- 412
- 413
- 414
- 415
- 416
- 417
- 418
- 419
- 420
- 421
- 422
- 423
- 424
- 425
- 426
- 427
- 428
- 429
- 430
- 431
- 432
- 433
- 434
- 435
- 436
- 437
- 438
- 439
- 440
- 441
- 442
- 443
- 444
- 445
- 446
- 447
- 448
- 449
- 450
- 451
- 452
- 453
- 454
- 455
- 456
- 457
- 458
- 459
- 460
- 461
- 462
- 463
- 464
- 465
- 466
- 467
- 468
- 469
- 470
- 471
- 472
- 473
- 474
- 475
- 476
- 477
- 478
- 479
- 480
- 481
- 482
- 483
- 484
- 485
- 486
- 487
- 488
- 489
- 490
- 491
- 492
- 493
- 494
- 495
- 496
- 497
- 498
- 499
- 500
- 501
- 502
- 503
- 504
- 505
- 506
- 507
- 508
- 509
- 510
- 511
- 512
- 513
- 514
- 515
- 516
- 517
- 518
- 519
- 520
- 521
- 522
- 523
- 524
- 525
- 526
- 527
- 528
- 529
- 530
- 531
- 532
- 533
- 534
- 535
- 536
- 537
- 538
- 539
- 540
- 541
- 542
- 543
- 544
- 545
- 546
- 547
- 548
- 549
- 550
- 551
- 552
- 553
- 554
- 555
- 556
- 557
- 558
- 559
- 560
- 561
- 562
- 563
- 564
- 565
- 566
- 567
- 568
- 569
- 570
- 571
- 572
- 573
- 574
- 575
- 576
- 577
- 578
- 579
- 580
- 581
- 582
- 583
- 584
- 585
- 586
- 587
- 588
- 589
- 590
- 591
- 592
- 593
- 594
- 595
- 596
- 597
- 598
- 599
- 600
- 601
- 602
- 603
- 604
- 605
- 606
- 607
- 608
- 609
- 610
- 611
- 612
- 613
- 614
- 615
- 616
- 617
- 618
- 619
- 620
- 621
- 622
- 623
- 624
- 625
- 626
- 627
- 628
- 629
- 630
- 631
- 632
- 633
- 634
- 635
- 636
- 637
- 638
- 639
- 640
- 641
- 642
- 643
- 644
- 645
- 646
- 647
- 648
- 649
- 650
- 651
- 652
- 653
- 654
- 655
- 656
- 657
- 658
- 659
- 660
- 661
- 662
- 663
- 664
- 665
- 666
- 667
- 668
- 669
- 670
- 671
- 672
- 673
- 674
- 675
- 676
- 677
- 678
- 679
- 680
- 681
- 682
- 683
- 684
- 685
- 686
- 687
- 688
- 689
- 690
- 691
- 692
- 693
- 694
- 695
- 696
- 697
- 698
- 699
- 700
- 701
- 702
- 703
- 704
- 705
- 706
- 707
- 708
- 709
- 710
- 711
- 712
- 713
- 714
- 715
- 716
- 717
- 718
- 719
- 720
- 721
- 722
- 723
- 724
- 725
- 726
- 727
- 728
- 729
- 730
- 731
- 732
- 733
- 734
- 735
- 736
- 737
- 738
- 739
- 740
- 741
- 742
- 743
- 744
- 745
- 746
- 747
- 748
- 749
- 750
- 751
- 752
- 753
- 754
- 755
- 756
- 757
- 758
- 759
- 760
- 761
- 762
- 763
- 764
- 765
- 766
- 767
- 768
- 769
- 770
- 771
- 772
- 773
- 774
- 775
- 776
- 777
- 778
- 779
- 780
- 781
- 782
- 783
- 784
- 785
- 786
- 787
- 788
- 789
- 790
- 791
- 792
- 793
- 794
- 795
- 796
- 797
- 798
- 799
- 800
- 801
- 802
- 803
- 804
- 805
- 806
- 807
- 808
- 809
- 810
- 811
- 812
- 813
- 814
- 815
- 816
- 817
- 818
- 819
- 820
- 821
- 822
- 823
- 824
- 825
- 826
- 827
- 828
- 829
- 830
- 831
- 832
- 833
- 834
- 835
- 836
- 837
- 838
- 839
- 840
- 841
- 842
- 843
- 844
- 845
- 846
- 847
- 848
- 849
- 850
- 851
- 852
- 853
- 854
- 855
- 856
- 857
- 858
- 859
- 860
- 861
- 862
- 863
- 864
- 865
- 866
- 867
- 868
- 869
- 870
- 871
- 872
- 873
- 874
- 875
- 876
- 877
- 878
- 879
- 880
- 881
- 882
- 883
- 884
- 885
- 886
- 887
- 888
- 889
- 890
- 891
- 892
- 893
- 894
- 895
- 896
- 897
- 898
- 899
- 900
- 901
- 902
- 903
- 904
- 905
- 906
- 907
- 908
- 909
- 910
- 911
- 912
- 913
- 914
- 915
- 916
- 917
- 918
- 919
- 920
- 921
- 922
- 923
- 924
- 925
- 926
- 927
- 928
- 929
- 930
- 931
- 932
- 933
- 934
- 935
- 936
- 937
- 938
- 939
- 940
- 941
- 942
- 943
- 944
- 945
- 946
- 947
- 948
- 949
- 950
- 951
- 952
- 953
- 954
- 955
- 956
- 957
- 958
- 959
- 960
- 961
- 962
- 963
- 964
- 965
- 966
- 967
- 968
- 969
- 970
- 971
- 972
- 973
- 974
- 975
- 976
- 977
- 978
- 979
- 980
- 981
- 982
- 983
- 984
- 985
- 986
- 987
- 988
- 989
- 990
- 991
- 992
- 993
- 994
- 995
- 996
- 997
- 998
- 999
-1000
-1001
-1002
-1003
-1004
-1005
-1006
-1007
-1008
-1009
-1010
-1011
-1012
-1013
-1014
-1015
-1016
-1017
-1018
-1019
-1020
-1021
-1022
-1023
-1024
-1025
-1026
-1027
-1028
-1029
-1030
-1031
-1032
-1033
-1034
-1035
-1036
-1037
-1038
-1039
-1040
-1041
-1042
-1043
-1044
-1045
-1046
-1047
-1048
-1049
-1050
-1051
-1052
-1053
-1054
-1055
-1056
-1057
-1058
-1059
-1060
-1061
-1062
-1063
-1064
-1065
-1066
-1067
-1068
-1069
-1070
-1071
-1072
-1073
-1074
-1075
-1076
-1077
-1078
-1079
-1080
-1081
-1082
-1083
-1084
-1085
-1086
-1087
-1088
-1089
-1090
-1091
-1092
-1093
-1094
-1095
-1096
-1097
-1098
-1099
-1100
-1101
-1102
-1103
-1104
-1105
-1106
-1107
-1108
-1109
-1110
-1111
-1112
-1113
-1114
-1115
-1116
-1117
-1118
-1119
-1120
-1121
-1122
-1123
-1124
-1125
-1126
-1127
-1128
-1129
-1130
-1131
-1132
-1133
-1134
-1135
-1136
-1137
-1138
-1139
-1140
-1141
-1142
-1143
-1144
-1145
-1146
-1147
-1148
-1149
-1150
-1151
-1152
-1153
-1154
-1155
-1156
-1157
-1158
-1159
-1160
-1161
-1162
-1163
-1164
-1165
-1166
-1167
-1168
-1169
-1170
-1171
-1172
-1173
-1174
-1175
-1176
-1177
-1178
-1179
-1180
-1181
-1182
-1183
-1184
-1185
-1186
-1187
-1188
-1189
-1190
-1191
-1192
-1193
-1194
-1195
-1196
-1197
-1198
-1199
-1200
-1201
-1202
-1203
-1204
-1205
-1206
-1207
-1208
-1209
-1210
-1211
-1212
-1213
-1214
-1215
-1216
-1217
-1218
-1219
-1220
-1221
-1222
-1223
-1224
-1225
-1226
-1227
-1228
-1229
-1230
-1231
-1232
-1233
-1234
-1235
-1236
-1237
-1238
-1239
-1240
-1241
-1242
-1243
-1244
-1245
-1246
-1247
-1248
-1249
-1250
-1251
-1252
-1253
-1254
-1255
-1256
-1257
-1258
-1259
-1260
-1261
-1262
-1263
-1264
-1265
-1266
-1267
-1268
-1269
-1270
-1271
-1272
-1273
-1274
-1275
-1276
-1277
-1278
-1279
-1280
-1281
-1282
-1283
-1284
-1285
-1286
-1287
-1288
-1289
-1290
-1291
-1292
-1293
-1294
-1295
-1296
-1297
-1298
-1299
-1300
-1301
-1302
-1303
-1304
-1305
-1306
-1307
-1308
-1309
-1310
-1311
-1312
-1313
-1314
-1315
-1316
-1317
-1318
-1319
-1320
-1321
-1322
-1323
-1324
-1325
-1326
-1327
-1328
-1329
-1330
-1331
-1332
-1333
-1334
-1335
-1336
-1337
-1338
-1339
-1340
-1341
-1342
-1343
-1344
-1345
-1346
-1347
-1348
-1349
-1350
-1351
-1352
-1353
-1354
-1355
-1356
-1357
-1358
-1359
-1360
-1361
-1362
-1363
-1364
-1365
-1366
-1367
-1368
-1369
-1370
-1371
-1372
-1373
-1374
-1375
-1376
-1377
-1378
-1379
-1380
-1381
-1382
-1383
-1384
-1385
-1386
-1387
-1388
-1389
-1390
-1391
-1392
-1393
-1394
-1395
-1396
-1397
-1398
-1399
-1400
-1401
-1402
-1403
-1404
-1405
-1406
-1407
-1408
-1409
-1410
-1411
-1412
-1413
-1414
-1415
-1416
-1417
-1418
-1419
-1420
-1421
-1422
-1423
-1424
-1425
-1426
-1427
-1428
-1429
-1430
-1431
-1432
-1433
-1434
-1435
-1436
-1437
-1438
-1439
-1440
-1441
-1442
-1443
-1444
-1445
-1446
-1447
-1448
-1449
-1450
-1451
-1452
-1453
-1454
-1455
-1456
-1457
-1458
-1459
-1460
-1461
-1462
-1463
-1464
-1465
-1466
-1467
-1468
-1469
-1470
-1471
-1472
-1473
-1474
-1475
-1476
-1477
-1478
-1479
-1480
-1481
-1482
-1483
-1484
-1485
-1486
// *****************************************************************************
+
  1
+  2
+  3
+  4
+  5
+  6
+  7
+  8
+  9
+ 10
+ 11
+ 12
+ 13
+ 14
+ 15
+ 16
+ 17
+ 18
+ 19
+ 20
+ 21
+ 22
+ 23
+ 24
+ 25
+ 26
+ 27
+ 28
+ 29
+ 30
+ 31
+ 32
+ 33
+ 34
+ 35
+ 36
+ 37
+ 38
+ 39
+ 40
+ 41
+ 42
+ 43
+ 44
+ 45
+ 46
+ 47
+ 48
+ 49
+ 50
+ 51
+ 52
+ 53
+ 54
+ 55
+ 56
+ 57
+ 58
+ 59
+ 60
+ 61
+ 62
+ 63
+ 64
+ 65
+ 66
+ 67
+ 68
+ 69
+ 70
+ 71
+ 72
+ 73
+ 74
+ 75
+ 76
+ 77
+ 78
+ 79
+ 80
+ 81
+ 82
+ 83
+ 84
+ 85
+ 86
+ 87
+ 88
+ 89
+ 90
+ 91
+ 92
+ 93
+ 94
+ 95
+ 96
+ 97
+ 98
+ 99
+100
+101
+102
+103
+104
+105
+106
+107
+108
+109
+110
+111
+112
+113
+114
+115
+116
+117
+118
+119
+120
+121
+122
+123
+124
+125
+126
+127
+128
+129
+130
+131
+132
+133
+134
+135
+136
+137
+138
+139
+140
+141
+142
+143
+144
+145
+146
+147
+148
+149
+150
+151
+152
+153
+154
+155
+156
+157
+158
+159
+160
+161
+162
+163
+164
+165
+166
+167
+168
// *****************************************************************************
 /*!
-  \file      src/Inciter/OversetFE.cpp
+  \file      src/PDE/ConfigureCompFlow.cpp
   \copyright 2012-2015 J. Bakosi,
              2016-2018 Los Alamos National Security, LLC.,
              2019-2021 Triad National Security, LLC.
              All rights reserved. See the LICENSE file for details.
-  \brief     OversetFE for a PDE system with continuous Galerkin FE + RK
-  \details   OversetFE advances a system of partial differential equations
-    using a continuous Galerkin (CG) finite element (FE) spatial discretization
-    (using linear shapefunctions on tetrahedron elements) combined with a
-    Runge-Kutta (RK) time stepping scheme and overset grids.
-  \see The documentation in OversetFE.hpp.
-*/
-// *****************************************************************************
-
-#include "QuinoaBuildConfig.hpp"
-#include "OversetFE.hpp"
-#include "Vector.hpp"
-#include "Reader.hpp"
-#include "ContainerUtil.hpp"
-#include "UnsMesh.hpp"
-#include "ExodusIIMeshWriter.hpp"
-#include "Inciter/InputDeck/InputDeck.hpp"
-#include "DerivedData.hpp"
-#include "CGPDE.hpp"
-#include "Discretization.hpp"
-#include "DiagReducer.hpp"
-#include "NodeBC.hpp"
-#include "Refiner.hpp"
-#include "Reorder.hpp"
-#include "Around.hpp"
-#include "CGPDE.hpp"
-#include "FieldOutput.hpp"
-
-namespace inciter {
-
-extern ctr::InputDeck g_inputdeck;
-extern std::vector< CGPDE > g_cgpde;
-
-//! Runge-Kutta coefficients
-static const std::array< tk::real, 3 > rkcoef{{ 1.0/3.0, 1.0/2.0, 1.0 }};
-
-} // inciter::
-
-using inciter::OversetFE;
-
-OversetFE::OversetFE( const CProxy_Discretization& disc,
-              const CProxy_Ghosts&,
-              const std::map< int, std::vector< std::size_t > >& bface,
-              const std::map< int, std::vector< std::size_t > >& bnode,
-              const std::vector< std::size_t >& triinpoel ) :
-  m_disc( disc ),
-  m_nsol( 0 ),
-  m_ngrad( 0 ),
-  m_nrhs( 0 ),
-  m_nbnorm( 0 ),
-  m_ndfnorm( 0 ),
-  m_nmblk( 0 ),
-  m_bnode( bnode ),
-  m_bface( bface ),
-  m_triinpoel( tk::remap( triinpoel, Disc()->Lid() ) ),
-  m_bndel( Disc()->bndel() ),
-  m_dfnorm(),
-  m_dfnormc(),
-  m_dfn(),
-  m_esup( tk::genEsup( Disc()->Inpoel(), 4 ) ),
-  m_psup( tk::genPsup( Disc()->Inpoel(), 4, m_esup ) ),
-  m_u( Disc()->Gid().size(),
-       g_inputdeck.get< tag::ncomp >() ),
-  m_uc( m_u.nunk(), m_u.nprop()+1 ),
-  m_un( m_u.nunk(), m_u.nprop() ),
-  m_rhs( m_u.nunk(), m_u.nprop() ),
-  m_rhsc(),
-  m_chBndGrad( Disc()->Bid().size(), m_u.nprop()*3 ),
-  m_dirbc(),
-  m_chBndGradc(),
-  m_blank( m_u.nunk(), 1.0 ),
-  m_diag(),
-  m_bnorm(),
-  m_bnormc(),
-  m_symbcnodes(),
-  m_farfieldbcnodes(),
-  m_symbctri(),
-  m_timedepbcnodes(),
-  m_timedepbcFn(),
-  m_stage( 0 ),
-  m_boxnodes(),
-  m_edgenode(),
-  m_edgeid(),
-  m_dtp( m_u.nunk(), 0.0 ),
-  m_tp( m_u.nunk(), g_inputdeck.get< tag::t0 >() ),
-  m_finished( 0 ),
-  m_movedmesh( 0 ),
-  m_nusermeshblk( 0 ),
-  m_nodeblockid(),
-  m_nodeblockidc(),
-  m_ixfer(0)
-// *****************************************************************************
-//  Constructor
-//! \param[in] disc Discretization proxy
-//! \param[in] bface Boundary-faces mapped to side sets used in the input file
-//! \param[in] bnode Boundary-node lists mapped to side sets used in input file
-//! \param[in] triinpoel Boundary-face connectivity where BCs set (global ids)
-// *****************************************************************************
-//! [Constructor]
-{
-  usesAtSync = true;    // enable migration at AtSync
-
-  auto d = Disc();
+  \brief     Register and compile configuration for compressible flow PDE
+  \details   Register and compile configuration for compressible flow PDE.
+*/
+// *****************************************************************************
+
+#include <set>
+#include <map>
+#include <vector>
+#include <string>
+#include <limits>
+
+#include <brigand/algorithms/for_each.hpp>
+
+#include "Tags.hpp"
+#include "CartesianProduct.hpp"
+#include "PDEFactory.hpp"
+#include "Inciter/Options/PDE.hpp"
+#include "ContainerUtil.hpp"
+#include "ConfigureCompFlow.hpp"
+#include "CompFlow/Physics/CG.hpp"
+#include "CompFlow/Physics/DG.hpp"
+#include "CompFlow/CGCompFlow.hpp"
+#include "CompFlow/DGCompFlow.hpp"
+#include "CompFlow/Problem.hpp"
+
+namespace inciter {
+
+void
+registerCompFlow( CGFactory& cf,
+                  DGFactory& df,
+                  std::set< ctr::PDEType >& cgt,
+                  std::set< ctr::PDEType >& dgt )
+// *****************************************************************************
+// Register compressible flow PDE into PDE factory
+//! \param[in,out] cf Continuous Galerkin PDE factory to register to
+//! \param[in,out] df Discontinuous Galerkin PDE factory to register to
+//! \param[in,out] cgt Counters for equation types registered into CG factory
+//! \param[in,out] dgt Counters for equation types registered into DG factory
+// *****************************************************************************
+{
+  // Construct vector of vectors for all possible policies
+  using CGCompFlowPolicies =
+    tk::cartesian_product< cg::CompFlowPhysics, CompFlowProblems >;
+  // Register PDEs for all combinations of policies
+  brigand::for_each< CGCompFlowPolicies >(
+    registerCG< cg::CompFlow >( cf, cgt, ctr::PDEType::COMPFLOW ) );
+
+  // Construct vector of vectors for all possible policies
+  using DGCompFlowPolicies =
+    tk::cartesian_product< dg::CompFlowPhysics, CompFlowProblems >;
+  // Register PDEs for all combinations of policies
+  brigand::for_each< DGCompFlowPolicies >(
+    registerDG< dg::CompFlow >( df, dgt, ctr::PDEType::COMPFLOW ) );
+}
+
+std::vector< std::pair< std::string, std::string > >
+infoCompFlow( std::map< ctr::PDEType, tk::ncomp_t >& cnt )
+// *****************************************************************************
+//  Return information on the compressible flow system of PDEs
+//! \param[inout] cnt std::map of counters for all PDE types
+//! \return vector of string pairs describing the PDE configuration
+// *****************************************************************************
+{
+  using eq = tag::compflow;
+  using tk::parameter;
+  using tk::parameters;
+
+  auto c = ++cnt[ ctr::PDEType::COMPFLOW ];       // count eqs
+  --c;  // used to index vectors starting with 0<--- Variable 'c' is assigned a value that is never used.
+
+  std::vector< std::pair< std::string, std::string > > nfo;
+
+  nfo.emplace_back( ctr::PDE().name( ctr::PDEType::COMPFLOW ), "" );
+
+  nfo.emplace_back( "physics", ctr::Physics().name(
+    g_inputdeck.get< eq, tag::physics >() ) );
+
+  nfo.emplace_back( "problem", ctr::Problem().name(
+    g_inputdeck.get< eq, tag::problem >() ) );
+
+  auto ncomp = g_inputdeck.get< tag::ncomp >();
+  nfo.emplace_back( "number of components", parameter( ncomp ) );
+
+  const auto scheme = g_inputdeck.get< tag::scheme >();
+  if (scheme != ctr::SchemeType::ALECG && scheme != ctr::SchemeType::OversetFE)
+    nfo.emplace_back( "flux", ctr::Flux().name(
+      g_inputdeck.get< tag::flux >() ) );
+
+  // ICs
+
+  const auto& ic = g_inputdeck.get< tag::ic >();
+
+  const auto& icbox = ic.get< tag::box >();
+  if (!icbox.empty()) {
+    std::size_t bcnt = 0;
+    for (const auto& b : icbox) {   // for all boxes configured for this eq
+      std::vector< tk::real > box
+        { b.get< tag::xmin >(), b.get< tag::xmax >(),
+          b.get< tag::ymin >(), b.get< tag::ymax >(),
+          b.get< tag::zmin >(), b.get< tag::zmax >() };
+
+      std::string boxname = "IC box " + parameter(bcnt);
+      nfo.emplace_back( boxname, parameters( box ) );
 
-  // Perform optional operator-access-pattern mesh node reordering
-  if (g_inputdeck.get< tag::operator_reorder >()) {
+      nfo.emplace_back( boxname + " orientation",
+        parameters(b.get< tag::orientation >()) );
 
-    // Create new local ids based on access pattern of PDE operators
-    std::unordered_map< std::size_t, std::size_t > map;
-    std::size_t n = 0;
+      const auto& initiate = b.get< tag::initiate >();
+      auto opt = ctr::Initiate();
+      nfo.emplace_back( boxname + ' ' + opt.group(), opt.name(initiate) );
 
-    for (std::size_t p=0; p<m_u.nunk(); ++p) {  // for each point p
-      if (map.find(p) == end(map)) map[p] = n++;<--- Searching before insertion is not necessary.
-      for (auto q : tk::Around(m_psup,p)) {     // for each edge p-q
-        if (map.find(q) == end(map)) map[q] = n++;<--- Searching before insertion is not necessary.
-      }
-    }
-
-    Assert( map.size() == d->Gid().size(), "Map size mismatch" );
+      ++bcnt;
+    }
+  }
+
+  const auto& icblock = ic.get< tag::meshblock >();
+  for (const auto& b : icblock) {   // for all blocks configured for eq
+    std::string blockname = "IC mesh block " +
+      parameter(b.get< tag::blockid >());
 
-    // Remap data in bound Discretization object
-    d->remap( map );
-    // Recompute elements surrounding points
-    m_esup = tk::genEsup( d->Inpoel(), 4 );
-    // Recompute points surrounding points
-    m_psup = tk::genPsup( d->Inpoel(), 4, m_esup );
-    // Remap boundary triangle face connectivity
-    tk::remap( m_triinpoel, map );
-  }
-
-  // Query/update boundary-conditions-related data structures from user input
-  getBCNodes();
-
-  // Activate SDAG wait for initially computing normals, and mesh blocks
-  thisProxy[ thisIndex ].wait4norm();
-  thisProxy[ thisIndex ].wait4meshblk();
-
-  // Determine user-specified mesh velocity
-  const auto& uservelvec =
-    g_inputdeck.get< tag::mesh >()[d->MeshId()].get< tag::velocity >();
-  m_uservel = {uservelvec[0], uservelvec[1], uservelvec[2]};
-
-  if (g_inputdeck.get< tag::steady_state >() &&
-    std::sqrt(tk::dot(m_uservel, m_uservel)) > 1e-8)
-    Throw("Mesh motion cannot be activated for steady state problem");
-
-  d->comfinal();
+    const auto& initiate = b.get< tag::initiate >();
+    auto opt = ctr::Initiate();
+    nfo.emplace_back( blockname + ' ' + opt.group(), opt.name(initiate) );
+  }
+
+  // BCs
+
+  const auto& bc = g_inputdeck.get< tag::bc >();
+  for (const auto& ib : bc) {
+    const auto& stag = ib.get< tag::stag_point >();
+    const auto& radius = ib.get< tag::radius >();
+    if (!stag.empty()) {
+      nfo.emplace_back( "Stagnation point(s)", parameters( stag ) );
+      nfo.emplace_back( "Stagnation point(s) radii", parameter( radius ) );
+    }
+
+    const auto& fs = ib.get< tag::farfield >();
+    if (!fs.empty())
+      nfo.emplace_back( "Farfield BC sideset(s)", parameters( fs ) );
+
+    const auto& sym = ib.get< tag::symmetry >();
+    if (!sym.empty())
+      nfo.emplace_back( "Symmetry BC sideset(s)", parameters( sym ) );
+
+    const auto& dir = ib.get< tag::dirichlet >();
+    if (!dir.empty())
+      nfo.emplace_back( "Dirichlet BC sideset(s)", parameters( dir ) );
 
-}
-//! [Constructor]
-
-void
-OversetFE::getBCNodes()
-// *****************************************************************************
-// Query/update boundary-conditions-related data structures from user input
-// *****************************************************************************
-{
-  auto d = Disc();
-
-  // Prepare unique set of symmetry BC nodes
-  auto sym = d->bcnodes< tag::symmetry >( m_bface, m_triinpoel );
-  for (const auto& [s,nodes] : sym)
-    m_symbcnodes.insert( begin(nodes), end(nodes) );
-
-  // Prepare unique set of farfield BC nodes
-  auto far = d->bcnodes< tag::farfield >( m_bface, m_triinpoel );
-  for (const auto& [s,nodes] : far)
-    m_farfieldbcnodes.insert( begin(nodes), end(nodes) );
-
-  // If farfield BC is set on a node, will not also set symmetry BC
-  for (auto fn : m_farfieldbcnodes) m_symbcnodes.erase(fn);
-
-  // Prepare boundary nodes contiguously accessible from a triangle-face loop
-  m_symbctri.resize( m_triinpoel.size()/3, 0 );
-  for (std::size_t e=0; e<m_triinpoel.size()/3; ++e)
-    if (m_symbcnodes.find(m_triinpoel[e*3+0]) != end(m_symbcnodes))
-      m_symbctri[e] = 1;
-
-  // Prepare unique set of time dependent BC nodes
-  m_timedepbcnodes.clear();
-  m_timedepbcFn.clear();
-  const auto& timedep =
-    g_inputdeck.get< tag::bc >()[d->MeshId()].get< tag::timedep >();
-  if (!timedep.empty()) {
-    m_timedepbcnodes.resize(timedep.size());
-    m_timedepbcFn.resize(timedep.size());
-    std::size_t ib=0;
-    for (const auto& bndry : timedep) {
-      std::unordered_set< std::size_t > nodes;
-      for (const auto& s : bndry.template get< tag::sideset >()) {
-        auto k = m_bnode.find(static_cast<int>(s));
-        if (k != end(m_bnode)) {
-          for (auto g : k->second) {      // global node ids on side set
-            nodes.insert( tk::cref_find(d->Lid(),g) );
-          }
-        }
-      }
-      m_timedepbcnodes[ib].insert( begin(nodes), end(nodes) );
-
-      // Store user defined discrete function in time. This is done in the same
-      // loop as the BC nodes, so that the indices for the two vectors
-      // m_timedepbcnodes and m_timedepbcFn are consistent with each other
-      auto fn = bndry.template get< tag::fn >();
-      for (std::size_t ir=0; ir<fn.size()/6; ++ir) {
-        m_timedepbcFn[ib].push_back({{ fn[ir*6+0], fn[ir*6+1], fn[ir*6+2],
-          fn[ir*6+3], fn[ir*6+4], fn[ir*6+5] }});
-      }
-      ++ib;
-    }
-  }
-
-  Assert(m_timedepbcFn.size() == m_timedepbcnodes.size(), "Incorrect number of "
-    "time dependent functions.");
-}
-
-void
-OversetFE::norm()
-// *****************************************************************************
-// Start (re-)computing boundary point-, and dual-face normals
-// *****************************************************************************
-{
-  auto d = Disc();
-
-  // Query nodes at which symmetry BCs are specified
-  auto bn = d->bcnodes< tag::symmetry >( m_bface, m_triinpoel );
-
-  // Query nodes at which farfield BCs are specified
-  auto far = d->bcnodes< tag::farfield >( m_bface, m_triinpoel );
-  // Merge BC data where boundary-point normals are required
-  for (const auto& [s,n] : far) bn[s].insert( begin(n), end(n) );
-
-  // Query nodes at which mesh velocity symmetry BCs are specified
-  std::unordered_map<int, std::unordered_set< std::size_t >> ms;
-  for (const auto& s : g_inputdeck.get< tag::ale, tag::symmetry >()) {
-    auto k = m_bface.find(static_cast<int>(s));
-    if (k != end(m_bface)) {
-      auto& n = ms[ k->first ];
-      for (auto f : k->second) {
-        n.insert( m_triinpoel[f*3+0] );
-        n.insert( m_triinpoel[f*3+1] );
-        n.insert( m_triinpoel[f*3+2] );
-      }
-    }
-  }
-  // Merge BC data where boundary-point normals are required
-  for (const auto& [s,n] : ms) bn[s].insert( begin(n), end(n) );
-
-  // Compute boundary point normals
-  bnorm( bn );
-
-  // Compute dual-face normals associated to edges
-  dfnorm();
-}
-
-std::array< tk::real, 3 >
-OversetFE::edfnorm( const tk::UnsMesh::Edge& edge,
-                const std::unordered_map< tk::UnsMesh::Edge,
-                        std::vector< std::size_t >,
-                        tk::UnsMesh::Hash<2>, tk::UnsMesh::Eq<2> >& esued )
-const
-// *****************************************************************************
-//  Compute normal of dual-mesh associated to edge
-//! \param[in] edge Edge whose dual-face normal to compute given by local ids
-//! \param[in] esued Elements surrounding edges
-//! \return Dual-face normal for edge
-// *****************************************************************************
-{
-  auto d = Disc();
-  const auto& inpoel = d->Inpoel();
-  const auto& coord = d->Coord();
-  const auto& x = coord[0];
-  const auto& y = coord[1];
-  const auto& z = coord[2];
-
-  std::array< tk::real, 3 > n{ 0.0, 0.0, 0.0 };
-
-  for (auto e : tk::cref_find(esued,edge)) {
-    // access node IDs
-    const std::array< std::size_t, 4 >
-      N{ inpoel[e*4+0], inpoel[e*4+1], inpoel[e*4+2], inpoel[e*4+3] };
-    // compute element Jacobi determinant
-    const std::array< tk::real, 3 >
-      ba{{ x[N[1]]-x[N[0]], y[N[1]]-y[N[0]], z[N[1]]-z[N[0]] }},
-      ca{{ x[N[2]]-x[N[0]], y[N[2]]-y[N[0]], z[N[2]]-z[N[0]] }},
-      da{{ x[N[3]]-x[N[0]], y[N[3]]-y[N[0]], z[N[3]]-z[N[0]] }};
-    const auto J = tk::triple( ba, ca, da );        // J = 6V
-    Assert( J > 0, "Element Jacobian non-positive" );
-    // shape function derivatives, nnode*ndim [4][3]
-    std::array< std::array< tk::real, 3 >, 4 > grad;
-    grad[1] = tk::crossdiv( ca, da, J );
-    grad[2] = tk::crossdiv( da, ba, J );
-    grad[3] = tk::crossdiv( ba, ca, J );
-    for (std::size_t i=0; i<3; ++i)
-      grad[0][i] = -grad[1][i]-grad[2][i]-grad[3][i];
-    // sum normal contributions
-    // The constant 1/48: Eq (12) from Waltz et al. Computers & fluids (92) 2014
-    // The result of the integral of shape function N on a tet is V/4.
-    // This can be written as J/(6*4). Eq (12) has a 1/2 multiplier.
-    // This leads to J/48.
-    auto J48 = J/48.0;
-    for (const auto& [a,b] : tk::lpoed) {
-      auto s = tk::orient( {N[a],N[b]}, edge );
-      for (std::size_t j=0; j<3; ++j)
-        n[j] += J48 * s * (grad[a][j] - grad[b][j]);
-    }
-  }
-
-  return n;
-}
-
-void
-OversetFE::dfnorm()
-// *****************************************************************************
-// Compute dual-face normals associated to edges
-// *****************************************************************************
-{
-  auto d = Disc();
-  const auto& inpoel = d->Inpoel();
-  const auto& gid = d->Gid();
-
-  // compute derived data structures
-  auto esued = tk::genEsued( inpoel, 4, tk::genEsup( inpoel, 4 ) );
-
-  // Compute dual-face normals for domain edges
-  for (std::size_t p=0; p<gid.size(); ++p)    // for each point p
-    for (auto q : tk::Around(m_psup,p))       // for each edge p-q
-      if (gid[p] < gid[q])
-        m_dfnorm[{gid[p],gid[q]}] = edfnorm( {p,q}, esued );
-
-  // Send our dual-face normal contributions to neighbor chares
-  if (d->EdgeCommMap().empty())
-    comdfnorm_complete();
-  else {
-    for (const auto& [c,edges] : d->EdgeCommMap()) {
-      decltype(m_dfnorm) exp;
-      for (const auto& e : edges) exp[e] = tk::cref_find(m_dfnorm,e);
-      thisProxy[c].comdfnorm( exp );
-    }
-  }
-
-  owndfnorm_complete();
-}
-
-void
-OversetFE::comdfnorm( const std::unordered_map< tk::UnsMesh::Edge,
-                    std::array< tk::real, 3 >,
-                    tk::UnsMesh::Hash<2>, tk::UnsMesh::Eq<2> >& dfnorm )
-// *****************************************************************************
-// Receive contributions to dual-face normals on chare-boundaries
-//! \param[in] dfnorm Incoming partial sums of dual-face normals associated to
-//!   chare-boundary edges
-// *****************************************************************************
-{
-  // Buffer up inccoming contributions to dual-face normals
-  for (const auto& [e,n] : dfnorm) {
-    auto& dfn = m_dfnormc[e];
-    dfn[0] += n[0];
-    dfn[1] += n[1];
-    dfn[2] += n[2];
-  }
-
-  if (++m_ndfnorm == Disc()->EdgeCommMap().size()) {
-    m_ndfnorm = 0;
-    comdfnorm_complete();
-  }
-}
-
-void
-OversetFE::bnorm( const std::unordered_map< int,
-                std::unordered_set< std::size_t > >& bcnodes )
-// *****************************************************************************
-//  Compute boundary point normals
-//! \param[in] bcnodes Local node ids associated to side set ids at which BCs
-//!    are set that require normals
-//*****************************************************************************
-{
-  auto d = Disc();
-
-  m_bnorm = cg::bnorm( m_bface, m_triinpoel, d->Coord(), d->Gid(), bcnodes );
-
-  // Send our nodal normal contributions to neighbor chares
-  if (d->NodeCommMap().empty())
-    comnorm_complete();
-  else
-    for (const auto& [ neighborchare, sharednodes ] : d->NodeCommMap()) {
-      std::unordered_map< int,
-        std::unordered_map< std::size_t, std::array< tk::real, 4 > > > exp;
-      for (auto i : sharednodes) {
-        for (const auto& [s,norms] : m_bnorm) {
-          auto j = norms.find(i);
-          if (j != end(norms)) exp[s][i] = j->second;
-        }
-      }
-      thisProxy[ neighborchare ].comnorm( exp );
-    }
-
-  ownnorm_complete();
-}
-
-void
-OversetFE::comnorm( const std::unordered_map< int,
-  std::unordered_map< std::size_t, std::array< tk::real, 4 > > >& innorm )
-// *****************************************************************************
-// Receive boundary point normals on chare-boundaries
-//! \param[in] innorm Incoming partial sums of boundary point normal
-//!   contributions to normals (first 3 components), inverse distance squared
-//!   (4th component), associated to side set ids
-// *****************************************************************************
-{
-  // Buffer up incoming boundary-point normal vector contributions
-  for (const auto& [s,norms] : innorm) {
-    auto& bnorms = m_bnormc[s];
-    for (const auto& [p,n] : norms) {
-      auto& bnorm = bnorms[p];
-      bnorm[0] += n[0];
-      bnorm[1] += n[1];
-      bnorm[2] += n[2];
-      bnorm[3] += n[3];
-    }
-  }
-
-  if (++m_nbnorm == Disc()->NodeCommMap().size()) {
-    m_nbnorm = 0;
-    comnorm_complete();
-  }
-}
-
-void
-OversetFE::registerReducers()
-// *****************************************************************************
-//  Configure Charm++ reduction types initiated from this chare array
-//! \details Since this is a [initnode] routine, the runtime system executes the
-//!   routine exactly once on every logical node early on in the Charm++ init
-//!   sequence. Must be static as it is called without an object. See also:
-//!   Section "Initializations at Program Startup" at in the Charm++ manual
-//!   http://charm.cs.illinois.edu/manuals/html/charm++/manual.html.
-// *****************************************************************************
-{
-  NodeDiagnostics::registerReducers();
-}
-
-void
-OversetFE::ResumeFromSync()
-// *****************************************************************************
-//  Return from migration
-//! \details This is called when load balancing (LB) completes. The presence of
-//!   this function does not affect whether or not we block on LB.
-// *****************************************************************************
-{
-  if (Disc()->It() == 0) Throw( "it = 0 in ResumeFromSync()" );
-
-  if (!g_inputdeck.get< tag::cmd, tag::nonblocking >()) next();
-}
-
-//! [setup]
-void
-OversetFE::setup()
-// *****************************************************************************
-// Start setup for solution
-// *****************************************************************************
-{
-  auto d = Disc();
-
-  // Determine nodes inside user-defined IC box
-  g_cgpde[d->MeshId()].IcBoxNodes( d->Coord(), d->Inpoel(),
-    d->ElemBlockId(), m_boxnodes, m_nodeblockid, m_nusermeshblk );
-
-  // Communicate mesh block nodes to other chares on chare-boundary
-  if (d->NodeCommMap().empty())        // in serial we are done
-    comblk_complete();
-  else // send mesh block information to chare-boundary nodes to fellow chares
-    for (const auto& [c,n] : d->NodeCommMap()) {
-      // data structure assigning block ids (set of values) to nodes (index).
-      // although nodeblockid is a map with key-blockid and value-nodeid, the
-      // sending data structure has to be inverted, because of how communication
-      // data is handled.
-      std::vector< std::set< std::size_t > > mb( n.size() );
-      std::size_t j = 0;
-      for (auto i : n) {
-        for (const auto& [blid, ndset] : m_nodeblockid) {
-          // if node was found in a block, add to send-data
-          if (ndset.find(tk::cref_find(d->Lid(),i)) != ndset.end())
-            mb[j].insert(blid);
-        }
-        if (m_nusermeshblk > 0)
-          Assert(mb[j].size() > 0, "Sending no block data for node");
-        ++j;
-      }
-      thisProxy[c].comblk( std::vector<std::size_t>(begin(n),end(n)), mb );
-    }
-
-  ownblk_complete();
-}
-
-void
-OversetFE::comblk( const std::vector< std::size_t >& gid,
-               const std::vector< std::set< std::size_t > >& mb )
-// *****************************************************************************
-//  Receive mesh block information for nodes on chare-boundaries
-//! \param[in] gid Global mesh node IDs at which we receive RHS contributions
-//! \param[in] mb Block ids for each node on chare-boundaries
-//! \details This function receives mesh block information for nodes on chare
-//!   boundaries. While m_nodeblockid stores block information for own nodes,
-//!   m_nodeblockidc collects the neighbor chare information during
-//!   communication. This way work on m_nodeblockid and m_nodeblockidc is
-//!   overlapped. The two are combined in continueSetup().
-// *****************************************************************************
-{
-  Assert( mb.size() == gid.size(), "Size mismatch" );
-
-  for (std::size_t i=0; i<gid.size(); ++i) {
-    for (const auto& blid : mb[i]) {
-      m_nodeblockidc[blid].insert(gid[i]);
-    }
-  }
-
-  // When we have heard from all chares we communicate with, this chare is done
-  if (++m_nmblk == Disc()->NodeCommMap().size()) {
-    m_nmblk = 0;
-    comblk_complete();
-  }
-}
-
-void
-OversetFE::continueSetup()
-// *****************************************************************************
-// Continue setup for solution, after communication for mesh blocks
-// *****************************************************************************
-{
-  auto d = Disc();
-
-  // Combine own and communicated mesh block information
-  for (const auto& [blid, ndset] : m_nodeblockidc) {
-    for (const auto& i : ndset) {
-      auto lid = tk::cref_find(d->Lid(), i);
-      m_nodeblockid[blid].insert(lid);
-    }
-  }
-
-  // clear receive buffer
-  tk::destroy(m_nodeblockidc);
-
-  // Compute volume of user-defined box IC
-  d->boxvol( m_boxnodes, m_nodeblockid, m_nusermeshblk );
-
-  // Query time history field output labels from all PDEs integrated
-  const auto& hist_points = g_inputdeck.get< tag::history_output, tag::point >();
-  if (!hist_points.empty()) {
-    std::vector< std::string > histnames;
-    auto n = g_cgpde[d->MeshId()].histNames();
-    histnames.insert( end(histnames), begin(n), end(n) );
-    d->histheader( std::move(histnames) );
-  }
-}
-//! [setup]
-
-void
-OversetFE::box( tk::real v, const std::vector< tk::real >& blkvols )
-// *****************************************************************************
-// Receive total box IC volume and set conditions in box
-//! \param[in] v Total volume within user-specified box
-//! \param[in] blkvols Vector of mesh block discrete volumes with user ICs
-// *****************************************************************************
-{
-  Assert(blkvols.size() == m_nusermeshblk,
-    "Incorrect size of block volume vector");
-  auto d = Disc();
-
-  // Store user-defined box/block IC volume
-  d->Boxvol() = v;
-  d->MeshBlkVol() = blkvols;
-
-  // Set initial conditions for all PDEs
-  g_cgpde[d->MeshId()].initialize( d->Coord(), m_u, d->T(), d->Boxvol(),
-    m_boxnodes, d->MeshBlkVol(), m_nodeblockid );
-
-  // Initialize nodal mesh volumes at previous time step stage
-  d->Voln() = d->Vol();
-
-  // Initiate solution transfer (if coupled)
-  transferSol();
-}
-
-void
-OversetFE::transferSol()
-// *****************************************************************************
-// Transfer solution to other solver and mesh if coupled
-// *****************************************************************************
-{
-  // Set up transfer-flags for receiving mesh
-  if (m_ixfer == 1) {
-    applySolTransfer(0);
-  }
-  setTransferFlags(m_ixfer);
-  ++m_ixfer;
-
-  // Initiate IC transfer (if coupled)
-  Disc()->transfer( m_uc, m_ixfer-1,
-    CkCallback(CkIndex_OversetFE::lhs(), thisProxy[thisIndex]) );
-}
-
-//! [Compute lhs]
-void
-OversetFE::lhs()
-// *****************************************************************************
-// Compute the left-hand side of transport equations
-//! \details Also (re-)compute all data structures if the mesh changed.
-// *****************************************************************************
-{
-  // Do corrections in solution based on incoming transfer
-  applySolTransfer(1);
-  m_ixfer = 0;
-
-  // No need for LHS in OversetFE
-
-  // If mesh moved: (Re-)compute boundary point- and dual-face normals, and
-  //   then proceed to stage()
-  // If mesh did not move: shortcut to stage()
-  if (m_movedmesh || Disc()->Initial()) norm();
-  else stage();
-}
-//! [Compute lhs]
-
-//! [Merge normals and continue]
-void
-OversetFE::mergelhs()
-// *****************************************************************************
-// The own and communication portion of the left-hand side is complete
-// *****************************************************************************
-{
-  // Combine own and communicated contributions of normals
-  normfinal();
-
-  // Start with time stepping logic
-  if (Disc()->Initial()) {
-    // Output initial conditions to file and then start time stepping
-    writeFields( CkCallback(CkIndex_OversetFE::start(), thisProxy[thisIndex]) );
-  }
-  else stage();
-}
-//! [Merge normals and continue]
-
-//! [start]
-void
-OversetFE::start()
-// *****************************************************************************
-// Start time stepping
-// *****************************************************************************
-{
-  // Set flag that indicates that we are now during time stepping
-  Disc()->Initial( 0 );
-  // Start timer measuring time stepping wall clock time
-  Disc()->Timer().zero();
-  // Zero grind-timer
-  Disc()->grindZero();
-  // Continue to first time step
-  next();
-}
-//! [start]
-
-void
-OversetFE::applySolTransfer(
-  std::size_t dirn )
-// *****************************************************************************
-// \brief Apply the transferred solution to the solution vector based on
-//   transfer flags previously set up
-//! \param[in] dirn 0 if called from B to O, 1 if called from O to B
-// *****************************************************************************
-{
-  // Change solution only if:
-  //   1. undergoing transfer from B to O, and currently on O
-  if (dirn == 0 && Disc()->MeshId() != 0) {
-
-    for (auto i : m_farfieldbcnodes) {
-      // overset-BC nodes: use transferred solution and blank nodes.
-      // the transfer-flag from m_uc is not used since it has been overwritten
-      // by Disc()->transfer() with the flag from B
-      for (ncomp_t c=0; c<m_u.nprop(); ++c) { // Loop over number of equations
-        m_u(i,c) = m_uc(i,c);
-      }
-      m_blank[i] = 0.0;
-    }
-
-  }
-  //   2. undergoing transfer from O to B, and currently on B
-  else if (dirn == 1 && Disc()->MeshId() == 0) {
-
-    //TODO: index the flag in a better way
-    std::size_t iflag = m_uc.nprop()-1;
-
-    // Zero out solution space for nodes with a specific transfer flag set
-    for (std::size_t i=0; i<m_uc.nunk(); ++i) { // Check flag value
-
-      if (std::abs(m_uc(i,iflag) - 1.0) < 1e-4) {
-        // overset-BC nodes: use transferred solution and blank nodes
-        for (ncomp_t c=0; c<m_u.nprop(); ++c) { // Loop over number of equations
-          m_u(i,c) = m_uc(i,c);
-        }
-        m_blank[i] = 0.0;
-      }
-      else if (std::abs(m_uc(i,iflag) - 2.0) < 1e-4) {
-        // hole: blank nodes
-        m_blank[i] = 0.0;
-      }
-      else {
-        // do nothing
-        m_blank[i] = 1.0;
-      }
-
-    }
-
-  }
-}
-
-void
-OversetFE::setTransferFlags(
-  std::size_t dirn )
-// *****************************************************************************
-//  Set flags informing solution transfer decisions
-//! \param[in] dirn 0 if called from B to O, 1 if called from O to B
-// *****************************************************************************
-{
-  // Copy solution and reset flags
-  //TODO: index the flag in a better way
-  std::size_t iflag = m_uc.nprop()-1;
-
-  for (std::size_t i=0; i<m_u.nunk(); ++i) {
-    for (std::size_t c=0; c<m_u.nprop(); ++c) {
-      m_uc(i,c) = m_u(i,c);
-    }
-    // Reset flags
-    m_uc(i,iflag) = 0.0;
-
-    // reset blanking coefficient
-    m_blank[i] = 1.0;
-  }
-
-  // Transfer flags for O to B are based on block-ids that are hardcoded
-  // TODO: remove hardcoding
-
-  // Called from transfer-B-to-O
-  if (dirn == 0) {
-    if (Disc()->MeshId() != 0) {
-      // Overset meshes: assign appropriate values to flag
-      for (auto i : m_farfieldbcnodes) m_uc(i,iflag) = 1.0;
-    }
-  }
-  // Called from transfer-O-to-B
-  else {
-    if (Disc()->MeshId() != 0) {
-      // Overset meshes: assign appropriate values to flag
-      for (const auto& [blid, ndset] : m_nodeblockid) {
-        if (blid == 103) {
-          for (auto i : ndset) m_uc(i,iflag) = 1.0;
-        }
-        else if (blid == 104) {
-          for (auto i : ndset) m_uc(i,iflag) = 2.0;
-        }
-      }
-    }
-  }
-}
-
-void
-OversetFE::normfinal()
-// *****************************************************************************
-//  Finish computing dual-face and boundary point normals
-// *****************************************************************************
-{
-  auto d = Disc();
-  const auto& lid = d->Lid();
-
-  // Combine own and communicated contributions to boundary point normals
-  for (const auto& [s,norms] : m_bnormc) {
-    auto& bnorms = m_bnorm[s];
-    for (const auto& [p,n] : norms) {
-      auto& norm = bnorms[p];
-      norm[0] += n[0];
-      norm[1] += n[1];
-      norm[2] += n[2];
-      norm[3] += n[3];
-    }
-  }
-  tk::destroy( m_bnormc );
-
-  // Divide summed point normals by the sum of inverse distance squared
-  for (auto& [s,norms] : m_bnorm)
-    for (auto& [p,n] : norms) {
-      n[0] /= n[3];
-      n[1] /= n[3];
-      n[2] /= n[3];
-      Assert( (n[0]*n[0] + n[1]*n[1] + n[2]*n[2] - 1.0) <
-              1.0e+3*std::numeric_limits< tk::real >::epsilon(),
-              "Non-unit normal" );
-    }
-
-  // Replace global->local ids associated to boundary point normals
-  decltype(m_bnorm) bnorm;
-  for (auto& [s,norms] : m_bnorm) {
-    auto& bnorms = bnorm[s];
-    for (auto&& [g,n] : norms)
-      bnorms[ tk::cref_find(lid,g) ] = std::move(n);
-  }
-  m_bnorm = std::move(bnorm);
-
-  // Count contributions to chare-boundary edges
-  std::unordered_map< tk::UnsMesh::Edge, std::size_t,
-    tk::UnsMesh::Hash<2>, tk::UnsMesh::Eq<2> > edge_node_count;
-  for (const auto& [c,edges] : d->EdgeCommMap())
-    for (const auto& e : edges)
-      ++edge_node_count[e];
-
-  // Combine and weigh communicated contributions to dual-face normals
-  for (auto& [e,n] : m_dfnormc) {
-    const auto& dfn = tk::cref_find( m_dfnorm, e );
-    n[0] += dfn[0];
-    n[1] += dfn[1];
-    n[2] += dfn[2];
-    auto count = static_cast< tk::real >( tk::cref_find( edge_node_count, e ) );
-    auto factor = 1.0/(count + 1.0);
-    for (auto & x : n) x *= factor;<--- Consider using std::transform algorithm instead of a raw loop.
-  }
-
-  // Generate list of unique edges
-  tk::UnsMesh::EdgeSet uedge;
-  for (std::size_t p=0; p<m_u.nunk(); ++p)
-    for (auto q : tk::Around(m_psup,p))
-      uedge.insert( {p,q} );
-
-  // Flatten edge list
-  m_edgenode.resize( uedge.size() * 2 );
-  std::size_t f = 0;
-  const auto& gid = d->Gid();
-  for (auto&& [p,q] : uedge) {
-    if (gid[p] > gid[q]) {
-      m_edgenode[f+0] = std::move(q);
-      m_edgenode[f+1] = std::move(p);
-    } else {
-      m_edgenode[f+0] = std::move(p);
-      m_edgenode[f+1] = std::move(q);
-    }
-    f += 2;
-  }
-  tk::destroy(uedge);
-
-  // Convert dual-face normals to streamable (and vectorizable) data structure
-  m_dfn.resize( m_edgenode.size() * 3 );      // 2 vectors per access
-  std::unordered_map< tk::UnsMesh::Edge, std::size_t,
-                      tk::UnsMesh::Hash<2>, tk::UnsMesh::Eq<2> > eid;
-  for (std::size_t e=0; e<m_edgenode.size()/2; ++e) {
-    auto p = m_edgenode[e*2+0];
-    auto q = m_edgenode[e*2+1];
-    eid[{p,q}] = e;
-    std::array< std::size_t, 2 > g{ gid[p], gid[q] };
-    auto n = tk::cref_find( m_dfnorm, g );
-    // figure out if this is an edge on the parallel boundary
-    auto nit = m_dfnormc.find( g );
-    auto m = ( nit != m_dfnormc.end() ) ? nit->second : n;
-    m_dfn[e*6+0] = n[0];
-    m_dfn[e*6+1] = n[1];
-    m_dfn[e*6+2] = n[2];
-    m_dfn[e*6+3] = m[0];
-    m_dfn[e*6+4] = m[1];
-    m_dfn[e*6+5] = m[2];
-  }
-
-  tk::destroy( m_dfnorm );
-  tk::destroy( m_dfnormc );
-
-  // Flatten edge id data structure
-  m_edgeid.resize( m_psup.first.size() );
-  for (std::size_t p=0,k=0; p<m_u.nunk(); ++p)
-    for (auto q : tk::Around(m_psup,p))
-      m_edgeid[k++] = tk::cref_find( eid, {p,q} );
-}
-
-void
-OversetFE::BC()
-// *****************************************************************************
-// Apply boundary conditions
-// \details The following BC enforcement changes the initial condition or
-//!   updated solution (dependending on when it is called) to ensure strong
-//!   imposition of the BCs. This is a matter of choice. Another alternative is
-//!   to only apply BCs when computing fluxes at boundary faces, thereby only
-//!   weakly enforcing the BCs. The former is conventionally used in continunous
-//!   Galerkin finite element methods (such as OversetFE implements), whereas the
-//!   latter, in finite volume methods.
-// *****************************************************************************
-{
-  auto d = Disc();
-  const auto& coord = d->Coord();
-
-  const auto& bcmesh = g_inputdeck.get< tag::bc >();
-
-  for (const auto& bci : bcmesh) {
-    const auto& bcm = bci.get< tag::mesh >();
-    for (const auto& im : bcm) {
-      // only if this bc is meant for current mesh
-      if (im-1 == d->MeshId()) {
-
-        // Query and match user-specified Dirichlet boundary conditions to side sets
-        const auto steady = g_inputdeck.get< tag::steady_state >();
-        if (steady) for (auto& deltat : m_dtp) deltat *= rkcoef[m_stage];<--- Consider using std::transform algorithm instead of a raw loop.
-        m_dirbc = match( d->MeshId(), m_u.nprop(), d->T(), rkcoef[m_stage] * d->Dt(),
-                         m_tp, m_dtp, d->Coord(), d->Lid(), m_bnode,
-                       /* increment = */ false );
-        if (steady) for (auto& deltat : m_dtp) deltat /= rkcoef[m_stage];<--- Consider using std::transform algorithm instead of a raw loop.
-
-        // Apply Dirichlet BCs
-        for (const auto& [b,bc] : m_dirbc)
-          for (ncomp_t c=0; c<m_u.nprop(); ++c)
-            if (bc[c].first) m_u(b,c) = bc[c].second;
-
-        // Apply symmetry BCs
-        g_cgpde[d->MeshId()].symbc( m_u, coord, m_bnorm, m_symbcnodes );
-
-        // Apply farfield BCs
-        if (bci.get< tag::farfield >().empty() || (d->MeshId() == 0)) {
-          g_cgpde[d->MeshId()].farfieldbc( m_u, coord, m_bnorm, m_farfieldbcnodes );
-        }
-
-        // Apply user defined time dependent BCs
-        g_cgpde[d->MeshId()].timedepbc( d->T(), m_u, m_timedepbcnodes,
-          m_timedepbcFn );
-      }
-    }
-  }
-}
-
-void
-OversetFE::next()
-// *****************************************************************************
-// Continue to next time step
-// *****************************************************************************
-{
-  dt();
-}
-
-void
-OversetFE::dt()
-// *****************************************************************************
-// Compute time step size
-// *****************************************************************************
-{
-  tk::real mindt = std::numeric_limits< tk::real >::max();
-
-  auto const_dt = g_inputdeck.get< tag::dt >();
-  auto eps = std::numeric_limits< tk::real >::epsilon();
-
-  auto d = Disc();
-
-  // use constant dt if configured
-  if (std::abs(const_dt) > eps) {
-
-    mindt = const_dt;
-
-  } else {      // compute dt based on CFL
-
-    //! [Find the minimum dt across all PDEs integrated]
-    if (g_inputdeck.get< tag::steady_state >()) {
-
-      // compute new dt for each mesh point
-      g_cgpde[d->MeshId()].dt( d->It(), d->Vol(), m_u, m_dtp );
-
-      // find the smallest dt of all nodes on this chare
-      mindt = *std::min_element( begin(m_dtp), end(m_dtp) );
-
-    } else {    // compute new dt for this chare
-
-      // find the smallest dt of all equations on this chare
-      auto eqdt = g_cgpde[d->MeshId()].dt( d->Coord(), d->Inpoel(), d->T(),
-        d->Dtn(), m_u, d->Vol(), d->Voln() );
-      if (eqdt < mindt) mindt = eqdt;
-
-    }
-    //! [Find the minimum dt across all PDEs integrated]
-
-  }
-
-  // Determine if this chunk of mesh needs to be moved
-  g_cgpde[d->MeshId()].getMeshVel(d->T(), d->Coord(), m_psup, m_symbcnodes,
-    m_uservel, m_u, d->MeshVel(), m_movedmesh);
-
-  //! [Advance]
-  // Actiavate SDAG waits for next time step stage
-  thisProxy[ thisIndex ].wait4grad();
-  thisProxy[ thisIndex ].wait4rhs();
-
-  // TODO: this is a hacky way to know if any chunk moved. redesign it
-  std::vector < tk::real > reducndata(d->Transfers().size()+2, 0.0);
-
-  reducndata[0] = mindt;
-  reducndata[d->MeshId()+1] = static_cast< tk::real >(-m_movedmesh);
-
-  // Contribute to minimum dt across all chares and advance to next step
-  if (g_inputdeck.get< tag::steady_state >()) {
-    contribute( reducndata, CkReduction::min_double,
-                CkCallback(CkReductionTarget(OversetFE,advance), thisProxy) );
-  }
-  else {
-    // if solving a time-accurate problem, find minimum dt across all meshes
-    // and eventually broadcast to OversetFE::advance()
-    contribute( reducndata, CkReduction::min_double,
-      CkCallback(CkReductionTarget(Transporter,minDtAcrossMeshes), d->Tr()) );
-  }
-  //! [Advance]
-}
-
-void
-OversetFE::advance( tk::real newdt, tk::real nmovedmesh )
-// *****************************************************************************
-// Advance equations to next time step
-//! \param[in] newdt The smallest dt across the whole problem
-//! \param[in] nmovedmesh (negative of) if any chunk of this mesh moved
-// *****************************************************************************
-{
-  auto d = Disc();
-
-  // Set new time step size
-  if (m_stage == 0) d->setdt( newdt );
-
-  // TODO: this is a hacky way to know if any chunk moved. redesign it
-  if (nmovedmesh < -0.1) m_movedmesh = 1;
-
-  // Compute gradients for next time step
-  chBndGrad();
-}
-
-void
-OversetFE::chBndGrad()
-// *****************************************************************************
-// Compute nodal gradients at chare-boundary nodes. Gradients at internal nodes
-// are calculated locally as needed and are not stored.
-// *****************************************************************************
-{
-  auto d = Disc();
-
-  // Compute own portion of gradients for all equations
-  g_cgpde[d->MeshId()].chBndGrad( d->Coord(), d->Inpoel(), m_bndel, d->Gid(),
-    d->Bid(), m_u, m_chBndGrad );
-
-  // Communicate gradients to other chares on chare-boundary
-  if (d->NodeCommMap().empty())        // in serial we are done
-    comgrad_complete();
-  else // send gradients contributions to chare-boundary nodes to fellow chares
-    for (const auto& [c,n] : d->NodeCommMap()) {
-      std::vector< std::vector< tk::real > > g( n.size() );
-      std::size_t j = 0;
-      for (auto i : n) g[ j++ ] = m_chBndGrad[ tk::cref_find(d->Bid(),i) ];
-      thisProxy[c].comChBndGrad( std::vector<std::size_t>(begin(n),end(n)), g );
-    }
-
-  owngrad_complete();
-}
-
-void
-OversetFE::comChBndGrad( const std::vector< std::size_t >& gid,
-                     const std::vector< std::vector< tk::real > >& G )
-// *****************************************************************************
-//  Receive contributions to nodal gradients on chare-boundaries
-//! \param[in] gid Global mesh node IDs at which we receive grad contributions
-//! \param[in] G Partial contributions of gradients to chare-boundary nodes
-//! \details This function receives contributions to m_chBndGrad, which stores
-//!   nodal gradients at mesh chare-boundary nodes. While m_chBndGrad stores
-//!   own contributions, m_chBndGradc collects the neighbor chare
-//!   contributions during communication. This way work on m_chBndGrad and
-//!   m_chBndGradc is overlapped. The two are combined in rhs().
-// *****************************************************************************
-{
-  Assert( G.size() == gid.size(), "Size mismatch" );
-
-  using tk::operator+=;
-
-  for (std::size_t i=0; i<gid.size(); ++i) m_chBndGradc[ gid[i] ] += G[i];
-
-  if (++m_ngrad == Disc()->NodeCommMap().size()) {
-    m_ngrad = 0;
-    comgrad_complete();
-  }
-}
-
-void
-OversetFE::rhs()
-// *****************************************************************************
-// Compute right-hand side of transport equations
-// *****************************************************************************
-{
-  auto d = Disc();
-
-  // Combine own and communicated contributions to nodal gradients
-  for (const auto& [gid,g] : m_chBndGradc) {
-    auto bid = tk::cref_find( d->Bid(), gid );
-    for (ncomp_t c=0; c<m_chBndGrad.nprop(); ++c)
-      m_chBndGrad(bid,c) += g[c];
-  }
-
-  // clear gradients receive buffer
-  tk::destroy(m_chBndGradc);
-
-  const auto steady = g_inputdeck.get< tag::steady_state >();
-
-  // Assign mesh velocity
-  if (m_movedmesh) {
-    const auto& coord = d->Coord();
-    auto& mvel = d->MeshVel();
-    for (std::size_t p=0; p<coord[0].size(); ++p) {
-      for (std::size_t i=0; i<3; ++i)
-        mvel(p, i) = m_uservel[i];
-    }
-  }
-
-  // Compute own portion of right-hand side for all equations
-  auto prev_rkcoef = m_stage == 0 ? 0.0 : rkcoef[m_stage-1];
-  if (steady)
-    for (std::size_t p=0; p<m_tp.size(); ++p) m_tp[p] += prev_rkcoef * m_dtp[p];
-  g_cgpde[d->MeshId()].rhs( d->T() + prev_rkcoef * d->Dt(), d->Coord(), d->Inpoel(),
-          m_triinpoel, d->Gid(), d->Bid(), d->Lid(), m_dfn, m_psup, m_esup,
-          m_symbctri, d->Vol(), m_edgenode, m_edgeid,
-          m_boxnodes, m_chBndGrad, m_u, d->MeshVel(), m_tp, d->Boxvol(),
-          m_rhs );
-  if (steady)
-    for (std::size_t p=0; p<m_tp.size(); ++p) m_tp[p] -= prev_rkcoef * m_dtp[p];
-
-  // Communicate rhs to other chares on chare-boundary
-  if (d->NodeCommMap().empty())        // in serial we are done
-    comrhs_complete();
-  else // send contributions of rhs to chare-boundary nodes to fellow chares
-    for (const auto& [c,n] : d->NodeCommMap()) {
-      std::vector< std::vector< tk::real > > r( n.size() );
-      std::size_t j = 0;
-      for (auto i : n) r[ j++ ] = m_rhs[ tk::cref_find(d->Lid(),i) ];
-      thisProxy[c].comrhs( std::vector<std::size_t>(begin(n),end(n)), r );
-    }
-
-  ownrhs_complete();
-}
-
-void
-OversetFE::comrhs( const std::vector< std::size_t >& gid,
-               const std::vector< std::vector< tk::real > >& R )
-// *****************************************************************************
-//  Receive contributions to right-hand side vector on chare-boundaries
-//! \param[in] gid Global mesh node IDs at which we receive RHS contributions
-//! \param[in] R Partial contributions of RHS to chare-boundary nodes
-//! \details This function receives contributions to m_rhs, which stores the
-//!   right hand side vector at mesh nodes. While m_rhs stores own
-//!   contributions, m_rhsc collects the neighbor chare contributions during
-//!   communication. This way work on m_rhs and m_rhsc is overlapped. The two
-//!   are combined in solve().
-// *****************************************************************************
-{
-  Assert( R.size() == gid.size(), "Size mismatch" );
-
-  using tk::operator+=;
-
-  for (std::size_t i=0; i<gid.size(); ++i) m_rhsc[ gid[i] ] += R[i];
-
-  // When we have heard from all chares we communicate with, this chare is done
-  if (++m_nrhs == Disc()->NodeCommMap().size()) {
-    m_nrhs = 0;
-    comrhs_complete();
-  }
-}
-
-void
-OversetFE::solve()
-// *****************************************************************************
-//  Advance systems of equations
-// *****************************************************************************
-{
-  auto d = Disc();
-
-  // Combine own and communicated contributions to rhs
-  for (const auto& b : m_rhsc) {
-    auto lid = tk::cref_find( d->Lid(), b.first );
-    for (ncomp_t c=0; c<m_rhs.nprop(); ++c) m_rhs(lid,c) += b.second[c];
-  }
-
-  // clear receive buffer
-  tk::destroy(m_rhsc);
-
-  // Update state at time n
-  if (m_stage == 0) {
-    m_un = m_u;
-  }
-
-  // Explicit time-stepping using RK3
-  const auto steady = g_inputdeck.get< tag::steady_state >();
-  for (std::size_t i=0; i<m_u.nunk(); ++i) {
-    // time-step
-    auto dtp = d->Dt();
-    if (steady) dtp = m_dtp[i];
-
-    for (ncomp_t c=0; c<m_u.nprop(); ++c)
-      m_u(i,c) = m_un(i,c) + m_blank[i] * rkcoef[m_stage] * dtp * m_rhs(i,c)
-        / d->Vol()[i];
-  }
-
-  // Move overset mesh
-  if (m_movedmesh) {
-    auto& x = d->Coord()[0];
-    auto& y = d->Coord()[1];
-    auto& z = d->Coord()[2];
-    const auto& w = d->MeshVel();
-    for (std::size_t i=0; i<w.nunk(); ++i) {
-      // time-step
-      auto dtp = d->Dt();
-      if (steady) dtp = m_dtp[i];
-
-      x[i] += rkcoef[m_stage] * dtp * w(i,0);
-      y[i] += rkcoef[m_stage] * dtp * w(i,1);
-      z[i] += rkcoef[m_stage] * dtp * w(i,2);
-    }
-  }
-  // the following line will be needed for situations where the mesh stops
-  // moving after its initial motion
-  // else m_movedmesh = 0;
-
-  // Apply boundary-conditions
-  BC();
-
-  // Increment Runge-Kutta stage counter
-  ++m_stage;
-
-  // Activate SDAG wait for next time step stage
-  thisProxy[ thisIndex ].wait4grad();
-  thisProxy[ thisIndex ].wait4rhs();
-
-  // Compute diagnostics, and finish-up time step (if m_stage == 3)
-  bool diag_computed(false);
-  if (m_stage == 3) {
-    // Compute diagnostics, e.g., residuals
-    diag_computed = m_diag.compute( *d, m_u, m_un, m_bnorm,
-                                    m_symbcnodes, m_farfieldbcnodes );
-    // Increase number of iterations and physical time
-    d->next();
-    // Advance physical time for local time stepping
-    if (g_inputdeck.get< tag::steady_state >())
-      for (std::size_t i=0; i<m_u.nunk(); ++i) m_tp[i] += m_dtp[i];
-  }
-  // Continue to finish-up time-step-stage
-  // Note: refine is called via a bcast if diag_computed == true
-  if (!diag_computed) refine( std::vector< tk::real >( m_u.nprop(), 1.0 ) );
-}
-
-//! [Refine]
-void
-OversetFE::refine( const std::vector< tk::real >& l2res )
-// *****************************************************************************
-// Finish up end of time-step procedures and continue to moving mesh
-//! \param[in] l2res L2-norms of the residual for each scalar component
-//!   computed across the whole problem
-// *****************************************************************************
-{
-  auto d = Disc();
-
-  if (m_stage == 3) {
-    const auto steady = g_inputdeck.get< tag::steady_state >();
-    const auto residual = g_inputdeck.get< tag::residual >();
-    const auto rc = g_inputdeck.get< tag::rescomp >() - 1;
-
-    if (m_movedmesh) {
-      d->Itf() = 0;  // Zero field output iteration count if mesh moved
-      ++d->Itr();    // Increase number of iterations with a change in the mesh
-    }
-
-    if (steady) {
-
-      // this is the last time step if max time of max number of time steps
-      // reached or the residual has reached its convergence criterion
-      if (d->finished() or l2res[rc] < residual) m_finished = 1;
-
-    } else {
-
-      // this is the last time step if max time or max iterations reached
-      if (d->finished()) m_finished = 1;
-
-    }
-  }
-
-  if (m_movedmesh) {
-    // Normals need to be recomputed if overset mesh has been moved
-    thisProxy[ thisIndex ].wait4norm();
-  }
-
-  // Start solution transfer
-  transferSol();
-}
-//! [Refine]
-
-//! [stage]
-void
-OversetFE::stage()
-// *****************************************************************************
-// Evaluate whether to continue with next time step stage
-// *****************************************************************************
-{
-  // if not all Runge-Kutta stages complete, continue to next time stage,
-  // otherwise start next time step
-  if (m_stage == 3) {
-    // output field data and start with next time step
-    out();
-  }
-  else {
-    // start with next time-step stage
-    chBndGrad();
-  }
-}
-//! [stage]
-
-void
-OversetFE::writeFields( CkCallback c )
-// *****************************************************************************
-// Output mesh-based fields to file
-//! \param[in] c Function to continue with after the write
-// *****************************************************************************
-{
-  if (g_inputdeck.get< tag::cmd, tag::benchmark >()) {
-
-    c.send();
-
-  } else {
-
-    auto d = Disc();
-    const auto& coord = d->Coord();
-
-    //// if coupled: depvars: src:'a', dst:'b','c',...
-    //char depvar = 0;
-    //if (not d->Transfers().empty()) {
-    //  depvar = 'a' + static_cast< char >( d->MeshId() );
-    //}
-
-    // Query fields names requested by user
-    auto nodefieldnames = numericFieldNames( tk::Centering::NODE );
-
-    // Collect field output from numerical solution requested by user
-    auto nodefields = numericFieldOutput( m_u, tk::Centering::NODE,
-      g_cgpde[Disc()->MeshId()].OutVarFn(), m_u );
-
-    // Collect field output names for analytical solutions
-    analyticFieldNames( g_cgpde[d->MeshId()], tk::Centering::NODE,
-      nodefieldnames );
-
-    // Collect field output from analytical solutions (if exist)
-    analyticFieldOutput( g_cgpde[d->MeshId()], tk::Centering::NODE, coord[0],
-      coord[1], coord[2], d->T(), nodefields );
-
-    // Query and collect nodal block and surface field names from PDEs integrated
-    std::vector< std::string > nodesurfnames;
-    auto sn = g_cgpde[d->MeshId()].surfNames();
-    nodesurfnames.insert( end(nodesurfnames), begin(sn), end(sn) );
-
-    // Collect nodal block and surface field solution
-    std::vector< std::vector< tk::real > > nodesurfs;
-    auto so = g_cgpde[d->MeshId()].surfOutput( tk::bfacenodes(m_bface,
-      m_triinpoel), m_u );
-    nodesurfs.insert( end(nodesurfs), begin(so), end(so) );
-
-    // Collect elemental block and surface field names from PDEs integrated
-    auto elemsurfnames = nodesurfnames;<--- Variable 'elemsurfnames' is assigned a value that is never used.
-
-    // Collect elemental block and surface field solution
-    std::vector< std::vector< tk::real > > elemsurfs;
-    auto eso = g_cgpde[d->MeshId()].elemSurfOutput( m_bface, m_triinpoel, m_u );
-    elemsurfs.insert( end(elemsurfs), begin(eso), end(eso) );
-
-    Assert( nodefieldnames.size() == nodefields.size(), "Size mismatch" );
-
-    // Send mesh and fields data (solution dump) for output to file
-    d->write( d->Inpoel(), coord, m_bface, tk::remap(m_bnode,d->Lid()),
-              m_triinpoel, {}, nodefieldnames, elemsurfnames,
-              nodesurfnames, {}, nodefields, elemsurfs, nodesurfs, c );
-
-  }
-}
-
-void
-OversetFE::out()
-// *****************************************************************************
-// Output mesh field data and continue to next time step
-// *****************************************************************************
-{
-  auto d = Disc();
-
-  // Output time history
-  if (d->histiter() or d->histtime() or d->histrange()) {
-    std::vector< std::vector< tk::real > > hist;
-    auto h = g_cgpde[d->MeshId()].histOutput( d->Hist(), d->Inpoel(), m_u );
-    hist.insert( end(hist), begin(h), end(h) );
-    d->history( std::move(hist) );
-  }
-
-  // Output field data
-  if (d->fielditer() or d->fieldtime() or d->fieldrange() or m_finished)
-    writeFields(CkCallback( CkIndex_OversetFE::step(), thisProxy[thisIndex]) );
-  else
-    step();
-}
-
-void
-OversetFE::evalLB( int nrestart )
-// *****************************************************************************
-// Evaluate whether to do load balancing
-//! \param[in] nrestart Number of times restarted
-// *****************************************************************************
-{
-  auto d = Disc();
-
-  // Detect if just returned from a checkpoint and if so, zero timers and
-  // finished flag
-  if (d->restarted( nrestart )) m_finished = 0;
-
-  const auto lbfreq = g_inputdeck.get< tag::cmd, tag::lbfreq >();
-  const auto nonblocking = g_inputdeck.get< tag::cmd, tag::nonblocking >();
-
-  // Load balancing if user frequency is reached or after the second time-step
-  if ( (d->It()) % lbfreq == 0 || d->It() == 2 ) {
-
-    AtSync();
-    if (nonblocking) next();
-
-  } else {
-
-    next();
-
-  }
-}
-
-void
-OversetFE::evalRestart()
-// *****************************************************************************
-// Evaluate whether to save checkpoint/restart
-// *****************************************************************************
-{
-  auto d = Disc();
-
-  const auto rsfreq = g_inputdeck.get< tag::cmd, tag::rsfreq >();
-  const auto benchmark = g_inputdeck.get< tag::cmd, tag::benchmark >();
-
-  if (not benchmark and not (d->It() % rsfreq)) {
-
-    std::vector< std::size_t > meshdata{ /* finished = */ 0, d->MeshId() };
-    contribute( meshdata, CkReduction::nop,
-      CkCallback(CkReductionTarget(Transporter,checkpoint), d->Tr()) );
-
-  } else {
-
-    evalLB( /* nrestart = */ -1 );
-
-  }
-}
-
-void
-OversetFE::step()
-// *****************************************************************************
-// Evaluate whether to continue with next time step
-// *****************************************************************************
-{
-  auto d = Disc();
-
-  // Output one-liner status report to screen
-  d->status();
-  // Reset Runge-Kutta stage counter
-  m_stage = 0;
-
-  if (not m_finished) {
-
-    evalRestart();
-
-  } else {
-
-    auto meshid = d->MeshId();
-    d->contribute( sizeof(std::size_t), &meshid, CkReduction::nop,
-                   CkCallback(CkReductionTarget(Transporter,finish), d->Tr()) );
-
-  }
-}
-
-#include "NoWarning/oversetfe.def.h"
+    const auto& timedep = ib.get< tag::timedep >();
+    if (!timedep.empty()) {
+      for (const auto& bndry : timedep) {
+        nfo.emplace_back( "Time dependent BC sideset(s)",<--- Consider using std::transform algorithm instead of a raw loop.
+          parameters(bndry.get< tag::sideset >()) );
+      }
+    }
+  }
+
+  return nfo;
+}
+
+}  // inciter::
 
diff --git a/Release/cppcheck/49.html b/Release/cppcheck/49.html index 6adb888aaedd..3d4333aca98b 100644 --- a/Release/cppcheck/49.html +++ b/Release/cppcheck/49.html @@ -152,3239 +152,1457 @@
- - + diff --git a/Release/test_coverage/Inciter/AMR/marked_refinements_store.hpp.func-sort-c.html b/Release/test_coverage/Inciter/AMR/marked_refinements_store.hpp.func-sort-c.html index a53b7893114b..d118ff0b492a 100644 --- a/Release/test_coverage/Inciter/AMR/marked_refinements_store.hpp.func-sort-c.html +++ b/Release/test_coverage/Inciter/AMR/marked_refinements_store.hpp.func-sort-c.html @@ -33,7 +33,7 @@ - + diff --git a/Release/test_coverage/Inciter/AMR/marked_refinements_store.hpp.func.html b/Release/test_coverage/Inciter/AMR/marked_refinements_store.hpp.func.html index 10ef76ec7e56..c28ef1c0fdd1 100644 --- a/Release/test_coverage/Inciter/AMR/marked_refinements_store.hpp.func.html +++ b/Release/test_coverage/Inciter/AMR/marked_refinements_store.hpp.func.html @@ -33,7 +33,7 @@ - + diff --git a/Release/test_coverage/Inciter/AMR/marked_refinements_store.hpp.gcov.html b/Release/test_coverage/Inciter/AMR/marked_refinements_store.hpp.gcov.html index 3e7fdbafffb6..d43a8c302e60 100644 --- a/Release/test_coverage/Inciter/AMR/marked_refinements_store.hpp.gcov.html +++ b/Release/test_coverage/Inciter/AMR/marked_refinements_store.hpp.gcov.html @@ -33,7 +33,7 @@ - + @@ -106,7 +106,7 @@ 32 : : //! Non-const-ref access to state 33 : : //! \return Map of marked refinements 34 : : std::unordered_map<size_t, case_t>& data() { - 35 : 48780 : return marked_refinements; + 35 : 48162 : return marked_refinements; 36 : : } 37 : : 38 : : /** @@ -191,7 +191,7 @@ 117 : : */ 118 : : bool& get_state_changed() 119 : : { - 120 : 48780 : return state_changed; + 120 : 48162 : return state_changed; 121 : : } 122 : : }; 123 : : } diff --git a/Release/test_coverage/Inciter/AMR/master_element_store.hpp.func-sort-c.html b/Release/test_coverage/Inciter/AMR/master_element_store.hpp.func-sort-c.html index f5fbcc272428..bb9e5c7878a6 100644 --- a/Release/test_coverage/Inciter/AMR/master_element_store.hpp.func-sort-c.html +++ b/Release/test_coverage/Inciter/AMR/master_element_store.hpp.func-sort-c.html @@ -33,7 +33,7 @@ - + diff --git a/Release/test_coverage/Inciter/AMR/master_element_store.hpp.func.html b/Release/test_coverage/Inciter/AMR/master_element_store.hpp.func.html index cf2ba6fd7f62..5f9008aa37a2 100644 --- a/Release/test_coverage/Inciter/AMR/master_element_store.hpp.func.html +++ b/Release/test_coverage/Inciter/AMR/master_element_store.hpp.func.html @@ -33,7 +33,7 @@ - + diff --git a/Release/test_coverage/Inciter/AMR/master_element_store.hpp.gcov.html b/Release/test_coverage/Inciter/AMR/master_element_store.hpp.gcov.html index 5b7d3efe70b2..6c0f14142966 100644 --- a/Release/test_coverage/Inciter/AMR/master_element_store.hpp.gcov.html +++ b/Release/test_coverage/Inciter/AMR/master_element_store.hpp.gcov.html @@ -33,7 +33,7 @@ - + @@ -90,7 +90,7 @@ 16 : : public: 17 : : //! Non-const-ref access to state 18 : : std::map<size_t, Refinement_State>& data() { - 19 : 24390 : return master_elements; + 19 : 24081 : return master_elements; 20 : : } 21 : : 22 : : /** diff --git a/Release/test_coverage/Inciter/AMR/mesh_adapter.cpp.func-sort-c.html b/Release/test_coverage/Inciter/AMR/mesh_adapter.cpp.func-sort-c.html index 8c821ede3791..f8c6ba668f3c 100644 --- a/Release/test_coverage/Inciter/AMR/mesh_adapter.cpp.func-sort-c.html +++ b/Release/test_coverage/Inciter/AMR/mesh_adapter.cpp.func-sort-c.html @@ -33,7 +33,7 @@ - + diff --git a/Release/test_coverage/Inciter/AMR/mesh_adapter.cpp.func.html b/Release/test_coverage/Inciter/AMR/mesh_adapter.cpp.func.html index 728561b985b3..b88e43425ab7 100644 --- a/Release/test_coverage/Inciter/AMR/mesh_adapter.cpp.func.html +++ b/Release/test_coverage/Inciter/AMR/mesh_adapter.cpp.func.html @@ -33,7 +33,7 @@ - + diff --git a/Release/test_coverage/Inciter/AMR/mesh_adapter.cpp.gcov.html b/Release/test_coverage/Inciter/AMR/mesh_adapter.cpp.gcov.html index 9cbe537f81f4..9920e8f98fb5 100644 --- a/Release/test_coverage/Inciter/AMR/mesh_adapter.cpp.gcov.html +++ b/Release/test_coverage/Inciter/AMR/mesh_adapter.cpp.gcov.html @@ -33,7 +33,7 @@ - + diff --git a/Release/test_coverage/Inciter/AMR/mesh_adapter.hpp.func-sort-c.html b/Release/test_coverage/Inciter/AMR/mesh_adapter.hpp.func-sort-c.html index 0ea5049a5b28..0f8c131a1afa 100644 --- a/Release/test_coverage/Inciter/AMR/mesh_adapter.hpp.func-sort-c.html +++ b/Release/test_coverage/Inciter/AMR/mesh_adapter.hpp.func-sort-c.html @@ -33,7 +33,7 @@ - + @@ -77,7 +77,7 @@ - +
   1
-   2
-   3
-   4
-   5
-   6
-   7
-   8
-   9
-  10
-  11
-  12
-  13
-  14
-  15
-  16
-  17
-  18
-  19
-  20
-  21
-  22
-  23
-  24
-  25
-  26
-  27
-  28
-  29
-  30
-  31
-  32
-  33
-  34
-  35
-  36
-  37
-  38
-  39
-  40
-  41
-  42
-  43
-  44
-  45
-  46
-  47
-  48
-  49
-  50
-  51
-  52
-  53
-  54
-  55
-  56
-  57
-  58
-  59
-  60
-  61
-  62
-  63
-  64
-  65
-  66
-  67
-  68
-  69
-  70
-  71
-  72
-  73
-  74
-  75
-  76
-  77
-  78
-  79
-  80
-  81
-  82
-  83
-  84
-  85
-  86
-  87
-  88
-  89
-  90
-  91
-  92
-  93
-  94
-  95
-  96
-  97
-  98
-  99
- 100
- 101
- 102
- 103
- 104
- 105
- 106
- 107
- 108
- 109
- 110
- 111
- 112
- 113
- 114
- 115
- 116
- 117
- 118
- 119
- 120
- 121
- 122
- 123
- 124
- 125
- 126
- 127
- 128
- 129
- 130
- 131
- 132
- 133
- 134
- 135
- 136
- 137
- 138
- 139
- 140
- 141
- 142
- 143
- 144
- 145
- 146
- 147
- 148
- 149
- 150
- 151
- 152
- 153
- 154
- 155
- 156
- 157
- 158
- 159
- 160
- 161
- 162
- 163
- 164
- 165
- 166
- 167
- 168
- 169
- 170
- 171
- 172
- 173
- 174
- 175
- 176
- 177
- 178
- 179
- 180
- 181
- 182
- 183
- 184
- 185
- 186
- 187
- 188
- 189
- 190
- 191
- 192
- 193
- 194
- 195
- 196
- 197
- 198
- 199
- 200
- 201
- 202
- 203
- 204
- 205
- 206
- 207
- 208
- 209
- 210
- 211
- 212
- 213
- 214
- 215
- 216
- 217
- 218
- 219
- 220
- 221
- 222
- 223
- 224
- 225
- 226
- 227
- 228
- 229
- 230
- 231
- 232
- 233
- 234
- 235
- 236
- 237
- 238
- 239
- 240
- 241
- 242
- 243
- 244
- 245
- 246
- 247
- 248
- 249
- 250
- 251
- 252
- 253
- 254
- 255
- 256
- 257
- 258
- 259
- 260
- 261
- 262
- 263
- 264
- 265
- 266
- 267
- 268
- 269
- 270
- 271
- 272
- 273
- 274
- 275
- 276
- 277
- 278
- 279
- 280
- 281
- 282
- 283
- 284
- 285
- 286
- 287
- 288
- 289
- 290
- 291
- 292
- 293
- 294
- 295
- 296
- 297
- 298
- 299
- 300
- 301
- 302
- 303
- 304
- 305
- 306
- 307
- 308
- 309
- 310
- 311
- 312
- 313
- 314
- 315
- 316
- 317
- 318
- 319
- 320
- 321
- 322
- 323
- 324
- 325
- 326
- 327
- 328
- 329
- 330
- 331
- 332
- 333
- 334
- 335
- 336
- 337
- 338
- 339
- 340
- 341
- 342
- 343
- 344
- 345
- 346
- 347
- 348
- 349
- 350
- 351
- 352
- 353
- 354
- 355
- 356
- 357
- 358
- 359
- 360
- 361
- 362
- 363
- 364
- 365
- 366
- 367
- 368
- 369
- 370
- 371
- 372
- 373
- 374
- 375
- 376
- 377
- 378
- 379
- 380
- 381
- 382
- 383
- 384
- 385
- 386
- 387
- 388
- 389
- 390
- 391
- 392
- 393
- 394
- 395
- 396
- 397
- 398
- 399
- 400
- 401
- 402
- 403
- 404
- 405
- 406
- 407
- 408
- 409
- 410
- 411
- 412
- 413
- 414
- 415
- 416
- 417
- 418
- 419
- 420
- 421
- 422
- 423
- 424
- 425
- 426
- 427
- 428
- 429
- 430
- 431
- 432
- 433
- 434
- 435
- 436
- 437
- 438
- 439
- 440
- 441
- 442
- 443
- 444
- 445
- 446
- 447
- 448
- 449
- 450
- 451
- 452
- 453
- 454
- 455
- 456
- 457
- 458
- 459
- 460
- 461
- 462
- 463
- 464
- 465
- 466
- 467
- 468
- 469
- 470
- 471
- 472
- 473
- 474
- 475
- 476
- 477
- 478
- 479
- 480
- 481
- 482
- 483
- 484
- 485
- 486
- 487
- 488
- 489
- 490
- 491
- 492
- 493
- 494
- 495
- 496
- 497
- 498
- 499
- 500
- 501
- 502
- 503
- 504
- 505
- 506
- 507
- 508
- 509
- 510
- 511
- 512
- 513
- 514
- 515
- 516
- 517
- 518
- 519
- 520
- 521
- 522
- 523
- 524
- 525
- 526
- 527
- 528
- 529
- 530
- 531
- 532
- 533
- 534
- 535
- 536
- 537
- 538
- 539
- 540
- 541
- 542
- 543
- 544
- 545
- 546
- 547
- 548
- 549
- 550
- 551
- 552
- 553
- 554
- 555
- 556
- 557
- 558
- 559
- 560
- 561
- 562
- 563
- 564
- 565
- 566
- 567
- 568
- 569
- 570
- 571
- 572
- 573
- 574
- 575
- 576
- 577
- 578
- 579
- 580
- 581
- 582
- 583
- 584
- 585
- 586
- 587
- 588
- 589
- 590
- 591
- 592
- 593
- 594
- 595
- 596
- 597
- 598
- 599
- 600
- 601
- 602
- 603
- 604
- 605
- 606
- 607
- 608
- 609
- 610
- 611
- 612
- 613
- 614
- 615
- 616
- 617
- 618
- 619
- 620
- 621
- 622
- 623
- 624
- 625
- 626
- 627
- 628
- 629
- 630
- 631
- 632
- 633
- 634
- 635
- 636
- 637
- 638
- 639
- 640
- 641
- 642
- 643
- 644
- 645
- 646
- 647
- 648
- 649
- 650
- 651
- 652
- 653
- 654
- 655
- 656
- 657
- 658
- 659
- 660
- 661
- 662
- 663
- 664
- 665
- 666
- 667
- 668
- 669
- 670
- 671
- 672
- 673
- 674
- 675
- 676
- 677
- 678
- 679
- 680
- 681
- 682
- 683
- 684
- 685
- 686
- 687
- 688
- 689
- 690
- 691
- 692
- 693
- 694
- 695
- 696
- 697
- 698
- 699
- 700
- 701
- 702
- 703
- 704
- 705
- 706
- 707
- 708
- 709
- 710
- 711
- 712
- 713
- 714
- 715
- 716
- 717
- 718
- 719
- 720
- 721
- 722
- 723
- 724
- 725
- 726
- 727
- 728
- 729
- 730
- 731
- 732
- 733
- 734
- 735
- 736
- 737
- 738
- 739
- 740
- 741
- 742
- 743
- 744
- 745
- 746
- 747
- 748
- 749
- 750
- 751
- 752
- 753
- 754
- 755
- 756
- 757
- 758
- 759
- 760
- 761
- 762
- 763
- 764
- 765
- 766
- 767
- 768
- 769
- 770
- 771
- 772
- 773
- 774
- 775
- 776
- 777
- 778
- 779
- 780
- 781
- 782
- 783
- 784
- 785
- 786
- 787
- 788
- 789
- 790
- 791
- 792
- 793
- 794
- 795
- 796
- 797
- 798
- 799
- 800
- 801
- 802
- 803
- 804
- 805
- 806
- 807
- 808
- 809
- 810
- 811
- 812
- 813
- 814
- 815
- 816
- 817
- 818
- 819
- 820
- 821
- 822
- 823
- 824
- 825
- 826
- 827
- 828
- 829
- 830
- 831
- 832
- 833
- 834
- 835
- 836
- 837
- 838
- 839
- 840
- 841
- 842
- 843
- 844
- 845
- 846
- 847
- 848
- 849
- 850
- 851
- 852
- 853
- 854
- 855
- 856
- 857
- 858
- 859
- 860
- 861
- 862
- 863
- 864
- 865
- 866
- 867
- 868
- 869
- 870
- 871
- 872
- 873
- 874
- 875
- 876
- 877
- 878
- 879
- 880
- 881
- 882
- 883
- 884
- 885
- 886
- 887
- 888
- 889
- 890
- 891
- 892
- 893
- 894
- 895
- 896
- 897
- 898
- 899
- 900
- 901
- 902
- 903
- 904
- 905
- 906
- 907
- 908
- 909
- 910
- 911
- 912
- 913
- 914
- 915
- 916
- 917
- 918
- 919
- 920
- 921
- 922
- 923
- 924
- 925
- 926
- 927
- 928
- 929
- 930
- 931
- 932
- 933
- 934
- 935
- 936
- 937
- 938
- 939
- 940
- 941
- 942
- 943
- 944
- 945
- 946
- 947
- 948
- 949
- 950
- 951
- 952
- 953
- 954
- 955
- 956
- 957
- 958
- 959
- 960
- 961
- 962
- 963
- 964
- 965
- 966
- 967
- 968
- 969
- 970
- 971
- 972
- 973
- 974
- 975
- 976
- 977
- 978
- 979
- 980
- 981
- 982
- 983
- 984
- 985
- 986
- 987
- 988
- 989
- 990
- 991
- 992
- 993
- 994
- 995
- 996
- 997
- 998
- 999
-1000
-1001
-1002
-1003
-1004
-1005
-1006
-1007
-1008
-1009
-1010
-1011
-1012
-1013
-1014
-1015
-1016
-1017
-1018
-1019
-1020
-1021
-1022
-1023
-1024
-1025
-1026
-1027
-1028
-1029
-1030
-1031
-1032
-1033
-1034
-1035
-1036
-1037
-1038
-1039
-1040
-1041
-1042
-1043
-1044
-1045
-1046
-1047
-1048
-1049
-1050
-1051
-1052
-1053
-1054
-1055
-1056
-1057
-1058
-1059
-1060
-1061
-1062
-1063
-1064
-1065
-1066
-1067
-1068
-1069
-1070
-1071
-1072
-1073
-1074
-1075
-1076
-1077
-1078
-1079
-1080
-1081
-1082
-1083
-1084
-1085
-1086
-1087
-1088
-1089
-1090
-1091
-1092
-1093
-1094
-1095
-1096
-1097
-1098
-1099
-1100
-1101
-1102
-1103
-1104
-1105
-1106
-1107
-1108
-1109
-1110
-1111
-1112
-1113
-1114
-1115
-1116
-1117
-1118
-1119
-1120
-1121
-1122
-1123
-1124
-1125
-1126
-1127
-1128
-1129
-1130
-1131
-1132
-1133
-1134
-1135
-1136
-1137
-1138
-1139
-1140
-1141
-1142
-1143
-1144
-1145
-1146
-1147
-1148
-1149
-1150
-1151
-1152
-1153
-1154
-1155
-1156
-1157
-1158
-1159
-1160
-1161
-1162
-1163
-1164
-1165
-1166
-1167
-1168
-1169
-1170
-1171
-1172
-1173
-1174
-1175
-1176
-1177
-1178
-1179
-1180
-1181
-1182
-1183
-1184
-1185
-1186
-1187
-1188
-1189
-1190
-1191
-1192
-1193
-1194
-1195
-1196
-1197
-1198
-1199
-1200
-1201
-1202
-1203
-1204
-1205
-1206
-1207
-1208
-1209
-1210
-1211
-1212
-1213
-1214
-1215
-1216
-1217
-1218
-1219
-1220
-1221
-1222
-1223
-1224
-1225
-1226
-1227
-1228
-1229
-1230
-1231
-1232
-1233
-1234
-1235
-1236
-1237
-1238
-1239
-1240
-1241
-1242
-1243
-1244
-1245
-1246
-1247
-1248
-1249
-1250
-1251
-1252
-1253
-1254
-1255
-1256
-1257
-1258
-1259
-1260
-1261
-1262
-1263
-1264
-1265
-1266
-1267
-1268
-1269
-1270
-1271
-1272
-1273
-1274
-1275
-1276
-1277
-1278
-1279
-1280
-1281
-1282
-1283
-1284
-1285
-1286
-1287
-1288
-1289
-1290
-1291
-1292
-1293
-1294
-1295
-1296
-1297
-1298
-1299
-1300
-1301
-1302
-1303
-1304
-1305
-1306
-1307
-1308
-1309
-1310
-1311
-1312
-1313
-1314
-1315
-1316
-1317
-1318
-1319
-1320
-1321
-1322
-1323
-1324
-1325
-1326
-1327
-1328
-1329
-1330
-1331
-1332
-1333
-1334
-1335
-1336
-1337
-1338
-1339
-1340
-1341
-1342
-1343
-1344
-1345
-1346
-1347
-1348
-1349
-1350
-1351
-1352
-1353
-1354
-1355
-1356
-1357
-1358
-1359
-1360
-1361
-1362
-1363
-1364
-1365
-1366
-1367
-1368
-1369
-1370
-1371
-1372
-1373
-1374
-1375
-1376
-1377
-1378
-1379
-1380
-1381
-1382
-1383
-1384
-1385
-1386
-1387
-1388
-1389
-1390
-1391
-1392
-1393
-1394
-1395
-1396
-1397
-1398
-1399
-1400
-1401
-1402
-1403
-1404
-1405
-1406
-1407
-1408
-1409
-1410
-1411
-1412
-1413
-1414
-1415
-1416
-1417
-1418
-1419
-1420
-1421
-1422
-1423
-1424
-1425
-1426
-1427
-1428
-1429
-1430
-1431
-1432
-1433
-1434
-1435
-1436
-1437
-1438
-1439
-1440
-1441
-1442
-1443
-1444
-1445
-1446
-1447
-1448
-1449
-1450
-1451
-1452
-1453
-1454
-1455
-1456
-1457
-1458
-1459
-1460
-1461
-1462
-1463
-1464
-1465
-1466
-1467
-1468
-1469
-1470
-1471
-1472
-1473
-1474
-1475
-1476
-1477
-1478
-1479
-1480
-1481
-1482
-1483
-1484
-1485
-1486
-1487
-1488
-1489
-1490
-1491
-1492
-1493
-1494
-1495
-1496
-1497
-1498
-1499
-1500
-1501
-1502
-1503
-1504
-1505
-1506
-1507
-1508
-1509
-1510
-1511
-1512
-1513
-1514
-1515
-1516
-1517
-1518
-1519
-1520
-1521
-1522
-1523
-1524
-1525
-1526
-1527
-1528
-1529
-1530
-1531
-1532
-1533
-1534
-1535
-1536
-1537
-1538
-1539
-1540
-1541
-1542
-1543
-1544
-1545
-1546
-1547
-1548
-1549
-1550
-1551
-1552
-1553
-1554
-1555
-1556
-1557
-1558
-1559
-1560
-1561
-1562
-1563
-1564
-1565
-1566
-1567
-1568
-1569
-1570
-1571
-1572
-1573
-1574
-1575
-1576
-1577
-1578
-1579
-1580
-1581
-1582
-1583
-1584
-1585
-1586
-1587
-1588
-1589
-1590
-1591
-1592
-1593
-1594
-1595
-1596
-1597
-1598
-1599
-1600
-1601
-1602
-1603
-1604
-1605
-1606
-1607
-1608
-1609
-1610
-1611
-1612
-1613
// *****************************************************************************
+
  1
+  2
+  3
+  4
+  5
+  6
+  7
+  8
+  9
+ 10
+ 11
+ 12
+ 13
+ 14
+ 15
+ 16
+ 17
+ 18
+ 19
+ 20
+ 21
+ 22
+ 23
+ 24
+ 25
+ 26
+ 27
+ 28
+ 29
+ 30
+ 31
+ 32
+ 33
+ 34
+ 35
+ 36
+ 37
+ 38
+ 39
+ 40
+ 41
+ 42
+ 43
+ 44
+ 45
+ 46
+ 47
+ 48
+ 49
+ 50
+ 51
+ 52
+ 53
+ 54
+ 55
+ 56
+ 57
+ 58
+ 59
+ 60
+ 61
+ 62
+ 63
+ 64
+ 65
+ 66
+ 67
+ 68
+ 69
+ 70
+ 71
+ 72
+ 73
+ 74
+ 75
+ 76
+ 77
+ 78
+ 79
+ 80
+ 81
+ 82
+ 83
+ 84
+ 85
+ 86
+ 87
+ 88
+ 89
+ 90
+ 91
+ 92
+ 93
+ 94
+ 95
+ 96
+ 97
+ 98
+ 99
+100
+101
+102
+103
+104
+105
+106
+107
+108
+109
+110
+111
+112
+113
+114
+115
+116
+117
+118
+119
+120
+121
+122
+123
+124
+125
+126
+127
+128
+129
+130
+131
+132
+133
+134
+135
+136
+137
+138
+139
+140
+141
+142
+143
+144
+145
+146
+147
+148
+149
+150
+151
+152
+153
+154
+155
+156
+157
+158
+159
+160
+161
+162
+163
+164
+165
+166
+167
+168
+169
+170
+171
+172
+173
+174
+175
+176
+177
+178
+179
+180
+181
+182
+183
+184
+185
+186
+187
+188
+189
+190
+191
+192
+193
+194
+195
+196
+197
+198
+199
+200
+201
+202
+203
+204
+205
+206
+207
+208
+209
+210
+211
+212
+213
+214
+215
+216
+217
+218
+219
+220
+221
+222
+223
+224
+225
+226
+227
+228
+229
+230
+231
+232
+233
+234
+235
+236
+237
+238
+239
+240
+241
+242
+243
+244
+245
+246
+247
+248
+249
+250
+251
+252
+253
+254
+255
+256
+257
+258
+259
+260
+261
+262
+263
+264
+265
+266
+267
+268
+269
+270
+271
+272
+273
+274
+275
+276
+277
+278
+279
+280
+281
+282
+283
+284
+285
+286
+287
+288
+289
+290
+291
+292
+293
+294
+295
+296
+297
+298
+299
+300
+301
+302
+303
+304
+305
+306
+307
+308
+309
+310
+311
+312
+313
+314
+315
+316
+317
+318
+319
+320
+321
+322
+323
+324
+325
+326
+327
+328
+329
+330
+331
+332
+333
+334
+335
+336
+337
+338
+339
+340
+341
+342
+343
+344
+345
+346
+347
+348
+349
+350
+351
+352
+353
+354
+355
+356
+357
+358
+359
+360
+361
+362
+363
+364
+365
+366
+367
+368
+369
+370
+371
+372
+373
+374
+375
+376
+377
+378
+379
+380
+381
+382
+383
+384
+385
+386
+387
+388
+389
+390
+391
+392
+393
+394
+395
+396
+397
+398
+399
+400
+401
+402
+403
+404
+405
+406
+407
+408
+409
+410
+411
+412
+413
+414
+415
+416
+417
+418
+419
+420
+421
+422
+423
+424
+425
+426
+427
+428
+429
+430
+431
+432
+433
+434
+435
+436
+437
+438
+439
+440
+441
+442
+443
+444
+445
+446
+447
+448
+449
+450
+451
+452
+453
+454
+455
+456
+457
+458
+459
+460
+461
+462
+463
+464
+465
+466
+467
+468
+469
+470
+471
+472
+473
+474
+475
+476
+477
+478
+479
+480
+481
+482
+483
+484
+485
+486
+487
+488
+489
+490
+491
+492
+493
+494
+495
+496
+497
+498
+499
+500
+501
+502
+503
+504
+505
+506
+507
+508
+509
+510
+511
+512
+513
+514
+515
+516
+517
+518
+519
+520
+521
+522
+523
+524
+525
+526
+527
+528
+529
+530
+531
+532
+533
+534
+535
+536
+537
+538
+539
+540
+541
+542
+543
+544
+545
+546
+547
+548
+549
+550
+551
+552
+553
+554
+555
+556
+557
+558
+559
+560
+561
+562
+563
+564
+565
+566
+567
+568
+569
+570
+571
+572
+573
+574
+575
+576
+577
+578
+579
+580
+581
+582
+583
+584
+585
+586
+587
+588
+589
+590
+591
+592
+593
+594
+595
+596
+597
+598
+599
+600
+601
+602
+603
+604
+605
+606
+607
+608
+609
+610
+611
+612
+613
+614
+615
+616
+617
+618
+619
+620
+621
+622
+623
+624
+625
+626
+627
+628
+629
+630
+631
+632
+633
+634
+635
+636
+637
+638
+639
+640
+641
+642
+643
+644
+645
+646
+647
+648
+649
+650
+651
+652
+653
+654
+655
+656
+657
+658
+659
+660
+661
+662
+663
+664
+665
+666
+667
+668
+669
+670
+671
+672
+673
+674
+675
+676
+677
+678
+679
+680
+681
+682
+683
+684
+685
+686
+687
+688
+689
+690
+691
+692
+693
+694
+695
+696
+697
+698
+699
+700
+701
+702
+703
+704
+705
+706
+707
+708
+709
+710
+711
+712
+713
+714
+715
+716
+717
+718
+719
+720
+721
+722
// *****************************************************************************
 /*!
-  \file      src/PDE/CompFlow/CGCompFlow.hpp
+  \file      src/PDE/DGPDE.hpp
   \copyright 2012-2015 J. Bakosi,
              2016-2018 Los Alamos National Security, LLC.,
              2019-2021 Triad National Security, LLC.
              All rights reserved. See the LICENSE file for details.
-  \brief     Compressible single-material flow using continuous Galerkin
-  \details   This file implements the physics operators governing compressible
-    single-material flow using continuous Galerkin discretization.
-*/
-// *****************************************************************************
-#ifndef CGCompFlow_h
-#define CGCompFlow_h
-
-#include <cmath>
-#include <algorithm>
-#include <unordered_set>
-#include <unordered_map>
-
-#include "DerivedData.hpp"
-#include "Exception.hpp"
-#include "Vector.hpp"
-#include "Mesh/Around.hpp"
-#include "Reconstruction.hpp"
-#include "Problem/FieldOutput.hpp"
-#include "Problem/BoxInitialization.hpp"
-#include "Riemann/Rusanov.hpp"
-#include "NodeBC.hpp"
-#include "EoS/EOS.hpp"
-#include "History.hpp"
-#include "Table.hpp"
-
-namespace inciter {
-
-extern ctr::InputDeck g_inputdeck;
-
-namespace cg {
-
-//! \brief CompFlow used polymorphically with tk::CGPDE
-//! \details The template arguments specify policies and are used to configure
-//!   the behavior of the class. The policies are:
-//!   - Physics - physics configuration, see PDE/CompFlow/Physics.h
-//!   - Problem - problem configuration, see PDE/CompFlow/Problems.h
-//! \note The default physics is Euler, set in inciter::deck::check_compflow()
-template< class Physics, class Problem >
-class CompFlow {
-
-  private:
-    using ncomp_t = tk::ncomp_t;
-    using eq = tag::compflow;
-    using real = tk::real;
-
-    static constexpr std::size_t m_ncomp = 5;
-    static constexpr real muscl_eps = 1.0e-9;
-    static constexpr real muscl_const = 1.0/3.0;
-    static constexpr real muscl_m1 = 1.0 - muscl_const;
-    static constexpr real muscl_p1 = 1.0 + muscl_const;
-
-  public:
-    //! \brief Constructor
-    explicit CompFlow() :
-      m_physics(),
-      m_problem(),
-      m_stagCnf(),
-      m_fr(),
-      m_fp(),
-      m_fu()
-    {
-      Assert( g_inputdeck.get< tag::ncomp >() == m_ncomp,
-       "Number of CompFlow PDE components must be " + std::to_string(m_ncomp) );
-
-      // EoS initialization
-      const auto& matprop =
-        g_inputdeck.get< tag::material >();
-      const auto& matidxmap =
-        g_inputdeck.get< tag::matidxmap >();
-      auto mateos = matprop[matidxmap.get< tag::eosidx >()[0]].get<tag::eos>();
-      m_mat_blk.emplace_back( mateos, EqType::compflow, 0 );
-
-      // Boundary condition configurations
-      for (const auto& bci : g_inputdeck.get< tag::bc >()) {
-        // store stag-point coordinates
-        auto& spt = std::get< 0 >(m_stagCnf);
-        spt.insert( spt.end(), bci.get< tag::stag_point >().begin(),
-          bci.get< tag::stag_point >().end() );
-        // store stag-radius
-        std::get< 1 >(m_stagCnf).push_back( bci.get< tag::radius >() );
-        // freestream quantities
-        m_fr = bci.get< tag::density >();
-        m_fp = bci.get< tag::pressure >();
-        m_fu = bci.get< tag::velocity >();
-      }
-    }
-
-    //! Determine nodes that lie inside the user-defined IC box and mesh blocks
-    //! \param[in] coord Mesh node coordinates
-    //! \param[in] inpoel Element node connectivity
-    //! \param[in,out] inbox List of nodes at which box user ICs are set for
-    //!    each IC box
-    //! \param[in] elemblkid Element ids associated with mesh block ids where
-    //!   user ICs are set
-    //! \param[in,out] nodeblkid Node ids associated to mesh block ids, where
-    //!   user ICs are set
-    //! \param[in,out] nuserblk number of mesh blocks where user ICs are set
-    void IcBoxNodes( const tk::UnsMesh::Coords& coord,
-      const std::vector< std::size_t >& inpoel,
-      const std::unordered_map< std::size_t, std::set< std::size_t > >& elemblkid,
-      std::vector< std::unordered_set< std::size_t > >& inbox,
-      std::unordered_map< std::size_t, std::set< std::size_t > >& nodeblkid,
-      std::size_t& nuserblk ) const
-    {
-      const auto& x = coord[0];
-      const auto& y = coord[1];
-      const auto& z = coord[2];
-
-      // Detect if user has configured IC boxes
-      const auto& icbox = g_inputdeck.get<tag::ic, tag::box>();
-      if (!icbox.empty()) {
-        std::size_t bcnt = 0;
-        for (const auto& b : icbox) {   // for all boxes for this eq
-          inbox.emplace_back();
-          std::vector< tk::real > box
-            { b.template get< tag::xmin >(), b.template get< tag::xmax >(),
-              b.template get< tag::ymin >(), b.template get< tag::ymax >(),
-              b.template get< tag::zmin >(), b.template get< tag::zmax >() };
+  \brief     Partial differential equation base for discontinuous Galerkin PDEs
+  \details   This file defines a generic partial differential equation (PDE)
+    class for PDEs that use discontinuous Galerkin spatial discretization.
+    The class uses runtime polymorphism without client-side inheritance:
+    inheritance is confined to the internals of the class, invisible to
+    client-code. The class exclusively deals with ownership enabling client-side
+    value semantics. Credit goes to Sean Parent at Adobe:
+    https://github.com/sean-parent/sean-parent.github.com/wiki/
+    Papers-and-Presentations.
+*/
+// *****************************************************************************
+#ifndef DGPDE_h
+#define DGPDE_h
+
+#include <array>
+#include <string>
+#include <vector>
+#include <memory>
+#include <unordered_set>
+#include <functional>
+
+#include "Types.hpp"
+#include "Fields.hpp"
+#include "FaceData.hpp"
+#include "UnsMesh.hpp"
+#include "Inciter/InputDeck/InputDeck.hpp"
+#include "FunctionPrototypes.hpp"
+#include "History.hpp"
+
+namespace inciter {
+
+extern ctr::InputDeck g_inputdeck;
+
+using ncomp_t = tk::ncomp_t;
+using BCStateFn =
+  std::vector< std::pair< std::vector< std::size_t >, tk::StateFn > >;
+
+//! Extract BC configuration ignoring if BC not specified
+//! \note A more preferable way of catching errors such as this function
+//!   hides is during parsing, so that we don't even get here if BCs are
+//!   not correctly specified. For now we simply ignore if BCs are not
+//!   specified by allowing empty BC vectors from the user input.
+struct ConfigBC {
+  BCStateFn& state;    //!< BC state config: sidesets + statefn
+  const std::vector< tk::StateFn >& fn;    //!< BC state functions
+  std::size_t c;       //!< Counts BC types configured
+  //! Constructor
+  ConfigBC( BCStateFn& s,
+            const std::vector< tk::StateFn >& f ) :
+    state(s), fn(f), c(0) {}
+  //! Function to call for each BC type
+  template< typename U > void operator()( brigand::type_<U> ) {
+    std::vector< std::size_t > cfg, v;
+    // collect sidesets across all meshes
+    for (const auto& ibc : g_inputdeck.get< tag::bc >()) {
+      v.insert(v.end(), ibc.get< U >().begin(), ibc.get< U >().end());
+    }
+    if (v.size() > 0) cfg = v;<--- Variable 'cfg' is assigned a value that is never used.
+    Assert( fn.size() > c, "StateFn missing for BC type" );
+    state.push_back( { cfg, fn[c++] } );
+  }
+};
+
+//! State function for invalid/un-configured boundary conditions
+[[noreturn]] tk::StateFn::result_type
+invalidBC( ncomp_t, const std::vector< EOS >&,
+           const std::vector< tk::real >&, tk::real, tk::real, tk::real,
+           tk::real, const std::array< tk::real, 3> & );
+
+//! \brief Partial differential equation base for discontinuous Galerkin PDEs
+//! \details This class uses runtime polymorphism without client-side
+//!   inheritance: inheritance is confined to the internals of the this class,
+//!   invisible to client-code. The class exclusively deals with ownership
+//!   enabling client-side value semantics. Credit goes to Sean Parent at Adobe:
+//!   https://github.com/sean-parent/sean-parent.github.com/wiki/
+//!   Papers-and-Presentations. For example client code that models a DGPDE,
+//!   see inciter::CompFlow.
+class DGPDE {
+
+  private:
+    using ncomp_t = tk::ncomp_t;
+
+  public:
+    //! Default constructor taking no arguments for Charm++
+    explicit DGPDE() = default;
+
+    //! \brief Constructor taking an object modeling Concept.
+    //! \details The object of class T comes pre-constructed.
+    //! \param[in] x Instantiated object of type T given by the template
+    //!   argument.
+    template< typename T > explicit DGPDE( T x ) :
+      self( std::make_unique< Model<T> >( std::move(x) ) ) {}
+
+    //! \brief Constructor taking a function pointer to a constructor of an
+    //!   object modeling Concept.
+    //! \details Passing std::function allows late execution of the constructor,
+    //!   i.e., as late as inside this class' constructor, and thus usage from
+    //!   a factory. Note that there are at least two different ways of using
+    //!   this constructor:
+    //!   - Bind T's constructor arguments and place it in std::function<T()>
+    //!   and passing no arguments as args.... This case then instantiates the
+    //!   model via its constructor and stores it in here.
+    //!   - Bind a single placeholder argument to T's constructor and pass it in
+    //!   as host's args..., which then forwards it to model's constructor. This
+    //!   allows late binding, i.e., binding the argument only here.
+    //! \see See also the wrapper tk::recordModel() which does the former and
+    //!   tk::recordModelLate() which does the latter, both defined in
+    //!   src/Base/Factory.h.
+    //! \param[in] x Function pointer to a constructor of an object modeling
+    //!    Concept.
+    //! \param[in] args Zero or more constructor arguments
+    template< typename T, typename...Args >
+    explicit DGPDE( std::function<T(Args...)> x, Args&&... args ) :
+      self( std::make_unique< Model<T> >(
+              std::move( x( std::forward<Args>(args)... ) ) ) ) {}
+
+    //! Public interface to find number of primitive quantities for the diff eq
+    std::size_t nprim() const
+    { return self->nprim(); }
 
-          // Determine orientation of box
-          std::array< tk::real, 3 > b_orientn{{
-            b.template get< tag::orientation >()[0],
-            b.template get< tag::orientation >()[1],
-            b.template get< tag::orientation >()[2] }};
-          std::array< tk::real, 3 > b_centroid{{ 0.5*(box[0]+box[1]),
-            0.5*(box[2]+box[3]), 0.5*(box[4]+box[5]) }};
+    //! Public interface to find number of materials for the diff eq
+    std::size_t nmat() const
+    { return self->nmat(); }
+
+    //! Public interface to find Dofs for each equation in pde system
+    void numEquationDofs(std::vector< std::size_t >& numEqDof) const
+    { return self->numEquationDofs(numEqDof); }
 
-          const auto eps = std::numeric_limits< tk::real >::epsilon();
-          // Determine which nodes lie in the IC box
-          if ( std::any_of( begin(box), end(box), [=](auto p)
-                            { return abs(p) > eps; } ) )
-          {
-            // Transform box to reference space
-            std::array< tk::real, 3 > b_min{{box[0], box[2], box[4]}};
-            std::array< tk::real, 3 > b_max{{box[1], box[3], box[5]}};
-            tk::movePoint(b_centroid, b_min);
-            tk::movePoint(b_centroid, b_max);
-
-            for (ncomp_t i=0; i<x.size(); ++i) {
-              std::array< tk::real, 3 > node{{ x[i], y[i], z[i] }};
-              // Transform node to reference space of box
-              tk::movePoint(b_centroid, node);
-              tk::rotatePoint({{-b_orientn[0], -b_orientn[1], -b_orientn[2]}},
-                node);
-              if ( node[0]>b_min[0] && node[0]<b_max[0] &&
-                node[1]>b_min[1] && node[1]<b_max[1] &&
-                node[2]>b_min[2] && node[2]<b_max[2] )
-              {
-                inbox[bcnt].insert( i );
-              }
-            }
-          }
-          ++bcnt;
-        }
-      }
-
-      // size IC mesh blocks volume vector
-      const auto& mblks = g_inputdeck.get< tag::ic, tag::meshblock >();
-      // if mesh blocks have been specified for this system
-      if (!mblks.empty()) {
-        std::size_t idMax(0);
-        for (const auto& imb : mblks) {
-          idMax = std::max(idMax, imb.get< tag::blockid >());
-        }
-        // size is idMax+1 since block ids are usually 1-based
-        nuserblk = nuserblk+idMax+1;
-      }
+    //! Public interface to find how 'stiff equations', which are the inverse
+    //! deformation equations because of plasticity
+    std::size_t nstiffeq() const
+    { return self->nstiffeq(); }
+
+    //! Public interface to find how 'nonstiff equations', which are the inverse
+    //! deformation equations because of plasticity
+    std::size_t nnonstiffeq() const
+    { return self->nnonstiffeq(); }
+
+    //! Public function to locate the stiff equations
+    void setStiffEqIdx( std::vector< std::size_t >& stiffEqIdx ) const
+    { return self->setStiffEqIdx( stiffEqIdx ); }
+
+    //! Public function to locate the nonstiff equations
+    void setNonStiffEqIdx( std::vector< std::size_t >& nonStiffEqIdx ) const
+    { return self->setNonStiffEqIdx( nonStiffEqIdx ); }
+
+    //! Public interface to determine elements that lie inside the IC box
+    void IcBoxElems( const tk::Fields& geoElem,
+      std::size_t nielem,
+      std::vector< std::unordered_set< std::size_t > >& inbox ) const
+    { self->IcBoxElems( geoElem, nielem, inbox ); }
+
+    //! Public interface to setting the initial conditions for the diff eq
+    void initialize(
+      const tk::Fields& L,
+      const std::vector< std::size_t >& inpoel,
+      const tk::UnsMesh::Coords& coord,
+      const std::vector< std::unordered_set< std::size_t > >& inbox,
+      const std::unordered_map< std::size_t, std::set< std::size_t > >&
+        elemblkid,
+      tk::Fields& unk,
+      tk::real t,
+      const std::size_t nielem ) const
+    { self->initialize( L, inpoel, coord, inbox, elemblkid, unk, t, nielem ); }
+
+    //! Public interface for saving initial densities of materials
+    void setRho0mat( std::vector< tk::real >& rho0mat) const
+    { return self->setRho0mat( rho0mat ); }
 
-      // determine node set for IC mesh blocks
-      for (const auto& [blid, elset] : elemblkid) {
-        if (!elset.empty()) {
-          auto& ndset = nodeblkid[blid];
-          for (auto ie : elset) {
-            for (std::size_t i=0; i<4; ++i) ndset.insert(inpoel[4*ie+i]);
-          }
-        }
-      }
-    }
+    //! Public interface for computing density constraint
+    void computeDensityConstr( std::size_t nelem,
+                               tk::Fields& unk,
+                               std::vector< tk::real >& rho0mat,
+                               std::vector< tk::real >& densityConstr) const
+    { self->computeDensityConstr( nelem, unk, rho0mat, densityConstr); }
+
+    //! Public interface to computing the left-hand side matrix for the diff eq
+    void lhs( const tk::Fields& geoElem, tk::Fields& l ) const
+    { self->lhs( geoElem, l ); }
 
-    //! Initalize the compressible flow equations, prepare for time integration
-    //! \param[in] coord Mesh node coordinates
-    //! \param[in,out] unk Array of unknowns
-    //! \param[in] t Physical time
-    //! \param[in] V Discrete volume of user-defined IC box
-    //! \param[in] inbox List of nodes at which box user ICs are set (for each
-    //!    box IC)
-    //! \param[in] nodeblkid Node ids associated to mesh block ids, where
-    //!   user ICs are set
-    //! \param[in] blkvols Vector of discrete volumes of each block where user
-    //!   ICs are set
-    void initialize(
-      const std::array< std::vector< real >, 3 >& coord,
-      tk::Fields& unk,
-      real t,
-      real V,
-      const std::vector< std::unordered_set< std::size_t > >& inbox,
-      const std::vector< tk::real >& blkvols,
-      const std::unordered_map< std::size_t, std::set< std::size_t > >&
-        nodeblkid ) const
-    {
-      Assert( coord[0].size() == unk.nunk(), "Size mismatch" );
-
-      const auto& x = coord[0];
-      const auto& y = coord[1];
-      const auto& z = coord[2];
-
-      const auto& ic = g_inputdeck.get< tag::ic >();
-      const auto& icbox = ic.get< tag::box >();
-      const auto& mblks = ic.get< tag::meshblock >();
-
-      const auto eps = 1000.0 * std::numeric_limits< tk::real >::epsilon();
-
-      tk::real bgpre = ic.get< tag::pressure >();
-
-      auto c_v = getmatprop< tag::cv >();
+    //! Public interface to updating the interface cells for the diff eq
+    void updateInterfaceCells( tk::Fields& unk,
+                               std::size_t nielem,
+                               std::vector< std::size_t >& ndofel ) const
+    { self->updateInterfaceCells( unk, nielem, ndofel ); }
+
+    //! Public interface to updating the primitives for the diff eq
+    void updatePrimitives( const tk::Fields& unk,
+                           const tk::Fields& L,
+                           const tk::Fields& geoElem,
+                           tk::Fields& prim,
+                           std::size_t nielem ) const
+    { self->updatePrimitives( unk, L, geoElem, prim, nielem ); }
+
+    //! Public interface to cleaning up trace materials for the diff eq
+    void cleanTraceMaterial( tk::real t,
+                             const tk::Fields& geoElem,
+                             tk::Fields& unk,
+                             tk::Fields& prim,
+                             std::size_t nielem ) const
+    { self->cleanTraceMaterial( t, geoElem, unk, prim, nielem ); }
+
+    //! Public interface to reconstructing the second-order solution
+    void reconstruct( tk::real t,
+                      const tk::Fields& geoFace,
+                      const tk::Fields& geoElem,
+                      const inciter::FaceData& fd,
+                      const std::map< std::size_t, std::vector< std::size_t > >&
+                        esup,
+                      const std::vector< std::size_t >& inpoel,
+                      const tk::UnsMesh::Coords& coord,
+                      tk::Fields& U,
+                      tk::Fields& P ) const
+    {
+      self->reconstruct( t, geoFace, geoElem, fd, esup, inpoel, coord, U, P );
+    }
 
-      // Set initial and boundary conditions using problem policy
-      for (ncomp_t i=0; i<x.size(); ++i) {
-        auto s = Problem::initialize( m_ncomp, m_mat_blk, x[i], y[i], z[i], t );
-
-        // initialize the user-defined box IC
-        if (!icbox.empty()) {
-          std::size_t bcnt = 0;
-          for (const auto& b : icbox) { // for all boxes
-            if (inbox.size() > bcnt && inbox[bcnt].find(i) != inbox[bcnt].end())
-            {
-              std::vector< tk::real > box
-              { b.template get< tag::xmin >(), b.template get< tag::xmax >(),
-                b.template get< tag::ymin >(), b.template get< tag::ymax >(),
-                b.template get< tag::zmin >(), b.template get< tag::zmax >() };
-              auto V_ex = (box[1]-box[0]) * (box[3]-box[2]) * (box[5]-box[4]);
-              if (V_ex < eps) V = 1.0;
-              initializeBox<ctr::boxList>( m_mat_blk, V_ex/V,
-                V_ex, t, b, bgpre, c_v, s );
-            }
-            ++bcnt;
-          }
-        }
-
-        // initialize user-defined mesh block ICs
-        for (const auto& b : mblks) { // for all blocks
-          auto blid = b.get< tag::blockid >();
-          auto V_ex = b.get< tag::volume >();
-          if (blid >= blkvols.size()) Throw("Block volume not found");
-          if (nodeblkid.find(blid) != nodeblkid.end()) {
-            const auto& ndset = tk::cref_find(nodeblkid, blid);
-            if (ndset.find(i) != ndset.end()) {
-              initializeBox<ctr::meshblockList>( m_mat_blk,
-                V_ex/blkvols[blid], V_ex, t, b, bgpre, c_v, s );
-            }
-          }
-        }
-
-        unk(i,0) = s[0]; // rho
-        if (stagPoint(x[i],y[i],z[i])) {
-          unk(i,1) = unk(i,2) = unk(i,3) = 0.0;
-        } else {
-          unk(i,1) = s[1]; // rho * u
-          unk(i,2) = s[2]; // rho * v
-          unk(i,3) = s[3]; // rho * w
-        }
-        unk(i,4) = s[4]; // rho * e, e: total = kinetic + internal
-      }
-    }
-
-    //! Query the fluid velocity
-    //! \param[in] u Solution vector of conserved variables
-    //! \param[in,out] v Velocity components
-    void velocity( const tk::Fields& u, tk::UnsMesh::Coords& v ) const {
-      for (std::size_t j=0; j<3; ++j) {
-        // extract momentum
-        v[j] = u.extract_comp( 1+j );
-        Assert( v[j].size() == u.nunk(), "Size mismatch" );
-        // divide by density
-        for (std::size_t i=0; i<u.nunk(); ++i) v[j][i] /= u(i,0);
-      }
-    }
-
-    //! Query the sound speed
-    //! \param[in] U Solution vector of conserved variables
-    //! \param[in,out] s Speed of sound in mesh nodes
-    void soundspeed( const tk::Fields& U, std::vector< tk::real >& s ) const {
-      s.resize( U.nunk() );
-      for (std::size_t i=0; i<U.nunk(); ++i) {
-        auto r  = U(i,0);
-        auto ru = U(i,1);
-        auto rv = U(i,2);
-        auto rw = U(i,3);
-        auto re = U(i,4);
-        auto p = m_mat_blk[0].compute< EOS::pressure >(r, ru/r, rv/r, rw/r, re);
-        s[i] = m_mat_blk[0].compute< EOS::soundspeed >( r, p );
-      }
-    }
-
-    //! Return analytic solution (if defined by Problem) at xi, yi, zi, t
-    //! \param[in] xi X-coordinate
-    //! \param[in] yi Y-coordinate
-    //! \param[in] zi Z-coordinate
-    //! \param[in] t Physical time
-    //! \return Vector of analytic solution at given location and time
-    std::vector< real >
-    analyticSolution( real xi, real yi, real zi, real t ) const
-    { return Problem::analyticSolution( m_ncomp, m_mat_blk, xi, yi, zi, t ); }
-
-    //! Return analytic solution for conserved variables
-    //! \param[in] xi X-coordinate at which to evaluate the analytic solution
-    //! \param[in] yi Y-coordinate at which to evaluate the analytic solution
-    //! \param[in] zi Z-coordinate at which to evaluate the analytic solution
-    //! \param[in] t Physical time at which to evaluate the analytic solution
-    //! \return Vector of analytic solution at given location and time
-    std::vector< tk::real >
-    solution( tk::real xi, tk::real yi, tk::real zi, tk::real t ) const
-    { return Problem::initialize( m_ncomp, m_mat_blk, xi, yi, zi, t ); }
-
-    //! \brief Compute nodal gradients of primitive variables for ALECG along
-    //!   chare-boundary
-    //! \param[in] coord Mesh node coordinates
-    //! \param[in] inpoel Mesh element connectivity
-    //! \param[in] bndel List of elements contributing to chare-boundary nodes
-    //! \param[in] gid Local->global node id map
-    //! \param[in] bid Local chare-boundary node ids (value) associated to
-    //!    global node ids (key)
-    //! \param[in] U Solution vector at recent time step
-    //! \param[in,out] G Nodal gradients of primitive variables
-    //! \details This function only computes local contributions to gradients
-    //!   at chare-boundary nodes. Internal node gradients are calculated as
-    //!   required, and do not need to be stored.
-    void chBndGrad( const std::array< std::vector< real >, 3 >& coord,
-                    const std::vector< std::size_t >& inpoel,
-                    const std::vector< std::size_t >& bndel,
-                    const std::vector< std::size_t >& gid,
-                    const std::unordered_map< std::size_t, std::size_t >& bid,
-                    const tk::Fields& U,
-                    tk::Fields& G ) const
-    {
-      Assert( U.nunk() == coord[0].size(), "Number of unknowns in solution "
-              "vector at recent time step incorrect" );
-
-      // compute gradients of primitive variables in points
-      G.fill( 0.0 );
-
-      // access node cooordinates
-      const auto& x = coord[0];
-      const auto& y = coord[1];
-      const auto& z = coord[2];
+    //! Public interface to limiting the second-order solution
+    void limit( tk::real t,
+                const tk::Fields& geoFace,
+                const tk::Fields& geoElem,
+                const inciter::FaceData& fd,
+                const std::map< std::size_t, std::vector< std::size_t > >& esup,
+                const std::vector< std::size_t >& inpoel,
+                const tk::UnsMesh::Coords& coord,
+                const std::vector< std::size_t >& ndofel,
+                const std::vector< std::size_t >& gid,
+                const std::unordered_map< std::size_t, std::size_t >& bid,
+                const std::vector< std::vector<tk::real> >& uNodalExtrm,
+                const std::vector< std::vector<tk::real> >& pNodalExtrm,
+                const std::vector< std::vector<tk::real> >& mtInv,
+                tk::Fields& U,
+                tk::Fields& P,
+                std::vector< std::size_t >& shockmarker ) const
+    {
+      self->limit( t, geoFace, geoElem, fd, esup, inpoel, coord, ndofel, gid,
+                   bid, uNodalExtrm, pNodalExtrm, mtInv, U, P, shockmarker );
+    }
+
+    //! Public interface to update the conservative variable solution
+    void CPL( const tk::Fields& prim,
+              const tk::Fields& geoElem,
+              const std::vector< std::size_t >& inpoel,
+              const tk::UnsMesh::Coords& coord,
+              tk::Fields& unk,
+              std::size_t nielem ) const
+    {
+      self->CPL( prim, geoElem, inpoel, coord, unk, nielem );
+    }
+
+    //! Public interface to getting the cell-averaged deformation gradients
+    std::array< std::vector< tk::real >, 9 > cellAvgDeformGrad(
+      const tk::Fields& U,
+      std::size_t nielem ) const
+    {
+      return self->cellAvgDeformGrad( U, nielem );
+    }
+
+    //! Public interface to computing the P1 right-hand side vector
+    void rhs( tk::real t,
+              const tk::Fields& geoFace,
+              const tk::Fields& geoElem,
+              const inciter::FaceData& fd,
+              const std::vector< std::size_t >& inpoel,
+              const std::vector< std::unordered_set< std::size_t > >& boxelems,
+              const tk::UnsMesh::Coords& coord,
+              const tk::Fields& U,
+              const tk::Fields& P,
+              const std::vector< std::size_t >& ndofel,
+              const std::vector< tk::real >& rho0mat,
+              const tk::real dt,
+              tk::Fields& R ) const
+    {
+      self->rhs( t, geoFace, geoElem, fd, inpoel, boxelems, coord, U, P,
+                 ndofel, rho0mat, dt, R );
+    }
+
+    //! Evaluate the adaptive indicator and mark the ndof for each element
+    void eval_ndof( std::size_t nunk,
+                    const tk::UnsMesh::Coords& coord,
+                    const std::vector< std::size_t >& inpoel,
+                    const inciter::FaceData& fd,
+                    const tk::Fields& unk,
+                    const tk::Fields& prim,
+                    inciter::ctr::PrefIndicatorType indicator,
+                    std::size_t ndof,
+                    std::size_t ndofmax,
+                    tk::real tolref,
+                    std::vector< std::size_t >& ndofel ) const
+    {
+      self->eval_ndof( nunk, coord, inpoel, fd, unk, prim, indicator, ndof,
+        ndofmax, tolref, ndofel );
+    }
+
+    //! Public interface for computing the minimum time step size
+    tk::real dt( const std::array< std::vector< tk::real >, 3 >& coord,
+                 const std::vector< std::size_t >& inpoel,
+                 const inciter::FaceData& fd,
+                 const tk::Fields& geoFace,
+                 const tk::Fields& geoElem,
+                 const std::vector< std::size_t >& ndofel,
+                 const tk::Fields& U,
+                 const tk::Fields& P,
+                 const std::size_t nielem ) const
+    { return self->dt( coord, inpoel, fd, geoFace, geoElem, ndofel, U,
+                       P, nielem ); }
+
+    //! Public interface for computing stiff terms for an element
+    void stiff_rhs( std::size_t e,
+                    const tk::Fields& geoElem,
+                    const std::vector< std::size_t >& inpoel,
+                    const tk::UnsMesh::Coords& coord,
+                    const tk::Fields& U,
+                    const tk::Fields& P,
+                    const std::vector< std::size_t >& ndofel,
+                    tk::Fields& R ) const
+    { return self->stiff_rhs( e, geoElem, inpoel, coord, U, P, ndofel, R); }
+
+    //! Public interface to returning maps of output var functions
+    std::map< std::string, tk::GetVarFn > OutVarFn() const
+    { return self->OutVarFn(); }
+
+    //! Public interface to returning analytic field output labels
+    std::vector< std::string > analyticFieldNames() const
+    { return self->analyticFieldNames(); }
+
+    //! Public interface to returning time history field output labels
+    std::vector< std::string > histNames() const { return self->histNames(); }
+
+    //! Public interface to returning variable names
+    std::vector< std::string > names() const { return self->names(); }
+
+    //! Public interface to returning surface field output
+    std::vector< std::vector< tk::real > >
+    surfOutput( const std::map< int, std::vector< std::size_t > >& bnd,
+                tk::Fields& U ) const
+    { return self->surfOutput( bnd, U ); }
+
+    //! Public interface to return point history output
+    std::vector< std::vector< tk::real > >
+    histOutput( const std::vector< HistData >& h,
+      const std::vector< std::size_t >& inpoel,
+      const tk::UnsMesh::Coords& coord,
+      const tk::Fields& U,
+      const tk::Fields& P ) const
+    { return self->histOutput( h, inpoel, coord, U, P ); }
 
-      for (auto e : bndel) {  // elements contributing to chare boundary nodes
-        // access node IDs
-        std::size_t N[4] =
-          { inpoel[e*4+0], inpoel[e*4+1], inpoel[e*4+2], inpoel[e*4+3] };
-        // compute element Jacobi determinant, J = 6V
-        real bax = x[N[1]]-x[N[0]];
-        real bay = y[N[1]]-y[N[0]];
-        real baz = z[N[1]]-z[N[0]];
-        real cax = x[N[2]]-x[N[0]];
-        real cay = y[N[2]]-y[N[0]];
-        real caz = z[N[2]]-z[N[0]];
-        real dax = x[N[3]]-x[N[0]];
-        real day = y[N[3]]-y[N[0]];
-        real daz = z[N[3]]-z[N[0]];
-        auto J = tk::triple( bax, bay, baz, cax, cay, caz, dax, day, daz );
-        ErrChk( J > 0, "Element Jacobian non-positive" );
-        auto J24 = J/24.0;
-        // shape function derivatives, nnode*ndim [4][3]
-        real g[4][3];
-        tk::crossdiv( cax, cay, caz, dax, day, daz, J,
-                      g[1][0], g[1][1], g[1][2] );
-        tk::crossdiv( dax, day, daz, bax, bay, baz, J,
-                      g[2][0], g[2][1], g[2][2] );
-        tk::crossdiv( bax, bay, baz, cax, cay, caz, J,
-                      g[3][0], g[3][1], g[3][2] );
-        for (std::size_t i=0; i<3; ++i)
-          g[0][i] = -g[1][i] - g[2][i] - g[3][i];
-        // scatter-add gradient contributions to boundary nodes
-        for (std::size_t a=0; a<4; ++a) {
-          auto i = bid.find( gid[N[a]] );
-          if (i != end(bid)) {
-            real u[5];
-            for (std::size_t b=0; b<4; ++b) {
-              u[0] = U(N[b],0);
-              u[1] = U(N[b],1)/u[0];
-              u[2] = U(N[b],2)/u[0];
-              u[3] = U(N[b],3)/u[0];
-              u[4] = U(N[b],4)/u[0]
-                     - 0.5*(u[1]*u[1] + u[2]*u[2] + u[3]*u[3]);
-              if ( stagPoint(x[N[b]],y[N[b]],z[N[b]]) )
-              {
-                u[1] = u[2] = u[3] = 0.0;
-              }
-              for (std::size_t c=0; c<5; ++c)
-                for (std::size_t j=0; j<3; ++j)
-                  G(i->second,c*3+j) += J24 * g[b][j] * u[c];
-            }
-          }
-        }
-      }
-    }
-
-    //! Compute right hand side for ALECG
-    //! \param[in] t Physical time
-    //! \param[in] coord Mesh node coordinates
-    //! \param[in] inpoel Mesh element connectivity
-    //! \param[in] triinpoel Boundary triangle face connecitivity with local ids
-    //! \param[in] bid Local chare-boundary node ids (value) associated to
-    //!    global node ids (key)
-    //! \param[in] gid Local->glocal node ids
-    //! \param[in] lid Global->local node ids
-    //! \param[in] dfn Dual-face normals
-    //! \param[in] psup Points surrounding points
-    //! \param[in] esup Elements surrounding points
-    //! \param[in] symbctri Vector with 1 at symmetry BC boundary triangles
-    //! \param[in] vol Nodal volumes
-    //! \param[in] edgenode Local node IDs of edges
-    //! \param[in] edgeid Edge ids in the order of access
-    //! \param[in] boxnodes Mesh node ids within user-defined IC boxes
-    //! \param[in] G Nodal gradients for chare-boundary nodes
-    //! \param[in] U Solution vector at recent time step
-    //! \param[in] W Mesh velocity
-    //! \param[in] tp Physical time for each mesh node
-    //! \param[in] V Total box volume
-    //! \param[in,out] R Right-hand side vector computed
-    void rhs( real t,
-              const std::array< std::vector< real >, 3 >& coord,
-              const std::vector< std::size_t >& inpoel,
-              const std::vector< std::size_t >& triinpoel,
-              const std::vector< std::size_t >& gid,
-              const std::unordered_map< std::size_t, std::size_t >& bid,
-              const std::unordered_map< std::size_t, std::size_t >& lid,
-              const std::vector< real >& dfn,
-              const std::pair< std::vector< std::size_t >,
-                               std::vector< std::size_t > >& psup,
-              const std::pair< std::vector< std::size_t >,
-                               std::vector< std::size_t > >& esup,
-              const std::vector< int >& symbctri,
-              const std::vector< real >& vol,
-              const std::vector< std::size_t >& edgenode,
-              const std::vector< std::size_t >& edgeid,
-              const std::vector< std::unordered_set< std::size_t > >& boxnodes,
-              const tk::Fields& G,
-              const tk::Fields& U,
-              const tk::Fields& W,
-              const std::vector< tk::real >& tp,
-              real V,
-              tk::Fields& R ) const
-    {
-      Assert( G.nprop() == m_ncomp*3,
-              "Number of components in gradient vector incorrect" );
-      Assert( U.nunk() == coord[0].size(), "Number of unknowns in solution "
-              "vector at recent time step incorrect" );
-      Assert( R.nunk() == coord[0].size(),
-              "Number of unknowns and/or number of components in right-hand "
-              "side vector incorrect" );
-      Assert( W.nunk() == coord[0].size(), "Size mismatch " );
-
-      // compute/assemble gradients in points
-      auto Grad = nodegrad( coord, inpoel, lid, bid, vol, esup, U, G );
-
-      // zero right hand side for all components
-      for (ncomp_t c=0; c<m_ncomp; ++c) R.fill( c, 0.0 );
-
-      // compute domain-edge integral
-      domainint( coord, gid, edgenode, edgeid, psup, dfn, U, W, Grad, R );
-
-      // compute boundary integrals
-      bndint( coord, triinpoel, symbctri, U, W, R );
-
-      // compute external (energy) sources
-      const auto& icbox = g_inputdeck.get< tag::ic, tag::box >();
-
-      if (!icbox.empty() && !boxnodes.empty()) {
-        std::size_t bcnt = 0;
-        for (const auto& b : icbox) {   // for all boxes for this eq
-          std::vector< tk::real > box
-           { b.template get< tag::xmin >(), b.template get< tag::xmax >(),
-             b.template get< tag::ymin >(), b.template get< tag::ymax >(),
-             b.template get< tag::zmin >(), b.template get< tag::zmax >() };
-
-          const auto& initiate = b.template get< tag::initiate >();
-          if (initiate == ctr::InitiateType::LINEAR) {
-            boxSrc( V, t, inpoel, esup, boxnodes[bcnt], coord, R );
-          }
-          ++bcnt;
-        }
-      }
-
-      // compute optional source integral
-      src( coord, inpoel, t, tp, R );
-    }
-
-    //! Compute overset mesh motion for OversetFE
-//    //! \param[in] t Physical time
-//    //! \param[in] coord Mesh node coordinates
-    //! \param[in] psup Points surrounding points
-    //! \param[in] symbcnodes Symmetry BC node list
-    //! \param[in] uservel User specified constant mesh velocity
-    //! \param[in] U Solution vector at recent time step
-//    //! \param[in,out] meshvel Velocity of each mesh node based on user input
-    //! \param[in,out] movedmesh True/false if mesh moved
-    void getMeshVel(
-      real /*t*/,
-      const std::array< std::vector< real >, 3 >& /*coord*/,
-      const std::pair< std::vector< std::size_t >,
-                       std::vector< std::size_t > >& psup,
-      const std::unordered_set< std::size_t >& symbcnodes,
-      const std::array< tk::real, 3 >& uservel,
-      const tk::Fields& U,
-      tk::Fields& /*meshvel*/,
-      int& movedmesh ) const
-    {
-      //Assert( meshvel.nunk() == U.nunk(),
-      //  "Mesh-velocity vector has incorrect size" );
-
-      auto uvelmag = std::sqrt(tk::dot(uservel, uservel));
-
-      // Check for pressure differential only if mesh has not moved before
-      if (movedmesh == 0 && uvelmag > 1e-8) {
-        for (auto p : symbcnodes) {
-          for (auto q : tk::Around(psup,p)) {
-            // compute pressure difference
-            real rL  = U(p,0);
-            real ruL = U(p,1) / rL;
-            real rvL = U(p,2) / rL;
-            real rwL = U(p,3) / rL;
-            real reL = U(p,4) / rL - 0.5*(ruL*ruL + rvL*rvL + rwL*rwL);
-            real rR  = U(q,0);
-            real ruR = U(q,1) / rR;
-            real rvR = U(q,2) / rR;
-            real rwR = U(q,3) / rR;
-            real reR = U(q,4) / rR - 0.5*(ruR*ruR + rvR*rvR + rwR*rwR);
-            real pL = m_mat_blk[0].compute< EOS::pressure >( rL, ruL/rL, rvL/rL,
-              rwL/rL, reL );
-            real pR = m_mat_blk[0].compute< EOS::pressure >( rR, ruR/rR, rvR/rR,
-              rwR/rR, reR );
-
-            if (std::abs(pR/pL) > 2.0) {
-              movedmesh = 1;
-              break;
-            }
-          }
-          if (movedmesh) break;
-        }
-      }
-    }
-
-    //! Compute the minimum time step size (for unsteady time stepping)
-    //! \param[in] coord Mesh node coordinates
-    //! \param[in] inpoel Mesh element connectivity
-    //! \param[in] t Physical time
-    //! \param[in] dtn Time step size at the previous time step
-    //! \param[in] U Solution vector at recent time step
-    //! \param[in] vol Nodal volume (with contributions from other chares)
-    //! \param[in] voln Nodal volume (with contributions from other chares) at
-    //!   the previous time step
-    //! \return Minimum time step size
-    real dt( const std::array< std::vector< real >, 3 >& coord,
-             const std::vector< std::size_t >& inpoel,
-             tk::real t,
-             tk::real dtn,
-             const tk::Fields& U,
-             const std::vector< tk::real >& vol,
-             const std::vector< tk::real >& voln ) const
-    {
-      Assert( U.nunk() == coord[0].size(), "Number of unknowns in solution "
-              "vector at recent time step incorrect" );
-
-      // energy source propagation time and velocity
-      const auto& icbox = g_inputdeck.get< tag::ic, tag::box >();
-
-      const auto& x = coord[0];
-      const auto& y = coord[1];
-      const auto& z = coord[2];
-
-      // ratio of specific heats
-      auto g = getmatprop< tag::gamma >();
-      // compute the minimum dt across all elements we own
-      real mindt = std::numeric_limits< real >::max();
-      for (std::size_t e=0; e<inpoel.size()/4; ++e) {
-        const std::array< std::size_t, 4 > N{{ inpoel[e*4+0], inpoel[e*4+1],
-                                               inpoel[e*4+2], inpoel[e*4+3] }};
-        // compute cubic root of element volume as the characteristic length
-        const std::array< real, 3 >
-          ba{{ x[N[1]]-x[N[0]], y[N[1]]-y[N[0]], z[N[1]]-z[N[0]] }},
-          ca{{ x[N[2]]-x[N[0]], y[N[2]]-y[N[0]], z[N[2]]-z[N[0]] }},
-          da{{ x[N[3]]-x[N[0]], y[N[3]]-y[N[0]], z[N[3]]-z[N[0]] }};
-        const auto L = std::cbrt( tk::triple( ba, ca, da ) / 6.0 );
-        // access solution at element nodes at recent time step
-        std::array< std::array< real, 4 >, m_ncomp > u;
-        for (ncomp_t c=0; c<m_ncomp; ++c) u[c] = U.extract( c, N );
-        // compute the maximum length of the characteristic velocity (fluid
-        // velocity + sound velocity) across the four element nodes
-        real maxvel = 0.0;
-        for (std::size_t j=0; j<4; ++j) {
-          auto& r  = u[0][j];    // rho
-          auto& ru = u[1][j];    // rho * u
-          auto& rv = u[2][j];    // rho * v
-          auto& rw = u[3][j];    // rho * w
-          auto& re = u[4][j];    // rho * e
-          auto p = m_mat_blk[0].compute< EOS::pressure >( r, ru/r, rv/r, rw/r,
-            re );
-          if (p < 0) p = 0.0;
-          auto c = m_mat_blk[0].compute< EOS::soundspeed >( r, p );
-          auto v = std::sqrt((ru*ru + rv*rv + rw*rw)/r/r) + c; // char. velocity
-
-          // energy source propagation velocity (in all IC boxes configured)
-          if (!icbox.empty()) {
-            for (const auto& b : icbox) {   // for all boxes for this eq
-              const auto& initiate = b.template get< tag::initiate >();
-              auto iv = b.template get< tag::front_speed >();
-              if (initiate == ctr::InitiateType::LINEAR) {
-                auto zmin = b.template get< tag::zmin >();
-                auto zmax = b.template get< tag::zmax >();
-                auto wFront = 0.08;
-                auto tInit = 0.0;
-                auto tFinal = tInit + (zmax - zmin - 2.0*wFront) /
-                  std::fabs(iv);
-                if (t >= tInit && t <= tFinal)
-                  v = std::max(v, std::fabs(iv));
-              }
-            }
-          }
-
-          if (v > maxvel) maxvel = v;
-        }
-        // compute element dt for the Euler equations
-        auto euler_dt = L / maxvel;
-        // compute element dt based on the viscous force
-        auto viscous_dt = m_physics.viscous_dt( L, u );
-        // compute element dt based on thermal diffusion
-        auto conduct_dt = m_physics.conduct_dt( L, g, u );
-        // compute minimum element dt
-        auto elemdt = std::min( euler_dt, std::min( viscous_dt, conduct_dt ) );
-        // find minimum dt across all elements
-        mindt = std::min( elemdt, mindt );
-      }
-      mindt *= g_inputdeck.get< tag::cfl >();
-
-      // compute the minimum dt across all nodes we contribute to due to volume
-      // change in time
-      auto dvcfl = g_inputdeck.get< tag::ale, tag::dvcfl >();
-      if (dtn > 0.0 && dvcfl > 0.0) {
-        Assert( vol.size() == voln.size(), "Size mismatch" );
-        for (std::size_t p=0; p<vol.size(); ++p) {
-          auto vol_dt = dtn *
-            std::min(voln[p],vol[p]) / std::abs(voln[p]-vol[p]+1.0e-14);
-          mindt = std::min( vol_dt, mindt );
-        }
-        mindt *= dvcfl;
-      }
-
-      return mindt;
-    }
-
-    //! Compute a time step size for each mesh node (for steady time stepping)
-    //! \param[in] U Solution vector at recent time step
-    //! \param[in] vol Nodal volume (with contributions from other chares)
-    //! \param[in,out] dtp Time step size for each mesh node
-    void dt( uint64_t,
-             const std::vector< tk::real >& vol,
-             const tk::Fields& U,
-             std::vector< tk::real >& dtp ) const
-    {
-      for (std::size_t i=0; i<U.nunk(); ++i) {
-        // compute cubic root of element volume as the characteristic length
-        const auto L = std::cbrt( vol[i] );
-        // access solution at node p at recent time step
-        const auto u = U[i];
-        // compute pressure
-        auto p = m_mat_blk[0].compute< EOS::pressure >( u[0], u[1]/u[0],
-          u[2]/u[0], u[3]/u[0], u[4] );
-        if (p < 0) p = 0.0;
-        auto c = m_mat_blk[0].compute< EOS::soundspeed >( u[0], p );
-        // characteristic velocity
-        auto v = std::sqrt((u[1]*u[1] + u[2]*u[2] + u[3]*u[3])/u[0]/u[0]) + c;
-        // compute dt for node
-        dtp[i] = L / v * g_inputdeck.get< tag::cfl >();
-      }
-    }
-
-    //! \brief Query Dirichlet boundary condition value on a given side set for
-    //!    all components in this PDE system
-    //! \param[in] t Physical time
-    //! \param[in] deltat Time step size
-    //! \param[in] tp Physical time for each mesh node
-    //! \param[in] dtp Time step size for each mesh node
-    //! \param[in] ss Pair of side set ID and (local) node IDs on the side set
-    //! \param[in] coord Mesh node coordinates
-    //! \param[in] increment If true, evaluate the solution increment between
-    //!   t and t+dt for Dirichlet BCs. If false, evlauate the solution instead.
-    //! \return Vector of pairs of bool and boundary condition value associated
-    //!   to mesh node IDs at which Dirichlet boundary conditions are set. Note
-    //!   that if increment is true, instead of the actual boundary condition
-    //!   value, we return the increment between t+deltat and t, since,
-    //!   depending on client code and solver, that may be what the solution
-    //!   requires.
-    std::map< std::size_t, std::vector< std::pair<bool,real> > >
-    dirbc( real t,
-           real deltat,
-           const std::vector< tk::real >& tp,
-           const std::vector< tk::real >& dtp,
-           const std::pair< const int, std::vector< std::size_t > >& ss,
-           const std::array< std::vector< real >, 3 >& coord,
-           bool increment ) const
-    {
-      using NodeBC = std::vector< std::pair< bool, real > >;
-      std::map< std::size_t, NodeBC > bc;
-
-      // collect sidesets across all meshes
-      std::vector< std::size_t > ubc;
-      for (const auto& ibc : g_inputdeck.get< tag::bc >()) {
-        ubc.insert(ubc.end(), ibc.get< tag::dirichlet >().begin(),
-          ibc.get< tag::dirichlet >().end());
-      }
+    //! Public interface to returning analytic solution
+    tk::InitializeFn::result_type
+    analyticSolution( tk::real xi, tk::real yi, tk::real zi, tk::real t ) const
+    { return self->analyticSolution( xi, yi, zi, t ); }
+
+    //! Public interface to returning the analytic solution for conserved vars
+    tk::InitializeFn::result_type
+    solution( tk::real xi, tk::real yi, tk::real zi, tk::real t ) const
+    { return self->solution( xi, yi, zi, t ); }
+
+    //! Public interface to returning the specific total energy
+    tk::real
+    sp_totalenergy( std::size_t e, const tk::Fields& unk ) const
+    { return self->sp_totalenergy( e, unk ); }
+
+    //! Copy assignment
+    DGPDE& operator=( const DGPDE& x )
+    { DGPDE tmp(x); *this = std::move(tmp); return *this; }
+    //! Copy constructor
+    DGPDE( const DGPDE& x ) : self( x.self->copy() ) {}
+    //! Move assignment
+    DGPDE& operator=( DGPDE&& ) noexcept = default;
+    //! Move constructor
+    DGPDE( DGPDE&& ) noexcept = default;
+
+  private:
+    //! \brief Concept is a pure virtual base class specifying the requirements
+    //!   of polymorphic objects deriving from it
+    struct Concept {
+      Concept() = default;
+      Concept( const Concept& ) = default;
+      virtual ~Concept() = default;
+      virtual Concept* copy() const = 0;
+      virtual std::size_t nprim() const = 0;
+      virtual std::size_t nmat() const = 0;
+      virtual void numEquationDofs(std::vector< std::size_t >&) const = 0;
+      virtual std::size_t nstiffeq() const = 0;
+      virtual std::size_t nnonstiffeq() const = 0;
+      virtual void setStiffEqIdx( std::vector< std::size_t >& ) const = 0;
+      virtual void setNonStiffEqIdx( std::vector< std::size_t >& ) const = 0;
+      virtual void IcBoxElems( const tk::Fields&,
+        std::size_t,
+        std::vector< std::unordered_set< std::size_t > >& ) const = 0;
+      virtual void initialize(
+        const tk::Fields&,
+        const std::vector< std::size_t >&,
+        const tk::UnsMesh::Coords&,
+        const std::vector< std::unordered_set< std::size_t > >&,
+        const std::unordered_map< std::size_t, std::set< std::size_t > >&,
+        tk::Fields&,
+        tk::real,
+        const std::size_t nielem ) const = 0;
+      virtual void setRho0mat( std::vector< tk::real >& ) const = 0;
+      virtual void computeDensityConstr( std::size_t nelem,
+                                         tk::Fields& unk,
+                                         std::vector< tk::real >& rho0mat,
+                                         std::vector< tk::real >& densityConstr)
+                                         const = 0;
+      virtual void lhs( const tk::Fields&, tk::Fields& ) const = 0;
+      virtual void updateInterfaceCells( tk::Fields&,
+                                         std::size_t,
+                                         std::vector< std::size_t >& ) const = 0;
+      virtual void updatePrimitives( const tk::Fields&,
+                                     const tk::Fields&,
+                                     const tk::Fields&,
+                                     tk::Fields&,
+                                     std::size_t ) const = 0;
+      virtual void cleanTraceMaterial( tk::real,
+                                       const tk::Fields&,
+                                       tk::Fields&,
+                                       tk::Fields&,
+                                       std::size_t ) const = 0;
+      virtual void reconstruct( tk::real,
+                                const tk::Fields&,
+                                const tk::Fields&,
+                                const inciter::FaceData&,
+                                const std::map< std::size_t,
+                                  std::vector< std::size_t > >&,
+                                const std::vector< std::size_t >&,
+                                const tk::UnsMesh::Coords&,
+                                tk::Fields&,
+                                tk::Fields& ) const = 0;
+      virtual void limit( tk::real,
+                          const tk::Fields&,
+                          const tk::Fields&,
+                          const inciter::FaceData&,
+                          const std::map< std::size_t,
+                            std::vector< std::size_t > >&,
+                          const std::vector< std::size_t >&,
+                          const tk::UnsMesh::Coords&,
+                          const std::vector< std::size_t >&,
+                          const std::vector< std::size_t >&,
+                          const std::unordered_map< std::size_t, std::size_t >&,
+                          const std::vector< std::vector<tk::real> >&,
+                          const std::vector< std::vector<tk::real> >&,
+                          const std::vector< std::vector<tk::real> >&,
+                          tk::Fields&,
+                          tk::Fields&,
+                          std::vector< std::size_t >& ) const = 0;
+      virtual void CPL( const tk::Fields&,
+                        const tk::Fields&,
+                        const std::vector< std::size_t >&,
+                        const tk::UnsMesh::Coords&,
+                        tk::Fields&,
+                        std::size_t ) const = 0;
+      virtual std::array< std::vector< tk::real >, 9 > cellAvgDeformGrad(
+        const tk::Fields&,
+        std::size_t ) const = 0;
+      virtual void rhs( tk::real,
+                        const tk::Fields&,
+                        const tk::Fields&,
+                        const inciter::FaceData&,
+                        const std::vector< std::size_t >&,
+                        const std::vector< std::unordered_set< std::size_t > >&,
+                        const tk::UnsMesh::Coords&,
+                        const tk::Fields&,
+                        const tk::Fields&,
+                        const std::vector< std::size_t >&,
+                        const std::vector< tk::real >&,
+                        const tk::real,
+                        tk::Fields& ) const = 0;
+      virtual void eval_ndof( std::size_t,
+                              const tk::UnsMesh::Coords&,
+                              const std::vector< std::size_t >&,
+                              const inciter::FaceData&,
+                              const tk::Fields&,
+                              const tk::Fields&,
+                              inciter::ctr::PrefIndicatorType,
+                              std::size_t,
+                              std::size_t,
+                              tk::real,
+                              std::vector< std::size_t >& ) const = 0;
+      virtual tk::real dt( const std::array< std::vector< tk::real >, 3 >&,
+                           const std::vector< std::size_t >&,
+                           const inciter::FaceData&,
+                           const tk::Fields&,
+                           const tk::Fields&,
+                           const std::vector< std::size_t >&,
+                           const tk::Fields&,
+                           const tk::Fields&,
+                           const std::size_t ) const = 0;
+      virtual void stiff_rhs( std::size_t,
+                              const tk::Fields&,
+                              const std::vector< std::size_t >&,
+                              const tk::UnsMesh::Coords&,
+                              const tk::Fields&,
+                              const tk::Fields&,
+                              const std::vector< std::size_t >&,
+                              tk::Fields& ) const = 0;
+      virtual std::map< std::string, tk::GetVarFn > OutVarFn() const = 0;
+      virtual std::vector< std::string > analyticFieldNames() const = 0;
+      virtual std::vector< std::string > histNames() const = 0;
+      virtual std::vector< std::string > names() const = 0;
+      virtual std::vector< std::vector< tk::real > > surfOutput(
+        const std::map< int, std::vector< std::size_t > >&,
+        tk::Fields& ) const = 0;
+      virtual std::vector< std::vector< tk::real > > histOutput(
+        const std::vector< HistData >&,
+        const std::vector< std::size_t >&,
+        const tk::UnsMesh::Coords&,
+        const tk::Fields&,
+        const tk::Fields& ) const = 0;
+      virtual tk::InitializeFn::result_type analyticSolution(
+        tk::real xi, tk::real yi, tk::real zi, tk::real t ) const = 0;
+      virtual tk::InitializeFn::result_type solution(
+        tk::real xi, tk::real yi, tk::real zi, tk::real t ) const = 0;
+      virtual tk::real sp_totalenergy(
+        std::size_t, const tk::Fields& ) const = 0;
+    };
+
+    //! \brief Model models the Concept above by deriving from it and overriding
+    //!   the virtual functions required by Concept
+    template< typename T >
+    struct Model : Concept {
+      explicit Model( T x ) : data( std::move(x) ) {}
+      Concept* copy() const override { return new Model( *this ); }
+      std::size_t nprim() const override
+      { return data.nprim(); }
+      std::size_t nmat() const override
+      { return data.nmat(); }
+      void numEquationDofs(std::vector< std::size_t >& numEqDof) const override
+      { data.numEquationDofs(numEqDof); }
+      std::size_t nstiffeq() const override
+      { return data.nstiffeq(); }
+      std::size_t nnonstiffeq() const override
+      { return data.nnonstiffeq(); }
+      void setStiffEqIdx( std::vector< std::size_t >& stiffEqIdx ) const override
+      { data.setStiffEqIdx(stiffEqIdx); }
+      void setNonStiffEqIdx( std::vector< std::size_t >& nonStiffEqIdx ) const override
+      { data.setNonStiffEqIdx(nonStiffEqIdx); }
+      void IcBoxElems( const tk::Fields& geoElem,
+        std::size_t nielem,
+        std::vector< std::unordered_set< std::size_t > >& inbox )
+      const override { data.IcBoxElems( geoElem, nielem, inbox ); }
+      void initialize(
+        const tk::Fields& L,
+        const std::vector< std::size_t >& inpoel,
+        const tk::UnsMesh::Coords& coord,
+        const std::vector< std::unordered_set< std::size_t > >& inbox,
+        const std::unordered_map< std::size_t, std::set< std::size_t > >&
+          elemblkid,
+        tk::Fields& unk,
+        tk::real t,
+        const std::size_t nielem )
+      const override { data.initialize( L, inpoel, coord, inbox, elemblkid, unk,
+        t, nielem ); }
+      void setRho0mat( std::vector< tk::real >& rho0mat ) const override
+      { data.setRho0mat( rho0mat ); }
+      void computeDensityConstr( std::size_t nelem,
+                                 tk::Fields& unk,
+                                 std::vector< tk::real >& rho0mat,
+                                 std::vector< tk::real >& densityConstr)
+                                 const override
+      { data.computeDensityConstr( nelem, unk, rho0mat, densityConstr ); }
+      void lhs( const tk::Fields& geoElem, tk::Fields& l ) const override
+      { data.lhs( geoElem, l ); }
+      void updateInterfaceCells( tk::Fields& unk,
+                                 std::size_t nielem,
+                                 std::vector< std::size_t >& ndofel )
+      const override { data.updateInterfaceCells( unk, nielem, ndofel ); }
+      void updatePrimitives( const tk::Fields& unk,
+                             const tk::Fields& L,
+                             const tk::Fields& geoElem,
+                             tk::Fields& prim,
+                             std::size_t nielem )
+      const override { data.updatePrimitives( unk, L, geoElem, prim, nielem ); }
+      void cleanTraceMaterial( tk::real t,
+                               const tk::Fields& geoElem,
+                               tk::Fields& unk,
+                               tk::Fields& prim,
+                               std::size_t nielem )
+      const override { data.cleanTraceMaterial( t, geoElem, unk, prim, nielem ); }
+      void reconstruct( tk::real t,
+                        const tk::Fields& geoFace,
+                        const tk::Fields& geoElem,
+                        const inciter::FaceData& fd,
+                        const std::map< std::size_t,
+                          std::vector< std::size_t > >& esup,
+                        const std::vector< std::size_t >& inpoel,
+                        const tk::UnsMesh::Coords& coord,
+                        tk::Fields& U,
+                        tk::Fields& P ) const override
+      {
+        data.reconstruct( t, geoFace, geoElem, fd, esup, inpoel, coord, U, P );
+      }
+      void limit( tk::real t,
+                  const tk::Fields& geoFace,
+                  const tk::Fields& geoElem,
+                  const inciter::FaceData& fd,
+                  const std::map< std::size_t, std::vector< std::size_t > >&
+                    esup,
+                  const std::vector< std::size_t >& inpoel,
+                  const tk::UnsMesh::Coords& coord,
+                  const std::vector< std::size_t >& ndofel,
+                  const std::vector< std::size_t >& gid,
+                  const std::unordered_map< std::size_t, std::size_t >& bid,
+                  const std::vector< std::vector<tk::real> >& uNodalExtrm,
+                  const std::vector< std::vector<tk::real> >& pNodalExtrm,
+                  const std::vector< std::vector<tk::real> >& mtInv,
+                  tk::Fields& U,
+                  tk::Fields& P,
+                  std::vector< std::size_t >& shockmarker ) const override
+      {
+        data.limit( t, geoFace, geoElem, fd, esup, inpoel, coord, ndofel, gid,
+                    bid, uNodalExtrm, pNodalExtrm, mtInv, U, P, shockmarker );
+      }
+      void CPL( const tk::Fields& prim,
+                const tk::Fields& geoElem,
+                const std::vector< std::size_t >& inpoel,
+                const tk::UnsMesh::Coords& coord,
+                tk::Fields& unk,
+                std::size_t nielem ) const override
+      {
+        data.CPL( prim, geoElem, inpoel, coord, unk, nielem );
+      }
+      std::array< std::vector< tk::real >, 9 > cellAvgDeformGrad(
+        const tk::Fields& U,
+        std::size_t nielem ) const override
+      {
+        return data.cellAvgDeformGrad( U, nielem );
+      }
+      void rhs(
+        tk::real t,
+        const tk::Fields& geoFace,
+        const tk::Fields& geoElem,
+        const inciter::FaceData& fd,
+        const std::vector< std::size_t >& inpoel,
+        const std::vector< std::unordered_set< std::size_t > >& boxelems,
+        const tk::UnsMesh::Coords& coord,
+        const tk::Fields& U,
+        const tk::Fields& P,
+        const std::vector< std::size_t >& ndofel,
+        const std::vector< tk::real >& rho0mat,
+        const tk::real dt,
+        tk::Fields& R ) const override
+      {
+        data.rhs( t, geoFace, geoElem, fd, inpoel, boxelems, coord, U, P,
+                  ndofel, rho0mat, dt, R );
+      }
+      void eval_ndof( std::size_t nunk,
+                      const tk::UnsMesh::Coords& coord,
+                      const std::vector< std::size_t >& inpoel,
+                      const inciter::FaceData& fd,
+                      const tk::Fields& unk,
+                      const tk::Fields& prim,
+                      inciter::ctr::PrefIndicatorType indicator,
+                      std::size_t ndof,
+                      std::size_t ndofmax,
+                      tk::real tolref,
+                      std::vector< std::size_t >& ndofel ) const override
+      { data.eval_ndof( nunk, coord, inpoel, fd, unk, prim, indicator, ndof,
+                        ndofmax, tolref, ndofel ); }
+      tk::real dt( const std::array< std::vector< tk::real >, 3 >& coord,
+                   const std::vector< std::size_t >& inpoel,
+                   const inciter::FaceData& fd,
+                   const tk::Fields& geoFace,
+                   const tk::Fields& geoElem,
+                   const std::vector< std::size_t >& ndofel,
+                   const tk::Fields& U,
+                   const tk::Fields& P,
+                   const std::size_t nielem ) const override
+      { return data.dt( coord, inpoel, fd, geoFace, geoElem, ndofel,
+                        U, P, nielem ); }
+      void stiff_rhs( std::size_t e,
+                      const tk::Fields& geoElem,
+                      const std::vector< std::size_t >& inpoel,
+                      const tk::UnsMesh::Coords& coord,
+                      const tk::Fields& U,
+                      const tk::Fields& P,
+                      const std::vector< std::size_t >& ndofel,
+                      tk::Fields& R ) const override
+      { return data.stiff_rhs( e, geoElem, inpoel, coord, U, P, ndofel, R ); }
+      std::map< std::string, tk::GetVarFn > OutVarFn() const override
+      { return data.OutVarFn(); }
+      std::vector< std::string > analyticFieldNames() const override
+      { return data.analyticFieldNames(); }
+      std::vector< std::string > histNames() const override
+      { return data.histNames(); }
+      std::vector< std::string > names() const override
+      { return data.names(); }
+      std::vector< std::vector< tk::real > > surfOutput(
+        const std::map< int, std::vector< std::size_t > >& bnd,
+        tk::Fields& U ) const override
+      { return data.surfOutput( bnd, U ); }
+      std::vector< std::vector< tk::real > > histOutput(
+        const std::vector< HistData >& h,
+        const std::vector< std::size_t >& inpoel,
+        const tk::UnsMesh::Coords& coord,
+        const tk::Fields& U,
+        const tk::Fields& P ) const override
+      { return data.histOutput( h, inpoel, coord, U, P ); }
+      tk::InitializeFn::result_type
+      analyticSolution( tk::real xi, tk::real yi, tk::real zi, tk::real t )
+       const override { return data.analyticSolution( xi, yi, zi, t ); }
+      tk::InitializeFn::result_type
+      solution( tk::real xi, tk::real yi, tk::real zi, tk::real t )
+       const override { return data.solution( xi, yi, zi, t ); }
+      tk::real sp_totalenergy( std::size_t e, const tk::Fields& unk )
+       const override { return data.sp_totalenergy( e, unk ); }
+      T data;
+    };
+
+    std::unique_ptr< Concept > self;    //!< Base pointer used polymorphically
+};
+
+} // inciter::
 
-      const auto steady = g_inputdeck.get< tag::steady_state >();<--- Variable 'steady' is assigned a value that is never used.
-      if (!ubc.empty()) {
-        Assert( ubc.size() > 0, "Indexing out of Dirichlet BC eq-vector" );
-        const auto& x = coord[0];
-        const auto& y = coord[1];
-        const auto& z = coord[2];
-        for (const auto& b : ubc)
-          if (static_cast<int>(b) == ss.first)
-            for (auto n : ss.second) {
-              Assert( x.size() > n, "Indexing out of coordinate array" );
-              if (steady) { t = tp[n]; deltat = dtp[n]; }
-              auto s = increment ?
-                solinc( m_ncomp, m_mat_blk, x[n], y[n], z[n],
-                        t, deltat, Problem::initialize ) :
-                Problem::initialize( m_ncomp, m_mat_blk, x[n], y[n],
-                                     z[n], t+deltat );
-              if ( stagPoint(x[n],y[n],z[n]) ) {
-                s[1] = s[2] = s[3] = 0.0;
-              }
-              bc[n] = {{ {true,s[0]}, {true,s[1]}, {true,s[2]}, {true,s[3]},
-                         {true,s[4]} }};
-            }
-      }
-      return bc;
-    }
-
-    //! Set symmetry boundary conditions at nodes
-    //! \param[in] U Solution vector at recent time step
-    //! \param[in] bnorm Face normals in boundary points, key local node id,
-    //!   first 3 reals of value: unit normal, outer key: side set id
-    //! \param[in] nodes Unique set of node ids at which to set symmetry BCs
-    void
-    symbc( tk::Fields& U,
-           const std::array< std::vector< real >, 3 >&,
-           const std::unordered_map< int,
-             std::unordered_map< std::size_t, std::array< real, 4 > > >& bnorm,
-           const std::unordered_set< std::size_t >& nodes ) const
-    {
-      // collect sidesets across all meshes
-      std::vector< std::size_t > sbc;
-      for (const auto& ibc : g_inputdeck.get< tag::bc >()) {
-        sbc.insert(sbc.end(), ibc.get< tag::symmetry >().begin(),
-          ibc.get< tag::symmetry >().end());
-      }
-
-      if (sbc.size() > 0) {             // use symbcs for this system
-        for (auto p : nodes) {                 // for all symbc nodes
-          // for all user-def symbc sets
-          for (std::size_t s=0; s<sbc.size(); ++s) {
-            // find nodes & normals for side
-            auto j = bnorm.find(static_cast<int>(sbc[s]));
-            if (j != end(bnorm)) {
-              auto i = j->second.find(p);      // find normal for node
-              if (i != end(j->second)) {
-                std::array< real, 3 >
-                  n{ i->second[0], i->second[1], i->second[2] },
-                  v{ U(p,1), U(p,2), U(p,3) };
-                auto v_dot_n = tk::dot( v, n );
-                // symbc: remove normal component of velocity
-                U(p,1) -= v_dot_n * n[0];
-                U(p,2) -= v_dot_n * n[1];
-                U(p,3) -= v_dot_n * n[2];
-              }
-            }
-          }
-        }
-      }
-    }
-
-    //! Set farfield boundary conditions at nodes
-    //! \param[in] U Solution vector at recent time step
-    //! \param[in] bnorm Face normals in boundary points, key local node id,
-    //!   first 3 reals of value: unit normal, outer key: side set id
-    //! \param[in] nodes Unique set of node ids at which to set farfield BCs
-    void
-    farfieldbc(
-      tk::Fields& U,
-      const std::array< std::vector< real >, 3 >&,
-      const std::unordered_map< int,
-        std::unordered_map< std::size_t, std::array< real, 4 > > >& bnorm,
-      const std::unordered_set< std::size_t >& nodes ) const
-    {
-      // collect sidesets across all meshes
-      std::vector< std::size_t > fbc;
-      for (const auto& ibc : g_inputdeck.get< tag::bc >()) {
-        fbc.insert(fbc.end(), ibc.get< tag::farfield >().begin(),
-          ibc.get< tag::farfield >().end());
-      }
-
-      if (fbc.size() > 0)               // use farbcs for this system
-        for (auto p : nodes)                   // for all farfieldbc nodes
-          for (const auto& s : fbc) {// for all user-def farbc sets
-            auto j = bnorm.find(static_cast<int>(s));// find nodes & normals for side
-            if (j != end(bnorm)) {
-              auto i = j->second.find(p);      // find normal for node
-              if (i != end(j->second)) {
-                auto& r  = U(p,0);
-                auto& ru = U(p,1);
-                auto& rv = U(p,2);
-                auto& rw = U(p,3);
-                auto& re = U(p,4);
-                auto vn =
-                  (ru*i->second[0] + rv*i->second[1] + rw*i->second[2]) / r;
-                auto a = m_mat_blk[0].compute< EOS::soundspeed >( r,
-                  m_mat_blk[0].compute< EOS::pressure >( r, ru/r, rv/r, rw/r,
-                  re ) );
-                auto M = vn / a;
-                if (M <= -1.0) {                      // supersonic inflow
-                  r  = m_fr;
-                  ru = m_fr * m_fu[0];
-                  rv = m_fr * m_fu[1];
-                  rw = m_fr * m_fu[2];
-                  re = m_mat_blk[0].compute< EOS::totalenergy >( m_fr,
-                    m_fu[0], m_fu[1], m_fu[2], m_fp );
-                } else if (M > -1.0 && M < 0.0) {     // subsonic inflow
-                  auto pr = m_mat_blk[0].compute< EOS::pressure >
-                                                ( r, ru/r, rv/r, rw/r, re );
-                  r  = m_fr;
-                  ru = m_fr * m_fu[0];
-                  rv = m_fr * m_fu[1];
-                  rw = m_fr * m_fu[2];
-                  re = m_mat_blk[0].compute< EOS::totalenergy >( m_fr,
-                    m_fu[0], m_fu[1], m_fu[2], pr );
-                } else if (M >= 0.0 && M < 1.0) {     // subsonic outflow
-                  re = m_mat_blk[0].compute< EOS::totalenergy >( r, ru/r,
-                    rv/r, rw/r, m_fp );
-                }
-              }
-            }
-          }
-    }
-
-    //! Apply user defined time dependent BCs
-    //! \param[in] t Physical time
-    //! \param[in,out] U Solution vector at recent time step
-    //! \param[in] nodes Vector of unique sets of node ids at which to apply BCs
-    //! \details This function applies user defined time dependent boundary
-    //!   conditions on groups of side sets specified in the input file.
-    //!   The user specifies pressure, density, and velocity as discrete
-    //!   functions of time, in the control file, associated with a group of
-    //!   side sets. Several such groups can be specified, each with their
-    //!   own discrete function: p(t), rho(t), vx(t), vy(t), vz(t).
-    void
-    timedepbc( tk::real t,
-      tk::Fields& U,<--- Parameter 'U' can be declared with const
-      const std::vector< std::unordered_set< std::size_t > >& nodes,
-      const std::vector< tk::Table<5> >& timedepfn ) const
-    {
-      for (std::size_t ib=0; ib<nodes.size(); ++ib) {
-        for (auto p:nodes[ib]) {
-          // sample primitive vars from discrete data at time t
-          auto unk = tk::sample<5>(t, timedepfn[ib]);
-
-          // apply BCs after converting to conserved vars
-          U(p,0) = unk[1];
-          U(p,1) = unk[1]*unk[2];
-          U(p,2) = unk[1]*unk[3];
-          U(p,3) = unk[1]*unk[4];
-          U(p,4) = m_mat_blk[0].compute< EOS::totalenergy >( unk[1], unk[2],
-            unk[3], unk[4], unk[0]);
-        }
-      }
-    }
-
-    //! Return a map that associates user-specified strings to functions
-    //! \return Map that associates user-specified strings to functions that
-    //!   compute relevant quantities to be output to file
-    std::map< std::string, tk::GetVarFn > OutVarFn() const
-    { return CompFlowOutVarFn(); }
-
-    //! Return analytic field names to be output to file
-    //! \return Vector of strings labelling analytic fields output in file
-    std::vector< std::string > analyticFieldNames() const
-    { return m_problem.analyticFieldNames( m_ncomp ); }
-
-    //! Return surface field names to be output to file
-    //! \return Vector of strings labelling surface fields output in file
-    std::vector< std::string > surfNames() const
-    { return CompFlowSurfNames(); }
-
-    //! Return time history field names to be output to file
-    //! \return Vector of strings labelling time history fields output in file
-    std::vector< std::string > histNames() const
-    { return CompFlowHistNames(); }
-
-    //! Return nodal surface field output going to file
-    std::vector< std::vector< real > >
-    surfOutput( const std::map< int, std::vector< std::size_t > >& bnd,
-                const tk::Fields& U ) const
-    { return CompFlowSurfOutput( m_mat_blk, bnd, U ); }
-
-    //! Return elemental surface field output (on triangle faces) going to file
-    std::vector< std::vector< real > >
-    elemSurfOutput( const std::map< int, std::vector< std::size_t > >& bface,
-      const std::vector< std::size_t >& triinpoel,
-      const tk::Fields& U ) const
-    {
-      return CompFlowElemSurfOutput( m_mat_blk, bface, triinpoel, U );
-    }
-
-    //! Return time history field output evaluated at time history points
-    std::vector< std::vector< real > >
-    histOutput( const std::vector< HistData >& h,
-                const std::vector< std::size_t >& inpoel,
-                const tk::Fields& U ) const
-    { return CompFlowHistOutput( m_mat_blk, h, inpoel, U ); }
-
-    //! Return names of integral variables to be output to diagnostics file
-    //! \return Vector of strings labelling integral variables output
-    std::vector< std::string > names() const
-    { return m_problem.names( m_ncomp ); }
-
-  private:
-    const Physics m_physics;            //!< Physics policy
-    const Problem m_problem;            //!< Problem policy
-    //! Stagnation BC user configuration: point coordinates and radii
-    std::tuple< std::vector< real >, std::vector< real > > m_stagCnf;
-    real m_fr;                    //!< Farfield density
-    real m_fp;                    //!< Farfield pressure
-    std::vector< real > m_fu;     //!< Farfield velocity
-    //! EOS material block
-    std::vector< EOS > m_mat_blk;
-
-    //! Decide if point is a stagnation point
-    //! \param[in] x X mesh point coordinates to query
-    //! \param[in] y Y mesh point coordinates to query
-    //! \param[in] z Z mesh point coordinates to query
-    //! \return True if point is configured as a stagnation point by the user
-    #pragma omp declare simd
-    bool
-    stagPoint( real x, real y, real z ) const {
-      const auto& pnt = std::get< 0 >( m_stagCnf );
-      const auto& rad = std::get< 1 >( m_stagCnf );
-      for (std::size_t i=0; i<pnt.size()/3; ++i) {
-        if (tk::length( x-pnt[i*3+0], y-pnt[i*3+1], z-pnt[i*3+2] ) < rad[i])
-          return true;
-      }
-      return false;
-    }
-
-    //! \brief Compute/assemble nodal gradients of primitive variables for
-    //!   ALECG in all points
-    //! \param[in] coord Mesh node coordinates
-    //! \param[in] inpoel Mesh element connectivity
-    //! \param[in] lid Global->local node ids
-    //! \param[in] bid Local chare-boundary node ids (value) associated to
-    //!    global node ids (key)
-    //! \param[in] vol Nodal volumes
-    //! \param[in] esup Elements surrounding points
-    //! \param[in] U Solution vector at recent time step
-    //! \param[in] G Nodal gradients of primitive variables in chare-boundary
-    //!    nodes
-    //! \return Gradients of primitive variables in all mesh points
-    tk::Fields
-    nodegrad( const std::array< std::vector< real >, 3 >& coord,
-              const std::vector< std::size_t >& inpoel,
-              const std::unordered_map< std::size_t, std::size_t >& lid,
-              const std::unordered_map< std::size_t, std::size_t >& bid,
-              const std::vector< real >& vol,
-              const std::pair< std::vector< std::size_t >,
-                               std::vector< std::size_t > >& esup,
-              const tk::Fields& U,
-              const tk::Fields& G ) const
-    {
-      // allocate storage for nodal gradients of primitive variables
-      tk::Fields Grad( U.nunk(), m_ncomp*3 );
-      Grad.fill( 0.0 );
-
-      // access node cooordinates
-      const auto& x = coord[0];
-      const auto& y = coord[1];
-      const auto& z = coord[2];
-
-      // compute gradients of primitive variables in points
-      auto npoin = U.nunk();
-      #pragma omp simd
-      for (std::size_t p=0; p<npoin; ++p)
-        for (auto e : tk::Around(esup,p)) {
-          // access node IDs
-          std::size_t N[4] =
-            { inpoel[e*4+0], inpoel[e*4+1], inpoel[e*4+2], inpoel[e*4+3] };
-          // compute element Jacobi determinant, J = 6V
-          real bax = x[N[1]]-x[N[0]];
-          real bay = y[N[1]]-y[N[0]];
-          real baz = z[N[1]]-z[N[0]];
-          real cax = x[N[2]]-x[N[0]];
-          real cay = y[N[2]]-y[N[0]];
-          real caz = z[N[2]]-z[N[0]];
-          real dax = x[N[3]]-x[N[0]];
-          real day = y[N[3]]-y[N[0]];
-          real daz = z[N[3]]-z[N[0]];
-          auto J = tk::triple( bax, bay, baz, cax, cay, caz, dax, day, daz );
-          auto J24 = J/24.0;
-          // shape function derivatives, nnode*ndim [4][3]
-          real g[4][3];
-          tk::crossdiv( cax, cay, caz, dax, day, daz, J,
-                        g[1][0], g[1][1], g[1][2] );
-          tk::crossdiv( dax, day, daz, bax, bay, baz, J,
-                        g[2][0], g[2][1], g[2][2] );
-          tk::crossdiv( bax, bay, baz, cax, cay, caz, J,
-                        g[3][0], g[3][1], g[3][2] );
-          for (std::size_t i=0; i<3; ++i)
-            g[0][i] = -g[1][i] - g[2][i] - g[3][i];
-          // scatter-add gradient contributions to boundary nodes
-          real u[m_ncomp];
-          for (std::size_t b=0; b<4; ++b) {
-            u[0] = U(N[b],0);
-            u[1] = U(N[b],1)/u[0];
-            u[2] = U(N[b],2)/u[0];
-            u[3] = U(N[b],3)/u[0];
-            u[4] = U(N[b],4)/u[0]
-                   - 0.5*(u[1]*u[1] + u[2]*u[2] + u[3]*u[3]);
-            if ( stagPoint(x[N[b]],y[N[b]],z[N[b]]) )
-            {
-              u[1] = u[2] = u[3] = 0.0;
-            }
-            for (std::size_t c=0; c<m_ncomp; ++c)
-              for (std::size_t i=0; i<3; ++i)
-                Grad(p,c*3+i) += J24 * g[b][i] * u[c];
-          }
-        }
-
-      // put in nodal gradients of chare-boundary points
-      for (const auto& [g,b] : bid) {
-        auto i = tk::cref_find( lid, g );
-        for (ncomp_t c=0; c<Grad.nprop(); ++c)
-          Grad(i,c) = G(b,c);
-      }
-
-      // divide weak result in gradients by nodal volume
-      for (std::size_t p=0; p<npoin; ++p)
-        for (std::size_t c=0; c<m_ncomp*3; ++c)
-          Grad(p,c) /= vol[p];
-
-      return Grad;
-    }
-
-    //! Compute domain-edge integral for ALECG
-    //! \param[in] coord Mesh node coordinates
-    //! \param[in] gid Local->glocal node ids
-    //! \param[in] edgenode Local node ids of edges
-    //! \param[in] edgeid Local node id pair -> edge id map
-    //! \param[in] psup Points surrounding points
-    //! \param[in] dfn Dual-face normals
-    //! \param[in] U Solution vector at recent time step
-    //! \param[in] W Mesh velocity
-    //! \param[in] G Nodal gradients
-    //! \param[in,out] R Right-hand side vector computed
-    void domainint( const std::array< std::vector< real >, 3 >& coord,
-                    const std::vector< std::size_t >& gid,
-                    const std::vector< std::size_t >& edgenode,
-                    const std::vector< std::size_t >& edgeid,
-                    const std::pair< std::vector< std::size_t >,
-                                     std::vector< std::size_t > >& psup,
-                    const std::vector< real >& dfn,
-                    const tk::Fields& U,
-                    const tk::Fields& W,
-                    const tk::Fields& G,
-                    tk::Fields& R ) const
-    {
-      // domain-edge integral: compute fluxes in edges
-      std::vector< real > dflux( edgenode.size()/2 * m_ncomp );
-
-      // access node coordinates
-      const auto& x = coord[0];
-      const auto& y = coord[1];
-      const auto& z = coord[2];
-
-      #pragma omp simd
-      for (std::size_t e=0; e<edgenode.size()/2; ++e) {
-        auto p = edgenode[e*2+0];
-        auto q = edgenode[e*2+1];
-
-        // compute primitive variables at edge-end points
-        real rL  = U(p,0);
-        real ruL = U(p,1) / rL;
-        real rvL = U(p,2) / rL;
-        real rwL = U(p,3) / rL;
-        real reL = U(p,4) / rL - 0.5*(ruL*ruL + rvL*rvL + rwL*rwL);
-        real w1L = W(p,0);
-        real w2L = W(p,1);
-        real w3L = W(p,2);
-        real rR  = U(q,0);
-        real ruR = U(q,1) / rR;
-        real rvR = U(q,2) / rR;
-        real rwR = U(q,3) / rR;
-        real reR = U(q,4) / rR - 0.5*(ruR*ruR + rvR*rvR + rwR*rwR);
-        real w1R = W(q,0);
-        real w2R = W(q,1);
-        real w3R = W(q,2);
-
-        // apply stagnation BCs to primitive variables
-        if ( stagPoint(x[p],y[p],z[p]) )
-          ruL = rvL = rwL = 0.0;
-        if ( stagPoint(x[q],y[q],z[q]) )
-          ruR = rvR = rwR = 0.0;
-
-        // compute MUSCL reconstruction in edge-end points
-        muscl( p, q, coord, G,
-               rL, ruL, rvL, rwL, reL, rR, ruR, rvR, rwR, reR );
-
-        // convert back to conserved variables
-        reL = (reL + 0.5*(ruL*ruL + rvL*rvL + rwL*rwL)) * rL;
-        ruL *= rL;
-        rvL *= rL;
-        rwL *= rL;
-        reR = (reR + 0.5*(ruR*ruR + rvR*rvR + rwR*rwR)) * rR;
-        ruR *= rR;
-        rvR *= rR;
-        rwR *= rR;
-
-        // evaluate pressure at edge-end points
-        real pL = m_mat_blk[0].compute< EOS::pressure >( rL, ruL/rL, rvL/rL,
-          rwL/rL, reL );
-        real pR = m_mat_blk[0].compute< EOS::pressure >( rR, ruR/rR, rvR/rR,
-          rwR/rR, reR );
-
-        // compute Riemann flux using edge-end point states
-        real f[m_ncomp];
-        Rusanov::flux( m_mat_blk,
-                       dfn[e*6+0], dfn[e*6+1], dfn[e*6+2],
-                       dfn[e*6+3], dfn[e*6+4], dfn[e*6+5],
-                       rL, ruL, rvL, rwL, reL,
-                       rR, ruR, rvR, rwR, reR,
-                       w1L, w2L, w3L, w1R, w2R, w3R,
-                       pL, pR,
-                       f[0], f[1], f[2], f[3], f[4] );
-        // store flux in edges
-        for (std::size_t c=0; c<m_ncomp; ++c) dflux[e*m_ncomp+c] = f[c];
-      }
-
-      // access pointer to right hand side at component
-      std::array< const real*, m_ncomp > r;
-      for (ncomp_t c=0; c<m_ncomp; ++c) r[c] = R.cptr( c );
-
-      // domain-edge integral: sum flux contributions to points
-      for (std::size_t p=0,k=0; p<U.nunk(); ++p)
-        for (auto q : tk::Around(psup,p)) {
-          auto s = gid[p] > gid[q] ? -1.0 : 1.0;
-          auto e = edgeid[k++];
-          // the 2.0 in the following expression is so that the RHS contribution
-          // conforms with Eq 12 (Waltz et al. Computers & fluids (92) 2014);
-          // The 1/2 in Eq 12 is extracted from the flux function (Rusanov).
-          // However, Rusanov::flux computes the flux with the 1/2. This 2
-          // cancels with the 1/2 in Rusanov::flux, so that the 1/2 can be
-          // extracted out and multiplied as in Eq 12
-          for (std::size_t c=0; c<m_ncomp; ++c)
-            R.var(r[c],p) -= 2.0*s*dflux[e*m_ncomp+c];
-        }
-
-      tk::destroy(dflux);
-    }
-
-    //! \brief Compute MUSCL reconstruction in edge-end points using a MUSCL
-    //!    procedure with van Leer limiting
-    //! \param[in] p Left node id of edge-end
-    //! \param[in] q Right node id of edge-end
-    //! \param[in] coord Array of nodal coordinates
-    //! \param[in] G Gradient of all unknowns in mesh points
-    //! \param[in,out] rL Left density
-    //! \param[in,out] uL Left X velocity
-    //! \param[in,out] vL Left Y velocity
-    //! \param[in,out] wL Left Z velocity
-    //! \param[in,out] eL Left internal energy
-    //! \param[in,out] rR Right density
-    //! \param[in,out] uR Right X velocity
-    //! \param[in,out] vR Right Y velocity
-    //! \param[in,out] wR Right Z velocity
-    //! \param[in,out] eR Right internal energy
-    void muscl( std::size_t p,
-                std::size_t q,
-                const tk::UnsMesh::Coords& coord,
-                const tk::Fields& G,
-                real& rL, real& uL, real& vL, real& wL, real& eL,
-                real& rR, real& uR, real& vR, real& wR, real& eR ) const
-    {
-      // access node coordinates
-      const auto& x = coord[0];
-      const auto& y = coord[1];
-      const auto& z = coord[2];
-
-      // edge vector
-      std::array< real, 3 > vw{ x[q]-x[p], y[q]-y[p], z[q]-z[p] };
-
-      real delta1[5], delta2[5], delta3[5];
-      std::array< real, 5 > ls{ rL, uL, vL, wL, eL };
-      std::array< real, 5 > rs{ rR, uR, vR, wR, eR };
-      auto url = ls;
-      auto urr = rs;
-
-      // MUSCL reconstruction of edge-end-point primitive variables
-      for (std::size_t c=0; c<5; ++c) {
-        // gradients
-        std::array< real, 3 > g1{ G(p,c*3+0), G(p,c*3+1), G(p,c*3+2) },
-                              g2{ G(q,c*3+0), G(q,c*3+1), G(q,c*3+2) };
-
-        delta2[c] = rs[c] - ls[c];
-        delta1[c] = 2.0 * tk::dot(g1,vw) - delta2[c];
-        delta3[c] = 2.0 * tk::dot(g2,vw) - delta2[c];
-
-        // MUSCL extrapolation option 1:
-        // ---------------------------------------------------------------------
-        // Uncomment the following 3 blocks of code if this version is required.
-        // this reconstruction is from the following paper:
-        // Waltz, J., Morgan, N. R., Canfield, T. R., Charest, M. R.,
-        // Risinger, L. D., & Wohlbier, J. G. (2014). A three-dimensional
-        // finite element arbitrary Lagrangian–Eulerian method for shock
-        // hydrodynamics on unstructured grids. Computers & Fluids, 92,
-        // 172-187.
-
-        //// form limiters
-        //auto rcL = (delta2[c] + muscl_eps) / (delta1[c] + muscl_eps);
-        //auto rcR = (delta2[c] + muscl_eps) / (delta3[c] + muscl_eps);
-        //auto rLinv = (delta1[c] + muscl_eps) / (delta2[c] + muscl_eps);
-        //auto rRinv = (delta3[c] + muscl_eps) / (delta2[c] + muscl_eps);
-
-        //// van Leer limiter
-        //// any other symmetric limiter could be used instead too
-        //auto phiL = (std::abs(rcL) + rcL) / (std::abs(rcL) + 1.0);
-        //auto phiR = (std::abs(rcR) + rcR) / (std::abs(rcR) + 1.0);
-        //auto phi_L_inv = (std::abs(rLinv) + rLinv) / (std::abs(rLinv) + 1.0);
-        //auto phi_R_inv = (std::abs(rRinv) + rRinv) / (std::abs(rRinv) + 1.0);
-
-        //// update unknowns with reconstructed unknowns
-        //url[c] += 0.25*(delta1[c]*muscl_m1*phiL + delta2[c]*muscl_p1*phi_L_inv);
-        //urr[c] -= 0.25*(delta3[c]*muscl_m1*phiR + delta2[c]*muscl_p1*phi_R_inv);
-
-        // ---------------------------------------------------------------------
-
-        // MUSCL extrapolation option 2:
-        // ---------------------------------------------------------------------
-        // The following 2 blocks of code.
-        // this reconstruction is from the following paper:
-        // Luo, H., Baum, J. D., & Lohner, R. (1994). Edge-based finite element
-        // scheme for the Euler equations. AIAA journal, 32(6), 1183-1190.
-        // Van Leer, B. (1974). Towards the ultimate conservative difference
-        // scheme. II. Monotonicity and conservation combined in a second-order
-        // scheme. Journal of computational physics, 14(4), 361-370.
-
-        // get Van Albada limiter
-        // the following form is derived from the flux limiter phi as:
-        // s = phi_inv - (1 - phi)
-        auto sL = std::max(0.0, (2.0*delta1[c]*delta2[c] + muscl_eps)
-          /(delta1[c]*delta1[c] + delta2[c]*delta2[c] + muscl_eps));
-        auto sR = std::max(0.0, (2.0*delta3[c]*delta2[c] + muscl_eps)
-          /(delta3[c]*delta3[c] + delta2[c]*delta2[c] + muscl_eps));
-
-        // update unknowns with reconstructed unknowns
-        url[c] += 0.25*sL*(delta1[c]*(1.0-muscl_const*sL)
-          + delta2[c]*(1.0+muscl_const*sL));
-        urr[c] -= 0.25*sR*(delta3[c]*(1.0-muscl_const*sR)
-          + delta2[c]*(1.0+muscl_const*sR));
-
-        // ---------------------------------------------------------------------
-      }
-
-      // force first order if the reconstructions for density or internal energy
-      // would have allowed negative values
-      if (ls[0] < delta1[0] || ls[4] < delta1[4]) url = ls;
-      if (rs[0] < -delta3[0] || rs[4] < -delta3[4]) urr = rs;
-
-      rL = url[0];
-      uL = url[1];
-      vL = url[2];
-      wL = url[3];
-      eL = url[4];
-
-      rR = urr[0];
-      uR = urr[1];
-      vR = urr[2];
-      wR = urr[3];
-      eR = urr[4];
-    }
-
-    //! Compute boundary integrals for ALECG
-    //! \param[in] coord Mesh node coordinates
-    //! \param[in] triinpoel Boundary triangle face connecitivity with local ids
-    //! \param[in] symbctri Vector with 1 at symmetry BC boundary triangles
-    //! \param[in] U Solution vector at recent time step
-    //! \param[in] W Mesh velocity
-    //! \param[in,out] R Right-hand side vector computed
-    void bndint( const std::array< std::vector< real >, 3 >& coord,
-                 const std::vector< std::size_t >& triinpoel,
-                 const std::vector< int >& symbctri,
-                 const tk::Fields& U,
-                 const tk::Fields& W,
-                 tk::Fields& R ) const
-    {
-
-      // access node coordinates
-      const auto& x = coord[0];
-      const auto& y = coord[1];
-      const auto& z = coord[2];
-
-      // boundary integrals: compute fluxes in edges
-      std::vector< real > bflux( triinpoel.size() * m_ncomp * 2 );
-
-      #pragma omp simd
-      for (std::size_t e=0; e<triinpoel.size()/3; ++e) {
-        // access node IDs
-        std::size_t N[3] =
-          { triinpoel[e*3+0], triinpoel[e*3+1], triinpoel[e*3+2] };
-        // access solution at element nodes
-        real rA  = U(N[0],0);
-        real rB  = U(N[1],0);
-        real rC  = U(N[2],0);
-        real ruA = U(N[0],1);
-        real ruB = U(N[1],1);
-        real ruC = U(N[2],1);
-        real rvA = U(N[0],2);
-        real rvB = U(N[1],2);
-        real rvC = U(N[2],2);
-        real rwA = U(N[0],3);
-        real rwB = U(N[1],3);
-        real rwC = U(N[2],3);
-        real reA = U(N[0],4);
-        real reB = U(N[1],4);
-        real reC = U(N[2],4);
-        real w1A = W(N[0],0);
-        real w2A = W(N[0],1);
-        real w3A = W(N[0],2);
-        real w1B = W(N[1],0);
-        real w2B = W(N[1],1);
-        real w3B = W(N[1],2);
-        real w1C = W(N[2],0);
-        real w2C = W(N[2],1);
-        real w3C = W(N[2],2);
-        // apply stagnation BCs
-        if ( stagPoint(x[N[0]],y[N[0]],z[N[0]]) )
-        {
-          ruA = rvA = rwA = 0.0;
-        }
-        if ( stagPoint(x[N[1]],y[N[1]],z[N[1]]) )
-        {
-          ruB = rvB = rwB = 0.0;
-        }
-        if ( stagPoint(x[N[2]],y[N[2]],z[N[2]]) )
-        {
-          ruC = rvC = rwC = 0.0;
-        }
-        // compute face normal
-        real nx, ny, nz;
-        tk::normal( x[N[0]], x[N[1]], x[N[2]],
-                    y[N[0]], y[N[1]], y[N[2]],
-                    z[N[0]], z[N[1]], z[N[2]],
-                    nx, ny, nz );
-        // compute boundary flux
-        real f[m_ncomp][3];
-        real p, vn;
-        int sym = symbctri[e];
-        p = m_mat_blk[0].compute< EOS::pressure >( rA, ruA/rA, rvA/rA, rwA/rA,
-          reA );
-        vn = sym ? 0.0 : (nx*(ruA/rA-w1A) + ny*(rvA/rA-w2A) + nz*(rwA/rA-w3A));
-        f[0][0] = rA*vn;
-        f[1][0] = ruA*vn + p*nx;
-        f[2][0] = rvA*vn + p*ny;
-        f[3][0] = rwA*vn + p*nz;
-        f[4][0] = reA*vn + p*(sym ? 0.0 : (nx*ruA + ny*rvA + nz*rwA)/rA);
-        p = m_mat_blk[0].compute< EOS::pressure >( rB, ruB/rB, rvB/rB, rwB/rB,
-          reB );
-        vn = sym ? 0.0 : (nx*(ruB/rB-w1B) + ny*(rvB/rB-w2B) + nz*(rwB/rB-w3B));
-        f[0][1] = rB*vn;
-        f[1][1] = ruB*vn + p*nx;
-        f[2][1] = rvB*vn + p*ny;
-        f[3][1] = rwB*vn + p*nz;
-        f[4][1] = reB*vn + p*(sym ? 0.0 : (nx*ruB + ny*rvB + nz*rwB)/rB);
-        p = m_mat_blk[0].compute< EOS::pressure >( rC, ruC/rC, rvC/rC, rwC/rC,
-          reC );
-        vn = sym ? 0.0 : (nx*(ruC/rC-w1C) + ny*(rvC/rC-w2C) + nz*(rwC/rC-w3C));
-        f[0][2] = rC*vn;
-        f[1][2] = ruC*vn + p*nx;
-        f[2][2] = rvC*vn + p*ny;
-        f[3][2] = rwC*vn + p*nz;
-        f[4][2] = reC*vn + p*(sym ? 0.0 : (nx*ruC + ny*rvC + nz*rwC)/rC);
-        // compute face area
-        auto A6 = tk::area( x[N[0]], x[N[1]], x[N[2]],
-                            y[N[0]], y[N[1]], y[N[2]],
-                            z[N[0]], z[N[1]], z[N[2]] ) / 6.0;
-        auto A24 = A6/4.0;
-        // store flux in boundary elements
-        for (std::size_t c=0; c<m_ncomp; ++c) {
-          auto eb = (e*m_ncomp+c)*6;
-          auto Bab = A24 * (f[c][0] + f[c][1]);
-          bflux[eb+0] = Bab + A6 * f[c][0];
-          bflux[eb+1] = Bab;
-          Bab = A24 * (f[c][1] + f[c][2]);
-          bflux[eb+2] = Bab + A6 * f[c][1];
-          bflux[eb+3] = Bab;
-          Bab = A24 * (f[c][2] + f[c][0]);
-          bflux[eb+4] = Bab + A6 * f[c][2];
-          bflux[eb+5] = Bab;
-        }
-      }
-
-      // access pointer to right hand side at component
-      std::array< const real*, m_ncomp > r;
-      for (ncomp_t c=0; c<m_ncomp; ++c) r[c] = R.cptr( c );
-
-      // boundary integrals: sum flux contributions to points
-      for (std::size_t e=0; e<triinpoel.size()/3; ++e)
-        for (std::size_t c=0; c<m_ncomp; ++c) {
-          auto eb = (e*m_ncomp+c)*6;
-          R.var(r[c],triinpoel[e*3+0]) -= bflux[eb+0] + bflux[eb+5];
-          R.var(r[c],triinpoel[e*3+1]) -= bflux[eb+1] + bflux[eb+2];
-          R.var(r[c],triinpoel[e*3+2]) -= bflux[eb+3] + bflux[eb+4];
-        }
-
-      tk::destroy(bflux);
-    }
-
-    //! Compute optional source integral
-    //! \param[in] coord Mesh node coordinates
-    //! \param[in] inpoel Mesh element connectivity
-    //! \param[in] t Physical time
-    //! \param[in] tp Physical time for each mesh node
-    //! \param[in,out] R Right-hand side vector computed
-    void src( const std::array< std::vector< real >, 3 >& coord,
-              const std::vector< std::size_t >& inpoel,
-              real t,
-              const std::vector< tk::real >& tp,
-              tk::Fields& R ) const
-    {
-      // access node coordinates
-      const auto& x = coord[0];
-      const auto& y = coord[1];
-      const auto& z = coord[2];
-
-      // access pointer to right hand side at component
-      std::array< const real*, m_ncomp > r;
-      for (ncomp_t c=0; c<m_ncomp; ++c) r[c] = R.cptr( c );
-
-      // source integral
-      for (std::size_t e=0; e<inpoel.size()/4; ++e) {
-        std::size_t N[4] =
-          { inpoel[e*4+0], inpoel[e*4+1], inpoel[e*4+2], inpoel[e*4+3] };
-        // compute element Jacobi determinant, J = 6V
-        auto J24 = tk::triple(
-          x[N[1]]-x[N[0]], y[N[1]]-y[N[0]], z[N[1]]-z[N[0]],
-          x[N[2]]-x[N[0]], y[N[2]]-y[N[0]], z[N[2]]-z[N[0]],
-          x[N[3]]-x[N[0]], y[N[3]]-y[N[0]], z[N[3]]-z[N[0]] ) / 24.0;
-        // sum source contributions to nodes
-        for (std::size_t a=0; a<4; ++a) {
-          std::vector< real > s(m_ncomp);
-          if (g_inputdeck.get< tag::steady_state >()) t = tp[N[a]];
-          Problem::src( 1, m_mat_blk, x[N[a]], y[N[a]], z[N[a]], t, s );
-          for (std::size_t c=0; c<m_ncomp; ++c)
-            R.var(r[c],N[a]) += J24 * s[c];
-        }
-      }
-    }
-
-    //! Compute sources corresponding to a propagating front in user-defined box
-    //! \param[in] V Total box volume
-    //! \param[in] t Physical time
-    //! \param[in] inpoel Element point connectivity
-    //! \param[in] esup Elements surrounding points
-    //! \param[in] boxnodes Mesh node ids within user-defined box
-    //! \param[in] coord Mesh node coordinates
-    //! \param[in] R Right-hand side vector
-    //! \details This function add the energy source corresponding to a planar
-    //!   wave-front propagating along the z-direction with a user-specified
-    //!   velocity, within a box initial condition, configured by the user.
-    //!   Example (SI) units of the quantities involved:
-    //!    * internal energy content (energy per unit volume): J/m^3
-    //!    * specific energy (internal energy per unit mass): J/kg
-    void boxSrc( real V,
-                 real t,
-                 const std::vector< std::size_t >& inpoel,
-                 const std::pair< std::vector< std::size_t >,
-                                  std::vector< std::size_t > >& esup,
-                 const std::unordered_set< std::size_t >& boxnodes,
-                 const std::array< std::vector< real >, 3 >& coord,
-                 tk::Fields& R ) const<--- Parameter 'R' can be declared with const
-    {
-      const auto& icbox = g_inputdeck.get< tag::ic, tag::box >();
-
-      if (!icbox.empty()) {
-        for (const auto& b : icbox) {   // for all boxes for this eq
-          std::vector< tk::real > box
-           { b.template get< tag::xmin >(), b.template get< tag::xmax >(),
-             b.template get< tag::ymin >(), b.template get< tag::ymax >(),
-             b.template get< tag::zmin >(), b.template get< tag::zmax >() };
-
-          auto boxenc = b.template get< tag::energy_content >();
-          Assert( boxenc > 0.0, "Box energy content must be nonzero" );
-
-          auto V_ex = (box[1]-box[0]) * (box[3]-box[2]) * (box[5]-box[4]);
-
-          // determine times at which sourcing is initialized and terminated
-          auto iv = b.template get< tag::front_speed >();
-          auto wFront = b.template get< tag::front_width >();
-          auto tInit = b.template get< tag::init_time >();
-          auto tFinal = tInit + (box[5] - box[4] - wFront) / std::fabs(iv);
-          auto aBox = (box[1]-box[0]) * (box[3]-box[2]);
-
-          const auto& x = coord[0];
-          const auto& y = coord[1];
-          const auto& z = coord[2];
-
-          if (t >= tInit && t <= tFinal) {
-            // The energy front is assumed to have a half-sine-wave shape. The
-            // half wave-length is the width of the front. At t=0, the center of
-            // this front (i.e. the peak of the partial-sine-wave) is at X_0 +
-            // W_0.  W_0 is calculated based on the width of the front and the
-            // direction of propagation (which is assumed to be along the
-            // z-direction).  If the front propagation velocity is positive, it
-            // is assumed that the initial position of the energy source is the
-            // minimum z-coordinate of the box; whereas if this velocity is
-            // negative, the initial position is the maximum z-coordinate of the
-            // box.
-
-            // Orientation of box
-            std::array< tk::real, 3 > b_orientn{{
-              b.template get< tag::orientation >()[0],
-              b.template get< tag::orientation >()[1],
-              b.template get< tag::orientation >()[2] }};
-            std::array< tk::real, 3 > b_centroid{{ 0.5*(box[0]+box[1]),
-              0.5*(box[2]+box[3]), 0.5*(box[4]+box[5]) }};
-            // Transform box to reference space
-            std::array< tk::real, 3 > b_min{{box[0], box[2], box[4]}};
-            std::array< tk::real, 3 > b_max{{box[1], box[3], box[5]}};
-            tk::movePoint(b_centroid, b_min);
-            tk::movePoint(b_centroid, b_max);
-
-            // initial center of front
-            tk::real zInit(b_min[2]);
-            if (iv < 0.0) zInit = b_max[2];
-            // current location of front
-            auto z0 = zInit + iv * (t-tInit);
-            auto z1 = z0 + std::copysign(wFront, iv);
-            tk::real s0(z0), s1(z1);
-            // if velocity of propagation is negative, initial position is z1
-            if (iv < 0.0) {
-              s0 = z1;
-              s1 = z0;
-            }
-            // Sine-wave (positive part of the wave) source term amplitude
-            auto pi = 4.0 * std::atan(1.0);
-            auto amplE = boxenc * V_ex * pi
-              / (aBox * wFront * 2.0 * (tFinal-tInit));
-            //// Square wave (constant) source term amplitude
-            //auto amplE = boxenc * V_ex
-            //  / (aBox * wFront * (tFinal-tInit));
-            //// arbitrary shape form
-            //auto amplE = boxenc * std::abs(iv) / wFront;
-            amplE *= V_ex / V;
-
-            // add source
-            for (auto p : boxnodes) {
-              std::array< tk::real, 3 > node{{ x[p], y[p], z[p] }};
-              // Transform node to reference space of box
-              tk::movePoint(b_centroid, node);
-              tk::rotatePoint({{-b_orientn[0], -b_orientn[1], -b_orientn[2]}},
-                node);
-
-              if (node[2] >= s0 && node[2] <= s1) {
-                auto S = amplE * std::sin(pi*(node[2]-s0)/wFront);
-                //// arbitrary shape form
-                //auto S = amplE;
-                for (auto e : tk::Around(esup,p)) {
-                  // access node IDs
-                  std::size_t N[4] =
-                    {inpoel[e*4+0], inpoel[e*4+1], inpoel[e*4+2], inpoel[e*4+3]};
-                  // compute element Jacobi determinant, J = 6V
-                  real bax = x[N[1]]-x[N[0]];
-                  real bay = y[N[1]]-y[N[0]];
-                  real baz = z[N[1]]-z[N[0]];
-                  real cax = x[N[2]]-x[N[0]];
-                  real cay = y[N[2]]-y[N[0]];
-                  real caz = z[N[2]]-z[N[0]];
-                  real dax = x[N[3]]-x[N[0]];
-                  real day = y[N[3]]-y[N[0]];
-                  real daz = z[N[3]]-z[N[0]];
-                  auto J =
-                    tk::triple( bax, bay, baz, cax, cay, caz, dax, day, daz );
-                  auto J24 = J/24.0;
-                  R(p,4) += J24 * S;
-                }
-              }
-            }
-          }
-        }
-      }
-    }
-
-};
-
-} // cg::
-
-} // inciter::
-
-#endif // CGCompFlow_h
+#endif // DGPDE_h
 
diff --git a/Release/cppcheck/5.html b/Release/cppcheck/5.html index 9001e5504c58..b38f3ea5b682 100644 --- a/Release/cppcheck/5.html +++ b/Release/cppcheck/5.html @@ -152,12 +152,12 @@
  1
@@ -278,549 +278,125 @@ 

Cppcheck report - [

// *****************************************************************************
+119
// *****************************************************************************
 /*!
-  \file      src/Base/ContainerUtil.hpp
+  \file      src/Inciter/DiagReducer.cpp
   \copyright 2012-2015 J. Bakosi,
              2016-2018 Los Alamos National Security, LLC.,
              2019-2021 Triad National Security, LLC.
              All rights reserved. See the LICENSE file for details.
-  \brief     Various STL container utilities
-  \details   Various STL container utilities.
+  \brief     Custom Charm++ reducer for merging std::vectors across PEs
+  \details   Custom Charm++ reducer for merging std::vectors across PEs.
 */
 // *****************************************************************************
-#ifndef ContainerUtil_h
-#define ContainerUtil_h
-
-#include <vector>
-#include <map>
-#include <set>
-#include <algorithm>
-#include <iterator>
-#include <unordered_set>
-#include <unordered_map>
-#include <type_traits>
-#include <sstream>
-
-#include "Exception.hpp"
-
-namespace tk {
-
-//! Make elements of container unique (in-place, overwriting source container)
-//! \param[in,out] c Container
-template< class Container >
-void
-unique( Container& c )
-{
-  std::sort( begin(c), end(c) );
-  auto it = std::unique( begin(c), end(c) );
-  auto d = std::distance( begin(c), it );
-  Assert( d >= 0, "Distance must be non-negative in tk::unique()" );<--- Unsigned positive
-  c.resize( static_cast< std::size_t >( d ) );
-}
+
+#include <stddef.h>
+#include <type_traits>
+#include <memory>
+
+#include "DiagReducer.hpp"
+#include "Diagnostics.hpp"
+#include "Exception.hpp"
+
+namespace inciter {
+
+std::pair< int, std::unique_ptr<char[]> >
+serialize( std::size_t meshid,
+           std::size_t ncomp,
+           const std::vector< std::vector< tk::real > >& d )
+// *****************************************************************************
+// Serialize std::vectors to raw memory stream
+//! \param[in] meshid Mesh ID
+//! \param[in] ncomp Number of scalar components being solved
+//! \param[in] d Diagnostics vector of vectors (of eq components)
+//! \return Pair of the length and the raw stream containing the serialized
+//!   vectors
+// *****************************************************************************
+{
+  // Prepare for serializing diagnostics to a raw binary stream, compute size
+  PUP::sizer sizer;
+  sizer | meshid;
+  sizer | ncomp;
+  sizer | const_cast< std::vector< std::vector< tk::real > >& >( d );
 
-//! Make elements of container unique (on a copy, leaving the source as is)
-//! \param[in] src Container
-//! \return Container containing only unique elements compared to src
-template< class Container >
-Container
-uniquecopy( const Container& src )
-{
-  auto c = src;
-  unique( c );
-  return c;
-}
-
-//! \brief Find and return a constant reference to value for key in container
-//!   that provides a find() member function with error handling
-//! \param[in] map Map associating values to keys
-//! \param[in] key Key to search for
-//! \return A constant reference to the value associated to the key in map
-//! \note If key is not found an exception is thrown.
-template< typename Container >
-auto cref_find( const Container& map, const typename Container::key_type& key )
-noexcept(ndebug)
-  -> const typename Container::mapped_type&
+  // Create raw character stream to store the serialized vectors
+  std::unique_ptr<char[]> flatData = std::make_unique<char[]>( sizer.size() );
+
+  // Serialize vector, each message will contain a vector
+  PUP::toMem packer( flatData.get() );
+  packer | meshid;
+  packer | ncomp;
+  packer | const_cast< std::vector< std::vector< tk::real > >& >( d );
+
+  // Return size of and raw stream
+  return { sizer.size(), std::move(flatData) };
+}
+
+CkReductionMsg*
+mergeDiag( int nmsg, CkReductionMsg **msgs )
+// *****************************************************************************
+// Charm++ custom reducer for merging diagnostics during reduction across PEs
+//! \param[in] nmsg Number of messages in msgs
+//! \param[in] msgs Charm++ reduction message containing the serialized
+//!   diagnostics
+//! \return Aggregated diagnostics built for further aggregation if needed
+// *****************************************************************************
 {
-  const auto it = map.find( key );
-  Assert( it != end(map), "Can't find key" );<--- Exception thrown in function declared not to throw exceptions.
-  return it->second;
-}
-
-//! \brief Find and return a reference to value for key in a container that
-//!   provides a find() member function with error handling
-//! \param[in] map Map associating values to keys
-//! \param[in] key Key to search for
-//! \return A reference to the value associated to the key in map
-//! \note If key is not found an exception is thrown.
-template< typename Container >
-auto ref_find( const Container& map, const typename Container::key_type& key )
-noexcept(ndebug)
-  -> typename Container::mapped_type&
-{
-  return const_cast< typename Container::mapped_type& >( cref_find(map,key) );<--- Exception thrown in function declared not to throw exceptions.
-}
-
-//! \brief Return minimum and maximum values of a vector
-//! \param[in] vec Vector whose extents to compute
-//! \return Array of two values with the minimum and maximum values
-//! \note This function should not be called with heavy T types, as the a copy
-//!   of a std::array< T, 2 > is created and returned.
-template< typename T >
-std::array< T, 2 >
-extents( const std::vector< T >& vec )
-{
-  auto x = std::minmax_element( begin(vec), end(vec) );
-  return {{ *x.first, *x.second }};
-}
-
-//! \brief Find and return minimum and maximum values in associative container
-//! \param[in] map Map whose extents of values to find 
-//! \return Array of two values with the minimum and maximum values in the map
-//! \note This function should not be called with heavy Value types, as the a
-//!   copy of a std::array< Value, 2 > is created and returned.
-template< typename Container >
-auto extents( const Container& map )
-  -> std::array< typename Container::mapped_type, 2 >
-{
-  auto x = std::minmax_element( begin(map), end(map),
-             []( const auto& a, const auto& b )
-             { return a.second < b.second; } );
-  return {{ x.first->second, x.second->second }};
-}
+  std::size_t meshid, ncomp;
+  std::vector< std::vector< tk::real > > v;
+
+  // Create PUP deserializer based on message passed in
+  PUP::fromMem creator( msgs[0]->getData() );
+
+  // Deserialize vector from raw stream
+  creator | meshid;<--- Uninitialized variable: meshid
+  creator | ncomp;<--- Uninitialized variable: ncomp
+  creator | v;
+
+  for (int m=1; m<nmsg; ++m) {
+    // Unpack vector
+    std::size_t mid, nc;
+    std::vector< std::vector< tk::real > > w;
+    PUP::fromMem curCreator( msgs[m]->getData() );
+    curCreator | mid;<--- Uninitialized variable: mid
+    curCreator | nc;<--- Uninitialized variable: nc
+    curCreator | w;
+    // Aggregate diagnostics vector
+    meshid = mid;<--- Uninitialized variable: mid<--- Variable 'meshid' is assigned a value that is never used.
+    ncomp = nc;<--- Uninitialized variable: nc<--- Variable 'ncomp' is assigned a value that is never used.
+    Assert( v.size() == w.size(),
+            "Size mismatch during diagnostics aggregation" );
+    Assert( v.size() == inciter::NUMDIAG,
+            "Size mismatch during diagnostics aggregation" );
+    for (std::size_t i=0; i<v.size(); ++i)<--- Unsigned less than zero
+      Assert( v[i].size() == w[i].size(),
+              "Size mismatch during diagnostics aggregation" );
+    // Apply diagnostics aggregation policy
+    // Sum for L2 normal of the numerical solution for all scalar components
+    for (std::size_t i=0; i<v[L2SOL].size(); ++i) v[L2SOL][i] += w[L2SOL][i];
+    // Sum for the L2 norm of the numerical - analytical solution for all comps
+    for (std::size_t i=0; i<v[L2ERR].size(); ++i) v[L2ERR][i] += w[L2ERR][i];
+    // Sum for the L2 norm of the residual of all components
+    for (std::size_t i=0; i<v[L2RES].size(); ++i) v[L2RES][i] += w[L2RES][i];
+    // Max for the Linf norm of the numerical - analytical solution for all comp
+    for (std::size_t i=0; i<v[LINFERR].size(); ++i)
+      if (w[LINFERR][i] > v[LINFERR][i]) v[LINFERR][i] = w[LINFERR][i];
+    // Sum of the total energy over the entire domain
+    v[TOTALSOL][0] += w[TOTALSOL][0];
+    // Copy ITER, TIME, DT
+    for (std::size_t j=v.size()-3; j<v.size(); ++j)
+      for (std::size_t i=0; i<v[j].size(); ++i)
+        v[j][i] = w[j][i];
+  }
 
-//! Add all elements of an array to those of another one
-//! \param[in,out] dst Destination array, i.e., left-hand side of a1 += a2
-//! \param[in] src Source array, i.e., righ-hand side of a1 += a2
-//! \return Destination containing a1[0] += a2[0], a1[1] += a2[1], ...
-template< class T, std::size_t N >
-std::array< T, N >&
-operator+=( std::array< T, N >& dst, const std::array< T, N >& src ) {
-  std::transform( src.cbegin(), src.cend(), dst.begin(), dst.begin(),
-                  []( const T& s, T& d ){ return d += s; } );
-  return dst;
-}
-
-//! Add all elements of a vector to those of another one
-//! \param[in,out] dst Destination vector, i.e., left-hand side of v1 += v2
-//! \param[in] src Source vector, i.e., righ-hand side of v1 += v2
-//! \return Destination containing v1[0] += v2[0], v1[1] += v2[1], ...
-//! \details If src.size() > dst.size() will grow dst to that of src.size()
-//!   padding with zeros.
-//! \note Will throw exception in DEBUG if src is empty (to warn on no-op), and
-//!   if src.size() < dst.size() (to warn on loosing data).
-template< class T, class Allocator >
-std::vector< T, Allocator >&
-operator+=( std::vector< T, Allocator >& dst,
-            const std::vector< T, Allocator >& src )
-{
-  Assert( !src.empty(), "src empty in std::vector<T,Allocator>::operator+=()" );
-  Assert( src.size() >= dst.size(), "src.size() < dst.size() would loose data "
-          "in std::vector<T,Allocator>::operator+=()" );
-  dst.resize( src.size() );
-  std::transform( src.cbegin(), src.cend(), dst.begin(), dst.begin(),
-                  []( const T& s, T& d ){ return d += s; } );
-  return dst;
-}
-
-//! Divide all elements of a vector with those of another one
-//! \param[in,out] dst Destination vector, i.e., left-hand side of v1 /= v2
-//! \param[in] src Source vector, i.e., righ-hand side of v1 /= v2
-//! \return Destination containing v1[0] /= v2[0], v1[1] /= v2[1], ...
-//! \details If src.size() > dst.size() will grow dst to that of src.size()
-//!   padding with zeros.
-//! \note Will throw exception in DEBUG if src is empty (to warn on no-op), and
-//!   if src.size() < dst.size() (to warn on loosing data).
-template< class T, class Allocator >
-std::vector< T, Allocator >&
-operator/=( std::vector< T, Allocator >& dst,
-            const std::vector< T, Allocator >& src )
-{
-  Assert( !src.empty(), "src empty in std::vector<T,Allocator>::operator/=()" );
-  Assert( src.size() >= dst.size(), "src.size() < dst.size() would loose data "
-          "in std::vector<T,Allocator>::operator/=()" );
-  dst.resize( src.size() );
-  std::transform( src.cbegin(), src.cend(), dst.begin(), dst.begin(),
-                  []( const T& s, T& d ){ return d /= s; } );
-  return dst;
-}
-
-//! Test if all keys of two associative containers are equal
-//! \param[in] a 1st container to compare
-//! \param[in] b 2nd container to compare
-//! \return True if the containers have the same size and all keys (and only the
-//!   keys) of the two containers are equal
-//! \note It is an error to call this function with unequal-size containers,
-//!   triggering an exception in DEBUG mode.
-//! \note Operator != is used to compare the container keys.
-template< class C1, class C2 >
-bool keyEqual( const C1& a, const C2& b ) {
-  Assert( a.size() == b.size(), "Size mismatch comparing containers" );
-  std::set< typename C1::key_type > sorted_keys_of_a;
-  for (const auto& c : a) sorted_keys_of_a.insert( c.first );
-  std::set< typename C2::key_type > sorted_keys_of_b;
-  for (const auto& c : b) sorted_keys_of_b.insert( c.first );
-  return sorted_keys_of_a == sorted_keys_of_b;
-}
-
-//! Compute the sum of the sizes of a container of containers
-//! \param[in] c Container of containers
-//! \return Sum of the sizes of the containers of the container
-template< class Container >
-std::size_t sumsize( const Container& c ) {
-  std::size_t sum = 0;
-  // cppcheck-suppress useStlAlgorithm
-  for (const auto& s : c) sum += s.size();
-  return sum;
-}
-
-//! Compute the number of unique values in a container of containers
-//! \param[in] c Container of containers
-//! \return Number of unique values in a container of containers
-template< class Container >
-std::size_t numunique( const Container& c ) {
-  using value_type = typename Container::value_type::value_type;
-  static_assert( std::is_integral<value_type>::value,
-    "Container::value_type::value_type must be an integral type." );
-  std::unordered_set< value_type > u;
-  for (const auto& r : c) u.insert( begin(r), end(r) );
-  return u.size();
-}
-
-//! Compute the sum of the sizes of the values of an associative container
-//! \tparam Map Container of containers type
-//! \param[in] c Container of containers
-//! \return Sum of the sizes of the values of the associative container
-template< class Map >
-std::size_t sumvalsize( const Map& c ) {
-  std::size_t sum = 0;
-  // cppcheck-suppress useStlAlgorithm
-  for (const auto& s : c) sum += s.second.size();
-  return sum;
-}
-
-//! Free memory of a container
-//! \param[in] c Container defining a swap() member function
-//! \details See http://stackoverflow.com/a/10465032 as to why this is done with
-//!   the swap() member function of the container.
-//! \see Specializations of std::swap are documented at
-//!   http://en.cppreference.com/w/cpp/algorithm/swap
-template< class Container >
-void destroy( Container& c ) {
-  typename std::remove_reference< decltype(c) >::type().swap( c );
-}
-
-//! Remove items from container based on predicate
-//! \tparam Container Type of container to remove from
-//! \tparam Predicate Type for functor defining the predicate
-//! \param items Container object to remove from
-//! \param predicate Predicate object instance to use
-template< typename Container, typename Predicate >
-void erase_if( Container& items, const Predicate& predicate ) {
-  for ( auto it = items.begin(); it != items.end(); ) {
-    if ( predicate(*it) ) it = items.erase(it);
-    else ++it;
-  }
-}
-
-//! Concatenate vectors of T
-//! \tparam T Vector value type
-//! \param[in,out] src Source vector (moved from)
-//! \param[in,out] dst Destination vector
-template< class T >
-void concat( std::vector< T >&& src, std::vector< T >& dst )
-{
-  if (dst.empty())
-    dst = std::move(src);
-  else {
-    dst.reserve( dst.size() + src.size() );
-    std::move( std::begin(src), std::end(src), std::back_inserter(dst) );
-    src.clear();
-  }
-}
-
-//! Overwrite vectors of pair< bool, tk::real >
-//! \tparam T Vector value type
-//! \param[in,out] src Source vector (moved from)
-//! \param[in,out] dst Destination vector
-template< class T >
-void concat( std::vector< std::pair< bool, T > >&& src,
-             std::vector< std::pair< bool, T > >& dst )
-{
-  dst = std::move(src);
-}
-
-//! Concatenate unordered sets
-//! \tparam Key Set key
-//! \tparam Hash Set hasher
-//! \tparam Eq Set equality operator
-//! \param[in,out] src Source set (moved from)
-//! \param[in,out] dst Destination set
-template< class Key,
-          class Hash = std::hash< Key >,
-          class Eq = std::equal_to< Key > >
-void concat( std::unordered_set< Key, Hash,Eq >&& src,
-             std::unordered_set< Key, Hash, Eq >& dst )
-{
-  if (dst.empty())
-    dst = std::move(src);
-  else {
-    dst.reserve( dst.size() + src.size() );
-    std::move( std::begin(src), std::end(src), std::inserter(dst,end(dst)) );
-    src.clear();
-  }
-}
-
-//! Operator << for writing value_type of a standard map to output streams
-//! \param[in,out] os Output stream to write to
-//! \param[in] v value_type entry of a map
-//! \return Updated output stream
-template< class Key, class Value >
-std::ostream&
-operator<< ( std::ostream& os, const std::pair< const Key, Value  >& v ) {
-  os << v.first << ':' << v.second;
-  return os;
-}
-
-//! \brief Convert and return value as string
-//! \tparam T Value type for input
-//! \param[in] v Value for input to return as a string
-//! \return String for input value
-template< typename T >
-std::string parameter( const T& v ) {
-  std::stringstream s;
-  s << v;
-  return s.str();
-}
-
-//! \brief Convert and return values from container as string
-//! \tparam V Container range for works on
-//! \param[in] v Container whose components to return as a string
-//! \return Concatenated string of values read from a container
-template< typename V >
-std::string parameters( const V& v ) {
-  std::stringstream s;
-  s << "{ ";
-  for (auto p : v) s << p << ' ';
-  s << "}";
-  return s.str();
-}
-
-} // tk::
-
-#endif // ContainerUtil_h
+  // Serialize concatenated diagnostics vector to raw stream
+  auto stream = serialize( meshid, ncomp, v );
+
+  // Forward serialized diagnostics
+  return CkReductionMsg::buildNew( stream.first, stream.second.get() );
+}
+
+} // inciter::
 
diff --git a/Release/cppcheck/50.html b/Release/cppcheck/50.html index 03ef9c9350d0..25f5d029374b 100644 --- a/Release/cppcheck/50.html +++ b/Release/cppcheck/50.html @@ -152,349 +152,2985 @@
- - + @@ -99,23 +99,23 @@ 25 : : 26 : : // Constructors 27 : : edge_t() - 28 [ - + ]: 1791089 : { + 28 [ - + ]: 1791643 : { 29 : : } 30 : : - 31 [ + + ][ + - ]: 30442500 : edge_t(size_t A, size_t B) : data( {{std::min(A,B), std::max(A,B)}} ) + 31 [ + + ][ + - ]: 30445518 : edge_t(size_t A, size_t B) : data( {{std::min(A,B), std::max(A,B)}} ) [ + - ][ - + ] [ + + ][ + - ] [ + + ][ + - ] - [ + + ][ + + ] - [ + + ][ + + ] - [ + + ][ + + ] - [ + + ][ + + ] - [ + + ][ + + ] - [ + + ][ + + ] + [ + + ][ + + ] + [ + + ][ + + ] + [ + + ][ + + ] + [ + + ][ + + ] + [ + + ][ + + ] + [ + + ][ + + ] [ + + ][ + + ] [ + + ][ + + ] [ + + ][ + + ] - [ + + ] + [ + + ] 32 : : { 33 : : } 34 : : @@ -143,22 +143,22 @@ 55 : : //{ 56 : : // return (data > rhs.get_data()); 57 : : //} - 58 : 928946792 : bool operator<(const edge_t& rhs) const + 58 : 928936570 : bool operator<(const edge_t& rhs) const 59 : : { 60 : : // ensure entries of rhs and this are in ascending order - 61 [ - + ]: 928946792 : auto this_copy = this->data; - 62 [ + - ]: 928946792 : this_copy[0] = std::min(this->data[0], this->data[1]); - 63 [ - + ]: 928946792 : this_copy[1] = std::max(this->data[0], this->data[1]); + 61 [ - + ]: 928936570 : auto this_copy = this->data; + 62 [ + - ]: 928936570 : this_copy[0] = std::min(this->data[0], this->data[1]); + 63 [ - + ]: 928936570 : this_copy[1] = std::max(this->data[0], this->data[1]); 64 : : std::array< std::size_t, 2 > rhs_copy; - 65 [ + - ]: 928946792 : rhs_copy[0] = std::min(rhs.get_data()[0], rhs.get_data()[1]); - 66 : 928946792 : rhs_copy[1] = std::max(rhs.get_data()[0], rhs.get_data()[1]); + 65 [ + - ]: 928936570 : rhs_copy[0] = std::min(rhs.get_data()[0], rhs.get_data()[1]); + 66 : 928936570 : rhs_copy[1] = std::max(rhs.get_data()[0], rhs.get_data()[1]); 67 : : - 68 [ + + ]: 928946792 : if (this_copy[0] < rhs_copy[0]) + 68 [ + + ]: 928936570 : if (this_copy[0] < rhs_copy[0]) 69 : : return true; - 70 [ + + ][ + + ]: 606408518 : else if (this_copy[0] == rhs_copy[0] && this_copy[1] < rhs_copy[1]) + 70 [ + + ][ + + ]: 606668423 : else if (this_copy[0] == rhs_copy[0] && this_copy[1] < rhs_copy[1]) 71 : : return true; 72 : : else - 73 : 490475656 : return false; + 73 : 490720329 : return false; 74 : : } 75 : : 76 : : size_t first() const diff --git a/Release/test_coverage/Inciter/AMR/edge_store.hpp.func-sort-c.html b/Release/test_coverage/Inciter/AMR/edge_store.hpp.func-sort-c.html index 55ef7a3463bc..83fc3d0c4639 100644 --- a/Release/test_coverage/Inciter/AMR/edge_store.hpp.func-sort-c.html +++ b/Release/test_coverage/Inciter/AMR/edge_store.hpp.func-sort-c.html @@ -33,7 +33,7 @@ - + diff --git a/Release/test_coverage/Inciter/AMR/edge_store.hpp.func.html b/Release/test_coverage/Inciter/AMR/edge_store.hpp.func.html index 1baabbec5387..b1952ba0b17e 100644 --- a/Release/test_coverage/Inciter/AMR/edge_store.hpp.func.html +++ b/Release/test_coverage/Inciter/AMR/edge_store.hpp.func.html @@ -33,7 +33,7 @@ - + diff --git a/Release/test_coverage/Inciter/AMR/edge_store.hpp.gcov.html b/Release/test_coverage/Inciter/AMR/edge_store.hpp.gcov.html index 22de367487d7..8756ca5a3335 100644 --- a/Release/test_coverage/Inciter/AMR/edge_store.hpp.gcov.html +++ b/Release/test_coverage/Inciter/AMR/edge_store.hpp.gcov.html @@ -33,7 +33,7 @@ - + @@ -132,7 +132,7 @@ 58 : : * @param B Second node 59 : : * @param lc Lock case for new edge 60 : : */ - 61 [ + + ]: 1136292 : void generate(size_t A, size_t B, Edge_Lock_Case lc) + 61 [ + + ]: 1136292 : void generate(size_t A, size_t B, Edge_Lock_Case lc) 62 : : { 63 : : if ((A != 0) && (B != 0)) { 64 : : trace_out << "A " << A << " B " << B << std::endl; @@ -349,24 +349,24 @@ 275 : 4347936 : size_t A = tet[0]; 276 : 4347936 : size_t B = tet[1]; 277 : 4347936 : size_t C = tet[2]; - 278 [ + + ]: 4347936 : size_t D = tet[3]; + 278 [ + + ]: 4347936 : size_t D = tet[3]; 279 : : 280 : : edge_t key; 281 : : 282 : : key = nodes_to_key(A,B); - 283 [ + + ]: 4347936 : key_list[0] = key; + 283 [ + + ]: 4347936 : key_list[0] = key; 284 : : 285 : : key = nodes_to_key(A,C); - 286 [ + + ]: 4347936 : key_list[1] = key; + 286 [ + + ]: 4347936 : key_list[1] = key; 287 : : 288 : : key = nodes_to_key(A,D); - 289 [ + + ]: 4347936 : key_list[2] = key; + 289 [ + + ]: 4347936 : key_list[2] = key; 290 : : 291 : : key = nodes_to_key(B,C); - 292 [ + + ]: 4347936 : key_list[3] = key; + 292 [ + + ]: 4347936 : key_list[3] = key; 293 : : 294 : : key = nodes_to_key(B,D); - 295 [ + + ]: 4347936 : key_list[4] = key; + 295 [ + + ]: 4347936 : key_list[4] = key; 296 : : 297 : : key = nodes_to_key(C,D); 298 : 4347936 : key_list[5] = key; diff --git a/Release/test_coverage/Inciter/AMR/id_generator.hpp.func-sort-c.html b/Release/test_coverage/Inciter/AMR/id_generator.hpp.func-sort-c.html index 055534ecf199..1553135c0bba 100644 --- a/Release/test_coverage/Inciter/AMR/id_generator.hpp.func-sort-c.html +++ b/Release/test_coverage/Inciter/AMR/id_generator.hpp.func-sort-c.html @@ -33,7 +33,7 @@ - + diff --git a/Release/test_coverage/Inciter/AMR/id_generator.hpp.func.html b/Release/test_coverage/Inciter/AMR/id_generator.hpp.func.html index c335367e1f6e..45a71bb9d6c5 100644 --- a/Release/test_coverage/Inciter/AMR/id_generator.hpp.func.html +++ b/Release/test_coverage/Inciter/AMR/id_generator.hpp.func.html @@ -33,7 +33,7 @@ - + diff --git a/Release/test_coverage/Inciter/AMR/id_generator.hpp.gcov.html b/Release/test_coverage/Inciter/AMR/id_generator.hpp.gcov.html index 09ed35d1337c..81ce87ba3131 100644 --- a/Release/test_coverage/Inciter/AMR/id_generator.hpp.gcov.html +++ b/Release/test_coverage/Inciter/AMR/id_generator.hpp.gcov.html @@ -33,7 +33,7 @@ - + diff --git a/Release/test_coverage/Inciter/AMR/index-sort-b.html b/Release/test_coverage/Inciter/AMR/index-sort-b.html index 9fb985a1c406..8af1b6cd3984 100644 --- a/Release/test_coverage/Inciter/AMR/index-sort-b.html +++ b/Release/test_coverage/Inciter/AMR/index-sort-b.html @@ -33,7 +33,7 @@ - + diff --git a/Release/test_coverage/Inciter/AMR/index-sort-f.html b/Release/test_coverage/Inciter/AMR/index-sort-f.html index 18e0797a49cb..40f1d0a60718 100644 --- a/Release/test_coverage/Inciter/AMR/index-sort-f.html +++ b/Release/test_coverage/Inciter/AMR/index-sort-f.html @@ -33,7 +33,7 @@ - + @@ -154,7 +154,7 @@ - + @@ -162,11 +162,11 @@ - - + + - + @@ -174,8 +174,8 @@ - - + + @@ -189,6 +189,18 @@ + + + + + + + + + + - + - - - - - + + + + + - + - + + + - - @@ -249,18 +261,6 @@ - - - - - - - - - - - + @@ -190,7 +190,7 @@ - + @@ -198,11 +198,11 @@ - - + + - + @@ -210,8 +210,8 @@ - - + + @@ -250,28 +250,28 @@ - + - - - + + + - + - - - + + +
  1
-  2
-  3
-  4
-  5
-  6
-  7
-  8
-  9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
- 37
- 38
- 39
- 40
- 41
- 42
- 43
- 44
- 45
- 46
- 47
- 48
- 49
- 50
- 51
- 52
- 53
- 54
- 55
- 56
- 57
- 58
- 59
- 60
- 61
- 62
- 63
- 64
- 65
- 66
- 67
- 68
- 69
- 70
- 71
- 72
- 73
- 74
- 75
- 76
- 77
- 78
- 79
- 80
- 81
- 82
- 83
- 84
- 85
- 86
- 87
- 88
- 89
- 90
- 91
- 92
- 93
- 94
- 95
- 96
- 97
- 98
- 99
-100
-101
-102
-103
-104
-105
-106
-107
-108
-109
-110
-111
-112
-113
-114
-115
-116
-117
-118
-119
-120
-121
-122
-123
-124
-125
-126
-127
-128
-129
-130
-131
-132
-133
-134
-135
-136
-137
-138
-139
-140
-141
-142
-143
-144
-145
-146
-147
-148
-149
-150
-151
-152
-153
-154
-155
-156
-157
-158
-159
-160
-161
-162
-163
-164
-165
-166
-167
-168
// *****************************************************************************
+
   1
+   2
+   3
+   4
+   5
+   6
+   7
+   8
+   9
+  10
+  11
+  12
+  13
+  14
+  15
+  16
+  17
+  18
+  19
+  20
+  21
+  22
+  23
+  24
+  25
+  26
+  27
+  28
+  29
+  30
+  31
+  32
+  33
+  34
+  35
+  36
+  37
+  38
+  39
+  40
+  41
+  42
+  43
+  44
+  45
+  46
+  47
+  48
+  49
+  50
+  51
+  52
+  53
+  54
+  55
+  56
+  57
+  58
+  59
+  60
+  61
+  62
+  63
+  64
+  65
+  66
+  67
+  68
+  69
+  70
+  71
+  72
+  73
+  74
+  75
+  76
+  77
+  78
+  79
+  80
+  81
+  82
+  83
+  84
+  85
+  86
+  87
+  88
+  89
+  90
+  91
+  92
+  93
+  94
+  95
+  96
+  97
+  98
+  99
+ 100
+ 101
+ 102
+ 103
+ 104
+ 105
+ 106
+ 107
+ 108
+ 109
+ 110
+ 111
+ 112
+ 113
+ 114
+ 115
+ 116
+ 117
+ 118
+ 119
+ 120
+ 121
+ 122
+ 123
+ 124
+ 125
+ 126
+ 127
+ 128
+ 129
+ 130
+ 131
+ 132
+ 133
+ 134
+ 135
+ 136
+ 137
+ 138
+ 139
+ 140
+ 141
+ 142
+ 143
+ 144
+ 145
+ 146
+ 147
+ 148
+ 149
+ 150
+ 151
+ 152
+ 153
+ 154
+ 155
+ 156
+ 157
+ 158
+ 159
+ 160
+ 161
+ 162
+ 163
+ 164
+ 165
+ 166
+ 167
+ 168
+ 169
+ 170
+ 171
+ 172
+ 173
+ 174
+ 175
+ 176
+ 177
+ 178
+ 179
+ 180
+ 181
+ 182
+ 183
+ 184
+ 185
+ 186
+ 187
+ 188
+ 189
+ 190
+ 191
+ 192
+ 193
+ 194
+ 195
+ 196
+ 197
+ 198
+ 199
+ 200
+ 201
+ 202
+ 203
+ 204
+ 205
+ 206
+ 207
+ 208
+ 209
+ 210
+ 211
+ 212
+ 213
+ 214
+ 215
+ 216
+ 217
+ 218
+ 219
+ 220
+ 221
+ 222
+ 223
+ 224
+ 225
+ 226
+ 227
+ 228
+ 229
+ 230
+ 231
+ 232
+ 233
+ 234
+ 235
+ 236
+ 237
+ 238
+ 239
+ 240
+ 241
+ 242
+ 243
+ 244
+ 245
+ 246
+ 247
+ 248
+ 249
+ 250
+ 251
+ 252
+ 253
+ 254
+ 255
+ 256
+ 257
+ 258
+ 259
+ 260
+ 261
+ 262
+ 263
+ 264
+ 265
+ 266
+ 267
+ 268
+ 269
+ 270
+ 271
+ 272
+ 273
+ 274
+ 275
+ 276
+ 277
+ 278
+ 279
+ 280
+ 281
+ 282
+ 283
+ 284
+ 285
+ 286
+ 287
+ 288
+ 289
+ 290
+ 291
+ 292
+ 293
+ 294
+ 295
+ 296
+ 297
+ 298
+ 299
+ 300
+ 301
+ 302
+ 303
+ 304
+ 305
+ 306
+ 307
+ 308
+ 309
+ 310
+ 311
+ 312
+ 313
+ 314
+ 315
+ 316
+ 317
+ 318
+ 319
+ 320
+ 321
+ 322
+ 323
+ 324
+ 325
+ 326
+ 327
+ 328
+ 329
+ 330
+ 331
+ 332
+ 333
+ 334
+ 335
+ 336
+ 337
+ 338
+ 339
+ 340
+ 341
+ 342
+ 343
+ 344
+ 345
+ 346
+ 347
+ 348
+ 349
+ 350
+ 351
+ 352
+ 353
+ 354
+ 355
+ 356
+ 357
+ 358
+ 359
+ 360
+ 361
+ 362
+ 363
+ 364
+ 365
+ 366
+ 367
+ 368
+ 369
+ 370
+ 371
+ 372
+ 373
+ 374
+ 375
+ 376
+ 377
+ 378
+ 379
+ 380
+ 381
+ 382
+ 383
+ 384
+ 385
+ 386
+ 387
+ 388
+ 389
+ 390
+ 391
+ 392
+ 393
+ 394
+ 395
+ 396
+ 397
+ 398
+ 399
+ 400
+ 401
+ 402
+ 403
+ 404
+ 405
+ 406
+ 407
+ 408
+ 409
+ 410
+ 411
+ 412
+ 413
+ 414
+ 415
+ 416
+ 417
+ 418
+ 419
+ 420
+ 421
+ 422
+ 423
+ 424
+ 425
+ 426
+ 427
+ 428
+ 429
+ 430
+ 431
+ 432
+ 433
+ 434
+ 435
+ 436
+ 437
+ 438
+ 439
+ 440
+ 441
+ 442
+ 443
+ 444
+ 445
+ 446
+ 447
+ 448
+ 449
+ 450
+ 451
+ 452
+ 453
+ 454
+ 455
+ 456
+ 457
+ 458
+ 459
+ 460
+ 461
+ 462
+ 463
+ 464
+ 465
+ 466
+ 467
+ 468
+ 469
+ 470
+ 471
+ 472
+ 473
+ 474
+ 475
+ 476
+ 477
+ 478
+ 479
+ 480
+ 481
+ 482
+ 483
+ 484
+ 485
+ 486
+ 487
+ 488
+ 489
+ 490
+ 491
+ 492
+ 493
+ 494
+ 495
+ 496
+ 497
+ 498
+ 499
+ 500
+ 501
+ 502
+ 503
+ 504
+ 505
+ 506
+ 507
+ 508
+ 509
+ 510
+ 511
+ 512
+ 513
+ 514
+ 515
+ 516
+ 517
+ 518
+ 519
+ 520
+ 521
+ 522
+ 523
+ 524
+ 525
+ 526
+ 527
+ 528
+ 529
+ 530
+ 531
+ 532
+ 533
+ 534
+ 535
+ 536
+ 537
+ 538
+ 539
+ 540
+ 541
+ 542
+ 543
+ 544
+ 545
+ 546
+ 547
+ 548
+ 549
+ 550
+ 551
+ 552
+ 553
+ 554
+ 555
+ 556
+ 557
+ 558
+ 559
+ 560
+ 561
+ 562
+ 563
+ 564
+ 565
+ 566
+ 567
+ 568
+ 569
+ 570
+ 571
+ 572
+ 573
+ 574
+ 575
+ 576
+ 577
+ 578
+ 579
+ 580
+ 581
+ 582
+ 583
+ 584
+ 585
+ 586
+ 587
+ 588
+ 589
+ 590
+ 591
+ 592
+ 593
+ 594
+ 595
+ 596
+ 597
+ 598
+ 599
+ 600
+ 601
+ 602
+ 603
+ 604
+ 605
+ 606
+ 607
+ 608
+ 609
+ 610
+ 611
+ 612
+ 613
+ 614
+ 615
+ 616
+ 617
+ 618
+ 619
+ 620
+ 621
+ 622
+ 623
+ 624
+ 625
+ 626
+ 627
+ 628
+ 629
+ 630
+ 631
+ 632
+ 633
+ 634
+ 635
+ 636
+ 637
+ 638
+ 639
+ 640
+ 641
+ 642
+ 643
+ 644
+ 645
+ 646
+ 647
+ 648
+ 649
+ 650
+ 651
+ 652
+ 653
+ 654
+ 655
+ 656
+ 657
+ 658
+ 659
+ 660
+ 661
+ 662
+ 663
+ 664
+ 665
+ 666
+ 667
+ 668
+ 669
+ 670
+ 671
+ 672
+ 673
+ 674
+ 675
+ 676
+ 677
+ 678
+ 679
+ 680
+ 681
+ 682
+ 683
+ 684
+ 685
+ 686
+ 687
+ 688
+ 689
+ 690
+ 691
+ 692
+ 693
+ 694
+ 695
+ 696
+ 697
+ 698
+ 699
+ 700
+ 701
+ 702
+ 703
+ 704
+ 705
+ 706
+ 707
+ 708
+ 709
+ 710
+ 711
+ 712
+ 713
+ 714
+ 715
+ 716
+ 717
+ 718
+ 719
+ 720
+ 721
+ 722
+ 723
+ 724
+ 725
+ 726
+ 727
+ 728
+ 729
+ 730
+ 731
+ 732
+ 733
+ 734
+ 735
+ 736
+ 737
+ 738
+ 739
+ 740
+ 741
+ 742
+ 743
+ 744
+ 745
+ 746
+ 747
+ 748
+ 749
+ 750
+ 751
+ 752
+ 753
+ 754
+ 755
+ 756
+ 757
+ 758
+ 759
+ 760
+ 761
+ 762
+ 763
+ 764
+ 765
+ 766
+ 767
+ 768
+ 769
+ 770
+ 771
+ 772
+ 773
+ 774
+ 775
+ 776
+ 777
+ 778
+ 779
+ 780
+ 781
+ 782
+ 783
+ 784
+ 785
+ 786
+ 787
+ 788
+ 789
+ 790
+ 791
+ 792
+ 793
+ 794
+ 795
+ 796
+ 797
+ 798
+ 799
+ 800
+ 801
+ 802
+ 803
+ 804
+ 805
+ 806
+ 807
+ 808
+ 809
+ 810
+ 811
+ 812
+ 813
+ 814
+ 815
+ 816
+ 817
+ 818
+ 819
+ 820
+ 821
+ 822
+ 823
+ 824
+ 825
+ 826
+ 827
+ 828
+ 829
+ 830
+ 831
+ 832
+ 833
+ 834
+ 835
+ 836
+ 837
+ 838
+ 839
+ 840
+ 841
+ 842
+ 843
+ 844
+ 845
+ 846
+ 847
+ 848
+ 849
+ 850
+ 851
+ 852
+ 853
+ 854
+ 855
+ 856
+ 857
+ 858
+ 859
+ 860
+ 861
+ 862
+ 863
+ 864
+ 865
+ 866
+ 867
+ 868
+ 869
+ 870
+ 871
+ 872
+ 873
+ 874
+ 875
+ 876
+ 877
+ 878
+ 879
+ 880
+ 881
+ 882
+ 883
+ 884
+ 885
+ 886
+ 887
+ 888
+ 889
+ 890
+ 891
+ 892
+ 893
+ 894
+ 895
+ 896
+ 897
+ 898
+ 899
+ 900
+ 901
+ 902
+ 903
+ 904
+ 905
+ 906
+ 907
+ 908
+ 909
+ 910
+ 911
+ 912
+ 913
+ 914
+ 915
+ 916
+ 917
+ 918
+ 919
+ 920
+ 921
+ 922
+ 923
+ 924
+ 925
+ 926
+ 927
+ 928
+ 929
+ 930
+ 931
+ 932
+ 933
+ 934
+ 935
+ 936
+ 937
+ 938
+ 939
+ 940
+ 941
+ 942
+ 943
+ 944
+ 945
+ 946
+ 947
+ 948
+ 949
+ 950
+ 951
+ 952
+ 953
+ 954
+ 955
+ 956
+ 957
+ 958
+ 959
+ 960
+ 961
+ 962
+ 963
+ 964
+ 965
+ 966
+ 967
+ 968
+ 969
+ 970
+ 971
+ 972
+ 973
+ 974
+ 975
+ 976
+ 977
+ 978
+ 979
+ 980
+ 981
+ 982
+ 983
+ 984
+ 985
+ 986
+ 987
+ 988
+ 989
+ 990
+ 991
+ 992
+ 993
+ 994
+ 995
+ 996
+ 997
+ 998
+ 999
+1000
+1001
+1002
+1003
+1004
+1005
+1006
+1007
+1008
+1009
+1010
+1011
+1012
+1013
+1014
+1015
+1016
+1017
+1018
+1019
+1020
+1021
+1022
+1023
+1024
+1025
+1026
+1027
+1028
+1029
+1030
+1031
+1032
+1033
+1034
+1035
+1036
+1037
+1038
+1039
+1040
+1041
+1042
+1043
+1044
+1045
+1046
+1047
+1048
+1049
+1050
+1051
+1052
+1053
+1054
+1055
+1056
+1057
+1058
+1059
+1060
+1061
+1062
+1063
+1064
+1065
+1066
+1067
+1068
+1069
+1070
+1071
+1072
+1073
+1074
+1075
+1076
+1077
+1078
+1079
+1080
+1081
+1082
+1083
+1084
+1085
+1086
+1087
+1088
+1089
+1090
+1091
+1092
+1093
+1094
+1095
+1096
+1097
+1098
+1099
+1100
+1101
+1102
+1103
+1104
+1105
+1106
+1107
+1108
+1109
+1110
+1111
+1112
+1113
+1114
+1115
+1116
+1117
+1118
+1119
+1120
+1121
+1122
+1123
+1124
+1125
+1126
+1127
+1128
+1129
+1130
+1131
+1132
+1133
+1134
+1135
+1136
+1137
+1138
+1139
+1140
+1141
+1142
+1143
+1144
+1145
+1146
+1147
+1148
+1149
+1150
+1151
+1152
+1153
+1154
+1155
+1156
+1157
+1158
+1159
+1160
+1161
+1162
+1163
+1164
+1165
+1166
+1167
+1168
+1169
+1170
+1171
+1172
+1173
+1174
+1175
+1176
+1177
+1178
+1179
+1180
+1181
+1182
+1183
+1184
+1185
+1186
+1187
+1188
+1189
+1190
+1191
+1192
+1193
+1194
+1195
+1196
+1197
+1198
+1199
+1200
+1201
+1202
+1203
+1204
+1205
+1206
+1207
+1208
+1209
+1210
+1211
+1212
+1213
+1214
+1215
+1216
+1217
+1218
+1219
+1220
+1221
+1222
+1223
+1224
+1225
+1226
+1227
+1228
+1229
+1230
+1231
+1232
+1233
+1234
+1235
+1236
+1237
+1238
+1239
+1240
+1241
+1242
+1243
+1244
+1245
+1246
+1247
+1248
+1249
+1250
+1251
+1252
+1253
+1254
+1255
+1256
+1257
+1258
+1259
+1260
+1261
+1262
+1263
+1264
+1265
+1266
+1267
+1268
+1269
+1270
+1271
+1272
+1273
+1274
+1275
+1276
+1277
+1278
+1279
+1280
+1281
+1282
+1283
+1284
+1285
+1286
+1287
+1288
+1289
+1290
+1291
+1292
+1293
+1294
+1295
+1296
+1297
+1298
+1299
+1300
+1301
+1302
+1303
+1304
+1305
+1306
+1307
+1308
+1309
+1310
+1311
+1312
+1313
+1314
+1315
+1316
+1317
+1318
+1319
+1320
+1321
+1322
+1323
+1324
+1325
+1326
+1327
+1328
+1329
+1330
+1331
+1332
+1333
+1334
+1335
+1336
+1337
+1338
+1339
+1340
+1341
+1342
+1343
+1344
+1345
+1346
+1347
+1348
+1349
+1350
+1351
+1352
+1353
+1354
+1355
+1356
+1357
+1358
+1359
+1360
+1361
+1362
+1363
+1364
+1365
+1366
+1367
+1368
+1369
+1370
+1371
+1372
+1373
+1374
+1375
+1376
+1377
+1378
+1379
+1380
+1381
+1382
+1383
+1384
+1385
+1386
+1387
+1388
+1389
+1390
+1391
+1392
+1393
+1394
+1395
+1396
+1397
+1398
+1399
+1400
+1401
+1402
+1403
+1404
+1405
+1406
+1407
+1408
+1409
+1410
+1411
+1412
+1413
+1414
+1415
+1416
+1417
+1418
+1419
+1420
+1421
+1422
+1423
+1424
+1425
+1426
+1427
+1428
+1429
+1430
+1431
+1432
+1433
+1434
+1435
+1436
+1437
+1438
+1439
+1440
+1441
+1442
+1443
+1444
+1445
+1446
+1447
+1448
+1449
+1450
+1451
+1452
+1453
+1454
+1455
+1456
+1457
+1458
+1459
+1460
+1461
+1462
+1463
+1464
+1465
+1466
+1467
+1468
+1469
+1470
+1471
+1472
+1473
+1474
+1475
+1476
+1477
+1478
+1479
+1480
+1481
+1482
+1483
+1484
+1485
+1486
// *****************************************************************************
 /*!
-  \file      src/PDE/ConfigureCompFlow.cpp
+  \file      src/Inciter/OversetFE.cpp
   \copyright 2012-2015 J. Bakosi,
              2016-2018 Los Alamos National Security, LLC.,
              2019-2021 Triad National Security, LLC.
              All rights reserved. See the LICENSE file for details.
-  \brief     Register and compile configuration for compressible flow PDE
-  \details   Register and compile configuration for compressible flow PDE.
-*/
-// *****************************************************************************
-
-#include <set>
-#include <map>
-#include <vector>
-#include <string>
-#include <limits>
-
-#include <brigand/algorithms/for_each.hpp>
-
-#include "Tags.hpp"
-#include "CartesianProduct.hpp"
-#include "PDEFactory.hpp"
-#include "Inciter/Options/PDE.hpp"
-#include "ContainerUtil.hpp"
-#include "ConfigureCompFlow.hpp"
-#include "CompFlow/Physics/CG.hpp"
-#include "CompFlow/Physics/DG.hpp"
-#include "CompFlow/CGCompFlow.hpp"
-#include "CompFlow/DGCompFlow.hpp"
-#include "CompFlow/Problem.hpp"
-
-namespace inciter {
-
-void
-registerCompFlow( CGFactory& cf,
-                  DGFactory& df,
-                  std::set< ctr::PDEType >& cgt,
-                  std::set< ctr::PDEType >& dgt )
-// *****************************************************************************
-// Register compressible flow PDE into PDE factory
-//! \param[in,out] cf Continuous Galerkin PDE factory to register to
-//! \param[in,out] df Discontinuous Galerkin PDE factory to register to
-//! \param[in,out] cgt Counters for equation types registered into CG factory
-//! \param[in,out] dgt Counters for equation types registered into DG factory
-// *****************************************************************************
-{
-  // Construct vector of vectors for all possible policies
-  using CGCompFlowPolicies =
-    tk::cartesian_product< cg::CompFlowPhysics, CompFlowProblems >;
-  // Register PDEs for all combinations of policies
-  brigand::for_each< CGCompFlowPolicies >(
-    registerCG< cg::CompFlow >( cf, cgt, ctr::PDEType::COMPFLOW ) );
-
-  // Construct vector of vectors for all possible policies
-  using DGCompFlowPolicies =
-    tk::cartesian_product< dg::CompFlowPhysics, CompFlowProblems >;
-  // Register PDEs for all combinations of policies
-  brigand::for_each< DGCompFlowPolicies >(
-    registerDG< dg::CompFlow >( df, dgt, ctr::PDEType::COMPFLOW ) );
-}
-
-std::vector< std::pair< std::string, std::string > >
-infoCompFlow( std::map< ctr::PDEType, tk::ncomp_t >& cnt )
-// *****************************************************************************
-//  Return information on the compressible flow system of PDEs
-//! \param[inout] cnt std::map of counters for all PDE types
-//! \return vector of string pairs describing the PDE configuration
-// *****************************************************************************
-{
-  using eq = tag::compflow;
-  using tk::parameter;
-  using tk::parameters;
-
-  auto c = ++cnt[ ctr::PDEType::COMPFLOW ];       // count eqs
-  --c;  // used to index vectors starting with 0<--- Variable 'c' is assigned a value that is never used.
-
-  std::vector< std::pair< std::string, std::string > > nfo;
-
-  nfo.emplace_back( ctr::PDE().name( ctr::PDEType::COMPFLOW ), "" );
-
-  nfo.emplace_back( "physics", ctr::Physics().name(
-    g_inputdeck.get< eq, tag::physics >() ) );
-
-  nfo.emplace_back( "problem", ctr::Problem().name(
-    g_inputdeck.get< eq, tag::problem >() ) );
-
-  auto ncomp = g_inputdeck.get< tag::ncomp >();
-  nfo.emplace_back( "number of components", parameter( ncomp ) );
-
-  const auto scheme = g_inputdeck.get< tag::scheme >();
-  if (scheme != ctr::SchemeType::ALECG && scheme != ctr::SchemeType::OversetFE)
-    nfo.emplace_back( "flux", ctr::Flux().name(
-      g_inputdeck.get< tag::flux >() ) );
-
-  // ICs
-
-  const auto& ic = g_inputdeck.get< tag::ic >();
-
-  const auto& icbox = ic.get< tag::box >();
-  if (!icbox.empty()) {
-    std::size_t bcnt = 0;
-    for (const auto& b : icbox) {   // for all boxes configured for this eq
-      std::vector< tk::real > box
-        { b.get< tag::xmin >(), b.get< tag::xmax >(),
-          b.get< tag::ymin >(), b.get< tag::ymax >(),
-          b.get< tag::zmin >(), b.get< tag::zmax >() };
-
-      std::string boxname = "IC box " + parameter(bcnt);
-      nfo.emplace_back( boxname, parameters( box ) );
+  \brief     OversetFE for a PDE system with continuous Galerkin FE + RK
+  \details   OversetFE advances a system of partial differential equations
+    using a continuous Galerkin (CG) finite element (FE) spatial discretization
+    (using linear shapefunctions on tetrahedron elements) combined with a
+    Runge-Kutta (RK) time stepping scheme and overset grids.
+  \see The documentation in OversetFE.hpp.
+*/
+// *****************************************************************************
+
+#include "QuinoaBuildConfig.hpp"
+#include "OversetFE.hpp"
+#include "Vector.hpp"
+#include "Reader.hpp"
+#include "ContainerUtil.hpp"
+#include "UnsMesh.hpp"
+#include "ExodusIIMeshWriter.hpp"
+#include "Inciter/InputDeck/InputDeck.hpp"
+#include "DerivedData.hpp"
+#include "CGPDE.hpp"
+#include "Discretization.hpp"
+#include "DiagReducer.hpp"
+#include "NodeBC.hpp"
+#include "Refiner.hpp"
+#include "Reorder.hpp"
+#include "Around.hpp"
+#include "CGPDE.hpp"
+#include "FieldOutput.hpp"
+
+namespace inciter {
+
+extern ctr::InputDeck g_inputdeck;
+extern std::vector< CGPDE > g_cgpde;
+
+//! Runge-Kutta coefficients
+static const std::array< tk::real, 3 > rkcoef{{ 1.0/3.0, 1.0/2.0, 1.0 }};
+
+} // inciter::
+
+using inciter::OversetFE;
+
+OversetFE::OversetFE( const CProxy_Discretization& disc,
+              const CProxy_Ghosts&,
+              const std::map< int, std::vector< std::size_t > >& bface,
+              const std::map< int, std::vector< std::size_t > >& bnode,
+              const std::vector< std::size_t >& triinpoel ) :
+  m_disc( disc ),
+  m_nsol( 0 ),
+  m_ngrad( 0 ),
+  m_nrhs( 0 ),
+  m_nbnorm( 0 ),
+  m_ndfnorm( 0 ),
+  m_nmblk( 0 ),
+  m_bnode( bnode ),
+  m_bface( bface ),
+  m_triinpoel( tk::remap( triinpoel, Disc()->Lid() ) ),
+  m_bndel( Disc()->bndel() ),
+  m_dfnorm(),
+  m_dfnormc(),
+  m_dfn(),
+  m_esup( tk::genEsup( Disc()->Inpoel(), 4 ) ),
+  m_psup( tk::genPsup( Disc()->Inpoel(), 4, m_esup ) ),
+  m_u( Disc()->Gid().size(),
+       g_inputdeck.get< tag::ncomp >() ),
+  m_uc( m_u.nunk(), m_u.nprop()+1 ),
+  m_un( m_u.nunk(), m_u.nprop() ),
+  m_rhs( m_u.nunk(), m_u.nprop() ),
+  m_rhsc(),
+  m_chBndGrad( Disc()->Bid().size(), m_u.nprop()*3 ),
+  m_dirbc(),
+  m_chBndGradc(),
+  m_blank( m_u.nunk(), 1.0 ),
+  m_diag(),
+  m_bnorm(),
+  m_bnormc(),
+  m_symbcnodes(),
+  m_farfieldbcnodes(),
+  m_symbctri(),
+  m_timedepbcnodes(),
+  m_timedepbcFn(),
+  m_stage( 0 ),
+  m_boxnodes(),
+  m_edgenode(),
+  m_edgeid(),
+  m_dtp( m_u.nunk(), 0.0 ),
+  m_tp( m_u.nunk(), g_inputdeck.get< tag::t0 >() ),
+  m_finished( 0 ),
+  m_movedmesh( 0 ),
+  m_nusermeshblk( 0 ),
+  m_nodeblockid(),
+  m_nodeblockidc(),
+  m_ixfer(0)
+// *****************************************************************************
+//  Constructor
+//! \param[in] disc Discretization proxy
+//! \param[in] bface Boundary-faces mapped to side sets used in the input file
+//! \param[in] bnode Boundary-node lists mapped to side sets used in input file
+//! \param[in] triinpoel Boundary-face connectivity where BCs set (global ids)
+// *****************************************************************************
+//! [Constructor]
+{
+  usesAtSync = true;    // enable migration at AtSync
+
+  auto d = Disc();
 
-      nfo.emplace_back( boxname + " orientation",
-        parameters(b.get< tag::orientation >()) );
+  // Perform optional operator-access-pattern mesh node reordering
+  if (g_inputdeck.get< tag::operator_reorder >()) {
 
-      const auto& initiate = b.get< tag::initiate >();
-      auto opt = ctr::Initiate();
-      nfo.emplace_back( boxname + ' ' + opt.group(), opt.name(initiate) );
+    // Create new local ids based on access pattern of PDE operators
+    std::unordered_map< std::size_t, std::size_t > map;
+    std::size_t n = 0;
 
-      ++bcnt;
-    }
-  }
-
-  const auto& icblock = ic.get< tag::meshblock >();
-  for (const auto& b : icblock) {   // for all blocks configured for eq
-    std::string blockname = "IC mesh block " +
-      parameter(b.get< tag::blockid >());
+    for (std::size_t p=0; p<m_u.nunk(); ++p) {  // for each point p
+      if (map.find(p) == end(map)) map[p] = n++;<--- Searching before insertion is not necessary.
+      for (auto q : tk::Around(m_psup,p)) {     // for each edge p-q
+        if (map.find(q) == end(map)) map[q] = n++;<--- Searching before insertion is not necessary.
+      }
+    }
+
+    Assert( map.size() == d->Gid().size(), "Map size mismatch" );
 
-    const auto& initiate = b.get< tag::initiate >();
-    auto opt = ctr::Initiate();
-    nfo.emplace_back( blockname + ' ' + opt.group(), opt.name(initiate) );
-  }
-
-  // BCs
-
-  const auto& bc = g_inputdeck.get< tag::bc >();
-  for (const auto& ib : bc) {
-    const auto& stag = ib.get< tag::stag_point >();
-    const auto& radius = ib.get< tag::radius >();
-    if (!stag.empty()) {
-      nfo.emplace_back( "Stagnation point(s)", parameters( stag ) );
-      nfo.emplace_back( "Stagnation point(s) radii", parameter( radius ) );
-    }
-
-    const auto& fs = ib.get< tag::farfield >();
-    if (!fs.empty())
-      nfo.emplace_back( "Farfield BC sideset(s)", parameters( fs ) );
-
-    const auto& sym = ib.get< tag::symmetry >();
-    if (!sym.empty())
-      nfo.emplace_back( "Symmetry BC sideset(s)", parameters( sym ) );
-
-    const auto& dir = ib.get< tag::dirichlet >();
-    if (!dir.empty())
-      nfo.emplace_back( "Dirichlet BC sideset(s)", parameters( dir ) );
+    // Remap data in bound Discretization object
+    d->remap( map );
+    // Recompute elements surrounding points
+    m_esup = tk::genEsup( d->Inpoel(), 4 );
+    // Recompute points surrounding points
+    m_psup = tk::genPsup( d->Inpoel(), 4, m_esup );
+    // Remap boundary triangle face connectivity
+    tk::remap( m_triinpoel, map );
+  }
+
+  // Query/update boundary-conditions-related data structures from user input
+  getBCNodes();
+
+  // Activate SDAG wait for initially computing normals, and mesh blocks
+  thisProxy[ thisIndex ].wait4norm();
+  thisProxy[ thisIndex ].wait4meshblk();
+
+  // Determine user-specified mesh velocity
+  const auto& uservelvec =
+    g_inputdeck.get< tag::mesh >()[d->MeshId()].get< tag::velocity >();
+  m_uservel = {uservelvec[0], uservelvec[1], uservelvec[2]};
+
+  if (g_inputdeck.get< tag::steady_state >() &&
+    std::sqrt(tk::dot(m_uservel, m_uservel)) > 1e-8)
+    Throw("Mesh motion cannot be activated for steady state problem");
+
+  d->comfinal();
 
-    const auto& timedep = ib.get< tag::timedep >();
-    if (!timedep.empty()) {
-      for (const auto& bndry : timedep) {
-        nfo.emplace_back( "Time dependent BC sideset(s)",<--- Consider using std::transform algorithm instead of a raw loop.
-          parameters(bndry.get< tag::sideset >()) );
-      }
-    }
-  }
-
-  return nfo;
-}
-
-}  // inciter::
+}
+//! [Constructor]
+
+void
+OversetFE::getBCNodes()
+// *****************************************************************************
+// Query/update boundary-conditions-related data structures from user input
+// *****************************************************************************
+{
+  auto d = Disc();
+
+  // Prepare unique set of symmetry BC nodes
+  auto sym = d->bcnodes< tag::symmetry >( m_bface, m_triinpoel );
+  for (const auto& [s,nodes] : sym)
+    m_symbcnodes.insert( begin(nodes), end(nodes) );
+
+  // Prepare unique set of farfield BC nodes
+  auto far = d->bcnodes< tag::farfield >( m_bface, m_triinpoel );
+  for (const auto& [s,nodes] : far)
+    m_farfieldbcnodes.insert( begin(nodes), end(nodes) );
+
+  // If farfield BC is set on a node, will not also set symmetry BC
+  for (auto fn : m_farfieldbcnodes) m_symbcnodes.erase(fn);
+
+  // Prepare boundary nodes contiguously accessible from a triangle-face loop
+  m_symbctri.resize( m_triinpoel.size()/3, 0 );
+  for (std::size_t e=0; e<m_triinpoel.size()/3; ++e)
+    if (m_symbcnodes.find(m_triinpoel[e*3+0]) != end(m_symbcnodes))
+      m_symbctri[e] = 1;
+
+  // Prepare unique set of time dependent BC nodes
+  m_timedepbcnodes.clear();
+  m_timedepbcFn.clear();
+  const auto& timedep =
+    g_inputdeck.get< tag::bc >()[d->MeshId()].get< tag::timedep >();
+  if (!timedep.empty()) {
+    m_timedepbcnodes.resize(timedep.size());
+    m_timedepbcFn.resize(timedep.size());
+    std::size_t ib=0;
+    for (const auto& bndry : timedep) {
+      std::unordered_set< std::size_t > nodes;
+      for (const auto& s : bndry.template get< tag::sideset >()) {
+        auto k = m_bnode.find(static_cast<int>(s));
+        if (k != end(m_bnode)) {
+          for (auto g : k->second) {      // global node ids on side set
+            nodes.insert( tk::cref_find(d->Lid(),g) );
+          }
+        }
+      }
+      m_timedepbcnodes[ib].insert( begin(nodes), end(nodes) );
+
+      // Store user defined discrete function in time. This is done in the same
+      // loop as the BC nodes, so that the indices for the two vectors
+      // m_timedepbcnodes and m_timedepbcFn are consistent with each other
+      auto fn = bndry.template get< tag::fn >();
+      for (std::size_t ir=0; ir<fn.size()/6; ++ir) {
+        m_timedepbcFn[ib].push_back({{ fn[ir*6+0], fn[ir*6+1], fn[ir*6+2],
+          fn[ir*6+3], fn[ir*6+4], fn[ir*6+5] }});
+      }
+      ++ib;
+    }
+  }
+
+  Assert(m_timedepbcFn.size() == m_timedepbcnodes.size(), "Incorrect number of "
+    "time dependent functions.");
+}
+
+void
+OversetFE::norm()
+// *****************************************************************************
+// Start (re-)computing boundary point-, and dual-face normals
+// *****************************************************************************
+{
+  auto d = Disc();
+
+  // Query nodes at which symmetry BCs are specified
+  auto bn = d->bcnodes< tag::symmetry >( m_bface, m_triinpoel );
+
+  // Query nodes at which farfield BCs are specified
+  auto far = d->bcnodes< tag::farfield >( m_bface, m_triinpoel );
+  // Merge BC data where boundary-point normals are required
+  for (const auto& [s,n] : far) bn[s].insert( begin(n), end(n) );
+
+  // Query nodes at which mesh velocity symmetry BCs are specified
+  std::unordered_map<int, std::unordered_set< std::size_t >> ms;
+  for (const auto& s : g_inputdeck.get< tag::ale, tag::symmetry >()) {
+    auto k = m_bface.find(static_cast<int>(s));
+    if (k != end(m_bface)) {
+      auto& n = ms[ k->first ];
+      for (auto f : k->second) {
+        n.insert( m_triinpoel[f*3+0] );
+        n.insert( m_triinpoel[f*3+1] );
+        n.insert( m_triinpoel[f*3+2] );
+      }
+    }
+  }
+  // Merge BC data where boundary-point normals are required
+  for (const auto& [s,n] : ms) bn[s].insert( begin(n), end(n) );
+
+  // Compute boundary point normals
+  bnorm( bn );
+
+  // Compute dual-face normals associated to edges
+  dfnorm();
+}
+
+std::array< tk::real, 3 >
+OversetFE::edfnorm( const tk::UnsMesh::Edge& edge,
+                const std::unordered_map< tk::UnsMesh::Edge,
+                        std::vector< std::size_t >,
+                        tk::UnsMesh::Hash<2>, tk::UnsMesh::Eq<2> >& esued )
+const
+// *****************************************************************************
+//  Compute normal of dual-mesh associated to edge
+//! \param[in] edge Edge whose dual-face normal to compute given by local ids
+//! \param[in] esued Elements surrounding edges
+//! \return Dual-face normal for edge
+// *****************************************************************************
+{
+  auto d = Disc();
+  const auto& inpoel = d->Inpoel();
+  const auto& coord = d->Coord();
+  const auto& x = coord[0];
+  const auto& y = coord[1];
+  const auto& z = coord[2];
+
+  std::array< tk::real, 3 > n{ 0.0, 0.0, 0.0 };
+
+  for (auto e : tk::cref_find(esued,edge)) {
+    // access node IDs
+    const std::array< std::size_t, 4 >
+      N{ inpoel[e*4+0], inpoel[e*4+1], inpoel[e*4+2], inpoel[e*4+3] };
+    // compute element Jacobi determinant
+    const std::array< tk::real, 3 >
+      ba{{ x[N[1]]-x[N[0]], y[N[1]]-y[N[0]], z[N[1]]-z[N[0]] }},
+      ca{{ x[N[2]]-x[N[0]], y[N[2]]-y[N[0]], z[N[2]]-z[N[0]] }},
+      da{{ x[N[3]]-x[N[0]], y[N[3]]-y[N[0]], z[N[3]]-z[N[0]] }};
+    const auto J = tk::triple( ba, ca, da );        // J = 6V
+    Assert( J > 0, "Element Jacobian non-positive" );
+    // shape function derivatives, nnode*ndim [4][3]
+    std::array< std::array< tk::real, 3 >, 4 > grad;
+    grad[1] = tk::crossdiv( ca, da, J );
+    grad[2] = tk::crossdiv( da, ba, J );
+    grad[3] = tk::crossdiv( ba, ca, J );
+    for (std::size_t i=0; i<3; ++i)
+      grad[0][i] = -grad[1][i]-grad[2][i]-grad[3][i];
+    // sum normal contributions
+    // The constant 1/48: Eq (12) from Waltz et al. Computers & fluids (92) 2014
+    // The result of the integral of shape function N on a tet is V/4.
+    // This can be written as J/(6*4). Eq (12) has a 1/2 multiplier.
+    // This leads to J/48.
+    auto J48 = J/48.0;
+    for (const auto& [a,b] : tk::lpoed) {
+      auto s = tk::orient( {N[a],N[b]}, edge );
+      for (std::size_t j=0; j<3; ++j)
+        n[j] += J48 * s * (grad[a][j] - grad[b][j]);
+    }
+  }
+
+  return n;
+}
+
+void
+OversetFE::dfnorm()
+// *****************************************************************************
+// Compute dual-face normals associated to edges
+// *****************************************************************************
+{
+  auto d = Disc();
+  const auto& inpoel = d->Inpoel();
+  const auto& gid = d->Gid();
+
+  // compute derived data structures
+  auto esued = tk::genEsued( inpoel, 4, tk::genEsup( inpoel, 4 ) );
+
+  // Compute dual-face normals for domain edges
+  for (std::size_t p=0; p<gid.size(); ++p)    // for each point p
+    for (auto q : tk::Around(m_psup,p))       // for each edge p-q
+      if (gid[p] < gid[q])
+        m_dfnorm[{gid[p],gid[q]}] = edfnorm( {p,q}, esued );
+
+  // Send our dual-face normal contributions to neighbor chares
+  if (d->EdgeCommMap().empty())
+    comdfnorm_complete();
+  else {
+    for (const auto& [c,edges] : d->EdgeCommMap()) {
+      decltype(m_dfnorm) exp;
+      for (const auto& e : edges) exp[e] = tk::cref_find(m_dfnorm,e);
+      thisProxy[c].comdfnorm( exp );
+    }
+  }
+
+  owndfnorm_complete();
+}
+
+void
+OversetFE::comdfnorm( const std::unordered_map< tk::UnsMesh::Edge,
+                    std::array< tk::real, 3 >,
+                    tk::UnsMesh::Hash<2>, tk::UnsMesh::Eq<2> >& dfnorm )
+// *****************************************************************************
+// Receive contributions to dual-face normals on chare-boundaries
+//! \param[in] dfnorm Incoming partial sums of dual-face normals associated to
+//!   chare-boundary edges
+// *****************************************************************************
+{
+  // Buffer up inccoming contributions to dual-face normals
+  for (const auto& [e,n] : dfnorm) {
+    auto& dfn = m_dfnormc[e];
+    dfn[0] += n[0];
+    dfn[1] += n[1];
+    dfn[2] += n[2];
+  }
+
+  if (++m_ndfnorm == Disc()->EdgeCommMap().size()) {
+    m_ndfnorm = 0;
+    comdfnorm_complete();
+  }
+}
+
+void
+OversetFE::bnorm( const std::unordered_map< int,
+                std::unordered_set< std::size_t > >& bcnodes )
+// *****************************************************************************
+//  Compute boundary point normals
+//! \param[in] bcnodes Local node ids associated to side set ids at which BCs
+//!    are set that require normals
+//*****************************************************************************
+{
+  auto d = Disc();
+
+  m_bnorm = cg::bnorm( m_bface, m_triinpoel, d->Coord(), d->Gid(), bcnodes );
+
+  // Send our nodal normal contributions to neighbor chares
+  if (d->NodeCommMap().empty())
+    comnorm_complete();
+  else
+    for (const auto& [ neighborchare, sharednodes ] : d->NodeCommMap()) {
+      std::unordered_map< int,
+        std::unordered_map< std::size_t, std::array< tk::real, 4 > > > exp;
+      for (auto i : sharednodes) {
+        for (const auto& [s,norms] : m_bnorm) {
+          auto j = norms.find(i);
+          if (j != end(norms)) exp[s][i] = j->second;
+        }
+      }
+      thisProxy[ neighborchare ].comnorm( exp );
+    }
+
+  ownnorm_complete();
+}
+
+void
+OversetFE::comnorm( const std::unordered_map< int,
+  std::unordered_map< std::size_t, std::array< tk::real, 4 > > >& innorm )
+// *****************************************************************************
+// Receive boundary point normals on chare-boundaries
+//! \param[in] innorm Incoming partial sums of boundary point normal
+//!   contributions to normals (first 3 components), inverse distance squared
+//!   (4th component), associated to side set ids
+// *****************************************************************************
+{
+  // Buffer up incoming boundary-point normal vector contributions
+  for (const auto& [s,norms] : innorm) {
+    auto& bnorms = m_bnormc[s];
+    for (const auto& [p,n] : norms) {
+      auto& bnorm = bnorms[p];
+      bnorm[0] += n[0];
+      bnorm[1] += n[1];
+      bnorm[2] += n[2];
+      bnorm[3] += n[3];
+    }
+  }
+
+  if (++m_nbnorm == Disc()->NodeCommMap().size()) {
+    m_nbnorm = 0;
+    comnorm_complete();
+  }
+}
+
+void
+OversetFE::registerReducers()
+// *****************************************************************************
+//  Configure Charm++ reduction types initiated from this chare array
+//! \details Since this is a [initnode] routine, the runtime system executes the
+//!   routine exactly once on every logical node early on in the Charm++ init
+//!   sequence. Must be static as it is called without an object. See also:
+//!   Section "Initializations at Program Startup" at in the Charm++ manual
+//!   http://charm.cs.illinois.edu/manuals/html/charm++/manual.html.
+// *****************************************************************************
+{
+  NodeDiagnostics::registerReducers();
+}
+
+void
+OversetFE::ResumeFromSync()
+// *****************************************************************************
+//  Return from migration
+//! \details This is called when load balancing (LB) completes. The presence of
+//!   this function does not affect whether or not we block on LB.
+// *****************************************************************************
+{
+  if (Disc()->It() == 0) Throw( "it = 0 in ResumeFromSync()" );
+
+  if (!g_inputdeck.get< tag::cmd, tag::nonblocking >()) next();
+}
+
+//! [setup]
+void
+OversetFE::setup()
+// *****************************************************************************
+// Start setup for solution
+// *****************************************************************************
+{
+  auto d = Disc();
+
+  // Determine nodes inside user-defined IC box
+  g_cgpde[d->MeshId()].IcBoxNodes( d->Coord(), d->Inpoel(),
+    d->ElemBlockId(), m_boxnodes, m_nodeblockid, m_nusermeshblk );
+
+  // Communicate mesh block nodes to other chares on chare-boundary
+  if (d->NodeCommMap().empty())        // in serial we are done
+    comblk_complete();
+  else // send mesh block information to chare-boundary nodes to fellow chares
+    for (const auto& [c,n] : d->NodeCommMap()) {
+      // data structure assigning block ids (set of values) to nodes (index).
+      // although nodeblockid is a map with key-blockid and value-nodeid, the
+      // sending data structure has to be inverted, because of how communication
+      // data is handled.
+      std::vector< std::set< std::size_t > > mb( n.size() );
+      std::size_t j = 0;
+      for (auto i : n) {
+        for (const auto& [blid, ndset] : m_nodeblockid) {
+          // if node was found in a block, add to send-data
+          if (ndset.find(tk::cref_find(d->Lid(),i)) != ndset.end())
+            mb[j].insert(blid);
+        }
+        if (m_nusermeshblk > 0)
+          Assert(mb[j].size() > 0, "Sending no block data for node");
+        ++j;
+      }
+      thisProxy[c].comblk( std::vector<std::size_t>(begin(n),end(n)), mb );
+    }
+
+  ownblk_complete();
+}
+
+void
+OversetFE::comblk( const std::vector< std::size_t >& gid,
+               const std::vector< std::set< std::size_t > >& mb )
+// *****************************************************************************
+//  Receive mesh block information for nodes on chare-boundaries
+//! \param[in] gid Global mesh node IDs at which we receive RHS contributions
+//! \param[in] mb Block ids for each node on chare-boundaries
+//! \details This function receives mesh block information for nodes on chare
+//!   boundaries. While m_nodeblockid stores block information for own nodes,
+//!   m_nodeblockidc collects the neighbor chare information during
+//!   communication. This way work on m_nodeblockid and m_nodeblockidc is
+//!   overlapped. The two are combined in continueSetup().
+// *****************************************************************************
+{
+  Assert( mb.size() == gid.size(), "Size mismatch" );
+
+  for (std::size_t i=0; i<gid.size(); ++i) {
+    for (const auto& blid : mb[i]) {
+      m_nodeblockidc[blid].insert(gid[i]);
+    }
+  }
+
+  // When we have heard from all chares we communicate with, this chare is done
+  if (++m_nmblk == Disc()->NodeCommMap().size()) {
+    m_nmblk = 0;
+    comblk_complete();
+  }
+}
+
+void
+OversetFE::continueSetup()
+// *****************************************************************************
+// Continue setup for solution, after communication for mesh blocks
+// *****************************************************************************
+{
+  auto d = Disc();
+
+  // Combine own and communicated mesh block information
+  for (const auto& [blid, ndset] : m_nodeblockidc) {
+    for (const auto& i : ndset) {
+      auto lid = tk::cref_find(d->Lid(), i);
+      m_nodeblockid[blid].insert(lid);
+    }
+  }
+
+  // clear receive buffer
+  tk::destroy(m_nodeblockidc);
+
+  // Compute volume of user-defined box IC
+  d->boxvol( m_boxnodes, m_nodeblockid, m_nusermeshblk );
+
+  // Query time history field output labels from all PDEs integrated
+  const auto& hist_points = g_inputdeck.get< tag::history_output, tag::point >();
+  if (!hist_points.empty()) {
+    std::vector< std::string > histnames;
+    auto n = g_cgpde[d->MeshId()].histNames();
+    histnames.insert( end(histnames), begin(n), end(n) );
+    d->histheader( std::move(histnames) );
+  }
+}
+//! [setup]
+
+void
+OversetFE::box( tk::real v, const std::vector< tk::real >& blkvols )
+// *****************************************************************************
+// Receive total box IC volume and set conditions in box
+//! \param[in] v Total volume within user-specified box
+//! \param[in] blkvols Vector of mesh block discrete volumes with user ICs
+// *****************************************************************************
+{
+  Assert(blkvols.size() == m_nusermeshblk,
+    "Incorrect size of block volume vector");
+  auto d = Disc();
+
+  // Store user-defined box/block IC volume
+  d->Boxvol() = v;
+  d->MeshBlkVol() = blkvols;
+
+  // Set initial conditions for all PDEs
+  g_cgpde[d->MeshId()].initialize( d->Coord(), m_u, d->T(), d->Boxvol(),
+    m_boxnodes, d->MeshBlkVol(), m_nodeblockid );
+
+  // Initialize nodal mesh volumes at previous time step stage
+  d->Voln() = d->Vol();
+
+  // Initiate solution transfer (if coupled)
+  transferSol();
+}
+
+void
+OversetFE::transferSol()
+// *****************************************************************************
+// Transfer solution to other solver and mesh if coupled
+// *****************************************************************************
+{
+  // Set up transfer-flags for receiving mesh
+  if (m_ixfer == 1) {
+    applySolTransfer(0);
+  }
+  setTransferFlags(m_ixfer);
+  ++m_ixfer;
+
+  // Initiate IC transfer (if coupled)
+  Disc()->transfer( m_uc, m_ixfer-1,
+    CkCallback(CkIndex_OversetFE::lhs(), thisProxy[thisIndex]) );
+}
+
+//! [Compute lhs]
+void
+OversetFE::lhs()
+// *****************************************************************************
+// Compute the left-hand side of transport equations
+//! \details Also (re-)compute all data structures if the mesh changed.
+// *****************************************************************************
+{
+  // Do corrections in solution based on incoming transfer
+  applySolTransfer(1);
+  m_ixfer = 0;
+
+  // No need for LHS in OversetFE
+
+  // If mesh moved: (Re-)compute boundary point- and dual-face normals, and
+  //   then proceed to stage()
+  // If mesh did not move: shortcut to stage()
+  if (m_movedmesh || Disc()->Initial()) norm();
+  else stage();
+}
+//! [Compute lhs]
+
+//! [Merge normals and continue]
+void
+OversetFE::mergelhs()
+// *****************************************************************************
+// The own and communication portion of the left-hand side is complete
+// *****************************************************************************
+{
+  // Combine own and communicated contributions of normals
+  normfinal();
+
+  // Start with time stepping logic
+  if (Disc()->Initial()) {
+    // Output initial conditions to file and then start time stepping
+    writeFields( CkCallback(CkIndex_OversetFE::start(), thisProxy[thisIndex]) );
+  }
+  else stage();
+}
+//! [Merge normals and continue]
+
+//! [start]
+void
+OversetFE::start()
+// *****************************************************************************
+// Start time stepping
+// *****************************************************************************
+{
+  // Set flag that indicates that we are now during time stepping
+  Disc()->Initial( 0 );
+  // Start timer measuring time stepping wall clock time
+  Disc()->Timer().zero();
+  // Zero grind-timer
+  Disc()->grindZero();
+  // Continue to first time step
+  next();
+}
+//! [start]
+
+void
+OversetFE::applySolTransfer(
+  std::size_t dirn )
+// *****************************************************************************
+// \brief Apply the transferred solution to the solution vector based on
+//   transfer flags previously set up
+//! \param[in] dirn 0 if called from B to O, 1 if called from O to B
+// *****************************************************************************
+{
+  // Change solution only if:
+  //   1. undergoing transfer from B to O, and currently on O
+  if (dirn == 0 && Disc()->MeshId() != 0) {
+
+    for (auto i : m_farfieldbcnodes) {
+      // overset-BC nodes: use transferred solution and blank nodes.
+      // the transfer-flag from m_uc is not used since it has been overwritten
+      // by Disc()->transfer() with the flag from B
+      for (ncomp_t c=0; c<m_u.nprop(); ++c) { // Loop over number of equations
+        m_u(i,c) = m_uc(i,c);
+      }
+      m_blank[i] = 0.0;
+    }
+
+  }
+  //   2. undergoing transfer from O to B, and currently on B
+  else if (dirn == 1 && Disc()->MeshId() == 0) {
+
+    //TODO: index the flag in a better way
+    std::size_t iflag = m_uc.nprop()-1;
+
+    // Zero out solution space for nodes with a specific transfer flag set
+    for (std::size_t i=0; i<m_uc.nunk(); ++i) { // Check flag value
+
+      if (std::abs(m_uc(i,iflag) - 1.0) < 1e-4) {
+        // overset-BC nodes: use transferred solution and blank nodes
+        for (ncomp_t c=0; c<m_u.nprop(); ++c) { // Loop over number of equations
+          m_u(i,c) = m_uc(i,c);
+        }
+        m_blank[i] = 0.0;
+      }
+      else if (std::abs(m_uc(i,iflag) - 2.0) < 1e-4) {
+        // hole: blank nodes
+        m_blank[i] = 0.0;
+      }
+      else {
+        // do nothing
+        m_blank[i] = 1.0;
+      }
+
+    }
+
+  }
+}
+
+void
+OversetFE::setTransferFlags(
+  std::size_t dirn )
+// *****************************************************************************
+//  Set flags informing solution transfer decisions
+//! \param[in] dirn 0 if called from B to O, 1 if called from O to B
+// *****************************************************************************
+{
+  // Copy solution and reset flags
+  //TODO: index the flag in a better way
+  std::size_t iflag = m_uc.nprop()-1;
+
+  for (std::size_t i=0; i<m_u.nunk(); ++i) {
+    for (std::size_t c=0; c<m_u.nprop(); ++c) {
+      m_uc(i,c) = m_u(i,c);
+    }
+    // Reset flags
+    m_uc(i,iflag) = 0.0;
+
+    // reset blanking coefficient
+    m_blank[i] = 1.0;
+  }
+
+  // Transfer flags for O to B are based on block-ids that are hardcoded
+  // TODO: remove hardcoding
+
+  // Called from transfer-B-to-O
+  if (dirn == 0) {
+    if (Disc()->MeshId() != 0) {
+      // Overset meshes: assign appropriate values to flag
+      for (auto i : m_farfieldbcnodes) m_uc(i,iflag) = 1.0;
+    }
+  }
+  // Called from transfer-O-to-B
+  else {
+    if (Disc()->MeshId() != 0) {
+      // Overset meshes: assign appropriate values to flag
+      for (const auto& [blid, ndset] : m_nodeblockid) {
+        if (blid == 103) {
+          for (auto i : ndset) m_uc(i,iflag) = 1.0;
+        }
+        else if (blid == 104) {
+          for (auto i : ndset) m_uc(i,iflag) = 2.0;
+        }
+      }
+    }
+  }
+}
+
+void
+OversetFE::normfinal()
+// *****************************************************************************
+//  Finish computing dual-face and boundary point normals
+// *****************************************************************************
+{
+  auto d = Disc();
+  const auto& lid = d->Lid();
+
+  // Combine own and communicated contributions to boundary point normals
+  for (const auto& [s,norms] : m_bnormc) {
+    auto& bnorms = m_bnorm[s];
+    for (const auto& [p,n] : norms) {
+      auto& norm = bnorms[p];
+      norm[0] += n[0];
+      norm[1] += n[1];
+      norm[2] += n[2];
+      norm[3] += n[3];
+    }
+  }
+  tk::destroy( m_bnormc );
+
+  // Divide summed point normals by the sum of inverse distance squared
+  for (auto& [s,norms] : m_bnorm)
+    for (auto& [p,n] : norms) {
+      n[0] /= n[3];
+      n[1] /= n[3];
+      n[2] /= n[3];
+      Assert( (n[0]*n[0] + n[1]*n[1] + n[2]*n[2] - 1.0) <
+              1.0e+3*std::numeric_limits< tk::real >::epsilon(),
+              "Non-unit normal" );
+    }
+
+  // Replace global->local ids associated to boundary point normals
+  decltype(m_bnorm) bnorm;
+  for (auto& [s,norms] : m_bnorm) {
+    auto& bnorms = bnorm[s];
+    for (auto&& [g,n] : norms)
+      bnorms[ tk::cref_find(lid,g) ] = std::move(n);
+  }
+  m_bnorm = std::move(bnorm);
+
+  // Count contributions to chare-boundary edges
+  std::unordered_map< tk::UnsMesh::Edge, std::size_t,
+    tk::UnsMesh::Hash<2>, tk::UnsMesh::Eq<2> > edge_node_count;
+  for (const auto& [c,edges] : d->EdgeCommMap())
+    for (const auto& e : edges)
+      ++edge_node_count[e];
+
+  // Combine and weigh communicated contributions to dual-face normals
+  for (auto& [e,n] : m_dfnormc) {
+    const auto& dfn = tk::cref_find( m_dfnorm, e );
+    n[0] += dfn[0];
+    n[1] += dfn[1];
+    n[2] += dfn[2];
+    auto count = static_cast< tk::real >( tk::cref_find( edge_node_count, e ) );
+    auto factor = 1.0/(count + 1.0);
+    for (auto & x : n) x *= factor;<--- Consider using std::transform algorithm instead of a raw loop.
+  }
+
+  // Generate list of unique edges
+  tk::UnsMesh::EdgeSet uedge;
+  for (std::size_t p=0; p<m_u.nunk(); ++p)
+    for (auto q : tk::Around(m_psup,p))
+      uedge.insert( {p,q} );
+
+  // Flatten edge list
+  m_edgenode.resize( uedge.size() * 2 );
+  std::size_t f = 0;
+  const auto& gid = d->Gid();
+  for (auto&& [p,q] : uedge) {
+    if (gid[p] > gid[q]) {
+      m_edgenode[f+0] = std::move(q);
+      m_edgenode[f+1] = std::move(p);
+    } else {
+      m_edgenode[f+0] = std::move(p);
+      m_edgenode[f+1] = std::move(q);
+    }
+    f += 2;
+  }
+  tk::destroy(uedge);
+
+  // Convert dual-face normals to streamable (and vectorizable) data structure
+  m_dfn.resize( m_edgenode.size() * 3 );      // 2 vectors per access
+  std::unordered_map< tk::UnsMesh::Edge, std::size_t,
+                      tk::UnsMesh::Hash<2>, tk::UnsMesh::Eq<2> > eid;
+  for (std::size_t e=0; e<m_edgenode.size()/2; ++e) {
+    auto p = m_edgenode[e*2+0];
+    auto q = m_edgenode[e*2+1];
+    eid[{p,q}] = e;
+    std::array< std::size_t, 2 > g{ gid[p], gid[q] };
+    auto n = tk::cref_find( m_dfnorm, g );
+    // figure out if this is an edge on the parallel boundary
+    auto nit = m_dfnormc.find( g );
+    auto m = ( nit != m_dfnormc.end() ) ? nit->second : n;
+    m_dfn[e*6+0] = n[0];
+    m_dfn[e*6+1] = n[1];
+    m_dfn[e*6+2] = n[2];
+    m_dfn[e*6+3] = m[0];
+    m_dfn[e*6+4] = m[1];
+    m_dfn[e*6+5] = m[2];
+  }
+
+  tk::destroy( m_dfnorm );
+  tk::destroy( m_dfnormc );
+
+  // Flatten edge id data structure
+  m_edgeid.resize( m_psup.first.size() );
+  for (std::size_t p=0,k=0; p<m_u.nunk(); ++p)
+    for (auto q : tk::Around(m_psup,p))
+      m_edgeid[k++] = tk::cref_find( eid, {p,q} );
+}
+
+void
+OversetFE::BC()
+// *****************************************************************************
+// Apply boundary conditions
+// \details The following BC enforcement changes the initial condition or
+//!   updated solution (dependending on when it is called) to ensure strong
+//!   imposition of the BCs. This is a matter of choice. Another alternative is
+//!   to only apply BCs when computing fluxes at boundary faces, thereby only
+//!   weakly enforcing the BCs. The former is conventionally used in continunous
+//!   Galerkin finite element methods (such as OversetFE implements), whereas the
+//!   latter, in finite volume methods.
+// *****************************************************************************
+{
+  auto d = Disc();
+  const auto& coord = d->Coord();
+
+  const auto& bcmesh = g_inputdeck.get< tag::bc >();
+
+  for (const auto& bci : bcmesh) {
+    const auto& bcm = bci.get< tag::mesh >();
+    for (const auto& im : bcm) {
+      // only if this bc is meant for current mesh
+      if (im-1 == d->MeshId()) {
+
+        // Query and match user-specified Dirichlet boundary conditions to side sets
+        const auto steady = g_inputdeck.get< tag::steady_state >();
+        if (steady) for (auto& deltat : m_dtp) deltat *= rkcoef[m_stage];<--- Consider using std::transform algorithm instead of a raw loop.
+        m_dirbc = match( d->MeshId(), m_u.nprop(), d->T(), rkcoef[m_stage] * d->Dt(),
+                         m_tp, m_dtp, d->Coord(), d->Lid(), m_bnode,
+                       /* increment = */ false );
+        if (steady) for (auto& deltat : m_dtp) deltat /= rkcoef[m_stage];<--- Consider using std::transform algorithm instead of a raw loop.
+
+        // Apply Dirichlet BCs
+        for (const auto& [b,bc] : m_dirbc)
+          for (ncomp_t c=0; c<m_u.nprop(); ++c)
+            if (bc[c].first) m_u(b,c) = bc[c].second;
+
+        // Apply symmetry BCs
+        g_cgpde[d->MeshId()].symbc( m_u, coord, m_bnorm, m_symbcnodes );
+
+        // Apply farfield BCs
+        if (bci.get< tag::farfield >().empty() || (d->MeshId() == 0)) {
+          g_cgpde[d->MeshId()].farfieldbc( m_u, coord, m_bnorm, m_farfieldbcnodes );
+        }
+
+        // Apply user defined time dependent BCs
+        g_cgpde[d->MeshId()].timedepbc( d->T(), m_u, m_timedepbcnodes,
+          m_timedepbcFn );
+      }
+    }
+  }
+}
+
+void
+OversetFE::next()
+// *****************************************************************************
+// Continue to next time step
+// *****************************************************************************
+{
+  dt();
+}
+
+void
+OversetFE::dt()
+// *****************************************************************************
+// Compute time step size
+// *****************************************************************************
+{
+  tk::real mindt = std::numeric_limits< tk::real >::max();
+
+  auto const_dt = g_inputdeck.get< tag::dt >();
+  auto eps = std::numeric_limits< tk::real >::epsilon();
+
+  auto d = Disc();
+
+  // use constant dt if configured
+  if (std::abs(const_dt) > eps) {
+
+    mindt = const_dt;
+
+  } else {      // compute dt based on CFL
+
+    //! [Find the minimum dt across all PDEs integrated]
+    if (g_inputdeck.get< tag::steady_state >()) {
+
+      // compute new dt for each mesh point
+      g_cgpde[d->MeshId()].dt( d->It(), d->Vol(), m_u, m_dtp );
+
+      // find the smallest dt of all nodes on this chare
+      mindt = *std::min_element( begin(m_dtp), end(m_dtp) );
+
+    } else {    // compute new dt for this chare
+
+      // find the smallest dt of all equations on this chare
+      auto eqdt = g_cgpde[d->MeshId()].dt( d->Coord(), d->Inpoel(), d->T(),
+        d->Dtn(), m_u, d->Vol(), d->Voln() );
+      if (eqdt < mindt) mindt = eqdt;
+
+    }
+    //! [Find the minimum dt across all PDEs integrated]
+
+  }
+
+  // Determine if this chunk of mesh needs to be moved
+  g_cgpde[d->MeshId()].getMeshVel(d->T(), d->Coord(), m_psup, m_symbcnodes,
+    m_uservel, m_u, d->MeshVel(), m_movedmesh);
+
+  //! [Advance]
+  // Actiavate SDAG waits for next time step stage
+  thisProxy[ thisIndex ].wait4grad();
+  thisProxy[ thisIndex ].wait4rhs();
+
+  // TODO: this is a hacky way to know if any chunk moved. redesign it
+  std::vector < tk::real > reducndata(d->Transfers().size()+2, 0.0);
+
+  reducndata[0] = mindt;
+  reducndata[d->MeshId()+1] = static_cast< tk::real >(-m_movedmesh);
+
+  // Contribute to minimum dt across all chares and advance to next step
+  if (g_inputdeck.get< tag::steady_state >()) {
+    contribute( reducndata, CkReduction::min_double,
+                CkCallback(CkReductionTarget(OversetFE,advance), thisProxy) );
+  }
+  else {
+    // if solving a time-accurate problem, find minimum dt across all meshes
+    // and eventually broadcast to OversetFE::advance()
+    contribute( reducndata, CkReduction::min_double,
+      CkCallback(CkReductionTarget(Transporter,minDtAcrossMeshes), d->Tr()) );
+  }
+  //! [Advance]
+}
+
+void
+OversetFE::advance( tk::real newdt, tk::real nmovedmesh )
+// *****************************************************************************
+// Advance equations to next time step
+//! \param[in] newdt The smallest dt across the whole problem
+//! \param[in] nmovedmesh (negative of) if any chunk of this mesh moved
+// *****************************************************************************
+{
+  auto d = Disc();
+
+  // Set new time step size
+  if (m_stage == 0) d->setdt( newdt );
+
+  // TODO: this is a hacky way to know if any chunk moved. redesign it
+  if (nmovedmesh < -0.1) m_movedmesh = 1;
+
+  // Compute gradients for next time step
+  chBndGrad();
+}
+
+void
+OversetFE::chBndGrad()
+// *****************************************************************************
+// Compute nodal gradients at chare-boundary nodes. Gradients at internal nodes
+// are calculated locally as needed and are not stored.
+// *****************************************************************************
+{
+  auto d = Disc();
+
+  // Compute own portion of gradients for all equations
+  g_cgpde[d->MeshId()].chBndGrad( d->Coord(), d->Inpoel(), m_bndel, d->Gid(),
+    d->Bid(), m_u, m_chBndGrad );
+
+  // Communicate gradients to other chares on chare-boundary
+  if (d->NodeCommMap().empty())        // in serial we are done
+    comgrad_complete();
+  else // send gradients contributions to chare-boundary nodes to fellow chares
+    for (const auto& [c,n] : d->NodeCommMap()) {
+      std::vector< std::vector< tk::real > > g( n.size() );
+      std::size_t j = 0;
+      for (auto i : n) g[ j++ ] = m_chBndGrad[ tk::cref_find(d->Bid(),i) ];
+      thisProxy[c].comChBndGrad( std::vector<std::size_t>(begin(n),end(n)), g );
+    }
+
+  owngrad_complete();
+}
+
+void
+OversetFE::comChBndGrad( const std::vector< std::size_t >& gid,
+                     const std::vector< std::vector< tk::real > >& G )
+// *****************************************************************************
+//  Receive contributions to nodal gradients on chare-boundaries
+//! \param[in] gid Global mesh node IDs at which we receive grad contributions
+//! \param[in] G Partial contributions of gradients to chare-boundary nodes
+//! \details This function receives contributions to m_chBndGrad, which stores
+//!   nodal gradients at mesh chare-boundary nodes. While m_chBndGrad stores
+//!   own contributions, m_chBndGradc collects the neighbor chare
+//!   contributions during communication. This way work on m_chBndGrad and
+//!   m_chBndGradc is overlapped. The two are combined in rhs().
+// *****************************************************************************
+{
+  Assert( G.size() == gid.size(), "Size mismatch" );
+
+  using tk::operator+=;
+
+  for (std::size_t i=0; i<gid.size(); ++i) m_chBndGradc[ gid[i] ] += G[i];
+
+  if (++m_ngrad == Disc()->NodeCommMap().size()) {
+    m_ngrad = 0;
+    comgrad_complete();
+  }
+}
+
+void
+OversetFE::rhs()
+// *****************************************************************************
+// Compute right-hand side of transport equations
+// *****************************************************************************
+{
+  auto d = Disc();
+
+  // Combine own and communicated contributions to nodal gradients
+  for (const auto& [gid,g] : m_chBndGradc) {
+    auto bid = tk::cref_find( d->Bid(), gid );
+    for (ncomp_t c=0; c<m_chBndGrad.nprop(); ++c)
+      m_chBndGrad(bid,c) += g[c];
+  }
+
+  // clear gradients receive buffer
+  tk::destroy(m_chBndGradc);
+
+  const auto steady = g_inputdeck.get< tag::steady_state >();
+
+  // Assign mesh velocity
+  if (m_movedmesh) {
+    const auto& coord = d->Coord();
+    auto& mvel = d->MeshVel();
+    for (std::size_t p=0; p<coord[0].size(); ++p) {
+      for (std::size_t i=0; i<3; ++i)
+        mvel(p, i) = m_uservel[i];
+    }
+  }
+
+  // Compute own portion of right-hand side for all equations
+  auto prev_rkcoef = m_stage == 0 ? 0.0 : rkcoef[m_stage-1];
+  if (steady)
+    for (std::size_t p=0; p<m_tp.size(); ++p) m_tp[p] += prev_rkcoef * m_dtp[p];
+  g_cgpde[d->MeshId()].rhs( d->T() + prev_rkcoef * d->Dt(), d->Coord(), d->Inpoel(),
+          m_triinpoel, d->Gid(), d->Bid(), d->Lid(), m_dfn, m_psup, m_esup,
+          m_symbctri, d->Vol(), m_edgenode, m_edgeid,
+          m_boxnodes, m_chBndGrad, m_u, d->MeshVel(), m_tp, d->Boxvol(),
+          m_rhs );
+  if (steady)
+    for (std::size_t p=0; p<m_tp.size(); ++p) m_tp[p] -= prev_rkcoef * m_dtp[p];
+
+  // Communicate rhs to other chares on chare-boundary
+  if (d->NodeCommMap().empty())        // in serial we are done
+    comrhs_complete();
+  else // send contributions of rhs to chare-boundary nodes to fellow chares
+    for (const auto& [c,n] : d->NodeCommMap()) {
+      std::vector< std::vector< tk::real > > r( n.size() );
+      std::size_t j = 0;
+      for (auto i : n) r[ j++ ] = m_rhs[ tk::cref_find(d->Lid(),i) ];
+      thisProxy[c].comrhs( std::vector<std::size_t>(begin(n),end(n)), r );
+    }
+
+  ownrhs_complete();
+}
+
+void
+OversetFE::comrhs( const std::vector< std::size_t >& gid,
+               const std::vector< std::vector< tk::real > >& R )
+// *****************************************************************************
+//  Receive contributions to right-hand side vector on chare-boundaries
+//! \param[in] gid Global mesh node IDs at which we receive RHS contributions
+//! \param[in] R Partial contributions of RHS to chare-boundary nodes
+//! \details This function receives contributions to m_rhs, which stores the
+//!   right hand side vector at mesh nodes. While m_rhs stores own
+//!   contributions, m_rhsc collects the neighbor chare contributions during
+//!   communication. This way work on m_rhs and m_rhsc is overlapped. The two
+//!   are combined in solve().
+// *****************************************************************************
+{
+  Assert( R.size() == gid.size(), "Size mismatch" );
+
+  using tk::operator+=;
+
+  for (std::size_t i=0; i<gid.size(); ++i) m_rhsc[ gid[i] ] += R[i];
+
+  // When we have heard from all chares we communicate with, this chare is done
+  if (++m_nrhs == Disc()->NodeCommMap().size()) {
+    m_nrhs = 0;
+    comrhs_complete();
+  }
+}
+
+void
+OversetFE::solve()
+// *****************************************************************************
+//  Advance systems of equations
+// *****************************************************************************
+{
+  auto d = Disc();
+
+  // Combine own and communicated contributions to rhs
+  for (const auto& b : m_rhsc) {
+    auto lid = tk::cref_find( d->Lid(), b.first );
+    for (ncomp_t c=0; c<m_rhs.nprop(); ++c) m_rhs(lid,c) += b.second[c];
+  }
+
+  // clear receive buffer
+  tk::destroy(m_rhsc);
+
+  // Update state at time n
+  if (m_stage == 0) {
+    m_un = m_u;
+  }
+
+  // Explicit time-stepping using RK3
+  const auto steady = g_inputdeck.get< tag::steady_state >();
+  for (std::size_t i=0; i<m_u.nunk(); ++i) {
+    // time-step
+    auto dtp = d->Dt();
+    if (steady) dtp = m_dtp[i];
+
+    for (ncomp_t c=0; c<m_u.nprop(); ++c)
+      m_u(i,c) = m_un(i,c) + m_blank[i] * rkcoef[m_stage] * dtp * m_rhs(i,c)
+        / d->Vol()[i];
+  }
+
+  // Move overset mesh
+  if (m_movedmesh) {
+    auto& x = d->Coord()[0];
+    auto& y = d->Coord()[1];
+    auto& z = d->Coord()[2];
+    const auto& w = d->MeshVel();
+    for (std::size_t i=0; i<w.nunk(); ++i) {
+      // time-step
+      auto dtp = d->Dt();
+      if (steady) dtp = m_dtp[i];
+
+      x[i] += rkcoef[m_stage] * dtp * w(i,0);
+      y[i] += rkcoef[m_stage] * dtp * w(i,1);
+      z[i] += rkcoef[m_stage] * dtp * w(i,2);
+    }
+  }
+  // the following line will be needed for situations where the mesh stops
+  // moving after its initial motion
+  // else m_movedmesh = 0;
+
+  // Apply boundary-conditions
+  BC();
+
+  // Increment Runge-Kutta stage counter
+  ++m_stage;
+
+  // Activate SDAG wait for next time step stage
+  thisProxy[ thisIndex ].wait4grad();
+  thisProxy[ thisIndex ].wait4rhs();
+
+  // Compute diagnostics, and finish-up time step (if m_stage == 3)
+  bool diag_computed(false);
+  if (m_stage == 3) {
+    // Compute diagnostics, e.g., residuals
+    diag_computed = m_diag.compute( *d, m_u, m_un, m_bnorm,
+                                    m_symbcnodes, m_farfieldbcnodes );
+    // Increase number of iterations and physical time
+    d->next();
+    // Advance physical time for local time stepping
+    if (g_inputdeck.get< tag::steady_state >())
+      for (std::size_t i=0; i<m_u.nunk(); ++i) m_tp[i] += m_dtp[i];
+  }
+  // Continue to finish-up time-step-stage
+  // Note: refine is called via a bcast if diag_computed == true
+  if (!diag_computed) refine( std::vector< tk::real >( m_u.nprop(), 1.0 ) );
+}
+
+//! [Refine]
+void
+OversetFE::refine( const std::vector< tk::real >& l2res )
+// *****************************************************************************
+// Finish up end of time-step procedures and continue to moving mesh
+//! \param[in] l2res L2-norms of the residual for each scalar component
+//!   computed across the whole problem
+// *****************************************************************************
+{
+  auto d = Disc();
+
+  if (m_stage == 3) {
+    const auto steady = g_inputdeck.get< tag::steady_state >();
+    const auto residual = g_inputdeck.get< tag::residual >();
+    const auto rc = g_inputdeck.get< tag::rescomp >() - 1;
+
+    if (m_movedmesh) {
+      d->Itf() = 0;  // Zero field output iteration count if mesh moved
+      ++d->Itr();    // Increase number of iterations with a change in the mesh
+    }
+
+    if (steady) {
+
+      // this is the last time step if max time of max number of time steps
+      // reached or the residual has reached its convergence criterion
+      if (d->finished() or l2res[rc] < residual) m_finished = 1;
+
+    } else {
+
+      // this is the last time step if max time or max iterations reached
+      if (d->finished()) m_finished = 1;
+
+    }
+  }
+
+  if (m_movedmesh) {
+    // Normals need to be recomputed if overset mesh has been moved
+    thisProxy[ thisIndex ].wait4norm();
+  }
+
+  // Start solution transfer
+  transferSol();
+}
+//! [Refine]
+
+//! [stage]
+void
+OversetFE::stage()
+// *****************************************************************************
+// Evaluate whether to continue with next time step stage
+// *****************************************************************************
+{
+  // if not all Runge-Kutta stages complete, continue to next time stage,
+  // otherwise start next time step
+  if (m_stage == 3) {
+    // output field data and start with next time step
+    out();
+  }
+  else {
+    // start with next time-step stage
+    chBndGrad();
+  }
+}
+//! [stage]
+
+void
+OversetFE::writeFields( CkCallback c )
+// *****************************************************************************
+// Output mesh-based fields to file
+//! \param[in] c Function to continue with after the write
+// *****************************************************************************
+{
+  if (g_inputdeck.get< tag::cmd, tag::benchmark >()) {
+
+    c.send();
+
+  } else {
+
+    auto d = Disc();
+    const auto& coord = d->Coord();
+
+    //// if coupled: depvars: src:'a', dst:'b','c',...
+    //char depvar = 0;
+    //if (not d->Transfers().empty()) {
+    //  depvar = 'a' + static_cast< char >( d->MeshId() );
+    //}
+
+    // Query fields names requested by user
+    auto nodefieldnames = numericFieldNames( tk::Centering::NODE );
+
+    // Collect field output from numerical solution requested by user
+    auto nodefields = numericFieldOutput( m_u, tk::Centering::NODE,
+      g_cgpde[Disc()->MeshId()].OutVarFn(), m_u );
+
+    // Collect field output names for analytical solutions
+    analyticFieldNames( g_cgpde[d->MeshId()], tk::Centering::NODE,
+      nodefieldnames );
+
+    // Collect field output from analytical solutions (if exist)
+    analyticFieldOutput( g_cgpde[d->MeshId()], tk::Centering::NODE, coord[0],
+      coord[1], coord[2], d->T(), nodefields );
+
+    // Query and collect nodal block and surface field names from PDEs integrated
+    std::vector< std::string > nodesurfnames;
+    auto sn = g_cgpde[d->MeshId()].surfNames();
+    nodesurfnames.insert( end(nodesurfnames), begin(sn), end(sn) );
+
+    // Collect nodal block and surface field solution
+    std::vector< std::vector< tk::real > > nodesurfs;
+    auto so = g_cgpde[d->MeshId()].surfOutput( tk::bfacenodes(m_bface,
+      m_triinpoel), m_u );
+    nodesurfs.insert( end(nodesurfs), begin(so), end(so) );
+
+    // Collect elemental block and surface field names from PDEs integrated
+    auto elemsurfnames = nodesurfnames;<--- Variable 'elemsurfnames' is assigned a value that is never used.
+
+    // Collect elemental block and surface field solution
+    std::vector< std::vector< tk::real > > elemsurfs;
+    auto eso = g_cgpde[d->MeshId()].elemSurfOutput( m_bface, m_triinpoel, m_u );
+    elemsurfs.insert( end(elemsurfs), begin(eso), end(eso) );
+
+    Assert( nodefieldnames.size() == nodefields.size(), "Size mismatch" );
+
+    // Send mesh and fields data (solution dump) for output to file
+    d->write( d->Inpoel(), coord, m_bface, tk::remap(m_bnode,d->Lid()),
+              m_triinpoel, {}, nodefieldnames, elemsurfnames,
+              nodesurfnames, {}, nodefields, elemsurfs, nodesurfs, c );
+
+  }
+}
+
+void
+OversetFE::out()
+// *****************************************************************************
+// Output mesh field data and continue to next time step
+// *****************************************************************************
+{
+  auto d = Disc();
+
+  // Output time history
+  if (d->histiter() or d->histtime() or d->histrange()) {
+    std::vector< std::vector< tk::real > > hist;
+    auto h = g_cgpde[d->MeshId()].histOutput( d->Hist(), d->Inpoel(), m_u );
+    hist.insert( end(hist), begin(h), end(h) );
+    d->history( std::move(hist) );
+  }
+
+  // Output field data
+  if (d->fielditer() or d->fieldtime() or d->fieldrange() or m_finished)
+    writeFields(CkCallback( CkIndex_OversetFE::step(), thisProxy[thisIndex]) );
+  else
+    step();
+}
+
+void
+OversetFE::evalLB( int nrestart )
+// *****************************************************************************
+// Evaluate whether to do load balancing
+//! \param[in] nrestart Number of times restarted
+// *****************************************************************************
+{
+  auto d = Disc();
+
+  // Detect if just returned from a checkpoint and if so, zero timers and
+  // finished flag
+  if (d->restarted( nrestart )) m_finished = 0;
+
+  const auto lbfreq = g_inputdeck.get< tag::cmd, tag::lbfreq >();
+  const auto nonblocking = g_inputdeck.get< tag::cmd, tag::nonblocking >();
+
+  // Load balancing if user frequency is reached or after the second time-step
+  if ( (d->It()) % lbfreq == 0 || d->It() == 2 ) {
+
+    AtSync();
+    if (nonblocking) next();
+
+  } else {
+
+    next();
+
+  }
+}
+
+void
+OversetFE::evalRestart()
+// *****************************************************************************
+// Evaluate whether to save checkpoint/restart
+// *****************************************************************************
+{
+  auto d = Disc();
+
+  const auto rsfreq = g_inputdeck.get< tag::cmd, tag::rsfreq >();
+  const auto benchmark = g_inputdeck.get< tag::cmd, tag::benchmark >();
+
+  if (not benchmark and not (d->It() % rsfreq)) {
+
+    std::vector< std::size_t > meshdata{ /* finished = */ 0, d->MeshId() };
+    contribute( meshdata, CkReduction::nop,
+      CkCallback(CkReductionTarget(Transporter,checkpoint), d->Tr()) );
+
+  } else {
+
+    evalLB( /* nrestart = */ -1 );
+
+  }
+}
+
+void
+OversetFE::step()
+// *****************************************************************************
+// Evaluate whether to continue with next time step
+// *****************************************************************************
+{
+  auto d = Disc();
+
+  // Output one-liner status report to screen
+  d->status();
+  // Reset Runge-Kutta stage counter
+  m_stage = 0;
+
+  if (not m_finished) {
+
+    evalRestart();
+
+  } else {
+
+    auto meshid = d->MeshId();
+    d->contribute( sizeof(std::size_t), &meshid, CkReduction::nop,
+                   CkCallback(CkReductionTarget(Transporter,finish), d->Tr()) );
+
+  }
+}
+
+#include "NoWarning/oversetfe.def.h"
 
diff --git a/Release/cppcheck/51.html b/Release/cppcheck/51.html index c9ed9a1f5a3d..a6f5b93fe3af 100644 --- a/Release/cppcheck/51.html +++ b/Release/cppcheck/51.html @@ -152,12 +152,12 @@
   1
@@ -1288,3549 +1288,1135 @@ 

Cppcheck report - [

// *****************************************************************************
+1129
// *****************************************************************************
 /*!
-  \file      src/Inciter/DG.cpp
+  \file      src/Inciter/FV.cpp
   \copyright 2012-2015 J. Bakosi,
              2016-2018 Los Alamos National Security, LLC.,
              2019-2021 Triad National Security, LLC.
              All rights reserved. See the LICENSE file for details.
-  \brief     DG advances a system of PDEs with the discontinuous Galerkin scheme
-  \details   DG advances a system of partial differential equations (PDEs) using
-    discontinuous Galerkin (DG) finite element (FE) spatial discretization (on
-    tetrahedron elements) combined with Runge-Kutta (RK) time stepping.
-  \see The documentation in DG.h.
-*/
-// *****************************************************************************
-
-#include <algorithm>
-#include <numeric>
-#include <sstream>
-
-#include "DG.hpp"
-#include "Discretization.hpp"
-#include "DGPDE.hpp"
-#include "DiagReducer.hpp"
-#include "DerivedData.hpp"
-#include "ElemDiagnostics.hpp"
-#include "Inciter/InputDeck/InputDeck.hpp"
-#include "Refiner.hpp"
-#include "Limiter.hpp"
+  \brief     FV advances a system of PDEs with the finite volume scheme
+  \details   FV advances a system of partial differential equations (PDEs) using
+    the finite volume (FV) (on tetrahedron elements).
+  \see The documentation in FV.h.
+*/
+// *****************************************************************************
+
+#include <algorithm>
+#include <numeric>
+#include <sstream>
+
+#include "FV.hpp"
+#include "Discretization.hpp"
+#include "FVPDE.hpp"
+#include "DiagReducer.hpp"
+#include "DerivedData.hpp"
+#include "ElemDiagnostics.hpp"
+#include "Inciter/InputDeck/InputDeck.hpp"
+#include "Refiner.hpp"
+#include "Limiter.hpp"
+#include "PrefIndicator.hpp"
 #include "Reorder.hpp"
 #include "Vector.hpp"
 #include "Around.hpp"
 #include "Integrate/Basis.hpp"
 #include "FieldOutput.hpp"
 #include "ChareStateCollector.hpp"
-#include "PDE/MultiMat/MultiMatIndexing.hpp"
-
-namespace inciter {
-
-extern ctr::InputDeck g_inputdeck;
-extern std::vector< DGPDE > g_dgpde;
-
-//! Runge-Kutta coefficients
-static const std::array< std::array< tk::real, 3 >, 2 >
-  rkcoef{{ {{ 0.0, 3.0/4.0, 1.0/3.0 }}, {{ 1.0, 1.0/4.0, 2.0/3.0 }} }};
-
-//! Implicit-Explicit Runge-Kutta Coefficients
-static const tk::real rk_gamma = (2.0-std::sqrt(2.0))/2.0;
-static const tk::real rk_delta = -2.0*std::sqrt(2.0)/3.0;
-static const tk::real c2 =
-  (27.0 + std::pow(2187.0-1458.0*std::sqrt(2.0),1.0/3.0)
-   + 9.0*std::pow(3.0+2.0*std::sqrt(2.0),1.0/3.0))/54.0;
-static const tk::real c3 = c2/(6.0*std::pow(c2,2.0)-3.0*c2+1.0);
-static const tk::real b2 = (3.0*c2-1.0)/(6.0*std::pow(c2,2.0));
-static const tk::real b3 =
-  (6.0*std::pow(c2,2.0)-3.0*c2+1.0)/(6.0*std::pow(c2,2.0));
-static const tk::real a22_impl = c2;
-static const tk::real a21_expl = c2;
-static const tk::real a32_expl = c3;
-static const tk::real a33_impl =
-  (1.0/6.0-b2*std::pow(c2,2.0)-b3*c2*c3)/(b3*(c3-c2));
-static const tk::real a32_impl = a33_impl-c3;
-static const std::array< std::array< tk::real, 3 >, 2 >
-  expl_rkcoef{{ {{ 0.0, 0.0, b2 }},
-                {{ a21_expl, a32_expl, b3 }} }};
-static const std::array< std::array< tk::real, 3 >, 2>
-  impl_rkcoef{{ {{ 0.0, a32_impl, b2 }},
-                {{ a22_impl, a33_impl, b3}} }};
-
-} // inciter::
-
-extern tk::CProxy_ChareStateCollector stateProxy;
-
-using inciter::DG;
-
-DG::DG( const CProxy_Discretization& disc,
-        const CProxy_Ghosts& ghostsproxy,
-        const std::map< int, std::vector< std::size_t > >& bface,
-        const std::map< int, std::vector< std::size_t > >& /* bnode */,
-        const std::vector< std::size_t >& triinpoel ) :
-  m_disc( disc ),
-  m_ghosts( ghostsproxy ),
-  m_ndof_NodalExtrm( 3 ), // for the first order derivatives in 3 directions
-  m_nsol( 0 ),
-  m_ninitsol( 0 ),
-  m_nlim( 0 ),
-  m_nnod( 0 ),
-  m_nrefine( 0 ),
-  m_nsmooth( 0 ),
-  m_nreco( 0 ),
-  m_nnodalExtrema( 0 ),
-  m_nstiffeq( g_dgpde[Disc()->MeshId()].nstiffeq() ),
-  m_nnonstiffeq( g_dgpde[Disc()->MeshId()].nnonstiffeq() ),
-  m_u( Disc()->Inpoel().size()/4,
-       g_inputdeck.get< tag::rdof >()*
-       g_inputdeck.get< tag::ncomp >() ),
-  m_un( m_u.nunk(), m_u.nprop() ),
-  m_p( m_u.nunk(), g_inputdeck.get< tag::rdof >()*
-    g_dgpde[Disc()->MeshId()].nprim() ),
-  m_lhs( m_u.nunk(),
-         g_inputdeck.get< tag::ndof >()*
-         g_inputdeck.get< tag::ncomp >() ),
-  m_rhs( m_u.nunk(), m_lhs.nprop() ),
-  m_rhsprev( m_u.nunk(), m_lhs.nprop() ),
-  m_stiffrhs( m_u.nunk(), g_inputdeck.get< tag::ndof >()*
-              g_dgpde[Disc()->MeshId()].nstiffeq() ),
-  m_stiffrhsprev( m_u.nunk(), g_inputdeck.get< tag::ndof >()*
-                  g_dgpde[Disc()->MeshId()].nstiffeq() ),
-  m_stiffEqIdx( g_dgpde[Disc()->MeshId()].nstiffeq() ),
-  m_nonStiffEqIdx( g_dgpde[Disc()->MeshId()].nnonstiffeq() ),
-  m_mtInv(
-    tk::invMassMatTaylorRefEl(g_inputdeck.get< tag::rdof >()) ),
-  m_uNodalExtrm(),
-  m_pNodalExtrm(),
-  m_uNodalExtrmc(),
-  m_pNodalExtrmc(),
-  m_npoin( Disc()->Coord()[0].size() ),
-  m_diag(),
-  m_stage( 0 ),
-  m_ndof(),
-  m_numEqDof(),
-  m_uc(),
-  m_pc(),
-  m_ndofc(),
-  m_initial( 1 ),
-  m_uElemfields( m_u.nunk(),
-                 g_inputdeck.get< tag::ncomp >() ),
-  m_pElemfields( m_u.nunk(),
-                 m_p.nprop() / g_inputdeck.get< tag::rdof >() ),
-  m_uNodefields( m_npoin,
-                 g_inputdeck.get< tag::ncomp >() ),
-  m_pNodefields( m_npoin,
-                 m_p.nprop() / g_inputdeck.get< tag::rdof >() ),
-  m_uNodefieldsc(),
-  m_pNodefieldsc(),
-  m_outmesh(),
-  m_boxelems(),
-  m_shockmarker(m_u.nunk(), 1),
-  m_rho0mat()
-// *****************************************************************************
-//  Constructor
-//! \param[in] disc Discretization proxy
-//! \param[in] bface Boundary-faces mapped to side set ids
-//! \param[in] triinpoel Boundary-face connectivity
+
+namespace inciter {
+
+extern ctr::InputDeck g_inputdeck;
+extern std::vector< FVPDE > g_fvpde;
+
+} // inciter::
+
+extern tk::CProxy_ChareStateCollector stateProxy;
+
+using inciter::FV;
+
+FV::FV( const CProxy_Discretization& disc,
+        const CProxy_Ghosts& ghostsproxy,
+        const std::map< int, std::vector< std::size_t > >& bface,
+        const std::map< int, std::vector< std::size_t > >& /* bnode */,
+        const std::vector< std::size_t >& triinpoel ) :
+  m_disc( disc ),
+  m_ghosts( ghostsproxy ),
+  m_nsol( 0 ),
+  m_ninitsol( 0 ),
+  m_nlim( 0 ),
+  m_nnod( 0 ),
+  m_u( Disc()->Inpoel().size()/4,
+       g_inputdeck.get< tag::rdof >()*
+       g_inputdeck.get< tag::ncomp >() ),
+  m_un( m_u.nunk(), m_u.nprop() ),
+  m_p( m_u.nunk(), g_inputdeck.get< tag::rdof >()*
+    g_fvpde[Disc()->MeshId()].nprim() ),
+  m_lhs( m_u.nunk(),
+         g_inputdeck.get< tag::ncomp >() ),
+  m_rhs( m_u.nunk(), m_lhs.nprop() ),
+  m_npoin( Disc()->Coord()[0].size() ),
+  m_diag(),
+  m_stage( 0 ),
+  m_uc(),
+  m_pc(),
+  m_initial( 1 ),
+  m_uElemfields( m_u.nunk(), m_lhs.nprop() ),
+  m_pElemfields(m_u.nunk(),
+    m_p.nprop()/g_inputdeck.get< tag::rdof >()),
+  m_uNodefields( m_npoin, m_lhs.nprop() ),
+  m_pNodefields(m_npoin,
+    m_p.nprop()/g_inputdeck.get< tag::rdof >()),
+  m_uNodefieldsc(),
+  m_pNodefieldsc(),
+  m_boxelems(),
+  m_srcFlag(m_u.nunk(), 0),
+  m_nrk(0),
+  m_dte(m_u.nunk(), 0.0),
+  m_finished(0)
+// *****************************************************************************
+//  Constructor
+//! \param[in] disc Discretization proxy
+//! \param[in] bface Boundary-faces mapped to side set ids
+//! \param[in] triinpoel Boundary-face connectivity
+// *****************************************************************************
+{
+  //! Runge-Kutta coefficients
+  m_nrk = 2;
+  m_rkcoef[0].resize(m_nrk);
+  m_rkcoef[1].resize(m_nrk);
+  if (m_nrk == 2) {
+    m_rkcoef = {{ {{ 0.0, 1.0/2.0 }}, {{ 1.0, 1.0/2.0 }} }};
+  }
+  else {
+    m_rkcoef = {{ {{ 0.0, 3.0/4.0, 1.0/3.0 }}, {{ 1.0, 1.0/4.0, 2.0/3.0 }} }};
+  }
+
+  if (g_inputdeck.get< tag::cmd, tag::chare >() ||
+      g_inputdeck.get< tag::cmd, tag::quiescence >())
+    stateProxy.ckLocalBranch()->insert( "FV", thisIndex, CkMyPe(), Disc()->It(),
+                                        "FV" );
+
+  usesAtSync = true;    // enable migration at AtSync
+
+  // Enable SDAG wait for initially building the solution vector and limiting
+  if (m_initial) {
+    thisProxy[ thisIndex ].wait4sol();
+    thisProxy[ thisIndex ].wait4lim();
+    thisProxy[ thisIndex ].wait4nod();
+  }
+
+  m_ghosts[thisIndex].insert(m_disc, bface, triinpoel, m_u.nunk(),
+    CkCallback(CkIndex_FV::resizeSolVectors(), thisProxy[thisIndex]));
+
+  // global-sync to call doneInserting on m_ghosts
+  auto meshid = Disc()->MeshId();
+  contribute( sizeof(std::size_t), &meshid, CkReduction::nop,
+    CkCallback(CkReductionTarget(Transporter,doneInsertingGhosts),
+    Disc()->Tr()) );
+}
+
+void
+FV::registerReducers()
+// *****************************************************************************
+//  Configure Charm++ reduction types
+//! \details Since this is a [initnode] routine, the runtime system executes the
+//!   routine exactly once on every logical node early on in the Charm++ init
+//!   sequence. Must be static as it is called without an object. See also:
+//!   Section "Initializations at Program Startup" at in the Charm++ manual
+//!   http://charm.cs.illinois.edu/manuals/html/charm++/manual.html.
+// *****************************************************************************
+{
+  ElemDiagnostics::registerReducers();
+}
+
+void
+FV::ResumeFromSync()
 // *****************************************************************************
-{
-  if (g_inputdeck.get< tag::cmd, tag::chare >() ||
-      g_inputdeck.get< tag::cmd, tag::quiescence >())
-    stateProxy.ckLocalBranch()->insert( "DG", thisIndex, CkMyPe(), Disc()->It(),
-                                        "DG" );
-
-  // assign number of dofs for each equation in all pde systems
-  g_dgpde[Disc()->MeshId()].numEquationDofs(m_numEqDof);
-
-  // Allocate storage for the vector of nodal extrema
-  m_uNodalExtrm.resize( Disc()->Bid().size(),
-    std::vector<tk::real>( 2 * m_ndof_NodalExtrm *
-    g_inputdeck.get< tag::ncomp >() ) );
-  m_pNodalExtrm.resize( Disc()->Bid().size(),
-    std::vector<tk::real>( 2 * m_ndof_NodalExtrm *
-    m_p.nprop() / g_inputdeck.get< tag::rdof >() ) );
-
-  // Initialization for the buffer vector of nodal extrema
-  resizeNodalExtremac();
-
-  usesAtSync = true;    // enable migration at AtSync
-
-  // Enable SDAG wait for initially building the solution vector and limiting
-  if (m_initial) {
-    thisProxy[ thisIndex ].wait4sol();
-    thisProxy[ thisIndex ].wait4refine();
-    thisProxy[ thisIndex ].wait4smooth();
-    thisProxy[ thisIndex ].wait4lim();
-    thisProxy[ thisIndex ].wait4nod();
-    thisProxy[ thisIndex ].wait4reco();
-    thisProxy[ thisIndex ].wait4nodalExtrema();
-  }
-
-  m_ghosts[thisIndex].insert(m_disc, bface, triinpoel, m_u.nunk(),
-    CkCallback(CkIndex_DG::resizeSolVectors(), thisProxy[thisIndex]));
-
-  // global-sync to call doneInserting on m_ghosts
-  auto meshid = Disc()->MeshId();
-  contribute( sizeof(std::size_t), &meshid, CkReduction::nop,
-    CkCallback(CkReductionTarget(Transporter,doneInsertingGhosts),
-    Disc()->Tr()) );
-}
-
-void
-DG::registerReducers()
-// *****************************************************************************
-//  Configure Charm++ reduction types
-//! \details Since this is a [initnode] routine, the runtime system executes the
-//!   routine exactly once on every logical node early on in the Charm++ init
-//!   sequence. Must be static as it is called without an object. See also:
-//!   Section "Initializations at Program Startup" at in the Charm++ manual
-//!   http://charm.cs.illinois.edu/manuals/html/charm++/manual.html.
-// *****************************************************************************
-{
-  ElemDiagnostics::registerReducers();
-}
+//  Return from migration
+//! \details This is called when load balancing (LB) completes. The presence of
+//!   this function does not affect whether or not we block on LB.
+// *****************************************************************************
+{
+  if (Disc()->It() == 0) Throw( "it = 0 in ResumeFromSync()" );
+
+  if (!g_inputdeck.get< tag::cmd, tag::nonblocking >()) next();
+}
+
+void
+FV::resizeSolVectors()
+// *****************************************************************************
+// Resize solution vectors after extension due to Ghosts
+// *****************************************************************************
+{
+  // Resize solution vectors, lhs and rhs by the number of ghost tets
+  m_u.resize( myGhosts()->m_nunk );
+  m_un.resize( myGhosts()->m_nunk );
+  m_srcFlag.resize( myGhosts()->m_nunk );
+  m_p.resize( myGhosts()->m_nunk );
+  m_lhs.resize( myGhosts()->m_nunk );
+  m_rhs.resize( myGhosts()->m_nunk );
+  m_dte.resize( myGhosts()->m_nunk );
+
+  // Size communication buffer for solution
+  for (auto& u : m_uc) u.resize( myGhosts()->m_bid.size() );
+  for (auto& p : m_pc) p.resize( myGhosts()->m_bid.size() );
+
+  // Ensure that we also have all the geometry and connectivity data
+  // (including those of ghosts)
+  Assert( myGhosts()->m_geoElem.nunk() == m_u.nunk(),
+    "GeoElem unknowns size mismatch" );
+
+  // Signal the runtime system that all workers have received their adjacency
+  std::vector< std::size_t > meshdata{ myGhosts()->m_initial, Disc()->MeshId() };
+  contribute( meshdata, CkReduction::sum_ulong,
+    CkCallback(CkReductionTarget(Transporter,comfinal), Disc()->Tr()) );
+}
+
+void
+FV::setup()
+// *****************************************************************************
+// Set initial conditions, generate lhs, output mesh
+// *****************************************************************************
+{
+  if (g_inputdeck.get< tag::cmd, tag::chare >() ||
+      g_inputdeck.get< tag::cmd, tag::quiescence >())
+    stateProxy.ckLocalBranch()->insert( "FV", thisIndex, CkMyPe(), Disc()->It(),
+                                        "setup" );
+
+  auto d = Disc();<--- Variable 'd' is assigned a value that is never used.
+
+  // Basic error checking on sizes of element geometry data and connectivity
+  Assert( myGhosts()->m_geoElem.nunk() == m_lhs.nunk(),
+    "Size mismatch in FV::setup()" );
 
-void
-DG::ResumeFromSync()
-// *****************************************************************************
-//  Return from migration
-//! \details This is called when load balancing (LB) completes. The presence of
-//!   this function does not affect whether or not we block on LB.
-// *****************************************************************************
-{
-  if (Disc()->It() == 0) Throw( "it = 0 in ResumeFromSync()" );
+  // Compute left-hand side of discrete PDEs
+  lhs();
+
+  // Determine elements inside user-defined IC box
+  g_fvpde[d->MeshId()].IcBoxElems( myGhosts()->m_geoElem,
+    myGhosts()->m_fd.Esuel().size()/4, m_boxelems );
+
+  // Compute volume of user-defined box IC
+  d->boxvol( {}, {}, 0 );      // punt for now
 
-  if (!g_inputdeck.get< tag::cmd, tag::nonblocking >()) next();
-}
-
-void
-DG::resizeSolVectors()
-// *****************************************************************************
-// Resize solution vectors after extension due to Ghosts and continue with setup
-// *****************************************************************************
-{
-  // Resize solution vectors, lhs and rhs by the number of ghost tets
-  m_u.resize( myGhosts()->m_nunk );
-  m_un.resize( myGhosts()->m_nunk );
-  m_p.resize( myGhosts()->m_nunk );
-  m_lhs.resize( myGhosts()->m_nunk );
-  m_rhs.resize( myGhosts()->m_nunk );
-  m_rhsprev.resize( myGhosts()->m_nunk );
-  m_stiffrhs.resize( myGhosts()->m_nunk );
-  m_stiffrhsprev.resize( myGhosts()->m_nunk );
+  // Query time history field output labels from all PDEs integrated
+  const auto& hist_points = g_inputdeck.get< tag::history_output, tag::point >();
+  if (!hist_points.empty()) {
+    std::vector< std::string > histnames;
+    auto n = g_fvpde[d->MeshId()].histNames();
+    histnames.insert( end(histnames), begin(n), end(n) );
+    d->histheader( std::move(histnames) );
+  }
+}
+
+void
+FV::box( tk::real v, const std::vector< tk::real >& )
+// *****************************************************************************
+// Receive total box IC volume and set conditions in box
+//! \param[in] v Total volume within user-specified box
+// *****************************************************************************
+{
+  auto d = Disc();
 
-  // Size communication buffer for solution and number of degrees of freedom
-  for (auto& n : m_ndofc) n.resize( myGhosts()->m_bid.size() );
-  for (auto& u : m_uc) u.resize( myGhosts()->m_bid.size() );
-  for (auto& p : m_pc) p.resize( myGhosts()->m_bid.size() );
-
-  // Initialize number of degrees of freedom in mesh elements
-  const auto pref = g_inputdeck.get< tag::pref, tag::pref >();
-  if( pref )
-  {
-    const auto ndofmax = g_inputdeck.get< tag::pref, tag::ndofmax >();
-    m_ndof.resize( myGhosts()->m_nunk, ndofmax );
-  }
-  else
-  {
-    const auto ndof = g_inputdeck.get< tag::ndof >();
-    m_ndof.resize( myGhosts()->m_nunk, ndof );
-  }
-
-  // Ensure that we also have all the geometry and connectivity data
-  // (including those of ghosts)
-  Assert( myGhosts()->m_geoElem.nunk() == m_u.nunk(),
-    "GeoElem unknowns size mismatch" );
-
-  // Signal the runtime system that all workers have received their adjacency
-  std::vector< std::size_t > meshdata{ myGhosts()->m_initial, Disc()->MeshId() };
-  contribute( meshdata, CkReduction::sum_ulong,
-    CkCallback(CkReductionTarget(Transporter,comfinal), Disc()->Tr()) );
-}
-
-void
-DG::setup()
-// *****************************************************************************
-// Set initial conditions, generate lhs, output mesh
-// *****************************************************************************
-{
-  if (g_inputdeck.get< tag::cmd, tag::chare >() ||
-      g_inputdeck.get< tag::cmd, tag::quiescence >())
-    stateProxy.ckLocalBranch()->insert( "DG", thisIndex, CkMyPe(), Disc()->It(),
-                                        "setup" );
+  // Store user-defined box IC volume
+  d->Boxvol() = v;
+
+  // Set initial conditions for all PDEs
+  g_fvpde[d->MeshId()].initialize( m_lhs, myGhosts()->m_inpoel,
+    myGhosts()->m_coord, m_boxelems, d->ElemBlockId(), m_u, d->T(),
+    myGhosts()->m_fd.Esuel().size()/4 );
+  g_fvpde[d->MeshId()].updatePrimitives( m_u, m_p,
+    myGhosts()->m_fd.Esuel().size()/4 );
+
+  m_un = m_u;
+
+  // Output initial conditions to file (regardless of whether it was requested)
+  startFieldOutput( CkCallback(CkIndex_FV::start(), thisProxy[thisIndex]) );
+}
+
+void
+FV::start()
+// *****************************************************************************
+//  Start time stepping
+// *****************************************************************************
+{
+  // Start timer measuring time stepping wall clock time
+  Disc()->Timer().zero();
+  // Zero grind-timer
+  Disc()->grindZero();
+  // Start time stepping by computing the size of the next time step)
+  next();
+}
+
+void
+FV::startFieldOutput( CkCallback c )
+// *****************************************************************************
+// Start preparing fields for output to file
+//! \param[in] c Function to continue with after the write
+// *****************************************************************************
+{
+  // No field output in benchmark mode or if field output frequency not hit
+  if (g_inputdeck.get< tag::cmd, tag::benchmark >() || !fieldOutput()) {
 
-  auto d = Disc();<--- Variable 'd' is assigned a value that is never used.
-
-  // Basic error checking on sizes of element geometry data and connectivity
-  Assert( myGhosts()->m_geoElem.nunk() == m_lhs.nunk(),
-    "Size mismatch in DG::setup()" );
-
-  // Compute left-hand side of discrete PDEs
-  lhs();
+    c.send();
+
+  } else {
+
+    // Optionally refine mesh for field output
+    auto d = Disc();
+
+    if (refinedOutput()) {
 
-  // Determine elements inside user-defined IC box
-  g_dgpde[d->MeshId()].IcBoxElems( myGhosts()->m_geoElem,
-    myGhosts()->m_fd.Esuel().size()/4, m_boxelems );
-
-  // Compute volume of user-defined box IC
-  d->boxvol( {}, {}, 0 );      // punt for now
-
-  // Query time history field output labels from all PDEs integrated
-  const auto& hist_points = g_inputdeck.get< tag::history_output, tag::point >();
-  if (!hist_points.empty()) {
-    std::vector< std::string > histnames;
-    auto n = g_dgpde[d->MeshId()].histNames();
-    histnames.insert( end(histnames), begin(n), end(n) );
-    d->histheader( std::move(histnames) );
-  }
-
-  // If working with IMEX-RK, Store stiff equations into m_stiffEqIdx
-  if (g_inputdeck.get< tag::imex_runge_kutta >())
-  {
-    g_dgpde[Disc()->MeshId()].setStiffEqIdx(m_stiffEqIdx);
-    g_dgpde[Disc()->MeshId()].setNonStiffEqIdx(m_nonStiffEqIdx);
-  }
-}
-
-void
-DG::box( tk::real v, const std::vector< tk::real >& )
-// *****************************************************************************
-// Receive total box IC volume and set conditions in box
-//! \param[in] v Total volume within user-specified box
-// *****************************************************************************
-{
-  auto d = Disc();
-
-  // Store user-defined box IC volume
-  d->Boxvol() = v;
-
-  // Set initial conditions for all PDEs
-  g_dgpde[d->MeshId()].initialize( m_lhs, myGhosts()->m_inpoel,
-    myGhosts()->m_coord, m_boxelems, d->ElemBlockId(), m_u, d->T(),
-    myGhosts()->m_fd.Esuel().size()/4 );
-  g_dgpde[d->MeshId()].updatePrimitives( m_u, m_lhs, myGhosts()->m_geoElem, m_p,
-    myGhosts()->m_fd.Esuel().size()/4 );
-  // Save initial densities of all materials
-  g_dgpde[d->MeshId()].setRho0mat( m_rho0mat );
-
-  m_un = m_u;
-
-  // Output initial conditions to file (regardless of whether it was requested)
-  startFieldOutput( CkCallback(CkIndex_DG::start(), thisProxy[thisIndex]) );
-}
-
-void
-DG::start()
-// *****************************************************************************
-//  Start time stepping
-// *****************************************************************************
-{
-  // Free memory storing output mesh
-  m_outmesh.destroy();
-
-  // Start timer measuring time stepping wall clock time
-  Disc()->Timer().zero();
-  // Zero grind-timer
-  Disc()->grindZero();
-  // Start time stepping by computing the size of the next time step)
-  next();
-}
-
-void
-DG::startFieldOutput( CkCallback c )
-// *****************************************************************************
-// Start preparing fields for output to file
-//! \param[in] c Function to continue with after the write
-// *****************************************************************************
-{
-  // No field output in benchmark mode or if field output frequency not hit
-  if (g_inputdeck.get< tag::cmd, tag::benchmark >() || !fieldOutput()) {
-
-    c.send();
-
-  } else {
-
-    // Optionally refine mesh for field output
-    auto d = Disc();
-
-    if (refinedOutput()) {
-
-      const auto& tr = tk::remap( myGhosts()->m_fd.Triinpoel(), d->Gid() );
-      d->Ref()->outref( myGhosts()->m_fd.Bface(), {}, tr, c );
-
-    } else {
-
-      // cut off ghosts from mesh connectivity and coordinates
-      const auto& tr = tk::remap( myGhosts()->m_fd.Triinpoel(), d->Gid() );
-      extractFieldOutput( {}, d->Chunk(), d->Coord(), {}, {},
-                          d->NodeCommMap(), myGhosts()->m_fd.Bface(), {}, tr, c );
-
-    }
-
-  }
-}
-
-void
-DG::next()
-// *****************************************************************************
-// Advance equations to next time step
-// *****************************************************************************
-{
-  const auto pref = g_inputdeck.get< tag::pref, tag::pref >();
-
-  auto d = Disc();
-
-  if (pref && m_stage == 0 && d->T() > 0)
-    g_dgpde[d->MeshId()].eval_ndof( myGhosts()->m_nunk, myGhosts()->m_coord,
-                  myGhosts()->m_inpoel,
-                  myGhosts()->m_fd, m_u, m_p,
-                  g_inputdeck.get< tag::pref, tag::indicator >(),
-                  g_inputdeck.get< tag::ndof >(),
-                  g_inputdeck.get< tag::pref, tag::ndofmax >(),
-                  g_inputdeck.get< tag::pref, tag::tolref >(),
-                  m_ndof );
-
-  // communicate solution ghost data (if any)
-  if (myGhosts()->m_sendGhost.empty())
-    comsol_complete();
-  else
-    for(const auto& [cid, ghostdata] : myGhosts()->m_sendGhost) {
-      std::vector< std::size_t > tetid( ghostdata.size() );
-      std::vector< std::vector< tk::real > > u( ghostdata.size() ),
-                                             prim( ghostdata.size() );
-      std::vector< std::size_t > ndof;
-      std::size_t j = 0;
-      for(const auto& i : ghostdata) {
-        Assert( i < myGhosts()->m_fd.Esuel().size()/4,
-          "Sending solution ghost data" );
-        tetid[j] = i;
-        u[j] = m_u[i];
-        prim[j] = m_p[i];
-        if (pref && m_stage == 0) ndof.push_back( m_ndof[i] );
-        ++j;
-      }
-      thisProxy[ cid ].comsol( thisIndex, m_stage, tetid, u, prim, ndof );
+      const auto& tr = tk::remap( myGhosts()->m_fd.Triinpoel(), d->Gid() );
+      d->Ref()->outref( myGhosts()->m_fd.Bface(), {}, tr, c );
+
+    } else {
+
+      // cut off ghosts from mesh connectivity and coordinates
+      extractFieldOutput( {}, d->Chunk(), d->Coord(), {}, {}, d->NodeCommMap(),
+        {}, {}, {}, c );
+
+    }
+
+  }
+}
+
+void
+FV::next()
+// *****************************************************************************
+// Advance equations to next time step
+// *****************************************************************************
+{
+  // communicate solution ghost data (if any)
+  if (myGhosts()->m_sendGhost.empty())
+    comsol_complete();
+  else
+    for(const auto& [cid, ghostdata] : myGhosts()->m_sendGhost) {
+      std::vector< std::size_t > tetid( ghostdata.size() );
+      std::vector< std::vector< tk::real > > u( ghostdata.size() ),
+                                             prim( ghostdata.size() );
+      std::size_t j = 0;
+      for(const auto& i : ghostdata) {
+        Assert( i < myGhosts()->m_fd.Esuel().size()/4,
+          "Sending solution ghost data" );
+        tetid[j] = i;
+        u[j] = m_u[i];
+        prim[j] = m_p[i];
+        ++j;
+      }
+      thisProxy[ cid ].comsol( thisIndex, tetid, u, prim );
+    }
+
+  ownsol_complete();
+}
+
+void
+FV::comsol( int fromch,
+            const std::vector< std::size_t >& tetid,
+            const std::vector< std::vector< tk::real > >& u,
+            const std::vector< std::vector< tk::real > >& prim )
+// *****************************************************************************
+//  Receive chare-boundary solution ghost data from neighboring chares
+//! \param[in] fromch Sender chare id
+//! \param[in] tetid Ghost tet ids we receive solution data for
+//! \param[in] u Solution ghost data
+//! \param[in] prim Primitive variables in ghost cells
+//! \details This function receives contributions to the unlimited solution
+//!   from fellow chares.
+// *****************************************************************************
+{
+  Assert( u.size() == tetid.size(), "Size mismatch in FV::comsol()" );
+  Assert( prim.size() == tetid.size(), "Size mismatch in FV::comsol()" );
+
+  // Find local-to-ghost tet id map for sender chare
+  const auto& n = tk::cref_find( myGhosts()->m_ghost, fromch );
+
+  for (std::size_t i=0; i<tetid.size(); ++i) {
+    auto j = tk::cref_find( n, tetid[i] );
+    Assert( j >= myGhosts()->m_fd.Esuel().size()/4,
+      "Receiving solution non-ghost data" );
+    auto b = tk::cref_find( myGhosts()->m_bid, j );
+    Assert( b < m_uc[0].size(), "Indexing out of bounds" );
+    m_uc[0][b] = u[i];
+    m_pc[0][b] = prim[i];
+  }
+
+  // if we have received all solution ghost contributions from neighboring
+  // chares (chares we communicate along chare-boundary faces with), and
+  // contributed our solution to these neighbors, proceed to reconstructions
+  if (++m_nsol == myGhosts()->m_sendGhost.size()) {
+    m_nsol = 0;
+    comsol_complete();
+  }
+}
+
+void
+FV::extractFieldOutput(
+  const std::vector< std::size_t >& /*ginpoel*/,
+  const tk::UnsMesh::Chunk& chunk,
+  const tk::UnsMesh::Coords& coord,
+  const std::unordered_map< std::size_t, tk::UnsMesh::Edge >& /*addedNodes*/,
+  const std::unordered_map< std::size_t, std::size_t >& addedTets,
+  const tk::NodeCommMap& nodeCommMap,
+  const std::map< int, std::vector< std::size_t > >& /* bface */,
+  const std::map< int, std::vector< std::size_t > >& /* bnode */,
+  const std::vector< std::size_t >& /* triinpoel */,
+  CkCallback c )
+// *****************************************************************************
+// Extract field output going to file
+//! \param[in] chunk Field-output mesh chunk (connectivity and global<->local
+//!    id maps)
+//! \param[in] coord Field-output mesh node coordinates
+//! \param[in] addedTets Field-output mesh cells and their parents (local ids)
+//! \param[in] nodeCommMap Field-output mesh node communication map
+//! \param[in] c Function to continue with after the write
+// *****************************************************************************
+{
+  const auto& inpoel = std::get< 0 >( chunk );
+
+  // Evaluate element solution on incoming mesh
+  evalSolution( *Disc(), inpoel, coord, addedTets, std::vector< std::size_t>{},
+    m_u, m_p, m_uElemfields, m_pElemfields, m_uNodefields, m_pNodefields );
+
+  // Send node fields contributions to neighbor chares
+  if (nodeCommMap.empty())
+    comnodeout_complete();
+  else {
+    const auto& lid = std::get< 2 >( chunk );
+    auto esup = tk::genEsup( inpoel, 4 );
+    for(const auto& [ch,nodes] : nodeCommMap) {
+      // Pack node field data in chare boundary nodes
+      std::vector< std::vector< tk::real > >
+        lu( m_uNodefields.nprop(), std::vector< tk::real >( nodes.size() ) );
+      std::vector< std::vector< tk::real > >
+        lp( m_pNodefields.nprop(), std::vector< tk::real >( nodes.size() ) );
+      for (std::size_t f=0; f<m_uNodefields.nprop(); ++f) {
+        std::size_t j = 0;
+        for (auto g : nodes)
+          lu[f][j++] = m_uNodefields(tk::cref_find(lid,g),f);
+      }
+      for (std::size_t f=0; f<m_pNodefields.nprop(); ++f) {
+        std::size_t j = 0;
+        for (auto g : nodes)
+          lp[f][j++] = m_pNodefields(tk::cref_find(lid,g),f);
+      }
+      // Pack (partial) number of elements surrounding chare boundary nodes
+      std::vector< std::size_t > nesup( nodes.size() );
+      std::size_t j = 0;
+      for (auto g : nodes) {
+        auto i = tk::cref_find( lid, g );
+        nesup[j++] = esup.second[i+1] - esup.second[i];
+      }
+      thisProxy[ch].comnodeout(
+        std::vector<std::size_t>(begin(nodes),end(nodes)), nesup, lu, lp );
     }
-
-  ownsol_complete();
-}
-
-void
-DG::comsol( int fromch,
-            std::size_t fromstage,
-            const std::vector< std::size_t >& tetid,
-            const std::vector< std::vector< tk::real > >& u,
-            const std::vector< std::vector< tk::real > >& prim,
-            const std::vector< std::size_t >& ndof )
-// *****************************************************************************
-//  Receive chare-boundary solution ghost data from neighboring chares
-//! \param[in] fromch Sender chare id
-//! \param[in] fromstage Sender chare time step stage
-//! \param[in] tetid Ghost tet ids we receive solution data for
-//! \param[in] u Solution ghost data
-//! \param[in] prim Primitive variables in ghost cells
-//! \param[in] ndof Number of degrees of freedom for chare-boundary elements
-//! \details This function receives contributions to the unlimited solution
-//!   from fellow chares.
-// *****************************************************************************
-{
-  Assert( u.size() == tetid.size(), "Size mismatch in DG::comsol()" );
-  Assert( prim.size() == tetid.size(), "Size mismatch in DG::comsol()" );
-
-  const auto pref = g_inputdeck.get< tag::pref, tag::pref >();
-
-  if (pref && fromstage == 0)
-    Assert( ndof.size() == tetid.size(), "Size mismatch in DG::comsol()" );
-
-  // Find local-to-ghost tet id map for sender chare
-  const auto& n = tk::cref_find( myGhosts()->m_ghost, fromch );
-
-  for (std::size_t i=0; i<tetid.size(); ++i) {
-    auto j = tk::cref_find( n, tetid[i] );
-    Assert( j >= myGhosts()->m_fd.Esuel().size()/4,
-      "Receiving solution non-ghost data" );
-    auto b = tk::cref_find( myGhosts()->m_bid, j );
-    Assert( b < m_uc[0].size(), "Indexing out of bounds" );
-    m_uc[0][b] = u[i];
-    m_pc[0][b] = prim[i];
-    if (pref && fromstage == 0) {
-      Assert( b < m_ndofc[0].size(), "Indexing out of bounds" );
-      m_ndofc[0][b] = ndof[i];
-    }
-  }
-
-  // if we have received all solution ghost contributions from neighboring
-  // chares (chares we communicate along chare-boundary faces with), and
-  // contributed our solution to these neighbors, proceed to reconstructions
-  if (++m_nsol == myGhosts()->m_sendGhost.size()) {
-    m_nsol = 0;
-    comsol_complete();
-  }
-}
-
-void
-DG::extractFieldOutput(
-  const std::vector< std::size_t >& /*ginpoel*/,
-  const tk::UnsMesh::Chunk& chunk,
-  const tk::UnsMesh::Coords& coord,
-  const std::unordered_map< std::size_t, tk::UnsMesh::Edge >& /*addedNodes*/,
-  const std::unordered_map< std::size_t, std::size_t >& addedTets,
-  const tk::NodeCommMap& nodeCommMap,
-  const std::map< int, std::vector< std::size_t > >& bface,
-  const std::map< int, std::vector< std::size_t > >& /* bnode */,
-  const std::vector< std::size_t >& triinpoel,
-  CkCallback c )
-// *****************************************************************************
-// Extract field output going to file
-//! \param[in] chunk Field-output mesh chunk (connectivity and global<->local
-//!    id maps)
-//! \param[in] coord Field-output mesh node coordinates
-//! \param[in] addedTets Field-output mesh cells and their parents (local ids)
-//! \param[in] nodeCommMap Field-output mesh node communication map
-//! \param[in] bface Field-output meshndary-faces mapped to side set ids
-//! \param[in] triinpoel Field-output mesh boundary-face connectivity
-//! \param[in] c Function to continue with after the write
-// *****************************************************************************
-{
-  m_outmesh.chunk = chunk;
-  m_outmesh.coord = coord;
-  m_outmesh.triinpoel = triinpoel;
-  m_outmesh.bface = bface;
-  m_outmesh.nodeCommMap = nodeCommMap;
-
-  const auto& inpoel = std::get< 0 >( chunk );
-
-  // Evaluate element solution on incoming mesh
-  evalSolution( *Disc(), inpoel, coord, addedTets, m_ndof, m_u, m_p,
-    m_uElemfields, m_pElemfields, m_uNodefields, m_pNodefields );
-
-  // Send node fields contributions to neighbor chares
-  if (nodeCommMap.empty())
-    comnodeout_complete();
-  else {
-    const auto& lid = std::get< 2 >( chunk );
-    auto esup = tk::genEsup( inpoel, 4 );
-    for(const auto& [ch,nodes] : nodeCommMap) {
-      // Pack node field data in chare boundary nodes
-      std::vector< std::vector< tk::real > >
-        lu( m_uNodefields.nprop(), std::vector< tk::real >( nodes.size() ) );
-      std::vector< std::vector< tk::real > >
-        lp( m_pNodefields.nprop(), std::vector< tk::real >( nodes.size() ) );
-      for (std::size_t f=0; f<m_uNodefields.nprop(); ++f) {
-        std::size_t j = 0;
-        for (auto g : nodes)
-          lu[f][j++] = m_uNodefields(tk::cref_find(lid,g),f);
-      }
-      for (std::size_t f=0; f<m_pNodefields.nprop(); ++f) {
-        std::size_t j = 0;
-        for (auto g : nodes)
-          lp[f][j++] = m_pNodefields(tk::cref_find(lid,g),f);
-      }
-      // Pack (partial) number of elements surrounding chare boundary nodes
-      std::vector< std::size_t > nesup( nodes.size() );
-      std::size_t j = 0;
-      for (auto g : nodes) {
-        auto i = tk::cref_find( lid, g );
-        nesup[j++] = esup.second[i+1] - esup.second[i];
-      }
-      thisProxy[ch].comnodeout(
-        std::vector<std::size_t>(begin(nodes),end(nodes)), nesup, lu, lp );
-    }
-  }
-
-  ownnod_complete( c, addedTets );
-}
-
-void
-DG::lhs()
-// *****************************************************************************
-// Compute left-hand side of discrete transport equations
-// *****************************************************************************
-{
-  g_dgpde[Disc()->MeshId()].lhs( myGhosts()->m_geoElem, m_lhs );
-
-  if (!m_initial) stage();
-}
-
-void DG::refine()
-// *****************************************************************************
-// Add the protective layer for ndof refinement
-// *****************************************************************************
-{
-  const auto pref = g_inputdeck.get< tag::pref, tag::pref >();
+  }
+
+  ownnod_complete( c );
+}
+
+void
+FV::lhs()
+// *****************************************************************************
+// Compute left-hand side of discrete transport equations
+// *****************************************************************************
+{
+  g_fvpde[Disc()->MeshId()].lhs( myGhosts()->m_geoElem, m_lhs );
+
+  if (!m_initial) stage();
+}
+
+void
+FV::reco()
+// *****************************************************************************
+// Compute reconstructions
+// *****************************************************************************
+{
+  const auto rdof = g_inputdeck.get< tag::rdof >();
+
+  // Combine own and communicated contributions of unreconstructed solution and
+  // degrees of freedom in cells (if p-adaptive)
+  for (const auto& b : myGhosts()->m_bid) {
+    Assert( m_uc[0][b.second].size() == m_u.nprop(), "ncomp size mismatch" );
+    Assert( m_pc[0][b.second].size() == m_p.nprop(), "ncomp size mismatch" );
+    for (std::size_t c=0; c<m_u.nprop(); ++c) {
+      m_u(b.first,c) = m_uc[0][b.second][c];
+    }
+    for (std::size_t c=0; c<m_p.nprop(); ++c) {
+      m_p(b.first,c) = m_pc[0][b.second][c];
+    }
+  }
+
+  if (rdof > 1) {
+    // Reconstruct second-order solution and primitive quantities
+    g_fvpde[Disc()->MeshId()].reconstruct( myGhosts()->m_geoElem, myGhosts()->m_fd,
+      myGhosts()->m_esup, myGhosts()->m_inpoel, myGhosts()->m_coord, m_u, m_p );
+  }
+
+  // start limiting
+  lim();
+}
+
+void
+FV::lim()
+// *****************************************************************************
+// Compute limiter function
+// *****************************************************************************
+{
+  const auto rdof = g_inputdeck.get< tag::rdof >();
+
+  if (rdof > 1) {
+    g_fvpde[Disc()->MeshId()].limit( myGhosts()->m_geoFace, myGhosts()->m_fd,
+      myGhosts()->m_esup,
+      myGhosts()->m_inpoel, myGhosts()->m_coord, m_srcFlag, m_u, m_p );
+  }
+
+  // Send limited solution to neighboring chares
+  if (myGhosts()->m_sendGhost.empty())
+    comlim_complete();
+  else
+    for(const auto& [cid, ghostdata] : myGhosts()->m_sendGhost) {
+      std::vector< std::size_t > tetid( ghostdata.size() );
+      std::vector< std::vector< tk::real > > u( ghostdata.size() ),
+                                             prim( ghostdata.size() );
+      std::size_t j = 0;
+      for(const auto& i : ghostdata) {
+        Assert( i < myGhosts()->m_fd.Esuel().size()/4,
+          "Sending limiter ghost data" );
+        tetid[j] = i;
+        u[j] = m_u[i];
+        prim[j] = m_p[i];
+        ++j;
+      }
+      thisProxy[ cid ].comlim( thisIndex, tetid, u, prim );
+    }
+
+  ownlim_complete();
+}
+
+void
+FV::comlim( int fromch,
+            const std::vector< std::size_t >& tetid,
+            const std::vector< std::vector< tk::real > >& u,
+            const std::vector< std::vector< tk::real > >& prim )
+// *****************************************************************************
+//  Receive chare-boundary limiter ghost data from neighboring chares
+//! \param[in] fromch Sender chare id
+//! \param[in] tetid Ghost tet ids we receive solution data for
+//! \param[in] u Limited high-order solution
+//! \param[in] prim Limited high-order primitive quantities
+//! \details This function receives contributions to the limited solution from
+//!   fellow chares.
+// *****************************************************************************
+{
+  Assert( u.size() == tetid.size(), "Size mismatch in FV::comlim()" );
+  Assert( prim.size() == tetid.size(), "Size mismatch in FV::comlim()" );
+
+  // Find local-to-ghost tet id map for sender chare
+  const auto& n = tk::cref_find( myGhosts()->m_ghost, fromch );
+
+  for (std::size_t i=0; i<tetid.size(); ++i) {
+    auto j = tk::cref_find( n, tetid[i] );
+    Assert( j >= myGhosts()->m_fd.Esuel().size()/4,
+      "Receiving solution non-ghost data" );
+    auto b = tk::cref_find( myGhosts()->m_bid, j );
+    Assert( b < m_uc[1].size(), "Indexing out of bounds" );
+    Assert( b < m_pc[1].size(), "Indexing out of bounds" );
+    m_uc[1][b] = u[i];
+    m_pc[1][b] = prim[i];
+  }
+
+  // if we have received all solution ghost contributions from neighboring
+  // chares (chares we communicate along chare-boundary faces with), and
+  // contributed our solution to these neighbors, proceed to limiting
+  if (++m_nlim == myGhosts()->m_sendGhost.size()) {
+    m_nlim = 0;
+    comlim_complete();
+  }
+}
+
+void
+FV::dt()
+// *****************************************************************************
+// Compute time step size
+// *****************************************************************************
+{
+  auto d = Disc();
+
+  // Combine own and communicated contributions of limited solution and degrees
+  // of freedom in cells (if p-adaptive)
+  for (const auto& b : myGhosts()->m_bid) {
+    Assert( m_uc[1][b.second].size() == m_u.nprop(), "ncomp size mismatch" );
+    Assert( m_pc[1][b.second].size() == m_p.nprop(), "ncomp size mismatch" );
+    for (std::size_t c=0; c<m_u.nprop(); ++c) {
+      m_u(b.first,c) = m_uc[1][b.second][c];
+    }
+    for (std::size_t c=0; c<m_p.nprop(); ++c) {
+      m_p(b.first,c) = m_pc[1][b.second][c];
+    }
+  }
+
+  auto mindt = std::numeric_limits< tk::real >::max();
 
-  // Combine own and communicated contributions of unreconstructed solution and
-  // degrees of freedom in cells (if p-adaptive)
-  for (const auto& b : myGhosts()->m_bid) {
-    Assert( m_uc[0][b.second].size() == m_u.nprop(), "ncomp size mismatch" );
-    Assert( m_pc[0][b.second].size() == m_p.nprop(), "ncomp size mismatch" );
-    for (std::size_t c=0; c<m_u.nprop(); ++c) {
-      m_u(b.first,c) = m_uc[0][b.second][c];
-    }
-    for (std::size_t c=0; c<m_p.nprop(); ++c) {
-      m_p(b.first,c) = m_pc[0][b.second][c];
-    }
-    if (pref && m_stage == 0) {
-      m_ndof[ b.first ] = m_ndofc[0][ b.second ];
-    }
-  }
-
-  if (pref && m_stage==0) refine_ndof();
-
-  if (myGhosts()->m_sendGhost.empty())
-    comrefine_complete();
-  else
-    for(const auto& [cid, ghostdata] : myGhosts()->m_sendGhost) {
-      std::vector< std::size_t > tetid( ghostdata.size() );
-      std::vector< std::vector< tk::real > > u( ghostdata.size() ),
-                                             prim( ghostdata.size() );
-      std::vector< std::size_t > ndof( ghostdata.size() );
-      std::size_t j = 0;
-      for(const auto& i : ghostdata) {
-        Assert( i < myGhosts()->m_fd.Esuel().size()/4, "Sending refined ndof  "
-          "data" );
-        tetid[j] = i;
-        if (pref && m_stage == 0) ndof[j] = m_ndof[i];
-        ++j;
-      }
-      thisProxy[ cid ].comrefine( thisIndex, tetid, ndof );
-    }
-
-  ownrefine_complete();
-}
-
-void
-DG::comrefine( int fromch,
-               const std::vector< std::size_t >& tetid,
-               const std::vector< std::size_t >& ndof )
-// *****************************************************************************
-//  Receive chare-boundary ghost data from neighboring chares
-//! \param[in] fromch Sender chare id
-//! \param[in] tetid Ghost tet ids we receive solution data for
-//! \param[in] ndof Number of degrees of freedom for chare-boundary elements
-//! \details This function receives contributions to the refined ndof data
-//!   from fellow chares.
-// *****************************************************************************
-{
-  const auto pref = g_inputdeck.get< tag::pref, tag::pref >();
-
-  if (pref && m_stage == 0)
-    Assert( ndof.size() == tetid.size(), "Size mismatch in DG::comrefine()" );
-
-  // Find local-to-ghost tet id map for sender chare
-  const auto& n = tk::cref_find( myGhosts()->m_ghost, fromch );
-
-  for (std::size_t i=0; i<tetid.size(); ++i) {
-    auto j = tk::cref_find( n, tetid[i] );
-    Assert( j >= myGhosts()->m_fd.Esuel().size()/4,
-      "Receiving solution non-ghost data" );
-    auto b = tk::cref_find( myGhosts()->m_bid, j );
-    if (pref && m_stage == 0) {
-      Assert( b < m_ndofc[1].size(), "Indexing out of bounds" );
-      m_ndofc[1][b] = ndof[i];
-    }
-  }
-
-  // if we have received all solution ghost contributions from neighboring
-  // chares (chares we communicate along chare-boundary faces with), and
-  // contributed our solution to these neighbors, proceed to limiting
-  if (++m_nrefine == myGhosts()->m_sendGhost.size()) {
-    m_nrefine = 0;
-    comrefine_complete();
-  }
-}
-
-void
-DG::smooth()
-// *****************************************************************************
-// Smooth the refined ndof distribution
-// *****************************************************************************
-{
-  const auto pref = g_inputdeck.get< tag::pref, tag::pref >();
-
-  for (const auto& b : myGhosts()->m_bid) {
-    if (pref && m_stage == 0)
-      m_ndof[ b.first ] = m_ndofc[1][ b.second ];
-  }
-
-  if (pref && m_stage==0) smooth_ndof();
-
-  if (myGhosts()->m_sendGhost.empty())
-    comsmooth_complete();
-  else
-    for(const auto& [cid, ghostdata] : myGhosts()->m_sendGhost) {
-      std::vector< std::size_t > tetid( ghostdata.size() );
-      std::vector< std::size_t > ndof;
-      std::size_t j = 0;
-      for(const auto& i : ghostdata) {
-        Assert( i < myGhosts()->m_fd.Esuel().size()/4, "Sending ndof data" );
-        tetid[j] = i;
-        if (pref && m_stage == 0) ndof.push_back( m_ndof[i] );
-        ++j;
-      }
-      thisProxy[ cid ].comsmooth( thisIndex, tetid, ndof );
-    }
-
-  ownsmooth_complete();
-}
+  if (m_stage == 0)
+  {
+    auto const_dt = g_inputdeck.get< tag::dt >();
+    auto eps = std::numeric_limits< tk::real >::epsilon();
+
+    // use constant dt if configured
+    if (std::abs(const_dt) > eps) {
+
+      mindt = const_dt;
+
+    } else {      // compute dt based on CFL
+
+      // find the minimum dt across all PDEs integrated
+      auto eqdt =
+        g_fvpde[d->MeshId()].dt( myGhosts()->m_fd, myGhosts()->m_geoFace,
+          myGhosts()->m_geoElem, m_u, m_p, myGhosts()->m_fd.Esuel().size()/4,
+          m_srcFlag, m_dte );
+      if (eqdt < mindt) mindt = eqdt;
+
+      // time-step suppression for unsteady problems
+      tk::real coeff(1.0);
+      if (!g_inputdeck.get< tag::steady_state >()) {
+        if (d->It() < 100) coeff = 0.01 * static_cast< tk::real >(d->It());
+      }
+
+      mindt *= coeff * g_inputdeck.get< tag::cfl >();
+    }
+  }
+  else
+  {
+    mindt = d->Dt();
+  }
+
+  // Contribute to minimum dt across all chares then advance to next step
+  contribute( sizeof(tk::real), &mindt, CkReduction::min_double,
+              CkCallback(CkReductionTarget(FV,solve), thisProxy) );
+}
+
+void
+FV::solve( tk::real newdt )
+// *****************************************************************************
+// Compute right-hand side of discrete transport equations
+//! \param[in] newdt Size of this new time step
+// *****************************************************************************
+{
+  // Enable SDAG wait for building the solution vector during the next stage
+  thisProxy[ thisIndex ].wait4sol();
+  thisProxy[ thisIndex ].wait4lim();
+  thisProxy[ thisIndex ].wait4nod();
+
+  auto d = Disc();
+  const auto rdof = g_inputdeck.get< tag::rdof >();
+  const auto neq = m_u.nprop()/rdof;
+
+  // Set new time step size
+  if (m_stage == 0) d->setdt( newdt );
+
+  // Update Un
+  if (m_stage == 0) m_un = m_u;
+
+  // physical time at time-stage for computing exact source terms for
+  // unsteady problems
+  tk::real physT(d->T());
+  // 2-stage RK
+  if (m_nrk == 2) {
+    if (m_stage == 1) {
+      physT += d->Dt();
+    }
+  }
+  // 3-stage RK
+  else {
+    if (m_stage == 1) {
+      physT += d->Dt();
+    }
+    else if (m_stage == 2) {
+      physT += 0.5*d->Dt();
+    }
+  }
+
+  // Compute rhs
+  g_fvpde[d->MeshId()].rhs( physT, myGhosts()->m_geoFace, myGhosts()->m_geoElem,
+    myGhosts()->m_fd, myGhosts()->m_inpoel, myGhosts()->m_coord,
+    d->ElemBlockId(), m_u, m_p, m_rhs, m_srcFlag );
+
+  // Explicit time-stepping using RK3 to discretize time-derivative
+  const auto steady = g_inputdeck.get< tag::steady_state >();
+  for (std::size_t e=0; e<myGhosts()->m_nunk; ++e)
+    for (std::size_t c=0; c<neq; ++c)
+    {
+      auto dte = d->Dt();
+      if (steady) dte = m_dte[e];
+      auto rmark = c*rdof;
+      m_u(e, rmark) =  m_rkcoef[0][m_stage] * m_un(e, rmark)
+        + m_rkcoef[1][m_stage] * ( m_u(e, rmark)
+          + dte * m_rhs(e, c)/m_lhs(e, c) );
+      // zero out reconstructed dofs of equations using reduced dofs
+      if (rdof > 1) {
+        for (std::size_t k=1; k<rdof; ++k)
+        {
+          rmark = c*rdof+k;
+          m_u(e, rmark) = 0.0;
+        }
+      }
+    }
+
+  // Update primitives based on the evolved solution
+  g_fvpde[d->MeshId()].updatePrimitives( m_u, m_p,
+    myGhosts()->m_fd.Esuel().size()/4 );
+  if (!g_inputdeck.get< tag::accuracy_test >()) {
+    g_fvpde[d->MeshId()].cleanTraceMaterial( physT, myGhosts()->m_geoElem, m_u,
+      m_p, myGhosts()->m_fd.Esuel().size()/4 );
+  }
+
+  if (m_stage < m_nrk-1) {
 
-void
-DG::comsmooth( int fromch,
-               const std::vector< std::size_t >& tetid,
-               const std::vector< std::size_t >& ndof )
-// *****************************************************************************
-//  Receive chare-boundary ghost data from neighboring chares
-//! \param[in] fromch Sender chare id
-//! \param[in] tetid Ghost tet ids we receive solution data for
-//! \param[in] ndof Number of degrees of freedom for chare-boundary elements
-//! \details This function receives contributions to the smoothed ndof data
-//!   from fellow chares.
-// *****************************************************************************
-{
-  const auto pref = g_inputdeck.get< tag::pref, tag::pref >();
-
-  if (pref && m_stage == 0)
-    Assert( ndof.size() == tetid.size(), "Size mismatch in DG::comsmooth()" );
-
-  const auto& n = tk::cref_find( myGhosts()->m_ghost, fromch );
-
-  for (std::size_t i=0; i<tetid.size(); ++i) {
-    auto j = tk::cref_find( n, tetid[i] );
-    Assert( j >= myGhosts()->m_fd.Esuel().size()/4, "Receiving ndof data" );
-    auto b = tk::cref_find( myGhosts()->m_bid, j );
-    if (pref && m_stage == 0) {
-      Assert( b < m_ndofc[2].size(), "Indexing out of bounds" );
-      m_ndofc[2][b] = ndof[i];
-    }
-  }
-
-  if (++m_nsmooth == myGhosts()->m_sendGhost.size()) {
-    m_nsmooth = 0;
-    comsmooth_complete();
-  }
-}
-
-void
-DG::reco()
-// *****************************************************************************
-// Compute reconstructions
-// *****************************************************************************
-{
-  const auto pref = g_inputdeck.get< tag::pref, tag::pref >();
-  const auto rdof = g_inputdeck.get< tag::rdof >();
-
-  // Combine own and communicated contributions of unreconstructed solution and
-  // degrees of freedom in cells (if p-adaptive)
-  for (const auto& b : myGhosts()->m_bid) {
-    if (pref && m_stage == 0) {
-      m_ndof[ b.first ] = m_ndofc[2][ b.second ];
-    }
-  }
-
-  auto d = Disc();
-  if (rdof > 1)
-    // Reconstruct second-order solution and primitive quantities
-    g_dgpde[d->MeshId()].reconstruct( d->T(), myGhosts()->m_geoFace,
-      myGhosts()->m_geoElem,
-      myGhosts()->m_fd, myGhosts()->m_esup, myGhosts()->m_inpoel,
-      myGhosts()->m_coord, m_u, m_p );
-
-  // Send reconstructed solution to neighboring chares
-  if (myGhosts()->m_sendGhost.empty())
-    comreco_complete();
-  else
-    for(const auto& [cid, ghostdata] : myGhosts()->m_sendGhost) {
-      std::vector< std::size_t > tetid( ghostdata.size() );
-      std::vector< std::vector< tk::real > > u( ghostdata.size() ),
-                                             prim( ghostdata.size() );
-      std::size_t j = 0;
-      for(const auto& i : ghostdata) {
-        Assert( i < myGhosts()->m_fd.Esuel().size()/4, "Sending reconstructed ghost "
-          "data" );
-        tetid[j] = i;
-        u[j] = m_u[i];
-        prim[j] = m_p[i];
-        ++j;
-      }
-      thisProxy[ cid ].comreco( thisIndex, tetid, u, prim );
-    }
-
-  ownreco_complete();
-}
-
-void
-DG::comreco( int fromch,
-             const std::vector< std::size_t >& tetid,
-             const std::vector< std::vector< tk::real > >& u,
-             const std::vector< std::vector< tk::real > >& prim )
-// *****************************************************************************
-//  Receive chare-boundary reconstructed ghost data from neighboring chares
-//! \param[in] fromch Sender chare id
-//! \param[in] tetid Ghost tet ids we receive solution data for
-//! \param[in] u Reconstructed high-order solution
-//! \param[in] prim Limited high-order primitive quantities
-//! \details This function receives contributions to the reconstructed solution
-//!   from fellow chares.
-// *****************************************************************************
-{
-  Assert( u.size() == tetid.size(), "Size mismatch in DG::comreco()" );
-  Assert( prim.size() == tetid.size(), "Size mismatch in DG::comreco()" );
+    // continue with next time step stage
+    stage();
+
+  } else {
+
+    // Increase number of iterations and physical time
+    d->next();
+
+    // Compute diagnostics, e.g., residuals
+    auto diag_computed = m_diag.compute( *d,
+      m_u.nunk()-myGhosts()->m_fd.Esuel().size()/4, myGhosts()->m_geoElem,
+      std::vector< std::size_t>{}, m_u, m_un );
+
+    // Continue to mesh refinement (if configured)
+    if (!diag_computed) refine( std::vector< tk::real >( m_u.nprop(), 1.0 ) );
+
+  }
+}
+
+void
+FV::refine( const std::vector< tk::real >& l2res )
+// *****************************************************************************
+// Optionally refine/derefine mesh
+//! \param[in] l2res L2-norms of the residual for each scalar component
+//!   computed across the whole problem
+// *****************************************************************************
+{
+  auto d = Disc();
+
+  // Assess convergence for steady state
+  const auto steady = g_inputdeck.get< tag::steady_state >();
+  const auto residual = g_inputdeck.get< tag::residual >();
+  const auto rc = g_inputdeck.get< tag::rescomp >() - 1;
+
+  bool converged(false);
+  if (steady) converged = l2res[rc] < residual;
+
+  // this is the last time step if max time of max number of time steps
+  // reached or the residual has reached its convergence criterion
+  if (d->finished() or converged) m_finished = 1;
+
+  auto dtref = g_inputdeck.get< tag::amr, tag::dtref >();
+  auto dtfreq = g_inputdeck.get< tag::amr, tag::dtfreq >();
+
+  // if t>0 refinement enabled and we hit the dtref frequency
+  if (dtref && !(d->It() % dtfreq)) {   // refine
+
+    d->startvol();
+    d->Ref()->dtref( myGhosts()->m_fd.Bface(), {},
+      tk::remap(myGhosts()->m_fd.Triinpoel(),d->Gid()) );
+    d->refined() = 1;
+
+  } else {      // do not refine
+
+    d->refined() = 0;
+    stage();
+
+  }
+}
+
+void
+FV::resizePostAMR(
+  const std::vector< std::size_t >& /*ginpoel*/,
+  const tk::UnsMesh::Chunk& chunk,
+  const tk::UnsMesh::Coords& coord,
+  const std::unordered_map< std::size_t, tk::UnsMesh::Edge >& /*addedNodes*/,
+  const std::unordered_map< std::size_t, std::size_t >& addedTets,
+  const std::set< std::size_t >& removedNodes,
+  const std::unordered_map< std::size_t, std::size_t >& amrNodeMap,
+  const tk::NodeCommMap& nodeCommMap,
+  const std::map< int, std::vector< std::size_t > >& bface,
+  const std::map< int, std::vector< std::size_t > >& /* bnode */,
+  const std::vector< std::size_t >& triinpoel,
+  const std::unordered_map< std::size_t, std::set< std::size_t > >& elemblockid )
+// *****************************************************************************
+//  Receive new mesh from Refiner
+//! \param[in] chunk New mesh chunk (connectivity and global<->local id maps)
+//! \param[in] coord New mesh node coordinates
+//! \param[in] addedTets Newly added mesh cells and their parents (local ids)
+//! \param[in] removedNodes Newly removed mesh node local ids
+//! \param[in] amrNodeMap Node id map after amr (local ids)
+//! \param[in] nodeCommMap New node communication map
+//! \param[in] bface Boundary-faces mapped to side set ids
+//! \param[in] triinpoel Boundary-face connectivity
+//! \param[in] elemblockid Local tet ids associated with mesh block ids
+// *****************************************************************************
+{
+  auto d = Disc();
+
+  // Set flag that indicates that we are during time stepping
+  m_initial = 0;
+  myGhosts()->m_initial = 0;
+
+  // Zero field output iteration count between two mesh refinement steps
+  d->Itf() = 0;
+
+  // Increase number of iterations with mesh refinement
+  ++d->Itr();
+
+  // Save old number of elements
+  [[maybe_unused]] auto old_nelem = myGhosts()->m_inpoel.size()/4;
 
-  // Find local-to-ghost tet id map for sender chare
-  const auto& n = tk::cref_find( myGhosts()->m_ghost, fromch );
-
-  for (std::size_t i=0; i<tetid.size(); ++i) {
-    auto j = tk::cref_find( n, tetid[i] );
-    Assert( j >= myGhosts()->m_fd.Esuel().size()/4,
-      "Receiving solution non-ghost data" );
-    auto b = tk::cref_find( myGhosts()->m_bid, j );
-    Assert( b < m_uc[1].size(), "Indexing out of bounds" );
-    Assert( b < m_pc[1].size(), "Indexing out of bounds" );
-    m_uc[1][b] = u[i];
-    m_pc[1][b] = prim[i];
-  }
-
-  // if we have received all solution ghost contributions from neighboring
-  // chares (chares we communicate along chare-boundary faces with), and
-  // contributed our solution to these neighbors, proceed to limiting
-  if (++m_nreco == myGhosts()->m_sendGhost.size()) {
-    m_nreco = 0;
-    comreco_complete();
-  }
-}
-
-void
-DG::nodalExtrema()
-// *****************************************************************************
-// Compute nodal extrema at chare-boundary nodes. Extrema at internal nodes
-// are calculated in limiter function.
-// *****************************************************************************
-{
-  auto d = Disc();
-  auto gid = d->Gid();
-  auto bid = d->Bid();
-  const auto rdof = g_inputdeck.get< tag::rdof >();
-  const auto ncomp = m_u.nprop() / rdof;
-  const auto nprim = m_p.nprop() / rdof;
-
-  // Combine own and communicated contributions of unlimited solution, and
-  // if a p-adaptive algorithm is used, degrees of freedom in cells
-  for (const auto& [boundary, localtet] : myGhosts()->m_bid) {
-    Assert( m_uc[1][localtet].size() == m_u.nprop(), "ncomp size mismatch" );
-    Assert( m_pc[1][localtet].size() == m_p.nprop(), "ncomp size mismatch" );
-    for (std::size_t c=0; c<m_u.nprop(); ++c) {
-      m_u(boundary,c) = m_uc[1][localtet][c];
-    }
-    for (std::size_t c=0; c<m_p.nprop(); ++c) {
-      m_p(boundary,c) = m_pc[1][localtet][c];
-    }
-  }
+  // Resize mesh data structures
+  d->resizePostAMR( chunk, coord, amrNodeMap, nodeCommMap, removedNodes,
+    elemblockid );
+
+  // Update state
+  myGhosts()->m_inpoel = d->Inpoel();
+  myGhosts()->m_coord = d->Coord();
+  auto nelem = myGhosts()->m_inpoel.size()/4;
+  m_p.resize( nelem );
+  m_u.resize( nelem );
+  m_srcFlag.resize( nelem );
+  m_un.resize( nelem );
+  m_lhs.resize( nelem );
+  m_rhs.resize( nelem );
+
+  myGhosts()->m_fd = FaceData( myGhosts()->m_inpoel, bface,
+    tk::remap(triinpoel,d->Lid()) );
+
+  myGhosts()->m_geoFace =
+    tk::Fields( tk::genGeoFaceTri( myGhosts()->m_fd.Nipfac(),
+    myGhosts()->m_fd.Inpofa(), coord ) );
+  myGhosts()->m_geoElem = tk::Fields( tk::genGeoElemTet( myGhosts()->m_inpoel,
+    coord ) );
+
+  myGhosts()->m_nfac = myGhosts()->m_fd.Inpofa().size()/3;
+  myGhosts()->m_nunk = nelem;
+  m_npoin = coord[0].size();
+  myGhosts()->m_bndFace.clear();
+  myGhosts()->m_exptGhost.clear();
+  myGhosts()->m_sendGhost.clear();
+  myGhosts()->m_ghost.clear();
+  myGhosts()->m_esup.clear();
+
+  // Update solution on new mesh, P0 (cell center value) only for now
+  m_un = m_u;
+  auto pn = m_p;<--- Variable 'pn' is assigned a value that is never used.
+  auto unprop = m_u.nprop();<--- Variable 'unprop' is assigned a value that is never used.
+  auto pnprop = m_p.nprop();<--- Variable 'pnprop' is assigned a value that is never used.
+  for (const auto& [child,parent] : addedTets) {
+    Assert( child < nelem, "Indexing out of new solution vector" );
+    Assert( parent < old_nelem, "Indexing out of old solution vector" );
+    for (std::size_t i=0; i<unprop; ++i) m_u(child,i) = m_un(parent,i);
+    for (std::size_t i=0; i<pnprop; ++i) m_p(child,i) = pn(parent,i);
+  }
+  m_un = m_u;
+
+  // Resize communication buffers
+  m_ghosts[thisIndex].resizeComm();
+}
 
-  // Initialize nodal extrema vector
-  auto large = std::numeric_limits< tk::real >::max();
-  for(std::size_t i = 0; i<bid.size(); i++)
-  {
-    for (std::size_t c=0; c<ncomp; ++c)
-    {
-      for(std::size_t idof=0; idof<m_ndof_NodalExtrm; idof++)
-      {
-        auto max_mark = 2*c*m_ndof_NodalExtrm + 2*idof;
-        auto min_mark = max_mark + 1;
-        m_uNodalExtrm[i][max_mark] = -large;
-        m_uNodalExtrm[i][min_mark] =  large;
-      }
-    }
-    for (std::size_t c=0; c<nprim; ++c)
-    {
-      for(std::size_t idof=0; idof<m_ndof_NodalExtrm; idof++)
-      {
-        auto max_mark = 2*c*m_ndof_NodalExtrm + 2*idof;
-        auto min_mark = max_mark + 1;
-        m_pNodalExtrm[i][max_mark] = -large;
-        m_pNodalExtrm[i][min_mark] =  large;
-      }
-    }
-  }
-
-  // Evaluate the max/min value for the chare-boundary nodes
-  if(rdof > 4) {
-      evalNodalExtrmRefEl(ncomp, nprim, m_ndof_NodalExtrm, d->bndel(),
-        myGhosts()->m_inpoel, gid, bid, m_u, m_p, m_uNodalExtrm, m_pNodalExtrm);
-  }
-
-  // Communicate extrema at nodes to other chares on chare-boundary
-  if (d->NodeCommMap().empty())        // in serial we are done
-    comnodalExtrema_complete();
-  else  // send nodal extrema to chare-boundary nodes to fellow chares
-  {
-    for (const auto& [c,n] : d->NodeCommMap()) {
-      std::vector< std::vector< tk::real > > g1( n.size() ), g2( n.size() );
-      std::size_t j = 0;
-      for (auto i : n)
-      {
-        auto p = tk::cref_find(d->Bid(),i);
-        g1[ j   ] = m_uNodalExtrm[ p ];
-        g2[ j++ ] = m_pNodalExtrm[ p ];
-      }
-      thisProxy[c].comnodalExtrema( std::vector<std::size_t>(begin(n),end(n)),
-        g1, g2 );
-    }
-  }
-  ownnodalExtrema_complete();
-}
-
-void
-DG::comnodalExtrema( const std::vector< std::size_t >& gid,
-                     const std::vector< std::vector< tk::real > >& G1,
-                     const std::vector< std::vector< tk::real > >& G2 )
-// *****************************************************************************
-//  Receive contributions to nodal extrema on chare-boundaries
-//! \param[in] gid Global mesh node IDs at which we receive grad contributions
-//! \param[in] G1 Partial contributions of extrema for conservative variables to
-//!   chare-boundary nodes
-//! \param[in] G2 Partial contributions of extrema for primitive variables to
-//!   chare-boundary nodes
-//! \details This function receives contributions to m_uNodalExtrm/m_pNodalExtrm
-//!   , which stores nodal extrems at mesh chare-boundary nodes. While
-//!   m_uNodalExtrm/m_pNodalExtrm stores own contributions, m_uNodalExtrmc
-//!   /m_pNodalExtrmc collects the neighbor chare contributions during
-//!   communication.
-// *****************************************************************************
-{
-  Assert( G1.size() == gid.size(), "Size mismatch" );
-  Assert( G2.size() == gid.size(), "Size mismatch" );
-
-  const auto rdof = g_inputdeck.get< tag::rdof >();
-  const auto ncomp = m_u.nprop() / rdof;
-  const auto nprim = m_p.nprop() / rdof;
-
-  for (std::size_t i=0; i<gid.size(); ++i)
-  {
-    auto& u = m_uNodalExtrmc[gid[i]];
-    auto& p = m_pNodalExtrmc[gid[i]];
-    for (std::size_t c=0; c<ncomp; ++c)
-    {
-      for(std::size_t idof=0; idof<m_ndof_NodalExtrm; idof++)
-      {
-        auto max_mark = 2*c*m_ndof_NodalExtrm + 2*idof;
-        auto min_mark = max_mark + 1;
-        u[max_mark] = std::max( G1[i][max_mark], u[max_mark] );
-        u[min_mark] = std::min( G1[i][min_mark], u[min_mark] );
-      }
-    }
-    for (std::size_t c=0; c<nprim; ++c)
-    {
-      for(std::size_t idof=0; idof<m_ndof_NodalExtrm; idof++)
-      {
-        auto max_mark = 2*c*m_ndof_NodalExtrm + 2*idof;
-        auto min_mark = max_mark + 1;
-        p[max_mark] = std::max( G2[i][max_mark], p[max_mark] );
-        p[min_mark] = std::min( G2[i][min_mark], p[min_mark] );
-      }
-    }
-  }
+bool
+FV::fieldOutput() const
+// *****************************************************************************
+// Decide wether to output field data
+//! \return True if field data is output in this step
+// *****************************************************************************
+{
+  auto d = Disc();
+
+  // Output field data
+  return d->fielditer() or d->fieldtime() or d->fieldrange() or m_finished;
+}
+
+bool
+FV::refinedOutput() const
+// *****************************************************************************
+// Decide if we write field output using a refined mesh
+//! \return True if field output will use a refined mesh
+// *****************************************************************************
+{
+  return g_inputdeck.get< tag::field_output, tag::refined >() &&
+         g_inputdeck.get< tag::scheme >() != ctr::SchemeType::FV;
+}
+
+void
+FV::writeFields( CkCallback c )
+// *****************************************************************************
+// Output mesh field data
+//! \param[in] c Function to continue with after the write
+// *****************************************************************************
+{
+  auto d = Disc();
+
+  const auto& inpoel = std::get< 0 >( d->Chunk() );
+  auto esup = tk::genEsup( inpoel, 4 );
+  auto nelem = inpoel.size() / 4;
+
+  // Combine own and communicated contributions and finish averaging of node
+  // field output in chare boundary nodes
+  const auto& lid = std::get< 2 >( d->Chunk() );
+  for (const auto& [g,f] : m_uNodefieldsc) {
+    Assert( m_uNodefields.nprop() == f.first.size(), "Size mismatch" );
+    auto p = tk::cref_find( lid, g );
+    for (std::size_t i=0; i<f.first.size(); ++i) {
+      m_uNodefields(p,i) += f.first[i];
+      m_uNodefields(p,i) /= static_cast< tk::real >(
+                              esup.second[p+1] - esup.second[p] + f.second );
+    }
+  }
+  tk::destroy( m_uNodefieldsc );
+  for (const auto& [g,f] : m_pNodefieldsc) {
+    Assert( m_pNodefields.nprop() == f.first.size(), "Size mismatch" );
+    auto p = tk::cref_find( lid, g );
+    for (std::size_t i=0; i<f.first.size(); ++i) {
+      m_pNodefields(p,i) += f.first[i];
+      m_pNodefields(p,i) /= static_cast< tk::real >(
+                              esup.second[p+1] - esup.second[p] + f.second );
+    }
+  }
+  tk::destroy( m_pNodefieldsc );
+
+  // Lambda to decide if a node (global id) is on a chare boundary of the field
+  // output mesh. p - global node id, return true if node is on the chare
+  // boundary.
+  auto chbnd = [ this ]( std::size_t p ) {
+    return
+      std::any_of( Disc()->NodeCommMap().cbegin(), Disc()->NodeCommMap().cend(),
+        [&](const auto& s) { return s.second.find(p) != s.second.cend(); } );
+  };
+
+  // Finish computing node field output averages in internal nodes
+  auto npoin = d->Coord()[0].size();
+  auto& gid = std::get< 1 >( d->Chunk() );
+  for (std::size_t p=0; p<npoin; ++p) {
+    if (!chbnd(gid[p])) {
+      auto n = static_cast< tk::real >( esup.second[p+1] - esup.second[p] );
+      for (std::size_t i=0; i<m_uNodefields.nprop(); ++i)
+        m_uNodefields(p,i) /= n;
+      for (std::size_t i=0; i<m_pNodefields.nprop(); ++i)
+        m_pNodefields(p,i) /= n;
+    }
+  }
+
+  // Collect field output from numerical solution requested by user
+  auto elemfields = numericFieldOutput( m_uElemfields, tk::Centering::ELEM,
+    g_fvpde[Disc()->MeshId()].OutVarFn(), m_pElemfields );
+  auto nodefields = numericFieldOutput( m_uNodefields, tk::Centering::NODE,
+    g_fvpde[Disc()->MeshId()].OutVarFn(), m_pNodefields );
+
+  // Collect field output from analytical solutions (if exist)
+  const auto& coord = d->Coord();
+  auto geoElem = tk::genGeoElemTet( inpoel, coord );
+  auto t = Disc()->T();
+  analyticFieldOutput( g_fvpde[d->MeshId()], tk::Centering::ELEM,
+    geoElem.extract_comp(1), geoElem.extract_comp(2), geoElem.extract_comp(3),
+    t, elemfields );
+  analyticFieldOutput( g_fvpde[d->MeshId()], tk::Centering::NODE, coord[0],
+    coord[1], coord[2], t, nodefields );
+
+  // Add sound speed vector
+  std::vector< tk::real > soundspd(nelem, 0.0);
+  g_fvpde[d->MeshId()].soundspeed(nelem, m_u, m_p, soundspd);
+  elemfields.push_back(soundspd);
 
-  if (++m_nnodalExtrema == Disc()->NodeCommMap().size())
-  {
-    m_nnodalExtrema = 0;
-    comnodalExtrema_complete();
-  }
-}
-
-void DG::resizeNodalExtremac()
-// *****************************************************************************
-//  Resize the buffer vector of nodal extrema
-// *****************************************************************************
-{
-  const auto rdof = g_inputdeck.get< tag::rdof >();
-  const auto ncomp = m_u.nprop() / rdof;
-  const auto nprim = m_p.nprop() / rdof;
+  // Add source flag array to element-centered field output
+  std::vector< tk::real > srcFlag( begin(m_srcFlag), end(m_srcFlag) );
+  // Here m_srcFlag has a size of m_u.nunk() which is the number of the
+  // elements within this partition (nelem) plus the ghost partition cells.
+  // For the purpose of output, we only need the solution data within this
+  // partition. Therefore, resizing it to nelem removes the extra partition
+  // boundary allocations in the srcFlag vector. Since the code assumes that
+  // the boundary elements are on the top, the resize operation keeps the lower
+  // portion.
+  srcFlag.resize( nelem );
+  elemfields.push_back( srcFlag );
+
+  // Query fields names requested by user
+  auto elemfieldnames = numericFieldNames( tk::Centering::ELEM );
+  auto nodefieldnames = numericFieldNames( tk::Centering::NODE );
 
-  auto large = std::numeric_limits< tk::real >::max();
-  for (const auto& [c,n] : Disc()->NodeCommMap())
-  {
-    for (auto i : n) {
-      auto& u = m_uNodalExtrmc[i];
-      auto& p = m_pNodalExtrmc[i];
-      u.resize( 2*m_ndof_NodalExtrm*ncomp, large );
-      p.resize( 2*m_ndof_NodalExtrm*nprim, large );
-
-      // Initialize the minimum nodal extrema
-      for(std::size_t idof=0; idof<m_ndof_NodalExtrm; idof++)
-      {
-        for(std::size_t k = 0; k < ncomp; k++)
-          u[2*k*m_ndof_NodalExtrm+2*idof] = -large;
-        for(std::size_t k = 0; k < nprim; k++)
-          p[2*k*m_ndof_NodalExtrm+2*idof] = -large;
-      }
-    }
-  }
-}
-
-void DG::evalNodalExtrmRefEl(
-  const std::size_t ncomp,
-  const std::size_t nprim,
-  const std::size_t ndof_NodalExtrm,
-  const std::vector< std::size_t >& bndel,
-  const std::vector< std::size_t >& inpoel,
-  const std::vector< std::size_t >& gid,
-  const std::unordered_map< std::size_t, std::size_t >& bid,
-  const tk::Fields& U,
-  const tk::Fields& P,
-  std::vector< std::vector<tk::real> >& uNodalExtrm,
-  std::vector< std::vector<tk::real> >& pNodalExtrm )
-// *****************************************************************************
-//  Compute the nodal extrema of ref el derivatives for chare-boundary nodes
-//! \param[in] ncomp Number of conservative variables
-//! \param[in] nprim Number of primitive variables
-//! \param[in] ndof_NodalExtrm Degree of freedom for nodal extrema
-//! \param[in] bndel List of elements contributing to chare-boundary nodes
-//! \param[in] inpoel Element-node connectivity for element e
-//! \param[in] gid Local->global node id map
-//! \param[in] bid Local chare-boundary node ids (value) associated to
-//!   global node ids (key)
-//! \param[in] U Vector of conservative variables
-//! \param[in] P Vector of primitive variables
-//! \param[in,out] uNodalExtrm Chare-boundary nodal extrema for conservative
-//!   variables
-//! \param[in,out] pNodalExtrm Chare-boundary nodal extrema for primitive
-//!   variables
-// *****************************************************************************
-{
-  const auto rdof = g_inputdeck.get< tag::rdof >();
-
-  for (auto e : bndel)
-  {
-    // access node IDs
-    const std::vector<std::size_t> N
-      { inpoel[e*4+0], inpoel[e*4+1], inpoel[e*4+2], inpoel[e*4+3] };
+  // Collect field output names for analytical solutions
+  analyticFieldNames( g_fvpde[d->MeshId()], tk::Centering::ELEM, elemfieldnames );
+  analyticFieldNames( g_fvpde[d->MeshId()], tk::Centering::NODE, nodefieldnames );
+
+  elemfieldnames.push_back( "sound speed" );
+  elemfieldnames.push_back( "src_flag" );
+
+  Assert( elemfieldnames.size() == elemfields.size(), "Size mismatch" );
+  Assert( nodefieldnames.size() == nodefields.size(), "Size mismatch" );
+
+  // Collect surface output names
+  auto surfnames = g_fvpde[d->MeshId()].surfNames();
+
+  // Collect surface field solution
+  const auto& fd = myGhosts()->m_fd;
+  auto elemsurfs = g_fvpde[d->MeshId()].surfOutput(fd, m_u, m_p);
+
+  // Output chare mesh and fields metadata to file
+  const auto& triinpoel = tk::remap( fd.Triinpoel(), d->Gid() );
+  d->write( inpoel, d->Coord(), fd.Bface(), {},
+            tk::remap( triinpoel, lid ), elemfieldnames, nodefieldnames,
+            surfnames, {}, elemfields, nodefields, elemsurfs, {}, c );
+}
+
+void
+FV::comnodeout( const std::vector< std::size_t >& gid,
+                const std::vector< std::size_t >& nesup,
+                const std::vector< std::vector< tk::real > >& Lu,
+                const std::vector< std::vector< tk::real > >& Lp )
+// *****************************************************************************
+//  Receive chare-boundary nodal solution (for field output) contributions from
+//  neighboring chares
+//! \param[in] gid Global mesh node IDs at which we receive contributions
+//! \param[in] nesup Number of elements surrounding points
+//! \param[in] Lu Partial contributions of solution nodal fields to
+//!   chare-boundary nodes
+//! \param[in] Lp Partial contributions of primitive quantity nodal fields to
+//!   chare-boundary nodes
+// *****************************************************************************
+{
+  Assert( gid.size() == nesup.size(), "Size mismatch" );
+  Assert(Lu.size() == m_uNodefields.nprop(), "Fields size mismatch");
+  Assert(Lp.size() == m_pNodefields.nprop(), "Fields size mismatch");
+  for (std::size_t f=0; f<Lu.size(); ++f)
+    Assert( gid.size() == Lu[f].size(), "Size mismatch" );
+  for (std::size_t f=0; f<Lp.size(); ++f)
+    Assert( gid.size() == Lp[f].size(), "Size mismatch" );
+
+  for (std::size_t i=0; i<gid.size(); ++i) {
+    auto& nfu = m_uNodefieldsc[ gid[i] ];
+    nfu.first.resize( Lu.size() );
+    for (std::size_t f=0; f<Lu.size(); ++f) nfu.first[f] += Lu[f][i];
+    nfu.second += nesup[i];
+    auto& nfp = m_pNodefieldsc[ gid[i] ];
+    nfp.first.resize( Lp.size() );
+    for (std::size_t f=0; f<Lp.size(); ++f) nfp.first[f] += Lp[f][i];
+    nfp.second += nesup[i];
+  }
 
-    // Loop over nodes of element e
-    for(std::size_t ip=0; ip<4; ++ip)
-    {
-      auto i = bid.find( gid[N[ip]] );
-      if (i != end(bid))      // If ip is the chare boundary point
-      {
-        // If DG(P2) is applied, find the nodal extrema of the gradients of
-        // conservative/primitive variables in the reference element
-
-        // Vector used to store the first order derivatives for both
-        // conservative and primitive variables
-        std::vector< std::array< tk::real, 3 > > gradc(ncomp, {0.0, 0.0, 0.0});
-        std::vector< std::array< tk::real, 3 > > gradp(ncomp, {0.0, 0.0, 0.0});
-
-        // Derivatives of the Dubiner basis
-        std::array< tk::real, 3 > center {{0.25, 0.25, 0.25}};
-        auto dBdxi = tk::eval_dBdxi(rdof, center);
-
-        // Evaluate the first order derivative
-        for(std::size_t icomp = 0; icomp < ncomp; icomp++)
-        {
-          auto mark = icomp * rdof;
-          for(std::size_t idir = 0; idir < 3; idir++)
-          {
-            gradc[icomp][idir] = 0;
-            for(std::size_t idof = 1; idof < rdof; idof++)
-              gradc[icomp][idir] += U(e, mark+idof) * dBdxi[idir][idof];
-          }
-        }
-        for(std::size_t icomp = 0; icomp < nprim; icomp++)
-        {
-          auto mark = icomp * rdof;
-          for(std::size_t idir = 0; idir < 3; idir++)
-          {
-            gradp[icomp][idir] = 0;
-            for(std::size_t idof = 1; idof < rdof; idof++)
-              gradp[icomp][idir] += P(e, mark+idof) * dBdxi[idir][idof];
-          }
-        }
-
-        // Store the extrema for the gradients
-        for (std::size_t c=0; c<ncomp; ++c)
-        {
-          for (std::size_t idof = 0; idof < ndof_NodalExtrm; idof++)
-          {
-            auto max_mark = 2*c*m_ndof_NodalExtrm + 2*idof;
-            auto min_mark = max_mark + 1;
-            auto& ex = uNodalExtrm[i->second];
-            ex[max_mark] = std::max(ex[max_mark], gradc[c][idof]);
-            ex[min_mark] = std::min(ex[min_mark], gradc[c][idof]);
-          }
-        }
-        for (std::size_t c=0; c<nprim; ++c)
-        {
-          for (std::size_t idof = 0; idof < ndof_NodalExtrm; idof++)
-          {
-            auto max_mark = 2*c*m_ndof_NodalExtrm + 2*idof;
-            auto min_mark = max_mark + 1;
-            auto& ex = pNodalExtrm[i->second];
-            ex[max_mark] = std::max(ex[max_mark], gradp[c][idof]);
-            ex[min_mark] = std::min(ex[min_mark], gradp[c][idof]);
-          }
-        }
-      }
-    }
-  }
-}
-
-void
-DG::lim()
-// *****************************************************************************
-// Compute limiter function
-// *****************************************************************************
-{
-  auto d = Disc();
-  const auto rdof = g_inputdeck.get< tag::rdof >();
-  const auto ncomp = m_u.nprop() / rdof;
-  const auto nprim = m_p.nprop() / rdof;
-
-  // Combine own and communicated contributions to nodal extrema
-  for (const auto& [gid,g] : m_uNodalExtrmc) {
-    auto bid = tk::cref_find( d->Bid(), gid );
-    for (ncomp_t c=0; c<ncomp; ++c)
-    {
-      for(std::size_t idof=0; idof<m_ndof_NodalExtrm; idof++)
-      {
-        auto max_mark = 2*c*m_ndof_NodalExtrm + 2*idof;
-        auto min_mark = max_mark + 1;
-        m_uNodalExtrm[bid][max_mark] =
-          std::max(g[max_mark], m_uNodalExtrm[bid][max_mark]);
-        m_uNodalExtrm[bid][min_mark] =
-          std::min(g[min_mark], m_uNodalExtrm[bid][min_mark]);
-      }
-    }
-  }
-  for (const auto& [gid,g] : m_pNodalExtrmc) {
-    auto bid = tk::cref_find( d->Bid(), gid );
-    for (ncomp_t c=0; c<nprim; ++c)
-    {
-      for(std::size_t idof=0; idof<m_ndof_NodalExtrm; idof++)
-      {
-        auto max_mark = 2*c*m_ndof_NodalExtrm + 2*idof;
-        auto min_mark = max_mark + 1;
-        m_pNodalExtrm[bid][max_mark] =
-          std::max(g[max_mark], m_pNodalExtrm[bid][max_mark]);
-        m_pNodalExtrm[bid][min_mark] =
-          std::min(g[min_mark], m_pNodalExtrm[bid][min_mark]);
-      }
-    }
+  // When we have heard from all chares we communicate with, this chare is done
+  if (++m_nnod == Disc()->NodeCommMap().size()) {
+    m_nnod = 0;
+    comnodeout_complete();
+  }
+}
+
+void
+FV::stage()
+// *****************************************************************************
+// Evaluate whether to continue with next time step stage
+// *****************************************************************************
+{
+  // Increment Runge-Kutta stage counter
+  ++m_stage;
+
+  // if not all Runge-Kutta stages complete, continue to next time stage,
+  // otherwise prepare for nodal field output
+  if (m_stage < m_nrk)
+    next();
+  else
+    startFieldOutput( CkCallback(CkIndex_FV::step(), thisProxy[thisIndex]) );
+}
+
+void
+FV::evalLB( int nrestart )
+// *****************************************************************************
+// Evaluate whether to do load balancing
+//! \param[in] nrestart Number of times restarted
+// *****************************************************************************
+{
+  auto d = Disc();
+
+  // Detect if just returned from a checkpoint and if so, zero timers and flag
+  if (d->restarted( nrestart )) m_finished = 0;
+
+  const auto lbfreq = g_inputdeck.get< tag::cmd, tag::lbfreq >();
+  const auto nonblocking = g_inputdeck.get< tag::cmd, tag::nonblocking >();
+
+  // Load balancing if user frequency is reached or after the second time-step
+  if ( (d->It()) % lbfreq == 0 || d->It() == 2 ) {
+
+    AtSync();
+    if (nonblocking) next();
+
+  } else {
+
+    next();
+
+  }
+}
+
+void
+FV::evalRestart()
+// *****************************************************************************
+// Evaluate whether to save checkpoint/restart
+// *****************************************************************************
+{
+  auto d = Disc();
+
+  const auto rsfreq = g_inputdeck.get< tag::cmd, tag::rsfreq >();
+  const auto benchmark = g_inputdeck.get< tag::cmd, tag::benchmark >();
+
+  if ( !benchmark && (d->It()) % rsfreq == 0 ) {
+
+    std::vector< std::size_t > meshdata{ /* finished = */ 0, d->MeshId() };
+    contribute( meshdata, CkReduction::nop,
+      CkCallback(CkReductionTarget(Transporter,checkpoint), d->Tr()) );
+
+  } else {
+
+    evalLB( /* nrestart = */ -1 );
+
+  }
+}
+
+void
+FV::step()
+// *****************************************************************************
+// Evaluate wether to continue with next time step
+// *****************************************************************************
+{
+  auto d = Disc();
+
+  // Output time history
+  if (d->histiter() or d->histtime() or d->histrange()) {
+    std::vector< std::vector< tk::real > > hist;
+    auto h = g_fvpde[d->MeshId()].histOutput( d->Hist(), myGhosts()->m_inpoel,
+      myGhosts()->m_coord, m_u, m_p );
+    hist.insert( end(hist), begin(h), end(h) );
+    d->history( std::move(hist) );
+  }
+
+  // Output one-liner status report to screen
+  d->status();
+  // Reset Runge-Kutta stage counter
+  m_stage = 0;
+
+  // If neither max iterations nor max time reached, continue, otherwise finish
+  if (not m_finished) {
+
+    evalRestart();
+ 
+  } else {
+
+    auto meshid = d->MeshId();
+    d->contribute( sizeof(std::size_t), &meshid, CkReduction::nop,
+                   CkCallback(CkReductionTarget(Transporter,finish), d->Tr()) );
+
   }
-
-  // clear gradients receive buffer
-  tk::destroy(m_uNodalExtrmc);
-  tk::destroy(m_pNodalExtrmc);
-
-  if (rdof > 1) {
-    g_dgpde[d->MeshId()].limit( d->T(), myGhosts()->m_geoFace, myGhosts()->m_geoElem,
-              myGhosts()->m_fd, myGhosts()->m_esup, myGhosts()->m_inpoel,
-              myGhosts()->m_coord, m_ndof, d->Gid(), d->Bid(), m_uNodalExtrm,
-              m_pNodalExtrm, m_mtInv, m_u, m_p, m_shockmarker );
-
-    if (g_inputdeck.get< tag::limsol_projection >())
-      g_dgpde[d->MeshId()].CPL(m_p, myGhosts()->m_geoElem,
-        myGhosts()->m_inpoel, myGhosts()->m_coord, m_u,
-        myGhosts()->m_fd.Esuel().size()/4);
-  }
-
-  // Send limited solution to neighboring chares
-  if (myGhosts()->m_sendGhost.empty())
-    comlim_complete();
-  else
-    for(const auto& [cid, ghostdata] : myGhosts()->m_sendGhost) {
-      std::vector< std::size_t > tetid( ghostdata.size() );
-      std::vector< std::vector< tk::real > > u( ghostdata.size() ),
-                                             prim( ghostdata.size() );
-      std::vector< std::size_t > ndof;<--- Unused variable: ndof
-      std::size_t j = 0;
-      for(const auto& i : ghostdata) {
-        Assert( i < myGhosts()->m_fd.Esuel().size()/4,
-          "Sending limiter ghost data" );
-        tetid[j] = i;
-        u[j] = m_u[i];
-        prim[j] = m_p[i];
-        ++j;
-      }
-      thisProxy[ cid ].comlim( thisIndex, tetid, u, prim );
-    }
-
-  ownlim_complete();
-}
-
-void
-DG::refine_ndof()
-// *****************************************************************************
-//  p-refine all elements that are adjacent to p-refined elements
-//! \details This function p-refines all the neighbors of an element that has
-//!   been p-refined as a result of an error indicator.
-// *****************************************************************************
-{
-  auto d = Disc();
-  const auto& inpoel = d->Inpoel();
-  const auto npoin = d->Coord()[0].size();
-  const auto nelem = myGhosts()->m_fd.Esuel().size()/4;
-  std::vector<std::size_t> node_ndof(npoin, 1);
-
-  // Mark the max ndof for each node and store in node_ndof
-  for(std::size_t ip=0; ip<npoin; ip++)
-  {
-    const auto& pesup = tk::cref_find(myGhosts()->m_esup, ip);
-    for(auto er : pesup)
-      node_ndof[ip] = std::max(m_ndof[er], node_ndof[ip]);
-  }
-
-  for(std::size_t e = 0; e < nelem; e++)
-  {
-    // Find if any node of this element has p1/p2 ndofs
-    std::size_t counter_p2(0);
-    std::size_t counter_p1(0);
-    for(std::size_t inode = 0; inode < 4; inode++)
-    {
-      auto node = inpoel[4*e+inode];
-      if(node_ndof[node] == 10)
-        counter_p2++;
-      else if (node_ndof[node] == 4)
-        counter_p1++;
-    }
-
-    // If there is at least one node with p1/p2 ndofs, all of the elements
-    // around this node are refined to p1/p2.
-    if(counter_p2 > 0 && m_ndof[e] < 10)
-    {
-      if(m_ndof[e] == 4)
-        m_ndof[e] = 10;
-      if(m_ndof[e] == 1)
-        m_ndof[e] = 4;
-    }
-    else if(counter_p1 > 0 && m_ndof[e] < 4)
-      m_ndof[e] = 4;
-  }
-}
-
-void DG::smooth_ndof()
-// *****************************************************************************
-//  Smooth the refined ndof distribution to avoid zigzag refinement
-// *****************************************************************************
-{
-  auto d = Disc();
-  const auto& inpoel = d->Inpoel();
-  const auto npoin = d->Coord()[0].size();
-  const auto nelem = myGhosts()->m_fd.Esuel().size()/4;
-  std::vector<std::size_t> node_ndof(npoin, 1);
-
-  // Mark the max ndof for each node and store in node_ndof
-  for(std::size_t ip=0; ip<npoin; ip++)
-  {
-    const auto& pesup = tk::cref_find(myGhosts()->m_esup, ip);
-    for(auto er : pesup)
-      node_ndof[ip] = std::max(m_ndof[er], node_ndof[ip]);
-  }
-
-  for(std::size_t e = 0; e < nelem; e++)
-  {
-    // Find if any node of this element has p1/p2 ndofs
-    std::size_t counter_p2(0);
-    std::size_t counter_p1(0);
-    for(std::size_t inode = 0; inode < 4; inode++)
-    {
-      auto node = inpoel[4*e+inode];
-      if(node_ndof[node] == 10)
-        counter_p2++;
-      else if (node_ndof[node] == 4)
-        counter_p1++;
-    }
-
-    // If all the nodes in the element are p1/p2, this element is refined to
-    // p1/p2.
-    if(counter_p2 == 4 && m_ndof[e] == 4)
-      m_ndof[e] = 10;
-    else if(counter_p1 == 4 && m_ndof[e] == 1)
-      m_ndof[e] = 4;
-  }
-}
-
-void
-DG::comlim( int fromch,
-            const std::vector< std::size_t >& tetid,
-            const std::vector< std::vector< tk::real > >& u,
-            const std::vector< std::vector< tk::real > >& prim )
-// *****************************************************************************
-//  Receive chare-boundary limiter ghost data from neighboring chares
-//! \param[in] fromch Sender chare id
-//! \param[in] tetid Ghost tet ids we receive solution data for
-//! \param[in] u Limited high-order solution
-//! \param[in] prim Limited high-order primitive quantities
-//! \details This function receives contributions to the limited solution from
-//!   fellow chares.
-// *****************************************************************************
-{
-  Assert( u.size() == tetid.size(), "Size mismatch in DG::comlim()" );
-  Assert( prim.size() == tetid.size(), "Size mismatch in DG::comlim()" );
-
-  // Find local-to-ghost tet id map for sender chare
-  const auto& n = tk::cref_find( myGhosts()->m_ghost, fromch );
-
-  for (std::size_t i=0; i<tetid.size(); ++i) {
-    auto j = tk::cref_find( n, tetid[i] );
-    Assert( j >= myGhosts()->m_fd.Esuel().size()/4,
-      "Receiving solution non-ghost data" );
-    auto b = tk::cref_find( myGhosts()->m_bid, j );
-    Assert( b < m_uc[2].size(), "Indexing out of bounds" );
-    Assert( b < m_pc[2].size(), "Indexing out of bounds" );
-    m_uc[2][b] = u[i];
-    m_pc[2][b] = prim[i];
-  }
-
-  // if we have received all solution ghost contributions from neighboring
-  // chares (chares we communicate along chare-boundary faces with), and
-  // contributed our solution to these neighbors, proceed to limiting
-  if (++m_nlim == myGhosts()->m_sendGhost.size()) {
-    m_nlim = 0;
-    comlim_complete();
-  }
-}
-
-void
-DG::dt()
-// *****************************************************************************
-// Compute time step size
-// *****************************************************************************
-{
-  auto d = Disc();
-
-  // Combine own and communicated contributions of limited solution and degrees
-  // of freedom in cells (if p-adaptive)
-  for (const auto& b : myGhosts()->m_bid) {
-    Assert( m_uc[2][b.second].size() == m_u.nprop(), "ncomp size mismatch" );
-    Assert( m_pc[2][b.second].size() == m_p.nprop(), "ncomp size mismatch" );
-    for (std::size_t c=0; c<m_u.nprop(); ++c) {
-      m_u(b.first,c) = m_uc[2][b.second][c];
-    }
-    for (std::size_t c=0; c<m_p.nprop(); ++c) {
-      m_p(b.first,c) = m_pc[2][b.second][c];
-    }
-  }
-
-  auto mindt = std::numeric_limits< tk::real >::max();
-
-  if (m_stage == 0)
-  {
-    auto const_dt = g_inputdeck.get< tag::dt >();
-    auto eps = std::numeric_limits< tk::real >::epsilon();
-
-    // use constant dt if configured
-    if (std::abs(const_dt) > eps) {
-
-      mindt = const_dt;
-
-    } else {      // compute dt based on CFL
-
-      // find the minimum dt across all PDEs integrated
-      auto eqdt =
-        g_dgpde[d->MeshId()].dt( myGhosts()->m_coord, myGhosts()->m_inpoel,
-          myGhosts()->m_fd,
-          myGhosts()->m_geoFace, myGhosts()->m_geoElem, m_ndof, m_u, m_p,
-          myGhosts()->m_fd.Esuel().size()/4 );
-      if (eqdt < mindt) mindt = eqdt;
-
-      mindt *= g_inputdeck.get< tag::cfl >();
-    }
-  }
-  else
-  {
-    mindt = d->Dt();
-  }
-
-  // Resize the buffer vector of nodal extrema
-  resizeNodalExtremac();
-
-  // Contribute to minimum dt across all chares then advance to next step
-  contribute( sizeof(tk::real), &mindt, CkReduction::min_double,
-              CkCallback(CkReductionTarget(DG,solve), thisProxy) );
-}
-
-void
-DG::solve( tk::real newdt )
-// *****************************************************************************
-// Compute right-hand side of discrete transport equations
-//! \param[in] newdt Size of this new time step
-// *****************************************************************************
-{
-  // Enable SDAG wait for building the solution vector during the next stage
-  thisProxy[ thisIndex ].wait4sol();
-  thisProxy[ thisIndex ].wait4refine();
-  thisProxy[ thisIndex ].wait4smooth();
-  thisProxy[ thisIndex ].wait4reco();
-  thisProxy[ thisIndex ].wait4nodalExtrema();
-  thisProxy[ thisIndex ].wait4lim();
-  thisProxy[ thisIndex ].wait4nod();
-
-  auto d = Disc();
-  const auto rdof = g_inputdeck.get< tag::rdof >();
-  const auto ndof = g_inputdeck.get< tag::ndof >();
-  const auto neq = m_u.nprop()/rdof;
-
-  // Set new time step size
-  if (m_stage == 0) d->setdt( newdt );
-
-  const auto pref = g_inputdeck.get< tag::pref, tag::pref >();
-  if (pref && m_stage == 0)
-  {
-    // When the element are coarsened, high order terms should be zero
-    for(std::size_t e = 0; e < myGhosts()->m_nunk; e++)
-    {
-      const auto ncomp= m_u.nprop()/rdof;
-      if(m_ndof[e] == 1)
-      {
-        for (std::size_t c=0; c<ncomp; ++c)
-        {
-          auto mark = c*rdof;
-          m_u(e, mark+1) = 0.0;
-          m_u(e, mark+2) = 0.0;
-          m_u(e, mark+3) = 0.0;
-        }
-      } else if(m_ndof[e] == 4)
-      {
-        for (std::size_t c=0; c<ncomp; ++c)
-        {
-          auto mark = c*ndof;
-          m_u(e, mark+4) = 0.0;
-          m_u(e, mark+5) = 0.0;
-          m_u(e, mark+6) = 0.0;
-          m_u(e, mark+7) = 0.0;
-          m_u(e, mark+8) = 0.0;
-          m_u(e, mark+9) = 0.0;
-        }
-      }
-    }
-  }
-
-  // Update Un
-  if (m_stage == 0) m_un = m_u;
-
-  // Explicit or IMEX
-  const auto imex_runge_kutta = g_inputdeck.get< tag::imex_runge_kutta >();
-
-  // physical time at time-stage for computing exact source terms
-  tk::real physT(d->T());
-  if (m_stage == 1) {
-    physT += d->Dt();
-  }
-  else if (m_stage == 2) {
-    physT += 0.5*d->Dt();
-  }
-
-  if (imex_runge_kutta) {
-    if (m_stage == 0)
-    {
-      // Save previous rhs
-      m_rhsprev = m_rhs;
-      // Initialize m_stiffrhs to zero
-      m_stiffrhs.fill(0.0);
-      m_stiffrhsprev.fill(0.0);
-    }
-  }
-
-  g_dgpde[d->MeshId()].rhs( physT, myGhosts()->m_geoFace, myGhosts()->m_geoElem,
-    myGhosts()->m_fd, myGhosts()->m_inpoel, m_boxelems, myGhosts()->m_coord,
-    m_u, m_p, m_ndof, m_rho0mat, d->Dt(), m_rhs );
-
-  if (!imex_runge_kutta) {
-    // Explicit time-stepping using RK3 to discretize time-derivative
-    for(std::size_t e=0; e<myGhosts()->m_nunk; ++e)
-      for(std::size_t c=0; c<neq; ++c)
-      {
-        for (std::size_t k=0; k<m_numEqDof[c]; ++k)
-        {
-          auto rmark = c*rdof+k;
-          auto mark = c*ndof+k;
-          m_u(e, rmark) =  rkcoef[0][m_stage] * m_un(e, rmark)
-            + rkcoef[1][m_stage] * ( m_u(e, rmark)
-              + d->Dt() * m_rhs(e, mark)/m_lhs(e, mark) );
-          if(fabs(m_u(e, rmark)) < 1e-16)
-            m_u(e, rmark) = 0;
-        }
-      }
-  }
-  else {
-    // Implicit-Explicit time-stepping using RK3 to discretize time-derivative
-    DG::imex_integrate();
-  }
-
-  for(std::size_t e=0; e<myGhosts()->m_nunk; ++e)
-    for(std::size_t c=0; c<neq; ++c)
-    {
-      // zero out unused/reconstructed dofs of equations using reduced dofs
-      // (see DGMultiMat::numEquationDofs())
-      if (m_numEqDof[c] < rdof) {
-        for (std::size_t k=m_numEqDof[c]; k<rdof; ++k)
-        {
-          auto rmark = c*rdof+k;
-          m_u(e, rmark) = 0.0;
-        }
-      }
-    }
-
-  // Update primitives based on the evolved solution
-  g_dgpde[d->MeshId()].updateInterfaceCells( m_u,
-    myGhosts()->m_fd.Esuel().size()/4, m_ndof );
-  g_dgpde[d->MeshId()].updatePrimitives( m_u, m_lhs, myGhosts()->m_geoElem, m_p,
-    myGhosts()->m_fd.Esuel().size()/4 );
-  if (!g_inputdeck.get< tag::accuracy_test >()) {
-    g_dgpde[d->MeshId()].cleanTraceMaterial( physT, myGhosts()->m_geoElem, m_u,
-      m_p, myGhosts()->m_fd.Esuel().size()/4 );
-  }
-
-  if (m_stage < 2) {
-
-    // continue with next time step stage
-    stage();
-
-  } else {
-
-    // Increase number of iterations and physical time
-    d->next();
-
-    // Compute diagnostics, e.g., residuals
-    auto diag_computed = m_diag.compute( *d,
-      m_u.nunk()-myGhosts()->m_fd.Esuel().size()/4, myGhosts()->m_geoElem,
-      m_ndof, m_u, m_un );
-
-    // Continue to mesh refinement (if configured)
-    if (!diag_computed) refine( std::vector< tk::real >( m_u.nprop(), 0.0 ) );
-
-  }
-}
-
-void
-DG::refine( [[maybe_unused]] const std::vector< tk::real >& l2res )
-// *****************************************************************************
-// Optionally refine/derefine mesh
-//! \param[in] l2res L2-norms of the residual for each scalar component
-//!   computed across the whole problem
-// *****************************************************************************
-{
-  auto d = Disc();
-
-  auto dtref = g_inputdeck.get< tag::amr, tag::dtref >();
-  auto dtfreq = g_inputdeck.get< tag::amr, tag::dtfreq >();
-
-  // if t>0 refinement enabled and we hit the dtref frequency
-  if (dtref && !(d->It() % dtfreq)) {   // refine
-
-    d->startvol();
-    d->Ref()->dtref( myGhosts()->m_fd.Bface(), {},
-      tk::remap(myGhosts()->m_fd.Triinpoel(),d->Gid()) );
-    d->refined() = 1;
-
-  } else {      // do not refine
-
-    d->refined() = 0;
-    stage();
-
-  }
-}
-
-void
-DG::resizePostAMR(
-  const std::vector< std::size_t >& /*ginpoel*/,
-  const tk::UnsMesh::Chunk& chunk,
-  const tk::UnsMesh::Coords& coord,
-  const std::unordered_map< std::size_t, tk::UnsMesh::Edge >& /*addedNodes*/,
-  const std::unordered_map< std::size_t, std::size_t >& addedTets,
-  const std::set< std::size_t >& removedNodes,
-  const std::unordered_map< std::size_t, std::size_t >& amrNodeMap,
-  const tk::NodeCommMap& nodeCommMap,
-  const std::map< int, std::vector< std::size_t > >& bface,
-  const std::map< int, std::vector< std::size_t > >& /* bnode */,
-  const std::vector< std::size_t >& triinpoel,
-  const std::unordered_map< std::size_t, std::set< std::size_t > >& elemblockid )
-// *****************************************************************************
-//  Receive new mesh from Refiner
-//! \param[in] chunk New mesh chunk (connectivity and global<->local id maps)
-//! \param[in] coord New mesh node coordinates
-//! \param[in] addedTets Newly added mesh cells and their parents (local ids)
-//! \param[in] removedNodes Newly removed mesh node local ids
-//! \param[in] amrNodeMap Node id map after amr (local ids)
-//! \param[in] nodeCommMap New node communication map
-//! \param[in] bface Boundary-faces mapped to side set ids
-//! \param[in] triinpoel Boundary-face connectivity
-//! \param[in] elemblockid Local tet ids associated with mesh block ids
-// *****************************************************************************
-{
-  auto d = Disc();
-
-  // Set flag that indicates that we are during time stepping
-  m_initial = 0;
-  myGhosts()->m_initial = 0;
-
-  // Zero field output iteration count between two mesh refinement steps
-  d->Itf() = 0;
-
-  // Increase number of iterations with mesh refinement
-  ++d->Itr();
-
-  // Save old number of elements
-  [[maybe_unused]] auto old_nelem = myGhosts()->m_inpoel.size()/4;
-
-  // Resize mesh data structures
-  d->resizePostAMR( chunk, coord, amrNodeMap, nodeCommMap, removedNodes,
-    elemblockid );
-
-  // Update state
-  myGhosts()->m_inpoel = d->Inpoel();
-  myGhosts()->m_coord = d->Coord();
-  auto nelem = myGhosts()->m_inpoel.size()/4;
-  m_p.resize( nelem );
-  m_u.resize( nelem );
-  m_un.resize( nelem );
-  m_lhs.resize( nelem );
-  m_rhs.resize( nelem );
-  m_rhsprev.resize( nelem );
-  m_stiffrhs.resize( nelem );
-  m_stiffrhsprev.resize( nelem );
-  m_uNodalExtrm.resize( Disc()->Bid().size(), std::vector<tk::real>( 2*
-    m_ndof_NodalExtrm*g_inputdeck.get< tag::ncomp >() ) );
-  m_pNodalExtrm.resize( Disc()->Bid().size(), std::vector<tk::real>( 2*
-    m_ndof_NodalExtrm*m_p.nprop()/g_inputdeck.get< tag::rdof >()));
-
-  // Resize the buffer vector of nodal extrema
-  resizeNodalExtremac();
-
-  myGhosts()->m_fd = FaceData( myGhosts()->m_inpoel, bface,
-    tk::remap(triinpoel,d->Lid()) );
-
-  myGhosts()->m_geoFace =
-    tk::Fields( tk::genGeoFaceTri( myGhosts()->m_fd.Nipfac(),
-    myGhosts()->m_fd.Inpofa(), coord ) );
-  myGhosts()->m_geoElem = tk::Fields( tk::genGeoElemTet( myGhosts()->m_inpoel,
-    coord ) );
-
-  myGhosts()->m_nfac = myGhosts()->m_fd.Inpofa().size()/3;
-  myGhosts()->m_nunk = nelem;
-  m_npoin = coord[0].size();
-  myGhosts()->m_bndFace.clear();
-  myGhosts()->m_exptGhost.clear();
-  myGhosts()->m_sendGhost.clear();
-  myGhosts()->m_ghost.clear();
-  myGhosts()->m_esup.clear();
-
-  // Update solution on new mesh, P0 (cell center value) only for now
-  m_un = m_u;
-  auto pn = m_p;<--- Variable 'pn' is assigned a value that is never used.
-  auto unprop = m_u.nprop();<--- Variable 'unprop' is assigned a value that is never used.
-  auto pnprop = m_p.nprop();<--- Variable 'pnprop' is assigned a value that is never used.
-  for (const auto& [child,parent] : addedTets) {
-    Assert( child < nelem, "Indexing out of new solution vector" );
-    Assert( parent < old_nelem, "Indexing out of old solution vector" );
-    for (std::size_t i=0; i<unprop; ++i) m_u(child,i) = m_un(parent,i);
-    for (std::size_t i=0; i<pnprop; ++i) m_p(child,i) = pn(parent,i);
-  }
-  m_un = m_u;
-
-  // Resize communication buffers
-  m_ghosts[thisIndex].resizeComm();
-}
-
-bool
-DG::fieldOutput() const
-// *****************************************************************************
-// Decide wether to output field data
-//! \return True if field data is output in this step
-// *****************************************************************************
-{
-  auto d = Disc();
-
-  // Output field data
-  return d->fielditer() or d->fieldtime() or d->fieldrange() or d->finished();
-}
-
-bool
-DG::refinedOutput() const
-// *****************************************************************************
-// Decide if we write field output using a refined mesh
-//! \return True if field output will use a refined mesh
-// *****************************************************************************
-{
-  return g_inputdeck.get< tag::field_output, tag::refined >() &&
-         g_inputdeck.get< tag::scheme >() != ctr::SchemeType::DG;
-}
-
-void
-DG::writeFields(
-  CkCallback c,
-  const std::unordered_map< std::size_t, std::size_t >& addedTets )
-// *****************************************************************************
-// Output mesh field data
-//! \param[in] c Function to continue with after the write
-//! \param[in] addedTets Newly added mesh cells and their parents (local ids)
-// *****************************************************************************
-{
-  auto d = Disc();
-
-  const auto& inpoel = std::get< 0 >( m_outmesh.chunk );
-  auto esup = tk::genEsup( inpoel, 4 );
-  auto nelem = inpoel.size() / 4;
-
-  // Combine own and communicated contributions and finish averaging of node
-  // field output in chare boundary nodes
-  const auto& lid = std::get< 2 >( m_outmesh.chunk );
-  for (const auto& [g,f] : m_uNodefieldsc) {
-    Assert( m_uNodefields.nprop() == f.first.size(), "Size mismatch" );
-    auto p = tk::cref_find( lid, g );
-    for (std::size_t i=0; i<f.first.size(); ++i) {
-      m_uNodefields(p,i) += f.first[i];
-      m_uNodefields(p,i) /= static_cast< tk::real >(
-                              esup.second[p+1] - esup.second[p] + f.second );
-    }
-  }
-  tk::destroy( m_uNodefieldsc );
-  for (const auto& [g,f] : m_pNodefieldsc) {
-    Assert( m_pNodefields.nprop() == f.first.size(), "Size mismatch" );
-    auto p = tk::cref_find( lid, g );
-    for (std::size_t i=0; i<f.first.size(); ++i) {
-      m_pNodefields(p,i) += f.first[i];
-      m_pNodefields(p,i) /= static_cast< tk::real >(
-                              esup.second[p+1] - esup.second[p] + f.second );
-    }
-  }
-  tk::destroy( m_pNodefieldsc );
-
-  // Lambda to decide if a node (global id) is on a chare boundary of the field
-  // output mesh. p - global node id, return true if node is on the chare
-  // boundary.
-  auto chbnd = [ this ]( std::size_t p ) {
-    return
-      std::any_of( m_outmesh.nodeCommMap.cbegin(), m_outmesh.nodeCommMap.cend(),
-        [&](const auto& s) { return s.second.find(p) != s.second.cend(); } );
-  };
-
-  // Finish computing node field output averages in internal nodes
-  auto npoin = m_outmesh.coord[0].size();
-  auto& gid = std::get< 1 >( m_outmesh.chunk );
-  for (std::size_t p=0; p<npoin; ++p) {
-    if (!chbnd(gid[p])) {
-      auto n = static_cast< tk::real >( esup.second[p+1] - esup.second[p] );
-      for (std::size_t i=0; i<m_uNodefields.nprop(); ++i)
-        m_uNodefields(p,i) /= n;
-      for (std::size_t i=0; i<m_pNodefields.nprop(); ++i)
-        m_pNodefields(p,i) /= n;
-    }
-  }
-
-  // Collect field output from numerical solution requested by user
-  auto elemfields = numericFieldOutput( m_uElemfields, tk::Centering::ELEM,
-    g_dgpde[Disc()->MeshId()].OutVarFn(), m_pElemfields );
-  auto nodefields = numericFieldOutput( m_uNodefields, tk::Centering::NODE,
-    g_dgpde[Disc()->MeshId()].OutVarFn(), m_pNodefields );
-
-  // Collect field output from analytical solutions (if exist)
-  const auto& coord = m_outmesh.coord;
-  auto geoElem = tk::genGeoElemTet( inpoel, coord );
-  auto t = Disc()->T();
-  analyticFieldOutput( g_dgpde[d->MeshId()], tk::Centering::ELEM,
-    geoElem.extract_comp(1), geoElem.extract_comp(2), geoElem.extract_comp(3),
-    t, elemfields );
-  analyticFieldOutput( g_dgpde[d->MeshId()], tk::Centering::NODE, coord[0],
-    coord[1], coord[2], t, nodefields );
-
-  // Add adaptive indicator array to element-centered field output
-  if (g_inputdeck.get< tag::pref, tag::pref >()) {
-    std::vector< tk::real > ndof( begin(m_ndof), end(m_ndof) );
-    ndof.resize( nelem );
-    for (const auto& [child,parent] : addedTets)
-      ndof[child] = static_cast< tk::real >( m_ndof[parent] );
-    elemfields.push_back( ndof );
-  }
-
-  // Add shock detection marker array to element-centered field output
-  std::vector< tk::real > shockmarker( begin(m_shockmarker), end(m_shockmarker) );
-  // Here m_shockmarker has a size of m_u.nunk() which is the number of the
-  // elements within this partition (nelem) plus the ghost partition cells. In
-  // terms of output purpose, we only need the solution data within this
-  // partition. Therefore, resizing it to nelem removes the extra partition
-  // boundary allocations in the shockmarker vector. Since the code assumes that
-  // the boundary elements are on the top, the resize operation keeps the lower
-  // portion.
-  shockmarker.resize( nelem );
-  for (const auto& [child,parent] : addedTets)
-    shockmarker[child] = static_cast< tk::real >(m_shockmarker[parent]);
-  elemfields.push_back( shockmarker );
-
-  // Add rho0*det(g)/rho to make sure it is staying close to 1,
-  // averaged for all materials
-  std::vector< tk::real > densityConstr(nelem);
-  g_dgpde[d->MeshId()].computeDensityConstr(nelem, m_u, m_rho0mat,
-                                            densityConstr);
-  for (const auto& [child,parent] : addedTets)
-    densityConstr[child] = 0.0;
-  if (densityConstr.size() > 0) elemfields.push_back( densityConstr );
-
-  // Query fields names requested by user
-  auto elemfieldnames = numericFieldNames( tk::Centering::ELEM );
-  auto nodefieldnames = numericFieldNames( tk::Centering::NODE );
-
-  // Collect field output names for analytical solutions
-  analyticFieldNames( g_dgpde[d->MeshId()], tk::Centering::ELEM, elemfieldnames );
-  analyticFieldNames( g_dgpde[d->MeshId()], tk::Centering::NODE, nodefieldnames );
-
-  if (g_inputdeck.get< tag::pref, tag::pref >())
-    elemfieldnames.push_back( "NDOF" );
-
-  elemfieldnames.push_back( "shock_marker" );
-
-  if (densityConstr.size() > 0)
-    elemfieldnames.push_back( "density_constraint" );
-
-  Assert( elemfieldnames.size() == elemfields.size(), "Size mismatch" );
-  Assert( nodefieldnames.size() == nodefields.size(), "Size mismatch" );
-
-  // Output chare mesh and fields metadata to file
-  const auto& triinpoel = m_outmesh.triinpoel;
-  d->write( inpoel, m_outmesh.coord, m_outmesh.bface, {},
-            tk::remap( triinpoel, lid ), elemfieldnames, nodefieldnames,
-            {}, {}, elemfields, nodefields, {}, {}, c );
-}
-
-void
-DG::comnodeout( const std::vector< std::size_t >& gid,
-                const std::vector< std::size_t >& nesup,
-                const std::vector< std::vector< tk::real > >& Lu,
-                const std::vector< std::vector< tk::real > >& Lp )
-// *****************************************************************************
-//  Receive chare-boundary nodal solution (for field output) contributions from
-//  neighboring chares
-//! \param[in] gid Global mesh node IDs at which we receive contributions
-//! \param[in] nesup Number of elements surrounding points
-//! \param[in] Lu Partial contributions of solution nodal fields to
-//!   chare-boundary nodes
-//! \param[in] Lp Partial contributions of primitive quantity nodal fields to
-//!   chare-boundary nodes
-// *****************************************************************************
-{
-  Assert( gid.size() == nesup.size(), "Size mismatch" );
-  Assert(Lu.size() == m_uNodefields.nprop(), "Fields size mismatch");
-  Assert(Lp.size() == m_pNodefields.nprop(), "Fields size mismatch");
-  for (std::size_t f=0; f<Lu.size(); ++f)
-    Assert( gid.size() == Lu[f].size(), "Size mismatch" );
-  for (std::size_t f=0; f<Lp.size(); ++f)
-    Assert( gid.size() == Lp[f].size(), "Size mismatch" );
-
-  for (std::size_t i=0; i<gid.size(); ++i) {
-    auto& nfu = m_uNodefieldsc[ gid[i] ];
-    nfu.first.resize( Lu.size() );
-    for (std::size_t f=0; f<Lu.size(); ++f) nfu.first[f] += Lu[f][i];
-    nfu.second += nesup[i];
-    auto& nfp = m_pNodefieldsc[ gid[i] ];
-    nfp.first.resize( Lp.size() );
-    for (std::size_t f=0; f<Lp.size(); ++f) nfp.first[f] += Lp[f][i];
-    nfp.second += nesup[i];
-  }
-
-  // When we have heard from all chares we communicate with, this chare is done
-  if (++m_nnod == Disc()->NodeCommMap().size()) {
-    m_nnod = 0;
-    comnodeout_complete();
-  }
-}
-
-void
-DG::stage()
-// *****************************************************************************
-// Evaluate whether to continue with next time step stage
-// *****************************************************************************
-{
-  // Increment Runge-Kutta stage counter
-  ++m_stage;
-
-  // if not all Runge-Kutta stages complete, continue to next time stage,
-  // otherwise prepare for nodal field output
-  if (m_stage < 3)
-    next();
-  else
-    startFieldOutput( CkCallback(CkIndex_DG::step(), thisProxy[thisIndex]) );
-}
-
-void
-DG::evalLB( int nrestart )
-// *****************************************************************************
-// Evaluate whether to do load balancing
-//! \param[in] nrestart Number of times restarted
-// *****************************************************************************
-{
-  auto d = Disc();
-
-  // Detect if just returned from a checkpoint and if so, zero timers
-  d->restarted( nrestart );
-
-  const auto lbfreq = g_inputdeck.get< tag::cmd, tag::lbfreq >();
-  const auto nonblocking = g_inputdeck.get< tag::cmd, tag::nonblocking >();
-
-  // Load balancing if user frequency is reached or after the second time-step
-  if ( (d->It()) % lbfreq == 0 || d->It() == 2 ) {
-
-    AtSync();
-    if (nonblocking) next();
-
-  } else {
-
-    next();
-
-  }
-}
-
-void
-DG::evalRestart()
-// *****************************************************************************
-// Evaluate whether to save checkpoint/restart
-// *****************************************************************************
-{
-  auto d = Disc();
-
-  const auto rsfreq = g_inputdeck.get< tag::cmd, tag::rsfreq >();
-  const auto benchmark = g_inputdeck.get< tag::cmd, tag::benchmark >();
-
-  if (not benchmark and not (d->It() % rsfreq)) {
-
-    std::vector< std::size_t > meshdata{ /* finished = */ 0, d->MeshId() };
-    contribute( meshdata, CkReduction::nop,
-      CkCallback(CkReductionTarget(Transporter,checkpoint), d->Tr()) );
-
-  } else {
-
-    evalLB( /* nrestart = */ -1 );
-
-  }
-}
-
-void
-DG::step()
-// *****************************************************************************
-// Evaluate wether to continue with next time step
-// *****************************************************************************
-{
-  auto d = Disc();
-
-  // Output time history
-  if (d->histiter() or d->histtime() or d->histrange()) {
-    std::vector< std::vector< tk::real > > hist;
-    auto h = g_dgpde[d->MeshId()].histOutput( d->Hist(), myGhosts()->m_inpoel,
-      myGhosts()->m_coord, m_u, m_p );
-    hist.insert( end(hist), begin(h), end(h) );
-    d->history( std::move(hist) );
-  }
-
-  // Free memory storing output mesh
-  m_outmesh.destroy();
-
-  // Output one-liner status report to screen
-  d->status();
-  // Reset Runge-Kutta stage counter
-  m_stage = 0;
-
-  const auto term = g_inputdeck.get< tag::term >();
-  const auto nstep = g_inputdeck.get< tag::nstep >();
-  const auto eps = std::numeric_limits< tk::real >::epsilon();
-
-  // If neither max iterations nor max time reached, continue, otherwise finish
-  if (std::fabs(d->T()-term) > eps && d->It() < nstep) {
-
-    evalRestart();
- 
-  } else {
-
-    auto meshid = d->MeshId();
-    d->contribute( sizeof(std::size_t), &meshid, CkReduction::nop,
-                   CkCallback(CkReductionTarget(Transporter,finish), d->Tr()) );
-
-  }
-}
-
-void
-DG::imex_integrate()
-{
-  /*****************************************************************************
-  Performs the Implicit-Explicit Runge-Kutta step.
-
-  \details Performs the Implicit-Explicit Runge-Kutta step. Scheme taken from
-  Cavaglieri, D., & Bewley, T. (2015). Low-storage implicit/explicit Runge–Kutta
-  schemes for the simulation of stiff high-dimensional ODE systems. Journal of
-  Computational Physics, 286, 172-193.
-
-  Scheme given by equations (25a,b):
-
-  u[0] = u[n] + dt * (expl_rkcoef[1,0]*R_ex(u[n])+impl_rkcoef[1,1]*R_im(u[0]))
-
-  u[1] = u[n] + dt * (expl_rkcoef[2,1]*R_ex(u[0])+impl_rkcoef[2,1]*R_im(u[0])
-                                                 +impl_rkcoef[2,2]*R_im(u[1]))
-
-  u[n+1] = u[n] + dt * (expl_rkcoef[3,1]*R_ex(u[0])+impl_rkcoef[3,1]*R_im(u[0])
-                        expl_rkcoef[3,2]*R_ex(u[1])+impl_rkcoef[3,2]*R_im(u[1]))
-
-  In order to solve the first two equations we need to solve a series of systems
-  of non-linear equations:
-
-  F1(u[0]) = B1 + R1(u[0]) = 0, and
-  F2(u[1]) = B2 + R2(u[1]) = 0,
-
-  where
-
-  B1 = u[n] + dt * expl_rkcoef[1,0]*R_ex(u[n]),
-  R1 = dt * impl_rkcoef[1,1]*R_im(u[0]) - u([0]),
-  B2 = u[n] + dt * (expl_rkcoef[2,1]*R_ex(u[0])+impl_rkcoef[2,1]*R_im(u[0])),
-  R2 = dt * impl_rkcoef[2,2]*R_im(u[1]) - u([1]).
-
-  In order to solve the non-linear system F(U) = 0, we employ Broyden's method.
-  Taken from https://en.wikipedia.org/wiki/Broyden%27s_method.
-  The method consists in obtaining an approximation for the inverse of the
-  Jacobian H = J^(-1) and advancing in a quasi-newton step:
-
-  U[k+1] = U[k] - H[k]*F(U[k]),
-
-  until F(U) is close enough to zero.
-
-  The approximation H[k] is improved at every iteration following
-
-  H[k] = H[k-1] + (DU[k]-H[k-1]*DF[k])/(DU[k]^T*H[k-1]*DF[k]) * DU[k]^T*H[k-1],
-
-  where DU[k] = U[k] - U[k-1] and DF[k] = F(U[k]) - F(U[k-1)).
-
-  This function performs the following main algorithmic steps:
-  - If stage == 0 or stage == 1:
-    - Take Initial value:
-      U[0] = U[n] + dt * expl_rkcoef[1,0]*R_ex(U[n]) (for stage 0)
-      U[1] = U[n] + dt * (expl_rkcoef[2,1]*R_ex(U[0])
-                         +impl_rkcoef[2,1]*R_im(U[0])) (for stage 1)
-    - Loop over the Elements (e++)
-      - Initialize Jacobian inverse approximation as the identity
-      - Compute implicit right-hand-side (F_im) with current U
-      - Iterate for the solution (iter++)
-        - Compute new solution U[k+1] = U[k] - H[k]*F(U[k])
-        - Compute implicit right-hand-side (F_im) with current U
-        - Compute DU and DF
-        - Update inverse Jacobian approximation by:
-          - Compute V1 = H[k-1]*DF[k] and V2 = DU[k]^T*H[k-1]
-          - Compute d = DU[k]^T*V1 and V3 = DU[k]-V1
-          - Compute V4 = V3/d
-          - Update H[k] = H[k-1] + V4*V2
-        - Save old U and F
-        - Compute absolute and relative errors
-        - Break iterations if error < tol or iter == max_iter
-     - Update explicit equations using only the explicit terms.
-  - Else if stage == 2:
-     - Update explicit equations using only the explicit terms.
-     - Update implicit equations using:
-     u[n+1] = u[n]+dt*(expl_rkcoef[3,1]*R_ex(u[0])+impl_rkcoef[3,1]*R_im(u[0])
-                       expl_rkcoef[3,2]*R_ex(u[1])+impl_rkcoef[3,2]*R_im(u[1]))
-
-  ******************************************************************************/
-  auto d = Disc();
-  const auto rdof = g_inputdeck.get< tag::rdof >();
-  const auto ndof = g_inputdeck.get< tag::ndof >();
-  if (m_stage < 2) {
-    // Save previous stiff_rhs
-    m_stiffrhsprev = m_stiffrhs;
-
-    // Compute the imex update
-
-    // Integrate explicitly on the imex equations
-    // (To use as initial values)
-    for (std::size_t e=0; e<myGhosts()->m_nunk; ++e)
-      for (std::size_t c=0; c<m_nstiffeq; ++c)
-      {
-        for (std::size_t k=0; k<m_numEqDof[c]; ++k)
-        {
-          auto rmark = m_stiffEqIdx[c]*rdof+k;
-          auto mark = m_stiffEqIdx[c]*ndof+k;
-          m_u(e, rmark) =  m_un(e, rmark) + d->Dt() * (
-            expl_rkcoef[0][m_stage] * m_rhsprev(e, mark)/m_lhs(e, mark)
-            + expl_rkcoef[1][m_stage] * m_rhs(e, mark)/m_lhs(e, mark)
-            + impl_rkcoef[0][m_stage]
-            * m_stiffrhsprev(e,c*ndof+k)/m_lhs(e, mark) );
-          if(fabs(m_u(e, rmark)) < 1e-16)
-            m_u(e, rmark) = 0;
-        }
-      }
-
-    // Solve for implicit-explicit equations
-    const auto nelem = myGhosts()->m_fd.Esuel().size()/4;
-    for (std::size_t e=0; e<nelem; ++e)
-    {
-      // Non-linear system f(u) = 0 to be solved
-      // Broyden's method
-      // Control parameters
-      std::size_t max_iter = g_inputdeck.get< tag::imex_maxiter >();
-      tk::real rel_tol = g_inputdeck.get< tag::imex_reltol >();
-      tk::real abs_tol = g_inputdeck.get< tag::imex_abstol >();
-      tk::real rel_err = rel_tol+1;
-      tk::real abs_err = abs_tol+1;
-      std::size_t nstiff = m_nstiffeq*ndof;
-
-      // Initialize Jacobian to be the identity
-      std::vector< std::vector< tk::real > >
-        approx_jacob(nstiff, std::vector< tk::real >(nstiff, 0.0));
-      for (std::size_t i=0; i<nstiff; ++i)
-        approx_jacob[i][i] = 1.0e+00;
-
-      // Save explicit terms to be re-used
-      std::vector< tk::real > expl_terms(nstiff, 0.0);
-      for (size_t ieq=0; ieq<m_nstiffeq; ++ieq)
-        for (size_t idof=0; idof<m_numEqDof[ieq]; ++idof)
-        {
-          auto stiffmark = m_stiffEqIdx[ieq]*ndof+idof;
-          auto stiffrmark = m_stiffEqIdx[ieq]*rdof+idof;
-          expl_terms[ieq*ndof+idof] = m_un(e, stiffrmark)
-            + d->Dt() * ( expl_rkcoef[0][m_stage]
-            * m_rhsprev(e,stiffmark)/m_lhs(e,stiffmark)
-            + expl_rkcoef[1][m_stage]
-            * m_rhs(e,stiffmark)/m_lhs(e,stiffmark)
-            + impl_rkcoef[0][m_stage]
-            * m_stiffrhsprev(e,ieq*ndof+idof)/m_lhs(e,stiffmark) );
-        }
-
-      // Compute stiff_rhs with initial u
-      g_dgpde[d->MeshId()].stiff_rhs( e, myGhosts()->m_geoElem,
-        myGhosts()->m_inpoel, myGhosts()->m_coord,
-        m_u, m_p, m_ndof, m_stiffrhs );
-
-      // Make auxiliary u_old and f_old to store previous values
-      std::vector< tk::real > u_old(nstiff, 0.0), f_old(nstiff, 0.0);
-      // Make delta_u and delta_f
-      std::vector< tk::real > delta_u(nstiff, 0.0), delta_f(nstiff, 0.0);
-      // Store f
-      std::vector< tk::real > f(nstiff, 0.0);
-      for (std::size_t ieq=0; ieq<m_nstiffeq; ++ieq)
-        for (std::size_t idof=0; idof<m_numEqDof[ieq]; ++idof)
-        {
-          auto stiffrmark = m_stiffEqIdx[ieq]*rdof+idof;
-          auto stiffmark = m_stiffEqIdx[ieq]*ndof+idof;
-          f[ieq*ndof+idof] = expl_terms[ieq*ndof+idof]
-            + d->Dt() * impl_rkcoef[1][m_stage]
-            * m_stiffrhs(e,ieq*ndof+idof)/m_lhs(e,stiffmark)
-            - m_u(e, stiffrmark);
-        }
-
-      // Initialize u_old and f_old
-      for (std::size_t ieq=0; ieq<m_nstiffeq; ++ieq)
-        for (std::size_t idof=0; idof<m_numEqDof[ieq]; ++idof)
-        {
-          u_old[ieq*ndof+idof] = m_u(e, m_stiffEqIdx[ieq]*rdof+idof);
-          f_old[ieq*ndof+idof] = f[ieq*ndof+idof];
-        }
-
-      // Store the norm of f initially, for relative error measure
-      tk::real err0 = 0.0;
-      for (std::size_t ieq=0; ieq<m_nstiffeq; ++ieq)
-        for (std::size_t idof=0; idof<m_numEqDof[ieq]; ++idof)
-          err0 += f[ieq*ndof+idof]*f[ieq*ndof+idof];
-      err0 = std::sqrt(err0);
-
-      // Iterate for the solution if err0 > 0
-      if (err0 > abs_tol)
-        for (size_t iter=0; iter<max_iter; ++iter)
-        {
-
-          // Compute new solution
-          tk::real delta;
-          for (std::size_t ieq=0; ieq<m_nstiffeq; ++ieq)
-            for (std::size_t idof=0; idof<m_numEqDof[ieq]; ++idof)
-            {
-              delta = 0.0;
-              for (std::size_t jeq=0; jeq<m_nstiffeq; ++jeq)
-                for (std::size_t jdof=0; jdof<m_numEqDof[jeq]; ++jdof)
-                  delta +=
-                    approx_jacob[ieq*ndof+idof][jeq*ndof+jdof] * f[jeq*ndof+jdof];
-              // Update u
-              auto stiffrmark = m_stiffEqIdx[ieq]*rdof+idof;
-              m_u(e, stiffrmark) -= delta;
-            }
-
-          // Compute new stiff_rhs
-          g_dgpde[d->MeshId()].stiff_rhs( e, myGhosts()->m_geoElem,
-            myGhosts()->m_inpoel, myGhosts()->m_coord,
-            m_u, m_p, m_ndof, m_stiffrhs );
-
-          // Compute new f(u)
-          for (std::size_t ieq=0; ieq<m_nstiffeq; ++ieq)
-            for (std::size_t idof=0; idof<m_numEqDof[ieq]; ++idof)
-            {
-              auto stiffrmark = m_stiffEqIdx[ieq]*rdof+idof;
-              auto stiffmark = m_stiffEqIdx[ieq]*ndof+idof;
-              f[ieq*ndof+idof] = expl_terms[ieq*ndof+idof]
-                + d->Dt() * impl_rkcoef[1][m_stage]
-                * m_stiffrhs(e,ieq*ndof+idof)/m_lhs(e,stiffmark)
-                - m_u(e, stiffrmark);
-            }
-
-          // Compute delta_u and delta_f
-          for (std::size_t ieq=0; ieq<m_nstiffeq; ++ieq)
-            for (std::size_t idof=0; idof<m_numEqDof[ieq]; ++idof)
-            {
-              auto stiffrmark = m_stiffEqIdx[ieq]*rdof+idof;
-              delta_u[ieq*ndof+idof] = m_u(e, stiffrmark) - u_old[ieq*ndof+idof];
-              delta_f[ieq*ndof+idof] = f[ieq*ndof+idof] - f_old[ieq*ndof+idof];
-            }
-
-          // Update inverse Jacobian approximation
-
-          // 1. Compute approx_jacob*delta_f and delta_u*jacob_approx
-          tk::real sum1, sum2;
-          std::vector< tk::real > auxvec1(nstiff, 0.0), auxvec2(nstiff, 0.0);
-          for (std::size_t ieq=0; ieq<m_nstiffeq; ++ieq)
-            for (std::size_t idof=0; idof<m_numEqDof[ieq]; ++idof)
-            {
-              sum1 = 0.0;
-              sum2 = 0.0;
-              for (std::size_t jeq=0; jeq<m_nstiffeq; ++jeq)
-                for (std::size_t jdof=0; jdof<m_numEqDof[jeq]; ++jdof)
-                {
-                  sum1 += approx_jacob[ieq*ndof+idof][jeq*ndof+jdof] *
-                    delta_f[jeq*ndof+jdof];
-                  sum2 += delta_u[jeq*ndof+jdof] *
-                    approx_jacob[jeq*ndof+jdof][ieq*ndof+idof];
-                }
-              auxvec1[ieq*ndof+idof] = sum1;
-              auxvec2[ieq*ndof+idof] = sum2;
-            }
-
-          // 2. Compute delta_u*approx_jacob*delta_f
-          // and delta_u-approx_jacob*delta_f
-          tk::real denom = 0.0;
-          for (std::size_t jeq=0; jeq<m_nstiffeq; ++jeq)
-            for (std::size_t jdof=0; jdof<m_numEqDof[jeq]; ++jdof)
-            {
-              denom += delta_u[jeq*ndof+jdof]*auxvec1[jeq*ndof+jdof];
-              auxvec1[jeq*ndof+jdof] =
-                delta_u[jeq*ndof+jdof]-auxvec1[jeq*ndof+jdof];
-            }
-
-          // 3. Divide delta_u+approx_jacob*delta_f
-          // by delta_u*(approx_jacob*delta_f)
-          if (std::abs(denom) < 1.0e-18)
-          {
-            if (denom < 0.0)
-            {
-              for (std::size_t jeq=0; jeq<m_nstiffeq; ++jeq)
-                for (std::size_t jdof=0; jdof<m_numEqDof[jeq]; ++jdof)
-                  auxvec1[jeq*ndof+jdof] /= -1.0e-18;
-            }
-            else
-            {
-              for (std::size_t jeq=0; jeq<m_nstiffeq; ++jeq)
-                for (std::size_t jdof=0; jdof<m_numEqDof[jeq]; ++jdof)
-                  auxvec1[jeq*ndof+jdof] /= 1.0e-18;
-            }
-          }
-          else
-          {
-            for (std::size_t jeq=0; jeq<m_nstiffeq; ++jeq)
-              for (std::size_t jdof=0; jdof<m_numEqDof[jeq]; ++jdof)
-                auxvec1[jeq*ndof+jdof] /= denom;
-          }
-
-          // 4. Perform outter product between the two arrays and
-          // add that quantity to the new jacobian approximation
-          for (std::size_t ieq=0; ieq<m_nstiffeq; ++ieq)
-            for (std::size_t idof=0; idof<m_numEqDof[ieq]; ++idof)
-              for (std::size_t jeq=0; jeq<m_nstiffeq; ++jeq)
-                for (std::size_t jdof=0; jdof<m_numEqDof[jeq]; ++jdof)
-                  approx_jacob[ieq*ndof+idof][jeq*ndof+jdof] +=
-                    auxvec1[ieq*ndof+idof] * auxvec2[jeq*ndof+jdof];
-
-          // Save solution and f
-          for (std::size_t ieq=0; ieq<m_nstiffeq; ++ieq)
-            for (std::size_t idof=0; idof<m_numEqDof[ieq]; ++idof)
-            {
-              u_old[ieq*ndof+idof] = m_u(e, m_stiffEqIdx[ieq]*rdof+idof);
-              f_old[ieq*ndof+idof] = f[ieq*ndof+idof];
-            }
-
-          // Compute a measure of error, use norm of f
-          tk::real err = 0.0;
-          for (std::size_t ieq=0; ieq<m_nstiffeq; ++ieq)
-            for (std::size_t idof=0; idof<m_numEqDof[ieq]; ++idof)
-              err += f[ieq*ndof+idof]*f[ieq*ndof+idof];
-          abs_err = std::sqrt(err);
-          rel_err = abs_err/err0;
-
-          // Check if error condition is met and loop back
-          if (rel_err < rel_tol || abs_err < abs_tol)
-            break;
-
-          // If we did not converge, print a message
-          if (iter == max_iter-1)
-          {
-            printf("\nIMEX-RK: Non-linear solver did not converge in %lu iterations\n", max_iter);<--- %lu in format string (no. 1) requires 'unsigned long' but the argument type is 'std::size_t {aka unsigned long}'.
-            printf("Element #%lu\n", e);<--- %lu in format string (no. 1) requires 'unsigned long' but the argument type is 'std::size_t {aka unsigned long}'.
-            printf("Relative error: %e\n", rel_err);
-            printf("Absolute error: %e\n\n", abs_err);
-          }
-        }
-    }
-
-    // Then, integrate explicitly on the remaining equations
-    for (std::size_t e=0; e<nelem; ++e)
-      for (std::size_t c=0; c<m_nnonstiffeq; ++c)
-      {
-        for (std::size_t k=0; k<m_numEqDof[c]; ++k)
-        {
-          auto rmark = m_nonStiffEqIdx[c]*rdof+k;
-          auto mark = m_nonStiffEqIdx[c]*ndof+k;
-          m_u(e, rmark) =  m_un(e, rmark) + d->Dt() * (
-            expl_rkcoef[0][m_stage] * m_rhsprev(e, mark)/m_lhs(e, mark)
-            + expl_rkcoef[1][m_stage] * m_rhs(e, mark)/m_lhs(e, mark));
-          if(fabs(m_u(e, rmark)) < 1e-16)
-            m_u(e, rmark) = 0;
-        }
-      }
-  }
-  else {
-    // For last stage just use all previously computed stages
-    const auto nelem = myGhosts()->m_fd.Esuel().size()/4;
-    for (std::size_t e=0; e<nelem; ++e)
-    {
-      // First integrate explicitly on nonstiff equations
-      for (std::size_t c=0; c<m_nnonstiffeq; ++c)
-      {
-        for (std::size_t k=0; k<m_numEqDof[c]; ++k)
-        {
-          auto rmark = m_nonStiffEqIdx[c]*rdof+k;
-          auto mark = m_nonStiffEqIdx[c]*ndof+k;
-          m_u(e, rmark) =  m_un(e, rmark) + d->Dt() * (
-            expl_rkcoef[0][m_stage] * m_rhsprev(e, mark)/m_lhs(e, mark)
-            + expl_rkcoef[1][m_stage] * m_rhs(e, mark)/m_lhs(e, mark));
-          if(fabs(m_u(e, rmark)) < 1e-16)
-            m_u(e, rmark) = 0;
-        }
-      }
-      // Then, integrate the imex-equations
-      for (std::size_t ieq=0; ieq<m_nstiffeq; ++ieq)
-        for (std::size_t idof=0; idof<m_numEqDof[ieq]; ++idof)
-        {
-          auto rmark = m_stiffEqIdx[ieq]*rdof+idof;
-          auto mark = m_stiffEqIdx[ieq]*ndof+idof;
-          m_u(e, rmark) = m_un(e, rmark)
-            + d->Dt() * (expl_rkcoef[0][m_stage]
-                         * m_rhsprev(e,mark)/m_lhs(e,mark)
-                         + expl_rkcoef[1][m_stage]
-                         * m_rhs(e,mark)/m_lhs(e,mark)
-                         + impl_rkcoef[0][m_stage]
-                         * m_stiffrhsprev(e,ieq*ndof+idof)/m_lhs(e,mark)
-                         + impl_rkcoef[1][m_stage]
-                         * m_stiffrhs(e,ieq*ndof+idof)/m_lhs(e,mark) );
-          if(fabs(m_u(e, rmark)) < 1e-16)
-            m_u(e, rmark) = 0;
-        }
-    }
-  }
-}
-
-#include "NoWarning/dg.def.h"
+}
+
+#include "NoWarning/fv.def.h"
 
diff --git a/Release/cppcheck/52.html b/Release/cppcheck/52.html index 265e1270f351..06d144db68d3 100644 --- a/Release/cppcheck/52.html +++ b/Release/cppcheck/52.html @@ -152,4403 +152,407 @@
- - + @@ -73,7 +73,7 @@ - +
   1
-   2
-   3
-   4
-   5
-   6
-   7
-   8
-   9
-  10
-  11
-  12
-  13
-  14
-  15
-  16
-  17
-  18
-  19
-  20
-  21
-  22
-  23
-  24
-  25
-  26
-  27
-  28
-  29
-  30
-  31
-  32
-  33
-  34
-  35
-  36
-  37
-  38
-  39
-  40
-  41
-  42
-  43
-  44
-  45
-  46
-  47
-  48
-  49
-  50
-  51
-  52
-  53
-  54
-  55
-  56
-  57
-  58
-  59
-  60
-  61
-  62
-  63
-  64
-  65
-  66
-  67
-  68
-  69
-  70
-  71
-  72
-  73
-  74
-  75
-  76
-  77
-  78
-  79
-  80
-  81
-  82
-  83
-  84
-  85
-  86
-  87
-  88
-  89
-  90
-  91
-  92
-  93
-  94
-  95
-  96
-  97
-  98
-  99
- 100
- 101
- 102
- 103
- 104
- 105
- 106
- 107
- 108
- 109
- 110
- 111
- 112
- 113
- 114
- 115
- 116
- 117
- 118
- 119
- 120
- 121
- 122
- 123
- 124
- 125
- 126
- 127
- 128
- 129
- 130
- 131
- 132
- 133
- 134
- 135
- 136
- 137
- 138
- 139
- 140
- 141
- 142
- 143
- 144
- 145
- 146
- 147
- 148
- 149
- 150
- 151
- 152
- 153
- 154
- 155
- 156
- 157
- 158
- 159
- 160
- 161
- 162
- 163
- 164
- 165
- 166
- 167
- 168
- 169
- 170
- 171
- 172
- 173
- 174
- 175
- 176
- 177
- 178
- 179
- 180
- 181
- 182
- 183
- 184
- 185
- 186
- 187
- 188
- 189
- 190
- 191
- 192
- 193
- 194
- 195
- 196
- 197
- 198
- 199
- 200
- 201
- 202
- 203
- 204
- 205
- 206
- 207
- 208
- 209
- 210
- 211
- 212
- 213
- 214
- 215
- 216
- 217
- 218
- 219
- 220
- 221
- 222
- 223
- 224
- 225
- 226
- 227
- 228
- 229
- 230
- 231
- 232
- 233
- 234
- 235
- 236
- 237
- 238
- 239
- 240
- 241
- 242
- 243
- 244
- 245
- 246
- 247
- 248
- 249
- 250
- 251
- 252
- 253
- 254
- 255
- 256
- 257
- 258
- 259
- 260
- 261
- 262
- 263
- 264
- 265
- 266
- 267
- 268
- 269
- 270
- 271
- 272
- 273
- 274
- 275
- 276
- 277
- 278
- 279
- 280
- 281
- 282
- 283
- 284
- 285
- 286
- 287
- 288
- 289
- 290
- 291
- 292
- 293
- 294
- 295
- 296
- 297
- 298
- 299
- 300
- 301
- 302
- 303
- 304
- 305
- 306
- 307
- 308
- 309
- 310
- 311
- 312
- 313
- 314
- 315
- 316
- 317
- 318
- 319
- 320
- 321
- 322
- 323
- 324
- 325
- 326
- 327
- 328
- 329
- 330
- 331
- 332
- 333
- 334
- 335
- 336
- 337
- 338
- 339
- 340
- 341
- 342
- 343
- 344
- 345
- 346
- 347
- 348
- 349
- 350
- 351
- 352
- 353
- 354
- 355
- 356
- 357
- 358
- 359
- 360
- 361
- 362
- 363
- 364
- 365
- 366
- 367
- 368
- 369
- 370
- 371
- 372
- 373
- 374
- 375
- 376
- 377
- 378
- 379
- 380
- 381
- 382
- 383
- 384
- 385
- 386
- 387
- 388
- 389
- 390
- 391
- 392
- 393
- 394
- 395
- 396
- 397
- 398
- 399
- 400
- 401
- 402
- 403
- 404
- 405
- 406
- 407
- 408
- 409
- 410
- 411
- 412
- 413
- 414
- 415
- 416
- 417
- 418
- 419
- 420
- 421
- 422
- 423
- 424
- 425
- 426
- 427
- 428
- 429
- 430
- 431
- 432
- 433
- 434
- 435
- 436
- 437
- 438
- 439
- 440
- 441
- 442
- 443
- 444
- 445
- 446
- 447
- 448
- 449
- 450
- 451
- 452
- 453
- 454
- 455
- 456
- 457
- 458
- 459
- 460
- 461
- 462
- 463
- 464
- 465
- 466
- 467
- 468
- 469
- 470
- 471
- 472
- 473
- 474
- 475
- 476
- 477
- 478
- 479
- 480
- 481
- 482
- 483
- 484
- 485
- 486
- 487
- 488
- 489
- 490
- 491
- 492
- 493
- 494
- 495
- 496
- 497
- 498
- 499
- 500
- 501
- 502
- 503
- 504
- 505
- 506
- 507
- 508
- 509
- 510
- 511
- 512
- 513
- 514
- 515
- 516
- 517
- 518
- 519
- 520
- 521
- 522
- 523
- 524
- 525
- 526
- 527
- 528
- 529
- 530
- 531
- 532
- 533
- 534
- 535
- 536
- 537
- 538
- 539
- 540
- 541
- 542
- 543
- 544
- 545
- 546
- 547
- 548
- 549
- 550
- 551
- 552
- 553
- 554
- 555
- 556
- 557
- 558
- 559
- 560
- 561
- 562
- 563
- 564
- 565
- 566
- 567
- 568
- 569
- 570
- 571
- 572
- 573
- 574
- 575
- 576
- 577
- 578
- 579
- 580
- 581
- 582
- 583
- 584
- 585
- 586
- 587
- 588
- 589
- 590
- 591
- 592
- 593
- 594
- 595
- 596
- 597
- 598
- 599
- 600
- 601
- 602
- 603
- 604
- 605
- 606
- 607
- 608
- 609
- 610
- 611
- 612
- 613
- 614
- 615
- 616
- 617
- 618
- 619
- 620
- 621
- 622
- 623
- 624
- 625
- 626
- 627
- 628
- 629
- 630
- 631
- 632
- 633
- 634
- 635
- 636
- 637
- 638
- 639
- 640
- 641
- 642
- 643
- 644
- 645
- 646
- 647
- 648
- 649
- 650
- 651
- 652
- 653
- 654
- 655
- 656
- 657
- 658
- 659
- 660
- 661
- 662
- 663
- 664
- 665
- 666
- 667
- 668
- 669
- 670
- 671
- 672
- 673
- 674
- 675
- 676
- 677
- 678
- 679
- 680
- 681
- 682
- 683
- 684
- 685
- 686
- 687
- 688
- 689
- 690
- 691
- 692
- 693
- 694
- 695
- 696
- 697
- 698
- 699
- 700
- 701
- 702
- 703
- 704
- 705
- 706
- 707
- 708
- 709
- 710
- 711
- 712
- 713
- 714
- 715
- 716
- 717
- 718
- 719
- 720
- 721
- 722
- 723
- 724
- 725
- 726
- 727
- 728
- 729
- 730
- 731
- 732
- 733
- 734
- 735
- 736
- 737
- 738
- 739
- 740
- 741
- 742
- 743
- 744
- 745
- 746
- 747
- 748
- 749
- 750
- 751
- 752
- 753
- 754
- 755
- 756
- 757
- 758
- 759
- 760
- 761
- 762
- 763
- 764
- 765
- 766
- 767
- 768
- 769
- 770
- 771
- 772
- 773
- 774
- 775
- 776
- 777
- 778
- 779
- 780
- 781
- 782
- 783
- 784
- 785
- 786
- 787
- 788
- 789
- 790
- 791
- 792
- 793
- 794
- 795
- 796
- 797
- 798
- 799
- 800
- 801
- 802
- 803
- 804
- 805
- 806
- 807
- 808
- 809
- 810
- 811
- 812
- 813
- 814
- 815
- 816
- 817
- 818
- 819
- 820
- 821
- 822
- 823
- 824
- 825
- 826
- 827
- 828
- 829
- 830
- 831
- 832
- 833
- 834
- 835
- 836
- 837
- 838
- 839
- 840
- 841
- 842
- 843
- 844
- 845
- 846
- 847
- 848
- 849
- 850
- 851
- 852
- 853
- 854
- 855
- 856
- 857
- 858
- 859
- 860
- 861
- 862
- 863
- 864
- 865
- 866
- 867
- 868
- 869
- 870
- 871
- 872
- 873
- 874
- 875
- 876
- 877
- 878
- 879
- 880
- 881
- 882
- 883
- 884
- 885
- 886
- 887
- 888
- 889
- 890
- 891
- 892
- 893
- 894
- 895
- 896
- 897
- 898
- 899
- 900
- 901
- 902
- 903
- 904
- 905
- 906
- 907
- 908
- 909
- 910
- 911
- 912
- 913
- 914
- 915
- 916
- 917
- 918
- 919
- 920
- 921
- 922
- 923
- 924
- 925
- 926
- 927
- 928
- 929
- 930
- 931
- 932
- 933
- 934
- 935
- 936
- 937
- 938
- 939
- 940
- 941
- 942
- 943
- 944
- 945
- 946
- 947
- 948
- 949
- 950
- 951
- 952
- 953
- 954
- 955
- 956
- 957
- 958
- 959
- 960
- 961
- 962
- 963
- 964
- 965
- 966
- 967
- 968
- 969
- 970
- 971
- 972
- 973
- 974
- 975
- 976
- 977
- 978
- 979
- 980
- 981
- 982
- 983
- 984
- 985
- 986
- 987
- 988
- 989
- 990
- 991
- 992
- 993
- 994
- 995
- 996
- 997
- 998
- 999
-1000
-1001
-1002
-1003
-1004
-1005
-1006
-1007
-1008
-1009
-1010
-1011
-1012
-1013
-1014
-1015
-1016
-1017
-1018
-1019
-1020
-1021
-1022
-1023
-1024
-1025
-1026
-1027
-1028
-1029
-1030
-1031
-1032
-1033
-1034
-1035
-1036
-1037
-1038
-1039
-1040
-1041
-1042
-1043
-1044
-1045
-1046
-1047
-1048
-1049
-1050
-1051
-1052
-1053
-1054
-1055
-1056
-1057
-1058
-1059
-1060
-1061
-1062
-1063
-1064
-1065
-1066
-1067
-1068
-1069
-1070
-1071
-1072
-1073
-1074
-1075
-1076
-1077
-1078
-1079
-1080
-1081
-1082
-1083
-1084
-1085
-1086
-1087
-1088
-1089
-1090
-1091
-1092
-1093
-1094
-1095
-1096
-1097
-1098
-1099
-1100
-1101
-1102
-1103
-1104
-1105
-1106
-1107
-1108
-1109
-1110
-1111
-1112
-1113
-1114
-1115
-1116
-1117
-1118
-1119
-1120
-1121
-1122
-1123
-1124
-1125
-1126
-1127
-1128
-1129
-1130
-1131
-1132
-1133
-1134
-1135
-1136
-1137
-1138
-1139
-1140
-1141
-1142
-1143
-1144
-1145
-1146
-1147
-1148
-1149
-1150
-1151
-1152
-1153
-1154
-1155
-1156
-1157
-1158
-1159
-1160
-1161
-1162
-1163
-1164
-1165
-1166
-1167
-1168
-1169
-1170
-1171
-1172
-1173
-1174
-1175
-1176
-1177
-1178
-1179
-1180
-1181
-1182
-1183
-1184
-1185
-1186
-1187
-1188
-1189
-1190
-1191
-1192
-1193
-1194
-1195
-1196
-1197
-1198
-1199
-1200
-1201
-1202
-1203
-1204
-1205
-1206
-1207
-1208
-1209
-1210
-1211
-1212
-1213
-1214
-1215
-1216
-1217
-1218
-1219
-1220
-1221
-1222
-1223
-1224
-1225
-1226
-1227
-1228
-1229
-1230
-1231
-1232
-1233
-1234
-1235
-1236
-1237
-1238
-1239
-1240
-1241
-1242
-1243
-1244
-1245
-1246
-1247
-1248
-1249
-1250
-1251
-1252
-1253
-1254
-1255
-1256
-1257
-1258
-1259
-1260
-1261
-1262
-1263
-1264
-1265
-1266
-1267
-1268
-1269
-1270
-1271
-1272
-1273
-1274
-1275
-1276
-1277
-1278
-1279
-1280
-1281
-1282
-1283
-1284
-1285
-1286
-1287
-1288
-1289
-1290
-1291
-1292
-1293
-1294
-1295
-1296
-1297
-1298
-1299
-1300
-1301
-1302
-1303
-1304
-1305
-1306
-1307
-1308
-1309
-1310
-1311
-1312
-1313
-1314
-1315
-1316
-1317
-1318
-1319
-1320
-1321
-1322
-1323
-1324
-1325
-1326
-1327
-1328
-1329
-1330
-1331
-1332
-1333
-1334
-1335
-1336
-1337
-1338
-1339
-1340
-1341
-1342
-1343
-1344
-1345
-1346
-1347
-1348
-1349
-1350
-1351
-1352
-1353
-1354
-1355
-1356
-1357
-1358
-1359
-1360
-1361
-1362
-1363
-1364
-1365
-1366
-1367
-1368
-1369
-1370
-1371
-1372
-1373
-1374
-1375
-1376
-1377
-1378
-1379
-1380
-1381
-1382
-1383
-1384
-1385
-1386
-1387
-1388
-1389
-1390
-1391
-1392
-1393
-1394
-1395
-1396
-1397
-1398
-1399
-1400
-1401
-1402
-1403
-1404
-1405
-1406
-1407
-1408
-1409
-1410
-1411
-1412
-1413
-1414
-1415
-1416
-1417
-1418
-1419
-1420
-1421
-1422
-1423
-1424
-1425
-1426
-1427
-1428
-1429
-1430
-1431
-1432
-1433
-1434
-1435
-1436
-1437
-1438
-1439
-1440
-1441
-1442
-1443
-1444
-1445
-1446
-1447
-1448
-1449
-1450
-1451
-1452
-1453
-1454
-1455
-1456
-1457
-1458
-1459
-1460
-1461
-1462
-1463
-1464
-1465
-1466
-1467
-1468
-1469
-1470
-1471
-1472
-1473
-1474
-1475
-1476
-1477
-1478
-1479
-1480
-1481
-1482
-1483
-1484
-1485
-1486
-1487
-1488
-1489
-1490
-1491
-1492
-1493
-1494
-1495
-1496
-1497
-1498
-1499
-1500
-1501
-1502
-1503
-1504
-1505
-1506
-1507
-1508
-1509
-1510
-1511
-1512
-1513
-1514
-1515
-1516
-1517
-1518
-1519
-1520
-1521
-1522
-1523
-1524
-1525
-1526
-1527
-1528
-1529
-1530
-1531
-1532
-1533
-1534
-1535
-1536
-1537
-1538
-1539
-1540
-1541
-1542
-1543
-1544
-1545
-1546
-1547
-1548
-1549
-1550
-1551
-1552
-1553
-1554
-1555
-1556
-1557
-1558
-1559
-1560
-1561
-1562
-1563
-1564
-1565
-1566
-1567
-1568
-1569
-1570
-1571
-1572
-1573
-1574
-1575
-1576
-1577
-1578
-1579
-1580
-1581
-1582
-1583
-1584
-1585
-1586
-1587
-1588
-1589
-1590
-1591
-1592
-1593
-1594
-1595
-1596
-1597
-1598
-1599
-1600
-1601
-1602
-1603
-1604
-1605
-1606
-1607
-1608
-1609
-1610
-1611
-1612
-1613
-1614
-1615
-1616
-1617
-1618
-1619
-1620
-1621
-1622
-1623
-1624
-1625
-1626
-1627
-1628
-1629
-1630
-1631
-1632
-1633
-1634
-1635
-1636
-1637
-1638
-1639
-1640
-1641
-1642
-1643
-1644
-1645
-1646
-1647
-1648
-1649
-1650
-1651
-1652
-1653
-1654
-1655
-1656
-1657
-1658
-1659
-1660
-1661
-1662
-1663
-1664
-1665
-1666
-1667
-1668
-1669
-1670
-1671
-1672
-1673
-1674
-1675
-1676
-1677
-1678
-1679
-1680
-1681
-1682
-1683
-1684
-1685
-1686
-1687
-1688
-1689
-1690
-1691
-1692
-1693
-1694
-1695
-1696
-1697
-1698
-1699
-1700
-1701
-1702
-1703
-1704
-1705
-1706
-1707
-1708
-1709
-1710
-1711
-1712
-1713
-1714
-1715
-1716
-1717
-1718
-1719
-1720
-1721
-1722
-1723
-1724
-1725
-1726
-1727
-1728
-1729
-1730
-1731
-1732
-1733
-1734
-1735
-1736
-1737
-1738
-1739
-1740
-1741
-1742
-1743
-1744
-1745
-1746
-1747
-1748
-1749
-1750
-1751
-1752
-1753
-1754
-1755
-1756
-1757
-1758
-1759
-1760
-1761
-1762
-1763
-1764
-1765
-1766
-1767
-1768
-1769
-1770
-1771
-1772
-1773
-1774
-1775
-1776
-1777
-1778
-1779
-1780
-1781
-1782
-1783
-1784
-1785
-1786
-1787
-1788
-1789
-1790
-1791
-1792
-1793
-1794
-1795
-1796
-1797
-1798
-1799
-1800
-1801
-1802
-1803
-1804
-1805
-1806
-1807
-1808
-1809
-1810
-1811
-1812
-1813
-1814
-1815
-1816
-1817
-1818
-1819
-1820
-1821
-1822
-1823
-1824
-1825
-1826
-1827
-1828
-1829
-1830
-1831
-1832
-1833
-1834
-1835
-1836
-1837
-1838
-1839
-1840
-1841
-1842
-1843
-1844
-1845
-1846
-1847
-1848
-1849
-1850
-1851
-1852
-1853
-1854
-1855
-1856
-1857
-1858
-1859
-1860
-1861
-1862
-1863
-1864
-1865
-1866
-1867
-1868
-1869
-1870
-1871
-1872
-1873
-1874
-1875
-1876
-1877
-1878
-1879
-1880
-1881
-1882
-1883
-1884
-1885
-1886
-1887
-1888
-1889
-1890
-1891
-1892
-1893
-1894
-1895
-1896
-1897
-1898
-1899
-1900
-1901
-1902
-1903
-1904
-1905
-1906
-1907
-1908
-1909
-1910
-1911
-1912
-1913
-1914
-1915
-1916
-1917
-1918
-1919
-1920
-1921
-1922
-1923
-1924
-1925
-1926
-1927
-1928
-1929
-1930
-1931
-1932
-1933
-1934
-1935
-1936
-1937
-1938
-1939
-1940
-1941
-1942
-1943
-1944
-1945
-1946
-1947
-1948
-1949
-1950
-1951
-1952
-1953
-1954
-1955
-1956
-1957
-1958
-1959
-1960
-1961
-1962
-1963
-1964
-1965
-1966
-1967
-1968
-1969
-1970
-1971
-1972
-1973
-1974
-1975
-1976
-1977
-1978
-1979
-1980
-1981
-1982
-1983
-1984
-1985
-1986
-1987
-1988
-1989
-1990
-1991
-1992
-1993
-1994
-1995
-1996
-1997
-1998
-1999
-2000
-2001
-2002
-2003
-2004
-2005
-2006
-2007
-2008
-2009
-2010
-2011
-2012
-2013
-2014
-2015
-2016
-2017
-2018
-2019
-2020
-2021
-2022
-2023
-2024
-2025
-2026
-2027
-2028
-2029
-2030
-2031
-2032
-2033
-2034
-2035
-2036
-2037
-2038
-2039
-2040
-2041
-2042
-2043
-2044
-2045
-2046
-2047
-2048
-2049
-2050
-2051
-2052
-2053
-2054
-2055
-2056
-2057
-2058
-2059
-2060
-2061
-2062
-2063
-2064
-2065
-2066
-2067
-2068
-2069
-2070
-2071
-2072
-2073
-2074
-2075
-2076
-2077
-2078
-2079
-2080
-2081
-2082
-2083
-2084
-2085
-2086
-2087
-2088
-2089
-2090
-2091
-2092
-2093
-2094
-2095
-2096
-2097
-2098
-2099
-2100
-2101
-2102
-2103
-2104
-2105
-2106
-2107
-2108
-2109
-2110
-2111
-2112
-2113
-2114
-2115
-2116
-2117
-2118
-2119
-2120
-2121
-2122
-2123
-2124
-2125
-2126
-2127
-2128
-2129
-2130
-2131
-2132
-2133
-2134
-2135
-2136
-2137
-2138
-2139
-2140
-2141
-2142
-2143
-2144
-2145
-2146
-2147
-2148
-2149
-2150
-2151
-2152
-2153
-2154
-2155
-2156
-2157
-2158
-2159
-2160
-2161
-2162
-2163
-2164
-2165
-2166
-2167
-2168
-2169
-2170
-2171
-2172
-2173
-2174
-2175
-2176
-2177
// *****************************************************************************
+
  1
+  2
+  3
+  4
+  5
+  6
+  7
+  8
+  9
+ 10
+ 11
+ 12
+ 13
+ 14
+ 15
+ 16
+ 17
+ 18
+ 19
+ 20
+ 21
+ 22
+ 23
+ 24
+ 25
+ 26
+ 27
+ 28
+ 29
+ 30
+ 31
+ 32
+ 33
+ 34
+ 35
+ 36
+ 37
+ 38
+ 39
+ 40
+ 41
+ 42
+ 43
+ 44
+ 45
+ 46
+ 47
+ 48
+ 49
+ 50
+ 51
+ 52
+ 53
+ 54
+ 55
+ 56
+ 57
+ 58
+ 59
+ 60
+ 61
+ 62
+ 63
+ 64
+ 65
+ 66
+ 67
+ 68
+ 69
+ 70
+ 71
+ 72
+ 73
+ 74
+ 75
+ 76
+ 77
+ 78
+ 79
+ 80
+ 81
+ 82
+ 83
+ 84
+ 85
+ 86
+ 87
+ 88
+ 89
+ 90
+ 91
+ 92
+ 93
+ 94
+ 95
+ 96
+ 97
+ 98
+ 99
+100
+101
+102
+103
+104
+105
+106
+107
+108
+109
+110
+111
+112
+113
+114
+115
+116
+117
+118
+119
+120
+121
+122
+123
+124
+125
+126
+127
+128
+129
+130
+131
+132
+133
+134
+135
+136
+137
+138
+139
+140
+141
+142
+143
+144
+145
+146
+147
+148
+149
+150
+151
+152
+153
+154
+155
+156
+157
+158
+159
+160
+161
+162
+163
+164
+165
+166
+167
+168
+169
+170
+171
+172
+173
+174
+175
+176
+177
+178
+179
+180
+181
+182
+183
+184
+185
+186
+187
+188
+189
+190
+191
+192
+193
+194
+195
+196
+197
// *****************************************************************************
 /*!
-  \file      src/Inciter/Refiner.cpp
+  \file      src/PDE/MultiMat/Problem/BoxInitialization.hpp
   \copyright 2012-2015 J. Bakosi,
              2016-2018 Los Alamos National Security, LLC.,
              2019-2021 Triad National Security, LLC.
              All rights reserved. See the LICENSE file for details.
-  \brief     Mesh refiner for interfacing the mesh refinement library
-  \see       Refiner.h for more info.
-*/
-// *****************************************************************************
-
-#include <vector>
-#include <algorithm>
+  \brief     User-defined box initialization
+  \details   This file defines functions for initializing solutions for
+    compressible multi-material equations inside the user-defined box.
+*/
+// *****************************************************************************
+#ifndef MultiMatBoxInitialization_h
+#define MultiMatBoxInitialization_h
 
-#include "Refiner.hpp"
-#include "Reorder.hpp"
-#include "AMR/mesh_adapter.hpp"
-#include "AMR/Error.hpp"
-#include "Inciter/InputDeck/InputDeck.hpp"
-#include "CGPDE.hpp"
-#include "DGPDE.hpp"
-#include "FVPDE.hpp"
-#include "DerivedData.hpp"
-#include "UnsMesh.hpp"
-#include "Centering.hpp"
-#include "Around.hpp"
-#include "Sorter.hpp"
-#include "Discretization.hpp"
-
-namespace inciter {
-
-extern ctr::InputDeck g_inputdeck;
-extern ctr::InputDeck g_inputdeck_defaults;
-extern std::vector< CGPDE > g_cgpde;
-extern std::vector< DGPDE > g_dgpde;
-extern std::vector< FVPDE > g_fvpde;
-
-} // inciter::
-
-using inciter::Refiner;
-
-Refiner::Refiner( std::size_t meshid,
-                  const CProxy_Transporter& transporter,
-                  const CProxy_Sorter& sorter,
-                  const tk::CProxy_MeshWriter& meshwriter,
-                  const std::vector< Scheme >& scheme,
-                  const tk::RefinerCallback& cbr,
-                  const tk::SorterCallback& cbs,
-                  const std::vector< std::size_t >& ginpoel,
-                  const tk::UnsMesh::CoordMap& coordmap,
-                  const std::map< int, std::vector< std::size_t > >& bface,
-                  const std::vector< std::size_t >& triinpoel,
-                  const std::map< int, std::vector< std::size_t > >& bnode,
-                  const std::vector< std::size_t >& elemblid,
-                  int nchare ) :
-  m_meshid( meshid ),
-  m_ncit(0),
-  m_host( transporter ),
-  m_sorter( sorter ),
-  m_meshwriter( meshwriter ),
-  m_scheme( scheme ),
-  m_cbr( cbr ),
-  m_cbs( cbs ),
-  m_ginpoel( ginpoel ),
-  m_el( tk::global2local( ginpoel ) ),     // fills m_inpoel, m_gid, m_lid
-  m_coordmap( coordmap ),
-  m_coord( flatcoord(coordmap) ),
-  m_bface( bface ),
-  m_bnode( bnode ),
-  m_triinpoel( triinpoel ),
-  m_elemblockid(),
-  m_nchare( nchare ),
-  m_mode( RefMode::T0REF ),
-  m_initref( g_inputdeck.get< tag::amr, tag::initial >() ),
-  m_ninitref( g_inputdeck.get< tag::amr, tag::initial >().size() ),
-  m_refiner( g_inputdeck.get< tag::amr, tag::maxlevels >(), m_inpoel ),
-  m_nref( 0 ),
-  m_nbnd( 0 ),
-  m_extra( 0 ),
-  m_ch(),
-  m_edgech(),
-  m_chedge(),
-  m_localEdgeData(),
-  m_remoteEdgeData(),
-  m_nodeCommMap(),
-  m_oldTets(),
-  m_addedNodes(),
-  m_addedTets(),
-  m_removedNodes(),
-  m_amrNodeMap(),
-  m_oldntets( 0 ),
-  m_coarseBndFaces(),
-  m_coarseBndNodes(),
-  m_coarseBlkElems(),
-  m_rid( m_coord[0].size() ),
-//  m_oldrid(),
-  m_lref( m_rid.size() ),
-//  m_oldparent(),
-  m_writeCallback(),
-  m_outref_ginpoel(),
-  m_outref_el(),
-  m_outref_coord(),
-  m_outref_addedNodes(),
-  m_outref_addedTets(),
-  m_outref_nodeCommMap(),
-  m_outref_bface(),
-  m_outref_bnode(),
-  m_outref_triinpoel()
-// *****************************************************************************
-//  Constructor
-//! \param[in] meshid Mesh ID
-//! \param[in] transporter Transporter (host) proxy
-//! \param[in] sorter Mesh reordering (sorter) proxy
-//! \param[in] meshwriter Mesh writer proxy
-//! \param[in] scheme Discretization schemes (one per mesh)
-//! \param[in] cbr Charm++ callbacks for Refiner
-//! \param[in] cbs Charm++ callbacks for Sorter
-//! \param[in] ginpoel Mesh connectivity (this chare) using global node IDs
-//! \param[in] coordmap Mesh node coordinates (this chare) for global node IDs
-//! \param[in] bface File-internal elem ids of side sets
-//! \param[in] triinpoel Triangle face connectivity with global IDs
-//! \param[in] bnode Node lists of side sets
-//! \param[in] elemblid Mesh block ids associated to local tet ids
-//! \param[in] nchare Total number of refiner chares (chare array elements)
-// *****************************************************************************
-{
-  Assert( !m_ginpoel.empty(), "No elements assigned to refiner chare" );
-  Assert( tk::positiveJacobians( m_inpoel, m_coord ),
-          "Input mesh to Refiner Jacobian non-positive" );
-  Assert( !tk::leakyPartition(
-            tk::genEsuelTet( m_inpoel, tk::genEsup(m_inpoel,4) ),
-            m_inpoel, m_coord ),
-          "Input mesh to Refiner leaky" );
-
-  // Construct data structure assigning sets of element ids to mesh blocks
-  for (std::size_t ie=0; ie<elemblid.size(); ++ie) {
-    m_elemblockid[elemblid[ie]].insert(ie);
-  }
-
-  #if not defined(__INTEL_COMPILER) || defined(NDEBUG)
-  // The above ifdef skips running the conformity test with the intel compiler
-  // in debug mode only. This is necessary because in tk::conforming(), filling
-  // up the map can fail with some meshes (only in parallel), e.g., tube.exo,
-  // used by some regression tests, due to the intel compiler generating some
-  // garbage incorrect code - only in debug, only in parallel, only with that
-  // mesh.
-  Assert( tk::conforming( m_inpoel, m_coord, true, m_rid ),
-          "Input mesh to Refiner not conforming" );
-  #endif
-
-  // Generate local -> refiner lib node id map and its inverse
-  libmap();
-
-  // Reverse initial mesh refinement type list (will pop from back)
-  std::reverse( begin(m_initref), end(m_initref) );
-
-  // Generate boundary data structures for coarse mesh
-  coarseMesh();
+#include "Fields.hpp"
+#include "EoS/EOS.hpp"
+#include "ContainerUtil.hpp"
+#include "MultiMat/MultiMatIndexing.hpp"
+
+namespace inciter {
+
+using ncomp_t = tk::ncomp_t;
+
+template< class B >
+void initializeBox( const std::vector< EOS >& mat_blk,
+                    tk::real V_ex,
+                    tk::real t,
+                    const B& b,
+                    tk::real bgpreic,
+                    tk::real bgtempic,
+                    std::vector< tk::real >& s )
+// *****************************************************************************
+// Set the solution in the user-defined IC box/mesh block
+//! \tparam B IC-block type to operate, ctr::box, or ctr::meshblock
+//! \param[in] V_ex Exact box volume
+//! \param[in] t Physical time
+//! \param[in] b IC box configuration to use
+//! \param[in] bgpreic Background pressure user input
+//! \param[in] bgtempic Background temperature user input
+//! \param[in,out] s Solution vector that is set to box ICs
+//! \details This function sets the fluid density and total specific energy
+//!   within a box initial condition, configured by the user. If the user
+//!   is specified a box where mass is specified, we also assume here that
+//!   internal energy content (energy per unit volume) is also
+//!   specified. Specific internal energy (energy per unit mass) is then
+//!   computed here (and added to the kinetic energy) from the internal
+//!   energy per unit volume by multiplying it with the total box volume
+//!   and dividing it by the total mass of the material in the box.
+//!   Example (SI) units of the quantities involved:
+//!    * internal energy content (energy per unit volume): J/m^3
+//!    * specific energy (internal energy per unit mass): J/kg
+// *****************************************************************************
+{
+  auto nmat = g_inputdeck.get< tag::multimat, tag::nmat >();
+
+  const auto& solidx = g_inputdeck.get< tag::matidxmap, tag::solidx >();
+
+  const auto& initiate = b.template get< tag::initiate >();
+
+  // get material id in box (offset by 1, since input deck uses 1-based ids)
+  std::size_t boxmatid = b.template get< tag::materialid >() - 1;
+  const auto& boxvel = b.template get< tag::velocity >();
+  auto boxpre = b.template get< tag::pressure >();
+  auto boxene = b.template get< tag::energy >();
+  auto boxtemp = b.template get< tag::temperature >();
+  auto boxmas = b.template get< tag::mass >();
+  auto boxenc = b.template get< tag::energy_content >();
+
+  auto alphamin = 1.0e-12;
+
+  // [I] Compute the states inside the IC box/block based on the type of user
+  // input.
+
+  // material volume fractions
+  for (std::size_t k=0; k<nmat; ++k) {
+    if (k == boxmatid) {
+      s[volfracIdx(nmat,k)] = 1.0 - (static_cast< tk::real >(nmat-1))*alphamin;
+    }
+    else {
+      s[volfracIdx(nmat,k)] = alphamin;
+    }
+  }
+  // material states (density, pressure, velocity)
+  tk::real u = 0.0, v = 0.0, w = 0.0, spi(0.0), pr(0.0), tmp(0.0), rbulk(0.0);
+  std::vector< tk::real > rhok(nmat, 0.0);
+  // 1. User-specified mass, specific energy (J/m^3) and volume of box
+  if (boxmas > 0.0) {
+    if (boxenc <= 1e-12) Throw( "Box energy content must be nonzero" );<--- If condition 'boxenc<=1e-12' is true, the function will return/exit
+    // determine density and energy of material in the box
+    rhok[boxmatid] = boxmas / V_ex;
+    spi = boxenc / rhok[boxmatid];
+
+    // Determine pressure and temperature
+    auto boxmat_vf = s[volfracIdx(nmat,boxmatid)];
+
+    // Since initiate type 'linear' assigns the background IC values to all
+    // nodes within a box at initialization (followed by adding a time-dependent
+    // energy source term representing a propagating wave-front), the pressure
+    // in the box needs to be set to background pressure.
+    if (initiate == ctr::InitiateType::LINEAR && t < 1e-12) {
+      if (boxmas <= 1e-12 || boxenc <= 1e-12 || bgpreic <= 1e-12 ||<--- Testing identical condition 'boxenc<=1e-12'
+        bgtempic <= 1e-12)
+        Throw("Box mass, energy content, background pressure and background "
+          "temperature must be specified for IC with linear propagating source");
+
+      pr = bgpreic;
+      auto te = mat_blk[boxmatid].compute< EOS::totalenergy >(
+        rhok[boxmatid], u, v, w, pr);
+      tmp = mat_blk[boxmatid].compute< EOS::temperature >(
+        boxmat_vf*rhok[boxmatid], u, v, w, boxmat_vf*te, boxmat_vf );
+
+      // if the above density and pressure lead to an invalid thermodynamic
+      // state (negative temperature/energy), change temperature to background
+      // temperature and use corresponding density.
+      if (tmp < 0.0 || te < 0.0) {
+        tmp = bgtempic;
+        rhok[boxmatid] = mat_blk[boxmatid].compute< EOS::density >(pr, tmp);
+        spi = boxenc / rhok[boxmatid];
+      }
+    }
+    // For initiate type 'impulse', pressure and temperature are determined from
+    // energy content that needs to be dumped into the box at IC.
+    else if (initiate == ctr::InitiateType::IMPULSE) {
+      pr = mat_blk[boxmatid].compute< EOS::pressure >(
+        boxmat_vf*rhok[boxmatid], u, v, w, boxmat_vf*rhok[boxmatid]*spi,
+        boxmat_vf, boxmatid );
+      tmp = mat_blk[boxmatid].compute< EOS::temperature >(
+        boxmat_vf*rhok[boxmatid], u, v, w, boxmat_vf*rhok[boxmatid]*spi,
+        boxmat_vf );
+    }
+    else Throw( "IC box initiate type not implemented for multimat" );
+
+    // find density of trace material quantities in the box based on pressure
+    for (std::size_t k=0; k<nmat; ++k) {
+      if (k != boxmatid) {
+        rhok[k] = mat_blk[k].compute< EOS::density >(pr, tmp);
+      }
+    }
+  }
+  // 2. User-specified temperature, pressure and velocity in box
+  else {
+    for (std::size_t k=0; k<nmat; ++k) {
+      rhok[k] = mat_blk[k].compute< EOS::density >(boxpre, boxtemp);
+    }
+    if (boxvel.size() == 3) {
+      u = boxvel[0];
+      v = boxvel[1];
+      w = boxvel[2];
+    }
+    if (boxpre > 0.0) {
+      pr = boxpre;
+    }
+    if (boxene > 0.0) {
+      Throw("IC-box with specified energy not set up for multimat");
+    }
+  }
+  // bulk density
+  for (std::size_t k=0; k<nmat; ++k) rbulk += s[volfracIdx(nmat,k)]*rhok[k];
 
-  // If initial mesh refinement is configured, start initial mesh refinement.
-  // See also tk::grm::check_amr_errors in Control/Inciter/InputDeck/Ggrammar.h.
-  if (g_inputdeck.get< tag::amr, tag::t0ref >() && m_ninitref > 0)
-    t0ref();
-  else
-    endt0ref();
-}
-
-void
-Refiner::libmap()
-// *****************************************************************************
-// (Re-)generate local -> refiner lib node id map and its inverse
-// *****************************************************************************
-{
-  // Fill initial (matching) mapping between local and refiner node ids
-  std::iota( begin(m_rid), end(m_rid), 0 );
-
-  // Fill in inverse, mapping refiner to local node ids
-  std::size_t i = 0;
-  for (auto r : m_rid) m_lref[r] = i++;
-}
-
-void
-Refiner::coarseMesh()
-// *****************************************************************************
-// (Re-)generate side set and block data structures for coarse mesh
-// *****************************************************************************
-{
-  // Generate unique set of faces for each side set of the input (coarsest) mesh
-  m_coarseBndFaces.clear();
-  for (const auto& [ setid, faceids ] : m_bface) {
-    auto& faces = m_coarseBndFaces[ setid ];
-    for (auto f : faceids) {
-      faces.insert(
-        {{{ m_triinpoel[f*3+0], m_triinpoel[f*3+1], m_triinpoel[f*3+2] }}} );
-    }
-  }
-
-  // Generate unique set of nodes for each side set of the input (coarsest) mesh
-  m_coarseBndNodes.clear();
-  for (const auto& [ setid, nodes ] : m_bnode) {
-    m_coarseBndNodes[ setid ].insert( begin(nodes), end(nodes) );
-  }
-
-  // Generate set of elements for each mesh block of the input (coarsest) mesh
-  m_coarseBlkElems.clear();
-  for (const auto& [blid, elids] : m_elemblockid) {
-    for (auto ie : elids) {
-      m_coarseBlkElems[blid].insert( {{{m_inpoel[ie*4+0], m_inpoel[ie*4+1],
-        m_inpoel[ie*4+2], m_inpoel[ie*4+3]}}} );
-    }
-  }
-}
-
-void
-Refiner::sendProxy()
-// *****************************************************************************
-// Send Refiner proxy to Discretization objects
-//! \details This should be called when bound Discretization chare array
-//!   elements have already been created.
-// *****************************************************************************
-{
-  // Make sure (bound) Discretization chare is already created and accessible
-  Assert( m_scheme[m_meshid].disc()[thisIndex].ckLocal() != nullptr,
-          "About to dereference nullptr" );
-
-  // Pass Refiner Charm++ chare proxy to fellow (bound) Discretization object
-  m_scheme[m_meshid].disc()[thisIndex].ckLocal()->setRefiner( thisProxy );
-}
-
-void
-Refiner::reorder()
-// *****************************************************************************
-// Query Sorter and update local mesh with the reordered one
-// *****************************************************************************
-{
-  m_sorter[thisIndex].ckLocal()->
-    mesh( m_ginpoel, m_coordmap, m_triinpoel, m_bnode );
-
-  // Update local mesh data based on data just received from Sorter
-  m_el = tk::global2local( m_ginpoel );     // fills m_inpoel, m_gid, m_lid
-  m_coord = flatcoord( m_coordmap );
-
-  // Re-generate boundary data structures for coarse mesh
-  coarseMesh();
-
-  // WARNING: This re-creates the AMR lib which is probably not what we
-  // ultimately want, beacuse this deletes its history recorded during initial
-  // (t<0) refinement. However, this appears to correctly update the local mesh
-  // based on the reordered one (from Sorter) at least when t0ref is off.
-  m_refiner = AMR::mesh_adapter_t(
-    g_inputdeck.get< tag::amr, tag::maxlevels >(), m_inpoel );
-}
-
-tk::UnsMesh::Coords
-Refiner::flatcoord( const tk::UnsMesh::CoordMap& coordmap )
-// *****************************************************************************
-// Generate flat coordinate data from coordinate map
-//! \param[in] coordmap Coordinates associated to global node IDs of mesh chunk
-//! \return Flat coordinate data
-// *****************************************************************************
-{
-  tk::UnsMesh::Coords coord;
-
-  // Convert node coordinates associated to global node IDs to a flat vector
-  auto npoin = coordmap.size();
-  Assert( m_gid.size() == npoin, "Size mismatch" );
-  coord[0].resize( npoin );
-  coord[1].resize( npoin );
-  coord[2].resize( npoin );
-  for (const auto& [ gid, coords ] : coordmap) {
-    auto i = tk::cref_find( m_lid, gid );
-    Assert( i < npoin, "Indexing out of coordinate map" );
-    coord[0][i] = coords[0];
-    coord[1][i] = coords[1];
-    coord[2][i] = coords[2];
-  }
-
-  return coord;
-}
-
-void
-Refiner::dtref( const std::map< int, std::vector< std::size_t > >& bface,
-                const std::map< int, std::vector< std::size_t > >& bnode,
-                const std::vector< std::size_t >& triinpoel )
-// *****************************************************************************
-// Start mesh refinement (during time stepping, t>0)
-//! \param[in] bface Boundary-faces mapped to side set ids
-//! \param[in] bnode Boundary-node lists mapped to side set ids
-//! \param[in] triinpoel Boundary-face connectivity
-// *****************************************************************************
-{
-  m_mode = RefMode::DTREF;
-
-  // Update boundary node lists
-  m_bface = bface;
-  m_bnode = bnode;
-  m_triinpoel = tk::remap(triinpoel, m_gid);
-
-  start();
-}
-
-void
-Refiner::outref( const std::map< int, std::vector< std::size_t > >& bface,
-                 const std::map< int, std::vector< std::size_t > >& bnode,
-                 const std::vector< std::size_t >& triinpoel,
-                 CkCallback c,
-                 RefMode mode )
-// *****************************************************************************
-// Start mesh refinement (for field output)
-//! \param[in] bface Boundary-faces mapped to side set ids
-//! \param[in] bnode Boundary-node lists mapped to side set ids
-//! \param[in] triinpoel Boundary-face connectivity
-//! \param[in] c Function to continue with after the writing field output
-//! \param[in] mode Refinement mode
-// *****************************************************************************
-{
-  m_mode = mode;
-
-  m_writeCallback = c;
-
-  // Update boundary node lists
-  m_bface = bface;
-  m_bnode = bnode;
-  m_triinpoel = triinpoel;
-
-  start();
-}
-
-void
-Refiner::t0ref()
-// *****************************************************************************
-// Output mesh to file before a new step mesh refinement
-// *****************************************************************************
-{
-  Assert( m_ninitref > 0, "No initial mesh refinement steps configured" );
-  // Output initial mesh to file
-  auto l = m_ninitref - m_initref.size();  // num initref steps completed
-  auto t0 = g_inputdeck.get< tag::t0 >();
-  if (l == 0) {
-    writeMesh( "t0ref", l, t0-1.0,
-      CkCallback( CkIndex_Refiner::start(), thisProxy[thisIndex] ) );
-  } else {
-    start();
-  }
-}
-
-void
-Refiner::start()
-// *****************************************************************************
-//  Start new step of mesh refinement
-// *****************************************************************************
-{
-  m_extra = 0;
-  m_ch.clear();
-  m_remoteEdgeData.clear();
-  m_remoteEdges.clear();
-
-  updateEdgeData();
-
-  // Generate and communicate boundary edges
-  bndEdges();
-}
-
-void
-Refiner::bndEdges()
-// *****************************************************************************
-// Generate boundary edges and send them to all chares
-//! \details Extract edges on the boundary only. The boundary edges (shared by
-//!   multiple chares) will be agreed on a refinement that yields a conforming
-//!   mesh across chares boundaries.
-// *****************************************************************************
-{
-  // Compute the number of edges (chunksize) a chare will respond to when
-  // computing shared edges
-  auto N = static_cast< std::size_t >( m_nchare );
-  std::size_t chunksize = std::numeric_limits< std::size_t >::max() / N;<--- Variable 'chunksize' is assigned a value that is never used.
-
-  // Generate boundary edges of our mesh chunk
-  std::unordered_map< int, EdgeSet > chbedges;
-  auto esup = tk::genEsup( m_inpoel, 4 );         // elements surrounding points
-  auto esuel = tk::genEsuelTet( m_inpoel, esup ); // elems surrounding elements
-  for (std::size_t e=0; e<esuel.size()/4; ++e) {
-    auto mark = e*4;
-    for (std::size_t f=0; f<4; ++f) {
-      if (esuel[mark+f] == -1) {
-        auto A = m_ginpoel[ mark+tk::lpofa[f][0] ];
-        auto B = m_ginpoel[ mark+tk::lpofa[f][1] ];<--- Variable 'B' is assigned a value that is never used.
-        auto C = m_ginpoel[ mark+tk::lpofa[f][2] ];<--- Variable 'C' is assigned a value that is never used.
-        Assert( m_lid.find( A ) != end(m_lid), "Local node ID not found" );
-        Assert( m_lid.find( B ) != end(m_lid), "Local node ID not found" );
-        Assert( m_lid.find( C ) != end(m_lid), "Local node ID not found" );
-        // assign edges to bins a single chare will respond to when computing
-        // shared edges
-        auto bin = A / chunksize;
-        Assert( bin < N, "Will index out of number of chares" );
-        chbedges[ static_cast<int>(bin) ].insert( {A,B} );
-        bin = B / chunksize;
-        Assert( bin < N, "Will index out of number of chares" );
-        chbedges[ static_cast<int>(bin) ].insert( {B,C} );
-        bin = C / chunksize;
-        Assert( bin < N, "Will index out of number of chares" );
-        chbedges[ static_cast<int>(bin) ].insert( {C,A} );
-      }
-    }
-  }
-
-  // Send edges in bins to chares that will compute shared edges
-  m_nbnd = chbedges.size();
-  if (m_nbnd == 0)
-    contribute( sizeof(std::size_t), &m_meshid, CkReduction::nop,
-                m_cbr.get< tag::queried >() );
-  else
-    for (const auto& [ targetchare, bndedges ] : chbedges)
-      thisProxy[ targetchare ].query( thisIndex, bndedges );
-}
-
-void
-Refiner::query( int fromch, const EdgeSet& edges )
-// *****************************************************************************
-// Incoming query for a list boundary edges for which this chare compiles
-// shared edges
-//! \param[in] fromch Sender chare ID
-//! \param[in] edges Chare-boundary edge list from another chare
-// *****************************************************************************
-{
-  // Store incoming edges in edge->chare and its inverse, chare->edge, maps
-  for (const auto& e : edges) m_edgech[ e ].push_back( fromch );
-  m_chedge[ fromch ].insert( begin(edges), end(edges) );
-  // Report back to chare message received from
-  thisProxy[ fromch ].recvquery();
-}
-
-void
-Refiner::recvquery()
-// *****************************************************************************
-// Receive receipt of boundary edge lists to query
-// *****************************************************************************
-{
-  if (--m_nbnd == 0)
-    contribute( sizeof(std::size_t), &m_meshid, CkReduction::nop,
-                m_cbr.get< tag::queried >() );
-}
-
-void
-Refiner::response()
-// *****************************************************************************
-//  Respond to boundary edge list queries
-// *****************************************************************************
-{
-  std::unordered_map< int, std::vector< int > > exp;
-
-  // Compute shared edges whose chare ids will be sent back to querying chares
-  for (const auto& [ neighborchare, bndedges ] : m_chedge) {
-    auto& e = exp[ neighborchare ];
-    for (const auto& ed : bndedges)
-      for (auto d : tk::cref_find(m_edgech,ed))
-        if (d != neighborchare)
-          e.push_back( d );<--- Consider using std::copy_if algorithm instead of a raw loop.
-  }
-
-  // Send chare ids of shared edges to chares that issued a query to us. Shared
-  // boundary edges assigned to chare ids sharing the boundary edge were
-  // computed above for those chares that queried this map from us. These
-  // boundary edges form a distributed table and we only work on a chunk of it.
-  // Note that we only send data back to those chares that have queried us. The
-  // receiving sides do not know in advance if they receive messages or not.
-  // Completion is detected by having the receiver respond back and counting
-  // the responses on the sender side, i.e., this chare.
-  m_nbnd = exp.size();
-  if (m_nbnd == 0)
-    contribute( sizeof(std::size_t), &m_meshid, CkReduction::nop,
-                m_cbr.get< tag::responded >() );
-  else
-    for (const auto& [ targetchare, bndedges ] : exp)
-      thisProxy[ targetchare ].bnd( thisIndex, bndedges );
-}
-
-void
-Refiner::bnd( int fromch, const std::vector< int >& chares )
-// *****************************************************************************
-// Receive shared boundary edges for our mesh chunk
-//! \param[in] fromch Sender chare ID
-//! \param[in] chares Chare ids we share edges with
-// *****************************************************************************
-{
-  // Store chare ids we share edges with
-  m_ch.insert( begin(chares), end(chares) );
-
-  // Report back to chare message received from
-  thisProxy[ fromch ].recvbnd();
-}
-
-void
-Refiner::recvbnd()
-// *****************************************************************************
-// Receive receipt of shared boundary edges
-// *****************************************************************************
-{
-  if (--m_nbnd == 0)
-    contribute( sizeof(std::size_t), &m_meshid, CkReduction::nop,
-                m_cbr.get< tag::responded >() );
-}
-
-void
-Refiner::refine()
-// *****************************************************************************
-//  Do a single step of mesh refinement (really, only tag edges)
-//! \details During initial (t<0, t0ref) mesh refinement, this is a single step
-//!   in a potentially multiple-entry list of initial adaptive mesh refinement
-//!   steps. Distribution of the chare-boundary edges must have preceded this
-//!   step, so that boundary edges (shared by multiple chares) can agree on a
-//!   refinement that yields a conforming mesh across chare boundaries.
-//!
-//!   During-timestepping (t>0, dtref) mesh refinement this is called once, as
-//!   we only do a single step during time stepping.
-//!
-//!   During field-output (outref) mesh refinement, this may be called multiple
-//!   times, depending the number of refinement levels needed for the field
-//!   output.
-// *****************************************************************************
-{
-  // Free memory used for computing shared boundary edges
-  tk::destroy( m_edgech );
-  tk::destroy( m_chedge );
-
-  // Perform leak test on old mesh
-  Assert( !tk::leakyPartition(
-            tk::genEsuelTet( m_inpoel, tk::genEsup(m_inpoel,4) ),
-            m_inpoel, m_coord ),
-          "Mesh partition before refinement leaky" );
-
-  if (m_mode == RefMode::T0REF) {
-
-    // Refine mesh based on next initial refinement type
-    if (!m_initref.empty()) {
-      auto r = m_initref.back();    // consume (reversed) list from its back
-      if (r == ctr::AMRInitialType::UNIFORM)
-        uniformRefine();
-      else if (r == ctr::AMRInitialType::UNIFORM_DEREFINE)
-        uniformDeRefine();
-      else if (r == ctr::AMRInitialType::INITIAL_CONDITIONS)
-        errorRefine();
-      else if (r == ctr::AMRInitialType::COORDINATES)
-        coordRefine();
-      else if (r == ctr::AMRInitialType::EDGELIST)
-        edgelistRefine();
-      else Throw( "Initial AMR type not implemented" );
-    }
-
-  } else if (m_mode == RefMode::DTREF) {
-
-    if (g_inputdeck.get< tag::amr, tag::dtref_uniform >())
-      uniformRefine();
-    else
-      errorRefine();
-
-  } else if (m_mode == RefMode::OUTREF) {
-
-    uniformRefine();
-
-  } else if (m_mode == RefMode::OUTDEREF) {
-
-    uniformDeRefine();
-
-  } else Throw( "RefMode not implemented" );
-
-  // Communicate extra edges
-  comExtra();
-}
-
-void
-Refiner::comExtra()
-// *****************************************************************************
-// Communicate extra edges along chare boundaries
-// *****************************************************************************
-{
-  // Export extra added nodes on our mesh chunk boundary to other chares
-  if (m_ch.empty()) {
-    correctref();
-  } else {
-    for (auto c : m_ch) {  // for all chares we share at least an edge with
-      thisProxy[c].addRefBndEdges(thisIndex, m_localEdgeData, m_intermediates);
-    }
-  }
-}
-
-void
-Refiner::addRefBndEdges(
-  int fromch,
-  const AMR::EdgeData& ed,
-  const std::unordered_set< std::size_t >& intermediates )
-// *****************************************************************************
-//! Receive edges on our chare boundary from other chares
-//! \param[in] fromch Chare call coming from
-//! \param[in] ed Edges on chare boundary
-//! \param[in] intermediates Intermediate nodes
-//! \details Other than update remoteEdge data, this function also updates
-//!   locking information for such edges whos nodes are marked as intermediate
-//!   by neighboring chares.
-// *****************************************************************************
-{
-  // Save/augment buffers of edge data for each sender chare
-  auto& red = m_remoteEdgeData[ fromch ];
-  auto& re = m_remoteEdges[ fromch ];
-  using edge_data_t = std::tuple< Edge, int, int, AMR::Edge_Lock_Case >;
-  for (const auto& [ edge, data ] : ed) {
-    red.push_back( edge_data_t{ edge, std::get<0>(data), std::get<1>(data),
-      std::get<2>(data) } );
-    re.push_back( edge );
-  }
-
-  // Add intermediates to mesh refiner lib
-  // needs to be done only when mesh has been actually updated, i.e. first iter
-  if (m_ncit == 0) {
-    auto esup = tk::genEsup( m_inpoel, 4 );
-    auto psup = tk::genPsup( m_inpoel, 4, esup );
-    for (const auto g : intermediates) {
-      auto l = m_lid.find( g ); // convert to local node ids
-      if (l != end(m_lid)) {
-        // lock all edges connected to intermediate node
-        auto p = l->second;
-        for (auto q : tk::Around(psup,p)) {
-          AMR::edge_t e(m_rid[p], m_rid[q]);
-          auto& refedge = m_refiner.tet_store.edge_store.get(e);
-          if (refedge.lock_case == AMR::Edge_Lock_Case::unlocked) {
-            refedge.lock_case = AMR::Edge_Lock_Case::temporary; //intermediate;
-            refedge.needs_refining = 0;
-          }
-        }
-      }
-    }
-  }
-
-  // Heard from every worker we share at least a single edge with
-  if (++m_nref == m_ch.size()) {
-    m_nref = 0;
-
-    updateBndEdgeData();
-
-    std::vector< std::size_t > meshdata{ m_meshid };
-    contribute( meshdata, CkReduction::max_ulong,
-                m_cbr.get< tag::compatibility >() );
-  }
-}
-
-void
-Refiner::correctref()
-// *****************************************************************************
-//  Correct extra edges to arrive at conforming mesh across chare boundaries
-//! \details This function is called repeatedly until there is not a a single
-//!    edge that needs correction for the whole distributed problem to arrive at
-//!    a conforming mesh across chare boundaries during a mesh refinement step.
-// *****************************************************************************
-{
-  auto unlocked = AMR::Edge_Lock_Case::unlocked;
-
-  // Storage for edge data that need correction to yield a conforming mesh
-  AMR::EdgeData extra;
-  std::size_t neigh_extra(0);
-
-  // Vars for debugging purposes
-  std::size_t nlocked(0);<--- Variable 'nlocked' is assigned a value that is never used.
-  std::array< std::size_t, 4 > ncorrcase{{0,0,0,0}};
-
-  // loop through all edges shared with other chares
-  for (const auto& [ neighborchare, edgedata ] : m_remoteEdgeData) {
-    for (const auto& [edge,remote_needs_refining,remote_needs_derefining,
-      remote_lock_case] : edgedata) {
-      // find local data of remote edge
-      auto it = m_localEdgeData.find( edge );
-      if (it != end(m_localEdgeData)) {
-        auto& local = it->second;
-        auto& local_needs_refining = std::get<0>(local);
-        auto& local_needs_derefining = std::get<1>(local);
-        auto& local_lock_case = std::get<2>(local);
-
-        auto local_needs_refining_orig = local_needs_refining;<--- Variable 'local_needs_refining_orig' is assigned a value that is never used.
-        auto local_needs_derefining_orig = local_needs_derefining;<--- Variable 'local_needs_derefining_orig' is assigned a value that is never used.
-        auto local_lock_case_orig = local_lock_case;<--- Variable 'local_lock_case_orig' is assigned a value that is never used.
-
-        Assert( !(local_lock_case > unlocked && local_needs_refining),
-                "Invalid local edge: locked & needs refining" );
-        Assert( !(remote_lock_case > unlocked && remote_needs_refining),
-                "Invalid remote edge: locked & needs refining" );
-        Assert( !(local_needs_derefining == 1 && local_needs_refining > 0),
-                "Invalid local edge: needs refining and derefining" );
-
-        // The parallel compatibility (par-compat) algorithm
-
-        // compute lock from local and remote locks as most restrictive
-        local_lock_case = std::max( local_lock_case, remote_lock_case );
-
-        if (local_lock_case > unlocked) {
-          local_needs_refining = 0;
-          if (local_needs_refining != local_needs_refining_orig ||
-            local_lock_case != local_lock_case_orig)
-            ++ncorrcase[0];
-        }
-
-        // Possible combinations of remote-local ref-deref decisions
-        // rows 1, 5, 9: no action needed.
-        // rows 4, 7, 8: no action on local-side; comm needed.
-        //
-        //    LOCAL          |        REMOTE    |  Result
-        // 1  d              |        d         |  d
-        // 2  d              |        -         |  -
-        // 3  d              |        r         |  r
-        // 4  -              |        d         |  -
-        // 5  -              |        -         |  -
-        // 6  -              |        r         |  r
-        // 7  r              |        d         |  r
-        // 8  r              |        -         |  r
-        // 9  r              |        r         |  r
-
-        // Rows 3, 6
-        // If remote wants to refine
-        if (remote_needs_refining == 1) {
-          if (local_lock_case == unlocked) {
-            local_needs_refining = 1;
-            local_needs_derefining = false;
-            if (local_needs_refining != local_needs_refining_orig ||
-              local_needs_derefining != local_needs_derefining_orig)
-              ++ncorrcase[1];
-          }
-          else {
-           ++nlocked;
-          }
-        }
-
-        // Row 2
-        // If remote neither wants to refine nor derefine
-        if (remote_needs_refining == 0 && remote_needs_derefining == false) {
-          local_needs_derefining = false;
-          if (local_needs_derefining != local_needs_derefining_orig)
-            ++ncorrcase[2];
-        }
-
-        // Row 1: special case
-        // If remote wants to deref-ref (either of 8:4, 8:2, 4:2)
-        // and local does not want to refine (neither pure ref nor deref-ref)
-        if (remote_needs_refining == 2 && local_needs_refining == 0) {
-          if (local_lock_case == unlocked) {
-            local_needs_refining = 1;
-            local_needs_derefining = false;
-            if (local_needs_refining != local_needs_refining_orig ||
-              local_needs_derefining != local_needs_derefining_orig)
-              ++ncorrcase[3];
-          }
-          else {
-            ++nlocked;<--- Variable 'nlocked' is assigned a value that is never used.
-          }
-        }
-
-        // Rows 4, 7, 8
-
-        // if the remote sent us data that makes us change our local state,
-        // e.g., local{-,0} + remote{r,0} -> local{r,0}, i.e., I changed my
-        // state I need to tell the world about it
-        if (local_lock_case != local_lock_case_orig ||
-            local_needs_refining != local_needs_refining_orig ||
-            local_needs_derefining != local_needs_derefining_orig)
-        {
-          auto l1 = tk::cref_find( m_lid, edge[0] );
-          auto l2 = tk::cref_find( m_lid, edge[1] );
-          Assert( l1 != l2, "Edge end-points local ids are the same" );
-          auto r1 = m_rid[ l1 ];
-          auto r2 = m_rid[ l2 ];
-          Assert( r1 != r2, "Edge end-points refiner ids are the same" );
-          //std::cout << thisIndex << ": " << r1 << ", " << r2 << std::endl;
-          //if (m_refiner.tet_store.edge_store.get(AMR::edge_t(r1,r2)).lock_case > local_lock_case) {
-          //  std::cout << thisIndex << ": edge " << r1 << "-" << r2 <<
-          //    "; prev=" << local_lock_case_orig <<
-          //    "; new=" << local_lock_case <<
-          //    "; amr-lib=" << m_refiner.tet_store.edge_store.get(AMR::edge_t(r1,r2)).lock_case <<
-          //    " | parcompatiter " << m_ncit << std::endl;
-          //}
-           extra[ {{ std::min(r1,r2), std::max(r1,r2) }} ] =
-             { local_needs_refining, local_needs_derefining, local_lock_case };
-        }
-        // or if the remote data is inconsistent with what I think, e.g.,
-        // local{r,0} + remote{-,0} -> local{r,0}, i.e., the remote does not
-        // yet agree, so another par-compat iteration will be pursued. but
-        // I do not have to locally run ref-compat.
-        else if (local_lock_case != remote_lock_case ||
-          local_needs_refining != remote_needs_refining ||
-          local_needs_derefining != remote_needs_derefining)
-        {
-          ++neigh_extra;
-        }
-      }
-    }
-  }
-
-  m_remoteEdgeData.clear();
-  m_extra = extra.size();
-  //std::cout << thisIndex << ": amr correction reqd for nedge: " << m_extra << std::endl;
-  //std::cout << thisIndex << ": amr correction reqd for neighbor edges: " << neigh_extra << std::endl;
-  //std::cout << thisIndex << ": edge counts by correction case: " << ncorrcase[0]
-  //  << ", " << ncorrcase[1] << ", " << ncorrcase[2] << ", " << ncorrcase[3] << std::endl;
-  //std::cout << thisIndex << ": locked edges that req corr: " << nlocked << std::endl;
-
-  if (!extra.empty()) {
-    //std::cout << thisIndex << ": redoing markings" << std::endl;
-    // Do refinement compatibility (ref-compat) for edges that need correction
-    m_refiner.mark_error_refinement_corr( extra );
-    ++m_ncit;
-    // Update our extra-edge store based on refiner
-    updateEdgeData();
-    m_remoteEdges.clear();
-  }
-  else if (neigh_extra == 0) {
-    m_ncit = 0;
-  }
-
-  // Aggregate number of extra edges that still need correction and some
-  // refinement/derefinement statistics
-  const auto& tet_store = m_refiner.tet_store;
-  std::vector< std::size_t >
-    m{ m_meshid,
-       m_extra,
-       tet_store.marked_refinements.size(),
-       tet_store.marked_derefinements.size(),
-       static_cast< std::underlying_type_t< RefMode > >( m_mode ) };
-  contribute( m, CkReduction::sum_ulong, m_cbr.get< tag::matched >() );
-}
-
-void
-Refiner::updateEdgeData()
-// *****************************************************************************
-// Query AMR lib and update our local store of edge data
-// *****************************************************************************
-{
-  m_localEdgeData.clear();
-  m_intermediates.clear();
-
-  // This currently takes ALL edges from the AMR lib, i.e., on the whole
-  // domain. We should eventually only collect edges here that are shared with
-  // other chares.
-  const auto& ref_edges = m_refiner.tet_store.edge_store.edges;
-  const auto& refinpoel = m_refiner.tet_store.get_active_inpoel();
-
-  for (std::size_t e=0; e<refinpoel.size()/4; ++e) {
-    auto A = refinpoel[e*4+0];
-    auto B = refinpoel[e*4+1];
-    auto C = refinpoel[e*4+2];
-    auto D = refinpoel[e*4+3];
-    std::array<Edge,6> edges{{ {{A,B}}, {{B,C}}, {{A,C}},
-                               {{A,D}}, {{B,D}}, {{C,D}} }};
-    for (const auto& ed : edges) {
-      auto ae = AMR::edge_t{{{ std::min(ed[0],ed[1]), std::max(ed[0],ed[1]) }}};
-      auto r = tk::cref_find( ref_edges, ae );
-      const auto ged = Edge{{ m_gid[ tk::cref_find( m_lref, ed[0] ) ],
-                              m_gid[ tk::cref_find( m_lref, ed[1] ) ] }};
-      m_localEdgeData[ ged ] = { r.needs_refining, r.needs_derefining,
-        r.lock_case };
-    }
-  }
-
-  // Build intermediates to send. This currently takes ALL intermediates from
-  // the AMR lib, i.e., on the whole domain. We should eventually only collect
-  // edges here that are shared with other chares.
-  for (const auto& r : m_refiner.tet_store.intermediate_list) {
-    m_intermediates.insert( m_gid[ tk::cref_find( m_lref, r ) ] );
-  }
-}
-
-void
-Refiner::updateBndEdgeData()
-// *****************************************************************************
-// Query AMR lib and update our local store of boundary edge data
-// *****************************************************************************
-{
-  // This currently takes ALL edges from the AMR lib, i.e., on the whole
-  // domain. We should eventually only collect edges here that are shared with
-  // other chares.
-  const auto& ref_edges = m_refiner.tet_store.edge_store.edges;
-  const auto& refinpoel = m_refiner.tet_store.get_active_inpoel();
-
-  for (std::size_t e=0; e<refinpoel.size()/4; ++e) {
-    auto A = refinpoel[e*4+0];
-    auto B = refinpoel[e*4+1];
-    auto C = refinpoel[e*4+2];
-    auto D = refinpoel[e*4+3];
-    std::array<Edge,6> edges{{ {{A,B}}, {{B,C}}, {{A,C}},
-                               {{A,D}}, {{B,D}}, {{C,D}} }};
-    for (const auto& ed : edges) {
-      auto ae = AMR::edge_t{{{ std::min(ed[0],ed[1]), std::max(ed[0],ed[1]) }}};
-      auto r = tk::cref_find( ref_edges, ae );
-      const auto ged = Edge{{ m_gid[ tk::cref_find( m_lref, ed[0] ) ],
-                              m_gid[ tk::cref_find( m_lref, ed[1] ) ] }};
-      // only update edges that are on chare boundary OR unlocked
-      if (m_localEdgeData.find(ged) == m_localEdgeData.end() ||
-        std::get<2>(m_localEdgeData[ged]) == AMR::Edge_Lock_Case::unlocked) {
-        m_localEdgeData[ ged ] = { r.needs_refining, r.needs_derefining,
-          r.lock_case };
-      }
-    }
-  }
-}
-
-std::tuple< std::vector< std::string >,
-            std::vector< std::vector< tk::real > >,
-            std::vector< std::string >,
-            std::vector< std::vector< tk::real > > >
-Refiner::refinementFields() const
-// *****************************************************************************
-//  Collect mesh output fields from refiner lib
-//! \return Names and fields of mesh refinement data in mesh cells and nodes
-// *****************************************************************************
-{
-  // Find number of nodes in current mesh
-  auto npoin = tk::npoin_in_graph( m_inpoel );
-  // Generate edges surrounding points in current mesh
-  auto esup = tk::genEsup( m_inpoel, 4 );
-
-  // Update solution on current mesh
-  const auto& u = solution( npoin, esup );
-  Assert( u.nunk() == npoin, "Solution uninitialized or wrong size" );
-
-  // Compute error in edges on current mesh
-  auto edgeError = errorsInEdges( npoin, esup, u );
-
-  // Transfer error from edges to cells for field output
-  std::vector< tk::real > error( m_inpoel.size()/4, 0.0 );
-  for (std::size_t e=0; e<m_inpoel.size()/4; ++e) {
-    auto A = m_inpoel[e*4+0];
-    auto B = m_inpoel[e*4+1];
-    auto C = m_inpoel[e*4+2];
-    auto D = m_inpoel[e*4+3];
-    std::array<Edge,6> edges{{ {{A,B}}, {{B,C}}, {{A,C}},
-                               {{A,D}}, {{B,D}}, {{C,D}} }};
-    // sum error from edges to elements
-    for (const auto& ed : edges) error[e] += tk::cref_find( edgeError, ed );
-    error[e] /= 6.0;    // assign edge-average error to element
-  }
-
-  // Prepare element fields with mesh refinement data
-  std::vector< std::string >
-    elemfieldnames{ "refinement level", "cell type", "error" };
-  auto& tet_store = m_refiner.tet_store;
-  std::vector< std::vector< tk::real > > elemfields{
-    tet_store.get_refinement_level_list(),
-    tet_store.get_cell_type_list(),
-    error };
-
-  using tuple_t = std::tuple< std::vector< std::string >,
-                              std::vector< std::vector< tk::real > >,
-                              std::vector< std::string >,
-                              std::vector< std::vector< tk::real > > >;
-  return tuple_t{ elemfieldnames, elemfields, {}, {} };
-}
-
-void
-Refiner::writeMesh( const std::string& basefilename,
-                    uint64_t itr,
-                    tk::real t,
-                    CkCallback c ) const
-// *****************************************************************************
-//  Output mesh to file(s)
-//! \param[in] basefilename File name to append to
-//! \param[in] itr Iteration count since a new mesh
-//! \param[in] t "Physical time" to write to file. "Time" here is used to
-//!   designate a new time step at which the mesh is saved.
-//! \param[in] c Function to continue with after the write
-// *****************************************************************************
-{
-  auto r = refinementFields();
-  auto& elemfieldnames = std::get< 0 >( r );
-  auto& elemfields = std::get< 1 >( r );
-  auto& nodefieldnames = std::get< 2 >( r );
-  auto& nodefields = std::get< 3 >( r );
-
-  // Prepare solution field names: depvar + component id for all eqs
-  auto nprop = g_inputdeck.get< tag::ncomp >();
-  std::vector< std::string > solfieldnames;
-  for (std::size_t i=0; i<nprop; ++i) {
-    solfieldnames.push_back(
-      g_inputdeck.get< tag::depvar >()[0] + std::to_string(i+1) );
-  }
-  Assert( solfieldnames.size() == nprop, "Size mismatch" );
-
-  const auto scheme = g_inputdeck.get< tag::scheme >();
-  const auto centering = ctr::Scheme().centering( scheme );
-  auto t0 = g_inputdeck.get< tag::t0 >();
-
-  // list of nodes/elements at which box ICs are defined
-  std::vector< std::unordered_set< std::size_t > > inbox;
-  tk::real V = 1.0;
-  std::vector< tk::real > blkvols;
-  std::unordered_map< std::size_t, std::set< std::size_t > > nodeblockid,
-    elemblockid;
-
-  // Prepare node or element fields for output to file
-  if (centering == tk::Centering::NODE) {
-
-    // Augment element field names with solution variable names + field ids
-    nodefieldnames.insert( end(nodefieldnames),
-                           begin(solfieldnames), end(solfieldnames) );
-
-    // Evaluate initial conditions on current mesh at t0
-    tk::Fields u( m_coord[0].size(), nprop );
-    g_cgpde[m_meshid].initialize( m_coord, u, t0, V, inbox, blkvols,
-      nodeblockid );
-
-    // Extract all scalar components from solution for output to file
-    for (std::size_t i=0; i<nprop; ++i)
-      nodefields.push_back( u.extract_comp( i ) );
-
-  } else if (centering == tk::Centering::ELEM) {
-
-    // Augment element field names with solution variable names + field ids
-    elemfieldnames.insert( end(elemfieldnames),
-                           begin(solfieldnames), end(solfieldnames) );
-
-    auto ndof = g_inputdeck.get< tag::ndof >();
-    tk::Fields lhs( m_inpoel.size()/4, ndof*nprop );
-
-    // Generate left hand side for DG and evaluate initial conditions on
-    // current mesh at t0
-    auto geoElem = tk::genGeoElemTet( m_inpoel, m_coord );
-    auto u = lhs;
-    if (scheme == ctr::SchemeType::FV) {
-      g_fvpde[m_meshid].lhs( geoElem, lhs );
-      g_fvpde[m_meshid].initialize( lhs, m_inpoel, m_coord, inbox, elemblockid,
-        u, t0, m_inpoel.size()/4 );
-    }
-    else {
-      g_dgpde[m_meshid].lhs( geoElem, lhs );
-      g_dgpde[m_meshid].initialize( lhs, m_inpoel, m_coord, inbox, elemblockid,
-        u, t0, m_inpoel.size()/4 );
-    }
-
-    // Extract all scalar components from solution for output to file
-    for (std::size_t i=0; i<nprop; ++i)
-      elemfields.push_back( u.extract_comp( i ) );
-  }
-
-  // Output mesh
-  m_meshwriter[ CkNodeFirst( CkMyNode() ) ].
-    write( m_meshid, /*meshoutput = */ true, /*fieldoutput = */ true, itr, 1, t,
-           thisIndex, basefilename, m_inpoel, m_coord, m_bface,
-           tk::remap(m_bnode,m_lid), tk::remap(m_triinpoel,m_lid),
-           elemfieldnames, nodefieldnames, {}, {}, elemfields, nodefields, {},
-           {}, {}, c );
-}
-
-void
-Refiner::perform()
-// *****************************************************************************
-// Perform mesh refinement and decide how to continue
-//! \details First the mesh refiner object is called to perform a single step
-//!   of mesh refinement. Then, if this function is called during a step
-//!   (potentially multiple levels of) initial AMR, it evaluates whether to do
-//!   another one. If it is called during time stepping, this concludes the
-//!   single mesh refinement step and the new mesh is sent to the PDE worker
-//!   (Discretization).
-// *****************************************************************************
-{
-  // Save old tets and their ids before performing refinement. Outref is always
-  // followed by outderef, so to the outside world, the mesh is uchanged, thus
-  // no update.
-  if (m_mode != RefMode::OUTREF && m_mode != RefMode::OUTDEREF) {
-    m_oldTets.clear();
-    for (const auto& [ id, tet ] : m_refiner.tet_store.tets) {
-      m_oldTets.insert( tet );
-    }
-    m_oldntets = m_oldTets.size();
-  }
-
-  if (m_mode == RefMode::T0REF) {
-
-    // Refine mesh based on next initial refinement type
-    if (!m_initref.empty()) {
-      auto r = m_initref.back();    // consume (reversed) list from its back
-      if (r == ctr::AMRInitialType::UNIFORM_DEREFINE)
-        m_refiner.perform_derefinement();
-      else
-        m_refiner.perform_refinement();
-    }
-
-  } else {
-
-    // TODO: does not work yet, fix as above
-    m_refiner.perform_refinement();
-    m_refiner.perform_derefinement();
-  }
-
-  // Remove temporary edge-locks resulting from the parallel compatibility
-  m_refiner.remove_edge_locks(1);
-  m_refiner.remove_edge_temp_locks();
-
-  //auto& tet_store = m_refiner.tet_store;
-  //std::cout << "before ref: " << tet_store.marked_refinements.size() << ", " << tet_store.marked_derefinements.size() << ", " << tet_store.size() << ", " << tet_store.get_active_inpoel().size() << '\n';
-  //std::cout << "after ref: " << tet_store.marked_refinements.size() << ", " << tet_store.marked_derefinements.size() << ", " << tet_store.size() << ", " << tet_store.get_active_inpoel().size() << '\n';
-  //std::cout << "after deref: " << tet_store.marked_refinements.size() << ", " << tet_store.marked_derefinements.size() << ", " << tet_store.size() << ", " << tet_store.get_active_inpoel().size() << '\n';
-
-  // Update volume and boundary mesh
-  updateMesh();
-
-  // Save mesh at every initial refinement step (mainly for debugging). Will
-  // replace with just a 'next()' in production.
-  if (m_mode == RefMode::T0REF) {
-
-    auto l = m_ninitref - m_initref.size() + 1;  // num initref steps completed
-    auto t0 = g_inputdeck.get< tag::t0 >();
-    // Generate times equally subdividing t0-1...t0 to ninitref steps
-    auto t =
-      t0 - 1.0 + static_cast<tk::real>(l)/static_cast<tk::real>(m_ninitref);
-    auto itr = l;
-    // Output mesh after refinement step
-    writeMesh( "t0ref", itr, t,
-               CkCallback( CkIndex_Refiner::next(), thisProxy[thisIndex] ) );
-
-  } else {
-
-    next();
-
-  }
-}
-
-void
-Refiner::next()
-// *****************************************************************************
-// Continue after finishing a refinement step
-// *****************************************************************************
-{
-  if (m_mode == RefMode::T0REF) {
-
-    // Remove initial mesh refinement step from list
-    if (!m_initref.empty()) m_initref.pop_back();
-    // Continue to next initial AMR step or finish
-    if (!m_initref.empty()) t0ref(); else endt0ref();
-
-  } else if (m_mode == RefMode::DTREF) {
-
-    // Send new mesh, solution, and communication data back to PDE worker
-    m_scheme[m_meshid].ckLocal< Scheme::resizePostAMR >( thisIndex,  m_ginpoel,
-      m_el, m_coord, m_addedNodes, m_addedTets, m_removedNodes, m_amrNodeMap,
-      m_nodeCommMap, m_bface, m_bnode, m_triinpoel, m_elemblockid );
-
-  } else if (m_mode == RefMode::OUTREF) {
-
-    // Store field output mesh
-    m_outref_ginpoel = m_ginpoel;
-    m_outref_el = m_el;
-    m_outref_coord = m_coord;
-    m_outref_addedNodes = m_addedNodes;
-    m_outref_addedTets = m_addedTets;
-    m_outref_nodeCommMap = m_nodeCommMap;
-    m_outref_bface = m_bface;
-    m_outref_bnode = m_bnode;
-    m_outref_triinpoel = m_triinpoel;
-
-    // Derefine mesh to the state previous to field output
-    outref( m_outref_bface, m_outref_bnode, m_outref_triinpoel, m_writeCallback,
-            RefMode::OUTDEREF );
-
-  } else if (m_mode == RefMode::OUTDEREF) {
-
-    // Send field output mesh to PDE worker
-    m_scheme[m_meshid].ckLocal< Scheme::extractFieldOutput >( thisIndex,
-      m_outref_ginpoel, m_outref_el, m_outref_coord, m_outref_addedNodes,
-      m_outref_addedTets, m_outref_nodeCommMap, m_outref_bface, m_outref_bnode,
-      m_outref_triinpoel, m_writeCallback );
-
-  } else Throw( "RefMode not implemented" );
-}
-
-void
-Refiner::endt0ref()
-// *****************************************************************************
-// Finish initial mesh refinement
-//! \details This function is called as after initial mesh refinement has
-//!   finished. If initial mesh reifnement was not configured by the user, this
-//!   is the point where we continue after the constructor, by computing the
-//!   total number of elements across the whole problem.
-// *****************************************************************************
-{
-  // create sorter Charm++ chare array elements using dynamic insertion
-  m_sorter[ thisIndex ].insert( m_meshid, m_host, m_meshwriter, m_cbs, m_scheme,
-    CkCallback(CkIndex_Refiner::reorder(), thisProxy[thisIndex]), m_ginpoel,
-    m_coordmap, m_el, m_bface, m_triinpoel, m_bnode, m_elemblockid, m_nchare );
-
-  // Compute final number of cells across whole problem
-  std::vector< std::size_t >
-    meshdata{ m_meshid, m_ginpoel.size()/4, m_coord[0].size() };
-  contribute( meshdata, CkReduction::sum_ulong, m_cbr.get< tag::refined >() );
-
-  // // Free up memory if no dtref
-  // if (!g_inputdeck.get< tag::amr, tag::dtref >()) {
-  //   tk::destroy( m_ginpoel );
-  //   tk::destroy( m_el );
-  //   tk::destroy( m_coordmap );
-  //   tk::destroy( m_coord );
-  //   tk::destroy( m_bface );
-  //   tk::destroy( m_bnode );
-  //   tk::destroy( m_triinpoel );
-  //   tk::destroy( m_initref );
-  //   tk::destroy( m_ch );
-  //   tk::destroy( m_edgech );
-  //   tk::destroy( m_chedge );
-  //   tk::destroy( m_localEdgeData );
-  //   tk::destroy( m_remoteEdgeData );
-  //   tk::destroy( m_remoteEdges );
-  //   tk::destroy( m_intermediates );
-  //   tk::destroy( m_nodeCommMap );
-  //   tk::destroy( m_oldTets );
-  //   tk::destroy( m_addedNodes );
-  //   tk::destroy( m_addedTets );
-  //   tk::destroy( m_coarseBndFaces );
-  //   tk::destroy( m_coarseBndNodes );
-  //   tk::destroy( m_rid );
-//  //   tk::destroy( m_oldrid );
-  //   tk::destroy( m_lref );
-//  //   tk::destroy( m_oldparent );
-  // }
-}
-
-void
-Refiner::uniformRefine()
-// *****************************************************************************
-// Do uniform mesh refinement
-// *****************************************************************************
-{
-  // Do uniform refinement
-  m_refiner.mark_uniform_refinement();
-
-  // Update our extra-edge store based on refiner
-  updateEdgeData();
-
-  // Set number of extra edges to be zero, skipping correction (if this is the
-  // only step in this refinement step)
-  m_extra = 0;
-}
-
-void
-Refiner::uniformDeRefine()
-// *****************************************************************************
-// Do uniform mesh derefinement
-// *****************************************************************************
-{
-  // Do uniform derefinement
-  m_refiner.mark_uniform_derefinement();
-
-  // Update our extra-edge store based on refiner
-  updateEdgeData();
-
-  // Set number of extra edges to be zero, skipping correction (if this is the
-  // only step in this refinement step)
-  m_extra = 0;
-}
-
-Refiner::EdgeError
-Refiner::errorsInEdges(
-  std::size_t npoin,
-  const std::pair< std::vector<std::size_t>, std::vector<std::size_t> >& esup,
-  const tk::Fields& u ) const
-// *****************************************************************************
-//  Compute errors in edges
-//! \param[in] npoin Number nodes in current mesh (partition)
-//! \param[in] esup Elements surrounding points linked vectors
-//! \param[in] u Solution evaluated at mesh nodes for all scalar components
-//! \return A map associating errors (real values between 0.0 and 1.0 incusive)
-//!   to edges (2 local node IDs)
-// *****************************************************************************
-{
-  // Get the indices (in the system of systems) of refinement variables and the
-  // error indicator configured
-  auto ncomp = g_inputdeck.get< tag::ncomp >();
-  auto errtype = g_inputdeck.get< tag::amr, tag::error >();
-
-  // Compute points surrounding points
-  auto psup = tk::genPsup( m_inpoel, 4, esup );
-
-  // Compute errors in ICs and define refinement criteria for edges
-  AMR::Error error;
-  EdgeError edgeError;
-
-  for (std::size_t p=0; p<npoin; ++p) { // for all mesh nodes on this chare
-    for (auto q : tk::Around(psup,p)) { // for all nodes surrounding p
-      tk::real cmax = 0.0;
-      AMR::edge_t e(p,q);
-      for (std::size_t i=0; i<ncomp; ++i) { // for all refinement variables
-        auto c = error.scalar( u, e, i, m_coord, m_inpoel, esup, errtype );
-        if (c > cmax) cmax = c;        // find max error at edge
-      }
-      edgeError[ {{p,q}} ] = cmax;       // associate error to edge
-    }
-  }
-
-  return edgeError;
-}
-
-tk::Fields
-Refiner::solution( std::size_t npoin,
-                   const std::pair< std::vector< std::size_t >,
-                                    std::vector< std::size_t > >& esup ) const
-// *****************************************************************************
-//  Update (or evaluate) solution on current mesh
-//! \param[in] npoin Number nodes in current mesh (partition)
-//! \param[in] esup Elements surrounding points linked vectors
-//! \return Solution updated/evaluated for all scalar components
-// *****************************************************************************
-{
-  // Get solution whose error to evaluate
-  tk::Fields u;
-
-  if (m_mode == RefMode::T0REF) {
-
-    // Evaluate initial conditions at mesh nodes
-    u = nodeinit( npoin, esup );
-
-  } else if (m_mode == RefMode::DTREF) {
-
-    // Query current solution
-    u = m_scheme[m_meshid].ckLocal< Scheme::solution >( thisIndex );
- 
-    const auto scheme = g_inputdeck.get< tag::scheme >();
-    const auto centering = ctr::Scheme().centering( scheme );
-    if (centering == tk::Centering::ELEM) {
-
-      // ...
-      Throw("Element-based solution handling not implemented in Refiner");
-
-    }
-
-  } else if (m_mode == RefMode::OUTREF) {
-
-
-
-  } else if (m_mode == RefMode::OUTDEREF) {
-
-
-
-  } else Throw( "RefMode not implemented" );
-
-  return u;
-}
-
-void
-Refiner::errorRefine()
-// *****************************************************************************
-// Do error-based mesh refinement and derefinement
-// *****************************************************************************
-{
-  // Find number of nodes in old mesh
-  auto npoin = tk::npoin_in_graph( m_inpoel );
-  // Generate edges surrounding points in old mesh
-  auto esup = tk::genEsup( m_inpoel, 4 );
-
-  // Update solution on current mesh
-  const auto& u = solution( npoin, esup );
-  Assert( u.nunk() == npoin, "Solution uninitialized or wrong size" );
-
-  using AMR::edge_t;
-  using AMR::edge_tag;
-
-  // Compute error in edges. Tag edge for refinement if error exceeds
-  // refinement tolerance, tag edge for derefinement if error is below
-  // derefinement tolerance.
-  auto tolref = g_inputdeck.get< tag::amr, tag::tol_refine >();
-  auto tolderef = g_inputdeck.get< tag::amr, tag::tol_derefine >();
-  std::vector< std::pair< edge_t, edge_tag > > tagged_edges;
-  for (const auto& e : errorsInEdges(npoin,esup,u)) {
-    if (e.second > tolref) {
-      tagged_edges.push_back( { edge_t( m_rid[e.first[0]], m_rid[e.first[1]] ),
-                                edge_tag::REFINE } );
-    } else if (e.second < tolderef) {
-      tagged_edges.push_back( { edge_t( m_rid[e.first[0]], m_rid[e.first[1]] ),
-                                edge_tag::DEREFINE } );
-    }
-  }
-
-  // Do error-based refinement
-  m_refiner.mark_error_refinement( tagged_edges );
-
-  // Update our extra-edge store based on refiner
-  updateEdgeData();
-
-  // Set number of extra edges to a nonzero number, triggering correction
-  m_extra = 1;
-}
-
-void
-Refiner::edgelistRefine()
-// *****************************************************************************
-// Do mesh refinement based on user explicitly tagging edges
-// *****************************************************************************
-{
-  // Get user-defined node-pairs (edges) to tag for refinement
-  const auto& edgenodelist = g_inputdeck.get< tag::amr, tag::edgelist >();
-
-  if (!edgenodelist.empty()) {  // if user explicitly tagged edges
-    // Find number of nodes in old mesh
-    auto npoin = tk::npoin_in_graph( m_inpoel );
-    // Generate edges surrounding points in old mesh
-    auto esup = tk::genEsup( m_inpoel, 4 );
-    auto psup = tk::genPsup( m_inpoel, 4, esup );
-
-    EdgeSet useredges;
-    for (std::size_t i=0; i<edgenodelist.size()/2; ++i)
-      useredges.insert( {{ {edgenodelist[i*2+0], edgenodelist[i*2+1]} }} );
-
-    using AMR::edge_t;
-    using AMR::edge_tag;
-
-    // Tag edges the user configured
-    std::vector< std::pair< edge_t, edge_tag > > tagged_edges;
-    for (std::size_t p=0; p<npoin; ++p)        // for all mesh nodes on this chare
-      for (auto q : tk::Around(psup,p)) {      // for all nodes surrounding p
-        Edge e{{ m_gid[p], m_gid[q] }};
-        auto f = useredges.find(e);
-        if (f != end(useredges)) { // tag edge if on user's list
-          tagged_edges.push_back( { edge_t( m_rid[p], m_rid[q] ),
-                                    edge_tag::REFINE } );
-          useredges.erase( f );
-        }
-      }
-
-    // Do error-based refinement
-    m_refiner.mark_error_refinement( tagged_edges );
-
-    // Update our extra-edge store based on refiner
-    updateEdgeData();
-
-    // Set number of extra edges to a nonzero number, triggering correction
-    m_extra = 1;
-  }
-}
-
-void
-Refiner::coordRefine()
-// *****************************************************************************
-// Do mesh refinement based on tagging edges based on end-point coordinates
-// *****************************************************************************
-{
-  // Get user-defined half-world coordinates
-  const auto& amr_coord = g_inputdeck.get< tag::amr, tag::coords >();
-  auto xminus = amr_coord.get< tag::xminus >();
-  auto xplus  = amr_coord.get< tag::xplus >();
-  auto yminus = amr_coord.get< tag::yminus >();
-  auto yplus  = amr_coord.get< tag::yplus >();
-  auto zminus = amr_coord.get< tag::zminus >();
-  auto zplus  = amr_coord.get< tag::zplus >();
-
-  // The default is the largest representable double
-  auto eps =
-    std::numeric_limits< tk::real >::epsilon();
-  const auto& amr_defcoord = g_inputdeck_defaults.get< tag::amr, tag::coords >();
-  auto xminus_default = amr_defcoord.get< tag::xminus >();
-  auto xplus_default = amr_defcoord.get< tag::xplus >();
-  auto yminus_default = amr_defcoord.get< tag::yminus >();
-  auto yplus_default = amr_defcoord.get< tag::yplus >();
-  auto zminus_default = amr_defcoord.get< tag::zminus >();
-  auto zplus_default = amr_defcoord.get< tag::zplus >();
-
-  // Decide if user has configured the half-world
-  bool xm = std::abs(xminus - xminus_default) > eps ? true : false;
-  bool xp = std::abs(xplus - xplus_default) > eps ? true : false;
-  bool ym = std::abs(yminus - yminus_default) > eps ? true : false;
-  bool yp = std::abs(yplus - yplus_default) > eps ? true : false;
-  bool zm = std::abs(zminus - zminus_default) > eps ? true : false;
-  bool zp = std::abs(zplus - zplus_default) > eps ? true : false;
-
-  using AMR::edge_t;
-  using AMR::edge_tag;
-
-  if (xm || xp || ym || yp || zm || zp) {       // if any half-world configured
-    // Find number of nodes in old mesh
-    auto npoin = tk::npoin_in_graph( m_inpoel );
-    // Generate edges surrounding points in old mesh
-    auto esup = tk::genEsup( m_inpoel, 4 );
-    auto psup = tk::genPsup( m_inpoel, 4, esup );
-    // Get access to node coordinates
-    const auto& x = m_coord[0];
-    const auto& y = m_coord[1];
-    const auto& z = m_coord[2];
-    // Compute edges to be tagged for refinement
-    std::vector< std::pair< edge_t, edge_tag > > tagged_edges;
-    for (std::size_t p=0; p<npoin; ++p)    // for all mesh nodes on this chare
-      for (auto q : tk::Around(psup,p)) {  // for all nodes surrounding p
-        Edge e{{p,q}};
-
-        bool t = true;
-        if (xm) { if (x[p]>xminus && x[q]>xminus) t = false; }
-        if (xp) { if (x[p]<xplus && x[q]<xplus) t = false; }
-        if (ym) { if (y[p]>yminus && y[q]>yminus) t = false; }
-        if (yp) { if (y[p]<yplus && y[q]<yplus) t = false; }
-        if (zm) { if (z[p]>zminus && z[q]>zminus) t = false; }
-        if (zp) { if (z[p]<zplus && z[q]<zplus) t = false; }
-
-        if (t) {
-          tagged_edges.push_back( { edge_t( m_rid[e[0]], m_rid[e[1]] ),
-                                    edge_tag::REFINE } );
-        }
-      }
-
-    // Do error-based refinement
-    m_refiner.mark_error_refinement( tagged_edges );
-
-    // Update our extra-edge store based on refiner
-    updateEdgeData();
-
-    // Set number of extra edges to a nonzero number, triggering correction
-    m_extra = 1;
-  }
-}
-
-tk::Fields
-Refiner::nodeinit( std::size_t npoin,
-                   const std::pair< std::vector< std::size_t >,
-                                    std::vector< std::size_t > >& esup ) const
-// *****************************************************************************
-// Evaluate initial conditions (IC) at mesh nodes
-//! \param[in] npoin Number points in mesh (on this chare)
-//! \param[in] esup Elements surrounding points as linked lists, see tk::genEsup
-//! \return Initial conditions (evaluated at t0) at nodes
-// *****************************************************************************
-{
-  auto t0 = g_inputdeck.get< tag::t0 >();
-  auto nprop = g_inputdeck.get< tag::ncomp >();
-
-  // Will store nodal ICs
-  tk::Fields u( m_coord[0].size(), nprop );
-
-  // Evaluate ICs differently depending on nodal or cell-centered discretization
-  const auto scheme = g_inputdeck.get< tag::scheme >();
-  const auto centering = ctr::Scheme().centering( scheme );
-  // list of nodes/elements at which box ICs are defined
-  std::vector< std::unordered_set< std::size_t > > inbox;
-  tk::real V = 1.0;
-  std::vector< tk::real > blkvols;
-  std::unordered_map< std::size_t, std::set< std::size_t > > nodeblockid,
-    elemblockid;
-
-  if (centering == tk::Centering::NODE) {
-
-    // Evaluate ICs for all scalar components integrated
-    g_cgpde[m_meshid].initialize( m_coord, u, t0, V, inbox, blkvols,
-      nodeblockid );
-
-  } else if (centering == tk::Centering::ELEM) {
-
-    auto esuel = tk::genEsuelTet( m_inpoel, esup ); // elems surrounding elements
-    // Initialize cell-based unknowns
-    tk::Fields ue( m_inpoel.size()/4, nprop );
-    auto lhs = ue;
-    auto geoElem = tk::genGeoElemTet( m_inpoel, m_coord );
-    if (scheme == ctr::SchemeType::FV) {
-    g_fvpde[m_meshid].lhs( geoElem, lhs );
-    g_fvpde[m_meshid].initialize( lhs, m_inpoel, m_coord, inbox, elemblockid,
-      ue, t0, esuel.size()/4 );
-    }
-    else {
-    g_dgpde[m_meshid].lhs( geoElem, lhs );
-    g_dgpde[m_meshid].initialize( lhs, m_inpoel, m_coord, inbox, elemblockid,
-      ue, t0, esuel.size()/4 );
-    }
-
-    // Transfer initial conditions from cells to nodes
-    for (std::size_t p=0; p<npoin; ++p) {    // for all mesh nodes on this chare
-      std::vector< tk::real > up( nprop, 0.0 );
-      tk::real vol = 0.0;
-      for (auto e : tk::Around(esup,p)) {       // for all cells around node p
-        // compute nodal volume: every element contributes their volume / 4
-        vol += geoElem(e,0) / 4.0;
-        // sum cell value to node weighed by cell volume / 4
-        for (std::size_t c=0; c<nprop; ++c)
-          up[c] += ue[e][c] * geoElem(e,0) / 4.0;
-      }
-      // store nodal value
-      for (std::size_t c=0; c<nprop; ++c) u(p,c) = up[c] / vol;
-    }
-
-  } else Throw( "Scheme centring not handled for nodal initialization" );
-
-  Assert( u.nunk() == m_coord[0].size(), "Size mismatch" );
-  Assert( u.nprop() == nprop, "Size mismatch" );
-
-  return u;
-}
-
-void
-Refiner::updateMesh()
-// *****************************************************************************
-// Update old mesh after refinement
-// *****************************************************************************
-{
-  // Get refined mesh connectivity
-  const auto& refinpoel = m_refiner.tet_store.get_active_inpoel();
-  Assert( refinpoel.size()%4 == 0, "Inconsistent refined mesh connectivity" );
-
-  // Generate unique node lists of old and refined mesh using local ids
-  auto rinpoel = m_inpoel;
-  tk::remap( rinpoel, m_rid );
-  std::unordered_set< std::size_t > old( begin(rinpoel), end(rinpoel) );
-  std::unordered_set< std::size_t > ref( begin(refinpoel), end(refinpoel) );
-
-  // Augment refiner id -> local node id map with newly added nodes
-  std::size_t l = m_lref.size();
-  for (auto r : ref) if (old.find(r) == end(old)) m_lref[r] = l++;
-
-  // Get nodal communication map from Discretization worker
-  if ( m_mode == RefMode::DTREF ||
-       m_mode == RefMode::OUTREF ||
-       m_mode == RefMode::OUTDEREF ) {
-    m_nodeCommMap =
-      m_scheme[m_meshid].disc()[thisIndex].ckLocal()->NodeCommMap();
-  }
-
-  // Update mesh and solution after refinement
-  newVolMesh( old, ref );
-
-  // Update mesh connectivity from refiner lib, remapping refiner to local ids
-  m_inpoel = m_refiner.tet_store.get_active_inpoel();
-  tk::remap( m_inpoel, m_lref );
-
-  // Update mesh connectivity with new global node ids
-  m_ginpoel = m_inpoel;
-  Assert( tk::uniquecopy(m_ginpoel).size() == m_coord[0].size(),
-          "Size mismatch" );
-  tk::remap( m_ginpoel, m_gid );
-
-  // Update boundary face and node information
-  newBndMesh( ref );
-
-  // Augment node communication map with newly added nodes on chare-boundary
-  if (m_mode == RefMode::DTREF || m_mode == RefMode::OUTREF) {
-    for (const auto& [ neighborchare, edges ] : m_remoteEdges) {
-      auto& nodes = tk::ref_find( m_nodeCommMap, neighborchare );
-      for (const auto& e : edges) {
-        // If parent nodes were part of the node communication map for chare
-        if (nodes.find(e[0]) != end(nodes) && nodes.find(e[1]) != end(nodes)) {
-          // Add new node if local id was generated for it
-          auto n = Hash<2>()( e );
-          if (m_lid.find(n) != end(m_lid)) nodes.insert( n );
-        }
-      }
-    }
-  }
-
-  // Ensure valid mesh after refinement
-  Assert( tk::positiveJacobians( m_inpoel, m_coord ),
-          "Refined mesh cell Jacobian non-positive" );
-
-  Assert( tk::conforming( m_inpoel, m_coord, true, m_rid ),
-          "Chare-"+std::to_string(thisIndex)+
-          " mesh not conforming after updating mesh after mesh refinement" );
-
-  // Perform leak test on new mesh
-  Assert( !tk::leakyPartition(
-            tk::genEsuelTet( m_inpoel, tk::genEsup(m_inpoel,4) ),
-            m_inpoel, m_coord ),
-          "Refined mesh partition leaky" );
-}
-
-void
-Refiner::newVolMesh( const std::unordered_set< std::size_t >& old,
-                     const std::unordered_set< std::size_t >& ref )
-// *****************************************************************************
-//  Compute new volume mesh after mesh refinement
-//! \param[in] old Unique nodes of the old (unrefined) mesh using
-//!   refiner-lib ids
-//! \param[in] ref Unique nodes of the refined mesh using refiner-lib ids
-// *****************************************************************************
-{
-  const auto& x = m_coord[0];
-  const auto& y = m_coord[1];
-  const auto& z = m_coord[2];
-
-  // Generate coordinates and ids to newly added nodes after refinement
-  std::unordered_map< std::size_t, std::size_t > gid_add;
-  tk::destroy( m_addedNodes );
-  tk::destroy( m_removedNodes );
-  tk::destroy( m_amrNodeMap );
-  for (auto r : ref) {               // for all unique nodes of the refined mesh
-    if (old.find(r) == end(old)) {   // if node is newly added
-      // get (local) parent ids of newly added node
-      auto p = m_refiner.node_connectivity.get( r );
-      Assert(p[0] != p[1], "Node without parent edge in newVolMesh");
-      Assert( old.find(p[0]) != end(old) && old.find(p[1]) != end(old),
-              "Parent(s) not in old mesh" );
-      // local parent ids
-      decltype(p) lp{{tk::cref_find(m_lref,p[0]), tk::cref_find(m_lref,p[1])}};
-      // global parent ids
-      decltype(p) gp{{m_gid[lp[0]], m_gid[lp[1]]}};
-      // generate new global ID for newly added node
-      auto g = Hash<2>()( gp );
-
-      // if node added by AMR lib has not yet been added to Refiner's new mesh
-      if (m_coordmap.find(g) == end(m_coordmap)) {
-        Assert( g >= old.size(), "Hashed id overwriting old id" );
-        Assert( m_lid.find(g) == end(m_lid),
-                "Overwriting entry global->local node ID map" );
-        auto l = tk::cref_find( m_lref, r );
-        // store newly added node id and their parent ids (local ids)
-        m_addedNodes[r] = lp;   // key = r for later update to local
-        // assign new node to refiner->global map
-        gid_add[r] = g; // key = r for later search
-        // assign new node to global->local map
-        m_lid[g] = l;
-        // generate and store coordinates for newly added node
-        m_coordmap.insert( {g, {{ (x[lp[0]] + x[lp[1]])/2.0,
-                                  (y[lp[0]] + y[lp[1]])/2.0,
-                                  (z[lp[0]] + z[lp[1]])/2.0 }} } );
-      }
-    }
-  }
-  tk::destroy( m_coord );
-
-  // generate a node map based on oldnodes+addednodes
-  std::vector< size_t > nodeVec(m_coordmap.size());
-  for (size_t j=0; j<nodeVec.size(); ++j) {
-    nodeVec[j] = j;
-  }
-
-  // Remove coordinates and ids of removed nodes due to derefinement
-  std::unordered_map< std::size_t, std::size_t > gid_rem;
-  for (auto o : old) {               // for all unique nodes of the old mesh
-    if (ref.find(o) == end(ref)) {   // if node is no longer in new mesh
-      auto l = tk::cref_find( m_lref, o );
-      auto g = m_gid[l];
-      // store local-ids of removed nodes
-      m_removedNodes.insert(l);
-      // remove derefined nodes from node comm map
-      for (auto& [neighborchare, sharednodes] : m_nodeCommMap) {
-        if (sharednodes.find(g) != sharednodes.end()) {
-          sharednodes.erase(g);
-        }
-      }
-      gid_rem[l] = g;
-      m_lid.erase( g );
-      m_coordmap.erase( g );
-    }
-  }
-
-  // update the node map by removing the derefined nodes
-  if (m_mode == RefMode::DTREF && m_removedNodes.size() > 0) {
-    // remove derefined nodes
-    size_t remCount = 0;
-    size_t origSize = nodeVec.size();
-    for (size_t j=0; j<origSize; ++j) {
-      auto nd = nodeVec[j-remCount];
-
-      bool no_change = false;
-      size_t nodeidx = 0;
-      for (const auto& rn : m_removedNodes) {
-        if (nd < *m_removedNodes.cbegin()) {
-          no_change = true;
-          break;
-        }
-        else if (nd <= rn) {
-          nodeidx = rn;
-          break;
-        }
-      }
-
-      // if node is out-or-range of removed nodes list, continue with next entry
-      if (no_change)
-        continue;
-      // if not is within range of removed nodes list, erase node appropriately
-      else if (nodeidx == nd) {
-        //! Difference type for iterator/pointer arithmetics
-        using diff_type = std::vector< std::size_t >::difference_type;
-        nodeVec.erase(nodeVec.begin()+static_cast< diff_type >(j-remCount));
-        ++remCount;
-      }
-    }
-
-    Assert(remCount == m_removedNodes.size(), "Incorrect number of nodes removed "
-      "from node map.");
-  }
-
-  // invert node vector to get node map
-  for (size_t i=0; i<nodeVec.size(); ++i) {
-    m_amrNodeMap[nodeVec[i]] = i;
-  }
-
-  //// Save previous states of refiner-local node id maps before update
-  //m_oldrid = m_rid;
-  //m_oldlref = m_lref;
-
-  // Generate new node id maps for nodes kept
-  tk::destroy( m_lref );
-  std::vector< std::size_t > rid( ref.size() );
-  std::vector< std::size_t > gid( ref.size() );
-  std::size_t l = 0;    // will generate new local node id
-  for (std::size_t i=0; i<m_gid.size(); ++i) {
-    if (gid_rem.find(i) == end(gid_rem)) {
-      gid[l] = m_gid[i];
-      rid[l] = m_rid[i];
-      m_lref[ m_rid[i] ] = l;
-      ++l;
-    }
-  }
-  // Add newly added nodes due to refinement to node id maps
-  decltype(m_addedNodes) addedNodes( m_addedNodes.size() );<--- Variable 'addedNodes' is assigned a value that is never used.
-  for (const auto& n : gid_add) {
-    auto r = n.first;
-    auto g = n.second;
-    gid[l] = g;
-    rid[l] = r;<--- Variable 'rid[l]' is assigned a value that is never used.
-    Assert(m_lref.find(r) == m_lref.end(), "Overwriting lref");
-    m_lref[r] = l;
-    auto it = m_addedNodes.find( r );
-    Assert( it != end(m_addedNodes), "Cannot find added node" );
-    addedNodes[l] = std::move(it->second);
-    addedNodes.at(l)[0] = m_amrNodeMap[addedNodes.at(l)[0]];
-    addedNodes.at(l)[1] = m_amrNodeMap[addedNodes.at(l)[1]];
-    ++l;
-  }
-  Assert( m_lref.size() == ref.size(), "Size mismatch" );
-  //for (auto r : ref) {
-  //  Assert(m_lref.find(r) != m_lref.end(), "Node missing in lref");
-  //}
-  //const auto& int_list = m_refiner.tet_store.intermediate_list;
-  //for (auto in : int_list) {
-  //  Assert(m_lref.find(in) != m_lref.end(), "Interm node missing in lref: "
-  //    + std::to_string(in));
-  //}
-  m_rid = std::move( rid );
-  Assert( m_rid.size() == ref.size(), "Size mismatch" );
-  m_addedNodes = std::move( addedNodes );
-
-  // Update node coordinates, ids, and id maps
-  auto& rx = m_coord[0];
-  auto& ry = m_coord[1];
-  auto& rz = m_coord[2];
-  rx.resize( ref.size() );
-  ry.resize( ref.size() );
-  rz.resize( ref.size() );
-  for (std::size_t i=0; i<gid.size(); ++i) {
-    tk::ref_find( m_lid, gid[i] ) = i;
-    const auto& c = tk::cref_find( m_coordmap, gid[i] );
-    rx[i] = c[0];
-    ry[i] = c[1];
-    rz[i] = c[2];
-  }
-  m_gid = std::move( gid );
-  Assert( m_gid.size() == m_lid.size() && m_gid.size() == ref.size(),
-    "Size mismatch" );
-}
-
-std::unordered_set< std::size_t >
-Refiner::ancestors( std::size_t n )
-// *****************************************************************************
-// Find the oldest parents of a mesh node in the AMR hierarchy
-//! \param[in] n Local node id whose ancestors to search
-//! \return Parents of local node id from the coarsest (original) mesh
-// *****************************************************************************
-{
-  auto d = m_refiner.node_connectivity.get( m_rid[n] );
-  decltype(d) p{{ tk::cref_find( m_lref, d[0] ),
-                  tk::cref_find( m_lref, d[1] ) }};
-
-  std::unordered_set< std::size_t > s;
-
-  if (p != AMR::node_pair_t{{n,n}}) {
-    auto q = ancestors( p[0] );
-    s.insert( begin(q), end(q) );
-    auto r = ancestors( p[1] );
-    s.insert( begin(r), end(r) );
-  } else {
-    s.insert( begin(p), end(p) );
-  }
-
-  return s;
-}
-
-Refiner::BndFaceData
-Refiner::boundary()
-// *****************************************************************************
-//  Generate boundary data structures used to update refined/derefined boundary
-//  faces and nodes of side sets
-//! \return A tuple of boundary face data
-//! \details The output of this function is used to regenerate physical boundary
-//!   face and node data structures after refinement, see updateBndData().
-// *****************************************************************************
-{
-  // Generate the inverse of AMR's tet store.
-  std::unordered_map< Tet, std::size_t, Hash<4>, Eq<4> > invtets;
-  for (const auto& [key, tet] : m_refiner.tet_store.tets)
-    invtets[ tet ] = key;
-
-  //std::cout << thisIndex << " invt: " << invtets.size() << '\n';
-  //std::cout << thisIndex << " active inpoel size: " << m_refiner.tet_store.get_active_inpoel().size() << '\n';
-  //std::cout << thisIndex << " marked derefinement size: " << m_refiner.tet_store.marked_derefinements.size() << '\n';
-
-  // Generate data structure pcFaceTets for the new (post-AMR) mesh:
-  // pcFaceTets is a map that associates all triangle boundary faces (physical
-  // and chare) to the id of the tet adjacent to the said face.
-  // Key: Face-nodes' global id; Value: tet-id.
-  std::unordered_map< Face, std::size_t, Hash<3>, Eq<3> > pcFaceTets;
-  auto esuel = tk::genEsuelTet( m_inpoel, tk::genEsup(m_inpoel,4) );
-  for (std::size_t e=0; e<esuel.size()/4; ++e) {
-    auto m = e*4;
-    for (std::size_t f=0; f<4; ++f) {
-      if (esuel[m+f] == -1) {  // if a face does not have an adjacent tet
-        Face b{{ m_ginpoel[ m+tk::lpofa[f][0] ],
-                 m_ginpoel[ m+tk::lpofa[f][1] ],
-                 m_ginpoel[ m+tk::lpofa[f][2] ] }};
-        Assert( m_inpoel[m+0] < m_rid.size() &&
-                m_inpoel[m+1] < m_rid.size() &&
-                m_inpoel[m+2] < m_rid.size() &&
-                m_inpoel[m+3] < m_rid.size(), "Indexing out of rid" );
-        Tet t{{ m_rid[ m_inpoel[m+0] ], m_rid[ m_inpoel[m+1] ],
-                m_rid[ m_inpoel[m+2] ], m_rid[ m_inpoel[m+3] ] }};
-        //Tet t{{ m_inpoel[m+0], m_inpoel[m+1],
-        //        m_inpoel[m+2], m_inpoel[m+3] }};
-        // associate tet id to adjacent (physical or chare) boundary face
-        auto i = invtets.find( t );
-        Assert(m_refiner.tet_store.is_active(i->second),
-          "Inactive element while regenerating boundary data");
-        if (i != end(invtets)) {
-          //std::cout << "refacetets: " <<
-          //  b[0] << "-" << b[1] << "-" << b[2] << std::endl;
-          pcFaceTets[ b ] = i->second;
-        } else {
-          Throw("Active element not found in tet_store");
-        }
-      }
-    }
-  }
-
-  // Generate child->parent tet and id maps after refinement/derefinement step
-//  tk::destroy( m_oldparent );
-  m_addedTets.clear();
-  std::size_t p = 0;
-  std::size_t c = 0;<--- Variable 'c' is assigned a value that is never used.
-  const auto& tet_store = m_refiner.tet_store;
-  for (const auto& t : tet_store.tets) {
-    // query number of children of tet
-    auto nc = tet_store.data( t.first ).children.size();
-    for (decltype(nc) i=0; i<nc; ++i ) {      // for all child tets
-      // get child tet id
-      auto childtet = tet_store.get_child_id( t.first, i );
-      auto ct = tet_store.tets.find( childtet );
-      Assert(ct != tet_store.tets.end(), "Child not found in tet store");
-//      //auto cA = tk::cref_find( m_lref, ct->second[0] );
-//      //auto cB = tk::cref_find( m_lref, ct->second[1] );
-//      //auto cC = tk::cref_find( m_lref, ct->second[2] );
-//      //auto cD = tk::cref_find( m_lref, ct->second[3] );
-//      // get nodes of parent tet
-//      //auto pA = tk::cref_find( m_lref, t.second[0] );
-//      //auto pB = tk::cref_find( m_lref, t.second[1] );
-//      //auto pC = tk::cref_find( m_lref, t.second[2] );
-//      //auto pD = tk::cref_find( m_lref, t.second[3] );
-//      // assign parent tet to child tet
-//      //m_oldparent[ {{cA,cB,cC,cD}} ] = {{pA,pB,pC,pD}};
-//      m_oldparent[ ct->second ] = t.second; //{{pA,pB,pC,pD}};
-      if (m_oldTets.find(ct->second) == end(m_oldTets)) {
-        // TODO: the following code can assign negative ids to newly added tets.
-        // This needs to be corrected before applying to cell-based schemes.
-        //Assert((p-m_oldntets) > 0, "Negative id assigned to added tet");
-        m_addedTets[ c++ ] = p - m_oldntets;
-      }
-    }
-    ++p;
-  }
-
-  //std::cout << thisIndex << " added: " << m_addedTets.size() << '\n';
-  //std::cout << thisIndex << " parent: " << m_oldparent.size() << '\n';
-  //std::cout << thisIndex << " pcret: " << pcFaceTets.size() << '\n';
-
-  //for (std::size_t f=0; f<m_triinpoel.size()/3; ++f) {
-  //  std::cout << "triinpoel: " <<
-  //    m_triinpoel[f*3+0] << "-" << m_triinpoel[f*3+1] << "-" <<
-  //    m_triinpoel[f*3+2] << std::endl;
-  //}
-
-  return pcFaceTets;
-}
-
-void
-Refiner::newBndMesh( const std::unordered_set< std::size_t >& ref )
-// *****************************************************************************
-// Update boundary data structures after mesh refinement
-//! \param[in] ref Unique nodes of the refined mesh using refiner-lib ids
-// *****************************************************************************
-{
-  // Generate boundary face data structures used to regenerate boundary face
-  // and node data after mesh refinement
-  auto pcFaceTets = boundary();
-
-  // Regerate boundary faces and nodes after AMR step
-  updateBndData( ref, pcFaceTets );
-}
-
-void
-Refiner::updateBndData(
-  [[maybe_unused]] const std::unordered_set< std::size_t >& ref,
-  const BndFaceData& pcFaceTets )
-// *****************************************************************************
-// Regenerate boundary faces and nodes after AMR step
-//! \param[in] ref Unique nodes of the refined mesh using refiner-lib ids
-//! \param[in] pcFaceTets Boundary face data
-// *****************************************************************************
-{
-  // storage for boundary faces associated to side-set IDs of the refined mesh
-  tk::destroy( m_bface );
-  // storage for boundary faces-node connectivity of the refined mesh
-  tk::destroy( m_triinpoel );
-  // storage for boundary nodes associated to side-set IDs of the refined mesh
-  tk::destroy( m_bnode );
-
-  // face id counter
-  std::size_t facecnt = 0;
-  // will collect unique faces added for each side set
-  std::unordered_map< int, FaceSet > bf;
-
-  // Lambda to associate a boundary face and connectivity to a side set.
-  // Argument 's' is the list of faces (ids) to add the new face to. Argument
-  // 'ss' is the side set id to which the face is added. Argument 'f' is the
-  // triangle face connectivity to add.
-  auto addBndFace = [&]( std::vector< std::size_t >& s, int ss, const Face& f )
-  {
-    // only add face if it has not yet been aded to this side set
-    if (bf[ ss ].insert( f ).second) {
-      s.push_back( facecnt++ );
-      m_triinpoel.insert( end(m_triinpoel), begin(f), end(f) );
-      Assert(m_triinpoel.size()/3 == facecnt, "Incorrect size of triinpoel");
-    }
-  };
-
-  // Lambda to search the parents in the coarsest mesh of a mesh node and if
-  // found, add its global id to boundary node lists associated to the side
-  // set(s) of its parents. Argument 'n' is the local id of the mesh node id
-  // whose parents to search.
-  auto addBndNodes = [&]( std::size_t n ){
-    auto a = ancestors( n );  // find parents of n in coarse mesh
-    if (a.size() == 1) {
-      // node was part of the coarse mesh
-      Assert(*a.cbegin() == n, "Single ancestor not self");
-      auto ss = keys( m_coarseBndNodes, m_gid[*a.cbegin()] );
-      for (auto s : ss)
-        m_bnode[ s ].push_back( m_gid[n] );
-    } else if (a.size() == 2) {
-      // node was added to an edge of a coarse face
-      std::vector< std::size_t > p( begin(a), end(a) );
-      auto ss1 = keys( m_coarseBndNodes, m_gid[p[0]] );
-      auto ss2 = keys( m_coarseBndNodes, m_gid[p[1]] );
-      for (auto s : ss1) {
-        // only add 'n' to bnode if all parent nodes are in same side set, else
-        // 'n' is not a boundary node
-        if (ss2.find(s) != end(ss2)) {
-          m_bnode[ s ].push_back( m_gid[n] );
-        }
-      }
-    } else if (a.size() == 3) {
-      // node was added inside of a coarse face
-      std::vector< std::size_t > p( begin(a), end(a) );
-      auto ss1 = keys( m_coarseBndNodes, m_gid[p[0]] );
-      auto ss2 = keys( m_coarseBndNodes, m_gid[p[1]] );
-      auto ss3 = keys( m_coarseBndNodes, m_gid[p[2]] );
-      for (auto s : ss1) {
-        // only add 'n' to bnode if all parent nodes are in same side set, else
-        // 'n' is not a boundary node
-        if (ss2.find(s) != end(ss2) && ss3.find(s) != end(ss3)) {
-          m_bnode[ s ].push_back( m_gid[n] );
-        }
-      }
-    }
-  };
-
-  // Regenerate boundary faces for new mesh along side sets. For all faces
-  // associated to side sets, we find the ancestors (parents of nodes in the
-  // original/coarsest mesh) of the nodes comprising the physical and chare
-  // boundary faces of the new mesh.
-  //bool faceNoSs = false;
-  // for all P/C faces in current (post-AMR) mesh
-  for (const auto& [ face, tetid ] : pcFaceTets) {
-    // find ancestors of face
-    std::unordered_set< std::size_t > ans;
-    for (std::size_t i=0; i<3; ++i) {
-      auto ai = ancestors(tk::cref_find(m_lid, face[i]));
-      ans.insert(ai.begin(), ai.end());
-    }
-    Assert(ans.size() == 3, "Incorrect number of ancestors in refined face");
-    Face af;
-    std::size_t i = 0;
-    for (auto ai:ans) {
-      af[i] = m_gid[ai];
-      ++i;
-    }
-    // for all boundary faces in original mesh
-    //std::size_t fss = 0;
-    for (const auto& [ss, cfaceset] : m_coarseBndFaces) {
-      if (cfaceset.find(af) != cfaceset.end()) {
-        addBndFace(m_bface[ss], ss, face);
-        //++fss;
-      }
-      for (auto j : face) {
-        addBndNodes(tk::cref_find(m_lid, j));
-      }
-    }
-    //if (fss==0) {
-    //  std::cout << "Face added to no/multiple side sets; " << fss << std::endl;
-    //  faceNoSs = true;
-    //}
-  }
-
-  // Commented code below, since diagcg can work without sideset/bcs
-  //Assert(!faceNoSs, "Face/s added to incorrect number of side sets");
-
-  // Make boundary node IDs unique for each physical boundary (side set)
-  for (auto& s : m_bnode) tk::unique( s.second );
-
-  //for (const auto& [ setid, faceids ] : m_bface) {
-  //  std::cout << "sset: " << setid << std::endl;
-  //  for (auto f : faceids) {
-  //    Assert(f<m_triinpoel.size()/3, "Out of bounds access into triinpoel");
-  //    std::cout << "new bndfaces: " <<
-  //      m_triinpoel[f*3+0] << "-" << m_triinpoel[f*3+1] << "-" <<
-  //      m_triinpoel[f*3+2] << std::endl;
-  //  }
-  //}
-
-  //for (std::size_t f=0; f<m_triinpoel.size()/3; ++f) {
-  //  std::cout << "new triinpoel: " <<
-  //    m_triinpoel[f*3+0] << "-" << m_triinpoel[f*3+1] << "-" <<
-  //    m_triinpoel[f*3+2] << std::endl;
-  //}
-
-  //std::cout << thisIndex << " bf: " << tk::sumvalsize( m_bface ) << '\n';
-
-  //std::cout << thisIndex << " bn: " << tk::sumvalsize( m_bnode ) << '\n';
-
-  // Perform leak-test on boundary face data just updated (only in DEBUG)
-  Assert( bndIntegral(), "Partial boundary integral" );
-}
-
-bool
-Refiner::bndIntegral()
-// *****************************************************************************
-//  Compute partial boundary surface integral and sum across all chares
-//! \return true so we don't trigger assert in client code
-//! \details This function computes a partial surface integral over the boundary
-//!   of the faces of this mesh partition then sends its contribution to perform
-//!   the integral acorss the total problem boundary. After the global sum a
-//!   non-zero vector result indicates a leak, e.g., a hole in the boundary
-//!   which indicates an error in the boundary face data structures used to
-//!   compute the partial surface integrals.
-// *****************************************************************************
-{
-  const auto& x = m_coord[0];
-  const auto& y = m_coord[1];
-  const auto& z = m_coord[2];
-
-  std::vector< tk::real > s{{ 0.0, 0.0, 0.0 }};
-
-  for (const auto& [ setid, faceids ] : m_bface) {
-    for (auto f : faceids) {
-      auto A = tk::cref_find( m_lid, m_triinpoel[f*3+0] );
-      auto B = tk::cref_find( m_lid, m_triinpoel[f*3+1] );
-      auto C = tk::cref_find( m_lid, m_triinpoel[f*3+2] );
-      // Compute geometry data for face
-      auto geoface = tk::geoFaceTri( {{x[A], x[B], x[C]}},
-                                     {{y[A], y[B], y[C]}},
-                                     {{z[A], z[B], z[C]}} );
-      // Sum up face area * face unit-normal
-      s[0] += geoface(0,0) * geoface(0,1);
-      s[1] += geoface(0,0) * geoface(0,2);
-      s[2] += geoface(0,0) * geoface(0,3);
-    }
-  }
-
-  s.push_back( -1.0 );  // negative: no call-back after reduction
-  s.push_back( static_cast< tk::real >( m_meshid ) );
-
-  // Send contribution to host summing partial surface integrals
-  contribute( s, CkReduction::sum_double, m_cbr.get< tag::bndint >() );
-
-  return true;  // don't trigger the assert in client code
-}
-
-#include "NoWarning/refiner.def.h"
+  // [II] Finally initialize the solution vector
+  for (std::size_t k=0; k<nmat; ++k) {
+    // partial density
+    s[densityIdx(nmat,k)] = s[volfracIdx(nmat,k)] * rhok[k];
+    // total specific energy
+    if (boxmas > 0.0 && k == boxmatid &&
+      initiate == ctr::InitiateType::IMPULSE) {
+      s[energyIdx(nmat,k)] = s[volfracIdx(nmat,k)] * rhok[k] * spi;
+    }
+    else {
+      // TEMP: Eventually we would need to initialize gk from control file
+      std::array< std::array< tk::real, 3 >, 3 > gk;
+      if (solidx[k] > 0) {
+        for (std::size_t i=0; i<3; ++i) {
+          for (std::size_t j=0; j<3; ++j) {
+            if (i==j) gk[i][j] = 1.0;
+            else gk[i][j] = 0.0;
+            s[deformIdx(nmat,solidx[k],i,j)] = gk[i][j];
+          }
+        }
+      }
+      else {
+        gk = {{}};
+      }
+      s[energyIdx(nmat,k)] = s[volfracIdx(nmat,k)] *
+        mat_blk[k].compute< EOS::totalenergy >( rhok[k], u, v, w, pr, gk );
+    }
+  }
+  // bulk momentum
+  s[momentumIdx(nmat,0)] = rbulk * u;
+  s[momentumIdx(nmat,1)] = rbulk * v;
+  s[momentumIdx(nmat,2)] = rbulk * w;
+}
+
+} //inciter::
+
+#endif // MultiMatBoxInitialization_h
 
diff --git a/Release/cppcheck/53.html b/Release/cppcheck/53.html index 4e770b325018..e9679bd17446 100644 --- a/Release/cppcheck/53.html +++ b/Release/cppcheck/53.html @@ -152,407 +152,3237 @@
- - + @@ -146,7 +146,7 @@ 72 : : #endif 73 : : //! Migrate constructor 74 : : // cppcheck-suppress uninitMemberVar - 75 : 111 : explicit ALE( CkMigrateMessage* ) {} + 75 : 115 : explicit ALE( CkMigrateMessage* ) {} 76 : : #if defined(__clang__) 77 : : #pragma clang diagnostic pop 78 : : #endif @@ -214,38 +214,38 @@ 140 : : ///@{ 141 : : //! \brief Pack/Unpack serialize member function 142 : : //! \param[in,out] p Charm++'s PUP::er serializer object reference - 143 : 364 : void pup( PUP::er &p ) override { - 144 : 364 : p | m_conjugategradients; - 145 : 364 : p | m_done; - 146 : 364 : p | m_soundspeed; - 147 : 364 : p | m_nvort; - 148 : 364 : p | m_ndiv; - 149 : 364 : p | m_npot; - 150 : 364 : p | m_nwf; - 151 : 364 : p | m_nodeCommMap; - 152 : 364 : p | m_lid; + 143 : 376 : void pup( PUP::er &p ) override { + 144 : 376 : p | m_conjugategradients; + 145 : 376 : p | m_done; + 146 : 376 : p | m_soundspeed; + 147 : 376 : p | m_nvort; + 148 : 376 : p | m_ndiv; + 149 : 376 : p | m_npot; + 150 : 376 : p | m_nwf; + 151 : 376 : p | m_nodeCommMap; + 152 : 376 : p | m_lid; 153 : : p | m_coord0; 154 : : p | m_coord; - 155 : 364 : p | m_inpoel; - 156 : 364 : p | m_vol0; - 157 : 364 : p | m_vol; - 158 : 364 : p | m_it; - 159 : 364 : p | m_t; - 160 : 364 : p | m_adt; - 161 : 364 : p | m_w; - 162 : 364 : p | m_wf; - 163 : 364 : p | m_wfc; - 164 : 364 : p | m_veldiv; - 165 : 364 : p | m_veldivc; + 155 : 376 : p | m_inpoel; + 156 : 376 : p | m_vol0; + 157 : 376 : p | m_vol; + 158 : 376 : p | m_it; + 159 : 376 : p | m_t; + 160 : 376 : p | m_adt; + 161 : 376 : p | m_w; + 162 : 376 : p | m_wf; + 163 : 376 : p | m_wfc; + 164 : 376 : p | m_veldiv; + 165 : 376 : p | m_veldivc; 166 : : p | m_gradpot; 167 : : p | m_gradpotc; 168 : : p | m_vorticity; 169 : : p | m_vorticityc; - 170 : 364 : p | m_bnorm; - 171 : 364 : p | m_meshveldirbcnodes; - 172 : 364 : p | m_meshvelsymbcnodes; - 173 : 364 : p | m_move; - 174 : 364 : } + 170 : 376 : p | m_bnorm; + 171 : 376 : p | m_meshveldirbcnodes; + 172 : 376 : p | m_meshvelsymbcnodes; + 173 : 376 : p | m_move; + 174 : 376 : } 175 : : //! \brief Pack/Unpack serialize operator| 176 : : //! \param[in,out] p Charm++'s PUP::er serializer object reference 177 : : //! \param[in,out] a ALE object reference diff --git a/Release/test_coverage/Inciter/ALECG.cpp.func-sort-c.html b/Release/test_coverage/Inciter/ALECG.cpp.func-sort-c.html index 5c6602bae106..2c4fd12c73a8 100644 --- a/Release/test_coverage/Inciter/ALECG.cpp.func-sort-c.html +++ b/Release/test_coverage/Inciter/ALECG.cpp.func-sort-c.html @@ -33,7 +33,7 @@ - + diff --git a/Release/test_coverage/Inciter/ALECG.cpp.func.html b/Release/test_coverage/Inciter/ALECG.cpp.func.html index 9cd763f31734..649bbf90b477 100644 --- a/Release/test_coverage/Inciter/ALECG.cpp.func.html +++ b/Release/test_coverage/Inciter/ALECG.cpp.func.html @@ -33,7 +33,7 @@ - + diff --git a/Release/test_coverage/Inciter/ALECG.cpp.gcov.html b/Release/test_coverage/Inciter/ALECG.cpp.gcov.html index b2d0b2775e01..494583170110 100644 --- a/Release/test_coverage/Inciter/ALECG.cpp.gcov.html +++ b/Release/test_coverage/Inciter/ALECG.cpp.gcov.html @@ -33,7 +33,7 @@ - + @@ -894,12 +894,12 @@ 803 : : std::size_t f = 0; 804 : 1617 : const auto& gid = d->Gid(); 805 [ + + ]: 7476488 : for (auto&& [p,q] : uedge) { - 806 [ + + ]: 7474871 : if (gid[p] > gid[q]) { - 807 : 96365 : m_edgenode[f+0] = std::move(q); - 808 : 96365 : m_edgenode[f+1] = std::move(p); + 806 [ + + ]: 7474871 : if (gid[p] > gid[q]) { + 807 : 99310 : m_edgenode[f+0] = std::move(q); + 808 : 99310 : m_edgenode[f+1] = std::move(p); 809 : : } else { - 810 : 7378506 : m_edgenode[f+0] = std::move(p); - 811 : 7378506 : m_edgenode[f+1] = std::move(q); + 810 : 7375561 : m_edgenode[f+0] = std::move(p); + 811 : 7375561 : m_edgenode[f+1] = std::move(q); 812 : : } 813 : 7474871 : f += 2; 814 : : } diff --git a/Release/test_coverage/Inciter/ALECG.hpp.func-sort-c.html b/Release/test_coverage/Inciter/ALECG.hpp.func-sort-c.html index 133407851be4..a3d46087587f 100644 --- a/Release/test_coverage/Inciter/ALECG.hpp.func-sort-c.html +++ b/Release/test_coverage/Inciter/ALECG.hpp.func-sort-c.html @@ -33,7 +33,7 @@ - + @@ -73,11 +73,11 @@ - + - + diff --git a/Release/test_coverage/Inciter/ALECG.hpp.func.html b/Release/test_coverage/Inciter/ALECG.hpp.func.html index ec5eaba2f350..304143e013ec 100644 --- a/Release/test_coverage/Inciter/ALECG.hpp.func.html +++ b/Release/test_coverage/Inciter/ALECG.hpp.func.html @@ -33,7 +33,7 @@ - + @@ -73,11 +73,11 @@ - + - + diff --git a/Release/test_coverage/Inciter/ALECG.hpp.gcov.html b/Release/test_coverage/Inciter/ALECG.hpp.gcov.html index 34fed65ab81f..3365a2fdc29a 100644 --- a/Release/test_coverage/Inciter/ALECG.hpp.gcov.html +++ b/Release/test_coverage/Inciter/ALECG.hpp.gcov.html @@ -33,7 +33,7 @@ - + @@ -158,7 +158,7 @@ 84 : : #endif 85 : : //! Migrate constructor 86 : : // cppcheck-suppress uninitMemberVar - 87 : 1632 : explicit ALECG( CkMigrateMessage* msg ) : CBase_ALECG( msg ) {} + 87 : 1625 : explicit ALECG( CkMigrateMessage* msg ) : CBase_ALECG( msg ) {} 88 : : #if defined(__clang__) 89 : : #pragma clang diagnostic pop 90 : : #endif @@ -279,51 +279,51 @@ 205 : : ///@{ 206 : : //! \brief Pack/Unpack serialize member function 207 : : //! \param[in,out] p Charm++'s PUP::er serializer object reference - 208 : 5136 : void pup( PUP::er &p ) override { - 209 : 5136 : p | m_disc; - 210 : 5136 : p | m_nsol; - 211 : 5136 : p | m_ngrad; - 212 : 5136 : p | m_nrhs; - 213 : 5136 : p | m_nbnorm; - 214 : 5136 : p | m_ndfnorm; - 215 : 5136 : p | m_nmblk; - 216 : 5136 : p | m_bnode; - 217 : 5136 : p | m_bface; - 218 : 5136 : p | m_triinpoel; - 219 : 5136 : p | m_bndel; - 220 : 5136 : p | m_dfnorm; - 221 : 5136 : p | m_dfnormc; - 222 : 5136 : p | m_dfn; - 223 : 5136 : p | m_esup; - 224 : 5136 : p | m_psup; - 225 : 5136 : p | m_u; - 226 : 5136 : p | m_un; - 227 : 5136 : p | m_rhs; - 228 : 5136 : p | m_rhsc; - 229 : 5136 : p | m_chBndGrad; - 230 : 5136 : p | m_dirbc; - 231 : 5136 : p | m_chBndGradc; + 208 : 5115 : void pup( PUP::er &p ) override { + 209 : 5115 : p | m_disc; + 210 : 5115 : p | m_nsol; + 211 : 5115 : p | m_ngrad; + 212 : 5115 : p | m_nrhs; + 213 : 5115 : p | m_nbnorm; + 214 : 5115 : p | m_ndfnorm; + 215 : 5115 : p | m_nmblk; + 216 : 5115 : p | m_bnode; + 217 : 5115 : p | m_bface; + 218 : 5115 : p | m_triinpoel; + 219 : 5115 : p | m_bndel; + 220 : 5115 : p | m_dfnorm; + 221 : 5115 : p | m_dfnormc; + 222 : 5115 : p | m_dfn; + 223 : 5115 : p | m_esup; + 224 : 5115 : p | m_psup; + 225 : 5115 : p | m_u; + 226 : 5115 : p | m_un; + 227 : 5115 : p | m_rhs; + 228 : 5115 : p | m_rhsc; + 229 : 5115 : p | m_chBndGrad; + 230 : 5115 : p | m_dirbc; + 231 : 5115 : p | m_chBndGradc; 232 : : p | m_diag; - 233 : 5136 : p | m_bnorm; - 234 : 5136 : p | m_bnormc; - 235 : 5136 : p | m_symbcnodes; - 236 : 5136 : p | m_farfieldbcnodes; - 237 : 5136 : p | m_symbctri; - 238 : 5136 : p | m_timedepbcnodes; - 239 : 5136 : p | m_timedepbcFn; - 240 : 5136 : p | m_stage; - 241 : 5136 : p | m_boxnodes; - 242 : 5136 : p | m_edgenode; - 243 : 5136 : p | m_edgeid; - 244 : 5136 : p | m_dtp; - 245 : 5136 : p | m_tp; - 246 : 5136 : p | m_finished; - 247 : 5136 : p | m_newmesh; - 248 : 5136 : p | m_refinedmesh; - 249 : 5136 : p | m_nusermeshblk; - 250 : 5136 : p | m_nodeblockid; - 251 : 5136 : p | m_nodeblockidc; - 252 : 5136 : } + 233 : 5115 : p | m_bnorm; + 234 : 5115 : p | m_bnormc; + 235 : 5115 : p | m_symbcnodes; + 236 : 5115 : p | m_farfieldbcnodes; + 237 : 5115 : p | m_symbctri; + 238 : 5115 : p | m_timedepbcnodes; + 239 : 5115 : p | m_timedepbcFn; + 240 : 5115 : p | m_stage; + 241 : 5115 : p | m_boxnodes; + 242 : 5115 : p | m_edgenode; + 243 : 5115 : p | m_edgeid; + 244 : 5115 : p | m_dtp; + 245 : 5115 : p | m_tp; + 246 : 5115 : p | m_finished; + 247 : 5115 : p | m_newmesh; + 248 : 5115 : p | m_refinedmesh; + 249 : 5115 : p | m_nusermeshblk; + 250 : 5115 : p | m_nodeblockid; + 251 : 5115 : p | m_nodeblockidc; + 252 : 5115 : } 253 : : //! \brief Pack/Unpack serialize operator| 254 : : //! \param[in,out] p Charm++'s PUP::er serializer object reference 255 : : //! \param[in,out] i ALECG object reference diff --git a/Release/test_coverage/Inciter/AMR/AMR_types.hpp.func-sort-c.html b/Release/test_coverage/Inciter/AMR/AMR_types.hpp.func-sort-c.html index 5d690392cd9e..b82abadea86c 100644 --- a/Release/test_coverage/Inciter/AMR/AMR_types.hpp.func-sort-c.html +++ b/Release/test_coverage/Inciter/AMR/AMR_types.hpp.func-sort-c.html @@ -33,7 +33,7 @@ - + diff --git a/Release/test_coverage/Inciter/AMR/AMR_types.hpp.func.html b/Release/test_coverage/Inciter/AMR/AMR_types.hpp.func.html index b898fda92857..3308ba71949d 100644 --- a/Release/test_coverage/Inciter/AMR/AMR_types.hpp.func.html +++ b/Release/test_coverage/Inciter/AMR/AMR_types.hpp.func.html @@ -33,7 +33,7 @@ - + diff --git a/Release/test_coverage/Inciter/AMR/AMR_types.hpp.gcov.html b/Release/test_coverage/Inciter/AMR/AMR_types.hpp.gcov.html index d1de8d772058..1e718ef7d12e 100644 --- a/Release/test_coverage/Inciter/AMR/AMR_types.hpp.gcov.html +++ b/Release/test_coverage/Inciter/AMR/AMR_types.hpp.gcov.html @@ -33,7 +33,7 @@ - + @@ -124,12 +124,12 @@ 50 : : Edge_Lock_Case lock_case; // TODO: Refactor this to match _ style? 51 : : 52 : : // Explicit Empty Constructor - 53 : 1791089 : Edge_Refinement() : + 53 : 1791643 : Edge_Refinement() : 54 : : A(0), 55 : : B(0), 56 : : needs_refining(0), 57 : : needs_derefining(false), - 58 [ - + ]: 1791089 : lock_case(Edge_Lock_Case::unlocked) + 58 [ - + ]: 1791643 : lock_case(Edge_Lock_Case::unlocked) 59 : : { 60 : : // Empty 61 : : } diff --git a/Release/test_coverage/Inciter/AMR/Error.cpp.func-sort-c.html b/Release/test_coverage/Inciter/AMR/Error.cpp.func-sort-c.html index 20679001c9ef..1a78b76039a8 100644 --- a/Release/test_coverage/Inciter/AMR/Error.cpp.func-sort-c.html +++ b/Release/test_coverage/Inciter/AMR/Error.cpp.func-sort-c.html @@ -33,7 +33,7 @@ - + diff --git a/Release/test_coverage/Inciter/AMR/Error.cpp.func.html b/Release/test_coverage/Inciter/AMR/Error.cpp.func.html index 0e36cc084926..e76d60f18321 100644 --- a/Release/test_coverage/Inciter/AMR/Error.cpp.func.html +++ b/Release/test_coverage/Inciter/AMR/Error.cpp.func.html @@ -33,7 +33,7 @@ - + diff --git a/Release/test_coverage/Inciter/AMR/Error.cpp.gcov.html b/Release/test_coverage/Inciter/AMR/Error.cpp.gcov.html index c6345a53ac61..34ce386f21f0 100644 --- a/Release/test_coverage/Inciter/AMR/Error.cpp.gcov.html +++ b/Release/test_coverage/Inciter/AMR/Error.cpp.gcov.html @@ -33,7 +33,7 @@ - + diff --git a/Release/test_coverage/Inciter/AMR/Refinement_State.hpp.func-sort-c.html b/Release/test_coverage/Inciter/AMR/Refinement_State.hpp.func-sort-c.html index 560b0ace3ed0..f81081ff8bbc 100644 --- a/Release/test_coverage/Inciter/AMR/Refinement_State.hpp.func-sort-c.html +++ b/Release/test_coverage/Inciter/AMR/Refinement_State.hpp.func-sort-c.html @@ -33,7 +33,7 @@ - + diff --git a/Release/test_coverage/Inciter/AMR/Refinement_State.hpp.func.html b/Release/test_coverage/Inciter/AMR/Refinement_State.hpp.func.html index a78a2dd19d97..95d6d3d7d3a2 100644 --- a/Release/test_coverage/Inciter/AMR/Refinement_State.hpp.func.html +++ b/Release/test_coverage/Inciter/AMR/Refinement_State.hpp.func.html @@ -33,7 +33,7 @@ - + diff --git a/Release/test_coverage/Inciter/AMR/Refinement_State.hpp.gcov.html b/Release/test_coverage/Inciter/AMR/Refinement_State.hpp.gcov.html index 36b8f99ef09a..149bb7961daf 100644 --- a/Release/test_coverage/Inciter/AMR/Refinement_State.hpp.gcov.html +++ b/Release/test_coverage/Inciter/AMR/Refinement_State.hpp.gcov.html @@ -33,7 +33,7 @@ - + @@ -97,7 +97,7 @@ 23 : : enum Derefinement_Case { two_to_one = 0, four_to_one, four_to_two, 24 : : eight_to_one, eight_to_two, eight_to_four, skip }; 25 : : - 26 [ + - ][ + - ]: 1898309 : class Refinement_State { + 26 [ + - ][ + - ]: 1901802 : class Refinement_State { 27 : : 28 : : public: 29 : : /// Common to active and master elements @@ -110,7 +110,7 @@ 36 : : bool normal; 37 : : bool has_parent; 38 : : - 39 [ - + ]: 1038276 : Refinement_State() {} + 39 [ - + ]: 1041769 : Refinement_State() {} 40 : : 41 : : /** 42 : : * @brief Constructor which allows for all data fields to be explicitly diff --git a/Release/test_coverage/Inciter/AMR/active_element_store.hpp.func-sort-c.html b/Release/test_coverage/Inciter/AMR/active_element_store.hpp.func-sort-c.html index a9648b83b658..5cd89d8cb460 100644 --- a/Release/test_coverage/Inciter/AMR/active_element_store.hpp.func-sort-c.html +++ b/Release/test_coverage/Inciter/AMR/active_element_store.hpp.func-sort-c.html @@ -33,7 +33,7 @@ - + diff --git a/Release/test_coverage/Inciter/AMR/active_element_store.hpp.func.html b/Release/test_coverage/Inciter/AMR/active_element_store.hpp.func.html index a97c2e3c4a72..55a27b472a5f 100644 --- a/Release/test_coverage/Inciter/AMR/active_element_store.hpp.func.html +++ b/Release/test_coverage/Inciter/AMR/active_element_store.hpp.func.html @@ -33,7 +33,7 @@ - + diff --git a/Release/test_coverage/Inciter/AMR/active_element_store.hpp.gcov.html b/Release/test_coverage/Inciter/AMR/active_element_store.hpp.gcov.html index e44d19079bb1..6f8ab9f03b61 100644 --- a/Release/test_coverage/Inciter/AMR/active_element_store.hpp.gcov.html +++ b/Release/test_coverage/Inciter/AMR/active_element_store.hpp.gcov.html @@ -33,7 +33,7 @@ - + @@ -86,7 +86,7 @@ 12 : : public: 13 : : 14 : : //! Non-const-ref access to state - 15 : 24390 : std::set<size_t>& data() { return active_elements; } + 15 : 24081 : std::set<size_t>& data() { return active_elements; } 16 : : 17 : : /** 18 : : * @brief Function to add active elements diff --git a/Release/test_coverage/Inciter/AMR/edge.cpp.func-sort-c.html b/Release/test_coverage/Inciter/AMR/edge.cpp.func-sort-c.html index 42e26311ed73..06ca654cf2cd 100644 --- a/Release/test_coverage/Inciter/AMR/edge.cpp.func-sort-c.html +++ b/Release/test_coverage/Inciter/AMR/edge.cpp.func-sort-c.html @@ -33,7 +33,7 @@ - + diff --git a/Release/test_coverage/Inciter/AMR/edge.cpp.func.html b/Release/test_coverage/Inciter/AMR/edge.cpp.func.html index b29c58e2c280..6f039dff8c49 100644 --- a/Release/test_coverage/Inciter/AMR/edge.cpp.func.html +++ b/Release/test_coverage/Inciter/AMR/edge.cpp.func.html @@ -33,7 +33,7 @@ - + diff --git a/Release/test_coverage/Inciter/AMR/edge.cpp.gcov.html b/Release/test_coverage/Inciter/AMR/edge.cpp.gcov.html index 6702707d1090..6bfc87e8e6e6 100644 --- a/Release/test_coverage/Inciter/AMR/edge.cpp.gcov.html +++ b/Release/test_coverage/Inciter/AMR/edge.cpp.gcov.html @@ -33,7 +33,7 @@ - + diff --git a/Release/test_coverage/Inciter/AMR/edge.hpp.func-sort-c.html b/Release/test_coverage/Inciter/AMR/edge.hpp.func-sort-c.html index 37f374d50dca..446eeae0adce 100644 --- a/Release/test_coverage/Inciter/AMR/edge.hpp.func-sort-c.html +++ b/Release/test_coverage/Inciter/AMR/edge.hpp.func-sort-c.html @@ -33,7 +33,7 @@ - + @@ -73,7 +73,7 @@ - +
  1
-  2
-  3
-  4
-  5
-  6
-  7
-  8
-  9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
- 37
- 38
- 39
- 40
- 41
- 42
- 43
- 44
- 45
- 46
- 47
- 48
- 49
- 50
- 51
- 52
- 53
- 54
- 55
- 56
- 57
- 58
- 59
- 60
- 61
- 62
- 63
- 64
- 65
- 66
- 67
- 68
- 69
- 70
- 71
- 72
- 73
- 74
- 75
- 76
- 77
- 78
- 79
- 80
- 81
- 82
- 83
- 84
- 85
- 86
- 87
- 88
- 89
- 90
- 91
- 92
- 93
- 94
- 95
- 96
- 97
- 98
- 99
-100
-101
-102
-103
-104
-105
-106
-107
-108
-109
-110
-111
-112
-113
-114
-115
-116
-117
-118
-119
-120
-121
-122
-123
-124
-125
-126
-127
-128
-129
-130
-131
-132
-133
-134
-135
-136
-137
-138
-139
-140
-141
-142
-143
-144
-145
-146
-147
-148
-149
-150
-151
-152
-153
-154
-155
-156
-157
-158
-159
-160
-161
-162
-163
-164
-165
-166
-167
-168
-169
-170
-171
-172
-173
-174
-175
-176
-177
-178
-179
-180
-181
-182
-183
-184
-185
-186
-187
-188
-189
-190
-191
-192
-193
-194
-195
-196
-197
// *****************************************************************************
+
   1
+   2
+   3
+   4
+   5
+   6
+   7
+   8
+   9
+  10
+  11
+  12
+  13
+  14
+  15
+  16
+  17
+  18
+  19
+  20
+  21
+  22
+  23
+  24
+  25
+  26
+  27
+  28
+  29
+  30
+  31
+  32
+  33
+  34
+  35
+  36
+  37
+  38
+  39
+  40
+  41
+  42
+  43
+  44
+  45
+  46
+  47
+  48
+  49
+  50
+  51
+  52
+  53
+  54
+  55
+  56
+  57
+  58
+  59
+  60
+  61
+  62
+  63
+  64
+  65
+  66
+  67
+  68
+  69
+  70
+  71
+  72
+  73
+  74
+  75
+  76
+  77
+  78
+  79
+  80
+  81
+  82
+  83
+  84
+  85
+  86
+  87
+  88
+  89
+  90
+  91
+  92
+  93
+  94
+  95
+  96
+  97
+  98
+  99
+ 100
+ 101
+ 102
+ 103
+ 104
+ 105
+ 106
+ 107
+ 108
+ 109
+ 110
+ 111
+ 112
+ 113
+ 114
+ 115
+ 116
+ 117
+ 118
+ 119
+ 120
+ 121
+ 122
+ 123
+ 124
+ 125
+ 126
+ 127
+ 128
+ 129
+ 130
+ 131
+ 132
+ 133
+ 134
+ 135
+ 136
+ 137
+ 138
+ 139
+ 140
+ 141
+ 142
+ 143
+ 144
+ 145
+ 146
+ 147
+ 148
+ 149
+ 150
+ 151
+ 152
+ 153
+ 154
+ 155
+ 156
+ 157
+ 158
+ 159
+ 160
+ 161
+ 162
+ 163
+ 164
+ 165
+ 166
+ 167
+ 168
+ 169
+ 170
+ 171
+ 172
+ 173
+ 174
+ 175
+ 176
+ 177
+ 178
+ 179
+ 180
+ 181
+ 182
+ 183
+ 184
+ 185
+ 186
+ 187
+ 188
+ 189
+ 190
+ 191
+ 192
+ 193
+ 194
+ 195
+ 196
+ 197
+ 198
+ 199
+ 200
+ 201
+ 202
+ 203
+ 204
+ 205
+ 206
+ 207
+ 208
+ 209
+ 210
+ 211
+ 212
+ 213
+ 214
+ 215
+ 216
+ 217
+ 218
+ 219
+ 220
+ 221
+ 222
+ 223
+ 224
+ 225
+ 226
+ 227
+ 228
+ 229
+ 230
+ 231
+ 232
+ 233
+ 234
+ 235
+ 236
+ 237
+ 238
+ 239
+ 240
+ 241
+ 242
+ 243
+ 244
+ 245
+ 246
+ 247
+ 248
+ 249
+ 250
+ 251
+ 252
+ 253
+ 254
+ 255
+ 256
+ 257
+ 258
+ 259
+ 260
+ 261
+ 262
+ 263
+ 264
+ 265
+ 266
+ 267
+ 268
+ 269
+ 270
+ 271
+ 272
+ 273
+ 274
+ 275
+ 276
+ 277
+ 278
+ 279
+ 280
+ 281
+ 282
+ 283
+ 284
+ 285
+ 286
+ 287
+ 288
+ 289
+ 290
+ 291
+ 292
+ 293
+ 294
+ 295
+ 296
+ 297
+ 298
+ 299
+ 300
+ 301
+ 302
+ 303
+ 304
+ 305
+ 306
+ 307
+ 308
+ 309
+ 310
+ 311
+ 312
+ 313
+ 314
+ 315
+ 316
+ 317
+ 318
+ 319
+ 320
+ 321
+ 322
+ 323
+ 324
+ 325
+ 326
+ 327
+ 328
+ 329
+ 330
+ 331
+ 332
+ 333
+ 334
+ 335
+ 336
+ 337
+ 338
+ 339
+ 340
+ 341
+ 342
+ 343
+ 344
+ 345
+ 346
+ 347
+ 348
+ 349
+ 350
+ 351
+ 352
+ 353
+ 354
+ 355
+ 356
+ 357
+ 358
+ 359
+ 360
+ 361
+ 362
+ 363
+ 364
+ 365
+ 366
+ 367
+ 368
+ 369
+ 370
+ 371
+ 372
+ 373
+ 374
+ 375
+ 376
+ 377
+ 378
+ 379
+ 380
+ 381
+ 382
+ 383
+ 384
+ 385
+ 386
+ 387
+ 388
+ 389
+ 390
+ 391
+ 392
+ 393
+ 394
+ 395
+ 396
+ 397
+ 398
+ 399
+ 400
+ 401
+ 402
+ 403
+ 404
+ 405
+ 406
+ 407
+ 408
+ 409
+ 410
+ 411
+ 412
+ 413
+ 414
+ 415
+ 416
+ 417
+ 418
+ 419
+ 420
+ 421
+ 422
+ 423
+ 424
+ 425
+ 426
+ 427
+ 428
+ 429
+ 430
+ 431
+ 432
+ 433
+ 434
+ 435
+ 436
+ 437
+ 438
+ 439
+ 440
+ 441
+ 442
+ 443
+ 444
+ 445
+ 446
+ 447
+ 448
+ 449
+ 450
+ 451
+ 452
+ 453
+ 454
+ 455
+ 456
+ 457
+ 458
+ 459
+ 460
+ 461
+ 462
+ 463
+ 464
+ 465
+ 466
+ 467
+ 468
+ 469
+ 470
+ 471
+ 472
+ 473
+ 474
+ 475
+ 476
+ 477
+ 478
+ 479
+ 480
+ 481
+ 482
+ 483
+ 484
+ 485
+ 486
+ 487
+ 488
+ 489
+ 490
+ 491
+ 492
+ 493
+ 494
+ 495
+ 496
+ 497
+ 498
+ 499
+ 500
+ 501
+ 502
+ 503
+ 504
+ 505
+ 506
+ 507
+ 508
+ 509
+ 510
+ 511
+ 512
+ 513
+ 514
+ 515
+ 516
+ 517
+ 518
+ 519
+ 520
+ 521
+ 522
+ 523
+ 524
+ 525
+ 526
+ 527
+ 528
+ 529
+ 530
+ 531
+ 532
+ 533
+ 534
+ 535
+ 536
+ 537
+ 538
+ 539
+ 540
+ 541
+ 542
+ 543
+ 544
+ 545
+ 546
+ 547
+ 548
+ 549
+ 550
+ 551
+ 552
+ 553
+ 554
+ 555
+ 556
+ 557
+ 558
+ 559
+ 560
+ 561
+ 562
+ 563
+ 564
+ 565
+ 566
+ 567
+ 568
+ 569
+ 570
+ 571
+ 572
+ 573
+ 574
+ 575
+ 576
+ 577
+ 578
+ 579
+ 580
+ 581
+ 582
+ 583
+ 584
+ 585
+ 586
+ 587
+ 588
+ 589
+ 590
+ 591
+ 592
+ 593
+ 594
+ 595
+ 596
+ 597
+ 598
+ 599
+ 600
+ 601
+ 602
+ 603
+ 604
+ 605
+ 606
+ 607
+ 608
+ 609
+ 610
+ 611
+ 612
+ 613
+ 614
+ 615
+ 616
+ 617
+ 618
+ 619
+ 620
+ 621
+ 622
+ 623
+ 624
+ 625
+ 626
+ 627
+ 628
+ 629
+ 630
+ 631
+ 632
+ 633
+ 634
+ 635
+ 636
+ 637
+ 638
+ 639
+ 640
+ 641
+ 642
+ 643
+ 644
+ 645
+ 646
+ 647
+ 648
+ 649
+ 650
+ 651
+ 652
+ 653
+ 654
+ 655
+ 656
+ 657
+ 658
+ 659
+ 660
+ 661
+ 662
+ 663
+ 664
+ 665
+ 666
+ 667
+ 668
+ 669
+ 670
+ 671
+ 672
+ 673
+ 674
+ 675
+ 676
+ 677
+ 678
+ 679
+ 680
+ 681
+ 682
+ 683
+ 684
+ 685
+ 686
+ 687
+ 688
+ 689
+ 690
+ 691
+ 692
+ 693
+ 694
+ 695
+ 696
+ 697
+ 698
+ 699
+ 700
+ 701
+ 702
+ 703
+ 704
+ 705
+ 706
+ 707
+ 708
+ 709
+ 710
+ 711
+ 712
+ 713
+ 714
+ 715
+ 716
+ 717
+ 718
+ 719
+ 720
+ 721
+ 722
+ 723
+ 724
+ 725
+ 726
+ 727
+ 728
+ 729
+ 730
+ 731
+ 732
+ 733
+ 734
+ 735
+ 736
+ 737
+ 738
+ 739
+ 740
+ 741
+ 742
+ 743
+ 744
+ 745
+ 746
+ 747
+ 748
+ 749
+ 750
+ 751
+ 752
+ 753
+ 754
+ 755
+ 756
+ 757
+ 758
+ 759
+ 760
+ 761
+ 762
+ 763
+ 764
+ 765
+ 766
+ 767
+ 768
+ 769
+ 770
+ 771
+ 772
+ 773
+ 774
+ 775
+ 776
+ 777
+ 778
+ 779
+ 780
+ 781
+ 782
+ 783
+ 784
+ 785
+ 786
+ 787
+ 788
+ 789
+ 790
+ 791
+ 792
+ 793
+ 794
+ 795
+ 796
+ 797
+ 798
+ 799
+ 800
+ 801
+ 802
+ 803
+ 804
+ 805
+ 806
+ 807
+ 808
+ 809
+ 810
+ 811
+ 812
+ 813
+ 814
+ 815
+ 816
+ 817
+ 818
+ 819
+ 820
+ 821
+ 822
+ 823
+ 824
+ 825
+ 826
+ 827
+ 828
+ 829
+ 830
+ 831
+ 832
+ 833
+ 834
+ 835
+ 836
+ 837
+ 838
+ 839
+ 840
+ 841
+ 842
+ 843
+ 844
+ 845
+ 846
+ 847
+ 848
+ 849
+ 850
+ 851
+ 852
+ 853
+ 854
+ 855
+ 856
+ 857
+ 858
+ 859
+ 860
+ 861
+ 862
+ 863
+ 864
+ 865
+ 866
+ 867
+ 868
+ 869
+ 870
+ 871
+ 872
+ 873
+ 874
+ 875
+ 876
+ 877
+ 878
+ 879
+ 880
+ 881
+ 882
+ 883
+ 884
+ 885
+ 886
+ 887
+ 888
+ 889
+ 890
+ 891
+ 892
+ 893
+ 894
+ 895
+ 896
+ 897
+ 898
+ 899
+ 900
+ 901
+ 902
+ 903
+ 904
+ 905
+ 906
+ 907
+ 908
+ 909
+ 910
+ 911
+ 912
+ 913
+ 914
+ 915
+ 916
+ 917
+ 918
+ 919
+ 920
+ 921
+ 922
+ 923
+ 924
+ 925
+ 926
+ 927
+ 928
+ 929
+ 930
+ 931
+ 932
+ 933
+ 934
+ 935
+ 936
+ 937
+ 938
+ 939
+ 940
+ 941
+ 942
+ 943
+ 944
+ 945
+ 946
+ 947
+ 948
+ 949
+ 950
+ 951
+ 952
+ 953
+ 954
+ 955
+ 956
+ 957
+ 958
+ 959
+ 960
+ 961
+ 962
+ 963
+ 964
+ 965
+ 966
+ 967
+ 968
+ 969
+ 970
+ 971
+ 972
+ 973
+ 974
+ 975
+ 976
+ 977
+ 978
+ 979
+ 980
+ 981
+ 982
+ 983
+ 984
+ 985
+ 986
+ 987
+ 988
+ 989
+ 990
+ 991
+ 992
+ 993
+ 994
+ 995
+ 996
+ 997
+ 998
+ 999
+1000
+1001
+1002
+1003
+1004
+1005
+1006
+1007
+1008
+1009
+1010
+1011
+1012
+1013
+1014
+1015
+1016
+1017
+1018
+1019
+1020
+1021
+1022
+1023
+1024
+1025
+1026
+1027
+1028
+1029
+1030
+1031
+1032
+1033
+1034
+1035
+1036
+1037
+1038
+1039
+1040
+1041
+1042
+1043
+1044
+1045
+1046
+1047
+1048
+1049
+1050
+1051
+1052
+1053
+1054
+1055
+1056
+1057
+1058
+1059
+1060
+1061
+1062
+1063
+1064
+1065
+1066
+1067
+1068
+1069
+1070
+1071
+1072
+1073
+1074
+1075
+1076
+1077
+1078
+1079
+1080
+1081
+1082
+1083
+1084
+1085
+1086
+1087
+1088
+1089
+1090
+1091
+1092
+1093
+1094
+1095
+1096
+1097
+1098
+1099
+1100
+1101
+1102
+1103
+1104
+1105
+1106
+1107
+1108
+1109
+1110
+1111
+1112
+1113
+1114
+1115
+1116
+1117
+1118
+1119
+1120
+1121
+1122
+1123
+1124
+1125
+1126
+1127
+1128
+1129
+1130
+1131
+1132
+1133
+1134
+1135
+1136
+1137
+1138
+1139
+1140
+1141
+1142
+1143
+1144
+1145
+1146
+1147
+1148
+1149
+1150
+1151
+1152
+1153
+1154
+1155
+1156
+1157
+1158
+1159
+1160
+1161
+1162
+1163
+1164
+1165
+1166
+1167
+1168
+1169
+1170
+1171
+1172
+1173
+1174
+1175
+1176
+1177
+1178
+1179
+1180
+1181
+1182
+1183
+1184
+1185
+1186
+1187
+1188
+1189
+1190
+1191
+1192
+1193
+1194
+1195
+1196
+1197
+1198
+1199
+1200
+1201
+1202
+1203
+1204
+1205
+1206
+1207
+1208
+1209
+1210
+1211
+1212
+1213
+1214
+1215
+1216
+1217
+1218
+1219
+1220
+1221
+1222
+1223
+1224
+1225
+1226
+1227
+1228
+1229
+1230
+1231
+1232
+1233
+1234
+1235
+1236
+1237
+1238
+1239
+1240
+1241
+1242
+1243
+1244
+1245
+1246
+1247
+1248
+1249
+1250
+1251
+1252
+1253
+1254
+1255
+1256
+1257
+1258
+1259
+1260
+1261
+1262
+1263
+1264
+1265
+1266
+1267
+1268
+1269
+1270
+1271
+1272
+1273
+1274
+1275
+1276
+1277
+1278
+1279
+1280
+1281
+1282
+1283
+1284
+1285
+1286
+1287
+1288
+1289
+1290
+1291
+1292
+1293
+1294
+1295
+1296
+1297
+1298
+1299
+1300
+1301
+1302
+1303
+1304
+1305
+1306
+1307
+1308
+1309
+1310
+1311
+1312
+1313
+1314
+1315
+1316
+1317
+1318
+1319
+1320
+1321
+1322
+1323
+1324
+1325
+1326
+1327
+1328
+1329
+1330
+1331
+1332
+1333
+1334
+1335
+1336
+1337
+1338
+1339
+1340
+1341
+1342
+1343
+1344
+1345
+1346
+1347
+1348
+1349
+1350
+1351
+1352
+1353
+1354
+1355
+1356
+1357
+1358
+1359
+1360
+1361
+1362
+1363
+1364
+1365
+1366
+1367
+1368
+1369
+1370
+1371
+1372
+1373
+1374
+1375
+1376
+1377
+1378
+1379
+1380
+1381
+1382
+1383
+1384
+1385
+1386
+1387
+1388
+1389
+1390
+1391
+1392
+1393
+1394
+1395
+1396
+1397
+1398
+1399
+1400
+1401
+1402
+1403
+1404
+1405
+1406
+1407
+1408
+1409
+1410
+1411
+1412
+1413
+1414
+1415
+1416
+1417
+1418
+1419
+1420
+1421
+1422
+1423
+1424
+1425
+1426
+1427
+1428
+1429
+1430
+1431
+1432
+1433
+1434
+1435
+1436
+1437
+1438
+1439
+1440
+1441
+1442
+1443
+1444
+1445
+1446
+1447
+1448
+1449
+1450
+1451
+1452
+1453
+1454
+1455
+1456
+1457
+1458
+1459
+1460
+1461
+1462
+1463
+1464
+1465
+1466
+1467
+1468
+1469
+1470
+1471
+1472
+1473
+1474
+1475
+1476
+1477
+1478
+1479
+1480
+1481
+1482
+1483
+1484
+1485
+1486
+1487
+1488
+1489
+1490
+1491
+1492
+1493
+1494
+1495
+1496
+1497
+1498
+1499
+1500
+1501
+1502
+1503
+1504
+1505
+1506
+1507
+1508
+1509
+1510
+1511
+1512
+1513
+1514
+1515
+1516
+1517
+1518
+1519
+1520
+1521
+1522
+1523
+1524
+1525
+1526
+1527
+1528
+1529
+1530
+1531
+1532
+1533
+1534
+1535
+1536
+1537
+1538
+1539
+1540
+1541
+1542
+1543
+1544
+1545
+1546
+1547
+1548
+1549
+1550
+1551
+1552
+1553
+1554
+1555
+1556
+1557
+1558
+1559
+1560
+1561
+1562
+1563
+1564
+1565
+1566
+1567
+1568
+1569
+1570
+1571
+1572
+1573
+1574
+1575
+1576
+1577
+1578
+1579
+1580
+1581
+1582
+1583
+1584
+1585
+1586
+1587
+1588
+1589
+1590
+1591
+1592
+1593
+1594
+1595
+1596
+1597
+1598
+1599
+1600
+1601
+1602
+1603
+1604
+1605
+1606
+1607
+1608
+1609
+1610
+1611
+1612
// *****************************************************************************
 /*!
-  \file      src/PDE/MultiMat/Problem/BoxInitialization.hpp
+  \file      src/Inciter/ALECG.cpp
   \copyright 2012-2015 J. Bakosi,
              2016-2018 Los Alamos National Security, LLC.,
              2019-2021 Triad National Security, LLC.
              All rights reserved. See the LICENSE file for details.
-  \brief     User-defined box initialization
-  \details   This file defines functions for initializing solutions for
-    compressible multi-material equations inside the user-defined box.
-*/
-// *****************************************************************************
-#ifndef MultiMatBoxInitialization_h
-#define MultiMatBoxInitialization_h
-
-#include "Fields.hpp"
-#include "EoS/EOS.hpp"
-#include "ContainerUtil.hpp"
-#include "MultiMat/MultiMatIndexing.hpp"
-
-namespace inciter {
-
-using ncomp_t = tk::ncomp_t;
-
-template< class B >
-void initializeBox( const std::vector< EOS >& mat_blk,
-                    tk::real V_ex,
-                    tk::real t,
-                    const B& b,
-                    tk::real bgpreic,
-                    tk::real bgtempic,
-                    std::vector< tk::real >& s )
-// *****************************************************************************
-// Set the solution in the user-defined IC box/mesh block
-//! \tparam B IC-block type to operate, ctr::box, or ctr::meshblock
-//! \param[in] V_ex Exact box volume
-//! \param[in] t Physical time
-//! \param[in] b IC box configuration to use
-//! \param[in] bgpreic Background pressure user input
-//! \param[in] bgtempic Background temperature user input
-//! \param[in,out] s Solution vector that is set to box ICs
-//! \details This function sets the fluid density and total specific energy
-//!   within a box initial condition, configured by the user. If the user
-//!   is specified a box where mass is specified, we also assume here that
-//!   internal energy content (energy per unit volume) is also
-//!   specified. Specific internal energy (energy per unit mass) is then
-//!   computed here (and added to the kinetic energy) from the internal
-//!   energy per unit volume by multiplying it with the total box volume
-//!   and dividing it by the total mass of the material in the box.
-//!   Example (SI) units of the quantities involved:
-//!    * internal energy content (energy per unit volume): J/m^3
-//!    * specific energy (internal energy per unit mass): J/kg
-// *****************************************************************************
-{
-  auto nmat = g_inputdeck.get< tag::multimat, tag::nmat >();
-
-  const auto& solidx = g_inputdeck.get< tag::matidxmap, tag::solidx >();
-
-  const auto& initiate = b.template get< tag::initiate >();
-
-  // get material id in box (offset by 1, since input deck uses 1-based ids)
-  std::size_t boxmatid = b.template get< tag::materialid >() - 1;
-  const auto& boxvel = b.template get< tag::velocity >();
-  auto boxpre = b.template get< tag::pressure >();
-  auto boxene = b.template get< tag::energy >();
-  auto boxtemp = b.template get< tag::temperature >();
-  auto boxmas = b.template get< tag::mass >();
-  auto boxenc = b.template get< tag::energy_content >();
-
-  auto alphamin = 1.0e-12;
-
-  // [I] Compute the states inside the IC box/block based on the type of user
-  // input.
-
-  // material volume fractions
-  for (std::size_t k=0; k<nmat; ++k) {
-    if (k == boxmatid) {
-      s[volfracIdx(nmat,k)] = 1.0 - (static_cast< tk::real >(nmat-1))*alphamin;
-    }
-    else {
-      s[volfracIdx(nmat,k)] = alphamin;
-    }
-  }
-  // material states (density, pressure, velocity)
-  tk::real u = 0.0, v = 0.0, w = 0.0, spi(0.0), pr(0.0), tmp(0.0), rbulk(0.0);
-  std::vector< tk::real > rhok(nmat, 0.0);
-  // 1. User-specified mass, specific energy (J/m^3) and volume of box
-  if (boxmas > 0.0) {
-    if (boxenc <= 1e-12) Throw( "Box energy content must be nonzero" );<--- If condition 'boxenc<=1e-12' is true, the function will return/exit
-    // determine density and energy of material in the box
-    rhok[boxmatid] = boxmas / V_ex;
-    spi = boxenc / rhok[boxmatid];
-
-    // Determine pressure and temperature
-    auto boxmat_vf = s[volfracIdx(nmat,boxmatid)];
-
-    // Since initiate type 'linear' assigns the background IC values to all
-    // nodes within a box at initialization (followed by adding a time-dependent
-    // energy source term representing a propagating wave-front), the pressure
-    // in the box needs to be set to background pressure.
-    if (initiate == ctr::InitiateType::LINEAR && t < 1e-12) {
-      if (boxmas <= 1e-12 || boxenc <= 1e-12 || bgpreic <= 1e-12 ||<--- Testing identical condition 'boxenc<=1e-12'
-        bgtempic <= 1e-12)
-        Throw("Box mass, energy content, background pressure and background "
-          "temperature must be specified for IC with linear propagating source");
-
-      pr = bgpreic;
-      auto te = mat_blk[boxmatid].compute< EOS::totalenergy >(
-        rhok[boxmatid], u, v, w, pr);
-      tmp = mat_blk[boxmatid].compute< EOS::temperature >(
-        boxmat_vf*rhok[boxmatid], u, v, w, boxmat_vf*te, boxmat_vf );
-
-      // if the above density and pressure lead to an invalid thermodynamic
-      // state (negative temperature/energy), change temperature to background
-      // temperature and use corresponding density.
-      if (tmp < 0.0 || te < 0.0) {
-        tmp = bgtempic;
-        rhok[boxmatid] = mat_blk[boxmatid].compute< EOS::density >(pr, tmp);
-        spi = boxenc / rhok[boxmatid];
-      }
-    }
-    // For initiate type 'impulse', pressure and temperature are determined from
-    // energy content that needs to be dumped into the box at IC.
-    else if (initiate == ctr::InitiateType::IMPULSE) {
-      pr = mat_blk[boxmatid].compute< EOS::pressure >(
-        boxmat_vf*rhok[boxmatid], u, v, w, boxmat_vf*rhok[boxmatid]*spi,
-        boxmat_vf, boxmatid );
-      tmp = mat_blk[boxmatid].compute< EOS::temperature >(
-        boxmat_vf*rhok[boxmatid], u, v, w, boxmat_vf*rhok[boxmatid]*spi,
-        boxmat_vf );
-    }
-    else Throw( "IC box initiate type not implemented for multimat" );
-
-    // find density of trace material quantities in the box based on pressure
-    for (std::size_t k=0; k<nmat; ++k) {
-      if (k != boxmatid) {
-        rhok[k] = mat_blk[k].compute< EOS::density >(pr, tmp);
-      }
-    }
-  }
-  // 2. User-specified temperature, pressure and velocity in box
-  else {
-    for (std::size_t k=0; k<nmat; ++k) {
-      rhok[k] = mat_blk[k].compute< EOS::density >(boxpre, boxtemp);
-    }
-    if (boxvel.size() == 3) {
-      u = boxvel[0];
-      v = boxvel[1];
-      w = boxvel[2];
-    }
-    if (boxpre > 0.0) {
-      pr = boxpre;
-    }
-    if (boxene > 0.0) {
-      Throw("IC-box with specified energy not set up for multimat");
-    }
-  }
-  // bulk density
-  for (std::size_t k=0; k<nmat; ++k) rbulk += s[volfracIdx(nmat,k)]*rhok[k];
-
-  // [II] Finally initialize the solution vector
-  for (std::size_t k=0; k<nmat; ++k) {
-    // partial density
-    s[densityIdx(nmat,k)] = s[volfracIdx(nmat,k)] * rhok[k];
-    // total specific energy
-    if (boxmas > 0.0 && k == boxmatid &&
-      initiate == ctr::InitiateType::IMPULSE) {
-      s[energyIdx(nmat,k)] = s[volfracIdx(nmat,k)] * rhok[k] * spi;
-    }
-    else {
-      // TEMP: Eventually we would need to initialize gk from control file
-      std::array< std::array< tk::real, 3 >, 3 > gk;
-      if (solidx[k] > 0) {
-        for (std::size_t i=0; i<3; ++i) {
-          for (std::size_t j=0; j<3; ++j) {
-            if (i==j) gk[i][j] = 1.0;
-            else gk[i][j] = 0.0;
-            s[deformIdx(nmat,solidx[k],i,j)] = gk[i][j];
-          }
-        }
-      }
-      else {
-        gk = {{}};
-      }
-      s[energyIdx(nmat,k)] = s[volfracIdx(nmat,k)] *
-        mat_blk[k].compute< EOS::totalenergy >( rhok[k], u, v, w, pr, gk );
-    }
-  }
-  // bulk momentum
-  s[momentumIdx(nmat,0)] = rbulk * u;
-  s[momentumIdx(nmat,1)] = rbulk * v;
-  s[momentumIdx(nmat,2)] = rbulk * w;
-}
-
-} //inciter::
-
-#endif // MultiMatBoxInitialization_h
+  \brief     ALECG for a PDE system with continuous Galerkin + ALE + RK
+  \details   ALECG advances a system of partial differential equations (PDEs)
+    using a continuous Galerkin (CG) finite element (FE) spatial discretization
+    (using linear shapefunctions on tetrahedron elements) combined with a
+    Runge-Kutta (RK) time stepping scheme in the arbitrary Eulerian-Lagrangian
+    reference frame.
+  \see The documentation in ALECG.hpp.
+*/
+// *****************************************************************************
+
+#include "QuinoaBuildConfig.hpp"
+#include "ALECG.hpp"
+#include "Vector.hpp"
+#include "Reader.hpp"
+#include "ContainerUtil.hpp"
+#include "UnsMesh.hpp"
+#include "ExodusIIMeshWriter.hpp"
+#include "Inciter/InputDeck/InputDeck.hpp"
+#include "DerivedData.hpp"
+#include "CGPDE.hpp"
+#include "Discretization.hpp"
+#include "DiagReducer.hpp"
+#include "NodeBC.hpp"
+#include "Refiner.hpp"
+#include "Reorder.hpp"
+#include "Around.hpp"
+#include "CGPDE.hpp"
+#include "Integrate/Mass.hpp"
+#include "FieldOutput.hpp"
+
+namespace inciter {
+
+extern ctr::InputDeck g_inputdeck;
+extern std::vector< CGPDE > g_cgpde;
+
+//! Runge-Kutta coefficients
+static const std::array< tk::real, 3 > rkcoef{{ 1.0/3.0, 1.0/2.0, 1.0 }};
+
+} // inciter::
+
+using inciter::ALECG;
+
+ALECG::ALECG( const CProxy_Discretization& disc,
+              const CProxy_Ghosts&,
+              const std::map< int, std::vector< std::size_t > >& bface,
+              const std::map< int, std::vector< std::size_t > >& bnode,
+              const std::vector< std::size_t >& triinpoel ) :
+  m_disc( disc ),
+  m_nsol( 0 ),
+  m_ngrad( 0 ),
+  m_nrhs( 0 ),
+  m_nbnorm( 0 ),
+  m_ndfnorm( 0 ),
+  m_nmblk( 0 ),
+  m_bnode( bnode ),
+  m_bface( bface ),
+  m_triinpoel( tk::remap( triinpoel, Disc()->Lid() ) ),
+  m_bndel( Disc()->bndel() ),
+  m_dfnorm(),
+  m_dfnormc(),
+  m_dfn(),
+  m_esup( tk::genEsup( Disc()->Inpoel(), 4 ) ),
+  m_psup( tk::genPsup( Disc()->Inpoel(), 4, m_esup ) ),
+  m_u( Disc()->Gid().size(),
+       g_inputdeck.get< tag::ncomp >() ),
+  m_un( m_u.nunk(), m_u.nprop() ),
+  m_rhs( m_u.nunk(), m_u.nprop() ),
+  m_rhsc(),
+  m_chBndGrad( Disc()->Bid().size(), m_u.nprop()*3 ),
+  m_dirbc(),
+  m_chBndGradc(),
+  m_diag(),
+  m_bnorm(),
+  m_bnormc(),
+  m_symbcnodes(),
+  m_farfieldbcnodes(),
+  m_symbctri(),
+  m_timedepbcnodes(),
+  m_timedepbcFn(),
+  m_stage( 0 ),
+  m_boxnodes(),
+  m_edgenode(),
+  m_edgeid(),
+  m_dtp( m_u.nunk(), 0.0 ),
+  m_tp( m_u.nunk(), g_inputdeck.get< tag::t0 >() ),
+  m_finished( 0 ),
+  m_newmesh( 0 ),
+  m_refinedmesh( 0 ),
+  m_nusermeshblk( 0 ),
+  m_nodeblockid(),
+  m_nodeblockidc()
+// *****************************************************************************
+//  Constructor
+//! \param[in] disc Discretization proxy
+//! \param[in] bface Boundary-faces mapped to side sets used in the input file
+//! \param[in] bnode Boundary-node lists mapped to side sets used in input file
+//! \param[in] triinpoel Boundary-face connectivity where BCs set (global ids)
+// *****************************************************************************
+//! [Constructor]
+{
+  usesAtSync = true;    // enable migration at AtSync
+
+  auto d = Disc();
+
+  // Perform optional operator-access-pattern mesh node reordering
+  if (g_inputdeck.get< tag::operator_reorder >()) {
+
+    // Create new local ids based on access pattern of PDE operators
+    std::unordered_map< std::size_t, std::size_t > map;
+    std::size_t n = 0;
+
+    for (std::size_t p=0; p<m_u.nunk(); ++p) {  // for each point p
+      if (map.find(p) == end(map)) map[p] = n++;<--- Searching before insertion is not necessary.
+      for (auto q : tk::Around(m_psup,p)) {     // for each edge p-q
+        if (map.find(q) == end(map)) map[q] = n++;<--- Searching before insertion is not necessary.
+      }
+    }
+
+    Assert( map.size() == d->Gid().size(), "Map size mismatch" );
+
+    // Remap data in bound Discretization object
+    d->remap( map );
+    // Recompute elements surrounding points
+    m_esup = tk::genEsup( d->Inpoel(), 4 );
+    // Recompute points surrounding points
+    m_psup = tk::genPsup( d->Inpoel(), 4, m_esup );
+    // Remap boundary triangle face connectivity
+    tk::remap( m_triinpoel, map );
+  }
+
+  // Query/update boundary-conditions-related data structures from user input
+  queryBnd();
+
+  // Activate SDAG wait for initially computing normals, and mesh blocks
+  thisProxy[ thisIndex ].wait4norm();
+  thisProxy[ thisIndex ].wait4meshblk();
+
+  d->comfinal();
+
+}
+//! [Constructor]
+
+void
+ALECG::queryBnd()
+// *****************************************************************************
+// Query/update boundary-conditions-related data structures from user input
+// *****************************************************************************
+{
+  auto d = Disc();
+
+  // Query and match user-specified Dirichlet boundary conditions to side sets
+  const auto steady = g_inputdeck.get< tag::steady_state >();
+  if (steady) for (auto& deltat : m_dtp) deltat *= rkcoef[m_stage];<--- Consider using std::transform algorithm instead of a raw loop.
+  m_dirbc = match( d->MeshId(), m_u.nprop(), d->T(), rkcoef[m_stage] * d->Dt(),
+                   m_tp, m_dtp, d->Coord(), d->Lid(), m_bnode,
+                   /* increment = */ false );
+  if (steady) for (auto& deltat : m_dtp) deltat /= rkcoef[m_stage];<--- Consider using std::transform algorithm instead of a raw loop.
+
+  // Prepare unique set of symmetry BC nodes
+  auto sym = d->bcnodes< tag::symmetry >( m_bface, m_triinpoel );
+  for (const auto& [s,nodes] : sym)
+    m_symbcnodes.insert( begin(nodes), end(nodes) );
+
+  // Prepare unique set of farfield BC nodes
+  auto far = d->bcnodes< tag::farfield >( m_bface, m_triinpoel );
+  for (const auto& [s,nodes] : far)
+    m_farfieldbcnodes.insert( begin(nodes), end(nodes) );
+
+  // If farfield BC is set on a node, will not also set symmetry BC
+  for (auto fn : m_farfieldbcnodes) m_symbcnodes.erase(fn);
+
+  // Prepare boundary nodes contiguously accessible from a triangle-face loop
+  m_symbctri.resize( m_triinpoel.size()/3, 0 );
+  for (std::size_t e=0; e<m_triinpoel.size()/3; ++e)
+    if (m_symbcnodes.find(m_triinpoel[e*3+0]) != end(m_symbcnodes))
+      m_symbctri[e] = 1;
+
+  // Prepare unique set of time dependent BC nodes
+  m_timedepbcnodes.clear();
+  m_timedepbcFn.clear();
+  const auto& timedep =
+    g_inputdeck.get< tag::bc >()[d->MeshId()].get< tag::timedep >();
+  if (!timedep.empty()) {
+    m_timedepbcnodes.resize(timedep.size());
+    m_timedepbcFn.resize(timedep.size());
+    std::size_t ib=0;
+    for (const auto& bndry : timedep) {
+      std::unordered_set< std::size_t > nodes;
+      for (const auto& s : bndry.template get< tag::sideset >()) {
+        auto k = m_bnode.find(static_cast<int>(s));
+        if (k != end(m_bnode)) {
+          for (auto g : k->second) {      // global node ids on side set
+            nodes.insert( tk::cref_find(d->Lid(),g) );
+          }
+        }
+      }
+      m_timedepbcnodes[ib].insert( begin(nodes), end(nodes) );
+
+      // Store user defined discrete function in time. This is done in the same
+      // loop as the BC nodes, so that the indices for the two vectors
+      // m_timedepbcnodes and m_timedepbcFn are consistent with each other
+      auto fn = bndry.template get< tag::fn >();
+      for (std::size_t ir=0; ir<fn.size()/6; ++ir) {
+        m_timedepbcFn[ib].push_back({{ fn[ir*6+0], fn[ir*6+1], fn[ir*6+2],
+          fn[ir*6+3], fn[ir*6+4], fn[ir*6+5] }});
+      }
+      ++ib;
+    }
+  }
+
+  Assert(m_timedepbcFn.size() == m_timedepbcnodes.size(), "Incorrect number of "
+    "time dependent functions.");
+
+  // Query ALE mesh velocity boundary condition node lists and node lists at
+  // which ALE moves boundaries
+  d->meshvelBnd( m_bface, m_bnode, m_triinpoel );
+}
+
+void
+ALECG::norm()
+// *****************************************************************************
+// Start (re-)computing boundary point-, and dual-face normals
+// *****************************************************************************
+{
+  auto d = Disc();
+
+  // Query nodes at which symmetry BCs are specified
+  auto bn = d->bcnodes< tag::symmetry >( m_bface, m_triinpoel );
+
+  // Query nodes at which farfield BCs are specified
+  auto far = d->bcnodes< tag::farfield >( m_bface, m_triinpoel );
+  // Merge BC data where boundary-point normals are required
+  for (const auto& [s,n] : far) bn[s].insert( begin(n), end(n) );
+
+  // Query nodes at which mesh velocity symmetry BCs are specified
+  std::unordered_map<int, std::unordered_set< std::size_t >> ms;
+  for (const auto& s : g_inputdeck.get< tag::ale, tag::symmetry >()) {
+    auto k = m_bface.find(static_cast<int>(s));
+    if (k != end(m_bface)) {
+      auto& n = ms[ k->first ];
+      for (auto f : k->second) {
+        n.insert( m_triinpoel[f*3+0] );
+        n.insert( m_triinpoel[f*3+1] );
+        n.insert( m_triinpoel[f*3+2] );
+      }
+    }
+  }
+  // Merge BC data where boundary-point normals are required
+  for (const auto& [s,n] : ms) bn[s].insert( begin(n), end(n) );
+
+  // Compute boundary point normals
+  bnorm( bn );
+
+  // Compute dual-face normals associated to edges
+  dfnorm();
+}
+
+std::array< tk::real, 3 >
+ALECG::edfnorm( const tk::UnsMesh::Edge& edge,
+                const std::unordered_map< tk::UnsMesh::Edge,
+                        std::vector< std::size_t >,
+                        tk::UnsMesh::Hash<2>, tk::UnsMesh::Eq<2> >& esued )
+const
+// *****************************************************************************
+//  Compute normal of dual-mesh associated to edge
+//! \param[in] edge Edge whose dual-face normal to compute given by local ids
+//! \param[in] esued Elements surrounding edges
+//! \return Dual-face normal for edge
+// *****************************************************************************
+{
+  auto d = Disc();
+  const auto& inpoel = d->Inpoel();
+  const auto& coord = d->Coord();
+  const auto& x = coord[0];
+  const auto& y = coord[1];
+  const auto& z = coord[2];
+
+  std::array< tk::real, 3 > n{ 0.0, 0.0, 0.0 };
+
+  for (auto e : tk::cref_find(esued,edge)) {
+    // access node IDs
+    const std::array< std::size_t, 4 >
+      N{ inpoel[e*4+0], inpoel[e*4+1], inpoel[e*4+2], inpoel[e*4+3] };
+    // compute element Jacobi determinant
+    const std::array< tk::real, 3 >
+      ba{{ x[N[1]]-x[N[0]], y[N[1]]-y[N[0]], z[N[1]]-z[N[0]] }},
+      ca{{ x[N[2]]-x[N[0]], y[N[2]]-y[N[0]], z[N[2]]-z[N[0]] }},
+      da{{ x[N[3]]-x[N[0]], y[N[3]]-y[N[0]], z[N[3]]-z[N[0]] }};
+    const auto J = tk::triple( ba, ca, da );        // J = 6V
+    Assert( J > 0, "Element Jacobian non-positive" );
+    // shape function derivatives, nnode*ndim [4][3]
+    std::array< std::array< tk::real, 3 >, 4 > grad;
+    grad[1] = tk::crossdiv( ca, da, J );
+    grad[2] = tk::crossdiv( da, ba, J );
+    grad[3] = tk::crossdiv( ba, ca, J );
+    for (std::size_t i=0; i<3; ++i)
+      grad[0][i] = -grad[1][i]-grad[2][i]-grad[3][i];
+    // sum normal contributions
+    // The constant 1/48: Eq (12) from Waltz et al. Computers & fluids (92) 2014
+    // The result of the integral of shape function N on a tet is V/4.
+    // This can be written as J/(6*4). Eq (12) has a 1/2 multiplier.
+    // This leads to J/48.
+    auto J48 = J/48.0;
+    for (const auto& [a,b] : tk::lpoed) {
+      auto s = tk::orient( {N[a],N[b]}, edge );
+      for (std::size_t j=0; j<3; ++j)
+        n[j] += J48 * s * (grad[a][j] - grad[b][j]);
+    }
+  }
+
+  return n;
+}
+
+void
+ALECG::dfnorm()
+// *****************************************************************************
+// Compute dual-face normals associated to edges
+// *****************************************************************************
+{
+  auto d = Disc();
+  const auto& inpoel = d->Inpoel();
+  const auto& gid = d->Gid();
+
+  // compute derived data structures
+  auto esued = tk::genEsued( inpoel, 4, tk::genEsup( inpoel, 4 ) );
+
+  // Compute dual-face normals for domain edges
+  for (std::size_t p=0; p<gid.size(); ++p)    // for each point p
+    for (auto q : tk::Around(m_psup,p))       // for each edge p-q
+      if (gid[p] < gid[q])
+        m_dfnorm[{gid[p],gid[q]}] = edfnorm( {p,q}, esued );
+
+  // Send our dual-face normal contributions to neighbor chares
+  if (d->EdgeCommMap().empty())
+    comdfnorm_complete();
+  else {
+    for (const auto& [c,edges] : d->EdgeCommMap()) {
+      decltype(m_dfnorm) exp;
+      for (const auto& e : edges) exp[e] = tk::cref_find(m_dfnorm,e);
+      thisProxy[c].comdfnorm( exp );
+    }
+  }
+
+  owndfnorm_complete();
+}
+
+void
+ALECG::comdfnorm( const std::unordered_map< tk::UnsMesh::Edge,
+                    std::array< tk::real, 3 >,
+                    tk::UnsMesh::Hash<2>, tk::UnsMesh::Eq<2> >& dfnorm )
+// *****************************************************************************
+// Receive contributions to dual-face normals on chare-boundaries
+//! \param[in] dfnorm Incoming partial sums of dual-face normals associated to
+//!   chare-boundary edges
+// *****************************************************************************
+{
+  // Buffer up inccoming contributions to dual-face normals
+  for (const auto& [e,n] : dfnorm) {
+    auto& dfn = m_dfnormc[e];
+    dfn[0] += n[0];
+    dfn[1] += n[1];
+    dfn[2] += n[2];
+  }
+
+  if (++m_ndfnorm == Disc()->EdgeCommMap().size()) {
+    m_ndfnorm = 0;
+    comdfnorm_complete();
+  }
+}
+
+void
+ALECG::bnorm( const std::unordered_map< int,
+                std::unordered_set< std::size_t > >& bcnodes )
+// *****************************************************************************
+//  Compute boundary point normals
+//! \param[in] bcnodes Local node ids associated to side set ids at which BCs
+//!    are set that require normals
+//*****************************************************************************
+{
+  auto d = Disc();
+
+  m_bnorm = cg::bnorm( m_bface, m_triinpoel, d->Coord(), d->Gid(), bcnodes );
+
+  // Send our nodal normal contributions to neighbor chares
+  if (d->NodeCommMap().empty())
+    comnorm_complete();
+  else
+    for (const auto& [ neighborchare, sharednodes ] : d->NodeCommMap()) {
+      std::unordered_map< int,
+        std::unordered_map< std::size_t, std::array< tk::real, 4 > > > exp;
+      for (auto i : sharednodes) {
+        for (const auto& [s,norms] : m_bnorm) {
+          auto j = norms.find(i);
+          if (j != end(norms)) exp[s][i] = j->second;
+        }
+      }
+      thisProxy[ neighborchare ].comnorm( exp );
+    }
+
+  ownnorm_complete();
+}
+
+void
+ALECG::comnorm( const std::unordered_map< int,
+  std::unordered_map< std::size_t, std::array< tk::real, 4 > > >& innorm )
+// *****************************************************************************
+// Receive boundary point normals on chare-boundaries
+//! \param[in] innorm Incoming partial sums of boundary point normal
+//!   contributions to normals (first 3 components), inverse distance squared
+//!   (4th component), associated to side set ids
+// *****************************************************************************
+{
+  // Buffer up incoming boundary-point normal vector contributions
+  for (const auto& [s,norms] : innorm) {
+    auto& bnorms = m_bnormc[s];
+    for (const auto& [p,n] : norms) {
+      auto& bnorm = bnorms[p];
+      bnorm[0] += n[0];
+      bnorm[1] += n[1];
+      bnorm[2] += n[2];
+      bnorm[3] += n[3];
+    }
+  }
+
+  if (++m_nbnorm == Disc()->NodeCommMap().size()) {
+    m_nbnorm = 0;
+    comnorm_complete();
+  }
+}
+
+void
+ALECG::registerReducers()
+// *****************************************************************************
+//  Configure Charm++ reduction types initiated from this chare array
+//! \details Since this is a [initnode] routine, the runtime system executes the
+//!   routine exactly once on every logical node early on in the Charm++ init
+//!   sequence. Must be static as it is called without an object. See also:
+//!   Section "Initializations at Program Startup" at in the Charm++ manual
+//!   http://charm.cs.illinois.edu/manuals/html/charm++/manual.html.
+// *****************************************************************************
+{
+  NodeDiagnostics::registerReducers();
+}
+
+void
+ALECG::ResumeFromSync()
+// *****************************************************************************
+//  Return from migration
+//! \details This is called when load balancing (LB) completes. The presence of
+//!   this function does not affect whether or not we block on LB.
+// *****************************************************************************
+{
+  if (Disc()->It() == 0) Throw( "it = 0 in ResumeFromSync()" );
+
+  if (!g_inputdeck.get< tag::cmd, tag::nonblocking >()) next();
+}
+
+//! [setup]
+void
+ALECG::setup()
+// *****************************************************************************
+// Start setup for solution
+// *****************************************************************************
+{
+  auto d = Disc();
+
+  // Determine nodes inside user-defined IC box
+  g_cgpde[d->MeshId()].IcBoxNodes( d->Coord(), d->Inpoel(),
+    d->ElemBlockId(), m_boxnodes, m_nodeblockid, m_nusermeshblk );
+
+  // Communicate mesh block nodes to other chares on chare-boundary
+  if (d->NodeCommMap().empty())        // in serial we are done
+    comblk_complete();
+  else // send mesh block information to chare-boundary nodes to fellow chares
+    for (const auto& [c,n] : d->NodeCommMap()) {
+      // data structure assigning block ids (set of values) to nodes (index).
+      // although nodeblockid is a map with key-blockid and value-nodeid, the
+      // sending data structure has to be inverted, because of how communication
+      // data is handled.
+      std::vector< std::set< std::size_t > > mb( n.size() );
+      std::size_t j = 0;
+      for (auto i : n) {
+        for (const auto& [blid, ndset] : m_nodeblockid) {
+          // if node was found in a block, add to send-data
+          if (ndset.find(tk::cref_find(d->Lid(),i)) != ndset.end())
+            mb[j].insert(blid);
+        }
+        if (m_nusermeshblk > 0)
+          Assert(mb[j].size() > 0, "Sending no block data for node");
+        ++j;
+      }
+      thisProxy[c].comblk( std::vector<std::size_t>(begin(n),end(n)), mb );
+    }
+
+  ownblk_complete();
+}
+
+void
+ALECG::comblk( const std::vector< std::size_t >& gid,
+               const std::vector< std::set< std::size_t > >& mb )
+// *****************************************************************************
+//  Receive mesh block information for nodes on chare-boundaries
+//! \param[in] gid Global mesh node IDs at which we receive RHS contributions
+//! \param[in] mb Block ids for each node on chare-boundaries
+//! \details This function receives mesh block information for nodes on chare
+//!   boundaries. While m_nodeblockid stores block information for own nodes,
+//!   m_nodeblockidc collects the neighbor chare information during
+//!   communication. This way work on m_nodeblockid and m_nodeblockidc is
+//!   overlapped. The two are combined in continueSetup().
+// *****************************************************************************
+{
+  Assert( mb.size() == gid.size(), "Size mismatch" );
+
+  for (std::size_t i=0; i<gid.size(); ++i) {
+    for (const auto& blid : mb[i]) {
+      m_nodeblockidc[blid].insert(gid[i]);
+    }
+  }
+
+  // When we have heard from all chares we communicate with, this chare is done
+  if (++m_nmblk == Disc()->NodeCommMap().size()) {
+    m_nmblk = 0;
+    comblk_complete();
+  }
+}
+
+void
+ALECG::continueSetup()
+// *****************************************************************************
+// Continue setup for solution, after communication for mesh blocks
+// *****************************************************************************
+{
+  auto d = Disc();
+
+  // Combine own and communicated mesh block information
+  for (const auto& [blid, ndset] : m_nodeblockidc) {
+    for (const auto& i : ndset) {
+      auto lid = tk::cref_find(d->Lid(), i);
+      m_nodeblockid[blid].insert(lid);
+    }
+  }
+
+  // clear receive buffer
+  tk::destroy(m_nodeblockidc);
+
+  // Compute volume of user-defined box IC
+  d->boxvol( m_boxnodes, m_nodeblockid, m_nusermeshblk );
+
+  // Query time history field output labels from all PDEs integrated
+  const auto& hist_points = g_inputdeck.get< tag::history_output, tag::point >();
+  if (!hist_points.empty()) {
+    std::vector< std::string > histnames;
+    auto n = g_cgpde[d->MeshId()].histNames();
+    histnames.insert( end(histnames), begin(n), end(n) );
+    d->histheader( std::move(histnames) );
+  }
+}
+//! [setup]
+
+void
+ALECG::volumetric( tk::Fields& u, const std::vector< tk::real >& v )
+// *****************************************************************************
+//  Multiply solution with mesh volume
+//! \param[in,out] u Solution vector
+//! \param[in] v Volume to multiply with
+// *****************************************************************************
+{
+  Assert( v.size() == u.nunk(), "Size mismatch" );
+
+  for (std::size_t i=0; i<u.nunk(); ++i)
+    for (ncomp_t c=0; c<u.nprop(); ++c)
+      u(i,c) *= v[i];
+}
+
+void
+ALECG::conserved( tk::Fields& u, const std::vector< tk::real >& v )
+// *****************************************************************************
+//  Divide solution with mesh volume
+//! \param[in,out] u Solution vector
+//! \param[in] v Volume to divide with
+// *****************************************************************************
+{
+  Assert( v.size() == u.nunk(), "Size mismatch" );
+
+  for (std::size_t i=0; i<u.nunk(); ++i)
+    for (ncomp_t c=0; c<u.nprop(); ++c) {
+      u(i,c) /= v[i];
+    }
+}
+
+void
+ALECG::box( tk::real v, const std::vector< tk::real >& blkvols )
+// *****************************************************************************
+// Receive total box IC volume and set conditions in box
+//! \param[in] v Total volume within user-specified box
+//! \param[in] blkvols Vector of mesh block discrete volumes with user ICs
+// *****************************************************************************
+{
+  Assert(blkvols.size() == m_nusermeshblk,
+    "Incorrect size of block volume vector");
+  auto d = Disc();
+
+  // Store user-defined box/block IC volume
+  d->Boxvol() = v;
+  d->MeshBlkVol() = blkvols;
+
+  // Set initial conditions for all PDEs
+  g_cgpde[d->MeshId()].initialize( d->Coord(), m_u, d->T(), d->Boxvol(),
+    m_boxnodes, d->MeshBlkVol(), m_nodeblockid );
+
+  // Multiply conserved variables with mesh volume
+  volumetric( m_u, Disc()->Vol() );
+
+  // Initialize nodal mesh volumes at previous time step stage
+  d->Voln() = d->Vol();
+
+  // Start computing the mesh mesh velocity for ALE
+  meshvelstart();
+}
+
+void
+ALECG::meshvelstart()
+// *****************************************************************************
+// Start computing the mesh mesh velocity for ALE
+// *****************************************************************************
+{
+  auto d = Disc();
+
+  // Apply boundary conditions on numerical solution
+  BC();
+
+  conserved( m_u, d->Vol() );
+
+  // query fluid velocity across all systems integrated
+  tk::UnsMesh::Coords vel;
+  g_cgpde[d->MeshId()].velocity( m_u, vel );
+  // query speed of sound in mesh nodes across all systems integrated
+  std::vector< tk::real > soundspeed;
+  g_cgpde[d->MeshId()].soundspeed( m_u, soundspeed );
+
+  volumetric( m_u, d->Vol() );
+
+  // Start computing the mesh mesh velocity for ALE
+  d->meshvelStart( vel, soundspeed, m_bnorm, rkcoef[m_stage] * d->Dt(),
+    CkCallback(CkIndex_ALECG::meshveldone(), thisProxy[thisIndex]) );
+}
+
+void
+ALECG::meshveldone()
+// *****************************************************************************
+// Done with computing the mesh velocity for ALE
+// *****************************************************************************
+{
+  // Assess and record mesh velocity linear solver conergence
+  Disc()->meshvelConv();
+
+  // Continue
+  if (Disc()->Initial()) {
+
+    conserved( m_u, Disc()->Vol() );
+
+    // Initiate IC transfer (if coupled)
+    Disc()->transfer( m_u, 0,
+      CkCallback(CkIndex_ALECG::transfer_complete(), thisProxy[thisIndex]) );
+
+    lhs();
+
+  } else {
+
+    ale();
+
+  }
+}
+
+//! [start]
+void
+ALECG::start()
+// *****************************************************************************
+// Start time stepping
+// *****************************************************************************
+{
+  // Set flag that indicates that we are now during time stepping
+  Disc()->Initial( 0 );
+  // Start timer measuring time stepping wall clock time
+  Disc()->Timer().zero();
+  // Zero grind-timer
+  Disc()->grindZero();
+  // Continue to first time step
+  next();
+}
+//! [start]
+
+//! [Compute lhs]
+void
+ALECG::lhs()
+// *****************************************************************************
+// Compute the left-hand side of transport equations
+//! \details Also (re-)compute all data structures if the mesh changed.
+// *****************************************************************************
+{
+  // No need for LHS in ALECG
+
+  // (Re-)compute boundary point-, and dual-face normals
+  norm();
+}
+//! [Compute lhs]
+
+//! [Merge normals and continue]
+void
+ALECG::mergelhs()
+// *****************************************************************************
+// The own and communication portion of the left-hand side is complete
+// *****************************************************************************
+{
+  // Combine own and communicated contributions of normals
+  normfinal();
+
+  if (Disc()->Initial()) {
+    volumetric( m_u, Disc()->Vol() );
+    // Output initial conditions to file
+    writeFields( CkCallback(CkIndex_ALECG::start(), thisProxy[thisIndex]) );
+  } else {
+    norm_complete();
+  }
+}
+//! [Merge normals and continue]
+
+void
+ALECG::normfinal()
+// *****************************************************************************
+//  Finish computing dual-face and boundary point normals
+// *****************************************************************************
+{
+  auto d = Disc();
+  const auto& lid = d->Lid();
+
+  // Combine own and communicated contributions to boundary point normals
+  for (const auto& [s,norms] : m_bnormc) {
+    auto& bnorms = m_bnorm[s];
+    for (const auto& [p,n] : norms) {
+      auto& norm = bnorms[p];
+      norm[0] += n[0];
+      norm[1] += n[1];
+      norm[2] += n[2];
+      norm[3] += n[3];
+    }
+  }
+  tk::destroy( m_bnormc );
+
+  // Divide summed point normals by the sum of inverse distance squared
+  for (auto& [s,norms] : m_bnorm)
+    for (auto& [p,n] : norms) {
+      n[0] /= n[3];
+      n[1] /= n[3];
+      n[2] /= n[3];
+      Assert( (n[0]*n[0] + n[1]*n[1] + n[2]*n[2] - 1.0) <
+              1.0e+3*std::numeric_limits< tk::real >::epsilon(),
+              "Non-unit normal" );
+    }
+
+  // Replace global->local ids associated to boundary point normals
+  decltype(m_bnorm) bnorm;
+  for (auto& [s,norms] : m_bnorm) {
+    auto& bnorms = bnorm[s];
+    for (auto&& [g,n] : norms)
+      bnorms[ tk::cref_find(lid,g) ] = std::move(n);
+  }
+  m_bnorm = std::move(bnorm);
+
+  // Count contributions to chare-boundary edges
+  std::unordered_map< tk::UnsMesh::Edge, std::size_t,
+    tk::UnsMesh::Hash<2>, tk::UnsMesh::Eq<2> > edge_node_count;
+  for (const auto& [c,edges] : d->EdgeCommMap())
+    for (const auto& e : edges)
+      ++edge_node_count[e];
+
+  // Combine and weigh communicated contributions to dual-face normals
+  for (auto& [e,n] : m_dfnormc) {
+    const auto& dfn = tk::cref_find( m_dfnorm, e );
+    n[0] += dfn[0];
+    n[1] += dfn[1];
+    n[2] += dfn[2];
+    auto count = static_cast< tk::real >( tk::cref_find( edge_node_count, e ) );
+    auto factor = 1.0/(count + 1.0);
+    for (auto & x : n) x *= factor;<--- Consider using std::transform algorithm instead of a raw loop.
+  }
+
+  // Generate list of unique edges
+  tk::UnsMesh::EdgeSet uedge;
+  for (std::size_t p=0; p<m_u.nunk(); ++p)
+    for (auto q : tk::Around(m_psup,p))
+      uedge.insert( {p,q} );
+
+  // Flatten edge list
+  m_edgenode.resize( uedge.size() * 2 );
+  std::size_t f = 0;
+  const auto& gid = d->Gid();
+  for (auto&& [p,q] : uedge) {
+    if (gid[p] > gid[q]) {
+      m_edgenode[f+0] = std::move(q);
+      m_edgenode[f+1] = std::move(p);
+    } else {
+      m_edgenode[f+0] = std::move(p);
+      m_edgenode[f+1] = std::move(q);
+    }
+    f += 2;
+  }
+  tk::destroy(uedge);
+
+  // Convert dual-face normals to streamable (and vectorizable) data structure
+  m_dfn.resize( m_edgenode.size() * 3 );      // 2 vectors per access
+  std::unordered_map< tk::UnsMesh::Edge, std::size_t,
+                      tk::UnsMesh::Hash<2>, tk::UnsMesh::Eq<2> > eid;
+  for (std::size_t e=0; e<m_edgenode.size()/2; ++e) {
+    auto p = m_edgenode[e*2+0];
+    auto q = m_edgenode[e*2+1];
+    eid[{p,q}] = e;
+    std::array< std::size_t, 2 > g{ gid[p], gid[q] };
+    auto n = tk::cref_find( m_dfnorm, g );
+    // figure out if this is an edge on the parallel boundary
+    auto nit = m_dfnormc.find( g );
+    auto m = ( nit != m_dfnormc.end() ) ? nit->second : n;
+    m_dfn[e*6+0] = n[0];
+    m_dfn[e*6+1] = n[1];
+    m_dfn[e*6+2] = n[2];
+    m_dfn[e*6+3] = m[0];
+    m_dfn[e*6+4] = m[1];
+    m_dfn[e*6+5] = m[2];
+  }
+
+  tk::destroy( m_dfnorm );
+  tk::destroy( m_dfnormc );
+
+  // Flatten edge id data structure
+  m_edgeid.resize( m_psup.first.size() );
+  for (std::size_t p=0,k=0; p<m_u.nunk(); ++p)
+    for (auto q : tk::Around(m_psup,p))
+      m_edgeid[k++] = tk::cref_find( eid, {p,q} );
+}
+
+void
+ALECG::BC()
+// *****************************************************************************
+// Apply boundary conditions
+// \details The following BC enforcement changes the initial condition or
+//!   updated solution (dependending on when it is called) to ensure strong
+//!   imposition of the BCs. This is a matter of choice. Another alternative is
+//!   to only apply BCs when computing fluxes at boundary faces, thereby only
+//!   weakly enforcing the BCs. The former is conventionally used in continunous
+//!   Galerkin finite element methods (such as ALECG implements), whereas the
+//!   latter, in finite volume methods.
+// *****************************************************************************
+{
+  auto d = Disc();
+  const auto& coord = d->Coord();
+
+  conserved( m_u, d->Vol() );
+
+  // Apply Dirichlet BCs
+  for (const auto& [b,bc] : m_dirbc)
+    for (ncomp_t c=0; c<m_u.nprop(); ++c)
+      if (bc[c].first) m_u(b,c) = bc[c].second;
+
+  // Apply symmetry BCs
+  g_cgpde[d->MeshId()].symbc( m_u, coord, m_bnorm, m_symbcnodes );
+
+  // Apply farfield BCs
+  g_cgpde[d->MeshId()].farfieldbc( m_u, coord, m_bnorm, m_farfieldbcnodes );
+
+  // Apply user defined time dependent BCs
+  g_cgpde[d->MeshId()].timedepbc( d->T(), m_u, m_timedepbcnodes,
+    m_timedepbcFn );
+
+  volumetric( m_u, d->Vol() );
+}
+
+void
+ALECG::next()
+// *****************************************************************************
+// Continue to next time step
+// *****************************************************************************
+{
+  dt();
+}
+
+void
+ALECG::dt()
+// *****************************************************************************
+// Compute time step size
+// *****************************************************************************
+{
+  tk::real mindt = std::numeric_limits< tk::real >::max();
+
+  auto const_dt = g_inputdeck.get< tag::dt >();
+  auto eps = std::numeric_limits< tk::real >::epsilon();
+
+  auto d = Disc();
+
+  // use constant dt if configured
+  if (std::abs(const_dt) > eps) {
+
+    mindt = const_dt;
+
+  } else {      // compute dt based on CFL
+
+    //! [Find the minimum dt across all PDEs integrated]
+    conserved( m_u, Disc()->Vol() );
+    if (g_inputdeck.get< tag::steady_state >()) {
+
+      // compute new dt for each mesh point
+      g_cgpde[d->MeshId()].dt( d->It(), d->Vol(), m_u, m_dtp );
+
+      // find the smallest dt of all nodes on this chare
+      mindt = *std::min_element( begin(m_dtp), end(m_dtp) );
+
+    } else {    // compute new dt for this chare
+
+      // find the smallest dt of all equations on this chare
+      auto eqdt = g_cgpde[d->MeshId()].dt( d->Coord(), d->Inpoel(), d->T(),
+        d->Dtn(), m_u, d->Vol(), d->Voln() );
+      if (eqdt < mindt) mindt = eqdt;
+
+    }
+    volumetric( m_u, Disc()->Vol() );
+    //! [Find the minimum dt across all PDEs integrated]
+
+  }
+
+  //! [Advance]
+  // Actiavate SDAG waits for next time step stage
+  thisProxy[ thisIndex ].wait4grad();
+  thisProxy[ thisIndex ].wait4rhs();
+
+  // Contribute to minimum dt across all chares and advance to next step
+  contribute( sizeof(tk::real), &mindt, CkReduction::min_double,
+              CkCallback(CkReductionTarget(ALECG,advance), thisProxy) );
+  //! [Advance]
+}
+
+void
+ALECG::advance( tk::real newdt, tk::real )
+// *****************************************************************************
+// Advance equations to next time step
+//! \param[in] newdt The smallest dt across the whole problem
+// *****************************************************************************
+{
+  auto d = Disc();
+
+  // Set new time step size
+  if (m_stage == 0) d->setdt( newdt );
+
+  // Compute gradients for next time step
+  chBndGrad();
+}
+
+void
+ALECG::chBndGrad()
+// *****************************************************************************
+// Compute nodal gradients at chare-boundary nodes. Gradients at internal nodes
+// are calculated locally as needed and are not stored.
+// *****************************************************************************
+{
+  auto d = Disc();
+
+  // Divide solution with mesh volume
+  conserved( m_u, Disc()->Vol() );
+  // Compute own portion of gradients for all equations
+  g_cgpde[d->MeshId()].chBndGrad( d->Coord(), d->Inpoel(), m_bndel, d->Gid(),
+    d->Bid(), m_u, m_chBndGrad );
+  // Multiply solution with mesh volume
+  volumetric( m_u, Disc()->Vol() );
+
+  // Communicate gradients to other chares on chare-boundary
+  if (d->NodeCommMap().empty())        // in serial we are done
+    comgrad_complete();
+  else // send gradients contributions to chare-boundary nodes to fellow chares
+    for (const auto& [c,n] : d->NodeCommMap()) {
+      std::vector< std::vector< tk::real > > g( n.size() );
+      std::size_t j = 0;
+      for (auto i : n) g[ j++ ] = m_chBndGrad[ tk::cref_find(d->Bid(),i) ];
+      thisProxy[c].comChBndGrad( std::vector<std::size_t>(begin(n),end(n)), g );
+    }
+
+  owngrad_complete();
+}
+
+void
+ALECG::comChBndGrad( const std::vector< std::size_t >& gid,
+                     const std::vector< std::vector< tk::real > >& G )
+// *****************************************************************************
+//  Receive contributions to nodal gradients on chare-boundaries
+//! \param[in] gid Global mesh node IDs at which we receive grad contributions
+//! \param[in] G Partial contributions of gradients to chare-boundary nodes
+//! \details This function receives contributions to m_chBndGrad, which stores
+//!   nodal gradients at mesh chare-boundary nodes. While m_chBndGrad stores
+//!   own contributions, m_chBndGradc collects the neighbor chare
+//!   contributions during communication. This way work on m_chBndGrad and
+//!   m_chBndGradc is overlapped. The two are combined in rhs().
+// *****************************************************************************
+{
+  Assert( G.size() == gid.size(), "Size mismatch" );
+
+  using tk::operator+=;
+
+  for (std::size_t i=0; i<gid.size(); ++i) m_chBndGradc[ gid[i] ] += G[i];
+
+  if (++m_ngrad == Disc()->NodeCommMap().size()) {
+    m_ngrad = 0;
+    comgrad_complete();
+  }
+}
+
+void
+ALECG::rhs()
+// *****************************************************************************
+// Compute right-hand side of transport equations
+// *****************************************************************************
+{
+  auto d = Disc();
+
+  // Combine own and communicated contributions to nodal gradients
+  for (const auto& [gid,g] : m_chBndGradc) {
+    auto bid = tk::cref_find( d->Bid(), gid );
+    for (ncomp_t c=0; c<m_chBndGrad.nprop(); ++c)
+      m_chBndGrad(bid,c) += g[c];
+  }
+
+  // clear gradients receive buffer
+  tk::destroy(m_chBndGradc);
+
+  const auto steady = g_inputdeck.get< tag::steady_state >();
+
+  // Compute own portion of right-hand side for all equations
+  auto prev_rkcoef = m_stage == 0 ? 0.0 : rkcoef[m_stage-1];
+  if (steady)
+    for (std::size_t p=0; p<m_tp.size(); ++p) m_tp[p] += prev_rkcoef * m_dtp[p];
+  conserved( m_u, Disc()->Vol() );
+  g_cgpde[d->MeshId()].rhs( d->T() + prev_rkcoef * d->Dt(), d->Coord(), d->Inpoel(),
+          m_triinpoel, d->Gid(), d->Bid(), d->Lid(), m_dfn, m_psup, m_esup,
+          m_symbctri, d->Vol(), m_edgenode, m_edgeid,
+          m_boxnodes, m_chBndGrad, m_u, d->meshvel(), m_tp, d->Boxvol(),
+          m_rhs );
+  volumetric( m_u, Disc()->Vol() );
+  if (steady)
+    for (std::size_t p=0; p<m_tp.size(); ++p) m_tp[p] -= prev_rkcoef * m_dtp[p];
+
+  // Query/update boundary-conditions-related data structures from user input
+  queryBnd();
+
+  // Communicate rhs to other chares on chare-boundary
+  if (d->NodeCommMap().empty())        // in serial we are done
+    comrhs_complete();
+  else // send contributions of rhs to chare-boundary nodes to fellow chares
+    for (const auto& [c,n] : d->NodeCommMap()) {
+      std::vector< std::vector< tk::real > > r( n.size() );
+      std::size_t j = 0;
+      for (auto i : n) r[ j++ ] = m_rhs[ tk::cref_find(d->Lid(),i) ];
+      thisProxy[c].comrhs( std::vector<std::size_t>(begin(n),end(n)), r );
+    }
+
+  ownrhs_complete();
+}
+
+void
+ALECG::comrhs( const std::vector< std::size_t >& gid,
+               const std::vector< std::vector< tk::real > >& R )
+// *****************************************************************************
+//  Receive contributions to right-hand side vector on chare-boundaries
+//! \param[in] gid Global mesh node IDs at which we receive RHS contributions
+//! \param[in] R Partial contributions of RHS to chare-boundary nodes
+//! \details This function receives contributions to m_rhs, which stores the
+//!   right hand side vector at mesh nodes. While m_rhs stores own
+//!   contributions, m_rhsc collects the neighbor chare contributions during
+//!   communication. This way work on m_rhs and m_rhsc is overlapped. The two
+//!   are combined in solve().
+// *****************************************************************************
+{
+  Assert( R.size() == gid.size(), "Size mismatch" );
+
+  using tk::operator+=;
+
+  for (std::size_t i=0; i<gid.size(); ++i) m_rhsc[ gid[i] ] += R[i];
+
+  // When we have heard from all chares we communicate with, this chare is done
+  if (++m_nrhs == Disc()->NodeCommMap().size()) {
+    m_nrhs = 0;
+    comrhs_complete();
+  }
+}
+
+void
+ALECG::solve()
+// *****************************************************************************
+//  Advance systems of equations
+// *****************************************************************************
+{
+  auto d = Disc();
+
+  // Combine own and communicated contributions to rhs
+  for (const auto& b : m_rhsc) {
+    auto lid = tk::cref_find( d->Lid(), b.first );
+    for (ncomp_t c=0; c<m_rhs.nprop(); ++c) m_rhs(lid,c) += b.second[c];
+  }
+
+  // clear receive buffer
+  tk::destroy(m_rhsc);
+
+  // Update state at time n
+  if (m_stage == 0) {
+    m_un = m_u;
+    if (g_inputdeck.get< tag::ale, tag::ale >()) d->UpdateCoordn();
+  }
+
+  // Solve the sytem
+  if (g_inputdeck.get< tag::steady_state >()) {
+
+    // Advance solution, converging to steady state
+    for (std::size_t i=0; i<m_u.nunk(); ++i)
+      for (ncomp_t c=0; c<m_u.nprop(); ++c)
+        m_u(i,c) = m_un(i,c) + rkcoef[m_stage] * m_dtp[i] * m_rhs(i,c);
+
+  } else {
+
+    auto adt = rkcoef[m_stage] * d->Dt();
+
+    // Advance unsteady solution
+    m_u = m_un + adt * m_rhs;
+
+    // Advance mesh if ALE is enabled
+    if (g_inputdeck.get< tag::ale, tag::ale >()) {
+      auto& coord = d->Coord();
+      const auto& w = d->meshvel();
+      for (auto j : g_inputdeck.get< tag::ale, tag::mesh_motion >())
+        for (std::size_t i=0; i<coord[j].size(); ++i)
+          coord[j][i] = d->Coordn()[j][i] + adt * w(i,j);
+    }
+
+  }
+
+  m_newmesh = 0;  // recompute normals after ALE (if enabled)
+  m_refinedmesh = 0;  // mesh has not been refined by ALE
+  // Activate SDAG waits
+  thisProxy[ thisIndex ].wait4norm();
+  thisProxy[ thisIndex ].wait4mesh();
+
+  //! [Continue after solve]
+  // Recompute mesh volumes if ALE is enabled
+  if (g_inputdeck.get< tag::ale, tag::ale >()) {
+
+    transfer_complete();
+    // Save nodal volumes at previous time step stage
+    d->Voln() = d->Vol();
+    // Prepare for recomputing the nodal volumes
+    d->startvol();
+    auto meshid = d->MeshId();
+    contribute( sizeof(std::size_t), &meshid, CkReduction::nop,
+                CkCallback(CkReductionTarget(Transporter,resized), d->Tr()) );
+
+  } else {
+
+    norm_complete();
+    resized();
+
+  }
+  //! [Continue after solve]
+}
+
+void
+ALECG::ale()
+// *****************************************************************************
+//  Continue after computing the new mesh velocity for ALE
+// *****************************************************************************
+{
+  auto d = Disc();
+
+  if (m_stage < 2) {
+
+    // Activate SDAG wait for next time step stage
+    thisProxy[ thisIndex ].wait4grad();
+    thisProxy[ thisIndex ].wait4rhs();
+
+    // continue to mesh-to-mesh transfer (if coupled)
+    transfer();
+
+  } else {
+
+    // Ensure new field output file if mesh moved if ALE is enabled
+    if (g_inputdeck.get< tag::ale, tag::ale >()) {
+      d->Itf() = 0;  // Zero field output iteration count if mesh moved
+      ++d->Itr();    // Increase number of iterations with a change in the mesh
+    }
+
+    // Compute diagnostics, e.g., residuals
+    conserved( m_u, Disc()->Vol() );
+    conserved( m_un, Disc()->Voln() );
+    auto diag_computed = m_diag.compute( *d, m_u, m_un, m_bnorm,
+                                         m_symbcnodes, m_farfieldbcnodes );
+    volumetric( m_u, Disc()->Vol() );
+    volumetric( m_un, Disc()->Voln() );
+    // Increase number of iterations and physical time
+    d->next();
+    // Advance physical time for local time stepping
+    if (g_inputdeck.get< tag::steady_state >())
+      for (std::size_t i=0; i<m_u.nunk(); ++i) m_tp[i] += m_dtp[i];
+    // Continue to mesh refinement (if configured)
+    if (!diag_computed) refine( std::vector< tk::real >( m_u.nprop(), 1.0 ) );
+
+  }
+}
+
+//! [Refine]
+void
+ALECG::refine( const std::vector< tk::real >& l2res )
+// *****************************************************************************
+// Optionally refine/derefine mesh
+//! \param[in] l2res L2-norms of the residual for each scalar component
+//!   computed across the whole problem
+// *****************************************************************************
+{
+  auto d = Disc();
+
+  const auto steady = g_inputdeck.get< tag::steady_state >();
+  const auto residual = g_inputdeck.get< tag::residual >();
+  const auto rc = g_inputdeck.get< tag::rescomp >() - 1;
+
+  if (steady) {
+
+    // this is the last time step if max time of max number of time steps
+    // reached or the residual has reached its convergence criterion
+    if (d->finished() or l2res[rc] < residual) m_finished = 1;
+
+  } else {
+
+    // this is the last time step if max time or max iterations reached
+    if (d->finished()) m_finished = 1;
+
+  }
+
+  auto dtref = g_inputdeck.get< tag::amr, tag::dtref >();
+  auto dtfreq = g_inputdeck.get< tag::amr, tag::dtfreq >();
+
+  // Activate SDAG waits for re-computing the normals
+  m_newmesh = 1;  // recompute normals after AMR (if enabled)
+  thisProxy[ thisIndex ].wait4norm();
+  thisProxy[ thisIndex ].wait4mesh();
+
+  // if t>0 refinement enabled and we hit the frequency
+  if (dtref && !(d->It() % dtfreq)) {   // refine
+
+    // Convert to conserved unknowns, since the next step changes volumes
+    conserved(m_u, d->Vol());
+
+    m_refinedmesh = 1;
+    d->startvol();
+    d->Ref()->dtref( m_bface, m_bnode, m_triinpoel );
+    d->refined() = 1;
+
+  } else {      // do not refine
+
+    m_refinedmesh = 0;
+    d->refined() = 0;
+    norm_complete();
+    resized();
+
+  }
+}
+//! [Refine]
+
+//! [Resize]
+void
+ALECG::resizePostAMR(
+  const std::vector< std::size_t >& /*ginpoel*/,
+  const tk::UnsMesh::Chunk& chunk,
+  const tk::UnsMesh::Coords& coord,
+  const std::unordered_map< std::size_t, tk::UnsMesh::Edge >& addedNodes,
+  const std::unordered_map< std::size_t, std::size_t >& /*addedTets*/,
+  const std::set< std::size_t >& removedNodes,
+  const std::unordered_map< std::size_t, std::size_t >& amrNodeMap,
+  const tk::NodeCommMap& nodeCommMap,
+  const std::map< int, std::vector< std::size_t > >& bface,
+  const std::map< int, std::vector< std::size_t > >& bnode,
+  const std::vector< std::size_t >& triinpoel,
+  const std::unordered_map< std::size_t, std::set< std::size_t > >& elemblockid )
+// *****************************************************************************
+//  Receive new mesh from Refiner
+//! \param[in] ginpoel Mesh connectivity with global node ids
+//! \param[in] chunk New mesh chunk (connectivity and global<->local id maps)
+//! \param[in] coord New mesh node coordinates
+//! \param[in] addedNodes Newly added mesh nodes and their parents (local ids)
+//! \param[in] addedTets Newly added mesh cells and their parents (local ids)
+//! \param[in] removedNodes Newly removed mesh node local ids
+//! \param[in] amrNodeMap Node id map after amr (local ids)
+//! \param[in] nodeCommMap New node communication map
+//! \param[in] bface Boundary-faces mapped to side set ids
+//! \param[in] bnode Boundary-node lists mapped to side set ids
+//! \param[in] triinpoel Boundary-face connectivity
+//! \param[in] elemblockid Local tet ids associated with mesh block ids
+// *****************************************************************************
+{
+  auto d = Disc();
+
+  d->Itf() = 0;  // Zero field output iteration count if AMR
+  ++d->Itr();    // Increase number of iterations with a change in the mesh
+
+  // Resize mesh data structures after mesh refinement
+  d->resizePostAMR( chunk, coord, amrNodeMap, nodeCommMap, removedNodes,
+    elemblockid );
+
+  // Remove newly removed nodes from solution vectors
+  m_u.rm(removedNodes);
+  m_un.rm(removedNodes);
+  m_rhs.rm(removedNodes);
+
+  // Resize auxiliary solution vectors
+  auto npoin = coord[0].size();
+  auto nprop = m_u.nprop();
+  m_u.resize( npoin );
+  m_un.resize( npoin );
+  m_rhs.resize( npoin );
+  m_chBndGrad.resize( d->Bid().size() );
+  tk::destroy(m_esup);
+  tk::destroy(m_psup);
+  m_esup = tk::genEsup( d->Inpoel(), 4 );
+  m_psup = tk::genPsup( d->Inpoel(), 4, m_esup );
+
+  // Update solution on new mesh
+  for (const auto& n : addedNodes)
+    for (std::size_t c=0; c<nprop; ++c) {
+      Assert(n.first < m_u.nunk(), "Added node index out of bounds post-AMR");
+      Assert(n.second[0] < m_u.nunk() && n.second[1] < m_u.nunk(),
+        "Indices of parent-edge nodes out of bounds post-AMR");
+      m_u(n.first,c) = (m_u(n.second[0],c) + m_u(n.second[1],c))/2.0;
+    }
+
+  // Update physical-boundary node-, face-, and element lists
+  m_bnode = bnode;
+  m_bface = bface;
+  m_triinpoel = tk::remap( triinpoel, d->Lid() );
+
+  auto meshid = d->MeshId();
+  contribute( sizeof(std::size_t), &meshid, CkReduction::nop,
+              CkCallback(CkReductionTarget(Transporter,resized), d->Tr()) );
+}
+//! [Resize]
+
+void
+ALECG::resized()
+// *****************************************************************************
+// Resizing data sutrctures after mesh refinement has been completed
+// *****************************************************************************
+{
+  auto d = Disc();
+
+  // Revert to volumetric unknowns, if soln was converted in ALECG::refine()
+  auto dtref = g_inputdeck.get< tag::amr, tag::dtref >();
+  auto dtfreq = g_inputdeck.get< tag::amr, tag::dtfreq >();
+  if (dtref && !(d->It() % dtfreq) && m_refinedmesh==1) {
+    volumetric(m_u, d->Vol());
+    // Update previous volumes after refinement
+    d->Voln() = d->Vol();
+  }
+
+  resize_complete();
+}
+
+void
+ALECG::transfer()
+// *****************************************************************************
+// Transfer solution to other solver and mesh if coupled
+// *****************************************************************************
+{
+  // Initiate solution transfer (if coupled)
+
+//TODO: enable this for during-timestepping solution transfer
+//  Disc()->transfer(m_u, CkCallback(CkIndex_ALECG::stage(), thisProxy[thisIndex]));
+  thisProxy[thisIndex].stage();
+}
+
+//! [stage]
+void
+ALECG::stage()
+// *****************************************************************************
+// Evaluate whether to continue with next time step stage
+// *****************************************************************************
+{
+  transfer_complete();
+
+  // Increment Runge-Kutta stage counter
+  ++m_stage;
+
+  // if not all Runge-Kutta stages complete, continue to next time stage,
+  // otherwise output field data to file(s)
+  if (m_stage < 3) chBndGrad(); else out();
+}
+//! [stage]
+
+void
+ALECG::writeFields( CkCallback c )
+// *****************************************************************************
+// Output mesh-based fields to file
+//! \param[in] c Function to continue with after the write
+// *****************************************************************************
+{
+  if (g_inputdeck.get< tag::cmd, tag::benchmark >()) {
+
+    c.send();
+
+  } else {
+
+    auto d = Disc();
+    const auto& coord = d->Coord();
+
+    // Query fields names requested by user
+    auto nodefieldnames = numericFieldNames( tk::Centering::NODE );
+
+    // Collect field output from numerical solution requested by user
+    conserved( m_u, Disc()->Vol() );
+    auto nodefields = numericFieldOutput( m_u, tk::Centering::NODE,
+      g_cgpde[Disc()->MeshId()].OutVarFn(), m_u );
+    volumetric( m_u, Disc()->Vol() );
+
+    //! Lambda to put in a field for output if not empty
+    auto add_node_field = [&]( const auto& name, const auto& field ){
+      if (not field.empty()) {
+        nodefieldnames.push_back( name );
+        nodefields.push_back( field );
+      }
+    };
+
+    // Output mesh velocity if ALE is enabled
+    if (g_inputdeck.get< tag::ale, tag::ale >()) {
+      const auto& w = d->meshvel();
+      add_node_field( "x-mesh-velocity", w.extract_comp(0) );
+      add_node_field( "y-mesh-velocity", w.extract_comp(1) );
+      add_node_field( "z-mesh-velocity", w.extract_comp(2) );
+      add_node_field( "volume", d->Vol() );
+    }
+
+    // Collect field output names for analytical solutions
+    analyticFieldNames( g_cgpde[d->MeshId()], tk::Centering::NODE,
+      nodefieldnames );
+
+    // Collect field output from analytical solutions (if exist)
+    analyticFieldOutput( g_cgpde[d->MeshId()], tk::Centering::NODE, coord[0],
+      coord[1], coord[2], d->T(), nodefields );
+
+    // Query and collect nodal block and surface field names from PDEs integrated
+    std::vector< std::string > nodesurfnames;
+    auto sn = g_cgpde[d->MeshId()].surfNames();
+    nodesurfnames.insert( end(nodesurfnames), begin(sn), end(sn) );
+
+    // Collect nodal block and surface field solution
+    std::vector< std::vector< tk::real > > nodesurfs;
+    conserved( m_u, Disc()->Vol() );
+    auto so = g_cgpde[d->MeshId()].surfOutput( tk::bfacenodes(m_bface,
+      m_triinpoel), m_u );
+    nodesurfs.insert( end(nodesurfs), begin(so), end(so) );
+
+    // Collect elemental block and surface field names from PDEs integrated
+    auto elemsurfnames = nodesurfnames;
+
+    // Collect elemental block and surface field solution
+    std::vector< std::vector< tk::real > > elemsurfs;
+    auto eso = g_cgpde[d->MeshId()].elemSurfOutput( m_bface, m_triinpoel, m_u );
+    elemsurfs.insert( end(elemsurfs), begin(eso), end(eso) );
+
+    // Query refinement data
+    auto dtref = g_inputdeck.get< tag::amr, tag::dtref >();
+
+    std::tuple< std::vector< std::string >,
+                std::vector< std::vector< tk::real > >,
+                std::vector< std::string >,
+                std::vector< std::vector< tk::real > > > r;
+    if (dtref) r = d->Ref()->refinementFields();
+    volumetric( m_u, Disc()->Vol() );
+
+    auto& refinement_elemfieldnames = std::get< 0 >( r );
+    auto& refinement_elemfields = std::get< 1 >( r );
+    auto& refinement_nodefieldnames = std::get< 2 >( r );
+    auto& refinement_nodefields = std::get< 3 >( r );
+
+    nodefieldnames.insert( end(nodefieldnames),
+      begin(refinement_nodefieldnames), end(refinement_nodefieldnames) );
+    nodefields.insert( end(nodefields),
+      begin(refinement_nodefields), end(refinement_nodefields) );
+
+    auto elemfieldnames = std::move(refinement_elemfieldnames);
+    auto elemfields = std::move(refinement_elemfields);
+
+    Assert( elemfieldnames.size() == elemfields.size(), "Size mismatch" );
+    Assert( nodefieldnames.size() == nodefields.size(), "Size mismatch" );
+
+    // Send mesh and fields data (solution dump) for output to file
+    d->write( d->Inpoel(), coord, m_bface, tk::remap(m_bnode,d->Lid()),
+              m_triinpoel, elemfieldnames, nodefieldnames, elemsurfnames,
+              nodesurfnames, elemfields, nodefields, elemsurfs, nodesurfs, c );
+
+  }
+}
+
+void
+ALECG::out()
+// *****************************************************************************
+// Output mesh field data
+// *****************************************************************************
+{
+  auto d = Disc();
+
+  // Output time history
+  if (d->histiter() or d->histtime() or d->histrange()) {
+    std::vector< std::vector< tk::real > > hist;
+    conserved( m_u, Disc()->Vol() );
+    auto h = g_cgpde[d->MeshId()].histOutput( d->Hist(), d->Inpoel(), m_u );
+    hist.insert( end(hist), begin(h), end(h) );
+    volumetric( m_u, Disc()->Vol() );
+    d->history( std::move(hist) );
+  }
+
+  // Output field data
+  if (d->fielditer() or d->fieldtime() or d->fieldrange() or m_finished)
+    writeFields( CkCallback(CkIndex_ALECG::step(), thisProxy[thisIndex]) );
+  else
+    step();
+}
+
+void
+ALECG::evalLB( int nrestart )
+// *****************************************************************************
+// Evaluate whether to do load balancing
+//! \param[in] nrestart Number of times restarted
+// *****************************************************************************
+{
+  auto d = Disc();
+
+  // Detect if just returned from a checkpoint and if so, zero timers and
+  // finished flag
+  if (d->restarted( nrestart )) m_finished = 0;
+
+  const auto lbfreq = g_inputdeck.get< tag::cmd, tag::lbfreq >();
+  const auto nonblocking = g_inputdeck.get< tag::cmd, tag::nonblocking >();
+
+  // Load balancing if user frequency is reached or after the second time-step
+  if ( (d->It()) % lbfreq == 0 || d->It() == 2 ) {
+
+    AtSync();
+    if (nonblocking) next();
+
+  } else {
+
+    next();
+
+  }
+}
+
+void
+ALECG::evalRestart()
+// *****************************************************************************
+// Evaluate whether to save checkpoint/restart
+// *****************************************************************************
+{
+  auto d = Disc();
+
+  const auto rsfreq = g_inputdeck.get< tag::cmd, tag::rsfreq >();
+  const auto benchmark = g_inputdeck.get< tag::cmd, tag::benchmark >();
+
+  if (not benchmark and not (d->It() % rsfreq)) {
+
+    std::vector< std::size_t > meshdata{ /* finished = */ 0, d->MeshId() };
+    contribute( meshdata, CkReduction::nop,
+      CkCallback(CkReductionTarget(Transporter,checkpoint), d->Tr()) );
+
+  } else {
+
+    evalLB( /* nrestart = */ -1 );
+
+  }
+}
+
+void
+ALECG::step()
+// *****************************************************************************
+// Evaluate whether to continue with next time step
+// *****************************************************************************
+{
+  auto d = Disc();
+
+  // Output one-liner status report to screen
+  d->status();
+  // Reset Runge-Kutta stage counter
+  m_stage = 0;
+
+  if (not m_finished) {
+
+    evalRestart();
+
+  } else {
+
+    auto meshid = d->MeshId();
+    d->contribute( sizeof(std::size_t), &meshid, CkReduction::nop,
+                   CkCallback(CkReductionTarget(Transporter,finish), d->Tr()) );
+
+  }
+}
+
+#include "NoWarning/alecg.def.h"
 
diff --git a/Release/cppcheck/55.html b/Release/cppcheck/55.html index c307a70d4ba3..885ac28caa5d 100644 --- a/Release/cppcheck/55.html +++ b/Release/cppcheck/55.html @@ -152,2271 +152,1609 @@
- - + @@ -73,11 +73,11 @@ - + - +
   1
-   2
-   3
-   4
-   5
-   6
-   7
-   8
-   9
-  10
-  11
-  12
-  13
-  14
-  15
-  16
-  17
-  18
-  19
-  20
-  21
-  22
-  23
-  24
-  25
-  26
-  27
-  28
-  29
-  30
-  31
-  32
-  33
-  34
-  35
-  36
-  37
-  38
-  39
-  40
-  41
-  42
-  43
-  44
-  45
-  46
-  47
-  48
-  49
-  50
-  51
-  52
-  53
-  54
-  55
-  56
-  57
-  58
-  59
-  60
-  61
-  62
-  63
-  64
-  65
-  66
-  67
-  68
-  69
-  70
-  71
-  72
-  73
-  74
-  75
-  76
-  77
-  78
-  79
-  80
-  81
-  82
-  83
-  84
-  85
-  86
-  87
-  88
-  89
-  90
-  91
-  92
-  93
-  94
-  95
-  96
-  97
-  98
-  99
- 100
- 101
- 102
- 103
- 104
- 105
- 106
- 107
- 108
- 109
- 110
- 111
- 112
- 113
- 114
- 115
- 116
- 117
- 118
- 119
- 120
- 121
- 122
- 123
- 124
- 125
- 126
- 127
- 128
- 129
- 130
- 131
- 132
- 133
- 134
- 135
- 136
- 137
- 138
- 139
- 140
- 141
- 142
- 143
- 144
- 145
- 146
- 147
- 148
- 149
- 150
- 151
- 152
- 153
- 154
- 155
- 156
- 157
- 158
- 159
- 160
- 161
- 162
- 163
- 164
- 165
- 166
- 167
- 168
- 169
- 170
- 171
- 172
- 173
- 174
- 175
- 176
- 177
- 178
- 179
- 180
- 181
- 182
- 183
- 184
- 185
- 186
- 187
- 188
- 189
- 190
- 191
- 192
- 193
- 194
- 195
- 196
- 197
- 198
- 199
- 200
- 201
- 202
- 203
- 204
- 205
- 206
- 207
- 208
- 209
- 210
- 211
- 212
- 213
- 214
- 215
- 216
- 217
- 218
- 219
- 220
- 221
- 222
- 223
- 224
- 225
- 226
- 227
- 228
- 229
- 230
- 231
- 232
- 233
- 234
- 235
- 236
- 237
- 238
- 239
- 240
- 241
- 242
- 243
- 244
- 245
- 246
- 247
- 248
- 249
- 250
- 251
- 252
- 253
- 254
- 255
- 256
- 257
- 258
- 259
- 260
- 261
- 262
- 263
- 264
- 265
- 266
- 267
- 268
- 269
- 270
- 271
- 272
- 273
- 274
- 275
- 276
- 277
- 278
- 279
- 280
- 281
- 282
- 283
- 284
- 285
- 286
- 287
- 288
- 289
- 290
- 291
- 292
- 293
- 294
- 295
- 296
- 297
- 298
- 299
- 300
- 301
- 302
- 303
- 304
- 305
- 306
- 307
- 308
- 309
- 310
- 311
- 312
- 313
- 314
- 315
- 316
- 317
- 318
- 319
- 320
- 321
- 322
- 323
- 324
- 325
- 326
- 327
- 328
- 329
- 330
- 331
- 332
- 333
- 334
- 335
- 336
- 337
- 338
- 339
- 340
- 341
- 342
- 343
- 344
- 345
- 346
- 347
- 348
- 349
- 350
- 351
- 352
- 353
- 354
- 355
- 356
- 357
- 358
- 359
- 360
- 361
- 362
- 363
- 364
- 365
- 366
- 367
- 368
- 369
- 370
- 371
- 372
- 373
- 374
- 375
- 376
- 377
- 378
- 379
- 380
- 381
- 382
- 383
- 384
- 385
- 386
- 387
- 388
- 389
- 390
- 391
- 392
- 393
- 394
- 395
- 396
- 397
- 398
- 399
- 400
- 401
- 402
- 403
- 404
- 405
- 406
- 407
- 408
- 409
- 410
- 411
- 412
- 413
- 414
- 415
- 416
- 417
- 418
- 419
- 420
- 421
- 422
- 423
- 424
- 425
- 426
- 427
- 428
- 429
- 430
- 431
- 432
- 433
- 434
- 435
- 436
- 437
- 438
- 439
- 440
- 441
- 442
- 443
- 444
- 445
- 446
- 447
- 448
- 449
- 450
- 451
- 452
- 453
- 454
- 455
- 456
- 457
- 458
- 459
- 460
- 461
- 462
- 463
- 464
- 465
- 466
- 467
- 468
- 469
- 470
- 471
- 472
- 473
- 474
- 475
- 476
- 477
- 478
- 479
- 480
- 481
- 482
- 483
- 484
- 485
- 486
- 487
- 488
- 489
- 490
- 491
- 492
- 493
- 494
- 495
- 496
- 497
- 498
- 499
- 500
- 501
- 502
- 503
- 504
- 505
- 506
- 507
- 508
- 509
- 510
- 511
- 512
- 513
- 514
- 515
- 516
- 517
- 518
- 519
- 520
- 521
- 522
- 523
- 524
- 525
- 526
- 527
- 528
- 529
- 530
- 531
- 532
- 533
- 534
- 535
- 536
- 537
- 538
- 539
- 540
- 541
- 542
- 543
- 544
- 545
- 546
- 547
- 548
- 549
- 550
- 551
- 552
- 553
- 554
- 555
- 556
- 557
- 558
- 559
- 560
- 561
- 562
- 563
- 564
- 565
- 566
- 567
- 568
- 569
- 570
- 571
- 572
- 573
- 574
- 575
- 576
- 577
- 578
- 579
- 580
- 581
- 582
- 583
- 584
- 585
- 586
- 587
- 588
- 589
- 590
- 591
- 592
- 593
- 594
- 595
- 596
- 597
- 598
- 599
- 600
- 601
- 602
- 603
- 604
- 605
- 606
- 607
- 608
- 609
- 610
- 611
- 612
- 613
- 614
- 615
- 616
- 617
- 618
- 619
- 620
- 621
- 622
- 623
- 624
- 625
- 626
- 627
- 628
- 629
- 630
- 631
- 632
- 633
- 634
- 635
- 636
- 637
- 638
- 639
- 640
- 641
- 642
- 643
- 644
- 645
- 646
- 647
- 648
- 649
- 650
- 651
- 652
- 653
- 654
- 655
- 656
- 657
- 658
- 659
- 660
- 661
- 662
- 663
- 664
- 665
- 666
- 667
- 668
- 669
- 670
- 671
- 672
- 673
- 674
- 675
- 676
- 677
- 678
- 679
- 680
- 681
- 682
- 683
- 684
- 685
- 686
- 687
- 688
- 689
- 690
- 691
- 692
- 693
- 694
- 695
- 696
- 697
- 698
- 699
- 700
- 701
- 702
- 703
- 704
- 705
- 706
- 707
- 708
- 709
- 710
- 711
- 712
- 713
- 714
- 715
- 716
- 717
- 718
- 719
- 720
- 721
- 722
- 723
- 724
- 725
- 726
- 727
- 728
- 729
- 730
- 731
- 732
- 733
- 734
- 735
- 736
- 737
- 738
- 739
- 740
- 741
- 742
- 743
- 744
- 745
- 746
- 747
- 748
- 749
- 750
- 751
- 752
- 753
- 754
- 755
- 756
- 757
- 758
- 759
- 760
- 761
- 762
- 763
- 764
- 765
- 766
- 767
- 768
- 769
- 770
- 771
- 772
- 773
- 774
- 775
- 776
- 777
- 778
- 779
- 780
- 781
- 782
- 783
- 784
- 785
- 786
- 787
- 788
- 789
- 790
- 791
- 792
- 793
- 794
- 795
- 796
- 797
- 798
- 799
- 800
- 801
- 802
- 803
- 804
- 805
- 806
- 807
- 808
- 809
- 810
- 811
- 812
- 813
- 814
- 815
- 816
- 817
- 818
- 819
- 820
- 821
- 822
- 823
- 824
- 825
- 826
- 827
- 828
- 829
- 830
- 831
- 832
- 833
- 834
- 835
- 836
- 837
- 838
- 839
- 840
- 841
- 842
- 843
- 844
- 845
- 846
- 847
- 848
- 849
- 850
- 851
- 852
- 853
- 854
- 855
- 856
- 857
- 858
- 859
- 860
- 861
- 862
- 863
- 864
- 865
- 866
- 867
- 868
- 869
- 870
- 871
- 872
- 873
- 874
- 875
- 876
- 877
- 878
- 879
- 880
- 881
- 882
- 883
- 884
- 885
- 886
- 887
- 888
- 889
- 890
- 891
- 892
- 893
- 894
- 895
- 896
- 897
- 898
- 899
- 900
- 901
- 902
- 903
- 904
- 905
- 906
- 907
- 908
- 909
- 910
- 911
- 912
- 913
- 914
- 915
- 916
- 917
- 918
- 919
- 920
- 921
- 922
- 923
- 924
- 925
- 926
- 927
- 928
- 929
- 930
- 931
- 932
- 933
- 934
- 935
- 936
- 937
- 938
- 939
- 940
- 941
- 942
- 943
- 944
- 945
- 946
- 947
- 948
- 949
- 950
- 951
- 952
- 953
- 954
- 955
- 956
- 957
- 958
- 959
- 960
- 961
- 962
- 963
- 964
- 965
- 966
- 967
- 968
- 969
- 970
- 971
- 972
- 973
- 974
- 975
- 976
- 977
- 978
- 979
- 980
- 981
- 982
- 983
- 984
- 985
- 986
- 987
- 988
- 989
- 990
- 991
- 992
- 993
- 994
- 995
- 996
- 997
- 998
- 999
-1000
-1001
-1002
-1003
-1004
-1005
-1006
-1007
-1008
-1009
-1010
-1011
-1012
-1013
-1014
-1015
-1016
-1017
-1018
-1019
-1020
-1021
-1022
-1023
-1024
-1025
-1026
-1027
-1028
-1029
-1030
-1031
-1032
-1033
-1034
-1035
-1036
-1037
-1038
-1039
-1040
-1041
-1042
-1043
-1044
-1045
-1046
-1047
-1048
-1049
-1050
-1051
-1052
-1053
-1054
-1055
-1056
-1057
-1058
-1059
-1060
-1061
-1062
-1063
-1064
-1065
-1066
-1067
-1068
-1069
-1070
-1071
-1072
-1073
-1074
-1075
-1076
-1077
-1078
-1079
-1080
-1081
-1082
-1083
-1084
-1085
-1086
-1087
-1088
-1089
-1090
-1091
-1092
-1093
-1094
-1095
-1096
-1097
-1098
-1099
-1100
-1101
-1102
-1103
-1104
-1105
-1106
-1107
-1108
-1109
-1110
-1111
-1112
-1113
-1114
-1115
-1116
-1117
-1118
-1119
-1120
-1121
-1122
-1123
-1124
-1125
-1126
-1127
-1128
-1129
// *****************************************************************************
+
  1
+  2
+  3
+  4
+  5
+  6
+  7
+  8
+  9
+ 10
+ 11
+ 12
+ 13
+ 14
+ 15
+ 16
+ 17
+ 18
+ 19
+ 20
+ 21
+ 22
+ 23
+ 24
+ 25
+ 26
+ 27
+ 28
+ 29
+ 30
+ 31
+ 32
+ 33
+ 34
+ 35
+ 36
+ 37
+ 38
+ 39
+ 40
+ 41
+ 42
+ 43
+ 44
+ 45
+ 46
+ 47
+ 48
+ 49
+ 50
+ 51
+ 52
+ 53
+ 54
+ 55
+ 56
+ 57
+ 58
+ 59
+ 60
+ 61
+ 62
+ 63
+ 64
+ 65
+ 66
+ 67
+ 68
+ 69
+ 70
+ 71
+ 72
+ 73
+ 74
+ 75
+ 76
+ 77
+ 78
+ 79
+ 80
+ 81
+ 82
+ 83
+ 84
+ 85
+ 86
+ 87
+ 88
+ 89
+ 90
+ 91
+ 92
+ 93
+ 94
+ 95
+ 96
+ 97
+ 98
+ 99
+100
+101
+102
+103
+104
+105
+106
+107
+108
+109
+110
+111
+112
+113
+114
+115
+116
+117
+118
+119
+120
+121
+122
+123
+124
+125
+126
+127
+128
+129
+130
+131
+132
+133
+134
+135
+136
+137
+138
+139
+140
+141
+142
+143
+144
+145
+146
+147
+148
+149
+150
+151
+152
+153
+154
+155
+156
+157
+158
+159
+160
+161
+162
+163
+164
+165
+166
+167
+168
+169
+170
+171
+172
+173
+174
+175
+176
+177
+178
+179
+180
+181
+182
+183
+184
+185
+186
+187
+188
+189
+190
+191
+192
+193
+194
+195
+196
+197
+198
+199
+200
+201
+202
+203
+204
+205
+206
+207
+208
+209
+210
+211
+212
+213
+214
+215
+216
+217
+218
+219
+220
+221
+222
+223
+224
+225
+226
+227
+228
+229
+230
+231
+232
+233
+234
+235
+236
+237
+238
+239
+240
+241
+242
+243
+244
+245
+246
+247
+248
+249
+250
+251
+252
+253
+254
+255
+256
+257
+258
+259
+260
+261
+262
+263
+264
+265
+266
+267
+268
+269
+270
+271
+272
+273
+274
+275
+276
+277
+278
+279
+280
+281
+282
+283
+284
+285
+286
+287
+288
+289
+290
+291
+292
+293
+294
+295
+296
+297
+298
+299
+300
+301
+302
+303
+304
+305
+306
+307
+308
+309
+310
+311
+312
+313
+314
+315
+316
+317
+318
+319
+320
+321
+322
+323
+324
+325
+326
+327
+328
+329
+330
+331
+332
+333
+334
+335
+336
+337
+338
+339
+340
+341
+342
+343
+344
+345
+346
+347
+348
+349
+350
+351
+352
+353
+354
+355
+356
+357
+358
+359
+360
+361
+362
+363
+364
+365
+366
+367
+368
+369
+370
+371
+372
+373
+374
+375
+376
+377
+378
+379
+380
+381
+382
+383
+384
+385
+386
+387
+388
+389
+390
+391
+392
+393
+394
+395
+396
+397
+398
+399
+400
+401
+402
+403
+404
+405
+406
+407
+408
+409
+410
+411
+412
+413
+414
+415
+416
+417
+418
+419
+420
+421
+422
+423
+424
+425
+426
+427
+428
+429
+430
+431
+432
+433
+434
+435
+436
+437
+438
+439
+440
+441
+442
+443
+444
+445
+446
+447
+448
+449
+450
+451
+452
+453
+454
+455
+456
+457
+458
+459
+460
+461
+462
+463
+464
+465
+466
+467
+468
+469
+470
+471
+472
+473
+474
+475
+476
+477
+478
+479
+480
+481
+482
+483
+484
+485
+486
+487
+488
+489
+490
+491
+492
+493
+494
+495
+496
+497
+498
+499
+500
+501
+502
+503
+504
+505
+506
+507
+508
+509
+510
+511
+512
+513
+514
+515
+516
+517
+518
+519
+520
+521
+522
+523
+524
+525
+526
+527
+528
+529
+530
+531
+532
+533
+534
+535
+536
+537
+538
+539
+540
+541
+542
+543
+544
+545
+546
+547
+548
+549
+550
+551
+552
+553
+554
+555
+556
+557
+558
+559
+560
+561
+562
+563
+564
+565
+566
+567
+568
+569
+570
+571
+572
+573
+574
+575
+576
+577
+578
+579
+580
+581
+582
+583
+584
+585
+586
+587
+588
+589
+590
+591
+592
+593
+594
+595
+596
+597
+598
+599
+600
+601
+602
+603
+604
+605
+606
+607
+608
+609
+610
+611
+612
+613
+614
+615
+616
+617
+618
+619
+620
+621
+622
+623
+624
+625
+626
+627
+628
+629
+630
+631
+632
+633
+634
+635
+636
+637
+638
+639
+640
+641
+642
+643
+644
+645
+646
+647
+648
+649
+650
+651
+652
+653
+654
+655
+656
+657
+658
+659
+660
+661
+662
+663
+664
+665
+666
+667
+668
+669
+670
+671
+672
+673
+674
+675
+676
+677
+678
+679
+680
+681
+682
+683
+684
+685
+686
+687
+688
+689
+690
+691
+692
+693
+694
+695
+696
+697
+698
+699
+700
+701
+702
+703
+704
+705
+706
+707
+708
+709
+710
+711
+712
+713
+714
+715
+716
+717
+718
+719
+720
+721
+722
+723
+724
+725
+726
+727
+728
+729
+730
+731
+732
+733
+734
+735
+736
+737
+738
+739
+740
+741
+742
+743
+744
+745
+746
+747
+748
+749
+750
+751
+752
+753
+754
+755
+756
+757
+758
+759
+760
+761
+762
+763
+764
+765
+766
+767
+768
+769
+770
+771
+772
+773
+774
+775
+776
+777
+778
+779
+780
+781
+782
+783
+784
+785
+786
+787
+788
+789
+790
+791
+792
+793
+794
+795
+796
+797
+798
// *****************************************************************************
 /*!
-  \file      src/Inciter/FV.cpp
+  \file      src/PDE/Transport/CGTransport.hpp
   \copyright 2012-2015 J. Bakosi,
              2016-2018 Los Alamos National Security, LLC.,
              2019-2021 Triad National Security, LLC.
              All rights reserved. See the LICENSE file for details.
-  \brief     FV advances a system of PDEs with the finite volume scheme
-  \details   FV advances a system of partial differential equations (PDEs) using
-    the finite volume (FV) (on tetrahedron elements).
-  \see The documentation in FV.h.
-*/
-// *****************************************************************************
-
-#include <algorithm>
-#include <numeric>
-#include <sstream>
-
-#include "FV.hpp"
-#include "Discretization.hpp"
-#include "FVPDE.hpp"
-#include "DiagReducer.hpp"
-#include "DerivedData.hpp"
-#include "ElemDiagnostics.hpp"
-#include "Inciter/InputDeck/InputDeck.hpp"
-#include "Refiner.hpp"
-#include "Limiter.hpp"
-#include "PrefIndicator.hpp"
-#include "Reorder.hpp"
-#include "Vector.hpp"
-#include "Around.hpp"
-#include "Integrate/Basis.hpp"
-#include "FieldOutput.hpp"
-#include "ChareStateCollector.hpp"
+  \brief     Scalar transport using continous Galerkin discretization
+  \details   This file implements the physics operators governing transported
+     scalars using continuous Galerkin discretization.
+*/
+// *****************************************************************************
+#ifndef CGTransport_h
+#define CGTransport_h
+
+#include <vector>
+#include <array>
+#include <limits>
+#include <cmath>
+#include <unordered_set>
+#include <unordered_map>
+
+#include "Exception.hpp"
+#include "Vector.hpp"
+#include "DerivedData.hpp"
+#include "Around.hpp"
+#include "Reconstruction.hpp"
+#include "Inciter/InputDeck/InputDeck.hpp"
+#include "CGPDE.hpp"
+#include "History.hpp"
+
+namespace inciter {
+
+extern ctr::InputDeck g_inputdeck;
 
-namespace inciter {
+namespace cg {
 
-extern ctr::InputDeck g_inputdeck;
-extern std::vector< FVPDE > g_fvpde;
-
-} // inciter::
-
-extern tk::CProxy_ChareStateCollector stateProxy;
-
-using inciter::FV;
-
-FV::FV( const CProxy_Discretization& disc,
-        const CProxy_Ghosts& ghostsproxy,
-        const std::map< int, std::vector< std::size_t > >& bface,
-        const std::map< int, std::vector< std::size_t > >& /* bnode */,
-        const std::vector< std::size_t >& triinpoel ) :
-  m_disc( disc ),
-  m_ghosts( ghostsproxy ),
-  m_nsol( 0 ),
-  m_ninitsol( 0 ),
-  m_nlim( 0 ),
-  m_nnod( 0 ),
-  m_u( Disc()->Inpoel().size()/4,
-       g_inputdeck.get< tag::rdof >()*
-       g_inputdeck.get< tag::ncomp >() ),
-  m_un( m_u.nunk(), m_u.nprop() ),
-  m_p( m_u.nunk(), g_inputdeck.get< tag::rdof >()*
-    g_fvpde[Disc()->MeshId()].nprim() ),
-  m_lhs( m_u.nunk(),
-         g_inputdeck.get< tag::ncomp >() ),
-  m_rhs( m_u.nunk(), m_lhs.nprop() ),
-  m_npoin( Disc()->Coord()[0].size() ),
-  m_diag(),
-  m_stage( 0 ),
-  m_uc(),
-  m_pc(),
-  m_initial( 1 ),
-  m_uElemfields( m_u.nunk(), m_lhs.nprop() ),
-  m_pElemfields(m_u.nunk(),
-    m_p.nprop()/g_inputdeck.get< tag::rdof >()),
-  m_uNodefields( m_npoin, m_lhs.nprop() ),
-  m_pNodefields(m_npoin,
-    m_p.nprop()/g_inputdeck.get< tag::rdof >()),
-  m_uNodefieldsc(),
-  m_pNodefieldsc(),
-  m_boxelems(),
-  m_srcFlag(m_u.nunk(), 0),
-  m_nrk(0),
-  m_dte(m_u.nunk(), 0.0),
-  m_finished(0)
-// *****************************************************************************
-//  Constructor
-//! \param[in] disc Discretization proxy
-//! \param[in] bface Boundary-faces mapped to side set ids
-//! \param[in] triinpoel Boundary-face connectivity
-// *****************************************************************************
-{
-  //! Runge-Kutta coefficients
-  m_nrk = 2;
-  m_rkcoef[0].resize(m_nrk);
-  m_rkcoef[1].resize(m_nrk);
-  if (m_nrk == 2) {
-    m_rkcoef = {{ {{ 0.0, 1.0/2.0 }}, {{ 1.0, 1.0/2.0 }} }};
-  }
-  else {
-    m_rkcoef = {{ {{ 0.0, 3.0/4.0, 1.0/3.0 }}, {{ 1.0, 1.0/4.0, 2.0/3.0 }} }};
-  }
-
-  if (g_inputdeck.get< tag::cmd, tag::chare >() ||
-      g_inputdeck.get< tag::cmd, tag::quiescence >())
-    stateProxy.ckLocalBranch()->insert( "FV", thisIndex, CkMyPe(), Disc()->It(),
-                                        "FV" );
-
-  usesAtSync = true;    // enable migration at AtSync
-
-  // Enable SDAG wait for initially building the solution vector and limiting
-  if (m_initial) {
-    thisProxy[ thisIndex ].wait4sol();
-    thisProxy[ thisIndex ].wait4lim();
-    thisProxy[ thisIndex ].wait4nod();
-  }
-
-  m_ghosts[thisIndex].insert(m_disc, bface, triinpoel, m_u.nunk(),
-    CkCallback(CkIndex_FV::resizeSolVectors(), thisProxy[thisIndex]));
-
-  // global-sync to call doneInserting on m_ghosts
-  auto meshid = Disc()->MeshId();
-  contribute( sizeof(std::size_t), &meshid, CkReduction::nop,
-    CkCallback(CkReductionTarget(Transporter,doneInsertingGhosts),
-    Disc()->Tr()) );
-}
-
-void
-FV::registerReducers()
-// *****************************************************************************
-//  Configure Charm++ reduction types
-//! \details Since this is a [initnode] routine, the runtime system executes the
-//!   routine exactly once on every logical node early on in the Charm++ init
-//!   sequence. Must be static as it is called without an object. See also:
-//!   Section "Initializations at Program Startup" at in the Charm++ manual
-//!   http://charm.cs.illinois.edu/manuals/html/charm++/manual.html.
-// *****************************************************************************
-{
-  ElemDiagnostics::registerReducers();
-}
-
-void
-FV::ResumeFromSync()
-// *****************************************************************************
-//  Return from migration
-//! \details This is called when load balancing (LB) completes. The presence of
-//!   this function does not affect whether or not we block on LB.
-// *****************************************************************************
-{
-  if (Disc()->It() == 0) Throw( "it = 0 in ResumeFromSync()" );
-
-  if (!g_inputdeck.get< tag::cmd, tag::nonblocking >()) next();
-}
-
-void
-FV::resizeSolVectors()
-// *****************************************************************************
-// Resize solution vectors after extension due to Ghosts
-// *****************************************************************************
-{
-  // Resize solution vectors, lhs and rhs by the number of ghost tets
-  m_u.resize( myGhosts()->m_nunk );
-  m_un.resize( myGhosts()->m_nunk );
-  m_srcFlag.resize( myGhosts()->m_nunk );
-  m_p.resize( myGhosts()->m_nunk );
-  m_lhs.resize( myGhosts()->m_nunk );
-  m_rhs.resize( myGhosts()->m_nunk );
-  m_dte.resize( myGhosts()->m_nunk );
-
-  // Size communication buffer for solution
-  for (auto& u : m_uc) u.resize( myGhosts()->m_bid.size() );
-  for (auto& p : m_pc) p.resize( myGhosts()->m_bid.size() );
-
-  // Ensure that we also have all the geometry and connectivity data
-  // (including those of ghosts)
-  Assert( myGhosts()->m_geoElem.nunk() == m_u.nunk(),
-    "GeoElem unknowns size mismatch" );
-
-  // Signal the runtime system that all workers have received their adjacency
-  std::vector< std::size_t > meshdata{ myGhosts()->m_initial, Disc()->MeshId() };
-  contribute( meshdata, CkReduction::sum_ulong,
-    CkCallback(CkReductionTarget(Transporter,comfinal), Disc()->Tr()) );
-}
-
-void
-FV::setup()
-// *****************************************************************************
-// Set initial conditions, generate lhs, output mesh
-// *****************************************************************************
-{
-  if (g_inputdeck.get< tag::cmd, tag::chare >() ||
-      g_inputdeck.get< tag::cmd, tag::quiescence >())
-    stateProxy.ckLocalBranch()->insert( "FV", thisIndex, CkMyPe(), Disc()->It(),
-                                        "setup" );
-
-  auto d = Disc();<--- Variable 'd' is assigned a value that is never used.
-
-  // Basic error checking on sizes of element geometry data and connectivity
-  Assert( myGhosts()->m_geoElem.nunk() == m_lhs.nunk(),
-    "Size mismatch in FV::setup()" );
-
-  // Compute left-hand side of discrete PDEs
-  lhs();
-
-  // Determine elements inside user-defined IC box
-  g_fvpde[d->MeshId()].IcBoxElems( myGhosts()->m_geoElem,
-    myGhosts()->m_fd.Esuel().size()/4, m_boxelems );
-
-  // Compute volume of user-defined box IC
-  d->boxvol( {}, {}, 0 );      // punt for now
-
-  // Query time history field output labels from all PDEs integrated
-  const auto& hist_points = g_inputdeck.get< tag::history_output, tag::point >();
-  if (!hist_points.empty()) {
-    std::vector< std::string > histnames;
-    auto n = g_fvpde[d->MeshId()].histNames();
-    histnames.insert( end(histnames), begin(n), end(n) );
-    d->histheader( std::move(histnames) );
-  }
-}
-
-void
-FV::box( tk::real v, const std::vector< tk::real >& )
-// *****************************************************************************
-// Receive total box IC volume and set conditions in box
-//! \param[in] v Total volume within user-specified box
-// *****************************************************************************
-{
-  auto d = Disc();
-
-  // Store user-defined box IC volume
-  d->Boxvol() = v;
-
-  // Set initial conditions for all PDEs
-  g_fvpde[d->MeshId()].initialize( m_lhs, myGhosts()->m_inpoel,
-    myGhosts()->m_coord, m_boxelems, d->ElemBlockId(), m_u, d->T(),
-    myGhosts()->m_fd.Esuel().size()/4 );
-  g_fvpde[d->MeshId()].updatePrimitives( m_u, m_p,
-    myGhosts()->m_fd.Esuel().size()/4 );
-
-  m_un = m_u;
-
-  // Output initial conditions to file (regardless of whether it was requested)
-  startFieldOutput( CkCallback(CkIndex_FV::start(), thisProxy[thisIndex]) );
-}
-
-void
-FV::start()
-// *****************************************************************************
-//  Start time stepping
-// *****************************************************************************
-{
-  // Start timer measuring time stepping wall clock time
-  Disc()->Timer().zero();
-  // Zero grind-timer
-  Disc()->grindZero();
-  // Start time stepping by computing the size of the next time step)
-  next();
-}
-
-void
-FV::startFieldOutput( CkCallback c )
-// *****************************************************************************
-// Start preparing fields for output to file
-//! \param[in] c Function to continue with after the write
-// *****************************************************************************
-{
-  // No field output in benchmark mode or if field output frequency not hit
-  if (g_inputdeck.get< tag::cmd, tag::benchmark >() || !fieldOutput()) {
-
-    c.send();
-
-  } else {
+//! \brief Transport equation used polymorphically with tk::CGPDE
+//! \details The template argument(s) specify policies and are used to configure
+//!   the behavior of the class. The policies are:
+//!   - Physics - physics configuration, see PDE/Transport/Physics/CG.h
+//!   - Problem - problem configuration, see PDE/Transport/Problem.h
+//! \note The default physics is CGAdvection, set in
+//!    inciter::deck::check_transport()
+template< class Physics, class Problem >
+class Transport {
+
+  private:
+    using ncomp_t = tk::ncomp_t;
+    using real = tk::real;
+    using eq = tag::transport;
+
+    static constexpr real muscl_eps = 1.0e-9;
+    static constexpr real muscl_const = 1.0/3.0;
+    static constexpr real muscl_m1 = 1.0 - muscl_const;
+    static constexpr real muscl_p1 = 1.0 + muscl_const;
+
+  public:
+    //! Constructor
+    explicit Transport() :
+      m_physics( Physics() ),
+      m_problem( Problem() ),
+      m_ncomp(g_inputdeck.get< tag::ncomp >())
+    {
+      m_problem.errchk( m_ncomp );
+    }
+
+    //! Determine nodes that lie inside the user-defined IC box
+    void
+    IcBoxNodes( const tk::UnsMesh::Coords&,
+                const std::vector< std::size_t >&,
+                const std::unordered_map< std::size_t, std::set< std::size_t > >&,
+                std::vector< std::unordered_set< std::size_t > >&,
+                std::unordered_map< std::size_t, std::set< std::size_t > >&,
+                std::size_t& ) const {}
+
+    //! Initalize the transport equations using problem policy
+    //! \param[in] coord Mesh node coordinates
+    //! \param[in,out] unk Array of unknowns
+    //! \param[in] t Physical time
+    void
+    initialize( const std::array< std::vector< real >, 3 >& coord,
+                tk::Fields& unk,
+                real t,
+                real,
+                const std::vector< std::unordered_set< std::size_t > >&,
+                const std::vector< tk::real >&,
+                const std::unordered_map< std::size_t, std::set< std::size_t > >&
+              ) const
+    {
+      Assert( coord[0].size() == unk.nunk(), "Size mismatch" );
+      const auto& x = coord[0];
+      const auto& y = coord[1];
+      const auto& z = coord[2];
+      for (ncomp_t i=0; i<x.size(); ++i) {
+        auto s = Problem::initialize( m_ncomp, m_mat_blk, x[i], y[i],
+                                      z[i], t );
+        for (ncomp_t c=0; c<m_ncomp; ++c)
+          unk( i, c ) = s[c];
+      }
+    }
+
+    //! Query a velocity
+    //! \note Since this function does not touch its output argument, that
+    //!   means this system does not define a "velocity".
+    void velocity( const tk::Fields&, tk::UnsMesh::Coords& ) const {}
+
+    //! Query the sound speed
+    //! \note Since this function does not touch its output argument, that
+    //!   means this system does not define a "sound speed".
+    void soundspeed( const tk::Fields&, std::vector< tk::real >& ) const {}
+
+    //! Return analytic solution (if defined by Problem) at xi, yi, zi, t
+    //! \param[in] xi X-coordinate
+    //! \param[in] yi Y-coordinate
+    //! \param[in] zi Z-coordinate
+    //! \param[in] t Physical time
+    //! \return Vector of analytic solution at given location and time
+    std::vector< real >
+    analyticSolution( real xi, real yi, real zi, real t ) const
+    { return Problem::analyticSolution( m_ncomp, m_mat_blk, xi, yi, zi, t ); }
+
+    //! Return analytic solution for conserved variables
+    //! \param[in] xi X-coordinate at which to evaluate the analytic solution
+    //! \param[in] yi Y-coordinate at which to evaluate the analytic solution
+    //! \param[in] zi Z-coordinate at which to evaluate the analytic solution
+    //! \param[in] t Physical time at which to evaluate the analytic solution
+    //! \return Vector of analytic solution at given location and time
+    std::vector< tk::real >
+    solution( tk::real xi, tk::real yi, tk::real zi, tk::real t ) const
+    { return Problem::initialize( m_ncomp, m_mat_blk, xi, yi, zi, t ); }
+
+    //! Compute nodal gradients of primitive variables for ALECG
+    //! \param[in] coord Mesh node coordinates
+    //! \param[in] inpoel Mesh element connectivity
+    //! \param[in] bndel List of elements contributing to chare-boundary nodes
+    //! \param[in] gid Local->global node id map
+    //! \param[in] bid Local chare-boundary node ids (value) associated to
+    //!    global node ids (key)
+    //! \param[in] U Solution vector at recent time step
+    //! \param[in,out] G Nodal gradients of primitive variables
+    void chBndGrad( const std::array< std::vector< real >, 3 >& coord,
+      const std::vector< std::size_t >& inpoel,
+      const std::vector< std::size_t >& bndel,
+      const std::vector< std::size_t >& gid,
+      const std::unordered_map< std::size_t, std::size_t >& bid,
+      const tk::Fields& U,
+      tk::Fields& G ) const
+    {
+      Assert( U.nunk() == coord[0].size(), "Number of unknowns in solution "
+              "vector at recent time step incorrect" );
+
+      // compute gradients of primitive variables in points
+      G.fill( 0.0 );
+
+      // access node cooordinates
+      const auto& x = coord[0];
+      const auto& y = coord[1];
+      const auto& z = coord[2];
+
+      for (auto e : bndel) {  // elements contributing to chare boundary nodes
+        // access node IDs
+        std::size_t N[4] =
+          { inpoel[e*4+0], inpoel[e*4+1], inpoel[e*4+2], inpoel[e*4+3] };
+        // compute element Jacobi determinant, J = 6V
+        real bax = x[N[1]]-x[N[0]];
+        real bay = y[N[1]]-y[N[0]];
+        real baz = z[N[1]]-z[N[0]];
+        real cax = x[N[2]]-x[N[0]];
+        real cay = y[N[2]]-y[N[0]];
+        real caz = z[N[2]]-z[N[0]];
+        real dax = x[N[3]]-x[N[0]];
+        real day = y[N[3]]-y[N[0]];
+        real daz = z[N[3]]-z[N[0]];
+        auto J = tk::triple( bax, bay, baz, cax, cay, caz, dax, day, daz );
+        auto J24 = J/24.0;
+        // shape function derivatives, nnode*ndim [4][3]
+        real g[4][3];
+        tk::crossdiv( cax, cay, caz, dax, day, daz, J,
+                      g[1][0], g[1][1], g[1][2] );
+        tk::crossdiv( dax, day, daz, bax, bay, baz, J,
+                      g[2][0], g[2][1], g[2][2] );
+        tk::crossdiv( bax, bay, baz, cax, cay, caz, J,
+                      g[3][0], g[3][1], g[3][2] );
+        for (std::size_t i=0; i<3; ++i)
+          g[0][i] = -g[1][i] - g[2][i] - g[3][i];
+        // scatter-add gradient contributions to boundary nodes
+        for (std::size_t a=0; a<4; ++a) {
+          auto i = bid.find( gid[N[a]] );
+          if (i != end(bid))
+            for (std::size_t c=0; c<m_ncomp; ++c)
+              for (std::size_t b=0; b<4; ++b)
+                for (std::size_t j=0; j<3; ++j)
+                  G(i->second,c*3+j) += J24 * g[b][j] * U(N[b],c);
+        }
+      }
+    }
+
+    //! Compute right hand side for ALECG
+    //! \param[in] coord Mesh node coordinates
+    //! \param[in] inpoel Mesh element connectivity
+    //! \param[in] triinpoel Boundary triangle face connecitivity
+    //! \param[in] bid Local chare-boundary node ids (value) associated to
+    //!    global node ids (key)
+    //! \param[in] lid Global->local node ids
+    //! \param[in] dfn Dual-face normals
+    //! \param[in] psup Points surrounding points
+    //! \param[in] esup Elements surrounding points
+    //! \param[in] symbctri Vector with 1 at symmetry BC nodes
+    //! \param[in] vol Nodal volumes
+    //! \param[in] edgeid Local node id pair -> edge id map
+    //! \param[in] G Nodal gradients in chare-boundary nodes
+    //! \param[in] U Solution vector at recent time step
+    //! \param[in] W Mesh velocity
+    //! \param[in,out] R Right-hand side vector computed
+    void rhs(
+      real,
+      const std::array< std::vector< real >, 3 >&  coord,
+      const std::vector< std::size_t >& inpoel,
+      const std::vector< std::size_t >& triinpoel,
+      const std::vector< std::size_t >&,
+      const std::unordered_map< std::size_t, std::size_t >& bid,
+      const std::unordered_map< std::size_t, std::size_t >& lid,
+      const std::vector< real >& dfn,
+      const std::pair< std::vector< std::size_t >,
+                       std::vector< std::size_t > >& psup,
+      const std::pair< std::vector< std::size_t >,
+                       std::vector< std::size_t > >& esup,
+      const std::vector< int >& symbctri,
+      const std::vector< real >& vol,
+      const std::vector< std::size_t >&,
+      const std::vector< std::size_t >& edgeid,
+      const std::vector< std::unordered_set< std::size_t > >&,
+      const tk::Fields& G,
+      const tk::Fields& U,
+      [[maybe_unused]] const tk::Fields& W,
+      const std::vector< tk::real >&,
+      real,
+      tk::Fields& R ) const
+    {
+      Assert( G.nprop() == m_ncomp*3,
+              "Number of components in gradient vector incorrect" );
+      Assert( U.nunk() == coord[0].size(), "Number of unknowns in solution "
+              "vector at recent time step incorrect" );
+      Assert( R.nunk() == coord[0].size(),
+              "Number of unknowns and/or number of components in right-hand "
+              "side vector incorrect" );
+
+      // compute/assemble gradients in points
+      auto Grad = nodegrad( coord, inpoel, lid, bid, vol, esup, U, G );
+
+      // zero right hand side for all components
+      for (ncomp_t c=0; c<m_ncomp; ++c) R.fill( c, 0.0 );
+
+      // compute domain-edge integral
+      domainint( coord, inpoel, edgeid, psup, dfn, U, Grad, R );
+
+      // compute boundary integrals
+      bndint( coord, triinpoel, symbctri, U, R );
+    }
+
+    //! Compute overset mesh motion for OversetFE (no-op for transport)
+    void getMeshVel(
+      real,
+      const std::array< std::vector< real >, 3 >&,
+      const std::pair< std::vector< std::size_t >,
+                       std::vector< std::size_t > >&,
+      const std::unordered_set< std::size_t >&,
+      const std::array< tk::real, 3 >&,
+      const tk::Fields&,
+      tk::Fields&,
+      int& ) const
+    { }
 
-    // Optionally refine mesh for field output
-    auto d = Disc();
-
-    if (refinedOutput()) {
-
-      const auto& tr = tk::remap( myGhosts()->m_fd.Triinpoel(), d->Gid() );
-      d->Ref()->outref( myGhosts()->m_fd.Bface(), {}, tr, c );
-
-    } else {
-
-      // cut off ghosts from mesh connectivity and coordinates
-      extractFieldOutput( {}, d->Chunk(), d->Coord(), {}, {}, d->NodeCommMap(),
-        {}, {}, {}, c );
-
-    }
-
-  }
-}
-
-void
-FV::next()
-// *****************************************************************************
-// Advance equations to next time step
-// *****************************************************************************
-{
-  // communicate solution ghost data (if any)
-  if (myGhosts()->m_sendGhost.empty())
-    comsol_complete();
-  else
-    for(const auto& [cid, ghostdata] : myGhosts()->m_sendGhost) {
-      std::vector< std::size_t > tetid( ghostdata.size() );
-      std::vector< std::vector< tk::real > > u( ghostdata.size() ),
-                                             prim( ghostdata.size() );
-      std::size_t j = 0;
-      for(const auto& i : ghostdata) {
-        Assert( i < myGhosts()->m_fd.Esuel().size()/4,
-          "Sending solution ghost data" );
-        tetid[j] = i;
-        u[j] = m_u[i];
-        prim[j] = m_p[i];
-        ++j;
-      }
-      thisProxy[ cid ].comsol( thisIndex, tetid, u, prim );
-    }
-
-  ownsol_complete();
-}
-
-void
-FV::comsol( int fromch,
-            const std::vector< std::size_t >& tetid,
-            const std::vector< std::vector< tk::real > >& u,
-            const std::vector< std::vector< tk::real > >& prim )
-// *****************************************************************************
-//  Receive chare-boundary solution ghost data from neighboring chares
-//! \param[in] fromch Sender chare id
-//! \param[in] tetid Ghost tet ids we receive solution data for
-//! \param[in] u Solution ghost data
-//! \param[in] prim Primitive variables in ghost cells
-//! \details This function receives contributions to the unlimited solution
-//!   from fellow chares.
-// *****************************************************************************
-{
-  Assert( u.size() == tetid.size(), "Size mismatch in FV::comsol()" );
-  Assert( prim.size() == tetid.size(), "Size mismatch in FV::comsol()" );
+    //! Compute the minimum time step size (for unsteady time stepping)
+    //! \param[in] U Solution vector at recent time step
+    //! \param[in] coord Mesh node coordinates
+    //! \param[in] inpoel Mesh element connectivity
+    //! \param[in] t Physical time
+    //! \return Minimum time step size
+    real dt( const std::array< std::vector< real >, 3 >& coord,
+             const std::vector< std::size_t >& inpoel,
+             tk::real t,
+             tk::real,
+             const tk::Fields& U,
+             const std::vector< tk::real >&,
+             const std::vector< tk::real >& ) const
+    {
+      using tag::transport;
+      Assert( U.nunk() == coord[0].size(), "Number of unknowns in solution "
+              "vector at recent time step incorrect" );
+      const auto& x = coord[0];
+      const auto& y = coord[1];
+      const auto& z = coord[2];
+      // compute the minimum dt across all elements we own
+      auto mindt = std::numeric_limits< tk::real >::max();
+      auto eps = std::numeric_limits< tk::real >::epsilon();
+      auto large = std::numeric_limits< tk::real >::max();
+      for (std::size_t e=0; e<inpoel.size()/4; ++e) {
+        const std::array< std::size_t, 4 >
+          N{{ inpoel[e*4+0], inpoel[e*4+1], inpoel[e*4+2], inpoel[e*4+3] }};
+        // compute cubic root of element volume as the characteristic length
+        const std::array< real, 3 >
+          ba{{ x[N[1]]-x[N[0]], y[N[1]]-y[N[0]], z[N[1]]-z[N[0]] }},
+          ca{{ x[N[2]]-x[N[0]], y[N[2]]-y[N[0]], z[N[2]]-z[N[0]] }},
+          da{{ x[N[3]]-x[N[0]], y[N[3]]-y[N[0]], z[N[3]]-z[N[0]] }};
+        const auto L = std::cbrt( tk::triple( ba, ca, da ) / 6.0 );
+        // access solution at element nodes at recent time step
+        std::vector< std::array< real, 4 > > u( m_ncomp );
+        for (ncomp_t c=0; c<m_ncomp; ++c) u[c] = U.extract( c, N );
+        // get velocity for problem
+        const std::array< std::vector<std::array<real,3>>, 4 > vel{{
+          Problem::prescribedVelocity( m_ncomp,
+                                       x[N[0]], y[N[0]], z[N[0]], t ),
+          Problem::prescribedVelocity( m_ncomp,
+                                       x[N[1]], y[N[1]], z[N[1]], t ),
+          Problem::prescribedVelocity( m_ncomp,
+                                       x[N[2]], y[N[2]], z[N[2]], t ),
+          Problem::prescribedVelocity( m_ncomp,
+                                       x[N[3]], y[N[3]], z[N[3]], t ) }};
+        // compute the maximum length of the characteristic velocity (advection
+        // velocity) across the four element nodes
+        real maxvel = 0.0;
+        for (ncomp_t c=0; c<m_ncomp; ++c)
+          for (std::size_t i=0; i<4; ++i) {
+            auto v = tk::length( vel[i][c] );
+            if (v > maxvel) maxvel = v;
+          }
+        // compute element dt for the advection
+        auto advection_dt = std::abs(maxvel) > eps ? L / maxvel : large;
+        // compute element dt based on diffusion
+        auto diffusion_dt = m_physics.diffusion_dt( m_ncomp, L, u );
+        // compute minimum element dt
+        auto elemdt = std::min( advection_dt, diffusion_dt );
+        // find minimum dt across all elements
+        if (elemdt < mindt) mindt = elemdt;
+      }
+      return mindt * g_inputdeck.get< tag::cfl >();
+    }
 
-  // Find local-to-ghost tet id map for sender chare
-  const auto& n = tk::cref_find( myGhosts()->m_ghost, fromch );
-
-  for (std::size_t i=0; i<tetid.size(); ++i) {
-    auto j = tk::cref_find( n, tetid[i] );
-    Assert( j >= myGhosts()->m_fd.Esuel().size()/4,
-      "Receiving solution non-ghost data" );
-    auto b = tk::cref_find( myGhosts()->m_bid, j );
-    Assert( b < m_uc[0].size(), "Indexing out of bounds" );
-    m_uc[0][b] = u[i];
-    m_pc[0][b] = prim[i];
-  }
-
-  // if we have received all solution ghost contributions from neighboring
-  // chares (chares we communicate along chare-boundary faces with), and
-  // contributed our solution to these neighbors, proceed to reconstructions
-  if (++m_nsol == myGhosts()->m_sendGhost.size()) {
-    m_nsol = 0;
-    comsol_complete();
-  }
-}
-
-void
-FV::extractFieldOutput(
-  const std::vector< std::size_t >& /*ginpoel*/,
-  const tk::UnsMesh::Chunk& chunk,
-  const tk::UnsMesh::Coords& coord,
-  const std::unordered_map< std::size_t, tk::UnsMesh::Edge >& /*addedNodes*/,
-  const std::unordered_map< std::size_t, std::size_t >& addedTets,
-  const tk::NodeCommMap& nodeCommMap,
-  const std::map< int, std::vector< std::size_t > >& /* bface */,
-  const std::map< int, std::vector< std::size_t > >& /* bnode */,
-  const std::vector< std::size_t >& /* triinpoel */,
-  CkCallback c )
-// *****************************************************************************
-// Extract field output going to file
-//! \param[in] chunk Field-output mesh chunk (connectivity and global<->local
-//!    id maps)
-//! \param[in] coord Field-output mesh node coordinates
-//! \param[in] addedTets Field-output mesh cells and their parents (local ids)
-//! \param[in] nodeCommMap Field-output mesh node communication map
-//! \param[in] c Function to continue with after the write
-// *****************************************************************************
-{
-  const auto& inpoel = std::get< 0 >( chunk );
-
-  // Evaluate element solution on incoming mesh
-  evalSolution( *Disc(), inpoel, coord, addedTets, std::vector< std::size_t>{},
-    m_u, m_p, m_uElemfields, m_pElemfields, m_uNodefields, m_pNodefields );
-
-  // Send node fields contributions to neighbor chares
-  if (nodeCommMap.empty())
-    comnodeout_complete();
-  else {
-    const auto& lid = std::get< 2 >( chunk );
-    auto esup = tk::genEsup( inpoel, 4 );
-    for(const auto& [ch,nodes] : nodeCommMap) {
-      // Pack node field data in chare boundary nodes
-      std::vector< std::vector< tk::real > >
-        lu( m_uNodefields.nprop(), std::vector< tk::real >( nodes.size() ) );
-      std::vector< std::vector< tk::real > >
-        lp( m_pNodefields.nprop(), std::vector< tk::real >( nodes.size() ) );
-      for (std::size_t f=0; f<m_uNodefields.nprop(); ++f) {
-        std::size_t j = 0;
-        for (auto g : nodes)
-          lu[f][j++] = m_uNodefields(tk::cref_find(lid,g),f);
-      }
-      for (std::size_t f=0; f<m_pNodefields.nprop(); ++f) {
-        std::size_t j = 0;
-        for (auto g : nodes)
-          lp[f][j++] = m_pNodefields(tk::cref_find(lid,g),f);
-      }
-      // Pack (partial) number of elements surrounding chare boundary nodes
-      std::vector< std::size_t > nesup( nodes.size() );
-      std::size_t j = 0;
-      for (auto g : nodes) {
-        auto i = tk::cref_find( lid, g );
-        nesup[j++] = esup.second[i+1] - esup.second[i];
-      }
-      thisProxy[ch].comnodeout(
-        std::vector<std::size_t>(begin(nodes),end(nodes)), nesup, lu, lp );
-    }
-  }
+    //! Compute a time step size for each mesh node (for steady time stepping)
+    void dt( uint64_t,
+             const std::vector< tk::real >&,
+             const tk::Fields&,
+             std::vector< tk::real >& ) const {}
+
+    //! \brief Query Dirichlet boundary condition value on a given side set for
+    //!    all components in this PDE system
+    //! \param[in] t Physical time
+    //! \param[in] deltat Time step size
+    //! \param[in] tp Physical time for each mesh node
+    //! \param[in] dtp Time step size for each mesh node
+    //! \param[in] ss Pair of side set ID and list of node IDs on the side set
+    //! \param[in] coord Mesh node coordinates
+    //! \param[in] increment If true, evaluate the solution increment between
+    //!   t and t+dt for Dirichlet BCs. If false, evlauate the solution instead.
+    //! \return Vector of pairs of bool and boundary condition value associated
+    //!   to mesh node IDs at which Dirichlet boundary conditions are set. Note
+    //!   that if increment is true, instead of the actual boundary condition
+    //!   value, we return the increment between t+deltat and t, since,
+    //!   depending on client code and solver, that may be what the solution
+    //!   requires.
+    std::map< std::size_t, std::vector< std::pair<bool,real> > >
+    dirbc( real t,
+           real deltat,
+           const std::vector< tk::real >& tp,
+           const std::vector< tk::real >& dtp,
+           const std::pair< const int, std::vector< std::size_t > >& ss,
+           const std::array< std::vector< real >, 3 >& coord,
+           bool increment ) const
+    {
+      using NodeBC = std::vector< std::pair< bool, real > >;
+      std::map< std::size_t, NodeBC > bc;
+      const auto& ubc = g_inputdeck.get< tag::bc >()[0].get< tag::dirichlet >();
+      const auto steady = g_inputdeck.get< tag::steady_state >();<--- Variable 'steady' is assigned a value that is never used.
+      if (!ubc.empty()) {
+        Assert( ubc.size() > 0, "Indexing out of Dirichlet BC eq-vector" );
+        const auto& x = coord[0];
+        const auto& y = coord[1];
+        const auto& z = coord[2];
+        for (const auto& b : ubc)
+          if (static_cast<int>(b) == ss.first)
+            for (auto n : ss.second) {
+              Assert( x.size() > n, "Indexing out of coordinate array" );
+              if (steady) { t = tp[n]; deltat = dtp[n]; }
+              const auto s = increment ?
+                solinc( m_ncomp, m_mat_blk, x[n], y[n], z[n],
+                        t, deltat, Problem::initialize ) :
+                Problem::initialize( m_ncomp, m_mat_blk, x[n], y[n],
+                                     z[n], t+deltat );
+              auto& nbc = bc[n] = NodeBC( m_ncomp );
+              for (ncomp_t c=0; c<m_ncomp; ++c)
+                nbc[c] = { true, s[c] };
+            }
+      }
+      return bc;
+    }
+
+    //! Set symmetry boundary conditions at nodes
+    void
+    symbc(
+      tk::Fields&,
+      const std::array< std::vector< real >, 3 >&,
+      const std::unordered_map< int,
+              std::unordered_map< std::size_t,
+                std::array< real, 4 > > >&,
+      const std::unordered_set< std::size_t >& ) const {}
+
+    //! Set farfield boundary conditions at nodes
+    void farfieldbc(
+      tk::Fields&,
+      const std::array< std::vector< real >, 3 >&,
+      const std::unordered_map< int,
+              std::unordered_map< std::size_t,
+                std::array< real, 4 > > >&,
+      const std::unordered_set< std::size_t >& ) const {}
+
+    //! Apply user defined time dependent BCs (no-op for transport)
+    void
+    timedepbc( tk::real,
+      tk::Fields&,
+      const std::vector< std::unordered_set< std::size_t > >&,
+      const std::vector< tk::Table<5> >& ) const {}
 
-  ownnod_complete( c );
-}
-
-void
-FV::lhs()
-// *****************************************************************************
-// Compute left-hand side of discrete transport equations
-// *****************************************************************************
-{
-  g_fvpde[Disc()->MeshId()].lhs( myGhosts()->m_geoElem, m_lhs );
-
-  if (!m_initial) stage();
-}
-
-void
-FV::reco()
-// *****************************************************************************
-// Compute reconstructions
-// *****************************************************************************
-{
-  const auto rdof = g_inputdeck.get< tag::rdof >();
-
-  // Combine own and communicated contributions of unreconstructed solution and
-  // degrees of freedom in cells (if p-adaptive)
-  for (const auto& b : myGhosts()->m_bid) {
-    Assert( m_uc[0][b.second].size() == m_u.nprop(), "ncomp size mismatch" );
-    Assert( m_pc[0][b.second].size() == m_p.nprop(), "ncomp size mismatch" );
-    for (std::size_t c=0; c<m_u.nprop(); ++c) {
-      m_u(b.first,c) = m_uc[0][b.second][c];
-    }
-    for (std::size_t c=0; c<m_p.nprop(); ++c) {
-      m_p(b.first,c) = m_pc[0][b.second][c];
-    }
-  }
-
-  if (rdof > 1) {
-    // Reconstruct second-order solution and primitive quantities
-    g_fvpde[Disc()->MeshId()].reconstruct( myGhosts()->m_geoElem, myGhosts()->m_fd,
-      myGhosts()->m_esup, myGhosts()->m_inpoel, myGhosts()->m_coord, m_u, m_p );
-  }
+    //! Return a map that associates user-specified strings to functions
+    //! \return Map that associates user-specified strings to functions that
+    //!  compute relevant quantities to be output to file
+    std::map< std::string, tk::GetVarFn > OutVarFn() const {
+      std::map< std::string, tk::GetVarFn > OutFnMap;
+      OutFnMap["material_indicator"] = transport::matIndicatorOutVar;
+
+      return OutFnMap;
+    }
+
+    //! Return analytic field names to be output to file
+    //! \return Vector of strings labelling analytic fields output in file
+    std::vector< std::string > analyticFieldNames() const {
+      std::vector< std::string > n;
+      auto depvar = g_inputdeck.get< tag::depvar >()[0];
+      for (ncomp_t c=0; c<m_ncomp; ++c)
+        n.push_back( depvar + std::to_string(c) + "_analytic" );
+      return n;
+    }
+
+    //! Return surface field names to be output to file
+    //! \return Vector of strings labelling surface fields output in file
+    //! \details This functions should be written in conjunction with
+    //!   surfOutput(), which provides the vector of surface fields to be output
+    std::vector< std::string > surfNames() const { return {}; }
+
+    //! Return nodal surface field output going to file
+    std::vector< std::vector< real > >
+    surfOutput( const std::map< int, std::vector< std::size_t > >&,
+                const tk::Fields& ) const { return {}; }
+
+    //! Return elemental surface field output (on triangle faces) going to file
+    std::vector< std::vector< real > >
+    elemSurfOutput( const std::map< int, std::vector< std::size_t > >&,
+      const std::vector< std::size_t >&,
+      const tk::Fields& ) const { return {}; }
+
+    //! Return time history field names to be output to file
+    //! \return Vector of strings labelling time history fields output in file
+    std::vector< std::string > histNames() const { return {}; }
 
-  // start limiting
-  lim();
-}
-
-void
-FV::lim()
-// *****************************************************************************
-// Compute limiter function
-// *****************************************************************************
-{
-  const auto rdof = g_inputdeck.get< tag::rdof >();
-
-  if (rdof > 1) {
-    g_fvpde[Disc()->MeshId()].limit( myGhosts()->m_geoFace, myGhosts()->m_fd,
-      myGhosts()->m_esup,
-      myGhosts()->m_inpoel, myGhosts()->m_coord, m_srcFlag, m_u, m_p );
-  }
+    //! Return time history field output evaluated at time history points
+    std::vector< std::vector< real > >
+    histOutput( const std::vector< HistData >&,
+                const std::vector< std::size_t >&,
+                const tk::Fields& ) const { return {}; }
+
+    //! Return names of integral variables to be output to diagnostics file
+    //! \return Vector of strings labelling integral variables output
+    std::vector< std::string > names() const {
+      std::vector< std::string > n;
+      const auto& depvar =
+        g_inputdeck.get< tag::depvar >().at(0);
+      // construct the name of the numerical solution for all components
+      for (ncomp_t c=0; c<m_ncomp; ++c)
+        n.push_back( depvar + std::to_string(c) );
+      return n;
+    }
 
-  // Send limited solution to neighboring chares
-  if (myGhosts()->m_sendGhost.empty())
-    comlim_complete();
-  else
-    for(const auto& [cid, ghostdata] : myGhosts()->m_sendGhost) {
-      std::vector< std::size_t > tetid( ghostdata.size() );
-      std::vector< std::vector< tk::real > > u( ghostdata.size() ),
-                                             prim( ghostdata.size() );
-      std::size_t j = 0;
-      for(const auto& i : ghostdata) {
-        Assert( i < myGhosts()->m_fd.Esuel().size()/4,
-          "Sending limiter ghost data" );
-        tetid[j] = i;
-        u[j] = m_u[i];
-        prim[j] = m_p[i];
-        ++j;
-      }
-      thisProxy[ cid ].comlim( thisIndex, tetid, u, prim );
-    }
-
-  ownlim_complete();
-}
-
-void
-FV::comlim( int fromch,
-            const std::vector< std::size_t >& tetid,
-            const std::vector< std::vector< tk::real > >& u,
-            const std::vector< std::vector< tk::real > >& prim )
-// *****************************************************************************
-//  Receive chare-boundary limiter ghost data from neighboring chares
-//! \param[in] fromch Sender chare id
-//! \param[in] tetid Ghost tet ids we receive solution data for
-//! \param[in] u Limited high-order solution
-//! \param[in] prim Limited high-order primitive quantities
-//! \details This function receives contributions to the limited solution from
-//!   fellow chares.
-// *****************************************************************************
-{
-  Assert( u.size() == tetid.size(), "Size mismatch in FV::comlim()" );
-  Assert( prim.size() == tetid.size(), "Size mismatch in FV::comlim()" );
-
-  // Find local-to-ghost tet id map for sender chare
-  const auto& n = tk::cref_find( myGhosts()->m_ghost, fromch );
-
-  for (std::size_t i=0; i<tetid.size(); ++i) {
-    auto j = tk::cref_find( n, tetid[i] );
-    Assert( j >= myGhosts()->m_fd.Esuel().size()/4,
-      "Receiving solution non-ghost data" );
-    auto b = tk::cref_find( myGhosts()->m_bid, j );
-    Assert( b < m_uc[1].size(), "Indexing out of bounds" );
-    Assert( b < m_pc[1].size(), "Indexing out of bounds" );
-    m_uc[1][b] = u[i];
-    m_pc[1][b] = prim[i];
-  }
-
-  // if we have received all solution ghost contributions from neighboring
-  // chares (chares we communicate along chare-boundary faces with), and
-  // contributed our solution to these neighbors, proceed to limiting
-  if (++m_nlim == myGhosts()->m_sendGhost.size()) {
-    m_nlim = 0;
-    comlim_complete();
-  }
-}
-
-void
-FV::dt()
-// *****************************************************************************
-// Compute time step size
-// *****************************************************************************
-{
-  auto d = Disc();
-
-  // Combine own and communicated contributions of limited solution and degrees
-  // of freedom in cells (if p-adaptive)
-  for (const auto& b : myGhosts()->m_bid) {
-    Assert( m_uc[1][b.second].size() == m_u.nprop(), "ncomp size mismatch" );
-    Assert( m_pc[1][b.second].size() == m_p.nprop(), "ncomp size mismatch" );
-    for (std::size_t c=0; c<m_u.nprop(); ++c) {
-      m_u(b.first,c) = m_uc[1][b.second][c];
-    }
-    for (std::size_t c=0; c<m_p.nprop(); ++c) {
-      m_p(b.first,c) = m_pc[1][b.second][c];
-    }
-  }
-
-  auto mindt = std::numeric_limits< tk::real >::max();
-
-  if (m_stage == 0)
-  {
-    auto const_dt = g_inputdeck.get< tag::dt >();
-    auto eps = std::numeric_limits< tk::real >::epsilon();
-
-    // use constant dt if configured
-    if (std::abs(const_dt) > eps) {
-
-      mindt = const_dt;
-
-    } else {      // compute dt based on CFL
-
-      // find the minimum dt across all PDEs integrated
-      auto eqdt =
-        g_fvpde[d->MeshId()].dt( myGhosts()->m_fd, myGhosts()->m_geoFace,
-          myGhosts()->m_geoElem, m_u, m_p, myGhosts()->m_fd.Esuel().size()/4,
-          m_srcFlag, m_dte );
-      if (eqdt < mindt) mindt = eqdt;
-
-      // time-step suppression for unsteady problems
-      tk::real coeff(1.0);
-      if (!g_inputdeck.get< tag::steady_state >()) {
-        if (d->It() < 100) coeff = 0.01 * static_cast< tk::real >(d->It());
-      }
-
-      mindt *= coeff * g_inputdeck.get< tag::cfl >();
-    }
-  }
-  else
-  {
-    mindt = d->Dt();
-  }
+  private:
+    const Physics m_physics;            //!< Physics policy
+    const Problem m_problem;            //!< Problem policy
+    const ncomp_t m_ncomp;              //!< Number of components in this PDE
+    //! EOS material block
+    const std::vector< EOS > m_mat_blk;
+
+    //! \brief Compute/assemble nodal gradients of primitive variables for
+    //!   ALECG in all points
+    //! \param[in] coord Mesh node coordinates
+    //! \param[in] inpoel Mesh element connectivity
+    //! \param[in] lid Global->local node ids
+    //! \param[in] bid Local chare-boundary node ids (value) associated to
+    //!    global node ids (key)
+    //! \param[in] vol Nodal volumes
+    //! \param[in] esup Elements surrounding points
+    //! \param[in] U Solution vector at recent time step
+    //! \param[in] G Nodal gradients of primitive variables in chare-boundary nodes
+    //! \return Gradients of primitive variables in all mesh points
+    tk::Fields
+    nodegrad( const std::array< std::vector< real >, 3 >& coord,
+              const std::vector< std::size_t >& inpoel,
+              const std::unordered_map< std::size_t, std::size_t >& lid,
+              const std::unordered_map< std::size_t, std::size_t >& bid,
+              const std::vector< real >& vol,
+              const std::pair< std::vector< std::size_t >,
+                               std::vector< std::size_t > >& esup,
+              const tk::Fields& U,
+              const tk::Fields& G ) const
+    {
+      // allocate storage for nodal gradients of primitive variables
+      tk::Fields Grad( U.nunk(), m_ncomp*3 );
+      Grad.fill( 0.0 );
+
+      // access node cooordinates
+      const auto& x = coord[0];
+      const auto& y = coord[1];
+      const auto& z = coord[2];
+
+      // compute gradients of primitive variables in points
+      auto npoin = U.nunk();
+      #pragma omp simd
+      for (std::size_t p=0; p<npoin; ++p)
+        for (auto e : tk::Around(esup,p)) {
+          // access node IDs
+          std::size_t N[4] =
+            { inpoel[e*4+0], inpoel[e*4+1], inpoel[e*4+2], inpoel[e*4+3] };
+          // compute element Jacobi determinant, J = 6V
+          real bax = x[N[1]]-x[N[0]];
+          real bay = y[N[1]]-y[N[0]];
+          real baz = z[N[1]]-z[N[0]];
+          real cax = x[N[2]]-x[N[0]];
+          real cay = y[N[2]]-y[N[0]];
+          real caz = z[N[2]]-z[N[0]];
+          real dax = x[N[3]]-x[N[0]];
+          real day = y[N[3]]-y[N[0]];
+          real daz = z[N[3]]-z[N[0]];
+          auto J = tk::triple( bax, bay, baz, cax, cay, caz, dax, day, daz );
+          auto J24 = J/24.0;
+          // shape function derivatives, nnode*ndim [4][3]
+          real g[4][3];
+          tk::crossdiv( cax, cay, caz, dax, day, daz, J,
+                        g[1][0], g[1][1], g[1][2] );
+          tk::crossdiv( dax, day, daz, bax, bay, baz, J,
+                        g[2][0], g[2][1], g[2][2] );
+          tk::crossdiv( bax, bay, baz, cax, cay, caz, J,
+                        g[3][0], g[3][1], g[3][2] );
+          for (std::size_t i=0; i<3; ++i)
+            g[0][i] = -g[1][i] - g[2][i] - g[3][i];
+          // scatter-add gradient contributions to boundary nodes
+          for (std::size_t c=0; c<m_ncomp; ++c)
+            for (std::size_t b=0; b<4; ++b)
+              for (std::size_t i=0; i<3; ++i)
+                Grad(p,c*3+i) += J24 * g[b][i] * U(N[b],c);
+        }
+
+      // put in nodal gradients of chare-boundary points
+      for (const auto& [g,b] : bid) {
+        auto i = tk::cref_find( lid, g );
+        for (ncomp_t c=0; c<Grad.nprop(); ++c)
+          Grad(i,c) = G(b,c);
+      }
+
+      // divide weak result in gradients by nodal volume
+      for (std::size_t p=0; p<npoin; ++p)
+        for (std::size_t c=0; c<m_ncomp*3; ++c)
+          Grad(p,c) /= vol[p];
+
+      return Grad;
+    }
+
+    //! \brief Compute MUSCL reconstruction in edge-end points using a MUSCL
+    //!    procedure with van Leer limiting
+    //! \param[in] p Left node id of edge-end
+    //! \param[in] q Right node id of edge-end
+    //! \param[in] coord Array of nodal coordinates
+    //! \param[in] G Gradient of all unknowns in mesh points
+    //! \param[in,out] uL Primitive variables at left edge-end point
+    //! \param[in,out] uR Primitive variables at right edge-end point
+    void
+    muscl( std::size_t p,
+           std::size_t q,
+           const tk::UnsMesh::Coords& coord,
+           const tk::Fields& G,
+           std::vector< real >& uL,
+           std::vector< real >& uR ) const
+    {
+      Assert( uL.size() == m_ncomp && uR.size() == m_ncomp, "Size mismatch" );
+      Assert( G.nprop()/3 == m_ncomp, "Size mismatch" );
+
+      const auto& x = coord[0];
+      const auto& y = coord[1];
+      const auto& z = coord[2];
+
+      // edge vector
+      std::array< real, 3 > vw{ x[q]-x[p], y[q]-y[p], z[q]-z[p] };
+
+      std::vector< real >
+        delta1( m_ncomp, 0.0 ), delta2( m_ncomp, 0.0 ), delta3( m_ncomp, 0.0 );
 
-  // Contribute to minimum dt across all chares then advance to next step
-  contribute( sizeof(tk::real), &mindt, CkReduction::min_double,
-              CkCallback(CkReductionTarget(FV,solve), thisProxy) );
-}
-
-void
-FV::solve( tk::real newdt )
-// *****************************************************************************
-// Compute right-hand side of discrete transport equations
-//! \param[in] newdt Size of this new time step
-// *****************************************************************************
-{
-  // Enable SDAG wait for building the solution vector during the next stage
-  thisProxy[ thisIndex ].wait4sol();
-  thisProxy[ thisIndex ].wait4lim();
-  thisProxy[ thisIndex ].wait4nod();
+      // MUSCL reconstruction of edge-end-point primitive variables
+      for (std::size_t c=0; c<m_ncomp; ++c) {
+        // gradients
+        std::array< real, 3 >
+          g1{ G(p,c*3+0), G(p,c*3+1), G(p,c*3+2) },
+          g2{ G(q,c*3+0), G(q,c*3+1), G(q,c*3+2) };
+
+        delta2[c] = uR[c] - uL[c];
+        delta1[c] = 2.0 * tk::dot(g1,vw) - delta2[c];
+        delta3[c] = 2.0 * tk::dot(g2,vw) - delta2[c];
+
+        // form limiters
+        auto rL = (delta2[c] + muscl_eps) / (delta1[c] + muscl_eps);
+        auto rR = (delta2[c] + muscl_eps) / (delta3[c] + muscl_eps);
+        auto rLinv = (delta1[c] + muscl_eps) / (delta2[c] + muscl_eps);
+        auto rRinv = (delta3[c] + muscl_eps) / (delta2[c] + muscl_eps);
 
-  auto d = Disc();
-  const auto rdof = g_inputdeck.get< tag::rdof >();
-  const auto neq = m_u.nprop()/rdof;
-
-  // Set new time step size
-  if (m_stage == 0) d->setdt( newdt );
-
-  // Update Un
-  if (m_stage == 0) m_un = m_u;
-
-  // physical time at time-stage for computing exact source terms for
-  // unsteady problems
-  tk::real physT(d->T());
-  // 2-stage RK
-  if (m_nrk == 2) {
-    if (m_stage == 1) {
-      physT += d->Dt();
-    }
-  }
-  // 3-stage RK
-  else {
-    if (m_stage == 1) {
-      physT += d->Dt();
-    }
-    else if (m_stage == 2) {
-      physT += 0.5*d->Dt();
-    }
-  }
-
-  // Compute rhs
-  g_fvpde[d->MeshId()].rhs( physT, myGhosts()->m_geoFace, myGhosts()->m_geoElem,
-    myGhosts()->m_fd, myGhosts()->m_inpoel, myGhosts()->m_coord,
-    d->ElemBlockId(), m_u, m_p, m_rhs, m_srcFlag );
-
-  // Explicit time-stepping using RK3 to discretize time-derivative
-  const auto steady = g_inputdeck.get< tag::steady_state >();
-  for (std::size_t e=0; e<myGhosts()->m_nunk; ++e)
-    for (std::size_t c=0; c<neq; ++c)
-    {
-      auto dte = d->Dt();
-      if (steady) dte = m_dte[e];
-      auto rmark = c*rdof;
-      m_u(e, rmark) =  m_rkcoef[0][m_stage] * m_un(e, rmark)
-        + m_rkcoef[1][m_stage] * ( m_u(e, rmark)
-          + dte * m_rhs(e, c)/m_lhs(e, c) );
-      // zero out reconstructed dofs of equations using reduced dofs
-      if (rdof > 1) {
-        for (std::size_t k=1; k<rdof; ++k)
-        {
-          rmark = c*rdof+k;
-          m_u(e, rmark) = 0.0;
-        }
-      }
-    }
-
-  // Update primitives based on the evolved solution
-  g_fvpde[d->MeshId()].updatePrimitives( m_u, m_p,
-    myGhosts()->m_fd.Esuel().size()/4 );
-  if (!g_inputdeck.get< tag::accuracy_test >()) {
-    g_fvpde[d->MeshId()].cleanTraceMaterial( physT, myGhosts()->m_geoElem, m_u,
-      m_p, myGhosts()->m_fd.Esuel().size()/4 );
-  }
-
-  if (m_stage < m_nrk-1) {
-
-    // continue with next time step stage
-    stage();
-
-  } else {
-
-    // Increase number of iterations and physical time
-    d->next();
-
-    // Compute diagnostics, e.g., residuals
-    auto diag_computed = m_diag.compute( *d,
-      m_u.nunk()-myGhosts()->m_fd.Esuel().size()/4, myGhosts()->m_geoElem,
-      std::vector< std::size_t>{}, m_u, m_un );
-
-    // Continue to mesh refinement (if configured)
-    if (!diag_computed) refine( std::vector< tk::real >( m_u.nprop(), 1.0 ) );
-
-  }
-}
-
-void
-FV::refine( const std::vector< tk::real >& l2res )
-// *****************************************************************************
-// Optionally refine/derefine mesh
-//! \param[in] l2res L2-norms of the residual for each scalar component
-//!   computed across the whole problem
-// *****************************************************************************
-{
-  auto d = Disc();
-
-  // Assess convergence for steady state
-  const auto steady = g_inputdeck.get< tag::steady_state >();
-  const auto residual = g_inputdeck.get< tag::residual >();
-  const auto rc = g_inputdeck.get< tag::rescomp >() - 1;
-
-  bool converged(false);
-  if (steady) converged = l2res[rc] < residual;
-
-  // this is the last time step if max time of max number of time steps
-  // reached or the residual has reached its convergence criterion
-  if (d->finished() or converged) m_finished = 1;
-
-  auto dtref = g_inputdeck.get< tag::amr, tag::dtref >();
-  auto dtfreq = g_inputdeck.get< tag::amr, tag::dtfreq >();
-
-  // if t>0 refinement enabled and we hit the dtref frequency
-  if (dtref && !(d->It() % dtfreq)) {   // refine
+        auto phiL = (std::abs(rL) + rL) / (std::abs(rL) + 1.0);
+        auto phiR = (std::abs(rR) + rR) / (std::abs(rR) + 1.0);
+        auto phi_L_inv = (std::abs(rLinv) + rLinv) / (std::abs(rLinv) + 1.0);
+        auto phi_R_inv = (std::abs(rRinv) + rRinv) / (std::abs(rRinv) + 1.0);
+
+        // update unknowns with reconstructed unknowns
+        uL[c] += 0.25*(delta1[c]*muscl_m1*phiL + delta2[c]*muscl_p1*phi_L_inv);
+        uR[c] -= 0.25*(delta3[c]*muscl_m1*phiR + delta2[c]*muscl_p1*phi_R_inv);
+      }
+    }
+
+    //! Compute domain-edge integral for ALECG
+    //! \param[in] coord Mesh node coordinates
+    //! \param[in] inpoel Mesh element connectivity
+    //! \param[in] edgeid Local node id pair -> edge id map
+    //! \param[in] psup Points surrounding points
+    //! \param[in] dfn Dual-face normals
+    //! \param[in] U Solution vector at recent time step
+    //! \param[in] G Nodal gradients
+    //! \param[in,out] R Right-hand side vector computed
+    void domainint( const std::array< std::vector< real >, 3 >& coord,
+                    const std::vector< std::size_t >& inpoel,
+                    const std::vector< std::size_t >& edgeid,
+                    const std::pair< std::vector< std::size_t >,
+                                     std::vector< std::size_t > >& psup,
+                    const std::vector< real >& dfn,
+                    const tk::Fields& U,
+                    const tk::Fields& G,
+                    tk::Fields& R ) const
+    {
+      // access node cooordinates
+      const auto& x = coord[0];
+      const auto& y = coord[1];
+      const auto& z = coord[2];
+
+      // compute derived data structures
+      auto esued = tk::genEsued( inpoel, 4, tk::genEsup( inpoel, 4 ) );
+
+      // access pointer to right hand side at component
+      std::vector< const real* > r( m_ncomp );
+      for (ncomp_t c=0; c<m_ncomp; ++c) r[c] = R.cptr( c );
+
+      // domain-edge integral
+      for (std::size_t p=0,k=0; p<U.nunk(); ++p) {
+        for (auto q : tk::Around(psup,p)) {
+          // access dual-face normals for edge p-q
+          auto ed = edgeid[k++];
+          std::array< tk::real, 3 > n{ dfn[ed*6+0], dfn[ed*6+1], dfn[ed*6+2] };
+
+          std::vector< tk::real > uL( m_ncomp, 0.0 );
+          std::vector< tk::real > uR( m_ncomp, 0.0 );
+          for (std::size_t c=0; c<m_ncomp; ++c) {
+            uL[c] = U(p,c);
+            uR[c] = U(q,c);
+          }
+          // compute MUSCL reconstruction in edge-end points
+          muscl( p, q, coord, G, uL, uR );
+
+          // evaluate prescribed velocity
+          auto v =
+            Problem::prescribedVelocity( m_ncomp, x[p], y[p], z[p], 0.0 );
+          // sum donain-edge contributions
+          for (auto e : tk::cref_find(esued,{p,q})) {
+            const std::array< std::size_t, 4 >
+              N{{ inpoel[e*4+0], inpoel[e*4+1], inpoel[e*4+2], inpoel[e*4+3] }};
+            // compute element Jacobi determinant
+            const std::array< tk::real, 3 >
+              ba{{ x[N[1]]-x[N[0]], y[N[1]]-y[N[0]], z[N[1]]-z[N[0]] }},
+              ca{{ x[N[2]]-x[N[0]], y[N[2]]-y[N[0]], z[N[2]]-z[N[0]] }},
+              da{{ x[N[3]]-x[N[0]], y[N[3]]-y[N[0]], z[N[3]]-z[N[0]] }};
+            const auto J = tk::triple( ba, ca, da );        // J = 6V
+            // shape function derivatives, nnode*ndim [4][3]
+            std::array< std::array< tk::real, 3 >, 4 > grad;
+            grad[1] = tk::crossdiv( ca, da, J );
+            grad[2] = tk::crossdiv( da, ba, J );
+            grad[3] = tk::crossdiv( ba, ca, J );
+            for (std::size_t i=0; i<3; ++i)
+              grad[0][i] = -grad[1][i]-grad[2][i]-grad[3][i];
+            auto J48 = J/48.0;
+            for (const auto& [a,b] : tk::lpoed) {
+              auto s = tk::orient( {N[a],N[b]}, {p,q} );
+              for (std::size_t j=0; j<3; ++j) {
+                for (std::size_t c=0; c<m_ncomp; ++c) {
+                  R.var(r[c],p) -= J48 * s * (grad[a][j] - grad[b][j])
+                                   * v[c][j]*(uL[c] + uR[c])
+                    - J48 * std::abs(s * (grad[a][j] - grad[b][j]))
+                          * std::abs(tk::dot(v[c],n)) * (uR[c] - uL[c]);
+                }
+              }
+            }
+          }
+        }
+      }
+    }
+
+    //! Compute boundary integrals for ALECG
+    //! \param[in] coord Mesh node coordinates
+    //! \param[in] triinpoel Boundary triangle face connecitivity with local ids
+    //! \param[in] symbctri Vector with 1 at symmetry BC boundary triangles
+    //! \param[in] U Solution vector at recent time step
+    //! \param[in,out] R Right-hand side vector computed
+    void bndint( const std::array< std::vector< real >, 3 >& coord,
+                 const std::vector< std::size_t >& triinpoel,
+                 const std::vector< int >& symbctri,
+                 const tk::Fields& U,
+                 tk::Fields& R ) const
+    {
+      // access node coordinates
+      const auto& x = coord[0];
+      const auto& y = coord[1];
+      const auto& z = coord[2];
 
-    d->startvol();
-    d->Ref()->dtref( myGhosts()->m_fd.Bface(), {},
-      tk::remap(myGhosts()->m_fd.Triinpoel(),d->Gid()) );
-    d->refined() = 1;
-
-  } else {      // do not refine
-
-    d->refined() = 0;
-    stage();
-
-  }
-}
-
-void
-FV::resizePostAMR(
-  const std::vector< std::size_t >& /*ginpoel*/,
-  const tk::UnsMesh::Chunk& chunk,
-  const tk::UnsMesh::Coords& coord,
-  const std::unordered_map< std::size_t, tk::UnsMesh::Edge >& /*addedNodes*/,
-  const std::unordered_map< std::size_t, std::size_t >& addedTets,
-  const std::set< std::size_t >& removedNodes,
-  const std::unordered_map< std::size_t, std::size_t >& amrNodeMap,
-  const tk::NodeCommMap& nodeCommMap,
-  const std::map< int, std::vector< std::size_t > >& bface,
-  const std::map< int, std::vector< std::size_t > >& /* bnode */,
-  const std::vector< std::size_t >& triinpoel,
-  const std::unordered_map< std::size_t, std::set< std::size_t > >& elemblockid )
-// *****************************************************************************
-//  Receive new mesh from Refiner
-//! \param[in] chunk New mesh chunk (connectivity and global<->local id maps)
-//! \param[in] coord New mesh node coordinates
-//! \param[in] addedTets Newly added mesh cells and their parents (local ids)
-//! \param[in] removedNodes Newly removed mesh node local ids
-//! \param[in] amrNodeMap Node id map after amr (local ids)
-//! \param[in] nodeCommMap New node communication map
-//! \param[in] bface Boundary-faces mapped to side set ids
-//! \param[in] triinpoel Boundary-face connectivity
-//! \param[in] elemblockid Local tet ids associated with mesh block ids
-// *****************************************************************************
-{
-  auto d = Disc();
+      // boundary integrals: compute fluxes in edges
+      std::vector< real > bflux( triinpoel.size() * m_ncomp * 2 );
+
+      for (std::size_t e=0; e<triinpoel.size()/3; ++e) {
+        // access node IDs
+        std::array< std::size_t, 3 >
+          N{ triinpoel[e*3+0], triinpoel[e*3+1], triinpoel[e*3+2] };
+        // apply symmetry BCs
+        if (symbctri[e]) continue;
+        // node coordinates
+        std::array< tk::real, 3 > xp{ x[N[0]], x[N[1]], x[N[2]] },
+                                  yp{ y[N[0]], y[N[1]], y[N[2]] },
+                                  zp{ z[N[0]], z[N[1]], z[N[2]] };
+        // access solution at element nodes
+        std::vector< std::array< real, 3 > > u( m_ncomp );
+        for (ncomp_t c=0; c<m_ncomp; ++c) u[c] = U.extract( c, N );
+        // evaluate prescribed velocity
+        auto v =
+          Problem::prescribedVelocity( m_ncomp, xp[0], yp[0], zp[0], 0.0 );
+        // compute face area
+        auto A6 = tk::area( x[N[0]], x[N[1]], x[N[2]],
+                            y[N[0]], y[N[1]], y[N[2]],
+                            z[N[0]], z[N[1]], z[N[2]] ) / 6.0;
+        auto A24 = A6/4.0;
+        // compute face normal
+        auto n = tk::normal( xp, yp, zp );
+        // store flux in boundary elements
+        for (std::size_t c=0; c<m_ncomp; ++c) {
+          auto eb = (e*m_ncomp+c)*6;
+          auto vdotn = tk::dot( v[c], n );
+          auto Bab = A24 * vdotn * (u[c][0] + u[c][1]);
+          bflux[eb+0] = Bab + A6 * vdotn * u[c][0];
+          bflux[eb+1] = Bab;
+          Bab = A24 * vdotn * (u[c][1] + u[c][2]);
+          bflux[eb+2] = Bab + A6 * vdotn * u[c][1];
+          bflux[eb+3] = Bab;
+          Bab = A24 * vdotn * (u[c][2] + u[c][0]);
+          bflux[eb+4] = Bab + A6 * vdotn * u[c][2];
+          bflux[eb+5] = Bab;
+        }
+      }
 
-  // Set flag that indicates that we are during time stepping
-  m_initial = 0;
-  myGhosts()->m_initial = 0;
+      // access pointer to right hand side at component
+      std::vector< const real* > r( m_ncomp );
+      for (ncomp_t c=0; c<m_ncomp; ++c) r[c] = R.cptr( c );
 
-  // Zero field output iteration count between two mesh refinement steps
-  d->Itf() = 0;
-
-  // Increase number of iterations with mesh refinement
-  ++d->Itr();
-
-  // Save old number of elements
-  [[maybe_unused]] auto old_nelem = myGhosts()->m_inpoel.size()/4;
-
-  // Resize mesh data structures
-  d->resizePostAMR( chunk, coord, amrNodeMap, nodeCommMap, removedNodes,
-    elemblockid );
-
-  // Update state
-  myGhosts()->m_inpoel = d->Inpoel();
-  myGhosts()->m_coord = d->Coord();
-  auto nelem = myGhosts()->m_inpoel.size()/4;
-  m_p.resize( nelem );
-  m_u.resize( nelem );
-  m_srcFlag.resize( nelem );
-  m_un.resize( nelem );
-  m_lhs.resize( nelem );
-  m_rhs.resize( nelem );
-
-  myGhosts()->m_fd = FaceData( myGhosts()->m_inpoel, bface,
-    tk::remap(triinpoel,d->Lid()) );
-
-  myGhosts()->m_geoFace =
-    tk::Fields( tk::genGeoFaceTri( myGhosts()->m_fd.Nipfac(),
-    myGhosts()->m_fd.Inpofa(), coord ) );
-  myGhosts()->m_geoElem = tk::Fields( tk::genGeoElemTet( myGhosts()->m_inpoel,
-    coord ) );
-
-  myGhosts()->m_nfac = myGhosts()->m_fd.Inpofa().size()/3;
-  myGhosts()->m_nunk = nelem;
-  m_npoin = coord[0].size();
-  myGhosts()->m_bndFace.clear();
-  myGhosts()->m_exptGhost.clear();
-  myGhosts()->m_sendGhost.clear();
-  myGhosts()->m_ghost.clear();
-  myGhosts()->m_esup.clear();
-
-  // Update solution on new mesh, P0 (cell center value) only for now
-  m_un = m_u;
-  auto pn = m_p;<--- Variable 'pn' is assigned a value that is never used.
-  auto unprop = m_u.nprop();<--- Variable 'unprop' is assigned a value that is never used.
-  auto pnprop = m_p.nprop();<--- Variable 'pnprop' is assigned a value that is never used.
-  for (const auto& [child,parent] : addedTets) {
-    Assert( child < nelem, "Indexing out of new solution vector" );
-    Assert( parent < old_nelem, "Indexing out of old solution vector" );
-    for (std::size_t i=0; i<unprop; ++i) m_u(child,i) = m_un(parent,i);
-    for (std::size_t i=0; i<pnprop; ++i) m_p(child,i) = pn(parent,i);
-  }
-  m_un = m_u;
-
-  // Resize communication buffers
-  m_ghosts[thisIndex].resizeComm();
-}
-
-bool
-FV::fieldOutput() const
-// *****************************************************************************
-// Decide wether to output field data
-//! \return True if field data is output in this step
-// *****************************************************************************
-{
-  auto d = Disc();
-
-  // Output field data
-  return d->fielditer() or d->fieldtime() or d->fieldrange() or m_finished;
-}
-
-bool
-FV::refinedOutput() const
-// *****************************************************************************
-// Decide if we write field output using a refined mesh
-//! \return True if field output will use a refined mesh
-// *****************************************************************************
-{
-  return g_inputdeck.get< tag::field_output, tag::refined >() &&
-         g_inputdeck.get< tag::scheme >() != ctr::SchemeType::FV;
-}
-
-void
-FV::writeFields( CkCallback c )
-// *****************************************************************************
-// Output mesh field data
-//! \param[in] c Function to continue with after the write
-// *****************************************************************************
-{
-  auto d = Disc();
-
-  const auto& inpoel = std::get< 0 >( d->Chunk() );
-  auto esup = tk::genEsup( inpoel, 4 );
-  auto nelem = inpoel.size() / 4;
-
-  // Combine own and communicated contributions and finish averaging of node
-  // field output in chare boundary nodes
-  const auto& lid = std::get< 2 >( d->Chunk() );
-  for (const auto& [g,f] : m_uNodefieldsc) {
-    Assert( m_uNodefields.nprop() == f.first.size(), "Size mismatch" );
-    auto p = tk::cref_find( lid, g );
-    for (std::size_t i=0; i<f.first.size(); ++i) {
-      m_uNodefields(p,i) += f.first[i];
-      m_uNodefields(p,i) /= static_cast< tk::real >(
-                              esup.second[p+1] - esup.second[p] + f.second );
-    }
-  }
-  tk::destroy( m_uNodefieldsc );
-  for (const auto& [g,f] : m_pNodefieldsc) {
-    Assert( m_pNodefields.nprop() == f.first.size(), "Size mismatch" );
-    auto p = tk::cref_find( lid, g );
-    for (std::size_t i=0; i<f.first.size(); ++i) {
-      m_pNodefields(p,i) += f.first[i];
-      m_pNodefields(p,i) /= static_cast< tk::real >(
-                              esup.second[p+1] - esup.second[p] + f.second );
-    }
-  }
-  tk::destroy( m_pNodefieldsc );
-
-  // Lambda to decide if a node (global id) is on a chare boundary of the field
-  // output mesh. p - global node id, return true if node is on the chare
-  // boundary.
-  auto chbnd = [ this ]( std::size_t p ) {
-    return
-      std::any_of( Disc()->NodeCommMap().cbegin(), Disc()->NodeCommMap().cend(),
-        [&](const auto& s) { return s.second.find(p) != s.second.cend(); } );
-  };
-
-  // Finish computing node field output averages in internal nodes
-  auto npoin = d->Coord()[0].size();
-  auto& gid = std::get< 1 >( d->Chunk() );
-  for (std::size_t p=0; p<npoin; ++p) {
-    if (!chbnd(gid[p])) {
-      auto n = static_cast< tk::real >( esup.second[p+1] - esup.second[p] );
-      for (std::size_t i=0; i<m_uNodefields.nprop(); ++i)
-        m_uNodefields(p,i) /= n;
-      for (std::size_t i=0; i<m_pNodefields.nprop(); ++i)
-        m_pNodefields(p,i) /= n;
-    }
-  }
-
-  // Collect field output from numerical solution requested by user
-  auto elemfields = numericFieldOutput( m_uElemfields, tk::Centering::ELEM,
-    g_fvpde[Disc()->MeshId()].OutVarFn(), m_pElemfields );
-  auto nodefields = numericFieldOutput( m_uNodefields, tk::Centering::NODE,
-    g_fvpde[Disc()->MeshId()].OutVarFn(), m_pNodefields );
-
-  // Collect field output from analytical solutions (if exist)
-  const auto& coord = d->Coord();
-  auto geoElem = tk::genGeoElemTet( inpoel, coord );
-  auto t = Disc()->T();
-  analyticFieldOutput( g_fvpde[d->MeshId()], tk::Centering::ELEM,
-    geoElem.extract_comp(1), geoElem.extract_comp(2), geoElem.extract_comp(3),
-    t, elemfields );
-  analyticFieldOutput( g_fvpde[d->MeshId()], tk::Centering::NODE, coord[0],
-    coord[1], coord[2], t, nodefields );
-
-  // Add sound speed vector
-  std::vector< tk::real > soundspd(nelem, 0.0);
-  g_fvpde[d->MeshId()].soundspeed(nelem, m_u, m_p, soundspd);
-  elemfields.push_back(soundspd);
-
-  // Add source flag array to element-centered field output
-  std::vector< tk::real > srcFlag( begin(m_srcFlag), end(m_srcFlag) );
-  // Here m_srcFlag has a size of m_u.nunk() which is the number of the
-  // elements within this partition (nelem) plus the ghost partition cells.
-  // For the purpose of output, we only need the solution data within this
-  // partition. Therefore, resizing it to nelem removes the extra partition
-  // boundary allocations in the srcFlag vector. Since the code assumes that
-  // the boundary elements are on the top, the resize operation keeps the lower
-  // portion.
-  srcFlag.resize( nelem );
-  elemfields.push_back( srcFlag );
-
-  // Query fields names requested by user
-  auto elemfieldnames = numericFieldNames( tk::Centering::ELEM );
-  auto nodefieldnames = numericFieldNames( tk::Centering::NODE );
-
-  // Collect field output names for analytical solutions
-  analyticFieldNames( g_fvpde[d->MeshId()], tk::Centering::ELEM, elemfieldnames );
-  analyticFieldNames( g_fvpde[d->MeshId()], tk::Centering::NODE, nodefieldnames );
-
-  elemfieldnames.push_back( "sound speed" );
-  elemfieldnames.push_back( "src_flag" );
-
-  Assert( elemfieldnames.size() == elemfields.size(), "Size mismatch" );
-  Assert( nodefieldnames.size() == nodefields.size(), "Size mismatch" );
-
-  // Collect surface output names
-  auto surfnames = g_fvpde[d->MeshId()].surfNames();
-
-  // Collect surface field solution
-  const auto& fd = myGhosts()->m_fd;
-  auto elemsurfs = g_fvpde[d->MeshId()].surfOutput(fd, m_u, m_p);
-
-  // Output chare mesh and fields metadata to file
-  const auto& triinpoel = tk::remap( fd.Triinpoel(), d->Gid() );
-  d->write( inpoel, d->Coord(), fd.Bface(), {},
-            tk::remap( triinpoel, lid ), elemfieldnames, nodefieldnames,
-            surfnames, {}, elemfields, nodefields, elemsurfs, {}, c );
-}
-
-void
-FV::comnodeout( const std::vector< std::size_t >& gid,
-                const std::vector< std::size_t >& nesup,
-                const std::vector< std::vector< tk::real > >& Lu,
-                const std::vector< std::vector< tk::real > >& Lp )
-// *****************************************************************************
-//  Receive chare-boundary nodal solution (for field output) contributions from
-//  neighboring chares
-//! \param[in] gid Global mesh node IDs at which we receive contributions
-//! \param[in] nesup Number of elements surrounding points
-//! \param[in] Lu Partial contributions of solution nodal fields to
-//!   chare-boundary nodes
-//! \param[in] Lp Partial contributions of primitive quantity nodal fields to
-//!   chare-boundary nodes
-// *****************************************************************************
-{
-  Assert( gid.size() == nesup.size(), "Size mismatch" );
-  Assert(Lu.size() == m_uNodefields.nprop(), "Fields size mismatch");
-  Assert(Lp.size() == m_pNodefields.nprop(), "Fields size mismatch");
-  for (std::size_t f=0; f<Lu.size(); ++f)
-    Assert( gid.size() == Lu[f].size(), "Size mismatch" );
-  for (std::size_t f=0; f<Lp.size(); ++f)
-    Assert( gid.size() == Lp[f].size(), "Size mismatch" );
-
-  for (std::size_t i=0; i<gid.size(); ++i) {
-    auto& nfu = m_uNodefieldsc[ gid[i] ];
-    nfu.first.resize( Lu.size() );
-    for (std::size_t f=0; f<Lu.size(); ++f) nfu.first[f] += Lu[f][i];
-    nfu.second += nesup[i];
-    auto& nfp = m_pNodefieldsc[ gid[i] ];
-    nfp.first.resize( Lp.size() );
-    for (std::size_t f=0; f<Lp.size(); ++f) nfp.first[f] += Lp[f][i];
-    nfp.second += nesup[i];
-  }
-
-  // When we have heard from all chares we communicate with, this chare is done
-  if (++m_nnod == Disc()->NodeCommMap().size()) {
-    m_nnod = 0;
-    comnodeout_complete();
-  }
-}
-
-void
-FV::stage()
-// *****************************************************************************
-// Evaluate whether to continue with next time step stage
-// *****************************************************************************
-{
-  // Increment Runge-Kutta stage counter
-  ++m_stage;
-
-  // if not all Runge-Kutta stages complete, continue to next time stage,
-  // otherwise prepare for nodal field output
-  if (m_stage < m_nrk)
-    next();
-  else
-    startFieldOutput( CkCallback(CkIndex_FV::step(), thisProxy[thisIndex]) );
-}
-
-void
-FV::evalLB( int nrestart )
-// *****************************************************************************
-// Evaluate whether to do load balancing
-//! \param[in] nrestart Number of times restarted
-// *****************************************************************************
-{
-  auto d = Disc();
-
-  // Detect if just returned from a checkpoint and if so, zero timers and flag
-  if (d->restarted( nrestart )) m_finished = 0;
-
-  const auto lbfreq = g_inputdeck.get< tag::cmd, tag::lbfreq >();
-  const auto nonblocking = g_inputdeck.get< tag::cmd, tag::nonblocking >();
-
-  // Load balancing if user frequency is reached or after the second time-step
-  if ( (d->It()) % lbfreq == 0 || d->It() == 2 ) {
-
-    AtSync();
-    if (nonblocking) next();
-
-  } else {
-
-    next();
-
-  }
-}
-
-void
-FV::evalRestart()
-// *****************************************************************************
-// Evaluate whether to save checkpoint/restart
-// *****************************************************************************
-{
-  auto d = Disc();
-
-  const auto rsfreq = g_inputdeck.get< tag::cmd, tag::rsfreq >();
-  const auto benchmark = g_inputdeck.get< tag::cmd, tag::benchmark >();
-
-  if ( !benchmark && (d->It()) % rsfreq == 0 ) {
-
-    std::vector< std::size_t > meshdata{ /* finished = */ 0, d->MeshId() };
-    contribute( meshdata, CkReduction::nop,
-      CkCallback(CkReductionTarget(Transporter,checkpoint), d->Tr()) );
-
-  } else {
-
-    evalLB( /* nrestart = */ -1 );
-
-  }
-}
-
-void
-FV::step()
-// *****************************************************************************
-// Evaluate wether to continue with next time step
-// *****************************************************************************
-{
-  auto d = Disc();
-
-  // Output time history
-  if (d->histiter() or d->histtime() or d->histrange()) {
-    std::vector< std::vector< tk::real > > hist;
-    auto h = g_fvpde[d->MeshId()].histOutput( d->Hist(), myGhosts()->m_inpoel,
-      myGhosts()->m_coord, m_u, m_p );
-    hist.insert( end(hist), begin(h), end(h) );
-    d->history( std::move(hist) );
-  }
-
-  // Output one-liner status report to screen
-  d->status();
-  // Reset Runge-Kutta stage counter
-  m_stage = 0;
-
-  // If neither max iterations nor max time reached, continue, otherwise finish
-  if (not m_finished) {
-
-    evalRestart();
- 
-  } else {
-
-    auto meshid = d->MeshId();
-    d->contribute( sizeof(std::size_t), &meshid, CkReduction::nop,
-                   CkCallback(CkReductionTarget(Transporter,finish), d->Tr()) );
-
-  }
-}
-
-#include "NoWarning/fv.def.h"
+      // boundary integrals: sum flux contributions to points
+      for (std::size_t e=0; e<triinpoel.size()/3; ++e) {
+        std::size_t N[3] =
+          { triinpoel[e*3+0], triinpoel[e*3+1], triinpoel[e*3+2] };
+        for (std::size_t c=0; c<m_ncomp; ++c) {
+          auto eb = (e*m_ncomp+c)*6;
+          R.var(r[c],N[0]) -= bflux[eb+0] + bflux[eb+5];
+          R.var(r[c],N[1]) -= bflux[eb+1] + bflux[eb+2];
+          R.var(r[c],N[2]) -= bflux[eb+3] + bflux[eb+4];
+        }
+      }
+
+      tk::destroy(bflux);
+    }
+};
+
+} // cg::
+} // inciter::
+
+#endif // Transport_h
 
diff --git a/Release/cppcheck/56.html b/Release/cppcheck/56.html index 2c51e72ccadd..81a0c0e0208b 100644 --- a/Release/cppcheck/56.html +++ b/Release/cppcheck/56.html @@ -152,12 +152,12 @@
  1
@@ -871,1088 +871,718 @@ 

Cppcheck report - [

// *****************************************************************************
+712
// *****************************************************************************
 /*!
-  \file      src/PDE/MultiMat/FVMultiMat.hpp
+  \file      src/PDE/Transport/DGTransport.hpp
   \copyright 2012-2015 J. Bakosi,
              2016-2018 Los Alamos National Security, LLC.,
              2019-2021 Triad National Security, LLC.
              All rights reserved. See the LICENSE file for details.
-  \brief     Compressible multi-material flow using finite volumes
-  \details   This file implements calls to the physics operators governing
-    compressible multi-material flow (with velocity equilibrium) using finite
-    volume discretizations.
-*/
-// *****************************************************************************
-#ifndef FVMultiMat_h
-#define FVMultiMat_h
-
-#include <cmath>
-#include <algorithm>
-#include <unordered_set>
-#include <map>
-#include <array>
+  \brief     Scalar transport using disccontinous Galerkin discretization
+  \details   This file implements the physics operators governing transported
+     scalars using disccontinuous Galerkin discretization.
+*/
+// *****************************************************************************
+#ifndef DGTransport_h
+#define DGTransport_h
+
+#include <vector>
+#include <array>
+#include <limits>
+#include <cmath>
+#include <unordered_set>
+#include <map>
 
 #include "Macro.hpp"
 #include "Exception.hpp"
 #include "Vector.hpp"
-#include "ContainerUtil.hpp"
-#include "UnsMesh.hpp"
-#include "Inciter/InputDeck/InputDeck.hpp"
-#include "Integrate/Basis.hpp"
-#include "Integrate/Quadrature.hpp"
-#include "Integrate/Initialize.hpp"
-#include "Integrate/Mass.hpp"
-#include "Integrate/Surface.hpp"
-#include "Integrate/Boundary.hpp"
-#include "Integrate/Volume.hpp"
-#include "Integrate/MultiMatTerms.hpp"
-#include "Integrate/Source.hpp"
-#include "RiemannChoice.hpp"
-#include "MultiMat/MultiMatIndexing.hpp"
-#include "Reconstruction.hpp"
-#include "Limiter.hpp"
-#include "Problem/FieldOutput.hpp"
-#include "Problem/BoxInitialization.hpp"
-#include "MultiMat/BCFunctions.hpp"
-#include "MultiMat/MiscMultiMatFns.hpp"
-
-namespace inciter {
-
-extern ctr::InputDeck g_inputdeck;
-
-namespace fv {
-
-//! \brief MultiMat used polymorphically with tk::FVPDE
-//! \details The template arguments specify policies and are used to configure
-//!   the behavior of the class. The policies are:
-//!   - Physics - physics configuration, see PDE/MultiMat/Physics.h
-//!   - Problem - problem configuration, see PDE/MultiMat/Problem.h
-//! \note The default physics is Euler, set in inciter::deck::check_multimat()
-template< class Physics, class Problem >
-class MultiMat {
-
-  private:
-    using eq = tag::multimat;
-
-  public:
-    //! Constructor
-    explicit MultiMat() :
-      m_physics(),
-      m_ncomp( g_inputdeck.get< tag::ncomp >() ),
-      m_riemann( multimatRiemannSolver(
-        g_inputdeck.get< tag::flux >() ) )
-    {
-      // associate boundary condition configurations with state functions
-      brigand::for_each< ctr::bclist::Keys >( ConfigBC( m_bc,
-        { dirichlet
-        , symmetry
-        , invalidBC         // Inlet BC not implemented
-        , invalidBC         // Outlet BC not implemented
-        , farfieldOutlet
-        , extrapolate } ) );
-
-      // EoS initialization
-      initializeMaterialEoS( m_mat_blk );
-    }
-
-    //! Find the number of primitive quantities required for this PDE system
-    //! \return The number of primitive quantities required to be stored for
-    //!   this PDE system
-    std::size_t nprim() const<--- Shadowed declaration
-    {
-      auto nmat = g_inputdeck.get< tag::multimat, tag::nmat >();<--- Shadow variable
-      // multimat needs individual material pressures and velocities currently
-      return (nmat+3);
+#include "UnsMesh.hpp"
+#include "Integrate/Basis.hpp"
+#include "Integrate/Quadrature.hpp"
+#include "Integrate/Initialize.hpp"
+#include "Integrate/Mass.hpp"
+#include "Integrate/Surface.hpp"
+#include "Integrate/Boundary.hpp"
+#include "Integrate/Volume.hpp"
+#include "Riemann/Upwind.hpp"
+#include "Reconstruction.hpp"
+#include "Limiter.hpp"
+#include "PrefIndicator.hpp"
+#include "EoS/EOS.hpp"
+#include "FunctionPrototypes.hpp"
+#include "ConfigureTransport.hpp"
+
+namespace inciter {
+
+extern ctr::InputDeck g_inputdeck;
+
+namespace dg {
+
+//! \brief Transport equation used polymorphically with tk::DGPDE
+//! \details The template argument(s) specify policies and are used to configure
+//!   the behavior of the class. The policies are:
+//!   - Physics - physics configuration, see PDE/Transport/Physics.h
+//!   - Problem - problem configuration, see PDE/Transport/Problem.h
+//! \note The default physics is DGAdvection, set in
+//!    inciter::deck::check_transport()
+template< class Physics, class Problem >
+class Transport {
+
+  private:
+    using eq = tag::transport;
+
+  public:
+    //! Constructor
+    explicit Transport() :
+      m_physics( Physics() ),
+      m_problem( Problem() ),
+      m_ncomp( g_inputdeck.get< tag::ncomp >() )
+    {
+      // associate boundary condition configurations with state functions, the
+      // order in which the state functions listed matters, see ctr::bc::Keys
+      brigand::for_each< ctr::bclist::Keys >( ConfigBC( m_bc,
+        { dirichlet
+        , invalidBC  // Symmetry BC not implemented
+        , inlet
+        , outlet
+        , invalidBC  // Characteristic BC not implemented
+        , extrapolate } ) );
+      m_problem.errchk( m_ncomp );
+    }
+
+    //! Find the number of primitive quantities required for this PDE system
+    //! \return The number of primitive quantities required to be stored for
+    //!   this PDE system
+    std::size_t nprim() const
+    {
+      // transport does not need/store any primitive quantities currently
+      return 0;
+    }
+
+    //! Find the number of materials set up for this PDE system
+    //! \return The number of materials set up for this PDE system
+    std::size_t nmat() const
+    {
+      return m_ncomp;
     }
 
-    //! Find the number of materials set up for this PDE system
-    //! \return The number of materials set up for this PDE system
-    std::size_t nmat() const<--- Shadowed declaration<--- Shadowed declaration<--- Shadowed declaration<--- Shadowed declaration<--- Shadowed declaration<--- Shadowed declaration<--- Shadowed declaration<--- Shadowed declaration<--- Shadowed declaration<--- Shadowed declaration<--- Shadowed declaration<--- Shadowed declaration<--- Shadowed declaration<--- Shadowed declaration<--- Shadowed declaration<--- Shadowed declaration<--- Shadowed declaration
-    {
-      auto nmat = g_inputdeck.get< tag::multimat, tag::nmat >();
-      return nmat;
-    }
-
-    //! Determine elements that lie inside the user-defined IC box
-    //! \param[in] geoElem Element geometry array
-    //! \param[in] nielem Number of internal elements
-    //! \param[in,out] inbox List of nodes at which box user ICs are set for
-    //!    each IC box
-    void IcBoxElems( const tk::Fields& geoElem,
-      std::size_t nielem,
-      std::vector< std::unordered_set< std::size_t > >& inbox ) const
-    {
-      tk::BoxElems< eq >(geoElem, nielem, inbox);
-    }
-
-    //! Initalize the compressible flow equations, prepare for time integration
-    //! \param[in] L Block diagonal mass matrix
-    //! \param[in] inpoel Element-node connectivity
-    //! \param[in] coord Array of nodal coordinates
-    //! \param[in] inbox List of elements at which box user ICs are set for
-    //!   each IC box
-    //! \param[in] elemblkid Element ids associated with mesh block ids where
-    //!   user ICs are set
-    //! \param[in,out] unk Array of unknowns
-    //! \param[in] t Physical time
-    //! \param[in] nielem Number of internal elements
-    void initialize( const tk::Fields& L,
-      const std::vector< std::size_t >& inpoel,
-      const tk::UnsMesh::Coords& coord,
-      const std::vector< std::unordered_set< std::size_t > >& inbox,
-      const std::unordered_map< std::size_t, std::set< std::size_t > >&
-        elemblkid,
-      tk::Fields& unk,
-      tk::real t,
-      const std::size_t nielem ) const
-    {
-      tk::initialize( m_ncomp, m_mat_blk, L, inpoel, coord,
-                      Problem::initialize, unk, t, nielem );
-
-      const auto rdof = g_inputdeck.get< tag::rdof >();
-      const auto& ic = g_inputdeck.get< tag::ic >();
-      const auto& icbox = ic.get< tag::box >();
-      const auto& icmbk = ic.get< tag::meshblock >();
-
-      const auto& bgpre = ic.get< tag::pressure >();
-      const auto& bgtemp = ic.get< tag::temperature >();
-
-      // Set initial conditions inside user-defined IC boxes and mesh blocks
-      std::vector< tk::real > s(m_ncomp, 0.0);
-      for (std::size_t e=0; e<nielem; ++e) {
-        // inside user-defined box
-        if (!icbox.empty()) {
-          std::size_t bcnt = 0;
-          for (const auto& b : icbox) {   // for all boxes
-            if (inbox.size() > bcnt && inbox[bcnt].find(e) != inbox[bcnt].end())
-            {
-              std::vector< tk::real > box
-                { b.template get< tag::xmin >(), b.template get< tag::xmax >(),
-                  b.template get< tag::ymin >(), b.template get< tag::ymax >(),
-                  b.template get< tag::zmin >(), b.template get< tag::zmax >() };
-              auto V_ex = (box[1]-box[0]) * (box[3]-box[2]) * (box[5]-box[4]);
-              for (std::size_t c=0; c<m_ncomp; ++c) {
-                auto mark = c*rdof;
-                s[c] = unk(e,mark);
-                // set high-order DOFs to zero
-                for (std::size_t i=1; i<rdof; ++i)
-                  unk(e,mark+i) = 0.0;
-              }
-              initializeBox<ctr::boxList>( m_mat_blk, V_ex, t, b, bgpre,
-                bgtemp, s );
-              // store box-initialization in solution vector
-              for (std::size_t c=0; c<m_ncomp; ++c) {
-                auto mark = c*rdof;
-                unk(e,mark) = s[c];
-              }
-            }
-            ++bcnt;
-          }
-        }
+    //! Assign number of DOFs per equation in the PDE system
+    //! \param[in,out] numEqDof Array storing number of Dofs for each PDE
+    //!   equation
+    void numEquationDofs(std::vector< std::size_t >& numEqDof) const
+    {
+      // all equation-dofs initialized to ndofs
+      for (std::size_t i=0; i<m_ncomp; ++i) {
+        numEqDof.push_back(g_inputdeck.get< tag::ndof >());
+      }
+    }
+
+    //! Find how 'stiff equations', which we currently
+    //! have none for Transport
+    //! \return number of stiff equations
+    std::size_t nstiffeq() const
+    { return 0; }
+
+    //! Find how 'nonstiff equations', which we currently
+    //! don't use for Transport
+    //! \return number of non-stiff equations
+    std::size_t nnonstiffeq() const
+    { return 0; }
+
+    //! Locate the stiff equations. Unused for transport.
+    //! \param[out] stiffEqIdx list
+    void setStiffEqIdx( std::vector< std::size_t >& stiffEqIdx ) const
+    {
+      stiffEqIdx.resize(0);
+    }
+
+    //! Locate the nonstiff equations. Unused for transport.
+    //! \param[out] nonStiffEqIdx list
+    void setNonStiffEqIdx( std::vector< std::size_t >& nonStiffEqIdx ) const
+    {
+      nonStiffEqIdx.resize(0);
+    }
+
+    //! Determine elements that lie inside the user-defined IC box
+    void IcBoxElems( const tk::Fields&,
+      std::size_t,
+      std::vector< std::unordered_set< std::size_t > >& ) const
+    {}
+
+    //! Initalize the transport equations for DG
+    //! \param[in] L Element mass matrix
+    //! \param[in] inpoel Element-node connectivity
+    //! \param[in] coord Array of nodal coordinates
+    //! \param[in,out] unk Array of unknowns
+    //! \param[in] t Physical time
+    //! \param[in] nielem Number of internal elements
+    void
+    initialize(
+      const tk::Fields& L,
+      const std::vector< std::size_t >& inpoel,
+      const tk::UnsMesh::Coords& coord,
+      const std::vector< std::unordered_set< std::size_t > >& /*inbox*/,
+      const std::unordered_map< std::size_t, std::set< std::size_t > >&,
+      tk::Fields& unk,
+      tk::real t,
+      const std::size_t nielem ) const
+    {
+      tk::initialize( m_ncomp, m_mat_blk, L, inpoel, coord,
+                      Problem::initialize, unk, t, nielem );
+    }
+
+    //! Save initial densities for all materials
+    //! \param[out] rho0mat List of initial densities
+    void setRho0mat( std::vector< tk::real >& rho0mat ) const
+    {
+      rho0mat.resize(0);
+    }
+
+    //! Compute density constraint for a given material
+    // //! \param[in] nelem Number of elements
+    // //! \param[in] unk Array of unknowns
+    // //! \param[in] rho0mat List of initial densities
+    //! \param[out] densityConstr Density Constraint: rho/(rho0*det(g))
+    void computeDensityConstr( std::size_t /*nelem*/,
+                               tk::Fields& /*unk*/,
+                               std::vector< tk::real >& /*rho0mat*/,
+                               std::vector< tk::real >& densityConstr) const
+    {
+      densityConstr.resize(0);
+    }
 
-        // inside user-specified mesh blocks
-        for (const auto& b : icmbk) { // for all blocks
-          auto blid = b.get< tag::blockid >();
-          auto V_ex = b.get< tag::volume >();
-          if (elemblkid.find(blid) != elemblkid.end()) {
-            const auto& elset = tk::cref_find(elemblkid, blid);
-            if (elset.find(e) != elset.end()) {
-              initializeBox<ctr::meshblockList>( m_mat_blk, V_ex, t, b,
-                bgpre, bgtemp, s );
-              // store initialization in solution vector
-              for (std::size_t c=0; c<m_ncomp; ++c) {
-                auto mark = c*rdof;
-                unk(e,mark) = s[c];
-              }
-            }
-          }
-        }
-      }
-    }
-
-    //! Compute the left hand side block-diagonal mass matrix
-    //! \param[in] geoElem Element geometry array
-    //! \param[in,out] l Block diagonal mass matrix
-    void lhs( const tk::Fields& geoElem, tk::Fields& l ) const {<--- Parameter 'l' can be declared with const
-      const auto nelem = geoElem.nunk();
-      for (std::size_t e=0; e<nelem; ++e)
-        for (ncomp_t c=0; c<m_ncomp; ++c)
-          l(e, c) = geoElem(e,0);
-    }
-
-    //! Update the primitives for this PDE system
-    //! \param[in] unk Array of unknowns
-    //! \param[in,out] prim Array of primitives
-    //! \param[in] nielem Number of internal elements
-    //! \details This function computes and stores the dofs for primitive
-    //!   quantities, which are required for obtaining reconstructed states used
-    //!   in the Riemann solver. See /PDE/Riemann/AUSM.hpp, where the
-    //!   normal velocity for advection is calculated from independently
-    //!   reconstructed velocities.
-    void updatePrimitives( const tk::Fields& unk,
-                           tk::Fields& prim,<--- Parameter 'prim' can be declared with const
-                           std::size_t nielem ) const
-    {
-      const auto rdof = g_inputdeck.get< tag::rdof >();<--- Variable 'rdof' is assigned a value that is never used.
-      auto nmat = g_inputdeck.get< tag::multimat, tag::nmat >();<--- Shadow variable<--- Variable 'nmat' is assigned a value that is never used.
-
-      Assert( unk.nunk() == prim.nunk(), "Number of unknowns in solution "
-              "vector and primitive vector at recent time step incorrect" );
-      Assert( unk.nprop() == rdof*m_ncomp, "Number of components in solution "
-              "vector must equal "+ std::to_string(rdof*m_ncomp) );
-      Assert( prim.nprop() == rdof*nprim(), "Number of components in vector of "
-              "primitive quantities must equal "+ std::to_string(rdof*nprim()) );
-
-      for (std::size_t e=0; e<nielem; ++e)
-      {
-        // cell-average bulk density
-        tk::real rhob(0.0);
-        for (std::size_t k=0; k<nmat; ++k)
-        {
-          rhob += unk(e, densityDofIdx(nmat, k, rdof, 0));
-        }
+    //! Compute the left hand side mass matrix
+    //! \param[in] geoElem Element geometry array
+    //! \param[in,out] l Block diagonal mass matrix
+    void lhs( const tk::Fields& geoElem, tk::Fields& l ) const {
+      const auto ndof = g_inputdeck.get< tag::ndof >();
+      tk::mass( m_ncomp, ndof, geoElem, l );
+    }
+
+    //! Update the interface cells to first order dofs
+    //! \details This function resets the high-order terms in interface cells,
+    //!   and is currently not used in transport.
+    void updateInterfaceCells( tk::Fields&,
+      std::size_t,
+      std::vector< std::size_t >& ) const {}
+
+    //! Update the primitives for this PDE system
+    //! \details This function computes and stores the dofs for primitive
+    //!   quantities, which are currently unused for transport.
+    void updatePrimitives( const tk::Fields&,
+                           const tk::Fields&,
+                           const tk::Fields&,
+                           tk::Fields&,
+                           std::size_t ) const {}
+
+    //! Clean up the state of trace materials for this PDE system
+    //! \details This function cleans up the state of materials present in trace
+    //!   quantities in each cell. This is currently unused for transport.
+    void cleanTraceMaterial( tk::real,
+                             const tk::Fields&,
+                             tk::Fields&,
+                             tk::Fields&,
+                             std::size_t ) const {}
+
+    //! Reconstruct second-order solution from first-order
+    //! \param[in] t Physical time
+    //! \param[in] geoFace Face geometry array
+    //! \param[in] geoElem Element geometry array
+    //! \param[in] fd Face connectivity and boundary conditions object
+    //! \param[in] esup Elements-surrounding-nodes connectivity
+    //! \param[in] inpoel Element-node connectivity
+    //! \param[in] coord Array of nodal coordinates
+    //! \param[in,out] U Solution vector at recent time step
+    //! \param[in,out] P Primitive vector at recent time step
+    void reconstruct( tk::real t,
+                      const tk::Fields& geoFace,
+                      const tk::Fields& geoElem,
+                      const inciter::FaceData& fd,
+                      const std::map< std::size_t, std::vector< std::size_t > >&
+                        esup,
+                      const std::vector< std::size_t >& inpoel,
+                      const tk::UnsMesh::Coords& coord,
+                      tk::Fields& U,
+                      tk::Fields& P ) const
+    {
+      const auto rdof = g_inputdeck.get< tag::rdof >();
+
+      // do reconstruction only if P0P1
+      if (rdof == 4 && g_inputdeck.get< tag::ndof >() == 1) {
+        const auto nelem = fd.Esuel().size()/4;<--- Variable 'nelem' is assigned a value that is never used.
+        const auto intsharp = g_inputdeck.get< tag::transport,<--- Variable 'intsharp' is assigned a value that is never used.
+          tag::intsharp >();
 
-        // cell-average velocity
-        std::array< tk::real, 3 >
-          vel{{ unk(e, momentumDofIdx(nmat, 0, rdof, 0))/rhob,
-                unk(e, momentumDofIdx(nmat, 1, rdof, 0))/rhob,
-                unk(e, momentumDofIdx(nmat, 2, rdof, 0))/rhob }};
-
-        for (std::size_t idir=0; idir<3; ++idir)
-        {
-          prim(e, velocityDofIdx(nmat, idir, rdof, 0)) = vel[idir];
-          for (std::size_t idof=1; idof<rdof; ++idof)
-            prim(e, velocityDofIdx(nmat, idir, rdof, idof)) = 0.0;
-        }
-
-        // cell-average material pressure
-        for (std::size_t k=0; k<nmat; ++k)
-        {
-          tk::real arhomat = unk(e, densityDofIdx(nmat, k, rdof, 0));
-          tk::real arhoemat = unk(e, energyDofIdx(nmat, k, rdof, 0));
-          tk::real alphamat = unk(e, volfracDofIdx(nmat, k, rdof, 0));
-          auto gmat = getDeformGrad(nmat, k, unk.extract(e));
-          prim(e, pressureDofIdx(nmat, k, rdof, 0)) =
-            m_mat_blk[k].compute< EOS::pressure >( arhomat, vel[0], vel[1],
-            vel[2], arhoemat, alphamat, k, gmat );
-          prim(e, pressureDofIdx(nmat, k, rdof, 0)) =
-            constrain_pressure( m_mat_blk,
-            prim(e, pressureDofIdx(nmat, k, rdof, 0)), arhomat, alphamat, k);
-          for (std::size_t idof=1; idof<rdof; ++idof)
-            prim(e, pressureDofIdx(nmat, k, rdof, idof)) = 0.0;
-        }
-      }
-    }
+        Assert( U.nprop() == rdof*m_ncomp, "Number of components in solution "
+                "vector must equal "+ std::to_string(rdof*m_ncomp) );
+        Assert( fd.Inpofa().size()/3 == fd.Esuf().size()/2,
+                "Mismatch in inpofa size" );
+
+        // allocate and initialize matrix and vector for reconstruction
+        std::vector< std::array< std::array< tk::real, 3 >, 3 > >
+          lhs_ls( nelem, {{ {{0.0, 0.0, 0.0}},
+                            {{0.0, 0.0, 0.0}},
+                            {{0.0, 0.0, 0.0}} }} );
+        // specify how many variables need to be reconstructed
+        std::vector< std::size_t > vars;
+        for (std::size_t c=0; c<m_ncomp; ++c) vars.push_back(c);
+
+        std::vector< std::vector< std::array< tk::real, 3 > > >
+          rhs_ls( nelem, std::vector< std::array< tk::real, 3 > >
+            ( m_ncomp,
+              {{ 0.0, 0.0, 0.0 }} ) );
+
+        // reconstruct x,y,z-derivatives of unknowns
+        // 0. get lhs matrix, which is only geometry dependent
+        tk::lhsLeastSq_P0P1(fd, geoElem, geoFace, lhs_ls);
+
+        // 1. internal face contributions
+        tk::intLeastSq_P0P1( rdof, fd, geoElem, U, rhs_ls, vars );
+
+        // 2. boundary face contributions
+        for (const auto& b : m_bc)
+          tk::bndLeastSqConservedVar_P0P1( m_ncomp, 
+            m_mat_blk, rdof, b.first, fd, geoFace, geoElem, t, b.second, 
+            P, U, rhs_ls, vars );
 
-    //! Clean up the state of trace materials for this PDE system
-    //! \param[in] t Physical time
-    //! \param[in] geoElem Element geometry array
-    //! \param[in,out] unk Array of unknowns
-    //! \param[in,out] prim Array of primitives
-    //! \param[in] nielem Number of internal elements
-    //! \details This function cleans up the state of materials present in trace
-    //!   quantities in each cell. Specifically, the state of materials with
-    //!   very low volume-fractions in a cell is replaced by the state of the
-    //!   material which is present in the largest quantity in that cell. This
-    //!   becomes necessary when shocks pass through cells which contain a very
-    //!   small amount of material. The state of that tiny material might
-    //!   become unphysical and cause solution to diverge; thus requiring such
-    //!   a "reset".
-    void cleanTraceMaterial( tk::real t,
-                             const tk::Fields& geoElem,
-                             tk::Fields& unk,
-                             tk::Fields& prim,
-                             std::size_t nielem ) const
-    {
-      [[maybe_unused]] const auto rdof = g_inputdeck.get< tag::rdof >();
-      auto nmat = g_inputdeck.get< tag::multimat, tag::nmat >();<--- Shadow variable<--- Variable 'nmat' is assigned a value that is never used.
-
-      Assert( unk.nunk() == prim.nunk(), "Number of unknowns in solution "
-              "vector and primitive vector at recent time step incorrect" );
-      Assert( unk.nprop() == rdof*m_ncomp, "Number of components in solution "
-              "vector must equal "+ std::to_string(rdof*m_ncomp) );
-      Assert( prim.nprop() == rdof*nprim(), "Number of components in vector of "
-              "primitive quantities must equal "+ std::to_string(rdof*nprim()) );
-      Assert( (g_inputdeck.get< tag::ndof >()) <= 4, "High-order "
-              "discretizations not set up for multimat cleanTraceMaterial()" );
-
-      auto neg_density = cleanTraceMultiMat(t, nielem, m_mat_blk, geoElem, nmat,
-        unk, prim);
-
-      if (neg_density) Throw("Negative partial density.");
-    }
-
-    //! Reconstruct second-order solution from first-order
-    //! \param[in] geoElem Element geometry array
-    //! \param[in] fd Face connectivity and boundary conditions object
-    //! \param[in] esup Elements-surrounding-nodes connectivity
-    //! \param[in] inpoel Element-node connectivity
-    //! \param[in] coord Array of nodal coordinates
-    //! \param[in,out] U Solution vector at recent time step
-    //! \param[in,out] P Vector of primitives at recent time step
-    void reconstruct( const tk::Fields& geoElem,
-                      const inciter::FaceData& fd,
-                      const std::map< std::size_t, std::vector< std::size_t > >&
-                        esup,
-                      const std::vector< std::size_t >& inpoel,
-                      const tk::UnsMesh::Coords& coord,
-                      tk::Fields& U,
-                      tk::Fields& P ) const
+        // 3. solve 3x3 least-squares system
+        tk::solveLeastSq_P0P1( rdof, lhs_ls, rhs_ls, U, vars );
+
+        for (std::size_t e=0; e<nelem; ++e)
+        {
+          std::vector< std::size_t > matInt(m_ncomp, 0);
+          std::vector< tk::real > alAvg(m_ncomp, 0.0);
+          for (std::size_t k=0; k<m_ncomp; ++k)
+            alAvg[k] = U(e, k*rdof);
+          auto intInd = interfaceIndicator(m_ncomp, alAvg, matInt);
+          if ((intsharp > 0) && intInd)
+          {
+            // Reconstruct second-order dofs of volume-fractions in Taylor space
+            // using nodal-stencils, for a good interface-normal estimate
+            tk::recoLeastSqExtStencil( rdof, e, esup, inpoel, geoElem,
+              U, vars );
+          }
+        }
+
+        // 4. transform reconstructed derivatives to Dubiner dofs
+        tk::transform_P0P1( rdof, nelem, inpoel, coord, U, vars );
+      }
+    }
+
+    //! Limit second-order solution
+    //! \param[in] t Physical time
+    //! \param[in] geoFace Face geometry array
+    //! \param[in] fd Face connectivity and boundary conditions object
+    //! \param[in] esup Elements surrounding points
+    //! \param[in] inpoel Element-node connectivity
+    //! \param[in] coord Array of nodal coordinates
+    //! \param[in] ndofel Vector of local number of degrees of freedome
+//    //! \param[in] gid Local->global node id map
+//    //! \param[in] bid Local chare-boundary node ids (value) associated to
+//    //!   global node ids (key)
+//    //! \param[in] uNodalExtrm Chare-boundary nodal extrema for conservative
+//    //!   variables
+    //! \param[in,out] U Solution vector at recent time step
+    void limit( [[maybe_unused]] tk::real t,
+                [[maybe_unused]] const tk::Fields& geoFace,
+                const tk::Fields&,
+                const inciter::FaceData& fd,
+                const std::map< std::size_t, std::vector< std::size_t > >& esup,
+                const std::vector< std::size_t >& inpoel,
+                const tk::UnsMesh::Coords& coord,
+                const std::vector< std::size_t >& ndofel,
+                const std::vector< std::size_t >&,
+                const std::unordered_map< std::size_t, std::size_t >&,
+                const std::vector< std::vector<tk::real> >&,
+                const std::vector< std::vector<tk::real> >&,
+                const std::vector< std::vector<tk::real> >&,
+                tk::Fields& U,
+                tk::Fields&,
+                std::vector< std::size_t >& ) const
     {
-      const auto rdof = g_inputdeck.get< tag::rdof >();
-      const auto nelem = fd.Esuel().size()/4;<--- Variable 'nelem' is assigned a value that is never used.
-      auto nmat = g_inputdeck.get< tag::multimat, tag::nmat >();<--- Shadow variable<--- Variable 'nmat' is assigned a value that is never used.
-
-      Assert( U.nprop() == rdof*m_ncomp, "Number of components in solution "
-              "vector must equal "+ std::to_string(rdof*m_ncomp) );
-
-      //----- reconstruction of conserved quantities -----
-      //--------------------------------------------------
-      // specify how many variables need to be reconstructed
-      std::vector< std::size_t > vars;
-      for (std::size_t k=0; k<nmat; ++k) {
-        vars.push_back(volfracIdx(nmat,k));
-        vars.push_back(densityIdx(nmat,k));
-      }
-
-      // 1. solve 3x3 least-squares system
-      for (std::size_t e=0; e<nelem; ++e)
-      {
-        // Reconstruct second-order dofs of volume-fractions in Taylor space
-        // using nodal-stencils, for a good interface-normal estimate
-        tk::recoLeastSqExtStencil( rdof, e, esup, inpoel, geoElem, U, vars );
-      }
-
-      // 2. transform reconstructed derivatives to Dubiner dofs
-      tk::transform_P0P1(rdof, nelem, inpoel, coord, U, vars);
-
-      //----- reconstruction of primitive quantities -----
-      //--------------------------------------------------
-      // For multimat, conserved and primitive quantities are reconstructed
-      // separately.
-      vars.clear();
-      for (std::size_t c=0; c<nprim(); ++c) vars.push_back(c);
-      // 1.
-      for (std::size_t e=0; e<nelem; ++e)
-      {
-        // Reconstruct second-order dofs of volume-fractions in Taylor space
-        // using nodal-stencils, for a good interface-normal estimate
-        tk::recoLeastSqExtStencil( rdof, e, esup, inpoel, geoElem, P, vars );
-      }
-
-      // 2.
-      tk::transform_P0P1(rdof, nelem, inpoel, coord, P, vars);
-    }
-
-    //! Limit second-order solution, and primitive quantities separately
-    //! \param[in] geoFace Face geometry array
-    //! \param[in] fd Face connectivity and boundary conditions object
-    //! \param[in] esup Elements-surrounding-nodes connectivity
-    //! \param[in] inpoel Element-node connectivity
-    //! \param[in] coord Array of nodal coordinates
-    //! \param[in] srcFlag Whether the energy source was added
-    //! \param[in,out] U Solution vector at recent time step
-    //! \param[in,out] P Vector of primitives at recent time step
-    void limit( const tk::Fields& geoFace,
-                const inciter::FaceData& fd,
-                const std::map< std::size_t, std::vector< std::size_t > >& esup,
-                const std::vector< std::size_t >& inpoel,
-                const tk::UnsMesh::Coords& coord,
-                const std::vector< int >& srcFlag,
-                tk::Fields& U,
-                tk::Fields& P ) const
-    {
+      const auto limiter = g_inputdeck.get< tag::limiter >();
+
+      if (limiter == ctr::LimiterType::WENOP1)
+        WENO_P1( fd.Esuel(), U );
+      else if (limiter == ctr::LimiterType::SUPERBEEP1)
+        Superbee_P1( fd.Esuel(), inpoel, ndofel, coord, U );
+      else if (limiter == ctr::LimiterType::VERTEXBASEDP1)
+        VertexBasedTransport_P1( esup, inpoel, ndofel, fd.Esuel().size()/4,
+          coord, U );
+    }
+
+    //! Update the conservative variable solution for this PDE system
+    //! \details This function computes the updated dofs for conservative
+    //!   quantities based on the limited solution and is currently not used in
+    //!   transport.
+    void CPL( const tk::Fields&,
+              const tk::Fields&,
+              const std::vector< std::size_t >&,
+              const tk::UnsMesh::Coords&,
+              tk::Fields&,
+              std::size_t ) const {}
+
+    //! Return cell-average deformation gradient tensor (no-op for transport)
+    //! \details This function is a no-op in transport.
+    std::array< std::vector< tk::real >, 9 > cellAvgDeformGrad(
+      const tk::Fields&,
+      std::size_t ) const
+    {
+      return {};
+    }
+
+    //! Compute right hand side
+    //! \param[in] t Physical time
+    //! \param[in] geoFace Face geometry array
+    //! \param[in] geoElem Element geometry array
+    //! \param[in] fd Face connectivity and boundary conditions object
+    //! \param[in] inpoel Element-node connectivity
+    //! \param[in] coord Array of nodal coordinates
+    //! \param[in] U Solution vector at recent time step
+    //! \param[in] P Primitive vector at recent time step
+    //! \param[in] ndofel Vector of local number of degrees of freedom
+    // //! \param[in] rho0mat Initial densities of all materials
+    //! \param[in] dt Delta time
+    //! \param[in,out] R Right-hand side vector computed
+    void rhs( tk::real t,
+              const tk::Fields& geoFace,
+              const tk::Fields& geoElem,
+              const inciter::FaceData& fd,
+              const std::vector< std::size_t >& inpoel,
+              const std::vector< std::unordered_set< std::size_t > >&,
+              const tk::UnsMesh::Coords& coord,
+              const tk::Fields& U,
+              const tk::Fields& P,
+              const std::vector< std::size_t >& ndofel,
+              const std::vector< tk::real >& /*rho0mat*/,
+              const tk::real dt,
+              tk::Fields& R ) const
+    {
+      const auto ndof = g_inputdeck.get< tag::ndof >();<--- Variable 'ndof' is assigned a value that is never used.
+      const auto rdof = g_inputdeck.get< tag::rdof >();<--- Variable 'rdof' is assigned a value that is never used.
+      const auto intsharp = g_inputdeck.get< tag::transport,<--- Variable 'intsharp' is assigned a value that is never used.
+        tag::intsharp >();
+
       Assert( U.nunk() == P.nunk(), "Number of unknowns in solution "
               "vector and primitive vector at recent time step incorrect" );
-
-      const auto limiter = g_inputdeck.get< tag::limiter >();
-      auto nmat = g_inputdeck.get< tag::multimat, tag::nmat >();<--- Shadow variable
-      const auto& solidx = g_inputdeck.get<
-        tag::matidxmap, tag::solidx >();
-
-      // limit vectors of conserved and primitive quantities
-      if (limiter == ctr::LimiterType::VERTEXBASEDP1)
-      {
-        VertexBasedMultiMat_FV( esup, inpoel, fd.Esuel().size()/4,
-          coord, srcFlag, solidx, U, P, nmat );
-        PositivityPreservingMultiMat_FV( inpoel, fd.Esuel().size()/4, nmat,
-          m_mat_blk, coord, geoFace, U, P );
-      }
-      else if (limiter != ctr::LimiterType::NOLIMITER)
-      {
-        Throw("Limiter type not configured for multimat.");
-      }
-    }
-
-    //! Apply CPL to the conservative variable solution for this PDE system
-    //! \param[in] prim Array of primitive variables
-    //! \param[in] geoElem Element geometry array
-    //! \param[in] inpoel Element-node connectivity
-    //! \param[in] coord Array of nodal coordinates
-    //! \param[in,out] unk Array of conservative variables
-    //! \param[in] nielem Number of internal elements
-    //! \details This function applies CPL to obtain consistent dofs for
-    //!   conservative quantities based on the limited primitive quantities.
-    //!   See Pandare et al. (2023). On the Design of Stable,
-    //!   Consistent, and Conservative High-Order Methods for Multi-Material
-    //!   Hydrodynamics. J Comp Phys, 112313.
-    void CPL( const tk::Fields& prim,
-      const tk::Fields& geoElem,
-      const std::vector< std::size_t >& inpoel,
-      const tk::UnsMesh::Coords& coord,
-      tk::Fields& unk,
-      std::size_t nielem ) const
-    {
-      [[maybe_unused]] const auto rdof = g_inputdeck.get< tag::rdof >();
-      auto nmat = g_inputdeck.get< tag::multimat, tag::nmat >();<--- Shadow variable<--- Variable 'nmat' is assigned a value that is never used.
-
-      Assert( unk.nunk() == prim.nunk(), "Number of unknowns in solution "
-              "vector and primitive vector at recent time step incorrect" );
-      Assert( unk.nprop() == rdof*m_ncomp, "Number of components in solution "
-              "vector must equal "+ std::to_string(rdof*m_ncomp) );
-      Assert( prim.nprop() == rdof*nprim(), "Number of components in vector of "
-              "primitive quantities must equal "+ std::to_string(rdof*nprim()) );
-
-      correctLimConservMultiMat(nielem, m_mat_blk, nmat, inpoel,
-        coord, geoElem, prim, unk);
-    }
-
-    //! Compute right hand side
-    //! \param[in] t Physical time
-    //! \param[in] geoFace Face geometry array
-    //! \param[in] geoElem Element geometry array
-    //! \param[in] fd Face connectivity and boundary conditions object
-    //! \param[in] inpoel Element-node connectivity
-    //! \param[in] coord Array of nodal coordinates
-    //! \param[in] elemblkid Element ids associated with mesh block ids where
-    //!   user ICs are set
-    //! \param[in] U Solution vector at recent time step
-    //! \param[in] P Primitive vector at recent time step
-    //! \param[in,out] R Right-hand side vector computed
-    //! \param[in,out] srcFlag Whether the energy source was added
-    void rhs( tk::real t,
-              const tk::Fields& geoFace,
-              const tk::Fields& geoElem,
-              const inciter::FaceData& fd,
-              const std::vector< std::size_t >& inpoel,
-              const tk::UnsMesh::Coords& coord,
-              const std::unordered_map< std::size_t, std::set< std::size_t > >&
-                elemblkid,
-              const tk::Fields& U,
-              const tk::Fields& P,
-              tk::Fields& R,
-              std::vector< int >& srcFlag ) const
-    {
-      const auto rdof = g_inputdeck.get< tag::rdof >();
-      auto nmat = g_inputdeck.get< tag::multimat, tag::nmat >();<--- Shadow variable
-      const auto intsharp =
-        g_inputdeck.get< tag::multimat, tag::intsharp >();
-
-      const auto nelem = fd.Esuel().size()/4;
-
-      Assert( U.nunk() == P.nunk(), "Number of unknowns in solution "
-              "vector and primitive vector at recent time step incorrect" );
-      Assert( U.nunk() == R.nunk(), "Number of unknowns in solution "
-              "vector and right-hand side at recent time step incorrect" );
-      Assert( U.nprop() == rdof*m_ncomp, "Number of components in solution "
-              "vector must equal "+ std::to_string(rdof*m_ncomp) );
-      Assert( P.nprop() == rdof*nprim(), "Number of components in primitive "
-              "vector must equal "+ std::to_string(rdof*nprim()) );
-      Assert( fd.Inpofa().size()/3 == fd.Esuf().size()/2,
-              "Mismatch in inpofa size" );
-
-      // set rhs to zero
-      R.fill(0.0);
-
-      // configure a no-op lambda for prescribed velocity
-      auto velfn = []( ncomp_t, tk::real, tk::real, tk::real, tk::real ){
-        return tk::VelFn::result_type(); };
-
-      // compute internal surface flux (including non-conservative) integrals
-      tk::surfIntFV( nmat, m_mat_blk, t, rdof, inpoel,
-                     coord, fd, geoFace, geoElem, m_riemann, velfn, U, P,
-                     srcFlag, R, intsharp );
-
-      // compute boundary surface flux (including non-conservative) integrals
-      for (const auto& b : m_bc)
-        tk::bndSurfIntFV( nmat, m_mat_blk, rdof, b.first,
-                          fd, geoFace, geoElem, inpoel, coord, t, m_riemann,
-                          velfn, b.second, U, P, srcFlag, R, intsharp );
-
-      // compute optional source term
-      tk::srcIntFV( m_mat_blk, t, fd.Esuel().size()/4,
-                    geoElem, Problem::src, R, nmat );
-
-      // compute finite pressure relaxation terms
-      if (g_inputdeck.get< tag::multimat, tag::prelax >())
-      {
-        const auto ct = g_inputdeck.get< tag::multimat,
-                                         tag::prelax_timescale >();
-        tk::pressureRelaxationIntFV( nmat, m_mat_blk, rdof,
-                                     nelem, inpoel, coord, geoElem, U, P, ct,
-                                     R );
-      }
-
-      // compute external (energy) sources
-      m_physics.physSrc(nmat, t, geoElem, elemblkid, R, srcFlag);
-    }
-
-    //! Compute the minimum time step size
-//    //! \param[in] fd Face connectivity and boundary conditions object
-//    //! \param[in] geoFace Face geometry array
-    //! \param[in] geoElem Element geometry array
-    //! \param[in] U Solution vector at recent time step
-    //! \param[in] P Vector of primitive quantities at recent time step
-    //! \param[in] nielem Number of internal elements
-    //! \param[in] srcFlag Whether the energy source was added
-    //! \param[in,out] local_dte Time step size for each element (for local
-    //!   time stepping)
-    //! \return Minimum time step size
-    //! \details The allowable dt is calculated by looking at the maximum
-    //!   wave-speed in elements surrounding each face, times the area of that
-    //!   face. Once the maximum of this quantity over the mesh is determined,
-    //!   the volume of each cell is divided by this quantity. A minimum of this
-    //!   ratio is found over the entire mesh, which gives the allowable dt.
-    tk::real dt( const inciter::FaceData& /*fd*/,
-                 const tk::Fields& /*geoFace*/,
-                 const tk::Fields& geoElem,
-                 const tk::Fields& U,
-                 const tk::Fields& P,
-                 const std::size_t nielem,
-                 const std::vector< int >& srcFlag,
-                 std::vector< tk::real >& local_dte ) const
-    {
-      auto nmat = g_inputdeck.get< tag::multimat, tag::nmat >();<--- Shadow variable
-
-      // obtain dt restrictions from all physics
-      auto dt_e = timeStepSizeMultiMatFV(m_mat_blk, geoElem, nielem, nmat, U,
-        P, local_dte);
-      auto dt_p = m_physics.dtRestriction(geoElem, nielem, srcFlag);
-
-      return std::min(dt_e, dt_p);
-    }
-
-    //! Extract the velocity field at cell nodes. Currently unused.
-    //! \param[in] U Solution vector at recent time step
-    //! \param[in] N Element node indices
-    //! \return Array of the four values of the velocity field
-    std::array< std::array< tk::real, 4 >, 3 >
-    velocity( const tk::Fields& U,
-              const std::array< std::vector< tk::real >, 3 >&,
-              const std::array< std::size_t, 4 >& N ) const
-    {
-      const auto rdof = g_inputdeck.get< tag::rdof >();
-      auto nmat = g_inputdeck.get< tag::multimat, tag::nmat >();<--- Shadow variable
-
-      std::array< std::array< tk::real, 4 >, 3 > v;
-      v[0] = U.extract( momentumDofIdx(nmat, 0, rdof, 0), N );
-      v[1] = U.extract( momentumDofIdx(nmat, 1, rdof, 0), N );
-      v[2] = U.extract( momentumDofIdx(nmat, 2, rdof, 0), N );
-
-      std::vector< std::array< tk::real, 4 > > ar;
-      ar.resize(nmat);
-      for (std::size_t k=0; k<nmat; ++k)
-        ar[k] = U.extract( densityDofIdx(nmat, k, rdof, 0), N );
-
-      std::array< tk::real, 4 > r{{ 0.0, 0.0, 0.0, 0.0 }};
-      for (std::size_t i=0; i<r.size(); ++i) {
-        for (std::size_t k=0; k<nmat; ++k)
-          r[i] += ar[k][i];
-      }
+      Assert( U.nunk() == R.nunk(), "Number of unknowns in solution "
+              "vector and right-hand side at recent time step incorrect" );
+      Assert( U.nprop() == rdof*m_ncomp, "Number of components in solution "
+              "vector must equal "+ std::to_string(rdof*m_ncomp) );
+      Assert( P.nprop() == 0, "Number of components in primitive "
+              "vector must equal "+ std::to_string(0) );
+      Assert( R.nprop() == ndof*m_ncomp, "Number of components in right-hand "
+              "side vector must equal "+ std::to_string(ndof*m_ncomp) );
+      Assert( fd.Inpofa().size()/3 == fd.Esuf().size()/2,
+              "Mismatch in inpofa size" );
+
+      // set rhs to zero
+      R.fill(0.0);
+
+      // empty vector for non-conservative terms. This vector is unused for
+      // linear transport since, there are no non-conservative terms in the
+      // system of PDEs.
+      std::vector< std::vector < tk::real > > riemannDeriv;
+
+      std::vector< std::vector< tk::real > > vriem;
+      std::vector< std::vector< tk::real > > riemannLoc;
+
+      // compute internal surface flux integrals
+      std::vector< std::size_t > solidx(1, 0);
+      tk::surfInt( m_ncomp, m_mat_blk, t, ndof, rdof,
+                   inpoel, solidx, coord, fd, geoFace, geoElem, Upwind::flux,
+                   Problem::prescribedVelocity, U, P, ndofel, dt, R, vriem,
+                   riemannLoc, riemannDeriv, intsharp );
+
+      if(ndof > 1)
+        // compute volume integrals
+        tk::volInt( m_ncomp, t, m_mat_blk, ndof, rdof,
+                    fd.Esuel().size()/4, inpoel, coord, geoElem, flux,
+                    Problem::prescribedVelocity, U, P, ndofel, R, intsharp );
+
+      // compute boundary surface flux integrals
+      for (const auto& b : m_bc)
+        tk::bndSurfInt( m_ncomp, m_mat_blk, ndof, rdof,
+          b.first, fd, geoFace, geoElem, inpoel, coord, t, Upwind::flux,
+          Problem::prescribedVelocity, b.second, U, P, ndofel, R, vriem,
+          riemannLoc, riemannDeriv, intsharp );
+    }
+
+    //! Evaluate the adaptive indicator and mark the ndof for each element
+    //! \param[in] nunk Number of unknowns
+    //! \param[in] coord Array of nodal coordinates
+    //! \param[in] inpoel Element-node connectivity
+    //! \param[in] fd Face connectivity and boundary conditions object
+    //! \param[in] unk Array of unknowns
+    //! \param[in] prim Array of primitive quantities
+    //! \param[in] indicator p-refinement indicator type
+    //! \param[in] ndof Number of degrees of freedom in the solution
+    //! \param[in] ndofmax Max number of degrees of freedom for p-refinement
+    //! \param[in] tolref Tolerance for p-refinement
+    //! \param[in,out] ndofel Vector of local number of degrees of freedome
+    void eval_ndof( std::size_t nunk,
+                    [[maybe_unused]] const tk::UnsMesh::Coords& coord,
+                    [[maybe_unused]] const std::vector< std::size_t >& inpoel,
+                    const inciter::FaceData& fd,
+                    const tk::Fields& unk,
+                    const tk::Fields& prim,
+                    inciter::ctr::PrefIndicatorType indicator,
+                    std::size_t ndof,
+                    std::size_t ndofmax,
+                    tk::real tolref,
+                    std::vector< std::size_t >& ndofel ) const
+    {
+      const auto& esuel = fd.Esuel();
+
+      if(indicator == inciter::ctr::PrefIndicatorType::SPECTRAL_DECAY)
+        spectral_decay( 1, nunk, esuel, unk, prim, ndof, ndofmax, tolref,
+          ndofel );
+      else
+        Throw( "No such adaptive indicator type" );
+    }
+
+    //! Compute the minimum time step size
+//     //! \param[in] U Solution vector at recent time step
+//     //! \param[in] coord Mesh node coordinates
+//     //! \param[in] inpoel Mesh element connectivity
+    //! \return Minimum time step size
+    tk::real dt( const std::array< std::vector< tk::real >, 3 >& /*coord*/,
+                 const std::vector< std::size_t >& /*inpoel*/,
+                 const inciter::FaceData& /*fd*/,
+                 const tk::Fields& /*geoFace*/,
+                 const tk::Fields& /*geoElem*/,
+                 const std::vector< std::size_t >& /*ndofel*/,
+                 const tk::Fields& /*U*/,
+                 const tk::Fields&,
+                 const std::size_t /*nielem*/ ) const
+    {
+      tk::real mindt = std::numeric_limits< tk::real >::max();
+      return mindt;
+    }
+
+    //! Compute stiff terms for a single element, not implemented here
+    // //! \param[in] e Element number
+    // //! \param[in] geoElem Element geometry array
+    // //! \param[in] inpoel Element-node connectivity
+    // //! \param[in] coord Array of nodal coordinates
+    // //! \param[in] U Solution vector at recent time step
+    // //! \param[in] P Primitive vector at recent time step
+    // //! \param[in] ndofel Vector of local number of degrees of freedom
+    // //! \param[in,out] R Right-hand side vector computed
+    void stiff_rhs( std::size_t /*e*/,
+                    const tk::Fields& /*geoElem*/,
+                    const std::vector< std::size_t >& /*inpoel*/,
+                    const tk::UnsMesh::Coords& /*coord*/,
+                    const tk::Fields& /*U*/,
+                    const tk::Fields& /*P*/,
+                    const std::vector< std::size_t >& /*ndofel*/,
+                    tk::Fields& /*R*/ ) const
+    {}
+
+    //! Return a map that associates user-specified strings to functions
+    //! \return Map that associates user-specified strings to functions that
+    //!  compute relevant quantities to be output to file
+    std::map< std::string, tk::GetVarFn > OutVarFn() const {
+      std::map< std::string, tk::GetVarFn > OutFnMap;
+      OutFnMap["material_indicator"] = transport::matIndicatorOutVar;
+
+      return OutFnMap;
+    }
+
+    //! Return analytic field names to be output to file
+    //! \return Vector of strings labelling analytic fields output in file
+    std::vector< std::string > analyticFieldNames() const {
+      std::vector< std::string > n;
+      auto depvar = g_inputdeck.get< tag::depvar >()[0];
+      for (ncomp_t c=0; c<m_ncomp; ++c)
+        n.push_back( depvar + std::to_string(c) + "_analytic" );
+      return n;
+    }
+
+    //! Return surface field output going to file
+    std::vector< std::vector< tk::real > >
+    surfOutput( const std::map< int, std::vector< std::size_t > >&,
+                tk::Fields& ) const
+    {
+      std::vector< std::vector< tk::real > > s; // punt for now
+      return s;
+    }
+
+    //! Return time history field names to be output to file
+    //! \return Vector of strings labelling time history fields output in file
+    std::vector< std::string > histNames() const {
+      std::vector< std::string > s; // punt for now
+      return s;
+    }
+
+    //! Return names of integral variables to be output to diagnostics file
+    //! \return Vector of strings labelling integral variables output
+    std::vector< std::string > names() const {
+      std::vector< std::string > n;
+      const auto& depvar =
+      g_inputdeck.get< tag::depvar >().at(0);
+      // construct the name of the numerical solution for all components
+      for (ncomp_t c=0; c<m_ncomp; ++c)
+        n.push_back( depvar + std::to_string(c) );
+      return n;
+    }
+
+    //! Return analytic solution (if defined by Problem) at xi, yi, zi, t
+    //! \param[in] xi X-coordinate at which to evaluate the analytic solution
+    //! \param[in] yi Y-coordinate at which to evaluate the analytic solution
+    //! \param[in] zi Z-coordinate at which to evaluate the analytic solution
+    //! \param[in] t Physical time at which to evaluate the analytic solution
+    //! \return Vector of analytic solution at given spatial location and time
+    std::vector< tk::real >
+    analyticSolution( tk::real xi, tk::real yi, tk::real zi, tk::real t ) const
+    { return Problem::analyticSolution( m_ncomp, m_mat_blk, xi, yi,
+                                        zi, t ); }
+
+    //! Return analytic solution for conserved variables
+    //! \param[in] xi X-coordinate at which to evaluate the analytic solution
+    //! \param[in] yi Y-coordinate at which to evaluate the analytic solution
+    //! \param[in] zi Z-coordinate at which to evaluate the analytic solution
+    //! \param[in] t Physical time at which to evaluate the analytic solution
+    //! \return Vector of analytic solution at given location and time
+    std::vector< tk::real >
+    solution( tk::real xi, tk::real yi, tk::real zi, tk::real t ) const
+    { return Problem::initialize( m_ncomp, m_mat_blk, xi, yi, zi, t ); }
+
+    //! Return time history field output evaluated at time history points
+    //! \param[in] h History point data
+    std::vector< std::vector< tk::real > >
+    histOutput( const std::vector< HistData >& h,
+                const std::vector< std::size_t >&,
+                const tk::UnsMesh::Coords&,
+                const tk::Fields&,
+                const tk::Fields& ) const
+    {
+      std::vector< std::vector< tk::real > > Up(h.size()); //punt for now
+      return Up;
+    }
 
-      std::transform( r.begin(), r.end(), v[0].begin(), v[0].begin(),
-                      []( tk::real s, tk::real& d ){ return d /= s; } );
-      std::transform( r.begin(), r.end(), v[1].begin(), v[1].begin(),
-                      []( tk::real s, tk::real& d ){ return d /= s; } );
-      std::transform( r.begin(), r.end(), v[2].begin(), v[2].begin(),
-                      []( tk::real s, tk::real& d ){ return d /= s; } );
-      return v;
-    }
-
-    //! Return a map that associates user-specified strings to functions
-    //! \return Map that associates user-specified strings to functions that
-    //!   compute relevant quantities to be output to file
-    std::map< std::string, tk::GetVarFn > OutVarFn() const
-    { return MultiMatOutVarFn(); }
-
-    //! Return analytic field names to be output to file
-    //! \return Vector of strings labelling analytic fields output in file
-    std::vector< std::string > analyticFieldNames() const {
-      auto nmat = g_inputdeck.get< eq, tag::nmat >();<--- Shadow variable
-
-      return MultiMatFieldNames(nmat);
-    }
-
-    //! Return surface field names to be output to file
-    //! \return Vector of strings labelling surface fields output in file
-    std::vector< std::string > surfNames() const
-    { return MultiMatSurfNames(); }
-
-    //! Return time history field names to be output to file
-    //! \return Vector of strings labelling time history fields output in file
-    std::vector< std::string > histNames() const {
-      return MultiMatHistNames();
-    }
-
-    //! Return surface field output going to file
-    std::vector< std::vector< tk::real > >
-    surfOutput( const inciter::FaceData& fd,
-      const tk::Fields& U,
-      const tk::Fields& P ) const
-    {
-      const auto rdof = g_inputdeck.get< tag::rdof >();
-      auto nmat = g_inputdeck.get< tag::multimat, tag::nmat >();<--- Shadow variable
-
-      return MultiMatSurfOutput( nmat, rdof, fd, U, P );
-    }
-
-    //! Return time history field output evaluated at time history points
-    //! \param[in] h History point data
-    //! \param[in] inpoel Element-node connectivity
-    //! \param[in] coord Array of nodal coordinates
-    //! \param[in] U Array of unknowns
-    //! \param[in] P Array of primitive quantities
-    //! \return Vector of time history output of bulk flow quantities (density,
-    //!   velocity, total energy, pressure, and volume fraction) evaluated at 
-    //!   time history points
-    std::vector< std::vector< tk::real > >
-    histOutput( const std::vector< HistData >& h,
-                const std::vector< std::size_t >& inpoel,
-                const tk::UnsMesh::Coords& coord,
-                const tk::Fields& U,
-                const tk::Fields& P ) const
-    {
-      const auto rdof = g_inputdeck.get< tag::rdof >();
-      auto nmat = g_inputdeck.get< tag::multimat, tag::nmat >();<--- Shadow variable
-
-      const auto& x = coord[0];
-      const auto& y = coord[1];
-      const auto& z = coord[2];
-
-      std::vector< std::vector< tk::real > > Up(h.size());
-
-      std::size_t j = 0;
-      for (const auto& p : h) {
-        auto e = p.get< tag::elem >();
-        auto chp = p.get< tag::coord >();
-
-        // Evaluate inverse Jacobian
-        std::array< std::array< tk::real, 3>, 4 > cp{{
-          {{ x[inpoel[4*e  ]], y[inpoel[4*e  ]], z[inpoel[4*e  ]] }},
-          {{ x[inpoel[4*e+1]], y[inpoel[4*e+1]], z[inpoel[4*e+1]] }},
-          {{ x[inpoel[4*e+2]], y[inpoel[4*e+2]], z[inpoel[4*e+2]] }},
-          {{ x[inpoel[4*e+3]], y[inpoel[4*e+3]], z[inpoel[4*e+3]] }} }};
-        auto J = tk::inverseJacobian( cp[0], cp[1], cp[2], cp[3] );
-
-        // evaluate solution at history-point
-        std::array< tk::real, 3 > dc{{chp[0]-cp[0][0], chp[1]-cp[0][1],
-          chp[2]-cp[0][2]}};
-        auto B = tk::eval_basis(rdof, tk::dot(J[0],dc), tk::dot(J[1],dc),
-          tk::dot(J[2],dc));
-        auto uhp = eval_state(m_ncomp, rdof, rdof, e, U, B);
-        auto php = eval_state(nprim(), rdof, rdof, e, P, B);
-
-        // store solution in history output vector
-        Up[j].resize(6+nmat, 0.0);
-        for (std::size_t k=0; k<nmat; ++k) {
-          Up[j][0] += uhp[densityIdx(nmat,k)];
-          Up[j][4] += uhp[energyIdx(nmat,k)];
-          Up[j][5] += php[pressureIdx(nmat,k)];
-          Up[j][6+k] = uhp[volfracIdx(nmat,k)];
-        }
-        Up[j][1] = php[velocityIdx(nmat,0)];
-        Up[j][2] = php[velocityIdx(nmat,1)];
-        Up[j][3] = php[velocityIdx(nmat,2)];
-        ++j;
-      }
-
-      return Up;
-    }
-
-    //! Return names of integral variables to be output to diagnostics file
-    //! \return Vector of strings labelling integral variables output
-    std::vector< std::string > names() const
-    {
-      auto nmat = g_inputdeck.get< tag::multimat, tag::nmat >();<--- Shadow variable
-      return MultiMatDiagNames(nmat);
+    //! Return cell-averaged total component mass per unit volume for an element
+    //! \param[in] e Element id for which total energy is required
+    //! \param[in] unk Vector of conserved quantities
+    //! \return Cell-averaged total component mass per unit volume for given
+    //!   element. Since transport does not have an associated total energy,
+    //!   return total mass.
+    tk::real sp_totalenergy(std::size_t e, const tk::Fields& unk) const
+    {
+      const auto rdof = g_inputdeck.get< tag::rdof >();
+
+      tk::real sp_m(0.0);
+      for (std::size_t c=0; c<m_ncomp; ++c) {
+        sp_m += unk(e,c*rdof);
+      }
+      return sp_m;
+    }
+
+  private:
+    const Physics m_physics;            //!< Physics policy
+    const Problem m_problem;            //!< Problem policy
+    const ncomp_t m_ncomp;              //!< Number of components in this PDE
+    //! BC configuration
+    BCStateFn m_bc;
+    //! \brief EOS material block - This PDE does not require an EOS block,
+    //! thus this variable has not been intialized.
+    std::vector< EOS > m_mat_blk;
+
+    //! Evaluate physical flux function for this PDE system
+    //! \param[in] ncomp Number of scalar components in this PDE system
+    //! \param[in] ugp Numerical solution at the Gauss point at which to
+    //!   evaluate the flux
+    //! \param[in] v Prescribed velocity evaluated at the Gauss point at which
+    //!   to evaluate the flux
+    //! \return Flux vectors for all components in this PDE system
+    //! \note The function signature must follow tk::FluxFn
+    static tk::FluxFn::result_type
+    flux( ncomp_t ncomp,
+          const std::vector< EOS >&,
+          const std::vector< tk::real >& ugp,
+          const std::vector< std::array< tk::real, 3 > >& v )
+
+    {
+      Assert( ugp.size() == ncomp, "Size mismatch" );
+      Assert( v.size() == ncomp, "Size mismatch" );
+
+      std::vector< std::array< tk::real, 3 > > fl( ugp.size() );
+
+      for (ncomp_t c=0; c<ncomp; ++c)
+        fl[c] = {{ v[c][0] * ugp[c], v[c][1] * ugp[c], v[c][2] * ugp[c] }};
+
+      return fl;
+    }
+
+    //! \brief Boundary state function providing the left and right state of a
+    //!   face at extrapolation boundaries
+    //! \param[in] ul Left (domain-internal) state
+    //! \return Left and right states for all scalar components in this PDE
+    //!   system
+    //! \note The function signature must follow tk::StateFn
+    static tk::StateFn::result_type
+    extrapolate( ncomp_t, const std::vector< EOS >&,
+                 const std::vector< tk::real >& ul, tk::real, tk::real,
+                 tk::real, tk::real, const std::array< tk::real, 3 >& )
+    {
+      return {{ ul, ul }};
+    }
+
+    //! \brief Boundary state function providing the left and right state of a
+    //!   face at extrapolation boundaries
+    //! \param[in] ul Left (domain-internal) state
+    //! \return Left and right states for all scalar components in this PDE
+    //!   system
+    //! \note The function signature must follow tk::StateFn
+    static tk::StateFn::result_type
+    inlet( ncomp_t, const std::vector< EOS >&,
+           const std::vector< tk::real >& ul, tk::real, tk::real, tk::real,
+           tk::real, const std::array< tk::real, 3 >& )
+    {
+      auto ur = ul;
+      std::fill( begin(ur), end(ur), 0.0 );
+      return {{ ul, std::move(ur) }};
+    }
+
+    //! \brief Boundary state function providing the left and right state of a
+    //!   face at outlet boundaries
+    //! \param[in] ul Left (domain-internal) state
+    //! \return Left and right states for all scalar components in this PDE
+    //!   system
+    //! \note The function signature must follow tk::StateFn
+    static tk::StateFn::result_type
+    outlet( ncomp_t, const std::vector< EOS >&,
+            const std::vector< tk::real >& ul, tk::real, tk::real, tk::real,
+            tk::real, const std::array< tk::real, 3 >& )
+    {
+      return {{ ul, ul }};
+    }
+
+    //! \brief Boundary state function providing the left and right state of a
+    //!   face at Dirichlet boundaries
+    //! \param[in] ncomp Number of scalar components in this PDE system
+    //! \param[in] ul Left (domain-internal) state
+    //! \param[in] x X-coordinate at which to compute the states
+    //! \param[in] y Y-coordinate at which to compute the states
+    //! \param[in] z Z-coordinate at which to compute the states
+    //! \param[in] t Physical time
+    //! \return Left and right states for all scalar components in this PDE
+    //!   system
+    //! \note The function signature must follow tk::StateFn
+    static tk::StateFn::result_type
+    dirichlet( ncomp_t ncomp, 
+               const std::vector< EOS >& mat_blk,
+               const std::vector< tk::real >& ul, tk::real x, tk::real y,
+               tk::real z, tk::real t, const std::array< tk::real, 3 >& )
+    {
+      return {{ ul, Problem::initialize( ncomp, mat_blk, x, y, z, t ) }};
     }
-
-    //! Return analytic solution (if defined by Problem) at xi, yi, zi, t
-    //! \param[in] xi X-coordinate at which to evaluate the analytic solution
-    //! \param[in] yi Y-coordinate at which to evaluate the analytic solution
-    //! \param[in] zi Z-coordinate at which to evaluate the analytic solution
-    //! \param[in] t Physical time at which to evaluate the analytic solution
-    //! \return Vector of analytic solution at given location and time
-    std::vector< tk::real >
-    analyticSolution( tk::real xi, tk::real yi, tk::real zi, tk::real t ) const
-    { return Problem::analyticSolution( m_ncomp, m_mat_blk, xi, yi, zi, t ); }
-
-    //! Return analytic solution for conserved variables
-    //! \param[in] xi X-coordinate at which to evaluate the analytic solution
-    //! \param[in] yi Y-coordinate at which to evaluate the analytic solution
-    //! \param[in] zi Z-coordinate at which to evaluate the analytic solution
-    //! \param[in] t Physical time at which to evaluate the analytic solution
-    //! \return Vector of analytic solution at given location and time
-    std::vector< tk::real >
-    solution( tk::real xi, tk::real yi, tk::real zi, tk::real t ) const
-    { return Problem::initialize( m_ncomp, m_mat_blk, xi, yi, zi, t ); }
-
-    //! Return cell-averaged specific total energy for an element
-    //! \param[in] e Element id for which total energy is required
-    //! \param[in] unk Vector of conserved quantities
-    //! \return Cell-averaged specific total energy for given element
-    tk::real sp_totalenergy(std::size_t e, const tk::Fields& unk) const
-    {
-      const auto rdof = g_inputdeck.get< tag::rdof >();
-      auto nmat = g_inputdeck.get< tag::multimat, tag::nmat >();<--- Shadow variable
-
-      tk::real sp_te(0.0);
-      // sum each material total energy
-      for (std::size_t k=0; k<nmat; ++k) {
-        sp_te += unk(e, energyDofIdx(nmat,k,rdof,0));
-      }
-      return sp_te;
-    }
-
-    //! Compute relevant sound speed for output
-    //! \param[in] nielem Number of internal elements
-    //! \param[in] U Solution vector at recent time step
-    //! \param[in] P Primitive vector at recent time step
-    //! \param[in,out] ss Sound speed vector
-    void soundspeed(
-      std::size_t nielem,
-      const tk::Fields& U,
-      const tk::Fields& P,
-      std::vector< tk::real >& ss) const
-    {
-      Assert( ss.size() == nielem, "Size of sound speed vector incorrect " );
-
-      const auto ndof = g_inputdeck.get< tag::ndof >();
-      const auto rdof = g_inputdeck.get< tag::rdof >();
-      const auto use_mass_avg =
-        g_inputdeck.get< tag::multimat, tag::dt_sos_massavg >();
-      auto nmat = g_inputdeck.get< tag::multimat, tag::nmat >();<--- Shadow variable
-      std::size_t ncomp = U.nprop()/rdof;
-      std::size_t nprim = P.nprop()/rdof;<--- Shadow variable
-
-      std::vector< tk::real > ugp(ncomp, 0.0), pgp(nprim, 0.0);<--- Variable 'ugp' is assigned a value that is never used.<--- Variable 'pgp' is assigned a value that is never used.
-
-      for (std::size_t e=0; e<nielem; ++e) {
-        // basis function at centroid
-        std::vector< tk::real > B(rdof, 0.0);
-        B[0] = 1.0;
-
-        // get conserved quantities
-        ugp = eval_state(ncomp, rdof, ndof, e, U, B);
-        // get primitive quantities
-        pgp = eval_state(nprim, rdof, ndof, e, P, B);
-
-        // acoustic speed (this should be consistent with time-step calculation)
-        ss[e] = 0.0;
-        tk::real mixtureDensity = 0.0;
-        for (std::size_t k=0; k<nmat; ++k)
-        {
-          if (use_mass_avg > 0)
-          {
-            // mass averaging SoS
-            ss[e] += ugp[densityIdx(nmat,k)]*
-              m_mat_blk[k].compute< EOS::soundspeed >(
-              ugp[densityIdx(nmat, k)], pgp[pressureIdx(nmat, k)],
-              ugp[volfracIdx(nmat, k)], k );
-
-            mixtureDensity += ugp[densityIdx(nmat,k)];
-          }
-          else
-          {
-            if (ugp[volfracIdx(nmat, k)] > 1.0e-04)
-            {
-              ss[e] = std::max( ss[e], m_mat_blk[k].compute< EOS::soundspeed >(
-                ugp[densityIdx(nmat, k)], pgp[pressureIdx(nmat, k)],
-                ugp[volfracIdx(nmat, k)], k ) );
-            }
-          }
-        }
-        if (use_mass_avg > 0) ss[e] /= mixtureDensity;
-      }
-    }
-
-  private:
-    //! Physics policy
-    const Physics m_physics;
-    //! Number of components in this PDE system
-    const ncomp_t m_ncomp;
-    //! Riemann solver
-    tk::RiemannFluxFn m_riemann;
-    //! BC configuration
-    BCStateFn m_bc;
-    //! EOS material block
-    std::vector< EOS > m_mat_blk;
-
-    //! Evaluate conservative part of physical flux function for this PDE system
-    //! \param[in] ncomp Number of scalar components in this PDE system
-    //! \param[in] ugp Numerical solution at the Gauss point at which to
-    //!   evaluate the flux
-    //! \return Flux vectors for all components in this PDE system
-    //! \note The function signature must follow tk::FluxFn
-    static tk::FluxFn::result_type
-    flux( ncomp_t ncomp,
-          const std::vector< EOS >& mat_blk,
-          const std::vector< tk::real >& ugp,
-          const std::vector< std::array< tk::real, 3 > >& )
-    {
-      auto nmat = g_inputdeck.get< tag::multimat, tag::nmat >();<--- Shadow variable
-
-      return tk::fluxTerms(ncomp, nmat, mat_blk, ugp);
-    }
-
-    //! \brief Boundary state function providing the left and right state of a
-    //!   face at Dirichlet boundaries
-    //! \param[in] ncomp Number of scalar components in this PDE system
-    //! \param[in] ul Left (domain-internal) state
-    //! \param[in] x X-coordinate at which to compute the states
-    //! \param[in] y Y-coordinate at which to compute the states
-    //! \param[in] z Z-coordinate at which to compute the states
-    //! \param[in] t Physical time
-    //! \return Left and right states for all scalar components in this PDE
-    //!   system
-    //! \note The function signature must follow tk::StateFn. For multimat, the
-    //!   left or right state is the vector of conserved quantities, followed by
-    //!   the vector of primitive quantities appended to it.
-    static tk::StateFn::result_type
-    dirichlet( ncomp_t ncomp,
-               const std::vector< EOS >& mat_blk,
-               const std::vector< tk::real >& ul, tk::real x, tk::real y,
-               tk::real z, tk::real t, const std::array< tk::real, 3 >& )
-    {
-      auto nmat = g_inputdeck.get< tag::multimat, tag::nmat >();<--- Shadow variable<--- Variable 'nmat' is assigned a value that is never used.
-
-      auto ur = Problem::initialize( ncomp, mat_blk, x, y, z, t );
-      Assert( ur.size() == ncomp, "Incorrect size for boundary state vector" );
-
-      ur.resize(ul.size());
-
-      tk::real rho(0.0);
-      for (std::size_t k=0; k<nmat; ++k)
-        rho += ur[densityIdx(nmat, k)];
-
-      // get primitives in boundary state
-
-      // velocity
-      ur[ncomp+velocityIdx(nmat, 0)] = ur[momentumIdx(nmat, 0)] / rho;
-      ur[ncomp+velocityIdx(nmat, 1)] = ur[momentumIdx(nmat, 1)] / rho;
-      ur[ncomp+velocityIdx(nmat, 2)] = ur[momentumIdx(nmat, 2)] / rho;
-
-      // material pressures
-      for (std::size_t k=0; k<nmat; ++k)
-      {
-        auto gk = getDeformGrad(nmat, k, ur);
-        ur[ncomp+pressureIdx(nmat, k)] = mat_blk[k].compute< EOS::pressure >(
-          ur[densityIdx(nmat, k)], ur[ncomp+velocityIdx(nmat, 0)],
-          ur[ncomp+velocityIdx(nmat, 1)], ur[ncomp+velocityIdx(nmat, 2)],
-          ur[energyIdx(nmat, k)], ur[volfracIdx(nmat, k)], k, gk );
-      }
-
-      Assert( ur.size() == ncomp+nmat+3, "Incorrect size for appended "
-              "boundary state vector" );
-
-      return {{ std::move(ul), std::move(ur) }};
-    }
-
-    // Other boundary condition types that do not depend on "Problem" should be
-    // added in BCFunctions.hpp
-};
-
-} // fv::
-
-} // inciter::
-
-#endif // FVMultiMat_h
+};
+
+} // dg::
+} // inciter::
+
+#endif // DGTransport_h
 
diff --git a/Release/cppcheck/57.html b/Release/cppcheck/57.html index 7fd9975c50e0..be7f2fc58907 100644 --- a/Release/cppcheck/57.html +++ b/Release/cppcheck/57.html @@ -152,3237 +152,259 @@
- - + @@ -94,7 +94,7 @@ - + @@ -106,7 +106,7 @@ - + @@ -118,7 +118,7 @@ - + diff --git a/Release/test_coverage/Control/Options/index.html b/Release/test_coverage/Control/Options/index.html index 1b294359708d..f2b1278badb2 100644 --- a/Release/test_coverage/Control/Options/index.html +++ b/Release/test_coverage/Control/Options/index.html @@ -33,7 +33,7 @@ - + diff --git a/Release/test_coverage/Control/StatCtr.hpp.func-sort-c.html b/Release/test_coverage/Control/StatCtr.hpp.func-sort-c.html index 1f0e924a946b..29559a188534 100644 --- a/Release/test_coverage/Control/StatCtr.hpp.func-sort-c.html +++ b/Release/test_coverage/Control/StatCtr.hpp.func-sort-c.html @@ -33,7 +33,7 @@ - + diff --git a/Release/test_coverage/Control/StatCtr.hpp.func.html b/Release/test_coverage/Control/StatCtr.hpp.func.html index b7533f10c7a5..ade525dd7dc3 100644 --- a/Release/test_coverage/Control/StatCtr.hpp.func.html +++ b/Release/test_coverage/Control/StatCtr.hpp.func.html @@ -33,7 +33,7 @@ - + diff --git a/Release/test_coverage/Control/StatCtr.hpp.gcov.html b/Release/test_coverage/Control/StatCtr.hpp.gcov.html index 63e5428d4154..a4b3862d21e9 100644 --- a/Release/test_coverage/Control/StatCtr.hpp.gcov.html +++ b/Release/test_coverage/Control/StatCtr.hpp.gcov.html @@ -33,7 +33,7 @@ - + diff --git a/Release/test_coverage/Control/StringParser.cpp.func-sort-c.html b/Release/test_coverage/Control/StringParser.cpp.func-sort-c.html index d1726de51831..7f12f90f50f7 100644 --- a/Release/test_coverage/Control/StringParser.cpp.func-sort-c.html +++ b/Release/test_coverage/Control/StringParser.cpp.func-sort-c.html @@ -33,7 +33,7 @@ - + diff --git a/Release/test_coverage/Control/StringParser.cpp.func.html b/Release/test_coverage/Control/StringParser.cpp.func.html index 51f9143d79b0..878e2eefdab5 100644 --- a/Release/test_coverage/Control/StringParser.cpp.func.html +++ b/Release/test_coverage/Control/StringParser.cpp.func.html @@ -33,7 +33,7 @@ - + diff --git a/Release/test_coverage/Control/StringParser.cpp.gcov.html b/Release/test_coverage/Control/StringParser.cpp.gcov.html index 72cd0f7195d8..f74600400ef2 100644 --- a/Release/test_coverage/Control/StringParser.cpp.gcov.html +++ b/Release/test_coverage/Control/StringParser.cpp.gcov.html @@ -33,7 +33,7 @@ - + diff --git a/Release/test_coverage/Control/StringParser.hpp.func-sort-c.html b/Release/test_coverage/Control/StringParser.hpp.func-sort-c.html index 6e0a781177b9..27971e5a0089 100644 --- a/Release/test_coverage/Control/StringParser.hpp.func-sort-c.html +++ b/Release/test_coverage/Control/StringParser.hpp.func-sort-c.html @@ -33,7 +33,7 @@ - + diff --git a/Release/test_coverage/Control/StringParser.hpp.func.html b/Release/test_coverage/Control/StringParser.hpp.func.html index a16acf124465..c73aadc6842d 100644 --- a/Release/test_coverage/Control/StringParser.hpp.func.html +++ b/Release/test_coverage/Control/StringParser.hpp.func.html @@ -33,7 +33,7 @@ - + diff --git a/Release/test_coverage/Control/StringParser.hpp.gcov.html b/Release/test_coverage/Control/StringParser.hpp.gcov.html index 60b8e6bf1326..92e413eaba44 100644 --- a/Release/test_coverage/Control/StringParser.hpp.gcov.html +++ b/Release/test_coverage/Control/StringParser.hpp.gcov.html @@ -33,7 +33,7 @@ - + diff --git a/Release/test_coverage/Control/Tags.hpp.func-sort-c.html b/Release/test_coverage/Control/Tags.hpp.func-sort-c.html index 04c1582ff75e..f214296fab22 100644 --- a/Release/test_coverage/Control/Tags.hpp.func-sort-c.html +++ b/Release/test_coverage/Control/Tags.hpp.func-sort-c.html @@ -33,7 +33,7 @@ - + diff --git a/Release/test_coverage/Control/Tags.hpp.func.html b/Release/test_coverage/Control/Tags.hpp.func.html index 4afd182e6636..ebd9f7681d7f 100644 --- a/Release/test_coverage/Control/Tags.hpp.func.html +++ b/Release/test_coverage/Control/Tags.hpp.func.html @@ -33,7 +33,7 @@ - + diff --git a/Release/test_coverage/Control/Tags.hpp.gcov.html b/Release/test_coverage/Control/Tags.hpp.gcov.html index 6fb5acd76482..9058e9cdc4db 100644 --- a/Release/test_coverage/Control/Tags.hpp.gcov.html +++ b/Release/test_coverage/Control/Tags.hpp.gcov.html @@ -33,7 +33,7 @@ - + diff --git a/Release/test_coverage/Control/Toggle.hpp.func-sort-c.html b/Release/test_coverage/Control/Toggle.hpp.func-sort-c.html index 534c58a569cc..a972172434a1 100644 --- a/Release/test_coverage/Control/Toggle.hpp.func-sort-c.html +++ b/Release/test_coverage/Control/Toggle.hpp.func-sort-c.html @@ -33,7 +33,7 @@ - + diff --git a/Release/test_coverage/Control/Toggle.hpp.func.html b/Release/test_coverage/Control/Toggle.hpp.func.html index 072ded1d0989..7dcbebbd7851 100644 --- a/Release/test_coverage/Control/Toggle.hpp.func.html +++ b/Release/test_coverage/Control/Toggle.hpp.func.html @@ -33,7 +33,7 @@ - + diff --git a/Release/test_coverage/Control/Toggle.hpp.gcov.html b/Release/test_coverage/Control/Toggle.hpp.gcov.html index 6cef11ebfcdb..ecaa3c306498 100644 --- a/Release/test_coverage/Control/Toggle.hpp.gcov.html +++ b/Release/test_coverage/Control/Toggle.hpp.gcov.html @@ -33,7 +33,7 @@ - + diff --git a/Release/test_coverage/Control/UnitTest/CmdLine/CmdLine.hpp.func-sort-c.html b/Release/test_coverage/Control/UnitTest/CmdLine/CmdLine.hpp.func-sort-c.html index 68c8f6ae5c15..9a7e1401a425 100644 --- a/Release/test_coverage/Control/UnitTest/CmdLine/CmdLine.hpp.func-sort-c.html +++ b/Release/test_coverage/Control/UnitTest/CmdLine/CmdLine.hpp.func-sort-c.html @@ -33,7 +33,7 @@ - + diff --git a/Release/test_coverage/Control/UnitTest/CmdLine/CmdLine.hpp.func.html b/Release/test_coverage/Control/UnitTest/CmdLine/CmdLine.hpp.func.html index fb478c089f4b..5dd99b0e8ac8 100644 --- a/Release/test_coverage/Control/UnitTest/CmdLine/CmdLine.hpp.func.html +++ b/Release/test_coverage/Control/UnitTest/CmdLine/CmdLine.hpp.func.html @@ -33,7 +33,7 @@ - + diff --git a/Release/test_coverage/Control/UnitTest/CmdLine/CmdLine.hpp.gcov.html b/Release/test_coverage/Control/UnitTest/CmdLine/CmdLine.hpp.gcov.html index 8d9285d00d4b..086091c6adcb 100644 --- a/Release/test_coverage/Control/UnitTest/CmdLine/CmdLine.hpp.gcov.html +++ b/Release/test_coverage/Control/UnitTest/CmdLine/CmdLine.hpp.gcov.html @@ -33,7 +33,7 @@ - + diff --git a/Release/test_coverage/Control/UnitTest/CmdLine/Parser.cpp.func-sort-c.html b/Release/test_coverage/Control/UnitTest/CmdLine/Parser.cpp.func-sort-c.html index 76016e23e1a9..2f4f74b23c25 100644 --- a/Release/test_coverage/Control/UnitTest/CmdLine/Parser.cpp.func-sort-c.html +++ b/Release/test_coverage/Control/UnitTest/CmdLine/Parser.cpp.func-sort-c.html @@ -33,7 +33,7 @@ - + diff --git a/Release/test_coverage/Control/UnitTest/CmdLine/Parser.cpp.func.html b/Release/test_coverage/Control/UnitTest/CmdLine/Parser.cpp.func.html index 5412c764428f..c2a8e18b10ab 100644 --- a/Release/test_coverage/Control/UnitTest/CmdLine/Parser.cpp.func.html +++ b/Release/test_coverage/Control/UnitTest/CmdLine/Parser.cpp.func.html @@ -33,7 +33,7 @@ - + diff --git a/Release/test_coverage/Control/UnitTest/CmdLine/Parser.cpp.gcov.html b/Release/test_coverage/Control/UnitTest/CmdLine/Parser.cpp.gcov.html index 53d365ad1362..ce2ebf9ce43a 100644 --- a/Release/test_coverage/Control/UnitTest/CmdLine/Parser.cpp.gcov.html +++ b/Release/test_coverage/Control/UnitTest/CmdLine/Parser.cpp.gcov.html @@ -33,7 +33,7 @@ - + diff --git a/Release/test_coverage/Control/UnitTest/CmdLine/Parser.hpp.func-sort-c.html b/Release/test_coverage/Control/UnitTest/CmdLine/Parser.hpp.func-sort-c.html index 05b576de0375..1dab5380bd60 100644 --- a/Release/test_coverage/Control/UnitTest/CmdLine/Parser.hpp.func-sort-c.html +++ b/Release/test_coverage/Control/UnitTest/CmdLine/Parser.hpp.func-sort-c.html @@ -33,7 +33,7 @@ - + diff --git a/Release/test_coverage/Control/UnitTest/CmdLine/Parser.hpp.func.html b/Release/test_coverage/Control/UnitTest/CmdLine/Parser.hpp.func.html index 1efb58f98962..92ecb1cc2fca 100644 --- a/Release/test_coverage/Control/UnitTest/CmdLine/Parser.hpp.func.html +++ b/Release/test_coverage/Control/UnitTest/CmdLine/Parser.hpp.func.html @@ -33,7 +33,7 @@ - + diff --git a/Release/test_coverage/Control/UnitTest/CmdLine/Parser.hpp.gcov.html b/Release/test_coverage/Control/UnitTest/CmdLine/Parser.hpp.gcov.html index 55de22a99a9c..232056b07125 100644 --- a/Release/test_coverage/Control/UnitTest/CmdLine/Parser.hpp.gcov.html +++ b/Release/test_coverage/Control/UnitTest/CmdLine/Parser.hpp.gcov.html @@ -33,7 +33,7 @@ - + diff --git a/Release/test_coverage/Control/UnitTest/CmdLine/index-sort-b.html b/Release/test_coverage/Control/UnitTest/CmdLine/index-sort-b.html index 0e7bf35b89b7..a29d5572e3f8 100644 --- a/Release/test_coverage/Control/UnitTest/CmdLine/index-sort-b.html +++ b/Release/test_coverage/Control/UnitTest/CmdLine/index-sort-b.html @@ -33,7 +33,7 @@ - + diff --git a/Release/test_coverage/Control/UnitTest/CmdLine/index-sort-f.html b/Release/test_coverage/Control/UnitTest/CmdLine/index-sort-f.html index e58f2cb65cfb..9023b452bf08 100644 --- a/Release/test_coverage/Control/UnitTest/CmdLine/index-sort-f.html +++ b/Release/test_coverage/Control/UnitTest/CmdLine/index-sort-f.html @@ -33,7 +33,7 @@ - + diff --git a/Release/test_coverage/Control/UnitTest/CmdLine/index-sort-l.html b/Release/test_coverage/Control/UnitTest/CmdLine/index-sort-l.html index e753ea9066d6..89702feba1ed 100644 --- a/Release/test_coverage/Control/UnitTest/CmdLine/index-sort-l.html +++ b/Release/test_coverage/Control/UnitTest/CmdLine/index-sort-l.html @@ -33,7 +33,7 @@ - + diff --git a/Release/test_coverage/Control/UnitTest/CmdLine/index.html b/Release/test_coverage/Control/UnitTest/CmdLine/index.html index ced7778af1da..ca9cc3e7ddb1 100644 --- a/Release/test_coverage/Control/UnitTest/CmdLine/index.html +++ b/Release/test_coverage/Control/UnitTest/CmdLine/index.html @@ -33,7 +33,7 @@ - + diff --git a/Release/test_coverage/Control/index-sort-b.html b/Release/test_coverage/Control/index-sort-b.html index 9bbb96aa0edf..5f9c89ed3fd1 100644 --- a/Release/test_coverage/Control/index-sort-b.html +++ b/Release/test_coverage/Control/index-sort-b.html @@ -33,7 +33,7 @@ - + diff --git a/Release/test_coverage/Control/index-sort-f.html b/Release/test_coverage/Control/index-sort-f.html index b4d92754be0c..7878256911f8 100644 --- a/Release/test_coverage/Control/index-sort-f.html +++ b/Release/test_coverage/Control/index-sort-f.html @@ -33,7 +33,7 @@ - + @@ -105,18 +105,6 @@ - - - - - - - - - - + + + + + + + + + + - + diff --git a/Release/test_coverage/Control/index.html b/Release/test_coverage/Control/index.html index 4a166c1759b4..800219e8d73f 100644 --- a/Release/test_coverage/Control/index.html +++ b/Release/test_coverage/Control/index.html @@ -33,7 +33,7 @@ - + diff --git a/Release/test_coverage/IO/ASCMeshReader.cpp.func-sort-c.html b/Release/test_coverage/IO/ASCMeshReader.cpp.func-sort-c.html index b840befe0ca9..3af3f4f02d2a 100644 --- a/Release/test_coverage/IO/ASCMeshReader.cpp.func-sort-c.html +++ b/Release/test_coverage/IO/ASCMeshReader.cpp.func-sort-c.html @@ -33,7 +33,7 @@ - + diff --git a/Release/test_coverage/IO/ASCMeshReader.cpp.func.html b/Release/test_coverage/IO/ASCMeshReader.cpp.func.html index 79415e718a21..a227e09182d7 100644 --- a/Release/test_coverage/IO/ASCMeshReader.cpp.func.html +++ b/Release/test_coverage/IO/ASCMeshReader.cpp.func.html @@ -33,7 +33,7 @@ - + diff --git a/Release/test_coverage/IO/ASCMeshReader.cpp.gcov.html b/Release/test_coverage/IO/ASCMeshReader.cpp.gcov.html index fe95e1587380..91eb55c42fba 100644 --- a/Release/test_coverage/IO/ASCMeshReader.cpp.gcov.html +++ b/Release/test_coverage/IO/ASCMeshReader.cpp.gcov.html @@ -33,7 +33,7 @@ - + diff --git a/Release/test_coverage/IO/ASCMeshReader.hpp.func-sort-c.html b/Release/test_coverage/IO/ASCMeshReader.hpp.func-sort-c.html index 51abcfda7174..8d62f58c704c 100644 --- a/Release/test_coverage/IO/ASCMeshReader.hpp.func-sort-c.html +++ b/Release/test_coverage/IO/ASCMeshReader.hpp.func-sort-c.html @@ -33,7 +33,7 @@ - + diff --git a/Release/test_coverage/IO/ASCMeshReader.hpp.func.html b/Release/test_coverage/IO/ASCMeshReader.hpp.func.html index af9345760918..421c77122ff3 100644 --- a/Release/test_coverage/IO/ASCMeshReader.hpp.func.html +++ b/Release/test_coverage/IO/ASCMeshReader.hpp.func.html @@ -33,7 +33,7 @@ - + diff --git a/Release/test_coverage/IO/ASCMeshReader.hpp.gcov.html b/Release/test_coverage/IO/ASCMeshReader.hpp.gcov.html index be7b86779a74..6c0ad43aa479 100644 --- a/Release/test_coverage/IO/ASCMeshReader.hpp.gcov.html +++ b/Release/test_coverage/IO/ASCMeshReader.hpp.gcov.html @@ -33,7 +33,7 @@ - + diff --git a/Release/test_coverage/IO/DiagWriter.cpp.func-sort-c.html b/Release/test_coverage/IO/DiagWriter.cpp.func-sort-c.html index 9684254094c1..295c6909f56c 100644 --- a/Release/test_coverage/IO/DiagWriter.cpp.func-sort-c.html +++ b/Release/test_coverage/IO/DiagWriter.cpp.func-sort-c.html @@ -33,7 +33,7 @@ - + diff --git a/Release/test_coverage/IO/DiagWriter.cpp.func.html b/Release/test_coverage/IO/DiagWriter.cpp.func.html index 055442b2357b..1cfe23ba0435 100644 --- a/Release/test_coverage/IO/DiagWriter.cpp.func.html +++ b/Release/test_coverage/IO/DiagWriter.cpp.func.html @@ -33,7 +33,7 @@ - + diff --git a/Release/test_coverage/IO/DiagWriter.cpp.gcov.html b/Release/test_coverage/IO/DiagWriter.cpp.gcov.html index dcc50d2e25ad..7c5240f4ec9d 100644 --- a/Release/test_coverage/IO/DiagWriter.cpp.gcov.html +++ b/Release/test_coverage/IO/DiagWriter.cpp.gcov.html @@ -33,7 +33,7 @@ - + diff --git a/Release/test_coverage/IO/DiagWriter.hpp.func-sort-c.html b/Release/test_coverage/IO/DiagWriter.hpp.func-sort-c.html index 2070dfe89f8e..ccda94f56df0 100644 --- a/Release/test_coverage/IO/DiagWriter.hpp.func-sort-c.html +++ b/Release/test_coverage/IO/DiagWriter.hpp.func-sort-c.html @@ -33,7 +33,7 @@ - + diff --git a/Release/test_coverage/IO/DiagWriter.hpp.func.html b/Release/test_coverage/IO/DiagWriter.hpp.func.html index 10e380662204..d52895da9df4 100644 --- a/Release/test_coverage/IO/DiagWriter.hpp.func.html +++ b/Release/test_coverage/IO/DiagWriter.hpp.func.html @@ -33,7 +33,7 @@ - + diff --git a/Release/test_coverage/IO/DiagWriter.hpp.gcov.html b/Release/test_coverage/IO/DiagWriter.hpp.gcov.html index f738d49601ab..0aa2e20c3d13 100644 --- a/Release/test_coverage/IO/DiagWriter.hpp.gcov.html +++ b/Release/test_coverage/IO/DiagWriter.hpp.gcov.html @@ -33,7 +33,7 @@ - + diff --git a/Release/test_coverage/IO/ExodusIIMeshReader.cpp.func-sort-c.html b/Release/test_coverage/IO/ExodusIIMeshReader.cpp.func-sort-c.html index 7bd965fff8ad..1e43d089fc84 100644 --- a/Release/test_coverage/IO/ExodusIIMeshReader.cpp.func-sort-c.html +++ b/Release/test_coverage/IO/ExodusIIMeshReader.cpp.func-sort-c.html @@ -33,7 +33,7 @@ - + diff --git a/Release/test_coverage/IO/ExodusIIMeshReader.cpp.func.html b/Release/test_coverage/IO/ExodusIIMeshReader.cpp.func.html index 0ed6bbf70c1a..c971b49397a6 100644 --- a/Release/test_coverage/IO/ExodusIIMeshReader.cpp.func.html +++ b/Release/test_coverage/IO/ExodusIIMeshReader.cpp.func.html @@ -33,7 +33,7 @@ - + diff --git a/Release/test_coverage/IO/ExodusIIMeshReader.cpp.gcov.html b/Release/test_coverage/IO/ExodusIIMeshReader.cpp.gcov.html index b7e3a6610573..812381293c3d 100644 --- a/Release/test_coverage/IO/ExodusIIMeshReader.cpp.gcov.html +++ b/Release/test_coverage/IO/ExodusIIMeshReader.cpp.gcov.html @@ -33,7 +33,7 @@ - + diff --git a/Release/test_coverage/IO/ExodusIIMeshReader.hpp.func-sort-c.html b/Release/test_coverage/IO/ExodusIIMeshReader.hpp.func-sort-c.html index 634a37d4bd2b..bd20d51225b7 100644 --- a/Release/test_coverage/IO/ExodusIIMeshReader.hpp.func-sort-c.html +++ b/Release/test_coverage/IO/ExodusIIMeshReader.hpp.func-sort-c.html @@ -33,7 +33,7 @@ - + diff --git a/Release/test_coverage/IO/ExodusIIMeshReader.hpp.func.html b/Release/test_coverage/IO/ExodusIIMeshReader.hpp.func.html index f89dda439598..473824894bbd 100644 --- a/Release/test_coverage/IO/ExodusIIMeshReader.hpp.func.html +++ b/Release/test_coverage/IO/ExodusIIMeshReader.hpp.func.html @@ -33,7 +33,7 @@ - + diff --git a/Release/test_coverage/IO/ExodusIIMeshReader.hpp.gcov.html b/Release/test_coverage/IO/ExodusIIMeshReader.hpp.gcov.html index a8c145671717..03dfee57158c 100644 --- a/Release/test_coverage/IO/ExodusIIMeshReader.hpp.gcov.html +++ b/Release/test_coverage/IO/ExodusIIMeshReader.hpp.gcov.html @@ -33,7 +33,7 @@ - + diff --git a/Release/test_coverage/IO/ExodusIIMeshWriter.cpp.func-sort-c.html b/Release/test_coverage/IO/ExodusIIMeshWriter.cpp.func-sort-c.html index 60455746f2ff..5bc0df242beb 100644 --- a/Release/test_coverage/IO/ExodusIIMeshWriter.cpp.func-sort-c.html +++ b/Release/test_coverage/IO/ExodusIIMeshWriter.cpp.func-sort-c.html @@ -33,7 +33,7 @@ - + diff --git a/Release/test_coverage/IO/ExodusIIMeshWriter.cpp.func.html b/Release/test_coverage/IO/ExodusIIMeshWriter.cpp.func.html index 38b6af8ae494..fbce08860b90 100644 --- a/Release/test_coverage/IO/ExodusIIMeshWriter.cpp.func.html +++ b/Release/test_coverage/IO/ExodusIIMeshWriter.cpp.func.html @@ -33,7 +33,7 @@ - + diff --git a/Release/test_coverage/IO/ExodusIIMeshWriter.cpp.gcov.html b/Release/test_coverage/IO/ExodusIIMeshWriter.cpp.gcov.html index 0efc3667efa6..42932bfe6b8e 100644 --- a/Release/test_coverage/IO/ExodusIIMeshWriter.cpp.gcov.html +++ b/Release/test_coverage/IO/ExodusIIMeshWriter.cpp.gcov.html @@ -33,7 +33,7 @@ - + diff --git a/Release/test_coverage/IO/ExodusIIMeshWriter.hpp.func-sort-c.html b/Release/test_coverage/IO/ExodusIIMeshWriter.hpp.func-sort-c.html index 6905e6b320bc..27c16cdf1686 100644 --- a/Release/test_coverage/IO/ExodusIIMeshWriter.hpp.func-sort-c.html +++ b/Release/test_coverage/IO/ExodusIIMeshWriter.hpp.func-sort-c.html @@ -33,7 +33,7 @@ - + diff --git a/Release/test_coverage/IO/ExodusIIMeshWriter.hpp.func.html b/Release/test_coverage/IO/ExodusIIMeshWriter.hpp.func.html index cd443ca4642b..ea43897269ec 100644 --- a/Release/test_coverage/IO/ExodusIIMeshWriter.hpp.func.html +++ b/Release/test_coverage/IO/ExodusIIMeshWriter.hpp.func.html @@ -33,7 +33,7 @@ - + diff --git a/Release/test_coverage/IO/ExodusIIMeshWriter.hpp.gcov.html b/Release/test_coverage/IO/ExodusIIMeshWriter.hpp.gcov.html index 6773c82485da..977980390475 100644 --- a/Release/test_coverage/IO/ExodusIIMeshWriter.hpp.gcov.html +++ b/Release/test_coverage/IO/ExodusIIMeshWriter.hpp.gcov.html @@ -33,7 +33,7 @@ - + diff --git a/Release/test_coverage/IO/GmshMeshReader.cpp.func-sort-c.html b/Release/test_coverage/IO/GmshMeshReader.cpp.func-sort-c.html index a6258a160e8d..7334ccbe196b 100644 --- a/Release/test_coverage/IO/GmshMeshReader.cpp.func-sort-c.html +++ b/Release/test_coverage/IO/GmshMeshReader.cpp.func-sort-c.html @@ -33,7 +33,7 @@ - + diff --git a/Release/test_coverage/IO/GmshMeshReader.cpp.func.html b/Release/test_coverage/IO/GmshMeshReader.cpp.func.html index 3469272ea908..1f60ba0a6447 100644 --- a/Release/test_coverage/IO/GmshMeshReader.cpp.func.html +++ b/Release/test_coverage/IO/GmshMeshReader.cpp.func.html @@ -33,7 +33,7 @@ - + diff --git a/Release/test_coverage/IO/GmshMeshReader.cpp.gcov.html b/Release/test_coverage/IO/GmshMeshReader.cpp.gcov.html index c4abd11f9101..a63893fac141 100644 --- a/Release/test_coverage/IO/GmshMeshReader.cpp.gcov.html +++ b/Release/test_coverage/IO/GmshMeshReader.cpp.gcov.html @@ -33,7 +33,7 @@ - + diff --git a/Release/test_coverage/IO/GmshMeshReader.hpp.func-sort-c.html b/Release/test_coverage/IO/GmshMeshReader.hpp.func-sort-c.html index 3b35239275ea..85ffd2f158a6 100644 --- a/Release/test_coverage/IO/GmshMeshReader.hpp.func-sort-c.html +++ b/Release/test_coverage/IO/GmshMeshReader.hpp.func-sort-c.html @@ -33,7 +33,7 @@ - + diff --git a/Release/test_coverage/IO/GmshMeshReader.hpp.func.html b/Release/test_coverage/IO/GmshMeshReader.hpp.func.html index 3fce5ce7cd76..748c31223db4 100644 --- a/Release/test_coverage/IO/GmshMeshReader.hpp.func.html +++ b/Release/test_coverage/IO/GmshMeshReader.hpp.func.html @@ -33,7 +33,7 @@ - + diff --git a/Release/test_coverage/IO/GmshMeshReader.hpp.gcov.html b/Release/test_coverage/IO/GmshMeshReader.hpp.gcov.html index 1d9659ff0fe2..75e738d051e5 100644 --- a/Release/test_coverage/IO/GmshMeshReader.hpp.gcov.html +++ b/Release/test_coverage/IO/GmshMeshReader.hpp.gcov.html @@ -33,7 +33,7 @@ - + diff --git a/Release/test_coverage/IO/GmshMeshWriter.cpp.func-sort-c.html b/Release/test_coverage/IO/GmshMeshWriter.cpp.func-sort-c.html index f5ea362de363..669e2c533b90 100644 --- a/Release/test_coverage/IO/GmshMeshWriter.cpp.func-sort-c.html +++ b/Release/test_coverage/IO/GmshMeshWriter.cpp.func-sort-c.html @@ -33,7 +33,7 @@ - + diff --git a/Release/test_coverage/IO/GmshMeshWriter.cpp.func.html b/Release/test_coverage/IO/GmshMeshWriter.cpp.func.html index 76dcd8bd07ae..2ef6a5228ec6 100644 --- a/Release/test_coverage/IO/GmshMeshWriter.cpp.func.html +++ b/Release/test_coverage/IO/GmshMeshWriter.cpp.func.html @@ -33,7 +33,7 @@ - + diff --git a/Release/test_coverage/IO/GmshMeshWriter.cpp.gcov.html b/Release/test_coverage/IO/GmshMeshWriter.cpp.gcov.html index 7a3fec3315ed..2b2890c0b6ed 100644 --- a/Release/test_coverage/IO/GmshMeshWriter.cpp.gcov.html +++ b/Release/test_coverage/IO/GmshMeshWriter.cpp.gcov.html @@ -33,7 +33,7 @@ - + diff --git a/Release/test_coverage/IO/GmshMeshWriter.hpp.func-sort-c.html b/Release/test_coverage/IO/GmshMeshWriter.hpp.func-sort-c.html index ef7886d24a2d..f7942dd13905 100644 --- a/Release/test_coverage/IO/GmshMeshWriter.hpp.func-sort-c.html +++ b/Release/test_coverage/IO/GmshMeshWriter.hpp.func-sort-c.html @@ -33,7 +33,7 @@ - + diff --git a/Release/test_coverage/IO/GmshMeshWriter.hpp.func.html b/Release/test_coverage/IO/GmshMeshWriter.hpp.func.html index 46f9b5a8daca..65a742af06d8 100644 --- a/Release/test_coverage/IO/GmshMeshWriter.hpp.func.html +++ b/Release/test_coverage/IO/GmshMeshWriter.hpp.func.html @@ -33,7 +33,7 @@ - + diff --git a/Release/test_coverage/IO/GmshMeshWriter.hpp.gcov.html b/Release/test_coverage/IO/GmshMeshWriter.hpp.gcov.html index 0114ce34c498..ea2e432447e7 100644 --- a/Release/test_coverage/IO/GmshMeshWriter.hpp.gcov.html +++ b/Release/test_coverage/IO/GmshMeshWriter.hpp.gcov.html @@ -33,7 +33,7 @@ - + diff --git a/Release/test_coverage/IO/HyperMeshReader.cpp.func-sort-c.html b/Release/test_coverage/IO/HyperMeshReader.cpp.func-sort-c.html index 463b7fc51813..6ef577512151 100644 --- a/Release/test_coverage/IO/HyperMeshReader.cpp.func-sort-c.html +++ b/Release/test_coverage/IO/HyperMeshReader.cpp.func-sort-c.html @@ -33,7 +33,7 @@ - + diff --git a/Release/test_coverage/IO/HyperMeshReader.cpp.func.html b/Release/test_coverage/IO/HyperMeshReader.cpp.func.html index 84288d198edc..43d65d14d8d9 100644 --- a/Release/test_coverage/IO/HyperMeshReader.cpp.func.html +++ b/Release/test_coverage/IO/HyperMeshReader.cpp.func.html @@ -33,7 +33,7 @@ - + diff --git a/Release/test_coverage/IO/HyperMeshReader.cpp.gcov.html b/Release/test_coverage/IO/HyperMeshReader.cpp.gcov.html index 005fbd7a92bc..af0f383685c9 100644 --- a/Release/test_coverage/IO/HyperMeshReader.cpp.gcov.html +++ b/Release/test_coverage/IO/HyperMeshReader.cpp.gcov.html @@ -33,7 +33,7 @@ - + diff --git a/Release/test_coverage/IO/HyperMeshReader.hpp.func-sort-c.html b/Release/test_coverage/IO/HyperMeshReader.hpp.func-sort-c.html index 0fd865824581..ff3d1d805a32 100644 --- a/Release/test_coverage/IO/HyperMeshReader.hpp.func-sort-c.html +++ b/Release/test_coverage/IO/HyperMeshReader.hpp.func-sort-c.html @@ -33,7 +33,7 @@ - + diff --git a/Release/test_coverage/IO/HyperMeshReader.hpp.func.html b/Release/test_coverage/IO/HyperMeshReader.hpp.func.html index 512501d056d9..959ddb59a61c 100644 --- a/Release/test_coverage/IO/HyperMeshReader.hpp.func.html +++ b/Release/test_coverage/IO/HyperMeshReader.hpp.func.html @@ -33,7 +33,7 @@ - + diff --git a/Release/test_coverage/IO/HyperMeshReader.hpp.gcov.html b/Release/test_coverage/IO/HyperMeshReader.hpp.gcov.html index aada27e36f00..4f9d93c93572 100644 --- a/Release/test_coverage/IO/HyperMeshReader.hpp.gcov.html +++ b/Release/test_coverage/IO/HyperMeshReader.hpp.gcov.html @@ -33,7 +33,7 @@ - + diff --git a/Release/test_coverage/IO/MeshDetect.cpp.func-sort-c.html b/Release/test_coverage/IO/MeshDetect.cpp.func-sort-c.html index 4e0f80bfcc3e..58415e6e66e3 100644 --- a/Release/test_coverage/IO/MeshDetect.cpp.func-sort-c.html +++ b/Release/test_coverage/IO/MeshDetect.cpp.func-sort-c.html @@ -33,7 +33,7 @@ - + diff --git a/Release/test_coverage/IO/MeshDetect.cpp.func.html b/Release/test_coverage/IO/MeshDetect.cpp.func.html index e78a47f56def..a496d0cd881d 100644 --- a/Release/test_coverage/IO/MeshDetect.cpp.func.html +++ b/Release/test_coverage/IO/MeshDetect.cpp.func.html @@ -33,7 +33,7 @@ - + diff --git a/Release/test_coverage/IO/MeshDetect.cpp.gcov.html b/Release/test_coverage/IO/MeshDetect.cpp.gcov.html index 4726106b23eb..d2837dc525d8 100644 --- a/Release/test_coverage/IO/MeshDetect.cpp.gcov.html +++ b/Release/test_coverage/IO/MeshDetect.cpp.gcov.html @@ -33,7 +33,7 @@ - + diff --git a/Release/test_coverage/IO/MeshFactory.cpp.func-sort-c.html b/Release/test_coverage/IO/MeshFactory.cpp.func-sort-c.html index 4ea521e394fd..02ea7b14e0fd 100644 --- a/Release/test_coverage/IO/MeshFactory.cpp.func-sort-c.html +++ b/Release/test_coverage/IO/MeshFactory.cpp.func-sort-c.html @@ -33,7 +33,7 @@ - + diff --git a/Release/test_coverage/IO/MeshFactory.cpp.func.html b/Release/test_coverage/IO/MeshFactory.cpp.func.html index 7709ed90f72d..da588f5744ed 100644 --- a/Release/test_coverage/IO/MeshFactory.cpp.func.html +++ b/Release/test_coverage/IO/MeshFactory.cpp.func.html @@ -33,7 +33,7 @@ - + diff --git a/Release/test_coverage/IO/MeshFactory.cpp.gcov.html b/Release/test_coverage/IO/MeshFactory.cpp.gcov.html index 11118061cfb8..02cf4d5ca8ae 100644 --- a/Release/test_coverage/IO/MeshFactory.cpp.gcov.html +++ b/Release/test_coverage/IO/MeshFactory.cpp.gcov.html @@ -33,7 +33,7 @@ - + diff --git a/Release/test_coverage/IO/MeshReader.hpp.func-sort-c.html b/Release/test_coverage/IO/MeshReader.hpp.func-sort-c.html index 8262ed640c7a..fdeefbc69726 100644 --- a/Release/test_coverage/IO/MeshReader.hpp.func-sort-c.html +++ b/Release/test_coverage/IO/MeshReader.hpp.func-sort-c.html @@ -33,7 +33,7 @@ - + diff --git a/Release/test_coverage/IO/MeshReader.hpp.func.html b/Release/test_coverage/IO/MeshReader.hpp.func.html index 410783cfe84d..ed31646d126f 100644 --- a/Release/test_coverage/IO/MeshReader.hpp.func.html +++ b/Release/test_coverage/IO/MeshReader.hpp.func.html @@ -33,7 +33,7 @@ - + diff --git a/Release/test_coverage/IO/MeshReader.hpp.gcov.html b/Release/test_coverage/IO/MeshReader.hpp.gcov.html index da4c20a819b8..3a4f46009e33 100644 --- a/Release/test_coverage/IO/MeshReader.hpp.gcov.html +++ b/Release/test_coverage/IO/MeshReader.hpp.gcov.html @@ -33,7 +33,7 @@ - + diff --git a/Release/test_coverage/IO/MeshWriter.cpp.func-sort-c.html b/Release/test_coverage/IO/MeshWriter.cpp.func-sort-c.html index eb4bef509f15..1157683697bf 100644 --- a/Release/test_coverage/IO/MeshWriter.cpp.func-sort-c.html +++ b/Release/test_coverage/IO/MeshWriter.cpp.func-sort-c.html @@ -33,7 +33,7 @@ - + diff --git a/Release/test_coverage/IO/MeshWriter.cpp.func.html b/Release/test_coverage/IO/MeshWriter.cpp.func.html index 10ead95351f9..19a4a0ccecae 100644 --- a/Release/test_coverage/IO/MeshWriter.cpp.func.html +++ b/Release/test_coverage/IO/MeshWriter.cpp.func.html @@ -33,7 +33,7 @@ - + diff --git a/Release/test_coverage/IO/MeshWriter.cpp.gcov.html b/Release/test_coverage/IO/MeshWriter.cpp.gcov.html index f45b7670fac9..bf73835302eb 100644 --- a/Release/test_coverage/IO/MeshWriter.cpp.gcov.html +++ b/Release/test_coverage/IO/MeshWriter.cpp.gcov.html @@ -33,7 +33,7 @@ - + diff --git a/Release/test_coverage/IO/MeshWriter.hpp.func-sort-c.html b/Release/test_coverage/IO/MeshWriter.hpp.func-sort-c.html index 5319bce6364e..911c597f4724 100644 --- a/Release/test_coverage/IO/MeshWriter.hpp.func-sort-c.html +++ b/Release/test_coverage/IO/MeshWriter.hpp.func-sort-c.html @@ -33,7 +33,7 @@ - + diff --git a/Release/test_coverage/IO/MeshWriter.hpp.func.html b/Release/test_coverage/IO/MeshWriter.hpp.func.html index 55654ef8306f..360a9287bd79 100644 --- a/Release/test_coverage/IO/MeshWriter.hpp.func.html +++ b/Release/test_coverage/IO/MeshWriter.hpp.func.html @@ -33,7 +33,7 @@ - + diff --git a/Release/test_coverage/IO/MeshWriter.hpp.gcov.html b/Release/test_coverage/IO/MeshWriter.hpp.gcov.html index d27ba54a66d5..e390de94d8a5 100644 --- a/Release/test_coverage/IO/MeshWriter.hpp.gcov.html +++ b/Release/test_coverage/IO/MeshWriter.hpp.gcov.html @@ -33,7 +33,7 @@ - + diff --git a/Release/test_coverage/IO/NetgenMeshReader.cpp.func-sort-c.html b/Release/test_coverage/IO/NetgenMeshReader.cpp.func-sort-c.html index 8712c3d27bd6..960e7be4dfaa 100644 --- a/Release/test_coverage/IO/NetgenMeshReader.cpp.func-sort-c.html +++ b/Release/test_coverage/IO/NetgenMeshReader.cpp.func-sort-c.html @@ -33,7 +33,7 @@ - + diff --git a/Release/test_coverage/IO/NetgenMeshReader.cpp.func.html b/Release/test_coverage/IO/NetgenMeshReader.cpp.func.html index 448edf4f8dc2..9069f1058f2e 100644 --- a/Release/test_coverage/IO/NetgenMeshReader.cpp.func.html +++ b/Release/test_coverage/IO/NetgenMeshReader.cpp.func.html @@ -33,7 +33,7 @@ - + diff --git a/Release/test_coverage/IO/NetgenMeshReader.cpp.gcov.html b/Release/test_coverage/IO/NetgenMeshReader.cpp.gcov.html index 1c571893decf..34a7119f6d4e 100644 --- a/Release/test_coverage/IO/NetgenMeshReader.cpp.gcov.html +++ b/Release/test_coverage/IO/NetgenMeshReader.cpp.gcov.html @@ -33,7 +33,7 @@ - + diff --git a/Release/test_coverage/IO/NetgenMeshReader.hpp.func-sort-c.html b/Release/test_coverage/IO/NetgenMeshReader.hpp.func-sort-c.html index 65bf1a913259..6e400c40a1ea 100644 --- a/Release/test_coverage/IO/NetgenMeshReader.hpp.func-sort-c.html +++ b/Release/test_coverage/IO/NetgenMeshReader.hpp.func-sort-c.html @@ -33,7 +33,7 @@ - + diff --git a/Release/test_coverage/IO/NetgenMeshReader.hpp.func.html b/Release/test_coverage/IO/NetgenMeshReader.hpp.func.html index b862a7779f29..da3a1f0f5c82 100644 --- a/Release/test_coverage/IO/NetgenMeshReader.hpp.func.html +++ b/Release/test_coverage/IO/NetgenMeshReader.hpp.func.html @@ -33,7 +33,7 @@ - + diff --git a/Release/test_coverage/IO/NetgenMeshReader.hpp.gcov.html b/Release/test_coverage/IO/NetgenMeshReader.hpp.gcov.html index b6c3bcdea8f4..fd8cfc4a0390 100644 --- a/Release/test_coverage/IO/NetgenMeshReader.hpp.gcov.html +++ b/Release/test_coverage/IO/NetgenMeshReader.hpp.gcov.html @@ -33,7 +33,7 @@ - + diff --git a/Release/test_coverage/IO/NetgenMeshWriter.cpp.func-sort-c.html b/Release/test_coverage/IO/NetgenMeshWriter.cpp.func-sort-c.html index 8e5e7f1c8773..a3e739c304b1 100644 --- a/Release/test_coverage/IO/NetgenMeshWriter.cpp.func-sort-c.html +++ b/Release/test_coverage/IO/NetgenMeshWriter.cpp.func-sort-c.html @@ -33,7 +33,7 @@ - + diff --git a/Release/test_coverage/IO/NetgenMeshWriter.cpp.func.html b/Release/test_coverage/IO/NetgenMeshWriter.cpp.func.html index a962c0992bc3..3aa6a44382d7 100644 --- a/Release/test_coverage/IO/NetgenMeshWriter.cpp.func.html +++ b/Release/test_coverage/IO/NetgenMeshWriter.cpp.func.html @@ -33,7 +33,7 @@ - + diff --git a/Release/test_coverage/IO/NetgenMeshWriter.cpp.gcov.html b/Release/test_coverage/IO/NetgenMeshWriter.cpp.gcov.html index 2e558bfc09ca..d439bcc1c61e 100644 --- a/Release/test_coverage/IO/NetgenMeshWriter.cpp.gcov.html +++ b/Release/test_coverage/IO/NetgenMeshWriter.cpp.gcov.html @@ -33,7 +33,7 @@ - + diff --git a/Release/test_coverage/IO/NetgenMeshWriter.hpp.func-sort-c.html b/Release/test_coverage/IO/NetgenMeshWriter.hpp.func-sort-c.html index 533bca2b521f..ea7ac887c1fe 100644 --- a/Release/test_coverage/IO/NetgenMeshWriter.hpp.func-sort-c.html +++ b/Release/test_coverage/IO/NetgenMeshWriter.hpp.func-sort-c.html @@ -33,7 +33,7 @@ - + diff --git a/Release/test_coverage/IO/NetgenMeshWriter.hpp.func.html b/Release/test_coverage/IO/NetgenMeshWriter.hpp.func.html index ababaeace804..89520725e003 100644 --- a/Release/test_coverage/IO/NetgenMeshWriter.hpp.func.html +++ b/Release/test_coverage/IO/NetgenMeshWriter.hpp.func.html @@ -33,7 +33,7 @@ - + diff --git a/Release/test_coverage/IO/NetgenMeshWriter.hpp.gcov.html b/Release/test_coverage/IO/NetgenMeshWriter.hpp.gcov.html index a27258189f98..c3100510c633 100644 --- a/Release/test_coverage/IO/NetgenMeshWriter.hpp.gcov.html +++ b/Release/test_coverage/IO/NetgenMeshWriter.hpp.gcov.html @@ -33,7 +33,7 @@ - + diff --git a/Release/test_coverage/IO/PDFWriter.cpp.func-sort-c.html b/Release/test_coverage/IO/PDFWriter.cpp.func-sort-c.html index 84c9af1de9d8..9c240782661a 100644 --- a/Release/test_coverage/IO/PDFWriter.cpp.func-sort-c.html +++ b/Release/test_coverage/IO/PDFWriter.cpp.func-sort-c.html @@ -33,7 +33,7 @@ - + diff --git a/Release/test_coverage/IO/PDFWriter.cpp.func.html b/Release/test_coverage/IO/PDFWriter.cpp.func.html index 48cdcf6786c0..a6a43e66d5bc 100644 --- a/Release/test_coverage/IO/PDFWriter.cpp.func.html +++ b/Release/test_coverage/IO/PDFWriter.cpp.func.html @@ -33,7 +33,7 @@ - + diff --git a/Release/test_coverage/IO/PDFWriter.cpp.gcov.html b/Release/test_coverage/IO/PDFWriter.cpp.gcov.html index f430ebdc2e6c..841815ef4d01 100644 --- a/Release/test_coverage/IO/PDFWriter.cpp.gcov.html +++ b/Release/test_coverage/IO/PDFWriter.cpp.gcov.html @@ -33,7 +33,7 @@ - + diff --git a/Release/test_coverage/IO/PDFWriter.hpp.func-sort-c.html b/Release/test_coverage/IO/PDFWriter.hpp.func-sort-c.html index 57068b414156..df5160f34499 100644 --- a/Release/test_coverage/IO/PDFWriter.hpp.func-sort-c.html +++ b/Release/test_coverage/IO/PDFWriter.hpp.func-sort-c.html @@ -33,7 +33,7 @@ - + diff --git a/Release/test_coverage/IO/PDFWriter.hpp.func.html b/Release/test_coverage/IO/PDFWriter.hpp.func.html index 5d7494f41521..a869caf06e66 100644 --- a/Release/test_coverage/IO/PDFWriter.hpp.func.html +++ b/Release/test_coverage/IO/PDFWriter.hpp.func.html @@ -33,7 +33,7 @@ - + diff --git a/Release/test_coverage/IO/PDFWriter.hpp.gcov.html b/Release/test_coverage/IO/PDFWriter.hpp.gcov.html index 367e5ad8fca4..c2dc7f6e6c6c 100644 --- a/Release/test_coverage/IO/PDFWriter.hpp.gcov.html +++ b/Release/test_coverage/IO/PDFWriter.hpp.gcov.html @@ -33,7 +33,7 @@ - + diff --git a/Release/test_coverage/IO/RDGFLOMeshReader.cpp.func-sort-c.html b/Release/test_coverage/IO/RDGFLOMeshReader.cpp.func-sort-c.html index feefd927dfe8..2f80ab02e694 100644 --- a/Release/test_coverage/IO/RDGFLOMeshReader.cpp.func-sort-c.html +++ b/Release/test_coverage/IO/RDGFLOMeshReader.cpp.func-sort-c.html @@ -33,7 +33,7 @@ - + diff --git a/Release/test_coverage/IO/RDGFLOMeshReader.cpp.func.html b/Release/test_coverage/IO/RDGFLOMeshReader.cpp.func.html index 5c283e8d33a3..7f75211f147d 100644 --- a/Release/test_coverage/IO/RDGFLOMeshReader.cpp.func.html +++ b/Release/test_coverage/IO/RDGFLOMeshReader.cpp.func.html @@ -33,7 +33,7 @@ - + diff --git a/Release/test_coverage/IO/RDGFLOMeshReader.cpp.gcov.html b/Release/test_coverage/IO/RDGFLOMeshReader.cpp.gcov.html index 57a811dfe5ea..42d4251c77a3 100644 --- a/Release/test_coverage/IO/RDGFLOMeshReader.cpp.gcov.html +++ b/Release/test_coverage/IO/RDGFLOMeshReader.cpp.gcov.html @@ -33,7 +33,7 @@ - + diff --git a/Release/test_coverage/IO/RDGFLOMeshReader.hpp.func-sort-c.html b/Release/test_coverage/IO/RDGFLOMeshReader.hpp.func-sort-c.html index b9816cb0bb4a..8af92e1b8fec 100644 --- a/Release/test_coverage/IO/RDGFLOMeshReader.hpp.func-sort-c.html +++ b/Release/test_coverage/IO/RDGFLOMeshReader.hpp.func-sort-c.html @@ -33,7 +33,7 @@ - + diff --git a/Release/test_coverage/IO/RDGFLOMeshReader.hpp.func.html b/Release/test_coverage/IO/RDGFLOMeshReader.hpp.func.html index e3b0eb7f9388..feb9d59acacf 100644 --- a/Release/test_coverage/IO/RDGFLOMeshReader.hpp.func.html +++ b/Release/test_coverage/IO/RDGFLOMeshReader.hpp.func.html @@ -33,7 +33,7 @@ - + diff --git a/Release/test_coverage/IO/RDGFLOMeshReader.hpp.gcov.html b/Release/test_coverage/IO/RDGFLOMeshReader.hpp.gcov.html index 3a70afa784f2..2c2c436a401f 100644 --- a/Release/test_coverage/IO/RDGFLOMeshReader.hpp.gcov.html +++ b/Release/test_coverage/IO/RDGFLOMeshReader.hpp.gcov.html @@ -33,7 +33,7 @@ - + diff --git a/Release/test_coverage/IO/STLTxtMeshReader.cpp.func-sort-c.html b/Release/test_coverage/IO/STLTxtMeshReader.cpp.func-sort-c.html index 6ff622cf2200..4227f42f9790 100644 --- a/Release/test_coverage/IO/STLTxtMeshReader.cpp.func-sort-c.html +++ b/Release/test_coverage/IO/STLTxtMeshReader.cpp.func-sort-c.html @@ -33,7 +33,7 @@ - + diff --git a/Release/test_coverage/IO/STLTxtMeshReader.cpp.func.html b/Release/test_coverage/IO/STLTxtMeshReader.cpp.func.html index 51d98df08658..0efa01c15eda 100644 --- a/Release/test_coverage/IO/STLTxtMeshReader.cpp.func.html +++ b/Release/test_coverage/IO/STLTxtMeshReader.cpp.func.html @@ -33,7 +33,7 @@ - + diff --git a/Release/test_coverage/IO/STLTxtMeshReader.cpp.gcov.html b/Release/test_coverage/IO/STLTxtMeshReader.cpp.gcov.html index 99c8226c178b..ad80fdc3efc2 100644 --- a/Release/test_coverage/IO/STLTxtMeshReader.cpp.gcov.html +++ b/Release/test_coverage/IO/STLTxtMeshReader.cpp.gcov.html @@ -33,7 +33,7 @@ - + diff --git a/Release/test_coverage/IO/STLTxtMeshReader.hpp.func-sort-c.html b/Release/test_coverage/IO/STLTxtMeshReader.hpp.func-sort-c.html index 76721ecc3426..4a09b1d9ac3d 100644 --- a/Release/test_coverage/IO/STLTxtMeshReader.hpp.func-sort-c.html +++ b/Release/test_coverage/IO/STLTxtMeshReader.hpp.func-sort-c.html @@ -33,7 +33,7 @@ - + diff --git a/Release/test_coverage/IO/STLTxtMeshReader.hpp.func.html b/Release/test_coverage/IO/STLTxtMeshReader.hpp.func.html index 5e6486347f9c..0045fa648e66 100644 --- a/Release/test_coverage/IO/STLTxtMeshReader.hpp.func.html +++ b/Release/test_coverage/IO/STLTxtMeshReader.hpp.func.html @@ -33,7 +33,7 @@ - + diff --git a/Release/test_coverage/IO/STLTxtMeshReader.hpp.gcov.html b/Release/test_coverage/IO/STLTxtMeshReader.hpp.gcov.html index d923f638bdb0..bc17a6ffccc8 100644 --- a/Release/test_coverage/IO/STLTxtMeshReader.hpp.gcov.html +++ b/Release/test_coverage/IO/STLTxtMeshReader.hpp.gcov.html @@ -33,7 +33,7 @@ - + diff --git a/Release/test_coverage/IO/TxtStatWriter.cpp.func-sort-c.html b/Release/test_coverage/IO/TxtStatWriter.cpp.func-sort-c.html index 575474849025..971bf04b2d84 100644 --- a/Release/test_coverage/IO/TxtStatWriter.cpp.func-sort-c.html +++ b/Release/test_coverage/IO/TxtStatWriter.cpp.func-sort-c.html @@ -33,7 +33,7 @@ - + diff --git a/Release/test_coverage/IO/TxtStatWriter.cpp.func.html b/Release/test_coverage/IO/TxtStatWriter.cpp.func.html index c04117e3a2c9..a648119c7ae1 100644 --- a/Release/test_coverage/IO/TxtStatWriter.cpp.func.html +++ b/Release/test_coverage/IO/TxtStatWriter.cpp.func.html @@ -33,7 +33,7 @@ - + diff --git a/Release/test_coverage/IO/TxtStatWriter.cpp.gcov.html b/Release/test_coverage/IO/TxtStatWriter.cpp.gcov.html index 6db401d69daf..4868b791d1f7 100644 --- a/Release/test_coverage/IO/TxtStatWriter.cpp.gcov.html +++ b/Release/test_coverage/IO/TxtStatWriter.cpp.gcov.html @@ -33,7 +33,7 @@ - + diff --git a/Release/test_coverage/IO/UGRIDMeshReader.cpp.func-sort-c.html b/Release/test_coverage/IO/UGRIDMeshReader.cpp.func-sort-c.html index 49e686d85358..4dcf88f78100 100644 --- a/Release/test_coverage/IO/UGRIDMeshReader.cpp.func-sort-c.html +++ b/Release/test_coverage/IO/UGRIDMeshReader.cpp.func-sort-c.html @@ -33,7 +33,7 @@ - + diff --git a/Release/test_coverage/IO/UGRIDMeshReader.cpp.func.html b/Release/test_coverage/IO/UGRIDMeshReader.cpp.func.html index 4dea826a0f9b..fb18efc491e5 100644 --- a/Release/test_coverage/IO/UGRIDMeshReader.cpp.func.html +++ b/Release/test_coverage/IO/UGRIDMeshReader.cpp.func.html @@ -33,7 +33,7 @@ - + diff --git a/Release/test_coverage/IO/UGRIDMeshReader.cpp.gcov.html b/Release/test_coverage/IO/UGRIDMeshReader.cpp.gcov.html index 5fc27756f006..38a1c186dfa8 100644 --- a/Release/test_coverage/IO/UGRIDMeshReader.cpp.gcov.html +++ b/Release/test_coverage/IO/UGRIDMeshReader.cpp.gcov.html @@ -33,7 +33,7 @@ - + diff --git a/Release/test_coverage/IO/UGRIDMeshReader.hpp.func-sort-c.html b/Release/test_coverage/IO/UGRIDMeshReader.hpp.func-sort-c.html index e09cd5d1a514..e40b36302fed 100644 --- a/Release/test_coverage/IO/UGRIDMeshReader.hpp.func-sort-c.html +++ b/Release/test_coverage/IO/UGRIDMeshReader.hpp.func-sort-c.html @@ -33,7 +33,7 @@ - + diff --git a/Release/test_coverage/IO/UGRIDMeshReader.hpp.func.html b/Release/test_coverage/IO/UGRIDMeshReader.hpp.func.html index 083cfbcee461..70f09da237be 100644 --- a/Release/test_coverage/IO/UGRIDMeshReader.hpp.func.html +++ b/Release/test_coverage/IO/UGRIDMeshReader.hpp.func.html @@ -33,7 +33,7 @@ - + diff --git a/Release/test_coverage/IO/UGRIDMeshReader.hpp.gcov.html b/Release/test_coverage/IO/UGRIDMeshReader.hpp.gcov.html index 8794f0fa0b21..9c67f246fc6c 100644 --- a/Release/test_coverage/IO/UGRIDMeshReader.hpp.gcov.html +++ b/Release/test_coverage/IO/UGRIDMeshReader.hpp.gcov.html @@ -33,7 +33,7 @@ - + diff --git a/Release/test_coverage/IO/index-sort-b.html b/Release/test_coverage/IO/index-sort-b.html index 71ac32aab17f..22a7500a40ec 100644 --- a/Release/test_coverage/IO/index-sort-b.html +++ b/Release/test_coverage/IO/index-sort-b.html @@ -33,7 +33,7 @@ - + @@ -334,7 +334,7 @@ - + @@ -346,19 +346,19 @@ - + - + - + @@ -370,36 +370,36 @@ - + - + - + - + - + - + diff --git a/Release/test_coverage/IO/index-sort-f.html b/Release/test_coverage/IO/index-sort-f.html index 0381ff22699f..9e9b35efab0e 100644 --- a/Release/test_coverage/IO/index-sort-f.html +++ b/Release/test_coverage/IO/index-sort-f.html @@ -33,7 +33,7 @@ - + @@ -94,28 +94,28 @@ - + - + - + - + - + - + @@ -190,43 +190,43 @@ - + - - - + + + - + - + - + - + - + - + @@ -238,48 +238,48 @@ - + - + + + - - - + - + - + - + - + - + - + @@ -309,6 +309,18 @@ + + + + + + + + + + - + + + - - - - - + + + @@ -370,76 +382,64 @@ - - - - - - - - - - - + - + - - + + - + - + - - + + - + - + - - + + - + - + - - + + - + - + - - + + diff --git a/Release/test_coverage/IO/index-sort-l.html b/Release/test_coverage/IO/index-sort-l.html index 7b7e66e25144..795f32138328 100644 --- a/Release/test_coverage/IO/index-sort-l.html +++ b/Release/test_coverage/IO/index-sort-l.html @@ -33,7 +33,7 @@ - + @@ -226,7 +226,7 @@ - + @@ -234,8 +234,8 @@ - - + + @@ -250,7 +250,7 @@ - + @@ -258,8 +258,8 @@ - - + + @@ -286,7 +286,7 @@ - + @@ -298,7 +298,7 @@ - + @@ -310,7 +310,7 @@ - + @@ -322,7 +322,7 @@ - + @@ -334,28 +334,28 @@ - + - - - + + + - + - - - + + + diff --git a/Release/test_coverage/IO/index.html b/Release/test_coverage/IO/index.html index 478da9b891d3..9eb441a5a361 100644 --- a/Release/test_coverage/IO/index.html +++ b/Release/test_coverage/IO/index.html @@ -33,7 +33,7 @@ - + diff --git a/Release/test_coverage/Inciter/ALE.cpp.func-sort-c.html b/Release/test_coverage/Inciter/ALE.cpp.func-sort-c.html index 7223e562d4f0..2417bea2b0eb 100644 --- a/Release/test_coverage/Inciter/ALE.cpp.func-sort-c.html +++ b/Release/test_coverage/Inciter/ALE.cpp.func-sort-c.html @@ -33,7 +33,7 @@ - + diff --git a/Release/test_coverage/Inciter/ALE.cpp.func.html b/Release/test_coverage/Inciter/ALE.cpp.func.html index e52889c7c8eb..4038ad2fa733 100644 --- a/Release/test_coverage/Inciter/ALE.cpp.func.html +++ b/Release/test_coverage/Inciter/ALE.cpp.func.html @@ -33,7 +33,7 @@ - + diff --git a/Release/test_coverage/Inciter/ALE.cpp.gcov.html b/Release/test_coverage/Inciter/ALE.cpp.gcov.html index 1c5c708cabb1..2d238ee34996 100644 --- a/Release/test_coverage/Inciter/ALE.cpp.gcov.html +++ b/Release/test_coverage/Inciter/ALE.cpp.gcov.html @@ -33,7 +33,7 @@ - + @@ -843,7 +843,7 @@ 742 : : 743 : : // max sound speed across nodes of element 744 : 5105910 : tk::real c = 1.0e-3; // floor on sound speed - 745 [ + + ][ + + ]: 25529550 : for (std::size_t a=0; a<4; ++a) c = std::max( c, m_soundspeed[N[a]] ); + 745 [ + + ][ + + ]: 25529550 : for (std::size_t a=0; a<4; ++a) c = std::max( c, m_soundspeed[N[a]] ); 746 : : 747 : : // mesh force in nodes 748 : 5105910 : auto V = J/6.0; diff --git a/Release/test_coverage/Inciter/ALE.hpp.func-sort-c.html b/Release/test_coverage/Inciter/ALE.hpp.func-sort-c.html index b65850d01830..93196909dda3 100644 --- a/Release/test_coverage/Inciter/ALE.hpp.func-sort-c.html +++ b/Release/test_coverage/Inciter/ALE.hpp.func-sort-c.html @@ -33,7 +33,7 @@ - + @@ -73,11 +73,11 @@ - + - +
   1
-   2
-   3
-   4
-   5
-   6
-   7
-   8
-   9
-  10
-  11
-  12
-  13
-  14
-  15
-  16
-  17
-  18
-  19
-  20
-  21
-  22
-  23
-  24
-  25
-  26
-  27
-  28
-  29
-  30
-  31
-  32
-  33
-  34
-  35
-  36
-  37
-  38
-  39
-  40
-  41
-  42
-  43
-  44
-  45
-  46
-  47
-  48
-  49
-  50
-  51
-  52
-  53
-  54
-  55
-  56
-  57
-  58
-  59
-  60
-  61
-  62
-  63
-  64
-  65
-  66
-  67
-  68
-  69
-  70
-  71
-  72
-  73
-  74
-  75
-  76
-  77
-  78
-  79
-  80
-  81
-  82
-  83
-  84
-  85
-  86
-  87
-  88
-  89
-  90
-  91
-  92
-  93
-  94
-  95
-  96
-  97
-  98
-  99
- 100
- 101
- 102
- 103
- 104
- 105
- 106
- 107
- 108
- 109
- 110
- 111
- 112
- 113
- 114
- 115
- 116
- 117
- 118
- 119
- 120
- 121
- 122
- 123
- 124
- 125
- 126
- 127
- 128
- 129
- 130
- 131
- 132
- 133
- 134
- 135
- 136
- 137
- 138
- 139
- 140
- 141
- 142
- 143
- 144
- 145
- 146
- 147
- 148
- 149
- 150
- 151
- 152
- 153
- 154
- 155
- 156
- 157
- 158
- 159
- 160
- 161
- 162
- 163
- 164
- 165
- 166
- 167
- 168
- 169
- 170
- 171
- 172
- 173
- 174
- 175
- 176
- 177
- 178
- 179
- 180
- 181
- 182
- 183
- 184
- 185
- 186
- 187
- 188
- 189
- 190
- 191
- 192
- 193
- 194
- 195
- 196
- 197
- 198
- 199
- 200
- 201
- 202
- 203
- 204
- 205
- 206
- 207
- 208
- 209
- 210
- 211
- 212
- 213
- 214
- 215
- 216
- 217
- 218
- 219
- 220
- 221
- 222
- 223
- 224
- 225
- 226
- 227
- 228
- 229
- 230
- 231
- 232
- 233
- 234
- 235
- 236
- 237
- 238
- 239
- 240
- 241
- 242
- 243
- 244
- 245
- 246
- 247
- 248
- 249
- 250
- 251
- 252
- 253
- 254
- 255
- 256
- 257
- 258
- 259
- 260
- 261
- 262
- 263
- 264
- 265
- 266
- 267
- 268
- 269
- 270
- 271
- 272
- 273
- 274
- 275
- 276
- 277
- 278
- 279
- 280
- 281
- 282
- 283
- 284
- 285
- 286
- 287
- 288
- 289
- 290
- 291
- 292
- 293
- 294
- 295
- 296
- 297
- 298
- 299
- 300
- 301
- 302
- 303
- 304
- 305
- 306
- 307
- 308
- 309
- 310
- 311
- 312
- 313
- 314
- 315
- 316
- 317
- 318
- 319
- 320
- 321
- 322
- 323
- 324
- 325
- 326
- 327
- 328
- 329
- 330
- 331
- 332
- 333
- 334
- 335
- 336
- 337
- 338
- 339
- 340
- 341
- 342
- 343
- 344
- 345
- 346
- 347
- 348
- 349
- 350
- 351
- 352
- 353
- 354
- 355
- 356
- 357
- 358
- 359
- 360
- 361
- 362
- 363
- 364
- 365
- 366
- 367
- 368
- 369
- 370
- 371
- 372
- 373
- 374
- 375
- 376
- 377
- 378
- 379
- 380
- 381
- 382
- 383
- 384
- 385
- 386
- 387
- 388
- 389
- 390
- 391
- 392
- 393
- 394
- 395
- 396
- 397
- 398
- 399
- 400
- 401
- 402
- 403
- 404
- 405
- 406
- 407
- 408
- 409
- 410
- 411
- 412
- 413
- 414
- 415
- 416
- 417
- 418
- 419
- 420
- 421
- 422
- 423
- 424
- 425
- 426
- 427
- 428
- 429
- 430
- 431
- 432
- 433
- 434
- 435
- 436
- 437
- 438
- 439
- 440
- 441
- 442
- 443
- 444
- 445
- 446
- 447
- 448
- 449
- 450
- 451
- 452
- 453
- 454
- 455
- 456
- 457
- 458
- 459
- 460
- 461
- 462
- 463
- 464
- 465
- 466
- 467
- 468
- 469
- 470
- 471
- 472
- 473
- 474
- 475
- 476
- 477
- 478
- 479
- 480
- 481
- 482
- 483
- 484
- 485
- 486
- 487
- 488
- 489
- 490
- 491
- 492
- 493
- 494
- 495
- 496
- 497
- 498
- 499
- 500
- 501
- 502
- 503
- 504
- 505
- 506
- 507
- 508
- 509
- 510
- 511
- 512
- 513
- 514
- 515
- 516
- 517
- 518
- 519
- 520
- 521
- 522
- 523
- 524
- 525
- 526
- 527
- 528
- 529
- 530
- 531
- 532
- 533
- 534
- 535
- 536
- 537
- 538
- 539
- 540
- 541
- 542
- 543
- 544
- 545
- 546
- 547
- 548
- 549
- 550
- 551
- 552
- 553
- 554
- 555
- 556
- 557
- 558
- 559
- 560
- 561
- 562
- 563
- 564
- 565
- 566
- 567
- 568
- 569
- 570
- 571
- 572
- 573
- 574
- 575
- 576
- 577
- 578
- 579
- 580
- 581
- 582
- 583
- 584
- 585
- 586
- 587
- 588
- 589
- 590
- 591
- 592
- 593
- 594
- 595
- 596
- 597
- 598
- 599
- 600
- 601
- 602
- 603
- 604
- 605
- 606
- 607
- 608
- 609
- 610
- 611
- 612
- 613
- 614
- 615
- 616
- 617
- 618
- 619
- 620
- 621
- 622
- 623
- 624
- 625
- 626
- 627
- 628
- 629
- 630
- 631
- 632
- 633
- 634
- 635
- 636
- 637
- 638
- 639
- 640
- 641
- 642
- 643
- 644
- 645
- 646
- 647
- 648
- 649
- 650
- 651
- 652
- 653
- 654
- 655
- 656
- 657
- 658
- 659
- 660
- 661
- 662
- 663
- 664
- 665
- 666
- 667
- 668
- 669
- 670
- 671
- 672
- 673
- 674
- 675
- 676
- 677
- 678
- 679
- 680
- 681
- 682
- 683
- 684
- 685
- 686
- 687
- 688
- 689
- 690
- 691
- 692
- 693
- 694
- 695
- 696
- 697
- 698
- 699
- 700
- 701
- 702
- 703
- 704
- 705
- 706
- 707
- 708
- 709
- 710
- 711
- 712
- 713
- 714
- 715
- 716
- 717
- 718
- 719
- 720
- 721
- 722
- 723
- 724
- 725
- 726
- 727
- 728
- 729
- 730
- 731
- 732
- 733
- 734
- 735
- 736
- 737
- 738
- 739
- 740
- 741
- 742
- 743
- 744
- 745
- 746
- 747
- 748
- 749
- 750
- 751
- 752
- 753
- 754
- 755
- 756
- 757
- 758
- 759
- 760
- 761
- 762
- 763
- 764
- 765
- 766
- 767
- 768
- 769
- 770
- 771
- 772
- 773
- 774
- 775
- 776
- 777
- 778
- 779
- 780
- 781
- 782
- 783
- 784
- 785
- 786
- 787
- 788
- 789
- 790
- 791
- 792
- 793
- 794
- 795
- 796
- 797
- 798
- 799
- 800
- 801
- 802
- 803
- 804
- 805
- 806
- 807
- 808
- 809
- 810
- 811
- 812
- 813
- 814
- 815
- 816
- 817
- 818
- 819
- 820
- 821
- 822
- 823
- 824
- 825
- 826
- 827
- 828
- 829
- 830
- 831
- 832
- 833
- 834
- 835
- 836
- 837
- 838
- 839
- 840
- 841
- 842
- 843
- 844
- 845
- 846
- 847
- 848
- 849
- 850
- 851
- 852
- 853
- 854
- 855
- 856
- 857
- 858
- 859
- 860
- 861
- 862
- 863
- 864
- 865
- 866
- 867
- 868
- 869
- 870
- 871
- 872
- 873
- 874
- 875
- 876
- 877
- 878
- 879
- 880
- 881
- 882
- 883
- 884
- 885
- 886
- 887
- 888
- 889
- 890
- 891
- 892
- 893
- 894
- 895
- 896
- 897
- 898
- 899
- 900
- 901
- 902
- 903
- 904
- 905
- 906
- 907
- 908
- 909
- 910
- 911
- 912
- 913
- 914
- 915
- 916
- 917
- 918
- 919
- 920
- 921
- 922
- 923
- 924
- 925
- 926
- 927
- 928
- 929
- 930
- 931
- 932
- 933
- 934
- 935
- 936
- 937
- 938
- 939
- 940
- 941
- 942
- 943
- 944
- 945
- 946
- 947
- 948
- 949
- 950
- 951
- 952
- 953
- 954
- 955
- 956
- 957
- 958
- 959
- 960
- 961
- 962
- 963
- 964
- 965
- 966
- 967
- 968
- 969
- 970
- 971
- 972
- 973
- 974
- 975
- 976
- 977
- 978
- 979
- 980
- 981
- 982
- 983
- 984
- 985
- 986
- 987
- 988
- 989
- 990
- 991
- 992
- 993
- 994
- 995
- 996
- 997
- 998
- 999
-1000
-1001
-1002
-1003
-1004
-1005
-1006
-1007
-1008
-1009
-1010
-1011
-1012
-1013
-1014
-1015
-1016
-1017
-1018
-1019
-1020
-1021
-1022
-1023
-1024
-1025
-1026
-1027
-1028
-1029
-1030
-1031
-1032
-1033
-1034
-1035
-1036
-1037
-1038
-1039
-1040
-1041
-1042
-1043
-1044
-1045
-1046
-1047
-1048
-1049
-1050
-1051
-1052
-1053
-1054
-1055
-1056
-1057
-1058
-1059
-1060
-1061
-1062
-1063
-1064
-1065
-1066
-1067
-1068
-1069
-1070
-1071
-1072
-1073
-1074
-1075
-1076
-1077
-1078
-1079
-1080
-1081
-1082
-1083
-1084
-1085
-1086
-1087
-1088
-1089
-1090
-1091
-1092
-1093
-1094
-1095
-1096
-1097
-1098
-1099
-1100
-1101
-1102
-1103
-1104
-1105
-1106
-1107
-1108
-1109
-1110
-1111
-1112
-1113
-1114
-1115
-1116
-1117
-1118
-1119
-1120
-1121
-1122
-1123
-1124
-1125
-1126
-1127
-1128
-1129
-1130
-1131
-1132
-1133
-1134
-1135
-1136
-1137
-1138
-1139
-1140
-1141
-1142
-1143
-1144
-1145
-1146
-1147
-1148
-1149
-1150
-1151
-1152
-1153
-1154
-1155
-1156
-1157
-1158
-1159
-1160
-1161
-1162
-1163
-1164
-1165
-1166
-1167
-1168
-1169
-1170
-1171
-1172
-1173
-1174
-1175
-1176
-1177
-1178
-1179
-1180
-1181
-1182
-1183
-1184
-1185
-1186
-1187
-1188
-1189
-1190
-1191
-1192
-1193
-1194
-1195
-1196
-1197
-1198
-1199
-1200
-1201
-1202
-1203
-1204
-1205
-1206
-1207
-1208
-1209
-1210
-1211
-1212
-1213
-1214
-1215
-1216
-1217
-1218
-1219
-1220
-1221
-1222
-1223
-1224
-1225
-1226
-1227
-1228
-1229
-1230
-1231
-1232
-1233
-1234
-1235
-1236
-1237
-1238
-1239
-1240
-1241
-1242
-1243
-1244
-1245
-1246
-1247
-1248
-1249
-1250
-1251
-1252
-1253
-1254
-1255
-1256
-1257
-1258
-1259
-1260
-1261
-1262
-1263
-1264
-1265
-1266
-1267
-1268
-1269
-1270
-1271
-1272
-1273
-1274
-1275
-1276
-1277
-1278
-1279
-1280
-1281
-1282
-1283
-1284
-1285
-1286
-1287
-1288
-1289
-1290
-1291
-1292
-1293
-1294
-1295
-1296
-1297
-1298
-1299
-1300
-1301
-1302
-1303
-1304
-1305
-1306
-1307
-1308
-1309
-1310
-1311
-1312
-1313
-1314
-1315
-1316
-1317
-1318
-1319
-1320
-1321
-1322
-1323
-1324
-1325
-1326
-1327
-1328
-1329
-1330
-1331
-1332
-1333
-1334
-1335
-1336
-1337
-1338
-1339
-1340
-1341
-1342
-1343
-1344
-1345
-1346
-1347
-1348
-1349
-1350
-1351
-1352
-1353
-1354
-1355
-1356
-1357
-1358
-1359
-1360
-1361
-1362
-1363
-1364
-1365
-1366
-1367
-1368
-1369
-1370
-1371
-1372
-1373
-1374
-1375
-1376
-1377
-1378
-1379
-1380
-1381
-1382
-1383
-1384
-1385
-1386
-1387
-1388
-1389
-1390
-1391
-1392
-1393
-1394
-1395
-1396
-1397
-1398
-1399
-1400
-1401
-1402
-1403
-1404
-1405
-1406
-1407
-1408
-1409
-1410
-1411
-1412
-1413
-1414
-1415
-1416
-1417
-1418
-1419
-1420
-1421
-1422
-1423
-1424
-1425
-1426
-1427
-1428
-1429
-1430
-1431
-1432
-1433
-1434
-1435
-1436
-1437
-1438
-1439
-1440
-1441
-1442
-1443
-1444
-1445
-1446
-1447
-1448
-1449
-1450
-1451
-1452
-1453
-1454
-1455
-1456
-1457
-1458
-1459
-1460
-1461
-1462
-1463
-1464
-1465
-1466
-1467
-1468
-1469
-1470
-1471
-1472
-1473
-1474
-1475
-1476
-1477
-1478
-1479
-1480
-1481
-1482
-1483
-1484
-1485
-1486
-1487
-1488
-1489
-1490
-1491
-1492
-1493
-1494
-1495
-1496
-1497
-1498
-1499
-1500
-1501
-1502
-1503
-1504
-1505
-1506
-1507
-1508
-1509
-1510
-1511
-1512
-1513
-1514
-1515
-1516
-1517
-1518
-1519
-1520
-1521
-1522
-1523
-1524
-1525
-1526
-1527
-1528
-1529
-1530
-1531
-1532
-1533
-1534
-1535
-1536
-1537
-1538
-1539
-1540
-1541
-1542
-1543
-1544
-1545
-1546
-1547
-1548
-1549
-1550
-1551
-1552
-1553
-1554
-1555
-1556
-1557
-1558
-1559
-1560
-1561
-1562
-1563
-1564
-1565
-1566
-1567
-1568
-1569
-1570
-1571
-1572
-1573
-1574
-1575
-1576
-1577
-1578
-1579
-1580
-1581
-1582
-1583
-1584
-1585
-1586
-1587
-1588
-1589
-1590
-1591
-1592
-1593
-1594
-1595
-1596
-1597
-1598
-1599
-1600
-1601
-1602
-1603
-1604
-1605
-1606
-1607
-1608
-1609
-1610
-1611
-1612
// *****************************************************************************
+
  1
+  2
+  3
+  4
+  5
+  6
+  7
+  8
+  9
+ 10
+ 11
+ 12
+ 13
+ 14
+ 15
+ 16
+ 17
+ 18
+ 19
+ 20
+ 21
+ 22
+ 23
+ 24
+ 25
+ 26
+ 27
+ 28
+ 29
+ 30
+ 31
+ 32
+ 33
+ 34
+ 35
+ 36
+ 37
+ 38
+ 39
+ 40
+ 41
+ 42
+ 43
+ 44
+ 45
+ 46
+ 47
+ 48
+ 49
+ 50
+ 51
+ 52
+ 53
+ 54
+ 55
+ 56
+ 57
+ 58
+ 59
+ 60
+ 61
+ 62
+ 63
+ 64
+ 65
+ 66
+ 67
+ 68
+ 69
+ 70
+ 71
+ 72
+ 73
+ 74
+ 75
+ 76
+ 77
+ 78
+ 79
+ 80
+ 81
+ 82
+ 83
+ 84
+ 85
+ 86
+ 87
+ 88
+ 89
+ 90
+ 91
+ 92
+ 93
+ 94
+ 95
+ 96
+ 97
+ 98
+ 99
+100
+101
+102
+103
+104
+105
+106
+107
+108
+109
+110
+111
+112
+113
+114
+115
+116
+117
+118
+119
+120
+121
+122
+123
// *****************************************************************************
 /*!
-  \file      src/Inciter/ALECG.cpp
+  \file      src/PDE/ConfigureTransport.cpp
   \copyright 2012-2015 J. Bakosi,
              2016-2018 Los Alamos National Security, LLC.,
              2019-2021 Triad National Security, LLC.
              All rights reserved. See the LICENSE file for details.
-  \brief     ALECG for a PDE system with continuous Galerkin + ALE + RK
-  \details   ALECG advances a system of partial differential equations (PDEs)
-    using a continuous Galerkin (CG) finite element (FE) spatial discretization
-    (using linear shapefunctions on tetrahedron elements) combined with a
-    Runge-Kutta (RK) time stepping scheme in the arbitrary Eulerian-Lagrangian
-    reference frame.
-  \see The documentation in ALECG.hpp.
-*/
-// *****************************************************************************
+  \brief     Register and compile configuration on the transport PDE
+  \details   Register and compile configuration on the transport PDE.
+*/
+// *****************************************************************************
+
+#include <set>
+#include <map>
+#include <vector>
+#include <string>
 
-#include "QuinoaBuildConfig.hpp"
-#include "ALECG.hpp"
-#include "Vector.hpp"
-#include "Reader.hpp"
-#include "ContainerUtil.hpp"
-#include "UnsMesh.hpp"
-#include "ExodusIIMeshWriter.hpp"
-#include "Inciter/InputDeck/InputDeck.hpp"
-#include "DerivedData.hpp"
-#include "CGPDE.hpp"
-#include "Discretization.hpp"
-#include "DiagReducer.hpp"
-#include "NodeBC.hpp"
-#include "Refiner.hpp"
-#include "Reorder.hpp"
-#include "Around.hpp"
-#include "CGPDE.hpp"
-#include "Integrate/Mass.hpp"
-#include "FieldOutput.hpp"
-
-namespace inciter {
-
-extern ctr::InputDeck g_inputdeck;
-extern std::vector< CGPDE > g_cgpde;
-
-//! Runge-Kutta coefficients
-static const std::array< tk::real, 3 > rkcoef{{ 1.0/3.0, 1.0/2.0, 1.0 }};
-
-} // inciter::
-
-using inciter::ALECG;
-
-ALECG::ALECG( const CProxy_Discretization& disc,
-              const CProxy_Ghosts&,
-              const std::map< int, std::vector< std::size_t > >& bface,
-              const std::map< int, std::vector< std::size_t > >& bnode,
-              const std::vector< std::size_t >& triinpoel ) :
-  m_disc( disc ),
-  m_nsol( 0 ),
-  m_ngrad( 0 ),
-  m_nrhs( 0 ),
-  m_nbnorm( 0 ),
-  m_ndfnorm( 0 ),
-  m_nmblk( 0 ),
-  m_bnode( bnode ),
-  m_bface( bface ),
-  m_triinpoel( tk::remap( triinpoel, Disc()->Lid() ) ),
-  m_bndel( Disc()->bndel() ),
-  m_dfnorm(),
-  m_dfnormc(),
-  m_dfn(),
-  m_esup( tk::genEsup( Disc()->Inpoel(), 4 ) ),
-  m_psup( tk::genPsup( Disc()->Inpoel(), 4, m_esup ) ),
-  m_u( Disc()->Gid().size(),
-       g_inputdeck.get< tag::ncomp >() ),
-  m_un( m_u.nunk(), m_u.nprop() ),
-  m_rhs( m_u.nunk(), m_u.nprop() ),
-  m_rhsc(),
-  m_chBndGrad( Disc()->Bid().size(), m_u.nprop()*3 ),
-  m_dirbc(),
-  m_chBndGradc(),
-  m_diag(),
-  m_bnorm(),
-  m_bnormc(),
-  m_symbcnodes(),
-  m_farfieldbcnodes(),
-  m_symbctri(),
-  m_timedepbcnodes(),
-  m_timedepbcFn(),
-  m_stage( 0 ),
-  m_boxnodes(),
-  m_edgenode(),
-  m_edgeid(),
-  m_dtp( m_u.nunk(), 0.0 ),
-  m_tp( m_u.nunk(), g_inputdeck.get< tag::t0 >() ),
-  m_finished( 0 ),
-  m_newmesh( 0 ),
-  m_refinedmesh( 0 ),
-  m_nusermeshblk( 0 ),
-  m_nodeblockid(),
-  m_nodeblockidc()
-// *****************************************************************************
-//  Constructor
-//! \param[in] disc Discretization proxy
-//! \param[in] bface Boundary-faces mapped to side sets used in the input file
-//! \param[in] bnode Boundary-node lists mapped to side sets used in input file
-//! \param[in] triinpoel Boundary-face connectivity where BCs set (global ids)
-// *****************************************************************************
-//! [Constructor]
-{
-  usesAtSync = true;    // enable migration at AtSync
-
-  auto d = Disc();
-
-  // Perform optional operator-access-pattern mesh node reordering
-  if (g_inputdeck.get< tag::operator_reorder >()) {
-
-    // Create new local ids based on access pattern of PDE operators
-    std::unordered_map< std::size_t, std::size_t > map;
-    std::size_t n = 0;
-
-    for (std::size_t p=0; p<m_u.nunk(); ++p) {  // for each point p
-      if (map.find(p) == end(map)) map[p] = n++;<--- Searching before insertion is not necessary.
-      for (auto q : tk::Around(m_psup,p)) {     // for each edge p-q
-        if (map.find(q) == end(map)) map[q] = n++;<--- Searching before insertion is not necessary.
-      }
-    }
-
-    Assert( map.size() == d->Gid().size(), "Map size mismatch" );
-
-    // Remap data in bound Discretization object
-    d->remap( map );
-    // Recompute elements surrounding points
-    m_esup = tk::genEsup( d->Inpoel(), 4 );
-    // Recompute points surrounding points
-    m_psup = tk::genPsup( d->Inpoel(), 4, m_esup );
-    // Remap boundary triangle face connectivity
-    tk::remap( m_triinpoel, map );
-  }
-
-  // Query/update boundary-conditions-related data structures from user input
-  queryBnd();
-
-  // Activate SDAG wait for initially computing normals, and mesh blocks
-  thisProxy[ thisIndex ].wait4norm();
-  thisProxy[ thisIndex ].wait4meshblk();
-
-  d->comfinal();
-
-}
-//! [Constructor]
-
-void
-ALECG::queryBnd()
-// *****************************************************************************
-// Query/update boundary-conditions-related data structures from user input
-// *****************************************************************************
-{
-  auto d = Disc();
-
-  // Query and match user-specified Dirichlet boundary conditions to side sets
-  const auto steady = g_inputdeck.get< tag::steady_state >();
-  if (steady) for (auto& deltat : m_dtp) deltat *= rkcoef[m_stage];<--- Consider using std::transform algorithm instead of a raw loop.
-  m_dirbc = match( d->MeshId(), m_u.nprop(), d->T(), rkcoef[m_stage] * d->Dt(),
-                   m_tp, m_dtp, d->Coord(), d->Lid(), m_bnode,
-                   /* increment = */ false );
-  if (steady) for (auto& deltat : m_dtp) deltat /= rkcoef[m_stage];<--- Consider using std::transform algorithm instead of a raw loop.
-
-  // Prepare unique set of symmetry BC nodes
-  auto sym = d->bcnodes< tag::symmetry >( m_bface, m_triinpoel );
-  for (const auto& [s,nodes] : sym)
-    m_symbcnodes.insert( begin(nodes), end(nodes) );
-
-  // Prepare unique set of farfield BC nodes
-  auto far = d->bcnodes< tag::farfield >( m_bface, m_triinpoel );
-  for (const auto& [s,nodes] : far)
-    m_farfieldbcnodes.insert( begin(nodes), end(nodes) );
-
-  // If farfield BC is set on a node, will not also set symmetry BC
-  for (auto fn : m_farfieldbcnodes) m_symbcnodes.erase(fn);
-
-  // Prepare boundary nodes contiguously accessible from a triangle-face loop
-  m_symbctri.resize( m_triinpoel.size()/3, 0 );
-  for (std::size_t e=0; e<m_triinpoel.size()/3; ++e)
-    if (m_symbcnodes.find(m_triinpoel[e*3+0]) != end(m_symbcnodes))
-      m_symbctri[e] = 1;
-
-  // Prepare unique set of time dependent BC nodes
-  m_timedepbcnodes.clear();
-  m_timedepbcFn.clear();
-  const auto& timedep =
-    g_inputdeck.get< tag::bc >()[d->MeshId()].get< tag::timedep >();
-  if (!timedep.empty()) {
-    m_timedepbcnodes.resize(timedep.size());
-    m_timedepbcFn.resize(timedep.size());
-    std::size_t ib=0;
-    for (const auto& bndry : timedep) {
-      std::unordered_set< std::size_t > nodes;
-      for (const auto& s : bndry.template get< tag::sideset >()) {
-        auto k = m_bnode.find(static_cast<int>(s));
-        if (k != end(m_bnode)) {
-          for (auto g : k->second) {      // global node ids on side set
-            nodes.insert( tk::cref_find(d->Lid(),g) );
-          }
-        }
-      }
-      m_timedepbcnodes[ib].insert( begin(nodes), end(nodes) );
-
-      // Store user defined discrete function in time. This is done in the same
-      // loop as the BC nodes, so that the indices for the two vectors
-      // m_timedepbcnodes and m_timedepbcFn are consistent with each other
-      auto fn = bndry.template get< tag::fn >();
-      for (std::size_t ir=0; ir<fn.size()/6; ++ir) {
-        m_timedepbcFn[ib].push_back({{ fn[ir*6+0], fn[ir*6+1], fn[ir*6+2],
-          fn[ir*6+3], fn[ir*6+4], fn[ir*6+5] }});
-      }
-      ++ib;
-    }
-  }
-
-  Assert(m_timedepbcFn.size() == m_timedepbcnodes.size(), "Incorrect number of "
-    "time dependent functions.");
-
-  // Query ALE mesh velocity boundary condition node lists and node lists at
-  // which ALE moves boundaries
-  d->meshvelBnd( m_bface, m_bnode, m_triinpoel );
-}
-
-void
-ALECG::norm()
-// *****************************************************************************
-// Start (re-)computing boundary point-, and dual-face normals
-// *****************************************************************************
-{
-  auto d = Disc();
-
-  // Query nodes at which symmetry BCs are specified
-  auto bn = d->bcnodes< tag::symmetry >( m_bface, m_triinpoel );
-
-  // Query nodes at which farfield BCs are specified
-  auto far = d->bcnodes< tag::farfield >( m_bface, m_triinpoel );
-  // Merge BC data where boundary-point normals are required
-  for (const auto& [s,n] : far) bn[s].insert( begin(n), end(n) );
-
-  // Query nodes at which mesh velocity symmetry BCs are specified
-  std::unordered_map<int, std::unordered_set< std::size_t >> ms;
-  for (const auto& s : g_inputdeck.get< tag::ale, tag::symmetry >()) {
-    auto k = m_bface.find(static_cast<int>(s));
-    if (k != end(m_bface)) {
-      auto& n = ms[ k->first ];
-      for (auto f : k->second) {
-        n.insert( m_triinpoel[f*3+0] );
-        n.insert( m_triinpoel[f*3+1] );
-        n.insert( m_triinpoel[f*3+2] );
-      }
-    }
-  }
-  // Merge BC data where boundary-point normals are required
-  for (const auto& [s,n] : ms) bn[s].insert( begin(n), end(n) );
-
-  // Compute boundary point normals
-  bnorm( bn );
-
-  // Compute dual-face normals associated to edges
-  dfnorm();
-}
-
-std::array< tk::real, 3 >
-ALECG::edfnorm( const tk::UnsMesh::Edge& edge,
-                const std::unordered_map< tk::UnsMesh::Edge,
-                        std::vector< std::size_t >,
-                        tk::UnsMesh::Hash<2>, tk::UnsMesh::Eq<2> >& esued )
-const
-// *****************************************************************************
-//  Compute normal of dual-mesh associated to edge
-//! \param[in] edge Edge whose dual-face normal to compute given by local ids
-//! \param[in] esued Elements surrounding edges
-//! \return Dual-face normal for edge
-// *****************************************************************************
-{
-  auto d = Disc();
-  const auto& inpoel = d->Inpoel();
-  const auto& coord = d->Coord();
-  const auto& x = coord[0];
-  const auto& y = coord[1];
-  const auto& z = coord[2];
-
-  std::array< tk::real, 3 > n{ 0.0, 0.0, 0.0 };
-
-  for (auto e : tk::cref_find(esued,edge)) {
-    // access node IDs
-    const std::array< std::size_t, 4 >
-      N{ inpoel[e*4+0], inpoel[e*4+1], inpoel[e*4+2], inpoel[e*4+3] };
-    // compute element Jacobi determinant
-    const std::array< tk::real, 3 >
-      ba{{ x[N[1]]-x[N[0]], y[N[1]]-y[N[0]], z[N[1]]-z[N[0]] }},
-      ca{{ x[N[2]]-x[N[0]], y[N[2]]-y[N[0]], z[N[2]]-z[N[0]] }},
-      da{{ x[N[3]]-x[N[0]], y[N[3]]-y[N[0]], z[N[3]]-z[N[0]] }};
-    const auto J = tk::triple( ba, ca, da );        // J = 6V
-    Assert( J > 0, "Element Jacobian non-positive" );
-    // shape function derivatives, nnode*ndim [4][3]
-    std::array< std::array< tk::real, 3 >, 4 > grad;
-    grad[1] = tk::crossdiv( ca, da, J );
-    grad[2] = tk::crossdiv( da, ba, J );
-    grad[3] = tk::crossdiv( ba, ca, J );
-    for (std::size_t i=0; i<3; ++i)
-      grad[0][i] = -grad[1][i]-grad[2][i]-grad[3][i];
-    // sum normal contributions
-    // The constant 1/48: Eq (12) from Waltz et al. Computers & fluids (92) 2014
-    // The result of the integral of shape function N on a tet is V/4.
-    // This can be written as J/(6*4). Eq (12) has a 1/2 multiplier.
-    // This leads to J/48.
-    auto J48 = J/48.0;
-    for (const auto& [a,b] : tk::lpoed) {
-      auto s = tk::orient( {N[a],N[b]}, edge );
-      for (std::size_t j=0; j<3; ++j)
-        n[j] += J48 * s * (grad[a][j] - grad[b][j]);
-    }
-  }
-
-  return n;
-}
-
-void
-ALECG::dfnorm()
-// *****************************************************************************
-// Compute dual-face normals associated to edges
-// *****************************************************************************
-{
-  auto d = Disc();
-  const auto& inpoel = d->Inpoel();
-  const auto& gid = d->Gid();
-
-  // compute derived data structures
-  auto esued = tk::genEsued( inpoel, 4, tk::genEsup( inpoel, 4 ) );
-
-  // Compute dual-face normals for domain edges
-  for (std::size_t p=0; p<gid.size(); ++p)    // for each point p
-    for (auto q : tk::Around(m_psup,p))       // for each edge p-q
-      if (gid[p] < gid[q])
-        m_dfnorm[{gid[p],gid[q]}] = edfnorm( {p,q}, esued );
-
-  // Send our dual-face normal contributions to neighbor chares
-  if (d->EdgeCommMap().empty())
-    comdfnorm_complete();
-  else {
-    for (const auto& [c,edges] : d->EdgeCommMap()) {
-      decltype(m_dfnorm) exp;
-      for (const auto& e : edges) exp[e] = tk::cref_find(m_dfnorm,e);
-      thisProxy[c].comdfnorm( exp );
-    }
-  }
-
-  owndfnorm_complete();
-}
-
-void
-ALECG::comdfnorm( const std::unordered_map< tk::UnsMesh::Edge,
-                    std::array< tk::real, 3 >,
-                    tk::UnsMesh::Hash<2>, tk::UnsMesh::Eq<2> >& dfnorm )
-// *****************************************************************************
-// Receive contributions to dual-face normals on chare-boundaries
-//! \param[in] dfnorm Incoming partial sums of dual-face normals associated to
-//!   chare-boundary edges
-// *****************************************************************************
-{
-  // Buffer up inccoming contributions to dual-face normals
-  for (const auto& [e,n] : dfnorm) {
-    auto& dfn = m_dfnormc[e];
-    dfn[0] += n[0];
-    dfn[1] += n[1];
-    dfn[2] += n[2];
-  }
-
-  if (++m_ndfnorm == Disc()->EdgeCommMap().size()) {
-    m_ndfnorm = 0;
-    comdfnorm_complete();
-  }
-}
-
-void
-ALECG::bnorm( const std::unordered_map< int,
-                std::unordered_set< std::size_t > >& bcnodes )
-// *****************************************************************************
-//  Compute boundary point normals
-//! \param[in] bcnodes Local node ids associated to side set ids at which BCs
-//!    are set that require normals
-//*****************************************************************************
-{
-  auto d = Disc();
-
-  m_bnorm = cg::bnorm( m_bface, m_triinpoel, d->Coord(), d->Gid(), bcnodes );
-
-  // Send our nodal normal contributions to neighbor chares
-  if (d->NodeCommMap().empty())
-    comnorm_complete();
-  else
-    for (const auto& [ neighborchare, sharednodes ] : d->NodeCommMap()) {
-      std::unordered_map< int,
-        std::unordered_map< std::size_t, std::array< tk::real, 4 > > > exp;
-      for (auto i : sharednodes) {
-        for (const auto& [s,norms] : m_bnorm) {
-          auto j = norms.find(i);
-          if (j != end(norms)) exp[s][i] = j->second;
-        }
-      }
-      thisProxy[ neighborchare ].comnorm( exp );
-    }
-
-  ownnorm_complete();
-}
-
-void
-ALECG::comnorm( const std::unordered_map< int,
-  std::unordered_map< std::size_t, std::array< tk::real, 4 > > >& innorm )
-// *****************************************************************************
-// Receive boundary point normals on chare-boundaries
-//! \param[in] innorm Incoming partial sums of boundary point normal
-//!   contributions to normals (first 3 components), inverse distance squared
-//!   (4th component), associated to side set ids
-// *****************************************************************************
-{
-  // Buffer up incoming boundary-point normal vector contributions
-  for (const auto& [s,norms] : innorm) {
-    auto& bnorms = m_bnormc[s];
-    for (const auto& [p,n] : norms) {
-      auto& bnorm = bnorms[p];
-      bnorm[0] += n[0];
-      bnorm[1] += n[1];
-      bnorm[2] += n[2];
-      bnorm[3] += n[3];
-    }
-  }
-
-  if (++m_nbnorm == Disc()->NodeCommMap().size()) {
-    m_nbnorm = 0;
-    comnorm_complete();
-  }
-}
-
-void
-ALECG::registerReducers()
-// *****************************************************************************
-//  Configure Charm++ reduction types initiated from this chare array
-//! \details Since this is a [initnode] routine, the runtime system executes the
-//!   routine exactly once on every logical node early on in the Charm++ init
-//!   sequence. Must be static as it is called without an object. See also:
-//!   Section "Initializations at Program Startup" at in the Charm++ manual
-//!   http://charm.cs.illinois.edu/manuals/html/charm++/manual.html.
-// *****************************************************************************
-{
-  NodeDiagnostics::registerReducers();
-}
-
-void
-ALECG::ResumeFromSync()
-// *****************************************************************************
-//  Return from migration
-//! \details This is called when load balancing (LB) completes. The presence of
-//!   this function does not affect whether or not we block on LB.
-// *****************************************************************************
-{
-  if (Disc()->It() == 0) Throw( "it = 0 in ResumeFromSync()" );
-
-  if (!g_inputdeck.get< tag::cmd, tag::nonblocking >()) next();
-}
-
-//! [setup]
-void
-ALECG::setup()
-// *****************************************************************************
-// Start setup for solution
-// *****************************************************************************
-{
-  auto d = Disc();
-
-  // Determine nodes inside user-defined IC box
-  g_cgpde[d->MeshId()].IcBoxNodes( d->Coord(), d->Inpoel(),
-    d->ElemBlockId(), m_boxnodes, m_nodeblockid, m_nusermeshblk );
-
-  // Communicate mesh block nodes to other chares on chare-boundary
-  if (d->NodeCommMap().empty())        // in serial we are done
-    comblk_complete();
-  else // send mesh block information to chare-boundary nodes to fellow chares
-    for (const auto& [c,n] : d->NodeCommMap()) {
-      // data structure assigning block ids (set of values) to nodes (index).
-      // although nodeblockid is a map with key-blockid and value-nodeid, the
-      // sending data structure has to be inverted, because of how communication
-      // data is handled.
-      std::vector< std::set< std::size_t > > mb( n.size() );
-      std::size_t j = 0;
-      for (auto i : n) {
-        for (const auto& [blid, ndset] : m_nodeblockid) {
-          // if node was found in a block, add to send-data
-          if (ndset.find(tk::cref_find(d->Lid(),i)) != ndset.end())
-            mb[j].insert(blid);
-        }
-        if (m_nusermeshblk > 0)
-          Assert(mb[j].size() > 0, "Sending no block data for node");
-        ++j;
-      }
-      thisProxy[c].comblk( std::vector<std::size_t>(begin(n),end(n)), mb );
-    }
-
-  ownblk_complete();
-}
-
-void
-ALECG::comblk( const std::vector< std::size_t >& gid,
-               const std::vector< std::set< std::size_t > >& mb )
-// *****************************************************************************
-//  Receive mesh block information for nodes on chare-boundaries
-//! \param[in] gid Global mesh node IDs at which we receive RHS contributions
-//! \param[in] mb Block ids for each node on chare-boundaries
-//! \details This function receives mesh block information for nodes on chare
-//!   boundaries. While m_nodeblockid stores block information for own nodes,
-//!   m_nodeblockidc collects the neighbor chare information during
-//!   communication. This way work on m_nodeblockid and m_nodeblockidc is
-//!   overlapped. The two are combined in continueSetup().
-// *****************************************************************************
-{
-  Assert( mb.size() == gid.size(), "Size mismatch" );
-
-  for (std::size_t i=0; i<gid.size(); ++i) {
-    for (const auto& blid : mb[i]) {
-      m_nodeblockidc[blid].insert(gid[i]);
-    }
-  }
-
-  // When we have heard from all chares we communicate with, this chare is done
-  if (++m_nmblk == Disc()->NodeCommMap().size()) {
-    m_nmblk = 0;
-    comblk_complete();
-  }
-}
-
-void
-ALECG::continueSetup()
-// *****************************************************************************
-// Continue setup for solution, after communication for mesh blocks
-// *****************************************************************************
-{
-  auto d = Disc();
-
-  // Combine own and communicated mesh block information
-  for (const auto& [blid, ndset] : m_nodeblockidc) {
-    for (const auto& i : ndset) {
-      auto lid = tk::cref_find(d->Lid(), i);
-      m_nodeblockid[blid].insert(lid);
-    }
-  }
-
-  // clear receive buffer
-  tk::destroy(m_nodeblockidc);
-
-  // Compute volume of user-defined box IC
-  d->boxvol( m_boxnodes, m_nodeblockid, m_nusermeshblk );
-
-  // Query time history field output labels from all PDEs integrated
-  const auto& hist_points = g_inputdeck.get< tag::history_output, tag::point >();
-  if (!hist_points.empty()) {
-    std::vector< std::string > histnames;
-    auto n = g_cgpde[d->MeshId()].histNames();
-    histnames.insert( end(histnames), begin(n), end(n) );
-    d->histheader( std::move(histnames) );
-  }
-}
-//! [setup]
-
-void
-ALECG::volumetric( tk::Fields& u, const std::vector< tk::real >& v )
-// *****************************************************************************
-//  Multiply solution with mesh volume
-//! \param[in,out] u Solution vector
-//! \param[in] v Volume to multiply with
-// *****************************************************************************
-{
-  Assert( v.size() == u.nunk(), "Size mismatch" );
-
-  for (std::size_t i=0; i<u.nunk(); ++i)
-    for (ncomp_t c=0; c<u.nprop(); ++c)
-      u(i,c) *= v[i];
-}
-
-void
-ALECG::conserved( tk::Fields& u, const std::vector< tk::real >& v )
-// *****************************************************************************
-//  Divide solution with mesh volume
-//! \param[in,out] u Solution vector
-//! \param[in] v Volume to divide with
-// *****************************************************************************
-{
-  Assert( v.size() == u.nunk(), "Size mismatch" );
-
-  for (std::size_t i=0; i<u.nunk(); ++i)
-    for (ncomp_t c=0; c<u.nprop(); ++c) {
-      u(i,c) /= v[i];
-    }
-}
-
-void
-ALECG::box( tk::real v, const std::vector< tk::real >& blkvols )
-// *****************************************************************************
-// Receive total box IC volume and set conditions in box
-//! \param[in] v Total volume within user-specified box
-//! \param[in] blkvols Vector of mesh block discrete volumes with user ICs
-// *****************************************************************************
-{
-  Assert(blkvols.size() == m_nusermeshblk,
-    "Incorrect size of block volume vector");
-  auto d = Disc();
-
-  // Store user-defined box/block IC volume
-  d->Boxvol() = v;
-  d->MeshBlkVol() = blkvols;
-
-  // Set initial conditions for all PDEs
-  g_cgpde[d->MeshId()].initialize( d->Coord(), m_u, d->T(), d->Boxvol(),
-    m_boxnodes, d->MeshBlkVol(), m_nodeblockid );
-
-  // Multiply conserved variables with mesh volume
-  volumetric( m_u, Disc()->Vol() );
-
-  // Initialize nodal mesh volumes at previous time step stage
-  d->Voln() = d->Vol();
-
-  // Start computing the mesh mesh velocity for ALE
-  meshvelstart();
-}
-
-void
-ALECG::meshvelstart()
-// *****************************************************************************
-// Start computing the mesh mesh velocity for ALE
-// *****************************************************************************
-{
-  auto d = Disc();
-
-  // Apply boundary conditions on numerical solution
-  BC();
-
-  conserved( m_u, d->Vol() );
-
-  // query fluid velocity across all systems integrated
-  tk::UnsMesh::Coords vel;
-  g_cgpde[d->MeshId()].velocity( m_u, vel );
-  // query speed of sound in mesh nodes across all systems integrated
-  std::vector< tk::real > soundspeed;
-  g_cgpde[d->MeshId()].soundspeed( m_u, soundspeed );
-
-  volumetric( m_u, d->Vol() );
-
-  // Start computing the mesh mesh velocity for ALE
-  d->meshvelStart( vel, soundspeed, m_bnorm, rkcoef[m_stage] * d->Dt(),
-    CkCallback(CkIndex_ALECG::meshveldone(), thisProxy[thisIndex]) );
-}
-
-void
-ALECG::meshveldone()
-// *****************************************************************************
-// Done with computing the mesh velocity for ALE
-// *****************************************************************************
-{
-  // Assess and record mesh velocity linear solver conergence
-  Disc()->meshvelConv();
-
-  // Continue
-  if (Disc()->Initial()) {
-
-    conserved( m_u, Disc()->Vol() );
-
-    // Initiate IC transfer (if coupled)
-    Disc()->transfer( m_u, 0,
-      CkCallback(CkIndex_ALECG::transfer_complete(), thisProxy[thisIndex]) );
-
-    lhs();
-
-  } else {
-
-    ale();
-
-  }
-}
-
-//! [start]
-void
-ALECG::start()
-// *****************************************************************************
-// Start time stepping
-// *****************************************************************************
-{
-  // Set flag that indicates that we are now during time stepping
-  Disc()->Initial( 0 );
-  // Start timer measuring time stepping wall clock time
-  Disc()->Timer().zero();
-  // Zero grind-timer
-  Disc()->grindZero();
-  // Continue to first time step
-  next();
-}
-//! [start]
-
-//! [Compute lhs]
-void
-ALECG::lhs()
-// *****************************************************************************
-// Compute the left-hand side of transport equations
-//! \details Also (re-)compute all data structures if the mesh changed.
-// *****************************************************************************
-{
-  // No need for LHS in ALECG
-
-  // (Re-)compute boundary point-, and dual-face normals
-  norm();
-}
-//! [Compute lhs]
-
-//! [Merge normals and continue]
-void
-ALECG::mergelhs()
-// *****************************************************************************
-// The own and communication portion of the left-hand side is complete
-// *****************************************************************************
-{
-  // Combine own and communicated contributions of normals
-  normfinal();
-
-  if (Disc()->Initial()) {
-    volumetric( m_u, Disc()->Vol() );
-    // Output initial conditions to file
-    writeFields( CkCallback(CkIndex_ALECG::start(), thisProxy[thisIndex]) );
-  } else {
-    norm_complete();
-  }
-}
-//! [Merge normals and continue]
-
-void
-ALECG::normfinal()
-// *****************************************************************************
-//  Finish computing dual-face and boundary point normals
-// *****************************************************************************
-{
-  auto d = Disc();
-  const auto& lid = d->Lid();
-
-  // Combine own and communicated contributions to boundary point normals
-  for (const auto& [s,norms] : m_bnormc) {
-    auto& bnorms = m_bnorm[s];
-    for (const auto& [p,n] : norms) {
-      auto& norm = bnorms[p];
-      norm[0] += n[0];
-      norm[1] += n[1];
-      norm[2] += n[2];
-      norm[3] += n[3];
-    }
-  }
-  tk::destroy( m_bnormc );
-
-  // Divide summed point normals by the sum of inverse distance squared
-  for (auto& [s,norms] : m_bnorm)
-    for (auto& [p,n] : norms) {
-      n[0] /= n[3];
-      n[1] /= n[3];
-      n[2] /= n[3];
-      Assert( (n[0]*n[0] + n[1]*n[1] + n[2]*n[2] - 1.0) <
-              1.0e+3*std::numeric_limits< tk::real >::epsilon(),
-              "Non-unit normal" );
-    }
-
-  // Replace global->local ids associated to boundary point normals
-  decltype(m_bnorm) bnorm;
-  for (auto& [s,norms] : m_bnorm) {
-    auto& bnorms = bnorm[s];
-    for (auto&& [g,n] : norms)
-      bnorms[ tk::cref_find(lid,g) ] = std::move(n);
-  }
-  m_bnorm = std::move(bnorm);
-
-  // Count contributions to chare-boundary edges
-  std::unordered_map< tk::UnsMesh::Edge, std::size_t,
-    tk::UnsMesh::Hash<2>, tk::UnsMesh::Eq<2> > edge_node_count;
-  for (const auto& [c,edges] : d->EdgeCommMap())
-    for (const auto& e : edges)
-      ++edge_node_count[e];
-
-  // Combine and weigh communicated contributions to dual-face normals
-  for (auto& [e,n] : m_dfnormc) {
-    const auto& dfn = tk::cref_find( m_dfnorm, e );
-    n[0] += dfn[0];
-    n[1] += dfn[1];
-    n[2] += dfn[2];
-    auto count = static_cast< tk::real >( tk::cref_find( edge_node_count, e ) );
-    auto factor = 1.0/(count + 1.0);
-    for (auto & x : n) x *= factor;<--- Consider using std::transform algorithm instead of a raw loop.
-  }
-
-  // Generate list of unique edges
-  tk::UnsMesh::EdgeSet uedge;
-  for (std::size_t p=0; p<m_u.nunk(); ++p)
-    for (auto q : tk::Around(m_psup,p))
-      uedge.insert( {p,q} );
-
-  // Flatten edge list
-  m_edgenode.resize( uedge.size() * 2 );
-  std::size_t f = 0;
-  const auto& gid = d->Gid();
-  for (auto&& [p,q] : uedge) {
-    if (gid[p] > gid[q]) {
-      m_edgenode[f+0] = std::move(q);
-      m_edgenode[f+1] = std::move(p);
-    } else {
-      m_edgenode[f+0] = std::move(p);
-      m_edgenode[f+1] = std::move(q);
-    }
-    f += 2;
-  }
-  tk::destroy(uedge);
-
-  // Convert dual-face normals to streamable (and vectorizable) data structure
-  m_dfn.resize( m_edgenode.size() * 3 );      // 2 vectors per access
-  std::unordered_map< tk::UnsMesh::Edge, std::size_t,
-                      tk::UnsMesh::Hash<2>, tk::UnsMesh::Eq<2> > eid;
-  for (std::size_t e=0; e<m_edgenode.size()/2; ++e) {
-    auto p = m_edgenode[e*2+0];
-    auto q = m_edgenode[e*2+1];
-    eid[{p,q}] = e;
-    std::array< std::size_t, 2 > g{ gid[p], gid[q] };
-    auto n = tk::cref_find( m_dfnorm, g );
-    // figure out if this is an edge on the parallel boundary
-    auto nit = m_dfnormc.find( g );
-    auto m = ( nit != m_dfnormc.end() ) ? nit->second : n;
-    m_dfn[e*6+0] = n[0];
-    m_dfn[e*6+1] = n[1];
-    m_dfn[e*6+2] = n[2];
-    m_dfn[e*6+3] = m[0];
-    m_dfn[e*6+4] = m[1];
-    m_dfn[e*6+5] = m[2];
-  }
-
-  tk::destroy( m_dfnorm );
-  tk::destroy( m_dfnormc );
-
-  // Flatten edge id data structure
-  m_edgeid.resize( m_psup.first.size() );
-  for (std::size_t p=0,k=0; p<m_u.nunk(); ++p)
-    for (auto q : tk::Around(m_psup,p))
-      m_edgeid[k++] = tk::cref_find( eid, {p,q} );
-}
-
-void
-ALECG::BC()
-// *****************************************************************************
-// Apply boundary conditions
-// \details The following BC enforcement changes the initial condition or
-//!   updated solution (dependending on when it is called) to ensure strong
-//!   imposition of the BCs. This is a matter of choice. Another alternative is
-//!   to only apply BCs when computing fluxes at boundary faces, thereby only
-//!   weakly enforcing the BCs. The former is conventionally used in continunous
-//!   Galerkin finite element methods (such as ALECG implements), whereas the
-//!   latter, in finite volume methods.
-// *****************************************************************************
-{
-  auto d = Disc();
-  const auto& coord = d->Coord();
-
-  conserved( m_u, d->Vol() );
-
-  // Apply Dirichlet BCs
-  for (const auto& [b,bc] : m_dirbc)
-    for (ncomp_t c=0; c<m_u.nprop(); ++c)
-      if (bc[c].first) m_u(b,c) = bc[c].second;
-
-  // Apply symmetry BCs
-  g_cgpde[d->MeshId()].symbc( m_u, coord, m_bnorm, m_symbcnodes );
-
-  // Apply farfield BCs
-  g_cgpde[d->MeshId()].farfieldbc( m_u, coord, m_bnorm, m_farfieldbcnodes );
-
-  // Apply user defined time dependent BCs
-  g_cgpde[d->MeshId()].timedepbc( d->T(), m_u, m_timedepbcnodes,
-    m_timedepbcFn );
-
-  volumetric( m_u, d->Vol() );
-}
-
-void
-ALECG::next()
-// *****************************************************************************
-// Continue to next time step
-// *****************************************************************************
-{
-  dt();
-}
-
-void
-ALECG::dt()
-// *****************************************************************************
-// Compute time step size
-// *****************************************************************************
-{
-  tk::real mindt = std::numeric_limits< tk::real >::max();
-
-  auto const_dt = g_inputdeck.get< tag::dt >();
-  auto eps = std::numeric_limits< tk::real >::epsilon();
-
-  auto d = Disc();
-
-  // use constant dt if configured
-  if (std::abs(const_dt) > eps) {
-
-    mindt = const_dt;
-
-  } else {      // compute dt based on CFL
-
-    //! [Find the minimum dt across all PDEs integrated]
-    conserved( m_u, Disc()->Vol() );
-    if (g_inputdeck.get< tag::steady_state >()) {
-
-      // compute new dt for each mesh point
-      g_cgpde[d->MeshId()].dt( d->It(), d->Vol(), m_u, m_dtp );
-
-      // find the smallest dt of all nodes on this chare
-      mindt = *std::min_element( begin(m_dtp), end(m_dtp) );
-
-    } else {    // compute new dt for this chare
-
-      // find the smallest dt of all equations on this chare
-      auto eqdt = g_cgpde[d->MeshId()].dt( d->Coord(), d->Inpoel(), d->T(),
-        d->Dtn(), m_u, d->Vol(), d->Voln() );
-      if (eqdt < mindt) mindt = eqdt;
-
-    }
-    volumetric( m_u, Disc()->Vol() );
-    //! [Find the minimum dt across all PDEs integrated]
-
-  }
-
-  //! [Advance]
-  // Actiavate SDAG waits for next time step stage
-  thisProxy[ thisIndex ].wait4grad();
-  thisProxy[ thisIndex ].wait4rhs();
-
-  // Contribute to minimum dt across all chares and advance to next step
-  contribute( sizeof(tk::real), &mindt, CkReduction::min_double,
-              CkCallback(CkReductionTarget(ALECG,advance), thisProxy) );
-  //! [Advance]
-}
-
-void
-ALECG::advance( tk::real newdt, tk::real )
-// *****************************************************************************
-// Advance equations to next time step
-//! \param[in] newdt The smallest dt across the whole problem
-// *****************************************************************************
-{
-  auto d = Disc();
-
-  // Set new time step size
-  if (m_stage == 0) d->setdt( newdt );
-
-  // Compute gradients for next time step
-  chBndGrad();
-}
-
-void
-ALECG::chBndGrad()
-// *****************************************************************************
-// Compute nodal gradients at chare-boundary nodes. Gradients at internal nodes
-// are calculated locally as needed and are not stored.
-// *****************************************************************************
-{
-  auto d = Disc();
-
-  // Divide solution with mesh volume
-  conserved( m_u, Disc()->Vol() );
-  // Compute own portion of gradients for all equations
-  g_cgpde[d->MeshId()].chBndGrad( d->Coord(), d->Inpoel(), m_bndel, d->Gid(),
-    d->Bid(), m_u, m_chBndGrad );
-  // Multiply solution with mesh volume
-  volumetric( m_u, Disc()->Vol() );
-
-  // Communicate gradients to other chares on chare-boundary
-  if (d->NodeCommMap().empty())        // in serial we are done
-    comgrad_complete();
-  else // send gradients contributions to chare-boundary nodes to fellow chares
-    for (const auto& [c,n] : d->NodeCommMap()) {
-      std::vector< std::vector< tk::real > > g( n.size() );
-      std::size_t j = 0;
-      for (auto i : n) g[ j++ ] = m_chBndGrad[ tk::cref_find(d->Bid(),i) ];
-      thisProxy[c].comChBndGrad( std::vector<std::size_t>(begin(n),end(n)), g );
-    }
-
-  owngrad_complete();
-}
-
-void
-ALECG::comChBndGrad( const std::vector< std::size_t >& gid,
-                     const std::vector< std::vector< tk::real > >& G )
-// *****************************************************************************
-//  Receive contributions to nodal gradients on chare-boundaries
-//! \param[in] gid Global mesh node IDs at which we receive grad contributions
-//! \param[in] G Partial contributions of gradients to chare-boundary nodes
-//! \details This function receives contributions to m_chBndGrad, which stores
-//!   nodal gradients at mesh chare-boundary nodes. While m_chBndGrad stores
-//!   own contributions, m_chBndGradc collects the neighbor chare
-//!   contributions during communication. This way work on m_chBndGrad and
-//!   m_chBndGradc is overlapped. The two are combined in rhs().
-// *****************************************************************************
-{
-  Assert( G.size() == gid.size(), "Size mismatch" );
-
-  using tk::operator+=;
-
-  for (std::size_t i=0; i<gid.size(); ++i) m_chBndGradc[ gid[i] ] += G[i];
-
-  if (++m_ngrad == Disc()->NodeCommMap().size()) {
-    m_ngrad = 0;
-    comgrad_complete();
-  }
-}
-
-void
-ALECG::rhs()
-// *****************************************************************************
-// Compute right-hand side of transport equations
-// *****************************************************************************
-{
-  auto d = Disc();
-
-  // Combine own and communicated contributions to nodal gradients
-  for (const auto& [gid,g] : m_chBndGradc) {
-    auto bid = tk::cref_find( d->Bid(), gid );
-    for (ncomp_t c=0; c<m_chBndGrad.nprop(); ++c)
-      m_chBndGrad(bid,c) += g[c];
-  }
-
-  // clear gradients receive buffer
-  tk::destroy(m_chBndGradc);
-
-  const auto steady = g_inputdeck.get< tag::steady_state >();
-
-  // Compute own portion of right-hand side for all equations
-  auto prev_rkcoef = m_stage == 0 ? 0.0 : rkcoef[m_stage-1];
-  if (steady)
-    for (std::size_t p=0; p<m_tp.size(); ++p) m_tp[p] += prev_rkcoef * m_dtp[p];
-  conserved( m_u, Disc()->Vol() );
-  g_cgpde[d->MeshId()].rhs( d->T() + prev_rkcoef * d->Dt(), d->Coord(), d->Inpoel(),
-          m_triinpoel, d->Gid(), d->Bid(), d->Lid(), m_dfn, m_psup, m_esup,
-          m_symbctri, d->Vol(), m_edgenode, m_edgeid,
-          m_boxnodes, m_chBndGrad, m_u, d->meshvel(), m_tp, d->Boxvol(),
-          m_rhs );
-  volumetric( m_u, Disc()->Vol() );
-  if (steady)
-    for (std::size_t p=0; p<m_tp.size(); ++p) m_tp[p] -= prev_rkcoef * m_dtp[p];
-
-  // Query/update boundary-conditions-related data structures from user input
-  queryBnd();
-
-  // Communicate rhs to other chares on chare-boundary
-  if (d->NodeCommMap().empty())        // in serial we are done
-    comrhs_complete();
-  else // send contributions of rhs to chare-boundary nodes to fellow chares
-    for (const auto& [c,n] : d->NodeCommMap()) {
-      std::vector< std::vector< tk::real > > r( n.size() );
-      std::size_t j = 0;
-      for (auto i : n) r[ j++ ] = m_rhs[ tk::cref_find(d->Lid(),i) ];
-      thisProxy[c].comrhs( std::vector<std::size_t>(begin(n),end(n)), r );
-    }
-
-  ownrhs_complete();
-}
-
-void
-ALECG::comrhs( const std::vector< std::size_t >& gid,
-               const std::vector< std::vector< tk::real > >& R )
-// *****************************************************************************
-//  Receive contributions to right-hand side vector on chare-boundaries
-//! \param[in] gid Global mesh node IDs at which we receive RHS contributions
-//! \param[in] R Partial contributions of RHS to chare-boundary nodes
-//! \details This function receives contributions to m_rhs, which stores the
-//!   right hand side vector at mesh nodes. While m_rhs stores own
-//!   contributions, m_rhsc collects the neighbor chare contributions during
-//!   communication. This way work on m_rhs and m_rhsc is overlapped. The two
-//!   are combined in solve().
-// *****************************************************************************
-{
-  Assert( R.size() == gid.size(), "Size mismatch" );
-
-  using tk::operator+=;
-
-  for (std::size_t i=0; i<gid.size(); ++i) m_rhsc[ gid[i] ] += R[i];
-
-  // When we have heard from all chares we communicate with, this chare is done
-  if (++m_nrhs == Disc()->NodeCommMap().size()) {
-    m_nrhs = 0;
-    comrhs_complete();
-  }
-}
-
-void
-ALECG::solve()
-// *****************************************************************************
-//  Advance systems of equations
-// *****************************************************************************
-{
-  auto d = Disc();
-
-  // Combine own and communicated contributions to rhs
-  for (const auto& b : m_rhsc) {
-    auto lid = tk::cref_find( d->Lid(), b.first );
-    for (ncomp_t c=0; c<m_rhs.nprop(); ++c) m_rhs(lid,c) += b.second[c];
-  }
-
-  // clear receive buffer
-  tk::destroy(m_rhsc);
-
-  // Update state at time n
-  if (m_stage == 0) {
-    m_un = m_u;
-    if (g_inputdeck.get< tag::ale, tag::ale >()) d->UpdateCoordn();
-  }
-
-  // Solve the sytem
-  if (g_inputdeck.get< tag::steady_state >()) {
-
-    // Advance solution, converging to steady state
-    for (std::size_t i=0; i<m_u.nunk(); ++i)
-      for (ncomp_t c=0; c<m_u.nprop(); ++c)
-        m_u(i,c) = m_un(i,c) + rkcoef[m_stage] * m_dtp[i] * m_rhs(i,c);
-
-  } else {
-
-    auto adt = rkcoef[m_stage] * d->Dt();
-
-    // Advance unsteady solution
-    m_u = m_un + adt * m_rhs;
-
-    // Advance mesh if ALE is enabled
-    if (g_inputdeck.get< tag::ale, tag::ale >()) {
-      auto& coord = d->Coord();
-      const auto& w = d->meshvel();
-      for (auto j : g_inputdeck.get< tag::ale, tag::mesh_motion >())
-        for (std::size_t i=0; i<coord[j].size(); ++i)
-          coord[j][i] = d->Coordn()[j][i] + adt * w(i,j);
-    }
-
-  }
-
-  m_newmesh = 0;  // recompute normals after ALE (if enabled)
-  m_refinedmesh = 0;  // mesh has not been refined by ALE
-  // Activate SDAG waits
-  thisProxy[ thisIndex ].wait4norm();
-  thisProxy[ thisIndex ].wait4mesh();
-
-  //! [Continue after solve]
-  // Recompute mesh volumes if ALE is enabled
-  if (g_inputdeck.get< tag::ale, tag::ale >()) {
-
-    transfer_complete();
-    // Save nodal volumes at previous time step stage
-    d->Voln() = d->Vol();
-    // Prepare for recomputing the nodal volumes
-    d->startvol();
-    auto meshid = d->MeshId();
-    contribute( sizeof(std::size_t), &meshid, CkReduction::nop,
-                CkCallback(CkReductionTarget(Transporter,resized), d->Tr()) );
-
-  } else {
-
-    norm_complete();
-    resized();
-
-  }
-  //! [Continue after solve]
-}
-
-void
-ALECG::ale()
-// *****************************************************************************
-//  Continue after computing the new mesh velocity for ALE
-// *****************************************************************************
-{
-  auto d = Disc();
-
-  if (m_stage < 2) {
-
-    // Activate SDAG wait for next time step stage
-    thisProxy[ thisIndex ].wait4grad();
-    thisProxy[ thisIndex ].wait4rhs();
-
-    // continue to mesh-to-mesh transfer (if coupled)
-    transfer();
-
-  } else {
-
-    // Ensure new field output file if mesh moved if ALE is enabled
-    if (g_inputdeck.get< tag::ale, tag::ale >()) {
-      d->Itf() = 0;  // Zero field output iteration count if mesh moved
-      ++d->Itr();    // Increase number of iterations with a change in the mesh
-    }
-
-    // Compute diagnostics, e.g., residuals
-    conserved( m_u, Disc()->Vol() );
-    conserved( m_un, Disc()->Voln() );
-    auto diag_computed = m_diag.compute( *d, m_u, m_un, m_bnorm,
-                                         m_symbcnodes, m_farfieldbcnodes );
-    volumetric( m_u, Disc()->Vol() );
-    volumetric( m_un, Disc()->Voln() );
-    // Increase number of iterations and physical time
-    d->next();
-    // Advance physical time for local time stepping
-    if (g_inputdeck.get< tag::steady_state >())
-      for (std::size_t i=0; i<m_u.nunk(); ++i) m_tp[i] += m_dtp[i];
-    // Continue to mesh refinement (if configured)
-    if (!diag_computed) refine( std::vector< tk::real >( m_u.nprop(), 1.0 ) );
-
-  }
-}
-
-//! [Refine]
-void
-ALECG::refine( const std::vector< tk::real >& l2res )
-// *****************************************************************************
-// Optionally refine/derefine mesh
-//! \param[in] l2res L2-norms of the residual for each scalar component
-//!   computed across the whole problem
-// *****************************************************************************
-{
-  auto d = Disc();
-
-  const auto steady = g_inputdeck.get< tag::steady_state >();
-  const auto residual = g_inputdeck.get< tag::residual >();
-  const auto rc = g_inputdeck.get< tag::rescomp >() - 1;
-
-  if (steady) {
-
-    // this is the last time step if max time of max number of time steps
-    // reached or the residual has reached its convergence criterion
-    if (d->finished() or l2res[rc] < residual) m_finished = 1;
-
-  } else {
-
-    // this is the last time step if max time or max iterations reached
-    if (d->finished()) m_finished = 1;
-
-  }
-
-  auto dtref = g_inputdeck.get< tag::amr, tag::dtref >();
-  auto dtfreq = g_inputdeck.get< tag::amr, tag::dtfreq >();
-
-  // Activate SDAG waits for re-computing the normals
-  m_newmesh = 1;  // recompute normals after AMR (if enabled)
-  thisProxy[ thisIndex ].wait4norm();
-  thisProxy[ thisIndex ].wait4mesh();
-
-  // if t>0 refinement enabled and we hit the frequency
-  if (dtref && !(d->It() % dtfreq)) {   // refine
-
-    // Convert to conserved unknowns, since the next step changes volumes
-    conserved(m_u, d->Vol());
-
-    m_refinedmesh = 1;
-    d->startvol();
-    d->Ref()->dtref( m_bface, m_bnode, m_triinpoel );
-    d->refined() = 1;
-
-  } else {      // do not refine
-
-    m_refinedmesh = 0;
-    d->refined() = 0;
-    norm_complete();
-    resized();
-
-  }
-}
-//! [Refine]
-
-//! [Resize]
-void
-ALECG::resizePostAMR(
-  const std::vector< std::size_t >& /*ginpoel*/,
-  const tk::UnsMesh::Chunk& chunk,
-  const tk::UnsMesh::Coords& coord,
-  const std::unordered_map< std::size_t, tk::UnsMesh::Edge >& addedNodes,
-  const std::unordered_map< std::size_t, std::size_t >& /*addedTets*/,
-  const std::set< std::size_t >& removedNodes,
-  const std::unordered_map< std::size_t, std::size_t >& amrNodeMap,
-  const tk::NodeCommMap& nodeCommMap,
-  const std::map< int, std::vector< std::size_t > >& bface,
-  const std::map< int, std::vector< std::size_t > >& bnode,
-  const std::vector< std::size_t >& triinpoel,
-  const std::unordered_map< std::size_t, std::set< std::size_t > >& elemblockid )
-// *****************************************************************************
-//  Receive new mesh from Refiner
-//! \param[in] ginpoel Mesh connectivity with global node ids
-//! \param[in] chunk New mesh chunk (connectivity and global<->local id maps)
-//! \param[in] coord New mesh node coordinates
-//! \param[in] addedNodes Newly added mesh nodes and their parents (local ids)
-//! \param[in] addedTets Newly added mesh cells and their parents (local ids)
-//! \param[in] removedNodes Newly removed mesh node local ids
-//! \param[in] amrNodeMap Node id map after amr (local ids)
-//! \param[in] nodeCommMap New node communication map
-//! \param[in] bface Boundary-faces mapped to side set ids
-//! \param[in] bnode Boundary-node lists mapped to side set ids
-//! \param[in] triinpoel Boundary-face connectivity
-//! \param[in] elemblockid Local tet ids associated with mesh block ids
-// *****************************************************************************
-{
-  auto d = Disc();
-
-  d->Itf() = 0;  // Zero field output iteration count if AMR
-  ++d->Itr();    // Increase number of iterations with a change in the mesh
-
-  // Resize mesh data structures after mesh refinement
-  d->resizePostAMR( chunk, coord, amrNodeMap, nodeCommMap, removedNodes,
-    elemblockid );
-
-  // Remove newly removed nodes from solution vectors
-  m_u.rm(removedNodes);
-  m_un.rm(removedNodes);
-  m_rhs.rm(removedNodes);
-
-  // Resize auxiliary solution vectors
-  auto npoin = coord[0].size();
-  auto nprop = m_u.nprop();
-  m_u.resize( npoin );
-  m_un.resize( npoin );
-  m_rhs.resize( npoin );
-  m_chBndGrad.resize( d->Bid().size() );
-  tk::destroy(m_esup);
-  tk::destroy(m_psup);
-  m_esup = tk::genEsup( d->Inpoel(), 4 );
-  m_psup = tk::genPsup( d->Inpoel(), 4, m_esup );
-
-  // Update solution on new mesh
-  for (const auto& n : addedNodes)
-    for (std::size_t c=0; c<nprop; ++c) {
-      Assert(n.first < m_u.nunk(), "Added node index out of bounds post-AMR");
-      Assert(n.second[0] < m_u.nunk() && n.second[1] < m_u.nunk(),
-        "Indices of parent-edge nodes out of bounds post-AMR");
-      m_u(n.first,c) = (m_u(n.second[0],c) + m_u(n.second[1],c))/2.0;
-    }
-
-  // Update physical-boundary node-, face-, and element lists
-  m_bnode = bnode;
-  m_bface = bface;
-  m_triinpoel = tk::remap( triinpoel, d->Lid() );
-
-  auto meshid = d->MeshId();
-  contribute( sizeof(std::size_t), &meshid, CkReduction::nop,
-              CkCallback(CkReductionTarget(Transporter,resized), d->Tr()) );
-}
-//! [Resize]
-
-void
-ALECG::resized()
-// *****************************************************************************
-// Resizing data sutrctures after mesh refinement has been completed
-// *****************************************************************************
-{
-  auto d = Disc();
-
-  // Revert to volumetric unknowns, if soln was converted in ALECG::refine()
-  auto dtref = g_inputdeck.get< tag::amr, tag::dtref >();
-  auto dtfreq = g_inputdeck.get< tag::amr, tag::dtfreq >();
-  if (dtref && !(d->It() % dtfreq) && m_refinedmesh==1) {
-    volumetric(m_u, d->Vol());
-    // Update previous volumes after refinement
-    d->Voln() = d->Vol();
-  }
-
-  resize_complete();
-}
-
-void
-ALECG::transfer()
-// *****************************************************************************
-// Transfer solution to other solver and mesh if coupled
-// *****************************************************************************
-{
-  // Initiate solution transfer (if coupled)
-
-//TODO: enable this for during-timestepping solution transfer
-//  Disc()->transfer(m_u, CkCallback(CkIndex_ALECG::stage(), thisProxy[thisIndex]));
-  thisProxy[thisIndex].stage();
-}
-
-//! [stage]
-void
-ALECG::stage()
-// *****************************************************************************
-// Evaluate whether to continue with next time step stage
-// *****************************************************************************
-{
-  transfer_complete();
-
-  // Increment Runge-Kutta stage counter
-  ++m_stage;
-
-  // if not all Runge-Kutta stages complete, continue to next time stage,
-  // otherwise output field data to file(s)
-  if (m_stage < 3) chBndGrad(); else out();
-}
-//! [stage]
-
-void
-ALECG::writeFields( CkCallback c )
-// *****************************************************************************
-// Output mesh-based fields to file
-//! \param[in] c Function to continue with after the write
-// *****************************************************************************
-{
-  if (g_inputdeck.get< tag::cmd, tag::benchmark >()) {
-
-    c.send();
-
-  } else {
-
-    auto d = Disc();
-    const auto& coord = d->Coord();
-
-    // Query fields names requested by user
-    auto nodefieldnames = numericFieldNames( tk::Centering::NODE );
-
-    // Collect field output from numerical solution requested by user
-    conserved( m_u, Disc()->Vol() );
-    auto nodefields = numericFieldOutput( m_u, tk::Centering::NODE,
-      g_cgpde[Disc()->MeshId()].OutVarFn(), m_u );
-    volumetric( m_u, Disc()->Vol() );
-
-    //! Lambda to put in a field for output if not empty
-    auto add_node_field = [&]( const auto& name, const auto& field ){
-      if (not field.empty()) {
-        nodefieldnames.push_back( name );
-        nodefields.push_back( field );
-      }
-    };
-
-    // Output mesh velocity if ALE is enabled
-    if (g_inputdeck.get< tag::ale, tag::ale >()) {
-      const auto& w = d->meshvel();
-      add_node_field( "x-mesh-velocity", w.extract_comp(0) );
-      add_node_field( "y-mesh-velocity", w.extract_comp(1) );
-      add_node_field( "z-mesh-velocity", w.extract_comp(2) );
-      add_node_field( "volume", d->Vol() );
-    }
-
-    // Collect field output names for analytical solutions
-    analyticFieldNames( g_cgpde[d->MeshId()], tk::Centering::NODE,
-      nodefieldnames );
-
-    // Collect field output from analytical solutions (if exist)
-    analyticFieldOutput( g_cgpde[d->MeshId()], tk::Centering::NODE, coord[0],
-      coord[1], coord[2], d->T(), nodefields );
-
-    // Query and collect nodal block and surface field names from PDEs integrated
-    std::vector< std::string > nodesurfnames;
-    auto sn = g_cgpde[d->MeshId()].surfNames();
-    nodesurfnames.insert( end(nodesurfnames), begin(sn), end(sn) );
-
-    // Collect nodal block and surface field solution
-    std::vector< std::vector< tk::real > > nodesurfs;
-    conserved( m_u, Disc()->Vol() );
-    auto so = g_cgpde[d->MeshId()].surfOutput( tk::bfacenodes(m_bface,
-      m_triinpoel), m_u );
-    nodesurfs.insert( end(nodesurfs), begin(so), end(so) );
-
-    // Collect elemental block and surface field names from PDEs integrated
-    auto elemsurfnames = nodesurfnames;
-
-    // Collect elemental block and surface field solution
-    std::vector< std::vector< tk::real > > elemsurfs;
-    auto eso = g_cgpde[d->MeshId()].elemSurfOutput( m_bface, m_triinpoel, m_u );
-    elemsurfs.insert( end(elemsurfs), begin(eso), end(eso) );
-
-    // Query refinement data
-    auto dtref = g_inputdeck.get< tag::amr, tag::dtref >();
-
-    std::tuple< std::vector< std::string >,
-                std::vector< std::vector< tk::real > >,
-                std::vector< std::string >,
-                std::vector< std::vector< tk::real > > > r;
-    if (dtref) r = d->Ref()->refinementFields();
-    volumetric( m_u, Disc()->Vol() );
-
-    auto& refinement_elemfieldnames = std::get< 0 >( r );
-    auto& refinement_elemfields = std::get< 1 >( r );
-    auto& refinement_nodefieldnames = std::get< 2 >( r );
-    auto& refinement_nodefields = std::get< 3 >( r );
-
-    nodefieldnames.insert( end(nodefieldnames),
-      begin(refinement_nodefieldnames), end(refinement_nodefieldnames) );
-    nodefields.insert( end(nodefields),
-      begin(refinement_nodefields), end(refinement_nodefields) );
-
-    auto elemfieldnames = std::move(refinement_elemfieldnames);
-    auto elemfields = std::move(refinement_elemfields);
-
-    Assert( elemfieldnames.size() == elemfields.size(), "Size mismatch" );
-    Assert( nodefieldnames.size() == nodefields.size(), "Size mismatch" );
-
-    // Send mesh and fields data (solution dump) for output to file
-    d->write( d->Inpoel(), coord, m_bface, tk::remap(m_bnode,d->Lid()),
-              m_triinpoel, elemfieldnames, nodefieldnames, elemsurfnames,
-              nodesurfnames, elemfields, nodefields, elemsurfs, nodesurfs, c );
-
-  }
-}
-
-void
-ALECG::out()
-// *****************************************************************************
-// Output mesh field data
-// *****************************************************************************
-{
-  auto d = Disc();
-
-  // Output time history
-  if (d->histiter() or d->histtime() or d->histrange()) {
-    std::vector< std::vector< tk::real > > hist;
-    conserved( m_u, Disc()->Vol() );
-    auto h = g_cgpde[d->MeshId()].histOutput( d->Hist(), d->Inpoel(), m_u );
-    hist.insert( end(hist), begin(h), end(h) );
-    volumetric( m_u, Disc()->Vol() );
-    d->history( std::move(hist) );
-  }
-
-  // Output field data
-  if (d->fielditer() or d->fieldtime() or d->fieldrange() or m_finished)
-    writeFields( CkCallback(CkIndex_ALECG::step(), thisProxy[thisIndex]) );
-  else
-    step();
-}
-
-void
-ALECG::evalLB( int nrestart )
-// *****************************************************************************
-// Evaluate whether to do load balancing
-//! \param[in] nrestart Number of times restarted
-// *****************************************************************************
-{
-  auto d = Disc();
-
-  // Detect if just returned from a checkpoint and if so, zero timers and
-  // finished flag
-  if (d->restarted( nrestart )) m_finished = 0;
-
-  const auto lbfreq = g_inputdeck.get< tag::cmd, tag::lbfreq >();
-  const auto nonblocking = g_inputdeck.get< tag::cmd, tag::nonblocking >();
-
-  // Load balancing if user frequency is reached or after the second time-step
-  if ( (d->It()) % lbfreq == 0 || d->It() == 2 ) {
-
-    AtSync();
-    if (nonblocking) next();
-
-  } else {
-
-    next();
-
-  }
-}
-
-void
-ALECG::evalRestart()
-// *****************************************************************************
-// Evaluate whether to save checkpoint/restart
-// *****************************************************************************
-{
-  auto d = Disc();
-
-  const auto rsfreq = g_inputdeck.get< tag::cmd, tag::rsfreq >();
-  const auto benchmark = g_inputdeck.get< tag::cmd, tag::benchmark >();
-
-  if (not benchmark and not (d->It() % rsfreq)) {
-
-    std::vector< std::size_t > meshdata{ /* finished = */ 0, d->MeshId() };
-    contribute( meshdata, CkReduction::nop,
-      CkCallback(CkReductionTarget(Transporter,checkpoint), d->Tr()) );
-
-  } else {
-
-    evalLB( /* nrestart = */ -1 );
-
-  }
-}
-
-void
-ALECG::step()
-// *****************************************************************************
-// Evaluate whether to continue with next time step
-// *****************************************************************************
-{
-  auto d = Disc();
-
-  // Output one-liner status report to screen
-  d->status();
-  // Reset Runge-Kutta stage counter
-  m_stage = 0;
-
-  if (not m_finished) {
-
-    evalRestart();
-
-  } else {
-
-    auto meshid = d->MeshId();
-    d->contribute( sizeof(std::size_t), &meshid, CkReduction::nop,
-                   CkCallback(CkReductionTarget(Transporter,finish), d->Tr()) );
-
-  }
-}
-
-#include "NoWarning/alecg.def.h"
+#include <brigand/algorithms/for_each.hpp>
+
+#include "Tags.hpp"
+#include "CartesianProduct.hpp"
+#include "PDEFactory.hpp"
+#include "Inciter/Options/PDE.hpp"
+#include "ContainerUtil.hpp"
+#include "ConfigureTransport.hpp"
+#include "Transport/Physics/CG.hpp"
+#include "Transport/Physics/DG.hpp"
+#include "Transport/CGTransport.hpp"
+#include "Transport/DGTransport.hpp"
+#include "Transport/Problem.hpp"
+
+namespace inciter {
+
+void
+registerTransport( CGFactory& cf,
+                   DGFactory& df,
+                   std::set< ctr::PDEType >& cgt,
+                   std::set< ctr::PDEType >& dgt )
+// *****************************************************************************
+// Register transport PDE into PDE factory
+//! \param[in,out] cf Continuous Galerkin PDE factory to register to
+//! \param[in,out] df Discontinuous Galerkin PDE factory to register to
+//! \param[in,out] cgt Counters for equation types registered into CG factory
+//! \param[in,out] dgt Counters for equation types registered into DG factory
+// *****************************************************************************
+{
+  // Construct vector of vectors for all possible policies
+  using CGTransportPolicies =
+    tk::cartesian_product< cg::TransportPhysics, TransportProblems >;
+  // Register PDEs for all combinations of policies
+  brigand::for_each< CGTransportPolicies >(
+    registerCG< cg::Transport >( cf, cgt, ctr::PDEType::TRANSPORT ) );
+
+  // Construct vector of vectors for all possible policies
+  using DGTransportPolicies =
+    tk::cartesian_product< dg::TransportPhysics, TransportProblems >;
+  // Register PDEs for all combinations of policies
+  brigand::for_each< DGTransportPolicies >(
+    registerDG< dg::Transport >( df, dgt, ctr::PDEType::TRANSPORT ) );
+}
+
+std::vector< std::pair< std::string, std::string > >
+infoTransport( std::map< ctr::PDEType, tk::ncomp_t >& cnt )
+// *****************************************************************************
+//  Return information on the transport PDE
+//! \param[inout] cnt std::map of counters for all PDE types
+//! \return vector of string pairs describing the PDE configuration
+// *****************************************************************************
+{
+  using tk::parameters;
+  using eq = tag::transport;
+
+  auto c = ++cnt[ ctr::PDEType::TRANSPORT ];       // count eqs
+  --c;  // used to index vectors starting with 0<--- Variable 'c' is assigned a value that is never used.
+
+  std::vector< std::pair< std::string, std::string > > nfo;
+
+  nfo.emplace_back( ctr::PDE().name( ctr::PDEType::TRANSPORT ), "" );
+
+  nfo.emplace_back( "problem", ctr::Problem().name(
+    g_inputdeck.get< eq, tag::problem >() ) );
+
+  auto intsharp = g_inputdeck.get< eq, tag::intsharp >();
+  nfo.emplace_back( "interface sharpening", std::to_string( intsharp ) );
+
+  auto ncomp = g_inputdeck.get< tag::ncomp >();
+  nfo.emplace_back( "number of components", std::to_string( ncomp ) );
+
+  const auto& bc = g_inputdeck.get< tag::bc >();
+  for (const auto& ib : bc) {
+    const auto& bcdir = ib.get< tag::dirichlet >();
+    if (!bcdir.empty())
+      nfo.emplace_back( "Dirichlet boundary [" + std::to_string( ncomp ) + "]",
+        parameters( bcdir ) );
+
+    const auto& bcsym = ib.get< tag::symmetry >();
+    if (!bcsym.empty())
+      nfo.emplace_back( "Symmetry boundary [" + std::to_string( ncomp ) + "]",
+        parameters( bcsym ) );
+
+    const auto& bcinlet =
+      ib.get< tag::inlet >();
+    if (!bcinlet.empty())
+      nfo.emplace_back( "Inlet boundary [" + std::to_string( ncomp ) + "]",
+        parameters( bcinlet ) );
+
+    const auto& bcoutlet =
+      ib.get< tag::outlet >();
+    if (!bcoutlet.empty())
+      nfo.emplace_back( "Outlet boundary [" + std::to_string( ncomp ) + "]",
+        parameters( bcoutlet ) );
+
+    const auto& bcextrapolate =
+      ib.get< tag::extrapolate >();
+    if (!bcextrapolate.empty())
+      nfo.emplace_back( "Symmetry boundary [" + std::to_string( ncomp ) + "]",
+        parameters( bcextrapolate ) );
+  }
+
+  return nfo;
+}
+
+}  // inciter::
 
diff --git a/Release/cppcheck/58.html b/Release/cppcheck/58.html index 3f1a6e6a3f71..3080ae77b7ff 100644 --- a/Release/cppcheck/58.html +++ b/Release/cppcheck/58.html @@ -152,2119 +152,1807 @@
- - - + + - - + + diff --git a/Release/test_coverage/Control/CommonGrammar.hpp.func-sort-c.html b/Release/test_coverage/Control/CommonGrammar.hpp.func-sort-c.html index 9925d3e6d4c8..e4a0f6a20e85 100644 --- a/Release/test_coverage/Control/CommonGrammar.hpp.func-sort-c.html +++ b/Release/test_coverage/Control/CommonGrammar.hpp.func-sort-c.html @@ -33,7 +33,7 @@ - + diff --git a/Release/test_coverage/Control/CommonGrammar.hpp.func.html b/Release/test_coverage/Control/CommonGrammar.hpp.func.html index e0efb10e2634..3ea843fb382d 100644 --- a/Release/test_coverage/Control/CommonGrammar.hpp.func.html +++ b/Release/test_coverage/Control/CommonGrammar.hpp.func.html @@ -33,7 +33,7 @@ - + diff --git a/Release/test_coverage/Control/CommonGrammar.hpp.gcov.html b/Release/test_coverage/Control/CommonGrammar.hpp.gcov.html index 03cdabb978fc..4e79ee909021 100644 --- a/Release/test_coverage/Control/CommonGrammar.hpp.gcov.html +++ b/Release/test_coverage/Control/CommonGrammar.hpp.gcov.html @@ -33,7 +33,7 @@ - + diff --git a/Release/test_coverage/Control/HelpFactory.hpp.func-sort-c.html b/Release/test_coverage/Control/HelpFactory.hpp.func-sort-c.html index a749eb75a028..a0525d117586 100644 --- a/Release/test_coverage/Control/HelpFactory.hpp.func-sort-c.html +++ b/Release/test_coverage/Control/HelpFactory.hpp.func-sort-c.html @@ -33,7 +33,7 @@ - + diff --git a/Release/test_coverage/Control/HelpFactory.hpp.func.html b/Release/test_coverage/Control/HelpFactory.hpp.func.html index c8fc821f1beb..d15eabc56bc3 100644 --- a/Release/test_coverage/Control/HelpFactory.hpp.func.html +++ b/Release/test_coverage/Control/HelpFactory.hpp.func.html @@ -33,7 +33,7 @@ - + diff --git a/Release/test_coverage/Control/HelpFactory.hpp.gcov.html b/Release/test_coverage/Control/HelpFactory.hpp.gcov.html index ff8f9e5571bf..bbe98e1f3fa0 100644 --- a/Release/test_coverage/Control/HelpFactory.hpp.gcov.html +++ b/Release/test_coverage/Control/HelpFactory.hpp.gcov.html @@ -33,7 +33,7 @@ - + diff --git a/Release/test_coverage/Control/Inciter/CmdLine/CmdLine.hpp.func-sort-c.html b/Release/test_coverage/Control/Inciter/CmdLine/CmdLine.hpp.func-sort-c.html index af51625b33d5..e786a3326803 100644 --- a/Release/test_coverage/Control/Inciter/CmdLine/CmdLine.hpp.func-sort-c.html +++ b/Release/test_coverage/Control/Inciter/CmdLine/CmdLine.hpp.func-sort-c.html @@ -33,7 +33,7 @@ - + diff --git a/Release/test_coverage/Control/Inciter/CmdLine/CmdLine.hpp.func.html b/Release/test_coverage/Control/Inciter/CmdLine/CmdLine.hpp.func.html index d2bd002347fa..075a1478b900 100644 --- a/Release/test_coverage/Control/Inciter/CmdLine/CmdLine.hpp.func.html +++ b/Release/test_coverage/Control/Inciter/CmdLine/CmdLine.hpp.func.html @@ -33,7 +33,7 @@ - + diff --git a/Release/test_coverage/Control/Inciter/CmdLine/CmdLine.hpp.gcov.html b/Release/test_coverage/Control/Inciter/CmdLine/CmdLine.hpp.gcov.html index 764b7617e5c0..3ee8440930f8 100644 --- a/Release/test_coverage/Control/Inciter/CmdLine/CmdLine.hpp.gcov.html +++ b/Release/test_coverage/Control/Inciter/CmdLine/CmdLine.hpp.gcov.html @@ -33,7 +33,7 @@ - + diff --git a/Release/test_coverage/Control/Inciter/CmdLine/Parser.cpp.func-sort-c.html b/Release/test_coverage/Control/Inciter/CmdLine/Parser.cpp.func-sort-c.html index 2aa926d90f78..30fc169ac8ed 100644 --- a/Release/test_coverage/Control/Inciter/CmdLine/Parser.cpp.func-sort-c.html +++ b/Release/test_coverage/Control/Inciter/CmdLine/Parser.cpp.func-sort-c.html @@ -33,7 +33,7 @@ - + diff --git a/Release/test_coverage/Control/Inciter/CmdLine/Parser.cpp.func.html b/Release/test_coverage/Control/Inciter/CmdLine/Parser.cpp.func.html index 5d03b367a8b4..92b0f0a26637 100644 --- a/Release/test_coverage/Control/Inciter/CmdLine/Parser.cpp.func.html +++ b/Release/test_coverage/Control/Inciter/CmdLine/Parser.cpp.func.html @@ -33,7 +33,7 @@ - + diff --git a/Release/test_coverage/Control/Inciter/CmdLine/Parser.cpp.gcov.html b/Release/test_coverage/Control/Inciter/CmdLine/Parser.cpp.gcov.html index 3715640aca97..e0b944d8b138 100644 --- a/Release/test_coverage/Control/Inciter/CmdLine/Parser.cpp.gcov.html +++ b/Release/test_coverage/Control/Inciter/CmdLine/Parser.cpp.gcov.html @@ -33,7 +33,7 @@ - + diff --git a/Release/test_coverage/Control/Inciter/CmdLine/Parser.hpp.func-sort-c.html b/Release/test_coverage/Control/Inciter/CmdLine/Parser.hpp.func-sort-c.html index c9c411b71ba9..88e26fe0a687 100644 --- a/Release/test_coverage/Control/Inciter/CmdLine/Parser.hpp.func-sort-c.html +++ b/Release/test_coverage/Control/Inciter/CmdLine/Parser.hpp.func-sort-c.html @@ -33,7 +33,7 @@ - + diff --git a/Release/test_coverage/Control/Inciter/CmdLine/Parser.hpp.func.html b/Release/test_coverage/Control/Inciter/CmdLine/Parser.hpp.func.html index 39cfd32468c4..28bcce24c7ae 100644 --- a/Release/test_coverage/Control/Inciter/CmdLine/Parser.hpp.func.html +++ b/Release/test_coverage/Control/Inciter/CmdLine/Parser.hpp.func.html @@ -33,7 +33,7 @@ - + diff --git a/Release/test_coverage/Control/Inciter/CmdLine/Parser.hpp.gcov.html b/Release/test_coverage/Control/Inciter/CmdLine/Parser.hpp.gcov.html index b1dfc4d82cd3..00404f0f6f2e 100644 --- a/Release/test_coverage/Control/Inciter/CmdLine/Parser.hpp.gcov.html +++ b/Release/test_coverage/Control/Inciter/CmdLine/Parser.hpp.gcov.html @@ -33,7 +33,7 @@ - + diff --git a/Release/test_coverage/Control/Inciter/CmdLine/index-sort-b.html b/Release/test_coverage/Control/Inciter/CmdLine/index-sort-b.html index 29cf18eb77a6..e71cccd46b98 100644 --- a/Release/test_coverage/Control/Inciter/CmdLine/index-sort-b.html +++ b/Release/test_coverage/Control/Inciter/CmdLine/index-sort-b.html @@ -33,7 +33,7 @@ - + diff --git a/Release/test_coverage/Control/Inciter/CmdLine/index-sort-f.html b/Release/test_coverage/Control/Inciter/CmdLine/index-sort-f.html index 85501eb3d982..bcacacb47f4d 100644 --- a/Release/test_coverage/Control/Inciter/CmdLine/index-sort-f.html +++ b/Release/test_coverage/Control/Inciter/CmdLine/index-sort-f.html @@ -33,7 +33,7 @@ - + diff --git a/Release/test_coverage/Control/Inciter/CmdLine/index-sort-l.html b/Release/test_coverage/Control/Inciter/CmdLine/index-sort-l.html index 95a9c32ffd98..a32430ceb471 100644 --- a/Release/test_coverage/Control/Inciter/CmdLine/index-sort-l.html +++ b/Release/test_coverage/Control/Inciter/CmdLine/index-sort-l.html @@ -33,7 +33,7 @@ - + diff --git a/Release/test_coverage/Control/Inciter/CmdLine/index.html b/Release/test_coverage/Control/Inciter/CmdLine/index.html index 9dc6b704e06e..ecbeeb51e298 100644 --- a/Release/test_coverage/Control/Inciter/CmdLine/index.html +++ b/Release/test_coverage/Control/Inciter/CmdLine/index.html @@ -33,7 +33,7 @@ - + diff --git a/Release/test_coverage/Control/Inciter/InputDeck/InputDeck.hpp.func-sort-c.html b/Release/test_coverage/Control/Inciter/InputDeck/InputDeck.hpp.func-sort-c.html index 8a968272a834..ac021aa81cee 100644 --- a/Release/test_coverage/Control/Inciter/InputDeck/InputDeck.hpp.func-sort-c.html +++ b/Release/test_coverage/Control/Inciter/InputDeck/InputDeck.hpp.func-sort-c.html @@ -33,7 +33,7 @@ - + diff --git a/Release/test_coverage/Control/Inciter/InputDeck/InputDeck.hpp.func.html b/Release/test_coverage/Control/Inciter/InputDeck/InputDeck.hpp.func.html index 15321d3659cc..987ec80cf733 100644 --- a/Release/test_coverage/Control/Inciter/InputDeck/InputDeck.hpp.func.html +++ b/Release/test_coverage/Control/Inciter/InputDeck/InputDeck.hpp.func.html @@ -33,7 +33,7 @@ - + diff --git a/Release/test_coverage/Control/Inciter/InputDeck/InputDeck.hpp.gcov.html b/Release/test_coverage/Control/Inciter/InputDeck/InputDeck.hpp.gcov.html index a9ba726a94cb..7d649c4ae7de 100644 --- a/Release/test_coverage/Control/Inciter/InputDeck/InputDeck.hpp.gcov.html +++ b/Release/test_coverage/Control/Inciter/InputDeck/InputDeck.hpp.gcov.html @@ -33,7 +33,7 @@ - + diff --git a/Release/test_coverage/Control/Inciter/InputDeck/LuaParser.cpp.func-sort-c.html b/Release/test_coverage/Control/Inciter/InputDeck/LuaParser.cpp.func-sort-c.html index 598dd1d8bc6e..d2a502f50398 100644 --- a/Release/test_coverage/Control/Inciter/InputDeck/LuaParser.cpp.func-sort-c.html +++ b/Release/test_coverage/Control/Inciter/InputDeck/LuaParser.cpp.func-sort-c.html @@ -33,7 +33,7 @@ - + diff --git a/Release/test_coverage/Control/Inciter/InputDeck/LuaParser.cpp.func.html b/Release/test_coverage/Control/Inciter/InputDeck/LuaParser.cpp.func.html index 562026dd90ef..ad6c952b911c 100644 --- a/Release/test_coverage/Control/Inciter/InputDeck/LuaParser.cpp.func.html +++ b/Release/test_coverage/Control/Inciter/InputDeck/LuaParser.cpp.func.html @@ -33,7 +33,7 @@ - + diff --git a/Release/test_coverage/Control/Inciter/InputDeck/LuaParser.cpp.gcov.html b/Release/test_coverage/Control/Inciter/InputDeck/LuaParser.cpp.gcov.html index 8e97dc14f051..3a5d08538afb 100644 --- a/Release/test_coverage/Control/Inciter/InputDeck/LuaParser.cpp.gcov.html +++ b/Release/test_coverage/Control/Inciter/InputDeck/LuaParser.cpp.gcov.html @@ -33,7 +33,7 @@ - + diff --git a/Release/test_coverage/Control/Inciter/InputDeck/LuaParser.hpp.func-sort-c.html b/Release/test_coverage/Control/Inciter/InputDeck/LuaParser.hpp.func-sort-c.html index a88667c31f45..8b6bde1aac55 100644 --- a/Release/test_coverage/Control/Inciter/InputDeck/LuaParser.hpp.func-sort-c.html +++ b/Release/test_coverage/Control/Inciter/InputDeck/LuaParser.hpp.func-sort-c.html @@ -33,7 +33,7 @@ - + diff --git a/Release/test_coverage/Control/Inciter/InputDeck/LuaParser.hpp.func.html b/Release/test_coverage/Control/Inciter/InputDeck/LuaParser.hpp.func.html index a10977898054..d64ebdb3156f 100644 --- a/Release/test_coverage/Control/Inciter/InputDeck/LuaParser.hpp.func.html +++ b/Release/test_coverage/Control/Inciter/InputDeck/LuaParser.hpp.func.html @@ -33,7 +33,7 @@ - + diff --git a/Release/test_coverage/Control/Inciter/InputDeck/LuaParser.hpp.gcov.html b/Release/test_coverage/Control/Inciter/InputDeck/LuaParser.hpp.gcov.html index 71247b647acb..c0e219813316 100644 --- a/Release/test_coverage/Control/Inciter/InputDeck/LuaParser.hpp.gcov.html +++ b/Release/test_coverage/Control/Inciter/InputDeck/LuaParser.hpp.gcov.html @@ -33,7 +33,7 @@ - + diff --git a/Release/test_coverage/Control/Inciter/InputDeck/index-sort-b.html b/Release/test_coverage/Control/Inciter/InputDeck/index-sort-b.html index 9a9563e5d091..bf8aebc14ca9 100644 --- a/Release/test_coverage/Control/Inciter/InputDeck/index-sort-b.html +++ b/Release/test_coverage/Control/Inciter/InputDeck/index-sort-b.html @@ -33,7 +33,7 @@ - + diff --git a/Release/test_coverage/Control/Inciter/InputDeck/index-sort-f.html b/Release/test_coverage/Control/Inciter/InputDeck/index-sort-f.html index ad79b134cfbf..adeca0257c62 100644 --- a/Release/test_coverage/Control/Inciter/InputDeck/index-sort-f.html +++ b/Release/test_coverage/Control/Inciter/InputDeck/index-sort-f.html @@ -33,7 +33,7 @@ - + diff --git a/Release/test_coverage/Control/Inciter/InputDeck/index-sort-l.html b/Release/test_coverage/Control/Inciter/InputDeck/index-sort-l.html index 8347271e357a..a9b1e1b1a721 100644 --- a/Release/test_coverage/Control/Inciter/InputDeck/index-sort-l.html +++ b/Release/test_coverage/Control/Inciter/InputDeck/index-sort-l.html @@ -33,7 +33,7 @@ - + diff --git a/Release/test_coverage/Control/Inciter/InputDeck/index.html b/Release/test_coverage/Control/Inciter/InputDeck/index.html index ced59d1649e2..22568b19bf0b 100644 --- a/Release/test_coverage/Control/Inciter/InputDeck/index.html +++ b/Release/test_coverage/Control/Inciter/InputDeck/index.html @@ -33,7 +33,7 @@ - + diff --git a/Release/test_coverage/Control/Inciter/Options/AMRError.hpp.func-sort-c.html b/Release/test_coverage/Control/Inciter/Options/AMRError.hpp.func-sort-c.html index 5ae106770f27..af0da08f9189 100644 --- a/Release/test_coverage/Control/Inciter/Options/AMRError.hpp.func-sort-c.html +++ b/Release/test_coverage/Control/Inciter/Options/AMRError.hpp.func-sort-c.html @@ -33,7 +33,7 @@ - + diff --git a/Release/test_coverage/Control/Inciter/Options/AMRError.hpp.func.html b/Release/test_coverage/Control/Inciter/Options/AMRError.hpp.func.html index 3cf77b8873ea..7a616c1b8d2d 100644 --- a/Release/test_coverage/Control/Inciter/Options/AMRError.hpp.func.html +++ b/Release/test_coverage/Control/Inciter/Options/AMRError.hpp.func.html @@ -33,7 +33,7 @@ - + diff --git a/Release/test_coverage/Control/Inciter/Options/AMRError.hpp.gcov.html b/Release/test_coverage/Control/Inciter/Options/AMRError.hpp.gcov.html index 08f3daded203..a2ec8a3957ea 100644 --- a/Release/test_coverage/Control/Inciter/Options/AMRError.hpp.gcov.html +++ b/Release/test_coverage/Control/Inciter/Options/AMRError.hpp.gcov.html @@ -33,7 +33,7 @@ - + diff --git a/Release/test_coverage/Control/Inciter/Options/AMRInitial.hpp.func-sort-c.html b/Release/test_coverage/Control/Inciter/Options/AMRInitial.hpp.func-sort-c.html index f00d25d91b74..12aa72febd9e 100644 --- a/Release/test_coverage/Control/Inciter/Options/AMRInitial.hpp.func-sort-c.html +++ b/Release/test_coverage/Control/Inciter/Options/AMRInitial.hpp.func-sort-c.html @@ -33,7 +33,7 @@ - + diff --git a/Release/test_coverage/Control/Inciter/Options/AMRInitial.hpp.func.html b/Release/test_coverage/Control/Inciter/Options/AMRInitial.hpp.func.html index 3da24297fd4c..891ae9139d96 100644 --- a/Release/test_coverage/Control/Inciter/Options/AMRInitial.hpp.func.html +++ b/Release/test_coverage/Control/Inciter/Options/AMRInitial.hpp.func.html @@ -33,7 +33,7 @@ - + diff --git a/Release/test_coverage/Control/Inciter/Options/AMRInitial.hpp.gcov.html b/Release/test_coverage/Control/Inciter/Options/AMRInitial.hpp.gcov.html index c4b38173e72b..ca384a7a98cf 100644 --- a/Release/test_coverage/Control/Inciter/Options/AMRInitial.hpp.gcov.html +++ b/Release/test_coverage/Control/Inciter/Options/AMRInitial.hpp.gcov.html @@ -33,7 +33,7 @@ - + diff --git a/Release/test_coverage/Control/Inciter/Options/Flux.hpp.func-sort-c.html b/Release/test_coverage/Control/Inciter/Options/Flux.hpp.func-sort-c.html index de330055edc5..8ca058d56b41 100644 --- a/Release/test_coverage/Control/Inciter/Options/Flux.hpp.func-sort-c.html +++ b/Release/test_coverage/Control/Inciter/Options/Flux.hpp.func-sort-c.html @@ -33,7 +33,7 @@ - + diff --git a/Release/test_coverage/Control/Inciter/Options/Flux.hpp.func.html b/Release/test_coverage/Control/Inciter/Options/Flux.hpp.func.html index 1e03be06d08d..be7d09615bc3 100644 --- a/Release/test_coverage/Control/Inciter/Options/Flux.hpp.func.html +++ b/Release/test_coverage/Control/Inciter/Options/Flux.hpp.func.html @@ -33,7 +33,7 @@ - + diff --git a/Release/test_coverage/Control/Inciter/Options/Flux.hpp.gcov.html b/Release/test_coverage/Control/Inciter/Options/Flux.hpp.gcov.html index 530e2f26f4d3..66c501ccfe8a 100644 --- a/Release/test_coverage/Control/Inciter/Options/Flux.hpp.gcov.html +++ b/Release/test_coverage/Control/Inciter/Options/Flux.hpp.gcov.html @@ -33,7 +33,7 @@ - + diff --git a/Release/test_coverage/Control/Inciter/Options/Initiate.hpp.func-sort-c.html b/Release/test_coverage/Control/Inciter/Options/Initiate.hpp.func-sort-c.html index 3ac1b43c16d3..9b26d853097d 100644 --- a/Release/test_coverage/Control/Inciter/Options/Initiate.hpp.func-sort-c.html +++ b/Release/test_coverage/Control/Inciter/Options/Initiate.hpp.func-sort-c.html @@ -33,7 +33,7 @@ - + diff --git a/Release/test_coverage/Control/Inciter/Options/Initiate.hpp.func.html b/Release/test_coverage/Control/Inciter/Options/Initiate.hpp.func.html index eec10fbf0587..cabd0cd5e91c 100644 --- a/Release/test_coverage/Control/Inciter/Options/Initiate.hpp.func.html +++ b/Release/test_coverage/Control/Inciter/Options/Initiate.hpp.func.html @@ -33,7 +33,7 @@ - + diff --git a/Release/test_coverage/Control/Inciter/Options/Initiate.hpp.gcov.html b/Release/test_coverage/Control/Inciter/Options/Initiate.hpp.gcov.html index 7217a050a8d6..a44c0a671b01 100644 --- a/Release/test_coverage/Control/Inciter/Options/Initiate.hpp.gcov.html +++ b/Release/test_coverage/Control/Inciter/Options/Initiate.hpp.gcov.html @@ -33,7 +33,7 @@ - + diff --git a/Release/test_coverage/Control/Inciter/Options/Limiter.hpp.func-sort-c.html b/Release/test_coverage/Control/Inciter/Options/Limiter.hpp.func-sort-c.html index 6708f0b1b6e2..5803622374ab 100644 --- a/Release/test_coverage/Control/Inciter/Options/Limiter.hpp.func-sort-c.html +++ b/Release/test_coverage/Control/Inciter/Options/Limiter.hpp.func-sort-c.html @@ -33,7 +33,7 @@ - + diff --git a/Release/test_coverage/Control/Inciter/Options/Limiter.hpp.func.html b/Release/test_coverage/Control/Inciter/Options/Limiter.hpp.func.html index b547ec2011cc..34e175446257 100644 --- a/Release/test_coverage/Control/Inciter/Options/Limiter.hpp.func.html +++ b/Release/test_coverage/Control/Inciter/Options/Limiter.hpp.func.html @@ -33,7 +33,7 @@ - + diff --git a/Release/test_coverage/Control/Inciter/Options/Limiter.hpp.gcov.html b/Release/test_coverage/Control/Inciter/Options/Limiter.hpp.gcov.html index 6caefb735b41..3d84ca0c5c14 100644 --- a/Release/test_coverage/Control/Inciter/Options/Limiter.hpp.gcov.html +++ b/Release/test_coverage/Control/Inciter/Options/Limiter.hpp.gcov.html @@ -33,7 +33,7 @@ - + diff --git a/Release/test_coverage/Control/Inciter/Options/Material.hpp.func-sort-c.html b/Release/test_coverage/Control/Inciter/Options/Material.hpp.func-sort-c.html index 8cc0d89bca90..db40cdd45c8f 100644 --- a/Release/test_coverage/Control/Inciter/Options/Material.hpp.func-sort-c.html +++ b/Release/test_coverage/Control/Inciter/Options/Material.hpp.func-sort-c.html @@ -33,7 +33,7 @@ - + diff --git a/Release/test_coverage/Control/Inciter/Options/Material.hpp.func.html b/Release/test_coverage/Control/Inciter/Options/Material.hpp.func.html index edc825f74eba..1c456bb6150f 100644 --- a/Release/test_coverage/Control/Inciter/Options/Material.hpp.func.html +++ b/Release/test_coverage/Control/Inciter/Options/Material.hpp.func.html @@ -33,7 +33,7 @@ - + diff --git a/Release/test_coverage/Control/Inciter/Options/Material.hpp.gcov.html b/Release/test_coverage/Control/Inciter/Options/Material.hpp.gcov.html index 43f9bac5a33f..a62646af7bb9 100644 --- a/Release/test_coverage/Control/Inciter/Options/Material.hpp.gcov.html +++ b/Release/test_coverage/Control/Inciter/Options/Material.hpp.gcov.html @@ -33,7 +33,7 @@ - + diff --git a/Release/test_coverage/Control/Inciter/Options/MeshVelocity.hpp.func-sort-c.html b/Release/test_coverage/Control/Inciter/Options/MeshVelocity.hpp.func-sort-c.html index 06c21853c12b..9cdef3e17079 100644 --- a/Release/test_coverage/Control/Inciter/Options/MeshVelocity.hpp.func-sort-c.html +++ b/Release/test_coverage/Control/Inciter/Options/MeshVelocity.hpp.func-sort-c.html @@ -33,7 +33,7 @@ - + diff --git a/Release/test_coverage/Control/Inciter/Options/MeshVelocity.hpp.func.html b/Release/test_coverage/Control/Inciter/Options/MeshVelocity.hpp.func.html index 2b2de56cc275..4c2a37db9f63 100644 --- a/Release/test_coverage/Control/Inciter/Options/MeshVelocity.hpp.func.html +++ b/Release/test_coverage/Control/Inciter/Options/MeshVelocity.hpp.func.html @@ -33,7 +33,7 @@ - + diff --git a/Release/test_coverage/Control/Inciter/Options/MeshVelocity.hpp.gcov.html b/Release/test_coverage/Control/Inciter/Options/MeshVelocity.hpp.gcov.html index 63338b15917f..f721d5466624 100644 --- a/Release/test_coverage/Control/Inciter/Options/MeshVelocity.hpp.gcov.html +++ b/Release/test_coverage/Control/Inciter/Options/MeshVelocity.hpp.gcov.html @@ -33,7 +33,7 @@ - + diff --git a/Release/test_coverage/Control/Inciter/Options/MeshVelocitySmoother.hpp.func-sort-c.html b/Release/test_coverage/Control/Inciter/Options/MeshVelocitySmoother.hpp.func-sort-c.html index f416e82668d2..019936e5dea2 100644 --- a/Release/test_coverage/Control/Inciter/Options/MeshVelocitySmoother.hpp.func-sort-c.html +++ b/Release/test_coverage/Control/Inciter/Options/MeshVelocitySmoother.hpp.func-sort-c.html @@ -33,7 +33,7 @@ - + diff --git a/Release/test_coverage/Control/Inciter/Options/MeshVelocitySmoother.hpp.func.html b/Release/test_coverage/Control/Inciter/Options/MeshVelocitySmoother.hpp.func.html index 70ba1a755d91..98511bd7657b 100644 --- a/Release/test_coverage/Control/Inciter/Options/MeshVelocitySmoother.hpp.func.html +++ b/Release/test_coverage/Control/Inciter/Options/MeshVelocitySmoother.hpp.func.html @@ -33,7 +33,7 @@ - + diff --git a/Release/test_coverage/Control/Inciter/Options/MeshVelocitySmoother.hpp.gcov.html b/Release/test_coverage/Control/Inciter/Options/MeshVelocitySmoother.hpp.gcov.html index 349c33daa4c8..5cfe846bbe1e 100644 --- a/Release/test_coverage/Control/Inciter/Options/MeshVelocitySmoother.hpp.gcov.html +++ b/Release/test_coverage/Control/Inciter/Options/MeshVelocitySmoother.hpp.gcov.html @@ -33,7 +33,7 @@ - + diff --git a/Release/test_coverage/Control/Inciter/Options/PDE.hpp.func-sort-c.html b/Release/test_coverage/Control/Inciter/Options/PDE.hpp.func-sort-c.html index 0cfe715599f3..a0747ea49ca3 100644 --- a/Release/test_coverage/Control/Inciter/Options/PDE.hpp.func-sort-c.html +++ b/Release/test_coverage/Control/Inciter/Options/PDE.hpp.func-sort-c.html @@ -33,7 +33,7 @@ - + diff --git a/Release/test_coverage/Control/Inciter/Options/PDE.hpp.func.html b/Release/test_coverage/Control/Inciter/Options/PDE.hpp.func.html index ea6f967649bb..67ad6fe93dc1 100644 --- a/Release/test_coverage/Control/Inciter/Options/PDE.hpp.func.html +++ b/Release/test_coverage/Control/Inciter/Options/PDE.hpp.func.html @@ -33,7 +33,7 @@ - + diff --git a/Release/test_coverage/Control/Inciter/Options/PDE.hpp.gcov.html b/Release/test_coverage/Control/Inciter/Options/PDE.hpp.gcov.html index ddab7f544b7e..8aa74f4169c8 100644 --- a/Release/test_coverage/Control/Inciter/Options/PDE.hpp.gcov.html +++ b/Release/test_coverage/Control/Inciter/Options/PDE.hpp.gcov.html @@ -33,7 +33,7 @@ - + diff --git a/Release/test_coverage/Control/Inciter/Options/Physics.hpp.func-sort-c.html b/Release/test_coverage/Control/Inciter/Options/Physics.hpp.func-sort-c.html index 7f90e1a13b97..80c422118e30 100644 --- a/Release/test_coverage/Control/Inciter/Options/Physics.hpp.func-sort-c.html +++ b/Release/test_coverage/Control/Inciter/Options/Physics.hpp.func-sort-c.html @@ -33,7 +33,7 @@ - + diff --git a/Release/test_coverage/Control/Inciter/Options/Physics.hpp.func.html b/Release/test_coverage/Control/Inciter/Options/Physics.hpp.func.html index 6b8341b8ba1d..17bd0cdcf6ed 100644 --- a/Release/test_coverage/Control/Inciter/Options/Physics.hpp.func.html +++ b/Release/test_coverage/Control/Inciter/Options/Physics.hpp.func.html @@ -33,7 +33,7 @@ - + diff --git a/Release/test_coverage/Control/Inciter/Options/Physics.hpp.gcov.html b/Release/test_coverage/Control/Inciter/Options/Physics.hpp.gcov.html index 2bd12a42f4bd..9f3f59735d71 100644 --- a/Release/test_coverage/Control/Inciter/Options/Physics.hpp.gcov.html +++ b/Release/test_coverage/Control/Inciter/Options/Physics.hpp.gcov.html @@ -33,7 +33,7 @@ - + diff --git a/Release/test_coverage/Control/Inciter/Options/PrefIndicator.hpp.func-sort-c.html b/Release/test_coverage/Control/Inciter/Options/PrefIndicator.hpp.func-sort-c.html index fd353aa2bff7..a0aeedd5448c 100644 --- a/Release/test_coverage/Control/Inciter/Options/PrefIndicator.hpp.func-sort-c.html +++ b/Release/test_coverage/Control/Inciter/Options/PrefIndicator.hpp.func-sort-c.html @@ -33,7 +33,7 @@ - + diff --git a/Release/test_coverage/Control/Inciter/Options/PrefIndicator.hpp.func.html b/Release/test_coverage/Control/Inciter/Options/PrefIndicator.hpp.func.html index 4c627dcc3a6f..7b79370ef32a 100644 --- a/Release/test_coverage/Control/Inciter/Options/PrefIndicator.hpp.func.html +++ b/Release/test_coverage/Control/Inciter/Options/PrefIndicator.hpp.func.html @@ -33,7 +33,7 @@ - + diff --git a/Release/test_coverage/Control/Inciter/Options/PrefIndicator.hpp.gcov.html b/Release/test_coverage/Control/Inciter/Options/PrefIndicator.hpp.gcov.html index dc8789eaca1f..0f5f0f10c3a6 100644 --- a/Release/test_coverage/Control/Inciter/Options/PrefIndicator.hpp.gcov.html +++ b/Release/test_coverage/Control/Inciter/Options/PrefIndicator.hpp.gcov.html @@ -33,7 +33,7 @@ - + diff --git a/Release/test_coverage/Control/Inciter/Options/Problem.hpp.func-sort-c.html b/Release/test_coverage/Control/Inciter/Options/Problem.hpp.func-sort-c.html index 77849dc3d806..c224c9e27bb5 100644 --- a/Release/test_coverage/Control/Inciter/Options/Problem.hpp.func-sort-c.html +++ b/Release/test_coverage/Control/Inciter/Options/Problem.hpp.func-sort-c.html @@ -33,7 +33,7 @@ - + diff --git a/Release/test_coverage/Control/Inciter/Options/Problem.hpp.func.html b/Release/test_coverage/Control/Inciter/Options/Problem.hpp.func.html index 27286cea6de8..553c4bf484c1 100644 --- a/Release/test_coverage/Control/Inciter/Options/Problem.hpp.func.html +++ b/Release/test_coverage/Control/Inciter/Options/Problem.hpp.func.html @@ -33,7 +33,7 @@ - + diff --git a/Release/test_coverage/Control/Inciter/Options/Problem.hpp.gcov.html b/Release/test_coverage/Control/Inciter/Options/Problem.hpp.gcov.html index 3dba406df269..637e9a2a5881 100644 --- a/Release/test_coverage/Control/Inciter/Options/Problem.hpp.gcov.html +++ b/Release/test_coverage/Control/Inciter/Options/Problem.hpp.gcov.html @@ -33,7 +33,7 @@ - + diff --git a/Release/test_coverage/Control/Inciter/Options/Scheme.hpp.func-sort-c.html b/Release/test_coverage/Control/Inciter/Options/Scheme.hpp.func-sort-c.html index 6ea78fe08794..c21dcba2596a 100644 --- a/Release/test_coverage/Control/Inciter/Options/Scheme.hpp.func-sort-c.html +++ b/Release/test_coverage/Control/Inciter/Options/Scheme.hpp.func-sort-c.html @@ -33,7 +33,7 @@ - + diff --git a/Release/test_coverage/Control/Inciter/Options/Scheme.hpp.func.html b/Release/test_coverage/Control/Inciter/Options/Scheme.hpp.func.html index aeb6fd29ff1e..606f3dea0014 100644 --- a/Release/test_coverage/Control/Inciter/Options/Scheme.hpp.func.html +++ b/Release/test_coverage/Control/Inciter/Options/Scheme.hpp.func.html @@ -33,7 +33,7 @@ - + diff --git a/Release/test_coverage/Control/Inciter/Options/Scheme.hpp.gcov.html b/Release/test_coverage/Control/Inciter/Options/Scheme.hpp.gcov.html index 46dd2326ce80..e299a07dea1b 100644 --- a/Release/test_coverage/Control/Inciter/Options/Scheme.hpp.gcov.html +++ b/Release/test_coverage/Control/Inciter/Options/Scheme.hpp.gcov.html @@ -33,7 +33,7 @@ - + diff --git a/Release/test_coverage/Control/Inciter/Options/index-sort-b.html b/Release/test_coverage/Control/Inciter/Options/index-sort-b.html index 44eed6e9aa89..b70248c95e01 100644 --- a/Release/test_coverage/Control/Inciter/Options/index-sort-b.html +++ b/Release/test_coverage/Control/Inciter/Options/index-sort-b.html @@ -33,7 +33,7 @@ - + @@ -94,19 +94,19 @@ - + - + - + @@ -118,31 +118,31 @@ - + - + - + - + - + @@ -154,7 +154,7 @@ - + @@ -166,36 +166,36 @@ - + - + - + - + - + - + @@ -214,7 +214,7 @@ - + @@ -226,7 +226,7 @@ - + diff --git a/Release/test_coverage/Control/Inciter/Options/index-sort-f.html b/Release/test_coverage/Control/Inciter/Options/index-sort-f.html index 03c010f3dc53..a44c3d87ee03 100644 --- a/Release/test_coverage/Control/Inciter/Options/index-sort-f.html +++ b/Release/test_coverage/Control/Inciter/Options/index-sort-f.html @@ -33,7 +33,7 @@ - + @@ -82,19 +82,19 @@ - + - + - + @@ -106,19 +106,19 @@ - + - + - - + + - + @@ -126,23 +126,23 @@ - - + + - + - + - - + + - + @@ -166,7 +166,7 @@ - + @@ -174,11 +174,11 @@ - - + + - + @@ -186,8 +186,8 @@ - - + + @@ -202,7 +202,7 @@ - + @@ -210,16 +210,16 @@ - - + + - + - + diff --git a/Release/test_coverage/Control/Inciter/Options/index-sort-l.html b/Release/test_coverage/Control/Inciter/Options/index-sort-l.html index 1a891a323ddf..b9ba1293617f 100644 --- a/Release/test_coverage/Control/Inciter/Options/index-sort-l.html +++ b/Release/test_coverage/Control/Inciter/Options/index-sort-l.html @@ -33,7 +33,7 @@ - + @@ -106,7 +106,7 @@ - + @@ -118,7 +118,7 @@ - + @@ -142,7 +142,7 @@ - + @@ -150,11 +150,11 @@ - - + + - + @@ -162,11 +162,11 @@ - - + + - + @@ -174,11 +174,11 @@ - - + + - + @@ -190,7 +190,7 @@ - + @@ -214,7 +214,7 @@ - + @@ -222,11 +222,11 @@ - - + + - + diff --git a/Release/test_coverage/Control/Inciter/Options/index.html b/Release/test_coverage/Control/Inciter/Options/index.html index 8b26a4b56d32..f72264a893d8 100644 --- a/Release/test_coverage/Control/Inciter/Options/index.html +++ b/Release/test_coverage/Control/Inciter/Options/index.html @@ -33,7 +33,7 @@ - + diff --git a/Release/test_coverage/Control/Inciter/OutVar.hpp.func-sort-c.html b/Release/test_coverage/Control/Inciter/OutVar.hpp.func-sort-c.html index 08e445085b7c..38897be73d69 100644 --- a/Release/test_coverage/Control/Inciter/OutVar.hpp.func-sort-c.html +++ b/Release/test_coverage/Control/Inciter/OutVar.hpp.func-sort-c.html @@ -33,7 +33,7 @@ - + diff --git a/Release/test_coverage/Control/Inciter/OutVar.hpp.func.html b/Release/test_coverage/Control/Inciter/OutVar.hpp.func.html index 556daf30f723..a62d9dbd8f7e 100644 --- a/Release/test_coverage/Control/Inciter/OutVar.hpp.func.html +++ b/Release/test_coverage/Control/Inciter/OutVar.hpp.func.html @@ -33,7 +33,7 @@ - + diff --git a/Release/test_coverage/Control/Inciter/OutVar.hpp.gcov.html b/Release/test_coverage/Control/Inciter/OutVar.hpp.gcov.html index 9c85c60f7eeb..34d44f63b632 100644 --- a/Release/test_coverage/Control/Inciter/OutVar.hpp.gcov.html +++ b/Release/test_coverage/Control/Inciter/OutVar.hpp.gcov.html @@ -33,7 +33,7 @@ - + diff --git a/Release/test_coverage/Control/Inciter/index-sort-b.html b/Release/test_coverage/Control/Inciter/index-sort-b.html index cc6a582881db..4abd0faaadd7 100644 --- a/Release/test_coverage/Control/Inciter/index-sort-b.html +++ b/Release/test_coverage/Control/Inciter/index-sort-b.html @@ -33,7 +33,7 @@ - + diff --git a/Release/test_coverage/Control/Inciter/index-sort-f.html b/Release/test_coverage/Control/Inciter/index-sort-f.html index eb1f37df6d17..c0b36edee815 100644 --- a/Release/test_coverage/Control/Inciter/index-sort-f.html +++ b/Release/test_coverage/Control/Inciter/index-sort-f.html @@ -33,7 +33,7 @@ - + diff --git a/Release/test_coverage/Control/Inciter/index-sort-l.html b/Release/test_coverage/Control/Inciter/index-sort-l.html index 0b8ff6e42732..b779aa934505 100644 --- a/Release/test_coverage/Control/Inciter/index-sort-l.html +++ b/Release/test_coverage/Control/Inciter/index-sort-l.html @@ -33,7 +33,7 @@ - + diff --git a/Release/test_coverage/Control/Inciter/index.html b/Release/test_coverage/Control/Inciter/index.html index 22ade405f052..b987317ab1be 100644 --- a/Release/test_coverage/Control/Inciter/index.html +++ b/Release/test_coverage/Control/Inciter/index.html @@ -33,7 +33,7 @@ - + diff --git a/Release/test_coverage/Control/Keyword.hpp.func-sort-c.html b/Release/test_coverage/Control/Keyword.hpp.func-sort-c.html index a42109d13126..81eb8aa26fff 100644 --- a/Release/test_coverage/Control/Keyword.hpp.func-sort-c.html +++ b/Release/test_coverage/Control/Keyword.hpp.func-sort-c.html @@ -33,7 +33,7 @@ - + diff --git a/Release/test_coverage/Control/Keyword.hpp.func.html b/Release/test_coverage/Control/Keyword.hpp.func.html index 23cac01d422c..53c356a7a4f7 100644 --- a/Release/test_coverage/Control/Keyword.hpp.func.html +++ b/Release/test_coverage/Control/Keyword.hpp.func.html @@ -33,7 +33,7 @@ - + diff --git a/Release/test_coverage/Control/Keyword.hpp.gcov.html b/Release/test_coverage/Control/Keyword.hpp.gcov.html index eee11823906d..d8e05f1381fc 100644 --- a/Release/test_coverage/Control/Keyword.hpp.gcov.html +++ b/Release/test_coverage/Control/Keyword.hpp.gcov.html @@ -33,7 +33,7 @@ - + diff --git a/Release/test_coverage/Control/Keywords.hpp.func-sort-c.html b/Release/test_coverage/Control/Keywords.hpp.func-sort-c.html index 3ad7063929a6..b3382b5cf539 100644 --- a/Release/test_coverage/Control/Keywords.hpp.func-sort-c.html +++ b/Release/test_coverage/Control/Keywords.hpp.func-sort-c.html @@ -33,7 +33,7 @@ - + diff --git a/Release/test_coverage/Control/Keywords.hpp.func.html b/Release/test_coverage/Control/Keywords.hpp.func.html index e714421b5f81..e785b8099476 100644 --- a/Release/test_coverage/Control/Keywords.hpp.func.html +++ b/Release/test_coverage/Control/Keywords.hpp.func.html @@ -33,7 +33,7 @@ - + diff --git a/Release/test_coverage/Control/Keywords.hpp.gcov.html b/Release/test_coverage/Control/Keywords.hpp.gcov.html index 86f9be10f824..35b44d4b11d0 100644 --- a/Release/test_coverage/Control/Keywords.hpp.gcov.html +++ b/Release/test_coverage/Control/Keywords.hpp.gcov.html @@ -33,7 +33,7 @@ - + diff --git a/Release/test_coverage/Control/MeshConv/CmdLine/CmdLine.hpp.func-sort-c.html b/Release/test_coverage/Control/MeshConv/CmdLine/CmdLine.hpp.func-sort-c.html index 9f0f7116fd07..48236da5494f 100644 --- a/Release/test_coverage/Control/MeshConv/CmdLine/CmdLine.hpp.func-sort-c.html +++ b/Release/test_coverage/Control/MeshConv/CmdLine/CmdLine.hpp.func-sort-c.html @@ -33,7 +33,7 @@ - + diff --git a/Release/test_coverage/Control/MeshConv/CmdLine/CmdLine.hpp.func.html b/Release/test_coverage/Control/MeshConv/CmdLine/CmdLine.hpp.func.html index 997ed64f4ca2..f33974555b6e 100644 --- a/Release/test_coverage/Control/MeshConv/CmdLine/CmdLine.hpp.func.html +++ b/Release/test_coverage/Control/MeshConv/CmdLine/CmdLine.hpp.func.html @@ -33,7 +33,7 @@ - + diff --git a/Release/test_coverage/Control/MeshConv/CmdLine/CmdLine.hpp.gcov.html b/Release/test_coverage/Control/MeshConv/CmdLine/CmdLine.hpp.gcov.html index 362ec3d16340..345126a25a1c 100644 --- a/Release/test_coverage/Control/MeshConv/CmdLine/CmdLine.hpp.gcov.html +++ b/Release/test_coverage/Control/MeshConv/CmdLine/CmdLine.hpp.gcov.html @@ -33,7 +33,7 @@ - + diff --git a/Release/test_coverage/Control/MeshConv/CmdLine/Parser.cpp.func-sort-c.html b/Release/test_coverage/Control/MeshConv/CmdLine/Parser.cpp.func-sort-c.html index 561e843e7a28..aff8c2c825f9 100644 --- a/Release/test_coverage/Control/MeshConv/CmdLine/Parser.cpp.func-sort-c.html +++ b/Release/test_coverage/Control/MeshConv/CmdLine/Parser.cpp.func-sort-c.html @@ -33,7 +33,7 @@ - + diff --git a/Release/test_coverage/Control/MeshConv/CmdLine/Parser.cpp.func.html b/Release/test_coverage/Control/MeshConv/CmdLine/Parser.cpp.func.html index 495998aa095b..908561f7f87f 100644 --- a/Release/test_coverage/Control/MeshConv/CmdLine/Parser.cpp.func.html +++ b/Release/test_coverage/Control/MeshConv/CmdLine/Parser.cpp.func.html @@ -33,7 +33,7 @@ - + diff --git a/Release/test_coverage/Control/MeshConv/CmdLine/Parser.cpp.gcov.html b/Release/test_coverage/Control/MeshConv/CmdLine/Parser.cpp.gcov.html index 200c55145cce..1d620fb82bc0 100644 --- a/Release/test_coverage/Control/MeshConv/CmdLine/Parser.cpp.gcov.html +++ b/Release/test_coverage/Control/MeshConv/CmdLine/Parser.cpp.gcov.html @@ -33,7 +33,7 @@ - + diff --git a/Release/test_coverage/Control/MeshConv/CmdLine/Parser.hpp.func-sort-c.html b/Release/test_coverage/Control/MeshConv/CmdLine/Parser.hpp.func-sort-c.html index 2c050ba7edc8..1cd6dc262553 100644 --- a/Release/test_coverage/Control/MeshConv/CmdLine/Parser.hpp.func-sort-c.html +++ b/Release/test_coverage/Control/MeshConv/CmdLine/Parser.hpp.func-sort-c.html @@ -33,7 +33,7 @@ - + diff --git a/Release/test_coverage/Control/MeshConv/CmdLine/Parser.hpp.func.html b/Release/test_coverage/Control/MeshConv/CmdLine/Parser.hpp.func.html index 3fcdd70f714e..08bde9f28fff 100644 --- a/Release/test_coverage/Control/MeshConv/CmdLine/Parser.hpp.func.html +++ b/Release/test_coverage/Control/MeshConv/CmdLine/Parser.hpp.func.html @@ -33,7 +33,7 @@ - + diff --git a/Release/test_coverage/Control/MeshConv/CmdLine/Parser.hpp.gcov.html b/Release/test_coverage/Control/MeshConv/CmdLine/Parser.hpp.gcov.html index a3d197fb5fd4..482fb2252ff4 100644 --- a/Release/test_coverage/Control/MeshConv/CmdLine/Parser.hpp.gcov.html +++ b/Release/test_coverage/Control/MeshConv/CmdLine/Parser.hpp.gcov.html @@ -33,7 +33,7 @@ - + diff --git a/Release/test_coverage/Control/MeshConv/CmdLine/index-sort-b.html b/Release/test_coverage/Control/MeshConv/CmdLine/index-sort-b.html index a79c7842bf42..a8823d477a46 100644 --- a/Release/test_coverage/Control/MeshConv/CmdLine/index-sort-b.html +++ b/Release/test_coverage/Control/MeshConv/CmdLine/index-sort-b.html @@ -33,7 +33,7 @@ - + diff --git a/Release/test_coverage/Control/MeshConv/CmdLine/index-sort-f.html b/Release/test_coverage/Control/MeshConv/CmdLine/index-sort-f.html index b4834fe5f3e8..a3200058ff93 100644 --- a/Release/test_coverage/Control/MeshConv/CmdLine/index-sort-f.html +++ b/Release/test_coverage/Control/MeshConv/CmdLine/index-sort-f.html @@ -33,7 +33,7 @@ - + diff --git a/Release/test_coverage/Control/MeshConv/CmdLine/index-sort-l.html b/Release/test_coverage/Control/MeshConv/CmdLine/index-sort-l.html index 9c14eab6adf3..9a120879245b 100644 --- a/Release/test_coverage/Control/MeshConv/CmdLine/index-sort-l.html +++ b/Release/test_coverage/Control/MeshConv/CmdLine/index-sort-l.html @@ -33,7 +33,7 @@ - + diff --git a/Release/test_coverage/Control/MeshConv/CmdLine/index.html b/Release/test_coverage/Control/MeshConv/CmdLine/index.html index c3002ae2e1c9..589cf92a2a5b 100644 --- a/Release/test_coverage/Control/MeshConv/CmdLine/index.html +++ b/Release/test_coverage/Control/MeshConv/CmdLine/index.html @@ -33,7 +33,7 @@ - + diff --git a/Release/test_coverage/Control/Options/Error.hpp.func-sort-c.html b/Release/test_coverage/Control/Options/Error.hpp.func-sort-c.html index d7a78d5cbf9c..e7178391fb48 100644 --- a/Release/test_coverage/Control/Options/Error.hpp.func-sort-c.html +++ b/Release/test_coverage/Control/Options/Error.hpp.func-sort-c.html @@ -33,7 +33,7 @@ - + diff --git a/Release/test_coverage/Control/Options/Error.hpp.func.html b/Release/test_coverage/Control/Options/Error.hpp.func.html index 443c61dc0c1b..187582962351 100644 --- a/Release/test_coverage/Control/Options/Error.hpp.func.html +++ b/Release/test_coverage/Control/Options/Error.hpp.func.html @@ -33,7 +33,7 @@ - + diff --git a/Release/test_coverage/Control/Options/Error.hpp.gcov.html b/Release/test_coverage/Control/Options/Error.hpp.gcov.html index e927742e76d9..fefe0e6a9478 100644 --- a/Release/test_coverage/Control/Options/Error.hpp.gcov.html +++ b/Release/test_coverage/Control/Options/Error.hpp.gcov.html @@ -33,7 +33,7 @@ - + diff --git a/Release/test_coverage/Control/Options/FieldFile.hpp.func-sort-c.html b/Release/test_coverage/Control/Options/FieldFile.hpp.func-sort-c.html index 7208d88bf9d1..ee11adcff72c 100644 --- a/Release/test_coverage/Control/Options/FieldFile.hpp.func-sort-c.html +++ b/Release/test_coverage/Control/Options/FieldFile.hpp.func-sort-c.html @@ -33,7 +33,7 @@ - + diff --git a/Release/test_coverage/Control/Options/FieldFile.hpp.func.html b/Release/test_coverage/Control/Options/FieldFile.hpp.func.html index ba0edef28230..d4d42322215e 100644 --- a/Release/test_coverage/Control/Options/FieldFile.hpp.func.html +++ b/Release/test_coverage/Control/Options/FieldFile.hpp.func.html @@ -33,7 +33,7 @@ - + diff --git a/Release/test_coverage/Control/Options/FieldFile.hpp.gcov.html b/Release/test_coverage/Control/Options/FieldFile.hpp.gcov.html index 68b38ae02921..4c844407ddaa 100644 --- a/Release/test_coverage/Control/Options/FieldFile.hpp.gcov.html +++ b/Release/test_coverage/Control/Options/FieldFile.hpp.gcov.html @@ -33,7 +33,7 @@ - + diff --git a/Release/test_coverage/Control/Options/PartitioningAlgorithm.hpp.func-sort-c.html b/Release/test_coverage/Control/Options/PartitioningAlgorithm.hpp.func-sort-c.html index 7472a385d556..5bd3e2de63e7 100644 --- a/Release/test_coverage/Control/Options/PartitioningAlgorithm.hpp.func-sort-c.html +++ b/Release/test_coverage/Control/Options/PartitioningAlgorithm.hpp.func-sort-c.html @@ -33,7 +33,7 @@ - + diff --git a/Release/test_coverage/Control/Options/PartitioningAlgorithm.hpp.func.html b/Release/test_coverage/Control/Options/PartitioningAlgorithm.hpp.func.html index 0691f8b6e968..037659648e8c 100644 --- a/Release/test_coverage/Control/Options/PartitioningAlgorithm.hpp.func.html +++ b/Release/test_coverage/Control/Options/PartitioningAlgorithm.hpp.func.html @@ -33,7 +33,7 @@ - + diff --git a/Release/test_coverage/Control/Options/PartitioningAlgorithm.hpp.gcov.html b/Release/test_coverage/Control/Options/PartitioningAlgorithm.hpp.gcov.html index f329a17a8c60..f4608f285204 100644 --- a/Release/test_coverage/Control/Options/PartitioningAlgorithm.hpp.gcov.html +++ b/Release/test_coverage/Control/Options/PartitioningAlgorithm.hpp.gcov.html @@ -33,7 +33,7 @@ - + diff --git a/Release/test_coverage/Control/Options/TxtFloatFormat.hpp.func-sort-c.html b/Release/test_coverage/Control/Options/TxtFloatFormat.hpp.func-sort-c.html index 219dca51a027..edad780422d3 100644 --- a/Release/test_coverage/Control/Options/TxtFloatFormat.hpp.func-sort-c.html +++ b/Release/test_coverage/Control/Options/TxtFloatFormat.hpp.func-sort-c.html @@ -33,7 +33,7 @@ - + diff --git a/Release/test_coverage/Control/Options/TxtFloatFormat.hpp.func.html b/Release/test_coverage/Control/Options/TxtFloatFormat.hpp.func.html index 3d4bb32b0664..4dcb4a4ce5d4 100644 --- a/Release/test_coverage/Control/Options/TxtFloatFormat.hpp.func.html +++ b/Release/test_coverage/Control/Options/TxtFloatFormat.hpp.func.html @@ -33,7 +33,7 @@ - + diff --git a/Release/test_coverage/Control/Options/TxtFloatFormat.hpp.gcov.html b/Release/test_coverage/Control/Options/TxtFloatFormat.hpp.gcov.html index a4f425ffb6a9..a69551a5328e 100644 --- a/Release/test_coverage/Control/Options/TxtFloatFormat.hpp.gcov.html +++ b/Release/test_coverage/Control/Options/TxtFloatFormat.hpp.gcov.html @@ -33,7 +33,7 @@ - + diff --git a/Release/test_coverage/Control/Options/UserTable.hpp.func-sort-c.html b/Release/test_coverage/Control/Options/UserTable.hpp.func-sort-c.html index 805c407b14a4..5e019b3ef824 100644 --- a/Release/test_coverage/Control/Options/UserTable.hpp.func-sort-c.html +++ b/Release/test_coverage/Control/Options/UserTable.hpp.func-sort-c.html @@ -33,7 +33,7 @@ - + diff --git a/Release/test_coverage/Control/Options/UserTable.hpp.func.html b/Release/test_coverage/Control/Options/UserTable.hpp.func.html index 1de172fa883c..84afd2e94cce 100644 --- a/Release/test_coverage/Control/Options/UserTable.hpp.func.html +++ b/Release/test_coverage/Control/Options/UserTable.hpp.func.html @@ -33,7 +33,7 @@ - + diff --git a/Release/test_coverage/Control/Options/UserTable.hpp.gcov.html b/Release/test_coverage/Control/Options/UserTable.hpp.gcov.html index c76d6701175a..12dc434c5c81 100644 --- a/Release/test_coverage/Control/Options/UserTable.hpp.gcov.html +++ b/Release/test_coverage/Control/Options/UserTable.hpp.gcov.html @@ -33,7 +33,7 @@ - + diff --git a/Release/test_coverage/Control/Options/index-sort-b.html b/Release/test_coverage/Control/Options/index-sort-b.html index 2a9b5effd7b4..3f13d9191459 100644 --- a/Release/test_coverage/Control/Options/index-sort-b.html +++ b/Release/test_coverage/Control/Options/index-sort-b.html @@ -33,7 +33,7 @@ - + @@ -94,7 +94,7 @@ - + @@ -106,7 +106,7 @@ - + @@ -118,7 +118,7 @@ - + diff --git a/Release/test_coverage/Control/Options/index-sort-f.html b/Release/test_coverage/Control/Options/index-sort-f.html index fa268c2e55ea..95403c14c2da 100644 --- a/Release/test_coverage/Control/Options/index-sort-f.html +++ b/Release/test_coverage/Control/Options/index-sort-f.html @@ -33,7 +33,7 @@ - + @@ -94,19 +94,19 @@ - + - + - - + + - + @@ -118,7 +118,7 @@ - + @@ -130,16 +130,16 @@ - + - + - - + +
   1
-   2
-   3
-   4
-   5
-   6
-   7
-   8
-   9
-  10
-  11
-  12
-  13
-  14
-  15
-  16
-  17
-  18
-  19
-  20
-  21
-  22
-  23
-  24
-  25
-  26
-  27
-  28
-  29
-  30
-  31
-  32
-  33
-  34
-  35
-  36
-  37
-  38
-  39
-  40
-  41
-  42
-  43
-  44
-  45
-  46
-  47
-  48
-  49
-  50
-  51
-  52
-  53
-  54
-  55
-  56
-  57
-  58
-  59
-  60
-  61
-  62
-  63
-  64
-  65
-  66
-  67
-  68
-  69
-  70
-  71
-  72
-  73
-  74
-  75
-  76
-  77
-  78
-  79
-  80
-  81
-  82
-  83
-  84
-  85
-  86
-  87
-  88
-  89
-  90
-  91
-  92
-  93
-  94
-  95
-  96
-  97
-  98
-  99
- 100
- 101
- 102
- 103
- 104
- 105
- 106
- 107
- 108
- 109
- 110
- 111
- 112
- 113
- 114
- 115
- 116
- 117
- 118
- 119
- 120
- 121
- 122
- 123
- 124
- 125
- 126
- 127
- 128
- 129
- 130
- 131
- 132
- 133
- 134
- 135
- 136
- 137
- 138
- 139
- 140
- 141
- 142
- 143
- 144
- 145
- 146
- 147
- 148
- 149
- 150
- 151
- 152
- 153
- 154
- 155
- 156
- 157
- 158
- 159
- 160
- 161
- 162
- 163
- 164
- 165
- 166
- 167
- 168
- 169
- 170
- 171
- 172
- 173
- 174
- 175
- 176
- 177
- 178
- 179
- 180
- 181
- 182
- 183
- 184
- 185
- 186
- 187
- 188
- 189
- 190
- 191
- 192
- 193
- 194
- 195
- 196
- 197
- 198
- 199
- 200
- 201
- 202
- 203
- 204
- 205
- 206
- 207
- 208
- 209
- 210
- 211
- 212
- 213
- 214
- 215
- 216
- 217
- 218
- 219
- 220
- 221
- 222
- 223
- 224
- 225
- 226
- 227
- 228
- 229
- 230
- 231
- 232
- 233
- 234
- 235
- 236
- 237
- 238
- 239
- 240
- 241
- 242
- 243
- 244
- 245
- 246
- 247
- 248
- 249
- 250
- 251
- 252
- 253
- 254
- 255
- 256
- 257
- 258
- 259
- 260
- 261
- 262
- 263
- 264
- 265
- 266
- 267
- 268
- 269
- 270
- 271
- 272
- 273
- 274
- 275
- 276
- 277
- 278
- 279
- 280
- 281
- 282
- 283
- 284
- 285
- 286
- 287
- 288
- 289
- 290
- 291
- 292
- 293
- 294
- 295
- 296
- 297
- 298
- 299
- 300
- 301
- 302
- 303
- 304
- 305
- 306
- 307
- 308
- 309
- 310
- 311
- 312
- 313
- 314
- 315
- 316
- 317
- 318
- 319
- 320
- 321
- 322
- 323
- 324
- 325
- 326
- 327
- 328
- 329
- 330
- 331
- 332
- 333
- 334
- 335
- 336
- 337
- 338
- 339
- 340
- 341
- 342
- 343
- 344
- 345
- 346
- 347
- 348
- 349
- 350
- 351
- 352
- 353
- 354
- 355
- 356
- 357
- 358
- 359
- 360
- 361
- 362
- 363
- 364
- 365
- 366
- 367
- 368
- 369
- 370
- 371
- 372
- 373
- 374
- 375
- 376
- 377
- 378
- 379
- 380
- 381
- 382
- 383
- 384
- 385
- 386
- 387
- 388
- 389
- 390
- 391
- 392
- 393
- 394
- 395
- 396
- 397
- 398
- 399
- 400
- 401
- 402
- 403
- 404
- 405
- 406
- 407
- 408
- 409
- 410
- 411
- 412
- 413
- 414
- 415
- 416
- 417
- 418
- 419
- 420
- 421
- 422
- 423
- 424
- 425
- 426
- 427
- 428
- 429
- 430
- 431
- 432
- 433
- 434
- 435
- 436
- 437
- 438
- 439
- 440
- 441
- 442
- 443
- 444
- 445
- 446
- 447
- 448
- 449
- 450
- 451
- 452
- 453
- 454
- 455
- 456
- 457
- 458
- 459
- 460
- 461
- 462
- 463
- 464
- 465
- 466
- 467
- 468
- 469
- 470
- 471
- 472
- 473
- 474
- 475
- 476
- 477
- 478
- 479
- 480
- 481
- 482
- 483
- 484
- 485
- 486
- 487
- 488
- 489
- 490
- 491
- 492
- 493
- 494
- 495
- 496
- 497
- 498
- 499
- 500
- 501
- 502
- 503
- 504
- 505
- 506
- 507
- 508
- 509
- 510
- 511
- 512
- 513
- 514
- 515
- 516
- 517
- 518
- 519
- 520
- 521
- 522
- 523
- 524
- 525
- 526
- 527
- 528
- 529
- 530
- 531
- 532
- 533
- 534
- 535
- 536
- 537
- 538
- 539
- 540
- 541
- 542
- 543
- 544
- 545
- 546
- 547
- 548
- 549
- 550
- 551
- 552
- 553
- 554
- 555
- 556
- 557
- 558
- 559
- 560
- 561
- 562
- 563
- 564
- 565
- 566
- 567
- 568
- 569
- 570
- 571
- 572
- 573
- 574
- 575
- 576
- 577
- 578
- 579
- 580
- 581
- 582
- 583
- 584
- 585
- 586
- 587
- 588
- 589
- 590
- 591
- 592
- 593
- 594
- 595
- 596
- 597
- 598
- 599
- 600
- 601
- 602
- 603
- 604
- 605
- 606
- 607
- 608
- 609
- 610
- 611
- 612
- 613
- 614
- 615
- 616
- 617
- 618
- 619
- 620
- 621
- 622
- 623
- 624
- 625
- 626
- 627
- 628
- 629
- 630
- 631
- 632
- 633
- 634
- 635
- 636
- 637
- 638
- 639
- 640
- 641
- 642
- 643
- 644
- 645
- 646
- 647
- 648
- 649
- 650
- 651
- 652
- 653
- 654
- 655
- 656
- 657
- 658
- 659
- 660
- 661
- 662
- 663
- 664
- 665
- 666
- 667
- 668
- 669
- 670
- 671
- 672
- 673
- 674
- 675
- 676
- 677
- 678
- 679
- 680
- 681
- 682
- 683
- 684
- 685
- 686
- 687
- 688
- 689
- 690
- 691
- 692
- 693
- 694
- 695
- 696
- 697
- 698
- 699
- 700
- 701
- 702
- 703
- 704
- 705
- 706
- 707
- 708
- 709
- 710
- 711
- 712
- 713
- 714
- 715
- 716
- 717
- 718
- 719
- 720
- 721
- 722
- 723
- 724
- 725
- 726
- 727
- 728
- 729
- 730
- 731
- 732
- 733
- 734
- 735
- 736
- 737
- 738
- 739
- 740
- 741
- 742
- 743
- 744
- 745
- 746
- 747
- 748
- 749
- 750
- 751
- 752
- 753
- 754
- 755
- 756
- 757
- 758
- 759
- 760
- 761
- 762
- 763
- 764
- 765
- 766
- 767
- 768
- 769
- 770
- 771
- 772
- 773
- 774
- 775
- 776
- 777
- 778
- 779
- 780
- 781
- 782
- 783
- 784
- 785
- 786
- 787
- 788
- 789
- 790
- 791
- 792
- 793
- 794
- 795
- 796
- 797
- 798
- 799
- 800
- 801
- 802
- 803
- 804
- 805
- 806
- 807
- 808
- 809
- 810
- 811
- 812
- 813
- 814
- 815
- 816
- 817
- 818
- 819
- 820
- 821
- 822
- 823
- 824
- 825
- 826
- 827
- 828
- 829
- 830
- 831
- 832
- 833
- 834
- 835
- 836
- 837
- 838
- 839
- 840
- 841
- 842
- 843
- 844
- 845
- 846
- 847
- 848
- 849
- 850
- 851
- 852
- 853
- 854
- 855
- 856
- 857
- 858
- 859
- 860
- 861
- 862
- 863
- 864
- 865
- 866
- 867
- 868
- 869
- 870
- 871
- 872
- 873
- 874
- 875
- 876
- 877
- 878
- 879
- 880
- 881
- 882
- 883
- 884
- 885
- 886
- 887
- 888
- 889
- 890
- 891
- 892
- 893
- 894
- 895
- 896
- 897
- 898
- 899
- 900
- 901
- 902
- 903
- 904
- 905
- 906
- 907
- 908
- 909
- 910
- 911
- 912
- 913
- 914
- 915
- 916
- 917
- 918
- 919
- 920
- 921
- 922
- 923
- 924
- 925
- 926
- 927
- 928
- 929
- 930
- 931
- 932
- 933
- 934
- 935
- 936
- 937
- 938
- 939
- 940
- 941
- 942
- 943
- 944
- 945
- 946
- 947
- 948
- 949
- 950
- 951
- 952
- 953
- 954
- 955
- 956
- 957
- 958
- 959
- 960
- 961
- 962
- 963
- 964
- 965
- 966
- 967
- 968
- 969
- 970
- 971
- 972
- 973
- 974
- 975
- 976
- 977
- 978
- 979
- 980
- 981
- 982
- 983
- 984
- 985
- 986
- 987
- 988
- 989
- 990
- 991
- 992
- 993
- 994
- 995
- 996
- 997
- 998
- 999
-1000
-1001
-1002
-1003
-1004
-1005
-1006
-1007
-1008
-1009
-1010
-1011
-1012
-1013
-1014
-1015
-1016
-1017
-1018
-1019
-1020
-1021
-1022
-1023
-1024
-1025
-1026
-1027
-1028
-1029
-1030
-1031
-1032
-1033
-1034
-1035
-1036
-1037
-1038
-1039
-1040
-1041
-1042
-1043
-1044
-1045
-1046
-1047
-1048
-1049
-1050
-1051
-1052
-1053
// *****************************************************************************
+
  1
+  2
+  3
+  4
+  5
+  6
+  7
+  8
+  9
+ 10
+ 11
+ 12
+ 13
+ 14
+ 15
+ 16
+ 17
+ 18
+ 19
+ 20
+ 21
+ 22
+ 23
+ 24
+ 25
+ 26
+ 27
+ 28
+ 29
+ 30
+ 31
+ 32
+ 33
+ 34
+ 35
+ 36
+ 37
+ 38
+ 39
+ 40
+ 41
+ 42
+ 43
+ 44
+ 45
+ 46
+ 47
+ 48
+ 49
+ 50
+ 51
+ 52
+ 53
+ 54
+ 55
+ 56
+ 57
+ 58
+ 59
+ 60
+ 61
+ 62
+ 63
+ 64
+ 65
+ 66
+ 67
+ 68
+ 69
+ 70
+ 71
+ 72
+ 73
+ 74
+ 75
+ 76
+ 77
+ 78
+ 79
+ 80
+ 81
+ 82
+ 83
+ 84
+ 85
+ 86
+ 87
+ 88
+ 89
+ 90
+ 91
+ 92
+ 93
+ 94
+ 95
+ 96
+ 97
+ 98
+ 99
+100
+101
+102
+103
+104
+105
+106
+107
+108
+109
+110
+111
+112
+113
+114
+115
+116
+117
+118
+119
+120
+121
+122
+123
+124
+125
+126
+127
+128
+129
+130
+131
+132
+133
+134
+135
+136
+137
+138
+139
+140
+141
+142
+143
+144
+145
+146
+147
+148
+149
+150
+151
+152
+153
+154
+155
+156
+157
+158
+159
+160
+161
+162
+163
+164
+165
+166
+167
+168
+169
+170
+171
+172
+173
+174
+175
+176
+177
+178
+179
+180
+181
+182
+183
+184
+185
+186
+187
+188
+189
+190
+191
+192
+193
+194
+195
+196
+197
+198
+199
+200
+201
+202
+203
+204
+205
+206
+207
+208
+209
+210
+211
+212
+213
+214
+215
+216
+217
+218
+219
+220
+221
+222
+223
+224
+225
+226
+227
+228
+229
+230
+231
+232
+233
+234
+235
+236
+237
+238
+239
+240
+241
+242
+243
+244
+245
+246
+247
+248
+249
+250
+251
+252
+253
+254
+255
+256
+257
+258
+259
+260
+261
+262
+263
+264
+265
+266
+267
+268
+269
+270
+271
+272
+273
+274
+275
+276
+277
+278
+279
+280
+281
+282
+283
+284
+285
+286
+287
+288
+289
+290
+291
+292
+293
+294
+295
+296
+297
+298
+299
+300
+301
+302
+303
+304
+305
+306
+307
+308
+309
+310
+311
+312
+313
+314
+315
+316
+317
+318
+319
+320
+321
+322
+323
+324
+325
+326
+327
+328
+329
+330
+331
+332
+333
+334
+335
+336
+337
+338
+339
+340
+341
+342
+343
+344
+345
+346
+347
+348
+349
+350
+351
+352
+353
+354
+355
+356
+357
+358
+359
+360
+361
+362
+363
+364
+365
+366
+367
+368
+369
+370
+371
+372
+373
+374
+375
+376
+377
+378
+379
+380
+381
+382
+383
+384
+385
+386
+387
+388
+389
+390
+391
+392
+393
+394
+395
+396
+397
+398
+399
+400
+401
+402
+403
+404
+405
+406
+407
+408
+409
+410
+411
+412
+413
+414
+415
+416
+417
+418
+419
+420
+421
+422
+423
+424
+425
+426
+427
+428
+429
+430
+431
+432
+433
+434
+435
+436
+437
+438
+439
+440
+441
+442
+443
+444
+445
+446
+447
+448
+449
+450
+451
+452
+453
+454
+455
+456
+457
+458
+459
+460
+461
+462
+463
+464
+465
+466
+467
+468
+469
+470
+471
+472
+473
+474
+475
+476
+477
+478
+479
+480
+481
+482
+483
+484
+485
+486
+487
+488
+489
+490
+491
+492
+493
+494
+495
+496
+497
+498
+499
+500
+501
+502
+503
+504
+505
+506
+507
+508
+509
+510
+511
+512
+513
+514
+515
+516
+517
+518
+519
+520
+521
+522
+523
+524
+525
+526
+527
+528
+529
+530
+531
+532
+533
+534
+535
+536
+537
+538
+539
+540
+541
+542
+543
+544
+545
+546
+547
+548
+549
+550
+551
+552
+553
+554
+555
+556
+557
+558
+559
+560
+561
+562
+563
+564
+565
+566
+567
+568
+569
+570
+571
+572
+573
+574
+575
+576
+577
+578
+579
+580
+581
+582
+583
+584
+585
+586
+587
+588
+589
+590
+591
+592
+593
+594
+595
+596
+597
+598
+599
+600
+601
+602
+603
+604
+605
+606
+607
+608
+609
+610
+611
+612
+613
+614
+615
+616
+617
+618
+619
+620
+621
+622
+623
+624
+625
+626
+627
+628
+629
+630
+631
+632
+633
+634
+635
+636
+637
+638
+639
+640
+641
+642
+643
+644
+645
+646
+647
+648
+649
+650
+651
+652
+653
+654
+655
+656
+657
+658
+659
+660
+661
+662
+663
+664
+665
+666
+667
+668
+669
+670
+671
+672
+673
+674
+675
+676
+677
+678
+679
+680
+681
+682
+683
+684
+685
+686
+687
+688
+689
+690
+691
+692
+693
+694
+695
+696
+697
+698
+699
+700
+701
+702
+703
+704
+705
+706
+707
+708
+709
+710
+711
+712
+713
+714
+715
+716
+717
+718
+719
+720
+721
+722
+723
+724
+725
+726
+727
+728
+729
+730
+731
+732
+733
+734
+735
+736
+737
+738
+739
+740
+741
+742
+743
+744
+745
+746
+747
+748
+749
+750
+751
+752
+753
+754
+755
+756
+757
+758
+759
+760
+761
+762
+763
+764
+765
+766
+767
+768
+769
+770
+771
+772
+773
+774
+775
+776
+777
+778
+779
+780
+781
+782
+783
+784
+785
+786
+787
+788
+789
+790
+791
+792
+793
+794
+795
+796
+797
+798
+799
+800
+801
+802
+803
+804
+805
+806
+807
+808
+809
+810
+811
+812
+813
+814
+815
+816
+817
+818
+819
+820
+821
+822
+823
+824
+825
+826
+827
+828
+829
+830
+831
+832
+833
+834
+835
+836
+837
+838
+839
+840
+841
+842
+843
+844
+845
+846
+847
+848
+849
+850
+851
+852
+853
+854
+855
+856
+857
+858
+859
+860
+861
+862
+863
+864
+865
+866
+867
+868
+869
+870
+871
+872
+873
+874
+875
+876
+877
+878
+879
+880
+881
+882
+883
+884
+885
+886
+887
+888
+889
+890
+891
+892
+893
+894
+895
+896
+897
// *****************************************************************************
 /*!
-  \file      src/PDE/Integrate/Basis.cpp
+  \file      src/PDE/MultiMat/FVMultiMat.hpp
   \copyright 2012-2015 J. Bakosi,
              2016-2018 Los Alamos National Security, LLC.,
              2019-2021 Triad National Security, LLC.
              All rights reserved. See the LICENSE file for details.
-  \brief     Functions for computing the Dubiner basis functions in DG methods
-  \details   This file contains functionality for computing the basis functions
-     and relating coordinates transformation functions used in discontinuous
-     Galerkin methods for variaous orders of numerical representation. The basis
-     functions chosen for the DG method are the Dubiner basis, which are
-     Legendre polynomials modified for tetrahedra, which are defined only on
-     the reference/master tetrahedron.
-  \see [1] https://doi.org/10.1007/BF01060030
-  \see [2] https://doi.org/10.1093/imamat/hxh111
-*/
-// *****************************************************************************
-
-#include <array>
-#include "QuinoaConfig.hpp"
+  \brief     Compressible multi-material flow using finite volumes
+  \details   This file implements calls to the physics operators governing
+    compressible multi-material flow (with velocity equilibrium) using finite
+    volume discretizations.
+*/
+// *****************************************************************************
+#ifndef FVMultiMat_h
+#define FVMultiMat_h
+
+#include <cmath>
+#include <algorithm>
+#include <unordered_set>
+#include <map>
+#include <array>
 
-#include "Basis.hpp"
-#include "Vector.hpp"
-#include "Mass.hpp"
-
-std::array< tk::real, 3 >
-tk::eval_gp ( const std::size_t igp,
-              const std::array< std::array< tk::real, 3>, 3 >& coordfa,
-              const std::array< std::vector< tk::real >, 2 >& coordgp )
-// *****************************************************************************
-//  Compute the coordinates of quadrature points for face integral in physical
-//  space
-//! \param[in] igp Index of quadrature points
-//! \param[in] coordfa Array of nodal coordinates for face element
-//! \param[in] coordgp Array of coordinates for quadrature points in reference
-//!   space
-//! \return Array of coordinates for quadrature points in physical space
-// *****************************************************************************
-{
-  // Barycentric coordinates for the triangular face
-  auto shp1 = 1.0 - coordgp[0][igp] - coordgp[1][igp];
-  auto shp2 = coordgp[0][igp];
-  auto shp3 = coordgp[1][igp];
-
-  // Transformation of the quadrature point from the 2D reference/master
-  // element to physical space, to obtain its physical (x,y,z) coordinates.
-  return {{ coordfa[0][0]*shp1 + coordfa[1][0]*shp2 + coordfa[2][0]*shp3,
-            coordfa[0][1]*shp1 + coordfa[1][1]*shp2 + coordfa[2][1]*shp3,
-            coordfa[0][2]*shp1 + coordfa[1][2]*shp2 + coordfa[2][2]*shp3 }};
-}
+#include "Macro.hpp"
+#include "Exception.hpp"
+#include "Vector.hpp"
+#include "ContainerUtil.hpp"
+#include "UnsMesh.hpp"
+#include "Inciter/InputDeck/InputDeck.hpp"
+#include "Integrate/Basis.hpp"
+#include "Integrate/Quadrature.hpp"
+#include "Integrate/Initialize.hpp"
+#include "Integrate/Mass.hpp"
+#include "Integrate/Surface.hpp"
+#include "Integrate/Boundary.hpp"
+#include "Integrate/Volume.hpp"
+#include "Integrate/MultiMatTerms.hpp"
+#include "Integrate/Source.hpp"
+#include "RiemannChoice.hpp"
+#include "MultiMat/MultiMatIndexing.hpp"
+#include "Reconstruction.hpp"
+#include "Limiter.hpp"
+#include "Problem/FieldOutput.hpp"
+#include "Problem/BoxInitialization.hpp"
+#include "MultiMat/BCFunctions.hpp"
+#include "MultiMat/MiscMultiMatFns.hpp"
+
+namespace inciter {
+
+extern ctr::InputDeck g_inputdeck;
+
+namespace fv {
 
-std::array< tk::real, 3 >
-tk::eval_gp ( const std::size_t igp,
-              const std::array< std::array< tk::real, 3>, 4 >& coord,
-              const std::array< std::vector< tk::real >, 3 >& coordgp )
-// *****************************************************************************
-//  Compute the coordinates of quadrature points for volume integral in
-//  physical space
-//! \param[in] igp Index of quadrature points
-//! \param[in] coord Array of nodal coordinates for tetrahedron element
-//! \param[in] coordgp Array of coordinates for quadrature points in reference space
-//! \return Array of coordinates for quadrature points in physical space
-// *****************************************************************************
-{
-  // Barycentric coordinates for the tetradedron element
-  auto shp1 = 1.0 - coordgp[0][igp] - coordgp[1][igp] - coordgp[2][igp];
-  auto shp2 = coordgp[0][igp];
-  auto shp3 = coordgp[1][igp];
-  auto shp4 = coordgp[2][igp];
-
-  // Transformation of the quadrature point from the reference/master
-  // element to physical space, to obtain its physical (x,y,z) coordinates.
-  return {{
-   coord[0][0]*shp1 + coord[1][0]*shp2 + coord[2][0]*shp3 + coord[3][0]*shp4,
-   coord[0][1]*shp1 + coord[1][1]*shp2 + coord[2][1]*shp3 + coord[3][1]*shp4,
-   coord[0][2]*shp1 + coord[1][2]*shp2 + coord[2][2]*shp3 + coord[3][2]*shp4 }};
-}
-
-std::array< std::vector<tk::real>, 3 >
-tk::eval_dBdxi( const std::size_t ndof,
-  const std::array< tk::real, 3 >& coordgp )
-// *****************************************************************************
-//  Compute the derivatives of Dubiner basis wrt. reference coordinates
-//! \param[in] ndof Number of degrees of freedom
-//! \param[in] coordgp Coordinates in ref element where derivatives are needed
-//! \return Array of the derivatives of basis functions
-// *****************************************************************************
-{
-  // Initialize array
-  std::array< std::vector< tk::real >, 3 > dBdxi;
-  for (std::size_t idir=0; idir<3; ++idir) {
-    dBdxi[idir].resize(ndof, 0.0);
-  }
+//! \brief MultiMat used polymorphically with tk::FVPDE
+//! \details The template arguments specify policies and are used to configure
+//!   the behavior of the class. The policies are:
+//!   - Physics - physics configuration, see PDE/MultiMat/Physics.h
+//!   - Problem - problem configuration, see PDE/MultiMat/Problem.h
+//! \note The default physics is Euler, set in inciter::deck::check_multimat()
+template< class Physics, class Problem >
+class MultiMat {
+
+  private:
+    using eq = tag::multimat;
+
+  public:
+    //! Constructor
+    explicit MultiMat() :
+      m_physics(),
+      m_ncomp( g_inputdeck.get< tag::ncomp >() ),
+      m_riemann( multimatRiemannSolver(
+        g_inputdeck.get< tag::flux >() ) )
+    {
+      // associate boundary condition configurations with state functions
+      brigand::for_each< ctr::bclist::Keys >( ConfigBC( m_bc,
+        { dirichlet
+        , symmetry
+        , invalidBC         // Inlet BC not implemented
+        , invalidBC         // Outlet BC not implemented
+        , farfieldOutlet
+        , extrapolate } ) );
+
+      // EoS initialization
+      initializeMaterialEoS( m_mat_blk );
+    }
+
+    //! Find the number of primitive quantities required for this PDE system
+    //! \return The number of primitive quantities required to be stored for
+    //!   this PDE system
+    std::size_t nprim() const<--- Shadowed declaration
+    {
+      auto nmat = g_inputdeck.get< tag::multimat, tag::nmat >();<--- Shadow variable
+      // multimat needs individual material pressures and velocities currently
+      return (nmat+3);
+    }
 
-  // high-order basis
-  if (ndof > 1) {
-    dBdxi[0][0] = 0.0;
-    dBdxi[1][0] = 0.0;
-    dBdxi[2][0] = 0.0;
-
-    dBdxi[0][1] = 2.0;
-    dBdxi[1][1] = 1.0;
-    dBdxi[2][1] = 1.0;
-
-    dBdxi[0][2] = 0.0;
-    dBdxi[1][2] = 3.0;
-    dBdxi[2][2] = 1.0;
-
-    dBdxi[0][3] = 0.0;
-    dBdxi[1][3] = 0.0;
-    dBdxi[2][3] = 4.0;
-
-    if (ndof > 4) {
-      dBdxi[0][4] = 12.0 * coordgp[0] + 6.0 * coordgp[1]
-                  +  6.0 * coordgp[2] - 6.0;
-      dBdxi[1][4] =  6.0 * coordgp[0] + 2.0 * coordgp[1]
-                  +  2.0 * coordgp[2] - 2.0;
-      dBdxi[2][4] =  6.0 * coordgp[0] + 2.0 * coordgp[1]
-                  +  2.0 * coordgp[2] - 2.0;
-
-      dBdxi[0][5] = 10.0 * coordgp[1] +  2.0 * coordgp[2] - 2.0;
-      dBdxi[1][5] = 10.0 * coordgp[0] + 10.0 * coordgp[1]
-                  +  6.0 * coordgp[2] - 6.0;
-      dBdxi[2][5] =  2.0 * coordgp[0] +  6.0 * coordgp[1]
-                  +  2.0 * coordgp[2] - 2.0;
-
-      dBdxi[0][6] = 12.0 * coordgp[2] - 2.0;
-      dBdxi[1][6] =  6.0 * coordgp[2] - 1.0;
-      dBdxi[2][6] = 12.0 * coordgp[0] + 6.0 * coordgp[1]
-                  + 12.0 * coordgp[2] - 7.0;
-
-      dBdxi[0][7] = 0.0;
-      dBdxi[1][7] = 20.0 * coordgp[1] + 8.0 * coordgp[2] - 8.0;
-      dBdxi[2][7] =  8.0 * coordgp[1] + 2.0 * coordgp[2] - 2.0;
-
-      dBdxi[0][8] = 0.0;
-      dBdxi[1][8] = 18.0 * coordgp[2] -  3.0;
-      dBdxi[2][8] = 18.0 * coordgp[1] + 12.0 * coordgp[2] - 7.0;
-
-      dBdxi[0][9] = 0.0;
-      dBdxi[1][9] = 0.0;
-      dBdxi[2][9] = 30.0 * coordgp[2] - 10.0;
-    }
-  }
-
-  return dBdxi;
-}
-
-std::array< std::vector<tk::real>, 3 >
-tk::eval_dBdx_p1( const std::size_t ndof,
-                  const std::array< std::array< tk::real, 3 >, 3 >& jacInv )
-// *****************************************************************************
-//  Compute the derivatives of basis functions for DG(P1)
-//! \param[in] ndof Number of degrees of freedom
-//! \param[in] jacInv Array of the inverse of Jacobian
-//! \return Array of the derivatives of basis functions
-// *****************************************************************************
-{
-  // The derivatives of the basis functions dB/dx are easily calculated
-  // via a transformation to the reference space as,
-  // dB/dx = dB/dxi . dxi/dx,
-  // where, x = (x,y,z) are the physical coordinates, and
-  //        xi = (xi, eta, zeta) are the reference coordinates.
-  // The matrix dxi/dx is the inverse of the Jacobian of transformation
-  // and the matrix vector product has to be calculated. This follows.
-
-  std::array< std::vector<tk::real>, 3 > dBdx;
-  dBdx[0].resize( ndof, 0 );
-  dBdx[1].resize( ndof, 0 );
-  dBdx[2].resize( ndof, 0 );
-
-  auto db2dxi1 = 2.0;
-  auto db2dxi2 = 1.0;
-  auto db2dxi3 = 1.0;
-
-  auto db3dxi1 = 0.0;
-  auto db3dxi2 = 3.0;
-  auto db3dxi3 = 1.0;
+    //! Find the number of materials set up for this PDE system
+    //! \return The number of materials set up for this PDE system
+    std::size_t nmat() const<--- Shadowed declaration<--- Shadowed declaration<--- Shadowed declaration<--- Shadowed declaration<--- Shadowed declaration<--- Shadowed declaration<--- Shadowed declaration<--- Shadowed declaration<--- Shadowed declaration<--- Shadowed declaration<--- Shadowed declaration<--- Shadowed declaration<--- Shadowed declaration<--- Shadowed declaration<--- Shadowed declaration<--- Shadowed declaration<--- Shadowed declaration
+    {
+      auto nmat = g_inputdeck.get< tag::multimat, tag::nmat >();
+      return nmat;
+    }
+
+    //! Determine elements that lie inside the user-defined IC box
+    //! \param[in] geoElem Element geometry array
+    //! \param[in] nielem Number of internal elements
+    //! \param[in,out] inbox List of nodes at which box user ICs are set for
+    //!    each IC box
+    void IcBoxElems( const tk::Fields& geoElem,
+      std::size_t nielem,
+      std::vector< std::unordered_set< std::size_t > >& inbox ) const
+    {
+      tk::BoxElems< eq >(geoElem, nielem, inbox);
+    }
+
+    //! Initalize the compressible flow equations, prepare for time integration
+    //! \param[in] L Block diagonal mass matrix
+    //! \param[in] inpoel Element-node connectivity
+    //! \param[in] coord Array of nodal coordinates
+    //! \param[in] inbox List of elements at which box user ICs are set for
+    //!   each IC box
+    //! \param[in] elemblkid Element ids associated with mesh block ids where
+    //!   user ICs are set
+    //! \param[in,out] unk Array of unknowns
+    //! \param[in] t Physical time
+    //! \param[in] nielem Number of internal elements
+    void initialize( const tk::Fields& L,
+      const std::vector< std::size_t >& inpoel,
+      const tk::UnsMesh::Coords& coord,
+      const std::vector< std::unordered_set< std::size_t > >& inbox,
+      const std::unordered_map< std::size_t, std::set< std::size_t > >&
+        elemblkid,
+      tk::Fields& unk,
+      tk::real t,
+      const std::size_t nielem ) const
+    {
+      tk::initialize( m_ncomp, m_mat_blk, L, inpoel, coord,
+                      Problem::initialize, unk, t, nielem );
+
+      const auto rdof = g_inputdeck.get< tag::rdof >();
+      const auto& ic = g_inputdeck.get< tag::ic >();
+      const auto& icbox = ic.get< tag::box >();
+      const auto& icmbk = ic.get< tag::meshblock >();
+
+      const auto& bgpre = ic.get< tag::pressure >();
+      const auto& bgtemp = ic.get< tag::temperature >();
+
+      // Set initial conditions inside user-defined IC boxes and mesh blocks
+      std::vector< tk::real > s(m_ncomp, 0.0);
+      for (std::size_t e=0; e<nielem; ++e) {
+        // inside user-defined box
+        if (!icbox.empty()) {
+          std::size_t bcnt = 0;
+          for (const auto& b : icbox) {   // for all boxes
+            if (inbox.size() > bcnt && inbox[bcnt].find(e) != inbox[bcnt].end())
+            {
+              std::vector< tk::real > box
+                { b.template get< tag::xmin >(), b.template get< tag::xmax >(),
+                  b.template get< tag::ymin >(), b.template get< tag::ymax >(),
+                  b.template get< tag::zmin >(), b.template get< tag::zmax >() };
+              auto V_ex = (box[1]-box[0]) * (box[3]-box[2]) * (box[5]-box[4]);
+              for (std::size_t c=0; c<m_ncomp; ++c) {
+                auto mark = c*rdof;
+                s[c] = unk(e,mark);
+                // set high-order DOFs to zero
+                for (std::size_t i=1; i<rdof; ++i)
+                  unk(e,mark+i) = 0.0;
+              }
+              initializeBox<ctr::boxList>( m_mat_blk, V_ex, t, b, bgpre,
+                bgtemp, s );
+              // store box-initialization in solution vector
+              for (std::size_t c=0; c<m_ncomp; ++c) {
+                auto mark = c*rdof;
+                unk(e,mark) = s[c];
+              }
+            }
+            ++bcnt;
+          }
+        }
 
-  auto db4dxi1 = 0.0;
-  auto db4dxi2 = 0.0;
-  auto db4dxi3 = 4.0;
-
-  dBdx[0][1] =  db2dxi1 * jacInv[0][0]
-              + db2dxi2 * jacInv[1][0]
-              + db2dxi3 * jacInv[2][0];
-
-  dBdx[1][1] =  db2dxi1 * jacInv[0][1]
-              + db2dxi2 * jacInv[1][1]
-              + db2dxi3 * jacInv[2][1];
-
-  dBdx[2][1] =  db2dxi1 * jacInv[0][2]
-              + db2dxi2 * jacInv[1][2]
-              + db2dxi3 * jacInv[2][2];
-
-  dBdx[0][2] =  db3dxi1 * jacInv[0][0]
-              + db3dxi2 * jacInv[1][0]
-              + db3dxi3 * jacInv[2][0];
+        // inside user-specified mesh blocks
+        for (const auto& b : icmbk) { // for all blocks
+          auto blid = b.get< tag::blockid >();
+          auto V_ex = b.get< tag::volume >();
+          if (elemblkid.find(blid) != elemblkid.end()) {
+            const auto& elset = tk::cref_find(elemblkid, blid);
+            if (elset.find(e) != elset.end()) {
+              initializeBox<ctr::meshblockList>( m_mat_blk, V_ex, t, b,
+                bgpre, bgtemp, s );
+              // store initialization in solution vector
+              for (std::size_t c=0; c<m_ncomp; ++c) {
+                auto mark = c*rdof;
+                unk(e,mark) = s[c];
+              }
+            }
+          }
+        }
+      }
+    }
 
-  dBdx[1][2] =  db3dxi1 * jacInv[0][1]
-              + db3dxi2 * jacInv[1][1]
-              + db3dxi3 * jacInv[2][1];
-
-  dBdx[2][2] =  db3dxi1 * jacInv[0][2]
-              + db3dxi2 * jacInv[1][2]
-              + db3dxi3 * jacInv[2][2];
-
-  dBdx[0][3] =  db4dxi1 * jacInv[0][0]
-              + db4dxi2 * jacInv[1][0]
-              + db4dxi3 * jacInv[2][0];
-
-  dBdx[1][3] =  db4dxi1 * jacInv[0][1]
-              + db4dxi2 * jacInv[1][1]
-              + db4dxi3 * jacInv[2][1];
-
-  dBdx[2][3] =  db4dxi1 * jacInv[0][2]
-              + db4dxi2 * jacInv[1][2]
-              + db4dxi3 * jacInv[2][2];
-
-  return dBdx;
-}
-
-void
-tk::eval_dBdx_p2( const std::size_t igp,
-                  const std::array< std::vector< tk::real >, 3 >& coordgp,
-                  const std::array< std::array< tk::real, 3 >, 3 >& jacInv,
-                  std::array< std::vector<tk::real>, 3 >& dBdx )
-// *****************************************************************************
-//  Compute the derivatives of Dubiner basis function for DG(P2)
-//! \param[in] igp Index of quadrature points
-//! \param[in] coordgp Gauss point coordinates for tetrahedron element
-//! \param[in] jacInv Array of the inverse of Jacobian
-//! \param[in,out] dBdx Array of the derivatives of basis function
-// *****************************************************************************
-{
-  auto db5dxi1 = 12.0 * coordgp[0][igp] + 6.0 * coordgp[1][igp]
-               +  6.0 * coordgp[2][igp] - 6.0;
-  auto db5dxi2 =  6.0 * coordgp[0][igp] + 2.0 * coordgp[1][igp]
-               +  2.0 * coordgp[2][igp] - 2.0;
-  auto db5dxi3 =  6.0 * coordgp[0][igp] + 2.0 * coordgp[1][igp]
-               +  2.0 * coordgp[2][igp] - 2.0;
-
-  auto db6dxi1 = 10.0 * coordgp[1][igp] +  2.0 * coordgp[2][igp] - 2.0;
-  auto db6dxi2 = 10.0 * coordgp[0][igp] + 10.0 * coordgp[1][igp]
-               +  6.0 * coordgp[2][igp] - 6.0;
-  auto db6dxi3 =  2.0 * coordgp[0][igp] +  6.0 * coordgp[1][igp]
-               +  2.0 * coordgp[2][igp] - 2.0;
-
-  auto db7dxi1 = 12.0 * coordgp[2][igp] - 2.0;
-  auto db7dxi2 =  6.0 * coordgp[2][igp] - 1.0;
-  auto db7dxi3 = 12.0 * coordgp[0][igp] + 6.0 * coordgp[1][igp]
-               + 12.0 * coordgp[2][igp] - 7.0;
-
-  auto db8dxi1 =  0;
-  auto db8dxi2 = 20.0 * coordgp[1][igp] + 8.0 * coordgp[2][igp] - 8.0;
-  auto db8dxi3 =  8.0 * coordgp[1][igp] + 2.0 * coordgp[2][igp] - 2.0;
-
-  auto db9dxi1 =  0;
-  auto db9dxi2 = 18.0 * coordgp[2][igp] -  3.0;
-  auto db9dxi3 = 18.0 * coordgp[1][igp] + 12.0 * coordgp[2][igp] - 7.0;
-
-  auto db10dxi1 =  0;
-  auto db10dxi2 =  0;
-  auto db10dxi3 = 30.0 * coordgp[2][igp] - 10.0;
-
-  dBdx[0][4] =  db5dxi1 * jacInv[0][0]
-              + db5dxi2 * jacInv[1][0]
-              + db5dxi3 * jacInv[2][0];
-
-  dBdx[1][4] =  db5dxi1 * jacInv[0][1]
-              + db5dxi2 * jacInv[1][1]
-              + db5dxi3 * jacInv[2][1];
+    //! Compute the left hand side block-diagonal mass matrix
+    //! \param[in] geoElem Element geometry array
+    //! \param[in,out] l Block diagonal mass matrix
+    void lhs( const tk::Fields& geoElem, tk::Fields& l ) const {<--- Parameter 'l' can be declared with const
+      const auto nelem = geoElem.nunk();
+      for (std::size_t e=0; e<nelem; ++e)
+        for (ncomp_t c=0; c<m_ncomp; ++c)
+          l(e, c) = geoElem(e,0);
+    }
+
+    //! Update the primitives for this PDE system
+    //! \param[in] unk Array of unknowns
+    //! \param[in,out] prim Array of primitives
+    //! \param[in] nielem Number of internal elements
+    //! \details This function computes and stores the dofs for primitive
+    //!   quantities, which are required for obtaining reconstructed states used
+    //!   in the Riemann solver. See /PDE/Riemann/AUSM.hpp, where the
+    //!   normal velocity for advection is calculated from independently
+    //!   reconstructed velocities.
+    void updatePrimitives( const tk::Fields& unk,
+                           tk::Fields& prim,<--- Parameter 'prim' can be declared with const
+                           std::size_t nielem ) const
+    {
+      const auto rdof = g_inputdeck.get< tag::rdof >();<--- Variable 'rdof' is assigned a value that is never used.
+      auto nmat = g_inputdeck.get< tag::multimat, tag::nmat >();<--- Shadow variable<--- Variable 'nmat' is assigned a value that is never used.
+
+      Assert( unk.nunk() == prim.nunk(), "Number of unknowns in solution "
+              "vector and primitive vector at recent time step incorrect" );
+      Assert( unk.nprop() == rdof*m_ncomp, "Number of components in solution "
+              "vector must equal "+ std::to_string(rdof*m_ncomp) );
+      Assert( prim.nprop() == rdof*nprim(), "Number of components in vector of "
+              "primitive quantities must equal "+ std::to_string(rdof*nprim()) );
+
+      for (std::size_t e=0; e<nielem; ++e)
+      {
+        // cell-average bulk density
+        tk::real rhob(0.0);
+        for (std::size_t k=0; k<nmat; ++k)
+        {
+          rhob += unk(e, densityDofIdx(nmat, k, rdof, 0));
+        }
+
+        // cell-average velocity
+        std::array< tk::real, 3 >
+          vel{{ unk(e, momentumDofIdx(nmat, 0, rdof, 0))/rhob,
+                unk(e, momentumDofIdx(nmat, 1, rdof, 0))/rhob,
+                unk(e, momentumDofIdx(nmat, 2, rdof, 0))/rhob }};
+
+        for (std::size_t idir=0; idir<3; ++idir)
+        {
+          prim(e, velocityDofIdx(nmat, idir, rdof, 0)) = vel[idir];
+          for (std::size_t idof=1; idof<rdof; ++idof)
+            prim(e, velocityDofIdx(nmat, idir, rdof, idof)) = 0.0;
+        }
+
+        // cell-average material pressure
+        for (std::size_t k=0; k<nmat; ++k)
+        {
+          tk::real arhomat = unk(e, densityDofIdx(nmat, k, rdof, 0));
+          tk::real arhoemat = unk(e, energyDofIdx(nmat, k, rdof, 0));
+          tk::real alphamat = unk(e, volfracDofIdx(nmat, k, rdof, 0));
+          auto gmat = getDeformGrad(nmat, k, unk.extract(e));
+          prim(e, pressureDofIdx(nmat, k, rdof, 0)) =
+            m_mat_blk[k].compute< EOS::pressure >( arhomat, vel[0], vel[1],
+            vel[2], arhoemat, alphamat, k, gmat );
+          prim(e, pressureDofIdx(nmat, k, rdof, 0)) =
+            constrain_pressure( m_mat_blk,
+            prim(e, pressureDofIdx(nmat, k, rdof, 0)), arhomat, alphamat, k);
+          for (std::size_t idof=1; idof<rdof; ++idof)
+            prim(e, pressureDofIdx(nmat, k, rdof, idof)) = 0.0;
+        }
+      }
+    }
 
-  dBdx[2][4] =  db5dxi1 * jacInv[0][2]
-              + db5dxi2 * jacInv[1][2]
-              + db5dxi3 * jacInv[2][2];
-
-  dBdx[0][5] =  db6dxi1 * jacInv[0][0]
-              + db6dxi2 * jacInv[1][0]
-              + db6dxi3 * jacInv[2][0];
-
-  dBdx[1][5] =  db6dxi1 * jacInv[0][1]
-              + db6dxi2 * jacInv[1][1]
-              + db6dxi3 * jacInv[2][1];
-
-  dBdx[2][5] =  db6dxi1 * jacInv[0][2]
-              + db6dxi2 * jacInv[1][2]
-              + db6dxi3 * jacInv[2][2];
-
-  dBdx[0][6] =  db7dxi1 * jacInv[0][0]
-              + db7dxi2 * jacInv[1][0]
-              + db7dxi3 * jacInv[2][0];
-
-  dBdx[1][6] =  db7dxi1 * jacInv[0][1]
-              + db7dxi2 * jacInv[1][1]
-              + db7dxi3 * jacInv[2][1];
-
-  dBdx[2][6] =  db7dxi1 * jacInv[0][2]
-              + db7dxi2 * jacInv[1][2]
-              + db7dxi3 * jacInv[2][2];
-
-  dBdx[0][7] =  db8dxi1 * jacInv[0][0]
-              + db8dxi2 * jacInv[1][0]
-              + db8dxi3 * jacInv[2][0];
+    //! Clean up the state of trace materials for this PDE system
+    //! \param[in] t Physical time
+    //! \param[in] geoElem Element geometry array
+    //! \param[in,out] unk Array of unknowns
+    //! \param[in,out] prim Array of primitives
+    //! \param[in] nielem Number of internal elements
+    //! \details This function cleans up the state of materials present in trace
+    //!   quantities in each cell. Specifically, the state of materials with
+    //!   very low volume-fractions in a cell is replaced by the state of the
+    //!   material which is present in the largest quantity in that cell. This
+    //!   becomes necessary when shocks pass through cells which contain a very
+    //!   small amount of material. The state of that tiny material might
+    //!   become unphysical and cause solution to diverge; thus requiring such
+    //!   a "reset".
+    void cleanTraceMaterial( tk::real t,
+                             const tk::Fields& geoElem,
+                             tk::Fields& unk,
+                             tk::Fields& prim,
+                             std::size_t nielem ) const
+    {
+      [[maybe_unused]] const auto rdof = g_inputdeck.get< tag::rdof >();
+      auto nmat = g_inputdeck.get< tag::multimat, tag::nmat >();<--- Shadow variable<--- Variable 'nmat' is assigned a value that is never used.
+
+      Assert( unk.nunk() == prim.nunk(), "Number of unknowns in solution "
+              "vector and primitive vector at recent time step incorrect" );
+      Assert( unk.nprop() == rdof*m_ncomp, "Number of components in solution "
+              "vector must equal "+ std::to_string(rdof*m_ncomp) );
+      Assert( prim.nprop() == rdof*nprim(), "Number of components in vector of "
+              "primitive quantities must equal "+ std::to_string(rdof*nprim()) );
+      Assert( (g_inputdeck.get< tag::ndof >()) <= 4, "High-order "
+              "discretizations not set up for multimat cleanTraceMaterial()" );
 
-  dBdx[1][7] =  db8dxi1 * jacInv[0][1]
-              + db8dxi2 * jacInv[1][1]
-              + db8dxi3 * jacInv[2][1];
-
-  dBdx[2][7] =  db8dxi1 * jacInv[0][2]
-              + db8dxi2 * jacInv[1][2]
-              + db8dxi3 * jacInv[2][2];
-
-  dBdx[0][8] =  db9dxi1 * jacInv[0][0]
-              + db9dxi2 * jacInv[1][0]
-              + db9dxi3 * jacInv[2][0];
-
-  dBdx[1][8] =  db9dxi1 * jacInv[0][1]
-              + db9dxi2 * jacInv[1][1]
-              + db9dxi3 * jacInv[2][1];
-
-  dBdx[2][8] =  db9dxi1 * jacInv[0][2]
-              + db9dxi2 * jacInv[1][2]
-              + db9dxi3 * jacInv[2][2];
-
-  dBdx[0][9] =  db10dxi1 * jacInv[0][0]
-              + db10dxi2 * jacInv[1][0]
-              + db10dxi3 * jacInv[2][0];
-
-  dBdx[1][9] =  db10dxi1 * jacInv[0][1]
-              + db10dxi2 * jacInv[1][1]
-              + db10dxi3 * jacInv[2][1];
-
-  dBdx[2][9] =  db10dxi1 * jacInv[0][2]
-              + db10dxi2 * jacInv[1][2]
-              + db10dxi3 * jacInv[2][2];
-}
-
-std::vector< tk::real >
-tk::eval_basis( const std::size_t ndof,
-                const tk::real xi,
-                const tk::real eta,
-                const tk::real zeta )
-// *****************************************************************************
-//  Compute the Dubiner basis functions
-//! \param[in] ndof Number of degrees of freedom
-//! \param[in] xi,eta,zeta Coordinates for quadrature points in reference space
-//! \return Vector of basis functions
-// *****************************************************************************
-{
-  // Array of basis functions
-  std::vector< tk::real > B( ndof, 1.0 );
-
-  if ( ndof > 1 )           // DG(P1)
-  {
-    B[1] = 2.0 * xi + eta + zeta - 1.0;
-    B[2] = 3.0 * eta + zeta - 1.0;
-    B[3] = 4.0 * zeta - 1.0;
-
-    if( ndof > 4 )         // DG(P2)
-    {
-      B[4] =  6.0 * xi * xi + eta * eta + zeta * zeta
-            + 6.0 * xi * eta + 6.0 * xi * zeta + 2.0 * eta * zeta
-            - 6.0 * xi - 2.0 * eta - 2.0 * zeta + 1.0;
-      B[5] =  5.0 * eta * eta + zeta * zeta
-            + 10.0 * xi * eta + 2.0 * xi * zeta + 6.0 * eta * zeta
-            - 2.0 * xi - 6.0 * eta - 2.0 * zeta + 1.0;
-      B[6] =  6.0 * zeta * zeta + 12.0 * xi * zeta + 6.0 * eta * zeta - 2.0 * xi
-            - eta - 7.0 * zeta + 1.0;
-      B[7] =  10.0 * eta * eta + zeta * zeta + 8.0 * eta * zeta
-            - 8.0 * eta - 2.0 * zeta + 1.0;
-      B[8] =  6.0 * zeta * zeta + 18.0 * eta * zeta - 3.0 * eta - 7.0 * zeta
-            + 1.0;
-      B[9] =  15.0 * zeta * zeta - 10.0 * zeta + 1.0;
-    }
-  }
-
-  return B;
-}
-
-std::vector< tk::real >
-tk::eval_state ( ncomp_t ncomp,
-                 const std::size_t ndof,
-                 const std::size_t ndof_el,
-                 const std::size_t e,
-                 const Fields& U,
-                 const std::vector< tk::real >& B )
-// *****************************************************************************
-//  Compute the state variables for the tetrahedron element
-//! \param[in] ncomp Number of scalar components in this PDE system
-//! \param[in] ndof Maximum number of degrees of freedom
-//! \param[in] ndof_el Number of degrees of freedom for the local element
-//! \param[in] e Index for the tetrahedron element
-//! \param[in] U Solution vector at recent time step
-//! \param[in] B Vector of basis functions
-//! \return Vector of state variable for tetrahedron element
-// *****************************************************************************
-{
-  // This is commented for now because that when p0/p1 adaptive with limiter
-  // applied, the size of basis will be 10. However, ndof_el will be 4 which
-  // leads to a size mismatch in limiter function.
-  //Assert( B.size() == ndof_el, "Size mismatch" );
-
-  if (U.empty()) return {};
-
-  // Array of state variable for tetrahedron element
-  std::vector< tk::real > state( ncomp, 0.0 );
-
-  for (ncomp_t c=0; c<ncomp; ++c)
-  {
-    auto mark = c*ndof;
-    state[c] = U( e, mark );
+      auto neg_density = cleanTraceMultiMat(t, nielem, m_mat_blk, geoElem, nmat,
+        unk, prim);
+
+      if (neg_density) Throw("Negative partial density.");
+    }
+
+    //! Reconstruct second-order solution from first-order
+    //! \param[in] geoElem Element geometry array
+    //! \param[in] fd Face connectivity and boundary conditions object
+    //! \param[in] esup Elements-surrounding-nodes connectivity
+    //! \param[in] inpoel Element-node connectivity
+    //! \param[in] coord Array of nodal coordinates
+    //! \param[in,out] U Solution vector at recent time step
+    //! \param[in,out] P Vector of primitives at recent time step
+    void reconstruct( const tk::Fields& geoElem,
+                      const inciter::FaceData& fd,
+                      const std::map< std::size_t, std::vector< std::size_t > >&
+                        esup,
+                      const std::vector< std::size_t >& inpoel,
+                      const tk::UnsMesh::Coords& coord,
+                      tk::Fields& U,
+                      tk::Fields& P ) const
+    {
+      const auto rdof = g_inputdeck.get< tag::rdof >();
+      const auto nelem = fd.Esuel().size()/4;<--- Variable 'nelem' is assigned a value that is never used.
+      auto nmat = g_inputdeck.get< tag::multimat, tag::nmat >();<--- Shadow variable<--- Variable 'nmat' is assigned a value that is never used.
+
+      Assert( U.nprop() == rdof*m_ncomp, "Number of components in solution "
+              "vector must equal "+ std::to_string(rdof*m_ncomp) );
+
+      //----- reconstruction of conserved quantities -----
+      //--------------------------------------------------
+      // specify how many variables need to be reconstructed
+      std::vector< std::size_t > vars;
+      for (std::size_t k=0; k<nmat; ++k) {
+        vars.push_back(volfracIdx(nmat,k));
+        vars.push_back(densityIdx(nmat,k));
+      }
+
+      // 1. solve 3x3 least-squares system
+      for (std::size_t e=0; e<nelem; ++e)
+      {
+        // Reconstruct second-order dofs of volume-fractions in Taylor space
+        // using nodal-stencils, for a good interface-normal estimate
+        tk::recoLeastSqExtStencil( rdof, e, esup, inpoel, geoElem, U, vars );
+      }
+
+      // 2. transform reconstructed derivatives to Dubiner dofs
+      tk::transform_P0P1(rdof, nelem, inpoel, coord, U, vars);
+
+      //----- reconstruction of primitive quantities -----
+      //--------------------------------------------------
+      // For multimat, conserved and primitive quantities are reconstructed
+      // separately.
+      vars.clear();
+      for (std::size_t c=0; c<nprim(); ++c) vars.push_back(c);
+      // 1.
+      for (std::size_t e=0; e<nelem; ++e)
+      {
+        // Reconstruct second-order dofs of volume-fractions in Taylor space
+        // using nodal-stencils, for a good interface-normal estimate
+        tk::recoLeastSqExtStencil( rdof, e, esup, inpoel, geoElem, P, vars );
+      }
+
+      // 2.
+      tk::transform_P0P1(rdof, nelem, inpoel, coord, P, vars);
+    }
+
+    //! Limit second-order solution, and primitive quantities separately
+    //! \param[in] geoFace Face geometry array
+    //! \param[in] fd Face connectivity and boundary conditions object
+    //! \param[in] esup Elements-surrounding-nodes connectivity
+    //! \param[in] inpoel Element-node connectivity
+    //! \param[in] coord Array of nodal coordinates
+    //! \param[in] srcFlag Whether the energy source was added
+    //! \param[in,out] U Solution vector at recent time step
+    //! \param[in,out] P Vector of primitives at recent time step
+    void limit( const tk::Fields& geoFace,
+                const inciter::FaceData& fd,
+                const std::map< std::size_t, std::vector< std::size_t > >& esup,
+                const std::vector< std::size_t >& inpoel,
+                const tk::UnsMesh::Coords& coord,
+                const std::vector< int >& srcFlag,
+                tk::Fields& U,
+                tk::Fields& P ) const
+    {
+      Assert( U.nunk() == P.nunk(), "Number of unknowns in solution "
+              "vector and primitive vector at recent time step incorrect" );
+
+      const auto limiter = g_inputdeck.get< tag::limiter >();
+      auto nmat = g_inputdeck.get< tag::multimat, tag::nmat >();<--- Shadow variable
+      const auto& solidx = g_inputdeck.get<
+        tag::matidxmap, tag::solidx >();
+
+      // limit vectors of conserved and primitive quantities
+      if (limiter == ctr::LimiterType::VERTEXBASEDP1)
+      {
+        VertexBasedMultiMat_FV( esup, inpoel, fd.Esuel().size()/4,
+          coord, srcFlag, solidx, U, P, nmat );
+        PositivityPreservingMultiMat_FV( inpoel, fd.Esuel().size()/4, nmat,
+          m_mat_blk, coord, geoFace, U, P );
+      }
+      else if (limiter != ctr::LimiterType::NOLIMITER)
+      {
+        Throw("Limiter type not configured for multimat.");
+      }
+    }
 
-    if(ndof_el > 1)        //DG(P1)
-    {
-      state[c] += U( e, mark+1 ) * B[1]
-                + U( e, mark+2 ) * B[2]
-                + U( e, mark+3 ) * B[3];
-    }
-
-    if(ndof_el > 4)        //DG(P2)
-    {
-      state[c] += U( e, mark+4 ) * B[4]
-                + U( e, mark+5 ) * B[5]
-                + U( e, mark+6 ) * B[6]
-                + U( e, mark+7 ) * B[7]
-                + U( e, mark+8 ) * B[8]
-                + U( e, mark+9 ) * B[9];
-    }
-  }
-
-  return state;
-}
-
-std::vector< std::vector< tk::real > >
-tk::DubinerToTaylor( ncomp_t ncomp,
-                     const std::size_t e,
-                     const std::size_t ndof,
-                     const tk::Fields& U,
-                     const std::vector< std::size_t >& inpoel,
-                     const tk::UnsMesh::Coords& coord )
-// *****************************************************************************
-//  Transform the solution with Dubiner basis to the solution with Taylor basis
-//! \param[in] ncomp Number of scalar components in this PDE system
-//! \param[in] e Id of element whose solution is to be limited
-//! \param[in] ndof Maximum number of degrees of freedom
-//! \param[in] U High-order solution vector with Dubiner basis
-//! \param[in] inpoel Element connectivity
-//! \param[in] coord Array of nodal coordinates
-//! \return High-order solution vector with Taylor basis
-// *****************************************************************************
-{
-  std::vector< std::vector< tk::real > >
-    unk(ncomp, std::vector<tk::real>(ndof, 0.0));
-
-  const auto& cx = coord[0];
-  const auto& cy = coord[1];
-  const auto& cz = coord[2];
-
-  std::array< std::vector< tk::real >, 3 > center;
-  center[0].resize(1, 0.25);
-  center[1].resize(1, 0.25);
-  center[2].resize(1, 0.25);
-
-  // Evaluate the cell center solution
-  for(ncomp_t icomp = 0; icomp < ncomp; icomp++)
-  {
-    auto mark = icomp * ndof;
-    unk[icomp][0] = U(e, mark);
-  }
-
-  // Evaluate the first order derivative
-  std::array< std::array< tk::real, 3>, 4 > coordel {{
-    {{ cx[ inpoel[4*e  ] ], cy[ inpoel[4*e  ] ], cz[ inpoel[4*e  ] ] }},
-    {{ cx[ inpoel[4*e+1] ], cy[ inpoel[4*e+1] ], cz[ inpoel[4*e+1] ] }},
-    {{ cx[ inpoel[4*e+2] ], cy[ inpoel[4*e+2] ], cz[ inpoel[4*e+2] ] }},
-    {{ cx[ inpoel[4*e+3] ], cy[ inpoel[4*e+3] ], cz[ inpoel[4*e+3] ] }}
-  }};
+    //! Apply CPL to the conservative variable solution for this PDE system
+    //! \param[in] prim Array of primitive variables
+    //! \param[in] geoElem Element geometry array
+    //! \param[in] inpoel Element-node connectivity
+    //! \param[in] coord Array of nodal coordinates
+    //! \param[in,out] unk Array of conservative variables
+    //! \param[in] nielem Number of internal elements
+    //! \details This function applies CPL to obtain consistent dofs for
+    //!   conservative quantities based on the limited primitive quantities.
+    //!   See Pandare et al. (2023). On the Design of Stable,
+    //!   Consistent, and Conservative High-Order Methods for Multi-Material
+    //!   Hydrodynamics. J Comp Phys, 112313.
+    void CPL( const tk::Fields& prim,
+      const tk::Fields& geoElem,
+      const std::vector< std::size_t >& inpoel,
+      const tk::UnsMesh::Coords& coord,
+      tk::Fields& unk,
+      std::size_t nielem ) const
+    {
+      [[maybe_unused]] const auto rdof = g_inputdeck.get< tag::rdof >();
+      auto nmat = g_inputdeck.get< tag::multimat, tag::nmat >();<--- Shadow variable<--- Variable 'nmat' is assigned a value that is never used.
+
+      Assert( unk.nunk() == prim.nunk(), "Number of unknowns in solution "
+              "vector and primitive vector at recent time step incorrect" );
+      Assert( unk.nprop() == rdof*m_ncomp, "Number of components in solution "
+              "vector must equal "+ std::to_string(rdof*m_ncomp) );
+      Assert( prim.nprop() == rdof*nprim(), "Number of components in vector of "
+              "primitive quantities must equal "+ std::to_string(rdof*nprim()) );
+
+      correctLimConservMultiMat(nielem, m_mat_blk, nmat, inpoel,
+        coord, geoElem, prim, unk);
+    }
+
+    //! Compute right hand side
+    //! \param[in] t Physical time
+    //! \param[in] geoFace Face geometry array
+    //! \param[in] geoElem Element geometry array
+    //! \param[in] fd Face connectivity and boundary conditions object
+    //! \param[in] inpoel Element-node connectivity
+    //! \param[in] coord Array of nodal coordinates
+    //! \param[in] elemblkid Element ids associated with mesh block ids where
+    //!   user ICs are set
+    //! \param[in] U Solution vector at recent time step
+    //! \param[in] P Primitive vector at recent time step
+    //! \param[in,out] R Right-hand side vector computed
+    //! \param[in,out] srcFlag Whether the energy source was added
+    void rhs( tk::real t,
+              const tk::Fields& geoFace,
+              const tk::Fields& geoElem,
+              const inciter::FaceData& fd,
+              const std::vector< std::size_t >& inpoel,
+              const tk::UnsMesh::Coords& coord,
+              const std::unordered_map< std::size_t, std::set< std::size_t > >&
+                elemblkid,
+              const tk::Fields& U,
+              const tk::Fields& P,
+              tk::Fields& R,
+              std::vector< int >& srcFlag ) const
+    {
+      const auto rdof = g_inputdeck.get< tag::rdof >();
+      auto nmat = g_inputdeck.get< tag::multimat, tag::nmat >();<--- Shadow variable
+      const auto intsharp =
+        g_inputdeck.get< tag::multimat, tag::intsharp >();
+
+      const auto nelem = fd.Esuel().size()/4;
 
-  auto jacInv =
-              tk::inverseJacobian( coordel[0], coordel[1], coordel[2], coordel[3] );
-
-  // Compute the derivatives of basis function for DG(P1)
-  auto dBdx = tk::eval_dBdx_p1( ndof, jacInv );
-
-  if(ndof > 4) {
-    tk::eval_dBdx_p2(0, center, jacInv, dBdx);
-  }
-
-  for(ncomp_t icomp = 0; icomp < ncomp; icomp++)
-  {
-    auto mark = icomp * ndof; 
-    for(std::size_t idir = 0; idir < 3; idir++)
-    {
-      unk[icomp][idir+1] = 0;
-      for(std::size_t idof = 1; idof < ndof; idof++)
-        unk[icomp][idir+1] += U(e, mark+idof) * dBdx[idir][idof];
-    }
-  }
-
-  // Evaluate the second order derivative if DGP2 is applied
-  // The basic idea of the computation follows
-  //    d2Udx2 = /sum u_i * (d2B_i/dx2)
-  // where d2B_i/dx2 = d( dB_i/dxi * dxi/dx ) / dxi * dxi/dx
-  if(ndof > 4)
-  {
-    // Matrix to store the second order derivatives of basis functions in
-    // reference domain
-    tk::real d2Bdxi2[6][6] =
-    { { 12.0,  0.0,  0.0,  0.0,  0.0,  0.0 },
-      {  2.0, 10.0,  0.0, 20.0,  0.0,  0.0 },
-      {  2.0,  2.0, 12.0,  2.0, 12.0, 30.0 },
-      {  6.0, 10.0,  0.0,  0.0,  0.0,  0.0 },
-      {  6.0,  2.0, 12.0,  0.0,  0.0,  0.0 },
-      {  2.0,  6.0,  6.0,  8.0, 18.0,  0.0 } };
-
-    // Transform matrix to convert the second order derivatives of basis
-    // function in reference domain to the one in physical domain
-    tk::real d2xdxi2[6][6];
-
-    d2xdxi2[0][0] = jacInv[0][0] * jacInv[0][0];
-    d2xdxi2[0][1] = jacInv[1][0] * jacInv[1][0];
-    d2xdxi2[0][2] = jacInv[2][0] * jacInv[2][0];
-    d2xdxi2[0][3] = jacInv[0][0] * jacInv[1][0] * 2.0;
-    d2xdxi2[0][4] = jacInv[0][0] * jacInv[2][0] * 2.0;
-    d2xdxi2[0][5] = jacInv[1][0] * jacInv[2][0] * 2.0;
-
-    d2xdxi2[1][0] = jacInv[0][1] * jacInv[0][1];
-    d2xdxi2[1][1] = jacInv[1][1] * jacInv[1][1];
-    d2xdxi2[1][2] = jacInv[2][1] * jacInv[2][1];
-    d2xdxi2[1][3] = jacInv[0][1] * jacInv[1][1] * 2.0;
-    d2xdxi2[1][4] = jacInv[0][1] * jacInv[2][1] * 2.0;
-    d2xdxi2[1][5] = jacInv[1][1] * jacInv[2][1] * 2.0;
-
-    d2xdxi2[2][0] = jacInv[0][2] * jacInv[0][2];
-    d2xdxi2[2][1] = jacInv[1][2] * jacInv[1][2];
-    d2xdxi2[2][2] = jacInv[2][2] * jacInv[2][2];
-    d2xdxi2[2][3] = jacInv[0][2] * jacInv[1][2] * 2.0;
-    d2xdxi2[2][4] = jacInv[0][2] * jacInv[2][2] * 2.0;
-    d2xdxi2[2][5] = jacInv[1][2] * jacInv[2][2] * 2.0;
-
-    d2xdxi2[3][0] = jacInv[0][0] * jacInv[0][1];
-    d2xdxi2[3][1] = jacInv[1][0] * jacInv[1][1];
-    d2xdxi2[3][2] = jacInv[2][0] * jacInv[2][1];
-    d2xdxi2[3][3] = jacInv[0][0] * jacInv[1][1] + jacInv[1][0] * jacInv[0][1];
-    d2xdxi2[3][4] = jacInv[0][0] * jacInv[2][1] + jacInv[2][0] * jacInv[0][1];
-    d2xdxi2[3][5] = jacInv[1][0] * jacInv[2][1] + jacInv[2][0] * jacInv[1][1];
-
-    d2xdxi2[4][0] = jacInv[0][0] * jacInv[0][2];
-    d2xdxi2[4][1] = jacInv[1][0] * jacInv[1][2];
-    d2xdxi2[4][2] = jacInv[2][0] * jacInv[2][2];
-    d2xdxi2[4][3] = jacInv[0][0] * jacInv[1][2] + jacInv[1][0] * jacInv[0][2];
-    d2xdxi2[4][4] = jacInv[0][0] * jacInv[2][2] + jacInv[2][0] * jacInv[0][2];
-    d2xdxi2[4][5] = jacInv[1][0] * jacInv[2][2] + jacInv[2][0] * jacInv[1][2];
-
-    d2xdxi2[5][0] = jacInv[0][1] * jacInv[0][2];
-    d2xdxi2[5][1] = jacInv[1][1] * jacInv[1][2];
-    d2xdxi2[5][2] = jacInv[2][1] * jacInv[2][2];
-    d2xdxi2[5][3] = jacInv[0][1] * jacInv[1][2] + jacInv[1][1] * jacInv[0][2];
-    d2xdxi2[5][4] = jacInv[0][1] * jacInv[2][2] + jacInv[2][1] * jacInv[0][2];
-    d2xdxi2[5][5] = jacInv[1][1] * jacInv[2][2] + jacInv[2][1] * jacInv[1][2];
-
-    // Matrix to store the second order derivatives of basis functions in
-    // physical domain
-    tk::real d2Bdx2[6][6];
-    for(std::size_t ibasis = 0; ibasis < 6; ibasis++) {
-      for(std::size_t idir = 0; idir < 6; idir++) {
-        d2Bdx2[idir][ibasis] = 0;
-        for(std::size_t k = 0; k < 6; k++)
-          d2Bdx2[idir][ibasis] += d2xdxi2[idir][k] * d2Bdxi2[k][ibasis];
-      }
-    }
-
-    for(ncomp_t icomp = 0; icomp < ncomp; icomp++)
-    {
-      auto mark = icomp * ndof;
-      for(std::size_t idir = 0; idir < 6; idir++)
-      {
-        unk[icomp][idir+4] = 0;
-        for(std::size_t ibasis = 0; ibasis < 6; ibasis++)
-          unk[icomp][idir+4] += U(e, mark+4+ibasis) * d2Bdx2[idir][ibasis];
-      }
-    }
-  }
-  return unk;
-}
-
-void
-tk::TaylorToDubiner( ncomp_t ncomp,
-                     std::size_t e,
-                     std::size_t ndof,
-                     const std::vector< std::size_t >& inpoel,
-                     const tk::UnsMesh::Coords& coord,
-                     const tk::Fields& geoElem,
-                     std::vector< std::vector< tk::real > >& unk )
-// *****************************************************************************
-//  Convert the solution with Taylor basis to the solution with Dubiner basis by
-//    projection method
-//! \param[in] ncomp Number of scalar components in this PDE system
-//! \param[in] e Id of element whose solution is to be limited
-//! \param[in] ndof Maximum number of degrees of freedom
-//! \param[in] inpoel Element connectivity
-//! \param[in] coord Array of nodal coordinates
-//! \param[in, out] unk High-order solution vector with Taylor basis
-// *****************************************************************************
-{
-  Assert( ncomp > 0, "Number of scalar components is incorrect" );
-
-  // The diagonal of mass matrix
-  std::vector< tk::real > L(ndof, 0.0);
-
-  tk::real vol = 1.0 / 6.0;
-
-  L[0] = vol;
-
-  if(ndof > 1) {
-    Assert( (ndof == 4)||(ndof == 10),
-      "Mismatch in number of degrees of freedom" );
-    L[1] = vol / 10.0;
-    L[2] = vol * 3.0/10.0;
-    L[3] = vol * 3.0/5.0;
-  }
+      Assert( U.nunk() == P.nunk(), "Number of unknowns in solution "
+              "vector and primitive vector at recent time step incorrect" );
+      Assert( U.nunk() == R.nunk(), "Number of unknowns in solution "
+              "vector and right-hand side at recent time step incorrect" );
+      Assert( U.nprop() == rdof*m_ncomp, "Number of components in solution "
+              "vector must equal "+ std::to_string(rdof*m_ncomp) );
+      Assert( P.nprop() == rdof*nprim(), "Number of components in primitive "
+              "vector must equal "+ std::to_string(rdof*nprim()) );
+      Assert( fd.Inpofa().size()/3 == fd.Esuf().size()/2,
+              "Mismatch in inpofa size" );
+
+      // set rhs to zero
+      R.fill(0.0);
+
+      // configure a no-op lambda for prescribed velocity
+      auto velfn = []( ncomp_t, tk::real, tk::real, tk::real, tk::real ){
+        return tk::VelFn::result_type(); };
+
+      // compute internal surface flux (including non-conservative) integrals
+      tk::surfIntFV( nmat, m_mat_blk, t, rdof, inpoel,
+                     coord, fd, geoFace, geoElem, m_riemann, velfn, U, P,
+                     srcFlag, R, intsharp );
+
+      // compute boundary surface flux (including non-conservative) integrals
+      for (const auto& b : m_bc)
+        tk::bndSurfIntFV( nmat, m_mat_blk, rdof, b.first,
+                          fd, geoFace, geoElem, inpoel, coord, t, m_riemann,
+                          velfn, b.second, U, P, srcFlag, R, intsharp );
+
+      // compute optional source term
+      tk::srcIntFV( m_mat_blk, t, fd.Esuel().size()/4,
+                    geoElem, Problem::src, R, nmat );
+
+      // compute finite pressure relaxation terms
+      if (g_inputdeck.get< tag::multimat, tag::prelax >())
+      {
+        const auto ct = g_inputdeck.get< tag::multimat,
+                                         tag::prelax_timescale >();
+        tk::pressureRelaxationIntFV( nmat, m_mat_blk, rdof,
+                                     nelem, inpoel, coord, geoElem, U, P, ct,
+                                     R );
+      }
+
+      // compute external (energy) sources
+      m_physics.physSrc(nmat, t, geoElem, elemblkid, R, srcFlag);
+    }
+
+    //! Compute the minimum time step size
+//    //! \param[in] fd Face connectivity and boundary conditions object
+//    //! \param[in] geoFace Face geometry array
+    //! \param[in] geoElem Element geometry array
+    //! \param[in] U Solution vector at recent time step
+    //! \param[in] P Vector of primitive quantities at recent time step
+    //! \param[in] nielem Number of internal elements
+    //! \param[in] srcFlag Whether the energy source was added
+    //! \param[in,out] local_dte Time step size for each element (for local
+    //!   time stepping)
+    //! \return Minimum time step size
+    //! \details The allowable dt is calculated by looking at the maximum
+    //!   wave-speed in elements surrounding each face, times the area of that
+    //!   face. Once the maximum of this quantity over the mesh is determined,
+    //!   the volume of each cell is divided by this quantity. A minimum of this
+    //!   ratio is found over the entire mesh, which gives the allowable dt.
+    tk::real dt( const inciter::FaceData& /*fd*/,
+                 const tk::Fields& /*geoFace*/,
+                 const tk::Fields& geoElem,
+                 const tk::Fields& U,
+                 const tk::Fields& P,
+                 const std::size_t nielem,
+                 const std::vector< int >& srcFlag,
+                 std::vector< tk::real >& local_dte ) const
+    {
+      auto nmat = g_inputdeck.get< tag::multimat, tag::nmat >();<--- Shadow variable
+
+      // obtain dt restrictions from all physics
+      auto dt_e = timeStepSizeMultiMatFV(m_mat_blk, geoElem, nielem, nmat, U,
+        P, local_dte);
+      auto dt_p = m_physics.dtRestriction(geoElem, nielem, srcFlag);
+
+      return std::min(dt_e, dt_p);
+    }
+
+    //! Extract the velocity field at cell nodes. Currently unused.
+    //! \param[in] U Solution vector at recent time step
+    //! \param[in] N Element node indices
+    //! \return Array of the four values of the velocity field
+    std::array< std::array< tk::real, 4 >, 3 >
+    velocity( const tk::Fields& U,
+              const std::array< std::vector< tk::real >, 3 >&,
+              const std::array< std::size_t, 4 >& N ) const
+    {
+      const auto rdof = g_inputdeck.get< tag::rdof >();
+      auto nmat = g_inputdeck.get< tag::multimat, tag::nmat >();<--- Shadow variable
+
+      std::array< std::array< tk::real, 4 >, 3 > v;
+      v[0] = U.extract( momentumDofIdx(nmat, 0, rdof, 0), N );
+      v[1] = U.extract( momentumDofIdx(nmat, 1, rdof, 0), N );
+      v[2] = U.extract( momentumDofIdx(nmat, 2, rdof, 0), N );
+
+      std::vector< std::array< tk::real, 4 > > ar;
+      ar.resize(nmat);
+      for (std::size_t k=0; k<nmat; ++k)
+        ar[k] = U.extract( densityDofIdx(nmat, k, rdof, 0), N );
+
+      std::array< tk::real, 4 > r{{ 0.0, 0.0, 0.0, 0.0 }};
+      for (std::size_t i=0; i<r.size(); ++i) {
+        for (std::size_t k=0; k<nmat; ++k)
+          r[i] += ar[k][i];
+      }
+
+      std::transform( r.begin(), r.end(), v[0].begin(), v[0].begin(),
+                      []( tk::real s, tk::real& d ){ return d /= s; } );
+      std::transform( r.begin(), r.end(), v[1].begin(), v[1].begin(),
+                      []( tk::real s, tk::real& d ){ return d /= s; } );
+      std::transform( r.begin(), r.end(), v[2].begin(), v[2].begin(),
+                      []( tk::real s, tk::real& d ){ return d /= s; } );
+      return v;
+    }
+
+    //! Return a map that associates user-specified strings to functions
+    //! \return Map that associates user-specified strings to functions that
+    //!   compute relevant quantities to be output to file
+    std::map< std::string, tk::GetVarFn > OutVarFn() const
+    { return MultiMatOutVarFn(); }
+
+    //! Return analytic field names to be output to file
+    //! \return Vector of strings labelling analytic fields output in file
+    std::vector< std::string > analyticFieldNames() const {
+      auto nmat = g_inputdeck.get< eq, tag::nmat >();<--- Shadow variable
+
+      return MultiMatFieldNames(nmat);
+    }
+
+    //! Return surface field names to be output to file
+    //! \return Vector of strings labelling surface fields output in file
+    std::vector< std::string > surfNames() const
+    { return MultiMatSurfNames(); }
+
+    //! Return time history field names to be output to file
+    //! \return Vector of strings labelling time history fields output in file
+    std::vector< std::string > histNames() const {
+      return MultiMatHistNames();
+    }
 
-  if(ndof > 4) {
-    Assert( ndof == 10, "Mismatch in number of degrees of freedom" );
-    L[4] = vol / 35.0;
-    L[5] = vol / 21.0;
-    L[6] = vol / 14.0;
-    L[7] = vol / 7.0;
-    L[8] = vol * 3.0/14.0;
-    L[9] = vol * 3.0/7.0;
-  }
-
-  // Coordinates of the centroid in physical domain
-  std::array< tk::real, 3 > x_c{geoElem(e,1), geoElem(e,2), geoElem(e,3)};
-
-  const auto& cx = coord[0];
-  const auto& cy = coord[1];
-  const auto& cz = coord[2];
-
-  std::array< std::array< tk::real, 3>, 4 > coordel {{
-    {{ cx[ inpoel[4*e  ] ], cy[ inpoel[4*e  ] ], cz[ inpoel[4*e  ] ] }},
-    {{ cx[ inpoel[4*e+1] ], cy[ inpoel[4*e+1] ], cz[ inpoel[4*e+1] ] }},
-    {{ cx[ inpoel[4*e+2] ], cy[ inpoel[4*e+2] ], cz[ inpoel[4*e+2] ] }},
-    {{ cx[ inpoel[4*e+3] ], cy[ inpoel[4*e+3] ], cz[ inpoel[4*e+3] ] }}
-  }};
-
-  // Number of quadrature points for volume integration
-  auto ng = tk::NGvol(ndof);
-
-  // arrays for quadrature points
-  std::array< std::vector< tk::real >, 3 > coordgp;
-  std::vector< tk::real > wgp;
-
-  coordgp[0].resize( ng );
-  coordgp[1].resize( ng );
-  coordgp[2].resize( ng );
-  wgp.resize( ng );
-
-  // get quadrature point weights and coordinates for triangle
-  tk::GaussQuadratureTet( ng, coordgp, wgp );
-
-  // right hand side vector
-  std::vector< tk::real > R( ncomp*ndof, 0.0 );
+    //! Return surface field output going to file
+    std::vector< std::vector< tk::real > >
+    surfOutput( const inciter::FaceData& fd,
+      const tk::Fields& U,
+      const tk::Fields& P ) const
+    {
+      const auto rdof = g_inputdeck.get< tag::rdof >();
+      auto nmat = g_inputdeck.get< tag::multimat, tag::nmat >();<--- Shadow variable
+
+      return MultiMatSurfOutput( nmat, rdof, fd, U, P );
+    }
+
+    //! Return time history field output evaluated at time history points
+    //! \param[in] h History point data
+    //! \param[in] inpoel Element-node connectivity
+    //! \param[in] coord Array of nodal coordinates
+    //! \param[in] U Array of unknowns
+    //! \param[in] P Array of primitive quantities
+    //! \return Vector of time history output of bulk flow quantities (density,
+    //!   velocity, total energy, pressure, and volume fraction) evaluated at 
+    //!   time history points
+    std::vector< std::vector< tk::real > >
+    histOutput( const std::vector< HistData >& h,
+                const std::vector< std::size_t >& inpoel,
+                const tk::UnsMesh::Coords& coord,
+                const tk::Fields& U,
+                const tk::Fields& P ) const
+    {
+      const auto rdof = g_inputdeck.get< tag::rdof >();
+      auto nmat = g_inputdeck.get< tag::multimat, tag::nmat >();<--- Shadow variable
+
+      const auto& x = coord[0];
+      const auto& y = coord[1];
+      const auto& z = coord[2];
+
+      std::vector< std::vector< tk::real > > Up(h.size());
+
+      std::size_t j = 0;
+      for (const auto& p : h) {
+        auto e = p.get< tag::elem >();
+        auto chp = p.get< tag::coord >();
 
-  // Gaussian quadrature
-  for (std::size_t igp=0; igp<ng; ++igp)
-  {
-    auto wt = wgp[igp] * vol;
-
-    auto gp = tk::eval_gp( igp, coordel, coordgp );
-
-    auto B_taylor = eval_TaylorBasis( ndof, gp, x_c, coordel);
-
-    // Compute high order solution at gauss point
-    std::vector< tk::real > state( ncomp, 0.0 );
-    for (ncomp_t c=0; c<ncomp; ++c)
-    {
-      state[c] = unk[c][0];
-      state[c] += unk[c][1] * B_taylor[1]
-                + unk[c][2] * B_taylor[2]
-                + unk[c][3] * B_taylor[3];
-
-      if(ndof > 4)
-        state[c] += unk[c][4] * B_taylor[4] + unk[c][5] * B_taylor[5]
-                  + unk[c][6] * B_taylor[6] + unk[c][7] * B_taylor[7]
-                  + unk[c][8] * B_taylor[8] + unk[c][9] * B_taylor[9];
-    }
-
-    auto B = tk::eval_basis( ndof, coordgp[0][igp], coordgp[1][igp], coordgp[2][igp] );
-
-    for (ncomp_t c=0; c<ncomp; ++c)
-    {
-      auto mark = c*ndof;
-      R[mark] += wt * state[c];
-
-      if(ndof > 1)
-      {
-        R[mark+1] += wt * state[c] * B[1];
-        R[mark+2] += wt * state[c] * B[2];
-        R[mark+3] += wt * state[c] * B[3];
-
-        if(ndof > 4)
-        {
-          R[mark+4] += wt * state[c] * B[4];
-          R[mark+5] += wt * state[c] * B[5];
-          R[mark+6] += wt * state[c] * B[6];
-          R[mark+7] += wt * state[c] * B[7];
-          R[mark+8] += wt * state[c] * B[8];
-          R[mark+9] += wt * state[c] * B[9];
-        }
-      }
-    }
-  }
-
-  for (ncomp_t c=0; c<ncomp; ++c)
-  {
-    auto mark = c*ndof;
-    for(std::size_t idof = 0; idof < ndof; idof++)
-      unk[c][idof] = R[mark+idof] / L[idof];
-  }
-}
-
-std::vector< tk::real >
-tk::eval_TaylorBasis( const std::size_t ndof,
-                      const std::array< tk::real, 3 >& x,
-                      const std::array< tk::real, 3 >& x_c,
-                      const std::array< std::array< tk::real, 3>, 4 >& coordel )
-// *****************************************************************************
-//  Evaluate the Taylor basis at points
-//! \param[in] ndof Maximum number of degrees of freedom
-//! \param[in] x Nodal coordinates
-//! \param[in] x_c Coordinates of the centroid
-//! \param[in] coordel Array of nodal coordinates for the tetrahedron
-// *****************************************************************************
-{
-  std::vector< tk::real > avg( 6, 0.0 );
-  if(ndof > 4)
-  {
-    Assert( ndof == 10, "Mismatch in number of degrees of freedom" );
-    auto ng = tk::NGvol(ndof);
-
-    std::array< std::vector< tk::real >, 3 > coordgp;
-    std::vector< tk::real > wgp;
-
-    coordgp[0].resize( ng );
-    coordgp[1].resize( ng );
-    coordgp[2].resize( ng );
-    wgp.resize( ng );
-
-    tk::GaussQuadratureTet( ng, coordgp, wgp );
-
-    for (std::size_t igp=0; igp<ng; ++igp)
+        // Evaluate inverse Jacobian
+        std::array< std::array< tk::real, 3>, 4 > cp{{
+          {{ x[inpoel[4*e  ]], y[inpoel[4*e  ]], z[inpoel[4*e  ]] }},
+          {{ x[inpoel[4*e+1]], y[inpoel[4*e+1]], z[inpoel[4*e+1]] }},
+          {{ x[inpoel[4*e+2]], y[inpoel[4*e+2]], z[inpoel[4*e+2]] }},
+          {{ x[inpoel[4*e+3]], y[inpoel[4*e+3]], z[inpoel[4*e+3]] }} }};
+        auto J = tk::inverseJacobian( cp[0], cp[1], cp[2], cp[3] );
+
+        // evaluate solution at history-point
+        std::array< tk::real, 3 > dc{{chp[0]-cp[0][0], chp[1]-cp[0][1],
+          chp[2]-cp[0][2]}};
+        auto B = tk::eval_basis(rdof, tk::dot(J[0],dc), tk::dot(J[1],dc),
+          tk::dot(J[2],dc));
+        auto uhp = eval_state(m_ncomp, rdof, rdof, e, U, B);
+        auto php = eval_state(nprim(), rdof, rdof, e, P, B);
+
+        // store solution in history output vector
+        Up[j].resize(6+nmat, 0.0);
+        for (std::size_t k=0; k<nmat; ++k) {
+          Up[j][0] += uhp[densityIdx(nmat,k)];
+          Up[j][4] += uhp[energyIdx(nmat,k)];
+          Up[j][5] += php[pressureIdx(nmat,k)];
+          Up[j][6+k] = uhp[volfracIdx(nmat,k)];
+        }
+        Up[j][1] = php[velocityIdx(nmat,0)];
+        Up[j][2] = php[velocityIdx(nmat,1)];
+        Up[j][3] = php[velocityIdx(nmat,2)];
+        ++j;
+      }
+
+      return Up;
+    }
+
+    //! Return names of integral variables to be output to diagnostics file
+    //! \return Vector of strings labelling integral variables output
+    std::vector< std::string > names() const
+    {
+      auto nmat = g_inputdeck.get< tag::multimat, tag::nmat >();<--- Shadow variable
+      return MultiMatDiagNames(nmat);
+    }
+
+    //! Return analytic solution (if defined by Problem) at xi, yi, zi, t
+    //! \param[in] xi X-coordinate at which to evaluate the analytic solution
+    //! \param[in] yi Y-coordinate at which to evaluate the analytic solution
+    //! \param[in] zi Z-coordinate at which to evaluate the analytic solution
+    //! \param[in] t Physical time at which to evaluate the analytic solution
+    //! \return Vector of analytic solution at given location and time
+    std::vector< tk::real >
+    analyticSolution( tk::real xi, tk::real yi, tk::real zi, tk::real t ) const
+    { return Problem::analyticSolution( m_ncomp, m_mat_blk, xi, yi, zi, t ); }
+
+    //! Return analytic solution for conserved variables
+    //! \param[in] xi X-coordinate at which to evaluate the analytic solution
+    //! \param[in] yi Y-coordinate at which to evaluate the analytic solution
+    //! \param[in] zi Z-coordinate at which to evaluate the analytic solution
+    //! \param[in] t Physical time at which to evaluate the analytic solution
+    //! \return Vector of analytic solution at given location and time
+    std::vector< tk::real >
+    solution( tk::real xi, tk::real yi, tk::real zi, tk::real t ) const
+    { return Problem::initialize( m_ncomp, m_mat_blk, xi, yi, zi, t ); }
+
+    //! Return cell-averaged specific total energy for an element
+    //! \param[in] e Element id for which total energy is required
+    //! \param[in] unk Vector of conserved quantities
+    //! \return Cell-averaged specific total energy for given element
+    tk::real sp_totalenergy(std::size_t e, const tk::Fields& unk) const
+    {
+      const auto rdof = g_inputdeck.get< tag::rdof >();
+      auto nmat = g_inputdeck.get< tag::multimat, tag::nmat >();<--- Shadow variable
+
+      tk::real sp_te(0.0);
+      // sum each material total energy
+      for (std::size_t k=0; k<nmat; ++k) {
+        sp_te += unk(e, energyDofIdx(nmat,k,rdof,0));
+      }
+      return sp_te;
+    }
+
+    //! Compute relevant sound speed for output
+    //! \param[in] nielem Number of internal elements
+    //! \param[in] U Solution vector at recent time step
+    //! \param[in] P Primitive vector at recent time step
+    //! \param[in,out] ss Sound speed vector
+    void soundspeed(
+      std::size_t nielem,
+      const tk::Fields& U,
+      const tk::Fields& P,
+      std::vector< tk::real >& ss) const
     {
-      // Compute the coordinates of quadrature point at physical domain
-      auto gp = tk::eval_gp( igp, coordel, coordgp );
-
-      avg[0] += wgp[igp] * (gp[0] - x_c[0]) * (gp[0] - x_c[0]) * 0.5;
-      avg[1] += wgp[igp] * (gp[1] - x_c[1]) * (gp[1] - x_c[1]) * 0.5;
-      avg[2] += wgp[igp] * (gp[2] - x_c[2]) * (gp[2] - x_c[2]) * 0.5;
-      avg[3] += wgp[igp] * (gp[0] - x_c[0]) * (gp[1] - x_c[1]);
-      avg[4] += wgp[igp] * (gp[0] - x_c[0]) * (gp[2] - x_c[2]);
-      avg[5] += wgp[igp] * (gp[1] - x_c[1]) * (gp[2] - x_c[2]);
-    }
-  }
-
-  std::vector< tk::real > B( ndof, 1.0 );
-
-  if(ndof > 1) {
-    Assert( (ndof == 4)||(ndof == 10) ,
-      "Mismatch in number of degrees of freedom" );
-    B[1] = x[0] - x_c[0];
-    B[2] = x[1] - x_c[1];
-    B[3] = x[2] - x_c[2];
-  }
+      Assert( ss.size() == nielem, "Size of sound speed vector incorrect " );
+
+      const auto ndof = g_inputdeck.get< tag::ndof >();
+      const auto rdof = g_inputdeck.get< tag::rdof >();
+      const auto use_mass_avg =
+        g_inputdeck.get< tag::multimat, tag::dt_sos_massavg >();
+      auto nmat = g_inputdeck.get< tag::multimat, tag::nmat >();<--- Shadow variable
+      std::size_t ncomp = U.nprop()/rdof;
+      std::size_t nprim = P.nprop()/rdof;<--- Shadow variable
+
+      std::vector< tk::real > ugp(ncomp, 0.0), pgp(nprim, 0.0);<--- Variable 'ugp' is assigned a value that is never used.<--- Variable 'pgp' is assigned a value that is never used.
+
+      for (std::size_t e=0; e<nielem; ++e) {
+        // basis function at centroid
+        std::vector< tk::real > B(rdof, 0.0);
+        B[0] = 1.0;
+
+        // get conserved quantities
+        ugp = eval_state(ncomp, rdof, ndof, e, U, B);
+        // get primitive quantities
+        pgp = eval_state(nprim, rdof, ndof, e, P, B);
 
-  if(ndof > 4) {
-    B[4] = B[1] * B[1] * 0.5 - avg[0];
-    B[5] = B[2] * B[2] * 0.5 - avg[1];
-    B[6] = B[3] * B[3] * 0.5 - avg[2];
-    B[7] = B[1] * B[2] - avg[3];
-    B[8] = B[1] * B[3] - avg[4];
-    B[9] = B[2] * B[3] - avg[5];
-  }
-
-  return B;
-}
-
-// -----------------------------------------------------------------------------
-// Functions for reference element Taylor basis and related Xforms
-// -----------------------------------------------------------------------------
-
-std::vector< std::vector< tk::real > >
-tk::DubinerToTaylorRefEl( ncomp_t ncomp,
-  const std::size_t e,
-  const std::size_t ndof,
-  const std::size_t ndof_el,
-  const std::vector< std::vector< tk::real > >& mtInv,
-  const tk::Fields& U )
-// *****************************************************************************
-//  Transform the solution from Dubiner basis to Taylor basis
-//! \param[in] ncomp Number of scalar components in this PDE system
-//! \param[in] e Id of element whose solution is to be limited
-//! \param[in] ndof Maximum number of degrees of freedom
-//! \param[in] ndof_el Local number of degrees of freedom for the element
-//! \param[in] mtInv Inverse of Taylor mass matrix
-//! \param[in] U High-order solution vector with Dubiner basis
-//! \return High-order solution vector with Taylor basis (ref element)
-// *****************************************************************************
-{
-  auto vol = 1.0/6.0;
-
-  // 1. Get rhs for L2-projection
-  // Quadrature setup
-  auto ng = tk::NGvol(ndof_el);
-  std::array< std::vector< real >, 3 > coordgp;
-  std::vector< real > wgp;
-  coordgp[0].resize( ng );
-  coordgp[1].resize( ng );
-  coordgp[2].resize( ng );
-  wgp.resize( ng );
-  GaussQuadratureTet( ng, coordgp, wgp );
-
-  // Gaussian quadrature
-  std::vector< std::vector< tk::real > >
-    R(ncomp, std::vector<tk::real>(ndof_el, 0.0));
-  for (std::size_t igp=0; igp<ng; ++igp)
-  {
-    // Dubiner basis functions
-    auto B = eval_basis( ndof_el, coordgp[0][igp], coordgp[1][igp],
-                         coordgp[2][igp] );
-    // Taylor basis functions
-    auto Bt = eval_TaylorBasisRefEl(ndof_el, coordgp[0][igp], coordgp[1][igp],
-      coordgp[2][igp]);
-
-    auto state = tk::eval_state(ncomp, ndof, ndof_el, e, U, B);
-
-    for (std::size_t c=0; c<ncomp; ++c) {
-      for (std::size_t id=0; id<ndof_el; ++id) {
-        R[c][id] += wgp[igp] * vol * state[c] * Bt[id];
-      }
-    }
-  }
-
-
-  // 2. Get Taylor solution by premultiplying by mass matrix inverse
-  std::vector< std::vector< tk::real > >
-    unk(ncomp, std::vector<tk::real>(ndof_el, 0.0));
-  for (std::size_t c=0; c<ncomp; ++c) {
-    for (std::size_t id=0; id<ndof_el; ++id) {
-      for (std::size_t jd=0; jd<ndof_el; ++jd) {
-        unk[c][id] += mtInv[id][jd] * R[c][jd];
-      }
-    }
-  }
-
-  return unk;
-}
-
-void
-tk::TaylorToDubinerRefEl( ncomp_t ncomp,
-  const std::size_t ndof,
-  std::vector< std::vector< tk::real > >& unk )
-// *****************************************************************************
-//  Transform the solution from Taylor to Dubiner basis
-//! \param[in] ncomp Number of scalar components in this PDE system
-//! \param[in] ndof Number of degrees of freedom
-//! \param[in,out] unk High-order solution vector with Taylor basis that gets
-//!   transformed to solution with Dubiner basis
-// *****************************************************************************
-{
-  auto vol = 1.0/6.0;
-
-  auto M = massMatrixDubiner(ndof, vol);
-
-  // 1. Get rhs for L2-projection
-  // Quadrature setup
-  auto ng = tk::NGvol(ndof);
-  std::array< std::vector< real >, 3 > coordgp;
-  std::vector< real > wgp;
-  coordgp[0].resize( ng );
-  coordgp[1].resize( ng );
-  coordgp[2].resize( ng );
-  wgp.resize( ng );
-  GaussQuadratureTet( ng, coordgp, wgp );
-
-  // Gaussian quadrature
-  std::vector< std::vector< tk::real > >
-    R(ncomp, std::vector<tk::real>(ndof, 0.0));
-  for (std::size_t igp=0; igp<ng; ++igp)
-  {
-    // Dubiner basis functions
-    auto B = eval_basis( ndof, coordgp[0][igp], coordgp[1][igp],
-                         coordgp[2][igp] );
-    // Taylor basis functions
-    auto Bt = eval_TaylorBasisRefEl(ndof, coordgp[0][igp], coordgp[1][igp],
-      coordgp[2][igp]);
-
-    for (std::size_t c=0; c<ncomp; ++c) {
-      real state(0.0);
-      for (std::size_t id=0; id<ndof; ++id) {
-        state += unk[c][id] * Bt[id];
-      }
-      for (std::size_t id=0; id<ndof; ++id) {
-        R[c][id] += wgp[igp] * vol * state * B[id];
-      }
-    }
-  }
-
-  // 2. Get Dubiner solution by premultiplying by mass matrix inverse
-  for (std::size_t c=0; c<ncomp; ++c) {
-    for (std::size_t id=0; id<ndof; ++id) {
-      unk[c][id] = R[c][id] / M[id];
-    }
-  }
-}
-
-std::vector< tk::real >
-tk::eval_TaylorBasisRefEl( std::size_t ndof, tk::real x, tk::real y,
-  tk::real z )
-// *****************************************************************************
-//  Evaluate the Taylor basis at a point in the reference element
-//! \param[in] ndof Number of degrees of freedom
-//! \param[in] x Xi coordinate of point in reference element
-//! \param[in] y Eta coordinate of point in reference element
-//! \param[in] z Zeta coordinate of point in reference element
-// *****************************************************************************
-{
-  // Get averages required for P2 basis functions
-  std::vector< tk::real > avg( 6, 0.0 );
-  if(ndof > 4)
-  {
-    auto ng = tk::NGvol(ndof);
-    std::array< std::vector< tk::real >, 3 > coordgp;
-    std::vector< tk::real > wgp;
-    coordgp[0].resize( ng );
-    coordgp[1].resize( ng );
-    coordgp[2].resize( ng );
-    wgp.resize( ng );
-    tk::GaussQuadratureTet( ng, coordgp, wgp );
-
-    for (std::size_t igp=0; igp<ng; ++igp)
-    {
-      avg[0] += wgp[igp] * (coordgp[0][igp] - 0.25) * (coordgp[0][igp] - 0.25) * 0.5;
-      avg[1] += wgp[igp] * (coordgp[1][igp] - 0.25) * (coordgp[1][igp] - 0.25) * 0.5;
-      avg[2] += wgp[igp] * (coordgp[2][igp] - 0.25) * (coordgp[2][igp] - 0.25) * 0.5;
-      avg[3] += wgp[igp] * (coordgp[0][igp] - 0.25) * (coordgp[1][igp] - 0.25);
-      avg[4] += wgp[igp] * (coordgp[0][igp] - 0.25) * (coordgp[2][igp] - 0.25);
-      avg[5] += wgp[igp] * (coordgp[1][igp] - 0.25) * (coordgp[2][igp] - 0.25);
-    }
-  }
-
-  // Get Taylor basis functions
-  std::vector< tk::real > B( ndof, 1.0 );
-  if(ndof > 1) {
-    B[1] = x - 0.25;
-    B[2] = y - 0.25;
-    B[3] = z - 0.25;
-    if(ndof > 4) {
-      B[4] = B[1] * B[1] * 0.5 - avg[0];
-      B[5] = B[2] * B[2] * 0.5 - avg[1];
-      B[6] = B[3] * B[3] * 0.5 - avg[2];
-      B[7] = B[1] * B[2] - avg[3];
-      B[8] = B[1] * B[3] - avg[4];
-      B[9] = B[2] * B[3] - avg[5];
-    }
-  }
-
-  return B;
-}
-
-std::vector< std::vector< tk::real > >
-tk::invMassMatTaylorRefEl( std::size_t dof )
-// *****************************************************************************
-//  Obtain inverse mass matrix for Taylor basis in reference element
-//! \param[in] dof Number of degrees of freedom
-//! \return Inverse mass matrix
-// *****************************************************************************
-{
-  // Get Taylor mass matrix
-  auto Mt = massMatrixTaylorRefEl(dof);
-
-  // Only invert if DGP2
-  if (dof > 4) {
-    double mtInv[10*10];
-    for (std::size_t i=0; i<Mt.size(); ++i) {
-      for (std::size_t j=0; j<Mt[i].size(); ++j) {
-        std::size_t idx = 10*i+j;
-        mtInv[idx] = Mt[i][j];
-      }
-    }
-    lapack_int ipiv[10];
-    // LU-factorization for inversion
-    lapack_int info1 = LAPACKE_dgetrf(LAPACK_ROW_MAJOR, 10, 10, mtInv, 10, ipiv);
-    if (info1 != 0) Throw("Taylor mass matrix is singular");
-    // Inversion
-    lapack_int info2 = LAPACKE_dgetri(LAPACK_ROW_MAJOR, 10, mtInv, 10, ipiv);
-    if (info2 != 0) Throw("Error while inverting Taylor mass matrix");
-
-    // Get 2D vector from 1D array mass matrix inverse
-    for (std::size_t i=0; i<Mt.size(); ++i) {
-      for (std::size_t j=0; j<Mt[i].size(); ++j) {
-        std::size_t idx = 10*i+j;
-        Mt[i][j] = mtInv[idx];
-      }
-    }
-  }
-
-  return Mt;
-}
-
-std::vector< std::vector< tk::real > >
-tk::massMatrixTaylorRefEl(std::size_t dof)
-// *****************************************************************************
-//  Obtain mass matrix for Taylor basis in reference element
-//! \param[in] dof Number of degrees of freedom
-//! \return Mass matrix
-// *****************************************************************************
-{
-  std::vector< std::vector< tk::real > >
-    Mt(dof, std::vector<tk::real>(dof,0.0));
-
-  // Mt(1,1)
-  tk::real vol = 1.0/6.0;
-  Mt[0][0] = vol;
-
-  // Mt(i,j) for i,j > 1
-  if (dof > 1) {
-    // Quadrature information
-    auto ng = tk::NGvol(dof);
-    std::array< std::vector< tk::real >, 3 > coordgp;
-    std::vector< tk::real > wgp;
-    coordgp[0].resize( ng );
-    coordgp[1].resize( ng );
-    coordgp[2].resize( ng );
-    wgp.resize( ng );
-    tk::GaussQuadratureTet( ng, coordgp, wgp );
-
-    for (std::size_t igp=0; igp<ng; ++igp)
-    {
-      auto Bt = eval_TaylorBasisRefEl(dof, coordgp[0][igp], coordgp[1][igp],
-        coordgp[2][igp]);
-      for (std::size_t id=1; id<dof; ++id) {
-        for (std::size_t jd=1; jd<dof; ++jd) {
-          Mt[id][jd] += vol*wgp[igp]*Bt[id]*Bt[jd];
-        }
-      }
-    }
-  }
-
-  return Mt;
-}
+        // acoustic speed (this should be consistent with time-step calculation)
+        ss[e] = 0.0;
+        tk::real mixtureDensity = 0.0;
+        for (std::size_t k=0; k<nmat; ++k)
+        {
+          if (use_mass_avg > 0)
+          {
+            // mass averaging SoS
+            ss[e] += ugp[densityIdx(nmat,k)]*
+              m_mat_blk[k].compute< EOS::soundspeed >(
+              ugp[densityIdx(nmat, k)], pgp[pressureIdx(nmat, k)],
+              ugp[volfracIdx(nmat, k)], k );
+
+            mixtureDensity += ugp[densityIdx(nmat,k)];
+          }
+          else
+          {
+            if (ugp[volfracIdx(nmat, k)] > 1.0e-04)
+            {
+              ss[e] = std::max( ss[e], m_mat_blk[k].compute< EOS::soundspeed >(
+                ugp[densityIdx(nmat, k)], pgp[pressureIdx(nmat, k)],
+                ugp[volfracIdx(nmat, k)], k ) );
+            }
+          }
+        }
+        if (use_mass_avg > 0) ss[e] /= mixtureDensity;
+      }
+    }
+
+  private:
+    //! Physics policy
+    const Physics m_physics;
+    //! Number of components in this PDE system
+    const ncomp_t m_ncomp;
+    //! Riemann solver
+    tk::RiemannFluxFn m_riemann;
+    //! BC configuration
+    BCStateFn m_bc;
+    //! EOS material block
+    std::vector< EOS > m_mat_blk;
+
+    //! Evaluate conservative part of physical flux function for this PDE system
+    //! \param[in] ncomp Number of scalar components in this PDE system
+    //! \param[in] ugp Numerical solution at the Gauss point at which to
+    //!   evaluate the flux
+    //! \return Flux vectors for all components in this PDE system
+    //! \note The function signature must follow tk::FluxFn
+    static tk::FluxFn::result_type
+    flux( ncomp_t ncomp,
+          const std::vector< EOS >& mat_blk,
+          const std::vector< tk::real >& ugp,
+          const std::vector< std::array< tk::real, 3 > >& )
+    {
+      auto nmat = g_inputdeck.get< tag::multimat, tag::nmat >();<--- Shadow variable
+
+      return tk::fluxTerms(ncomp, nmat, mat_blk, ugp);
+    }
+
+    //! \brief Boundary state function providing the left and right state of a
+    //!   face at Dirichlet boundaries
+    //! \param[in] ncomp Number of scalar components in this PDE system
+    //! \param[in] ul Left (domain-internal) state
+    //! \param[in] x X-coordinate at which to compute the states
+    //! \param[in] y Y-coordinate at which to compute the states
+    //! \param[in] z Z-coordinate at which to compute the states
+    //! \param[in] t Physical time
+    //! \return Left and right states for all scalar components in this PDE
+    //!   system
+    //! \note The function signature must follow tk::StateFn. For multimat, the
+    //!   left or right state is the vector of conserved quantities, followed by
+    //!   the vector of primitive quantities appended to it.
+    static tk::StateFn::result_type
+    dirichlet( ncomp_t ncomp,
+               const std::vector< EOS >& mat_blk,
+               const std::vector< tk::real >& ul, tk::real x, tk::real y,
+               tk::real z, tk::real t, const std::array< tk::real, 3 >& )
+    {
+      auto nmat = g_inputdeck.get< tag::multimat, tag::nmat >();<--- Shadow variable<--- Variable 'nmat' is assigned a value that is never used.
+
+      auto ur = Problem::initialize( ncomp, mat_blk, x, y, z, t );
+      Assert( ur.size() == ncomp, "Incorrect size for boundary state vector" );
+
+      ur.resize(ul.size());
+
+      tk::real rho(0.0);
+      for (std::size_t k=0; k<nmat; ++k)
+        rho += ur[densityIdx(nmat, k)];
+
+      // get primitives in boundary state
+
+      // velocity
+      ur[ncomp+velocityIdx(nmat, 0)] = ur[momentumIdx(nmat, 0)] / rho;
+      ur[ncomp+velocityIdx(nmat, 1)] = ur[momentumIdx(nmat, 1)] / rho;
+      ur[ncomp+velocityIdx(nmat, 2)] = ur[momentumIdx(nmat, 2)] / rho;
+
+      // material pressures
+      for (std::size_t k=0; k<nmat; ++k)
+      {
+        auto gk = getDeformGrad(nmat, k, ur);
+        ur[ncomp+pressureIdx(nmat, k)] = mat_blk[k].compute< EOS::pressure >(
+          ur[densityIdx(nmat, k)], ur[ncomp+velocityIdx(nmat, 0)],
+          ur[ncomp+velocityIdx(nmat, 1)], ur[ncomp+velocityIdx(nmat, 2)],
+          ur[energyIdx(nmat, k)], ur[volfracIdx(nmat, k)], k, gk );
+      }
+
+      Assert( ur.size() == ncomp+nmat+3, "Incorrect size for appended "
+              "boundary state vector" );
+
+      return {{ std::move(ul), std::move(ur) }};
+    }
+
+    // Other boundary condition types that do not depend on "Problem" should be
+    // added in BCFunctions.hpp
+};
+
+} // fv::
+
+} // inciter::
+
+#endif // FVMultiMat_h
 
diff --git a/Release/cppcheck/59.html b/Release/cppcheck/59.html index 1d5dcf9c7939..37bd5f0606ae 100644 --- a/Release/cppcheck/59.html +++ b/Release/cppcheck/59.html @@ -152,3193 +152,341 @@
- - - - - - - - - - - + + + + + + + + + + - + - - - + + + - + - - - + + + diff --git a/Release/test_coverage/Base/index.html b/Release/test_coverage/Base/index.html index 7163643c8d63..32edbd2615f8 100644 --- a/Release/test_coverage/Base/index.html +++ b/Release/test_coverage/Base/index.html @@ -27,13 +27,13 @@ - + - + - + @@ -49,9 +49,9 @@ - - - + + +
   1
-   2
-   3
-   4
-   5
-   6
-   7
-   8
-   9
-  10
-  11
-  12
-  13
-  14
-  15
-  16
-  17
-  18
-  19
-  20
-  21
-  22
-  23
-  24
-  25
-  26
-  27
-  28
-  29
-  30
-  31
-  32
-  33
-  34
-  35
-  36
-  37
-  38
-  39
-  40
-  41
-  42
-  43
-  44
-  45
-  46
-  47
-  48
-  49
-  50
-  51
-  52
-  53
-  54
-  55
-  56
-  57
-  58
-  59
-  60
-  61
-  62
-  63
-  64
-  65
-  66
-  67
-  68
-  69
-  70
-  71
-  72
-  73
-  74
-  75
-  76
-  77
-  78
-  79
-  80
-  81
-  82
-  83
-  84
-  85
-  86
-  87
-  88
-  89
-  90
-  91
-  92
-  93
-  94
-  95
-  96
-  97
-  98
-  99
- 100
- 101
- 102
- 103
- 104
- 105
- 106
- 107
- 108
- 109
- 110
- 111
- 112
- 113
- 114
- 115
- 116
- 117
- 118
- 119
- 120
- 121
- 122
- 123
- 124
- 125
- 126
- 127
- 128
- 129
- 130
- 131
- 132
- 133
- 134
- 135
- 136
- 137
- 138
- 139
- 140
- 141
- 142
- 143
- 144
- 145
- 146
- 147
- 148
- 149
- 150
- 151
- 152
- 153
- 154
- 155
- 156
- 157
- 158
- 159
- 160
- 161
- 162
- 163
- 164
- 165
- 166
- 167
- 168
- 169
- 170
- 171
- 172
- 173
- 174
- 175
- 176
- 177
- 178
- 179
- 180
- 181
- 182
- 183
- 184
- 185
- 186
- 187
- 188
- 189
- 190
- 191
- 192
- 193
- 194
- 195
- 196
- 197
- 198
- 199
- 200
- 201
- 202
- 203
- 204
- 205
- 206
- 207
- 208
- 209
- 210
- 211
- 212
- 213
- 214
- 215
- 216
- 217
- 218
- 219
- 220
- 221
- 222
- 223
- 224
- 225
- 226
- 227
- 228
- 229
- 230
- 231
- 232
- 233
- 234
- 235
- 236
- 237
- 238
- 239
- 240
- 241
- 242
- 243
- 244
- 245
- 246
- 247
- 248
- 249
- 250
- 251
- 252
- 253
- 254
- 255
- 256
- 257
- 258
- 259
- 260
- 261
- 262
- 263
- 264
- 265
- 266
- 267
- 268
- 269
- 270
- 271
- 272
- 273
- 274
- 275
- 276
- 277
- 278
- 279
- 280
- 281
- 282
- 283
- 284
- 285
- 286
- 287
- 288
- 289
- 290
- 291
- 292
- 293
- 294
- 295
- 296
- 297
- 298
- 299
- 300
- 301
- 302
- 303
- 304
- 305
- 306
- 307
- 308
- 309
- 310
- 311
- 312
- 313
- 314
- 315
- 316
- 317
- 318
- 319
- 320
- 321
- 322
- 323
- 324
- 325
- 326
- 327
- 328
- 329
- 330
- 331
- 332
- 333
- 334
- 335
- 336
- 337
- 338
- 339
- 340
- 341
- 342
- 343
- 344
- 345
- 346
- 347
- 348
- 349
- 350
- 351
- 352
- 353
- 354
- 355
- 356
- 357
- 358
- 359
- 360
- 361
- 362
- 363
- 364
- 365
- 366
- 367
- 368
- 369
- 370
- 371
- 372
- 373
- 374
- 375
- 376
- 377
- 378
- 379
- 380
- 381
- 382
- 383
- 384
- 385
- 386
- 387
- 388
- 389
- 390
- 391
- 392
- 393
- 394
- 395
- 396
- 397
- 398
- 399
- 400
- 401
- 402
- 403
- 404
- 405
- 406
- 407
- 408
- 409
- 410
- 411
- 412
- 413
- 414
- 415
- 416
- 417
- 418
- 419
- 420
- 421
- 422
- 423
- 424
- 425
- 426
- 427
- 428
- 429
- 430
- 431
- 432
- 433
- 434
- 435
- 436
- 437
- 438
- 439
- 440
- 441
- 442
- 443
- 444
- 445
- 446
- 447
- 448
- 449
- 450
- 451
- 452
- 453
- 454
- 455
- 456
- 457
- 458
- 459
- 460
- 461
- 462
- 463
- 464
- 465
- 466
- 467
- 468
- 469
- 470
- 471
- 472
- 473
- 474
- 475
- 476
- 477
- 478
- 479
- 480
- 481
- 482
- 483
- 484
- 485
- 486
- 487
- 488
- 489
- 490
- 491
- 492
- 493
- 494
- 495
- 496
- 497
- 498
- 499
- 500
- 501
- 502
- 503
- 504
- 505
- 506
- 507
- 508
- 509
- 510
- 511
- 512
- 513
- 514
- 515
- 516
- 517
- 518
- 519
- 520
- 521
- 522
- 523
- 524
- 525
- 526
- 527
- 528
- 529
- 530
- 531
- 532
- 533
- 534
- 535
- 536
- 537
- 538
- 539
- 540
- 541
- 542
- 543
- 544
- 545
- 546
- 547
- 548
- 549
- 550
- 551
- 552
- 553
- 554
- 555
- 556
- 557
- 558
- 559
- 560
- 561
- 562
- 563
- 564
- 565
- 566
- 567
- 568
- 569
- 570
- 571
- 572
- 573
- 574
- 575
- 576
- 577
- 578
- 579
- 580
- 581
- 582
- 583
- 584
- 585
- 586
- 587
- 588
- 589
- 590
- 591
- 592
- 593
- 594
- 595
- 596
- 597
- 598
- 599
- 600
- 601
- 602
- 603
- 604
- 605
- 606
- 607
- 608
- 609
- 610
- 611
- 612
- 613
- 614
- 615
- 616
- 617
- 618
- 619
- 620
- 621
- 622
- 623
- 624
- 625
- 626
- 627
- 628
- 629
- 630
- 631
- 632
- 633
- 634
- 635
- 636
- 637
- 638
- 639
- 640
- 641
- 642
- 643
- 644
- 645
- 646
- 647
- 648
- 649
- 650
- 651
- 652
- 653
- 654
- 655
- 656
- 657
- 658
- 659
- 660
- 661
- 662
- 663
- 664
- 665
- 666
- 667
- 668
- 669
- 670
- 671
- 672
- 673
- 674
- 675
- 676
- 677
- 678
- 679
- 680
- 681
- 682
- 683
- 684
- 685
- 686
- 687
- 688
- 689
- 690
- 691
- 692
- 693
- 694
- 695
- 696
- 697
- 698
- 699
- 700
- 701
- 702
- 703
- 704
- 705
- 706
- 707
- 708
- 709
- 710
- 711
- 712
- 713
- 714
- 715
- 716
- 717
- 718
- 719
- 720
- 721
- 722
- 723
- 724
- 725
- 726
- 727
- 728
- 729
- 730
- 731
- 732
- 733
- 734
- 735
- 736
- 737
- 738
- 739
- 740
- 741
- 742
- 743
- 744
- 745
- 746
- 747
- 748
- 749
- 750
- 751
- 752
- 753
- 754
- 755
- 756
- 757
- 758
- 759
- 760
- 761
- 762
- 763
- 764
- 765
- 766
- 767
- 768
- 769
- 770
- 771
- 772
- 773
- 774
- 775
- 776
- 777
- 778
- 779
- 780
- 781
- 782
- 783
- 784
- 785
- 786
- 787
- 788
- 789
- 790
- 791
- 792
- 793
- 794
- 795
- 796
- 797
- 798
- 799
- 800
- 801
- 802
- 803
- 804
- 805
- 806
- 807
- 808
- 809
- 810
- 811
- 812
- 813
- 814
- 815
- 816
- 817
- 818
- 819
- 820
- 821
- 822
- 823
- 824
- 825
- 826
- 827
- 828
- 829
- 830
- 831
- 832
- 833
- 834
- 835
- 836
- 837
- 838
- 839
- 840
- 841
- 842
- 843
- 844
- 845
- 846
- 847
- 848
- 849
- 850
- 851
- 852
- 853
- 854
- 855
- 856
- 857
- 858
- 859
- 860
- 861
- 862
- 863
- 864
- 865
- 866
- 867
- 868
- 869
- 870
- 871
- 872
- 873
- 874
- 875
- 876
- 877
- 878
- 879
- 880
- 881
- 882
- 883
- 884
- 885
- 886
- 887
- 888
- 889
- 890
- 891
- 892
- 893
- 894
- 895
- 896
- 897
- 898
- 899
- 900
- 901
- 902
- 903
- 904
- 905
- 906
- 907
- 908
- 909
- 910
- 911
- 912
- 913
- 914
- 915
- 916
- 917
- 918
- 919
- 920
- 921
- 922
- 923
- 924
- 925
- 926
- 927
- 928
- 929
- 930
- 931
- 932
- 933
- 934
- 935
- 936
- 937
- 938
- 939
- 940
- 941
- 942
- 943
- 944
- 945
- 946
- 947
- 948
- 949
- 950
- 951
- 952
- 953
- 954
- 955
- 956
- 957
- 958
- 959
- 960
- 961
- 962
- 963
- 964
- 965
- 966
- 967
- 968
- 969
- 970
- 971
- 972
- 973
- 974
- 975
- 976
- 977
- 978
- 979
- 980
- 981
- 982
- 983
- 984
- 985
- 986
- 987
- 988
- 989
- 990
- 991
- 992
- 993
- 994
- 995
- 996
- 997
- 998
- 999
-1000
-1001
-1002
-1003
-1004
-1005
-1006
-1007
-1008
-1009
-1010
-1011
-1012
-1013
-1014
-1015
-1016
-1017
-1018
-1019
-1020
-1021
-1022
-1023
-1024
-1025
-1026
-1027
-1028
-1029
-1030
-1031
-1032
-1033
-1034
-1035
-1036
-1037
-1038
-1039
-1040
-1041
-1042
-1043
-1044
-1045
-1046
-1047
-1048
-1049
-1050
-1051
-1052
-1053
-1054
-1055
-1056
-1057
-1058
-1059
-1060
-1061
-1062
-1063
-1064
-1065
-1066
-1067
-1068
-1069
-1070
-1071
-1072
-1073
-1074
-1075
-1076
-1077
-1078
-1079
-1080
-1081
-1082
-1083
-1084
-1085
-1086
-1087
-1088
-1089
-1090
-1091
-1092
-1093
-1094
-1095
-1096
-1097
-1098
-1099
-1100
-1101
-1102
-1103
-1104
-1105
-1106
-1107
-1108
-1109
-1110
-1111
-1112
-1113
-1114
-1115
-1116
-1117
-1118
-1119
-1120
-1121
-1122
-1123
-1124
-1125
-1126
-1127
-1128
-1129
-1130
-1131
-1132
-1133
-1134
-1135
-1136
-1137
-1138
-1139
-1140
-1141
-1142
-1143
-1144
-1145
-1146
-1147
-1148
-1149
-1150
-1151
-1152
-1153
-1154
-1155
-1156
-1157
-1158
-1159
-1160
-1161
-1162
-1163
-1164
-1165
-1166
-1167
-1168
-1169
-1170
-1171
-1172
-1173
-1174
-1175
-1176
-1177
-1178
-1179
-1180
-1181
-1182
-1183
-1184
-1185
-1186
-1187
-1188
-1189
-1190
-1191
-1192
-1193
-1194
-1195
-1196
-1197
-1198
-1199
-1200
-1201
-1202
-1203
-1204
-1205
-1206
-1207
-1208
-1209
-1210
-1211
-1212
-1213
-1214
-1215
-1216
-1217
-1218
-1219
-1220
-1221
-1222
-1223
-1224
-1225
-1226
-1227
-1228
-1229
-1230
-1231
-1232
-1233
-1234
-1235
-1236
-1237
-1238
-1239
-1240
-1241
-1242
-1243
-1244
-1245
-1246
-1247
-1248
-1249
-1250
-1251
-1252
-1253
-1254
-1255
-1256
-1257
-1258
-1259
-1260
-1261
-1262
-1263
-1264
-1265
-1266
-1267
-1268
-1269
-1270
-1271
-1272
-1273
-1274
-1275
-1276
-1277
-1278
-1279
-1280
-1281
-1282
-1283
-1284
-1285
-1286
-1287
-1288
-1289
-1290
-1291
-1292
-1293
-1294
-1295
-1296
-1297
-1298
-1299
-1300
-1301
-1302
-1303
-1304
-1305
-1306
-1307
-1308
-1309
-1310
-1311
-1312
-1313
-1314
-1315
-1316
-1317
-1318
-1319
-1320
-1321
-1322
-1323
-1324
-1325
-1326
-1327
-1328
-1329
-1330
-1331
-1332
-1333
-1334
-1335
-1336
-1337
-1338
-1339
-1340
-1341
-1342
-1343
-1344
-1345
-1346
-1347
-1348
-1349
-1350
-1351
-1352
-1353
-1354
-1355
-1356
-1357
-1358
-1359
-1360
-1361
-1362
-1363
-1364
-1365
-1366
-1367
-1368
-1369
-1370
-1371
-1372
-1373
-1374
-1375
-1376
-1377
-1378
-1379
-1380
-1381
-1382
-1383
-1384
-1385
-1386
-1387
-1388
-1389
-1390
-1391
-1392
-1393
-1394
-1395
-1396
-1397
-1398
-1399
-1400
-1401
-1402
-1403
-1404
-1405
-1406
-1407
-1408
-1409
-1410
-1411
-1412
-1413
-1414
-1415
-1416
-1417
-1418
-1419
-1420
-1421
-1422
-1423
-1424
-1425
-1426
-1427
-1428
-1429
-1430
-1431
-1432
-1433
-1434
-1435
-1436
-1437
-1438
-1439
-1440
-1441
-1442
-1443
-1444
-1445
-1446
-1447
-1448
-1449
-1450
-1451
-1452
-1453
-1454
-1455
-1456
-1457
-1458
-1459
-1460
-1461
-1462
-1463
-1464
-1465
-1466
-1467
-1468
-1469
-1470
-1471
-1472
-1473
-1474
-1475
-1476
-1477
-1478
-1479
-1480
-1481
-1482
-1483
-1484
-1485
-1486
-1487
-1488
-1489
-1490
-1491
-1492
-1493
-1494
-1495
-1496
-1497
-1498
-1499
-1500
-1501
-1502
-1503
-1504
-1505
-1506
-1507
-1508
-1509
-1510
-1511
-1512
-1513
-1514
-1515
-1516
-1517
-1518
-1519
-1520
-1521
-1522
-1523
-1524
-1525
-1526
-1527
-1528
-1529
-1530
-1531
-1532
-1533
-1534
-1535
-1536
-1537
-1538
-1539
-1540
-1541
-1542
-1543
-1544
-1545
-1546
-1547
-1548
-1549
-1550
-1551
-1552
-1553
-1554
-1555
-1556
-1557
-1558
-1559
-1560
-1561
-1562
-1563
-1564
-1565
-1566
-1567
-1568
-1569
-1570
-1571
-1572
-1573
-1574
-1575
-1576
-1577
-1578
-1579
-1580
-1581
-1582
-1583
-1584
-1585
-1586
-1587
-1588
-1589
-1590
// *****************************************************************************
+
  1
+  2
+  3
+  4
+  5
+  6
+  7
+  8
+  9
+ 10
+ 11
+ 12
+ 13
+ 14
+ 15
+ 16
+ 17
+ 18
+ 19
+ 20
+ 21
+ 22
+ 23
+ 24
+ 25
+ 26
+ 27
+ 28
+ 29
+ 30
+ 31
+ 32
+ 33
+ 34
+ 35
+ 36
+ 37
+ 38
+ 39
+ 40
+ 41
+ 42
+ 43
+ 44
+ 45
+ 46
+ 47
+ 48
+ 49
+ 50
+ 51
+ 52
+ 53
+ 54
+ 55
+ 56
+ 57
+ 58
+ 59
+ 60
+ 61
+ 62
+ 63
+ 64
+ 65
+ 66
+ 67
+ 68
+ 69
+ 70
+ 71
+ 72
+ 73
+ 74
+ 75
+ 76
+ 77
+ 78
+ 79
+ 80
+ 81
+ 82
+ 83
+ 84
+ 85
+ 86
+ 87
+ 88
+ 89
+ 90
+ 91
+ 92
+ 93
+ 94
+ 95
+ 96
+ 97
+ 98
+ 99
+100
+101
+102
+103
+104
+105
+106
+107
+108
+109
+110
+111
+112
+113
+114
+115
+116
+117
+118
+119
+120
+121
+122
+123
+124
+125
+126
+127
+128
+129
+130
+131
+132
+133
+134
+135
+136
+137
+138
+139
+140
+141
+142
+143
+144
+145
+146
+147
+148
+149
+150
+151
+152
+153
+154
+155
+156
+157
+158
+159
+160
+161
+162
+163
+164
// *****************************************************************************
 /*!
-  \file      src/Inciter/Transporter.cpp
+  \file      src/PDE/ConfigureMultiMat.cpp
   \copyright 2012-2015 J. Bakosi,
              2016-2018 Los Alamos National Security, LLC.,
              2019-2021 Triad National Security, LLC.
              All rights reserved. See the LICENSE file for details.
-  \brief     Transporter drives the time integration of transport equations
-  \details   Transporter drives the time integration of transport equations.
-    The implementation uses the Charm++ runtime system and is fully asynchronous,
-    overlapping computation, communication as well as I/O. The algorithm
-    utilizes the structured dagger (SDAG) Charm++ functionality. The high-level
-    overview of the algorithm structure and how it interfaces with Charm++ is
-    discussed in the Charm++ interface file src/Inciter/transporter.ci.
-*/
-// *****************************************************************************
-
+  \brief     Register and compile configuration for multi-material compressible
+     flow PDE
+  \details   Register and compile configuration for compressible multi-material
+     flow PDE.
+*/
+// *****************************************************************************
+
+#include <set>
+#include <map>
+#include <vector>
 #include <string>
-#include <iostream>
-#include <cstddef>
-#include <unordered_set>
-#include <limits>
-#include <cmath>
-
-#include <brigand/algorithms/for_each.hpp>
-
-#include "Macro.hpp"
-#include "Transporter.hpp"
-#include "Fields.hpp"
-#include "PDEStack.hpp"
-#include "UniPDF.hpp"
-#include "PDFWriter.hpp"
-#include "ContainerUtil.hpp"
-#include "LoadDistributor.hpp"
-#include "MeshReader.hpp"
-#include "Inciter/InputDeck/InputDeck.hpp"
-#include "NodeDiagnostics.hpp"
-#include "ElemDiagnostics.hpp"
-#include "DiagWriter.hpp"
-#include "Callback.hpp"
-#include "CartesianProduct.hpp"
-
-#include "NoWarning/inciter.decl.h"
-#include "NoWarning/partitioner.decl.h"
-
-extern CProxy_Main mainProxy;
-
-namespace inciter {
-
-extern ctr::InputDeck g_inputdeck_defaults;
-extern ctr::InputDeck g_inputdeck;
-extern std::vector< CGPDE > g_cgpde;
-extern std::vector< DGPDE > g_dgpde;
-extern std::vector< FVPDE > g_fvpde;
-
-}
-
-using inciter::Transporter;
-
-Transporter::Transporter() :
-  m_input( input() ),
-  m_nchare( m_input.size() ),
-  m_meshid(),
-  m_ncit( m_nchare.size(), 0 ),
-  m_nload( 0 ),
-  m_ntrans( 0 ),
-  m_ndtmsh( 0 ),
-  m_dtmsh(),
-  m_npart( 0 ),
-  m_nstat( 0 ),
-  m_ndisc( 0 ),
-  m_nchk( 0 ),
-  m_ncom( 0 ),
-  m_nt0refit( m_nchare.size(), 0 ),
-  m_ndtrefit( m_nchare.size(), 0 ),
-  m_noutrefit( m_nchare.size(), 0 ),
-  m_noutderefit( m_nchare.size(), 0 ),
-  m_scheme(),
-  m_partitioner(),
-  m_refiner(),
-  m_meshwriter(),
-  m_sorter(),
-  m_nelem( m_nchare.size() ),
-  m_npoin(),
-  m_finished( m_nchare.size(), 0 ),
-  m_meshvol( m_nchare.size() ),
-  m_minstat( m_nchare.size() ),
-  m_maxstat( m_nchare.size() ),
-  m_avgstat( m_nchare.size() ),
-  m_timer(),
-  m_progMesh( g_inputdeck.get< tag::cmd, tag::feedback >(),
-              ProgMeshPrefix, ProgMeshLegend ),
-  m_progWork( g_inputdeck.get< tag::cmd, tag::feedback >(),
-              ProgWorkPrefix, ProgWorkLegend )
-// *****************************************************************************
-//  Constructor
-// *****************************************************************************
-{
-  // Echo configuration to screen
-  info( printer() );
-
-  const auto nstep = g_inputdeck.get< tag::nstep >();
-  const auto t0 = g_inputdeck.get< tag::t0 >();
-  const auto term = g_inputdeck.get< tag::term >();
-  const auto constdt = g_inputdeck.get< tag::dt >();
-
-  // If the desired max number of time steps is larger than zero, and the
-  // termination time is larger than the initial time, and the constant time
-  // step size (if that is used) is smaller than the duration of the time to be
-  // simulated, we have work to do, otherwise, finish right away. If a constant
-  // dt is not used, that part of the logic is always true as the default
-  // constdt is zero, see inciter::ctr::InputDeck::InputDeck().
-  if ( nstep != 0 && term > t0 && constdt < term-t0 ) {
-
-    // Enable SDAG waits for collecting mesh statistics
-    thisProxy.wait4stat();
+
+#include <brigand/algorithms/for_each.hpp>
+
+#include "Tags.hpp"
+#include "CartesianProduct.hpp"
+#include "PDEFactory.hpp"
+#include "Inciter/Options/PDE.hpp"
+#include "ContainerUtil.hpp"
+#include "ConfigureMultiMat.hpp"
+#include "MultiMat/Physics/DG.hpp"
+#include "MultiMat/Physics/FV.hpp"
+#include "MultiMat/DGMultiMat.hpp"
+#include "MultiMat/FVMultiMat.hpp"
+#include "MultiMat/Problem.hpp"
+#include "Inciter/Options/Material.hpp"
+
+namespace inciter {
+
+void
+registerMultiMat( DGFactory& df, FVFactory& ff,
+  std::set< ctr::PDEType >& fvt, std::set< ctr::PDEType >& dgt )
+// *****************************************************************************
+// Register multi-material compressible flow PDE into PDE factory
+//! \param[in,out] df Discontinuous Galerkin PDE factory to register to
+//! \param[in,out] ff Finite volume PDE factory to register to
+//! \param[in,out] dgt Counters for equation types registered into DG factory
+//! \param[in,out] fvt Counters for equation types registered into FV factory
+// *****************************************************************************
+{
+  // Construct vector of vectors for all possible policies
+  using DGMultiMatPolicies =
+    tk::cartesian_product< dg::MultiMatPhysics, MultiMatProblems >;
+  // Register PDEs for all combinations of policies
+  brigand::for_each< DGMultiMatPolicies >(
+    registerDG< dg::MultiMat >( df, dgt, ctr::PDEType::MULTIMAT ) );
+
+  // Construct vector of vectors for all possible policies
+  using FVMultiMatPolicies =
+    tk::cartesian_product< fv::MultiMatPhysics, MultiMatProblems >;
+  // Register PDEs for all combinations of policies
+  brigand::for_each< FVMultiMatPolicies >(
+    registerFV< fv::MultiMat >( ff, fvt, ctr::PDEType::MULTIMAT ) );
+}
+
+std::vector< std::pair< std::string, std::string > >
+infoMultiMat( std::map< ctr::PDEType, tk::ncomp_t >& cnt )
+// *****************************************************************************
+//  Return information on the compressible flow system of PDEs
+//! \param[inout] cnt std::map of counters for all PDE types
+//! \return vector of string pairs describing the PDE configuration
+// *****************************************************************************
+{
+  using eq = tag::multimat;
+  using tk::parameter;
+  using tk::parameters;
+
+  auto c = ++cnt[ ctr::PDEType::MULTIMAT ];       // count eqs
+  --c;  // used to index vectors starting with 0<--- Variable 'c' is assigned a value that is never used.
+
+  std::vector< std::pair< std::string, std::string > > nfo;
+
+  nfo.emplace_back( ctr::PDE().name( ctr::PDEType::MULTIMAT ), "" );
+
+  nfo.emplace_back( "physics", ctr::Physics().name(
+    g_inputdeck.get< eq, tag::physics >() ) );
+
+  nfo.emplace_back( "problem", ctr::Problem().name(
+    g_inputdeck.get< eq, tag::problem >() ) );
+
+  nfo.emplace_back( "flux", ctr::Flux().name(
+    g_inputdeck.get< tag::flux >() ) );
+
+  auto nmat = g_inputdeck.get< eq, tag::nmat >();
+  nfo.emplace_back( "number of materials", std::to_string( nmat ) );
+
+  auto prelax = g_inputdeck.get< eq, tag::prelax >();
+  nfo.emplace_back( "finite pressure relaxation", std::to_string( prelax ) );
+
+  auto intsharp = g_inputdeck.get< eq, tag::intsharp >();
+  nfo.emplace_back( "interface sharpening", std::to_string( intsharp ) );
+
+  auto rho0cn = g_inputdeck.get< eq, tag::rho0constraint >();
+  nfo.emplace_back( "density constraint correction", std::to_string( rho0cn ) );
+
+  auto ncomp = g_inputdeck.get< tag::ncomp >();
+  nfo.emplace_back( "number of components", std::to_string( ncomp ) );
+
+  // Material eos output
+  const auto& matprop = g_inputdeck.get< tag::material >();
+  for (const auto& mtype : matprop) {
+    const auto& m_id = mtype.get< tag::id >();
+    ctr::Material opt;
+    nfo.emplace_back( opt.name( mtype.get< tag::eos >() ),
+      std::to_string(m_id.size())+" materials" );
+    nfo.emplace_back( "material id", parameters( m_id ) );
+  }
+
+  // ICs and IC-boxes
 
-    // Configure and write diagnostics file header
-    diagHeader();
-
-    // Create mesh partitioner AND boundary condition object group
-    createPartitioner();
-
-  } else finish();      // stop if no time stepping requested
-}
-
-Transporter::Transporter( CkMigrateMessage* m ) :
-  CBase_Transporter( m ),
-  m_progMesh( g_inputdeck.get< tag::cmd, tag::feedback >(),
-              ProgMeshPrefix, ProgMeshLegend ),
-  m_progWork( g_inputdeck.get< tag::cmd, tag::feedback >(),
-              ProgWorkPrefix, ProgWorkLegend )
-// *****************************************************************************
-//  Migrate constructor: returning from a checkpoint
-//! \param[in] m Charm++ migrate message
-// *****************************************************************************
-{
-   auto print = printer();
-   print.diag( "Restarted from checkpoint" );
-   info( print );
-   inthead( print );
-}
-
-std::vector< std::string >
-Transporter::input()
-// *****************************************************************************
-// Generate list of input mesh filenames configured by the user
-//! \return List of input mesh filenames configured by the user
-//! \details If the input file is given on the command line, a single solver
-//!   will be instantiated on the single mesh, solving potentially multiple
-//!   systems of (potentially coupled) equations. If the input file is not given
-//!   on the command line, the mesh files are expected to be configured in the
-//!   control/input file, associating a potentially different mesh to each
-//!   solver. Both configurations allow the solution of coupled systems, but the
-//!   first one solves all equations on the same mesh, while the latter can
-//!   couple solutions computed on multiple different meshes.
-// *****************************************************************************
-{
-  // Query input mesh filename specified on the command line
-  const auto& cmdinput = g_inputdeck.get< tag::cmd, tag::io, tag::input >();
-
-  // Extract mesh filenames specified in the control file (assigned to solvers)
-  std::vector< std::string > ctrinput;
-  for (const auto& im : g_inputdeck.get< tag::mesh >()) {
-    ctrinput.push_back(im.get< tag::filename >());<--- Consider using std::transform algorithm instead of a raw loop.
-  }
-
-  ErrChk( not cmdinput.empty() or not ctrinput.empty(),
-    "Either a single input mesh must be given on the command line or multiple "
-    "meshes must be configured in the control file." );
-
-   // Prepend control file path to mesh filenames in given in control file
-  if (not ctrinput.empty()) {
-     const auto& ctr = g_inputdeck.get< tag::cmd, tag::io, tag::control >();
-     auto path = ctr.substr( 0, ctr.find_last_of("/")+1 );
-     for (auto& f : ctrinput) f = path + f;<--- Consider using std::transform algorithm instead of a raw loop.
-  }
-
-  if (cmdinput.empty()) return ctrinput; else return { cmdinput };
-}
-
-void
-Transporter::info( const InciterPrint& print )
-// *****************************************************************************
-// Echo configuration to screen
-//! \param[in] print Pretty printer object to use for printing
-// *****************************************************************************
-{
-  print.part( "Factory" );
-
-  // Print out info data layout
-  print.list( "Unknowns data layout (CMake: FIELD_DATA_LAYOUT)",
-              std::list< std::string >{ tk::Fields::layout() } );
-
-  // Re-create partial differential equations stack for output
-  PDEStack stack;
-
-  // Print out information on PDE factories
-  print.eqlist( "Registered PDEs using continuous Galerkin (CG) methods",
-                stack.cgfactory(), stack.cgntypes() );
-  print.eqlist( "Registered PDEs using discontinuous Galerkin (DG) methods",
-                stack.dgfactory(), stack.dgntypes() );
-  print.eqlist( "Registered PDEs using finite volume (DG) methods",
-                stack.fvfactory(), stack.fvntypes() );
-  print.endpart();
-
-  // Print out information on problem
-  print.part( "Problem" );
-
-  // Print out info on problem title
-  if ( !g_inputdeck.get< tag::title >().empty() )
-    print.title( g_inputdeck.get< tag::title >() );
-
-  const auto nstep = g_inputdeck.get< tag::nstep >();
-  const auto t0 = g_inputdeck.get< tag::t0 >();
-  const auto term = g_inputdeck.get< tag::term >();
-  const auto constdt = g_inputdeck.get< tag::dt >();
-  const auto cfl = g_inputdeck.get< tag::cfl >();
-  const auto scheme = g_inputdeck.get< tag::scheme >();
-
-  // Print discretization parameters
-  print.section( "Discretization parameters" );
-  print.Item< ctr::Scheme, tag::scheme >();
-  print.item( "Implicit-Explicit Runge-Kutta",
-              g_inputdeck.get< tag::imex_runge_kutta >() );
-
-  if (g_inputdeck.centering() == tk::Centering::ELEM)
-  {
-    print.Item< ctr::Limiter, tag::limiter >();
-
-    print.item("Shock detection based limiting",
-      g_inputdeck.get< tag::shock_detector_coeff >());
-
-    if (g_inputdeck.get< tag::accuracy_test >())
-    {
-      print.item("WARNING: order-of-accuracy testing enabled",
-        "robustness corrections inactive");
-    }
-
-    print.item("Limited solution projection",
-      g_inputdeck.get< tag::limsol_projection >());
-  }
-  print.item( "PE-locality mesh reordering",
-              g_inputdeck.get< tag::pelocal_reorder >() );
-  print.item( "Operator-access mesh reordering",
-              g_inputdeck.get< tag::operator_reorder >() );
-  auto steady = g_inputdeck.get< tag::steady_state >();
-  print.item( "Local time stepping", steady );
-  if (steady) {
-    print.item( "L2-norm residual convergence criterion",
-                g_inputdeck.get< tag::residual >() );
-    print.item( "Convergence criterion component index",
-                g_inputdeck.get< tag::rescomp >() );
-  }
-  print.item( "Number of time steps", nstep );
-  print.item( "Start time", t0 );
-  print.item( "Terminate time", term );
-
-  if (constdt > std::numeric_limits< tk::real >::epsilon())
-    print.item( "Constant time step size", constdt );
-  else if (cfl > std::numeric_limits< tk::real >::epsilon())
-  {
-    print.item( "CFL coefficient", cfl );
-  }
-
-  const auto& meshes = g_inputdeck.get< tag::mesh >();
-  const auto& depvars = g_inputdeck.get< tag::depvar >();
-  for (std::size_t i=0; i<meshes.size(); ++i) {
-    print.item( "Dependent var name and assoc. mesh", std::string{depvars[i]}
-      + " - " + meshes[i].get< tag::filename >() );
-  }
-
-  // Print out info on settings of selected partial differential equations
-  print.pdes( "Partial differential equations integrated", stack.info() );
-
-  // Print out adaptive polynomial refinement configuration
-  if (scheme == ctr::SchemeType::PDG) {
-    print.section( "Polynomial refinement (p-ref)" );
-    print.item( "p-refinement",
-                g_inputdeck.get< tag::pref, tag::pref >() );
-    print.Item< ctr::PrefIndicator, tag::pref, tag::indicator >();
-    print.item( "Max degrees of freedom",
-                g_inputdeck.get< tag::pref, tag::ndofmax >() );
-    print.item( "Tolerance",
-                g_inputdeck.get< tag::pref, tag::tolref >() );
-  }
-
-  // Print out adaptive mesh refinement configuration
-  const auto amr = g_inputdeck.get< tag::amr, tag::amr >();
-  if (amr) {
-    print.section( "Mesh refinement (h-ref)" );
-    auto maxlevels = g_inputdeck.get< tag::amr, tag::maxlevels >();
-    print.item( "Maximum mesh refinement levels", maxlevels );
-    print.Item< ctr::AMRError, tag::amr, tag::error >();
-    auto t0ref = g_inputdeck.get< tag::amr, tag::t0ref >();
-    print.item( "Refinement at t<0 (t0ref)", t0ref );
-    if (t0ref) {
-      const auto& initref = g_inputdeck.get< tag::amr, tag::initial >();
-      print.item( "Initial refinement steps", initref.size() );
-
-      auto eps = std::numeric_limits< tk::real >::epsilon();
-
-      const auto& amr_coord = g_inputdeck.get< tag::amr, tag::coords >();
-      const auto& amr_defcoord = g_inputdeck_defaults.get< tag::amr, tag::coords >();
-
-      auto xminus = amr_coord.get< tag::xminus >();
-      auto xminus_default = amr_defcoord.get< tag::xminus >();
-      if (std::abs( xminus - xminus_default ) > eps)
-        print.item( "Initial refinement x-", xminus );
-      auto xplus = amr_coord.get< tag::xplus >();
-      auto xplus_default = amr_defcoord.get< tag::xplus >();
-      if (std::abs( xplus - xplus_default ) > eps)
-        print.item( "Initial refinement x+", xplus );
-
-      auto yminus = amr_coord.get< tag::yminus >();
-      auto yminus_default = amr_defcoord.get< tag::yminus >();
-      if (std::abs( yminus - yminus_default ) > eps)
-        print.item( "Initial refinement y-", yminus );
-      auto yplus = amr_coord.get< tag::yplus >();
-      auto yplus_default = amr_defcoord.get< tag::yplus >();
-      if (std::abs( yplus - yplus_default ) > eps)
-        print.item( "Initial refinement y+", yplus );
-
-      auto zminus = amr_coord.get< tag::zminus >();
-      auto zminus_default = amr_defcoord.get< tag::zminus >();
-      if (std::abs( zminus - zminus_default ) > eps)
-        print.item( "Initial refinement z-", zminus );
-      auto zplus = amr_coord.get< tag::zplus >();
-      auto zplus_default = amr_defcoord.get< tag::zplus >();
-      if (std::abs( zplus - zplus_default ) > eps)
-        print.item( "Initial refinement z+", zplus );
-    }
-    auto dtref = g_inputdeck.get< tag::amr, tag::dtref >();
-    print.item( "Refinement at t>0 (dtref)", dtref );
-    if (dtref) {
-      auto dtfreq = g_inputdeck.get< tag::amr, tag::dtfreq >();
-      print.item( "Mesh refinement frequency, t>0", dtfreq );
-      print.item( "Uniform-only mesh refinement, t>0",
-                  g_inputdeck.get< tag::amr, tag::dtref_uniform >() );
-    }
-    print.item( "Refinement tolerance",
-                g_inputdeck.get< tag::amr, tag::tol_refine >() );
-    print.item( "De-refinement tolerance",
-                g_inputdeck.get< tag::amr, tag::tol_derefine >() );
-  }
-
-  // Print out ALE configuration
-  const auto ale = g_inputdeck.get< tag::ale, tag::ale >();
-  if (ale) {
-    print.section( "Arbitrary Lagrangian-Eulerian (ALE) mesh motion" );
-    auto dvcfl = g_inputdeck.get< tag::ale, tag::dvcfl >();
-    print.item( "Volume-change CFL coefficient", dvcfl );
-    print.Item< ctr::MeshVelocity, tag::ale, tag::mesh_velocity >();
-    print.Item< ctr::MeshVelocitySmoother, tag::ale, tag::smoother >();
-    print.item( "Mesh motion dimensions", tk::parameters(
-                g_inputdeck.get< tag::ale, tag::mesh_motion >() ) );
-    const auto& meshforce = g_inputdeck.get< tag::ale, tag::meshforce >();
-    print.item( "Mesh velocity force coefficients", tk::parameters(meshforce) );
-    print.item( "Vorticity multiplier",
-                g_inputdeck.get< tag::ale, tag::vortmult >() );
-    print.item( "Mesh velocity linear solver tolerance",
-                g_inputdeck.get< tag::ale, tag::tolerance >() );
-    print.item( "Mesh velocity linear solver maxit",
-                g_inputdeck.get< tag::ale, tag::maxit >() );
-    const auto& dir = g_inputdeck.get< tag::ale, tag::dirichlet >();
-    if (not dir.empty())
-      print.item( "Mesh velocity Dirichlet BC sideset(s)",
-                  tk::parameters( dir ) );
-    const auto& sym = g_inputdeck.get< tag::ale, tag::symmetry >();
-    if (not sym.empty())
-      print.item( "Mesh velocity symmetry BC sideset(s)",
-                  tk::parameters( sym ) );
-    std::size_t i = 1;
-    for (const auto& m : g_inputdeck.get< tag::ale, tag::move >()) {
-       tk::ctr::UserTable opt;
-       print.item( opt.group() + ' ' + std::to_string(i) + " interpreted as",
-                   opt.name( m.get< tag::fntype >() ) );
-       const auto& s = m.get< tag::sideset >();
-       if (not s.empty())
-         print.item( "Moving sideset(s) with table " + std::to_string(i),
-                     tk::parameters(s));
-       ++i;
-    }
-  }
-
-  // Print I/O filenames
-  print.section( "Input/Output filenames and directories" );
-  print.item( "Input mesh(es)", tk::parameters( m_input ) );
-  const auto& of = g_inputdeck.get< tag::cmd, tag::io, tag::output >();
-  print.item( "Volume field output file(s)",
-              of + ".e-s.<meshid>.<numchares>.<chareid>" );
-  print.item( "Surface field output file(s)",
-              of + "-surf.<surfid>.e-s.<meshid>.<numchares>.<chareid>" );
-  print.item( "History output file(s)", of + ".hist.{pointid}" );
-  print.item( "Diagnostics file",
-              g_inputdeck.get< tag::cmd, tag::io, tag::diag >() );
-  print.item( "Checkpoint/restart directory",
-              g_inputdeck.get< tag::cmd, tag::io, tag::restart >() + '/' );
-
-  // Print output intervals
-  print.section( "Output intervals (in units of iteration count)" );
-  print.item( "TTY", g_inputdeck.get< tag::ttyi>() );
-  print.item( "Field and surface",
-              g_inputdeck.get< tag::field_output, tag::interval >() );
-  print.item( "History",
-              g_inputdeck.get< tag::history_output, tag::interval >() );
-  print.item( "Diagnostics",
-              g_inputdeck.get< tag::diagnostics, tag::interval >() );
-  print.item( "Checkpoint/restart",
-              g_inputdeck.get< tag::cmd, tag::rsfreq >() );
-  auto tf = g_inputdeck.get< tag::field_output, tag::time_interval >();
-  auto th = g_inputdeck.get< tag::history_output, tag::time_interval >();
-  if (tf>0.0 || th>0.0) {
-    print.section( "Output intervals (in units of physics time)" );
-    if (tf > 0.0) print.item( "Field and surface", tf );
-    if (th > 0.0) print.item( "History", th );
-  }
-  const auto& rf = g_inputdeck.get< tag::field_output, tag::time_range >();
-  const auto& rh = g_inputdeck.get< tag::history_output, tag::time_range >();
-  if (not rf.empty() or not rh.empty()) {
-    print.section( "Output time ranges (in units of physics time)" );
-    print.item("Field output { mintime, maxtime, dt }", tk::parameters(rf));
-    print.item("History output { mintime, maxtime, dt }", tk::parameters(rh));
-  }
-
-  //// Print output variables: fields and surfaces
-  //const auto nodeoutvars = g_inputdeck.outvars( tk::Centering::NODE );
-  //const auto elemoutvars = g_inputdeck.outvars( tk::Centering::ELEM );
-  //const auto outsets = g_inputdeck.outsets();
-  //if (!nodeoutvars.empty() || !elemoutvars.empty() || !outsets.empty())
-  //   print.section( "Output fields" );
-  //if (!nodeoutvars.empty())
-  //  print.item( "Node field(s)", tk::parameters(nodeoutvars) );
-  //if (!elemoutvars.empty())
-  //  print.item( "Elem field(s)", tk::parameters(elemoutvars) );
-  //if (!aliases.empty())
-  //  print.item( "Alias(es)", tk::parameters(aliases) );
-  //if (!outsets.empty())
-  //  print.item( "Surface side set(s)", tk::parameters(outsets) );
-
-  // Print output variables: history
-  const auto& pt = g_inputdeck.get< tag::history_output, tag::point >();
-  if (!pt.empty()) {
-    print.section( "Output time history" );
-    for (std::size_t p=0; p<pt.size(); ++p) {
-      const auto& id = pt[p].get< tag::id >();
-      std::stringstream ss;
-      auto prec = g_inputdeck.get< tag::history_output, tag::precision >();
-      ss << std::setprecision( static_cast<int>(prec) );
-      ss << of << ".hist." << id;
-      print.longitem( "At point " + id + ' ' +
-        tk::parameters(pt[p].get<tag::coord>()), ss.str() );
-    }
-  }
-
-  print.endsubsection();
-}
-
-bool
-Transporter::matchBCs( std::map< int, std::vector< std::size_t > >& bnd )
-// *****************************************************************************
- // Verify that side sets specified in the control file exist in mesh file
- //! \details This function does two things: (1) it verifies that the side
- //!   sets used in the input file (either to which boundary conditions (BC)
- //!   are assigned or listed as field output by the user in the
- //!   input file) all exist among the side sets read from the input mesh
- //!   file and errors out if at least one does not, and (2) it matches the
- //!   side set ids at which the user has configured BCs (or listed as an output
- //!   surface) to side set ids read from the mesh file and removes those face
- //!   and node lists associated to side sets that the user did not set BCs or
- //!   listed as field output on (as they will not need processing further since
- //!   they will not be used).
- //! \param[in,out] bnd Node or face lists mapped to side set ids
- //! \return True if sidesets have been used and found in mesh
-// *****************************************************************************
-{
-  // Query side set ids at which BCs assigned for all BC types for all PDEs
-  using bclist = ctr::bclist::Keys;
-  std::unordered_set< int > usedsets;
-  brigand::for_each< bclist >( UserBC( g_inputdeck, usedsets ) );
-
-  // Query side sets of time dependent BCs (since tag::bctimedep is not a part
-  // of tag::bc)
-  const auto& bcs = g_inputdeck.get< tag::bc >();
-  for (const auto& bci : bcs) {
-    for (const auto& b : bci.get< tag::timedep >()) {
-      for (auto i : b.get< tag::sideset >())
-        usedsets.insert(static_cast<int>(i));
-    }
-  }
-
-  // Query side sets of boundaries prescribed as moving with ALE
-  for (const auto& move : g_inputdeck.get< tag::ale, tag::move >())
-    for (auto i : move.get< tag::sideset >())
-      usedsets.insert(static_cast<int>(i));
-
-  // Add sidesets requested for field output
-  const auto& ss = g_inputdeck.get< tag::cmd, tag::io, tag::surface >();
-  for (const auto& s : ss) {
-    std::stringstream conv( s );
-    int num;
-    conv >> num;
-    usedsets.insert( num );
-  }
-
-  // Find user-configured side set ids among side sets read from mesh file
-  std::unordered_set< int > sidesets_used;
-  for (auto i : usedsets) {       // for all side sets used in control file
-    if (bnd.find(i) != end(bnd))  // used set found among side sets in file
-      sidesets_used.insert( i );  // store side set id configured as BC
-    //else {
-    //  Throw( "Boundary conditions specified on side set " +
-    //    std::to_string(i) + " which does not exist in mesh file" );
-    //}
-  }
-
-  // Remove sidesets not used (will not process those further)
-  tk::erase_if( bnd, [&]( auto& item ) {
-    return sidesets_used.find( item.first ) == end(sidesets_used);
-  });
-
-  return !bnd.empty();
-}
-
-void
-Transporter::createPartitioner()
-// *****************************************************************************
-// Create mesh partitioner AND boundary conditions group
-// *****************************************************************************
-{
-  auto scheme = g_inputdeck.get< tag::scheme >();
-  auto centering = ctr::Scheme().centering( scheme );
-  auto print = printer();
-
-  // Create partitioner callbacks (order important)
-  tk::PartitionerCallback cbp {{
-      CkCallback( CkReductionTarget(Transporter,load), thisProxy )
-    , CkCallback( CkReductionTarget(Transporter,partitioned), thisProxy )
-    , CkCallback( CkReductionTarget(Transporter,distributed), thisProxy )
-    , CkCallback( CkReductionTarget(Transporter,refinserted), thisProxy )
-    , CkCallback( CkReductionTarget(Transporter,refined), thisProxy )
-  }};
-
-  // Create refiner callbacks (order important)
-  tk::RefinerCallback cbr {{
-      CkCallback( CkReductionTarget(Transporter,queriedRef), thisProxy )
-    , CkCallback( CkReductionTarget(Transporter,respondedRef), thisProxy )
-    , CkCallback( CkReductionTarget(Transporter,compatibility), thisProxy )
-    , CkCallback( CkReductionTarget(Transporter,bndint), thisProxy )
-    , CkCallback( CkReductionTarget(Transporter,matched), thisProxy )
-    , CkCallback( CkReductionTarget(Transporter,refined), thisProxy )
-  }};
-
-  // Create sorter callbacks (order important)
-  tk::SorterCallback cbs {{
-      CkCallback( CkReductionTarget(Transporter,queried), thisProxy )
-    , CkCallback( CkReductionTarget(Transporter,responded), thisProxy )
-    , CkCallback( CkReductionTarget(Transporter,discinserted), thisProxy )
-    , CkCallback( CkReductionTarget(Transporter,workinserted), thisProxy )
-  }};
-
-  // Start timer measuring preparation of mesh(es) for partitioning
-  m_timer[ TimerTag::MESH_READ ];
-
-  // Start preparing mesh(es)
-  print.diag( "Reading mesh(es)" );
-
-  // Create (discretization) Scheme chare worker arrays for all meshes
-  for ([[maybe_unused]] const auto& filename : m_input)
-    m_scheme.emplace_back( g_inputdeck.get< tag::scheme >(),
-                           g_inputdeck.get< tag::ale, tag::ale >(),
-                           need_linearsolver(),
-                           centering );
-
-  ErrChk( !m_input.empty(), "No input mesh" );
-
-  // Read boundary (side set) data from a list of input mesh files
-  std::size_t meshid = 0;
-  for (const auto& filename : m_input) {
-    // Create mesh reader for reading side sets from file
-    tk::MeshReader mr( filename );
-
-    // Read out total number of mesh points from mesh file
-    m_npoin.push_back( mr.npoin() );
-
-    std::map< int, std::vector< std::size_t > > bface;
-    std::map< int, std::vector< std::size_t > > faces;
-    std::map< int, std::vector< std::size_t > > bnode;
-
-    // Read boundary-face connectivity on side sets
-    mr.readSidesetFaces( bface, faces );
-
-    bool bcs_set = false;
-    if (centering == tk::Centering::ELEM) {
-
-      // Verify boundarty condition (BC) side sets used exist in mesh file
-      bcs_set = matchBCs( bface );
-
-    } else if (centering == tk::Centering::NODE) {
-
-      // Read node lists on side sets
-      bnode = mr.readSidesetNodes();
-      // Verify boundarty condition (BC) side sets used exist in mesh file
-      bool bcnode_set = matchBCs( bnode );
-      bool bcface_set = matchBCs( bface );
-      bcs_set = bcface_set or bcnode_set;
-    }
-
-    // Warn on no BCs
-    if (!bcs_set) print << "\n>>> WARNING: No boundary conditions set\n\n";
-
-    auto opt = m_scheme[meshid].arrayoptions();
-    // Create empty mesh refiner chare array (bound to workers)
-    m_refiner.push_back( CProxy_Refiner::ckNew(opt) );
-    // Create empty mesh sorter Charm++ chare array (bound to workers)
-    m_sorter.push_back( CProxy_Sorter::ckNew(opt) );
-
-    // Create MeshWriter chare group for mesh
-    m_meshwriter.push_back(
-      tk::CProxy_MeshWriter::ckNew(
-        g_inputdeck.get< tag::field_output, tag::filetype >(),
-        centering,
-        g_inputdeck.get< tag::cmd, tag::benchmark >(),
-        m_input.size() ) );
-
-    // Create mesh partitioner Charm++ chare nodegroup for all meshes
-    m_partitioner.push_back(
-      CProxy_Partitioner::ckNew( meshid, filename, cbp, cbr, cbs,
-        thisProxy, m_refiner.back(), m_sorter.back(), m_meshwriter.back(),
-        m_scheme, bface, faces, bnode ) );
-
-    ++meshid;
-  }
-}
-
-void
-Transporter::load( std::size_t meshid, std::size_t nelem )
-// *****************************************************************************
-// Reduction target: the mesh has been read from file on all PEs
-//! \param[in] meshid Mesh id (summed accross all compute nodes)
-//! \param[in] nelem Number of mesh elements per mesh (summed across all
-//!    compute nodes)
-// *****************************************************************************
-{
-  meshid /= static_cast< std::size_t >( CkNumNodes() );
-  Assert( meshid < m_nelem.size(), "MeshId indexing out" );
-  m_nelem[meshid] = nelem;
-
-  // Compute load distribution given total work (nelem) and user-specified
-  // virtualization
-  uint64_t chunksize, remainder;
-  m_nchare[meshid] = static_cast<int>(
-    tk::linearLoadDistributor(
-       g_inputdeck.get< tag::cmd, tag::virtualization >(),
-       m_nelem[meshid], CkNumPes(), chunksize, remainder ) );
-
-  // Store sum of meshids (across all chares, key) for each meshid (value).
-  // This is used to look up the mesh id after collectives that sum their data.
-  m_meshid[ static_cast<std::size_t>(m_nchare[meshid])*meshid ] = meshid;
-  Assert( meshid < m_nelem.size(), "MeshId indexing out" );
-
-  // Tell the meshwriter for this mesh the total number of its chares
-  m_meshwriter[meshid].nchare( meshid, m_nchare[meshid] );
-
-  if (++m_nload == m_nelem.size()) {     // all meshes have been loaded
-    m_nload = 0;
-    auto print = printer();
-
-    // Start timer measuring preparation of the mesh for partitioning
-    const auto& timer = tk::cref_find( m_timer, TimerTag::MESH_READ );
-    print.diag( "Mesh read time: " + std::to_string( timer.dsec() ) + " sec" );
-
-    // Print out mesh partitioning configuration
-    print.section( "Mesh partitioning" );
-    print.Item< tk::ctr::PartitioningAlgorithm, tag::partitioning >();
-    print.item( "Virtualization [0.0...1.0]",
-                g_inputdeck.get< tag::cmd, tag::virtualization >() );
-    // Print out initial mesh statistics
-    meshstat( "Initial load distribution" );
-
-    // Query number of initial mesh refinement steps
-    int nref = 0;
-    if (g_inputdeck.get< tag::amr, tag::t0ref >())
-      nref = static_cast<int>(g_inputdeck.get< tag::amr,
-        tag::initial >().size());
-
-    m_progMesh.start( print, "Preparing mesh", {{ CkNumPes(), CkNumPes(), nref,
-      m_nchare[0], m_nchare[0], m_nchare[0], m_nchare[0] }} );
-
-    // Partition first mesh
-    m_partitioner[0].partition( m_nchare[0] );
-  }
-}
-
-void
-Transporter::partitioned( std::size_t meshid )
-// *****************************************************************************
-// Reduction target: a mesh has been partitioned
-//! \param[in] meshid Mesh id
-// *****************************************************************************
-{
-  if (++m_npart == m_nelem.size()) {     // all meshes have been partitioned
-    m_npart = 0;
-  } else { // partition next mesh
-    m_partitioner[meshid+1].partition( m_nchare[meshid+1] );
-  }
-}
-
-void
-Transporter::distributed( std::size_t meshid )
-// *****************************************************************************
-// Reduction target: all compute nodes have distributed their mesh after
-// partitioning
-//! \param[in] meshid Mesh id
-// *****************************************************************************
-{
-  m_partitioner[meshid].refine();
-}
-
-void
-Transporter::refinserted( std::size_t meshid, std::size_t error )
-// *****************************************************************************
-// Reduction target: all compute nodes have created the mesh refiners
-//! \param[in] meshid Mesh id (aggregated across all compute nodes with operator
-//!   max)
-//! \param[in] error Error code (aggregated across all compute nodes with
-//!   operator max)
-// *****************************************************************************
-{
-  if (error) {
-
-    printer() << "\n>>> ERROR: A worker chare was not assigned any mesh "
-              "elements after distributing mesh " + std::to_string(meshid) +
-              ". This can happen in SMP-mode with a large +ppn "
-              "parameter (number of worker threads per logical node) and is "
-              "most likely the fault of the mesh partitioning algorithm not "
-              "tolerating the case when it is asked to divide the "
-              "computational domain into a number of partitions different "
-              "than the number of ranks it is called on, i.e., in case of "
-              "overdecomposition and/or calling the partitioner in SMP mode "
-              "with +ppn larger than 1. Solution 1: Try a different "
-              "partitioning algorithm (e.g., rcb instead of mj). Solution 2: "
-              "Decrease +ppn.";
-    finish( meshid );
-
-  } else {
-
-     m_refiner[meshid].doneInserting();
-
-  }
-}
-
-void
-Transporter::queriedRef( std::size_t meshid )
-// *****************************************************************************
-// Reduction target: all Refiner chares have queried their boundary edges
-//! \param[in] meshid Mesh id
-// *****************************************************************************
-{
-  m_refiner[meshid].response();
-}
-
-void
-Transporter::respondedRef( std::size_t meshid )
-// *****************************************************************************
-// Reduction target: all Refiner chares have setup their boundary edges
-//! \param[in] meshid Mesh id
-// *****************************************************************************
-{
-  m_refiner[meshid].refine();
-}
-
-void
-Transporter::compatibility( std::size_t meshid )
-// *****************************************************************************
-// Reduction target: all Refiner chares have received a round of edges,
-// and have run their compatibility algorithm
-//! \param[in] meshid Mesh id (aggregated across all chares using operator max)
-//! \details This is called iteratively, until convergence by Refiner. At this
-//!   point all Refiner chares have received a round of edge data (tags whether
-//!   an edge needs to be refined, etc.), and applied the compatibility
-//!   algorithm independent of other Refiner chares. We keep going until the
-//!   mesh is no longer modified by the compatibility algorithm, based on a new
-//!   round of edge data communication started in Refiner::comExtra().
-// *****************************************************************************
-{
-  m_refiner[meshid].correctref();
-}
-
-void
-Transporter::matched( std::size_t summeshid,
-                      std::size_t nextra,
-                      std::size_t nref,
-                      std::size_t nderef,
-                      std::size_t sumrefmode )
-// *****************************************************************************
-// Reduction target: all Refiner chares have matched/corrected the tagging
-// of chare-boundary edges, all chares are ready to perform refinement.
-//! \param[in] summeshid Mesh id (summed across all chares)
-//! \param[in] nextra Sum (across all chares) of the number of edges on each
-//!   chare that need correction along chare boundaries
-//! \param[in] nref Sum of number of refined tetrahedra across all chares.
-//! \param[in] nderef Sum of number of derefined tetrahedra across all chares.
-//! \param[in] sumrefmode Sum of contributions from all chares, encoding
-//!   refinement mode of operation.
-// *****************************************************************************
-{
-  auto meshid = tk::cref_find( m_meshid, summeshid );
-
-  // If at least a single edge on a chare still needs correction, do correction,
-  // otherwise, this mesh refinement step is complete
-  if (nextra > 0) {
-
-    ++m_ncit[meshid];
-    m_refiner[meshid].comExtra();
-
-  } else {
-
-    auto print = printer();
-
-    // decode refmode
-    auto refmode = static_cast< Refiner::RefMode >(
-                     sumrefmode / static_cast<std::size_t>(m_nchare[meshid]) );
-
-    if (refmode == Refiner::RefMode::T0REF) {
-
-      if (!g_inputdeck.get< tag::cmd, tag::feedback >()) {
-        ctr::AMRInitial opt;
-        print.diag( { "meshid", "t0ref", "type", "nref", "nderef", "ncorr" },
-                    { std::to_string(meshid),
-                      std::to_string(m_nt0refit[meshid]),
-                      "initial",
-                      std::to_string(nref),
-                      std::to_string(nderef),
-                      std::to_string(m_ncit[meshid]) } );
-        ++m_nt0refit[meshid];
-      }
-      m_progMesh.inc< REFINE >( print );
-
-    } else if (refmode == Refiner::RefMode::DTREF) {
-
-      auto dtref_uni = g_inputdeck.get< tag::amr, tag::dtref_uniform >();
-      print.diag( { "meshid", "dtref", "type", "nref", "nderef", "ncorr" },
-                  { std::to_string(meshid),
-                    std::to_string(++m_ndtrefit[meshid]),
-                    (dtref_uni?"uniform":"error"),
-                    std::to_string(nref),
-                    std::to_string(nderef),
-                    std::to_string(m_ncit[meshid]) },
-                  false );
-
-    } else if (refmode == Refiner::RefMode::OUTREF) {
-
-      print.diag( { "meshid", "outref", "nref", "nderef", "ncorr" },
-                  { std::to_string(meshid),
-                    std::to_string(++m_noutrefit[meshid]),
-                    std::to_string(nref),
-                    std::to_string(nderef),
-                    std::to_string(m_ncit[meshid]) }, false );
-
-    } else if (refmode == Refiner::RefMode::OUTDEREF) {
-
-      print.diag( { "meshid", "outderef", "nref", "nderef", "ncorr" },
-                  { std::to_string(meshid),
-                    std::to_string(++m_noutderefit[meshid]),
-                    std::to_string(nref),
-                    std::to_string(nderef),
-                    std::to_string(m_ncit[meshid]) },
-                  false );
-
-    } else Throw( "RefMode not implemented" );
-
-    m_ncit[meshid] = 0;
-    m_refiner[meshid].perform();
-
-  }
-}
-
-void
-Transporter::bndint( tk::real sx, tk::real sy, tk::real sz, tk::real cb,
-                     tk::real summeshid )
-// *****************************************************************************
-// Compute surface integral across the whole problem and perform leak-test
-//! \param[in] sx X component of vector summed
-//! \param[in] sy Y component of vector summed
-//! \param[in] sz Z component of vector summed
-//! \param[in] cb Invoke callback if positive
-//! \param[in] summeshid Mesh id (summed accross all chares)
-//! \details This function aggregates partial surface integrals across the
-//!   boundary faces of the whole problem. After this global sum a
-//!   non-zero vector result indicates a leak, e.g., a hole in the boundary,
-//!   which indicates an error in the boundary face data structures used to
-//!   compute the partial surface integrals.
-// *****************************************************************************
-{
-  auto meshid = tk::cref_find( m_meshid, static_cast<std::size_t>(summeshid) );
-
-  std::stringstream err;
-  if (cb < 0.0) {
-    err << "Mesh boundary leaky after mesh refinement step; this is due to a "
-     "problem with updating the side sets used to specify boundary conditions "
-     "on faces: ";
-  } else if (cb > 0.0) {
-    err << "Mesh boundary leaky during initialization; this is due to "
-    "incorrect or incompletely specified boundary conditions for a given input "
-    "mesh: ";
-  }
-
-  auto eps = 1.0e-10;
-  if (std::abs(sx) > eps || std::abs(sy) > eps || std::abs(sz) > eps) {
-    err << "Integral result must be a zero vector: " << std::setprecision(12) <<
-           std::abs(sx) << ", " << std::abs(sy) << ", " << std::abs(sz) <<
-           ", eps = " << eps;
-    Throw( err.str() );
-  }
-
-  if (cb > 0.0) m_scheme[meshid].ghosts().resizeComm();
-}
-
-void
-Transporter::refined( std::size_t summeshid,
-                      std::size_t nelem,
-                      std::size_t npoin )
-// *****************************************************************************
-// Reduction target: all chares have refined their mesh
-//! \param[in] summeshid Mesh id (summed accross all Refiner chares)
-//! \param[in] nelem Total number of elements in mesh summed across the
-//!   distributed mesh
-//! \param[in] npoin Total number of mesh points summed across the distributed
-//!   mesh. Note that in parallel this is larger than the number of points in
-//!   the mesh, because the boundary nodes are multi-counted. But we only need
-//!   an equal or larger than npoin for Sorter::setup, so this is okay.
-// *****************************************************************************
-{
-  auto meshid = tk::cref_find( m_meshid, summeshid );
-
-  // Store new number of elements for initially refined mesh
-  m_nelem[meshid] = nelem;
-
-  m_sorter[meshid].doneInserting();
-  m_sorter[meshid].setup( npoin );
-}
-
-void
-Transporter::queried( std::size_t meshid )
-// *****************************************************************************
-// Reduction target: all Sorter chares have queried their boundary edges
-//! \param[in] meshid Mesh id
-// *****************************************************************************
-{
-  m_sorter[meshid].response();
-}
-
-void
-Transporter::responded( std::size_t meshid )
-// *****************************************************************************
-// Reduction target: all Sorter chares have responded with their boundary edges
-//! \param[in] meshid Mesh id
-// *****************************************************************************
-{
-  m_sorter[meshid].start();
-}
-
-void
-Transporter::resized( std::size_t meshid )
-// *****************************************************************************
-// Reduction target: all worker chares have resized their own mesh data after
-// AMR or ALE
-//! \param[in] meshid Mesh id
-//! \note Only used for nodal schemes
-// *****************************************************************************
-{
-  m_scheme[meshid].disc().vol();
-  m_scheme[meshid].bcast< Scheme::lhs >();
-}
-
-void
-Transporter::startEsup( std::size_t meshid )
-// *****************************************************************************
-// Reduction target: all worker chares have generated their own esup
-//! \param[in] meshid Mesh id
-//! \note Only used for cell-centered schemes
-// *****************************************************************************
-{
-  m_scheme[meshid].ghosts().nodeNeighSetup();
-}
-
-void
-Transporter::discinserted( std::size_t meshid )
-// *****************************************************************************
-// Reduction target: all Discretization chares have been inserted
-//! \param[in] meshid Mesh id
-// *****************************************************************************
-{
-  m_scheme[meshid].disc().doneInserting();
-}
-
-void
-Transporter::meshstat( const std::string& header ) const
-// *****************************************************************************
-// Print out mesh statistics
-//! \param[in] header Section header
-// *****************************************************************************
-{
-  auto print = printer();
-
-  print.section( header );
-
-  if (m_nelem.size() > 1) {
-    print.item( "Number of tetrahedra (per mesh)",tk::parameters(m_nelem) );
-    print.item( "Number of points (per mesh)", tk::parameters(m_npoin) );
-    print.item( "Number of work units (per mesh)", tk::parameters(m_nchare) );
-  }
-
-  print.item( "Total number of tetrahedra",
-              std::accumulate( begin(m_nelem), end(m_nelem), 0UL ) );
-  print.item( "Total number of points",
-              std::accumulate( begin(m_npoin), end(m_npoin), 0UL ) );
-  print.item( "Total number of work units",
-              std::accumulate( begin(m_nchare), end(m_nchare), 0 ) );
-
-  print.endsubsection();
-}
-
-bool
-Transporter::need_linearsolver() const
-// *****************************************************************************
-//  Decide if we need a linear solver for ALE
-//! \return True if ALE will neeed a linear solver
-// *****************************************************************************
-{
-  auto smoother = g_inputdeck.get< tag::ale, tag::smoother >();
-
-  if ( g_inputdeck.get< tag::ale, tag::ale >() and
-       (smoother == ctr::MeshVelocitySmootherType::LAPLACE ||
-        smoother == ctr::MeshVelocitySmootherType::HELMHOLTZ) )
-  {
-     return true;
-  } else {
-     return false;
-  }
-}
-
-void
-Transporter::disccreated( std::size_t summeshid, std::size_t npoin )
-// *****************************************************************************
-// Reduction target: all Discretization constructors have been called
-//! \param[in] summeshid Mesh id (summed accross all chares)
-//! \param[in] npoin Total number of mesh points (summed across all chares)
-//!  Note that as opposed to npoin in refined(), this npoin is not
-//!  multi-counted, and thus should be correct in parallel.
-// *****************************************************************************
-{
-  auto meshid = tk::cref_find( m_meshid, summeshid );
-  //std::cout << "Trans: " << meshid << " Transporter::disccreated()\n";
-
-  // Update number of mesh points for mesh, since it may have been refined
-  if (g_inputdeck.get< tag::amr, tag::t0ref >()) m_npoin[meshid] = npoin;
-
-  if (++m_ndisc == m_nelem.size()) { // all Disc arrays have been created
-    m_ndisc = 0;
-    auto print = printer();
-    m_progMesh.end( print );
-    if (g_inputdeck.get< tag::amr, tag::t0ref >())
-      meshstat( "Initially (t<0) refined mesh graph statistics" );
-  }
-
-  m_refiner[meshid].sendProxy();
-
-  if (g_inputdeck.get< tag::ale, tag::ale >())
-    m_scheme[meshid].ale().doneInserting();
-
-  if (need_linearsolver())
-    m_scheme[meshid].conjugategradients().doneInserting();
-
-  m_scheme[meshid].disc().vol();
-}
-
-void
-Transporter::workinserted( std::size_t meshid )
-// *****************************************************************************
-// Reduction target: all worker (derived discretization) chares have been
-// inserted
-//! \param[in] meshid Mesh id
-// *****************************************************************************
-{
-  m_scheme[meshid].bcast< Scheme::doneInserting >();
-}
-
-void
-Transporter::diagHeader()
-// *****************************************************************************
-// Configure and write diagnostics file header
-// *****************************************************************************
-{
-  for (std::size_t m=0; m<m_input.size(); ++m) {
-
-   // Output header for diagnostics output file
-    auto mid = m_input.size() > 1 ? std::string( '.' + std::to_string(m) ) : "";
-    tk::DiagWriter dw( g_inputdeck.get< tag::cmd, tag::io, tag::diag >() + mid,
-      g_inputdeck.get< tag::diagnostics, tag::format >(),
-      g_inputdeck.get< tag::diagnostics, tag::precision >() );
-
-    // Collect variables names for integral/diagnostics output
-    std::vector< std::string > var;
-    const auto scheme = g_inputdeck.get< tag::scheme >();
-    if ( scheme == ctr::SchemeType::ALECG ||
-         scheme == ctr::SchemeType::OversetFE )
-      for (const auto& eq : g_cgpde) varnames( eq, var );
-    else if ( scheme == ctr::SchemeType::DG ||
-              scheme == ctr::SchemeType::P0P1 ||
-              scheme == ctr::SchemeType::DGP1 ||
-              scheme == ctr::SchemeType::DGP2 ||
-              scheme == ctr::SchemeType::PDG )
-      for (const auto& eq : g_dgpde) varnames( eq, var );
-    else if (scheme == ctr::SchemeType::FV)
-      for (const auto& eq : g_fvpde) varnames( eq, var );
-    else Throw( "Diagnostics header not handled for discretization scheme" );
-
-    const tk::ctr::Error opt;
-    auto nv = var.size() / m_input.size();
-    std::vector< std::string > d;
-
-    // Add 'L2(var)' for all variables as those are always computed
-    const auto& l2name = opt.name( tk::ctr::ErrorType::L2 );
-    for (std::size_t i=0; i<nv; ++i) d.push_back( l2name + '(' + var[i] + ')' );
-
-    // Query user-requested diagnostics and augment diagnostics file header by
-    // 'err(var)', where 'err' is the error type  configured, and var is the
-    // variable computed, for all variables and all error types configured.
-    const auto& err = g_inputdeck.get< tag::diagnostics, tag::error >();
-    const auto& errname = opt.name( err );
-    for (std::size_t i=0; i<nv; ++i)
-      d.push_back( errname + '(' + var[i] + "-IC)" );
-
-    // Augment diagnostics variables by L2-norm of the residual and total energy
-    if ( scheme == ctr::SchemeType::ALECG ||
-         scheme == ctr::SchemeType::OversetFE ||
-         scheme == ctr::SchemeType::FV )
-    {
-      for (std::size_t i=0; i<nv; ++i) d.push_back( "L2(d" + var[i] + ')' );
-    }
-    d.push_back( "mE" );
-
-    // Write diagnostics header
-    dw.header( d );
-
-  }
-}
-
-void
-Transporter::doneInsertingGhosts(std::size_t meshid)
-// *****************************************************************************
-// Reduction target indicating all "ghosts" insertions are done
-//! \param[in] meshid Mesh id
-// *****************************************************************************
-{
-  m_scheme[meshid].ghosts().doneInserting();
-  m_scheme[meshid].ghosts().startCommSetup();
-}
-
-void
-Transporter::comfinal( std::size_t initial, std::size_t summeshid )
-// *****************************************************************************
-// Reduction target indicating that communication maps have been setup
-//! \param[in] initial Sum of contributions from all chares. If larger than
-//!    zero, we are during time stepping and if zero we are during setup.
-//! \param[in] summeshid Mesh id (summed accross the distributed mesh)
-// *****************************************************************************
-// [Discretization-specific communication maps]
-{
-  auto meshid = tk::cref_find( m_meshid, static_cast<std::size_t>(summeshid) );
-
-  if (initial > 0) {
-    m_scheme[meshid].bcast< Scheme::setup >();
-    // Turn on automatic load balancing
-    if (++m_ncom == m_nelem.size()) { // all worker arrays have finished
-      m_ncom = 0;
-      auto print = printer();
-      m_progWork.end( print );
-      tk::CProxy_LBSwitch::ckNew();
-      print.diag( "Load balancing on (if enabled in Charm++)" );
-    }
-  } else {
-    m_scheme[meshid].bcast< Scheme::lhs >();
-  }
-}
-// [Discretization-specific communication maps]
-
-void
-Transporter::totalvol( tk::real v, tk::real initial, tk::real summeshid )
-// *****************************************************************************
-// Reduction target summing total mesh volume across all workers
-//! \param[in] v Mesh volume summed across the distributed mesh
-//! \param[in] initial Sum of contributions from all chares. If larger than
-//!    zero, we are during setup, if zero, during time stepping.
-//! \param[in] summeshid Mesh id (summed accross the distributed mesh)
-// *****************************************************************************
-{
-  auto meshid = tk::cref_find( m_meshid, static_cast<std::size_t>(summeshid) );
-
-  m_meshvol[meshid] = v;
-
-  if (initial > 0.0)   // during initialization
-    m_scheme[meshid].disc().stat( v );
-  else                  // during ALE or AMR
-    m_scheme[meshid].bcast< Scheme::resized >();
-}
-
-void
-Transporter::minstat( tk::real d0, tk::real d1, tk::real d2, tk::real rmeshid )
-// *****************************************************************************
-// Reduction target yielding minimum mesh statistcs across all workers
-//! \param[in] d0 Minimum mesh statistics collected over all chares
-//! \param[in] d1 Minimum mesh statistics collected over all chares
-//! \param[in] d2 Minimum mesh statistics collected over all chares
-//! \param[in] rmeshid Mesh id as a real
-// *****************************************************************************
-{
-  auto meshid = static_cast<std::size_t>(rmeshid);
-
-  m_minstat[meshid][0] = d0;  // minimum edge length
-  m_minstat[meshid][1] = d1;  // minimum cell volume cubic root
-  m_minstat[meshid][2] = d2;  // minimum number of cells on chare
-
-  minstat_complete(meshid);
-}
-
-void
-Transporter::maxstat( tk::real d0, tk::real d1, tk::real d2, tk::real rmeshid )
-// *****************************************************************************
-// Reduction target yielding the maximum mesh statistics across all workers
-//! \param[in] d0 Maximum mesh statistics collected over all chares
-//! \param[in] d1 Maximum mesh statistics collected over all chares
-//! \param[in] d2 Maximum mesh statistics collected over all chares
-//! \param[in] rmeshid Mesh id as a real
-// *****************************************************************************
-{
-  auto meshid = static_cast<std::size_t>(rmeshid);
-
-  m_maxstat[meshid][0] = d0;  // maximum edge length
-  m_maxstat[meshid][1] = d1;  // maximum cell volume cubic root
-  m_maxstat[meshid][2] = d2;  // maximum number of cells on chare
-
-  maxstat_complete(meshid);
-}
-
-void
-Transporter::sumstat( tk::real d0, tk::real d1, tk::real d2, tk::real d3,
-                      tk::real d4, tk::real d5, tk::real summeshid )
-// *****************************************************************************
-// Reduction target yielding the sum mesh statistics across all workers
-//! \param[in] d0 Sum mesh statistics collected over all chares
-//! \param[in] d1 Sum mesh statistics collected over all chares
-//! \param[in] d2 Sum mesh statistics collected over all chares
-//! \param[in] d3 Sum mesh statistics collected over all chares
-//! \param[in] d4 Sum mesh statistics collected over all chares
-//! \param[in] d5 Sum mesh statistics collected over all chares
-//! \param[in] summeshid Mesh id (summed accross the distributed mesh)
-// *****************************************************************************
-{
-  auto meshid = tk::cref_find( m_meshid, static_cast<std::size_t>(summeshid) );
-
-  m_avgstat[meshid][0] = d1 / d0;      // average edge length
-  m_avgstat[meshid][1] = d3 / d2;      // average cell volume cubic root
-  m_avgstat[meshid][2] = d5 / d4;      // average number of cells per chare
-
-  sumstat_complete(meshid);
-}
-
-void
-Transporter::pdfstat( CkReductionMsg* msg )
-// *****************************************************************************
-// Reduction target yielding PDF of mesh statistics across all workers
-//! \param[in] msg Serialized PDF
-// *****************************************************************************
-{
-  std::size_t meshid;
-  std::vector< tk::UniPDF > pdf;
-
-  // Deserialize final PDF
-  PUP::fromMem creator( msg->getData() );
-  creator | meshid;<--- Uninitialized variable: meshid
-  creator | pdf;
-  delete msg;
-
-  auto id = std::to_string(meshid);<--- Uninitialized variable: meshid
-
-  // Create new PDF file (overwrite if exists)
-  tk::PDFWriter pdfe( "mesh_edge_pdf." + id + ".txt" );
-  // Output edgelength PDF
-  // cppcheck-suppress containerOutOfBounds
-  pdfe.writeTxt( pdf[0],
-                 tk::ctr::PDFInfo{ {"PDF"}, {}, {"edgelength"}, 0, 0.0 } );
-
-  // Create new PDF file (overwrite if exists)
-  tk::PDFWriter pdfv( "mesh_vol_pdf." + id + ".txt" );
-  // Output cell volume cubic root PDF
-  pdfv.writeTxt( pdf[1],<--- Access out of bounds
-                 tk::ctr::PDFInfo{ {"PDF"}, {}, {"V^{1/3}"}, 0, 0.0 } );
-
-  // Create new PDF file (overwrite if exists)
-  tk::PDFWriter pdfn( "mesh_ntet_pdf." + id + ".txt" );
-  // Output number of cells PDF
-  pdfn.writeTxt( pdf[2],<--- Access out of bounds
-                 tk::ctr::PDFInfo{ {"PDF"}, {}, {"ntets"}, 0, 0.0 } );
-
-  pdfstat_complete(meshid);
-}
-
-void
-Transporter::stat()
-// *****************************************************************************
-// Echo diagnostics on mesh statistics
-// *****************************************************************************
-{
-  auto print = printer();
-
-  if (++m_nstat == m_nelem.size()) {     // stats from all meshes have arrived
-    m_nstat = 0;
-    for (std::size_t i=0; i<m_nelem.size(); ++i) {
-      print.diag(
-        "Mesh " + std::to_string(i) +
-        " distribution statistics: min/max/avg(edgelength) = " +
-        std::to_string( m_minstat[i][0] ) + " / " +
-        std::to_string( m_maxstat[i][0] ) + " / " +
-        std::to_string( m_avgstat[i][0] ) + ", " +
-        "min/max/avg(V^{1/3}) = " +
-        std::to_string( m_minstat[i][1] ) + " / " +
-        std::to_string( m_maxstat[i][1] ) + " / " +
-        std::to_string( m_avgstat[i][1] ) + ", " +
-        "min/max/avg(ntets) = " +
-        std::to_string( static_cast<std::size_t>(m_minstat[i][2]) ) + " / " +
-        std::to_string( static_cast<std::size_t>(m_maxstat[i][2]) ) + " / " +
-        std::to_string( static_cast<std::size_t>(m_avgstat[i][2]) ) );
-    }
-
-    // Print out time integration header to screen
-    inthead( print );
-
-    m_progWork.start( print, "Preparing workers",
-      {{ m_nchare[0], m_nchare[0], m_nchare[0], m_nchare[0], m_nchare[0] }} );
-
-    // Create "derived-class" workers
-    for (std::size_t i=0; i<m_nelem.size(); ++i) m_sorter[i].createWorkers();
-  }
-}
-
-void
-Transporter::boxvol( tk::real* meshdata, int n )
-// *****************************************************************************
-// Reduction target computing total volume of IC mesh blocks and box
-//! \param[in] meshdata Vector containing volumes of all IC mesh blocks,
-//!   volume of IC box, and mesh id as a real summed across the distributed mesh
-//! \param[in] n Size of vector, automatically computed by Charm
-// *****************************************************************************
-{
-  Assert(n>=2, "mesh data size incorrect");
-
-  // extract summed mesh id from vector
-  tk::real summeshid = meshdata[n-1];
-  auto meshid = tk::cref_find( m_meshid, static_cast<std::size_t>(summeshid) );
-
-  // extract summed box volume from vector
-  tk::real v = meshdata[n-2];
-  if (v > 0.0) printer().diag( "Box IC volume: " + std::to_string(v) );
-
-  // extract summed mesh block volumes from the vector
-  std::vector< tk::real > blockvols;
-  for (std::size_t blid=0; blid<(static_cast<std::size_t>(n)-2); ++blid) {
-    blockvols.push_back(meshdata[blid]);
-    if (blockvols[blid] > 0.0)
-      printer().diag( "Mesh block " + std::to_string(blid) +
-        " discrete volume: " + std::to_string(blockvols[blid]) );
-  }
-
-  m_scheme[meshid].bcast< Scheme::box >( v, blockvols );
-}
-
-void
-Transporter::solutionTransferred()
-// *****************************************************************************
-// Reduction target broadcasting to Schemes after mesh transfer
-// *****************************************************************************
-{
-  if (++m_ntrans == m_nelem.size()) {    // all meshes have been loaded
-    m_ntrans = 0;
-    for (auto& m : m_scheme) m.bcast< Scheme::transferSol >();
-  }
-}
-
-void
-Transporter::minDtAcrossMeshes( tk::real* reducndata, [[maybe_unused]] int n )
-// *****************************************************************************
-// Reduction target that computes minimum timestep across all meshes
-//! \param[in] reducndata Vector containing minimum values of dt and mesh-moved
-//!   flags, collected across all meshes
-//! \param[in] n Size of vector, automatically computed by Charm
-// *****************************************************************************
-{
-  Assert(static_cast<std::size_t>(n-1) == m_nelem.size(),
-    "Incorrectly sized reduction vector");
-  m_dtmsh.push_back(reducndata[0]);
-
-  if (++m_ndtmsh == m_nelem.size()) {    // all meshes have been loaded
-    Assert(m_dtmsh.size() == m_nelem.size(), "Incorrect size of dtmsh");
-
-    // compute minimum dt across meshes
-    tk::real dt = std::numeric_limits< tk::real >::max();
-    for (auto idt : m_dtmsh) dt = std::min(dt, idt);
-
-    // clear dt-vector and counter
-    m_dtmsh.clear();
-    m_ndtmsh = 0;
-
-    // broadcast to advance time step
-    std::size_t ic(0);
-    for (auto& m : m_scheme) {
-      m.bcast< Scheme::advance >( dt, reducndata[ic+1] );
-      ++ic;
-    }
-  }
-}
-
-void
-Transporter::inthead( const InciterPrint& print )
-// *****************************************************************************
-// Print out time integration header to screen
-//! \param[in] print Pretty printer object to use for printing
-// *****************************************************************************
-{
-  auto refined = g_inputdeck.get< tag::field_output, tag::refined >();
-  const auto scheme = g_inputdeck.get< tag::scheme >();
-  if (refined && scheme == ctr::SchemeType::DG) {
-    printer() << "\n>>> WARNING: Ignoring refined field output for DG(P0)\n\n";
-    refined = false;
-  }
-
-  print.inthead( "Time integration", "Navier-Stokes solver",
-  "Legend: it - iteration count\n"
-  "         t - physics time\n"
-  "        dt - physics time step size\n"
-  "       ETE - estimated wall-clock time elapsed (h:m:s)\n"
-  "       ETA - estimated wall-clock time for accomplishment (h:m:s)\n"
-  "       EGT - estimated grind wall-clock time (ms/timestep)\n"
-  "       flg - status flags, legend:\n"
-  "             f - " + std::string(refined ? "refined " : "")
-                      + "field (volume and surface)\n"
-  "             d - diagnostics\n"
-  "             t - physics time history\n"
-  "             h - h-refinement\n"
-  "             l - load balancing\n"
-  "             r - checkpoint\n"
-  "             a - ALE mesh velocity linear solver did not converge\n",
-  "\n      it             t            dt        ETE        ETA        EGT  flg\n"
-    " -------------------------------------------------------------------------\n" );
-}
-
-void
-Transporter::diagnostics( CkReductionMsg* msg )
-// *****************************************************************************
-// Reduction target optionally collecting diagnostics, e.g., residuals
-//! \param[in] msg Serialized diagnostics vector aggregated across all PEs
-//! \note Only used for nodal schemes
-// *****************************************************************************
-{
-  std::size_t meshid, ncomp;
-  std::vector< std::vector< tk::real > > d;
-
-  // Deserialize diagnostics vector
-  PUP::fromMem creator( msg->getData() );
-  creator | meshid;<--- Uninitialized variable: meshid
-  creator | ncomp;<--- Uninitialized variable: ncomp
-  creator | d;
-  delete msg;
-
-  auto id = std::to_string(meshid);<--- Uninitialized variable: meshid<--- Variable 'id' is assigned a value that is never used.
-
-  Assert( ncomp > 0, "Number of scalar components must be positive");<--- Uninitialized variable: ncomp
-  Assert( d.size() == NUMDIAG, "Diagnostics vector size mismatch" );
-
-  for (std::size_t i=0; i<d.size(); ++i)<--- Unsigned less than zero
-     Assert( d[i].size() == ncomp, "Size mismatch at final stage of "
-             "diagnostics aggregation for mesh " + id );
-
-  // Allocate storage for those diagnostics that are always computed
-  std::vector< tk::real > diag( ncomp, 0.0 );
-
-  // Finish computing diagnostics
-  for (std::size_t i=0; i<d[L2SOL].size(); ++i)
-    diag[i] = sqrt( d[L2SOL][i] / m_meshvol[meshid] );<--- Uninitialized variable: meshid
-  
-  // Query user-requested error types to output
-  const auto& error = g_inputdeck.get< tag::diagnostics, tag::error >();
-
-  decltype(ncomp) n = 0;<--- Variable 'n' is assigned a value that is never used.
-  n += ncomp;<--- Variable 'n' is assigned a value that is never used.
-  if (error == tk::ctr::ErrorType::L2) {
-   // Finish computing the L2 norm of the numerical - analytical solution
-   for (std::size_t i=0; i<d[L2ERR].size(); ++i)
-     diag.push_back( sqrt( d[L2ERR][i] / m_meshvol[meshid] ) );<--- Uninitialized variable: meshid
-  } else if (error == tk::ctr::ErrorType::LINF) {
-    // Finish computing the Linf norm of the numerical - analytical solution
-    for (std::size_t i=0; i<d[LINFERR].size(); ++i)
-      diag.push_back( d[LINFERR][i] );
-  }
-
-  // Finish computing the L2 norm of the residual and append
-  const auto scheme = g_inputdeck.get< tag::scheme >();
-  std::vector< tk::real > l2res( d[L2RES].size(), 0.0 );
-  if (scheme == ctr::SchemeType::ALECG || scheme == ctr::SchemeType::OversetFE) {
-    for (std::size_t i=0; i<d[L2RES].size(); ++i) {
-      l2res[i] = std::sqrt( d[L2RES][i] / m_meshvol[meshid] );<--- Uninitialized variable: meshid
-      diag.push_back( l2res[i] );
-    }
-  }
-  else if (scheme == ctr::SchemeType::FV) {
-    for (std::size_t i=0; i<d[L2RES].size(); ++i) {
-      l2res[i] = std::sqrt( d[L2RES][i] );
-      diag.push_back( l2res[i] );
-    }
-  }
-
-  // Append total energy
-  diag.push_back( d[TOTALSOL][0] );
-
-  // Append diagnostics file at selected times
-  auto filename = g_inputdeck.get< tag::cmd, tag::io, tag::diag >();
-  if (m_nelem.size() > 1) filename += '.' + id;
-  tk::DiagWriter dw( filename,
-    g_inputdeck.get< tag::diagnostics, tag::format >(),
-    g_inputdeck.get< tag::diagnostics, tag::precision >(),
-    std::ios_base::app );
-  dw.diag( static_cast<uint64_t>(d[ITER][0]), d[TIME][0], d[DT][0], diag );
-
-  // Continue time step
-  m_scheme[meshid].bcast< Scheme::refine >( l2res );<--- Uninitialized variable: meshid
-}
-
-void
-Transporter::resume()
-// *****************************************************************************
-// Resume execution from checkpoint/restart files
-//! \details This is invoked by Charm++ after the checkpoint is done, as well as
-//!   when the restart (returning from a checkpoint) is complete
-// *****************************************************************************
-{
-  if (std::any_of(begin(m_finished), end(m_finished), [](auto f){return !f;})) {
-    // If just restarted from a checkpoint, Main( CkMigrateMessage* msg ) has
-    // increased nrestart in g_inputdeck, but only on PE 0, so broadcast.
-    auto nrestart = g_inputdeck.get< tag::cmd, tag::io, tag::nrestart >();
-    for (std::size_t i=0; i<m_nelem.size(); ++i)
-      m_scheme[i].bcast< Scheme::evalLB >( nrestart );
-  } else
-    mainProxy.finalize();
-}
-
-void
-Transporter::checkpoint( std::size_t finished, std::size_t meshid )
-// *****************************************************************************
-// Save checkpoint/restart files
-//! \param[in] finished Nonzero if finished with time stepping
-//! \param[in] meshid Mesh id
-// *****************************************************************************
-{
-  m_finished[meshid] = finished;
-
-  if (++m_nchk == m_nelem.size()) { // all worker arrays have checkpointed
-    m_nchk = 0;
-    if (not g_inputdeck.get< tag::cmd, tag::benchmark >()) {
-      const auto& restart = g_inputdeck.get< tag::cmd, tag::io, tag::restart >();
-      CkCallback res( CkIndex_Transporter::resume(), thisProxy );
-      CkStartCheckpoint( restart.c_str(), res );
-    } else {
-      resume();
-    }
-  }
-}
-
-void
-Transporter::finish( std::size_t meshid )
-// *****************************************************************************
-// Normal finish of time stepping
-//! \param[in] meshid Mesh id
-// *****************************************************************************
-{
-  checkpoint( /* finished = */ 1, meshid );
-}
-
-#include "NoWarning/transporter.def.h"
+  const auto& ic = g_inputdeck.get< tag::ic >();
+
+  const auto& bgmatidic = ic.get< tag::materialid >();
+  nfo.emplace_back( "IC background material id", parameter( bgmatidic ) );
+
+  const auto& icbox = ic.get< tag::box >();
+  if (!icbox.empty()) {
+    std::size_t bcnt = 0;
+    for (const auto& b : icbox) {   // for all boxes configured for this eq
+      std::vector< tk::real > box
+        { b.get< tag::xmin >(), b.get< tag::xmax >(),
+          b.get< tag::ymin >(), b.get< tag::ymax >(),
+          b.get< tag::zmin >(), b.get< tag::zmax >() };
+
+      std::string boxname = "IC box " + parameter(bcnt);
+      nfo.emplace_back( boxname, parameters( box ) );
+
+      nfo.emplace_back( boxname + " orientation",
+        parameters(b.get< tag::orientation >()) );
+
+      nfo.emplace_back( boxname + " material id",
+                        parameter( b.get< tag::materialid >() ) );
+
+      const auto& initiate = b.get< tag::initiate >();
+      auto opt = ctr::Initiate();
+      nfo.emplace_back( boxname + ' ' + opt.group(), opt.name(initiate) );
+
+      ++bcnt;
+    }
+  }
+
+  const auto& icblock = ic.get< tag::meshblock >();
+  for (const auto& b : icblock) {   // for all blocks configured for eq
+    std::string blockname = "IC mesh block " +
+      parameter(b.get< tag::blockid >());
+
+    nfo.emplace_back( blockname + " material id",
+                      parameter( b.get< tag::materialid >() ) );
+    const auto& initiate = b.get< tag::initiate >();
+    auto opt = ctr::Initiate();
+    nfo.emplace_back( blockname + ' ' + opt.group(), opt.name(initiate) );
+  }
+
+  return nfo;
+}
+
+}  // inciter::
 
diff --git a/Release/cppcheck/6.html b/Release/cppcheck/6.html index 6183e8058fd6..853d766e5051 100644 --- a/Release/cppcheck/6.html +++ b/Release/cppcheck/6.html @@ -152,12 +152,12 @@
  1
@@ -280,127 +280,547 @@ 

Cppcheck report - [

// *****************************************************************************
+121
+122
+123
+124
+125
+126
+127
+128
+129
+130
+131
+132
+133
+134
+135
+136
+137
+138
+139
+140
+141
+142
+143
+144
+145
+146
+147
+148
+149
+150
+151
+152
+153
+154
+155
+156
+157
+158
+159
+160
+161
+162
+163
+164
+165
+166
+167
+168
+169
+170
+171
+172
+173
+174
+175
+176
+177
+178
+179
+180
+181
+182
+183
+184
+185
+186
+187
+188
+189
+190
+191
+192
+193
+194
+195
+196
+197
+198
+199
+200
+201
+202
+203
+204
+205
+206
+207
+208
+209
+210
+211
+212
+213
+214
+215
+216
+217
+218
+219
+220
+221
+222
+223
+224
+225
+226
+227
+228
+229
+230
+231
+232
+233
+234
+235
+236
+237
+238
+239
+240
+241
+242
+243
+244
+245
+246
+247
+248
+249
+250
+251
+252
+253
+254
+255
+256
+257
+258
+259
+260
+261
+262
+263
+264
+265
+266
+267
+268
+269
+270
+271
+272
+273
+274
+275
+276
+277
+278
+279
+280
+281
+282
+283
+284
+285
+286
+287
+288
+289
+290
+291
+292
+293
+294
+295
+296
+297
+298
+299
+300
+301
+302
+303
+304
+305
+306
+307
+308
+309
+310
+311
+312
+313
+314
+315
+316
+317
+318
+319
+320
+321
+322
+323
+324
+325
+326
+327
+328
+329
+330
+331
// *****************************************************************************
 /*!
-  \file      src/IO/MeshWriter.hpp
+  \file      src/Base/ContainerUtil.hpp
   \copyright 2012-2015 J. Bakosi,
              2016-2018 Los Alamos National Security, LLC.,
              2019-2021 Triad National Security, LLC.
              All rights reserved. See the LICENSE file for details.
-  \brief     Charm++ group for outputing mesh data to file
-  \details   Charm++ group declaration used to output data associated to
-     unstructured meshes to file(s). Charm++ chares (work units) send mesh and
-     field data associated to mesh entities to the MeshWriter class defined here
-     to write the data to file(s).
-*/
-// *****************************************************************************
-#ifndef MeshWriter_h
-#define MeshWriter_h
-
-#include <vector>
-#include <string>
-#include <tuple>
-#include <map>
-
-#include "Types.hpp"
-#include "Options/FieldFile.hpp"
-#include "Centering.hpp"
-#include "UnsMesh.hpp"
-
-#include "NoWarning/meshwriter.decl.h"
-
-namespace tk {
-
-//! Charm++ group used to output particle data to file in parallel
-class MeshWriter : public CBase_MeshWriter {
-
-  public:
-    //! Constructor: set some defaults that stay constant at all times
-    MeshWriter( ctr::FieldFileType filetype,
-                Centering bnd_centering,
-                bool benchmark,
-                std::size_t nmesh );
+  \brief     Various STL container utilities
+  \details   Various STL container utilities.
+*/
+// *****************************************************************************
+#ifndef ContainerUtil_h
+#define ContainerUtil_h
+
+#include <vector>
+#include <map>
+#include <set>
+#include <algorithm>
+#include <iterator>
+#include <unordered_set>
+#include <unordered_map>
+#include <type_traits>
+#include <sstream>
+
+#include "Exception.hpp"
+
+namespace tk {
+
+//! Make elements of container unique (in-place, overwriting source container)
+//! \param[in,out] c Container
+template< class Container >
+void
+unique( Container& c )
+{
+  std::sort( begin(c), end(c) );
+  auto it = std::unique( begin(c), end(c) );
+  auto d = std::distance( begin(c), it );
+  Assert( d >= 0, "Distance must be non-negative in tk::unique()" );<--- Unsigned positive
+  c.resize( static_cast< std::size_t >( d ) );
+}
 
-    #if defined(__clang__)
-      #pragma clang diagnostic push
-      #pragma clang diagnostic ignored "-Wundefined-func-template"
-    #endif
-    //! Migrate constructor
-    explicit MeshWriter( CkMigrateMessage* m ) : CBase_MeshWriter( m ) {}<--- Member variable 'MeshWriter::m_filetype' is not initialized in the constructor.<--- Member variable 'MeshWriter::m_benchmark' is not initialized in the constructor.<--- Member variable 'MeshWriter::m_nmesh' is not initialized in the constructor.
-    #if defined(__clang__)
-      #pragma clang diagnostic pop
-    #endif
-
-    //! Set the total number of chares
-    void nchare( std::size_t meshid, int n );
-
-    //! Output unstructured mesh into file
-    void write( std::size_t meshid,
-                bool meshoutput,
-                bool fieldoutput,
-                uint64_t itr,
-                uint64_t itf,
-                tk::real time,
-                int chareid,
-                const std::string& basefilename,
-                const std::vector< std::size_t >& inpoel,
-                const UnsMesh::Coords& coord,
-                const std::map< int, std::vector< std::size_t > >& bface,
-                const std::map< int, std::vector< std::size_t > >& bnode,
-                const std::vector< std::size_t >& triinpoel,
-                const std::vector< std::string >& elemfieldnames,
-                const std::vector< std::string >& nodefieldnames,
-                const std::vector< std::string >& elemsurfnames,
-                const std::vector< std::string >& nodesurfnames,
-                const std::vector< std::vector< tk::real > >& elemfields,
-                const std::vector< std::vector< tk::real > >& nodefields,
-                const std::vector< std::vector< tk::real > >& elemsurfs,
-                const std::vector< std::vector< tk::real > >& nodesurfs,
-                const std::set< int >& outsets,
-                CkCallback c );
-
-    /** @name Charm++ pack/unpack serializer member functions */
-    ///@{
-    //! \brief Pack/Unpack serialize member function
-    //! \param[in,out] p Charm++'s PUP::er serializer object reference
-    //! \note This is a Charm++ group, pup() is thus only for
-    //!    checkpoint/restart.
-    void pup( PUP::er &p ) override {
-      p | m_filetype;
-      p | m_bndCentering;
-      p | m_benchmark;
-      p | m_nmesh;
-      p | m_nchare;
-    }
-    //! \brief Pack/Unpack serialize operator|
-    //! \param[in,out] p Charm++'s PUP::er serializer object reference
-    //! \param[in,out] m MeshWriter object reference
-    friend void operator|( PUP::er& p, MeshWriter& m ) { m.pup(p); }
-    //@}
-
-  private:
-    //! Output file format type
-    ctr::FieldFileType m_filetype;
-    //! Centering to identify what boundary data to write.
-    Centering m_bndCentering;
-    //! True if benchmark mode
-    bool m_benchmark;
-    //! Total number of meshes
-    std::size_t m_nmesh;
-    //! Total number chares across the whole problem (one per mesh)
-    std::vector< int > m_nchare;
-
-    //! Compute filename
-    std::string filename( const std::string& basefilename,
-                          std::size_t meshid,
-                          uint64_t itr,
-                          int chareid,
-                          int surfid = 0 ) const;
-};
-
-} // tk::
-
-#endif // MeshWriter_h
+//! Make elements of container unique (on a copy, leaving the source as is)
+//! \param[in] src Container
+//! \return Container containing only unique elements compared to src
+template< class Container >
+Container
+uniquecopy( const Container& src )
+{
+  auto c = src;
+  unique( c );
+  return c;
+}
+
+//! \brief Find and return a constant reference to value for key in container
+//!   that provides a find() member function with error handling
+//! \param[in] map Map associating values to keys
+//! \param[in] key Key to search for
+//! \return A constant reference to the value associated to the key in map
+//! \note If key is not found an exception is thrown.
+template< typename Container >
+auto cref_find( const Container& map, const typename Container::key_type& key )
+noexcept(ndebug)
+  -> const typename Container::mapped_type&
+{
+  const auto it = map.find( key );
+  Assert( it != end(map), "Can't find key" );<--- Exception thrown in function declared not to throw exceptions.
+  return it->second;
+}
+
+//! \brief Find and return a reference to value for key in a container that
+//!   provides a find() member function with error handling
+//! \param[in] map Map associating values to keys
+//! \param[in] key Key to search for
+//! \return A reference to the value associated to the key in map
+//! \note If key is not found an exception is thrown.
+template< typename Container >
+auto ref_find( const Container& map, const typename Container::key_type& key )
+noexcept(ndebug)
+  -> typename Container::mapped_type&
+{
+  return const_cast< typename Container::mapped_type& >( cref_find(map,key) );<--- Exception thrown in function declared not to throw exceptions.
+}
+
+//! \brief Return minimum and maximum values of a vector
+//! \param[in] vec Vector whose extents to compute
+//! \return Array of two values with the minimum and maximum values
+//! \note This function should not be called with heavy T types, as the a copy
+//!   of a std::array< T, 2 > is created and returned.
+template< typename T >
+std::array< T, 2 >
+extents( const std::vector< T >& vec )
+{
+  auto x = std::minmax_element( begin(vec), end(vec) );
+  return {{ *x.first, *x.second }};
+}
+
+//! \brief Find and return minimum and maximum values in associative container
+//! \param[in] map Map whose extents of values to find 
+//! \return Array of two values with the minimum and maximum values in the map
+//! \note This function should not be called with heavy Value types, as the a
+//!   copy of a std::array< Value, 2 > is created and returned.
+template< typename Container >
+auto extents( const Container& map )
+  -> std::array< typename Container::mapped_type, 2 >
+{
+  auto x = std::minmax_element( begin(map), end(map),
+             []( const auto& a, const auto& b )
+             { return a.second < b.second; } );
+  return {{ x.first->second, x.second->second }};
+}
+
+//! Add all elements of an array to those of another one
+//! \param[in,out] dst Destination array, i.e., left-hand side of a1 += a2
+//! \param[in] src Source array, i.e., righ-hand side of a1 += a2
+//! \return Destination containing a1[0] += a2[0], a1[1] += a2[1], ...
+template< class T, std::size_t N >
+std::array< T, N >&
+operator+=( std::array< T, N >& dst, const std::array< T, N >& src ) {
+  std::transform( src.cbegin(), src.cend(), dst.begin(), dst.begin(),
+                  []( const T& s, T& d ){ return d += s; } );
+  return dst;
+}
+
+//! Add all elements of a vector to those of another one
+//! \param[in,out] dst Destination vector, i.e., left-hand side of v1 += v2
+//! \param[in] src Source vector, i.e., righ-hand side of v1 += v2
+//! \return Destination containing v1[0] += v2[0], v1[1] += v2[1], ...
+//! \details If src.size() > dst.size() will grow dst to that of src.size()
+//!   padding with zeros.
+//! \note Will throw exception in DEBUG if src is empty (to warn on no-op), and
+//!   if src.size() < dst.size() (to warn on loosing data).
+template< class T, class Allocator >
+std::vector< T, Allocator >&
+operator+=( std::vector< T, Allocator >& dst,
+            const std::vector< T, Allocator >& src )
+{
+  Assert( !src.empty(), "src empty in std::vector<T,Allocator>::operator+=()" );
+  Assert( src.size() >= dst.size(), "src.size() < dst.size() would loose data "
+          "in std::vector<T,Allocator>::operator+=()" );
+  dst.resize( src.size() );
+  std::transform( src.cbegin(), src.cend(), dst.begin(), dst.begin(),
+                  []( const T& s, T& d ){ return d += s; } );
+  return dst;
+}
+
+//! Divide all elements of a vector with those of another one
+//! \param[in,out] dst Destination vector, i.e., left-hand side of v1 /= v2
+//! \param[in] src Source vector, i.e., righ-hand side of v1 /= v2
+//! \return Destination containing v1[0] /= v2[0], v1[1] /= v2[1], ...
+//! \details If src.size() > dst.size() will grow dst to that of src.size()
+//!   padding with zeros.
+//! \note Will throw exception in DEBUG if src is empty (to warn on no-op), and
+//!   if src.size() < dst.size() (to warn on loosing data).
+template< class T, class Allocator >
+std::vector< T, Allocator >&
+operator/=( std::vector< T, Allocator >& dst,
+            const std::vector< T, Allocator >& src )
+{
+  Assert( !src.empty(), "src empty in std::vector<T,Allocator>::operator/=()" );
+  Assert( src.size() >= dst.size(), "src.size() < dst.size() would loose data "
+          "in std::vector<T,Allocator>::operator/=()" );
+  dst.resize( src.size() );
+  std::transform( src.cbegin(), src.cend(), dst.begin(), dst.begin(),
+                  []( const T& s, T& d ){ return d /= s; } );
+  return dst;
+}
+
+//! Test if all keys of two associative containers are equal
+//! \param[in] a 1st container to compare
+//! \param[in] b 2nd container to compare
+//! \return True if the containers have the same size and all keys (and only the
+//!   keys) of the two containers are equal
+//! \note It is an error to call this function with unequal-size containers,
+//!   triggering an exception in DEBUG mode.
+//! \note Operator != is used to compare the container keys.
+template< class C1, class C2 >
+bool keyEqual( const C1& a, const C2& b ) {
+  Assert( a.size() == b.size(), "Size mismatch comparing containers" );
+  std::set< typename C1::key_type > sorted_keys_of_a;
+  for (const auto& c : a) sorted_keys_of_a.insert( c.first );
+  std::set< typename C2::key_type > sorted_keys_of_b;
+  for (const auto& c : b) sorted_keys_of_b.insert( c.first );
+  return sorted_keys_of_a == sorted_keys_of_b;
+}
+
+//! Compute the sum of the sizes of a container of containers
+//! \param[in] c Container of containers
+//! \return Sum of the sizes of the containers of the container
+template< class Container >
+std::size_t sumsize( const Container& c ) {
+  std::size_t sum = 0;
+  // cppcheck-suppress useStlAlgorithm
+  for (const auto& s : c) sum += s.size();
+  return sum;
+}
+
+//! Compute the number of unique values in a container of containers
+//! \param[in] c Container of containers
+//! \return Number of unique values in a container of containers
+template< class Container >
+std::size_t numunique( const Container& c ) {
+  using value_type = typename Container::value_type::value_type;
+  static_assert( std::is_integral<value_type>::value,
+    "Container::value_type::value_type must be an integral type." );
+  std::unordered_set< value_type > u;
+  for (const auto& r : c) u.insert( begin(r), end(r) );
+  return u.size();
+}
+
+//! Compute the sum of the sizes of the values of an associative container
+//! \tparam Map Container of containers type
+//! \param[in] c Container of containers
+//! \return Sum of the sizes of the values of the associative container
+template< class Map >
+std::size_t sumvalsize( const Map& c ) {
+  std::size_t sum = 0;
+  // cppcheck-suppress useStlAlgorithm
+  for (const auto& s : c) sum += s.second.size();
+  return sum;
+}
+
+//! Free memory of a container
+//! \param[in] c Container defining a swap() member function
+//! \details See http://stackoverflow.com/a/10465032 as to why this is done with
+//!   the swap() member function of the container.
+//! \see Specializations of std::swap are documented at
+//!   http://en.cppreference.com/w/cpp/algorithm/swap
+template< class Container >
+void destroy( Container& c ) {
+  typename std::remove_reference< decltype(c) >::type().swap( c );
+}
+
+//! Remove items from container based on predicate
+//! \tparam Container Type of container to remove from
+//! \tparam Predicate Type for functor defining the predicate
+//! \param items Container object to remove from
+//! \param predicate Predicate object instance to use
+template< typename Container, typename Predicate >
+void erase_if( Container& items, const Predicate& predicate ) {
+  for ( auto it = items.begin(); it != items.end(); ) {
+    if ( predicate(*it) ) it = items.erase(it);
+    else ++it;
+  }
+}
+
+//! Concatenate vectors of T
+//! \tparam T Vector value type
+//! \param[in,out] src Source vector (moved from)
+//! \param[in,out] dst Destination vector
+template< class T >
+void concat( std::vector< T >&& src, std::vector< T >& dst )
+{
+  if (dst.empty())
+    dst = std::move(src);
+  else {
+    dst.reserve( dst.size() + src.size() );
+    std::move( std::begin(src), std::end(src), std::back_inserter(dst) );
+    src.clear();
+  }
+}
+
+//! Overwrite vectors of pair< bool, tk::real >
+//! \tparam T Vector value type
+//! \param[in,out] src Source vector (moved from)
+//! \param[in,out] dst Destination vector
+template< class T >
+void concat( std::vector< std::pair< bool, T > >&& src,
+             std::vector< std::pair< bool, T > >& dst )
+{
+  dst = std::move(src);
+}
+
+//! Concatenate unordered sets
+//! \tparam Key Set key
+//! \tparam Hash Set hasher
+//! \tparam Eq Set equality operator
+//! \param[in,out] src Source set (moved from)
+//! \param[in,out] dst Destination set
+template< class Key,
+          class Hash = std::hash< Key >,
+          class Eq = std::equal_to< Key > >
+void concat( std::unordered_set< Key, Hash,Eq >&& src,
+             std::unordered_set< Key, Hash, Eq >& dst )
+{
+  if (dst.empty())
+    dst = std::move(src);
+  else {
+    dst.reserve( dst.size() + src.size() );
+    std::move( std::begin(src), std::end(src), std::inserter(dst,end(dst)) );
+    src.clear();
+  }
+}
+
+//! Operator << for writing value_type of a standard map to output streams
+//! \param[in,out] os Output stream to write to
+//! \param[in] v value_type entry of a map
+//! \return Updated output stream
+template< class Key, class Value >
+std::ostream&
+operator<< ( std::ostream& os, const std::pair< const Key, Value  >& v ) {
+  os << v.first << ':' << v.second;
+  return os;
+}
+
+//! \brief Convert and return value as string
+//! \tparam T Value type for input
+//! \param[in] v Value for input to return as a string
+//! \return String for input value
+template< typename T >
+std::string parameter( const T& v ) {
+  std::stringstream s;
+  s << v;
+  return s.str();
+}
+
+//! \brief Convert and return values from container as string
+//! \tparam V Container range for works on
+//! \param[in] v Container whose components to return as a string
+//! \return Concatenated string of values read from a container
+template< typename V >
+std::string parameters( const V& v ) {
+  std::stringstream s;
+  s << "{ ";
+  for (auto p : v) s << p << ' ';
+  s << "}";
+  return s.str();
+}
+
+} // tk::
+
+#endif // ContainerUtil_h
 
diff --git a/Release/cppcheck/60.html b/Release/cppcheck/60.html index 006373480ab3..f37eea4614fe 100644 --- a/Release/cppcheck/60.html +++ b/Release/cppcheck/60.html @@ -152,341 +152,2119 @@
- - - + + - - + + @@ -238,24 +238,24 @@ - + - + - + - + @@ -298,64 +298,64 @@ - + - + - - + + - + - + - - + + - + - + - - + + - + - + - - + + - + - + - - + + diff --git a/Release/test_coverage/Base/index-sort-l.html b/Release/test_coverage/Base/index-sort-l.html index 2e7f0fe9cd78..51d849cc7620 100644 --- a/Release/test_coverage/Base/index-sort-l.html +++ b/Release/test_coverage/Base/index-sort-l.html @@ -27,13 +27,13 @@ - + - + - + @@ -49,9 +49,9 @@ - - - + + +
  1
-  2
-  3
-  4
-  5
-  6
-  7
-  8
-  9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
- 37
- 38
- 39
- 40
- 41
- 42
- 43
- 44
- 45
- 46
- 47
- 48
- 49
- 50
- 51
- 52
- 53
- 54
- 55
- 56
- 57
- 58
- 59
- 60
- 61
- 62
- 63
- 64
- 65
- 66
- 67
- 68
- 69
- 70
- 71
- 72
- 73
- 74
- 75
- 76
- 77
- 78
- 79
- 80
- 81
- 82
- 83
- 84
- 85
- 86
- 87
- 88
- 89
- 90
- 91
- 92
- 93
- 94
- 95
- 96
- 97
- 98
- 99
-100
-101
-102
-103
-104
-105
-106
-107
-108
-109
-110
-111
-112
-113
-114
-115
-116
-117
-118
-119
-120
-121
-122
-123
-124
-125
-126
-127
-128
-129
-130
-131
-132
-133
-134
-135
-136
-137
-138
-139
-140
-141
-142
-143
-144
-145
-146
-147
-148
-149
-150
-151
-152
-153
-154
-155
-156
-157
-158
-159
-160
-161
-162
-163
-164
// *****************************************************************************
+
   1
+   2
+   3
+   4
+   5
+   6
+   7
+   8
+   9
+  10
+  11
+  12
+  13
+  14
+  15
+  16
+  17
+  18
+  19
+  20
+  21
+  22
+  23
+  24
+  25
+  26
+  27
+  28
+  29
+  30
+  31
+  32
+  33
+  34
+  35
+  36
+  37
+  38
+  39
+  40
+  41
+  42
+  43
+  44
+  45
+  46
+  47
+  48
+  49
+  50
+  51
+  52
+  53
+  54
+  55
+  56
+  57
+  58
+  59
+  60
+  61
+  62
+  63
+  64
+  65
+  66
+  67
+  68
+  69
+  70
+  71
+  72
+  73
+  74
+  75
+  76
+  77
+  78
+  79
+  80
+  81
+  82
+  83
+  84
+  85
+  86
+  87
+  88
+  89
+  90
+  91
+  92
+  93
+  94
+  95
+  96
+  97
+  98
+  99
+ 100
+ 101
+ 102
+ 103
+ 104
+ 105
+ 106
+ 107
+ 108
+ 109
+ 110
+ 111
+ 112
+ 113
+ 114
+ 115
+ 116
+ 117
+ 118
+ 119
+ 120
+ 121
+ 122
+ 123
+ 124
+ 125
+ 126
+ 127
+ 128
+ 129
+ 130
+ 131
+ 132
+ 133
+ 134
+ 135
+ 136
+ 137
+ 138
+ 139
+ 140
+ 141
+ 142
+ 143
+ 144
+ 145
+ 146
+ 147
+ 148
+ 149
+ 150
+ 151
+ 152
+ 153
+ 154
+ 155
+ 156
+ 157
+ 158
+ 159
+ 160
+ 161
+ 162
+ 163
+ 164
+ 165
+ 166
+ 167
+ 168
+ 169
+ 170
+ 171
+ 172
+ 173
+ 174
+ 175
+ 176
+ 177
+ 178
+ 179
+ 180
+ 181
+ 182
+ 183
+ 184
+ 185
+ 186
+ 187
+ 188
+ 189
+ 190
+ 191
+ 192
+ 193
+ 194
+ 195
+ 196
+ 197
+ 198
+ 199
+ 200
+ 201
+ 202
+ 203
+ 204
+ 205
+ 206
+ 207
+ 208
+ 209
+ 210
+ 211
+ 212
+ 213
+ 214
+ 215
+ 216
+ 217
+ 218
+ 219
+ 220
+ 221
+ 222
+ 223
+ 224
+ 225
+ 226
+ 227
+ 228
+ 229
+ 230
+ 231
+ 232
+ 233
+ 234
+ 235
+ 236
+ 237
+ 238
+ 239
+ 240
+ 241
+ 242
+ 243
+ 244
+ 245
+ 246
+ 247
+ 248
+ 249
+ 250
+ 251
+ 252
+ 253
+ 254
+ 255
+ 256
+ 257
+ 258
+ 259
+ 260
+ 261
+ 262
+ 263
+ 264
+ 265
+ 266
+ 267
+ 268
+ 269
+ 270
+ 271
+ 272
+ 273
+ 274
+ 275
+ 276
+ 277
+ 278
+ 279
+ 280
+ 281
+ 282
+ 283
+ 284
+ 285
+ 286
+ 287
+ 288
+ 289
+ 290
+ 291
+ 292
+ 293
+ 294
+ 295
+ 296
+ 297
+ 298
+ 299
+ 300
+ 301
+ 302
+ 303
+ 304
+ 305
+ 306
+ 307
+ 308
+ 309
+ 310
+ 311
+ 312
+ 313
+ 314
+ 315
+ 316
+ 317
+ 318
+ 319
+ 320
+ 321
+ 322
+ 323
+ 324
+ 325
+ 326
+ 327
+ 328
+ 329
+ 330
+ 331
+ 332
+ 333
+ 334
+ 335
+ 336
+ 337
+ 338
+ 339
+ 340
+ 341
+ 342
+ 343
+ 344
+ 345
+ 346
+ 347
+ 348
+ 349
+ 350
+ 351
+ 352
+ 353
+ 354
+ 355
+ 356
+ 357
+ 358
+ 359
+ 360
+ 361
+ 362
+ 363
+ 364
+ 365
+ 366
+ 367
+ 368
+ 369
+ 370
+ 371
+ 372
+ 373
+ 374
+ 375
+ 376
+ 377
+ 378
+ 379
+ 380
+ 381
+ 382
+ 383
+ 384
+ 385
+ 386
+ 387
+ 388
+ 389
+ 390
+ 391
+ 392
+ 393
+ 394
+ 395
+ 396
+ 397
+ 398
+ 399
+ 400
+ 401
+ 402
+ 403
+ 404
+ 405
+ 406
+ 407
+ 408
+ 409
+ 410
+ 411
+ 412
+ 413
+ 414
+ 415
+ 416
+ 417
+ 418
+ 419
+ 420
+ 421
+ 422
+ 423
+ 424
+ 425
+ 426
+ 427
+ 428
+ 429
+ 430
+ 431
+ 432
+ 433
+ 434
+ 435
+ 436
+ 437
+ 438
+ 439
+ 440
+ 441
+ 442
+ 443
+ 444
+ 445
+ 446
+ 447
+ 448
+ 449
+ 450
+ 451
+ 452
+ 453
+ 454
+ 455
+ 456
+ 457
+ 458
+ 459
+ 460
+ 461
+ 462
+ 463
+ 464
+ 465
+ 466
+ 467
+ 468
+ 469
+ 470
+ 471
+ 472
+ 473
+ 474
+ 475
+ 476
+ 477
+ 478
+ 479
+ 480
+ 481
+ 482
+ 483
+ 484
+ 485
+ 486
+ 487
+ 488
+ 489
+ 490
+ 491
+ 492
+ 493
+ 494
+ 495
+ 496
+ 497
+ 498
+ 499
+ 500
+ 501
+ 502
+ 503
+ 504
+ 505
+ 506
+ 507
+ 508
+ 509
+ 510
+ 511
+ 512
+ 513
+ 514
+ 515
+ 516
+ 517
+ 518
+ 519
+ 520
+ 521
+ 522
+ 523
+ 524
+ 525
+ 526
+ 527
+ 528
+ 529
+ 530
+ 531
+ 532
+ 533
+ 534
+ 535
+ 536
+ 537
+ 538
+ 539
+ 540
+ 541
+ 542
+ 543
+ 544
+ 545
+ 546
+ 547
+ 548
+ 549
+ 550
+ 551
+ 552
+ 553
+ 554
+ 555
+ 556
+ 557
+ 558
+ 559
+ 560
+ 561
+ 562
+ 563
+ 564
+ 565
+ 566
+ 567
+ 568
+ 569
+ 570
+ 571
+ 572
+ 573
+ 574
+ 575
+ 576
+ 577
+ 578
+ 579
+ 580
+ 581
+ 582
+ 583
+ 584
+ 585
+ 586
+ 587
+ 588
+ 589
+ 590
+ 591
+ 592
+ 593
+ 594
+ 595
+ 596
+ 597
+ 598
+ 599
+ 600
+ 601
+ 602
+ 603
+ 604
+ 605
+ 606
+ 607
+ 608
+ 609
+ 610
+ 611
+ 612
+ 613
+ 614
+ 615
+ 616
+ 617
+ 618
+ 619
+ 620
+ 621
+ 622
+ 623
+ 624
+ 625
+ 626
+ 627
+ 628
+ 629
+ 630
+ 631
+ 632
+ 633
+ 634
+ 635
+ 636
+ 637
+ 638
+ 639
+ 640
+ 641
+ 642
+ 643
+ 644
+ 645
+ 646
+ 647
+ 648
+ 649
+ 650
+ 651
+ 652
+ 653
+ 654
+ 655
+ 656
+ 657
+ 658
+ 659
+ 660
+ 661
+ 662
+ 663
+ 664
+ 665
+ 666
+ 667
+ 668
+ 669
+ 670
+ 671
+ 672
+ 673
+ 674
+ 675
+ 676
+ 677
+ 678
+ 679
+ 680
+ 681
+ 682
+ 683
+ 684
+ 685
+ 686
+ 687
+ 688
+ 689
+ 690
+ 691
+ 692
+ 693
+ 694
+ 695
+ 696
+ 697
+ 698
+ 699
+ 700
+ 701
+ 702
+ 703
+ 704
+ 705
+ 706
+ 707
+ 708
+ 709
+ 710
+ 711
+ 712
+ 713
+ 714
+ 715
+ 716
+ 717
+ 718
+ 719
+ 720
+ 721
+ 722
+ 723
+ 724
+ 725
+ 726
+ 727
+ 728
+ 729
+ 730
+ 731
+ 732
+ 733
+ 734
+ 735
+ 736
+ 737
+ 738
+ 739
+ 740
+ 741
+ 742
+ 743
+ 744
+ 745
+ 746
+ 747
+ 748
+ 749
+ 750
+ 751
+ 752
+ 753
+ 754
+ 755
+ 756
+ 757
+ 758
+ 759
+ 760
+ 761
+ 762
+ 763
+ 764
+ 765
+ 766
+ 767
+ 768
+ 769
+ 770
+ 771
+ 772
+ 773
+ 774
+ 775
+ 776
+ 777
+ 778
+ 779
+ 780
+ 781
+ 782
+ 783
+ 784
+ 785
+ 786
+ 787
+ 788
+ 789
+ 790
+ 791
+ 792
+ 793
+ 794
+ 795
+ 796
+ 797
+ 798
+ 799
+ 800
+ 801
+ 802
+ 803
+ 804
+ 805
+ 806
+ 807
+ 808
+ 809
+ 810
+ 811
+ 812
+ 813
+ 814
+ 815
+ 816
+ 817
+ 818
+ 819
+ 820
+ 821
+ 822
+ 823
+ 824
+ 825
+ 826
+ 827
+ 828
+ 829
+ 830
+ 831
+ 832
+ 833
+ 834
+ 835
+ 836
+ 837
+ 838
+ 839
+ 840
+ 841
+ 842
+ 843
+ 844
+ 845
+ 846
+ 847
+ 848
+ 849
+ 850
+ 851
+ 852
+ 853
+ 854
+ 855
+ 856
+ 857
+ 858
+ 859
+ 860
+ 861
+ 862
+ 863
+ 864
+ 865
+ 866
+ 867
+ 868
+ 869
+ 870
+ 871
+ 872
+ 873
+ 874
+ 875
+ 876
+ 877
+ 878
+ 879
+ 880
+ 881
+ 882
+ 883
+ 884
+ 885
+ 886
+ 887
+ 888
+ 889
+ 890
+ 891
+ 892
+ 893
+ 894
+ 895
+ 896
+ 897
+ 898
+ 899
+ 900
+ 901
+ 902
+ 903
+ 904
+ 905
+ 906
+ 907
+ 908
+ 909
+ 910
+ 911
+ 912
+ 913
+ 914
+ 915
+ 916
+ 917
+ 918
+ 919
+ 920
+ 921
+ 922
+ 923
+ 924
+ 925
+ 926
+ 927
+ 928
+ 929
+ 930
+ 931
+ 932
+ 933
+ 934
+ 935
+ 936
+ 937
+ 938
+ 939
+ 940
+ 941
+ 942
+ 943
+ 944
+ 945
+ 946
+ 947
+ 948
+ 949
+ 950
+ 951
+ 952
+ 953
+ 954
+ 955
+ 956
+ 957
+ 958
+ 959
+ 960
+ 961
+ 962
+ 963
+ 964
+ 965
+ 966
+ 967
+ 968
+ 969
+ 970
+ 971
+ 972
+ 973
+ 974
+ 975
+ 976
+ 977
+ 978
+ 979
+ 980
+ 981
+ 982
+ 983
+ 984
+ 985
+ 986
+ 987
+ 988
+ 989
+ 990
+ 991
+ 992
+ 993
+ 994
+ 995
+ 996
+ 997
+ 998
+ 999
+1000
+1001
+1002
+1003
+1004
+1005
+1006
+1007
+1008
+1009
+1010
+1011
+1012
+1013
+1014
+1015
+1016
+1017
+1018
+1019
+1020
+1021
+1022
+1023
+1024
+1025
+1026
+1027
+1028
+1029
+1030
+1031
+1032
+1033
+1034
+1035
+1036
+1037
+1038
+1039
+1040
+1041
+1042
+1043
+1044
+1045
+1046
+1047
+1048
+1049
+1050
+1051
+1052
+1053
// *****************************************************************************
 /*!
-  \file      src/PDE/ConfigureMultiMat.cpp
+  \file      src/PDE/Integrate/Basis.cpp
   \copyright 2012-2015 J. Bakosi,
              2016-2018 Los Alamos National Security, LLC.,
              2019-2021 Triad National Security, LLC.
              All rights reserved. See the LICENSE file for details.
-  \brief     Register and compile configuration for multi-material compressible
-     flow PDE
-  \details   Register and compile configuration for compressible multi-material
-     flow PDE.
-*/
-// *****************************************************************************
-
-#include <set>
-#include <map>
-#include <vector>
-#include <string>
+  \brief     Functions for computing the Dubiner basis functions in DG methods
+  \details   This file contains functionality for computing the basis functions
+     and relating coordinates transformation functions used in discontinuous
+     Galerkin methods for variaous orders of numerical representation. The basis
+     functions chosen for the DG method are the Dubiner basis, which are
+     Legendre polynomials modified for tetrahedra, which are defined only on
+     the reference/master tetrahedron.
+  \see [1] https://doi.org/10.1007/BF01060030
+  \see [2] https://doi.org/10.1093/imamat/hxh111
+*/
+// *****************************************************************************
 
-#include <brigand/algorithms/for_each.hpp>
-
-#include "Tags.hpp"
-#include "CartesianProduct.hpp"
-#include "PDEFactory.hpp"
-#include "Inciter/Options/PDE.hpp"
-#include "ContainerUtil.hpp"
-#include "ConfigureMultiMat.hpp"
-#include "MultiMat/Physics/DG.hpp"
-#include "MultiMat/Physics/FV.hpp"
-#include "MultiMat/DGMultiMat.hpp"
-#include "MultiMat/FVMultiMat.hpp"
-#include "MultiMat/Problem.hpp"
-#include "Inciter/Options/Material.hpp"
-
-namespace inciter {
-
-void
-registerMultiMat( DGFactory& df, FVFactory& ff,
-  std::set< ctr::PDEType >& fvt, std::set< ctr::PDEType >& dgt )
-// *****************************************************************************
-// Register multi-material compressible flow PDE into PDE factory
-//! \param[in,out] df Discontinuous Galerkin PDE factory to register to
-//! \param[in,out] ff Finite volume PDE factory to register to
-//! \param[in,out] dgt Counters for equation types registered into DG factory
-//! \param[in,out] fvt Counters for equation types registered into FV factory
-// *****************************************************************************
-{
-  // Construct vector of vectors for all possible policies
-  using DGMultiMatPolicies =
-    tk::cartesian_product< dg::MultiMatPhysics, MultiMatProblems >;
-  // Register PDEs for all combinations of policies
-  brigand::for_each< DGMultiMatPolicies >(
-    registerDG< dg::MultiMat >( df, dgt, ctr::PDEType::MULTIMAT ) );
-
-  // Construct vector of vectors for all possible policies
-  using FVMultiMatPolicies =
-    tk::cartesian_product< fv::MultiMatPhysics, MultiMatProblems >;
-  // Register PDEs for all combinations of policies
-  brigand::for_each< FVMultiMatPolicies >(
-    registerFV< fv::MultiMat >( ff, fvt, ctr::PDEType::MULTIMAT ) );
-}
-
-std::vector< std::pair< std::string, std::string > >
-infoMultiMat( std::map< ctr::PDEType, tk::ncomp_t >& cnt )
-// *****************************************************************************
-//  Return information on the compressible flow system of PDEs
-//! \param[inout] cnt std::map of counters for all PDE types
-//! \return vector of string pairs describing the PDE configuration
-// *****************************************************************************
-{
-  using eq = tag::multimat;
-  using tk::parameter;
-  using tk::parameters;
-
-  auto c = ++cnt[ ctr::PDEType::MULTIMAT ];       // count eqs
-  --c;  // used to index vectors starting with 0<--- Variable 'c' is assigned a value that is never used.
-
-  std::vector< std::pair< std::string, std::string > > nfo;
+#include <array>
+#include "QuinoaConfig.hpp"
+
+#include "Basis.hpp"
+#include "Vector.hpp"
+#include "Mass.hpp"
+
+std::array< tk::real, 3 >
+tk::eval_gp ( const std::size_t igp,
+              const std::array< std::array< tk::real, 3>, 3 >& coordfa,
+              const std::array< std::vector< tk::real >, 2 >& coordgp )
+// *****************************************************************************
+//  Compute the coordinates of quadrature points for face integral in physical
+//  space
+//! \param[in] igp Index of quadrature points
+//! \param[in] coordfa Array of nodal coordinates for face element
+//! \param[in] coordgp Array of coordinates for quadrature points in reference
+//!   space
+//! \return Array of coordinates for quadrature points in physical space
+// *****************************************************************************
+{
+  // Barycentric coordinates for the triangular face
+  auto shp1 = 1.0 - coordgp[0][igp] - coordgp[1][igp];
+  auto shp2 = coordgp[0][igp];
+  auto shp3 = coordgp[1][igp];
+
+  // Transformation of the quadrature point from the 2D reference/master
+  // element to physical space, to obtain its physical (x,y,z) coordinates.
+  return {{ coordfa[0][0]*shp1 + coordfa[1][0]*shp2 + coordfa[2][0]*shp3,
+            coordfa[0][1]*shp1 + coordfa[1][1]*shp2 + coordfa[2][1]*shp3,
+            coordfa[0][2]*shp1 + coordfa[1][2]*shp2 + coordfa[2][2]*shp3 }};
+}
+
+std::array< tk::real, 3 >
+tk::eval_gp ( const std::size_t igp,
+              const std::array< std::array< tk::real, 3>, 4 >& coord,
+              const std::array< std::vector< tk::real >, 3 >& coordgp )
+// *****************************************************************************
+//  Compute the coordinates of quadrature points for volume integral in
+//  physical space
+//! \param[in] igp Index of quadrature points
+//! \param[in] coord Array of nodal coordinates for tetrahedron element
+//! \param[in] coordgp Array of coordinates for quadrature points in reference space
+//! \return Array of coordinates for quadrature points in physical space
+// *****************************************************************************
+{
+  // Barycentric coordinates for the tetradedron element
+  auto shp1 = 1.0 - coordgp[0][igp] - coordgp[1][igp] - coordgp[2][igp];
+  auto shp2 = coordgp[0][igp];
+  auto shp3 = coordgp[1][igp];
+  auto shp4 = coordgp[2][igp];
+
+  // Transformation of the quadrature point from the reference/master
+  // element to physical space, to obtain its physical (x,y,z) coordinates.
+  return {{
+   coord[0][0]*shp1 + coord[1][0]*shp2 + coord[2][0]*shp3 + coord[3][0]*shp4,
+   coord[0][1]*shp1 + coord[1][1]*shp2 + coord[2][1]*shp3 + coord[3][1]*shp4,
+   coord[0][2]*shp1 + coord[1][2]*shp2 + coord[2][2]*shp3 + coord[3][2]*shp4 }};
+}
 
-  nfo.emplace_back( ctr::PDE().name( ctr::PDEType::MULTIMAT ), "" );
-
-  nfo.emplace_back( "physics", ctr::Physics().name(
-    g_inputdeck.get< eq, tag::physics >() ) );
-
-  nfo.emplace_back( "problem", ctr::Problem().name(
-    g_inputdeck.get< eq, tag::problem >() ) );
-
-  nfo.emplace_back( "flux", ctr::Flux().name(
-    g_inputdeck.get< tag::flux >() ) );
-
-  auto nmat = g_inputdeck.get< eq, tag::nmat >();
-  nfo.emplace_back( "number of materials", std::to_string( nmat ) );
-
-  auto prelax = g_inputdeck.get< eq, tag::prelax >();
-  nfo.emplace_back( "finite pressure relaxation", std::to_string( prelax ) );
-
-  auto intsharp = g_inputdeck.get< eq, tag::intsharp >();
-  nfo.emplace_back( "interface sharpening", std::to_string( intsharp ) );
-
-  auto rho0cn = g_inputdeck.get< eq, tag::rho0constraint >();
-  nfo.emplace_back( "density constraint correction", std::to_string( rho0cn ) );
-
-  auto ncomp = g_inputdeck.get< tag::ncomp >();
-  nfo.emplace_back( "number of components", std::to_string( ncomp ) );
+std::array< std::vector<tk::real>, 3 >
+tk::eval_dBdxi( const std::size_t ndof,
+  const std::array< tk::real, 3 >& coordgp )
+// *****************************************************************************
+//  Compute the derivatives of Dubiner basis wrt. reference coordinates
+//! \param[in] ndof Number of degrees of freedom
+//! \param[in] coordgp Coordinates in ref element where derivatives are needed
+//! \return Array of the derivatives of basis functions
+// *****************************************************************************
+{
+  // Initialize array
+  std::array< std::vector< tk::real >, 3 > dBdxi;
+  for (std::size_t idir=0; idir<3; ++idir) {
+    dBdxi[idir].resize(ndof, 0.0);
+  }
+
+  // high-order basis
+  if (ndof > 1) {
+    dBdxi[0][0] = 0.0;
+    dBdxi[1][0] = 0.0;
+    dBdxi[2][0] = 0.0;
+
+    dBdxi[0][1] = 2.0;
+    dBdxi[1][1] = 1.0;
+    dBdxi[2][1] = 1.0;
 
-  // Material eos output
-  const auto& matprop = g_inputdeck.get< tag::material >();
-  for (const auto& mtype : matprop) {
-    const auto& m_id = mtype.get< tag::id >();
-    ctr::Material opt;
-    nfo.emplace_back( opt.name( mtype.get< tag::eos >() ),
-      std::to_string(m_id.size())+" materials" );
-    nfo.emplace_back( "material id", parameters( m_id ) );
-  }
-
-  // ICs and IC-boxes
-
-  const auto& ic = g_inputdeck.get< tag::ic >();
-
-  const auto& bgmatidic = ic.get< tag::materialid >();
-  nfo.emplace_back( "IC background material id", parameter( bgmatidic ) );
-
-  const auto& icbox = ic.get< tag::box >();
-  if (!icbox.empty()) {
-    std::size_t bcnt = 0;
-    for (const auto& b : icbox) {   // for all boxes configured for this eq
-      std::vector< tk::real > box
-        { b.get< tag::xmin >(), b.get< tag::xmax >(),
-          b.get< tag::ymin >(), b.get< tag::ymax >(),
-          b.get< tag::zmin >(), b.get< tag::zmax >() };
-
-      std::string boxname = "IC box " + parameter(bcnt);
-      nfo.emplace_back( boxname, parameters( box ) );
-
-      nfo.emplace_back( boxname + " orientation",
-        parameters(b.get< tag::orientation >()) );
-
-      nfo.emplace_back( boxname + " material id",
-                        parameter( b.get< tag::materialid >() ) );
+    dBdxi[0][2] = 0.0;
+    dBdxi[1][2] = 3.0;
+    dBdxi[2][2] = 1.0;
+
+    dBdxi[0][3] = 0.0;
+    dBdxi[1][3] = 0.0;
+    dBdxi[2][3] = 4.0;
+
+    if (ndof > 4) {
+      dBdxi[0][4] = 12.0 * coordgp[0] + 6.0 * coordgp[1]
+                  +  6.0 * coordgp[2] - 6.0;
+      dBdxi[1][4] =  6.0 * coordgp[0] + 2.0 * coordgp[1]
+                  +  2.0 * coordgp[2] - 2.0;
+      dBdxi[2][4] =  6.0 * coordgp[0] + 2.0 * coordgp[1]
+                  +  2.0 * coordgp[2] - 2.0;
+
+      dBdxi[0][5] = 10.0 * coordgp[1] +  2.0 * coordgp[2] - 2.0;
+      dBdxi[1][5] = 10.0 * coordgp[0] + 10.0 * coordgp[1]
+                  +  6.0 * coordgp[2] - 6.0;
+      dBdxi[2][5] =  2.0 * coordgp[0] +  6.0 * coordgp[1]
+                  +  2.0 * coordgp[2] - 2.0;
+
+      dBdxi[0][6] = 12.0 * coordgp[2] - 2.0;
+      dBdxi[1][6] =  6.0 * coordgp[2] - 1.0;
+      dBdxi[2][6] = 12.0 * coordgp[0] + 6.0 * coordgp[1]
+                  + 12.0 * coordgp[2] - 7.0;
+
+      dBdxi[0][7] = 0.0;
+      dBdxi[1][7] = 20.0 * coordgp[1] + 8.0 * coordgp[2] - 8.0;
+      dBdxi[2][7] =  8.0 * coordgp[1] + 2.0 * coordgp[2] - 2.0;
+
+      dBdxi[0][8] = 0.0;
+      dBdxi[1][8] = 18.0 * coordgp[2] -  3.0;
+      dBdxi[2][8] = 18.0 * coordgp[1] + 12.0 * coordgp[2] - 7.0;
 
-      const auto& initiate = b.get< tag::initiate >();
-      auto opt = ctr::Initiate();
-      nfo.emplace_back( boxname + ' ' + opt.group(), opt.name(initiate) );
-
-      ++bcnt;
-    }
-  }
-
-  const auto& icblock = ic.get< tag::meshblock >();
-  for (const auto& b : icblock) {   // for all blocks configured for eq
-    std::string blockname = "IC mesh block " +
-      parameter(b.get< tag::blockid >());
-
-    nfo.emplace_back( blockname + " material id",
-                      parameter( b.get< tag::materialid >() ) );
-    const auto& initiate = b.get< tag::initiate >();
-    auto opt = ctr::Initiate();
-    nfo.emplace_back( blockname + ' ' + opt.group(), opt.name(initiate) );
-  }
-
-  return nfo;
-}
-
-}  // inciter::
+      dBdxi[0][9] = 0.0;
+      dBdxi[1][9] = 0.0;
+      dBdxi[2][9] = 30.0 * coordgp[2] - 10.0;
+    }
+  }
+
+  return dBdxi;
+}
+
+std::array< std::vector<tk::real>, 3 >
+tk::eval_dBdx_p1( const std::size_t ndof,
+                  const std::array< std::array< tk::real, 3 >, 3 >& jacInv )
+// *****************************************************************************
+//  Compute the derivatives of basis functions for DG(P1)
+//! \param[in] ndof Number of degrees of freedom
+//! \param[in] jacInv Array of the inverse of Jacobian
+//! \return Array of the derivatives of basis functions
+// *****************************************************************************
+{
+  // The derivatives of the basis functions dB/dx are easily calculated
+  // via a transformation to the reference space as,
+  // dB/dx = dB/dxi . dxi/dx,
+  // where, x = (x,y,z) are the physical coordinates, and
+  //        xi = (xi, eta, zeta) are the reference coordinates.
+  // The matrix dxi/dx is the inverse of the Jacobian of transformation
+  // and the matrix vector product has to be calculated. This follows.
+
+  std::array< std::vector<tk::real>, 3 > dBdx;
+  dBdx[0].resize( ndof, 0 );
+  dBdx[1].resize( ndof, 0 );
+  dBdx[2].resize( ndof, 0 );
+
+  auto db2dxi1 = 2.0;
+  auto db2dxi2 = 1.0;
+  auto db2dxi3 = 1.0;
+
+  auto db3dxi1 = 0.0;
+  auto db3dxi2 = 3.0;
+  auto db3dxi3 = 1.0;
+
+  auto db4dxi1 = 0.0;
+  auto db4dxi2 = 0.0;
+  auto db4dxi3 = 4.0;
+
+  dBdx[0][1] =  db2dxi1 * jacInv[0][0]
+              + db2dxi2 * jacInv[1][0]
+              + db2dxi3 * jacInv[2][0];
+
+  dBdx[1][1] =  db2dxi1 * jacInv[0][1]
+              + db2dxi2 * jacInv[1][1]
+              + db2dxi3 * jacInv[2][1];
+
+  dBdx[2][1] =  db2dxi1 * jacInv[0][2]
+              + db2dxi2 * jacInv[1][2]
+              + db2dxi3 * jacInv[2][2];
+
+  dBdx[0][2] =  db3dxi1 * jacInv[0][0]
+              + db3dxi2 * jacInv[1][0]
+              + db3dxi3 * jacInv[2][0];
+
+  dBdx[1][2] =  db3dxi1 * jacInv[0][1]
+              + db3dxi2 * jacInv[1][1]
+              + db3dxi3 * jacInv[2][1];
+
+  dBdx[2][2] =  db3dxi1 * jacInv[0][2]
+              + db3dxi2 * jacInv[1][2]
+              + db3dxi3 * jacInv[2][2];
+
+  dBdx[0][3] =  db4dxi1 * jacInv[0][0]
+              + db4dxi2 * jacInv[1][0]
+              + db4dxi3 * jacInv[2][0];
+
+  dBdx[1][3] =  db4dxi1 * jacInv[0][1]
+              + db4dxi2 * jacInv[1][1]
+              + db4dxi3 * jacInv[2][1];
+
+  dBdx[2][3] =  db4dxi1 * jacInv[0][2]
+              + db4dxi2 * jacInv[1][2]
+              + db4dxi3 * jacInv[2][2];
+
+  return dBdx;
+}
+
+void
+tk::eval_dBdx_p2( const std::size_t igp,
+                  const std::array< std::vector< tk::real >, 3 >& coordgp,
+                  const std::array< std::array< tk::real, 3 >, 3 >& jacInv,
+                  std::array< std::vector<tk::real>, 3 >& dBdx )
+// *****************************************************************************
+//  Compute the derivatives of Dubiner basis function for DG(P2)
+//! \param[in] igp Index of quadrature points
+//! \param[in] coordgp Gauss point coordinates for tetrahedron element
+//! \param[in] jacInv Array of the inverse of Jacobian
+//! \param[in,out] dBdx Array of the derivatives of basis function
+// *****************************************************************************
+{
+  auto db5dxi1 = 12.0 * coordgp[0][igp] + 6.0 * coordgp[1][igp]
+               +  6.0 * coordgp[2][igp] - 6.0;
+  auto db5dxi2 =  6.0 * coordgp[0][igp] + 2.0 * coordgp[1][igp]
+               +  2.0 * coordgp[2][igp] - 2.0;
+  auto db5dxi3 =  6.0 * coordgp[0][igp] + 2.0 * coordgp[1][igp]
+               +  2.0 * coordgp[2][igp] - 2.0;
+
+  auto db6dxi1 = 10.0 * coordgp[1][igp] +  2.0 * coordgp[2][igp] - 2.0;
+  auto db6dxi2 = 10.0 * coordgp[0][igp] + 10.0 * coordgp[1][igp]
+               +  6.0 * coordgp[2][igp] - 6.0;
+  auto db6dxi3 =  2.0 * coordgp[0][igp] +  6.0 * coordgp[1][igp]
+               +  2.0 * coordgp[2][igp] - 2.0;
+
+  auto db7dxi1 = 12.0 * coordgp[2][igp] - 2.0;
+  auto db7dxi2 =  6.0 * coordgp[2][igp] - 1.0;
+  auto db7dxi3 = 12.0 * coordgp[0][igp] + 6.0 * coordgp[1][igp]
+               + 12.0 * coordgp[2][igp] - 7.0;
+
+  auto db8dxi1 =  0;
+  auto db8dxi2 = 20.0 * coordgp[1][igp] + 8.0 * coordgp[2][igp] - 8.0;
+  auto db8dxi3 =  8.0 * coordgp[1][igp] + 2.0 * coordgp[2][igp] - 2.0;
+
+  auto db9dxi1 =  0;
+  auto db9dxi2 = 18.0 * coordgp[2][igp] -  3.0;
+  auto db9dxi3 = 18.0 * coordgp[1][igp] + 12.0 * coordgp[2][igp] - 7.0;
+
+  auto db10dxi1 =  0;
+  auto db10dxi2 =  0;
+  auto db10dxi3 = 30.0 * coordgp[2][igp] - 10.0;
+
+  dBdx[0][4] =  db5dxi1 * jacInv[0][0]
+              + db5dxi2 * jacInv[1][0]
+              + db5dxi3 * jacInv[2][0];
+
+  dBdx[1][4] =  db5dxi1 * jacInv[0][1]
+              + db5dxi2 * jacInv[1][1]
+              + db5dxi3 * jacInv[2][1];
+
+  dBdx[2][4] =  db5dxi1 * jacInv[0][2]
+              + db5dxi2 * jacInv[1][2]
+              + db5dxi3 * jacInv[2][2];
+
+  dBdx[0][5] =  db6dxi1 * jacInv[0][0]
+              + db6dxi2 * jacInv[1][0]
+              + db6dxi3 * jacInv[2][0];
+
+  dBdx[1][5] =  db6dxi1 * jacInv[0][1]
+              + db6dxi2 * jacInv[1][1]
+              + db6dxi3 * jacInv[2][1];
+
+  dBdx[2][5] =  db6dxi1 * jacInv[0][2]
+              + db6dxi2 * jacInv[1][2]
+              + db6dxi3 * jacInv[2][2];
+
+  dBdx[0][6] =  db7dxi1 * jacInv[0][0]
+              + db7dxi2 * jacInv[1][0]
+              + db7dxi3 * jacInv[2][0];
+
+  dBdx[1][6] =  db7dxi1 * jacInv[0][1]
+              + db7dxi2 * jacInv[1][1]
+              + db7dxi3 * jacInv[2][1];
+
+  dBdx[2][6] =  db7dxi1 * jacInv[0][2]
+              + db7dxi2 * jacInv[1][2]
+              + db7dxi3 * jacInv[2][2];
+
+  dBdx[0][7] =  db8dxi1 * jacInv[0][0]
+              + db8dxi2 * jacInv[1][0]
+              + db8dxi3 * jacInv[2][0];
+
+  dBdx[1][7] =  db8dxi1 * jacInv[0][1]
+              + db8dxi2 * jacInv[1][1]
+              + db8dxi3 * jacInv[2][1];
+
+  dBdx[2][7] =  db8dxi1 * jacInv[0][2]
+              + db8dxi2 * jacInv[1][2]
+              + db8dxi3 * jacInv[2][2];
+
+  dBdx[0][8] =  db9dxi1 * jacInv[0][0]
+              + db9dxi2 * jacInv[1][0]
+              + db9dxi3 * jacInv[2][0];
+
+  dBdx[1][8] =  db9dxi1 * jacInv[0][1]
+              + db9dxi2 * jacInv[1][1]
+              + db9dxi3 * jacInv[2][1];
+
+  dBdx[2][8] =  db9dxi1 * jacInv[0][2]
+              + db9dxi2 * jacInv[1][2]
+              + db9dxi3 * jacInv[2][2];
+
+  dBdx[0][9] =  db10dxi1 * jacInv[0][0]
+              + db10dxi2 * jacInv[1][0]
+              + db10dxi3 * jacInv[2][0];
+
+  dBdx[1][9] =  db10dxi1 * jacInv[0][1]
+              + db10dxi2 * jacInv[1][1]
+              + db10dxi3 * jacInv[2][1];
+
+  dBdx[2][9] =  db10dxi1 * jacInv[0][2]
+              + db10dxi2 * jacInv[1][2]
+              + db10dxi3 * jacInv[2][2];
+}
+
+std::vector< tk::real >
+tk::eval_basis( const std::size_t ndof,
+                const tk::real xi,
+                const tk::real eta,
+                const tk::real zeta )
+// *****************************************************************************
+//  Compute the Dubiner basis functions
+//! \param[in] ndof Number of degrees of freedom
+//! \param[in] xi,eta,zeta Coordinates for quadrature points in reference space
+//! \return Vector of basis functions
+// *****************************************************************************
+{
+  // Array of basis functions
+  std::vector< tk::real > B( ndof, 1.0 );
+
+  if ( ndof > 1 )           // DG(P1)
+  {
+    B[1] = 2.0 * xi + eta + zeta - 1.0;
+    B[2] = 3.0 * eta + zeta - 1.0;
+    B[3] = 4.0 * zeta - 1.0;
+
+    if( ndof > 4 )         // DG(P2)
+    {
+      B[4] =  6.0 * xi * xi + eta * eta + zeta * zeta
+            + 6.0 * xi * eta + 6.0 * xi * zeta + 2.0 * eta * zeta
+            - 6.0 * xi - 2.0 * eta - 2.0 * zeta + 1.0;
+      B[5] =  5.0 * eta * eta + zeta * zeta
+            + 10.0 * xi * eta + 2.0 * xi * zeta + 6.0 * eta * zeta
+            - 2.0 * xi - 6.0 * eta - 2.0 * zeta + 1.0;
+      B[6] =  6.0 * zeta * zeta + 12.0 * xi * zeta + 6.0 * eta * zeta - 2.0 * xi
+            - eta - 7.0 * zeta + 1.0;
+      B[7] =  10.0 * eta * eta + zeta * zeta + 8.0 * eta * zeta
+            - 8.0 * eta - 2.0 * zeta + 1.0;
+      B[8] =  6.0 * zeta * zeta + 18.0 * eta * zeta - 3.0 * eta - 7.0 * zeta
+            + 1.0;
+      B[9] =  15.0 * zeta * zeta - 10.0 * zeta + 1.0;
+    }
+  }
+
+  return B;
+}
+
+std::vector< tk::real >
+tk::eval_state ( ncomp_t ncomp,
+                 const std::size_t ndof,
+                 const std::size_t ndof_el,
+                 const std::size_t e,
+                 const Fields& U,
+                 const std::vector< tk::real >& B )
+// *****************************************************************************
+//  Compute the state variables for the tetrahedron element
+//! \param[in] ncomp Number of scalar components in this PDE system
+//! \param[in] ndof Maximum number of degrees of freedom
+//! \param[in] ndof_el Number of degrees of freedom for the local element
+//! \param[in] e Index for the tetrahedron element
+//! \param[in] U Solution vector at recent time step
+//! \param[in] B Vector of basis functions
+//! \return Vector of state variable for tetrahedron element
+// *****************************************************************************
+{
+  // This is commented for now because that when p0/p1 adaptive with limiter
+  // applied, the size of basis will be 10. However, ndof_el will be 4 which
+  // leads to a size mismatch in limiter function.
+  //Assert( B.size() == ndof_el, "Size mismatch" );
+
+  if (U.empty()) return {};
+
+  // Array of state variable for tetrahedron element
+  std::vector< tk::real > state( ncomp, 0.0 );
+
+  for (ncomp_t c=0; c<ncomp; ++c)
+  {
+    auto mark = c*ndof;
+    state[c] = U( e, mark );
+
+    if(ndof_el > 1)        //DG(P1)
+    {
+      state[c] += U( e, mark+1 ) * B[1]
+                + U( e, mark+2 ) * B[2]
+                + U( e, mark+3 ) * B[3];
+    }
+
+    if(ndof_el > 4)        //DG(P2)
+    {
+      state[c] += U( e, mark+4 ) * B[4]
+                + U( e, mark+5 ) * B[5]
+                + U( e, mark+6 ) * B[6]
+                + U( e, mark+7 ) * B[7]
+                + U( e, mark+8 ) * B[8]
+                + U( e, mark+9 ) * B[9];
+    }
+  }
+
+  return state;
+}
+
+std::vector< std::vector< tk::real > >
+tk::DubinerToTaylor( ncomp_t ncomp,
+                     const std::size_t e,
+                     const std::size_t ndof,
+                     const tk::Fields& U,
+                     const std::vector< std::size_t >& inpoel,
+                     const tk::UnsMesh::Coords& coord )
+// *****************************************************************************
+//  Transform the solution with Dubiner basis to the solution with Taylor basis
+//! \param[in] ncomp Number of scalar components in this PDE system
+//! \param[in] e Id of element whose solution is to be limited
+//! \param[in] ndof Maximum number of degrees of freedom
+//! \param[in] U High-order solution vector with Dubiner basis
+//! \param[in] inpoel Element connectivity
+//! \param[in] coord Array of nodal coordinates
+//! \return High-order solution vector with Taylor basis
+// *****************************************************************************
+{
+  std::vector< std::vector< tk::real > >
+    unk(ncomp, std::vector<tk::real>(ndof, 0.0));
+
+  const auto& cx = coord[0];
+  const auto& cy = coord[1];
+  const auto& cz = coord[2];
+
+  std::array< std::vector< tk::real >, 3 > center;
+  center[0].resize(1, 0.25);
+  center[1].resize(1, 0.25);
+  center[2].resize(1, 0.25);
+
+  // Evaluate the cell center solution
+  for(ncomp_t icomp = 0; icomp < ncomp; icomp++)
+  {
+    auto mark = icomp * ndof;
+    unk[icomp][0] = U(e, mark);
+  }
+
+  // Evaluate the first order derivative
+  std::array< std::array< tk::real, 3>, 4 > coordel {{
+    {{ cx[ inpoel[4*e  ] ], cy[ inpoel[4*e  ] ], cz[ inpoel[4*e  ] ] }},
+    {{ cx[ inpoel[4*e+1] ], cy[ inpoel[4*e+1] ], cz[ inpoel[4*e+1] ] }},
+    {{ cx[ inpoel[4*e+2] ], cy[ inpoel[4*e+2] ], cz[ inpoel[4*e+2] ] }},
+    {{ cx[ inpoel[4*e+3] ], cy[ inpoel[4*e+3] ], cz[ inpoel[4*e+3] ] }}
+  }};
+
+  auto jacInv =
+              tk::inverseJacobian( coordel[0], coordel[1], coordel[2], coordel[3] );
+
+  // Compute the derivatives of basis function for DG(P1)
+  auto dBdx = tk::eval_dBdx_p1( ndof, jacInv );
+
+  if(ndof > 4) {
+    tk::eval_dBdx_p2(0, center, jacInv, dBdx);
+  }
+
+  for(ncomp_t icomp = 0; icomp < ncomp; icomp++)
+  {
+    auto mark = icomp * ndof; 
+    for(std::size_t idir = 0; idir < 3; idir++)
+    {
+      unk[icomp][idir+1] = 0;
+      for(std::size_t idof = 1; idof < ndof; idof++)
+        unk[icomp][idir+1] += U(e, mark+idof) * dBdx[idir][idof];
+    }
+  }
+
+  // Evaluate the second order derivative if DGP2 is applied
+  // The basic idea of the computation follows
+  //    d2Udx2 = /sum u_i * (d2B_i/dx2)
+  // where d2B_i/dx2 = d( dB_i/dxi * dxi/dx ) / dxi * dxi/dx
+  if(ndof > 4)
+  {
+    // Matrix to store the second order derivatives of basis functions in
+    // reference domain
+    tk::real d2Bdxi2[6][6] =
+    { { 12.0,  0.0,  0.0,  0.0,  0.0,  0.0 },
+      {  2.0, 10.0,  0.0, 20.0,  0.0,  0.0 },
+      {  2.0,  2.0, 12.0,  2.0, 12.0, 30.0 },
+      {  6.0, 10.0,  0.0,  0.0,  0.0,  0.0 },
+      {  6.0,  2.0, 12.0,  0.0,  0.0,  0.0 },
+      {  2.0,  6.0,  6.0,  8.0, 18.0,  0.0 } };
+
+    // Transform matrix to convert the second order derivatives of basis
+    // function in reference domain to the one in physical domain
+    tk::real d2xdxi2[6][6];
+
+    d2xdxi2[0][0] = jacInv[0][0] * jacInv[0][0];
+    d2xdxi2[0][1] = jacInv[1][0] * jacInv[1][0];
+    d2xdxi2[0][2] = jacInv[2][0] * jacInv[2][0];
+    d2xdxi2[0][3] = jacInv[0][0] * jacInv[1][0] * 2.0;
+    d2xdxi2[0][4] = jacInv[0][0] * jacInv[2][0] * 2.0;
+    d2xdxi2[0][5] = jacInv[1][0] * jacInv[2][0] * 2.0;
+
+    d2xdxi2[1][0] = jacInv[0][1] * jacInv[0][1];
+    d2xdxi2[1][1] = jacInv[1][1] * jacInv[1][1];
+    d2xdxi2[1][2] = jacInv[2][1] * jacInv[2][1];
+    d2xdxi2[1][3] = jacInv[0][1] * jacInv[1][1] * 2.0;
+    d2xdxi2[1][4] = jacInv[0][1] * jacInv[2][1] * 2.0;
+    d2xdxi2[1][5] = jacInv[1][1] * jacInv[2][1] * 2.0;
+
+    d2xdxi2[2][0] = jacInv[0][2] * jacInv[0][2];
+    d2xdxi2[2][1] = jacInv[1][2] * jacInv[1][2];
+    d2xdxi2[2][2] = jacInv[2][2] * jacInv[2][2];
+    d2xdxi2[2][3] = jacInv[0][2] * jacInv[1][2] * 2.0;
+    d2xdxi2[2][4] = jacInv[0][2] * jacInv[2][2] * 2.0;
+    d2xdxi2[2][5] = jacInv[1][2] * jacInv[2][2] * 2.0;
+
+    d2xdxi2[3][0] = jacInv[0][0] * jacInv[0][1];
+    d2xdxi2[3][1] = jacInv[1][0] * jacInv[1][1];
+    d2xdxi2[3][2] = jacInv[2][0] * jacInv[2][1];
+    d2xdxi2[3][3] = jacInv[0][0] * jacInv[1][1] + jacInv[1][0] * jacInv[0][1];
+    d2xdxi2[3][4] = jacInv[0][0] * jacInv[2][1] + jacInv[2][0] * jacInv[0][1];
+    d2xdxi2[3][5] = jacInv[1][0] * jacInv[2][1] + jacInv[2][0] * jacInv[1][1];
+
+    d2xdxi2[4][0] = jacInv[0][0] * jacInv[0][2];
+    d2xdxi2[4][1] = jacInv[1][0] * jacInv[1][2];
+    d2xdxi2[4][2] = jacInv[2][0] * jacInv[2][2];
+    d2xdxi2[4][3] = jacInv[0][0] * jacInv[1][2] + jacInv[1][0] * jacInv[0][2];
+    d2xdxi2[4][4] = jacInv[0][0] * jacInv[2][2] + jacInv[2][0] * jacInv[0][2];
+    d2xdxi2[4][5] = jacInv[1][0] * jacInv[2][2] + jacInv[2][0] * jacInv[1][2];
+
+    d2xdxi2[5][0] = jacInv[0][1] * jacInv[0][2];
+    d2xdxi2[5][1] = jacInv[1][1] * jacInv[1][2];
+    d2xdxi2[5][2] = jacInv[2][1] * jacInv[2][2];
+    d2xdxi2[5][3] = jacInv[0][1] * jacInv[1][2] + jacInv[1][1] * jacInv[0][2];
+    d2xdxi2[5][4] = jacInv[0][1] * jacInv[2][2] + jacInv[2][1] * jacInv[0][2];
+    d2xdxi2[5][5] = jacInv[1][1] * jacInv[2][2] + jacInv[2][1] * jacInv[1][2];
+
+    // Matrix to store the second order derivatives of basis functions in
+    // physical domain
+    tk::real d2Bdx2[6][6];
+    for(std::size_t ibasis = 0; ibasis < 6; ibasis++) {
+      for(std::size_t idir = 0; idir < 6; idir++) {
+        d2Bdx2[idir][ibasis] = 0;
+        for(std::size_t k = 0; k < 6; k++)
+          d2Bdx2[idir][ibasis] += d2xdxi2[idir][k] * d2Bdxi2[k][ibasis];
+      }
+    }
+
+    for(ncomp_t icomp = 0; icomp < ncomp; icomp++)
+    {
+      auto mark = icomp * ndof;
+      for(std::size_t idir = 0; idir < 6; idir++)
+      {
+        unk[icomp][idir+4] = 0;
+        for(std::size_t ibasis = 0; ibasis < 6; ibasis++)
+          unk[icomp][idir+4] += U(e, mark+4+ibasis) * d2Bdx2[idir][ibasis];
+      }
+    }
+  }
+  return unk;
+}
+
+void
+tk::TaylorToDubiner( ncomp_t ncomp,
+                     std::size_t e,
+                     std::size_t ndof,
+                     const std::vector< std::size_t >& inpoel,
+                     const tk::UnsMesh::Coords& coord,
+                     const tk::Fields& geoElem,
+                     std::vector< std::vector< tk::real > >& unk )
+// *****************************************************************************
+//  Convert the solution with Taylor basis to the solution with Dubiner basis by
+//    projection method
+//! \param[in] ncomp Number of scalar components in this PDE system
+//! \param[in] e Id of element whose solution is to be limited
+//! \param[in] ndof Maximum number of degrees of freedom
+//! \param[in] inpoel Element connectivity
+//! \param[in] coord Array of nodal coordinates
+//! \param[in, out] unk High-order solution vector with Taylor basis
+// *****************************************************************************
+{
+  Assert( ncomp > 0, "Number of scalar components is incorrect" );
+
+  // The diagonal of mass matrix
+  std::vector< tk::real > L(ndof, 0.0);
+
+  tk::real vol = 1.0 / 6.0;
+
+  L[0] = vol;
+
+  if(ndof > 1) {
+    Assert( (ndof == 4)||(ndof == 10),
+      "Mismatch in number of degrees of freedom" );
+    L[1] = vol / 10.0;
+    L[2] = vol * 3.0/10.0;
+    L[3] = vol * 3.0/5.0;
+  }
+
+  if(ndof > 4) {
+    Assert( ndof == 10, "Mismatch in number of degrees of freedom" );
+    L[4] = vol / 35.0;
+    L[5] = vol / 21.0;
+    L[6] = vol / 14.0;
+    L[7] = vol / 7.0;
+    L[8] = vol * 3.0/14.0;
+    L[9] = vol * 3.0/7.0;
+  }
+
+  // Coordinates of the centroid in physical domain
+  std::array< tk::real, 3 > x_c{geoElem(e,1), geoElem(e,2), geoElem(e,3)};
+
+  const auto& cx = coord[0];
+  const auto& cy = coord[1];
+  const auto& cz = coord[2];
+
+  std::array< std::array< tk::real, 3>, 4 > coordel {{
+    {{ cx[ inpoel[4*e  ] ], cy[ inpoel[4*e  ] ], cz[ inpoel[4*e  ] ] }},
+    {{ cx[ inpoel[4*e+1] ], cy[ inpoel[4*e+1] ], cz[ inpoel[4*e+1] ] }},
+    {{ cx[ inpoel[4*e+2] ], cy[ inpoel[4*e+2] ], cz[ inpoel[4*e+2] ] }},
+    {{ cx[ inpoel[4*e+3] ], cy[ inpoel[4*e+3] ], cz[ inpoel[4*e+3] ] }}
+  }};
+
+  // Number of quadrature points for volume integration
+  auto ng = tk::NGvol(ndof);
+
+  // arrays for quadrature points
+  std::array< std::vector< tk::real >, 3 > coordgp;
+  std::vector< tk::real > wgp;
+
+  coordgp[0].resize( ng );
+  coordgp[1].resize( ng );
+  coordgp[2].resize( ng );
+  wgp.resize( ng );
+
+  // get quadrature point weights and coordinates for triangle
+  tk::GaussQuadratureTet( ng, coordgp, wgp );
+
+  // right hand side vector
+  std::vector< tk::real > R( ncomp*ndof, 0.0 );
+
+  // Gaussian quadrature
+  for (std::size_t igp=0; igp<ng; ++igp)
+  {
+    auto wt = wgp[igp] * vol;
+
+    auto gp = tk::eval_gp( igp, coordel, coordgp );
+
+    auto B_taylor = eval_TaylorBasis( ndof, gp, x_c, coordel);
+
+    // Compute high order solution at gauss point
+    std::vector< tk::real > state( ncomp, 0.0 );
+    for (ncomp_t c=0; c<ncomp; ++c)
+    {
+      state[c] = unk[c][0];
+      state[c] += unk[c][1] * B_taylor[1]
+                + unk[c][2] * B_taylor[2]
+                + unk[c][3] * B_taylor[3];
+
+      if(ndof > 4)
+        state[c] += unk[c][4] * B_taylor[4] + unk[c][5] * B_taylor[5]
+                  + unk[c][6] * B_taylor[6] + unk[c][7] * B_taylor[7]
+                  + unk[c][8] * B_taylor[8] + unk[c][9] * B_taylor[9];
+    }
+
+    auto B = tk::eval_basis( ndof, coordgp[0][igp], coordgp[1][igp], coordgp[2][igp] );
+
+    for (ncomp_t c=0; c<ncomp; ++c)
+    {
+      auto mark = c*ndof;
+      R[mark] += wt * state[c];
+
+      if(ndof > 1)
+      {
+        R[mark+1] += wt * state[c] * B[1];
+        R[mark+2] += wt * state[c] * B[2];
+        R[mark+3] += wt * state[c] * B[3];
+
+        if(ndof > 4)
+        {
+          R[mark+4] += wt * state[c] * B[4];
+          R[mark+5] += wt * state[c] * B[5];
+          R[mark+6] += wt * state[c] * B[6];
+          R[mark+7] += wt * state[c] * B[7];
+          R[mark+8] += wt * state[c] * B[8];
+          R[mark+9] += wt * state[c] * B[9];
+        }
+      }
+    }
+  }
+
+  for (ncomp_t c=0; c<ncomp; ++c)
+  {
+    auto mark = c*ndof;
+    for(std::size_t idof = 0; idof < ndof; idof++)
+      unk[c][idof] = R[mark+idof] / L[idof];
+  }
+}
+
+std::vector< tk::real >
+tk::eval_TaylorBasis( const std::size_t ndof,
+                      const std::array< tk::real, 3 >& x,
+                      const std::array< tk::real, 3 >& x_c,
+                      const std::array< std::array< tk::real, 3>, 4 >& coordel )
+// *****************************************************************************
+//  Evaluate the Taylor basis at points
+//! \param[in] ndof Maximum number of degrees of freedom
+//! \param[in] x Nodal coordinates
+//! \param[in] x_c Coordinates of the centroid
+//! \param[in] coordel Array of nodal coordinates for the tetrahedron
+// *****************************************************************************
+{
+  std::vector< tk::real > avg( 6, 0.0 );
+  if(ndof > 4)
+  {
+    Assert( ndof == 10, "Mismatch in number of degrees of freedom" );
+    auto ng = tk::NGvol(ndof);
+
+    std::array< std::vector< tk::real >, 3 > coordgp;
+    std::vector< tk::real > wgp;
+
+    coordgp[0].resize( ng );
+    coordgp[1].resize( ng );
+    coordgp[2].resize( ng );
+    wgp.resize( ng );
+
+    tk::GaussQuadratureTet( ng, coordgp, wgp );
+
+    for (std::size_t igp=0; igp<ng; ++igp)
+    {
+      // Compute the coordinates of quadrature point at physical domain
+      auto gp = tk::eval_gp( igp, coordel, coordgp );
+
+      avg[0] += wgp[igp] * (gp[0] - x_c[0]) * (gp[0] - x_c[0]) * 0.5;
+      avg[1] += wgp[igp] * (gp[1] - x_c[1]) * (gp[1] - x_c[1]) * 0.5;
+      avg[2] += wgp[igp] * (gp[2] - x_c[2]) * (gp[2] - x_c[2]) * 0.5;
+      avg[3] += wgp[igp] * (gp[0] - x_c[0]) * (gp[1] - x_c[1]);
+      avg[4] += wgp[igp] * (gp[0] - x_c[0]) * (gp[2] - x_c[2]);
+      avg[5] += wgp[igp] * (gp[1] - x_c[1]) * (gp[2] - x_c[2]);
+    }
+  }
+
+  std::vector< tk::real > B( ndof, 1.0 );
+
+  if(ndof > 1) {
+    Assert( (ndof == 4)||(ndof == 10) ,
+      "Mismatch in number of degrees of freedom" );
+    B[1] = x[0] - x_c[0];
+    B[2] = x[1] - x_c[1];
+    B[3] = x[2] - x_c[2];
+  }
+
+  if(ndof > 4) {
+    B[4] = B[1] * B[1] * 0.5 - avg[0];
+    B[5] = B[2] * B[2] * 0.5 - avg[1];
+    B[6] = B[3] * B[3] * 0.5 - avg[2];
+    B[7] = B[1] * B[2] - avg[3];
+    B[8] = B[1] * B[3] - avg[4];
+    B[9] = B[2] * B[3] - avg[5];
+  }
+
+  return B;
+}
+
+// -----------------------------------------------------------------------------
+// Functions for reference element Taylor basis and related Xforms
+// -----------------------------------------------------------------------------
+
+std::vector< std::vector< tk::real > >
+tk::DubinerToTaylorRefEl( ncomp_t ncomp,
+  const std::size_t e,
+  const std::size_t ndof,
+  const std::size_t ndof_el,
+  const std::vector< std::vector< tk::real > >& mtInv,
+  const tk::Fields& U )
+// *****************************************************************************
+//  Transform the solution from Dubiner basis to Taylor basis
+//! \param[in] ncomp Number of scalar components in this PDE system
+//! \param[in] e Id of element whose solution is to be limited
+//! \param[in] ndof Maximum number of degrees of freedom
+//! \param[in] ndof_el Local number of degrees of freedom for the element
+//! \param[in] mtInv Inverse of Taylor mass matrix
+//! \param[in] U High-order solution vector with Dubiner basis
+//! \return High-order solution vector with Taylor basis (ref element)
+// *****************************************************************************
+{
+  auto vol = 1.0/6.0;
+
+  // 1. Get rhs for L2-projection
+  // Quadrature setup
+  auto ng = tk::NGvol(ndof_el);
+  std::array< std::vector< real >, 3 > coordgp;
+  std::vector< real > wgp;
+  coordgp[0].resize( ng );
+  coordgp[1].resize( ng );
+  coordgp[2].resize( ng );
+  wgp.resize( ng );
+  GaussQuadratureTet( ng, coordgp, wgp );
+
+  // Gaussian quadrature
+  std::vector< std::vector< tk::real > >
+    R(ncomp, std::vector<tk::real>(ndof_el, 0.0));
+  for (std::size_t igp=0; igp<ng; ++igp)
+  {
+    // Dubiner basis functions
+    auto B = eval_basis( ndof_el, coordgp[0][igp], coordgp[1][igp],
+                         coordgp[2][igp] );
+    // Taylor basis functions
+    auto Bt = eval_TaylorBasisRefEl(ndof_el, coordgp[0][igp], coordgp[1][igp],
+      coordgp[2][igp]);
+
+    auto state = tk::eval_state(ncomp, ndof, ndof_el, e, U, B);
+
+    for (std::size_t c=0; c<ncomp; ++c) {
+      for (std::size_t id=0; id<ndof_el; ++id) {
+        R[c][id] += wgp[igp] * vol * state[c] * Bt[id];
+      }
+    }
+  }
+
+
+  // 2. Get Taylor solution by premultiplying by mass matrix inverse
+  std::vector< std::vector< tk::real > >
+    unk(ncomp, std::vector<tk::real>(ndof_el, 0.0));
+  for (std::size_t c=0; c<ncomp; ++c) {
+    for (std::size_t id=0; id<ndof_el; ++id) {
+      for (std::size_t jd=0; jd<ndof_el; ++jd) {
+        unk[c][id] += mtInv[id][jd] * R[c][jd];
+      }
+    }
+  }
+
+  return unk;
+}
+
+void
+tk::TaylorToDubinerRefEl( ncomp_t ncomp,
+  const std::size_t ndof,
+  std::vector< std::vector< tk::real > >& unk )
+// *****************************************************************************
+//  Transform the solution from Taylor to Dubiner basis
+//! \param[in] ncomp Number of scalar components in this PDE system
+//! \param[in] ndof Number of degrees of freedom
+//! \param[in,out] unk High-order solution vector with Taylor basis that gets
+//!   transformed to solution with Dubiner basis
+// *****************************************************************************
+{
+  auto vol = 1.0/6.0;
+
+  auto M = massMatrixDubiner(ndof, vol);
+
+  // 1. Get rhs for L2-projection
+  // Quadrature setup
+  auto ng = tk::NGvol(ndof);
+  std::array< std::vector< real >, 3 > coordgp;
+  std::vector< real > wgp;
+  coordgp[0].resize( ng );
+  coordgp[1].resize( ng );
+  coordgp[2].resize( ng );
+  wgp.resize( ng );
+  GaussQuadratureTet( ng, coordgp, wgp );
+
+  // Gaussian quadrature
+  std::vector< std::vector< tk::real > >
+    R(ncomp, std::vector<tk::real>(ndof, 0.0));
+  for (std::size_t igp=0; igp<ng; ++igp)
+  {
+    // Dubiner basis functions
+    auto B = eval_basis( ndof, coordgp[0][igp], coordgp[1][igp],
+                         coordgp[2][igp] );
+    // Taylor basis functions
+    auto Bt = eval_TaylorBasisRefEl(ndof, coordgp[0][igp], coordgp[1][igp],
+      coordgp[2][igp]);
+
+    for (std::size_t c=0; c<ncomp; ++c) {
+      real state(0.0);
+      for (std::size_t id=0; id<ndof; ++id) {
+        state += unk[c][id] * Bt[id];
+      }
+      for (std::size_t id=0; id<ndof; ++id) {
+        R[c][id] += wgp[igp] * vol * state * B[id];
+      }
+    }
+  }
+
+  // 2. Get Dubiner solution by premultiplying by mass matrix inverse
+  for (std::size_t c=0; c<ncomp; ++c) {
+    for (std::size_t id=0; id<ndof; ++id) {
+      unk[c][id] = R[c][id] / M[id];
+    }
+  }
+}
+
+std::vector< tk::real >
+tk::eval_TaylorBasisRefEl( std::size_t ndof, tk::real x, tk::real y,
+  tk::real z )
+// *****************************************************************************
+//  Evaluate the Taylor basis at a point in the reference element
+//! \param[in] ndof Number of degrees of freedom
+//! \param[in] x Xi coordinate of point in reference element
+//! \param[in] y Eta coordinate of point in reference element
+//! \param[in] z Zeta coordinate of point in reference element
+// *****************************************************************************
+{
+  // Get averages required for P2 basis functions
+  std::vector< tk::real > avg( 6, 0.0 );
+  if(ndof > 4)
+  {
+    auto ng = tk::NGvol(ndof);
+    std::array< std::vector< tk::real >, 3 > coordgp;
+    std::vector< tk::real > wgp;
+    coordgp[0].resize( ng );
+    coordgp[1].resize( ng );
+    coordgp[2].resize( ng );
+    wgp.resize( ng );
+    tk::GaussQuadratureTet( ng, coordgp, wgp );
+
+    for (std::size_t igp=0; igp<ng; ++igp)
+    {
+      avg[0] += wgp[igp] * (coordgp[0][igp] - 0.25) * (coordgp[0][igp] - 0.25) * 0.5;
+      avg[1] += wgp[igp] * (coordgp[1][igp] - 0.25) * (coordgp[1][igp] - 0.25) * 0.5;
+      avg[2] += wgp[igp] * (coordgp[2][igp] - 0.25) * (coordgp[2][igp] - 0.25) * 0.5;
+      avg[3] += wgp[igp] * (coordgp[0][igp] - 0.25) * (coordgp[1][igp] - 0.25);
+      avg[4] += wgp[igp] * (coordgp[0][igp] - 0.25) * (coordgp[2][igp] - 0.25);
+      avg[5] += wgp[igp] * (coordgp[1][igp] - 0.25) * (coordgp[2][igp] - 0.25);
+    }
+  }
+
+  // Get Taylor basis functions
+  std::vector< tk::real > B( ndof, 1.0 );
+  if(ndof > 1) {
+    B[1] = x - 0.25;
+    B[2] = y - 0.25;
+    B[3] = z - 0.25;
+    if(ndof > 4) {
+      B[4] = B[1] * B[1] * 0.5 - avg[0];
+      B[5] = B[2] * B[2] * 0.5 - avg[1];
+      B[6] = B[3] * B[3] * 0.5 - avg[2];
+      B[7] = B[1] * B[2] - avg[3];
+      B[8] = B[1] * B[3] - avg[4];
+      B[9] = B[2] * B[3] - avg[5];
+    }
+  }
+
+  return B;
+}
+
+std::vector< std::vector< tk::real > >
+tk::invMassMatTaylorRefEl( std::size_t dof )
+// *****************************************************************************
+//  Obtain inverse mass matrix for Taylor basis in reference element
+//! \param[in] dof Number of degrees of freedom
+//! \return Inverse mass matrix
+// *****************************************************************************
+{
+  // Get Taylor mass matrix
+  auto Mt = massMatrixTaylorRefEl(dof);
+
+  // Only invert if DGP2
+  if (dof > 4) {
+    double mtInv[10*10];
+    for (std::size_t i=0; i<Mt.size(); ++i) {
+      for (std::size_t j=0; j<Mt[i].size(); ++j) {
+        std::size_t idx = 10*i+j;
+        mtInv[idx] = Mt[i][j];
+      }
+    }
+    lapack_int ipiv[10];
+    // LU-factorization for inversion
+    lapack_int info1 = LAPACKE_dgetrf(LAPACK_ROW_MAJOR, 10, 10, mtInv, 10, ipiv);
+    if (info1 != 0) Throw("Taylor mass matrix is singular");
+    // Inversion
+    lapack_int info2 = LAPACKE_dgetri(LAPACK_ROW_MAJOR, 10, mtInv, 10, ipiv);
+    if (info2 != 0) Throw("Error while inverting Taylor mass matrix");
+
+    // Get 2D vector from 1D array mass matrix inverse
+    for (std::size_t i=0; i<Mt.size(); ++i) {
+      for (std::size_t j=0; j<Mt[i].size(); ++j) {
+        std::size_t idx = 10*i+j;
+        Mt[i][j] = mtInv[idx];
+      }
+    }
+  }
+
+  return Mt;
+}
+
+std::vector< std::vector< tk::real > >
+tk::massMatrixTaylorRefEl(std::size_t dof)
+// *****************************************************************************
+//  Obtain mass matrix for Taylor basis in reference element
+//! \param[in] dof Number of degrees of freedom
+//! \return Mass matrix
+// *****************************************************************************
+{
+  std::vector< std::vector< tk::real > >
+    Mt(dof, std::vector<tk::real>(dof,0.0));
+
+  // Mt(1,1)
+  tk::real vol = 1.0/6.0;
+  Mt[0][0] = vol;
+
+  // Mt(i,j) for i,j > 1
+  if (dof > 1) {
+    // Quadrature information
+    auto ng = tk::NGvol(dof);
+    std::array< std::vector< tk::real >, 3 > coordgp;
+    std::vector< tk::real > wgp;
+    coordgp[0].resize( ng );
+    coordgp[1].resize( ng );
+    coordgp[2].resize( ng );
+    wgp.resize( ng );
+    tk::GaussQuadratureTet( ng, coordgp, wgp );
+
+    for (std::size_t igp=0; igp<ng; ++igp)
+    {
+      auto Bt = eval_TaylorBasisRefEl(dof, coordgp[0][igp], coordgp[1][igp],
+        coordgp[2][igp]);
+      for (std::size_t id=1; id<dof; ++id) {
+        for (std::size_t jd=1; jd<dof; ++jd) {
+          Mt[id][jd] += vol*wgp[igp]*Bt[id]*Bt[jd];
+        }
+      }
+    }
+  }
+
+  return Mt;
+}
 
diff --git a/Release/cppcheck/62.html b/Release/cppcheck/62.html index 31e4fd99bf2c..47e81d8b9a5e 100644 --- a/Release/cppcheck/62.html +++ b/Release/cppcheck/62.html @@ -152,12 +152,12 @@
  1
@@ -337,664 +337,184 @@ 

Cppcheck report - [

// *****************************************************************************
+178
// *****************************************************************************
 /*!
-  \file      src/PDE/Integrate/Boundary.cpp
+  \file      src/PDE/Integrate/Source.cpp
   \copyright 2012-2015 J. Bakosi,
              2016-2018 Los Alamos National Security, LLC.,
              2019-2021 Triad National Security, LLC.
              All rights reserved. See the LICENSE file for details.
-  \brief     Functions for computing physical boundary surface integrals of a
-     system of PDEs in DG methods
-  \details   This file contains functionality for computing physical boundary
-     surface integrals of a system of PDEs used in discontinuous Galerkin
-     methods for various orders of numerical representation.
-*/
-// *****************************************************************************
-
-#include <array>
-
-#include "Basis.hpp"
-#include "Boundary.hpp"
-#include "Vector.hpp"
-#include "Quadrature.hpp"
-#include "MultiMatTerms.hpp"
-#include "MultiMat/MultiMatIndexing.hpp"
-#include "Reconstruction.hpp"
-#include "Inciter/InputDeck/InputDeck.hpp"
-
-namespace inciter {
-extern ctr::InputDeck g_inputdeck;
-}
-
-namespace tk {
-
-void
-bndSurfInt( std::size_t nmat,
-            const std::vector< inciter::EOS >& mat_blk,
-            const std::size_t ndof,
-            const std::size_t rdof,
-            const std::vector< std::size_t >& bcconfig,
-            const inciter::FaceData& fd,
-            const Fields& geoFace,
-            const Fields& geoElem,
-            const std::vector< std::size_t >& inpoel,
-            const UnsMesh::Coords& coord,
-            real t,
-            const RiemannFluxFn& flux,
-            const VelFn& vel,
-            const StateFn& state,
-            const Fields& U,
-            const Fields& P,
-            const std::vector< std::size_t >& ndofel,
-            Fields& R,
-            std::vector< std::vector< tk::real > >&,
-            std::vector< std::vector< tk::real > >&,
-            std::vector< std::vector< tk::real > >& riemannDeriv,
-            int intsharp )
-// *****************************************************************************
-//! Compute boundary surface flux integrals for a given boundary type for DG
-//! \details This function computes contributions from surface integrals along
-//!   all faces for a particular boundary condition type, configured by the state
-//!   function
-//! \param[in] nmat Number of materials in this PDE system
-//! \param[in] mat_blk EOS material block
-//! \param[in] ndof Maximum number of degrees of freedom
-//! \param[in] rdof Maximum number of reconstructed degrees of freedom
-//! \param[in] bcconfig BC configuration vector for multiple side sets
-//! \param[in] fd Face connectivity and boundary conditions object
-//! \param[in] geoFace Face geometry array
-//! \param[in] geoElem Element geometry array
-//! \param[in] inpoel Element-node connectivity
-//! \param[in] coord Array of nodal coordinates
-//! \param[in] t Physical time
-//! \param[in] flux Riemann flux function to use
-//! \param[in] vel Function to use to query prescribed velocity (if any)
-//! \param[in] state Function to evaluate the left and right solution state at
-//!   boundaries
-//! \param[in] U Solution vector at recent time step
-//! \param[in] P Vector of primitives at recent time step
-//! \param[in] ndofel Vector of local number of degrees of freedom
-//! \param[in,out] R Right-hand side vector computed
-//! \param[in,out] vriem Vector of the riemann velocity
-//! \param[in,out] riemannLoc Vector of coordinates where Riemann velocity data
-//!   is available
-//! \param[in,out] riemannDeriv Derivatives of partial-pressures and velocities
-//!   computed from the Riemann solver for use in the non-conservative terms.
-//!   These derivatives are used only for multi-material hydro and unused for
-//!   single-material compflow and linear transport.
-//! \param[in] intsharp Interface compression tag, an optional argument, with
-//!   default 0, so that it is unused for single-material and transport.
-// *****************************************************************************
-{
-  const auto& bface = fd.Bface();
-  const auto& esuf = fd.Esuf();
-  const auto& inpofa = fd.Inpofa();
-
-  const auto& cx = coord[0];
-  const auto& cy = coord[1];
-  const auto& cz = coord[2];
-
-  auto ncomp = U.nprop()/rdof;<--- Variable 'ncomp' is assigned a value that is never used.
-  auto nprim = P.nprop()/rdof;<--- Variable 'nprim' is assigned a value that is never used.
-
-  //Assert( (nmat==1 ? riemannDeriv.empty() : true), "Non-empty Riemann "
-  //        "derivative vector for single material compflow" );
-
-  for (const auto& s : bcconfig) {       // for all bc sidesets
-    auto bc = bface.find(static_cast<int>(s));// faces for side set
-    if (bc != end(bface))
-    {
-      for (const auto& f : bc->second)
-      {
-        Assert( esuf[2*f+1] == -1, "outside boundary element not -1" );
-
-        std::size_t el = static_cast< std::size_t >(esuf[2*f]);
-
-        auto ng = tk::NGfa(ndofel[el]);
-
-        // arrays for quadrature points
-        std::array< std::vector< real >, 2 > coordgp;
-        std::vector< real > wgp;
-
-        coordgp[0].resize( ng );
-        coordgp[1].resize( ng );
-        wgp.resize( ng );
-
-        // get quadrature point weights and coordinates for triangle
-        GaussQuadratureTri( ng, coordgp, wgp );
-
-        // Extract the left element coordinates
-        std::array< std::array< tk::real, 3>, 4 > coordel_l {{
-        {{ cx[ inpoel[4*el  ] ], cy[ inpoel[4*el  ] ], cz[ inpoel[4*el  ] ] }},
-        {{ cx[ inpoel[4*el+1] ], cy[ inpoel[4*el+1] ], cz[ inpoel[4*el+1] ] }},
-        {{ cx[ inpoel[4*el+2] ], cy[ inpoel[4*el+2] ], cz[ inpoel[4*el+2] ] }},
-        {{ cx[ inpoel[4*el+3] ], cy[ inpoel[4*el+3] ], cz[ inpoel[4*el+3] ] }} }};
-
-        // Compute the determinant of Jacobian matrix
-        auto detT_l =
-          Jacobian( coordel_l[0], coordel_l[1], coordel_l[2], coordel_l[3] );
-
-        // Extract the face coordinates
-        std::array< std::array< tk::real, 3>, 3 > coordfa {{
-          {{ cx[ inpofa[3*f  ] ], cy[ inpofa[3*f  ] ], cz[ inpofa[3*f  ] ] }},
-          {{ cx[ inpofa[3*f+1] ], cy[ inpofa[3*f+1] ], cz[ inpofa[3*f+1] ] }},
-          {{ cx[ inpofa[3*f+2] ], cy[ inpofa[3*f+2] ], cz[ inpofa[3*f+2] ] }} }};
-
-        std::array< real, 3 >
-          fn{{ geoFace(f,1), geoFace(f,2), geoFace(f,3) }};
-
-        // Gaussian quadrature
-        for (std::size_t igp=0; igp<ng; ++igp)
-        {
-          // Compute the coordinates of quadrature point at physical domain
-          auto gp = eval_gp( igp, coordfa, coordgp );
-
-          // If an rDG method is set up (P0P1), then, currently we compute the P1
-          // basis functions and solutions by default. This implies that P0P1 is
-          // unsupported in the p-adaptive DG (PDG). This is a workaround until
-          // we have rdofel, which is needed to distinguish between ndofs and
-          // rdofs per element for pDG.
-          std::size_t dof_el;
-          if (rdof > ndof)
-          {
-            dof_el = rdof;
-          }
-          else
-          {
-            dof_el = ndofel[el];
-          }
-
-          std::array< tk::real, 3> ref_gp_l{
-            Jacobian( coordel_l[0], gp, coordel_l[2], coordel_l[3] ) / detT_l,
-            Jacobian( coordel_l[0], coordel_l[1], gp, coordel_l[3] ) / detT_l,
-            Jacobian( coordel_l[0], coordel_l[1], coordel_l[2], gp ) / detT_l };
-
-          //Compute the basis functions for the left element
-          auto B_l = eval_basis( dof_el, ref_gp_l[0], ref_gp_l[1], ref_gp_l[2] );
-
-          auto wt = wgp[igp] * geoFace(f,0);<--- Variable 'wt' is assigned a value that is never used.
-
-          // Compute the state variables at the left element
-          auto ugp = evalPolynomialSol(mat_blk, intsharp, ncomp, nprim,
-            rdof, nmat, el, dof_el, inpoel, coord, geoElem, ref_gp_l, B_l, U, P);
-
-          Assert( ugp.size() == ncomp+nprim, "Incorrect size for "
-                  "appended boundary state vector" );
-
-          auto var = state( ncomp, mat_blk, ugp, gp[0], gp[1], gp[2], t, fn );
-
-          // Compute the numerical flux
-          auto fl = flux(mat_blk, fn, var, vel(ncomp, gp[0], gp[1], gp[2], t));
-
-          // Code below commented until details about the form of these terms in
-          // the \alpha_k g_k equations are sorted out.
-          // // Add RHS inverse deformation terms if necessary
-          // if (haveSolid)
-          //   solidTermsSurfInt( nmat, ndof, rdof, fn, el, er, solidx, geoElem, U,
-          //                      coordel_l, coordel_r, igp, coordgp, dt, fl );
-
-          // Add the surface integration term to the rhs
-          update_rhs_bc( ncomp, nmat, ndof, ndofel[el], wt, fn, el, fl,
-                         B_l, R, riemannDeriv );
-        }
-      }
-    }
-  }
-}
-
-void
-update_rhs_bc ( ncomp_t ncomp,
-                std::size_t nmat,
-                const std::size_t ndof,
-                const std::size_t ndof_l,
-                const tk::real wt,
-                const std::array< tk::real, 3 >& fn,
-                const std::size_t el,
-                const std::vector< tk::real >& fl,
-                const std::vector< tk::real >& B_l,
-                Fields& R,<--- Parameter 'R' can be declared with const
-                std::vector< std::vector< tk::real > >& riemannDeriv )
-// *****************************************************************************
-//  Update the rhs by adding the boundary surface integration term
-//! \param[in] ncomp Number of scalar components in this PDE system
-//! \param[in] nmat Number of materials in this PDE system
-//! \param[in] ndof Maximum number of degrees of freedom
-//! \param[in] ndof_l Number of degrees of freedom for the left element
-//! \param[in] wt Weight of gauss quadrature point
-//! \param[in] fn Face/Surface normal
-//! \param[in] el Left element index
-//! \param[in] fl Surface flux
-//! \param[in] B_l Basis function for the left element
-//! \param[in,out] R Right-hand side vector computed
-//! \param[in,out] riemannDeriv Derivatives of partial-pressures and velocities
-//!   computed from the Riemann solver for use in the non-conservative terms.
-//!   These derivatives are used only for multi-material hydro and unused for
-//!   single-material compflow and linear transport.
-// *****************************************************************************
-{
-  // following line commented until rdofel is made available.
-  //Assert( B_l.size() == ndof_l, "Size mismatch" );
-
-  using inciter::newSolidsAccFn;
-
-  const auto& solidx =
-    inciter::g_inputdeck.get< tag::matidxmap, tag::solidx >();
-
-  for (ncomp_t c=0; c<ncomp; ++c)
-  {
-    auto mark = c*ndof;
-    R(el, mark) -= wt * fl[c];
-
-    if(ndof_l > 1)          //DG(P1)
-    {
-      R(el, mark+1) -= wt * fl[c] * B_l[1];
-      R(el, mark+2) -= wt * fl[c] * B_l[2];
-      R(el, mark+3) -= wt * fl[c] * B_l[3];
-    }
-
-    if(ndof_l > 4)          //DG(P2)
-    {
-      R(el, mark+4) -= wt * fl[c] * B_l[4];
-      R(el, mark+5) -= wt * fl[c] * B_l[5];
-      R(el, mark+6) -= wt * fl[c] * B_l[6];
-      R(el, mark+7) -= wt * fl[c] * B_l[7];
-      R(el, mark+8) -= wt * fl[c] * B_l[8];
-      R(el, mark+9) -= wt * fl[c] * B_l[9];
-    }
-  }
-
-  // Prep for non-conservative terms in multimat
-  if (fl.size() > ncomp)
-  {
-    // Gradients of partial pressures
-    for (std::size_t k=0; k<nmat; ++k)
-    {
-      for (std::size_t idir=0; idir<3; ++idir)
-        riemannDeriv[3*k+idir][el] += wt * fl[ncomp+k] * fn[idir];
-    }
-
-    // Divergence of velocity multiples basis fucntion( d(uB) / dx )
-    for(std::size_t idof = 0; idof < ndof; idof++)
-      riemannDeriv[3*nmat+idof][el] += wt * fl[ncomp+nmat] * B_l[idof];
-
-    // Divergence of asigma: d(asig_ij)/dx_j
-    for (std::size_t k=0; k<nmat; ++k)
-      if (solidx[k] > 0)
-      {
-        std::size_t mark = ncomp+nmat+1+3*(solidx[k]-1);
-
-        for (std::size_t i=0; i<3; ++i)
-          riemannDeriv[3*nmat+ndof+3*(solidx[k]-1)+i][el] -=
-            wt * fl[mark+i];
-      }
-  }
-}
-
-void
-bndSurfIntFV(
-  std::size_t nmat,
-  const std::vector< inciter::EOS >& mat_blk,
-  const std::size_t rdof,
-  const std::vector< std::size_t >& bcconfig,
-  const inciter::FaceData& fd,
-  const Fields& geoFace,
-  const Fields& geoElem,
-  const std::vector< std::size_t >& inpoel,
-  const UnsMesh::Coords& coord,
-  real t,
-  const RiemannFluxFn& flux,
-  const VelFn& vel,
-  const StateFn& state,
-  const Fields& U,
-  const Fields& P,
-  const std::vector< int >& srcFlag,
-  Fields& R,
-  int intsharp )
-// *****************************************************************************
-//! Compute boundary surface flux integrals for a given boundary type for FV
-//! \details This function computes contributions from surface integrals along
-//!   all faces for a particular boundary condition type, configured by the state
-//!   function
-//! \param[in] nmat Number of materials in this PDE system
-//! \param[in] mat_blk EOS material block
-//! \param[in] rdof Maximum number of reconstructed degrees of freedom
-//! \param[in] bcconfig BC configuration vector for multiple side sets
-//! \param[in] fd Face connectivity and boundary conditions object
-//! \param[in] geoFace Face geometry array
-//! \param[in] geoElem Element geometry array
-//! \param[in] inpoel Element-node connectivity
-//! \param[in] coord Array of nodal coordinates
-//! \param[in] t Physical time
-//! \param[in] flux Riemann flux function to use
-//! \param[in] vel Function to use to query prescribed velocity (if any)
-//! \param[in] state Function to evaluate the left and right solution state at
-//!   boundaries
-//! \param[in] U Solution vector at recent time step
-//! \param[in] P Vector of primitives at recent time step
-//! \param[in] srcFlag Whether the energy source was added
-//! \param[in,out] R Right-hand side vector computed
-//! \param[in] intsharp Interface compression tag, an optional argument, with
-//!   default 0, so that it is unused for single-material and transport.
-// *****************************************************************************
-{
-  const auto& bface = fd.Bface();
-  const auto& esuf = fd.Esuf();
-
-  const auto& cx = coord[0];
-  const auto& cy = coord[1];
-  const auto& cz = coord[2];
-
-  auto ncomp = U.nprop()/rdof;<--- Variable 'ncomp' is assigned a value that is never used.
-  auto nprim = P.nprop()/rdof;<--- Variable 'nprim' is assigned a value that is never used.
-
-  for (const auto& s : bcconfig) {       // for all bc sidesets
-    auto bc = bface.find(static_cast<int>(s));// faces for side set
-    if (bc != end(bface))
-    {
-      for (const auto& f : bc->second)
-      {
-        Assert( esuf[2*f+1] == -1, "outside boundary element not -1" );
-
-        std::size_t el = static_cast< std::size_t >(esuf[2*f]);
-
-        // Extract the left element coordinates
-        std::array< std::array< tk::real, 3>, 4 > coordel_l {{
-        {{ cx[ inpoel[4*el  ] ], cy[ inpoel[4*el  ] ], cz[ inpoel[4*el  ] ] }},
-        {{ cx[ inpoel[4*el+1] ], cy[ inpoel[4*el+1] ], cz[ inpoel[4*el+1] ] }},
-        {{ cx[ inpoel[4*el+2] ], cy[ inpoel[4*el+2] ], cz[ inpoel[4*el+2] ] }},
-        {{ cx[ inpoel[4*el+3] ], cy[ inpoel[4*el+3] ], cz[ inpoel[4*el+3] ] }} }};
-
-        // Compute the determinant of Jacobian matrix
-        auto detT_l =
-          Jacobian( coordel_l[0], coordel_l[1], coordel_l[2], coordel_l[3] );
-
-        // face normal
-        std::array< real, 3 >
-          fn{{ geoFace(f,1), geoFace(f,2), geoFace(f,3) }};
-
-        // face centroid
-        std::array< real, 3 >
-          gp{{ geoFace(f,4), geoFace(f,5), geoFace(f,6) }};
-
-        std::array< tk::real, 3> ref_gp_l{
-          Jacobian( coordel_l[0], gp, coordel_l[2], coordel_l[3] ) / detT_l,
-          Jacobian( coordel_l[0], coordel_l[1], gp, coordel_l[3] ) / detT_l,
-          Jacobian( coordel_l[0], coordel_l[1], coordel_l[2], gp ) / detT_l };
-
-        //Compute the basis functions for the left element
-        auto B_l = eval_basis( rdof, ref_gp_l[0], ref_gp_l[1], ref_gp_l[2] );
-
-        // Compute the state variables at the left element
-        auto ugp = evalFVSol(mat_blk, intsharp, ncomp, nprim,
-          rdof, nmat, el, inpoel, coord, geoElem, ref_gp_l, B_l, U, P,
-          srcFlag[el]);
-
-        Assert( ugp.size() == ncomp+nprim, "Incorrect size for "
-                "appended boundary state vector" );
-
-        auto var = state( ncomp, mat_blk, ugp, gp[0], gp[1], gp[2], t, fn );
-
-        // Compute the numerical flux
-        auto fl = flux( mat_blk, fn, var, vel(ncomp, gp[0], gp[1], gp[2], t) );
-
-        // compute non-conservative terms
-        std::vector< tk::real > var_riemann(nmat+1, 0.0);
-        for (std::size_t k=0; k<nmat+1; ++k) var_riemann[k] = fl[ncomp+k];
-
-        auto ncf_l = nonConservativeIntFV(nmat, rdof, el, fn, U, P, var_riemann);
-
-        // Add the surface integration term to the rhs
-        for (ncomp_t c=0; c<ncomp; ++c)
-        {
-          R(el, c) -= geoFace(f,0) * (fl[c] - ncf_l[c]);
-        }
-      }
-    }
-  }
-}
-
-} // tk::
+  \brief     Functions for computing integrals of an arbitrary source term of a
+     for single-material compressible flow, CompFlow using DG methods
+  \details   This file contains functionality for computing integrals of an
+     arbitrary source term for single-material compressible flow, CompFlow with
+     discontinuous Galerkin methods for various orders of numerical
+     representation.
+*/
+// *****************************************************************************
+
+#include <vector>
+
+#include "Source.hpp"
+#include "Quadrature.hpp"
+
+void
+tk::srcInt( const std::vector< inciter::EOS >& mat_blk,
+            real t,
+            const std::size_t ndof,
+            const std::size_t nelem,
+            const std::vector< std::size_t >& inpoel,
+            const UnsMesh::Coords& coord,
+            const Fields& geoElem,
+            const SrcFn& src,
+            const std::vector< std::size_t >& ndofel,
+            Fields& R,
+            std::size_t nmat )
+// *****************************************************************************
+//  Compute source term integrals for DG
+//! \param[in] mat_blk Material block EOS
+//! \param[in] t Physical time
+//! \param[in] ndof Maximum number of degrees of freedom
+//! \param[in] nelem Maximum number of elements
+//! \param[in] inpoel Element-node connectivity
+//! \param[in] coord Array of nodal coordinates
+//! \param[in] geoElem Element geometry array
+//! \param[in] src Source function to use
+//! \param[in] ndofel Vector of local number of degrees of freedome
+//! \param[in,out] R Right-hand side vector computed
+//! \param[in] nmat Number of materials. A default is set to 1, so that calling
+//!   code for single material systems primitive quantities does not need to
+//!   specify this argument.
+// *****************************************************************************
+{
+  auto ncomp = R.nprop()/ndof;
+  const auto& cx = coord[0];
+  const auto& cy = coord[1];
+  const auto& cz = coord[2];
+
+  for (std::size_t e=0; e<nelem; ++e)
+  {
+    auto ng = tk::NGvol(ndofel[e]);
+
+    // arrays for quadrature points
+    std::array< std::vector< real >, 3 > coordgp;
+    std::vector< real > wgp;
+
+    coordgp[0].resize( ng );
+    coordgp[1].resize( ng );
+    coordgp[2].resize( ng );
+    wgp.resize( ng );
+
+    GaussQuadratureTet( ng, coordgp, wgp );
+
+    // Extract the element coordinates
+    std::array< std::array< real, 3>, 4 > coordel {{
+      {{ cx[ inpoel[4*e  ] ], cy[ inpoel[4*e  ] ], cz[ inpoel[4*e  ] ] }},
+      {{ cx[ inpoel[4*e+1] ], cy[ inpoel[4*e+1] ], cz[ inpoel[4*e+1] ] }},
+      {{ cx[ inpoel[4*e+2] ], cy[ inpoel[4*e+2] ], cz[ inpoel[4*e+2] ] }},
+      {{ cx[ inpoel[4*e+3] ], cy[ inpoel[4*e+3] ], cz[ inpoel[4*e+3] ] }} }};
+
+    for (std::size_t igp=0; igp<ng; ++igp)
+    {
+      // Compute the coordinates of quadrature point at physical domain
+      auto gp = eval_gp( igp, coordel, coordgp );
+
+      // Compute the basis function
+      auto B =
+        eval_basis( ndofel[e], coordgp[0][igp], coordgp[1][igp], coordgp[2][igp] );
+
+      // Compute the source term variable
+      std::vector< real > s(ncomp, 0.0);
+      src( nmat, mat_blk, gp[0], gp[1], gp[2], t, s );
+
+      auto wt = wgp[igp] * geoElem(e, 0);
+
+      update_rhs( ndof, ndofel[e], wt, e, B, s, R );
+    }
+  }
+}
+
+void
+tk::update_rhs( const std::size_t ndof,
+                const std::size_t ndof_el,
+                const tk::real wt,
+                const std::size_t e,
+                const std::vector< tk::real >& B,
+                const std::vector< tk::real >& s,
+                Fields& R )
+// *****************************************************************************
+//  Update the rhs by adding the source term integrals
+//! \param[in] ndof Maximum number of degrees of freedom
+//! \param[in] ndof_el Number of degrees of freedom for local element
+//! \param[in] wt Weight of gauss quadrature point
+//! \param[in] e Element index
+//! \param[in] B Vector of basis functions
+//! \param[in] s Source term vector
+//! \param[in,out] R Right-hand side vector computed
+// *****************************************************************************
+{
+  Assert( B.size() == ndof_el, "Size mismatch for basis function" );
+
+  for (ncomp_t c=0; c<s.size(); ++c)
+  {
+    auto mark = c*ndof;
+    R(e, mark)   += wt * s[c];
+
+    if ( ndof_el > 1 )
+    {
+      R(e, mark+1) += wt * s[c] * B[1];
+      R(e, mark+2) += wt * s[c] * B[2];
+      R(e, mark+3) += wt * s[c] * B[3];
+
+      if( ndof_el > 4 )
+      {
+        R(e, mark+4) += wt * s[c] * B[4];
+        R(e, mark+5) += wt * s[c] * B[5];
+        R(e, mark+6) += wt * s[c] * B[6];
+        R(e, mark+7) += wt * s[c] * B[7];
+        R(e, mark+8) += wt * s[c] * B[8];
+        R(e, mark+9) += wt * s[c] * B[9];
+      }
+    }
+  }
+}
+
+void
+tk::srcIntFV( const std::vector< inciter::EOS >& mat_blk,
+              real t,
+              const std::size_t nelem,
+              const Fields& geoElem,
+              const SrcFn& src,
+              Fields& R,<--- Parameter 'R' can be declared with const
+              std::size_t nmat )
+// *****************************************************************************
+//  Compute source term integrals for DG
+//! \param[in] mat_blk Material block EOS
+//! \param[in] t Physical time
+//! \param[in] nelem Maximum number of elements
+//! \param[in] geoElem Element geometry array
+//! \param[in] src Source function to use
+//! \param[in,out] R Right-hand side vector computed
+//! \param[in] nmat Number of materials. A default is set to 1, so that calling
+//!   code for single material systems primitive quantities does not need to
+//!   specify this argument.
+// *****************************************************************************
+{
+  auto ncomp = R.nprop();
+
+  for (std::size_t e=0; e<nelem; ++e)
+  {
+    // Compute the source term variable
+    std::vector< real > s(ncomp, 0.0);
+    src( nmat, mat_blk, geoElem(e,1), geoElem(e,2), geoElem(e,3), t, s );
+
+    // Add the source term to the rhs
+    for (ncomp_t c=0; c<ncomp; ++c)
+    {
+      R(e, c) += geoElem(e,0) * s[c];
+    }
+  }
+}
 
diff --git a/Release/cppcheck/63.html b/Release/cppcheck/63.html index e25570203d5e..b5f55924b656 100644 --- a/Release/cppcheck/63.html +++ b/Release/cppcheck/63.html @@ -152,12 +152,12 @@
  1
@@ -337,184 +337,244 @@ 

Cppcheck report - [

// *****************************************************************************
+178
+179
+180
+181
+182
+183
+184
+185
+186
+187
+188
+189
+190
+191
+192
+193
+194
+195
+196
+197
+198
+199
+200
+201
+202
+203
+204
+205
+206
+207
+208
// *****************************************************************************
 /*!
-  \file      src/PDE/Integrate/Source.cpp
+  \file      src/PDE/Integrate/Initialize.cpp
   \copyright 2012-2015 J. Bakosi,
              2016-2018 Los Alamos National Security, LLC.,
              2019-2021 Triad National Security, LLC.
              All rights reserved. See the LICENSE file for details.
-  \brief     Functions for computing integrals of an arbitrary source term of a
-     for single-material compressible flow, CompFlow using DG methods
-  \details   This file contains functionality for computing integrals of an
-     arbitrary source term for single-material compressible flow, CompFlow with
-     discontinuous Galerkin methods for various orders of numerical
-     representation.
-*/
-// *****************************************************************************
-
-#include <vector>
-
-#include "Source.hpp"
+  \brief     Functions for initialization of system of PDEs in DG methods
+  \details   This file contains functionality for setting initial conditions
+     and evaluating known solutions used in discontinuous Galerkin methods for
+     various orders of numerical representation.
+*/
+// *****************************************************************************
+
+#include <array>
+#include <vector>
+#include <iostream>
+#include "Data.hpp"
+#include "Initialize.hpp"
 #include "Quadrature.hpp"
-
-void
-tk::srcInt( const std::vector< inciter::EOS >& mat_blk,
-            real t,
-            const std::size_t ndof,
-            const std::size_t nelem,
-            const std::vector< std::size_t >& inpoel,
-            const UnsMesh::Coords& coord,
-            const Fields& geoElem,
-            const SrcFn& src,
-            const std::vector< std::size_t >& ndofel,
-            Fields& R,
-            std::size_t nmat )
-// *****************************************************************************
-//  Compute source term integrals for DG
-//! \param[in] mat_blk Material block EOS
-//! \param[in] t Physical time
-//! \param[in] ndof Maximum number of degrees of freedom
-//! \param[in] nelem Maximum number of elements
-//! \param[in] inpoel Element-node connectivity
-//! \param[in] coord Array of nodal coordinates
-//! \param[in] geoElem Element geometry array
-//! \param[in] src Source function to use
-//! \param[in] ndofel Vector of local number of degrees of freedome
-//! \param[in,out] R Right-hand side vector computed
-//! \param[in] nmat Number of materials. A default is set to 1, so that calling
-//!   code for single material systems primitive quantities does not need to
-//!   specify this argument.
-// *****************************************************************************
-{
-  auto ncomp = R.nprop()/ndof;
-  const auto& cx = coord[0];
-  const auto& cy = coord[1];
-  const auto& cz = coord[2];
-
-  for (std::size_t e=0; e<nelem; ++e)
-  {
-    auto ng = tk::NGvol(ndofel[e]);
+#include "Inciter/InputDeck/InputDeck.hpp"
+
+namespace inciter {
+
+extern ctr::InputDeck g_inputdeck;
+
+} // inciter::
+
+void
+tk::initialize( ncomp_t ncomp,
+                const std::vector< inciter::EOS >& mat_blk,
+                const Fields& L,
+                const std::vector< std::size_t >& inpoel,
+                const UnsMesh::Coords& coord,
+                const InitializeFn& solution,
+                Fields& unk,
+                real t,
+                const std::size_t nielem )
+// *****************************************************************************
+//! Initalize a system of DGPDEs by projecting the exact solution in the DG
+//! solution space
+//! \details This is the public interface exposed to client code.
+//! \param[in] ncomp Number of scalar components in this PDE system
+//! \param[in] L Block diagonal mass matrix
+//! \param[in] inpoel Element-node connectivity
+//! \param[in] coord Array of node coordinates
+//! \param[in] solution Function to call to evaluate known solution or initial
+//!   conditions at x,y,z,t
+//! \param[in,out] unk Array of unknowns
+//! \param[in] t Physical time
+//! \param[in] nielem Number of internal elements
+// *****************************************************************************
+{
+  const auto ndof = inciter::g_inputdeck.get< tag::ndof >();
+  const auto rdof = inciter::g_inputdeck.get< tag::rdof >();
+
+  // Number of quadrature points for volume integration
+  auto ng = tk::NGinit(ndof);
 
-    // arrays for quadrature points
-    std::array< std::vector< real >, 3 > coordgp;
-    std::vector< real > wgp;
+  // arrays for quadrature points
+  std::array< std::vector< real >, 3 > coordgp;
+  std::vector< real > wgp;
 
-    coordgp[0].resize( ng );
-    coordgp[1].resize( ng );
-    coordgp[2].resize( ng );
-    wgp.resize( ng );
+  coordgp[0].resize( ng );
+  coordgp[1].resize( ng );
+  coordgp[2].resize( ng );
+  wgp.resize( ng );
 
-    GaussQuadratureTet( ng, coordgp, wgp );
-
-    // Extract the element coordinates
-    std::array< std::array< real, 3>, 4 > coordel {{
-      {{ cx[ inpoel[4*e  ] ], cy[ inpoel[4*e  ] ], cz[ inpoel[4*e  ] ] }},
-      {{ cx[ inpoel[4*e+1] ], cy[ inpoel[4*e+1] ], cz[ inpoel[4*e+1] ] }},
-      {{ cx[ inpoel[4*e+2] ], cy[ inpoel[4*e+2] ], cz[ inpoel[4*e+2] ] }},
-      {{ cx[ inpoel[4*e+3] ], cy[ inpoel[4*e+3] ], cz[ inpoel[4*e+3] ] }} }};
-
-    for (std::size_t igp=0; igp<ng; ++igp)
-    {
-      // Compute the coordinates of quadrature point at physical domain
-      auto gp = eval_gp( igp, coordel, coordgp );
-
-      // Compute the basis function
-      auto B =
-        eval_basis( ndofel[e], coordgp[0][igp], coordgp[1][igp], coordgp[2][igp] );
+  // get quadrature point weights and coordinates for triangle
+  GaussQuadratureTet( ng, coordgp, wgp );
+
+  const auto& cx = coord[0];
+  const auto& cy = coord[1];
+  const auto& cz = coord[2];
+
+  for (std::size_t e=0; e<nielem; ++e) {    // for all tets
+    // The volume of tetrahedron
+    auto vole = L(e, 0);
+
+    // Extract the element coordinates
+    std::array< std::array< real, 3>, 4 > coordel {{
+      {{ cx[ inpoel[4*e  ] ], cy[ inpoel[4*e  ] ], cz[ inpoel[4*e  ] ] }},
+      {{ cx[ inpoel[4*e+1] ], cy[ inpoel[4*e+1] ], cz[ inpoel[4*e+1] ] }},
+      {{ cx[ inpoel[4*e+2] ], cy[ inpoel[4*e+2] ], cz[ inpoel[4*e+2] ] }},
+      {{ cx[ inpoel[4*e+3] ], cy[ inpoel[4*e+3] ], cz[ inpoel[4*e+3] ] }} }};
 
-      // Compute the source term variable
-      std::vector< real > s(ncomp, 0.0);
-      src( nmat, mat_blk, gp[0], gp[1], gp[2], t, s );
-
-      auto wt = wgp[igp] * geoElem(e, 0);
-
-      update_rhs( ndof, ndofel[e], wt, e, B, s, R );
-    }
-  }
-}
-
-void
-tk::update_rhs( const std::size_t ndof,
-                const std::size_t ndof_el,
-                const tk::real wt,
-                const std::size_t e,
-                const std::vector< tk::real >& B,
-                const std::vector< tk::real >& s,
-                Fields& R )
-// *****************************************************************************
-//  Update the rhs by adding the source term integrals
-//! \param[in] ndof Maximum number of degrees of freedom
-//! \param[in] ndof_el Number of degrees of freedom for local element
-//! \param[in] wt Weight of gauss quadrature point
-//! \param[in] e Element index
-//! \param[in] B Vector of basis functions
-//! \param[in] s Source term vector
-//! \param[in,out] R Right-hand side vector computed
-// *****************************************************************************
-{
-  Assert( B.size() == ndof_el, "Size mismatch for basis function" );
-
-  for (ncomp_t c=0; c<s.size(); ++c)
-  {
-    auto mark = c*ndof;
-    R(e, mark)   += wt * s[c];
-
-    if ( ndof_el > 1 )
-    {
-      R(e, mark+1) += wt * s[c] * B[1];
-      R(e, mark+2) += wt * s[c] * B[2];
-      R(e, mark+3) += wt * s[c] * B[3];
-
-      if( ndof_el > 4 )
-      {
-        R(e, mark+4) += wt * s[c] * B[4];
-        R(e, mark+5) += wt * s[c] * B[5];
-        R(e, mark+6) += wt * s[c] * B[6];
-        R(e, mark+7) += wt * s[c] * B[7];
-        R(e, mark+8) += wt * s[c] * B[8];
-        R(e, mark+9) += wt * s[c] * B[9];
-      }
-    }
-  }
-}
-
-void
-tk::srcIntFV( const std::vector< inciter::EOS >& mat_blk,
-              real t,
-              const std::size_t nelem,
-              const Fields& geoElem,
-              const SrcFn& src,
-              Fields& R,<--- Parameter 'R' can be declared with const
-              std::size_t nmat )
-// *****************************************************************************
-//  Compute source term integrals for DG
-//! \param[in] mat_blk Material block EOS
-//! \param[in] t Physical time
-//! \param[in] nelem Maximum number of elements
-//! \param[in] geoElem Element geometry array
-//! \param[in] src Source function to use
-//! \param[in,out] R Right-hand side vector computed
-//! \param[in] nmat Number of materials. A default is set to 1, so that calling
-//!   code for single material systems primitive quantities does not need to
-//!   specify this argument.
-// *****************************************************************************
-{
-  auto ncomp = R.nprop();
-
-  for (std::size_t e=0; e<nelem; ++e)
-  {
-    // Compute the source term variable
-    std::vector< real > s(ncomp, 0.0);
-    src( nmat, mat_blk, geoElem(e,1), geoElem(e,2), geoElem(e,3), t, s );
-
-    // Add the source term to the rhs
-    for (ncomp_t c=0; c<ncomp; ++c)
-    {
-      R(e, c) += geoElem(e,0) * s[c];
-    }
-  }
-}
+    // right hand side vector
+    std::vector< real > R( ncomp*ndof, 0.0 );
+
+    // Gaussian quadrature
+    for (std::size_t igp=0; igp<ng; ++igp)
+    {
+      // Compute the coordinates of quadrature point at physical domain
+      auto gp = eval_gp( igp, coordel, coordgp );
+
+      // Compute the basis function
+      auto B =
+        eval_basis( ndof, coordgp[0][igp], coordgp[1][igp], coordgp[2][igp] );
+
+      const auto s = solution( ncomp, mat_blk, gp[0], gp[1], gp[2], t );
+
+      auto wt = wgp[igp] * vole;
+
+      update_rhs( ncomp, ndof, wt, B, s, R );
+    }
+
+    // Compute the initial conditions
+    eval_init(ncomp, ndof, rdof, e, R, L, unk);
+  }
+}
+
+void
+tk::update_rhs( ncomp_t ncomp,
+                const std::size_t ndof,
+                const tk::real wt,
+                const std::vector< tk::real >& B,
+                const std::vector< tk::real >& s,
+                std::vector< tk::real >& R )
+// *****************************************************************************
+//  Update the rhs by adding the initial analytical solution term
+//! \param[in] ncomp Number of scalar components in this PDE system
+//! \param[in] ndof Number of degrees of freedom
+//! \param[in] wt Weight of gauss quadrature point
+//! \param[in] B Vector of basis functions
+//! \param[in] s Vector of analytical solution at quadrature point
+//! \param[in,out] R Right-hand side vector
+// *****************************************************************************
+{
+  Assert( B.size() == ndof, "Size mismatch for basis function" );
+  Assert( s.size() >= ncomp, "Size mismatch for source term" );
+
+  for (ncomp_t c=0; c<ncomp; ++c)
+  {
+    // DG(P0)
+    auto mark = c*ndof;
+    R[mark] += wt * s[c];
+
+    if(ndof > 1)         //DG(P1)
+    {
+      R[mark+1] += wt * s[c] * B[1];
+      R[mark+2] += wt * s[c] * B[2];
+      R[mark+3] += wt * s[c] * B[3];
+
+      if(ndof > 4)      //DG(P2)
+      {
+        R[mark+4] += wt * s[c] * B[4];
+        R[mark+5] += wt * s[c] * B[5];
+        R[mark+6] += wt * s[c] * B[6];
+        R[mark+7] += wt * s[c] * B[7];
+        R[mark+8] += wt * s[c] * B[8];
+        R[mark+9] += wt * s[c] * B[9];
+      }
+    }
+  }
+}
+
+void
+tk::eval_init( ncomp_t ncomp,
+               const std::size_t ndof,
+               const std::size_t rdof,
+               const std::size_t e,
+               const std::vector< tk::real >& R,
+               const Fields& L,
+               Fields& unk )<--- Parameter 'unk' can be declared with const
+// *****************************************************************************
+//  Compute the initial conditions
+//! \param[in] ncomp Number of scalar components in this PDE system
+//! \param[in] ndof Number of degrees of freedom
+//! \param[in] rdof Total number of reconstructed degrees of freedom
+//! \param[in] e Element index
+//! \param[in] R Right-hand side vector
+//! \param[in] L Block diagonal mass matrix
+//! \param[in,out] unk Array of unknowns
+// *****************************************************************************
+{
+  for (ncomp_t c=0; c<ncomp; ++c)
+  {
+    // DG(P0)
+    auto mark = c*ndof;
+    auto rmark = c*rdof;
+    unk(e, rmark) = R[mark] / L(e, mark);
+
+    // if P0P1, initialize higher dofs to 0
+    if (rdof > ndof)
+    {
+      unk(e, rmark+1) = 0.0;
+      unk(e, rmark+2) = 0.0;
+      unk(e, rmark+3) = 0.0;
+    }
+
+    if(ndof > 1)          // DG(P1)
+    {
+      unk(e, rmark+1) = R[mark+1] / L(e, mark+1);
+      unk(e, rmark+2) = R[mark+2] / L(e, mark+2);
+      unk(e, rmark+3) = R[mark+3] / L(e, mark+3);
+ 
+      if(ndof > 4)        // DG(P2)
+      {
+        unk(e, rmark+4) = R[mark+4] / L(e, mark+4);
+        unk(e, rmark+5) = R[mark+5] / L(e, mark+5);
+        unk(e, rmark+6) = R[mark+6] / L(e, mark+6);
+        unk(e, rmark+7) = R[mark+7] / L(e, mark+7);
+        unk(e, rmark+8) = R[mark+8] / L(e, mark+8);
+        unk(e, rmark+9) = R[mark+9] / L(e, mark+9);
+      }
+    }
+  }
+}
 
diff --git a/Release/cppcheck/64.html b/Release/cppcheck/64.html index 2362a3467077..e9063e2865dd 100644 --- a/Release/cppcheck/64.html +++ b/Release/cppcheck/64.html @@ -152,12 +152,12 @@
  1
@@ -367,214 +367,634 @@ 

Cppcheck report - [

// *****************************************************************************
+208
+209
+210
+211
+212
+213
+214
+215
+216
+217
+218
+219
+220
+221
+222
+223
+224
+225
+226
+227
+228
+229
+230
+231
+232
+233
+234
+235
+236
+237
+238
+239
+240
+241
+242
+243
+244
+245
+246
+247
+248
+249
+250
+251
+252
+253
+254
+255
+256
+257
+258
+259
+260
+261
+262
+263
+264
+265
+266
+267
+268
+269
+270
+271
+272
+273
+274
+275
+276
+277
+278
+279
+280
+281
+282
+283
+284
+285
+286
+287
+288
+289
+290
+291
+292
+293
+294
+295
+296
+297
+298
+299
+300
+301
+302
+303
+304
+305
+306
+307
+308
+309
+310
+311
+312
+313
+314
+315
+316
+317
+318
+319
+320
+321
+322
+323
+324
+325
+326
+327
+328
+329
+330
+331
+332
+333
+334
+335
+336
+337
+338
+339
+340
+341
+342
+343
+344
+345
+346
+347
+348
+349
+350
+351
+352
+353
+354
+355
+356
+357
+358
+359
+360
+361
+362
+363
+364
+365
+366
+367
+368
+369
+370
+371
+372
+373
+374
+375
+376
+377
+378
+379
+380
+381
+382
+383
+384
+385
+386
+387
+388
+389
+390
+391
+392
+393
+394
+395
+396
+397
+398
+399
+400
+401
+402
+403
+404
+405
+406
+407
+408
+409
+410
+411
+412
+413
+414
+415
+416
+417
+418
// *****************************************************************************
 /*!
-  \file      src/PDE/Integrate/Initialize.cpp
+  \file      src/PDE/Integrate/Boundary.cpp
   \copyright 2012-2015 J. Bakosi,
              2016-2018 Los Alamos National Security, LLC.,
              2019-2021 Triad National Security, LLC.
              All rights reserved. See the LICENSE file for details.
-  \brief     Functions for initialization of system of PDEs in DG methods
-  \details   This file contains functionality for setting initial conditions
-     and evaluating known solutions used in discontinuous Galerkin methods for
-     various orders of numerical representation.
-*/
-// *****************************************************************************
-
-#include <array>
-#include <vector>
-#include <iostream>
-#include "Data.hpp"
-#include "Initialize.hpp"
-#include "Quadrature.hpp"
-#include "Inciter/InputDeck/InputDeck.hpp"
-
-namespace inciter {
-
-extern ctr::InputDeck g_inputdeck;
+  \brief     Functions for computing physical boundary surface integrals of a
+     system of PDEs in DG methods
+  \details   This file contains functionality for computing physical boundary
+     surface integrals of a system of PDEs used in discontinuous Galerkin
+     methods for various orders of numerical representation.
+*/
+// *****************************************************************************
+
+#include <array>
+
+#include "Basis.hpp"
+#include "Boundary.hpp"
+#include "Vector.hpp"
+#include "Quadrature.hpp"
+#include "MultiMatTerms.hpp"
+#include "MultiMat/MultiMatIndexing.hpp"
+#include "Reconstruction.hpp"
+#include "Inciter/InputDeck/InputDeck.hpp"
 
-} // inciter::
-
-void
-tk::initialize( ncomp_t ncomp,
-                const std::vector< inciter::EOS >& mat_blk,
-                const Fields& L,
-                const std::vector< std::size_t >& inpoel,
-                const UnsMesh::Coords& coord,
-                const InitializeFn& solution,
-                Fields& unk,
-                real t,
-                const std::size_t nielem )
-// *****************************************************************************
-//! Initalize a system of DGPDEs by projecting the exact solution in the DG
-//! solution space
-//! \details This is the public interface exposed to client code.
-//! \param[in] ncomp Number of scalar components in this PDE system
-//! \param[in] L Block diagonal mass matrix
-//! \param[in] inpoel Element-node connectivity
-//! \param[in] coord Array of node coordinates
-//! \param[in] solution Function to call to evaluate known solution or initial
-//!   conditions at x,y,z,t
-//! \param[in,out] unk Array of unknowns
-//! \param[in] t Physical time
-//! \param[in] nielem Number of internal elements
-// *****************************************************************************
-{
-  const auto ndof = inciter::g_inputdeck.get< tag::ndof >();
-  const auto rdof = inciter::g_inputdeck.get< tag::rdof >();
-
-  // Number of quadrature points for volume integration
-  auto ng = tk::NGinit(ndof);
-
-  // arrays for quadrature points
-  std::array< std::vector< real >, 3 > coordgp;
-  std::vector< real > wgp;
-
-  coordgp[0].resize( ng );
-  coordgp[1].resize( ng );
-  coordgp[2].resize( ng );
-  wgp.resize( ng );
-
-  // get quadrature point weights and coordinates for triangle
-  GaussQuadratureTet( ng, coordgp, wgp );
-
-  const auto& cx = coord[0];
-  const auto& cy = coord[1];
-  const auto& cz = coord[2];
-
-  for (std::size_t e=0; e<nielem; ++e) {    // for all tets
-    // The volume of tetrahedron
-    auto vole = L(e, 0);
-
-    // Extract the element coordinates
-    std::array< std::array< real, 3>, 4 > coordel {{
-      {{ cx[ inpoel[4*e  ] ], cy[ inpoel[4*e  ] ], cz[ inpoel[4*e  ] ] }},
-      {{ cx[ inpoel[4*e+1] ], cy[ inpoel[4*e+1] ], cz[ inpoel[4*e+1] ] }},
-      {{ cx[ inpoel[4*e+2] ], cy[ inpoel[4*e+2] ], cz[ inpoel[4*e+2] ] }},
-      {{ cx[ inpoel[4*e+3] ], cy[ inpoel[4*e+3] ], cz[ inpoel[4*e+3] ] }} }};
-
-    // right hand side vector
-    std::vector< real > R( ncomp*ndof, 0.0 );
-
-    // Gaussian quadrature
-    for (std::size_t igp=0; igp<ng; ++igp)
-    {
-      // Compute the coordinates of quadrature point at physical domain
-      auto gp = eval_gp( igp, coordel, coordgp );
-
-      // Compute the basis function
-      auto B =
-        eval_basis( ndof, coordgp[0][igp], coordgp[1][igp], coordgp[2][igp] );
-
-      const auto s = solution( ncomp, mat_blk, gp[0], gp[1], gp[2], t );
-
-      auto wt = wgp[igp] * vole;
-
-      update_rhs( ncomp, ndof, wt, B, s, R );
-    }
-
-    // Compute the initial conditions
-    eval_init(ncomp, ndof, rdof, e, R, L, unk);
-  }
-}
-
-void
-tk::update_rhs( ncomp_t ncomp,
-                const std::size_t ndof,
-                const tk::real wt,
-                const std::vector< tk::real >& B,
-                const std::vector< tk::real >& s,
-                std::vector< tk::real >& R )
-// *****************************************************************************
-//  Update the rhs by adding the initial analytical solution term
-//! \param[in] ncomp Number of scalar components in this PDE system
-//! \param[in] ndof Number of degrees of freedom
-//! \param[in] wt Weight of gauss quadrature point
-//! \param[in] B Vector of basis functions
-//! \param[in] s Vector of analytical solution at quadrature point
-//! \param[in,out] R Right-hand side vector
-// *****************************************************************************
-{
-  Assert( B.size() == ndof, "Size mismatch for basis function" );
-  Assert( s.size() >= ncomp, "Size mismatch for source term" );
-
-  for (ncomp_t c=0; c<ncomp; ++c)
-  {
-    // DG(P0)
-    auto mark = c*ndof;
-    R[mark] += wt * s[c];
-
-    if(ndof > 1)         //DG(P1)
-    {
-      R[mark+1] += wt * s[c] * B[1];
-      R[mark+2] += wt * s[c] * B[2];
-      R[mark+3] += wt * s[c] * B[3];
-
-      if(ndof > 4)      //DG(P2)
-      {
-        R[mark+4] += wt * s[c] * B[4];
-        R[mark+5] += wt * s[c] * B[5];
-        R[mark+6] += wt * s[c] * B[6];
-        R[mark+7] += wt * s[c] * B[7];
-        R[mark+8] += wt * s[c] * B[8];
-        R[mark+9] += wt * s[c] * B[9];
-      }
-    }
-  }
-}
-
-void
-tk::eval_init( ncomp_t ncomp,
-               const std::size_t ndof,
-               const std::size_t rdof,
-               const std::size_t e,
-               const std::vector< tk::real >& R,
-               const Fields& L,
-               Fields& unk )<--- Parameter 'unk' can be declared with const
-// *****************************************************************************
-//  Compute the initial conditions
-//! \param[in] ncomp Number of scalar components in this PDE system
-//! \param[in] ndof Number of degrees of freedom
-//! \param[in] rdof Total number of reconstructed degrees of freedom
-//! \param[in] e Element index
-//! \param[in] R Right-hand side vector
-//! \param[in] L Block diagonal mass matrix
-//! \param[in,out] unk Array of unknowns
-// *****************************************************************************
-{
-  for (ncomp_t c=0; c<ncomp; ++c)
-  {
-    // DG(P0)
-    auto mark = c*ndof;
-    auto rmark = c*rdof;
-    unk(e, rmark) = R[mark] / L(e, mark);
+namespace inciter {
+extern ctr::InputDeck g_inputdeck;
+}
+
+namespace tk {
+
+void
+bndSurfInt( std::size_t nmat,
+            const std::vector< inciter::EOS >& mat_blk,
+            const std::size_t ndof,
+            const std::size_t rdof,
+            const std::vector< std::size_t >& bcconfig,
+            const inciter::FaceData& fd,
+            const Fields& geoFace,
+            const Fields& geoElem,
+            const std::vector< std::size_t >& inpoel,
+            const UnsMesh::Coords& coord,
+            real t,
+            const RiemannFluxFn& flux,
+            const VelFn& vel,
+            const StateFn& state,
+            const Fields& U,
+            const Fields& P,
+            const std::vector< std::size_t >& ndofel,
+            Fields& R,
+            std::vector< std::vector< tk::real > >&,
+            std::vector< std::vector< tk::real > >&,
+            std::vector< std::vector< tk::real > >& riemannDeriv,
+            int intsharp )
+// *****************************************************************************
+//! Compute boundary surface flux integrals for a given boundary type for DG
+//! \details This function computes contributions from surface integrals along
+//!   all faces for a particular boundary condition type, configured by the state
+//!   function
+//! \param[in] nmat Number of materials in this PDE system
+//! \param[in] mat_blk EOS material block
+//! \param[in] ndof Maximum number of degrees of freedom
+//! \param[in] rdof Maximum number of reconstructed degrees of freedom
+//! \param[in] bcconfig BC configuration vector for multiple side sets
+//! \param[in] fd Face connectivity and boundary conditions object
+//! \param[in] geoFace Face geometry array
+//! \param[in] geoElem Element geometry array
+//! \param[in] inpoel Element-node connectivity
+//! \param[in] coord Array of nodal coordinates
+//! \param[in] t Physical time
+//! \param[in] flux Riemann flux function to use
+//! \param[in] vel Function to use to query prescribed velocity (if any)
+//! \param[in] state Function to evaluate the left and right solution state at
+//!   boundaries
+//! \param[in] U Solution vector at recent time step
+//! \param[in] P Vector of primitives at recent time step
+//! \param[in] ndofel Vector of local number of degrees of freedom
+//! \param[in,out] R Right-hand side vector computed
+//! \param[in,out] vriem Vector of the riemann velocity
+//! \param[in,out] riemannLoc Vector of coordinates where Riemann velocity data
+//!   is available
+//! \param[in,out] riemannDeriv Derivatives of partial-pressures and velocities
+//!   computed from the Riemann solver for use in the non-conservative terms.
+//!   These derivatives are used only for multi-material hydro and unused for
+//!   single-material compflow and linear transport.
+//! \param[in] intsharp Interface compression tag, an optional argument, with
+//!   default 0, so that it is unused for single-material and transport.
+// *****************************************************************************
+{
+  const auto& bface = fd.Bface();
+  const auto& esuf = fd.Esuf();
+  const auto& inpofa = fd.Inpofa();
+
+  const auto& cx = coord[0];
+  const auto& cy = coord[1];
+  const auto& cz = coord[2];
+
+  auto ncomp = U.nprop()/rdof;<--- Variable 'ncomp' is assigned a value that is never used.
+  auto nprim = P.nprop()/rdof;<--- Variable 'nprim' is assigned a value that is never used.
+
+  //Assert( (nmat==1 ? riemannDeriv.empty() : true), "Non-empty Riemann "
+  //        "derivative vector for single material compflow" );
+
+  for (const auto& s : bcconfig) {       // for all bc sidesets
+    auto bc = bface.find(static_cast<int>(s));// faces for side set
+    if (bc != end(bface))
+    {
+      for (const auto& f : bc->second)
+      {
+        Assert( esuf[2*f+1] == -1, "outside boundary element not -1" );
+
+        std::size_t el = static_cast< std::size_t >(esuf[2*f]);
+
+        auto ng = tk::NGfa(ndofel[el]);
+
+        // arrays for quadrature points
+        std::array< std::vector< real >, 2 > coordgp;
+        std::vector< real > wgp;
+
+        coordgp[0].resize( ng );
+        coordgp[1].resize( ng );
+        wgp.resize( ng );
+
+        // get quadrature point weights and coordinates for triangle
+        GaussQuadratureTri( ng, coordgp, wgp );
+
+        // Extract the left element coordinates
+        std::array< std::array< tk::real, 3>, 4 > coordel_l {{
+        {{ cx[ inpoel[4*el  ] ], cy[ inpoel[4*el  ] ], cz[ inpoel[4*el  ] ] }},
+        {{ cx[ inpoel[4*el+1] ], cy[ inpoel[4*el+1] ], cz[ inpoel[4*el+1] ] }},
+        {{ cx[ inpoel[4*el+2] ], cy[ inpoel[4*el+2] ], cz[ inpoel[4*el+2] ] }},
+        {{ cx[ inpoel[4*el+3] ], cy[ inpoel[4*el+3] ], cz[ inpoel[4*el+3] ] }} }};
+
+        // Compute the determinant of Jacobian matrix
+        auto detT_l =
+          Jacobian( coordel_l[0], coordel_l[1], coordel_l[2], coordel_l[3] );
+
+        // Extract the face coordinates
+        std::array< std::array< tk::real, 3>, 3 > coordfa {{
+          {{ cx[ inpofa[3*f  ] ], cy[ inpofa[3*f  ] ], cz[ inpofa[3*f  ] ] }},
+          {{ cx[ inpofa[3*f+1] ], cy[ inpofa[3*f+1] ], cz[ inpofa[3*f+1] ] }},
+          {{ cx[ inpofa[3*f+2] ], cy[ inpofa[3*f+2] ], cz[ inpofa[3*f+2] ] }} }};
+
+        std::array< real, 3 >
+          fn{{ geoFace(f,1), geoFace(f,2), geoFace(f,3) }};
+
+        // Gaussian quadrature
+        for (std::size_t igp=0; igp<ng; ++igp)
+        {
+          // Compute the coordinates of quadrature point at physical domain
+          auto gp = eval_gp( igp, coordfa, coordgp );
+
+          // If an rDG method is set up (P0P1), then, currently we compute the P1
+          // basis functions and solutions by default. This implies that P0P1 is
+          // unsupported in the p-adaptive DG (PDG). This is a workaround until
+          // we have rdofel, which is needed to distinguish between ndofs and
+          // rdofs per element for pDG.
+          std::size_t dof_el;
+          if (rdof > ndof)
+          {
+            dof_el = rdof;
+          }
+          else
+          {
+            dof_el = ndofel[el];
+          }
+
+          std::array< tk::real, 3> ref_gp_l{
+            Jacobian( coordel_l[0], gp, coordel_l[2], coordel_l[3] ) / detT_l,
+            Jacobian( coordel_l[0], coordel_l[1], gp, coordel_l[3] ) / detT_l,
+            Jacobian( coordel_l[0], coordel_l[1], coordel_l[2], gp ) / detT_l };
+
+          //Compute the basis functions for the left element
+          auto B_l = eval_basis( dof_el, ref_gp_l[0], ref_gp_l[1], ref_gp_l[2] );
+
+          auto wt = wgp[igp] * geoFace(f,0);<--- Variable 'wt' is assigned a value that is never used.
+
+          // Compute the state variables at the left element
+          auto ugp = evalPolynomialSol(mat_blk, intsharp, ncomp, nprim,
+            rdof, nmat, el, dof_el, inpoel, coord, geoElem, ref_gp_l, B_l, U, P);
 
-    // if P0P1, initialize higher dofs to 0
-    if (rdof > ndof)
-    {
-      unk(e, rmark+1) = 0.0;
-      unk(e, rmark+2) = 0.0;
-      unk(e, rmark+3) = 0.0;
-    }
+          Assert( ugp.size() == ncomp+nprim, "Incorrect size for "
+                  "appended boundary state vector" );
+
+          auto var = state( ncomp, mat_blk, ugp, gp[0], gp[1], gp[2], t, fn );
+
+          // Compute the numerical flux
+          auto fl = flux(mat_blk, fn, var, vel(ncomp, gp[0], gp[1], gp[2], t));
 
-    if(ndof > 1)          // DG(P1)
-    {
-      unk(e, rmark+1) = R[mark+1] / L(e, mark+1);
-      unk(e, rmark+2) = R[mark+2] / L(e, mark+2);
-      unk(e, rmark+3) = R[mark+3] / L(e, mark+3);
- 
-      if(ndof > 4)        // DG(P2)
-      {
-        unk(e, rmark+4) = R[mark+4] / L(e, mark+4);
-        unk(e, rmark+5) = R[mark+5] / L(e, mark+5);
-        unk(e, rmark+6) = R[mark+6] / L(e, mark+6);
-        unk(e, rmark+7) = R[mark+7] / L(e, mark+7);
-        unk(e, rmark+8) = R[mark+8] / L(e, mark+8);
-        unk(e, rmark+9) = R[mark+9] / L(e, mark+9);
-      }
-    }
-  }
-}
+          // Code below commented until details about the form of these terms in
+          // the \alpha_k g_k equations are sorted out.
+          // // Add RHS inverse deformation terms if necessary
+          // if (haveSolid)
+          //   solidTermsSurfInt( nmat, ndof, rdof, fn, el, er, solidx, geoElem, U,
+          //                      coordel_l, coordel_r, igp, coordgp, dt, fl );
+
+          // Add the surface integration term to the rhs
+          update_rhs_bc( ncomp, nmat, ndof, ndofel[el], wt, fn, el, fl,
+                         B_l, R, riemannDeriv );
+        }
+      }
+    }
+  }
+}
+
+void
+update_rhs_bc ( ncomp_t ncomp,
+                std::size_t nmat,
+                const std::size_t ndof,
+                const std::size_t ndof_l,
+                const tk::real wt,
+                const std::array< tk::real, 3 >& fn,
+                const std::size_t el,
+                const std::vector< tk::real >& fl,
+                const std::vector< tk::real >& B_l,
+                Fields& R,<--- Parameter 'R' can be declared with const
+                std::vector< std::vector< tk::real > >& riemannDeriv )
+// *****************************************************************************
+//  Update the rhs by adding the boundary surface integration term
+//! \param[in] ncomp Number of scalar components in this PDE system
+//! \param[in] nmat Number of materials in this PDE system
+//! \param[in] ndof Maximum number of degrees of freedom
+//! \param[in] ndof_l Number of degrees of freedom for the left element
+//! \param[in] wt Weight of gauss quadrature point
+//! \param[in] fn Face/Surface normal
+//! \param[in] el Left element index
+//! \param[in] fl Surface flux
+//! \param[in] B_l Basis function for the left element
+//! \param[in,out] R Right-hand side vector computed
+//! \param[in,out] riemannDeriv Derivatives of partial-pressures and velocities
+//!   computed from the Riemann solver for use in the non-conservative terms.
+//!   These derivatives are used only for multi-material hydro and unused for
+//!   single-material compflow and linear transport.
+// *****************************************************************************
+{
+  // following line commented until rdofel is made available.
+  //Assert( B_l.size() == ndof_l, "Size mismatch" );
+
+  using inciter::newSolidsAccFn;
+
+  const auto& solidx =
+    inciter::g_inputdeck.get< tag::matidxmap, tag::solidx >();
+
+  for (ncomp_t c=0; c<ncomp; ++c)
+  {
+    auto mark = c*ndof;
+    R(el, mark) -= wt * fl[c];
+
+    if(ndof_l > 1)          //DG(P1)
+    {
+      R(el, mark+1) -= wt * fl[c] * B_l[1];
+      R(el, mark+2) -= wt * fl[c] * B_l[2];
+      R(el, mark+3) -= wt * fl[c] * B_l[3];
+    }
+
+    if(ndof_l > 4)          //DG(P2)
+    {
+      R(el, mark+4) -= wt * fl[c] * B_l[4];
+      R(el, mark+5) -= wt * fl[c] * B_l[5];
+      R(el, mark+6) -= wt * fl[c] * B_l[6];
+      R(el, mark+7) -= wt * fl[c] * B_l[7];
+      R(el, mark+8) -= wt * fl[c] * B_l[8];
+      R(el, mark+9) -= wt * fl[c] * B_l[9];
+    }
+  }
+
+  // Prep for non-conservative terms in multimat
+  if (fl.size() > ncomp)
+  {
+    // Gradients of partial pressures
+    for (std::size_t k=0; k<nmat; ++k)
+    {
+      for (std::size_t idir=0; idir<3; ++idir)
+        riemannDeriv[3*k+idir][el] += wt * fl[ncomp+k] * fn[idir];
+    }
+
+    // Divergence of velocity multiples basis fucntion( d(uB) / dx )
+    for(std::size_t idof = 0; idof < ndof; idof++)
+      riemannDeriv[3*nmat+idof][el] += wt * fl[ncomp+nmat] * B_l[idof];
+
+    // Divergence of asigma: d(asig_ij)/dx_j
+    for (std::size_t k=0; k<nmat; ++k)
+      if (solidx[k] > 0)
+      {
+        std::size_t mark = ncomp+nmat+1+3*(solidx[k]-1);
+
+        for (std::size_t i=0; i<3; ++i)
+          riemannDeriv[3*nmat+ndof+3*(solidx[k]-1)+i][el] -=
+            wt * fl[mark+i];
+      }
+  }
+}
+
+void
+bndSurfIntFV(
+  std::size_t nmat,
+  const std::vector< inciter::EOS >& mat_blk,
+  const std::size_t rdof,
+  const std::vector< std::size_t >& bcconfig,
+  const inciter::FaceData& fd,
+  const Fields& geoFace,
+  const Fields& geoElem,
+  const std::vector< std::size_t >& inpoel,
+  const UnsMesh::Coords& coord,
+  real t,
+  const RiemannFluxFn& flux,
+  const VelFn& vel,
+  const StateFn& state,
+  const Fields& U,
+  const Fields& P,
+  const std::vector< int >& srcFlag,
+  Fields& R,
+  int intsharp )
+// *****************************************************************************
+//! Compute boundary surface flux integrals for a given boundary type for FV
+//! \details This function computes contributions from surface integrals along
+//!   all faces for a particular boundary condition type, configured by the state
+//!   function
+//! \param[in] nmat Number of materials in this PDE system
+//! \param[in] mat_blk EOS material block
+//! \param[in] rdof Maximum number of reconstructed degrees of freedom
+//! \param[in] bcconfig BC configuration vector for multiple side sets
+//! \param[in] fd Face connectivity and boundary conditions object
+//! \param[in] geoFace Face geometry array
+//! \param[in] geoElem Element geometry array
+//! \param[in] inpoel Element-node connectivity
+//! \param[in] coord Array of nodal coordinates
+//! \param[in] t Physical time
+//! \param[in] flux Riemann flux function to use
+//! \param[in] vel Function to use to query prescribed velocity (if any)
+//! \param[in] state Function to evaluate the left and right solution state at
+//!   boundaries
+//! \param[in] U Solution vector at recent time step
+//! \param[in] P Vector of primitives at recent time step
+//! \param[in] srcFlag Whether the energy source was added
+//! \param[in,out] R Right-hand side vector computed
+//! \param[in] intsharp Interface compression tag, an optional argument, with
+//!   default 0, so that it is unused for single-material and transport.
+// *****************************************************************************
+{
+  const auto& bface = fd.Bface();
+  const auto& esuf = fd.Esuf();
+
+  const auto& cx = coord[0];
+  const auto& cy = coord[1];
+  const auto& cz = coord[2];
+
+  auto ncomp = U.nprop()/rdof;<--- Variable 'ncomp' is assigned a value that is never used.
+  auto nprim = P.nprop()/rdof;<--- Variable 'nprim' is assigned a value that is never used.
+
+  for (const auto& s : bcconfig) {       // for all bc sidesets
+    auto bc = bface.find(static_cast<int>(s));// faces for side set
+    if (bc != end(bface))
+    {
+      for (const auto& f : bc->second)
+      {
+        Assert( esuf[2*f+1] == -1, "outside boundary element not -1" );
+
+        std::size_t el = static_cast< std::size_t >(esuf[2*f]);
+
+        // Extract the left element coordinates
+        std::array< std::array< tk::real, 3>, 4 > coordel_l {{
+        {{ cx[ inpoel[4*el  ] ], cy[ inpoel[4*el  ] ], cz[ inpoel[4*el  ] ] }},
+        {{ cx[ inpoel[4*el+1] ], cy[ inpoel[4*el+1] ], cz[ inpoel[4*el+1] ] }},
+        {{ cx[ inpoel[4*el+2] ], cy[ inpoel[4*el+2] ], cz[ inpoel[4*el+2] ] }},
+        {{ cx[ inpoel[4*el+3] ], cy[ inpoel[4*el+3] ], cz[ inpoel[4*el+3] ] }} }};
+
+        // Compute the determinant of Jacobian matrix
+        auto detT_l =
+          Jacobian( coordel_l[0], coordel_l[1], coordel_l[2], coordel_l[3] );
+
+        // face normal
+        std::array< real, 3 >
+          fn{{ geoFace(f,1), geoFace(f,2), geoFace(f,3) }};
+
+        // face centroid
+        std::array< real, 3 >
+          gp{{ geoFace(f,4), geoFace(f,5), geoFace(f,6) }};
+
+        std::array< tk::real, 3> ref_gp_l{
+          Jacobian( coordel_l[0], gp, coordel_l[2], coordel_l[3] ) / detT_l,
+          Jacobian( coordel_l[0], coordel_l[1], gp, coordel_l[3] ) / detT_l,
+          Jacobian( coordel_l[0], coordel_l[1], coordel_l[2], gp ) / detT_l };
+
+        //Compute the basis functions for the left element
+        auto B_l = eval_basis( rdof, ref_gp_l[0], ref_gp_l[1], ref_gp_l[2] );
+
+        // Compute the state variables at the left element
+        auto ugp = evalFVSol(mat_blk, intsharp, ncomp, nprim,
+          rdof, nmat, el, inpoel, coord, geoElem, ref_gp_l, B_l, U, P,
+          srcFlag[el]);
+
+        Assert( ugp.size() == ncomp+nprim, "Incorrect size for "
+                "appended boundary state vector" );
+
+        auto var = state( ncomp, mat_blk, ugp, gp[0], gp[1], gp[2], t, fn );
+
+        // Compute the numerical flux
+        auto fl = flux( mat_blk, fn, var, vel(ncomp, gp[0], gp[1], gp[2], t) );
+
+        // compute non-conservative terms
+        std::vector< tk::real > var_riemann(nmat+1, 0.0);
+        for (std::size_t k=0; k<nmat+1; ++k) var_riemann[k] = fl[ncomp+k];
+
+        auto ncf_l = nonConservativeIntFV(nmat, rdof, el, fn, U, P, var_riemann);
+
+        // Add the surface integration term to the rhs
+        for (ncomp_t c=0; c<ncomp; ++c)
+        {
+          R(el, c) -= geoFace(f,0) * (fl[c] - ncf_l[c]);
+        }
+      }
+    }
+  }
+}
+
+} // tk::
 
diff --git a/Release/cppcheck/65.html b/Release/cppcheck/65.html index d7fec30649d2..105cf45ab643 100644 --- a/Release/cppcheck/65.html +++ b/Release/cppcheck/65.html @@ -152,997 +152,2031 @@
- - - + + - - + + @@ -370,50 +370,50 @@ - + - + - + - + - - + + - + - + - + - + - + - + diff --git a/Release/test_coverage/Base/index-sort-f.html b/Release/test_coverage/Base/index-sort-f.html index 4e3e4e00da77..94ed4fcfd9f4 100644 --- a/Release/test_coverage/Base/index-sort-f.html +++ b/Release/test_coverage/Base/index-sort-f.html @@ -27,13 +27,13 @@ - + - + - + @@ -49,9 +49,9 @@ - - - + + +
  1
-  2
-  3
-  4
-  5
-  6
-  7
-  8
-  9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
- 37
- 38
- 39
- 40
- 41
- 42
- 43
- 44
- 45
- 46
- 47
- 48
- 49
- 50
- 51
- 52
- 53
- 54
- 55
- 56
- 57
- 58
- 59
- 60
- 61
- 62
- 63
- 64
- 65
- 66
- 67
- 68
- 69
- 70
- 71
- 72
- 73
- 74
- 75
- 76
- 77
- 78
- 79
- 80
- 81
- 82
- 83
- 84
- 85
- 86
- 87
- 88
- 89
- 90
- 91
- 92
- 93
- 94
- 95
- 96
- 97
- 98
- 99
-100
-101
-102
-103
-104
-105
-106
-107
-108
-109
-110
-111
-112
-113
-114
-115
-116
-117
-118
-119
-120
-121
-122
-123
-124
-125
-126
-127
-128
-129
-130
-131
-132
-133
-134
-135
-136
-137
-138
-139
-140
-141
-142
-143
-144
-145
-146
-147
-148
-149
-150
-151
-152
-153
-154
-155
-156
-157
-158
-159
-160
-161
-162
-163
-164
-165
-166
-167
-168
-169
-170
-171
-172
-173
-174
-175
-176
-177
-178
-179
-180
-181
-182
-183
-184
-185
-186
-187
-188
-189
-190
-191
-192
-193
-194
-195
-196
-197
-198
-199
-200
-201
-202
-203
-204
-205
-206
-207
-208
-209
-210
-211
-212
-213
-214
-215
-216
-217
-218
-219
-220
-221
-222
-223
-224
-225
-226
-227
-228
-229
-230
-231
-232
-233
-234
-235
-236
-237
-238
-239
-240
-241
-242
-243
-244
-245
-246
-247
-248
-249
-250
-251
-252
-253
-254
-255
-256
-257
-258
-259
-260
-261
-262
-263
-264
-265
-266
-267
-268
-269
-270
-271
-272
-273
-274
-275
-276
-277
-278
-279
-280
-281
-282
-283
-284
-285
-286
-287
-288
-289
-290
-291
-292
-293
-294
-295
-296
-297
-298
-299
-300
-301
-302
-303
-304
-305
-306
-307
-308
-309
-310
-311
-312
-313
-314
-315
-316
-317
-318
-319
-320
-321
-322
-323
-324
-325
-326
-327
-328
-329
-330
-331
-332
-333
-334
-335
-336
-337
-338
-339
-340
-341
-342
-343
-344
-345
-346
-347
-348
-349
-350
-351
-352
-353
-354
-355
-356
-357
-358
-359
-360
-361
-362
-363
-364
-365
-366
-367
-368
-369
-370
-371
-372
-373
-374
-375
-376
-377
-378
-379
-380
-381
-382
-383
-384
-385
-386
-387
-388
-389
-390
-391
-392
-393
-394
-395
-396
-397
-398
-399
-400
-401
-402
-403
-404
-405
-406
-407
-408
-409
-410
-411
-412
-413
-414
-415
-416
-417
-418
-419
-420
-421
-422
-423
-424
-425
-426
-427
-428
-429
-430
-431
-432
-433
-434
-435
-436
-437
-438
-439
-440
-441
-442
-443
-444
-445
-446
-447
-448
-449
-450
-451
-452
-453
-454
-455
-456
-457
-458
-459
-460
-461
-462
-463
-464
-465
-466
-467
-468
-469
-470
-471
-472
-473
-474
-475
-476
-477
-478
-479
-480
-481
-482
-483
-484
-485
-486
-487
-488
-489
-490
-491
-492
// *****************************************************************************
+
   1
+   2
+   3
+   4
+   5
+   6
+   7
+   8
+   9
+  10
+  11
+  12
+  13
+  14
+  15
+  16
+  17
+  18
+  19
+  20
+  21
+  22
+  23
+  24
+  25
+  26
+  27
+  28
+  29
+  30
+  31
+  32
+  33
+  34
+  35
+  36
+  37
+  38
+  39
+  40
+  41
+  42
+  43
+  44
+  45
+  46
+  47
+  48
+  49
+  50
+  51
+  52
+  53
+  54
+  55
+  56
+  57
+  58
+  59
+  60
+  61
+  62
+  63
+  64
+  65
+  66
+  67
+  68
+  69
+  70
+  71
+  72
+  73
+  74
+  75
+  76
+  77
+  78
+  79
+  80
+  81
+  82
+  83
+  84
+  85
+  86
+  87
+  88
+  89
+  90
+  91
+  92
+  93
+  94
+  95
+  96
+  97
+  98
+  99
+ 100
+ 101
+ 102
+ 103
+ 104
+ 105
+ 106
+ 107
+ 108
+ 109
+ 110
+ 111
+ 112
+ 113
+ 114
+ 115
+ 116
+ 117
+ 118
+ 119
+ 120
+ 121
+ 122
+ 123
+ 124
+ 125
+ 126
+ 127
+ 128
+ 129
+ 130
+ 131
+ 132
+ 133
+ 134
+ 135
+ 136
+ 137
+ 138
+ 139
+ 140
+ 141
+ 142
+ 143
+ 144
+ 145
+ 146
+ 147
+ 148
+ 149
+ 150
+ 151
+ 152
+ 153
+ 154
+ 155
+ 156
+ 157
+ 158
+ 159
+ 160
+ 161
+ 162
+ 163
+ 164
+ 165
+ 166
+ 167
+ 168
+ 169
+ 170
+ 171
+ 172
+ 173
+ 174
+ 175
+ 176
+ 177
+ 178
+ 179
+ 180
+ 181
+ 182
+ 183
+ 184
+ 185
+ 186
+ 187
+ 188
+ 189
+ 190
+ 191
+ 192
+ 193
+ 194
+ 195
+ 196
+ 197
+ 198
+ 199
+ 200
+ 201
+ 202
+ 203
+ 204
+ 205
+ 206
+ 207
+ 208
+ 209
+ 210
+ 211
+ 212
+ 213
+ 214
+ 215
+ 216
+ 217
+ 218
+ 219
+ 220
+ 221
+ 222
+ 223
+ 224
+ 225
+ 226
+ 227
+ 228
+ 229
+ 230
+ 231
+ 232
+ 233
+ 234
+ 235
+ 236
+ 237
+ 238
+ 239
+ 240
+ 241
+ 242
+ 243
+ 244
+ 245
+ 246
+ 247
+ 248
+ 249
+ 250
+ 251
+ 252
+ 253
+ 254
+ 255
+ 256
+ 257
+ 258
+ 259
+ 260
+ 261
+ 262
+ 263
+ 264
+ 265
+ 266
+ 267
+ 268
+ 269
+ 270
+ 271
+ 272
+ 273
+ 274
+ 275
+ 276
+ 277
+ 278
+ 279
+ 280
+ 281
+ 282
+ 283
+ 284
+ 285
+ 286
+ 287
+ 288
+ 289
+ 290
+ 291
+ 292
+ 293
+ 294
+ 295
+ 296
+ 297
+ 298
+ 299
+ 300
+ 301
+ 302
+ 303
+ 304
+ 305
+ 306
+ 307
+ 308
+ 309
+ 310
+ 311
+ 312
+ 313
+ 314
+ 315
+ 316
+ 317
+ 318
+ 319
+ 320
+ 321
+ 322
+ 323
+ 324
+ 325
+ 326
+ 327
+ 328
+ 329
+ 330
+ 331
+ 332
+ 333
+ 334
+ 335
+ 336
+ 337
+ 338
+ 339
+ 340
+ 341
+ 342
+ 343
+ 344
+ 345
+ 346
+ 347
+ 348
+ 349
+ 350
+ 351
+ 352
+ 353
+ 354
+ 355
+ 356
+ 357
+ 358
+ 359
+ 360
+ 361
+ 362
+ 363
+ 364
+ 365
+ 366
+ 367
+ 368
+ 369
+ 370
+ 371
+ 372
+ 373
+ 374
+ 375
+ 376
+ 377
+ 378
+ 379
+ 380
+ 381
+ 382
+ 383
+ 384
+ 385
+ 386
+ 387
+ 388
+ 389
+ 390
+ 391
+ 392
+ 393
+ 394
+ 395
+ 396
+ 397
+ 398
+ 399
+ 400
+ 401
+ 402
+ 403
+ 404
+ 405
+ 406
+ 407
+ 408
+ 409
+ 410
+ 411
+ 412
+ 413
+ 414
+ 415
+ 416
+ 417
+ 418
+ 419
+ 420
+ 421
+ 422
+ 423
+ 424
+ 425
+ 426
+ 427
+ 428
+ 429
+ 430
+ 431
+ 432
+ 433
+ 434
+ 435
+ 436
+ 437
+ 438
+ 439
+ 440
+ 441
+ 442
+ 443
+ 444
+ 445
+ 446
+ 447
+ 448
+ 449
+ 450
+ 451
+ 452
+ 453
+ 454
+ 455
+ 456
+ 457
+ 458
+ 459
+ 460
+ 461
+ 462
+ 463
+ 464
+ 465
+ 466
+ 467
+ 468
+ 469
+ 470
+ 471
+ 472
+ 473
+ 474
+ 475
+ 476
+ 477
+ 478
+ 479
+ 480
+ 481
+ 482
+ 483
+ 484
+ 485
+ 486
+ 487
+ 488
+ 489
+ 490
+ 491
+ 492
+ 493
+ 494
+ 495
+ 496
+ 497
+ 498
+ 499
+ 500
+ 501
+ 502
+ 503
+ 504
+ 505
+ 506
+ 507
+ 508
+ 509
+ 510
+ 511
+ 512
+ 513
+ 514
+ 515
+ 516
+ 517
+ 518
+ 519
+ 520
+ 521
+ 522
+ 523
+ 524
+ 525
+ 526
+ 527
+ 528
+ 529
+ 530
+ 531
+ 532
+ 533
+ 534
+ 535
+ 536
+ 537
+ 538
+ 539
+ 540
+ 541
+ 542
+ 543
+ 544
+ 545
+ 546
+ 547
+ 548
+ 549
+ 550
+ 551
+ 552
+ 553
+ 554
+ 555
+ 556
+ 557
+ 558
+ 559
+ 560
+ 561
+ 562
+ 563
+ 564
+ 565
+ 566
+ 567
+ 568
+ 569
+ 570
+ 571
+ 572
+ 573
+ 574
+ 575
+ 576
+ 577
+ 578
+ 579
+ 580
+ 581
+ 582
+ 583
+ 584
+ 585
+ 586
+ 587
+ 588
+ 589
+ 590
+ 591
+ 592
+ 593
+ 594
+ 595
+ 596
+ 597
+ 598
+ 599
+ 600
+ 601
+ 602
+ 603
+ 604
+ 605
+ 606
+ 607
+ 608
+ 609
+ 610
+ 611
+ 612
+ 613
+ 614
+ 615
+ 616
+ 617
+ 618
+ 619
+ 620
+ 621
+ 622
+ 623
+ 624
+ 625
+ 626
+ 627
+ 628
+ 629
+ 630
+ 631
+ 632
+ 633
+ 634
+ 635
+ 636
+ 637
+ 638
+ 639
+ 640
+ 641
+ 642
+ 643
+ 644
+ 645
+ 646
+ 647
+ 648
+ 649
+ 650
+ 651
+ 652
+ 653
+ 654
+ 655
+ 656
+ 657
+ 658
+ 659
+ 660
+ 661
+ 662
+ 663
+ 664
+ 665
+ 666
+ 667
+ 668
+ 669
+ 670
+ 671
+ 672
+ 673
+ 674
+ 675
+ 676
+ 677
+ 678
+ 679
+ 680
+ 681
+ 682
+ 683
+ 684
+ 685
+ 686
+ 687
+ 688
+ 689
+ 690
+ 691
+ 692
+ 693
+ 694
+ 695
+ 696
+ 697
+ 698
+ 699
+ 700
+ 701
+ 702
+ 703
+ 704
+ 705
+ 706
+ 707
+ 708
+ 709
+ 710
+ 711
+ 712
+ 713
+ 714
+ 715
+ 716
+ 717
+ 718
+ 719
+ 720
+ 721
+ 722
+ 723
+ 724
+ 725
+ 726
+ 727
+ 728
+ 729
+ 730
+ 731
+ 732
+ 733
+ 734
+ 735
+ 736
+ 737
+ 738
+ 739
+ 740
+ 741
+ 742
+ 743
+ 744
+ 745
+ 746
+ 747
+ 748
+ 749
+ 750
+ 751
+ 752
+ 753
+ 754
+ 755
+ 756
+ 757
+ 758
+ 759
+ 760
+ 761
+ 762
+ 763
+ 764
+ 765
+ 766
+ 767
+ 768
+ 769
+ 770
+ 771
+ 772
+ 773
+ 774
+ 775
+ 776
+ 777
+ 778
+ 779
+ 780
+ 781
+ 782
+ 783
+ 784
+ 785
+ 786
+ 787
+ 788
+ 789
+ 790
+ 791
+ 792
+ 793
+ 794
+ 795
+ 796
+ 797
+ 798
+ 799
+ 800
+ 801
+ 802
+ 803
+ 804
+ 805
+ 806
+ 807
+ 808
+ 809
+ 810
+ 811
+ 812
+ 813
+ 814
+ 815
+ 816
+ 817
+ 818
+ 819
+ 820
+ 821
+ 822
+ 823
+ 824
+ 825
+ 826
+ 827
+ 828
+ 829
+ 830
+ 831
+ 832
+ 833
+ 834
+ 835
+ 836
+ 837
+ 838
+ 839
+ 840
+ 841
+ 842
+ 843
+ 844
+ 845
+ 846
+ 847
+ 848
+ 849
+ 850
+ 851
+ 852
+ 853
+ 854
+ 855
+ 856
+ 857
+ 858
+ 859
+ 860
+ 861
+ 862
+ 863
+ 864
+ 865
+ 866
+ 867
+ 868
+ 869
+ 870
+ 871
+ 872
+ 873
+ 874
+ 875
+ 876
+ 877
+ 878
+ 879
+ 880
+ 881
+ 882
+ 883
+ 884
+ 885
+ 886
+ 887
+ 888
+ 889
+ 890
+ 891
+ 892
+ 893
+ 894
+ 895
+ 896
+ 897
+ 898
+ 899
+ 900
+ 901
+ 902
+ 903
+ 904
+ 905
+ 906
+ 907
+ 908
+ 909
+ 910
+ 911
+ 912
+ 913
+ 914
+ 915
+ 916
+ 917
+ 918
+ 919
+ 920
+ 921
+ 922
+ 923
+ 924
+ 925
+ 926
+ 927
+ 928
+ 929
+ 930
+ 931
+ 932
+ 933
+ 934
+ 935
+ 936
+ 937
+ 938
+ 939
+ 940
+ 941
+ 942
+ 943
+ 944
+ 945
+ 946
+ 947
+ 948
+ 949
+ 950
+ 951
+ 952
+ 953
+ 954
+ 955
+ 956
+ 957
+ 958
+ 959
+ 960
+ 961
+ 962
+ 963
+ 964
+ 965
+ 966
+ 967
+ 968
+ 969
+ 970
+ 971
+ 972
+ 973
+ 974
+ 975
+ 976
+ 977
+ 978
+ 979
+ 980
+ 981
+ 982
+ 983
+ 984
+ 985
+ 986
+ 987
+ 988
+ 989
+ 990
+ 991
+ 992
+ 993
+ 994
+ 995
+ 996
+ 997
+ 998
+ 999
+1000
+1001
+1002
+1003
+1004
+1005
+1006
+1007
+1008
+1009
// *****************************************************************************
 /*!
-  \file      src/PDE/Integrate/Surface.cpp
+  \file      src/PDE/Integrate/MultiMatTerms.cpp
   \copyright 2012-2015 J. Bakosi,
              2016-2018 Los Alamos National Security, LLC.,
              2019-2021 Triad National Security, LLC.
              All rights reserved. See the LICENSE file for details.
-  \brief     Functions for computing internal surface integrals of a system
-     of PDEs in DG methods
-  \details   This file contains functionality for computing internal surface
-     integrals of a system of PDEs used in discontinuous Galerkin methods for
-     various orders of numerical representation.
-*/
-// *****************************************************************************
-
-#include <array>
-
-#include "Surface.hpp"
-#include "Vector.hpp"
-#include "Quadrature.hpp"
-#include "Reconstruction.hpp"
-#include "Integrate/SolidTerms.hpp"
-#include "Inciter/InputDeck/InputDeck.hpp"
-#include "MultiMat/MiscMultiMatFns.hpp"
-
-namespace inciter {
-extern ctr::InputDeck g_inputdeck;
-}
-
-namespace tk {
-
-void
-surfInt( std::size_t nmat,
-         const std::vector< inciter::EOS >& mat_blk,
-         real t,
-         const std::size_t ndof,
-         const std::size_t rdof,
-         const std::vector< std::size_t >& inpoel,
-         const std::vector< std::size_t >& /*solidx*/,
-         const UnsMesh::Coords& coord,
-         const inciter::FaceData& fd,
-         const Fields& geoFace,
-         const Fields& geoElem,
-         const RiemannFluxFn& flux,
-         const VelFn& vel,
-         const Fields& U,
-         const Fields& P,
-         const std::vector< std::size_t >& ndofel,
-         const tk::real /*dt*/,
-         Fields& R,
-         std::vector< std::vector< tk::real > >&,
-         std::vector< std::vector< tk::real > >&,
-         std::vector< std::vector< tk::real > >& riemannDeriv,
-         int intsharp )
-// *****************************************************************************
-//  Compute internal surface flux integrals
-//! \param[in] nmat Number of materials in this PDE system
-//! \param[in] mat_blk EOS material block
-//! \param[in] t Physical time
-//! \param[in] ndof Maximum number of degrees of freedom
-//! \param[in] rdof Maximum number of reconstructed degrees of freedom
-//! \param[in] inpoel Element-node connectivity
-// //! \param[in] solidx Material index indicator
-//! \param[in] coord Array of nodal coordinates
-//! \param[in] fd Face connectivity and boundary conditions object
-//! \param[in] geoFace Face geometry array
-//! \param[in] geoElem Element geometry array
-//! \param[in] flux Riemann flux function to use
-//! \param[in] vel Function to use to query prescribed velocity (if any)
-//! \param[in] U Solution vector at recent time step
-//! \param[in] P Vector of primitives at recent time step
-//! \param[in] ndofel Vector of local number of degrees of freedom
-// //! \param[in] dt Delta time
-//! \param[in,out] R Right-hand side vector computed
-//! \param[in,out] vriem Vector of the riemann velocity
-//! \param[in,out] riemannLoc Vector of coordinates where Riemann velocity data
-//!   is available
-//! \param[in,out] riemannDeriv Derivatives of partial-pressures and velocities
-//!   computed from the Riemann solver for use in the non-conservative terms.
-//!   These derivatives are used only for multi-material hydro and unused for
-//!   single-material compflow and linear transport.
-//! \param[in] intsharp Interface compression tag, an optional argument, with
-//!   default 0, so that it is unused for single-material and transport.
-// *****************************************************************************
-{
-  const auto& esuf = fd.Esuf();
-  const auto& inpofa = fd.Inpofa();
-
-  const auto& cx = coord[0];
-  const auto& cy = coord[1];
-  const auto& cz = coord[2];
+  \brief     Functions for computing volume integrals of multi-material terms
+     using DG methods
+  \details   This file contains functionality for computing volume integrals of
+     non-conservative and pressure relaxation terms that appear in the
+     multi-material hydrodynamic equations, using the discontinuous Galerkin
+     method for various orders of numerical representation.
+*/
+// *****************************************************************************
+
+#include "QuinoaConfig.hpp"
+
+#include "MultiMatTerms.hpp"
+#include "Vector.hpp"
+#include "Quadrature.hpp"
+#include "MultiMat/MultiMatIndexing.hpp"
+#include "Reconstruction.hpp"
+#include "Inciter/InputDeck/InputDeck.hpp"
+#include "EoS/GetMatProp.hpp"
+
+namespace inciter {
+extern ctr::InputDeck g_inputdeck;
+}
+
+// Lapacke forward declarations
+extern "C" {
+
+using lapack_int = long;
+
+#define LAPACK_ROW_MAJOR 101
+
+lapack_int LAPACKE_dsysv( int, char, lapack_int, lapack_int, double*,
+    lapack_int, lapack_int*, double*, lapack_int );
+
+}
+
+namespace tk {
+
+void
+nonConservativeInt( std::size_t nmat,
+                    const std::vector< inciter::EOS >& mat_blk,
+                    const std::size_t ndof,
+                    const std::size_t rdof,
+                    const std::size_t nelem,
+                    const std::vector< std::size_t >& inpoel,
+                    const UnsMesh::Coords& coord,
+                    const Fields& geoElem,
+                    const Fields& U,
+                    const Fields& P,
+                    const std::vector< std::vector< tk::real > >& riemannDeriv,
+                    const std::vector< std::size_t >& ndofel,
+                    Fields& R,
+                    int intsharp )
+// *****************************************************************************
+//  Compute volume integrals for multi-material DG
+//! \details This is called for multi-material DG, computing volume integrals of
+//!   terms in the volume fraction and energy equations, which do not exist in
+//!   the single-material flow formulation (for `CompFlow` DG). For further
+//!   details see Pelanti, M., & Shyue, K. M. (2019). A numerical model for
+//!   multiphase liquid–vapor–gas flows with interfaces and cavitation.
+//!   International Journal of Multiphase Flow, 113, 208-230.
+//! \param[in] nmat Number of materials in this PDE system
+//! \param[in] mat_blk EOS material block
+//! \param[in] ndof Maximum number of degrees of freedom
+//! \param[in] rdof Maximum number of reconstructed degrees of freedom
+//! \param[in] nelem Total number of elements
+//! \param[in] inpoel Element-node connectivity
+//! \param[in] coord Array of nodal coordinates
+//! \param[in] geoElem Element geometry array
+//! \param[in] U Solution vector at recent time step
+//! \param[in] P Vector of primitive quantities at recent time step
+//! \param[in] riemannDeriv Derivatives of partial-pressures and velocities
+//!   computed from the Riemann solver for use in the non-conservative terms
+//! \param[in] ndofel Vector of local number of degrees of freedome
+//! \param[in,out] R Right-hand side vector added to
+//! \param[in] intsharp Interface reconstruction indicator
+// *****************************************************************************
+{
+  using inciter::volfracIdx;
+  using inciter::densityIdx;
+  using inciter::momentumIdx;
+  using inciter::energyIdx;
+  using inciter::velocityIdx;
+  using inciter::deformIdx;
+  using inciter::newSolidsAccFn;
 
-  auto ncomp = U.nprop()/rdof;<--- Variable 'ncomp' is assigned a value that is never used.
-  auto nprim = P.nprop()/rdof;<--- Variable 'nprim' is assigned a value that is never used.
-
-  //// Determine if we have solids in our problem
-  //bool haveSolid = inciter::haveSolid(nmat, solidx);
-
-  //Assert( (nmat==1 ? riemannDeriv.empty() : true), "Non-empty Riemann "
-  //        "derivative vector for single material compflow" );
-
-  // compute internal surface flux integrals
-  for (auto f=fd.Nbfac(); f<esuf.size()/2; ++f)
-  {
-    Assert( esuf[2*f] > -1 && esuf[2*f+1] > -1, "Interior element detected "
-            "as -1" );
+  const auto& solidx =
+    inciter::g_inputdeck.get< tag::matidxmap, tag::solidx >();
+
+  const auto& cx = coord[0];
+  const auto& cy = coord[1];
+  const auto& cz = coord[2];
+
+  auto ncomp = U.nprop()/rdof;
+  auto nprim = P.nprop()/rdof;
+
+  // compute volume integrals
+  for (std::size_t e=0; e<nelem; ++e)
+  {
+    auto ng = tk::NGvol(ndofel[e]);
 
-    std::size_t el = static_cast< std::size_t >(esuf[2*f]);
-    std::size_t er = static_cast< std::size_t >(esuf[2*f+1]);
-
-    auto ng_l = tk::NGfa(ndofel[el]);
-    auto ng_r = tk::NGfa(ndofel[er]);
-
-    // When the number of gauss points for the left and right element are
-    // different, choose the larger ng
-    auto ng = std::max( ng_l, ng_r );
-
-    // arrays for quadrature points
-    std::array< std::vector< real >, 2 > coordgp;
-    std::vector< real > wgp;
-
-    coordgp[0].resize( ng );
-    coordgp[1].resize( ng );
-    wgp.resize( ng );
-
-    // get quadrature point weights and coordinates for triangle
-    GaussQuadratureTri( ng, coordgp, wgp );
-
-    // Extract the element coordinates
-    std::array< std::array< tk::real, 3>, 4 > coordel_l {{
-      {{ cx[ inpoel[4*el  ] ], cy[ inpoel[4*el  ] ], cz[ inpoel[4*el  ] ] }},
-      {{ cx[ inpoel[4*el+1] ], cy[ inpoel[4*el+1] ], cz[ inpoel[4*el+1] ] }},
-      {{ cx[ inpoel[4*el+2] ], cy[ inpoel[4*el+2] ], cz[ inpoel[4*el+2] ] }},
-      {{ cx[ inpoel[4*el+3] ], cy[ inpoel[4*el+3] ], cz[ inpoel[4*el+3] ] }} }};
-
-    std::array< std::array< tk::real, 3>, 4 > coordel_r {{
-      {{ cx[ inpoel[4*er  ] ], cy[ inpoel[4*er  ] ], cz[ inpoel[4*er  ] ] }},
-      {{ cx[ inpoel[4*er+1] ], cy[ inpoel[4*er+1] ], cz[ inpoel[4*er+1] ] }},
-      {{ cx[ inpoel[4*er+2] ], cy[ inpoel[4*er+2] ], cz[ inpoel[4*er+2] ] }},
-      {{ cx[ inpoel[4*er+3] ], cy[ inpoel[4*er+3] ], cz[ inpoel[4*er+3] ] }} }};
-
-    // Compute the determinant of Jacobian matrix
-    auto detT_l =
-      Jacobian( coordel_l[0], coordel_l[1], coordel_l[2], coordel_l[3] );
-    auto detT_r =
-      Jacobian( coordel_r[0], coordel_r[1], coordel_r[2], coordel_r[3] );
-
-    // Extract the face coordinates
-    std::array< std::array< tk::real, 3>, 3 > coordfa {{
-      {{ cx[ inpofa[3*f  ] ], cy[ inpofa[3*f  ] ], cz[ inpofa[3*f  ] ] }},
-      {{ cx[ inpofa[3*f+1] ], cy[ inpofa[3*f+1] ], cz[ inpofa[3*f+1] ] }},
-      {{ cx[ inpofa[3*f+2] ], cy[ inpofa[3*f+2] ], cz[ inpofa[3*f+2] ] }} }};
+    // arrays for quadrature points
+    std::array< std::vector< real >, 3 > coordgp;
+    std::vector< real > wgp;
+
+    coordgp[0].resize( ng );
+    coordgp[1].resize( ng );
+    coordgp[2].resize( ng );
+    wgp.resize( ng );
+
+    GaussQuadratureTet( ng, coordgp, wgp );
+
+    // Extract the element coordinates
+    std::array< std::array< real, 3>, 4 > coordel {{
+      {{ cx[ inpoel[4*e  ] ], cy[ inpoel[4*e  ] ], cz[ inpoel[4*e  ] ] }},
+      {{ cx[ inpoel[4*e+1] ], cy[ inpoel[4*e+1] ], cz[ inpoel[4*e+1] ] }},
+      {{ cx[ inpoel[4*e+2] ], cy[ inpoel[4*e+2] ], cz[ inpoel[4*e+2] ] }},
+      {{ cx[ inpoel[4*e+3] ], cy[ inpoel[4*e+3] ], cz[ inpoel[4*e+3] ] }}
+    }};
+
+    auto jacInv =
+            inverseJacobian( coordel[0], coordel[1], coordel[2], coordel[3] );
+
+    // Compute the derivatives of basis function for DG(P1)
+    std::array< std::vector<tk::real>, 3 > dBdx;
+    if (ndofel[e] > 1)
+      dBdx = eval_dBdx_p1( ndofel[e], jacInv );
+
+    // Gaussian quadrature
+    for (std::size_t igp=0; igp<ng; ++igp)
+    {
+      if (ndofel[e] > 4)
+        eval_dBdx_p2( igp, coordgp, jacInv, dBdx );
+
+      // If an rDG method is set up (P0P1), then, currently we compute the P1
+      // basis functions and solutions by default. This implies that P0P1 is
+      // unsupported in the p-adaptive DG (PDG).
+      std::size_t dof_el;
+      if (rdof > ndof)
+      {
+        dof_el = rdof;
+      }
+      else
+      {
+        dof_el = ndofel[e];
+      }
 
-    std::array< real, 3 >
-      fn{{ geoFace(f,1), geoFace(f,2), geoFace(f,3) }};
-
-    // Gaussian quadrature
-    for (std::size_t igp=0; igp<ng; ++igp)
-    {
-      // Compute the coordinates of quadrature point at physical domain
-      auto gp = eval_gp( igp, coordfa, coordgp );
-
-      // In order to determine the high-order solution from the left and right
-      // elements at the surface quadrature points, the basis functions from
-      // the left and right elements are needed. For this, a transformation to
-      // the reference coordinates is necessary, since the basis functions are
-      // defined on the reference tetrahedron only.
-      // The transformation relations are shown below:
-      //  xi   = Jacobian( coordel[0], gp, coordel[2], coordel[3] ) / detT
-      //  eta  = Jacobian( coordel[0], coordel[2], gp, coordel[3] ) / detT
-      //  zeta = Jacobian( coordel[0], coordel[2], coordel[3], gp ) / detT
-
-      // If an rDG method is set up (P0P1), then, currently we compute the P1
-      // basis functions and solutions by default. This implies that P0P1 is
-      // unsupported in the p-adaptive DG (PDG). This is a workaround until we
-      // have rdofel, which is needed to distinguish between ndofs and rdofs per
-      // element for pDG.
-      std::size_t dof_el, dof_er;
-      if (rdof > ndof)
-      {
-        dof_el = rdof;
-        dof_er = rdof;
-      }
-      else
-      {
-        dof_el = ndofel[el];
-        dof_er = ndofel[er];
-      }
-
-      std::array< tk::real, 3> ref_gp_l{
-        Jacobian( coordel_l[0], gp, coordel_l[2], coordel_l[3] ) / detT_l,
-        Jacobian( coordel_l[0], coordel_l[1], gp, coordel_l[3] ) / detT_l,
-        Jacobian( coordel_l[0], coordel_l[1], coordel_l[2], gp ) / detT_l };
-      std::array< tk::real, 3> ref_gp_r{
-        Jacobian( coordel_r[0], gp, coordel_r[2], coordel_r[3] ) / detT_r,
-        Jacobian( coordel_r[0], coordel_r[1], gp, coordel_r[3] ) / detT_r,
-        Jacobian( coordel_r[0], coordel_r[1], coordel_r[2], gp ) / detT_r };
-
-      //Compute the basis functions
-      auto B_l = eval_basis( dof_el, ref_gp_l[0], ref_gp_l[1], ref_gp_l[2] );
-      auto B_r = eval_basis( dof_er, ref_gp_r[0], ref_gp_r[1], ref_gp_r[2] );
-
-      auto wt = wgp[igp] * geoFace(f,0);<--- Variable 'wt' is assigned a value that is never used.
-
-      std::array< std::vector< real >, 2 > state;
-
-      state[0] = evalPolynomialSol(mat_blk, intsharp, ncomp, nprim, rdof,
-        nmat, el, dof_el, inpoel, coord, geoElem, ref_gp_l, B_l, U, P);
-      state[1] = evalPolynomialSol(mat_blk, intsharp, ncomp, nprim, rdof,
-        nmat, er, dof_er, inpoel, coord, geoElem, ref_gp_r, B_r, U, P);
-
-      Assert( state[0].size() == ncomp+nprim, "Incorrect size for "
-              "appended boundary state vector" );
-      Assert( state[1].size() == ncomp+nprim, "Incorrect size for "
-              "appended boundary state vector" );
-
-      // evaluate prescribed velocity (if any)
-      auto v = vel( ncomp, gp[0], gp[1], gp[2], t );
-
-      // compute flux
-      auto fl = flux( mat_blk, fn, state, v );
-
-      // Add the surface integration term to the rhs
-      update_rhs_fa( ncomp, nmat, ndof, ndofel[el], ndofel[er], wt, fn,
-                     el, er, fl, B_l, B_r, R, riemannDeriv );
-    }
-  }
-}
-
-void
-update_rhs_fa( ncomp_t ncomp,
-               std::size_t nmat,
-               const std::size_t ndof,
-               const std::size_t ndof_l,
-               const std::size_t ndof_r,
-               const tk::real wt,
-               const std::array< tk::real, 3 >& fn,
-               const std::size_t el,
-               const std::size_t er,
-               const std::vector< tk::real >& fl,
-               const std::vector< tk::real >& B_l,
-               const std::vector< tk::real >& B_r,
-               Fields& R,<--- Parameter 'R' can be declared with const
-               std::vector< std::vector< tk::real > >& riemannDeriv )
-// *****************************************************************************
-//  Update the rhs by adding the surface integration term
-//! \param[in] ncomp Number of scalar components in this PDE system
-//! \param[in] nmat Number of materials in this PDE system
-//! \param[in] ndof Maximum number of degrees of freedom
-//! \param[in] ndof_l Number of degrees of freedom for left element
-//! \param[in] ndof_r Number of degrees of freedom for right element
-//! \param[in] wt Weight of gauss quadrature point
-//! \param[in] fn Face/Surface normal
-//! \param[in] el Left element index
-//! \param[in] er Right element index
-//! \param[in] fl Surface flux
-//! \param[in] B_l Basis function for the left element
-//! \param[in] B_r Basis function for the right element
-//! \param[in,out] R Right-hand side vector computed
-//! \param[in,out] riemannDeriv Derivatives of partial-pressures and velocities
-//!   computed from the Riemann solver for use in the non-conservative terms.
-//!   These derivatives are used only for multi-material hydro and unused for
-//!   single-material compflow and linear transport.
-// *****************************************************************************
-{
-  // following lines commented until rdofel is made available.
-  //Assert( B_l.size() == ndof_l, "Size mismatch" );
-  //Assert( B_r.size() == ndof_r, "Size mismatch" );
-
-  using inciter::newSolidsAccFn;
-
-  const auto& solidx =
-    inciter::g_inputdeck.get< tag::matidxmap, tag::solidx >();
-
-  for (ncomp_t c=0; c<ncomp; ++c)
-  {
-    auto mark = c*ndof;
-    R(el, mark) -= wt * fl[c];
-    R(er, mark) += wt * fl[c];
-
-    if(ndof_l > 1)          //DG(P1)
-    {
-      R(el, mark+1) -= wt * fl[c] * B_l[1];
-      R(el, mark+2) -= wt * fl[c] * B_l[2];
-      R(el, mark+3) -= wt * fl[c] * B_l[3];
-    }
-
-    if(ndof_r > 1)          //DG(P1)
-    {
-      R(er, mark+1) += wt * fl[c] * B_r[1];
-      R(er, mark+2) += wt * fl[c] * B_r[2];
-      R(er, mark+3) += wt * fl[c] * B_r[3];
-    }
-
-    if(ndof_l > 4)          //DG(P2)
-    {
-      R(el, mark+4) -= wt * fl[c] * B_l[4];
-      R(el, mark+5) -= wt * fl[c] * B_l[5];
-      R(el, mark+6) -= wt * fl[c] * B_l[6];
-      R(el, mark+7) -= wt * fl[c] * B_l[7];
-      R(el, mark+8) -= wt * fl[c] * B_l[8];
-      R(el, mark+9) -= wt * fl[c] * B_l[9];
-    }
-
-    if(ndof_r > 4)          //DG(P2)
-    {
-      R(er, mark+4) += wt * fl[c] * B_r[4];
-      R(er, mark+5) += wt * fl[c] * B_r[5];
-      R(er, mark+6) += wt * fl[c] * B_r[6];
-      R(er, mark+7) += wt * fl[c] * B_r[7];
-      R(er, mark+8) += wt * fl[c] * B_r[8];
-      R(er, mark+9) += wt * fl[c] * B_r[9];
-    }
-  }
-
-  // Prep for non-conservative terms in multimat
-  if (fl.size() > ncomp)
-  {
-    // Gradients of partial pressures
-    for (std::size_t k=0; k<nmat; ++k)
-    {
-      for (std::size_t idir=0; idir<3; ++idir)
-      {
-        riemannDeriv[3*k+idir][el] += wt * fl[ncomp+k] * fn[idir];
-        riemannDeriv[3*k+idir][er] -= wt * fl[ncomp+k] * fn[idir];
-      }
-    }
-
-    // Divergence of velocity multiples basis fucntion( d(uB) / dx )
-    for(std::size_t idof = 0; idof < ndof; idof++) {
-      riemannDeriv[3*nmat+idof][el] += wt * fl[ncomp+nmat] * B_l[idof];
-      riemannDeriv[3*nmat+idof][er] -= wt * fl[ncomp+nmat] * B_r[idof];
-    }
-
-    // Divergence of asigma: d(asig_ij)/dx_j
-    for (std::size_t k=0; k<nmat; ++k)
-      if (solidx[k] > 0)
-      {
-        std::size_t mark = ncomp+nmat+1+3*(solidx[k]-1);
-
-        for (std::size_t i=0; i<3; ++i)
-        {
-          riemannDeriv[3*nmat+ndof+3*(solidx[k]-1)+i][el] -=
-            wt * fl[mark+i];
-          riemannDeriv[3*nmat+ndof+3*(solidx[k]-1)+i][er] +=
-            wt * fl[mark+i];
-        }
-      }
-  }
-}
+      // Compute the basis function
+      auto B =
+        eval_basis( dof_el, coordgp[0][igp], coordgp[1][igp], coordgp[2][igp] );
+
+      auto wt = wgp[igp] * geoElem(e, 0);
+
+      auto state = evalPolynomialSol(mat_blk, intsharp, ncomp, nprim,
+        rdof, nmat, e, dof_el, inpoel, coord, geoElem,
+        {{coordgp[0][igp], coordgp[1][igp], coordgp[2][igp]}}, B, U, P);
+
+      // get bulk properties
+      tk::real rhob(0.0);
+      for (std::size_t k=0; k<nmat; ++k)
+          rhob += state[densityIdx(nmat, k)];
+
+      // get the velocity vector
+      std::array< tk::real, 3 > vel{{ state[ncomp+velocityIdx(nmat, 0)],
+                                      state[ncomp+velocityIdx(nmat, 1)],
+                                      state[ncomp+velocityIdx(nmat, 2)] }};
+
+      std::vector< tk::real > ymat(nmat, 0.0);
+      std::array< tk::real, 3 > dap{{0.0, 0.0, 0.0}};
+      for (std::size_t k=0; k<nmat; ++k)
+      {
+        ymat[k] = state[densityIdx(nmat, k)]/rhob;
+
+        std::size_t mark(3*k);
+        if (solidx[k] > 0) mark = 3*nmat+ndof+3*(solidx[k]-1);
+
+        for (std::size_t idir=0; idir<3; ++idir)
+          dap[idir] += riemannDeriv[mark+idir][e];
+      }
+
+      // compute non-conservative terms
+      std::vector< std::vector< tk::real > > ncf
+        (ncomp, std::vector<tk::real>(ndof,0.0));
+
+      for (std::size_t idir=0; idir<3; ++idir)
+        for(std::size_t idof=0; idof<ndof; ++idof)
+          ncf[momentumIdx(nmat, idir)][idof] = 0.0;
+
+      for (std::size_t k=0; k<nmat; ++k)
+      {
+        // evaluate non-conservative term for energy equation
+        std::size_t mark(3*k);
+        if (solidx[k] > 0) mark = 3*nmat+ndof+3*(solidx[k]-1);
+
+        for(std::size_t idof=0; idof<ndof; ++idof)
+        {
+          ncf[densityIdx(nmat, k)][idof] = 0.0;
+
+          for (std::size_t idir=0; idir<3; ++idir)
+            ncf[energyIdx(nmat, k)][idof] -= vel[idir] * ( ymat[k]*dap[idir]
+                                                  - riemannDeriv[mark+idir][e] );
+        }
+
+        // Evaluate non-conservative term for volume fraction equation:
+        // Here we make an assumption that the derivative of Riemann velocity
+        // times the basis function is constant. Therefore, when P0P1/DGP1/DGP2
+        // are used for constant velocity problems, the discretization is
+        // consistent. However, for a general problem with varying velocity,
+        // there will be errors since the said derivative is not constant.
+        // A discretization that solves this issue has not been implemented yet.
+        // Nevertheless, this does not affect high-order accuracy in
+        // single material regions for problems with sharp interfaces. Since
+        // volume fractions are nearly constant in such regions, using
+        // high-order for volume fractions does not show any benefits over
+        // THINC. Therefore, for such problems, we only use FV for the volume
+        // fractions, and these non-conservative high-order terms do not need
+        // to be computed.
+        // In summary, high-order discretization for non-conservative terms in
+        // volume fraction equations is avoided for sharp interface problems.
+        if (ndof <= 4 || intsharp == 1) {
+          for(std::size_t idof=0; idof<ndof; ++idof)
+            ncf[volfracIdx(nmat, k)][idof] = state[volfracIdx(nmat, k)]
+                                           * riemannDeriv[3*nmat+idof][e];
+        } else if (intsharp == 0) {     // If DGP2 without THINC
+          // DGP2 is discretized differently than DGP1/FV to guarantee 3rd order
+          // convergence for the testcases with uniform and constant velocity.
+
+          // P0 contributions for all equations
+          for(std::size_t idof=0; idof<ndof; ++idof)
+          ncf[volfracIdx(nmat, k)][idof] = state[volfracIdx(nmat, k)]
+                                         * riemannDeriv[3*nmat][e] * B[idof];
+          // High order contributions
+          for(std::size_t idof=1; idof<ndof; ++idof)
+            for(std::size_t idir=0; idir<3; ++idir)
+            ncf[volfracIdx(nmat, k)][idof] += state[volfracIdx(nmat, k)]
+                                            * vel[idir] * dBdx[idir][idof];
+        }
+      }
+
+      updateRhsNonCons( ncomp, nmat, ndof, ndofel[e], wt, e, B, dBdx, ncf, R );
+    }
+  }
+}
+
+void
+updateRhsNonCons(
+  ncomp_t ncomp,
+  const std::size_t nmat,
+  const std::size_t ndof,
+  [[maybe_unused]] const std::size_t ndof_el,
+  const tk::real wt,
+  const std::size_t e,
+  const std::vector<tk::real>& B,
+  [[maybe_unused]] const std::array< std::vector<tk::real>, 3 >& dBdx,
+  const std::vector< std::vector< tk::real > >& ncf,
+  Fields& R )
+// *****************************************************************************
+//  Update the rhs by adding the non-conservative term integrals
+//! \param[in] ncomp Number of scalar components in this PDE system
+//! \param[in] nmat Number of materials
+//! \param[in] ndof Maximum number of degrees of freedom
+//! \param[in] ndof_el Number of degrees of freedom for local element
+//! \param[in] wt Weight of gauss quadrature point
+//! \param[in] e Element index
+//! \param[in] B Basis function evaluated at local quadrature point
+//! \param[in] dBdx Vector of basis function derivatives
+//! \param[in] ncf Vector of non-conservative terms
+//! \param[in,out] R Right-hand side vector computed
+// *****************************************************************************
+{
+  using inciter::volfracIdx;
+  using inciter::energyIdx;
+  using inciter::volfracDofIdx;
+  using inciter::energyDofIdx;
+
+  //Assert( dBdx[0].size() == ndof_el,
+  //        "Size mismatch for basis function derivatives" );
+  //Assert( dBdx[1].size() == ndof_el,
+  //        "Size mismatch for basis function derivatives" );
+  //Assert( dBdx[2].size() == ndof_el,
+  //        "Size mismatch for basis function derivatives" );
+  //Assert( ncf.size() == ncomp,
+  //        "Size mismatch for non-conservative term" );
+  Assert( ncf.size() == ncomp, "Size mismatch for non-conservative term" );
+
+  for (ncomp_t c=0; c<ncomp; ++c)
+  {
+    auto mark = c*ndof;
+    R(e, mark) += wt * ncf[c][0];
+  }
+
+  if( ndof_el > 1)
+  {
+    // Update rhs with distributions from volume fraction and energy equations
+    for (std::size_t k=0; k<nmat; ++k)
+    {
+      for(std::size_t idof = 1; idof < ndof; idof++)
+      {
+        R(e, volfracDofIdx(nmat,k,ndof,idof)) +=
+          wt * ncf[volfracIdx(nmat,k)][idof];
+        R(e, energyDofIdx(nmat,k,ndof,idof)) +=
+          wt * ncf[energyIdx(nmat,k)][idof] * B[idof];
+      }
+    }
+  }
+}
+
+std::vector< tk::real >
+nonConservativeIntFV(
+  std::size_t nmat,
+  const std::size_t rdof,
+  const std::size_t e,
+  const std::array< tk::real, 3 >& fn,
+  const Fields& U,
+  const Fields& P,
+  const std::vector< tk::real >& var_riemann )
+// *****************************************************************************
+//  Compute integrals of non-conservative terms for multi-material FV
+//! \details This is called for multi-material FV, computing integrals of
+//!   terms in the volume fraction and energy equations, which do not exist in
+//!   the single-material flow formulation (for `CompFlow`). For further
+//!   details see Pelanti, M., & Shyue, K. M. (2019). A numerical model for
+//!   multiphase liquid–vapor–gas flows with interfaces and cavitation.
+//!   International Journal of Multiphase Flow, 113, 208-230.
+//! \param[in] nmat Number of materials in this PDE system
+//! \param[in] rdof Maximum number of reconstructed degrees of freedom
+//! \param[in] e Element for which contribution is to be calculated
+//! \param[in] fn Face normal
+//! \param[in] U Solution vector at recent time step
+//! \param[in] P Vector of primitive quantities at recent time step
+//! \param[in] var_riemann Riemann-values of partial-pressures and velocities
+//!   computed from the Riemann solver for use in the non-conservative terms
+// *****************************************************************************
+{
+  using inciter::volfracIdx;
+  using inciter::densityIdx;
+  using inciter::momentumIdx;
+  using inciter::energyIdx;
+  using inciter::velocityIdx;
+  using inciter::volfracDofIdx;
+  using inciter::densityDofIdx;
+  using inciter::velocityDofIdx;
+
+  auto ncomp = U.nprop()/rdof;
 
-void
-surfIntFV(
-  std::size_t nmat,
-  const std::vector< inciter::EOS >& mat_blk,
-  real t,
-  const std::size_t rdof,
-  const std::vector< std::size_t >& inpoel,
-  const UnsMesh::Coords& coord,
-  const inciter::FaceData& fd,
-  const Fields& geoFace,
-  const Fields& geoElem,
-  const RiemannFluxFn& flux,
-  const VelFn& vel,
-  const Fields& U,
-  const Fields& P,
-  const std::vector< int >& srcFlag,
-  Fields& R,
-  int intsharp )
-// *****************************************************************************
-//  Compute internal surface flux integrals for second order FV
-//! \param[in] nmat Number of materials in this PDE system
-//! \param[in] t Physical time
-//! \param[in] rdof Maximum number of reconstructed degrees of freedom
-//! \param[in] inpoel Element-node connectivity
-//! \param[in] coord Array of nodal coordinates
-//! \param[in] fd Face connectivity and boundary conditions object
-//! \param[in] geoFace Face geometry array
-//! \param[in] geoElem Element geometry array
-//! \param[in] flux Riemann flux function to use
-//! \param[in] vel Function to use to query prescribed velocity (if any)
-//! \param[in] U Solution vector at recent time step
-//! \param[in] P Vector of primitives at recent time step
-//! \param[in] srcFlag Whether the energy source was added
-//! \param[in,out] R Right-hand side vector computed
-//! \param[in] intsharp Interface compression tag, an optional argument, with
-//!   default 0, so that it is unused for single-material and transport.
-// *****************************************************************************
-{
-  const auto& esuf = fd.Esuf();
-
-  const auto& cx = coord[0];
-  const auto& cy = coord[1];
-  const auto& cz = coord[2];
-
-  auto ncomp = U.nprop()/rdof;<--- Variable 'ncomp' is assigned a value that is never used.
-  auto nprim = P.nprop()/rdof;<--- Variable 'nprim' is assigned a value that is never used.
-
-  // compute internal surface flux integrals
-  for (auto f=fd.Nbfac(); f<esuf.size()/2; ++f)
-  {
-    Assert( esuf[2*f] > -1 && esuf[2*f+1] > -1, "Interior element detected "
-            "as -1" );
-
-    std::size_t el = static_cast< std::size_t >(esuf[2*f]);
-    std::size_t er = static_cast< std::size_t >(esuf[2*f+1]);
-
-    // Extract the element coordinates
-    std::array< std::array< tk::real, 3>, 4 > coordel_l {{
-      {{ cx[ inpoel[4*el  ] ], cy[ inpoel[4*el  ] ], cz[ inpoel[4*el  ] ] }},
-      {{ cx[ inpoel[4*el+1] ], cy[ inpoel[4*el+1] ], cz[ inpoel[4*el+1] ] }},
-      {{ cx[ inpoel[4*el+2] ], cy[ inpoel[4*el+2] ], cz[ inpoel[4*el+2] ] }},
-      {{ cx[ inpoel[4*el+3] ], cy[ inpoel[4*el+3] ], cz[ inpoel[4*el+3] ] }} }};
-
-    std::array< std::array< tk::real, 3>, 4 > coordel_r {{
-      {{ cx[ inpoel[4*er  ] ], cy[ inpoel[4*er  ] ], cz[ inpoel[4*er  ] ] }},
-      {{ cx[ inpoel[4*er+1] ], cy[ inpoel[4*er+1] ], cz[ inpoel[4*er+1] ] }},
-      {{ cx[ inpoel[4*er+2] ], cy[ inpoel[4*er+2] ], cz[ inpoel[4*er+2] ] }},
-      {{ cx[ inpoel[4*er+3] ], cy[ inpoel[4*er+3] ], cz[ inpoel[4*er+3] ] }} }};
-
-    // Compute the determinant of Jacobian matrix
-    auto detT_l =
-      Jacobian( coordel_l[0], coordel_l[1], coordel_l[2], coordel_l[3] );
-    auto detT_r =
-      Jacobian( coordel_r[0], coordel_r[1], coordel_r[2], coordel_r[3] );
-
-    // face normal
-    std::array< real, 3 > fn{{geoFace(f,1), geoFace(f,2), geoFace(f,3)}};
-
-    // face centroid
-    std::array< real, 3 > gp{{geoFace(f,4), geoFace(f,5), geoFace(f,6)}};
-
-    // In order to determine the high-order solution from the left and right
-    // elements at the surface quadrature points, the basis functions from
-    // the left and right elements are needed. For this, a transformation to
-    // the reference coordinates is necessary, since the basis functions are
-    // defined on the reference tetrahedron only.
-    // The transformation relations are shown below:
-    //  xi   = Jacobian( coordel[0], gp, coordel[2], coordel[3] ) / detT
-    //  eta  = Jacobian( coordel[0], coordel[2], gp, coordel[3] ) / detT
-    //  zeta = Jacobian( coordel[0], coordel[2], coordel[3], gp ) / detT
-
-    std::array< tk::real, 3> ref_gp_l{
-      Jacobian( coordel_l[0], gp, coordel_l[2], coordel_l[3] ) / detT_l,
-      Jacobian( coordel_l[0], coordel_l[1], gp, coordel_l[3] ) / detT_l,
-      Jacobian( coordel_l[0], coordel_l[1], coordel_l[2], gp ) / detT_l };
-    std::array< tk::real, 3> ref_gp_r{
-      Jacobian( coordel_r[0], gp, coordel_r[2], coordel_r[3] ) / detT_r,
-      Jacobian( coordel_r[0], coordel_r[1], gp, coordel_r[3] ) / detT_r,
-      Jacobian( coordel_r[0], coordel_r[1], coordel_r[2], gp ) / detT_r };
-
-    //Compute the basis functions
-    auto B_l = eval_basis( rdof, ref_gp_l[0], ref_gp_l[1], ref_gp_l[2] );
-    auto B_r = eval_basis( rdof, ref_gp_r[0], ref_gp_r[1], ref_gp_r[2] );
-
-    std::array< std::vector< real >, 2 > state;
+  // get bulk properties
+  tk::real rhob(0.0), p_face(0.0);
+  for (std::size_t k=0; k<nmat; ++k)
+  {
+    rhob += U(e, densityDofIdx(nmat,k,rdof,0));
+    p_face += var_riemann[k];
+  }
+
+  std::array< tk::real, 3 > vel{{ P(e, velocityDofIdx(nmat,0,rdof,0)),
+                                  P(e, velocityDofIdx(nmat,1,rdof,0)),
+                                  P(e, velocityDofIdx(nmat,2,rdof,0)) }};
+
+  // compute non-conservative terms
+  std::vector< tk::real > ncf(ncomp, 0.0);
+  std::vector< tk::real > ymat(nmat, 0.0);
+  for (std::size_t k=0; k<nmat; ++k)
+  {
+    ymat[k] = U(e, densityDofIdx(nmat,k,rdof,0))/rhob;
+
+    // evaluate non-conservative term for energy equation
+    for (std::size_t idir=0; idir<3; ++idir)
+      ncf[energyIdx(nmat, k)] -= vel[idir] * ( ymat[k]*p_face*fn[idir]
+                                            - var_riemann[k]*fn[idir] );
+
+    // evaluate non-conservative term for volume fraction equation
+    ncf[volfracIdx(nmat, k)] = U(e, volfracDofIdx(nmat,k,rdof,0))
+      * var_riemann[nmat];
+  }
+
+  return ncf;
+}
+
+void
+pressureRelaxationInt( std::size_t nmat,
+                       const std::vector< inciter::EOS >& mat_blk,
+                       const std::size_t ndof,
+                       const std::size_t rdof,
+                       const std::size_t nelem,
+                       const std::vector< std::size_t >& inpoel,
+                       const UnsMesh::Coords& coord,
+                       const Fields& geoElem,
+                       const Fields& U,
+                       const Fields& P,
+                       const std::vector< std::size_t >& ndofel,
+                       const tk::real ct,
+                       Fields& R,
+                       int intsharp )
+// *****************************************************************************
+//  Compute volume integrals of pressure relaxation terms in multi-material DG
+//! \details This is called for multi-material DG to compute volume integrals of
+//!   finite pressure relaxation terms in the volume fraction and energy
+//!   equations, which do not exist in the single-material flow formulation (for
+//!   `CompFlow` DG). For further details see Dobrev, V. A., Kolev, T. V.,
+//!   Rieben, R. N., & Tomov, V. Z. (2016). Multi‐material closure model for
+//!   high‐order finite element Lagrangian hydrodynamics. International Journal
+//!   for Numerical Methods in Fluids, 82(10), 689-706.
+//! \param[in] nmat Number of materials in this PDE system
+//! \param[in] mat_blk EOS material block
+//! \param[in] ndof Maximum number of degrees of freedom
+//! \param[in] rdof Maximum number of reconstructed degrees of freedom
+//! \param[in] nelem Total number of elements
+//! \param[in] inpoel Element-node connectivity
+//! \param[in] coord Array of nodal coordinates
+//! \param[in] geoElem Element geometry array
+//! \param[in] U Solution vector at recent time step
+//! \param[in] P Vector of primitive quantities at recent time step
+//! \param[in] ndofel Vector of local number of degrees of freedome
+//! \param[in] ct Pressure relaxation time-scale for this system
+//! \param[in,out] R Right-hand side vector added to
+//! \param[in] intsharp Interface reconstruction indicator
+// *****************************************************************************
+{
+  using inciter::volfracIdx;
+  using inciter::densityIdx;
+  using inciter::momentumIdx;
+  using inciter::energyIdx;
+  using inciter::pressureIdx;
+  using inciter::velocityIdx;
+  using inciter::deformIdx;
+
+  const auto& solidx =
+    inciter::g_inputdeck.get< tag::matidxmap, tag::solidx >();
+
+  auto ncomp = U.nprop()/rdof;
+  auto nprim = P.nprop()/rdof;
+
+  // compute volume integrals
+  for (std::size_t e=0; e<nelem; ++e)
+  {
+    auto dx = geoElem(e,4)/2.0;
+    auto ng = NGvol(ndofel[e]);
+
+    // arrays for quadrature points
+    std::array< std::vector< real >, 3 > coordgp;
+    std::vector< real > wgp;
+
+    coordgp[0].resize( ng );
+    coordgp[1].resize( ng );
+    coordgp[2].resize( ng );
+    wgp.resize( ng );
+
+    GaussQuadratureTet( ng, coordgp, wgp );
+
+    // Compute the derivatives of basis function for DG(P1)
+    std::array< std::vector<real>, 3 > dBdx;
 
-    state[0] = evalFVSol(mat_blk, intsharp, ncomp, nprim, rdof,
-      nmat, el, inpoel, coord, geoElem, ref_gp_l, B_l, U, P, srcFlag[el]);
-    state[1] = evalFVSol(mat_blk, intsharp, ncomp, nprim, rdof,
-      nmat, er, inpoel, coord, geoElem, ref_gp_r, B_r, U, P, srcFlag[er]);
-
-    //safeReco(rdof, nmat, el, er, U, state);
-
-    Assert( state[0].size() == ncomp+nprim, "Incorrect size for "
-            "appended boundary state vector" );
-    Assert( state[1].size() == ncomp+nprim, "Incorrect size for "
-            "appended boundary state vector" );
-
-    // evaluate prescribed velocity (if any)
-    auto v = vel( ncomp, gp[0], gp[1], gp[2], t );
-
-    // compute flux
-    auto fl = flux( mat_blk, fn, state, v );
-
-    // compute non-conservative terms
-    std::vector< tk::real > var_riemann(nmat+1, 0.0);
-    for (std::size_t k=0; k<nmat+1; ++k) var_riemann[k] = fl[ncomp+k];
+    // Gaussian quadrature
+    for (std::size_t igp=0; igp<ng; ++igp)
+    {
+      // If an rDG method is set up (P0P1), then, currently we compute the P1
+      // basis functions and solutions by default. This implies that P0P1 is
+      // unsupported in the p-adaptive DG (PDG).
+      std::size_t dof_el;
+      if (rdof > ndof)
+      {
+        dof_el = rdof;
+      }
+      else
+      {
+        dof_el = ndofel[e];
+      }
+
+      // Compute the basis function
+      auto B =
+        eval_basis( dof_el, coordgp[0][igp], coordgp[1][igp], coordgp[2][igp] );
+
+      auto wt = wgp[igp] * geoElem(e, 0);
 
-    auto ncf_l = nonConservativeIntFV(nmat, rdof, el, fn, U, P, var_riemann);
-    auto ncf_r = nonConservativeIntFV(nmat, rdof, er, fn, U, P, var_riemann);
-
-    // Add the surface integration term to the rhs
-    for (ncomp_t c=0; c<ncomp; ++c)
-    {
-      R(el, c) -= geoFace(f,0) * (fl[c] - ncf_l[c]);
-      R(er, c) += geoFace(f,0) * (fl[c] - ncf_r[c]);
-    }
-  }
-}
-
-} // tk::
+      auto state = evalPolynomialSol(mat_blk, intsharp, ncomp, nprim,
+        rdof, nmat, e, dof_el, inpoel, coord, geoElem,
+        {{coordgp[0][igp], coordgp[1][igp], coordgp[2][igp]}}, B, U, P);
+
+      // get bulk properties
+      real rhob(0.0);
+      for (std::size_t k=0; k<nmat; ++k)
+        rhob += state[densityIdx(nmat, k)];
+
+      // get pressures and bulk modulii
+      real pb(0.0), nume(0.0), deno(0.0), trelax(0.0);
+      std::vector< real > apmat(nmat, 0.0), kmat(nmat, 0.0);
+      for (std::size_t k=0; k<nmat; ++k)
+      {
+        real arhomat = state[densityIdx(nmat, k)];
+        real alphamat = state[volfracIdx(nmat, k)];
+        apmat[k] = state[ncomp+pressureIdx(nmat, k)];
+        real amat = 0.0;
+        if (solidx[k] > 0)
+        {
+          std::array< std::array< tk::real, 3 >, 3 > g;
+          for (std::size_t i=0; i<3; ++i)
+            for (std::size_t j=0; j<3; ++j)
+              g[i][j] = state[deformIdx(nmat,solidx[k],i,j)];
+          auto grot = tk::rotateTensor(g, {{1.0, 0.0, 0.0}});
+          amat = mat_blk[k].compute< inciter::EOS::soundspeed >( arhomat,
+            apmat[k], alphamat, k, grot);
+          grot = tk::rotateTensor(g, {{0.0, 1.0, 0.0}});
+          amat = std::max(amat, mat_blk[k].compute< inciter::EOS::soundspeed >(
+            arhomat, apmat[k], alphamat, k, grot));
+          grot = tk::rotateTensor(g, {{0.0, 0.0, 1.0}});
+          amat = std::max(amat, mat_blk[k].compute< inciter::EOS::soundspeed >(
+            arhomat, apmat[k], alphamat, k, grot));
+        }
+        else
+        {
+          amat = mat_blk[k].compute< inciter::EOS::soundspeed >( arhomat,
+            apmat[k], alphamat, k );
+        }
+        kmat[k] = arhomat * amat * amat;
+        pb += apmat[k];
+
+        // relaxation parameters
+        trelax = std::max(trelax, ct*dx/amat);
+        nume += alphamat * apmat[k] / kmat[k];
+        deno += alphamat * alphamat / kmat[k];
+      }
+      auto p_relax = nume/deno;
+
+      // compute pressure relaxation terms
+      std::vector< real > s_prelax(ncomp, 0.0);
+      for (std::size_t k=0; k<nmat; ++k)
+      {
+        auto s_alpha = (apmat[k]-p_relax*state[volfracIdx(nmat, k)])
+          * (state[volfracIdx(nmat, k)]/kmat[k]) / trelax;
+        s_prelax[volfracIdx(nmat, k)] = s_alpha;
+        s_prelax[energyIdx(nmat, k)] = - pb*s_alpha;
+      }
+
+      updateRhsPre( ncomp, ndof, dof_el, wt, e, B, s_prelax, R );
+    }
+  }
+}
+
+void
+updateRhsPre(
+  ncomp_t ncomp,
+  const std::size_t ndof,
+  [[maybe_unused]] const std::size_t ndof_el,
+  const tk::real wt,
+  const std::size_t e,
+  const std::vector< tk::real >& B,
+  std::vector< tk::real >& ncf,
+  Fields& R )
+// *****************************************************************************
+//  Update the rhs by adding the pressure relaxation integrals
+//! \param[in] ncomp Number of scalar components in this PDE system
+//! \param[in] ndof Maximum number of degrees of freedom
+//! \param[in] ndof_el Number of degrees of freedom for local element
+//! \param[in] wt Weight of gauss quadrature point
+//! \param[in] e Element index
+//! \param[in] B Basis function evaluated at local quadrature point
+//! \param[in] ncf Vector of non-conservative terms
+//! \param[in,out] R Right-hand side vector computed
+// *****************************************************************************
+{
+  //Assert( dBdx[0].size() == ndof_el,
+  //        "Size mismatch for basis function derivatives" );
+  //Assert( dBdx[1].size() == ndof_el,
+  //        "Size mismatch for basis function derivatives" );
+  //Assert( dBdx[2].size() == ndof_el,
+  //        "Size mismatch for basis function derivatives" );
+  //Assert( ncf.size() == ncomp,
+  //        "Size mismatch for non-conservative term" );
+  Assert( ncf.size() == ncomp, "Size mismatch for non-conservative term" );
+
+  for (ncomp_t c=0; c<ncomp; ++c)
+  {
+    auto mark = c*ndof;
+    for(std::size_t idof = 0; idof < ndof; idof++)
+      R(e, mark+idof) += wt * ncf[c] * B[idof];
+  }
+}
+
+void
+pressureRelaxationIntFV(
+  std::size_t nmat,
+  const std::vector< inciter::EOS >& mat_blk,
+  const std::size_t rdof,
+  const std::size_t nelem,
+  const std::vector< std::size_t >& inpoel,
+  const UnsMesh::Coords& coord,
+  const Fields& geoElem,
+  const Fields& U,
+  const Fields& P,
+  const tk::real ct,
+  Fields& R )<--- Parameter 'R' can be declared with const
+// *****************************************************************************
+//  Compute volume integrals of pressure relaxation terms in multi-material FV
+//! \details This is called for multi-material FV to compute volume integrals of
+//!   finite pressure relaxation terms in the volume fraction and energy
+//!   equations, which do not exist in the single-material flow formulation (for
+//!   `CompFlow`). For further details see Dobrev, V. A., Kolev, T. V.,
+//!   Rieben, R. N., & Tomov, V. Z. (2016). Multi‐material closure model for
+//!   high‐order finite element Lagrangian hydrodynamics. International Journal
+//!   for Numerical Methods in Fluids, 82(10), 689-706.
+//! \param[in] nmat Number of materials in this PDE system
+//! \param[in] mat_blk EOS material block
+//! \param[in] rdof Maximum number of reconstructed degrees of freedom
+//! \param[in] nelem Total number of elements
+//! \param[in] geoElem Element geometry array
+//! \param[in] U Solution vector at recent time step
+//! \param[in] P Vector of primitive quantities at recent time step
+//! \param[in] ct Pressure relaxation time-scale for this system
+//! \param[in,out] R Right-hand side vector added to
+// *****************************************************************************
+{
+  using inciter::volfracIdx;
+  using inciter::energyIdx;
+  using inciter::pressureIdx;
+  using inciter::velocityIdx;
+  using inciter::densityIdx;
+
+  auto ncomp = U.nprop()/rdof;
+  auto nprim = P.nprop()/rdof;
+
+  // compute volume integrals
+  for (std::size_t e=0; e<nelem; ++e)
+  {
+    auto dx = geoElem(e,4)/2.0;
+
+    // Compute the basis function
+    std::vector< tk::real > B(rdof, 0.0);
+    B[0] = 1.0;
+
+    auto state = evalPolynomialSol(mat_blk, 0, ncomp, nprim,
+      rdof, nmat, e, rdof, inpoel, coord, geoElem,
+      {{0.25, 0.25, 0.25}}, B, U, P);
+
+    // get bulk properties
+    real rhob(0.0);
+    for (std::size_t k=0; k<nmat; ++k)
+      rhob += state[densityIdx(nmat, k)];
+
+    // get pressures and bulk modulii
+    real pb(0.0), nume(0.0), deno(0.0), trelax(0.0);
+    std::vector< real > apmat(nmat, 0.0), kmat(nmat, 0.0);
+    for (std::size_t k=0; k<nmat; ++k)
+    {
+      real arhomat = state[densityIdx(nmat, k)];
+      real alphamat = state[volfracIdx(nmat, k)];
+      apmat[k] = state[ncomp+pressureIdx(nmat, k)];
+      real amat = mat_blk[k].compute< inciter::EOS::soundspeed >( arhomat,
+        apmat[k], alphamat, k );
+      kmat[k] = arhomat * amat * amat;
+      pb += apmat[k];
+
+      // relaxation parameters
+      trelax = std::max(trelax, ct*dx/amat);
+      nume += alphamat * apmat[k] / kmat[k];
+      deno += alphamat * alphamat / kmat[k];
+    }
+    auto p_relax = nume/deno;
+
+    // compute pressure relaxation terms
+    std::vector< real > s_prelax(ncomp, 0.0);
+
+    // terms to ensure only existing materials are relaxed
+    real e_leftover(0), vf_leftover(0);
+    auto almax(0.0);
+    std::size_t kmax = 0;
+    for (std::size_t k=0; k<nmat; ++k)
+    {
+      real alphamat = state[volfracIdx(nmat, k)];
+      auto s_alpha = (apmat[k]-p_relax*state[volfracIdx(nmat, k)])
+        * (state[volfracIdx(nmat, k)]/kmat[k]) / trelax;
+
+      // only perform prelax on existing quantities
+      if (inciter::matExists(state[volfracIdx(nmat,k)])) {
+        s_prelax[volfracIdx(nmat, k)] = s_alpha;
+        s_prelax[energyIdx(nmat, k)] = - pb*s_alpha;
+      } else {
+        vf_leftover += s_alpha;
+        e_leftover  += - pb*s_alpha;
+      }
+      // get material that takes up most volume
+      if (alphamat > almax)
+      {
+        almax = alphamat;
+        kmax = k;
+      }
+    }
+
+    // add leftovers of non-existent mat to mat with most volume
+    s_prelax[volfracIdx(nmat, kmax)] += vf_leftover;
+    s_prelax[energyIdx(nmat, kmax)] += e_leftover;
+
+    for (ncomp_t c=0; c<ncomp; ++c)
+    {
+      R(e, c) += geoElem(e,0) * s_prelax[c];
+    }
+  }
+}
+
+std::vector< std::vector< tk::real > >
+solvevriem( std::size_t nelem,
+            const std::vector< std::vector< tk::real > >& vriem,
+            const std::vector< std::vector< tk::real > >& riemannLoc )
+// *****************************************************************************
+//  Solve the reconstruct velocity used for volume fraction equation by
+//  Least square method
+//! \param[in] nelem Numer of elements
+//! \param[in,out] vriem Vector of the riemann velocity
+//! \param[in,out] riemannLoc Vector of coordinates where Riemann velocity data
+//!   is available
+//! \return Vector of Riemann velocity polynomial solution
+// *****************************************************************************
+{
+  std::vector< std::vector< tk::real > >
+    vriempoly( nelem, std::vector<tk::real>(12,0.0) );
+
+  for (std::size_t e=0; e<nelem; ++e)
+  {
+    // Use the normal method to construct the linear system A^T * A * x = u
+    auto numgp = riemannLoc[e].size()/3;
+    std::vector< std::vector< tk::real > > A(numgp,
+                                             std::vector<tk::real>(4, 1.0));
+
+    for(std::size_t k = 0; k < numgp; k++)
+    {
+      auto mark = k * 3;
+      A[k][1] = riemannLoc[e][mark];
+      A[k][2] = riemannLoc[e][mark+1];
+      A[k][3] = riemannLoc[e][mark+2];
+    }
+
+    for(std::size_t idir = 0; idir < 3; idir++)
+    {
+      double AA_T[4*4], u[4];
+
+      for(std::size_t i = 0; i < 4; i++)
+        for(std::size_t j = 0; j < 4; j++)
+        {
+          auto id = 4 * i + j;
+          AA_T[id] = 0;
+          for(std::size_t k = 0; k < numgp; k++)
+            AA_T[id] += A[k][i] * A[k][j];
+        }
+
+      std::vector<tk::real> vel(numgp, 1.0);
+      for(std::size_t k = 0; k < numgp; k++)
+      {
+        auto mark = k * 3 + idir;
+        vel[k] = vriem[e][mark];
+      }
+      for(std::size_t k = 0; k < 4; k++)
+      {
+        u[k] = 0;
+        for(std::size_t i = 0; i < numgp; i++)
+          u[k] += A[i][k] * vel[i];
+      }
+ 
+      lapack_int IPIV[4];
+      #ifndef NDEBUG
+      lapack_int info =
+      #endif
+        LAPACKE_dsysv( LAPACK_ROW_MAJOR, 'U', 4, 1, AA_T, 4, IPIV, u, 1 );
+      Assert( info == 0, "Error in linear system solver" );
+
+      auto idirmark = idir * 4;
+      for(std::size_t k = 0; k < 4; k++)
+        vriempoly[e][idirmark+k] = u[k];
+    }
+  }
+  return vriempoly;
+}
+
+void evaluRiemann( ncomp_t ncomp,
+                   const int e_left,
+                   const int e_right,
+                   const std::size_t nmat,
+                   const std::vector< tk::real >& fl,
+                   const std::array< tk::real, 3 >& fn,
+                   const std::array< tk::real, 3 >& gp,
+                   const std::array< std::vector< tk::real >, 2 >& state,
+                   std::vector< std::vector< tk::real > >& vriem,
+                   std::vector< std::vector< tk::real > >& riemannLoc )
+// *****************************************************************************
+//  Compute the riemann velocity at the interface
+//! \param[in] ncomp Number of scalar components in this PDE system
+//! \param[in] e_left Index for the left element
+//! \param[in] e_right Index for the right element
+//! \param[in] nmat Number of materials in this PDE system
+//! \param[in] fn Face/Surface normal
+//! \param[in] gp Gauss points coordinates
+//! \param[in] fl Surface flux
+//! \param[in] state Vector of state variables for left and right side
+//! \param[in,out] vriem Vector of the riemann velocity
+//! \param[in,out] riemannLoc Vector of coordinates where Riemann velocity data
+//!   is available
+// *****************************************************************************
+{
+  using inciter::densityIdx;
+  using inciter::momentumIdx;
+
+  std::size_t el(0), er(0);
+  el = static_cast< std::size_t >(e_left);
+  if(e_right != -1)
+    er = static_cast< std::size_t >(e_right);
+
+  riemannLoc[el].push_back( gp[0] );
+  riemannLoc[el].push_back( gp[1] );
+  riemannLoc[el].push_back( gp[2] );
+
+  if(e_right != -1)
+  {
+    riemannLoc[er].push_back( gp[0] );
+    riemannLoc[er].push_back( gp[1] );
+    riemannLoc[er].push_back( gp[2] );
+  }
+
+  tk::real rhobl(0.0), rhobr(0.0);
+  for (std::size_t k=0; k<nmat; ++k)
+  {
+    rhobl += state[0][densityIdx(nmat, k)];
+    rhobr += state[1][densityIdx(nmat, k)];
+  }
+
+  auto ul = state[0][momentumIdx(nmat, 0)] / rhobl;
+  auto vl = state[0][momentumIdx(nmat, 1)] / rhobl;
+  auto wl = state[0][momentumIdx(nmat, 2)] / rhobl;
+
+  auto ur = state[1][momentumIdx(nmat, 0)] / rhobr;
+  auto vr = state[1][momentumIdx(nmat, 1)] / rhobr;
+  auto wr = state[1][momentumIdx(nmat, 2)] / rhobr;
+
+  // Compute the normal velocities from left and right cells
+  auto vnl = ul * fn[0] + vl * fn[1] + wl * fn[2];
+  auto vnr = ur * fn[0] + vr * fn[1] + wr * fn[2];
+
+  // The interface velocity is evaluated by adding the normal velocity which
+  // is taken from the Riemann solver and the tangential velocity which is
+  // evaluated as an average of the left and right cells
+  auto urie = 0.5 * ((ul + ur) - fn[0] * (vnl + vnr)) + fl[ncomp+nmat] * fn[0];
+  auto vrie = 0.5 * ((vl + vr) - fn[1] * (vnl + vnr)) + fl[ncomp+nmat] * fn[1];
+  auto wrie = 0.5 * ((wl + wr) - fn[2] * (vnl + vnr)) + fl[ncomp+nmat] * fn[2];
+
+  vriem[el].push_back(urie);
+  vriem[el].push_back(vrie);
+  vriem[el].push_back(wrie);
+
+  if(e_right != -1)
+  {
+    vriem[er].push_back(urie);
+    vriem[er].push_back(vrie);
+    vriem[er].push_back(wrie);
+  }
+}
+
+std::vector< std::array< tk::real, 3 > >
+fluxTerms(
+  std::size_t ncomp,
+  std::size_t nmat,
+  const std::vector< inciter::EOS >& /*mat_blk*/,
+  const std::vector< tk::real >& ugp )
+// *****************************************************************************
+//  Compute the flux-function for the multimaterial PDEs
+//! \param[in] ncomp Number of components in this PDE system
+//! \param[in] nmat Number of materials in this PDE system
+// //! \param[in] mat_blk EOS material block
+//! \param[in] ugp State vector at the Gauss point at which flux is required
+//! \return Flux vectors for all components in multi-material PDE system
+// *****************************************************************************
+{
+  using inciter::volfracIdx;
+  using inciter::densityIdx;
+  using inciter::momentumIdx;
+  using inciter::energyIdx;
+  using inciter::velocityIdx;
+  using inciter::pressureIdx;
+  using inciter::deformIdx;
+
+  const auto& solidx =
+    inciter::g_inputdeck.get< tag::matidxmap, tag::solidx >();
+
+  std::vector< std::array< tk::real, 3 > > fl( ncomp, {{0, 0, 0}} );
+
+  tk::real rho(0.0);<--- Variable 'rho' is assigned a value that is never used.
+  for (std::size_t k=0; k<nmat; ++k)
+    rho += ugp[densityIdx(nmat, k)];<--- Variable 'rho' is assigned a value that is never used.
+
+  auto u = ugp[ncomp+velocityIdx(nmat,0)];
+  auto v = ugp[ncomp+velocityIdx(nmat,1)];
+  auto w = ugp[ncomp+velocityIdx(nmat,2)];
+
+  if (inciter::haveSolid(nmat, solidx))
+  {
+    std::vector< tk::real > al(nmat, 0.0);
+    std::vector< std::array< std::array< tk::real, 3 >, 3 > > g, asig;
+    std::array< std::array< tk::real, 3 >, 3 >
+      sig {{ {{0, 0, 0}}, {{0, 0, 0}}, {{0, 0, 0}} }};
+    for (std::size_t k=0; k<nmat; ++k)
+    {
+      al[k] = ugp[volfracIdx(nmat, k)];
+      // inv deformation gradient and Cauchy stress tensors
+      g.push_back(inciter::getDeformGrad(nmat, k, ugp));
+      asig.push_back(inciter::getCauchyStress(nmat, k, ncomp, ugp));
+      for (std::size_t i=0; i<3; ++i) asig[k][i][i] -= ugp[ncomp+pressureIdx(nmat,k)];
+
+      for (size_t i=0; i<3; ++i)
+        for (size_t j=0; j<3; ++j)
+          sig[i][j] += asig[k][i][j];
+    }
+
+    // conservative part of momentum flux
+    fl[momentumIdx(nmat, 0)][0] = ugp[momentumIdx(nmat, 0)] * u - sig[0][0];
+    fl[momentumIdx(nmat, 1)][0] = ugp[momentumIdx(nmat, 1)] * u - sig[0][1];
+    fl[momentumIdx(nmat, 2)][0] = ugp[momentumIdx(nmat, 2)] * u - sig[0][2];
+
+    fl[momentumIdx(nmat, 0)][1] = ugp[momentumIdx(nmat, 0)] * v - sig[1][0];
+    fl[momentumIdx(nmat, 1)][1] = ugp[momentumIdx(nmat, 1)] * v - sig[1][1];
+    fl[momentumIdx(nmat, 2)][1] = ugp[momentumIdx(nmat, 2)] * v - sig[1][2];
+
+    fl[momentumIdx(nmat, 0)][2] = ugp[momentumIdx(nmat, 0)] * w - sig[2][0];
+    fl[momentumIdx(nmat, 1)][2] = ugp[momentumIdx(nmat, 1)] * w - sig[2][1];
+    fl[momentumIdx(nmat, 2)][2] = ugp[momentumIdx(nmat, 2)] * w - sig[2][2];
+
+    for (std::size_t k=0; k<nmat; ++k)
+    {
+      // conservative part of volume-fraction flux
+      fl[volfracIdx(nmat, k)][0] = 0.0;
+      fl[volfracIdx(nmat, k)][1] = 0.0;
+      fl[volfracIdx(nmat, k)][2] = 0.0;
+
+      // conservative part of material continuity flux
+      fl[densityIdx(nmat, k)][0] = u * ugp[densityIdx(nmat, k)];
+      fl[densityIdx(nmat, k)][1] = v * ugp[densityIdx(nmat, k)];
+      fl[densityIdx(nmat, k)][2] = w * ugp[densityIdx(nmat, k)];
+
+      // conservative part of material total-energy flux
+      fl[energyIdx(nmat, k)][0] = u * ugp[energyIdx(nmat, k)]
+        - u * asig[k][0][0] - v * asig[k][1][0] - w * asig[k][2][0];
+      fl[energyIdx(nmat, k)][1] = v * ugp[energyIdx(nmat, k)]
+        - u * asig[k][0][1] - v * asig[k][1][1] - w * asig[k][2][1];
+      fl[energyIdx(nmat, k)][2] = w * ugp[energyIdx(nmat, k)]
+        - u * asig[k][0][2] - v * asig[k][1][2] - w * asig[k][2][2];
+
+      // conservative part of material inverse deformation gradient
+      // g_ij: \partial (g_il u_l) / \partial (x_j)
+      if (solidx[k] > 0)
+      {
+        for (std::size_t i=0; i<3; ++i)
+        {
+          for (std::size_t j=0; j<3; ++j)
+          {
+            fl[deformIdx(nmat,solidx[k],i,j)][j] =
+              u*g[k][i][0] + v*g[k][i][1] + w*g[k][i][2];
+          }
+          // other components are zero
+        }
+      }
+    }
+  }
+  else
+  {
+    tk::real p(0.0);
+    std::vector< tk::real > apk( nmat, 0.0 );
+    for (std::size_t k=0; k<nmat; ++k)
+    {
+      apk[k] = ugp[ncomp+pressureIdx(nmat,k)];
+      p += apk[k];
+    }
+
+    // conservative part of momentum flux
+    fl[momentumIdx(nmat, 0)][0] = ugp[momentumIdx(nmat, 0)] * u + p;
+    fl[momentumIdx(nmat, 1)][0] = ugp[momentumIdx(nmat, 1)] * u;
+    fl[momentumIdx(nmat, 2)][0] = ugp[momentumIdx(nmat, 2)] * u;
+
+    fl[momentumIdx(nmat, 0)][1] = ugp[momentumIdx(nmat, 0)] * v;
+    fl[momentumIdx(nmat, 1)][1] = ugp[momentumIdx(nmat, 1)] * v + p;
+    fl[momentumIdx(nmat, 2)][1] = ugp[momentumIdx(nmat, 2)] * v;
+
+    fl[momentumIdx(nmat, 0)][2] = ugp[momentumIdx(nmat, 0)] * w;
+    fl[momentumIdx(nmat, 1)][2] = ugp[momentumIdx(nmat, 1)] * w;
+    fl[momentumIdx(nmat, 2)][2] = ugp[momentumIdx(nmat, 2)] * w + p;
+
+    for (std::size_t k=0; k<nmat; ++k)
+    {
+      // conservative part of volume-fraction flux
+      fl[volfracIdx(nmat, k)][0] = 0.0;
+      fl[volfracIdx(nmat, k)][1] = 0.0;
+      fl[volfracIdx(nmat, k)][2] = 0.0;
+
+      // conservative part of material continuity flux
+      fl[densityIdx(nmat, k)][0] = u * ugp[densityIdx(nmat, k)];
+      fl[densityIdx(nmat, k)][1] = v * ugp[densityIdx(nmat, k)];
+      fl[densityIdx(nmat, k)][2] = w * ugp[densityIdx(nmat, k)];
+
+      // conservative part of material total-energy flux
+      auto hmat = ugp[energyIdx(nmat, k)] + apk[k];
+      fl[energyIdx(nmat, k)][0] = u * hmat;
+      fl[energyIdx(nmat, k)][1] = v * hmat;
+      fl[energyIdx(nmat, k)][2] = w * hmat;
+    }
+  }
+
+  return fl;
+}
+
+}// tk::
 
diff --git a/Release/cppcheck/67.html b/Release/cppcheck/67.html index 351a168febdc..49cb97bfcf9f 100644 --- a/Release/cppcheck/67.html +++ b/Release/cppcheck/67.html @@ -152,2031 +152,997 @@
- - + diff --git a/Release/test_coverage/Base/Writer.cpp.func.html b/Release/test_coverage/Base/Writer.cpp.func.html index f74e30089e21..c62ed3e846b6 100644 --- a/Release/test_coverage/Base/Writer.cpp.func.html +++ b/Release/test_coverage/Base/Writer.cpp.func.html @@ -33,7 +33,7 @@ - + diff --git a/Release/test_coverage/Base/Writer.cpp.gcov.html b/Release/test_coverage/Base/Writer.cpp.gcov.html index ca5fca4b0011..b06b38791bb3 100644 --- a/Release/test_coverage/Base/Writer.cpp.gcov.html +++ b/Release/test_coverage/Base/Writer.cpp.gcov.html @@ -33,7 +33,7 @@ - + diff --git a/Release/test_coverage/Base/index-sort-b.html b/Release/test_coverage/Base/index-sort-b.html index 044d2fb68f79..ffc776ae4b38 100644 --- a/Release/test_coverage/Base/index-sort-b.html +++ b/Release/test_coverage/Base/index-sort-b.html @@ -27,13 +27,13 @@ - + - + - + @@ -49,9 +49,9 @@ - - - + + +
   1
-   2
-   3
-   4
-   5
-   6
-   7
-   8
-   9
-  10
-  11
-  12
-  13
-  14
-  15
-  16
-  17
-  18
-  19
-  20
-  21
-  22
-  23
-  24
-  25
-  26
-  27
-  28
-  29
-  30
-  31
-  32
-  33
-  34
-  35
-  36
-  37
-  38
-  39
-  40
-  41
-  42
-  43
-  44
-  45
-  46
-  47
-  48
-  49
-  50
-  51
-  52
-  53
-  54
-  55
-  56
-  57
-  58
-  59
-  60
-  61
-  62
-  63
-  64
-  65
-  66
-  67
-  68
-  69
-  70
-  71
-  72
-  73
-  74
-  75
-  76
-  77
-  78
-  79
-  80
-  81
-  82
-  83
-  84
-  85
-  86
-  87
-  88
-  89
-  90
-  91
-  92
-  93
-  94
-  95
-  96
-  97
-  98
-  99
- 100
- 101
- 102
- 103
- 104
- 105
- 106
- 107
- 108
- 109
- 110
- 111
- 112
- 113
- 114
- 115
- 116
- 117
- 118
- 119
- 120
- 121
- 122
- 123
- 124
- 125
- 126
- 127
- 128
- 129
- 130
- 131
- 132
- 133
- 134
- 135
- 136
- 137
- 138
- 139
- 140
- 141
- 142
- 143
- 144
- 145
- 146
- 147
- 148
- 149
- 150
- 151
- 152
- 153
- 154
- 155
- 156
- 157
- 158
- 159
- 160
- 161
- 162
- 163
- 164
- 165
- 166
- 167
- 168
- 169
- 170
- 171
- 172
- 173
- 174
- 175
- 176
- 177
- 178
- 179
- 180
- 181
- 182
- 183
- 184
- 185
- 186
- 187
- 188
- 189
- 190
- 191
- 192
- 193
- 194
- 195
- 196
- 197
- 198
- 199
- 200
- 201
- 202
- 203
- 204
- 205
- 206
- 207
- 208
- 209
- 210
- 211
- 212
- 213
- 214
- 215
- 216
- 217
- 218
- 219
- 220
- 221
- 222
- 223
- 224
- 225
- 226
- 227
- 228
- 229
- 230
- 231
- 232
- 233
- 234
- 235
- 236
- 237
- 238
- 239
- 240
- 241
- 242
- 243
- 244
- 245
- 246
- 247
- 248
- 249
- 250
- 251
- 252
- 253
- 254
- 255
- 256
- 257
- 258
- 259
- 260
- 261
- 262
- 263
- 264
- 265
- 266
- 267
- 268
- 269
- 270
- 271
- 272
- 273
- 274
- 275
- 276
- 277
- 278
- 279
- 280
- 281
- 282
- 283
- 284
- 285
- 286
- 287
- 288
- 289
- 290
- 291
- 292
- 293
- 294
- 295
- 296
- 297
- 298
- 299
- 300
- 301
- 302
- 303
- 304
- 305
- 306
- 307
- 308
- 309
- 310
- 311
- 312
- 313
- 314
- 315
- 316
- 317
- 318
- 319
- 320
- 321
- 322
- 323
- 324
- 325
- 326
- 327
- 328
- 329
- 330
- 331
- 332
- 333
- 334
- 335
- 336
- 337
- 338
- 339
- 340
- 341
- 342
- 343
- 344
- 345
- 346
- 347
- 348
- 349
- 350
- 351
- 352
- 353
- 354
- 355
- 356
- 357
- 358
- 359
- 360
- 361
- 362
- 363
- 364
- 365
- 366
- 367
- 368
- 369
- 370
- 371
- 372
- 373
- 374
- 375
- 376
- 377
- 378
- 379
- 380
- 381
- 382
- 383
- 384
- 385
- 386
- 387
- 388
- 389
- 390
- 391
- 392
- 393
- 394
- 395
- 396
- 397
- 398
- 399
- 400
- 401
- 402
- 403
- 404
- 405
- 406
- 407
- 408
- 409
- 410
- 411
- 412
- 413
- 414
- 415
- 416
- 417
- 418
- 419
- 420
- 421
- 422
- 423
- 424
- 425
- 426
- 427
- 428
- 429
- 430
- 431
- 432
- 433
- 434
- 435
- 436
- 437
- 438
- 439
- 440
- 441
- 442
- 443
- 444
- 445
- 446
- 447
- 448
- 449
- 450
- 451
- 452
- 453
- 454
- 455
- 456
- 457
- 458
- 459
- 460
- 461
- 462
- 463
- 464
- 465
- 466
- 467
- 468
- 469
- 470
- 471
- 472
- 473
- 474
- 475
- 476
- 477
- 478
- 479
- 480
- 481
- 482
- 483
- 484
- 485
- 486
- 487
- 488
- 489
- 490
- 491
- 492
- 493
- 494
- 495
- 496
- 497
- 498
- 499
- 500
- 501
- 502
- 503
- 504
- 505
- 506
- 507
- 508
- 509
- 510
- 511
- 512
- 513
- 514
- 515
- 516
- 517
- 518
- 519
- 520
- 521
- 522
- 523
- 524
- 525
- 526
- 527
- 528
- 529
- 530
- 531
- 532
- 533
- 534
- 535
- 536
- 537
- 538
- 539
- 540
- 541
- 542
- 543
- 544
- 545
- 546
- 547
- 548
- 549
- 550
- 551
- 552
- 553
- 554
- 555
- 556
- 557
- 558
- 559
- 560
- 561
- 562
- 563
- 564
- 565
- 566
- 567
- 568
- 569
- 570
- 571
- 572
- 573
- 574
- 575
- 576
- 577
- 578
- 579
- 580
- 581
- 582
- 583
- 584
- 585
- 586
- 587
- 588
- 589
- 590
- 591
- 592
- 593
- 594
- 595
- 596
- 597
- 598
- 599
- 600
- 601
- 602
- 603
- 604
- 605
- 606
- 607
- 608
- 609
- 610
- 611
- 612
- 613
- 614
- 615
- 616
- 617
- 618
- 619
- 620
- 621
- 622
- 623
- 624
- 625
- 626
- 627
- 628
- 629
- 630
- 631
- 632
- 633
- 634
- 635
- 636
- 637
- 638
- 639
- 640
- 641
- 642
- 643
- 644
- 645
- 646
- 647
- 648
- 649
- 650
- 651
- 652
- 653
- 654
- 655
- 656
- 657
- 658
- 659
- 660
- 661
- 662
- 663
- 664
- 665
- 666
- 667
- 668
- 669
- 670
- 671
- 672
- 673
- 674
- 675
- 676
- 677
- 678
- 679
- 680
- 681
- 682
- 683
- 684
- 685
- 686
- 687
- 688
- 689
- 690
- 691
- 692
- 693
- 694
- 695
- 696
- 697
- 698
- 699
- 700
- 701
- 702
- 703
- 704
- 705
- 706
- 707
- 708
- 709
- 710
- 711
- 712
- 713
- 714
- 715
- 716
- 717
- 718
- 719
- 720
- 721
- 722
- 723
- 724
- 725
- 726
- 727
- 728
- 729
- 730
- 731
- 732
- 733
- 734
- 735
- 736
- 737
- 738
- 739
- 740
- 741
- 742
- 743
- 744
- 745
- 746
- 747
- 748
- 749
- 750
- 751
- 752
- 753
- 754
- 755
- 756
- 757
- 758
- 759
- 760
- 761
- 762
- 763
- 764
- 765
- 766
- 767
- 768
- 769
- 770
- 771
- 772
- 773
- 774
- 775
- 776
- 777
- 778
- 779
- 780
- 781
- 782
- 783
- 784
- 785
- 786
- 787
- 788
- 789
- 790
- 791
- 792
- 793
- 794
- 795
- 796
- 797
- 798
- 799
- 800
- 801
- 802
- 803
- 804
- 805
- 806
- 807
- 808
- 809
- 810
- 811
- 812
- 813
- 814
- 815
- 816
- 817
- 818
- 819
- 820
- 821
- 822
- 823
- 824
- 825
- 826
- 827
- 828
- 829
- 830
- 831
- 832
- 833
- 834
- 835
- 836
- 837
- 838
- 839
- 840
- 841
- 842
- 843
- 844
- 845
- 846
- 847
- 848
- 849
- 850
- 851
- 852
- 853
- 854
- 855
- 856
- 857
- 858
- 859
- 860
- 861
- 862
- 863
- 864
- 865
- 866
- 867
- 868
- 869
- 870
- 871
- 872
- 873
- 874
- 875
- 876
- 877
- 878
- 879
- 880
- 881
- 882
- 883
- 884
- 885
- 886
- 887
- 888
- 889
- 890
- 891
- 892
- 893
- 894
- 895
- 896
- 897
- 898
- 899
- 900
- 901
- 902
- 903
- 904
- 905
- 906
- 907
- 908
- 909
- 910
- 911
- 912
- 913
- 914
- 915
- 916
- 917
- 918
- 919
- 920
- 921
- 922
- 923
- 924
- 925
- 926
- 927
- 928
- 929
- 930
- 931
- 932
- 933
- 934
- 935
- 936
- 937
- 938
- 939
- 940
- 941
- 942
- 943
- 944
- 945
- 946
- 947
- 948
- 949
- 950
- 951
- 952
- 953
- 954
- 955
- 956
- 957
- 958
- 959
- 960
- 961
- 962
- 963
- 964
- 965
- 966
- 967
- 968
- 969
- 970
- 971
- 972
- 973
- 974
- 975
- 976
- 977
- 978
- 979
- 980
- 981
- 982
- 983
- 984
- 985
- 986
- 987
- 988
- 989
- 990
- 991
- 992
- 993
- 994
- 995
- 996
- 997
- 998
- 999
-1000
-1001
-1002
-1003
-1004
-1005
-1006
-1007
-1008
-1009
// *****************************************************************************
+
  1
+  2
+  3
+  4
+  5
+  6
+  7
+  8
+  9
+ 10
+ 11
+ 12
+ 13
+ 14
+ 15
+ 16
+ 17
+ 18
+ 19
+ 20
+ 21
+ 22
+ 23
+ 24
+ 25
+ 26
+ 27
+ 28
+ 29
+ 30
+ 31
+ 32
+ 33
+ 34
+ 35
+ 36
+ 37
+ 38
+ 39
+ 40
+ 41
+ 42
+ 43
+ 44
+ 45
+ 46
+ 47
+ 48
+ 49
+ 50
+ 51
+ 52
+ 53
+ 54
+ 55
+ 56
+ 57
+ 58
+ 59
+ 60
+ 61
+ 62
+ 63
+ 64
+ 65
+ 66
+ 67
+ 68
+ 69
+ 70
+ 71
+ 72
+ 73
+ 74
+ 75
+ 76
+ 77
+ 78
+ 79
+ 80
+ 81
+ 82
+ 83
+ 84
+ 85
+ 86
+ 87
+ 88
+ 89
+ 90
+ 91
+ 92
+ 93
+ 94
+ 95
+ 96
+ 97
+ 98
+ 99
+100
+101
+102
+103
+104
+105
+106
+107
+108
+109
+110
+111
+112
+113
+114
+115
+116
+117
+118
+119
+120
+121
+122
+123
+124
+125
+126
+127
+128
+129
+130
+131
+132
+133
+134
+135
+136
+137
+138
+139
+140
+141
+142
+143
+144
+145
+146
+147
+148
+149
+150
+151
+152
+153
+154
+155
+156
+157
+158
+159
+160
+161
+162
+163
+164
+165
+166
+167
+168
+169
+170
+171
+172
+173
+174
+175
+176
+177
+178
+179
+180
+181
+182
+183
+184
+185
+186
+187
+188
+189
+190
+191
+192
+193
+194
+195
+196
+197
+198
+199
+200
+201
+202
+203
+204
+205
+206
+207
+208
+209
+210
+211
+212
+213
+214
+215
+216
+217
+218
+219
+220
+221
+222
+223
+224
+225
+226
+227
+228
+229
+230
+231
+232
+233
+234
+235
+236
+237
+238
+239
+240
+241
+242
+243
+244
+245
+246
+247
+248
+249
+250
+251
+252
+253
+254
+255
+256
+257
+258
+259
+260
+261
+262
+263
+264
+265
+266
+267
+268
+269
+270
+271
+272
+273
+274
+275
+276
+277
+278
+279
+280
+281
+282
+283
+284
+285
+286
+287
+288
+289
+290
+291
+292
+293
+294
+295
+296
+297
+298
+299
+300
+301
+302
+303
+304
+305
+306
+307
+308
+309
+310
+311
+312
+313
+314
+315
+316
+317
+318
+319
+320
+321
+322
+323
+324
+325
+326
+327
+328
+329
+330
+331
+332
+333
+334
+335
+336
+337
+338
+339
+340
+341
+342
+343
+344
+345
+346
+347
+348
+349
+350
+351
+352
+353
+354
+355
+356
+357
+358
+359
+360
+361
+362
+363
+364
+365
+366
+367
+368
+369
+370
+371
+372
+373
+374
+375
+376
+377
+378
+379
+380
+381
+382
+383
+384
+385
+386
+387
+388
+389
+390
+391
+392
+393
+394
+395
+396
+397
+398
+399
+400
+401
+402
+403
+404
+405
+406
+407
+408
+409
+410
+411
+412
+413
+414
+415
+416
+417
+418
+419
+420
+421
+422
+423
+424
+425
+426
+427
+428
+429
+430
+431
+432
+433
+434
+435
+436
+437
+438
+439
+440
+441
+442
+443
+444
+445
+446
+447
+448
+449
+450
+451
+452
+453
+454
+455
+456
+457
+458
+459
+460
+461
+462
+463
+464
+465
+466
+467
+468
+469
+470
+471
+472
+473
+474
+475
+476
+477
+478
+479
+480
+481
+482
+483
+484
+485
+486
+487
+488
+489
+490
+491
+492
// *****************************************************************************
 /*!
-  \file      src/PDE/Integrate/MultiMatTerms.cpp
+  \file      src/PDE/Integrate/Surface.cpp
   \copyright 2012-2015 J. Bakosi,
              2016-2018 Los Alamos National Security, LLC.,
              2019-2021 Triad National Security, LLC.
              All rights reserved. See the LICENSE file for details.
-  \brief     Functions for computing volume integrals of multi-material terms
-     using DG methods
-  \details   This file contains functionality for computing volume integrals of
-     non-conservative and pressure relaxation terms that appear in the
-     multi-material hydrodynamic equations, using the discontinuous Galerkin
-     method for various orders of numerical representation.
-*/
-// *****************************************************************************
-
-#include "QuinoaConfig.hpp"
-
-#include "MultiMatTerms.hpp"
-#include "Vector.hpp"
-#include "Quadrature.hpp"
-#include "MultiMat/MultiMatIndexing.hpp"
-#include "Reconstruction.hpp"
-#include "Inciter/InputDeck/InputDeck.hpp"
-#include "EoS/GetMatProp.hpp"
-
-namespace inciter {
-extern ctr::InputDeck g_inputdeck;
-}
-
-// Lapacke forward declarations
-extern "C" {
-
-using lapack_int = long;
-
-#define LAPACK_ROW_MAJOR 101
-
-lapack_int LAPACKE_dsysv( int, char, lapack_int, lapack_int, double*,
-    lapack_int, lapack_int*, double*, lapack_int );
-
-}
-
-namespace tk {
-
-void
-nonConservativeInt( std::size_t nmat,
-                    const std::vector< inciter::EOS >& mat_blk,
-                    const std::size_t ndof,
-                    const std::size_t rdof,
-                    const std::size_t nelem,
-                    const std::vector< std::size_t >& inpoel,
-                    const UnsMesh::Coords& coord,
-                    const Fields& geoElem,
-                    const Fields& U,
-                    const Fields& P,
-                    const std::vector< std::vector< tk::real > >& riemannDeriv,
-                    const std::vector< std::size_t >& ndofel,
-                    Fields& R,
-                    int intsharp )
-// *****************************************************************************
-//  Compute volume integrals for multi-material DG
-//! \details This is called for multi-material DG, computing volume integrals of
-//!   terms in the volume fraction and energy equations, which do not exist in
-//!   the single-material flow formulation (for `CompFlow` DG). For further
-//!   details see Pelanti, M., & Shyue, K. M. (2019). A numerical model for
-//!   multiphase liquid–vapor–gas flows with interfaces and cavitation.
-//!   International Journal of Multiphase Flow, 113, 208-230.
-//! \param[in] nmat Number of materials in this PDE system
-//! \param[in] mat_blk EOS material block
-//! \param[in] ndof Maximum number of degrees of freedom
-//! \param[in] rdof Maximum number of reconstructed degrees of freedom
-//! \param[in] nelem Total number of elements
-//! \param[in] inpoel Element-node connectivity
-//! \param[in] coord Array of nodal coordinates
-//! \param[in] geoElem Element geometry array
-//! \param[in] U Solution vector at recent time step
-//! \param[in] P Vector of primitive quantities at recent time step
-//! \param[in] riemannDeriv Derivatives of partial-pressures and velocities
-//!   computed from the Riemann solver for use in the non-conservative terms
-//! \param[in] ndofel Vector of local number of degrees of freedome
-//! \param[in,out] R Right-hand side vector added to
-//! \param[in] intsharp Interface reconstruction indicator
-// *****************************************************************************
-{
-  using inciter::volfracIdx;
-  using inciter::densityIdx;
-  using inciter::momentumIdx;
-  using inciter::energyIdx;
-  using inciter::velocityIdx;
-  using inciter::deformIdx;
-  using inciter::newSolidsAccFn;
+  \brief     Functions for computing internal surface integrals of a system
+     of PDEs in DG methods
+  \details   This file contains functionality for computing internal surface
+     integrals of a system of PDEs used in discontinuous Galerkin methods for
+     various orders of numerical representation.
+*/
+// *****************************************************************************
+
+#include <array>
+
+#include "Surface.hpp"
+#include "Vector.hpp"
+#include "Quadrature.hpp"
+#include "Reconstruction.hpp"
+#include "Integrate/SolidTerms.hpp"
+#include "Inciter/InputDeck/InputDeck.hpp"
+#include "MultiMat/MiscMultiMatFns.hpp"
+
+namespace inciter {
+extern ctr::InputDeck g_inputdeck;
+}
+
+namespace tk {
+
+void
+surfInt( std::size_t nmat,
+         const std::vector< inciter::EOS >& mat_blk,
+         real t,
+         const std::size_t ndof,
+         const std::size_t rdof,
+         const std::vector< std::size_t >& inpoel,
+         const std::vector< std::size_t >& /*solidx*/,
+         const UnsMesh::Coords& coord,
+         const inciter::FaceData& fd,
+         const Fields& geoFace,
+         const Fields& geoElem,
+         const RiemannFluxFn& flux,
+         const VelFn& vel,
+         const Fields& U,
+         const Fields& P,
+         const std::vector< std::size_t >& ndofel,
+         const tk::real /*dt*/,
+         Fields& R,
+         std::vector< std::vector< tk::real > >&,
+         std::vector< std::vector< tk::real > >&,
+         std::vector< std::vector< tk::real > >& riemannDeriv,
+         int intsharp )
+// *****************************************************************************
+//  Compute internal surface flux integrals
+//! \param[in] nmat Number of materials in this PDE system
+//! \param[in] mat_blk EOS material block
+//! \param[in] t Physical time
+//! \param[in] ndof Maximum number of degrees of freedom
+//! \param[in] rdof Maximum number of reconstructed degrees of freedom
+//! \param[in] inpoel Element-node connectivity
+// //! \param[in] solidx Material index indicator
+//! \param[in] coord Array of nodal coordinates
+//! \param[in] fd Face connectivity and boundary conditions object
+//! \param[in] geoFace Face geometry array
+//! \param[in] geoElem Element geometry array
+//! \param[in] flux Riemann flux function to use
+//! \param[in] vel Function to use to query prescribed velocity (if any)
+//! \param[in] U Solution vector at recent time step
+//! \param[in] P Vector of primitives at recent time step
+//! \param[in] ndofel Vector of local number of degrees of freedom
+// //! \param[in] dt Delta time
+//! \param[in,out] R Right-hand side vector computed
+//! \param[in,out] vriem Vector of the riemann velocity
+//! \param[in,out] riemannLoc Vector of coordinates where Riemann velocity data
+//!   is available
+//! \param[in,out] riemannDeriv Derivatives of partial-pressures and velocities
+//!   computed from the Riemann solver for use in the non-conservative terms.
+//!   These derivatives are used only for multi-material hydro and unused for
+//!   single-material compflow and linear transport.
+//! \param[in] intsharp Interface compression tag, an optional argument, with
+//!   default 0, so that it is unused for single-material and transport.
+// *****************************************************************************
+{
+  const auto& esuf = fd.Esuf();
+  const auto& inpofa = fd.Inpofa();
+
+  const auto& cx = coord[0];
+  const auto& cy = coord[1];
+  const auto& cz = coord[2];
 
-  const auto& solidx =
-    inciter::g_inputdeck.get< tag::matidxmap, tag::solidx >();
-
-  const auto& cx = coord[0];
-  const auto& cy = coord[1];
-  const auto& cz = coord[2];
-
-  auto ncomp = U.nprop()/rdof;
-  auto nprim = P.nprop()/rdof;
-
-  // compute volume integrals
-  for (std::size_t e=0; e<nelem; ++e)
-  {
-    auto ng = tk::NGvol(ndofel[e]);
+  auto ncomp = U.nprop()/rdof;<--- Variable 'ncomp' is assigned a value that is never used.
+  auto nprim = P.nprop()/rdof;<--- Variable 'nprim' is assigned a value that is never used.
+
+  //// Determine if we have solids in our problem
+  //bool haveSolid = inciter::haveSolid(nmat, solidx);
+
+  //Assert( (nmat==1 ? riemannDeriv.empty() : true), "Non-empty Riemann "
+  //        "derivative vector for single material compflow" );
+
+  // compute internal surface flux integrals
+  for (auto f=fd.Nbfac(); f<esuf.size()/2; ++f)
+  {
+    Assert( esuf[2*f] > -1 && esuf[2*f+1] > -1, "Interior element detected "
+            "as -1" );
 
-    // arrays for quadrature points
-    std::array< std::vector< real >, 3 > coordgp;
-    std::vector< real > wgp;
-
-    coordgp[0].resize( ng );
-    coordgp[1].resize( ng );
-    coordgp[2].resize( ng );
-    wgp.resize( ng );
-
-    GaussQuadratureTet( ng, coordgp, wgp );
-
-    // Extract the element coordinates
-    std::array< std::array< real, 3>, 4 > coordel {{
-      {{ cx[ inpoel[4*e  ] ], cy[ inpoel[4*e  ] ], cz[ inpoel[4*e  ] ] }},
-      {{ cx[ inpoel[4*e+1] ], cy[ inpoel[4*e+1] ], cz[ inpoel[4*e+1] ] }},
-      {{ cx[ inpoel[4*e+2] ], cy[ inpoel[4*e+2] ], cz[ inpoel[4*e+2] ] }},
-      {{ cx[ inpoel[4*e+3] ], cy[ inpoel[4*e+3] ], cz[ inpoel[4*e+3] ] }}
-    }};
-
-    auto jacInv =
-            inverseJacobian( coordel[0], coordel[1], coordel[2], coordel[3] );
-
-    // Compute the derivatives of basis function for DG(P1)
-    std::array< std::vector<tk::real>, 3 > dBdx;
-    if (ndofel[e] > 1)
-      dBdx = eval_dBdx_p1( ndofel[e], jacInv );
-
-    // Gaussian quadrature
-    for (std::size_t igp=0; igp<ng; ++igp)
-    {
-      if (ndofel[e] > 4)
-        eval_dBdx_p2( igp, coordgp, jacInv, dBdx );
-
-      // If an rDG method is set up (P0P1), then, currently we compute the P1
-      // basis functions and solutions by default. This implies that P0P1 is
-      // unsupported in the p-adaptive DG (PDG).
-      std::size_t dof_el;
-      if (rdof > ndof)
-      {
-        dof_el = rdof;
-      }
-      else
-      {
-        dof_el = ndofel[e];
-      }
+    std::size_t el = static_cast< std::size_t >(esuf[2*f]);
+    std::size_t er = static_cast< std::size_t >(esuf[2*f+1]);
+
+    auto ng_l = tk::NGfa(ndofel[el]);
+    auto ng_r = tk::NGfa(ndofel[er]);
+
+    // When the number of gauss points for the left and right element are
+    // different, choose the larger ng
+    auto ng = std::max( ng_l, ng_r );
+
+    // arrays for quadrature points
+    std::array< std::vector< real >, 2 > coordgp;
+    std::vector< real > wgp;
+
+    coordgp[0].resize( ng );
+    coordgp[1].resize( ng );
+    wgp.resize( ng );
+
+    // get quadrature point weights and coordinates for triangle
+    GaussQuadratureTri( ng, coordgp, wgp );
+
+    // Extract the element coordinates
+    std::array< std::array< tk::real, 3>, 4 > coordel_l {{
+      {{ cx[ inpoel[4*el  ] ], cy[ inpoel[4*el  ] ], cz[ inpoel[4*el  ] ] }},
+      {{ cx[ inpoel[4*el+1] ], cy[ inpoel[4*el+1] ], cz[ inpoel[4*el+1] ] }},
+      {{ cx[ inpoel[4*el+2] ], cy[ inpoel[4*el+2] ], cz[ inpoel[4*el+2] ] }},
+      {{ cx[ inpoel[4*el+3] ], cy[ inpoel[4*el+3] ], cz[ inpoel[4*el+3] ] }} }};
+
+    std::array< std::array< tk::real, 3>, 4 > coordel_r {{
+      {{ cx[ inpoel[4*er  ] ], cy[ inpoel[4*er  ] ], cz[ inpoel[4*er  ] ] }},
+      {{ cx[ inpoel[4*er+1] ], cy[ inpoel[4*er+1] ], cz[ inpoel[4*er+1] ] }},
+      {{ cx[ inpoel[4*er+2] ], cy[ inpoel[4*er+2] ], cz[ inpoel[4*er+2] ] }},
+      {{ cx[ inpoel[4*er+3] ], cy[ inpoel[4*er+3] ], cz[ inpoel[4*er+3] ] }} }};
+
+    // Compute the determinant of Jacobian matrix
+    auto detT_l =
+      Jacobian( coordel_l[0], coordel_l[1], coordel_l[2], coordel_l[3] );
+    auto detT_r =
+      Jacobian( coordel_r[0], coordel_r[1], coordel_r[2], coordel_r[3] );
+
+    // Extract the face coordinates
+    std::array< std::array< tk::real, 3>, 3 > coordfa {{
+      {{ cx[ inpofa[3*f  ] ], cy[ inpofa[3*f  ] ], cz[ inpofa[3*f  ] ] }},
+      {{ cx[ inpofa[3*f+1] ], cy[ inpofa[3*f+1] ], cz[ inpofa[3*f+1] ] }},
+      {{ cx[ inpofa[3*f+2] ], cy[ inpofa[3*f+2] ], cz[ inpofa[3*f+2] ] }} }};
 
-      // Compute the basis function
-      auto B =
-        eval_basis( dof_el, coordgp[0][igp], coordgp[1][igp], coordgp[2][igp] );
-
-      auto wt = wgp[igp] * geoElem(e, 0);
-
-      auto state = evalPolynomialSol(mat_blk, intsharp, ncomp, nprim,
-        rdof, nmat, e, dof_el, inpoel, coord, geoElem,
-        {{coordgp[0][igp], coordgp[1][igp], coordgp[2][igp]}}, B, U, P);
-
-      // get bulk properties
-      tk::real rhob(0.0);
-      for (std::size_t k=0; k<nmat; ++k)
-          rhob += state[densityIdx(nmat, k)];
-
-      // get the velocity vector
-      std::array< tk::real, 3 > vel{{ state[ncomp+velocityIdx(nmat, 0)],
-                                      state[ncomp+velocityIdx(nmat, 1)],
-                                      state[ncomp+velocityIdx(nmat, 2)] }};
-
-      std::vector< tk::real > ymat(nmat, 0.0);
-      std::array< tk::real, 3 > dap{{0.0, 0.0, 0.0}};
-      for (std::size_t k=0; k<nmat; ++k)
-      {
-        ymat[k] = state[densityIdx(nmat, k)]/rhob;
-
-        std::size_t mark(3*k);
-        if (solidx[k] > 0) mark = 3*nmat+ndof+3*(solidx[k]-1);
-
-        for (std::size_t idir=0; idir<3; ++idir)
-          dap[idir] += riemannDeriv[mark+idir][e];
-      }
-
-      // compute non-conservative terms
-      std::vector< std::vector< tk::real > > ncf
-        (ncomp, std::vector<tk::real>(ndof,0.0));
-
-      for (std::size_t idir=0; idir<3; ++idir)
-        for(std::size_t idof=0; idof<ndof; ++idof)
-          ncf[momentumIdx(nmat, idir)][idof] = 0.0;
-
-      for (std::size_t k=0; k<nmat; ++k)
-      {
-        // evaluate non-conservative term for energy equation
-        std::size_t mark(3*k);
-        if (solidx[k] > 0) mark = 3*nmat+ndof+3*(solidx[k]-1);
-
-        for(std::size_t idof=0; idof<ndof; ++idof)
-        {
-          ncf[densityIdx(nmat, k)][idof] = 0.0;
-
-          for (std::size_t idir=0; idir<3; ++idir)
-            ncf[energyIdx(nmat, k)][idof] -= vel[idir] * ( ymat[k]*dap[idir]
-                                                  - riemannDeriv[mark+idir][e] );
-        }
-
-        // Evaluate non-conservative term for volume fraction equation:
-        // Here we make an assumption that the derivative of Riemann velocity
-        // times the basis function is constant. Therefore, when P0P1/DGP1/DGP2
-        // are used for constant velocity problems, the discretization is
-        // consistent. However, for a general problem with varying velocity,
-        // there will be errors since the said derivative is not constant.
-        // A discretization that solves this issue has not been implemented yet.
-        // Nevertheless, this does not affect high-order accuracy in
-        // single material regions for problems with sharp interfaces. Since
-        // volume fractions are nearly constant in such regions, using
-        // high-order for volume fractions does not show any benefits over
-        // THINC. Therefore, for such problems, we only use FV for the volume
-        // fractions, and these non-conservative high-order terms do not need
-        // to be computed.
-        // In summary, high-order discretization for non-conservative terms in
-        // volume fraction equations is avoided for sharp interface problems.
-        if (ndof <= 4 || intsharp == 1) {
-          for(std::size_t idof=0; idof<ndof; ++idof)
-            ncf[volfracIdx(nmat, k)][idof] = state[volfracIdx(nmat, k)]
-                                           * riemannDeriv[3*nmat+idof][e];
-        } else if (intsharp == 0) {     // If DGP2 without THINC
-          // DGP2 is discretized differently than DGP1/FV to guarantee 3rd order
-          // convergence for the testcases with uniform and constant velocity.
-
-          // P0 contributions for all equations
-          for(std::size_t idof=0; idof<ndof; ++idof)
-          ncf[volfracIdx(nmat, k)][idof] = state[volfracIdx(nmat, k)]
-                                         * riemannDeriv[3*nmat][e] * B[idof];
-          // High order contributions
-          for(std::size_t idof=1; idof<ndof; ++idof)
-            for(std::size_t idir=0; idir<3; ++idir)
-            ncf[volfracIdx(nmat, k)][idof] += state[volfracIdx(nmat, k)]
-                                            * vel[idir] * dBdx[idir][idof];
-        }
-      }
-
-      updateRhsNonCons( ncomp, nmat, ndof, ndofel[e], wt, e, B, dBdx, ncf, R );
-    }
-  }
-}
-
-void
-updateRhsNonCons(
-  ncomp_t ncomp,
-  const std::size_t nmat,
-  const std::size_t ndof,
-  [[maybe_unused]] const std::size_t ndof_el,
-  const tk::real wt,
-  const std::size_t e,
-  const std::vector<tk::real>& B,
-  [[maybe_unused]] const std::array< std::vector<tk::real>, 3 >& dBdx,
-  const std::vector< std::vector< tk::real > >& ncf,
-  Fields& R )
-// *****************************************************************************
-//  Update the rhs by adding the non-conservative term integrals
-//! \param[in] ncomp Number of scalar components in this PDE system
-//! \param[in] nmat Number of materials
-//! \param[in] ndof Maximum number of degrees of freedom
-//! \param[in] ndof_el Number of degrees of freedom for local element
-//! \param[in] wt Weight of gauss quadrature point
-//! \param[in] e Element index
-//! \param[in] B Basis function evaluated at local quadrature point
-//! \param[in] dBdx Vector of basis function derivatives
-//! \param[in] ncf Vector of non-conservative terms
-//! \param[in,out] R Right-hand side vector computed
-// *****************************************************************************
-{
-  using inciter::volfracIdx;
-  using inciter::energyIdx;
-  using inciter::volfracDofIdx;
-  using inciter::energyDofIdx;
-
-  //Assert( dBdx[0].size() == ndof_el,
-  //        "Size mismatch for basis function derivatives" );
-  //Assert( dBdx[1].size() == ndof_el,
-  //        "Size mismatch for basis function derivatives" );
-  //Assert( dBdx[2].size() == ndof_el,
-  //        "Size mismatch for basis function derivatives" );
-  //Assert( ncf.size() == ncomp,
-  //        "Size mismatch for non-conservative term" );
-  Assert( ncf.size() == ncomp, "Size mismatch for non-conservative term" );
-
-  for (ncomp_t c=0; c<ncomp; ++c)
-  {
-    auto mark = c*ndof;
-    R(e, mark) += wt * ncf[c][0];
-  }
-
-  if( ndof_el > 1)
-  {
-    // Update rhs with distributions from volume fraction and energy equations
-    for (std::size_t k=0; k<nmat; ++k)
-    {
-      for(std::size_t idof = 1; idof < ndof; idof++)
-      {
-        R(e, volfracDofIdx(nmat,k,ndof,idof)) +=
-          wt * ncf[volfracIdx(nmat,k)][idof];
-        R(e, energyDofIdx(nmat,k,ndof,idof)) +=
-          wt * ncf[energyIdx(nmat,k)][idof] * B[idof];
-      }
-    }
-  }
-}
-
-std::vector< tk::real >
-nonConservativeIntFV(
-  std::size_t nmat,
-  const std::size_t rdof,
-  const std::size_t e,
-  const std::array< tk::real, 3 >& fn,
-  const Fields& U,
-  const Fields& P,
-  const std::vector< tk::real >& var_riemann )
-// *****************************************************************************
-//  Compute integrals of non-conservative terms for multi-material FV
-//! \details This is called for multi-material FV, computing integrals of
-//!   terms in the volume fraction and energy equations, which do not exist in
-//!   the single-material flow formulation (for `CompFlow`). For further
-//!   details see Pelanti, M., & Shyue, K. M. (2019). A numerical model for
-//!   multiphase liquid–vapor–gas flows with interfaces and cavitation.
-//!   International Journal of Multiphase Flow, 113, 208-230.
-//! \param[in] nmat Number of materials in this PDE system
-//! \param[in] rdof Maximum number of reconstructed degrees of freedom
-//! \param[in] e Element for which contribution is to be calculated
-//! \param[in] fn Face normal
-//! \param[in] U Solution vector at recent time step
-//! \param[in] P Vector of primitive quantities at recent time step
-//! \param[in] var_riemann Riemann-values of partial-pressures and velocities
-//!   computed from the Riemann solver for use in the non-conservative terms
-// *****************************************************************************
-{
-  using inciter::volfracIdx;
-  using inciter::densityIdx;
-  using inciter::momentumIdx;
-  using inciter::energyIdx;
-  using inciter::velocityIdx;
-  using inciter::volfracDofIdx;
-  using inciter::densityDofIdx;
-  using inciter::velocityDofIdx;
-
-  auto ncomp = U.nprop()/rdof;
+    std::array< real, 3 >
+      fn{{ geoFace(f,1), geoFace(f,2), geoFace(f,3) }};
+
+    // Gaussian quadrature
+    for (std::size_t igp=0; igp<ng; ++igp)
+    {
+      // Compute the coordinates of quadrature point at physical domain
+      auto gp = eval_gp( igp, coordfa, coordgp );
+
+      // In order to determine the high-order solution from the left and right
+      // elements at the surface quadrature points, the basis functions from
+      // the left and right elements are needed. For this, a transformation to
+      // the reference coordinates is necessary, since the basis functions are
+      // defined on the reference tetrahedron only.
+      // The transformation relations are shown below:
+      //  xi   = Jacobian( coordel[0], gp, coordel[2], coordel[3] ) / detT
+      //  eta  = Jacobian( coordel[0], coordel[2], gp, coordel[3] ) / detT
+      //  zeta = Jacobian( coordel[0], coordel[2], coordel[3], gp ) / detT
+
+      // If an rDG method is set up (P0P1), then, currently we compute the P1
+      // basis functions and solutions by default. This implies that P0P1 is
+      // unsupported in the p-adaptive DG (PDG). This is a workaround until we
+      // have rdofel, which is needed to distinguish between ndofs and rdofs per
+      // element for pDG.
+      std::size_t dof_el, dof_er;
+      if (rdof > ndof)
+      {
+        dof_el = rdof;
+        dof_er = rdof;
+      }
+      else
+      {
+        dof_el = ndofel[el];
+        dof_er = ndofel[er];
+      }
+
+      std::array< tk::real, 3> ref_gp_l{
+        Jacobian( coordel_l[0], gp, coordel_l[2], coordel_l[3] ) / detT_l,
+        Jacobian( coordel_l[0], coordel_l[1], gp, coordel_l[3] ) / detT_l,
+        Jacobian( coordel_l[0], coordel_l[1], coordel_l[2], gp ) / detT_l };
+      std::array< tk::real, 3> ref_gp_r{
+        Jacobian( coordel_r[0], gp, coordel_r[2], coordel_r[3] ) / detT_r,
+        Jacobian( coordel_r[0], coordel_r[1], gp, coordel_r[3] ) / detT_r,
+        Jacobian( coordel_r[0], coordel_r[1], coordel_r[2], gp ) / detT_r };
+
+      //Compute the basis functions
+      auto B_l = eval_basis( dof_el, ref_gp_l[0], ref_gp_l[1], ref_gp_l[2] );
+      auto B_r = eval_basis( dof_er, ref_gp_r[0], ref_gp_r[1], ref_gp_r[2] );
+
+      auto wt = wgp[igp] * geoFace(f,0);<--- Variable 'wt' is assigned a value that is never used.
+
+      std::array< std::vector< real >, 2 > state;
+
+      state[0] = evalPolynomialSol(mat_blk, intsharp, ncomp, nprim, rdof,
+        nmat, el, dof_el, inpoel, coord, geoElem, ref_gp_l, B_l, U, P);
+      state[1] = evalPolynomialSol(mat_blk, intsharp, ncomp, nprim, rdof,
+        nmat, er, dof_er, inpoel, coord, geoElem, ref_gp_r, B_r, U, P);
+
+      Assert( state[0].size() == ncomp+nprim, "Incorrect size for "
+              "appended boundary state vector" );
+      Assert( state[1].size() == ncomp+nprim, "Incorrect size for "
+              "appended boundary state vector" );
+
+      // evaluate prescribed velocity (if any)
+      auto v = vel( ncomp, gp[0], gp[1], gp[2], t );
+
+      // compute flux
+      auto fl = flux( mat_blk, fn, state, v );
+
+      // Add the surface integration term to the rhs
+      update_rhs_fa( ncomp, nmat, ndof, ndofel[el], ndofel[er], wt, fn,
+                     el, er, fl, B_l, B_r, R, riemannDeriv );
+    }
+  }
+}
+
+void
+update_rhs_fa( ncomp_t ncomp,
+               std::size_t nmat,
+               const std::size_t ndof,
+               const std::size_t ndof_l,
+               const std::size_t ndof_r,
+               const tk::real wt,
+               const std::array< tk::real, 3 >& fn,
+               const std::size_t el,
+               const std::size_t er,
+               const std::vector< tk::real >& fl,
+               const std::vector< tk::real >& B_l,
+               const std::vector< tk::real >& B_r,
+               Fields& R,<--- Parameter 'R' can be declared with const
+               std::vector< std::vector< tk::real > >& riemannDeriv )
+// *****************************************************************************
+//  Update the rhs by adding the surface integration term
+//! \param[in] ncomp Number of scalar components in this PDE system
+//! \param[in] nmat Number of materials in this PDE system
+//! \param[in] ndof Maximum number of degrees of freedom
+//! \param[in] ndof_l Number of degrees of freedom for left element
+//! \param[in] ndof_r Number of degrees of freedom for right element
+//! \param[in] wt Weight of gauss quadrature point
+//! \param[in] fn Face/Surface normal
+//! \param[in] el Left element index
+//! \param[in] er Right element index
+//! \param[in] fl Surface flux
+//! \param[in] B_l Basis function for the left element
+//! \param[in] B_r Basis function for the right element
+//! \param[in,out] R Right-hand side vector computed
+//! \param[in,out] riemannDeriv Derivatives of partial-pressures and velocities
+//!   computed from the Riemann solver for use in the non-conservative terms.
+//!   These derivatives are used only for multi-material hydro and unused for
+//!   single-material compflow and linear transport.
+// *****************************************************************************
+{
+  // following lines commented until rdofel is made available.
+  //Assert( B_l.size() == ndof_l, "Size mismatch" );
+  //Assert( B_r.size() == ndof_r, "Size mismatch" );
+
+  using inciter::newSolidsAccFn;
+
+  const auto& solidx =
+    inciter::g_inputdeck.get< tag::matidxmap, tag::solidx >();
+
+  for (ncomp_t c=0; c<ncomp; ++c)
+  {
+    auto mark = c*ndof;
+    R(el, mark) -= wt * fl[c];
+    R(er, mark) += wt * fl[c];
+
+    if(ndof_l > 1)          //DG(P1)
+    {
+      R(el, mark+1) -= wt * fl[c] * B_l[1];
+      R(el, mark+2) -= wt * fl[c] * B_l[2];
+      R(el, mark+3) -= wt * fl[c] * B_l[3];
+    }
+
+    if(ndof_r > 1)          //DG(P1)
+    {
+      R(er, mark+1) += wt * fl[c] * B_r[1];
+      R(er, mark+2) += wt * fl[c] * B_r[2];
+      R(er, mark+3) += wt * fl[c] * B_r[3];
+    }
+
+    if(ndof_l > 4)          //DG(P2)
+    {
+      R(el, mark+4) -= wt * fl[c] * B_l[4];
+      R(el, mark+5) -= wt * fl[c] * B_l[5];
+      R(el, mark+6) -= wt * fl[c] * B_l[6];
+      R(el, mark+7) -= wt * fl[c] * B_l[7];
+      R(el, mark+8) -= wt * fl[c] * B_l[8];
+      R(el, mark+9) -= wt * fl[c] * B_l[9];
+    }
+
+    if(ndof_r > 4)          //DG(P2)
+    {
+      R(er, mark+4) += wt * fl[c] * B_r[4];
+      R(er, mark+5) += wt * fl[c] * B_r[5];
+      R(er, mark+6) += wt * fl[c] * B_r[6];
+      R(er, mark+7) += wt * fl[c] * B_r[7];
+      R(er, mark+8) += wt * fl[c] * B_r[8];
+      R(er, mark+9) += wt * fl[c] * B_r[9];
+    }
+  }
+
+  // Prep for non-conservative terms in multimat
+  if (fl.size() > ncomp)
+  {
+    // Gradients of partial pressures
+    for (std::size_t k=0; k<nmat; ++k)
+    {
+      for (std::size_t idir=0; idir<3; ++idir)
+      {
+        riemannDeriv[3*k+idir][el] += wt * fl[ncomp+k] * fn[idir];
+        riemannDeriv[3*k+idir][er] -= wt * fl[ncomp+k] * fn[idir];
+      }
+    }
+
+    // Divergence of velocity multiples basis fucntion( d(uB) / dx )
+    for(std::size_t idof = 0; idof < ndof; idof++) {
+      riemannDeriv[3*nmat+idof][el] += wt * fl[ncomp+nmat] * B_l[idof];
+      riemannDeriv[3*nmat+idof][er] -= wt * fl[ncomp+nmat] * B_r[idof];
+    }
+
+    // Divergence of asigma: d(asig_ij)/dx_j
+    for (std::size_t k=0; k<nmat; ++k)
+      if (solidx[k] > 0)
+      {
+        std::size_t mark = ncomp+nmat+1+3*(solidx[k]-1);
+
+        for (std::size_t i=0; i<3; ++i)
+        {
+          riemannDeriv[3*nmat+ndof+3*(solidx[k]-1)+i][el] -=
+            wt * fl[mark+i];
+          riemannDeriv[3*nmat+ndof+3*(solidx[k]-1)+i][er] +=
+            wt * fl[mark+i];
+        }
+      }
+  }
+}
 
-  // get bulk properties
-  tk::real rhob(0.0), p_face(0.0);
-  for (std::size_t k=0; k<nmat; ++k)
-  {
-    rhob += U(e, densityDofIdx(nmat,k,rdof,0));
-    p_face += var_riemann[k];
-  }
-
-  std::array< tk::real, 3 > vel{{ P(e, velocityDofIdx(nmat,0,rdof,0)),
-                                  P(e, velocityDofIdx(nmat,1,rdof,0)),
-                                  P(e, velocityDofIdx(nmat,2,rdof,0)) }};
-
-  // compute non-conservative terms
-  std::vector< tk::real > ncf(ncomp, 0.0);
-  std::vector< tk::real > ymat(nmat, 0.0);
-  for (std::size_t k=0; k<nmat; ++k)
-  {
-    ymat[k] = U(e, densityDofIdx(nmat,k,rdof,0))/rhob;
-
-    // evaluate non-conservative term for energy equation
-    for (std::size_t idir=0; idir<3; ++idir)
-      ncf[energyIdx(nmat, k)] -= vel[idir] * ( ymat[k]*p_face*fn[idir]
-                                            - var_riemann[k]*fn[idir] );
-
-    // evaluate non-conservative term for volume fraction equation
-    ncf[volfracIdx(nmat, k)] = U(e, volfracDofIdx(nmat,k,rdof,0))
-      * var_riemann[nmat];
-  }
-
-  return ncf;
-}
-
-void
-pressureRelaxationInt( std::size_t nmat,
-                       const std::vector< inciter::EOS >& mat_blk,
-                       const std::size_t ndof,
-                       const std::size_t rdof,
-                       const std::size_t nelem,
-                       const std::vector< std::size_t >& inpoel,
-                       const UnsMesh::Coords& coord,
-                       const Fields& geoElem,
-                       const Fields& U,
-                       const Fields& P,
-                       const std::vector< std::size_t >& ndofel,
-                       const tk::real ct,
-                       Fields& R,
-                       int intsharp )
-// *****************************************************************************
-//  Compute volume integrals of pressure relaxation terms in multi-material DG
-//! \details This is called for multi-material DG to compute volume integrals of
-//!   finite pressure relaxation terms in the volume fraction and energy
-//!   equations, which do not exist in the single-material flow formulation (for
-//!   `CompFlow` DG). For further details see Dobrev, V. A., Kolev, T. V.,
-//!   Rieben, R. N., & Tomov, V. Z. (2016). Multi‐material closure model for
-//!   high‐order finite element Lagrangian hydrodynamics. International Journal
-//!   for Numerical Methods in Fluids, 82(10), 689-706.
-//! \param[in] nmat Number of materials in this PDE system
-//! \param[in] mat_blk EOS material block
-//! \param[in] ndof Maximum number of degrees of freedom
-//! \param[in] rdof Maximum number of reconstructed degrees of freedom
-//! \param[in] nelem Total number of elements
-//! \param[in] inpoel Element-node connectivity
-//! \param[in] coord Array of nodal coordinates
-//! \param[in] geoElem Element geometry array
-//! \param[in] U Solution vector at recent time step
-//! \param[in] P Vector of primitive quantities at recent time step
-//! \param[in] ndofel Vector of local number of degrees of freedome
-//! \param[in] ct Pressure relaxation time-scale for this system
-//! \param[in,out] R Right-hand side vector added to
-//! \param[in] intsharp Interface reconstruction indicator
-// *****************************************************************************
-{
-  using inciter::volfracIdx;
-  using inciter::densityIdx;
-  using inciter::momentumIdx;
-  using inciter::energyIdx;
-  using inciter::pressureIdx;
-  using inciter::velocityIdx;
-  using inciter::deformIdx;
-
-  const auto& solidx =
-    inciter::g_inputdeck.get< tag::matidxmap, tag::solidx >();
-
-  auto ncomp = U.nprop()/rdof;
-  auto nprim = P.nprop()/rdof;
-
-  // compute volume integrals
-  for (std::size_t e=0; e<nelem; ++e)
-  {
-    auto dx = geoElem(e,4)/2.0;
-    auto ng = NGvol(ndofel[e]);
-
-    // arrays for quadrature points
-    std::array< std::vector< real >, 3 > coordgp;
-    std::vector< real > wgp;
-
-    coordgp[0].resize( ng );
-    coordgp[1].resize( ng );
-    coordgp[2].resize( ng );
-    wgp.resize( ng );
-
-    GaussQuadratureTet( ng, coordgp, wgp );
-
-    // Compute the derivatives of basis function for DG(P1)
-    std::array< std::vector<real>, 3 > dBdx;
+void
+surfIntFV(
+  std::size_t nmat,
+  const std::vector< inciter::EOS >& mat_blk,
+  real t,
+  const std::size_t rdof,
+  const std::vector< std::size_t >& inpoel,
+  const UnsMesh::Coords& coord,
+  const inciter::FaceData& fd,
+  const Fields& geoFace,
+  const Fields& geoElem,
+  const RiemannFluxFn& flux,
+  const VelFn& vel,
+  const Fields& U,
+  const Fields& P,
+  const std::vector< int >& srcFlag,
+  Fields& R,
+  int intsharp )
+// *****************************************************************************
+//  Compute internal surface flux integrals for second order FV
+//! \param[in] nmat Number of materials in this PDE system
+//! \param[in] t Physical time
+//! \param[in] rdof Maximum number of reconstructed degrees of freedom
+//! \param[in] inpoel Element-node connectivity
+//! \param[in] coord Array of nodal coordinates
+//! \param[in] fd Face connectivity and boundary conditions object
+//! \param[in] geoFace Face geometry array
+//! \param[in] geoElem Element geometry array
+//! \param[in] flux Riemann flux function to use
+//! \param[in] vel Function to use to query prescribed velocity (if any)
+//! \param[in] U Solution vector at recent time step
+//! \param[in] P Vector of primitives at recent time step
+//! \param[in] srcFlag Whether the energy source was added
+//! \param[in,out] R Right-hand side vector computed
+//! \param[in] intsharp Interface compression tag, an optional argument, with
+//!   default 0, so that it is unused for single-material and transport.
+// *****************************************************************************
+{
+  const auto& esuf = fd.Esuf();
+
+  const auto& cx = coord[0];
+  const auto& cy = coord[1];
+  const auto& cz = coord[2];
+
+  auto ncomp = U.nprop()/rdof;<--- Variable 'ncomp' is assigned a value that is never used.
+  auto nprim = P.nprop()/rdof;<--- Variable 'nprim' is assigned a value that is never used.
+
+  // compute internal surface flux integrals
+  for (auto f=fd.Nbfac(); f<esuf.size()/2; ++f)
+  {
+    Assert( esuf[2*f] > -1 && esuf[2*f+1] > -1, "Interior element detected "
+            "as -1" );
+
+    std::size_t el = static_cast< std::size_t >(esuf[2*f]);
+    std::size_t er = static_cast< std::size_t >(esuf[2*f+1]);
+
+    // Extract the element coordinates
+    std::array< std::array< tk::real, 3>, 4 > coordel_l {{
+      {{ cx[ inpoel[4*el  ] ], cy[ inpoel[4*el  ] ], cz[ inpoel[4*el  ] ] }},
+      {{ cx[ inpoel[4*el+1] ], cy[ inpoel[4*el+1] ], cz[ inpoel[4*el+1] ] }},
+      {{ cx[ inpoel[4*el+2] ], cy[ inpoel[4*el+2] ], cz[ inpoel[4*el+2] ] }},
+      {{ cx[ inpoel[4*el+3] ], cy[ inpoel[4*el+3] ], cz[ inpoel[4*el+3] ] }} }};
+
+    std::array< std::array< tk::real, 3>, 4 > coordel_r {{
+      {{ cx[ inpoel[4*er  ] ], cy[ inpoel[4*er  ] ], cz[ inpoel[4*er  ] ] }},
+      {{ cx[ inpoel[4*er+1] ], cy[ inpoel[4*er+1] ], cz[ inpoel[4*er+1] ] }},
+      {{ cx[ inpoel[4*er+2] ], cy[ inpoel[4*er+2] ], cz[ inpoel[4*er+2] ] }},
+      {{ cx[ inpoel[4*er+3] ], cy[ inpoel[4*er+3] ], cz[ inpoel[4*er+3] ] }} }};
+
+    // Compute the determinant of Jacobian matrix
+    auto detT_l =
+      Jacobian( coordel_l[0], coordel_l[1], coordel_l[2], coordel_l[3] );
+    auto detT_r =
+      Jacobian( coordel_r[0], coordel_r[1], coordel_r[2], coordel_r[3] );
+
+    // face normal
+    std::array< real, 3 > fn{{geoFace(f,1), geoFace(f,2), geoFace(f,3)}};
+
+    // face centroid
+    std::array< real, 3 > gp{{geoFace(f,4), geoFace(f,5), geoFace(f,6)}};
+
+    // In order to determine the high-order solution from the left and right
+    // elements at the surface quadrature points, the basis functions from
+    // the left and right elements are needed. For this, a transformation to
+    // the reference coordinates is necessary, since the basis functions are
+    // defined on the reference tetrahedron only.
+    // The transformation relations are shown below:
+    //  xi   = Jacobian( coordel[0], gp, coordel[2], coordel[3] ) / detT
+    //  eta  = Jacobian( coordel[0], coordel[2], gp, coordel[3] ) / detT
+    //  zeta = Jacobian( coordel[0], coordel[2], coordel[3], gp ) / detT
+
+    std::array< tk::real, 3> ref_gp_l{
+      Jacobian( coordel_l[0], gp, coordel_l[2], coordel_l[3] ) / detT_l,
+      Jacobian( coordel_l[0], coordel_l[1], gp, coordel_l[3] ) / detT_l,
+      Jacobian( coordel_l[0], coordel_l[1], coordel_l[2], gp ) / detT_l };
+    std::array< tk::real, 3> ref_gp_r{
+      Jacobian( coordel_r[0], gp, coordel_r[2], coordel_r[3] ) / detT_r,
+      Jacobian( coordel_r[0], coordel_r[1], gp, coordel_r[3] ) / detT_r,
+      Jacobian( coordel_r[0], coordel_r[1], coordel_r[2], gp ) / detT_r };
+
+    //Compute the basis functions
+    auto B_l = eval_basis( rdof, ref_gp_l[0], ref_gp_l[1], ref_gp_l[2] );
+    auto B_r = eval_basis( rdof, ref_gp_r[0], ref_gp_r[1], ref_gp_r[2] );
+
+    std::array< std::vector< real >, 2 > state;
 
-    // Gaussian quadrature
-    for (std::size_t igp=0; igp<ng; ++igp)
-    {
-      // If an rDG method is set up (P0P1), then, currently we compute the P1
-      // basis functions and solutions by default. This implies that P0P1 is
-      // unsupported in the p-adaptive DG (PDG).
-      std::size_t dof_el;
-      if (rdof > ndof)
-      {
-        dof_el = rdof;
-      }
-      else
-      {
-        dof_el = ndofel[e];
-      }
-
-      // Compute the basis function
-      auto B =
-        eval_basis( dof_el, coordgp[0][igp], coordgp[1][igp], coordgp[2][igp] );
-
-      auto wt = wgp[igp] * geoElem(e, 0);
+    state[0] = evalFVSol(mat_blk, intsharp, ncomp, nprim, rdof,
+      nmat, el, inpoel, coord, geoElem, ref_gp_l, B_l, U, P, srcFlag[el]);
+    state[1] = evalFVSol(mat_blk, intsharp, ncomp, nprim, rdof,
+      nmat, er, inpoel, coord, geoElem, ref_gp_r, B_r, U, P, srcFlag[er]);
+
+    //safeReco(rdof, nmat, el, er, U, state);
+
+    Assert( state[0].size() == ncomp+nprim, "Incorrect size for "
+            "appended boundary state vector" );
+    Assert( state[1].size() == ncomp+nprim, "Incorrect size for "
+            "appended boundary state vector" );
+
+    // evaluate prescribed velocity (if any)
+    auto v = vel( ncomp, gp[0], gp[1], gp[2], t );
+
+    // compute flux
+    auto fl = flux( mat_blk, fn, state, v );
+
+    // compute non-conservative terms
+    std::vector< tk::real > var_riemann(nmat+1, 0.0);
+    for (std::size_t k=0; k<nmat+1; ++k) var_riemann[k] = fl[ncomp+k];
 
-      auto state = evalPolynomialSol(mat_blk, intsharp, ncomp, nprim,
-        rdof, nmat, e, dof_el, inpoel, coord, geoElem,
-        {{coordgp[0][igp], coordgp[1][igp], coordgp[2][igp]}}, B, U, P);
-
-      // get bulk properties
-      real rhob(0.0);
-      for (std::size_t k=0; k<nmat; ++k)
-        rhob += state[densityIdx(nmat, k)];
-
-      // get pressures and bulk modulii
-      real pb(0.0), nume(0.0), deno(0.0), trelax(0.0);
-      std::vector< real > apmat(nmat, 0.0), kmat(nmat, 0.0);
-      for (std::size_t k=0; k<nmat; ++k)
-      {
-        real arhomat = state[densityIdx(nmat, k)];
-        real alphamat = state[volfracIdx(nmat, k)];
-        apmat[k] = state[ncomp+pressureIdx(nmat, k)];
-        real amat = 0.0;
-        if (solidx[k] > 0)
-        {
-          std::array< std::array< tk::real, 3 >, 3 > g;
-          for (std::size_t i=0; i<3; ++i)
-            for (std::size_t j=0; j<3; ++j)
-              g[i][j] = state[deformIdx(nmat,solidx[k],i,j)];
-          auto grot = tk::rotateTensor(g, {{1.0, 0.0, 0.0}});
-          amat = mat_blk[k].compute< inciter::EOS::soundspeed >( arhomat,
-            apmat[k], alphamat, k, grot);
-          grot = tk::rotateTensor(g, {{0.0, 1.0, 0.0}});
-          amat = std::max(amat, mat_blk[k].compute< inciter::EOS::soundspeed >(
-            arhomat, apmat[k], alphamat, k, grot));
-          grot = tk::rotateTensor(g, {{0.0, 0.0, 1.0}});
-          amat = std::max(amat, mat_blk[k].compute< inciter::EOS::soundspeed >(
-            arhomat, apmat[k], alphamat, k, grot));
-        }
-        else
-        {
-          amat = mat_blk[k].compute< inciter::EOS::soundspeed >( arhomat,
-            apmat[k], alphamat, k );
-        }
-        kmat[k] = arhomat * amat * amat;
-        pb += apmat[k];
-
-        // relaxation parameters
-        trelax = std::max(trelax, ct*dx/amat);
-        nume += alphamat * apmat[k] / kmat[k];
-        deno += alphamat * alphamat / kmat[k];
-      }
-      auto p_relax = nume/deno;
-
-      // compute pressure relaxation terms
-      std::vector< real > s_prelax(ncomp, 0.0);
-      for (std::size_t k=0; k<nmat; ++k)
-      {
-        auto s_alpha = (apmat[k]-p_relax*state[volfracIdx(nmat, k)])
-          * (state[volfracIdx(nmat, k)]/kmat[k]) / trelax;
-        s_prelax[volfracIdx(nmat, k)] = s_alpha;
-        s_prelax[energyIdx(nmat, k)] = - pb*s_alpha;
-      }
-
-      updateRhsPre( ncomp, ndof, dof_el, wt, e, B, s_prelax, R );
-    }
-  }
-}
-
-void
-updateRhsPre(
-  ncomp_t ncomp,
-  const std::size_t ndof,
-  [[maybe_unused]] const std::size_t ndof_el,
-  const tk::real wt,
-  const std::size_t e,
-  const std::vector< tk::real >& B,
-  std::vector< tk::real >& ncf,
-  Fields& R )
-// *****************************************************************************
-//  Update the rhs by adding the pressure relaxation integrals
-//! \param[in] ncomp Number of scalar components in this PDE system
-//! \param[in] ndof Maximum number of degrees of freedom
-//! \param[in] ndof_el Number of degrees of freedom for local element
-//! \param[in] wt Weight of gauss quadrature point
-//! \param[in] e Element index
-//! \param[in] B Basis function evaluated at local quadrature point
-//! \param[in] ncf Vector of non-conservative terms
-//! \param[in,out] R Right-hand side vector computed
-// *****************************************************************************
-{
-  //Assert( dBdx[0].size() == ndof_el,
-  //        "Size mismatch for basis function derivatives" );
-  //Assert( dBdx[1].size() == ndof_el,
-  //        "Size mismatch for basis function derivatives" );
-  //Assert( dBdx[2].size() == ndof_el,
-  //        "Size mismatch for basis function derivatives" );
-  //Assert( ncf.size() == ncomp,
-  //        "Size mismatch for non-conservative term" );
-  Assert( ncf.size() == ncomp, "Size mismatch for non-conservative term" );
-
-  for (ncomp_t c=0; c<ncomp; ++c)
-  {
-    auto mark = c*ndof;
-    for(std::size_t idof = 0; idof < ndof; idof++)
-      R(e, mark+idof) += wt * ncf[c] * B[idof];
-  }
-}
-
-void
-pressureRelaxationIntFV(
-  std::size_t nmat,
-  const std::vector< inciter::EOS >& mat_blk,
-  const std::size_t rdof,
-  const std::size_t nelem,
-  const std::vector< std::size_t >& inpoel,
-  const UnsMesh::Coords& coord,
-  const Fields& geoElem,
-  const Fields& U,
-  const Fields& P,
-  const tk::real ct,
-  Fields& R )<--- Parameter 'R' can be declared with const
-// *****************************************************************************
-//  Compute volume integrals of pressure relaxation terms in multi-material FV
-//! \details This is called for multi-material FV to compute volume integrals of
-//!   finite pressure relaxation terms in the volume fraction and energy
-//!   equations, which do not exist in the single-material flow formulation (for
-//!   `CompFlow`). For further details see Dobrev, V. A., Kolev, T. V.,
-//!   Rieben, R. N., & Tomov, V. Z. (2016). Multi‐material closure model for
-//!   high‐order finite element Lagrangian hydrodynamics. International Journal
-//!   for Numerical Methods in Fluids, 82(10), 689-706.
-//! \param[in] nmat Number of materials in this PDE system
-//! \param[in] mat_blk EOS material block
-//! \param[in] rdof Maximum number of reconstructed degrees of freedom
-//! \param[in] nelem Total number of elements
-//! \param[in] geoElem Element geometry array
-//! \param[in] U Solution vector at recent time step
-//! \param[in] P Vector of primitive quantities at recent time step
-//! \param[in] ct Pressure relaxation time-scale for this system
-//! \param[in,out] R Right-hand side vector added to
-// *****************************************************************************
-{
-  using inciter::volfracIdx;
-  using inciter::energyIdx;
-  using inciter::pressureIdx;
-  using inciter::velocityIdx;
-  using inciter::densityIdx;
-
-  auto ncomp = U.nprop()/rdof;
-  auto nprim = P.nprop()/rdof;
-
-  // compute volume integrals
-  for (std::size_t e=0; e<nelem; ++e)
-  {
-    auto dx = geoElem(e,4)/2.0;
-
-    // Compute the basis function
-    std::vector< tk::real > B(rdof, 0.0);
-    B[0] = 1.0;
-
-    auto state = evalPolynomialSol(mat_blk, 0, ncomp, nprim,
-      rdof, nmat, e, rdof, inpoel, coord, geoElem,
-      {{0.25, 0.25, 0.25}}, B, U, P);
-
-    // get bulk properties
-    real rhob(0.0);
-    for (std::size_t k=0; k<nmat; ++k)
-      rhob += state[densityIdx(nmat, k)];
-
-    // get pressures and bulk modulii
-    real pb(0.0), nume(0.0), deno(0.0), trelax(0.0);
-    std::vector< real > apmat(nmat, 0.0), kmat(nmat, 0.0);
-    for (std::size_t k=0; k<nmat; ++k)
-    {
-      real arhomat = state[densityIdx(nmat, k)];
-      real alphamat = state[volfracIdx(nmat, k)];
-      apmat[k] = state[ncomp+pressureIdx(nmat, k)];
-      real amat = mat_blk[k].compute< inciter::EOS::soundspeed >( arhomat,
-        apmat[k], alphamat, k );
-      kmat[k] = arhomat * amat * amat;
-      pb += apmat[k];
-
-      // relaxation parameters
-      trelax = std::max(trelax, ct*dx/amat);
-      nume += alphamat * apmat[k] / kmat[k];
-      deno += alphamat * alphamat / kmat[k];
-    }
-    auto p_relax = nume/deno;
-
-    // compute pressure relaxation terms
-    std::vector< real > s_prelax(ncomp, 0.0);
-
-    // terms to ensure only existing materials are relaxed
-    real e_leftover(0), vf_leftover(0);
-    auto almax(0.0);
-    std::size_t kmax = 0;
-    for (std::size_t k=0; k<nmat; ++k)
-    {
-      real alphamat = state[volfracIdx(nmat, k)];
-      auto s_alpha = (apmat[k]-p_relax*state[volfracIdx(nmat, k)])
-        * (state[volfracIdx(nmat, k)]/kmat[k]) / trelax;
-
-      // only perform prelax on existing quantities
-      if (inciter::matExists(state[volfracIdx(nmat,k)])) {
-        s_prelax[volfracIdx(nmat, k)] = s_alpha;
-        s_prelax[energyIdx(nmat, k)] = - pb*s_alpha;
-      } else {
-        vf_leftover += s_alpha;
-        e_leftover  += - pb*s_alpha;
-      }
-      // get material that takes up most volume
-      if (alphamat > almax)
-      {
-        almax = alphamat;
-        kmax = k;
-      }
-    }
-
-    // add leftovers of non-existent mat to mat with most volume
-    s_prelax[volfracIdx(nmat, kmax)] += vf_leftover;
-    s_prelax[energyIdx(nmat, kmax)] += e_leftover;
-
-    for (ncomp_t c=0; c<ncomp; ++c)
-    {
-      R(e, c) += geoElem(e,0) * s_prelax[c];
-    }
-  }
-}
-
-std::vector< std::vector< tk::real > >
-solvevriem( std::size_t nelem,
-            const std::vector< std::vector< tk::real > >& vriem,
-            const std::vector< std::vector< tk::real > >& riemannLoc )
-// *****************************************************************************
-//  Solve the reconstruct velocity used for volume fraction equation by
-//  Least square method
-//! \param[in] nelem Numer of elements
-//! \param[in,out] vriem Vector of the riemann velocity
-//! \param[in,out] riemannLoc Vector of coordinates where Riemann velocity data
-//!   is available
-//! \return Vector of Riemann velocity polynomial solution
-// *****************************************************************************
-{
-  std::vector< std::vector< tk::real > >
-    vriempoly( nelem, std::vector<tk::real>(12,0.0) );
-
-  for (std::size_t e=0; e<nelem; ++e)
-  {
-    // Use the normal method to construct the linear system A^T * A * x = u
-    auto numgp = riemannLoc[e].size()/3;
-    std::vector< std::vector< tk::real > > A(numgp,
-                                             std::vector<tk::real>(4, 1.0));
-
-    for(std::size_t k = 0; k < numgp; k++)
-    {
-      auto mark = k * 3;
-      A[k][1] = riemannLoc[e][mark];
-      A[k][2] = riemannLoc[e][mark+1];
-      A[k][3] = riemannLoc[e][mark+2];
-    }
-
-    for(std::size_t idir = 0; idir < 3; idir++)
-    {
-      double AA_T[4*4], u[4];
-
-      for(std::size_t i = 0; i < 4; i++)
-        for(std::size_t j = 0; j < 4; j++)
-        {
-          auto id = 4 * i + j;
-          AA_T[id] = 0;
-          for(std::size_t k = 0; k < numgp; k++)
-            AA_T[id] += A[k][i] * A[k][j];
-        }
-
-      std::vector<tk::real> vel(numgp, 1.0);
-      for(std::size_t k = 0; k < numgp; k++)
-      {
-        auto mark = k * 3 + idir;
-        vel[k] = vriem[e][mark];
-      }
-      for(std::size_t k = 0; k < 4; k++)
-      {
-        u[k] = 0;
-        for(std::size_t i = 0; i < numgp; i++)
-          u[k] += A[i][k] * vel[i];
-      }
- 
-      lapack_int IPIV[4];
-      #ifndef NDEBUG
-      lapack_int info =
-      #endif
-        LAPACKE_dsysv( LAPACK_ROW_MAJOR, 'U', 4, 1, AA_T, 4, IPIV, u, 1 );
-      Assert( info == 0, "Error in linear system solver" );
-
-      auto idirmark = idir * 4;
-      for(std::size_t k = 0; k < 4; k++)
-        vriempoly[e][idirmark+k] = u[k];
-    }
-  }
-  return vriempoly;
-}
-
-void evaluRiemann( ncomp_t ncomp,
-                   const int e_left,
-                   const int e_right,
-                   const std::size_t nmat,
-                   const std::vector< tk::real >& fl,
-                   const std::array< tk::real, 3 >& fn,
-                   const std::array< tk::real, 3 >& gp,
-                   const std::array< std::vector< tk::real >, 2 >& state,
-                   std::vector< std::vector< tk::real > >& vriem,
-                   std::vector< std::vector< tk::real > >& riemannLoc )
-// *****************************************************************************
-//  Compute the riemann velocity at the interface
-//! \param[in] ncomp Number of scalar components in this PDE system
-//! \param[in] e_left Index for the left element
-//! \param[in] e_right Index for the right element
-//! \param[in] nmat Number of materials in this PDE system
-//! \param[in] fn Face/Surface normal
-//! \param[in] gp Gauss points coordinates
-//! \param[in] fl Surface flux
-//! \param[in] state Vector of state variables for left and right side
-//! \param[in,out] vriem Vector of the riemann velocity
-//! \param[in,out] riemannLoc Vector of coordinates where Riemann velocity data
-//!   is available
-// *****************************************************************************
-{
-  using inciter::densityIdx;
-  using inciter::momentumIdx;
-
-  std::size_t el(0), er(0);
-  el = static_cast< std::size_t >(e_left);
-  if(e_right != -1)
-    er = static_cast< std::size_t >(e_right);
-
-  riemannLoc[el].push_back( gp[0] );
-  riemannLoc[el].push_back( gp[1] );
-  riemannLoc[el].push_back( gp[2] );
-
-  if(e_right != -1)
-  {
-    riemannLoc[er].push_back( gp[0] );
-    riemannLoc[er].push_back( gp[1] );
-    riemannLoc[er].push_back( gp[2] );
-  }
-
-  tk::real rhobl(0.0), rhobr(0.0);
-  for (std::size_t k=0; k<nmat; ++k)
-  {
-    rhobl += state[0][densityIdx(nmat, k)];
-    rhobr += state[1][densityIdx(nmat, k)];
-  }
-
-  auto ul = state[0][momentumIdx(nmat, 0)] / rhobl;
-  auto vl = state[0][momentumIdx(nmat, 1)] / rhobl;
-  auto wl = state[0][momentumIdx(nmat, 2)] / rhobl;
-
-  auto ur = state[1][momentumIdx(nmat, 0)] / rhobr;
-  auto vr = state[1][momentumIdx(nmat, 1)] / rhobr;
-  auto wr = state[1][momentumIdx(nmat, 2)] / rhobr;
-
-  // Compute the normal velocities from left and right cells
-  auto vnl = ul * fn[0] + vl * fn[1] + wl * fn[2];
-  auto vnr = ur * fn[0] + vr * fn[1] + wr * fn[2];
-
-  // The interface velocity is evaluated by adding the normal velocity which
-  // is taken from the Riemann solver and the tangential velocity which is
-  // evaluated as an average of the left and right cells
-  auto urie = 0.5 * ((ul + ur) - fn[0] * (vnl + vnr)) + fl[ncomp+nmat] * fn[0];
-  auto vrie = 0.5 * ((vl + vr) - fn[1] * (vnl + vnr)) + fl[ncomp+nmat] * fn[1];
-  auto wrie = 0.5 * ((wl + wr) - fn[2] * (vnl + vnr)) + fl[ncomp+nmat] * fn[2];
-
-  vriem[el].push_back(urie);
-  vriem[el].push_back(vrie);
-  vriem[el].push_back(wrie);
-
-  if(e_right != -1)
-  {
-    vriem[er].push_back(urie);
-    vriem[er].push_back(vrie);
-    vriem[er].push_back(wrie);
-  }
-}
-
-std::vector< std::array< tk::real, 3 > >
-fluxTerms(
-  std::size_t ncomp,
-  std::size_t nmat,
-  const std::vector< inciter::EOS >& /*mat_blk*/,
-  const std::vector< tk::real >& ugp )
-// *****************************************************************************
-//  Compute the flux-function for the multimaterial PDEs
-//! \param[in] ncomp Number of components in this PDE system
-//! \param[in] nmat Number of materials in this PDE system
-// //! \param[in] mat_blk EOS material block
-//! \param[in] ugp State vector at the Gauss point at which flux is required
-//! \return Flux vectors for all components in multi-material PDE system
-// *****************************************************************************
-{
-  using inciter::volfracIdx;
-  using inciter::densityIdx;
-  using inciter::momentumIdx;
-  using inciter::energyIdx;
-  using inciter::velocityIdx;
-  using inciter::pressureIdx;
-  using inciter::deformIdx;
-
-  const auto& solidx =
-    inciter::g_inputdeck.get< tag::matidxmap, tag::solidx >();
-
-  std::vector< std::array< tk::real, 3 > > fl( ncomp, {{0, 0, 0}} );
-
-  tk::real rho(0.0);<--- Variable 'rho' is assigned a value that is never used.
-  for (std::size_t k=0; k<nmat; ++k)
-    rho += ugp[densityIdx(nmat, k)];<--- Variable 'rho' is assigned a value that is never used.
-
-  auto u = ugp[ncomp+velocityIdx(nmat,0)];
-  auto v = ugp[ncomp+velocityIdx(nmat,1)];
-  auto w = ugp[ncomp+velocityIdx(nmat,2)];
-
-  if (inciter::haveSolid(nmat, solidx))
-  {
-    std::vector< tk::real > al(nmat, 0.0);
-    std::vector< std::array< std::array< tk::real, 3 >, 3 > > g, asig;
-    std::array< std::array< tk::real, 3 >, 3 >
-      sig {{ {{0, 0, 0}}, {{0, 0, 0}}, {{0, 0, 0}} }};
-    for (std::size_t k=0; k<nmat; ++k)
-    {
-      al[k] = ugp[volfracIdx(nmat, k)];
-      // inv deformation gradient and Cauchy stress tensors
-      g.push_back(inciter::getDeformGrad(nmat, k, ugp));
-      asig.push_back(inciter::getCauchyStress(nmat, k, ncomp, ugp));
-      for (std::size_t i=0; i<3; ++i) asig[k][i][i] -= ugp[ncomp+pressureIdx(nmat,k)];
-
-      for (size_t i=0; i<3; ++i)
-        for (size_t j=0; j<3; ++j)
-          sig[i][j] += asig[k][i][j];
-    }
-
-    // conservative part of momentum flux
-    fl[momentumIdx(nmat, 0)][0] = ugp[momentumIdx(nmat, 0)] * u - sig[0][0];
-    fl[momentumIdx(nmat, 1)][0] = ugp[momentumIdx(nmat, 1)] * u - sig[0][1];
-    fl[momentumIdx(nmat, 2)][0] = ugp[momentumIdx(nmat, 2)] * u - sig[0][2];
-
-    fl[momentumIdx(nmat, 0)][1] = ugp[momentumIdx(nmat, 0)] * v - sig[1][0];
-    fl[momentumIdx(nmat, 1)][1] = ugp[momentumIdx(nmat, 1)] * v - sig[1][1];
-    fl[momentumIdx(nmat, 2)][1] = ugp[momentumIdx(nmat, 2)] * v - sig[1][2];
-
-    fl[momentumIdx(nmat, 0)][2] = ugp[momentumIdx(nmat, 0)] * w - sig[2][0];
-    fl[momentumIdx(nmat, 1)][2] = ugp[momentumIdx(nmat, 1)] * w - sig[2][1];
-    fl[momentumIdx(nmat, 2)][2] = ugp[momentumIdx(nmat, 2)] * w - sig[2][2];
-
-    for (std::size_t k=0; k<nmat; ++k)
-    {
-      // conservative part of volume-fraction flux
-      fl[volfracIdx(nmat, k)][0] = 0.0;
-      fl[volfracIdx(nmat, k)][1] = 0.0;
-      fl[volfracIdx(nmat, k)][2] = 0.0;
-
-      // conservative part of material continuity flux
-      fl[densityIdx(nmat, k)][0] = u * ugp[densityIdx(nmat, k)];
-      fl[densityIdx(nmat, k)][1] = v * ugp[densityIdx(nmat, k)];
-      fl[densityIdx(nmat, k)][2] = w * ugp[densityIdx(nmat, k)];
-
-      // conservative part of material total-energy flux
-      fl[energyIdx(nmat, k)][0] = u * ugp[energyIdx(nmat, k)]
-        - u * asig[k][0][0] - v * asig[k][1][0] - w * asig[k][2][0];
-      fl[energyIdx(nmat, k)][1] = v * ugp[energyIdx(nmat, k)]
-        - u * asig[k][0][1] - v * asig[k][1][1] - w * asig[k][2][1];
-      fl[energyIdx(nmat, k)][2] = w * ugp[energyIdx(nmat, k)]
-        - u * asig[k][0][2] - v * asig[k][1][2] - w * asig[k][2][2];
-
-      // conservative part of material inverse deformation gradient
-      // g_ij: \partial (g_il u_l) / \partial (x_j)
-      if (solidx[k] > 0)
-      {
-        for (std::size_t i=0; i<3; ++i)
-        {
-          for (std::size_t j=0; j<3; ++j)
-          {
-            fl[deformIdx(nmat,solidx[k],i,j)][j] =
-              u*g[k][i][0] + v*g[k][i][1] + w*g[k][i][2];
-          }
-          // other components are zero
-        }
-      }
-    }
-  }
-  else
-  {
-    tk::real p(0.0);
-    std::vector< tk::real > apk( nmat, 0.0 );
-    for (std::size_t k=0; k<nmat; ++k)
-    {
-      apk[k] = ugp[ncomp+pressureIdx(nmat,k)];
-      p += apk[k];
-    }
-
-    // conservative part of momentum flux
-    fl[momentumIdx(nmat, 0)][0] = ugp[momentumIdx(nmat, 0)] * u + p;
-    fl[momentumIdx(nmat, 1)][0] = ugp[momentumIdx(nmat, 1)] * u;
-    fl[momentumIdx(nmat, 2)][0] = ugp[momentumIdx(nmat, 2)] * u;
-
-    fl[momentumIdx(nmat, 0)][1] = ugp[momentumIdx(nmat, 0)] * v;
-    fl[momentumIdx(nmat, 1)][1] = ugp[momentumIdx(nmat, 1)] * v + p;
-    fl[momentumIdx(nmat, 2)][1] = ugp[momentumIdx(nmat, 2)] * v;
-
-    fl[momentumIdx(nmat, 0)][2] = ugp[momentumIdx(nmat, 0)] * w;
-    fl[momentumIdx(nmat, 1)][2] = ugp[momentumIdx(nmat, 1)] * w;
-    fl[momentumIdx(nmat, 2)][2] = ugp[momentumIdx(nmat, 2)] * w + p;
-
-    for (std::size_t k=0; k<nmat; ++k)
-    {
-      // conservative part of volume-fraction flux
-      fl[volfracIdx(nmat, k)][0] = 0.0;
-      fl[volfracIdx(nmat, k)][1] = 0.0;
-      fl[volfracIdx(nmat, k)][2] = 0.0;
-
-      // conservative part of material continuity flux
-      fl[densityIdx(nmat, k)][0] = u * ugp[densityIdx(nmat, k)];
-      fl[densityIdx(nmat, k)][1] = v * ugp[densityIdx(nmat, k)];
-      fl[densityIdx(nmat, k)][2] = w * ugp[densityIdx(nmat, k)];
-
-      // conservative part of material total-energy flux
-      auto hmat = ugp[energyIdx(nmat, k)] + apk[k];
-      fl[energyIdx(nmat, k)][0] = u * hmat;
-      fl[energyIdx(nmat, k)][1] = v * hmat;
-      fl[energyIdx(nmat, k)][2] = w * hmat;
-    }
-  }
-
-  return fl;
-}
-
-}// tk::
+    auto ncf_l = nonConservativeIntFV(nmat, rdof, el, fn, U, P, var_riemann);
+    auto ncf_r = nonConservativeIntFV(nmat, rdof, er, fn, U, P, var_riemann);
+
+    // Add the surface integration term to the rhs
+    for (ncomp_t c=0; c<ncomp; ++c)
+    {
+      R(el, c) -= geoFace(f,0) * (fl[c] - ncf_l[c]);
+      R(er, c) += geoFace(f,0) * (fl[c] - ncf_r[c]);
+    }
+  }
+}
+
+} // tk::
 
diff --git a/Release/cppcheck/72.html b/Release/cppcheck/72.html index 0f7aaef1c5c0..24a254975c4c 100644 --- a/Release/cppcheck/72.html +++ b/Release/cppcheck/72.html @@ -152,2531 +152,299 @@
- - + diff --git a/Release/test_coverage/Base/Vector.hpp.gcov.html b/Release/test_coverage/Base/Vector.hpp.gcov.html index a903291fa74c..0943b58d27fa 100644 --- a/Release/test_coverage/Base/Vector.hpp.gcov.html +++ b/Release/test_coverage/Base/Vector.hpp.gcov.html @@ -27,13 +27,13 @@ - + - + - + @@ -52,9 +52,9 @@ - - - + + +
   1
-   2
-   3
-   4
-   5
-   6
-   7
-   8
-   9
-  10
-  11
-  12
-  13
-  14
-  15
-  16
-  17
-  18
-  19
-  20
-  21
-  22
-  23
-  24
-  25
-  26
-  27
-  28
-  29
-  30
-  31
-  32
-  33
-  34
-  35
-  36
-  37
-  38
-  39
-  40
-  41
-  42
-  43
-  44
-  45
-  46
-  47
-  48
-  49
-  50
-  51
-  52
-  53
-  54
-  55
-  56
-  57
-  58
-  59
-  60
-  61
-  62
-  63
-  64
-  65
-  66
-  67
-  68
-  69
-  70
-  71
-  72
-  73
-  74
-  75
-  76
-  77
-  78
-  79
-  80
-  81
-  82
-  83
-  84
-  85
-  86
-  87
-  88
-  89
-  90
-  91
-  92
-  93
-  94
-  95
-  96
-  97
-  98
-  99
- 100
- 101
- 102
- 103
- 104
- 105
- 106
- 107
- 108
- 109
- 110
- 111
- 112
- 113
- 114
- 115
- 116
- 117
- 118
- 119
- 120
- 121
- 122
- 123
- 124
- 125
- 126
- 127
- 128
- 129
- 130
- 131
- 132
- 133
- 134
- 135
- 136
- 137
- 138
- 139
- 140
- 141
- 142
- 143
- 144
- 145
- 146
- 147
- 148
- 149
- 150
- 151
- 152
- 153
- 154
- 155
- 156
- 157
- 158
- 159
- 160
- 161
- 162
- 163
- 164
- 165
- 166
- 167
- 168
- 169
- 170
- 171
- 172
- 173
- 174
- 175
- 176
- 177
- 178
- 179
- 180
- 181
- 182
- 183
- 184
- 185
- 186
- 187
- 188
- 189
- 190
- 191
- 192
- 193
- 194
- 195
- 196
- 197
- 198
- 199
- 200
- 201
- 202
- 203
- 204
- 205
- 206
- 207
- 208
- 209
- 210
- 211
- 212
- 213
- 214
- 215
- 216
- 217
- 218
- 219
- 220
- 221
- 222
- 223
- 224
- 225
- 226
- 227
- 228
- 229
- 230
- 231
- 232
- 233
- 234
- 235
- 236
- 237
- 238
- 239
- 240
- 241
- 242
- 243
- 244
- 245
- 246
- 247
- 248
- 249
- 250
- 251
- 252
- 253
- 254
- 255
- 256
- 257
- 258
- 259
- 260
- 261
- 262
- 263
- 264
- 265
- 266
- 267
- 268
- 269
- 270
- 271
- 272
- 273
- 274
- 275
- 276
- 277
- 278
- 279
- 280
- 281
- 282
- 283
- 284
- 285
- 286
- 287
- 288
- 289
- 290
- 291
- 292
- 293
- 294
- 295
- 296
- 297
- 298
- 299
- 300
- 301
- 302
- 303
- 304
- 305
- 306
- 307
- 308
- 309
- 310
- 311
- 312
- 313
- 314
- 315
- 316
- 317
- 318
- 319
- 320
- 321
- 322
- 323
- 324
- 325
- 326
- 327
- 328
- 329
- 330
- 331
- 332
- 333
- 334
- 335
- 336
- 337
- 338
- 339
- 340
- 341
- 342
- 343
- 344
- 345
- 346
- 347
- 348
- 349
- 350
- 351
- 352
- 353
- 354
- 355
- 356
- 357
- 358
- 359
- 360
- 361
- 362
- 363
- 364
- 365
- 366
- 367
- 368
- 369
- 370
- 371
- 372
- 373
- 374
- 375
- 376
- 377
- 378
- 379
- 380
- 381
- 382
- 383
- 384
- 385
- 386
- 387
- 388
- 389
- 390
- 391
- 392
- 393
- 394
- 395
- 396
- 397
- 398
- 399
- 400
- 401
- 402
- 403
- 404
- 405
- 406
- 407
- 408
- 409
- 410
- 411
- 412
- 413
- 414
- 415
- 416
- 417
- 418
- 419
- 420
- 421
- 422
- 423
- 424
- 425
- 426
- 427
- 428
- 429
- 430
- 431
- 432
- 433
- 434
- 435
- 436
- 437
- 438
- 439
- 440
- 441
- 442
- 443
- 444
- 445
- 446
- 447
- 448
- 449
- 450
- 451
- 452
- 453
- 454
- 455
- 456
- 457
- 458
- 459
- 460
- 461
- 462
- 463
- 464
- 465
- 466
- 467
- 468
- 469
- 470
- 471
- 472
- 473
- 474
- 475
- 476
- 477
- 478
- 479
- 480
- 481
- 482
- 483
- 484
- 485
- 486
- 487
- 488
- 489
- 490
- 491
- 492
- 493
- 494
- 495
- 496
- 497
- 498
- 499
- 500
- 501
- 502
- 503
- 504
- 505
- 506
- 507
- 508
- 509
- 510
- 511
- 512
- 513
- 514
- 515
- 516
- 517
- 518
- 519
- 520
- 521
- 522
- 523
- 524
- 525
- 526
- 527
- 528
- 529
- 530
- 531
- 532
- 533
- 534
- 535
- 536
- 537
- 538
- 539
- 540
- 541
- 542
- 543
- 544
- 545
- 546
- 547
- 548
- 549
- 550
- 551
- 552
- 553
- 554
- 555
- 556
- 557
- 558
- 559
- 560
- 561
- 562
- 563
- 564
- 565
- 566
- 567
- 568
- 569
- 570
- 571
- 572
- 573
- 574
- 575
- 576
- 577
- 578
- 579
- 580
- 581
- 582
- 583
- 584
- 585
- 586
- 587
- 588
- 589
- 590
- 591
- 592
- 593
- 594
- 595
- 596
- 597
- 598
- 599
- 600
- 601
- 602
- 603
- 604
- 605
- 606
- 607
- 608
- 609
- 610
- 611
- 612
- 613
- 614
- 615
- 616
- 617
- 618
- 619
- 620
- 621
- 622
- 623
- 624
- 625
- 626
- 627
- 628
- 629
- 630
- 631
- 632
- 633
- 634
- 635
- 636
- 637
- 638
- 639
- 640
- 641
- 642
- 643
- 644
- 645
- 646
- 647
- 648
- 649
- 650
- 651
- 652
- 653
- 654
- 655
- 656
- 657
- 658
- 659
- 660
- 661
- 662
- 663
- 664
- 665
- 666
- 667
- 668
- 669
- 670
- 671
- 672
- 673
- 674
- 675
- 676
- 677
- 678
- 679
- 680
- 681
- 682
- 683
- 684
- 685
- 686
- 687
- 688
- 689
- 690
- 691
- 692
- 693
- 694
- 695
- 696
- 697
- 698
- 699
- 700
- 701
- 702
- 703
- 704
- 705
- 706
- 707
- 708
- 709
- 710
- 711
- 712
- 713
- 714
- 715
- 716
- 717
- 718
- 719
- 720
- 721
- 722
- 723
- 724
- 725
- 726
- 727
- 728
- 729
- 730
- 731
- 732
- 733
- 734
- 735
- 736
- 737
- 738
- 739
- 740
- 741
- 742
- 743
- 744
- 745
- 746
- 747
- 748
- 749
- 750
- 751
- 752
- 753
- 754
- 755
- 756
- 757
- 758
- 759
- 760
- 761
- 762
- 763
- 764
- 765
- 766
- 767
- 768
- 769
- 770
- 771
- 772
- 773
- 774
- 775
- 776
- 777
- 778
- 779
- 780
- 781
- 782
- 783
- 784
- 785
- 786
- 787
- 788
- 789
- 790
- 791
- 792
- 793
- 794
- 795
- 796
- 797
- 798
- 799
- 800
- 801
- 802
- 803
- 804
- 805
- 806
- 807
- 808
- 809
- 810
- 811
- 812
- 813
- 814
- 815
- 816
- 817
- 818
- 819
- 820
- 821
- 822
- 823
- 824
- 825
- 826
- 827
- 828
- 829
- 830
- 831
- 832
- 833
- 834
- 835
- 836
- 837
- 838
- 839
- 840
- 841
- 842
- 843
- 844
- 845
- 846
- 847
- 848
- 849
- 850
- 851
- 852
- 853
- 854
- 855
- 856
- 857
- 858
- 859
- 860
- 861
- 862
- 863
- 864
- 865
- 866
- 867
- 868
- 869
- 870
- 871
- 872
- 873
- 874
- 875
- 876
- 877
- 878
- 879
- 880
- 881
- 882
- 883
- 884
- 885
- 886
- 887
- 888
- 889
- 890
- 891
- 892
- 893
- 894
- 895
- 896
- 897
- 898
- 899
- 900
- 901
- 902
- 903
- 904
- 905
- 906
- 907
- 908
- 909
- 910
- 911
- 912
- 913
- 914
- 915
- 916
- 917
- 918
- 919
- 920
- 921
- 922
- 923
- 924
- 925
- 926
- 927
- 928
- 929
- 930
- 931
- 932
- 933
- 934
- 935
- 936
- 937
- 938
- 939
- 940
- 941
- 942
- 943
- 944
- 945
- 946
- 947
- 948
- 949
- 950
- 951
- 952
- 953
- 954
- 955
- 956
- 957
- 958
- 959
- 960
- 961
- 962
- 963
- 964
- 965
- 966
- 967
- 968
- 969
- 970
- 971
- 972
- 973
- 974
- 975
- 976
- 977
- 978
- 979
- 980
- 981
- 982
- 983
- 984
- 985
- 986
- 987
- 988
- 989
- 990
- 991
- 992
- 993
- 994
- 995
- 996
- 997
- 998
- 999
-1000
-1001
-1002
-1003
-1004
-1005
-1006
-1007
-1008
-1009
-1010
-1011
-1012
-1013
-1014
-1015
-1016
-1017
-1018
-1019
-1020
-1021
-1022
-1023
-1024
-1025
-1026
-1027
-1028
-1029
-1030
-1031
-1032
-1033
-1034
-1035
-1036
-1037
-1038
-1039
-1040
-1041
-1042
-1043
-1044
-1045
-1046
-1047
-1048
-1049
-1050
-1051
-1052
-1053
-1054
-1055
-1056
-1057
-1058
-1059
-1060
-1061
-1062
-1063
-1064
-1065
-1066
-1067
-1068
-1069
-1070
-1071
-1072
-1073
-1074
-1075
-1076
-1077
-1078
-1079
-1080
-1081
-1082
-1083
-1084
-1085
-1086
-1087
-1088
-1089
-1090
-1091
-1092
-1093
-1094
-1095
-1096
-1097
-1098
-1099
-1100
-1101
-1102
-1103
-1104
-1105
-1106
-1107
-1108
-1109
-1110
-1111
-1112
-1113
-1114
-1115
-1116
-1117
-1118
-1119
-1120
-1121
-1122
-1123
-1124
-1125
-1126
-1127
-1128
-1129
-1130
-1131
-1132
-1133
-1134
-1135
-1136
-1137
-1138
-1139
-1140
-1141
-1142
-1143
-1144
-1145
-1146
-1147
-1148
-1149
-1150
-1151
-1152
-1153
-1154
-1155
-1156
-1157
-1158
-1159
-1160
-1161
-1162
-1163
-1164
-1165
-1166
-1167
-1168
-1169
-1170
-1171
-1172
-1173
-1174
-1175
-1176
-1177
-1178
-1179
-1180
-1181
-1182
-1183
-1184
-1185
-1186
-1187
-1188
-1189
-1190
-1191
-1192
-1193
-1194
-1195
-1196
-1197
-1198
-1199
-1200
-1201
-1202
-1203
-1204
-1205
-1206
-1207
-1208
-1209
-1210
-1211
-1212
-1213
-1214
-1215
-1216
-1217
-1218
-1219
-1220
-1221
-1222
-1223
-1224
-1225
-1226
-1227
-1228
-1229
-1230
-1231
-1232
-1233
-1234
-1235
-1236
-1237
-1238
-1239
-1240
-1241
-1242
-1243
-1244
-1245
-1246
-1247
-1248
-1249
-1250
-1251
-1252
-1253
-1254
-1255
-1256
-1257
-1258
-1259
// *****************************************************************************
+
  1
+  2
+  3
+  4
+  5
+  6
+  7
+  8
+  9
+ 10
+ 11
+ 12
+ 13
+ 14
+ 15
+ 16
+ 17
+ 18
+ 19
+ 20
+ 21
+ 22
+ 23
+ 24
+ 25
+ 26
+ 27
+ 28
+ 29
+ 30
+ 31
+ 32
+ 33
+ 34
+ 35
+ 36
+ 37
+ 38
+ 39
+ 40
+ 41
+ 42
+ 43
+ 44
+ 45
+ 46
+ 47
+ 48
+ 49
+ 50
+ 51
+ 52
+ 53
+ 54
+ 55
+ 56
+ 57
+ 58
+ 59
+ 60
+ 61
+ 62
+ 63
+ 64
+ 65
+ 66
+ 67
+ 68
+ 69
+ 70
+ 71
+ 72
+ 73
+ 74
+ 75
+ 76
+ 77
+ 78
+ 79
+ 80
+ 81
+ 82
+ 83
+ 84
+ 85
+ 86
+ 87
+ 88
+ 89
+ 90
+ 91
+ 92
+ 93
+ 94
+ 95
+ 96
+ 97
+ 98
+ 99
+100
+101
+102
+103
+104
+105
+106
+107
+108
+109
+110
+111
+112
+113
+114
+115
+116
+117
+118
+119
+120
+121
+122
+123
+124
+125
+126
+127
+128
+129
+130
+131
+132
+133
+134
+135
+136
+137
+138
+139
+140
+141
+142
+143
// *****************************************************************************
 /*!
-  \file      src/PDE/Reconstruction.cpp
+  \file      src/PDE/MultiMat/Physics/FVEnergyPill.cpp
   \copyright 2012-2015 J. Bakosi,
              2016-2018 Los Alamos National Security, LLC.,
              2019-2021 Triad National Security, LLC.
              All rights reserved. See the LICENSE file for details.
-  \brief     Reconstruction for reconstructed discontinuous Galerkin methods
-  \details   This file contains functions that reconstruct an "n"th order
-    polynomial to an "n+1"th order polynomial using a least-squares
-    reconstruction procedure.
-*/
-// *****************************************************************************
-
-#include <array>
-#include <vector>
-#include <iostream>
-#include <iomanip>
-
-#include "Vector.hpp"
-#include "Around.hpp"
-#include "Base/HashMapReducer.hpp"
-#include "Reconstruction.hpp"
-#include "MultiMat/MultiMatIndexing.hpp"
-#include "Inciter/InputDeck/InputDeck.hpp"
-#include "Limiter.hpp"
+  \brief     Physics policy for the Euler equation governing multi-material flow
+    using a finite volume method
+  \details   This file defines a Physics policy class for the compressible
+    flow equations class fv::MultiMat, defined in PDE/MultiMat/FVMultiMat.h.
+    This specific class allows energy pill initialization of a user defined
+    box/block for multi-material flow. See PDE/MultiMat/Physics/FV.h for general
+    requirements on Physics policy classes for fv::MultiMat.
+*/
+// *****************************************************************************
+
+#include "FVEnergyPill.hpp"
+#include "Inciter/InputDeck/InputDeck.hpp"
+#include "ContainerUtil.hpp"
+#include "MultiMat/MultiMatIndexing.hpp"
+#include "NoWarning/charm++.hpp"
+
+namespace inciter {
+
+extern ctr::InputDeck g_inputdeck;
 
-namespace inciter {
-extern ctr::InputDeck g_inputdeck;
-}
+} // inciter::
+
+using inciter::fv::MultiMatPhysicsEnergyPill;
 
-namespace tk {
-
-void
-lhsLeastSq_P0P1( const inciter::FaceData& fd,
-                 const Fields& geoElem,
-                 const Fields& geoFace,
-                 std::vector< std::array< std::array< real, 3 >, 3 > >& lhs_ls )
-// *****************************************************************************
-//  Compute lhs matrix for the least-squares reconstruction
-//! \param[in] fd Face connectivity and boundary conditions object
-//! \param[in] geoElem Element geometry array
-//! \param[in] geoFace Face geometry array
-//! \param[in,out] lhs_ls LHS reconstruction matrix
-//! \details This function computing the lhs matrix for reconstruction, is
-//!   common for primitive and conserved quantities.
-// *****************************************************************************
-{
-  const auto& esuf = fd.Esuf();
-  const auto nelem = fd.Esuel().size()/4;
-
-  // Compute internal and boundary face contributions
-  for (std::size_t f=0; f<esuf.size()/2; ++f)
-  {
-    Assert( esuf[2*f] > -1, "Left-side element detected as -1" );
+tk::real
+MultiMatPhysicsEnergyPill::dtRestriction(
+  const tk::Fields& geoElem,
+  std::size_t nelem,
+  const std::vector< int >& engSrcAd ) const
+// *****************************************************************************
+//  Compute the time step size restriction based on this physics
+//! \param[in] geoElem Element geometry array
+//! \param[in] nelem Number of elements
+//! \param[in] engSrcAd Whether the energy source was added
+//! \return Maximum allowable time step based on front propagation speed
+// *****************************************************************************
+{
+  auto mindt = std::numeric_limits< tk::real >::max();
+  // determine front propagation speed
+  const auto& icmbk = g_inputdeck.get< tag::ic, tag::meshblock >();
+  tk::real v_front(0.0);
+  for (const auto& b : icmbk) { // for all blocks
+    auto inittype = b.template get< tag::initiate >();
+    if (inittype == ctr::InitiateType::LINEAR) {
+      v_front = std::max(v_front,
+        b.template get< tag::front_speed >());
+    }
+  }
 
-    auto el = static_cast< std::size_t >(esuf[2*f]);
-    auto er = esuf[2*f+1];
-
-    std::array< real, 3 > geoElemR;
-    std::size_t eR(0);
+  for (std::size_t e=0; e<nelem; ++e)
+  {
+    // characteristic length (radius of insphere)
+    auto dx = std::min(std::cbrt(geoElem(e,0)), geoElem(e,4))
+      /std::sqrt(24.0);
 
-    // A second-order (piecewise linear) solution polynomial can be obtained
-    // from the first-order (piecewise constant) FV solutions by using a
-    // least-squares (LS) reconstruction process. LS uses the first-order
-    // solutions from the cell being processed, and the cells surrounding it.
-    // The LS system is obtaining by requiring the following to hold:
-    // 'Taylor expansions of solution from cell-i to the centroids of each of
-    // its neighboring cells should be equal to the cell average solution on
-    // that neighbor cell.'
-    // This gives a system of equations for the three second-order DOFs that are
-    // to be determined. In 3D tetrahedral meshes, this would give four
-    // equations (one for each neighbor )for the three unknown DOFs. This
-    // overdetermined system is solved in the least-squares sense using the
-    // normal equations approach. The normal equations approach involves
-    // pre-multiplying the overdetermined system by the transpose of the system
-    // matrix to obtain a square matrix (3x3 in this case).
-
-    // get a 3x3 system by applying the normal equation approach to the
-    // least-squares overdetermined system
-
-    if (er > -1) {
-    // internal face contribution
-      eR = static_cast< std::size_t >(er);
-      // Put in cell-centroid coordinates
-      geoElemR = {{ geoElem(eR,1), geoElem(eR,2), geoElem(eR,3) }};
-    }
-    else {
-    // boundary face contribution
-      // Put in face-centroid coordinates
-      geoElemR = {{ geoFace(f,4), geoFace(f,5), geoFace(f,6) }};
-    }
-
-    std::array< real, 3 > wdeltax{{ geoElemR[0]-geoElem(el,1),
-                                    geoElemR[1]-geoElem(el,2),
-                                    geoElemR[2]-geoElem(el,3) }};
-
-    // define a lambda for contributing to lhs matrix
-    auto lhs = [&]( std::size_t e ){
-    for (std::size_t idir=0; idir<3; ++idir)
-      for (std::size_t jdir=0; jdir<3; ++jdir)
-        lhs_ls[e][idir][jdir] += wdeltax[idir] * wdeltax[jdir];
-    };
+    // element dt restriction if relevant energy sources were added
+    if (engSrcAd[e] > 0 && std::abs(v_front) > 1e-8)
+      mindt = std::min(mindt, dx/v_front);
+  }
+
+  return mindt;
+}
+
+void MultiMatPhysicsEnergyPill::
+physSrc(
+  std::size_t nmat,
+  tk::real t,
+  const tk::Fields& geoElem,
+  const std::unordered_map< std::size_t, std::set< std::size_t > >& elemblkid,
+  tk::Fields& R,<--- Parameter 'R' can be declared with const
+  std::vector< int >& engSrcAdded ) const
+// *****************************************************************************
+//! Compute sources corresponding to a propagating front in user-defined box
+//! \param[in] nmat Number of materials
+//! \param[in] t Physical time
+//! \param[in] geoElem Element geometry array
+//! \param[in] elemblkid Element ids associated with mesh block ids where
+//!   user ICs are set
+//! \param[in,out] R Right-hand side vector
+//! \param[in,out] engSrcAdded Whether the energy source was added
+//! \details This function adds the energy source corresponding to a
+//!   spherically growing wave-front propagating with a user-specified
+//!   velocity, within a user-configured mesh block initial condition.
+//!   Example (SI) units of the quantities involved:
+//!    * internal energy content (energy per unit volume): J/m^3
+//!    * specific energy (internal energy per unit mass): J/kg
+// *****************************************************************************
+{
+  const auto& icmbk = g_inputdeck.get< tag::ic, tag::meshblock >();
+  for (const auto& mb : icmbk) { // for all blocks
+    auto blid = mb.get< tag::blockid >();
+    if (elemblkid.find(blid) != elemblkid.end()) { // if elements exist in blk
+      const auto& initiate = mb.template get< tag::initiate >();
+      if (initiate == ctr::InitiateType::LINEAR) { // if propagating src
+
+        const auto& blkelems = tk::cref_find(elemblkid,blid);
 
-    // always add left element contribution (at a boundary face, the internal
-    // element is always the left element)
-    lhs(el);
-    // add right element contribution for internal faces only
-    if (er > -1)
-      if (eR < nelem) lhs(eR);
-
-  }
-}
-
-void
-intLeastSq_P0P1( const std::size_t rdof,
-                 const inciter::FaceData& fd,
-                 const Fields& geoElem,
-                 const Fields& W,
-                 std::vector< std::vector< std::array< real, 3 > > >& rhs_ls,
-                 const std::vector< std::size_t >& varList )
-// *****************************************************************************
-//  \brief Compute internal surface contributions to rhs vector of the
-//    least-squares reconstruction
-//! \param[in] rdof Maximum number of reconstructed degrees of freedom
-//! \param[in] fd Face connectivity and boundary conditions object
-//! \param[in] geoElem Element geometry array
-//! \param[in] W Solution vector to be reconstructed at recent time step
-//! \param[in,out] rhs_ls RHS reconstruction vector
-//! \param[in] varList List of indices in W, that need to be reconstructed
-//! \details This function computing the internal face contributions to the rhs
-//!   vector for reconstruction, is common for primitive and conserved
-//!   quantities. If `W` == `U`, compute internal face contributions for the
-//!   conserved variables. If `W` == `P`, compute internal face contributions
-//!   for the primitive variables.
-// *****************************************************************************
-{
-  const auto& esuf = fd.Esuf();
-  const auto nelem = fd.Esuel().size()/4;<--- Variable 'nelem' is assigned a value that is never used.
-
-  // Compute internal face contributions
-  for (auto f=fd.Nbfac(); f<esuf.size()/2; ++f)
-  {
-    Assert( esuf[2*f] > -1 && esuf[2*f+1] > -1, "Interior element detected "
-            "as -1" );
-
-    auto el = static_cast< std::size_t >(esuf[2*f]);
-    auto er = static_cast< std::size_t >(esuf[2*f+1]);
-
-    // get a 3x3 system by applying the normal equation approach to the
-    // least-squares overdetermined system
-
-    // 'wdeltax' is the distance vector between the centroids of this element
-    // and its neighbor
-    std::array< real, 3 > wdeltax{{ geoElem(er,1)-geoElem(el,1),
-                                    geoElem(er,2)-geoElem(el,2),
-                                    geoElem(er,3)-geoElem(el,3) }};
-
-    for (std::size_t idir=0; idir<3; ++idir)
-    {
-      // rhs vector
-      for (std::size_t i=0; i<varList.size(); ++i)
-      {
-        auto c = varList[i];
-        auto mark = c*rdof;
-        rhs_ls[el][c][idir] +=
-          wdeltax[idir] * (W(er,mark)-W(el,mark));
-        if (er < nelem)
-          rhs_ls[er][c][idir] +=
-            wdeltax[idir] * (W(er,mark)-W(el,mark));
-      }
-    }
-  }
-}
-
-void
-bndLeastSqConservedVar_P0P1(
-  ncomp_t ncomp,
-  const std::vector< inciter::EOS >& mat_blk,
-  std::size_t rdof,
-  const std::vector< std::size_t >& bcconfig,
-  const inciter::FaceData& fd,
-  const Fields& geoFace,
-  const Fields& geoElem,
-  real t,
-  const StateFn& state,
-  const Fields& P,
-  const Fields& U,
-  std::vector< std::vector< std::array< real, 3 > > >& rhs_ls,
-  const std::vector< std::size_t >& varList,
-  std::size_t nprim )
-// *****************************************************************************
-//  \brief Compute boundary surface contributions to rhs vector of the
-//    least-squares reconstruction of conserved quantities of the PDE system
-//! \param[in] ncomp Number of scalar components in this PDE system
-//! \param[in] mat_blk EOS material block
-//! \param[in] rdof Maximum number of reconstructed degrees of freedom
-//! \param[in] bcconfig BC configuration vector for multiple side sets
-//! \param[in] fd Face connectivity and boundary conditions object
-//! \param[in] geoFace Face geometry array
-//! \param[in] geoElem Element geometry array
-//! \param[in] t Physical time
-//! \param[in] state Function to evaluate the left and right solution state at
-//!   boundaries
-//! \param[in] P Primitive vector to be reconstructed at recent time step
-//! \param[in] U Solution vector to be reconstructed at recent time step
-//! \param[in,out] rhs_ls RHS reconstruction vector
-//! \param[in] varList List of indices in W, that need to be reconstructed
-//! \param[in] nprim This is the number of primitive quantities stored for this
-//!   PDE system. This is necessary to extend the state vector to the right
-//!   size, so that correct boundary conditions are obtained.
-//!   A default is set to 0, so that calling code for systems that do not store
-//!   primitive quantities does not need to specify this argument.
-//! \details This function computing the boundary face contributions to the rhs
-//!   vector for reconstruction, is used for conserved quantities only.
-// *****************************************************************************
-{
-  const auto& bface = fd.Bface();
-  const auto& esuf = fd.Esuf();
-
-  for (const auto& s : bcconfig) {       // for all bc sidesets
-    auto bc = bface.find(static_cast<int>(s));// faces for side set
-    if (bc != end(bface))
-    {
-      // Compute boundary face contributions
-      for (const auto& f : bc->second)
-      {
-        Assert( esuf[2*f+1] == -1, "physical boundary element not -1" );
-
-        std::size_t el = static_cast< std::size_t >(esuf[2*f]);
-
-        // arrays for quadrature points
-        std::array< real, 3 >
-          fc{{ geoFace(f,4), geoFace(f,5), geoFace(f,6) }};
-        std::array< real, 3 >
-          fn{{ geoFace(f,1), geoFace(f,2), geoFace(f,3) }};
-
-        // Compute the state variables at the left element
-        std::vector< real >B(1,1.0);
-        auto ul = eval_state( ncomp, rdof, 1, el, U, B );
-        auto uprim = eval_state( nprim, rdof, 1, el, P, B );
-
-        // consolidate primitives into state vector
-        ul.insert(ul.end(), uprim.begin(), uprim.end());
-
-        Assert( ul.size() == ncomp+nprim, "Incorrect size for "
-                "appended state vector" );
-
-        // Compute the state at the face-center using BC
-        auto ustate = state( ncomp, mat_blk, ul, fc[0], fc[1], fc[2], t, fn );
-
-        std::array< real, 3 > wdeltax{{ fc[0]-geoElem(el,1),
-                                        fc[1]-geoElem(el,2),
-                                        fc[2]-geoElem(el,3) }};
-
-        for (std::size_t idir=0; idir<3; ++idir)
-        {
-          // rhs vector
-          for (std::size_t i=0; i<varList.size(); ++i)
-          {
-            auto c = varList[i];
-            rhs_ls[el][c][idir] +=
-              wdeltax[idir] * (ustate[1][c]-ustate[0][c]);
-          }
-        }
-      }
-    }
-  }
-}
-
-void
-solveLeastSq_P0P1(
-  const std::size_t rdof,
-  const std::vector< std::array< std::array< real, 3 >, 3 > >& lhs,
-  const std::vector< std::vector< std::array< real, 3 > > >& rhs,
-  Fields& W,<--- Parameter 'W' can be declared with const
-  const std::vector< std::size_t >& varList )
-// *****************************************************************************
-//  Solve the 3x3 linear system for least-squares reconstruction
-//! \param[in] rdof Maximum number of reconstructed degrees of freedom
-//! \param[in] lhs LHS reconstruction matrix
-//! \param[in] rhs RHS reconstruction vector
-//! \param[in,out] W Solution vector to be reconstructed at recent time step
-//! \param[in] varList List of indices in W, that need to be reconstructed
-//! \details Solves the 3x3 linear system for each element, individually. For
-//!   systems that require reconstructions of primitive quantities, this should
-//!   be called twice, once with the argument 'W' as U (conserved), and again
-//!   with 'W' as P (primitive).
-// *****************************************************************************
-{
-  auto nelem = lhs.size();
-
-  for (std::size_t e=0; e<nelem; ++e)
-  {
-    for (std::size_t i=0; i<varList.size(); ++i)
-    {
-      auto mark = varList[i]*rdof;
-
-      // solve system using Cramer's rule
-      auto ux = tk::cramer( lhs[e], rhs[e][varList[i]] );
-
-      W(e,mark+1) = ux[0];
-      W(e,mark+2) = ux[1];
-      W(e,mark+3) = ux[2];
-    }
-  }
-}
-
-void
-recoLeastSqExtStencil(
-  std::size_t rdof,
-  std::size_t e,
-  const std::map< std::size_t, std::vector< std::size_t > >& esup,
-  const std::vector< std::size_t >& inpoel,
-  const Fields& geoElem,
-  Fields& W,<--- Parameter 'W' can be declared with const
-  const std::vector< std::size_t >& varList )
-// *****************************************************************************
-//  \brief Reconstruct the second-order solution using least-squares approach
-//    from an extended stencil involving the node-neighbors
-//! \param[in] rdof Maximum number of reconstructed degrees of freedom
-//! \param[in] e Element whoes solution is being reconstructed
-//! \param[in] esup Elements surrounding points
-//! \param[in] inpoel Element-node connectivity
-//! \param[in] geoElem Element geometry array
-//! \param[in,out] W Solution vector to be reconstructed at recent time step
-//! \param[in] varList List of indices in W, that need to be reconstructed
-//! \details A second-order (piecewise linear) solution polynomial is obtained
-//!   from the first-order (piecewise constant) FV solutions by using a
-//!   least-squares (LS) reconstruction process. This LS reconstruction function
-//!   using the nodal-neighbors of a cell, to get an overdetermined system of
-//!   equations for the derivatives of the solution. This overdetermined system
-//!   is solved in the least-squares sense using the normal equations approach.
-// *****************************************************************************
-{
-  // lhs matrix
-  std::array< std::array< tk::real, 3 >, 3 >
-    lhs_ls( {{ {{0.0, 0.0, 0.0}},
-               {{0.0, 0.0, 0.0}},
-               {{0.0, 0.0, 0.0}} }} );
-  // rhs matrix
-  std::vector< std::array< tk::real, 3 > >
-  rhs_ls( varList.size(), {{ 0.0, 0.0, 0.0 }} );
-
-  // loop over all nodes of the element e
-  for (std::size_t lp=0; lp<4; ++lp)
-  {
-    auto p = inpoel[4*e+lp];
-    const auto& pesup = cref_find(esup, p);
-
-    // loop over all the elements surrounding this node p
-    for (auto er : pesup)
-    {
-      // centroid distance
-      std::array< real, 3 > wdeltax{{ geoElem(er,1)-geoElem(e,1),
-                                      geoElem(er,2)-geoElem(e,2),
-                                      geoElem(er,3)-geoElem(e,3) }};
-
-      // contribute to lhs matrix
-      for (std::size_t idir=0; idir<3; ++idir)
-        for (std::size_t jdir=0; jdir<3; ++jdir)
-          lhs_ls[idir][jdir] += wdeltax[idir] * wdeltax[jdir];
-
-      // compute rhs matrix
-      for (std::size_t i=0; i<varList.size(); i++)
-      {
-        auto mark = varList[i]*rdof;
-        for (std::size_t idir=0; idir<3; ++idir)
-          rhs_ls[i][idir] +=
-            wdeltax[idir] * (W(er,mark)-W(e,mark));
-
-      }
-    }
-  }
-
-  // solve least-square normal equation system using Cramer's rule
-  for (std::size_t i=0; i<varList.size(); i++)
-  {
-    auto mark = varList[i]*rdof;
-
-    auto ux = tk::cramer( lhs_ls, rhs_ls[i] );
-
-    // Update the P1 dofs with the reconstructioned gradients.
-    // Since this reconstruction does not affect the cell-averaged solution,
-    // W(e,mark+0) is unchanged.
-    W(e,mark+1) = ux[0];
-    W(e,mark+2) = ux[1];
-    W(e,mark+3) = ux[2];
-  }
-}
-
-void
-transform_P0P1( std::size_t rdof,
-                std::size_t nelem,
-                const std::vector< std::size_t >& inpoel,
-                const UnsMesh::Coords& coord,
-                Fields& W,<--- Parameter 'W' can be declared with const
-                const std::vector< std::size_t >& varList )
-// *****************************************************************************
-//  Transform the reconstructed P1-derivatives to the Dubiner dofs
-//! \param[in] rdof Total number of reconstructed dofs
-//! \param[in] nelem Total number of elements
-//! \param[in] inpoel Element-node connectivity
-//! \param[in] coord Array of nodal coordinates
-//! \param[in,out] W Second-order reconstructed vector which gets transformed to
-//!   the Dubiner reference space
-//! \param[in] varList List of indices in W, that need to be reconstructed
-//! \details Since the DG solution (and the primitive quantities) are assumed to
-//!   be stored in the Dubiner space, this transformation from Taylor
-//!   coefficients to Dubiner coefficients is necessary.
-// *****************************************************************************
-{
-  const auto& cx = coord[0];
-  const auto& cy = coord[1];
-  const auto& cz = coord[2];
-
-  for (std::size_t e=0; e<nelem; ++e)
-  {
-    // Extract the element coordinates
-    std::array< std::array< real, 3>, 4 > coordel {{
-      {{ cx[ inpoel[4*e  ] ], cy[ inpoel[4*e  ] ], cz[ inpoel[4*e  ] ] }},
-      {{ cx[ inpoel[4*e+1] ], cy[ inpoel[4*e+1] ], cz[ inpoel[4*e+1] ] }},
-      {{ cx[ inpoel[4*e+2] ], cy[ inpoel[4*e+2] ], cz[ inpoel[4*e+2] ] }},
-      {{ cx[ inpoel[4*e+3] ], cy[ inpoel[4*e+3] ], cz[ inpoel[4*e+3] ] }}
-    }};
-
-    auto jacInv =
-      tk::inverseJacobian( coordel[0], coordel[1], coordel[2], coordel[3] );
-
-    // Compute the derivatives of basis function for DG(P1)
-    auto dBdx = tk::eval_dBdx_p1( rdof, jacInv );
-
-    for (std::size_t i=0; i<varList.size(); ++i)
-    {
-      auto mark = varList[i]*rdof;
-
-      // solve system using Cramer's rule
-      auto ux = tk::cramer( {{ {{dBdx[0][1], dBdx[0][2], dBdx[0][3]}},
-                               {{dBdx[1][1], dBdx[1][2], dBdx[1][3]}},
-                               {{dBdx[2][1], dBdx[2][2], dBdx[2][3]}} }},
-                            {{ W(e,mark+1),
-                               W(e,mark+2),
-                               W(e,mark+3) }} );
-
-      // replace physical derivatives with transformed dofs
-      W(e,mark+1) = ux[0];
-      W(e,mark+2) = ux[1];
-      W(e,mark+3) = ux[2];
-    }
-  }
-}
-
-void
-THINCReco( std::size_t rdof,
-           std::size_t nmat,
-           std::size_t e,
-           const std::vector< std::size_t >& inpoel,
-           const UnsMesh::Coords& coord,
-           const Fields& geoElem,
-           const std::array< real, 3 >& ref_xp,
-           const Fields& U,
-           const Fields& P,
-           bool intInd,
-           const std::vector< std::size_t >& matInt,
-           [[maybe_unused]] const std::vector< real >& vfmin,
-           [[maybe_unused]] const std::vector< real >& vfmax,
-           std::vector< real >& state )
-// *****************************************************************************
-//  Compute THINC reconstructions at quadrature point for multi-material flows
-//! \param[in] rdof Total number of reconstructed dofs
-//! \param[in] nmat Total number of materials
-//! \param[in] e Element for which interface reconstruction is being calculated
-//! \param[in] inpoel Element-node connectivity
-//! \param[in] coord Array of nodal coordinates
-//! \param[in] geoElem Element geometry array
-//! \param[in] ref_xp Quadrature point in reference space
-//! \param[in] U Solution vector
-//! \param[in] P Vector of primitives
-//! \param[in] intInd Boolean which indicates if the element contains a
-//!   material interface
-//! \param[in] matInt Array indicating which material has an interface
-//! \param[in] vfmin Vector containing min volume fractions for each material
-//!   in this cell
-//! \param[in] vfmax Vector containing max volume fractions for each material
-//!   in this cell
-//! \param[in,out] state Unknown/state vector at quadrature point, modified
-//!   if near interfaces using THINC
-//! \details This function is an interface for the multimat PDEs that use the
-//!   algebraic multi-material THINC reconstruction. This particular function
-//!   should only be called for multimat.
-// *****************************************************************************
-{
-  using inciter::volfracDofIdx;
-  using inciter::densityDofIdx;
-  using inciter::momentumDofIdx;
-  using inciter::energyDofIdx;
-  using inciter::pressureDofIdx;
-  using inciter::velocityDofIdx;
-  using inciter::deformDofIdx;
-  using inciter::stressDofIdx;
-  using inciter::volfracIdx;
-  using inciter::densityIdx;
-  using inciter::momentumIdx;
-  using inciter::energyIdx;
-  using inciter::pressureIdx;
-  using inciter::velocityIdx;
-  using inciter::deformIdx;
-  using inciter::stressIdx;
-
-  auto bparam = inciter::g_inputdeck.get< tag::multimat,
-    tag::intsharp_param >();
-  const auto ncomp = U.nprop()/rdof;
-  const auto& solidx = inciter::g_inputdeck.get< tag::matidxmap,
-    tag::solidx >();
-
-  // Step-1: Perform THINC reconstruction
-  // create a vector of volume-fractions and pass it to the THINC function
-  std::vector< real > alSol(rdof*nmat, 0.0);
-  std::vector< real > alReco(nmat, 0.0);
-  for (std::size_t k=0; k<nmat; ++k) {
-    auto mark = k*rdof;
-    for (std::size_t i=0; i<rdof; ++i) {
-      alSol[mark+i] = U(e, volfracDofIdx(nmat,k,rdof,i));
-    }
-    // initialize with TVD reconstructions which will be modified if near
-    // material interface
-    alReco[k] = state[volfracIdx(nmat,k)];
-  }
-  THINCFunction(rdof, nmat, e, inpoel, coord, ref_xp, geoElem(e,0), bparam,
-    alSol, intInd, matInt, alReco);
-
-  // check reconstructed volfracs for positivity
-  bool neg_vf = false;
-  for (std::size_t k=0; k<nmat; ++k) {
-    if (alReco[k] < 1e-16 && matInt[k] > 0) neg_vf = true;
-  }
-  for (std::size_t k=0; k<nmat; ++k) {
-    if (neg_vf) {
-      std::cout << "Material-id:        " << k << std::endl;
-      std::cout << "Volume-fraction:    " << std::setprecision(18) << alReco[k]
-        << std::endl;
-      std::cout << "Cell-avg vol-frac:  " << std::setprecision(18) <<
-        U(e,volfracDofIdx(nmat,k,rdof,0)) << std::endl;
-      std::cout << "Material-interface? " << intInd << std::endl;
-      std::cout << "Mat-k-involved?     " << matInt[k] << std::endl;
-    }
-  }
-  if (neg_vf) Throw("Material has negative volume fraction after THINC "
-    "reconstruction.");
-
-  // Step-2: Perform consistent reconstruction on other conserved quantities
-  if (intInd)
-  {
-    auto rhobCC(0.0), rhobHO(0.0);
-    for (std::size_t k=0; k<nmat; ++k)
-    {
-      auto alCC = U(e, volfracDofIdx(nmat,k,rdof,0));
-      alCC = std::max(1e-14, alCC);
-
-      if (matInt[k])
-      {
-        state[volfracIdx(nmat,k)] = alReco[k];
-        state[densityIdx(nmat,k)] = alReco[k]
-          * U(e, densityDofIdx(nmat,k,rdof,0))/alCC;
-        state[energyIdx(nmat,k)] = alReco[k]
-          * U(e, energyDofIdx(nmat,k,rdof,0))/alCC;
-        state[ncomp+pressureIdx(nmat,k)] = alReco[k]
-          * P(e, pressureDofIdx(nmat,k,rdof,0))/alCC;
-        if (solidx[k] > 0) {
-          for (std::size_t i=0; i<3; ++i)
-            for (std::size_t j=0; j<3; ++j)
-              state[deformIdx(nmat,solidx[k],i,j)] =
-                U(e, deformDofIdx(nmat,solidx[k],i,j,rdof,0));
-
-          for (std::size_t i=0; i<6; ++i)
-            state[ncomp+stressIdx(nmat,solidx[k],i)] = alReco[k]
-              * P(e, stressDofIdx(nmat,solidx[k],i,rdof,0))/alCC;
-        }
-      }
-
-      rhobCC += U(e, densityDofIdx(nmat,k,rdof,0));
-      rhobHO += state[densityIdx(nmat,k)];
-    }
-
-    // consistent reconstruction for bulk momentum
-    for (std::size_t i=0; i<3; ++i)
-    {
-      state[momentumIdx(nmat,i)] = rhobHO
-        * U(e, momentumDofIdx(nmat,i,rdof,0))/rhobCC;
-      state[ncomp+velocityIdx(nmat,i)] =
-        P(e, velocityDofIdx(nmat,i,rdof,0));
-    }
-  }
-}
-
-void
-THINCRecoTransport( std::size_t rdof,
-                    std::size_t,
-                    std::size_t e,
-                    const std::vector< std::size_t >& inpoel,
-                    const UnsMesh::Coords& coord,
-                    const Fields& geoElem,
-                    const std::array< real, 3 >& ref_xp,
-                    const Fields& U,
-                    const Fields&,
-                    [[maybe_unused]] const std::vector< real >& vfmin,
-                    [[maybe_unused]] const std::vector< real >& vfmax,
-                    std::vector< real >& state )
-// *****************************************************************************
-//  Compute THINC reconstructions at quadrature point for transport
-//! \param[in] rdof Total number of reconstructed dofs
-//! \param[in] e Element for which interface reconstruction is being calculated
-//! \param[in] inpoel Element-node connectivity
-//! \param[in] coord Array of nodal coordinates
-//! \param[in] geoElem Element geometry array
-//! \param[in] ref_xp Quadrature point in reference space
-//! \param[in] U Solution vector
-//! \param[in] vfmin Vector containing min volume fractions for each material
-//!   in this cell
-//! \param[in] vfmax Vector containing max volume fractions for each material
-//!   in this cell
-//! \param[in,out] state Unknown/state vector at quadrature point, modified
-//!   if near interfaces using THINC
-//! \details This function is an interface for the transport PDEs that use the
-//!   algebraic multi-material THINC reconstruction. This particular function
-//!   should only be called for transport.
-// *****************************************************************************
-{
-  auto bparam = inciter::g_inputdeck.get< tag::transport,
-    tag::intsharp_param >();
-  auto ncomp = U.nprop()/rdof;
-
-  // interface detection
-  std::vector< std::size_t > matInt(ncomp, 0);
-  std::vector< tk::real > alAvg(ncomp, 0.0);
-  for (std::size_t k=0; k<ncomp; ++k)
-    alAvg[k] = U(e, k*rdof);
-  auto intInd = inciter::interfaceIndicator(ncomp, alAvg, matInt);
-
-  // create a vector of volume-fractions and pass it to the THINC function
-  std::vector< real > alSol(rdof*ncomp, 0.0);
-  // initialize with TVD reconstructions (modified if near interface)
-  auto alReco = state;
-  for (std::size_t k=0; k<ncomp; ++k) {
-    auto mark = k*rdof;
-    for (std::size_t i=0; i<rdof; ++i) {
-      alSol[mark+i] = U(e,mark+i);
-    }
-  }
-  THINCFunction(rdof, ncomp, e, inpoel, coord, ref_xp, geoElem(e,0), bparam,
-    alSol, intInd, matInt, alReco);
-
-  state = alReco;
-}
-
-void
-THINCFunction( std::size_t rdof,
-               std::size_t nmat,
-               std::size_t e,
-               const std::vector< std::size_t >& inpoel,
-               const UnsMesh::Coords& coord,
-               const std::array< real, 3 >& ref_xp,
-               real vol,
-               real bparam,
-               const std::vector< real >& alSol,
-               bool intInd,
-               const std::vector< std::size_t >& matInt,
-               std::vector< real >& alReco )
-// *****************************************************************************
-//  Old version of the Multi-Medium THINC reconstruction function
-//! \param[in] rdof Total number of reconstructed dofs
-//! \param[in] nmat Total number of materials
-//! \param[in] e Element for which interface reconstruction is being calculated
-//! \param[in] inpoel Element-node connectivity
-//! \param[in] coord Array of nodal coordinates
-//! \param[in] ref_xp Quadrature point in reference space
-//! \param[in] vol Element volume
-//! \param[in] bparam User specified Beta for THINC, from the input file
-//! \param[in] alSol Volume fraction solution vector for element e
-//! \param[in] intInd Interface indicator, true if e is interface element
-//! \param[in] matInt Vector indicating materials which constitute interface
-//! \param[in,out] alReco Unknown/state vector at quadrature point, which gets
-//!   modified if near interface using MM-THINC
-//! \details This function computes the interface reconstruction using the
-//!   algebraic multi-material THINC reconstruction for each material at the
-//!   given (ref_xp) quadrature point. This function is based on the following:
-//!   Pandare A. K., Waltz J., & Bakosi J. (2021) Multi-Material Hydrodynamics
-//!   with Algebraic Sharp Interface Capturing. Computers & Fluids,
-//!   doi: https://doi.org/10.1016/j.compfluid.2020.104804.
-//!   This function will be removed after the newer version (see
-//!   THINCFunction_new) is sufficiently tested.
-// *****************************************************************************
-{
-  // determine number of materials with interfaces in this cell
-  auto epsl(1e-4), epsh(1e-1), bred(1.25), bmod(bparam);
-  std::size_t nIntMat(0);
-  for (std::size_t k=0; k<nmat; ++k)
-  {
-    auto alk = alSol[k*rdof];
-    if (alk > epsl)
-    {
-      ++nIntMat;
-      if ((alk > epsl) && (alk < epsh))
-        bmod = std::min(bmod,
-          (alk-epsl)/(epsh-epsl) * (bred - bparam) + bparam);
-      else if (alk > epsh)
-        bmod = bred;
-    }
-  }
-
-  if (nIntMat > 2) bparam = bmod;
-
-  // compression parameter
-  auto beta = bparam/std::cbrt(6.0*vol);
-
-  if (intInd)
-  {
-    // 1. Get unit normals to material interface
-
-    // Compute Jacobian matrix for converting Dubiner dofs to derivatives
-    const auto& cx = coord[0];
-    const auto& cy = coord[1];
-    const auto& cz = coord[2];
-
-    std::array< std::array< real, 3>, 4 > coordel {{
-      {{ cx[ inpoel[4*e  ] ], cy[ inpoel[4*e  ] ], cz[ inpoel[4*e  ] ] }},
-      {{ cx[ inpoel[4*e+1] ], cy[ inpoel[4*e+1] ], cz[ inpoel[4*e+1] ] }},
-      {{ cx[ inpoel[4*e+2] ], cy[ inpoel[4*e+2] ], cz[ inpoel[4*e+2] ] }},
-      {{ cx[ inpoel[4*e+3] ], cy[ inpoel[4*e+3] ], cz[ inpoel[4*e+3] ] }}
-    }};
-
-    auto jacInv =
-      tk::inverseJacobian( coordel[0], coordel[1], coordel[2], coordel[3] );
-
-    auto dBdx = tk::eval_dBdx_p1( rdof, jacInv );
-
-    std::array< real, 3 > nInt;
-    std::vector< std::array< real, 3 > > ref_n(nmat, {{0.0, 0.0, 0.0}});
-
-    // Get normals
-    for (std::size_t k=0; k<nmat; ++k)
-    {
-      // Get derivatives from moments in Dubiner space
-      for (std::size_t i=0; i<3; ++i)
-        nInt[i] = dBdx[i][1] * alSol[k*rdof+1]
-          + dBdx[i][2] * alSol[k*rdof+2]
-          + dBdx[i][3] * alSol[k*rdof+3];
-
-      auto nMag = std::sqrt(tk::dot(nInt, nInt)) + 1e-14;
-
-      for (std::size_t i=0; i<3; ++i)
-        nInt[i] /= nMag;
-
-      // project interface normal onto local/reference coordinate system
-      for (std::size_t i=0; i<3; ++i)
-      {
-        std::array< real, 3 > axis{
-          coordel[i+1][0]-coordel[0][0],
-          coordel[i+1][1]-coordel[0][1],
-          coordel[i+1][2]-coordel[0][2] };
-        ref_n[k][i] = tk::dot(nInt, axis);
-      }
-    }
-
-    // 2. Reconstruct volume fractions using THINC
-    auto max_lim = 1.0 - (static_cast<tk::real>(nmat-1)*1.0e-12);
-    auto min_lim = 1e-12;
-    auto sum_inter(0.0), sum_non_inter(0.0);
-    for (std::size_t k=0; k<nmat; ++k)
-    {
-      if (matInt[k])
-      {
-        // get location of material interface (volume fraction 0.5) from the
-        // assumed tanh volume fraction distribution, and cell-averaged
-        // volume fraction
-        auto alCC(alSol[k*rdof]);
-        auto Ac(0.0), Bc(0.0), Qc(0.0);
-        if ((std::abs(ref_n[k][0]) > std::abs(ref_n[k][1]))
-          && (std::abs(ref_n[k][0]) > std::abs(ref_n[k][2])))
-        {
-          Ac = std::exp(0.5*beta*ref_n[k][0]);
-          Bc = std::exp(0.5*beta*(ref_n[k][1]+ref_n[k][2]));
-          Qc = std::exp(0.5*beta*ref_n[k][0]*(2.0*alCC-1.0));
-        }
-        else if ((std::abs(ref_n[k][1]) > std::abs(ref_n[k][0]))
-          && (std::abs(ref_n[k][1]) > std::abs(ref_n[k][2])))
-        {
-          Ac = std::exp(0.5*beta*ref_n[k][1]);
-          Bc = std::exp(0.5*beta*(ref_n[k][0]+ref_n[k][2]));
-          Qc = std::exp(0.5*beta*ref_n[k][1]*(2.0*alCC-1.0));
-        }
-        else
-        {
-          Ac = std::exp(0.5*beta*ref_n[k][2]);
-          Bc = std::exp(0.5*beta*(ref_n[k][0]+ref_n[k][1]));
-          Qc = std::exp(0.5*beta*ref_n[k][2]*(2.0*alCC-1.0));
-        }
-        auto d = std::log((1.0-Ac*Qc) / (Ac*Bc*(Qc-Ac))) / (2.0*beta);
-
-        // THINC reconstruction
-        auto al_c = 0.5 * (1.0 + std::tanh(beta*(tk::dot(ref_n[k], ref_xp) + d)));
-
-        alReco[k] = std::min(max_lim, std::max(min_lim, al_c));
-
-        sum_inter += alReco[k];
-      } else
-      {
-        sum_non_inter += alReco[k];
-      }
-      // else, if this material does not have an interface close-by, the TVD
-      // reconstructions must be used for state variables. This is ensured by
-      // initializing the alReco vector as the TVD state.
-    }
-
-    // Rescale volume fractions of interface-materials to ensure unit sum
-    auto sum_rest = 1.0 - sum_non_inter;
-    for (std::size_t k=0; k<nmat; ++k)
-      if(matInt[k])
-        alReco[k] = alReco[k] * sum_rest / sum_inter;
-  }
-}
-
-void
-THINCFunction_new( std::size_t rdof,
-                   std::size_t nmat,
-                   std::size_t e,
-                   const std::vector< std::size_t >& inpoel,
-                   const UnsMesh::Coords& coord,
-                   const std::array< real, 3 >& ref_xp,
-                   real vol,
-                   real bparam,
-                   const std::vector< real >& alSol,
-                   bool intInd,
-                   const std::vector< std::size_t >& matInt,
-                   std::vector< real >& alReco )
-// *****************************************************************************
-//  New Multi-Medium THINC reconstruction function for volume fractions
-//! \param[in] rdof Total number of reconstructed dofs
-//! \param[in] nmat Total number of materials
-//! \param[in] e Element for which interface reconstruction is being calculated
-//! \param[in] inpoel Element-node connectivity
-//! \param[in] coord Array of nodal coordinates
-//! \param[in] ref_xp Quadrature point in reference space
-//! \param[in] vol Element volume
-//! \param[in] bparam User specified Beta for THINC, from the input file
-//! \param[in] alSol Volume fraction solution vector for element e
-//! \param[in] intInd Interface indicator, true if e is interface element
-//! \param[in] matInt Vector indicating materials which constitute interface
-//! \param[in,out] alReco Unknown/state vector at quadrature point, which gets
-//!   modified if near interface using MM-THINC
-//! \details This function computes the interface reconstruction using the
-//!   algebraic multi-material THINC reconstruction for each material at the
-//!   given (ref_xp) quadrature point. This function succeeds the older version
-//!   of the mm-THINC (see THINCFunction), but is still under testing and is
-//!   currently experimental.
-// *****************************************************************************
-{
-  // compression parameter
-  auto beta = bparam/std::cbrt(6.0*vol);
-
-  // If the cell is not material interface, return this function
-  if (not intInd) return;
-
-  // If the cell is material interface, THINC reconstruction is applied
-  // Step 1. Get unit normals to material interface
-  // -------------------------------------------------------------------------
-
-  // Compute Jacobian matrix for converting Dubiner dofs to derivatives
-  const auto& cx = coord[0];
-  const auto& cy = coord[1];
-  const auto& cz = coord[2];
-
-  std::array< std::array< real, 3>, 4 > coordel {{
-    {{ cx[ inpoel[4*e  ] ], cy[ inpoel[4*e  ] ], cz[ inpoel[4*e  ] ] }},
-    {{ cx[ inpoel[4*e+1] ], cy[ inpoel[4*e+1] ], cz[ inpoel[4*e+1] ] }},
-    {{ cx[ inpoel[4*e+2] ], cy[ inpoel[4*e+2] ], cz[ inpoel[4*e+2] ] }},
-    {{ cx[ inpoel[4*e+3] ], cy[ inpoel[4*e+3] ], cz[ inpoel[4*e+3] ] }}
-  }};
-
-  auto jacInv =
-    tk::inverseJacobian( coordel[0], coordel[1], coordel[2], coordel[3] );
-
-  auto dBdx = tk::eval_dBdx_p1( rdof, jacInv );
-
-  std::array< real, 3 > nInt;
-  std::array< real, 3 > ref_n{0.0, 0.0, 0.0};
-  auto almax(0.0);
-  std::size_t kmax(0);
-
-  // Determine index of material present in majority
-  for (std::size_t k=0; k<nmat; ++k)
-  {
-    auto alk = alSol[k*rdof];
-    if (alk > almax)
-    {
-      almax = alk;
-      kmax = k;
-    }
-  }
-
-  // Get normals of material present in majority
-  // Get derivatives from moments in Dubiner space
-  for (std::size_t i=0; i<3; ++i)
-    nInt[i] = dBdx[i][1] * alSol[kmax*rdof+1]
-      + dBdx[i][2] * alSol[kmax*rdof+2]
-      + dBdx[i][3] * alSol[kmax*rdof+3];
-
-  auto nMag = std::sqrt(tk::dot(nInt, nInt)) + 1e-14;
-
-  for (std::size_t i=0; i<3; ++i)
-    nInt[i] /= nMag;
-
-  // project interface normal onto local/reference coordinate system
-  for (std::size_t i=0; i<3; ++i)
-  {
-    std::array< real, 3 > axis{
-      coordel[i+1][0]-coordel[0][0],
-      coordel[i+1][1]-coordel[0][1],
-      coordel[i+1][2]-coordel[0][2] };
-    ref_n[i] = tk::dot(nInt, axis);
-  }
-
-  // Step 2. Reconstruct volume fraction of majority material using THINC
-  // -------------------------------------------------------------------------
-
-  auto al_max = 1.0 - (static_cast<tk::real>(nmat-1)*1.0e-12);
-  auto al_min = 1e-12;
-  auto alsum(0.0);
-  // get location of material interface (volume fraction 0.5) from the
-  // assumed tanh volume fraction distribution, and cell-averaged
-  // volume fraction
-  auto alCC(alSol[kmax*rdof]);
-  auto Ac(0.0), Bc(0.0), Qc(0.0);
-  if ((std::abs(ref_n[0]) > std::abs(ref_n[1]))
-    && (std::abs(ref_n[0]) > std::abs(ref_n[2])))
-  {
-    Ac = std::exp(0.5*beta*ref_n[0]);
-    Bc = std::exp(0.5*beta*(ref_n[1]+ref_n[2]));
-    Qc = std::exp(0.5*beta*ref_n[0]*(2.0*alCC-1.0));
-  }
-  else if ((std::abs(ref_n[1]) > std::abs(ref_n[0]))
-    && (std::abs(ref_n[1]) > std::abs(ref_n[2])))
-  {
-    Ac = std::exp(0.5*beta*ref_n[1]);
-    Bc = std::exp(0.5*beta*(ref_n[0]+ref_n[2]));
-    Qc = std::exp(0.5*beta*ref_n[1]*(2.0*alCC-1.0));
-  }
-  else
-  {
-    Ac = std::exp(0.5*beta*ref_n[2]);
-    Bc = std::exp(0.5*beta*(ref_n[0]+ref_n[1]));
-    Qc = std::exp(0.5*beta*ref_n[2]*(2.0*alCC-1.0));
-  }
-  auto d = std::log((1.0-Ac*Qc) / (Ac*Bc*(Qc-Ac))) / (2.0*beta);
-
-  // THINC reconstruction
-  auto al_c = 0.5 * (1.0 + std::tanh(beta*(tk::dot(ref_n, ref_xp) + d)));
-
-  alReco[kmax] = std::min(al_max, std::max(al_min, al_c));
-  alsum += alReco[kmax];
-
-  // if this material does not have an interface close-by, the TVD
-  // reconstructions must be used for state variables. This is ensured by
-  // initializing the alReco vector as the TVD state.
-  for (std::size_t k=0; k<nmat; ++k) {
-    if (!matInt[k]) {
-      alsum += alReco[k];
-    }
-  }
-
-  // Step 3. Do multimaterial cell corrections
-  // -------------------------------------------------------------------------
-
-  // distribute remaining volume to rest of materials
-  auto sum_left = 1.0 - alsum;
-  real den = 0.0;
-  for (std::size_t k=0; k<nmat; ++k) {
-    if (matInt[k] && k != kmax) {
-      auto mark = k * rdof;
-      alReco[k] = sum_left * alSol[mark];
-      den += alSol[mark];
-    }
-  }
-  // the distributed volfracs might be below al_min, correct that
-  real err = 0.0;
-  for (std::size_t k=0; k<nmat; ++k) {
-    if (matInt[k] && k != kmax) {
-      alReco[k] /= den;
-      if (alReco[k] < al_min) {
-        err += al_min - alReco[k];
-        alReco[k] = al_min;
-      }
-    }
-  }
-
-  // balance out errors
-  alReco[kmax] -= err;
-}
-
-std::vector< tk::real >
-evalPolynomialSol( const std::vector< inciter::EOS >& mat_blk,
-                   int intsharp,
-                   std::size_t ncomp,
-                   std::size_t nprim,
-                   std::size_t rdof,
-                   std::size_t nmat,
-                   std::size_t e,
-                   std::size_t dof_e,
-                   const std::vector< std::size_t >& inpoel,
-                   const UnsMesh::Coords& coord,
-                   const Fields& geoElem,
-                   const std::array< real, 3 >& ref_gp,
-                   const std::vector< real >& B,
-                   const Fields& U,
-                   const Fields& P )
-// *****************************************************************************
-//  Evaluate polynomial solution at quadrature point
-//! \param[in] mat_blk EOS material block
-//! \param[in] intsharp Interface reconstruction indicator
-//! \param[in] ncomp Number of components in the PDE system
-//! \param[in] nprim Number of primitive quantities
-//! \param[in] rdof Total number of reconstructed dofs
-//! \param[in] nmat Total number of materials
-//! \param[in] e Element for which polynomial solution is being evaluated
-//! \param[in] dof_e Degrees of freedom for element
-//! \param[in] inpoel Element-node connectivity
-//! \param[in] coord Array of nodal coordinates
-//! \param[in] geoElem Element geometry array
-//! \param[in] ref_gp Quadrature point in reference space
-//! \param[in] B Basis function at given quadrature point
-//! \param[in] U Solution vector
-//! \param[in] P Vector of primitives
-//! \return High-order unknown/state vector at quadrature point, modified
-//!   if near interfaces using THINC
-// *****************************************************************************
-{
-  std::vector< real > state;
-  std::vector< real > sprim;
-
-  state = eval_state( ncomp, rdof, dof_e, e, U, B );
-  sprim = eval_state( nprim, rdof, dof_e, e, P, B );
-
-  // interface detection
-  std::vector< std::size_t > matInt(nmat, 0);
-  bool intInd(false);
-  if (nmat > 1) {
-    std::vector< tk::real > alAvg(nmat, 0.0);
-    for (std::size_t k=0; k<nmat; ++k)
-      alAvg[k] = U(e, inciter::volfracDofIdx(nmat,k,rdof,0));
-    intInd = inciter::interfaceIndicator(nmat, alAvg, matInt);
-  }
-
-  // consolidate primitives into state vector
-  state.insert(state.end(), sprim.begin(), sprim.end());
-
-  if (intsharp > 0)
-  {
-    std::vector< tk::real > vfmax(nmat, 0.0), vfmin(nmat, 0.0);
-
-    // Until the appropriate setup for activating THINC with Transport
-    // is ready, the following two chunks of code will need to be commented
-    // for using THINC with Transport
-    //for (std::size_t k=0; k<nmat; ++k) {
-    //  vfmin[k] = VolFracMax(el, 2*k, 0);
-    //  vfmax[k] = VolFracMax(el, 2*k+1, 0);
-    //}
-    tk::THINCReco(rdof, nmat, e, inpoel, coord, geoElem,
-      ref_gp, U, P, intInd, matInt, vfmin, vfmax, state);
-
-    // Until the appropriate setup for activating THINC with Transport
-    // is ready, the following lines will need to be uncommented for
-    // using THINC with Transport
-    //tk::THINCRecoTransport(rdof, nmat, el, inpoel, coord,
-    //  geoElem, ref_gp_l, U, P, vfmin, vfmax, state[0]);
-  }
-
-  // physical constraints
-  if (state.size() > ncomp) {
-    using inciter::pressureIdx;
-    using inciter::volfracIdx;
-    using inciter::densityIdx;
-
-    for (std::size_t k=0; k<nmat; ++k) {
-      state[ncomp+pressureIdx(nmat,k)] = constrain_pressure( mat_blk,
-        state[ncomp+pressureIdx(nmat,k)], state[densityIdx(nmat,k)],
-        state[volfracIdx(nmat,k)], k );
-    }
-  }
-
-  return state;
-}
-
-std::vector< tk::real >
-evalFVSol( const std::vector< inciter::EOS >& mat_blk,
-           int intsharp,
-           std::size_t ncomp,
-           std::size_t nprim,
-           std::size_t rdof,
-           std::size_t nmat,
-           std::size_t e,
-           const std::vector< std::size_t >& inpoel,
-           const UnsMesh::Coords& coord,
-           const Fields& geoElem,
-           const std::array< real, 3 >& ref_gp,
-           const std::vector< real >& B,
-           const Fields& U,
-           const Fields& P,
-           int srcFlag )
-// *****************************************************************************
-//  Evaluate second-order FV solution at quadrature point
-//! \param[in] mat_blk EOS material block
-//! \param[in] intsharp Interface reconstruction indicator
-//! \param[in] ncomp Number of components in the PDE system
-//! \param[in] nprim Number of primitive quantities
-//! \param[in] rdof Total number of reconstructed dofs
-//! \param[in] nmat Total number of materials
-//! \param[in] e Element for which polynomial solution is being evaluated
-//! \param[in] inpoel Element-node connectivity
-//! \param[in] coord Array of nodal coordinates
-//! \param[in] geoElem Element geometry array
-//! \param[in] ref_gp Quadrature point in reference space
-//! \param[in] B Basis function at given quadrature point
-//! \param[in] U Solution vector
-//! \param[in] P Vector of primitives
-//! \param[in] srcFlag Whether the energy source was added to element e
-//! \return High-order unknown/state vector at quadrature point, modified
-//!   if near interfaces using THINC
-// *****************************************************************************
-{
-  using inciter::pressureIdx;
-  using inciter::velocityIdx;
-  using inciter::volfracIdx;
-  using inciter::densityIdx;
-  using inciter::energyIdx;
-  using inciter::momentumIdx;
-
-  std::vector< real > state;
-  std::vector< real > sprim;
-
-  state = eval_state( ncomp, rdof, rdof, e, U, B );
-  sprim = eval_state( nprim, rdof, rdof, e, P, B );
-
-  // interface detection so that eos is called on the appropriate quantities
-  std::vector< std::size_t > matInt(nmat, 0);
-  std::vector< tk::real > alAvg(nmat, 0.0);
-  for (std::size_t k=0; k<nmat; ++k)
-    alAvg[k] = U(e, inciter::volfracDofIdx(nmat,k,rdof,0));
-  auto intInd = inciter::interfaceIndicator(nmat, alAvg, matInt);
-
-  // get mat-energy from reconstructed mat-pressure
-  auto rhob(0.0);
-  for (std::size_t k=0; k<nmat; ++k) {
-    auto alk = state[volfracIdx(nmat,k)];
-    if (matInt[k]) {
-      alk = std::max(std::min(alk, 1.0-static_cast<tk::real>(nmat-1)*1e-12),
-        1e-12);
-    }
-    state[energyIdx(nmat,k)] = alk *
-      mat_blk[k].compute< inciter::EOS::totalenergy >(
-      state[densityIdx(nmat,k)]/alk, sprim[velocityIdx(nmat,0)],
-      sprim[velocityIdx(nmat,1)], sprim[velocityIdx(nmat,2)],
-      sprim[pressureIdx(nmat,k)]/alk);
-    rhob += state[densityIdx(nmat,k)];
-  }
-  // get momentum from reconstructed velocity and bulk density
-  for (std::size_t i=0; i<3; ++i) {
-    state[momentumIdx(nmat,i)] = rhob * sprim[velocityIdx(nmat,i)];
-  }
-
-  // consolidate primitives into state vector
-  state.insert(state.end(), sprim.begin(), sprim.end());
-
-  if (intsharp > 0 && srcFlag == 0)
-  {
-    std::vector< tk::real > vfmax(nmat, 0.0), vfmin(nmat, 0.0);
-
-    tk::THINCReco(rdof, nmat, e, inpoel, coord, geoElem,
-      ref_gp, U, P, intInd, matInt, vfmin, vfmax, state);
-  }
-
-  // physical constraints
-  if (state.size() > ncomp) {
-    for (std::size_t k=0; k<nmat; ++k) {
-      state[ncomp+pressureIdx(nmat,k)] = constrain_pressure( mat_blk,
-        state[ncomp+pressureIdx(nmat,k)], state[densityIdx(nmat,k)],
-        state[volfracIdx(nmat,k)], k );
-    }
-  }
-
-  return state;
-}
-
-void
-safeReco( std::size_t rdof,
-          std::size_t nmat,
-          std::size_t el,
-          int er,
-          const Fields& U,
-          std::array< std::vector< real >, 2 >& state )
-// *****************************************************************************
-//  Compute safe reconstructions near material interfaces
-//! \param[in] rdof Total number of reconstructed dofs
-//! \param[in] nmat Total number of material is PDE system
-//! \param[in] el Element on the left-side of face
-//! \param[in] er Element on the right-side of face
-//! \param[in] U Solution vector at recent time-stage
-//! \param[in,out] state Second-order reconstructed state, at cell-face, that
-//!   is being modified for safety
-//! \details When the consistent limiting is applied, there is a possibility
-//!   that the material densities and energies violate TVD bounds. This function
-//!   enforces the TVD bounds locally
-// *****************************************************************************
-{
-  using inciter::densityIdx;
-  using inciter::energyIdx;
-  using inciter::densityDofIdx;
-  using inciter::energyDofIdx;
-
-  if (er < 0) Throw("safe limiting cannot be called for boundary cells");
-
-  auto eR = static_cast< std::size_t >(er);
-
-  // define a lambda for the safe limiting
-  auto safeLimit = [&]( std::size_t c, real ul, real ur )
-  {
-    // find min/max at the face
-    auto uMin = std::min(ul, ur);
-    auto uMax = std::max(ul, ur);
-
-    // left-state limiting
-    state[0][c] = std::min(uMax, std::max(uMin, state[0][c]));
-
-    // right-state limiting
-    state[1][c] = std::min(uMax, std::max(uMin, state[1][c]));
-  };
-
-  for (std::size_t k=0; k<nmat; ++k)
-  {
-    real ul(0.0), ur(0.0);
-
-    // Density
-    // establish left- and right-hand states
-    ul = U(el, densityDofIdx(nmat, k, rdof, 0));
-    ur = U(eR, densityDofIdx(nmat, k, rdof, 0));
-
-    // limit reconstructed density
-    safeLimit(densityIdx(nmat,k), ul, ur);
-
-    // Energy
-    // establish left- and right-hand states
-    ul = U(el, energyDofIdx(nmat, k, rdof, 0));
-    ur = U(eR, energyDofIdx(nmat, k, rdof, 0));
-
-    // limit reconstructed energy
-    safeLimit(energyIdx(nmat,k), ul, ur);
-  }
-}
-
-} // tk::
+        auto enc = mb.template get< tag::energy_content >();
+        Assert( enc > 0.0, "Box energy content must be nonzero" );
+        const auto& x0_front = mb.template get< tag::point >();
+        Assert(x0_front.size()==3, "Incorrectly sized front initial location");
+        auto blkmatid = mb.template get< tag::materialid >();
+
+        // determine times at which sourcing is initialized and terminated
+        auto v_front = mb.template get< tag::front_speed >();
+        auto w_front = mb.template get< tag::front_width >();
+        auto tInit = mb.template get< tag::init_time >();
+
+        if (t >= tInit) {
+          // current radius of front
+          tk::real r_front = v_front * (t-tInit);
+          // arbitrary shape form
+          auto amplE = enc * v_front / w_front;
+
+          for (auto e : blkelems) {
+            std::array< tk::real, 3 > node{{ geoElem(e,1), geoElem(e,2),
+              geoElem(e,3) }};
+
+            auto r_e = std::sqrt(
+              (node[0]-x0_front[0])*(node[0]-x0_front[0]) +
+              (node[1]-x0_front[1])*(node[1]-x0_front[1]) +
+              (node[2]-x0_front[2])*(node[2]-x0_front[2]) );
+
+            // if element centroid lies within spherical shell add sources
+            if (r_e >= r_front && r_e <= r_front+w_front) {
+              // Add the source term to the rhs
+              R(e, energyDofIdx(nmat,blkmatid-1,1,0)) += geoElem(e,0) * amplE;
+              engSrcAdded[e] = 1;
+            }
+          }
+        }
+
+      }
+    }
+  }
+}
 
diff --git a/Release/cppcheck/74.html b/Release/cppcheck/74.html index a05eedfe6139..209fb26f128a 100644 --- a/Release/cppcheck/74.html +++ b/Release/cppcheck/74.html @@ -152,183 +152,2531 @@
- - + diff --git a/Release/test_coverage/Base/Vector.hpp.func.html b/Release/test_coverage/Base/Vector.hpp.func.html index 74cf58e8c602..2b9afc25e84e 100644 --- a/Release/test_coverage/Base/Vector.hpp.func.html +++ b/Release/test_coverage/Base/Vector.hpp.func.html @@ -27,13 +27,13 @@ - + - + - + @@ -52,9 +52,9 @@ - - - + + +
 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
-10
-11
-12
-13
-14
-15
-16
-17
-18
-19
-20
-21
-22
-23
-24
-25
-26
-27
-28
-29
-30
-31
-32
-33
-34
-35
-36
-37
-38
-39
-40
-41
-42
-43
-44
-45
-46
-47
-48
-49
-50
-51
-52
-53
-54
-55
-56
-57
-58
-59
-60
-61
-62
-63
-64
-65
-66
-67
-68
-69
-70
-71
-72
-73
-74
-75
-76
-77
-78
-79
-80
-81
-82
-83
-84
-85
// *****************************************************************************
+
   1
+   2
+   3
+   4
+   5
+   6
+   7
+   8
+   9
+  10
+  11
+  12
+  13
+  14
+  15
+  16
+  17
+  18
+  19
+  20
+  21
+  22
+  23
+  24
+  25
+  26
+  27
+  28
+  29
+  30
+  31
+  32
+  33
+  34
+  35
+  36
+  37
+  38
+  39
+  40
+  41
+  42
+  43
+  44
+  45
+  46
+  47
+  48
+  49
+  50
+  51
+  52
+  53
+  54
+  55
+  56
+  57
+  58
+  59
+  60
+  61
+  62
+  63
+  64
+  65
+  66
+  67
+  68
+  69
+  70
+  71
+  72
+  73
+  74
+  75
+  76
+  77
+  78
+  79
+  80
+  81
+  82
+  83
+  84
+  85
+  86
+  87
+  88
+  89
+  90
+  91
+  92
+  93
+  94
+  95
+  96
+  97
+  98
+  99
+ 100
+ 101
+ 102
+ 103
+ 104
+ 105
+ 106
+ 107
+ 108
+ 109
+ 110
+ 111
+ 112
+ 113
+ 114
+ 115
+ 116
+ 117
+ 118
+ 119
+ 120
+ 121
+ 122
+ 123
+ 124
+ 125
+ 126
+ 127
+ 128
+ 129
+ 130
+ 131
+ 132
+ 133
+ 134
+ 135
+ 136
+ 137
+ 138
+ 139
+ 140
+ 141
+ 142
+ 143
+ 144
+ 145
+ 146
+ 147
+ 148
+ 149
+ 150
+ 151
+ 152
+ 153
+ 154
+ 155
+ 156
+ 157
+ 158
+ 159
+ 160
+ 161
+ 162
+ 163
+ 164
+ 165
+ 166
+ 167
+ 168
+ 169
+ 170
+ 171
+ 172
+ 173
+ 174
+ 175
+ 176
+ 177
+ 178
+ 179
+ 180
+ 181
+ 182
+ 183
+ 184
+ 185
+ 186
+ 187
+ 188
+ 189
+ 190
+ 191
+ 192
+ 193
+ 194
+ 195
+ 196
+ 197
+ 198
+ 199
+ 200
+ 201
+ 202
+ 203
+ 204
+ 205
+ 206
+ 207
+ 208
+ 209
+ 210
+ 211
+ 212
+ 213
+ 214
+ 215
+ 216
+ 217
+ 218
+ 219
+ 220
+ 221
+ 222
+ 223
+ 224
+ 225
+ 226
+ 227
+ 228
+ 229
+ 230
+ 231
+ 232
+ 233
+ 234
+ 235
+ 236
+ 237
+ 238
+ 239
+ 240
+ 241
+ 242
+ 243
+ 244
+ 245
+ 246
+ 247
+ 248
+ 249
+ 250
+ 251
+ 252
+ 253
+ 254
+ 255
+ 256
+ 257
+ 258
+ 259
+ 260
+ 261
+ 262
+ 263
+ 264
+ 265
+ 266
+ 267
+ 268
+ 269
+ 270
+ 271
+ 272
+ 273
+ 274
+ 275
+ 276
+ 277
+ 278
+ 279
+ 280
+ 281
+ 282
+ 283
+ 284
+ 285
+ 286
+ 287
+ 288
+ 289
+ 290
+ 291
+ 292
+ 293
+ 294
+ 295
+ 296
+ 297
+ 298
+ 299
+ 300
+ 301
+ 302
+ 303
+ 304
+ 305
+ 306
+ 307
+ 308
+ 309
+ 310
+ 311
+ 312
+ 313
+ 314
+ 315
+ 316
+ 317
+ 318
+ 319
+ 320
+ 321
+ 322
+ 323
+ 324
+ 325
+ 326
+ 327
+ 328
+ 329
+ 330
+ 331
+ 332
+ 333
+ 334
+ 335
+ 336
+ 337
+ 338
+ 339
+ 340
+ 341
+ 342
+ 343
+ 344
+ 345
+ 346
+ 347
+ 348
+ 349
+ 350
+ 351
+ 352
+ 353
+ 354
+ 355
+ 356
+ 357
+ 358
+ 359
+ 360
+ 361
+ 362
+ 363
+ 364
+ 365
+ 366
+ 367
+ 368
+ 369
+ 370
+ 371
+ 372
+ 373
+ 374
+ 375
+ 376
+ 377
+ 378
+ 379
+ 380
+ 381
+ 382
+ 383
+ 384
+ 385
+ 386
+ 387
+ 388
+ 389
+ 390
+ 391
+ 392
+ 393
+ 394
+ 395
+ 396
+ 397
+ 398
+ 399
+ 400
+ 401
+ 402
+ 403
+ 404
+ 405
+ 406
+ 407
+ 408
+ 409
+ 410
+ 411
+ 412
+ 413
+ 414
+ 415
+ 416
+ 417
+ 418
+ 419
+ 420
+ 421
+ 422
+ 423
+ 424
+ 425
+ 426
+ 427
+ 428
+ 429
+ 430
+ 431
+ 432
+ 433
+ 434
+ 435
+ 436
+ 437
+ 438
+ 439
+ 440
+ 441
+ 442
+ 443
+ 444
+ 445
+ 446
+ 447
+ 448
+ 449
+ 450
+ 451
+ 452
+ 453
+ 454
+ 455
+ 456
+ 457
+ 458
+ 459
+ 460
+ 461
+ 462
+ 463
+ 464
+ 465
+ 466
+ 467
+ 468
+ 469
+ 470
+ 471
+ 472
+ 473
+ 474
+ 475
+ 476
+ 477
+ 478
+ 479
+ 480
+ 481
+ 482
+ 483
+ 484
+ 485
+ 486
+ 487
+ 488
+ 489
+ 490
+ 491
+ 492
+ 493
+ 494
+ 495
+ 496
+ 497
+ 498
+ 499
+ 500
+ 501
+ 502
+ 503
+ 504
+ 505
+ 506
+ 507
+ 508
+ 509
+ 510
+ 511
+ 512
+ 513
+ 514
+ 515
+ 516
+ 517
+ 518
+ 519
+ 520
+ 521
+ 522
+ 523
+ 524
+ 525
+ 526
+ 527
+ 528
+ 529
+ 530
+ 531
+ 532
+ 533
+ 534
+ 535
+ 536
+ 537
+ 538
+ 539
+ 540
+ 541
+ 542
+ 543
+ 544
+ 545
+ 546
+ 547
+ 548
+ 549
+ 550
+ 551
+ 552
+ 553
+ 554
+ 555
+ 556
+ 557
+ 558
+ 559
+ 560
+ 561
+ 562
+ 563
+ 564
+ 565
+ 566
+ 567
+ 568
+ 569
+ 570
+ 571
+ 572
+ 573
+ 574
+ 575
+ 576
+ 577
+ 578
+ 579
+ 580
+ 581
+ 582
+ 583
+ 584
+ 585
+ 586
+ 587
+ 588
+ 589
+ 590
+ 591
+ 592
+ 593
+ 594
+ 595
+ 596
+ 597
+ 598
+ 599
+ 600
+ 601
+ 602
+ 603
+ 604
+ 605
+ 606
+ 607
+ 608
+ 609
+ 610
+ 611
+ 612
+ 613
+ 614
+ 615
+ 616
+ 617
+ 618
+ 619
+ 620
+ 621
+ 622
+ 623
+ 624
+ 625
+ 626
+ 627
+ 628
+ 629
+ 630
+ 631
+ 632
+ 633
+ 634
+ 635
+ 636
+ 637
+ 638
+ 639
+ 640
+ 641
+ 642
+ 643
+ 644
+ 645
+ 646
+ 647
+ 648
+ 649
+ 650
+ 651
+ 652
+ 653
+ 654
+ 655
+ 656
+ 657
+ 658
+ 659
+ 660
+ 661
+ 662
+ 663
+ 664
+ 665
+ 666
+ 667
+ 668
+ 669
+ 670
+ 671
+ 672
+ 673
+ 674
+ 675
+ 676
+ 677
+ 678
+ 679
+ 680
+ 681
+ 682
+ 683
+ 684
+ 685
+ 686
+ 687
+ 688
+ 689
+ 690
+ 691
+ 692
+ 693
+ 694
+ 695
+ 696
+ 697
+ 698
+ 699
+ 700
+ 701
+ 702
+ 703
+ 704
+ 705
+ 706
+ 707
+ 708
+ 709
+ 710
+ 711
+ 712
+ 713
+ 714
+ 715
+ 716
+ 717
+ 718
+ 719
+ 720
+ 721
+ 722
+ 723
+ 724
+ 725
+ 726
+ 727
+ 728
+ 729
+ 730
+ 731
+ 732
+ 733
+ 734
+ 735
+ 736
+ 737
+ 738
+ 739
+ 740
+ 741
+ 742
+ 743
+ 744
+ 745
+ 746
+ 747
+ 748
+ 749
+ 750
+ 751
+ 752
+ 753
+ 754
+ 755
+ 756
+ 757
+ 758
+ 759
+ 760
+ 761
+ 762
+ 763
+ 764
+ 765
+ 766
+ 767
+ 768
+ 769
+ 770
+ 771
+ 772
+ 773
+ 774
+ 775
+ 776
+ 777
+ 778
+ 779
+ 780
+ 781
+ 782
+ 783
+ 784
+ 785
+ 786
+ 787
+ 788
+ 789
+ 790
+ 791
+ 792
+ 793
+ 794
+ 795
+ 796
+ 797
+ 798
+ 799
+ 800
+ 801
+ 802
+ 803
+ 804
+ 805
+ 806
+ 807
+ 808
+ 809
+ 810
+ 811
+ 812
+ 813
+ 814
+ 815
+ 816
+ 817
+ 818
+ 819
+ 820
+ 821
+ 822
+ 823
+ 824
+ 825
+ 826
+ 827
+ 828
+ 829
+ 830
+ 831
+ 832
+ 833
+ 834
+ 835
+ 836
+ 837
+ 838
+ 839
+ 840
+ 841
+ 842
+ 843
+ 844
+ 845
+ 846
+ 847
+ 848
+ 849
+ 850
+ 851
+ 852
+ 853
+ 854
+ 855
+ 856
+ 857
+ 858
+ 859
+ 860
+ 861
+ 862
+ 863
+ 864
+ 865
+ 866
+ 867
+ 868
+ 869
+ 870
+ 871
+ 872
+ 873
+ 874
+ 875
+ 876
+ 877
+ 878
+ 879
+ 880
+ 881
+ 882
+ 883
+ 884
+ 885
+ 886
+ 887
+ 888
+ 889
+ 890
+ 891
+ 892
+ 893
+ 894
+ 895
+ 896
+ 897
+ 898
+ 899
+ 900
+ 901
+ 902
+ 903
+ 904
+ 905
+ 906
+ 907
+ 908
+ 909
+ 910
+ 911
+ 912
+ 913
+ 914
+ 915
+ 916
+ 917
+ 918
+ 919
+ 920
+ 921
+ 922
+ 923
+ 924
+ 925
+ 926
+ 927
+ 928
+ 929
+ 930
+ 931
+ 932
+ 933
+ 934
+ 935
+ 936
+ 937
+ 938
+ 939
+ 940
+ 941
+ 942
+ 943
+ 944
+ 945
+ 946
+ 947
+ 948
+ 949
+ 950
+ 951
+ 952
+ 953
+ 954
+ 955
+ 956
+ 957
+ 958
+ 959
+ 960
+ 961
+ 962
+ 963
+ 964
+ 965
+ 966
+ 967
+ 968
+ 969
+ 970
+ 971
+ 972
+ 973
+ 974
+ 975
+ 976
+ 977
+ 978
+ 979
+ 980
+ 981
+ 982
+ 983
+ 984
+ 985
+ 986
+ 987
+ 988
+ 989
+ 990
+ 991
+ 992
+ 993
+ 994
+ 995
+ 996
+ 997
+ 998
+ 999
+1000
+1001
+1002
+1003
+1004
+1005
+1006
+1007
+1008
+1009
+1010
+1011
+1012
+1013
+1014
+1015
+1016
+1017
+1018
+1019
+1020
+1021
+1022
+1023
+1024
+1025
+1026
+1027
+1028
+1029
+1030
+1031
+1032
+1033
+1034
+1035
+1036
+1037
+1038
+1039
+1040
+1041
+1042
+1043
+1044
+1045
+1046
+1047
+1048
+1049
+1050
+1051
+1052
+1053
+1054
+1055
+1056
+1057
+1058
+1059
+1060
+1061
+1062
+1063
+1064
+1065
+1066
+1067
+1068
+1069
+1070
+1071
+1072
+1073
+1074
+1075
+1076
+1077
+1078
+1079
+1080
+1081
+1082
+1083
+1084
+1085
+1086
+1087
+1088
+1089
+1090
+1091
+1092
+1093
+1094
+1095
+1096
+1097
+1098
+1099
+1100
+1101
+1102
+1103
+1104
+1105
+1106
+1107
+1108
+1109
+1110
+1111
+1112
+1113
+1114
+1115
+1116
+1117
+1118
+1119
+1120
+1121
+1122
+1123
+1124
+1125
+1126
+1127
+1128
+1129
+1130
+1131
+1132
+1133
+1134
+1135
+1136
+1137
+1138
+1139
+1140
+1141
+1142
+1143
+1144
+1145
+1146
+1147
+1148
+1149
+1150
+1151
+1152
+1153
+1154
+1155
+1156
+1157
+1158
+1159
+1160
+1161
+1162
+1163
+1164
+1165
+1166
+1167
+1168
+1169
+1170
+1171
+1172
+1173
+1174
+1175
+1176
+1177
+1178
+1179
+1180
+1181
+1182
+1183
+1184
+1185
+1186
+1187
+1188
+1189
+1190
+1191
+1192
+1193
+1194
+1195
+1196
+1197
+1198
+1199
+1200
+1201
+1202
+1203
+1204
+1205
+1206
+1207
+1208
+1209
+1210
+1211
+1212
+1213
+1214
+1215
+1216
+1217
+1218
+1219
+1220
+1221
+1222
+1223
+1224
+1225
+1226
+1227
+1228
+1229
+1230
+1231
+1232
+1233
+1234
+1235
+1236
+1237
+1238
+1239
+1240
+1241
+1242
+1243
+1244
+1245
+1246
+1247
+1248
+1249
+1250
+1251
+1252
+1253
+1254
+1255
+1256
+1257
+1258
+1259
// *****************************************************************************
 /*!
-  \file      src/PDE/Transport/Problem/CylVortex.cpp
+  \file      src/PDE/Reconstruction.cpp
   \copyright 2012-2015 J. Bakosi,
              2016-2018 Los Alamos National Security, LLC.,
              2019-2021 Triad National Security, LLC.
              All rights reserved. See the LICENSE file for details.
-  \brief     Problem configuration for transport equations
-  \details   This file defines a Problem policy class for the transport
-    equations, defined in PDE/Transport/CGTransport.hpp implementing
-    node-centered continuous Galerkin (CG) and PDE/Transport/DGTransport.hpp
-    implementing cell-centered discontinuous Galerkin (DG) discretizations.
-    See PDE/Transport/Problem.hpp for general requirements on Problem policy
-    classes for cg::Transport and dg::Transport.
-*/
-// *****************************************************************************
-
-#include "CylVortex.hpp"
+  \brief     Reconstruction for reconstructed discontinuous Galerkin methods
+  \details   This file contains functions that reconstruct an "n"th order
+    polynomial to an "n+1"th order polynomial using a least-squares
+    reconstruction procedure.
+*/
+// *****************************************************************************
+
+#include <array>
+#include <vector>
+#include <iostream>
+#include <iomanip>
 
-using inciter::TransportProblemCylVortex;
-
-std::vector< tk::real >
-TransportProblemCylVortex::initialize( ncomp_t ncomp,
-                                       const std::vector< EOS >&,
-                                       tk::real x, tk::real y, tk::real,
-                                       tk::real t )
-// *****************************************************************************
-//  Evaluate initial solution at (x,y,t) for all components
-//! \param[in] ncomp Number of components in this transport equation system
-//! \param[in] x X coordinate where to evaluate the solution
-//! \param[in] y Y coordinate where to evaluate the solution
-//! \param[in] t Time where to evaluate the solution
-//! \return Values of all components evaluated at (x,y,t=0)
-//! \details This function only gives the initial condition for the cylinder,
-//!   and not the solution at any time t>0.
-// *****************************************************************************
-{
-  const auto vel = prescribedVelocity( ncomp, x, y, 0.0, t );<--- Variable 'vel' is assigned a value that is never used.
-
-  if (ncomp != 4) Throw("Cylinder deformation in vortex is only set up for 4 "
-    "components");
-
-  std::vector< tk::real > s( ncomp, 0.0 );
-
-  // center of the cylinder
-  auto x0 = 0.5;
-  auto y0 = 0.75;
-  auto r = sqrt((x-x0)*(x-x0) + (y-y0)*(y-y0));
-
-  if (r<=0.15) {
-    if (x<x0 && y>=y0) s[0] = 1.0;
-    else if (x>=x0 && y>=y0) s[1] = 1.0;
-    else if (x>=x0 && y<y0) s[2] = 1.0;
-    else if (x<x0 && y<y0) s[3] = 1.0;
-  }
+#include "Vector.hpp"
+#include "Around.hpp"
+#include "Base/HashMapReducer.hpp"
+#include "Reconstruction.hpp"
+#include "MultiMat/MultiMatIndexing.hpp"
+#include "Inciter/InputDeck/InputDeck.hpp"
+#include "Limiter.hpp"
+
+namespace inciter {
+extern ctr::InputDeck g_inputdeck;
+}
+
+namespace tk {
+
+void
+lhsLeastSq_P0P1( const inciter::FaceData& fd,
+                 const Fields& geoElem,
+                 const Fields& geoFace,
+                 std::vector< std::array< std::array< real, 3 >, 3 > >& lhs_ls )
+// *****************************************************************************
+//  Compute lhs matrix for the least-squares reconstruction
+//! \param[in] fd Face connectivity and boundary conditions object
+//! \param[in] geoElem Element geometry array
+//! \param[in] geoFace Face geometry array
+//! \param[in,out] lhs_ls LHS reconstruction matrix
+//! \details This function computing the lhs matrix for reconstruction, is
+//!   common for primitive and conserved quantities.
+// *****************************************************************************
+{
+  const auto& esuf = fd.Esuf();
+  const auto nelem = fd.Esuel().size()/4;
+
+  // Compute internal and boundary face contributions
+  for (std::size_t f=0; f<esuf.size()/2; ++f)
+  {
+    Assert( esuf[2*f] > -1, "Left-side element detected as -1" );
 
-  return s;
-}
+    auto el = static_cast< std::size_t >(esuf[2*f]);
+    auto er = esuf[2*f+1];
 
-std::vector< std::array< tk::real, 3 > >
-TransportProblemCylVortex::prescribedVelocity( ncomp_t ncomp,
-  tk::real x, tk::real y, tk::real, tk::real t )
-// *****************************************************************************
-//! Assign prescribed velocity at a point
-//! \param[in] ncomp Number of components in this transport equation
-//! \param[in] x x coordinate at which to assign velocity
-//! \param[in] y y coordinate at which to assign velocity
-//! \param[in] t time at which to assign velocity
-//! \return Velocity assigned to all vertices of a tetrehedron, size:
-//!   ncomp * ndim = [ncomp][3]
-// *****************************************************************************
-{
-  std::vector< std::array< tk::real, 3 > > vel( ncomp );
-
-  auto pi = 4.0 * std::atan(1.0);
-  for (ncomp_t c=0; c<ncomp; ++c) {
-    vel[c][0] = - 2.0*std::cos(t*pi/4.0) * std::pow(std::sin(pi*x), 2)
-      * std::sin(pi*y) * std::cos(pi*y);
-    vel[c][1] = 2.0*std::cos(t*pi/4.0) * std::pow(std::sin(pi*y), 2)
-      * std::sin(pi*x) * std::cos(pi*x);
-    vel[c][2] = 0.0;
-  }
-
-  return vel;
-}
+    std::array< real, 3 > geoElemR;
+    std::size_t eR(0);
+
+    // A second-order (piecewise linear) solution polynomial can be obtained
+    // from the first-order (piecewise constant) FV solutions by using a
+    // least-squares (LS) reconstruction process. LS uses the first-order
+    // solutions from the cell being processed, and the cells surrounding it.
+    // The LS system is obtaining by requiring the following to hold:
+    // 'Taylor expansions of solution from cell-i to the centroids of each of
+    // its neighboring cells should be equal to the cell average solution on
+    // that neighbor cell.'
+    // This gives a system of equations for the three second-order DOFs that are
+    // to be determined. In 3D tetrahedral meshes, this would give four
+    // equations (one for each neighbor )for the three unknown DOFs. This
+    // overdetermined system is solved in the least-squares sense using the
+    // normal equations approach. The normal equations approach involves
+    // pre-multiplying the overdetermined system by the transpose of the system
+    // matrix to obtain a square matrix (3x3 in this case).
+
+    // get a 3x3 system by applying the normal equation approach to the
+    // least-squares overdetermined system
+
+    if (er > -1) {
+    // internal face contribution
+      eR = static_cast< std::size_t >(er);
+      // Put in cell-centroid coordinates
+      geoElemR = {{ geoElem(eR,1), geoElem(eR,2), geoElem(eR,3) }};
+    }
+    else {
+    // boundary face contribution
+      // Put in face-centroid coordinates
+      geoElemR = {{ geoFace(f,4), geoFace(f,5), geoFace(f,6) }};
+    }
+
+    std::array< real, 3 > wdeltax{{ geoElemR[0]-geoElem(el,1),
+                                    geoElemR[1]-geoElem(el,2),
+                                    geoElemR[2]-geoElem(el,3) }};
+
+    // define a lambda for contributing to lhs matrix
+    auto lhs = [&]( std::size_t e ){
+    for (std::size_t idir=0; idir<3; ++idir)
+      for (std::size_t jdir=0; jdir<3; ++jdir)
+        lhs_ls[e][idir][jdir] += wdeltax[idir] * wdeltax[jdir];
+    };
+
+    // always add left element contribution (at a boundary face, the internal
+    // element is always the left element)
+    lhs(el);
+    // add right element contribution for internal faces only
+    if (er > -1)
+      if (eR < nelem) lhs(eR);
+
+  }
+}
+
+void
+intLeastSq_P0P1( const std::size_t rdof,
+                 const inciter::FaceData& fd,
+                 const Fields& geoElem,
+                 const Fields& W,
+                 std::vector< std::vector< std::array< real, 3 > > >& rhs_ls,
+                 const std::vector< std::size_t >& varList )
+// *****************************************************************************
+//  \brief Compute internal surface contributions to rhs vector of the
+//    least-squares reconstruction
+//! \param[in] rdof Maximum number of reconstructed degrees of freedom
+//! \param[in] fd Face connectivity and boundary conditions object
+//! \param[in] geoElem Element geometry array
+//! \param[in] W Solution vector to be reconstructed at recent time step
+//! \param[in,out] rhs_ls RHS reconstruction vector
+//! \param[in] varList List of indices in W, that need to be reconstructed
+//! \details This function computing the internal face contributions to the rhs
+//!   vector for reconstruction, is common for primitive and conserved
+//!   quantities. If `W` == `U`, compute internal face contributions for the
+//!   conserved variables. If `W` == `P`, compute internal face contributions
+//!   for the primitive variables.
+// *****************************************************************************
+{
+  const auto& esuf = fd.Esuf();
+  const auto nelem = fd.Esuel().size()/4;<--- Variable 'nelem' is assigned a value that is never used.
+
+  // Compute internal face contributions
+  for (auto f=fd.Nbfac(); f<esuf.size()/2; ++f)
+  {
+    Assert( esuf[2*f] > -1 && esuf[2*f+1] > -1, "Interior element detected "
+            "as -1" );
+
+    auto el = static_cast< std::size_t >(esuf[2*f]);
+    auto er = static_cast< std::size_t >(esuf[2*f+1]);
+
+    // get a 3x3 system by applying the normal equation approach to the
+    // least-squares overdetermined system
+
+    // 'wdeltax' is the distance vector between the centroids of this element
+    // and its neighbor
+    std::array< real, 3 > wdeltax{{ geoElem(er,1)-geoElem(el,1),
+                                    geoElem(er,2)-geoElem(el,2),
+                                    geoElem(er,3)-geoElem(el,3) }};
+
+    for (std::size_t idir=0; idir<3; ++idir)
+    {
+      // rhs vector
+      for (std::size_t i=0; i<varList.size(); ++i)
+      {
+        auto c = varList[i];
+        auto mark = c*rdof;
+        rhs_ls[el][c][idir] +=
+          wdeltax[idir] * (W(er,mark)-W(el,mark));
+        if (er < nelem)
+          rhs_ls[er][c][idir] +=
+            wdeltax[idir] * (W(er,mark)-W(el,mark));
+      }
+    }
+  }
+}
+
+void
+bndLeastSqConservedVar_P0P1(
+  ncomp_t ncomp,
+  const std::vector< inciter::EOS >& mat_blk,
+  std::size_t rdof,
+  const std::vector< std::size_t >& bcconfig,
+  const inciter::FaceData& fd,
+  const Fields& geoFace,
+  const Fields& geoElem,
+  real t,
+  const StateFn& state,
+  const Fields& P,
+  const Fields& U,
+  std::vector< std::vector< std::array< real, 3 > > >& rhs_ls,
+  const std::vector< std::size_t >& varList,
+  std::size_t nprim )
+// *****************************************************************************
+//  \brief Compute boundary surface contributions to rhs vector of the
+//    least-squares reconstruction of conserved quantities of the PDE system
+//! \param[in] ncomp Number of scalar components in this PDE system
+//! \param[in] mat_blk EOS material block
+//! \param[in] rdof Maximum number of reconstructed degrees of freedom
+//! \param[in] bcconfig BC configuration vector for multiple side sets
+//! \param[in] fd Face connectivity and boundary conditions object
+//! \param[in] geoFace Face geometry array
+//! \param[in] geoElem Element geometry array
+//! \param[in] t Physical time
+//! \param[in] state Function to evaluate the left and right solution state at
+//!   boundaries
+//! \param[in] P Primitive vector to be reconstructed at recent time step
+//! \param[in] U Solution vector to be reconstructed at recent time step
+//! \param[in,out] rhs_ls RHS reconstruction vector
+//! \param[in] varList List of indices in W, that need to be reconstructed
+//! \param[in] nprim This is the number of primitive quantities stored for this
+//!   PDE system. This is necessary to extend the state vector to the right
+//!   size, so that correct boundary conditions are obtained.
+//!   A default is set to 0, so that calling code for systems that do not store
+//!   primitive quantities does not need to specify this argument.
+//! \details This function computing the boundary face contributions to the rhs
+//!   vector for reconstruction, is used for conserved quantities only.
+// *****************************************************************************
+{
+  const auto& bface = fd.Bface();
+  const auto& esuf = fd.Esuf();
+
+  for (const auto& s : bcconfig) {       // for all bc sidesets
+    auto bc = bface.find(static_cast<int>(s));// faces for side set
+    if (bc != end(bface))
+    {
+      // Compute boundary face contributions
+      for (const auto& f : bc->second)
+      {
+        Assert( esuf[2*f+1] == -1, "physical boundary element not -1" );
+
+        std::size_t el = static_cast< std::size_t >(esuf[2*f]);
+
+        // arrays for quadrature points
+        std::array< real, 3 >
+          fc{{ geoFace(f,4), geoFace(f,5), geoFace(f,6) }};
+        std::array< real, 3 >
+          fn{{ geoFace(f,1), geoFace(f,2), geoFace(f,3) }};
+
+        // Compute the state variables at the left element
+        std::vector< real >B(1,1.0);
+        auto ul = eval_state( ncomp, rdof, 1, el, U, B );
+        auto uprim = eval_state( nprim, rdof, 1, el, P, B );
+
+        // consolidate primitives into state vector
+        ul.insert(ul.end(), uprim.begin(), uprim.end());
+
+        Assert( ul.size() == ncomp+nprim, "Incorrect size for "
+                "appended state vector" );
+
+        // Compute the state at the face-center using BC
+        auto ustate = state( ncomp, mat_blk, ul, fc[0], fc[1], fc[2], t, fn );
+
+        std::array< real, 3 > wdeltax{{ fc[0]-geoElem(el,1),
+                                        fc[1]-geoElem(el,2),
+                                        fc[2]-geoElem(el,3) }};
+
+        for (std::size_t idir=0; idir<3; ++idir)
+        {
+          // rhs vector
+          for (std::size_t i=0; i<varList.size(); ++i)
+          {
+            auto c = varList[i];
+            rhs_ls[el][c][idir] +=
+              wdeltax[idir] * (ustate[1][c]-ustate[0][c]);
+          }
+        }
+      }
+    }
+  }
+}
+
+void
+solveLeastSq_P0P1(
+  const std::size_t rdof,
+  const std::vector< std::array< std::array< real, 3 >, 3 > >& lhs,
+  const std::vector< std::vector< std::array< real, 3 > > >& rhs,
+  Fields& W,<--- Parameter 'W' can be declared with const
+  const std::vector< std::size_t >& varList )
+// *****************************************************************************
+//  Solve the 3x3 linear system for least-squares reconstruction
+//! \param[in] rdof Maximum number of reconstructed degrees of freedom
+//! \param[in] lhs LHS reconstruction matrix
+//! \param[in] rhs RHS reconstruction vector
+//! \param[in,out] W Solution vector to be reconstructed at recent time step
+//! \param[in] varList List of indices in W, that need to be reconstructed
+//! \details Solves the 3x3 linear system for each element, individually. For
+//!   systems that require reconstructions of primitive quantities, this should
+//!   be called twice, once with the argument 'W' as U (conserved), and again
+//!   with 'W' as P (primitive).
+// *****************************************************************************
+{
+  auto nelem = lhs.size();
+
+  for (std::size_t e=0; e<nelem; ++e)
+  {
+    for (std::size_t i=0; i<varList.size(); ++i)
+    {
+      auto mark = varList[i]*rdof;
+
+      // solve system using Cramer's rule
+      auto ux = tk::cramer( lhs[e], rhs[e][varList[i]] );
+
+      W(e,mark+1) = ux[0];
+      W(e,mark+2) = ux[1];
+      W(e,mark+3) = ux[2];
+    }
+  }
+}
+
+void
+recoLeastSqExtStencil(
+  std::size_t rdof,
+  std::size_t e,
+  const std::map< std::size_t, std::vector< std::size_t > >& esup,
+  const std::vector< std::size_t >& inpoel,
+  const Fields& geoElem,
+  Fields& W,<--- Parameter 'W' can be declared with const
+  const std::vector< std::size_t >& varList )
+// *****************************************************************************
+//  \brief Reconstruct the second-order solution using least-squares approach
+//    from an extended stencil involving the node-neighbors
+//! \param[in] rdof Maximum number of reconstructed degrees of freedom
+//! \param[in] e Element whoes solution is being reconstructed
+//! \param[in] esup Elements surrounding points
+//! \param[in] inpoel Element-node connectivity
+//! \param[in] geoElem Element geometry array
+//! \param[in,out] W Solution vector to be reconstructed at recent time step
+//! \param[in] varList List of indices in W, that need to be reconstructed
+//! \details A second-order (piecewise linear) solution polynomial is obtained
+//!   from the first-order (piecewise constant) FV solutions by using a
+//!   least-squares (LS) reconstruction process. This LS reconstruction function
+//!   using the nodal-neighbors of a cell, to get an overdetermined system of
+//!   equations for the derivatives of the solution. This overdetermined system
+//!   is solved in the least-squares sense using the normal equations approach.
+// *****************************************************************************
+{
+  // lhs matrix
+  std::array< std::array< tk::real, 3 >, 3 >
+    lhs_ls( {{ {{0.0, 0.0, 0.0}},
+               {{0.0, 0.0, 0.0}},
+               {{0.0, 0.0, 0.0}} }} );
+  // rhs matrix
+  std::vector< std::array< tk::real, 3 > >
+  rhs_ls( varList.size(), {{ 0.0, 0.0, 0.0 }} );
+
+  // loop over all nodes of the element e
+  for (std::size_t lp=0; lp<4; ++lp)
+  {
+    auto p = inpoel[4*e+lp];
+    const auto& pesup = cref_find(esup, p);
+
+    // loop over all the elements surrounding this node p
+    for (auto er : pesup)
+    {
+      // centroid distance
+      std::array< real, 3 > wdeltax{{ geoElem(er,1)-geoElem(e,1),
+                                      geoElem(er,2)-geoElem(e,2),
+                                      geoElem(er,3)-geoElem(e,3) }};
+
+      // contribute to lhs matrix
+      for (std::size_t idir=0; idir<3; ++idir)
+        for (std::size_t jdir=0; jdir<3; ++jdir)
+          lhs_ls[idir][jdir] += wdeltax[idir] * wdeltax[jdir];
+
+      // compute rhs matrix
+      for (std::size_t i=0; i<varList.size(); i++)
+      {
+        auto mark = varList[i]*rdof;
+        for (std::size_t idir=0; idir<3; ++idir)
+          rhs_ls[i][idir] +=
+            wdeltax[idir] * (W(er,mark)-W(e,mark));
+
+      }
+    }
+  }
+
+  // solve least-square normal equation system using Cramer's rule
+  for (std::size_t i=0; i<varList.size(); i++)
+  {
+    auto mark = varList[i]*rdof;
+
+    auto ux = tk::cramer( lhs_ls, rhs_ls[i] );
+
+    // Update the P1 dofs with the reconstructioned gradients.
+    // Since this reconstruction does not affect the cell-averaged solution,
+    // W(e,mark+0) is unchanged.
+    W(e,mark+1) = ux[0];
+    W(e,mark+2) = ux[1];
+    W(e,mark+3) = ux[2];
+  }
+}
+
+void
+transform_P0P1( std::size_t rdof,
+                std::size_t nelem,
+                const std::vector< std::size_t >& inpoel,
+                const UnsMesh::Coords& coord,
+                Fields& W,<--- Parameter 'W' can be declared with const
+                const std::vector< std::size_t >& varList )
+// *****************************************************************************
+//  Transform the reconstructed P1-derivatives to the Dubiner dofs
+//! \param[in] rdof Total number of reconstructed dofs
+//! \param[in] nelem Total number of elements
+//! \param[in] inpoel Element-node connectivity
+//! \param[in] coord Array of nodal coordinates
+//! \param[in,out] W Second-order reconstructed vector which gets transformed to
+//!   the Dubiner reference space
+//! \param[in] varList List of indices in W, that need to be reconstructed
+//! \details Since the DG solution (and the primitive quantities) are assumed to
+//!   be stored in the Dubiner space, this transformation from Taylor
+//!   coefficients to Dubiner coefficients is necessary.
+// *****************************************************************************
+{
+  const auto& cx = coord[0];
+  const auto& cy = coord[1];
+  const auto& cz = coord[2];
+
+  for (std::size_t e=0; e<nelem; ++e)
+  {
+    // Extract the element coordinates
+    std::array< std::array< real, 3>, 4 > coordel {{
+      {{ cx[ inpoel[4*e  ] ], cy[ inpoel[4*e  ] ], cz[ inpoel[4*e  ] ] }},
+      {{ cx[ inpoel[4*e+1] ], cy[ inpoel[4*e+1] ], cz[ inpoel[4*e+1] ] }},
+      {{ cx[ inpoel[4*e+2] ], cy[ inpoel[4*e+2] ], cz[ inpoel[4*e+2] ] }},
+      {{ cx[ inpoel[4*e+3] ], cy[ inpoel[4*e+3] ], cz[ inpoel[4*e+3] ] }}
+    }};
+
+    auto jacInv =
+      tk::inverseJacobian( coordel[0], coordel[1], coordel[2], coordel[3] );
+
+    // Compute the derivatives of basis function for DG(P1)
+    auto dBdx = tk::eval_dBdx_p1( rdof, jacInv );
+
+    for (std::size_t i=0; i<varList.size(); ++i)
+    {
+      auto mark = varList[i]*rdof;
+
+      // solve system using Cramer's rule
+      auto ux = tk::cramer( {{ {{dBdx[0][1], dBdx[0][2], dBdx[0][3]}},
+                               {{dBdx[1][1], dBdx[1][2], dBdx[1][3]}},
+                               {{dBdx[2][1], dBdx[2][2], dBdx[2][3]}} }},
+                            {{ W(e,mark+1),
+                               W(e,mark+2),
+                               W(e,mark+3) }} );
+
+      // replace physical derivatives with transformed dofs
+      W(e,mark+1) = ux[0];
+      W(e,mark+2) = ux[1];
+      W(e,mark+3) = ux[2];
+    }
+  }
+}
+
+void
+THINCReco( std::size_t rdof,
+           std::size_t nmat,
+           std::size_t e,
+           const std::vector< std::size_t >& inpoel,
+           const UnsMesh::Coords& coord,
+           const Fields& geoElem,
+           const std::array< real, 3 >& ref_xp,
+           const Fields& U,
+           const Fields& P,
+           bool intInd,
+           const std::vector< std::size_t >& matInt,
+           [[maybe_unused]] const std::vector< real >& vfmin,
+           [[maybe_unused]] const std::vector< real >& vfmax,
+           std::vector< real >& state )
+// *****************************************************************************
+//  Compute THINC reconstructions at quadrature point for multi-material flows
+//! \param[in] rdof Total number of reconstructed dofs
+//! \param[in] nmat Total number of materials
+//! \param[in] e Element for which interface reconstruction is being calculated
+//! \param[in] inpoel Element-node connectivity
+//! \param[in] coord Array of nodal coordinates
+//! \param[in] geoElem Element geometry array
+//! \param[in] ref_xp Quadrature point in reference space
+//! \param[in] U Solution vector
+//! \param[in] P Vector of primitives
+//! \param[in] intInd Boolean which indicates if the element contains a
+//!   material interface
+//! \param[in] matInt Array indicating which material has an interface
+//! \param[in] vfmin Vector containing min volume fractions for each material
+//!   in this cell
+//! \param[in] vfmax Vector containing max volume fractions for each material
+//!   in this cell
+//! \param[in,out] state Unknown/state vector at quadrature point, modified
+//!   if near interfaces using THINC
+//! \details This function is an interface for the multimat PDEs that use the
+//!   algebraic multi-material THINC reconstruction. This particular function
+//!   should only be called for multimat.
+// *****************************************************************************
+{
+  using inciter::volfracDofIdx;
+  using inciter::densityDofIdx;
+  using inciter::momentumDofIdx;
+  using inciter::energyDofIdx;
+  using inciter::pressureDofIdx;
+  using inciter::velocityDofIdx;
+  using inciter::deformDofIdx;
+  using inciter::stressDofIdx;
+  using inciter::volfracIdx;
+  using inciter::densityIdx;
+  using inciter::momentumIdx;
+  using inciter::energyIdx;
+  using inciter::pressureIdx;
+  using inciter::velocityIdx;
+  using inciter::deformIdx;
+  using inciter::stressIdx;
+
+  auto bparam = inciter::g_inputdeck.get< tag::multimat,
+    tag::intsharp_param >();
+  const auto ncomp = U.nprop()/rdof;
+  const auto& solidx = inciter::g_inputdeck.get< tag::matidxmap,
+    tag::solidx >();
+
+  // Step-1: Perform THINC reconstruction
+  // create a vector of volume-fractions and pass it to the THINC function
+  std::vector< real > alSol(rdof*nmat, 0.0);
+  std::vector< real > alReco(nmat, 0.0);
+  for (std::size_t k=0; k<nmat; ++k) {
+    auto mark = k*rdof;
+    for (std::size_t i=0; i<rdof; ++i) {
+      alSol[mark+i] = U(e, volfracDofIdx(nmat,k,rdof,i));
+    }
+    // initialize with TVD reconstructions which will be modified if near
+    // material interface
+    alReco[k] = state[volfracIdx(nmat,k)];
+  }
+  THINCFunction(rdof, nmat, e, inpoel, coord, ref_xp, geoElem(e,0), bparam,
+    alSol, intInd, matInt, alReco);
+
+  // check reconstructed volfracs for positivity
+  bool neg_vf = false;
+  for (std::size_t k=0; k<nmat; ++k) {
+    if (alReco[k] < 1e-16 && matInt[k] > 0) neg_vf = true;
+  }
+  for (std::size_t k=0; k<nmat; ++k) {
+    if (neg_vf) {
+      std::cout << "Material-id:        " << k << std::endl;
+      std::cout << "Volume-fraction:    " << std::setprecision(18) << alReco[k]
+        << std::endl;
+      std::cout << "Cell-avg vol-frac:  " << std::setprecision(18) <<
+        U(e,volfracDofIdx(nmat,k,rdof,0)) << std::endl;
+      std::cout << "Material-interface? " << intInd << std::endl;
+      std::cout << "Mat-k-involved?     " << matInt[k] << std::endl;
+    }
+  }
+  if (neg_vf) Throw("Material has negative volume fraction after THINC "
+    "reconstruction.");
+
+  // Step-2: Perform consistent reconstruction on other conserved quantities
+  if (intInd)
+  {
+    auto rhobCC(0.0), rhobHO(0.0);
+    for (std::size_t k=0; k<nmat; ++k)
+    {
+      auto alCC = U(e, volfracDofIdx(nmat,k,rdof,0));
+      alCC = std::max(1e-14, alCC);
+
+      if (matInt[k])
+      {
+        state[volfracIdx(nmat,k)] = alReco[k];
+        state[densityIdx(nmat,k)] = alReco[k]
+          * U(e, densityDofIdx(nmat,k,rdof,0))/alCC;
+        state[energyIdx(nmat,k)] = alReco[k]
+          * U(e, energyDofIdx(nmat,k,rdof,0))/alCC;
+        state[ncomp+pressureIdx(nmat,k)] = alReco[k]
+          * P(e, pressureDofIdx(nmat,k,rdof,0))/alCC;
+        if (solidx[k] > 0) {
+          for (std::size_t i=0; i<3; ++i)
+            for (std::size_t j=0; j<3; ++j)
+              state[deformIdx(nmat,solidx[k],i,j)] =
+                U(e, deformDofIdx(nmat,solidx[k],i,j,rdof,0));
+
+          for (std::size_t i=0; i<6; ++i)
+            state[ncomp+stressIdx(nmat,solidx[k],i)] = alReco[k]
+              * P(e, stressDofIdx(nmat,solidx[k],i,rdof,0))/alCC;
+        }
+      }
+
+      rhobCC += U(e, densityDofIdx(nmat,k,rdof,0));
+      rhobHO += state[densityIdx(nmat,k)];
+    }
+
+    // consistent reconstruction for bulk momentum
+    for (std::size_t i=0; i<3; ++i)
+    {
+      state[momentumIdx(nmat,i)] = rhobHO
+        * U(e, momentumDofIdx(nmat,i,rdof,0))/rhobCC;
+      state[ncomp+velocityIdx(nmat,i)] =
+        P(e, velocityDofIdx(nmat,i,rdof,0));
+    }
+  }
+}
+
+void
+THINCRecoTransport( std::size_t rdof,
+                    std::size_t,
+                    std::size_t e,
+                    const std::vector< std::size_t >& inpoel,
+                    const UnsMesh::Coords& coord,
+                    const Fields& geoElem,
+                    const std::array< real, 3 >& ref_xp,
+                    const Fields& U,
+                    const Fields&,
+                    [[maybe_unused]] const std::vector< real >& vfmin,
+                    [[maybe_unused]] const std::vector< real >& vfmax,
+                    std::vector< real >& state )
+// *****************************************************************************
+//  Compute THINC reconstructions at quadrature point for transport
+//! \param[in] rdof Total number of reconstructed dofs
+//! \param[in] e Element for which interface reconstruction is being calculated
+//! \param[in] inpoel Element-node connectivity
+//! \param[in] coord Array of nodal coordinates
+//! \param[in] geoElem Element geometry array
+//! \param[in] ref_xp Quadrature point in reference space
+//! \param[in] U Solution vector
+//! \param[in] vfmin Vector containing min volume fractions for each material
+//!   in this cell
+//! \param[in] vfmax Vector containing max volume fractions for each material
+//!   in this cell
+//! \param[in,out] state Unknown/state vector at quadrature point, modified
+//!   if near interfaces using THINC
+//! \details This function is an interface for the transport PDEs that use the
+//!   algebraic multi-material THINC reconstruction. This particular function
+//!   should only be called for transport.
+// *****************************************************************************
+{
+  auto bparam = inciter::g_inputdeck.get< tag::transport,
+    tag::intsharp_param >();
+  auto ncomp = U.nprop()/rdof;
+
+  // interface detection
+  std::vector< std::size_t > matInt(ncomp, 0);
+  std::vector< tk::real > alAvg(ncomp, 0.0);
+  for (std::size_t k=0; k<ncomp; ++k)
+    alAvg[k] = U(e, k*rdof);
+  auto intInd = inciter::interfaceIndicator(ncomp, alAvg, matInt);
+
+  // create a vector of volume-fractions and pass it to the THINC function
+  std::vector< real > alSol(rdof*ncomp, 0.0);
+  // initialize with TVD reconstructions (modified if near interface)
+  auto alReco = state;
+  for (std::size_t k=0; k<ncomp; ++k) {
+    auto mark = k*rdof;
+    for (std::size_t i=0; i<rdof; ++i) {
+      alSol[mark+i] = U(e,mark+i);
+    }
+  }
+  THINCFunction(rdof, ncomp, e, inpoel, coord, ref_xp, geoElem(e,0), bparam,
+    alSol, intInd, matInt, alReco);
+
+  state = alReco;
+}
+
+void
+THINCFunction( std::size_t rdof,
+               std::size_t nmat,
+               std::size_t e,
+               const std::vector< std::size_t >& inpoel,
+               const UnsMesh::Coords& coord,
+               const std::array< real, 3 >& ref_xp,
+               real vol,
+               real bparam,
+               const std::vector< real >& alSol,
+               bool intInd,
+               const std::vector< std::size_t >& matInt,
+               std::vector< real >& alReco )
+// *****************************************************************************
+//  Old version of the Multi-Medium THINC reconstruction function
+//! \param[in] rdof Total number of reconstructed dofs
+//! \param[in] nmat Total number of materials
+//! \param[in] e Element for which interface reconstruction is being calculated
+//! \param[in] inpoel Element-node connectivity
+//! \param[in] coord Array of nodal coordinates
+//! \param[in] ref_xp Quadrature point in reference space
+//! \param[in] vol Element volume
+//! \param[in] bparam User specified Beta for THINC, from the input file
+//! \param[in] alSol Volume fraction solution vector for element e
+//! \param[in] intInd Interface indicator, true if e is interface element
+//! \param[in] matInt Vector indicating materials which constitute interface
+//! \param[in,out] alReco Unknown/state vector at quadrature point, which gets
+//!   modified if near interface using MM-THINC
+//! \details This function computes the interface reconstruction using the
+//!   algebraic multi-material THINC reconstruction for each material at the
+//!   given (ref_xp) quadrature point. This function is based on the following:
+//!   Pandare A. K., Waltz J., & Bakosi J. (2021) Multi-Material Hydrodynamics
+//!   with Algebraic Sharp Interface Capturing. Computers & Fluids,
+//!   doi: https://doi.org/10.1016/j.compfluid.2020.104804.
+//!   This function will be removed after the newer version (see
+//!   THINCFunction_new) is sufficiently tested.
+// *****************************************************************************
+{
+  // determine number of materials with interfaces in this cell
+  auto epsl(1e-4), epsh(1e-1), bred(1.25), bmod(bparam);
+  std::size_t nIntMat(0);
+  for (std::size_t k=0; k<nmat; ++k)
+  {
+    auto alk = alSol[k*rdof];
+    if (alk > epsl)
+    {
+      ++nIntMat;
+      if ((alk > epsl) && (alk < epsh))
+        bmod = std::min(bmod,
+          (alk-epsl)/(epsh-epsl) * (bred - bparam) + bparam);
+      else if (alk > epsh)
+        bmod = bred;
+    }
+  }
+
+  if (nIntMat > 2) bparam = bmod;
+
+  // compression parameter
+  auto beta = bparam/std::cbrt(6.0*vol);
+
+  if (intInd)
+  {
+    // 1. Get unit normals to material interface
+
+    // Compute Jacobian matrix for converting Dubiner dofs to derivatives
+    const auto& cx = coord[0];
+    const auto& cy = coord[1];
+    const auto& cz = coord[2];
+
+    std::array< std::array< real, 3>, 4 > coordel {{
+      {{ cx[ inpoel[4*e  ] ], cy[ inpoel[4*e  ] ], cz[ inpoel[4*e  ] ] }},
+      {{ cx[ inpoel[4*e+1] ], cy[ inpoel[4*e+1] ], cz[ inpoel[4*e+1] ] }},
+      {{ cx[ inpoel[4*e+2] ], cy[ inpoel[4*e+2] ], cz[ inpoel[4*e+2] ] }},
+      {{ cx[ inpoel[4*e+3] ], cy[ inpoel[4*e+3] ], cz[ inpoel[4*e+3] ] }}
+    }};
+
+    auto jacInv =
+      tk::inverseJacobian( coordel[0], coordel[1], coordel[2], coordel[3] );
+
+    auto dBdx = tk::eval_dBdx_p1( rdof, jacInv );
+
+    std::array< real, 3 > nInt;
+    std::vector< std::array< real, 3 > > ref_n(nmat, {{0.0, 0.0, 0.0}});
+
+    // Get normals
+    for (std::size_t k=0; k<nmat; ++k)
+    {
+      // Get derivatives from moments in Dubiner space
+      for (std::size_t i=0; i<3; ++i)
+        nInt[i] = dBdx[i][1] * alSol[k*rdof+1]
+          + dBdx[i][2] * alSol[k*rdof+2]
+          + dBdx[i][3] * alSol[k*rdof+3];
+
+      auto nMag = std::sqrt(tk::dot(nInt, nInt)) + 1e-14;
+
+      for (std::size_t i=0; i<3; ++i)
+        nInt[i] /= nMag;
+
+      // project interface normal onto local/reference coordinate system
+      for (std::size_t i=0; i<3; ++i)
+      {
+        std::array< real, 3 > axis{
+          coordel[i+1][0]-coordel[0][0],
+          coordel[i+1][1]-coordel[0][1],
+          coordel[i+1][2]-coordel[0][2] };
+        ref_n[k][i] = tk::dot(nInt, axis);
+      }
+    }
+
+    // 2. Reconstruct volume fractions using THINC
+    auto max_lim = 1.0 - (static_cast<tk::real>(nmat-1)*1.0e-12);
+    auto min_lim = 1e-12;
+    auto sum_inter(0.0), sum_non_inter(0.0);
+    for (std::size_t k=0; k<nmat; ++k)
+    {
+      if (matInt[k])
+      {
+        // get location of material interface (volume fraction 0.5) from the
+        // assumed tanh volume fraction distribution, and cell-averaged
+        // volume fraction
+        auto alCC(alSol[k*rdof]);
+        auto Ac(0.0), Bc(0.0), Qc(0.0);
+        if ((std::abs(ref_n[k][0]) > std::abs(ref_n[k][1]))
+          && (std::abs(ref_n[k][0]) > std::abs(ref_n[k][2])))
+        {
+          Ac = std::exp(0.5*beta*ref_n[k][0]);
+          Bc = std::exp(0.5*beta*(ref_n[k][1]+ref_n[k][2]));
+          Qc = std::exp(0.5*beta*ref_n[k][0]*(2.0*alCC-1.0));
+        }
+        else if ((std::abs(ref_n[k][1]) > std::abs(ref_n[k][0]))
+          && (std::abs(ref_n[k][1]) > std::abs(ref_n[k][2])))
+        {
+          Ac = std::exp(0.5*beta*ref_n[k][1]);
+          Bc = std::exp(0.5*beta*(ref_n[k][0]+ref_n[k][2]));
+          Qc = std::exp(0.5*beta*ref_n[k][1]*(2.0*alCC-1.0));
+        }
+        else
+        {
+          Ac = std::exp(0.5*beta*ref_n[k][2]);
+          Bc = std::exp(0.5*beta*(ref_n[k][0]+ref_n[k][1]));
+          Qc = std::exp(0.5*beta*ref_n[k][2]*(2.0*alCC-1.0));
+        }
+        auto d = std::log((1.0-Ac*Qc) / (Ac*Bc*(Qc-Ac))) / (2.0*beta);
+
+        // THINC reconstruction
+        auto al_c = 0.5 * (1.0 + std::tanh(beta*(tk::dot(ref_n[k], ref_xp) + d)));
+
+        alReco[k] = std::min(max_lim, std::max(min_lim, al_c));
+
+        sum_inter += alReco[k];
+      } else
+      {
+        sum_non_inter += alReco[k];
+      }
+      // else, if this material does not have an interface close-by, the TVD
+      // reconstructions must be used for state variables. This is ensured by
+      // initializing the alReco vector as the TVD state.
+    }
+
+    // Rescale volume fractions of interface-materials to ensure unit sum
+    auto sum_rest = 1.0 - sum_non_inter;
+    for (std::size_t k=0; k<nmat; ++k)
+      if(matInt[k])
+        alReco[k] = alReco[k] * sum_rest / sum_inter;
+  }
+}
+
+void
+THINCFunction_new( std::size_t rdof,
+                   std::size_t nmat,
+                   std::size_t e,
+                   const std::vector< std::size_t >& inpoel,
+                   const UnsMesh::Coords& coord,
+                   const std::array< real, 3 >& ref_xp,
+                   real vol,
+                   real bparam,
+                   const std::vector< real >& alSol,
+                   bool intInd,
+                   const std::vector< std::size_t >& matInt,
+                   std::vector< real >& alReco )
+// *****************************************************************************
+//  New Multi-Medium THINC reconstruction function for volume fractions
+//! \param[in] rdof Total number of reconstructed dofs
+//! \param[in] nmat Total number of materials
+//! \param[in] e Element for which interface reconstruction is being calculated
+//! \param[in] inpoel Element-node connectivity
+//! \param[in] coord Array of nodal coordinates
+//! \param[in] ref_xp Quadrature point in reference space
+//! \param[in] vol Element volume
+//! \param[in] bparam User specified Beta for THINC, from the input file
+//! \param[in] alSol Volume fraction solution vector for element e
+//! \param[in] intInd Interface indicator, true if e is interface element
+//! \param[in] matInt Vector indicating materials which constitute interface
+//! \param[in,out] alReco Unknown/state vector at quadrature point, which gets
+//!   modified if near interface using MM-THINC
+//! \details This function computes the interface reconstruction using the
+//!   algebraic multi-material THINC reconstruction for each material at the
+//!   given (ref_xp) quadrature point. This function succeeds the older version
+//!   of the mm-THINC (see THINCFunction), but is still under testing and is
+//!   currently experimental.
+// *****************************************************************************
+{
+  // compression parameter
+  auto beta = bparam/std::cbrt(6.0*vol);
+
+  // If the cell is not material interface, return this function
+  if (not intInd) return;
+
+  // If the cell is material interface, THINC reconstruction is applied
+  // Step 1. Get unit normals to material interface
+  // -------------------------------------------------------------------------
+
+  // Compute Jacobian matrix for converting Dubiner dofs to derivatives
+  const auto& cx = coord[0];
+  const auto& cy = coord[1];
+  const auto& cz = coord[2];
+
+  std::array< std::array< real, 3>, 4 > coordel {{
+    {{ cx[ inpoel[4*e  ] ], cy[ inpoel[4*e  ] ], cz[ inpoel[4*e  ] ] }},
+    {{ cx[ inpoel[4*e+1] ], cy[ inpoel[4*e+1] ], cz[ inpoel[4*e+1] ] }},
+    {{ cx[ inpoel[4*e+2] ], cy[ inpoel[4*e+2] ], cz[ inpoel[4*e+2] ] }},
+    {{ cx[ inpoel[4*e+3] ], cy[ inpoel[4*e+3] ], cz[ inpoel[4*e+3] ] }}
+  }};
+
+  auto jacInv =
+    tk::inverseJacobian( coordel[0], coordel[1], coordel[2], coordel[3] );
+
+  auto dBdx = tk::eval_dBdx_p1( rdof, jacInv );
+
+  std::array< real, 3 > nInt;
+  std::array< real, 3 > ref_n{0.0, 0.0, 0.0};
+  auto almax(0.0);
+  std::size_t kmax(0);
+
+  // Determine index of material present in majority
+  for (std::size_t k=0; k<nmat; ++k)
+  {
+    auto alk = alSol[k*rdof];
+    if (alk > almax)
+    {
+      almax = alk;
+      kmax = k;
+    }
+  }
+
+  // Get normals of material present in majority
+  // Get derivatives from moments in Dubiner space
+  for (std::size_t i=0; i<3; ++i)
+    nInt[i] = dBdx[i][1] * alSol[kmax*rdof+1]
+      + dBdx[i][2] * alSol[kmax*rdof+2]
+      + dBdx[i][3] * alSol[kmax*rdof+3];
+
+  auto nMag = std::sqrt(tk::dot(nInt, nInt)) + 1e-14;
+
+  for (std::size_t i=0; i<3; ++i)
+    nInt[i] /= nMag;
+
+  // project interface normal onto local/reference coordinate system
+  for (std::size_t i=0; i<3; ++i)
+  {
+    std::array< real, 3 > axis{
+      coordel[i+1][0]-coordel[0][0],
+      coordel[i+1][1]-coordel[0][1],
+      coordel[i+1][2]-coordel[0][2] };
+    ref_n[i] = tk::dot(nInt, axis);
+  }
+
+  // Step 2. Reconstruct volume fraction of majority material using THINC
+  // -------------------------------------------------------------------------
+
+  auto al_max = 1.0 - (static_cast<tk::real>(nmat-1)*1.0e-12);
+  auto al_min = 1e-12;
+  auto alsum(0.0);
+  // get location of material interface (volume fraction 0.5) from the
+  // assumed tanh volume fraction distribution, and cell-averaged
+  // volume fraction
+  auto alCC(alSol[kmax*rdof]);
+  auto Ac(0.0), Bc(0.0), Qc(0.0);
+  if ((std::abs(ref_n[0]) > std::abs(ref_n[1]))
+    && (std::abs(ref_n[0]) > std::abs(ref_n[2])))
+  {
+    Ac = std::exp(0.5*beta*ref_n[0]);
+    Bc = std::exp(0.5*beta*(ref_n[1]+ref_n[2]));
+    Qc = std::exp(0.5*beta*ref_n[0]*(2.0*alCC-1.0));
+  }
+  else if ((std::abs(ref_n[1]) > std::abs(ref_n[0]))
+    && (std::abs(ref_n[1]) > std::abs(ref_n[2])))
+  {
+    Ac = std::exp(0.5*beta*ref_n[1]);
+    Bc = std::exp(0.5*beta*(ref_n[0]+ref_n[2]));
+    Qc = std::exp(0.5*beta*ref_n[1]*(2.0*alCC-1.0));
+  }
+  else
+  {
+    Ac = std::exp(0.5*beta*ref_n[2]);
+    Bc = std::exp(0.5*beta*(ref_n[0]+ref_n[1]));
+    Qc = std::exp(0.5*beta*ref_n[2]*(2.0*alCC-1.0));
+  }
+  auto d = std::log((1.0-Ac*Qc) / (Ac*Bc*(Qc-Ac))) / (2.0*beta);
+
+  // THINC reconstruction
+  auto al_c = 0.5 * (1.0 + std::tanh(beta*(tk::dot(ref_n, ref_xp) + d)));
+
+  alReco[kmax] = std::min(al_max, std::max(al_min, al_c));
+  alsum += alReco[kmax];
+
+  // if this material does not have an interface close-by, the TVD
+  // reconstructions must be used for state variables. This is ensured by
+  // initializing the alReco vector as the TVD state.
+  for (std::size_t k=0; k<nmat; ++k) {
+    if (!matInt[k]) {
+      alsum += alReco[k];
+    }
+  }
+
+  // Step 3. Do multimaterial cell corrections
+  // -------------------------------------------------------------------------
+
+  // distribute remaining volume to rest of materials
+  auto sum_left = 1.0 - alsum;
+  real den = 0.0;
+  for (std::size_t k=0; k<nmat; ++k) {
+    if (matInt[k] && k != kmax) {
+      auto mark = k * rdof;
+      alReco[k] = sum_left * alSol[mark];
+      den += alSol[mark];
+    }
+  }
+  // the distributed volfracs might be below al_min, correct that
+  real err = 0.0;
+  for (std::size_t k=0; k<nmat; ++k) {
+    if (matInt[k] && k != kmax) {
+      alReco[k] /= den;
+      if (alReco[k] < al_min) {
+        err += al_min - alReco[k];
+        alReco[k] = al_min;
+      }
+    }
+  }
+
+  // balance out errors
+  alReco[kmax] -= err;
+}
+
+std::vector< tk::real >
+evalPolynomialSol( const std::vector< inciter::EOS >& mat_blk,
+                   int intsharp,
+                   std::size_t ncomp,
+                   std::size_t nprim,
+                   std::size_t rdof,
+                   std::size_t nmat,
+                   std::size_t e,
+                   std::size_t dof_e,
+                   const std::vector< std::size_t >& inpoel,
+                   const UnsMesh::Coords& coord,
+                   const Fields& geoElem,
+                   const std::array< real, 3 >& ref_gp,
+                   const std::vector< real >& B,
+                   const Fields& U,
+                   const Fields& P )
+// *****************************************************************************
+//  Evaluate polynomial solution at quadrature point
+//! \param[in] mat_blk EOS material block
+//! \param[in] intsharp Interface reconstruction indicator
+//! \param[in] ncomp Number of components in the PDE system
+//! \param[in] nprim Number of primitive quantities
+//! \param[in] rdof Total number of reconstructed dofs
+//! \param[in] nmat Total number of materials
+//! \param[in] e Element for which polynomial solution is being evaluated
+//! \param[in] dof_e Degrees of freedom for element
+//! \param[in] inpoel Element-node connectivity
+//! \param[in] coord Array of nodal coordinates
+//! \param[in] geoElem Element geometry array
+//! \param[in] ref_gp Quadrature point in reference space
+//! \param[in] B Basis function at given quadrature point
+//! \param[in] U Solution vector
+//! \param[in] P Vector of primitives
+//! \return High-order unknown/state vector at quadrature point, modified
+//!   if near interfaces using THINC
+// *****************************************************************************
+{
+  std::vector< real > state;
+  std::vector< real > sprim;
+
+  state = eval_state( ncomp, rdof, dof_e, e, U, B );
+  sprim = eval_state( nprim, rdof, dof_e, e, P, B );
+
+  // interface detection
+  std::vector< std::size_t > matInt(nmat, 0);
+  bool intInd(false);
+  if (nmat > 1) {
+    std::vector< tk::real > alAvg(nmat, 0.0);
+    for (std::size_t k=0; k<nmat; ++k)
+      alAvg[k] = U(e, inciter::volfracDofIdx(nmat,k,rdof,0));
+    intInd = inciter::interfaceIndicator(nmat, alAvg, matInt);
+  }
+
+  // consolidate primitives into state vector
+  state.insert(state.end(), sprim.begin(), sprim.end());
+
+  if (intsharp > 0)
+  {
+    std::vector< tk::real > vfmax(nmat, 0.0), vfmin(nmat, 0.0);
+
+    // Until the appropriate setup for activating THINC with Transport
+    // is ready, the following two chunks of code will need to be commented
+    // for using THINC with Transport
+    //for (std::size_t k=0; k<nmat; ++k) {
+    //  vfmin[k] = VolFracMax(el, 2*k, 0);
+    //  vfmax[k] = VolFracMax(el, 2*k+1, 0);
+    //}
+    tk::THINCReco(rdof, nmat, e, inpoel, coord, geoElem,
+      ref_gp, U, P, intInd, matInt, vfmin, vfmax, state);
+
+    // Until the appropriate setup for activating THINC with Transport
+    // is ready, the following lines will need to be uncommented for
+    // using THINC with Transport
+    //tk::THINCRecoTransport(rdof, nmat, el, inpoel, coord,
+    //  geoElem, ref_gp_l, U, P, vfmin, vfmax, state[0]);
+  }
+
+  // physical constraints
+  if (state.size() > ncomp) {
+    using inciter::pressureIdx;
+    using inciter::volfracIdx;
+    using inciter::densityIdx;
+
+    for (std::size_t k=0; k<nmat; ++k) {
+      state[ncomp+pressureIdx(nmat,k)] = constrain_pressure( mat_blk,
+        state[ncomp+pressureIdx(nmat,k)], state[densityIdx(nmat,k)],
+        state[volfracIdx(nmat,k)], k );
+    }
+  }
+
+  return state;
+}
+
+std::vector< tk::real >
+evalFVSol( const std::vector< inciter::EOS >& mat_blk,
+           int intsharp,
+           std::size_t ncomp,
+           std::size_t nprim,
+           std::size_t rdof,
+           std::size_t nmat,
+           std::size_t e,
+           const std::vector< std::size_t >& inpoel,
+           const UnsMesh::Coords& coord,
+           const Fields& geoElem,
+           const std::array< real, 3 >& ref_gp,
+           const std::vector< real >& B,
+           const Fields& U,
+           const Fields& P,
+           int srcFlag )
+// *****************************************************************************
+//  Evaluate second-order FV solution at quadrature point
+//! \param[in] mat_blk EOS material block
+//! \param[in] intsharp Interface reconstruction indicator
+//! \param[in] ncomp Number of components in the PDE system
+//! \param[in] nprim Number of primitive quantities
+//! \param[in] rdof Total number of reconstructed dofs
+//! \param[in] nmat Total number of materials
+//! \param[in] e Element for which polynomial solution is being evaluated
+//! \param[in] inpoel Element-node connectivity
+//! \param[in] coord Array of nodal coordinates
+//! \param[in] geoElem Element geometry array
+//! \param[in] ref_gp Quadrature point in reference space
+//! \param[in] B Basis function at given quadrature point
+//! \param[in] U Solution vector
+//! \param[in] P Vector of primitives
+//! \param[in] srcFlag Whether the energy source was added to element e
+//! \return High-order unknown/state vector at quadrature point, modified
+//!   if near interfaces using THINC
+// *****************************************************************************
+{
+  using inciter::pressureIdx;
+  using inciter::velocityIdx;
+  using inciter::volfracIdx;
+  using inciter::densityIdx;
+  using inciter::energyIdx;
+  using inciter::momentumIdx;
+
+  std::vector< real > state;
+  std::vector< real > sprim;
+
+  state = eval_state( ncomp, rdof, rdof, e, U, B );
+  sprim = eval_state( nprim, rdof, rdof, e, P, B );
+
+  // interface detection so that eos is called on the appropriate quantities
+  std::vector< std::size_t > matInt(nmat, 0);
+  std::vector< tk::real > alAvg(nmat, 0.0);
+  for (std::size_t k=0; k<nmat; ++k)
+    alAvg[k] = U(e, inciter::volfracDofIdx(nmat,k,rdof,0));
+  auto intInd = inciter::interfaceIndicator(nmat, alAvg, matInt);
+
+  // get mat-energy from reconstructed mat-pressure
+  auto rhob(0.0);
+  for (std::size_t k=0; k<nmat; ++k) {
+    auto alk = state[volfracIdx(nmat,k)];
+    if (matInt[k]) {
+      alk = std::max(std::min(alk, 1.0-static_cast<tk::real>(nmat-1)*1e-12),
+        1e-12);
+    }
+    state[energyIdx(nmat,k)] = alk *
+      mat_blk[k].compute< inciter::EOS::totalenergy >(
+      state[densityIdx(nmat,k)]/alk, sprim[velocityIdx(nmat,0)],
+      sprim[velocityIdx(nmat,1)], sprim[velocityIdx(nmat,2)],
+      sprim[pressureIdx(nmat,k)]/alk);
+    rhob += state[densityIdx(nmat,k)];
+  }
+  // get momentum from reconstructed velocity and bulk density
+  for (std::size_t i=0; i<3; ++i) {
+    state[momentumIdx(nmat,i)] = rhob * sprim[velocityIdx(nmat,i)];
+  }
+
+  // consolidate primitives into state vector
+  state.insert(state.end(), sprim.begin(), sprim.end());
+
+  if (intsharp > 0 && srcFlag == 0)
+  {
+    std::vector< tk::real > vfmax(nmat, 0.0), vfmin(nmat, 0.0);
+
+    tk::THINCReco(rdof, nmat, e, inpoel, coord, geoElem,
+      ref_gp, U, P, intInd, matInt, vfmin, vfmax, state);
+  }
+
+  // physical constraints
+  if (state.size() > ncomp) {
+    for (std::size_t k=0; k<nmat; ++k) {
+      state[ncomp+pressureIdx(nmat,k)] = constrain_pressure( mat_blk,
+        state[ncomp+pressureIdx(nmat,k)], state[densityIdx(nmat,k)],
+        state[volfracIdx(nmat,k)], k );
+    }
+  }
+
+  return state;
+}
+
+void
+safeReco( std::size_t rdof,
+          std::size_t nmat,
+          std::size_t el,
+          int er,
+          const Fields& U,
+          std::array< std::vector< real >, 2 >& state )
+// *****************************************************************************
+//  Compute safe reconstructions near material interfaces
+//! \param[in] rdof Total number of reconstructed dofs
+//! \param[in] nmat Total number of material is PDE system
+//! \param[in] el Element on the left-side of face
+//! \param[in] er Element on the right-side of face
+//! \param[in] U Solution vector at recent time-stage
+//! \param[in,out] state Second-order reconstructed state, at cell-face, that
+//!   is being modified for safety
+//! \details When the consistent limiting is applied, there is a possibility
+//!   that the material densities and energies violate TVD bounds. This function
+//!   enforces the TVD bounds locally
+// *****************************************************************************
+{
+  using inciter::densityIdx;
+  using inciter::energyIdx;
+  using inciter::densityDofIdx;
+  using inciter::energyDofIdx;
+
+  if (er < 0) Throw("safe limiting cannot be called for boundary cells");
+
+  auto eR = static_cast< std::size_t >(er);
+
+  // define a lambda for the safe limiting
+  auto safeLimit = [&]( std::size_t c, real ul, real ur )
+  {
+    // find min/max at the face
+    auto uMin = std::min(ul, ur);
+    auto uMax = std::max(ul, ur);
+
+    // left-state limiting
+    state[0][c] = std::min(uMax, std::max(uMin, state[0][c]));
+
+    // right-state limiting
+    state[1][c] = std::min(uMax, std::max(uMin, state[1][c]));
+  };
+
+  for (std::size_t k=0; k<nmat; ++k)
+  {
+    real ul(0.0), ur(0.0);
+
+    // Density
+    // establish left- and right-hand states
+    ul = U(el, densityDofIdx(nmat, k, rdof, 0));
+    ur = U(eR, densityDofIdx(nmat, k, rdof, 0));
+
+    // limit reconstructed density
+    safeLimit(densityIdx(nmat,k), ul, ur);
+
+    // Energy
+    // establish left- and right-hand states
+    ul = U(el, energyDofIdx(nmat, k, rdof, 0));
+    ur = U(eR, energyDofIdx(nmat, k, rdof, 0));
+
+    // limit reconstructed energy
+    safeLimit(energyIdx(nmat,k), ul, ur);
+  }
+}
+
+} // tk::
 
diff --git a/Release/cppcheck/75.html b/Release/cppcheck/75.html index a8e3a3f12a46..10d8b69be026 100644 --- a/Release/cppcheck/75.html +++ b/Release/cppcheck/75.html @@ -152,299 +152,183 @@
- - - - - - - + + + + + + - - - - - + + + + + @@ -150,54 +150,54 @@

Cppcheck report - [

- - - - - - - - - + + + + + + + + + - - + + - - - - - - - - - - - - - - + + + + + + + + + + + + + + - - - - - - - - + + + + + + + + - - - + + + @@ -207,145 +207,145 @@

Cppcheck report - [

- - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - - - + + + + + - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -362,61 +362,61 @@

Cppcheck report - [

- - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + - - - - - - - - - - - + + + + + + + + + + + - - - - + + + + - - - - - - - - - + + + + + + + + + @@ -476,36 +476,36 @@

Cppcheck report - [

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -519,10 +519,10 @@

Cppcheck report - [

- - - - + + + + @@ -530,21 +530,21 @@

Cppcheck report - [

- - - - - - - - - - - - - - - + + + + + + + + + + + + + + + diff --git a/Release/cppcheck/stats.html b/Release/cppcheck/stats.html index 321baefa6056..a4cafeed2b85 100644 --- a/Release/cppcheck/stats.html +++ b/Release/cppcheck/stats.html @@ -88,55 +88,55 @@

Cppcheck report - [

Top 10 files for error severity, total findings: 34
-   12 
/tmp/TeamCity-1/work/5ad443c8abe7fc0a/src/Inciter/Transporter.cpp
+   12  /tmp/TeamCity-1/work/5ad443c8abe7fc0a/src/Inciter/Transporter.cpp
   10  /tmp/TeamCity-1/work/5ad443c8abe7fc0a/src/Statistics/PDFReducer.cpp
-   6   /tmp/TeamCity-1/work/5ad443c8abe7fc0a/src/Inciter/DiagReducer.cpp
-   2   /tmp/TeamCity-1/work/5ad443c8abe7fc0a/src/Base/ContainerUtil.hpp
+   6   /tmp/TeamCity-1/work/5ad443c8abe7fc0a/src/Inciter/DiagReducer.cpp
+   2   /tmp/TeamCity-1/work/5ad443c8abe7fc0a/src/Base/ContainerUtil.hpp
   1   /tmp/TeamCity-1/work/5ad443c8abe7fc0a/src/LinearSolver/CSR.cpp
   1   /tmp/TeamCity-1/work/5ad443c8abe7fc0a/src/Base/Vector.hpp
-   1   /tmp/TeamCity-1/work/5ad443c8abe7fc0a/src/Base/TaggedTuple.hpp
+   1   /tmp/TeamCity-1/work/5ad443c8abe7fc0a/src/Base/TaggedTuple.hpp
   1   /tmp/TeamCity-1/work/5ad443c8abe7fc0a/src/Base/Exception.cpp

Top 10 files for warning severity, total findings: 30
-   13  /tmp/TeamCity-1/work/5ad443c8abe7fc0a/src/LinearSolver/ConjugateGradients.hpp
+   13  /tmp/TeamCity-1/work/5ad443c8abe7fc0a/src/LinearSolver/ConjugateGradients.hpp
   5   /tmp/TeamCity-1/work/5ad443c8abe7fc0a/src/Transfer/TransferDetails.cpp
   3   /tmp/TeamCity-1/work/5ad443c8abe7fc0a/src/Inciter/Partitioner.hpp
-   3   /tmp/TeamCity-1/work/5ad443c8abe7fc0a/src/IO/MeshWriter.hpp
+   3   /tmp/TeamCity-1/work/5ad443c8abe7fc0a/src/IO/MeshWriter.hpp
   1   /tmp/TeamCity-1/work/5ad443c8abe7fc0a/src/Transfer/M2MTransfer.hpp
-   1   /tmp/TeamCity-1/work/5ad443c8abe7fc0a/src/PDE/MultiMat/Problem/BoxInitialization.hpp
-   1   /tmp/TeamCity-1/work/5ad443c8abe7fc0a/src/LinearSolver/ConjugateGradients.cpp
+   1   /tmp/TeamCity-1/work/5ad443c8abe7fc0a/src/PDE/MultiMat/Problem/BoxInitialization.hpp
+   1   /tmp/TeamCity-1/work/5ad443c8abe7fc0a/src/LinearSolver/ConjugateGradients.cpp
   1   /tmp/TeamCity-1/work/5ad443c8abe7fc0a/src/Inciter/ElemDiagnostics.cpp
   1   /tmp/TeamCity-1/work/5ad443c8abe7fc0a/src/Inciter/AMR/edge_store.hpp
-   1   /tmp/TeamCity-1/work/5ad443c8abe7fc0a/src/IO/ExodusIIMeshReader.cpp
+   1   /tmp/TeamCity-1/work/5ad443c8abe7fc0a/src/IO/ExodusIIMeshReader.cpp

Top 10 files for portability severity, total findings: 2
-   2  /tmp/TeamCity-1/work/5ad443c8abe7fc0a/src/Inciter/DG.cpp
+   2  /tmp/TeamCity-1/work/5ad443c8abe7fc0a/src/Inciter/DG.cpp

Top 10 files for performance severity, total findings: 19
   8  /tmp/TeamCity-1/work/5ad443c8abe7fc0a/src/Base/Types.hpp
-   5  /tmp/TeamCity-1/work/5ad443c8abe7fc0a/src/Control/Inciter/InputDeck/LuaParser.hpp
-   2  /tmp/TeamCity-1/work/5ad443c8abe7fc0a/src/Main/MeshConvDriver.cpp
-   2  /tmp/TeamCity-1/work/5ad443c8abe7fc0a/src/Inciter/OversetFE.cpp
-   2  /tmp/TeamCity-1/work/5ad443c8abe7fc0a/src/Inciter/ALECG.cpp
+   5  /tmp/TeamCity-1/work/5ad443c8abe7fc0a/src/Control/Inciter/InputDeck/LuaParser.hpp
+   2  /tmp/TeamCity-1/work/5ad443c8abe7fc0a/src/Main/MeshConvDriver.cpp
+   2  /tmp/TeamCity-1/work/5ad443c8abe7fc0a/src/Inciter/OversetFE.cpp
+   2  /tmp/TeamCity-1/work/5ad443c8abe7fc0a/src/Inciter/ALECG.cpp

Top 10 files for style severity, total findings: 278
   43  /tmp/TeamCity-1/work/5ad443c8abe7fc0a/src/PDE/MultiMat/DGMultiMat.hpp
-   29  /tmp/TeamCity-1/work/5ad443c8abe7fc0a/src/PDE/MultiMat/FVMultiMat.hpp
-   16  /tmp/TeamCity-1/work/5ad443c8abe7fc0a/src/Inciter/Refiner.cpp
+   29  /tmp/TeamCity-1/work/5ad443c8abe7fc0a/src/PDE/MultiMat/FVMultiMat.hpp
+   16  /tmp/TeamCity-1/work/5ad443c8abe7fc0a/src/Inciter/Refiner.cpp
   15  /tmp/TeamCity-1/work/5ad443c8abe7fc0a/src/Mesh/DerivedData.cpp
   14  /tmp/TeamCity-1/work/5ad443c8abe7fc0a/src/PDE/Limiter.cpp
   12  /tmp/TeamCity-1/work/5ad443c8abe7fc0a/src/PDE/MultiMat/MiscMultiMatFns.cpp
-   9   /tmp/TeamCity-1/work/5ad443c8abe7fc0a/src/Inciter/Discretization.cpp
-   7   /tmp/TeamCity-1/work/5ad443c8abe7fc0a/src/PDE/CompFlow/DGCompFlow.hpp
-   6   /tmp/TeamCity-1/work/5ad443c8abe7fc0a/src/PDE/Integrate/Surface.cpp
-   6   /tmp/TeamCity-1/work/5ad443c8abe7fc0a/src/PDE/Integrate/Boundary.cpp
+   9   /tmp/TeamCity-1/work/5ad443c8abe7fc0a/src/Inciter/Discretization.cpp
+   7   /tmp/TeamCity-1/work/5ad443c8abe7fc0a/src/PDE/CompFlow/DGCompFlow.hpp
+   6   /tmp/TeamCity-1/work/5ad443c8abe7fc0a/src/PDE/Integrate/Surface.cpp
+   6   /tmp/TeamCity-1/work/5ad443c8abe7fc0a/src/PDE/Integrate/Boundary.cpp

Top 10 files for information severity, total findings: 6
   2  /tmp/TeamCity-1/work/5ad443c8abe7fc0a/src/Inciter/ElemDiagnostics.cpp
-   1  /tmp/TeamCity-1/work/5ad443c8abe7fc0a/src/Main/UnitTest.cpp
-   1  /tmp/TeamCity-1/work/5ad443c8abe7fc0a/src/Main/MeshConv.cpp
-   1  /tmp/TeamCity-1/work/5ad443c8abe7fc0a/src/Main/Inciter.cpp
-   1  /tmp/TeamCity-1/work/5ad443c8abe7fc0a/src/Inciter/Ghosts.cpp
+   1  /tmp/TeamCity-1/work/5ad443c8abe7fc0a/src/Main/UnitTest.cpp
+   1  /tmp/TeamCity-1/work/5ad443c8abe7fc0a/src/Main/MeshConv.cpp
+   1  /tmp/TeamCity-1/work/5ad443c8abe7fc0a/src/Main/Inciter.cpp
+   1  /tmp/TeamCity-1/work/5ad443c8abe7fc0a/src/Inciter/Ghosts.cpp

diff --git a/Release/test_coverage/Base/ChareStateCollector.cpp.func-sort-c.html b/Release/test_coverage/Base/ChareStateCollector.cpp.func-sort-c.html index 714459bb96b7..a3a4676a579e 100644 --- a/Release/test_coverage/Base/ChareStateCollector.cpp.func-sort-c.html +++ b/Release/test_coverage/Base/ChareStateCollector.cpp.func-sort-c.html @@ -33,7 +33,7 @@

- + diff --git a/Release/test_coverage/Base/ChareStateCollector.cpp.func.html b/Release/test_coverage/Base/ChareStateCollector.cpp.func.html index 622bc385173e..d519ec0cc31d 100644 --- a/Release/test_coverage/Base/ChareStateCollector.cpp.func.html +++ b/Release/test_coverage/Base/ChareStateCollector.cpp.func.html @@ -33,7 +33,7 @@ - + diff --git a/Release/test_coverage/Base/ChareStateCollector.cpp.gcov.html b/Release/test_coverage/Base/ChareStateCollector.cpp.gcov.html index 73ade2b86947..97f24426faca 100644 --- a/Release/test_coverage/Base/ChareStateCollector.cpp.gcov.html +++ b/Release/test_coverage/Base/ChareStateCollector.cpp.gcov.html @@ -33,7 +33,7 @@ - + diff --git a/Release/test_coverage/Base/ChareStateCollector.hpp.func-sort-c.html b/Release/test_coverage/Base/ChareStateCollector.hpp.func-sort-c.html index 640bddf34686..ba599f24330b 100644 --- a/Release/test_coverage/Base/ChareStateCollector.hpp.func-sort-c.html +++ b/Release/test_coverage/Base/ChareStateCollector.hpp.func-sort-c.html @@ -33,7 +33,7 @@ - + diff --git a/Release/test_coverage/Base/ChareStateCollector.hpp.func.html b/Release/test_coverage/Base/ChareStateCollector.hpp.func.html index f99537428d3b..a0deed1b42c8 100644 --- a/Release/test_coverage/Base/ChareStateCollector.hpp.func.html +++ b/Release/test_coverage/Base/ChareStateCollector.hpp.func.html @@ -33,7 +33,7 @@ - + diff --git a/Release/test_coverage/Base/ChareStateCollector.hpp.gcov.html b/Release/test_coverage/Base/ChareStateCollector.hpp.gcov.html index 7d2e0fadaec5..f77909253711 100644 --- a/Release/test_coverage/Base/ChareStateCollector.hpp.gcov.html +++ b/Release/test_coverage/Base/ChareStateCollector.hpp.gcov.html @@ -33,7 +33,7 @@ - + diff --git a/Release/test_coverage/Base/ContainerUtil.hpp.func-sort-c.html b/Release/test_coverage/Base/ContainerUtil.hpp.func-sort-c.html index 05180529590d..754e5755de73 100644 --- a/Release/test_coverage/Base/ContainerUtil.hpp.func-sort-c.html +++ b/Release/test_coverage/Base/ContainerUtil.hpp.func-sort-c.html @@ -33,7 +33,7 @@ - + diff --git a/Release/test_coverage/Base/ContainerUtil.hpp.func.html b/Release/test_coverage/Base/ContainerUtil.hpp.func.html index e0cee48423a9..3984ba9be1f2 100644 --- a/Release/test_coverage/Base/ContainerUtil.hpp.func.html +++ b/Release/test_coverage/Base/ContainerUtil.hpp.func.html @@ -33,7 +33,7 @@ - + diff --git a/Release/test_coverage/Base/ContainerUtil.hpp.gcov.html b/Release/test_coverage/Base/ContainerUtil.hpp.gcov.html index bc5fcf2bf8a1..33f909136749 100644 --- a/Release/test_coverage/Base/ContainerUtil.hpp.gcov.html +++ b/Release/test_coverage/Base/ContainerUtil.hpp.gcov.html @@ -33,7 +33,7 @@ - + diff --git a/Release/test_coverage/Base/Data.hpp.func-sort-c.html b/Release/test_coverage/Base/Data.hpp.func-sort-c.html index b87a8c14ca17..1332043f7214 100644 --- a/Release/test_coverage/Base/Data.hpp.func-sort-c.html +++ b/Release/test_coverage/Base/Data.hpp.func-sort-c.html @@ -33,7 +33,7 @@ - + @@ -181,7 +181,7 @@ - + diff --git a/Release/test_coverage/Base/Data.hpp.func.html b/Release/test_coverage/Base/Data.hpp.func.html index 81ad26299b6e..be27124f659d 100644 --- a/Release/test_coverage/Base/Data.hpp.func.html +++ b/Release/test_coverage/Base/Data.hpp.func.html @@ -33,7 +33,7 @@ - + @@ -93,7 +93,7 @@ - + diff --git a/Release/test_coverage/Base/Data.hpp.gcov.html b/Release/test_coverage/Base/Data.hpp.gcov.html index 0c9302b04143..c0a4287e9acd 100644 --- a/Release/test_coverage/Base/Data.hpp.gcov.html +++ b/Release/test_coverage/Base/Data.hpp.gcov.html @@ -33,7 +33,7 @@ - + @@ -181,7 +181,7 @@ 41 : : 42 : : public: 43 : : //! Default constructor (required for Charm++ migration) - 44 [ + - ][ - - ]: 29064 : explicit Data() : m_vec(), m_nunk(), m_nprop() {} + 44 [ + - ][ - - ]: 28688 : explicit Data() : m_vec(), m_nunk(), m_nprop() {} 45 : : 46 : : //! Constructor 47 : : //! \param[in] nu Number of unknowns to allocate memory for @@ -698,15 +698,15 @@ 481 : : ///@{ 482 : : //! \brief Pack/Unpack serialize member function 483 : : //! \param[in,out] p Charm++'s PUP::er serializer object reference - 484 : 303630 : void pup( PUP::er &p ) { - 485 : 303630 : p | m_vec; - 486 : 303630 : p | m_nunk; - 487 : 303630 : p | m_nprop; - 488 : 303630 : } + 484 : 299163 : void pup( PUP::er &p ) { + 485 : 299163 : p | m_vec; + 486 : 299163 : p | m_nunk; + 487 : 299163 : p | m_nprop; + 488 : 299163 : } 489 : : //! \brief Pack/Unpack serialize operator| 490 : : //! \param[in,out] p Charm++'s PUP::er serializer object reference 491 : : //! \param[in,out] d DataLyaout object reference - 492 : 105809 : friend void operator|( PUP::er& p, Data& d ) { d.pup(p); } + 492 : 104360 : friend void operator|( PUP::er& p, Data& d ) { d.pup(p); } 493 : : //@} 494 : : 495 : : private: @@ -731,17 +731,17 @@ 514 : : "component < number of properties" ); 515 : : Assert( unknown < m_nunk, "Out-of-bounds access: unknown < number of " 516 : : "unknowns" ); - 517 [ + + ][ + + ]:13713879258 : return m_vec[ unknown*m_nprop + component ]; - [ + + ][ + + ] - [ + + ][ + + ] - [ + + ][ + + ] + 517 [ + + ][ + + ]:13713881013 : return m_vec[ unknown*m_nprop + component ]; + [ + + ][ + + ] + [ + + ][ + + ] + [ + + ][ + + ] [ + + ][ + - ] [ + - ][ + - ] [ + - ][ + - ] [ + + ][ + + ] - [ + - ][ + + ] - [ + + ][ + + ] - [ + + ][ + + ] + [ + - ][ + + ] + [ + + ][ + + ] + [ + + ][ + + ] [ - - ][ - - ] [ - - ][ - - ] [ - - ][ - - ] @@ -803,20 +803,20 @@ [ - - ][ - - ] [ - - ][ + - ] [ + + ][ + - ] - [ + + ][ + + ] + [ + + ][ + + ] [ + - ][ + + ] - [ + - ][ + + ] - [ + + ][ - - ] + [ + - ][ + + ] + [ + + ][ - - ] [ - - ][ - - ] [ - - ][ - - ] [ - - ][ - - ] [ - - ][ - - ] [ - - ][ + - ] [ + + ][ + - ] - [ + + ][ + + ] + [ + + ][ + + ] [ + - ][ + + ] - [ + - ][ + + ] - [ + + ][ - - ] + [ + - ][ + + ] + [ + + ][ - - ] [ - - ][ - - ] [ - - ][ - - ] 518 : : } diff --git a/Release/test_coverage/Base/Escaper.hpp.func-sort-c.html b/Release/test_coverage/Base/Escaper.hpp.func-sort-c.html index ccec1ed8fca9..20685a9e388a 100644 --- a/Release/test_coverage/Base/Escaper.hpp.func-sort-c.html +++ b/Release/test_coverage/Base/Escaper.hpp.func-sort-c.html @@ -33,7 +33,7 @@ - + diff --git a/Release/test_coverage/Base/Escaper.hpp.func.html b/Release/test_coverage/Base/Escaper.hpp.func.html index 2f80dbf1347c..a97b872b1d43 100644 --- a/Release/test_coverage/Base/Escaper.hpp.func.html +++ b/Release/test_coverage/Base/Escaper.hpp.func.html @@ -33,7 +33,7 @@ - + diff --git a/Release/test_coverage/Base/Escaper.hpp.gcov.html b/Release/test_coverage/Base/Escaper.hpp.gcov.html index 00356eff0ecd..d47ce5c53e6d 100644 --- a/Release/test_coverage/Base/Escaper.hpp.gcov.html +++ b/Release/test_coverage/Base/Escaper.hpp.gcov.html @@ -33,7 +33,7 @@ - + diff --git a/Release/test_coverage/Base/Exception.cpp.func-sort-c.html b/Release/test_coverage/Base/Exception.cpp.func-sort-c.html index 15aba47bc3a5..c4ae95b5accb 100644 --- a/Release/test_coverage/Base/Exception.cpp.func-sort-c.html +++ b/Release/test_coverage/Base/Exception.cpp.func-sort-c.html @@ -33,7 +33,7 @@ - + diff --git a/Release/test_coverage/Base/Exception.cpp.func.html b/Release/test_coverage/Base/Exception.cpp.func.html index 31d6725cede5..405bf0907798 100644 --- a/Release/test_coverage/Base/Exception.cpp.func.html +++ b/Release/test_coverage/Base/Exception.cpp.func.html @@ -33,7 +33,7 @@ - + diff --git a/Release/test_coverage/Base/Exception.cpp.gcov.html b/Release/test_coverage/Base/Exception.cpp.gcov.html index 49a90f95026a..a2c6c85a4a8d 100644 --- a/Release/test_coverage/Base/Exception.cpp.gcov.html +++ b/Release/test_coverage/Base/Exception.cpp.gcov.html @@ -33,7 +33,7 @@ - + diff --git a/Release/test_coverage/Base/Exception.hpp.func-sort-c.html b/Release/test_coverage/Base/Exception.hpp.func-sort-c.html index 28aee3aaecf8..d3b50a550467 100644 --- a/Release/test_coverage/Base/Exception.hpp.func-sort-c.html +++ b/Release/test_coverage/Base/Exception.hpp.func-sort-c.html @@ -33,7 +33,7 @@ - + diff --git a/Release/test_coverage/Base/Exception.hpp.func.html b/Release/test_coverage/Base/Exception.hpp.func.html index 0e76649918c2..2a41f56c7a97 100644 --- a/Release/test_coverage/Base/Exception.hpp.func.html +++ b/Release/test_coverage/Base/Exception.hpp.func.html @@ -33,7 +33,7 @@ - + diff --git a/Release/test_coverage/Base/Exception.hpp.gcov.html b/Release/test_coverage/Base/Exception.hpp.gcov.html index 23f1817046fc..6559062768d8 100644 --- a/Release/test_coverage/Base/Exception.hpp.gcov.html +++ b/Release/test_coverage/Base/Exception.hpp.gcov.html @@ -33,7 +33,7 @@ - + diff --git a/Release/test_coverage/Base/Factory.hpp.func-sort-c.html b/Release/test_coverage/Base/Factory.hpp.func-sort-c.html index 4037896a693c..ccc52f404523 100644 --- a/Release/test_coverage/Base/Factory.hpp.func-sort-c.html +++ b/Release/test_coverage/Base/Factory.hpp.func-sort-c.html @@ -33,7 +33,7 @@ - + diff --git a/Release/test_coverage/Base/Factory.hpp.func.html b/Release/test_coverage/Base/Factory.hpp.func.html index 98cb53e260cd..7c03d0bddc3e 100644 --- a/Release/test_coverage/Base/Factory.hpp.func.html +++ b/Release/test_coverage/Base/Factory.hpp.func.html @@ -33,7 +33,7 @@ - + diff --git a/Release/test_coverage/Base/Factory.hpp.gcov.html b/Release/test_coverage/Base/Factory.hpp.gcov.html index 585787a61153..9cb648f708fb 100644 --- a/Release/test_coverage/Base/Factory.hpp.gcov.html +++ b/Release/test_coverage/Base/Factory.hpp.gcov.html @@ -33,7 +33,7 @@ - + diff --git a/Release/test_coverage/Base/Flip_map.hpp.func-sort-c.html b/Release/test_coverage/Base/Flip_map.hpp.func-sort-c.html index ae678083b4bf..a5108e5a3280 100644 --- a/Release/test_coverage/Base/Flip_map.hpp.func-sort-c.html +++ b/Release/test_coverage/Base/Flip_map.hpp.func-sort-c.html @@ -33,7 +33,7 @@ - + diff --git a/Release/test_coverage/Base/Flip_map.hpp.func.html b/Release/test_coverage/Base/Flip_map.hpp.func.html index 62bf203c486f..c4bee60315d9 100644 --- a/Release/test_coverage/Base/Flip_map.hpp.func.html +++ b/Release/test_coverage/Base/Flip_map.hpp.func.html @@ -33,7 +33,7 @@ - + diff --git a/Release/test_coverage/Base/Flip_map.hpp.gcov.html b/Release/test_coverage/Base/Flip_map.hpp.gcov.html index 63d4b318ebb1..c3f4899e2daf 100644 --- a/Release/test_coverage/Base/Flip_map.hpp.gcov.html +++ b/Release/test_coverage/Base/Flip_map.hpp.gcov.html @@ -33,7 +33,7 @@ - + diff --git a/Release/test_coverage/Base/HashMapReducer.hpp.func-sort-c.html b/Release/test_coverage/Base/HashMapReducer.hpp.func-sort-c.html index 438384bfdeb9..aa2b9dd62771 100644 --- a/Release/test_coverage/Base/HashMapReducer.hpp.func-sort-c.html +++ b/Release/test_coverage/Base/HashMapReducer.hpp.func-sort-c.html @@ -33,7 +33,7 @@ - + diff --git a/Release/test_coverage/Base/HashMapReducer.hpp.func.html b/Release/test_coverage/Base/HashMapReducer.hpp.func.html index ae739b2ed2a2..7164b7f6fc73 100644 --- a/Release/test_coverage/Base/HashMapReducer.hpp.func.html +++ b/Release/test_coverage/Base/HashMapReducer.hpp.func.html @@ -33,7 +33,7 @@ - + diff --git a/Release/test_coverage/Base/HashMapReducer.hpp.gcov.html b/Release/test_coverage/Base/HashMapReducer.hpp.gcov.html index 4a03166bcf9c..51b20e9ae9ec 100644 --- a/Release/test_coverage/Base/HashMapReducer.hpp.gcov.html +++ b/Release/test_coverage/Base/HashMapReducer.hpp.gcov.html @@ -33,7 +33,7 @@ - + diff --git a/Release/test_coverage/Base/LoadDistributor.cpp.func-sort-c.html b/Release/test_coverage/Base/LoadDistributor.cpp.func-sort-c.html index 19014548e707..7f965c05d010 100644 --- a/Release/test_coverage/Base/LoadDistributor.cpp.func-sort-c.html +++ b/Release/test_coverage/Base/LoadDistributor.cpp.func-sort-c.html @@ -33,7 +33,7 @@ - + diff --git a/Release/test_coverage/Base/LoadDistributor.cpp.func.html b/Release/test_coverage/Base/LoadDistributor.cpp.func.html index 054001d95c74..a4f92417d81e 100644 --- a/Release/test_coverage/Base/LoadDistributor.cpp.func.html +++ b/Release/test_coverage/Base/LoadDistributor.cpp.func.html @@ -33,7 +33,7 @@ - + diff --git a/Release/test_coverage/Base/LoadDistributor.cpp.gcov.html b/Release/test_coverage/Base/LoadDistributor.cpp.gcov.html index 96a0ee38c3a3..6667fc60fb02 100644 --- a/Release/test_coverage/Base/LoadDistributor.cpp.gcov.html +++ b/Release/test_coverage/Base/LoadDistributor.cpp.gcov.html @@ -33,7 +33,7 @@ - + diff --git a/Release/test_coverage/Base/PUPUtil.hpp.func-sort-c.html b/Release/test_coverage/Base/PUPUtil.hpp.func-sort-c.html index cc85b02a852d..1e9a00bc78f5 100644 --- a/Release/test_coverage/Base/PUPUtil.hpp.func-sort-c.html +++ b/Release/test_coverage/Base/PUPUtil.hpp.func-sort-c.html @@ -33,7 +33,7 @@ - + @@ -93,51 +93,51 @@ - + - + - + - + - + - + - + - + - + - + - + - + diff --git a/Release/test_coverage/Base/PUPUtil.hpp.func.html b/Release/test_coverage/Base/PUPUtil.hpp.func.html index 796f57614dd1..07eec22645ed 100644 --- a/Release/test_coverage/Base/PUPUtil.hpp.func.html +++ b/Release/test_coverage/Base/PUPUtil.hpp.func.html @@ -33,7 +33,7 @@ - + @@ -73,19 +73,19 @@ - + - + - + - + @@ -97,7 +97,7 @@ - + @@ -109,27 +109,27 @@ - + - + - + - + - + - + @@ -137,7 +137,7 @@ - + diff --git a/Release/test_coverage/Base/PUPUtil.hpp.gcov.html b/Release/test_coverage/Base/PUPUtil.hpp.gcov.html index 26ec4e026539..ad3c47217d4a 100644 --- a/Release/test_coverage/Base/PUPUtil.hpp.gcov.html +++ b/Release/test_coverage/Base/PUPUtil.hpp.gcov.html @@ -33,7 +33,7 @@ - + @@ -158,21 +158,21 @@ 67 : : class T, 68 : : class Hash = std::hash< Key >, 69 : : class KeyEqual = std::equal_to< Key > > - 70 : 154854 : inline void pup( PUP::er& p, std::unordered_map< Key, T, Hash, KeyEqual >& m ) { + 70 : 153522 : inline void pup( PUP::er& p, std::unordered_map< Key, T, Hash, KeyEqual >& m ) { 71 : : auto size = PUP_stl_container_size( p, m ); - 72 [ + + ]: 154854 : if (p.isUnpacking()) { - 73 [ + + ]: 1974558 : for (decltype(size) s=0; s<size; ++s) { + 72 [ + + ]: 153522 : if (p.isUnpacking()) { + 73 [ + + ]: 1983102 : for (decltype(size) s=0; s<size; ++s) { 74 : 1550902 : std::pair< Key, T > node; - 75 [ + - ]: 1924198 : p | node; + 75 [ + - ]: 1933186 : p | node; 76 : : m.emplace( node ); 77 : : } 78 : : } else { - 79 [ + + ]: 4227530 : for (auto& t : m) { + 79 [ + + ]: 4244618 : for (auto& t : m) { 80 : : std::pair< Key, T > node( t ); - 81 [ + - ]: 4123036 : p | node; + 81 [ + - ]: 4141012 : p | node; 82 : : } 83 : : } - 84 : 154854 : } + 84 : 153522 : } 85 : : //! Pack/Unpack std::unordered_map. 86 : : //! \param[in] p Charm++'s pack/unpack object 87 : : //! \param[in] m std::unordered_map< Key, T, Hash, KeyEqual > to pack/unpack @@ -182,7 +182,7 @@ 91 : : class KeyEqual = std::equal_to< Key > > 92 : : inline void operator|( PUP::er& p, 93 : : std::unordered_map< Key, T, Hash, KeyEqual >& m ) - 94 [ - - ][ - - ]: 146763 : { pup( p, m ); } + 94 [ - - ][ - - ]: 145479 : { pup( p, m ); } [ - - ][ - - ] [ - - ][ - - ] [ + - ][ - - ] @@ -197,21 +197,21 @@ 101 : : template< class Key, 102 : : class Hash = std::hash< Key >, 103 : : class KeyEqual = std::equal_to< Key > > - 104 : 848097 : inline void pup( PUP::er& p, std::unordered_set< Key, Hash, KeyEqual >& s ) { + 104 : 840453 : inline void pup( PUP::er& p, std::unordered_set< Key, Hash, KeyEqual >& s ) { 105 : : auto size = PUP_stl_container_size( p, s ); - 106 [ + + ]: 848097 : if (p.isUnpacking()) { - 107 [ + + ]: 3545940 : for (decltype(size) i=0; i<size; ++i) { + 106 [ + + ]: 840453 : if (p.isUnpacking()) { + 107 [ + + ]: 3556824 : for (decltype(size) i=0; i<size; ++i) { 108 : : Key node; 109 : : p | node; 110 : : s.emplace( node ); 111 : : } 112 : : } else { - 113 [ + + ]: 8274039 : for (auto& t : s) { - 114 : 7702936 : Key node( t ); + 113 [ + + ]: 8295807 : for (auto& t : s) { + 114 : 7729800 : Key node( t ); 115 : : p | node; 116 : : } 117 : : } - 118 : 848097 : } + 118 : 840453 : } 119 : : //! Pack/Unpack std::unordered_set. 120 : : //! \param[in] p Charm++'s pack/unpack object 121 : : //! \param[in] s std::unordered_set< Key, Hash, KeyEqual > to pack/unpack @@ -220,8 +220,8 @@ 124 : : class KeyEqual = std::equal_to< Key > > 125 : : inline void operator|( PUP::er& p, 126 : : std::unordered_set< Key, Hash, KeyEqual >& s ) - 127 [ + - ][ + - ]: 848097 : { pup( p, s ); } - [ + - ][ - - ] + 127 [ + - ][ + - ]: 840453 : { pup( p, s ); } + [ + - ][ - - ] [ - - ][ - - ] [ - - ][ + - ] [ - - ][ + - ] @@ -277,42 +277,42 @@ 168 : : //! \param[in] p Charm++'s pack/unpack object 169 : : //! \param[in] var std::variant< Ts... > of arbitrary types to pack/unpack 170 : : template <class T, class... Ts> - 171 : 249112 : char pup_helper( std::size_t& index, + 171 : 246640 : char pup_helper( std::size_t& index, 172 : : const std::size_t send_index, 173 : : PUP::er& p, 174 : : std::variant<Ts...>& var ) 175 : : { - 176 [ + + ]: 249112 : if (index == send_index) { - 177 [ + + ]: 62281 : if (p.isUnpacking()) { + 176 [ + + ]: 246640 : if (index == send_index) { + 177 [ + + ]: 61663 : if (p.isUnpacking()) { 178 : 2 : T t{}; - 179 [ + - ]: 20331 : p | t; - 180 [ + - ]: 20331 : var = std::move(t); + 179 [ + - ]: 20125 : p | t; + 180 [ + - ]: 20125 : var = std::move(t); 181 : : } else { - 182 : 41944 : p | std::get<T>(var); + 182 : 41532 : p | std::get<T>(var); 183 : : } 184 : : } - 185 : 249112 : index++; - 186 : 249112 : return '0'; + 185 : 246640 : index++; + 186 : 246640 : return '0'; 187 : : } 188 : : 189 : : //! Pack/Unpack std::variant 190 : : //! \param[in] p Charm++'s pack/unpack object 191 : : //! \param[in] var std::variant< Ts... > of arbitrary types to pack/unpack 192 : : template <class... Ts> - 193 : 62281 : void pup(PUP::er& p, std::variant<Ts...>& var) { - 194 : 62281 : std::size_t index = 0; - 195 [ + - ]: 124562 : auto send_index = var.index(); + 193 : 61663 : void pup(PUP::er& p, std::variant<Ts...>& var) { + 194 : 61663 : std::size_t index = 0; + 195 [ + - ]: 123326 : auto send_index = var.index(); 196 : : p | send_index; - 197 : 249112 : (void)std::initializer_list<char>{ - 198 : 62281 : pup_helper<Ts>(index, send_index, p, var)...}; - 199 : 62281 : } + 197 : 246640 : (void)std::initializer_list<char>{ + 198 : 61663 : pup_helper<Ts>(index, send_index, p, var)...}; + 199 : 61663 : } 200 : : 201 : : //! Pack/Unpack std::variant 202 : : //! \param[in] p Charm++'s pack/unpack object 203 : : //! \param[in] d std::variant< Ts... > of arbitrary types to pack/unpack 204 : : template <typename... Ts> 205 : : inline void operator|(PUP::er& p, std::variant<Ts...>& d) { - 206 [ - - ][ - - ]: 62281 : pup(p, d); + 206 [ - - ][ - - ]: 61663 : pup(p, d); [ - - ][ + - ] [ - - ][ - - ] [ + - ][ + - ] diff --git a/Release/test_coverage/Base/Print.hpp.func-sort-c.html b/Release/test_coverage/Base/Print.hpp.func-sort-c.html index 2952a553281e..881b712a8a66 100644 --- a/Release/test_coverage/Base/Print.hpp.func-sort-c.html +++ b/Release/test_coverage/Base/Print.hpp.func-sort-c.html @@ -33,7 +33,7 @@ - + diff --git a/Release/test_coverage/Base/Print.hpp.func.html b/Release/test_coverage/Base/Print.hpp.func.html index 91caffbe37b3..6eed1d671453 100644 --- a/Release/test_coverage/Base/Print.hpp.func.html +++ b/Release/test_coverage/Base/Print.hpp.func.html @@ -33,7 +33,7 @@ - + diff --git a/Release/test_coverage/Base/Print.hpp.gcov.html b/Release/test_coverage/Base/Print.hpp.gcov.html index 1a0d1c14f9c9..1a7ffff11e61 100644 --- a/Release/test_coverage/Base/Print.hpp.gcov.html +++ b/Release/test_coverage/Base/Print.hpp.gcov.html @@ -33,7 +33,7 @@ - + diff --git a/Release/test_coverage/Base/PrintUtil.cpp.func-sort-c.html b/Release/test_coverage/Base/PrintUtil.cpp.func-sort-c.html index 78b9a1851470..bdcc5d7c20a4 100644 --- a/Release/test_coverage/Base/PrintUtil.cpp.func-sort-c.html +++ b/Release/test_coverage/Base/PrintUtil.cpp.func-sort-c.html @@ -33,7 +33,7 @@ - + diff --git a/Release/test_coverage/Base/PrintUtil.cpp.func.html b/Release/test_coverage/Base/PrintUtil.cpp.func.html index 6e745f142924..0ed3d6e08b6b 100644 --- a/Release/test_coverage/Base/PrintUtil.cpp.func.html +++ b/Release/test_coverage/Base/PrintUtil.cpp.func.html @@ -33,7 +33,7 @@ - + diff --git a/Release/test_coverage/Base/PrintUtil.cpp.gcov.html b/Release/test_coverage/Base/PrintUtil.cpp.gcov.html index d71b984c718f..9e91b68a99a3 100644 --- a/Release/test_coverage/Base/PrintUtil.cpp.gcov.html +++ b/Release/test_coverage/Base/PrintUtil.cpp.gcov.html @@ -33,7 +33,7 @@ - + diff --git a/Release/test_coverage/Base/PrintUtil.hpp.func-sort-c.html b/Release/test_coverage/Base/PrintUtil.hpp.func-sort-c.html index be565ceb1f3b..71bffeae3948 100644 --- a/Release/test_coverage/Base/PrintUtil.hpp.func-sort-c.html +++ b/Release/test_coverage/Base/PrintUtil.hpp.func-sort-c.html @@ -33,7 +33,7 @@ - + diff --git a/Release/test_coverage/Base/PrintUtil.hpp.func.html b/Release/test_coverage/Base/PrintUtil.hpp.func.html index 16a956c1b924..97dce46876cd 100644 --- a/Release/test_coverage/Base/PrintUtil.hpp.func.html +++ b/Release/test_coverage/Base/PrintUtil.hpp.func.html @@ -33,7 +33,7 @@ - + diff --git a/Release/test_coverage/Base/PrintUtil.hpp.gcov.html b/Release/test_coverage/Base/PrintUtil.hpp.gcov.html index 0c6ab317dd2d..9df1a6ca8d09 100644 --- a/Release/test_coverage/Base/PrintUtil.hpp.gcov.html +++ b/Release/test_coverage/Base/PrintUtil.hpp.gcov.html @@ -33,7 +33,7 @@ - + diff --git a/Release/test_coverage/Base/ProcessException.cpp.func-sort-c.html b/Release/test_coverage/Base/ProcessException.cpp.func-sort-c.html index d1a3d06c06ec..15ee39a6467d 100644 --- a/Release/test_coverage/Base/ProcessException.cpp.func-sort-c.html +++ b/Release/test_coverage/Base/ProcessException.cpp.func-sort-c.html @@ -33,7 +33,7 @@ - + diff --git a/Release/test_coverage/Base/ProcessException.cpp.func.html b/Release/test_coverage/Base/ProcessException.cpp.func.html index c2cf557baa6d..bb547d827c7e 100644 --- a/Release/test_coverage/Base/ProcessException.cpp.func.html +++ b/Release/test_coverage/Base/ProcessException.cpp.func.html @@ -33,7 +33,7 @@ - + diff --git a/Release/test_coverage/Base/ProcessException.cpp.gcov.html b/Release/test_coverage/Base/ProcessException.cpp.gcov.html index 713a0f051694..4883a8a9acd5 100644 --- a/Release/test_coverage/Base/ProcessException.cpp.gcov.html +++ b/Release/test_coverage/Base/ProcessException.cpp.gcov.html @@ -33,7 +33,7 @@ - + diff --git a/Release/test_coverage/Base/Progress.hpp.func-sort-c.html b/Release/test_coverage/Base/Progress.hpp.func-sort-c.html index 9fed88d4d29f..89125be16022 100644 --- a/Release/test_coverage/Base/Progress.hpp.func-sort-c.html +++ b/Release/test_coverage/Base/Progress.hpp.func-sort-c.html @@ -33,7 +33,7 @@ - + diff --git a/Release/test_coverage/Base/Progress.hpp.func.html b/Release/test_coverage/Base/Progress.hpp.func.html index a7007c19502e..df6c91fecff1 100644 --- a/Release/test_coverage/Base/Progress.hpp.func.html +++ b/Release/test_coverage/Base/Progress.hpp.func.html @@ -33,7 +33,7 @@ - + diff --git a/Release/test_coverage/Base/Progress.hpp.gcov.html b/Release/test_coverage/Base/Progress.hpp.gcov.html index fe60a92c4152..430e9943bad7 100644 --- a/Release/test_coverage/Base/Progress.hpp.gcov.html +++ b/Release/test_coverage/Base/Progress.hpp.gcov.html @@ -33,7 +33,7 @@ - + diff --git a/Release/test_coverage/Base/Reader.cpp.func-sort-c.html b/Release/test_coverage/Base/Reader.cpp.func-sort-c.html index 93ff4564ddf8..25383ec7e86d 100644 --- a/Release/test_coverage/Base/Reader.cpp.func-sort-c.html +++ b/Release/test_coverage/Base/Reader.cpp.func-sort-c.html @@ -33,7 +33,7 @@ - + diff --git a/Release/test_coverage/Base/Reader.cpp.func.html b/Release/test_coverage/Base/Reader.cpp.func.html index c30a286d7bf2..4baf6a52bc63 100644 --- a/Release/test_coverage/Base/Reader.cpp.func.html +++ b/Release/test_coverage/Base/Reader.cpp.func.html @@ -33,7 +33,7 @@ - + diff --git a/Release/test_coverage/Base/Reader.cpp.gcov.html b/Release/test_coverage/Base/Reader.cpp.gcov.html index c54656bdded3..9384e98cba8d 100644 --- a/Release/test_coverage/Base/Reader.cpp.gcov.html +++ b/Release/test_coverage/Base/Reader.cpp.gcov.html @@ -33,7 +33,7 @@ - + diff --git a/Release/test_coverage/Base/Table.hpp.func-sort-c.html b/Release/test_coverage/Base/Table.hpp.func-sort-c.html index a8930ff36c1d..8b0ce67b1070 100644 --- a/Release/test_coverage/Base/Table.hpp.func-sort-c.html +++ b/Release/test_coverage/Base/Table.hpp.func-sort-c.html @@ -33,7 +33,7 @@ - + diff --git a/Release/test_coverage/Base/Table.hpp.func.html b/Release/test_coverage/Base/Table.hpp.func.html index 444e77ac57bd..828aa23b0d67 100644 --- a/Release/test_coverage/Base/Table.hpp.func.html +++ b/Release/test_coverage/Base/Table.hpp.func.html @@ -33,7 +33,7 @@ - + diff --git a/Release/test_coverage/Base/Table.hpp.gcov.html b/Release/test_coverage/Base/Table.hpp.gcov.html index b5ee1d55f10d..f13e99342c5b 100644 --- a/Release/test_coverage/Base/Table.hpp.gcov.html +++ b/Release/test_coverage/Base/Table.hpp.gcov.html @@ -33,7 +33,7 @@ - + diff --git a/Release/test_coverage/Base/TaggedTuple.hpp.func-sort-c.html b/Release/test_coverage/Base/TaggedTuple.hpp.func-sort-c.html index 5726e5a95b8e..4bafaf776c83 100644 --- a/Release/test_coverage/Base/TaggedTuple.hpp.func-sort-c.html +++ b/Release/test_coverage/Base/TaggedTuple.hpp.func-sort-c.html @@ -33,7 +33,7 @@ - + diff --git a/Release/test_coverage/Base/TaggedTuple.hpp.func.html b/Release/test_coverage/Base/TaggedTuple.hpp.func.html index 32e75bdd00ba..29db004236f8 100644 --- a/Release/test_coverage/Base/TaggedTuple.hpp.func.html +++ b/Release/test_coverage/Base/TaggedTuple.hpp.func.html @@ -33,7 +33,7 @@ - + diff --git a/Release/test_coverage/Base/TaggedTuple.hpp.gcov.html b/Release/test_coverage/Base/TaggedTuple.hpp.gcov.html index 1c97410ad968..db57be1a84e1 100644 --- a/Release/test_coverage/Base/TaggedTuple.hpp.gcov.html +++ b/Release/test_coverage/Base/TaggedTuple.hpp.gcov.html @@ -33,7 +33,7 @@ - + @@ -246,7 +246,7 @@ 171 : : ///@{ 172 : : //! \brief Pack/Unpack serialize member function 173 : : //! \param[in,out] p Charm++'s PUP::er serializer object reference - 174 [ - - ][ + - ]: 186284 : void pup( PUP::er& p ) { p | m_members; } + 174 [ - - ][ + - ]: 185357 : void pup( PUP::er& p ) { p | m_members; } [ - - ][ + - ] [ + - ][ + - ] [ - - ][ - - ] diff --git a/Release/test_coverage/Base/TaggedTupleDeepPrint.hpp.func-sort-c.html b/Release/test_coverage/Base/TaggedTupleDeepPrint.hpp.func-sort-c.html index 1109467eee93..573704dcad78 100644 --- a/Release/test_coverage/Base/TaggedTupleDeepPrint.hpp.func-sort-c.html +++ b/Release/test_coverage/Base/TaggedTupleDeepPrint.hpp.func-sort-c.html @@ -33,7 +33,7 @@ - + diff --git a/Release/test_coverage/Base/TaggedTupleDeepPrint.hpp.func.html b/Release/test_coverage/Base/TaggedTupleDeepPrint.hpp.func.html index 5b86af81f205..8e878fbb626e 100644 --- a/Release/test_coverage/Base/TaggedTupleDeepPrint.hpp.func.html +++ b/Release/test_coverage/Base/TaggedTupleDeepPrint.hpp.func.html @@ -33,7 +33,7 @@ - + diff --git a/Release/test_coverage/Base/TaggedTupleDeepPrint.hpp.gcov.html b/Release/test_coverage/Base/TaggedTupleDeepPrint.hpp.gcov.html index c7ffab8d2c93..96fd3869d894 100644 --- a/Release/test_coverage/Base/TaggedTupleDeepPrint.hpp.gcov.html +++ b/Release/test_coverage/Base/TaggedTupleDeepPrint.hpp.gcov.html @@ -33,7 +33,7 @@ - + diff --git a/Release/test_coverage/Base/TaggedTuplePrint.hpp.func-sort-c.html b/Release/test_coverage/Base/TaggedTuplePrint.hpp.func-sort-c.html index 82c71ffde632..2fc08a3f646f 100644 --- a/Release/test_coverage/Base/TaggedTuplePrint.hpp.func-sort-c.html +++ b/Release/test_coverage/Base/TaggedTuplePrint.hpp.func-sort-c.html @@ -33,7 +33,7 @@ - + diff --git a/Release/test_coverage/Base/TaggedTuplePrint.hpp.func.html b/Release/test_coverage/Base/TaggedTuplePrint.hpp.func.html index 9d6f9a260fe1..7dc48238857d 100644 --- a/Release/test_coverage/Base/TaggedTuplePrint.hpp.func.html +++ b/Release/test_coverage/Base/TaggedTuplePrint.hpp.func.html @@ -33,7 +33,7 @@ - + diff --git a/Release/test_coverage/Base/TaggedTuplePrint.hpp.gcov.html b/Release/test_coverage/Base/TaggedTuplePrint.hpp.gcov.html index d84fbdb62fe0..e94a137a2044 100644 --- a/Release/test_coverage/Base/TaggedTuplePrint.hpp.gcov.html +++ b/Release/test_coverage/Base/TaggedTuplePrint.hpp.gcov.html @@ -33,7 +33,7 @@ - + diff --git a/Release/test_coverage/Base/TeeBuf.hpp.func-sort-c.html b/Release/test_coverage/Base/TeeBuf.hpp.func-sort-c.html index a44d3bf93754..273993e184de 100644 --- a/Release/test_coverage/Base/TeeBuf.hpp.func-sort-c.html +++ b/Release/test_coverage/Base/TeeBuf.hpp.func-sort-c.html @@ -33,7 +33,7 @@ - + diff --git a/Release/test_coverage/Base/TeeBuf.hpp.func.html b/Release/test_coverage/Base/TeeBuf.hpp.func.html index abdbc2434836..ba7f0079b060 100644 --- a/Release/test_coverage/Base/TeeBuf.hpp.func.html +++ b/Release/test_coverage/Base/TeeBuf.hpp.func.html @@ -33,7 +33,7 @@ - + diff --git a/Release/test_coverage/Base/TeeBuf.hpp.gcov.html b/Release/test_coverage/Base/TeeBuf.hpp.gcov.html index a4f4d9b94df1..7047809144a8 100644 --- a/Release/test_coverage/Base/TeeBuf.hpp.gcov.html +++ b/Release/test_coverage/Base/TeeBuf.hpp.gcov.html @@ -33,7 +33,7 @@ - + diff --git a/Release/test_coverage/Base/Timer.cpp.func-sort-c.html b/Release/test_coverage/Base/Timer.cpp.func-sort-c.html index cf269b340ac1..fde03b0eb330 100644 --- a/Release/test_coverage/Base/Timer.cpp.func-sort-c.html +++ b/Release/test_coverage/Base/Timer.cpp.func-sort-c.html @@ -33,7 +33,7 @@ - + diff --git a/Release/test_coverage/Base/Timer.cpp.func.html b/Release/test_coverage/Base/Timer.cpp.func.html index 26c76e88c35b..911be6b72c0e 100644 --- a/Release/test_coverage/Base/Timer.cpp.func.html +++ b/Release/test_coverage/Base/Timer.cpp.func.html @@ -33,7 +33,7 @@ - + diff --git a/Release/test_coverage/Base/Timer.cpp.gcov.html b/Release/test_coverage/Base/Timer.cpp.gcov.html index 54372c0f3d9c..06e06afa8dca 100644 --- a/Release/test_coverage/Base/Timer.cpp.gcov.html +++ b/Release/test_coverage/Base/Timer.cpp.gcov.html @@ -33,7 +33,7 @@ - + diff --git a/Release/test_coverage/Base/Timer.hpp.func-sort-c.html b/Release/test_coverage/Base/Timer.hpp.func-sort-c.html index b029a4a39b42..cfa2dfb5e5a2 100644 --- a/Release/test_coverage/Base/Timer.hpp.func-sort-c.html +++ b/Release/test_coverage/Base/Timer.hpp.func-sort-c.html @@ -33,7 +33,7 @@ - + diff --git a/Release/test_coverage/Base/Timer.hpp.func.html b/Release/test_coverage/Base/Timer.hpp.func.html index cd505bcfdf10..8ba9a3b196e4 100644 --- a/Release/test_coverage/Base/Timer.hpp.func.html +++ b/Release/test_coverage/Base/Timer.hpp.func.html @@ -33,7 +33,7 @@ - + diff --git a/Release/test_coverage/Base/Timer.hpp.gcov.html b/Release/test_coverage/Base/Timer.hpp.gcov.html index 279262e25307..823845103fe9 100644 --- a/Release/test_coverage/Base/Timer.hpp.gcov.html +++ b/Release/test_coverage/Base/Timer.hpp.gcov.html @@ -33,7 +33,7 @@ - + @@ -129,7 +129,7 @@ 54 : : }; 55 : : 56 : : //! Constructor: initialize clock to current time stamp. - 57 [ + + ]: 10763 : explicit Timer() : m_start( clock::now() ) {} + 57 [ + + ]: 10660 : explicit Timer() : m_start( clock::now() ) {} 58 : : 59 : : //! Zero timer 60 [ + - ]: 2001 : void zero() { m_start = clock::now(); } @@ -153,7 +153,7 @@ 77 : : //! Pack/Unpack serialize member function 78 : : //! \param[in,out] p Charm++'s PUP::er serializer object reference 79 : : void pup( PUP::er& p ) - 80 [ - - ][ + - ]: 25009 : { p( reinterpret_cast<char*>(&m_start), sizeof(clock::time_point) ); } + 80 [ - - ][ + - ]: 24700 : { p( reinterpret_cast<char*>(&m_start), sizeof(clock::time_point) ); } 81 : : //! \brief Pack/Unpack serialize operator| 82 : : //! \param[in,out] p Charm++'s PUP::er serializer object reference 83 : : //! \param[in,out] t Timer object reference diff --git a/Release/test_coverage/Base/Types.hpp.func-sort-c.html b/Release/test_coverage/Base/Types.hpp.func-sort-c.html index 2d940ee866b5..539907d92b32 100644 --- a/Release/test_coverage/Base/Types.hpp.func-sort-c.html +++ b/Release/test_coverage/Base/Types.hpp.func-sort-c.html @@ -33,7 +33,7 @@ - + diff --git a/Release/test_coverage/Base/Types.hpp.func.html b/Release/test_coverage/Base/Types.hpp.func.html index 363205cf88b6..0d46cf46b8c6 100644 --- a/Release/test_coverage/Base/Types.hpp.func.html +++ b/Release/test_coverage/Base/Types.hpp.func.html @@ -33,7 +33,7 @@ - + diff --git a/Release/test_coverage/Base/Types.hpp.gcov.html b/Release/test_coverage/Base/Types.hpp.gcov.html index e9ded33d82ae..426e4bc609c6 100644 --- a/Release/test_coverage/Base/Types.hpp.gcov.html +++ b/Release/test_coverage/Base/Types.hpp.gcov.html @@ -33,7 +33,7 @@ - + diff --git a/Release/test_coverage/Base/Vector.hpp.func-sort-c.html b/Release/test_coverage/Base/Vector.hpp.func-sort-c.html index e639c8a949e6..80b18a80ffdb 100644 --- a/Release/test_coverage/Base/Vector.hpp.func-sort-c.html +++ b/Release/test_coverage/Base/Vector.hpp.func-sort-c.html @@ -27,13 +27,13 @@ - + - + - + @@ -52,9 +52,9 @@ - - - + + +
  1
-  2
-  3
-  4
-  5
-  6
-  7
-  8
-  9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
- 37
- 38
- 39
- 40
- 41
- 42
- 43
- 44
- 45
- 46
- 47
- 48
- 49
- 50
- 51
- 52
- 53
- 54
- 55
- 56
- 57
- 58
- 59
- 60
- 61
- 62
- 63
- 64
- 65
- 66
- 67
- 68
- 69
- 70
- 71
- 72
- 73
- 74
- 75
- 76
- 77
- 78
- 79
- 80
- 81
- 82
- 83
- 84
- 85
- 86
- 87
- 88
- 89
- 90
- 91
- 92
- 93
- 94
- 95
- 96
- 97
- 98
- 99
-100
-101
-102
-103
-104
-105
-106
-107
-108
-109
-110
-111
-112
-113
-114
-115
-116
-117
-118
-119
-120
-121
-122
-123
-124
-125
-126
-127
-128
-129
-130
-131
-132
-133
-134
-135
-136
-137
-138
-139
-140
-141
-142
-143
// *****************************************************************************
+
 1
+ 2
+ 3
+ 4
+ 5
+ 6
+ 7
+ 8
+ 9
+10
+11
+12
+13
+14
+15
+16
+17
+18
+19
+20
+21
+22
+23
+24
+25
+26
+27
+28
+29
+30
+31
+32
+33
+34
+35
+36
+37
+38
+39
+40
+41
+42
+43
+44
+45
+46
+47
+48
+49
+50
+51
+52
+53
+54
+55
+56
+57
+58
+59
+60
+61
+62
+63
+64
+65
+66
+67
+68
+69
+70
+71
+72
+73
+74
+75
+76
+77
+78
+79
+80
+81
+82
+83
+84
+85
// *****************************************************************************
 /*!
-  \file      src/PDE/MultiMat/Physics/FVEnergyPill.cpp
+  \file      src/PDE/Transport/Problem/CylVortex.cpp
   \copyright 2012-2015 J. Bakosi,
              2016-2018 Los Alamos National Security, LLC.,
              2019-2021 Triad National Security, LLC.
              All rights reserved. See the LICENSE file for details.
-  \brief     Physics policy for the Euler equation governing multi-material flow
-    using a finite volume method
-  \details   This file defines a Physics policy class for the compressible
-    flow equations class fv::MultiMat, defined in PDE/MultiMat/FVMultiMat.h.
-    This specific class allows energy pill initialization of a user defined
-    box/block for multi-material flow. See PDE/MultiMat/Physics/FV.h for general
-    requirements on Physics policy classes for fv::MultiMat.
+  \brief     Problem configuration for transport equations
+  \details   This file defines a Problem policy class for the transport
+    equations, defined in PDE/Transport/CGTransport.hpp implementing
+    node-centered continuous Galerkin (CG) and PDE/Transport/DGTransport.hpp
+    implementing cell-centered discontinuous Galerkin (DG) discretizations.
+    See PDE/Transport/Problem.hpp for general requirements on Problem policy
+    classes for cg::Transport and dg::Transport.
 */
 // *****************************************************************************
 
-#include "FVEnergyPill.hpp"
-#include "Inciter/InputDeck/InputDeck.hpp"
-#include "ContainerUtil.hpp"
-#include "MultiMat/MultiMatIndexing.hpp"
-#include "NoWarning/charm++.hpp"
-
-namespace inciter {
-
-extern ctr::InputDeck g_inputdeck;
-
-} // inciter::
-
-using inciter::fv::MultiMatPhysicsEnergyPill;
-
-tk::real
-MultiMatPhysicsEnergyPill::dtRestriction(
-  const tk::Fields& geoElem,
-  std::size_t nelem,
-  const std::vector< int >& engSrcAd ) const
-// *****************************************************************************
-//  Compute the time step size restriction based on this physics
-//! \param[in] geoElem Element geometry array
-//! \param[in] nelem Number of elements
-//! \param[in] engSrcAd Whether the energy source was added
-//! \return Maximum allowable time step based on front propagation speed
-// *****************************************************************************
-{
-  auto mindt = std::numeric_limits< tk::real >::max();
-  // determine front propagation speed
-  const auto& icmbk = g_inputdeck.get< tag::ic, tag::meshblock >();
-  tk::real v_front(0.0);
-  for (const auto& b : icmbk) { // for all blocks
-    auto inittype = b.template get< tag::initiate >();
-    if (inittype == ctr::InitiateType::LINEAR) {
-      v_front = std::max(v_front,
-        b.template get< tag::front_speed >());
-    }
+#include "CylVortex.hpp"
+
+using inciter::TransportProblemCylVortex;
+
+std::vector< tk::real >
+TransportProblemCylVortex::initialize( ncomp_t ncomp,
+                                       const std::vector< EOS >&,
+                                       tk::real x, tk::real y, tk::real,
+                                       tk::real t )
+// *****************************************************************************
+//  Evaluate initial solution at (x,y,t) for all components
+//! \param[in] ncomp Number of components in this transport equation system
+//! \param[in] x X coordinate where to evaluate the solution
+//! \param[in] y Y coordinate where to evaluate the solution
+//! \param[in] t Time where to evaluate the solution
+//! \return Values of all components evaluated at (x,y,t=0)
+//! \details This function only gives the initial condition for the cylinder,
+//!   and not the solution at any time t>0.
+// *****************************************************************************
+{
+  const auto vel = prescribedVelocity( ncomp, x, y, 0.0, t );<--- Variable 'vel' is assigned a value that is never used.
+
+  if (ncomp != 4) Throw("Cylinder deformation in vortex is only set up for 4 "
+    "components");
+
+  std::vector< tk::real > s( ncomp, 0.0 );
+
+  // center of the cylinder
+  auto x0 = 0.5;
+  auto y0 = 0.75;
+  auto r = sqrt((x-x0)*(x-x0) + (y-y0)*(y-y0));
+
+  if (r<=0.15) {
+    if (x<x0 && y>=y0) s[0] = 1.0;
+    else if (x>=x0 && y>=y0) s[1] = 1.0;
+    else if (x>=x0 && y<y0) s[2] = 1.0;
+    else if (x<x0 && y<y0) s[3] = 1.0;
   }
 
-  for (std::size_t e=0; e<nelem; ++e)
-  {
-    // characteristic length (radius of insphere)
-    auto dx = std::min(std::cbrt(geoElem(e,0)), geoElem(e,4))
-      /std::sqrt(24.0);
-
-    // element dt restriction if relevant energy sources were added
-    if (engSrcAd[e] > 0 && std::abs(v_front) > 1e-8)
-      mindt = std::min(mindt, dx/v_front);
-  }
-
-  return mindt;
-}
-
-void MultiMatPhysicsEnergyPill::
-physSrc(
-  std::size_t nmat,
-  tk::real t,
-  const tk::Fields& geoElem,
-  const std::unordered_map< std::size_t, std::set< std::size_t > >& elemblkid,
-  tk::Fields& R,<--- Parameter 'R' can be declared with const
-  std::vector< int >& engSrcAdded ) const
-// *****************************************************************************
-//! Compute sources corresponding to a propagating front in user-defined box
-//! \param[in] nmat Number of materials
-//! \param[in] t Physical time
-//! \param[in] geoElem Element geometry array
-//! \param[in] elemblkid Element ids associated with mesh block ids where
-//!   user ICs are set
-//! \param[in,out] R Right-hand side vector
-//! \param[in,out] engSrcAdded Whether the energy source was added
-//! \details This function adds the energy source corresponding to a
-//!   spherically growing wave-front propagating with a user-specified
-//!   velocity, within a user-configured mesh block initial condition.
-//!   Example (SI) units of the quantities involved:
-//!    * internal energy content (energy per unit volume): J/m^3
-//!    * specific energy (internal energy per unit mass): J/kg
-// *****************************************************************************
-{
-  const auto& icmbk = g_inputdeck.get< tag::ic, tag::meshblock >();
-  for (const auto& mb : icmbk) { // for all blocks
-    auto blid = mb.get< tag::blockid >();
-    if (elemblkid.find(blid) != elemblkid.end()) { // if elements exist in blk
-      const auto& initiate = mb.template get< tag::initiate >();
-      if (initiate == ctr::InitiateType::LINEAR) { // if propagating src
-
-        const auto& blkelems = tk::cref_find(elemblkid,blid);
-
-        auto enc = mb.template get< tag::energy_content >();
-        Assert( enc > 0.0, "Box energy content must be nonzero" );
-        const auto& x0_front = mb.template get< tag::point >();
-        Assert(x0_front.size()==3, "Incorrectly sized front initial location");
-        auto blkmatid = mb.template get< tag::materialid >();
-
-        // determine times at which sourcing is initialized and terminated
-        auto v_front = mb.template get< tag::front_speed >();
-        auto w_front = mb.template get< tag::front_width >();
-        auto tInit = mb.template get< tag::init_time >();
-
-        if (t >= tInit) {
-          // current radius of front
-          tk::real r_front = v_front * (t-tInit);
-          // arbitrary shape form
-          auto amplE = enc * v_front / w_front;
-
-          for (auto e : blkelems) {
-            std::array< tk::real, 3 > node{{ geoElem(e,1), geoElem(e,2),
-              geoElem(e,3) }};
-
-            auto r_e = std::sqrt(
-              (node[0]-x0_front[0])*(node[0]-x0_front[0]) +
-              (node[1]-x0_front[1])*(node[1]-x0_front[1]) +
-              (node[2]-x0_front[2])*(node[2]-x0_front[2]) );
-
-            // if element centroid lies within spherical shell add sources
-            if (r_e >= r_front && r_e <= r_front+w_front) {
-              // Add the source term to the rhs
-              R(e, energyDofIdx(nmat,blkmatid-1,1,0)) += geoElem(e,0) * amplE;
-              engSrcAdded[e] = 1;
-            }
-          }
-        }
-
-      }
-    }
-  }
-}
+  return s;
+}
+
+std::vector< std::array< tk::real, 3 > >
+TransportProblemCylVortex::prescribedVelocity( ncomp_t ncomp,
+  tk::real x, tk::real y, tk::real, tk::real t )
+// *****************************************************************************
+//! Assign prescribed velocity at a point
+//! \param[in] ncomp Number of components in this transport equation
+//! \param[in] x x coordinate at which to assign velocity
+//! \param[in] y y coordinate at which to assign velocity
+//! \param[in] t time at which to assign velocity
+//! \return Velocity assigned to all vertices of a tetrehedron, size:
+//!   ncomp * ndim = [ncomp][3]
+// *****************************************************************************
+{
+  std::vector< std::array< tk::real, 3 > > vel( ncomp );
+
+  auto pi = 4.0 * std::atan(1.0);
+  for (ncomp_t c=0; c<ncomp; ++c) {
+    vel[c][0] = - 2.0*std::cos(t*pi/4.0) * std::pow(std::sin(pi*x), 2)
+      * std::sin(pi*y) * std::cos(pi*y);
+    vel[c][1] = 2.0*std::cos(t*pi/4.0) * std::pow(std::sin(pi*y), 2)
+      * std::sin(pi*x) * std::cos(pi*x);
+    vel[c][2] = 0.0;
+  }
+
+  return vel;
+}
 
diff --git a/Release/cppcheck/cppcheck-report.xml b/Release/cppcheck/cppcheck-report.xml index efbc77ed449d..2702c7d561e6 100644 --- a/Release/cppcheck/cppcheck-report.xml +++ b/Release/cppcheck/cppcheck-report.xml @@ -29,6 +29,9 @@ + + + @@ -38,6 +41,9 @@ + + + @@ -47,9 +53,15 @@ + + + + + + @@ -59,29 +71,14 @@ - - - - - - - - - - - - - - - - - + + @@ -89,18 +86,39 @@ + + + + + + + + + + + + + + + + + + + + + @@ -143,36 +161,18 @@ - - - - - - - - - - - - - - - - - + + - - - @@ -209,36 +209,36 @@ - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + @@ -303,6 +303,28 @@ + + + + + + + + + + + + + + + + + + + + + + @@ -315,19 +337,12 @@ - - - - - - - - - + + @@ -341,53 +356,38 @@ - - - - - - - - - - - - - - - - - + + - - + + - - + + - - + + - - + + - - + + - - + + @@ -398,29 +398,11 @@ - - - - - - - - - - - - - - - - - - - - + + - - + + @@ -434,67 +416,184 @@ - - - - - - - - + + - - + + - - + + - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - + + - - + + + + + + + + + + + + + + + + + + + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + + + + + + + + + + + + + + + + @@ -519,6 +618,9 @@ + + + @@ -531,34 +633,40 @@ - - + + + + + - - + + - - + + - - + + + + + @@ -567,40 +675,22 @@ - - - - - - - - - - - - - - - - - - @@ -609,9 +699,6 @@ - - - @@ -680,9 +767,6 @@ - - - @@ -691,48 +775,18 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - @@ -745,31 +799,6 @@ - - - - - - - - - - - - - - - - - - - - - - - - - @@ -779,12 +808,6 @@ - - - - - - @@ -806,51 +829,24 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - @@ -872,9 +868,19 @@ + + + + + + + + + + @@ -893,17 +899,20 @@ - - + + - - + + - - + + - - + + + + + @@ -911,9 +920,6 @@ - - - @@ -926,15 +932,6 @@ - - - - - - - - - @@ -1006,6 +1003,9 @@ + + + @@ -1021,21 +1021,15 @@ - - - - - - - - - + + + @@ -1048,6 +1042,18 @@ + + + + + + + + + + + + @@ -1060,15 +1066,9 @@ - - - - - - diff --git a/Release/cppcheck/index.html b/Release/cppcheck/index.html index 28f9c7dd88bc..5476d1a9bcea 100644 --- a/Release/cppcheck/index.html +++ b/Release/cppcheck/index.html @@ -126,19 +126,19 @@

Cppcheck report - [

LineIdCWESeverityMessage
/tmp/TeamCity-1/work/5ad443c8abe7fc0a/src/Base/ContainerUtil.hpp
38unsignedPositive570styleUnsigned expression 'd' can't be negative so it is unnecessary to test it.
66throwInNoexceptFunction398errorException thrown in function declared not to throw exceptions.
81throwInNoexceptFunction398errorException thrown in function declared not to throw exceptions.
/tmp/TeamCity-1/work/5ad443c8abe7fc0a/src/Base/Data.hpp
484constParameter398styleParameter 'p' can be declared with const
/tmp/TeamCity-1/work/5ad443c8abe7fc0a/src/Base/ContainerUtil.hpp
38unsignedPositive570styleUnsigned expression 'd' can't be negative so it is unnecessary to test it.
66throwInNoexceptFunction398errorException thrown in function declared not to throw exceptions.
81throwInNoexceptFunction398errorException thrown in function declared not to throw exceptions.
/tmp/TeamCity-1/work/5ad443c8abe7fc0a/src/Base/Data.hpp
484constParameter398styleParameter 'p' can be declared with const
/tmp/TeamCity-1/work/5ad443c8abe7fc0a/src/Base/Exception.cpp
49syntaxErrorerrorsyntax error: keyword 'try' is not allowed in global scope
/tmp/TeamCity-1/work/5ad443c8abe7fc0a/src/Base/HashMapReducer.hpp
90knownEmptyContainer398styleIterating over container 'u' that is always empty.
/tmp/TeamCity-1/work/5ad443c8abe7fc0a/src/Base/TaggedTuple.hpp
121internalAstErrorerrorSyntax Error: AST broken, binary operator '>' doesn't have two operands.
174constParameter398styleParameter 'p' can be declared with const
/tmp/TeamCity-1/work/5ad443c8abe7fc0a/src/Base/HashMapReducer.hpp
90knownEmptyContainer398styleIterating over container 'u' that is always empty.
/tmp/TeamCity-1/work/5ad443c8abe7fc0a/src/Base/TaggedTuple.hpp
121internalAstErrorerrorSyntax Error: AST broken, binary operator '>' doesn't have two operands.
174constParameter398styleParameter 'p' can be declared with const
/tmp/TeamCity-1/work/5ad443c8abe7fc0a/src/Base/Types.hpp
37passedByValue398performanceFunction parameter 'k' should be passed by const reference.
38passedByValue398performanceFunction parameter 's' should be passed by const reference.
63passedByValue398performanceFunction parameter 'tDescr' should be passed by const reference.
/tmp/TeamCity-1/work/5ad443c8abe7fc0a/src/Base/Vector.hpp
182throwInNoexceptFunction398errorException thrown in function declared not to throw exceptions.
/tmp/TeamCity-1/work/5ad443c8abe7fc0a/src/Control/HelpFactory.hpp
51constParameter398styleParameter 'p' can be declared with const
84constParameter398styleParameter 'p' can be declared with const
/tmp/TeamCity-1/work/5ad443c8abe7fc0a/src/Control/Inciter/InputDeck/LuaParser.hpp
43passedByValue398performanceFunction parameter 'key' should be passed by const reference.
70passedByValue398performanceFunction parameter 'key' should be passed by const reference.
92passedByValue398performanceFunction parameter 'key' should be passed by const reference.
114passedByValue398performanceFunction parameter 'key' should be passed by const reference.
138passedByValue398performanceFunction parameter 'key' should be passed by const reference.
/tmp/TeamCity-1/work/5ad443c8abe7fc0a/src/Control/HelpFactory.hpp
51constParameter398styleParameter 'p' can be declared with const
84constParameter398styleParameter 'p' can be declared with const
/tmp/TeamCity-1/work/5ad443c8abe7fc0a/src/Control/Inciter/InputDeck/LuaParser.hpp
43passedByValue398performanceFunction parameter 'key' should be passed by const reference.
70passedByValue398performanceFunction parameter 'key' should be passed by const reference.
92passedByValue398performanceFunction parameter 'key' should be passed by const reference.
114passedByValue398performanceFunction parameter 'key' should be passed by const reference.
138passedByValue398performanceFunction parameter 'key' should be passed by const reference.
/tmp/TeamCity-1/work/5ad443c8abe7fc0a/src/Control/Inciter/OutVar.hpp
47constParameter398styleParameter 'p' can be declared with const
/tmp/TeamCity-1/work/5ad443c8abe7fc0a/src/Control/MeshConv/CmdLine/Parser.cpp
119unreadVariable563styleVariable 'oalias' is assigned a value that is never used.
/tmp/TeamCity-1/work/5ad443c8abe7fc0a/src/Control/MeshConv/CmdLine/Parser.cpp
119unreadVariable563styleVariable 'oalias' is assigned a value that is never used.
/tmp/TeamCity-1/work/5ad443c8abe7fc0a/src/Control/StatCtr.hpp
325constVariable398styleVariable 'kind' can be declared with const
/tmp/TeamCity-1/work/5ad443c8abe7fc0a/src/IO/ExodusIIMeshReader.cpp
25uninitMemberVar398warningMember variable 'ExodusIIMeshReader::m_nelem' is not initialized in the constructor.
338unreadVariable563styleVariable 'nnode' is assigned a value that is never used.
656useStlAlgorithm398styleConsider using std::transform algorithm instead of a raw loop.
899useStlAlgorithm398styleConsider using std::fill or std::generate algorithm instead of a raw loop.
948useStlAlgorithm398styleConsider using std::fill or std::generate algorithm instead of a raw loop.
/tmp/TeamCity-1/work/5ad443c8abe7fc0a/src/IO/MeshWriter.hpp
47uninitMemberVar398warningMember variable 'MeshWriter::m_filetype' is not initialized in the constructor.
47uninitMemberVar398warningMember variable 'MeshWriter::m_benchmark' is not initialized in the constructor.
47uninitMemberVar398warningMember variable 'MeshWriter::m_nmesh' is not initialized in the constructor.
/tmp/TeamCity-1/work/5ad443c8abe7fc0a/src/IO/Omega_h_MeshReader.cpp
134constParameter398styleParameter 'bface' can be declared with const
149constParameter398styleParameter 'bface' can be declared with const
150constParameter398styleParameter 'faces' can be declared with const
/tmp/TeamCity-1/work/5ad443c8abe7fc0a/src/IO/ExodusIIMeshReader.cpp
25uninitMemberVar398warningMember variable 'ExodusIIMeshReader::m_nelem' is not initialized in the constructor.
338unreadVariable563styleVariable 'nnode' is assigned a value that is never used.
656useStlAlgorithm398styleConsider using std::transform algorithm instead of a raw loop.
899useStlAlgorithm398styleConsider using std::fill or std::generate algorithm instead of a raw loop.
948useStlAlgorithm398styleConsider using std::fill or std::generate algorithm instead of a raw loop.
/tmp/TeamCity-1/work/5ad443c8abe7fc0a/src/IO/MeshWriter.hpp
47uninitMemberVar398warningMember variable 'MeshWriter::m_filetype' is not initialized in the constructor.
47uninitMemberVar398warningMember variable 'MeshWriter::m_benchmark' is not initialized in the constructor.
47uninitMemberVar398warningMember variable 'MeshWriter::m_nmesh' is not initialized in the constructor.
/tmp/TeamCity-1/work/5ad443c8abe7fc0a/src/IO/Omega_h_MeshReader.cpp
134constParameter398styleParameter 'bface' can be declared with const
149constParameter398styleParameter 'bface' can be declared with const
150constParameter398styleParameter 'faces' can be declared with const
/tmp/TeamCity-1/work/5ad443c8abe7fc0a/src/IO/PDFWriter.cpp
962unreadVariable563styleVariable 'nbix' is assigned a value that is never used.
962unreadVariable563styleVariable 'nbiy' is assigned a value that is never used.
1097unreadVariable563styleVariable 'nbix' is assigned a value that is never used.
1097unreadVariable563styleVariable 'nbiy' is assigned a value that is never used.
1097unreadVariable563styleVariable 'nbiz' is assigned a value that is never used.
/tmp/TeamCity-1/work/5ad443c8abe7fc0a/src/IO/UGRIDMeshReader.cpp
35unusedVariable563styleUnused variable: s
/tmp/TeamCity-1/work/5ad443c8abe7fc0a/src/Inciter/ALECG.cpp
120stlFindInsert398performanceSearching before insertion is not necessary.
122stlFindInsert398performanceSearching before insertion is not necessary.
160useStlAlgorithm398styleConsider using std::transform algorithm instead of a raw loop.
164useStlAlgorithm398styleConsider using std::transform algorithm instead of a raw loop.
792useStlAlgorithm398styleConsider using std::transform algorithm instead of a raw loop.
/tmp/TeamCity-1/work/5ad443c8abe7fc0a/src/IO/UGRIDMeshReader.cpp
35unusedVariable563styleUnused variable: s
/tmp/TeamCity-1/work/5ad443c8abe7fc0a/src/Inciter/ALECG.cpp
120stlFindInsert398performanceSearching before insertion is not necessary.
122stlFindInsert398performanceSearching before insertion is not necessary.
160useStlAlgorithm398styleConsider using std::transform algorithm instead of a raw loop.
164useStlAlgorithm398styleConsider using std::transform algorithm instead of a raw loop.
792useStlAlgorithm398styleConsider using std::transform algorithm instead of a raw loop.
/tmp/TeamCity-1/work/5ad443c8abe7fc0a/src/Inciter/AMR/edge_store.hpp
98assertWithSideEffect398warningAssert statement calls a function which may have desired side effects: 'exists'.
/tmp/TeamCity-1/work/5ad443c8abe7fc0a/src/Inciter/AMR/mesh_adapter.cpp
982constVariable398styleVariable 'element' can be declared with const
1477useStlAlgorithm398styleConsider using std::transform algorithm instead of a raw loop.
/tmp/TeamCity-1/work/5ad443c8abe7fc0a/src/Inciter/AMR/mesh_adapter.cpp
982constVariable398styleVariable 'element' can be declared with const
1477useStlAlgorithm398styleConsider using std::transform algorithm instead of a raw loop.
/tmp/TeamCity-1/work/5ad443c8abe7fc0a/src/Inciter/AMR/refinement.hpp
34noExplicitConstructor398styleClass 'refinement_t' has a constructor with 1 argument that is not explicit.
57constVariable398styleVariable 'master_element' can be declared with const
1131constVariable398styleVariable 'master_element' can be declared with const
/tmp/TeamCity-1/work/5ad443c8abe7fc0a/src/Inciter/AMR/tet_store.hpp
720constVariable398styleVariable 'parent' can be declared with const
/tmp/TeamCity-1/work/5ad443c8abe7fc0a/src/Inciter/DG.cpp
271unreadVariable563styleVariable 'd' is assigned a value that is never used.
1152unusedVariable563styleUnused variable: ndof
1628unreadVariable563styleVariable 'pn' is assigned a value that is never used.
1629unreadVariable563styleVariable 'unprop' is assigned a value that is never used.
1630unreadVariable563styleVariable 'pnprop' is assigned a value that is never used.
2271invalidPrintfArgType_uint686portability%lu in format string (no. 1) requires 'unsigned long' but the argument type is 'std::size_t {aka unsigned long}'.
2272invalidPrintfArgType_uint686portability%lu in format string (no. 1) requires 'unsigned long' but the argument type is 'std::size_t {aka unsigned long}'.
/tmp/TeamCity-1/work/5ad443c8abe7fc0a/src/Inciter/DiagReducer.cpp
72uninitvar457errorUninitialized variable: meshid
73uninitvar457errorUninitialized variable: ncomp
81uninitvar457errorUninitialized variable: mid
82uninitvar457errorUninitialized variable: nc
85uninitvar457errorUninitialized variable: mid
85unreadVariable563styleVariable 'meshid' is assigned a value that is never used.
86uninitvar457errorUninitialized variable: nc
86unreadVariable563styleVariable 'ncomp' is assigned a value that is never used.
91unsignedLessThanZero570styleChecking if unsigned expression 'i' is less than zero.
/tmp/TeamCity-1/work/5ad443c8abe7fc0a/src/Inciter/Discretization.cpp
291useStlAlgorithm398styleConsider using std::copy_if algorithm instead of a raw loop.
331unreadVariable563styleVariable 'fromMesh' is assigned a value that is never used.
332unreadVariable563styleVariable 'toMesh' is assigned a value that is never used.
333unreadVariable563styleVariable 'cb_xfer' is assigned a value that is never used.
336unreadVariable563styleVariable 'fromMesh' is assigned a value that is never used.
337unreadVariable563styleVariable 'toMesh' is assigned a value that is never used.
338unreadVariable563styleVariable 'cb_xfer' is assigned a value that is never used.
361redundantAssignment563styleVariable 'm_ndst' is reassigned a value before the old one has been used.
815useStlAlgorithm398styleConsider using std::accumulate algorithm instead of a raw loop.
/tmp/TeamCity-1/work/5ad443c8abe7fc0a/src/Inciter/DG.cpp
271unreadVariable563styleVariable 'd' is assigned a value that is never used.
1152unusedVariable563styleUnused variable: ndof
1628unreadVariable563styleVariable 'pn' is assigned a value that is never used.
1629unreadVariable563styleVariable 'unprop' is assigned a value that is never used.
1630unreadVariable563styleVariable 'pnprop' is assigned a value that is never used.
2271invalidPrintfArgType_uint686portability%lu in format string (no. 1) requires 'unsigned long' but the argument type is 'std::size_t {aka unsigned long}'.
2272invalidPrintfArgType_uint686portability%lu in format string (no. 1) requires 'unsigned long' but the argument type is 'std::size_t {aka unsigned long}'.
/tmp/TeamCity-1/work/5ad443c8abe7fc0a/src/Inciter/DiagReducer.cpp
72uninitvar457errorUninitialized variable: meshid
73uninitvar457errorUninitialized variable: ncomp
81uninitvar457errorUninitialized variable: mid
82uninitvar457errorUninitialized variable: nc
85uninitvar457errorUninitialized variable: mid
85unreadVariable563styleVariable 'meshid' is assigned a value that is never used.
86uninitvar457errorUninitialized variable: nc
86unreadVariable563styleVariable 'ncomp' is assigned a value that is never used.
91unsignedLessThanZero570styleChecking if unsigned expression 'i' is less than zero.
/tmp/TeamCity-1/work/5ad443c8abe7fc0a/src/Inciter/Discretization.cpp
291useStlAlgorithm398styleConsider using std::copy_if algorithm instead of a raw loop.
331unreadVariable563styleVariable 'fromMesh' is assigned a value that is never used.
332unreadVariable563styleVariable 'toMesh' is assigned a value that is never used.
333unreadVariable563styleVariable 'cb_xfer' is assigned a value that is never used.
336unreadVariable563styleVariable 'fromMesh' is assigned a value that is never used.
337unreadVariable563styleVariable 'toMesh' is assigned a value that is never used.
338unreadVariable563styleVariable 'cb_xfer' is assigned a value that is never used.
361redundantAssignment563styleVariable 'm_ndst' is reassigned a value before the old one has been used.
815useStlAlgorithm398styleConsider using std::accumulate algorithm instead of a raw loop.
/tmp/TeamCity-1/work/5ad443c8abe7fc0a/src/Inciter/ElemDiagnostics.cpp
118funcArgOrderDifferent683warningFunction 'compute_diag' argument order different: declaration 'd, ndofel, nchGhost, geoElem, pIndex, u, un, diag' definition 'd, rdof, nchGhost, geoElem, ndofel, u, un, diag'
187unmatchedSuppressioninformationUnmatched suppression: useStlAlgorithm
224unmatchedSuppressioninformationUnmatched suppression: useStlAlgorithm
/tmp/TeamCity-1/work/5ad443c8abe7fc0a/src/Inciter/FV.cpp
196unreadVariable563styleVariable 'd' is assigned a value that is never used.
823unreadVariable563styleVariable 'pn' is assigned a value that is never used.
824unreadVariable563styleVariable 'unprop' is assigned a value that is never used.
825unreadVariable563styleVariable 'pnprop' is assigned a value that is never used.
/tmp/TeamCity-1/work/5ad443c8abe7fc0a/src/Inciter/FV.cpp
196unreadVariable563styleVariable 'd' is assigned a value that is never used.
823unreadVariable563styleVariable 'pn' is assigned a value that is never used.
824unreadVariable563styleVariable 'unprop' is assigned a value that is never used.
825unreadVariable563styleVariable 'pnprop' is assigned a value that is never used.
/tmp/TeamCity-1/work/5ad443c8abe7fc0a/src/Inciter/FaceData.hpp
76constParameter398styleParameter 'p' can be declared with const
/tmp/TeamCity-1/work/5ad443c8abe7fc0a/src/Inciter/Ghosts.cpp
469unreadVariable563styleVariable 'ncoord' is assigned a value that is never used.
478unreadVariable563styleVariable 'e' is assigned a value that is never used.
551unreadVariable563styleVariable 'ncoord' is assigned a value that is never used.
944unmatchedSuppressioninformationUnmatched suppression: useStlAlgorithm
968unreadVariable563styleVariable 'ip' is assigned a value that is never used.
1053unreadVariable563styleVariable 'nmatch' is assigned a value that is never used.
/tmp/TeamCity-1/work/5ad443c8abe7fc0a/src/Inciter/Ghosts.hpp
101constParameter398styleParameter 'p' can be declared with const
/tmp/TeamCity-1/work/5ad443c8abe7fc0a/src/Inciter/OversetFE.cpp
120stlFindInsert398performanceSearching before insertion is not necessary.
122stlFindInsert398performanceSearching before insertion is not necessary.
828useStlAlgorithm398styleConsider using std::transform algorithm instead of a raw loop.
910useStlAlgorithm398styleConsider using std::transform algorithm instead of a raw loop.
914useStlAlgorithm398styleConsider using std::transform algorithm instead of a raw loop.
1367unreadVariable563styleVariable 'elemsurfnames' is assigned a value that is never used.
/tmp/TeamCity-1/work/5ad443c8abe7fc0a/src/Inciter/Ghosts.cpp
469unreadVariable563styleVariable 'ncoord' is assigned a value that is never used.
478unreadVariable563styleVariable 'e' is assigned a value that is never used.
551unreadVariable563styleVariable 'ncoord' is assigned a value that is never used.
944unmatchedSuppressioninformationUnmatched suppression: useStlAlgorithm
968unreadVariable563styleVariable 'ip' is assigned a value that is never used.
1053unreadVariable563styleVariable 'nmatch' is assigned a value that is never used.
/tmp/TeamCity-1/work/5ad443c8abe7fc0a/src/Inciter/Ghosts.hpp
101constParameter398styleParameter 'p' can be declared with const
/tmp/TeamCity-1/work/5ad443c8abe7fc0a/src/Inciter/OversetFE.cpp
120stlFindInsert398performanceSearching before insertion is not necessary.
122stlFindInsert398performanceSearching before insertion is not necessary.
828useStlAlgorithm398styleConsider using std::transform algorithm instead of a raw loop.
910useStlAlgorithm398styleConsider using std::transform algorithm instead of a raw loop.
914useStlAlgorithm398styleConsider using std::transform algorithm instead of a raw loop.
1367unreadVariable563styleVariable 'elemsurfnames' is assigned a value that is never used.
/tmp/TeamCity-1/work/5ad443c8abe7fc0a/src/Inciter/Partitioner.cpp
425variableScope398styleThe scope of the variable 'added' can be reduced.
/tmp/TeamCity-1/work/5ad443c8abe7fc0a/src/Inciter/Partitioner.hpp
79uninitMemberVar398warningMember variable 'Partitioner::m_meshid' is not initialized in the constructor.
79uninitMemberVar398warningMember variable 'Partitioner::m_ndist' is not initialized in the constructor.
79uninitMemberVar398warningMember variable 'Partitioner::m_nchare' is not initialized in the constructor.
/tmp/TeamCity-1/work/5ad443c8abe7fc0a/src/Inciter/Refiner.cpp
377unreadVariable563styleVariable 'chunksize' is assigned a value that is never used.
388unreadVariable563styleVariable 'B' is assigned a value that is never used.
389unreadVariable563styleVariable 'C' is assigned a value that is never used.
459useStlAlgorithm398styleConsider using std::copy_if algorithm instead of a raw loop.
663unreadVariable563styleVariable 'nlocked' is assigned a value that is never used.
678unreadVariable563styleVariable 'local_needs_refining_orig' is assigned a value that is never used.
679unreadVariable563styleVariable 'local_needs_derefining_orig' is assigned a value that is never used.
680unreadVariable563styleVariable 'local_lock_case_orig' is assigned a value that is never used.
751unreadVariable563styleVariable 'nlocked' is assigned a value that is never used.
989variableScope398styleThe scope of the variable 'V' can be reduced.
1532variableScope398styleThe scope of the variable 'V' can be reduced.
1728redundantIfRemove398styleRedundant checking of STL container element existence before removing it.
1798unreadVariable563styleVariable 'addedNodes' is assigned a value that is never used.
1803unreadVariable563styleVariable 'rid[l]' is assigned a value that is never used.
1930unreadVariable563styleVariable 'c' is assigned a value that is never used.
2008variableScope398styleThe scope of the variable 'facecnt' can be reduced.
/tmp/TeamCity-1/work/5ad443c8abe7fc0a/src/Inciter/Scheme.hpp
174constParameter398styleParameter 'p' can be declared with const
237constParameter398styleParameter 'p' can be declared with const
279constParameter398styleParameter 'p' can be declared with const
/tmp/TeamCity-1/work/5ad443c8abe7fc0a/src/Inciter/Sorter.cpp
127unreadVariable563styleVariable 'scheme' is assigned a value that is never used.
570useStlAlgorithm398styleConsider using std::transform algorithm instead of a raw loop.
/tmp/TeamCity-1/work/5ad443c8abe7fc0a/src/Inciter/Transporter.cpp
165useStlAlgorithm398styleConsider using std::transform algorithm instead of a raw loop.
176useStlAlgorithm398styleConsider using std::transform algorithm instead of a raw loop.
1283uninitvar457errorUninitialized variable: meshid
1287uninitvar457errorUninitialized variable: meshid
1299containerOutOfBounds398errorOut of bounds access in expression 'pdf[1]' because 'pdf' is empty.
1305containerOutOfBounds398errorOut of bounds access in expression 'pdf[2]' because 'pdf' is empty.
1472uninitvar457errorUninitialized variable: meshid
1473uninitvar457errorUninitialized variable: ncomp
1477uninitvar457errorUninitialized variable: meshid
1477unreadVariable563styleVariable 'id' is assigned a value that is never used.
1479uninitvar457errorUninitialized variable: ncomp
1482unsignedLessThanZero570styleChecking if unsigned expression 'i' is less than zero.
1491uninitvar457errorUninitialized variable: meshid
1496unreadVariable563styleVariable 'n' is assigned a value that is never used.
1497unreadVariable563styleVariable 'n' is assigned a value that is never used.
1501uninitvar457errorUninitialized variable: meshid
1513uninitvar457errorUninitialized variable: meshid
1537uninitvar457errorUninitialized variable: meshid
/tmp/TeamCity-1/work/5ad443c8abe7fc0a/src/Inciter/Refiner.cpp
377unreadVariable563styleVariable 'chunksize' is assigned a value that is never used.
388unreadVariable563styleVariable 'B' is assigned a value that is never used.
389unreadVariable563styleVariable 'C' is assigned a value that is never used.
459useStlAlgorithm398styleConsider using std::copy_if algorithm instead of a raw loop.
663unreadVariable563styleVariable 'nlocked' is assigned a value that is never used.
678unreadVariable563styleVariable 'local_needs_refining_orig' is assigned a value that is never used.
679unreadVariable563styleVariable 'local_needs_derefining_orig' is assigned a value that is never used.
680unreadVariable563styleVariable 'local_lock_case_orig' is assigned a value that is never used.
751unreadVariable563styleVariable 'nlocked' is assigned a value that is never used.
989variableScope398styleThe scope of the variable 'V' can be reduced.
1532variableScope398styleThe scope of the variable 'V' can be reduced.
1728redundantIfRemove398styleRedundant checking of STL container element existence before removing it.
1798unreadVariable563styleVariable 'addedNodes' is assigned a value that is never used.
1803unreadVariable563styleVariable 'rid[l]' is assigned a value that is never used.
1930unreadVariable563styleVariable 'c' is assigned a value that is never used.
2008variableScope398styleThe scope of the variable 'facecnt' can be reduced.
/tmp/TeamCity-1/work/5ad443c8abe7fc0a/src/Inciter/Scheme.hpp
174constParameter398styleParameter 'p' can be declared with const
237constParameter398styleParameter 'p' can be declared with const
279constParameter398styleParameter 'p' can be declared with const
/tmp/TeamCity-1/work/5ad443c8abe7fc0a/src/Inciter/Sorter.cpp
127unreadVariable563styleVariable 'scheme' is assigned a value that is never used.
570useStlAlgorithm398styleConsider using std::transform algorithm instead of a raw loop.
/tmp/TeamCity-1/work/5ad443c8abe7fc0a/src/Inciter/Transporter.cpp
165useStlAlgorithm398styleConsider using std::transform algorithm instead of a raw loop.
176useStlAlgorithm398styleConsider using std::transform algorithm instead of a raw loop.
1283uninitvar457errorUninitialized variable: meshid
1287uninitvar457errorUninitialized variable: meshid
1299containerOutOfBounds398errorOut of bounds access in expression 'pdf[1]' because 'pdf' is empty.
1305containerOutOfBounds398errorOut of bounds access in expression 'pdf[2]' because 'pdf' is empty.
1472uninitvar457errorUninitialized variable: meshid
1473uninitvar457errorUninitialized variable: ncomp
1477uninitvar457errorUninitialized variable: meshid
1477unreadVariable563styleVariable 'id' is assigned a value that is never used.
1479uninitvar457errorUninitialized variable: ncomp
1482unsignedLessThanZero570styleChecking if unsigned expression 'i' is less than zero.
1491uninitvar457errorUninitialized variable: meshid
1496unreadVariable563styleVariable 'n' is assigned a value that is never used.
1497unreadVariable563styleVariable 'n' is assigned a value that is never used.
1501uninitvar457errorUninitialized variable: meshid
1513uninitvar457errorUninitialized variable: meshid
1537uninitvar457errorUninitialized variable: meshid
/tmp/TeamCity-1/work/5ad443c8abe7fc0a/src/LinearSolver/CSR.cpp
21syntaxErrorerrorsyntax error: keyword 'try' is not allowed in global scope
/tmp/TeamCity-1/work/5ad443c8abe7fc0a/src/LinearSolver/CSR.hpp
83constParameter398styleParameter 'p' can be declared with const
/tmp/TeamCity-1/work/5ad443c8abe7fc0a/src/LinearSolver/ConjugateGradients.cpp
35uninitMemberVar398warningMember variable 'ConjugateGradients::m_tol' is not initialized in the constructor.
216useStlAlgorithm398styleConsider using std::transform algorithm instead of a raw loop.
/tmp/TeamCity-1/work/5ad443c8abe7fc0a/src/LinearSolver/ConjugateGradients.hpp
66uninitMemberVar398warningMember variable 'ConjugateGradients::m_tol' is not initialized in the constructor.
79uninitMemberVar398warningMember variable 'ConjugateGradients::m_nr' is not initialized in the constructor.
79uninitMemberVar398warningMember variable 'ConjugateGradients::m_nb' is not initialized in the constructor.
79uninitMemberVar398warningMember variable 'ConjugateGradients::m_nq' is not initialized in the constructor.
79uninitMemberVar398warningMember variable 'ConjugateGradients::m_normb' is not initialized in the constructor.
79uninitMemberVar398warningMember variable 'ConjugateGradients::m_it' is not initialized in the constructor.
79uninitMemberVar398warningMember variable 'ConjugateGradients::m_maxit' is not initialized in the constructor.
79uninitMemberVar398warningMember variable 'ConjugateGradients::m_tol' is not initialized in the constructor.
79uninitMemberVar398warningMember variable 'ConjugateGradients::m_rho' is not initialized in the constructor.
79uninitMemberVar398warningMember variable 'ConjugateGradients::m_rho0' is not initialized in the constructor.
79uninitMemberVar398warningMember variable 'ConjugateGradients::m_alpha' is not initialized in the constructor.
79uninitMemberVar398warningMember variable 'ConjugateGradients::m_converged' is not initialized in the constructor.
79uninitMemberVar398warningMember variable 'ConjugateGradients::m_nx' is not initialized in the constructor.
/tmp/TeamCity-1/work/5ad443c8abe7fc0a/src/Main/Inciter.cpp
188unmatchedSuppressioninformationUnmatched suppression: noConstructor
209noExplicitConstructor398styleClass 'Main' has a constructor with 1 argument that is not explicit.
/tmp/TeamCity-1/work/5ad443c8abe7fc0a/src/Main/InciterPrint.hpp
114unusedPrivateFunction398styleUnused private function: 'InciterPrint::PDEName'
/tmp/TeamCity-1/work/5ad443c8abe7fc0a/src/Main/MeshConv.cpp
58unmatchedSuppressioninformationUnmatched suppression: noConstructor
77noExplicitConstructor398styleClass 'Main' has a constructor with 1 argument that is not explicit.
/tmp/TeamCity-1/work/5ad443c8abe7fc0a/src/Main/MeshConvDriver.cpp
40useInitializationList398performanceVariable 'm_input' is assigned in constructor body. Consider performing initialization in initialization list.
42useInitializationList398performanceVariable 'm_output' is assigned in constructor body. Consider performing initialization in initialization list.
/tmp/TeamCity-1/work/5ad443c8abe7fc0a/src/Main/UnitTest.cpp
120unmatchedSuppressioninformationUnmatched suppression: noConstructor
142noExplicitConstructor398styleClass 'Main' has a constructor with 1 argument that is not explicit.
/tmp/TeamCity-1/work/5ad443c8abe7fc0a/src/LinearSolver/CSR.hpp
83constParameter398styleParameter 'p' can be declared with const
/tmp/TeamCity-1/work/5ad443c8abe7fc0a/src/LinearSolver/ConjugateGradients.cpp
35uninitMemberVar398warningMember variable 'ConjugateGradients::m_tol' is not initialized in the constructor.
216useStlAlgorithm398styleConsider using std::transform algorithm instead of a raw loop.
/tmp/TeamCity-1/work/5ad443c8abe7fc0a/src/LinearSolver/ConjugateGradients.hpp
66uninitMemberVar398warningMember variable 'ConjugateGradients::m_tol' is not initialized in the constructor.
79uninitMemberVar398warningMember variable 'ConjugateGradients::m_nr' is not initialized in the constructor.
79uninitMemberVar398warningMember variable 'ConjugateGradients::m_nb' is not initialized in the constructor.
79uninitMemberVar398warningMember variable 'ConjugateGradients::m_nq' is not initialized in the constructor.
79uninitMemberVar398warningMember variable 'ConjugateGradients::m_normb' is not initialized in the constructor.
79uninitMemberVar398warningMember variable 'ConjugateGradients::m_it' is not initialized in the constructor.
79uninitMemberVar398warningMember variable 'ConjugateGradients::m_maxit' is not initialized in the constructor.
79uninitMemberVar398warningMember variable 'ConjugateGradients::m_tol' is not initialized in the constructor.
79uninitMemberVar398warningMember variable 'ConjugateGradients::m_rho' is not initialized in the constructor.
79uninitMemberVar398warningMember variable 'ConjugateGradients::m_rho0' is not initialized in the constructor.
79uninitMemberVar398warningMember variable 'ConjugateGradients::m_alpha' is not initialized in the constructor.
79uninitMemberVar398warningMember variable 'ConjugateGradients::m_converged' is not initialized in the constructor.
79uninitMemberVar398warningMember variable 'ConjugateGradients::m_nx' is not initialized in the constructor.
/tmp/TeamCity-1/work/5ad443c8abe7fc0a/src/Main/Inciter.cpp
188unmatchedSuppressioninformationUnmatched suppression: noConstructor
209noExplicitConstructor398styleClass 'Main' has a constructor with 1 argument that is not explicit.
/tmp/TeamCity-1/work/5ad443c8abe7fc0a/src/Main/InciterPrint.hpp
114unusedPrivateFunction398styleUnused private function: 'InciterPrint::PDEName'
/tmp/TeamCity-1/work/5ad443c8abe7fc0a/src/Main/MeshConv.cpp
58unmatchedSuppressioninformationUnmatched suppression: noConstructor
77noExplicitConstructor398styleClass 'Main' has a constructor with 1 argument that is not explicit.
/tmp/TeamCity-1/work/5ad443c8abe7fc0a/src/Main/MeshConvDriver.cpp
40useInitializationList398performanceVariable 'm_input' is assigned in constructor body. Consider performing initialization in initialization list.
42useInitializationList398performanceVariable 'm_output' is assigned in constructor body. Consider performing initialization in initialization list.
/tmp/TeamCity-1/work/5ad443c8abe7fc0a/src/Main/UnitTest.cpp
120unmatchedSuppressioninformationUnmatched suppression: noConstructor
142noExplicitConstructor398styleClass 'Main' has a constructor with 1 argument that is not explicit.
/tmp/TeamCity-1/work/5ad443c8abe7fc0a/src/Mesh/DerivedData.cpp
305constVariable398styleVariable 'esup1' can be declared with const
306constVariable398styleVariable 'esup2' can be declared with const
1175unreadVariable563styleVariable 'nnpe' is assigned a value that is never used.
1175unreadVariable563styleVariable 'nnpf' is assigned a value that is never used.
1245unreadVariable563styleVariable 'tag' is assigned a value that is never used.
/tmp/TeamCity-1/work/5ad443c8abe7fc0a/src/Mesh/Reorder.cpp
157useStlAlgorithm398styleConsider using std::transform algorithm instead of a raw loop.
/tmp/TeamCity-1/work/5ad443c8abe7fc0a/src/PDE/CompFlow/CGCompFlow.hpp
722unreadVariable563styleVariable 'steady' is assigned a value that is never used.
866constParameter398styleParameter 'U' can be declared with const
1494constParameter398styleParameter 'R' can be declared with const
/tmp/TeamCity-1/work/5ad443c8abe7fc0a/src/PDE/CompFlow/DGCompFlow.hpp
299unreadVariable563styleVariable 'nelem' is assigned a value that is never used.
637unreadVariable563styleVariable 'dSV_l' is assigned a value that is never used.
754unreadVariable563styleVariable 'dgp' is assigned a value that is never used.
1094knownConditionTrueFalse571styleCondition 'fM>-1' is always true
1094knownConditionTrueFalse570styleCondition 'fM<0' is always false
1106knownConditionTrueFalse571styleCondition 'fM>=0' is always true
1158unreadVariable563styleVariable 'ndof' is assigned a value that is never used.
/tmp/TeamCity-1/work/5ad443c8abe7fc0a/src/PDE/ConfigureCompFlow.cpp
76unreadVariable563styleVariable 'c' is assigned a value that is never used.
159useStlAlgorithm398styleConsider using std::transform algorithm instead of a raw loop.
/tmp/TeamCity-1/work/5ad443c8abe7fc0a/src/PDE/ConfigureMultiMat.cpp
76unreadVariable563styleVariable 'c' is assigned a value that is never used.
/tmp/TeamCity-1/work/5ad443c8abe7fc0a/src/PDE/ConfigureTransport.cpp
74unreadVariable563styleVariable 'c' is assigned a value that is never used.
/tmp/TeamCity-1/work/5ad443c8abe7fc0a/src/PDE/DGPDE.hpp
65unreadVariable563styleVariable 'cfg' is assigned a value that is never used.
/tmp/TeamCity-1/work/5ad443c8abe7fc0a/src/Mesh/Reorder.cpp
157useStlAlgorithm398styleConsider using std::transform algorithm instead of a raw loop.
/tmp/TeamCity-1/work/5ad443c8abe7fc0a/src/PDE/CompFlow/CGCompFlow.hpp
722unreadVariable563styleVariable 'steady' is assigned a value that is never used.
866constParameter398styleParameter 'U' can be declared with const
1494constParameter398styleParameter 'R' can be declared with const
/tmp/TeamCity-1/work/5ad443c8abe7fc0a/src/PDE/CompFlow/DGCompFlow.hpp
299unreadVariable563styleVariable 'nelem' is assigned a value that is never used.
637unreadVariable563styleVariable 'dSV_l' is assigned a value that is never used.
754unreadVariable563styleVariable 'dgp' is assigned a value that is never used.
1094knownConditionTrueFalse571styleCondition 'fM>-1' is always true
1094knownConditionTrueFalse570styleCondition 'fM<0' is always false
1106knownConditionTrueFalse571styleCondition 'fM>=0' is always true
1158unreadVariable563styleVariable 'ndof' is assigned a value that is never used.
/tmp/TeamCity-1/work/5ad443c8abe7fc0a/src/PDE/ConfigureCompFlow.cpp
76unreadVariable563styleVariable 'c' is assigned a value that is never used.
159useStlAlgorithm398styleConsider using std::transform algorithm instead of a raw loop.
/tmp/TeamCity-1/work/5ad443c8abe7fc0a/src/PDE/ConfigureMultiMat.cpp
76unreadVariable563styleVariable 'c' is assigned a value that is never used.
/tmp/TeamCity-1/work/5ad443c8abe7fc0a/src/PDE/ConfigureTransport.cpp
74unreadVariable563styleVariable 'c' is assigned a value that is never used.
/tmp/TeamCity-1/work/5ad443c8abe7fc0a/src/PDE/DGPDE.hpp
65unreadVariable563styleVariable 'cfg' is assigned a value that is never used.
/tmp/TeamCity-1/work/5ad443c8abe7fc0a/src/PDE/EoS/EOS.hpp
118constParameter398styleParameter 'p' can be declared with const
/tmp/TeamCity-1/work/5ad443c8abe7fc0a/src/PDE/EoS/JWL.cpp
365knownConditionTrueFalse570styleCondition 'idebug==1' is always false
/tmp/TeamCity-1/work/5ad443c8abe7fc0a/src/PDE/Integrate/Basis.cpp
239duplicateAssignExpression398styleSame expression used in consecutive assignments of 'db5dxi2' and 'db5dxi3'.
/tmp/TeamCity-1/work/5ad443c8abe7fc0a/src/PDE/Integrate/Boundary.cpp
99unreadVariable563styleVariable 'ncomp' is assigned a value that is never used.
100unreadVariable563styleVariable 'nprim' is assigned a value that is never used.
177unreadVariable563styleVariable 'wt' is assigned a value that is never used.
217constParameter398styleParameter 'R' can be declared with const
349unreadVariable563styleVariable 'ncomp' is assigned a value that is never used.
350unreadVariable563styleVariable 'nprim' is assigned a value that is never used.
/tmp/TeamCity-1/work/5ad443c8abe7fc0a/src/PDE/Integrate/Initialize.cpp
164constParameter398styleParameter 'unk' can be declared with const
/tmp/TeamCity-1/work/5ad443c8abe7fc0a/src/PDE/Integrate/Basis.cpp
239duplicateAssignExpression398styleSame expression used in consecutive assignments of 'db5dxi2' and 'db5dxi3'.
/tmp/TeamCity-1/work/5ad443c8abe7fc0a/src/PDE/Integrate/Boundary.cpp
99unreadVariable563styleVariable 'ncomp' is assigned a value that is never used.
100unreadVariable563styleVariable 'nprim' is assigned a value that is never used.
177unreadVariable563styleVariable 'wt' is assigned a value that is never used.
217constParameter398styleParameter 'R' can be declared with const
349unreadVariable563styleVariable 'ncomp' is assigned a value that is never used.
350unreadVariable563styleVariable 'nprim' is assigned a value that is never used.
/tmp/TeamCity-1/work/5ad443c8abe7fc0a/src/PDE/Integrate/Initialize.cpp
164constParameter398styleParameter 'unk' can be declared with const
/tmp/TeamCity-1/work/5ad443c8abe7fc0a/src/PDE/Integrate/Mass.cpp
32unreadVariable563styleVariable 'nelem' is assigned a value that is never used.
/tmp/TeamCity-1/work/5ad443c8abe7fc0a/src/PDE/Integrate/MultiMatTerms.cpp
596constParameter398styleParameter 'R' can be declared with const
887unreadVariable563styleVariable 'rho' is assigned a value that is never used.
889unreadVariable563styleVariable 'rho' is assigned a value that is never used.
/tmp/TeamCity-1/work/5ad443c8abe7fc0a/src/PDE/Integrate/MultiMatTerms.cpp
596constParameter398styleParameter 'R' can be declared with const
887unreadVariable563styleVariable 'rho' is assigned a value that is never used.
889unreadVariable563styleVariable 'rho' is assigned a value that is never used.
/tmp/TeamCity-1/work/5ad443c8abe7fc0a/src/PDE/Integrate/SolidTerms.cpp
169constParameter398styleParameter 'R' can be declared with const
/tmp/TeamCity-1/work/5ad443c8abe7fc0a/src/PDE/Integrate/Source.cpp
149constParameter398styleParameter 'R' can be declared with const
/tmp/TeamCity-1/work/5ad443c8abe7fc0a/src/PDE/Integrate/Surface.cpp
93unreadVariable563styleVariable 'ncomp' is assigned a value that is never used.
94unreadVariable563styleVariable 'nprim' is assigned a value that is never used.
203unreadVariable563styleVariable 'wt' is assigned a value that is never used.
243constParameter398styleParameter 'R' can be declared with const
396unreadVariable563styleVariable 'ncomp' is assigned a value that is never used.
397unreadVariable563styleVariable 'nprim' is assigned a value that is never used.
/tmp/TeamCity-1/work/5ad443c8abe7fc0a/src/PDE/Integrate/Source.cpp
149constParameter398styleParameter 'R' can be declared with const
/tmp/TeamCity-1/work/5ad443c8abe7fc0a/src/PDE/Integrate/Surface.cpp
93unreadVariable563styleVariable 'ncomp' is assigned a value that is never used.
94unreadVariable563styleVariable 'nprim' is assigned a value that is never used.
203unreadVariable563styleVariable 'wt' is assigned a value that is never used.
243constParameter398styleParameter 'R' can be declared with const
396unreadVariable563styleVariable 'ncomp' is assigned a value that is never used.
397unreadVariable563styleVariable 'nprim' is assigned a value that is never used.
/tmp/TeamCity-1/work/5ad443c8abe7fc0a/src/PDE/Limiter.cpp
188unusedVariable563styleUnused variable: unk
188unusedVariable563styleUnused variable: prim
1375shadowFunction398styleLocal variable 'nmat' shadows outer function
1409shadowFunction398styleLocal variable 'nmat' shadows outer function
1434shadowFunction398styleLocal variable 'nmat' shadows outer function
/tmp/TeamCity-1/work/5ad443c8abe7fc0a/src/PDE/MultiMat/FVMultiMat.hpp
91shadowFunction398styleLocal variable 'nmat' shadows outer function
204constParameter398styleParameter 'l' can be declared with const
221constParameter398styleParameter 'prim' can be declared with const
224unreadVariable563styleVariable 'rdof' is assigned a value that is never used.
225shadowFunction398styleLocal variable 'nmat' shadows outer function
225unreadVariable563styleVariable 'nmat' is assigned a value that is never used.
296shadowFunction398styleLocal variable 'nmat' shadows outer function
296unreadVariable563styleVariable 'nmat' is assigned a value that is never used.
331unreadVariable563styleVariable 'nelem' is assigned a value that is never used.
332shadowFunction398styleLocal variable 'nmat' shadows outer function
332unreadVariable563styleVariable 'nmat' is assigned a value that is never used.
397shadowFunction398styleLocal variable 'nmat' shadows outer function
435shadowFunction398styleLocal variable 'nmat' shadows outer function
435unreadVariable563styleVariable 'nmat' is assigned a value that is never used.
475shadowFunction398styleLocal variable 'nmat' shadows outer function
553shadowFunction398styleLocal variable 'nmat' shadows outer function
573shadowFunction398styleLocal variable 'nmat' shadows outer function
609shadowFunction398styleLocal variable 'nmat' shadows outer function
632shadowFunction398styleLocal variable 'nmat' shadows outer function
654shadowFunction398styleLocal variable 'nmat' shadows outer function
704shadowFunction398styleLocal variable 'nmat' shadows outer function
735shadowFunction398styleLocal variable 'nmat' shadows outer function
762shadowFunction398styleLocal variable 'nmat' shadows outer function
764shadowFunction398styleLocal variable 'nprim' shadows outer function
766unreadVariable563styleVariable 'ugp' is assigned a value that is never used.
766unreadVariable563styleVariable 'pgp' is assigned a value that is never used.
831shadowFunction398styleLocal variable 'nmat' shadows outer function
855shadowFunction398styleLocal variable 'nmat' shadows outer function
855unreadVariable563styleVariable 'nmat' is assigned a value that is never used.
/tmp/TeamCity-1/work/5ad443c8abe7fc0a/src/PDE/MultiMat/FVMultiMat.hpp
91shadowFunction398styleLocal variable 'nmat' shadows outer function
204constParameter398styleParameter 'l' can be declared with const
221constParameter398styleParameter 'prim' can be declared with const
224unreadVariable563styleVariable 'rdof' is assigned a value that is never used.
225shadowFunction398styleLocal variable 'nmat' shadows outer function
225unreadVariable563styleVariable 'nmat' is assigned a value that is never used.
296shadowFunction398styleLocal variable 'nmat' shadows outer function
296unreadVariable563styleVariable 'nmat' is assigned a value that is never used.
331unreadVariable563styleVariable 'nelem' is assigned a value that is never used.
332shadowFunction398styleLocal variable 'nmat' shadows outer function
332unreadVariable563styleVariable 'nmat' is assigned a value that is never used.
397shadowFunction398styleLocal variable 'nmat' shadows outer function
435shadowFunction398styleLocal variable 'nmat' shadows outer function
435unreadVariable563styleVariable 'nmat' is assigned a value that is never used.
475shadowFunction398styleLocal variable 'nmat' shadows outer function
553shadowFunction398styleLocal variable 'nmat' shadows outer function
573shadowFunction398styleLocal variable 'nmat' shadows outer function
609shadowFunction398styleLocal variable 'nmat' shadows outer function
632shadowFunction398styleLocal variable 'nmat' shadows outer function
654shadowFunction398styleLocal variable 'nmat' shadows outer function
704shadowFunction398styleLocal variable 'nmat' shadows outer function
735shadowFunction398styleLocal variable 'nmat' shadows outer function
762shadowFunction398styleLocal variable 'nmat' shadows outer function
764shadowFunction398styleLocal variable 'nprim' shadows outer function
766unreadVariable563styleVariable 'ugp' is assigned a value that is never used.
766unreadVariable563styleVariable 'pgp' is assigned a value that is never used.
831shadowFunction398styleLocal variable 'nmat' shadows outer function
855shadowFunction398styleLocal variable 'nmat' shadows outer function
855unreadVariable563styleVariable 'nmat' is assigned a value that is never used.
/tmp/TeamCity-1/work/5ad443c8abe7fc0a/src/PDE/MultiMat/MiscMultiMatFns.cpp
370variableScope398styleThe scope of the variable 'u' can be reduced.
370variableScope398styleThe scope of the variable 'v' can be reduced.
501unreadVariable563styleVariable 'pgp' is assigned a value that is never used.
568constParameter398styleParameter 'U' can be declared with const
569constParameter398styleParameter 'P' can be declared with const
/tmp/TeamCity-1/work/5ad443c8abe7fc0a/src/PDE/MultiMat/Physics/FVEnergyPill.cpp
77constParameter398styleParameter 'R' can be declared with const
/tmp/TeamCity-1/work/5ad443c8abe7fc0a/src/PDE/MultiMat/Problem/BoxInitialization.hpp
102identicalConditionAfterEarlyExit398warningIdentical condition 'boxenc<=1e-12', second condition is always false
/tmp/TeamCity-1/work/5ad443c8abe7fc0a/src/PDE/MultiMat/Physics/FVEnergyPill.cpp
77constParameter398styleParameter 'R' can be declared with const
/tmp/TeamCity-1/work/5ad443c8abe7fc0a/src/PDE/MultiMat/Problem/BoxInitialization.hpp
102identicalConditionAfterEarlyExit398warningIdentical condition 'boxenc<=1e-12', second condition is always false
/tmp/TeamCity-1/work/5ad443c8abe7fc0a/src/PDE/MultiMat/Problem/ShockDensityWave.cpp
53variableScope398styleThe scope of the variable 'alphamin' can be reduced.
/tmp/TeamCity-1/work/5ad443c8abe7fc0a/src/PDE/PDEStack.hpp
/tmp/TeamCity-1/work/5ad443c8abe7fc0a/src/PDE/PrefIndicator.cpp
147unreadVariable563styleVariable 'ncomp' is assigned a value that is never used.
227unreadVariable563styleVariable 'state[1]' is assigned a value that is never used.
/tmp/TeamCity-1/work/5ad443c8abe7fc0a/src/PDE/Reconstruction.cpp
139unreadVariable563styleVariable 'nelem' is assigned a value that is never used.
276constParameter398styleParameter 'W' can be declared with const
316constParameter398styleParameter 'W' can be declared with const
397constParameter398styleParameter 'W' can be declared with const
/tmp/TeamCity-1/work/5ad443c8abe7fc0a/src/PDE/Transport/CGTransport.hpp
375unreadVariable563styleVariable 'steady' is assigned a value that is never used.
/tmp/TeamCity-1/work/5ad443c8abe7fc0a/src/PDE/Transport/DGTransport.hpp
239unreadVariable563styleVariable 'nelem' is assigned a value that is never used.
240unreadVariable563styleVariable 'intsharp' is assigned a value that is never used.
388unreadVariable563styleVariable 'ndof' is assigned a value that is never used.
389unreadVariable563styleVariable 'rdof' is assigned a value that is never used.
390unreadVariable563styleVariable 'intsharp' is assigned a value that is never used.
/tmp/TeamCity-1/work/5ad443c8abe7fc0a/src/PDE/Transport/Problem/CylVortex.cpp
38unreadVariable563styleVariable 'vel' is assigned a value that is never used.
/tmp/TeamCity-1/work/5ad443c8abe7fc0a/src/PDE/Reconstruction.cpp
139unreadVariable563styleVariable 'nelem' is assigned a value that is never used.
276constParameter398styleParameter 'W' can be declared with const
316constParameter398styleParameter 'W' can be declared with const
397constParameter398styleParameter 'W' can be declared with const
/tmp/TeamCity-1/work/5ad443c8abe7fc0a/src/PDE/Transport/CGTransport.hpp
375unreadVariable563styleVariable 'steady' is assigned a value that is never used.
/tmp/TeamCity-1/work/5ad443c8abe7fc0a/src/PDE/Transport/DGTransport.hpp
239unreadVariable563styleVariable 'nelem' is assigned a value that is never used.
240unreadVariable563styleVariable 'intsharp' is assigned a value that is never used.
388unreadVariable563styleVariable 'ndof' is assigned a value that is never used.
389unreadVariable563styleVariable 'rdof' is assigned a value that is never used.
390unreadVariable563styleVariable 'intsharp' is assigned a value that is never used.
/tmp/TeamCity-1/work/5ad443c8abe7fc0a/src/PDE/Transport/Problem/CylVortex.cpp
38unreadVariable563styleVariable 'vel' is assigned a value that is never used.
/tmp/TeamCity-1/work/5ad443c8abe7fc0a/src/Statistics/BiPDF.hpp
114constParameter398styleParameter 'p' can be declared with const
/tmp/TeamCity-1/work/5ad443c8abe7fc0a/src/Statistics/PDFReducer.cpp
Date:2024-07-10 11:26:062024-07-11 14:48:26 Functions: 3
Date:2024-07-10 11:26:062024-07-11 14:48:26 Functions: 3
Date:2024-07-10 11:26:062024-07-11 14:48:26 Functions: 3
Date:2024-07-10 11:26:062024-07-11 14:48:26 Functions: 3
Date:2024-07-10 11:26:062024-07-11 14:48:26 Functions: 3
Date:2024-07-10 11:26:062024-07-11 14:48:26 Functions: 3
Date:2024-07-10 11:26:062024-07-11 14:48:26 Functions: 60
Date:2024-07-10 11:26:062024-07-11 14:48:26 Functions: 60
Date:2024-07-10 11:26:062024-07-11 14:48:26 Functions: 60
Date:2024-07-10 11:26:062024-07-11 14:48:26 Functions: 30
tk::Data<(unsigned char)0>::pup(PUP::er&)303630299163
tk::Data<(unsigned char)0>::extract(unsigned long, std::array<unsigned long, 4ul> const&) const
Date:2024-07-10 11:26:062024-07-11 14:48:26 Functions: 30
tk::Data<(unsigned char)0>::pup(PUP::er&)303630299163
tk::Data<(unsigned char)1>::operator=(std::vector<double, std::allocator<double> > const&)
Date:2024-07-10 11:26:062024-07-11 14:48:26 Functions: 30
Date:2024-07-10 11:26:062024-07-11 14:48:26 Functions: 147
Date:2024-07-10 11:26:062024-07-11 14:48:26 Functions: 147
Date:2024-07-10 11:26:062024-07-11 14:48:26 Functions: 147
Date:2024-07-10 11:26:062024-07-11 14:48:26 Functions: 3
Date:2024-07-10 11:26:062024-07-11 14:48:26 Functions: 3
Date:2024-07-10 11:26:062024-07-11 14:48:26 Functions: 3
Date:2024-07-10 11:26:062024-07-11 14:48:26 Functions: 1
Date:2024-07-10 11:26:062024-07-11 14:48:26 Functions: 1
Date:2024-07-10 11:26:062024-07-11 14:48:26 Functions: 1
Date:2024-07-10 11:26:062024-07-11 14:48:26 Functions: 93
Date:2024-07-10 11:26:062024-07-11 14:48:26 Functions: 93
Date:2024-07-10 11:26:062024-07-11 14:48:26 Functions: 93
Date:2024-07-10 11:26:062024-07-11 14:48:26 Functions: 2
Date:2024-07-10 11:26:062024-07-11 14:48:26 Functions: 2
Date:2024-07-10 11:26:062024-07-11 14:48:26 Functions: 2
Date:2024-07-10 11:26:062024-07-11 14:48:26 Functions: 2
Date:2024-07-10 11:26:062024-07-11 14:48:26 Functions: 2
Date:2024-07-10 11:26:062024-07-11 14:48:26 Functions: 2
Date:2024-07-10 11:26:062024-07-11 14:48:26 Functions: 1
Date:2024-07-10 11:26:062024-07-11 14:48:26 Functions: 1
Date:2024-07-10 11:26:062024-07-11 14:48:26 Functions: 1
Date:2024-07-10 11:26:062024-07-11 14:48:26 Functions: 17
void PUP::pup<std::array<unsigned long, 2ul>, unsigned long, tk::UnsMesh::Hash<2ul>, tk::UnsMesh::Eq<2ul> >(PUP::er&, std::unordered_map<std::array<unsigned long, 2ul>, unsigned long, tk::UnsMesh::Hash<2ul>, tk::UnsMesh::Eq<2ul>, std::allocator<std::pair<std::array<unsigned long, 2ul> const, unsigned long> > >&)2439024081
void PUP::pup<std::array<unsigned long, 2ul>, std::tuple<int, int, AMR::Edge_Lock_Case>, tk::UnsMesh::Hash<2ul>, tk::UnsMesh::Eq<2ul> >(PUP::er&, std::unordered_map<std::array<unsigned long, 2ul>, std::tuple<int, int, AMR::Edge_Lock_Case>, tk::UnsMesh::Hash<2ul>, tk::UnsMesh::Eq<2ul>, std::allocator<std::pair<std::array<unsigned long, 2ul> const, std::tuple<int, int, AMR::Edge_Lock_Case> > > >&)2533825029
void PUP::pup<std::array<unsigned long, 2ul>, std::vector<int, std::allocator<int> >, tk::UnsMesh::Hash<2ul>, tk::UnsMesh::Eq<2ul> >(PUP::er&, std::unordered_map<std::array<unsigned long, 2ul>, std::vector<int, std::allocator<int> >, tk::UnsMesh::Hash<2ul>, tk::UnsMesh::Eq<2ul>, std::allocator<std::pair<std::array<unsigned long, 2ul> const, std::vector<int, std::allocator<int> > > > >&)4878048162
void PUP::pup<std::array<unsigned long, 4ul>, tk::UnsMesh::Hash<4ul>, tk::UnsMesh::Eq<4ul> >(PUP::er&, std::unordered_set<std::array<unsigned long, 4ul>, tk::UnsMesh::Hash<4ul>, tk::UnsMesh::Eq<4ul>, std::allocator<std::array<unsigned long, 4ul> > >&)4879848180
void PUP::pup<std::array<unsigned long, 2ul>, std::array<double, 3ul>, tk::UnsMesh::Hash<2ul>, tk::UnsMesh::Eq<2ul> >(PUP::er&, std::unordered_map<std::array<unsigned long, 2ul>, std::array<double, 3ul>, tk::UnsMesh::Hash<2ul>, tk::UnsMesh::Eq<2ul>, std::allocator<std::pair<std::array<unsigned long, 2ul> const, std::array<double, 3ul> > > >&)5634656250
char PUP::pup_helper<inciter::CProxy_ALECG, inciter::CProxy_DG, inciter::CProxy_ALECG, inciter::CProxy_OversetFE, inciter::CProxy_FV>(unsigned long&, unsigned long, PUP::er&, std::variant<inciter::CProxy_DG, inciter::CProxy_ALECG, inciter::CProxy_OversetFE, inciter::CProxy_FV>&)6227561657
char PUP::pup_helper<inciter::CProxy_OversetFE, inciter::CProxy_DG, inciter::CProxy_ALECG, inciter::CProxy_OversetFE, inciter::CProxy_FV>(unsigned long&, unsigned long, PUP::er&, std::variant<inciter::CProxy_DG, inciter::CProxy_ALECG, inciter::CProxy_OversetFE, inciter::CProxy_FV>&)6227561657
char PUP::pup_helper<inciter::CProxy_DG, inciter::CProxy_DG, inciter::CProxy_ALECG, inciter::CProxy_OversetFE, inciter::CProxy_FV>(unsigned long&, unsigned long, PUP::er&, std::variant<inciter::CProxy_DG, inciter::CProxy_ALECG, inciter::CProxy_OversetFE, inciter::CProxy_FV>&)6227561657
char PUP::pup_helper<inciter::CProxy_FV, inciter::CProxy_DG, inciter::CProxy_ALECG, inciter::CProxy_OversetFE, inciter::CProxy_FV>(unsigned long&, unsigned long, PUP::er&, std::variant<inciter::CProxy_DG, inciter::CProxy_ALECG, inciter::CProxy_OversetFE, inciter::CProxy_FV>&)6227561657
void PUP::pup<inciter::CProxy_DG, inciter::CProxy_ALECG, inciter::CProxy_OversetFE, inciter::CProxy_FV>(PUP::er&, std::variant<inciter::CProxy_DG, inciter::CProxy_ALECG, inciter::CProxy_OversetFE, inciter::CProxy_FV>&)6227561657
void PUP::pup<std::array<unsigned long, 3ul>, tk::UnsMesh::Hash<3ul>, tk::UnsMesh::Eq<3ul> >(PUP::er&, std::unordered_set<std::array<unsigned long, 3ul>, tk::UnsMesh::Hash<3ul>, tk::UnsMesh::Eq<3ul>, std::allocator<std::array<unsigned long, 3ul> > >&)9687296050
void PUP::pup<std::array<unsigned long, 2ul>, tk::UnsMesh::Hash<2ul>, tk::UnsMesh::Eq<2ul> >(PUP::er&, std::unordered_set<std::array<unsigned long, 2ul>, tk::UnsMesh::Hash<2ul>, tk::UnsMesh::Eq<2ul>, std::allocator<std::array<unsigned long, 2ul> > >&)702427696223
void PUP::pup<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >(PUP::er&, std::optional<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >&)
Date:2024-07-10 11:26:062024-07-11 14:48:26 Functions: 17
char PUP::pup_helper<inciter::CProxy_ALECG, inciter::CProxy_DG, inciter::CProxy_ALECG, inciter::CProxy_OversetFE, inciter::CProxy_FV>(unsigned long&, unsigned long, PUP::er&, std::variant<inciter::CProxy_DG, inciter::CProxy_ALECG, inciter::CProxy_OversetFE, inciter::CProxy_FV>&)6227561657
char PUP::pup_helper<inciter::CProxy_OversetFE, inciter::CProxy_DG, inciter::CProxy_ALECG, inciter::CProxy_OversetFE, inciter::CProxy_FV>(unsigned long&, unsigned long, PUP::er&, std::variant<inciter::CProxy_DG, inciter::CProxy_ALECG, inciter::CProxy_OversetFE, inciter::CProxy_FV>&)6227561657
char PUP::pup_helper<inciter::CProxy_DG, inciter::CProxy_DG, inciter::CProxy_ALECG, inciter::CProxy_OversetFE, inciter::CProxy_FV>(unsigned long&, unsigned long, PUP::er&, std::variant<inciter::CProxy_DG, inciter::CProxy_ALECG, inciter::CProxy_OversetFE, inciter::CProxy_FV>&)6227561657
char PUP::pup_helper<inciter::CProxy_FV, inciter::CProxy_DG, inciter::CProxy_ALECG, inciter::CProxy_OversetFE, inciter::CProxy_FV>(unsigned long&, unsigned long, PUP::er&, std::variant<inciter::CProxy_DG, inciter::CProxy_ALECG, inciter::CProxy_OversetFE, inciter::CProxy_FV>&)6227561657
char PUP::pup_helper<double, int, double>(unsigned long&, unsigned long, PUP::er&, std::variant<int, double>&)
void PUP::pup<inciter::CProxy_DG, inciter::CProxy_ALECG, inciter::CProxy_OversetFE, inciter::CProxy_FV>(PUP::er&, std::variant<inciter::CProxy_DG, inciter::CProxy_ALECG, inciter::CProxy_OversetFE, inciter::CProxy_FV>&)6227561657
void PUP::pup<int, double>(PUP::er&, std::variant<int, double>&)
void PUP::pup<std::array<unsigned long, 2ul>, tk::UnsMesh::Hash<2ul>, tk::UnsMesh::Eq<2ul> >(PUP::er&, std::unordered_set<std::array<unsigned long, 2ul>, tk::UnsMesh::Hash<2ul>, tk::UnsMesh::Eq<2ul>, std::allocator<std::array<unsigned long, 2ul> > >&)702427696223
void PUP::pup<std::array<unsigned long, 2ul>, std::array<double, 3ul>, tk::UnsMesh::Hash<2ul>, tk::UnsMesh::Eq<2ul> >(PUP::er&, std::unordered_map<std::array<unsigned long, 2ul>, std::array<double, 3ul>, tk::UnsMesh::Hash<2ul>, tk::UnsMesh::Eq<2ul>, std::allocator<std::pair<std::array<unsigned long, 2ul> const, std::array<double, 3ul> > > >&)5634656250
void PUP::pup<std::array<unsigned long, 2ul>, std::tuple<int, int, AMR::Edge_Lock_Case>, tk::UnsMesh::Hash<2ul>, tk::UnsMesh::Eq<2ul> >(PUP::er&, std::unordered_map<std::array<unsigned long, 2ul>, std::tuple<int, int, AMR::Edge_Lock_Case>, tk::UnsMesh::Hash<2ul>, tk::UnsMesh::Eq<2ul>, std::allocator<std::pair<std::array<unsigned long, 2ul> const, std::tuple<int, int, AMR::Edge_Lock_Case> > > >&)2533825029
void PUP::pup<std::array<unsigned long, 2ul>, std::vector<int, std::allocator<int> >, tk::UnsMesh::Hash<2ul>, tk::UnsMesh::Eq<2ul> >(PUP::er&, std::unordered_map<std::array<unsigned long, 2ul>, std::vector<int, std::allocator<int> >, tk::UnsMesh::Hash<2ul>, tk::UnsMesh::Eq<2ul>, std::allocator<std::pair<std::array<unsigned long, 2ul> const, std::vector<int, std::allocator<int> > > > >&)4878048162
void PUP::pup<std::array<unsigned long, 2ul>, unsigned long, tk::UnsMesh::Hash<2ul>, tk::UnsMesh::Eq<2ul> >(PUP::er&, std::unordered_map<std::array<unsigned long, 2ul>, unsigned long, tk::UnsMesh::Hash<2ul>, tk::UnsMesh::Eq<2ul>, std::allocator<std::pair<std::array<unsigned long, 2ul> const, unsigned long> > >&)2439024081
void PUP::pup<std::array<unsigned long, 3ul>, tk::UnsMesh::Hash<3ul>, tk::UnsMesh::Eq<3ul> >(PUP::er&, std::unordered_set<std::array<unsigned long, 3ul>, tk::UnsMesh::Hash<3ul>, tk::UnsMesh::Eq<3ul>, std::allocator<std::array<unsigned long, 3ul> > >&)9687296050
void PUP::pup<std::array<unsigned long, 3ul>, std::array<unsigned long, 2ul>, tk::UnsMesh::Hash<3ul>, tk::UnsMesh::Eq<3ul> >(PUP::er&, std::unordered_map<std::array<unsigned long, 3ul>, std::array<unsigned long, 2ul>, tk::UnsMesh::Hash<3ul>, tk::UnsMesh::Eq<3ul>, std::allocator<std::pair<std::array<unsigned long, 3ul> const, std::array<unsigned long, 2ul> > > >&)
void PUP::pup<std::array<unsigned long, 4ul>, tk::UnsMesh::Hash<4ul>, tk::UnsMesh::Eq<4ul> >(PUP::er&, std::unordered_set<std::array<unsigned long, 4ul>, tk::UnsMesh::Hash<4ul>, tk::UnsMesh::Eq<4ul>, std::allocator<std::array<unsigned long, 4ul> > >&)4879848180
void PUP::pup<int>(PUP::er&, std::optional<int>&)
Date:2024-07-10 11:26:062024-07-11 14:48:26 Functions: 17
Date:2024-07-10 11:26:062024-07-11 14:48:26 Functions: 39
Date:2024-07-10 11:26:062024-07-11 14:48:26 Functions: 39
Date:2024-07-10 11:26:062024-07-11 14:48:26 Functions: 39
Date:2024-07-10 11:26:062024-07-11 14:48:26 Functions: 3
Date:2024-07-10 11:26:062024-07-11 14:48:26 Functions: 3
Date:2024-07-10 11:26:062024-07-11 14:48:26 Functions: 3
Date:2024-07-10 11:26:062024-07-11 14:48:26 Functions: 20
Date:2024-07-10 11:26:062024-07-11 14:48:26 Functions: 20
Date:2024-07-10 11:26:062024-07-11 14:48:26 Functions: 20
Date:2024-07-10 11:26:062024-07-11 14:48:26 Functions: 1
Date:2024-07-10 11:26:062024-07-11 14:48:26 Functions: 1
Date:2024-07-10 11:26:062024-07-11 14:48:26 Functions: 1
Date:2024-07-10 11:26:062024-07-11 14:48:26 Functions: 7
Date:2024-07-10 11:26:062024-07-11 14:48:26 Functions: 7
Date:2024-07-10 11:26:062024-07-11 14:48:26 Functions: 7
Date:2024-07-10 11:26:062024-07-11 14:48:26 Functions: 4
Date:2024-07-10 11:26:062024-07-11 14:48:26 Functions: 4
Date:2024-07-10 11:26:062024-07-11 14:48:26 Functions: 4
Date:2024-07-10 11:26:062024-07-11 14:48:26 Functions: 2
Date:2024-07-10 11:26:062024-07-11 14:48:26 Functions: 2
Date:2024-07-10 11:26:062024-07-11 14:48:26 Functions: 2
Date:2024-07-10 11:26:062024-07-11 14:48:26 Functions: 9
Date:2024-07-10 11:26:062024-07-11 14:48:26 Functions: 9
Date:2024-07-10 11:26:062024-07-11 14:48:26 Functions: 9
Date:2024-07-10 11:26:062024-07-11 14:48:26 Functions: 170
Date:2024-07-10 11:26:062024-07-11 14:48:26 Functions: 170
Date:2024-07-10 11:26:062024-07-11 14:48:26 Functions: 170
Date:2024-07-10 11:26:062024-07-11 14:48:26 Functions: 8
Date:2024-07-10 11:26:062024-07-11 14:48:26 Functions: 8
Date:2024-07-10 11:26:062024-07-11 14:48:26 Functions: 8
Date:2024-07-10 11:26:062024-07-11 14:48:26 Functions: 4
Date:2024-07-10 11:26:062024-07-11 14:48:26 Functions: 4
Date:2024-07-10 11:26:062024-07-11 14:48:26 Functions: 4
Date:2024-07-10 11:26:062024-07-11 14:48:26 Functions: 3
Date:2024-07-10 11:26:062024-07-11 14:48:26 Functions: 3
Date:2024-07-10 11:26:062024-07-11 14:48:26 Functions: 3
Date:2024-07-10 11:26:062024-07-11 14:48:26 Functions: 0
Date:2024-07-10 11:26:062024-07-11 14:48:26 Functions: 0
Date:2024-07-10 11:26:062024-07-11 14:48:26 Functions: 0
Date:2024-07-10 11:26:062024-07-11 14:48:26 Functions: 3
Date:2024-07-10 11:26:062024-07-11 14:48:26 Functions: 3
Date:2024-07-10 11:26:062024-07-11 14:48:26 Functions: 3-128-NOTFOUND Lines:124128 16376.1 %78.5 %
Date:2024-07-10 11:26:062024-07-11 14:48:26 Functions: 10 Branches:576189.2 %6562610.4 %
@@ -105,7 +105,7 @@
tk::rotateTensor(std::array<std::array<double, 3ul>, 3ul> const&, std::array<double, 3ul> const&)8638751549875
tk::inverseJacobian(std::array<double, 3ul> const&, std::array<double, 3ul> const&, std::array<double, 3ul> const&, std::array<double, 3ul> const&)-128-NOTFOUND Lines:124128 16376.1 %78.5 %
Date:2024-07-10 11:26:062024-07-11 14:48:26 Functions: 10 Branches:576189.2 %6562610.4 %
@@ -81,7 +81,7 @@
tk::rotateTensor(std::array<std::array<double, 3ul>, 3ul> const&, std::array<double, 3ul> const&)8638751549875
tk::reflectTensor(std::array<std::array<double, 3ul>, 3ul> const&, std::array<std::array<double, 3ul>, 3ul> const&)-128-NOTFOUND Lines:124128 16376.1 %78.5 %
Date:2024-07-10 11:26:062024-07-11 14:48:26 Functions: 10 Branches:576189.2 %6562610.4 %
@@ -205,7 +205,7 @@ 131 : : inline real 132 : : dot( const std::array< real, 3 >& v1, const std::array< real, 3 >& v2 ) 133 : : { - 134 [ + + ][ + + ]: 1565196674 : return v1[0]*v2[0] + v1[1]*v2[1] + v1[2]*v2[2]; + 134 [ + + ][ + + ]: 1565196674 : return v1[0]*v2[0] + v1[1]*v2[1] + v1[2]*v2[2]; [ + + ][ + + ] [ + + ][ + + ] [ - - ][ - - ] @@ -244,10 +244,12 @@ 143 : : const std::array< std::array< real, 3 >, 3 >& m, 144 : : const std::array< real, 3 >& v ) 145 : : { - 146 : 0 : std::array< real, 3 > mv{0, 0, 0}; - 147 [ - - ][ - - ]: 0 : for (std::size_t i=0; i<3; ++i) { - 148 [ - - ][ - - ]: 0 : for (std::size_t j=0; j<3; ++j) - 149 : 0 : mv[i] += m[i][j]*v[j]; + 146 : 686000 : std::array< real, 3 > mv{0, 0, 0}; + 147 [ - - ][ - - ]: 2744000 : for (std::size_t i=0; i<3; ++i) { + [ + + ][ + + ] + 148 [ - - ][ - - ]: 8232000 : for (std::size_t j=0; j<3; ++j) + [ + + ][ + + ] + 149 : 6174000 : mv[i] += m[i][j]*v[j]; 150 : : } 151 : : 152 : : return mv; @@ -281,7 +283,7 @@ 170 : : inline real 171 : : length( const std::array< real, 3 >& v ) 172 : : { - 173 [ + + ][ + + ]: 23692393 : return std::sqrt( dot(v,v) ); + 173 [ + + ][ + + ]: 23692393 : return std::sqrt( dot(v,v) ); [ - - ][ - - ] [ - - ][ - - ] [ - - ][ - - ] @@ -762,66 +764,66 @@ 548 : : //! \param[in] r Coordinates of the first basis vector r = (rx,ry,rz). 549 : : //! \return rotated tensor 550 : : inline std::array< std::array< tk::real, 3 >, 3 > - 551 : 863875 : rotateTensor(const std::array< std::array< tk::real, 3 >, 3 >& mat, + 551 : 1549875 : rotateTensor(const std::array< std::array< tk::real, 3 >, 3 >& mat, 552 : : const std::array< tk::real, 3 >& r ) 553 : : { 554 : : // define rotation matrix 555 : : tk::real eps = 1.0e-04; 556 : : double rotMat[9]; - 557 : 863875 : tk::real rx = r[0]; - 558 : 863875 : tk::real ry = r[1]; - 559 [ + + ]: 863875 : tk::real rz = r[2]; - 560 [ + + ][ + + ]: 863875 : if (std::abs(rx) > eps || std::abs(ry) > eps) + 557 : 1549875 : tk::real rx = r[0]; + 558 : 1549875 : tk::real ry = r[1]; + 559 [ + + ]: 1549875 : tk::real rz = r[2]; + 560 [ + + ][ + + ]: 1549875 : if (std::abs(rx) > eps || std::abs(ry) > eps) 561 : : { - 562 : 791332 : tk::real rxryNorm = std::sqrt(rx*rx+ry*ry); - 563 : 791332 : rotMat[0] = rx; - 564 : 791332 : rotMat[1] = ry; - 565 : 791332 : rotMat[2] = rz; - 566 : 791332 : rotMat[3] = ry/rxryNorm; - 567 : 791332 : rotMat[4] = -rx/rxryNorm; - 568 : 791332 : rotMat[5] = 0.0; - 569 : 791332 : rotMat[6] = rx*rz/rxryNorm; - 570 : 791332 : rotMat[7] = ry*rz/rxryNorm; - 571 : 791332 : rotMat[8] = -rxryNorm; + 562 : 1373932 : tk::real rxryNorm = std::sqrt(rx*rx+ry*ry); + 563 : 1373932 : rotMat[0] = rx; + 564 : 1373932 : rotMat[1] = ry; + 565 : 1373932 : rotMat[2] = rz; + 566 : 1373932 : rotMat[3] = ry/rxryNorm; + 567 : 1373932 : rotMat[4] = -rx/rxryNorm; + 568 : 1373932 : rotMat[5] = 0.0; + 569 : 1373932 : rotMat[6] = rx*rz/rxryNorm; + 570 : 1373932 : rotMat[7] = ry*rz/rxryNorm; + 571 : 1373932 : rotMat[8] = -rxryNorm; 572 : : } 573 : : else 574 : : { - 575 : 72543 : rotMat[0] = rx; - 576 : 72543 : rotMat[1] = ry; - 577 : 72543 : rotMat[2] = rz; - 578 : 72543 : rotMat[3] = 1.0; - 579 : 72543 : rotMat[4] = 0.0; - 580 : 72543 : rotMat[5] = 0.0; - 581 : 72543 : rotMat[6] = 0.0; - 582 : 72543 : rotMat[7] = 1.0; - 583 : 72543 : rotMat[8] = 0.0; + 575 : 175943 : rotMat[0] = rx; + 576 : 175943 : rotMat[1] = ry; + 577 : 175943 : rotMat[2] = rz; + 578 : 175943 : rotMat[3] = 1.0; + 579 : 175943 : rotMat[4] = 0.0; + 580 : 175943 : rotMat[5] = 0.0; + 581 : 175943 : rotMat[6] = 0.0; + 582 : 175943 : rotMat[7] = 1.0; + 583 : 175943 : rotMat[8] = 0.0; 584 : : } 585 : : 586 : : // define matrices 587 : : double matAuxIn[9], matAuxOut[9]; - 588 [ + + ]: 3455500 : for (std::size_t i=0; i<3; ++i) - 589 [ + + ]: 10366500 : for (std::size_t j=0; j<3; ++j) - 590 : 7774875 : matAuxIn[i*3+j] = mat[i][j]; + 588 [ + + ]: 6199500 : for (std::size_t i=0; i<3; ++i) + 589 [ + + ]: 18598500 : for (std::size_t j=0; j<3; ++j) + 590 : 13948875 : matAuxIn[i*3+j] = mat[i][j]; 591 : : 592 : : // compute matAuxIn*rotMat and store it into matAuxOut - 593 : 863875 : cblas_dgemm(CblasRowMajor, CblasNoTrans, CblasNoTrans, + 593 : 1549875 : cblas_dgemm(CblasRowMajor, CblasNoTrans, CblasNoTrans, 594 : : 3, 3, 3, 1.0, matAuxIn, 3, rotMat, 3, 0.0, matAuxOut, 3); 595 : : 596 : : // matAuxOut -> matAuxIn - 597 [ + + ]: 8638750 : for (std::size_t i=0; i<9; i++) + 597 [ + + ]: 15498750 : for (std::size_t i=0; i<9; i++) 598 : : { - 599 : 7774875 : matAuxIn[i] = matAuxOut[i]; - 600 : 7774875 : matAuxOut[i] = 0.0; + 599 : 13948875 : matAuxIn[i] = matAuxOut[i]; + 600 : 13948875 : matAuxOut[i] = 0.0; 601 : : } 602 : : 603 : : // compute rotMat^T*matAuxIn and store it into matAuxOut - 604 : 863875 : cblas_dgemm(CblasRowMajor, CblasTrans, CblasNoTrans, + 604 : 1549875 : cblas_dgemm(CblasRowMajor, CblasTrans, CblasNoTrans, 605 : : 3, 3, 3, 1.0, rotMat, 3, matAuxIn, 3, 0.0, matAuxOut, 3); 606 : : 607 : : // return matAuxOut as a 2D array - 608 : 863875 : return {{ {matAuxOut[0], matAuxOut[1], matAuxOut[2]}, - 609 : 863875 : {matAuxOut[3], matAuxOut[4], matAuxOut[5]}, - 610 : 863875 : {matAuxOut[6], matAuxOut[7], matAuxOut[8]} }}; + 608 : 1549875 : return {{ {matAuxOut[0], matAuxOut[1], matAuxOut[2]}, + 609 : 1549875 : {matAuxOut[3], matAuxOut[4], matAuxOut[5]}, + 610 : 1549875 : {matAuxOut[6], matAuxOut[7], matAuxOut[8]} }}; 611 : : } 612 : : 613 : : //! \brief Reflect a second order tensor (e.g. a Strain/Stress matrix) diff --git a/Release/test_coverage/Base/Writer.cpp.func-sort-c.html b/Release/test_coverage/Base/Writer.cpp.func-sort-c.html index 2b1494bb3b7d..8bedf2055c3e 100644 --- a/Release/test_coverage/Base/Writer.cpp.func-sort-c.html +++ b/Release/test_coverage/Base/Writer.cpp.func-sort-c.html @@ -33,7 +33,7 @@
Date:2024-07-10 11:26:062024-07-11 14:48:26 Functions: 2
Date:2024-07-10 11:26:062024-07-11 14:48:26 Functions: 2
Date:2024-07-10 11:26:062024-07-11 14:48:26 Functions: 2-128-NOTFOUND Lines:772776 94082.1 %82.6 %
Date:2024-07-10 11:26:062024-07-11 14:48:26 Functions: 647 Branches:1086319134.0 %1094319934.2 %
@@ -96,14 +96,14 @@
Vector.hpp -
76.1%76.1%
+
78.5%78.5%
76.1 %124 / 16378.5 %128 / 163 76.9 % 10 / 139.2 %57 / 61810.4 %65 / 626
Progress.hpp19 / 20
Exception.hppTaggedTuplePrint.hpp
100.0%
100.0 %2 / 25 / 5 100.0 %1 / 18 / 8 - 0 / 0
TaggedTuplePrint.hppLoadDistributor.cpp
100.0%
100.0 %5 / 5100.0 % 8 / 8100.0 %1 / 1 - 0 / 0
ChareStateCollector.hppException.hpp
100.0%
100.0 %6 / 62 / 2 100.0 %3 / 31 / 1 - 0 / 0
LoadDistributor.cppChareStateCollector.hpp
100.0%
100.0 %8 / 86 / 6 100.0 %1 / 13 / 3 - 0 / 0
-128-NOTFOUND Lines:772776 94082.1 %82.6 %
Date:2024-07-10 11:26:062024-07-11 14:48:26 Functions: 647 Branches:1086319134.0 %1094319934.2 %
@@ -156,14 +156,14 @@
Vector.hpp -
76.1%76.1%
+
78.5%78.5%
76.1 %124 / 16378.5 %128 / 163 76.9 % 10 / 139.2 %57 / 61810.4 %65 / 626
Print.hpp12 / 22
Exception.hppLoadDistributor.cpp
100.0%
100.0 %2 / 28 / 8 100.0 % 1 / 1 - 0 / 0
LoadDistributor.cppException.hpp
100.0%
100.0 %8 / 82 / 2 100.0 % 1 / 1 -19 / 20
ChareStateCollector.hppPrintUtil.cpp
100.0%
100.0 %6 / 620 / 20 100.0 % 3 / 3-0 / 057.1 %16 / 28
Types.hppChareStateCollector.cpp
100.0%
100.0 %15 / 1513 / 13 100.0 % 3 / 360.7 %17 / 2835.7 %5 / 14
PrintUtil.cppTypes.hpp
100.0%
100.0 %20 / 2015 / 15 100.0 % 3 / 357.1 %16 / 2860.7 %17 / 28
ChareStateCollector.cppTimer.cpp
100.0%
100.0 %13 / 1320 / 20 100.0 % 3 / 335.7 %5 / 1462.5 %5 / 8
Timer.cppChareStateCollector.hpp
100.0%
100.0 %20 / 206 / 6 100.0 % 3 / 362.5 %5 / 8-0 / 0
TaggedTuplePrint.hpp-128-NOTFOUND Lines:772776 94082.1 %82.6 %
Date:2024-07-10 11:26:062024-07-11 14:48:26 Functions: 647 Branches:1086319134.0 %1094319934.2 %
@@ -129,18 +129,6 @@
32.6 % 30 / 92
Vector.hpp -
76.1%76.1%
-
76.1 %124 / 16376.9 %10 / 139.2 %57 / 618
Escaper.hpp @@ -153,6 +141,18 @@ 29.2 % 7 / 24
Vector.hpp +
78.5%78.5%
+
78.5 %128 / 16376.9 %10 / 1310.4 %65 / 626
Print.hpp @@ -214,28 +214,28 @@ 0 / 0
TaggedTuplePrint.hppFlip_map.hpp
100.0%
100.0 % 5 / 5 100.0 %8 / 8-0 / 02 / 250.0 %2 / 4
Flip_map.hppTaggedTuplePrint.hpp
100.0%
100.0 % 5 / 5 100.0 %2 / 250.0 %2 / 48 / 8-0 / 0
ChareStateCollector.hpp-128-NOTFOUND Lines:772776 94082.1 %82.6 %
Date:2024-07-10 11:26:062024-07-11 14:48:26 Functions: 647 Branches:1086319134.0 %1094319934.2 %
@@ -396,14 +396,14 @@
Vector.hpp -
76.1%76.1%
+
78.5%78.5%
76.1 %124 / 16378.5 %128 / 163 76.9 % 10 / 139.2 %57 / 61810.4 %65 / 626
Writer.cpp
Date:2024-07-10 11:26:062024-07-11 14:48:26 Functions: 6
Date:2024-07-10 11:26:062024-07-11 14:48:26 Functions: 6
Date:2024-07-10 11:26:062024-07-11 14:48:26 Functions: 6
Date:2024-07-10 11:26:062024-07-11 14:48:26 Functions: 26
Date:2024-07-10 11:26:062024-07-11 14:48:26 Functions: 26
Date:2024-07-10 11:26:062024-07-11 14:48:26 Functions: 26
Date:2024-07-10 11:26:062024-07-11 14:48:26 Functions: 2
Date:2024-07-10 11:26:062024-07-11 14:48:26 Functions: 2
Date:2024-07-10 11:26:062024-07-11 14:48:26 Functions: 2
Date:2024-07-10 11:26:062024-07-11 14:48:26 Functions: 1
Date:2024-07-10 11:26:062024-07-11 14:48:26 Functions: 1
Date:2024-07-10 11:26:062024-07-11 14:48:26 Functions: 1
Date:2024-07-10 11:26:062024-07-11 14:48:26 Functions: 0
Date:2024-07-10 11:26:062024-07-11 14:48:26 Functions: 0
Date:2024-07-10 11:26:062024-07-11 14:48:26 Functions: 0
Date:2024-07-10 11:26:062024-07-11 14:48:26 Functions: 3
Date:2024-07-10 11:26:062024-07-11 14:48:26 Functions: 3
Date:2024-07-10 11:26:062024-07-11 14:48:26 Functions: 3
Date:2024-07-10 11:26:062024-07-11 14:48:26 Functions: 3
Date:2024-07-10 11:26:062024-07-11 14:48:26 Functions: 2
Date:2024-07-10 11:26:062024-07-11 14:48:26 Functions: 2
Date:2024-07-10 11:26:062024-07-11 14:48:26 Functions: 2
Date:2024-07-10 11:26:062024-07-11 14:48:26 Functions: 4
Date:2024-07-10 11:26:062024-07-11 14:48:26 Functions: 4
Date:2024-07-10 11:26:062024-07-11 14:48:26 Functions: 4
Date:2024-07-10 11:26:062024-07-11 14:48:26 Functions: 39
Date:2024-07-10 11:26:062024-07-11 14:48:26 Functions: 39
Date:2024-07-10 11:26:062024-07-11 14:48:26 Functions: 39
Date:2024-07-10 11:26:062024-07-11 14:48:26 Functions: 45
Date:2024-07-10 11:26:062024-07-11 14:48:26 Functions: 45
Date:2024-07-10 11:26:062024-07-11 14:48:26 Functions: 45
Date:2024-07-10 11:26:062024-07-11 14:48:26 Functions: 45
Date:2024-07-10 11:26:062024-07-11 14:48:26 Functions: 1
Date:2024-07-10 11:26:062024-07-11 14:48:26 Functions: 1
Date:2024-07-10 11:26:062024-07-11 14:48:26 Functions: 1
Date:2024-07-10 11:26:062024-07-11 14:48:26 Functions: 1
Date:2024-07-10 11:26:062024-07-11 14:48:26 Functions: 1
Date:2024-07-10 11:26:062024-07-11 14:48:26 Functions: 1
Date:2024-07-10 11:26:062024-07-11 14:48:26 Functions: 1
Date:2024-07-10 11:26:062024-07-11 14:48:26 Functions: 1
Date:2024-07-10 11:26:062024-07-11 14:48:26 Functions: 1
Date:2024-07-10 11:26:062024-07-11 14:48:26 Functions: 1
Date:2024-07-10 11:26:062024-07-11 14:48:26 Functions: 1
Date:2024-07-10 11:26:062024-07-11 14:48:26 Functions: 1
Date:2024-07-10 11:26:062024-07-11 14:48:26 Functions: 1
Date:2024-07-10 11:26:062024-07-11 14:48:26 Functions: 1
Date:2024-07-10 11:26:062024-07-11 14:48:26 Functions: 1
Date:2024-07-10 11:26:062024-07-11 14:48:26 Functions: 1
Date:2024-07-10 11:26:062024-07-11 14:48:26 Functions: 1
Date:2024-07-10 11:26:062024-07-11 14:48:26 Functions: 1
Date:2024-07-10 11:26:062024-07-11 14:48:26 Functions: 1
Date:2024-07-10 11:26:062024-07-11 14:48:26 Functions: 1
Date:2024-07-10 11:26:062024-07-11 14:48:26 Functions: 1
Date:2024-07-10 11:26:062024-07-11 14:48:26 Functions: 1
Date:2024-07-10 11:26:062024-07-11 14:48:26 Functions: 1
Date:2024-07-10 11:26:062024-07-11 14:48:26 Functions: 1
Date:2024-07-10 11:26:062024-07-11 14:48:26 Functions: 1
Date:2024-07-10 11:26:062024-07-11 14:48:26 Functions: 1
Date:2024-07-10 11:26:062024-07-11 14:48:26 Functions: 1
Date:2024-07-10 11:26:062024-07-11 14:48:26 Functions: 1
Date:2024-07-10 11:26:062024-07-11 14:48:26 Functions: 1
Date:2024-07-10 11:26:062024-07-11 14:48:26 Functions: 1
Date:2024-07-10 11:26:062024-07-11 14:48:26 Functions: 1
Date:2024-07-10 11:26:062024-07-11 14:48:26 Functions: 1
Date:2024-07-10 11:26:062024-07-11 14:48:26 Functions: 1
Date:2024-07-10 11:26:062024-07-11 14:48:26 Functions: 1
Date:2024-07-10 11:26:062024-07-11 14:48:26 Functions: 1
Date:2024-07-10 11:26:062024-07-11 14:48:26 Functions: 1
Date:2024-07-10 11:26:062024-07-11 14:48:26 Functions: 2
Date:2024-07-10 11:26:062024-07-11 14:48:26 Functions: 2
Date:2024-07-10 11:26:062024-07-11 14:48:26 Functions: 2
Date:2024-07-10 11:26:062024-07-11 14:48:26 Functions: 1412 / 38
MeshVelocity.hppPDE.hpp
100.0%
100.0 %4 / 43 / 3 100.0 % 1 / 1 40.9 % 9 / 22
Material.hppMeshVelocity.hpp
100.0%
9 / 22
PDE.hppLimiter.hpp
100.0%
100.0 %3 / 34 / 4 100.0 % 1 / 1 40.9 % 9 / 22
Limiter.hppAMRError.hpp
100.0%
100.0 %4 / 43 / 3 100.0 % 1 / 1 40.9 % 9 / 22
Physics.hppMeshVelocitySmoother.hpp
100.0%
9 / 22
Flux.hppPhysics.hpp
100.0%
9 / 22
PrefIndicator.hppMaterial.hpp
100.0%
100.0 %3 / 34 / 4 100.0 % 1 / 1 40.9 % 9 / 22
MeshVelocitySmoother.hppPrefIndicator.hpp
100.0%
100.0 %4 / 43 / 3 100.0 % 1 / 1 40.9 % 9 / 22
AMRError.hppFlux.hpp
100.0%
100.0 %3 / 34 / 4 100.0 % 1 / 1 40.9 %11 / 26
AMRInitial.hppProblem.hpp
100.0%
11 / 22
Problem.hppAMRInitial.hpp
100.0%
Date:2024-07-10 11:26:062024-07-11 14:48:26 Functions: 14Branches Sort by branch coverage
MeshVelocity.hppPDE.hpp
100.0%
100.0 %4 / 43 / 3 100.0 % 1 / 1 40.9 % 9 / 22
Material.hppMeshVelocity.hpp
100.0%
9 / 22
PDE.hppInitiate.hpp
100.0%
100.0 %3 / 34 / 4 100.0 % 1 / 140.9 %9 / 2242.3 %11 / 26
AMRInitial.hppLimiter.hpp
100.0%
4 / 4 100.0 % 1 / 150.0 %11 / 2240.9 %9 / 22
Initiate.hppAMRError.hpp
100.0%
100.0 %4 / 43 / 3 100.0 % 1 / 142.3 %11 / 2640.9 %9 / 22
Limiter.hppMeshVelocitySmoother.hpp
100.0%
9 / 22
Problem.hppMaterial.hpp
100.0%
4 / 4 100.0 % 1 / 150.0 %11 / 2240.9 %9 / 22
Flux.hppProblem.hpp
100.0%
4 / 4 100.0 % 1 / 140.9 %9 / 2250.0 %11 / 22
PrefIndicator.hpp9 / 22
MeshVelocitySmoother.hppAMRInitial.hpp
100.0%
4 / 4 100.0 % 1 / 140.9 %9 / 2250.0 %11 / 22
AMRError.hppFlux.hpp
100.0%
100.0 %3 / 34 / 4 100.0 % 1 / 1 40.9 %
Date:2024-07-10 11:26:062024-07-11 14:48:26 Functions: 149 / 22
PrefIndicator.hppAMRError.hpp
100.0%
9 / 22
AMRError.hppPrefIndicator.hpp
100.0%
9 / 22
Material.hppInitiate.hpp
100.0%
4 / 4 100.0 % 1 / 140.9 %9 / 2242.3 %11 / 26
AMRInitial.hppLimiter.hpp
100.0%
4 / 4 100.0 % 1 / 150.0 %11 / 2240.9 %9 / 22
Initiate.hppMeshVelocitySmoother.hpp
100.0%
4 / 4 100.0 % 1 / 142.3 %11 / 2640.9 %9 / 22
Limiter.hppPhysics.hpp
100.0%
9 / 22
Physics.hppMaterial.hpp
100.0%
11 / 22
Flux.hppAMRInitial.hpp
100.0%
4 / 4 100.0 % 1 / 140.9 %9 / 2250.0 %11 / 22
MeshVelocitySmoother.hppFlux.hpp
100.0%
Date:2024-07-10 11:26:062024-07-11 14:48:26 Functions: 14
Date:2024-07-10 11:26:062024-07-11 14:48:26 Functions: 4
Date:2024-07-10 11:26:062024-07-11 14:48:26 Functions: 4
Date:2024-07-10 11:26:062024-07-11 14:48:26 Functions: 4
Date:2024-07-10 11:26:062024-07-11 14:48:26 Functions: 4
Date:2024-07-10 11:26:062024-07-11 14:48:26 Functions: 4
Date:2024-07-10 11:26:062024-07-11 14:48:26 Functions: 4
Date:2024-07-10 11:26:062024-07-11 14:48:26 Functions: 4
Date:2024-07-10 11:26:062024-07-11 14:48:26 Functions: 44
Date:2024-07-10 11:26:062024-07-11 14:48:26 Functions: 44
Date:2024-07-10 11:26:062024-07-11 14:48:26 Functions: 44
Date:2024-07-10 11:26:062024-07-11 14:48:26 Functions: 3
Date:2024-07-10 11:26:062024-07-11 14:48:26 Functions: 3
Date:2024-07-10 11:26:062024-07-11 14:48:26 Functions: 3
Date:2024-07-10 11:26:062024-07-11 14:48:26 Functions: 2
Date:2024-07-10 11:26:062024-07-11 14:48:26 Functions: 2
Date:2024-07-10 11:26:062024-07-11 14:48:26 Functions: 2
Date:2024-07-10 11:26:062024-07-11 14:48:26 Functions: 1
Date:2024-07-10 11:26:062024-07-11 14:48:26 Functions: 1
Date:2024-07-10 11:26:062024-07-11 14:48:26 Functions: 1
Date:2024-07-10 11:26:062024-07-11 14:48:26 Functions: 0
Date:2024-07-10 11:26:062024-07-11 14:48:26 Functions: 0
Date:2024-07-10 11:26:062024-07-11 14:48:26 Functions: 0
Date:2024-07-10 11:26:062024-07-11 14:48:26 Functions: 3
Date:2024-07-10 11:26:062024-07-11 14:48:26 Functions: 3
Date:2024-07-10 11:26:062024-07-11 14:48:26 Functions: 3
Date:2024-07-10 11:26:062024-07-11 14:48:26 Functions: 3
Date:2024-07-10 11:26:062024-07-11 14:48:26 Functions: 1
Date:2024-07-10 11:26:062024-07-11 14:48:26 Functions: 1
Date:2024-07-10 11:26:062024-07-11 14:48:26 Functions: 1
Date:2024-07-10 11:26:062024-07-11 14:48:26 Functions: 1
Date:2024-07-10 11:26:062024-07-11 14:48:26 Functions: 1
Date:2024-07-10 11:26:062024-07-11 14:48:26 Functions: 1
Date:2024-07-10 11:26:062024-07-11 14:48:26 Functions: 1
Date:2024-07-10 11:26:062024-07-11 14:48:26 Functions: 1
Date:2024-07-10 11:26:062024-07-11 14:48:26 Functions: 1
Date:2024-07-10 11:26:062024-07-11 14:48:26 Functions: 1
Date:2024-07-10 11:26:062024-07-11 14:48:26 Functions: 1
Date:2024-07-10 11:26:062024-07-11 14:48:26 Functions: 1
Date:2024-07-10 11:26:062024-07-11 14:48:26 Functions: 1
Date:2024-07-10 11:26:062024-07-11 14:48:26 Functions: 1
Date:2024-07-10 11:26:062024-07-11 14:48:26 Functions: 1
Date:2024-07-10 11:26:062024-07-11 14:48:26 Functions: 59 / 22
UserTable.hppFieldFile.hpp
100.0%
9 / 22
FieldFile.hppError.hpp
100.0%
9 / 22
Error.hppUserTable.hpp
100.0%
Date:2024-07-10 11:26:062024-07-11 14:48:26 Functions: 59 / 22
PartitioningAlgorithm.hppFieldFile.hpp
100.0%
100.0 %4 / 43 / 3 100.0 % 1 / 141.7 %15 / 3640.9 %9 / 22
UserTable.hppError.hpp
100.0%
9 / 22
FieldFile.hppUserTable.hpp
100.0%
9 / 22
Error.hppPartitioningAlgorithm.hpp
100.0%
100.0 %3 / 34 / 4 100.0 % 1 / 140.9 %9 / 2241.7 %15 / 36
diff --git a/Release/test_coverage/Control/Options/index-sort-l.html b/Release/test_coverage/Control/Options/index-sort-l.html index 7f32b14a0aee..39e7ce249d23 100644 --- a/Release/test_coverage/Control/Options/index-sort-l.html +++ b/Release/test_coverage/Control/Options/index-sort-l.html @@ -33,7 +33,7 @@
Date:2024-07-10 11:26:062024-07-11 14:48:26 Functions: 59 / 22
UserTable.hppFieldFile.hpp
100.0%
9 / 22
FieldFile.hppError.hpp
100.0%
9 / 22
Error.hppUserTable.hpp
100.0%
Date:2024-07-10 11:26:062024-07-11 14:48:26 Functions: 5
Date:2024-07-10 11:26:062024-07-11 14:48:26 Functions: 2
Date:2024-07-10 11:26:062024-07-11 14:48:26 Functions: 2
Date:2024-07-10 11:26:062024-07-11 14:48:26 Functions: 2
Date:2024-07-10 11:26:062024-07-11 14:48:26 Functions: 2
Date:2024-07-10 11:26:062024-07-11 14:48:26 Functions: 2
Date:2024-07-10 11:26:062024-07-11 14:48:26 Functions: 2
Date:2024-07-10 11:26:062024-07-11 14:48:26 Functions: 0
Date:2024-07-10 11:26:062024-07-11 14:48:26 Functions: 0
Date:2024-07-10 11:26:062024-07-11 14:48:26 Functions: 0
Date:2024-07-10 11:26:062024-07-11 14:48:26 Functions: 0
Date:2024-07-10 11:26:062024-07-11 14:48:26 Functions: 0
Date:2024-07-10 11:26:062024-07-11 14:48:26 Functions: 0
Date:2024-07-10 11:26:062024-07-11 14:48:26 Functions: 19
Date:2024-07-10 11:26:062024-07-11 14:48:26 Functions: 19
Date:2024-07-10 11:26:062024-07-11 14:48:26 Functions: 19
Date:2024-07-10 11:26:062024-07-11 14:48:26 Functions: 2
Date:2024-07-10 11:26:062024-07-11 14:48:26 Functions: 2
Date:2024-07-10 11:26:062024-07-11 14:48:26 Functions: 2
Date:2024-07-10 11:26:062024-07-11 14:48:26 Functions: 1
Date:2024-07-10 11:26:062024-07-11 14:48:26 Functions: 1
Date:2024-07-10 11:26:062024-07-11 14:48:26 Functions: 1
Date:2024-07-10 11:26:062024-07-11 14:48:26 Functions: 0
Date:2024-07-10 11:26:062024-07-11 14:48:26 Functions: 0
Date:2024-07-10 11:26:062024-07-11 14:48:26 Functions: 0
Date:2024-07-10 11:26:062024-07-11 14:48:26 Functions: 3
Date:2024-07-10 11:26:062024-07-11 14:48:26 Functions: 3
Date:2024-07-10 11:26:062024-07-11 14:48:26 Functions: 3
Date:2024-07-10 11:26:062024-07-11 14:48:26 Functions: 3
Date:2024-07-10 11:26:062024-07-11 14:48:26 Functions: 102
Date:2024-07-10 11:26:062024-07-11 14:48:26 Functions: 10250.0 % 18 / 36
Tags.hpp -
100.0%
-
100.0 %24 / 24-0 / 050.0 %24 / 48
StringParser.hpp @@ -129,6 +117,18 @@ - 0 / 0
Tags.hpp +
100.0%
+
100.0 %24 / 24-0 / 050.0 %24 / 48
StringParser.cpp diff --git a/Release/test_coverage/Control/index-sort-l.html b/Release/test_coverage/Control/index-sort-l.html index 152dfe9c6abd..89358669d293 100644 --- a/Release/test_coverage/Control/index-sort-l.html +++ b/Release/test_coverage/Control/index-sort-l.html @@ -33,7 +33,7 @@
Date:2024-07-10 11:26:062024-07-11 14:48:26 Functions: 102
Date:2024-07-10 11:26:062024-07-11 14:48:26 Functions: 102
Date:2024-07-10 11:26:062024-07-11 14:48:26 Functions: 4
Date:2024-07-10 11:26:062024-07-11 14:48:26 Functions: 4
Date:2024-07-10 11:26:062024-07-11 14:48:26 Functions: 4
Date:2024-07-10 11:26:062024-07-11 14:48:26 Functions: 0
Date:2024-07-10 11:26:062024-07-11 14:48:26 Functions: 0
Date:2024-07-10 11:26:062024-07-11 14:48:26 Functions: 0
Date:2024-07-10 11:26:062024-07-11 14:48:26 Functions: 3
Date:2024-07-10 11:26:062024-07-11 14:48:26 Functions: 3
Date:2024-07-10 11:26:062024-07-11 14:48:26 Functions: 3
Date:2024-07-10 11:26:062024-07-11 14:48:26 Functions: 0
Date:2024-07-10 11:26:062024-07-11 14:48:26 Functions: 0
Date:2024-07-10 11:26:062024-07-11 14:48:26 Functions: 0
Date:2024-07-10 11:26:062024-07-11 14:48:26 Functions: 26
Date:2024-07-10 11:26:062024-07-11 14:48:26 Functions: 26
Date:2024-07-10 11:26:062024-07-11 14:48:26 Functions: 26
Date:2024-07-10 11:26:062024-07-11 14:48:26 Functions: 4
Date:2024-07-10 11:26:062024-07-11 14:48:26 Functions: 4
Date:2024-07-10 11:26:062024-07-11 14:48:26 Functions: 4
Date:2024-07-10 11:26:062024-07-11 14:48:26 Functions: 19
Date:2024-07-10 11:26:062024-07-11 14:48:26 Functions: 19
Date:2024-07-10 11:26:062024-07-11 14:48:26 Functions: 19
Date:2024-07-10 11:26:062024-07-11 14:48:26 Functions: 2
Date:2024-07-10 11:26:062024-07-11 14:48:26 Functions: 2
Date:2024-07-10 11:26:062024-07-11 14:48:26 Functions: 2
Date:2024-07-10 11:26:062024-07-11 14:48:26 Functions: 4
Date:2024-07-10 11:26:062024-07-11 14:48:26 Functions: 4
Date:2024-07-10 11:26:062024-07-11 14:48:26 Functions: 4
Date:2024-07-10 11:26:062024-07-11 14:48:26 Functions: 1
Date:2024-07-10 11:26:062024-07-11 14:48:26 Functions: 1
Date:2024-07-10 11:26:062024-07-11 14:48:26 Functions: 1
Date:2024-07-10 11:26:062024-07-11 14:48:26 Functions: 5
Date:2024-07-10 11:26:062024-07-11 14:48:26 Functions: 5
Date:2024-07-10 11:26:062024-07-11 14:48:26 Functions: 5
Date:2024-07-10 11:26:062024-07-11 14:48:26 Functions: 0
Date:2024-07-10 11:26:062024-07-11 14:48:26 Functions: 0
Date:2024-07-10 11:26:062024-07-11 14:48:26 Functions: 0
Date:2024-07-10 11:26:062024-07-11 14:48:26 Functions: 4
Date:2024-07-10 11:26:062024-07-11 14:48:26 Functions: 4
Date:2024-07-10 11:26:062024-07-11 14:48:26 Functions: 4
Date:2024-07-10 11:26:062024-07-11 14:48:26 Functions: 0
Date:2024-07-10 11:26:062024-07-11 14:48:26 Functions: 0
Date:2024-07-10 11:26:062024-07-11 14:48:26 Functions: 0
Date:2024-07-10 11:26:062024-07-11 14:48:26 Functions: 2
Date:2024-07-10 11:26:062024-07-11 14:48:26 Functions: 2
Date:2024-07-10 11:26:062024-07-11 14:48:26 Functions: 2
Date:2024-07-10 11:26:062024-07-11 14:48:26 Functions: 2
Date:2024-07-10 11:26:062024-07-11 14:48:26 Functions: 2
Date:2024-07-10 11:26:062024-07-11 14:48:26 Functions: 2
Date:2024-07-10 11:26:062024-07-11 14:48:26 Functions: 8
Date:2024-07-10 11:26:062024-07-11 14:48:26 Functions: 8
Date:2024-07-10 11:26:062024-07-11 14:48:26 Functions: 8
Date:2024-07-10 11:26:062024-07-11 14:48:26 Functions: 4
Date:2024-07-10 11:26:062024-07-11 14:48:26 Functions: 4
Date:2024-07-10 11:26:062024-07-11 14:48:26 Functions: 4
Date:2024-07-10 11:26:062024-07-11 14:48:26 Functions: 1
Date:2024-07-10 11:26:062024-07-11 14:48:26 Functions: 1
Date:2024-07-10 11:26:062024-07-11 14:48:26 Functions: 1
Date:2024-07-10 11:26:062024-07-11 14:48:26 Functions: 3
Date:2024-07-10 11:26:062024-07-11 14:48:26 Functions: 3
Date:2024-07-10 11:26:062024-07-11 14:48:26 Functions: 3
Date:2024-07-10 11:26:062024-07-11 14:48:26 Functions: 0
Date:2024-07-10 11:26:062024-07-11 14:48:26 Functions: 0
Date:2024-07-10 11:26:062024-07-11 14:48:26 Functions: 0
Date:2024-07-10 11:26:062024-07-11 14:48:26 Functions: 3
Date:2024-07-10 11:26:062024-07-11 14:48:26 Functions: 3
Date:2024-07-10 11:26:062024-07-11 14:48:26 Functions: 3
Date:2024-07-10 11:26:062024-07-11 14:48:26 Functions: 0
Date:2024-07-10 11:26:062024-07-11 14:48:26 Functions: 0
Date:2024-07-10 11:26:062024-07-11 14:48:26 Functions: 0
Date:2024-07-10 11:26:062024-07-11 14:48:26 Functions: 3
Date:2024-07-10 11:26:062024-07-11 14:48:26 Functions: 3
Date:2024-07-10 11:26:062024-07-11 14:48:26 Functions: 3
Date:2024-07-10 11:26:062024-07-11 14:48:26 Functions: 0
Date:2024-07-10 11:26:062024-07-11 14:48:26 Functions: 0
Date:2024-07-10 11:26:062024-07-11 14:48:26 Functions: 0
Date:2024-07-10 11:26:062024-07-11 14:48:26 Functions: 4
Date:2024-07-10 11:26:062024-07-11 14:48:26 Functions: 4
Date:2024-07-10 11:26:062024-07-11 14:48:26 Functions: 4
Date:2024-07-10 11:26:062024-07-11 14:48:26 Functions: 0
Date:2024-07-10 11:26:062024-07-11 14:48:26 Functions: 0
Date:2024-07-10 11:26:062024-07-11 14:48:26 Functions: 0
Date:2024-07-10 11:26:062024-07-11 14:48:26 Functions: 0
Date:2024-07-10 11:26:062024-07-11 14:48:26 Functions: 0
Date:2024-07-10 11:26:062024-07-11 14:48:26 Functions: 0
Date:2024-07-10 11:26:062024-07-11 14:48:26 Functions: 0
Date:2024-07-10 11:26:062024-07-11 14:48:26 Functions: 0
Date:2024-07-10 11:26:062024-07-11 14:48:26 Functions: 0
Date:2024-07-10 11:26:062024-07-11 14:48:26 Functions: 0
Date:2024-07-10 11:26:062024-07-11 14:48:26 Functions: 0
Date:2024-07-10 11:26:062024-07-11 14:48:26 Functions: 0
Date:2024-07-10 11:26:062024-07-11 14:48:26 Functions: 4
Date:2024-07-10 11:26:062024-07-11 14:48:26 Functions: 4
Date:2024-07-10 11:26:062024-07-11 14:48:26 Functions: 4
Date:2024-07-10 11:26:062024-07-11 14:48:26 Functions: 0
Date:2024-07-10 11:26:062024-07-11 14:48:26 Functions: 0
Date:2024-07-10 11:26:062024-07-11 14:48:26 Functions: 0
Date:2024-07-10 11:26:062024-07-11 14:48:26 Functions: 1062 / 4
HyperMeshReader.hppNetgenMeshReader.hpp
100.0%
2 / 4
ASCMeshReader.hppDiagWriter.hpp
100.0%
100.0 %3 / 31 / 1 - 0 / 0 50.0 % 2 / 4
NetgenMeshReader.hppHyperMeshReader.hpp
100.0%
2 / 4
UGRIDMeshReader.hppNetgenMeshWriter.hpp
100.0%
100.0 %3 / 32 / 2 - 0 / 0 50.0 % 2 / 4
NetgenMeshWriter.hppUGRIDMeshReader.hpp
100.0%
100.0 %2 / 23 / 3 - 0 / 0 50.0 % 2 / 4
DiagWriter.hppASCMeshReader.hpp
100.0%
100.0 %1 / 13 / 3 - 0 / 0 50.0 %
Date:2024-07-10 11:26:062024-07-11 14:48:26 Functions: 1060 / 30
STLTxtMeshReader.cppTxtStatWriter.cpp
0.0%
0.0 %0 / 480 / 36 0.0 % 0 / 3 0.0 %0 / 900 / 58
TxtStatWriter.cppSTLTxtMeshReader.cpp
0.0%
0.0 %0 / 360 / 48 0.0 % 0 / 3 0.0 %0 / 580 / 90
PDFWriter.cpp2 / 4
GmshMeshWriter.hppNetgenMeshReader.hpp
100.0%
100.0 %1 / 1-0 / 03 / 3 - 0 / 050.0 %2 / 4
HyperMeshReader.hppDiagWriter.hpp
100.0%
100.0 %3 / 31 / 1 - 0 / 0 50.0 % 2 / 4
ASCMeshReader.hppPDFWriter.hpp
100.0%
100.0 %3 / 31 / 1 - 0 / 0 50.0 %2 / 41 / 2
NetgenMeshReader.hppHyperMeshReader.hpp
100.0%
2 / 4
UGRIDMeshReader.hppGmshMeshWriter.hpp
100.0%
100.0 %3 / 31 / 1-0 / 0 - 0 / 050.0 %2 / 4
PDFWriter.hppNetgenMeshWriter.hpp
100.0%
100.0 %1 / 12 / 2 - 0 / 0 50.0 %1 / 22 / 4
NetgenMeshWriter.hppUGRIDMeshReader.hpp
100.0%
100.0 %2 / 23 / 3 - 0 / 0 50.0 % 2 / 4
DiagWriter.hppASCMeshReader.hpp
100.0%
100.0 %1 / 13 / 3 - 0 / 0 50.0 %- 0 / 0
ExodusIIMeshWriter.hpp +
100.0%
+
100.0 %4 / 4100.0 %2 / 241.7 %5 / 12
MeshDetect.cpp @@ -334,16 +346,16 @@ 88 / 170
ExodusIIMeshWriter.hppDiagWriter.cpp -
100.0%
+
92.6%92.6%
92.6 %25 / 27 100.0 %4 / 4100.0 %2 / 241.7 %5 / 123 / 341.2 %14 / 34
NetgenMeshReader.cpp30 / 48
DiagWriter.cpp -
92.6%92.6%
-
92.6 %25 / 27100.0 %3 / 341.2 %14 / 34
RDGFLOMeshReader.cppASCMeshReader.cpp
100.0%
100.0 %51 / 5135 / 35 100.0 % 4 / 429.4 %37 / 12639.7 %31 / 78
ExodusIIMeshReader.hppUGRIDMeshReader.cpp
100.0%
100.0 %51 / 5140 / 40 100.0 % 4 / 417.4 %8 / 4666.7 %16 / 24
ASCMeshReader.cppRDGFLOMeshReader.cpp
100.0%
100.0 %35 / 3551 / 51 100.0 % 4 / 439.7 %31 / 7829.4 %37 / 126
UGRIDMeshReader.cppHyperMeshReader.cpp
100.0%
100.0 %40 / 4035 / 35 100.0 % 4 / 466.7 %16 / 2438.5 %50 / 130
HyperMeshReader.cppExodusIIMeshReader.hpp
100.0%
100.0 %35 / 3551 / 51 100.0 % 4 / 438.5 %50 / 13017.4 %8 / 46
GmshMeshWriter.cpp
Date:2024-07-10 11:26:062024-07-11 14:48:26 Functions: 10637 / 86
GmshMeshWriter.hppDiagWriter.hpp
100.0%
1 / 1 - 0 / 0-0 / 050.0 %2 / 4
PDFWriter.hpp1 / 2
DiagWriter.hppGmshMeshWriter.hpp
100.0%
1 / 1 - 0 / 050.0 %2 / 4-0 / 0
NetgenMeshWriter.hpp2 / 4
HyperMeshReader.hppNetgenMeshReader.hpp
100.0%
2 / 4
ASCMeshReader.hppHyperMeshReader.hpp
100.0%
2 / 4
NetgenMeshReader.hppUGRIDMeshReader.hpp
100.0%
2 / 4
UGRIDMeshReader.hppASCMeshReader.hpp
100.0%
2 / 4
GmshMeshReader.hppExodusIIMeshWriter.hpp
100.0%
100.0 % 4 / 4 100.0 %1 / 150.0 %1 / 22 / 241.7 %5 / 12
ExodusIIMeshWriter.hppGmshMeshReader.hpp
100.0%
100.0 % 4 / 4 100.0 %2 / 241.7 %5 / 121 / 150.0 %1 / 2
MeshWriter.hpp
Date:2024-07-10 11:26:062024-07-11 14:48:26 Functions: 106
Date:2024-07-10 11:26:062024-07-11 14:48:26 Functions: 19
Date:2024-07-10 11:26:062024-07-11 14:48:26 Functions: 19
Date:2024-07-10 11:26:062024-07-11 14:48:26 Functions: 19
Date:2024-07-10 11:26:062024-07-11 14:48:26 Functions: 2
inciter::ALE::ALE(CkMigrateMessage*)111115
inciter::ALE::pup(PUP::er&)364376

diff --git a/Release/test_coverage/Inciter/ALE.hpp.func.html b/Release/test_coverage/Inciter/ALE.hpp.func.html index 22826ff50687..f7ee16e9c210 100644 --- a/Release/test_coverage/Inciter/ALE.hpp.func.html +++ b/Release/test_coverage/Inciter/ALE.hpp.func.html @@ -33,7 +33,7 @@
Date:2024-07-10 11:26:062024-07-11 14:48:26 Functions: 2
inciter::ALE::pup(PUP::er&)364376
inciter::ALE::ALE(CkMigrateMessage*)111115

diff --git a/Release/test_coverage/Inciter/ALE.hpp.gcov.html b/Release/test_coverage/Inciter/ALE.hpp.gcov.html index efada21b90c9..27fb4c3d51b2 100644 --- a/Release/test_coverage/Inciter/ALE.hpp.gcov.html +++ b/Release/test_coverage/Inciter/ALE.hpp.gcov.html @@ -33,7 +33,7 @@
Date:2024-07-10 11:26:062024-07-11 14:48:26 Functions: 2
Date:2024-07-10 11:26:062024-07-11 14:48:26 Functions: 43
Date:2024-07-10 11:26:062024-07-11 14:48:26 Functions: 43
Date:2024-07-10 11:26:062024-07-11 14:48:26 Functions: 43
Date:2024-07-10 11:26:062024-07-11 14:48:26 Functions: 3
inciter::ALECG::ALECG(CkMigrateMessage*)16321625
inciter::ALECG::pup(PUP::er&)51365115
inciter::ALECG::Disc() const
Date:2024-07-10 11:26:062024-07-11 14:48:26 Functions: 3
inciter::ALECG::pup(PUP::er&)51365115
inciter::ALECG::ALECG(CkMigrateMessage*)16321625
inciter::ALECG::Disc() const
Date:2024-07-10 11:26:062024-07-11 14:48:26 Functions: 3
Date:2024-07-10 11:26:062024-07-11 14:48:26 Functions: 0
Date:2024-07-10 11:26:062024-07-11 14:48:26 Functions: 0
Date:2024-07-10 11:26:062024-07-11 14:48:26 Functions: 0
Date:2024-07-10 11:26:062024-07-11 14:48:26 Functions: 3
Date:2024-07-10 11:26:062024-07-11 14:48:26 Functions: 3
Date:2024-07-10 11:26:062024-07-11 14:48:26 Functions: 3
Date:2024-07-10 11:26:062024-07-11 14:48:26 Functions: 1
Date:2024-07-10 11:26:062024-07-11 14:48:26 Functions: 1
Date:2024-07-10 11:26:062024-07-11 14:48:26 Functions: 1
Date:2024-07-10 11:26:062024-07-11 14:48:26 Functions: 0
Date:2024-07-10 11:26:062024-07-11 14:48:26 Functions: 0
Date:2024-07-10 11:26:062024-07-11 14:48:26 Functions: 0
Date:2024-07-10 11:26:062024-07-11 14:48:26 Functions: 0
Date:2024-07-10 11:26:062024-07-11 14:48:26 Functions: 0
Date:2024-07-10 11:26:062024-07-11 14:48:26 Functions: 0
Date:2024-07-10 11:26:062024-07-11 14:48:26 Functions: 1
AMR::edge_t::operator<(AMR::edge_t const&) const928946792928936570

diff --git a/Release/test_coverage/Inciter/AMR/edge.hpp.func.html b/Release/test_coverage/Inciter/AMR/edge.hpp.func.html index 30350fe91bfe..82d7a00790aa 100644 --- a/Release/test_coverage/Inciter/AMR/edge.hpp.func.html +++ b/Release/test_coverage/Inciter/AMR/edge.hpp.func.html @@ -33,7 +33,7 @@
Date:2024-07-10 11:26:062024-07-11 14:48:26 Functions: 1
AMR::edge_t::operator<(AMR::edge_t const&) const928946792928936570

diff --git a/Release/test_coverage/Inciter/AMR/edge.hpp.gcov.html b/Release/test_coverage/Inciter/AMR/edge.hpp.gcov.html index 93c7ccebac36..1b362febc327 100644 --- a/Release/test_coverage/Inciter/AMR/edge.hpp.gcov.html +++ b/Release/test_coverage/Inciter/AMR/edge.hpp.gcov.html @@ -33,7 +33,7 @@
Date:2024-07-10 11:26:062024-07-11 14:48:26 Functions: 1
Date:2024-07-10 11:26:062024-07-11 14:48:26 Functions: 4
Date:2024-07-10 11:26:062024-07-11 14:48:26 Functions: 4
Date:2024-07-10 11:26:062024-07-11 14:48:26 Functions: 4
Date:2024-07-10 11:26:062024-07-11 14:48:26 Functions: 1
Date:2024-07-10 11:26:062024-07-11 14:48:26 Functions: 1
Date:2024-07-10 11:26:062024-07-11 14:48:26 Functions: 1
Date:2024-07-10 11:26:062024-07-11 14:48:26 Functions: 63
Date:2024-07-10 11:26:062024-07-11 14:48:26 Functions: 6358 / 120
AMR_types.hppactive_element_store.hpp
100.0%
2 / 2 - 0 / 050.0 %1 / 278.6 %11 / 14
active_element_store.hppAMR_types.hpp
100.0%
2 / 2 - 0 / 078.6 %11 / 1450.0 %1 / 2
Refinement_State.hpp50.0 % 5 / 10
edge.hpp +
66.7%66.7%
+
66.7 %14 / 21100.0 %1 / 157.7 %60 / 104
id_generator.hpp @@ -214,28 +226,28 @@ 11 / 36
edge.hppmesh_adapter.hpp -
66.7%66.7%
+
100.0%
66.7 %14 / 21 100.0 %1 / 157.7 %60 / 1047 / 7100.0 %2 / 250.0 %3 / 6
mesh_adapter.hppmarked_refinements_store.hpp
100.0%
100.0 %7 / 710 / 10100.0 %2 / 2 100.0 % 2 / 250.0 %3 / 6
node_connectivity.hpp91.7 % 11 / 12
marked_refinements_store.hpp -
100.0%
-
100.0 %10 / 10100.0 %2 / 2100.0 %2 / 2
Error.cpp diff --git a/Release/test_coverage/Inciter/AMR/index-sort-l.html b/Release/test_coverage/Inciter/AMR/index-sort-l.html index 559068800d59..37efb64fea52 100644 --- a/Release/test_coverage/Inciter/AMR/index-sort-l.html +++ b/Release/test_coverage/Inciter/AMR/index-sort-l.html @@ -33,7 +33,7 @@
Date:2024-07-10 11:26:062024-07-11 14:48:26 Functions: 635 / 18
AMR_types.hppactive_element_store.hpp
100.0%
2 / 2 - 0 / 050.0 %1 / 278.6 %11 / 14
active_element_store.hppAMR_types.hpp
100.0%
2 / 2 - 0 / 078.6 %11 / 1450.0 %1 / 2
Refinement_State.hpp4 / 6
master_element_store.hppmarked_refinements_store.hpp
100.0%
100.0 % 10 / 10 100.0 %1 / 130.6 %11 / 362 / 2100.0 %2 / 2
marked_refinements_store.hppmaster_element_store.hpp
100.0%
100.0 % 10 / 10 100.0 %2 / 2100.0 %2 / 21 / 130.6 %11 / 36
diff --git a/Release/test_coverage/Inciter/AMR/index.html b/Release/test_coverage/Inciter/AMR/index.html index 16af22c99596..417a3f3e71d1 100644 --- a/Release/test_coverage/Inciter/AMR/index.html +++ b/Release/test_coverage/Inciter/AMR/index.html @@ -33,7 +33,7 @@
Date:2024-07-10 11:26:062024-07-11 14:48:26 Functions: 63
Date:2024-07-10 11:26:062024-07-11 14:48:26 Functions: 2
Date:2024-07-10 11:26:062024-07-11 14:48:26 Functions: 2
Date:2024-07-10 11:26:062024-07-11 14:48:26 Functions: 2
Date:2024-07-10 11:26:062024-07-11 14:48:26 Functions: 1
Date:2024-07-10 11:26:062024-07-11 14:48:26 Functions: 1
Date:2024-07-10 11:26:062024-07-11 14:48:26 Functions: 1
Date:2024-07-10 11:26:062024-07-11 14:48:26 Functions: 22
Date:2024-07-10 11:26:062024-07-11 14:48:26 Functions: 22
Date:2024-07-10 11:26:062024-07-11 14:48:26 Functions: 22
Date:2024-07-10 11:26:062024-07-11 14:48:26 Functions: 2
AMR::mesh_adapter_t::mesh_adapter_t()78587755

diff --git a/Release/test_coverage/Inciter/AMR/mesh_adapter.hpp.func.html b/Release/test_coverage/Inciter/AMR/mesh_adapter.hpp.func.html index def65170dc6b..634a35cfa73a 100644 --- a/Release/test_coverage/Inciter/AMR/mesh_adapter.hpp.func.html +++ b/Release/test_coverage/Inciter/AMR/mesh_adapter.hpp.func.html @@ -33,7 +33,7 @@
Date:2024-07-10 11:26:062024-07-11 14:48:26 Functions: 2
AMR::mesh_adapter_t::mesh_adapter_t()78587755

diff --git a/Release/test_coverage/Inciter/AMR/mesh_adapter.hpp.gcov.html b/Release/test_coverage/Inciter/AMR/mesh_adapter.hpp.gcov.html index e64bd3a0822e..84a7a38ce224 100644 --- a/Release/test_coverage/Inciter/AMR/mesh_adapter.hpp.gcov.html +++ b/Release/test_coverage/Inciter/AMR/mesh_adapter.hpp.gcov.html @@ -33,7 +33,7 @@
Date:2024-07-10 11:26:062024-07-11 14:48:26 Functions: 2
Date:2024-07-10 11:26:062024-07-11 14:48:26 Functions: 2
Date:2024-07-10 11:26:062024-07-11 14:48:26 Functions: 2
Date:2024-07-10 11:26:062024-07-11 14:48:26 Functions: 2
Date:2024-07-10 11:26:062024-07-11 14:48:26 Functions: 10
Date:2024-07-10 11:26:062024-07-11 14:48:26 Functions: 10
Date:2024-07-10 11:26:062024-07-11 14:48:26 Functions: 10
Date:2024-07-10 11:26:062024-07-11 14:48:26 Functions: 14
Date:2024-07-10 11:26:062024-07-11 14:48:26 Functions: 14
Date:2024-07-10 11:26:062024-07-11 14:48:26 Functions: 14
Date:2024-07-10 11:26:062024-07-11 14:48:26 Functions: 0
Date:2024-07-10 11:26:062024-07-11 14:48:26 Functions: 0
Date:2024-07-10 11:26:062024-07-11 14:48:26 Functions: 0
Date:2024-07-10 11:26:062024-07-11 14:48:26 Functions: 37
Date:2024-07-10 11:26:062024-07-11 14:48:26 Functions: 37
Date:2024-07-10 11:26:062024-07-11 14:48:26 Functions: 37
Date:2024-07-10 11:26:062024-07-11 14:48:26 Functions: 4
inciter::DG::DG(CkMigrateMessage*)51405049
inciter::DG::pup(PUP::er&)1597615703
inciter::DG::Disc() const
Date:2024-07-10 11:26:062024-07-11 14:48:26 Functions: 4
inciter::DG::pup(PUP::er&)1597615703
inciter::DG::DG(CkMigrateMessage*)51405049
inciter::DG::Disc() const
Date:2024-07-10 11:26:062024-07-11 14:48:26 Functions: 4
Date:2024-07-10 11:26:062024-07-11 14:48:26 Functions: 2
inciter::mergeDiag(int, CkReductionMsg**)51045099
inciter::serialize(unsigned long, unsigned long, std::vector<std::vector<double, std::allocator<double> >, std::allocator<std::vector<double, std::allocator<double> > > > const&)3583235827

diff --git a/Release/test_coverage/Inciter/DiagReducer.cpp.func.html b/Release/test_coverage/Inciter/DiagReducer.cpp.func.html index a8c822701c09..af60056de272 100644 --- a/Release/test_coverage/Inciter/DiagReducer.cpp.func.html +++ b/Release/test_coverage/Inciter/DiagReducer.cpp.func.html @@ -33,7 +33,7 @@
Date:2024-07-10 11:26:062024-07-11 14:48:26 Functions: 2
inciter::mergeDiag(int, CkReductionMsg**)51045099
inciter::serialize(unsigned long, unsigned long, std::vector<std::vector<double, std::allocator<double> >, std::allocator<std::vector<double, std::allocator<double> > > > const&)3583235827

diff --git a/Release/test_coverage/Inciter/DiagReducer.cpp.gcov.html b/Release/test_coverage/Inciter/DiagReducer.cpp.gcov.html index fb341f3fdff6..6aebf2b67df3 100644 --- a/Release/test_coverage/Inciter/DiagReducer.cpp.gcov.html +++ b/Release/test_coverage/Inciter/DiagReducer.cpp.gcov.html @@ -33,7 +33,7 @@
Date:2024-07-10 11:26:062024-07-11 14:48:26 Functions: 2
Date:2024-07-10 11:26:062024-07-11 14:48:26 Functions: 41
Date:2024-07-10 11:26:062024-07-11 14:48:26 Functions: 41
Date:2024-07-10 11:26:062024-07-11 14:48:26 Functions: 41
Date:2024-07-10 11:26:062024-07-11 14:48:26 Functions: 7
inciter::Discretization::Discretization(CkMigrateMessage*)78587755
inciter::Discretization::pup(PUP::er&)2439024081
inciter::Discretization::SidesetNodes<tag::farfield>::SidesetNodes(std::map<int, std::vector<unsigned long, std::allocator<unsigned long> >, std::less<int>, std::allocator<std::pair<int const, std::vector<unsigned long, std::allocator<unsigned long> > > > > const&, std::vector<unsigned long, std::allocator<unsigned long> > const&, std::unordered_map<int, std::unordered_set<unsigned long, std::hash<unsigned long>, std::equal_to<unsigned long>, std::allocator<unsigned long> >, std::hash<int>, std::equal_to<int>, std::allocator<std::pair<int const, std::unordered_set<unsigned long, std::hash<unsigned long>, std::equal_to<unsigned long>, std::allocator<unsigned long> > > > >&, unsigned long)
Date:2024-07-10 11:26:062024-07-11 14:48:26 Functions: 7
inciter::Discretization::pup(PUP::er&)2439024081
inciter::Discretization::Discretization(CkMigrateMessage*)78587755
inciter::Discretization::Ref() const
Date:2024-07-10 11:26:062024-07-11 14:48:26 Functions: 7
Date:2024-07-10 11:26:062024-07-11 14:48:26 Functions: 3
Date:2024-07-10 11:26:062024-07-11 14:48:26 Functions: 3
Date:2024-07-10 11:26:062024-07-11 14:48:26 Functions: 3
Date:2024-07-10 11:26:062024-07-11 14:48:26 Functions: 27
Date:2024-07-10 11:26:062024-07-11 14:48:26 Functions: 27
Date:2024-07-10 11:26:062024-07-11 14:48:26 Functions: 27
Date:2024-07-10 11:26:062024-07-11 14:48:26 Functions: 4
inciter::FV::FV(CkMigrateMessage*)106110
inciter::FV::pup(PUP::er&)323335
inciter::FV::Disc() const
Date:2024-07-10 11:26:062024-07-11 14:48:26 Functions: 4
inciter::FV::pup(PUP::er&)323335
inciter::FV::FV(CkMigrateMessage*)106110
inciter::FV::Disc() const
Date:2024-07-10 11:26:062024-07-11 14:48:26 Functions: 4
Date:2024-07-10 11:26:062024-07-11 14:48:26 Functions: 1
Date:2024-07-10 11:26:062024-07-11 14:48:26 Functions: 1
Date:2024-07-10 11:26:062024-07-11 14:48:26 Functions: 1
Date:2024-07-10 11:26:062024-07-11 14:48:26 Functions: 1
inciter::FaceData::pup(PUP::er&)1629916038

diff --git a/Release/test_coverage/Inciter/FaceData.hpp.func.html b/Release/test_coverage/Inciter/FaceData.hpp.func.html index 42d99d993934..2217cf772925 100644 --- a/Release/test_coverage/Inciter/FaceData.hpp.func.html +++ b/Release/test_coverage/Inciter/FaceData.hpp.func.html @@ -33,7 +33,7 @@
Date:2024-07-10 11:26:062024-07-11 14:48:26 Functions: 1
inciter::FaceData::pup(PUP::er&)1629916038

diff --git a/Release/test_coverage/Inciter/FaceData.hpp.gcov.html b/Release/test_coverage/Inciter/FaceData.hpp.gcov.html index 06552e88947f..547a1915276d 100644 --- a/Release/test_coverage/Inciter/FaceData.hpp.gcov.html +++ b/Release/test_coverage/Inciter/FaceData.hpp.gcov.html @@ -33,7 +33,7 @@
Date:2024-07-10 11:26:062024-07-11 14:48:26 Functions: 1
Date:2024-07-10 11:26:062024-07-11 14:48:26 Functions: 3
Date:2024-07-10 11:26:062024-07-11 14:48:26 Functions: 3
Date:2024-07-10 11:26:062024-07-11 14:48:26 Functions: 3
Date:2024-07-10 11:26:062024-07-11 14:48:26 Functions: 6
Date:2024-07-10 11:26:062024-07-11 14:48:26 Functions: 6
Date:2024-07-10 11:26:062024-07-11 14:48:26 Functions: 6
Date:2024-07-10 11:26:062024-07-11 14:48:26 Functions: 18
Date:2024-07-10 11:26:062024-07-11 14:48:26 Functions: 18
Date:2024-07-10 11:26:062024-07-11 14:48:26 Functions: 18
Date:2024-07-10 11:26:062024-07-11 14:48:26 Functions: 5
inciter::Ghosts::Ghosts(CkMigrateMessage*)52465159
inciter::Ghosts::OutMesh::pup(PUP::er&)1597615703
inciter::Ghosts::pup(PUP::er&)1629916038
inciter::Ghosts::OutMesh::destroy()
Date:2024-07-10 11:26:062024-07-11 14:48:26 Functions: 5
inciter::Ghosts::pup(PUP::er&)1629916038
inciter::Ghosts::OutMesh::pup(PUP::er&)1597615703
inciter::Ghosts::OutMesh::destroy()
inciter::Ghosts::Ghosts(CkMigrateMessage*)52465159
inciter::Ghosts::Disc() const
Date:2024-07-10 11:26:062024-07-11 14:48:26 Functions: 5
Date:2024-07-10 11:26:062024-07-11 14:48:26 Functions: 2
Date:2024-07-10 11:26:062024-07-11 14:48:26 Functions: 2
Date:2024-07-10 11:26:062024-07-11 14:48:26 Functions: 2
Date:2024-07-10 11:26:062024-07-11 14:48:26 Functions: 2
Date:2024-07-10 11:26:062024-07-11 14:48:26 Functions: 2
Date:2024-07-10 11:26:062024-07-11 14:48:26 Functions: 2
Date:2024-07-10 11:26:062024-07-11 14:48:26 Functions: 37
Date:2024-07-10 11:26:062024-07-11 14:48:26 Functions: 37
Date:2024-07-10 11:26:062024-07-11 14:48:26 Functions: 37
Date:2024-07-10 11:26:062024-07-11 14:48:26 Functions: 3
inciter::OversetFE::OversetFE(CkMigrateMessage*)980971
inciter::OversetFE::pup(PUP::er&)29552928
inciter::OversetFE::Disc() const
Date:2024-07-10 11:26:062024-07-11 14:48:26 Functions: 3
inciter::OversetFE::pup(PUP::er&)29552928
inciter::OversetFE::OversetFE(CkMigrateMessage*)980971
inciter::OversetFE::Disc() const
Date:2024-07-10 11:26:062024-07-11 14:48:26 Functions: 3
Date:2024-07-10 11:26:062024-07-11 14:48:26 Functions: 9
PUP::pup(PUP::er&, AMR::tet_store_t&)2439024081
PUP::pup(PUP::er&, AMR::edge_store_t&)2439024081
PUP::pup(PUP::er&, AMR::refinement_t&)2439024081
PUP::pup(PUP::er&, AMR::id_generator_t&)2439024081
PUP::pup(PUP::er&, AMR::mesh_adapter_t&)2439024081
PUP::pup(PUP::er&, AMR::node_connectivity_t&)2439024081
PUP::pup(PUP::er&, AMR::Refinement_State&)36200533630532
PUP::pup(PUP::er&, AMR::Edge_Refinement&)62256226227284
PUP::pup(PUP::er&, AMR::edge_t&)62256226227284

diff --git a/Release/test_coverage/Inciter/PUPAMR.cpp.func.html b/Release/test_coverage/Inciter/PUPAMR.cpp.func.html index b934317c374c..7428a420be3c 100644 --- a/Release/test_coverage/Inciter/PUPAMR.cpp.func.html +++ b/Release/test_coverage/Inciter/PUPAMR.cpp.func.html @@ -33,7 +33,7 @@
Date:2024-07-10 11:26:062024-07-11 14:48:26 Functions: 9
PUP::pup(PUP::er&, AMR::tet_store_t&)2439024081
PUP::pup(PUP::er&, AMR::edge_store_t&)2439024081
PUP::pup(PUP::er&, AMR::refinement_t&)2439024081
PUP::pup(PUP::er&, AMR::id_generator_t&)2439024081
PUP::pup(PUP::er&, AMR::mesh_adapter_t&)2439024081
PUP::pup(PUP::er&, AMR::Edge_Refinement&)62256226227284
PUP::pup(PUP::er&, AMR::Refinement_State&)36200533630532
PUP::pup(PUP::er&, AMR::node_connectivity_t&)2439024081
PUP::pup(PUP::er&, AMR::active_element_store_t&)
PUP::pup(PUP::er&, AMR::edge_t&)62256226227284

diff --git a/Release/test_coverage/Inciter/PUPAMR.cpp.gcov.html b/Release/test_coverage/Inciter/PUPAMR.cpp.gcov.html index ed9e4d1efa53..379dcbfa8806 100644 --- a/Release/test_coverage/Inciter/PUPAMR.cpp.gcov.html +++ b/Release/test_coverage/Inciter/PUPAMR.cpp.gcov.html @@ -33,7 +33,7 @@
Date:2024-07-10 11:26:062024-07-11 14:48:26 Functions: 9
Date:2024-07-10 11:26:062024-07-11 14:48:26 Functions: 2
void PUP::pup<AMR::Refinement_Case>(PUP::er&, AMR::marked_refinements_store_t<AMR::Refinement_Case>&)2439024081
void PUP::pup<AMR::Derefinement_Case>(PUP::er&, AMR::marked_refinements_store_t<AMR::Derefinement_Case>&)2439024081

diff --git a/Release/test_coverage/Inciter/PUPAMR.hpp.func.html b/Release/test_coverage/Inciter/PUPAMR.hpp.func.html index 4ad1b711608b..8fb5bedbae57 100644 --- a/Release/test_coverage/Inciter/PUPAMR.hpp.func.html +++ b/Release/test_coverage/Inciter/PUPAMR.hpp.func.html @@ -33,7 +33,7 @@
Date:2024-07-10 11:26:062024-07-11 14:48:26 Functions: 2
void PUP::pup<AMR::Refinement_Case>(PUP::er&, AMR::marked_refinements_store_t<AMR::Refinement_Case>&)2439024081
void PUP::pup<AMR::Derefinement_Case>(PUP::er&, AMR::marked_refinements_store_t<AMR::Derefinement_Case>&)2439024081

diff --git a/Release/test_coverage/Inciter/PUPAMR.hpp.gcov.html b/Release/test_coverage/Inciter/PUPAMR.hpp.gcov.html index e957baed0099..6e2799294abd 100644 --- a/Release/test_coverage/Inciter/PUPAMR.hpp.gcov.html +++ b/Release/test_coverage/Inciter/PUPAMR.hpp.gcov.html @@ -33,7 +33,7 @@
Date:2024-07-10 11:26:062024-07-11 14:48:26 Functions: 2
Date:2024-07-10 11:26:062024-07-11 14:48:26 Functions: 12
Date:2024-07-10 11:26:062024-07-11 14:48:26 Functions: 12
Date:2024-07-10 11:26:062024-07-11 14:48:26 Functions: 12
Date:2024-07-10 11:26:062024-07-11 14:48:26 Functions: 2
Date:2024-07-10 11:26:062024-07-11 14:48:26 Functions: 2
Date:2024-07-10 11:26:062024-07-11 14:48:26 Functions: 2
Date:2024-07-10 11:26:062024-07-11 14:48:26 Functions: 41
Date:2024-07-10 11:26:062024-07-11 14:48:26 Functions: 41
Date:2024-07-10 11:26:062024-07-11 14:48:26 Functions: 41
Date:2024-07-10 11:26:062024-07-11 14:48:26 Functions: 3
inciter::Refiner::Refiner(CkMigrateMessage*)78587755
inciter::Refiner::pup(PUP::er&)2439024081
std::unordered_set<int, std::hash<int>, std::equal_to<int>, std::allocator<int> > inciter::Refiner::keys<std::unordered_map<int, std::unordered_set<unsigned long, std::hash<unsigned long>, std::equal_to<unsigned long>, std::allocator<unsigned long> >, std::hash<int>, std::equal_to<int>, std::allocator<std::pair<int const, std::unordered_set<unsigned long, std::hash<unsigned long>, std::equal_to<unsigned long>, std::allocator<unsigned long> > > > >, unsigned long>(std::unordered_map<int, std::unordered_set<unsigned long, std::hash<unsigned long>, std::equal_to<unsigned long>, std::allocator<unsigned long> >, std::hash<int>, std::equal_to<int>, std::allocator<std::pair<int const, std::unordered_set<unsigned long, std::hash<unsigned long>, std::equal_to<unsigned long>, std::allocator<unsigned long> > > > > const&, unsigned long const&)
Date:2024-07-10 11:26:062024-07-11 14:48:26 Functions: 3
inciter::Refiner::pup(PUP::er&)2439024081
std::unordered_set<int, std::hash<int>, std::equal_to<int>, std::allocator<int> > inciter::Refiner::keys<std::unordered_map<int, std::unordered_set<unsigned long, std::hash<unsigned long>, std::equal_to<unsigned long>, std::allocator<unsigned long> >, std::hash<int>, std::equal_to<int>, std::allocator<std::pair<int const, std::unordered_set<unsigned long, std::hash<unsigned long>, std::equal_to<unsigned long>, std::allocator<unsigned long> > > > >, unsigned long>(std::unordered_map<int, std::unordered_set<unsigned long, std::hash<unsigned long>, std::equal_to<unsigned long>, std::allocator<unsigned long> >, std::hash<int>, std::equal_to<int>, std::allocator<std::pair<int const, std::unordered_set<unsigned long, std::hash<unsigned long>, std::equal_to<unsigned long>, std::allocator<unsigned long> > > > > const&, unsigned long const&)
inciter::Refiner::Refiner(CkMigrateMessage*)78587755

diff --git a/Release/test_coverage/Inciter/Refiner.hpp.gcov.html b/Release/test_coverage/Inciter/Refiner.hpp.gcov.html index cbf1896c0e60..91f8c5b53b9a 100644 --- a/Release/test_coverage/Inciter/Refiner.hpp.gcov.html +++ b/Release/test_coverage/Inciter/Refiner.hpp.gcov.html @@ -33,7 +33,7 @@
Date:2024-07-10 11:26:062024-07-11 14:48:26 Functions: 3
Date:2024-07-10 11:26:062024-07-11 14:48:26 Functions: 15
inciter::Scheme::Scheme()2033120125
inciter::Scheme::pup(PUP::er&)6227561657

diff --git a/Release/test_coverage/Inciter/Scheme.hpp.func.html b/Release/test_coverage/Inciter/Scheme.hpp.func.html index 906b381d078f..519c31cc2d52 100644 --- a/Release/test_coverage/Inciter/Scheme.hpp.func.html +++ b/Release/test_coverage/Inciter/Scheme.hpp.func.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:26:06 + 2024-07-11 14:48:26 Functions: 15 @@ -73,7 +73,7 @@ inciter::Scheme::pup(PUP::er&) - 62275 + 61657 void inciter::Scheme::insert<inciter::CProxy_Discretization&, inciter::CProxy_Ghosts&, std::map<int, std::vector<unsigned long, std::allocator<unsigned long> >, std::less<int>, std::allocator<std::pair<int const, std::vector<unsigned long, std::allocator<unsigned long> > > > >&, std::map<int, std::vector<unsigned long, std::allocator<unsigned long> >, std::less<int>, std::allocator<std::pair<int const, std::vector<unsigned long, std::allocator<unsigned long> > > > >&, std::vector<unsigned long, std::allocator<unsigned long> >&>(CkArrayIndex1D const&, inciter::CProxy_Discretization&, inciter::CProxy_Ghosts&, std::map<int, std::vector<unsigned long, std::allocator<unsigned long> >, std::less<int>, std::allocator<std::pair<int const, std::vector<unsigned long, std::allocator<unsigned long> > > > >&, std::map<int, std::vector<unsigned long, std::allocator<unsigned long> >, std::less<int>, std::allocator<std::pair<int const, std::vector<unsigned long, std::allocator<unsigned long> > > > >&, std::vector<unsigned long, std::allocator<unsigned long> >&) @@ -85,7 +85,7 @@ inciter::Scheme::Scheme() - 20331 + 20125 inciter::Scheme::index_element() const diff --git a/Release/test_coverage/Inciter/Scheme.hpp.gcov.html b/Release/test_coverage/Inciter/Scheme.hpp.gcov.html index 8cd4efacb162..ef8fb9515ab6 100644 --- a/Release/test_coverage/Inciter/Scheme.hpp.gcov.html +++ b/Release/test_coverage/Inciter/Scheme.hpp.gcov.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:26:06 + 2024-07-11 14:48:26 Functions: 15 @@ -182,7 +182,7 @@ 108 : : , CProxy_FV::element_t >; 109 : : 110 : : //! Empty constructor for Charm++ - 111 [ + - ]: 20331 : explicit Scheme() {} + 111 [ + - ]: 20125 : explicit Scheme() {} 112 : : 113 : : //! Constructor 114 : : //! \param[in] scheme Discretization scheme @@ -360,18 +360,18 @@ 276 : : ///@{ 277 : : //! \brief Pack/Unpack serialize member function 278 : : //! \param[in,out] p Charm++'s PUP::er serializer object reference - 279 : 62275 : void pup( PUP::er &p ) { - 280 : 62275 : p | proxy; - 281 : 62275 : p | discproxy; - 282 : 62275 : p | aleproxy; - 283 : 62275 : p | conjugategradientsproxy; - 284 : 62275 : p | ghostsproxy; - 285 : 62275 : p | bound; - 286 : 62275 : } + 279 : 61657 : void pup( PUP::er &p ) { + 280 : 61657 : p | proxy; + 281 : 61657 : p | discproxy; + 282 : 61657 : p | aleproxy; + 283 : 61657 : p | conjugategradientsproxy; + 284 : 61657 : p | ghostsproxy; + 285 : 61657 : p | bound; + 286 : 61657 : } 287 : : //! \brief Pack/Unpack serialize operator| 288 : : //! \param[in,out] p Charm++'s PUP::er serializer object reference 289 : : //! \param[in,out] s Scheme object reference - 290 [ + - ][ - - ]: 62275 : friend void operator|( PUP::er& p, Scheme& s ) { s.pup(p); } + 290 [ + - ][ - - ]: 61657 : friend void operator|( PUP::er& p, Scheme& s ) { s.pup(p); } [ - - ][ + - ] [ - - ][ - - ] [ + - ][ + - ] diff --git a/Release/test_coverage/Inciter/Sorter.cpp.func-sort-c.html b/Release/test_coverage/Inciter/Sorter.cpp.func-sort-c.html index f88a49dc4718..81b1421c8a88 100644 --- a/Release/test_coverage/Inciter/Sorter.cpp.func-sort-c.html +++ b/Release/test_coverage/Inciter/Sorter.cpp.func-sort-c.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:26:06 + 2024-07-11 14:48:26 Functions: 19 diff --git a/Release/test_coverage/Inciter/Sorter.cpp.func.html b/Release/test_coverage/Inciter/Sorter.cpp.func.html index b6c967068075..01bc234d305d 100644 --- a/Release/test_coverage/Inciter/Sorter.cpp.func.html +++ b/Release/test_coverage/Inciter/Sorter.cpp.func.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:26:06 + 2024-07-11 14:48:26 Functions: 19 diff --git a/Release/test_coverage/Inciter/Sorter.cpp.gcov.html b/Release/test_coverage/Inciter/Sorter.cpp.gcov.html index c5453371d882..36c89ae089b6 100644 --- a/Release/test_coverage/Inciter/Sorter.cpp.gcov.html +++ b/Release/test_coverage/Inciter/Sorter.cpp.gcov.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:26:06 + 2024-07-11 14:48:26 Functions: 19 diff --git a/Release/test_coverage/Inciter/Sorter.hpp.func-sort-c.html b/Release/test_coverage/Inciter/Sorter.hpp.func-sort-c.html index 24eb380ad164..fa2d6b8d5126 100644 --- a/Release/test_coverage/Inciter/Sorter.hpp.func-sort-c.html +++ b/Release/test_coverage/Inciter/Sorter.hpp.func-sort-c.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:26:06 + 2024-07-11 14:48:26 Functions: 2 @@ -73,11 +73,11 @@ inciter::Sorter::Sorter(CkMigrateMessage*) - 7858 + 7755 inciter::Sorter::pup(PUP::er&) - 24390 + 24081
diff --git a/Release/test_coverage/Inciter/Sorter.hpp.func.html b/Release/test_coverage/Inciter/Sorter.hpp.func.html index 3452199d0424..fdf68d097fd2 100644 --- a/Release/test_coverage/Inciter/Sorter.hpp.func.html +++ b/Release/test_coverage/Inciter/Sorter.hpp.func.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:26:06 + 2024-07-11 14:48:26 Functions: 2 @@ -73,11 +73,11 @@ inciter::Sorter::pup(PUP::er&) - 24390 + 24081 inciter::Sorter::Sorter(CkMigrateMessage*) - 7858 + 7755
diff --git a/Release/test_coverage/Inciter/Sorter.hpp.gcov.html b/Release/test_coverage/Inciter/Sorter.hpp.gcov.html index f90d544f03f0..63f9bf63584f 100644 --- a/Release/test_coverage/Inciter/Sorter.hpp.gcov.html +++ b/Release/test_coverage/Inciter/Sorter.hpp.gcov.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:26:06 + 2024-07-11 14:48:26 Functions: 2 @@ -156,7 +156,7 @@ 82 : : #endif 83 : : //! Migrate constructor 84 : : // cppcheck-suppress uninitMemberVarPrivate - 85 : 7858 : explicit Sorter( CkMigrateMessage* ) {} + 85 : 7755 : explicit Sorter( CkMigrateMessage* ) {} 86 : : #if defined(__clang__) 87 : : #pragma clang diagnostic pop 88 : : #endif @@ -208,37 +208,37 @@ 134 : : ///@{ 135 : : //! \brief Pack/Unpack serialize member function 136 : : //! \param[in,out] p Charm++'s PUP::er serializer object reference - 137 : 24390 : void pup( PUP::er &p ) override { - 138 : 24390 : p | m_meshid; - 139 : 24390 : p | m_host; - 140 : 24390 : p | m_meshwriter; + 137 : 24081 : void pup( PUP::er &p ) override { + 138 : 24081 : p | m_meshid; + 139 : 24081 : p | m_host; + 140 : 24081 : p | m_meshwriter; 141 : : p | m_cbs; - 142 : 24390 : p | m_scheme; - 143 : 24390 : p | m_reorderRefiner; - 144 : 24390 : p | m_ginpoel; - 145 : 24390 : p | m_coordmap; - 146 : 24390 : p | m_el; - 147 : 24390 : p | m_nbnd; - 148 : 24390 : p | m_bface; - 149 : 24390 : p | m_triinpoel; - 150 : 24390 : p | m_bnode; - 151 : 24390 : p | m_elemblockid; - 152 : 24390 : p | m_nchare; - 153 : 24390 : p | m_nodeset; - 154 : 24390 : p | m_noffset; - 155 : 24390 : p | m_nodech; - 156 : 24390 : p | m_chnode; - 157 : 24390 : p | m_edgech; - 158 : 24390 : p | m_chedge; - 159 : 24390 : p | m_msum; - 160 : 24390 : p | m_reordcomm; - 161 : 24390 : p | m_start; - 162 : 24390 : p | m_newnodes; - 163 : 24390 : p | m_newcoordmap; - 164 : 24390 : p | m_reqnodes; - 165 : 24390 : p | m_lower; - 166 : 24390 : p | m_upper; - 167 : 24390 : } + 142 : 24081 : p | m_scheme; + 143 : 24081 : p | m_reorderRefiner; + 144 : 24081 : p | m_ginpoel; + 145 : 24081 : p | m_coordmap; + 146 : 24081 : p | m_el; + 147 : 24081 : p | m_nbnd; + 148 : 24081 : p | m_bface; + 149 : 24081 : p | m_triinpoel; + 150 : 24081 : p | m_bnode; + 151 : 24081 : p | m_elemblockid; + 152 : 24081 : p | m_nchare; + 153 : 24081 : p | m_nodeset; + 154 : 24081 : p | m_noffset; + 155 : 24081 : p | m_nodech; + 156 : 24081 : p | m_chnode; + 157 : 24081 : p | m_edgech; + 158 : 24081 : p | m_chedge; + 159 : 24081 : p | m_msum; + 160 : 24081 : p | m_reordcomm; + 161 : 24081 : p | m_start; + 162 : 24081 : p | m_newnodes; + 163 : 24081 : p | m_newcoordmap; + 164 : 24081 : p | m_reqnodes; + 165 : 24081 : p | m_lower; + 166 : 24081 : p | m_upper; + 167 : 24081 : } 168 : : //! \brief Pack/Unpack serialize operator| 169 : : //! \param[in,out] p Charm++'s PUP::er serializer object reference 170 : : //! \param[in,out] s Sorter object reference diff --git a/Release/test_coverage/Inciter/Transfer.hpp.func-sort-c.html b/Release/test_coverage/Inciter/Transfer.hpp.func-sort-c.html index a2f9eb86b098..e1423d718b98 100644 --- a/Release/test_coverage/Inciter/Transfer.hpp.func-sort-c.html +++ b/Release/test_coverage/Inciter/Transfer.hpp.func-sort-c.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:26:06 + 2024-07-11 14:48:26 Functions: 1 diff --git a/Release/test_coverage/Inciter/Transfer.hpp.func.html b/Release/test_coverage/Inciter/Transfer.hpp.func.html index 107a384513a0..c68dd5fd37f9 100644 --- a/Release/test_coverage/Inciter/Transfer.hpp.func.html +++ b/Release/test_coverage/Inciter/Transfer.hpp.func.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:26:06 + 2024-07-11 14:48:26 Functions: 1 diff --git a/Release/test_coverage/Inciter/Transfer.hpp.gcov.html b/Release/test_coverage/Inciter/Transfer.hpp.gcov.html index 54f0a8bae7ae..5d085d4267b3 100644 --- a/Release/test_coverage/Inciter/Transfer.hpp.gcov.html +++ b/Release/test_coverage/Inciter/Transfer.hpp.gcov.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:26:06 + 2024-07-11 14:48:26 Functions: 1 diff --git a/Release/test_coverage/Inciter/Transporter.cpp.func-sort-c.html b/Release/test_coverage/Inciter/Transporter.cpp.func-sort-c.html index 7e40ab449da9..7862961db800 100644 --- a/Release/test_coverage/Inciter/Transporter.cpp.func-sort-c.html +++ b/Release/test_coverage/Inciter/Transporter.cpp.func-sort-c.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:26:06 + 2024-07-11 14:48:26 Functions: 42 diff --git a/Release/test_coverage/Inciter/Transporter.cpp.func.html b/Release/test_coverage/Inciter/Transporter.cpp.func.html index 9da3e60c3d47..6d2707332217 100644 --- a/Release/test_coverage/Inciter/Transporter.cpp.func.html +++ b/Release/test_coverage/Inciter/Transporter.cpp.func.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:26:06 + 2024-07-11 14:48:26 Functions: 42 diff --git a/Release/test_coverage/Inciter/Transporter.cpp.gcov.html b/Release/test_coverage/Inciter/Transporter.cpp.gcov.html index 3abe9b8a23e9..01d4d56f840f 100644 --- a/Release/test_coverage/Inciter/Transporter.cpp.gcov.html +++ b/Release/test_coverage/Inciter/Transporter.cpp.gcov.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:26:06 + 2024-07-11 14:48:26 Functions: 42 @@ -1666,7 +1666,7 @@ 1407 : : 1408 : : // compute minimum dt across meshes 1409 : 301 : tk::real dt = std::numeric_limits< tk::real >::max(); - 1410 [ + + ][ + + ]: 653 : for (auto idt : m_dtmsh) dt = std::min(dt, idt); + 1410 [ + + ][ + + ]: 653 : for (auto idt : m_dtmsh) dt = std::min(dt, idt); 1411 : : 1412 : : // clear dt-vector and counter 1413 : : m_dtmsh.clear(); diff --git a/Release/test_coverage/Inciter/Transporter.hpp.func-sort-c.html b/Release/test_coverage/Inciter/Transporter.hpp.func-sort-c.html index 76a7298de46b..274046d4d901 100644 --- a/Release/test_coverage/Inciter/Transporter.hpp.func-sort-c.html +++ b/Release/test_coverage/Inciter/Transporter.hpp.func-sort-c.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:26:06 + 2024-07-11 14:48:26 Functions: 8 diff --git a/Release/test_coverage/Inciter/Transporter.hpp.func.html b/Release/test_coverage/Inciter/Transporter.hpp.func.html index 9a232b7dc83b..4c7e1599acf7 100644 --- a/Release/test_coverage/Inciter/Transporter.hpp.func.html +++ b/Release/test_coverage/Inciter/Transporter.hpp.func.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:26:06 + 2024-07-11 14:48:26 Functions: 8 diff --git a/Release/test_coverage/Inciter/Transporter.hpp.gcov.html b/Release/test_coverage/Inciter/Transporter.hpp.gcov.html index 48c84827d4a6..b58d1808a3aa 100644 --- a/Release/test_coverage/Inciter/Transporter.hpp.gcov.html +++ b/Release/test_coverage/Inciter/Transporter.hpp.gcov.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:26:06 + 2024-07-11 14:48:26 Functions: 8 diff --git a/Release/test_coverage/Inciter/ale.ci.func-sort-c.html b/Release/test_coverage/Inciter/ale.ci.func-sort-c.html index 4fffb7c4aefd..7296475ccfde 100644 --- a/Release/test_coverage/Inciter/ale.ci.func-sort-c.html +++ b/Release/test_coverage/Inciter/ale.ci.func-sort-c.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:26:06 + 2024-07-11 14:48:26 Functions: 0 diff --git a/Release/test_coverage/Inciter/ale.ci.func.html b/Release/test_coverage/Inciter/ale.ci.func.html index 6631534f199a..dff8809e26a6 100644 --- a/Release/test_coverage/Inciter/ale.ci.func.html +++ b/Release/test_coverage/Inciter/ale.ci.func.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:26:06 + 2024-07-11 14:48:26 Functions: 0 diff --git a/Release/test_coverage/Inciter/ale.ci.gcov.html b/Release/test_coverage/Inciter/ale.ci.gcov.html index 804df1e41555..c25ed6987e65 100644 --- a/Release/test_coverage/Inciter/ale.ci.gcov.html +++ b/Release/test_coverage/Inciter/ale.ci.gcov.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:26:06 + 2024-07-11 14:48:26 Functions: 0 diff --git a/Release/test_coverage/Inciter/alecg.ci.func-sort-c.html b/Release/test_coverage/Inciter/alecg.ci.func-sort-c.html index 6c6a833e8afc..1e8d49140049 100644 --- a/Release/test_coverage/Inciter/alecg.ci.func-sort-c.html +++ b/Release/test_coverage/Inciter/alecg.ci.func-sort-c.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:26:06 + 2024-07-11 14:48:26 Functions: 0 diff --git a/Release/test_coverage/Inciter/alecg.ci.func.html b/Release/test_coverage/Inciter/alecg.ci.func.html index d50606d1c2c6..d3d82aeb4e3b 100644 --- a/Release/test_coverage/Inciter/alecg.ci.func.html +++ b/Release/test_coverage/Inciter/alecg.ci.func.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:26:06 + 2024-07-11 14:48:26 Functions: 0 diff --git a/Release/test_coverage/Inciter/alecg.ci.gcov.html b/Release/test_coverage/Inciter/alecg.ci.gcov.html index 4f7d692a4fd9..1fbaf5afb8c3 100644 --- a/Release/test_coverage/Inciter/alecg.ci.gcov.html +++ b/Release/test_coverage/Inciter/alecg.ci.gcov.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:26:06 + 2024-07-11 14:48:26 Functions: 0 diff --git a/Release/test_coverage/Inciter/dg.ci.func-sort-c.html b/Release/test_coverage/Inciter/dg.ci.func-sort-c.html index 000b41d07bab..4e3984b0181c 100644 --- a/Release/test_coverage/Inciter/dg.ci.func-sort-c.html +++ b/Release/test_coverage/Inciter/dg.ci.func-sort-c.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:26:06 + 2024-07-11 14:48:26 Functions: 0 diff --git a/Release/test_coverage/Inciter/dg.ci.func.html b/Release/test_coverage/Inciter/dg.ci.func.html index af6b0c40cedd..bfef1c23c085 100644 --- a/Release/test_coverage/Inciter/dg.ci.func.html +++ b/Release/test_coverage/Inciter/dg.ci.func.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:26:06 + 2024-07-11 14:48:26 Functions: 0 diff --git a/Release/test_coverage/Inciter/dg.ci.gcov.html b/Release/test_coverage/Inciter/dg.ci.gcov.html index c37944f9ec15..0c1e4cf3e7ce 100644 --- a/Release/test_coverage/Inciter/dg.ci.gcov.html +++ b/Release/test_coverage/Inciter/dg.ci.gcov.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:26:06 + 2024-07-11 14:48:26 Functions: 0 diff --git a/Release/test_coverage/Inciter/discretization.ci.func-sort-c.html b/Release/test_coverage/Inciter/discretization.ci.func-sort-c.html index 59ed62239149..03aa0d32074d 100644 --- a/Release/test_coverage/Inciter/discretization.ci.func-sort-c.html +++ b/Release/test_coverage/Inciter/discretization.ci.func-sort-c.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:26:06 + 2024-07-11 14:48:26 Functions: 0 diff --git a/Release/test_coverage/Inciter/discretization.ci.func.html b/Release/test_coverage/Inciter/discretization.ci.func.html index 92b606737be6..2beb7f8a0afc 100644 --- a/Release/test_coverage/Inciter/discretization.ci.func.html +++ b/Release/test_coverage/Inciter/discretization.ci.func.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:26:06 + 2024-07-11 14:48:26 Functions: 0 diff --git a/Release/test_coverage/Inciter/discretization.ci.gcov.html b/Release/test_coverage/Inciter/discretization.ci.gcov.html index 5492c81f3981..fe4448bbd8c3 100644 --- a/Release/test_coverage/Inciter/discretization.ci.gcov.html +++ b/Release/test_coverage/Inciter/discretization.ci.gcov.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:26:06 + 2024-07-11 14:48:26 Functions: 0 diff --git a/Release/test_coverage/Inciter/fv.ci.func-sort-c.html b/Release/test_coverage/Inciter/fv.ci.func-sort-c.html index 24ecf3292f19..db8c30dad670 100644 --- a/Release/test_coverage/Inciter/fv.ci.func-sort-c.html +++ b/Release/test_coverage/Inciter/fv.ci.func-sort-c.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:26:06 + 2024-07-11 14:48:26 Functions: 0 diff --git a/Release/test_coverage/Inciter/fv.ci.func.html b/Release/test_coverage/Inciter/fv.ci.func.html index 4a02ab4551f8..be3192d229a1 100644 --- a/Release/test_coverage/Inciter/fv.ci.func.html +++ b/Release/test_coverage/Inciter/fv.ci.func.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:26:06 + 2024-07-11 14:48:26 Functions: 0 diff --git a/Release/test_coverage/Inciter/fv.ci.gcov.html b/Release/test_coverage/Inciter/fv.ci.gcov.html index 710aad99351a..26631d16cc2e 100644 --- a/Release/test_coverage/Inciter/fv.ci.gcov.html +++ b/Release/test_coverage/Inciter/fv.ci.gcov.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:26:06 + 2024-07-11 14:48:26 Functions: 0 diff --git a/Release/test_coverage/Inciter/ghosts.ci.func-sort-c.html b/Release/test_coverage/Inciter/ghosts.ci.func-sort-c.html index c9aec10441cf..cf1aa136aa3e 100644 --- a/Release/test_coverage/Inciter/ghosts.ci.func-sort-c.html +++ b/Release/test_coverage/Inciter/ghosts.ci.func-sort-c.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:26:06 + 2024-07-11 14:48:26 Functions: 0 diff --git a/Release/test_coverage/Inciter/ghosts.ci.func.html b/Release/test_coverage/Inciter/ghosts.ci.func.html index 1d09846ee7b4..7b77e5e7e7f1 100644 --- a/Release/test_coverage/Inciter/ghosts.ci.func.html +++ b/Release/test_coverage/Inciter/ghosts.ci.func.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:26:06 + 2024-07-11 14:48:26 Functions: 0 diff --git a/Release/test_coverage/Inciter/ghosts.ci.gcov.html b/Release/test_coverage/Inciter/ghosts.ci.gcov.html index a880c480d54c..e15bb4fe3ffc 100644 --- a/Release/test_coverage/Inciter/ghosts.ci.gcov.html +++ b/Release/test_coverage/Inciter/ghosts.ci.gcov.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:26:06 + 2024-07-11 14:48:26 Functions: 0 diff --git a/Release/test_coverage/Inciter/index-sort-b.html b/Release/test_coverage/Inciter/index-sort-b.html index 87978681f705..495baeb3a83d 100644 --- a/Release/test_coverage/Inciter/index-sort-b.html +++ b/Release/test_coverage/Inciter/index-sort-b.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:26:06 + 2024-07-11 14:48:26 Functions: 426 @@ -154,48 +154,48 @@ 304 / 618 - ALE.hpp + PUPAMR.hpp
100.0%
100.0 % - 28 / 28 + 12 / 12 100.0 % 2 / 2 50.0 % 1 / 2 - PUPAMR.hpp + ALE.hpp
100.0%
100.0 % - 12 / 12 + 28 / 28 100.0 % 2 / 2 50.0 % 1 / 2 - fv.ci + dg.ci
100.0%
100.0 % - 3 / 3 + 7 / 7 - 0 / 0 50.0 % 2 / 4 - dg.ci + fv.ci
100.0%
100.0 % - 7 / 7 + 3 / 3 - 0 / 0 50.0 % @@ -418,74 +418,86 @@ 20 / 24 - FV.hpp + PUPAMR.cpp + +
92.7%92.7%
+ + 92.7 % + 51 / 55 + 81.8 % + 9 / 11 + - + 0 / 0 + + + discretization.ci
100.0%
100.0 % - 30 / 30 - 100.0 % - 4 / 4 + 1 / 1 + - + 0 / 0 - 0 / 0 - OversetFE.hpp + ALECG.hpp
100.0%
100.0 % - 49 / 49 + 47 / 47 100.0 % 3 / 3 - 0 / 0 - transporter.ci + Partitioner.hpp
100.0%
100.0 % - 1 / 1 - - - 0 / 0 + 28 / 28 + 100.0 % + 2 / 2 - 0 / 0 - oversetfe.ci + Sorter.hpp
100.0%
100.0 % - 4 / 4 - - - 0 / 0 + 31 / 31 + 100.0 % + 2 / 2 - 0 / 0 - ALECG.hpp + ghosts.ci
100.0%
100.0 % - 47 / 47 - 100.0 % 3 / 3 - 0 / 0 + - + 0 / 0 - Sorter.hpp + DG.hpp
100.0%
100.0 % - 31 / 31 + 50 / 50 100.0 % - 2 / 2 + 4 / 4 - 0 / 0 @@ -502,31 +514,31 @@ 0 / 0 - ghosts.ci + oversetfe.ci
100.0%
100.0 % - 3 / 3 + 4 / 4 - 0 / 0 - 0 / 0 - Partitioner.hpp + OversetFE.hpp
100.0%
100.0 % - 28 / 28 + 49 / 49 100.0 % - 2 / 2 + 3 / 3 - 0 / 0 - sorter.ci + transporter.ci
100.0%
@@ -538,62 +550,50 @@ 0 / 0 - discretization.ci + FV.hpp
100.0%
100.0 % - 1 / 1 - - - 0 / 0 + 30 / 30 + 100.0 % + 4 / 4 - 0 / 0 - DG.hpp + sorter.ci
100.0%
100.0 % - 50 / 50 - 100.0 % - 4 / 4 + 1 / 1 - 0 / 0 - - - PUPAMR.cpp - -
92.7%92.7%
- - 92.7 % - 51 / 55 - 81.8 % - 9 / 11 - 0 / 0 - Ghosts.hpp + alecg.ci
100.0%
100.0 % - 36 / 36 - 100.0 % 5 / 5 + - + 0 / 0 100.0 % 2 / 2 - alecg.ci + Ghosts.hpp
100.0%
100.0 % + 36 / 36 + 100.0 % 5 / 5 - - - 0 / 0 100.0 % 2 / 2 diff --git a/Release/test_coverage/Inciter/index-sort-f.html b/Release/test_coverage/Inciter/index-sort-f.html index a57e267b3e6d..87f17062c868 100644 --- a/Release/test_coverage/Inciter/index-sort-f.html +++ b/Release/test_coverage/Inciter/index-sort-f.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:26:06 + 2024-07-11 14:48:26 Functions: 426 @@ -177,18 +177,6 @@ 49.2 % 304 / 618 - - ALE.cpp - -
99.7%99.7%
- - 99.7 % - 324 / 325 - 95.0 % - 19 / 20 - 69.7 % - 326 / 468 - Sorter.cpp @@ -201,6 +189,18 @@ 72.8 % 134 / 184 + + ALE.cpp + +
99.7%99.7%
+ + 99.7 % + 324 / 325 + 95.0 % + 19 / 20 + 69.7 % + 326 / 468 + Discretization.cpp @@ -250,28 +250,16 @@ 416 / 674 - transporter.ci - -
100.0%
- - 100.0 % - 1 / 1 - - - 0 / 0 - - - 0 / 0 - - - oversetfe.ci + dg.ci
100.0%
100.0 % - 4 / 4 - - - 0 / 0 + 7 / 7 - 0 / 0 + 50.0 % + 2 / 4 alecg.ci @@ -286,19 +274,19 @@ 2 / 2 - ale.ci + discretization.ci
100.0%
100.0 % - 3 / 3 + 1 / 1 - 0 / 0 - 0 / 0 - fv.ci + ghosts.ci
100.0%
@@ -306,11 +294,11 @@ 3 / 3 - 0 / 0 - 50.0 % - 2 / 4 + - + 0 / 0 - ghosts.ci + ale.ci
100.0%
@@ -322,31 +310,31 @@ 0 / 0 - sorter.ci + oversetfe.ci
100.0%
100.0 % - 1 / 1 + 4 / 4 - 0 / 0 - 0 / 0 - dg.ci + transporter.ci
100.0%
100.0 % - 7 / 7 + 1 / 1 + - + 0 / 0 - 0 / 0 - 50.0 % - 2 / 4 - discretization.ci + sorter.ci
100.0%
@@ -358,16 +346,16 @@ 0 / 0 - Transfer.hpp + fv.ci
100.0%
100.0 % - 8 / 8 - 100.0 % - 1 / 1 + 3 / 3 + - + 0 / 0 50.0 % - 3 / 6 + 2 / 4 FaceData.hpp @@ -382,40 +370,40 @@ 8 / 52 - FaceData.cpp + Transfer.hpp
100.0%
100.0 % - 11 / 11 + 8 / 8 100.0 % 1 / 1 50.0 % - 8 / 16 + 3 / 6 - ALE.hpp + FaceData.cpp
100.0%
100.0 % - 28 / 28 + 11 / 11 100.0 % - 2 / 2 + 1 / 1 50.0 % - 1 / 2 + 8 / 16 - Sorter.hpp + NodeDiagnostics.cpp
100.0%
100.0 % - 31 / 31 + 29 / 29 100.0 % 2 / 2 - - - 0 / 0 + 70.5 % + 31 / 44 PUPAMR.hpp @@ -430,16 +418,16 @@ 1 / 2 - DiagReducer.cpp + ALE.hpp
100.0%
100.0 % - 23 / 23 + 28 / 28 100.0 % 2 / 2 - 82.1 % - 23 / 28 + 50.0 % + 1 / 2 Partitioner.hpp @@ -453,18 +441,6 @@ - 0 / 0 - - NodeDiagnostics.cpp - -
100.0%
- - 100.0 % - 29 / 29 - 100.0 % - 2 / 2 - 70.5 % - 31 / 44 - NodeBC.cpp @@ -478,28 +454,28 @@ 15 / 22 - OversetFE.hpp + Sorter.hpp
100.0%
100.0 % - 49 / 49 + 31 / 31 100.0 % - 3 / 3 + 2 / 2 - 0 / 0 - ALECG.hpp + DiagReducer.cpp
100.0%
100.0 % - 47 / 47 + 23 / 23 100.0 % - 3 / 3 - - - 0 / 0 + 2 / 2 + 82.1 % + 23 / 28 Refiner.hpp @@ -513,6 +489,18 @@ 80.0 % 8 / 10 + + ALECG.hpp + +
100.0%
+ + 100.0 % + 47 / 47 + 100.0 % + 3 / 3 + - + 0 / 0 + ElemDiagnostics.cpp @@ -538,14 +526,14 @@ 72 / 92 - FV.hpp + OversetFE.hpp
100.0%
100.0 % - 30 / 30 + 49 / 49 100.0 % - 4 / 4 + 3 / 3 - 0 / 0 @@ -561,6 +549,18 @@ - 0 / 0 + + FV.hpp + +
100.0%
+ + 100.0 % + 30 / 30 + 100.0 % + 4 / 4 + - + 0 / 0 + Ghosts.hpp diff --git a/Release/test_coverage/Inciter/index-sort-l.html b/Release/test_coverage/Inciter/index-sort-l.html index ea7dab290310..6fbfdf8ff6be 100644 --- a/Release/test_coverage/Inciter/index-sort-l.html +++ b/Release/test_coverage/Inciter/index-sort-l.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:26:06 + 2024-07-11 14:48:26 Functions: 426 @@ -274,7 +274,7 @@ 326 / 468 - transporter.ci + discretization.ci
100.0%
@@ -286,7 +286,7 @@ 0 / 0 - sorter.ci + transporter.ci
100.0%
@@ -298,7 +298,7 @@ 0 / 0 - discretization.ci + sorter.ci
100.0%
@@ -310,7 +310,7 @@ 0 / 0 - ale.ci + ghosts.ci
100.0%
@@ -322,7 +322,7 @@ 0 / 0 - fv.ci + ale.ci
100.0%
@@ -330,11 +330,11 @@ 3 / 3 - 0 / 0 - 50.0 % - 2 / 4 + - + 0 / 0 - ghosts.ci + fv.ci
100.0%
@@ -342,8 +342,8 @@ 3 / 3 - 0 / 0 - - - 0 / 0 + 50.0 % + 2 / 4 oversetfe.ci diff --git a/Release/test_coverage/Inciter/index.html b/Release/test_coverage/Inciter/index.html index 2322af3a8523..bdaad23390e0 100644 --- a/Release/test_coverage/Inciter/index.html +++ b/Release/test_coverage/Inciter/index.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:26:06 + 2024-07-11 14:48:26 Functions: 426 diff --git a/Release/test_coverage/Inciter/oversetfe.ci.func-sort-c.html b/Release/test_coverage/Inciter/oversetfe.ci.func-sort-c.html index fdd0c3b2001c..a3763b2b4fff 100644 --- a/Release/test_coverage/Inciter/oversetfe.ci.func-sort-c.html +++ b/Release/test_coverage/Inciter/oversetfe.ci.func-sort-c.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:26:06 + 2024-07-11 14:48:26 Functions: 0 diff --git a/Release/test_coverage/Inciter/oversetfe.ci.func.html b/Release/test_coverage/Inciter/oversetfe.ci.func.html index 95a63630885b..77318aeccbdf 100644 --- a/Release/test_coverage/Inciter/oversetfe.ci.func.html +++ b/Release/test_coverage/Inciter/oversetfe.ci.func.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:26:06 + 2024-07-11 14:48:26 Functions: 0 diff --git a/Release/test_coverage/Inciter/oversetfe.ci.gcov.html b/Release/test_coverage/Inciter/oversetfe.ci.gcov.html index b8c30e4817b3..396d502e1ec8 100644 --- a/Release/test_coverage/Inciter/oversetfe.ci.gcov.html +++ b/Release/test_coverage/Inciter/oversetfe.ci.gcov.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:26:06 + 2024-07-11 14:48:26 Functions: 0 diff --git a/Release/test_coverage/Inciter/sorter.ci.func-sort-c.html b/Release/test_coverage/Inciter/sorter.ci.func-sort-c.html index 239980a19d6e..92485f7efbce 100644 --- a/Release/test_coverage/Inciter/sorter.ci.func-sort-c.html +++ b/Release/test_coverage/Inciter/sorter.ci.func-sort-c.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:26:06 + 2024-07-11 14:48:26 Functions: 0 diff --git a/Release/test_coverage/Inciter/sorter.ci.func.html b/Release/test_coverage/Inciter/sorter.ci.func.html index 5823f7e89e30..ccb79f48a7c0 100644 --- a/Release/test_coverage/Inciter/sorter.ci.func.html +++ b/Release/test_coverage/Inciter/sorter.ci.func.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:26:06 + 2024-07-11 14:48:26 Functions: 0 diff --git a/Release/test_coverage/Inciter/sorter.ci.gcov.html b/Release/test_coverage/Inciter/sorter.ci.gcov.html index 354586c66d09..01ee04d67300 100644 --- a/Release/test_coverage/Inciter/sorter.ci.gcov.html +++ b/Release/test_coverage/Inciter/sorter.ci.gcov.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:26:06 + 2024-07-11 14:48:26 Functions: 0 diff --git a/Release/test_coverage/Inciter/transporter.ci.func-sort-c.html b/Release/test_coverage/Inciter/transporter.ci.func-sort-c.html index 772bc4b32aa3..45082d382521 100644 --- a/Release/test_coverage/Inciter/transporter.ci.func-sort-c.html +++ b/Release/test_coverage/Inciter/transporter.ci.func-sort-c.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:26:06 + 2024-07-11 14:48:26 Functions: 0 diff --git a/Release/test_coverage/Inciter/transporter.ci.func.html b/Release/test_coverage/Inciter/transporter.ci.func.html index 7e06fdfa7128..582d387c0d86 100644 --- a/Release/test_coverage/Inciter/transporter.ci.func.html +++ b/Release/test_coverage/Inciter/transporter.ci.func.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:26:06 + 2024-07-11 14:48:26 Functions: 0 diff --git a/Release/test_coverage/Inciter/transporter.ci.gcov.html b/Release/test_coverage/Inciter/transporter.ci.gcov.html index c8de55620637..92ba9a953eb7 100644 --- a/Release/test_coverage/Inciter/transporter.ci.gcov.html +++ b/Release/test_coverage/Inciter/transporter.ci.gcov.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:26:06 + 2024-07-11 14:48:26 Functions: 0 diff --git a/Release/test_coverage/LinearSolver/CSR.cpp.func-sort-c.html b/Release/test_coverage/LinearSolver/CSR.cpp.func-sort-c.html index 5eafd02afe63..572bbb500e17 100644 --- a/Release/test_coverage/LinearSolver/CSR.cpp.func-sort-c.html +++ b/Release/test_coverage/LinearSolver/CSR.cpp.func-sort-c.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:26:06 + 2024-07-11 14:48:26 Functions: 8 diff --git a/Release/test_coverage/LinearSolver/CSR.cpp.func.html b/Release/test_coverage/LinearSolver/CSR.cpp.func.html index 382dc9e7a97d..17cd5527fe2d 100644 --- a/Release/test_coverage/LinearSolver/CSR.cpp.func.html +++ b/Release/test_coverage/LinearSolver/CSR.cpp.func.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:26:06 + 2024-07-11 14:48:26 Functions: 8 diff --git a/Release/test_coverage/LinearSolver/CSR.cpp.gcov.html b/Release/test_coverage/LinearSolver/CSR.cpp.gcov.html index c9857b863b1d..683ab0394f2c 100644 --- a/Release/test_coverage/LinearSolver/CSR.cpp.gcov.html +++ b/Release/test_coverage/LinearSolver/CSR.cpp.gcov.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:26:06 + 2024-07-11 14:48:26 Functions: 8 @@ -173,8 +173,8 @@ 95 : : { 96 : 13371648 : auto rncomp = row * ncomp; 97 : : - 98 [ + - ]: 94258977 : for (std::size_t n=0, j=ia[rncomp+pos]-1; j<ia[rncomp+pos+1]-1; ++j, ++n) - 99 [ + + ]: 94258977 : if (col*ncomp+pos+1 == ja[j]) + 98 [ + - ]: 94242075 : for (std::size_t n=0, j=ia[rncomp+pos]-1; j<ia[rncomp+pos+1]-1; ++j, ++n) + 99 [ + + ]: 94242075 : if (col*ncomp+pos+1 == ja[j]) 100 : 13371648 : return a[ia[rncomp+pos]-1+n]; 101 : : 102 [ - - ][ - - ]: 0 : Throw("Sparse matrix index not found"); diff --git a/Release/test_coverage/LinearSolver/CSR.hpp.func-sort-c.html b/Release/test_coverage/LinearSolver/CSR.hpp.func-sort-c.html index ab39da74c6d5..96a87afb3404 100644 --- a/Release/test_coverage/LinearSolver/CSR.hpp.func-sort-c.html +++ b/Release/test_coverage/LinearSolver/CSR.hpp.func-sort-c.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:26:06 + 2024-07-11 14:48:26 Functions: 1 @@ -73,7 +73,7 @@ tk::CSR::pup(PUP::er&) - 285 + 288
diff --git a/Release/test_coverage/LinearSolver/CSR.hpp.func.html b/Release/test_coverage/LinearSolver/CSR.hpp.func.html index dd254019f27f..8464ecc41d4a 100644 --- a/Release/test_coverage/LinearSolver/CSR.hpp.func.html +++ b/Release/test_coverage/LinearSolver/CSR.hpp.func.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:26:06 + 2024-07-11 14:48:26 Functions: 1 @@ -73,7 +73,7 @@ tk::CSR::pup(PUP::er&) - 285 + 288
diff --git a/Release/test_coverage/LinearSolver/CSR.hpp.gcov.html b/Release/test_coverage/LinearSolver/CSR.hpp.gcov.html index 00c254d94c21..1ee3d5da91f6 100644 --- a/Release/test_coverage/LinearSolver/CSR.hpp.gcov.html +++ b/Release/test_coverage/LinearSolver/CSR.hpp.gcov.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:26:06 + 2024-07-11 14:48:26 Functions: 1 @@ -162,17 +162,17 @@ 80 : : ///@{ 81 : : //! \brief Pack/Unpack serialize member function 82 : : //! \param[in,out] p Charm++'s PUP::er serializer object reference - 83 : 285 : void pup( PUP::er &p ) { - 84 : 285 : p | ncomp; - 85 : 285 : p | rnz; - 86 : 285 : p | ia; - 87 : 285 : p | ja; - 88 : 285 : p | a; - 89 : 285 : } + 83 : 288 : void pup( PUP::er &p ) { + 84 : 288 : p | ncomp; + 85 : 288 : p | rnz; + 86 : 288 : p | ia; + 87 : 288 : p | ja; + 88 : 288 : p | a; + 89 : 288 : } 90 : : //! \brief Pack/Unpack serialize operator| 91 : : //! \param[in,out] p Charm++'s PUP::er serializer object reference 92 : : //! \param[in,out] c CSR object reference - 93 [ - - ][ - - ]: 285 : friend void operator|( PUP::er& p, CSR& c ) { c.pup(p); } + 93 [ - - ][ - - ]: 288 : friend void operator|( PUP::er& p, CSR& c ) { c.pup(p); } [ - - ][ + - ] [ - - ][ - - ] [ + - ][ + - ] diff --git a/Release/test_coverage/LinearSolver/ConjugateGradients.cpp.func-sort-c.html b/Release/test_coverage/LinearSolver/ConjugateGradients.cpp.func-sort-c.html index ebb85b06ba64..8378c6e5d399 100644 --- a/Release/test_coverage/LinearSolver/ConjugateGradients.cpp.func-sort-c.html +++ b/Release/test_coverage/LinearSolver/ConjugateGradients.cpp.func-sort-c.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:26:06 + 2024-07-11 14:48:26 Functions: 20 diff --git a/Release/test_coverage/LinearSolver/ConjugateGradients.cpp.func.html b/Release/test_coverage/LinearSolver/ConjugateGradients.cpp.func.html index d09f18a97e2a..41f8b89a56ed 100644 --- a/Release/test_coverage/LinearSolver/ConjugateGradients.cpp.func.html +++ b/Release/test_coverage/LinearSolver/ConjugateGradients.cpp.func.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:26:06 + 2024-07-11 14:48:26 Functions: 20 diff --git a/Release/test_coverage/LinearSolver/ConjugateGradients.cpp.gcov.html b/Release/test_coverage/LinearSolver/ConjugateGradients.cpp.gcov.html index 1ee53f94bf2e..7d7935bc44b5 100644 --- a/Release/test_coverage/LinearSolver/ConjugateGradients.cpp.gcov.html +++ b/Release/test_coverage/LinearSolver/ConjugateGradients.cpp.gcov.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:26:06 + 2024-07-11 14:48:26 Functions: 20 diff --git a/Release/test_coverage/LinearSolver/ConjugateGradients.hpp.func-sort-c.html b/Release/test_coverage/LinearSolver/ConjugateGradients.hpp.func-sort-c.html index 581f18426f46..91fa10030fb9 100644 --- a/Release/test_coverage/LinearSolver/ConjugateGradients.hpp.func-sort-c.html +++ b/Release/test_coverage/LinearSolver/ConjugateGradients.hpp.func-sort-c.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:26:06 + 2024-07-11 14:48:26 Functions: 2 @@ -73,11 +73,11 @@ tk::ConjugateGradients::ConjugateGradients(CkMigrateMessage*) - 61 + 62 tk::ConjugateGradients::pup(PUP::er&) - 204 + 207
diff --git a/Release/test_coverage/LinearSolver/ConjugateGradients.hpp.func.html b/Release/test_coverage/LinearSolver/ConjugateGradients.hpp.func.html index 28333bc5c4a4..f53c7b78bfba 100644 --- a/Release/test_coverage/LinearSolver/ConjugateGradients.hpp.func.html +++ b/Release/test_coverage/LinearSolver/ConjugateGradients.hpp.func.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:26:06 + 2024-07-11 14:48:26 Functions: 2 @@ -73,11 +73,11 @@ tk::ConjugateGradients::pup(PUP::er&) - 204 + 207 tk::ConjugateGradients::ConjugateGradients(CkMigrateMessage*) - 61 + 62
diff --git a/Release/test_coverage/LinearSolver/ConjugateGradients.hpp.gcov.html b/Release/test_coverage/LinearSolver/ConjugateGradients.hpp.gcov.html index eebca20b6eac..1c580bbe4b15 100644 --- a/Release/test_coverage/LinearSolver/ConjugateGradients.hpp.gcov.html +++ b/Release/test_coverage/LinearSolver/ConjugateGradients.hpp.gcov.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:26:06 + 2024-07-11 14:48:26 Functions: 2 @@ -150,7 +150,7 @@ 76 [ - - ][ + - ]: 21 : gid, lid, nodecommmap ) {} 77 : : 78 : : //! Migrate constructor - 79 : 61 : explicit ConjugateGradients( CkMigrateMessage* ) {} + 79 : 62 : explicit ConjugateGradients( CkMigrateMessage* ) {} 80 : : #if defined(__clang__) 81 : : #pragma clang diagnostic pop 82 : : #endif @@ -206,37 +206,37 @@ 132 : : ///@{ 133 : : //! \brief Pack/Unpack serialize member function 134 : : //! \param[in,out] p Charm++'s PUP::er serializer object reference - 135 : 204 : void pup( PUP::er &p ) override { - 136 : 204 : p | m_A; - 137 : 204 : p | m_x; - 138 : 204 : p | m_b; - 139 : 204 : p | m_gid; - 140 : 204 : p | m_lid; - 141 : 204 : p | m_nodeCommMap; - 142 : 204 : p | m_r; - 143 : 204 : p | m_rc; - 144 : 204 : p | m_nr; - 145 : 204 : p | m_bc; - 146 : 204 : p | m_bcc; - 147 : 204 : p | m_bcmask; - 148 : 204 : p | m_nb; - 149 : 204 : p | m_p; - 150 : 204 : p | m_q; - 151 : 204 : p | m_qc; - 152 : 204 : p | m_nq; - 153 : 204 : p | m_initres; - 154 : 204 : p | m_solved; - 155 : 204 : p | m_normb; - 156 : 204 : p | m_it; - 157 : 204 : p | m_maxit; - 158 : 204 : p | m_tol; - 159 : 204 : p | m_rho; - 160 : 204 : p | m_rho0; - 161 : 204 : p | m_alpha; - 162 : 204 : p | m_converged; - 163 : 204 : p | m_xc; - 164 : 204 : p | m_nx; - 165 : 204 : } + 135 : 207 : void pup( PUP::er &p ) override { + 136 : 207 : p | m_A; + 137 : 207 : p | m_x; + 138 : 207 : p | m_b; + 139 : 207 : p | m_gid; + 140 : 207 : p | m_lid; + 141 : 207 : p | m_nodeCommMap; + 142 : 207 : p | m_r; + 143 : 207 : p | m_rc; + 144 : 207 : p | m_nr; + 145 : 207 : p | m_bc; + 146 : 207 : p | m_bcc; + 147 : 207 : p | m_bcmask; + 148 : 207 : p | m_nb; + 149 : 207 : p | m_p; + 150 : 207 : p | m_q; + 151 : 207 : p | m_qc; + 152 : 207 : p | m_nq; + 153 : 207 : p | m_initres; + 154 : 207 : p | m_solved; + 155 : 207 : p | m_normb; + 156 : 207 : p | m_it; + 157 : 207 : p | m_maxit; + 158 : 207 : p | m_tol; + 159 : 207 : p | m_rho; + 160 : 207 : p | m_rho0; + 161 : 207 : p | m_alpha; + 162 : 207 : p | m_converged; + 163 : 207 : p | m_xc; + 164 : 207 : p | m_nx; + 165 : 207 : } 166 : : //! \brief Pack/Unpack serialize operator| 167 : : //! \param[in,out] p Charm++'s PUP::er serializer object reference 168 : : //! \param[in,out] c ConjugateGradients object reference diff --git a/Release/test_coverage/LinearSolver/conjugategradients.ci.func-sort-c.html b/Release/test_coverage/LinearSolver/conjugategradients.ci.func-sort-c.html index e6eafbd05419..3c2f57970213 100644 --- a/Release/test_coverage/LinearSolver/conjugategradients.ci.func-sort-c.html +++ b/Release/test_coverage/LinearSolver/conjugategradients.ci.func-sort-c.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:26:06 + 2024-07-11 14:48:26 Functions: 0 diff --git a/Release/test_coverage/LinearSolver/conjugategradients.ci.func.html b/Release/test_coverage/LinearSolver/conjugategradients.ci.func.html index 60da32f6e0f4..1867d01fd7e1 100644 --- a/Release/test_coverage/LinearSolver/conjugategradients.ci.func.html +++ b/Release/test_coverage/LinearSolver/conjugategradients.ci.func.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:26:06 + 2024-07-11 14:48:26 Functions: 0 diff --git a/Release/test_coverage/LinearSolver/conjugategradients.ci.gcov.html b/Release/test_coverage/LinearSolver/conjugategradients.ci.gcov.html index 544887c6f458..a0a222b96e7e 100644 --- a/Release/test_coverage/LinearSolver/conjugategradients.ci.gcov.html +++ b/Release/test_coverage/LinearSolver/conjugategradients.ci.gcov.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:26:06 + 2024-07-11 14:48:26 Functions: 0 diff --git a/Release/test_coverage/LinearSolver/index-sort-b.html b/Release/test_coverage/LinearSolver/index-sort-b.html index 58ddf67f6a08..8fd2a818121a 100644 --- a/Release/test_coverage/LinearSolver/index-sort-b.html +++ b/Release/test_coverage/LinearSolver/index-sort-b.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:26:06 + 2024-07-11 14:48:26 Functions: 31 diff --git a/Release/test_coverage/LinearSolver/index-sort-f.html b/Release/test_coverage/LinearSolver/index-sort-f.html index bd520da09f4b..250429fa534e 100644 --- a/Release/test_coverage/LinearSolver/index-sort-f.html +++ b/Release/test_coverage/LinearSolver/index-sort-f.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:26:06 + 2024-07-11 14:48:26 Functions: 31 diff --git a/Release/test_coverage/LinearSolver/index-sort-l.html b/Release/test_coverage/LinearSolver/index-sort-l.html index 1b348b59d726..a8bbb9375049 100644 --- a/Release/test_coverage/LinearSolver/index-sort-l.html +++ b/Release/test_coverage/LinearSolver/index-sort-l.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:26:06 + 2024-07-11 14:48:26 Functions: 31 diff --git a/Release/test_coverage/LinearSolver/index.html b/Release/test_coverage/LinearSolver/index.html index d5b5bc002484..98b0ca464438 100644 --- a/Release/test_coverage/LinearSolver/index.html +++ b/Release/test_coverage/LinearSolver/index.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:26:06 + 2024-07-11 14:48:26 Functions: 31 diff --git a/Release/test_coverage/LoadBalance/LinearMap.cpp.func-sort-c.html b/Release/test_coverage/LoadBalance/LinearMap.cpp.func-sort-c.html index 97f73312fb39..27414fdc32db 100644 --- a/Release/test_coverage/LoadBalance/LinearMap.cpp.func-sort-c.html +++ b/Release/test_coverage/LoadBalance/LinearMap.cpp.func-sort-c.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:26:06 + 2024-07-11 14:48:26 Functions: 2 diff --git a/Release/test_coverage/LoadBalance/LinearMap.cpp.func.html b/Release/test_coverage/LoadBalance/LinearMap.cpp.func.html index 6a113034bf25..0f0d4a0f2d2c 100644 --- a/Release/test_coverage/LoadBalance/LinearMap.cpp.func.html +++ b/Release/test_coverage/LoadBalance/LinearMap.cpp.func.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:26:06 + 2024-07-11 14:48:26 Functions: 2 diff --git a/Release/test_coverage/LoadBalance/LinearMap.cpp.gcov.html b/Release/test_coverage/LoadBalance/LinearMap.cpp.gcov.html index 0330962efeb5..e96607212536 100644 --- a/Release/test_coverage/LoadBalance/LinearMap.cpp.gcov.html +++ b/Release/test_coverage/LoadBalance/LinearMap.cpp.gcov.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:26:06 + 2024-07-11 14:48:26 Functions: 2 diff --git a/Release/test_coverage/LoadBalance/LinearMap.hpp.func-sort-c.html b/Release/test_coverage/LoadBalance/LinearMap.hpp.func-sort-c.html index 46107826452e..2c5631c6e81a 100644 --- a/Release/test_coverage/LoadBalance/LinearMap.hpp.func-sort-c.html +++ b/Release/test_coverage/LoadBalance/LinearMap.hpp.func-sort-c.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:26:06 + 2024-07-11 14:48:26 Functions: 0 diff --git a/Release/test_coverage/LoadBalance/LinearMap.hpp.func.html b/Release/test_coverage/LoadBalance/LinearMap.hpp.func.html index bb30dadaf845..96828fcf924f 100644 --- a/Release/test_coverage/LoadBalance/LinearMap.hpp.func.html +++ b/Release/test_coverage/LoadBalance/LinearMap.hpp.func.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:26:06 + 2024-07-11 14:48:26 Functions: 0 diff --git a/Release/test_coverage/LoadBalance/LinearMap.hpp.gcov.html b/Release/test_coverage/LoadBalance/LinearMap.hpp.gcov.html index decd65a46b48..ef1bbceb1910 100644 --- a/Release/test_coverage/LoadBalance/LinearMap.hpp.gcov.html +++ b/Release/test_coverage/LoadBalance/LinearMap.hpp.gcov.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:26:06 + 2024-07-11 14:48:26 Functions: 0 diff --git a/Release/test_coverage/LoadBalance/UnsMeshMap.cpp.func-sort-c.html b/Release/test_coverage/LoadBalance/UnsMeshMap.cpp.func-sort-c.html index cd967aa6f9c9..419a1a1886d3 100644 --- a/Release/test_coverage/LoadBalance/UnsMeshMap.cpp.func-sort-c.html +++ b/Release/test_coverage/LoadBalance/UnsMeshMap.cpp.func-sort-c.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:26:06 + 2024-07-11 14:48:26 Functions: 4 diff --git a/Release/test_coverage/LoadBalance/UnsMeshMap.cpp.func.html b/Release/test_coverage/LoadBalance/UnsMeshMap.cpp.func.html index f5f3d497af6b..12a099635ae3 100644 --- a/Release/test_coverage/LoadBalance/UnsMeshMap.cpp.func.html +++ b/Release/test_coverage/LoadBalance/UnsMeshMap.cpp.func.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:26:06 + 2024-07-11 14:48:26 Functions: 4 diff --git a/Release/test_coverage/LoadBalance/UnsMeshMap.cpp.gcov.html b/Release/test_coverage/LoadBalance/UnsMeshMap.cpp.gcov.html index d736b1e2e5bc..f9439fdf3d03 100644 --- a/Release/test_coverage/LoadBalance/UnsMeshMap.cpp.gcov.html +++ b/Release/test_coverage/LoadBalance/UnsMeshMap.cpp.gcov.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:26:06 + 2024-07-11 14:48:26 Functions: 4 diff --git a/Release/test_coverage/LoadBalance/ZoltanInterOp.cpp.func-sort-c.html b/Release/test_coverage/LoadBalance/ZoltanInterOp.cpp.func-sort-c.html index 2856689cec73..213f9950818a 100644 --- a/Release/test_coverage/LoadBalance/ZoltanInterOp.cpp.func-sort-c.html +++ b/Release/test_coverage/LoadBalance/ZoltanInterOp.cpp.func-sort-c.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:26:06 + 2024-07-11 14:48:26 Functions: 5 diff --git a/Release/test_coverage/LoadBalance/ZoltanInterOp.cpp.func.html b/Release/test_coverage/LoadBalance/ZoltanInterOp.cpp.func.html index e72adca53c20..d4767ad1bf96 100644 --- a/Release/test_coverage/LoadBalance/ZoltanInterOp.cpp.func.html +++ b/Release/test_coverage/LoadBalance/ZoltanInterOp.cpp.func.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:26:06 + 2024-07-11 14:48:26 Functions: 5 diff --git a/Release/test_coverage/LoadBalance/ZoltanInterOp.cpp.gcov.html b/Release/test_coverage/LoadBalance/ZoltanInterOp.cpp.gcov.html index a2658b059870..7e099c5947b7 100644 --- a/Release/test_coverage/LoadBalance/ZoltanInterOp.cpp.gcov.html +++ b/Release/test_coverage/LoadBalance/ZoltanInterOp.cpp.gcov.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:26:06 + 2024-07-11 14:48:26 Functions: 5 diff --git a/Release/test_coverage/LoadBalance/index-sort-b.html b/Release/test_coverage/LoadBalance/index-sort-b.html index b58e1ed999e1..c590543c650b 100644 --- a/Release/test_coverage/LoadBalance/index-sort-b.html +++ b/Release/test_coverage/LoadBalance/index-sort-b.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:26:06 + 2024-07-11 14:48:26 Functions: 11 diff --git a/Release/test_coverage/LoadBalance/index-sort-f.html b/Release/test_coverage/LoadBalance/index-sort-f.html index 7f5edce17875..843b820c8fec 100644 --- a/Release/test_coverage/LoadBalance/index-sort-f.html +++ b/Release/test_coverage/LoadBalance/index-sort-f.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:26:06 + 2024-07-11 14:48:26 Functions: 11 diff --git a/Release/test_coverage/LoadBalance/index-sort-l.html b/Release/test_coverage/LoadBalance/index-sort-l.html index 6ffa98a09222..3a37d3140732 100644 --- a/Release/test_coverage/LoadBalance/index-sort-l.html +++ b/Release/test_coverage/LoadBalance/index-sort-l.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:26:06 + 2024-07-11 14:48:26 Functions: 11 diff --git a/Release/test_coverage/LoadBalance/index.html b/Release/test_coverage/LoadBalance/index.html index 893fae35c0f6..053ba614268a 100644 --- a/Release/test_coverage/LoadBalance/index.html +++ b/Release/test_coverage/LoadBalance/index.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:26:06 + 2024-07-11 14:48:26 Functions: 11 diff --git a/Release/test_coverage/Main/Inciter.cpp.func-sort-c.html b/Release/test_coverage/Main/Inciter.cpp.func-sort-c.html index 9f90fec2fe86..bfd6935adab7 100644 --- a/Release/test_coverage/Main/Inciter.cpp.func-sort-c.html +++ b/Release/test_coverage/Main/Inciter.cpp.func-sort-c.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:26:06 + 2024-07-11 14:48:26 Functions: 8 diff --git a/Release/test_coverage/Main/Inciter.cpp.func.html b/Release/test_coverage/Main/Inciter.cpp.func.html index db6d45f53e11..61c149877b03 100644 --- a/Release/test_coverage/Main/Inciter.cpp.func.html +++ b/Release/test_coverage/Main/Inciter.cpp.func.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:26:06 + 2024-07-11 14:48:26 Functions: 8 diff --git a/Release/test_coverage/Main/Inciter.cpp.gcov.html b/Release/test_coverage/Main/Inciter.cpp.gcov.html index d0718e0bcb72..3d8425e69e55 100644 --- a/Release/test_coverage/Main/Inciter.cpp.gcov.html +++ b/Release/test_coverage/Main/Inciter.cpp.gcov.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:26:06 + 2024-07-11 14:48:26 Functions: 8 diff --git a/Release/test_coverage/Main/InciterDriver.cpp.func-sort-c.html b/Release/test_coverage/Main/InciterDriver.cpp.func-sort-c.html index dc44e40e02c9..7a106f7d5aa9 100644 --- a/Release/test_coverage/Main/InciterDriver.cpp.func-sort-c.html +++ b/Release/test_coverage/Main/InciterDriver.cpp.func-sort-c.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:26:06 + 2024-07-11 14:48:26 Functions: 2 diff --git a/Release/test_coverage/Main/InciterDriver.cpp.func.html b/Release/test_coverage/Main/InciterDriver.cpp.func.html index 29e3a2e52075..585959422c64 100644 --- a/Release/test_coverage/Main/InciterDriver.cpp.func.html +++ b/Release/test_coverage/Main/InciterDriver.cpp.func.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:26:06 + 2024-07-11 14:48:26 Functions: 2 diff --git a/Release/test_coverage/Main/InciterDriver.cpp.gcov.html b/Release/test_coverage/Main/InciterDriver.cpp.gcov.html index b0bcd8279e34..a4384e219b8d 100644 --- a/Release/test_coverage/Main/InciterDriver.cpp.gcov.html +++ b/Release/test_coverage/Main/InciterDriver.cpp.gcov.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:26:06 + 2024-07-11 14:48:26 Functions: 2 diff --git a/Release/test_coverage/Main/InciterPrint.cpp.func-sort-c.html b/Release/test_coverage/Main/InciterPrint.cpp.func-sort-c.html index 961cdb67339e..5e1482ae209b 100644 --- a/Release/test_coverage/Main/InciterPrint.cpp.func-sort-c.html +++ b/Release/test_coverage/Main/InciterPrint.cpp.func-sort-c.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:26:06 + 2024-07-11 14:48:26 Functions: 2 diff --git a/Release/test_coverage/Main/InciterPrint.cpp.func.html b/Release/test_coverage/Main/InciterPrint.cpp.func.html index 8fd17b1d9552..a3413f51d6be 100644 --- a/Release/test_coverage/Main/InciterPrint.cpp.func.html +++ b/Release/test_coverage/Main/InciterPrint.cpp.func.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:26:06 + 2024-07-11 14:48:26 Functions: 2 diff --git a/Release/test_coverage/Main/InciterPrint.cpp.gcov.html b/Release/test_coverage/Main/InciterPrint.cpp.gcov.html index ca40a6a5931b..ea20640a72a8 100644 --- a/Release/test_coverage/Main/InciterPrint.cpp.gcov.html +++ b/Release/test_coverage/Main/InciterPrint.cpp.gcov.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:26:06 + 2024-07-11 14:48:26 Functions: 2 diff --git a/Release/test_coverage/Main/InciterPrint.hpp.func-sort-c.html b/Release/test_coverage/Main/InciterPrint.hpp.func-sort-c.html index 71a7ef1488c6..76130bb06898 100644 --- a/Release/test_coverage/Main/InciterPrint.hpp.func-sort-c.html +++ b/Release/test_coverage/Main/InciterPrint.hpp.func-sort-c.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:26:06 + 2024-07-11 14:48:26 Functions: 10 diff --git a/Release/test_coverage/Main/InciterPrint.hpp.func.html b/Release/test_coverage/Main/InciterPrint.hpp.func.html index 369f3a4d67ce..ab72b4812eb0 100644 --- a/Release/test_coverage/Main/InciterPrint.hpp.func.html +++ b/Release/test_coverage/Main/InciterPrint.hpp.func.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:26:06 + 2024-07-11 14:48:26 Functions: 10 diff --git a/Release/test_coverage/Main/InciterPrint.hpp.gcov.html b/Release/test_coverage/Main/InciterPrint.hpp.gcov.html index cb01feb45d06..755c75ed120e 100644 --- a/Release/test_coverage/Main/InciterPrint.hpp.gcov.html +++ b/Release/test_coverage/Main/InciterPrint.hpp.gcov.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:26:06 + 2024-07-11 14:48:26 Functions: 10 diff --git a/Release/test_coverage/Main/Init.cpp.func-sort-c.html b/Release/test_coverage/Main/Init.cpp.func-sort-c.html index a68e61b078e5..c16161c6e7cc 100644 --- a/Release/test_coverage/Main/Init.cpp.func-sort-c.html +++ b/Release/test_coverage/Main/Init.cpp.func-sort-c.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:26:06 + 2024-07-11 14:48:26 Functions: 5 diff --git a/Release/test_coverage/Main/Init.cpp.func.html b/Release/test_coverage/Main/Init.cpp.func.html index f483ef9359c8..e5f90074dd8b 100644 --- a/Release/test_coverage/Main/Init.cpp.func.html +++ b/Release/test_coverage/Main/Init.cpp.func.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:26:06 + 2024-07-11 14:48:26 Functions: 5 diff --git a/Release/test_coverage/Main/Init.cpp.gcov.html b/Release/test_coverage/Main/Init.cpp.gcov.html index 9c1ae6b4bc6d..800e5459a0ac 100644 --- a/Release/test_coverage/Main/Init.cpp.gcov.html +++ b/Release/test_coverage/Main/Init.cpp.gcov.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:26:06 + 2024-07-11 14:48:26 Functions: 5 diff --git a/Release/test_coverage/Main/Init.hpp.func-sort-c.html b/Release/test_coverage/Main/Init.hpp.func-sort-c.html index 5c54b2a43537..9b772020d028 100644 --- a/Release/test_coverage/Main/Init.hpp.func-sort-c.html +++ b/Release/test_coverage/Main/Init.hpp.func-sort-c.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:26:06 + 2024-07-11 14:48:26 Functions: 11 diff --git a/Release/test_coverage/Main/Init.hpp.func.html b/Release/test_coverage/Main/Init.hpp.func.html index 500313dd9488..bb04a883fa6d 100644 --- a/Release/test_coverage/Main/Init.hpp.func.html +++ b/Release/test_coverage/Main/Init.hpp.func.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:26:06 + 2024-07-11 14:48:26 Functions: 11 diff --git a/Release/test_coverage/Main/Init.hpp.gcov.html b/Release/test_coverage/Main/Init.hpp.gcov.html index 23e78d2afd62..4a77f8f2224e 100644 --- a/Release/test_coverage/Main/Init.hpp.gcov.html +++ b/Release/test_coverage/Main/Init.hpp.gcov.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:26:06 + 2024-07-11 14:48:26 Functions: 11 diff --git a/Release/test_coverage/Main/LBSwitch.cpp.func-sort-c.html b/Release/test_coverage/Main/LBSwitch.cpp.func-sort-c.html index c9588bde7c0c..a35d4da06c27 100644 --- a/Release/test_coverage/Main/LBSwitch.cpp.func-sort-c.html +++ b/Release/test_coverage/Main/LBSwitch.cpp.func-sort-c.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:26:06 + 2024-07-11 14:48:26 Functions: 2 diff --git a/Release/test_coverage/Main/LBSwitch.cpp.func.html b/Release/test_coverage/Main/LBSwitch.cpp.func.html index e02c22365bb0..e633c44331b1 100644 --- a/Release/test_coverage/Main/LBSwitch.cpp.func.html +++ b/Release/test_coverage/Main/LBSwitch.cpp.func.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:26:06 + 2024-07-11 14:48:26 Functions: 2 diff --git a/Release/test_coverage/Main/LBSwitch.cpp.gcov.html b/Release/test_coverage/Main/LBSwitch.cpp.gcov.html index 4f437b690836..d4ccaef81722 100644 --- a/Release/test_coverage/Main/LBSwitch.cpp.gcov.html +++ b/Release/test_coverage/Main/LBSwitch.cpp.gcov.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:26:06 + 2024-07-11 14:48:26 Functions: 2 diff --git a/Release/test_coverage/Main/LBSwitch.hpp.func-sort-c.html b/Release/test_coverage/Main/LBSwitch.hpp.func-sort-c.html index 8514efb41ac2..b22735094295 100644 --- a/Release/test_coverage/Main/LBSwitch.hpp.func-sort-c.html +++ b/Release/test_coverage/Main/LBSwitch.hpp.func-sort-c.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:26:06 + 2024-07-11 14:48:26 Functions: 0 diff --git a/Release/test_coverage/Main/LBSwitch.hpp.func.html b/Release/test_coverage/Main/LBSwitch.hpp.func.html index 78bac031712e..7fd429412a63 100644 --- a/Release/test_coverage/Main/LBSwitch.hpp.func.html +++ b/Release/test_coverage/Main/LBSwitch.hpp.func.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:26:06 + 2024-07-11 14:48:26 Functions: 0 diff --git a/Release/test_coverage/Main/LBSwitch.hpp.gcov.html b/Release/test_coverage/Main/LBSwitch.hpp.gcov.html index 38978ed58b2c..a1b4bcee44f7 100644 --- a/Release/test_coverage/Main/LBSwitch.hpp.gcov.html +++ b/Release/test_coverage/Main/LBSwitch.hpp.gcov.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:26:06 + 2024-07-11 14:48:26 Functions: 0 diff --git a/Release/test_coverage/Main/MeshConv.cpp.func-sort-c.html b/Release/test_coverage/Main/MeshConv.cpp.func-sort-c.html index 60fddb0f67d3..5b332b26c0d1 100644 --- a/Release/test_coverage/Main/MeshConv.cpp.func-sort-c.html +++ b/Release/test_coverage/Main/MeshConv.cpp.func-sort-c.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:26:06 + 2024-07-11 14:48:26 Functions: 6 diff --git a/Release/test_coverage/Main/MeshConv.cpp.func.html b/Release/test_coverage/Main/MeshConv.cpp.func.html index c56e5cba8a9c..8c8d8f92bb8c 100644 --- a/Release/test_coverage/Main/MeshConv.cpp.func.html +++ b/Release/test_coverage/Main/MeshConv.cpp.func.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:26:06 + 2024-07-11 14:48:26 Functions: 6 diff --git a/Release/test_coverage/Main/MeshConv.cpp.gcov.html b/Release/test_coverage/Main/MeshConv.cpp.gcov.html index a681cd3c11ec..14355a5ea0e3 100644 --- a/Release/test_coverage/Main/MeshConv.cpp.gcov.html +++ b/Release/test_coverage/Main/MeshConv.cpp.gcov.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:26:06 + 2024-07-11 14:48:26 Functions: 6 diff --git a/Release/test_coverage/Main/MeshConvDriver.cpp.func-sort-c.html b/Release/test_coverage/Main/MeshConvDriver.cpp.func-sort-c.html index 88bb0b37ab6c..507d4fbb3238 100644 --- a/Release/test_coverage/Main/MeshConvDriver.cpp.func-sort-c.html +++ b/Release/test_coverage/Main/MeshConvDriver.cpp.func-sort-c.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:26:06 + 2024-07-11 14:48:26 Functions: 3 diff --git a/Release/test_coverage/Main/MeshConvDriver.cpp.func.html b/Release/test_coverage/Main/MeshConvDriver.cpp.func.html index b3b706298032..7994c19fb06e 100644 --- a/Release/test_coverage/Main/MeshConvDriver.cpp.func.html +++ b/Release/test_coverage/Main/MeshConvDriver.cpp.func.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:26:06 + 2024-07-11 14:48:26 Functions: 3 diff --git a/Release/test_coverage/Main/MeshConvDriver.cpp.gcov.html b/Release/test_coverage/Main/MeshConvDriver.cpp.gcov.html index 36cc33ca3997..d895d6dc69f8 100644 --- a/Release/test_coverage/Main/MeshConvDriver.cpp.gcov.html +++ b/Release/test_coverage/Main/MeshConvDriver.cpp.gcov.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:26:06 + 2024-07-11 14:48:26 Functions: 3 diff --git a/Release/test_coverage/Main/UnitTest.cpp.func-sort-c.html b/Release/test_coverage/Main/UnitTest.cpp.func-sort-c.html index 5f575ddd7037..6c698ccb5284 100644 --- a/Release/test_coverage/Main/UnitTest.cpp.func-sort-c.html +++ b/Release/test_coverage/Main/UnitTest.cpp.func-sort-c.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:26:06 + 2024-07-11 14:48:26 Functions: 4 diff --git a/Release/test_coverage/Main/UnitTest.cpp.func.html b/Release/test_coverage/Main/UnitTest.cpp.func.html index 57c42bd967c2..0d31831cbd9b 100644 --- a/Release/test_coverage/Main/UnitTest.cpp.func.html +++ b/Release/test_coverage/Main/UnitTest.cpp.func.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:26:06 + 2024-07-11 14:48:26 Functions: 4 diff --git a/Release/test_coverage/Main/UnitTest.cpp.gcov.html b/Release/test_coverage/Main/UnitTest.cpp.gcov.html index b1c26b82b72f..60a3b814a857 100644 --- a/Release/test_coverage/Main/UnitTest.cpp.gcov.html +++ b/Release/test_coverage/Main/UnitTest.cpp.gcov.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:26:06 + 2024-07-11 14:48:26 Functions: 4 diff --git a/Release/test_coverage/Main/UnitTestDriver.cpp.func-sort-c.html b/Release/test_coverage/Main/UnitTestDriver.cpp.func-sort-c.html index 13a4b828fecd..335efbcd7025 100644 --- a/Release/test_coverage/Main/UnitTestDriver.cpp.func-sort-c.html +++ b/Release/test_coverage/Main/UnitTestDriver.cpp.func-sort-c.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:26:06 + 2024-07-11 14:48:26 Functions: 1 diff --git a/Release/test_coverage/Main/UnitTestDriver.cpp.func.html b/Release/test_coverage/Main/UnitTestDriver.cpp.func.html index 92337db324bc..9454c1efe414 100644 --- a/Release/test_coverage/Main/UnitTestDriver.cpp.func.html +++ b/Release/test_coverage/Main/UnitTestDriver.cpp.func.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:26:06 + 2024-07-11 14:48:26 Functions: 1 diff --git a/Release/test_coverage/Main/UnitTestDriver.cpp.gcov.html b/Release/test_coverage/Main/UnitTestDriver.cpp.gcov.html index 5261d525aed8..09f4dca6513b 100644 --- a/Release/test_coverage/Main/UnitTestDriver.cpp.gcov.html +++ b/Release/test_coverage/Main/UnitTestDriver.cpp.gcov.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:26:06 + 2024-07-11 14:48:26 Functions: 1 diff --git a/Release/test_coverage/Main/UnitTestPrint.hpp.func-sort-c.html b/Release/test_coverage/Main/UnitTestPrint.hpp.func-sort-c.html index d1438d322492..6d1f0443112c 100644 --- a/Release/test_coverage/Main/UnitTestPrint.hpp.func-sort-c.html +++ b/Release/test_coverage/Main/UnitTestPrint.hpp.func-sort-c.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:26:06 + 2024-07-11 14:48:26 Functions: 3 diff --git a/Release/test_coverage/Main/UnitTestPrint.hpp.func.html b/Release/test_coverage/Main/UnitTestPrint.hpp.func.html index 9f3cacc27c95..6f126da874e9 100644 --- a/Release/test_coverage/Main/UnitTestPrint.hpp.func.html +++ b/Release/test_coverage/Main/UnitTestPrint.hpp.func.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:26:06 + 2024-07-11 14:48:26 Functions: 3 diff --git a/Release/test_coverage/Main/UnitTestPrint.hpp.gcov.html b/Release/test_coverage/Main/UnitTestPrint.hpp.gcov.html index cc12a57facd3..74ac09f49d6e 100644 --- a/Release/test_coverage/Main/UnitTestPrint.hpp.gcov.html +++ b/Release/test_coverage/Main/UnitTestPrint.hpp.gcov.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:26:06 + 2024-07-11 14:48:26 Functions: 3 diff --git a/Release/test_coverage/Main/index-sort-b.html b/Release/test_coverage/Main/index-sort-b.html index 4b2da82fa340..5be90ce9e35b 100644 --- a/Release/test_coverage/Main/index-sort-b.html +++ b/Release/test_coverage/Main/index-sort-b.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:26:06 + 2024-07-11 14:48:26 Functions: 57 diff --git a/Release/test_coverage/Main/index-sort-f.html b/Release/test_coverage/Main/index-sort-f.html index bc38359859fa..426e75458964 100644 --- a/Release/test_coverage/Main/index-sort-f.html +++ b/Release/test_coverage/Main/index-sort-f.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:26:06 + 2024-07-11 14:48:26 Functions: 57 diff --git a/Release/test_coverage/Main/index-sort-l.html b/Release/test_coverage/Main/index-sort-l.html index a5aafbfb59a4..f1e1bd458c86 100644 --- a/Release/test_coverage/Main/index-sort-l.html +++ b/Release/test_coverage/Main/index-sort-l.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:26:06 + 2024-07-11 14:48:26 Functions: 57 diff --git a/Release/test_coverage/Main/index.html b/Release/test_coverage/Main/index.html index 6ce64750fba1..581956f312c0 100644 --- a/Release/test_coverage/Main/index.html +++ b/Release/test_coverage/Main/index.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:26:06 + 2024-07-11 14:48:26 Functions: 57 diff --git a/Release/test_coverage/Mesh/Around.hpp.func-sort-c.html b/Release/test_coverage/Mesh/Around.hpp.func-sort-c.html index 6a298b432ed7..3bf39646d1cf 100644 --- a/Release/test_coverage/Mesh/Around.hpp.func-sort-c.html +++ b/Release/test_coverage/Mesh/Around.hpp.func-sort-c.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:26:06 + 2024-07-11 14:48:26 Functions: 0 diff --git a/Release/test_coverage/Mesh/Around.hpp.func.html b/Release/test_coverage/Mesh/Around.hpp.func.html index 61d28fee9e21..f8ba915ecd61 100644 --- a/Release/test_coverage/Mesh/Around.hpp.func.html +++ b/Release/test_coverage/Mesh/Around.hpp.func.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:26:06 + 2024-07-11 14:48:26 Functions: 0 diff --git a/Release/test_coverage/Mesh/Around.hpp.gcov.html b/Release/test_coverage/Mesh/Around.hpp.gcov.html index 876d25ded158..dd6f7d499e9f 100644 --- a/Release/test_coverage/Mesh/Around.hpp.gcov.html +++ b/Release/test_coverage/Mesh/Around.hpp.gcov.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:26:06 + 2024-07-11 14:48:26 Functions: 0 diff --git a/Release/test_coverage/Mesh/CommMap.cpp.func-sort-c.html b/Release/test_coverage/Mesh/CommMap.cpp.func-sort-c.html index fe0b193833ea..15afea3f26a3 100644 --- a/Release/test_coverage/Mesh/CommMap.cpp.func-sort-c.html +++ b/Release/test_coverage/Mesh/CommMap.cpp.func-sort-c.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:26:06 + 2024-07-11 14:48:26 Functions: 3 @@ -81,7 +81,7 @@ auto tk::slave(std::unordered_map<int, std::unordered_set<unsigned long, std::hash<unsigned long>, std::equal_to<unsigned long>, std::allocator<unsigned long> >, std::hash<int>, std::equal_to<int>, std::allocator<std::pair<int const, std::unordered_set<unsigned long, std::hash<unsigned long>, std::equal_to<unsigned long>, std::allocator<unsigned long> > > > > const&, unsigned long, int)::{lambda(auto:1 const&)#1}::operator()<std::pair<int const, std::unordered_set<unsigned long, std::hash<unsigned long>, std::equal_to<unsigned long>, std::allocator<unsigned long> > > >(std::pair<int const, std::unordered_set<unsigned long, std::hash<unsigned long>, std::equal_to<unsigned long>, std::allocator<unsigned long> > > const&) const [clone .isra.0] - 20092567 + 20091921
diff --git a/Release/test_coverage/Mesh/CommMap.cpp.func.html b/Release/test_coverage/Mesh/CommMap.cpp.func.html index 34d4b1d2104c..ed5bb25d4706 100644 --- a/Release/test_coverage/Mesh/CommMap.cpp.func.html +++ b/Release/test_coverage/Mesh/CommMap.cpp.func.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:26:06 + 2024-07-11 14:48:26 Functions: 3 @@ -81,7 +81,7 @@ auto tk::slave(std::unordered_map<int, std::unordered_set<unsigned long, std::hash<unsigned long>, std::equal_to<unsigned long>, std::allocator<unsigned long> >, std::hash<int>, std::equal_to<int>, std::allocator<std::pair<int const, std::unordered_set<unsigned long, std::hash<unsigned long>, std::equal_to<unsigned long>, std::allocator<unsigned long> > > > > const&, unsigned long, int)::{lambda(auto:1 const&)#1}::operator()<std::pair<int const, std::unordered_set<unsigned long, std::hash<unsigned long>, std::equal_to<unsigned long>, std::allocator<unsigned long> > > >(std::pair<int const, std::unordered_set<unsigned long, std::hash<unsigned long>, std::equal_to<unsigned long>, std::allocator<unsigned long> > > const&) const [clone .isra.0] - 20092567 + 20091921
diff --git a/Release/test_coverage/Mesh/CommMap.cpp.gcov.html b/Release/test_coverage/Mesh/CommMap.cpp.gcov.html index 289cf860bb14..986a23846a2e 100644 --- a/Release/test_coverage/Mesh/CommMap.cpp.gcov.html +++ b/Release/test_coverage/Mesh/CommMap.cpp.gcov.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:26:06 + 2024-07-11 14:48:26 Functions: 3 @@ -105,8 +105,8 @@ 31 : : { 32 : : return 33 : 17886651 : std::any_of( map.cbegin(), map.cend(), - 34 : 20092567 : [&](const auto& s) { - 35 [ + + ][ + + ]: 40185134 : return s.second.find(node) != s.second.cend() && s.first > chare; } ); + 34 : 20091921 : [&](const auto& s) { + 35 [ + + ][ + + ]: 40183842 : return s.second.find(node) != s.second.cend() && s.first > chare; } ); 36 : : } 37 : : 38 : 1340242 : tk::real count( const NodeCommMap& map, std::size_t node ) diff --git a/Release/test_coverage/Mesh/DerivedData.cpp.func-sort-c.html b/Release/test_coverage/Mesh/DerivedData.cpp.func-sort-c.html index 02cce8b50fe2..3c5063929f51 100644 --- a/Release/test_coverage/Mesh/DerivedData.cpp.func-sort-c.html +++ b/Release/test_coverage/Mesh/DerivedData.cpp.func-sort-c.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:26:06 + 2024-07-11 14:48:26 Functions: 27 @@ -177,7 +177,7 @@ tk::intet(std::array<std::vector<double, std::allocator<double> >, 3ul> const&, std::vector<unsigned long, std::allocator<unsigned long> > const&, std::vector<double, std::allocator<double> > const&, unsigned long, std::array<double, 4ul>&) - 3486001 + 3485988 tk::orient(std::array<unsigned long, 2ul> const&, std::array<unsigned long, 2ul> const&) diff --git a/Release/test_coverage/Mesh/DerivedData.cpp.func.html b/Release/test_coverage/Mesh/DerivedData.cpp.func.html index 52c0bf0414a7..bb754840e2a6 100644 --- a/Release/test_coverage/Mesh/DerivedData.cpp.func.html +++ b/Release/test_coverage/Mesh/DerivedData.cpp.func.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:26:06 + 2024-07-11 14:48:26 Functions: 27 @@ -129,7 +129,7 @@ tk::intet(std::array<std::vector<double, std::allocator<double> >, 3ul> const&, std::vector<unsigned long, std::allocator<unsigned long> > const&, std::vector<double, std::allocator<double> > const&, unsigned long, std::array<double, 4ul>&) - 3486001 + 3485988 tk::normal(std::array<double, 3ul> const&, std::array<double, 3ul> const&, std::array<double, 3ul> const&) diff --git a/Release/test_coverage/Mesh/DerivedData.cpp.gcov.html b/Release/test_coverage/Mesh/DerivedData.cpp.gcov.html index 1fccac4f2f8b..576718a7e931 100644 --- a/Release/test_coverage/Mesh/DerivedData.cpp.gcov.html +++ b/Release/test_coverage/Mesh/DerivedData.cpp.gcov.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:26:06 + 2024-07-11 14:48:26 Functions: 27 @@ -874,8 +874,8 @@ 794 : : // lambda that returns true if element e contains edge (p < q) 795 : : auto has = [ &inpoel, nnpe ]( std::size_t e, std::size_t p, std::size_t q ) { 796 : : int sp = 0; - 797 [ + + ]: 1197400849 : for (std::size_t n=0; n<nnpe; ++n) - 798 [ + + ][ + + ]: 957920636 : if (inpoel[e*nnpe+n] == p || inpoel[e*nnpe+n] == q) ++sp; + 797 [ + + ]: 1197523299 : for (std::size_t n=0; n<nnpe; ++n) + 798 [ + + ][ + + ]: 958018596 : if (inpoel[e*nnpe+n] == p || inpoel[e*nnpe+n] == q) ++sp; 799 : : return sp == 2; 800 : : }; 801 : : @@ -890,9 +890,9 @@ 810 [ + + ]: 162036296 : auto q = inpoel[ esup1[i] * nnpe + n ]; 811 [ + + ][ + + ]: 162036296 : if (q != p && lpoin[q] != p+1) { 812 [ + + ]: 34539934 : if (p < q) { // for edge given point ids p < q - 813 [ + + ]: 256750180 : for (std::size_t j=esup2[p]+1; j<=esup2[p+1]; ++j ) { - 814 : 239480213 : auto e = esup1[j]; - 815 [ + + ][ + - ]: 239480213 : if (has(e,p,q)) esued[{p,q}].push_back(e); + 813 [ + + ]: 256774670 : for (std::size_t j=esup2[p]+1; j<=esup2[p+1]; ++j ) { + 814 : 239504703 : auto e = esup1[j]; + 815 [ + + ][ + - ]: 239504703 : if (has(e,p,q)) esued[{p,q}].push_back(e); [ + - ] 816 : : } 817 : : } @@ -1348,18 +1348,18 @@ 1267 : : } 1268 : : 1269 : : // loop over element cluster to find repeating elements - 1270 [ + - ]: 803406 : for(std::size_t i=0; i<elemcluster.size(); ++i) + 1270 [ + - ]: 800668 : for(std::size_t i=0; i<elemcluster.size(); ++i) 1271 : : { - 1272 : 803406 : auto ge = elemcluster[i]; + 1272 : 800668 : auto ge = elemcluster[i]; 1273 : : tag = 1; - 1274 [ + + ]: 27531301 : for(std::size_t j=0; j<elemcluster.size(); ++j) + 1274 [ + + ]: 27437638 : for(std::size_t j=0; j<elemcluster.size(); ++j) 1275 : : { - 1276 [ + + ][ + + ]: 26727895 : if ( i != j && elemcluster[j] == ge ) + 1276 [ + + ][ + + ]: 26636970 : if ( i != j && elemcluster[j] == ge ) 1277 : : { - 1278 : 483936 : tag++; + 1278 : 483258 : tag++; 1279 : : } 1280 : : } - 1281 [ + + ]: 803406 : if (tag == nnpf) + 1281 [ + + ]: 800668 : if (tag == nnpf) 1282 : : { 1283 : : // this is the required boundary element 1284 : 130728 : belem[f] = ge; @@ -1772,7 +1772,7 @@ 1689 : : } 1690 : : 1691 : : bool - 1692 : 3486001 : intet( const std::array< std::vector< real >, 3 >& coord, + 1692 : 3485988 : intet( const std::array< std::vector< real >, 3 >& coord, 1693 : : const std::vector< std::size_t >& inpoel, 1694 : : const std::vector< real >& p, 1695 : : std::size_t e, @@ -1791,10 +1791,10 @@ 1708 : : Assert( p.size() == 3, "Size mismatch" ); 1709 : : 1710 : : // Tetrahedron node indices - 1711 [ + + ]: 3486001 : const auto A = inpoel[e*4+0]; - 1712 : 3486001 : const auto B = inpoel[e*4+1]; - 1713 : 3486001 : const auto C = inpoel[e*4+2]; - 1714 : 3486001 : const auto D = inpoel[e*4+3]; + 1711 [ + + ]: 3485988 : const auto A = inpoel[e*4+0]; + 1712 : 3485988 : const auto B = inpoel[e*4+1]; + 1713 : 3485988 : const auto C = inpoel[e*4+2]; + 1714 : 3485988 : const auto D = inpoel[e*4+3]; 1715 : : 1716 : : // Tetrahedron node coordinates 1717 : : const auto& x = coord[0]; @@ -1802,7 +1802,7 @@ 1719 : : const auto& z = coord[2]; 1720 : : 1721 : : // Point coordinates - 1722 : 3486001 : const auto& xp = p[0]; + 1722 : 3485988 : const auto& xp = p[0]; 1723 : : const auto& yp = p[1]; 1724 : : const auto& zp = p[2]; 1725 : : @@ -1812,57 +1812,57 @@ 1729 : : // | zp | | z1 z2 z3 z4 | | N3 | 1730 : : // | 1 | | 1 1 1 1 | | N4 | 1731 : : - 1732 : 3486001 : real DetX = (y[B]*z[C] - y[C]*z[B] - y[B]*z[D] + y[D]*z[B] + - 1733 : 3486001 : y[C]*z[D] - y[D]*z[C])*x[A] + x[B]*y[C]*z[A] - x[B]*y[A]*z[C] + - 1734 : 3486001 : x[C]*y[A]*z[B] - x[C]*y[B]*z[A] + x[B]*y[A]*z[D] - x[B]*y[D]*z[A] - - 1735 : 3486001 : x[D]*y[A]*z[B] + x[D]*y[B]*z[A] - x[C]*y[A]*z[D] + x[C]*y[D]*z[A] + - 1736 : 3486001 : x[D]*y[A]*z[C] - x[D]*y[C]*z[A] - x[B]*y[C]*z[D] + x[B]*y[D]*z[C] + - 1737 : 3486001 : x[C]*y[B]*z[D] - x[C]*y[D]*z[B] - x[D]*y[B]*z[C] + x[D]*y[C]*z[B]; + 1732 : 3485988 : real DetX = (y[B]*z[C] - y[C]*z[B] - y[B]*z[D] + y[D]*z[B] + + 1733 : 3485988 : y[C]*z[D] - y[D]*z[C])*x[A] + x[B]*y[C]*z[A] - x[B]*y[A]*z[C] + + 1734 : 3485988 : x[C]*y[A]*z[B] - x[C]*y[B]*z[A] + x[B]*y[A]*z[D] - x[B]*y[D]*z[A] - + 1735 : 3485988 : x[D]*y[A]*z[B] + x[D]*y[B]*z[A] - x[C]*y[A]*z[D] + x[C]*y[D]*z[A] + + 1736 : 3485988 : x[D]*y[A]*z[C] - x[D]*y[C]*z[A] - x[B]*y[C]*z[D] + x[B]*y[D]*z[C] + + 1737 : 3485988 : x[C]*y[B]*z[D] - x[C]*y[D]*z[B] - x[D]*y[B]*z[C] + x[D]*y[C]*z[B]; 1738 : : - 1739 : 3486001 : real DetX1 = (y[D]*z[C] - y[C]*z[D] + y[C]*zp - yp*z[C] - - 1740 : 3486001 : y[D]*zp + yp*z[D])*x[B] + x[C]*y[B]*z[D] - x[C]*y[D]*z[B] - - 1741 : 3486001 : x[D]*y[B]*z[C] + x[D]*y[C]*z[B] - x[C]*y[B]*zp + x[C]*yp*z[B] + - 1742 : 3486001 : xp*y[B]*z[C] - xp*y[C]*z[B] + x[D]*y[B]*zp - x[D]*yp*z[B] - - 1743 : 3486001 : xp*y[B]*z[D] + xp*y[D]*z[B] + x[C]*y[D]*zp - x[C]*yp*z[D] - - 1744 : 3486001 : x[D]*y[C]*zp + x[D]*yp*z[C] + xp*y[C]*z[D] - xp*y[D]*z[C]; + 1739 : 3485988 : real DetX1 = (y[D]*z[C] - y[C]*z[D] + y[C]*zp - yp*z[C] - + 1740 : 3485988 : y[D]*zp + yp*z[D])*x[B] + x[C]*y[B]*z[D] - x[C]*y[D]*z[B] - + 1741 : 3485988 : x[D]*y[B]*z[C] + x[D]*y[C]*z[B] - x[C]*y[B]*zp + x[C]*yp*z[B] + + 1742 : 3485988 : xp*y[B]*z[C] - xp*y[C]*z[B] + x[D]*y[B]*zp - x[D]*yp*z[B] - + 1743 : 3485988 : xp*y[B]*z[D] + xp*y[D]*z[B] + x[C]*y[D]*zp - x[C]*yp*z[D] - + 1744 : 3485988 : x[D]*y[C]*zp + x[D]*yp*z[C] + xp*y[C]*z[D] - xp*y[D]*z[C]; 1745 : : - 1746 : 3486001 : real DetX2 = (y[C]*z[D] - y[D]*z[C] - y[C]*zp + yp*z[C] + - 1747 : 3486001 : y[D]*zp - yp*z[D])*x[A] + x[C]*y[D]*z[A] - x[C]*y[A]*z[D] + - 1748 : 3486001 : x[D]*y[A]*z[C] - x[D]*y[C]*z[A] + x[C]*y[A]*zp - x[C]*yp*z[A] - - 1749 : 3486001 : xp*y[A]*z[C] + xp*y[C]*z[A] - x[D]*y[A]*zp + x[D]*yp*z[A] + - 1750 : 3486001 : xp*y[A]*z[D] - xp*y[D]*z[A] - x[C]*y[D]*zp + x[C]*yp*z[D] + - 1751 : 3486001 : x[D]*y[C]*zp - x[D]*yp*z[C] - xp*y[C]*z[D] + xp*y[D]*z[C]; + 1746 : 3485988 : real DetX2 = (y[C]*z[D] - y[D]*z[C] - y[C]*zp + yp*z[C] + + 1747 : 3485988 : y[D]*zp - yp*z[D])*x[A] + x[C]*y[D]*z[A] - x[C]*y[A]*z[D] + + 1748 : 3485988 : x[D]*y[A]*z[C] - x[D]*y[C]*z[A] + x[C]*y[A]*zp - x[C]*yp*z[A] - + 1749 : 3485988 : xp*y[A]*z[C] + xp*y[C]*z[A] - x[D]*y[A]*zp + x[D]*yp*z[A] + + 1750 : 3485988 : xp*y[A]*z[D] - xp*y[D]*z[A] - x[C]*y[D]*zp + x[C]*yp*z[D] + + 1751 : 3485988 : x[D]*y[C]*zp - x[D]*yp*z[C] - xp*y[C]*z[D] + xp*y[D]*z[C]; 1752 : : - 1753 : 3486001 : real DetX3 = (y[D]*z[B] - y[B]*z[D] + y[B]*zp - yp*z[B] - - 1754 : 3486001 : y[D]*zp + yp*z[D])*x[A] + x[B]*y[A]*z[D] - x[B]*y[D]*z[A] - - 1755 : 3486001 : x[D]*y[A]*z[B] + x[D]*y[B]*z[A] - x[B]*y[A]*zp + x[B]*yp*z[A] + - 1756 : 3486001 : xp*y[A]*z[B] - xp*y[B]*z[A] + x[D]*y[A]*zp - x[D]*yp*z[A] - - 1757 : 3486001 : xp*y[A]*z[D] + xp*y[D]*z[A] + x[B]*y[D]*zp - x[B]*yp*z[D] - - 1758 : 3486001 : x[D]*y[B]*zp + x[D]*yp*z[B] + xp*y[B]*z[D] - xp*y[D]*z[B]; + 1753 : 3485988 : real DetX3 = (y[D]*z[B] - y[B]*z[D] + y[B]*zp - yp*z[B] - + 1754 : 3485988 : y[D]*zp + yp*z[D])*x[A] + x[B]*y[A]*z[D] - x[B]*y[D]*z[A] - + 1755 : 3485988 : x[D]*y[A]*z[B] + x[D]*y[B]*z[A] - x[B]*y[A]*zp + x[B]*yp*z[A] + + 1756 : 3485988 : xp*y[A]*z[B] - xp*y[B]*z[A] + x[D]*y[A]*zp - x[D]*yp*z[A] - + 1757 : 3485988 : xp*y[A]*z[D] + xp*y[D]*z[A] + x[B]*y[D]*zp - x[B]*yp*z[D] - + 1758 : 3485988 : x[D]*y[B]*zp + x[D]*yp*z[B] + xp*y[B]*z[D] - xp*y[D]*z[B]; 1759 : : - 1760 : 3486001 : real DetX4 = (y[B]*z[C] - y[C]*z[B] - y[B]*zp + yp*z[B] + - 1761 : 3486001 : y[C]*zp - yp*z[C])*x[A] + x[B]*y[C]*z[A] - x[B]*y[A]*z[C] + - 1762 : 3486001 : x[C]*y[A]*z[B] - x[C]*y[B]*z[A] + x[B]*y[A]*zp - x[B]*yp*z[A] - - 1763 : 3486001 : xp*y[A]*z[B] + xp*y[B]*z[A] - x[C]*y[A]*zp + x[C]*yp*z[A] + - 1764 : 3486001 : xp*y[A]*z[C] - xp*y[C]*z[A] - x[B]*y[C]*zp + x[B]*yp*z[C] + - 1765 : 3486001 : x[C]*y[B]*zp - x[C]*yp*z[B] - xp*y[B]*z[C] + xp*y[C]*z[B]; + 1760 : 3485988 : real DetX4 = (y[B]*z[C] - y[C]*z[B] - y[B]*zp + yp*z[B] + + 1761 : 3485988 : y[C]*zp - yp*z[C])*x[A] + x[B]*y[C]*z[A] - x[B]*y[A]*z[C] + + 1762 : 3485988 : x[C]*y[A]*z[B] - x[C]*y[B]*z[A] + x[B]*y[A]*zp - x[B]*yp*z[A] - + 1763 : 3485988 : xp*y[A]*z[B] + xp*y[B]*z[A] - x[C]*y[A]*zp + x[C]*yp*z[A] + + 1764 : 3485988 : xp*y[A]*z[C] - xp*y[C]*z[A] - x[B]*y[C]*zp + x[B]*yp*z[C] + + 1765 : 3485988 : x[C]*y[B]*zp - x[C]*yp*z[B] - xp*y[B]*z[C] + xp*y[C]*z[B]; 1766 : : 1767 : : // Shape functions evaluated at point - 1768 : 3486001 : N[0] = DetX1/DetX; - 1769 : 3486001 : N[1] = DetX2/DetX; - 1770 : 3486001 : N[2] = DetX3/DetX; - 1771 : 3486001 : N[3] = DetX4/DetX; + 1768 : 3485988 : N[0] = DetX1/DetX; + 1769 : 3485988 : N[1] = DetX2/DetX; + 1770 : 3485988 : N[2] = DetX3/DetX; + 1771 : 3485988 : N[3] = DetX4/DetX; 1772 : : 1773 : : // if min( N^i, 1-N^i ) > 0 for all i, point is in cell - 1774 [ + + ][ + + ]: 6720701 : if ( std::min(N[0],1.0-N[0]) > 0 && std::min(N[1],1.0-N[1]) > 0 && - [ + + ] - 1775 [ + + ][ + + ]: 5648807 : std::min(N[2],1.0-N[2]) > 0 && std::min(N[3],1.0-N[3]) > 0 ) - [ + + ][ + + ] + 1774 [ + + ][ + + ]: 6720684 : if ( std::min(N[0],1.0-N[0]) > 0 && std::min(N[1],1.0-N[1]) > 0 && + [ + + ] + 1775 [ + + ][ + + ]: 5648793 : std::min(N[2],1.0-N[2]) > 0 && std::min(N[3],1.0-N[3]) > 0 ) + [ + + ][ + + ] [ + + ] 1776 : : { 1777 : 460107 : return true; 1778 : : } else { - 1779 : 3025894 : return false; + 1779 : 3025881 : return false; 1780 : : } 1781 : : } 1782 : : diff --git a/Release/test_coverage/Mesh/DerivedData.hpp.func-sort-c.html b/Release/test_coverage/Mesh/DerivedData.hpp.func-sort-c.html index b82f6ea8f0bd..3ca9a954ebb0 100644 --- a/Release/test_coverage/Mesh/DerivedData.hpp.func-sort-c.html +++ b/Release/test_coverage/Mesh/DerivedData.hpp.func-sort-c.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:26:06 + 2024-07-11 14:48:26 Functions: 2 diff --git a/Release/test_coverage/Mesh/DerivedData.hpp.func.html b/Release/test_coverage/Mesh/DerivedData.hpp.func.html index 773f7a8b6512..3b50e1f3f84c 100644 --- a/Release/test_coverage/Mesh/DerivedData.hpp.func.html +++ b/Release/test_coverage/Mesh/DerivedData.hpp.func.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:26:06 + 2024-07-11 14:48:26 Functions: 2 diff --git a/Release/test_coverage/Mesh/DerivedData.hpp.gcov.html b/Release/test_coverage/Mesh/DerivedData.hpp.gcov.html index 876de6978615..a0fdf0ba3428 100644 --- a/Release/test_coverage/Mesh/DerivedData.hpp.gcov.html +++ b/Release/test_coverage/Mesh/DerivedData.hpp.gcov.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:26:06 + 2024-07-11 14:48:26 Functions: 2 diff --git a/Release/test_coverage/Mesh/Gradients.cpp.func-sort-c.html b/Release/test_coverage/Mesh/Gradients.cpp.func-sort-c.html index ed9b9b9e49a2..bd53ff378bf9 100644 --- a/Release/test_coverage/Mesh/Gradients.cpp.func-sort-c.html +++ b/Release/test_coverage/Mesh/Gradients.cpp.func-sort-c.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:26:06 + 2024-07-11 14:48:26 Functions: 2 diff --git a/Release/test_coverage/Mesh/Gradients.cpp.func.html b/Release/test_coverage/Mesh/Gradients.cpp.func.html index f4c54ef0d67d..1b9114bccc70 100644 --- a/Release/test_coverage/Mesh/Gradients.cpp.func.html +++ b/Release/test_coverage/Mesh/Gradients.cpp.func.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:26:06 + 2024-07-11 14:48:26 Functions: 2 diff --git a/Release/test_coverage/Mesh/Gradients.cpp.gcov.html b/Release/test_coverage/Mesh/Gradients.cpp.gcov.html index 3672b2f6c93d..f4f186e99665 100644 --- a/Release/test_coverage/Mesh/Gradients.cpp.gcov.html +++ b/Release/test_coverage/Mesh/Gradients.cpp.gcov.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:26:06 + 2024-07-11 14:48:26 Functions: 2 diff --git a/Release/test_coverage/Mesh/Reorder.cpp.func-sort-c.html b/Release/test_coverage/Mesh/Reorder.cpp.func-sort-c.html index eb2a94b1a931..5ae19eee83ac 100644 --- a/Release/test_coverage/Mesh/Reorder.cpp.func-sort-c.html +++ b/Release/test_coverage/Mesh/Reorder.cpp.func-sort-c.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:26:06 + 2024-07-11 14:48:26 Functions: 12 diff --git a/Release/test_coverage/Mesh/Reorder.cpp.func.html b/Release/test_coverage/Mesh/Reorder.cpp.func.html index c30a425df56c..13967f5866b0 100644 --- a/Release/test_coverage/Mesh/Reorder.cpp.func.html +++ b/Release/test_coverage/Mesh/Reorder.cpp.func.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:26:06 + 2024-07-11 14:48:26 Functions: 12 diff --git a/Release/test_coverage/Mesh/Reorder.cpp.gcov.html b/Release/test_coverage/Mesh/Reorder.cpp.gcov.html index eee3f8f768c9..5e9d453b31e7 100644 --- a/Release/test_coverage/Mesh/Reorder.cpp.gcov.html +++ b/Release/test_coverage/Mesh/Reorder.cpp.gcov.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:26:06 + 2024-07-11 14:48:26 Functions: 12 diff --git a/Release/test_coverage/Mesh/STLMesh.cpp.func-sort-c.html b/Release/test_coverage/Mesh/STLMesh.cpp.func-sort-c.html index 4935e243d33d..9ba02744b843 100644 --- a/Release/test_coverage/Mesh/STLMesh.cpp.func-sort-c.html +++ b/Release/test_coverage/Mesh/STLMesh.cpp.func-sort-c.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:26:06 + 2024-07-11 14:48:26 Functions: 0 diff --git a/Release/test_coverage/Mesh/STLMesh.cpp.func.html b/Release/test_coverage/Mesh/STLMesh.cpp.func.html index 667e18f125f2..4de5d05ed565 100644 --- a/Release/test_coverage/Mesh/STLMesh.cpp.func.html +++ b/Release/test_coverage/Mesh/STLMesh.cpp.func.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:26:06 + 2024-07-11 14:48:26 Functions: 0 diff --git a/Release/test_coverage/Mesh/STLMesh.cpp.gcov.html b/Release/test_coverage/Mesh/STLMesh.cpp.gcov.html index 362814dcb066..3e4ff695f3c8 100644 --- a/Release/test_coverage/Mesh/STLMesh.cpp.gcov.html +++ b/Release/test_coverage/Mesh/STLMesh.cpp.gcov.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:26:06 + 2024-07-11 14:48:26 Functions: 0 diff --git a/Release/test_coverage/Mesh/STLMesh.hpp.func-sort-c.html b/Release/test_coverage/Mesh/STLMesh.hpp.func-sort-c.html index 858269bfde44..ca394a0fd9be 100644 --- a/Release/test_coverage/Mesh/STLMesh.hpp.func-sort-c.html +++ b/Release/test_coverage/Mesh/STLMesh.hpp.func-sort-c.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:26:06 + 2024-07-11 14:48:26 Functions: 0 diff --git a/Release/test_coverage/Mesh/STLMesh.hpp.func.html b/Release/test_coverage/Mesh/STLMesh.hpp.func.html index 344af63d5ae1..202a40363b15 100644 --- a/Release/test_coverage/Mesh/STLMesh.hpp.func.html +++ b/Release/test_coverage/Mesh/STLMesh.hpp.func.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:26:06 + 2024-07-11 14:48:26 Functions: 0 diff --git a/Release/test_coverage/Mesh/STLMesh.hpp.gcov.html b/Release/test_coverage/Mesh/STLMesh.hpp.gcov.html index 6dc698620eb5..2b72f4e4d12b 100644 --- a/Release/test_coverage/Mesh/STLMesh.hpp.gcov.html +++ b/Release/test_coverage/Mesh/STLMesh.hpp.gcov.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:26:06 + 2024-07-11 14:48:26 Functions: 0 diff --git a/Release/test_coverage/Mesh/UnsMesh.hpp.func-sort-c.html b/Release/test_coverage/Mesh/UnsMesh.hpp.func-sort-c.html index 3d401d1b37bb..ec5de6896205 100644 --- a/Release/test_coverage/Mesh/UnsMesh.hpp.func-sort-c.html +++ b/Release/test_coverage/Mesh/UnsMesh.hpp.func-sort-c.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:26:06 + 2024-07-11 14:48:26 Functions: 6 diff --git a/Release/test_coverage/Mesh/UnsMesh.hpp.func.html b/Release/test_coverage/Mesh/UnsMesh.hpp.func.html index b05c67f0bfd4..0c7d65492567 100644 --- a/Release/test_coverage/Mesh/UnsMesh.hpp.func.html +++ b/Release/test_coverage/Mesh/UnsMesh.hpp.func.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:26:06 + 2024-07-11 14:48:26 Functions: 6 diff --git a/Release/test_coverage/Mesh/UnsMesh.hpp.gcov.html b/Release/test_coverage/Mesh/UnsMesh.hpp.gcov.html index 0c1941ebfcc9..2a2a1cb072f5 100644 --- a/Release/test_coverage/Mesh/UnsMesh.hpp.gcov.html +++ b/Release/test_coverage/Mesh/UnsMesh.hpp.gcov.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:26:06 + 2024-07-11 14:48:26 Functions: 6 diff --git a/Release/test_coverage/Mesh/index-sort-b.html b/Release/test_coverage/Mesh/index-sort-b.html index f8f0fe1e907d..35333c6226a1 100644 --- a/Release/test_coverage/Mesh/index-sort-b.html +++ b/Release/test_coverage/Mesh/index-sort-b.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:26:06 + 2024-07-11 14:48:26 Functions: 52 diff --git a/Release/test_coverage/Mesh/index-sort-f.html b/Release/test_coverage/Mesh/index-sort-f.html index 661fa8a0eab8..ea83bd0b6236 100644 --- a/Release/test_coverage/Mesh/index-sort-f.html +++ b/Release/test_coverage/Mesh/index-sort-f.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:26:06 + 2024-07-11 14:48:26 Functions: 52 @@ -130,28 +130,28 @@ 0 / 2 - Gradients.cpp + DerivedData.hpp
100.0%
100.0 % - 40 / 40 + 21 / 21 100.0 % 2 / 2 - 100.0 % - 20 / 20 + - + 0 / 0 - DerivedData.hpp + Gradients.cpp
100.0%
100.0 % - 21 / 21 + 40 / 40 100.0 % 2 / 2 - - - 0 / 0 + 100.0 % + 20 / 20 CommMap.cpp diff --git a/Release/test_coverage/Mesh/index-sort-l.html b/Release/test_coverage/Mesh/index-sort-l.html index 677bab78e347..07bab491d79d 100644 --- a/Release/test_coverage/Mesh/index-sort-l.html +++ b/Release/test_coverage/Mesh/index-sort-l.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:26:06 + 2024-07-11 14:48:26 Functions: 52 diff --git a/Release/test_coverage/Mesh/index.html b/Release/test_coverage/Mesh/index.html index c2a92ed709ec..7b466c6bfe6f 100644 --- a/Release/test_coverage/Mesh/index.html +++ b/Release/test_coverage/Mesh/index.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:26:06 + 2024-07-11 14:48:26 Functions: 52 diff --git a/Release/test_coverage/PDE/CGPDE.cpp.func-sort-c.html b/Release/test_coverage/PDE/CGPDE.cpp.func-sort-c.html index 7af1b8240cbf..059c808ca001 100644 --- a/Release/test_coverage/PDE/CGPDE.cpp.func-sort-c.html +++ b/Release/test_coverage/PDE/CGPDE.cpp.func-sort-c.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:26:06 + 2024-07-11 14:48:26 Functions: 2 diff --git a/Release/test_coverage/PDE/CGPDE.cpp.func.html b/Release/test_coverage/PDE/CGPDE.cpp.func.html index ffa6b45e9910..74a8f2e549f4 100644 --- a/Release/test_coverage/PDE/CGPDE.cpp.func.html +++ b/Release/test_coverage/PDE/CGPDE.cpp.func.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:26:06 + 2024-07-11 14:48:26 Functions: 2 diff --git a/Release/test_coverage/PDE/CGPDE.cpp.gcov.html b/Release/test_coverage/PDE/CGPDE.cpp.gcov.html index f99fd9b8ca15..c28bed99c6eb 100644 --- a/Release/test_coverage/PDE/CGPDE.cpp.gcov.html +++ b/Release/test_coverage/PDE/CGPDE.cpp.gcov.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:26:06 + 2024-07-11 14:48:26 Functions: 2 diff --git a/Release/test_coverage/PDE/CGPDE.hpp.func-sort-c.html b/Release/test_coverage/PDE/CGPDE.hpp.func-sort-c.html index 2ffe52a2138c..6f4ee19690d7 100644 --- a/Release/test_coverage/PDE/CGPDE.hpp.func-sort-c.html +++ b/Release/test_coverage/PDE/CGPDE.hpp.func-sort-c.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:26:06 + 2024-07-11 14:48:26 Functions: 156 diff --git a/Release/test_coverage/PDE/CGPDE.hpp.func.html b/Release/test_coverage/PDE/CGPDE.hpp.func.html index ef3b626dfbb5..5a9c6e14fe36 100644 --- a/Release/test_coverage/PDE/CGPDE.hpp.func.html +++ b/Release/test_coverage/PDE/CGPDE.hpp.func.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:26:06 + 2024-07-11 14:48:26 Functions: 156 diff --git a/Release/test_coverage/PDE/CGPDE.hpp.gcov.html b/Release/test_coverage/PDE/CGPDE.hpp.gcov.html index f0c2dffcdf25..aaa358a5c4e1 100644 --- a/Release/test_coverage/PDE/CGPDE.hpp.gcov.html +++ b/Release/test_coverage/PDE/CGPDE.hpp.gcov.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:26:06 + 2024-07-11 14:48:26 Functions: 156 diff --git a/Release/test_coverage/PDE/CompFlow/CGCompFlow.hpp.func-sort-c.html b/Release/test_coverage/PDE/CompFlow/CGCompFlow.hpp.func-sort-c.html index c60cd4b1205f..efe4949fc559 100644 --- a/Release/test_coverage/PDE/CompFlow/CGCompFlow.hpp.func-sort-c.html +++ b/Release/test_coverage/PDE/CompFlow/CGCompFlow.hpp.func-sort-c.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:26:06 + 2024-07-11 14:48:26 Functions: 110 diff --git a/Release/test_coverage/PDE/CompFlow/CGCompFlow.hpp.func.html b/Release/test_coverage/PDE/CompFlow/CGCompFlow.hpp.func.html index 3888f2be5cda..db253490126e 100644 --- a/Release/test_coverage/PDE/CompFlow/CGCompFlow.hpp.func.html +++ b/Release/test_coverage/PDE/CompFlow/CGCompFlow.hpp.func.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:26:06 + 2024-07-11 14:48:26 Functions: 110 diff --git a/Release/test_coverage/PDE/CompFlow/CGCompFlow.hpp.gcov.html b/Release/test_coverage/PDE/CompFlow/CGCompFlow.hpp.gcov.html index 8f34d8accadb..e2ea82de2591 100644 --- a/Release/test_coverage/PDE/CompFlow/CGCompFlow.hpp.gcov.html +++ b/Release/test_coverage/PDE/CompFlow/CGCompFlow.hpp.gcov.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:26:06 + 2024-07-11 14:48:26 Functions: 110 @@ -709,7 +709,7 @@ 627 : : } 628 : : } 629 : : - 630 [ + + ]: 19922100 : if (v > maxvel) maxvel = v; + 630 [ + + ]: 19922100 : if (v > maxvel) maxvel = v; 631 : : } 632 : : // compute element dt for the Euler equations 633 : 4980525 : auto euler_dt = L / maxvel; @@ -718,7 +718,7 @@ 636 : : // compute element dt based on thermal diffusion 637 [ - + ]: 4980525 : auto conduct_dt = m_physics.conduct_dt( L, g, u ); 638 : : // compute minimum element dt - 639 [ + + ]: 4980525 : auto elemdt = std::min( euler_dt, std::min( viscous_dt, conduct_dt ) ); + 639 [ + + ]: 4980525 : auto elemdt = std::min( euler_dt, std::min( viscous_dt, conduct_dt ) ); 640 : : // find minimum dt across all elements 641 : 4980525 : mindt = std::min( elemdt, mindt ); 642 : : } @@ -731,7 +731,7 @@ 649 : : Assert( vol.size() == voln.size(), "Size mismatch" ); 650 [ + + ]: 375342 : for (std::size_t p=0; p<vol.size(); ++p) { 651 : 375044 : auto vol_dt = dtn * - 652 [ + + ][ + - ]: 477642 : std::min(voln[p],vol[p]) / std::abs(voln[p]-vol[p]+1.0e-14); + 652 [ + + ][ + - ]: 477640 : std::min(voln[p],vol[p]) / std::abs(voln[p]-vol[p]+1.0e-14); 653 : 375044 : mindt = std::min( vol_dt, mindt ); 654 : : } 655 : 298 : mindt *= dvcfl; @@ -1296,10 +1296,10 @@ 1212 : : // MUSCL reconstruction of edge-end-point primitive variables 1213 [ + + ]: 137823984 : for (std::size_t c=0; c<5; ++c) { 1214 : : // gradients - 1215 [ + + ]: 114853320 : std::array< real, 3 > g1{ G(p,c*3+0), G(p,c*3+1), G(p,c*3+2) }, + 1215 [ + + ]: 114853320 : std::array< real, 3 > g1{ G(p,c*3+0), G(p,c*3+1), G(p,c*3+2) }, 1216 : 114853320 : g2{ G(q,c*3+0), G(q,c*3+1), G(q,c*3+2) }; 1217 : : - 1218 [ + + ]: 114853320 : delta2[c] = rs[c] - ls[c]; + 1218 [ + + ]: 114853320 : delta2[c] = rs[c] - ls[c]; 1219 : 114853320 : delta1[c] = 2.0 * tk::dot(g1,vw) - delta2[c]; 1220 : 114853320 : delta3[c] = 2.0 * tk::dot(g2,vw) - delta2[c]; 1221 : : @@ -1346,9 +1346,9 @@ 1262 : : // the following form is derived from the flux limiter phi as: 1263 : : // s = phi_inv - (1 - phi) 1264 : 229706640 : auto sL = std::max(0.0, (2.0*delta1[c]*delta2[c] + muscl_eps) - 1265 [ + + ]: 114853320 : /(delta1[c]*delta1[c] + delta2[c]*delta2[c] + muscl_eps)); + 1265 [ + + ]: 114853320 : /(delta1[c]*delta1[c] + delta2[c]*delta2[c] + muscl_eps)); 1266 : 229706640 : auto sR = std::max(0.0, (2.0*delta3[c]*delta2[c] + muscl_eps) - 1267 [ + + ]: 114853320 : /(delta3[c]*delta3[c] + delta2[c]*delta2[c] + muscl_eps)); + 1267 [ + + ]: 114853320 : /(delta3[c]*delta3[c] + delta2[c]*delta2[c] + muscl_eps)); 1268 : : 1269 : : // update unknowns with reconstructed unknowns 1270 : 114853320 : url[c] += 0.25*sL*(delta1[c]*(1.0-muscl_const*sL) diff --git a/Release/test_coverage/PDE/CompFlow/DGCompFlow.hpp.func-sort-c.html b/Release/test_coverage/PDE/CompFlow/DGCompFlow.hpp.func-sort-c.html index 409d876a3c7b..5a08eee1ffa3 100644 --- a/Release/test_coverage/PDE/CompFlow/DGCompFlow.hpp.func-sort-c.html +++ b/Release/test_coverage/PDE/CompFlow/DGCompFlow.hpp.func-sort-c.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:26:06 + 2024-07-11 14:48:26 Functions: 58 diff --git a/Release/test_coverage/PDE/CompFlow/DGCompFlow.hpp.func.html b/Release/test_coverage/PDE/CompFlow/DGCompFlow.hpp.func.html index b6fe11ba74c6..033e9bfa7547 100644 --- a/Release/test_coverage/PDE/CompFlow/DGCompFlow.hpp.func.html +++ b/Release/test_coverage/PDE/CompFlow/DGCompFlow.hpp.func.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:26:06 + 2024-07-11 14:48:26 Functions: 58 diff --git a/Release/test_coverage/PDE/CompFlow/DGCompFlow.hpp.gcov.html b/Release/test_coverage/PDE/CompFlow/DGCompFlow.hpp.gcov.html index db91cd6cc2e2..dc3b6b31320b 100644 --- a/Release/test_coverage/PDE/CompFlow/DGCompFlow.hpp.gcov.html +++ b/Release/test_coverage/PDE/CompFlow/DGCompFlow.hpp.gcov.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:26:06 + 2024-07-11 14:48:26 Functions: 58 @@ -678,7 +678,7 @@ 594 : 1101260 : auto eR = static_cast< std::size_t >( er ); 595 : : 596 [ + - ]: 1101260 : auto ng_l = tk::NGfa(ndofel[el]); - 597 [ + - ][ + + ]: 1101260 : auto ng_r = tk::NGfa(ndofel[eR]); + 597 [ + - ][ + + ]: 1101260 : auto ng_r = tk::NGfa(ndofel[eR]); 598 : : 599 : : // When the number of gauss points for the left and right element are 600 : : // different, choose the larger ng @@ -743,18 +743,18 @@ 659 [ + - ]: 20758845 : auto mark = c*rdof; 660 [ + - ]: 20758845 : ugp[0].push_back( U(el, mark) ); 661 : : - 662 [ + + ]: 20758845 : if(ndofel[el] > 1) //DG(P1) - 663 : 17318145 : ugp[0][c] += U(el, mark+1) * B_l[1] - 664 : 17318145 : + U(el, mark+2) * B_l[2] - 665 : 17318145 : + U(el, mark+3) * B_l[3]; + 662 [ + + ]: 20758845 : if(ndofel[el] > 1) //DG(P1) + 663 : 17317560 : ugp[0][c] += U(el, mark+1) * B_l[1] + 664 : 17317560 : + U(el, mark+2) * B_l[2] + 665 : 17317560 : + U(el, mark+3) * B_l[3]; 666 : : - 667 [ + + ]: 20758845 : if(ndofel[el] > 4) //DG(P2) - 668 : 10488420 : ugp[0][c] += U(el, mark+4) * B_l[4] - 669 : 10488420 : + U(el, mark+5) * B_l[5] - 670 : 10488420 : + U(el, mark+6) * B_l[6] - 671 : 10488420 : + U(el, mark+7) * B_l[7] - 672 : 10488420 : + U(el, mark+8) * B_l[8] - 673 : 10488420 : + U(el, mark+9) * B_l[9]; + 667 [ + + ]: 20758845 : if(ndofel[el] > 4) //DG(P2) + 668 : 10490820 : ugp[0][c] += U(el, mark+4) * B_l[4] + 669 : 10490820 : + U(el, mark+5) * B_l[5] + 670 : 10490820 : + U(el, mark+6) * B_l[6] + 671 : 10490820 : + U(el, mark+7) * B_l[7] + 672 : 10490820 : + U(el, mark+8) * B_l[8] + 673 : 10490820 : + U(el, mark+9) * B_l[9]; 674 : : } 675 : : 676 : 4151769 : rho = ugp[0][0]; @@ -802,18 +802,18 @@ 718 [ + - ]: 15412820 : auto mark = c*rdof; 719 [ + - ]: 15412820 : ugp[1].push_back( U(eR, mark) ); 720 : : - 721 [ + + ]: 15412820 : if(ndofel[eR] > 1) //DG(P1) - 722 : 12829770 : ugp[1][c] += U(eR, mark+1) * B_r[1] - 723 : 12829770 : + U(eR, mark+2) * B_r[2] - 724 : 12829770 : + U(eR, mark+3) * B_r[3]; + 721 [ + + ]: 15412820 : if(ndofel[eR] > 1) //DG(P1) + 722 : 12830355 : ugp[1][c] += U(eR, mark+1) * B_r[1] + 723 : 12830355 : + U(eR, mark+2) * B_r[2] + 724 : 12830355 : + U(eR, mark+3) * B_r[3]; 725 : : - 726 [ + + ]: 15412820 : if(ndofel[eR] > 4) //DG(P2) - 727 : 7863960 : ugp[1][c] += U(eR, mark+4) * B_r[4] - 728 : 7863960 : + U(eR, mark+5) * B_r[5] - 729 : 7863960 : + U(eR, mark+6) * B_r[6] - 730 : 7863960 : + U(eR, mark+7) * B_r[7] - 731 : 7863960 : + U(eR, mark+8) * B_r[8] - 732 : 7863960 : + U(eR, mark+9) * B_r[9]; + 726 [ + + ]: 15412820 : if(ndofel[eR] > 4) //DG(P2) + 727 : 7861560 : ugp[1][c] += U(eR, mark+4) * B_r[4] + 728 : 7861560 : + U(eR, mark+5) * B_r[5] + 729 : 7861560 : + U(eR, mark+6) * B_r[6] + 730 : 7861560 : + U(eR, mark+7) * B_r[7] + 731 : 7861560 : + U(eR, mark+8) * B_r[8] + 732 : 7861560 : + U(eR, mark+9) * B_r[9]; 733 : : } 734 : : 735 : 3082564 : rho = ugp[1][0]; @@ -826,7 +826,7 @@ 742 : : 743 : 3082564 : vn = u*geoFace(f,1) + v*geoFace(f,2) + w*geoFace(f,3); 744 : : - 745 [ + + ]: 3082564 : dSV_r = wt * (std::fabs(vn) + a); + 745 [ + + ]: 3082564 : dSV_r = wt * (std::fabs(vn) + a); 746 [ + - ]: 3082564 : delt[eR] += std::max( dSV_l, dSV_r ); 747 : : } 748 : : @@ -852,7 +852,7 @@ 768 : : 769 : : // Scale smallest dt with CFL coefficient and the CFL is scaled by (2*p+1) 770 : : // where p is the order of the DG polynomial by linear stability theory. - 771 [ + + ]: 627919 : mindt = std::min( mindt, geoElem(e,0)/ (delt[e] * (2.0*dgp + 1.0)) ); + 771 [ + + ]: 627849 : mindt = std::min( mindt, geoElem(e,0)/ (delt[e] * (2.0*dgp + 1.0)) ); 772 : : } 773 : : 774 [ + - ]: 4140 : return mindt; diff --git a/Release/test_coverage/PDE/CompFlow/Physics/CGNavierStokes.cpp.func-sort-c.html b/Release/test_coverage/PDE/CompFlow/Physics/CGNavierStokes.cpp.func-sort-c.html index e71ed28bb8fe..3045183ed56d 100644 --- a/Release/test_coverage/PDE/CompFlow/Physics/CGNavierStokes.cpp.func-sort-c.html +++ b/Release/test_coverage/PDE/CompFlow/Physics/CGNavierStokes.cpp.func-sort-c.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:26:06 + 2024-07-11 14:48:26 Functions: 0 diff --git a/Release/test_coverage/PDE/CompFlow/Physics/CGNavierStokes.cpp.func.html b/Release/test_coverage/PDE/CompFlow/Physics/CGNavierStokes.cpp.func.html index bc0826c81a01..584546a94f71 100644 --- a/Release/test_coverage/PDE/CompFlow/Physics/CGNavierStokes.cpp.func.html +++ b/Release/test_coverage/PDE/CompFlow/Physics/CGNavierStokes.cpp.func.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:26:06 + 2024-07-11 14:48:26 Functions: 0 diff --git a/Release/test_coverage/PDE/CompFlow/Physics/CGNavierStokes.cpp.gcov.html b/Release/test_coverage/PDE/CompFlow/Physics/CGNavierStokes.cpp.gcov.html index bd4fa5537be0..157908f035cd 100644 --- a/Release/test_coverage/PDE/CompFlow/Physics/CGNavierStokes.cpp.gcov.html +++ b/Release/test_coverage/PDE/CompFlow/Physics/CGNavierStokes.cpp.gcov.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:26:06 + 2024-07-11 14:48:26 Functions: 0 diff --git a/Release/test_coverage/PDE/CompFlow/Physics/index-sort-b.html b/Release/test_coverage/PDE/CompFlow/Physics/index-sort-b.html index 4ec2911eda14..0ccbe6dfe7fc 100644 --- a/Release/test_coverage/PDE/CompFlow/Physics/index-sort-b.html +++ b/Release/test_coverage/PDE/CompFlow/Physics/index-sort-b.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:26:06 + 2024-07-11 14:48:26 Functions: 0 diff --git a/Release/test_coverage/PDE/CompFlow/Physics/index-sort-f.html b/Release/test_coverage/PDE/CompFlow/Physics/index-sort-f.html index 2757b3114d19..d6e52eb2735d 100644 --- a/Release/test_coverage/PDE/CompFlow/Physics/index-sort-f.html +++ b/Release/test_coverage/PDE/CompFlow/Physics/index-sort-f.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:26:06 + 2024-07-11 14:48:26 Functions: 0 diff --git a/Release/test_coverage/PDE/CompFlow/Physics/index-sort-l.html b/Release/test_coverage/PDE/CompFlow/Physics/index-sort-l.html index 8d532a506c99..151099d5998e 100644 --- a/Release/test_coverage/PDE/CompFlow/Physics/index-sort-l.html +++ b/Release/test_coverage/PDE/CompFlow/Physics/index-sort-l.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:26:06 + 2024-07-11 14:48:26 Functions: 0 diff --git a/Release/test_coverage/PDE/CompFlow/Physics/index.html b/Release/test_coverage/PDE/CompFlow/Physics/index.html index c52d98c01e74..cbd680e05b67 100644 --- a/Release/test_coverage/PDE/CompFlow/Physics/index.html +++ b/Release/test_coverage/PDE/CompFlow/Physics/index.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:26:06 + 2024-07-11 14:48:26 Functions: 0 diff --git a/Release/test_coverage/PDE/CompFlow/Problem/BoxInitialization.hpp.func-sort-c.html b/Release/test_coverage/PDE/CompFlow/Problem/BoxInitialization.hpp.func-sort-c.html index d62153243f16..48989948c9e1 100644 --- a/Release/test_coverage/PDE/CompFlow/Problem/BoxInitialization.hpp.func-sort-c.html +++ b/Release/test_coverage/PDE/CompFlow/Problem/BoxInitialization.hpp.func-sort-c.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:26:06 + 2024-07-11 14:48:26 Functions: 1 diff --git a/Release/test_coverage/PDE/CompFlow/Problem/BoxInitialization.hpp.func.html b/Release/test_coverage/PDE/CompFlow/Problem/BoxInitialization.hpp.func.html index 22e45b19b85b..ec892ea7b9c7 100644 --- a/Release/test_coverage/PDE/CompFlow/Problem/BoxInitialization.hpp.func.html +++ b/Release/test_coverage/PDE/CompFlow/Problem/BoxInitialization.hpp.func.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:26:06 + 2024-07-11 14:48:26 Functions: 1 diff --git a/Release/test_coverage/PDE/CompFlow/Problem/BoxInitialization.hpp.gcov.html b/Release/test_coverage/PDE/CompFlow/Problem/BoxInitialization.hpp.gcov.html index 772f8691cf36..8be99c303fce 100644 --- a/Release/test_coverage/PDE/CompFlow/Problem/BoxInitialization.hpp.gcov.html +++ b/Release/test_coverage/PDE/CompFlow/Problem/BoxInitialization.hpp.gcov.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:26:06 + 2024-07-11 14:48:26 Functions: 1 diff --git a/Release/test_coverage/PDE/CompFlow/Problem/FieldOutput.cpp.func-sort-c.html b/Release/test_coverage/PDE/CompFlow/Problem/FieldOutput.cpp.func-sort-c.html index 2410f6dee277..6e14611e8a50 100644 --- a/Release/test_coverage/PDE/CompFlow/Problem/FieldOutput.cpp.func-sort-c.html +++ b/Release/test_coverage/PDE/CompFlow/Problem/FieldOutput.cpp.func-sort-c.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:26:06 + 2024-07-11 14:48:26 Functions: 6 diff --git a/Release/test_coverage/PDE/CompFlow/Problem/FieldOutput.cpp.func.html b/Release/test_coverage/PDE/CompFlow/Problem/FieldOutput.cpp.func.html index 6c3ef599c2fe..4f7a4d60caec 100644 --- a/Release/test_coverage/PDE/CompFlow/Problem/FieldOutput.cpp.func.html +++ b/Release/test_coverage/PDE/CompFlow/Problem/FieldOutput.cpp.func.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:26:06 + 2024-07-11 14:48:26 Functions: 6 diff --git a/Release/test_coverage/PDE/CompFlow/Problem/FieldOutput.cpp.gcov.html b/Release/test_coverage/PDE/CompFlow/Problem/FieldOutput.cpp.gcov.html index 899bca525d37..2ea6557e3368 100644 --- a/Release/test_coverage/PDE/CompFlow/Problem/FieldOutput.cpp.gcov.html +++ b/Release/test_coverage/PDE/CompFlow/Problem/FieldOutput.cpp.gcov.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:26:06 + 2024-07-11 14:48:26 Functions: 6 diff --git a/Release/test_coverage/PDE/CompFlow/Problem/GaussHumpCompflow.cpp.func-sort-c.html b/Release/test_coverage/PDE/CompFlow/Problem/GaussHumpCompflow.cpp.func-sort-c.html index 84055ffa821d..f108a0629d8a 100644 --- a/Release/test_coverage/PDE/CompFlow/Problem/GaussHumpCompflow.cpp.func-sort-c.html +++ b/Release/test_coverage/PDE/CompFlow/Problem/GaussHumpCompflow.cpp.func-sort-c.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:26:06 + 2024-07-11 14:48:26 Functions: 5 diff --git a/Release/test_coverage/PDE/CompFlow/Problem/GaussHumpCompflow.cpp.func.html b/Release/test_coverage/PDE/CompFlow/Problem/GaussHumpCompflow.cpp.func.html index bf4796eec2a2..6a8b1b7ee449 100644 --- a/Release/test_coverage/PDE/CompFlow/Problem/GaussHumpCompflow.cpp.func.html +++ b/Release/test_coverage/PDE/CompFlow/Problem/GaussHumpCompflow.cpp.func.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:26:06 + 2024-07-11 14:48:26 Functions: 5 diff --git a/Release/test_coverage/PDE/CompFlow/Problem/GaussHumpCompflow.cpp.gcov.html b/Release/test_coverage/PDE/CompFlow/Problem/GaussHumpCompflow.cpp.gcov.html index c2cb38ab2f44..23d8d609812f 100644 --- a/Release/test_coverage/PDE/CompFlow/Problem/GaussHumpCompflow.cpp.gcov.html +++ b/Release/test_coverage/PDE/CompFlow/Problem/GaussHumpCompflow.cpp.gcov.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:26:06 + 2024-07-11 14:48:26 Functions: 5 diff --git a/Release/test_coverage/PDE/CompFlow/Problem/GaussHumpCompflow.hpp.func-sort-c.html b/Release/test_coverage/PDE/CompFlow/Problem/GaussHumpCompflow.hpp.func-sort-c.html index c617f0328dce..1f78f1f04154 100644 --- a/Release/test_coverage/PDE/CompFlow/Problem/GaussHumpCompflow.hpp.func-sort-c.html +++ b/Release/test_coverage/PDE/CompFlow/Problem/GaussHumpCompflow.hpp.func-sort-c.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:26:06 + 2024-07-11 14:48:26 Functions: 1 diff --git a/Release/test_coverage/PDE/CompFlow/Problem/GaussHumpCompflow.hpp.func.html b/Release/test_coverage/PDE/CompFlow/Problem/GaussHumpCompflow.hpp.func.html index 6aac21b522ee..fa9c44869941 100644 --- a/Release/test_coverage/PDE/CompFlow/Problem/GaussHumpCompflow.hpp.func.html +++ b/Release/test_coverage/PDE/CompFlow/Problem/GaussHumpCompflow.hpp.func.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:26:06 + 2024-07-11 14:48:26 Functions: 1 diff --git a/Release/test_coverage/PDE/CompFlow/Problem/GaussHumpCompflow.hpp.gcov.html b/Release/test_coverage/PDE/CompFlow/Problem/GaussHumpCompflow.hpp.gcov.html index d3d258083b81..58fb3784a6d8 100644 --- a/Release/test_coverage/PDE/CompFlow/Problem/GaussHumpCompflow.hpp.gcov.html +++ b/Release/test_coverage/PDE/CompFlow/Problem/GaussHumpCompflow.hpp.gcov.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:26:06 + 2024-07-11 14:48:26 Functions: 1 diff --git a/Release/test_coverage/PDE/CompFlow/Problem/NLEnergyGrowth.cpp.func-sort-c.html b/Release/test_coverage/PDE/CompFlow/Problem/NLEnergyGrowth.cpp.func-sort-c.html index 6fe5d6c0d76e..bec74613d862 100644 --- a/Release/test_coverage/PDE/CompFlow/Problem/NLEnergyGrowth.cpp.func-sort-c.html +++ b/Release/test_coverage/PDE/CompFlow/Problem/NLEnergyGrowth.cpp.func-sort-c.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:26:06 + 2024-07-11 14:48:26 Functions: 6 diff --git a/Release/test_coverage/PDE/CompFlow/Problem/NLEnergyGrowth.cpp.func.html b/Release/test_coverage/PDE/CompFlow/Problem/NLEnergyGrowth.cpp.func.html index 62af7ce30ed1..45eaef96583c 100644 --- a/Release/test_coverage/PDE/CompFlow/Problem/NLEnergyGrowth.cpp.func.html +++ b/Release/test_coverage/PDE/CompFlow/Problem/NLEnergyGrowth.cpp.func.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:26:06 + 2024-07-11 14:48:26 Functions: 6 diff --git a/Release/test_coverage/PDE/CompFlow/Problem/NLEnergyGrowth.cpp.gcov.html b/Release/test_coverage/PDE/CompFlow/Problem/NLEnergyGrowth.cpp.gcov.html index 502d1504ffd0..ef6c30cd3235 100644 --- a/Release/test_coverage/PDE/CompFlow/Problem/NLEnergyGrowth.cpp.gcov.html +++ b/Release/test_coverage/PDE/CompFlow/Problem/NLEnergyGrowth.cpp.gcov.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:26:06 + 2024-07-11 14:48:26 Functions: 6 diff --git a/Release/test_coverage/PDE/CompFlow/Problem/NLEnergyGrowth.hpp.func-sort-c.html b/Release/test_coverage/PDE/CompFlow/Problem/NLEnergyGrowth.hpp.func-sort-c.html index 11200cc36eab..3066cd7b9f3c 100644 --- a/Release/test_coverage/PDE/CompFlow/Problem/NLEnergyGrowth.hpp.func-sort-c.html +++ b/Release/test_coverage/PDE/CompFlow/Problem/NLEnergyGrowth.hpp.func-sort-c.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:26:06 + 2024-07-11 14:48:26 Functions: 1 diff --git a/Release/test_coverage/PDE/CompFlow/Problem/NLEnergyGrowth.hpp.func.html b/Release/test_coverage/PDE/CompFlow/Problem/NLEnergyGrowth.hpp.func.html index 398f2b6d49df..88e03c944aa2 100644 --- a/Release/test_coverage/PDE/CompFlow/Problem/NLEnergyGrowth.hpp.func.html +++ b/Release/test_coverage/PDE/CompFlow/Problem/NLEnergyGrowth.hpp.func.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:26:06 + 2024-07-11 14:48:26 Functions: 1 diff --git a/Release/test_coverage/PDE/CompFlow/Problem/NLEnergyGrowth.hpp.gcov.html b/Release/test_coverage/PDE/CompFlow/Problem/NLEnergyGrowth.hpp.gcov.html index 3568c7a8ff8f..6ec71652228b 100644 --- a/Release/test_coverage/PDE/CompFlow/Problem/NLEnergyGrowth.hpp.gcov.html +++ b/Release/test_coverage/PDE/CompFlow/Problem/NLEnergyGrowth.hpp.gcov.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:26:06 + 2024-07-11 14:48:26 Functions: 1 diff --git a/Release/test_coverage/PDE/CompFlow/Problem/RayleighTaylor.cpp.func-sort-c.html b/Release/test_coverage/PDE/CompFlow/Problem/RayleighTaylor.cpp.func-sort-c.html index d5dc3aa68788..d763cdac5ce6 100644 --- a/Release/test_coverage/PDE/CompFlow/Problem/RayleighTaylor.cpp.func-sort-c.html +++ b/Release/test_coverage/PDE/CompFlow/Problem/RayleighTaylor.cpp.func-sort-c.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:26:06 + 2024-07-11 14:48:26 Functions: 2 diff --git a/Release/test_coverage/PDE/CompFlow/Problem/RayleighTaylor.cpp.func.html b/Release/test_coverage/PDE/CompFlow/Problem/RayleighTaylor.cpp.func.html index d775b70bae30..5f23c79cc6b9 100644 --- a/Release/test_coverage/PDE/CompFlow/Problem/RayleighTaylor.cpp.func.html +++ b/Release/test_coverage/PDE/CompFlow/Problem/RayleighTaylor.cpp.func.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:26:06 + 2024-07-11 14:48:26 Functions: 2 diff --git a/Release/test_coverage/PDE/CompFlow/Problem/RayleighTaylor.cpp.gcov.html b/Release/test_coverage/PDE/CompFlow/Problem/RayleighTaylor.cpp.gcov.html index ae73f00c1750..5e00a607882b 100644 --- a/Release/test_coverage/PDE/CompFlow/Problem/RayleighTaylor.cpp.gcov.html +++ b/Release/test_coverage/PDE/CompFlow/Problem/RayleighTaylor.cpp.gcov.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:26:06 + 2024-07-11 14:48:26 Functions: 2 diff --git a/Release/test_coverage/PDE/CompFlow/Problem/RayleighTaylor.hpp.func-sort-c.html b/Release/test_coverage/PDE/CompFlow/Problem/RayleighTaylor.hpp.func-sort-c.html index 52d3e4efdbab..736d3c64b5d0 100644 --- a/Release/test_coverage/PDE/CompFlow/Problem/RayleighTaylor.hpp.func-sort-c.html +++ b/Release/test_coverage/PDE/CompFlow/Problem/RayleighTaylor.hpp.func-sort-c.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:26:06 + 2024-07-11 14:48:26 Functions: 1 diff --git a/Release/test_coverage/PDE/CompFlow/Problem/RayleighTaylor.hpp.func.html b/Release/test_coverage/PDE/CompFlow/Problem/RayleighTaylor.hpp.func.html index acac7ad5b001..94e0018fc6b8 100644 --- a/Release/test_coverage/PDE/CompFlow/Problem/RayleighTaylor.hpp.func.html +++ b/Release/test_coverage/PDE/CompFlow/Problem/RayleighTaylor.hpp.func.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:26:06 + 2024-07-11 14:48:26 Functions: 1 diff --git a/Release/test_coverage/PDE/CompFlow/Problem/RayleighTaylor.hpp.gcov.html b/Release/test_coverage/PDE/CompFlow/Problem/RayleighTaylor.hpp.gcov.html index 768c9c6d7cbf..d23a9d6d453f 100644 --- a/Release/test_coverage/PDE/CompFlow/Problem/RayleighTaylor.hpp.gcov.html +++ b/Release/test_coverage/PDE/CompFlow/Problem/RayleighTaylor.hpp.gcov.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:26:06 + 2024-07-11 14:48:26 Functions: 1 diff --git a/Release/test_coverage/PDE/CompFlow/Problem/RotatedSodShocktube.cpp.func-sort-c.html b/Release/test_coverage/PDE/CompFlow/Problem/RotatedSodShocktube.cpp.func-sort-c.html index 4337e4bb8ef6..144116726131 100644 --- a/Release/test_coverage/PDE/CompFlow/Problem/RotatedSodShocktube.cpp.func-sort-c.html +++ b/Release/test_coverage/PDE/CompFlow/Problem/RotatedSodShocktube.cpp.func-sort-c.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:26:06 + 2024-07-11 14:48:26 Functions: 1 diff --git a/Release/test_coverage/PDE/CompFlow/Problem/RotatedSodShocktube.cpp.func.html b/Release/test_coverage/PDE/CompFlow/Problem/RotatedSodShocktube.cpp.func.html index 0b5e60ff150a..e22b14b3459a 100644 --- a/Release/test_coverage/PDE/CompFlow/Problem/RotatedSodShocktube.cpp.func.html +++ b/Release/test_coverage/PDE/CompFlow/Problem/RotatedSodShocktube.cpp.func.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:26:06 + 2024-07-11 14:48:26 Functions: 1 diff --git a/Release/test_coverage/PDE/CompFlow/Problem/RotatedSodShocktube.cpp.gcov.html b/Release/test_coverage/PDE/CompFlow/Problem/RotatedSodShocktube.cpp.gcov.html index bffe83b53476..2460e9202d9d 100644 --- a/Release/test_coverage/PDE/CompFlow/Problem/RotatedSodShocktube.cpp.gcov.html +++ b/Release/test_coverage/PDE/CompFlow/Problem/RotatedSodShocktube.cpp.gcov.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:26:06 + 2024-07-11 14:48:26 Functions: 1 diff --git a/Release/test_coverage/PDE/CompFlow/Problem/SedovBlastwave.cpp.func-sort-c.html b/Release/test_coverage/PDE/CompFlow/Problem/SedovBlastwave.cpp.func-sort-c.html index 2db8ce81db6b..668fd9998770 100644 --- a/Release/test_coverage/PDE/CompFlow/Problem/SedovBlastwave.cpp.func-sort-c.html +++ b/Release/test_coverage/PDE/CompFlow/Problem/SedovBlastwave.cpp.func-sort-c.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:26:06 + 2024-07-11 14:48:26 Functions: 2 diff --git a/Release/test_coverage/PDE/CompFlow/Problem/SedovBlastwave.cpp.func.html b/Release/test_coverage/PDE/CompFlow/Problem/SedovBlastwave.cpp.func.html index cb23e9a8c9fd..225a16a8d8e7 100644 --- a/Release/test_coverage/PDE/CompFlow/Problem/SedovBlastwave.cpp.func.html +++ b/Release/test_coverage/PDE/CompFlow/Problem/SedovBlastwave.cpp.func.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:26:06 + 2024-07-11 14:48:26 Functions: 2 diff --git a/Release/test_coverage/PDE/CompFlow/Problem/SedovBlastwave.cpp.gcov.html b/Release/test_coverage/PDE/CompFlow/Problem/SedovBlastwave.cpp.gcov.html index a81e4b25fcf5..b72cb62a9e14 100644 --- a/Release/test_coverage/PDE/CompFlow/Problem/SedovBlastwave.cpp.gcov.html +++ b/Release/test_coverage/PDE/CompFlow/Problem/SedovBlastwave.cpp.gcov.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:26:06 + 2024-07-11 14:48:26 Functions: 2 diff --git a/Release/test_coverage/PDE/CompFlow/Problem/SedovBlastwave.hpp.func-sort-c.html b/Release/test_coverage/PDE/CompFlow/Problem/SedovBlastwave.hpp.func-sort-c.html index 5ae9953b5e4f..0705496cab77 100644 --- a/Release/test_coverage/PDE/CompFlow/Problem/SedovBlastwave.hpp.func-sort-c.html +++ b/Release/test_coverage/PDE/CompFlow/Problem/SedovBlastwave.hpp.func-sort-c.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:26:06 + 2024-07-11 14:48:26 Functions: 1 diff --git a/Release/test_coverage/PDE/CompFlow/Problem/SedovBlastwave.hpp.func.html b/Release/test_coverage/PDE/CompFlow/Problem/SedovBlastwave.hpp.func.html index 621368b065f8..6f1ac50551ce 100644 --- a/Release/test_coverage/PDE/CompFlow/Problem/SedovBlastwave.hpp.func.html +++ b/Release/test_coverage/PDE/CompFlow/Problem/SedovBlastwave.hpp.func.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:26:06 + 2024-07-11 14:48:26 Functions: 1 diff --git a/Release/test_coverage/PDE/CompFlow/Problem/SedovBlastwave.hpp.gcov.html b/Release/test_coverage/PDE/CompFlow/Problem/SedovBlastwave.hpp.gcov.html index 5b08094be231..93a83fbc5b0c 100644 --- a/Release/test_coverage/PDE/CompFlow/Problem/SedovBlastwave.hpp.gcov.html +++ b/Release/test_coverage/PDE/CompFlow/Problem/SedovBlastwave.hpp.gcov.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:26:06 + 2024-07-11 14:48:26 Functions: 1 diff --git a/Release/test_coverage/PDE/CompFlow/Problem/SheddingFlow.cpp.func-sort-c.html b/Release/test_coverage/PDE/CompFlow/Problem/SheddingFlow.cpp.func-sort-c.html index 339fdb3065b3..b574db153d63 100644 --- a/Release/test_coverage/PDE/CompFlow/Problem/SheddingFlow.cpp.func-sort-c.html +++ b/Release/test_coverage/PDE/CompFlow/Problem/SheddingFlow.cpp.func-sort-c.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:26:06 + 2024-07-11 14:48:26 Functions: 0 diff --git a/Release/test_coverage/PDE/CompFlow/Problem/SheddingFlow.cpp.func.html b/Release/test_coverage/PDE/CompFlow/Problem/SheddingFlow.cpp.func.html index 1c5d368d5d3f..bf8b62fbbb68 100644 --- a/Release/test_coverage/PDE/CompFlow/Problem/SheddingFlow.cpp.func.html +++ b/Release/test_coverage/PDE/CompFlow/Problem/SheddingFlow.cpp.func.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:26:06 + 2024-07-11 14:48:26 Functions: 0 diff --git a/Release/test_coverage/PDE/CompFlow/Problem/SheddingFlow.cpp.gcov.html b/Release/test_coverage/PDE/CompFlow/Problem/SheddingFlow.cpp.gcov.html index 31fe4cd786e4..8453bd474c5a 100644 --- a/Release/test_coverage/PDE/CompFlow/Problem/SheddingFlow.cpp.gcov.html +++ b/Release/test_coverage/PDE/CompFlow/Problem/SheddingFlow.cpp.gcov.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:26:06 + 2024-07-11 14:48:26 Functions: 0 diff --git a/Release/test_coverage/PDE/CompFlow/Problem/SheddingFlow.hpp.func-sort-c.html b/Release/test_coverage/PDE/CompFlow/Problem/SheddingFlow.hpp.func-sort-c.html index 1f623b63953a..3d99a9c69243 100644 --- a/Release/test_coverage/PDE/CompFlow/Problem/SheddingFlow.hpp.func-sort-c.html +++ b/Release/test_coverage/PDE/CompFlow/Problem/SheddingFlow.hpp.func-sort-c.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:26:06 + 2024-07-11 14:48:26 Functions: 0 diff --git a/Release/test_coverage/PDE/CompFlow/Problem/SheddingFlow.hpp.func.html b/Release/test_coverage/PDE/CompFlow/Problem/SheddingFlow.hpp.func.html index db9ba1f4781c..0c50cb3a9863 100644 --- a/Release/test_coverage/PDE/CompFlow/Problem/SheddingFlow.hpp.func.html +++ b/Release/test_coverage/PDE/CompFlow/Problem/SheddingFlow.hpp.func.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:26:06 + 2024-07-11 14:48:26 Functions: 0 diff --git a/Release/test_coverage/PDE/CompFlow/Problem/SheddingFlow.hpp.gcov.html b/Release/test_coverage/PDE/CompFlow/Problem/SheddingFlow.hpp.gcov.html index bbda93025edb..c114bb95a2b6 100644 --- a/Release/test_coverage/PDE/CompFlow/Problem/SheddingFlow.hpp.gcov.html +++ b/Release/test_coverage/PDE/CompFlow/Problem/SheddingFlow.hpp.gcov.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:26:06 + 2024-07-11 14:48:26 Functions: 0 diff --git a/Release/test_coverage/PDE/CompFlow/Problem/ShockDensityWave.cpp.func-sort-c.html b/Release/test_coverage/PDE/CompFlow/Problem/ShockDensityWave.cpp.func-sort-c.html index 5e5f6e56fa11..2e5c00ae31bb 100644 --- a/Release/test_coverage/PDE/CompFlow/Problem/ShockDensityWave.cpp.func-sort-c.html +++ b/Release/test_coverage/PDE/CompFlow/Problem/ShockDensityWave.cpp.func-sort-c.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:26:06 + 2024-07-11 14:48:26 Functions: 0 diff --git a/Release/test_coverage/PDE/CompFlow/Problem/ShockDensityWave.cpp.func.html b/Release/test_coverage/PDE/CompFlow/Problem/ShockDensityWave.cpp.func.html index e8e8c4bee09b..d1becb6b9035 100644 --- a/Release/test_coverage/PDE/CompFlow/Problem/ShockDensityWave.cpp.func.html +++ b/Release/test_coverage/PDE/CompFlow/Problem/ShockDensityWave.cpp.func.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:26:06 + 2024-07-11 14:48:26 Functions: 0 diff --git a/Release/test_coverage/PDE/CompFlow/Problem/ShockDensityWave.cpp.gcov.html b/Release/test_coverage/PDE/CompFlow/Problem/ShockDensityWave.cpp.gcov.html index 8c6f49f915ec..dce855f70f71 100644 --- a/Release/test_coverage/PDE/CompFlow/Problem/ShockDensityWave.cpp.gcov.html +++ b/Release/test_coverage/PDE/CompFlow/Problem/ShockDensityWave.cpp.gcov.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:26:06 + 2024-07-11 14:48:26 Functions: 0 diff --git a/Release/test_coverage/PDE/CompFlow/Problem/ShockDensityWave.hpp.func-sort-c.html b/Release/test_coverage/PDE/CompFlow/Problem/ShockDensityWave.hpp.func-sort-c.html index c03ef7c664c2..2422e2111296 100644 --- a/Release/test_coverage/PDE/CompFlow/Problem/ShockDensityWave.hpp.func-sort-c.html +++ b/Release/test_coverage/PDE/CompFlow/Problem/ShockDensityWave.hpp.func-sort-c.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:26:06 + 2024-07-11 14:48:26 Functions: 0 diff --git a/Release/test_coverage/PDE/CompFlow/Problem/ShockDensityWave.hpp.func.html b/Release/test_coverage/PDE/CompFlow/Problem/ShockDensityWave.hpp.func.html index dc60a421de03..ffd7d2c5fa45 100644 --- a/Release/test_coverage/PDE/CompFlow/Problem/ShockDensityWave.hpp.func.html +++ b/Release/test_coverage/PDE/CompFlow/Problem/ShockDensityWave.hpp.func.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:26:06 + 2024-07-11 14:48:26 Functions: 0 diff --git a/Release/test_coverage/PDE/CompFlow/Problem/ShockDensityWave.hpp.gcov.html b/Release/test_coverage/PDE/CompFlow/Problem/ShockDensityWave.hpp.gcov.html index 0e394367330c..2467ea56b437 100644 --- a/Release/test_coverage/PDE/CompFlow/Problem/ShockDensityWave.hpp.gcov.html +++ b/Release/test_coverage/PDE/CompFlow/Problem/ShockDensityWave.hpp.gcov.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:26:06 + 2024-07-11 14:48:26 Functions: 0 diff --git a/Release/test_coverage/PDE/CompFlow/Problem/SodShocktube.cpp.func-sort-c.html b/Release/test_coverage/PDE/CompFlow/Problem/SodShocktube.cpp.func-sort-c.html index 3a8e218a4e05..fde4e016ebb7 100644 --- a/Release/test_coverage/PDE/CompFlow/Problem/SodShocktube.cpp.func-sort-c.html +++ b/Release/test_coverage/PDE/CompFlow/Problem/SodShocktube.cpp.func-sort-c.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:26:06 + 2024-07-11 14:48:26 Functions: 2 diff --git a/Release/test_coverage/PDE/CompFlow/Problem/SodShocktube.cpp.func.html b/Release/test_coverage/PDE/CompFlow/Problem/SodShocktube.cpp.func.html index 01f66e0f5f0b..d18553fe7841 100644 --- a/Release/test_coverage/PDE/CompFlow/Problem/SodShocktube.cpp.func.html +++ b/Release/test_coverage/PDE/CompFlow/Problem/SodShocktube.cpp.func.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:26:06 + 2024-07-11 14:48:26 Functions: 2 diff --git a/Release/test_coverage/PDE/CompFlow/Problem/SodShocktube.cpp.gcov.html b/Release/test_coverage/PDE/CompFlow/Problem/SodShocktube.cpp.gcov.html index a75dd171f254..0f2c92dadabf 100644 --- a/Release/test_coverage/PDE/CompFlow/Problem/SodShocktube.cpp.gcov.html +++ b/Release/test_coverage/PDE/CompFlow/Problem/SodShocktube.cpp.gcov.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:26:06 + 2024-07-11 14:48:26 Functions: 2 diff --git a/Release/test_coverage/PDE/CompFlow/Problem/SodShocktube.hpp.func-sort-c.html b/Release/test_coverage/PDE/CompFlow/Problem/SodShocktube.hpp.func-sort-c.html index 164d5ca97971..8f2bc25d1eed 100644 --- a/Release/test_coverage/PDE/CompFlow/Problem/SodShocktube.hpp.func-sort-c.html +++ b/Release/test_coverage/PDE/CompFlow/Problem/SodShocktube.hpp.func-sort-c.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:26:06 + 2024-07-11 14:48:26 Functions: 1 diff --git a/Release/test_coverage/PDE/CompFlow/Problem/SodShocktube.hpp.func.html b/Release/test_coverage/PDE/CompFlow/Problem/SodShocktube.hpp.func.html index 2013cbc819b7..cbca84d5f32c 100644 --- a/Release/test_coverage/PDE/CompFlow/Problem/SodShocktube.hpp.func.html +++ b/Release/test_coverage/PDE/CompFlow/Problem/SodShocktube.hpp.func.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:26:06 + 2024-07-11 14:48:26 Functions: 1 diff --git a/Release/test_coverage/PDE/CompFlow/Problem/SodShocktube.hpp.gcov.html b/Release/test_coverage/PDE/CompFlow/Problem/SodShocktube.hpp.gcov.html index dedce2e06794..4a81ded1c761 100644 --- a/Release/test_coverage/PDE/CompFlow/Problem/SodShocktube.hpp.gcov.html +++ b/Release/test_coverage/PDE/CompFlow/Problem/SodShocktube.hpp.gcov.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:26:06 + 2024-07-11 14:48:26 Functions: 1 diff --git a/Release/test_coverage/PDE/CompFlow/Problem/TaylorGreen.cpp.func-sort-c.html b/Release/test_coverage/PDE/CompFlow/Problem/TaylorGreen.cpp.func-sort-c.html index 86fbb00857fe..a570eee0b1a4 100644 --- a/Release/test_coverage/PDE/CompFlow/Problem/TaylorGreen.cpp.func-sort-c.html +++ b/Release/test_coverage/PDE/CompFlow/Problem/TaylorGreen.cpp.func-sort-c.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:26:06 + 2024-07-11 14:48:26 Functions: 4 diff --git a/Release/test_coverage/PDE/CompFlow/Problem/TaylorGreen.cpp.func.html b/Release/test_coverage/PDE/CompFlow/Problem/TaylorGreen.cpp.func.html index 48883a0f21c4..e0cdd322d3f5 100644 --- a/Release/test_coverage/PDE/CompFlow/Problem/TaylorGreen.cpp.func.html +++ b/Release/test_coverage/PDE/CompFlow/Problem/TaylorGreen.cpp.func.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:26:06 + 2024-07-11 14:48:26 Functions: 4 diff --git a/Release/test_coverage/PDE/CompFlow/Problem/TaylorGreen.cpp.gcov.html b/Release/test_coverage/PDE/CompFlow/Problem/TaylorGreen.cpp.gcov.html index 7699d92f44fa..890975544421 100644 --- a/Release/test_coverage/PDE/CompFlow/Problem/TaylorGreen.cpp.gcov.html +++ b/Release/test_coverage/PDE/CompFlow/Problem/TaylorGreen.cpp.gcov.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:26:06 + 2024-07-11 14:48:26 Functions: 4 diff --git a/Release/test_coverage/PDE/CompFlow/Problem/TaylorGreen.hpp.func-sort-c.html b/Release/test_coverage/PDE/CompFlow/Problem/TaylorGreen.hpp.func-sort-c.html index 64090816ed9d..9bff25a509f6 100644 --- a/Release/test_coverage/PDE/CompFlow/Problem/TaylorGreen.hpp.func-sort-c.html +++ b/Release/test_coverage/PDE/CompFlow/Problem/TaylorGreen.hpp.func-sort-c.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:26:06 + 2024-07-11 14:48:26 Functions: 1 diff --git a/Release/test_coverage/PDE/CompFlow/Problem/TaylorGreen.hpp.func.html b/Release/test_coverage/PDE/CompFlow/Problem/TaylorGreen.hpp.func.html index 8f6db4c355a4..68ed5c663412 100644 --- a/Release/test_coverage/PDE/CompFlow/Problem/TaylorGreen.hpp.func.html +++ b/Release/test_coverage/PDE/CompFlow/Problem/TaylorGreen.hpp.func.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:26:06 + 2024-07-11 14:48:26 Functions: 1 diff --git a/Release/test_coverage/PDE/CompFlow/Problem/TaylorGreen.hpp.gcov.html b/Release/test_coverage/PDE/CompFlow/Problem/TaylorGreen.hpp.gcov.html index a71dbd7e951a..b19915e57abb 100644 --- a/Release/test_coverage/PDE/CompFlow/Problem/TaylorGreen.hpp.gcov.html +++ b/Release/test_coverage/PDE/CompFlow/Problem/TaylorGreen.hpp.gcov.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:26:06 + 2024-07-11 14:48:26 Functions: 1 diff --git a/Release/test_coverage/PDE/CompFlow/Problem/UserDefined.cpp.func-sort-c.html b/Release/test_coverage/PDE/CompFlow/Problem/UserDefined.cpp.func-sort-c.html index 9592a8952cc0..1f79784cb5ce 100644 --- a/Release/test_coverage/PDE/CompFlow/Problem/UserDefined.cpp.func-sort-c.html +++ b/Release/test_coverage/PDE/CompFlow/Problem/UserDefined.cpp.func-sort-c.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:26:06 + 2024-07-11 14:48:26 Functions: 2 diff --git a/Release/test_coverage/PDE/CompFlow/Problem/UserDefined.cpp.func.html b/Release/test_coverage/PDE/CompFlow/Problem/UserDefined.cpp.func.html index 422a8ad20cb3..65898c5d9778 100644 --- a/Release/test_coverage/PDE/CompFlow/Problem/UserDefined.cpp.func.html +++ b/Release/test_coverage/PDE/CompFlow/Problem/UserDefined.cpp.func.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:26:06 + 2024-07-11 14:48:26 Functions: 2 diff --git a/Release/test_coverage/PDE/CompFlow/Problem/UserDefined.cpp.gcov.html b/Release/test_coverage/PDE/CompFlow/Problem/UserDefined.cpp.gcov.html index bf09af400938..fd89dc781ac5 100644 --- a/Release/test_coverage/PDE/CompFlow/Problem/UserDefined.cpp.gcov.html +++ b/Release/test_coverage/PDE/CompFlow/Problem/UserDefined.cpp.gcov.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:26:06 + 2024-07-11 14:48:26 Functions: 2 diff --git a/Release/test_coverage/PDE/CompFlow/Problem/UserDefined.hpp.func-sort-c.html b/Release/test_coverage/PDE/CompFlow/Problem/UserDefined.hpp.func-sort-c.html index f0005bc32e12..e3173ce1766e 100644 --- a/Release/test_coverage/PDE/CompFlow/Problem/UserDefined.hpp.func-sort-c.html +++ b/Release/test_coverage/PDE/CompFlow/Problem/UserDefined.hpp.func-sort-c.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:26:06 + 2024-07-11 14:48:26 Functions: 0 diff --git a/Release/test_coverage/PDE/CompFlow/Problem/UserDefined.hpp.func.html b/Release/test_coverage/PDE/CompFlow/Problem/UserDefined.hpp.func.html index f2aabf5a182e..a33bacdbe6d7 100644 --- a/Release/test_coverage/PDE/CompFlow/Problem/UserDefined.hpp.func.html +++ b/Release/test_coverage/PDE/CompFlow/Problem/UserDefined.hpp.func.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:26:06 + 2024-07-11 14:48:26 Functions: 0 diff --git a/Release/test_coverage/PDE/CompFlow/Problem/UserDefined.hpp.gcov.html b/Release/test_coverage/PDE/CompFlow/Problem/UserDefined.hpp.gcov.html index 4a68871dc21e..4b376d7fb8bb 100644 --- a/Release/test_coverage/PDE/CompFlow/Problem/UserDefined.hpp.gcov.html +++ b/Release/test_coverage/PDE/CompFlow/Problem/UserDefined.hpp.gcov.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:26:06 + 2024-07-11 14:48:26 Functions: 0 diff --git a/Release/test_coverage/PDE/CompFlow/Problem/VorticalFlow.cpp.func-sort-c.html b/Release/test_coverage/PDE/CompFlow/Problem/VorticalFlow.cpp.func-sort-c.html index 98e777ae6a9a..99f9415e38ca 100644 --- a/Release/test_coverage/PDE/CompFlow/Problem/VorticalFlow.cpp.func-sort-c.html +++ b/Release/test_coverage/PDE/CompFlow/Problem/VorticalFlow.cpp.func-sort-c.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:26:06 + 2024-07-11 14:48:26 Functions: 4 diff --git a/Release/test_coverage/PDE/CompFlow/Problem/VorticalFlow.cpp.func.html b/Release/test_coverage/PDE/CompFlow/Problem/VorticalFlow.cpp.func.html index 4b773e393adb..708651beb764 100644 --- a/Release/test_coverage/PDE/CompFlow/Problem/VorticalFlow.cpp.func.html +++ b/Release/test_coverage/PDE/CompFlow/Problem/VorticalFlow.cpp.func.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:26:06 + 2024-07-11 14:48:26 Functions: 4 diff --git a/Release/test_coverage/PDE/CompFlow/Problem/VorticalFlow.cpp.gcov.html b/Release/test_coverage/PDE/CompFlow/Problem/VorticalFlow.cpp.gcov.html index 161069cc2459..03e535218eb4 100644 --- a/Release/test_coverage/PDE/CompFlow/Problem/VorticalFlow.cpp.gcov.html +++ b/Release/test_coverage/PDE/CompFlow/Problem/VorticalFlow.cpp.gcov.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:26:06 + 2024-07-11 14:48:26 Functions: 4 diff --git a/Release/test_coverage/PDE/CompFlow/Problem/VorticalFlow.hpp.func-sort-c.html b/Release/test_coverage/PDE/CompFlow/Problem/VorticalFlow.hpp.func-sort-c.html index 48b4fee32a74..2e7e89f77dfa 100644 --- a/Release/test_coverage/PDE/CompFlow/Problem/VorticalFlow.hpp.func-sort-c.html +++ b/Release/test_coverage/PDE/CompFlow/Problem/VorticalFlow.hpp.func-sort-c.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:26:06 + 2024-07-11 14:48:26 Functions: 1 diff --git a/Release/test_coverage/PDE/CompFlow/Problem/VorticalFlow.hpp.func.html b/Release/test_coverage/PDE/CompFlow/Problem/VorticalFlow.hpp.func.html index 75a32d9680ad..09edcda39db2 100644 --- a/Release/test_coverage/PDE/CompFlow/Problem/VorticalFlow.hpp.func.html +++ b/Release/test_coverage/PDE/CompFlow/Problem/VorticalFlow.hpp.func.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:26:06 + 2024-07-11 14:48:26 Functions: 1 diff --git a/Release/test_coverage/PDE/CompFlow/Problem/VorticalFlow.hpp.gcov.html b/Release/test_coverage/PDE/CompFlow/Problem/VorticalFlow.hpp.gcov.html index 4a2a6a96f81e..3d988a37f5b6 100644 --- a/Release/test_coverage/PDE/CompFlow/Problem/VorticalFlow.hpp.gcov.html +++ b/Release/test_coverage/PDE/CompFlow/Problem/VorticalFlow.hpp.gcov.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:26:06 + 2024-07-11 14:48:26 Functions: 1 diff --git a/Release/test_coverage/PDE/CompFlow/Problem/index-sort-b.html b/Release/test_coverage/PDE/CompFlow/Problem/index-sort-b.html index 097ccf80bf2c..8c77930bdd27 100644 --- a/Release/test_coverage/PDE/CompFlow/Problem/index-sort-b.html +++ b/Release/test_coverage/PDE/CompFlow/Problem/index-sort-b.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:26:06 + 2024-07-11 14:48:26 Functions: 42 @@ -226,79 +226,67 @@ 73 / 140 - UserDefined.hpp + ShockDensityWave.hpp -
33.3%33.3%
+
0.0%
- 33.3 % - 1 / 3 + 0.0 % + 0 / 3 0.0 % 0 / 1 - 0 / 0 - RayleighTaylor.hpp + TaylorGreen.hpp
100.0%
100.0 % - 42 / 42 + 5 / 5 100.0 % 1 / 1 - 0 / 0 - TaylorGreen.hpp + RotatedSodShocktube.cpp
100.0%
100.0 % - 5 / 5 + 3 / 3 100.0 % 1 / 1 - 0 / 0 - ShockDensityWave.hpp - -
0.0%
- - 0.0 % - 0 / 3 - 0.0 % - 0 / 1 - - - 0 / 0 - - - VorticalFlow.hpp + SodShocktube.hpp
100.0%
100.0 % - 11 / 11 + 3 / 3 100.0 % 1 / 1 - 0 / 0 - SodShocktube.hpp + VorticalFlow.hpp
100.0%
100.0 % - 3 / 3 + 11 / 11 100.0 % 1 / 1 - 0 / 0 - GaussHumpCompflow.hpp + SedovBlastwave.hpp
66.7%66.7%
@@ -310,31 +298,43 @@ 0 / 0 - NLEnergyGrowth.hpp + SheddingFlow.hpp -
100.0%
+
0.0%
- 100.0 % - 31 / 31 - 100.0 % - 1 / 1 + 0.0 % + 0 / 3 + 0.0 % + 0 / 1 - 0 / 0 - SheddingFlow.hpp + UserDefined.hpp -
0.0%
+
33.3%33.3%
- 0.0 % - 0 / 3 + 33.3 % + 1 / 3 0.0 % 0 / 1 - 0 / 0 - SedovBlastwave.hpp + RayleighTaylor.hpp + +
100.0%
+ + 100.0 % + 42 / 42 + 100.0 % + 1 / 1 + - + 0 / 0 + + + GaussHumpCompflow.hpp
66.7%66.7%
@@ -346,12 +346,12 @@ 0 / 0 - RotatedSodShocktube.cpp + NLEnergyGrowth.hpp
100.0%
100.0 % - 3 / 3 + 31 / 31 100.0 % 1 / 1 - diff --git a/Release/test_coverage/PDE/CompFlow/Problem/index-sort-f.html b/Release/test_coverage/PDE/CompFlow/Problem/index-sort-f.html index 7d601fe17a43..a43e00c4ca8a 100644 --- a/Release/test_coverage/PDE/CompFlow/Problem/index-sort-f.html +++ b/Release/test_coverage/PDE/CompFlow/Problem/index-sort-f.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:26:06 + 2024-07-11 14:48:26 Functions: 42 @@ -82,19 +82,19 @@ Branches Sort by branch coverage - UserDefined.hpp + ShockDensityWave.hpp -
33.3%33.3%
+
0.0%
- 33.3 % - 1 / 3 + 0.0 % + 0 / 3 0.0 % 0 / 1 - 0 / 0 - ShockDensityWave.hpp + SheddingFlow.hpp
0.0%
@@ -106,12 +106,12 @@ 0 / 0 - SheddingFlow.hpp + UserDefined.hpp -
0.0%
+
33.3%33.3%
- 0.0 % - 0 / 3 + 33.3 % + 1 / 3 0.0 % 0 / 1 - @@ -154,16 +154,16 @@ 15 / 50 - SedovBlastwave.cpp + RayleighTaylor.cpp -
46.2%46.2%
+
43.2%43.2%
- 46.2 % - 12 / 26 + 43.2 % + 19 / 44 50.0 % 2 / 4 - 29.6 % - 16 / 54 + 26.3 % + 10 / 38 SodShocktube.cpp @@ -178,67 +178,67 @@ 12 / 38 - RayleighTaylor.cpp + SedovBlastwave.cpp -
43.2%43.2%
+
46.2%46.2%
- 43.2 % - 19 / 44 + 46.2 % + 12 / 26 50.0 % 2 / 4 - 26.3 % - 10 / 38 + 29.6 % + 16 / 54 - RayleighTaylor.hpp + TaylorGreen.hpp
100.0%
100.0 % - 42 / 42 + 5 / 5 100.0 % 1 / 1 - 0 / 0 - TaylorGreen.hpp + RotatedSodShocktube.cpp
100.0%
100.0 % - 5 / 5 + 3 / 3 100.0 % 1 / 1 - 0 / 0 - VorticalFlow.hpp + SodShocktube.hpp
100.0%
100.0 % - 11 / 11 + 3 / 3 100.0 % 1 / 1 - 0 / 0 - SodShocktube.hpp + VorticalFlow.hpp
100.0%
100.0 % - 3 / 3 + 11 / 11 100.0 % 1 / 1 - 0 / 0 - GaussHumpCompflow.hpp + SedovBlastwave.hpp
66.7%66.7%
@@ -250,19 +250,19 @@ 0 / 0 - NLEnergyGrowth.hpp + RayleighTaylor.hpp
100.0%
100.0 % - 31 / 31 + 42 / 42 100.0 % 1 / 1 - 0 / 0 - SedovBlastwave.hpp + GaussHumpCompflow.hpp
66.7%66.7%
@@ -274,12 +274,12 @@ 0 / 0 - RotatedSodShocktube.cpp + NLEnergyGrowth.hpp
100.0%
100.0 % - 3 / 3 + 31 / 31 100.0 % 1 / 1 - @@ -334,28 +334,28 @@ 24 / 52 - FieldOutput.cpp + NLEnergyGrowth.cpp
100.0%
100.0 % - 84 / 84 + 43 / 43 100.0 % 6 / 6 - 52.1 % - 73 / 140 + 47.2 % + 17 / 36 - NLEnergyGrowth.cpp + FieldOutput.cpp
100.0%
100.0 % - 43 / 43 + 84 / 84 100.0 % 6 / 6 - 47.2 % - 17 / 36 + 52.1 % + 73 / 140 diff --git a/Release/test_coverage/PDE/CompFlow/Problem/index-sort-l.html b/Release/test_coverage/PDE/CompFlow/Problem/index-sort-l.html index 1e1d6cb487f7..d4d8485fa32b 100644 --- a/Release/test_coverage/PDE/CompFlow/Problem/index-sort-l.html +++ b/Release/test_coverage/PDE/CompFlow/Problem/index-sort-l.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:26:06 + 2024-07-11 14:48:26 Functions: 42 @@ -178,7 +178,7 @@ 12 / 38 - GaussHumpCompflow.hpp + SedovBlastwave.hpp
66.7%66.7%
@@ -190,7 +190,7 @@ 0 / 0 - SedovBlastwave.hpp + GaussHumpCompflow.hpp
66.7%66.7%
@@ -226,7 +226,7 @@ 15 / 50 - SodShocktube.hpp + RotatedSodShocktube.cpp
100.0%
@@ -238,7 +238,7 @@ 0 / 0 - RotatedSodShocktube.cpp + SodShocktube.hpp
100.0%
diff --git a/Release/test_coverage/PDE/CompFlow/Problem/index.html b/Release/test_coverage/PDE/CompFlow/Problem/index.html index 1c56dce531ab..7958c43913e0 100644 --- a/Release/test_coverage/PDE/CompFlow/Problem/index.html +++ b/Release/test_coverage/PDE/CompFlow/Problem/index.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:26:06 + 2024-07-11 14:48:26 Functions: 42 diff --git a/Release/test_coverage/PDE/CompFlow/RiemannChoice.hpp.func-sort-c.html b/Release/test_coverage/PDE/CompFlow/RiemannChoice.hpp.func-sort-c.html index d56a7f605128..e091d31b68e7 100644 --- a/Release/test_coverage/PDE/CompFlow/RiemannChoice.hpp.func-sort-c.html +++ b/Release/test_coverage/PDE/CompFlow/RiemannChoice.hpp.func-sort-c.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:26:06 + 2024-07-11 14:48:26 Functions: 1 diff --git a/Release/test_coverage/PDE/CompFlow/RiemannChoice.hpp.func.html b/Release/test_coverage/PDE/CompFlow/RiemannChoice.hpp.func.html index 08b3f26e8dfc..5f8fa1c23c65 100644 --- a/Release/test_coverage/PDE/CompFlow/RiemannChoice.hpp.func.html +++ b/Release/test_coverage/PDE/CompFlow/RiemannChoice.hpp.func.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:26:06 + 2024-07-11 14:48:26 Functions: 1 diff --git a/Release/test_coverage/PDE/CompFlow/RiemannChoice.hpp.gcov.html b/Release/test_coverage/PDE/CompFlow/RiemannChoice.hpp.gcov.html index f411536cd361..e57d36f09990 100644 --- a/Release/test_coverage/PDE/CompFlow/RiemannChoice.hpp.gcov.html +++ b/Release/test_coverage/PDE/CompFlow/RiemannChoice.hpp.gcov.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:26:06 + 2024-07-11 14:48:26 Functions: 1 diff --git a/Release/test_coverage/PDE/CompFlow/index-sort-b.html b/Release/test_coverage/PDE/CompFlow/index-sort-b.html index 06867b676b41..711dcbd19813 100644 --- a/Release/test_coverage/PDE/CompFlow/index-sort-b.html +++ b/Release/test_coverage/PDE/CompFlow/index-sort-b.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:26:06 + 2024-07-11 14:48:26 Functions: 169 diff --git a/Release/test_coverage/PDE/CompFlow/index-sort-f.html b/Release/test_coverage/PDE/CompFlow/index-sort-f.html index 036736279d8e..0a625135be30 100644 --- a/Release/test_coverage/PDE/CompFlow/index-sort-f.html +++ b/Release/test_coverage/PDE/CompFlow/index-sort-f.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:26:06 + 2024-07-11 14:48:26 Functions: 169 diff --git a/Release/test_coverage/PDE/CompFlow/index-sort-l.html b/Release/test_coverage/PDE/CompFlow/index-sort-l.html index d01962b975ee..927b87da7bde 100644 --- a/Release/test_coverage/PDE/CompFlow/index-sort-l.html +++ b/Release/test_coverage/PDE/CompFlow/index-sort-l.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:26:06 + 2024-07-11 14:48:26 Functions: 169 diff --git a/Release/test_coverage/PDE/CompFlow/index.html b/Release/test_coverage/PDE/CompFlow/index.html index c3fcab761d2b..0910db56d149 100644 --- a/Release/test_coverage/PDE/CompFlow/index.html +++ b/Release/test_coverage/PDE/CompFlow/index.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:26:06 + 2024-07-11 14:48:26 Functions: 169 diff --git a/Release/test_coverage/PDE/ConfigureCompFlow.cpp.func-sort-c.html b/Release/test_coverage/PDE/ConfigureCompFlow.cpp.func-sort-c.html index db56b675c29b..b9152eb854ae 100644 --- a/Release/test_coverage/PDE/ConfigureCompFlow.cpp.func-sort-c.html +++ b/Release/test_coverage/PDE/ConfigureCompFlow.cpp.func-sort-c.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:26:06 + 2024-07-11 14:48:26 Functions: 2 diff --git a/Release/test_coverage/PDE/ConfigureCompFlow.cpp.func.html b/Release/test_coverage/PDE/ConfigureCompFlow.cpp.func.html index 920ab6967b82..5bd11363c34c 100644 --- a/Release/test_coverage/PDE/ConfigureCompFlow.cpp.func.html +++ b/Release/test_coverage/PDE/ConfigureCompFlow.cpp.func.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:26:06 + 2024-07-11 14:48:26 Functions: 2 diff --git a/Release/test_coverage/PDE/ConfigureCompFlow.cpp.gcov.html b/Release/test_coverage/PDE/ConfigureCompFlow.cpp.gcov.html index 52526dc31ece..ae3f06daf9af 100644 --- a/Release/test_coverage/PDE/ConfigureCompFlow.cpp.gcov.html +++ b/Release/test_coverage/PDE/ConfigureCompFlow.cpp.gcov.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:26:06 + 2024-07-11 14:48:26 Functions: 2 diff --git a/Release/test_coverage/PDE/ConfigureCompFlow.hpp.func-sort-c.html b/Release/test_coverage/PDE/ConfigureCompFlow.hpp.func-sort-c.html index 2766cdc0c44f..9f9f375b3aeb 100644 --- a/Release/test_coverage/PDE/ConfigureCompFlow.hpp.func-sort-c.html +++ b/Release/test_coverage/PDE/ConfigureCompFlow.hpp.func-sort-c.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:26:06 + 2024-07-11 14:48:26 Functions: 6 diff --git a/Release/test_coverage/PDE/ConfigureCompFlow.hpp.func.html b/Release/test_coverage/PDE/ConfigureCompFlow.hpp.func.html index 1425fdd1ac0e..40ea0d395819 100644 --- a/Release/test_coverage/PDE/ConfigureCompFlow.hpp.func.html +++ b/Release/test_coverage/PDE/ConfigureCompFlow.hpp.func.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:26:06 + 2024-07-11 14:48:26 Functions: 6 diff --git a/Release/test_coverage/PDE/ConfigureCompFlow.hpp.gcov.html b/Release/test_coverage/PDE/ConfigureCompFlow.hpp.gcov.html index 841031600c4e..336eae4a4251 100644 --- a/Release/test_coverage/PDE/ConfigureCompFlow.hpp.gcov.html +++ b/Release/test_coverage/PDE/ConfigureCompFlow.hpp.gcov.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:26:06 + 2024-07-11 14:48:26 Functions: 6 diff --git a/Release/test_coverage/PDE/ConfigureMultiMat.cpp.func-sort-c.html b/Release/test_coverage/PDE/ConfigureMultiMat.cpp.func-sort-c.html index 4ea8eed9b04f..e4e40191ae8b 100644 --- a/Release/test_coverage/PDE/ConfigureMultiMat.cpp.func-sort-c.html +++ b/Release/test_coverage/PDE/ConfigureMultiMat.cpp.func-sort-c.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:26:06 + 2024-07-11 14:48:26 Functions: 2 diff --git a/Release/test_coverage/PDE/ConfigureMultiMat.cpp.func.html b/Release/test_coverage/PDE/ConfigureMultiMat.cpp.func.html index ebfb057a9936..f45bcf887d39 100644 --- a/Release/test_coverage/PDE/ConfigureMultiMat.cpp.func.html +++ b/Release/test_coverage/PDE/ConfigureMultiMat.cpp.func.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:26:06 + 2024-07-11 14:48:26 Functions: 2 diff --git a/Release/test_coverage/PDE/ConfigureMultiMat.cpp.gcov.html b/Release/test_coverage/PDE/ConfigureMultiMat.cpp.gcov.html index bb3c6c71e435..bd8d48213919 100644 --- a/Release/test_coverage/PDE/ConfigureMultiMat.cpp.gcov.html +++ b/Release/test_coverage/PDE/ConfigureMultiMat.cpp.gcov.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:26:06 + 2024-07-11 14:48:26 Functions: 2 diff --git a/Release/test_coverage/PDE/ConfigureMultiMat.hpp.func-sort-c.html b/Release/test_coverage/PDE/ConfigureMultiMat.hpp.func-sort-c.html index f161744010ea..823efc980c5b 100644 --- a/Release/test_coverage/PDE/ConfigureMultiMat.hpp.func-sort-c.html +++ b/Release/test_coverage/PDE/ConfigureMultiMat.hpp.func-sort-c.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:26:06 + 2024-07-11 14:48:26 Functions: 7 diff --git a/Release/test_coverage/PDE/ConfigureMultiMat.hpp.func.html b/Release/test_coverage/PDE/ConfigureMultiMat.hpp.func.html index fff481bb87eb..605657d87f7e 100644 --- a/Release/test_coverage/PDE/ConfigureMultiMat.hpp.func.html +++ b/Release/test_coverage/PDE/ConfigureMultiMat.hpp.func.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:26:06 + 2024-07-11 14:48:26 Functions: 7 diff --git a/Release/test_coverage/PDE/ConfigureMultiMat.hpp.gcov.html b/Release/test_coverage/PDE/ConfigureMultiMat.hpp.gcov.html index 7146bc58cf01..ddc6f736fd4c 100644 --- a/Release/test_coverage/PDE/ConfigureMultiMat.hpp.gcov.html +++ b/Release/test_coverage/PDE/ConfigureMultiMat.hpp.gcov.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:26:06 + 2024-07-11 14:48:26 Functions: 7 diff --git a/Release/test_coverage/PDE/ConfigureTransport.cpp.func-sort-c.html b/Release/test_coverage/PDE/ConfigureTransport.cpp.func-sort-c.html index c7e1ad15d097..8817331855bb 100644 --- a/Release/test_coverage/PDE/ConfigureTransport.cpp.func-sort-c.html +++ b/Release/test_coverage/PDE/ConfigureTransport.cpp.func-sort-c.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:26:06 + 2024-07-11 14:48:26 Functions: 2 diff --git a/Release/test_coverage/PDE/ConfigureTransport.cpp.func.html b/Release/test_coverage/PDE/ConfigureTransport.cpp.func.html index f3bdbced539a..528705b4b2ca 100644 --- a/Release/test_coverage/PDE/ConfigureTransport.cpp.func.html +++ b/Release/test_coverage/PDE/ConfigureTransport.cpp.func.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:26:06 + 2024-07-11 14:48:26 Functions: 2 diff --git a/Release/test_coverage/PDE/ConfigureTransport.cpp.gcov.html b/Release/test_coverage/PDE/ConfigureTransport.cpp.gcov.html index 1f950347b5a9..8434fb25860d 100644 --- a/Release/test_coverage/PDE/ConfigureTransport.cpp.gcov.html +++ b/Release/test_coverage/PDE/ConfigureTransport.cpp.gcov.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:26:06 + 2024-07-11 14:48:26 Functions: 2 diff --git a/Release/test_coverage/PDE/ConfigureTransport.hpp.func-sort-c.html b/Release/test_coverage/PDE/ConfigureTransport.hpp.func-sort-c.html index 8bce99741c94..e1140c981a4f 100644 --- a/Release/test_coverage/PDE/ConfigureTransport.hpp.func-sort-c.html +++ b/Release/test_coverage/PDE/ConfigureTransport.hpp.func-sort-c.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:26:06 + 2024-07-11 14:48:26 Functions: 0 diff --git a/Release/test_coverage/PDE/ConfigureTransport.hpp.func.html b/Release/test_coverage/PDE/ConfigureTransport.hpp.func.html index 1cf188f167c7..30c4de9fddee 100644 --- a/Release/test_coverage/PDE/ConfigureTransport.hpp.func.html +++ b/Release/test_coverage/PDE/ConfigureTransport.hpp.func.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:26:06 + 2024-07-11 14:48:26 Functions: 0 diff --git a/Release/test_coverage/PDE/ConfigureTransport.hpp.gcov.html b/Release/test_coverage/PDE/ConfigureTransport.hpp.gcov.html index b974cb3ae848..850c9837eb46 100644 --- a/Release/test_coverage/PDE/ConfigureTransport.hpp.gcov.html +++ b/Release/test_coverage/PDE/ConfigureTransport.hpp.gcov.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:26:06 + 2024-07-11 14:48:26 Functions: 0 diff --git a/Release/test_coverage/PDE/DGPDE.cpp.func-sort-c.html b/Release/test_coverage/PDE/DGPDE.cpp.func-sort-c.html index 312b9ce904b9..d65b0baa9bbd 100644 --- a/Release/test_coverage/PDE/DGPDE.cpp.func-sort-c.html +++ b/Release/test_coverage/PDE/DGPDE.cpp.func-sort-c.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:26:06 + 2024-07-11 14:48:26 Functions: 0 diff --git a/Release/test_coverage/PDE/DGPDE.cpp.func.html b/Release/test_coverage/PDE/DGPDE.cpp.func.html index 5127927f6d16..0853153def95 100644 --- a/Release/test_coverage/PDE/DGPDE.cpp.func.html +++ b/Release/test_coverage/PDE/DGPDE.cpp.func.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:26:06 + 2024-07-11 14:48:26 Functions: 0 diff --git a/Release/test_coverage/PDE/DGPDE.cpp.gcov.html b/Release/test_coverage/PDE/DGPDE.cpp.gcov.html index 5b88a8952050..97956863fa51 100644 --- a/Release/test_coverage/PDE/DGPDE.cpp.gcov.html +++ b/Release/test_coverage/PDE/DGPDE.cpp.gcov.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:26:06 + 2024-07-11 14:48:26 Functions: 0 diff --git a/Release/test_coverage/PDE/DGPDE.hpp.func-sort-c.html b/Release/test_coverage/PDE/DGPDE.hpp.func-sort-c.html index f427497fca6f..82949682274d 100644 --- a/Release/test_coverage/PDE/DGPDE.hpp.func-sort-c.html +++ b/Release/test_coverage/PDE/DGPDE.hpp.func-sort-c.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:26:06 + 2024-07-11 14:48:26 Functions: 295 diff --git a/Release/test_coverage/PDE/DGPDE.hpp.func.html b/Release/test_coverage/PDE/DGPDE.hpp.func.html index 458e59e21e80..a25bcacdad64 100644 --- a/Release/test_coverage/PDE/DGPDE.hpp.func.html +++ b/Release/test_coverage/PDE/DGPDE.hpp.func.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:26:06 + 2024-07-11 14:48:26 Functions: 295 diff --git a/Release/test_coverage/PDE/DGPDE.hpp.gcov.html b/Release/test_coverage/PDE/DGPDE.hpp.gcov.html index f3de980f5db8..f0ca21b20f1a 100644 --- a/Release/test_coverage/PDE/DGPDE.hpp.gcov.html +++ b/Release/test_coverage/PDE/DGPDE.hpp.gcov.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:26:06 + 2024-07-11 14:48:26 Functions: 295 diff --git a/Release/test_coverage/PDE/EoS/EOS.cpp.func-sort-c.html b/Release/test_coverage/PDE/EoS/EOS.cpp.func-sort-c.html index 8d52659c0f47..748536727a5b 100644 --- a/Release/test_coverage/PDE/EoS/EOS.cpp.func-sort-c.html +++ b/Release/test_coverage/PDE/EoS/EOS.cpp.func-sort-c.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:26:06 + 2024-07-11 14:48:26 Functions: 1 diff --git a/Release/test_coverage/PDE/EoS/EOS.cpp.func.html b/Release/test_coverage/PDE/EoS/EOS.cpp.func.html index 4ea2ea4994b2..c41cbb6ac3f1 100644 --- a/Release/test_coverage/PDE/EoS/EOS.cpp.func.html +++ b/Release/test_coverage/PDE/EoS/EOS.cpp.func.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:26:06 + 2024-07-11 14:48:26 Functions: 1 diff --git a/Release/test_coverage/PDE/EoS/EOS.cpp.gcov.html b/Release/test_coverage/PDE/EoS/EOS.cpp.gcov.html index 44d1aaaa4d49..3756fec49f6f 100644 --- a/Release/test_coverage/PDE/EoS/EOS.cpp.gcov.html +++ b/Release/test_coverage/PDE/EoS/EOS.cpp.gcov.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:26:06 + 2024-07-11 14:48:26 Functions: 1 diff --git a/Release/test_coverage/PDE/EoS/EOS.hpp.func-sort-c.html b/Release/test_coverage/PDE/EoS/EOS.hpp.func-sort-c.html index d4b6ab25417f..75b65af069b1 100644 --- a/Release/test_coverage/PDE/EoS/EOS.hpp.func-sort-c.html +++ b/Release/test_coverage/PDE/EoS/EOS.hpp.func-sort-c.html @@ -33,12 +33,12 @@ Date: - 2024-07-10 11:26:06 + 2024-07-11 14:48:26 Functions: - 27 + 28 96 - 28.1 % + 29.2 % Legend: @@ -52,7 +52,7 @@ Branches: - 219 + 218 2020 10.8 % @@ -111,10 +111,6 @@ double inciter::EOS::compute<inciter::EOS::soundspeed, double const&, double&, double&, unsigned long&>(double const&, double&, double&, unsigned long&) const::{lambda(auto:1 const&)#1}::operator()<inciter::JWL>(inciter::JWL const&) const 0 - - double inciter::EOS::compute<inciter::EOS::soundspeed, double const&, double&, double&, unsigned long&, std::array<std::array<double, 3ul>, 3ul>&>(double const&, double&, double&, unsigned long&, std::array<std::array<double, 3ul>, 3ul>&) const::{lambda(auto:1 const&)#1}::operator()<inciter::StiffenedGas>(inciter::StiffenedGas const&) const - 0 - double inciter::EOS::compute<inciter::EOS::soundspeed, double const&, double&, double&, unsigned long&, std::array<std::array<double, 3ul>, 3ul>&>(double const&, double&, double&, unsigned long&, std::array<std::array<double, 3ul>, 3ul>&) const::{lambda(auto:1 const&)#1}::operator()<inciter::SmallShearSolid>(inciter::SmallShearSolid const&) const 0 @@ -399,6 +395,10 @@ double inciter::EOS::compute<inciter::EOS::totalenergy, double&, double, double, double, double const&>(double&, double&&, double&&, double&&, double const&) const::{lambda(auto:1 const&)#1}::operator()<inciter::StiffenedGas>(inciter::StiffenedGas const&) const 547066 + + double inciter::EOS::compute<inciter::EOS::soundspeed, double const&, double&, double&, unsigned long&, std::array<std::array<double, 3ul>, 3ul>&>(double const&, double&, double&, unsigned long&, std::array<std::array<double, 3ul>, 3ul>&) const::{lambda(auto:1 const&)#1}::operator()<inciter::StiffenedGas>(inciter::StiffenedGas const&) const + 686000 + double inciter::EOS::compute<inciter::EOS::soundspeed, double&, double&, double&, unsigned long&, std::array<std::array<double, 3ul>, 3ul>&>(double&, double&, double&, unsigned long&, std::array<std::array<double, 3ul>, 3ul>&) const::{lambda(auto:1 const&)#1}::operator()<inciter::StiffenedGas>(inciter::StiffenedGas const&) const 863875 @@ -441,7 +441,7 @@ double inciter::EOS::compute<inciter::EOS::soundspeed, double const&, double&, double&, unsigned long&>(double const&, double&, double&, unsigned long&) const::{lambda(auto:1 const&)#1}::operator()<inciter::StiffenedGas>(inciter::StiffenedGas const&) const - 38295696 + 37609696 double inciter::EOS::compute<inciter::EOS::pressure, double&, double&, double&, double&, double const&>(double&, double&, double&, double&, double const&) const::{lambda(auto:1 const&)#1}::operator()<inciter::StiffenedGas>(inciter::StiffenedGas const&) const diff --git a/Release/test_coverage/PDE/EoS/EOS.hpp.func.html b/Release/test_coverage/PDE/EoS/EOS.hpp.func.html index c02090dfcc57..60e32d972aa7 100644 --- a/Release/test_coverage/PDE/EoS/EOS.hpp.func.html +++ b/Release/test_coverage/PDE/EoS/EOS.hpp.func.html @@ -33,12 +33,12 @@ Date: - 2024-07-10 11:26:06 + 2024-07-11 14:48:26 Functions: - 27 + 28 96 - 28.1 % + 29.2 % Legend: @@ -52,7 +52,7 @@ Branches: - 219 + 218 2020 10.8 % @@ -109,7 +109,7 @@ double inciter::EOS::compute<inciter::EOS::soundspeed, double const&, double&, double&, unsigned long&>(double const&, double&, double&, unsigned long&) const::{lambda(auto:1 const&)#1}::operator()<inciter::StiffenedGas>(inciter::StiffenedGas const&) const - 38295696 + 37609696 double inciter::EOS::compute<inciter::EOS::soundspeed, double const&, double&, double&, unsigned long&>(double const&, double&, double&, unsigned long&) const::{lambda(auto:1 const&)#1}::operator()<inciter::SmallShearSolid>(inciter::SmallShearSolid const&) const @@ -121,7 +121,7 @@ double inciter::EOS::compute<inciter::EOS::soundspeed, double const&, double&, double&, unsigned long&, std::array<std::array<double, 3ul>, 3ul>&>(double const&, double&, double&, unsigned long&, std::array<std::array<double, 3ul>, 3ul>&) const::{lambda(auto:1 const&)#1}::operator()<inciter::StiffenedGas>(inciter::StiffenedGas const&) const - 0 + 686000 double inciter::EOS::compute<inciter::EOS::soundspeed, double const&, double&, double&, unsigned long&, std::array<std::array<double, 3ul>, 3ul>&>(double const&, double&, double&, unsigned long&, std::array<std::array<double, 3ul>, 3ul>&) const::{lambda(auto:1 const&)#1}::operator()<inciter::SmallShearSolid>(inciter::SmallShearSolid const&) const diff --git a/Release/test_coverage/PDE/EoS/EOS.hpp.gcov.html b/Release/test_coverage/PDE/EoS/EOS.hpp.gcov.html index 3c2ffe2bbf07..2fd67e319660 100644 --- a/Release/test_coverage/PDE/EoS/EOS.hpp.gcov.html +++ b/Release/test_coverage/PDE/EoS/EOS.hpp.gcov.html @@ -33,12 +33,12 @@ Date: - 2024-07-10 11:26:06 + 2024-07-11 14:48:26 Functions: - 27 + 28 96 - 28.1 % + 29.2 % Legend: @@ -52,7 +52,7 @@ Branches: - 219 + 218 2020 10.8 % @@ -136,8 +136,8 @@ 62 : : //! EOS vector and is thus equivalent to mat_blk[imat].Fn(...). 63 : : template< typename Fn, typename... Args > 64 : : tk::real compute( Args&&... args ) const { - 65 [ + + ][ + + ]: 828372982 : return std::visit( [&]( const auto& m )-> tk::real { - [ + + ][ + + ] + 65 [ + + ][ + + ]: 828372982 : return std::visit( [&]( const auto& m )-> tk::real { + [ + + ][ + + ] [ + + ][ + + ] [ + - ][ + - ] [ + + ][ + + ] @@ -160,7 +160,7 @@ [ - - ][ - - ] [ - - ][ - - ] [ - - ][ - - ] - [ + + ][ + - ] + [ + - ][ + - ] [ - - ][ + - ] [ - - ][ - - ] [ - - ][ - - ] @@ -313,9 +313,9 @@ [ - - ][ - - ] [ - - ][ + - ] [ + + ][ + - ] - [ + + ][ - - ] + [ + + ][ - - ] [ + - ][ + + ] - [ + - ][ + + ] + [ + - ][ + + ] [ - - ][ - - ] [ - - ][ - - ] [ - - ][ - - ] @@ -323,9 +323,9 @@ [ - - ][ - - ] [ - - ][ + - ] [ + + ][ + - ] - [ + + ][ - - ] + [ + + ][ - - ] [ + - ][ + + ] - [ + - ][ + + ] + [ + - ][ + + ] [ - - ][ - - ] [ - - ][ - - ] [ - - ][ - - ] @@ -344,7 +344,7 @@ [ + + ][ + - ] [ + - ][ + - ] [ + - ][ + - ] - [ + + ] + [ + + ] 66 : : if constexpr( std::is_same_v< Fn, density > ) 67 : 2169502 : return m.density( std::forward< Args >( args )... ); 68 : : @@ -372,7 +372,7 @@ 90 : : else if constexpr( std::is_same_v< Fn, refPressure > ) 91 : : return m.refPressure( std::forward< Args >( args )... ); 92 [ + - ][ + - ]: 466328236 : }, m_material ); - [ + - ][ + - ] + [ + - ][ + - ] [ + - ][ + - ] [ + - ][ + - ] [ + - ][ + - ] diff --git a/Release/test_coverage/PDE/EoS/GetMatProp.hpp.func-sort-c.html b/Release/test_coverage/PDE/EoS/GetMatProp.hpp.func-sort-c.html index cc93c0efd96d..995b544f4fb1 100644 --- a/Release/test_coverage/PDE/EoS/GetMatProp.hpp.func-sort-c.html +++ b/Release/test_coverage/PDE/EoS/GetMatProp.hpp.func-sort-c.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:26:06 + 2024-07-11 14:48:26 Functions: 3 diff --git a/Release/test_coverage/PDE/EoS/GetMatProp.hpp.func.html b/Release/test_coverage/PDE/EoS/GetMatProp.hpp.func.html index cd5651241580..51de252316f5 100644 --- a/Release/test_coverage/PDE/EoS/GetMatProp.hpp.func.html +++ b/Release/test_coverage/PDE/EoS/GetMatProp.hpp.func.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:26:06 + 2024-07-11 14:48:26 Functions: 3 diff --git a/Release/test_coverage/PDE/EoS/GetMatProp.hpp.gcov.html b/Release/test_coverage/PDE/EoS/GetMatProp.hpp.gcov.html index d49054caa469..d31b2e43f78c 100644 --- a/Release/test_coverage/PDE/EoS/GetMatProp.hpp.gcov.html +++ b/Release/test_coverage/PDE/EoS/GetMatProp.hpp.gcov.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:26:06 + 2024-07-11 14:48:26 Functions: 3 diff --git a/Release/test_coverage/PDE/EoS/JWL.cpp.func-sort-c.html b/Release/test_coverage/PDE/EoS/JWL.cpp.func-sort-c.html index 584347dff7d8..2863a86b9287 100644 --- a/Release/test_coverage/PDE/EoS/JWL.cpp.func-sort-c.html +++ b/Release/test_coverage/PDE/EoS/JWL.cpp.func-sort-c.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:26:06 + 2024-07-11 14:48:26 Functions: 0 diff --git a/Release/test_coverage/PDE/EoS/JWL.cpp.func.html b/Release/test_coverage/PDE/EoS/JWL.cpp.func.html index 7faa9bf4fd19..5a09ea90675d 100644 --- a/Release/test_coverage/PDE/EoS/JWL.cpp.func.html +++ b/Release/test_coverage/PDE/EoS/JWL.cpp.func.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:26:06 + 2024-07-11 14:48:26 Functions: 0 diff --git a/Release/test_coverage/PDE/EoS/JWL.cpp.gcov.html b/Release/test_coverage/PDE/EoS/JWL.cpp.gcov.html index 43a53e2bc995..22ac9d963688 100644 --- a/Release/test_coverage/PDE/EoS/JWL.cpp.gcov.html +++ b/Release/test_coverage/PDE/EoS/JWL.cpp.gcov.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:26:06 + 2024-07-11 14:48:26 Functions: 0 diff --git a/Release/test_coverage/PDE/EoS/SmallShearSolid.cpp.func-sort-c.html b/Release/test_coverage/PDE/EoS/SmallShearSolid.cpp.func-sort-c.html index 9b7c45918182..aff5b5c56f5d 100644 --- a/Release/test_coverage/PDE/EoS/SmallShearSolid.cpp.func-sort-c.html +++ b/Release/test_coverage/PDE/EoS/SmallShearSolid.cpp.func-sort-c.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:26:06 + 2024-07-11 14:48:26 Functions: 0 diff --git a/Release/test_coverage/PDE/EoS/SmallShearSolid.cpp.func.html b/Release/test_coverage/PDE/EoS/SmallShearSolid.cpp.func.html index 76fa96aed7aa..747498ad17f2 100644 --- a/Release/test_coverage/PDE/EoS/SmallShearSolid.cpp.func.html +++ b/Release/test_coverage/PDE/EoS/SmallShearSolid.cpp.func.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:26:06 + 2024-07-11 14:48:26 Functions: 0 diff --git a/Release/test_coverage/PDE/EoS/SmallShearSolid.cpp.gcov.html b/Release/test_coverage/PDE/EoS/SmallShearSolid.cpp.gcov.html index d5268a7be138..9943d593d30b 100644 --- a/Release/test_coverage/PDE/EoS/SmallShearSolid.cpp.gcov.html +++ b/Release/test_coverage/PDE/EoS/SmallShearSolid.cpp.gcov.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:26:06 + 2024-07-11 14:48:26 Functions: 0 diff --git a/Release/test_coverage/PDE/EoS/StiffenedGas.cpp.func-sort-c.html b/Release/test_coverage/PDE/EoS/StiffenedGas.cpp.func-sort-c.html index 157e780fe7f3..24c92cd5ea8c 100644 --- a/Release/test_coverage/PDE/EoS/StiffenedGas.cpp.func-sort-c.html +++ b/Release/test_coverage/PDE/EoS/StiffenedGas.cpp.func-sort-c.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:26:06 + 2024-07-11 14:48:26 Functions: 7 diff --git a/Release/test_coverage/PDE/EoS/StiffenedGas.cpp.func.html b/Release/test_coverage/PDE/EoS/StiffenedGas.cpp.func.html index 47140a8e4798..e07db757e38a 100644 --- a/Release/test_coverage/PDE/EoS/StiffenedGas.cpp.func.html +++ b/Release/test_coverage/PDE/EoS/StiffenedGas.cpp.func.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:26:06 + 2024-07-11 14:48:26 Functions: 7 diff --git a/Release/test_coverage/PDE/EoS/StiffenedGas.cpp.gcov.html b/Release/test_coverage/PDE/EoS/StiffenedGas.cpp.gcov.html index 255df429f22f..c291ac28e73c 100644 --- a/Release/test_coverage/PDE/EoS/StiffenedGas.cpp.gcov.html +++ b/Release/test_coverage/PDE/EoS/StiffenedGas.cpp.gcov.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:26:06 + 2024-07-11 14:48:26 Functions: 7 diff --git a/Release/test_coverage/PDE/EoS/index-sort-b.html b/Release/test_coverage/PDE/EoS/index-sort-b.html index 6b3aefaf4ad0..5b4751949e21 100644 --- a/Release/test_coverage/PDE/EoS/index-sort-b.html +++ b/Release/test_coverage/PDE/EoS/index-sort-b.html @@ -33,12 +33,12 @@ Date: - 2024-07-10 11:26:06 + 2024-07-11 14:48:26 Functions: - 38 + 39 142 - 26.8 % + 27.5 % Legend: @@ -49,7 +49,7 @@ Branches: - 228 + 227 2502 9.1 % @@ -136,10 +136,10 @@ 72.7 % 8 / 11 - 28.1 % - 27 / 96 + 29.2 % + 28 / 96 10.8 % - 219 / 2020 + 218 / 2020 GetMatProp.hpp diff --git a/Release/test_coverage/PDE/EoS/index-sort-f.html b/Release/test_coverage/PDE/EoS/index-sort-f.html index 0370e7a56202..2229dccf2bb4 100644 --- a/Release/test_coverage/PDE/EoS/index-sort-f.html +++ b/Release/test_coverage/PDE/EoS/index-sort-f.html @@ -33,12 +33,12 @@ Date: - 2024-07-10 11:26:06 + 2024-07-11 14:48:26 Functions: - 38 + 39 142 - 26.8 % + 27.5 % Legend: @@ -49,7 +49,7 @@ Branches: - 228 + 227 2502 9.1 % @@ -124,10 +124,10 @@ 72.7 % 8 / 11 - 28.1 % - 27 / 96 + 29.2 % + 28 / 96 10.8 % - 219 / 2020 + 218 / 2020 StiffenedGas.cpp diff --git a/Release/test_coverage/PDE/EoS/index-sort-l.html b/Release/test_coverage/PDE/EoS/index-sort-l.html index a11cf536a9d9..c3784f4c3559 100644 --- a/Release/test_coverage/PDE/EoS/index-sort-l.html +++ b/Release/test_coverage/PDE/EoS/index-sort-l.html @@ -33,12 +33,12 @@ Date: - 2024-07-10 11:26:06 + 2024-07-11 14:48:26 Functions: - 38 + 39 142 - 26.8 % + 27.5 % Legend: @@ -49,7 +49,7 @@ Branches: - 228 + 227 2502 9.1 % @@ -124,10 +124,10 @@ 72.7 % 8 / 11 - 28.1 % - 27 / 96 + 29.2 % + 28 / 96 10.8 % - 219 / 2020 + 218 / 2020 StiffenedGas.cpp diff --git a/Release/test_coverage/PDE/EoS/index.html b/Release/test_coverage/PDE/EoS/index.html index 911ea6c71cc6..e23ce4f8c56d 100644 --- a/Release/test_coverage/PDE/EoS/index.html +++ b/Release/test_coverage/PDE/EoS/index.html @@ -33,12 +33,12 @@ Date: - 2024-07-10 11:26:06 + 2024-07-11 14:48:26 Functions: - 38 + 39 142 - 26.8 % + 27.5 % Legend: @@ -49,7 +49,7 @@ Branches: - 228 + 227 2502 9.1 % @@ -100,10 +100,10 @@ 72.7 % 8 / 11 - 28.1 % - 27 / 96 + 29.2 % + 28 / 96 10.8 % - 219 / 2020 + 218 / 2020 GetMatProp.hpp diff --git a/Release/test_coverage/PDE/FVPDE.hpp.func-sort-c.html b/Release/test_coverage/PDE/FVPDE.hpp.func-sort-c.html index 2711bb9552ad..0136d3a4660f 100644 --- a/Release/test_coverage/PDE/FVPDE.hpp.func-sort-c.html +++ b/Release/test_coverage/PDE/FVPDE.hpp.func-sort-c.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:26:06 + 2024-07-11 14:48:26 Functions: 43 diff --git a/Release/test_coverage/PDE/FVPDE.hpp.func.html b/Release/test_coverage/PDE/FVPDE.hpp.func.html index b5e5fcea801e..8ba2118b92dc 100644 --- a/Release/test_coverage/PDE/FVPDE.hpp.func.html +++ b/Release/test_coverage/PDE/FVPDE.hpp.func.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:26:06 + 2024-07-11 14:48:26 Functions: 43 diff --git a/Release/test_coverage/PDE/FVPDE.hpp.gcov.html b/Release/test_coverage/PDE/FVPDE.hpp.gcov.html index b1764fe39831..aa8db5a08eee 100644 --- a/Release/test_coverage/PDE/FVPDE.hpp.gcov.html +++ b/Release/test_coverage/PDE/FVPDE.hpp.gcov.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:26:06 + 2024-07-11 14:48:26 Functions: 43 diff --git a/Release/test_coverage/PDE/Integrate/Basis.cpp.func-sort-c.html b/Release/test_coverage/PDE/Integrate/Basis.cpp.func-sort-c.html index cc6eeef5acdb..c6e19b26894e 100644 --- a/Release/test_coverage/PDE/Integrate/Basis.cpp.func-sort-c.html +++ b/Release/test_coverage/PDE/Integrate/Basis.cpp.func-sort-c.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:26:06 + 2024-07-11 14:48:26 Functions: 10 diff --git a/Release/test_coverage/PDE/Integrate/Basis.cpp.func.html b/Release/test_coverage/PDE/Integrate/Basis.cpp.func.html index a3796410deb2..93344345bc65 100644 --- a/Release/test_coverage/PDE/Integrate/Basis.cpp.func.html +++ b/Release/test_coverage/PDE/Integrate/Basis.cpp.func.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:26:06 + 2024-07-11 14:48:26 Functions: 10 diff --git a/Release/test_coverage/PDE/Integrate/Basis.cpp.gcov.html b/Release/test_coverage/PDE/Integrate/Basis.cpp.gcov.html index cefe2d201274..5c770647cef7 100644 --- a/Release/test_coverage/PDE/Integrate/Basis.cpp.gcov.html +++ b/Release/test_coverage/PDE/Integrate/Basis.cpp.gcov.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:26:06 + 2024-07-11 14:48:26 Functions: 10 diff --git a/Release/test_coverage/PDE/Integrate/Boundary.cpp.func-sort-c.html b/Release/test_coverage/PDE/Integrate/Boundary.cpp.func-sort-c.html index b52ccb404b3a..129dd940448a 100644 --- a/Release/test_coverage/PDE/Integrate/Boundary.cpp.func-sort-c.html +++ b/Release/test_coverage/PDE/Integrate/Boundary.cpp.func-sort-c.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:26:06 + 2024-07-11 14:48:26 Functions: 3 diff --git a/Release/test_coverage/PDE/Integrate/Boundary.cpp.func.html b/Release/test_coverage/PDE/Integrate/Boundary.cpp.func.html index a3090c87b3df..8417096a0487 100644 --- a/Release/test_coverage/PDE/Integrate/Boundary.cpp.func.html +++ b/Release/test_coverage/PDE/Integrate/Boundary.cpp.func.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:26:06 + 2024-07-11 14:48:26 Functions: 3 diff --git a/Release/test_coverage/PDE/Integrate/Boundary.cpp.gcov.html b/Release/test_coverage/PDE/Integrate/Boundary.cpp.gcov.html index 4b96d0096d29..a50220a1795e 100644 --- a/Release/test_coverage/PDE/Integrate/Boundary.cpp.gcov.html +++ b/Release/test_coverage/PDE/Integrate/Boundary.cpp.gcov.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:26:06 + 2024-07-11 14:48:26 Functions: 3 diff --git a/Release/test_coverage/PDE/Integrate/Initialize.cpp.func-sort-c.html b/Release/test_coverage/PDE/Integrate/Initialize.cpp.func-sort-c.html index 03a7780852a8..2cbfac234342 100644 --- a/Release/test_coverage/PDE/Integrate/Initialize.cpp.func-sort-c.html +++ b/Release/test_coverage/PDE/Integrate/Initialize.cpp.func-sort-c.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:26:06 + 2024-07-11 14:48:26 Functions: 3 diff --git a/Release/test_coverage/PDE/Integrate/Initialize.cpp.func.html b/Release/test_coverage/PDE/Integrate/Initialize.cpp.func.html index c5b67c064013..e847bc7740c1 100644 --- a/Release/test_coverage/PDE/Integrate/Initialize.cpp.func.html +++ b/Release/test_coverage/PDE/Integrate/Initialize.cpp.func.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:26:06 + 2024-07-11 14:48:26 Functions: 3 diff --git a/Release/test_coverage/PDE/Integrate/Initialize.cpp.gcov.html b/Release/test_coverage/PDE/Integrate/Initialize.cpp.gcov.html index 4c4599ef541b..7be35261c9e5 100644 --- a/Release/test_coverage/PDE/Integrate/Initialize.cpp.gcov.html +++ b/Release/test_coverage/PDE/Integrate/Initialize.cpp.gcov.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:26:06 + 2024-07-11 14:48:26 Functions: 3 diff --git a/Release/test_coverage/PDE/Integrate/Initialize.hpp.func-sort-c.html b/Release/test_coverage/PDE/Integrate/Initialize.hpp.func-sort-c.html index 6e36259acd9f..39bdb215207d 100644 --- a/Release/test_coverage/PDE/Integrate/Initialize.hpp.func-sort-c.html +++ b/Release/test_coverage/PDE/Integrate/Initialize.hpp.func-sort-c.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:26:06 + 2024-07-11 14:48:26 Functions: 2 diff --git a/Release/test_coverage/PDE/Integrate/Initialize.hpp.func.html b/Release/test_coverage/PDE/Integrate/Initialize.hpp.func.html index 6e66f1f065e1..fe49ff260b64 100644 --- a/Release/test_coverage/PDE/Integrate/Initialize.hpp.func.html +++ b/Release/test_coverage/PDE/Integrate/Initialize.hpp.func.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:26:06 + 2024-07-11 14:48:26 Functions: 2 diff --git a/Release/test_coverage/PDE/Integrate/Initialize.hpp.gcov.html b/Release/test_coverage/PDE/Integrate/Initialize.hpp.gcov.html index eb92109600f7..acd49f5626bf 100644 --- a/Release/test_coverage/PDE/Integrate/Initialize.hpp.gcov.html +++ b/Release/test_coverage/PDE/Integrate/Initialize.hpp.gcov.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:26:06 + 2024-07-11 14:48:26 Functions: 2 diff --git a/Release/test_coverage/PDE/Integrate/Mass.cpp.func-sort-c.html b/Release/test_coverage/PDE/Integrate/Mass.cpp.func-sort-c.html index 9b2348ba228d..66d4c75e8b78 100644 --- a/Release/test_coverage/PDE/Integrate/Mass.cpp.func-sort-c.html +++ b/Release/test_coverage/PDE/Integrate/Mass.cpp.func-sort-c.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:26:06 + 2024-07-11 14:48:26 Functions: 2 diff --git a/Release/test_coverage/PDE/Integrate/Mass.cpp.func.html b/Release/test_coverage/PDE/Integrate/Mass.cpp.func.html index c22e2939ebe5..2c15bddb5c0f 100644 --- a/Release/test_coverage/PDE/Integrate/Mass.cpp.func.html +++ b/Release/test_coverage/PDE/Integrate/Mass.cpp.func.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:26:06 + 2024-07-11 14:48:26 Functions: 2 diff --git a/Release/test_coverage/PDE/Integrate/Mass.cpp.gcov.html b/Release/test_coverage/PDE/Integrate/Mass.cpp.gcov.html index f0463e80df40..0f0f2fa7a9f1 100644 --- a/Release/test_coverage/PDE/Integrate/Mass.cpp.gcov.html +++ b/Release/test_coverage/PDE/Integrate/Mass.cpp.gcov.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:26:06 + 2024-07-11 14:48:26 Functions: 2 diff --git a/Release/test_coverage/PDE/Integrate/MultiMatTerms.cpp.func-sort-c.html b/Release/test_coverage/PDE/Integrate/MultiMatTerms.cpp.func-sort-c.html index 10f72b3539a1..8ab529f7654f 100644 --- a/Release/test_coverage/PDE/Integrate/MultiMatTerms.cpp.func-sort-c.html +++ b/Release/test_coverage/PDE/Integrate/MultiMatTerms.cpp.func-sort-c.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:26:06 + 2024-07-11 14:48:26 Functions: 7 diff --git a/Release/test_coverage/PDE/Integrate/MultiMatTerms.cpp.func.html b/Release/test_coverage/PDE/Integrate/MultiMatTerms.cpp.func.html index 7a5b4cecedf3..75dbd4298535 100644 --- a/Release/test_coverage/PDE/Integrate/MultiMatTerms.cpp.func.html +++ b/Release/test_coverage/PDE/Integrate/MultiMatTerms.cpp.func.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:26:06 + 2024-07-11 14:48:26 Functions: 7 diff --git a/Release/test_coverage/PDE/Integrate/MultiMatTerms.cpp.gcov.html b/Release/test_coverage/PDE/Integrate/MultiMatTerms.cpp.gcov.html index 0ae2b1bb569c..22ea71d76b26 100644 --- a/Release/test_coverage/PDE/Integrate/MultiMatTerms.cpp.gcov.html +++ b/Release/test_coverage/PDE/Integrate/MultiMatTerms.cpp.gcov.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:26:06 + 2024-07-11 14:48:26 Functions: 7 diff --git a/Release/test_coverage/PDE/Integrate/Quadrature.cpp.func-sort-c.html b/Release/test_coverage/PDE/Integrate/Quadrature.cpp.func-sort-c.html index 90d01e0494c2..eddeee6671d5 100644 --- a/Release/test_coverage/PDE/Integrate/Quadrature.cpp.func-sort-c.html +++ b/Release/test_coverage/PDE/Integrate/Quadrature.cpp.func-sort-c.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:26:06 + 2024-07-11 14:48:26 Functions: 2 diff --git a/Release/test_coverage/PDE/Integrate/Quadrature.cpp.func.html b/Release/test_coverage/PDE/Integrate/Quadrature.cpp.func.html index 5719a31e837e..414a3afbab3c 100644 --- a/Release/test_coverage/PDE/Integrate/Quadrature.cpp.func.html +++ b/Release/test_coverage/PDE/Integrate/Quadrature.cpp.func.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:26:06 + 2024-07-11 14:48:26 Functions: 2 diff --git a/Release/test_coverage/PDE/Integrate/Quadrature.cpp.gcov.html b/Release/test_coverage/PDE/Integrate/Quadrature.cpp.gcov.html index 7b2e872bbce1..2d6900a4468b 100644 --- a/Release/test_coverage/PDE/Integrate/Quadrature.cpp.gcov.html +++ b/Release/test_coverage/PDE/Integrate/Quadrature.cpp.gcov.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:26:06 + 2024-07-11 14:48:26 Functions: 2 diff --git a/Release/test_coverage/PDE/Integrate/Quadrature.hpp.func-sort-c.html b/Release/test_coverage/PDE/Integrate/Quadrature.hpp.func-sort-c.html index 0d5124c937bd..b9ba1a7e52a2 100644 --- a/Release/test_coverage/PDE/Integrate/Quadrature.hpp.func-sort-c.html +++ b/Release/test_coverage/PDE/Integrate/Quadrature.hpp.func-sort-c.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:26:06 + 2024-07-11 14:48:26 Functions: 4 diff --git a/Release/test_coverage/PDE/Integrate/Quadrature.hpp.func.html b/Release/test_coverage/PDE/Integrate/Quadrature.hpp.func.html index 056b10f3cd91..25b7ffea10ea 100644 --- a/Release/test_coverage/PDE/Integrate/Quadrature.hpp.func.html +++ b/Release/test_coverage/PDE/Integrate/Quadrature.hpp.func.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:26:06 + 2024-07-11 14:48:26 Functions: 4 diff --git a/Release/test_coverage/PDE/Integrate/Quadrature.hpp.gcov.html b/Release/test_coverage/PDE/Integrate/Quadrature.hpp.gcov.html index 2e24be0f81f3..72818e9b38ed 100644 --- a/Release/test_coverage/PDE/Integrate/Quadrature.hpp.gcov.html +++ b/Release/test_coverage/PDE/Integrate/Quadrature.hpp.gcov.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:26:06 + 2024-07-11 14:48:26 Functions: 4 diff --git a/Release/test_coverage/PDE/Integrate/SolidTerms.cpp.func-sort-c.html b/Release/test_coverage/PDE/Integrate/SolidTerms.cpp.func-sort-c.html index 6f9601df2532..6c2e2ccdf3aa 100644 --- a/Release/test_coverage/PDE/Integrate/SolidTerms.cpp.func-sort-c.html +++ b/Release/test_coverage/PDE/Integrate/SolidTerms.cpp.func-sort-c.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:26:06 + 2024-07-11 14:48:26 Functions: 0 diff --git a/Release/test_coverage/PDE/Integrate/SolidTerms.cpp.func.html b/Release/test_coverage/PDE/Integrate/SolidTerms.cpp.func.html index d997dff2fe08..b28369aa903e 100644 --- a/Release/test_coverage/PDE/Integrate/SolidTerms.cpp.func.html +++ b/Release/test_coverage/PDE/Integrate/SolidTerms.cpp.func.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:26:06 + 2024-07-11 14:48:26 Functions: 0 diff --git a/Release/test_coverage/PDE/Integrate/SolidTerms.cpp.gcov.html b/Release/test_coverage/PDE/Integrate/SolidTerms.cpp.gcov.html index 57fa637b06ab..6974ff00907b 100644 --- a/Release/test_coverage/PDE/Integrate/SolidTerms.cpp.gcov.html +++ b/Release/test_coverage/PDE/Integrate/SolidTerms.cpp.gcov.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:26:06 + 2024-07-11 14:48:26 Functions: 0 diff --git a/Release/test_coverage/PDE/Integrate/Source.cpp.func-sort-c.html b/Release/test_coverage/PDE/Integrate/Source.cpp.func-sort-c.html index fbed99db8d7f..34db73bd6abb 100644 --- a/Release/test_coverage/PDE/Integrate/Source.cpp.func-sort-c.html +++ b/Release/test_coverage/PDE/Integrate/Source.cpp.func-sort-c.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:26:06 + 2024-07-11 14:48:26 Functions: 3 diff --git a/Release/test_coverage/PDE/Integrate/Source.cpp.func.html b/Release/test_coverage/PDE/Integrate/Source.cpp.func.html index 030d836ffe59..84e954110eeb 100644 --- a/Release/test_coverage/PDE/Integrate/Source.cpp.func.html +++ b/Release/test_coverage/PDE/Integrate/Source.cpp.func.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:26:06 + 2024-07-11 14:48:26 Functions: 3 diff --git a/Release/test_coverage/PDE/Integrate/Source.cpp.gcov.html b/Release/test_coverage/PDE/Integrate/Source.cpp.gcov.html index 88a078eac7f2..5693bccf2a45 100644 --- a/Release/test_coverage/PDE/Integrate/Source.cpp.gcov.html +++ b/Release/test_coverage/PDE/Integrate/Source.cpp.gcov.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:26:06 + 2024-07-11 14:48:26 Functions: 3 diff --git a/Release/test_coverage/PDE/Integrate/Surface.cpp.func-sort-c.html b/Release/test_coverage/PDE/Integrate/Surface.cpp.func-sort-c.html index 4bad30161c88..84f058ae59b5 100644 --- a/Release/test_coverage/PDE/Integrate/Surface.cpp.func-sort-c.html +++ b/Release/test_coverage/PDE/Integrate/Surface.cpp.func-sort-c.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:26:06 + 2024-07-11 14:48:26 Functions: 3 diff --git a/Release/test_coverage/PDE/Integrate/Surface.cpp.func.html b/Release/test_coverage/PDE/Integrate/Surface.cpp.func.html index fb87b026463d..d5039cdf2646 100644 --- a/Release/test_coverage/PDE/Integrate/Surface.cpp.func.html +++ b/Release/test_coverage/PDE/Integrate/Surface.cpp.func.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:26:06 + 2024-07-11 14:48:26 Functions: 3 diff --git a/Release/test_coverage/PDE/Integrate/Surface.cpp.gcov.html b/Release/test_coverage/PDE/Integrate/Surface.cpp.gcov.html index 5a93a4e1f3d5..71ddf58a3a99 100644 --- a/Release/test_coverage/PDE/Integrate/Surface.cpp.gcov.html +++ b/Release/test_coverage/PDE/Integrate/Surface.cpp.gcov.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:26:06 + 2024-07-11 14:48:26 Functions: 3 @@ -183,7 +183,7 @@ 109 : 33099075 : std::size_t er = static_cast< std::size_t >(esuf[2*f+1]); 110 : : 111 : 33099075 : auto ng_l = tk::NGfa(ndofel[el]); - 112 [ + + ]: 33099075 : auto ng_r = tk::NGfa(ndofel[er]); + 112 [ + + ]: 33099075 : auto ng_r = tk::NGfa(ndofel[er]); 113 : : 114 : : // When the number of gauss points for the left and right element are 115 : : // different, choose the larger ng @@ -349,41 +349,41 @@ 275 [ + + ]: 253470702 : for (ncomp_t c=0; c<ncomp; ++c) 276 : : { 277 : 193132950 : auto mark = c*ndof; - 278 [ + + ]: 193132950 : R(el, mark) -= wt * fl[c]; + 278 [ + + ]: 193132950 : R(el, mark) -= wt * fl[c]; 279 : 193132950 : R(er, mark) += wt * fl[c]; 280 : : - 281 [ + + ]: 193132950 : if(ndof_l > 1) //DG(P1) + 281 [ + + ]: 193132950 : if(ndof_l > 1) //DG(P1) 282 : : { - 283 : 116700615 : R(el, mark+1) -= wt * fl[c] * B_l[1]; - 284 : 116700615 : R(el, mark+2) -= wt * fl[c] * B_l[2]; - 285 : 116700615 : R(el, mark+3) -= wt * fl[c] * B_l[3]; + 283 : 116698860 : R(el, mark+1) -= wt * fl[c] * B_l[1]; + 284 : 116698860 : R(el, mark+2) -= wt * fl[c] * B_l[2]; + 285 : 116698860 : R(el, mark+3) -= wt * fl[c] * B_l[3]; 286 : : } 287 : : - 288 [ + + ]: 193132950 : if(ndof_r > 1) //DG(P1) + 288 [ + + ]: 193132950 : if(ndof_r > 1) //DG(P1) 289 : : { - 290 : 116687700 : R(er, mark+1) += wt * fl[c] * B_r[1]; - 291 : 116687700 : R(er, mark+2) += wt * fl[c] * B_r[2]; - 292 : 116687700 : R(er, mark+3) += wt * fl[c] * B_r[3]; + 290 : 116689455 : R(er, mark+1) += wt * fl[c] * B_r[1]; + 291 : 116689455 : R(er, mark+2) += wt * fl[c] * B_r[2]; + 292 : 116689455 : R(er, mark+3) += wt * fl[c] * B_r[3]; 293 : : } 294 : : - 295 [ + + ]: 193132950 : if(ndof_l > 4) //DG(P2) + 295 [ + + ]: 193132950 : if(ndof_l > 4) //DG(P2) 296 : : { - 297 : 47889000 : R(el, mark+4) -= wt * fl[c] * B_l[4]; - 298 : 47889000 : R(el, mark+5) -= wt * fl[c] * B_l[5]; - 299 : 47889000 : R(el, mark+6) -= wt * fl[c] * B_l[6]; - 300 : 47889000 : R(el, mark+7) -= wt * fl[c] * B_l[7]; - 301 : 47889000 : R(el, mark+8) -= wt * fl[c] * B_l[8]; - 302 : 47889000 : R(el, mark+9) -= wt * fl[c] * B_l[9]; + 297 : 47896200 : R(el, mark+4) -= wt * fl[c] * B_l[4]; + 298 : 47896200 : R(el, mark+5) -= wt * fl[c] * B_l[5]; + 299 : 47896200 : R(el, mark+6) -= wt * fl[c] * B_l[6]; + 300 : 47896200 : R(el, mark+7) -= wt * fl[c] * B_l[7]; + 301 : 47896200 : R(el, mark+8) -= wt * fl[c] * B_l[8]; + 302 : 47896200 : R(el, mark+9) -= wt * fl[c] * B_l[9]; 303 : : } 304 : : - 305 [ + + ]: 193132950 : if(ndof_r > 4) //DG(P2) + 305 [ + + ]: 193132950 : if(ndof_r > 4) //DG(P2) 306 : : { - 307 : 47868030 : R(er, mark+4) += wt * fl[c] * B_r[4]; - 308 : 47868030 : R(er, mark+5) += wt * fl[c] * B_r[5]; - 309 : 47868030 : R(er, mark+6) += wt * fl[c] * B_r[6]; - 310 : 47868030 : R(er, mark+7) += wt * fl[c] * B_r[7]; - 311 : 47868030 : R(er, mark+8) += wt * fl[c] * B_r[8]; - 312 : 47868030 : R(er, mark+9) += wt * fl[c] * B_r[9]; + 307 : 47860830 : R(er, mark+4) += wt * fl[c] * B_r[4]; + 308 : 47860830 : R(er, mark+5) += wt * fl[c] * B_r[5]; + 309 : 47860830 : R(er, mark+6) += wt * fl[c] * B_r[6]; + 310 : 47860830 : R(er, mark+7) += wt * fl[c] * B_r[7]; + 311 : 47860830 : R(er, mark+8) += wt * fl[c] * B_r[8]; + 312 : 47860830 : R(er, mark+9) += wt * fl[c] * B_r[9]; 313 : : } 314 : : } 315 : : diff --git a/Release/test_coverage/PDE/Integrate/Volume.cpp.func-sort-c.html b/Release/test_coverage/PDE/Integrate/Volume.cpp.func-sort-c.html index 61ea27d6c030..89ee21187516 100644 --- a/Release/test_coverage/PDE/Integrate/Volume.cpp.func-sort-c.html +++ b/Release/test_coverage/PDE/Integrate/Volume.cpp.func-sort-c.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:26:06 + 2024-07-11 14:48:26 Functions: 2 diff --git a/Release/test_coverage/PDE/Integrate/Volume.cpp.func.html b/Release/test_coverage/PDE/Integrate/Volume.cpp.func.html index 07737af4ad49..32364ee16c4b 100644 --- a/Release/test_coverage/PDE/Integrate/Volume.cpp.func.html +++ b/Release/test_coverage/PDE/Integrate/Volume.cpp.func.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:26:06 + 2024-07-11 14:48:26 Functions: 2 diff --git a/Release/test_coverage/PDE/Integrate/Volume.cpp.gcov.html b/Release/test_coverage/PDE/Integrate/Volume.cpp.gcov.html index e4fbf72ca52d..3df8ce2b9961 100644 --- a/Release/test_coverage/PDE/Integrate/Volume.cpp.gcov.html +++ b/Release/test_coverage/PDE/Integrate/Volume.cpp.gcov.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:26:06 + 2024-07-11 14:48:26 Functions: 2 diff --git a/Release/test_coverage/PDE/Integrate/index-sort-b.html b/Release/test_coverage/PDE/Integrate/index-sort-b.html index d48ca7e41c68..194827f5a584 100644 --- a/Release/test_coverage/PDE/Integrate/index-sort-b.html +++ b/Release/test_coverage/PDE/Integrate/index-sort-b.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:26:06 + 2024-07-11 14:48:26 Functions: 41 diff --git a/Release/test_coverage/PDE/Integrate/index-sort-f.html b/Release/test_coverage/PDE/Integrate/index-sort-f.html index 6531f2eda011..6b10b8bbfaf6 100644 --- a/Release/test_coverage/PDE/Integrate/index-sort-f.html +++ b/Release/test_coverage/PDE/Integrate/index-sort-f.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:26:06 + 2024-07-11 14:48:26 Functions: 41 @@ -129,18 +129,6 @@ 41.2 % 126 / 306 - - Volume.cpp - -
100.0%
- - 100.0 % - 54 / 54 - 100.0 % - 2 / 2 - 64.6 % - 31 / 48 - Quadrature.cpp @@ -165,6 +153,18 @@ 6.7 % 2 / 30 + + Volume.cpp + +
100.0%
+ + 100.0 % + 54 / 54 + 100.0 % + 2 / 2 + 64.6 % + 31 / 48 + Boundary.cpp @@ -190,28 +190,28 @@ 59 / 86 - Initialize.cpp + Source.cpp
100.0%
100.0 % - 61 / 61 + 45 / 45 100.0 % 3 / 3 - 73.1 % - 38 / 52 + 68.8 % + 33 / 48 - Source.cpp + Initialize.cpp
100.0%
100.0 % - 45 / 45 + 61 / 61 100.0 % 3 / 3 - 68.8 % - 33 / 48 + 73.1 % + 38 / 52 Quadrature.hpp diff --git a/Release/test_coverage/PDE/Integrate/index-sort-l.html b/Release/test_coverage/PDE/Integrate/index-sort-l.html index 83c23855121a..2882f8d02da4 100644 --- a/Release/test_coverage/PDE/Integrate/index-sort-l.html +++ b/Release/test_coverage/PDE/Integrate/index-sort-l.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:26:06 + 2024-07-11 14:48:26 Functions: 41 diff --git a/Release/test_coverage/PDE/Integrate/index.html b/Release/test_coverage/PDE/Integrate/index.html index 8f401418fbae..b1f67a277437 100644 --- a/Release/test_coverage/PDE/Integrate/index.html +++ b/Release/test_coverage/PDE/Integrate/index.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:26:06 + 2024-07-11 14:48:26 Functions: 41 diff --git a/Release/test_coverage/PDE/Limiter.cpp.func-sort-c.html b/Release/test_coverage/PDE/Limiter.cpp.func-sort-c.html index aa933e8e9524..5244d44fc7e4 100644 --- a/Release/test_coverage/PDE/Limiter.cpp.func-sort-c.html +++ b/Release/test_coverage/PDE/Limiter.cpp.func-sort-c.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:26:06 + 2024-07-11 14:48:26 Functions: 18 diff --git a/Release/test_coverage/PDE/Limiter.cpp.func.html b/Release/test_coverage/PDE/Limiter.cpp.func.html index b92bcfbe76f7..1138fe08651b 100644 --- a/Release/test_coverage/PDE/Limiter.cpp.func.html +++ b/Release/test_coverage/PDE/Limiter.cpp.func.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:26:06 + 2024-07-11 14:48:26 Functions: 18 diff --git a/Release/test_coverage/PDE/Limiter.cpp.gcov.html b/Release/test_coverage/PDE/Limiter.cpp.gcov.html index aea8ceb7c1e1..ecd344a7c1b0 100644 --- a/Release/test_coverage/PDE/Limiter.cpp.gcov.html +++ b/Release/test_coverage/PDE/Limiter.cpp.gcov.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:26:06 + 2024-07-11 14:48:26 Functions: 18 @@ -1184,9 +1184,9 @@ 1107 : 15954201 : auto n = static_cast< std::size_t >( nel ); 1108 [ + + ]: 44594406 : for (inciter::ncomp_t c=0; c<ncomp; ++c) 1109 : : { - 1110 [ + + ]: 28640205 : auto mark = c*rdof; - 1111 [ + + ]: 28640205 : uMin[c] = std::min(uMin[c], U(n, mark)); - 1112 [ + + ]: 33822167 : uMax[c] = std::max(uMax[c], U(n, mark)); + 1110 [ + + ]: 28640205 : auto mark = c*rdof; + 1111 [ + + ]: 28640205 : uMin[c] = std::min(uMin[c], U(n, mark)); + 1112 [ + + ]: 33822087 : uMax[c] = std::max(uMax[c], U(n, mark)); 1113 : : } 1114 : : } 1115 : : @@ -1259,25 +1259,25 @@ 1182 : : { 1183 : 72811680 : auto phi_gp = 1.0; 1184 : 72811680 : auto mark = c*rdof; - 1185 [ + + ]: 72811680 : auto uNeg = state[c] - U(e, mark); - 1186 [ + + ]: 72811680 : if (uNeg > 1.0e-14) + 1185 [ + + ]: 72811680 : auto uNeg = state[c] - U(e, mark); + 1186 [ + + ]: 72811680 : if (uNeg > 1.0e-14) 1187 : : { - 1188 [ + + ]: 7325851 : uNeg = std::max(uNeg, 1.0e-08); - 1189 [ + + ]: 11097550 : phi_gp = std::min( 1.0, (uMax[c]-U(e, mark))/(2.0*uNeg) ); + 1188 [ + + ]: 7325842 : uNeg = std::max(uNeg, 1.0e-08); + 1189 [ + + ]: 11097532 : phi_gp = std::min( 1.0, (uMax[c]-U(e, mark))/(2.0*uNeg) ); 1190 : : } - 1191 [ + + ]: 65485829 : else if (uNeg < -1.0e-14) + 1191 [ + + ]: 65485838 : else if (uNeg < -1.0e-14) 1192 : : { - 1193 [ + + ]: 7800831 : uNeg = std::min(uNeg, -1.0e-08); - 1194 [ + + ]: 12359511 : phi_gp = std::min( 1.0, (uMin[c]-U(e, mark))/(2.0*uNeg) ); + 1193 [ + + ]: 7800803 : uNeg = std::min(uNeg, -1.0e-08); + 1194 [ + + ]: 12359455 : phi_gp = std::min( 1.0, (uMin[c]-U(e, mark))/(2.0*uNeg) ); 1195 : : } 1196 : : else 1197 : : { 1198 : : phi_gp = 1.0; 1199 : : } - 1200 [ + + ]: 72811680 : phi_gp = std::max( 0.0, - 1201 [ + + ]: 72811680 : std::max( std::min(beta_lim*phi_gp, 1.0), + 1200 [ + + ]: 72811680 : phi_gp = std::max( 0.0, + 1201 [ + + ]: 72811680 : std::max( std::min(beta_lim*phi_gp, 1.0), 1202 : : std::min(phi_gp, beta_lim) ) ); - 1203 [ + + ]: 75269786 : phi[c] = std::min( phi[c], phi_gp ); + 1203 [ + + ]: 75269742 : phi[c] = std::min( phi[c], phi_gp ); 1204 : : } 1205 : : } 1206 : : } @@ -1356,9 +1356,9 @@ 1279 : : { 1280 [ + + ]: 919952616 : for (std::size_t i=0; i<VarList.size(); ++i) 1281 : : { - 1282 [ + + ]: 744717672 : auto mark = VarList[i]*rdof; - 1283 [ + + ]: 744717672 : uMin[i] = std::min(uMin[i], U(er, mark)); - 1284 [ + + ]: 807312077 : uMax[i] = std::max(uMax[i], U(er, mark)); + 1282 [ + + ]: 744717672 : auto mark = VarList[i]*rdof; + 1283 [ + + ]: 744717672 : uMin[i] = std::min(uMin[i], U(er, mark)); + 1284 [ + + ]: 807276860 : uMax[i] = std::max(uMax[i], U(er, mark)); 1285 : : } 1286 : : } 1287 : : @@ -1379,16 +1379,16 @@ 1302 : : { 1303 : 47235680 : auto c = VarList[i]; 1304 : 47235680 : auto phi_gp = 1.0; - 1305 [ + + ]: 47235680 : auto mark = c*rdof; - 1306 [ + + ]: 47235680 : auto uNeg = state[c] - U(e, mark); - 1307 [ + + ]: 47235680 : auto uref = std::max(std::fabs(U(e,mark)), 1e-14); - 1308 [ + + ]: 47235680 : if (uNeg > 1.0e-06*uref) + 1305 [ + + ]: 47235680 : auto mark = c*rdof; + 1306 [ + + ]: 47235680 : auto uNeg = state[c] - U(e, mark); + 1307 [ + + ]: 47235680 : auto uref = std::max(std::fabs(U(e,mark)), 1e-14); + 1308 [ + + ]: 47235680 : if (uNeg > 1.0e-06*uref) 1309 : : { - 1310 [ + + ]: 11492850 : phi_gp = std::min( 1.0, (uMax[i]-U(e, mark))/uNeg ); + 1310 [ + + ]: 11449085 : phi_gp = std::min( 1.0, (uMax[i]-U(e, mark))/uNeg ); 1311 : : } - 1312 [ + + ]: 38555844 : else if (uNeg < -1.0e-06*uref) + 1312 [ + + ]: 38583790 : else if (uNeg < -1.0e-06*uref) 1313 : : { - 1314 [ + + ]: 12629904 : phi_gp = std::min( 1.0, (uMin[i]-U(e, mark))/uNeg ); + 1314 [ + + ]: 12577142 : phi_gp = std::min( 1.0, (uMin[i]-U(e, mark))/uNeg ); 1315 : : } 1316 : : else 1317 : : { @@ -1396,7 +1396,7 @@ 1319 : : } 1320 : : 1321 : : // ----- Step-3: take the minimum of the nodal-limiter functions - 1322 [ + + ]: 51774472 : phi[c] = std::min( phi[c], phi_gp ); + 1322 [ + + ]: 51760271 : phi[c] = std::min( phi[c], phi_gp ); 1323 : : } 1324 : : } 1325 : 2789304 : } @@ -1594,7 +1594,7 @@ 1517 : : //std::size_t nmax(0); 1518 [ + + ]: 3547884 : for (std::size_t k=0; k<nmat; ++k) 1519 : : { - 1520 [ + + ]: 2382776 : phi_al_p1 = std::min( phi_al_p1, phic_p1[volfracIdx(nmat, k)] ); + 1520 [ + + ]: 2382776 : phi_al_p1 = std::min( phi_al_p1, phic_p1[volfracIdx(nmat, k)] ); 1521 [ - + ]: 2382776 : if(rdof > 4) 1522 [ - - ]: 0 : phi_al_p2 = std::min( phi_al_p2, phic_p2[volfracIdx(nmat, k)] ); 1523 [ + + ]: 2382776 : if (almax < U(e,volfracDofIdx(nmat, k, rdof, 0))) @@ -1607,7 +1607,7 @@ 1530 : : std::max( 1531 : 4765552 : std::abs(U(e,volfracDofIdx(nmat, k, rdof, 1))), 1532 [ + + ]: 2382776 : std::abs(U(e,volfracDofIdx(nmat, k, rdof, 2))) ), - 1533 [ + + ][ + + ]: 4765552 : std::abs(U(e,volfracDofIdx(nmat, k, rdof, 3))) ); + 1533 [ + + ][ + + ]: 4765552 : std::abs(U(e,volfracDofIdx(nmat, k, rdof, 3))) ); 1534 : 2382776 : dalmax = std::max( dalmax, dmax ); 1535 : : } 1536 : : @@ -2335,7 +2335,7 @@ 2258 : : // When the number of gauss points for the left and right element are 2259 : : // different, choose the larger ng 2260 [ + - ]: 1555380 : auto ng_l = tk::NGfa(ndofel[el]); - 2261 [ + - ][ + + ]: 1555380 : auto ng_r = tk::NGfa(ndofel[er]); + 2261 [ + - ][ + + ]: 1555380 : auto ng_r = tk::NGfa(ndofel[er]); 2262 : : 2263 : 1555380 : auto ng = std::max( ng_l, ng_r ); 2264 : : @@ -2454,7 +2454,7 @@ 2376 : 1555380 : tk::real Ind(0.0); 2377 [ + - ]: 1555380 : if(denom > 1e-8) 2378 : 1555380 : Ind = numer / denom; - 2379 [ + + ][ + + ]: 2196235 : IC[el] = std::max(IC[el], Ind); + 2379 [ + + ][ + + ]: 2199101 : IC[el] = std::max(IC[el], Ind); 2380 [ + - ]: 1555380 : IC[er] = std::max(IC[er], Ind); 2381 : : } 2382 : : diff --git a/Release/test_coverage/PDE/MultiMat/BCFunctions.hpp.func-sort-c.html b/Release/test_coverage/PDE/MultiMat/BCFunctions.hpp.func-sort-c.html index 044b65ab5075..bd1be07d7728 100644 --- a/Release/test_coverage/PDE/MultiMat/BCFunctions.hpp.func-sort-c.html +++ b/Release/test_coverage/PDE/MultiMat/BCFunctions.hpp.func-sort-c.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:26:06 + 2024-07-11 14:48:26 Functions: 2 diff --git a/Release/test_coverage/PDE/MultiMat/BCFunctions.hpp.func.html b/Release/test_coverage/PDE/MultiMat/BCFunctions.hpp.func.html index 9de56cbc35e5..b146640c8431 100644 --- a/Release/test_coverage/PDE/MultiMat/BCFunctions.hpp.func.html +++ b/Release/test_coverage/PDE/MultiMat/BCFunctions.hpp.func.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:26:06 + 2024-07-11 14:48:26 Functions: 2 diff --git a/Release/test_coverage/PDE/MultiMat/BCFunctions.hpp.gcov.html b/Release/test_coverage/PDE/MultiMat/BCFunctions.hpp.gcov.html index 0e88d65d1046..3220aa3a1b8f 100644 --- a/Release/test_coverage/PDE/MultiMat/BCFunctions.hpp.gcov.html +++ b/Release/test_coverage/PDE/MultiMat/BCFunctions.hpp.gcov.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:26:06 + 2024-07-11 14:48:26 Functions: 2 diff --git a/Release/test_coverage/PDE/MultiMat/DGMultiMat.hpp.func-sort-c.html b/Release/test_coverage/PDE/MultiMat/DGMultiMat.hpp.func-sort-c.html index 0f64e12125d6..254d29461a9f 100644 --- a/Release/test_coverage/PDE/MultiMat/DGMultiMat.hpp.func-sort-c.html +++ b/Release/test_coverage/PDE/MultiMat/DGMultiMat.hpp.func-sort-c.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:26:06 + 2024-07-11 14:48:26 Functions: 32 diff --git a/Release/test_coverage/PDE/MultiMat/DGMultiMat.hpp.func.html b/Release/test_coverage/PDE/MultiMat/DGMultiMat.hpp.func.html index b3fc06e06a02..20fb680736a6 100644 --- a/Release/test_coverage/PDE/MultiMat/DGMultiMat.hpp.func.html +++ b/Release/test_coverage/PDE/MultiMat/DGMultiMat.hpp.func.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:26:06 + 2024-07-11 14:48:26 Functions: 32 diff --git a/Release/test_coverage/PDE/MultiMat/DGMultiMat.hpp.gcov.html b/Release/test_coverage/PDE/MultiMat/DGMultiMat.hpp.gcov.html index a5c30a31685d..bcf93720723d 100644 --- a/Release/test_coverage/PDE/MultiMat/DGMultiMat.hpp.gcov.html +++ b/Release/test_coverage/PDE/MultiMat/DGMultiMat.hpp.gcov.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:26:06 + 2024-07-11 14:48:26 Functions: 32 @@ -657,9 +657,9 @@ 542 : 12596896 : auto rmark = k * rdof; 543 [ + + ]: 32811692 : for(std::size_t idof = 0; idof < ndof; idof++) 544 : : { - 545 [ + + ]: 20214796 : prim(e, rmark+idof) = R[mark+idof] / L(e, mark+idof); - 546 [ + + ]: 20214796 : if(fabs(prim(e, rmark+idof)) < 1e-16) - 547 : 5193732 : prim(e, rmark+idof) = 0; + 545 [ + + ]: 20214796 : prim(e, rmark+idof) = R[mark+idof] / L(e, mark+idof); + 546 [ + + ]: 20214796 : if(fabs(prim(e, rmark+idof)) < 1e-16) + 547 : 5193085 : prim(e, rmark+idof) = 0; 548 : : } 549 : : } 550 : : } diff --git a/Release/test_coverage/PDE/MultiMat/FVMultiMat.hpp.func-sort-c.html b/Release/test_coverage/PDE/MultiMat/FVMultiMat.hpp.func-sort-c.html index d78bf355400e..bbea59b64190 100644 --- a/Release/test_coverage/PDE/MultiMat/FVMultiMat.hpp.func-sort-c.html +++ b/Release/test_coverage/PDE/MultiMat/FVMultiMat.hpp.func-sort-c.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:26:06 + 2024-07-11 14:48:26 Functions: 23 diff --git a/Release/test_coverage/PDE/MultiMat/FVMultiMat.hpp.func.html b/Release/test_coverage/PDE/MultiMat/FVMultiMat.hpp.func.html index 144c409aaa53..e631991629d2 100644 --- a/Release/test_coverage/PDE/MultiMat/FVMultiMat.hpp.func.html +++ b/Release/test_coverage/PDE/MultiMat/FVMultiMat.hpp.func.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:26:06 + 2024-07-11 14:48:26 Functions: 23 diff --git a/Release/test_coverage/PDE/MultiMat/FVMultiMat.hpp.gcov.html b/Release/test_coverage/PDE/MultiMat/FVMultiMat.hpp.gcov.html index 84f027a5ce42..19a6df5618f9 100644 --- a/Release/test_coverage/PDE/MultiMat/FVMultiMat.hpp.gcov.html +++ b/Release/test_coverage/PDE/MultiMat/FVMultiMat.hpp.gcov.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:26:06 + 2024-07-11 14:48:26 Functions: 23 @@ -909,7 +909,7 @@ 796 : : { 797 [ + - ]: 21326 : ss[e] = std::max( ss[e], m_mat_blk[k].compute< EOS::soundspeed >( 798 : : ugp[densityIdx(nmat, k)], pgp[pressureIdx(nmat, k)], - 799 [ + + ]: 10663 : ugp[volfracIdx(nmat, k)], k ) ); + 799 [ + + ]: 10663 : ugp[volfracIdx(nmat, k)], k ) ); 800 : : } 801 : : } 802 : : } diff --git a/Release/test_coverage/PDE/MultiMat/MiscMultiMatFns.cpp.func-sort-c.html b/Release/test_coverage/PDE/MultiMat/MiscMultiMatFns.cpp.func-sort-c.html index b109d277728d..97eea1989894 100644 --- a/Release/test_coverage/PDE/MultiMat/MiscMultiMatFns.cpp.func-sort-c.html +++ b/Release/test_coverage/PDE/MultiMat/MiscMultiMatFns.cpp.func-sort-c.html @@ -27,18 +27,18 @@ -128-NOTFOUND Lines: - 201 + 205 237 - 84.8 % + 86.5 % Date: - 2024-07-10 11:26:06 + 2024-07-11 14:48:26 Functions: - 8 + 9 10 - 80.0 % + 90.0 % Legend: @@ -52,9 +52,9 @@ Branches: - 148 + 149 262 - 56.5 % + 56.9 % @@ -71,10 +71,6 @@ Function Name Sort by function name Hit count Sort by hit count - - inciter::getCauchyStress(unsigned long, unsigned long, unsigned long, std::vector<double, std::allocator<double> > const&) - 0 - inciter::cleanTraceMultiMat(double, unsigned long, std::vector<inciter::EOS, std::allocator<inciter::EOS> > const&, tk::Data<(unsigned char)0> const&, unsigned long, tk::Data<(unsigned char)0>&, tk::Data<(unsigned char)0>&)::{lambda()#1}::operator()() const 0 @@ -99,9 +95,13 @@ inciter::cleanTraceMultiMat(double, unsigned long, std::vector<inciter::EOS, std::allocator<inciter::EOS> > const&, tk::Data<(unsigned char)0> const&, unsigned long, tk::Data<(unsigned char)0>&, tk::Data<(unsigned char)0>&) 6898 + + inciter::getCauchyStress(unsigned long, unsigned long, unsigned long, std::vector<double, std::allocator<double> > const&) + 686000 + inciter::numSolids(unsigned long, std::vector<unsigned long, std::allocator<unsigned long> > const&) - 1891116 + 2062616 inciter::haveSolid(unsigned long, std::vector<unsigned long, std::allocator<unsigned long> > const&) @@ -109,7 +109,7 @@ inciter::getDeformGrad(unsigned long, unsigned long, std::vector<double, std::allocator<double> > const&) - 17848474 + 18534474
diff --git a/Release/test_coverage/PDE/MultiMat/MiscMultiMatFns.cpp.func.html b/Release/test_coverage/PDE/MultiMat/MiscMultiMatFns.cpp.func.html index 9e029d065071..f4267f6e9f4d 100644 --- a/Release/test_coverage/PDE/MultiMat/MiscMultiMatFns.cpp.func.html +++ b/Release/test_coverage/PDE/MultiMat/MiscMultiMatFns.cpp.func.html @@ -27,18 +27,18 @@ -128-NOTFOUND Lines: - 201 + 205 237 - 84.8 % + 86.5 % Date: - 2024-07-10 11:26:06 + 2024-07-11 14:48:26 Functions: - 8 + 9 10 - 80.0 % + 90.0 % Legend: @@ -52,9 +52,9 @@ Branches: - 148 + 149 262 - 56.5 % + 56.9 % @@ -73,11 +73,11 @@ inciter::getDeformGrad(unsigned long, unsigned long, std::vector<double, std::allocator<double> > const&) - 17848474 + 18534474 inciter::getCauchyStress(unsigned long, unsigned long, unsigned long, std::vector<double, std::allocator<double> > const&) - 0 + 686000 inciter::resetSolidTensors(unsigned long, unsigned long, unsigned long, tk::Data<(unsigned char)0>&, tk::Data<(unsigned char)0>&) @@ -105,7 +105,7 @@ inciter::numSolids(unsigned long, std::vector<unsigned long, std::allocator<unsigned long> > const&) - 1891116 + 2062616 inciter::cleanTraceMultiMat(double, unsigned long, std::vector<inciter::EOS, std::allocator<inciter::EOS> > const&, tk::Data<(unsigned char)0> const&, unsigned long, tk::Data<(unsigned char)0>&, tk::Data<(unsigned char)0>&)::{lambda()#1}::operator()() const diff --git a/Release/test_coverage/PDE/MultiMat/MiscMultiMatFns.cpp.gcov.html b/Release/test_coverage/PDE/MultiMat/MiscMultiMatFns.cpp.gcov.html index c7cec6e66441..e47d6b72ec33 100644 --- a/Release/test_coverage/PDE/MultiMat/MiscMultiMatFns.cpp.gcov.html +++ b/Release/test_coverage/PDE/MultiMat/MiscMultiMatFns.cpp.gcov.html @@ -27,18 +27,18 @@ -128-NOTFOUND Lines: - 201 + 205 237 - 84.8 % + 86.5 % Date: - 2024-07-10 11:26:06 + 2024-07-11 14:48:26 Functions: - 8 + 9 10 - 80.0 % + 90.0 % Legend: @@ -52,9 +52,9 @@ Branches: - 148 + 149 262 - 56.5 % + 56.9 % @@ -479,12 +479,12 @@ 404 : 470350 : a = 0.0; 405 [ + + ]: 1411050 : for (std::size_t k=0; k<nmat; ++k) 406 : : { - 407 [ + + ]: 940700 : if (ugp[volfracIdx(nmat, k)] > 1.0e-04) { - 408 [ + - ]: 487275 : auto gk = getDeformGrad(nmat, k, ugp); - 409 [ + - ]: 487275 : gk = tk::rotateTensor(gk, fn); - 410 [ + - ][ + + ]: 1451898 : a = std::max( a, mat_blk[k].compute< EOS::soundspeed >( + 407 [ + + ]: 940700 : if (ugp[volfracIdx(nmat, k)] > 1.0e-04) { + 408 [ + - ]: 487265 : auto gk = getDeformGrad(nmat, k, ugp); + 409 [ + - ]: 487265 : gk = tk::rotateTensor(gk, fn); + 410 [ + - ][ + + ]: 1451927 : a = std::max( a, mat_blk[k].compute< EOS::soundspeed >( 411 : : ugp[densityIdx(nmat, k)], - 412 [ + - ]: 487275 : pgp[pressureIdx(nmat, k)], ugp[volfracIdx(nmat, k)], k, gk ) ); + 412 [ + - ]: 487265 : pgp[pressureIdx(nmat, k)], ugp[volfracIdx(nmat, k)], k, gk ) ); 413 : : } 414 : : } 415 : : @@ -514,16 +514,16 @@ 439 : 362890 : a = 0.0; 440 [ + + ]: 1088670 : for (std::size_t k=0; k<nmat; ++k) 441 : : { - 442 [ + + ]: 725780 : if (ugp[volfracIdx(nmat, k)] > 1.0e-04) { - 443 [ + - ]: 376600 : auto gk = getDeformGrad(nmat, k, ugp); - 444 [ + - ]: 376600 : gk = tk::rotateTensor(gk, fn); - 445 [ + - ][ + + ]: 1122120 : a = std::max( a, mat_blk[k].compute< EOS::soundspeed >( + 442 [ + + ]: 725780 : if (ugp[volfracIdx(nmat, k)] > 1.0e-04) { + 443 [ + - ]: 376610 : auto gk = getDeformGrad(nmat, k, ugp); + 444 [ + - ]: 376610 : gk = tk::rotateTensor(gk, fn); + 445 [ + - ][ + + ]: 1122091 : a = std::max( a, mat_blk[k].compute< EOS::soundspeed >( 446 : : ugp[densityIdx(nmat, k)], - 447 [ + - ]: 376600 : pgp[pressureIdx(nmat, k)], ugp[volfracIdx(nmat, k)], k, gk ) ); + 447 [ + - ]: 376610 : pgp[pressureIdx(nmat, k)], ugp[volfracIdx(nmat, k)], k, gk ) ); 448 : : } 449 : : } 450 : : - 451 [ + + ]: 362890 : dSV_r = geoFace(f,0) * (std::fabs(vn) + a); + 451 [ + + ]: 362890 : dSV_r = geoFace(f,0) * (std::fabs(vn) + a); 452 : : 453 [ + - ]: 362890 : delt[eR] += std::max( dSV_l, dSV_r ); 454 : : } else { @@ -538,7 +538,7 @@ 463 : : // compute allowable dt 464 [ + + ]: 204945 : for (std::size_t e=0; e<nelem; ++e) 465 : : { - 466 [ + + ]: 206749 : mindt = std::min( mindt, geoElem(e,0)/delt[e] ); + 466 [ + + ]: 206702 : mindt = std::min( mindt, geoElem(e,0)/delt[e] ); 467 : : } 468 : : 469 [ + - ]: 570 : return mindt; @@ -612,7 +612,7 @@ 537 : : { 538 [ + + ]: 168200 : if (ugp[volfracIdx(nmat, k)] > 1.0e-04) 539 : : { - 540 [ + - ][ + + ]: 291110 : a = std::max( a, mat_blk[k].compute< EOS::soundspeed >( + 540 [ + - ][ + + ]: 291184 : a = std::max( a, mat_blk[k].compute< EOS::soundspeed >( 541 [ + - ]: 102936 : ugp[densityIdx(nmat, k)], pgp[pressureIdx(nmat, k)], 542 : : ugp[volfracIdx(nmat, k)], k ) ); 543 : : } @@ -628,7 +628,7 @@ 553 : 84100 : /std::sqrt(24.0); 554 : : 555 : : // element dt - 556 [ + + ]: 84100 : local_dte[e] = dx/v_char; + 556 [ + + ]: 84100 : local_dte[e] = dx/v_char; 557 [ + - ]: 84100 : mindt = std::min(mindt, local_dte[e]); 558 : : } 559 : : @@ -675,7 +675,7 @@ 600 : 10 : } 601 : : 602 : : std::array< std::array< tk::real, 3 >, 3 > - 603 : 17848474 : getDeformGrad( + 603 : 18534474 : getDeformGrad( 604 : : std::size_t nmat, 605 : : std::size_t k, 606 : : const std::vector< tk::real >& state ) @@ -690,7 +690,7 @@ 615 : : const auto& solidx = g_inputdeck.get< tag::matidxmap, tag::solidx >(); 616 : : std::array< std::array< tk::real, 3 >, 3 > gk; 617 : : - 618 [ - + ]: 17848474 : if (solidx[k] > 0) { + 618 [ - + ]: 18534474 : if (solidx[k] > 0) { 619 : : // deformation gradient for solids 620 [ - - ]: 0 : for (std::size_t i=0; i<3; ++i) { 621 [ - - ]: 0 : for (std::size_t j=0; j<3; ++j) @@ -699,14 +699,14 @@ 624 : : } 625 : : else { 626 : : // empty vector for fluids - 627 : 17848474 : gk = {{}}; + 627 : 18534474 : gk = {{}}; 628 : : } 629 : : - 630 : 17848474 : return gk; + 630 : 18534474 : return gk; 631 : : } 632 : : 633 : : std::array< std::array< tk::real, 3 >, 3 > - 634 : 0 : getCauchyStress( + 634 : 686000 : getCauchyStress( 635 : : std::size_t nmat, 636 : : std::size_t k, 637 : : std::size_t ncomp, @@ -722,10 +722,10 @@ 647 : : { 648 : : const auto& solidx = g_inputdeck.get< tag::matidxmap, tag::solidx >(); 649 : : std::array< std::array< tk::real, 3 >, 3 > - 650 : 0 : asigk{{ {{0,0,0}}, {{0,0,0}}, {{0,0,0}} }}; + 650 : 686000 : asigk{{ {{0,0,0}}, {{0,0,0}}, {{0,0,0}} }}; 651 : : 652 : : // elastic Cauchy stress for solids - 653 [ - - ]: 0 : if (solidx[k] > 0) { + 653 [ - + ]: 686000 : if (solidx[k] > 0) { 654 [ - - ]: 0 : for (std::size_t i=0; i<3; ++i) { 655 [ - - ]: 0 : for (std::size_t j=0; j<3; ++j) 656 : 0 : asigk[i][j] = state[ncomp + @@ -733,7 +733,7 @@ 658 : : } 659 : : } 660 : : - 661 : 0 : return asigk; + 661 : 686000 : return asigk; 662 : : } 663 : : 664 : : bool @@ -754,7 +754,7 @@ 679 : 7379280 : return haveSolid; 680 : : } 681 : : - 682 : 1891116 : std::size_t numSolids( + 682 : 2062616 : std::size_t numSolids( 683 : : std::size_t nmat, 684 : : const std::vector< std::size_t >& solidx ) 685 : : // ***************************************************************************** @@ -766,10 +766,10 @@ 691 : : { 692 : : // count number of solid materials 693 : : std::size_t nsld(0); - 694 [ + + ]: 6345528 : for (std::size_t k=0; k<nmat; ++k) - 695 [ - + ]: 4454412 : if (solidx[k] > 0) ++nsld; + 694 [ + + ]: 6860028 : for (std::size_t k=0; k<nmat; ++k) + 695 [ - + ]: 4797412 : if (solidx[k] > 0) ++nsld; 696 : : - 697 : 1891116 : return nsld; + 697 : 2062616 : return nsld; 698 : : } 699 : : 700 : : } //inciter:: diff --git a/Release/test_coverage/PDE/MultiMat/MultiMatIndexing.hpp.func-sort-c.html b/Release/test_coverage/PDE/MultiMat/MultiMatIndexing.hpp.func-sort-c.html index fc0d2eff78e2..bff4f3e129ec 100644 --- a/Release/test_coverage/PDE/MultiMat/MultiMatIndexing.hpp.func-sort-c.html +++ b/Release/test_coverage/PDE/MultiMat/MultiMatIndexing.hpp.func-sort-c.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:26:06 + 2024-07-11 14:48:26 Functions: 0 diff --git a/Release/test_coverage/PDE/MultiMat/MultiMatIndexing.hpp.func.html b/Release/test_coverage/PDE/MultiMat/MultiMatIndexing.hpp.func.html index b9a3dd894129..c9bc03467594 100644 --- a/Release/test_coverage/PDE/MultiMat/MultiMatIndexing.hpp.func.html +++ b/Release/test_coverage/PDE/MultiMat/MultiMatIndexing.hpp.func.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:26:06 + 2024-07-11 14:48:26 Functions: 0 diff --git a/Release/test_coverage/PDE/MultiMat/MultiMatIndexing.hpp.gcov.html b/Release/test_coverage/PDE/MultiMat/MultiMatIndexing.hpp.gcov.html index 70d0292d0794..4f233882ce37 100644 --- a/Release/test_coverage/PDE/MultiMat/MultiMatIndexing.hpp.gcov.html +++ b/Release/test_coverage/PDE/MultiMat/MultiMatIndexing.hpp.gcov.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:26:06 + 2024-07-11 14:48:26 Functions: 0 @@ -105,8 +105,8 @@ 31 : : //! \param[in] kmat Index of required material 32 : : //! \return Index of the required material continuity equation 33 : : inline std::size_t densityIdx( std::size_t nmat, std::size_t kmat ) - 34 [ + + ][ + - ]: 281511690 : { return (nmat+kmat); } - [ + + ][ + + ] + 34 [ + + ][ + - ]: 282197690 : { return (nmat+kmat); } + [ + + ][ + + ] [ + - ][ + + ] [ - + ][ - - ] [ + - ][ + - ] @@ -150,7 +150,8 @@ [ - + ][ - - ] [ - - ][ + - ] [ + - ][ + - ] - [ + - ] + [ + - ][ + - ] + [ + - ] 35 : : 36 : : //! Get the index of the required momentum equation component 37 : : //! \param[in] nmat Number of materials @@ -177,7 +178,7 @@ 48 : : //! \param[in] kmat Index of required material 49 : : //! \return Index of the required material total energy equation 50 : : inline std::size_t energyIdx( std::size_t nmat, std::size_t kmat ) - 51 [ + - ][ + - ]: 230577324 : { return (2*nmat+3+kmat); } + 51 [ + - ][ + - ]: 229891324 : { return (2*nmat+3+kmat); } [ + + ][ + + ] [ - - ][ + - ] [ - - ][ - - ] @@ -208,8 +209,7 @@ [ - - ][ + - ] [ - - ][ - - ] [ - + ][ + - ] - [ + - ][ + - ] - [ + - ] + [ + - ] 52 : : 53 : : //! Get the index of the required material deformation gradient equation 54 : : //! \param[in] nmat Number of materials @@ -229,7 +229,7 @@ 68 : : //! 2: Z-component. 69 : : //! \return Index of the required velocity component from vector of primitives 70 : : inline std::size_t velocityIdx( std::size_t nmat, std::size_t idir ) - 71 [ + - ][ + - ]: 44806807 : { return nmat+idir; } + 71 [ + - ][ + - ]: 46864807 : { return nmat+idir; } [ - - ][ - - ] [ - - ][ - - ] [ - - ][ - - ] diff --git a/Release/test_coverage/PDE/MultiMat/Physics/FVEnergyPill.cpp.func-sort-c.html b/Release/test_coverage/PDE/MultiMat/Physics/FVEnergyPill.cpp.func-sort-c.html index bd7b6b987629..9c3f0c4bf8db 100644 --- a/Release/test_coverage/PDE/MultiMat/Physics/FVEnergyPill.cpp.func-sort-c.html +++ b/Release/test_coverage/PDE/MultiMat/Physics/FVEnergyPill.cpp.func-sort-c.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:26:06 + 2024-07-11 14:48:26 Functions: 2 diff --git a/Release/test_coverage/PDE/MultiMat/Physics/FVEnergyPill.cpp.func.html b/Release/test_coverage/PDE/MultiMat/Physics/FVEnergyPill.cpp.func.html index 07ed1b9d63c3..345a9f604ca0 100644 --- a/Release/test_coverage/PDE/MultiMat/Physics/FVEnergyPill.cpp.func.html +++ b/Release/test_coverage/PDE/MultiMat/Physics/FVEnergyPill.cpp.func.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:26:06 + 2024-07-11 14:48:26 Functions: 2 diff --git a/Release/test_coverage/PDE/MultiMat/Physics/FVEnergyPill.cpp.gcov.html b/Release/test_coverage/PDE/MultiMat/Physics/FVEnergyPill.cpp.gcov.html index f1b903de9920..078f5554c721 100644 --- a/Release/test_coverage/PDE/MultiMat/Physics/FVEnergyPill.cpp.gcov.html +++ b/Release/test_coverage/PDE/MultiMat/Physics/FVEnergyPill.cpp.gcov.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:26:06 + 2024-07-11 14:48:26 Functions: 2 diff --git a/Release/test_coverage/PDE/MultiMat/Physics/index-sort-b.html b/Release/test_coverage/PDE/MultiMat/Physics/index-sort-b.html index a1477ca0ead4..e97ce553ddac 100644 --- a/Release/test_coverage/PDE/MultiMat/Physics/index-sort-b.html +++ b/Release/test_coverage/PDE/MultiMat/Physics/index-sort-b.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:26:06 + 2024-07-11 14:48:26 Functions: 2 diff --git a/Release/test_coverage/PDE/MultiMat/Physics/index-sort-f.html b/Release/test_coverage/PDE/MultiMat/Physics/index-sort-f.html index bcdb15d6bbef..b0c94899ad91 100644 --- a/Release/test_coverage/PDE/MultiMat/Physics/index-sort-f.html +++ b/Release/test_coverage/PDE/MultiMat/Physics/index-sort-f.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:26:06 + 2024-07-11 14:48:26 Functions: 2 diff --git a/Release/test_coverage/PDE/MultiMat/Physics/index-sort-l.html b/Release/test_coverage/PDE/MultiMat/Physics/index-sort-l.html index e2305f85bf98..c11ad8e477fc 100644 --- a/Release/test_coverage/PDE/MultiMat/Physics/index-sort-l.html +++ b/Release/test_coverage/PDE/MultiMat/Physics/index-sort-l.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:26:06 + 2024-07-11 14:48:26 Functions: 2 diff --git a/Release/test_coverage/PDE/MultiMat/Physics/index.html b/Release/test_coverage/PDE/MultiMat/Physics/index.html index 7b55db0cf571..3c40b5e80da1 100644 --- a/Release/test_coverage/PDE/MultiMat/Physics/index.html +++ b/Release/test_coverage/PDE/MultiMat/Physics/index.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:26:06 + 2024-07-11 14:48:26 Functions: 2 diff --git a/Release/test_coverage/PDE/MultiMat/Problem/BoxInitialization.hpp.func-sort-c.html b/Release/test_coverage/PDE/MultiMat/Problem/BoxInitialization.hpp.func-sort-c.html index 6f5672a30ba5..90caf887ace3 100644 --- a/Release/test_coverage/PDE/MultiMat/Problem/BoxInitialization.hpp.func-sort-c.html +++ b/Release/test_coverage/PDE/MultiMat/Problem/BoxInitialization.hpp.func-sort-c.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:26:06 + 2024-07-11 14:48:26 Functions: 1 diff --git a/Release/test_coverage/PDE/MultiMat/Problem/BoxInitialization.hpp.func.html b/Release/test_coverage/PDE/MultiMat/Problem/BoxInitialization.hpp.func.html index 9a11f0de7ba5..955030a30f43 100644 --- a/Release/test_coverage/PDE/MultiMat/Problem/BoxInitialization.hpp.func.html +++ b/Release/test_coverage/PDE/MultiMat/Problem/BoxInitialization.hpp.func.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:26:06 + 2024-07-11 14:48:26 Functions: 1 diff --git a/Release/test_coverage/PDE/MultiMat/Problem/BoxInitialization.hpp.gcov.html b/Release/test_coverage/PDE/MultiMat/Problem/BoxInitialization.hpp.gcov.html index 7f4739c80eb8..25dff606bcdf 100644 --- a/Release/test_coverage/PDE/MultiMat/Problem/BoxInitialization.hpp.gcov.html +++ b/Release/test_coverage/PDE/MultiMat/Problem/BoxInitialization.hpp.gcov.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:26:06 + 2024-07-11 14:48:26 Functions: 1 diff --git a/Release/test_coverage/PDE/MultiMat/Problem/EquilInterfaceAdvect.cpp.func-sort-c.html b/Release/test_coverage/PDE/MultiMat/Problem/EquilInterfaceAdvect.cpp.func-sort-c.html index b9041b4685ab..dce56fc05655 100644 --- a/Release/test_coverage/PDE/MultiMat/Problem/EquilInterfaceAdvect.cpp.func-sort-c.html +++ b/Release/test_coverage/PDE/MultiMat/Problem/EquilInterfaceAdvect.cpp.func-sort-c.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:26:06 + 2024-07-11 14:48:26 Functions: 0 diff --git a/Release/test_coverage/PDE/MultiMat/Problem/EquilInterfaceAdvect.cpp.func.html b/Release/test_coverage/PDE/MultiMat/Problem/EquilInterfaceAdvect.cpp.func.html index 494577381da7..b2002f181513 100644 --- a/Release/test_coverage/PDE/MultiMat/Problem/EquilInterfaceAdvect.cpp.func.html +++ b/Release/test_coverage/PDE/MultiMat/Problem/EquilInterfaceAdvect.cpp.func.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:26:06 + 2024-07-11 14:48:26 Functions: 0 diff --git a/Release/test_coverage/PDE/MultiMat/Problem/EquilInterfaceAdvect.cpp.gcov.html b/Release/test_coverage/PDE/MultiMat/Problem/EquilInterfaceAdvect.cpp.gcov.html index 5d07d0d03de3..2e810a046234 100644 --- a/Release/test_coverage/PDE/MultiMat/Problem/EquilInterfaceAdvect.cpp.gcov.html +++ b/Release/test_coverage/PDE/MultiMat/Problem/EquilInterfaceAdvect.cpp.gcov.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:26:06 + 2024-07-11 14:48:26 Functions: 0 diff --git a/Release/test_coverage/PDE/MultiMat/Problem/EquilInterfaceAdvect.hpp.func-sort-c.html b/Release/test_coverage/PDE/MultiMat/Problem/EquilInterfaceAdvect.hpp.func-sort-c.html index 3e1b484c6f63..6487bd6c2708 100644 --- a/Release/test_coverage/PDE/MultiMat/Problem/EquilInterfaceAdvect.hpp.func-sort-c.html +++ b/Release/test_coverage/PDE/MultiMat/Problem/EquilInterfaceAdvect.hpp.func-sort-c.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:26:06 + 2024-07-11 14:48:26 Functions: 0 diff --git a/Release/test_coverage/PDE/MultiMat/Problem/EquilInterfaceAdvect.hpp.func.html b/Release/test_coverage/PDE/MultiMat/Problem/EquilInterfaceAdvect.hpp.func.html index a6ffb4f56088..9a9225df88c3 100644 --- a/Release/test_coverage/PDE/MultiMat/Problem/EquilInterfaceAdvect.hpp.func.html +++ b/Release/test_coverage/PDE/MultiMat/Problem/EquilInterfaceAdvect.hpp.func.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:26:06 + 2024-07-11 14:48:26 Functions: 0 diff --git a/Release/test_coverage/PDE/MultiMat/Problem/EquilInterfaceAdvect.hpp.gcov.html b/Release/test_coverage/PDE/MultiMat/Problem/EquilInterfaceAdvect.hpp.gcov.html index fc6dcd52b3eb..6cf4612f8df0 100644 --- a/Release/test_coverage/PDE/MultiMat/Problem/EquilInterfaceAdvect.hpp.gcov.html +++ b/Release/test_coverage/PDE/MultiMat/Problem/EquilInterfaceAdvect.hpp.gcov.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:26:06 + 2024-07-11 14:48:26 Functions: 0 diff --git a/Release/test_coverage/PDE/MultiMat/Problem/FieldOutput.cpp.func-sort-c.html b/Release/test_coverage/PDE/MultiMat/Problem/FieldOutput.cpp.func-sort-c.html index b3408b150bf5..482c7dc05b75 100644 --- a/Release/test_coverage/PDE/MultiMat/Problem/FieldOutput.cpp.func-sort-c.html +++ b/Release/test_coverage/PDE/MultiMat/Problem/FieldOutput.cpp.func-sort-c.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:26:06 + 2024-07-11 14:48:26 Functions: 4 diff --git a/Release/test_coverage/PDE/MultiMat/Problem/FieldOutput.cpp.func.html b/Release/test_coverage/PDE/MultiMat/Problem/FieldOutput.cpp.func.html index e085f612c0e6..917630cee920 100644 --- a/Release/test_coverage/PDE/MultiMat/Problem/FieldOutput.cpp.func.html +++ b/Release/test_coverage/PDE/MultiMat/Problem/FieldOutput.cpp.func.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:26:06 + 2024-07-11 14:48:26 Functions: 4 diff --git a/Release/test_coverage/PDE/MultiMat/Problem/FieldOutput.cpp.gcov.html b/Release/test_coverage/PDE/MultiMat/Problem/FieldOutput.cpp.gcov.html index 8311c0e123e9..001f39d469be 100644 --- a/Release/test_coverage/PDE/MultiMat/Problem/FieldOutput.cpp.gcov.html +++ b/Release/test_coverage/PDE/MultiMat/Problem/FieldOutput.cpp.gcov.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:26:06 + 2024-07-11 14:48:26 Functions: 4 diff --git a/Release/test_coverage/PDE/MultiMat/Problem/InterfaceAdvection.cpp.func-sort-c.html b/Release/test_coverage/PDE/MultiMat/Problem/InterfaceAdvection.cpp.func-sort-c.html index 849d0cc20d93..bef35141c1d9 100644 --- a/Release/test_coverage/PDE/MultiMat/Problem/InterfaceAdvection.cpp.func-sort-c.html +++ b/Release/test_coverage/PDE/MultiMat/Problem/InterfaceAdvection.cpp.func-sort-c.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:26:06 + 2024-07-11 14:48:26 Functions: 1 diff --git a/Release/test_coverage/PDE/MultiMat/Problem/InterfaceAdvection.cpp.func.html b/Release/test_coverage/PDE/MultiMat/Problem/InterfaceAdvection.cpp.func.html index 7fabaadbb51a..04d04f57bddf 100644 --- a/Release/test_coverage/PDE/MultiMat/Problem/InterfaceAdvection.cpp.func.html +++ b/Release/test_coverage/PDE/MultiMat/Problem/InterfaceAdvection.cpp.func.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:26:06 + 2024-07-11 14:48:26 Functions: 1 diff --git a/Release/test_coverage/PDE/MultiMat/Problem/InterfaceAdvection.cpp.gcov.html b/Release/test_coverage/PDE/MultiMat/Problem/InterfaceAdvection.cpp.gcov.html index 4abd410d80e1..08fd24c001c9 100644 --- a/Release/test_coverage/PDE/MultiMat/Problem/InterfaceAdvection.cpp.gcov.html +++ b/Release/test_coverage/PDE/MultiMat/Problem/InterfaceAdvection.cpp.gcov.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:26:06 + 2024-07-11 14:48:26 Functions: 1 diff --git a/Release/test_coverage/PDE/MultiMat/Problem/InterfaceAdvection.hpp.func-sort-c.html b/Release/test_coverage/PDE/MultiMat/Problem/InterfaceAdvection.hpp.func-sort-c.html index 95d123303ec8..915c43a62145 100644 --- a/Release/test_coverage/PDE/MultiMat/Problem/InterfaceAdvection.hpp.func-sort-c.html +++ b/Release/test_coverage/PDE/MultiMat/Problem/InterfaceAdvection.hpp.func-sort-c.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:26:06 + 2024-07-11 14:48:26 Functions: 1 diff --git a/Release/test_coverage/PDE/MultiMat/Problem/InterfaceAdvection.hpp.func.html b/Release/test_coverage/PDE/MultiMat/Problem/InterfaceAdvection.hpp.func.html index 23b370a065c6..b9027133fb1f 100644 --- a/Release/test_coverage/PDE/MultiMat/Problem/InterfaceAdvection.hpp.func.html +++ b/Release/test_coverage/PDE/MultiMat/Problem/InterfaceAdvection.hpp.func.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:26:06 + 2024-07-11 14:48:26 Functions: 1 diff --git a/Release/test_coverage/PDE/MultiMat/Problem/InterfaceAdvection.hpp.gcov.html b/Release/test_coverage/PDE/MultiMat/Problem/InterfaceAdvection.hpp.gcov.html index 2c2aca29259a..8e2ade431c81 100644 --- a/Release/test_coverage/PDE/MultiMat/Problem/InterfaceAdvection.hpp.gcov.html +++ b/Release/test_coverage/PDE/MultiMat/Problem/InterfaceAdvection.hpp.gcov.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:26:06 + 2024-07-11 14:48:26 Functions: 1 diff --git a/Release/test_coverage/PDE/MultiMat/Problem/RichtmyerMeshkov.cpp.func-sort-c.html b/Release/test_coverage/PDE/MultiMat/Problem/RichtmyerMeshkov.cpp.func-sort-c.html index 3dfd353bb884..f449c22887ca 100644 --- a/Release/test_coverage/PDE/MultiMat/Problem/RichtmyerMeshkov.cpp.func-sort-c.html +++ b/Release/test_coverage/PDE/MultiMat/Problem/RichtmyerMeshkov.cpp.func-sort-c.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:26:06 + 2024-07-11 14:48:26 Functions: 0 diff --git a/Release/test_coverage/PDE/MultiMat/Problem/RichtmyerMeshkov.cpp.func.html b/Release/test_coverage/PDE/MultiMat/Problem/RichtmyerMeshkov.cpp.func.html index e3fcabd3f849..627dbc9db315 100644 --- a/Release/test_coverage/PDE/MultiMat/Problem/RichtmyerMeshkov.cpp.func.html +++ b/Release/test_coverage/PDE/MultiMat/Problem/RichtmyerMeshkov.cpp.func.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:26:06 + 2024-07-11 14:48:26 Functions: 0 diff --git a/Release/test_coverage/PDE/MultiMat/Problem/RichtmyerMeshkov.cpp.gcov.html b/Release/test_coverage/PDE/MultiMat/Problem/RichtmyerMeshkov.cpp.gcov.html index 866c02ef45a7..9de21ecdbaed 100644 --- a/Release/test_coverage/PDE/MultiMat/Problem/RichtmyerMeshkov.cpp.gcov.html +++ b/Release/test_coverage/PDE/MultiMat/Problem/RichtmyerMeshkov.cpp.gcov.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:26:06 + 2024-07-11 14:48:26 Functions: 0 diff --git a/Release/test_coverage/PDE/MultiMat/Problem/RichtmyerMeshkov.hpp.func-sort-c.html b/Release/test_coverage/PDE/MultiMat/Problem/RichtmyerMeshkov.hpp.func-sort-c.html index 7ee1a732b875..db855668f530 100644 --- a/Release/test_coverage/PDE/MultiMat/Problem/RichtmyerMeshkov.hpp.func-sort-c.html +++ b/Release/test_coverage/PDE/MultiMat/Problem/RichtmyerMeshkov.hpp.func-sort-c.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:26:06 + 2024-07-11 14:48:26 Functions: 0 diff --git a/Release/test_coverage/PDE/MultiMat/Problem/RichtmyerMeshkov.hpp.func.html b/Release/test_coverage/PDE/MultiMat/Problem/RichtmyerMeshkov.hpp.func.html index 19add1cfe4fd..ee09c2521c01 100644 --- a/Release/test_coverage/PDE/MultiMat/Problem/RichtmyerMeshkov.hpp.func.html +++ b/Release/test_coverage/PDE/MultiMat/Problem/RichtmyerMeshkov.hpp.func.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:26:06 + 2024-07-11 14:48:26 Functions: 0 diff --git a/Release/test_coverage/PDE/MultiMat/Problem/RichtmyerMeshkov.hpp.gcov.html b/Release/test_coverage/PDE/MultiMat/Problem/RichtmyerMeshkov.hpp.gcov.html index b1838348dbf6..5232b480459f 100644 --- a/Release/test_coverage/PDE/MultiMat/Problem/RichtmyerMeshkov.hpp.gcov.html +++ b/Release/test_coverage/PDE/MultiMat/Problem/RichtmyerMeshkov.hpp.gcov.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:26:06 + 2024-07-11 14:48:26 Functions: 0 diff --git a/Release/test_coverage/PDE/MultiMat/Problem/ShockDensityWave.cpp.func-sort-c.html b/Release/test_coverage/PDE/MultiMat/Problem/ShockDensityWave.cpp.func-sort-c.html index 5f4601c2662e..5f19e9d6ba9e 100644 --- a/Release/test_coverage/PDE/MultiMat/Problem/ShockDensityWave.cpp.func-sort-c.html +++ b/Release/test_coverage/PDE/MultiMat/Problem/ShockDensityWave.cpp.func-sort-c.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:26:06 + 2024-07-11 14:48:26 Functions: 0 diff --git a/Release/test_coverage/PDE/MultiMat/Problem/ShockDensityWave.cpp.func.html b/Release/test_coverage/PDE/MultiMat/Problem/ShockDensityWave.cpp.func.html index f5aad490b237..e81e1847ab4a 100644 --- a/Release/test_coverage/PDE/MultiMat/Problem/ShockDensityWave.cpp.func.html +++ b/Release/test_coverage/PDE/MultiMat/Problem/ShockDensityWave.cpp.func.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:26:06 + 2024-07-11 14:48:26 Functions: 0 diff --git a/Release/test_coverage/PDE/MultiMat/Problem/ShockDensityWave.cpp.gcov.html b/Release/test_coverage/PDE/MultiMat/Problem/ShockDensityWave.cpp.gcov.html index c4f426743be3..df3019b22606 100644 --- a/Release/test_coverage/PDE/MultiMat/Problem/ShockDensityWave.cpp.gcov.html +++ b/Release/test_coverage/PDE/MultiMat/Problem/ShockDensityWave.cpp.gcov.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:26:06 + 2024-07-11 14:48:26 Functions: 0 diff --git a/Release/test_coverage/PDE/MultiMat/Problem/ShockDensityWave.hpp.func-sort-c.html b/Release/test_coverage/PDE/MultiMat/Problem/ShockDensityWave.hpp.func-sort-c.html index cb3c49d5ff32..31f7d6c9a540 100644 --- a/Release/test_coverage/PDE/MultiMat/Problem/ShockDensityWave.hpp.func-sort-c.html +++ b/Release/test_coverage/PDE/MultiMat/Problem/ShockDensityWave.hpp.func-sort-c.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:26:06 + 2024-07-11 14:48:26 Functions: 0 diff --git a/Release/test_coverage/PDE/MultiMat/Problem/ShockDensityWave.hpp.func.html b/Release/test_coverage/PDE/MultiMat/Problem/ShockDensityWave.hpp.func.html index 03209e1dbf48..800bc00a8201 100644 --- a/Release/test_coverage/PDE/MultiMat/Problem/ShockDensityWave.hpp.func.html +++ b/Release/test_coverage/PDE/MultiMat/Problem/ShockDensityWave.hpp.func.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:26:06 + 2024-07-11 14:48:26 Functions: 0 diff --git a/Release/test_coverage/PDE/MultiMat/Problem/ShockDensityWave.hpp.gcov.html b/Release/test_coverage/PDE/MultiMat/Problem/ShockDensityWave.hpp.gcov.html index eb5e76a0dd97..2a48797d2aa4 100644 --- a/Release/test_coverage/PDE/MultiMat/Problem/ShockDensityWave.hpp.gcov.html +++ b/Release/test_coverage/PDE/MultiMat/Problem/ShockDensityWave.hpp.gcov.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:26:06 + 2024-07-11 14:48:26 Functions: 0 diff --git a/Release/test_coverage/PDE/MultiMat/Problem/ShockHeBubble.cpp.func-sort-c.html b/Release/test_coverage/PDE/MultiMat/Problem/ShockHeBubble.cpp.func-sort-c.html index d3e3cfc56d6e..4f3c28513a93 100644 --- a/Release/test_coverage/PDE/MultiMat/Problem/ShockHeBubble.cpp.func-sort-c.html +++ b/Release/test_coverage/PDE/MultiMat/Problem/ShockHeBubble.cpp.func-sort-c.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:26:06 + 2024-07-11 14:48:26 Functions: 0 diff --git a/Release/test_coverage/PDE/MultiMat/Problem/ShockHeBubble.cpp.func.html b/Release/test_coverage/PDE/MultiMat/Problem/ShockHeBubble.cpp.func.html index 7430e1a53ca4..94145d008928 100644 --- a/Release/test_coverage/PDE/MultiMat/Problem/ShockHeBubble.cpp.func.html +++ b/Release/test_coverage/PDE/MultiMat/Problem/ShockHeBubble.cpp.func.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:26:06 + 2024-07-11 14:48:26 Functions: 0 diff --git a/Release/test_coverage/PDE/MultiMat/Problem/ShockHeBubble.cpp.gcov.html b/Release/test_coverage/PDE/MultiMat/Problem/ShockHeBubble.cpp.gcov.html index fb923599414f..aea54780f51f 100644 --- a/Release/test_coverage/PDE/MultiMat/Problem/ShockHeBubble.cpp.gcov.html +++ b/Release/test_coverage/PDE/MultiMat/Problem/ShockHeBubble.cpp.gcov.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:26:06 + 2024-07-11 14:48:26 Functions: 0 diff --git a/Release/test_coverage/PDE/MultiMat/Problem/ShockHeBubble.hpp.func-sort-c.html b/Release/test_coverage/PDE/MultiMat/Problem/ShockHeBubble.hpp.func-sort-c.html index 68adeac3c618..a6a15445bb07 100644 --- a/Release/test_coverage/PDE/MultiMat/Problem/ShockHeBubble.hpp.func-sort-c.html +++ b/Release/test_coverage/PDE/MultiMat/Problem/ShockHeBubble.hpp.func-sort-c.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:26:06 + 2024-07-11 14:48:26 Functions: 0 diff --git a/Release/test_coverage/PDE/MultiMat/Problem/ShockHeBubble.hpp.func.html b/Release/test_coverage/PDE/MultiMat/Problem/ShockHeBubble.hpp.func.html index 768aee9129fd..7e78b66275c7 100644 --- a/Release/test_coverage/PDE/MultiMat/Problem/ShockHeBubble.hpp.func.html +++ b/Release/test_coverage/PDE/MultiMat/Problem/ShockHeBubble.hpp.func.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:26:06 + 2024-07-11 14:48:26 Functions: 0 diff --git a/Release/test_coverage/PDE/MultiMat/Problem/ShockHeBubble.hpp.gcov.html b/Release/test_coverage/PDE/MultiMat/Problem/ShockHeBubble.hpp.gcov.html index d40b17cae544..35c224a68c3e 100644 --- a/Release/test_coverage/PDE/MultiMat/Problem/ShockHeBubble.hpp.gcov.html +++ b/Release/test_coverage/PDE/MultiMat/Problem/ShockHeBubble.hpp.gcov.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:26:06 + 2024-07-11 14:48:26 Functions: 0 diff --git a/Release/test_coverage/PDE/MultiMat/Problem/SinewavePacket.cpp.func-sort-c.html b/Release/test_coverage/PDE/MultiMat/Problem/SinewavePacket.cpp.func-sort-c.html index ff6835e0222d..c15fa28098ac 100644 --- a/Release/test_coverage/PDE/MultiMat/Problem/SinewavePacket.cpp.func-sort-c.html +++ b/Release/test_coverage/PDE/MultiMat/Problem/SinewavePacket.cpp.func-sort-c.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:26:06 + 2024-07-11 14:48:26 Functions: 0 diff --git a/Release/test_coverage/PDE/MultiMat/Problem/SinewavePacket.cpp.func.html b/Release/test_coverage/PDE/MultiMat/Problem/SinewavePacket.cpp.func.html index bec9492132e9..802b057b3184 100644 --- a/Release/test_coverage/PDE/MultiMat/Problem/SinewavePacket.cpp.func.html +++ b/Release/test_coverage/PDE/MultiMat/Problem/SinewavePacket.cpp.func.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:26:06 + 2024-07-11 14:48:26 Functions: 0 diff --git a/Release/test_coverage/PDE/MultiMat/Problem/SinewavePacket.cpp.gcov.html b/Release/test_coverage/PDE/MultiMat/Problem/SinewavePacket.cpp.gcov.html index 480ba585173b..b58048c0785d 100644 --- a/Release/test_coverage/PDE/MultiMat/Problem/SinewavePacket.cpp.gcov.html +++ b/Release/test_coverage/PDE/MultiMat/Problem/SinewavePacket.cpp.gcov.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:26:06 + 2024-07-11 14:48:26 Functions: 0 diff --git a/Release/test_coverage/PDE/MultiMat/Problem/SinewavePacket.hpp.func-sort-c.html b/Release/test_coverage/PDE/MultiMat/Problem/SinewavePacket.hpp.func-sort-c.html index 07b51e3c2a44..5d12f0cdfa91 100644 --- a/Release/test_coverage/PDE/MultiMat/Problem/SinewavePacket.hpp.func-sort-c.html +++ b/Release/test_coverage/PDE/MultiMat/Problem/SinewavePacket.hpp.func-sort-c.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:26:06 + 2024-07-11 14:48:26 Functions: 0 diff --git a/Release/test_coverage/PDE/MultiMat/Problem/SinewavePacket.hpp.func.html b/Release/test_coverage/PDE/MultiMat/Problem/SinewavePacket.hpp.func.html index 6360a840c86c..1a01e64f4c63 100644 --- a/Release/test_coverage/PDE/MultiMat/Problem/SinewavePacket.hpp.func.html +++ b/Release/test_coverage/PDE/MultiMat/Problem/SinewavePacket.hpp.func.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:26:06 + 2024-07-11 14:48:26 Functions: 0 diff --git a/Release/test_coverage/PDE/MultiMat/Problem/SinewavePacket.hpp.gcov.html b/Release/test_coverage/PDE/MultiMat/Problem/SinewavePacket.hpp.gcov.html index 4d97478275b8..17fba9ed4954 100644 --- a/Release/test_coverage/PDE/MultiMat/Problem/SinewavePacket.hpp.gcov.html +++ b/Release/test_coverage/PDE/MultiMat/Problem/SinewavePacket.hpp.gcov.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:26:06 + 2024-07-11 14:48:26 Functions: 0 diff --git a/Release/test_coverage/PDE/MultiMat/Problem/SodShocktube.cpp.func-sort-c.html b/Release/test_coverage/PDE/MultiMat/Problem/SodShocktube.cpp.func-sort-c.html index 1d125016d3dc..0c6e5d5d40f1 100644 --- a/Release/test_coverage/PDE/MultiMat/Problem/SodShocktube.cpp.func-sort-c.html +++ b/Release/test_coverage/PDE/MultiMat/Problem/SodShocktube.cpp.func-sort-c.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:26:06 + 2024-07-11 14:48:26 Functions: 1 diff --git a/Release/test_coverage/PDE/MultiMat/Problem/SodShocktube.cpp.func.html b/Release/test_coverage/PDE/MultiMat/Problem/SodShocktube.cpp.func.html index 3121abd884f0..cda806f757d9 100644 --- a/Release/test_coverage/PDE/MultiMat/Problem/SodShocktube.cpp.func.html +++ b/Release/test_coverage/PDE/MultiMat/Problem/SodShocktube.cpp.func.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:26:06 + 2024-07-11 14:48:26 Functions: 1 diff --git a/Release/test_coverage/PDE/MultiMat/Problem/SodShocktube.cpp.gcov.html b/Release/test_coverage/PDE/MultiMat/Problem/SodShocktube.cpp.gcov.html index a7c9ad3ad665..80cdb91a98ac 100644 --- a/Release/test_coverage/PDE/MultiMat/Problem/SodShocktube.cpp.gcov.html +++ b/Release/test_coverage/PDE/MultiMat/Problem/SodShocktube.cpp.gcov.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:26:06 + 2024-07-11 14:48:26 Functions: 1 diff --git a/Release/test_coverage/PDE/MultiMat/Problem/SodShocktube.hpp.func-sort-c.html b/Release/test_coverage/PDE/MultiMat/Problem/SodShocktube.hpp.func-sort-c.html index 5c39bd12bd21..acafdb93541e 100644 --- a/Release/test_coverage/PDE/MultiMat/Problem/SodShocktube.hpp.func-sort-c.html +++ b/Release/test_coverage/PDE/MultiMat/Problem/SodShocktube.hpp.func-sort-c.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:26:06 + 2024-07-11 14:48:26 Functions: 1 diff --git a/Release/test_coverage/PDE/MultiMat/Problem/SodShocktube.hpp.func.html b/Release/test_coverage/PDE/MultiMat/Problem/SodShocktube.hpp.func.html index aa6ab6ae124c..2e7ff84943e1 100644 --- a/Release/test_coverage/PDE/MultiMat/Problem/SodShocktube.hpp.func.html +++ b/Release/test_coverage/PDE/MultiMat/Problem/SodShocktube.hpp.func.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:26:06 + 2024-07-11 14:48:26 Functions: 1 diff --git a/Release/test_coverage/PDE/MultiMat/Problem/SodShocktube.hpp.gcov.html b/Release/test_coverage/PDE/MultiMat/Problem/SodShocktube.hpp.gcov.html index 1ee1d22ec054..fb8f86a6f441 100644 --- a/Release/test_coverage/PDE/MultiMat/Problem/SodShocktube.hpp.gcov.html +++ b/Release/test_coverage/PDE/MultiMat/Problem/SodShocktube.hpp.gcov.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:26:06 + 2024-07-11 14:48:26 Functions: 1 diff --git a/Release/test_coverage/PDE/MultiMat/Problem/UnderwaterEx.cpp.func-sort-c.html b/Release/test_coverage/PDE/MultiMat/Problem/UnderwaterEx.cpp.func-sort-c.html index 2e5fab96acb5..bda24dfe068f 100644 --- a/Release/test_coverage/PDE/MultiMat/Problem/UnderwaterEx.cpp.func-sort-c.html +++ b/Release/test_coverage/PDE/MultiMat/Problem/UnderwaterEx.cpp.func-sort-c.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:26:06 + 2024-07-11 14:48:26 Functions: 0 diff --git a/Release/test_coverage/PDE/MultiMat/Problem/UnderwaterEx.cpp.func.html b/Release/test_coverage/PDE/MultiMat/Problem/UnderwaterEx.cpp.func.html index 277b5624b751..406805b43008 100644 --- a/Release/test_coverage/PDE/MultiMat/Problem/UnderwaterEx.cpp.func.html +++ b/Release/test_coverage/PDE/MultiMat/Problem/UnderwaterEx.cpp.func.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:26:06 + 2024-07-11 14:48:26 Functions: 0 diff --git a/Release/test_coverage/PDE/MultiMat/Problem/UnderwaterEx.cpp.gcov.html b/Release/test_coverage/PDE/MultiMat/Problem/UnderwaterEx.cpp.gcov.html index a19a642bfa71..987bdd3f322f 100644 --- a/Release/test_coverage/PDE/MultiMat/Problem/UnderwaterEx.cpp.gcov.html +++ b/Release/test_coverage/PDE/MultiMat/Problem/UnderwaterEx.cpp.gcov.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:26:06 + 2024-07-11 14:48:26 Functions: 0 diff --git a/Release/test_coverage/PDE/MultiMat/Problem/UnderwaterEx.hpp.func-sort-c.html b/Release/test_coverage/PDE/MultiMat/Problem/UnderwaterEx.hpp.func-sort-c.html index af822c849869..29426956c3fe 100644 --- a/Release/test_coverage/PDE/MultiMat/Problem/UnderwaterEx.hpp.func-sort-c.html +++ b/Release/test_coverage/PDE/MultiMat/Problem/UnderwaterEx.hpp.func-sort-c.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:26:06 + 2024-07-11 14:48:26 Functions: 0 diff --git a/Release/test_coverage/PDE/MultiMat/Problem/UnderwaterEx.hpp.func.html b/Release/test_coverage/PDE/MultiMat/Problem/UnderwaterEx.hpp.func.html index 9233045c2e5c..44d09beecf8d 100644 --- a/Release/test_coverage/PDE/MultiMat/Problem/UnderwaterEx.hpp.func.html +++ b/Release/test_coverage/PDE/MultiMat/Problem/UnderwaterEx.hpp.func.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:26:06 + 2024-07-11 14:48:26 Functions: 0 diff --git a/Release/test_coverage/PDE/MultiMat/Problem/UnderwaterEx.hpp.gcov.html b/Release/test_coverage/PDE/MultiMat/Problem/UnderwaterEx.hpp.gcov.html index 9d2f6cd59daa..10625728a724 100644 --- a/Release/test_coverage/PDE/MultiMat/Problem/UnderwaterEx.hpp.gcov.html +++ b/Release/test_coverage/PDE/MultiMat/Problem/UnderwaterEx.hpp.gcov.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:26:06 + 2024-07-11 14:48:26 Functions: 0 diff --git a/Release/test_coverage/PDE/MultiMat/Problem/UserDefined.cpp.func-sort-c.html b/Release/test_coverage/PDE/MultiMat/Problem/UserDefined.cpp.func-sort-c.html index 5435a64f6672..130dbbeac783 100644 --- a/Release/test_coverage/PDE/MultiMat/Problem/UserDefined.cpp.func-sort-c.html +++ b/Release/test_coverage/PDE/MultiMat/Problem/UserDefined.cpp.func-sort-c.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:26:06 + 2024-07-11 14:48:26 Functions: 1 diff --git a/Release/test_coverage/PDE/MultiMat/Problem/UserDefined.cpp.func.html b/Release/test_coverage/PDE/MultiMat/Problem/UserDefined.cpp.func.html index 200ea5f17133..05881b99f067 100644 --- a/Release/test_coverage/PDE/MultiMat/Problem/UserDefined.cpp.func.html +++ b/Release/test_coverage/PDE/MultiMat/Problem/UserDefined.cpp.func.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:26:06 + 2024-07-11 14:48:26 Functions: 1 diff --git a/Release/test_coverage/PDE/MultiMat/Problem/UserDefined.cpp.gcov.html b/Release/test_coverage/PDE/MultiMat/Problem/UserDefined.cpp.gcov.html index 964d9f6fb72e..8085ce157482 100644 --- a/Release/test_coverage/PDE/MultiMat/Problem/UserDefined.cpp.gcov.html +++ b/Release/test_coverage/PDE/MultiMat/Problem/UserDefined.cpp.gcov.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:26:06 + 2024-07-11 14:48:26 Functions: 1 diff --git a/Release/test_coverage/PDE/MultiMat/Problem/UserDefined.hpp.func-sort-c.html b/Release/test_coverage/PDE/MultiMat/Problem/UserDefined.hpp.func-sort-c.html index 1fafb16a03c7..0e5dbc340eb2 100644 --- a/Release/test_coverage/PDE/MultiMat/Problem/UserDefined.hpp.func-sort-c.html +++ b/Release/test_coverage/PDE/MultiMat/Problem/UserDefined.hpp.func-sort-c.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:26:06 + 2024-07-11 14:48:26 Functions: 1 diff --git a/Release/test_coverage/PDE/MultiMat/Problem/UserDefined.hpp.func.html b/Release/test_coverage/PDE/MultiMat/Problem/UserDefined.hpp.func.html index e3b3698630fc..ca3e2426107f 100644 --- a/Release/test_coverage/PDE/MultiMat/Problem/UserDefined.hpp.func.html +++ b/Release/test_coverage/PDE/MultiMat/Problem/UserDefined.hpp.func.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:26:06 + 2024-07-11 14:48:26 Functions: 1 diff --git a/Release/test_coverage/PDE/MultiMat/Problem/UserDefined.hpp.gcov.html b/Release/test_coverage/PDE/MultiMat/Problem/UserDefined.hpp.gcov.html index 2450fe175b6b..f1d53acd81d4 100644 --- a/Release/test_coverage/PDE/MultiMat/Problem/UserDefined.hpp.gcov.html +++ b/Release/test_coverage/PDE/MultiMat/Problem/UserDefined.hpp.gcov.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:26:06 + 2024-07-11 14:48:26 Functions: 1 diff --git a/Release/test_coverage/PDE/MultiMat/Problem/WaterAirShocktube.cpp.func-sort-c.html b/Release/test_coverage/PDE/MultiMat/Problem/WaterAirShocktube.cpp.func-sort-c.html index 44fb1f5ce2e1..3392ffe5a83d 100644 --- a/Release/test_coverage/PDE/MultiMat/Problem/WaterAirShocktube.cpp.func-sort-c.html +++ b/Release/test_coverage/PDE/MultiMat/Problem/WaterAirShocktube.cpp.func-sort-c.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:26:06 + 2024-07-11 14:48:26 Functions: 1 diff --git a/Release/test_coverage/PDE/MultiMat/Problem/WaterAirShocktube.cpp.func.html b/Release/test_coverage/PDE/MultiMat/Problem/WaterAirShocktube.cpp.func.html index b753db18a92e..8e3a7b22e630 100644 --- a/Release/test_coverage/PDE/MultiMat/Problem/WaterAirShocktube.cpp.func.html +++ b/Release/test_coverage/PDE/MultiMat/Problem/WaterAirShocktube.cpp.func.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:26:06 + 2024-07-11 14:48:26 Functions: 1 diff --git a/Release/test_coverage/PDE/MultiMat/Problem/WaterAirShocktube.cpp.gcov.html b/Release/test_coverage/PDE/MultiMat/Problem/WaterAirShocktube.cpp.gcov.html index 92977d672834..8ed72af9c492 100644 --- a/Release/test_coverage/PDE/MultiMat/Problem/WaterAirShocktube.cpp.gcov.html +++ b/Release/test_coverage/PDE/MultiMat/Problem/WaterAirShocktube.cpp.gcov.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:26:06 + 2024-07-11 14:48:26 Functions: 1 diff --git a/Release/test_coverage/PDE/MultiMat/Problem/WaterAirShocktube.hpp.func-sort-c.html b/Release/test_coverage/PDE/MultiMat/Problem/WaterAirShocktube.hpp.func-sort-c.html index d31ac5e96e7a..7abf20a5caed 100644 --- a/Release/test_coverage/PDE/MultiMat/Problem/WaterAirShocktube.hpp.func-sort-c.html +++ b/Release/test_coverage/PDE/MultiMat/Problem/WaterAirShocktube.hpp.func-sort-c.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:26:06 + 2024-07-11 14:48:26 Functions: 1 diff --git a/Release/test_coverage/PDE/MultiMat/Problem/WaterAirShocktube.hpp.func.html b/Release/test_coverage/PDE/MultiMat/Problem/WaterAirShocktube.hpp.func.html index 63fad3b8f900..88bb3cd33b58 100644 --- a/Release/test_coverage/PDE/MultiMat/Problem/WaterAirShocktube.hpp.func.html +++ b/Release/test_coverage/PDE/MultiMat/Problem/WaterAirShocktube.hpp.func.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:26:06 + 2024-07-11 14:48:26 Functions: 1 diff --git a/Release/test_coverage/PDE/MultiMat/Problem/WaterAirShocktube.hpp.gcov.html b/Release/test_coverage/PDE/MultiMat/Problem/WaterAirShocktube.hpp.gcov.html index 575fb133123e..63f98dd82a93 100644 --- a/Release/test_coverage/PDE/MultiMat/Problem/WaterAirShocktube.hpp.gcov.html +++ b/Release/test_coverage/PDE/MultiMat/Problem/WaterAirShocktube.hpp.gcov.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:26:06 + 2024-07-11 14:48:26 Functions: 1 diff --git a/Release/test_coverage/PDE/MultiMat/Problem/index-sort-b.html b/Release/test_coverage/PDE/MultiMat/Problem/index-sort-b.html index 71995057c53e..778bdef55b4e 100644 --- a/Release/test_coverage/PDE/MultiMat/Problem/index-sort-b.html +++ b/Release/test_coverage/PDE/MultiMat/Problem/index-sort-b.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:26:06 + 2024-07-11 14:48:26 Functions: 13 @@ -106,7 +106,7 @@ 0 / 2 - ShockHeBubble.hpp + SinewavePacket.hpp
0.0%
@@ -118,7 +118,7 @@ 0 / 2 - SinewavePacket.hpp + UnderwaterEx.hpp
0.0%
@@ -130,7 +130,7 @@ 0 / 2 - UnderwaterEx.hpp + ShockHeBubble.hpp
0.0%
@@ -190,24 +190,24 @@ 0 / 12 - UnderwaterEx.cpp + ShockHeBubble.cpp
0.0%
0.0 % - 0 / 33 + 0 / 29 0.0 % 0 / 1 0.0 % 0 / 22 - ShockHeBubble.cpp + UnderwaterEx.cpp
0.0%
0.0 % - 0 / 29 + 0 / 33 0.0 % 0 / 1 0.0 % diff --git a/Release/test_coverage/PDE/MultiMat/Problem/index-sort-f.html b/Release/test_coverage/PDE/MultiMat/Problem/index-sort-f.html index 0fb1fc98400d..a1367e326965 100644 --- a/Release/test_coverage/PDE/MultiMat/Problem/index-sort-f.html +++ b/Release/test_coverage/PDE/MultiMat/Problem/index-sort-f.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:26:06 + 2024-07-11 14:48:26 Functions: 13 @@ -82,16 +82,16 @@ Branches Sort by branch coverage - UnderwaterEx.cpp + ShockDensityWave.hpp
0.0%
0.0 % - 0 / 33 + 0 / 5 0.0 % 0 / 1 0.0 % - 0 / 22 + 0 / 2 SinewavePacket.cpp @@ -106,19 +106,19 @@ 0 / 6 - RichtmyerMeshkov.cpp + ShockHeBubble.cpp
0.0%
0.0 % - 0 / 26 + 0 / 29 0.0 % 0 / 1 0.0 % - 0 / 12 + 0 / 22 - ShockDensityWave.hpp + RichtmyerMeshkov.hpp
0.0%
@@ -130,79 +130,79 @@ 0 / 2 - EquilInterfaceAdvect.hpp + EquilInterfaceAdvect.cpp
0.0%
0.0 % - 0 / 17 + 0 / 24 0.0 % 0 / 1 0.0 % - 0 / 8 + 0 / 10 - RichtmyerMeshkov.hpp + RichtmyerMeshkov.cpp
0.0%
0.0 % - 0 / 5 + 0 / 26 0.0 % 0 / 1 0.0 % - 0 / 2 + 0 / 12 - ShockDensityWave.cpp + SinewavePacket.hpp
0.0%
0.0 % - 0 / 32 + 0 / 5 0.0 % 0 / 1 0.0 % - 0 / 26 + 0 / 2 - ShockHeBubble.hpp + UnderwaterEx.cpp
0.0%
0.0 % - 0 / 5 + 0 / 33 0.0 % 0 / 1 0.0 % - 0 / 2 + 0 / 22 - SinewavePacket.hpp + ShockDensityWave.cpp
0.0%
0.0 % - 0 / 5 + 0 / 32 0.0 % 0 / 1 0.0 % - 0 / 2 + 0 / 26 - EquilInterfaceAdvect.cpp + UnderwaterEx.hpp
0.0%
0.0 % - 0 / 24 + 0 / 5 0.0 % 0 / 1 0.0 % - 0 / 10 + 0 / 2 - UnderwaterEx.hpp + ShockHeBubble.hpp
0.0%
@@ -214,16 +214,16 @@ 0 / 2 - ShockHeBubble.cpp + EquilInterfaceAdvect.hpp
0.0%
0.0 % - 0 / 29 + 0 / 17 0.0 % 0 / 1 0.0 % - 0 / 22 + 0 / 8 BoxInitialization.hpp @@ -262,31 +262,31 @@ 2 / 2 - UserDefined.cpp + WaterAirShocktube.hpp -
80.6%80.6%
+
80.0%80.0%
- 80.6 % - 25 / 31 + 80.0 % + 4 / 5 100.0 % 1 / 1 - 22.7 % - 15 / 66 + 100.0 % + 2 / 2 - InterfaceAdvection.cpp + UserDefined.cpp -
93.8%93.8%
+
80.6%80.6%
- 93.8 % - 30 / 32 + 80.6 % + 25 / 31 100.0 % 1 / 1 - 55.9 % - 19 / 34 + 22.7 % + 15 / 66 - WaterAirShocktube.hpp + UserDefined.hpp
80.0%80.0%
@@ -298,16 +298,16 @@ 2 / 2 - UserDefined.hpp + SodShocktube.cpp -
80.0%80.0%
+
100.0%
- 80.0 % - 4 / 5 100.0 % - 1 / 1 + 25 / 25 100.0 % - 2 / 2 + 1 / 1 + 58.3 % + 7 / 12 WaterAirShocktube.cpp @@ -334,16 +334,16 @@ 2 / 2 - SodShocktube.cpp + InterfaceAdvection.cpp -
100.0%
+
93.8%93.8%
- 100.0 % - 25 / 25 + 93.8 % + 30 / 32 100.0 % 1 / 1 - 58.3 % - 7 / 12 + 55.9 % + 19 / 34 diff --git a/Release/test_coverage/PDE/MultiMat/Problem/index-sort-l.html b/Release/test_coverage/PDE/MultiMat/Problem/index-sort-l.html index c9bbae98932f..111f2a4d6564 100644 --- a/Release/test_coverage/PDE/MultiMat/Problem/index-sort-l.html +++ b/Release/test_coverage/PDE/MultiMat/Problem/index-sort-l.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:26:06 + 2024-07-11 14:48:26 Functions: 13 @@ -106,7 +106,7 @@ 0 / 2 - ShockHeBubble.hpp + SinewavePacket.hpp
0.0%
@@ -118,7 +118,7 @@ 0 / 2 - SinewavePacket.hpp + UnderwaterEx.hpp
0.0%
@@ -130,7 +130,7 @@ 0 / 2 - UnderwaterEx.hpp + ShockHeBubble.hpp
0.0%
@@ -322,7 +322,7 @@ 19 / 34 - WaterAirShocktube.cpp + SodShocktube.cpp
100.0%
@@ -330,11 +330,11 @@ 25 / 25 100.0 % 1 / 1 - 59.1 % - 13 / 22 + 58.3 % + 7 / 12 - SodShocktube.cpp + WaterAirShocktube.cpp
100.0%
@@ -342,8 +342,8 @@ 25 / 25 100.0 % 1 / 1 - 58.3 % - 7 / 12 + 59.1 % + 13 / 22 diff --git a/Release/test_coverage/PDE/MultiMat/Problem/index.html b/Release/test_coverage/PDE/MultiMat/Problem/index.html index f438e3519518..0b2aaff7bdd1 100644 --- a/Release/test_coverage/PDE/MultiMat/Problem/index.html +++ b/Release/test_coverage/PDE/MultiMat/Problem/index.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:26:06 + 2024-07-11 14:48:26 Functions: 13 diff --git a/Release/test_coverage/PDE/MultiMat/RiemannChoice.hpp.func-sort-c.html b/Release/test_coverage/PDE/MultiMat/RiemannChoice.hpp.func-sort-c.html index 0650e2401ac0..1f250335eef1 100644 --- a/Release/test_coverage/PDE/MultiMat/RiemannChoice.hpp.func-sort-c.html +++ b/Release/test_coverage/PDE/MultiMat/RiemannChoice.hpp.func-sort-c.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:26:06 + 2024-07-11 14:48:26 Functions: 1 diff --git a/Release/test_coverage/PDE/MultiMat/RiemannChoice.hpp.func.html b/Release/test_coverage/PDE/MultiMat/RiemannChoice.hpp.func.html index b0c1c3ddb9ff..6a065ad4cd1e 100644 --- a/Release/test_coverage/PDE/MultiMat/RiemannChoice.hpp.func.html +++ b/Release/test_coverage/PDE/MultiMat/RiemannChoice.hpp.func.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:26:06 + 2024-07-11 14:48:26 Functions: 1 diff --git a/Release/test_coverage/PDE/MultiMat/RiemannChoice.hpp.gcov.html b/Release/test_coverage/PDE/MultiMat/RiemannChoice.hpp.gcov.html index 22666e6929d3..3a3ad7022238 100644 --- a/Release/test_coverage/PDE/MultiMat/RiemannChoice.hpp.gcov.html +++ b/Release/test_coverage/PDE/MultiMat/RiemannChoice.hpp.gcov.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:26:06 + 2024-07-11 14:48:26 Functions: 1 diff --git a/Release/test_coverage/PDE/MultiMat/index-sort-b.html b/Release/test_coverage/PDE/MultiMat/index-sort-b.html index 00ad8f5b594d..317dc35e2f96 100644 --- a/Release/test_coverage/PDE/MultiMat/index-sort-b.html +++ b/Release/test_coverage/PDE/MultiMat/index-sort-b.html @@ -27,18 +27,18 @@ -128-NOTFOUND Lines: - 574 + 578 925 - 62.1 % + 62.5 % Date: - 2024-07-10 11:26:06 + 2024-07-11 14:48:26 Functions: - 66 + 67 574 - 11.5 % + 11.7 % Legend: @@ -49,7 +49,7 @@ Branches: - 509 + 510 1968 25.9 % @@ -144,14 +144,14 @@ MiscMultiMatFns.cpp -
84.8%84.8%
+
86.5%86.5%
- 84.8 % - 201 / 237 - 80.0 % - 8 / 10 - 56.5 % - 148 / 262 + 86.5 % + 205 / 237 + 90.0 % + 9 / 10 + 56.9 % + 149 / 262 diff --git a/Release/test_coverage/PDE/MultiMat/index-sort-f.html b/Release/test_coverage/PDE/MultiMat/index-sort-f.html index 008b14f3dc68..c448984b09fe 100644 --- a/Release/test_coverage/PDE/MultiMat/index-sort-f.html +++ b/Release/test_coverage/PDE/MultiMat/index-sort-f.html @@ -27,18 +27,18 @@ -128-NOTFOUND Lines: - 574 + 578 925 - 62.1 % + 62.5 % Date: - 2024-07-10 11:26:06 + 2024-07-11 14:48:26 Functions: - 66 + 67 574 - 11.5 % + 11.7 % Legend: @@ -49,7 +49,7 @@ Branches: - 509 + 510 1968 25.9 % @@ -120,14 +120,14 @@ MiscMultiMatFns.cpp -
84.8%84.8%
+
86.5%86.5%
- 84.8 % - 201 / 237 - 80.0 % - 8 / 10 - 56.5 % - 148 / 262 + 86.5 % + 205 / 237 + 90.0 % + 9 / 10 + 56.9 % + 149 / 262 MultiMatIndexing.hpp diff --git a/Release/test_coverage/PDE/MultiMat/index-sort-l.html b/Release/test_coverage/PDE/MultiMat/index-sort-l.html index 392eef91eb40..69e126449a26 100644 --- a/Release/test_coverage/PDE/MultiMat/index-sort-l.html +++ b/Release/test_coverage/PDE/MultiMat/index-sort-l.html @@ -27,18 +27,18 @@ -128-NOTFOUND Lines: - 574 + 578 925 - 62.1 % + 62.5 % Date: - 2024-07-10 11:26:06 + 2024-07-11 14:48:26 Functions: - 66 + 67 574 - 11.5 % + 11.7 % Legend: @@ -49,7 +49,7 @@ Branches: - 509 + 510 1968 25.9 % @@ -144,14 +144,14 @@ MiscMultiMatFns.cpp -
84.8%84.8%
+
86.5%86.5%
- 84.8 % - 201 / 237 - 80.0 % - 8 / 10 - 56.5 % - 148 / 262 + 86.5 % + 205 / 237 + 90.0 % + 9 / 10 + 56.9 % + 149 / 262 diff --git a/Release/test_coverage/PDE/MultiMat/index.html b/Release/test_coverage/PDE/MultiMat/index.html index fa0ca8fb2f16..e337638c304f 100644 --- a/Release/test_coverage/PDE/MultiMat/index.html +++ b/Release/test_coverage/PDE/MultiMat/index.html @@ -27,18 +27,18 @@ -128-NOTFOUND Lines: - 574 + 578 925 - 62.1 % + 62.5 % Date: - 2024-07-10 11:26:06 + 2024-07-11 14:48:26 Functions: - 66 + 67 574 - 11.5 % + 11.7 % Legend: @@ -49,7 +49,7 @@ Branches: - 509 + 510 1968 25.9 % @@ -120,14 +120,14 @@ MiscMultiMatFns.cpp -
84.8%84.8%
+
86.5%86.5%
- 84.8 % - 201 / 237 - 80.0 % - 8 / 10 - 56.5 % - 148 / 262 + 86.5 % + 205 / 237 + 90.0 % + 9 / 10 + 56.9 % + 149 / 262 MultiMatIndexing.hpp diff --git a/Release/test_coverage/PDE/PDEFactory.hpp.func-sort-c.html b/Release/test_coverage/PDE/PDEFactory.hpp.func-sort-c.html index f4c73680f686..ff3540084d4f 100644 --- a/Release/test_coverage/PDE/PDEFactory.hpp.func-sort-c.html +++ b/Release/test_coverage/PDE/PDEFactory.hpp.func-sort-c.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:26:06 + 2024-07-11 14:48:26 Functions: 0 diff --git a/Release/test_coverage/PDE/PDEFactory.hpp.func.html b/Release/test_coverage/PDE/PDEFactory.hpp.func.html index ea9fc76df4a8..e31bcc87a247 100644 --- a/Release/test_coverage/PDE/PDEFactory.hpp.func.html +++ b/Release/test_coverage/PDE/PDEFactory.hpp.func.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:26:06 + 2024-07-11 14:48:26 Functions: 0 diff --git a/Release/test_coverage/PDE/PDEFactory.hpp.gcov.html b/Release/test_coverage/PDE/PDEFactory.hpp.gcov.html index b503174d3e90..08642387b198 100644 --- a/Release/test_coverage/PDE/PDEFactory.hpp.gcov.html +++ b/Release/test_coverage/PDE/PDEFactory.hpp.gcov.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:26:06 + 2024-07-11 14:48:26 Functions: 0 diff --git a/Release/test_coverage/PDE/PDEStack.cpp.func-sort-c.html b/Release/test_coverage/PDE/PDEStack.cpp.func-sort-c.html index b43c53d1d311..29561ef6a7f3 100644 --- a/Release/test_coverage/PDE/PDEStack.cpp.func-sort-c.html +++ b/Release/test_coverage/PDE/PDEStack.cpp.func-sort-c.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:26:06 + 2024-07-11 14:48:26 Functions: 5 diff --git a/Release/test_coverage/PDE/PDEStack.cpp.func.html b/Release/test_coverage/PDE/PDEStack.cpp.func.html index 21fe2bc021e1..455d0ead9096 100644 --- a/Release/test_coverage/PDE/PDEStack.cpp.func.html +++ b/Release/test_coverage/PDE/PDEStack.cpp.func.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:26:06 + 2024-07-11 14:48:26 Functions: 5 diff --git a/Release/test_coverage/PDE/PDEStack.cpp.gcov.html b/Release/test_coverage/PDE/PDEStack.cpp.gcov.html index d4a3b72e0198..4b6f489d7ce4 100644 --- a/Release/test_coverage/PDE/PDEStack.cpp.gcov.html +++ b/Release/test_coverage/PDE/PDEStack.cpp.gcov.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:26:06 + 2024-07-11 14:48:26 Functions: 5 diff --git a/Release/test_coverage/PDE/PDEStack.hpp.func-sort-c.html b/Release/test_coverage/PDE/PDEStack.hpp.func-sort-c.html index 7b1e03282a87..038a04cfc2cf 100644 --- a/Release/test_coverage/PDE/PDEStack.hpp.func-sort-c.html +++ b/Release/test_coverage/PDE/PDEStack.hpp.func-sort-c.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:26:06 + 2024-07-11 14:48:26 Functions: 6 diff --git a/Release/test_coverage/PDE/PDEStack.hpp.func.html b/Release/test_coverage/PDE/PDEStack.hpp.func.html index 84388536a0da..83b849b06e41 100644 --- a/Release/test_coverage/PDE/PDEStack.hpp.func.html +++ b/Release/test_coverage/PDE/PDEStack.hpp.func.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:26:06 + 2024-07-11 14:48:26 Functions: 6 diff --git a/Release/test_coverage/PDE/PDEStack.hpp.gcov.html b/Release/test_coverage/PDE/PDEStack.hpp.gcov.html index 5df2a6d35ec6..59f0a4369393 100644 --- a/Release/test_coverage/PDE/PDEStack.hpp.gcov.html +++ b/Release/test_coverage/PDE/PDEStack.hpp.gcov.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:26:06 + 2024-07-11 14:48:26 Functions: 6 diff --git a/Release/test_coverage/PDE/PrefIndicator.cpp.func-sort-c.html b/Release/test_coverage/PDE/PrefIndicator.cpp.func-sort-c.html index 6ab443d6691f..7e9a84b4bcc2 100644 --- a/Release/test_coverage/PDE/PrefIndicator.cpp.func-sort-c.html +++ b/Release/test_coverage/PDE/PrefIndicator.cpp.func-sort-c.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:26:06 + 2024-07-11 14:48:26 Functions: 2 diff --git a/Release/test_coverage/PDE/PrefIndicator.cpp.func.html b/Release/test_coverage/PDE/PrefIndicator.cpp.func.html index b7b67fb0dc28..67d26bcbe898 100644 --- a/Release/test_coverage/PDE/PrefIndicator.cpp.func.html +++ b/Release/test_coverage/PDE/PrefIndicator.cpp.func.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:26:06 + 2024-07-11 14:48:26 Functions: 2 diff --git a/Release/test_coverage/PDE/PrefIndicator.cpp.gcov.html b/Release/test_coverage/PDE/PrefIndicator.cpp.gcov.html index 508842c206a4..6db9639a31de 100644 --- a/Release/test_coverage/PDE/PrefIndicator.cpp.gcov.html +++ b/Release/test_coverage/PDE/PrefIndicator.cpp.gcov.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:26:06 + 2024-07-11 14:48:26 Functions: 2 diff --git a/Release/test_coverage/PDE/Reconstruction.cpp.func-sort-c.html b/Release/test_coverage/PDE/Reconstruction.cpp.func-sort-c.html index 9d22e5087587..9ef58f4de7fa 100644 --- a/Release/test_coverage/PDE/Reconstruction.cpp.func-sort-c.html +++ b/Release/test_coverage/PDE/Reconstruction.cpp.func-sort-c.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:26:06 + 2024-07-11 14:48:26 Functions: 10 diff --git a/Release/test_coverage/PDE/Reconstruction.cpp.func.html b/Release/test_coverage/PDE/Reconstruction.cpp.func.html index 06a85e525396..016f9664fb2f 100644 --- a/Release/test_coverage/PDE/Reconstruction.cpp.func.html +++ b/Release/test_coverage/PDE/Reconstruction.cpp.func.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:26:06 + 2024-07-11 14:48:26 Functions: 10 diff --git a/Release/test_coverage/PDE/Reconstruction.cpp.gcov.html b/Release/test_coverage/PDE/Reconstruction.cpp.gcov.html index 531a78e3a5a7..c6b720d2dc55 100644 --- a/Release/test_coverage/PDE/Reconstruction.cpp.gcov.html +++ b/Release/test_coverage/PDE/Reconstruction.cpp.gcov.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:26:06 + 2024-07-11 14:48:26 Functions: 10 diff --git a/Release/test_coverage/PDE/Riemann/AUSM.hpp.func-sort-c.html b/Release/test_coverage/PDE/Riemann/AUSM.hpp.func-sort-c.html index 6ccc687cd3c8..b69be93ab970 100644 --- a/Release/test_coverage/PDE/Riemann/AUSM.hpp.func-sort-c.html +++ b/Release/test_coverage/PDE/Riemann/AUSM.hpp.func-sort-c.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:26:06 + 2024-07-11 14:48:26 Functions: 2 diff --git a/Release/test_coverage/PDE/Riemann/AUSM.hpp.func.html b/Release/test_coverage/PDE/Riemann/AUSM.hpp.func.html index e9aa646cbc8e..4271620329ae 100644 --- a/Release/test_coverage/PDE/Riemann/AUSM.hpp.func.html +++ b/Release/test_coverage/PDE/Riemann/AUSM.hpp.func.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:26:06 + 2024-07-11 14:48:26 Functions: 2 diff --git a/Release/test_coverage/PDE/Riemann/AUSM.hpp.gcov.html b/Release/test_coverage/PDE/Riemann/AUSM.hpp.gcov.html index 4cb0b7f3e294..7ef2fb5e7c9d 100644 --- a/Release/test_coverage/PDE/Riemann/AUSM.hpp.gcov.html +++ b/Release/test_coverage/PDE/Riemann/AUSM.hpp.gcov.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:26:06 + 2024-07-11 14:48:26 Functions: 2 @@ -233,20 +233,20 @@ 156 : 8054891 : l_minus = l_minus/( std::fabs(vriem) + 1.0e-12 ); 157 : : 158 : : // Store Riemann-advected partial pressures - 159 [ + + ]: 8054891 : if (std::fabs(l_plus) > 1.0e-10) + 159 [ + + ]: 8054891 : if (std::fabs(l_plus) > 1.0e-10) 160 : : { - 161 [ + + ]: 9044687 : for (std::size_t k=0; k<nmat; ++k) - 162 [ + - ]: 6367191 : flx.push_back( pml[k] ); + 161 [ + + ]: 9066592 : for (std::size_t k=0; k<nmat; ++k) + 162 [ + - ]: 6383027 : flx.push_back( pml[k] ); 163 : : } - 164 [ + + ]: 5377395 : else if (std::fabs(l_minus) > 1.0e-10) + 164 [ + + ]: 5371326 : else if (std::fabs(l_minus) > 1.0e-10) 165 : : { - 166 [ + + ]: 9084558 : for (std::size_t k=0; k<nmat; ++k) - 167 [ + - ]: 6405603 : flx.push_back( pmr[k] ); + 166 [ + + ]: 9066732 : for (std::size_t k=0; k<nmat; ++k) + 167 [ + - ]: 6392483 : flx.push_back( pmr[k] ); 168 : : } 169 : : else 170 : : { - 171 [ + + ]: 8730494 : for (std::size_t k=0; k<nmat; ++k) - 172 [ + - ][ - - ]: 6032054 : flx.push_back( 0.5*(pml[k] + pmr[k]) ); + 171 [ + + ]: 8726415 : for (std::size_t k=0; k<nmat; ++k) + 172 [ + - ][ - - ]: 6029338 : flx.push_back( 0.5*(pml[k] + pmr[k]) ); 173 : : } 174 : : 175 : : // Store Riemann velocity diff --git a/Release/test_coverage/PDE/Riemann/HLL.hpp.func-sort-c.html b/Release/test_coverage/PDE/Riemann/HLL.hpp.func-sort-c.html index b5ded443b954..5510bc74b2de 100644 --- a/Release/test_coverage/PDE/Riemann/HLL.hpp.func-sort-c.html +++ b/Release/test_coverage/PDE/Riemann/HLL.hpp.func-sort-c.html @@ -27,13 +27,13 @@ -128-NOTFOUND Lines: - 61 - 65 - 93.8 % + 82 + 98 + 83.7 % Date: - 2024-07-10 11:26:06 + 2024-07-11 14:48:26 Functions: 1 @@ -52,9 +52,9 @@ Branches: - 33 - 74 - 44.6 % + 57 + 116 + 49.1 % diff --git a/Release/test_coverage/PDE/Riemann/HLL.hpp.func.html b/Release/test_coverage/PDE/Riemann/HLL.hpp.func.html index 14ae8785504e..c930b642b8f7 100644 --- a/Release/test_coverage/PDE/Riemann/HLL.hpp.func.html +++ b/Release/test_coverage/PDE/Riemann/HLL.hpp.func.html @@ -27,13 +27,13 @@ -128-NOTFOUND Lines: - 61 - 65 - 93.8 % + 82 + 98 + 83.7 % Date: - 2024-07-10 11:26:06 + 2024-07-11 14:48:26 Functions: 1 @@ -52,9 +52,9 @@ Branches: - 33 - 74 - 44.6 % + 57 + 116 + 49.1 % diff --git a/Release/test_coverage/PDE/Riemann/HLL.hpp.gcov.html b/Release/test_coverage/PDE/Riemann/HLL.hpp.gcov.html index d51575844a79..0b688a813c76 100644 --- a/Release/test_coverage/PDE/Riemann/HLL.hpp.gcov.html +++ b/Release/test_coverage/PDE/Riemann/HLL.hpp.gcov.html @@ -27,13 +27,13 @@ -128-NOTFOUND Lines: - 61 - 65 - 93.8 % + 82 + 98 + 83.7 % Date: - 2024-07-10 11:26:06 + 2024-07-11 14:48:26 Functions: 1 @@ -52,9 +52,9 @@ Branches: - 33 - 74 - 44.6 % + 57 + 116 + 49.1 % @@ -112,136 +112,211 @@ 38 : : const std::vector< std::array< tk::real, 3 > >& ) 39 : : { 40 : 171500 : auto nmat = g_inputdeck.get< tag::multimat, tag::nmat >(); - 41 : : - 42 : 171500 : auto ncomp = u[0].size()-(3+nmat); - 43 [ + - ][ + - ]: 171500 : std::vector< tk::real > flx(ncomp, 0), fl(ncomp, 0), fr(ncomp, 0); + 41 : : const auto& solidx = g_inputdeck.get< tag::matidxmap, tag::solidx >(); + 42 : : + 43 : 171500 : auto nsld = numSolids(nmat, solidx); + 44 : 171500 : auto ncomp = u[0].size()-(3+nmat+nsld*6); + 45 [ + - ][ + - ]: 171500 : std::vector< tk::real > flx(ncomp, 0), fl(ncomp, 0), fr(ncomp, 0); [ - - ][ - - ] - 44 : : - 45 : : // Primitive quantities - 46 : : tk::real rhol(0.0), rhor(0.0); - 47 : : tk::real pl(0.0), pr(0.0), amatl(0.0), amatr(0.0), ac_l(0.0), ac_r(0.0); - 48 [ + - ][ + - ]: 171500 : std::vector< tk::real > al_l(nmat, 0.0), al_r(nmat, 0.0), + 46 : : + 47 : : // Primitive quantities + 48 : : tk::real rhol(0.0), rhor(0.0); + 49 : : tk::real amatl(0.0), amatr(0.0), ac_l(0.0), ac_r(0.0); + 50 [ + - ][ + - ]: 171500 : std::vector< tk::real > al_l(nmat, 0.0), al_r(nmat, 0.0), [ - - ][ - - ] - 49 [ + - ][ + - ]: 171500 : hml(nmat, 0.0), hmr(nmat, 0.0), + 51 [ + - ][ + - ]: 171500 : pml(nmat, 0.0), pmr(nmat, 0.0); [ - - ][ - - ] - 50 [ + - ][ + - ]: 171500 : pml(nmat, 0.0), pmr(nmat, 0.0); - [ - - ][ - - ] - 51 [ + + ]: 514500 : for (std::size_t k=0; k<nmat; ++k) - 52 : : { - 53 [ + - ]: 343000 : al_l[k] = u[0][volfracIdx(nmat, k)]; - 54 : 343000 : pml[k] = u[0][ncomp+pressureIdx(nmat, k)]; - 55 [ + - ]: 343000 : pl += pml[k]; - 56 : 343000 : hml[k] = u[0][energyIdx(nmat, k)] + pml[k]; - 57 [ + - ]: 343000 : amatl = mat_blk[k].compute< EOS::soundspeed >( - 58 : : u[0][densityIdx(nmat, k)], pml[k], al_l[k], k ); - 59 [ + - ]: 343000 : rhol += u[0][densityIdx(nmat, k)]; - 60 : : - 61 [ + - ]: 343000 : al_r[k] = u[1][volfracIdx(nmat, k)]; - 62 : 343000 : pmr[k] = u[1][ncomp+pressureIdx(nmat, k)]; - 63 [ + - ]: 343000 : pr += pmr[k]; - 64 : 343000 : hmr[k] = u[1][energyIdx(nmat, k)] + pmr[k]; - 65 [ + - ]: 343000 : amatr = mat_blk[k].compute< EOS::soundspeed >( - 66 : : u[1][densityIdx(nmat, k)], pmr[k], al_r[k], k ); - 67 : 343000 : rhor += u[1][densityIdx(nmat, k)]; - 68 : : - 69 : : // Mixture speed of sound - 70 : 343000 : ac_l += u[0][densityIdx(nmat, k)] * amatl * amatl; - 71 : 343000 : ac_r += u[1][densityIdx(nmat, k)] * amatr * amatr; - 72 : : } - 73 : : - 74 : 171500 : ac_l = std::sqrt(ac_l/rhol); - 75 : 171500 : ac_r = std::sqrt(ac_r/rhor); - 76 : : - 77 : : // Independently limited velocities for advection - 78 : 171500 : auto ul = u[0][ncomp+velocityIdx(nmat, 0)]; - 79 : 171500 : auto vl = u[0][ncomp+velocityIdx(nmat, 1)]; - 80 : 171500 : auto wl = u[0][ncomp+velocityIdx(nmat, 2)]; - 81 : 171500 : auto ur = u[1][ncomp+velocityIdx(nmat, 0)]; - 82 : 171500 : auto vr = u[1][ncomp+velocityIdx(nmat, 1)]; - 83 : 171500 : auto wr = u[1][ncomp+velocityIdx(nmat, 2)]; - 84 : : - 85 : : // Face-normal velocities from advective velocities - 86 : 171500 : auto vnl = ul*fn[0] + vl*fn[1] + wl*fn[2]; - 87 : 171500 : auto vnr = ur*fn[0] + vr*fn[1] + wr*fn[2]; - 88 : : - 89 : : // Flux functions - 90 [ + + ]: 514500 : for (std::size_t k=0; k<nmat; ++k) - 91 : : { - 92 : 343000 : fl[volfracIdx(nmat, k)] = vnl * al_l[k]; - 93 : 343000 : fl[densityIdx(nmat, k)] = vnl * u[0][densityIdx(nmat, k)]; - 94 : 343000 : fl[energyIdx(nmat, k)] = vnl * hml[k]; + 52 : : std::vector< std::array< std::array< tk::real, 3 >, 3 > > g_l, g_r, + 53 : : asig_l, asig_r; + 54 : : std::vector< std::array< tk::real, 3 > > asign_l, asign_r; + 55 : : std::vector< std::array< std::array< tk::real, 3 >, 3 > > gn_l, gn_r; + 56 : 171500 : std::array< tk::real, 3 > sign_l {{0, 0, 0}}, sign_r {{0, 0, 0}}; + 57 [ + + ]: 514500 : for (std::size_t k=0; k<nmat; ++k) + 58 : : { + 59 : : // Left state + 60 : : // ----------------------------------------------------------------------- + 61 [ + - ]: 343000 : al_l[k] = u[0][volfracIdx(nmat, k)]; + 62 [ + - ]: 343000 : pml[k] = u[0][ncomp+pressureIdx(nmat, k)]; + 63 [ + - ]: 343000 : rhol += u[0][densityIdx(nmat, k)]; + 64 : : + 65 : : // inv deformation gradient and Cauchy stress tensors + 66 [ + - ]: 343000 : g_l.push_back(getDeformGrad(nmat, k, u[0])); + 67 [ + - ]: 686000 : asig_l.push_back(getCauchyStress(nmat, k, ncomp, u[0])); + 68 [ + + ]: 1372000 : for (std::size_t i=0; i<3; ++i) asig_l[k][i][i] -= pml[k]; + 69 : : + 70 : : // normal stress (traction) vector + 71 : 686000 : asign_l.push_back(tk::matvec(asig_l[k], fn)); + 72 [ + + ]: 1372000 : for (std::size_t i=0; i<3; ++i) + 73 : 1029000 : sign_l[i] += asign_l[k][i]; + 74 : : + 75 : : // rotate deformation gradient tensor for speed of sound in normal dir + 76 [ + - ]: 343000 : gn_l.push_back(tk::rotateTensor(g_l[k], fn)); + 77 [ + - ]: 343000 : amatl = mat_blk[k].compute< EOS::soundspeed >( + 78 [ + - ]: 343000 : u[0][densityIdx(nmat, k)], pml[k], al_l[k], k, gn_l[k] ); + 79 : : + 80 : : // Right state + 81 : : // ----------------------------------------------------------------------- + 82 [ + - ]: 343000 : al_r[k] = u[1][volfracIdx(nmat, k)]; + 83 [ + - ]: 343000 : pmr[k] = u[1][ncomp+pressureIdx(nmat, k)]; + 84 [ + - ]: 343000 : rhor += u[1][densityIdx(nmat, k)]; + 85 : : + 86 : : // inv deformation gradient and Cauchy stress tensors + 87 [ + - ]: 343000 : g_r.push_back(getDeformGrad(nmat, k, u[1])); + 88 [ + - ]: 686000 : asig_r.push_back(getCauchyStress(nmat, k, ncomp, u[1])); + 89 [ + + ]: 1372000 : for (std::size_t i=0; i<3; ++i) asig_r[k][i][i] -= pmr[k]; + 90 : : + 91 : : // normal stress (traction) vector + 92 : 686000 : asign_r.push_back(tk::matvec(asig_r[k], fn)); + 93 [ + + ]: 1372000 : for (std::size_t i=0; i<3; ++i) + 94 : 1029000 : sign_r[i] += asign_r[k][i]; 95 : : - 96 : 343000 : fr[volfracIdx(nmat, k)] = vnr * al_r[k]; - 97 : 343000 : fr[densityIdx(nmat, k)] = vnr * u[1][densityIdx(nmat, k)]; - 98 : 343000 : fr[energyIdx(nmat, k)] = vnr * hmr[k]; - 99 : : } + 96 : : // rotate deformation gradient tensor for speed of sound in normal dir + 97 [ + - ]: 343000 : gn_r.push_back(tk::rotateTensor(g_r[k], fn)); + 98 [ + - ]: 343000 : amatr = mat_blk[k].compute< EOS::soundspeed >( + 99 [ + - ]: 343000 : u[1][densityIdx(nmat, k)], pmr[k], al_r[k], k, gn_r[k] ); 100 : : - 101 [ + + ]: 686000 : for (std::size_t idir=0; idir<3; ++idir) - 102 : : { - 103 : 514500 : fl[momentumIdx(nmat, idir)] = vnl * u[0][momentumIdx(nmat, idir)] - 104 : 514500 : + pl*fn[idir]; - 105 : : - 106 : 514500 : fr[momentumIdx(nmat, idir)] = vnr * u[1][momentumIdx(nmat, idir)] - 107 : 514500 : + pr*fn[idir]; - 108 : : } + 101 : : // Mixture speed of sound + 102 : : // ----------------------------------------------------------------------- + 103 : 343000 : ac_l += u[0][densityIdx(nmat, k)] * amatl * amatl; + 104 : 343000 : ac_r += u[1][densityIdx(nmat, k)] * amatr * amatr; + 105 : : } + 106 : : + 107 : 171500 : ac_l = std::sqrt(ac_l/rhol); + 108 : 171500 : ac_r = std::sqrt(ac_r/rhor); 109 : : - 110 : : // Signal velocities - 111 [ + + ]: 171500 : auto Sl = std::min((vnl-ac_l), (vnr-ac_r)); - 112 [ + + ]: 171500 : auto Sr = std::max((vnl+ac_l), (vnr+ac_r)); - 113 : : - 114 : : // Numerical flux functions and wave-speeds - 115 : : auto c_plus(0.0), c_minus(0.0), p_plus(0.0), p_minus(0.0); - 116 [ - + ]: 171500 : if (Sl >= 0.0) - 117 : : { - 118 [ - - ]: 0 : for (std::size_t k=0; k<flx.size(); ++k) - 119 : 0 : flx[k] = fl[k]; - 120 : : c_plus = vnl; - 121 : : p_plus = vnl; - 122 : : } - 123 [ - + ]: 171500 : else if (Sr <= 0.0) - 124 : : { - 125 [ - - ]: 0 : for (std::size_t k=0; k<flx.size(); ++k) - 126 : 0 : flx[k] = fr[k]; - 127 : : c_minus = vnr; - 128 : : p_minus = vnr; - 129 : : } - 130 : : else - 131 : : { - 132 [ + + ]: 1715000 : for (std::size_t k=0; k<flx.size(); ++k) - 133 : 1543500 : flx[k] = (Sr*fl[k] - Sl*fr[k] + Sl*Sr*(u[1][k]-u[0][k])) / (Sr-Sl); - 134 : 171500 : c_plus = (Sr*vnl - Sr*Sl) / (Sr-Sl); - 135 : 171500 : c_minus = (Sr*Sl - Sl*vnr) / (Sr-Sl); - 136 : 171500 : p_plus = Sr * vnl / (Sr-Sl); - 137 : 171500 : p_minus = -Sl * vnr / (Sr-Sl); - 138 : : } - 139 : : - 140 : 171500 : auto vriem = c_plus+c_minus; - 141 : : - 142 : 171500 : p_plus = p_plus/( vriem + std::copysign(1.0e-16,vriem) ); - 143 : 171500 : p_minus = p_minus/( vriem + std::copysign(1.0e-16,vriem) ); + 110 : : // Independently limited velocities for advection + 111 : 171500 : auto ul = u[0][ncomp+velocityIdx(nmat, 0)]; + 112 : 171500 : auto vl = u[0][ncomp+velocityIdx(nmat, 1)]; + 113 : 171500 : auto wl = u[0][ncomp+velocityIdx(nmat, 2)]; + 114 : 171500 : auto ur = u[1][ncomp+velocityIdx(nmat, 0)]; + 115 : 171500 : auto vr = u[1][ncomp+velocityIdx(nmat, 1)]; + 116 : 171500 : auto wr = u[1][ncomp+velocityIdx(nmat, 2)]; + 117 : : + 118 : : // Face-normal velocities from advective velocities + 119 : 171500 : auto vnl = ul*fn[0] + vl*fn[1] + wl*fn[2]; + 120 : 171500 : auto vnr = ur*fn[0] + vr*fn[1] + wr*fn[2]; + 121 : : + 122 : : // Conservative flux functions + 123 : : // ------------------------------------------------------------------------- + 124 [ + + ]: 514500 : for (std::size_t k=0; k<nmat; ++k) + 125 : : { + 126 : : // Left fluxes + 127 : 343000 : fl[volfracIdx(nmat, k)] = vnl * al_l[k]; + 128 : 343000 : fl[densityIdx(nmat, k)] = vnl * u[0][densityIdx(nmat, k)]; + 129 : 343000 : fl[energyIdx(nmat, k)] = vnl * u[0][energyIdx(nmat, k)]; + 130 [ + + ]: 1372000 : for (std::size_t i=0; i<3; ++i) { + 131 : 1029000 : fl[energyIdx(nmat, k)] -= u[0][ncomp+velocityIdx(nmat,i)] * + 132 : 1029000 : asign_l[k][i]; + 133 : : } + 134 : : + 135 : : // inv deformation gradient tensor + 136 [ - + ]: 343000 : if (solidx[k] > 0) { + 137 [ - - ]: 0 : for (std::size_t i=0; i<3; ++i) + 138 [ - - ]: 0 : for (std::size_t j=0; j<3; ++j) + 139 : 0 : fl[deformIdx(nmat,solidx[k],i,j)] = ( + 140 : 0 : g_l[k][i][0] * ul + + 141 : 0 : g_l[k][i][1] * vl + + 142 : 0 : g_l[k][i][2] * wl ) * fn[j]; + 143 : : } 144 : : - 145 : : // Store Riemann-advected partial pressures - 146 [ + + ]: 514500 : for (std::size_t k=0; k<nmat; ++k) - 147 [ + - ][ - - ]: 343000 : flx.push_back(p_plus*pml[k] + p_minus*pmr[k]); - 148 : : - 149 : : // Store Riemann velocity - 150 [ + - ]: 171500 : flx.push_back( vriem ); - 151 : : - 152 : : Assert( flx.size() == (3*nmat+3+nmat+1), "Size of multi-material flux " - 153 : : "vector incorrect" ); - 154 : : - 155 : 171500 : return flx; - 156 : : } - 157 : : - 158 : : //! Flux type accessor - 159 : : //! \return Flux type - 160 : : static ctr::FluxType type() noexcept { return ctr::FluxType::HLL; } - 161 : : - 162 : : }; - 163 : : - 164 : : } // inciter:: - 165 : : - 166 : : #endif // HLL_h + 145 : : // Right fluxes + 146 : 343000 : fr[volfracIdx(nmat, k)] = vnr * al_r[k]; + 147 : 343000 : fr[densityIdx(nmat, k)] = vnr * u[1][densityIdx(nmat, k)]; + 148 : 343000 : fr[energyIdx(nmat, k)] = vnr * u[1][energyIdx(nmat, k)]; + 149 [ + + ]: 1372000 : for (std::size_t i=0; i<3; ++i) { + 150 : 1029000 : fr[energyIdx(nmat, k)] -= u[1][ncomp+velocityIdx(nmat,i)] * + 151 : 1029000 : asign_r[k][i]; + 152 : : } + 153 : : + 154 : : // inv deformation gradient tensor + 155 [ - + ]: 343000 : if (solidx[k] > 0) { + 156 [ - - ]: 0 : for (std::size_t i=0; i<3; ++i) + 157 [ - - ]: 0 : for (std::size_t j=0; j<3; ++j) + 158 : 0 : fr[deformIdx(nmat,solidx[k],i,j)] = ( + 159 : 0 : g_r[k][i][0] * ur + + 160 : 0 : g_r[k][i][1] * vr + + 161 : 0 : g_r[k][i][2] * wr ) * fn[j]; + 162 : : } + 163 : : } + 164 : : + 165 : : // bulk momentum + 166 [ + + ]: 686000 : for (std::size_t idir=0; idir<3; ++idir) + 167 : : { + 168 : 514500 : fl[momentumIdx(nmat, idir)] = vnl*u[0][momentumIdx(nmat, idir)] + 169 : 514500 : - sign_l[idir]; + 170 : 514500 : fr[momentumIdx(nmat, idir)] = vnr*u[1][momentumIdx(nmat, idir)] + 171 : 514500 : - sign_r[idir]; + 172 : : } + 173 : : + 174 : : // Numerical fluxes + 175 : : // ------------------------------------------------------------------------- + 176 : : + 177 : : // Signal velocities + 178 [ + + ]: 171500 : auto Sl = std::min((vnl-ac_l), (vnr-ac_r)); + 179 [ + + ]: 171500 : auto Sr = std::max((vnl+ac_l), (vnr+ac_r)); + 180 : : //// Signal velocities by Einfeldt (HLLE) + 181 : : //auto Sl = std::min( 0.0, std::min((vnl-ac_l), 0.5*((vnl+vnr)-(ac_l+ac_r))) ); + 182 : : //auto Sr = std::max( 0.0, std::max((vnr+ac_r), 0.5*((vnl+vnr)+(ac_l+ac_r))) ); + 183 : : + 184 : : // Numerical flux functions and wave-speeds + 185 : : auto c_plus(0.0), c_minus(0.0), p_plus(0.0), p_minus(0.0); + 186 [ - + ]: 171500 : if (Sl >= 0.0) + 187 : : { + 188 [ - - ]: 0 : flx = fl; + 189 : : c_plus = vnl; + 190 : : p_plus = 1.0; + 191 : : } + 192 [ + - ]: 171500 : else if (Sr <= 0.0) + 193 : : { + 194 [ - - ]: 0 : flx = fr; + 195 : : c_minus = vnr; + 196 : : p_minus = 1.0; + 197 : : } + 198 : : else + 199 : : { + 200 [ + + ]: 1715000 : for (std::size_t k=0; k<flx.size(); ++k) + 201 : 1543500 : flx[k] = (Sr*fl[k] - Sl*fr[k] + Sl*Sr*(u[1][k]-u[0][k])) / (Sr-Sl); + 202 : 171500 : c_plus = (Sr*vnl - Sr*Sl) / (Sr-Sl); + 203 : 171500 : c_minus = (Sr*Sl - Sl*vnr) / (Sr-Sl); + 204 : 171500 : p_plus = Sr / (Sr-Sl); + 205 : 171500 : p_minus = -Sl / (Sr-Sl); + 206 : : } + 207 : : + 208 : : // Quantities for non-conservative terms + 209 : : // ------------------------------------------------------------------------- + 210 : : + 211 : 171500 : auto vriem = c_plus+c_minus; + 212 : : + 213 : : // Store Riemann-advected partial pressures + 214 [ + + ]: 514500 : for (std::size_t k=0; k<nmat; ++k) + 215 [ + - ]: 343000 : flx.push_back(p_plus*pml[k] + p_minus*pmr[k]); + 216 : : + 217 : : // Store Riemann velocity + 218 [ + - ]: 171500 : flx.push_back( vriem ); + 219 : : + 220 : : // Store Riemann asign_ij (3*nsld) + 221 [ + + ]: 514500 : for (std::size_t k=0; k<nmat; ++k) { + 222 [ - + ]: 343000 : if (solidx[k] > 0) { + 223 [ - - ]: 0 : for (std::size_t i=0; i<3; ++i) + 224 [ - - ][ - - ]: 0 : flx.push_back(p_plus*asign_l[k][i] + p_minus*asign_r[k][i]); + 225 : : } + 226 : : } + 227 : : + 228 : : Assert( flx.size() == (ncomp+nmat+1+3*nsld), "Size of " + 229 : : "multi-material flux vector incorrect" ); + 230 : : + 231 : 171500 : return flx; + 232 : : } + 233 : : + 234 : : //! Flux type accessor + 235 : : //! \return Flux type + 236 : : static ctr::FluxType type() noexcept { return ctr::FluxType::HLL; } + 237 : : + 238 : : }; + 239 : : + 240 : : } // inciter:: + 241 : : + 242 : : #endif // HLL_h diff --git a/Release/test_coverage/PDE/Riemann/HLLC.hpp.func-sort-c.html b/Release/test_coverage/PDE/Riemann/HLLC.hpp.func-sort-c.html index b9dfeac04312..1e2f289179ca 100644 --- a/Release/test_coverage/PDE/Riemann/HLLC.hpp.func-sort-c.html +++ b/Release/test_coverage/PDE/Riemann/HLLC.hpp.func-sort-c.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:26:06 + 2024-07-11 14:48:26 Functions: 1 diff --git a/Release/test_coverage/PDE/Riemann/HLLC.hpp.func.html b/Release/test_coverage/PDE/Riemann/HLLC.hpp.func.html index 05777e4125ea..b0baa2582d8d 100644 --- a/Release/test_coverage/PDE/Riemann/HLLC.hpp.func.html +++ b/Release/test_coverage/PDE/Riemann/HLLC.hpp.func.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:26:06 + 2024-07-11 14:48:26 Functions: 1 diff --git a/Release/test_coverage/PDE/Riemann/HLLC.hpp.gcov.html b/Release/test_coverage/PDE/Riemann/HLLC.hpp.gcov.html index 7418f9f6a01d..93960884c5ba 100644 --- a/Release/test_coverage/PDE/Riemann/HLLC.hpp.gcov.html +++ b/Release/test_coverage/PDE/Riemann/HLLC.hpp.gcov.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:26:06 + 2024-07-11 14:48:26 Functions: 1 @@ -165,33 +165,33 @@ 91 : 25431867 : uStar[1][4] = ((Sr-vnr) * u[1][4] - pr*vnr + pStar*Sm) / (Sr-Sm); 92 : : 93 : : // Numerical fluxes - 94 [ + + ]: 25431867 : if (Sl > 0.0) { - 95 : 227450 : flx[0] = u[0][0] * vnl; - 96 : 227450 : flx[1] = u[0][1] * vnl + pl*fn[0]; - 97 : 227450 : flx[2] = u[0][2] * vnl + pl*fn[1]; - 98 : 227450 : flx[3] = u[0][3] * vnl + pl*fn[2]; - 99 : 227450 : flx[4] = ( u[0][4] + pl ) * vnl; + 94 [ + + ]: 25431867 : if (Sl > 0.0) { + 95 : 232070 : flx[0] = u[0][0] * vnl; + 96 : 232070 : flx[1] = u[0][1] * vnl + pl*fn[0]; + 97 : 232070 : flx[2] = u[0][2] * vnl + pl*fn[1]; + 98 : 232070 : flx[3] = u[0][3] * vnl + pl*fn[2]; + 99 : 232070 : flx[4] = ( u[0][4] + pl ) * vnl; 100 : : } - 101 [ + - ][ + + ]: 25204417 : else if (Sl <= 0.0 && Sm > 0.0) { - 102 : 9818558 : flx[0] = uStar[0][0] * Sm; - 103 : 9818558 : flx[1] = uStar[0][1] * Sm + pStar*fn[0]; - 104 : 9818558 : flx[2] = uStar[0][2] * Sm + pStar*fn[1]; - 105 : 9818558 : flx[3] = uStar[0][3] * Sm + pStar*fn[2]; - 106 : 9818558 : flx[4] = ( uStar[0][4] + pStar ) * Sm; + 101 [ + - ][ + + ]: 25199797 : else if (Sl <= 0.0 && Sm > 0.0) { + 102 : 9798147 : flx[0] = uStar[0][0] * Sm; + 103 : 9798147 : flx[1] = uStar[0][1] * Sm + pStar*fn[0]; + 104 : 9798147 : flx[2] = uStar[0][2] * Sm + pStar*fn[1]; + 105 : 9798147 : flx[3] = uStar[0][3] * Sm + pStar*fn[2]; + 106 : 9798147 : flx[4] = ( uStar[0][4] + pStar ) * Sm; 107 : : } - 108 [ + - ][ + + ]: 15385859 : else if (Sm <= 0.0 && Sr >= 0.0) { - 109 : 15133073 : flx[0] = uStar[1][0] * Sm; - 110 : 15133073 : flx[1] = uStar[1][1] * Sm + pStar*fn[0]; - 111 : 15133073 : flx[2] = uStar[1][2] * Sm + pStar*fn[1]; - 112 : 15133073 : flx[3] = uStar[1][3] * Sm + pStar*fn[2]; - 113 : 15133073 : flx[4] = ( uStar[1][4] + pStar ) * Sm; + 108 [ + - ][ + + ]: 15401650 : else if (Sm <= 0.0 && Sr >= 0.0) { + 109 : 15153484 : flx[0] = uStar[1][0] * Sm; + 110 : 15153484 : flx[1] = uStar[1][1] * Sm + pStar*fn[0]; + 111 : 15153484 : flx[2] = uStar[1][2] * Sm + pStar*fn[1]; + 112 : 15153484 : flx[3] = uStar[1][3] * Sm + pStar*fn[2]; + 113 : 15153484 : flx[4] = ( uStar[1][4] + pStar ) * Sm; 114 : : } 115 : : else { - 116 : 252786 : flx[0] = u[1][0] * vnr; - 117 : 252786 : flx[1] = u[1][1] * vnr + pr*fn[0]; - 118 : 252786 : flx[2] = u[1][2] * vnr + pr*fn[1]; - 119 : 252786 : flx[3] = u[1][3] * vnr + pr*fn[2]; - 120 : 252786 : flx[4] = ( u[1][4] + pr ) * vnr; + 116 : 248166 : flx[0] = u[1][0] * vnr; + 117 : 248166 : flx[1] = u[1][1] * vnr + pr*fn[0]; + 118 : 248166 : flx[2] = u[1][2] * vnr + pr*fn[1]; + 119 : 248166 : flx[3] = u[1][3] * vnr + pr*fn[2]; + 120 : 248166 : flx[4] = ( u[1][4] + pr ) * vnr; 121 : : } 122 : : 123 : 25431867 : return flx; diff --git a/Release/test_coverage/PDE/Riemann/LaxFriedrichs.hpp.func-sort-c.html b/Release/test_coverage/PDE/Riemann/LaxFriedrichs.hpp.func-sort-c.html index 1986c4578866..bbd293a45002 100644 --- a/Release/test_coverage/PDE/Riemann/LaxFriedrichs.hpp.func-sort-c.html +++ b/Release/test_coverage/PDE/Riemann/LaxFriedrichs.hpp.func-sort-c.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:26:06 + 2024-07-11 14:48:26 Functions: 1 diff --git a/Release/test_coverage/PDE/Riemann/LaxFriedrichs.hpp.func.html b/Release/test_coverage/PDE/Riemann/LaxFriedrichs.hpp.func.html index 6bdf7c26c6e1..b806e91f11c0 100644 --- a/Release/test_coverage/PDE/Riemann/LaxFriedrichs.hpp.func.html +++ b/Release/test_coverage/PDE/Riemann/LaxFriedrichs.hpp.func.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:26:06 + 2024-07-11 14:48:26 Functions: 1 diff --git a/Release/test_coverage/PDE/Riemann/LaxFriedrichs.hpp.gcov.html b/Release/test_coverage/PDE/Riemann/LaxFriedrichs.hpp.gcov.html index b06fc4e6f203..1feac969f6ff 100644 --- a/Release/test_coverage/PDE/Riemann/LaxFriedrichs.hpp.gcov.html +++ b/Release/test_coverage/PDE/Riemann/LaxFriedrichs.hpp.gcov.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:26:06 + 2024-07-11 14:48:26 Functions: 1 diff --git a/Release/test_coverage/PDE/Riemann/LaxFriedrichsSolids.hpp.func-sort-c.html b/Release/test_coverage/PDE/Riemann/LaxFriedrichsSolids.hpp.func-sort-c.html index 002493b47f86..20000a4fb990 100644 --- a/Release/test_coverage/PDE/Riemann/LaxFriedrichsSolids.hpp.func-sort-c.html +++ b/Release/test_coverage/PDE/Riemann/LaxFriedrichsSolids.hpp.func-sort-c.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:26:06 + 2024-07-11 14:48:26 Functions: 0 diff --git a/Release/test_coverage/PDE/Riemann/LaxFriedrichsSolids.hpp.func.html b/Release/test_coverage/PDE/Riemann/LaxFriedrichsSolids.hpp.func.html index a3f78c529105..e51f65dc659b 100644 --- a/Release/test_coverage/PDE/Riemann/LaxFriedrichsSolids.hpp.func.html +++ b/Release/test_coverage/PDE/Riemann/LaxFriedrichsSolids.hpp.func.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:26:06 + 2024-07-11 14:48:26 Functions: 0 diff --git a/Release/test_coverage/PDE/Riemann/LaxFriedrichsSolids.hpp.gcov.html b/Release/test_coverage/PDE/Riemann/LaxFriedrichsSolids.hpp.gcov.html index bbb07902af4d..6dfdbc1cc4d3 100644 --- a/Release/test_coverage/PDE/Riemann/LaxFriedrichsSolids.hpp.gcov.html +++ b/Release/test_coverage/PDE/Riemann/LaxFriedrichsSolids.hpp.gcov.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:26:06 + 2024-07-11 14:48:26 Functions: 0 diff --git a/Release/test_coverage/PDE/Riemann/Rusanov.hpp.func-sort-c.html b/Release/test_coverage/PDE/Riemann/Rusanov.hpp.func-sort-c.html index 591e4322aeb8..59c8f92b9976 100644 --- a/Release/test_coverage/PDE/Riemann/Rusanov.hpp.func-sort-c.html +++ b/Release/test_coverage/PDE/Riemann/Rusanov.hpp.func-sort-c.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:26:06 + 2024-07-11 14:48:26 Functions: 1 diff --git a/Release/test_coverage/PDE/Riemann/Rusanov.hpp.func.html b/Release/test_coverage/PDE/Riemann/Rusanov.hpp.func.html index 11f703f06168..1f5cf5881ccc 100644 --- a/Release/test_coverage/PDE/Riemann/Rusanov.hpp.func.html +++ b/Release/test_coverage/PDE/Riemann/Rusanov.hpp.func.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:26:06 + 2024-07-11 14:48:26 Functions: 1 diff --git a/Release/test_coverage/PDE/Riemann/Rusanov.hpp.gcov.html b/Release/test_coverage/PDE/Riemann/Rusanov.hpp.gcov.html index 19706c73954c..35dfaa30f8bd 100644 --- a/Release/test_coverage/PDE/Riemann/Rusanov.hpp.gcov.html +++ b/Release/test_coverage/PDE/Riemann/Rusanov.hpp.gcov.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:26:06 + 2024-07-11 14:48:26 Functions: 1 @@ -160,9 +160,9 @@ 86 : : // dissipation 87 : : real len = tk::length( {mx,my,mz} ); 88 : 22970664 : real vml = ul*mx + vl*my + wl*mz; - 89 [ + + ]: 22970664 : real vmr = ur*mx + vr*my + wr*mz; + 89 [ + + ]: 22970664 : real vmr = ur*mx + vr*my + wr*mz; 90 : 22970664 : auto sl = std::abs(vml) + al*len; - 91 [ + + ]: 22970664 : auto sr = std::abs(vmr) + ar*len; + 91 [ + + ]: 22970664 : auto sr = std::abs(vmr) + ar*len; 92 : 22970664 : auto smax = std::max( sl, sr ); 93 : : 94 : : // face-normal velocities diff --git a/Release/test_coverage/PDE/Riemann/Upwind.hpp.func-sort-c.html b/Release/test_coverage/PDE/Riemann/Upwind.hpp.func-sort-c.html index db740780b300..570eb75cd410 100644 --- a/Release/test_coverage/PDE/Riemann/Upwind.hpp.func-sort-c.html +++ b/Release/test_coverage/PDE/Riemann/Upwind.hpp.func-sort-c.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:26:06 + 2024-07-11 14:48:26 Functions: 1 diff --git a/Release/test_coverage/PDE/Riemann/Upwind.hpp.func.html b/Release/test_coverage/PDE/Riemann/Upwind.hpp.func.html index 24fe798e9d4e..a35544129609 100644 --- a/Release/test_coverage/PDE/Riemann/Upwind.hpp.func.html +++ b/Release/test_coverage/PDE/Riemann/Upwind.hpp.func.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:26:06 + 2024-07-11 14:48:26 Functions: 1 diff --git a/Release/test_coverage/PDE/Riemann/Upwind.hpp.gcov.html b/Release/test_coverage/PDE/Riemann/Upwind.hpp.gcov.html index 75a15cf43cc2..3cbb3ca57bd4 100644 --- a/Release/test_coverage/PDE/Riemann/Upwind.hpp.gcov.html +++ b/Release/test_coverage/PDE/Riemann/Upwind.hpp.gcov.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:26:06 + 2024-07-11 14:48:26 Functions: 1 diff --git a/Release/test_coverage/PDE/Riemann/index-sort-b.html b/Release/test_coverage/PDE/Riemann/index-sort-b.html index 6424cfa0966a..d0cf9aa8612d 100644 --- a/Release/test_coverage/PDE/Riemann/index-sort-b.html +++ b/Release/test_coverage/PDE/Riemann/index-sort-b.html @@ -27,13 +27,13 @@ -128-NOTFOUND Lines: - 281 - 379 - 74.1 % + 302 + 412 + 73.3 % Date: - 2024-07-10 11:26:06 + 2024-07-11 14:48:26 Functions: 7 @@ -49,9 +49,9 @@ Branches: - 109 - 340 - 32.1 % + 133 + 382 + 34.8 % @@ -108,14 +108,14 @@ HLL.hpp -
93.8%93.8%
+
83.7%83.7%
- 93.8 % - 61 / 65 + 83.7 % + 82 / 98 100.0 % 1 / 1 - 44.6 % - 33 / 74 + 49.1 % + 57 / 116 AUSM.hpp diff --git a/Release/test_coverage/PDE/Riemann/index-sort-f.html b/Release/test_coverage/PDE/Riemann/index-sort-f.html index a44cd8bea080..ab80e8bb4a61 100644 --- a/Release/test_coverage/PDE/Riemann/index-sort-f.html +++ b/Release/test_coverage/PDE/Riemann/index-sort-f.html @@ -27,13 +27,13 @@ -128-NOTFOUND Lines: - 281 - 379 - 74.1 % + 302 + 412 + 73.3 % Date: - 2024-07-10 11:26:06 + 2024-07-11 14:48:26 Functions: 7 @@ -49,9 +49,9 @@ Branches: - 109 - 340 - 32.1 % + 133 + 382 + 34.8 % @@ -93,6 +93,18 @@ 0.0 % 0 / 122 + + HLL.hpp + +
83.7%83.7%
+ + 83.7 % + 82 / 98 + 100.0 % + 1 / 1 + 49.1 % + 57 / 116 + HLLC.hpp @@ -106,16 +118,16 @@ 13 / 20 - Rusanov.hpp + Upwind.hpp
100.0%
100.0 % - 25 / 25 + 8 / 8 100.0 % 1 / 1 - 75.0 % - 6 / 8 + 18.8 % + 3 / 16 LaxFriedrichs.hpp @@ -130,28 +142,16 @@ 12 / 22 - HLL.hpp - -
93.8%93.8%
- - 93.8 % - 61 / 65 - 100.0 % - 1 / 1 - 44.6 % - 33 / 74 - - - Upwind.hpp + Rusanov.hpp
100.0%
100.0 % - 8 / 8 + 25 / 25 100.0 % 1 / 1 - 18.8 % - 3 / 16 + 75.0 % + 6 / 8 AUSM.hpp diff --git a/Release/test_coverage/PDE/Riemann/index-sort-l.html b/Release/test_coverage/PDE/Riemann/index-sort-l.html index 296a6567d625..14851db194a9 100644 --- a/Release/test_coverage/PDE/Riemann/index-sort-l.html +++ b/Release/test_coverage/PDE/Riemann/index-sort-l.html @@ -27,13 +27,13 @@ -128-NOTFOUND Lines: - 281 - 379 - 74.1 % + 302 + 412 + 73.3 % Date: - 2024-07-10 11:26:06 + 2024-07-11 14:48:26 Functions: 7 @@ -49,9 +49,9 @@ Branches: - 109 - 340 - 32.1 % + 133 + 382 + 34.8 % @@ -96,14 +96,14 @@ HLL.hpp -
93.8%93.8%
+
83.7%83.7%
- 93.8 % - 61 / 65 + 83.7 % + 82 / 98 100.0 % 1 / 1 - 44.6 % - 33 / 74 + 49.1 % + 57 / 116 Upwind.hpp diff --git a/Release/test_coverage/PDE/Riemann/index.html b/Release/test_coverage/PDE/Riemann/index.html index cfc38d65429d..ae50715e0f40 100644 --- a/Release/test_coverage/PDE/Riemann/index.html +++ b/Release/test_coverage/PDE/Riemann/index.html @@ -27,13 +27,13 @@ -128-NOTFOUND Lines: - 281 - 379 - 74.1 % + 302 + 412 + 73.3 % Date: - 2024-07-10 11:26:06 + 2024-07-11 14:48:26 Functions: 7 @@ -49,9 +49,9 @@ Branches: - 109 - 340 - 32.1 % + 133 + 382 + 34.8 % @@ -96,14 +96,14 @@ HLL.hpp -
93.8%93.8%
+
83.7%83.7%
- 93.8 % - 61 / 65 + 83.7 % + 82 / 98 100.0 % 1 / 1 - 44.6 % - 33 / 74 + 49.1 % + 57 / 116 HLLC.hpp diff --git a/Release/test_coverage/PDE/Transport/CGTransport.hpp.func-sort-c.html b/Release/test_coverage/PDE/Transport/CGTransport.hpp.func-sort-c.html index 317bb967a51e..c677caf5868d 100644 --- a/Release/test_coverage/PDE/Transport/CGTransport.hpp.func-sort-c.html +++ b/Release/test_coverage/PDE/Transport/CGTransport.hpp.func-sort-c.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:26:06 + 2024-07-11 14:48:26 Functions: 22 diff --git a/Release/test_coverage/PDE/Transport/CGTransport.hpp.func.html b/Release/test_coverage/PDE/Transport/CGTransport.hpp.func.html index 34c7179384f8..63d6d3fe47c6 100644 --- a/Release/test_coverage/PDE/Transport/CGTransport.hpp.func.html +++ b/Release/test_coverage/PDE/Transport/CGTransport.hpp.func.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:26:06 + 2024-07-11 14:48:26 Functions: 22 diff --git a/Release/test_coverage/PDE/Transport/CGTransport.hpp.gcov.html b/Release/test_coverage/PDE/Transport/CGTransport.hpp.gcov.html index 6297ca0c35c3..2ac4c2120338 100644 --- a/Release/test_coverage/PDE/Transport/CGTransport.hpp.gcov.html +++ b/Release/test_coverage/PDE/Transport/CGTransport.hpp.gcov.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:26:06 + 2024-07-11 14:48:26 Functions: 22 diff --git a/Release/test_coverage/PDE/Transport/DGTransport.hpp.func-sort-c.html b/Release/test_coverage/PDE/Transport/DGTransport.hpp.func-sort-c.html index 825ee758e8b2..05328f027d1b 100644 --- a/Release/test_coverage/PDE/Transport/DGTransport.hpp.func-sort-c.html +++ b/Release/test_coverage/PDE/Transport/DGTransport.hpp.func-sort-c.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:26:06 + 2024-07-11 14:48:26 Functions: 32 diff --git a/Release/test_coverage/PDE/Transport/DGTransport.hpp.func.html b/Release/test_coverage/PDE/Transport/DGTransport.hpp.func.html index dcd1489a5c22..8e6ed3a53f95 100644 --- a/Release/test_coverage/PDE/Transport/DGTransport.hpp.func.html +++ b/Release/test_coverage/PDE/Transport/DGTransport.hpp.func.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:26:06 + 2024-07-11 14:48:26 Functions: 32 diff --git a/Release/test_coverage/PDE/Transport/DGTransport.hpp.gcov.html b/Release/test_coverage/PDE/Transport/DGTransport.hpp.gcov.html index 052ba3833f1c..59ad41c9219f 100644 --- a/Release/test_coverage/PDE/Transport/DGTransport.hpp.gcov.html +++ b/Release/test_coverage/PDE/Transport/DGTransport.hpp.gcov.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:26:06 + 2024-07-11 14:48:26 Functions: 32 diff --git a/Release/test_coverage/PDE/Transport/Physics/CGAdvDiff.cpp.func-sort-c.html b/Release/test_coverage/PDE/Transport/Physics/CGAdvDiff.cpp.func-sort-c.html index f3bcdea116ca..51d0e4594262 100644 --- a/Release/test_coverage/PDE/Transport/Physics/CGAdvDiff.cpp.func-sort-c.html +++ b/Release/test_coverage/PDE/Transport/Physics/CGAdvDiff.cpp.func-sort-c.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:26:06 + 2024-07-11 14:48:26 Functions: 0 diff --git a/Release/test_coverage/PDE/Transport/Physics/CGAdvDiff.cpp.func.html b/Release/test_coverage/PDE/Transport/Physics/CGAdvDiff.cpp.func.html index 52283b47c0cd..b86c7fdce5b5 100644 --- a/Release/test_coverage/PDE/Transport/Physics/CGAdvDiff.cpp.func.html +++ b/Release/test_coverage/PDE/Transport/Physics/CGAdvDiff.cpp.func.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:26:06 + 2024-07-11 14:48:26 Functions: 0 diff --git a/Release/test_coverage/PDE/Transport/Physics/CGAdvDiff.cpp.gcov.html b/Release/test_coverage/PDE/Transport/Physics/CGAdvDiff.cpp.gcov.html index ea6d97068094..5b4d4e8ebfbe 100644 --- a/Release/test_coverage/PDE/Transport/Physics/CGAdvDiff.cpp.gcov.html +++ b/Release/test_coverage/PDE/Transport/Physics/CGAdvDiff.cpp.gcov.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:26:06 + 2024-07-11 14:48:26 Functions: 0 diff --git a/Release/test_coverage/PDE/Transport/Physics/index-sort-b.html b/Release/test_coverage/PDE/Transport/Physics/index-sort-b.html index 16b7d2046ae6..83d38d017a9a 100644 --- a/Release/test_coverage/PDE/Transport/Physics/index-sort-b.html +++ b/Release/test_coverage/PDE/Transport/Physics/index-sort-b.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:26:06 + 2024-07-11 14:48:26 Functions: 0 diff --git a/Release/test_coverage/PDE/Transport/Physics/index-sort-f.html b/Release/test_coverage/PDE/Transport/Physics/index-sort-f.html index a8455133be66..5253dc04b3a9 100644 --- a/Release/test_coverage/PDE/Transport/Physics/index-sort-f.html +++ b/Release/test_coverage/PDE/Transport/Physics/index-sort-f.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:26:06 + 2024-07-11 14:48:26 Functions: 0 diff --git a/Release/test_coverage/PDE/Transport/Physics/index-sort-l.html b/Release/test_coverage/PDE/Transport/Physics/index-sort-l.html index c57c176bb78c..bc2412d35f33 100644 --- a/Release/test_coverage/PDE/Transport/Physics/index-sort-l.html +++ b/Release/test_coverage/PDE/Transport/Physics/index-sort-l.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:26:06 + 2024-07-11 14:48:26 Functions: 0 diff --git a/Release/test_coverage/PDE/Transport/Physics/index.html b/Release/test_coverage/PDE/Transport/Physics/index.html index 521d114ab835..da01d0668b4c 100644 --- a/Release/test_coverage/PDE/Transport/Physics/index.html +++ b/Release/test_coverage/PDE/Transport/Physics/index.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:26:06 + 2024-07-11 14:48:26 Functions: 0 diff --git a/Release/test_coverage/PDE/Transport/Problem/CylAdvect.cpp.func-sort-c.html b/Release/test_coverage/PDE/Transport/Problem/CylAdvect.cpp.func-sort-c.html index c03fa4164c93..51bd32bbb19c 100644 --- a/Release/test_coverage/PDE/Transport/Problem/CylAdvect.cpp.func-sort-c.html +++ b/Release/test_coverage/PDE/Transport/Problem/CylAdvect.cpp.func-sort-c.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:26:06 + 2024-07-11 14:48:26 Functions: 2 diff --git a/Release/test_coverage/PDE/Transport/Problem/CylAdvect.cpp.func.html b/Release/test_coverage/PDE/Transport/Problem/CylAdvect.cpp.func.html index f210e3cb9b1a..9a3ae8d19ba7 100644 --- a/Release/test_coverage/PDE/Transport/Problem/CylAdvect.cpp.func.html +++ b/Release/test_coverage/PDE/Transport/Problem/CylAdvect.cpp.func.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:26:06 + 2024-07-11 14:48:26 Functions: 2 diff --git a/Release/test_coverage/PDE/Transport/Problem/CylAdvect.cpp.gcov.html b/Release/test_coverage/PDE/Transport/Problem/CylAdvect.cpp.gcov.html index 8d2c9cb18e3e..6a2d62a62bc4 100644 --- a/Release/test_coverage/PDE/Transport/Problem/CylAdvect.cpp.gcov.html +++ b/Release/test_coverage/PDE/Transport/Problem/CylAdvect.cpp.gcov.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:26:06 + 2024-07-11 14:48:26 Functions: 2 diff --git a/Release/test_coverage/PDE/Transport/Problem/CylAdvect.hpp.func-sort-c.html b/Release/test_coverage/PDE/Transport/Problem/CylAdvect.hpp.func-sort-c.html index 929a97d379c8..9b7b98d5f47a 100644 --- a/Release/test_coverage/PDE/Transport/Problem/CylAdvect.hpp.func-sort-c.html +++ b/Release/test_coverage/PDE/Transport/Problem/CylAdvect.hpp.func-sort-c.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:26:06 + 2024-07-11 14:48:26 Functions: 0 diff --git a/Release/test_coverage/PDE/Transport/Problem/CylAdvect.hpp.func.html b/Release/test_coverage/PDE/Transport/Problem/CylAdvect.hpp.func.html index 07a845393017..f1f1d34076d6 100644 --- a/Release/test_coverage/PDE/Transport/Problem/CylAdvect.hpp.func.html +++ b/Release/test_coverage/PDE/Transport/Problem/CylAdvect.hpp.func.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:26:06 + 2024-07-11 14:48:26 Functions: 0 diff --git a/Release/test_coverage/PDE/Transport/Problem/CylAdvect.hpp.gcov.html b/Release/test_coverage/PDE/Transport/Problem/CylAdvect.hpp.gcov.html index 24a8365ea4f5..88e32bcfcd60 100644 --- a/Release/test_coverage/PDE/Transport/Problem/CylAdvect.hpp.gcov.html +++ b/Release/test_coverage/PDE/Transport/Problem/CylAdvect.hpp.gcov.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:26:06 + 2024-07-11 14:48:26 Functions: 0 diff --git a/Release/test_coverage/PDE/Transport/Problem/CylVortex.cpp.func-sort-c.html b/Release/test_coverage/PDE/Transport/Problem/CylVortex.cpp.func-sort-c.html index c116b91a90c4..ca5ec94aa394 100644 --- a/Release/test_coverage/PDE/Transport/Problem/CylVortex.cpp.func-sort-c.html +++ b/Release/test_coverage/PDE/Transport/Problem/CylVortex.cpp.func-sort-c.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:26:06 + 2024-07-11 14:48:26 Functions: 0 diff --git a/Release/test_coverage/PDE/Transport/Problem/CylVortex.cpp.func.html b/Release/test_coverage/PDE/Transport/Problem/CylVortex.cpp.func.html index b19438c87391..6d13cff0cafa 100644 --- a/Release/test_coverage/PDE/Transport/Problem/CylVortex.cpp.func.html +++ b/Release/test_coverage/PDE/Transport/Problem/CylVortex.cpp.func.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:26:06 + 2024-07-11 14:48:26 Functions: 0 diff --git a/Release/test_coverage/PDE/Transport/Problem/CylVortex.cpp.gcov.html b/Release/test_coverage/PDE/Transport/Problem/CylVortex.cpp.gcov.html index 42f8ff4a7f7d..3e507b5acfb9 100644 --- a/Release/test_coverage/PDE/Transport/Problem/CylVortex.cpp.gcov.html +++ b/Release/test_coverage/PDE/Transport/Problem/CylVortex.cpp.gcov.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:26:06 + 2024-07-11 14:48:26 Functions: 0 diff --git a/Release/test_coverage/PDE/Transport/Problem/CylVortex.hpp.func-sort-c.html b/Release/test_coverage/PDE/Transport/Problem/CylVortex.hpp.func-sort-c.html index a55fa937f183..78ff4348663d 100644 --- a/Release/test_coverage/PDE/Transport/Problem/CylVortex.hpp.func-sort-c.html +++ b/Release/test_coverage/PDE/Transport/Problem/CylVortex.hpp.func-sort-c.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:26:06 + 2024-07-11 14:48:26 Functions: 0 diff --git a/Release/test_coverage/PDE/Transport/Problem/CylVortex.hpp.func.html b/Release/test_coverage/PDE/Transport/Problem/CylVortex.hpp.func.html index 1a292ff647f9..d812abc20fa3 100644 --- a/Release/test_coverage/PDE/Transport/Problem/CylVortex.hpp.func.html +++ b/Release/test_coverage/PDE/Transport/Problem/CylVortex.hpp.func.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:26:06 + 2024-07-11 14:48:26 Functions: 0 diff --git a/Release/test_coverage/PDE/Transport/Problem/CylVortex.hpp.gcov.html b/Release/test_coverage/PDE/Transport/Problem/CylVortex.hpp.gcov.html index 48aa7a15fdf0..e74f953c0b22 100644 --- a/Release/test_coverage/PDE/Transport/Problem/CylVortex.hpp.gcov.html +++ b/Release/test_coverage/PDE/Transport/Problem/CylVortex.hpp.gcov.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:26:06 + 2024-07-11 14:48:26 Functions: 0 diff --git a/Release/test_coverage/PDE/Transport/Problem/GaussHump.cpp.func-sort-c.html b/Release/test_coverage/PDE/Transport/Problem/GaussHump.cpp.func-sort-c.html index 557f1545df5d..3beb812ca333 100644 --- a/Release/test_coverage/PDE/Transport/Problem/GaussHump.cpp.func-sort-c.html +++ b/Release/test_coverage/PDE/Transport/Problem/GaussHump.cpp.func-sort-c.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:26:06 + 2024-07-11 14:48:26 Functions: 2 diff --git a/Release/test_coverage/PDE/Transport/Problem/GaussHump.cpp.func.html b/Release/test_coverage/PDE/Transport/Problem/GaussHump.cpp.func.html index bb9b7f794ff4..7485697d3d4f 100644 --- a/Release/test_coverage/PDE/Transport/Problem/GaussHump.cpp.func.html +++ b/Release/test_coverage/PDE/Transport/Problem/GaussHump.cpp.func.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:26:06 + 2024-07-11 14:48:26 Functions: 2 diff --git a/Release/test_coverage/PDE/Transport/Problem/GaussHump.cpp.gcov.html b/Release/test_coverage/PDE/Transport/Problem/GaussHump.cpp.gcov.html index 95115c4a0eec..9b604a668fac 100644 --- a/Release/test_coverage/PDE/Transport/Problem/GaussHump.cpp.gcov.html +++ b/Release/test_coverage/PDE/Transport/Problem/GaussHump.cpp.gcov.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:26:06 + 2024-07-11 14:48:26 Functions: 2 diff --git a/Release/test_coverage/PDE/Transport/Problem/GaussHump.hpp.func-sort-c.html b/Release/test_coverage/PDE/Transport/Problem/GaussHump.hpp.func-sort-c.html index b11a148663e2..ad3ba728ad5b 100644 --- a/Release/test_coverage/PDE/Transport/Problem/GaussHump.hpp.func-sort-c.html +++ b/Release/test_coverage/PDE/Transport/Problem/GaussHump.hpp.func-sort-c.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:26:06 + 2024-07-11 14:48:26 Functions: 0 diff --git a/Release/test_coverage/PDE/Transport/Problem/GaussHump.hpp.func.html b/Release/test_coverage/PDE/Transport/Problem/GaussHump.hpp.func.html index a67bb3ba2448..dd6369d469ea 100644 --- a/Release/test_coverage/PDE/Transport/Problem/GaussHump.hpp.func.html +++ b/Release/test_coverage/PDE/Transport/Problem/GaussHump.hpp.func.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:26:06 + 2024-07-11 14:48:26 Functions: 0 diff --git a/Release/test_coverage/PDE/Transport/Problem/GaussHump.hpp.gcov.html b/Release/test_coverage/PDE/Transport/Problem/GaussHump.hpp.gcov.html index a9010f1d8637..e4287ac24888 100644 --- a/Release/test_coverage/PDE/Transport/Problem/GaussHump.hpp.gcov.html +++ b/Release/test_coverage/PDE/Transport/Problem/GaussHump.hpp.gcov.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:26:06 + 2024-07-11 14:48:26 Functions: 0 diff --git a/Release/test_coverage/PDE/Transport/Problem/ShearDiff.cpp.func-sort-c.html b/Release/test_coverage/PDE/Transport/Problem/ShearDiff.cpp.func-sort-c.html index c67d1ee54ab0..7a057746842a 100644 --- a/Release/test_coverage/PDE/Transport/Problem/ShearDiff.cpp.func-sort-c.html +++ b/Release/test_coverage/PDE/Transport/Problem/ShearDiff.cpp.func-sort-c.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:26:06 + 2024-07-11 14:48:26 Functions: 0 diff --git a/Release/test_coverage/PDE/Transport/Problem/ShearDiff.cpp.func.html b/Release/test_coverage/PDE/Transport/Problem/ShearDiff.cpp.func.html index 32d561a88d85..c38ec058a326 100644 --- a/Release/test_coverage/PDE/Transport/Problem/ShearDiff.cpp.func.html +++ b/Release/test_coverage/PDE/Transport/Problem/ShearDiff.cpp.func.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:26:06 + 2024-07-11 14:48:26 Functions: 0 diff --git a/Release/test_coverage/PDE/Transport/Problem/ShearDiff.cpp.gcov.html b/Release/test_coverage/PDE/Transport/Problem/ShearDiff.cpp.gcov.html index 906c47bd50f3..e6b2320caf2d 100644 --- a/Release/test_coverage/PDE/Transport/Problem/ShearDiff.cpp.gcov.html +++ b/Release/test_coverage/PDE/Transport/Problem/ShearDiff.cpp.gcov.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:26:06 + 2024-07-11 14:48:26 Functions: 0 diff --git a/Release/test_coverage/PDE/Transport/Problem/ShearDiff.hpp.func-sort-c.html b/Release/test_coverage/PDE/Transport/Problem/ShearDiff.hpp.func-sort-c.html index f3a9f370df23..fd1c3d95b089 100644 --- a/Release/test_coverage/PDE/Transport/Problem/ShearDiff.hpp.func-sort-c.html +++ b/Release/test_coverage/PDE/Transport/Problem/ShearDiff.hpp.func-sort-c.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:26:06 + 2024-07-11 14:48:26 Functions: 0 diff --git a/Release/test_coverage/PDE/Transport/Problem/ShearDiff.hpp.func.html b/Release/test_coverage/PDE/Transport/Problem/ShearDiff.hpp.func.html index 3df11925dde3..9c5965c82656 100644 --- a/Release/test_coverage/PDE/Transport/Problem/ShearDiff.hpp.func.html +++ b/Release/test_coverage/PDE/Transport/Problem/ShearDiff.hpp.func.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:26:06 + 2024-07-11 14:48:26 Functions: 0 diff --git a/Release/test_coverage/PDE/Transport/Problem/ShearDiff.hpp.gcov.html b/Release/test_coverage/PDE/Transport/Problem/ShearDiff.hpp.gcov.html index 30ed1cddedd3..367cbf1cb6dd 100644 --- a/Release/test_coverage/PDE/Transport/Problem/ShearDiff.hpp.gcov.html +++ b/Release/test_coverage/PDE/Transport/Problem/ShearDiff.hpp.gcov.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:26:06 + 2024-07-11 14:48:26 Functions: 0 diff --git a/Release/test_coverage/PDE/Transport/Problem/SlotCyl.cpp.func-sort-c.html b/Release/test_coverage/PDE/Transport/Problem/SlotCyl.cpp.func-sort-c.html index 3cd1f6137fbe..19dd9cfeb01d 100644 --- a/Release/test_coverage/PDE/Transport/Problem/SlotCyl.cpp.func-sort-c.html +++ b/Release/test_coverage/PDE/Transport/Problem/SlotCyl.cpp.func-sort-c.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:26:06 + 2024-07-11 14:48:26 Functions: 2 diff --git a/Release/test_coverage/PDE/Transport/Problem/SlotCyl.cpp.func.html b/Release/test_coverage/PDE/Transport/Problem/SlotCyl.cpp.func.html index d5ba4de0cf58..31ac915ce36c 100644 --- a/Release/test_coverage/PDE/Transport/Problem/SlotCyl.cpp.func.html +++ b/Release/test_coverage/PDE/Transport/Problem/SlotCyl.cpp.func.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:26:06 + 2024-07-11 14:48:26 Functions: 2 diff --git a/Release/test_coverage/PDE/Transport/Problem/SlotCyl.cpp.gcov.html b/Release/test_coverage/PDE/Transport/Problem/SlotCyl.cpp.gcov.html index e6d57109abc7..8cd7e542ece1 100644 --- a/Release/test_coverage/PDE/Transport/Problem/SlotCyl.cpp.gcov.html +++ b/Release/test_coverage/PDE/Transport/Problem/SlotCyl.cpp.gcov.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:26:06 + 2024-07-11 14:48:26 Functions: 2 diff --git a/Release/test_coverage/PDE/Transport/Problem/SlotCyl.hpp.func-sort-c.html b/Release/test_coverage/PDE/Transport/Problem/SlotCyl.hpp.func-sort-c.html index c0ce252b4052..9bbd8f034b05 100644 --- a/Release/test_coverage/PDE/Transport/Problem/SlotCyl.hpp.func-sort-c.html +++ b/Release/test_coverage/PDE/Transport/Problem/SlotCyl.hpp.func-sort-c.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:26:06 + 2024-07-11 14:48:26 Functions: 0 diff --git a/Release/test_coverage/PDE/Transport/Problem/SlotCyl.hpp.func.html b/Release/test_coverage/PDE/Transport/Problem/SlotCyl.hpp.func.html index 79ea5133abee..c65344850b43 100644 --- a/Release/test_coverage/PDE/Transport/Problem/SlotCyl.hpp.func.html +++ b/Release/test_coverage/PDE/Transport/Problem/SlotCyl.hpp.func.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:26:06 + 2024-07-11 14:48:26 Functions: 0 diff --git a/Release/test_coverage/PDE/Transport/Problem/SlotCyl.hpp.gcov.html b/Release/test_coverage/PDE/Transport/Problem/SlotCyl.hpp.gcov.html index e72adbc48a71..a85d4b1d7257 100644 --- a/Release/test_coverage/PDE/Transport/Problem/SlotCyl.hpp.gcov.html +++ b/Release/test_coverage/PDE/Transport/Problem/SlotCyl.hpp.gcov.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:26:06 + 2024-07-11 14:48:26 Functions: 0 diff --git a/Release/test_coverage/PDE/Transport/Problem/index-sort-b.html b/Release/test_coverage/PDE/Transport/Problem/index-sort-b.html index 3c739d8b4bfe..bca9d98d1755 100644 --- a/Release/test_coverage/PDE/Transport/Problem/index-sort-b.html +++ b/Release/test_coverage/PDE/Transport/Problem/index-sort-b.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:26:06 + 2024-07-11 14:48:26 Functions: 6 @@ -166,24 +166,24 @@ 0 / 0 - ShearDiff.hpp + CylAdvect.hpp -
0.0%
+
100.0%
- 0.0 % - 0 / 1 + 100.0 % + 1 / 1 - 0 / 0 - 0 / 0 - CylAdvect.hpp + ShearDiff.hpp -
100.0%
+
0.0%
- 100.0 % - 1 / 1 + 0.0 % + 0 / 1 - 0 / 0 - diff --git a/Release/test_coverage/PDE/Transport/Problem/index-sort-f.html b/Release/test_coverage/PDE/Transport/Problem/index-sort-f.html index 5f59a20d6b32..128c28b68ad8 100644 --- a/Release/test_coverage/PDE/Transport/Problem/index-sort-f.html +++ b/Release/test_coverage/PDE/Transport/Problem/index-sort-f.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:26:06 + 2024-07-11 14:48:26 Functions: 6 @@ -130,24 +130,24 @@ 0 / 0 - ShearDiff.hpp + CylAdvect.hpp -
0.0%
+
100.0%
- 0.0 % - 0 / 1 + 100.0 % + 1 / 1 - 0 / 0 - 0 / 0 - CylAdvect.hpp + ShearDiff.hpp -
100.0%
+
0.0%
- 100.0 % - 1 / 1 + 0.0 % + 0 / 1 - 0 / 0 - @@ -178,28 +178,28 @@ 9 / 12 - SlotCyl.cpp + GaussHump.cpp
100.0%
100.0 % - 37 / 37 + 13 / 13 100.0 % 2 / 2 - 94.4 % - 17 / 18 + 62.5 % + 5 / 8 - GaussHump.cpp + SlotCyl.cpp
100.0%
100.0 % - 13 / 13 + 37 / 37 100.0 % 2 / 2 - 62.5 % - 5 / 8 + 94.4 % + 17 / 18 diff --git a/Release/test_coverage/PDE/Transport/Problem/index-sort-l.html b/Release/test_coverage/PDE/Transport/Problem/index-sort-l.html index 1cd5390b04f1..ce0998a43272 100644 --- a/Release/test_coverage/PDE/Transport/Problem/index-sort-l.html +++ b/Release/test_coverage/PDE/Transport/Problem/index-sort-l.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:26:06 + 2024-07-11 14:48:26 Functions: 6 diff --git a/Release/test_coverage/PDE/Transport/Problem/index.html b/Release/test_coverage/PDE/Transport/Problem/index.html index b05af6a5f4c1..e3a33623a13c 100644 --- a/Release/test_coverage/PDE/Transport/Problem/index.html +++ b/Release/test_coverage/PDE/Transport/Problem/index.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:26:06 + 2024-07-11 14:48:26 Functions: 6 diff --git a/Release/test_coverage/PDE/Transport/index-sort-b.html b/Release/test_coverage/PDE/Transport/index-sort-b.html index abf27a149d11..33fd98250479 100644 --- a/Release/test_coverage/PDE/Transport/index-sort-b.html +++ b/Release/test_coverage/PDE/Transport/index-sort-b.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:26:06 + 2024-07-11 14:48:26 Functions: 54 diff --git a/Release/test_coverage/PDE/Transport/index-sort-f.html b/Release/test_coverage/PDE/Transport/index-sort-f.html index 5d2ec9b09b5e..c13c144f0055 100644 --- a/Release/test_coverage/PDE/Transport/index-sort-f.html +++ b/Release/test_coverage/PDE/Transport/index-sort-f.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:26:06 + 2024-07-11 14:48:26 Functions: 54 diff --git a/Release/test_coverage/PDE/Transport/index-sort-l.html b/Release/test_coverage/PDE/Transport/index-sort-l.html index da8307e88348..51141ac281da 100644 --- a/Release/test_coverage/PDE/Transport/index-sort-l.html +++ b/Release/test_coverage/PDE/Transport/index-sort-l.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:26:06 + 2024-07-11 14:48:26 Functions: 54 diff --git a/Release/test_coverage/PDE/Transport/index.html b/Release/test_coverage/PDE/Transport/index.html index 56d53b6314b2..f72ce82c0c2c 100644 --- a/Release/test_coverage/PDE/Transport/index.html +++ b/Release/test_coverage/PDE/Transport/index.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:26:06 + 2024-07-11 14:48:26 Functions: 54 diff --git a/Release/test_coverage/PDE/index-sort-b.html b/Release/test_coverage/PDE/index-sort-b.html index 7c4d50451ea8..57adfb70bd4b 100644 --- a/Release/test_coverage/PDE/index-sort-b.html +++ b/Release/test_coverage/PDE/index-sort-b.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:26:06 + 2024-07-11 14:48:26 Functions: 556 diff --git a/Release/test_coverage/PDE/index-sort-f.html b/Release/test_coverage/PDE/index-sort-f.html index c078d75edcfe..0314dc49f17a 100644 --- a/Release/test_coverage/PDE/index-sort-f.html +++ b/Release/test_coverage/PDE/index-sort-f.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:26:06 + 2024-07-11 14:48:26 Functions: 556 @@ -237,18 +237,6 @@ 48.4 % 59 / 122 - - ConfigureMultiMat.cpp - -
72.5%72.5%
- - 72.5 % - 37 / 51 - 100.0 % - 2 / 2 - 31.1 % - 46 / 148 - ConfigureTransport.cpp @@ -261,6 +249,18 @@ 43.1 % 56 / 130 + + ConfigureMultiMat.cpp + +
72.5%72.5%
+ + 72.5 % + 37 / 51 + 100.0 % + 2 / 2 + 31.1 % + 46 / 148 + PDEStack.cpp diff --git a/Release/test_coverage/PDE/index-sort-l.html b/Release/test_coverage/PDE/index-sort-l.html index 783469415168..6fefc5a97da9 100644 --- a/Release/test_coverage/PDE/index-sort-l.html +++ b/Release/test_coverage/PDE/index-sort-l.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:26:06 + 2024-07-11 14:48:26 Functions: 556 diff --git a/Release/test_coverage/PDE/index.html b/Release/test_coverage/PDE/index.html index ef2764d7d266..add572d6ffdc 100644 --- a/Release/test_coverage/PDE/index.html +++ b/Release/test_coverage/PDE/index.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:26:06 + 2024-07-11 14:48:26 Functions: 556 diff --git a/Release/test_coverage/Statistics/BiPDF.hpp.func-sort-c.html b/Release/test_coverage/Statistics/BiPDF.hpp.func-sort-c.html index 3ff23826b554..c2da8fa4dd07 100644 --- a/Release/test_coverage/Statistics/BiPDF.hpp.func-sort-c.html +++ b/Release/test_coverage/Statistics/BiPDF.hpp.func-sort-c.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:26:06 + 2024-07-11 14:48:26 Functions: 0 diff --git a/Release/test_coverage/Statistics/BiPDF.hpp.func.html b/Release/test_coverage/Statistics/BiPDF.hpp.func.html index adccf2ffdf08..cf19b82bb93d 100644 --- a/Release/test_coverage/Statistics/BiPDF.hpp.func.html +++ b/Release/test_coverage/Statistics/BiPDF.hpp.func.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:26:06 + 2024-07-11 14:48:26 Functions: 0 diff --git a/Release/test_coverage/Statistics/BiPDF.hpp.gcov.html b/Release/test_coverage/Statistics/BiPDF.hpp.gcov.html index 1633867f756c..43adbd5732eb 100644 --- a/Release/test_coverage/Statistics/BiPDF.hpp.gcov.html +++ b/Release/test_coverage/Statistics/BiPDF.hpp.gcov.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:26:06 + 2024-07-11 14:48:26 Functions: 0 diff --git a/Release/test_coverage/Statistics/PDFReducer.cpp.func-sort-c.html b/Release/test_coverage/Statistics/PDFReducer.cpp.func-sort-c.html index af4c7d65ee9b..7e37b59fced7 100644 --- a/Release/test_coverage/Statistics/PDFReducer.cpp.func-sort-c.html +++ b/Release/test_coverage/Statistics/PDFReducer.cpp.func-sort-c.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:26:06 + 2024-07-11 14:48:26 Functions: 2 diff --git a/Release/test_coverage/Statistics/PDFReducer.cpp.func.html b/Release/test_coverage/Statistics/PDFReducer.cpp.func.html index 24295de31b00..387781743c9f 100644 --- a/Release/test_coverage/Statistics/PDFReducer.cpp.func.html +++ b/Release/test_coverage/Statistics/PDFReducer.cpp.func.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:26:06 + 2024-07-11 14:48:26 Functions: 2 diff --git a/Release/test_coverage/Statistics/PDFReducer.cpp.gcov.html b/Release/test_coverage/Statistics/PDFReducer.cpp.gcov.html index ebbe50f5d771..d7be461248ad 100644 --- a/Release/test_coverage/Statistics/PDFReducer.cpp.gcov.html +++ b/Release/test_coverage/Statistics/PDFReducer.cpp.gcov.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:26:06 + 2024-07-11 14:48:26 Functions: 2 diff --git a/Release/test_coverage/Statistics/Statistics.cpp.func-sort-c.html b/Release/test_coverage/Statistics/Statistics.cpp.func-sort-c.html index 79d76c31efab..9e5efb967ec1 100644 --- a/Release/test_coverage/Statistics/Statistics.cpp.func-sort-c.html +++ b/Release/test_coverage/Statistics/Statistics.cpp.func-sort-c.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:26:06 + 2024-07-11 14:48:26 Functions: 0 diff --git a/Release/test_coverage/Statistics/Statistics.cpp.func.html b/Release/test_coverage/Statistics/Statistics.cpp.func.html index 413ff62cdb83..1e692cedd2d4 100644 --- a/Release/test_coverage/Statistics/Statistics.cpp.func.html +++ b/Release/test_coverage/Statistics/Statistics.cpp.func.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:26:06 + 2024-07-11 14:48:26 Functions: 0 diff --git a/Release/test_coverage/Statistics/Statistics.cpp.gcov.html b/Release/test_coverage/Statistics/Statistics.cpp.gcov.html index 6c442367475f..14a8b9d7a0aa 100644 --- a/Release/test_coverage/Statistics/Statistics.cpp.gcov.html +++ b/Release/test_coverage/Statistics/Statistics.cpp.gcov.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:26:06 + 2024-07-11 14:48:26 Functions: 0 diff --git a/Release/test_coverage/Statistics/TriPDF.hpp.func-sort-c.html b/Release/test_coverage/Statistics/TriPDF.hpp.func-sort-c.html index a5109b890b0f..4231bf257b3c 100644 --- a/Release/test_coverage/Statistics/TriPDF.hpp.func-sort-c.html +++ b/Release/test_coverage/Statistics/TriPDF.hpp.func-sort-c.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:26:06 + 2024-07-11 14:48:26 Functions: 0 diff --git a/Release/test_coverage/Statistics/TriPDF.hpp.func.html b/Release/test_coverage/Statistics/TriPDF.hpp.func.html index 3ddc41187a47..a23c8b85a5f3 100644 --- a/Release/test_coverage/Statistics/TriPDF.hpp.func.html +++ b/Release/test_coverage/Statistics/TriPDF.hpp.func.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:26:06 + 2024-07-11 14:48:26 Functions: 0 diff --git a/Release/test_coverage/Statistics/TriPDF.hpp.gcov.html b/Release/test_coverage/Statistics/TriPDF.hpp.gcov.html index 48242a6e25e9..aa91acc63eb4 100644 --- a/Release/test_coverage/Statistics/TriPDF.hpp.gcov.html +++ b/Release/test_coverage/Statistics/TriPDF.hpp.gcov.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:26:06 + 2024-07-11 14:48:26 Functions: 0 diff --git a/Release/test_coverage/Statistics/UniPDF.hpp.func-sort-c.html b/Release/test_coverage/Statistics/UniPDF.hpp.func-sort-c.html index a727e732b3de..87095a07f98f 100644 --- a/Release/test_coverage/Statistics/UniPDF.hpp.func-sort-c.html +++ b/Release/test_coverage/Statistics/UniPDF.hpp.func-sort-c.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:26:06 + 2024-07-11 14:48:26 Functions: 4 diff --git a/Release/test_coverage/Statistics/UniPDF.hpp.func.html b/Release/test_coverage/Statistics/UniPDF.hpp.func.html index 0595207278ee..17ea6551461c 100644 --- a/Release/test_coverage/Statistics/UniPDF.hpp.func.html +++ b/Release/test_coverage/Statistics/UniPDF.hpp.func.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:26:06 + 2024-07-11 14:48:26 Functions: 4 diff --git a/Release/test_coverage/Statistics/UniPDF.hpp.gcov.html b/Release/test_coverage/Statistics/UniPDF.hpp.gcov.html index 66a5403ce397..c8fc25489cc1 100644 --- a/Release/test_coverage/Statistics/UniPDF.hpp.gcov.html +++ b/Release/test_coverage/Statistics/UniPDF.hpp.gcov.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:26:06 + 2024-07-11 14:48:26 Functions: 4 diff --git a/Release/test_coverage/Statistics/index-sort-b.html b/Release/test_coverage/Statistics/index-sort-b.html index f4b4e68603e9..5979fc6a51fc 100644 --- a/Release/test_coverage/Statistics/index-sort-b.html +++ b/Release/test_coverage/Statistics/index-sort-b.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:26:06 + 2024-07-11 14:48:26 Functions: 6 diff --git a/Release/test_coverage/Statistics/index-sort-f.html b/Release/test_coverage/Statistics/index-sort-f.html index 98297a44d2a9..f0dc2be7c0b6 100644 --- a/Release/test_coverage/Statistics/index-sort-f.html +++ b/Release/test_coverage/Statistics/index-sort-f.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:26:06 + 2024-07-11 14:48:26 Functions: 6 @@ -82,28 +82,28 @@ Branches Sort by branch coverage - BiPDF.hpp + TriPDF.hpp
0.0%
0.0 % - 0 / 25 + 0 / 30 0.0 % 0 / 4 0.0 % - 0 / 38 + 0 / 54 - TriPDF.hpp + BiPDF.hpp
0.0%
0.0 % - 0 / 30 + 0 / 25 0.0 % 0 / 4 0.0 % - 0 / 54 + 0 / 38 Statistics.cpp diff --git a/Release/test_coverage/Statistics/index-sort-l.html b/Release/test_coverage/Statistics/index-sort-l.html index dafb5caa477d..670ba55265be 100644 --- a/Release/test_coverage/Statistics/index-sort-l.html +++ b/Release/test_coverage/Statistics/index-sort-l.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:26:06 + 2024-07-11 14:48:26 Functions: 6 diff --git a/Release/test_coverage/Statistics/index.html b/Release/test_coverage/Statistics/index.html index e261ddeee6a2..806b3ba37a6e 100644 --- a/Release/test_coverage/Statistics/index.html +++ b/Release/test_coverage/Statistics/index.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:26:06 + 2024-07-11 14:48:26 Functions: 6 diff --git a/Release/test_coverage/Transfer/M2MTransfer.cpp.func-sort-c.html b/Release/test_coverage/Transfer/M2MTransfer.cpp.func-sort-c.html index cf46fb87dffb..1d76ec6a6a98 100644 --- a/Release/test_coverage/Transfer/M2MTransfer.cpp.func-sort-c.html +++ b/Release/test_coverage/Transfer/M2MTransfer.cpp.func-sort-c.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:26:06 + 2024-07-11 14:48:26 Functions: 11 diff --git a/Release/test_coverage/Transfer/M2MTransfer.cpp.func.html b/Release/test_coverage/Transfer/M2MTransfer.cpp.func.html index b8497031aa48..f13cc8e982d7 100644 --- a/Release/test_coverage/Transfer/M2MTransfer.cpp.func.html +++ b/Release/test_coverage/Transfer/M2MTransfer.cpp.func.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:26:06 + 2024-07-11 14:48:26 Functions: 11 diff --git a/Release/test_coverage/Transfer/M2MTransfer.cpp.gcov.html b/Release/test_coverage/Transfer/M2MTransfer.cpp.gcov.html index 56e8579598dd..b84a038ae9ce 100644 --- a/Release/test_coverage/Transfer/M2MTransfer.cpp.gcov.html +++ b/Release/test_coverage/Transfer/M2MTransfer.cpp.gcov.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:26:06 + 2024-07-11 14:48:26 Functions: 11 @@ -188,10 +188,10 @@ 111 : : 112 : : // Separate collisions based on the destination mesh chare they belong to 113 [ + + ]: 3461332 : for (int i = 0; i < nColl; i++) { - 114 [ + + ][ + - ]: 3461022 : if (colls[i].A.chunk >= first && colls[i].A.chunk < first + nchare) { - 115 [ + - ]: 279066 : separated[static_cast<std::size_t>(colls[i].A.chunk - first)].push_back(colls[i]); + 114 [ + + ][ + - ]: 3461022 : if (colls[i].A.chunk >= first && colls[i].A.chunk < first + nchare) { + 115 [ + - ]: 3257672 : separated[static_cast<std::size_t>(colls[i].A.chunk - first)].push_back(colls[i]); 116 : : } else { - 117 [ + - ]: 3181956 : separated[static_cast<std::size_t>(colls[i].B.chunk - first)].push_back(colls[i]); + 117 [ + - ]: 203350 : separated[static_cast<std::size_t>(colls[i].B.chunk - first)].push_back(colls[i]); 118 : : } 119 : : } 120 : : diff --git a/Release/test_coverage/Transfer/M2MTransfer.hpp.func-sort-c.html b/Release/test_coverage/Transfer/M2MTransfer.hpp.func-sort-c.html index 6b4439722a96..cfca576f0183 100644 --- a/Release/test_coverage/Transfer/M2MTransfer.hpp.func-sort-c.html +++ b/Release/test_coverage/Transfer/M2MTransfer.hpp.func-sort-c.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:26:06 + 2024-07-11 14:48:26 Functions: 1 diff --git a/Release/test_coverage/Transfer/M2MTransfer.hpp.func.html b/Release/test_coverage/Transfer/M2MTransfer.hpp.func.html index 1ec19276f81e..7b03f4823894 100644 --- a/Release/test_coverage/Transfer/M2MTransfer.hpp.func.html +++ b/Release/test_coverage/Transfer/M2MTransfer.hpp.func.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:26:06 + 2024-07-11 14:48:26 Functions: 1 diff --git a/Release/test_coverage/Transfer/M2MTransfer.hpp.gcov.html b/Release/test_coverage/Transfer/M2MTransfer.hpp.gcov.html index ac68d7b5d126..5b4ec080c0f8 100644 --- a/Release/test_coverage/Transfer/M2MTransfer.hpp.gcov.html +++ b/Release/test_coverage/Transfer/M2MTransfer.hpp.gcov.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:26:06 + 2024-07-11 14:48:26 Functions: 1 diff --git a/Release/test_coverage/Transfer/TransferDetails.cpp.func-sort-c.html b/Release/test_coverage/Transfer/TransferDetails.cpp.func-sort-c.html index 01be814da77b..39bb77bd6501 100644 --- a/Release/test_coverage/Transfer/TransferDetails.cpp.func-sort-c.html +++ b/Release/test_coverage/Transfer/TransferDetails.cpp.func-sort-c.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:26:06 + 2024-07-11 14:48:26 Functions: 9 diff --git a/Release/test_coverage/Transfer/TransferDetails.cpp.func.html b/Release/test_coverage/Transfer/TransferDetails.cpp.func.html index 4dda19e5b70e..56abee0a84f8 100644 --- a/Release/test_coverage/Transfer/TransferDetails.cpp.func.html +++ b/Release/test_coverage/Transfer/TransferDetails.cpp.func.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:26:06 + 2024-07-11 14:48:26 Functions: 9 diff --git a/Release/test_coverage/Transfer/TransferDetails.cpp.gcov.html b/Release/test_coverage/Transfer/TransferDetails.cpp.gcov.html index 5df61b64cfda..5268e757f789 100644 --- a/Release/test_coverage/Transfer/TransferDetails.cpp.gcov.html +++ b/Release/test_coverage/Transfer/TransferDetails.cpp.gcov.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:26:06 + 2024-07-11 14:48:26 Functions: 9 @@ -255,14 +255,14 @@ 181 [ + + ]: 3462254 : for (int i = 0; i < nColl; i++) { 182 : : int chareindex; 183 : : PotentialCollision pColl; - 184 [ + + ]: 3461022 : if (colls[i].A.chunk == mychunk) { - 185 : 279066 : chareindex = colls[i].B.chunk - chunkoffset; - 186 : 279066 : pColl.dest_index = static_cast<std::size_t>(colls[i].A.number); - 187 : 279066 : pColl.source_index = static_cast<std::size_t>(colls[i].B.number); + 184 [ + + ]: 3461022 : if (colls[i].A.chunk == mychunk) { + 185 : 3257672 : chareindex = colls[i].B.chunk - chunkoffset; + 186 : 3257672 : pColl.dest_index = static_cast<std::size_t>(colls[i].A.number); + 187 : 3257672 : pColl.source_index = static_cast<std::size_t>(colls[i].B.number); 188 : : } else { - 189 : 3181956 : chareindex = colls[i].A.chunk - chunkoffset; - 190 : 3181956 : pColl.dest_index = static_cast<std::size_t>(colls[i].B.number); - 191 : 3181956 : pColl.source_index = static_cast<std::size_t>(colls[i].A.number); + 189 : 203350 : chareindex = colls[i].A.chunk - chunkoffset; + 190 : 203350 : pColl.dest_index = static_cast<std::size_t>(colls[i].B.number); + 191 : 203350 : pColl.source_index = static_cast<std::size_t>(colls[i].A.number); 192 : : } 193 : : 194 : : #if defined(STRICT_GNUC) diff --git a/Release/test_coverage/Transfer/TransferDetails.hpp.func-sort-c.html b/Release/test_coverage/Transfer/TransferDetails.hpp.func-sort-c.html index 9d63ce036ef0..60e4a209d7c8 100644 --- a/Release/test_coverage/Transfer/TransferDetails.hpp.func-sort-c.html +++ b/Release/test_coverage/Transfer/TransferDetails.hpp.func-sort-c.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:26:06 + 2024-07-11 14:48:26 Functions: 1 diff --git a/Release/test_coverage/Transfer/TransferDetails.hpp.func.html b/Release/test_coverage/Transfer/TransferDetails.hpp.func.html index 7f760e2c45b4..12907cd07c5f 100644 --- a/Release/test_coverage/Transfer/TransferDetails.hpp.func.html +++ b/Release/test_coverage/Transfer/TransferDetails.hpp.func.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:26:06 + 2024-07-11 14:48:26 Functions: 1 diff --git a/Release/test_coverage/Transfer/TransferDetails.hpp.gcov.html b/Release/test_coverage/Transfer/TransferDetails.hpp.gcov.html index 5ff654f54b81..b20c95c467fd 100644 --- a/Release/test_coverage/Transfer/TransferDetails.hpp.gcov.html +++ b/Release/test_coverage/Transfer/TransferDetails.hpp.gcov.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:26:06 + 2024-07-11 14:48:26 Functions: 1 diff --git a/Release/test_coverage/Transfer/index-sort-b.html b/Release/test_coverage/Transfer/index-sort-b.html index 1f31bb5a43c0..45307ac19d30 100644 --- a/Release/test_coverage/Transfer/index-sort-b.html +++ b/Release/test_coverage/Transfer/index-sort-b.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:26:06 + 2024-07-11 14:48:26 Functions: 22 diff --git a/Release/test_coverage/Transfer/index-sort-f.html b/Release/test_coverage/Transfer/index-sort-f.html index a7f756beacef..1ac17070f558 100644 --- a/Release/test_coverage/Transfer/index-sort-f.html +++ b/Release/test_coverage/Transfer/index-sort-f.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:26:06 + 2024-07-11 14:48:26 Functions: 22 diff --git a/Release/test_coverage/Transfer/index-sort-l.html b/Release/test_coverage/Transfer/index-sort-l.html index c112a4c7b9c2..4827d797fe1e 100644 --- a/Release/test_coverage/Transfer/index-sort-l.html +++ b/Release/test_coverage/Transfer/index-sort-l.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:26:06 + 2024-07-11 14:48:26 Functions: 22 diff --git a/Release/test_coverage/Transfer/index.html b/Release/test_coverage/Transfer/index.html index c4f2ab61cdad..f09aa8a44598 100644 --- a/Release/test_coverage/Transfer/index.html +++ b/Release/test_coverage/Transfer/index.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:26:06 + 2024-07-11 14:48:26 Functions: 22 diff --git a/Release/test_coverage/UnitTest/Assessment.cpp.func-sort-c.html b/Release/test_coverage/UnitTest/Assessment.cpp.func-sort-c.html index 3de8380e5c38..202f2ebcf9fe 100644 --- a/Release/test_coverage/UnitTest/Assessment.cpp.func-sort-c.html +++ b/Release/test_coverage/UnitTest/Assessment.cpp.func-sort-c.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:26:06 + 2024-07-11 14:48:26 Functions: 2 diff --git a/Release/test_coverage/UnitTest/Assessment.cpp.func.html b/Release/test_coverage/UnitTest/Assessment.cpp.func.html index cfcb41531c5f..ac31dd0db3d2 100644 --- a/Release/test_coverage/UnitTest/Assessment.cpp.func.html +++ b/Release/test_coverage/UnitTest/Assessment.cpp.func.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:26:06 + 2024-07-11 14:48:26 Functions: 2 diff --git a/Release/test_coverage/UnitTest/Assessment.cpp.gcov.html b/Release/test_coverage/UnitTest/Assessment.cpp.gcov.html index b62ceeb5e6d5..616f113f5763 100644 --- a/Release/test_coverage/UnitTest/Assessment.cpp.gcov.html +++ b/Release/test_coverage/UnitTest/Assessment.cpp.gcov.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:26:06 + 2024-07-11 14:48:26 Functions: 2 diff --git a/Release/test_coverage/UnitTest/MPIRunner.hpp.func-sort-c.html b/Release/test_coverage/UnitTest/MPIRunner.hpp.func-sort-c.html index 96409724a7ca..5d1885daf587 100644 --- a/Release/test_coverage/UnitTest/MPIRunner.hpp.func-sort-c.html +++ b/Release/test_coverage/UnitTest/MPIRunner.hpp.func-sort-c.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:26:06 + 2024-07-11 14:48:26 Functions: 2 diff --git a/Release/test_coverage/UnitTest/MPIRunner.hpp.func.html b/Release/test_coverage/UnitTest/MPIRunner.hpp.func.html index bba8dffa19e0..119cc887db9e 100644 --- a/Release/test_coverage/UnitTest/MPIRunner.hpp.func.html +++ b/Release/test_coverage/UnitTest/MPIRunner.hpp.func.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:26:06 + 2024-07-11 14:48:26 Functions: 2 diff --git a/Release/test_coverage/UnitTest/MPIRunner.hpp.gcov.html b/Release/test_coverage/UnitTest/MPIRunner.hpp.gcov.html index ec13bf209766..94aa306ecac3 100644 --- a/Release/test_coverage/UnitTest/MPIRunner.hpp.gcov.html +++ b/Release/test_coverage/UnitTest/MPIRunner.hpp.gcov.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:26:06 + 2024-07-11 14:48:26 Functions: 2 diff --git a/Release/test_coverage/UnitTest/QuietCerr.cpp.func-sort-c.html b/Release/test_coverage/UnitTest/QuietCerr.cpp.func-sort-c.html index 1531ebce70c8..6c3c650bdaab 100644 --- a/Release/test_coverage/UnitTest/QuietCerr.cpp.func-sort-c.html +++ b/Release/test_coverage/UnitTest/QuietCerr.cpp.func-sort-c.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:26:06 + 2024-07-11 14:48:26 Functions: 1 diff --git a/Release/test_coverage/UnitTest/QuietCerr.cpp.func.html b/Release/test_coverage/UnitTest/QuietCerr.cpp.func.html index 2b8b718a0dd2..52bf6d2d1eea 100644 --- a/Release/test_coverage/UnitTest/QuietCerr.cpp.func.html +++ b/Release/test_coverage/UnitTest/QuietCerr.cpp.func.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:26:06 + 2024-07-11 14:48:26 Functions: 1 diff --git a/Release/test_coverage/UnitTest/QuietCerr.cpp.gcov.html b/Release/test_coverage/UnitTest/QuietCerr.cpp.gcov.html index c86f2d962b34..8e30080f6bbd 100644 --- a/Release/test_coverage/UnitTest/QuietCerr.cpp.gcov.html +++ b/Release/test_coverage/UnitTest/QuietCerr.cpp.gcov.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:26:06 + 2024-07-11 14:48:26 Functions: 1 diff --git a/Release/test_coverage/UnitTest/QuietCerr.hpp.func-sort-c.html b/Release/test_coverage/UnitTest/QuietCerr.hpp.func-sort-c.html index e62ce4d9ccab..ad59debb259c 100644 --- a/Release/test_coverage/UnitTest/QuietCerr.hpp.func-sort-c.html +++ b/Release/test_coverage/UnitTest/QuietCerr.hpp.func-sort-c.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:26:06 + 2024-07-11 14:48:26 Functions: 0 diff --git a/Release/test_coverage/UnitTest/QuietCerr.hpp.func.html b/Release/test_coverage/UnitTest/QuietCerr.hpp.func.html index 436f816efeed..25f9d8a13891 100644 --- a/Release/test_coverage/UnitTest/QuietCerr.hpp.func.html +++ b/Release/test_coverage/UnitTest/QuietCerr.hpp.func.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:26:06 + 2024-07-11 14:48:26 Functions: 0 diff --git a/Release/test_coverage/UnitTest/QuietCerr.hpp.gcov.html b/Release/test_coverage/UnitTest/QuietCerr.hpp.gcov.html index cce4bee0bb73..7c2c9c83e532 100644 --- a/Release/test_coverage/UnitTest/QuietCerr.hpp.gcov.html +++ b/Release/test_coverage/UnitTest/QuietCerr.hpp.gcov.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:26:06 + 2024-07-11 14:48:26 Functions: 0 diff --git a/Release/test_coverage/UnitTest/TUTSuite.cpp.func-sort-c.html b/Release/test_coverage/UnitTest/TUTSuite.cpp.func-sort-c.html index c72f93fe32b4..09469dbc7935 100644 --- a/Release/test_coverage/UnitTest/TUTSuite.cpp.func-sort-c.html +++ b/Release/test_coverage/UnitTest/TUTSuite.cpp.func-sort-c.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:26:06 + 2024-07-11 14:48:26 Functions: 3 diff --git a/Release/test_coverage/UnitTest/TUTSuite.cpp.func.html b/Release/test_coverage/UnitTest/TUTSuite.cpp.func.html index 905b82c4f294..a42a3f9f0499 100644 --- a/Release/test_coverage/UnitTest/TUTSuite.cpp.func.html +++ b/Release/test_coverage/UnitTest/TUTSuite.cpp.func.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:26:06 + 2024-07-11 14:48:26 Functions: 3 diff --git a/Release/test_coverage/UnitTest/TUTSuite.cpp.gcov.html b/Release/test_coverage/UnitTest/TUTSuite.cpp.gcov.html index 01f0b0ca713a..2100ac205f83 100644 --- a/Release/test_coverage/UnitTest/TUTSuite.cpp.gcov.html +++ b/Release/test_coverage/UnitTest/TUTSuite.cpp.gcov.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:26:06 + 2024-07-11 14:48:26 Functions: 3 diff --git a/Release/test_coverage/UnitTest/TUTSuite.hpp.func-sort-c.html b/Release/test_coverage/UnitTest/TUTSuite.hpp.func-sort-c.html index 9898320b5d98..cf5c0b800211 100644 --- a/Release/test_coverage/UnitTest/TUTSuite.hpp.func-sort-c.html +++ b/Release/test_coverage/UnitTest/TUTSuite.hpp.func-sort-c.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:26:06 + 2024-07-11 14:48:26 Functions: 1 diff --git a/Release/test_coverage/UnitTest/TUTSuite.hpp.func.html b/Release/test_coverage/UnitTest/TUTSuite.hpp.func.html index d9632ba903b9..bf271a2504c0 100644 --- a/Release/test_coverage/UnitTest/TUTSuite.hpp.func.html +++ b/Release/test_coverage/UnitTest/TUTSuite.hpp.func.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:26:06 + 2024-07-11 14:48:26 Functions: 1 diff --git a/Release/test_coverage/UnitTest/TUTSuite.hpp.gcov.html b/Release/test_coverage/UnitTest/TUTSuite.hpp.gcov.html index 73a240adfcc7..4ad7ffe1d2a1 100644 --- a/Release/test_coverage/UnitTest/TUTSuite.hpp.gcov.html +++ b/Release/test_coverage/UnitTest/TUTSuite.hpp.gcov.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:26:06 + 2024-07-11 14:48:26 Functions: 1 diff --git a/Release/test_coverage/UnitTest/TUTTest.hpp.func-sort-c.html b/Release/test_coverage/UnitTest/TUTTest.hpp.func-sort-c.html index aadb162a2cc7..bebca728b9fd 100644 --- a/Release/test_coverage/UnitTest/TUTTest.hpp.func-sort-c.html +++ b/Release/test_coverage/UnitTest/TUTTest.hpp.func-sort-c.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:26:06 + 2024-07-11 14:48:26 Functions: 1 diff --git a/Release/test_coverage/UnitTest/TUTTest.hpp.func.html b/Release/test_coverage/UnitTest/TUTTest.hpp.func.html index 9fd16d38eaf4..c7a07a1af5ab 100644 --- a/Release/test_coverage/UnitTest/TUTTest.hpp.func.html +++ b/Release/test_coverage/UnitTest/TUTTest.hpp.func.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:26:06 + 2024-07-11 14:48:26 Functions: 1 diff --git a/Release/test_coverage/UnitTest/TUTTest.hpp.gcov.html b/Release/test_coverage/UnitTest/TUTTest.hpp.gcov.html index 577e4712ea66..63c3072057a6 100644 --- a/Release/test_coverage/UnitTest/TUTTest.hpp.gcov.html +++ b/Release/test_coverage/UnitTest/TUTTest.hpp.gcov.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:26:06 + 2024-07-11 14:48:26 Functions: 1 diff --git a/Release/test_coverage/UnitTest/TUTUtil.hpp.func-sort-c.html b/Release/test_coverage/UnitTest/TUTUtil.hpp.func-sort-c.html index 2937741fc9f7..9d6d670e3710 100644 --- a/Release/test_coverage/UnitTest/TUTUtil.hpp.func-sort-c.html +++ b/Release/test_coverage/UnitTest/TUTUtil.hpp.func-sort-c.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:26:06 + 2024-07-11 14:48:26 Functions: 0 diff --git a/Release/test_coverage/UnitTest/TUTUtil.hpp.func.html b/Release/test_coverage/UnitTest/TUTUtil.hpp.func.html index 7037686072fe..9e6aef91b04a 100644 --- a/Release/test_coverage/UnitTest/TUTUtil.hpp.func.html +++ b/Release/test_coverage/UnitTest/TUTUtil.hpp.func.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:26:06 + 2024-07-11 14:48:26 Functions: 0 diff --git a/Release/test_coverage/UnitTest/TUTUtil.hpp.gcov.html b/Release/test_coverage/UnitTest/TUTUtil.hpp.gcov.html index 2a2aaece8172..e55cea4235c9 100644 --- a/Release/test_coverage/UnitTest/TUTUtil.hpp.gcov.html +++ b/Release/test_coverage/UnitTest/TUTUtil.hpp.gcov.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:26:06 + 2024-07-11 14:48:26 Functions: 0 diff --git a/Release/test_coverage/UnitTest/TestArray.hpp.func-sort-c.html b/Release/test_coverage/UnitTest/TestArray.hpp.func-sort-c.html index 24d15c4d5f19..646ce5b6a450 100644 --- a/Release/test_coverage/UnitTest/TestArray.hpp.func-sort-c.html +++ b/Release/test_coverage/UnitTest/TestArray.hpp.func-sort-c.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:26:06 + 2024-07-11 14:48:26 Functions: 0 diff --git a/Release/test_coverage/UnitTest/TestArray.hpp.func.html b/Release/test_coverage/UnitTest/TestArray.hpp.func.html index 33368e63dda9..f805061692ab 100644 --- a/Release/test_coverage/UnitTest/TestArray.hpp.func.html +++ b/Release/test_coverage/UnitTest/TestArray.hpp.func.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:26:06 + 2024-07-11 14:48:26 Functions: 0 diff --git a/Release/test_coverage/UnitTest/TestArray.hpp.gcov.html b/Release/test_coverage/UnitTest/TestArray.hpp.gcov.html index 82f0cbbbbb92..b86783da3ec4 100644 --- a/Release/test_coverage/UnitTest/TestArray.hpp.gcov.html +++ b/Release/test_coverage/UnitTest/TestArray.hpp.gcov.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:26:06 + 2024-07-11 14:48:26 Functions: 0 diff --git a/Release/test_coverage/UnitTest/index-sort-b.html b/Release/test_coverage/UnitTest/index-sort-b.html index 3c340d793705..192e19032bc8 100644 --- a/Release/test_coverage/UnitTest/index-sort-b.html +++ b/Release/test_coverage/UnitTest/index-sort-b.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:26:06 + 2024-07-11 14:48:26 Functions: 10 diff --git a/Release/test_coverage/UnitTest/index-sort-f.html b/Release/test_coverage/UnitTest/index-sort-f.html index 60424cba09db..1a9b91c3a8cc 100644 --- a/Release/test_coverage/UnitTest/index-sort-f.html +++ b/Release/test_coverage/UnitTest/index-sort-f.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:26:06 + 2024-07-11 14:48:26 Functions: 10 diff --git a/Release/test_coverage/UnitTest/index-sort-l.html b/Release/test_coverage/UnitTest/index-sort-l.html index 2d0a1231bb6c..5b8e23fbd277 100644 --- a/Release/test_coverage/UnitTest/index-sort-l.html +++ b/Release/test_coverage/UnitTest/index-sort-l.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:26:06 + 2024-07-11 14:48:26 Functions: 10 diff --git a/Release/test_coverage/UnitTest/index.html b/Release/test_coverage/UnitTest/index.html index b0a77271cb7c..b12d4c5cf2da 100644 --- a/Release/test_coverage/UnitTest/index.html +++ b/Release/test_coverage/UnitTest/index.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:26:06 + 2024-07-11 14:48:26 Functions: 10 diff --git a/Release/test_coverage/index-sort-b.html b/Release/test_coverage/index-sort-b.html index d6c0569a0fb8..2c306d0cc23b 100644 --- a/Release/test_coverage/index-sort-b.html +++ b/Release/test_coverage/index-sort-b.html @@ -27,16 +27,16 @@ -128-NOTFOUND Lines: - 16025 - 20970 + 16054 + 21003 76.4 % Date: - 2024-07-10 11:26:06 + 2024-07-11 14:48:26 Functions: - 2614 + 2616 6127 42.7 % @@ -49,9 +49,9 @@ Branches: - 16254 - 42520 - 38.2 % + 16286 + 42570 + 38.3 % @@ -136,10 +136,10 @@ 12.0 % 59 / 493 - 26.8 % - 38 / 142 + 27.5 % + 39 / 142 9.1 % - 228 / 2502 + 227 / 2502 Control/Inciter/CmdLine @@ -204,38 +204,26 @@ PDE/MultiMat -
62.1%62.1%
+
62.5%62.5%
- 62.1 % - 574 / 925 - 11.5 % - 66 / 574 + 62.5 % + 578 / 925 + 11.7 % + 67 / 574 25.9 % - 509 / 1968 - - - PDE/Riemann - -
74.1%74.1%
- - 74.1 % - 281 / 379 - 87.5 % - 7 / 8 - 32.1 % - 109 / 340 + 510 / 1968 Base -
82.1%82.1%
+
82.6%82.6%
- 82.1 % - 772 / 940 + 82.6 % + 776 / 940 93.1 % 647 / 695 - 34.0 % - 1086 / 3191 + 34.2 % + 1094 / 3199 Control @@ -249,6 +237,18 @@ 34.5 % 151 / 438 + + PDE/Riemann + +
73.3%73.3%
+ + 73.3 % + 302 / 412 + 87.5 % + 7 / 8 + 34.8 % + 133 / 382 + PDE/CompFlow/Problem diff --git a/Release/test_coverage/index-sort-f.html b/Release/test_coverage/index-sort-f.html index fd726c7da409..afa7da7063f6 100644 --- a/Release/test_coverage/index-sort-f.html +++ b/Release/test_coverage/index-sort-f.html @@ -27,16 +27,16 @@ -128-NOTFOUND Lines: - 16025 - 20970 + 16054 + 21003 76.4 % Date: - 2024-07-10 11:26:06 + 2024-07-11 14:48:26 Functions: - 2614 + 2616 6127 42.7 % @@ -49,9 +49,9 @@ Branches: - 16254 - 42520 - 38.2 % + 16286 + 42570 + 38.3 % @@ -108,14 +108,14 @@ PDE/MultiMat -
62.1%62.1%
+
62.5%62.5%
- 62.1 % - 574 / 925 - 11.5 % - 66 / 574 + 62.5 % + 578 / 925 + 11.7 % + 67 / 574 25.9 % - 509 / 1968 + 510 / 1968 PDE @@ -141,18 +141,6 @@ 4.7 % 17 / 362 - - PDE/EoS - -
12.0%12.0%
- - 12.0 % - 59 / 493 - 26.8 % - 38 / 142 - 9.1 % - 228 / 2502 - PDE/CompFlow @@ -165,6 +153,18 @@ 58.1 % 489 / 842 + + PDE/EoS + +
12.0%12.0%
+ + 12.0 % + 59 / 493 + 27.5 % + 39 / 142 + 9.1 % + 227 / 2502 + PDE/Transport @@ -300,14 +300,14 @@ PDE/Riemann -
74.1%74.1%
+
73.3%73.3%
- 74.1 % - 281 / 379 + 73.3 % + 302 / 412 87.5 % 7 / 8 - 32.1 % - 109 / 340 + 34.8 % + 133 / 382 Main @@ -348,14 +348,14 @@ Base -
82.1%82.1%
+
82.6%82.6%
- 82.1 % - 772 / 940 + 82.6 % + 776 / 940 93.1 % 647 / 695 - 34.0 % - 1086 / 3191 + 34.2 % + 1094 / 3199 Mesh @@ -393,18 +393,6 @@ 36.7 % 11 / 30 - - Control/MeshConv/CmdLine - -
66.7%66.7%
- - 66.7 % - 34 / 51 - 100.0 % - 3 / 3 - 8.6 % - 25 / 290 - Control/Inciter/CmdLine @@ -417,6 +405,18 @@ 9.7 % 28 / 288 + + Control/MeshConv/CmdLine + +
66.7%66.7%
+ + 66.7 % + 34 / 51 + 100.0 % + 3 / 3 + 8.6 % + 25 / 290 + Control/UnitTest/CmdLine diff --git a/Release/test_coverage/index-sort-l.html b/Release/test_coverage/index-sort-l.html index 1c5d4b20c1f2..57c72d882859 100644 --- a/Release/test_coverage/index-sort-l.html +++ b/Release/test_coverage/index-sort-l.html @@ -27,16 +27,16 @@ -128-NOTFOUND Lines: - 16025 - 20970 + 16054 + 21003 76.4 % Date: - 2024-07-10 11:26:06 + 2024-07-11 14:48:26 Functions: - 2614 + 2616 6127 42.7 % @@ -49,9 +49,9 @@ Branches: - 16254 - 42520 - 38.2 % + 16286 + 42570 + 38.3 % @@ -112,10 +112,10 @@ 12.0 % 59 / 493 - 26.8 % - 38 / 142 + 27.5 % + 39 / 142 9.1 % - 228 / 2502 + 227 / 2502 Statistics @@ -180,14 +180,14 @@ PDE/MultiMat -
62.1%62.1%
+
62.5%62.5%
- 62.1 % - 574 / 925 - 11.5 % - 66 / 574 + 62.5 % + 578 / 925 + 11.7 % + 67 / 574 25.9 % - 509 / 1968 + 510 / 1968 Control/MeshConv/CmdLine @@ -264,14 +264,14 @@ PDE/Riemann -
74.1%74.1%
+
73.3%73.3%
- 74.1 % - 281 / 379 + 73.3 % + 302 / 412 87.5 % 7 / 8 - 32.1 % - 109 / 340 + 34.8 % + 133 / 382 /tmp/TeamCity-1/work/5ad443c8abe7fc0a/build/Main @@ -312,14 +312,14 @@ Base -
82.1%82.1%
+
82.6%82.6%
- 82.1 % - 772 / 940 + 82.6 % + 776 / 940 93.1 % 647 / 695 - 34.0 % - 1086 / 3191 + 34.2 % + 1094 / 3199 Main diff --git a/Release/test_coverage/index.html b/Release/test_coverage/index.html index aeabb49edb8f..f3a23020fc20 100644 --- a/Release/test_coverage/index.html +++ b/Release/test_coverage/index.html @@ -27,16 +27,16 @@ -128-NOTFOUND Lines: - 16025 - 20970 + 16054 + 21003 76.4 % Date: - 2024-07-10 11:26:06 + 2024-07-11 14:48:26 Functions: - 2614 + 2616 6127 42.7 % @@ -49,9 +49,9 @@ Branches: - 16254 - 42520 - 38.2 % + 16286 + 42570 + 38.3 % @@ -96,14 +96,14 @@ Base -
82.1%82.1%
+
82.6%82.6%
- 82.1 % - 772 / 940 + 82.6 % + 776 / 940 93.1 % 647 / 695 - 34.0 % - 1086 / 3191 + 34.2 % + 1094 / 3199 Control @@ -340,10 +340,10 @@ 12.0 % 59 / 493 - 26.8 % - 38 / 142 + 27.5 % + 39 / 142 9.1 % - 228 / 2502 + 227 / 2502 PDE/Integrate @@ -360,14 +360,14 @@ PDE/MultiMat -
62.1%62.1%
+
62.5%62.5%
- 62.1 % - 574 / 925 - 11.5 % - 66 / 574 + 62.5 % + 578 / 925 + 11.7 % + 67 / 574 25.9 % - 509 / 1968 + 510 / 1968 PDE/MultiMat/Physics @@ -396,14 +396,14 @@ PDE/Riemann -
74.1%74.1%
+
73.3%73.3%
- 74.1 % - 281 / 379 + 73.3 % + 302 / 412 87.5 % 7 / 8 - 32.1 % - 109 / 340 + 34.8 % + 133 / 382 PDE/Transport diff --git a/Release/test_coverage/tmp/TeamCity-1/work/5ad443c8abe7fc0a/build/Main/QuinoaConfig.cpp.func-sort-c.html b/Release/test_coverage/tmp/TeamCity-1/work/5ad443c8abe7fc0a/build/Main/QuinoaConfig.cpp.func-sort-c.html index 60999e484b90..3f6095ecd314 100644 --- a/Release/test_coverage/tmp/TeamCity-1/work/5ad443c8abe7fc0a/build/Main/QuinoaConfig.cpp.func-sort-c.html +++ b/Release/test_coverage/tmp/TeamCity-1/work/5ad443c8abe7fc0a/build/Main/QuinoaConfig.cpp.func-sort-c.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:26:06 + 2024-07-11 14:48:26 Functions: 10 diff --git a/Release/test_coverage/tmp/TeamCity-1/work/5ad443c8abe7fc0a/build/Main/QuinoaConfig.cpp.func.html b/Release/test_coverage/tmp/TeamCity-1/work/5ad443c8abe7fc0a/build/Main/QuinoaConfig.cpp.func.html index 67eb73fd50a7..0fef451bc9f9 100644 --- a/Release/test_coverage/tmp/TeamCity-1/work/5ad443c8abe7fc0a/build/Main/QuinoaConfig.cpp.func.html +++ b/Release/test_coverage/tmp/TeamCity-1/work/5ad443c8abe7fc0a/build/Main/QuinoaConfig.cpp.func.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:26:06 + 2024-07-11 14:48:26 Functions: 10 diff --git a/Release/test_coverage/tmp/TeamCity-1/work/5ad443c8abe7fc0a/build/Main/QuinoaConfig.cpp.gcov.html b/Release/test_coverage/tmp/TeamCity-1/work/5ad443c8abe7fc0a/build/Main/QuinoaConfig.cpp.gcov.html index 35fd7ece301c..38485776cdec 100644 --- a/Release/test_coverage/tmp/TeamCity-1/work/5ad443c8abe7fc0a/build/Main/QuinoaConfig.cpp.gcov.html +++ b/Release/test_coverage/tmp/TeamCity-1/work/5ad443c8abe7fc0a/build/Main/QuinoaConfig.cpp.gcov.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:26:06 + 2024-07-11 14:48:26 Functions: 10 @@ -103,7 +103,7 @@ 29 : : #define COMPILER "/usr/bin/g++" 30 : : #define BUILD_HOSTNAME "lagrange" 31 : : #define BUILD_TYPE "RELEASE" - 32 : : #define BUILD_DATE "Wed 10 Jul 2024 11:20:37 AM MDT" + 32 : : #define BUILD_DATE "Thu 11 Jul 2024 02:42:55 PM MDT" 33 : : #define REGRESSION_DIR "/tmp/TeamCity-1/work/5ad443c8abe7fc0a/tests/regression" 34 : : 35 : : // Accessor definitions as strings of configuration values imported from cmake diff --git a/Release/test_coverage/tmp/TeamCity-1/work/5ad443c8abe7fc0a/build/Main/index-sort-b.html b/Release/test_coverage/tmp/TeamCity-1/work/5ad443c8abe7fc0a/build/Main/index-sort-b.html index cd5f291fea40..72802c413b85 100644 --- a/Release/test_coverage/tmp/TeamCity-1/work/5ad443c8abe7fc0a/build/Main/index-sort-b.html +++ b/Release/test_coverage/tmp/TeamCity-1/work/5ad443c8abe7fc0a/build/Main/index-sort-b.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:26:06 + 2024-07-11 14:48:26 Functions: 10 diff --git a/Release/test_coverage/tmp/TeamCity-1/work/5ad443c8abe7fc0a/build/Main/index-sort-f.html b/Release/test_coverage/tmp/TeamCity-1/work/5ad443c8abe7fc0a/build/Main/index-sort-f.html index 289366c63822..f1a01de2a8f8 100644 --- a/Release/test_coverage/tmp/TeamCity-1/work/5ad443c8abe7fc0a/build/Main/index-sort-f.html +++ b/Release/test_coverage/tmp/TeamCity-1/work/5ad443c8abe7fc0a/build/Main/index-sort-f.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:26:06 + 2024-07-11 14:48:26 Functions: 10 diff --git a/Release/test_coverage/tmp/TeamCity-1/work/5ad443c8abe7fc0a/build/Main/index-sort-l.html b/Release/test_coverage/tmp/TeamCity-1/work/5ad443c8abe7fc0a/build/Main/index-sort-l.html index 767535dff1bf..08e627570467 100644 --- a/Release/test_coverage/tmp/TeamCity-1/work/5ad443c8abe7fc0a/build/Main/index-sort-l.html +++ b/Release/test_coverage/tmp/TeamCity-1/work/5ad443c8abe7fc0a/build/Main/index-sort-l.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:26:06 + 2024-07-11 14:48:26 Functions: 10 diff --git a/Release/test_coverage/tmp/TeamCity-1/work/5ad443c8abe7fc0a/build/Main/index.html b/Release/test_coverage/tmp/TeamCity-1/work/5ad443c8abe7fc0a/build/Main/index.html index 1b74f973b0b0..3d6d086afac0 100644 --- a/Release/test_coverage/tmp/TeamCity-1/work/5ad443c8abe7fc0a/build/Main/index.html +++ b/Release/test_coverage/tmp/TeamCity-1/work/5ad443c8abe7fc0a/build/Main/index.html @@ -33,7 +33,7 @@ Date: - 2024-07-10 11:26:06 + 2024-07-11 14:48:26 Functions: 10 diff --git a/_a_l_e_8cpp.html b/_a_l_e_8cpp.html index 10e206aff5c4..72a1343d4bcb 100644 --- a/_a_l_e_8cpp.html +++ b/_a_l_e_8cpp.html @@ -129,7 +129,7 @@

Namespaces

-

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Wednesday, Jul 10, 2024 using Doxygen and m.css. Contact us via GitHub.

+

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Thursday, Jul 11, 2024 using Doxygen and m.css. Contact us via GitHub.

diff --git a/_a_l_e_8hpp.html b/_a_l_e_8hpp.html index c9bd92ddce15..1afc64f8de2a 100644 --- a/_a_l_e_8hpp.html +++ b/_a_l_e_8hpp.html @@ -139,7 +139,7 @@

Classes

-

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Wednesday, Jul 10, 2024 using Doxygen and m.css. Contact us via GitHub.

+

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Thursday, Jul 11, 2024 using Doxygen and m.css. Contact us via GitHub.

diff --git a/_a_l_e_c_g_8cpp.html b/_a_l_e_c_g_8cpp.html index ab687eed986c..f28fe5b8da96 100644 --- a/_a_l_e_c_g_8cpp.html +++ b/_a_l_e_c_g_8cpp.html @@ -129,7 +129,7 @@

Namespaces

-

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Wednesday, Jul 10, 2024 using Doxygen and m.css. Contact us via GitHub.

+

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Thursday, Jul 11, 2024 using Doxygen and m.css. Contact us via GitHub.

diff --git a/_a_l_e_c_g_8hpp.html b/_a_l_e_c_g_8hpp.html index 0eb3f29c2a27..a155f95192c8 100644 --- a/_a_l_e_c_g_8hpp.html +++ b/_a_l_e_c_g_8hpp.html @@ -139,7 +139,7 @@

Classes

-

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Wednesday, Jul 10, 2024 using Doxygen and m.css. Contact us via GitHub.

+

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Thursday, Jul 11, 2024 using Doxygen and m.css. Contact us via GitHub.

diff --git a/_a_m_r_error_8hpp.html b/_a_m_r_error_8hpp.html index 4d08b2392b4d..6b983e8075f7 100644 --- a/_a_m_r_error_8hpp.html +++ b/_a_m_r_error_8hpp.html @@ -141,7 +141,7 @@

Classes

-

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Wednesday, Jul 10, 2024 using Doxygen and m.css. Contact us via GitHub.

+

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Thursday, Jul 11, 2024 using Doxygen and m.css. Contact us via GitHub.

diff --git a/_a_m_r_initial_8hpp.html b/_a_m_r_initial_8hpp.html index 06a249acb0e8..d5f4ca5ef3fe 100644 --- a/_a_m_r_initial_8hpp.html +++ b/_a_m_r_initial_8hpp.html @@ -141,7 +141,7 @@

Classes

-

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Wednesday, Jul 10, 2024 using Doxygen and m.css. Contact us via GitHub.

+

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Thursday, Jul 11, 2024 using Doxygen and m.css. Contact us via GitHub.

diff --git a/_a_s_c_mesh_reader_8cpp.html b/_a_s_c_mesh_reader_8cpp.html index 89f3283d50ab..380c9329b560 100644 --- a/_a_s_c_mesh_reader_8cpp.html +++ b/_a_s_c_mesh_reader_8cpp.html @@ -111,7 +111,7 @@

-

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Wednesday, Jul 10, 2024 using Doxygen and m.css. Contact us via GitHub.

+

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Thursday, Jul 11, 2024 using Doxygen and m.css. Contact us via GitHub.

diff --git a/_a_s_c_mesh_reader_8hpp.html b/_a_s_c_mesh_reader_8hpp.html index d6856e5f51dd..df7e9d93dac9 100644 --- a/_a_s_c_mesh_reader_8hpp.html +++ b/_a_s_c_mesh_reader_8hpp.html @@ -139,7 +139,7 @@

Classes

-

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Wednesday, Jul 10, 2024 using Doxygen and m.css. Contact us via GitHub.

+

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Thursday, Jul 11, 2024 using Doxygen and m.css. Contact us via GitHub.

diff --git a/_a_u_s_m_8hpp.html b/_a_u_s_m_8hpp.html index a495aea4abb5..b85c1abf8661 100644 --- a/_a_u_s_m_8hpp.html +++ b/_a_u_s_m_8hpp.html @@ -139,7 +139,7 @@

Classes

-

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Wednesday, Jul 10, 2024 using Doxygen and m.css. Contact us via GitHub.

+

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Thursday, Jul 11, 2024 using Doxygen and m.css. Contact us via GitHub.

diff --git a/_around_8hpp.html b/_around_8hpp.html index d2a91b113c58..290c73063d11 100644 --- a/_around_8hpp.html +++ b/_around_8hpp.html @@ -139,7 +139,7 @@

Classes

-

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Wednesday, Jul 10, 2024 using Doxygen and m.css. Contact us via GitHub.

+

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Thursday, Jul 11, 2024 using Doxygen and m.css. Contact us via GitHub.

diff --git a/_assessment_8cpp.html b/_assessment_8cpp.html index 60d98afaec58..65b284ca329c 100644 --- a/_assessment_8cpp.html +++ b/_assessment_8cpp.html @@ -129,7 +129,7 @@

Namespaces

-

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Wednesday, Jul 10, 2024 using Doxygen and m.css. Contact us via GitHub.

+

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Thursday, Jul 11, 2024 using Doxygen and m.css. Contact us via GitHub.

diff --git a/_assessment_8hpp.html b/_assessment_8hpp.html index 64a0939339c3..a93f3afbb1f2 100644 --- a/_assessment_8hpp.html +++ b/_assessment_8hpp.html @@ -131,7 +131,7 @@

Namespaces

-

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Wednesday, Jul 10, 2024 using Doxygen and m.css. Contact us via GitHub.

+

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Thursday, Jul 11, 2024 using Doxygen and m.css. Contact us via GitHub.

diff --git a/_b_c_functions_8hpp.html b/_b_c_functions_8hpp.html index c3642e4a97c0..cc0f20134610 100644 --- a/_b_c_functions_8hpp.html +++ b/_b_c_functions_8hpp.html @@ -129,7 +129,7 @@

Namespaces

-

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Wednesday, Jul 10, 2024 using Doxygen and m.css. Contact us via GitHub.

+

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Thursday, Jul 11, 2024 using Doxygen and m.css. Contact us via GitHub.

diff --git a/_base_2_factory_8hpp.html b/_base_2_factory_8hpp.html index 83f7a27084c8..0af2e5c990d2 100644 --- a/_base_2_factory_8hpp.html +++ b/_base_2_factory_8hpp.html @@ -129,7 +129,7 @@

Namespaces

-

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Wednesday, Jul 10, 2024 using Doxygen and m.css. Contact us via GitHub.

+

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Thursday, Jul 11, 2024 using Doxygen and m.css. Contact us via GitHub.

diff --git a/_base_2_types_8hpp.html b/_base_2_types_8hpp.html index f08a62f6ab03..1245ddde885b 100644 --- a/_base_2_types_8hpp.html +++ b/_base_2_types_8hpp.html @@ -143,7 +143,7 @@

Classes

-

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Wednesday, Jul 10, 2024 using Doxygen and m.css. Contact us via GitHub.

+

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Thursday, Jul 11, 2024 using Doxygen and m.css. Contact us via GitHub.

diff --git a/_basis_8cpp.html b/_basis_8cpp.html index 5ef5cb61589d..aa46b71329c4 100644 --- a/_basis_8cpp.html +++ b/_basis_8cpp.html @@ -111,7 +111,7 @@

-

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Wednesday, Jul 10, 2024 using Doxygen and m.css. Contact us via GitHub.

+

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Thursday, Jul 11, 2024 using Doxygen and m.css. Contact us via GitHub.

diff --git a/_basis_8hpp.html b/_basis_8hpp.html index 249045e5abd6..bb58ba43e9b9 100644 --- a/_basis_8hpp.html +++ b/_basis_8hpp.html @@ -129,7 +129,7 @@

Namespaces

-

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Wednesday, Jul 10, 2024 using Doxygen and m.css. Contact us via GitHub.

+

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Thursday, Jul 11, 2024 using Doxygen and m.css. Contact us via GitHub.

diff --git a/_bi_p_d_f_8hpp.html b/_bi_p_d_f_8hpp.html index 0768277199d2..f2ef118329d9 100644 --- a/_bi_p_d_f_8hpp.html +++ b/_bi_p_d_f_8hpp.html @@ -139,7 +139,7 @@

Classes

-

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Wednesday, Jul 10, 2024 using Doxygen and m.css. Contact us via GitHub.

+

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Thursday, Jul 11, 2024 using Doxygen and m.css. Contact us via GitHub.

diff --git a/_boundary_8cpp.html b/_boundary_8cpp.html index 7a29bde5613c..3e0a8706b5c8 100644 --- a/_boundary_8cpp.html +++ b/_boundary_8cpp.html @@ -131,7 +131,7 @@

Namespaces

-

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Wednesday, Jul 10, 2024 using Doxygen and m.css. Contact us via GitHub.

+

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Thursday, Jul 11, 2024 using Doxygen and m.css. Contact us via GitHub.

diff --git a/_boundary_8hpp.html b/_boundary_8hpp.html index 9c872879dc09..12cf7558e1e9 100644 --- a/_boundary_8hpp.html +++ b/_boundary_8hpp.html @@ -129,7 +129,7 @@

Namespaces

-

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Wednesday, Jul 10, 2024 using Doxygen and m.css. Contact us via GitHub.

+

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Thursday, Jul 11, 2024 using Doxygen and m.css. Contact us via GitHub.

diff --git a/_c_g_adv_diff_8cpp.html b/_c_g_adv_diff_8cpp.html index e15fb6e7289e..1fa3bd210990 100644 --- a/_c_g_adv_diff_8cpp.html +++ b/_c_g_adv_diff_8cpp.html @@ -129,7 +129,7 @@

Namespaces

-

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Wednesday, Jul 10, 2024 using Doxygen and m.css. Contact us via GitHub.

+

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Thursday, Jul 11, 2024 using Doxygen and m.css. Contact us via GitHub.

diff --git a/_c_g_adv_diff_8hpp.html b/_c_g_adv_diff_8hpp.html index 0cf4f254de29..0b6eafe61cf5 100644 --- a/_c_g_adv_diff_8hpp.html +++ b/_c_g_adv_diff_8hpp.html @@ -139,7 +139,7 @@

Classes

-

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Wednesday, Jul 10, 2024 using Doxygen and m.css. Contact us via GitHub.

+

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Thursday, Jul 11, 2024 using Doxygen and m.css. Contact us via GitHub.

diff --git a/_c_g_advection_8hpp.html b/_c_g_advection_8hpp.html index f0a91cd2f469..b3877421fdd8 100644 --- a/_c_g_advection_8hpp.html +++ b/_c_g_advection_8hpp.html @@ -139,7 +139,7 @@

Classes

-

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Wednesday, Jul 10, 2024 using Doxygen and m.css. Contact us via GitHub.

+

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Thursday, Jul 11, 2024 using Doxygen and m.css. Contact us via GitHub.

diff --git a/_c_g_comp_flow_8hpp.html b/_c_g_comp_flow_8hpp.html index a1411b77512b..9c3e86a9eafc 100644 --- a/_c_g_comp_flow_8hpp.html +++ b/_c_g_comp_flow_8hpp.html @@ -140,7 +140,7 @@

Classes

-

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Wednesday, Jul 10, 2024 using Doxygen and m.css. Contact us via GitHub.

+

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Thursday, Jul 11, 2024 using Doxygen and m.css. Contact us via GitHub.

diff --git a/_c_g_euler_8hpp.html b/_c_g_euler_8hpp.html index ca3ffcc58d2f..0af61a2f2917 100644 --- a/_c_g_euler_8hpp.html +++ b/_c_g_euler_8hpp.html @@ -139,7 +139,7 @@

Classes

-

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Wednesday, Jul 10, 2024 using Doxygen and m.css. Contact us via GitHub.

+

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Thursday, Jul 11, 2024 using Doxygen and m.css. Contact us via GitHub.

diff --git a/_c_g_navier_stokes_8cpp.html b/_c_g_navier_stokes_8cpp.html index af0f528c1d8f..4ecc1d32c478 100644 --- a/_c_g_navier_stokes_8cpp.html +++ b/_c_g_navier_stokes_8cpp.html @@ -111,7 +111,7 @@

-

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Wednesday, Jul 10, 2024 using Doxygen and m.css. Contact us via GitHub.

+

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Thursday, Jul 11, 2024 using Doxygen and m.css. Contact us via GitHub.

diff --git a/_c_g_navier_stokes_8hpp.html b/_c_g_navier_stokes_8hpp.html index a7a18b254d77..80c03e09e23d 100644 --- a/_c_g_navier_stokes_8hpp.html +++ b/_c_g_navier_stokes_8hpp.html @@ -139,7 +139,7 @@

Classes

-

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Wednesday, Jul 10, 2024 using Doxygen and m.css. Contact us via GitHub.

+

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Thursday, Jul 11, 2024 using Doxygen and m.css. Contact us via GitHub.

diff --git a/_c_g_p_d_e_8cpp.html b/_c_g_p_d_e_8cpp.html index 6fc241db9f05..77358bf2f51c 100644 --- a/_c_g_p_d_e_8cpp.html +++ b/_c_g_p_d_e_8cpp.html @@ -129,7 +129,7 @@

Namespaces

-

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Wednesday, Jul 10, 2024 using Doxygen and m.css. Contact us via GitHub.

+

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Thursday, Jul 11, 2024 using Doxygen and m.css. Contact us via GitHub.

diff --git a/_c_g_p_d_e_8hpp.html b/_c_g_p_d_e_8hpp.html index 86f806a7b211..1c3833e8598c 100644 --- a/_c_g_p_d_e_8hpp.html +++ b/_c_g_p_d_e_8hpp.html @@ -139,7 +139,7 @@

Classes

-

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Wednesday, Jul 10, 2024 using Doxygen and m.css. Contact us via GitHub.

+

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Thursday, Jul 11, 2024 using Doxygen and m.css. Contact us via GitHub.

diff --git a/_c_g_transport_8hpp.html b/_c_g_transport_8hpp.html index 7ea629e19253..3f55b4af2a3a 100644 --- a/_c_g_transport_8hpp.html +++ b/_c_g_transport_8hpp.html @@ -140,7 +140,7 @@

Classes

-

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Wednesday, Jul 10, 2024 using Doxygen and m.css. Contact us via GitHub.

+

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Thursday, Jul 11, 2024 using Doxygen and m.css. Contact us via GitHub.

diff --git a/_c_s_r_8cpp.html b/_c_s_r_8cpp.html index 87b095833b09..dde53a7e6b03 100644 --- a/_c_s_r_8cpp.html +++ b/_c_s_r_8cpp.html @@ -111,7 +111,7 @@

-

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Wednesday, Jul 10, 2024 using Doxygen and m.css. Contact us via GitHub.

+

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Thursday, Jul 11, 2024 using Doxygen and m.css. Contact us via GitHub.

diff --git a/_c_s_r_8hpp.html b/_c_s_r_8hpp.html index 3fe64014080d..f63139a0727a 100644 --- a/_c_s_r_8hpp.html +++ b/_c_s_r_8hpp.html @@ -139,7 +139,7 @@

Classes

-

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Wednesday, Jul 10, 2024 using Doxygen and m.css. Contact us via GitHub.

+

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Thursday, Jul 11, 2024 using Doxygen and m.css. Contact us via GitHub.

diff --git a/_callback_8hpp.html b/_callback_8hpp.html index 83d7a02c291c..af77950f903a 100644 --- a/_callback_8hpp.html +++ b/_callback_8hpp.html @@ -129,7 +129,7 @@

Namespaces

-

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Wednesday, Jul 10, 2024 using Doxygen and m.css. Contact us via GitHub.

+

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Thursday, Jul 11, 2024 using Doxygen and m.css. Contact us via GitHub.

diff --git a/_cartesian_product_8hpp.html b/_cartesian_product_8hpp.html index dfcaeac4c8c5..147157113706 100644 --- a/_cartesian_product_8hpp.html +++ b/_cartesian_product_8hpp.html @@ -129,7 +129,7 @@

Namespaces

-

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Wednesday, Jul 10, 2024 using Doxygen and m.css. Contact us via GitHub.

+

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Thursday, Jul 11, 2024 using Doxygen and m.css. Contact us via GitHub.

diff --git a/_centering_8hpp.html b/_centering_8hpp.html index e88d1d8d9170..3ca09d37bccd 100644 --- a/_centering_8hpp.html +++ b/_centering_8hpp.html @@ -129,7 +129,7 @@

Namespaces

-

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Wednesday, Jul 10, 2024 using Doxygen and m.css. Contact us via GitHub.

+

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Thursday, Jul 11, 2024 using Doxygen and m.css. Contact us via GitHub.

diff --git a/_chare_state_8hpp.html b/_chare_state_8hpp.html index 589e9abe19fe..821c046e2c9c 100644 --- a/_chare_state_8hpp.html +++ b/_chare_state_8hpp.html @@ -129,7 +129,7 @@

Namespaces

-

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Wednesday, Jul 10, 2024 using Doxygen and m.css. Contact us via GitHub.

+

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Thursday, Jul 11, 2024 using Doxygen and m.css. Contact us via GitHub.

diff --git a/_chare_state_collector_8cpp.html b/_chare_state_collector_8cpp.html index e289425d619c..3bc7608e249d 100644 --- a/_chare_state_collector_8cpp.html +++ b/_chare_state_collector_8cpp.html @@ -129,7 +129,7 @@

Namespaces

-

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Wednesday, Jul 10, 2024 using Doxygen and m.css. Contact us via GitHub.

+

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Thursday, Jul 11, 2024 using Doxygen and m.css. Contact us via GitHub.

diff --git a/_chare_state_collector_8hpp.html b/_chare_state_collector_8hpp.html index c88bcb6c2860..0f12120bb423 100644 --- a/_chare_state_collector_8hpp.html +++ b/_chare_state_collector_8hpp.html @@ -139,7 +139,7 @@

Classes

-

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Wednesday, Jul 10, 2024 using Doxygen and m.css. Contact us via GitHub.

+

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Thursday, Jul 11, 2024 using Doxygen and m.css. Contact us via GitHub.

diff --git a/_comm_map_8cpp.html b/_comm_map_8cpp.html index af89630c97d2..57997befbc73 100644 --- a/_comm_map_8cpp.html +++ b/_comm_map_8cpp.html @@ -129,7 +129,7 @@

Namespaces

-

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Wednesday, Jul 10, 2024 using Doxygen and m.css. Contact us via GitHub.

+

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Thursday, Jul 11, 2024 using Doxygen and m.css. Contact us via GitHub.

diff --git a/_comm_map_8hpp.html b/_comm_map_8hpp.html index c8acf9f4f57c..91e872e20120 100644 --- a/_comm_map_8hpp.html +++ b/_comm_map_8hpp.html @@ -129,7 +129,7 @@

Namespaces

-

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Wednesday, Jul 10, 2024 using Doxygen and m.css. Contact us via GitHub.

+

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Thursday, Jul 11, 2024 using Doxygen and m.css. Contact us via GitHub.

diff --git a/_common_grammar_8hpp.html b/_common_grammar_8hpp.html index 03e5dfb4d614..e884997424a6 100644 --- a/_common_grammar_8hpp.html +++ b/_common_grammar_8hpp.html @@ -284,7 +284,7 @@

Classes

-

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Wednesday, Jul 10, 2024 using Doxygen and m.css. Contact us via GitHub.

+

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Thursday, Jul 11, 2024 using Doxygen and m.css. Contact us via GitHub.

diff --git a/_comp_flow_2_physics_2_c_g_8hpp.html b/_comp_flow_2_physics_2_c_g_8hpp.html index 01a563f53cce..393c62da2086 100644 --- a/_comp_flow_2_physics_2_c_g_8hpp.html +++ b/_comp_flow_2_physics_2_c_g_8hpp.html @@ -131,7 +131,7 @@

Namespaces

-

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Wednesday, Jul 10, 2024 using Doxygen and m.css. Contact us via GitHub.

+

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Thursday, Jul 11, 2024 using Doxygen and m.css. Contact us via GitHub.

diff --git a/_comp_flow_2_physics_2_d_g_euler_8hpp.html b/_comp_flow_2_physics_2_d_g_euler_8hpp.html index 3d1dc35da3a1..318396830414 100644 --- a/_comp_flow_2_physics_2_d_g_euler_8hpp.html +++ b/_comp_flow_2_physics_2_d_g_euler_8hpp.html @@ -139,7 +139,7 @@

Classes

-

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Wednesday, Jul 10, 2024 using Doxygen and m.css. Contact us via GitHub.

+

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Thursday, Jul 11, 2024 using Doxygen and m.css. Contact us via GitHub.

diff --git a/_comp_flow_2_problem_2_box_initialization_8hpp.html b/_comp_flow_2_problem_2_box_initialization_8hpp.html index 8539e29d007a..a1e489cd4ae5 100644 --- a/_comp_flow_2_problem_2_box_initialization_8hpp.html +++ b/_comp_flow_2_problem_2_box_initialization_8hpp.html @@ -129,7 +129,7 @@

Namespaces

-

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Wednesday, Jul 10, 2024 using Doxygen and m.css. Contact us via GitHub.

+

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Thursday, Jul 11, 2024 using Doxygen and m.css. Contact us via GitHub.

diff --git a/_comp_flow_2_problem_2_shock_density_wave_8cpp.html b/_comp_flow_2_problem_2_shock_density_wave_8cpp.html index 103094dcae10..aaf9f2b43441 100644 --- a/_comp_flow_2_problem_2_shock_density_wave_8cpp.html +++ b/_comp_flow_2_problem_2_shock_density_wave_8cpp.html @@ -111,7 +111,7 @@

-

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Wednesday, Jul 10, 2024 using Doxygen and m.css. Contact us via GitHub.

+

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Thursday, Jul 11, 2024 using Doxygen and m.css. Contact us via GitHub.

diff --git a/_comp_flow_2_problem_2_shock_density_wave_8hpp.html b/_comp_flow_2_problem_2_shock_density_wave_8hpp.html index 2d9c8a4c9e84..bb73cb858213 100644 --- a/_comp_flow_2_problem_2_shock_density_wave_8hpp.html +++ b/_comp_flow_2_problem_2_shock_density_wave_8hpp.html @@ -139,7 +139,7 @@

Classes

-

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Wednesday, Jul 10, 2024 using Doxygen and m.css. Contact us via GitHub.

+

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Thursday, Jul 11, 2024 using Doxygen and m.css. Contact us via GitHub.

diff --git a/_comp_flow_2_problem_2_sod_shocktube_8cpp.html b/_comp_flow_2_problem_2_sod_shocktube_8cpp.html index 9ae6166b995c..29d878075051 100644 --- a/_comp_flow_2_problem_2_sod_shocktube_8cpp.html +++ b/_comp_flow_2_problem_2_sod_shocktube_8cpp.html @@ -111,7 +111,7 @@

-

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Wednesday, Jul 10, 2024 using Doxygen and m.css. Contact us via GitHub.

+

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Thursday, Jul 11, 2024 using Doxygen and m.css. Contact us via GitHub.

diff --git a/_comp_flow_2_problem_2_sod_shocktube_8hpp.html b/_comp_flow_2_problem_2_sod_shocktube_8hpp.html index ba6aaeaafe45..1cb54b327f5c 100644 --- a/_comp_flow_2_problem_2_sod_shocktube_8hpp.html +++ b/_comp_flow_2_problem_2_sod_shocktube_8hpp.html @@ -139,7 +139,7 @@

Classes

-

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Wednesday, Jul 10, 2024 using Doxygen and m.css. Contact us via GitHub.

+

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Thursday, Jul 11, 2024 using Doxygen and m.css. Contact us via GitHub.

diff --git a/_comp_flow_2_problem_2_user_defined_8cpp.html b/_comp_flow_2_problem_2_user_defined_8cpp.html index 721df9d552ce..6689b8ab5ab2 100644 --- a/_comp_flow_2_problem_2_user_defined_8cpp.html +++ b/_comp_flow_2_problem_2_user_defined_8cpp.html @@ -129,7 +129,7 @@

Namespaces

-

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Wednesday, Jul 10, 2024 using Doxygen and m.css. Contact us via GitHub.

+

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Thursday, Jul 11, 2024 using Doxygen and m.css. Contact us via GitHub.

diff --git a/_comp_flow_2_problem_2_user_defined_8hpp.html b/_comp_flow_2_problem_2_user_defined_8hpp.html index eac146a26fd7..595624a73392 100644 --- a/_comp_flow_2_problem_2_user_defined_8hpp.html +++ b/_comp_flow_2_problem_2_user_defined_8hpp.html @@ -139,7 +139,7 @@

Classes

-

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Wednesday, Jul 10, 2024 using Doxygen and m.css. Contact us via GitHub.

+

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Thursday, Jul 11, 2024 using Doxygen and m.css. Contact us via GitHub.

diff --git a/_configure_comp_flow_8cpp.html b/_configure_comp_flow_8cpp.html index 619c1c01c555..4e2bbf57048e 100644 --- a/_configure_comp_flow_8cpp.html +++ b/_configure_comp_flow_8cpp.html @@ -129,7 +129,7 @@

Namespaces

-

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Wednesday, Jul 10, 2024 using Doxygen and m.css. Contact us via GitHub.

+

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Thursday, Jul 11, 2024 using Doxygen and m.css. Contact us via GitHub.

diff --git a/_configure_comp_flow_8hpp.html b/_configure_comp_flow_8hpp.html index 6aa4767cd14b..0ac4fbd6138a 100644 --- a/_configure_comp_flow_8hpp.html +++ b/_configure_comp_flow_8hpp.html @@ -129,7 +129,7 @@

Namespaces

-

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Wednesday, Jul 10, 2024 using Doxygen and m.css. Contact us via GitHub.

+

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Thursday, Jul 11, 2024 using Doxygen and m.css. Contact us via GitHub.

diff --git a/_configure_multi_mat_8cpp.html b/_configure_multi_mat_8cpp.html index e8a6db3e11d1..8b40c59632ff 100644 --- a/_configure_multi_mat_8cpp.html +++ b/_configure_multi_mat_8cpp.html @@ -129,7 +129,7 @@

Namespaces

-

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Wednesday, Jul 10, 2024 using Doxygen and m.css. Contact us via GitHub.

+

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Thursday, Jul 11, 2024 using Doxygen and m.css. Contact us via GitHub.

diff --git a/_configure_multi_mat_8hpp.html b/_configure_multi_mat_8hpp.html index b735d6422b7e..d498ac954e12 100644 --- a/_configure_multi_mat_8hpp.html +++ b/_configure_multi_mat_8hpp.html @@ -129,7 +129,7 @@

Namespaces

-

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Wednesday, Jul 10, 2024 using Doxygen and m.css. Contact us via GitHub.

+

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Thursday, Jul 11, 2024 using Doxygen and m.css. Contact us via GitHub.

diff --git a/_configure_transport_8cpp.html b/_configure_transport_8cpp.html index 762fe5b1686d..87c3f038b95b 100644 --- a/_configure_transport_8cpp.html +++ b/_configure_transport_8cpp.html @@ -129,7 +129,7 @@

Namespaces

-

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Wednesday, Jul 10, 2024 using Doxygen and m.css. Contact us via GitHub.

+

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Thursday, Jul 11, 2024 using Doxygen and m.css. Contact us via GitHub.

diff --git a/_configure_transport_8hpp.html b/_configure_transport_8hpp.html index 3f8a69d58881..fcea4182d455 100644 --- a/_configure_transport_8hpp.html +++ b/_configure_transport_8hpp.html @@ -129,7 +129,7 @@

Namespaces

-

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Wednesday, Jul 10, 2024 using Doxygen and m.css. Contact us via GitHub.

+

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Thursday, Jul 11, 2024 using Doxygen and m.css. Contact us via GitHub.

diff --git a/_conjugate_gradients_8cpp.html b/_conjugate_gradients_8cpp.html index 699771ea8241..e006afe7868b 100644 --- a/_conjugate_gradients_8cpp.html +++ b/_conjugate_gradients_8cpp.html @@ -111,7 +111,7 @@

-

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Wednesday, Jul 10, 2024 using Doxygen and m.css. Contact us via GitHub.

+

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Thursday, Jul 11, 2024 using Doxygen and m.css. Contact us via GitHub.

diff --git a/_conjugate_gradients_8hpp.html b/_conjugate_gradients_8hpp.html index c12d27cbc87a..437563fb8943 100644 --- a/_conjugate_gradients_8hpp.html +++ b/_conjugate_gradients_8hpp.html @@ -139,7 +139,7 @@

Classes

-

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Wednesday, Jul 10, 2024 using Doxygen and m.css. Contact us via GitHub.

+

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Thursday, Jul 11, 2024 using Doxygen and m.css. Contact us via GitHub.

diff --git a/_container_util_8hpp.html b/_container_util_8hpp.html index e0cb9a7df37c..e472d7bc63df 100644 --- a/_container_util_8hpp.html +++ b/_container_util_8hpp.html @@ -129,7 +129,7 @@

Namespaces

-

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Wednesday, Jul 10, 2024 using Doxygen and m.css. Contact us via GitHub.

+

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Thursday, Jul 11, 2024 using Doxygen and m.css. Contact us via GitHub.

diff --git a/_control_2_inciter_2_options_2_limiter_8hpp.html b/_control_2_inciter_2_options_2_limiter_8hpp.html index 16b6920065e0..86902d3899c0 100644 --- a/_control_2_inciter_2_options_2_limiter_8hpp.html +++ b/_control_2_inciter_2_options_2_limiter_8hpp.html @@ -141,7 +141,7 @@

Classes

-

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Wednesday, Jul 10, 2024 using Doxygen and m.css. Contact us via GitHub.

+

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Thursday, Jul 11, 2024 using Doxygen and m.css. Contact us via GitHub.

diff --git a/_control_2_inciter_2_options_2_pref_indicator_8hpp.html b/_control_2_inciter_2_options_2_pref_indicator_8hpp.html index ad96470db22f..42c4a34efea9 100644 --- a/_control_2_inciter_2_options_2_pref_indicator_8hpp.html +++ b/_control_2_inciter_2_options_2_pref_indicator_8hpp.html @@ -141,7 +141,7 @@

Classes

-

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Wednesday, Jul 10, 2024 using Doxygen and m.css. Contact us via GitHub.

+

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Thursday, Jul 11, 2024 using Doxygen and m.css. Contact us via GitHub.

diff --git a/_control_2_inciter_2_options_2_problem_8hpp.html b/_control_2_inciter_2_options_2_problem_8hpp.html index 702bc8f32e7b..5d2978569182 100644 --- a/_control_2_inciter_2_options_2_problem_8hpp.html +++ b/_control_2_inciter_2_options_2_problem_8hpp.html @@ -141,7 +141,7 @@

Classes

-

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Wednesday, Jul 10, 2024 using Doxygen and m.css. Contact us via GitHub.

+

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Thursday, Jul 11, 2024 using Doxygen and m.css. Contact us via GitHub.

diff --git a/_control_2_inciter_2_options_2_scheme_8hpp.html b/_control_2_inciter_2_options_2_scheme_8hpp.html index e1c22d60ab0e..26c103c15988 100644 --- a/_control_2_inciter_2_options_2_scheme_8hpp.html +++ b/_control_2_inciter_2_options_2_scheme_8hpp.html @@ -141,7 +141,7 @@

Classes

-

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Wednesday, Jul 10, 2024 using Doxygen and m.css. Contact us via GitHub.

+

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Thursday, Jul 11, 2024 using Doxygen and m.css. Contact us via GitHub.

diff --git a/_control_2_mesh_conv_2_types_8hpp.html b/_control_2_mesh_conv_2_types_8hpp.html index ef01b69f4421..bbee0d2f7631 100644 --- a/_control_2_mesh_conv_2_types_8hpp.html +++ b/_control_2_mesh_conv_2_types_8hpp.html @@ -131,7 +131,7 @@

Namespaces

-

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Wednesday, Jul 10, 2024 using Doxygen and m.css. Contact us via GitHub.

+

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Thursday, Jul 11, 2024 using Doxygen and m.css. Contact us via GitHub.

diff --git a/_control_2_options_2_error_8hpp.html b/_control_2_options_2_error_8hpp.html index c4d4419e5be4..96c195deaeb1 100644 --- a/_control_2_options_2_error_8hpp.html +++ b/_control_2_options_2_error_8hpp.html @@ -139,7 +139,7 @@

Classes

-

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Wednesday, Jul 10, 2024 using Doxygen and m.css. Contact us via GitHub.

+

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Thursday, Jul 11, 2024 using Doxygen and m.css. Contact us via GitHub.

diff --git a/_control_2_unit_test_2_types_8hpp.html b/_control_2_unit_test_2_types_8hpp.html index 7e1f164f0dad..8efebc3efacd 100644 --- a/_control_2_unit_test_2_types_8hpp.html +++ b/_control_2_unit_test_2_types_8hpp.html @@ -131,7 +131,7 @@

Namespaces

-

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Wednesday, Jul 10, 2024 using Doxygen and m.css. Contact us via GitHub.

+

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Thursday, Jul 11, 2024 using Doxygen and m.css. Contact us via GitHub.

diff --git a/_cyl_advect_8cpp.html b/_cyl_advect_8cpp.html index 511b37a939fd..4480455ee17c 100644 --- a/_cyl_advect_8cpp.html +++ b/_cyl_advect_8cpp.html @@ -111,7 +111,7 @@

-

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Wednesday, Jul 10, 2024 using Doxygen and m.css. Contact us via GitHub.

+

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Thursday, Jul 11, 2024 using Doxygen and m.css. Contact us via GitHub.

diff --git a/_cyl_advect_8hpp.html b/_cyl_advect_8hpp.html index 2ee6fdb99cb5..5c71163f8bbf 100644 --- a/_cyl_advect_8hpp.html +++ b/_cyl_advect_8hpp.html @@ -139,7 +139,7 @@

Classes

-

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Wednesday, Jul 10, 2024 using Doxygen and m.css. Contact us via GitHub.

+

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Thursday, Jul 11, 2024 using Doxygen and m.css. Contact us via GitHub.

diff --git a/_cyl_vortex_8cpp.html b/_cyl_vortex_8cpp.html index da310c5e71cc..c7449bcd9a27 100644 --- a/_cyl_vortex_8cpp.html +++ b/_cyl_vortex_8cpp.html @@ -111,7 +111,7 @@

-

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Wednesday, Jul 10, 2024 using Doxygen and m.css. Contact us via GitHub.

+

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Thursday, Jul 11, 2024 using Doxygen and m.css. Contact us via GitHub.

diff --git a/_cyl_vortex_8hpp.html b/_cyl_vortex_8hpp.html index 5553aa881ff7..4f5f00b0901a 100644 --- a/_cyl_vortex_8hpp.html +++ b/_cyl_vortex_8hpp.html @@ -139,7 +139,7 @@

Classes

-

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Wednesday, Jul 10, 2024 using Doxygen and m.css. Contact us via GitHub.

+

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Thursday, Jul 11, 2024 using Doxygen and m.css. Contact us via GitHub.

diff --git a/_d_g_8cpp.html b/_d_g_8cpp.html index b517c727678d..09f86f654661 100644 --- a/_d_g_8cpp.html +++ b/_d_g_8cpp.html @@ -137,7 +137,7 @@

Variables

-

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Wednesday, Jul 10, 2024 using Doxygen and m.css. Contact us via GitHub.

+

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Thursday, Jul 11, 2024 using Doxygen and m.css. Contact us via GitHub.

diff --git a/_d_g_advection_8hpp.html b/_d_g_advection_8hpp.html index b1d62ae5d731..878ca133c65a 100644 --- a/_d_g_advection_8hpp.html +++ b/_d_g_advection_8hpp.html @@ -139,7 +139,7 @@

Classes

-

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Wednesday, Jul 10, 2024 using Doxygen and m.css. Contact us via GitHub.

+

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Thursday, Jul 11, 2024 using Doxygen and m.css. Contact us via GitHub.

diff --git a/_d_g_comp_flow_8hpp.html b/_d_g_comp_flow_8hpp.html index e97e6e9cc7d4..c0353aea9e23 100644 --- a/_d_g_comp_flow_8hpp.html +++ b/_d_g_comp_flow_8hpp.html @@ -140,7 +140,7 @@

Classes

-

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Wednesday, Jul 10, 2024 using Doxygen and m.css. Contact us via GitHub.

+

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Thursday, Jul 11, 2024 using Doxygen and m.css. Contact us via GitHub.

diff --git a/_d_g_multi_mat_8hpp.html b/_d_g_multi_mat_8hpp.html index 0fb7c6f926b0..1dedf0941542 100644 --- a/_d_g_multi_mat_8hpp.html +++ b/_d_g_multi_mat_8hpp.html @@ -140,7 +140,7 @@

Classes

-

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Wednesday, Jul 10, 2024 using Doxygen and m.css. Contact us via GitHub.

+

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Thursday, Jul 11, 2024 using Doxygen and m.css. Contact us via GitHub.

diff --git a/_d_g_p_d_e_8cpp.html b/_d_g_p_d_e_8cpp.html index 404f28f56016..d54fb311f149 100644 --- a/_d_g_p_d_e_8cpp.html +++ b/_d_g_p_d_e_8cpp.html @@ -111,7 +111,7 @@

-

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Wednesday, Jul 10, 2024 using Doxygen and m.css. Contact us via GitHub.

+

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Thursday, Jul 11, 2024 using Doxygen and m.css. Contact us via GitHub.

diff --git a/_d_g_p_d_e_8hpp.html b/_d_g_p_d_e_8hpp.html index 5cd023eade13..d5470f4c4acc 100644 --- a/_d_g_p_d_e_8hpp.html +++ b/_d_g_p_d_e_8hpp.html @@ -143,7 +143,7 @@

Classes

-

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Wednesday, Jul 10, 2024 using Doxygen and m.css. Contact us via GitHub.

+

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Thursday, Jul 11, 2024 using Doxygen and m.css. Contact us via GitHub.

diff --git a/_d_g_transport_8hpp.html b/_d_g_transport_8hpp.html index b431450fb3ae..dc7a2bfe134f 100644 --- a/_d_g_transport_8hpp.html +++ b/_d_g_transport_8hpp.html @@ -140,7 +140,7 @@

Classes

-

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Wednesday, Jul 10, 2024 using Doxygen and m.css. Contact us via GitHub.

+

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Thursday, Jul 11, 2024 using Doxygen and m.css. Contact us via GitHub.

diff --git a/_data_8hpp.html b/_data_8hpp.html index 41dd13f17fd7..66bd44d21d0c 100644 --- a/_data_8hpp.html +++ b/_data_8hpp.html @@ -140,7 +140,7 @@

Classes

-

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Wednesday, Jul 10, 2024 using Doxygen and m.css. Contact us via GitHub.

+

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Thursday, Jul 11, 2024 using Doxygen and m.css. Contact us via GitHub.

diff --git a/_derived_data_8cpp.html b/_derived_data_8cpp.html index 7abffc28e046..2d30fd2d38a5 100644 --- a/_derived_data_8cpp.html +++ b/_derived_data_8cpp.html @@ -129,7 +129,7 @@

Namespaces

-

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Wednesday, Jul 10, 2024 using Doxygen and m.css. Contact us via GitHub.

+

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Thursday, Jul 11, 2024 using Doxygen and m.css. Contact us via GitHub.

diff --git a/_derived_data_8hpp.html b/_derived_data_8hpp.html index 7706b1ad19ec..fc61172ff0eb 100644 --- a/_derived_data_8hpp.html +++ b/_derived_data_8hpp.html @@ -129,7 +129,7 @@

Namespaces

-

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Wednesday, Jul 10, 2024 using Doxygen and m.css. Contact us via GitHub.

+

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Thursday, Jul 11, 2024 using Doxygen and m.css. Contact us via GitHub.

diff --git a/_diag_reducer_8cpp.html b/_diag_reducer_8cpp.html index 2457d61aa7a1..a4bc08da5f2e 100644 --- a/_diag_reducer_8cpp.html +++ b/_diag_reducer_8cpp.html @@ -129,7 +129,7 @@

Namespaces

-

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Wednesday, Jul 10, 2024 using Doxygen and m.css. Contact us via GitHub.

+

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Thursday, Jul 11, 2024 using Doxygen and m.css. Contact us via GitHub.

diff --git a/_diag_reducer_8hpp.html b/_diag_reducer_8hpp.html index fcfbceb4cf3e..5efde85ec8f1 100644 --- a/_diag_reducer_8hpp.html +++ b/_diag_reducer_8hpp.html @@ -129,7 +129,7 @@

Namespaces

-

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Wednesday, Jul 10, 2024 using Doxygen and m.css. Contact us via GitHub.

+

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Thursday, Jul 11, 2024 using Doxygen and m.css. Contact us via GitHub.

diff --git a/_diag_writer_8cpp.html b/_diag_writer_8cpp.html index bc2cd9610a02..d0b70064a107 100644 --- a/_diag_writer_8cpp.html +++ b/_diag_writer_8cpp.html @@ -111,7 +111,7 @@

-

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Wednesday, Jul 10, 2024 using Doxygen and m.css. Contact us via GitHub.

+

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Thursday, Jul 11, 2024 using Doxygen and m.css. Contact us via GitHub.

diff --git a/_diag_writer_8hpp.html b/_diag_writer_8hpp.html index 96ae40bbf5b3..f61d8f60cece 100644 --- a/_diag_writer_8hpp.html +++ b/_diag_writer_8hpp.html @@ -139,7 +139,7 @@

Classes

-

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Wednesday, Jul 10, 2024 using Doxygen and m.css. Contact us via GitHub.

+

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Thursday, Jul 11, 2024 using Doxygen and m.css. Contact us via GitHub.

diff --git a/_diagnostics_8hpp.html b/_diagnostics_8hpp.html index 931ff9fa41e1..6d66336a7f9b 100644 --- a/_diagnostics_8hpp.html +++ b/_diagnostics_8hpp.html @@ -129,7 +129,7 @@

Namespaces

-

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Wednesday, Jul 10, 2024 using Doxygen and m.css. Contact us via GitHub.

+

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Thursday, Jul 11, 2024 using Doxygen and m.css. Contact us via GitHub.

diff --git a/_discretization_8cpp.html b/_discretization_8cpp.html index 7672bbfbf1f1..c104f6faa6fc 100644 --- a/_discretization_8cpp.html +++ b/_discretization_8cpp.html @@ -128,7 +128,7 @@

Namespaces

-

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Wednesday, Jul 10, 2024 using Doxygen and m.css. Contact us via GitHub.

+

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Thursday, Jul 11, 2024 using Doxygen and m.css. Contact us via GitHub.

diff --git a/_discretization_8hpp.html b/_discretization_8hpp.html index f68d5c36423d..9181c34998f7 100644 --- a/_discretization_8hpp.html +++ b/_discretization_8hpp.html @@ -143,7 +143,7 @@

Classes

-

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Wednesday, Jul 10, 2024 using Doxygen and m.css. Contact us via GitHub.

+

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Thursday, Jul 11, 2024 using Doxygen and m.css. Contact us via GitHub.

diff --git a/_e_o_s_8cpp.html b/_e_o_s_8cpp.html index 499b09ddf8f4..ce3323275985 100644 --- a/_e_o_s_8cpp.html +++ b/_e_o_s_8cpp.html @@ -111,7 +111,7 @@

-

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Wednesday, Jul 10, 2024 using Doxygen and m.css. Contact us via GitHub.

+

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Thursday, Jul 11, 2024 using Doxygen and m.css. Contact us via GitHub.

diff --git a/_e_o_s_8hpp.html b/_e_o_s_8hpp.html index e9234fd822af..47bcfa178d8a 100644 --- a/_e_o_s_8hpp.html +++ b/_e_o_s_8hpp.html @@ -147,7 +147,7 @@

Classes

-

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Wednesday, Jul 10, 2024 using Doxygen and m.css. Contact us via GitHub.

+

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Thursday, Jul 11, 2024 using Doxygen and m.css. Contact us via GitHub.

diff --git a/_elem_diagnostics_8cpp.html b/_elem_diagnostics_8cpp.html index 3faa338e9a96..dd01dc92b275 100644 --- a/_elem_diagnostics_8cpp.html +++ b/_elem_diagnostics_8cpp.html @@ -129,7 +129,7 @@

Namespaces

-

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Wednesday, Jul 10, 2024 using Doxygen and m.css. Contact us via GitHub.

+

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Thursday, Jul 11, 2024 using Doxygen and m.css. Contact us via GitHub.

diff --git a/_elem_diagnostics_8hpp.html b/_elem_diagnostics_8hpp.html index 4702cd6cc966..043ce2bed52a 100644 --- a/_elem_diagnostics_8hpp.html +++ b/_elem_diagnostics_8hpp.html @@ -139,7 +139,7 @@

Classes

-

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Wednesday, Jul 10, 2024 using Doxygen and m.css. Contact us via GitHub.

+

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Thursday, Jul 11, 2024 using Doxygen and m.css. Contact us via GitHub.

diff --git a/_equil_interface_advect_8cpp.html b/_equil_interface_advect_8cpp.html index 94466c0e703b..44a6deec92e8 100644 --- a/_equil_interface_advect_8cpp.html +++ b/_equil_interface_advect_8cpp.html @@ -129,7 +129,7 @@

Namespaces

-

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Wednesday, Jul 10, 2024 using Doxygen and m.css. Contact us via GitHub.

+

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Thursday, Jul 11, 2024 using Doxygen and m.css. Contact us via GitHub.

diff --git a/_equil_interface_advect_8hpp.html b/_equil_interface_advect_8hpp.html index 4558f98b97ed..66f500cddbff 100644 --- a/_equil_interface_advect_8hpp.html +++ b/_equil_interface_advect_8hpp.html @@ -139,7 +139,7 @@

Classes

-

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Wednesday, Jul 10, 2024 using Doxygen and m.css. Contact us via GitHub.

+

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Thursday, Jul 11, 2024 using Doxygen and m.css. Contact us via GitHub.

diff --git a/_error_8cpp.html b/_error_8cpp.html index 622b6c585ce6..2a77e9aa14ff 100644 --- a/_error_8cpp.html +++ b/_error_8cpp.html @@ -111,7 +111,7 @@

-

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Wednesday, Jul 10, 2024 using Doxygen and m.css. Contact us via GitHub.

+

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Thursday, Jul 11, 2024 using Doxygen and m.css. Contact us via GitHub.

diff --git a/_escaper_8hpp.html b/_escaper_8hpp.html index 9a4bd56e93e2..19d709197e02 100644 --- a/_escaper_8hpp.html +++ b/_escaper_8hpp.html @@ -129,7 +129,7 @@

Namespaces

-

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Wednesday, Jul 10, 2024 using Doxygen and m.css. Contact us via GitHub.

+

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Thursday, Jul 11, 2024 using Doxygen and m.css. Contact us via GitHub.

diff --git a/_exception_8cpp.html b/_exception_8cpp.html index 67933f40f1f7..b5f89ea7126c 100644 --- a/_exception_8cpp.html +++ b/_exception_8cpp.html @@ -138,7 +138,7 @@

-

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Wednesday, Jul 10, 2024 using Doxygen and m.css. Contact us via GitHub.

+

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Thursday, Jul 11, 2024 using Doxygen and m.css. Contact us via GitHub.

diff --git a/_exception_8hpp.html b/_exception_8hpp.html index 8aa4fccbf1e4..cda4e79c24c0 100644 --- a/_exception_8hpp.html +++ b/_exception_8hpp.html @@ -185,7 +185,7 @@

-

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Wednesday, Jul 10, 2024 using Doxygen and m.css. Contact us via GitHub.

+

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Thursday, Jul 11, 2024 using Doxygen and m.css. Contact us via GitHub.

diff --git a/_exception_m_p_i_8hpp.html b/_exception_m_p_i_8hpp.html index d2fd781b07d6..3da3929d315b 100644 --- a/_exception_m_p_i_8hpp.html +++ b/_exception_m_p_i_8hpp.html @@ -164,7 +164,7 @@

-

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Wednesday, Jul 10, 2024 using Doxygen and m.css. Contact us via GitHub.

+

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Thursday, Jul 11, 2024 using Doxygen and m.css. Contact us via GitHub.

diff --git a/_exodus_i_i_mesh_reader_8cpp.html b/_exodus_i_i_mesh_reader_8cpp.html index 82b2a88f6278..5dc650eb3f0b 100644 --- a/_exodus_i_i_mesh_reader_8cpp.html +++ b/_exodus_i_i_mesh_reader_8cpp.html @@ -111,7 +111,7 @@

-

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Wednesday, Jul 10, 2024 using Doxygen and m.css. Contact us via GitHub.

+

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Thursday, Jul 11, 2024 using Doxygen and m.css. Contact us via GitHub.

diff --git a/_exodus_i_i_mesh_reader_8hpp.html b/_exodus_i_i_mesh_reader_8hpp.html index 8782e969e82d..480bba5e8f7a 100644 --- a/_exodus_i_i_mesh_reader_8hpp.html +++ b/_exodus_i_i_mesh_reader_8hpp.html @@ -139,7 +139,7 @@

Classes

-

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Wednesday, Jul 10, 2024 using Doxygen and m.css. Contact us via GitHub.

+

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Thursday, Jul 11, 2024 using Doxygen and m.css. Contact us via GitHub.

diff --git a/_exodus_i_i_mesh_writer_8cpp.html b/_exodus_i_i_mesh_writer_8cpp.html index ddb5c3900fd7..0f193be10f6f 100644 --- a/_exodus_i_i_mesh_writer_8cpp.html +++ b/_exodus_i_i_mesh_writer_8cpp.html @@ -111,7 +111,7 @@

-

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Wednesday, Jul 10, 2024 using Doxygen and m.css. Contact us via GitHub.

+

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Thursday, Jul 11, 2024 using Doxygen and m.css. Contact us via GitHub.

diff --git a/_exodus_i_i_mesh_writer_8hpp.html b/_exodus_i_i_mesh_writer_8hpp.html index cfa5aa77ae78..483906849f10 100644 --- a/_exodus_i_i_mesh_writer_8hpp.html +++ b/_exodus_i_i_mesh_writer_8hpp.html @@ -139,7 +139,7 @@

Classes

-

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Wednesday, Jul 10, 2024 using Doxygen and m.css. Contact us via GitHub.

+

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Thursday, Jul 11, 2024 using Doxygen and m.css. Contact us via GitHub.

diff --git a/_f_v_8cpp.html b/_f_v_8cpp.html index fd222d191159..5622c34c165b 100644 --- a/_f_v_8cpp.html +++ b/_f_v_8cpp.html @@ -137,7 +137,7 @@

Variables

-

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Wednesday, Jul 10, 2024 using Doxygen and m.css. Contact us via GitHub.

+

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Thursday, Jul 11, 2024 using Doxygen and m.css. Contact us via GitHub.

diff --git a/_f_v_energy_pill_8cpp.html b/_f_v_energy_pill_8cpp.html index 29f239d6c560..0230655050f5 100644 --- a/_f_v_energy_pill_8cpp.html +++ b/_f_v_energy_pill_8cpp.html @@ -129,7 +129,7 @@

Namespaces

-

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Wednesday, Jul 10, 2024 using Doxygen and m.css. Contact us via GitHub.

+

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Thursday, Jul 11, 2024 using Doxygen and m.css. Contact us via GitHub.

diff --git a/_f_v_energy_pill_8hpp.html b/_f_v_energy_pill_8hpp.html index 43028481ae84..a9a7db4b9414 100644 --- a/_f_v_energy_pill_8hpp.html +++ b/_f_v_energy_pill_8hpp.html @@ -139,7 +139,7 @@

Classes

-

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Wednesday, Jul 10, 2024 using Doxygen and m.css. Contact us via GitHub.

+

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Thursday, Jul 11, 2024 using Doxygen and m.css. Contact us via GitHub.

diff --git a/_f_v_euler_8hpp.html b/_f_v_euler_8hpp.html index 26d0f8aab7dd..66473b3a3baa 100644 --- a/_f_v_euler_8hpp.html +++ b/_f_v_euler_8hpp.html @@ -139,7 +139,7 @@

Classes

-

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Wednesday, Jul 10, 2024 using Doxygen and m.css. Contact us via GitHub.

+

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Thursday, Jul 11, 2024 using Doxygen and m.css. Contact us via GitHub.

diff --git a/_f_v_multi_mat_8hpp.html b/_f_v_multi_mat_8hpp.html index 8060ad0f998b..a169f7b05a56 100644 --- a/_f_v_multi_mat_8hpp.html +++ b/_f_v_multi_mat_8hpp.html @@ -140,7 +140,7 @@

Classes

-

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Wednesday, Jul 10, 2024 using Doxygen and m.css. Contact us via GitHub.

+

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Thursday, Jul 11, 2024 using Doxygen and m.css. Contact us via GitHub.

diff --git a/_f_v_p_d_e_8cpp.html b/_f_v_p_d_e_8cpp.html index 0d82343a4a70..3149bcf0ac07 100644 --- a/_f_v_p_d_e_8cpp.html +++ b/_f_v_p_d_e_8cpp.html @@ -111,7 +111,7 @@

-

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Wednesday, Jul 10, 2024 using Doxygen and m.css. Contact us via GitHub.

+

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Thursday, Jul 11, 2024 using Doxygen and m.css. Contact us via GitHub.

diff --git a/_f_v_p_d_e_8hpp.html b/_f_v_p_d_e_8hpp.html index 25cec2d056d9..e649642f2e02 100644 --- a/_f_v_p_d_e_8hpp.html +++ b/_f_v_p_d_e_8hpp.html @@ -139,7 +139,7 @@

Classes

-

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Wednesday, Jul 10, 2024 using Doxygen and m.css. Contact us via GitHub.

+

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Thursday, Jul 11, 2024 using Doxygen and m.css. Contact us via GitHub.

diff --git a/_face_data_8cpp.html b/_face_data_8cpp.html index 001a08f66c8f..8172a3c49654 100644 --- a/_face_data_8cpp.html +++ b/_face_data_8cpp.html @@ -110,7 +110,7 @@

-

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Wednesday, Jul 10, 2024 using Doxygen and m.css. Contact us via GitHub.

+

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Thursday, Jul 11, 2024 using Doxygen and m.css. Contact us via GitHub.

diff --git a/_face_data_8hpp.html b/_face_data_8hpp.html index 663b1a66d109..84acaec5fe35 100644 --- a/_face_data_8hpp.html +++ b/_face_data_8hpp.html @@ -138,7 +138,7 @@

Classes

-

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Wednesday, Jul 10, 2024 using Doxygen and m.css. Contact us via GitHub.

+

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Thursday, Jul 11, 2024 using Doxygen and m.css. Contact us via GitHub.

diff --git a/_field_file_8hpp.html b/_field_file_8hpp.html index 60198cefbd96..cdbf4124a26b 100644 --- a/_field_file_8hpp.html +++ b/_field_file_8hpp.html @@ -139,7 +139,7 @@

Classes

-

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Wednesday, Jul 10, 2024 using Doxygen and m.css. Contact us via GitHub.

+

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Thursday, Jul 11, 2024 using Doxygen and m.css. Contact us via GitHub.

diff --git a/_fields_8hpp.html b/_fields_8hpp.html index 3428997508d7..6828aaa1d377 100644 --- a/_fields_8hpp.html +++ b/_fields_8hpp.html @@ -129,7 +129,7 @@

Namespaces

-

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Wednesday, Jul 10, 2024 using Doxygen and m.css. Contact us via GitHub.

+

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Thursday, Jul 11, 2024 using Doxygen and m.css. Contact us via GitHub.

diff --git a/_flip__map_8hpp.html b/_flip__map_8hpp.html index 720496b62cf8..02af3a2dd2c6 100644 --- a/_flip__map_8hpp.html +++ b/_flip__map_8hpp.html @@ -129,7 +129,7 @@

Namespaces

-

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Wednesday, Jul 10, 2024 using Doxygen and m.css. Contact us via GitHub.

+

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Thursday, Jul 11, 2024 using Doxygen and m.css. Contact us via GitHub.

diff --git a/_flux_8hpp.html b/_flux_8hpp.html index 7f03379a7194..6ec3002c326f 100644 --- a/_flux_8hpp.html +++ b/_flux_8hpp.html @@ -141,7 +141,7 @@

Classes

-

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Wednesday, Jul 10, 2024 using Doxygen and m.css. Contact us via GitHub.

+

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Thursday, Jul 11, 2024 using Doxygen and m.css. Contact us via GitHub.

diff --git a/_function_prototypes_8hpp.html b/_function_prototypes_8hpp.html index c8bdf41760dc..7e12aaebc31f 100644 --- a/_function_prototypes_8hpp.html +++ b/_function_prototypes_8hpp.html @@ -129,7 +129,7 @@

Namespaces

-

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Wednesday, Jul 10, 2024 using Doxygen and m.css. Contact us via GitHub.

+

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Thursday, Jul 11, 2024 using Doxygen and m.css. Contact us via GitHub.

diff --git a/_gauss_hump_8cpp.html b/_gauss_hump_8cpp.html index d612a3ea8f6a..a6b95e10e6bd 100644 --- a/_gauss_hump_8cpp.html +++ b/_gauss_hump_8cpp.html @@ -111,7 +111,7 @@

-

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Wednesday, Jul 10, 2024 using Doxygen and m.css. Contact us via GitHub.

+

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Thursday, Jul 11, 2024 using Doxygen and m.css. Contact us via GitHub.

diff --git a/_gauss_hump_8hpp.html b/_gauss_hump_8hpp.html index 671be1b841c6..f4b17a12160c 100644 --- a/_gauss_hump_8hpp.html +++ b/_gauss_hump_8hpp.html @@ -139,7 +139,7 @@

Classes

-

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Wednesday, Jul 10, 2024 using Doxygen and m.css. Contact us via GitHub.

+

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Thursday, Jul 11, 2024 using Doxygen and m.css. Contact us via GitHub.

diff --git a/_gauss_hump_compflow_8cpp.html b/_gauss_hump_compflow_8cpp.html index 5e5caae92568..021fa36d4139 100644 --- a/_gauss_hump_compflow_8cpp.html +++ b/_gauss_hump_compflow_8cpp.html @@ -111,7 +111,7 @@

-

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Wednesday, Jul 10, 2024 using Doxygen and m.css. Contact us via GitHub.

+

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Thursday, Jul 11, 2024 using Doxygen and m.css. Contact us via GitHub.

diff --git a/_gauss_hump_compflow_8hpp.html b/_gauss_hump_compflow_8hpp.html index 65810df72eac..8730071ebefe 100644 --- a/_gauss_hump_compflow_8hpp.html +++ b/_gauss_hump_compflow_8hpp.html @@ -139,7 +139,7 @@

Classes

-

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Wednesday, Jul 10, 2024 using Doxygen and m.css. Contact us via GitHub.

+

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Thursday, Jul 11, 2024 using Doxygen and m.css. Contact us via GitHub.

diff --git a/_get_mat_prop_8hpp.html b/_get_mat_prop_8hpp.html index 395aae225351..975e454a51d4 100644 --- a/_get_mat_prop_8hpp.html +++ b/_get_mat_prop_8hpp.html @@ -129,7 +129,7 @@

Namespaces

-

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Wednesday, Jul 10, 2024 using Doxygen and m.css. Contact us via GitHub.

+

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Thursday, Jul 11, 2024 using Doxygen and m.css. Contact us via GitHub.

diff --git a/_ghosts_8cpp.html b/_ghosts_8cpp.html index 757bafa80c6c..cae3f4198d0d 100644 --- a/_ghosts_8cpp.html +++ b/_ghosts_8cpp.html @@ -129,7 +129,7 @@

Variables

-

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Wednesday, Jul 10, 2024 using Doxygen and m.css. Contact us via GitHub.

+

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Thursday, Jul 11, 2024 using Doxygen and m.css. Contact us via GitHub.

diff --git a/_ghosts_8hpp.html b/_ghosts_8hpp.html index 85e8189157d9..6d1a553e8f3a 100644 --- a/_ghosts_8hpp.html +++ b/_ghosts_8hpp.html @@ -143,7 +143,7 @@

Classes

-

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Wednesday, Jul 10, 2024 using Doxygen and m.css. Contact us via GitHub.

+

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Thursday, Jul 11, 2024 using Doxygen and m.css. Contact us via GitHub.

diff --git a/_gmsh_mesh_i_o_8hpp.html b/_gmsh_mesh_i_o_8hpp.html index cf6d8ab366db..1dfa63348f7e 100644 --- a/_gmsh_mesh_i_o_8hpp.html +++ b/_gmsh_mesh_i_o_8hpp.html @@ -129,7 +129,7 @@

Namespaces

-

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Wednesday, Jul 10, 2024 using Doxygen and m.css. Contact us via GitHub.

+

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Thursday, Jul 11, 2024 using Doxygen and m.css. Contact us via GitHub.

diff --git a/_gmsh_mesh_reader_8cpp.html b/_gmsh_mesh_reader_8cpp.html index df5ff2c2eb72..f39d7b4ad7a8 100644 --- a/_gmsh_mesh_reader_8cpp.html +++ b/_gmsh_mesh_reader_8cpp.html @@ -111,7 +111,7 @@

-

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Wednesday, Jul 10, 2024 using Doxygen and m.css. Contact us via GitHub.

+

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Thursday, Jul 11, 2024 using Doxygen and m.css. Contact us via GitHub.

diff --git a/_gmsh_mesh_reader_8hpp.html b/_gmsh_mesh_reader_8hpp.html index 4fdb7914c7c6..f0d40e167d0b 100644 --- a/_gmsh_mesh_reader_8hpp.html +++ b/_gmsh_mesh_reader_8hpp.html @@ -139,7 +139,7 @@

Classes

-

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Wednesday, Jul 10, 2024 using Doxygen and m.css. Contact us via GitHub.

+

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Thursday, Jul 11, 2024 using Doxygen and m.css. Contact us via GitHub.

diff --git a/_gmsh_mesh_writer_8cpp.html b/_gmsh_mesh_writer_8cpp.html index b691a47ebf2f..845e9d264902 100644 --- a/_gmsh_mesh_writer_8cpp.html +++ b/_gmsh_mesh_writer_8cpp.html @@ -111,7 +111,7 @@

-

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Wednesday, Jul 10, 2024 using Doxygen and m.css. Contact us via GitHub.

+

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Thursday, Jul 11, 2024 using Doxygen and m.css. Contact us via GitHub.

diff --git a/_gmsh_mesh_writer_8hpp.html b/_gmsh_mesh_writer_8hpp.html index bbef593d4609..e3580c7b0cef 100644 --- a/_gmsh_mesh_writer_8hpp.html +++ b/_gmsh_mesh_writer_8hpp.html @@ -139,7 +139,7 @@

Classes

-

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Wednesday, Jul 10, 2024 using Doxygen and m.css. Contact us via GitHub.

+

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Thursday, Jul 11, 2024 using Doxygen and m.css. Contact us via GitHub.

diff --git a/_gradients_8cpp.html b/_gradients_8cpp.html index 063497775da6..29bdac038a24 100644 --- a/_gradients_8cpp.html +++ b/_gradients_8cpp.html @@ -129,7 +129,7 @@

Namespaces

-

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Wednesday, Jul 10, 2024 using Doxygen and m.css. Contact us via GitHub.

+

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Thursday, Jul 11, 2024 using Doxygen and m.css. Contact us via GitHub.

diff --git a/_gradients_8hpp.html b/_gradients_8hpp.html index f2e5ff6928c3..9e1af4a7a53e 100644 --- a/_gradients_8hpp.html +++ b/_gradients_8hpp.html @@ -129,7 +129,7 @@

Namespaces

-

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Wednesday, Jul 10, 2024 using Doxygen and m.css. Contact us via GitHub.

+

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Thursday, Jul 11, 2024 using Doxygen and m.css. Contact us via GitHub.

diff --git a/_h5_part_8hpp.html b/_h5_part_8hpp.html index a61a3dc147dd..5a1d4285a6b5 100644 --- a/_h5_part_8hpp.html +++ b/_h5_part_8hpp.html @@ -111,7 +111,7 @@

-

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Wednesday, Jul 10, 2024 using Doxygen and m.css. Contact us via GitHub.

+

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Thursday, Jul 11, 2024 using Doxygen and m.css. Contact us via GitHub.

diff --git a/_h_l_l_8hpp.html b/_h_l_l_8hpp.html index c669f88f7f1c..b266332866a0 100644 --- a/_h_l_l_8hpp.html +++ b/_h_l_l_8hpp.html @@ -139,7 +139,7 @@

Classes

-

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Wednesday, Jul 10, 2024 using Doxygen and m.css. Contact us via GitHub.

+

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Thursday, Jul 11, 2024 using Doxygen and m.css. Contact us via GitHub.

diff --git a/_h_l_l_c_8hpp.html b/_h_l_l_c_8hpp.html index 0fe640c65fc8..b7b058ac5f9e 100644 --- a/_h_l_l_c_8hpp.html +++ b/_h_l_l_c_8hpp.html @@ -139,7 +139,7 @@

Classes

-

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Wednesday, Jul 10, 2024 using Doxygen and m.css. Contact us via GitHub.

+

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Thursday, Jul 11, 2024 using Doxygen and m.css. Contact us via GitHub.

diff --git a/_h_y_p_r_e__krylov_8hpp.html b/_h_y_p_r_e__krylov_8hpp.html index 21f66f51af58..24b3347e1e15 100644 --- a/_h_y_p_r_e__krylov_8hpp.html +++ b/_h_y_p_r_e__krylov_8hpp.html @@ -111,7 +111,7 @@

-

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Wednesday, Jul 10, 2024 using Doxygen and m.css. Contact us via GitHub.

+

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Thursday, Jul 11, 2024 using Doxygen and m.css. Contact us via GitHub.

diff --git a/_h_y_p_r_e__parcsr__ls_8hpp.html b/_h_y_p_r_e__parcsr__ls_8hpp.html index 1f7818618efc..47db4ca975ff 100644 --- a/_h_y_p_r_e__parcsr__ls_8hpp.html +++ b/_h_y_p_r_e__parcsr__ls_8hpp.html @@ -111,7 +111,7 @@

-

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Wednesday, Jul 10, 2024 using Doxygen and m.css. Contact us via GitHub.

+

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Thursday, Jul 11, 2024 using Doxygen and m.css. Contact us via GitHub.

diff --git a/_has_8hpp.html b/_has_8hpp.html index c1e237ecce60..dad2669ec430 100644 --- a/_has_8hpp.html +++ b/_has_8hpp.html @@ -165,7 +165,7 @@

Classes

-

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Wednesday, Jul 10, 2024 using Doxygen and m.css. Contact us via GitHub.

+

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Thursday, Jul 11, 2024 using Doxygen and m.css. Contact us via GitHub.

diff --git a/_hash_map_reducer_8hpp.html b/_hash_map_reducer_8hpp.html index 4bef25a3a26b..e683cee5f497 100644 --- a/_hash_map_reducer_8hpp.html +++ b/_hash_map_reducer_8hpp.html @@ -129,7 +129,7 @@

Namespaces

-

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Wednesday, Jul 10, 2024 using Doxygen and m.css. Contact us via GitHub.

+

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Thursday, Jul 11, 2024 using Doxygen and m.css. Contact us via GitHub.

diff --git a/_help_factory_8hpp.html b/_help_factory_8hpp.html index 6c40f4d37f83..9ae29773c3b8 100644 --- a/_help_factory_8hpp.html +++ b/_help_factory_8hpp.html @@ -147,7 +147,7 @@

Classes

-

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Wednesday, Jul 10, 2024 using Doxygen and m.css. Contact us via GitHub.

+

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Thursday, Jul 11, 2024 using Doxygen and m.css. Contact us via GitHub.

diff --git a/_history_8hpp.html b/_history_8hpp.html index 229aed5975c9..b7aa7a4c6d49 100644 --- a/_history_8hpp.html +++ b/_history_8hpp.html @@ -129,7 +129,7 @@

Namespaces

-

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Wednesday, Jul 10, 2024 using Doxygen and m.css. Contact us via GitHub.

+

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Thursday, Jul 11, 2024 using Doxygen and m.css. Contact us via GitHub.

diff --git a/_hyper_mesh_reader_8cpp.html b/_hyper_mesh_reader_8cpp.html index dee384af5cc1..86582aca6d3e 100644 --- a/_hyper_mesh_reader_8cpp.html +++ b/_hyper_mesh_reader_8cpp.html @@ -111,7 +111,7 @@

-

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Wednesday, Jul 10, 2024 using Doxygen and m.css. Contact us via GitHub.

+

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Thursday, Jul 11, 2024 using Doxygen and m.css. Contact us via GitHub.

diff --git a/_hyper_mesh_reader_8hpp.html b/_hyper_mesh_reader_8hpp.html index 591534931e41..019a493aca15 100644 --- a/_hyper_mesh_reader_8hpp.html +++ b/_hyper_mesh_reader_8hpp.html @@ -139,7 +139,7 @@

Classes

-

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Wednesday, Jul 10, 2024 using Doxygen and m.css. Contact us via GitHub.

+

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Thursday, Jul 11, 2024 using Doxygen and m.css. Contact us via GitHub.

diff --git a/_if_8hpp.html b/_if_8hpp.html index d65a2563be8a..90da8e36085e 100644 --- a/_if_8hpp.html +++ b/_if_8hpp.html @@ -140,7 +140,7 @@

Classes

-

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Wednesday, Jul 10, 2024 using Doxygen and m.css. Contact us via GitHub.

+

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Thursday, Jul 11, 2024 using Doxygen and m.css. Contact us via GitHub.

diff --git a/_inciter_2_a_m_r_2_error_8hpp.html b/_inciter_2_a_m_r_2_error_8hpp.html index 39969af888c7..5661cd47b312 100644 --- a/_inciter_2_a_m_r_2_error_8hpp.html +++ b/_inciter_2_a_m_r_2_error_8hpp.html @@ -131,7 +131,7 @@

Classes

-

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Wednesday, Jul 10, 2024 using Doxygen and m.css. Contact us via GitHub.

+

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Thursday, Jul 11, 2024 using Doxygen and m.css. Contact us via GitHub.

diff --git a/_inciter_2_cmd_line_2_cmd_line_8hpp.html b/_inciter_2_cmd_line_2_cmd_line_8hpp.html index 6373cb51c093..5697a65b2851 100644 --- a/_inciter_2_cmd_line_2_cmd_line_8hpp.html +++ b/_inciter_2_cmd_line_2_cmd_line_8hpp.html @@ -141,7 +141,7 @@

Classes

-

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Wednesday, Jul 10, 2024 using Doxygen and m.css. Contact us via GitHub.

+

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Thursday, Jul 11, 2024 using Doxygen and m.css. Contact us via GitHub.

diff --git a/_inciter_2_cmd_line_2_grammar_8hpp.html b/_inciter_2_cmd_line_2_grammar_8hpp.html index 95edd44e1d77..48f86659e4a5 100644 --- a/_inciter_2_cmd_line_2_grammar_8hpp.html +++ b/_inciter_2_cmd_line_2_grammar_8hpp.html @@ -210,7 +210,7 @@

Classes

-

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Wednesday, Jul 10, 2024 using Doxygen and m.css. Contact us via GitHub.

+

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Thursday, Jul 11, 2024 using Doxygen and m.css. Contact us via GitHub.

diff --git a/_inciter_2_cmd_line_2_parser_8cpp.html b/_inciter_2_cmd_line_2_parser_8cpp.html index 9ab036323b73..d4007547aad8 100644 --- a/_inciter_2_cmd_line_2_parser_8cpp.html +++ b/_inciter_2_cmd_line_2_parser_8cpp.html @@ -133,7 +133,7 @@

Namespaces

-

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Wednesday, Jul 10, 2024 using Doxygen and m.css. Contact us via GitHub.

+

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Thursday, Jul 11, 2024 using Doxygen and m.css. Contact us via GitHub.

diff --git a/_inciter_2_cmd_line_2_parser_8hpp.html b/_inciter_2_cmd_line_2_parser_8hpp.html index 7833618a53ae..76468142dd05 100644 --- a/_inciter_2_cmd_line_2_parser_8hpp.html +++ b/_inciter_2_cmd_line_2_parser_8hpp.html @@ -141,7 +141,7 @@

Classes

-

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Wednesday, Jul 10, 2024 using Doxygen and m.css. Contact us via GitHub.

+

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Thursday, Jul 11, 2024 using Doxygen and m.css. Contact us via GitHub.

diff --git a/_inciter_2_d_g_8hpp.html b/_inciter_2_d_g_8hpp.html index f33973b044cd..748e5953141d 100644 --- a/_inciter_2_d_g_8hpp.html +++ b/_inciter_2_d_g_8hpp.html @@ -139,7 +139,7 @@

Classes

-

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Wednesday, Jul 10, 2024 using Doxygen and m.css. Contact us via GitHub.

+

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Thursday, Jul 11, 2024 using Doxygen and m.css. Contact us via GitHub.

diff --git a/_inciter_2_f_v_8hpp.html b/_inciter_2_f_v_8hpp.html index 722dbbcd75e4..4b0d6c61e6a9 100644 --- a/_inciter_2_f_v_8hpp.html +++ b/_inciter_2_f_v_8hpp.html @@ -139,7 +139,7 @@

Classes

-

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Wednesday, Jul 10, 2024 using Doxygen and m.css. Contact us via GitHub.

+

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Thursday, Jul 11, 2024 using Doxygen and m.css. Contact us via GitHub.

diff --git a/_inciter_2_field_output_8cpp.html b/_inciter_2_field_output_8cpp.html index e86a147be81f..11d879269477 100644 --- a/_inciter_2_field_output_8cpp.html +++ b/_inciter_2_field_output_8cpp.html @@ -129,7 +129,7 @@

Namespaces

-

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Wednesday, Jul 10, 2024 using Doxygen and m.css. Contact us via GitHub.

+

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Thursday, Jul 11, 2024 using Doxygen and m.css. Contact us via GitHub.

diff --git a/_inciter_2_field_output_8hpp.html b/_inciter_2_field_output_8hpp.html index d8fc540c533f..d3dc738f268d 100644 --- a/_inciter_2_field_output_8hpp.html +++ b/_inciter_2_field_output_8hpp.html @@ -129,7 +129,7 @@

Namespaces

-

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Wednesday, Jul 10, 2024 using Doxygen and m.css. Contact us via GitHub.

+

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Thursday, Jul 11, 2024 using Doxygen and m.css. Contact us via GitHub.

diff --git a/_inciter_2_scheme_8hpp.html b/_inciter_2_scheme_8hpp.html index 718dbdef5940..5f30e16b29db 100644 --- a/_inciter_2_scheme_8hpp.html +++ b/_inciter_2_scheme_8hpp.html @@ -154,7 +154,7 @@

Classes

-

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Wednesday, Jul 10, 2024 using Doxygen and m.css. Contact us via GitHub.

+

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Thursday, Jul 11, 2024 using Doxygen and m.css. Contact us via GitHub.

diff --git a/_inciter_8cpp.html b/_inciter_8cpp.html index effcd66a0c8b..a246fd8a828d 100644 --- a/_inciter_8cpp.html +++ b/_inciter_8cpp.html @@ -166,7 +166,7 @@

-

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Wednesday, Jul 10, 2024 using Doxygen and m.css. Contact us via GitHub.

+

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Thursday, Jul 11, 2024 using Doxygen and m.css. Contact us via GitHub.

diff --git a/_inciter_driver_8cpp.html b/_inciter_driver_8cpp.html index 42d750835bfd..b2c9f814bdbe 100644 --- a/_inciter_driver_8cpp.html +++ b/_inciter_driver_8cpp.html @@ -129,7 +129,7 @@

Namespaces

-

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Wednesday, Jul 10, 2024 using Doxygen and m.css. Contact us via GitHub.

+

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Thursday, Jul 11, 2024 using Doxygen and m.css. Contact us via GitHub.

diff --git a/_inciter_driver_8hpp.html b/_inciter_driver_8hpp.html index bcc2d9c79d47..f25b7222902a 100644 --- a/_inciter_driver_8hpp.html +++ b/_inciter_driver_8hpp.html @@ -139,7 +139,7 @@

Classes

-

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Wednesday, Jul 10, 2024 using Doxygen and m.css. Contact us via GitHub.

+

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Thursday, Jul 11, 2024 using Doxygen and m.css. Contact us via GitHub.

diff --git a/_inciter_print_8cpp.html b/_inciter_print_8cpp.html index 96c343399b88..1cee329eb378 100644 --- a/_inciter_print_8cpp.html +++ b/_inciter_print_8cpp.html @@ -129,7 +129,7 @@

Namespaces

-

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Wednesday, Jul 10, 2024 using Doxygen and m.css. Contact us via GitHub.

+

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Thursday, Jul 11, 2024 using Doxygen and m.css. Contact us via GitHub.

diff --git a/_inciter_print_8hpp.html b/_inciter_print_8hpp.html index 7678777c673f..fc071699dbf3 100644 --- a/_inciter_print_8hpp.html +++ b/_inciter_print_8hpp.html @@ -139,7 +139,7 @@

Classes

-

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Wednesday, Jul 10, 2024 using Doxygen and m.css. Contact us via GitHub.

+

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Thursday, Jul 11, 2024 using Doxygen and m.css. Contact us via GitHub.

diff --git a/_init_8cpp.html b/_init_8cpp.html index a9bc8adabd40..3aea3b3b236f 100644 --- a/_init_8cpp.html +++ b/_init_8cpp.html @@ -129,7 +129,7 @@

Namespaces

-

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Wednesday, Jul 10, 2024 using Doxygen and m.css. Contact us via GitHub.

+

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Thursday, Jul 11, 2024 using Doxygen and m.css. Contact us via GitHub.

diff --git a/_init_8hpp.html b/_init_8hpp.html index 6502f9e025cd..d03032673aa8 100644 --- a/_init_8hpp.html +++ b/_init_8hpp.html @@ -129,7 +129,7 @@

Namespaces

-

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Wednesday, Jul 10, 2024 using Doxygen and m.css. Contact us via GitHub.

+

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Thursday, Jul 11, 2024 using Doxygen and m.css. Contact us via GitHub.

diff --git a/_initialize_8cpp.html b/_initialize_8cpp.html index 09502ec9bbd2..e6d712a30716 100644 --- a/_initialize_8cpp.html +++ b/_initialize_8cpp.html @@ -129,7 +129,7 @@

Namespaces

-

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Wednesday, Jul 10, 2024 using Doxygen and m.css. Contact us via GitHub.

+

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Thursday, Jul 11, 2024 using Doxygen and m.css. Contact us via GitHub.

diff --git a/_initialize_8hpp.html b/_initialize_8hpp.html index 254fcf288ffa..1af282643e24 100644 --- a/_initialize_8hpp.html +++ b/_initialize_8hpp.html @@ -131,7 +131,7 @@

Namespaces

-

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Wednesday, Jul 10, 2024 using Doxygen and m.css. Contact us via GitHub.

+

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Thursday, Jul 11, 2024 using Doxygen and m.css. Contact us via GitHub.

diff --git a/_initiate_8hpp.html b/_initiate_8hpp.html index e24eb299359c..708fbc98243a 100644 --- a/_initiate_8hpp.html +++ b/_initiate_8hpp.html @@ -141,7 +141,7 @@

Classes

-

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Wednesday, Jul 10, 2024 using Doxygen and m.css. Contact us via GitHub.

+

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Thursday, Jul 11, 2024 using Doxygen and m.css. Contact us via GitHub.

diff --git a/_input_deck_8hpp.html b/_input_deck_8hpp.html index bb9009be4344..87acafa6954d 100644 --- a/_input_deck_8hpp.html +++ b/_input_deck_8hpp.html @@ -111,7 +111,7 @@

-

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Wednesday, Jul 10, 2024 using Doxygen and m.css. Contact us via GitHub.

+

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Thursday, Jul 11, 2024 using Doxygen and m.css. Contact us via GitHub.

diff --git a/_interface_advection_8cpp.html b/_interface_advection_8cpp.html index e1f80533d5f0..85ed7657ad5e 100644 --- a/_interface_advection_8cpp.html +++ b/_interface_advection_8cpp.html @@ -129,7 +129,7 @@

Namespaces

-

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Wednesday, Jul 10, 2024 using Doxygen and m.css. Contact us via GitHub.

+

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Thursday, Jul 11, 2024 using Doxygen and m.css. Contact us via GitHub.

diff --git a/_interface_advection_8hpp.html b/_interface_advection_8hpp.html index 7a15eee88a79..af8972bb4990 100644 --- a/_interface_advection_8hpp.html +++ b/_interface_advection_8hpp.html @@ -139,7 +139,7 @@

Classes

-

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Wednesday, Jul 10, 2024 using Doxygen and m.css. Contact us via GitHub.

+

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Thursday, Jul 11, 2024 using Doxygen and m.css. Contact us via GitHub.

diff --git a/_j_w_l_8cpp.html b/_j_w_l_8cpp.html index d365ff4d3107..3773fce0ae60 100644 --- a/_j_w_l_8cpp.html +++ b/_j_w_l_8cpp.html @@ -111,7 +111,7 @@

-

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Wednesday, Jul 10, 2024 using Doxygen and m.css. Contact us via GitHub.

+

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Thursday, Jul 11, 2024 using Doxygen and m.css. Contact us via GitHub.

diff --git a/_j_w_l_8hpp.html b/_j_w_l_8hpp.html index 744cba74e258..21128a324bf1 100644 --- a/_j_w_l_8hpp.html +++ b/_j_w_l_8hpp.html @@ -129,7 +129,7 @@

Namespaces

-

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Wednesday, Jul 10, 2024 using Doxygen and m.css. Contact us via GitHub.

+

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Thursday, Jul 11, 2024 using Doxygen and m.css. Contact us via GitHub.

diff --git a/_keyword_8hpp.html b/_keyword_8hpp.html index 434f11175a8a..a8cd1e3386d0 100644 --- a/_keyword_8hpp.html +++ b/_keyword_8hpp.html @@ -147,7 +147,7 @@

Classes

-

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Wednesday, Jul 10, 2024 using Doxygen and m.css. Contact us via GitHub.

+

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Thursday, Jul 11, 2024 using Doxygen and m.css. Contact us via GitHub.

diff --git a/_keywords_8hpp.html b/_keywords_8hpp.html index 9e0160ef4c9d..2e3d2bbd69fa 100644 --- a/_keywords_8hpp.html +++ b/_keywords_8hpp.html @@ -228,7 +228,7 @@

Namespaces

-

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Wednesday, Jul 10, 2024 using Doxygen and m.css. Contact us via GitHub.

+

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Thursday, Jul 11, 2024 using Doxygen and m.css. Contact us via GitHub.

diff --git a/_l_b_switch_8cpp.html b/_l_b_switch_8cpp.html index 2990a2acb97b..be1445f2768b 100644 --- a/_l_b_switch_8cpp.html +++ b/_l_b_switch_8cpp.html @@ -111,7 +111,7 @@

-

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Wednesday, Jul 10, 2024 using Doxygen and m.css. Contact us via GitHub.

+

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Thursday, Jul 11, 2024 using Doxygen and m.css. Contact us via GitHub.

diff --git a/_l_b_switch_8hpp.html b/_l_b_switch_8hpp.html index a4fb56a234ae..da4c29a197d9 100644 --- a/_l_b_switch_8hpp.html +++ b/_l_b_switch_8hpp.html @@ -139,7 +139,7 @@

Classes

-

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Wednesday, Jul 10, 2024 using Doxygen and m.css. Contact us via GitHub.

+

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Thursday, Jul 11, 2024 using Doxygen and m.css. Contact us via GitHub.

diff --git a/_lax_friedrichs_8hpp.html b/_lax_friedrichs_8hpp.html index d68736c7dc88..43e49ccc7f9c 100644 --- a/_lax_friedrichs_8hpp.html +++ b/_lax_friedrichs_8hpp.html @@ -139,7 +139,7 @@

Classes

-

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Wednesday, Jul 10, 2024 using Doxygen and m.css. Contact us via GitHub.

+

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Thursday, Jul 11, 2024 using Doxygen and m.css. Contact us via GitHub.

diff --git a/_lax_friedrichs_solids_8hpp.html b/_lax_friedrichs_solids_8hpp.html index 665aeb13b3f7..8e0278450847 100644 --- a/_lax_friedrichs_solids_8hpp.html +++ b/_lax_friedrichs_solids_8hpp.html @@ -139,7 +139,7 @@

Classes

-

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Wednesday, Jul 10, 2024 using Doxygen and m.css. Contact us via GitHub.

+

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Thursday, Jul 11, 2024 using Doxygen and m.css. Contact us via GitHub.

diff --git a/_limiter_8cpp.html b/_limiter_8cpp.html index 11df87a54bcb..6227a7b214a2 100644 --- a/_limiter_8cpp.html +++ b/_limiter_8cpp.html @@ -129,7 +129,7 @@

Namespaces

-

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Wednesday, Jul 10, 2024 using Doxygen and m.css. Contact us via GitHub.

+

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Thursday, Jul 11, 2024 using Doxygen and m.css. Contact us via GitHub.

diff --git a/_linear_map_8cpp.html b/_linear_map_8cpp.html index d10e9352ac49..f68372888ec5 100644 --- a/_linear_map_8cpp.html +++ b/_linear_map_8cpp.html @@ -111,7 +111,7 @@

-

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Wednesday, Jul 10, 2024 using Doxygen and m.css. Contact us via GitHub.

+

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Thursday, Jul 11, 2024 using Doxygen and m.css. Contact us via GitHub.

diff --git a/_linear_map_8hpp.html b/_linear_map_8hpp.html index 3cd61c9a63c2..37422251ea5e 100644 --- a/_linear_map_8hpp.html +++ b/_linear_map_8hpp.html @@ -139,7 +139,7 @@

Classes

-

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Wednesday, Jul 10, 2024 using Doxygen and m.css. Contact us via GitHub.

+

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Thursday, Jul 11, 2024 using Doxygen and m.css. Contact us via GitHub.

diff --git a/_load_distributor_8cpp.html b/_load_distributor_8cpp.html index 016684573879..8fd60e8cd83f 100644 --- a/_load_distributor_8cpp.html +++ b/_load_distributor_8cpp.html @@ -129,7 +129,7 @@

Namespaces

-

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Wednesday, Jul 10, 2024 using Doxygen and m.css. Contact us via GitHub.

+

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Thursday, Jul 11, 2024 using Doxygen and m.css. Contact us via GitHub.

diff --git a/_load_distributor_8hpp.html b/_load_distributor_8hpp.html index 485b48571c81..423fa75d23fe 100644 --- a/_load_distributor_8hpp.html +++ b/_load_distributor_8hpp.html @@ -129,7 +129,7 @@

Namespaces

-

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Wednesday, Jul 10, 2024 using Doxygen and m.css. Contact us via GitHub.

+

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Thursday, Jul 11, 2024 using Doxygen and m.css. Contact us via GitHub.

diff --git a/_lua_parser_8cpp.html b/_lua_parser_8cpp.html index 877bf2432622..4dc37ce830bb 100644 --- a/_lua_parser_8cpp.html +++ b/_lua_parser_8cpp.html @@ -141,7 +141,7 @@

Classes

-

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Wednesday, Jul 10, 2024 using Doxygen and m.css. Contact us via GitHub.

+

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Thursday, Jul 11, 2024 using Doxygen and m.css. Contact us via GitHub.

diff --git a/_lua_parser_8hpp.html b/_lua_parser_8hpp.html index 38bfeca3a9d6..4b0bad1254b9 100644 --- a/_lua_parser_8hpp.html +++ b/_lua_parser_8hpp.html @@ -141,7 +141,7 @@

Classes

-

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Wednesday, Jul 10, 2024 using Doxygen and m.css. Contact us via GitHub.

+

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Thursday, Jul 11, 2024 using Doxygen and m.css. Contact us via GitHub.

diff --git a/_m_p_i_runner_8cpp.html b/_m_p_i_runner_8cpp.html index 1614839436bb..bfbcba66a93c 100644 --- a/_m_p_i_runner_8cpp.html +++ b/_m_p_i_runner_8cpp.html @@ -111,7 +111,7 @@

-

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Wednesday, Jul 10, 2024 using Doxygen and m.css. Contact us via GitHub.

+

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Thursday, Jul 11, 2024 using Doxygen and m.css. Contact us via GitHub.

diff --git a/_m_p_i_runner_8hpp.html b/_m_p_i_runner_8hpp.html index 691233c30ea2..a40159f72d0b 100644 --- a/_m_p_i_runner_8hpp.html +++ b/_m_p_i_runner_8hpp.html @@ -140,7 +140,7 @@

Classes

-

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Wednesday, Jul 10, 2024 using Doxygen and m.css. Contact us via GitHub.

+

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Thursday, Jul 11, 2024 using Doxygen and m.css. Contact us via GitHub.

diff --git a/_macro_8hpp.html b/_macro_8hpp.html index f2374e75da27..4d5c109e886d 100644 --- a/_macro_8hpp.html +++ b/_macro_8hpp.html @@ -158,7 +158,7 @@

-

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Wednesday, Jul 10, 2024 using Doxygen and m.css. Contact us via GitHub.

+

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Thursday, Jul 11, 2024 using Doxygen and m.css. Contact us via GitHub.

diff --git a/_mass_8cpp.html b/_mass_8cpp.html index 062e6e32b4fe..e11496b4fbf4 100644 --- a/_mass_8cpp.html +++ b/_mass_8cpp.html @@ -111,7 +111,7 @@

-

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Wednesday, Jul 10, 2024 using Doxygen and m.css. Contact us via GitHub.

+

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Thursday, Jul 11, 2024 using Doxygen and m.css. Contact us via GitHub.

diff --git a/_mass_8hpp.html b/_mass_8hpp.html index 1d7ab2a8e51a..6dcf8e550068 100644 --- a/_mass_8hpp.html +++ b/_mass_8hpp.html @@ -129,7 +129,7 @@

Namespaces

-

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Wednesday, Jul 10, 2024 using Doxygen and m.css. Contact us via GitHub.

+

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Thursday, Jul 11, 2024 using Doxygen and m.css. Contact us via GitHub.

diff --git a/_material_8hpp.html b/_material_8hpp.html index c438f5281bb5..a3a2452e7b6d 100644 --- a/_material_8hpp.html +++ b/_material_8hpp.html @@ -141,7 +141,7 @@

Classes

-

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Wednesday, Jul 10, 2024 using Doxygen and m.css. Contact us via GitHub.

+

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Thursday, Jul 11, 2024 using Doxygen and m.css. Contact us via GitHub.

diff --git a/_mesh_conv_2_cmd_line_2_cmd_line_8hpp.html b/_mesh_conv_2_cmd_line_2_cmd_line_8hpp.html index d061913e4e67..5572c4d20973 100644 --- a/_mesh_conv_2_cmd_line_2_cmd_line_8hpp.html +++ b/_mesh_conv_2_cmd_line_2_cmd_line_8hpp.html @@ -141,7 +141,7 @@

Classes

-

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Wednesday, Jul 10, 2024 using Doxygen and m.css. Contact us via GitHub.

+

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Thursday, Jul 11, 2024 using Doxygen and m.css. Contact us via GitHub.

diff --git a/_mesh_conv_2_cmd_line_2_grammar_8hpp.html b/_mesh_conv_2_cmd_line_2_grammar_8hpp.html index ef883ab381e0..b037999a990e 100644 --- a/_mesh_conv_2_cmd_line_2_grammar_8hpp.html +++ b/_mesh_conv_2_cmd_line_2_grammar_8hpp.html @@ -186,7 +186,7 @@

Classes

-

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Wednesday, Jul 10, 2024 using Doxygen and m.css. Contact us via GitHub.

+

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Thursday, Jul 11, 2024 using Doxygen and m.css. Contact us via GitHub.

diff --git a/_mesh_conv_2_cmd_line_2_parser_8cpp.html b/_mesh_conv_2_cmd_line_2_parser_8cpp.html index fa0cb732359f..afaaabf54f87 100644 --- a/_mesh_conv_2_cmd_line_2_parser_8cpp.html +++ b/_mesh_conv_2_cmd_line_2_parser_8cpp.html @@ -131,7 +131,7 @@

Namespaces

-

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Wednesday, Jul 10, 2024 using Doxygen and m.css. Contact us via GitHub.

+

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Thursday, Jul 11, 2024 using Doxygen and m.css. Contact us via GitHub.

diff --git a/_mesh_conv_2_cmd_line_2_parser_8hpp.html b/_mesh_conv_2_cmd_line_2_parser_8hpp.html index 1de3a1bf72ec..1a88a38256cb 100644 --- a/_mesh_conv_2_cmd_line_2_parser_8hpp.html +++ b/_mesh_conv_2_cmd_line_2_parser_8hpp.html @@ -141,7 +141,7 @@

Classes

-

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Wednesday, Jul 10, 2024 using Doxygen and m.css. Contact us via GitHub.

+

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Thursday, Jul 11, 2024 using Doxygen and m.css. Contact us via GitHub.

diff --git a/_mesh_conv_8cpp.html b/_mesh_conv_8cpp.html index 2c84f567e016..7cafe5ca20f4 100644 --- a/_mesh_conv_8cpp.html +++ b/_mesh_conv_8cpp.html @@ -156,7 +156,7 @@

-

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Wednesday, Jul 10, 2024 using Doxygen and m.css. Contact us via GitHub.

+

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Thursday, Jul 11, 2024 using Doxygen and m.css. Contact us via GitHub.

diff --git a/_mesh_conv_driver_8cpp.html b/_mesh_conv_driver_8cpp.html index a64a9d309f53..7e7d174ae1ed 100644 --- a/_mesh_conv_driver_8cpp.html +++ b/_mesh_conv_driver_8cpp.html @@ -129,7 +129,7 @@

Variables

-

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Wednesday, Jul 10, 2024 using Doxygen and m.css. Contact us via GitHub.

+

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Thursday, Jul 11, 2024 using Doxygen and m.css. Contact us via GitHub.

diff --git a/_mesh_conv_driver_8hpp.html b/_mesh_conv_driver_8hpp.html index 8dba8bae6beb..2702fed3571f 100644 --- a/_mesh_conv_driver_8hpp.html +++ b/_mesh_conv_driver_8hpp.html @@ -139,7 +139,7 @@

Classes

-

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Wednesday, Jul 10, 2024 using Doxygen and m.css. Contact us via GitHub.

+

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Thursday, Jul 11, 2024 using Doxygen and m.css. Contact us via GitHub.

diff --git a/_mesh_detect_8cpp.html b/_mesh_detect_8cpp.html index 8774827fcb62..8c2b43b60882 100644 --- a/_mesh_detect_8cpp.html +++ b/_mesh_detect_8cpp.html @@ -129,7 +129,7 @@

Namespaces

-

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Wednesday, Jul 10, 2024 using Doxygen and m.css. Contact us via GitHub.

+

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Thursday, Jul 11, 2024 using Doxygen and m.css. Contact us via GitHub.

diff --git a/_mesh_detect_8hpp.html b/_mesh_detect_8hpp.html index fd5b75dfa24c..67002bac5705 100644 --- a/_mesh_detect_8hpp.html +++ b/_mesh_detect_8hpp.html @@ -129,7 +129,7 @@

Namespaces

-

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Wednesday, Jul 10, 2024 using Doxygen and m.css. Contact us via GitHub.

+

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Thursday, Jul 11, 2024 using Doxygen and m.css. Contact us via GitHub.

diff --git a/_mesh_factory_8cpp.html b/_mesh_factory_8cpp.html index 08b0f71bdc1f..17d71814030e 100644 --- a/_mesh_factory_8cpp.html +++ b/_mesh_factory_8cpp.html @@ -129,7 +129,7 @@

Namespaces

-

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Wednesday, Jul 10, 2024 using Doxygen and m.css. Contact us via GitHub.

+

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Thursday, Jul 11, 2024 using Doxygen and m.css. Contact us via GitHub.

diff --git a/_mesh_factory_8hpp.html b/_mesh_factory_8hpp.html index 7c55b4de8057..ed8a26cdf453 100644 --- a/_mesh_factory_8hpp.html +++ b/_mesh_factory_8hpp.html @@ -129,7 +129,7 @@

Namespaces

-

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Wednesday, Jul 10, 2024 using Doxygen and m.css. Contact us via GitHub.

+

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Thursday, Jul 11, 2024 using Doxygen and m.css. Contact us via GitHub.

diff --git a/_mesh_reader_8hpp.html b/_mesh_reader_8hpp.html index 31628bfba1b7..e5bd40a69de9 100644 --- a/_mesh_reader_8hpp.html +++ b/_mesh_reader_8hpp.html @@ -139,7 +139,7 @@

Classes

-

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Wednesday, Jul 10, 2024 using Doxygen and m.css. Contact us via GitHub.

+

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Thursday, Jul 11, 2024 using Doxygen and m.css. Contact us via GitHub.

diff --git a/_mesh_velocity_8hpp.html b/_mesh_velocity_8hpp.html index 41a561d8f32f..a849c3ea3c01 100644 --- a/_mesh_velocity_8hpp.html +++ b/_mesh_velocity_8hpp.html @@ -141,7 +141,7 @@

Classes

-

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Wednesday, Jul 10, 2024 using Doxygen and m.css. Contact us via GitHub.

+

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Thursday, Jul 11, 2024 using Doxygen and m.css. Contact us via GitHub.

diff --git a/_mesh_velocity_smoother_8hpp.html b/_mesh_velocity_smoother_8hpp.html index e97b697dc8dd..3941f1cfe384 100644 --- a/_mesh_velocity_smoother_8hpp.html +++ b/_mesh_velocity_smoother_8hpp.html @@ -141,7 +141,7 @@

Classes

-

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Wednesday, Jul 10, 2024 using Doxygen and m.css. Contact us via GitHub.

+

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Thursday, Jul 11, 2024 using Doxygen and m.css. Contact us via GitHub.

diff --git a/_mesh_writer_8cpp.html b/_mesh_writer_8cpp.html index 447e67e3375f..06be62417fde 100644 --- a/_mesh_writer_8cpp.html +++ b/_mesh_writer_8cpp.html @@ -111,7 +111,7 @@

-

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Wednesday, Jul 10, 2024 using Doxygen and m.css. Contact us via GitHub.

+

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Thursday, Jul 11, 2024 using Doxygen and m.css. Contact us via GitHub.

diff --git a/_mesh_writer_8hpp.html b/_mesh_writer_8hpp.html index a1ee4799827b..730860078ac2 100644 --- a/_mesh_writer_8hpp.html +++ b/_mesh_writer_8hpp.html @@ -139,7 +139,7 @@

Classes

-

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Wednesday, Jul 10, 2024 using Doxygen and m.css. Contact us via GitHub.

+

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Thursday, Jul 11, 2024 using Doxygen and m.css. Contact us via GitHub.

diff --git a/_migrated_types_8hpp.html b/_migrated_types_8hpp.html index f6977846066a..257ca6cb55c8 100644 --- a/_migrated_types_8hpp.html +++ b/_migrated_types_8hpp.html @@ -133,7 +133,7 @@

Namespaces

-

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Wednesday, Jul 10, 2024 using Doxygen and m.css. Contact us via GitHub.

+

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Thursday, Jul 11, 2024 using Doxygen and m.css. Contact us via GitHub.

diff --git a/_misc_multi_mat_fns_8hpp.html b/_misc_multi_mat_fns_8hpp.html index d49090311d66..f93fa3e8d919 100644 --- a/_misc_multi_mat_fns_8hpp.html +++ b/_misc_multi_mat_fns_8hpp.html @@ -129,7 +129,7 @@

Namespaces

-

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Wednesday, Jul 10, 2024 using Doxygen and m.css. Contact us via GitHub.

+

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Thursday, Jul 11, 2024 using Doxygen and m.css. Contact us via GitHub.

diff --git a/_multi_mat_2_physics_2_d_g_euler_8hpp.html b/_multi_mat_2_physics_2_d_g_euler_8hpp.html index 5e5c41c1cf8f..19a11e0c2146 100644 --- a/_multi_mat_2_physics_2_d_g_euler_8hpp.html +++ b/_multi_mat_2_physics_2_d_g_euler_8hpp.html @@ -139,7 +139,7 @@

Classes

-

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Wednesday, Jul 10, 2024 using Doxygen and m.css. Contact us via GitHub.

+

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Thursday, Jul 11, 2024 using Doxygen and m.css. Contact us via GitHub.

diff --git a/_multi_mat_2_problem_2_box_initialization_8hpp.html b/_multi_mat_2_problem_2_box_initialization_8hpp.html index cae55e0c609b..b63bcb8ffa5c 100644 --- a/_multi_mat_2_problem_2_box_initialization_8hpp.html +++ b/_multi_mat_2_problem_2_box_initialization_8hpp.html @@ -129,7 +129,7 @@

Namespaces

-

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Wednesday, Jul 10, 2024 using Doxygen and m.css. Contact us via GitHub.

+

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Thursday, Jul 11, 2024 using Doxygen and m.css. Contact us via GitHub.

diff --git a/_multi_mat_2_problem_2_shock_density_wave_8cpp.html b/_multi_mat_2_problem_2_shock_density_wave_8cpp.html index 82fa144f71e7..8fafda9e0fea 100644 --- a/_multi_mat_2_problem_2_shock_density_wave_8cpp.html +++ b/_multi_mat_2_problem_2_shock_density_wave_8cpp.html @@ -129,7 +129,7 @@

Namespaces

-

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Wednesday, Jul 10, 2024 using Doxygen and m.css. Contact us via GitHub.

+

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Thursday, Jul 11, 2024 using Doxygen and m.css. Contact us via GitHub.

diff --git a/_multi_mat_2_problem_2_shock_density_wave_8hpp.html b/_multi_mat_2_problem_2_shock_density_wave_8hpp.html index 9f41509f3744..075b7493eab5 100644 --- a/_multi_mat_2_problem_2_shock_density_wave_8hpp.html +++ b/_multi_mat_2_problem_2_shock_density_wave_8hpp.html @@ -139,7 +139,7 @@

Classes

-

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Wednesday, Jul 10, 2024 using Doxygen and m.css. Contact us via GitHub.

+

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Thursday, Jul 11, 2024 using Doxygen and m.css. Contact us via GitHub.

diff --git a/_multi_mat_2_problem_2_sod_shocktube_8cpp.html b/_multi_mat_2_problem_2_sod_shocktube_8cpp.html index f28521d15901..8a2378cc0fba 100644 --- a/_multi_mat_2_problem_2_sod_shocktube_8cpp.html +++ b/_multi_mat_2_problem_2_sod_shocktube_8cpp.html @@ -129,7 +129,7 @@

Namespaces

-

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Wednesday, Jul 10, 2024 using Doxygen and m.css. Contact us via GitHub.

+

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Thursday, Jul 11, 2024 using Doxygen and m.css. Contact us via GitHub.

diff --git a/_multi_mat_2_problem_2_sod_shocktube_8hpp.html b/_multi_mat_2_problem_2_sod_shocktube_8hpp.html index 9728803e4684..1f52c068b75b 100644 --- a/_multi_mat_2_problem_2_sod_shocktube_8hpp.html +++ b/_multi_mat_2_problem_2_sod_shocktube_8hpp.html @@ -139,7 +139,7 @@

Classes

-

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Wednesday, Jul 10, 2024 using Doxygen and m.css. Contact us via GitHub.

+

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Thursday, Jul 11, 2024 using Doxygen and m.css. Contact us via GitHub.

diff --git a/_multi_mat_2_problem_2_user_defined_8cpp.html b/_multi_mat_2_problem_2_user_defined_8cpp.html index 65c0d0ab2c96..ef6b89631138 100644 --- a/_multi_mat_2_problem_2_user_defined_8cpp.html +++ b/_multi_mat_2_problem_2_user_defined_8cpp.html @@ -129,7 +129,7 @@

Namespaces

-

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Wednesday, Jul 10, 2024 using Doxygen and m.css. Contact us via GitHub.

+

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Thursday, Jul 11, 2024 using Doxygen and m.css. Contact us via GitHub.

diff --git a/_multi_mat_2_problem_2_user_defined_8hpp.html b/_multi_mat_2_problem_2_user_defined_8hpp.html index 54288ec6f9a7..e569750d174f 100644 --- a/_multi_mat_2_problem_2_user_defined_8hpp.html +++ b/_multi_mat_2_problem_2_user_defined_8hpp.html @@ -139,7 +139,7 @@

Classes

-

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Wednesday, Jul 10, 2024 using Doxygen and m.css. Contact us via GitHub.

+

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Thursday, Jul 11, 2024 using Doxygen and m.css. Contact us via GitHub.

diff --git a/_multi_mat_2_riemann_choice_8hpp.html b/_multi_mat_2_riemann_choice_8hpp.html index 21b2ebcf51c7..ba15a638baeb 100644 --- a/_multi_mat_2_riemann_choice_8hpp.html +++ b/_multi_mat_2_riemann_choice_8hpp.html @@ -129,7 +129,7 @@

Namespaces

-

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Wednesday, Jul 10, 2024 using Doxygen and m.css. Contact us via GitHub.

+

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Thursday, Jul 11, 2024 using Doxygen and m.css. Contact us via GitHub.

diff --git a/_multi_mat_indexing_8hpp.html b/_multi_mat_indexing_8hpp.html index 4d69e762d00b..c4e6686ba6f1 100644 --- a/_multi_mat_indexing_8hpp.html +++ b/_multi_mat_indexing_8hpp.html @@ -129,7 +129,7 @@

Namespaces

-

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Wednesday, Jul 10, 2024 using Doxygen and m.css. Contact us via GitHub.

+

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Thursday, Jul 11, 2024 using Doxygen and m.css. Contact us via GitHub.

diff --git a/_multi_mat_terms_8cpp.html b/_multi_mat_terms_8cpp.html index 011ec41496da..ffea7e79b17e 100644 --- a/_multi_mat_terms_8cpp.html +++ b/_multi_mat_terms_8cpp.html @@ -131,7 +131,7 @@

Namespaces

-

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Wednesday, Jul 10, 2024 using Doxygen and m.css. Contact us via GitHub.

+

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Thursday, Jul 11, 2024 using Doxygen and m.css. Contact us via GitHub.

diff --git a/_multi_mat_terms_8hpp.html b/_multi_mat_terms_8hpp.html index 6fee3c9a82e2..f4ca3883dbd1 100644 --- a/_multi_mat_terms_8hpp.html +++ b/_multi_mat_terms_8hpp.html @@ -129,7 +129,7 @@

Namespaces

-

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Wednesday, Jul 10, 2024 using Doxygen and m.css. Contact us via GitHub.

+

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Thursday, Jul 11, 2024 using Doxygen and m.css. Contact us via GitHub.

diff --git a/_n_l_energy_growth_8cpp.html b/_n_l_energy_growth_8cpp.html index 7239df6da02d..204f7eedbd26 100644 --- a/_n_l_energy_growth_8cpp.html +++ b/_n_l_energy_growth_8cpp.html @@ -129,7 +129,7 @@

Namespaces

-

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Wednesday, Jul 10, 2024 using Doxygen and m.css. Contact us via GitHub.

+

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Thursday, Jul 11, 2024 using Doxygen and m.css. Contact us via GitHub.

diff --git a/_n_l_energy_growth_8hpp.html b/_n_l_energy_growth_8hpp.html index 03699cc04b00..20a26fc005a4 100644 --- a/_n_l_energy_growth_8hpp.html +++ b/_n_l_energy_growth_8hpp.html @@ -139,7 +139,7 @@

Classes

-

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Wednesday, Jul 10, 2024 using Doxygen and m.css. Contact us via GitHub.

+

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Thursday, Jul 11, 2024 using Doxygen and m.css. Contact us via GitHub.

diff --git a/_netgen_mesh_reader_8cpp.html b/_netgen_mesh_reader_8cpp.html index cd2784a61fe3..baac802e2bbd 100644 --- a/_netgen_mesh_reader_8cpp.html +++ b/_netgen_mesh_reader_8cpp.html @@ -111,7 +111,7 @@

-

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Wednesday, Jul 10, 2024 using Doxygen and m.css. Contact us via GitHub.

+

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Thursday, Jul 11, 2024 using Doxygen and m.css. Contact us via GitHub.

diff --git a/_netgen_mesh_reader_8hpp.html b/_netgen_mesh_reader_8hpp.html index bb43c9454d7f..b255838599bc 100644 --- a/_netgen_mesh_reader_8hpp.html +++ b/_netgen_mesh_reader_8hpp.html @@ -139,7 +139,7 @@

Classes

-

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Wednesday, Jul 10, 2024 using Doxygen and m.css. Contact us via GitHub.

+

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Thursday, Jul 11, 2024 using Doxygen and m.css. Contact us via GitHub.

diff --git a/_netgen_mesh_writer_8cpp.html b/_netgen_mesh_writer_8cpp.html index 63f30f54b428..deb2c959bd18 100644 --- a/_netgen_mesh_writer_8cpp.html +++ b/_netgen_mesh_writer_8cpp.html @@ -111,7 +111,7 @@

-

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Wednesday, Jul 10, 2024 using Doxygen and m.css. Contact us via GitHub.

+

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Thursday, Jul 11, 2024 using Doxygen and m.css. Contact us via GitHub.

diff --git a/_netgen_mesh_writer_8hpp.html b/_netgen_mesh_writer_8hpp.html index d3a042d70b8b..55750c092b49 100644 --- a/_netgen_mesh_writer_8hpp.html +++ b/_netgen_mesh_writer_8hpp.html @@ -139,7 +139,7 @@

Classes

-

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Wednesday, Jul 10, 2024 using Doxygen and m.css. Contact us via GitHub.

+

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Thursday, Jul 11, 2024 using Doxygen and m.css. Contact us via GitHub.

diff --git a/_no_warning_2_factory_8hpp.html b/_no_warning_2_factory_8hpp.html index 96f8a44d5911..ff65019e7ebc 100644 --- a/_no_warning_2_factory_8hpp.html +++ b/_no_warning_2_factory_8hpp.html @@ -111,7 +111,7 @@

-

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Wednesday, Jul 10, 2024 using Doxygen and m.css. Contact us via GitHub.

+

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Thursday, Jul 11, 2024 using Doxygen and m.css. Contact us via GitHub.

diff --git a/_node_b_c_8cpp.html b/_node_b_c_8cpp.html index d37c5f4eded0..9848a26b3258 100644 --- a/_node_b_c_8cpp.html +++ b/_node_b_c_8cpp.html @@ -129,7 +129,7 @@

Namespaces

-

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Wednesday, Jul 10, 2024 using Doxygen and m.css. Contact us via GitHub.

+

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Thursday, Jul 11, 2024 using Doxygen and m.css. Contact us via GitHub.

diff --git a/_node_b_c_8hpp.html b/_node_b_c_8hpp.html index 038057872a01..5b7c56dbf1cc 100644 --- a/_node_b_c_8hpp.html +++ b/_node_b_c_8hpp.html @@ -129,7 +129,7 @@

Namespaces

-

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Wednesday, Jul 10, 2024 using Doxygen and m.css. Contact us via GitHub.

+

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Thursday, Jul 11, 2024 using Doxygen and m.css. Contact us via GitHub.

diff --git a/_node_diagnostics_8cpp.html b/_node_diagnostics_8cpp.html index 00cf0bcf237f..f70804e3ecbe 100644 --- a/_node_diagnostics_8cpp.html +++ b/_node_diagnostics_8cpp.html @@ -129,7 +129,7 @@

Namespaces

-

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Wednesday, Jul 10, 2024 using Doxygen and m.css. Contact us via GitHub.

+

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Thursday, Jul 11, 2024 using Doxygen and m.css. Contact us via GitHub.

diff --git a/_node_diagnostics_8hpp.html b/_node_diagnostics_8hpp.html index 1847c9ed042c..32456cd9bd9d 100644 --- a/_node_diagnostics_8hpp.html +++ b/_node_diagnostics_8hpp.html @@ -139,7 +139,7 @@

Classes

-

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Wednesday, Jul 10, 2024 using Doxygen and m.css. Contact us via GitHub.

+

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Thursday, Jul 11, 2024 using Doxygen and m.css. Contact us via GitHub.

diff --git a/_omega__h___mesh_reader_8cpp.html b/_omega__h___mesh_reader_8cpp.html index b6ce64637784..048a4c0d1de4 100644 --- a/_omega__h___mesh_reader_8cpp.html +++ b/_omega__h___mesh_reader_8cpp.html @@ -111,7 +111,7 @@

-

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Wednesday, Jul 10, 2024 using Doxygen and m.css. Contact us via GitHub.

+

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Thursday, Jul 11, 2024 using Doxygen and m.css. Contact us via GitHub.

diff --git a/_omega__h___mesh_reader_8hpp.html b/_omega__h___mesh_reader_8hpp.html index 8ee5bdc17899..06d74e30dd95 100644 --- a/_omega__h___mesh_reader_8hpp.html +++ b/_omega__h___mesh_reader_8hpp.html @@ -139,7 +139,7 @@

Classes

-

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Wednesday, Jul 10, 2024 using Doxygen and m.css. Contact us via GitHub.

+

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Thursday, Jul 11, 2024 using Doxygen and m.css. Contact us via GitHub.

diff --git a/_omega__h__file_8hpp.html b/_omega__h__file_8hpp.html index 4493dce7aa53..8c20ac35ec37 100644 --- a/_omega__h__file_8hpp.html +++ b/_omega__h__file_8hpp.html @@ -111,7 +111,7 @@

-

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Wednesday, Jul 10, 2024 using Doxygen and m.css. Contact us via GitHub.

+

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Thursday, Jul 11, 2024 using Doxygen and m.css. Contact us via GitHub.

diff --git a/_out_var_8hpp.html b/_out_var_8hpp.html index 5d03b50954a3..b66df869d6ad 100644 --- a/_out_var_8hpp.html +++ b/_out_var_8hpp.html @@ -141,7 +141,7 @@

Classes

-

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Wednesday, Jul 10, 2024 using Doxygen and m.css. Contact us via GitHub.

+

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Thursday, Jul 11, 2024 using Doxygen and m.css. Contact us via GitHub.

diff --git a/_overset_f_e_8cpp.html b/_overset_f_e_8cpp.html index 651df2be2221..891bae7d4ec0 100644 --- a/_overset_f_e_8cpp.html +++ b/_overset_f_e_8cpp.html @@ -129,7 +129,7 @@

Namespaces

-

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Wednesday, Jul 10, 2024 using Doxygen and m.css. Contact us via GitHub.

+

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Thursday, Jul 11, 2024 using Doxygen and m.css. Contact us via GitHub.

diff --git a/_overset_f_e_8hpp.html b/_overset_f_e_8hpp.html index d33cf1dfedc8..77f1fc12f7e5 100644 --- a/_overset_f_e_8hpp.html +++ b/_overset_f_e_8hpp.html @@ -139,7 +139,7 @@

Classes

-

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Wednesday, Jul 10, 2024 using Doxygen and m.css. Contact us via GitHub.

+

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Thursday, Jul 11, 2024 using Doxygen and m.css. Contact us via GitHub.

diff --git a/_p_d_e_2_comp_flow_2_physics_2_d_g_8hpp.html b/_p_d_e_2_comp_flow_2_physics_2_d_g_8hpp.html index 2f03001724b2..266a3434bbbf 100644 --- a/_p_d_e_2_comp_flow_2_physics_2_d_g_8hpp.html +++ b/_p_d_e_2_comp_flow_2_physics_2_d_g_8hpp.html @@ -131,7 +131,7 @@

Namespaces

-

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Wednesday, Jul 10, 2024 using Doxygen and m.css. Contact us via GitHub.

+

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Thursday, Jul 11, 2024 using Doxygen and m.css. Contact us via GitHub.

diff --git a/_p_d_e_2_comp_flow_2_problem_2_field_output_8cpp.html b/_p_d_e_2_comp_flow_2_problem_2_field_output_8cpp.html index 39ba276fe2ae..effff1b1a680 100644 --- a/_p_d_e_2_comp_flow_2_problem_2_field_output_8cpp.html +++ b/_p_d_e_2_comp_flow_2_problem_2_field_output_8cpp.html @@ -129,7 +129,7 @@

Namespaces

-

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Wednesday, Jul 10, 2024 using Doxygen and m.css. Contact us via GitHub.

+

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Thursday, Jul 11, 2024 using Doxygen and m.css. Contact us via GitHub.

diff --git a/_p_d_e_2_comp_flow_2_problem_2_field_output_8hpp.html b/_p_d_e_2_comp_flow_2_problem_2_field_output_8hpp.html index cd6e0e39195a..e2a315c72c27 100644 --- a/_p_d_e_2_comp_flow_2_problem_2_field_output_8hpp.html +++ b/_p_d_e_2_comp_flow_2_problem_2_field_output_8hpp.html @@ -129,7 +129,7 @@

Namespaces

-

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Wednesday, Jul 10, 2024 using Doxygen and m.css. Contact us via GitHub.

+

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Thursday, Jul 11, 2024 using Doxygen and m.css. Contact us via GitHub.

diff --git a/_p_d_e_2_comp_flow_2_problem_8hpp.html b/_p_d_e_2_comp_flow_2_problem_8hpp.html index 28f67cd49c92..ee84499f8750 100644 --- a/_p_d_e_2_comp_flow_2_problem_8hpp.html +++ b/_p_d_e_2_comp_flow_2_problem_8hpp.html @@ -131,7 +131,7 @@

Namespaces

-

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Wednesday, Jul 10, 2024 using Doxygen and m.css. Contact us via GitHub.

+

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Thursday, Jul 11, 2024 using Doxygen and m.css. Contact us via GitHub.

diff --git a/_p_d_e_2_limiter_8hpp.html b/_p_d_e_2_limiter_8hpp.html index 58ddaee72d0c..d922b5f81da1 100644 --- a/_p_d_e_2_limiter_8hpp.html +++ b/_p_d_e_2_limiter_8hpp.html @@ -129,7 +129,7 @@

Namespaces

-

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Wednesday, Jul 10, 2024 using Doxygen and m.css. Contact us via GitHub.

+

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Thursday, Jul 11, 2024 using Doxygen and m.css. Contact us via GitHub.

diff --git a/_p_d_e_2_multi_mat_2_physics_2_d_g_8hpp.html b/_p_d_e_2_multi_mat_2_physics_2_d_g_8hpp.html index 0836eb9164a9..504e998b650b 100644 --- a/_p_d_e_2_multi_mat_2_physics_2_d_g_8hpp.html +++ b/_p_d_e_2_multi_mat_2_physics_2_d_g_8hpp.html @@ -131,7 +131,7 @@

Namespaces

-

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Wednesday, Jul 10, 2024 using Doxygen and m.css. Contact us via GitHub.

+

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Thursday, Jul 11, 2024 using Doxygen and m.css. Contact us via GitHub.

diff --git a/_p_d_e_2_multi_mat_2_physics_2_f_v_8hpp.html b/_p_d_e_2_multi_mat_2_physics_2_f_v_8hpp.html index 0b0d3fdc1dbc..8d3737275ff9 100644 --- a/_p_d_e_2_multi_mat_2_physics_2_f_v_8hpp.html +++ b/_p_d_e_2_multi_mat_2_physics_2_f_v_8hpp.html @@ -131,7 +131,7 @@

Namespaces

-

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Wednesday, Jul 10, 2024 using Doxygen and m.css. Contact us via GitHub.

+

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Thursday, Jul 11, 2024 using Doxygen and m.css. Contact us via GitHub.

diff --git a/_p_d_e_2_multi_mat_2_problem_2_field_output_8cpp.html b/_p_d_e_2_multi_mat_2_problem_2_field_output_8cpp.html index 7b3f1b72c962..a6a1e0b5669d 100644 --- a/_p_d_e_2_multi_mat_2_problem_2_field_output_8cpp.html +++ b/_p_d_e_2_multi_mat_2_problem_2_field_output_8cpp.html @@ -129,7 +129,7 @@

Namespaces

-

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Wednesday, Jul 10, 2024 using Doxygen and m.css. Contact us via GitHub.

+

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Thursday, Jul 11, 2024 using Doxygen and m.css. Contact us via GitHub.

diff --git a/_p_d_e_2_multi_mat_2_problem_2_field_output_8hpp.html b/_p_d_e_2_multi_mat_2_problem_2_field_output_8hpp.html index fb86df84f2bf..806602bd3a4d 100644 --- a/_p_d_e_2_multi_mat_2_problem_2_field_output_8hpp.html +++ b/_p_d_e_2_multi_mat_2_problem_2_field_output_8hpp.html @@ -129,7 +129,7 @@

Namespaces

-

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Wednesday, Jul 10, 2024 using Doxygen and m.css. Contact us via GitHub.

+

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Thursday, Jul 11, 2024 using Doxygen and m.css. Contact us via GitHub.

diff --git a/_p_d_e_2_multi_mat_2_problem_8hpp.html b/_p_d_e_2_multi_mat_2_problem_8hpp.html index d7d376b7be5f..825381178f09 100644 --- a/_p_d_e_2_multi_mat_2_problem_8hpp.html +++ b/_p_d_e_2_multi_mat_2_problem_8hpp.html @@ -131,7 +131,7 @@

Namespaces

-

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Wednesday, Jul 10, 2024 using Doxygen and m.css. Contact us via GitHub.

+

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Thursday, Jul 11, 2024 using Doxygen and m.css. Contact us via GitHub.

diff --git a/_p_d_e_2_transport_2_physics_2_d_g_8hpp.html b/_p_d_e_2_transport_2_physics_2_d_g_8hpp.html index 5df0f9d9160c..34b8e693f1bb 100644 --- a/_p_d_e_2_transport_2_physics_2_d_g_8hpp.html +++ b/_p_d_e_2_transport_2_physics_2_d_g_8hpp.html @@ -131,7 +131,7 @@

Namespaces

-

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Wednesday, Jul 10, 2024 using Doxygen and m.css. Contact us via GitHub.

+

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Thursday, Jul 11, 2024 using Doxygen and m.css. Contact us via GitHub.

diff --git a/_p_d_e_2_transport_2_problem_8hpp.html b/_p_d_e_2_transport_2_problem_8hpp.html index a9516dd89869..2210e821a75c 100644 --- a/_p_d_e_2_transport_2_problem_8hpp.html +++ b/_p_d_e_2_transport_2_problem_8hpp.html @@ -131,7 +131,7 @@

Namespaces

-

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Wednesday, Jul 10, 2024 using Doxygen and m.css. Contact us via GitHub.

+

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Thursday, Jul 11, 2024 using Doxygen and m.css. Contact us via GitHub.

diff --git a/_p_d_e_8hpp.html b/_p_d_e_8hpp.html index a317b909aef5..076bba61c194 100644 --- a/_p_d_e_8hpp.html +++ b/_p_d_e_8hpp.html @@ -141,7 +141,7 @@

Classes

-

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Wednesday, Jul 10, 2024 using Doxygen and m.css. Contact us via GitHub.

+

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Thursday, Jul 11, 2024 using Doxygen and m.css. Contact us via GitHub.

diff --git a/_p_d_e_factory_8hpp.html b/_p_d_e_factory_8hpp.html index 6c5c18afe50b..e39f66fab9f4 100644 --- a/_p_d_e_factory_8hpp.html +++ b/_p_d_e_factory_8hpp.html @@ -155,7 +155,7 @@

Classes

-

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Wednesday, Jul 10, 2024 using Doxygen and m.css. Contact us via GitHub.

+

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Thursday, Jul 11, 2024 using Doxygen and m.css. Contact us via GitHub.

diff --git a/_p_d_e_stack_8cpp.html b/_p_d_e_stack_8cpp.html index fdce87a0d852..0aa3bdc19a68 100644 --- a/_p_d_e_stack_8cpp.html +++ b/_p_d_e_stack_8cpp.html @@ -111,7 +111,7 @@

-

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Wednesday, Jul 10, 2024 using Doxygen and m.css. Contact us via GitHub.

+

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Thursday, Jul 11, 2024 using Doxygen and m.css. Contact us via GitHub.

diff --git a/_p_d_e_stack_8hpp.html b/_p_d_e_stack_8hpp.html index 42b2f9175a07..2bd679888b8f 100644 --- a/_p_d_e_stack_8hpp.html +++ b/_p_d_e_stack_8hpp.html @@ -139,7 +139,7 @@

Classes

-

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Wednesday, Jul 10, 2024 using Doxygen and m.css. Contact us via GitHub.

+

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Thursday, Jul 11, 2024 using Doxygen and m.css. Contact us via GitHub.

diff --git a/_p_d_f_centering_8hpp.html b/_p_d_f_centering_8hpp.html index c9bef98093a1..a0b09cae4d97 100644 --- a/_p_d_f_centering_8hpp.html +++ b/_p_d_f_centering_8hpp.html @@ -139,7 +139,7 @@

Classes

-

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Wednesday, Jul 10, 2024 using Doxygen and m.css. Contact us via GitHub.

+

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Thursday, Jul 11, 2024 using Doxygen and m.css. Contact us via GitHub.

diff --git a/_p_d_f_reducer_8cpp.html b/_p_d_f_reducer_8cpp.html index 52fccecf31bc..e4b3d4a00764 100644 --- a/_p_d_f_reducer_8cpp.html +++ b/_p_d_f_reducer_8cpp.html @@ -129,7 +129,7 @@

Namespaces

-

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Wednesday, Jul 10, 2024 using Doxygen and m.css. Contact us via GitHub.

+

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Thursday, Jul 11, 2024 using Doxygen and m.css. Contact us via GitHub.

diff --git a/_p_d_f_reducer_8hpp.html b/_p_d_f_reducer_8hpp.html index 4901027f62d7..da4668259489 100644 --- a/_p_d_f_reducer_8hpp.html +++ b/_p_d_f_reducer_8hpp.html @@ -129,7 +129,7 @@

Namespaces

-

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Wednesday, Jul 10, 2024 using Doxygen and m.css. Contact us via GitHub.

+

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Thursday, Jul 11, 2024 using Doxygen and m.css. Contact us via GitHub.

diff --git a/_p_d_f_writer_8cpp.html b/_p_d_f_writer_8cpp.html index 344318031bad..8079e9617bb7 100644 --- a/_p_d_f_writer_8cpp.html +++ b/_p_d_f_writer_8cpp.html @@ -111,7 +111,7 @@

-

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Wednesday, Jul 10, 2024 using Doxygen and m.css. Contact us via GitHub.

+

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Thursday, Jul 11, 2024 using Doxygen and m.css. Contact us via GitHub.

diff --git a/_p_d_f_writer_8hpp.html b/_p_d_f_writer_8hpp.html index 759f40f003ea..32b5941495cf 100644 --- a/_p_d_f_writer_8hpp.html +++ b/_p_d_f_writer_8hpp.html @@ -139,7 +139,7 @@

Classes

-

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Wednesday, Jul 10, 2024 using Doxygen and m.css. Contact us via GitHub.

+

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Thursday, Jul 11, 2024 using Doxygen and m.css. Contact us via GitHub.

diff --git a/_p_u_p_a_m_r_8cpp.html b/_p_u_p_a_m_r_8cpp.html index 495acfe9336d..b4fc225430b1 100644 --- a/_p_u_p_a_m_r_8cpp.html +++ b/_p_u_p_a_m_r_8cpp.html @@ -111,7 +111,7 @@

-

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Wednesday, Jul 10, 2024 using Doxygen and m.css. Contact us via GitHub.

+

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Thursday, Jul 11, 2024 using Doxygen and m.css. Contact us via GitHub.

diff --git a/_p_u_p_a_m_r_8hpp.html b/_p_u_p_a_m_r_8hpp.html index 2b0ce06952e0..5f700334125e 100644 --- a/_p_u_p_a_m_r_8hpp.html +++ b/_p_u_p_a_m_r_8hpp.html @@ -129,7 +129,7 @@

Namespaces

-

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Wednesday, Jul 10, 2024 using Doxygen and m.css. Contact us via GitHub.

+

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Thursday, Jul 11, 2024 using Doxygen and m.css. Contact us via GitHub.

diff --git a/_p_u_p_util_8hpp.html b/_p_u_p_util_8hpp.html index 2c1f6ae5dcb1..1f3998013fc8 100644 --- a/_p_u_p_util_8hpp.html +++ b/_p_u_p_util_8hpp.html @@ -129,7 +129,7 @@

Namespaces

-

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Wednesday, Jul 10, 2024 using Doxygen and m.css. Contact us via GitHub.

+

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Thursday, Jul 11, 2024 using Doxygen and m.css. Contact us via GitHub.

diff --git a/_particles_8hpp.html b/_particles_8hpp.html index 96d75cba15f7..021214e011df 100644 --- a/_particles_8hpp.html +++ b/_particles_8hpp.html @@ -129,7 +129,7 @@

Namespaces

-

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Wednesday, Jul 10, 2024 using Doxygen and m.css. Contact us via GitHub.

+

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Thursday, Jul 11, 2024 using Doxygen and m.css. Contact us via GitHub.

diff --git a/_partitioner_8cpp.html b/_partitioner_8cpp.html index 22879d0bdb98..5baf99ff41ac 100644 --- a/_partitioner_8cpp.html +++ b/_partitioner_8cpp.html @@ -129,7 +129,7 @@

Namespaces

-

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Wednesday, Jul 10, 2024 using Doxygen and m.css. Contact us via GitHub.

+

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Thursday, Jul 11, 2024 using Doxygen and m.css. Contact us via GitHub.

diff --git a/_partitioner_8hpp.html b/_partitioner_8hpp.html index e8e3529cb17d..141517d33d11 100644 --- a/_partitioner_8hpp.html +++ b/_partitioner_8hpp.html @@ -139,7 +139,7 @@

Classes

-

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Wednesday, Jul 10, 2024 using Doxygen and m.css. Contact us via GitHub.

+

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Thursday, Jul 11, 2024 using Doxygen and m.css. Contact us via GitHub.

diff --git a/_partitioning_algorithm_8hpp.html b/_partitioning_algorithm_8hpp.html index 2a9403fed1c5..88c1e0625d06 100644 --- a/_partitioning_algorithm_8hpp.html +++ b/_partitioning_algorithm_8hpp.html @@ -139,7 +139,7 @@

Classes

-

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Wednesday, Jul 10, 2024 using Doxygen and m.css. Contact us via GitHub.

+

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Thursday, Jul 11, 2024 using Doxygen and m.css. Contact us via GitHub.

diff --git a/_physics_8hpp.html b/_physics_8hpp.html index a570c4bab268..b77babc1e676 100644 --- a/_physics_8hpp.html +++ b/_physics_8hpp.html @@ -141,7 +141,7 @@

Classes

-

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Wednesday, Jul 10, 2024 using Doxygen and m.css. Contact us via GitHub.

+

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Thursday, Jul 11, 2024 using Doxygen and m.css. Contact us via GitHub.

diff --git a/_pref_indicator_8cpp.html b/_pref_indicator_8cpp.html index beaf20a86c48..dc3e9c9455e6 100644 --- a/_pref_indicator_8cpp.html +++ b/_pref_indicator_8cpp.html @@ -129,7 +129,7 @@

Namespaces

-

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Wednesday, Jul 10, 2024 using Doxygen and m.css. Contact us via GitHub.

+

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Thursday, Jul 11, 2024 using Doxygen and m.css. Contact us via GitHub.

diff --git a/_print_8hpp.html b/_print_8hpp.html index b86b2058b070..3555fbc4facc 100644 --- a/_print_8hpp.html +++ b/_print_8hpp.html @@ -139,7 +139,7 @@

Classes

-

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Wednesday, Jul 10, 2024 using Doxygen and m.css. Contact us via GitHub.

+

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Thursday, Jul 11, 2024 using Doxygen and m.css. Contact us via GitHub.

diff --git a/_print_util_8cpp.html b/_print_util_8cpp.html index 93a4bdf5ba2d..b2aeac743f4e 100644 --- a/_print_util_8cpp.html +++ b/_print_util_8cpp.html @@ -111,7 +111,7 @@

-

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Wednesday, Jul 10, 2024 using Doxygen and m.css. Contact us via GitHub.

+

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Thursday, Jul 11, 2024 using Doxygen and m.css. Contact us via GitHub.

diff --git a/_print_util_8hpp.html b/_print_util_8hpp.html index 78909890fd4a..51921981298c 100644 --- a/_print_util_8hpp.html +++ b/_print_util_8hpp.html @@ -129,7 +129,7 @@

Namespaces

-

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Wednesday, Jul 10, 2024 using Doxygen and m.css. Contact us via GitHub.

+

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Thursday, Jul 11, 2024 using Doxygen and m.css. Contact us via GitHub.

diff --git a/_process_exception_8cpp.html b/_process_exception_8cpp.html index 52ff6bfc6966..c6bfa450ecbc 100644 --- a/_process_exception_8cpp.html +++ b/_process_exception_8cpp.html @@ -129,7 +129,7 @@

Namespaces

-

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Wednesday, Jul 10, 2024 using Doxygen and m.css. Contact us via GitHub.

+

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Thursday, Jul 11, 2024 using Doxygen and m.css. Contact us via GitHub.

diff --git a/_process_exception_8hpp.html b/_process_exception_8hpp.html index 234f45f120e0..d8c9c51b6612 100644 --- a/_process_exception_8hpp.html +++ b/_process_exception_8hpp.html @@ -129,7 +129,7 @@

Namespaces

-

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Wednesday, Jul 10, 2024 using Doxygen and m.css. Contact us via GitHub.

+

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Thursday, Jul 11, 2024 using Doxygen and m.css. Contact us via GitHub.

diff --git a/_progress_8hpp.html b/_progress_8hpp.html index 05ce609bf02c..57e27717448d 100644 --- a/_progress_8hpp.html +++ b/_progress_8hpp.html @@ -140,7 +140,7 @@

Classes

-

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Wednesday, Jul 10, 2024 using Doxygen and m.css. Contact us via GitHub.

+

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Thursday, Jul 11, 2024 using Doxygen and m.css. Contact us via GitHub.

diff --git a/_q_endian_8hpp.html b/_q_endian_8hpp.html index f95103de5cfa..47cfc9518ba8 100644 --- a/_q_endian_8hpp.html +++ b/_q_endian_8hpp.html @@ -129,7 +129,7 @@

Namespaces

-

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Wednesday, Jul 10, 2024 using Doxygen and m.css. Contact us via GitHub.

+

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Thursday, Jul 11, 2024 using Doxygen and m.css. Contact us via GitHub.

diff --git a/_quadrature_8cpp.html b/_quadrature_8cpp.html index b294ea4a1a99..bca19a7013cb 100644 --- a/_quadrature_8cpp.html +++ b/_quadrature_8cpp.html @@ -111,7 +111,7 @@

-

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Wednesday, Jul 10, 2024 using Doxygen and m.css. Contact us via GitHub.

+

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Thursday, Jul 11, 2024 using Doxygen and m.css. Contact us via GitHub.

diff --git a/_quadrature_8hpp.html b/_quadrature_8hpp.html index 2242f07d83b3..b946a4b9cda8 100644 --- a/_quadrature_8hpp.html +++ b/_quadrature_8hpp.html @@ -129,7 +129,7 @@

Namespaces

-

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Wednesday, Jul 10, 2024 using Doxygen and m.css. Contact us via GitHub.

+

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Thursday, Jul 11, 2024 using Doxygen and m.css. Contact us via GitHub.

diff --git a/_quiet_cerr_8cpp.html b/_quiet_cerr_8cpp.html index b68027d2ebe6..3249c98c9498 100644 --- a/_quiet_cerr_8cpp.html +++ b/_quiet_cerr_8cpp.html @@ -129,7 +129,7 @@

Namespaces

-

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Wednesday, Jul 10, 2024 using Doxygen and m.css. Contact us via GitHub.

+

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Thursday, Jul 11, 2024 using Doxygen and m.css. Contact us via GitHub.

diff --git a/_quiet_cerr_8hpp.html b/_quiet_cerr_8hpp.html index 9546a1d1fc9c..cac021bcdc3f 100644 --- a/_quiet_cerr_8hpp.html +++ b/_quiet_cerr_8hpp.html @@ -139,7 +139,7 @@

Classes

-

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Wednesday, Jul 10, 2024 using Doxygen and m.css. Contact us via GitHub.

+

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Thursday, Jul 11, 2024 using Doxygen and m.css. Contact us via GitHub.

diff --git a/_r_d_g_f_l_o_mesh_reader_8cpp.html b/_r_d_g_f_l_o_mesh_reader_8cpp.html index fa3445b19042..dfd392766abd 100644 --- a/_r_d_g_f_l_o_mesh_reader_8cpp.html +++ b/_r_d_g_f_l_o_mesh_reader_8cpp.html @@ -111,7 +111,7 @@

-

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Wednesday, Jul 10, 2024 using Doxygen and m.css. Contact us via GitHub.

+

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Thursday, Jul 11, 2024 using Doxygen and m.css. Contact us via GitHub.

diff --git a/_r_d_g_f_l_o_mesh_reader_8hpp.html b/_r_d_g_f_l_o_mesh_reader_8hpp.html index d8d23fa1b652..238c296445c2 100644 --- a/_r_d_g_f_l_o_mesh_reader_8hpp.html +++ b/_r_d_g_f_l_o_mesh_reader_8hpp.html @@ -139,7 +139,7 @@

Classes

-

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Wednesday, Jul 10, 2024 using Doxygen and m.css. Contact us via GitHub.

+

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Thursday, Jul 11, 2024 using Doxygen and m.css. Contact us via GitHub.

diff --git a/_rayleigh_taylor_8cpp.html b/_rayleigh_taylor_8cpp.html index f677e316fa0a..4020ffaa332a 100644 --- a/_rayleigh_taylor_8cpp.html +++ b/_rayleigh_taylor_8cpp.html @@ -129,7 +129,7 @@

Namespaces

-

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Wednesday, Jul 10, 2024 using Doxygen and m.css. Contact us via GitHub.

+

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Thursday, Jul 11, 2024 using Doxygen and m.css. Contact us via GitHub.

diff --git a/_rayleigh_taylor_8hpp.html b/_rayleigh_taylor_8hpp.html index 1eba0a9eef1b..4a027cb91361 100644 --- a/_rayleigh_taylor_8hpp.html +++ b/_rayleigh_taylor_8hpp.html @@ -139,7 +139,7 @@

Classes

-

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Wednesday, Jul 10, 2024 using Doxygen and m.css. Contact us via GitHub.

+

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Thursday, Jul 11, 2024 using Doxygen and m.css. Contact us via GitHub.

diff --git a/_reader_8cpp.html b/_reader_8cpp.html index 0add101b8d12..80f4b2edd107 100644 --- a/_reader_8cpp.html +++ b/_reader_8cpp.html @@ -111,7 +111,7 @@

-

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Wednesday, Jul 10, 2024 using Doxygen and m.css. Contact us via GitHub.

+

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Thursday, Jul 11, 2024 using Doxygen and m.css. Contact us via GitHub.

diff --git a/_reader_8hpp.html b/_reader_8hpp.html index 8a203a4a1990..4105e5fdea2b 100644 --- a/_reader_8hpp.html +++ b/_reader_8hpp.html @@ -139,7 +139,7 @@

Classes

-

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Wednesday, Jul 10, 2024 using Doxygen and m.css. Contact us via GitHub.

+

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Thursday, Jul 11, 2024 using Doxygen and m.css. Contact us via GitHub.

diff --git a/_reconstruction_8cpp.html b/_reconstruction_8cpp.html index 604eaa125e49..3a5b7e507193 100644 --- a/_reconstruction_8cpp.html +++ b/_reconstruction_8cpp.html @@ -131,7 +131,7 @@

Namespaces

-

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Wednesday, Jul 10, 2024 using Doxygen and m.css. Contact us via GitHub.

+

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Thursday, Jul 11, 2024 using Doxygen and m.css. Contact us via GitHub.

diff --git a/_reconstruction_8hpp.html b/_reconstruction_8hpp.html index 8972b20bc034..f00a2eec7be8 100644 --- a/_reconstruction_8hpp.html +++ b/_reconstruction_8hpp.html @@ -129,7 +129,7 @@

Namespaces

-

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Wednesday, Jul 10, 2024 using Doxygen and m.css. Contact us via GitHub.

+

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Thursday, Jul 11, 2024 using Doxygen and m.css. Contact us via GitHub.

diff --git a/_refiner_8cpp.html b/_refiner_8cpp.html index 09a2e385f576..bdf27fcb86e1 100644 --- a/_refiner_8cpp.html +++ b/_refiner_8cpp.html @@ -129,7 +129,7 @@

Namespaces

-

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Wednesday, Jul 10, 2024 using Doxygen and m.css. Contact us via GitHub.

+

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Thursday, Jul 11, 2024 using Doxygen and m.css. Contact us via GitHub.

diff --git a/_refiner_8hpp.html b/_refiner_8hpp.html index 0205c7dc401a..f4aa0cd243d9 100644 --- a/_refiner_8hpp.html +++ b/_refiner_8hpp.html @@ -139,7 +139,7 @@

Classes

-

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Wednesday, Jul 10, 2024 using Doxygen and m.css. Contact us via GitHub.

+

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Thursday, Jul 11, 2024 using Doxygen and m.css. Contact us via GitHub.

diff --git a/_reorder_8cpp.html b/_reorder_8cpp.html index fc55498c95a2..5d169b0d07af 100644 --- a/_reorder_8cpp.html +++ b/_reorder_8cpp.html @@ -129,7 +129,7 @@

Namespaces

-

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Wednesday, Jul 10, 2024 using Doxygen and m.css. Contact us via GitHub.

+

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Thursday, Jul 11, 2024 using Doxygen and m.css. Contact us via GitHub.

diff --git a/_reorder_8hpp.html b/_reorder_8hpp.html index 53892d399893..6b57aa6fb797 100644 --- a/_reorder_8hpp.html +++ b/_reorder_8hpp.html @@ -129,7 +129,7 @@

Namespaces

-

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Wednesday, Jul 10, 2024 using Doxygen and m.css. Contact us via GitHub.

+

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Thursday, Jul 11, 2024 using Doxygen and m.css. Contact us via GitHub.

diff --git a/_richtmyer_meshkov_8cpp.html b/_richtmyer_meshkov_8cpp.html index 4de421a80f78..d32363d09a9a 100644 --- a/_richtmyer_meshkov_8cpp.html +++ b/_richtmyer_meshkov_8cpp.html @@ -129,7 +129,7 @@

Namespaces

-

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Wednesday, Jul 10, 2024 using Doxygen and m.css. Contact us via GitHub.

+

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Thursday, Jul 11, 2024 using Doxygen and m.css. Contact us via GitHub.

diff --git a/_richtmyer_meshkov_8hpp.html b/_richtmyer_meshkov_8hpp.html index 5c072a24d114..a723fdb97040 100644 --- a/_richtmyer_meshkov_8hpp.html +++ b/_richtmyer_meshkov_8hpp.html @@ -139,7 +139,7 @@

Classes

-

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Wednesday, Jul 10, 2024 using Doxygen and m.css. Contact us via GitHub.

+

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Thursday, Jul 11, 2024 using Doxygen and m.css. Contact us via GitHub.

diff --git a/_rotated_sod_shocktube_8cpp.html b/_rotated_sod_shocktube_8cpp.html index b2f1269ea9c5..497476876614 100644 --- a/_rotated_sod_shocktube_8cpp.html +++ b/_rotated_sod_shocktube_8cpp.html @@ -111,7 +111,7 @@

-

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Wednesday, Jul 10, 2024 using Doxygen and m.css. Contact us via GitHub.

+

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Thursday, Jul 11, 2024 using Doxygen and m.css. Contact us via GitHub.

diff --git a/_rotated_sod_shocktube_8hpp.html b/_rotated_sod_shocktube_8hpp.html index dbd12c0c822b..a65eda34222e 100644 --- a/_rotated_sod_shocktube_8hpp.html +++ b/_rotated_sod_shocktube_8hpp.html @@ -139,7 +139,7 @@

Classes

-

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Wednesday, Jul 10, 2024 using Doxygen and m.css. Contact us via GitHub.

+

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Thursday, Jul 11, 2024 using Doxygen and m.css. Contact us via GitHub.

diff --git a/_rusanov_8hpp.html b/_rusanov_8hpp.html index 40d7f1b355be..6a58aae3cf16 100644 --- a/_rusanov_8hpp.html +++ b/_rusanov_8hpp.html @@ -139,7 +139,7 @@

Classes

-

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Wednesday, Jul 10, 2024 using Doxygen and m.css. Contact us via GitHub.

+

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Thursday, Jul 11, 2024 using Doxygen and m.css. Contact us via GitHub.

diff --git a/_s_t_l_mesh_8cpp.html b/_s_t_l_mesh_8cpp.html index 559c7cdfe6dd..a231fd683b6e 100644 --- a/_s_t_l_mesh_8cpp.html +++ b/_s_t_l_mesh_8cpp.html @@ -111,7 +111,7 @@

-

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Wednesday, Jul 10, 2024 using Doxygen and m.css. Contact us via GitHub.

+

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Thursday, Jul 11, 2024 using Doxygen and m.css. Contact us via GitHub.

diff --git a/_s_t_l_mesh_8hpp.html b/_s_t_l_mesh_8hpp.html index 11224ddfb049..01fac5184496 100644 --- a/_s_t_l_mesh_8hpp.html +++ b/_s_t_l_mesh_8hpp.html @@ -139,7 +139,7 @@

Classes

-

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Wednesday, Jul 10, 2024 using Doxygen and m.css. Contact us via GitHub.

+

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Thursday, Jul 11, 2024 using Doxygen and m.css. Contact us via GitHub.

diff --git a/_s_t_l_txt_mesh_reader_8cpp.html b/_s_t_l_txt_mesh_reader_8cpp.html index 665fc37267c3..e37655f2a27b 100644 --- a/_s_t_l_txt_mesh_reader_8cpp.html +++ b/_s_t_l_txt_mesh_reader_8cpp.html @@ -111,7 +111,7 @@

-

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Wednesday, Jul 10, 2024 using Doxygen and m.css. Contact us via GitHub.

+

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Thursday, Jul 11, 2024 using Doxygen and m.css. Contact us via GitHub.

diff --git a/_s_t_l_txt_mesh_reader_8hpp.html b/_s_t_l_txt_mesh_reader_8hpp.html index e63f4864284a..4f8962c3226e 100644 --- a/_s_t_l_txt_mesh_reader_8hpp.html +++ b/_s_t_l_txt_mesh_reader_8hpp.html @@ -139,7 +139,7 @@

Classes

-

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Wednesday, Jul 10, 2024 using Doxygen and m.css. Contact us via GitHub.

+

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Thursday, Jul 11, 2024 using Doxygen and m.css. Contact us via GitHub.

diff --git a/_sedov_blastwave_8cpp.html b/_sedov_blastwave_8cpp.html index af4c9196af9b..c71f07d52c31 100644 --- a/_sedov_blastwave_8cpp.html +++ b/_sedov_blastwave_8cpp.html @@ -129,7 +129,7 @@

Namespaces

-

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Wednesday, Jul 10, 2024 using Doxygen and m.css. Contact us via GitHub.

+

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Thursday, Jul 11, 2024 using Doxygen and m.css. Contact us via GitHub.

diff --git a/_sedov_blastwave_8hpp.html b/_sedov_blastwave_8hpp.html index 70eaf0593577..26e843cb6676 100644 --- a/_sedov_blastwave_8hpp.html +++ b/_sedov_blastwave_8hpp.html @@ -139,7 +139,7 @@

Classes

-

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Wednesday, Jul 10, 2024 using Doxygen and m.css. Contact us via GitHub.

+

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Thursday, Jul 11, 2024 using Doxygen and m.css. Contact us via GitHub.

diff --git a/_shear_diff_8cpp.html b/_shear_diff_8cpp.html index e044e25a675e..fd39c7e986d5 100644 --- a/_shear_diff_8cpp.html +++ b/_shear_diff_8cpp.html @@ -129,7 +129,7 @@

Namespaces

-

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Wednesday, Jul 10, 2024 using Doxygen and m.css. Contact us via GitHub.

+

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Thursday, Jul 11, 2024 using Doxygen and m.css. Contact us via GitHub.

diff --git a/_shear_diff_8hpp.html b/_shear_diff_8hpp.html index 175791bc87c2..bf1645badd19 100644 --- a/_shear_diff_8hpp.html +++ b/_shear_diff_8hpp.html @@ -139,7 +139,7 @@

Classes

-

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Wednesday, Jul 10, 2024 using Doxygen and m.css. Contact us via GitHub.

+

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Thursday, Jul 11, 2024 using Doxygen and m.css. Contact us via GitHub.

diff --git a/_shedding_flow_8cpp.html b/_shedding_flow_8cpp.html index 737376f310d0..a8b4c57bb2c9 100644 --- a/_shedding_flow_8cpp.html +++ b/_shedding_flow_8cpp.html @@ -129,7 +129,7 @@

Namespaces

-

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Wednesday, Jul 10, 2024 using Doxygen and m.css. Contact us via GitHub.

+

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Thursday, Jul 11, 2024 using Doxygen and m.css. Contact us via GitHub.

diff --git a/_shedding_flow_8hpp.html b/_shedding_flow_8hpp.html index f21065cb347b..c443af2d426b 100644 --- a/_shedding_flow_8hpp.html +++ b/_shedding_flow_8hpp.html @@ -139,7 +139,7 @@

Classes

-

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Wednesday, Jul 10, 2024 using Doxygen and m.css. Contact us via GitHub.

+

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Thursday, Jul 11, 2024 using Doxygen and m.css. Contact us via GitHub.

diff --git a/_shock_he_bubble_8cpp.html b/_shock_he_bubble_8cpp.html index 6b099f9aeb35..d6b5231d1891 100644 --- a/_shock_he_bubble_8cpp.html +++ b/_shock_he_bubble_8cpp.html @@ -129,7 +129,7 @@

Namespaces

-

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Wednesday, Jul 10, 2024 using Doxygen and m.css. Contact us via GitHub.

+

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Thursday, Jul 11, 2024 using Doxygen and m.css. Contact us via GitHub.

diff --git a/_shock_he_bubble_8hpp.html b/_shock_he_bubble_8hpp.html index 40eeb835de08..b8329900f216 100644 --- a/_shock_he_bubble_8hpp.html +++ b/_shock_he_bubble_8hpp.html @@ -139,7 +139,7 @@

Classes

-

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Wednesday, Jul 10, 2024 using Doxygen and m.css. Contact us via GitHub.

+

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Thursday, Jul 11, 2024 using Doxygen and m.css. Contact us via GitHub.

diff --git a/_silo_writer_8cpp.html b/_silo_writer_8cpp.html index b41143d57957..00fc4309c614 100644 --- a/_silo_writer_8cpp.html +++ b/_silo_writer_8cpp.html @@ -111,7 +111,7 @@

-

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Wednesday, Jul 10, 2024 using Doxygen and m.css. Contact us via GitHub.

+

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Thursday, Jul 11, 2024 using Doxygen and m.css. Contact us via GitHub.

diff --git a/_silo_writer_8hpp.html b/_silo_writer_8hpp.html index 56c81de3a6ea..0182c96095f1 100644 --- a/_silo_writer_8hpp.html +++ b/_silo_writer_8hpp.html @@ -139,7 +139,7 @@

Classes

-

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Wednesday, Jul 10, 2024 using Doxygen and m.css. Contact us via GitHub.

+

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Thursday, Jul 11, 2024 using Doxygen and m.css. Contact us via GitHub.

diff --git a/_sinewave_packet_8cpp.html b/_sinewave_packet_8cpp.html index c31f4919dc15..37538d8c88d2 100644 --- a/_sinewave_packet_8cpp.html +++ b/_sinewave_packet_8cpp.html @@ -129,7 +129,7 @@

Namespaces

-

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Wednesday, Jul 10, 2024 using Doxygen and m.css. Contact us via GitHub.

+

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Thursday, Jul 11, 2024 using Doxygen and m.css. Contact us via GitHub.

diff --git a/_sinewave_packet_8hpp.html b/_sinewave_packet_8hpp.html index d56cea9eedc8..4b336b1be6dd 100644 --- a/_sinewave_packet_8hpp.html +++ b/_sinewave_packet_8hpp.html @@ -139,7 +139,7 @@

Classes

-

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Wednesday, Jul 10, 2024 using Doxygen and m.css. Contact us via GitHub.

+

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Thursday, Jul 11, 2024 using Doxygen and m.css. Contact us via GitHub.

diff --git a/_slot_cyl_8cpp.html b/_slot_cyl_8cpp.html index 0f74dbb91060..bf6cad32325b 100644 --- a/_slot_cyl_8cpp.html +++ b/_slot_cyl_8cpp.html @@ -111,7 +111,7 @@

-

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Wednesday, Jul 10, 2024 using Doxygen and m.css. Contact us via GitHub.

+

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Thursday, Jul 11, 2024 using Doxygen and m.css. Contact us via GitHub.

diff --git a/_slot_cyl_8hpp.html b/_slot_cyl_8hpp.html index 5848a18c9dcf..423e27790157 100644 --- a/_slot_cyl_8hpp.html +++ b/_slot_cyl_8hpp.html @@ -139,7 +139,7 @@

Classes

-

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Wednesday, Jul 10, 2024 using Doxygen and m.css. Contact us via GitHub.

+

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Thursday, Jul 11, 2024 using Doxygen and m.css. Contact us via GitHub.

diff --git a/_small_shear_solid_8hpp.html b/_small_shear_solid_8hpp.html index 4152570f347e..6ec87a7c5349 100644 --- a/_small_shear_solid_8hpp.html +++ b/_small_shear_solid_8hpp.html @@ -129,7 +129,7 @@

Namespaces

-

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Wednesday, Jul 10, 2024 using Doxygen and m.css. Contact us via GitHub.

+

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Thursday, Jul 11, 2024 using Doxygen and m.css. Contact us via GitHub.

diff --git a/_solid_terms_8cpp.html b/_solid_terms_8cpp.html index b5ffaa07f0dd..ff9117d9e5b8 100644 --- a/_solid_terms_8cpp.html +++ b/_solid_terms_8cpp.html @@ -131,7 +131,7 @@

Namespaces

-

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Wednesday, Jul 10, 2024 using Doxygen and m.css. Contact us via GitHub.

+

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Thursday, Jul 11, 2024 using Doxygen and m.css. Contact us via GitHub.

diff --git a/_solid_terms_8hpp.html b/_solid_terms_8hpp.html index 95c1657f1e89..1db28e702231 100644 --- a/_solid_terms_8hpp.html +++ b/_solid_terms_8hpp.html @@ -129,7 +129,7 @@

Namespaces

-

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Wednesday, Jul 10, 2024 using Doxygen and m.css. Contact us via GitHub.

+

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Thursday, Jul 11, 2024 using Doxygen and m.css. Contact us via GitHub.

diff --git a/_sorter_8cpp.html b/_sorter_8cpp.html index 9872cfd4eea0..b39013b4279d 100644 --- a/_sorter_8cpp.html +++ b/_sorter_8cpp.html @@ -129,7 +129,7 @@

Namespaces

-

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Wednesday, Jul 10, 2024 using Doxygen and m.css. Contact us via GitHub.

+

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Thursday, Jul 11, 2024 using Doxygen and m.css. Contact us via GitHub.

diff --git a/_sorter_8hpp.html b/_sorter_8hpp.html index 47cd26372201..864720e2b047 100644 --- a/_sorter_8hpp.html +++ b/_sorter_8hpp.html @@ -139,7 +139,7 @@

Classes

-

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Wednesday, Jul 10, 2024 using Doxygen and m.css. Contact us via GitHub.

+

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Thursday, Jul 11, 2024 using Doxygen and m.css. Contact us via GitHub.

diff --git a/_source_8cpp.html b/_source_8cpp.html index 05a623e7b5f1..6e2cd9d1774e 100644 --- a/_source_8cpp.html +++ b/_source_8cpp.html @@ -111,7 +111,7 @@

-

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Wednesday, Jul 10, 2024 using Doxygen and m.css. Contact us via GitHub.

+

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Thursday, Jul 11, 2024 using Doxygen and m.css. Contact us via GitHub.

diff --git a/_source_8hpp.html b/_source_8hpp.html index 972579b27143..563753de353a 100644 --- a/_source_8hpp.html +++ b/_source_8hpp.html @@ -129,7 +129,7 @@

Namespaces

-

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Wednesday, Jul 10, 2024 using Doxygen and m.css. Contact us via GitHub.

+

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Thursday, Jul 11, 2024 using Doxygen and m.css. Contact us via GitHub.

diff --git a/_stat_ctr_8hpp.html b/_stat_ctr_8hpp.html index 0b8826503902..d3383d6284a0 100644 --- a/_stat_ctr_8hpp.html +++ b/_stat_ctr_8hpp.html @@ -143,7 +143,7 @@

Classes

-

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Wednesday, Jul 10, 2024 using Doxygen and m.css. Contact us via GitHub.

+

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Thursday, Jul 11, 2024 using Doxygen and m.css. Contact us via GitHub.

diff --git a/_statistics_8cpp.html b/_statistics_8cpp.html index 0d07caab1f1b..1c04542ff1cb 100644 --- a/_statistics_8cpp.html +++ b/_statistics_8cpp.html @@ -111,7 +111,7 @@

-

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Wednesday, Jul 10, 2024 using Doxygen and m.css. Contact us via GitHub.

+

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Thursday, Jul 11, 2024 using Doxygen and m.css. Contact us via GitHub.

diff --git a/_statistics_8hpp.html b/_statistics_8hpp.html index bdecab9b42bd..dae3b1f2087e 100644 --- a/_statistics_8hpp.html +++ b/_statistics_8hpp.html @@ -139,7 +139,7 @@

Classes

-

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Wednesday, Jul 10, 2024 using Doxygen and m.css. Contact us via GitHub.

+

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Thursday, Jul 11, 2024 using Doxygen and m.css. Contact us via GitHub.

diff --git a/_stiffened_gas_8cpp.html b/_stiffened_gas_8cpp.html index 7d1a1e1cdd4b..dfaad47bb163 100644 --- a/_stiffened_gas_8cpp.html +++ b/_stiffened_gas_8cpp.html @@ -111,7 +111,7 @@

-

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Wednesday, Jul 10, 2024 using Doxygen and m.css. Contact us via GitHub.

+

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Thursday, Jul 11, 2024 using Doxygen and m.css. Contact us via GitHub.

diff --git a/_stiffened_gas_8hpp.html b/_stiffened_gas_8hpp.html index 30a3a82268d3..960233026389 100644 --- a/_stiffened_gas_8hpp.html +++ b/_stiffened_gas_8hpp.html @@ -129,7 +129,7 @@

Namespaces

-

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Wednesday, Jul 10, 2024 using Doxygen and m.css. Contact us via GitHub.

+

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Thursday, Jul 11, 2024 using Doxygen and m.css. Contact us via GitHub.

diff --git a/_string_parser_8cpp.html b/_string_parser_8cpp.html index d4eb14c86dfc..c0f87382ba35 100644 --- a/_string_parser_8cpp.html +++ b/_string_parser_8cpp.html @@ -111,7 +111,7 @@

-

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Wednesday, Jul 10, 2024 using Doxygen and m.css. Contact us via GitHub.

+

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Thursday, Jul 11, 2024 using Doxygen and m.css. Contact us via GitHub.

diff --git a/_string_parser_8hpp.html b/_string_parser_8hpp.html index 161998532344..c5ade408618f 100644 --- a/_string_parser_8hpp.html +++ b/_string_parser_8hpp.html @@ -139,7 +139,7 @@

Classes

-

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Wednesday, Jul 10, 2024 using Doxygen and m.css. Contact us via GitHub.

+

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Thursday, Jul 11, 2024 using Doxygen and m.css. Contact us via GitHub.

diff --git a/_surface_8cpp.html b/_surface_8cpp.html index a50fe11d56e9..75cb255eee8c 100644 --- a/_surface_8cpp.html +++ b/_surface_8cpp.html @@ -131,7 +131,7 @@

Namespaces

-

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Wednesday, Jul 10, 2024 using Doxygen and m.css. Contact us via GitHub.

+

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Thursday, Jul 11, 2024 using Doxygen and m.css. Contact us via GitHub.

diff --git a/_surface_8hpp.html b/_surface_8hpp.html index 96727939077c..cf03db07eefc 100644 --- a/_surface_8hpp.html +++ b/_surface_8hpp.html @@ -129,7 +129,7 @@

Namespaces

-

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Wednesday, Jul 10, 2024 using Doxygen and m.css. Contact us via GitHub.

+

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Thursday, Jul 11, 2024 using Doxygen and m.css. Contact us via GitHub.

diff --git a/_t_u_t_config_8hpp.html b/_t_u_t_config_8hpp.html index 8ee51ff80b5a..0b012766050d 100644 --- a/_t_u_t_config_8hpp.html +++ b/_t_u_t_config_8hpp.html @@ -129,7 +129,7 @@

Namespaces

-

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Wednesday, Jul 10, 2024 using Doxygen and m.css. Contact us via GitHub.

+

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Thursday, Jul 11, 2024 using Doxygen and m.css. Contact us via GitHub.

diff --git a/_t_u_t_suite_8cpp.html b/_t_u_t_suite_8cpp.html index a46b53df822a..5e98750e28ca 100644 --- a/_t_u_t_suite_8cpp.html +++ b/_t_u_t_suite_8cpp.html @@ -137,7 +137,7 @@

Variables

-

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Wednesday, Jul 10, 2024 using Doxygen and m.css. Contact us via GitHub.

+

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Thursday, Jul 11, 2024 using Doxygen and m.css. Contact us via GitHub.

diff --git a/_t_u_t_suite_8hpp.html b/_t_u_t_suite_8hpp.html index bd90b0b7e1b8..4c6b5e153274 100644 --- a/_t_u_t_suite_8hpp.html +++ b/_t_u_t_suite_8hpp.html @@ -139,7 +139,7 @@

Classes

-

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Wednesday, Jul 10, 2024 using Doxygen and m.css. Contact us via GitHub.

+

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Thursday, Jul 11, 2024 using Doxygen and m.css. Contact us via GitHub.

diff --git a/_t_u_t_test_8cpp.html b/_t_u_t_test_8cpp.html index 24d58026ec55..89e9db59b345 100644 --- a/_t_u_t_test_8cpp.html +++ b/_t_u_t_test_8cpp.html @@ -111,7 +111,7 @@

-

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Wednesday, Jul 10, 2024 using Doxygen and m.css. Contact us via GitHub.

+

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Thursday, Jul 11, 2024 using Doxygen and m.css. Contact us via GitHub.

diff --git a/_t_u_t_test_8hpp.html b/_t_u_t_test_8hpp.html index 55cf13de0e60..e7148629830d 100644 --- a/_t_u_t_test_8hpp.html +++ b/_t_u_t_test_8hpp.html @@ -140,7 +140,7 @@

Classes

-

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Wednesday, Jul 10, 2024 using Doxygen and m.css. Contact us via GitHub.

+

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Thursday, Jul 11, 2024 using Doxygen and m.css. Contact us via GitHub.

diff --git a/_t_u_t_util_8hpp.html b/_t_u_t_util_8hpp.html index 75f124b8a3be..e46f65d888e5 100644 --- a/_t_u_t_util_8hpp.html +++ b/_t_u_t_util_8hpp.html @@ -129,7 +129,7 @@

Namespaces

-

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Wednesday, Jul 10, 2024 using Doxygen and m.css. Contact us via GitHub.

+

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Thursday, Jul 11, 2024 using Doxygen and m.css. Contact us via GitHub.

diff --git a/_table_8hpp.html b/_table_8hpp.html index 06e030614dc0..4893f0644a76 100644 --- a/_table_8hpp.html +++ b/_table_8hpp.html @@ -129,7 +129,7 @@

Namespaces

-

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Wednesday, Jul 10, 2024 using Doxygen and m.css. Contact us via GitHub.

+

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Thursday, Jul 11, 2024 using Doxygen and m.css. Contact us via GitHub.

diff --git a/_tagged_tuple_8hpp.html b/_tagged_tuple_8hpp.html index 6e66b7be705f..cd324cb8a602 100644 --- a/_tagged_tuple_8hpp.html +++ b/_tagged_tuple_8hpp.html @@ -152,7 +152,7 @@

Defines

-

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Wednesday, Jul 10, 2024 using Doxygen and m.css. Contact us via GitHub.

+

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Thursday, Jul 11, 2024 using Doxygen and m.css. Contact us via GitHub.

diff --git a/_tagged_tuple_deep_print_8hpp.html b/_tagged_tuple_deep_print_8hpp.html index 96bb3fb0e3ac..c2e624a1c92d 100644 --- a/_tagged_tuple_deep_print_8hpp.html +++ b/_tagged_tuple_deep_print_8hpp.html @@ -140,7 +140,7 @@

Classes

-

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Wednesday, Jul 10, 2024 using Doxygen and m.css. Contact us via GitHub.

+

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Thursday, Jul 11, 2024 using Doxygen and m.css. Contact us via GitHub.

diff --git a/_tagged_tuple_print_8hpp.html b/_tagged_tuple_print_8hpp.html index 56262c848c6b..432333a85b79 100644 --- a/_tagged_tuple_print_8hpp.html +++ b/_tagged_tuple_print_8hpp.html @@ -140,7 +140,7 @@

Classes

-

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Wednesday, Jul 10, 2024 using Doxygen and m.css. Contact us via GitHub.

+

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Thursday, Jul 11, 2024 using Doxygen and m.css. Contact us via GitHub.

diff --git a/_tags_8hpp.html b/_tags_8hpp.html index 15ed0b5a528a..1965a2f7617a 100644 --- a/_tags_8hpp.html +++ b/_tags_8hpp.html @@ -129,7 +129,7 @@

Namespaces

-

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Wednesday, Jul 10, 2024 using Doxygen and m.css. Contact us via GitHub.

+

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Thursday, Jul 11, 2024 using Doxygen and m.css. Contact us via GitHub.

diff --git a/_taylor_green_8cpp.html b/_taylor_green_8cpp.html index c7a5c24ed3f2..995aeb7967aa 100644 --- a/_taylor_green_8cpp.html +++ b/_taylor_green_8cpp.html @@ -111,7 +111,7 @@

-

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Wednesday, Jul 10, 2024 using Doxygen and m.css. Contact us via GitHub.

+

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Thursday, Jul 11, 2024 using Doxygen and m.css. Contact us via GitHub.

diff --git a/_taylor_green_8hpp.html b/_taylor_green_8hpp.html index 311739cfbe38..085826f8229c 100644 --- a/_taylor_green_8hpp.html +++ b/_taylor_green_8hpp.html @@ -139,7 +139,7 @@

Classes

-

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Wednesday, Jul 10, 2024 using Doxygen and m.css. Contact us via GitHub.

+

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Thursday, Jul 11, 2024 using Doxygen and m.css. Contact us via GitHub.

diff --git a/_tee_buf_8hpp.html b/_tee_buf_8hpp.html index f73e8b53c5cd..beb1d54fd095 100644 --- a/_tee_buf_8hpp.html +++ b/_tee_buf_8hpp.html @@ -136,7 +136,7 @@

Namespaces

-

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Wednesday, Jul 10, 2024 using Doxygen and m.css. Contact us via GitHub.

+

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Thursday, Jul 11, 2024 using Doxygen and m.css. Contact us via GitHub.

diff --git a/_test_around_8cpp.html b/_test_around_8cpp.html index 0bd0a8f38246..75db8010e7c3 100644 --- a/_test_around_8cpp.html +++ b/_test_around_8cpp.html @@ -111,7 +111,7 @@

-

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Wednesday, Jul 10, 2024 using Doxygen and m.css. Contact us via GitHub.

+

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Thursday, Jul 11, 2024 using Doxygen and m.css. Contact us via GitHub.

diff --git a/_test_array_8hpp.html b/_test_array_8hpp.html index 0b9e9eaa3f13..62d48983b8a9 100644 --- a/_test_array_8hpp.html +++ b/_test_array_8hpp.html @@ -139,7 +139,7 @@

Classes

-

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Wednesday, Jul 10, 2024 using Doxygen and m.css. Contact us via GitHub.

+

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Thursday, Jul 11, 2024 using Doxygen and m.css. Contact us via GitHub.

diff --git a/_test_c_s_r_8cpp.html b/_test_c_s_r_8cpp.html index de15b5d8292d..94072cf20bfa 100644 --- a/_test_c_s_r_8cpp.html +++ b/_test_c_s_r_8cpp.html @@ -111,7 +111,7 @@

-

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Wednesday, Jul 10, 2024 using Doxygen and m.css. Contact us via GitHub.

+

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Thursday, Jul 11, 2024 using Doxygen and m.css. Contact us via GitHub.

diff --git a/_test_conjugate_gradients_8cpp.html b/_test_conjugate_gradients_8cpp.html index 9ed3e730d058..ae5ade3c6fdd 100644 --- a/_test_conjugate_gradients_8cpp.html +++ b/_test_conjugate_gradients_8cpp.html @@ -111,7 +111,7 @@

-

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Wednesday, Jul 10, 2024 using Doxygen and m.css. Contact us via GitHub.

+

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Thursday, Jul 11, 2024 using Doxygen and m.css. Contact us via GitHub.

diff --git a/_test_container_util_8cpp.html b/_test_container_util_8cpp.html index 6fc81927c1dd..67823394636f 100644 --- a/_test_container_util_8cpp.html +++ b/_test_container_util_8cpp.html @@ -111,7 +111,7 @@

-

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Wednesday, Jul 10, 2024 using Doxygen and m.css. Contact us via GitHub.

+

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Thursday, Jul 11, 2024 using Doxygen and m.css. Contact us via GitHub.

diff --git a/_test_data_8cpp.html b/_test_data_8cpp.html index f6375dff8170..33ed5dc312d6 100644 --- a/_test_data_8cpp.html +++ b/_test_data_8cpp.html @@ -111,7 +111,7 @@

-

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Wednesday, Jul 10, 2024 using Doxygen and m.css. Contact us via GitHub.

+

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Thursday, Jul 11, 2024 using Doxygen and m.css. Contact us via GitHub.

diff --git a/_test_derived_data_8cpp.html b/_test_derived_data_8cpp.html index b7201c5536b7..31202f2994b5 100644 --- a/_test_derived_data_8cpp.html +++ b/_test_derived_data_8cpp.html @@ -203,7 +203,7 @@

-

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Wednesday, Jul 10, 2024 using Doxygen and m.css. Contact us via GitHub.

+

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Thursday, Jul 11, 2024 using Doxygen and m.css. Contact us via GitHub.

diff --git a/_test_derived_data___m_p_i_single_8cpp.html b/_test_derived_data___m_p_i_single_8cpp.html index 3abeb7357d61..29cd8d9f90ca 100644 --- a/_test_derived_data___m_p_i_single_8cpp.html +++ b/_test_derived_data___m_p_i_single_8cpp.html @@ -111,7 +111,7 @@

-

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Wednesday, Jul 10, 2024 using Doxygen and m.css. Contact us via GitHub.

+

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Thursday, Jul 11, 2024 using Doxygen and m.css. Contact us via GitHub.

diff --git a/_test_error_8cpp.html b/_test_error_8cpp.html index fa49820bf9bb..abf248f3652c 100644 --- a/_test_error_8cpp.html +++ b/_test_error_8cpp.html @@ -157,7 +157,7 @@

-

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Wednesday, Jul 10, 2024 using Doxygen and m.css. Contact us via GitHub.

+

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Thursday, Jul 11, 2024 using Doxygen and m.css. Contact us via GitHub.

diff --git a/_test_exception_8cpp.html b/_test_exception_8cpp.html index bfe83ea67dc9..9a7d6fb5861f 100644 --- a/_test_exception_8cpp.html +++ b/_test_exception_8cpp.html @@ -111,7 +111,7 @@

-

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Wednesday, Jul 10, 2024 using Doxygen and m.css. Contact us via GitHub.

+

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Thursday, Jul 11, 2024 using Doxygen and m.css. Contact us via GitHub.

diff --git a/_test_exception_m_p_i_8cpp.html b/_test_exception_m_p_i_8cpp.html index 3b930a85fc8c..1359265c66f7 100644 --- a/_test_exception_m_p_i_8cpp.html +++ b/_test_exception_m_p_i_8cpp.html @@ -111,7 +111,7 @@

-

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Wednesday, Jul 10, 2024 using Doxygen and m.css. Contact us via GitHub.

+

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Thursday, Jul 11, 2024 using Doxygen and m.css. Contact us via GitHub.

diff --git a/_test_exodus_i_i_mesh_reader_8cpp.html b/_test_exodus_i_i_mesh_reader_8cpp.html index 90306d6bc5b5..0fd77a5b4ef4 100644 --- a/_test_exodus_i_i_mesh_reader_8cpp.html +++ b/_test_exodus_i_i_mesh_reader_8cpp.html @@ -111,7 +111,7 @@

-

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Wednesday, Jul 10, 2024 using Doxygen and m.css. Contact us via GitHub.

+

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Thursday, Jul 11, 2024 using Doxygen and m.css. Contact us via GitHub.

diff --git a/_test_factory_8cpp.html b/_test_factory_8cpp.html index dc12d5f4929e..f3a90c49961f 100644 --- a/_test_factory_8cpp.html +++ b/_test_factory_8cpp.html @@ -111,7 +111,7 @@

-

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Wednesday, Jul 10, 2024 using Doxygen and m.css. Contact us via GitHub.

+

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Thursday, Jul 11, 2024 using Doxygen and m.css. Contact us via GitHub.

diff --git a/_test_flip__map_8cpp.html b/_test_flip__map_8cpp.html index 78361a5de3db..45e26ba58daf 100644 --- a/_test_flip__map_8cpp.html +++ b/_test_flip__map_8cpp.html @@ -111,7 +111,7 @@

-

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Wednesday, Jul 10, 2024 using Doxygen and m.css. Contact us via GitHub.

+

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Thursday, Jul 11, 2024 using Doxygen and m.css. Contact us via GitHub.

diff --git a/_test_gradients_8cpp.html b/_test_gradients_8cpp.html index 77e3a68943dc..d6e1c01ac9a8 100644 --- a/_test_gradients_8cpp.html +++ b/_test_gradients_8cpp.html @@ -157,7 +157,7 @@

-

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Wednesday, Jul 10, 2024 using Doxygen and m.css. Contact us via GitHub.

+

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Thursday, Jul 11, 2024 using Doxygen and m.css. Contact us via GitHub.

diff --git a/_test_has_8cpp.html b/_test_has_8cpp.html index d0efe36d888a..93d3503757d6 100644 --- a/_test_has_8cpp.html +++ b/_test_has_8cpp.html @@ -111,7 +111,7 @@

-

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Wednesday, Jul 10, 2024 using Doxygen and m.css. Contact us via GitHub.

+

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Thursday, Jul 11, 2024 using Doxygen and m.css. Contact us via GitHub.

diff --git a/_test_linear_map_8cpp.html b/_test_linear_map_8cpp.html index afdbd00ef4eb..2a467452b517 100644 --- a/_test_linear_map_8cpp.html +++ b/_test_linear_map_8cpp.html @@ -129,7 +129,7 @@

Namespaces

-

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Wednesday, Jul 10, 2024 using Doxygen and m.css. Contact us via GitHub.

+

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Thursday, Jul 11, 2024 using Doxygen and m.css. Contact us via GitHub.

diff --git a/_test_load_distributor_8cpp.html b/_test_load_distributor_8cpp.html index 816792c78388..d9f6fe026011 100644 --- a/_test_load_distributor_8cpp.html +++ b/_test_load_distributor_8cpp.html @@ -129,7 +129,7 @@

Namespaces

-

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Wednesday, Jul 10, 2024 using Doxygen and m.css. Contact us via GitHub.

+

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Thursday, Jul 11, 2024 using Doxygen and m.css. Contact us via GitHub.

diff --git a/_test_mesh_8cpp.html b/_test_mesh_8cpp.html index dc6b209acdcf..e4d5598d0e73 100644 --- a/_test_mesh_8cpp.html +++ b/_test_mesh_8cpp.html @@ -111,7 +111,7 @@

-

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Wednesday, Jul 10, 2024 using Doxygen and m.css. Contact us via GitHub.

+

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Thursday, Jul 11, 2024 using Doxygen and m.css. Contact us via GitHub.

diff --git a/_test_mesh_reader_8cpp.html b/_test_mesh_reader_8cpp.html index df4e832da53b..a787d282355c 100644 --- a/_test_mesh_reader_8cpp.html +++ b/_test_mesh_reader_8cpp.html @@ -111,7 +111,7 @@

-

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Wednesday, Jul 10, 2024 using Doxygen and m.css. Contact us via GitHub.

+

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Thursday, Jul 11, 2024 using Doxygen and m.css. Contact us via GitHub.

diff --git a/_test_p_u_p_util_8cpp.html b/_test_p_u_p_util_8cpp.html index e76fc97f7d26..098c599e3ed7 100644 --- a/_test_p_u_p_util_8cpp.html +++ b/_test_p_u_p_util_8cpp.html @@ -111,7 +111,7 @@

-

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Wednesday, Jul 10, 2024 using Doxygen and m.css. Contact us via GitHub.

+

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Thursday, Jul 11, 2024 using Doxygen and m.css. Contact us via GitHub.

diff --git a/_test_print_8cpp.html b/_test_print_8cpp.html index 191fdc8004ca..5ef354678f5f 100644 --- a/_test_print_8cpp.html +++ b/_test_print_8cpp.html @@ -111,7 +111,7 @@

-

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Wednesday, Jul 10, 2024 using Doxygen and m.css. Contact us via GitHub.

+

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Thursday, Jul 11, 2024 using Doxygen and m.css. Contact us via GitHub.

diff --git a/_test_print_util_8cpp.html b/_test_print_util_8cpp.html index 512bc216e0d1..9ba02c5d1dc6 100644 --- a/_test_print_util_8cpp.html +++ b/_test_print_util_8cpp.html @@ -111,7 +111,7 @@

-

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Wednesday, Jul 10, 2024 using Doxygen and m.css. Contact us via GitHub.

+

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Thursday, Jul 11, 2024 using Doxygen and m.css. Contact us via GitHub.

diff --git a/_test_reader_8cpp.html b/_test_reader_8cpp.html index 51e4b961215a..d82d6ebe59f1 100644 --- a/_test_reader_8cpp.html +++ b/_test_reader_8cpp.html @@ -129,7 +129,7 @@

Namespaces

-

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Wednesday, Jul 10, 2024 using Doxygen and m.css. Contact us via GitHub.

+

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Thursday, Jul 11, 2024 using Doxygen and m.css. Contact us via GitHub.

diff --git a/_test_reorder_8cpp.html b/_test_reorder_8cpp.html index be3aa2cef4df..6ae2ea8c95cb 100644 --- a/_test_reorder_8cpp.html +++ b/_test_reorder_8cpp.html @@ -203,7 +203,7 @@

-

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Wednesday, Jul 10, 2024 using Doxygen and m.css. Contact us via GitHub.

+

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Thursday, Jul 11, 2024 using Doxygen and m.css. Contact us via GitHub.

diff --git a/_test_scheme_8cpp.html b/_test_scheme_8cpp.html index 23b08672c56e..f48a55491fa7 100644 --- a/_test_scheme_8cpp.html +++ b/_test_scheme_8cpp.html @@ -129,7 +129,7 @@

Namespaces

-

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Wednesday, Jul 10, 2024 using Doxygen and m.css. Contact us via GitHub.

+

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Thursday, Jul 11, 2024 using Doxygen and m.css. Contact us via GitHub.

diff --git a/_test_string_parser_8cpp.html b/_test_string_parser_8cpp.html index e43e73c9b3ed..b092bb5ed301 100644 --- a/_test_string_parser_8cpp.html +++ b/_test_string_parser_8cpp.html @@ -111,7 +111,7 @@

-

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Wednesday, Jul 10, 2024 using Doxygen and m.css. Contact us via GitHub.

+

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Thursday, Jul 11, 2024 using Doxygen and m.css. Contact us via GitHub.

diff --git a/_test_tagged_tuple_8cpp.html b/_test_tagged_tuple_8cpp.html index dcb51de9467f..bbee97c93f0b 100644 --- a/_test_tagged_tuple_8cpp.html +++ b/_test_tagged_tuple_8cpp.html @@ -111,7 +111,7 @@

-

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Wednesday, Jul 10, 2024 using Doxygen and m.css. Contact us via GitHub.

+

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Thursday, Jul 11, 2024 using Doxygen and m.css. Contact us via GitHub.

diff --git a/_test_timer_8cpp.html b/_test_timer_8cpp.html index b507d3fcd0f5..2b8a65e15e8b 100644 --- a/_test_timer_8cpp.html +++ b/_test_timer_8cpp.html @@ -129,7 +129,7 @@

Namespaces

-

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Wednesday, Jul 10, 2024 using Doxygen and m.css. Contact us via GitHub.

+

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Thursday, Jul 11, 2024 using Doxygen and m.css. Contact us via GitHub.

diff --git a/_test_toggle_8cpp.html b/_test_toggle_8cpp.html index 4c981a172bcf..e9a2488668bc 100644 --- a/_test_toggle_8cpp.html +++ b/_test_toggle_8cpp.html @@ -111,7 +111,7 @@

-

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Wednesday, Jul 10, 2024 using Doxygen and m.css. Contact us via GitHub.

+

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Thursday, Jul 11, 2024 using Doxygen and m.css. Contact us via GitHub.

diff --git a/_test_uns_mesh_map_8cpp.html b/_test_uns_mesh_map_8cpp.html index dade229984fa..1aa8374c1247 100644 --- a/_test_uns_mesh_map_8cpp.html +++ b/_test_uns_mesh_map_8cpp.html @@ -129,7 +129,7 @@

Namespaces

-

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Wednesday, Jul 10, 2024 using Doxygen and m.css. Contact us via GitHub.

+

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Thursday, Jul 11, 2024 using Doxygen and m.css. Contact us via GitHub.

diff --git a/_test_vector_8cpp.html b/_test_vector_8cpp.html index 0fef0972f432..20e749dbf023 100644 --- a/_test_vector_8cpp.html +++ b/_test_vector_8cpp.html @@ -111,7 +111,7 @@

-

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Wednesday, Jul 10, 2024 using Doxygen and m.css. Contact us via GitHub.

+

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Thursday, Jul 11, 2024 using Doxygen and m.css. Contact us via GitHub.

diff --git a/_test_writer_8cpp.html b/_test_writer_8cpp.html index bf47add96a12..075d060a4388 100644 --- a/_test_writer_8cpp.html +++ b/_test_writer_8cpp.html @@ -129,7 +129,7 @@

Namespaces

-

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Wednesday, Jul 10, 2024 using Doxygen and m.css. Contact us via GitHub.

+

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Thursday, Jul 11, 2024 using Doxygen and m.css. Contact us via GitHub.

diff --git a/_timer_8cpp.html b/_timer_8cpp.html index 4b820019fe45..3f550fdcd6bd 100644 --- a/_timer_8cpp.html +++ b/_timer_8cpp.html @@ -111,7 +111,7 @@

-

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Wednesday, Jul 10, 2024 using Doxygen and m.css. Contact us via GitHub.

+

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Thursday, Jul 11, 2024 using Doxygen and m.css. Contact us via GitHub.

diff --git a/_timer_8hpp.html b/_timer_8hpp.html index 35d24dc89f11..9c30f7eda985 100644 --- a/_timer_8hpp.html +++ b/_timer_8hpp.html @@ -143,7 +143,7 @@

Classes

-

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Wednesday, Jul 10, 2024 using Doxygen and m.css. Contact us via GitHub.

+

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Thursday, Jul 11, 2024 using Doxygen and m.css. Contact us via GitHub.

diff --git a/_toggle_8hpp.html b/_toggle_8hpp.html index bad7d8147faa..c07cee717e89 100644 --- a/_toggle_8hpp.html +++ b/_toggle_8hpp.html @@ -140,7 +140,7 @@

Classes

-

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Wednesday, Jul 10, 2024 using Doxygen and m.css. Contact us via GitHub.

+

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Thursday, Jul 11, 2024 using Doxygen and m.css. Contact us via GitHub.

diff --git a/_transfer_8hpp.html b/_transfer_8hpp.html index 923467d80245..3a078f0f368f 100644 --- a/_transfer_8hpp.html +++ b/_transfer_8hpp.html @@ -139,7 +139,7 @@

Classes

-

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Wednesday, Jul 10, 2024 using Doxygen and m.css. Contact us via GitHub.

+

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Thursday, Jul 11, 2024 using Doxygen and m.css. Contact us via GitHub.

diff --git a/_transfer_details_8cpp.html b/_transfer_details_8cpp.html index 64ebf13f58dc..1d814f35d47a 100644 --- a/_transfer_details_8cpp.html +++ b/_transfer_details_8cpp.html @@ -111,7 +111,7 @@

-

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Wednesday, Jul 10, 2024 using Doxygen and m.css. Contact us via GitHub.

+

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Thursday, Jul 11, 2024 using Doxygen and m.css. Contact us via GitHub.

diff --git a/_transfer_details_8hpp.html b/_transfer_details_8hpp.html index 741110fef9a1..8dc71062f156 100644 --- a/_transfer_details_8hpp.html +++ b/_transfer_details_8hpp.html @@ -131,7 +131,7 @@

Classes

-

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Wednesday, Jul 10, 2024 using Doxygen and m.css. Contact us via GitHub.

+

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Thursday, Jul 11, 2024 using Doxygen and m.css. Contact us via GitHub.

diff --git a/_transport_2_physics_2_c_g_8hpp.html b/_transport_2_physics_2_c_g_8hpp.html index 31b128e45572..84c349bd5768 100644 --- a/_transport_2_physics_2_c_g_8hpp.html +++ b/_transport_2_physics_2_c_g_8hpp.html @@ -131,7 +131,7 @@

Namespaces

-

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Wednesday, Jul 10, 2024 using Doxygen and m.css. Contact us via GitHub.

+

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Thursday, Jul 11, 2024 using Doxygen and m.css. Contact us via GitHub.

diff --git a/_transporter_8cpp.html b/_transporter_8cpp.html index 8a621b9884e3..4400bfdaa4b5 100644 --- a/_transporter_8cpp.html +++ b/_transporter_8cpp.html @@ -137,7 +137,7 @@

Variables

-

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Wednesday, Jul 10, 2024 using Doxygen and m.css. Contact us via GitHub.

+

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Thursday, Jul 11, 2024 using Doxygen and m.css. Contact us via GitHub.

diff --git a/_transporter_8hpp.html b/_transporter_8hpp.html index 06bf66aecf06..65bf80fa3c1c 100644 --- a/_transporter_8hpp.html +++ b/_transporter_8hpp.html @@ -139,7 +139,7 @@

Classes

-

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Wednesday, Jul 10, 2024 using Doxygen and m.css. Contact us via GitHub.

+

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Thursday, Jul 11, 2024 using Doxygen and m.css. Contact us via GitHub.

diff --git a/_tri_p_d_f_8hpp.html b/_tri_p_d_f_8hpp.html index 2ae12c7fa18a..3932281f52d1 100644 --- a/_tri_p_d_f_8hpp.html +++ b/_tri_p_d_f_8hpp.html @@ -139,7 +139,7 @@

Classes

-

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Wednesday, Jul 10, 2024 using Doxygen and m.css. Contact us via GitHub.

+

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Thursday, Jul 11, 2024 using Doxygen and m.css. Contact us via GitHub.

diff --git a/_txt_float_format_8hpp.html b/_txt_float_format_8hpp.html index ee707179ccc3..9f265afd194c 100644 --- a/_txt_float_format_8hpp.html +++ b/_txt_float_format_8hpp.html @@ -139,7 +139,7 @@

Classes

-

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Wednesday, Jul 10, 2024 using Doxygen and m.css. Contact us via GitHub.

+

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Thursday, Jul 11, 2024 using Doxygen and m.css. Contact us via GitHub.

diff --git a/_txt_stat_writer_8cpp.html b/_txt_stat_writer_8cpp.html index 71890f6c12e5..7dc688a9b2de 100644 --- a/_txt_stat_writer_8cpp.html +++ b/_txt_stat_writer_8cpp.html @@ -111,7 +111,7 @@

-

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Wednesday, Jul 10, 2024 using Doxygen and m.css. Contact us via GitHub.

+

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Thursday, Jul 11, 2024 using Doxygen and m.css. Contact us via GitHub.

diff --git a/_txt_stat_writer_8hpp.html b/_txt_stat_writer_8hpp.html index 39dbdbdd71d2..833c7ee6c6db 100644 --- a/_txt_stat_writer_8hpp.html +++ b/_txt_stat_writer_8hpp.html @@ -139,7 +139,7 @@

Classes

-

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Wednesday, Jul 10, 2024 using Doxygen and m.css. Contact us via GitHub.

+

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Thursday, Jul 11, 2024 using Doxygen and m.css. Contact us via GitHub.

diff --git a/_u_g_r_i_d_mesh_reader_8cpp.html b/_u_g_r_i_d_mesh_reader_8cpp.html index 8240affc249f..30f18e045cac 100644 --- a/_u_g_r_i_d_mesh_reader_8cpp.html +++ b/_u_g_r_i_d_mesh_reader_8cpp.html @@ -111,7 +111,7 @@

-

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Wednesday, Jul 10, 2024 using Doxygen and m.css. Contact us via GitHub.

+

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Thursday, Jul 11, 2024 using Doxygen and m.css. Contact us via GitHub.

diff --git a/_u_g_r_i_d_mesh_reader_8hpp.html b/_u_g_r_i_d_mesh_reader_8hpp.html index a0427aa48978..15e6b8262626 100644 --- a/_u_g_r_i_d_mesh_reader_8hpp.html +++ b/_u_g_r_i_d_mesh_reader_8hpp.html @@ -139,7 +139,7 @@

Classes

-

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Wednesday, Jul 10, 2024 using Doxygen and m.css. Contact us via GitHub.

+

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Thursday, Jul 11, 2024 using Doxygen and m.css. Contact us via GitHub.

diff --git a/_underwater_ex_8cpp.html b/_underwater_ex_8cpp.html index 35ed9b57d980..e104a551a32a 100644 --- a/_underwater_ex_8cpp.html +++ b/_underwater_ex_8cpp.html @@ -129,7 +129,7 @@

Namespaces

-

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Wednesday, Jul 10, 2024 using Doxygen and m.css. Contact us via GitHub.

+

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Thursday, Jul 11, 2024 using Doxygen and m.css. Contact us via GitHub.

diff --git a/_underwater_ex_8hpp.html b/_underwater_ex_8hpp.html index 35676cd8bbe3..9ceb2f9b81be 100644 --- a/_underwater_ex_8hpp.html +++ b/_underwater_ex_8hpp.html @@ -139,7 +139,7 @@

Classes

-

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Wednesday, Jul 10, 2024 using Doxygen and m.css. Contact us via GitHub.

+

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Thursday, Jul 11, 2024 using Doxygen and m.css. Contact us via GitHub.

diff --git a/_uni_p_d_f_8hpp.html b/_uni_p_d_f_8hpp.html index 32a414192e8f..95fb2ea93f57 100644 --- a/_uni_p_d_f_8hpp.html +++ b/_uni_p_d_f_8hpp.html @@ -139,7 +139,7 @@

Classes

-

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Wednesday, Jul 10, 2024 using Doxygen and m.css. Contact us via GitHub.

+

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Thursday, Jul 11, 2024 using Doxygen and m.css. Contact us via GitHub.

diff --git a/_unit_test_2_cmd_line_2_cmd_line_8hpp.html b/_unit_test_2_cmd_line_2_cmd_line_8hpp.html index 795d30798782..f8c7e5f62972 100644 --- a/_unit_test_2_cmd_line_2_cmd_line_8hpp.html +++ b/_unit_test_2_cmd_line_2_cmd_line_8hpp.html @@ -141,7 +141,7 @@

Classes

-

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Wednesday, Jul 10, 2024 using Doxygen and m.css. Contact us via GitHub.

+

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Thursday, Jul 11, 2024 using Doxygen and m.css. Contact us via GitHub.

diff --git a/_unit_test_2_cmd_line_2_grammar_8hpp.html b/_unit_test_2_cmd_line_2_grammar_8hpp.html index 21a7eaf76b0b..9101e8360a41 100644 --- a/_unit_test_2_cmd_line_2_grammar_8hpp.html +++ b/_unit_test_2_cmd_line_2_grammar_8hpp.html @@ -186,7 +186,7 @@

Classes

-

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Wednesday, Jul 10, 2024 using Doxygen and m.css. Contact us via GitHub.

+

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Thursday, Jul 11, 2024 using Doxygen and m.css. Contact us via GitHub.

diff --git a/_unit_test_2_cmd_line_2_parser_8cpp.html b/_unit_test_2_cmd_line_2_parser_8cpp.html index 1eca0fa4d905..beb41f13b9aa 100644 --- a/_unit_test_2_cmd_line_2_parser_8cpp.html +++ b/_unit_test_2_cmd_line_2_parser_8cpp.html @@ -131,7 +131,7 @@

Namespaces

-

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Wednesday, Jul 10, 2024 using Doxygen and m.css. Contact us via GitHub.

+

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Thursday, Jul 11, 2024 using Doxygen and m.css. Contact us via GitHub.

diff --git a/_unit_test_2_cmd_line_2_parser_8hpp.html b/_unit_test_2_cmd_line_2_parser_8hpp.html index 05849e253be1..821ad269e90d 100644 --- a/_unit_test_2_cmd_line_2_parser_8hpp.html +++ b/_unit_test_2_cmd_line_2_parser_8hpp.html @@ -141,7 +141,7 @@

Classes

-

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Wednesday, Jul 10, 2024 using Doxygen and m.css. Contact us via GitHub.

+

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Thursday, Jul 11, 2024 using Doxygen and m.css. Contact us via GitHub.

diff --git a/_unit_test_8cpp.html b/_unit_test_8cpp.html index c3288ed54798..415f840972ef 100644 --- a/_unit_test_8cpp.html +++ b/_unit_test_8cpp.html @@ -164,7 +164,7 @@

-

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Wednesday, Jul 10, 2024 using Doxygen and m.css. Contact us via GitHub.

+

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Thursday, Jul 11, 2024 using Doxygen and m.css. Contact us via GitHub.

diff --git a/_unit_test_driver_8cpp.html b/_unit_test_driver_8cpp.html index b19f95ae642d..d2643600b3e8 100644 --- a/_unit_test_driver_8cpp.html +++ b/_unit_test_driver_8cpp.html @@ -129,7 +129,7 @@

Namespaces

-

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Wednesday, Jul 10, 2024 using Doxygen and m.css. Contact us via GitHub.

+

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Thursday, Jul 11, 2024 using Doxygen and m.css. Contact us via GitHub.

diff --git a/_unit_test_driver_8hpp.html b/_unit_test_driver_8hpp.html index 2d9253a335b2..9f941659ef57 100644 --- a/_unit_test_driver_8hpp.html +++ b/_unit_test_driver_8hpp.html @@ -139,7 +139,7 @@

Classes

-

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Wednesday, Jul 10, 2024 using Doxygen and m.css. Contact us via GitHub.

+

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Thursday, Jul 11, 2024 using Doxygen and m.css. Contact us via GitHub.

diff --git a/_unit_test_print_8hpp.html b/_unit_test_print_8hpp.html index 8e4307bbe2f8..dd55ccbe34d6 100644 --- a/_unit_test_print_8hpp.html +++ b/_unit_test_print_8hpp.html @@ -139,7 +139,7 @@

Classes

-

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Wednesday, Jul 10, 2024 using Doxygen and m.css. Contact us via GitHub.

+

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Thursday, Jul 11, 2024 using Doxygen and m.css. Contact us via GitHub.

diff --git a/_uns_mesh_8hpp.html b/_uns_mesh_8hpp.html index aa3504830352..170f396f42ce 100644 --- a/_uns_mesh_8hpp.html +++ b/_uns_mesh_8hpp.html @@ -149,7 +149,7 @@

Classes

-

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Wednesday, Jul 10, 2024 using Doxygen and m.css. Contact us via GitHub.

+

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Thursday, Jul 11, 2024 using Doxygen and m.css. Contact us via GitHub.

diff --git a/_uns_mesh_map_8cpp.html b/_uns_mesh_map_8cpp.html index 45bf6eed7aa7..052702708593 100644 --- a/_uns_mesh_map_8cpp.html +++ b/_uns_mesh_map_8cpp.html @@ -111,7 +111,7 @@

-

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Wednesday, Jul 10, 2024 using Doxygen and m.css. Contact us via GitHub.

+

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Thursday, Jul 11, 2024 using Doxygen and m.css. Contact us via GitHub.

diff --git a/_uns_mesh_map_8hpp.html b/_uns_mesh_map_8hpp.html index 9cab6ff8c2c1..ec98bb7d6c5d 100644 --- a/_uns_mesh_map_8hpp.html +++ b/_uns_mesh_map_8hpp.html @@ -139,7 +139,7 @@

Classes

-

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Wednesday, Jul 10, 2024 using Doxygen and m.css. Contact us via GitHub.

+

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Thursday, Jul 11, 2024 using Doxygen and m.css. Contact us via GitHub.

diff --git a/_upwind_8hpp.html b/_upwind_8hpp.html index bcf4815cdddc..0620f0123524 100644 --- a/_upwind_8hpp.html +++ b/_upwind_8hpp.html @@ -139,7 +139,7 @@

Classes

-

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Wednesday, Jul 10, 2024 using Doxygen and m.css. Contact us via GitHub.

+

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Thursday, Jul 11, 2024 using Doxygen and m.css. Contact us via GitHub.

diff --git a/_user_table_8hpp.html b/_user_table_8hpp.html index 6603397c5503..b186a1e5d100 100644 --- a/_user_table_8hpp.html +++ b/_user_table_8hpp.html @@ -139,7 +139,7 @@

Classes

-

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Wednesday, Jul 10, 2024 using Doxygen and m.css. Contact us via GitHub.

+

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Thursday, Jul 11, 2024 using Doxygen and m.css. Contact us via GitHub.

diff --git a/_vector_8hpp.html b/_vector_8hpp.html index 9def613df92d..0095acad2ee5 100644 --- a/_vector_8hpp.html +++ b/_vector_8hpp.html @@ -129,7 +129,7 @@

Namespaces

-

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Wednesday, Jul 10, 2024 using Doxygen and m.css. Contact us via GitHub.

+

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Thursday, Jul 11, 2024 using Doxygen and m.css. Contact us via GitHub.

diff --git a/_volume_8cpp.html b/_volume_8cpp.html index 806d16f51f13..781fc220cbce 100644 --- a/_volume_8cpp.html +++ b/_volume_8cpp.html @@ -111,7 +111,7 @@

-

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Wednesday, Jul 10, 2024 using Doxygen and m.css. Contact us via GitHub.

+

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Thursday, Jul 11, 2024 using Doxygen and m.css. Contact us via GitHub.

diff --git a/_volume_8hpp.html b/_volume_8hpp.html index d1a199c10463..5f51c5a67811 100644 --- a/_volume_8hpp.html +++ b/_volume_8hpp.html @@ -129,7 +129,7 @@

Namespaces

-

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Wednesday, Jul 10, 2024 using Doxygen and m.css. Contact us via GitHub.

+

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Thursday, Jul 11, 2024 using Doxygen and m.css. Contact us via GitHub.

diff --git a/_vortical_flow_8cpp.html b/_vortical_flow_8cpp.html index a89e17a6de8a..1af543ade9aa 100644 --- a/_vortical_flow_8cpp.html +++ b/_vortical_flow_8cpp.html @@ -129,7 +129,7 @@

Namespaces

-

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Wednesday, Jul 10, 2024 using Doxygen and m.css. Contact us via GitHub.

+

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Thursday, Jul 11, 2024 using Doxygen and m.css. Contact us via GitHub.

diff --git a/_vortical_flow_8hpp.html b/_vortical_flow_8hpp.html index eb9b5e0c4303..46450df2759b 100644 --- a/_vortical_flow_8hpp.html +++ b/_vortical_flow_8hpp.html @@ -139,7 +139,7 @@

Classes

-

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Wednesday, Jul 10, 2024 using Doxygen and m.css. Contact us via GitHub.

+

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Thursday, Jul 11, 2024 using Doxygen and m.css. Contact us via GitHub.

diff --git a/_water_air_shocktube_8cpp.html b/_water_air_shocktube_8cpp.html index 77511330dfbd..4ebc365b1caf 100644 --- a/_water_air_shocktube_8cpp.html +++ b/_water_air_shocktube_8cpp.html @@ -129,7 +129,7 @@

Namespaces

-

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Wednesday, Jul 10, 2024 using Doxygen and m.css. Contact us via GitHub.

+

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Thursday, Jul 11, 2024 using Doxygen and m.css. Contact us via GitHub.

diff --git a/_water_air_shocktube_8hpp.html b/_water_air_shocktube_8hpp.html index b872e0c5b1f8..8f7e39400c23 100644 --- a/_water_air_shocktube_8hpp.html +++ b/_water_air_shocktube_8hpp.html @@ -139,7 +139,7 @@

Classes

-

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Wednesday, Jul 10, 2024 using Doxygen and m.css. Contact us via GitHub.

+

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Thursday, Jul 11, 2024 using Doxygen and m.css. Contact us via GitHub.

diff --git a/_writer_8cpp.html b/_writer_8cpp.html index 1d14b3d7d4d8..029ba32de767 100644 --- a/_writer_8cpp.html +++ b/_writer_8cpp.html @@ -111,7 +111,7 @@

-

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Wednesday, Jul 10, 2024 using Doxygen and m.css. Contact us via GitHub.

+

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Thursday, Jul 11, 2024 using Doxygen and m.css. Contact us via GitHub.

diff --git a/_writer_8hpp.html b/_writer_8hpp.html index 5a6a09fa7bd8..cc95955b4a35 100644 --- a/_writer_8hpp.html +++ b/_writer_8hpp.html @@ -139,7 +139,7 @@

Classes

-

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Wednesday, Jul 10, 2024 using Doxygen and m.css. Contact us via GitHub.

+

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Thursday, Jul 11, 2024 using Doxygen and m.css. Contact us via GitHub.

diff --git a/_zoltan2___partitioning_problem_8hpp.html b/_zoltan2___partitioning_problem_8hpp.html index 8bedd36a436c..680ef686adcd 100644 --- a/_zoltan2___partitioning_problem_8hpp.html +++ b/_zoltan2___partitioning_problem_8hpp.html @@ -111,7 +111,7 @@

-

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Wednesday, Jul 10, 2024 using Doxygen and m.css. Contact us via GitHub.

+

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Thursday, Jul 11, 2024 using Doxygen and m.css. Contact us via GitHub.

diff --git a/_zoltan_inter_op_8cpp.html b/_zoltan_inter_op_8cpp.html index ffc9d6b796b8..266b75aac905 100644 --- a/_zoltan_inter_op_8cpp.html +++ b/_zoltan_inter_op_8cpp.html @@ -142,7 +142,7 @@

Classes

-

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Wednesday, Jul 10, 2024 using Doxygen and m.css. Contact us via GitHub.

+

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Thursday, Jul 11, 2024 using Doxygen and m.css. Contact us via GitHub.

diff --git a/_zoltan_inter_op_8hpp.html b/_zoltan_inter_op_8hpp.html index 009491c906ca..53bcee94c195 100644 --- a/_zoltan_inter_op_8hpp.html +++ b/_zoltan_inter_op_8hpp.html @@ -131,7 +131,7 @@

Namespaces

-

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Wednesday, Jul 10, 2024 using Doxygen and m.css. Contact us via GitHub.

+

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Thursday, Jul 11, 2024 using Doxygen and m.css. Contact us via GitHub.

diff --git a/ale_8decl_8h.html b/ale_8decl_8h.html index b60743adb225..6423be1d647e 100644 --- a/ale_8decl_8h.html +++ b/ale_8decl_8h.html @@ -111,7 +111,7 @@

-

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Wednesday, Jul 10, 2024 using Doxygen and m.css. Contact us via GitHub.

+

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Thursday, Jul 11, 2024 using Doxygen and m.css. Contact us via GitHub.

diff --git a/ale_8def_8h.html b/ale_8def_8h.html index 092803035a4d..bb71af37b4a3 100644 --- a/ale_8def_8h.html +++ b/ale_8def_8h.html @@ -111,7 +111,7 @@

-

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Wednesday, Jul 10, 2024 using Doxygen and m.css. Contact us via GitHub.

+

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Thursday, Jul 11, 2024 using Doxygen and m.css. Contact us via GitHub.

diff --git a/alecg_8decl_8h.html b/alecg_8decl_8h.html index e6af41531a08..d28649d4823b 100644 --- a/alecg_8decl_8h.html +++ b/alecg_8decl_8h.html @@ -111,7 +111,7 @@

-

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Wednesday, Jul 10, 2024 using Doxygen and m.css. Contact us via GitHub.

+

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Thursday, Jul 11, 2024 using Doxygen and m.css. Contact us via GitHub.

diff --git a/alecg_8def_8h.html b/alecg_8def_8h.html index 28b89b069eaa..32d852ae0849 100644 --- a/alecg_8def_8h.html +++ b/alecg_8def_8h.html @@ -111,7 +111,7 @@

-

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Wednesday, Jul 10, 2024 using Doxygen and m.css. Contact us via GitHub.

+

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Thursday, Jul 11, 2024 using Doxygen and m.css. Contact us via GitHub.

diff --git a/annotated.html b/annotated.html index 4838c2366637..5787598097d6 100644 --- a/annotated.html +++ b/annotated.html @@ -532,7 +532,7 @@

Classes

-

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Wednesday, Jul 10, 2024 using Doxygen and m.css. Contact us via GitHub.

+

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Thursday, Jul 11, 2024 using Doxygen and m.css. Contact us via GitHub.

diff --git a/any_8hpp.html b/any_8hpp.html index be4b561d64bc..b9802305c413 100644 --- a/any_8hpp.html +++ b/any_8hpp.html @@ -111,7 +111,7 @@

-

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Wednesday, Jul 10, 2024 using Doxygen and m.css. Contact us via GitHub.

+

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Thursday, Jul 11, 2024 using Doxygen and m.css. Contact us via GitHub.

diff --git a/append_8hpp.html b/append_8hpp.html index 2cd5de018e99..68e99e5c6cdc 100644 --- a/append_8hpp.html +++ b/append_8hpp.html @@ -111,7 +111,7 @@

-

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Wednesday, Jul 10, 2024 using Doxygen and m.css. Contact us via GitHub.

+

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Thursday, Jul 11, 2024 using Doxygen and m.css. Contact us via GitHub.

diff --git a/back_8hpp.html b/back_8hpp.html index 52b8a657da40..b198ef78f384 100644 --- a/back_8hpp.html +++ b/back_8hpp.html @@ -111,7 +111,7 @@

-

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Wednesday, Jul 10, 2024 using Doxygen and m.css. Contact us via GitHub.

+

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Thursday, Jul 11, 2024 using Doxygen and m.css. Contact us via GitHub.

diff --git a/backward_8hpp.html b/backward_8hpp.html index 9d7c2eeaefdd..e80426df1a9f 100644 --- a/backward_8hpp.html +++ b/backward_8hpp.html @@ -111,7 +111,7 @@

-

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Wednesday, Jul 10, 2024 using Doxygen and m.css. Contact us via GitHub.

+

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Thursday, Jul 11, 2024 using Doxygen and m.css. Contact us via GitHub.

diff --git a/backwardcpp_license_page.html b/backwardcpp_license_page.html index 1e22a0a1e005..4633311fc9be 100644 --- a/backwardcpp_license_page.html +++ b/backwardcpp_license_page.html @@ -131,7 +131,7 @@

-

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Wednesday, Jul 10, 2024 using Doxygen and m.css. Contact us via GitHub.

+

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Thursday, Jul 11, 2024 using Doxygen and m.css. Contact us via GitHub.

diff --git a/blas_license_page.html b/blas_license_page.html index 0813e8047068..71300f84ace8 100644 --- a/blas_license_page.html +++ b/blas_license_page.html @@ -125,7 +125,7 @@

-

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Wednesday, Jul 10, 2024 using Doxygen and m.css. Contact us via GitHub.

+

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Thursday, Jul 11, 2024 using Doxygen and m.css. Contact us via GitHub.

diff --git a/boost_license_page.html b/boost_license_page.html index 7b5895990171..a53cacf93463 100644 --- a/boost_license_page.html +++ b/boost_license_page.html @@ -134,7 +134,7 @@

-

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Wednesday, Jul 10, 2024 using Doxygen and m.css. Contact us via GitHub.

+

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Thursday, Jul 11, 2024 using Doxygen and m.css. Contact us via GitHub.

diff --git a/brigand_license_page.html b/brigand_license_page.html index 3e342d5eb8d5..a566ac0bf1e2 100644 --- a/brigand_license_page.html +++ b/brigand_license_page.html @@ -134,7 +134,7 @@

-

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Wednesday, Jul 10, 2024 using Doxygen and m.css. Contact us via GitHub.

+

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Thursday, Jul 11, 2024 using Doxygen and m.css. Contact us via GitHub.

diff --git a/build.html b/build.html index 6e0edf518041..a80fc1f8546b 100644 --- a/build.html +++ b/build.html @@ -178,7 +178,7 @@

Contents

-

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Wednesday, Jul 10, 2024 using Doxygen and m.css. Contact us via GitHub.

+

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Thursday, Jul 11, 2024 using Doxygen and m.css. Contact us via GitHub.

diff --git a/build_system.html b/build_system.html index dd18c1513ea9..4287d1c6b3f2 100644 --- a/build_system.html +++ b/build_system.html @@ -119,7 +119,7 @@

Contents

-

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Wednesday, Jul 10, 2024 using Doxygen and m.css. Contact us via GitHub.

+

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Thursday, Jul 11, 2024 using Doxygen and m.css. Contact us via GitHub.

diff --git a/cgreceiver_8decl_8h.html b/cgreceiver_8decl_8h.html index bc37b91ae640..0934005cbe71 100644 --- a/cgreceiver_8decl_8h.html +++ b/cgreceiver_8decl_8h.html @@ -111,7 +111,7 @@

-

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Wednesday, Jul 10, 2024 using Doxygen and m.css. Contact us via GitHub.

+

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Thursday, Jul 11, 2024 using Doxygen and m.css. Contact us via GitHub.

diff --git a/cgreceiver_8def_8h.html b/cgreceiver_8def_8h.html index eeec6ade57da..abc4fbd5227e 100644 --- a/cgreceiver_8def_8h.html +++ b/cgreceiver_8def_8h.html @@ -111,7 +111,7 @@

-

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Wednesday, Jul 10, 2024 using Doxygen and m.css. Contact us via GitHub.

+

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Thursday, Jul 11, 2024 using Doxygen and m.css. Contact us via GitHub.

diff --git a/charestatecollector_8decl_8h.html b/charestatecollector_8decl_8h.html index 2933ca476e36..bd41d046d620 100644 --- a/charestatecollector_8decl_8h.html +++ b/charestatecollector_8decl_8h.html @@ -111,7 +111,7 @@

-

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Wednesday, Jul 10, 2024 using Doxygen and m.css. Contact us via GitHub.

+

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Thursday, Jul 11, 2024 using Doxygen and m.css. Contact us via GitHub.

diff --git a/charestatecollector_8def_8h.html b/charestatecollector_8def_8h.html index 6550654a6974..3ac4e395030a 100644 --- a/charestatecollector_8def_8h.html +++ b/charestatecollector_8def_8h.html @@ -111,7 +111,7 @@

-

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Wednesday, Jul 10, 2024 using Doxygen and m.css. Contact us via GitHub.

+

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Thursday, Jul 11, 2024 using Doxygen and m.css. Contact us via GitHub.

diff --git a/charm_09_09_8hpp.html b/charm_09_09_8hpp.html index 45d724c7a690..69e0c39fb9c8 100644 --- a/charm_09_09_8hpp.html +++ b/charm_09_09_8hpp.html @@ -111,7 +111,7 @@

-

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Wednesday, Jul 10, 2024 using Doxygen and m.css. Contact us via GitHub.

+

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Thursday, Jul 11, 2024 using Doxygen and m.css. Contact us via GitHub.

diff --git a/charm_8hpp.html b/charm_8hpp.html index f4ea0a6504c8..1ec581b2a52b 100644 --- a/charm_8hpp.html +++ b/charm_8hpp.html @@ -111,7 +111,7 @@

-

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Wednesday, Jul 10, 2024 using Doxygen and m.css. Contact us via GitHub.

+

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Thursday, Jul 11, 2024 using Doxygen and m.css. Contact us via GitHub.

diff --git a/charm_license_page.html b/charm_license_page.html index dcdf70c79a18..b53a01d241b2 100644 --- a/charm_license_page.html +++ b/charm_license_page.html @@ -257,7 +257,7 @@

-

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Wednesday, Jul 10, 2024 using Doxygen and m.css. Contact us via GitHub.

+

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Thursday, Jul 11, 2024 using Doxygen and m.css. Contact us via GitHub.

diff --git a/charmchild_8def_8h.html b/charmchild_8def_8h.html index 38a76e921226..3c2d1a3adea3 100644 --- a/charmchild_8def_8h.html +++ b/charmchild_8def_8h.html @@ -111,7 +111,7 @@

-

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Wednesday, Jul 10, 2024 using Doxygen and m.css. Contact us via GitHub.

+

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Thursday, Jul 11, 2024 using Doxygen and m.css. Contact us via GitHub.

diff --git a/charmtimer_8def_8h.html b/charmtimer_8def_8h.html index d7b05ab6e03e..a0804b09616d 100644 --- a/charmtimer_8def_8h.html +++ b/charmtimer_8def_8h.html @@ -111,7 +111,7 @@

-

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Wednesday, Jul 10, 2024 using Doxygen and m.css. Contact us via GitHub.

+

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Thursday, Jul 11, 2024 using Doxygen and m.css. Contact us via GitHub.

diff --git a/class_a_m_r_1_1_error.html b/class_a_m_r_1_1_error.html index 93babd539e8f..2437049b3edb 100644 --- a/class_a_m_r_1_1_error.html +++ b/class_a_m_r_1_1_error.html @@ -192,7 +192,7 @@

-

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Wednesday, Jul 10, 2024 using Doxygen and m.css. Contact us via GitHub.

+

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Thursday, Jul 11, 2024 using Doxygen and m.css. Contact us via GitHub.

diff --git a/class_a_m_r_1_1marked__refinements__store__t.html b/class_a_m_r_1_1marked__refinements__store__t.html index b902e0b0c464..8a806468521c 100644 --- a/class_a_m_r_1_1marked__refinements__store__t.html +++ b/class_a_m_r_1_1marked__refinements__store__t.html @@ -284,7 +284,7 @@

-

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Wednesday, Jul 10, 2024 using Doxygen and m.css. Contact us via GitHub.

+

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Thursday, Jul 11, 2024 using Doxygen and m.css. Contact us via GitHub.

diff --git a/class_a_m_r_1_1node__connectivity__t.html b/class_a_m_r_1_1node__connectivity__t.html index 9f3c532719a8..b55c35f1484f 100644 --- a/class_a_m_r_1_1node__connectivity__t.html +++ b/class_a_m_r_1_1node__connectivity__t.html @@ -296,7 +296,7 @@

-

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Wednesday, Jul 10, 2024 using Doxygen and m.css. Contact us via GitHub.

+

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Thursday, Jul 11, 2024 using Doxygen and m.css. Contact us via GitHub.

diff --git a/class_main.html b/class_main.html index 73f63929efea..9e847bebd0f6 100644 --- a/class_main.html +++ b/class_main.html @@ -299,7 +299,7 @@

-

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Wednesday, Jul 10, 2024 using Doxygen and m.css. Contact us via GitHub.

+

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Thursday, Jul 11, 2024 using Doxygen and m.css. Contact us via GitHub.

diff --git a/classexam2m_1_1_transfer_details.html b/classexam2m_1_1_transfer_details.html index b66383b2bc4e..8f3b82bcf1f9 100644 --- a/classexam2m_1_1_transfer_details.html +++ b/classexam2m_1_1_transfer_details.html @@ -411,7 +411,7 @@

-

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Wednesday, Jul 10, 2024 using Doxygen and m.css. Contact us via GitHub.

+

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Thursday, Jul 11, 2024 using Doxygen and m.css. Contact us via GitHub.

diff --git a/classexecute.html b/classexecute.html index 97e7a030813f..e1f4dccb637f 100644 --- a/classexecute.html +++ b/classexecute.html @@ -135,7 +135,7 @@

Constructors, destructors, conversion operators<
-

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Wednesday, Jul 10, 2024 using Doxygen and m.css. Contact us via GitHub.

+

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Thursday, Jul 11, 2024 using Doxygen and m.css. Contact us via GitHub.

diff --git a/classinciter_1_1_a_l_e.html b/classinciter_1_1_a_l_e.html index a174c666f920..7ef0758d8505 100644 --- a/classinciter_1_1_a_l_e.html +++ b/classinciter_1_1_a_l_e.html @@ -531,7 +531,7 @@

-

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Wednesday, Jul 10, 2024 using Doxygen and m.css. Contact us via GitHub.

+

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Thursday, Jul 11, 2024 using Doxygen and m.css. Contact us via GitHub.

diff --git a/classinciter_1_1_a_l_e_c_g.html b/classinciter_1_1_a_l_e_c_g.html index 130d0da2da79..b50faa3e8b26 100644 --- a/classinciter_1_1_a_l_e_c_g.html +++ b/classinciter_1_1_a_l_e_c_g.html @@ -809,7 +809,7 @@

-

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Wednesday, Jul 10, 2024 using Doxygen and m.css. Contact us via GitHub.

+

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Thursday, Jul 11, 2024 using Doxygen and m.css. Contact us via GitHub.

diff --git a/classinciter_1_1_c_g_p_d_e.html b/classinciter_1_1_c_g_p_d_e.html index 81bada9dea4c..20bd9f279850 100644 --- a/classinciter_1_1_c_g_p_d_e.html +++ b/classinciter_1_1_c_g_p_d_e.html @@ -386,7 +386,7 @@

-

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Wednesday, Jul 10, 2024 using Doxygen and m.css. Contact us via GitHub.

+

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Thursday, Jul 11, 2024 using Doxygen and m.css. Contact us via GitHub.

diff --git a/classinciter_1_1_cmd_line_parser.html b/classinciter_1_1_cmd_line_parser.html index 754734ad46e4..523218c3441d 100644 --- a/classinciter_1_1_cmd_line_parser.html +++ b/classinciter_1_1_cmd_line_parser.html @@ -179,7 +179,7 @@

-

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Wednesday, Jul 10, 2024 using Doxygen and m.css. Contact us via GitHub.

+

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Thursday, Jul 11, 2024 using Doxygen and m.css. Contact us via GitHub.

diff --git a/classinciter_1_1_comp_flow_problem_gauss_hump.html b/classinciter_1_1_comp_flow_problem_gauss_hump.html index daf179056b6b..2d2bafb2bc6c 100644 --- a/classinciter_1_1_comp_flow_problem_gauss_hump.html +++ b/classinciter_1_1_comp_flow_problem_gauss_hump.html @@ -342,7 +342,7 @@

-

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Wednesday, Jul 10, 2024 using Doxygen and m.css. Contact us via GitHub.

+

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Thursday, Jul 11, 2024 using Doxygen and m.css. Contact us via GitHub.

diff --git a/classinciter_1_1_comp_flow_problem_n_l_energy_growth.html b/classinciter_1_1_comp_flow_problem_n_l_energy_growth.html index b041902fc977..35375260e516 100644 --- a/classinciter_1_1_comp_flow_problem_n_l_energy_growth.html +++ b/classinciter_1_1_comp_flow_problem_n_l_energy_growth.html @@ -325,7 +325,7 @@

-

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Wednesday, Jul 10, 2024 using Doxygen and m.css. Contact us via GitHub.

+

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Thursday, Jul 11, 2024 using Doxygen and m.css. Contact us via GitHub.

diff --git a/classinciter_1_1_comp_flow_problem_rayleigh_taylor.html b/classinciter_1_1_comp_flow_problem_rayleigh_taylor.html index 1b928bb0b364..548c3c57ca18 100644 --- a/classinciter_1_1_comp_flow_problem_rayleigh_taylor.html +++ b/classinciter_1_1_comp_flow_problem_rayleigh_taylor.html @@ -329,7 +329,7 @@

-

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Wednesday, Jul 10, 2024 using Doxygen and m.css. Contact us via GitHub.

+

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Thursday, Jul 11, 2024 using Doxygen and m.css. Contact us via GitHub.

diff --git a/classinciter_1_1_comp_flow_problem_rotated_sod_shocktube.html b/classinciter_1_1_comp_flow_problem_rotated_sod_shocktube.html index dd8f68d679c0..97494988599c 100644 --- a/classinciter_1_1_comp_flow_problem_rotated_sod_shocktube.html +++ b/classinciter_1_1_comp_flow_problem_rotated_sod_shocktube.html @@ -197,7 +197,7 @@

-

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Wednesday, Jul 10, 2024 using Doxygen and m.css. Contact us via GitHub.

+

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Thursday, Jul 11, 2024 using Doxygen and m.css. Contact us via GitHub.

diff --git a/classinciter_1_1_comp_flow_problem_sedov_blastwave.html b/classinciter_1_1_comp_flow_problem_sedov_blastwave.html index 3614e6aba04f..701cf4bc451d 100644 --- a/classinciter_1_1_comp_flow_problem_sedov_blastwave.html +++ b/classinciter_1_1_comp_flow_problem_sedov_blastwave.html @@ -300,7 +300,7 @@

-

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Wednesday, Jul 10, 2024 using Doxygen and m.css. Contact us via GitHub.

+

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Thursday, Jul 11, 2024 using Doxygen and m.css. Contact us via GitHub.

diff --git a/classinciter_1_1_comp_flow_problem_shedding_flow.html b/classinciter_1_1_comp_flow_problem_shedding_flow.html index a48f4dfeeff8..3e9d5e7ae540 100644 --- a/classinciter_1_1_comp_flow_problem_shedding_flow.html +++ b/classinciter_1_1_comp_flow_problem_shedding_flow.html @@ -245,7 +245,7 @@

-

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Wednesday, Jul 10, 2024 using Doxygen and m.css. Contact us via GitHub.

+

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Thursday, Jul 11, 2024 using Doxygen and m.css. Contact us via GitHub.

diff --git a/classinciter_1_1_comp_flow_problem_shock_density_wave.html b/classinciter_1_1_comp_flow_problem_shock_density_wave.html index 7ec0dd701ba2..1ef70967be72 100644 --- a/classinciter_1_1_comp_flow_problem_shock_density_wave.html +++ b/classinciter_1_1_comp_flow_problem_shock_density_wave.html @@ -284,7 +284,7 @@

-

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Wednesday, Jul 10, 2024 using Doxygen and m.css. Contact us via GitHub.

+

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Thursday, Jul 11, 2024 using Doxygen and m.css. Contact us via GitHub.

diff --git a/classinciter_1_1_comp_flow_problem_sod_shocktube.html b/classinciter_1_1_comp_flow_problem_sod_shocktube.html index 4f2a799b9342..a63cd2705b8a 100644 --- a/classinciter_1_1_comp_flow_problem_sod_shocktube.html +++ b/classinciter_1_1_comp_flow_problem_sod_shocktube.html @@ -294,7 +294,7 @@

-

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Wednesday, Jul 10, 2024 using Doxygen and m.css. Contact us via GitHub.

+

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Thursday, Jul 11, 2024 using Doxygen and m.css. Contact us via GitHub.

diff --git a/classinciter_1_1_comp_flow_problem_taylor_green.html b/classinciter_1_1_comp_flow_problem_taylor_green.html index fd5af70bfb5a..0abb392d644e 100644 --- a/classinciter_1_1_comp_flow_problem_taylor_green.html +++ b/classinciter_1_1_comp_flow_problem_taylor_green.html @@ -302,7 +302,7 @@

-

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Wednesday, Jul 10, 2024 using Doxygen and m.css. Contact us via GitHub.

+

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Thursday, Jul 11, 2024 using Doxygen and m.css. Contact us via GitHub.

diff --git a/classinciter_1_1_comp_flow_problem_user_defined.html b/classinciter_1_1_comp_flow_problem_user_defined.html index 7250571c0b5e..96b16d8a1e72 100644 --- a/classinciter_1_1_comp_flow_problem_user_defined.html +++ b/classinciter_1_1_comp_flow_problem_user_defined.html @@ -241,7 +241,7 @@

-

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Wednesday, Jul 10, 2024 using Doxygen and m.css. Contact us via GitHub.

+

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Thursday, Jul 11, 2024 using Doxygen and m.css. Contact us via GitHub.

diff --git a/classinciter_1_1_comp_flow_problem_vortical_flow.html b/classinciter_1_1_comp_flow_problem_vortical_flow.html index 7dfcd00ce56b..fc3ba085b09b 100644 --- a/classinciter_1_1_comp_flow_problem_vortical_flow.html +++ b/classinciter_1_1_comp_flow_problem_vortical_flow.html @@ -317,7 +317,7 @@

-

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Wednesday, Jul 10, 2024 using Doxygen and m.css. Contact us via GitHub.

+

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Thursday, Jul 11, 2024 using Doxygen and m.css. Contact us via GitHub.

diff --git a/classinciter_1_1_d_g.html b/classinciter_1_1_d_g.html index b91b2924aba2..8d5ad77df2e8 100644 --- a/classinciter_1_1_d_g.html +++ b/classinciter_1_1_d_g.html @@ -991,7 +991,7 @@

-

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Wednesday, Jul 10, 2024 using Doxygen and m.css. Contact us via GitHub.

+

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Thursday, Jul 11, 2024 using Doxygen and m.css. Contact us via GitHub.

diff --git a/classinciter_1_1_d_g_p_d_e.html b/classinciter_1_1_d_g_p_d_e.html index 18359e656194..6d05429a0316 100644 --- a/classinciter_1_1_d_g_p_d_e.html +++ b/classinciter_1_1_d_g_p_d_e.html @@ -455,7 +455,7 @@

-

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Wednesday, Jul 10, 2024 using Doxygen and m.css. Contact us via GitHub.

+

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Thursday, Jul 11, 2024 using Doxygen and m.css. Contact us via GitHub.

diff --git a/classinciter_1_1_discretization.html b/classinciter_1_1_discretization.html index b58cbaca172d..7713f1d7ba5b 100644 --- a/classinciter_1_1_discretization.html +++ b/classinciter_1_1_discretization.html @@ -1462,7 +1462,7 @@

-

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Wednesday, Jul 10, 2024 using Doxygen and m.css. Contact us via GitHub.

+

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Thursday, Jul 11, 2024 using Doxygen and m.css. Contact us via GitHub.

diff --git a/classinciter_1_1_e_o_s.html b/classinciter_1_1_e_o_s.html index f0ac68799c9b..df5c8eaa3b13 100644 --- a/classinciter_1_1_e_o_s.html +++ b/classinciter_1_1_e_o_s.html @@ -322,7 +322,7 @@

-

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Wednesday, Jul 10, 2024 using Doxygen and m.css. Contact us via GitHub.

+

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Thursday, Jul 11, 2024 using Doxygen and m.css. Contact us via GitHub.

diff --git a/classinciter_1_1_elem_diagnostics.html b/classinciter_1_1_elem_diagnostics.html index c66966192810..c586f71a05ad 100644 --- a/classinciter_1_1_elem_diagnostics.html +++ b/classinciter_1_1_elem_diagnostics.html @@ -241,7 +241,7 @@

-

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Wednesday, Jul 10, 2024 using Doxygen and m.css. Contact us via GitHub.

+

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Thursday, Jul 11, 2024 using Doxygen and m.css. Contact us via GitHub.

diff --git a/classinciter_1_1_f_v.html b/classinciter_1_1_f_v.html index ee2f2518d780..1327bed37fa9 100644 --- a/classinciter_1_1_f_v.html +++ b/classinciter_1_1_f_v.html @@ -729,7 +729,7 @@

-

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Wednesday, Jul 10, 2024 using Doxygen and m.css. Contact us via GitHub.

+

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Thursday, Jul 11, 2024 using Doxygen and m.css. Contact us via GitHub.

diff --git a/classinciter_1_1_f_v_p_d_e.html b/classinciter_1_1_f_v_p_d_e.html index f3bce2827419..d44faa43fbcf 100644 --- a/classinciter_1_1_f_v_p_d_e.html +++ b/classinciter_1_1_f_v_p_d_e.html @@ -364,7 +364,7 @@

-

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Wednesday, Jul 10, 2024 using Doxygen and m.css. Contact us via GitHub.

+

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Thursday, Jul 11, 2024 using Doxygen and m.css. Contact us via GitHub.

diff --git a/classinciter_1_1_face_data.html b/classinciter_1_1_face_data.html index 10d68f2bb780..95e6748284ff 100644 --- a/classinciter_1_1_face_data.html +++ b/classinciter_1_1_face_data.html @@ -234,7 +234,7 @@

-

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Wednesday, Jul 10, 2024 using Doxygen and m.css. Contact us via GitHub.

+

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Thursday, Jul 11, 2024 using Doxygen and m.css. Contact us via GitHub.

diff --git a/classinciter_1_1_ghosts.html b/classinciter_1_1_ghosts.html index 7d432722464f..7ead8bcdc670 100644 --- a/classinciter_1_1_ghosts.html +++ b/classinciter_1_1_ghosts.html @@ -423,7 +423,7 @@

-

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Wednesday, Jul 10, 2024 using Doxygen and m.css. Contact us via GitHub.

+

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Thursday, Jul 11, 2024 using Doxygen and m.css. Contact us via GitHub.

diff --git a/classinciter_1_1_inciter_driver.html b/classinciter_1_1_inciter_driver.html index 3869e58cc4a9..258d95d13140 100644 --- a/classinciter_1_1_inciter_driver.html +++ b/classinciter_1_1_inciter_driver.html @@ -166,7 +166,7 @@

-

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Wednesday, Jul 10, 2024 using Doxygen and m.css. Contact us via GitHub.

+

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Thursday, Jul 11, 2024 using Doxygen and m.css. Contact us via GitHub.

diff --git a/classinciter_1_1_inciter_print.html b/classinciter_1_1_inciter_print.html index 8a12ab450c89..9e8e2c098c43 100644 --- a/classinciter_1_1_inciter_print.html +++ b/classinciter_1_1_inciter_print.html @@ -319,7 +319,7 @@

-

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Wednesday, Jul 10, 2024 using Doxygen and m.css. Contact us via GitHub.

+

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Thursday, Jul 11, 2024 using Doxygen and m.css. Contact us via GitHub.

diff --git a/classinciter_1_1_lua_parser.html b/classinciter_1_1_lua_parser.html index ca27f25ca80e..af4d38e23483 100644 --- a/classinciter_1_1_lua_parser.html +++ b/classinciter_1_1_lua_parser.html @@ -292,7 +292,7 @@

-

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Wednesday, Jul 10, 2024 using Doxygen and m.css. Contact us via GitHub.

+

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Thursday, Jul 11, 2024 using Doxygen and m.css. Contact us via GitHub.

diff --git a/classinciter_1_1_multi_mat_problem_equil_interface_advect.html b/classinciter_1_1_multi_mat_problem_equil_interface_advect.html index 02b68bc98c0c..6c3ee9da6a04 100644 --- a/classinciter_1_1_multi_mat_problem_equil_interface_advect.html +++ b/classinciter_1_1_multi_mat_problem_equil_interface_advect.html @@ -194,7 +194,7 @@

-

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Wednesday, Jul 10, 2024 using Doxygen and m.css. Contact us via GitHub.

+

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Thursday, Jul 11, 2024 using Doxygen and m.css. Contact us via GitHub.

diff --git a/classinciter_1_1_multi_mat_problem_interface_advection.html b/classinciter_1_1_multi_mat_problem_interface_advection.html index c6cd614830e8..beb4fb58746f 100644 --- a/classinciter_1_1_multi_mat_problem_interface_advection.html +++ b/classinciter_1_1_multi_mat_problem_interface_advection.html @@ -199,7 +199,7 @@

-

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Wednesday, Jul 10, 2024 using Doxygen and m.css. Contact us via GitHub.

+

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Thursday, Jul 11, 2024 using Doxygen and m.css. Contact us via GitHub.

diff --git a/classinciter_1_1_multi_mat_problem_richtmyer_meshkov.html b/classinciter_1_1_multi_mat_problem_richtmyer_meshkov.html index c7b75ce7695e..fb6b1d740612 100644 --- a/classinciter_1_1_multi_mat_problem_richtmyer_meshkov.html +++ b/classinciter_1_1_multi_mat_problem_richtmyer_meshkov.html @@ -194,7 +194,7 @@

-

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Wednesday, Jul 10, 2024 using Doxygen and m.css. Contact us via GitHub.

+

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Thursday, Jul 11, 2024 using Doxygen and m.css. Contact us via GitHub.

diff --git a/classinciter_1_1_multi_mat_problem_shock_density_wave.html b/classinciter_1_1_multi_mat_problem_shock_density_wave.html index b75705aa3e91..e490572429cc 100644 --- a/classinciter_1_1_multi_mat_problem_shock_density_wave.html +++ b/classinciter_1_1_multi_mat_problem_shock_density_wave.html @@ -194,7 +194,7 @@

-

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Wednesday, Jul 10, 2024 using Doxygen and m.css. Contact us via GitHub.

+

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Thursday, Jul 11, 2024 using Doxygen and m.css. Contact us via GitHub.

diff --git a/classinciter_1_1_multi_mat_problem_shock_he_bubble.html b/classinciter_1_1_multi_mat_problem_shock_he_bubble.html index c4d3f69ac9c0..39b38f3b578d 100644 --- a/classinciter_1_1_multi_mat_problem_shock_he_bubble.html +++ b/classinciter_1_1_multi_mat_problem_shock_he_bubble.html @@ -202,7 +202,7 @@

-

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Wednesday, Jul 10, 2024 using Doxygen and m.css. Contact us via GitHub.

+

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Thursday, Jul 11, 2024 using Doxygen and m.css. Contact us via GitHub.

diff --git a/classinciter_1_1_multi_mat_problem_sinewave_packet.html b/classinciter_1_1_multi_mat_problem_sinewave_packet.html index 2ded9b037999..51ccbb40d2c5 100644 --- a/classinciter_1_1_multi_mat_problem_sinewave_packet.html +++ b/classinciter_1_1_multi_mat_problem_sinewave_packet.html @@ -194,7 +194,7 @@

-

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Wednesday, Jul 10, 2024 using Doxygen and m.css. Contact us via GitHub.

+

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Thursday, Jul 11, 2024 using Doxygen and m.css. Contact us via GitHub.

diff --git a/classinciter_1_1_multi_mat_problem_sod_shocktube.html b/classinciter_1_1_multi_mat_problem_sod_shocktube.html index 7280ddfa479b..b78534f711aa 100644 --- a/classinciter_1_1_multi_mat_problem_sod_shocktube.html +++ b/classinciter_1_1_multi_mat_problem_sod_shocktube.html @@ -198,7 +198,7 @@

-

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Wednesday, Jul 10, 2024 using Doxygen and m.css. Contact us via GitHub.

+

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Thursday, Jul 11, 2024 using Doxygen and m.css. Contact us via GitHub.

diff --git a/classinciter_1_1_multi_mat_problem_underwater_ex.html b/classinciter_1_1_multi_mat_problem_underwater_ex.html index c5c4e97ef17a..4d48d586d9ac 100644 --- a/classinciter_1_1_multi_mat_problem_underwater_ex.html +++ b/classinciter_1_1_multi_mat_problem_underwater_ex.html @@ -202,7 +202,7 @@

-

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Wednesday, Jul 10, 2024 using Doxygen and m.css. Contact us via GitHub.

+

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Thursday, Jul 11, 2024 using Doxygen and m.css. Contact us via GitHub.

diff --git a/classinciter_1_1_multi_mat_problem_user_defined.html b/classinciter_1_1_multi_mat_problem_user_defined.html index 1b36dc1fec5c..988d2298236b 100644 --- a/classinciter_1_1_multi_mat_problem_user_defined.html +++ b/classinciter_1_1_multi_mat_problem_user_defined.html @@ -198,7 +198,7 @@

-

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Wednesday, Jul 10, 2024 using Doxygen and m.css. Contact us via GitHub.

+

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Thursday, Jul 11, 2024 using Doxygen and m.css. Contact us via GitHub.

diff --git a/classinciter_1_1_multi_mat_problem_water_air_shocktube.html b/classinciter_1_1_multi_mat_problem_water_air_shocktube.html index f64ae5fe16fb..59be50d0d478 100644 --- a/classinciter_1_1_multi_mat_problem_water_air_shocktube.html +++ b/classinciter_1_1_multi_mat_problem_water_air_shocktube.html @@ -185,7 +185,7 @@

-

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Wednesday, Jul 10, 2024 using Doxygen and m.css. Contact us via GitHub.

+

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Thursday, Jul 11, 2024 using Doxygen and m.css. Contact us via GitHub.

diff --git a/classinciter_1_1_node_diagnostics.html b/classinciter_1_1_node_diagnostics.html index 0213eca4b179..123d7cbe9372 100644 --- a/classinciter_1_1_node_diagnostics.html +++ b/classinciter_1_1_node_diagnostics.html @@ -241,7 +241,7 @@

-

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Wednesday, Jul 10, 2024 using Doxygen and m.css. Contact us via GitHub.

+

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Thursday, Jul 11, 2024 using Doxygen and m.css. Contact us via GitHub.

diff --git a/classinciter_1_1_overset_f_e.html b/classinciter_1_1_overset_f_e.html index e844a8370fba..3d914b45d7a9 100644 --- a/classinciter_1_1_overset_f_e.html +++ b/classinciter_1_1_overset_f_e.html @@ -739,7 +739,7 @@

-

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Wednesday, Jul 10, 2024 using Doxygen and m.css. Contact us via GitHub.

+

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Thursday, Jul 11, 2024 using Doxygen and m.css. Contact us via GitHub.

diff --git a/classinciter_1_1_p_d_e_stack.html b/classinciter_1_1_p_d_e_stack.html index 7bdf036399bf..236c2bd0a24d 100644 --- a/classinciter_1_1_p_d_e_stack.html +++ b/classinciter_1_1_p_d_e_stack.html @@ -326,7 +326,7 @@

-

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Wednesday, Jul 10, 2024 using Doxygen and m.css. Contact us via GitHub.

+

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Thursday, Jul 11, 2024 using Doxygen and m.css. Contact us via GitHub.

diff --git a/classinciter_1_1_partitioner.html b/classinciter_1_1_partitioner.html index 33f98c6bced7..e883e2763e94 100644 --- a/classinciter_1_1_partitioner.html +++ b/classinciter_1_1_partitioner.html @@ -440,7 +440,7 @@

-

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Wednesday, Jul 10, 2024 using Doxygen and m.css. Contact us via GitHub.

+

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Thursday, Jul 11, 2024 using Doxygen and m.css. Contact us via GitHub.

diff --git a/classinciter_1_1_refiner.html b/classinciter_1_1_refiner.html index 6c5a0b6ad202..0147aefcc3d4 100644 --- a/classinciter_1_1_refiner.html +++ b/classinciter_1_1_refiner.html @@ -741,7 +741,7 @@

-

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Wednesday, Jul 10, 2024 using Doxygen and m.css. Contact us via GitHub.

+

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Thursday, Jul 11, 2024 using Doxygen and m.css. Contact us via GitHub.

diff --git a/classinciter_1_1_scheme.html b/classinciter_1_1_scheme.html index 646177400b24..f864d5452902 100644 --- a/classinciter_1_1_scheme.html +++ b/classinciter_1_1_scheme.html @@ -525,7 +525,7 @@

-

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Wednesday, Jul 10, 2024 using Doxygen and m.css. Contact us via GitHub.

+

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Thursday, Jul 11, 2024 using Doxygen and m.css. Contact us via GitHub.

diff --git a/classinciter_1_1_sorter.html b/classinciter_1_1_sorter.html index 99a8412da957..7dfb8725f468 100644 --- a/classinciter_1_1_sorter.html +++ b/classinciter_1_1_sorter.html @@ -584,7 +584,7 @@

-

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Wednesday, Jul 10, 2024 using Doxygen and m.css. Contact us via GitHub.

+

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Thursday, Jul 11, 2024 using Doxygen and m.css. Contact us via GitHub.

diff --git a/classinciter_1_1_transport_problem_cyl_advect.html b/classinciter_1_1_transport_problem_cyl_advect.html index b7a27d86de43..64a0d190c1a8 100644 --- a/classinciter_1_1_transport_problem_cyl_advect.html +++ b/classinciter_1_1_transport_problem_cyl_advect.html @@ -241,7 +241,7 @@

-

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Wednesday, Jul 10, 2024 using Doxygen and m.css. Contact us via GitHub.

+

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Thursday, Jul 11, 2024 using Doxygen and m.css. Contact us via GitHub.

diff --git a/classinciter_1_1_transport_problem_cyl_vortex.html b/classinciter_1_1_transport_problem_cyl_vortex.html index 10a23fd8a706..40f1062b4fb8 100644 --- a/classinciter_1_1_transport_problem_cyl_vortex.html +++ b/classinciter_1_1_transport_problem_cyl_vortex.html @@ -254,7 +254,7 @@

-

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Wednesday, Jul 10, 2024 using Doxygen and m.css. Contact us via GitHub.

+

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Thursday, Jul 11, 2024 using Doxygen and m.css. Contact us via GitHub.

diff --git a/classinciter_1_1_transport_problem_gauss_hump.html b/classinciter_1_1_transport_problem_gauss_hump.html index d204e813d60c..9159dc3d19f5 100644 --- a/classinciter_1_1_transport_problem_gauss_hump.html +++ b/classinciter_1_1_transport_problem_gauss_hump.html @@ -241,7 +241,7 @@

-

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Wednesday, Jul 10, 2024 using Doxygen and m.css. Contact us via GitHub.

+

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Thursday, Jul 11, 2024 using Doxygen and m.css. Contact us via GitHub.

diff --git a/classinciter_1_1_transport_problem_shear_diff.html b/classinciter_1_1_transport_problem_shear_diff.html index 697a7ba608eb..628487c24d9f 100644 --- a/classinciter_1_1_transport_problem_shear_diff.html +++ b/classinciter_1_1_transport_problem_shear_diff.html @@ -538,7 +538,7 @@

-

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Wednesday, Jul 10, 2024 using Doxygen and m.css. Contact us via GitHub.

+

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Thursday, Jul 11, 2024 using Doxygen and m.css. Contact us via GitHub.

diff --git a/classinciter_1_1_transport_problem_slot_cyl.html b/classinciter_1_1_transport_problem_slot_cyl.html index 27eb98447ebe..5909e1b06e80 100644 --- a/classinciter_1_1_transport_problem_slot_cyl.html +++ b/classinciter_1_1_transport_problem_slot_cyl.html @@ -248,7 +248,7 @@

-

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Wednesday, Jul 10, 2024 using Doxygen and m.css. Contact us via GitHub.

+

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Thursday, Jul 11, 2024 using Doxygen and m.css. Contact us via GitHub.

diff --git a/classinciter_1_1_transporter.html b/classinciter_1_1_transporter.html index 323f7379e70f..f334be23d498 100644 --- a/classinciter_1_1_transporter.html +++ b/classinciter_1_1_transporter.html @@ -1136,7 +1136,7 @@

-

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Wednesday, Jul 10, 2024 using Doxygen and m.css. Contact us via GitHub.

+

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Thursday, Jul 11, 2024 using Doxygen and m.css. Contact us via GitHub.

diff --git a/classinciter_1_1cg_1_1_comp_flow.html b/classinciter_1_1cg_1_1_comp_flow.html index 5a8cd3e838ff..1833aae7170f 100644 --- a/classinciter_1_1cg_1_1_comp_flow.html +++ b/classinciter_1_1cg_1_1_comp_flow.html @@ -1081,7 +1081,7 @@

-

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Wednesday, Jul 10, 2024 using Doxygen and m.css. Contact us via GitHub.

+

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Thursday, Jul 11, 2024 using Doxygen and m.css. Contact us via GitHub.

diff --git a/classinciter_1_1cg_1_1_comp_flow_physics_euler.html b/classinciter_1_1cg_1_1_comp_flow_physics_euler.html index 356c670d0a75..23ce7fc26f43 100644 --- a/classinciter_1_1cg_1_1_comp_flow_physics_euler.html +++ b/classinciter_1_1cg_1_1_comp_flow_physics_euler.html @@ -201,7 +201,7 @@

-

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Wednesday, Jul 10, 2024 using Doxygen and m.css. Contact us via GitHub.

+

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Thursday, Jul 11, 2024 using Doxygen and m.css. Contact us via GitHub.

diff --git a/classinciter_1_1cg_1_1_comp_flow_physics_navier_stokes.html b/classinciter_1_1cg_1_1_comp_flow_physics_navier_stokes.html index 64e38532d1b6..f49a7823f453 100644 --- a/classinciter_1_1cg_1_1_comp_flow_physics_navier_stokes.html +++ b/classinciter_1_1cg_1_1_comp_flow_physics_navier_stokes.html @@ -327,7 +327,7 @@

-

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Wednesday, Jul 10, 2024 using Doxygen and m.css. Contact us via GitHub.

+

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Thursday, Jul 11, 2024 using Doxygen and m.css. Contact us via GitHub.

diff --git a/classinciter_1_1cg_1_1_transport.html b/classinciter_1_1cg_1_1_transport.html index db996234915f..4cd8372b54ee 100644 --- a/classinciter_1_1cg_1_1_transport.html +++ b/classinciter_1_1cg_1_1_transport.html @@ -782,7 +782,7 @@

-

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Wednesday, Jul 10, 2024 using Doxygen and m.css. Contact us via GitHub.

+

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Thursday, Jul 11, 2024 using Doxygen and m.css. Contact us via GitHub.

diff --git a/classinciter_1_1cg_1_1_transport_physics_adv_diff.html b/classinciter_1_1cg_1_1_transport_physics_adv_diff.html index 91dd63d7d3f6..7259d059abec 100644 --- a/classinciter_1_1cg_1_1_transport_physics_adv_diff.html +++ b/classinciter_1_1cg_1_1_transport_physics_adv_diff.html @@ -238,7 +238,7 @@

-

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Wednesday, Jul 10, 2024 using Doxygen and m.css. Contact us via GitHub.

+

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Thursday, Jul 11, 2024 using Doxygen and m.css. Contact us via GitHub.

diff --git a/classinciter_1_1cg_1_1_transport_physics_advection.html b/classinciter_1_1cg_1_1_transport_physics_advection.html index 20994081387c..812483c60e00 100644 --- a/classinciter_1_1cg_1_1_transport_physics_advection.html +++ b/classinciter_1_1cg_1_1_transport_physics_advection.html @@ -162,7 +162,7 @@

-

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Wednesday, Jul 10, 2024 using Doxygen and m.css. Contact us via GitHub.

+

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Thursday, Jul 11, 2024 using Doxygen and m.css. Contact us via GitHub.

diff --git a/classinciter_1_1ctr_1_1_a_m_r_error.html b/classinciter_1_1ctr_1_1_a_m_r_error.html index 56d295894995..3e6f17994004 100644 --- a/classinciter_1_1ctr_1_1_a_m_r_error.html +++ b/classinciter_1_1ctr_1_1_a_m_r_error.html @@ -151,7 +151,7 @@

-

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Wednesday, Jul 10, 2024 using Doxygen and m.css. Contact us via GitHub.

+

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Thursday, Jul 11, 2024 using Doxygen and m.css. Contact us via GitHub.

diff --git a/classinciter_1_1ctr_1_1_a_m_r_initial.html b/classinciter_1_1ctr_1_1_a_m_r_initial.html index 2e7242dbb7b2..a5487f7b68f5 100644 --- a/classinciter_1_1ctr_1_1_a_m_r_initial.html +++ b/classinciter_1_1ctr_1_1_a_m_r_initial.html @@ -151,7 +151,7 @@

-

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Wednesday, Jul 10, 2024 using Doxygen and m.css. Contact us via GitHub.

+

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Thursday, Jul 11, 2024 using Doxygen and m.css. Contact us via GitHub.

diff --git a/classinciter_1_1ctr_1_1_cmd_line.html b/classinciter_1_1ctr_1_1_cmd_line.html index 099e2f1394e2..d22fffbb39ae 100644 --- a/classinciter_1_1ctr_1_1_cmd_line.html +++ b/classinciter_1_1ctr_1_1_cmd_line.html @@ -274,7 +274,7 @@

-

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Wednesday, Jul 10, 2024 using Doxygen and m.css. Contact us via GitHub.

+

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Thursday, Jul 11, 2024 using Doxygen and m.css. Contact us via GitHub.

diff --git a/classinciter_1_1ctr_1_1_flux.html b/classinciter_1_1ctr_1_1_flux.html index 4cf731aaec84..104dc2630427 100644 --- a/classinciter_1_1ctr_1_1_flux.html +++ b/classinciter_1_1ctr_1_1_flux.html @@ -151,7 +151,7 @@

-

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Wednesday, Jul 10, 2024 using Doxygen and m.css. Contact us via GitHub.

+

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Thursday, Jul 11, 2024 using Doxygen and m.css. Contact us via GitHub.

diff --git a/classinciter_1_1ctr_1_1_initiate.html b/classinciter_1_1ctr_1_1_initiate.html index 1186cbf7e005..91d83f28d728 100644 --- a/classinciter_1_1ctr_1_1_initiate.html +++ b/classinciter_1_1ctr_1_1_initiate.html @@ -151,7 +151,7 @@

-

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Wednesday, Jul 10, 2024 using Doxygen and m.css. Contact us via GitHub.

+

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Thursday, Jul 11, 2024 using Doxygen and m.css. Contact us via GitHub.

diff --git a/classinciter_1_1ctr_1_1_limiter.html b/classinciter_1_1ctr_1_1_limiter.html index a127eee9f33e..349ca225e9da 100644 --- a/classinciter_1_1ctr_1_1_limiter.html +++ b/classinciter_1_1ctr_1_1_limiter.html @@ -151,7 +151,7 @@

-

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Wednesday, Jul 10, 2024 using Doxygen and m.css. Contact us via GitHub.

+

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Thursday, Jul 11, 2024 using Doxygen and m.css. Contact us via GitHub.

diff --git a/classinciter_1_1ctr_1_1_material.html b/classinciter_1_1ctr_1_1_material.html index d975449049a3..cb52c9271b2e 100644 --- a/classinciter_1_1ctr_1_1_material.html +++ b/classinciter_1_1ctr_1_1_material.html @@ -151,7 +151,7 @@

-

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Wednesday, Jul 10, 2024 using Doxygen and m.css. Contact us via GitHub.

+

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Thursday, Jul 11, 2024 using Doxygen and m.css. Contact us via GitHub.

diff --git a/classinciter_1_1ctr_1_1_mesh_velocity.html b/classinciter_1_1ctr_1_1_mesh_velocity.html index ed26e6e50160..484f187ea6b1 100644 --- a/classinciter_1_1ctr_1_1_mesh_velocity.html +++ b/classinciter_1_1ctr_1_1_mesh_velocity.html @@ -151,7 +151,7 @@

-

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Wednesday, Jul 10, 2024 using Doxygen and m.css. Contact us via GitHub.

+

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Thursday, Jul 11, 2024 using Doxygen and m.css. Contact us via GitHub.

diff --git a/classinciter_1_1ctr_1_1_mesh_velocity_smoother.html b/classinciter_1_1ctr_1_1_mesh_velocity_smoother.html index aca60cd282c8..c1ff628a829f 100644 --- a/classinciter_1_1ctr_1_1_mesh_velocity_smoother.html +++ b/classinciter_1_1ctr_1_1_mesh_velocity_smoother.html @@ -151,7 +151,7 @@

-

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Wednesday, Jul 10, 2024 using Doxygen and m.css. Contact us via GitHub.

+

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Thursday, Jul 11, 2024 using Doxygen and m.css. Contact us via GitHub.

diff --git a/classinciter_1_1ctr_1_1_p_d_e.html b/classinciter_1_1ctr_1_1_p_d_e.html index 1f455a2dbbb1..a2a35e0e84a6 100644 --- a/classinciter_1_1ctr_1_1_p_d_e.html +++ b/classinciter_1_1ctr_1_1_p_d_e.html @@ -150,7 +150,7 @@

-

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Wednesday, Jul 10, 2024 using Doxygen and m.css. Contact us via GitHub.

+

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Thursday, Jul 11, 2024 using Doxygen and m.css. Contact us via GitHub.

diff --git a/classinciter_1_1ctr_1_1_physics.html b/classinciter_1_1ctr_1_1_physics.html index 42761f1e591f..414fc7a9b2a8 100644 --- a/classinciter_1_1ctr_1_1_physics.html +++ b/classinciter_1_1ctr_1_1_physics.html @@ -151,7 +151,7 @@

-

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Wednesday, Jul 10, 2024 using Doxygen and m.css. Contact us via GitHub.

+

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Thursday, Jul 11, 2024 using Doxygen and m.css. Contact us via GitHub.

diff --git a/classinciter_1_1ctr_1_1_pref_indicator.html b/classinciter_1_1ctr_1_1_pref_indicator.html index a9149c7339da..85398bd38edc 100644 --- a/classinciter_1_1ctr_1_1_pref_indicator.html +++ b/classinciter_1_1ctr_1_1_pref_indicator.html @@ -151,7 +151,7 @@

-

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Wednesday, Jul 10, 2024 using Doxygen and m.css. Contact us via GitHub.

+

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Thursday, Jul 11, 2024 using Doxygen and m.css. Contact us via GitHub.

diff --git a/classinciter_1_1ctr_1_1_problem.html b/classinciter_1_1ctr_1_1_problem.html index 54ecd3ea7c7e..b42b9dfb32ca 100644 --- a/classinciter_1_1ctr_1_1_problem.html +++ b/classinciter_1_1ctr_1_1_problem.html @@ -151,7 +151,7 @@

-

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Wednesday, Jul 10, 2024 using Doxygen and m.css. Contact us via GitHub.

+

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Thursday, Jul 11, 2024 using Doxygen and m.css. Contact us via GitHub.

diff --git a/classinciter_1_1ctr_1_1_scheme.html b/classinciter_1_1ctr_1_1_scheme.html index 3011e5af398f..62342e511ad4 100644 --- a/classinciter_1_1ctr_1_1_scheme.html +++ b/classinciter_1_1ctr_1_1_scheme.html @@ -184,7 +184,7 @@

-

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Wednesday, Jul 10, 2024 using Doxygen and m.css. Contact us via GitHub.

+

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Thursday, Jul 11, 2024 using Doxygen and m.css. Contact us via GitHub.

diff --git a/classinciter_1_1dg_1_1_comp_flow.html b/classinciter_1_1dg_1_1_comp_flow.html index d0f46b1f9e7e..2dd2417359b5 100644 --- a/classinciter_1_1dg_1_1_comp_flow.html +++ b/classinciter_1_1dg_1_1_comp_flow.html @@ -1310,7 +1310,7 @@

-

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Wednesday, Jul 10, 2024 using Doxygen and m.css. Contact us via GitHub.

+

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Thursday, Jul 11, 2024 using Doxygen and m.css. Contact us via GitHub.

diff --git a/classinciter_1_1dg_1_1_comp_flow_physics_euler.html b/classinciter_1_1dg_1_1_comp_flow_physics_euler.html index 900512835e6b..ed623d41ebdd 100644 --- a/classinciter_1_1dg_1_1_comp_flow_physics_euler.html +++ b/classinciter_1_1dg_1_1_comp_flow_physics_euler.html @@ -147,7 +147,7 @@

-

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Wednesday, Jul 10, 2024 using Doxygen and m.css. Contact us via GitHub.

+

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Thursday, Jul 11, 2024 using Doxygen and m.css. Contact us via GitHub.

diff --git a/classinciter_1_1dg_1_1_multi_mat.html b/classinciter_1_1dg_1_1_multi_mat.html index b9aeab5de0cf..a302c21a86d9 100644 --- a/classinciter_1_1dg_1_1_multi_mat.html +++ b/classinciter_1_1dg_1_1_multi_mat.html @@ -1513,7 +1513,7 @@

-

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Wednesday, Jul 10, 2024 using Doxygen and m.css. Contact us via GitHub.

+

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Thursday, Jul 11, 2024 using Doxygen and m.css. Contact us via GitHub.

diff --git a/classinciter_1_1dg_1_1_multi_mat_physics_euler.html b/classinciter_1_1dg_1_1_multi_mat_physics_euler.html index 76242cd4d69e..446d0acbce3c 100644 --- a/classinciter_1_1dg_1_1_multi_mat_physics_euler.html +++ b/classinciter_1_1dg_1_1_multi_mat_physics_euler.html @@ -184,7 +184,7 @@

-

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Wednesday, Jul 10, 2024 using Doxygen and m.css. Contact us via GitHub.

+

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Thursday, Jul 11, 2024 using Doxygen and m.css. Contact us via GitHub.

diff --git a/classinciter_1_1dg_1_1_transport.html b/classinciter_1_1dg_1_1_transport.html index d45000d83420..ee9ab2fa2eb6 100644 --- a/classinciter_1_1dg_1_1_transport.html +++ b/classinciter_1_1dg_1_1_transport.html @@ -1169,7 +1169,7 @@

-

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Wednesday, Jul 10, 2024 using Doxygen and m.css. Contact us via GitHub.

+

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Thursday, Jul 11, 2024 using Doxygen and m.css. Contact us via GitHub.

diff --git a/classinciter_1_1dg_1_1_transport_physics_advection.html b/classinciter_1_1dg_1_1_transport_physics_advection.html index 8848d0554bd3..f8dd450a9619 100644 --- a/classinciter_1_1dg_1_1_transport_physics_advection.html +++ b/classinciter_1_1dg_1_1_transport_physics_advection.html @@ -165,7 +165,7 @@

-

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Wednesday, Jul 10, 2024 using Doxygen and m.css. Contact us via GitHub.

+

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Thursday, Jul 11, 2024 using Doxygen and m.css. Contact us via GitHub.

diff --git a/classinciter_1_1fv_1_1_multi_mat.html b/classinciter_1_1fv_1_1_multi_mat.html index 2e653a9fa3b0..c66974000172 100644 --- a/classinciter_1_1fv_1_1_multi_mat.html +++ b/classinciter_1_1fv_1_1_multi_mat.html @@ -1108,7 +1108,7 @@

-

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Wednesday, Jul 10, 2024 using Doxygen and m.css. Contact us via GitHub.

+

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Thursday, Jul 11, 2024 using Doxygen and m.css. Contact us via GitHub.

diff --git a/classinciter_1_1fv_1_1_multi_mat_physics_energy_pill.html b/classinciter_1_1fv_1_1_multi_mat_physics_energy_pill.html index cf68a4da25c9..9bde9f74f9b2 100644 --- a/classinciter_1_1fv_1_1_multi_mat_physics_energy_pill.html +++ b/classinciter_1_1fv_1_1_multi_mat_physics_energy_pill.html @@ -245,7 +245,7 @@

-

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Wednesday, Jul 10, 2024 using Doxygen and m.css. Contact us via GitHub.

+

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Thursday, Jul 11, 2024 using Doxygen and m.css. Contact us via GitHub.

diff --git a/classinciter_1_1fv_1_1_multi_mat_physics_euler.html b/classinciter_1_1fv_1_1_multi_mat_physics_euler.html index d359dbbf65d8..eb3b83bf9d20 100644 --- a/classinciter_1_1fv_1_1_multi_mat_physics_euler.html +++ b/classinciter_1_1fv_1_1_multi_mat_physics_euler.html @@ -184,7 +184,7 @@

-

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Wednesday, Jul 10, 2024 using Doxygen and m.css. Contact us via GitHub.

+

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Thursday, Jul 11, 2024 using Doxygen and m.css. Contact us via GitHub.

diff --git a/classmeshconv_1_1_cmd_line_parser.html b/classmeshconv_1_1_cmd_line_parser.html index 00a9ce9aefa4..55270b75f389 100644 --- a/classmeshconv_1_1_cmd_line_parser.html +++ b/classmeshconv_1_1_cmd_line_parser.html @@ -179,7 +179,7 @@

-

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Wednesday, Jul 10, 2024 using Doxygen and m.css. Contact us via GitHub.

+

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Thursday, Jul 11, 2024 using Doxygen and m.css. Contact us via GitHub.

diff --git a/classmeshconv_1_1_mesh_conv_driver.html b/classmeshconv_1_1_mesh_conv_driver.html index 3de8fb82c109..0b4c799a88eb 100644 --- a/classmeshconv_1_1_mesh_conv_driver.html +++ b/classmeshconv_1_1_mesh_conv_driver.html @@ -162,7 +162,7 @@

-

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Wednesday, Jul 10, 2024 using Doxygen and m.css. Contact us via GitHub.

+

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Thursday, Jul 11, 2024 using Doxygen and m.css. Contact us via GitHub.

diff --git a/classmeshconv_1_1ctr_1_1_cmd_line.html b/classmeshconv_1_1ctr_1_1_cmd_line.html index 69d10c3f0053..cb70c03662a4 100644 --- a/classmeshconv_1_1ctr_1_1_cmd_line.html +++ b/classmeshconv_1_1ctr_1_1_cmd_line.html @@ -263,7 +263,7 @@

-

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Wednesday, Jul 10, 2024 using Doxygen and m.css. Contact us via GitHub.

+

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Thursday, Jul 11, 2024 using Doxygen and m.css. Contact us via GitHub.

diff --git a/classtk_1_1_a_s_c_mesh_reader.html b/classtk_1_1_a_s_c_mesh_reader.html index af9f974c3b08..21995ed85fc0 100644 --- a/classtk_1_1_a_s_c_mesh_reader.html +++ b/classtk_1_1_a_s_c_mesh_reader.html @@ -171,7 +171,7 @@

-

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Wednesday, Jul 10, 2024 using Doxygen and m.css. Contact us via GitHub.

+

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Thursday, Jul 11, 2024 using Doxygen and m.css. Contact us via GitHub.

diff --git a/classtk_1_1_around.html b/classtk_1_1_around.html index 51414f6371a5..0bc802ea9ca1 100644 --- a/classtk_1_1_around.html +++ b/classtk_1_1_around.html @@ -234,7 +234,7 @@

-

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Wednesday, Jul 10, 2024 using Doxygen and m.css. Contact us via GitHub.

+

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Thursday, Jul 11, 2024 using Doxygen and m.css. Contact us via GitHub.

diff --git a/classtk_1_1_bi_p_d_f.html b/classtk_1_1_bi_p_d_f.html index 7f5ea002e8aa..896d0a49c7c0 100644 --- a/classtk_1_1_bi_p_d_f.html +++ b/classtk_1_1_bi_p_d_f.html @@ -368,7 +368,7 @@

-

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Wednesday, Jul 10, 2024 using Doxygen and m.css. Contact us via GitHub.

+

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Thursday, Jul 11, 2024 using Doxygen and m.css. Contact us via GitHub.

diff --git a/classtk_1_1_c_s_r.html b/classtk_1_1_c_s_r.html index 0ec861a7edf4..e5636af76519 100644 --- a/classtk_1_1_c_s_r.html +++ b/classtk_1_1_c_s_r.html @@ -467,7 +467,7 @@

-

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Wednesday, Jul 10, 2024 using Doxygen and m.css. Contact us via GitHub.

+

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Thursday, Jul 11, 2024 using Doxygen and m.css. Contact us via GitHub.

diff --git a/classtk_1_1_chare_state_collector.html b/classtk_1_1_chare_state_collector.html index a136811bf01d..727a90c949d4 100644 --- a/classtk_1_1_chare_state_collector.html +++ b/classtk_1_1_chare_state_collector.html @@ -297,7 +297,7 @@

-

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Wednesday, Jul 10, 2024 using Doxygen and m.css. Contact us via GitHub.

+

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Thursday, Jul 11, 2024 using Doxygen and m.css. Contact us via GitHub.

diff --git a/classtk_1_1_conjugate_gradients.html b/classtk_1_1_conjugate_gradients.html index fb0100754b33..bd0c920282ce 100644 --- a/classtk_1_1_conjugate_gradients.html +++ b/classtk_1_1_conjugate_gradients.html @@ -545,7 +545,7 @@

-

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Wednesday, Jul 10, 2024 using Doxygen and m.css. Contact us via GitHub.

+

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Thursday, Jul 11, 2024 using Doxygen and m.css. Contact us via GitHub.

diff --git a/classtk_1_1_data.html b/classtk_1_1_data.html index 67cb55a53fe6..303a0457672e 100644 --- a/classtk_1_1_data.html +++ b/classtk_1_1_data.html @@ -1362,7 +1362,7 @@

-

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Wednesday, Jul 10, 2024 using Doxygen and m.css. Contact us via GitHub.

+

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Thursday, Jul 11, 2024 using Doxygen and m.css. Contact us via GitHub.

diff --git a/classtk_1_1_diag_writer.html b/classtk_1_1_diag_writer.html index 375211845cf2..7828093f0fe9 100644 --- a/classtk_1_1_diag_writer.html +++ b/classtk_1_1_diag_writer.html @@ -255,7 +255,7 @@

-

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Wednesday, Jul 10, 2024 using Doxygen and m.css. Contact us via GitHub.

+

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Thursday, Jul 11, 2024 using Doxygen and m.css. Contact us via GitHub.

diff --git a/classtk_1_1_exception.html b/classtk_1_1_exception.html index 6d9589c1cbea..daac78e06c42 100644 --- a/classtk_1_1_exception.html +++ b/classtk_1_1_exception.html @@ -246,7 +246,7 @@

-

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Wednesday, Jul 10, 2024 using Doxygen and m.css. Contact us via GitHub.

+

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Thursday, Jul 11, 2024 using Doxygen and m.css. Contact us via GitHub.

diff --git a/classtk_1_1_exodus_i_i_mesh_reader.html b/classtk_1_1_exodus_i_i_mesh_reader.html index 517100cfe647..9198ae080103 100644 --- a/classtk_1_1_exodus_i_i_mesh_reader.html +++ b/classtk_1_1_exodus_i_i_mesh_reader.html @@ -764,7 +764,7 @@

-

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Wednesday, Jul 10, 2024 using Doxygen and m.css. Contact us via GitHub.

+

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Thursday, Jul 11, 2024 using Doxygen and m.css. Contact us via GitHub.

diff --git a/classtk_1_1_exodus_i_i_mesh_writer.html b/classtk_1_1_exodus_i_i_mesh_writer.html index c706933b76d9..c4dd9cf90a55 100644 --- a/classtk_1_1_exodus_i_i_mesh_writer.html +++ b/classtk_1_1_exodus_i_i_mesh_writer.html @@ -638,7 +638,7 @@

-

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Wednesday, Jul 10, 2024 using Doxygen and m.css. Contact us via GitHub.

+

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Thursday, Jul 11, 2024 using Doxygen and m.css. Contact us via GitHub.

diff --git a/classtk_1_1_gmsh_mesh_reader.html b/classtk_1_1_gmsh_mesh_reader.html index a254dd123a73..91d79222093f 100644 --- a/classtk_1_1_gmsh_mesh_reader.html +++ b/classtk_1_1_gmsh_mesh_reader.html @@ -170,7 +170,7 @@

-

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Wednesday, Jul 10, 2024 using Doxygen and m.css. Contact us via GitHub.

+

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Thursday, Jul 11, 2024 using Doxygen and m.css. Contact us via GitHub.

diff --git a/classtk_1_1_gmsh_mesh_writer.html b/classtk_1_1_gmsh_mesh_writer.html index 2657bf1baf2a..173cacd08ee0 100644 --- a/classtk_1_1_gmsh_mesh_writer.html +++ b/classtk_1_1_gmsh_mesh_writer.html @@ -205,7 +205,7 @@

-

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Wednesday, Jul 10, 2024 using Doxygen and m.css. Contact us via GitHub.

+

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Thursday, Jul 11, 2024 using Doxygen and m.css. Contact us via GitHub.

diff --git a/classtk_1_1_hyper_mesh_reader.html b/classtk_1_1_hyper_mesh_reader.html index e0b88b72aea8..85956ffac340 100644 --- a/classtk_1_1_hyper_mesh_reader.html +++ b/classtk_1_1_hyper_mesh_reader.html @@ -171,7 +171,7 @@

-

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Wednesday, Jul 10, 2024 using Doxygen and m.css. Contact us via GitHub.

+

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Thursday, Jul 11, 2024 using Doxygen and m.css. Contact us via GitHub.

diff --git a/classtk_1_1_l_b_switch.html b/classtk_1_1_l_b_switch.html index 320b92bf9452..f926f4204700 100644 --- a/classtk_1_1_l_b_switch.html +++ b/classtk_1_1_l_b_switch.html @@ -154,7 +154,7 @@

-

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Wednesday, Jul 10, 2024 using Doxygen and m.css. Contact us via GitHub.

+

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Thursday, Jul 11, 2024 using Doxygen and m.css. Contact us via GitHub.

diff --git a/classtk_1_1_linear_map.html b/classtk_1_1_linear_map.html index c973e8b32dfe..a5f5f90d281a 100644 --- a/classtk_1_1_linear_map.html +++ b/classtk_1_1_linear_map.html @@ -220,7 +220,7 @@

-

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Wednesday, Jul 10, 2024 using Doxygen and m.css. Contact us via GitHub.

+

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Thursday, Jul 11, 2024 using Doxygen and m.css. Contact us via GitHub.

diff --git a/classtk_1_1_mesh_reader.html b/classtk_1_1_mesh_reader.html index c9d8810e61d4..9f198aa91a76 100644 --- a/classtk_1_1_mesh_reader.html +++ b/classtk_1_1_mesh_reader.html @@ -221,7 +221,7 @@

-

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Wednesday, Jul 10, 2024 using Doxygen and m.css. Contact us via GitHub.

+

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Thursday, Jul 11, 2024 using Doxygen and m.css. Contact us via GitHub.

diff --git a/classtk_1_1_mesh_writer.html b/classtk_1_1_mesh_writer.html index 41c4322c40a0..e7e2c0dee26c 100644 --- a/classtk_1_1_mesh_writer.html +++ b/classtk_1_1_mesh_writer.html @@ -423,7 +423,7 @@

-

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Wednesday, Jul 10, 2024 using Doxygen and m.css. Contact us via GitHub.

+

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Thursday, Jul 11, 2024 using Doxygen and m.css. Contact us via GitHub.

diff --git a/classtk_1_1_netgen_mesh_reader.html b/classtk_1_1_netgen_mesh_reader.html index a12257042a23..aa29b3b5245e 100644 --- a/classtk_1_1_netgen_mesh_reader.html +++ b/classtk_1_1_netgen_mesh_reader.html @@ -171,7 +171,7 @@

-

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Wednesday, Jul 10, 2024 using Doxygen and m.css. Contact us via GitHub.

+

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Thursday, Jul 11, 2024 using Doxygen and m.css. Contact us via GitHub.

diff --git a/classtk_1_1_netgen_mesh_writer.html b/classtk_1_1_netgen_mesh_writer.html index 6cf0faa379b3..52f1d91018d5 100644 --- a/classtk_1_1_netgen_mesh_writer.html +++ b/classtk_1_1_netgen_mesh_writer.html @@ -170,7 +170,7 @@

-

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Wednesday, Jul 10, 2024 using Doxygen and m.css. Contact us via GitHub.

+

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Thursday, Jul 11, 2024 using Doxygen and m.css. Contact us via GitHub.

diff --git a/classtk_1_1_omega__h___mesh_reader.html b/classtk_1_1_omega__h___mesh_reader.html index b50edb76b0e8..7a79e9fb62c7 100644 --- a/classtk_1_1_omega__h___mesh_reader.html +++ b/classtk_1_1_omega__h___mesh_reader.html @@ -286,7 +286,7 @@

-

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Wednesday, Jul 10, 2024 using Doxygen and m.css. Contact us via GitHub.

+

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Thursday, Jul 11, 2024 using Doxygen and m.css. Contact us via GitHub.

diff --git a/classtk_1_1_p_d_f_writer.html b/classtk_1_1_p_d_f_writer.html index 609c78c0bb11..15f1bde66018 100644 --- a/classtk_1_1_p_d_f_writer.html +++ b/classtk_1_1_p_d_f_writer.html @@ -457,7 +457,7 @@

-

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Wednesday, Jul 10, 2024 using Doxygen and m.css. Contact us via GitHub.

+

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Thursday, Jul 11, 2024 using Doxygen and m.css. Contact us via GitHub.

diff --git a/classtk_1_1_print.html b/classtk_1_1_print.html index cd1d953e512a..9e666c3ef62b 100644 --- a/classtk_1_1_print.html +++ b/classtk_1_1_print.html @@ -1391,7 +1391,7 @@

-

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Wednesday, Jul 10, 2024 using Doxygen and m.css. Contact us via GitHub.

+

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Thursday, Jul 11, 2024 using Doxygen and m.css. Contact us via GitHub.

diff --git a/classtk_1_1_progress.html b/classtk_1_1_progress.html index 0e1b469c329b..34229f007749 100644 --- a/classtk_1_1_progress.html +++ b/classtk_1_1_progress.html @@ -297,7 +297,7 @@

-

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Wednesday, Jul 10, 2024 using Doxygen and m.css. Contact us via GitHub.

+

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Thursday, Jul 11, 2024 using Doxygen and m.css. Contact us via GitHub.

diff --git a/classtk_1_1_quiet_cerr.html b/classtk_1_1_quiet_cerr.html index df6273ae336c..9bc0176ce52e 100644 --- a/classtk_1_1_quiet_cerr.html +++ b/classtk_1_1_quiet_cerr.html @@ -150,7 +150,7 @@

-

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Wednesday, Jul 10, 2024 using Doxygen and m.css. Contact us via GitHub.

+

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Thursday, Jul 11, 2024 using Doxygen and m.css. Contact us via GitHub.

diff --git a/classtk_1_1_r_d_g_f_l_o_mesh_reader.html b/classtk_1_1_r_d_g_f_l_o_mesh_reader.html index 10dd3ba417b2..db07ce338717 100644 --- a/classtk_1_1_r_d_g_f_l_o_mesh_reader.html +++ b/classtk_1_1_r_d_g_f_l_o_mesh_reader.html @@ -171,7 +171,7 @@

-

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Wednesday, Jul 10, 2024 using Doxygen and m.css. Contact us via GitHub.

+

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Thursday, Jul 11, 2024 using Doxygen and m.css. Contact us via GitHub.

diff --git a/classtk_1_1_reader.html b/classtk_1_1_reader.html index c5367bbad695..e85a359d8201 100644 --- a/classtk_1_1_reader.html +++ b/classtk_1_1_reader.html @@ -307,7 +307,7 @@

-

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Wednesday, Jul 10, 2024 using Doxygen and m.css. Contact us via GitHub.

+

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Thursday, Jul 11, 2024 using Doxygen and m.css. Contact us via GitHub.

diff --git a/classtk_1_1_s_t_l_mesh.html b/classtk_1_1_s_t_l_mesh.html index d74352ab78b9..a6e85fd93f11 100644 --- a/classtk_1_1_s_t_l_mesh.html +++ b/classtk_1_1_s_t_l_mesh.html @@ -176,7 +176,7 @@

-

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Wednesday, Jul 10, 2024 using Doxygen and m.css. Contact us via GitHub.

+

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Thursday, Jul 11, 2024 using Doxygen and m.css. Contact us via GitHub.

diff --git a/classtk_1_1_s_t_l_txt_mesh_reader.html b/classtk_1_1_s_t_l_txt_mesh_reader.html index 0d941f74986f..3c3abfedcf48 100644 --- a/classtk_1_1_s_t_l_txt_mesh_reader.html +++ b/classtk_1_1_s_t_l_txt_mesh_reader.html @@ -177,7 +177,7 @@

-

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Wednesday, Jul 10, 2024 using Doxygen and m.css. Contact us via GitHub.

+

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Thursday, Jul 11, 2024 using Doxygen and m.css. Contact us via GitHub.

diff --git a/classtk_1_1_silo_writer.html b/classtk_1_1_silo_writer.html index 9cca0e1c0595..3848696aa9e1 100644 --- a/classtk_1_1_silo_writer.html +++ b/classtk_1_1_silo_writer.html @@ -157,7 +157,7 @@

-

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Wednesday, Jul 10, 2024 using Doxygen and m.css. Contact us via GitHub.

+

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Thursday, Jul 11, 2024 using Doxygen and m.css. Contact us via GitHub.

diff --git a/classtk_1_1_statistics.html b/classtk_1_1_statistics.html index 9a0d56044bc1..de59a1cd0eb4 100644 --- a/classtk_1_1_statistics.html +++ b/classtk_1_1_statistics.html @@ -355,7 +355,7 @@

-

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Wednesday, Jul 10, 2024 using Doxygen and m.css. Contact us via GitHub.

+

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Thursday, Jul 11, 2024 using Doxygen and m.css. Contact us via GitHub.

diff --git a/classtk_1_1_string_parser.html b/classtk_1_1_string_parser.html index b4edbc484b13..45b7fe6545e9 100644 --- a/classtk_1_1_string_parser.html +++ b/classtk_1_1_string_parser.html @@ -237,7 +237,7 @@

-

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Wednesday, Jul 10, 2024 using Doxygen and m.css. Contact us via GitHub.

+

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Thursday, Jul 11, 2024 using Doxygen and m.css. Contact us via GitHub.

diff --git a/classtk_1_1_tagged_tuple.html b/classtk_1_1_tagged_tuple.html index 1fafce8ab087..48d05dc718a5 100644 --- a/classtk_1_1_tagged_tuple.html +++ b/classtk_1_1_tagged_tuple.html @@ -404,7 +404,7 @@

-

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Wednesday, Jul 10, 2024 using Doxygen and m.css. Contact us via GitHub.

+

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Thursday, Jul 11, 2024 using Doxygen and m.css. Contact us via GitHub.

diff --git a/classtk_1_1_timer.html b/classtk_1_1_timer.html index 5eddd9cec7b4..6954d7f2c078 100644 --- a/classtk_1_1_timer.html +++ b/classtk_1_1_timer.html @@ -294,7 +294,7 @@

-

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Wednesday, Jul 10, 2024 using Doxygen and m.css. Contact us via GitHub.

+

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Thursday, Jul 11, 2024 using Doxygen and m.css. Contact us via GitHub.

diff --git a/classtk_1_1_toggle.html b/classtk_1_1_toggle.html index 23e2aa4d294f..9c43f379a029 100644 --- a/classtk_1_1_toggle.html +++ b/classtk_1_1_toggle.html @@ -278,7 +278,7 @@

-

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Wednesday, Jul 10, 2024 using Doxygen and m.css. Contact us via GitHub.

+

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Thursday, Jul 11, 2024 using Doxygen and m.css. Contact us via GitHub.

diff --git a/classtk_1_1_tri_p_d_f.html b/classtk_1_1_tri_p_d_f.html index 698f56a68cd3..9006b2888618 100644 --- a/classtk_1_1_tri_p_d_f.html +++ b/classtk_1_1_tri_p_d_f.html @@ -368,7 +368,7 @@

-

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Wednesday, Jul 10, 2024 using Doxygen and m.css. Contact us via GitHub.

+

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Thursday, Jul 11, 2024 using Doxygen and m.css. Contact us via GitHub.

diff --git a/classtk_1_1_txt_stat_writer.html b/classtk_1_1_txt_stat_writer.html index 95c55590e8a3..bc8edf3c6749 100644 --- a/classtk_1_1_txt_stat_writer.html +++ b/classtk_1_1_txt_stat_writer.html @@ -269,7 +269,7 @@

-

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Wednesday, Jul 10, 2024 using Doxygen and m.css. Contact us via GitHub.

+

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Thursday, Jul 11, 2024 using Doxygen and m.css. Contact us via GitHub.

diff --git a/classtk_1_1_u_g_r_i_d_mesh_reader.html b/classtk_1_1_u_g_r_i_d_mesh_reader.html index 61113f64c418..b409cffd49c9 100644 --- a/classtk_1_1_u_g_r_i_d_mesh_reader.html +++ b/classtk_1_1_u_g_r_i_d_mesh_reader.html @@ -171,7 +171,7 @@

-

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Wednesday, Jul 10, 2024 using Doxygen and m.css. Contact us via GitHub.

+

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Thursday, Jul 11, 2024 using Doxygen and m.css. Contact us via GitHub.

diff --git a/classtk_1_1_uni_p_d_f.html b/classtk_1_1_uni_p_d_f.html index 8d3fd202cb73..84538a69bd32 100644 --- a/classtk_1_1_uni_p_d_f.html +++ b/classtk_1_1_uni_p_d_f.html @@ -386,7 +386,7 @@

-

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Wednesday, Jul 10, 2024 using Doxygen and m.css. Contact us via GitHub.

+

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Thursday, Jul 11, 2024 using Doxygen and m.css. Contact us via GitHub.

diff --git a/classtk_1_1_uns_mesh.html b/classtk_1_1_uns_mesh.html index 3ce42dc1cfe1..880c195916d9 100644 --- a/classtk_1_1_uns_mesh.html +++ b/classtk_1_1_uns_mesh.html @@ -274,7 +274,7 @@

-

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Wednesday, Jul 10, 2024 using Doxygen and m.css. Contact us via GitHub.

+

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Thursday, Jul 11, 2024 using Doxygen and m.css. Contact us via GitHub.

diff --git a/classtk_1_1_uns_mesh_map.html b/classtk_1_1_uns_mesh_map.html index dc7b1f1a7eb6..71c94d723dd2 100644 --- a/classtk_1_1_uns_mesh_map.html +++ b/classtk_1_1_uns_mesh_map.html @@ -227,7 +227,7 @@

-

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Wednesday, Jul 10, 2024 using Doxygen and m.css. Contact us via GitHub.

+

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Thursday, Jul 11, 2024 using Doxygen and m.css. Contact us via GitHub.

diff --git a/classtk_1_1_writer.html b/classtk_1_1_writer.html index 4332c4691d16..2af4149d3281 100644 --- a/classtk_1_1_writer.html +++ b/classtk_1_1_writer.html @@ -240,7 +240,7 @@

-

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Wednesday, Jul 10, 2024 using Doxygen and m.css. Contact us via GitHub.

+

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Thursday, Jul 11, 2024 using Doxygen and m.css. Contact us via GitHub.

diff --git a/classtk_1_1cmd__keywords.html b/classtk_1_1cmd__keywords.html index 3df0427c0e64..bb67f8e6ace0 100644 --- a/classtk_1_1cmd__keywords.html +++ b/classtk_1_1cmd__keywords.html @@ -111,7 +111,7 @@

-

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Wednesday, Jul 10, 2024 using Doxygen and m.css. Contact us via GitHub.

+

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Thursday, Jul 11, 2024 using Doxygen and m.css. Contact us via GitHub.

diff --git a/classtk_1_1ctr_1_1_error.html b/classtk_1_1ctr_1_1_error.html index ae1be9694761..f95fc8cf2d02 100644 --- a/classtk_1_1ctr_1_1_error.html +++ b/classtk_1_1ctr_1_1_error.html @@ -151,7 +151,7 @@

-

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Wednesday, Jul 10, 2024 using Doxygen and m.css. Contact us via GitHub.

+

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Thursday, Jul 11, 2024 using Doxygen and m.css. Contact us via GitHub.

diff --git a/classtk_1_1ctr_1_1_field_file.html b/classtk_1_1ctr_1_1_field_file.html index 9afe0c8e2047..681ef25e8b84 100644 --- a/classtk_1_1ctr_1_1_field_file.html +++ b/classtk_1_1ctr_1_1_field_file.html @@ -151,7 +151,7 @@

-

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Wednesday, Jul 10, 2024 using Doxygen and m.css. Contact us via GitHub.

+

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Thursday, Jul 11, 2024 using Doxygen and m.css. Contact us via GitHub.

diff --git a/classtk_1_1ctr_1_1_p_d_f_centering.html b/classtk_1_1ctr_1_1_p_d_f_centering.html index 60a439fcf01e..00a831bd3a88 100644 --- a/classtk_1_1ctr_1_1_p_d_f_centering.html +++ b/classtk_1_1ctr_1_1_p_d_f_centering.html @@ -151,7 +151,7 @@

-

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Wednesday, Jul 10, 2024 using Doxygen and m.css. Contact us via GitHub.

+

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Thursday, Jul 11, 2024 using Doxygen and m.css. Contact us via GitHub.

diff --git a/classtk_1_1ctr_1_1_partitioning_algorithm.html b/classtk_1_1ctr_1_1_partitioning_algorithm.html index 6cbc86ec90a2..607146b803c8 100644 --- a/classtk_1_1ctr_1_1_partitioning_algorithm.html +++ b/classtk_1_1ctr_1_1_partitioning_algorithm.html @@ -211,7 +211,7 @@

-

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Wednesday, Jul 10, 2024 using Doxygen and m.css. Contact us via GitHub.

+

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Thursday, Jul 11, 2024 using Doxygen and m.css. Contact us via GitHub.

diff --git a/classtk_1_1ctr_1_1_txt_float_format.html b/classtk_1_1ctr_1_1_txt_float_format.html index 5e2d82bddce8..7d8e4616abdb 100644 --- a/classtk_1_1ctr_1_1_txt_float_format.html +++ b/classtk_1_1ctr_1_1_txt_float_format.html @@ -151,7 +151,7 @@

-

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Wednesday, Jul 10, 2024 using Doxygen and m.css. Contact us via GitHub.

+

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Thursday, Jul 11, 2024 using Doxygen and m.css. Contact us via GitHub.

diff --git a/classtk_1_1ctr_1_1_user_table.html b/classtk_1_1ctr_1_1_user_table.html index ea07318b36ea..ea329a7b1ae6 100644 --- a/classtk_1_1ctr_1_1_user_table.html +++ b/classtk_1_1ctr_1_1_user_table.html @@ -151,7 +151,7 @@

-

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Wednesday, Jul 10, 2024 using Doxygen and m.css. Contact us via GitHub.

+

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Thursday, Jul 11, 2024 using Doxygen and m.css. Contact us via GitHub.

diff --git a/classtk_1_1zoltan_1_1_geometric_mesh_elem_adapter.html b/classtk_1_1zoltan_1_1_geometric_mesh_elem_adapter.html index d7f7d6f3b303..d6221e80f5b9 100644 --- a/classtk_1_1zoltan_1_1_geometric_mesh_elem_adapter.html +++ b/classtk_1_1zoltan_1_1_geometric_mesh_elem_adapter.html @@ -304,7 +304,7 @@

-

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Wednesday, Jul 10, 2024 using Doxygen and m.css. Contact us via GitHub.

+

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Thursday, Jul 11, 2024 using Doxygen and m.css. Contact us via GitHub.

diff --git a/classtut_1_1_test_array.html b/classtut_1_1_test_array.html index 41cdf5c88aee..6b500eabcd9b 100644 --- a/classtut_1_1_test_array.html +++ b/classtut_1_1_test_array.html @@ -110,7 +110,7 @@

-

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Wednesday, Jul 10, 2024 using Doxygen and m.css. Contact us via GitHub.

+

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Thursday, Jul 11, 2024 using Doxygen and m.css. Contact us via GitHub.

diff --git a/classunittest_1_1_cmd_line_parser.html b/classunittest_1_1_cmd_line_parser.html index 7c0f2cd67602..10a97d19498c 100644 --- a/classunittest_1_1_cmd_line_parser.html +++ b/classunittest_1_1_cmd_line_parser.html @@ -185,7 +185,7 @@

-

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Wednesday, Jul 10, 2024 using Doxygen and m.css. Contact us via GitHub.

+

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Thursday, Jul 11, 2024 using Doxygen and m.css. Contact us via GitHub.

diff --git a/classunittest_1_1_m_p_i_runner.html b/classunittest_1_1_m_p_i_runner.html index 918fb4e8b4ab..19e441d2e0c0 100644 --- a/classunittest_1_1_m_p_i_runner.html +++ b/classunittest_1_1_m_p_i_runner.html @@ -141,7 +141,7 @@

Public functions

-

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Wednesday, Jul 10, 2024 using Doxygen and m.css. Contact us via GitHub.

+

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Thursday, Jul 11, 2024 using Doxygen and m.css. Contact us via GitHub.

diff --git a/classunittest_1_1_t_u_t_suite.html b/classunittest_1_1_t_u_t_suite.html index 92e6a045a547..0f946fd81c6b 100644 --- a/classunittest_1_1_t_u_t_suite.html +++ b/classunittest_1_1_t_u_t_suite.html @@ -160,7 +160,7 @@

-

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Wednesday, Jul 10, 2024 using Doxygen and m.css. Contact us via GitHub.

+

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Thursday, Jul 11, 2024 using Doxygen and m.css. Contact us via GitHub.

diff --git a/classunittest_1_1_t_u_t_test.html b/classunittest_1_1_t_u_t_test.html index 9526de343110..eff36598b74f 100644 --- a/classunittest_1_1_t_u_t_test.html +++ b/classunittest_1_1_t_u_t_test.html @@ -166,7 +166,7 @@

-

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Wednesday, Jul 10, 2024 using Doxygen and m.css. Contact us via GitHub.

+

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Thursday, Jul 11, 2024 using Doxygen and m.css. Contact us via GitHub.

diff --git a/classunittest_1_1_unit_test_driver.html b/classunittest_1_1_unit_test_driver.html index 9371f3660281..beca355241b9 100644 --- a/classunittest_1_1_unit_test_driver.html +++ b/classunittest_1_1_unit_test_driver.html @@ -162,7 +162,7 @@

-

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Wednesday, Jul 10, 2024 using Doxygen and m.css. Contact us via GitHub.

+

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Thursday, Jul 11, 2024 using Doxygen and m.css. Contact us via GitHub.

diff --git a/classunittest_1_1_unit_test_print.html b/classunittest_1_1_unit_test_print.html index cacc8f106554..44fbb95d0cb8 100644 --- a/classunittest_1_1_unit_test_print.html +++ b/classunittest_1_1_unit_test_print.html @@ -225,7 +225,7 @@

-

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Wednesday, Jul 10, 2024 using Doxygen and m.css. Contact us via GitHub.

+

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Thursday, Jul 11, 2024 using Doxygen and m.css. Contact us via GitHub.

diff --git a/classunittest_1_1ctr_1_1_cmd_line.html b/classunittest_1_1ctr_1_1_cmd_line.html index 9ce03f47114f..7591e485cdf9 100644 --- a/classunittest_1_1ctr_1_1_cmd_line.html +++ b/classunittest_1_1ctr_1_1_cmd_line.html @@ -262,7 +262,7 @@

-

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Wednesday, Jul 10, 2024 using Doxygen and m.css. Contact us via GitHub.

+

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Thursday, Jul 11, 2024 using Doxygen and m.css. Contact us via GitHub.

diff --git a/conjugategradients_8decl_8h.html b/conjugategradients_8decl_8h.html index 179defc287af..6cb38ca170cc 100644 --- a/conjugategradients_8decl_8h.html +++ b/conjugategradients_8decl_8h.html @@ -111,7 +111,7 @@

-

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Wednesday, Jul 10, 2024 using Doxygen and m.css. Contact us via GitHub.

+

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Thursday, Jul 11, 2024 using Doxygen and m.css. Contact us via GitHub.

diff --git a/conjugategradients_8def_8h.html b/conjugategradients_8def_8h.html index 7761177ddb50..5e3f0d6864f0 100644 --- a/conjugategradients_8def_8h.html +++ b/conjugategradients_8def_8h.html @@ -111,7 +111,7 @@

-

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Wednesday, Jul 10, 2024 using Doxygen and m.css. Contact us via GitHub.

+

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Thursday, Jul 11, 2024 using Doxygen and m.css. Contact us via GitHub.

diff --git a/contributing.html b/contributing.html index 8d0d349ffd94..cb7417ec6b71 100644 --- a/contributing.html +++ b/contributing.html @@ -179,7 +179,7 @@

Contents

-

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Wednesday, Jul 10, 2024 using Doxygen and m.css. Contact us via GitHub.

+

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Thursday, Jul 11, 2024 using Doxygen and m.css. Contact us via GitHub.

diff --git a/coverage.html b/coverage.html index 086f950dc5c0..97a83f67ef14 100644 --- a/coverage.html +++ b/coverage.html @@ -110,7 +110,7 @@

-

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Wednesday, Jul 10, 2024 using Doxygen and m.css. Contact us via GitHub.

+

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Thursday, Jul 11, 2024 using Doxygen and m.css. Contact us via GitHub.

diff --git a/devpage.html b/devpage.html index 6e725f607f5d..9f5d5bfcda50 100644 --- a/devpage.html +++ b/devpage.html @@ -118,7 +118,7 @@

-

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Wednesday, Jul 10, 2024 using Doxygen and m.css. Contact us via GitHub.

+

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Thursday, Jul 11, 2024 using Doxygen and m.css. Contact us via GitHub.

diff --git a/dg_8decl_8h.html b/dg_8decl_8h.html index 2b2a93136084..516b625f3d8c 100644 --- a/dg_8decl_8h.html +++ b/dg_8decl_8h.html @@ -111,7 +111,7 @@

-

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Wednesday, Jul 10, 2024 using Doxygen and m.css. Contact us via GitHub.

+

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Thursday, Jul 11, 2024 using Doxygen and m.css. Contact us via GitHub.

diff --git a/dg_8def_8h.html b/dg_8def_8h.html index 0d614b8f56d9..942abf12493e 100644 --- a/dg_8def_8h.html +++ b/dg_8def_8h.html @@ -111,7 +111,7 @@

-

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Wednesday, Jul 10, 2024 using Doxygen and m.css. Contact us via GitHub.

+

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Thursday, Jul 11, 2024 using Doxygen and m.css. Contact us via GitHub.

diff --git a/dir_13d798715fda4433a0299a6c8832bf45.html b/dir_13d798715fda4433a0299a6c8832bf45.html index 8fb1657474f5..7b40abdbab0c 100644 --- a/dir_13d798715fda4433a0299a6c8832bf45.html +++ b/dir_13d798715fda4433a0299a6c8832bf45.html @@ -134,7 +134,7 @@

Files

-

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Wednesday, Jul 10, 2024 using Doxygen and m.css. Contact us via GitHub.

+

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Thursday, Jul 11, 2024 using Doxygen and m.css. Contact us via GitHub.

diff --git a/dir_19ebcd79566bd9d5af8712d1523798e6.html b/dir_19ebcd79566bd9d5af8712d1523798e6.html index d0d2f76b510e..66734ee3c9d7 100644 --- a/dir_19ebcd79566bd9d5af8712d1523798e6.html +++ b/dir_19ebcd79566bd9d5af8712d1523798e6.html @@ -132,7 +132,7 @@

Files

-

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Wednesday, Jul 10, 2024 using Doxygen and m.css. Contact us via GitHub.

+

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Thursday, Jul 11, 2024 using Doxygen and m.css. Contact us via GitHub.

diff --git a/dir_1e433848fca829bd41af888ccc0f9cfa.html b/dir_1e433848fca829bd41af888ccc0f9cfa.html index 5f448cd4e4be..e70be794cb49 100644 --- a/dir_1e433848fca829bd41af888ccc0f9cfa.html +++ b/dir_1e433848fca829bd41af888ccc0f9cfa.html @@ -132,7 +132,7 @@

Files

-

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Wednesday, Jul 10, 2024 using Doxygen and m.css. Contact us via GitHub.

+

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Thursday, Jul 11, 2024 using Doxygen and m.css. Contact us via GitHub.

diff --git a/dir_2d3de2c14f6dcf1f72cbfea9e0787976.html b/dir_2d3de2c14f6dcf1f72cbfea9e0787976.html index 10f26aa9aad3..59aeec31f227 100644 --- a/dir_2d3de2c14f6dcf1f72cbfea9e0787976.html +++ b/dir_2d3de2c14f6dcf1f72cbfea9e0787976.html @@ -141,7 +141,7 @@

Files

-

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Wednesday, Jul 10, 2024 using Doxygen and m.css. Contact us via GitHub.

+

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Thursday, Jul 11, 2024 using Doxygen and m.css. Contact us via GitHub.

diff --git a/dir_2f0ae6e2319a99a416c85ff6c9edaa0c.html b/dir_2f0ae6e2319a99a416c85ff6c9edaa0c.html index 5c7ca00b39ef..a4c1e9c41206 100644 --- a/dir_2f0ae6e2319a99a416c85ff6c9edaa0c.html +++ b/dir_2f0ae6e2319a99a416c85ff6c9edaa0c.html @@ -136,7 +136,7 @@

Files

-

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Wednesday, Jul 10, 2024 using Doxygen and m.css. Contact us via GitHub.

+

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Thursday, Jul 11, 2024 using Doxygen and m.css. Contact us via GitHub.

diff --git a/dir_379df5382f4b465cfe90494dfa9647c0.html b/dir_379df5382f4b465cfe90494dfa9647c0.html index fc5a1a2083e3..beae80e4caca 100644 --- a/dir_379df5382f4b465cfe90494dfa9647c0.html +++ b/dir_379df5382f4b465cfe90494dfa9647c0.html @@ -138,7 +138,7 @@

Files

-

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Wednesday, Jul 10, 2024 using Doxygen and m.css. Contact us via GitHub.

+

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Thursday, Jul 11, 2024 using Doxygen and m.css. Contact us via GitHub.

diff --git a/dir_3e32a96ce5cfcb0c73109361e7fa459f.html b/dir_3e32a96ce5cfcb0c73109361e7fa459f.html index fb5cf6fe9541..5ed1f7173fa0 100644 --- a/dir_3e32a96ce5cfcb0c73109361e7fa459f.html +++ b/dir_3e32a96ce5cfcb0c73109361e7fa459f.html @@ -153,7 +153,7 @@

Files

-

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Wednesday, Jul 10, 2024 using Doxygen and m.css. Contact us via GitHub.

+

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Thursday, Jul 11, 2024 using Doxygen and m.css. Contact us via GitHub.

diff --git a/dir_3ff0826a6d651abbf0f532354e1ac7dc.html b/dir_3ff0826a6d651abbf0f532354e1ac7dc.html index 933a5810b2ca..9f76d3e707d9 100644 --- a/dir_3ff0826a6d651abbf0f532354e1ac7dc.html +++ b/dir_3ff0826a6d651abbf0f532354e1ac7dc.html @@ -159,7 +159,7 @@

Files

-

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Wednesday, Jul 10, 2024 using Doxygen and m.css. Contact us via GitHub.

+

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Thursday, Jul 11, 2024 using Doxygen and m.css. Contact us via GitHub.

diff --git a/dir_4814b1a558d470c33d85e65dbde02eaa.html b/dir_4814b1a558d470c33d85e65dbde02eaa.html index baae11605cda..4f00e9ae25b7 100644 --- a/dir_4814b1a558d470c33d85e65dbde02eaa.html +++ b/dir_4814b1a558d470c33d85e65dbde02eaa.html @@ -211,7 +211,7 @@

Files

-

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Wednesday, Jul 10, 2024 using Doxygen and m.css. Contact us via GitHub.

+

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Thursday, Jul 11, 2024 using Doxygen and m.css. Contact us via GitHub.

diff --git a/dir_4bb77202a85366e5a69049a6555c5ad7.html b/dir_4bb77202a85366e5a69049a6555c5ad7.html index 24d56b044426..ce0f33118257 100644 --- a/dir_4bb77202a85366e5a69049a6555c5ad7.html +++ b/dir_4bb77202a85366e5a69049a6555c5ad7.html @@ -159,7 +159,7 @@

Files

-

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Wednesday, Jul 10, 2024 using Doxygen and m.css. Contact us via GitHub.

+

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Thursday, Jul 11, 2024 using Doxygen and m.css. Contact us via GitHub.

diff --git a/dir_606df7a4664720c111e6e5b0e11c4e03.html b/dir_606df7a4664720c111e6e5b0e11c4e03.html index 562d8092c0b2..b1e75ec11a74 100644 --- a/dir_606df7a4664720c111e6e5b0e11c4e03.html +++ b/dir_606df7a4664720c111e6e5b0e11c4e03.html @@ -215,7 +215,7 @@

Files

-

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Wednesday, Jul 10, 2024 using Doxygen and m.css. Contact us via GitHub.

+

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Thursday, Jul 11, 2024 using Doxygen and m.css. Contact us via GitHub.

diff --git a/dir_68267d1309a1af8e8297ef4c3efbcdba.html b/dir_68267d1309a1af8e8297ef4c3efbcdba.html index e2cc07bcc86d..ed55c8f80ed9 100644 --- a/dir_68267d1309a1af8e8297ef4c3efbcdba.html +++ b/dir_68267d1309a1af8e8297ef4c3efbcdba.html @@ -147,7 +147,7 @@

Directories

-

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Wednesday, Jul 10, 2024 using Doxygen and m.css. Contact us via GitHub.

+

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Thursday, Jul 11, 2024 using Doxygen and m.css. Contact us via GitHub.

diff --git a/dir_6a65f8253cb19bc66f63ef1cca2dfcf2.html b/dir_6a65f8253cb19bc66f63ef1cca2dfcf2.html index b352663dc579..352fabaea236 100644 --- a/dir_6a65f8253cb19bc66f63ef1cca2dfcf2.html +++ b/dir_6a65f8253cb19bc66f63ef1cca2dfcf2.html @@ -153,7 +153,7 @@

Files

-

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Wednesday, Jul 10, 2024 using Doxygen and m.css. Contact us via GitHub.

+

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Thursday, Jul 11, 2024 using Doxygen and m.css. Contact us via GitHub.

diff --git a/dir_7004285ef73e7a5a0c2a82cddef3b877.html b/dir_7004285ef73e7a5a0c2a82cddef3b877.html index b8ba289d1fbf..300f134fefe3 100644 --- a/dir_7004285ef73e7a5a0c2a82cddef3b877.html +++ b/dir_7004285ef73e7a5a0c2a82cddef3b877.html @@ -128,7 +128,7 @@

Files

-

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Wednesday, Jul 10, 2024 using Doxygen and m.css. Contact us via GitHub.

+

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Thursday, Jul 11, 2024 using Doxygen and m.css. Contact us via GitHub.

diff --git a/dir_73e08412f24265c508c9e5aa551994ab.html b/dir_73e08412f24265c508c9e5aa551994ab.html index 2602c2df8354..544710e3f89d 100644 --- a/dir_73e08412f24265c508c9e5aa551994ab.html +++ b/dir_73e08412f24265c508c9e5aa551994ab.html @@ -138,7 +138,7 @@

Files

-

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Wednesday, Jul 10, 2024 using Doxygen and m.css. Contact us via GitHub.

+

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Thursday, Jul 11, 2024 using Doxygen and m.css. Contact us via GitHub.

diff --git a/dir_7711e90abc3d4bd55823d9013a185d04.html b/dir_7711e90abc3d4bd55823d9013a185d04.html index 1c96d13f66e4..12c17f096dc7 100644 --- a/dir_7711e90abc3d4bd55823d9013a185d04.html +++ b/dir_7711e90abc3d4bd55823d9013a185d04.html @@ -138,7 +138,7 @@

Directories

-

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Wednesday, Jul 10, 2024 using Doxygen and m.css. Contact us via GitHub.

+

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Thursday, Jul 11, 2024 using Doxygen and m.css. Contact us via GitHub.

diff --git a/dir_7e34f0efff2ff25c5f7cf9ee4af7a0ce.html b/dir_7e34f0efff2ff25c5f7cf9ee4af7a0ce.html index 7f36c614dfac..431966679721 100644 --- a/dir_7e34f0efff2ff25c5f7cf9ee4af7a0ce.html +++ b/dir_7e34f0efff2ff25c5f7cf9ee4af7a0ce.html @@ -318,7 +318,7 @@

Files

-

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Wednesday, Jul 10, 2024 using Doxygen and m.css. Contact us via GitHub.

+

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Thursday, Jul 11, 2024 using Doxygen and m.css. Contact us via GitHub.

diff --git a/dir_83a162011e887f70971d455fc16baea1.html b/dir_83a162011e887f70971d455fc16baea1.html index e8050f881f6e..e8aea14ae2a7 100644 --- a/dir_83a162011e887f70971d455fc16baea1.html +++ b/dir_83a162011e887f70971d455fc16baea1.html @@ -138,7 +138,7 @@

Files

-

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Wednesday, Jul 10, 2024 using Doxygen and m.css. Contact us via GitHub.

+

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Thursday, Jul 11, 2024 using Doxygen and m.css. Contact us via GitHub.

diff --git a/dir_936b9682310f724bddf97f7d4ce83a00.html b/dir_936b9682310f724bddf97f7d4ce83a00.html index bee211622092..c57d19fa4ebc 100644 --- a/dir_936b9682310f724bddf97f7d4ce83a00.html +++ b/dir_936b9682310f724bddf97f7d4ce83a00.html @@ -140,7 +140,7 @@

Files

-

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Wednesday, Jul 10, 2024 using Doxygen and m.css. Contact us via GitHub.

+

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Thursday, Jul 11, 2024 using Doxygen and m.css. Contact us via GitHub.

diff --git a/dir_95fc3c41be4c0cbce8d98b405b0f786e.html b/dir_95fc3c41be4c0cbce8d98b405b0f786e.html index fa3128a9bbce..7c4aa5d954b2 100644 --- a/dir_95fc3c41be4c0cbce8d98b405b0f786e.html +++ b/dir_95fc3c41be4c0cbce8d98b405b0f786e.html @@ -139,7 +139,7 @@

Files

-

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Wednesday, Jul 10, 2024 using Doxygen and m.css. Contact us via GitHub.

+

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Thursday, Jul 11, 2024 using Doxygen and m.css. Contact us via GitHub.

diff --git a/dir_a33b8d5cd59301f878bc360d154d6b93.html b/dir_a33b8d5cd59301f878bc360d154d6b93.html index 5bc8d3a39564..fbb7f10f228f 100644 --- a/dir_a33b8d5cd59301f878bc360d154d6b93.html +++ b/dir_a33b8d5cd59301f878bc360d154d6b93.html @@ -146,7 +146,7 @@

Files

-

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Wednesday, Jul 10, 2024 using Doxygen and m.css. Contact us via GitHub.

+

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Thursday, Jul 11, 2024 using Doxygen and m.css. Contact us via GitHub.

diff --git a/dir_a7d3fc9833d19f1732958458500091a7.html b/dir_a7d3fc9833d19f1732958458500091a7.html index 204790474b59..6a90e28c379a 100644 --- a/dir_a7d3fc9833d19f1732958458500091a7.html +++ b/dir_a7d3fc9833d19f1732958458500091a7.html @@ -172,7 +172,7 @@

Files

-

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Wednesday, Jul 10, 2024 using Doxygen and m.css. Contact us via GitHub.

+

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Thursday, Jul 11, 2024 using Doxygen and m.css. Contact us via GitHub.

diff --git a/dir_abaaa97aff342a5e0dc26bdf647473a5.html b/dir_abaaa97aff342a5e0dc26bdf647473a5.html index 49138a48b5a6..236531a9cee9 100644 --- a/dir_abaaa97aff342a5e0dc26bdf647473a5.html +++ b/dir_abaaa97aff342a5e0dc26bdf647473a5.html @@ -131,7 +131,7 @@

Files

-

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Wednesday, Jul 10, 2024 using Doxygen and m.css. Contact us via GitHub.

+

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Thursday, Jul 11, 2024 using Doxygen and m.css. Contact us via GitHub.

diff --git a/dir_bafcf941b40b7d0d5330a9c54a31c787.html b/dir_bafcf941b40b7d0d5330a9c54a31c787.html index 5e334f683990..e4a4528e0b13 100644 --- a/dir_bafcf941b40b7d0d5330a9c54a31c787.html +++ b/dir_bafcf941b40b7d0d5330a9c54a31c787.html @@ -151,7 +151,7 @@

Files

-

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Wednesday, Jul 10, 2024 using Doxygen and m.css. Contact us via GitHub.

+

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Thursday, Jul 11, 2024 using Doxygen and m.css. Contact us via GitHub.

diff --git a/dir_c42e8e1db41a5c55bc3abc8781af4c5a.html b/dir_c42e8e1db41a5c55bc3abc8781af4c5a.html index 0844b2ddc0f4..f2e569c0499e 100644 --- a/dir_c42e8e1db41a5c55bc3abc8781af4c5a.html +++ b/dir_c42e8e1db41a5c55bc3abc8781af4c5a.html @@ -152,7 +152,7 @@

Files

-

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Wednesday, Jul 10, 2024 using Doxygen and m.css. Contact us via GitHub.

+

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Thursday, Jul 11, 2024 using Doxygen and m.css. Contact us via GitHub.

diff --git a/dir_c78c083e0d54693d20bf35994c289174.html b/dir_c78c083e0d54693d20bf35994c289174.html index 7983d15a622f..805ae4b1c897 100644 --- a/dir_c78c083e0d54693d20bf35994c289174.html +++ b/dir_c78c083e0d54693d20bf35994c289174.html @@ -176,7 +176,7 @@

Files

-

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Wednesday, Jul 10, 2024 using Doxygen and m.css. Contact us via GitHub.

+

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Thursday, Jul 11, 2024 using Doxygen and m.css. Contact us via GitHub.

diff --git a/dir_c8520f8112b2b369594b20d3f1a9fecd.html b/dir_c8520f8112b2b369594b20d3f1a9fecd.html index 20c841fb653c..8f7048ca4e15 100644 --- a/dir_c8520f8112b2b369594b20d3f1a9fecd.html +++ b/dir_c8520f8112b2b369594b20d3f1a9fecd.html @@ -136,7 +136,7 @@

Files

-

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Wednesday, Jul 10, 2024 using Doxygen and m.css. Contact us via GitHub.

+

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Thursday, Jul 11, 2024 using Doxygen and m.css. Contact us via GitHub.

diff --git a/dir_cb9c0086b2e3c9b51938866b3587b856.html b/dir_cb9c0086b2e3c9b51938866b3587b856.html index 02111c4c3399..6e2322c95b95 100644 --- a/dir_cb9c0086b2e3c9b51938866b3587b856.html +++ b/dir_cb9c0086b2e3c9b51938866b3587b856.html @@ -143,7 +143,7 @@

Files

-

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Wednesday, Jul 10, 2024 using Doxygen and m.css. Contact us via GitHub.

+

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Thursday, Jul 11, 2024 using Doxygen and m.css. Contact us via GitHub.

diff --git a/dir_cbcae074a3753bd117e58cc85ba409e3.html b/dir_cbcae074a3753bd117e58cc85ba409e3.html index 9cfcfc30a574..d218fd66cfa1 100644 --- a/dir_cbcae074a3753bd117e58cc85ba409e3.html +++ b/dir_cbcae074a3753bd117e58cc85ba409e3.html @@ -158,7 +158,7 @@

Files

-

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Wednesday, Jul 10, 2024 using Doxygen and m.css. Contact us via GitHub.

+

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Thursday, Jul 11, 2024 using Doxygen and m.css. Contact us via GitHub.

diff --git a/dir_d518b3d349cd0cf21cb3fe334b142b00.html b/dir_d518b3d349cd0cf21cb3fe334b142b00.html index b3e2e7ae2f59..f252541e1077 100644 --- a/dir_d518b3d349cd0cf21cb3fe334b142b00.html +++ b/dir_d518b3d349cd0cf21cb3fe334b142b00.html @@ -130,7 +130,7 @@

Files

-

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Wednesday, Jul 10, 2024 using Doxygen and m.css. Contact us via GitHub.

+

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Thursday, Jul 11, 2024 using Doxygen and m.css. Contact us via GitHub.

diff --git a/dir_d9280c38316db7d1d0948d5d87d81738.html b/dir_d9280c38316db7d1d0948d5d87d81738.html index 9c7f7f0a7825..40bc56b33d3f 100644 --- a/dir_d9280c38316db7d1d0948d5d87d81738.html +++ b/dir_d9280c38316db7d1d0948d5d87d81738.html @@ -134,7 +134,7 @@

Files

-

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Wednesday, Jul 10, 2024 using Doxygen and m.css. Contact us via GitHub.

+

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Thursday, Jul 11, 2024 using Doxygen and m.css. Contact us via GitHub.

diff --git a/dir_dbf4ed52b34b963b18e61557f9feaf2c.html b/dir_dbf4ed52b34b963b18e61557f9feaf2c.html index 0559d14711e0..ab49d14e61ac 100644 --- a/dir_dbf4ed52b34b963b18e61557f9feaf2c.html +++ b/dir_dbf4ed52b34b963b18e61557f9feaf2c.html @@ -136,7 +136,7 @@

Files

-

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Wednesday, Jul 10, 2024 using Doxygen and m.css. Contact us via GitHub.

+

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Thursday, Jul 11, 2024 using Doxygen and m.css. Contact us via GitHub.

diff --git a/dir_dd5a5b1bf3e7567c4319c7f030467131.html b/dir_dd5a5b1bf3e7567c4319c7f030467131.html index a608f04ecda3..50342937baf1 100644 --- a/dir_dd5a5b1bf3e7567c4319c7f030467131.html +++ b/dir_dd5a5b1bf3e7567c4319c7f030467131.html @@ -136,7 +136,7 @@

Files

-

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Wednesday, Jul 10, 2024 using Doxygen and m.css. Contact us via GitHub.

+

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Thursday, Jul 11, 2024 using Doxygen and m.css. Contact us via GitHub.

diff --git a/dir_e2db7fc2306357382337d2f47c164685.html b/dir_e2db7fc2306357382337d2f47c164685.html index a1180fd6062e..19c001c01a14 100644 --- a/dir_e2db7fc2306357382337d2f47c164685.html +++ b/dir_e2db7fc2306357382337d2f47c164685.html @@ -134,7 +134,7 @@

Files

-

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Wednesday, Jul 10, 2024 using Doxygen and m.css. Contact us via GitHub.

+

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Thursday, Jul 11, 2024 using Doxygen and m.css. Contact us via GitHub.

diff --git a/dir_e87518858d70ea98b4c39cc24dcd5236.html b/dir_e87518858d70ea98b4c39cc24dcd5236.html index ea082c8b09f1..b4879950a329 100644 --- a/dir_e87518858d70ea98b4c39cc24dcd5236.html +++ b/dir_e87518858d70ea98b4c39cc24dcd5236.html @@ -167,7 +167,7 @@

Files

-

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Wednesday, Jul 10, 2024 using Doxygen and m.css. Contact us via GitHub.

+

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Thursday, Jul 11, 2024 using Doxygen and m.css. Contact us via GitHub.

diff --git a/dir_e8ebd5d5792131bdfd6b2c2daa81088c.html b/dir_e8ebd5d5792131bdfd6b2c2daa81088c.html index 82c9370f6e40..fabb77ef8565 100644 --- a/dir_e8ebd5d5792131bdfd6b2c2daa81088c.html +++ b/dir_e8ebd5d5792131bdfd6b2c2daa81088c.html @@ -185,7 +185,7 @@

Files

-

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Wednesday, Jul 10, 2024 using Doxygen and m.css. Contact us via GitHub.

+

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Thursday, Jul 11, 2024 using Doxygen and m.css. Contact us via GitHub.

diff --git a/dir_ec1cf62c000f17e7048c6127480956ca.html b/dir_ec1cf62c000f17e7048c6127480956ca.html index 3aebc93ae5e4..09d390ccaa52 100644 --- a/dir_ec1cf62c000f17e7048c6127480956ca.html +++ b/dir_ec1cf62c000f17e7048c6127480956ca.html @@ -138,7 +138,7 @@

Files

-

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Wednesday, Jul 10, 2024 using Doxygen and m.css. Contact us via GitHub.

+

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Thursday, Jul 11, 2024 using Doxygen and m.css. Contact us via GitHub.

diff --git a/dir_f2c0e1646bd8f4e9edf6fe12b66ea652.html b/dir_f2c0e1646bd8f4e9edf6fe12b66ea652.html index 37f14edb929d..de687de11f1f 100644 --- a/dir_f2c0e1646bd8f4e9edf6fe12b66ea652.html +++ b/dir_f2c0e1646bd8f4e9edf6fe12b66ea652.html @@ -132,7 +132,7 @@

Files

-

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Wednesday, Jul 10, 2024 using Doxygen and m.css. Contact us via GitHub.

+

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Thursday, Jul 11, 2024 using Doxygen and m.css. Contact us via GitHub.

diff --git a/dir_f3f7bf2ad2babbe2da3e1b24157e170d.html b/dir_f3f7bf2ad2babbe2da3e1b24157e170d.html index 444ee7cba3c9..01855c095bb1 100644 --- a/dir_f3f7bf2ad2babbe2da3e1b24157e170d.html +++ b/dir_f3f7bf2ad2babbe2da3e1b24157e170d.html @@ -143,7 +143,7 @@

Files

-

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Wednesday, Jul 10, 2024 using Doxygen and m.css. Contact us via GitHub.

+

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Thursday, Jul 11, 2024 using Doxygen and m.css. Contact us via GitHub.

diff --git a/dir_fae119eb913a40fe8ed97cde8b98911e.html b/dir_fae119eb913a40fe8ed97cde8b98911e.html index 815bf202318a..750d2c6e7d79 100644 --- a/dir_fae119eb913a40fe8ed97cde8b98911e.html +++ b/dir_fae119eb913a40fe8ed97cde8b98911e.html @@ -207,7 +207,7 @@

Files

-

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Wednesday, Jul 10, 2024 using Doxygen and m.css. Contact us via GitHub.

+

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Thursday, Jul 11, 2024 using Doxygen and m.css. Contact us via GitHub.

diff --git a/discretization_8decl_8h.html b/discretization_8decl_8h.html index 5b9995dedd71..cec0ba3ce384 100644 --- a/discretization_8decl_8h.html +++ b/discretization_8decl_8h.html @@ -111,7 +111,7 @@

-

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Wednesday, Jul 10, 2024 using Doxygen and m.css. Contact us via GitHub.

+

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Thursday, Jul 11, 2024 using Doxygen and m.css. Contact us via GitHub.

diff --git a/discretization_8def_8h.html b/discretization_8def_8h.html index 4ec6ec2a70b2..a1e361e15436 100644 --- a/discretization_8def_8h.html +++ b/discretization_8def_8h.html @@ -111,7 +111,7 @@

-

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Wednesday, Jul 10, 2024 using Doxygen and m.css. Contact us via GitHub.

+

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Thursday, Jul 11, 2024 using Doxygen and m.css. Contact us via GitHub.

diff --git a/easybuild.html b/easybuild.html index d9a1f05d4013..1ac232b8bb58 100644 --- a/easybuild.html +++ b/easybuild.html @@ -120,7 +120,7 @@

-

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Wednesday, Jul 10, 2024 using Doxygen and m.css. Contact us via GitHub.

+

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Thursday, Jul 11, 2024 using Doxygen and m.css. Contact us via GitHub.

diff --git a/exam2m_license_page.html b/exam2m_license_page.html index d0d2667b442b..b6b62c47ac60 100644 --- a/exam2m_license_page.html +++ b/exam2m_license_page.html @@ -131,7 +131,7 @@

-

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Wednesday, Jul 10, 2024 using Doxygen and m.css. Contact us via GitHub.

+

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Thursday, Jul 11, 2024 using Doxygen and m.css. Contact us via GitHub.

diff --git a/examples.html b/examples.html index 354e06f153d8..5128e5942886 100644 --- a/examples.html +++ b/examples.html @@ -110,7 +110,7 @@

-

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Wednesday, Jul 10, 2024 using Doxygen and m.css. Contact us via GitHub.

+

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Thursday, Jul 11, 2024 using Doxygen and m.css. Contact us via GitHub.

diff --git a/exodus_i_i_8hpp.html b/exodus_i_i_8hpp.html index 896b6899f695..8e1e9601ba17 100644 --- a/exodus_i_i_8hpp.html +++ b/exodus_i_i_8hpp.html @@ -111,7 +111,7 @@

-

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Wednesday, Jul 10, 2024 using Doxygen and m.css. Contact us via GitHub.

+

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Thursday, Jul 11, 2024 using Doxygen and m.css. Contact us via GitHub.

diff --git a/files.html b/files.html index c223aef5d54d..57f1cf02b626 100644 --- a/files.html +++ b/files.html @@ -767,7 +767,7 @@

Files

-

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Wednesday, Jul 10, 2024 using Doxygen and m.css. Contact us via GitHub.

+

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Thursday, Jul 11, 2024 using Doxygen and m.css. Contact us via GitHub.

diff --git a/flatten_8hpp.html b/flatten_8hpp.html index fdf9dde9f166..0381ed4c68bd 100644 --- a/flatten_8hpp.html +++ b/flatten_8hpp.html @@ -111,7 +111,7 @@

-

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Wednesday, Jul 10, 2024 using Doxygen and m.css. Contact us via GitHub.

+

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Thursday, Jul 11, 2024 using Doxygen and m.css. Contact us via GitHub.

diff --git a/fold_8hpp.html b/fold_8hpp.html index 7bd1d878e7ff..6548527b434d 100644 --- a/fold_8hpp.html +++ b/fold_8hpp.html @@ -111,7 +111,7 @@

-

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Wednesday, Jul 10, 2024 using Doxygen and m.css. Contact us via GitHub.

+

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Thursday, Jul 11, 2024 using Doxygen and m.css. Contact us via GitHub.

diff --git a/format_8hpp.html b/format_8hpp.html index 97f8a3d06b06..f2cb5f75679c 100644 --- a/format_8hpp.html +++ b/format_8hpp.html @@ -111,7 +111,7 @@

-

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Wednesday, Jul 10, 2024 using Doxygen and m.css. Contact us via GitHub.

+

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Thursday, Jul 11, 2024 using Doxygen and m.css. Contact us via GitHub.

diff --git a/front_8hpp.html b/front_8hpp.html index 317d7cf29d35..3e7f86faeb5f 100644 --- a/front_8hpp.html +++ b/front_8hpp.html @@ -111,7 +111,7 @@

-

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Wednesday, Jul 10, 2024 using Doxygen and m.css. Contact us via GitHub.

+

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Thursday, Jul 11, 2024 using Doxygen and m.css. Contact us via GitHub.

diff --git a/fv_8decl_8h.html b/fv_8decl_8h.html index b4cc54d77386..b258adbb69fc 100644 --- a/fv_8decl_8h.html +++ b/fv_8decl_8h.html @@ -111,7 +111,7 @@

-

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Wednesday, Jul 10, 2024 using Doxygen and m.css. Contact us via GitHub.

+

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Thursday, Jul 11, 2024 using Doxygen and m.css. Contact us via GitHub.

diff --git a/fv_8def_8h.html b/fv_8def_8h.html index 4c533bdefea8..602a41c9cfbf 100644 --- a/fv_8def_8h.html +++ b/fv_8def_8h.html @@ -111,7 +111,7 @@

-

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Wednesday, Jul 10, 2024 using Doxygen and m.css. Contact us via GitHub.

+

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Thursday, Jul 11, 2024 using Doxygen and m.css. Contact us via GitHub.

diff --git a/ghosts_8decl_8h.html b/ghosts_8decl_8h.html index e49b407edaef..9c0390479aed 100644 --- a/ghosts_8decl_8h.html +++ b/ghosts_8decl_8h.html @@ -111,7 +111,7 @@

-

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Wednesday, Jul 10, 2024 using Doxygen and m.css. Contact us via GitHub.

+

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Thursday, Jul 11, 2024 using Doxygen and m.css. Contact us via GitHub.

diff --git a/ghosts_8def_8h.html b/ghosts_8def_8h.html index acc6a4de3adf..801a6c17a405 100644 --- a/ghosts_8def_8h.html +++ b/ghosts_8def_8h.html @@ -111,7 +111,7 @@

-

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Wednesday, Jul 10, 2024 using Doxygen and m.css. Contact us via GitHub.

+

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Thursday, Jul 11, 2024 using Doxygen and m.css. Contact us via GitHub.

diff --git a/git_submodules_subtrees.html b/git_submodules_subtrees.html index a8b991192f59..1dcb96dceac7 100644 --- a/git_submodules_subtrees.html +++ b/git_submodules_subtrees.html @@ -324,7 +324,7 @@

Contents

-

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Wednesday, Jul 10, 2024 using Doxygen and m.css. Contact us via GitHub.

+

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Thursday, Jul 11, 2024 using Doxygen and m.css. Contact us via GitHub.

diff --git a/hdf5_license_page.html b/hdf5_license_page.html index 8c89d21c3aa0..199d3b2e077f 100644 --- a/hdf5_license_page.html +++ b/hdf5_license_page.html @@ -200,7 +200,7 @@

-

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Wednesday, Jul 10, 2024 using Doxygen and m.css. Contact us via GitHub.

+

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Thursday, Jul 11, 2024 using Doxygen and m.css. Contact us via GitHub.

diff --git a/highwayhash_license_page.html b/highwayhash_license_page.html index 8a50c70f4c81..99200305d3c1 100644 --- a/highwayhash_license_page.html +++ b/highwayhash_license_page.html @@ -208,7 +208,7 @@

-

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Wednesday, Jul 10, 2024 using Doxygen and m.css. Contact us via GitHub.

+

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Thursday, Jul 11, 2024 using Doxygen and m.css. Contact us via GitHub.

diff --git a/inciter_8decl_8h.html b/inciter_8decl_8h.html index 577e585e1b36..dc7e2f951850 100644 --- a/inciter_8decl_8h.html +++ b/inciter_8decl_8h.html @@ -111,7 +111,7 @@

-

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Wednesday, Jul 10, 2024 using Doxygen and m.css. Contact us via GitHub.

+

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Thursday, Jul 11, 2024 using Doxygen and m.css. Contact us via GitHub.

diff --git a/inciter_8def_8h.html b/inciter_8def_8h.html index 11e02346df08..09f5eefc7688 100644 --- a/inciter_8def_8h.html +++ b/inciter_8def_8h.html @@ -111,7 +111,7 @@

-

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Wednesday, Jul 10, 2024 using Doxygen and m.css. Contact us via GitHub.

+

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Thursday, Jul 11, 2024 using Doxygen and m.css. Contact us via GitHub.

diff --git a/inciter_alecg.html b/inciter_alecg.html index bd354ab4c3d6..aa01f643cba4 100644 --- a/inciter_alecg.html +++ b/inciter_alecg.html @@ -1739,7 +1739,7 @@

Contents

-

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Wednesday, Jul 10, 2024 using Doxygen and m.css. Contact us via GitHub.

+

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Thursday, Jul 11, 2024 using Doxygen and m.css. Contact us via GitHub.

diff --git a/inciter_amr.html b/inciter_amr.html index 80f2d829ed76..85bf02d2a75a 100644 --- a/inciter_amr.html +++ b/inciter_amr.html @@ -129,7 +129,7 @@

Contents

-

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Wednesday, Jul 10, 2024 using Doxygen and m.css. Contact us via GitHub.

+

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Thursday, Jul 11, 2024 using Doxygen and m.css. Contact us via GitHub.

diff --git a/inciter_cmd.html b/inciter_cmd.html index 80bff62d6e61..9c731d750e8a 100644 --- a/inciter_cmd.html +++ b/inciter_cmd.html @@ -164,7 +164,7 @@

Contents

-

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Wednesday, Jul 10, 2024 using Doxygen and m.css. Contact us via GitHub.

+

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Thursday, Jul 11, 2024 using Doxygen and m.css. Contact us via GitHub.

diff --git a/inciter_ctr.html b/inciter_ctr.html index 45b89cc33ded..9618281ff625 100644 --- a/inciter_ctr.html +++ b/inciter_ctr.html @@ -593,7 +593,7 @@

Contents

-

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Wednesday, Jul 10, 2024 using Doxygen and m.css. Contact us via GitHub.

+

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Thursday, Jul 11, 2024 using Doxygen and m.css. Contact us via GitHub.

diff --git a/inciter_design.html b/inciter_design.html index 26e654aba5f3..d8795a4674c1 100644 --- a/inciter_design.html +++ b/inciter_design.html @@ -140,7 +140,7 @@

Contents

-

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Wednesday, Jul 10, 2024 using Doxygen and m.css. Contact us via GitHub.

+

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Thursday, Jul 11, 2024 using Doxygen and m.css. Contact us via GitHub.

diff --git a/inciter_dg.html b/inciter_dg.html index 2b173e9b31da..423da298936e 100644 --- a/inciter_dg.html +++ b/inciter_dg.html @@ -1366,7 +1366,7 @@

Contents

-

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Wednesday, Jul 10, 2024 using Doxygen and m.css. Contact us via GitHub.

+

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Thursday, Jul 11, 2024 using Doxygen and m.css. Contact us via GitHub.

diff --git a/inciter_diagcg.html b/inciter_diagcg.html index 089d09a6a597..633803d78380 100644 --- a/inciter_diagcg.html +++ b/inciter_diagcg.html @@ -2718,7 +2718,7 @@

Contents

-

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Wednesday, Jul 10, 2024 using Doxygen and m.css. Contact us via GitHub.

+

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Thursday, Jul 11, 2024 using Doxygen and m.css. Contact us via GitHub.

diff --git a/inciter_example_f16.html b/inciter_example_f16.html index 1817400b8986..b69034754a4a 100644 --- a/inciter_example_f16.html +++ b/inciter_example_f16.html @@ -177,7 +177,7 @@

-

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Wednesday, Jul 10, 2024 using Doxygen and m.css. Contact us via GitHub.

+

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Thursday, Jul 11, 2024 using Doxygen and m.css. Contact us via GitHub.

diff --git a/inciter_example_gasimpact_4mat.html b/inciter_example_gasimpact_4mat.html index b233cf2bc4e1..52262b4013ba 100644 --- a/inciter_example_gasimpact_4mat.html +++ b/inciter_example_gasimpact_4mat.html @@ -218,7 +218,7 @@

-

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Wednesday, Jul 10, 2024 using Doxygen and m.css. Contact us via GitHub.

+

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Thursday, Jul 11, 2024 using Doxygen and m.css. Contact us via GitHub.

diff --git a/inciter_example_hump.html b/inciter_example_hump.html index ea42faf6546c..30f8724b3b12 100644 --- a/inciter_example_hump.html +++ b/inciter_example_hump.html @@ -2320,7 +2320,7 @@

-

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Wednesday, Jul 10, 2024 using Doxygen and m.css. Contact us via GitHub.

+

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Thursday, Jul 11, 2024 using Doxygen and m.css. Contact us via GitHub.

diff --git a/inciter_example_shear.html b/inciter_example_shear.html index d5f87d542f92..c4d16b24cd32 100644 --- a/inciter_example_shear.html +++ b/inciter_example_shear.html @@ -971,7 +971,7 @@

-

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Wednesday, Jul 10, 2024 using Doxygen and m.css. Contact us via GitHub.

+

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Thursday, Jul 11, 2024 using Doxygen and m.css. Contact us via GitHub.

diff --git a/inciter_example_slot_cyl.html b/inciter_example_slot_cyl.html index bce9307b3346..6843830952b3 100644 --- a/inciter_example_slot_cyl.html +++ b/inciter_example_slot_cyl.html @@ -403,7 +403,7 @@

-

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Wednesday, Jul 10, 2024 using Doxygen and m.css. Contact us via GitHub.

+

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Thursday, Jul 11, 2024 using Doxygen and m.css. Contact us via GitHub.

diff --git a/inciter_main.html b/inciter_main.html index 7fd04b10e7b6..bd9148cacf2c 100644 --- a/inciter_main.html +++ b/inciter_main.html @@ -110,7 +110,7 @@

-

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Wednesday, Jul 10, 2024 using Doxygen and m.css. Contact us via GitHub.

+

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Thursday, Jul 11, 2024 using Doxygen and m.css. Contact us via GitHub.

diff --git a/inciter_mm.html b/inciter_mm.html index ffcc5f2c8109..5bf3f5baf1a9 100644 --- a/inciter_mm.html +++ b/inciter_mm.html @@ -1122,7 +1122,7 @@

Contents

-

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Wednesday, Jul 10, 2024 using Doxygen and m.css. Contact us via GitHub.

+

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Thursday, Jul 11, 2024 using Doxygen and m.css. Contact us via GitHub.

diff --git a/inciter_newparse.html b/inciter_newparse.html index c84c3249f462..1188c2483ad8 100644 --- a/inciter_newparse.html +++ b/inciter_newparse.html @@ -153,7 +153,7 @@

-

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Wednesday, Jul 10, 2024 using Doxygen and m.css. Contact us via GitHub.

+

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Thursday, Jul 11, 2024 using Doxygen and m.css. Contact us via GitHub.

diff --git a/inciter_newpde.html b/inciter_newpde.html index 9aa9bb3ed9a5..4f77c0ede544 100644 --- a/inciter_newpde.html +++ b/inciter_newpde.html @@ -857,7 +857,7 @@

Contents

-

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Wednesday, Jul 10, 2024 using Doxygen and m.css. Contact us via GitHub.

+

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Thursday, Jul 11, 2024 using Doxygen and m.css. Contact us via GitHub.

diff --git a/inciter_newpde_configuremultimat_c.html b/inciter_newpde_configuremultimat_c.html index 2d1724131cb2..697ad7a86263 100644 --- a/inciter_newpde_configuremultimat_c.html +++ b/inciter_newpde_configuremultimat_c.html @@ -274,7 +274,7 @@

-

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Wednesday, Jul 10, 2024 using Doxygen and m.css. Contact us via GitHub.

+

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Thursday, Jul 11, 2024 using Doxygen and m.css. Contact us via GitHub.

diff --git a/inciter_newpde_configuremultimat_h.html b/inciter_newpde_configuremultimat_h.html index a0620379a5db..3eff7aa5a012 100644 --- a/inciter_newpde_configuremultimat_h.html +++ b/inciter_newpde_configuremultimat_h.html @@ -311,7 +311,7 @@

-

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Wednesday, Jul 10, 2024 using Doxygen and m.css. Contact us via GitHub.

+

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Thursday, Jul 11, 2024 using Doxygen and m.css. Contact us via GitHub.

diff --git a/inciter_newpde_dg_h.html b/inciter_newpde_dg_h.html index f96e0d2b0219..5005f04b8d4f 100644 --- a/inciter_newpde_dg_h.html +++ b/inciter_newpde_dg_h.html @@ -156,7 +156,7 @@

-

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Wednesday, Jul 10, 2024 using Doxygen and m.css. Contact us via GitHub.

+

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Thursday, Jul 11, 2024 using Doxygen and m.css. Contact us via GitHub.

diff --git a/inciter_newpde_dgeuler_h.html b/inciter_newpde_dgeuler_h.html index 4e21d2c91527..5edc1f1a695c 100644 --- a/inciter_newpde_dgeuler_h.html +++ b/inciter_newpde_dgeuler_h.html @@ -172,7 +172,7 @@

-

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Wednesday, Jul 10, 2024 using Doxygen and m.css. Contact us via GitHub.

+

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Thursday, Jul 11, 2024 using Doxygen and m.css. Contact us via GitHub.

diff --git a/inciter_newpde_dgmultimat_h.html b/inciter_newpde_dgmultimat_h.html index a4351577c296..b99ee3551807 100644 --- a/inciter_newpde_dgmultimat_h.html +++ b/inciter_newpde_dgmultimat_h.html @@ -1590,7 +1590,7 @@

-

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Wednesday, Jul 10, 2024 using Doxygen and m.css. Contact us via GitHub.

+

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Thursday, Jul 11, 2024 using Doxygen and m.css. Contact us via GitHub.

diff --git a/inciter_newpde_interfaceadvection_h.html b/inciter_newpde_interfaceadvection_h.html index f061d23e571d..3808c7f8c820 100644 --- a/inciter_newpde_interfaceadvection_h.html +++ b/inciter_newpde_interfaceadvection_h.html @@ -183,7 +183,7 @@

-

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Wednesday, Jul 10, 2024 using Doxygen and m.css. Contact us via GitHub.

+

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Thursday, Jul 11, 2024 using Doxygen and m.css. Contact us via GitHub.

diff --git a/inciter_newpde_problem_h.html b/inciter_newpde_problem_h.html index 1addb26ed1e9..3f6f64c5fbbf 100644 --- a/inciter_newpde_problem_h.html +++ b/inciter_newpde_problem_h.html @@ -184,7 +184,7 @@

-

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Wednesday, Jul 10, 2024 using Doxygen and m.css. Contact us via GitHub.

+

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Thursday, Jul 11, 2024 using Doxygen and m.css. Contact us via GitHub.

diff --git a/inciter_newpde_userdefined_h.html b/inciter_newpde_userdefined_h.html index a37034c26f0f..f2521a1be4e7 100644 --- a/inciter_newpde_userdefined_h.html +++ b/inciter_newpde_userdefined_h.html @@ -176,7 +176,7 @@

-

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Wednesday, Jul 10, 2024 using Doxygen and m.css. Contact us via GitHub.

+

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Thursday, Jul 11, 2024 using Doxygen and m.css. Contact us via GitHub.

diff --git a/inciter_newscheme.html b/inciter_newscheme.html index e05c5ad22eb1..b85e686afb8b 100644 --- a/inciter_newscheme.html +++ b/inciter_newscheme.html @@ -837,7 +837,7 @@

Contents

-

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Wednesday, Jul 10, 2024 using Doxygen and m.css. Contact us via GitHub.

+

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Thursday, Jul 11, 2024 using Doxygen and m.css. Contact us via GitHub.

diff --git a/inciter_newscheme_alecg_ci.html b/inciter_newscheme_alecg_ci.html index 68d65974c62c..d3de87ad000f 100644 --- a/inciter_newscheme_alecg_ci.html +++ b/inciter_newscheme_alecg_ci.html @@ -219,7 +219,7 @@

-

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Wednesday, Jul 10, 2024 using Doxygen and m.css. Contact us via GitHub.

+

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Thursday, Jul 11, 2024 using Doxygen and m.css. Contact us via GitHub.

diff --git a/inciter_newscheme_class_page.html b/inciter_newscheme_class_page.html index 674ac5fccd2b..9bba07a81e39 100644 --- a/inciter_newscheme_class_page.html +++ b/inciter_newscheme_class_page.html @@ -1722,7 +1722,7 @@

-

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Wednesday, Jul 10, 2024 using Doxygen and m.css. Contact us via GitHub.

+

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Thursday, Jul 11, 2024 using Doxygen and m.css. Contact us via GitHub.

diff --git a/inciter_newscheme_header_page.html b/inciter_newscheme_header_page.html index ae51d62282f7..64846aa16891 100644 --- a/inciter_newscheme_header_page.html +++ b/inciter_newscheme_header_page.html @@ -564,7 +564,7 @@

-

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Wednesday, Jul 10, 2024 using Doxygen and m.css. Contact us via GitHub.

+

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Thursday, Jul 11, 2024 using Doxygen and m.css. Contact us via GitHub.

diff --git a/inciter_newscheme_nowarning_page.html b/inciter_newscheme_nowarning_page.html index 1f24ab351f6e..6ea265fb5743 100644 --- a/inciter_newscheme_nowarning_page.html +++ b/inciter_newscheme_nowarning_page.html @@ -194,7 +194,7 @@

-

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Wednesday, Jul 10, 2024 using Doxygen and m.css. Contact us via GitHub.

+

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Thursday, Jul 11, 2024 using Doxygen and m.css. Contact us via GitHub.

diff --git a/inciter_performance.html b/inciter_performance.html index ac4f069d3d0d..05e12f74b40c 100644 --- a/inciter_performance.html +++ b/inciter_performance.html @@ -125,7 +125,7 @@

Contents

-

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Wednesday, Jul 10, 2024 using Doxygen and m.css. Contact us via GitHub.

+

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Thursday, Jul 11, 2024 using Doxygen and m.css. Contact us via GitHub.

diff --git a/index.html b/index.html index 066c8245c719..88019031eb9c 100644 --- a/index.html +++ b/index.html @@ -111,7 +111,7 @@

-

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Wednesday, Jul 10, 2024 using Doxygen and m.css. Contact us via GitHub.

+

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Thursday, Jul 11, 2024 using Doxygen and m.css. Contact us via GitHub.

diff --git a/index__of_8hpp.html b/index__of_8hpp.html index 6738e9f37625..283bbb4e6b29 100644 --- a/index__of_8hpp.html +++ b/index__of_8hpp.html @@ -111,7 +111,7 @@

-

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Wednesday, Jul 10, 2024 using Doxygen and m.css. Contact us via GitHub.

+

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Thursday, Jul 11, 2024 using Doxygen and m.css. Contact us via GitHub.

diff --git a/io.html b/io.html index f2ec4b3fd771..b84865012958 100644 --- a/io.html +++ b/io.html @@ -110,7 +110,7 @@

-

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Wednesday, Jul 10, 2024 using Doxygen and m.css. Contact us via GitHub.

+

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Thursday, Jul 11, 2024 using Doxygen and m.css. Contact us via GitHub.

diff --git a/kokkos__cr_8hpp.html b/kokkos__cr_8hpp.html index f571f8c02184..2f9e4194df8c 100644 --- a/kokkos__cr_8hpp.html +++ b/kokkos__cr_8hpp.html @@ -111,7 +111,7 @@

-

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Wednesday, Jul 10, 2024 using Doxygen and m.css. Contact us via GitHub.

+

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Thursday, Jul 11, 2024 using Doxygen and m.css. Contact us via GitHub.

diff --git a/lapack_license_page.html b/lapack_license_page.html index d71a7f2cd415..d79fab9060f9 100644 --- a/lapack_license_page.html +++ b/lapack_license_page.html @@ -159,7 +159,7 @@

-

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Wednesday, Jul 10, 2024 using Doxygen and m.css. Contact us via GitHub.

+

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Thursday, Jul 11, 2024 using Doxygen and m.css. Contact us via GitHub.

diff --git a/layout.html b/layout.html index de2aa1825fb1..d8188be4752d 100644 --- a/layout.html +++ b/layout.html @@ -561,7 +561,7 @@

Contents

-

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Wednesday, Jul 10, 2024 using Doxygen and m.css. Contact us via GitHub.

+

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Thursday, Jul 11, 2024 using Doxygen and m.css. Contact us via GitHub.

diff --git a/lbswitch_8decl_8h.html b/lbswitch_8decl_8h.html index 25897227b531..0b7ce6ddfee2 100644 --- a/lbswitch_8decl_8h.html +++ b/lbswitch_8decl_8h.html @@ -111,7 +111,7 @@

-

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Wednesday, Jul 10, 2024 using Doxygen and m.css. Contact us via GitHub.

+

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Thursday, Jul 11, 2024 using Doxygen and m.css. Contact us via GitHub.

diff --git a/lbswitch_8def_8h.html b/lbswitch_8def_8h.html index 527434d4c408..464293230da3 100644 --- a/lbswitch_8def_8h.html +++ b/lbswitch_8def_8h.html @@ -111,7 +111,7 @@

-

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Wednesday, Jul 10, 2024 using Doxygen and m.css. Contact us via GitHub.

+

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Thursday, Jul 11, 2024 using Doxygen and m.css. Contact us via GitHub.

diff --git a/libcpp_license_page.html b/libcpp_license_page.html index c60d2101224f..5191a36ec84c 100644 --- a/libcpp_license_page.html +++ b/libcpp_license_page.html @@ -125,7 +125,7 @@

-

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Wednesday, Jul 10, 2024 using Doxygen and m.css. Contact us via GitHub.

+

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Thursday, Jul 11, 2024 using Doxygen and m.css. Contact us via GitHub.

diff --git a/libstdcpp_license_page.html b/libstdcpp_license_page.html index 0d5ac5f6633b..a2e579fe623e 100644 --- a/libstdcpp_license_page.html +++ b/libstdcpp_license_page.html @@ -203,7 +203,7 @@

-

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Wednesday, Jul 10, 2024 using Doxygen and m.css. Contact us via GitHub.

+

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Thursday, Jul 11, 2024 using Doxygen and m.css. Contact us via GitHub.

diff --git a/licenses.html b/licenses.html index 00201abf6dbd..4292ea2a3f94 100644 --- a/licenses.html +++ b/licenses.html @@ -167,7 +167,7 @@

Contents

-

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Wednesday, Jul 10, 2024 using Doxygen and m.css. Contact us via GitHub.

+

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Thursday, Jul 11, 2024 using Doxygen and m.css. Contact us via GitHub.

diff --git a/linearmap_8decl_8h.html b/linearmap_8decl_8h.html index b0d8cabde6f5..9053ba55b448 100644 --- a/linearmap_8decl_8h.html +++ b/linearmap_8decl_8h.html @@ -111,7 +111,7 @@

-

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Wednesday, Jul 10, 2024 using Doxygen and m.css. Contact us via GitHub.

+

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Thursday, Jul 11, 2024 using Doxygen and m.css. Contact us via GitHub.

diff --git a/linearmap_8def_8h.html b/linearmap_8def_8h.html index 310f09ff8de3..e379a71e77fe 100644 --- a/linearmap_8def_8h.html +++ b/linearmap_8def_8h.html @@ -111,7 +111,7 @@

-

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Wednesday, Jul 10, 2024 using Doxygen and m.css. Contact us via GitHub.

+

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Thursday, Jul 11, 2024 using Doxygen and m.css. Contact us via GitHub.

diff --git a/lua_license_page.html b/lua_license_page.html index 3a8402142da7..a0f8843960ef 100644 --- a/lua_license_page.html +++ b/lua_license_page.html @@ -129,7 +129,7 @@

-

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Wednesday, Jul 10, 2024 using Doxygen and m.css. Contact us via GitHub.

+

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Thursday, Jul 11, 2024 using Doxygen and m.css. Contact us via GitHub.

diff --git a/m2mtransfer_8decl_8h.html b/m2mtransfer_8decl_8h.html index e1d2e5238a09..4db9ba74d5d9 100644 --- a/m2mtransfer_8decl_8h.html +++ b/m2mtransfer_8decl_8h.html @@ -111,7 +111,7 @@

-

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Wednesday, Jul 10, 2024 using Doxygen and m.css. Contact us via GitHub.

+

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Thursday, Jul 11, 2024 using Doxygen and m.css. Contact us via GitHub.

diff --git a/m2mtransfer_8def_8h.html b/m2mtransfer_8def_8h.html index ae7222e8fd58..2cd36724157c 100644 --- a/m2mtransfer_8def_8h.html +++ b/m2mtransfer_8def_8h.html @@ -111,7 +111,7 @@

-

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Wednesday, Jul 10, 2024 using Doxygen and m.css. Contact us via GitHub.

+

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Thursday, Jul 11, 2024 using Doxygen and m.css. Contact us via GitHub.

diff --git a/meshconv_8decl_8h.html b/meshconv_8decl_8h.html index fdae86a6dabe..bd25958e36d8 100644 --- a/meshconv_8decl_8h.html +++ b/meshconv_8decl_8h.html @@ -111,7 +111,7 @@

-

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Wednesday, Jul 10, 2024 using Doxygen and m.css. Contact us via GitHub.

+

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Thursday, Jul 11, 2024 using Doxygen and m.css. Contact us via GitHub.

diff --git a/meshconv_8def_8h.html b/meshconv_8def_8h.html index 06c6bdfa7bdf..f84ef505afe1 100644 --- a/meshconv_8def_8h.html +++ b/meshconv_8def_8h.html @@ -111,7 +111,7 @@

-

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Wednesday, Jul 10, 2024 using Doxygen and m.css. Contact us via GitHub.

+

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Thursday, Jul 11, 2024 using Doxygen and m.css. Contact us via GitHub.

diff --git a/meshconv_cmd.html b/meshconv_cmd.html index ea14cccbd68c..196c73a2118c 100644 --- a/meshconv_cmd.html +++ b/meshconv_cmd.html @@ -146,7 +146,7 @@

Contents

-

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Wednesday, Jul 10, 2024 using Doxygen and m.css. Contact us via GitHub.

+

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Thursday, Jul 11, 2024 using Doxygen and m.css. Contact us via GitHub.

diff --git a/meshconv_main.html b/meshconv_main.html index b42c186d022d..8cb92fa58115 100644 --- a/meshconv_main.html +++ b/meshconv_main.html @@ -110,7 +110,7 @@

-

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Wednesday, Jul 10, 2024 using Doxygen and m.css. Contact us via GitHub.

+

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Thursday, Jul 11, 2024 using Doxygen and m.css. Contact us via GitHub.

diff --git a/meshwriter_8decl_8h.html b/meshwriter_8decl_8h.html index 790cc64ceafe..b6046ef44a99 100644 --- a/meshwriter_8decl_8h.html +++ b/meshwriter_8decl_8h.html @@ -111,7 +111,7 @@

-

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Wednesday, Jul 10, 2024 using Doxygen and m.css. Contact us via GitHub.

+

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Thursday, Jul 11, 2024 using Doxygen and m.css. Contact us via GitHub.

diff --git a/meshwriter_8def_8h.html b/meshwriter_8def_8h.html index fad982271eec..7afab8d9e1bd 100644 --- a/meshwriter_8def_8h.html +++ b/meshwriter_8def_8h.html @@ -111,7 +111,7 @@

-

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Wednesday, Jul 10, 2024 using Doxygen and m.css. Contact us via GitHub.

+

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Thursday, Jul 11, 2024 using Doxygen and m.css. Contact us via GitHub.

diff --git a/migrated__base_8def_8h.html b/migrated__base_8def_8h.html index cc8735a506f9..46976834dec6 100644 --- a/migrated__base_8def_8h.html +++ b/migrated__base_8def_8h.html @@ -111,7 +111,7 @@

-

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Wednesday, Jul 10, 2024 using Doxygen and m.css. Contact us via GitHub.

+

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Thursday, Jul 11, 2024 using Doxygen and m.css. Contact us via GitHub.

diff --git a/migrated__inciter_8decl_8h.html b/migrated__inciter_8decl_8h.html index 60b07ed72b61..05cefd3a1609 100644 --- a/migrated__inciter_8decl_8h.html +++ b/migrated__inciter_8decl_8h.html @@ -111,7 +111,7 @@

-

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Wednesday, Jul 10, 2024 using Doxygen and m.css. Contact us via GitHub.

+

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Thursday, Jul 11, 2024 using Doxygen and m.css. Contact us via GitHub.

diff --git a/migrated__inciter_8def_8h.html b/migrated__inciter_8def_8h.html index 91c1b13e5ad2..096f9b191925 100644 --- a/migrated__inciter_8def_8h.html +++ b/migrated__inciter_8def_8h.html @@ -111,7 +111,7 @@

-

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Wednesday, Jul 10, 2024 using Doxygen and m.css. Contact us via GitHub.

+

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Thursday, Jul 11, 2024 using Doxygen and m.css. Contact us via GitHub.

diff --git a/mkl_license_page.html b/mkl_license_page.html index 02186cf75e19..1cbd02cf3fe5 100644 --- a/mkl_license_page.html +++ b/mkl_license_page.html @@ -631,7 +631,7 @@

-

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Wednesday, Jul 10, 2024 using Doxygen and m.css. Contact us via GitHub.

+

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Thursday, Jul 11, 2024 using Doxygen and m.css. Contact us via GitHub.

diff --git a/modules.html b/modules.html index a2dc6d996439..8c4d4973f1df 100644 --- a/modules.html +++ b/modules.html @@ -124,7 +124,7 @@

Modules

-

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Wednesday, Jul 10, 2024 using Doxygen and m.css. Contact us via GitHub.

+

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Thursday, Jul 11, 2024 using Doxygen and m.css. Contact us via GitHub.

diff --git a/mpi_8hpp.html b/mpi_8hpp.html index 02f3103942c8..edf743f154f1 100644 --- a/mpi_8hpp.html +++ b/mpi_8hpp.html @@ -111,7 +111,7 @@

-

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Wednesday, Jul 10, 2024 using Doxygen and m.css. Contact us via GitHub.

+

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Thursday, Jul 11, 2024 using Doxygen and m.css. Contact us via GitHub.

diff --git a/mpirunner_8decl_8h.html b/mpirunner_8decl_8h.html index daa99b8729ac..f5319f324a36 100644 --- a/mpirunner_8decl_8h.html +++ b/mpirunner_8decl_8h.html @@ -111,7 +111,7 @@

-

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Wednesday, Jul 10, 2024 using Doxygen and m.css. Contact us via GitHub.

+

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Thursday, Jul 11, 2024 using Doxygen and m.css. Contact us via GitHub.

diff --git a/mpirunner_8def_8h.html b/mpirunner_8def_8h.html index b828c906d052..89ae249dcf84 100644 --- a/mpirunner_8def_8h.html +++ b/mpirunner_8def_8h.html @@ -111,7 +111,7 @@

-

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Wednesday, Jul 10, 2024 using Doxygen and m.css. Contact us via GitHub.

+

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Thursday, Jul 11, 2024 using Doxygen and m.css. Contact us via GitHub.

diff --git a/musllibc_license_page.html b/musllibc_license_page.html index e68b069ad2ba..d104452022b2 100644 --- a/musllibc_license_page.html +++ b/musllibc_license_page.html @@ -274,7 +274,7 @@

-

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Wednesday, Jul 10, 2024 using Doxygen and m.css. Contact us via GitHub.

+

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Thursday, Jul 11, 2024 using Doxygen and m.css. Contact us via GitHub.

diff --git a/namespace_p_u_p.html b/namespace_p_u_p.html index 121180db9178..27fa7ed979f2 100644 --- a/namespace_p_u_p.html +++ b/namespace_p_u_p.html @@ -1217,7 +1217,7 @@

-

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Wednesday, Jul 10, 2024 using Doxygen and m.css. Contact us via GitHub.

+

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Thursday, Jul 11, 2024 using Doxygen and m.css. Contact us via GitHub.

diff --git a/namespaceinciter.html b/namespaceinciter.html index 4ea5431ae91b..e9a889f82ff5 100644 --- a/namespaceinciter.html +++ b/namespaceinciter.html @@ -5270,7 +5270,7 @@

-

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Wednesday, Jul 10, 2024 using Doxygen and m.css. Contact us via GitHub.

+

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Thursday, Jul 11, 2024 using Doxygen and m.css. Contact us via GitHub.

diff --git a/namespaceinciter_1_1cmd.html b/namespaceinciter_1_1cmd.html index 0c9340324725..6d2d2a45e240 100644 --- a/namespaceinciter_1_1cmd.html +++ b/namespaceinciter_1_1cmd.html @@ -208,7 +208,7 @@

Typedefs

-

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Wednesday, Jul 10, 2024 using Doxygen and m.css. Contact us via GitHub.

+

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Thursday, Jul 11, 2024 using Doxygen and m.css. Contact us via GitHub.

diff --git a/namespaceinciter_1_1ctr.html b/namespaceinciter_1_1ctr.html index 01d5b2f99046..e6911e8e27a5 100644 --- a/namespaceinciter_1_1ctr.html +++ b/namespaceinciter_1_1ctr.html @@ -457,7 +457,7 @@

-

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Wednesday, Jul 10, 2024 using Doxygen and m.css. Contact us via GitHub.

+

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Thursday, Jul 11, 2024 using Doxygen and m.css. Contact us via GitHub.

diff --git a/namespacekw.html b/namespacekw.html index 2fa4ac21d716..879fb5adaff9 100644 --- a/namespacekw.html +++ b/namespacekw.html @@ -134,7 +134,7 @@

Classes

-

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Wednesday, Jul 10, 2024 using Doxygen and m.css. Contact us via GitHub.

+

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Thursday, Jul 11, 2024 using Doxygen and m.css. Contact us via GitHub.

diff --git a/namespacemeshconv.html b/namespacemeshconv.html index c753e3b3e874..addddec3eb0b 100644 --- a/namespacemeshconv.html +++ b/namespacemeshconv.html @@ -142,7 +142,7 @@

Classes

-

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Wednesday, Jul 10, 2024 using Doxygen and m.css. Contact us via GitHub.

+

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Thursday, Jul 11, 2024 using Doxygen and m.css. Contact us via GitHub.

diff --git a/namespacemeshconv_1_1cmd.html b/namespacemeshconv_1_1cmd.html index 086aecdf6cf4..50aa6aac3d72 100644 --- a/namespacemeshconv_1_1cmd.html +++ b/namespacemeshconv_1_1cmd.html @@ -184,7 +184,7 @@

Typedefs

-

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Wednesday, Jul 10, 2024 using Doxygen and m.css. Contact us via GitHub.

+

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Thursday, Jul 11, 2024 using Doxygen and m.css. Contact us via GitHub.

diff --git a/namespacemeshconv_1_1ctr.html b/namespacemeshconv_1_1ctr.html index 7e8adbbc61f5..df4801c3192e 100644 --- a/namespacemeshconv_1_1ctr.html +++ b/namespacemeshconv_1_1ctr.html @@ -146,7 +146,7 @@

Typedefs

-

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Wednesday, Jul 10, 2024 using Doxygen and m.css. Contact us via GitHub.

+

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Thursday, Jul 11, 2024 using Doxygen and m.css. Contact us via GitHub.

diff --git a/namespaces.html b/namespaces.html index 212c4cc9632d..7167d20617a3 100644 --- a/namespaces.html +++ b/namespaces.html @@ -173,7 +173,7 @@

Namespaces

-

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Wednesday, Jul 10, 2024 using Doxygen and m.css. Contact us via GitHub.

+

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Thursday, Jul 11, 2024 using Doxygen and m.css. Contact us via GitHub.

diff --git a/namespacestd.html b/namespacestd.html index 64519006a2a3..0809964e2f0c 100644 --- a/namespacestd.html +++ b/namespacestd.html @@ -108,7 +108,7 @@

std namespace

-

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Wednesday, Jul 10, 2024 using Doxygen and m.css. Contact us via GitHub.

+

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Thursday, Jul 11, 2024 using Doxygen and m.css. Contact us via GitHub.

diff --git a/namespacetag.html b/namespacetag.html index 50130dfa64ce..a09b51ab3667 100644 --- a/namespacetag.html +++ b/namespacetag.html @@ -108,7 +108,7 @@

tag namespace

-

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Wednesday, Jul 10, 2024 using Doxygen and m.css. Contact us via GitHub.

+

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Thursday, Jul 11, 2024 using Doxygen and m.css. Contact us via GitHub.

diff --git a/namespacetk.html b/namespacetk.html index 18be6ed850be..bc186f04616d 100644 --- a/namespacetk.html +++ b/namespacetk.html @@ -10238,7 +10238,7 @@

-

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Wednesday, Jul 10, 2024 using Doxygen and m.css. Contact us via GitHub.

+

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Thursday, Jul 11, 2024 using Doxygen and m.css. Contact us via GitHub.

diff --git a/namespacetk_1_1grm.html b/namespacetk_1_1grm.html index d87d8074c83d..8c5b4d2f58a4 100644 --- a/namespacetk_1_1grm.html +++ b/namespacetk_1_1grm.html @@ -524,7 +524,7 @@

-

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Wednesday, Jul 10, 2024 using Doxygen and m.css. Contact us via GitHub.

+

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Thursday, Jul 11, 2024 using Doxygen and m.css. Contact us via GitHub.

diff --git a/namespacetk_1_1zoltan.html b/namespacetk_1_1zoltan.html index 156479e56c27..477ea4b6901f 100644 --- a/namespacetk_1_1zoltan.html +++ b/namespacetk_1_1zoltan.html @@ -184,7 +184,7 @@

-

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Wednesday, Jul 10, 2024 using Doxygen and m.css. Contact us via GitHub.

+

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Thursday, Jul 11, 2024 using Doxygen and m.css. Contact us via GitHub.

diff --git a/namespacetut.html b/namespacetut.html index 6c70353e5b8a..4634bf6d15f2 100644 --- a/namespacetut.html +++ b/namespacetut.html @@ -154,7 +154,7 @@

-

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Wednesday, Jul 10, 2024 using Doxygen and m.css. Contact us via GitHub.

+

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Thursday, Jul 11, 2024 using Doxygen and m.css. Contact us via GitHub.

diff --git a/namespacetut_1_1charm.html b/namespacetut_1_1charm.html index da1b059d7b17..0cf125b8a684 100644 --- a/namespacetut_1_1charm.html +++ b/namespacetut_1_1charm.html @@ -137,7 +137,7 @@

Functions

-

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Wednesday, Jul 10, 2024 using Doxygen and m.css. Contact us via GitHub.

+

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Thursday, Jul 11, 2024 using Doxygen and m.css. Contact us via GitHub.

diff --git a/namespacetut_1_1charm_1_1tag.html b/namespacetut_1_1charm_1_1tag.html index 97fc3800f755..4dffaca2792d 100644 --- a/namespacetut_1_1charm_1_1tag.html +++ b/namespacetut_1_1charm_1_1tag.html @@ -108,7 +108,7 @@

tut::
-

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Wednesday, Jul 10, 2024 using Doxygen and m.css. Contact us via GitHub.

+

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Thursday, Jul 11, 2024 using Doxygen and m.css. Contact us via GitHub.

diff --git a/namespaceunittest.html b/namespaceunittest.html index d1e29267a8f1..2689d931b4e6 100644 --- a/namespaceunittest.html +++ b/namespaceunittest.html @@ -411,7 +411,7 @@

-

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Wednesday, Jul 10, 2024 using Doxygen and m.css. Contact us via GitHub.

+

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Thursday, Jul 11, 2024 using Doxygen and m.css. Contact us via GitHub.

diff --git a/namespaceunittest_1_1cmd.html b/namespaceunittest_1_1cmd.html index bd3466771fa9..e4d0ca5b0304 100644 --- a/namespaceunittest_1_1cmd.html +++ b/namespaceunittest_1_1cmd.html @@ -184,7 +184,7 @@

Typedefs

-

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Wednesday, Jul 10, 2024 using Doxygen and m.css. Contact us via GitHub.

+

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Thursday, Jul 11, 2024 using Doxygen and m.css. Contact us via GitHub.

diff --git a/namespaceunittest_1_1ctr.html b/namespaceunittest_1_1ctr.html index a4962d5e1fb8..07a29b75ac54 100644 --- a/namespaceunittest_1_1ctr.html +++ b/namespaceunittest_1_1ctr.html @@ -146,7 +146,7 @@

Typedefs

-

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Wednesday, Jul 10, 2024 using Doxygen and m.css. Contact us via GitHub.

+

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Thursday, Jul 11, 2024 using Doxygen and m.css. Contact us via GitHub.

diff --git a/netcdf_license_page.html b/netcdf_license_page.html index 18880669d540..a9fa9bbd852f 100644 --- a/netcdf_license_page.html +++ b/netcdf_license_page.html @@ -139,7 +139,7 @@

-

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Wednesday, Jul 10, 2024 using Doxygen and m.css. Contact us via GitHub.

+

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Thursday, Jul 11, 2024 using Doxygen and m.css. Contact us via GitHub.

diff --git a/omega_h_license_page.html b/omega_h_license_page.html index 6aa41bc40bbc..d5495ca5faf7 100644 --- a/omega_h_license_page.html +++ b/omega_h_license_page.html @@ -137,7 +137,7 @@

-

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Wednesday, Jul 10, 2024 using Doxygen and m.css. Contact us via GitHub.

+

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Thursday, Jul 11, 2024 using Doxygen and m.css. Contact us via GitHub.

diff --git a/openmpi_license_page.html b/openmpi_license_page.html index 5e222964b169..4d08c6d44ef0 100644 --- a/openmpi_license_page.html +++ b/openmpi_license_page.html @@ -200,7 +200,7 @@

-

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Wednesday, Jul 10, 2024 using Doxygen and m.css. Contact us via GitHub.

+

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Thursday, Jul 11, 2024 using Doxygen and m.css. Contact us via GitHub.

diff --git a/oversetfe_8decl_8h.html b/oversetfe_8decl_8h.html index eee75e2b4937..dd03347bda22 100644 --- a/oversetfe_8decl_8h.html +++ b/oversetfe_8decl_8h.html @@ -111,7 +111,7 @@

-

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Wednesday, Jul 10, 2024 using Doxygen and m.css. Contact us via GitHub.

+

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Thursday, Jul 11, 2024 using Doxygen and m.css. Contact us via GitHub.

diff --git a/oversetfe_8def_8h.html b/oversetfe_8def_8h.html index 7fec148265fa..22f216f45e41 100644 --- a/oversetfe_8def_8h.html +++ b/oversetfe_8def_8h.html @@ -111,7 +111,7 @@

-

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Wednesday, Jul 10, 2024 using Doxygen and m.css. Contact us via GitHub.

+

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Thursday, Jul 11, 2024 using Doxygen and m.css. Contact us via GitHub.

diff --git a/pages.html b/pages.html index 5440ef0a609f..5360c84cf0e8 100644 --- a/pages.html +++ b/pages.html @@ -218,7 +218,7 @@

Pages

-

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Wednesday, Jul 10, 2024 using Doxygen and m.css. Contact us via GitHub.

+

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Thursday, Jul 11, 2024 using Doxygen and m.css. Contact us via GitHub.

diff --git a/papers.html b/papers.html index 9d8f35011c94..1f10cf4a1cf4 100644 --- a/papers.html +++ b/papers.html @@ -110,7 +110,7 @@

-

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Wednesday, Jul 10, 2024 using Doxygen and m.css. Contact us via GitHub.

+

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Thursday, Jul 11, 2024 using Doxygen and m.css. Contact us via GitHub.

diff --git a/particlewriter_8decl_8h.html b/particlewriter_8decl_8h.html index d8962023d178..a09e38cc17ad 100644 --- a/particlewriter_8decl_8h.html +++ b/particlewriter_8decl_8h.html @@ -111,7 +111,7 @@

-

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Wednesday, Jul 10, 2024 using Doxygen and m.css. Contact us via GitHub.

+

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Thursday, Jul 11, 2024 using Doxygen and m.css. Contact us via GitHub.

diff --git a/particlewriter_8def_8h.html b/particlewriter_8def_8h.html index 39cb267783e8..80bc57cce116 100644 --- a/particlewriter_8def_8h.html +++ b/particlewriter_8def_8h.html @@ -111,7 +111,7 @@

-

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Wednesday, Jul 10, 2024 using Doxygen and m.css. Contact us via GitHub.

+

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Thursday, Jul 11, 2024 using Doxygen and m.css. Contact us via GitHub.

diff --git a/partition_8hpp.html b/partition_8hpp.html index 35567288a992..7056c85ab2b3 100644 --- a/partition_8hpp.html +++ b/partition_8hpp.html @@ -111,7 +111,7 @@

-

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Wednesday, Jul 10, 2024 using Doxygen and m.css. Contact us via GitHub.

+

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Thursday, Jul 11, 2024 using Doxygen and m.css. Contact us via GitHub.

diff --git a/partitioner_8decl_8h.html b/partitioner_8decl_8h.html index a00d585b6655..f949fa7c4b3a 100644 --- a/partitioner_8decl_8h.html +++ b/partitioner_8decl_8h.html @@ -111,7 +111,7 @@

-

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Wednesday, Jul 10, 2024 using Doxygen and m.css. Contact us via GitHub.

+

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Thursday, Jul 11, 2024 using Doxygen and m.css. Contact us via GitHub.

diff --git a/partitioner_8def_8h.html b/partitioner_8def_8h.html index 7ffa0af71dd4..b8ee12e438d5 100644 --- a/partitioner_8def_8h.html +++ b/partitioner_8def_8h.html @@ -111,7 +111,7 @@

-

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Wednesday, Jul 10, 2024 using Doxygen and m.css. Contact us via GitHub.

+

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Thursday, Jul 11, 2024 using Doxygen and m.css. Contact us via GitHub.

diff --git a/pegtl_8hpp.html b/pegtl_8hpp.html index c65e63da6c96..7bad48930f67 100644 --- a/pegtl_8hpp.html +++ b/pegtl_8hpp.html @@ -111,7 +111,7 @@

-

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Wednesday, Jul 10, 2024 using Doxygen and m.css. Contact us via GitHub.

+

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Thursday, Jul 11, 2024 using Doxygen and m.css. Contact us via GitHub.

diff --git a/pegtl_license_page.html b/pegtl_license_page.html index 964ce90d05e5..b6291229fdf2 100644 --- a/pegtl_license_page.html +++ b/pegtl_license_page.html @@ -129,7 +129,7 @@

-

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Wednesday, Jul 10, 2024 using Doxygen and m.css. Contact us via GitHub.

+

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Thursday, Jul 11, 2024 using Doxygen and m.css. Contact us via GitHub.

diff --git a/pugixml_8hpp.html b/pugixml_8hpp.html index fd7f6fa087f2..6e50b891f717 100644 --- a/pugixml_8hpp.html +++ b/pugixml_8hpp.html @@ -111,7 +111,7 @@

-

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Wednesday, Jul 10, 2024 using Doxygen and m.css. Contact us via GitHub.

+

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Thursday, Jul 11, 2024 using Doxygen and m.css. Contact us via GitHub.

diff --git a/pugixml_license_page.html b/pugixml_license_page.html index 4bd8dd12851c..501ea75da4ee 100644 --- a/pugixml_license_page.html +++ b/pugixml_license_page.html @@ -133,7 +133,7 @@

-

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Wednesday, Jul 10, 2024 using Doxygen and m.css. Contact us via GitHub.

+

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Thursday, Jul 11, 2024 using Doxygen and m.css. Contact us via GitHub.

diff --git a/pup_8hpp.html b/pup_8hpp.html index 287f955641b3..fc96d4018438 100644 --- a/pup_8hpp.html +++ b/pup_8hpp.html @@ -111,7 +111,7 @@

-

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Wednesday, Jul 10, 2024 using Doxygen and m.css. Contact us via GitHub.

+

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Thursday, Jul 11, 2024 using Doxygen and m.css. Contact us via GitHub.

diff --git a/pup__stl_8hpp.html b/pup__stl_8hpp.html index 6810ba939fcf..27708429f98a 100644 --- a/pup__stl_8hpp.html +++ b/pup__stl_8hpp.html @@ -111,7 +111,7 @@

-

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Wednesday, Jul 10, 2024 using Doxygen and m.css. Contact us via GitHub.

+

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Thursday, Jul 11, 2024 using Doxygen and m.css. Contact us via GitHub.

diff --git a/quietcerr_8decl_8h.html b/quietcerr_8decl_8h.html index d0bd464470fd..6f8bbb6fbe93 100644 --- a/quietcerr_8decl_8h.html +++ b/quietcerr_8decl_8h.html @@ -111,7 +111,7 @@

-

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Wednesday, Jul 10, 2024 using Doxygen and m.css. Contact us via GitHub.

+

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Thursday, Jul 11, 2024 using Doxygen and m.css. Contact us via GitHub.

diff --git a/quietcerr_8def_8h.html b/quietcerr_8def_8h.html index e01c29cbbc7c..4d5d06f798c7 100644 --- a/quietcerr_8def_8h.html +++ b/quietcerr_8def_8h.html @@ -111,7 +111,7 @@

-

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Wednesday, Jul 10, 2024 using Doxygen and m.css. Contact us via GitHub.

+

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Thursday, Jul 11, 2024 using Doxygen and m.css. Contact us via GitHub.

diff --git a/refiner_8decl_8h.html b/refiner_8decl_8h.html index 88dab596cd72..13fc2251259a 100644 --- a/refiner_8decl_8h.html +++ b/refiner_8decl_8h.html @@ -111,7 +111,7 @@

-

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Wednesday, Jul 10, 2024 using Doxygen and m.css. Contact us via GitHub.

+

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Thursday, Jul 11, 2024 using Doxygen and m.css. Contact us via GitHub.

diff --git a/refiner_8def_8h.html b/refiner_8def_8h.html index a4b1fb934939..f38cc947a770 100644 --- a/refiner_8def_8h.html +++ b/refiner_8def_8h.html @@ -111,7 +111,7 @@

-

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Wednesday, Jul 10, 2024 using Doxygen and m.css. Contact us via GitHub.

+

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Thursday, Jul 11, 2024 using Doxygen and m.css. Contact us via GitHub.

diff --git a/resources.html b/resources.html index 262dd99c9a28..881d41902919 100644 --- a/resources.html +++ b/resources.html @@ -110,7 +110,7 @@

-

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Wednesday, Jul 10, 2024 using Doxygen and m.css. Contact us via GitHub.

+

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Thursday, Jul 11, 2024 using Doxygen and m.css. Contact us via GitHub.

diff --git a/roadmap.html b/roadmap.html index e6b8edfe4a6e..08880b027cfc 100644 --- a/roadmap.html +++ b/roadmap.html @@ -155,7 +155,7 @@

Contents

-

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Wednesday, Jul 10, 2024 using Doxygen and m.css. Contact us via GitHub.

+

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Thursday, Jul 11, 2024 using Doxygen and m.css. Contact us via GitHub.

diff --git a/running_inciter.html b/running_inciter.html index 5a74ff576aa8..4d1b53f9965c 100644 --- a/running_inciter.html +++ b/running_inciter.html @@ -127,7 +127,7 @@

-

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Wednesday, Jul 10, 2024 using Doxygen and m.css. Contact us via GitHub.

+

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Thursday, Jul 11, 2024 using Doxygen and m.css. Contact us via GitHub.

diff --git a/running_meshconv.html b/running_meshconv.html index 4946c4892444..7e0fcfdb306f 100644 --- a/running_meshconv.html +++ b/running_meshconv.html @@ -112,7 +112,7 @@

-

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Wednesday, Jul 10, 2024 using Doxygen and m.css. Contact us via GitHub.

+

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Thursday, Jul 11, 2024 using Doxygen and m.css. Contact us via GitHub.

diff --git a/seacas_license_page.html b/seacas_license_page.html index 6914536bfa49..720c8f5e3692 100644 --- a/seacas_license_page.html +++ b/seacas_license_page.html @@ -271,7 +271,7 @@

-

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Wednesday, Jul 10, 2024 using Doxygen and m.css. Contact us via GitHub.

+

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Thursday, Jul 11, 2024 using Doxygen and m.css. Contact us via GitHub.

diff --git a/set_8hpp.html b/set_8hpp.html index a3ba3a989129..ec3269658619 100644 --- a/set_8hpp.html +++ b/set_8hpp.html @@ -111,7 +111,7 @@

-

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Wednesday, Jul 10, 2024 using Doxygen and m.css. Contact us via GitHub.

+

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Thursday, Jul 11, 2024 using Doxygen and m.css. Contact us via GitHub.

diff --git a/sip__hash_8hpp.html b/sip__hash_8hpp.html index 24c54c515ef7..e18a24311401 100644 --- a/sip__hash_8hpp.html +++ b/sip__hash_8hpp.html @@ -111,7 +111,7 @@

-

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Wednesday, Jul 10, 2024 using Doxygen and m.css. Contact us via GitHub.

+

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Thursday, Jul 11, 2024 using Doxygen and m.css. Contact us via GitHub.

diff --git a/sol2_license_page.html b/sol2_license_page.html index 3e7e550c0215..995e3026b10a 100644 --- a/sol2_license_page.html +++ b/sol2_license_page.html @@ -131,7 +131,7 @@

-

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Wednesday, Jul 10, 2024 using Doxygen and m.css. Contact us via GitHub.

+

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Thursday, Jul 11, 2024 using Doxygen and m.css. Contact us via GitHub.

diff --git a/sol_8hpp.html b/sol_8hpp.html index 13c30b0deade..695001691e1f 100644 --- a/sol_8hpp.html +++ b/sol_8hpp.html @@ -111,7 +111,7 @@

-

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Wednesday, Jul 10, 2024 using Doxygen and m.css. Contact us via GitHub.

+

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Thursday, Jul 11, 2024 using Doxygen and m.css. Contact us via GitHub.

diff --git a/sorter_8decl_8h.html b/sorter_8decl_8h.html index 1ad7db2e9b5c..bdf62dfe7bf3 100644 --- a/sorter_8decl_8h.html +++ b/sorter_8decl_8h.html @@ -111,7 +111,7 @@

-

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Wednesday, Jul 10, 2024 using Doxygen and m.css. Contact us via GitHub.

+

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Thursday, Jul 11, 2024 using Doxygen and m.css. Contact us via GitHub.

diff --git a/sorter_8def_8h.html b/sorter_8def_8h.html index a484d18b4974..43f705eea761 100644 --- a/sorter_8def_8h.html +++ b/sorter_8def_8h.html @@ -111,7 +111,7 @@

-

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Wednesday, Jul 10, 2024 using Doxygen and m.css. Contact us via GitHub.

+

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Thursday, Jul 11, 2024 using Doxygen and m.css. Contact us via GitHub.

diff --git a/structinciter_1_1_a_u_s_m.html b/structinciter_1_1_a_u_s_m.html index c0b82b0ac795..6fd1c52fd08e 100644 --- a/structinciter_1_1_a_u_s_m.html +++ b/structinciter_1_1_a_u_s_m.html @@ -188,7 +188,7 @@

-

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Wednesday, Jul 10, 2024 using Doxygen and m.css. Contact us via GitHub.

+

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Thursday, Jul 11, 2024 using Doxygen and m.css. Contact us via GitHub.

diff --git a/structinciter_1_1_config_b_c.html b/structinciter_1_1_config_b_c.html index 4b884a7e6387..40f74d7e441c 100644 --- a/structinciter_1_1_config_b_c.html +++ b/structinciter_1_1_config_b_c.html @@ -163,7 +163,7 @@

-

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Wednesday, Jul 10, 2024 using Doxygen and m.css. Contact us via GitHub.

+

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Thursday, Jul 11, 2024 using Doxygen and m.css. Contact us via GitHub.

diff --git a/structinciter_1_1_discretization_1_1_sideset_nodes.html b/structinciter_1_1_discretization_1_1_sideset_nodes.html index f7dabf227e97..bbbbf075a4ae 100644 --- a/structinciter_1_1_discretization_1_1_sideset_nodes.html +++ b/structinciter_1_1_discretization_1_1_sideset_nodes.html @@ -111,7 +111,7 @@

-

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Wednesday, Jul 10, 2024 using Doxygen and m.css. Contact us via GitHub.

+

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Thursday, Jul 11, 2024 using Doxygen and m.css. Contact us via GitHub.

diff --git a/structinciter_1_1_e_o_s_1_1_cauchy_stress.html b/structinciter_1_1_e_o_s_1_1_cauchy_stress.html index 6b00c9060915..1496ff4dfb8a 100644 --- a/structinciter_1_1_e_o_s_1_1_cauchy_stress.html +++ b/structinciter_1_1_e_o_s_1_1_cauchy_stress.html @@ -110,7 +110,7 @@

-

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Wednesday, Jul 10, 2024 using Doxygen and m.css. Contact us via GitHub.

+

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Thursday, Jul 11, 2024 using Doxygen and m.css. Contact us via GitHub.

diff --git a/structinciter_1_1_e_o_s_1_1density.html b/structinciter_1_1_e_o_s_1_1density.html index 0ce2e2906472..8158eb9220e7 100644 --- a/structinciter_1_1_e_o_s_1_1density.html +++ b/structinciter_1_1_e_o_s_1_1density.html @@ -110,7 +110,7 @@

-

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Wednesday, Jul 10, 2024 using Doxygen and m.css. Contact us via GitHub.

+

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Thursday, Jul 11, 2024 using Doxygen and m.css. Contact us via GitHub.

diff --git a/structinciter_1_1_ghosts_1_1_out_mesh.html b/structinciter_1_1_ghosts_1_1_out_mesh.html index 2ceaf76ad7b7..874efab54d1c 100644 --- a/structinciter_1_1_ghosts_1_1_out_mesh.html +++ b/structinciter_1_1_ghosts_1_1_out_mesh.html @@ -170,7 +170,7 @@

-

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Wednesday, Jul 10, 2024 using Doxygen and m.css. Contact us via GitHub.

+

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Thursday, Jul 11, 2024 using Doxygen and m.css. Contact us via GitHub.

diff --git a/structinciter_1_1_h_l_l.html b/structinciter_1_1_h_l_l.html index 3ca53651472c..b97c7fdafa3e 100644 --- a/structinciter_1_1_h_l_l.html +++ b/structinciter_1_1_h_l_l.html @@ -188,7 +188,7 @@

-

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Wednesday, Jul 10, 2024 using Doxygen and m.css. Contact us via GitHub.

+

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Thursday, Jul 11, 2024 using Doxygen and m.css. Contact us via GitHub.

diff --git a/structinciter_1_1_h_l_l_c.html b/structinciter_1_1_h_l_l_c.html index 94fae4a7107e..a82dc7b837cc 100644 --- a/structinciter_1_1_h_l_l_c.html +++ b/structinciter_1_1_h_l_l_c.html @@ -188,7 +188,7 @@

-

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Wednesday, Jul 10, 2024 using Doxygen and m.css. Contact us via GitHub.

+

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Thursday, Jul 11, 2024 using Doxygen and m.css. Contact us via GitHub.

diff --git a/structinciter_1_1_lax_friedrichs.html b/structinciter_1_1_lax_friedrichs.html index 9b8c84eed8c2..8afc4961fca2 100644 --- a/structinciter_1_1_lax_friedrichs.html +++ b/structinciter_1_1_lax_friedrichs.html @@ -188,7 +188,7 @@

-

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Wednesday, Jul 10, 2024 using Doxygen and m.css. Contact us via GitHub.

+

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Thursday, Jul 11, 2024 using Doxygen and m.css. Contact us via GitHub.

diff --git a/structinciter_1_1_lax_friedrichs_solids.html b/structinciter_1_1_lax_friedrichs_solids.html index 0557dc44a3ff..09641fcec669 100644 --- a/structinciter_1_1_lax_friedrichs_solids.html +++ b/structinciter_1_1_lax_friedrichs_solids.html @@ -170,7 +170,7 @@

-

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Wednesday, Jul 10, 2024 using Doxygen and m.css. Contact us via GitHub.

+

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Thursday, Jul 11, 2024 using Doxygen and m.css. Contact us via GitHub.

diff --git a/structinciter_1_1_rusanov.html b/structinciter_1_1_rusanov.html index bd23d382f885..aa9d1568eca1 100644 --- a/structinciter_1_1_rusanov.html +++ b/structinciter_1_1_rusanov.html @@ -342,7 +342,7 @@

-

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Wednesday, Jul 10, 2024 using Doxygen and m.css. Contact us via GitHub.

+

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Thursday, Jul 11, 2024 using Doxygen and m.css. Contact us via GitHub.

diff --git a/structinciter_1_1_scheme_1_1resize_post_a_m_r.html b/structinciter_1_1_scheme_1_1resize_post_a_m_r.html index 4add3ab96314..aa246d8dd5d8 100644 --- a/structinciter_1_1_scheme_1_1resize_post_a_m_r.html +++ b/structinciter_1_1_scheme_1_1resize_post_a_m_r.html @@ -110,7 +110,7 @@

-

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Wednesday, Jul 10, 2024 using Doxygen and m.css. Contact us via GitHub.

+

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Thursday, Jul 11, 2024 using Doxygen and m.css. Contact us via GitHub.

diff --git a/structinciter_1_1_scheme_1_1setup.html b/structinciter_1_1_scheme_1_1setup.html index c3406c4752ed..aee34fa9e687 100644 --- a/structinciter_1_1_scheme_1_1setup.html +++ b/structinciter_1_1_scheme_1_1setup.html @@ -110,7 +110,7 @@

-

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Wednesday, Jul 10, 2024 using Doxygen and m.css. Contact us via GitHub.

+

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Thursday, Jul 11, 2024 using Doxygen and m.css. Contact us via GitHub.

diff --git a/structinciter_1_1_transfer.html b/structinciter_1_1_transfer.html index 39177dc9338c..c3c2b08ed63a 100644 --- a/structinciter_1_1_transfer.html +++ b/structinciter_1_1_transfer.html @@ -304,7 +304,7 @@

-

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Wednesday, Jul 10, 2024 using Doxygen and m.css. Contact us via GitHub.

+

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Thursday, Jul 11, 2024 using Doxygen and m.css. Contact us via GitHub.

diff --git a/structinciter_1_1_upwind.html b/structinciter_1_1_upwind.html index 61abd095bc3c..33ee89ce4af0 100644 --- a/structinciter_1_1_upwind.html +++ b/structinciter_1_1_upwind.html @@ -188,7 +188,7 @@

-

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Wednesday, Jul 10, 2024 using Doxygen and m.css. Contact us via GitHub.

+

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Thursday, Jul 11, 2024 using Doxygen and m.css. Contact us via GitHub.

diff --git a/structinciter_1_1cmd_1_1benchmark.html b/structinciter_1_1cmd_1_1benchmark.html index c887de6beb2c..cc0cb56cb905 100644 --- a/structinciter_1_1cmd_1_1benchmark.html +++ b/structinciter_1_1cmd_1_1benchmark.html @@ -120,7 +120,7 @@

Base classes

-

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Wednesday, Jul 10, 2024 using Doxygen and m.css. Contact us via GitHub.

+

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Thursday, Jul 11, 2024 using Doxygen and m.css. Contact us via GitHub.

diff --git a/structinciter_1_1cmd_1_1charestate.html b/structinciter_1_1cmd_1_1charestate.html index 83e0ed8b0df1..b5d7a78b458d 100644 --- a/structinciter_1_1cmd_1_1charestate.html +++ b/structinciter_1_1cmd_1_1charestate.html @@ -120,7 +120,7 @@

Base classes

-

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Wednesday, Jul 10, 2024 using Doxygen and m.css. Contact us via GitHub.

+

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Thursday, Jul 11, 2024 using Doxygen and m.css. Contact us via GitHub.

diff --git a/structinciter_1_1cmd_1_1feedback.html b/structinciter_1_1cmd_1_1feedback.html index 044072b48538..505fd742ae27 100644 --- a/structinciter_1_1cmd_1_1feedback.html +++ b/structinciter_1_1cmd_1_1feedback.html @@ -120,7 +120,7 @@

Base classes

-

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Wednesday, Jul 10, 2024 using Doxygen and m.css. Contact us via GitHub.

+

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Thursday, Jul 11, 2024 using Doxygen and m.css. Contact us via GitHub.

diff --git a/structinciter_1_1cmd_1_1help.html b/structinciter_1_1cmd_1_1help.html index 2f50f059ad63..46f3a4b174ac 100644 --- a/structinciter_1_1cmd_1_1help.html +++ b/structinciter_1_1cmd_1_1help.html @@ -120,7 +120,7 @@

Base classes

-

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Wednesday, Jul 10, 2024 using Doxygen and m.css. Contact us via GitHub.

+

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Thursday, Jul 11, 2024 using Doxygen and m.css. Contact us via GitHub.

diff --git a/structinciter_1_1cmd_1_1helpctr.html b/structinciter_1_1cmd_1_1helpctr.html index 65c1766d7dab..95c6ee2c93a0 100644 --- a/structinciter_1_1cmd_1_1helpctr.html +++ b/structinciter_1_1cmd_1_1helpctr.html @@ -120,7 +120,7 @@

Base classes

-

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Wednesday, Jul 10, 2024 using Doxygen and m.css. Contact us via GitHub.

+

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Thursday, Jul 11, 2024 using Doxygen and m.css. Contact us via GitHub.

diff --git a/structinciter_1_1cmd_1_1helpkw.html b/structinciter_1_1cmd_1_1helpkw.html index ae0da033dead..fa13f1c963ad 100644 --- a/structinciter_1_1cmd_1_1helpkw.html +++ b/structinciter_1_1cmd_1_1helpkw.html @@ -120,7 +120,7 @@

Base classes

-

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Wednesday, Jul 10, 2024 using Doxygen and m.css. Contact us via GitHub.

+

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Thursday, Jul 11, 2024 using Doxygen and m.css. Contact us via GitHub.

diff --git a/structinciter_1_1cmd_1_1io.html b/structinciter_1_1cmd_1_1io.html index e4424cfc4f45..14de0c3d9efe 100644 --- a/structinciter_1_1cmd_1_1io.html +++ b/structinciter_1_1cmd_1_1io.html @@ -121,7 +121,7 @@

Base classes

-

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Wednesday, Jul 10, 2024 using Doxygen and m.css. Contact us via GitHub.

+

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Thursday, Jul 11, 2024 using Doxygen and m.css. Contact us via GitHub.

diff --git a/structinciter_1_1cmd_1_1keywords.html b/structinciter_1_1cmd_1_1keywords.html index 9fe5bfde661d..06effe0c7fd2 100644 --- a/structinciter_1_1cmd_1_1keywords.html +++ b/structinciter_1_1cmd_1_1keywords.html @@ -110,7 +110,7 @@

-

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Wednesday, Jul 10, 2024 using Doxygen and m.css. Contact us via GitHub.

+

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Thursday, Jul 11, 2024 using Doxygen and m.css. Contact us via GitHub.

diff --git a/structinciter_1_1cmd_1_1lbfreq.html b/structinciter_1_1cmd_1_1lbfreq.html index 54f6b3efc2cd..26e51b5a0636 100644 --- a/structinciter_1_1cmd_1_1lbfreq.html +++ b/structinciter_1_1cmd_1_1lbfreq.html @@ -120,7 +120,7 @@

Base classes

-

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Wednesday, Jul 10, 2024 using Doxygen and m.css. Contact us via GitHub.

+

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Thursday, Jul 11, 2024 using Doxygen and m.css. Contact us via GitHub.

diff --git a/structinciter_1_1cmd_1_1license.html b/structinciter_1_1cmd_1_1license.html index 6e96a5370157..65d49c98fb4f 100644 --- a/structinciter_1_1cmd_1_1license.html +++ b/structinciter_1_1cmd_1_1license.html @@ -120,7 +120,7 @@

Base classes

-

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Wednesday, Jul 10, 2024 using Doxygen and m.css. Contact us via GitHub.

+

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Thursday, Jul 11, 2024 using Doxygen and m.css. Contact us via GitHub.

diff --git a/structinciter_1_1cmd_1_1nonblocking.html b/structinciter_1_1cmd_1_1nonblocking.html index 683276a58ecc..122a73364d74 100644 --- a/structinciter_1_1cmd_1_1nonblocking.html +++ b/structinciter_1_1cmd_1_1nonblocking.html @@ -120,7 +120,7 @@

Base classes

-

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Wednesday, Jul 10, 2024 using Doxygen and m.css. Contact us via GitHub.

+

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Thursday, Jul 11, 2024 using Doxygen and m.css. Contact us via GitHub.

diff --git a/structinciter_1_1cmd_1_1quiescence.html b/structinciter_1_1cmd_1_1quiescence.html index 73c9217ebf58..ca42ef5b3678 100644 --- a/structinciter_1_1cmd_1_1quiescence.html +++ b/structinciter_1_1cmd_1_1quiescence.html @@ -120,7 +120,7 @@

Base classes

-

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Wednesday, Jul 10, 2024 using Doxygen and m.css. Contact us via GitHub.

+

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Thursday, Jul 11, 2024 using Doxygen and m.css. Contact us via GitHub.

diff --git a/structinciter_1_1cmd_1_1read__string.html b/structinciter_1_1cmd_1_1read__string.html index e1ef650c408f..60fbd6e4a2f1 100644 --- a/structinciter_1_1cmd_1_1read__string.html +++ b/structinciter_1_1cmd_1_1read__string.html @@ -120,7 +120,7 @@

Base classes

-

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Wednesday, Jul 10, 2024 using Doxygen and m.css. Contact us via GitHub.

+

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Thursday, Jul 11, 2024 using Doxygen and m.css. Contact us via GitHub.

diff --git a/structinciter_1_1cmd_1_1rsfreq.html b/structinciter_1_1cmd_1_1rsfreq.html index 1c9c791230b8..81fd09304bec 100644 --- a/structinciter_1_1cmd_1_1rsfreq.html +++ b/structinciter_1_1cmd_1_1rsfreq.html @@ -120,7 +120,7 @@

Base classes

-

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Wednesday, Jul 10, 2024 using Doxygen and m.css. Contact us via GitHub.

+

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Thursday, Jul 11, 2024 using Doxygen and m.css. Contact us via GitHub.

diff --git a/structinciter_1_1cmd_1_1trace.html b/structinciter_1_1cmd_1_1trace.html index fc8a872092ae..f9f30b6ccf04 100644 --- a/structinciter_1_1cmd_1_1trace.html +++ b/structinciter_1_1cmd_1_1trace.html @@ -120,7 +120,7 @@

Base classes

-

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Wednesday, Jul 10, 2024 using Doxygen and m.css. Contact us via GitHub.

+

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Thursday, Jul 11, 2024 using Doxygen and m.css. Contact us via GitHub.

diff --git a/structinciter_1_1cmd_1_1verbose.html b/structinciter_1_1cmd_1_1verbose.html index a93fd5f3e0e7..520b0047e217 100644 --- a/structinciter_1_1cmd_1_1verbose.html +++ b/structinciter_1_1cmd_1_1verbose.html @@ -120,7 +120,7 @@

Base classes

-

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Wednesday, Jul 10, 2024 using Doxygen and m.css. Contact us via GitHub.

+

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Thursday, Jul 11, 2024 using Doxygen and m.css. Contact us via GitHub.

diff --git a/structinciter_1_1cmd_1_1version.html b/structinciter_1_1cmd_1_1version.html index cdb509de4955..e050f2d06112 100644 --- a/structinciter_1_1cmd_1_1version.html +++ b/structinciter_1_1cmd_1_1version.html @@ -120,7 +120,7 @@

Base classes

-

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Wednesday, Jul 10, 2024 using Doxygen and m.css. Contact us via GitHub.

+

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Thursday, Jul 11, 2024 using Doxygen and m.css. Contact us via GitHub.

diff --git a/structinciter_1_1cmd_1_1virtualization.html b/structinciter_1_1cmd_1_1virtualization.html index 6a917af5e8bd..f155921b0274 100644 --- a/structinciter_1_1cmd_1_1virtualization.html +++ b/structinciter_1_1cmd_1_1virtualization.html @@ -120,7 +120,7 @@

Base classes

-

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Wednesday, Jul 10, 2024 using Doxygen and m.css. Contact us via GitHub.

+

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Thursday, Jul 11, 2024 using Doxygen and m.css. Contact us via GitHub.

diff --git a/structinciter_1_1ctr_1_1_out_var.html b/structinciter_1_1ctr_1_1_out_var.html index fa62127fa200..a1ab999ac36e 100644 --- a/structinciter_1_1ctr_1_1_out_var.html +++ b/structinciter_1_1ctr_1_1_out_var.html @@ -286,7 +286,7 @@

-

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Wednesday, Jul 10, 2024 using Doxygen and m.css. Contact us via GitHub.

+

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Thursday, Jul 11, 2024 using Doxygen and m.css. Contact us via GitHub.

diff --git a/structinciter_1_1register_c_g.html b/structinciter_1_1register_c_g.html index 16186dee9125..09f87313e68f 100644 --- a/structinciter_1_1register_c_g.html +++ b/structinciter_1_1register_c_g.html @@ -177,7 +177,7 @@

-

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Wednesday, Jul 10, 2024 using Doxygen and m.css. Contact us via GitHub.

+

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Thursday, Jul 11, 2024 using Doxygen and m.css. Contact us via GitHub.

diff --git a/structinciter_1_1register_d_g.html b/structinciter_1_1register_d_g.html index 0d09a49f54cc..a1b1bed5e82c 100644 --- a/structinciter_1_1register_d_g.html +++ b/structinciter_1_1register_d_g.html @@ -177,7 +177,7 @@

-

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Wednesday, Jul 10, 2024 using Doxygen and m.css. Contact us via GitHub.

+

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Thursday, Jul 11, 2024 using Doxygen and m.css. Contact us via GitHub.

diff --git a/structinciter_1_1register_f_v.html b/structinciter_1_1register_f_v.html index b46f53ad04af..09819baec9c7 100644 --- a/structinciter_1_1register_f_v.html +++ b/structinciter_1_1register_f_v.html @@ -177,7 +177,7 @@

-

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Wednesday, Jul 10, 2024 using Doxygen and m.css. Contact us via GitHub.

+

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Thursday, Jul 11, 2024 using Doxygen and m.css. Contact us via GitHub.

diff --git a/structinciter_1_1register_p_d_e.html b/structinciter_1_1register_p_d_e.html index f853679cb302..073eb9e30e22 100644 --- a/structinciter_1_1register_p_d_e.html +++ b/structinciter_1_1register_p_d_e.html @@ -188,7 +188,7 @@

-

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Wednesday, Jul 10, 2024 using Doxygen and m.css. Contact us via GitHub.

+

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Thursday, Jul 11, 2024 using Doxygen and m.css. Contact us via GitHub.

diff --git a/structkw_1_1_alias.html b/structkw_1_1_alias.html index b3ea031c19ac..d7eae24cd81c 100644 --- a/structkw_1_1_alias.html +++ b/structkw_1_1_alias.html @@ -112,7 +112,7 @@

-

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Wednesday, Jul 10, 2024 using Doxygen and m.css. Contact us via GitHub.

+

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Thursday, Jul 11, 2024 using Doxygen and m.css. Contact us via GitHub.

diff --git a/structkw_1_1keyword.html b/structkw_1_1keyword.html index 233d79f0f1d5..b4264c21c17e 100644 --- a/structkw_1_1keyword.html +++ b/structkw_1_1keyword.html @@ -112,7 +112,7 @@

-

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Wednesday, Jul 10, 2024 using Doxygen and m.css. Contact us via GitHub.

+

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Thursday, Jul 11, 2024 using Doxygen and m.css. Contact us via GitHub.

diff --git a/structmeshconv_1_1cmd_1_1charestate.html b/structmeshconv_1_1cmd_1_1charestate.html index d024cde4dbe7..4b5a65b6150c 100644 --- a/structmeshconv_1_1cmd_1_1charestate.html +++ b/structmeshconv_1_1cmd_1_1charestate.html @@ -120,7 +120,7 @@

Base classes

-

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Wednesday, Jul 10, 2024 using Doxygen and m.css. Contact us via GitHub.

+

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Thursday, Jul 11, 2024 using Doxygen and m.css. Contact us via GitHub.

diff --git a/structmeshconv_1_1cmd_1_1help.html b/structmeshconv_1_1cmd_1_1help.html index 7bd6e71f0e4c..e34648d29535 100644 --- a/structmeshconv_1_1cmd_1_1help.html +++ b/structmeshconv_1_1cmd_1_1help.html @@ -120,7 +120,7 @@

Base classes

-

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Wednesday, Jul 10, 2024 using Doxygen and m.css. Contact us via GitHub.

+

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Thursday, Jul 11, 2024 using Doxygen and m.css. Contact us via GitHub.

diff --git a/structmeshconv_1_1cmd_1_1helpkw.html b/structmeshconv_1_1cmd_1_1helpkw.html index f08ee82015b6..2911fa6d3dad 100644 --- a/structmeshconv_1_1cmd_1_1helpkw.html +++ b/structmeshconv_1_1cmd_1_1helpkw.html @@ -120,7 +120,7 @@

Base classes

-

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Wednesday, Jul 10, 2024 using Doxygen and m.css. Contact us via GitHub.

+

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Thursday, Jul 11, 2024 using Doxygen and m.css. Contact us via GitHub.

diff --git a/structmeshconv_1_1cmd_1_1io.html b/structmeshconv_1_1cmd_1_1io.html index 39a5b58d0b3b..f5152549fd06 100644 --- a/structmeshconv_1_1cmd_1_1io.html +++ b/structmeshconv_1_1cmd_1_1io.html @@ -121,7 +121,7 @@

Base classes

-

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Wednesday, Jul 10, 2024 using Doxygen and m.css. Contact us via GitHub.

+

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Thursday, Jul 11, 2024 using Doxygen and m.css. Contact us via GitHub.

diff --git a/structmeshconv_1_1cmd_1_1keywords.html b/structmeshconv_1_1cmd_1_1keywords.html index 68175af768ee..7f1aef605b84 100644 --- a/structmeshconv_1_1cmd_1_1keywords.html +++ b/structmeshconv_1_1cmd_1_1keywords.html @@ -110,7 +110,7 @@

-

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Wednesday, Jul 10, 2024 using Doxygen and m.css. Contact us via GitHub.

+

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Thursday, Jul 11, 2024 using Doxygen and m.css. Contact us via GitHub.

diff --git a/structmeshconv_1_1cmd_1_1license.html b/structmeshconv_1_1cmd_1_1license.html index 6469825c9cae..56b804a28851 100644 --- a/structmeshconv_1_1cmd_1_1license.html +++ b/structmeshconv_1_1cmd_1_1license.html @@ -120,7 +120,7 @@

Base classes

-

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Wednesday, Jul 10, 2024 using Doxygen and m.css. Contact us via GitHub.

+

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Thursday, Jul 11, 2024 using Doxygen and m.css. Contact us via GitHub.

diff --git a/structmeshconv_1_1cmd_1_1quiescence.html b/structmeshconv_1_1cmd_1_1quiescence.html index 040de8a9fd7e..01ed8d7fc18e 100644 --- a/structmeshconv_1_1cmd_1_1quiescence.html +++ b/structmeshconv_1_1cmd_1_1quiescence.html @@ -120,7 +120,7 @@

Base classes

-

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Wednesday, Jul 10, 2024 using Doxygen and m.css. Contact us via GitHub.

+

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Thursday, Jul 11, 2024 using Doxygen and m.css. Contact us via GitHub.

diff --git a/structmeshconv_1_1cmd_1_1read__string.html b/structmeshconv_1_1cmd_1_1read__string.html index 00f90faeef8d..5db57988f075 100644 --- a/structmeshconv_1_1cmd_1_1read__string.html +++ b/structmeshconv_1_1cmd_1_1read__string.html @@ -120,7 +120,7 @@

Base classes

-

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Wednesday, Jul 10, 2024 using Doxygen and m.css. Contact us via GitHub.

+

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Thursday, Jul 11, 2024 using Doxygen and m.css. Contact us via GitHub.

diff --git a/structmeshconv_1_1cmd_1_1reorder.html b/structmeshconv_1_1cmd_1_1reorder.html index 6b085e82adb3..b0f496b95dee 100644 --- a/structmeshconv_1_1cmd_1_1reorder.html +++ b/structmeshconv_1_1cmd_1_1reorder.html @@ -120,7 +120,7 @@

Base classes

-

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Wednesday, Jul 10, 2024 using Doxygen and m.css. Contact us via GitHub.

+

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Thursday, Jul 11, 2024 using Doxygen and m.css. Contact us via GitHub.

diff --git a/structmeshconv_1_1cmd_1_1trace.html b/structmeshconv_1_1cmd_1_1trace.html index 0bb3faff765d..e9ef617406a8 100644 --- a/structmeshconv_1_1cmd_1_1trace.html +++ b/structmeshconv_1_1cmd_1_1trace.html @@ -120,7 +120,7 @@

Base classes

-

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Wednesday, Jul 10, 2024 using Doxygen and m.css. Contact us via GitHub.

+

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Thursday, Jul 11, 2024 using Doxygen and m.css. Contact us via GitHub.

diff --git a/structmeshconv_1_1cmd_1_1verbose.html b/structmeshconv_1_1cmd_1_1verbose.html index 9e018395c5b5..49e0ae2e61c3 100644 --- a/structmeshconv_1_1cmd_1_1verbose.html +++ b/structmeshconv_1_1cmd_1_1verbose.html @@ -120,7 +120,7 @@

Base classes

-

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Wednesday, Jul 10, 2024 using Doxygen and m.css. Contact us via GitHub.

+

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Thursday, Jul 11, 2024 using Doxygen and m.css. Contact us via GitHub.

diff --git a/structmeshconv_1_1cmd_1_1version.html b/structmeshconv_1_1cmd_1_1version.html index 3976092f067d..adc7ced9046a 100644 --- a/structmeshconv_1_1cmd_1_1version.html +++ b/structmeshconv_1_1cmd_1_1version.html @@ -120,7 +120,7 @@

Base classes

-

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Wednesday, Jul 10, 2024 using Doxygen and m.css. Contact us via GitHub.

+

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Thursday, Jul 11, 2024 using Doxygen and m.css. Contact us via GitHub.

diff --git a/structtk_1_1_deep_tuple_printer.html b/structtk_1_1_deep_tuple_printer.html index 285e118ee031..3d0e13a886a3 100644 --- a/structtk_1_1_deep_tuple_printer.html +++ b/structtk_1_1_deep_tuple_printer.html @@ -159,7 +159,7 @@

Public functions

-

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Wednesday, Jul 10, 2024 using Doxygen and m.css. Contact us via GitHub.

+

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Thursday, Jul 11, 2024 using Doxygen and m.css. Contact us via GitHub.

diff --git a/structtk_1_1_has_function__expect__choices.html b/structtk_1_1_has_function__expect__choices.html index 15f4df6c56ba..e5518df3a783 100644 --- a/structtk_1_1_has_function__expect__choices.html +++ b/structtk_1_1_has_function__expect__choices.html @@ -111,7 +111,7 @@

-

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Wednesday, Jul 10, 2024 using Doxygen and m.css. Contact us via GitHub.

+

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Thursday, Jul 11, 2024 using Doxygen and m.css. Contact us via GitHub.

diff --git a/structtk_1_1_has_function__expect__description.html b/structtk_1_1_has_function__expect__description.html index 4bee6cead64f..b530dff7b148 100644 --- a/structtk_1_1_has_function__expect__description.html +++ b/structtk_1_1_has_function__expect__description.html @@ -111,7 +111,7 @@

-

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Wednesday, Jul 10, 2024 using Doxygen and m.css. Contact us via GitHub.

+

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Thursday, Jul 11, 2024 using Doxygen and m.css. Contact us via GitHub.

diff --git a/structtk_1_1_has_typedef__alias.html b/structtk_1_1_has_typedef__alias.html index 60ee32da1615..aaafe47c64bb 100644 --- a/structtk_1_1_has_typedef__alias.html +++ b/structtk_1_1_has_typedef__alias.html @@ -111,7 +111,7 @@

-

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Wednesday, Jul 10, 2024 using Doxygen and m.css. Contact us via GitHub.

+

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Thursday, Jul 11, 2024 using Doxygen and m.css. Contact us via GitHub.

diff --git a/structtk_1_1_has_typedef__i__am__tagged__tuple.html b/structtk_1_1_has_typedef__i__am__tagged__tuple.html index 075e9892c4e5..8dd9c872ea61 100644 --- a/structtk_1_1_has_typedef__i__am__tagged__tuple.html +++ b/structtk_1_1_has_typedef__i__am__tagged__tuple.html @@ -111,7 +111,7 @@

-

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Wednesday, Jul 10, 2024 using Doxygen and m.css. Contact us via GitHub.

+

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Thursday, Jul 11, 2024 using Doxygen and m.css. Contact us via GitHub.

diff --git a/structtk_1_1_has_var__expect__lower.html b/structtk_1_1_has_var__expect__lower.html index bcbaca418a0b..ad4b141fd131 100644 --- a/structtk_1_1_has_var__expect__lower.html +++ b/structtk_1_1_has_var__expect__lower.html @@ -111,7 +111,7 @@

-

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Wednesday, Jul 10, 2024 using Doxygen and m.css. Contact us via GitHub.

+

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Thursday, Jul 11, 2024 using Doxygen and m.css. Contact us via GitHub.

diff --git a/structtk_1_1_has_var__expect__upper.html b/structtk_1_1_has_var__expect__upper.html index 94592c8e3f32..2f72f8909117 100644 --- a/structtk_1_1_has_var__expect__upper.html +++ b/structtk_1_1_has_var__expect__upper.html @@ -111,7 +111,7 @@

-

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Wednesday, Jul 10, 2024 using Doxygen and m.css. Contact us via GitHub.

+

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Thursday, Jul 11, 2024 using Doxygen and m.css. Contact us via GitHub.

diff --git a/structtk_1_1_timer_1_1_watch.html b/structtk_1_1_timer_1_1_watch.html index 65899529fade..113f0f29b14f 100644 --- a/structtk_1_1_timer_1_1_watch.html +++ b/structtk_1_1_timer_1_1_watch.html @@ -136,7 +136,7 @@

Constructors, destructors, conversion operators<
-

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Wednesday, Jul 10, 2024 using Doxygen and m.css. Contact us via GitHub.

+

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Thursday, Jul 11, 2024 using Doxygen and m.css. Contact us via GitHub.

diff --git a/structtk_1_1_tuple_printer.html b/structtk_1_1_tuple_printer.html index f2ac9d9b8cdf..9eb8239ad6ce 100644 --- a/structtk_1_1_tuple_printer.html +++ b/structtk_1_1_tuple_printer.html @@ -158,7 +158,7 @@

Public functions

-

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Wednesday, Jul 10, 2024 using Doxygen and m.css. Contact us via GitHub.

+

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Thursday, Jul 11, 2024 using Doxygen and m.css. Contact us via GitHub.

diff --git a/structtk_1_1_uns_mesh_1_1_eq.html b/structtk_1_1_uns_mesh_1_1_eq.html index 5ef66cc5a684..98ddba7b9831 100644 --- a/structtk_1_1_uns_mesh_1_1_eq.html +++ b/structtk_1_1_uns_mesh_1_1_eq.html @@ -177,7 +177,7 @@

-

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Wednesday, Jul 10, 2024 using Doxygen and m.css. Contact us via GitHub.

+

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Thursday, Jul 11, 2024 using Doxygen and m.css. Contact us via GitHub.

diff --git a/structtk_1_1_uns_mesh_1_1_hash.html b/structtk_1_1_uns_mesh_1_1_hash.html index acafbaccd231..aa43f58656ae 100644 --- a/structtk_1_1_uns_mesh_1_1_hash.html +++ b/structtk_1_1_uns_mesh_1_1_hash.html @@ -171,7 +171,7 @@

-

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Wednesday, Jul 10, 2024 using Doxygen and m.css. Contact us via GitHub.

+

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Thursday, Jul 11, 2024 using Doxygen and m.css. Contact us via GitHub.

diff --git a/structtk_1_1ctr_1_1_help_kw.html b/structtk_1_1ctr_1_1_help_kw.html index beb730d14630..f5913a32ae45 100644 --- a/structtk_1_1ctr_1_1_help_kw.html +++ b/structtk_1_1ctr_1_1_help_kw.html @@ -190,7 +190,7 @@

-

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Wednesday, Jul 10, 2024 using Doxygen and m.css. Contact us via GitHub.

+

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Thursday, Jul 11, 2024 using Doxygen and m.css. Contact us via GitHub.

diff --git a/structtk_1_1ctr_1_1_info.html b/structtk_1_1ctr_1_1_info.html index 4c00f628a584..6042f28cc6eb 100644 --- a/structtk_1_1ctr_1_1_info.html +++ b/structtk_1_1ctr_1_1_info.html @@ -154,7 +154,7 @@

Public variables

-

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Wednesday, Jul 10, 2024 using Doxygen and m.css. Contact us via GitHub.

+

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Thursday, Jul 11, 2024 using Doxygen and m.css. Contact us via GitHub.

diff --git a/structtk_1_1ctr_1_1_keyword_info.html b/structtk_1_1ctr_1_1_keyword_info.html index 3349c4d1e30e..2ff4acdab54f 100644 --- a/structtk_1_1ctr_1_1_keyword_info.html +++ b/structtk_1_1ctr_1_1_keyword_info.html @@ -198,7 +198,7 @@

-

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Wednesday, Jul 10, 2024 using Doxygen and m.css. Contact us via GitHub.

+

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Thursday, Jul 11, 2024 using Doxygen and m.css. Contact us via GitHub.

diff --git a/structtk_1_1ctr_1_1_p_d_f_info.html b/structtk_1_1ctr_1_1_p_d_f_info.html index 7c6b51a97041..11cb5807df48 100644 --- a/structtk_1_1ctr_1_1_p_d_f_info.html +++ b/structtk_1_1ctr_1_1_p_d_f_info.html @@ -137,7 +137,7 @@

Public variables

-

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Wednesday, Jul 10, 2024 using Doxygen and m.css. Contact us via GitHub.

+

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Thursday, Jul 11, 2024 using Doxygen and m.css. Contact us via GitHub.

diff --git a/structtk_1_1ctr_1_1_term.html b/structtk_1_1ctr_1_1_term.html index 77dca7623537..9cbefab6e9a2 100644 --- a/structtk_1_1ctr_1_1_term.html +++ b/structtk_1_1ctr_1_1_term.html @@ -291,7 +291,7 @@

-

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Wednesday, Jul 10, 2024 using Doxygen and m.css. Contact us via GitHub.

+

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Thursday, Jul 11, 2024 using Doxygen and m.css. Contact us via GitHub.

diff --git a/structtk_1_1entry__t.html b/structtk_1_1entry__t.html index 17ecb4ae94c7..6958cce3d631 100644 --- a/structtk_1_1entry__t.html +++ b/structtk_1_1entry__t.html @@ -318,7 +318,7 @@

-

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Wednesday, Jul 10, 2024 using Doxygen and m.css. Contact us via GitHub.

+

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Thursday, Jul 11, 2024 using Doxygen and m.css. Contact us via GitHub.

diff --git a/structtk_1_1grm_1_1_case_insensitive_char_less.html b/structtk_1_1grm_1_1_case_insensitive_char_less.html index 885c511be2c1..1202ad68dce4 100644 --- a/structtk_1_1grm_1_1_case_insensitive_char_less.html +++ b/structtk_1_1grm_1_1_case_insensitive_char_less.html @@ -162,7 +162,7 @@

-

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Wednesday, Jul 10, 2024 using Doxygen and m.css. Contact us via GitHub.

+

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Thursday, Jul 11, 2024 using Doxygen and m.css. Contact us via GitHub.

diff --git a/structtk_1_1grm_1_1_invert__switch.html b/structtk_1_1grm_1_1_invert__switch.html index 3ef91c94aa0f..1e229453170b 100644 --- a/structtk_1_1grm_1_1_invert__switch.html +++ b/structtk_1_1grm_1_1_invert__switch.html @@ -111,7 +111,7 @@

-

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Wednesday, Jul 10, 2024 using Doxygen and m.css. Contact us via GitHub.

+

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Thursday, Jul 11, 2024 using Doxygen and m.css. Contact us via GitHub.

diff --git a/structtk_1_1grm_1_1_store.html b/structtk_1_1grm_1_1_store.html index 4c0d3519b081..f09d01726792 100644 --- a/structtk_1_1grm_1_1_store.html +++ b/structtk_1_1grm_1_1_store.html @@ -111,7 +111,7 @@

-

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Wednesday, Jul 10, 2024 using Doxygen and m.css. Contact us via GitHub.

+

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Thursday, Jul 11, 2024 using Doxygen and m.css. Contact us via GitHub.

diff --git a/structtk_1_1grm_1_1act.html b/structtk_1_1grm_1_1act.html index fb3ff1084dde..002f3ebbbee6 100644 --- a/structtk_1_1grm_1_1act.html +++ b/structtk_1_1grm_1_1act.html @@ -111,7 +111,7 @@

-

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Wednesday, Jul 10, 2024 using Doxygen and m.css. Contact us via GitHub.

+

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Thursday, Jul 11, 2024 using Doxygen and m.css. Contact us via GitHub.

diff --git a/structtk_1_1grm_1_1action.html b/structtk_1_1grm_1_1action.html index b19242c7846f..76d73266fb04 100644 --- a/structtk_1_1grm_1_1action.html +++ b/structtk_1_1grm_1_1action.html @@ -111,7 +111,7 @@

-

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Wednesday, Jul 10, 2024 using Doxygen and m.css. Contact us via GitHub.

+

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Thursday, Jul 11, 2024 using Doxygen and m.css. Contact us via GitHub.

diff --git a/structtk_1_1grm_1_1action_3_01_invert__switch_3_01tags_8_8_8_01_4_01_4.html b/structtk_1_1grm_1_1action_3_01_invert__switch_3_01tags_8_8_8_01_4_01_4.html index 762fb36ed43d..cb9f5aebd0b0 100644 --- a/structtk_1_1grm_1_1action_3_01_invert__switch_3_01tags_8_8_8_01_4_01_4.html +++ b/structtk_1_1grm_1_1action_3_01_invert__switch_3_01tags_8_8_8_01_4_01_4.html @@ -111,7 +111,7 @@

-

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Wednesday, Jul 10, 2024 using Doxygen and m.css. Contact us via GitHub.

+

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Thursday, Jul 11, 2024 using Doxygen and m.css. Contact us via GitHub.

diff --git a/structtk_1_1grm_1_1action_3_01_store_3_01tag_00_01tags_8_8_8_01_4_01_4.html b/structtk_1_1grm_1_1action_3_01_store_3_01tag_00_01tags_8_8_8_01_4_01_4.html index 3f346605ad0c..b685273d0ebd 100644 --- a/structtk_1_1grm_1_1action_3_01_store_3_01tag_00_01tags_8_8_8_01_4_01_4.html +++ b/structtk_1_1grm_1_1action_3_01_store_3_01tag_00_01tags_8_8_8_01_4_01_4.html @@ -111,7 +111,7 @@

-

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Wednesday, Jul 10, 2024 using Doxygen and m.css. Contact us via GitHub.

+

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Thursday, Jul 11, 2024 using Doxygen and m.css. Contact us via GitHub.

diff --git a/structtk_1_1grm_1_1action_3_01act_3_01rule_00_01actions_8_8_8_01_4_01_4.html b/structtk_1_1grm_1_1action_3_01act_3_01rule_00_01actions_8_8_8_01_4_01_4.html index e8a30f4bca0e..e6c238c50a4c 100644 --- a/structtk_1_1grm_1_1action_3_01act_3_01rule_00_01actions_8_8_8_01_4_01_4.html +++ b/structtk_1_1grm_1_1action_3_01act_3_01rule_00_01actions_8_8_8_01_4_01_4.html @@ -121,7 +121,7 @@

Base classes

-

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Wednesday, Jul 10, 2024 using Doxygen and m.css. Contact us via GitHub.

+

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Thursday, Jul 11, 2024 using Doxygen and m.css. Contact us via GitHub.

diff --git a/structtk_1_1grm_1_1action_3_01check__lower__bound_3_01keyword_00_01tag_00_01tags_8_8_8_01_4_01_4.html b/structtk_1_1grm_1_1action_3_01check__lower__bound_3_01keyword_00_01tag_00_01tags_8_8_8_01_4_01_4.html index a5ccf1b08b9e..f00b8ca8fff8 100644 --- a/structtk_1_1grm_1_1action_3_01check__lower__bound_3_01keyword_00_01tag_00_01tags_8_8_8_01_4_01_4.html +++ b/structtk_1_1grm_1_1action_3_01check__lower__bound_3_01keyword_00_01tag_00_01tags_8_8_8_01_4_01_4.html @@ -111,7 +111,7 @@

-

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Wednesday, Jul 10, 2024 using Doxygen and m.css. Contact us via GitHub.

+

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Thursday, Jul 11, 2024 using Doxygen and m.css. Contact us via GitHub.

diff --git a/structtk_1_1grm_1_1action_3_01check__upper__bound_3_01keyword_00_01tag_00_01tags_8_8_8_01_4_01_4.html b/structtk_1_1grm_1_1action_3_01check__upper__bound_3_01keyword_00_01tag_00_01tags_8_8_8_01_4_01_4.html index f3edec8fcf79..b75a7969ef34 100644 --- a/structtk_1_1grm_1_1action_3_01check__upper__bound_3_01keyword_00_01tag_00_01tags_8_8_8_01_4_01_4.html +++ b/structtk_1_1grm_1_1action_3_01check__upper__bound_3_01keyword_00_01tag_00_01tags_8_8_8_01_4_01_4.html @@ -111,7 +111,7 @@

-

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Wednesday, Jul 10, 2024 using Doxygen and m.css. Contact us via GitHub.

+

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Thursday, Jul 11, 2024 using Doxygen and m.css. Contact us via GitHub.

diff --git a/structtk_1_1grm_1_1action_3_01helpkw_01_4.html b/structtk_1_1grm_1_1action_3_01helpkw_01_4.html index cf0856202c07..4c9a279ae129 100644 --- a/structtk_1_1grm_1_1action_3_01helpkw_01_4.html +++ b/structtk_1_1grm_1_1action_3_01helpkw_01_4.html @@ -112,7 +112,7 @@

-

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Wednesday, Jul 10, 2024 using Doxygen and m.css. Contact us via GitHub.

+

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Thursday, Jul 11, 2024 using Doxygen and m.css. Contact us via GitHub.

diff --git a/structtk_1_1grm_1_1action_3_01msg_3_01type_00_01key_01_4_01_4.html b/structtk_1_1grm_1_1action_3_01msg_3_01type_00_01key_01_4_01_4.html index 104fb850a336..fc99f20c4db7 100644 --- a/structtk_1_1grm_1_1action_3_01msg_3_01type_00_01key_01_4_01_4.html +++ b/structtk_1_1grm_1_1action_3_01msg_3_01type_00_01key_01_4_01_4.html @@ -111,7 +111,7 @@

-

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Wednesday, Jul 10, 2024 using Doxygen and m.css. Contact us via GitHub.

+

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Thursday, Jul 11, 2024 using Doxygen and m.css. Contact us via GitHub.

diff --git a/structtk_1_1grm_1_1alias.html b/structtk_1_1grm_1_1alias.html index 1613fedb7366..7ae924ffd0d6 100644 --- a/structtk_1_1grm_1_1alias.html +++ b/structtk_1_1grm_1_1alias.html @@ -111,7 +111,7 @@

-

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Wednesday, Jul 10, 2024 using Doxygen and m.css. Contact us via GitHub.

+

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Thursday, Jul 11, 2024 using Doxygen and m.css. Contact us via GitHub.

diff --git a/structtk_1_1grm_1_1call.html b/structtk_1_1grm_1_1call.html index 8c1d37994092..ae01cc2a1ed5 100644 --- a/structtk_1_1grm_1_1call.html +++ b/structtk_1_1grm_1_1call.html @@ -111,7 +111,7 @@

-

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Wednesday, Jul 10, 2024 using Doxygen and m.css. Contact us via GitHub.

+

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Thursday, Jul 11, 2024 using Doxygen and m.css. Contact us via GitHub.

diff --git a/structtk_1_1grm_1_1charmarg.html b/structtk_1_1grm_1_1charmarg.html index 86e5ccd59645..647857e4a1cf 100644 --- a/structtk_1_1grm_1_1charmarg.html +++ b/structtk_1_1grm_1_1charmarg.html @@ -110,7 +110,7 @@

-

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Wednesday, Jul 10, 2024 using Doxygen and m.css. Contact us via GitHub.

+

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Thursday, Jul 11, 2024 using Doxygen and m.css. Contact us via GitHub.

diff --git a/structtk_1_1grm_1_1check__lower__bound.html b/structtk_1_1grm_1_1check__lower__bound.html index 6868e40abaed..4a9de80de843 100644 --- a/structtk_1_1grm_1_1check__lower__bound.html +++ b/structtk_1_1grm_1_1check__lower__bound.html @@ -111,7 +111,7 @@

-

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Wednesday, Jul 10, 2024 using Doxygen and m.css. Contact us via GitHub.

+

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Thursday, Jul 11, 2024 using Doxygen and m.css. Contact us via GitHub.

diff --git a/structtk_1_1grm_1_1check__upper__bound.html b/structtk_1_1grm_1_1check__upper__bound.html index 9328429fd818..c60dedeb5f43 100644 --- a/structtk_1_1grm_1_1check__upper__bound.html +++ b/structtk_1_1grm_1_1check__upper__bound.html @@ -111,7 +111,7 @@

-

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Wednesday, Jul 10, 2024 using Doxygen and m.css. Contact us via GitHub.

+

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Thursday, Jul 11, 2024 using Doxygen and m.css. Contact us via GitHub.

diff --git a/structtk_1_1grm_1_1helpkw.html b/structtk_1_1grm_1_1helpkw.html index 7cb858ce235c..926b1d537f43 100644 --- a/structtk_1_1grm_1_1helpkw.html +++ b/structtk_1_1grm_1_1helpkw.html @@ -110,7 +110,7 @@

-

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Wednesday, Jul 10, 2024 using Doxygen and m.css. Contact us via GitHub.

+

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Thursday, Jul 11, 2024 using Doxygen and m.css. Contact us via GitHub.

diff --git a/structtk_1_1grm_1_1msg.html b/structtk_1_1grm_1_1msg.html index 9a474561aa2b..f660c18ff3bb 100644 --- a/structtk_1_1grm_1_1msg.html +++ b/structtk_1_1grm_1_1msg.html @@ -111,7 +111,7 @@

-

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Wednesday, Jul 10, 2024 using Doxygen and m.css. Contact us via GitHub.

+

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Thursday, Jul 11, 2024 using Doxygen and m.css. Contact us via GitHub.

diff --git a/structtk_1_1grm_1_1number.html b/structtk_1_1grm_1_1number.html index 8456e418a6a0..8cda8fe46b9d 100644 --- a/structtk_1_1grm_1_1number.html +++ b/structtk_1_1grm_1_1number.html @@ -110,7 +110,7 @@

-

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Wednesday, Jul 10, 2024 using Doxygen and m.css. Contact us via GitHub.

+

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Thursday, Jul 11, 2024 using Doxygen and m.css. Contact us via GitHub.

diff --git a/structtk_1_1grm_1_1process__cmd.html b/structtk_1_1grm_1_1process__cmd.html index c08e5cd7226b..545de67fbc47 100644 --- a/structtk_1_1grm_1_1process__cmd.html +++ b/structtk_1_1grm_1_1process__cmd.html @@ -111,7 +111,7 @@

-

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Wednesday, Jul 10, 2024 using Doxygen and m.css. Contact us via GitHub.

+

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Thursday, Jul 11, 2024 using Doxygen and m.css. Contact us via GitHub.

diff --git a/structtk_1_1grm_1_1process__cmd__switch.html b/structtk_1_1grm_1_1process__cmd__switch.html index b3398782b5fe..a8f70a708548 100644 --- a/structtk_1_1grm_1_1process__cmd__switch.html +++ b/structtk_1_1grm_1_1process__cmd__switch.html @@ -111,7 +111,7 @@

-

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Wednesday, Jul 10, 2024 using Doxygen and m.css. Contact us via GitHub.

+

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Thursday, Jul 11, 2024 using Doxygen and m.css. Contact us via GitHub.

diff --git a/structtk_1_1grm_1_1read__string.html b/structtk_1_1grm_1_1read__string.html index 058af2c6dd19..7124b3652f3b 100644 --- a/structtk_1_1grm_1_1read__string.html +++ b/structtk_1_1grm_1_1read__string.html @@ -128,7 +128,7 @@

Derived classes

-

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Wednesday, Jul 10, 2024 using Doxygen and m.css. Contact us via GitHub.

+

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Thursday, Jul 11, 2024 using Doxygen and m.css. Contact us via GitHub.

diff --git a/structtk_1_1grm_1_1readcmd.html b/structtk_1_1grm_1_1readcmd.html index fce2550eec0f..28557ae9d913 100644 --- a/structtk_1_1grm_1_1readcmd.html +++ b/structtk_1_1grm_1_1readcmd.html @@ -121,7 +121,7 @@

Base classes

-

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Wednesday, Jul 10, 2024 using Doxygen and m.css. Contact us via GitHub.

+

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Thursday, Jul 11, 2024 using Doxygen and m.css. Contact us via GitHub.

diff --git a/structtk_1_1grm_1_1readcmd_3_01keyword_00_01typename_01if___3_01false_00_01typename_01keyword_1_00e55a5c953a2708b6f3bafb2f26d0c9.html b/structtk_1_1grm_1_1readcmd_3_01keyword_00_01typename_01if___3_01false_00_01typename_01keyword_1_00e55a5c953a2708b6f3bafb2f26d0c9.html index c17857a403d4..459194991a58 100644 --- a/structtk_1_1grm_1_1readcmd_3_01keyword_00_01typename_01if___3_01false_00_01typename_01keyword_1_00e55a5c953a2708b6f3bafb2f26d0c9.html +++ b/structtk_1_1grm_1_1readcmd_3_01keyword_00_01typename_01if___3_01false_00_01typename_01keyword_1_00e55a5c953a2708b6f3bafb2f26d0c9.html @@ -111,7 +111,7 @@

-

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Wednesday, Jul 10, 2024 using Doxygen and m.css. Contact us via GitHub.

+

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Thursday, Jul 11, 2024 using Doxygen and m.css. Contact us via GitHub.

diff --git a/structtk_1_1grm_1_1readkw.html b/structtk_1_1grm_1_1readkw.html index e6c259b54ccf..cd709944524c 100644 --- a/structtk_1_1grm_1_1readkw.html +++ b/structtk_1_1grm_1_1readkw.html @@ -111,7 +111,7 @@

-

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Wednesday, Jul 10, 2024 using Doxygen and m.css. Contact us via GitHub.

+

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Thursday, Jul 11, 2024 using Doxygen and m.css. Contact us via GitHub.

diff --git a/structtk_1_1grm_1_1scan.html b/structtk_1_1grm_1_1scan.html index f50e10b484ac..09e11736c269 100644 --- a/structtk_1_1grm_1_1scan.html +++ b/structtk_1_1grm_1_1scan.html @@ -112,7 +112,7 @@

-

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Wednesday, Jul 10, 2024 using Doxygen and m.css. Contact us via GitHub.

+

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Thursday, Jul 11, 2024 using Doxygen and m.css. Contact us via GitHub.

diff --git a/structtk_1_1grm_1_1trim.html b/structtk_1_1grm_1_1trim.html index 1cd75188d45e..6725a60843a6 100644 --- a/structtk_1_1grm_1_1trim.html +++ b/structtk_1_1grm_1_1trim.html @@ -111,7 +111,7 @@

-

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Wednesday, Jul 10, 2024 using Doxygen and m.css. Contact us via GitHub.

+

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Thursday, Jul 11, 2024 using Doxygen and m.css. Contact us via GitHub.

diff --git a/structtk_1_1grm_1_1unknown.html b/structtk_1_1grm_1_1unknown.html index c40fcdbda1db..f2ecf45bd466 100644 --- a/structtk_1_1grm_1_1unknown.html +++ b/structtk_1_1grm_1_1unknown.html @@ -111,7 +111,7 @@

-

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Wednesday, Jul 10, 2024 using Doxygen and m.css. Contact us via GitHub.

+

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Thursday, Jul 11, 2024 using Doxygen and m.css. Contact us via GitHub.

diff --git a/structtk_1_1grm_1_1use.html b/structtk_1_1grm_1_1use.html index 98c5272aec6f..7d13df48bb95 100644 --- a/structtk_1_1grm_1_1use.html +++ b/structtk_1_1grm_1_1use.html @@ -112,7 +112,7 @@

-

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Wednesday, Jul 10, 2024 using Doxygen and m.css. Contact us via GitHub.

+

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Thursday, Jul 11, 2024 using Doxygen and m.css. Contact us via GitHub.

diff --git a/structtk_1_1grm_1_1verbose.html b/structtk_1_1grm_1_1verbose.html index 095403002707..e95648586d32 100644 --- a/structtk_1_1grm_1_1verbose.html +++ b/structtk_1_1grm_1_1verbose.html @@ -121,7 +121,7 @@

Derived classes

-

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Wednesday, Jul 10, 2024 using Doxygen and m.css. Contact us via GitHub.

+

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Thursday, Jul 11, 2024 using Doxygen and m.css. Contact us via GitHub.

diff --git a/structtk_1_1if__.html b/structtk_1_1if__.html index 9a85cd179cb7..d8ff1bc296d5 100644 --- a/structtk_1_1if__.html +++ b/structtk_1_1if__.html @@ -112,7 +112,7 @@

-

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Wednesday, Jul 10, 2024 using Doxygen and m.css. Contact us via GitHub.

+

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Thursday, Jul 11, 2024 using Doxygen and m.css. Contact us via GitHub.

diff --git a/structtk_1_1info__t.html b/structtk_1_1info__t.html index dde9d01e4c30..eea43f8b8181 100644 --- a/structtk_1_1info__t.html +++ b/structtk_1_1info__t.html @@ -110,7 +110,7 @@

-

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Wednesday, Jul 10, 2024 using Doxygen and m.css. Contact us via GitHub.

+

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Thursday, Jul 11, 2024 using Doxygen and m.css. Contact us via GitHub.

diff --git a/structunittest_1_1cmd_1_1charestate.html b/structunittest_1_1cmd_1_1charestate.html index 1c72fcd72857..5e6301e8c107 100644 --- a/structunittest_1_1cmd_1_1charestate.html +++ b/structunittest_1_1cmd_1_1charestate.html @@ -120,7 +120,7 @@

Base classes

-

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Wednesday, Jul 10, 2024 using Doxygen and m.css. Contact us via GitHub.

+

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Thursday, Jul 11, 2024 using Doxygen and m.css. Contact us via GitHub.

diff --git a/structunittest_1_1cmd_1_1group.html b/structunittest_1_1cmd_1_1group.html index 5f656667deca..2fbf6a730674 100644 --- a/structunittest_1_1cmd_1_1group.html +++ b/structunittest_1_1cmd_1_1group.html @@ -120,7 +120,7 @@

Base classes

-

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Wednesday, Jul 10, 2024 using Doxygen and m.css. Contact us via GitHub.

+

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Thursday, Jul 11, 2024 using Doxygen and m.css. Contact us via GitHub.

diff --git a/structunittest_1_1cmd_1_1help.html b/structunittest_1_1cmd_1_1help.html index 20a2b1b8d814..d0b8fe4093d3 100644 --- a/structunittest_1_1cmd_1_1help.html +++ b/structunittest_1_1cmd_1_1help.html @@ -120,7 +120,7 @@

Base classes

-

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Wednesday, Jul 10, 2024 using Doxygen and m.css. Contact us via GitHub.

+

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Thursday, Jul 11, 2024 using Doxygen and m.css. Contact us via GitHub.

diff --git a/structunittest_1_1cmd_1_1helpkw.html b/structunittest_1_1cmd_1_1helpkw.html index 5698debf4a21..2d0a4d217a1c 100644 --- a/structunittest_1_1cmd_1_1helpkw.html +++ b/structunittest_1_1cmd_1_1helpkw.html @@ -120,7 +120,7 @@

Base classes

-

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Wednesday, Jul 10, 2024 using Doxygen and m.css. Contact us via GitHub.

+

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Thursday, Jul 11, 2024 using Doxygen and m.css. Contact us via GitHub.

diff --git a/structunittest_1_1cmd_1_1io.html b/structunittest_1_1cmd_1_1io.html index edb212f3c263..72007e35e525 100644 --- a/structunittest_1_1cmd_1_1io.html +++ b/structunittest_1_1cmd_1_1io.html @@ -121,7 +121,7 @@

Base classes

-

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Wednesday, Jul 10, 2024 using Doxygen and m.css. Contact us via GitHub.

+

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Thursday, Jul 11, 2024 using Doxygen and m.css. Contact us via GitHub.

diff --git a/structunittest_1_1cmd_1_1keywords.html b/structunittest_1_1cmd_1_1keywords.html index 5e122e0cf153..80221197532f 100644 --- a/structunittest_1_1cmd_1_1keywords.html +++ b/structunittest_1_1cmd_1_1keywords.html @@ -110,7 +110,7 @@

-

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Wednesday, Jul 10, 2024 using Doxygen and m.css. Contact us via GitHub.

+

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Thursday, Jul 11, 2024 using Doxygen and m.css. Contact us via GitHub.

diff --git a/structunittest_1_1cmd_1_1license.html b/structunittest_1_1cmd_1_1license.html index fbc7c32eea0e..3d94c7c3621e 100644 --- a/structunittest_1_1cmd_1_1license.html +++ b/structunittest_1_1cmd_1_1license.html @@ -120,7 +120,7 @@

Base classes

-

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Wednesday, Jul 10, 2024 using Doxygen and m.css. Contact us via GitHub.

+

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Thursday, Jul 11, 2024 using Doxygen and m.css. Contact us via GitHub.

diff --git a/structunittest_1_1cmd_1_1quiescence.html b/structunittest_1_1cmd_1_1quiescence.html index 96bdffc9a82c..ea4dc61e3195 100644 --- a/structunittest_1_1cmd_1_1quiescence.html +++ b/structunittest_1_1cmd_1_1quiescence.html @@ -120,7 +120,7 @@

Base classes

-

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Wednesday, Jul 10, 2024 using Doxygen and m.css. Contact us via GitHub.

+

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Thursday, Jul 11, 2024 using Doxygen and m.css. Contact us via GitHub.

diff --git a/structunittest_1_1cmd_1_1read__string.html b/structunittest_1_1cmd_1_1read__string.html index 2077366d46e7..d0d981aa2a53 100644 --- a/structunittest_1_1cmd_1_1read__string.html +++ b/structunittest_1_1cmd_1_1read__string.html @@ -120,7 +120,7 @@

Base classes

-

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Wednesday, Jul 10, 2024 using Doxygen and m.css. Contact us via GitHub.

+

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Thursday, Jul 11, 2024 using Doxygen and m.css. Contact us via GitHub.

diff --git a/structunittest_1_1cmd_1_1trace.html b/structunittest_1_1cmd_1_1trace.html index 427cf4381a5a..4da5f939847c 100644 --- a/structunittest_1_1cmd_1_1trace.html +++ b/structunittest_1_1cmd_1_1trace.html @@ -120,7 +120,7 @@

Base classes

-

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Wednesday, Jul 10, 2024 using Doxygen and m.css. Contact us via GitHub.

+

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Thursday, Jul 11, 2024 using Doxygen and m.css. Contact us via GitHub.

diff --git a/structunittest_1_1cmd_1_1verbose.html b/structunittest_1_1cmd_1_1verbose.html index fc3c847fd35a..e0820ce3e518 100644 --- a/structunittest_1_1cmd_1_1verbose.html +++ b/structunittest_1_1cmd_1_1verbose.html @@ -120,7 +120,7 @@

Base classes

-

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Wednesday, Jul 10, 2024 using Doxygen and m.css. Contact us via GitHub.

+

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Thursday, Jul 11, 2024 using Doxygen and m.css. Contact us via GitHub.

diff --git a/structunittest_1_1cmd_1_1version.html b/structunittest_1_1cmd_1_1version.html index df19f158ba8e..e5f8a5058bf4 100644 --- a/structunittest_1_1cmd_1_1version.html +++ b/structunittest_1_1cmd_1_1version.html @@ -120,7 +120,7 @@

Base classes

-

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Wednesday, Jul 10, 2024 using Doxygen and m.css. Contact us via GitHub.

+

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Thursday, Jul 11, 2024 using Doxygen and m.css. Contact us via GitHub.

diff --git a/testarray_8decl_8h.html b/testarray_8decl_8h.html index 94621ba497a8..e3470ec0e894 100644 --- a/testarray_8decl_8h.html +++ b/testarray_8decl_8h.html @@ -111,7 +111,7 @@

-

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Wednesday, Jul 10, 2024 using Doxygen and m.css. Contact us via GitHub.

+

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Thursday, Jul 11, 2024 using Doxygen and m.css. Contact us via GitHub.

diff --git a/testarray_8def_8h.html b/testarray_8def_8h.html index 5f7e970b2332..dc308eb2e44f 100644 --- a/testarray_8def_8h.html +++ b/testarray_8def_8h.html @@ -111,7 +111,7 @@

-

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Wednesday, Jul 10, 2024 using Doxygen and m.css. Contact us via GitHub.

+

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Thursday, Jul 11, 2024 using Doxygen and m.css. Contact us via GitHub.

diff --git a/transferdetails_8decl_8h.html b/transferdetails_8decl_8h.html index 16d5c805f440..af17cca944f4 100644 --- a/transferdetails_8decl_8h.html +++ b/transferdetails_8decl_8h.html @@ -111,7 +111,7 @@

-

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Wednesday, Jul 10, 2024 using Doxygen and m.css. Contact us via GitHub.

+

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Thursday, Jul 11, 2024 using Doxygen and m.css. Contact us via GitHub.

diff --git a/transferdetails_8def_8h.html b/transferdetails_8def_8h.html index fb63f8f73523..d04ad6e6f559 100644 --- a/transferdetails_8def_8h.html +++ b/transferdetails_8def_8h.html @@ -111,7 +111,7 @@

-

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Wednesday, Jul 10, 2024 using Doxygen and m.css. Contact us via GitHub.

+

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Thursday, Jul 11, 2024 using Doxygen and m.css. Contact us via GitHub.

diff --git a/transform_8hpp.html b/transform_8hpp.html index 1dfe69d32931..837fbacb4c01 100644 --- a/transform_8hpp.html +++ b/transform_8hpp.html @@ -111,7 +111,7 @@

-

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Wednesday, Jul 10, 2024 using Doxygen and m.css. Contact us via GitHub.

+

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Thursday, Jul 11, 2024 using Doxygen and m.css. Contact us via GitHub.

diff --git a/transporter_8decl_8h.html b/transporter_8decl_8h.html index 6011a42e29be..44415cca18ef 100644 --- a/transporter_8decl_8h.html +++ b/transporter_8decl_8h.html @@ -111,7 +111,7 @@

-

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Wednesday, Jul 10, 2024 using Doxygen and m.css. Contact us via GitHub.

+

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Thursday, Jul 11, 2024 using Doxygen and m.css. Contact us via GitHub.

diff --git a/transporter_8def_8h.html b/transporter_8def_8h.html index b25e7a50e08d..281a5397c45c 100644 --- a/transporter_8def_8h.html +++ b/transporter_8def_8h.html @@ -111,7 +111,7 @@

-

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Wednesday, Jul 10, 2024 using Doxygen and m.css. Contact us via GitHub.

+

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Thursday, Jul 11, 2024 using Doxygen and m.css. Contact us via GitHub.

diff --git a/tut_8hpp.html b/tut_8hpp.html index 10f11ba2ba05..34c298bbc2ef 100644 --- a/tut_8hpp.html +++ b/tut_8hpp.html @@ -111,7 +111,7 @@

-

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Wednesday, Jul 10, 2024 using Doxygen and m.css. Contact us via GitHub.

+

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Thursday, Jul 11, 2024 using Doxygen and m.css. Contact us via GitHub.

diff --git a/tut__result_8hpp.html b/tut__result_8hpp.html index fd6da496511c..aded1edacbef 100644 --- a/tut__result_8hpp.html +++ b/tut__result_8hpp.html @@ -111,7 +111,7 @@

-

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Wednesday, Jul 10, 2024 using Doxygen and m.css. Contact us via GitHub.

+

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Thursday, Jul 11, 2024 using Doxygen and m.css. Contact us via GitHub.

diff --git a/tut__runner_8hpp.html b/tut__runner_8hpp.html index 53b0a8798927..fc2e92f742db 100644 --- a/tut__runner_8hpp.html +++ b/tut__runner_8hpp.html @@ -111,7 +111,7 @@

-

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Wednesday, Jul 10, 2024 using Doxygen and m.css. Contact us via GitHub.

+

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Thursday, Jul 11, 2024 using Doxygen and m.css. Contact us via GitHub.

diff --git a/tut_license_page.html b/tut_license_page.html index 82804e320d1e..4b42cd0064ce 100644 --- a/tut_license_page.html +++ b/tut_license_page.html @@ -137,7 +137,7 @@

-

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Wednesday, Jul 10, 2024 using Doxygen and m.css. Contact us via GitHub.

+

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Thursday, Jul 11, 2024 using Doxygen and m.css. Contact us via GitHub.

diff --git a/tutsuite_8decl_8h.html b/tutsuite_8decl_8h.html index d7f320b33098..02d06480686b 100644 --- a/tutsuite_8decl_8h.html +++ b/tutsuite_8decl_8h.html @@ -111,7 +111,7 @@

-

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Wednesday, Jul 10, 2024 using Doxygen and m.css. Contact us via GitHub.

+

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Thursday, Jul 11, 2024 using Doxygen and m.css. Contact us via GitHub.

diff --git a/tutsuite_8def_8h.html b/tutsuite_8def_8h.html index c3af74cf105f..757776e8d745 100644 --- a/tutsuite_8def_8h.html +++ b/tutsuite_8def_8h.html @@ -111,7 +111,7 @@

-

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Wednesday, Jul 10, 2024 using Doxygen and m.css. Contact us via GitHub.

+

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Thursday, Jul 11, 2024 using Doxygen and m.css. Contact us via GitHub.

diff --git a/tuttest_8decl_8h.html b/tuttest_8decl_8h.html index 49661ed74b37..c76b74d9e3e2 100644 --- a/tuttest_8decl_8h.html +++ b/tuttest_8decl_8h.html @@ -111,7 +111,7 @@

-

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Wednesday, Jul 10, 2024 using Doxygen and m.css. Contact us via GitHub.

+

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Thursday, Jul 11, 2024 using Doxygen and m.css. Contact us via GitHub.

diff --git a/tuttest_8def_8h.html b/tuttest_8def_8h.html index 9a454c242f32..aabd49c7e2a6 100644 --- a/tuttest_8def_8h.html +++ b/tuttest_8def_8h.html @@ -111,7 +111,7 @@

-

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Wednesday, Jul 10, 2024 using Doxygen and m.css. Contact us via GitHub.

+

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Thursday, Jul 11, 2024 using Doxygen and m.css. Contact us via GitHub.

diff --git a/unittest_8decl_8h.html b/unittest_8decl_8h.html index a196c61eebd2..159d639b7961 100644 --- a/unittest_8decl_8h.html +++ b/unittest_8decl_8h.html @@ -111,7 +111,7 @@

-

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Wednesday, Jul 10, 2024 using Doxygen and m.css. Contact us via GitHub.

+

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Thursday, Jul 11, 2024 using Doxygen and m.css. Contact us via GitHub.

diff --git a/unittest_8def_8h.html b/unittest_8def_8h.html index dba0d6c980be..4f8c12b07133 100644 --- a/unittest_8def_8h.html +++ b/unittest_8def_8h.html @@ -111,7 +111,7 @@

-

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Wednesday, Jul 10, 2024 using Doxygen and m.css. Contact us via GitHub.

+

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Thursday, Jul 11, 2024 using Doxygen and m.css. Contact us via GitHub.

diff --git a/unittest_cmd.html b/unittest_cmd.html index 7488b4457f38..89f3459b612b 100644 --- a/unittest_cmd.html +++ b/unittest_cmd.html @@ -142,7 +142,7 @@

Contents

-

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Wednesday, Jul 10, 2024 using Doxygen and m.css. Contact us via GitHub.

+

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Thursday, Jul 11, 2024 using Doxygen and m.css. Contact us via GitHub.

diff --git a/unittest_main.html b/unittest_main.html index a730d43b5171..67054a6b3c17 100644 --- a/unittest_main.html +++ b/unittest_main.html @@ -110,7 +110,7 @@

-

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Wednesday, Jul 10, 2024 using Doxygen and m.css. Contact us via GitHub.

+

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Thursday, Jul 11, 2024 using Doxygen and m.css. Contact us via GitHub.

diff --git a/unsmeshmap_8decl_8h.html b/unsmeshmap_8decl_8h.html index 42e5f25c6b9e..652f65e52123 100644 --- a/unsmeshmap_8decl_8h.html +++ b/unsmeshmap_8decl_8h.html @@ -111,7 +111,7 @@

-

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Wednesday, Jul 10, 2024 using Doxygen and m.css. Contact us via GitHub.

+

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Thursday, Jul 11, 2024 using Doxygen and m.css. Contact us via GitHub.

diff --git a/unsmeshmap_8def_8h.html b/unsmeshmap_8def_8h.html index 9dfa04a3faa0..b56df779b5a1 100644 --- a/unsmeshmap_8def_8h.html +++ b/unsmeshmap_8def_8h.html @@ -111,7 +111,7 @@

-

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Wednesday, Jul 10, 2024 using Doxygen and m.css. Contact us via GitHub.

+

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Thursday, Jul 11, 2024 using Doxygen and m.css. Contact us via GitHub.

diff --git a/value__factory_8hpp.html b/value__factory_8hpp.html index 16f097bc6eae..137bbbffb9a6 100644 --- a/value__factory_8hpp.html +++ b/value__factory_8hpp.html @@ -111,7 +111,7 @@

-

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Wednesday, Jul 10, 2024 using Doxygen and m.css. Contact us via GitHub.

+

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Thursday, Jul 11, 2024 using Doxygen and m.css. Contact us via GitHub.

diff --git a/why.html b/why.html index 96107774fb1b..93bd315c0715 100644 --- a/why.html +++ b/why.html @@ -110,7 +110,7 @@

-

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Wednesday, Jul 10, 2024 using Doxygen and m.css. Contact us via GitHub.

+

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Thursday, Jul 11, 2024 using Doxygen and m.css. Contact us via GitHub.

diff --git a/zoltan_license_page.html b/zoltan_license_page.html index a090c66170ef..5c8f2dc14e68 100644 --- a/zoltan_license_page.html +++ b/zoltan_license_page.html @@ -146,7 +146,7 @@

-

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Wednesday, Jul 10, 2024 using Doxygen and m.css. Contact us via GitHub.

+

Quinoa docs, part of the Quinoa project. Copyright © J. Bakosi 2012–2015, Los Alamos National Security, LLC, 2016–2018, Triad National Security, LLC, 2019-2023. Generated on Thursday, Jul 11, 2024 using Doxygen and m.css. Contact us via GitHub.